-
Notifications
You must be signed in to change notification settings - Fork 791
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(object-alt): ignore unloaded objects (#3680)
* fix(object-alt): ignore unloaded objects * fix failing test
- Loading branch information
1 parent
522bdfb
commit 8e03e2c
Showing
6 changed files
with
200 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import noExplicitNameRequired from './no-explicit-name-required-matches'; | ||
|
||
export default (node, vNode) => | ||
[noExplicitNameRequired, objectHasLoaded].every(fn => fn(node, vNode)); | ||
|
||
/** | ||
* Test if an object loaded content; assume yes if we can't prove otherwise | ||
* | ||
* @param {Element} node | ||
* @param {VirtualNode} vNode | ||
* @returns {boolean} | ||
*/ | ||
function objectHasLoaded(node) { | ||
if (!node?.ownerDocument?.createRange) { | ||
return true; // Assume it did | ||
} | ||
// There's no ready | ||
const range = node.ownerDocument.createRange(); | ||
range.setStart(node, 0); | ||
range.setEnd(node, node.childNodes.length); | ||
return range.getClientRects().length === 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,75 @@ | ||
<object id="pass1" title="This object has text"></object> | ||
<object id="pass2" aria-label="this object has text"></object> | ||
<span id="label1">this object has text</span> | ||
<object id="pass3" aria-labelledby="label1"></object> | ||
<object id="pass4" role="presentation"></object> | ||
<object id="pass5" role="none"></object> | ||
<object | ||
id="pass1" | ||
title="This object has text" | ||
data="data:text/html,Object%20content" | ||
></object> | ||
<object | ||
id="pass2" | ||
aria-label="this object has text" | ||
data="data:text/html,Object%20content" | ||
></object> | ||
<span id="label1" data="data:text/html,Object%20content" | ||
>this object has text</span | ||
> | ||
<object | ||
id="pass3" | ||
aria-labelledby="label1" | ||
data="data:text/html,Object%20content" | ||
></object> | ||
<object | ||
id="pass4" | ||
role="presentation" | ||
data="data:text/html,Object%20content" | ||
></object> | ||
<object id="pass5" role="none" data="data:text/html,Object%20content"></object> | ||
|
||
<object id="violation1"></object> | ||
<object id="violation2"><div></div></object> | ||
<object id="violation3">This object has text.</object> | ||
<object id="violation4" role="none" tabindex="0"></object> | ||
<object id="violation5" role="presentation" tabindex="0"></object> | ||
<object id="violation6" role="none" aria-live="assertive"></object> | ||
<object id="violation7" role="presentation" aria-live="assertive"></object> | ||
<object id="violation1" data="data:text/html,Object%20content"></object> | ||
<object id="violation2" data="data:text/html,Object%20content"> | ||
<div></div> | ||
</object> | ||
<object id="violation3" data="data:text/html,Object%20content"> | ||
This object has text. | ||
</object> | ||
<object | ||
id="violation4" | ||
role="none" | ||
tabindex="0" | ||
data="data:text/html,Object%20content" | ||
></object> | ||
<object | ||
id="violation5" | ||
role="presentation" | ||
tabindex="0" | ||
data="data:text/html,Object%20content" | ||
></object> | ||
<object | ||
id="violation6" | ||
role="none" | ||
aria-live="assertive" | ||
data="data:text/html,Object%20content" | ||
></object> | ||
<object | ||
id="violation7" | ||
role="presentation" | ||
aria-live="assertive" | ||
data="data:text/html,Object%20content" | ||
></object> | ||
<object | ||
id="violation8" | ||
role="img" | ||
data="data:text/html,Object%20content" | ||
></object> | ||
<object | ||
id="violation9" | ||
role="separator" | ||
tabindex="0" | ||
data="data:text/html,Object%20content" | ||
></object> | ||
|
||
<object id="violation8" role="img"></object> | ||
<object id="violation9" role="separator" tabindex="0"></object> | ||
<object id="inapplicable1" role="separator"></object> | ||
<object id="inapplicable1"><!-- no data attribute --></object> | ||
<object id="inapplicable2" data="">Fallback content</object> | ||
<object | ||
id="inapplicable3" | ||
role="separator" | ||
data="data:text/html,Object%20content" | ||
></object> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
describe('object-is-loaded-matches', () => { | ||
let rule, fixture; | ||
const data = `data:text/html,Object%20content`; | ||
|
||
// Give enough time for the browser to load / decide it cannot load objects | ||
async function delayedQueryFixture(html, delay = 50) { | ||
fixture.innerHTML = html; | ||
await new Promise(r => setTimeout(r, delay)); | ||
const tree = axe.setup(); | ||
return axe.utils.querySelectorAll(tree, '#target')[0]; | ||
} | ||
|
||
before(() => { | ||
fixture = document.querySelector('#fixture'); | ||
rule = axe.utils.getRule('object-alt'); | ||
}); | ||
|
||
afterEach(() => { | ||
fixture.innerHTML = ''; | ||
}); | ||
|
||
it(`returns true objects with hidden fallback content`, async () => { | ||
const vNode = await delayedQueryFixture( | ||
`<object data="${data}" height="30" id="target"> | ||
Fallback content | ||
</object>` | ||
); | ||
assert.isTrue(rule.matches(vNode.actualNode, vNode)); | ||
}); | ||
|
||
it(`returns false if the object shows any content`, async () => { | ||
const vNode = await delayedQueryFixture( | ||
`<object data="invalid" height="30" id="target"> | ||
Fallback content | ||
</object>` | ||
); | ||
assert.isFalse(rule.matches(vNode.actualNode, vNode)); | ||
}); | ||
|
||
it(`returns true if the object shows no content`, async () => { | ||
const vNode = await delayedQueryFixture( | ||
`<object data="invalid" height="30" id="target"></object>` | ||
); | ||
// Ideally, this should be false, don't know it can be done | ||
assert.isTrue(rule.matches(vNode.actualNode, vNode)); | ||
}); | ||
|
||
it(`returns false if the object has a role that doesn't require a name`, async () => { | ||
const vNode = await delayedQueryFixture( | ||
`<object data="${data}" height="30" id="target" role="grid"> | ||
Fallback content | ||
</object>` | ||
); | ||
assert.isFalse(rule.matches(vNode.actualNode, vNode)); | ||
}); | ||
}); |