Chromium Code Reviews| 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 |