Skip to content

Commit

Permalink
Include shadow DOM in name from content (#1470)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jym77 committed Sep 8, 2023
1 parent 5a29e0a commit 4f23124
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 2 deletions.
7 changes: 7 additions & 0 deletions .changeset/nine-yaks-grow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@siteimprove/alfa-aria": patch
---

**Fixed:** Name from content now correctly includes shadow DOM.

When the accessible name is computed from the descendants, slots and descendants inside a shadow DOM are correctly taken into account. This mimic what browsers are doing, and what the accessible name conputation group seems to be moving toward.
4 changes: 2 additions & 2 deletions packages/alfa-aria/src/name.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ export namespace Name {
public toJSON(): Descendant.JSON {
return {
type: "descendant",
element: this._element.path(),
element: this._element.path(Node.flatTree),
name: this._name.toJSON(),
};
}
Expand Down Expand Up @@ -823,7 +823,7 @@ export namespace Name {
state: State
): Option<Name> {
const names: Sequence<readonly [string, Name]> = element
.children()
.children(Node.flatTree)
.filter(or(isText, isElement))
.collect((element) =>
fromNode(element, device, state.recurse(true).descend(true)).map(
Expand Down
87 changes: 87 additions & 0 deletions packages/alfa-aria/test/name.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1659,3 +1659,90 @@ test(`.from() only associates <label> elements with for attributes with the

t.deepEqual(Name.from(bar, device).toJSON(), { type: "none" });
});

test(".from() looks for slotted descendants", (t) => {
const target = (
<button>
<slot name="content"></slot>
</button>
);

const _ = (
<div>
{h.shadow([target])}
<span slot="content">Hello</span>
</div>
);

t.deepEqual(getName(target), {
value: "Hello",
sources: [
{
element: "/div[1]/button[1]",
name: {
sources: [
{
element: "/div[1]/button[1]/span[1]",
name: {
sources: [{ text: "/div[1]/span[1]/text()[1]", type: "data" }],
value: "Hello",
},
type: "descendant",
},
],
value: "Hello",
},
type: "descendant",
},
],
});
});

test(".from() looks for shadow descendants", (t) => {
const target = (
<button>
{h.shadow([<slot name="content"></slot>])}
<span slot="content">Hello</span>
</button>
);

t.deepEqual(getName(target), {
value: "Hello",
sources: [
{
element: "/button[1]",
name: {
sources: [
{
element: "/button[1]/slot[1]",
name: {
sources: [
{
element: "/button[1]/span[1]",
name: {
sources: [
{ text: "/button[1]/span[1]/text()[1]", type: "data" },
],
value: "Hello",
},
type: "descendant",
},
],
value: "Hello",
},
type: "descendant",
},
],
value: "Hello",
},
type: "descendant",
},
],
});
});

test(".from() does not recurse into content documents", (t) => {
const target = <button>{h.document([<span>Hello</span>])}</button>;

t.deepEqual(Name.from(target, Device.standard()).isNone(), true);
});

0 comments on commit 4f23124

Please sign in to comment.