Created
May 7, 2024 18:14
-
-
Save yjbanov/f7755838910ccf1a873286e7bb2f1244 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/lib/web_ui/lib/src/engine/semantics/label_and_value.dart b/lib/web_ui/lib/src/engine/semantics/label_and_value.dart | |
index 843c4dedda..74ccc08d2a 100644 | |
--- a/lib/web_ui/lib/src/engine/semantics/label_and_value.dart | |
+++ b/lib/web_ui/lib/src/engine/semantics/label_and_value.dart | |
@@ -16,7 +16,7 @@ import 'semantics.dart'; | |
/// respect the `aria-label` without a [DomText] node. Crawlers typically do not | |
/// need this information, as they primarily scan visible text, which is | |
/// communicated in semantics as leaf text and heading nodes. | |
-enum LabelRepresentation { | |
+sealed class LabelRepresentation { | |
/// Represents the label as an `aria-label` attribute. | |
/// | |
/// This representation is the most efficient as all it does is pass a string | |
@@ -27,7 +27,7 @@ enum LabelRepresentation { | |
/// role) JAWS on Windows. However, this role is still the most common, as it | |
/// applies to all container nodes, and many ARIA roles (e.g. checkboxes, | |
/// radios, scrollables, sliders). | |
- ariaLabel(AriaLabelRepresentation), | |
+ static const LabelRepresentation ariaLabel = _AriaLabel(); | |
/// Represents the label as a [DomText] node. | |
/// | |
@@ -37,7 +37,7 @@ enum LabelRepresentation { | |
/// | |
/// This representation is compatible with most web crawlers, and it is the | |
/// best option for certain ARIA roles, such as buttons, links, and headings. | |
- domText(DomTextRepresentation), | |
+ static const LabelRepresentation domText = _DomText(); | |
/// Represents the label as a sized span. | |
/// | |
@@ -45,17 +45,38 @@ enum LabelRepresentation { | |
/// need to be laid out to compute the right size. It is compatible with most | |
/// web crawlers, and it is the best options for certain ARIA roles, such as | |
/// the implicit "generic" role used for plain text (not headings). | |
- sizedSpan(SizedSpanRepresentation); | |
- | |
- const LabelRepresentation(this.implementation); | |
+ static const LabelRepresentation sizedSpan = _SizedSpan(); | |
/// The type used to implement this representation. | |
- final Type implementation; | |
+ LabelRepresentationBehavior createBehavior(PrimaryRoleManager owner); | |
+} | |
+ | |
+final class _AriaLabel implements LabelRepresentation { | |
+ const _AriaLabel(); | |
+ | |
+ @override | |
+ LabelRepresentationBehavior createBehavior(PrimaryRoleManager owner) => AriaLabelRepresentation._(owner); | |
+} | |
+ | |
+final class _DomText implements LabelRepresentation { | |
+ const _DomText(); | |
+ | |
+ @override | |
+ LabelRepresentationBehavior createBehavior(PrimaryRoleManager owner) => DomTextRepresentation._(owner); | |
+} | |
+ | |
+final class _SizedSpan implements LabelRepresentation { | |
+ const _SizedSpan(); | |
+ | |
+ @override | |
+ LabelRepresentationBehavior createBehavior(PrimaryRoleManager owner) => SizedSpanRepresentation._(owner); | |
} | |
/// Provides a DOM behavior for a [LabelRepresentation]. | |
abstract final class LabelRepresentationBehavior { | |
- LabelRepresentationBehavior(this.owner); | |
+ LabelRepresentationBehavior(this.kind, this.owner); | |
+ | |
+ final LabelRepresentation kind; | |
/// The role manager that this label representation is attached to. | |
final PrimaryRoleManager owner; | |
@@ -103,7 +124,7 @@ abstract final class LabelRepresentationBehavior { | |
/// | |
/// <flt-semantics aria-label="Hello, World!"></flt-semantics> | |
final class AriaLabelRepresentation extends LabelRepresentationBehavior { | |
- AriaLabelRepresentation._(super.owner); | |
+ AriaLabelRepresentation._(PrimaryRoleManager owner) : super(LabelRepresentation.ariaLabel, owner); | |
String? _previousLabel; | |
@@ -137,7 +158,7 @@ final class AriaLabelRepresentation extends LabelRepresentationBehavior { | |
/// no ARIA role set, or the role does not size the element, then the | |
/// [SizedSpanRepresentation] representation can be used. | |
final class DomTextRepresentation extends LabelRepresentationBehavior { | |
- DomTextRepresentation._(super.owner); | |
+ DomTextRepresentation._(PrimaryRoleManager owner) : super(LabelRepresentation.domText, owner); | |
DomText? _domText; | |
String? _previousLabel; | |
@@ -200,7 +221,7 @@ typedef _Measurement = ({ | |
/// Text scaling is used to control the size of the screen reader focus ring. | |
/// This is used for plain text nodes (e.g. paragraphs of text). | |
final class SizedSpanRepresentation extends LabelRepresentationBehavior { | |
- SizedSpanRepresentation._(super.owner) { | |
+ SizedSpanRepresentation._(PrimaryRoleManager owner) : super(LabelRepresentation.sizedSpan, owner) { | |
_domText.style | |
// `inline-block` is needed for two reasons: | |
// - It supports measuring the true size of the text. Pure `block` would | |
@@ -423,13 +444,9 @@ class LabelAndValue extends RoleManager { | |
: preferredRepresentation; | |
LabelRepresentationBehavior? representation = _representation; | |
- if (representation == null || representation.runtimeType != effectiveRepresentation.implementation) { | |
+ if (representation == null || representation.kind != effectiveRepresentation) { | |
representation?.cleanUp(); | |
- _representation = representation = switch (effectiveRepresentation) { | |
- LabelRepresentation.ariaLabel => AriaLabelRepresentation._(owner), | |
- LabelRepresentation.domText => DomTextRepresentation._(owner), | |
- LabelRepresentation.sizedSpan => SizedSpanRepresentation._(owner), | |
- }; | |
+ _representation = representation = effectiveRepresentation.createBehavior(owner); | |
} | |
return representation; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment