chore: remove the leaf node notion (#33249)

This commit is contained in:
Pavel Feldman 2024-10-23 17:34:21 -07:00 committed by GitHub
parent 24cafbc8cb
commit 9a0a6cec10
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 46 additions and 56 deletions

View file

@ -16,7 +16,7 @@
import { escapeWithQuotes } from '@isomorphic/stringUtils';
import * as roleUtils from './roleUtils';
import { isElementVisible, isElementStyleVisibilityVisible, getElementComputedStyle } from './domUtils';
import { getElementComputedStyle } from './domUtils';
import type { AriaRole } from './roleUtils';
type AriaProps = {
@ -29,7 +29,7 @@ type AriaProps = {
};
type AriaNode = AriaProps & {
role: AriaRole | 'fragment' | 'text';
role: AriaRole | 'fragment';
name: string;
children: (AriaNode | string)[];
};
@ -56,22 +56,10 @@ export function generateAriaTree(rootElement: Element): AriaNode {
if (roleUtils.isElementHiddenForAria(element))
return;
const visible = isElementVisible(element);
const hasVisibleChildren = isElementStyleVisibilityVisible(element);
if (!hasVisibleChildren)
return;
if (visible) {
const childAriaNode = toAriaNode(element);
const isHiddenContainer = childAriaNode && hiddenContainerRoles.has(childAriaNode.ariaNode.role);
if (childAriaNode && !isHiddenContainer)
ariaNode.children.push(childAriaNode.ariaNode);
if (isHiddenContainer || !childAriaNode?.isLeaf)
processChildNodes(childAriaNode?.ariaNode || ariaNode, element);
} else {
processChildNodes(ariaNode, element);
}
const childAriaNode = toAriaNode(element);
if (childAriaNode)
ariaNode.children.push(childAriaNode);
processChildNodes(childAriaNode || ariaNode, element);
};
function processChildNodes(ariaNode: AriaNode, element: Element) {
@ -101,6 +89,9 @@ export function generateAriaTree(rootElement: Element): AriaNode {
if (treatAsBlock)
ariaNode.children.push(treatAsBlock);
if (ariaNode.children.length === 1 && ariaNode.name === ariaNode.children[0])
ariaNode.children = [];
}
roleUtils.beginAriaCaches();
@ -115,19 +106,13 @@ export function generateAriaTree(rootElement: Element): AriaNode {
return ariaRoot;
}
function toAriaNode(element: Element): { ariaNode: AriaNode, isLeaf: boolean } | null {
function toAriaNode(element: Element): AriaNode | null {
const role = roleUtils.getAriaRole(element);
if (!role)
return null;
const name = roleUtils.getElementAccessibleName(element, false) || '';
const isLeaf = leafRoles.has(role);
const result: AriaNode = { role, name, children: [] };
if (isLeaf && !name) {
const text = roleUtils.accumulatedElementText(element);
if (text)
result.children = [text];
}
if (roleUtils.kAriaCheckedRoles.includes(role))
result.checked = roleUtils.getAriaChecked(element);
@ -147,7 +132,7 @@ function toAriaNode(element: Element): { ariaNode: AriaNode, isLeaf: boolean } |
if (roleUtils.kAriaSelectedRoles.includes(role))
result.selected = roleUtils.getAriaSelected(element);
return { isLeaf, ariaNode: result };
return result;
}
export function renderedAriaTree(rootElement: Element): string {
@ -178,21 +163,12 @@ function normalizeStringChildren(rootA11yNode: AriaNode) {
}
flushChildren(buffer, normalizedChildren);
ariaNode.children = normalizedChildren.length ? normalizedChildren : [];
if (ariaNode.children.length === 1 && ariaNode.children[0] === ariaNode.name)
ariaNode.children = [];
};
visit(rootA11yNode);
}
const hiddenContainerRoles = new Set(['none', 'presentation']);
const leafRoles = new Set<AriaRole>([
'alert', 'blockquote', 'button', 'caption', 'checkbox', 'code', 'columnheader',
'definition', 'deletion', 'emphasis', 'generic', 'heading', 'img', 'insertion',
'link', 'menuitem', 'menuitemcheckbox', 'menuitemradio', 'meter', 'option',
'progressbar', 'radio', 'rowheader', 'scrollbar', 'searchbox', 'separator',
'slider', 'spinbutton', 'strong', 'subscript', 'superscript', 'switch', 'tab', 'term',
'textbox', 'time', 'tooltip'
]);
const normalizeWhitespaceWithin = (text: string) => text.replace(/[\s\t\r\n]+/g, ' ');
function matchesText(text: string | undefined, template: RegExp | string | undefined) {
@ -305,15 +281,7 @@ export function renderAriaTree(ariaNode: AriaNode, options?: { noText?: boolean
if (ariaNode.selected === true)
line += ` [selected]`;
const stringValue = !ariaNode.children.length || (ariaNode.children?.length === 1 && typeof ariaNode.children[0] === 'string');
if (stringValue) {
if (!options?.noText && ariaNode.children.length)
line += ': ' + quoteYamlString(ariaNode.children?.[0] as string);
lines.push(line);
return;
}
lines.push(line + ':');
lines.push(line + (ariaNode.children.length ? ':' : ''));
for (const child of ariaNode.children || [])
visit(child, indent + ' ');
};

View file

@ -64,8 +64,10 @@ it('should snapshot list with accessible name', async ({ page }) => {
`);
await checkAndMatchSnapshot(page.locator('body'), `
- list "my list":
- listitem: "one"
- listitem: "two"
- listitem:
- text: "one"
- listitem:
- text: "two"
`);
});
@ -105,7 +107,8 @@ it('should snapshot details visibility', async ({ page }) => {
`);
await checkAndMatchSnapshot(page.locator('body'), `
- group: "Summary"
- group:
- text: "Summary"
`);
});
@ -148,7 +151,8 @@ it('should snapshot integration', async ({ page }) => {
- text: "Open source projects and samples from Microsoft"
- list:
- listitem:
- group: "Verified"
- group:
- text: "Verified"
- listitem:
- link "Sponsor"
`);
@ -164,13 +168,15 @@ it('should support multiline text', async ({ page }) => {
`);
await checkAndMatchSnapshot(page.locator('body'), `
- paragraph: "Line 1 Line 2 Line 3"
- paragraph:
- text: "Line 1 Line 2 Line 3"
`);
await expect(page.locator('body')).toMatchAriaSnapshot(`
- paragraph: |
Line 1
Line 2
Line 3
- paragraph:
- text: |
Line 1
Line 2
Line 3
`);
});
@ -382,6 +388,22 @@ it('should include pseudo codepoints', async ({ page, server }) => {
`);
await checkAndMatchSnapshot(page.locator('body'), `
- paragraph: "\ueab2hello"
- paragraph:
- text: "\ueab2hello"
`);
});
it('check aria-hidden text', async ({ page, server }) => {
await page.goto(server.EMPTY_PAGE);
await page.setContent(`
<p>
<span>hello</span>
<span aria-hidden="true">world</span>
</p>
`);
await checkAndMatchSnapshot(page.locator('body'), `
- paragraph:
- text: "hello"
`);
});