Skip to content

Commit

Permalink
Revert "[web] switch from .didGain/LoseAccessibilityFocus to .focus (#…
Browse files Browse the repository at this point in the history
…53360)"

This reverts commit ad1343c.
  • Loading branch information
jiahaog authored Jul 2, 2024
1 parent 37d959c commit ed26c54
Show file tree
Hide file tree
Showing 9 changed files with 898 additions and 257 deletions.
3 changes: 0 additions & 3 deletions lib/ui/semantics.dart
Original file line number Diff line number Diff line change
Expand Up @@ -220,9 +220,6 @@ class SemanticsAction {
/// must immediately become editable, opening a virtual keyboard, if needed.
/// Buttons must respond to tap/click events from the keyboard.
///
/// Widget reaction to this action must be idempotent. It is possible to
/// receive this action more than once, or when the widget is already focused.
///
/// Focus behavior is specific to the platform and to the assistive technology
/// used. Typically on desktop operating systems, such as Windows, macOS, and
/// Linux, moving accessibility focus will also move the input focus. On
Expand Down
24 changes: 0 additions & 24 deletions lib/web_ui/lib/src/engine/dom.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2753,30 +2753,6 @@ DomCompositionEvent createDomCompositionEvent(String type,
}
}

/// This is a pseudo-type for DOM elements that have the boolean `disabled`
/// property.
///
/// This type cannot be part of the actual type hierarchy because each DOM type
/// defines its `disabled` property ad hoc, without inheriting it from a common
/// type, e.g. [DomHTMLInputElement] and [DomHTMLTextAreaElement].
///
/// To use, simply cast any element known to have the `disabled` property to
/// this type using `as DomElementWithDisabledProperty`, then read and write
/// this property as normal.
@JS()
@staticInterop
class DomElementWithDisabledProperty extends DomHTMLElement {}

extension DomElementWithDisabledPropertyExtension on DomElementWithDisabledProperty {
@JS('disabled')
external JSBoolean? get _disabled;
bool? get disabled => _disabled?.toDart;

@JS('disabled')
external set _disabled(JSBoolean? value);
set disabled(bool? value) => _disabled = value?.toJS;
}

@JS()
@staticInterop
class DomHTMLInputElement extends DomHTMLElement {}
Expand Down
17 changes: 13 additions & 4 deletions lib/web_ui/lib/src/engine/semantics/focusable.dart
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ typedef _FocusTarget = ({

/// The listener for the "focus" DOM event.
DomEventListener domFocusListener,

/// The listener for the "blur" DOM event.
DomEventListener domBlurListener,
});

/// Implements accessibility focus management for arbitrary elements.
Expand Down Expand Up @@ -132,6 +135,7 @@ class AccessibilityFocusManager {
semanticsNodeId: semanticsNodeId,
element: previousTarget.element,
domFocusListener: previousTarget.domFocusListener,
domBlurListener: previousTarget.domBlurListener,
);
return;
}
Expand All @@ -144,12 +148,14 @@ class AccessibilityFocusManager {
final _FocusTarget newTarget = (
semanticsNodeId: semanticsNodeId,
element: element,
domFocusListener: createDomEventListener((_) => _didReceiveDomFocus()),
domFocusListener: createDomEventListener((_) => _setFocusFromDom(true)),
domBlurListener: createDomEventListener((_) => _setFocusFromDom(false)),
);
_target = newTarget;

element.tabIndex = 0;
element.addEventListener('focus', newTarget.domFocusListener);
element.addEventListener('blur', newTarget.domBlurListener);
}

/// Stops managing the focus of the current element, if any.
Expand All @@ -164,9 +170,10 @@ class AccessibilityFocusManager {
}

target.element.removeEventListener('focus', target.domFocusListener);
target.element.removeEventListener('blur', target.domBlurListener);
}

void _didReceiveDomFocus() {
void _setFocusFromDom(bool acquireFocus) {
final _FocusTarget? target = _target;

if (target == null) {
Expand All @@ -177,7 +184,9 @@ class AccessibilityFocusManager {

EnginePlatformDispatcher.instance.invokeOnSemanticsAction(
target.semanticsNodeId,
ui.SemanticsAction.focus,
acquireFocus
? ui.SemanticsAction.didGainAccessibilityFocus
: ui.SemanticsAction.didLoseAccessibilityFocus,
null,
);
}
Expand Down Expand Up @@ -220,7 +229,7 @@ class AccessibilityFocusManager {
// a dialog, and nothing else in the dialog is focused. The Flutter
// framework expects that the screen reader will focus on the first (in
// traversal order) focusable element inside the dialog and send a
// SemanticsAction.focus action. Screen readers on the web do not do
// didGainAccessibilityFocus action. Screen readers on the web do not do
// that, and so the web engine has to implement this behavior directly. So
// the dialog will look for a focusable element and request focus on it,
// but now there may be a race between this method unsetting the focus and
Expand Down
2 changes: 2 additions & 0 deletions lib/web_ui/lib/src/engine/semantics/semantics.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2218,6 +2218,8 @@ class EngineSemantics {
'mousemove',
'mouseleave',
'mouseup',
'keyup',
'keydown',
];

if (pointerEventTypes.contains(event.type)) {
Expand Down
Loading

0 comments on commit ed26c54

Please sign in to comment.