OLD | NEW |
1 <!DOCTYPE html> | 1 <!doctype html> |
2 <html> | 2 <script src="../../resources/testharness.js"></script> |
3 <body> | 3 <script src="../../resources/testharnessreport.js"></script> |
4 <p>This test ensures WebKit adjusts the selection under document mutation.</p> | 4 <script src="../assert_selection.js"></script> |
5 <p> Examples are from:<br> http://www.w3.org/TR/DOM-Level-2-Traversal-Range/rang
es.html#Level-2-Range-Mutation</p> | |
6 <div id="test" contenteditable></div> | |
7 <pre> | |
8 <script> | 5 <script> |
9 | 6 function swapMarks(string) { |
10 var test = document.getElementById('test'); | 7 if (string.indexOf('^') === -1) |
11 test.focus(); | 8 return string; |
12 | 9 return string.replace('^', '$').replace('|', '^').replace('$', '|'); |
13 if (window.testRunner) | |
14 testRunner.dumpAsText(); | |
15 | |
16 var baseIsFirst = true; | |
17 var selection = window.getSelection(); | |
18 | |
19 function checkResult(expectedStartOffset, expectedEndOffset) { | |
20 var actualStartOffset = selection.getRangeAt(0).startOffset; | |
21 var actualEndOffset = selection.getRangeAt(0).endOffset; | |
22 if (actualStartOffset == expectedStartOffset && actualEndOffset == expectedE
ndOffset) | |
23 document.write('PASS: selection is (' + expectedStartOffset + ', ' + exp
ectedEndOffset + ') "' + selection + '"\n'); | |
24 else | |
25 document.write('FAIL: selection is (' + actualStartOffset + ', ' + actua
lEndOffset + ') "' + selection + | |
26 '" and expected selection is ' + '(' + expectedStartOffset + ', ' +
expectedEndOffset + ')\n'); | |
27 } | 10 } |
28 | 11 |
29 function setSelectionRange(startContainer, startOffset, endContainer, endOffset)
{ | 12 function test_selection(sample, closure, expected, description) { |
30 if (baseIsFirst) | 13 test(() => assert_selection(sample, closure, expected), |
31 selection.setBaseAndExtent(startContainer, startOffset, endContainer, en
dOffset); | 14 description + '; anchor is first'); |
32 else | 15 test(() => assert_selection(swapMarks(sample), closure, swapMarks(expected))
, |
33 selection.setBaseAndExtent(endContainer, endOffset, startContainer, star
tOffset); | 16 description + '; focus is first'); |
34 } | 17 } |
35 | 18 |
36 function runInsertionTest(actor, expectedStartOffset, expectedEndOffset) { | 19 function doInsert(selection, offset) { |
37 test.innerHTML = '<p>Abcd efgh XY blah ijkl</p>'; | 20 const element = selection.document.querySelector('p'); |
38 | 21 element.firstChild.insertData(offset, '_'.repeat(13)); |
39 // Select "Y blah i" | |
40 setSelectionRange(test.firstChild.firstChild, 11, test.firstChild.firstChild
, 19); | |
41 actor(test.firstChild.firstChild); | |
42 checkResult(expectedStartOffset, expectedEndOffset); | |
43 } | 22 } |
44 | 23 |
45 function runDeletionTest(actor, expectedStartOffset, expectedEndOffset) { | 24 function doDelete(selection, offset, length) { |
46 test.innerHTML = '<p>Abcd efgh The Range ijkl</p>'; | 25 const element = selection.document.querySelector('p'); |
47 | 26 element.firstChild.deleteData(offset, length); |
48 // Select "he Range i" | |
49 setSelectionRange(test.firstChild.firstChild, 11, test.firstChild.firstChild
, 21); | |
50 actor(test.firstChild.firstChild); | |
51 checkResult(expectedStartOffset, expectedEndOffset); | |
52 } | 27 } |
53 | 28 |
54 function deleteNodeContainingSelection(expectedStartOffset, expectedEndOffset) { | 29 // Insertion tests |
55 test.innerHTML = '<p>Abcd <em>efgh The Range ij</em>kl</p>'; | 30 test_selection( |
| 31 '<p>Abcd efgh X^Y blah i|jkl</p>', |
| 32 selection => doInsert(selection, 10), |
| 33 '<p>Abcd efgh _____________X^Y blah i|jkl</p>', |
| 34 'insertData at 10'); |
56 | 35 |
57 // Select "he Range i" | 36 test_selection( |
58 setSelectionRange(test.firstChild.firstChild.nextSibling.firstChild, 6, test
.firstChild.firstChild.nextSibling.firstChild, 16); | 37 '<p>Abcd efgh X^Y blah i|jkl</p>', |
59 test.firstChild.removeChild(test.firstChild.firstChild.nextSibling); | 38 selection => doInsert(selection, 11), |
60 checkResult(expectedStartOffset, expectedEndOffset); | 39 '<p>Abcd efgh X^_____________Y blah i|jkl</p>', |
61 } | 40 'insertData at 11'); |
62 | 41 |
63 function runTests() { | 42 test_selection( |
64 document.write('Insertion tests:\n'); | 43 '<p>Abcd efgh X^Y blah i|jkl</p>', |
65 runInsertionTest(function(node) { node.insertData(10, 'inserted text'); }, 2
4, 32); | 44 selection => doInsert(selection, 12), |
66 runInsertionTest(function(node) { node.insertData(11, 'inserted text'); }, 1
1, 32); | 45 '<p>Abcd efgh X^Y_____________ blah i|jkl</p>', |
67 runInsertionTest(function(node) { node.insertData(12, 'inserted text'); }, 1
1, 32); | 46 'insertData at 12'); |
68 runInsertionTest(function(node) { node.insertData(17, 'inserted text'); }, 1
1, 32); | |
69 runInsertionTest(function(node) { node.insertData(19, 'inserted text'); }, 1
1, 19); | |
70 | 47 |
71 document.write('\nDeletion tests:\n'); | 48 test_selection( |
72 runDeletionTest(function(node) { node.deleteData(5, 8); }, 5, 13); | 49 '<p>Abcd efgh X^Y blah i|jkl</p>', |
73 runDeletionTest(function(node) { node.deleteData(5, 17); }, 5, 5); | 50 selection => doInsert(selection, 17), |
74 runDeletionTest(function(node) { node.deleteData(5, 6); }, 5, 15); | 51 '<p>Abcd efgh X^Y blah_____________ i|jkl</p>', |
75 deleteNodeContainingSelection(1, 1); | 52 'insertData at 17'); |
76 } | |
77 | 53 |
78 document.write('Base is first\n\n'); | 54 test_selection( |
79 runTests(); | 55 '<p>Abcd efgh X^Y blah i|jkl</p>', |
| 56 selection => doInsert(selection, 19), |
| 57 '<p>Abcd efgh X^Y blah i|_____________jkl</p>', |
| 58 'insertData at 19'); |
80 | 59 |
81 baseIsFirst = false; | 60 // Deletion tests |
| 61 test_selection( |
| 62 '<p>Abcd efgh T^he Range i|jkl</p>', |
| 63 selection => doDelete(selection, 5, 8), |
| 64 '<p>Abcd ^ Range i|jkl</p>', |
| 65 'deleteData(5, 8)'); |
82 | 66 |
83 document.write('\n\nExtent is first\n\n'); | 67 test_selection( |
84 runTests(); | 68 '<p>Abcd efgh T^he Range i|jkl</p>', |
| 69 selection => doDelete(selection, 5, 6), |
| 70 '<p>Abcd ^he Range i|jkl</p>', |
| 71 'deleteData(5, 6)'); |
85 | 72 |
86 test.style.display = 'none'; | 73 test_selection( |
87 document.write('\nDONE'); | 74 '<p>Abcd efgh T^he Range i|jkl</p>', |
| 75 selection => doDelete(selection, 5, 17), |
| 76 '<p>Abcd |kl</p>', |
| 77 'deleteData(5, 17)'); |
| 78 |
| 79 // Delete node containing selection |
| 80 test_selection( |
| 81 '<p>Abcd <em>efgh T^he Range i|j</em>kl</p>', |
| 82 selection => selection.document.querySelector('em').remove(), |
| 83 '<p>Abcd |kl</p>', |
| 84 'delete node containing selection'); |
88 </script> | 85 </script> |
89 </pre> | |
90 </body> | |
91 </html> | |
OLD | NEW |