mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[web] remove Tappable from basic set of a11y roles; add it case by case (flutter/engine#51466)
Remove the `Tappable` role from the `PrimaryRoleManager.withBasics` constructor. Only add `Tappable` to primary roles that know for sure they need it. Fixes https://github.com/flutter/flutter/issues/144364
This commit is contained in:
parent
375b19aae9
commit
896df78f52
@ -56,7 +56,9 @@ class Checkable extends PrimaryRoleManager {
|
||||
PrimaryRole.checkable,
|
||||
semanticsObject,
|
||||
labelRepresentation: LeafLabelRepresentation.ariaLabel,
|
||||
);
|
||||
) {
|
||||
addTappable();
|
||||
}
|
||||
|
||||
final _CheckableKind _kind;
|
||||
|
||||
|
||||
@ -11,7 +11,9 @@ class Link extends PrimaryRoleManager {
|
||||
PrimaryRole.link,
|
||||
semanticsObject,
|
||||
labelRepresentation: LeafLabelRepresentation.domText,
|
||||
);
|
||||
) {
|
||||
addTappable();
|
||||
}
|
||||
|
||||
@override
|
||||
DomElement createElement() {
|
||||
|
||||
@ -439,7 +439,6 @@ abstract class PrimaryRoleManager {
|
||||
addLiveRegion();
|
||||
addRouteName();
|
||||
addLabelAndValue(labelRepresentation: labelRepresentation);
|
||||
addTappable();
|
||||
}
|
||||
|
||||
/// Initializes a blank role for a [semanticsObject].
|
||||
@ -625,7 +624,17 @@ final class GenericRole extends PrimaryRoleManager {
|
||||
PrimaryRole.generic,
|
||||
semanticsObject,
|
||||
labelRepresentation: LeafLabelRepresentation.domText,
|
||||
);
|
||||
) {
|
||||
// Typically a tappable widget would have a more specific role, such as
|
||||
// "link", "button", "checkbox", etc. However, there are situations when a
|
||||
// tappable is not a leaf node, but contains other nodes, which can also be
|
||||
// tappable. For example, the dismiss barrier of a pop-up menu is a tappable
|
||||
// ancestor of the menu itself, while the menu may contain tappable
|
||||
// children.
|
||||
if (semanticsObject.isTappable) {
|
||||
addTappable();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void update() {
|
||||
|
||||
@ -12,6 +12,7 @@ class Button extends PrimaryRoleManager {
|
||||
semanticsObject,
|
||||
labelRepresentation: LeafLabelRepresentation.domText,
|
||||
) {
|
||||
addTappable();
|
||||
setAriaRole('button');
|
||||
}
|
||||
|
||||
|
||||
@ -51,6 +51,9 @@ void runSemanticsTests() {
|
||||
group('Role managers', () {
|
||||
_testRoleManagerLifecycle();
|
||||
});
|
||||
group('Text', () {
|
||||
_testText();
|
||||
});
|
||||
group('container', () {
|
||||
_testContainer();
|
||||
});
|
||||
@ -718,6 +721,74 @@ void _testLongestIncreasingSubsequence() {
|
||||
});
|
||||
}
|
||||
|
||||
void _testText() {
|
||||
test('renders a piece of plain text', () async {
|
||||
semantics()
|
||||
..debugOverrideTimestampFunction(() => _testTime)
|
||||
..semanticsEnabled = true;
|
||||
|
||||
final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
|
||||
updateNode(
|
||||
builder,
|
||||
label: 'plain text',
|
||||
rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
|
||||
);
|
||||
owner().updateSemantics(builder.build());
|
||||
|
||||
expectSemanticsTree(
|
||||
owner(),
|
||||
'''<sem role="text" style="$rootSemanticStyle">plain text</sem>''',
|
||||
);
|
||||
|
||||
final SemanticsObject node = owner().debugSemanticsTree![0]!;
|
||||
expect(node.primaryRole?.role, PrimaryRole.generic);
|
||||
expect(
|
||||
node.primaryRole!.secondaryRoleManagers!.map((RoleManager m) => m.runtimeType).toList(),
|
||||
<Type>[
|
||||
Focusable,
|
||||
LiveRegion,
|
||||
RouteName,
|
||||
LabelAndValue,
|
||||
],
|
||||
);
|
||||
semantics().semanticsEnabled = false;
|
||||
});
|
||||
|
||||
test('renders a tappable piece of text', () async {
|
||||
semantics()
|
||||
..debugOverrideTimestampFunction(() => _testTime)
|
||||
..semanticsEnabled = true;
|
||||
|
||||
final SemanticsTester tester = SemanticsTester(owner());
|
||||
tester.updateNode(
|
||||
id: 0,
|
||||
hasTap: true,
|
||||
label: 'tappable text',
|
||||
rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
|
||||
);
|
||||
tester.apply();
|
||||
|
||||
expectSemanticsTree(
|
||||
owner(),
|
||||
'''<sem flt-tappable="" role="text" style="$rootSemanticStyle">tappable text</sem>''',
|
||||
);
|
||||
|
||||
final SemanticsObject node = owner().debugSemanticsTree![0]!;
|
||||
expect(node.primaryRole?.role, PrimaryRole.generic);
|
||||
expect(
|
||||
node.primaryRole!.secondaryRoleManagers!.map((RoleManager m) => m.runtimeType).toList(),
|
||||
<Type>[
|
||||
Focusable,
|
||||
LiveRegion,
|
||||
RouteName,
|
||||
LabelAndValue,
|
||||
Tappable,
|
||||
],
|
||||
);
|
||||
semantics().semanticsEnabled = false;
|
||||
});
|
||||
}
|
||||
|
||||
void _testContainer() {
|
||||
test('container node has no transform when there is no rect offset',
|
||||
() async {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user