mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-21 23:20:20 +00:00
LibWeb: Fix accessible-name computation for “tooltip” & empty-alt cases
This change fixes accessible-name computation for: - an element that has empty text content but that also has a title attribute (“tooltip”) with a non-empty value - an img element whose alt attribute is the empty string but that also has a “title” attribute with a non-empty value Otherwise, without this change, the accessible name unexpectedly isn’t computed correctly for those cases.
This commit is contained in:
parent
4ae1bca67d
commit
3594cdf948
Notes:
github-actions[bot]
2024-11-09 13:09:02 +00:00
Author: https://github.com/sideshowbarker Commit: https://github.com/LadybirdBrowser/ladybird/commit/3594cdf9486 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2209 Reviewed-by: https://github.com/trflynn89
3 changed files with 122 additions and 5 deletions
|
@ -0,0 +1,33 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 23 tests
|
||||
|
||||
23 Pass
|
||||
Details
|
||||
Result Test Name MessagePass link with img with tooltip label
|
||||
Pass link with text with tooltip label and no contents
|
||||
Pass link with text with tooltip label and contents
|
||||
Pass div with text with tooltip label
|
||||
Pass img with tooltip label without alt
|
||||
Pass img with tooltip label with empty alt
|
||||
Pass img with tooltip label with alt
|
||||
Pass img with tooltip label without title
|
||||
Pass select with tooltip label
|
||||
Pass button with tooltip label
|
||||
Pass checkbox input with tooltip label
|
||||
Pass radio input with tooltip label
|
||||
Pass text input with placeholder and tooltip label
|
||||
Pass password input with placeholder and tooltip label
|
||||
Pass number input with placeholder and tooltip label
|
||||
Pass search input with placeholder and tooltip label
|
||||
Pass tel input with placeholder and tooltip label
|
||||
Pass email input with placeholder and tooltip label
|
||||
Pass url input with placeholder and tooltip label
|
||||
Pass textarea with placeholder and tooltip label
|
||||
Pass abbr with tooltip label
|
||||
Pass summary with tooltip label and contents
|
||||
Pass iframe with tooltip label
|
|
@ -0,0 +1,70 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Name Comp: Tooltip</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_tooltip">#comp_tooltip</a> portions of the AccName <em>Name Computation</em> algorithm.</p>
|
||||
|
||||
<a href="#" title="title" data-expectedlabel="title" data-testname="link with img with tooltip label" class="ex"><img alt="" src="data:image/gif;base65,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="></a>
|
||||
<a href="#" title="title" data-expectedlabel="title" data-testname="link with text with tooltip label and no contents" class="ex"></a>
|
||||
<a href="#" title="title" data-expectedlabel="contents" data-testname="link with text with tooltip label and contents" class="ex">contents</a>
|
||||
<div title="title" role="group" data-expectedlabel="title" data-testname="div with text with tooltip label" class="ex">contents</div><!-- Note: group role disallows nameFrom:contents -->
|
||||
<img title="title" data-expectedlabel="title" data-testname="img with tooltip label without alt" class="ex" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==">
|
||||
<img title="title" data-expectedlabel="title" alt="" data-testname="img with tooltip label with empty alt" class="ex" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==">
|
||||
<img title="title" data-expectedlabel="alt" alt="alt" data-testname="img with tooltip label with alt" class="ex" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==">
|
||||
<img data-expectedlabel="alt" alt="alt" data-testname="img with tooltip label without title" class="ex" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==">
|
||||
|
||||
<select title="title" data-expectedlabel="title" data-testname="select with tooltip label" class="ex">
|
||||
<option value="" disabled selected>select options</option>
|
||||
<option value="1">option 1</option>
|
||||
<option value="2">option 2</option>
|
||||
<option value="3">option 3</option>
|
||||
</select>
|
||||
|
||||
|
||||
<!-- TODO: Move these: https://github.com/web-platform-tests/interop-accessibility/issues/78 -->
|
||||
<button title="title" data-expectedlabel="contents" data-testname="button with tooltip label" class="ex">contents</button>
|
||||
<input type="checkbox" title="title" data-expectedlabel="title" data-testname="checkbox input with tooltip label" class="ex">
|
||||
<input type="radio" title="title" data-expectedlabel="title" data-testname="radio input with tooltip label" class="ex">
|
||||
|
||||
<!-- TODO: Move these: https://github.com/web-platform-tests/interop-accessibility/issues/78 -->
|
||||
<!-- https://w3c.github.io/html-aam/#input-type-text-input-type-password-input-type-number-input-type-search-input-type-tel-input-type-email-input-type-url-and-textarea-element-accessible-name-computation -->
|
||||
<input type="text" title="title" data-expectedlabel="title" placeholder="placeholder" data-testname="text input with placeholder and tooltip label" class="ex">
|
||||
<input type="password" title="title" data-expectedlabel="title" placeholder="placeholder" data-testname="password input with placeholder and tooltip label" class="ex">
|
||||
<input type="number" title="title" data-expectedlabel="title" placeholder="placeholder" data-testname="number input with placeholder and tooltip label" class="ex">
|
||||
<input type="search" title="title" data-expectedlabel="title" placeholder="placeholder" data-testname="search input with placeholder and tooltip label" class="ex">
|
||||
<input type="tel" title="title" data-expectedlabel="title" placeholder="placeholder" data-testname="tel input with placeholder and tooltip label" class="ex">
|
||||
<input type="email" title="title" data-expectedlabel="title" placeholder="placeholder" data-testname="email input with placeholder and tooltip label" class="ex">
|
||||
<input type="url" title="title" data-expectedlabel="title" placeholder="placeholder" data-testname="url input with placeholder and tooltip label" class="ex">
|
||||
<textarea title="title" data-expectedlabel="title" placeholder="placeholder" data-testname="textarea with placeholder and tooltip label" class="ex"></textarea>
|
||||
|
||||
<!-- TODO: Move these: https://github.com/web-platform-tests/interop-accessibility/issues/78 -->
|
||||
<!-- https://w3c.github.io/html-aam/#text-level-element-accessible-name-computation -->
|
||||
<abbr title="Web Platform Tests" data-expectedlabel="Web Platform Tests" data-testname="abbr with tooltip label" class="ex">WPT</abbr>
|
||||
<!-- kbd test disabled: see resolution at https://github.com/web-platform-tests/interop-accessibility/issues/131 -->
|
||||
<!-- <kbd title="Control + Option" data-expectedlabel="Control + Option" data-testname="kbd with tooltip label" class="ex">CTRL + OPT</kbd> -->
|
||||
|
||||
<!-- TODO: Move these: https://github.com/web-platform-tests/interop-accessibility/issues/78 -->
|
||||
<!-- https://w3c.github.io/html-aam/#summary-element-accessible-name-computation -->
|
||||
<details>
|
||||
<summary title="title" data-expectedlabel="contents" data-testname="summary with tooltip label and contents" class="ex">contents</summary>
|
||||
details
|
||||
</details>
|
||||
|
||||
<!-- TODO: Move these: https://github.com/web-platform-tests/interop-accessibility/issues/78 -->
|
||||
<!-- https://w3c.github.io/html-aam/#iframe-element-accessible-name-computation -->
|
||||
<iframe title="title" data-expectedlabel="title" data-testname="iframe with tooltip label" width="20px" height="20px" class="ex"></iframe>
|
||||
|
||||
<script>
|
||||
AriaUtils.verifyLabelsBySelector(".ex");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -34,6 +34,7 @@
|
|||
#include <LibWeb/DOM/StaticNodeList.h>
|
||||
#include <LibWeb/HTML/CustomElements/CustomElementReactionNames.h>
|
||||
#include <LibWeb/HTML/HTMLAnchorElement.h>
|
||||
#include <LibWeb/HTML/HTMLImageElement.h>
|
||||
#include <LibWeb/HTML/HTMLInputElement.h>
|
||||
#include <LibWeb/HTML/HTMLSelectElement.h>
|
||||
#include <LibWeb/HTML/HTMLSlotElement.h>
|
||||
|
@ -2188,6 +2189,7 @@ 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();
|
||||
// 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
|
||||
|
@ -2312,11 +2314,22 @@ ErrorOr<String> Node::name_or_description(NameOrDescription target, Document con
|
|||
// - Otherwise, return the value of aria-label.
|
||||
return element->aria_label().value();
|
||||
}
|
||||
// TODO: D. Otherwise, if the current node's native markup provides an attribute (e.g. title) or element (e.g. HTML label) 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 (role="presentation" or role="none").
|
||||
|
||||
// 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
|
||||
// (role="presentation" or role="none").
|
||||
if (role != ARIA::Role::presentation && role != ARIA::Role::none) {
|
||||
if (is<HTML::HTMLImageElement>(*element)) {
|
||||
if (auto alt = element->get_attribute(HTML::AttributeNames::alt); alt.has_value())
|
||||
return alt.release_value();
|
||||
}
|
||||
// TODO: Add handling for SVGTitleElement, and also confirm (through existing WPT test cases) whether
|
||||
// HTMLLabelElement is already handled (by the code for step C. “Embedded Control” above) in conformance
|
||||
// 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:
|
||||
auto role = element->role_or_default();
|
||||
if ((role.has_value() && ARIA::allows_name_from_content(role.value())) || is_descendant == IsDescendant::Yes) {
|
||||
// i. Set the accumulated text to the empty string.
|
||||
total_accumulated_text.clear();
|
||||
|
@ -2348,8 +2361,9 @@ ErrorOr<String> Node::name_or_description(NameOrDescription target, Document con
|
|||
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
// iv. Return the accumulated text.
|
||||
return total_accumulated_text.to_string();
|
||||
// v. Return the accumulated text if it is not the empty string ("").
|
||||
if (!total_accumulated_text.is_empty())
|
||||
return total_accumulated_text.to_string();
|
||||
// Important: Each node in the subtree is consulted only once. If text has been collected from a descendant, but is referenced by another IDREF in some descendant node, then that second, or subsequent, reference is not followed. This is done to avoid infinite loops.
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue