test_bug348681.html (20072B)
1 <!DOCTYPE HTML> 2 <!-- This Source Code Form is subject to the terms of the Mozilla Public 3 - License, v. 2.0. If a copy of the MPL was not distributed with this 4 - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> 5 <html> 6 <!-- 7 https://bugzilla.mozilla.org/show_bug.cgi?id=348681 8 --> 9 10 <head> 11 <title>Test for Bug 348681</title> 12 <script src="/tests/SimpleTest/SimpleTest.js"></script> 13 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> 14 <script src="/tests/SimpleTest/EventUtils.js"></script> 15 </head> 16 17 <body onload="loaded()"> 18 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=348681">Mozilla Bug 348681</a> 19 <p id="display"></p> 20 <div id="content" style="display: none"> 21 </div> 22 23 <pre id="test"> 24 <script type="application/javascript"> 25 26 /** Test for Bug 348681 */ 27 28 SimpleTest.waitForExplicitFinish(); 29 30 function loaded() { 31 SpecialPowers.pushPrefEnv({"set": [["dom.testing.selection.GetRangesForInterval", true]]}, doTest); 32 } 33 34 var rangeChecker = { 35 ranges: [], 36 37 reset: function() { 38 this.ranges = []; 39 }, 40 41 check: function(testID, selection) { 42 is(selection.rangeCount, this.ranges.length, 43 "Test "+testID+": correct number of ranges in selection"); 44 var rangesMatch = true; 45 var foundMsg = "Found "; 46 var expectedMsg = "Expected "; 47 var maxIndex = Math.max(selection.rangeCount, this.ranges.length); 48 for (var x = 0; x < maxIndex; x++) { 49 var expect = null; 50 if (x < this.ranges.length) 51 expect = this.ranges[x]; 52 53 var found = null; 54 if (x < selection.rangeCount) 55 found = selection.getRangeAt(x); 56 57 if (found) { 58 foundMsg +="["+found.startOffset+","+found.endOffset+"] "; 59 } 60 if (expect) { 61 expectedMsg +="["+expect.start+","+expect.end+"] "; 62 } 63 64 if (found && expect) { 65 if (found.startContainer != expect.node || 66 found.endContainer != expect.node || 67 found.startOffset != expect.start || 68 found.endOffset != expect.end) 69 rangesMatch = false; 70 } else { 71 rangesMatch = false; 72 } 73 } 74 var okMsg = "Test "+testID+": correct ranges in selection."; 75 okMsg = okMsg + foundMsg + expectedMsg; 76 ok(rangesMatch, okMsg); 77 }, 78 79 addExpected: function(node, start, end) { 80 var expected = {}; 81 expected.node = node; 82 expected.start = start; 83 expected.end = end; 84 this.ranges[this.ranges.length] = expected; 85 this.ranges.sort(function(a,b) {return a.start - b.start;}); 86 } 87 } 88 89 var intervalChecker = { 90 ranges: [], 91 92 reset: function() { 93 this.ranges = []; 94 }, 95 96 check: function(testID, testArr) { 97 is(testArr.length, this.ranges.length, 98 "Test "+testID+": correct number of ranges for interval"); 99 var rangesMatch = true; 100 var foundMsg = "Found "; 101 var expectedMsg = "Expected "; 102 var maxIndex = Math.max(testArr.length, this.ranges.length); 103 for (var x = 0; x < maxIndex; x++) { 104 var expect = null; 105 if (x < this.ranges.length) 106 expect = this.ranges[x]; 107 108 var found = null; 109 if (x < testArr.length) { 110 // testArr may contain the results coming from 111 // Selection.GetRangesForInterval(), which are 112 // wrappers for the underlying objects, therefore we may 113 // need to unwrap them before comparing them with the 114 // expected objects. 115 found = SpecialPowers.unwrap(testArr[x]); 116 } 117 118 if (found) { 119 foundMsg +="["+found.startOffset+","+found.endOffset+"] "; 120 } 121 if (expect) { 122 expectedMsg +="["+expect.start+","+expect.end+"] "; 123 } 124 125 if (found && expect) { 126 if (found.startContainer != expect.node || 127 found.endContainer != expect.node || 128 found.startOffset != expect.start || 129 found.endOffset != expect.end) 130 rangesMatch = false; 131 } else { 132 rangesMatch = false; 133 } 134 } 135 var okMsg = "Test "+testID+": correct ranges for interval."; 136 okMsg = okMsg + foundMsg + expectedMsg; 137 ok(rangesMatch, okMsg); 138 }, 139 140 addExpected: function(node, start, end) { 141 var expected = {}; 142 expected.node = node; 143 expected.start = start; 144 expected.end = end; 145 this.ranges[this.ranges.length] = expected; 146 this.ranges.sort(function(a,b) {return a.start - b.start;}); 147 } 148 } 149 150 function doTest() { 151 var testNode = document.getElementById("testparagraph").firstChild; 152 153 var selection = window.getSelection(); 154 selection.removeAllRanges(); 155 ok(selection.rangeCount == 0, "Test 0 - No selections so far"); 156 157 // Test 1. Add a single range, to ensure we've not broken anything. 158 var range1 = document.createRange(); 159 range1.setStart(testNode, 0); 160 range1.setEnd(testNode, 5); 161 selection.addRange(range1); 162 rangeChecker.addExpected(testNode, 0, 5); 163 rangeChecker.check(1, selection); 164 165 // Test 2. Add a non-overlapping range, to ensure it gets added too. 166 var range2 = document.createRange(); 167 range2.setStart(testNode, 8); 168 range2.setEnd(testNode, 10); 169 selection.addRange(range2); 170 rangeChecker.addExpected(testNode, 8, 10); 171 rangeChecker.check(2, selection); 172 173 // Test 3. Add the same range again. This should silently succeed. 174 selection.addRange(range2); 175 rangeChecker.check(3, selection); 176 177 // Test 4. Add a range that is left-adjacent to an existing range. 178 var range3 = document.createRange(); 179 range3.setStart(testNode, 6); 180 range3.setEnd(testNode, 8); 181 selection.addRange(range3); 182 rangeChecker.addExpected(testNode, 6, 8); 183 rangeChecker.check(4, selection); 184 185 // Test 5. Add a range that is right-adjacent to an existing range. 186 selection.removeRange(range2); 187 selection.addRange(range2); 188 rangeChecker.check(5, selection); 189 190 // Test 6. Add a range, add a second range that overlaps it. 191 rangeChecker.reset(); 192 selection.removeAllRanges(); 193 selection.addRange(range2); 194 var range4 = document.createRange(); 195 range4.setStart(testNode, 9); 196 range4.setEnd(testNode, 11); 197 selection.addRange(range4); 198 rangeChecker.addExpected(testNode, 8, 9); 199 rangeChecker.addExpected(testNode, 9, 11); 200 rangeChecker.check(6, selection); 201 202 // Test 7. Add a range, and this time a left-hand overlap. 203 rangeChecker.reset(); 204 selection.removeAllRanges(); 205 var range5 = document.createRange(); 206 range5.setStart(testNode, 5); 207 range5.setEnd(testNode, 7); 208 selection.addRange(range3); 209 selection.addRange(range5); 210 rangeChecker.addExpected(testNode, 5, 7); 211 rangeChecker.addExpected(testNode, 7, 8); 212 rangeChecker.check(7, selection); 213 214 // Test 8. Add a range, and add a second range wholly contained 215 // within it. 216 rangeChecker.reset(); 217 selection.removeAllRanges(); 218 var range6 = document.createRange(); 219 range6.setStart(testNode, 0); 220 range6.setEnd(testNode, 10); 221 selection.addRange(range6); 222 selection.addRange(range5); 223 rangeChecker.addExpected(testNode, 0, 5); 224 rangeChecker.addExpected(testNode, 5, 7); 225 rangeChecker.addExpected(testNode, 7, 10); 226 rangeChecker.check(8, selection); 227 228 // Test 9. Add a range that will wholly contain some existing ranges. 229 rangeChecker.reset(); 230 selection.addRange(range6); 231 rangeChecker.addExpected(testNode, 0, 10); 232 rangeChecker.check(9, selection); 233 234 // Test 10. This time with the last range being a partial overlap. 235 selection.removeAllRanges(); 236 selection.addRange(range1); 237 selection.addRange(range3); 238 selection.addRange(range4); 239 selection.addRange(range6); 240 rangeChecker.addExpected(testNode, 10, 11); 241 rangeChecker.check(10, selection); 242 243 // Test 11. Check we can add a collapsed range without problem. 244 selection.removeAllRanges(); 245 rangeChecker.reset(); 246 range1.collapse(true); 247 selection.addRange(range1); 248 rangeChecker.addExpected(testNode, 0, 0); 249 rangeChecker.check(11, selection); 250 251 // Test 12. Check we can add a collapsed range twice without a problem. 252 // Part 1 - No other ranges present. 253 selection.addRange(range1); 254 rangeChecker.check(12, selection); 255 256 // Test 13. Check we can add a collapsed range twice without problem. 257 // Part 2 - Collapsed range is before all existing ranges. 258 selection.removeAllRanges(); 259 rangeChecker.reset(); 260 selection.addRange(range2); 261 selection.addRange(range1); 262 selection.addRange(range1); 263 rangeChecker.addExpected(testNode, 0, 0); 264 rangeChecker.addExpected(testNode, 8, 10); 265 rangeChecker.check(13, selection); 266 267 // Test 14. Check we can add a collapsed range twice without problem. 268 // Part 3 - Collapsed range is after all existing ranges. 269 selection.removeAllRanges(); 270 rangeChecker.reset(); 271 selection.addRange(range3); 272 range4.collapse(false); 273 selection.addRange(range3); 274 selection.addRange(range4); 275 rangeChecker.addExpected(testNode, 6, 8); 276 rangeChecker.addExpected(testNode, 11, 11); 277 rangeChecker.check(14, selection); 278 279 // Test 15. Check that when adding a range where after overlap 280 // adjustment an exisiting range would collapse that the collapsed range 281 // is removed - part 1 (LHS). 282 selection.removeAllRanges(); 283 rangeChecker.reset(); 284 selection.addRange(range2); 285 var range7 = document.createRange(); 286 range7.setStart(testNode, 6); 287 range7.setEnd(testNode, 10); 288 selection.addRange(range7); 289 rangeChecker.addExpected(testNode, 6, 10); 290 rangeChecker.check(15, selection); 291 292 // Test 16. Check that when adding a range where after overlap 293 // adjustment an exisiting range would collapse that the collapsed range 294 // is removed - part 2 (RHS). 295 selection.removeAllRanges(); 296 selection.addRange(range3); 297 selection.addRange(range7); 298 rangeChecker.check(16, selection); 299 300 // Test 17. Check GetRangesForInterval returns correct results. 301 // Part 1 - Test interval matches a range, adjacency not allowed. 302 selection.removeAllRanges(); 303 selection.addRange(range2); 304 selection.addRange(range3); 305 var range8 = document.createRange(); 306 range8.setStart(testNode, 10); 307 range8.setEnd(testNode, 12); 308 selection.addRange(range8); 309 intervalChecker.reset(); 310 intervalChecker.addExpected(testNode, 8, 10); 311 var privSel = SpecialPowers.wrap(selection); 312 var results = privSel.GetRangesForInterval(testNode, 8, testNode, 10, 313 false); 314 intervalChecker.check(17, results); 315 316 // Test 18. Check GetRangesForInterval returns correct results. 317 // Part 2 - Test interval matches a range, adjacent ranges allowed. 318 intervalChecker.addExpected(testNode, 6, 8); 319 intervalChecker.addExpected(testNode, 10, 12); 320 results = privSel.GetRangesForInterval(testNode, 8, testNode, 10, 321 true); 322 intervalChecker.check(18, results); 323 324 // Test 19. Check GetRangesForInterval returns correct results. 325 // Part 3 - Test interval not selected. 326 intervalChecker.reset(); 327 results = privSel.GetRangesForInterval(testNode, 14, testNode, 16, 328 true); 329 intervalChecker.check(19, results); 330 331 // Test 20. Check GetRangesForInterval returns correct results. 332 // Part 4 - Test interval is not equal to, and entirely contained in 333 // an existing range. 334 selection.removeAllRanges(); 335 selection.addRange(range6); 336 intervalChecker.reset(); 337 intervalChecker.addExpected(testNode, 0, 10); 338 results = privSel.GetRangesForInterval(testNode, 5, testNode, 7, 339 true); 340 intervalChecker.check(20, results); 341 342 // Test 21. Check GetRangesForInterval returns correct results. 343 // Part 5 - Test interval is not equal to, and entirely contains an 344 // existing range. 345 selection.removeAllRanges(); 346 selection.addRange(range3); 347 intervalChecker.reset(); 348 intervalChecker.addExpected(testNode, 6, 8); 349 results = privSel.GetRangesForInterval(testNode, 5, testNode, 9, 350 true); 351 intervalChecker.check(21, results); 352 353 // Test 22. Check GetRangesForInterval returns correct results. 354 // Part 6 - Test interval is end-adjacent to range at position 0 in 355 // the range array, and adjacencies permitted. 356 selection.removeAllRanges(); 357 selection.addRange(range2); 358 intervalChecker.reset(); 359 intervalChecker.addExpected(testNode, 8, 10); 360 results = privSel.GetRangesForInterval(testNode, 6, testNode, 8, 361 true); 362 intervalChecker.check(22, results); 363 364 // Test 23. Check GetRangesForInterval returns correct results. 365 // Part 7 - Test interval is end-adjacent to range at position 0 in 366 // the range array, and adjacencies not permitted. 367 intervalChecker.reset(); 368 results = privSel.GetRangesForInterval(testNode, 6, testNode, 8, 369 false); 370 intervalChecker.check(23, results); 371 372 // Test 24. Check GetRangesForInterval returns correct results. 373 // Part 8 - Test interval is start-adjacent to last range in array, 374 // and adjacencies permitted. 375 intervalChecker.addExpected(testNode, 8, 10); 376 results = privSel.GetRangesForInterval(testNode, 10, testNode, 12, 377 true); 378 intervalChecker.check(24, results); 379 380 // Test 25. Check GetRangesForInterval returns correct results. 381 // Part 9 - Test interval is start-adjacent to last range in array, 382 // and adjacencies not permitted. 383 intervalChecker.reset(); 384 results = privSel.GetRangesForInterval(testNode, 10, testNode, 12, 385 false); 386 intervalChecker.check(25, results); 387 388 // Test 26. Check GetRangesForInterval returns correct results. 389 // Part 10 - Test interval is equal to a collapsed range at position 0 390 // in the range array, and adjacencies permitted. 391 selection.removeAllRanges(); 392 selection.addRange(range4); 393 intervalChecker.addExpected(testNode, 11, 11); 394 results = privSel.GetRangesForInterval(testNode, 11, testNode, 11, 395 true); 396 intervalChecker.check(26, results); 397 398 // Test 27. Check GetRangesForInterval returns correct results. 399 // Part 11 - Test interval is equal to a collapsed range at position 0 400 // in the range array, and adjacencies not permitted. 401 results = privSel.GetRangesForInterval(testNode, 11, testNode, 11, 402 false); 403 intervalChecker.check(27, results); 404 405 // Test 28. Check GetRangesForInterval returns correct results. 406 // Part 12 - Test interval is equal to a collapsed range at end of the 407 // range array, and adjacencies permitted. 408 selection.removeAllRanges(); 409 selection.addRange(range2); 410 selection.addRange(range4); 411 results = privSel.GetRangesForInterval(testNode, 11, testNode, 11, 412 true); 413 intervalChecker.check(28, results); 414 415 // Test 29. Check GetRangesForInterval returns correct results. 416 // Part 13 - Test interval is equal to a collapsed range at end of the 417 // range array, and adjacencies not permitted. 418 results = privSel.GetRangesForInterval(testNode, 11, testNode, 11, 419 false); 420 intervalChecker.check(29, results); 421 422 // Test 30. Check GetRangesForInterval returns correct results. 423 // Part 14 - Test interval is a collapsed range contained in an 424 // existing range. 425 selection.removeAllRanges(); 426 selection.addRange(range3); 427 intervalChecker.reset(); 428 intervalChecker.addExpected(testNode, 6, 8); 429 results = privSel.GetRangesForInterval(testNode, 7, testNode, 7, 430 true); 431 intervalChecker.check(30, results); 432 433 // Test 31. Check GetRangesForInterval returns correct results. 434 // Part 15 - Test interval equals a collapsed range which is not stored 435 // at either endpoint of the selection's range array, 436 // adjacencies not allowed. 437 selection.removeAllRanges(); 438 range3.collapse(false); 439 selection.addRange(range5); 440 selection.addRange(range3); 441 selection.addRange(range8); 442 intervalChecker.reset(); 443 intervalChecker.addExpected(testNode, 8, 8); 444 results = privSel.GetRangesForInterval(testNode, 8, testNode, 8, 445 false); 446 intervalChecker.check(31, results); 447 448 // Test 32. Check GetRangesForInterval returns correct results. 449 // Part 16 - Test interval equals a collapsed range which is not stored 450 // at either endpoint of the selection's range array, 451 // adjacencies allowed. 452 results = privSel.GetRangesForInterval(testNode, 8, testNode, 8, 453 true); 454 intervalChecker.check(32, results); 455 456 // Test 33. Check GetRangesForInterval returns correct results. 457 // Part 17 - Test interval contains a collapsed range which is not 458 // stored at either endpoint of the selection's range array. 459 results = privSel.GetRangesForInterval(testNode, 7, testNode, 9, 460 false); 461 intervalChecker.check(33, results); 462 463 // Test 34. Check GetRangesForInterval returns correct results. 464 // Part 18 - Test interval left-ovelaps an existing range. 465 intervalChecker.reset(); 466 intervalChecker.addExpected(testNode, 5, 7); 467 results = privSel.GetRangesForInterval(testNode, 2, testNode, 6, 468 true); 469 intervalChecker.check(34, results); 470 471 // Test 35. Check GetRangesForInterval returns correct results. 472 // Part 19 - Test interval right-ovelaps an existing range. 473 selection.removeAllRanges(); 474 selection.addRange(range8); 475 intervalChecker.reset(); 476 intervalChecker.addExpected(testNode, 10, 12); 477 results = privSel.GetRangesForInterval(testNode, 11, testNode, 13, 478 true); 479 intervalChecker.check(35, results); 480 481 SimpleTest.finish(); 482 } 483 </script> 484 </pre> 485 486 <p id="testparagraph"> 487 This will be the first child of the p node above. The intention is that it is a suitably long text node to which we can add multiple ranges in order to test the various aspects of the bug. 488 </p> 489 </body> 490 </html>