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