Bug 1960416: Skip aria-hidden subtrees during initial tree creation when aria-hidden is specified on the root element r=Jamie
Differential Revision: https://phabricator.services.mozilla.com/D246057
This commit is contained in:
@@ -1612,6 +1612,22 @@ bool aria::IsValidARIAHidden(nsIContent* aContent) {
|
||||
!ShouldIgnoreARIAHidden(aContent);
|
||||
}
|
||||
|
||||
bool aria::IsValidARIAHidden(DocAccessible* aDocAcc) {
|
||||
nsCOMPtr<nsIContent> docContent = aDocAcc->GetContent();
|
||||
// First, check if our Doc Accessible has aria-hidden set on its content
|
||||
bool isValid = IsValidARIAHidden(docContent);
|
||||
|
||||
// If our Doc Accessible was created using an element other than the
|
||||
// root element, we need to verify the validity of any aria-hidden on
|
||||
// the root element as well.
|
||||
auto* rootElement = aDocAcc->DocumentNode()->GetRootElement();
|
||||
if (docContent != rootElement) {
|
||||
isValid |= IsValidARIAHidden(rootElement);
|
||||
}
|
||||
|
||||
return isValid;
|
||||
}
|
||||
|
||||
bool aria::ShouldIgnoreARIAHidden(nsIContent* aContent) {
|
||||
if (!aContent) {
|
||||
return false;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "ARIAStateMap.h"
|
||||
#include "mozilla/a11y/AccTypes.h"
|
||||
#include "mozilla/a11y/DocAccessible.h"
|
||||
#include "mozilla/a11y/Role.h"
|
||||
|
||||
#include "nsAtom.h"
|
||||
@@ -310,6 +311,14 @@ uint8_t AttrCharacteristicsFor(nsAtom* aAtom);
|
||||
*/
|
||||
bool IsValidARIAHidden(nsIContent* aContent);
|
||||
|
||||
/**
|
||||
* This function calls into the function above. It verifies the validity
|
||||
* of any `aria-hidden` specified on the given Doc Accessible's
|
||||
* mContent, as well as on the root element of mContent's owner
|
||||
* doc.
|
||||
*/
|
||||
bool IsValidARIAHidden(DocAccessible* aDocAcc);
|
||||
|
||||
/**
|
||||
* Return true if the element should render its subtree
|
||||
* regardless of the presence of aria-hidden.
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "TreeWalker.h"
|
||||
|
||||
#include "ARIAMap.h"
|
||||
#include "nsAccessibilityService.h"
|
||||
#include "DocAccessible.h"
|
||||
|
||||
@@ -323,7 +324,8 @@ LocalAccessible* TreeWalker::AccessibleFor(nsIContent* aNode, uint32_t aFlags,
|
||||
}
|
||||
|
||||
// Create an accessible if allowed.
|
||||
if (!(aFlags & eWalkCache) && mContext->IsAcceptableChild(aNode)) {
|
||||
if (!(aFlags & eWalkCache) && mContext->IsAcceptableChild(aNode) &&
|
||||
!aria::IsValidARIAHidden(mDoc)) {
|
||||
mDoc->RelocateARIAOwnedIfNeeded(aNode);
|
||||
return GetAccService()->CreateAccessible(aNode, mContext, aSkipSubtree);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,10 @@ skip-if = [
|
||||
|
||||
["browser_test_aria_hidden.js"]
|
||||
|
||||
["browser_test_aria_hidden_iframe.js"]
|
||||
|
||||
["browser_test_aria_hidden_svg.js"]
|
||||
|
||||
["browser_searchbar.js"]
|
||||
|
||||
["browser_select.js"]
|
||||
|
||||
@@ -7,11 +7,37 @@
|
||||
loadScripts({ name: "role.js", dir: MOCHITESTS_DIR });
|
||||
|
||||
/**
|
||||
* Verify loading a root doc with aria-hidden renders the document.
|
||||
* Non-root doc elements, like embedded iframes, should continue
|
||||
* Verify loading a tab document with aria-hidden specified on the root element
|
||||
* correctly renders the root element and its content. This test is meaninfully
|
||||
* different from testTabDocument which tests aria-hidden specified on the
|
||||
* body element.
|
||||
*/
|
||||
addAccessibleTask(
|
||||
`<html aria-hidden="true"><u>hello world`,
|
||||
async function testTabRootDocument(_, accDoc) {
|
||||
const tree = {
|
||||
DOCUMENT: [
|
||||
{
|
||||
TEXT_LEAF: [],
|
||||
},
|
||||
],
|
||||
};
|
||||
testAccessibleTree(accDoc, tree);
|
||||
},
|
||||
{
|
||||
chrome: true,
|
||||
topLevel: true,
|
||||
iframe: false,
|
||||
remoteIframe: false,
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Verify loading a tab doc with aria-hidden on the body renders the document.
|
||||
* Body elements inside of embedded iframes, should continue
|
||||
* to respect aria-hidden when present. This test ONLY tests
|
||||
* tab documents, it should not run in iframes. There is a separate
|
||||
* test for iframes below.
|
||||
* test for iframes in browser_test_aria_hidden_iframe.js.
|
||||
*/
|
||||
addAccessibleTask(
|
||||
`
|
||||
@@ -35,7 +61,7 @@ addAccessibleTask(
|
||||
* Non-root doc elements, like embedded iframes, should continue
|
||||
* to respect aria-hidden when applied. This test ONLY tests
|
||||
* tab documents, it should not run in iframes. There is a separate
|
||||
* test for iframes below.
|
||||
* test for iframes in browser_test_aria_hidden_iframe.js.
|
||||
*/
|
||||
addAccessibleTask(
|
||||
`
|
||||
@@ -56,274 +82,3 @@ addAccessibleTask(
|
||||
},
|
||||
{ chrome: true, topLevel: true, iframe: false, remoteIframe: false }
|
||||
);
|
||||
|
||||
/**
|
||||
* Verify loading an iframe doc with aria-hidden doesn't render the document.
|
||||
* This test ONLY tests iframe documents, it should not run in tab docs.
|
||||
* There is a separate test for tab docs above.
|
||||
*/
|
||||
addAccessibleTask(
|
||||
`
|
||||
<p id="content">I am some content in a document</p>
|
||||
`,
|
||||
async function testIframeDocument(browser, docAcc, topLevel) {
|
||||
const originalTree = { DOCUMENT: [{ INTERNAL_FRAME: [{ DOCUMENT: [] }] }] };
|
||||
testAccessibleTree(topLevel, originalTree);
|
||||
},
|
||||
{
|
||||
chrome: false,
|
||||
topLevel: false,
|
||||
iframe: true,
|
||||
remoteIframe: true,
|
||||
iframeDocBodyAttrs: { "aria-hidden": "true" },
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Verify adding aria-hidden to iframe doc elements removes
|
||||
* their subtree. This test ONLY tests iframe documents, it
|
||||
* should not run in tab documents. There is a separate test for
|
||||
* tab documents above.
|
||||
*/
|
||||
addAccessibleTask(
|
||||
`
|
||||
<p id="content">I am some content in a document</p>
|
||||
`,
|
||||
async function testIframeDocumentMutation(browser, docAcc, topLevel) {
|
||||
const originalTree = {
|
||||
DOCUMENT: [
|
||||
{
|
||||
INTERNAL_FRAME: [
|
||||
{
|
||||
DOCUMENT: [
|
||||
{
|
||||
PARAGRAPH: [
|
||||
{
|
||||
TEXT_LEAF: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
testAccessibleTree(topLevel, originalTree);
|
||||
info("Adding aria-hidden=true to content doc");
|
||||
await contentSpawnMutation(
|
||||
browser,
|
||||
{ expected: [[EVENT_REORDER, docAcc]] },
|
||||
function () {
|
||||
const b = content.document.body;
|
||||
b.setAttribute("aria-hidden", "true");
|
||||
}
|
||||
);
|
||||
const newTree = {
|
||||
DOCUMENT: [
|
||||
{
|
||||
INTERNAL_FRAME: [
|
||||
{
|
||||
DOCUMENT: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
testAccessibleTree(topLevel, newTree);
|
||||
},
|
||||
{ chrome: false, topLevel: false, iframe: true, remoteIframe: true }
|
||||
);
|
||||
|
||||
// // ///////////////////////////////
|
||||
// // //////////////////// SVG Tests
|
||||
// // //////////////////////////////
|
||||
|
||||
const SVG_DOCUMENT_ID = "rootSVG";
|
||||
const HIDDEN_SVG_URI =
|
||||
"data:image/svg+xml,%3Csvg%20id%3D%22rootSVG%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20aria-hidden%3D%22true%22%3E%3Ctext%20x%3D%2210%22%20y%3D%2250%22%20font-size%3D%2230%22%20id%3D%22textSVG%22%3EMy%20SVG%3C%2Ftext%3E%3C%2Fsvg%3E";
|
||||
const SVG_URI =
|
||||
"data:image/svg+xml,%3Csvg%20id%3D%22rootSVG%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Ctext%20x%3D%2210%22%20y%3D%2250%22%20font-size%3D%2230%22%20id%3D%22textSVG%22%3EMy%20SVG%3C%2Ftext%3E%3C%2Fsvg%3E";
|
||||
|
||||
/**
|
||||
* Verify loading an SVG document with aria-hidden=true renders the
|
||||
* entire document subtree.
|
||||
* Non-root svg elements, like those in embedded iframes, should
|
||||
* continue to respect aria-hidden when applied.
|
||||
*/
|
||||
addAccessibleTask(
|
||||
`hello world`,
|
||||
async function testSVGDocument(browser) {
|
||||
let loaded = waitForEvent(EVENT_DOCUMENT_LOAD_COMPLETE, SVG_DOCUMENT_ID);
|
||||
info("Loading SVG");
|
||||
browser.loadURI(Services.io.newURI(HIDDEN_SVG_URI), {
|
||||
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
});
|
||||
await loaded;
|
||||
|
||||
const tree = {
|
||||
DOCUMENT: [
|
||||
{
|
||||
TEXT_CONTAINER: [
|
||||
{
|
||||
TEXT_LEAF: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
const root = getRootAccessible(document);
|
||||
const svgRoot = findAccessibleChildByID(root, SVG_DOCUMENT_ID);
|
||||
testAccessibleTree(svgRoot, tree);
|
||||
},
|
||||
{ chrome: true, topLevel: true, iframe: false, remoteIframe: false }
|
||||
);
|
||||
|
||||
///////////
|
||||
///// TODO: Bug 1960416
|
||||
//////////
|
||||
// /**
|
||||
// * Verify loading an SVG document with aria-hidden=true
|
||||
// * in an iframe does not render the document subtree.
|
||||
// */
|
||||
// addAccessibleTask(
|
||||
// `hello world`,
|
||||
// async function testSVGIframeDocument(browser) {
|
||||
// info("Loading SVG");
|
||||
// const loaded = waitForEvent(EVENT_DOCUMENT_LOAD_COMPLETE, SVG_DOCUMENT_ID);
|
||||
// await SpecialPowers.spawn(browser, [DEFAULT_IFRAME_ID, HIDDEN_SVG_URI], (_id,_uri) => {
|
||||
// content.document.getElementById(_id).src = _uri;
|
||||
// });
|
||||
// await loaded;
|
||||
|
||||
// const tree = {
|
||||
// DOCUMENT: [],
|
||||
// };
|
||||
// const root = getRootAccessible(document);
|
||||
// const svgRoot = findAccessibleChildByID(root, SVG_DOCUMENT_ID);
|
||||
// testAccessibleTree(svgRoot, tree);
|
||||
// },
|
||||
// { chrome: false, topLevel: false, iframe: true, remoteIframe: true }
|
||||
// );
|
||||
|
||||
/**
|
||||
* Verify adding aria-hidden to root svg elements has no effect.
|
||||
* Non-root svg elements, like those in embedded iframes, should
|
||||
* continue to respect aria-hidden when applied.
|
||||
*/
|
||||
addAccessibleTask(
|
||||
`hello world`,
|
||||
async function testSVGDocumentMutation(browser) {
|
||||
let loaded = waitForEvent(EVENT_DOCUMENT_LOAD_COMPLETE, SVG_DOCUMENT_ID);
|
||||
info("Loading SVG");
|
||||
browser.loadURI(Services.io.newURI(SVG_URI), {
|
||||
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
});
|
||||
await loaded;
|
||||
|
||||
const originalTree = {
|
||||
DOCUMENT: [
|
||||
{
|
||||
TEXT_CONTAINER: [
|
||||
{
|
||||
TEXT_LEAF: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
const root = getRootAccessible(document);
|
||||
const svgRoot = findAccessibleChildByID(root, SVG_DOCUMENT_ID);
|
||||
testAccessibleTree(svgRoot, originalTree);
|
||||
info("Adding aria-hidden=true to svg");
|
||||
// XXX Bug 1959547: We incorrectly get a reorder
|
||||
// here. The tree should be unaffected by this attribute,
|
||||
// but it seems like it isn't! Below we'll verify that
|
||||
// the tree isn't removed, despite this reorder.
|
||||
const unexpectedEvents = { expected: [[EVENT_REORDER, SVG_DOCUMENT_ID]] };
|
||||
info("Adding aria-hidden");
|
||||
await contentSpawnMutation(
|
||||
browser,
|
||||
unexpectedEvents,
|
||||
function (_id) {
|
||||
const d = content.document.getElementById(_id);
|
||||
d.setAttribute("aria-hidden", "true");
|
||||
},
|
||||
[SVG_DOCUMENT_ID]
|
||||
);
|
||||
// XXX Bug 1959547: We end up with an extra node in the
|
||||
// tree after adding aria-hidden. It seems like SVG root
|
||||
// element is splitting off / no longer behaves as the
|
||||
// document...?
|
||||
const newTree = {
|
||||
DOCUMENT: [
|
||||
{
|
||||
DIAGRAM: [
|
||||
{
|
||||
TEXT_CONTAINER: [
|
||||
{
|
||||
TEXT_LEAF: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
testAccessibleTree(svgRoot, newTree);
|
||||
},
|
||||
{ chrome: true, topLevel: true, iframe: false, remoteIframe: false }
|
||||
);
|
||||
|
||||
/**
|
||||
* Verify adding aria-hidden to root svg elements in iframes removes
|
||||
* the svg subtree.
|
||||
*/
|
||||
addAccessibleTask(
|
||||
`hello world`,
|
||||
async function testSVGIframeDocumentMutation(browser) {
|
||||
info("Loading SVG");
|
||||
const loaded = waitForEvent(EVENT_DOCUMENT_LOAD_COMPLETE, SVG_DOCUMENT_ID);
|
||||
await SpecialPowers.spawn(
|
||||
browser,
|
||||
[DEFAULT_IFRAME_ID, SVG_URI],
|
||||
(contentId, _uri) => {
|
||||
content.document.getElementById(contentId).src = _uri;
|
||||
}
|
||||
);
|
||||
await loaded;
|
||||
const originalTree = {
|
||||
DOCUMENT: [
|
||||
{
|
||||
TEXT_CONTAINER: [
|
||||
{
|
||||
TEXT_LEAF: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
const svgRoot = findAccessibleChildByID(
|
||||
getRootAccessible(document),
|
||||
SVG_DOCUMENT_ID
|
||||
);
|
||||
testAccessibleTree(svgRoot, originalTree);
|
||||
|
||||
info("Adding aria-hidden=true to svg");
|
||||
const events = { expected: [[EVENT_REORDER, SVG_DOCUMENT_ID]] };
|
||||
await contentSpawnMutation(
|
||||
browser,
|
||||
events,
|
||||
function (_id) {
|
||||
const d = content.document.getElementById(_id);
|
||||
d.setAttribute("aria-hidden", "true");
|
||||
},
|
||||
[SVG_DOCUMENT_ID]
|
||||
);
|
||||
|
||||
const newTree = { DOCUMENT: [] };
|
||||
testAccessibleTree(svgRoot, newTree);
|
||||
},
|
||||
{ chrome: false, topLevel: false, iframe: true, remoteIframe: true }
|
||||
);
|
||||
|
||||
127
accessible/tests/browser/tree/browser_test_aria_hidden_iframe.js
Normal file
127
accessible/tests/browser/tree/browser_test_aria_hidden_iframe.js
Normal file
@@ -0,0 +1,127 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
/* import-globals-from ../../mochitest/role.js */
|
||||
loadScripts({ name: "role.js", dir: MOCHITESTS_DIR });
|
||||
|
||||
/**
|
||||
* Verify loading an iframe document with aria-hidden specified on the root element
|
||||
* correctly hides the root element and its content. This test is meaninfully
|
||||
* different from testIframeDocument which tests aria-hidden specified on the
|
||||
* body element.
|
||||
*/
|
||||
addAccessibleTask(
|
||||
`hello world`,
|
||||
async function testIframeRootDocument(browser) {
|
||||
info("Loading iframe document");
|
||||
const HIDDEN_IFRAME_URI =
|
||||
"data:text/html,<html id='new_html' aria-hidden='true'><body id='iframeBody'><u>hello world</u></body></html>";
|
||||
const loaded = waitForEvent(EVENT_DOCUMENT_LOAD_COMPLETE, "iframeBody");
|
||||
await SpecialPowers.spawn(
|
||||
browser,
|
||||
[DEFAULT_IFRAME_ID, HIDDEN_IFRAME_URI],
|
||||
(_id, _uri) => {
|
||||
content.document.getElementById(_id).src = _uri;
|
||||
}
|
||||
);
|
||||
await loaded;
|
||||
|
||||
const tree = {
|
||||
INTERNAL_FRAME: [
|
||||
{
|
||||
DOCUMENT: [],
|
||||
},
|
||||
],
|
||||
};
|
||||
const root = getRootAccessible(document);
|
||||
const iframeDoc = findAccessibleChildByID(root, DEFAULT_IFRAME_ID);
|
||||
testAccessibleTree(iframeDoc, tree);
|
||||
},
|
||||
{
|
||||
chrome: false,
|
||||
topLevel: false,
|
||||
iframe: true,
|
||||
remoteIframe: true,
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Verify loading an iframe doc with aria-hidden doesn't render the document.
|
||||
* This test ONLY tests iframe documents, it should not run in tab docs.
|
||||
* There is a separate test for tab docs in browser_test_aria_hidden.js.
|
||||
*/
|
||||
addAccessibleTask(
|
||||
`
|
||||
<p id="content">I am some content in a document</p>
|
||||
`,
|
||||
async function testIframeDocument(browser, docAcc, topLevel) {
|
||||
const originalTree = { DOCUMENT: [{ INTERNAL_FRAME: [{ DOCUMENT: [] }] }] };
|
||||
testAccessibleTree(topLevel, originalTree);
|
||||
},
|
||||
{
|
||||
chrome: false,
|
||||
topLevel: false,
|
||||
iframe: true,
|
||||
remoteIframe: true,
|
||||
iframeDocBodyAttrs: { "aria-hidden": "true" },
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Verify adding aria-hidden to iframe doc elements removes
|
||||
* their subtree. This test ONLY tests iframe documents, it
|
||||
* should not run in tab documents. There is a separate test for
|
||||
* tab documents in browser_test_aria_hidden.js.
|
||||
*/
|
||||
addAccessibleTask(
|
||||
`
|
||||
<p id="content">I am some content in a document</p>
|
||||
`,
|
||||
async function testIframeDocumentMutation(browser, docAcc, topLevel) {
|
||||
const originalTree = {
|
||||
DOCUMENT: [
|
||||
{
|
||||
INTERNAL_FRAME: [
|
||||
{
|
||||
DOCUMENT: [
|
||||
{
|
||||
PARAGRAPH: [
|
||||
{
|
||||
TEXT_LEAF: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
testAccessibleTree(topLevel, originalTree);
|
||||
info("Adding aria-hidden=true to content doc");
|
||||
await contentSpawnMutation(
|
||||
browser,
|
||||
{ expected: [[EVENT_REORDER, docAcc]] },
|
||||
function () {
|
||||
const b = content.document.body;
|
||||
b.setAttribute("aria-hidden", "true");
|
||||
}
|
||||
);
|
||||
const newTree = {
|
||||
DOCUMENT: [
|
||||
{
|
||||
INTERNAL_FRAME: [
|
||||
{
|
||||
DOCUMENT: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
testAccessibleTree(topLevel, newTree);
|
||||
},
|
||||
{ chrome: false, topLevel: false, iframe: true, remoteIframe: true }
|
||||
);
|
||||
197
accessible/tests/browser/tree/browser_test_aria_hidden_svg.js
Normal file
197
accessible/tests/browser/tree/browser_test_aria_hidden_svg.js
Normal file
@@ -0,0 +1,197 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
/* import-globals-from ../../mochitest/role.js */
|
||||
loadScripts({ name: "role.js", dir: MOCHITESTS_DIR });
|
||||
|
||||
const SVG_DOCUMENT_ID = "rootSVG";
|
||||
const HIDDEN_SVG_URI =
|
||||
"data:image/svg+xml,%3Csvg%20id%3D%22rootSVG%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20aria-hidden%3D%22true%22%3E%3Ctext%20x%3D%2210%22%20y%3D%2250%22%20font-size%3D%2230%22%20id%3D%22textSVG%22%3EMy%20SVG%3C%2Ftext%3E%3C%2Fsvg%3E";
|
||||
const SVG_URI =
|
||||
"data:image/svg+xml,%3Csvg%20id%3D%22rootSVG%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Ctext%20x%3D%2210%22%20y%3D%2250%22%20font-size%3D%2230%22%20id%3D%22textSVG%22%3EMy%20SVG%3C%2Ftext%3E%3C%2Fsvg%3E";
|
||||
|
||||
/**
|
||||
* Verify loading an SVG document with aria-hidden=true renders the
|
||||
* entire document subtree.
|
||||
* Non-root svg elements, like those in embedded iframes, should
|
||||
* continue to respect aria-hidden when applied.
|
||||
*/
|
||||
addAccessibleTask(
|
||||
`hello world`,
|
||||
async function testSVGDocument(browser) {
|
||||
let loaded = waitForEvent(EVENT_DOCUMENT_LOAD_COMPLETE, SVG_DOCUMENT_ID);
|
||||
info("Loading SVG");
|
||||
browser.loadURI(Services.io.newURI(HIDDEN_SVG_URI), {
|
||||
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
});
|
||||
await loaded;
|
||||
|
||||
const tree = {
|
||||
DOCUMENT: [
|
||||
{
|
||||
TEXT_CONTAINER: [
|
||||
{
|
||||
TEXT_LEAF: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
const root = getRootAccessible(document);
|
||||
const svgRoot = findAccessibleChildByID(root, SVG_DOCUMENT_ID);
|
||||
testAccessibleTree(svgRoot, tree);
|
||||
},
|
||||
{ chrome: true, topLevel: true, iframe: false, remoteIframe: false }
|
||||
);
|
||||
|
||||
/**
|
||||
* Verify loading an SVG document with aria-hidden=true
|
||||
* in an iframe does not render the document subtree.
|
||||
*/
|
||||
addAccessibleTask(
|
||||
`hello world`,
|
||||
async function testSVGIframeDocument(browser) {
|
||||
info("Loading SVG");
|
||||
const loaded = waitForEvent(EVENT_DOCUMENT_LOAD_COMPLETE, SVG_DOCUMENT_ID);
|
||||
await SpecialPowers.spawn(
|
||||
browser,
|
||||
[DEFAULT_IFRAME_ID, HIDDEN_SVG_URI],
|
||||
(_id, _uri) => {
|
||||
content.document.getElementById(_id).src = _uri;
|
||||
}
|
||||
);
|
||||
await loaded;
|
||||
|
||||
const tree = {
|
||||
DOCUMENT: [],
|
||||
};
|
||||
|
||||
const root = getRootAccessible(document);
|
||||
const svgRoot = findAccessibleChildByID(root, SVG_DOCUMENT_ID);
|
||||
testAccessibleTree(svgRoot, tree);
|
||||
},
|
||||
{ chrome: false, topLevel: false, iframe: true, remoteIframe: true }
|
||||
);
|
||||
|
||||
/**
|
||||
* Verify adding aria-hidden to root svg elements has no effect.
|
||||
* Non-root svg elements, like those in embedded iframes, should
|
||||
* continue to respect aria-hidden when applied.
|
||||
*/
|
||||
addAccessibleTask(
|
||||
`hello world`,
|
||||
async function testSVGDocumentMutation(browser) {
|
||||
let loaded = waitForEvent(EVENT_DOCUMENT_LOAD_COMPLETE, SVG_DOCUMENT_ID);
|
||||
info("Loading SVG");
|
||||
browser.loadURI(Services.io.newURI(SVG_URI), {
|
||||
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
});
|
||||
await loaded;
|
||||
|
||||
const originalTree = {
|
||||
DOCUMENT: [
|
||||
{
|
||||
TEXT_CONTAINER: [
|
||||
{
|
||||
TEXT_LEAF: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
const root = getRootAccessible(document);
|
||||
const svgRoot = findAccessibleChildByID(root, SVG_DOCUMENT_ID);
|
||||
testAccessibleTree(svgRoot, originalTree);
|
||||
info("Adding aria-hidden=true to svg");
|
||||
// XXX Bug 1959547: We incorrectly get a reorder
|
||||
// here. The tree should be unaffected by this attribute,
|
||||
// but it seems like it isn't! Below we'll verify that
|
||||
// the tree isn't removed, despite this reorder.
|
||||
const unexpectedEvents = { expected: [[EVENT_REORDER, SVG_DOCUMENT_ID]] };
|
||||
info("Adding aria-hidden");
|
||||
await contentSpawnMutation(
|
||||
browser,
|
||||
unexpectedEvents,
|
||||
function (_id) {
|
||||
const d = content.document.getElementById(_id);
|
||||
d.setAttribute("aria-hidden", "true");
|
||||
},
|
||||
[SVG_DOCUMENT_ID]
|
||||
);
|
||||
// XXX Bug 1959547: We end up with an extra node in the
|
||||
// tree after adding aria-hidden. It seems like SVG root
|
||||
// element is splitting off / no longer behaves as the
|
||||
// document...?
|
||||
const newTree = {
|
||||
DOCUMENT: [
|
||||
{
|
||||
DIAGRAM: [
|
||||
{
|
||||
TEXT_CONTAINER: [
|
||||
{
|
||||
TEXT_LEAF: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
testAccessibleTree(svgRoot, newTree);
|
||||
},
|
||||
{ chrome: true, topLevel: true, iframe: false, remoteIframe: false }
|
||||
);
|
||||
|
||||
/**
|
||||
* Verify adding aria-hidden to root svg elements in iframes removes
|
||||
* the svg subtree.
|
||||
*/
|
||||
addAccessibleTask(
|
||||
`hello world`,
|
||||
async function testSVGIframeDocumentMutation(browser) {
|
||||
info("Loading SVG");
|
||||
const loaded = waitForEvent(EVENT_DOCUMENT_LOAD_COMPLETE, SVG_DOCUMENT_ID);
|
||||
await SpecialPowers.spawn(
|
||||
browser,
|
||||
[DEFAULT_IFRAME_ID, SVG_URI],
|
||||
(contentId, _uri) => {
|
||||
content.document.getElementById(contentId).src = _uri;
|
||||
}
|
||||
);
|
||||
await loaded;
|
||||
const originalTree = {
|
||||
DOCUMENT: [
|
||||
{
|
||||
TEXT_CONTAINER: [
|
||||
{
|
||||
TEXT_LEAF: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
const svgRoot = findAccessibleChildByID(
|
||||
getRootAccessible(document),
|
||||
SVG_DOCUMENT_ID
|
||||
);
|
||||
testAccessibleTree(svgRoot, originalTree);
|
||||
|
||||
info("Adding aria-hidden=true to svg");
|
||||
const events = { expected: [[EVENT_REORDER, SVG_DOCUMENT_ID]] };
|
||||
await contentSpawnMutation(
|
||||
browser,
|
||||
events,
|
||||
function (_id) {
|
||||
const d = content.document.getElementById(_id);
|
||||
d.setAttribute("aria-hidden", "true");
|
||||
},
|
||||
[SVG_DOCUMENT_ID]
|
||||
);
|
||||
|
||||
const newTree = { DOCUMENT: [] };
|
||||
testAccessibleTree(svgRoot, newTree);
|
||||
},
|
||||
{ chrome: false, topLevel: false, iframe: true, remoteIframe: true }
|
||||
);
|
||||
Reference in New Issue
Block a user