1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/generic/test/test_bug348681.html Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,486 @@ 1.4 +<!DOCTYPE HTML> 1.5 +<!-- This Source Code Form is subject to the terms of the Mozilla Public 1.6 + - License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> 1.8 +<html> 1.9 +<!-- 1.10 +https://bugzilla.mozilla.org/show_bug.cgi?id=348681 1.11 +--> 1.12 + 1.13 +<head> 1.14 + <title>Test for Bug 348681</title> 1.15 + <script type="application/javascript" src="chrome://mochikit/content/MochiKit/MochiKit.js"></script> 1.16 + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> 1.17 + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> 1.18 + <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script> 1.19 +</head> 1.20 + 1.21 +<body onload="loaded()"> 1.22 + <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=348681">Mozilla Bug 348681</a> 1.23 + <p id="display"></p> 1.24 + <div id="content" style="display: none"> 1.25 + </div> 1.26 + 1.27 + <pre id="test"> 1.28 + <script type="application/javascript"> 1.29 + 1.30 + /** Test for Bug 348681 **/ 1.31 + 1.32 + SimpleTest.waitForExplicitFinish(); 1.33 + 1.34 + function loaded() { 1.35 + SpecialPowers.pushPrefEnv({"set": [["dom.testing.selection.GetRangesForInterval", true]]}, doTest); 1.36 + } 1.37 + 1.38 + var rangeChecker = { 1.39 + ranges: [], 1.40 + 1.41 + reset: function() { 1.42 + this.ranges = []; 1.43 + }, 1.44 + 1.45 + check: function(testID, selection) { 1.46 + is(selection.rangeCount, this.ranges.length, 1.47 + "Test "+testID+": correct number of ranges in selection"); 1.48 + var rangesMatch = true; 1.49 + var foundMsg = "Found "; 1.50 + var expectedMsg = "Expected "; 1.51 + var maxIndex = Math.max(selection.rangeCount, this.ranges.length); 1.52 + for (var x = 0; x < maxIndex; x++) { 1.53 + var expect = null; 1.54 + if (x < this.ranges.length) 1.55 + expect = this.ranges[x]; 1.56 + 1.57 + var found = null; 1.58 + if (x < selection.rangeCount) 1.59 + found = selection.getRangeAt(x); 1.60 + 1.61 + if (found) { 1.62 + foundMsg +="["+found.startOffset+","+found.endOffset+"] "; 1.63 + } 1.64 + if (expect) { 1.65 + expectedMsg +="["+expect.start+","+expect.end+"] "; 1.66 + } 1.67 + 1.68 + if (found && expect) { 1.69 + if (found.startContainer != expect.node || 1.70 + found.endContainer != expect.node || 1.71 + found.startOffset != expect.start || 1.72 + found.endOffset != expect.end) 1.73 + rangesMatch = false; 1.74 + } else { 1.75 + rangesMatch = false; 1.76 + } 1.77 + } 1.78 + var okMsg = "Test "+testID+": correct ranges in selection."; 1.79 + okMsg = okMsg + foundMsg + expectedMsg; 1.80 + ok(rangesMatch, okMsg); 1.81 + }, 1.82 + 1.83 + addExpected: function(node, start, end) { 1.84 + var expected = {}; 1.85 + expected.node = node; 1.86 + expected.start = start; 1.87 + expected.end = end; 1.88 + this.ranges[this.ranges.length] = expected; 1.89 + this.ranges.sort(function(a,b) {return a.start - b.start;}); 1.90 + } 1.91 + } 1.92 + 1.93 + var intervalChecker = { 1.94 + ranges: [], 1.95 + 1.96 + reset: function() { 1.97 + this.ranges = []; 1.98 + }, 1.99 + 1.100 + check: function(testID, testArr) { 1.101 + is(testArr.length, this.ranges.length, 1.102 + "Test "+testID+": correct number of ranges for interval"); 1.103 + var rangesMatch = true; 1.104 + var foundMsg = "Found "; 1.105 + var expectedMsg = "Expected "; 1.106 + var maxIndex = Math.max(testArr.length, this.ranges.length); 1.107 + for (var x = 0; x < maxIndex; x++) { 1.108 + var expect = null; 1.109 + if (x < this.ranges.length) 1.110 + expect = this.ranges[x]; 1.111 + 1.112 + var found = null; 1.113 + if (x < testArr.length) 1.114 + found = testArr[x]; 1.115 + 1.116 + if (found) { 1.117 + foundMsg +="["+found.startOffset+","+found.endOffset+"] "; 1.118 + } 1.119 + if (expect) { 1.120 + expectedMsg +="["+expect.start+","+expect.end+"] "; 1.121 + } 1.122 + 1.123 + if (found && expect) { 1.124 + if (found.startContainer != expect.node || 1.125 + found.endContainer != expect.node || 1.126 + found.startOffset != expect.start || 1.127 + found.endOffset != expect.end) 1.128 + rangesMatch = false; 1.129 + } else { 1.130 + rangesMatch = false; 1.131 + } 1.132 + } 1.133 + var okMsg = "Test "+testID+": correct ranges for interval."; 1.134 + okMsg = okMsg + foundMsg + expectedMsg; 1.135 + ok(rangesMatch, okMsg); 1.136 + }, 1.137 + 1.138 + addExpected: function(node, start, end) { 1.139 + var expected = {}; 1.140 + expected.node = node; 1.141 + expected.start = start; 1.142 + expected.end = end; 1.143 + this.ranges[this.ranges.length] = expected; 1.144 + this.ranges.sort(function(a,b) {return a.start - b.start;}); 1.145 + } 1.146 + } 1.147 + 1.148 + function doTest() { 1.149 + var testNode = document.getElementById("testparagraph").firstChild; 1.150 + 1.151 + var selection = window.getSelection(); 1.152 + selection.removeAllRanges(); 1.153 + ok(selection.rangeCount == 0, "Test 0 - No selections so far"); 1.154 + 1.155 + // Test 1. Add a single range, to ensure we've not broken anything. 1.156 + var range1 = document.createRange(); 1.157 + range1.setStart(testNode, 0); 1.158 + range1.setEnd(testNode, 5); 1.159 + selection.addRange(range1); 1.160 + rangeChecker.addExpected(testNode, 0, 5); 1.161 + rangeChecker.check(1, selection); 1.162 + 1.163 + // Test 2. Add a non-overlapping range, to ensure it gets added too. 1.164 + var range2 = document.createRange(); 1.165 + range2.setStart(testNode, 8); 1.166 + range2.setEnd(testNode, 10); 1.167 + selection.addRange(range2); 1.168 + rangeChecker.addExpected(testNode, 8, 10); 1.169 + rangeChecker.check(2, selection); 1.170 + 1.171 + // Test 3. Add the same range again. This should silently succeed. 1.172 + selection.addRange(range2); 1.173 + rangeChecker.check(3, selection); 1.174 + 1.175 + // Test 4. Add a range that is left-adjacent to an existing range. 1.176 + var range3 = document.createRange(); 1.177 + range3.setStart(testNode, 6); 1.178 + range3.setEnd(testNode, 8); 1.179 + selection.addRange(range3); 1.180 + rangeChecker.addExpected(testNode, 6, 8); 1.181 + rangeChecker.check(4, selection); 1.182 + 1.183 + // Test 5. Add a range that is right-adjacent to an existing range. 1.184 + selection.removeRange(range2); 1.185 + selection.addRange(range2); 1.186 + rangeChecker.check(5, selection); 1.187 + 1.188 + // Test 6. Add a range, add a second range that overlaps it. 1.189 + rangeChecker.reset(); 1.190 + selection.removeAllRanges(); 1.191 + selection.addRange(range2); 1.192 + var range4 = document.createRange(); 1.193 + range4.setStart(testNode, 9); 1.194 + range4.setEnd(testNode, 11); 1.195 + selection.addRange(range4); 1.196 + rangeChecker.addExpected(testNode, 8, 9); 1.197 + rangeChecker.addExpected(testNode, 9, 11); 1.198 + rangeChecker.check(6, selection); 1.199 + 1.200 + // Test 7. Add a range, and this time a left-hand overlap. 1.201 + rangeChecker.reset(); 1.202 + selection.removeAllRanges(); 1.203 + var range5 = document.createRange(); 1.204 + range5.setStart(testNode, 5); 1.205 + range5.setEnd(testNode, 7); 1.206 + selection.addRange(range3); 1.207 + selection.addRange(range5); 1.208 + rangeChecker.addExpected(testNode, 5, 7); 1.209 + rangeChecker.addExpected(testNode, 7, 8); 1.210 + rangeChecker.check(7, selection); 1.211 + 1.212 + // Test 8. Add a range, and add a second range wholly contained 1.213 + // within it. 1.214 + rangeChecker.reset(); 1.215 + selection.removeAllRanges(); 1.216 + var range6 = document.createRange(); 1.217 + range6.setStart(testNode, 0); 1.218 + range6.setEnd(testNode, 10); 1.219 + selection.addRange(range6); 1.220 + selection.addRange(range5); 1.221 + rangeChecker.addExpected(testNode, 0, 5); 1.222 + rangeChecker.addExpected(testNode, 5, 7); 1.223 + rangeChecker.addExpected(testNode, 7, 10); 1.224 + rangeChecker.check(8, selection); 1.225 + 1.226 + // Test 9. Add a range that will wholly contain some existing ranges. 1.227 + rangeChecker.reset(); 1.228 + selection.addRange(range6); 1.229 + rangeChecker.addExpected(testNode, 0, 10); 1.230 + rangeChecker.check(9, selection); 1.231 + 1.232 + // Test 10. This time with the last range being a partial overlap. 1.233 + selection.removeAllRanges(); 1.234 + selection.addRange(range1); 1.235 + selection.addRange(range3); 1.236 + selection.addRange(range4); 1.237 + selection.addRange(range6); 1.238 + rangeChecker.addExpected(testNode, 10, 11); 1.239 + rangeChecker.check(10, selection); 1.240 + 1.241 + // Test 11. Check we can add a collapsed range without problem. 1.242 + selection.removeAllRanges(); 1.243 + rangeChecker.reset(); 1.244 + range1.collapse(true); 1.245 + selection.addRange(range1); 1.246 + rangeChecker.addExpected(testNode, 0, 0); 1.247 + rangeChecker.check(11, selection); 1.248 + 1.249 + // Test 12. Check we can add a collapsed range twice without a problem. 1.250 + // Part 1 - No other ranges present. 1.251 + selection.addRange(range1); 1.252 + rangeChecker.check(12, selection); 1.253 + 1.254 + // Test 13. Check we can add a collapsed range twice without problem. 1.255 + // Part 2 - Collapsed range is before all existing ranges. 1.256 + selection.removeAllRanges(); 1.257 + rangeChecker.reset(); 1.258 + selection.addRange(range2); 1.259 + selection.addRange(range1); 1.260 + selection.addRange(range1); 1.261 + rangeChecker.addExpected(testNode, 0, 0); 1.262 + rangeChecker.addExpected(testNode, 8, 10); 1.263 + rangeChecker.check(13, selection); 1.264 + 1.265 + // Test 14. Check we can add a collapsed range twice without problem. 1.266 + // Part 3 - Collapsed range is after all existing ranges. 1.267 + selection.removeAllRanges(); 1.268 + rangeChecker.reset(); 1.269 + selection.addRange(range3); 1.270 + range4.collapse(false); 1.271 + selection.addRange(range3); 1.272 + selection.addRange(range4); 1.273 + rangeChecker.addExpected(testNode, 6, 8); 1.274 + rangeChecker.addExpected(testNode, 11, 11); 1.275 + rangeChecker.check(14, selection); 1.276 + 1.277 + // Test 15. Check that when adding a range where after overlap 1.278 + // adjustment an exisiting range would collapse that the collapsed range 1.279 + // is removed - part 1 (LHS). 1.280 + selection.removeAllRanges(); 1.281 + rangeChecker.reset(); 1.282 + selection.addRange(range2); 1.283 + var range7 = document.createRange(); 1.284 + range7.setStart(testNode, 6); 1.285 + range7.setEnd(testNode, 10); 1.286 + selection.addRange(range7); 1.287 + rangeChecker.addExpected(testNode, 6, 10); 1.288 + rangeChecker.check(15, selection); 1.289 + 1.290 + // Test 16. Check that when adding a range where after overlap 1.291 + // adjustment an exisiting range would collapse that the collapsed range 1.292 + // is removed - part 2 (RHS). 1.293 + selection.removeAllRanges(); 1.294 + selection.addRange(range3); 1.295 + selection.addRange(range7); 1.296 + rangeChecker.check(16, selection); 1.297 + 1.298 + // Test 17. Check GetRangesForInterval returns correct results. 1.299 + // Part 1 - Test interval matches a range, adjacency not allowed. 1.300 + selection.removeAllRanges(); 1.301 + selection.addRange(range2); 1.302 + selection.addRange(range3); 1.303 + var range8 = document.createRange(); 1.304 + range8.setStart(testNode, 10); 1.305 + range8.setEnd(testNode, 12); 1.306 + selection.addRange(range8); 1.307 + intervalChecker.reset(); 1.308 + intervalChecker.addExpected(testNode, 8, 10); 1.309 + var privSel = selection.QueryInterface(SpecialPowers.Ci.nsISelectionPrivate); 1.310 + ok(privSel, "Test 17 - QIed to instance of nsISelection2 interface"); 1.311 + var results = privSel.GetRangesForInterval(testNode, 8, testNode, 10, 1.312 + false); 1.313 + intervalChecker.check(17, results); 1.314 + 1.315 + // Test 18. Check GetRangesForInterval returns correct results. 1.316 + // Part 2 - Test interval matches a range, adjacent ranges allowed. 1.317 + intervalChecker.addExpected(testNode, 6, 8); 1.318 + intervalChecker.addExpected(testNode, 10, 12); 1.319 + results = privSel.GetRangesForInterval(testNode, 8, testNode, 10, 1.320 + true); 1.321 + intervalChecker.check(18, results); 1.322 + 1.323 + // Test 19. Check GetRangesForInterval returns correct results. 1.324 + // Part 3 - Test interval not selected. 1.325 + intervalChecker.reset(); 1.326 + results = privSel.GetRangesForInterval(testNode, 14, testNode, 16, 1.327 + true); 1.328 + intervalChecker.check(19, results); 1.329 + 1.330 + // Test 20. Check GetRangesForInterval returns correct results. 1.331 + // Part 4 - Test interval is not equal to, and entirely contained in 1.332 + // an existing range. 1.333 + selection.removeAllRanges(); 1.334 + selection.addRange(range6); 1.335 + intervalChecker.reset(); 1.336 + intervalChecker.addExpected(testNode, 0, 10); 1.337 + results = privSel.GetRangesForInterval(testNode, 5, testNode, 7, 1.338 + true); 1.339 + intervalChecker.check(20, results); 1.340 + 1.341 + // Test 21. Check GetRangesForInterval returns correct results. 1.342 + // Part 5 - Test interval is not equal to, and entirely contains an 1.343 + // existing range. 1.344 + selection.removeAllRanges(); 1.345 + selection.addRange(range3); 1.346 + intervalChecker.reset(); 1.347 + intervalChecker.addExpected(testNode, 6, 8); 1.348 + results = privSel.GetRangesForInterval(testNode, 5, testNode, 9, 1.349 + true); 1.350 + intervalChecker.check(21, results); 1.351 + 1.352 + // Test 22. Check GetRangesForInterval returns correct results. 1.353 + // Part 6 - Test interval is end-adjacent to range at position 0 in 1.354 + // the range array, and adjacencies permitted. 1.355 + selection.removeAllRanges(); 1.356 + selection.addRange(range2); 1.357 + intervalChecker.reset(); 1.358 + intervalChecker.addExpected(testNode, 8, 10); 1.359 + results = privSel.GetRangesForInterval(testNode, 6, testNode, 8, 1.360 + true); 1.361 + intervalChecker.check(22, results); 1.362 + 1.363 + // Test 23. Check GetRangesForInterval returns correct results. 1.364 + // Part 7 - Test interval is end-adjacent to range at position 0 in 1.365 + // the range array, and adjacencies not permitted. 1.366 + intervalChecker.reset(); 1.367 + results = privSel.GetRangesForInterval(testNode, 6, testNode, 8, 1.368 + false); 1.369 + intervalChecker.check(23, results); 1.370 + 1.371 + // Test 24. Check GetRangesForInterval returns correct results. 1.372 + // Part 8 - Test interval is start-adjacent to last range in array, 1.373 + // and adjacencies permitted. 1.374 + intervalChecker.addExpected(testNode, 8, 10); 1.375 + results = privSel.GetRangesForInterval(testNode, 10, testNode, 12, 1.376 + true); 1.377 + intervalChecker.check(24, results); 1.378 + 1.379 + // Test 25. Check GetRangesForInterval returns correct results. 1.380 + // Part 9 - Test interval is start-adjacent to last range in array, 1.381 + // and adjacencies not permitted. 1.382 + intervalChecker.reset(); 1.383 + results = privSel.GetRangesForInterval(testNode, 10, testNode, 12, 1.384 + false); 1.385 + intervalChecker.check(25, results); 1.386 + 1.387 + // Test 26. Check GetRangesForInterval returns correct results. 1.388 + // Part 10 - Test interval is equal to a collapsed range at position 0 1.389 + // in the range array, and adjacencies permitted. 1.390 + selection.removeAllRanges(); 1.391 + selection.addRange(range4); 1.392 + intervalChecker.addExpected(testNode, 11, 11); 1.393 + results = privSel.GetRangesForInterval(testNode, 11, testNode, 11, 1.394 + true); 1.395 + intervalChecker.check(26, results); 1.396 + 1.397 + // Test 27. Check GetRangesForInterval returns correct results. 1.398 + // Part 11 - Test interval is equal to a collapsed range at position 0 1.399 + // in the range array, and adjacencies not permitted. 1.400 + results = privSel.GetRangesForInterval(testNode, 11, testNode, 11, 1.401 + false); 1.402 + intervalChecker.check(27, results); 1.403 + 1.404 + // Test 28. Check GetRangesForInterval returns correct results. 1.405 + // Part 12 - Test interval is equal to a collapsed range at end of the 1.406 + // range array, and adjacencies permitted. 1.407 + selection.removeAllRanges(); 1.408 + selection.addRange(range2); 1.409 + selection.addRange(range4); 1.410 + results = privSel.GetRangesForInterval(testNode, 11, testNode, 11, 1.411 + true); 1.412 + intervalChecker.check(28, results); 1.413 + 1.414 + // Test 29. Check GetRangesForInterval returns correct results. 1.415 + // Part 13 - Test interval is equal to a collapsed range at end of the 1.416 + // range array, and adjacencies not permitted. 1.417 + results = privSel.GetRangesForInterval(testNode, 11, testNode, 11, 1.418 + false); 1.419 + intervalChecker.check(29, results); 1.420 + 1.421 + // Test 30. Check GetRangesForInterval returns correct results. 1.422 + // Part 14 - Test interval is a collapsed range contained in an 1.423 + // existing range. 1.424 + selection.removeAllRanges(); 1.425 + selection.addRange(range3); 1.426 + intervalChecker.reset(); 1.427 + intervalChecker.addExpected(testNode, 6, 8); 1.428 + results = privSel.GetRangesForInterval(testNode, 7, testNode, 7, 1.429 + true); 1.430 + intervalChecker.check(30, results); 1.431 + 1.432 + // Test 31. Check GetRangesForInterval returns correct results. 1.433 + // Part 15 - Test interval equals a collapsed range which is not stored 1.434 + // at either endpoint of the selection's range array, 1.435 + // adjacencies not allowed. 1.436 + selection.removeAllRanges(); 1.437 + range3.collapse(false); 1.438 + selection.addRange(range5); 1.439 + selection.addRange(range3); 1.440 + selection.addRange(range8); 1.441 + intervalChecker.reset(); 1.442 + intervalChecker.addExpected(testNode, 8, 8); 1.443 + results = privSel.GetRangesForInterval(testNode, 8, testNode, 8, 1.444 + false); 1.445 + intervalChecker.check(31, results); 1.446 + 1.447 + // Test 32. Check GetRangesForInterval returns correct results. 1.448 + // Part 16 - Test interval equals a collapsed range which is not stored 1.449 + // at either endpoint of the selection's range array, 1.450 + // adjacencies allowed. 1.451 + results = privSel.GetRangesForInterval(testNode, 8, testNode, 8, 1.452 + true); 1.453 + intervalChecker.check(32, results); 1.454 + 1.455 + // Test 33. Check GetRangesForInterval returns correct results. 1.456 + // Part 17 - Test interval contains a collapsed range which is not 1.457 + // stored at either endpoint of the selection's range array. 1.458 + results = privSel.GetRangesForInterval(testNode, 7, testNode, 9, 1.459 + false); 1.460 + intervalChecker.check(33, results); 1.461 + 1.462 + // Test 34. Check GetRangesForInterval returns correct results. 1.463 + // Part 18 - Test interval left-ovelaps an existing range. 1.464 + intervalChecker.reset(); 1.465 + intervalChecker.addExpected(testNode, 5, 7); 1.466 + results = privSel.GetRangesForInterval(testNode, 2, testNode, 6, 1.467 + true); 1.468 + intervalChecker.check(34, results); 1.469 + 1.470 + // Test 35. Check GetRangesForInterval returns correct results. 1.471 + // Part 19 - Test interval right-ovelaps an existing range. 1.472 + selection.removeAllRanges(); 1.473 + selection.addRange(range8); 1.474 + intervalChecker.reset(); 1.475 + intervalChecker.addExpected(testNode, 10, 12); 1.476 + results = privSel.GetRangesForInterval(testNode, 11, testNode, 13, 1.477 + true); 1.478 + intervalChecker.check(35, results); 1.479 + 1.480 + SimpleTest.finish(); 1.481 + } 1.482 + </script> 1.483 + </pre> 1.484 + 1.485 + <p id="testparagraph"> 1.486 +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. 1.487 +</p> 1.488 +</body> 1.489 +</html>