未验证 提交 9b299f2c 编写于 作者: Y Yegor 提交者: GitHub

fix editable placement in a11y mode (#14581)

上级 cce5afd4
......@@ -4,6 +4,70 @@
part of engine;
/// Text editing used by accesibility mode.
///
/// [SemanticsTextEditingStrategy] assumes the caller will own the creation,
/// insertion and disposal of the DOM element. Due to this
/// [initializeElementPlacement], [initializeTextEditing] and
/// [disable] strategies are handled differently.
///
/// This class is still responsible for hooking up the DOM element with the
/// [HybridTextEditing] instance so that changes are communicated to Flutter.
class SemanticsTextEditingStrategy extends DefaultTextEditingStrategy {
/// Creates a [SemanticsTextEditingStrategy] that eagerly instantiates
/// [domElement] so the caller can insert it before calling
/// [SemanticsTextEditingStrategy.enable].
SemanticsTextEditingStrategy(
HybridTextEditing owner, html.HtmlElement domElement)
: super(owner) {
// Make sure the DOM element is of a type that we support for text editing.
// TODO(yjbanov): move into initializer list when https://github.com/dart-lang/sdk/issues/37881 is fixed.
assert((domElement is html.InputElement) ||
(domElement is html.TextAreaElement));
super.domElement = domElement;
}
@override
void disable() {
// We don't want to remove the DOM element because the caller is responsible
// for that.
//
// Remove focus from the editable element to cause the keyboard to hide.
// Otherwise, the keyboard stays on screen even when the user navigates to
// a different screen (e.g. by hitting the "back" button).
domElement.blur();
}
@override
void initializeElementPlacement() {
// Element placement is done by [TextField].
}
@override
void initializeTextEditing(InputConfiguration inputConfig,
{_OnChangeCallback onChange, _OnActionCallback onAction}) {
// In accesibilty mode, the user of this class is supposed to insert the
// [domElement] on their own. Let's make sure they did.
assert(domElement != null);
assert(html.document.body.contains(domElement));
isEnabled = true;
_inputConfiguration = inputConfig;
_onChange = onChange;
_onAction = onAction;
domElement.focus();
}
@override
void setEditingState(EditingState editingState) {
super.setEditingState(editingState);
// Refocus after setting editing state.
domElement.focus();
}
}
/// Manages semantics objects that represent editable text fields.
///
/// This role is implemented via a content-editable HTML element. This role does
......@@ -19,15 +83,15 @@ class TextField extends RoleManager {
semanticsObject.hasFlag(ui.SemanticsFlag.isMultiline)
? html.TextAreaElement()
: html.InputElement();
persistentTextEditingElement = PersistentTextEditingElement(
textEditingElement = SemanticsTextEditingStrategy(
textEditing,
editableDomElement,
);
_setupDomElement();
}
PersistentTextEditingElement persistentTextEditingElement;
html.Element get _textFieldElement => persistentTextEditingElement.domElement;
SemanticsTextEditingStrategy textEditingElement;
html.Element get _textFieldElement => textEditingElement.domElement;
void _setupDomElement() {
// On iOS, even though the semantic text field is transparent, the cursor
......@@ -61,6 +125,7 @@ class TextField extends RoleManager {
switch (browserEngine) {
case BrowserEngine.blink:
case BrowserEngine.edge:
case BrowserEngine.ie11:
case BrowserEngine.firefox:
case BrowserEngine.ie11:
case BrowserEngine.unknown:
......@@ -82,7 +147,7 @@ class TextField extends RoleManager {
return;
}
textEditing.useCustomEditableElement(persistentTextEditingElement);
textEditing.useCustomEditableElement(textEditingElement);
ui.window
.onSemanticsAction(semanticsObject.id, ui.SemanticsAction.tap, null);
});
......@@ -98,7 +163,7 @@ class TextField extends RoleManager {
num lastTouchStartOffsetY;
_textFieldElement.addEventListener('touchstart', (html.Event event) {
textEditing.useCustomEditableElement(persistentTextEditingElement);
textEditing.useCustomEditableElement(textEditingElement);
final html.TouchEvent touchEvent = event;
lastTouchStartOffsetX = touchEvent.changedTouches.last.client.x;
lastTouchStartOffsetY = touchEvent.changedTouches.last.client.y;
......
......@@ -155,7 +155,7 @@ class EngineWindow extends ui.Window {
break;
case 'flutter/textinput':
textEditing.handleTextInput(data);
textEditing.channel.handleTextInput(data);
return;
case 'flutter/platform_views':
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册