<!
DOCTYPE html>
<
html>
<
head>
<
title>Test document root content mutations</
title>
<
link rel=
"stylesheet" type=
"text/css"
href=
"chrome://mochikit/content/tests/SimpleTest/test.css" />
<
script src=
"chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></
script>
<
script type=
"application/javascript"
src=
"../common.js"></
script>
<
script type=
"application/javascript"
src=
"../role.js"></
script>
<
script type=
"application/javascript"
src=
"../states.js"></
script>
<
script type=
"application/javascript"
src=
"../events.js"></
script>
<
script type=
"application/javascript">
// //////////////////////////////////////////////////////////////////////////
// Helpers
function getDocNode(aID) {
return getNode(aID).contentDocument;
}
function getDocChildNode(aID) {
return getDocNode(aID).
body.firstChild;
}
function rootContentReplaced(aID, aTextName, aRootContentRole) {
this.eventSeq = [
new invokerChecker(EVENT_SHOW, getDocChildNode, aID),
new invokerChecker(EVENT_REORDER, getDocNode, aID),
];
this.finalCheck = function rootContentReplaced_finalCheck() {
var tree = {
role: aRootContentRole || ROLE_DOCUMENT,
children: [
{
role: ROLE_TEXT_LEAF,
name: aTextName,
},
],
};
testAccessibleTree(getDocNode(aID), tree);
};
}
function rootContentRemoved(aID) {
this.eventSeq = [
new invokerChecker(EVENT_HIDE, null),
new invokerChecker(EVENT_REORDER, getDocNode, aID),
];
this.preinvoke = function rootContentRemoved_preinvoke() {
// Set up target for hide event before we invoke.
var text = getAccessible(getAccessible(getDocNode(aID)).firstChild);
this.eventSeq[0].target = text;
};
this.finalCheck = function rootContentRemoved_finalCheck() {
var tree = {
role: ROLE_DOCUMENT,
children: [ ],
};
testAccessibleTree(getDocNode(aID), tree);
};
}
function rootContentInserted(aID, aTextName) {
this.eventSeq = [
new invokerChecker(EVENT_SHOW, getDocChildNode, aID),
new invokerChecker(EVENT_REORDER, getDocNode, aID),
];
this.finalCheck = function rootContentInserted_finalCheck() {
var tree = {
role: ROLE_DOCUMENT,
children: [
{
role: ROLE_TEXT_LEAF,
name: aTextName,
},
],
};
testAccessibleTree(getDocNode(aID), tree);
};
}
// //////////////////////////////////////////////////////////////////////////
// Invokers
function writeIFrameDoc(aID) {
this.__proto__ = new rootContentReplaced(aID,
"hello");
this.invoke = function writeIFrameDoc_invoke() {
var docNode = getDocNode(aID);
// We can
't use open/write/close outside of iframe document because of
// security error.
var script = docNode.createElement(
"script");
script.textContent =
"document.open(); document.write('hello'); document.close();";
docNode.
body.appendChild(
script);
};
this.getID = function writeIFrameDoc_getID() {
return
"write document";
};
}
/**
* Replace
HTML element.
*/
function replaceIFrameHTMLElm(aID) {
this.eventSeq = [
new invokerChecker(EVENT_SHOW, getDocChildNode, aID),
new invokerChecker(EVENT_REORDER, getDocNode, aID),
];
this.invoke = function replaceIFrameHTMLElm_invoke() {
var docNode = getDocNode(aID);
var newHTMLNode = docNode.createElement(
"html");
newHTMLNode.innerHTML = `<
body><p>New Wave</p></
body`;
docNode.replaceChild(newHTMLNode, docNode.documentElement);
};
this.finalCheck = function replaceIFrameHTMLElm_finalCheck() {
var tree = {
role: ROLE_DOCUMENT,
children: [
{
role: ROLE_PARAGRAPH,
children: [
{
role: ROLE_TEXT_LEAF,
name:
"New Wave",
},
],
},
],
};
testAccessibleTree(getDocNode(aID), tree);
};
this.getID = function replaceIFrameHTMLElm_getID() {
return
"replace HTML element";
};
}
/**
* Replace
HTML body on new
body having ARIA role.
*/
function replaceIFrameBody(aID) {
this.__proto__ = new rootContentReplaced(aID,
"New Hello");
this.invoke = function replaceIFrameBody_invoke() {
var docNode = getDocNode(aID);
var newBodyNode = docNode.createElement(
"body");
var newTextNode = docNode.createTextNode(
"New Hello");
newBodyNode.appendChild(newTextNode);
docNode.documentElement.replaceChild(newBodyNode, docNode.
body);
};
this.getID = function replaceIFrameBody_getID() {
return
"replace body";
};
}
/**
* Replace
HTML body on new
body having ARIA role.
*/
function replaceIFrameBodyOnARIARoleBody(aID) {
this.__proto__ = new rootContentReplaced(aID,
"New Hello",
ROLE_APPLICATION);
this.invoke = function replaceIFrameBodyOnARIARoleBody_invoke() {
var docNode = getDocNode(aID);
var newBodyNode = docNode.createElement(
"body");
var newTextNode = docNode.createTextNode(
"New Hello");
newBodyNode.appendChild(newTextNode);
newBodyNode.setAttribute(
"role",
"application");
docNode.documentElement.replaceChild(newBodyNode, docNode.
body);
};
this.getID = function replaceIFrameBodyOnARIARoleBody_getID() {
return
"replace body on body having ARIA role";
};
}
/**
* Open/close document pair.
*/
function openIFrameDoc(aID) {
this.__proto__ = new rootContentRemoved(aID);
this.invoke = function openIFrameDoc_invoke() {
this.preinvoke();
// Open document.
var docNode = getDocNode(aID);
var script = docNode.createElement(
"script");
script.textContent =
"function closeMe() { document.write('Works?'); document.close(); } window.closeMe = closeMe; document.open();";
docNode.
body.appendChild(
script);
};
this.getID = function openIFrameDoc_getID() {
return
"open document";
};
}
function closeIFrameDoc(aID) {
this.__proto__ = new rootContentInserted(aID,
"Works?");
this.invoke = function closeIFrameDoc_invoke() {
// Write and close document.
getDocNode(aID).write(
"Works?"); getDocNode(aID).close();
};
this.getID = function closeIFrameDoc_getID() {
return
"close document";
};
}
/**
* Remove/insert
HTML element pair.
*/
function removeHTMLFromIFrameDoc(aID) {
this.__proto__ = new rootContentRemoved(aID);
this.invoke = function removeHTMLFromIFrameDoc_invoke() {
this.preinvoke();
// Remove
HTML element.
var docNode = getDocNode(aID);
docNode.firstChild.remove();
};
this.getID = function removeHTMLFromIFrameDoc_getID() {
return
"remove HTML element";
};
}
function insertHTMLToIFrameDoc(aID) {
this.__proto__ = new rootContentInserted(aID,
"Haha");
this.invoke = function insertHTMLToIFrameDoc_invoke() {
// Insert
HTML element.
var docNode = getDocNode(aID);
var html = docNode.createElement(
"html");
var body = docNode.createElement(
"body");
var text = docNode.createTextNode(
"Haha");
body.appendChild(text);
html.appendChild(
body);
docNode.appendChild(
html);
};
this.getID = function insertHTMLToIFrameDoc_getID() {
return
"insert HTML element document";
};
}
/**
* Remove/insert
HTML body pair.
*/
function removeBodyFromIFrameDoc(aID) {
this.__proto__ = new rootContentRemoved(aID);
this.invoke = function removeBodyFromIFrameDoc_invoke() {
this.preinvoke();
// Remove
body element.
var docNode = getDocNode(aID);
docNode.documentElement.removeChild(docNode.
body);
};
this.getID = function removeBodyFromIFrameDoc_getID() {
return
"remove body element";
};
}
function insertElmUnderDocElmWhileBodyMissed(aID) {
this.docNode = null;
this.inputNode = null;
function getInputNode() { return this.inputNode; }
this.eventSeq = [
new invokerChecker(EVENT_SHOW, getInputNode.bind(this)),
new invokerChecker(EVENT_REORDER, getDocNode, aID),
];
this.invoke = function invoke() {
this.docNode = getDocNode(aID);
this.inputNode = this.docNode.createElement(
"input");
this.docNode.documentElement.appendChild(this.inputNode);
};
this.finalCheck = function finalCheck() {
var tree =
{ DOCUMENT: [
{ ENTRY: [ ] },
] };
testAccessibleTree(this.docNode, tree);
// Remove aftermath of this test before next test starts.
this.docNode.documentElement.removeChild(this.inputNode);
};
this.getID = function getID() {
return
"Insert element under document element while body is missed.";
};
}
function insertBodyToIFrameDoc(aID) {
this.__proto__ = new rootContentInserted(aID,
"Yo ho ho i butylka roma!");
this.invoke = function insertBodyToIFrameDoc_invoke() {
// Insert
body element.
var docNode = getDocNode(aID);
var body = docNode.createElement(
"body");
var text = docNode.createTextNode(
"Yo ho ho i butylka roma!");
body.appendChild(text);
docNode.documentElement.appendChild(
body);
};
this.getID = function insertBodyToIFrameDoc_getID() {
return
"insert body element";
};
}
function changeSrc(aID) {
this.containerNode = getNode(aID);
this.eventSeq = [
new invokerChecker(EVENT_REORDER, this.containerNode),
];
this.invoke = function changeSrc_invoke() {
this.containerNode.src =
"data:text/html,<html><input></html>";
};
this.finalCheck = function changeSrc_finalCheck() {
var tree =
{ INTERNAL_FRAME: [
{ DOCUMENT: [
{ ENTRY: [ ] },
] },
] };
testAccessibleTree(this.containerNode, tree);
};
this.getID = function changeSrc_getID() {
return
"change src on iframe";
};
}
// //////////////////////////////////////////////////////////////////////////
// Test
// gA11yEventDumpToConsole = true;
// enableLogging(
'tree,verbose');
var gQueue = null;
function doTest() {
gQueue = new eventQueue();
gQueue.push(new writeIFrameDoc(
"iframe"));
gQueue.push(new replaceIFrameHTMLElm(
"iframe"));
gQueue.push(new replaceIFrameBody(
"iframe"));
gQueue.push(new openIFrameDoc(
"iframe"));
gQueue.push(new closeIFrameDoc(
"iframe"));
gQueue.push(new removeHTMLFromIFrameDoc(
"iframe"));
gQueue.push(new insertHTMLToIFrameDoc(
"iframe"));
gQueue.push(new removeBodyFromIFrameDoc(
"iframe"));
gQueue.push(new insertElmUnderDocElmWhileBodyMissed(
"iframe"));
gQueue.push(new insertBodyToIFrameDoc(
"iframe"));
gQueue.push(new changeSrc(
"iframe"));
gQueue.push(new replaceIFrameBodyOnARIARoleBody(
"iframe"));
gQueue.invoke(); // SimpleTest.finish() will be called in the end
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
</
script>
</
head>
<
body>
<a target=
"_blank"
title=
"Update accessible tree when root element is changed"
href=
"https://bugzilla.mozilla.org/show_bug.cgi?id=606082">Mozilla Bug 606082</a>
<a target=
"_blank"
title=
"Elements inserted outside the body aren't accessible"
href=
"https://bugzilla.mozilla.org/show_bug.cgi?id=608887">Mozilla Bug 608887</a>
<a target=
"_blank"
title=
"Reorder event for document must be fired after document initial tree creation"
href=
"https://bugzilla.mozilla.org/show_bug.cgi?id=669263">Mozilla Bug 669263</a>
<a target=
"_blank"
title=
"Changing the HTML body doesn't pick up ARIA role"
href=
"https://bugzilla.mozilla.org/show_bug.cgi?id=818407">Mozilla Bug 818407</a>
<p id=
"display"></p>
<
div id=
"content" style=
"display: none"></
div>
<
pre id=
"test">
</
pre>
<
iframe id=
"iframe"></
iframe>
<
div id=
"eventdump"></
div>
</
body>
</
html>