test_bug496275.html (10112B)
1 <!DOCTYPE HTML> 2 <html> 3 <!-- 4 https://bugzilla.mozilla.org/show_bug.cgi?id=496275 5 --> 6 7 <head> 8 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 9 <title>Test for Bug 496275</title> 10 <script src="/tests/SimpleTest/SimpleTest.js"></script> 11 <script src="/tests/SimpleTest/WindowSnapshot.js"></script> 12 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> 13 </head> 14 15 <body onload="run()" style="font-family: monospace"> 16 <a target="_blank" 17 href="https://bugzilla.mozilla.org/show_bug.cgi?id=496275"> 18 Mozilla Bug 496275 19 </a> 20 <p id="display"></p> 21 <div id="c" contenteditable="true"> 22 <p id="p1">The first paragraph. Another sentence. Even more text.</p> 23 <p id="p2">Paragraph no. 2.</p> 24 <p id="p3">This paragraph<br> 25 is broken up<br> 26 into four<br> 27 lines</p> 28 </div> 29 30 <div id="ltr" contenteditable="true"> 31 <p id="l1">םלש Hello</p> 32 <p id="l2">Goodbye</p> 33 </div> 34 35 <div id="rtl" contenteditable="true" dir="rtl"> 36 <p id="r1">התרגום האחרון שפיתחנו הוא עבור Firefox 3.5.6.</p> 37 <p id="r2">קראו את הערות ההפצה (אנגלית) להוראות ורשימת בעיות ידועות.</p> 38 </div> 39 40 <!-- Special characters: لا is actually two characters, while تَ should be 41 treated as one character. --> 42 <div id="special" contenteditable="true"> 43 <p id="s1">a لا b تَ c</p> 44 </div> 45 46 <div> 47 <p>Anchor offset: <span id="anchor-offset"></span></p> 48 <p>Focus offset: <span id="focus-offset"></span></p> 49 </div> 50 51 <script type="application/javascript"> 52 SimpleTest.waitForExplicitFinish(); 53 SimpleTest.requestFlakyTimeout("untriaged"); 54 SimpleTest.requestFlakyTimeout("untriaged"); 55 56 function isOrIsParent(actual, expected, msg) { 57 // actual should be expected or actual's parent node should be expected. 58 msg += " Expected " + actual + " or " + actual.parentNode + 59 " to be " + expected + "."; 60 61 ok(actual == expected || actual.parentNode == expected, msg); 62 } 63 64 function isAt(anchorNode, anchorOffset, focusNode, focusOffset, msg) { 65 var sel = window.getSelection(); 66 67 isOrIsParent(sel.anchorNode, $(anchorNode), msg + ": Wrong anchor node."); 68 is(sel.anchorOffset, anchorOffset, msg + ": Wrong anchor offset."); 69 isOrIsParent(sel.focusNode, $(focusNode), msg + ": Wrong focus node."); 70 is(sel.focusOffset, $(focusOffset), msg + ": Wrong focus offset."); 71 } 72 73 function run() { 74 var sel = window.getSelection(); 75 76 // If nothing is focused, selection.modify() should silently fail. 77 sel.removeAllRanges(); 78 sel.modify("move", "forward", "character"); 79 80 // Now focus our first div and put the cursor at the beginning of p1. 81 $("c").focus(); 82 sel.collapse($("p1"), 0); 83 84 // We're intentionally inconsistent with the capitalization of "move", 85 // "extend", etc. below to test the case-insensitivity of modify(). 86 87 // If we move backward, selection.modify() shouldn't do anything, since we're 88 // already at the beginning of the frame. 89 isAt("p1", 0, "p1", 0, "test 0a"); 90 sel.modify("Move", "Backward", "Character"); 91 isAt("p1", 0, "p1", 0, "test 0b"); 92 93 // After this move, the cursor should be at the second character of p1 94 sel.modify("Move", "Forward", "Character"); 95 isAt("p1", 1, "p1", 1, "test 1"); 96 97 // Select the first character in p1 98 sel.collapse($("p1"), 0); 99 sel.modify("Extend", "Forward", "Character"); 100 isAt("p1", 0, "p1", 1, "test 2"); 101 sel.modify("Move", "Forward", "Character"); 102 isAt("p1", 2, "p1", 2, "test 2a"); 103 104 // Select all of p1, then move the selection forward one character a few 105 // times. 106 sel.collapse($("p1"), 0); 107 sel.extend($("p1"), 1); 108 sel.modify("move", "forward", "character"); 109 isAt("p2", 0, "p2", 0, "test 3a"); 110 sel.modify("move", "forward", "character"); 111 isAt("p2", 1, "p2", 1, "test 3b"); 112 113 // Put the cursor at the beginning of p3, then extend forward one line. 114 // Now go back twice and forward once. Focus should now be at the end of p3. 115 sel.collapse($("p3"), 0); 116 sel.modify("Extend", "Forward", "Line"); 117 sel.modify("extend", "backward", "character"); 118 sel.modify("extend", "backward", "character"); 119 sel.modify("extend", "forward", "character"); 120 isAt("p3", 0, "p3", 14, "test 4"); 121 122 // Put the cursor at the beginning of p3, then go forward a few words 123 sel.collapse($("p3"), 0); 124 sel.modify("Move", "Forward", "Word"); 125 isAt("p3", 4, "p3", 4, "test 4a"); 126 sel.modify("move", "forward", "word"); 127 // Go back and forward so the indexes are correct. 128 sel.modify("move", "backward", "character"); 129 sel.modify("move", "forward", "character"); 130 isAt("p3", 14, "p3", 14, "test 4b"); 131 132 // Test the lineboundary granularity 133 sel.collapse($("p3"), 0); 134 sel.modify("Move", "Forward", "Lineboundary"); 135 // Go back and forward so the indexes are correct. 136 sel.modify("move", "Backward", "character"); 137 sel.modify("move", "forward", "character"); 138 isAt("p3", 14, "p3", 14, "test 5"); 139 140 // 141 // Test RTL text within a dir=LTR div. 142 // 143 $("ltr").focus(); 144 sel.collapse($("l1"), 0); 145 SpecialPowers.wrap(sel).caretBidiLevel = 1; 146 isAt("l1", 0, "l1", 0, "test 6a"); 147 sel.modify("Move", "Left", "Character"); 148 isAt("l1", 1, "l1", 1, "test 6b"); 149 sel.modify("Extend", "Backward", "Character"); 150 isAt("l1", 1, "l1", 0, "test 6c"); 151 sel.modify("extend", "forward", "character"); 152 isAt("l1", 1, "l1", 1, "test 6d"); 153 sel.modify("Extend", "Right", "Character"); 154 isAt("l1", 1, "l1", 0, "test 6e"); 155 156 sel.collapse($("l1"), 0); 157 SpecialPowers.wrap(sel).caretBidiLevel = 1; 158 sel.modify("move", "left", "character"); 159 sel.modify("extend", "right", "Word"); 160 isAt("l1", 1, "l1", 3, "test 7a"); 161 sel.modify("move", "left", "word"); 162 isAt("l1", 3, "l1", 3, "test 7b"); 163 sel.modify("move", "forward", "word"); 164 isAt("l1", 9, "l1", 9, "test 7c"); 165 sel.modify("extend", "backward", "word"); 166 isAt("l1", 9, "l1", 4, "test 7d"); 167 sel.modify("move", "left", "word"); 168 isAt("l1", 3, "l1", 3, "test 7e"); 169 170 sel.collapse($("l1"), 0); 171 SpecialPowers.wrap(sel).caretBidiLevel = 1; 172 sel.modify("extend", "left", "lineboundary"); 173 isAt("l1", 0, "l1", 0, "test 8a"); 174 sel.modify("move", "forward", "lineboundary"); 175 isAt("l1", 9, "l1", 9, "test 8b"); 176 sel.modify("extend", "backward", "lineboundary"); 177 isAt("l1", 9, "l1", 0, "test 8c"); 178 sel.modify("move", "left", "lineboundary"); 179 isAt("l1", 0, "l1", 0, "test 8d"); 180 sel.modify("extend", "forward", "lineboundary"); 181 isAt("l1", 0, "l1", 9, "test 8e"); 182 183 // Put the cursor at the left edge of the first line so that when we go up 184 // and down, where we end up doesn't depend on how the characters line up. 185 sel.collapse($("l1"), 0); 186 SpecialPowers.wrap(sel).caretBidiLevel = 1; 187 sel.modify("move", "left", "lineboundary"); 188 isAt("l1", 0, "l1", 0, "test 9a"); 189 sel.modify("move", "forward", "Line"); 190 // Offset becomes non-zero because the line boundary was in the middle of the 191 // line. See bug 1667129 192 isAt("l2", 3, "l2", 3, "test 9b"); 193 sel.modify("extend", "backward", "Line"); 194 // Going back to the beginning of the previous line 195 isAt("l2", 3, "l1", 0, "test 9c"); 196 197 // Same test as above, now with absolute directions. 198 sel.collapse($("l1"), 0); 199 SpecialPowers.wrap(sel).caretBidiLevel = 1; 200 sel.modify("move", "left", "lineboundary"); 201 isAt("l1", 0, "l1", 0, "test 10a"); 202 sel.modify("move", "right", "line"); 203 // Also bug 1667129 204 isAt("l2", 3, "l2", 3, "test 10b"); 205 sel.modify("extend", "left", "line"); 206 isAt("l2", 3, "l1", 0, "test 10c"); 207 208 // 209 // Test RTL text within a dir=RTL div. 210 // 211 $("rtl").focus(); 212 sel.collapse($("r1"), 0); 213 sel.modify("move", "forward", "character"); 214 isAt("r1", 1, "r1", 1, "test 11a"); 215 sel.modify("extend", "backward", "character"); 216 isAt("r1", 1, "r1", 0, "test 11b"); 217 sel.modify("move", "forward", "word"); 218 isAt("r1", 6, "r1", 6, "test 11c"); 219 sel.modify("extend", "backward", "word"); 220 isAt("r1", 6, "r1", 0, "test 11d"); 221 sel.modify("extend", "forward", "lineboundary"); 222 isAt("r1", 6, "r1", 45, "test 11e"); 223 224 // Same as above, but with absolute directions. 225 sel.collapse($("r1"), 0); 226 sel.modify("move", "left", "character"); 227 isAt("r1", 1, "r1", 1, "test 12a"); 228 sel.modify("extend", "right", "character"); 229 isAt("r1", 1, "r1", 0, "test 12b"); 230 sel.modify("move", "left", "word"); 231 isAt("r1", 6, "r1", 6, "test 12c"); 232 sel.modify("extend", "right", "word"); 233 isAt("r1", 6, "r1", 0, "test 12d"); 234 235 // Test that move left/right is correct within the RTL div. 236 sel.collapse($("r1"), 0); 237 sel.modify("extend", "left", "lineboundary"); 238 isAt("r1", 0, "r1", 45, "test 13a"); 239 sel.modify("move", "right", "lineboundary"); 240 isAt("r1", 0, "r1", 0, "test 13b"); 241 242 // Test that up/down at the first/last line correctly wraps to the 243 // beginning/end of the line. 244 sel.collapse($("r1"), 0); 245 sel.modify("move", "forward", "word"); 246 isAt("r1", 6, "r1", 6, "test 14a"); 247 // Even in RTL text, "left" still means up. 248 sel.modify("extend", "left", "Line"); 249 isAt("r1", 6, "r1", 0, "test 14b"); 250 sel.modify("move", "right", "line"); 251 isAt("r2", 0, "r2", 0, "test 14c"); 252 sel.modify("extend", "forward", "line"); 253 isAt("r2", 0, "r2", 57, "test 14d"); 254 sel.modify("move", "backward", "line"); 255 isAt("r1", 45, "r1", 45, "test 14e"); 256 257 // Test some special characters. 258 $("special").focus(); 259 sel.collapse($("s1"), 0); 260 sel.modify("move", "forward", "character"); 261 sel.modify("move", "forward", "character"); 262 sel.modify("move", "forward", "character"); 263 isAt("s1", 3, "s1", 3, "test 15a"); 264 sel.modify("move", "forward", "character"); 265 isAt("s1", 4, "s1", 4, "test 15b"); 266 sel.modify("move", "backward", "word"); 267 isAt("s1", 2, "s1", 2, "test 15c"); 268 sel.modify("move", "forward", "word"); 269 sel.modify("move", "forward", "word"); 270 sel.modify("move", "forward", "word"); 271 isAt("s1", 9, "s1", 9, "test 15d"); 272 273 SimpleTest.finish(); 274 } 275 276 function update_debug_info() { 277 var sel = window.getSelection(); 278 document.getElementById("anchor-offset").innerHTML = sel.anchorOffset; 279 document.getElementById("focus-offset").innerHTML = sel.focusOffset; 280 setTimeout(update_debug_info, 100); 281 } 282 283 setTimeout(update_debug_info, 100); 284 285 </script> 286 </body> 287 </html>