test_text_alg.html (7876B)
1 <html> 2 3 <head> 4 <title>Accessible text update algorithm testing</title> 5 6 <link rel="stylesheet" type="text/css" 7 href="chrome://mochikit/content/tests/SimpleTest/test.css" /> 8 9 <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> 10 <script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script> 11 12 <script type="application/javascript" 13 src="../common.js"></script> 14 <script type="application/javascript" 15 src="../events.js"></script> 16 17 <script type="application/javascript"> 18 // ////////////////////////////////////////////////////////////////////////// 19 // Invokers 20 21 const kRemoval = false; 22 const kInsertion = true; 23 const kUnexpected = true; 24 25 function changeText(aContainerID, aValue, aEventList) { 26 this.containerNode = getNode(aContainerID); 27 this.textNode = this.containerNode.firstChild; 28 this.textData = this.textNode.data; 29 30 this.eventSeq = [ ]; 31 this.unexpectedEventSeq = [ ]; 32 33 for (var i = 0; i < aEventList.length; i++) { 34 var event = aEventList[i]; 35 36 var isInserted = event[0]; 37 var str = event[1]; 38 var offset = event[2]; 39 var checker = new textChangeChecker(this.containerNode, offset, 40 offset + str.length, str, 41 isInserted); 42 43 if (event[3] == kUnexpected) 44 this.unexpectedEventSeq.push(checker); 45 else 46 this.eventSeq.push(checker); 47 } 48 49 this.invoke = function changeText_invoke() { 50 this.textNode.data = aValue; 51 }; 52 53 this.getID = function changeText_getID() { 54 return "change text '" + shortenString(this.textData) + "' -> '" + 55 shortenString(this.textNode.data) + "' for " + 56 prettyName(this.containerNode); 57 }; 58 } 59 60 function expStr(x, doublings) { 61 for (var i = 0; i < doublings; ++i) 62 x = x + x; 63 return x; 64 } 65 66 // ////////////////////////////////////////////////////////////////////////// 67 // Do tests 68 69 // gA11yEventDumpID = "eventdump"; // debug stuff 70 // gA11yEventDumpToConsole = true; 71 72 var gQueue = null; 73 function doTests() { 74 gQueue = new eventQueue(); 75 76 // //////////////////////////////////////////////////////////////////////// 77 // wqrema -> tqb: substitution coalesced with removal 78 79 var events = [ 80 [ kRemoval, "w", 0 ], // wqrema -> qrema 81 [ kInsertion, "t", 0], // qrema -> tqrema 82 [ kRemoval, "rema", 2 ], // tqrema -> tq 83 [ kInsertion, "b", 2], // tq -> tqb 84 ]; 85 gQueue.push(new changeText("p1", "tqb", events)); 86 87 // //////////////////////////////////////////////////////////////////////// 88 // b -> insa: substitution coalesced with insertion (complex substitution) 89 90 events = [ 91 [ kRemoval, "b", 0 ], // b -> 92 [ kInsertion, "insa", 0], // -> insa 93 ]; 94 gQueue.push(new changeText("p2", "insa", events)); 95 96 // //////////////////////////////////////////////////////////////////////// 97 // abc -> def: coalesced substitutions 98 99 events = [ 100 [ kRemoval, "abc", 0 ], // abc -> 101 [ kInsertion, "def", 0], // -> def 102 ]; 103 gQueue.push(new changeText("p3", "def", events)); 104 105 // //////////////////////////////////////////////////////////////////////// 106 // abcabc -> abcDEFabc: coalesced insertions 107 108 events = [ 109 [ kInsertion, "DEF", 3], // abcabc -> abcDEFabc 110 ]; 111 gQueue.push(new changeText("p4", "abcDEFabc", events)); 112 113 // //////////////////////////////////////////////////////////////////////// 114 // abc -> defabc: insertion into begin 115 116 events = [ 117 [ kInsertion, "def", 0], // abc -> defabc 118 ]; 119 gQueue.push(new changeText("p5", "defabc", events)); 120 121 // //////////////////////////////////////////////////////////////////////// 122 // abc -> abcdef: insertion into end 123 124 events = [ 125 [ kInsertion, "def", 3], // abc -> abcdef 126 ]; 127 gQueue.push(new changeText("p6", "abcdef", events)); 128 129 // //////////////////////////////////////////////////////////////////////// 130 // defabc -> abc: removal from begin 131 132 events = [ 133 [ kRemoval, "def", 0], // defabc -> abc 134 ]; 135 gQueue.push(new changeText("p7", "abc", events)); 136 137 // //////////////////////////////////////////////////////////////////////// 138 // abcdef -> abc: removal from the end 139 140 events = [ 141 [ kRemoval, "def", 3], // abcdef -> abc 142 ]; 143 gQueue.push(new changeText("p8", "abc", events)); 144 145 // //////////////////////////////////////////////////////////////////////// 146 // abcDEFabc -> abcabc: coalesced removals 147 148 events = [ 149 [ kRemoval, "DEF", 3], // abcDEFabc -> abcabc 150 ]; 151 gQueue.push(new changeText("p9", "abcabc", events)); 152 153 // //////////////////////////////////////////////////////////////////////// 154 // !abcdef@ -> @axbcef!: insertion, deletion and substitutions 155 156 events = [ 157 [ kRemoval, "!", 0 ], // !abcdef@ -> abcdef@ 158 [ kInsertion, "@", 0], // abcdef@ -> @abcdef@ 159 [ kInsertion, "x", 2 ], // @abcdef@ -> @axbcdef@ 160 [ kRemoval, "d", 5], // @axbcdef@ -> @axbcef@ 161 [ kRemoval, "@", 7 ], // @axbcef@ -> @axbcef 162 [ kInsertion, "!", 7 ], // @axbcef -> @axbcef! 163 ]; 164 gQueue.push(new changeText("p10", "@axbcef!", events)); 165 166 // //////////////////////////////////////////////////////////////////////// 167 // meilenstein -> levenshtein: insertion, complex and simple substitutions 168 169 events = [ 170 [ kRemoval, "m", 0 ], // meilenstein -> eilenstein 171 [ kInsertion, "l", 0], // eilenstein -> leilenstein 172 [ kRemoval, "il", 2 ], // leilenstein -> leenstein 173 [ kInsertion, "v", 2], // leenstein -> levenstein 174 [ kInsertion, "h", 6 ], // levenstein -> levenshtein 175 ]; 176 gQueue.push(new changeText("p11", "levenshtein", events)); 177 178 // //////////////////////////////////////////////////////////////////////// 179 // long strings, remove/insert pair as the old string was replaced on 180 // new one 181 182 var longStr1 = expStr("x", 16); 183 var longStr2 = expStr("X", 16); 184 185 var newStr = "a" + longStr1 + "b", insStr = longStr1, rmStr = ""; 186 events = [ 187 [ kRemoval, rmStr, 1, kUnexpected ], 188 [ kInsertion, insStr, 1 ], 189 ]; 190 gQueue.push(new changeText("p12", newStr, events)); 191 192 newStr = "a" + longStr2 + "b"; 193 insStr = longStr2; 194 rmStr = longStr1; 195 events = [ 196 [ kRemoval, rmStr, 1 ], 197 [ kInsertion, insStr, 1], 198 ]; 199 gQueue.push(new changeText("p12", newStr, events)); 200 201 newStr = "ab"; 202 insStr = ""; 203 rmStr = longStr2; 204 events = [ 205 [ kRemoval, rmStr, 1 ], 206 [ kInsertion, insStr, 1, kUnexpected ], 207 ]; 208 gQueue.push(new changeText("p12", newStr, events)); 209 210 gQueue.invoke(); // Will call SimpleTest.finish(); 211 } 212 213 SimpleTest.waitForExplicitFinish(); 214 addA11yLoadEvent(doTests); 215 </script> 216 </head> 217 218 <body> 219 220 <a target="_blank" 221 href="https://bugzilla.mozilla.org/show_bug.cgi?id=626660" 222 title="Cache rendered text on a11y side"> 223 Mozilla Bug 626660 224 </a> 225 <br> 226 227 <p id="display"></p> 228 <div id="content" style="display: none"></div> 229 <pre id="test"> 230 </pre> 231 <div id="eventdump"></div> 232 233 <!-- Note: only editable text gets diffed this way. --> 234 <div contenteditable="true"> 235 <p id="p1">wqrema</p> 236 <p id="p2">b</p> 237 <p id="p3">abc</p> 238 <p id="p4">abcabc</p> 239 <p id="p5">abc</p> 240 <p id="p6">abc</p> 241 <p id="p7">defabc</p> 242 <p id="p8">abcdef</p> 243 <p id="p9">abcDEFabc</p> 244 <p id="p10">!abcdef@</p> 245 <p id="p11">meilenstein</p> 246 <p id="p12">ab</p> 247 </div> 248 </body> 249 </html>