44
55part of engine;
66
7+ /// Text editing used by accesibility mode.
8+ ///
9+ /// [SemanticsTextEditingStrategy] assumes the caller will own the creation,
10+ /// insertion and disposal of the DOM element. Due to this
11+ /// [initializeElementPlacement] , [initializeTextEditing] and
12+ /// [disable] strategies are handled differently.
13+ ///
14+ /// This class is still responsible for hooking up the DOM element with the
15+ /// [HybridTextEditing] instance so that changes are communicated to Flutter.
16+ class SemanticsTextEditingStrategy extends DefaultTextEditingStrategy {
17+ /// Creates a [SemanticsTextEditingStrategy] that eagerly instantiates
18+ /// [domElement] so the caller can insert it before calling
19+ /// [SemanticsTextEditingStrategy.enable] .
20+ SemanticsTextEditingStrategy (
21+ HybridTextEditing owner, html.HtmlElement domElement)
22+ : super (owner) {
23+ // Make sure the DOM element is of a type that we support for text editing.
24+ // TODO(yjbanov): move into initializer list when https://github.com/dart-lang/sdk/issues/37881 is fixed.
25+ assert ((domElement is html.InputElement ) ||
26+ (domElement is html.TextAreaElement ));
27+ super .domElement = domElement;
28+ }
29+
30+ @override
31+ void disable () {
32+ // We don't want to remove the DOM element because the caller is responsible
33+ // for that.
34+ //
35+ // Remove focus from the editable element to cause the keyboard to hide.
36+ // Otherwise, the keyboard stays on screen even when the user navigates to
37+ // a different screen (e.g. by hitting the "back" button).
38+ domElement.blur ();
39+ }
40+
41+ @override
42+ void initializeElementPlacement () {
43+ // Element placement is done by [TextField].
44+ }
45+
46+ @override
47+ void initializeTextEditing (InputConfiguration inputConfig,
48+ {_OnChangeCallback onChange, _OnActionCallback onAction}) {
49+ // In accesibilty mode, the user of this class is supposed to insert the
50+ // [domElement] on their own. Let's make sure they did.
51+ assert (domElement != null );
52+ assert (html.document.body.contains (domElement));
53+
54+ isEnabled = true ;
55+ _inputConfiguration = inputConfig;
56+ _onChange = onChange;
57+ _onAction = onAction;
58+
59+ domElement.focus ();
60+ }
61+
62+ @override
63+ void setEditingState (EditingState editingState) {
64+ super .setEditingState (editingState);
65+
66+ // Refocus after setting editing state.
67+ domElement.focus ();
68+ }
69+ }
70+
771/// Manages semantics objects that represent editable text fields.
872///
973/// This role is implemented via a content-editable HTML element. This role does
@@ -19,15 +83,15 @@ class TextField extends RoleManager {
1983 semanticsObject.hasFlag (ui.SemanticsFlag .isMultiline)
2084 ? html.TextAreaElement ()
2185 : html.InputElement ();
22- persistentTextEditingElement = PersistentTextEditingElement (
86+ textEditingElement = SemanticsTextEditingStrategy (
2387 textEditing,
2488 editableDomElement,
2589 );
2690 _setupDomElement ();
2791 }
2892
29- PersistentTextEditingElement persistentTextEditingElement ;
30- html.Element get _textFieldElement => persistentTextEditingElement .domElement;
93+ SemanticsTextEditingStrategy textEditingElement ;
94+ html.Element get _textFieldElement => textEditingElement .domElement;
3195
3296 void _setupDomElement () {
3397 // On iOS, even though the semantic text field is transparent, the cursor
@@ -61,6 +125,7 @@ class TextField extends RoleManager {
61125 switch (browserEngine) {
62126 case BrowserEngine .blink:
63127 case BrowserEngine .edge:
128+ case BrowserEngine .ie11:
64129 case BrowserEngine .firefox:
65130 case BrowserEngine .ie11:
66131 case BrowserEngine .unknown:
@@ -82,7 +147,7 @@ class TextField extends RoleManager {
82147 return ;
83148 }
84149
85- textEditing.useCustomEditableElement (persistentTextEditingElement );
150+ textEditing.useCustomEditableElement (textEditingElement );
86151 ui.window
87152 .onSemanticsAction (semanticsObject.id, ui.SemanticsAction .tap, null );
88153 });
@@ -98,7 +163,7 @@ class TextField extends RoleManager {
98163 num lastTouchStartOffsetY;
99164
100165 _textFieldElement.addEventListener ('touchstart' , (html.Event event) {
101- textEditing.useCustomEditableElement (persistentTextEditingElement );
166+ textEditing.useCustomEditableElement (textEditingElement );
102167 final html.TouchEvent touchEvent = event;
103168 lastTouchStartOffsetX = touchEvent.changedTouches.last.client.x;
104169 lastTouchStartOffsetY = touchEvent.changedTouches.last.client.y;
0 commit comments