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, start, end) { |
Xiaocheng
2016/09/27 09:32:50
nit: |end| should be named |length| instead.
yosin_UTC9
2016/09/27 09:56:11
Done
| |
46 test.innerHTML = '<p>Abcd efgh The Range ijkl</p>'; | 25 const element = selection.document.querySelector('p'); |
47 | 26 element.firstChild.deleteData(start, end); |
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 |