summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorJonah <jonahshafran@gmail.com>2022-12-11 10:53:37 -0600
committerSam Atkins <atkinssj@gmail.com>2023-01-07 10:51:53 +0000
commitcd95e5f65620679dee8ddfaee5542f624f35318a (patch)
tree3de6d3a419af77445ace62fa9e2b468571164ccc /Userland
parentef48bd1878479595241c81ad69c22a63aa18a669 (diff)
downloadserenity-cd95e5f65620679dee8ddfaee5542f624f35318a.zip
LibWeb: Add (exclude/include)_from_accessibility_tree
These functions will be used in building the accessibility tree.
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Libraries/LibWeb/DOM/ARIAMixin.h6
-rw-r--r--Userland/Libraries/LibWeb/DOM/Element.cpp59
-rw-r--r--Userland/Libraries/LibWeb/DOM/Element.h4
3 files changed, 69 insertions, 0 deletions
diff --git a/Userland/Libraries/LibWeb/DOM/ARIAMixin.h b/Userland/Libraries/LibWeb/DOM/ARIAMixin.h
index a894ccbd5a..ec93ecb036 100644
--- a/Userland/Libraries/LibWeb/DOM/ARIAMixin.h
+++ b/Userland/Libraries/LibWeb/DOM/ARIAMixin.h
@@ -136,6 +136,12 @@ public:
FlyString role_or_default() const;
+ // https://www.w3.org/TR/wai-aria-1.2/#tree_exclusion
+ virtual bool exclude_from_accessibility_tree() const = 0;
+
+ // https://www.w3.org/TR/wai-aria-1.2/#tree_inclusion
+ virtual bool include_in_accessibility_tree() const = 0;
+
bool has_global_aria_attribute() const;
protected:
diff --git a/Userland/Libraries/LibWeb/DOM/Element.cpp b/Userland/Libraries/LibWeb/DOM/Element.cpp
index c628bab7c2..a7c4e4b085 100644
--- a/Userland/Libraries/LibWeb/DOM/Element.cpp
+++ b/Userland/Libraries/LibWeb/DOM/Element.cpp
@@ -1267,4 +1267,63 @@ void Element::invalidate_style_after_attribute_change(FlyString const& attribute
invalidate_style();
}
+// https://www.w3.org/TR/wai-aria-1.2/#tree_exclusion
+bool Element::exclude_from_accessibility_tree() const
+{
+ // The following elements are not exposed via the accessibility API and user agents MUST NOT include them in the accessibility tree:
+
+ // Elements, including their descendent elements, that have host language semantics specifying that the element is not displayed, such as CSS display:none, visibility:hidden, or the HTML hidden attribute.
+ if (!layout_node())
+ return true;
+
+ // Elements with none or presentation as the first role in the role attribute. However, their exclusion is conditional. In addition, the element's descendants and text content are generally included. These exceptions and conditions are documented in the presentation (role) section.
+ // FIXME: Handle exceptions to excluding presentation role
+ auto role = role_or_default().to_lowercase();
+ if (role == ARIARoleNames::none || role == ARIARoleNames::presentation)
+ return true;
+
+ // TODO: If not already excluded from the accessibility tree per the above rules, user agents SHOULD NOT include the following elements in the accessibility tree:
+ // Elements, including their descendants, that have aria-hidden set to true. In other words, aria-hidden="true" on a parent overrides aria-hidden="false" on descendants.
+ // Any descendants of elements that have the characteristic "Children Presentational: True" unless the descendant is not allowed to be presentational because it meets one of the conditions for exception described in Presentational Roles Conflict Resolution. However, the text content of any excluded descendants is included.
+ // Elements with the following roles have the characteristic "Children Presentational: True":
+ // button
+ // checkbox
+ // img
+ // menuitemcheckbox
+ // menuitemradio
+ // meter
+ // option
+ // progressbar
+ // radio
+ // scrollbar
+ // separator
+ // slider
+ // switch
+ // tab
+ return false;
+}
+
+// https://www.w3.org/TR/wai-aria-1.2/#tree_inclusion
+bool Element::include_in_accessibility_tree() const
+{
+ // If not excluded from or marked as hidden in the accessibility tree per the rules above in Excluding Elements in the Accessibility Tree, user agents MUST provide an accessible object in the accessibility tree for DOM elements that meet any of the following criteria:
+ if (exclude_from_accessibility_tree())
+ return false;
+ // Elements that are not hidden and may fire an accessibility API event, including:
+ // Elements that are currently focused, even if the element or one of its ancestor elements has its aria-hidden attribute set to true.
+ if (is_focused())
+ return true;
+ // TODO: Elements that are a valid target of an aria-activedescendant attribute.
+
+ // Elements that have an explicit role or a global WAI-ARIA attribute and do not have aria-hidden set to true. (See Excluding Elements in the Accessibility Tree for additional guidance on aria-hidden.)
+ // NOTE: The spec says only explicit roles count, but playing around in other browsers, this does not seem to be true in practice (for example button elements are always exposed with their implicit role if none is set)
+ // This issue https://github.com/w3c/aria/issues/1851 seeks clarification on this point
+ if ((!role_or_default().is_empty() || has_global_aria_attribute()) && aria_hidden() != "true")
+ return true;
+
+ // TODO: Elements that are not hidden and have an ID that is referenced by another element via a WAI-ARIA property.
+
+ return false;
+}
+
}
diff --git a/Userland/Libraries/LibWeb/DOM/Element.h b/Userland/Libraries/LibWeb/DOM/Element.h
index a31d9f2343..1792a32fc7 100644
--- a/Userland/Libraries/LibWeb/DOM/Element.h
+++ b/Userland/Libraries/LibWeb/DOM/Element.h
@@ -245,6 +245,10 @@ public:
#undef ARIA_IMPL
+ virtual bool exclude_from_accessibility_tree() const override;
+
+ virtual bool include_in_accessibility_tree() const override;
+
protected:
Element(Document&, DOM::QualifiedName);
virtual void initialize(JS::Realm&) override;