diff --git a/lib/web_ui/lib/src/engine/semantics/text_field.dart b/lib/web_ui/lib/src/engine/semantics/text_field.dart index 5f89f88f2f217..9d6a88a9ccb46 100644 --- a/lib/web_ui/lib/src/engine/semantics/text_field.dart +++ b/lib/web_ui/lib/src/engine/semantics/text_field.dart @@ -301,7 +301,16 @@ class TextField extends PrimaryRoleManager { } EnginePlatformDispatcher.instance.invokeOnSemanticsAction( - semanticsObject.id, ui.SemanticsAction.tap, null); + semanticsObject.id, ui.SemanticsAction.didGainAccessibilityFocus, null); + })); + activeEditableElement.addEventListener('blur', + createDomEventListener((DomEvent event) { + if (semanticsObject.owner.gestureMode != GestureMode.browserGestures) { + return; + } + + EnginePlatformDispatcher.instance.invokeOnSemanticsAction( + semanticsObject.id, ui.SemanticsAction.didLoseAccessibilityFocus, null); })); } diff --git a/lib/web_ui/test/engine/semantics/semantics_test.dart b/lib/web_ui/test/engine/semantics/semantics_test.dart index 5013ff3decc28..03a030358a74c 100644 --- a/lib/web_ui/test/engine/semantics/semantics_test.dart +++ b/lib/web_ui/test/engine/semantics/semantics_test.dart @@ -1517,7 +1517,7 @@ void _testTextField() { // TODO(yjbanov): this test will need to be adjusted for Safari when we add // Safari testing. - test('sends a tap action when text field is activated', () async { + test('sends a focus action when text field is activated', () async { final SemanticsActionLogger logger = SemanticsActionLogger(); semantics() ..debugOverrideTimestampFunction(() => _testTime) @@ -1526,7 +1526,7 @@ void _testTextField() { final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder(); updateNode( builder, - actions: 0 | ui.SemanticsAction.tap.index, + actions: 0 | ui.SemanticsAction.didGainAccessibilityFocus.index, flags: 0 | ui.SemanticsFlag.isTextField.index, value: 'hello', transform: Matrix4.identity().toFloat64(), @@ -1544,7 +1544,7 @@ void _testTextField() { expect(appHostNode.ownerDocument?.activeElement, textField); expect(await logger.idLog.first, 0); - expect(await logger.actionLog.first, ui.SemanticsAction.tap); + expect(await logger.actionLog.first, ui.SemanticsAction.didGainAccessibilityFocus); semantics().semanticsEnabled = false; }, // TODO(yjbanov): https://github.com/flutter/flutter/issues/46638 diff --git a/lib/web_ui/test/engine/semantics/text_field_test.dart b/lib/web_ui/test/engine/semantics/text_field_test.dart index 503f1cdd11bd9..197e2fe50644d 100644 --- a/lib/web_ui/test/engine/semantics/text_field_test.dart +++ b/lib/web_ui/test/engine/semantics/text_field_test.dart @@ -92,25 +92,31 @@ void testMain() { '''); }); - // TODO(yjbanov): this test will need to be adjusted for Safari when we add - // Safari testing. - test('sends a tap action when browser requests focus', () async { - final SemanticsActionLogger logger = SemanticsActionLogger(); - createTextFieldSemantics(value: 'hello'); + // TODO(yjbanov): this test will need to be adjusted for Safari when we add + // Safari testing. + test('sends a didGainAccessibilityFocus/didLoseAccessibilityFocus action when browser requests focus/blur', () async { + final SemanticsActionLogger logger = SemanticsActionLogger(); + createTextFieldSemantics(value: 'hello'); - final DomElement textField = appHostNode - .querySelector('input[data-semantics-role="text-field"]')!; + final DomElement textField = appHostNode + .querySelector('input[data-semantics-role="text-field"]')!; - expect(appHostNode.ownerDocument?.activeElement, isNot(textField)); + expect(appHostNode.ownerDocument?.activeElement, isNot(textField)); - textField.focus(); + textField.focus(); - expect(appHostNode.ownerDocument?.activeElement, textField); - expect(await logger.idLog.first, 0); - expect(await logger.actionLog.first, ui.SemanticsAction.tap); + expect(appHostNode.ownerDocument?.activeElement, textField); + expect(await logger.idLog.first, 0); + expect(await logger.actionLog.first, ui.SemanticsAction.didGainAccessibilityFocus); + + textField.blur(); + + expect(appHostNode.ownerDocument?.activeElement, isNot(textField)); + expect(await logger.idLog.first, 0); + expect(await logger.actionLog.first, ui.SemanticsAction.didLoseAccessibilityFocus); }, // TODO(yjbanov): https://github.com/flutter/flutter/issues/46638 - // TODO(yjbanov): https://github.com/flutter/flutter/issues/50590 - skip: browserEngine != BrowserEngine.blink); + // TODO(yjbanov): https://github.com/flutter/flutter/issues/50590 + skip: browserEngine != BrowserEngine.blink); test('Syncs semantic state from framework', () { expect(appHostNode.ownerDocument?.activeElement, domDocument.body);