mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-21 23:20:20 +00:00
Compare commits
3 commits
2450a28b0b
...
88ee33ed8b
Author | SHA1 | Date | |
---|---|---|---|
|
88ee33ed8b | ||
|
cf7b9dd2e6 | ||
|
48bbcb48ff |
7 changed files with 501 additions and 34 deletions
|
@ -1874,6 +1874,54 @@ void Element::invalidate_style_after_attribute_change(FlyString const& attribute
|
|||
invalidate_style(StyleInvalidationReason::ElementAttributeChange);
|
||||
}
|
||||
|
||||
bool Element::is_hidden() const
|
||||
{
|
||||
if (layout_node() == nullptr)
|
||||
return true;
|
||||
if ((layout_node() != nullptr) && (layout_node()->computed_values().visibility() == CSS::Visibility::Hidden || layout_node()->computed_values().visibility() == CSS::Visibility::Collapse || layout_node()->computed_values().content_visibility() == CSS::ContentVisibility::Hidden))
|
||||
return true;
|
||||
for (ParentNode const* self_or_ancestor = this; self_or_ancestor; self_or_ancestor = self_or_ancestor->parent_or_shadow_host()) {
|
||||
if (self_or_ancestor->is_element() && static_cast<DOM::Element const*>(self_or_ancestor)->aria_hidden() == "true")
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Element::has_hidden_ancestor() const
|
||||
{
|
||||
for (ParentNode const* self_or_ancestor = this; self_or_ancestor; self_or_ancestor = self_or_ancestor->parent_or_shadow_host()) {
|
||||
if (self_or_ancestor->is_element() && static_cast<DOM::Element const*>(self_or_ancestor)->is_hidden())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Element::is_referenced() const
|
||||
{
|
||||
bool is_referenced = false;
|
||||
if (id().has_value()) {
|
||||
this->root().for_each_in_inclusive_subtree_of_type<HTML::HTMLElement>([&](auto& element) {
|
||||
auto aria_data = MUST(Web::ARIA::AriaData::build_data(element));
|
||||
if (aria_data->aria_labelled_by_or_default().contains_slow(id().value())) {
|
||||
is_referenced = true;
|
||||
return TraversalDecision::Break;
|
||||
}
|
||||
return TraversalDecision::Continue;
|
||||
});
|
||||
}
|
||||
return is_referenced;
|
||||
}
|
||||
|
||||
bool Element::has_referenced_and_hidden_ancestor() const
|
||||
{
|
||||
for (auto const* ancestor = parent_or_shadow_host(); ancestor; ancestor = ancestor->parent_or_shadow_host()) {
|
||||
if (ancestor->is_element())
|
||||
if (auto const* element = static_cast<DOM::Element const*>(ancestor); element->is_referenced() && element->is_hidden())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/wai-aria-1.2/#tree_exclusion
|
||||
bool Element::exclude_from_accessibility_tree() const
|
||||
{
|
||||
|
|
|
@ -348,6 +348,12 @@ public:
|
|||
|
||||
virtual bool include_in_accessibility_tree() const override;
|
||||
|
||||
bool is_hidden() const;
|
||||
bool has_hidden_ancestor() const;
|
||||
|
||||
bool is_referenced() const;
|
||||
bool has_referenced_and_hidden_ancestor() const;
|
||||
|
||||
void enqueue_a_custom_element_upgrade_reaction(HTML::CustomElementDefinition& custom_element_definition);
|
||||
void enqueue_a_custom_element_callback_reaction(FlyString const& callback_name, GC::MarkedVector<JS::Value> arguments);
|
||||
|
||||
|
|
|
@ -2206,23 +2206,25 @@ ErrorOr<String> Node::name_or_description(NameOrDescription target, Document con
|
|||
if (is_element()) {
|
||||
auto const* element = static_cast<DOM::Element const*>(this);
|
||||
auto role = element->role_or_default();
|
||||
bool is_referenced = false;
|
||||
auto id = element->id();
|
||||
if (id.has_value()) {
|
||||
this->root().for_each_in_inclusive_subtree_of_type<HTML::HTMLElement>([&](auto& element) {
|
||||
auto aria_data = MUST(Web::ARIA::AriaData::build_data(element));
|
||||
if (aria_data->aria_labelled_by_or_default().contains_slow(id.value())) {
|
||||
is_referenced = true;
|
||||
return TraversalDecision::Break;
|
||||
}
|
||||
return TraversalDecision::Continue;
|
||||
});
|
||||
}
|
||||
// 2. Compute the text alternative for the current node:
|
||||
// A. If the current node is hidden and is not directly referenced by aria-labelledby or aria-describedby, nor directly referenced by a native host language text alternative element (e.g. label in HTML) or attribute, return the empty string.
|
||||
// FIXME: Check for references
|
||||
if (element->aria_hidden() == "true")
|
||||
return String {};
|
||||
|
||||
// A. Hidden Not Referenced: If the current node is hidden and is:
|
||||
// i. Not part of an aria-labelledby or aria-describedby traversal, where the node directly referenced by that
|
||||
// relation was hidden.
|
||||
// ii. Nor part of a native host language text alternative element (e.g. label in HTML) or attribute traversal,
|
||||
// where the root of that traversal was hidden.
|
||||
// Return the empty string.
|
||||
// NOTE: Nodes with CSS properties display:none, visibility:hidden, visibility:collapse or
|
||||
// content-visibility:hidden: They are considered hidden, as they match the guidelines "not perceivable" and
|
||||
// "explicitly hidden".
|
||||
//
|
||||
// AD-HOC: We don’t implement this step here — because strictly implementing this would cause us to return early
|
||||
// whenever encountering a node (element, actually) that “is hidden and is not directly referenced by
|
||||
// aria-labelledby or aria-describedby”, without traversing down through that element’s subtree to see if it has
|
||||
// (1) any descendant elements that are directly referenced and/or (2) any un-hidden nodes. So we instead (in
|
||||
// substep G below) traverse upward through ancestor nodes of every text node, and check in that way to do the
|
||||
// equivalent of what this step seems to have been intended to do.
|
||||
|
||||
// B. Otherwise:
|
||||
// - if computing a name, and the current node has an aria-labelledby attribute that contains at least one valid IDREF, and the current node is not already part of an aria-labelledby traversal,
|
||||
// process its IDREFs in the order they occur:
|
||||
|
@ -2265,13 +2267,31 @@ ErrorOr<String> Node::name_or_description(NameOrDescription target, Document con
|
|||
total_accumulated_text.append(result);
|
||||
}
|
||||
// iii. Return the accumulated text.
|
||||
// AD-HOC: This substep in the spec doesn’t seem to explicitly require the following check for an aria-label
|
||||
// value; but the “button's hidden referenced name (visibility:hidden) with hidden aria-labelledby traversal
|
||||
// falls back to aria-label” subtest at https://wpt.fyi/results/accname/name/comp_labelledby.html won’t pass
|
||||
// unless we do this check.
|
||||
if (total_accumulated_text.to_string().value().bytes_as_string_view().is_whitespace() && target == NameOrDescription::Name && element->aria_label().has_value() && !element->aria_label()->is_empty() && !element->aria_label()->bytes_as_string_view().is_whitespace())
|
||||
return element->aria_label().value();
|
||||
return total_accumulated_text.to_string();
|
||||
}
|
||||
// C. Embedded Control: Otherwise, if the current node is a control embedded
|
||||
// within the label (e.g. any element directly referenced by aria-labelledby) for
|
||||
// another widget, where the user can adjust the embedded control's value, then
|
||||
// return the embedded control as part of the text alternative in the following
|
||||
// manner:
|
||||
|
||||
// D. AriaLabel: Otherwise, if the current node has an aria-label attribute whose value is not undefined, not
|
||||
// the empty string, nor, when trimmed of whitespace, is not the empty string:
|
||||
// AD-HOC: We’ve reordered substeps C and D from https://w3c.github.io/accname/#step2 — because
|
||||
// the more-specific per-HTML-element requirements at https://w3c.github.io/html-aam/#accname-computation
|
||||
// necessitate doing so, and the “input with label for association is superceded by aria-label” subtest at
|
||||
// https://wpt.fyi/results/accname/name/comp_label.html won’t pass unless we do this reordering.
|
||||
// Spec PR: https://github.com/w3c/aria/pull/2377
|
||||
if (target == NameOrDescription::Name && element->aria_label().has_value() && !element->aria_label()->is_empty() && !element->aria_label()->bytes_as_string_view().is_whitespace()) {
|
||||
// TODO: - If traversal of the current node is due to recursion and the current node is an embedded control as defined in step 2E, ignore aria-label and skip to rule 2E.
|
||||
// - Otherwise, return the value of aria-label.
|
||||
return element->aria_label().value();
|
||||
}
|
||||
|
||||
// C. Embedded Control: Otherwise, if the current node is a control embedded within the label (e.g. any element
|
||||
// directly referenced by aria-labelledby) for another widget, where the user can adjust the embedded control's
|
||||
// value, then return the embedded control as part of the text alternative in the following manner:
|
||||
GC::Ptr<DOM::NodeList> labels;
|
||||
if (is<HTML::HTMLElement>(this))
|
||||
labels = (const_cast<HTML::HTMLElement&>(static_cast<HTML::HTMLElement const&>(*current_node))).labels();
|
||||
|
@ -2341,15 +2361,6 @@ ErrorOr<String> Node::name_or_description(NameOrDescription target, Document con
|
|||
return builder.to_string();
|
||||
}
|
||||
|
||||
// D. AriaLabel: Otherwise, if the current node has an aria-label attribute whose
|
||||
// value is not undefined, not the empty string, nor, when trimmed of whitespace,
|
||||
// is not the empty string:
|
||||
if (target == NameOrDescription::Name && element->aria_label().has_value() && !element->aria_label()->is_empty() && !element->aria_label()->bytes_as_string_view().is_whitespace()) {
|
||||
// TODO: - If traversal of the current node is due to recursion and the current node is an embedded control as defined in step 2E, ignore aria-label and skip to rule 2E.
|
||||
// - Otherwise, return the value of aria-label.
|
||||
return element->aria_label().value();
|
||||
}
|
||||
|
||||
// E. Host Language Label: Otherwise, if the current node's native markup provides an attribute (e.g. alt) or
|
||||
// element (e.g. HTML label or SVG title) that defines a text alternative, return that alternative in the form
|
||||
// of a flat string as defined by the host language, unless the element is marked as presentational
|
||||
|
@ -2361,8 +2372,10 @@ ErrorOr<String> Node::name_or_description(NameOrDescription target, Document con
|
|||
// with the spec requirements — and if not, then add handling for it here.
|
||||
}
|
||||
|
||||
// F. Otherwise, if the current node's role allows name from content, or if the current node is referenced by aria-labelledby, aria-describedby, or is a native host language text alternative element (e.g. label in HTML), or is a descendant of a native host language text alternative element:
|
||||
if ((role.has_value() && ARIA::allows_name_from_content(role.value())) || is_referenced || is_descendant == IsDescendant::Yes) {
|
||||
// F. Name From Content: Otherwise, if the current node's role allows name from content, or if the current node
|
||||
// is referenced by aria-labelledby, aria-describedby, or is a native host language text alternative element
|
||||
// (e.g. label in HTML), or is a descendant of a native host language text alternative element:
|
||||
if ((role.has_value() && ARIA::allows_name_from_content(role.value())) || element->is_referenced() || is_descendant == IsDescendant::Yes) {
|
||||
// i. Set the accumulated text to the empty string.
|
||||
total_accumulated_text.clear();
|
||||
// ii. Name From Generated Content: Check for CSS generated textual content associated with the current node and include
|
||||
|
@ -2427,13 +2440,24 @@ ErrorOr<String> Node::name_or_description(NameOrDescription target, Document con
|
|||
}
|
||||
|
||||
// G. Text Node: Otherwise, if the current node is a Text Node, return its textual contents.
|
||||
if (is_text()) {
|
||||
// AD-HOC: The spec doesn’t require ascending through the parent node and ancestor nodes of every text node we
|
||||
// reach — the way we’re doing there. But we implement it this way because the spec algorithm as written doesn’t
|
||||
// appear to achieve what it seems to be intended to achieve. Specifically, the spec algorithm as written doesn’t
|
||||
// cause traversal through element subtrees in way that’s necessary to check for descendants that are referenced by
|
||||
// aria-labelledby or aria-describedby and/or un-hidden. See the comment for substep A above.
|
||||
if (is_text() && (parent_element()->is_referenced() || !parent_element()->is_hidden() || !parent_element()->has_hidden_ancestor() || parent_element()->has_referenced_and_hidden_ancestor())) {
|
||||
if (layout_node() && layout_node()->is_text_node())
|
||||
return verify_cast<Layout::TextNode>(layout_node())->text_for_rendering();
|
||||
return text_content().value();
|
||||
}
|
||||
|
||||
// TODO: H. Otherwise, if the current node is a descendant of an element whose Accessible Name or Accessible Description is being computed, and contains descendants, proceed to 2F.i.
|
||||
// H. Otherwise, if the current node is a descendant of an element whose Accessible Name or Accessible Description
|
||||
// is being computed, and contains descendants, proceed to 2F.i.
|
||||
// AD-HOC: We don’t implement this step here — because is essentially unreachable code in the spec algorithm.
|
||||
// We could never get here without descending through every subtree of an element whose Accessible Name or
|
||||
// Accessible Description is being computed. And in our implementation of substep F about, we’re anyway already
|
||||
// recursively descending through all the child nodes of every element whose Accessible Name or Accessible
|
||||
// Description is being computed, in a way that never leads to this substep H every being hit.
|
||||
|
||||
// I. Otherwise, if the current node has a Tooltip attribute, return its value.
|
||||
// https://www.w3.org/TR/accname-1.2/#dfn-tooltip-attribute
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 5 tests
|
||||
|
||||
5 Pass
|
||||
Details
|
||||
Result Test Name MessagePass button containing a rendered, unreferenced element that is aria-hidden=true, an unreferenced element with the hidden host language attribute, and an unreferenced element that is unconditionally rendered
|
||||
Pass button labelled by element that is aria-hidden=true
|
||||
Pass button labelled by element with the hidden host language attribute
|
||||
Pass link labelled by elements with assorted visibility and a11y tree exposure
|
||||
Pass heading with name from content, containing element that is visibility:hidden with nested content that is visibility:visible
|
|
@ -0,0 +1,37 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 27 tests
|
||||
|
||||
27 Pass
|
||||
Details
|
||||
Result Test Name MessagePass button with aria-labelledby using display:none hidden span (with nested span)
|
||||
Pass button with aria-labelledby using display:none hidden span (with nested spans, depth 2)
|
||||
Pass button with aria-labelledby using span without display:none (with nested display:none spans, depth 2)
|
||||
Pass button with aria-labelledby using display:none hidden span (with nested sibling spans)
|
||||
Pass button with aria-labelledby using span without display:none (with nested display:none sibling spans)
|
||||
Pass button with aria-labelledby using span with display:none (with nested display:inline sibling spans)
|
||||
Pass button with aria-labelledby using visibility:hidden span (with nested span)
|
||||
Pass button with aria-labelledby using visibility:hidden span (with nested spans, depth 2)
|
||||
Pass button with aria-labelledby using span without visibility:hidden (with nested visibility:hidden spans, depth 2)
|
||||
Pass button with aria-labelledby using visibility:hidden hidden span (with nested sibling spans)
|
||||
Pass button with aria-labelledby using span without visibility:hidden (with nested visibility:hidden sibling spans)
|
||||
Pass button with aria-labelledby using span with visibility:hidden (with nested visibility:visible sibling spans)
|
||||
Pass button with aria-labelledby using visibility:collapse span (with nested span)
|
||||
Pass button with aria-labelledby using visibility:collapse span (with nested spans, depth 2)
|
||||
Pass button with aria-labelledby using span without visibility:collapse (with nested visibility:visible spans, depth 2)
|
||||
Pass button with aria-labelledby using visibility:collapse span (with nested sibling spans)
|
||||
Pass button with aria-labelledby using span without visibility:collapse (with nested visibility:collapse sibling spans)
|
||||
Pass button with aria-labelledby using span with visibility:collapse (with nested visible sibling spans)
|
||||
Pass button with aria-labelledby using aria-hidden span (with nested span)
|
||||
Pass button with aria-labelledby using aria-hidden span (with nested spans, depth 2)
|
||||
Pass button with aria-labelledby using span without aria-hidden (with nested aria-hidden spans, depth 2)
|
||||
Pass button with aria-labelledby using aria-hidden hidden span (with nested sibling spans)
|
||||
Pass button with aria-labelledby using HTML5 hidden span (with nested span)
|
||||
Pass button with aria-labelledby using HTML5 hidden span (with nested spans, depth 2)
|
||||
Pass button with aria-labelledby using span without HTML5 hidden (with nested HTML5 hidden spans, depth 2)
|
||||
Pass button with aria-labelledby using HTML5 hidden span (with nested hidden sibling spans)
|
||||
Pass button with aria-labelledby using span without HTML5 hidden (with nested hidden sibling spans)
|
|
@ -0,0 +1,92 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Name Comp: Hidden Not Referenced</title>
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<script src="../../resources/testdriver.js"></script>
|
||||
<script src="../../resources/testdriver-vendor.js"></script>
|
||||
<script src="../../resources/testdriver-actions.js"></script>
|
||||
<script src="../../wai-aria/scripts/aria-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p>Tests the <a href="https://w3c.github.io/accname/#comp_hidden_not_referenced">#comp_hidden_not_referenced</a> portions of the AccName <em>Name Computation</em> algorithm.</p>
|
||||
|
||||
<button
|
||||
class="ex"
|
||||
data-expectedlabel="visible to all users"
|
||||
data-testname="button containing a rendered, unreferenced element that is aria-hidden=true, an unreferenced element with the hidden host language attribute, and an unreferenced element that is unconditionally rendered"
|
||||
>
|
||||
<span aria-hidden="true">hidden,</span>
|
||||
<span hidden>hidden from all users,</span>
|
||||
<span>visible to all users</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="ex"
|
||||
data-expectedlabel="hidden but referenced,"
|
||||
data-testname="button labelled by element that is aria-hidden=true"
|
||||
aria-labelledby="button-label-2"
|
||||
>
|
||||
<span aria-hidden="true" id="button-label-2">hidden but referenced,</span>
|
||||
<span hidden>hidden from all users,</span>
|
||||
<span>visible to all users</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="ex"
|
||||
data-expectedlabel="hidden from all users but referenced,"
|
||||
data-testname="button labelled by element with the hidden host language attribute"
|
||||
aria-labelledby="button-label-3"
|
||||
>
|
||||
<span aria-hidden="true">hidden,</span>
|
||||
<span hidden id="button-label-3">hidden from all users but referenced,</span>
|
||||
<span>visible to all users</span>
|
||||
</button>
|
||||
|
||||
<a
|
||||
class="ex"
|
||||
data-testname="link labelled by elements with assorted visibility and a11y tree exposure"
|
||||
data-expectedlabel="visible to all users, hidden but referenced, hidden from all users but referenced"
|
||||
href="#"
|
||||
aria-labelledby="link-label-1a link-label-1b link-label-1c"
|
||||
>
|
||||
<span id="link-label-1a">
|
||||
<span>visible to all users,</span>
|
||||
<span aria-hidden="true">hidden,</span>
|
||||
</span>
|
||||
<span aria-hidden="true" id="link-label-1b">hidden but referenced,</span>
|
||||
<span hidden id="link-label-1c">hidden from all users but referenced</span>
|
||||
</a>
|
||||
|
||||
<h2
|
||||
class="ex"
|
||||
data-testname="heading with name from content, containing element that is visibility:hidden with nested content that is visibility:visible"
|
||||
data-expectedlabel="visible to all users, un-hidden for all users"
|
||||
>
|
||||
visible to all users,
|
||||
<span style="visibility: hidden;">
|
||||
hidden from all users,
|
||||
<span style="visibility: visible;">un-hidden for all users</span>
|
||||
</span>
|
||||
</h2>
|
||||
|
||||
<!-- TODO: Test cases once https://github.com/w3c/aria/issues/1256 resolved: -->
|
||||
<!-- - button labelled by an element that is aria-hidden=true which contains a nested child that is aria-hidden=false -->
|
||||
<!-- - button labelled by an element that is aria-hidden=false which belongs to a parent that is aria-hidden=true -->
|
||||
<!-- - heading with name from content, containing rendered content that is aria-hidden=true with nested, rendered content that is aria-hidden=false -->
|
||||
<!-- - heading with name from content, containing element with the hidden host language attribute with nested content that is aria-hidden=false -->
|
||||
|
||||
<!-- TODO: New test case?
|
||||
<!-- What is the expectation for a details element when it’s given an -->
|
||||
<!-- explicit role that allows name from contents (e.g., `comment`) -->
|
||||
<!-- but is also not in the open state, and therefore has contents -->
|
||||
<!-- that are both not rendered and excluded from the a11y tree. -->
|
||||
|
||||
<script>
|
||||
AriaUtils.verifyLabelsBySelector(".ex");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,245 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Name Comp: Labelledby & Hidden Nodes</title>
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<script src="../../resources/testdriver.js"></script>
|
||||
<script src="../../resources/testdriver-vendor.js"></script>
|
||||
<script src="../../resources/testdriver-actions.js"></script>
|
||||
<script src="../../wai-aria/scripts/aria-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p>Tests hidden node name computation as part of the <a href="https://w3c.github.io/accname/#comp_labelledby">#comp_labelledby</a> portion of the AccName <em>Name Computation</em> algorithm.</p>
|
||||
|
||||
<!--
|
||||
|
||||
These tests verify browser conformance with the following note as part of accName computation Step 2B:
|
||||
|
||||
"The result of LabelledBy Recursion in combination with Hidden Not Referenced means
|
||||
that user agents MUST include all nodes in the subtree as part of
|
||||
the accessible name or accessible description, when the node referenced
|
||||
by aria-labelledby or aria-describedby is hidden."
|
||||
|
||||
-->
|
||||
|
||||
<h2>Testing with <code>display:none</code></h2>
|
||||
|
||||
<button aria-labelledby="a11" data-expectedlabel="foo bar" data-testname="button with aria-labelledby using display:none hidden span (with nested span)" class="ex">x</button>
|
||||
<span id="a11" style="display: none;">
|
||||
foo
|
||||
<span id="a12">bar</span>
|
||||
</span>
|
||||
|
||||
<button aria-labelledby="a21" data-expectedlabel="foo bar baz" data-testname="button with aria-labelledby using display:none hidden span (with nested spans, depth 2)" class="ex">x</button>
|
||||
<span id="a21" style="display: none;">
|
||||
foo
|
||||
<span id="a22">
|
||||
bar
|
||||
<span id="a23">baz</span>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<button aria-labelledby="a31" data-expectedlabel="foo" data-testname="button with aria-labelledby using span without display:none (with nested display:none spans, depth 2)" class="ex">x</button>
|
||||
<span id="a31">
|
||||
foo
|
||||
<span id="a32" style="display: none;">
|
||||
bar
|
||||
<span id="a33">baz</span>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<button aria-labelledby="a41" data-expectedlabel="foo bar baz" data-testname="button with aria-labelledby using display:none hidden span (with nested sibling spans)" class="ex">x</button>
|
||||
<span id="a41" style="display: none;">
|
||||
foo
|
||||
<span id="a42">bar</span>
|
||||
<span id="a43">baz</span>
|
||||
</span>
|
||||
|
||||
<button aria-labelledby="a51" data-expectedlabel="foo" data-testname="button with aria-labelledby using span without display:none (with nested display:none sibling spans)" class="ex">x</button>
|
||||
<span id="a51">
|
||||
foo
|
||||
<span id="a52" style="display: none;">bar</span>
|
||||
<span id="a53" style="display: none;">baz</span>
|
||||
</span>
|
||||
|
||||
<button aria-labelledby="a61" data-expectedlabel="foo bar baz" data-testname="button with aria-labelledby using span with display:none (with nested display:inline sibling spans)" class="ex">x</button>
|
||||
<span id="a61" style="display: none;">
|
||||
foo
|
||||
<span id="a62" style="display: inline;">bar</span>
|
||||
<span id="a63" style="display: inline;">baz</span>
|
||||
</span>
|
||||
|
||||
<h2>Testing with <code>visibility:hidden</code></h2>
|
||||
|
||||
<button aria-labelledby="b11" data-expectedlabel="foo bar" data-testname="button with aria-labelledby using visibility:hidden span (with nested span)" class="ex">x</button>
|
||||
<span id="b11" style="visibility: hidden;">
|
||||
foo
|
||||
<span id="b12">bar</span>
|
||||
</span>
|
||||
|
||||
<button aria-labelledby="b21" data-expectedlabel="foo bar baz" data-testname="button with aria-labelledby using visibility:hidden span (with nested spans, depth 2)" class="ex">x</button>
|
||||
<span id="b21" style="visibility: hidden;">
|
||||
foo
|
||||
<span id="b22">
|
||||
bar
|
||||
<span id="b23">baz</span>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<button aria-labelledby="b31" data-expectedlabel="foo" data-testname="button with aria-labelledby using span without visibility:hidden (with nested visibility:hidden spans, depth 2)" class="ex">x</button>
|
||||
<span id="b31">
|
||||
foo
|
||||
<span id="b32" style="visibility: hidden;">
|
||||
bar
|
||||
<span id="b33">baz</span>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<button aria-labelledby="b41" data-expectedlabel="foo bar baz" data-testname="button with aria-labelledby using visibility:hidden hidden span (with nested sibling spans)" class="ex">x</button>
|
||||
<span id="b41" style="visibility: hidden;">
|
||||
foo
|
||||
<span id="b42">bar</span>
|
||||
<span id="b43">baz</span>
|
||||
</span>
|
||||
|
||||
<button aria-labelledby="b51" data-expectedlabel="foo" data-testname="button with aria-labelledby using span without visibility:hidden (with nested visibility:hidden sibling spans)" class="ex">x</button>
|
||||
<span id="b51">
|
||||
foo
|
||||
<span id="b52" style="visibility: hidden;">bar</span>
|
||||
<span id="b53" style="visibility: hidden;">baz</span>
|
||||
</span>
|
||||
|
||||
<button aria-labelledby="b61" data-expectedlabel="foo bar baz" data-testname="button with aria-labelledby using span with visibility:hidden (with nested visibility:visible sibling spans)" class="ex">x</button>
|
||||
<span id="b61" style="visibility: hidden;">
|
||||
foo
|
||||
<span id="b62" style="visibility: visible;">bar</span>
|
||||
<span id="b63" style="visibility: visible;">baz</span>
|
||||
</span>
|
||||
|
||||
<h2>Testing with <code>visibility:collapse</code></h2>
|
||||
|
||||
<button aria-labelledby="c11" data-expectedlabel="foo bar" data-testname="button with aria-labelledby using visibility:collapse span (with nested span)" class="ex">x</button>
|
||||
<span id="c11" style="visibility: collapse;">
|
||||
foo
|
||||
<span id="c12">bar</span>
|
||||
</span>
|
||||
|
||||
<button aria-labelledby="c21" data-expectedlabel="foo bar baz" data-testname="button with aria-labelledby using visibility:collapse span (with nested spans, depth 2)" class="ex">x</button>
|
||||
<span id="c21" style="visibility: collapse;">
|
||||
foo
|
||||
<span id="c22">
|
||||
bar
|
||||
<span id="c23">baz</span>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<button aria-labelledby="c31" data-expectedlabel="foo bar baz" data-testname="button with aria-labelledby using span without visibility:collapse (with nested visibility:visible spans, depth 2)" class="ex">x</button>
|
||||
<span id="c31">
|
||||
foo
|
||||
<span id="c32" style="visibility: visible;">
|
||||
bar
|
||||
<span id="c33" style="visibility: visible;">baz</span>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<button aria-labelledby="c41" data-expectedlabel="foo bar baz" data-testname="button with aria-labelledby using visibility:collapse span (with nested sibling spans)" class="ex">x</button>
|
||||
<span id="c41" style="visibility: collapse;">
|
||||
foo
|
||||
<span id="c42">bar</span>
|
||||
<span id="c43">baz</span>
|
||||
</span>
|
||||
|
||||
<button aria-labelledby="c51" data-expectedlabel="foo" data-testname="button with aria-labelledby using span without visibility:collapse (with nested visibility:collapse sibling spans)" class="ex">x</button>
|
||||
<span id="c51">
|
||||
foo
|
||||
<span id="c52" style="visibility: collapse;">bar</span>
|
||||
<span id="c53" style="visibility: collapse;">baz</span>
|
||||
</span>
|
||||
|
||||
<button aria-labelledby="c61" data-expectedlabel="foo bar baz" data-testname="button with aria-labelledby using span with visibility:collapse (with nested visible sibling spans)" class="ex">x</button>
|
||||
<span id="c61" style="visibility: collapse;">
|
||||
foo
|
||||
<span id="c62" style="visibility: visible;">bar</span>
|
||||
<span id="c63" style="visibility: visible;">baz</span>
|
||||
</span>
|
||||
|
||||
<h2>Testing with <code>aria-hidden</code></h2>
|
||||
|
||||
<button aria-labelledby="d11" data-expectedlabel="foo bar" data-testname="button with aria-labelledby using aria-hidden span (with nested span)" class="ex">x</button>
|
||||
<span id="d11" aria-hidden="true">
|
||||
foo
|
||||
<span id="d12">bar</span>
|
||||
</span>
|
||||
|
||||
<button aria-labelledby="d21" data-expectedlabel="foo bar baz" data-testname="button with aria-labelledby using aria-hidden span (with nested spans, depth 2)" class="ex">x</button>
|
||||
<span id="d21" aria-hidden="true">
|
||||
foo
|
||||
<span id="d22">
|
||||
bar
|
||||
<span id="d23">baz</span>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<button aria-labelledby="d31" data-expectedlabel="foo" data-testname="button with aria-labelledby using span without aria-hidden (with nested aria-hidden spans, depth 2)" class="ex">x</button>
|
||||
<span id="d31">
|
||||
foo
|
||||
<span id="d32" aria-hidden="true">
|
||||
bar
|
||||
<span id="d33">baz</span>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<button aria-labelledby="d41" data-expectedlabel="foo bar baz" data-testname="button with aria-labelledby using aria-hidden hidden span (with nested sibling spans)" class="ex">x</button>
|
||||
<span id="d41" aria-hidden="true">
|
||||
foo
|
||||
<span id="d42">bar</span>
|
||||
<span id="d43">baz</span>
|
||||
</span>
|
||||
|
||||
<h2>Testing with <code>hidden</code> attribute</h2>
|
||||
|
||||
<button aria-labelledby="e11" data-expectedlabel="foo bar" data-testname="button with aria-labelledby using HTML5 hidden span (with nested span)" class="ex">x</button>
|
||||
<span id="e11" hidden>
|
||||
foo
|
||||
<span id="e12">bar</span>
|
||||
</span>
|
||||
|
||||
<button aria-labelledby="e21" data-expectedlabel="foo bar baz" data-testname="button with aria-labelledby using HTML5 hidden span (with nested spans, depth 2)" class="ex">x</button>
|
||||
<span id="e21" hidden>
|
||||
foo
|
||||
<span id="e22">
|
||||
bar
|
||||
<span id="e23">baz</span>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<button aria-labelledby="e31" data-expectedlabel="foo" data-testname="button with aria-labelledby using span without HTML5 hidden (with nested HTML5 hidden spans, depth 2)" class="ex">x</button>
|
||||
<span id="e31">
|
||||
foo
|
||||
<span id="e32" hidden>
|
||||
bar
|
||||
<span id="e33">baz</span>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<button aria-labelledby="e41" data-expectedlabel="foo bar baz" data-testname="button with aria-labelledby using HTML5 hidden span (with nested hidden sibling spans)" class="ex">x</button>
|
||||
<span id="e41" hidden>
|
||||
foo
|
||||
<span id="e42">bar</span>
|
||||
<span id="e43">baz</span>
|
||||
</span>
|
||||
|
||||
<button aria-labelledby="e51" data-expectedlabel="foo" data-testname="button with aria-labelledby using span without HTML5 hidden (with nested hidden sibling spans)" class="ex">x</button>
|
||||
<span id="e51">
|
||||
foo
|
||||
<span id="e52" hidden>bar</span>
|
||||
<span id="e53" hidden>baz</span>
|
||||
</span>
|
||||
|
||||
<script>
|
||||
AriaUtils.verifyLabelsBySelector(".ex");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in a new issue