1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/accessible/tests/mochitest/treeupdate/test_doc.html Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,447 @@ 1.4 +<!DOCTYPE html> 1.5 +<html> 1.6 + 1.7 +<head> 1.8 + <title>Test document root content mutations</title> 1.9 + <link rel="stylesheet" type="text/css" 1.10 + href="chrome://mochikit/content/tests/SimpleTest/test.css" /> 1.11 + 1.12 + <script type="application/javascript" 1.13 + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> 1.14 + 1.15 + <script type="application/javascript" 1.16 + src="../common.js"></script> 1.17 + <script type="application/javascript" 1.18 + src="../role.js"></script> 1.19 + <script type="application/javascript" 1.20 + src="../states.js"></script> 1.21 + <script type="application/javascript" 1.22 + src="../events.js"></script> 1.23 + 1.24 + <script type="application/javascript"> 1.25 + 1.26 + //////////////////////////////////////////////////////////////////////////// 1.27 + // Helpers 1.28 + 1.29 + function getDocNode(aID) 1.30 + { 1.31 + return getNode(aID).contentDocument; 1.32 + } 1.33 + function getDocChildNode(aID) 1.34 + { 1.35 + return getDocNode(aID).body.firstChild; 1.36 + } 1.37 + 1.38 + function rootContentReplaced(aID, aTextName, aRootContentRole) 1.39 + { 1.40 + this.eventSeq = [ 1.41 + new invokerChecker(EVENT_SHOW, getDocChildNode, aID), 1.42 + new invokerChecker(EVENT_REORDER, getDocNode, aID) 1.43 + ]; 1.44 + 1.45 + this.finalCheck = function rootContentReplaced_finalCheck() 1.46 + { 1.47 + var tree = { 1.48 + role: aRootContentRole || ROLE_DOCUMENT, 1.49 + children: [ 1.50 + { 1.51 + role: ROLE_TEXT_LEAF, 1.52 + name: aTextName 1.53 + } 1.54 + ] 1.55 + }; 1.56 + testAccessibleTree(getDocNode(aID), tree); 1.57 + } 1.58 + } 1.59 + 1.60 + function rootContentRemoved(aID) 1.61 + { 1.62 + this.eventSeq = [ 1.63 + new invokerChecker(EVENT_HIDE, null), 1.64 + new invokerChecker(EVENT_REORDER, getDocNode, aID) 1.65 + ]; 1.66 + 1.67 + this.preinvoke = function rootContentRemoved_preinvoke() 1.68 + { 1.69 + // Set up target for hide event before we invoke. 1.70 + var text = getAccessible(getAccessible(getDocNode(aID)).firstChild); 1.71 + this.eventSeq[0].target = text; 1.72 + } 1.73 + 1.74 + this.finalCheck = function rootContentRemoved_finalCheck() 1.75 + { 1.76 + var tree = { 1.77 + role: ROLE_DOCUMENT, 1.78 + children: [ ] 1.79 + }; 1.80 + testAccessibleTree(getDocNode(aID), tree); 1.81 + } 1.82 + } 1.83 + 1.84 + function rootContentInserted(aID, aTextName) 1.85 + { 1.86 + this.eventSeq = [ 1.87 + new invokerChecker(EVENT_SHOW, getDocChildNode, aID), 1.88 + new invokerChecker(EVENT_REORDER, getDocNode, aID) 1.89 + ]; 1.90 + 1.91 + this.finalCheck = function rootContentInserted_finalCheck() 1.92 + { 1.93 + var tree = { 1.94 + role: ROLE_DOCUMENT, 1.95 + children: [ 1.96 + { 1.97 + role: ROLE_TEXT_LEAF, 1.98 + name: aTextName 1.99 + } 1.100 + ] 1.101 + }; 1.102 + testAccessibleTree(getDocNode(aID), tree); 1.103 + } 1.104 + } 1.105 + 1.106 + //////////////////////////////////////////////////////////////////////////// 1.107 + // Invokers 1.108 + 1.109 + function writeIFrameDoc(aID) 1.110 + { 1.111 + this.__proto__ = new rootContentReplaced(aID, "hello"); 1.112 + 1.113 + this.invoke = function writeIFrameDoc_invoke() 1.114 + { 1.115 + var docNode = getDocNode(aID); 1.116 + 1.117 + // We can't use open/write/close outside of iframe document because of 1.118 + // security error. 1.119 + var script = docNode.createElement("script"); 1.120 + script.textContent = "document.open(); document.write('hello'); document.close();"; 1.121 + docNode.body.appendChild(script); 1.122 + } 1.123 + 1.124 + this.getID = function writeIFrameDoc_getID() 1.125 + { 1.126 + return "write document"; 1.127 + } 1.128 + } 1.129 + 1.130 + /** 1.131 + * Replace HTML element. 1.132 + */ 1.133 + function replaceIFrameHTMLElm(aID) 1.134 + { 1.135 + this.__proto__ = new rootContentReplaced(aID, "New Wave"); 1.136 + 1.137 + this.invoke = function replaceIFrameHTMLElm_invoke() 1.138 + { 1.139 + var docNode = getDocNode(aID); 1.140 + var newHTMLNode = docNode.createElement("html"); 1.141 + var newBodyNode = docNode.createElement("body"); 1.142 + var newTextNode = docNode.createTextNode("New Wave"); 1.143 + newBodyNode.appendChild(newTextNode); 1.144 + newHTMLNode.appendChild(newBodyNode); 1.145 + docNode.replaceChild(newHTMLNode, docNode.documentElement); 1.146 + } 1.147 + 1.148 + this.getID = function replaceIFrameHTMLElm_getID() 1.149 + { 1.150 + return "replace HTML element"; 1.151 + } 1.152 + } 1.153 + 1.154 + /** 1.155 + * Replace HTML body on new body having ARIA role. 1.156 + */ 1.157 + function replaceIFrameBody(aID) 1.158 + { 1.159 + this.__proto__ = new rootContentReplaced(aID, "New Hello"); 1.160 + 1.161 + this.invoke = function replaceIFrameBody_invoke() 1.162 + { 1.163 + var docNode = getDocNode(aID); 1.164 + var newBodyNode = docNode.createElement("body"); 1.165 + var newTextNode = docNode.createTextNode("New Hello"); 1.166 + newBodyNode.appendChild(newTextNode); 1.167 + docNode.documentElement.replaceChild(newBodyNode, docNode.body); 1.168 + } 1.169 + 1.170 + this.getID = function replaceIFrameBody_getID() 1.171 + { 1.172 + return "replace body"; 1.173 + } 1.174 + } 1.175 + 1.176 + /** 1.177 + * Replace HTML body on new body having ARIA role. 1.178 + */ 1.179 + function replaceIFrameBodyOnARIARoleBody(aID) 1.180 + { 1.181 + this.__proto__ = new rootContentReplaced(aID, "New Hello", 1.182 + ROLE_PUSHBUTTON); 1.183 + 1.184 + this.invoke = function replaceIFrameBodyOnARIARoleBody_invoke() 1.185 + { 1.186 + var docNode = getDocNode(aID); 1.187 + var newBodyNode = docNode.createElement("body"); 1.188 + var newTextNode = docNode.createTextNode("New Hello"); 1.189 + newBodyNode.appendChild(newTextNode); 1.190 + newBodyNode.setAttribute("role", "button"); 1.191 + docNode.documentElement.replaceChild(newBodyNode, docNode.body); 1.192 + } 1.193 + 1.194 + this.getID = function replaceIFrameBodyOnARIARoleBody_getID() 1.195 + { 1.196 + return "replace body on body having ARIA role"; 1.197 + } 1.198 + } 1.199 + 1.200 + /** 1.201 + * Open/close document pair. 1.202 + */ 1.203 + function openIFrameDoc(aID) 1.204 + { 1.205 + this.__proto__ = new rootContentRemoved(aID); 1.206 + 1.207 + this.invoke = function openIFrameDoc_invoke() 1.208 + { 1.209 + this.preinvoke(); 1.210 + 1.211 + // Open document. 1.212 + var docNode = getDocNode(aID); 1.213 + var script = docNode.createElement("script"); 1.214 + script.textContent = "function closeMe() { document.write('Works?'); document.close(); } window.closeMe = closeMe; document.open();"; 1.215 + docNode.body.appendChild(script); 1.216 + } 1.217 + 1.218 + this.getID = function openIFrameDoc_getID() 1.219 + { 1.220 + return "open document"; 1.221 + } 1.222 + } 1.223 + 1.224 + function closeIFrameDoc(aID) 1.225 + { 1.226 + this.__proto__ = new rootContentInserted(aID, "Works?"); 1.227 + 1.228 + this.invoke = function closeIFrameDoc_invoke() 1.229 + { 1.230 + // Write and close document. 1.231 + getDocNode(aID).write('Works?'); getDocNode(aID).close(); 1.232 + } 1.233 + 1.234 + this.getID = function closeIFrameDoc_getID() 1.235 + { 1.236 + return "close document"; 1.237 + } 1.238 + } 1.239 + 1.240 + /** 1.241 + * Remove/insert HTML element pair. 1.242 + */ 1.243 + function removeHTMLFromIFrameDoc(aID) 1.244 + { 1.245 + this.__proto__ = new rootContentRemoved(aID); 1.246 + 1.247 + this.invoke = function removeHTMLFromIFrameDoc_invoke() 1.248 + { 1.249 + this.preinvoke(); 1.250 + 1.251 + // Remove HTML element. 1.252 + var docNode = getDocNode(aID); 1.253 + docNode.removeChild(docNode.firstChild); 1.254 + } 1.255 + 1.256 + this.getID = function removeHTMLFromIFrameDoc_getID() 1.257 + { 1.258 + return "remove HTML element"; 1.259 + } 1.260 + } 1.261 + 1.262 + function insertHTMLToIFrameDoc(aID) 1.263 + { 1.264 + this.__proto__ = new rootContentInserted(aID, "Haha"); 1.265 + 1.266 + this.invoke = function insertHTMLToIFrameDoc_invoke() 1.267 + { 1.268 + // Insert HTML element. 1.269 + var docNode = getDocNode(aID); 1.270 + var html = docNode.createElement("html"); 1.271 + var body = docNode.createElement("body"); 1.272 + var text = docNode.createTextNode("Haha"); 1.273 + body.appendChild(text); 1.274 + html.appendChild(body); 1.275 + docNode.appendChild(html); 1.276 + } 1.277 + 1.278 + this.getID = function insertHTMLToIFrameDoc_getID() 1.279 + { 1.280 + return "insert HTML element document"; 1.281 + } 1.282 + } 1.283 + 1.284 + /** 1.285 + * Remove/insert HTML body pair. 1.286 + */ 1.287 + function removeBodyFromIFrameDoc(aID) 1.288 + { 1.289 + this.__proto__ = new rootContentRemoved(aID); 1.290 + 1.291 + this.invoke = function removeBodyFromIFrameDoc_invoke() 1.292 + { 1.293 + this.preinvoke(); 1.294 + 1.295 + // Remove body element. 1.296 + var docNode = getDocNode(aID); 1.297 + docNode.documentElement.removeChild(docNode.body); 1.298 + } 1.299 + 1.300 + this.getID = function removeBodyFromIFrameDoc_getID() 1.301 + { 1.302 + return "remove body element"; 1.303 + } 1.304 + } 1.305 + 1.306 + function insertElmUnderDocElmWhileBodyMissed(aID) 1.307 + { 1.308 + this.docNode = null; 1.309 + this.inputNode = null; 1.310 + 1.311 + function getInputNode() 1.312 + { return this.inputNode; } 1.313 + 1.314 + this.eventSeq = [ 1.315 + new invokerChecker(EVENT_SHOW, getInputNode.bind(this)), 1.316 + new invokerChecker(EVENT_REORDER, getDocNode, aID) 1.317 + ]; 1.318 + 1.319 + this.invoke = function invoke() 1.320 + { 1.321 + this.docNode = getDocNode(aID); 1.322 + this.inputNode = this.docNode.createElement("input"); 1.323 + this.docNode.documentElement.appendChild(this.inputNode); 1.324 + } 1.325 + 1.326 + this.finalCheck = function finalCheck() 1.327 + { 1.328 + var tree = 1.329 + { DOCUMENT: [ 1.330 + { ENTRY: [ ] } 1.331 + ] }; 1.332 + testAccessibleTree(this.docNode, tree); 1.333 + 1.334 + // Remove aftermath of this test before next test starts. 1.335 + this.docNode.documentElement.removeChild(this.inputNode); 1.336 + } 1.337 + 1.338 + this.getID = function getID() 1.339 + { 1.340 + return "Insert element under document element while body is missed."; 1.341 + } 1.342 + } 1.343 + 1.344 + function insertBodyToIFrameDoc(aID) 1.345 + { 1.346 + this.__proto__ = new rootContentInserted(aID, "Yo ho ho i butylka roma!"); 1.347 + 1.348 + this.invoke = function insertBodyToIFrameDoc_invoke() 1.349 + { 1.350 + // Insert body element. 1.351 + var docNode = getDocNode(aID); 1.352 + var body = docNode.createElement("body"); 1.353 + var text = docNode.createTextNode("Yo ho ho i butylka roma!"); 1.354 + body.appendChild(text); 1.355 + docNode.documentElement.appendChild(body); 1.356 + } 1.357 + 1.358 + this.getID = function insertBodyToIFrameDoc_getID() 1.359 + { 1.360 + return "insert body element"; 1.361 + } 1.362 + } 1.363 + 1.364 + function changeSrc(aID) 1.365 + { 1.366 + this.containerNode = getNode(aID); 1.367 + 1.368 + this.eventSeq = [ 1.369 + new invokerChecker(EVENT_REORDER, this.containerNode) 1.370 + ]; 1.371 + 1.372 + this.invoke = function changeSrc_invoke() 1.373 + { 1.374 + this.containerNode.src = "data:text/html,<html><input></html>"; 1.375 + } 1.376 + 1.377 + this.finalCheck = function changeSrc_finalCheck() 1.378 + { 1.379 + var tree = 1.380 + { INTERNAL_FRAME: [ 1.381 + { DOCUMENT: [ 1.382 + { ENTRY: [ ] } 1.383 + ] } 1.384 + ] }; 1.385 + testAccessibleTree(this.containerNode, tree); 1.386 + } 1.387 + 1.388 + this.getID = function changeSrc_getID() 1.389 + { 1.390 + return "change src on iframe"; 1.391 + } 1.392 + } 1.393 + 1.394 + //////////////////////////////////////////////////////////////////////////// 1.395 + // Test 1.396 + 1.397 + //gA11yEventDumpID = "eventdump"; // debug stuff 1.398 + //gA11yEventDumpToConsole = true; 1.399 + 1.400 + var gQueue = null; 1.401 + 1.402 + function doTest() 1.403 + { 1.404 + gQueue = new eventQueue(); 1.405 + 1.406 + gQueue.push(new writeIFrameDoc("iframe")); 1.407 + gQueue.push(new replaceIFrameHTMLElm("iframe")); 1.408 + gQueue.push(new replaceIFrameBody("iframe")); 1.409 + gQueue.push(new openIFrameDoc("iframe")); 1.410 + gQueue.push(new closeIFrameDoc("iframe")); 1.411 + gQueue.push(new removeHTMLFromIFrameDoc("iframe")); 1.412 + gQueue.push(new insertHTMLToIFrameDoc("iframe")); 1.413 + gQueue.push(new removeBodyFromIFrameDoc("iframe")); 1.414 + gQueue.push(new insertElmUnderDocElmWhileBodyMissed("iframe")); 1.415 + gQueue.push(new insertBodyToIFrameDoc("iframe")); 1.416 + gQueue.push(new changeSrc("iframe")); 1.417 + gQueue.push(new replaceIFrameBodyOnARIARoleBody("iframe")); 1.418 + 1.419 + gQueue.invoke(); // SimpleTest.finish() will be called in the end 1.420 + } 1.421 + 1.422 + SimpleTest.waitForExplicitFinish(); 1.423 + addA11yLoadEvent(doTest); 1.424 + </script> 1.425 +</head> 1.426 +<body> 1.427 + 1.428 + <a target="_blank" 1.429 + title="Update accessible tree when root element is changed" 1.430 + href="https://bugzilla.mozilla.org/show_bug.cgi?id=606082">Mozilla Bug 606082</a> 1.431 + <a target="_blank" 1.432 + title="Elements inserted outside the body aren't accessible" 1.433 + href="https://bugzilla.mozilla.org/show_bug.cgi?id=608887">Mozilla Bug 608887</a> 1.434 + <a target="_blank" 1.435 + title="Reorder event for document must be fired after document initial tree creation" 1.436 + href="https://bugzilla.mozilla.org/show_bug.cgi?id=669263">Mozilla Bug 669263</a> 1.437 + <a target="_blank" 1.438 + title="Changing the HTML body doesn't pick up ARIA role" 1.439 + href="https://bugzilla.mozilla.org/show_bug.cgi?id=818407">Mozilla Bug 818407</a> 1.440 + 1.441 + <p id="display"></p> 1.442 + <div id="content" style="display: none"></div> 1.443 + <pre id="test"> 1.444 + </pre> 1.445 + 1.446 + <iframe id="iframe"></iframe> 1.447 + 1.448 + <div id="eventdump"></div> 1.449 +</body> 1.450 +</html>