| OLD | NEW |
| 1 <!DOCTYPE html> | 1 <!DOCTYPE html> |
| 2 <html> | 2 <html> |
| 3 <head> | 3 <head> |
| 4 <title>InputEvent: beforeinput for Drag and Drop</title> | 4 <title>InputEvent: beforeinput for Drag and Drop</title> |
| 5 <script src="../../../resources/testharness.js"></script> | 5 <script src="../../../resources/testharness.js"></script> |
| 6 <script src="../../../resources/testharnessreport.js"></script> | 6 <script src="../../../resources/testharnessreport.js"></script> |
| 7 <style> | 7 <style> |
| 8 div, img { | 8 div { |
| 9 width: 100px; | 9 width: 100px; |
| 10 height: 100px; | 10 height: 100px; |
| 11 } | 11 } |
| 12 </style> | 12 </style> |
| 13 </head> | 13 </head> |
| 14 <body> | 14 <body> |
| 15 <div id="editable1" contenteditable><img id="img" src="../resources/greenbox.png
"></div> | 15 <div id="editable1" contenteditable><b id="boldtext">EditableText</b></div> |
| 16 <div id="editable2" contenteditable></div> | 16 <div id="editable2" contenteditable></div> |
| 17 <textarea id="textarea1">Text</textarea> | 17 <textarea id="textarea1">Text</textarea> |
| 18 <textarea id="barrier"></textarea> | 18 <textarea id="barrier"></textarea> |
| 19 <script> | 19 <script> |
| 20 function simulateDragDrop(dragElement, dropElement) { | 20 function simulateDragDrop(dragElement, dropElement) { |
| 21 if (dragElement.select) { |
| 22 dragElement.select(); |
| 23 } else { |
| 24 var selection = window.getSelection(); |
| 25 selection.collapse(dragElement, 0); |
| 26 selection.extend(dragElement, 1); |
| 27 } |
| 28 |
| 21 eventSender.mouseMoveTo(dragElement.offsetLeft + dragElement.offsetWidth / 2
, | 29 eventSender.mouseMoveTo(dragElement.offsetLeft + dragElement.offsetWidth / 2
, |
| 22 dragElement.offsetTop + dragElement.offsetHeight / 2
); | 30 dragElement.offsetTop + dragElement.offsetHeight / 2
); |
| 23 eventSender.mouseDown(); | 31 eventSender.mouseDown(); |
| 24 eventSender.leapForward(600); | 32 eventSender.leapForward(600); |
| 25 eventSender.mouseMoveTo(dropElement.offsetLeft + dropElement.offsetWidth / 2
, | 33 eventSender.mouseMoveTo(dropElement.offsetLeft + dropElement.offsetWidth / 2
, |
| 26 dropElement.offsetTop + dropElement.offsetHeight / 2
); | 34 dropElement.offsetTop + dropElement.offsetHeight / 2
); |
| 27 eventSender.mouseUp(); | 35 eventSender.mouseUp(); |
| 28 } | 36 } |
| 29 | 37 |
| 30 function assertCleanInitialDOM(logInfo) { | 38 function assertCleanInitialDOM(logInfo) { |
| 31 const editable1 = document.getElementById('editable1'); | 39 const editable1 = document.getElementById('editable1'); |
| 32 const editable2 = document.getElementById('editable2'); | 40 const editable2 = document.getElementById('editable2'); |
| 33 const textarea1 = document.getElementById('textarea1'); | 41 const textarea1 = document.getElementById('textarea1'); |
| 34 assert_equals(editable1.children.length, 1, `${logInfo}, DOM is dirty`); | 42 assert_equals(editable1.children.length, 1, `${logInfo}, DOM is dirty`); |
| 35 assert_equals(editable1.children[0].tagName, 'IMG', `${logInfo}, DOM is dirt
y`); | 43 assert_equals(editable1.children[0].innerHTML, 'EditableText', `${logInfo},
DOM is dirty`); |
| 36 assert_equals(editable2.children.length, 0, `${logInfo}, DOM is dirty`); | 44 assert_equals(editable2.children.length, 0, `${logInfo}, DOM is dirty`); |
| 37 assert_equals(textarea1.value, 'Text', `${logInfo}, DOM is dirty`); | 45 assert_equals(textarea1.value, 'Text', `${logInfo}, DOM is dirty`); |
| 38 } | 46 } |
| 39 | 47 |
| 40 test(function() { | 48 test(function() { |
| 41 assertCleanInitialDOM(); | 49 assertCleanInitialDOM(); |
| 42 assert_not_equals(window.eventSender, undefined, 'This test requires eventSe
nder.'); | 50 assert_not_equals(window.eventSender, undefined, 'This test requires eventSe
nder.'); |
| 43 assert_not_equals(window.testRunner, undefined, 'This test requires testRunn
er.'); | 51 assert_not_equals(window.testRunner, undefined, 'This test requires testRunn
er.'); |
| 44 | 52 |
| 45 const editable1 = document.getElementById('editable1'); | 53 const editable1 = document.getElementById('editable1'); |
| 46 const editable2 = document.getElementById('editable2'); | 54 const editable2 = document.getElementById('editable2'); |
| 47 const textarea1 = document.getElementById('textarea1'); | 55 const textarea1 = document.getElementById('textarea1'); |
| 48 | 56 |
| 49 function preventDeleteByDragListener(event) { | 57 function preventDeleteByDragListener(event) { |
| 50 if (event.inputType == 'deleteByDrag') | 58 if (event.inputType == 'deleteByDrag') |
| 51 event.preventDefault(); | 59 event.preventDefault(); |
| 52 } | 60 } |
| 53 | 61 |
| 54 function preventInsertFromDropListener(event) { | 62 function preventInsertFromDropListener(event) { |
| 55 if (event.inputType == 'insertFromDrop') | 63 if (event.inputType == 'insertFromDrop') |
| 56 event.preventDefault(); | 64 event.preventDefault(); |
| 57 } | 65 } |
| 58 | 66 |
| 59 const undoBarrier = document.getElementById('barrier'); | 67 const undoBarrier = document.getElementById('barrier'); |
| 60 undoBarrier.focus(); | 68 undoBarrier.focus(); |
| 61 document.execCommand('insertText', false, 'abc'); | 69 document.execCommand('insertText', false, 'abc'); |
| 62 function assertBarrierUnchanged() { | 70 function assertBarrierUnchanged(log) { |
| 63 assert_equals(undoBarrier.value, 'abc'); | 71 assert_equals(undoBarrier.value, 'abc', log); |
| 64 } | 72 } |
| 65 | 73 |
| 66 // Normally Drag&Drop requires a single Undo. | 74 // Normally Drag&Drop requires a single Undo. |
| 67 simulateDragDrop(editable1, editable2); | 75 simulateDragDrop(editable1, editable2); |
| 76 assert_equals(editable1.children.length, 0, `Normal Drag&Drop should remove
data from editable1.`); |
| 77 assert_equals(editable2.children.length, 1, `Normal Drag&Drop should insert
data into editable2.`); |
| 68 testRunner.execCommand('undo'); | 78 testRunner.execCommand('undo'); |
| 69 assertCleanInitialDOM('Normal Drag&Drop'); | 79 assertCleanInitialDOM('Normal Drag&Drop'); |
| 70 assertBarrierUnchanged(); | 80 assertBarrierUnchanged('step 1'); |
| 71 | 81 |
| 72 // Canceling |DeleteByDrag|, still require a single Undo. | 82 // Canceling |DeleteByDrag|, still require a single Undo. |
| 73 editable1.addEventListener('beforeinput', preventDeleteByDragListener); | 83 editable1.addEventListener('beforeinput', preventDeleteByDragListener); |
| 74 simulateDragDrop(editable1, editable2); | 84 simulateDragDrop(editable1, editable2); |
| 75 testRunner.execCommand('undo'); | 85 testRunner.execCommand('undo'); |
| 76 assertCleanInitialDOM('Canceling |DeleteByDrag|'); | 86 assertCleanInitialDOM('Canceling |DeleteByDrag|'); |
| 77 editable1.removeEventListener('beforeinput', preventDeleteByDragListener); | 87 editable1.removeEventListener('beforeinput', preventDeleteByDragListener); |
| 78 assertBarrierUnchanged(); | 88 assertBarrierUnchanged('step 2'); |
| 79 | 89 |
| 80 // Canceling |InsertFromDrop|, still require a single Undo. | 90 // Canceling |InsertFromDrop|, still require a single Undo. |
| 81 editable2.addEventListener('beforeinput', preventInsertFromDropListener); | 91 editable2.addEventListener('beforeinput', preventInsertFromDropListener); |
| 82 simulateDragDrop(editable1, editable2); | 92 simulateDragDrop(editable1, editable2); |
| 83 testRunner.execCommand('undo'); | 93 testRunner.execCommand('undo'); |
| 84 assertCleanInitialDOM('Canceling |InsertFromDrop|'); | 94 assertCleanInitialDOM('Canceling |InsertFromDrop|'); |
| 85 editable2.removeEventListener('beforeinput', preventInsertFromDropListener); | 95 editable2.removeEventListener('beforeinput', preventInsertFromDropListener); |
| 86 assertBarrierUnchanged(); | 96 assertBarrierUnchanged('step 3'); |
| 87 | 97 |
| 88 // Canceling both, shouldn't create undo entry. | 98 // Canceling both, shouldn't create undo entry. |
| 89 editable1.addEventListener('beforeinput', preventDeleteByDragListener); | 99 editable1.addEventListener('beforeinput', preventDeleteByDragListener); |
| 90 editable2.addEventListener('beforeinput', preventInsertFromDropListener); | 100 editable2.addEventListener('beforeinput', preventInsertFromDropListener); |
| 91 simulateDragDrop(editable1, editable2); | 101 simulateDragDrop(editable1, editable2); |
| 92 assertCleanInitialDOM('Canceling both'); | 102 assertCleanInitialDOM('Canceling both'); |
| 93 testRunner.execCommand('undo'); | 103 testRunner.execCommand('undo'); |
| 94 assert_equals(undoBarrier.value, ''); | 104 assert_equals(undoBarrier.value, ''); |
| 95 testRunner.execCommand('redo'); | 105 testRunner.execCommand('redo'); |
| 96 assertBarrierUnchanged(); | 106 assertBarrierUnchanged('step 4'); |
| 97 editable1.removeEventListener('beforeinput', preventDeleteByDragListener); | 107 editable1.removeEventListener('beforeinput', preventDeleteByDragListener); |
| 98 editable2.removeEventListener('beforeinput', preventInsertFromDropListener); | 108 editable2.removeEventListener('beforeinput', preventInsertFromDropListener); |
| 99 | 109 |
| 100 // Two Drag&Drop, cancel first |InsertFromDrop| and second |DeleteByDrag|, s
hould still create 2 undo entries. | 110 // Two Drag&Drop, cancel first |InsertFromDrop| and second |DeleteByDrag|, s
hould still create 2 undo entries. |
| 101 editable2.addEventListener('beforeinput', preventInsertFromDropListener); | 111 editable2.addEventListener('beforeinput', preventInsertFromDropListener); |
| 102 simulateDragDrop(editable1, editable2); | 112 simulateDragDrop(editable1, editable2); |
| 103 editable2.removeEventListener('beforeinput', preventInsertFromDropListener); | 113 editable2.removeEventListener('beforeinput', preventInsertFromDropListener); |
| 104 textarea1.addEventListener('beforeinput', preventDeleteByDragListener); | 114 textarea1.addEventListener('beforeinput', preventDeleteByDragListener); |
| 105 textarea1.select(); | 115 textarea1.select(); |
| 106 simulateDragDrop(textarea1, editable2); | 116 simulateDragDrop(textarea1, editable2); |
| 107 textarea1.removeEventListener('beforeinput', preventDeleteByDragListener); | 117 textarea1.removeEventListener('beforeinput', preventDeleteByDragListener); |
| 108 assert_equals(editable1.children.length, 0); | 118 assert_equals(editable1.children.length, 0); |
| 109 assert_equals(editable2.innerHTML, 'Text'); | 119 assert_equals(editable2.innerHTML, 'Text'); |
| 110 assert_equals(textarea1.value, 'Text'); | 120 assert_equals(textarea1.value, 'Text'); |
| 111 // First undo. | 121 // First undo. |
| 112 testRunner.execCommand('undo'); | 122 testRunner.execCommand('undo'); |
| 113 assert_equals(editable1.children.length, 0); | 123 assert_equals(editable1.children.length, 0); |
| 114 assert_equals(editable2.innerHTML, ''); | 124 assert_equals(editable2.innerHTML, ''); |
| 115 assert_equals(textarea1.value, 'Text'); | 125 assert_equals(textarea1.value, 'Text'); |
| 116 // Second undo. | 126 // Second undo. |
| 117 testRunner.execCommand('undo'); | 127 testRunner.execCommand('undo'); |
| 118 assert_equals(editable1.children.length, 1); | 128 assert_equals(editable1.children.length, 1); |
| 119 assert_equals(editable2.innerHTML, ''); | 129 assert_equals(editable2.innerHTML, ''); |
| 120 assert_equals(textarea1.value, 'Text'); | 130 assert_equals(textarea1.value, 'Text'); |
| 121 // More undo should reach to |undoBarrier|. | 131 // More undo should reach to |undoBarrier|. |
| 122 assertBarrierUnchanged(); | 132 assertBarrierUnchanged('step 5'); |
| 123 testRunner.execCommand('undo'); | 133 testRunner.execCommand('undo'); |
| 124 assert_equals(undoBarrier.value, ''); | 134 assert_equals(undoBarrier.value, ''); |
| 125 testRunner.execCommand('redo'); | 135 testRunner.execCommand('redo'); |
| 126 }, 'Testing Drag and Drop, preventDefault() and Undo entry'); | 136 }, 'Testing Drag and Drop, preventDefault() and Undo entry'); |
| 127 | 137 |
| 128 test(function() { | 138 test(function() { |
| 129 assertCleanInitialDOM(); | 139 assertCleanInitialDOM(); |
| 130 assert_not_equals(window.eventSender, undefined, 'This test requires eventSe
nder.'); | 140 assert_not_equals(window.eventSender, undefined, 'This test requires eventSe
nder.'); |
| 131 assert_not_equals(window.testRunner, undefined, 'This test requires testRunn
er.'); | 141 assert_not_equals(window.testRunner, undefined, 'This test requires testRunn
er.'); |
| 132 | 142 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 143 function testDragDropEventOrder(dragElement, dropElement, expectedOrder) { | 153 function testDragDropEventOrder(dragElement, dropElement, expectedOrder) { |
| 144 assert_equals(dragElement.children.length, 1); | 154 assert_equals(dragElement.children.length, 1); |
| 145 eventOrderRecorder = []; | 155 eventOrderRecorder = []; |
| 146 simulateDragDrop(dragElement, dropElement); | 156 simulateDragDrop(dragElement, dropElement); |
| 147 assert_array_equals(eventOrderRecorder, expectedOrder, | 157 assert_array_equals(eventOrderRecorder, expectedOrder, |
| 148 `Testing drag ${dragElement.id} onto ${dropElement.id} actual order:
${eventOrderRecorder}`); | 158 `Testing drag ${dragElement.id} onto ${dropElement.id} actual order:
${eventOrderRecorder}`); |
| 149 } | 159 } |
| 150 | 160 |
| 151 // Test Drag and Drop. | 161 // Test Drag and Drop. |
| 152 testDragDropEventOrder(editable1, editable2, | 162 testDragDropEventOrder(editable1, editable2, |
| 153 ['editable2:drop', 'beforeinput:img:deleteByDrag', 'input:editable1:dele
teByDrag', | 163 ['editable2:drop', 'beforeinput:boldtext:deleteByDrag', 'input:editable1
:deleteByDrag', |
| 154 'beforeinput:editable2:insertFromDrop', 'input:editable2:insertFromDrop'
, 'editable1:dragend']); | 164 'beforeinput:editable2:insertFromDrop', 'input:editable2:insertFromDrop'
, 'editable1:dragend']); |
| 155 testRunner.execCommand('undo'); | 165 testRunner.execCommand('undo'); |
| 156 }, 'Testing Drag and Drop event order'); | 166 }, 'Testing Drag and Drop event order'); |
| 157 | 167 |
| 158 test(function() { | 168 test(function() { |
| 159 assertCleanInitialDOM(); | 169 assertCleanInitialDOM(); |
| 160 assert_not_equals(window.eventSender, undefined, 'This test requires eventSe
nder.'); | 170 assert_not_equals(window.eventSender, undefined, 'This test requires eventSe
nder.'); |
| 161 assert_not_equals(window.testRunner, undefined, 'This test requires testRunn
er.'); | 171 assert_not_equals(window.testRunner, undefined, 'This test requires testRunn
er.'); |
| 162 | 172 |
| 163 const editable1 = document.getElementById('editable1'); | 173 const editable1 = document.getElementById('editable1'); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 181 `Testing '${inputType}' getData('text/html')`); | 191 `Testing '${inputType}' getData('text/html')`); |
| 182 } else { | 192 } else { |
| 183 assert_equals(lastHTMLData[inputType], expectedHTML, | 193 assert_equals(lastHTMLData[inputType], expectedHTML, |
| 184 `Testing '${inputType}' getData('text/html')`); | 194 `Testing '${inputType}' getData('text/html')`); |
| 185 } | 195 } |
| 186 } | 196 } |
| 187 | 197 |
| 188 // Test Drag and Drop. | 198 // Test Drag and Drop. |
| 189 testDragDropDataTransfer('deleteByDrag', editable1, editable2, null, null); | 199 testDragDropDataTransfer('deleteByDrag', editable1, editable2, null, null); |
| 190 testRunner.execCommand('undo'); | 200 testRunner.execCommand('undo'); |
| 191 testDragDropDataTransfer('insertFromDrop', editable1, editable2, '', /^<img.
*greenbox\.png".*>$/); | 201 testDragDropDataTransfer('insertFromDrop', editable1, editable2, 'EditableTe
xt', /^.*EditableText<\/b>$/); |
| 192 testRunner.execCommand('undo'); | 202 testRunner.execCommand('undo'); |
| 193 }, 'Testing Drag and Drop dataTransfer'); | 203 }, 'Testing Drag and Drop dataTransfer'); |
| 194 | 204 |
| 195 test(function() { | 205 test(function() { |
| 196 assertCleanInitialDOM(); | 206 assertCleanInitialDOM(); |
| 197 assert_not_equals(window.eventSender, undefined, 'This test requires eventSe
nder.'); | 207 assert_not_equals(window.eventSender, undefined, 'This test requires eventSe
nder.'); |
| 198 assert_not_equals(window.testRunner, undefined, 'This test requires testRunn
er.'); | 208 assert_not_equals(window.testRunner, undefined, 'This test requires testRunn
er.'); |
| 199 | 209 |
| 200 const editable1 = document.getElementById('editable1'); | 210 const editable1 = document.getElementById('editable1'); |
| 201 const editable2 = document.getElementById('editable2'); | 211 const editable2 = document.getElementById('editable2'); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 testDragDropEventOrder(editable1, editable2, | 294 testDragDropEventOrder(editable1, editable2, |
| 285 ['editable2:drop', 'beforeinput:editable1:deleteByDrag', 'beforeinput:ed
itable2:insertFromDrop', | 295 ['editable2:drop', 'beforeinput:editable1:deleteByDrag', 'beforeinput:ed
itable2:insertFromDrop', |
| 286 'input:editable2:insertFromDrop', 'editable1:dragend']); | 296 'input:editable2:insertFromDrop', 'editable1:dragend']); |
| 287 editable1.removeEventListener('beforeinput', removeEditable1Listener); | 297 editable1.removeEventListener('beforeinput', removeEditable1Listener); |
| 288 testRunner.execCommand('undo'); | 298 testRunner.execCommand('undo'); |
| 289 document.body.appendChild(editable1); | 299 document.body.appendChild(editable1); |
| 290 }, 'Testing element removed by event handler'); | 300 }, 'Testing element removed by event handler'); |
| 291 </script> | 301 </script> |
| 292 </body> | 302 </body> |
| 293 </html> | 303 </html> |
| OLD | NEW |