This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Commit 1c12368
authored
[web] scale semantic text elements to match the desired focus ring size (#52586)
Due to https://g-issues.chromium.org/issues/40875151?pli=1&authuser=0
and a lack of an ARIA role for plain text nodes (after the removal of
`role="text"` in WebKit recently), there is no way to customize the size
of the screen reader focus ring for a plain text element. The focus ring
always tightly hugs the text itself.
A workaround implemented in this PR is to match the size of the text
exactly to the desired focus ring size. This is done by measuring the
size of the text in the DOM, then scaling it both vertically and
horizontally to match the size requested by the framework for the
corresponding semantics node.
To avoid serious performance penalty, the following optimizations were
included:
- Nodes that are satisfiable by just an `aria-label` do not need this
workaround, and are skipped.
- Nodes that must use DOM text (e.g. links, buttons) but have ARIA roles
that size them based on the element, do not need this workaround, and
are skipped.
- Nodes that do need the workaround are first measured in a single
batch, incurring only one page reflow. Then they are all updated in a
single batch without taking any further DOM measurements. This ensures
that no matter how many text spans are rendered, only one reflow is
needed to measure them all.
- Nodes that need the workaround cache the previous label and size, and
if they do not change, the size is not updated.
Other changes:
- Rename `LeafLabelRepresentation` to `LabelRepresentation`, because
labels also apply to non-leaf nodes (e.g. `aria-label` may be applied to
a container).
- Rename `labelRepresentation` to `preferredLabelRepresentation`,
because a particular label representation cannot be guaranteed. A node
that currently looks like a leaf text node may turn out to be an empty
container, and after adding children to it must switch from using DOM
text to an `aria-label`. Therefore, role manager only specify a
preference, but `LabelAndValue` ultimately decides which representation
is usable.
- Introduce `void initState()` in `PrimaryRoleManager` to be used for
one-time initialization of state and DOM structure after all objects
that are in a one-to-one relationship with each other create all the
references needed to establish that relationship (`PrimaryRoleManager`,
`SemanticsObject`, `element`, `owner`, etc). This is not available at
the time the constructors are called.
Fixes flutter/flutter#146774.1 parent c674206 commit 1c12368
File tree
15 files changed
+851
-182
lines changed- lib/web_ui
- lib/src/engine
- semantics
- test
- common
- engine
- semantics
15 files changed
+851
-182
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
589 | 589 | | |
590 | 590 | | |
591 | 591 | | |
| 592 | + | |
| 593 | + | |
| 594 | + | |
| 595 | + | |
| 596 | + | |
| 597 | + | |
| 598 | + | |
| 599 | + | |
592 | 600 | | |
593 | 601 | | |
594 | 602 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
55 | 55 | | |
56 | 56 | | |
57 | 57 | | |
58 | | - | |
| 58 | + | |
59 | 59 | | |
60 | 60 | | |
61 | 61 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
31 | | - | |
| 31 | + | |
32 | 32 | | |
33 | 33 | | |
34 | 34 | | |
| |||
0 commit comments