1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/accessible/tests/mochitest/events/test_text.html Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,338 @@ 1.4 +<html> 1.5 + 1.6 +<head> 1.7 + <title>Accessible mutation events testing</title> 1.8 + 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 + <script type="application/javascript" 1.15 + src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script> 1.16 + 1.17 + <script type="application/javascript" 1.18 + src="../common.js"></script> 1.19 + <script type="application/javascript" 1.20 + src="../events.js"></script> 1.21 + 1.22 + <script type="application/javascript"> 1.23 + //////////////////////////////////////////////////////////////////////////// 1.24 + // Invokers 1.25 + 1.26 + /** 1.27 + * Base text remove invoker and checker. 1.28 + */ 1.29 + function textRemoveInvoker(aID, aStart, aEnd, aText) 1.30 + { 1.31 + this.DOMNode = getNode(aID); 1.32 + 1.33 + this.eventSeq = [ 1.34 + new textChangeChecker(aID, aStart, aEnd, aText, false) 1.35 + ]; 1.36 + } 1.37 + 1.38 + function textInsertInvoker(aID, aStart, aEnd, aText) 1.39 + { 1.40 + this.DOMNode = getNode(aID); 1.41 + 1.42 + this.eventSeq = [ 1.43 + new textChangeChecker(aID, aStart, aEnd, aText, true) 1.44 + ]; 1.45 + } 1.46 + 1.47 + /** 1.48 + * Remove inaccessible child node containing accessibles. 1.49 + */ 1.50 + function removeChildSpan(aID) 1.51 + { 1.52 + this.__proto__ = new textRemoveInvoker(aID, 0, 5, "33322"); 1.53 + 1.54 + this.invoke = function removeChildSpan_invoke() 1.55 + { 1.56 + // remove HTML span, a first child of the node 1.57 + this.DOMNode.removeChild(this.DOMNode.firstChild); 1.58 + } 1.59 + 1.60 + this.getID = function removeChildSpan_getID() 1.61 + { 1.62 + return "Remove inaccessible span containing accessible nodes" + prettyName(aID); 1.63 + } 1.64 + } 1.65 + 1.66 + /** 1.67 + * Insert inaccessible child node containing accessibles. 1.68 + */ 1.69 + function insertChildSpan(aID, aInsertAllTogether) 1.70 + { 1.71 + this.__proto__ = new textInsertInvoker(aID, 0, 5, "33322"); 1.72 + 1.73 + this.invoke = function insertChildSpan_invoke() 1.74 + { 1.75 + // <span><span>333</span><span>22</span></span> 1.76 + if (aInsertAllTogether) { 1.77 + var topSpan = document.createElement("span"); 1.78 + var fSpan = document.createElement("span"); 1.79 + fSpan.textContent = "333"; 1.80 + topSpan.appendChild(fSpan); 1.81 + var sSpan = document.createElement("span"); 1.82 + sSpan.textContent = "22"; 1.83 + topSpan.appendChild(sSpan); 1.84 + 1.85 + this.DOMNode.insertBefore(topSpan, this.DOMNode.childNodes[0]); 1.86 + 1.87 + } else { 1.88 + var topSpan = document.createElement("span"); 1.89 + this.DOMNode.insertBefore(topSpan, this.DOMNode.childNodes[0]); 1.90 + 1.91 + var fSpan = document.createElement("span"); 1.92 + fSpan.textContent = "333"; 1.93 + topSpan.appendChild(fSpan); 1.94 + 1.95 + var sSpan = document.createElement("span"); 1.96 + sSpan.textContent = "22"; 1.97 + topSpan.appendChild(sSpan); 1.98 + } 1.99 + } 1.100 + 1.101 + this.getID = function insertChildSpan_getID() 1.102 + { 1.103 + return "Insert inaccessible span containing accessibles" + 1.104 + prettyName(aID); 1.105 + } 1.106 + } 1.107 + 1.108 + /** 1.109 + * Remove child embedded accessible. 1.110 + */ 1.111 + function removeChildDiv(aID) 1.112 + { 1.113 + this.__proto__ = new textRemoveInvoker(aID, 5, 6, kEmbedChar); 1.114 + 1.115 + this.invoke = function removeChildDiv_invoke() 1.116 + { 1.117 + var childDiv = this.DOMNode.childNodes[1]; 1.118 + 1.119 + // Ensure accessible is created to get text remove event when it's 1.120 + // removed. 1.121 + getAccessible(childDiv); 1.122 + 1.123 + this.DOMNode.removeChild(childDiv); 1.124 + } 1.125 + 1.126 + this.getID = function removeChildDiv_getID() 1.127 + { 1.128 + return "Remove accessible div from the middle of text accessible " + 1.129 + prettyName(aID); 1.130 + } 1.131 + } 1.132 + 1.133 + /** 1.134 + * Insert child embedded accessible. 1.135 + */ 1.136 + function insertChildDiv(aID) 1.137 + { 1.138 + this.__proto__ = new textInsertInvoker(aID, 5, 6, kEmbedChar); 1.139 + 1.140 + this.invoke = function insertChildDiv_invoke() 1.141 + { 1.142 + var childDiv = document.createElement("div"); 1.143 + this.DOMNode.insertBefore(childDiv, this.DOMNode.childNodes[1]); 1.144 + } 1.145 + 1.146 + this.getID = function insertChildDiv_getID() 1.147 + { 1.148 + return "Insert accessible div into the middle of text accessible " + 1.149 + prettyName(aID); 1.150 + } 1.151 + } 1.152 + 1.153 + /** 1.154 + * Remove children from text container from first to last child or vice 1.155 + * versa. 1.156 + */ 1.157 + function removeChildren(aID, aLastToFirst, aStart, aEnd, aText) 1.158 + { 1.159 + this.__proto__ = new textRemoveInvoker(aID, aStart, aEnd, aText); 1.160 + 1.161 + this.invoke = function removeChildren_invoke() 1.162 + { 1.163 + if (aLastToFirst) { 1.164 + while (this.DOMNode.firstChild) 1.165 + this.DOMNode.removeChild(this.DOMNode.lastChild); 1.166 + } else { 1.167 + while (this.DOMNode.firstChild) 1.168 + this.DOMNode.removeChild(this.DOMNode.firstChild); 1.169 + } 1.170 + } 1.171 + 1.172 + this.getID = function removeChildren_getID() 1.173 + { 1.174 + return "remove children of " + prettyName(aID) + 1.175 + (aLastToFirst ? " from last to first" : " from first to last"); 1.176 + } 1.177 + } 1.178 + 1.179 + /** 1.180 + * Remove text from HTML input. 1.181 + */ 1.182 + function removeTextFromInput(aID, aStart, aEnd, aText) 1.183 + { 1.184 + this.__proto__ = new textRemoveInvoker(aID, aStart, aEnd, aText); 1.185 + 1.186 + this.eventSeq.push(new invokerChecker(EVENT_VALUE_CHANGE, this.DOMNode)); 1.187 + 1.188 + this.invoke = function removeTextFromInput_invoke() 1.189 + { 1.190 + const nsIDOMNSEditableElement = 1.191 + Components.interfaces.nsIDOMNSEditableElement; 1.192 + 1.193 + this.DOMNode.focus(); 1.194 + this.DOMNode.setSelectionRange(aStart, aEnd); 1.195 + 1.196 + synthesizeKey("VK_DELETE", {}); 1.197 + } 1.198 + 1.199 + this.getID = function removeTextFromInput_getID() 1.200 + { 1.201 + return "Remove text from " + aStart + " to " + aEnd + " for " + 1.202 + prettyName(aID); 1.203 + } 1.204 + } 1.205 + 1.206 + /** 1.207 + * Add text into HTML input. 1.208 + */ 1.209 + function insertTextIntoInput(aID, aStart, aEnd, aText) 1.210 + { 1.211 + this.__proto__ = new textInsertInvoker(aID, aStart, aEnd, aText); 1.212 + 1.213 + this.eventSeq.push(new invokerChecker(EVENT_VALUE_CHANGE, this.DOMNode)); 1.214 + 1.215 + this.invoke = function insertTextIntoInput_invoke() 1.216 + { 1.217 + this.DOMNode.focus(); 1.218 + synthesizeKey("a", {}); 1.219 + } 1.220 + 1.221 + this.getID = function insertTextIntoInput_getID() 1.222 + { 1.223 + return "Insert text to " + aStart + " for " + prettyName(aID); 1.224 + } 1.225 + } 1.226 + 1.227 + /** 1.228 + * Remove text data from text node of editable area. 1.229 + */ 1.230 + function removeTextFromEditable(aID, aStart, aEnd, aText, aTextNode) 1.231 + { 1.232 + this.__proto__ = new textRemoveInvoker(aID, aStart, aEnd, aText); 1.233 + 1.234 + this.invoke = function removeTextFromEditable_invoke() 1.235 + { 1.236 + this.DOMNode.focus(); 1.237 + 1.238 + var selection = window.getSelection(); 1.239 + var range = document.createRange(); 1.240 + range.setStart(this.textNode, aStart); 1.241 + range.setEnd(this.textNode, aEnd); 1.242 + selection.addRange(range); 1.243 + 1.244 + synthesizeKey("VK_DELETE", {}); 1.245 + } 1.246 + 1.247 + this.getID = function removeTextFromEditable_getID() 1.248 + { 1.249 + return "Remove text from " + aStart + " to " + aEnd + " for " + 1.250 + prettyName(aID); 1.251 + } 1.252 + 1.253 + this.textNode = getNode(aTextNode); 1.254 + } 1.255 + 1.256 + //////////////////////////////////////////////////////////////////////////// 1.257 + // Do tests 1.258 + var gQueue = null; 1.259 + //gA11yEventDumpID = "eventdump"; // debug stuff 1.260 + 1.261 + function doTests() 1.262 + { 1.263 + gQueue = new eventQueue(); 1.264 + 1.265 + // Text remove event on inaccessible child HTML span removal containing 1.266 + // accessible text nodes. 1.267 + gQueue.push(new removeChildSpan("p")); 1.268 + gQueue.push(new insertChildSpan("p"), true); 1.269 + gQueue.push(new insertChildSpan("p"), false); 1.270 + 1.271 + // Remove embedded character. 1.272 + gQueue.push(new removeChildDiv("div")); 1.273 + gQueue.push(new insertChildDiv("div")); 1.274 + 1.275 + // Remove all children. 1.276 + var text = kEmbedChar + "txt" + kEmbedChar; 1.277 + gQueue.push(new removeChildren("div2", true, 0, 5, text)); 1.278 + gQueue.push(new removeChildren("div3", false, 0, 5, text)); 1.279 + 1.280 + // Text remove from text node within hypertext accessible. 1.281 + gQueue.push(new removeTextFromInput("input", 1, 3, "al")); 1.282 + gQueue.push(new insertTextIntoInput("input", 1, 2, "a")); 1.283 + 1.284 + // bug 570691 1.285 + todo(false, "Fix text change events from editable area, see bug 570691"); 1.286 + //var textNode = getNode("editable").firstChild; 1.287 + //gQueue.push(new removeTextFromEditable("editable", 1, 3, "al", textNode)); 1.288 + //textNode = getNode("editable2").firstChild.firstChild; 1.289 + //gQueue.push(new removeTextFromEditable("editable2", 1, 3, "al", textNode)); 1.290 + 1.291 + gQueue.invoke(); // Will call SimpleTest.finish(); 1.292 + } 1.293 + 1.294 + SimpleTest.waitForExplicitFinish(); 1.295 + addA11yLoadEvent(doTests); 1.296 + </script> 1.297 +</head> 1.298 + 1.299 +<body> 1.300 + 1.301 + <a target="_blank" 1.302 + href="https://bugzilla.mozilla.org/show_bug.cgi?id=566293" 1.303 + title=" wrong length of text remove event when inaccessible node containing accessible nodes is removed"> 1.304 + Mozilla Bug 566293 1.305 + </a><br> 1.306 + <a target="_blank" 1.307 + href="https://bugzilla.mozilla.org/show_bug.cgi?id=570710" 1.308 + title="Avoid extra array traversal during text event creation"> 1.309 + Mozilla Bug 570710 1.310 + </a><br> 1.311 + <a target="_blank" 1.312 + href="https://bugzilla.mozilla.org/show_bug.cgi?id=574003" 1.313 + title="Coalesce text events on nodes removal"> 1.314 + Mozilla Bug 574003 1.315 + </a> 1.316 + <a target="_blank" 1.317 + href="https://bugzilla.mozilla.org/show_bug.cgi?id=575052" 1.318 + title="Cache text offsets within hypertext accessible"> 1.319 + Mozilla Bug 575052 1.320 + </a> 1.321 + <a target="_blank" 1.322 + href="https://bugzilla.mozilla.org/show_bug.cgi?id=570275" 1.323 + title="Rework accessible tree update code"> 1.324 + Mozilla Bug 570275 1.325 + </a> 1.326 + 1.327 + <p id="display"></p> 1.328 + <div id="content" style="display: none"></div> 1.329 + <pre id="test"> 1.330 + </pre> 1.331 + <div id="eventdump"></div> 1.332 + 1.333 + <p id="p"><span><span>333</span><span>22</span></span>1111</p> 1.334 + <div id="div">hello<div>hello</div>hello</div> 1.335 + <div id="div2"><div>txt</div>txt<div>txt</div></div> 1.336 + <div id="div3"><div>txt</div>txt<div>txt</div></div> 1.337 + <input id="input" value="value"> 1.338 + <div contentEditable="true" id="editable">value</div> 1.339 + <div contentEditable="true" id="editable2"><span>value</span></div> 1.340 +</body> 1.341 +</html>