Skip to content

Commit

Permalink
fix: Follow aria-labelledby and aria-describedby if they point to ele…
Browse files Browse the repository at this point in the history
…ments in the same shadow root (#827)

* fix: fix co-located elements in shadow DOM

Partially addresses #768

* chore: fix prettier

* get rid of seemingly redundant "co-located" term

* add changeset

Co-authored-by: eps1lon <silbermann.sebastian@gmail.com>
  • Loading branch information
nolanlawson and eps1lon authored Apr 23, 2022
1 parent bc4c891 commit a1daca5
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/violet-cooks-promise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"dom-accessibility-api": patch
---

Follow aria-labelledby and aria-describedby if they point to elements in the same shadow root.
14 changes: 14 additions & 0 deletions sources/__tests__/accessible-description.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,17 @@ describe("wpt copies", () => {
testMarkup(markup, expectedAccessibleName)
);
});

describe("content in shadow DOM", () => {
it("works for aria-labelledby on elements in same shadow root", () => {
const container = renderIntoDocument("<div></div>");
const div = container.querySelector("div");
div.attachShadow({ mode: "open" }).innerHTML = `
<div id="theDescription">This is a button</div>
<button aria-describedby="theDescription">Click me</button>
`;

const button = div.shadowRoot.querySelector("button");
expect(computeAccessibleDescription(button)).toEqual("This is a button");
});
});
14 changes: 14 additions & 0 deletions sources/__tests__/accessible-name.js
Original file line number Diff line number Diff line change
Expand Up @@ -589,3 +589,17 @@ describe("options.hidden", () => {
);
});
});

describe("content in shadow DOM", () => {
it("works for aria-labelledby on elements in same shadow root", () => {
const container = renderIntoDocument("<div></div>");
const div = container.querySelector("div");
div.attachShadow({ mode: "open" }).innerHTML = `
<label id="theLabel">Type here</label>
<input type="text" aria-labelledby="theLabel">
`;

const input = div.shadowRoot.querySelector("input");
expect(computeAccessibleName(input)).toEqual("Type here");
});
});
7 changes: 6 additions & 1 deletion sources/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,13 @@ export function queryIdRefs(node: Node, attributeName: string): Element[] {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- safe due to hasAttribute check
const ids = node.getAttribute(attributeName)!.split(" ");

// Browsers that don't support shadow DOM won't have getRootNode
const root = node.getRootNode
? (node.getRootNode() as Document | ShadowRoot)
: node.ownerDocument;

return ids
.map((id) => node.ownerDocument.getElementById(id))
.map((id) => root.getElementById(id))
.filter(
(element: Element | null): element is Element => element !== null
// TODO: why does this not narrow?
Expand Down

0 comments on commit a1daca5

Please sign in to comment.