parent
b92dc47665
commit
11659ceb73
|
|
@ -103,7 +103,7 @@ export function isElementVisible(element: Element): boolean {
|
||||||
return rect.width > 0 && rect.height > 0;
|
return rect.width > 0 && rect.height > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isVisibleTextNode(node: Text) {
|
export function isVisibleTextNode(node: Text) {
|
||||||
// https://stackoverflow.com/questions/1461059/is-there-an-equivalent-to-getboundingclientrect-for-text-nodes
|
// https://stackoverflow.com/questions/1461059/is-there-an-equivalent-to-getboundingclientrect-for-text-nodes
|
||||||
const range = node.ownerDocument.createRange();
|
const range = node.ownerDocument.createRange();
|
||||||
range.selectNode(node);
|
range.selectNode(node);
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { closestCrossShadow, enclosingShadowRootOrDocument, getElementComputedStyle, isElementStyleVisibilityVisible, parentElementOrShadowHost } from './domUtils';
|
import { closestCrossShadow, enclosingShadowRootOrDocument, getElementComputedStyle, isElementStyleVisibilityVisible, isVisibleTextNode, parentElementOrShadowHost } from './domUtils';
|
||||||
|
|
||||||
function hasExplicitAccessibleName(e: Element) {
|
function hasExplicitAccessibleName(e: Element) {
|
||||||
return e.hasAttribute('aria-label') || e.hasAttribute('aria-labelledby');
|
return e.hasAttribute('aria-label') || e.hasAttribute('aria-labelledby');
|
||||||
|
|
@ -238,11 +238,22 @@ function getAriaBoolean(attr: string | null) {
|
||||||
export function isElementHiddenForAria(element: Element, cache: Map<Element, boolean>): boolean {
|
export function isElementHiddenForAria(element: Element, cache: Map<Element, boolean>): boolean {
|
||||||
if (['STYLE', 'SCRIPT', 'NOSCRIPT', 'TEMPLATE'].includes(element.tagName))
|
if (['STYLE', 'SCRIPT', 'NOSCRIPT', 'TEMPLATE'].includes(element.tagName))
|
||||||
return true;
|
return true;
|
||||||
|
const style = getElementComputedStyle(element);
|
||||||
|
const isSlot = element.nodeName === 'SLOT';
|
||||||
|
if (style?.display === 'contents' && !isSlot) {
|
||||||
|
// display:contents is not rendered itself, but its child nodes are.
|
||||||
|
for (let child = element.firstChild; child; child = child.nextSibling) {
|
||||||
|
if (child.nodeType === 1 /* Node.ELEMENT_NODE */ && !isElementHiddenForAria(child as Element, cache))
|
||||||
|
return false;
|
||||||
|
if (child.nodeType === 3 /* Node.TEXT_NODE */ && isVisibleTextNode(child as Text))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
// Note: <option> inside <select> are not affected by visibility or content-visibility.
|
// Note: <option> inside <select> are not affected by visibility or content-visibility.
|
||||||
// Same goes for <slot>.
|
// Same goes for <slot>.
|
||||||
const isOptionInsideSelect = element.nodeName === 'OPTION' && !!element.closest('select');
|
const isOptionInsideSelect = element.nodeName === 'OPTION' && !!element.closest('select');
|
||||||
const isSlot = element.nodeName === 'SLOT';
|
if (!isOptionInsideSelect && !isSlot && !isElementStyleVisibilityVisible(element, style))
|
||||||
if (!isOptionInsideSelect && !isSlot && !isElementStyleVisibilityVisible(element))
|
|
||||||
return true;
|
return true;
|
||||||
return belongsToDisplayNoneOrAriaHiddenOrNonSlotted(element, cache);
|
return belongsToDisplayNoneOrAriaHiddenOrNonSlotted(element, cache);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -299,6 +299,13 @@ test('native controls labelled-by', async ({ page }) => {
|
||||||
expect.soft(await getNameAndRole(page, '#textarea1')).toEqual({ role: 'textbox', name: 'TEXTAREA1 MORE2' });
|
expect.soft(await getNameAndRole(page, '#textarea1')).toEqual({ role: 'textbox', name: 'TEXTAREA1 MORE2' });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('display:contents should be visible when contents are visible', async ({ page }) => {
|
||||||
|
await page.setContent(`
|
||||||
|
<button style='display: contents;'>yo</button>
|
||||||
|
`);
|
||||||
|
await expect(page.getByRole('button')).toHaveCount(1);
|
||||||
|
});
|
||||||
|
|
||||||
function toArray(x: any): any[] {
|
function toArray(x: any): any[] {
|
||||||
return Array.isArray(x) ? x : [x];
|
return Array.isArray(x) ? x : [x];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue