LibWeb: Support accessible-name computation for SVG elements

This change adds support for computing accessible names for SVG
elements, per the https://w3c.github.io/svg-aam/#mapping_additional_nd
spec requirements. Otherwise, without this change, accessible names for
SVG elements don’t get exposed as expected.
This commit is contained in:
sideshowbarker 2024-11-21 05:03:28 +09:00
parent 063cd68bf4
commit e48c45af43
No known key found for this signature in database
3 changed files with 113 additions and 4 deletions

View file

@ -51,6 +51,8 @@
#include <LibWeb/Namespace.h>
#include <LibWeb/Painting/Paintable.h>
#include <LibWeb/Painting/PaintableBox.h>
#include <LibWeb/SVG/SVGTitleElement.h>
#include <LibWeb/XLink/AttributeNames.h>
namespace Web::DOM {
@ -2354,11 +2356,25 @@ ErrorOr<String> Node::name_or_description(NameOrDescription target, Document con
// 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 && is<HTML::HTMLImageElement>(*element)) {
// TODO: 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.
if (role != ARIA::Role::presentation && role != ARIA::Role::none && is<HTML::HTMLImageElement>(*element))
return element->alternative_text().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.
// https://w3c.github.io/svg-aam/#mapping_additional_nd
Optional<String> title_element_text;
if (element->is_svg_element()) {
// If the current node has at least one direct child title element, select the appropriate title based on
// the language rules for the SVG specification, and return the title text alternative as a flat string.
element->for_each_child_of_type<SVG::SVGTitleElement>([&](SVG::SVGTitleElement const& title) mutable {
title_element_text = title.text_content();
return IterationDecision::Break;
});
if (title_element_text.has_value())
return title_element_text.value();
// If the current node is a link, and there was no child title element, but it has an xlink:title attribute,
// return the value of that attribute.
if (auto title_attribute = element->get_attribute_ns(Namespace::XLink, XLink::AttributeNames::title); title_attribute.has_value())
return title_attribute.value();
}
// 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:

View file

@ -0,0 +1,22 @@
Summary
Harness status: OK
Rerun
Found 12 tests
12 Pass
Details
Result Test Name MessagePass circle > title
Pass rect > title
Pass polygon > title
Pass g > title
Pass [xlink:title][href] > circle
Pass [xlink:title][href] > rect
Pass [xlink:title][href] > polygon
Pass [xlink:title][href] > g
Pass [xlink:title][xlink:href] > circle
Pass [xlink:title][xlink:href] > rect
Pass [xlink:title][xlink:href] > polygon
Pass [xlink:title][xlink:href] > g

View file

@ -0,0 +1,71 @@
<!doctype html>
<html>
<head>
<title>Name Comp: Host Language Label</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>
<h1>SVG-AAM: Label Tests</h1>
<p>Tests SVG-specific host language label rules (title element and xlink:title attr) in <a href="https://w3c.github.io/svg-aam/#mapping_additional_nd">SVG-AAM §8.1 Name and Description</a>, but note the open issues in <a href="https://github.com/w3c/svg-aam/issues/31">SVG-AAM #31</a>.
<h2>SVG * > title</h2>
<svg viewbox="0 0 300 100">
<circle cx="26" cy="26" r="25" data-expectedlabel="circle label" data-testname="circle > title" class="ex"><title>circle label</title></circle>
<rect x="60" y="1" width="50" height="50" data-expectedlabel="rect label" data-testname="rect > title" class="ex"><title>rect label</title></rect>
<polygon points="100,100 150,25 150,75 200,0" fill="none" stroke="black" data-expectedlabel="polygon label" data-testname="polygon > title" class="ex"><title>polygon label</title></polygon>
</svg><br>
<svg viewbox="0 0 200 90">
<g fill="white" stroke="green" stroke-width="5" data-expectedlabel="group label" data-testname="g > title" class="ex">
<title>group label</title>
<circle cx="40" cy="40" r="25" />
<circle cx="60" cy="60" r="25" />
</g>
</svg>
<br>
<h2>SVG a[xlink:title][href]</h2>
<svg viewbox="0 0 300 100">
<a href="#" data-expectedlabel="circle link label" xlink:title="circle link label" data-testname="[xlink:title][href] > circle" class="ex"><circle cx="26" cy="26" r="25"></circle></a>
<a href="#" data-expectedlabel="rect link label" xlink:title="rect link label" data-testname="[xlink:title][href] > rect" class="ex"><rect x="60" y="1" width="50" height="50"></rect></a>
<a href="#" data-expectedlabel="polygon link label" xlink:title="polygon link label" data-testname="[xlink:title][href] > polygon" class="ex"><polygon points="100,100 150,25 150,75 200,0" fill="none" stroke="black"></polygon></a>
</svg><br>
<svg viewbox="0 0 200 90">
<a href="#" data-expectedlabel="group link label" xlink:title="group link label" data-testname="[xlink:title][href] > g" class="ex">
<g fill="white" stroke="green" stroke-width="5">
<circle cx="40" cy="40" r="25" />
<circle cx="60" cy="60" r="25" />
</g>
</a>
</svg>
<br>
<h2>SVG a[xlink:title][xlink:href]:not([href])</h2>
<svg viewbox="0 0 300 100">
<a xlink:href="#" data-expectedlabel="circle link label" xlink:title="circle link label" data-testname="[xlink:title][xlink:href] > circle" class="ex"><circle cx="26" cy="26" r="25"></circle></a>
<a xlink:href="#" data-expectedlabel="rect link label" xlink:title="rect link label" data-testname="[xlink:title][xlink:href] > rect" class="ex"><rect x="60" y="1" width="50" height="50"></rect></a>
<a xlink:href="#" data-expectedlabel="polygon link label" xlink:title="polygon link label" data-testname="[xlink:title][xlink:href] > polygon" class="ex"><polygon points="100,100 150,25 150,75 200,0" fill="none" stroke="black"></polygon></a>
</svg><br>
<svg viewbox="0 0 200 90">
<a xlink:href="#" data-expectedlabel="group link label" xlink:title="group link label" data-testname="[xlink:title][xlink:href] > g" class="ex">
<g fill="white" stroke="green" stroke-width="5">
<circle cx="40" cy="40" r="25" />
<circle cx="60" cy="60" r="25" />
</g>
</a>
</svg>
<br>
<script>
AriaUtils.verifyLabelsBySelector(".ex");
</script>
</body>
</html>