| Index: third_party/WebKit/LayoutTests/fast/events/inputevents/inputevent-drag-drop.html
|
| diff --git a/third_party/WebKit/LayoutTests/fast/events/inputevents/inputevent-drag-drop.html b/third_party/WebKit/LayoutTests/fast/events/inputevents/inputevent-drag-drop.html
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..ea68c1c380bd78786990f48f2ea5e028bbfc2cb4
|
| --- /dev/null
|
| +++ b/third_party/WebKit/LayoutTests/fast/events/inputevents/inputevent-drag-drop.html
|
| @@ -0,0 +1,189 @@
|
| +<!DOCTYPE html>
|
| +<html>
|
| +<head>
|
| +<title>InputEvent: beforeinput for Drag and Drop</title>
|
| +<script src="../../../resources/testharness.js"></script>
|
| +<script src="../../../resources/testharnessreport.js"></script>
|
| +<style>
|
| +div, img {
|
| + width: 100px;
|
| + height: 100px;
|
| +}
|
| +</style>
|
| +</head>
|
| +<body>
|
| +<div id="editable1" contenteditable><img id="img" src="../resources/greenbox.png"></div>
|
| +<div id="editable2" contenteditable></div>
|
| +<script>
|
| +function simulateDragDrop(dragElement, dropElement) {
|
| + eventSender.mouseMoveTo(dragElement.offsetLeft + dragElement.offsetWidth / 2,
|
| + dragElement.offsetTop + dragElement.offsetHeight / 2);
|
| + eventSender.mouseDown();
|
| + eventSender.leapForward(100);
|
| + eventSender.mouseMoveTo(dropElement.offsetLeft + dropElement.offsetWidth / 2,
|
| + dropElement.offsetTop + dropElement.offsetHeight / 2);
|
| + eventSender.mouseUp();
|
| +}
|
| +
|
| +test(function() {
|
| + assert_not_equals(window.eventSender, undefined, 'This test requires eventSender.');
|
| + assert_not_equals(window.testRunner, undefined, 'This test requires testRunner.');
|
| +
|
| + const editable1 = document.getElementById('editable1');
|
| + const editable2 = document.getElementById('editable2');
|
| + var eventOrderRecorder = [];
|
| + document.addEventListener('beforeinput', event =>
|
| + eventOrderRecorder.push(`beforeinput:${event.target.id}:${event.inputType}`));
|
| + document.addEventListener('input', event =>
|
| + eventOrderRecorder.push(`input:${event.target.id}:${event.inputType}`));
|
| + ['drop', 'dragend'].forEach(eventType => document.addEventListener(
|
| + eventType, () => eventOrderRecorder.push(`${event.target.id}:${eventType}`)));
|
| +
|
| + function testDragDropEventOrder(dragElement, dropElement, expectedOrder) {
|
| + assert_equals(dragElement.children.length, 1);
|
| + eventOrderRecorder = [];
|
| + simulateDragDrop(dragElement, dropElement);
|
| + assert_array_equals(eventOrderRecorder, expectedOrder,
|
| + `Testing drag ${dragElement.id} onto ${dropElement.id} actual order: ${eventOrderRecorder}`);
|
| + }
|
| +
|
| + // Test Drag and Drop.
|
| + testDragDropEventOrder(editable1, editable2,
|
| + ['editable2:drop', 'beforeinput:img:deleteByDrag', 'input:editable1:deleteByDrag',
|
| + 'beforeinput:editable2:insertFromDrop', 'input:editable2:insertFromDrop', 'editable1:dragend']);
|
| + testRunner.execCommand('undo');
|
| +}, 'Testing Drag and Drop event order');
|
| +
|
| +test(function() {
|
| + assert_not_equals(window.eventSender, undefined, 'This test requires eventSender.');
|
| + assert_not_equals(window.testRunner, undefined, 'This test requires testRunner.');
|
| +
|
| + const editable1 = document.getElementById('editable1');
|
| + const editable2 = document.getElementById('editable2');
|
| + var lastPlainTextData = {};
|
| + var lastHTMLData = {};
|
| + document.addEventListener('beforeinput', event => {
|
| + lastPlainTextData[event.inputType] = event.dataTransfer ? event.dataTransfer.getData('text/plain') : null;
|
| + lastHTMLData[event.inputType] = event.dataTransfer ? event.dataTransfer.getData('text/html') : null;
|
| + });
|
| +
|
| + function testDragDropDataTransfer(inputType, dragElement, dropElement, expectedPlainText, expectedHTML) {
|
| + assert_equals(dragElement.children.length, 1);
|
| + lastPlainTextData = {};
|
| + lastHTMLData = {};
|
| + simulateDragDrop(dragElement, dropElement);
|
| + assert_equals(lastPlainTextData[inputType], expectedPlainText,
|
| + `Testing '${inputType}' getData('text/plain')`);
|
| + if (expectedHTML && expectedHTML.test) {
|
| + assert_regexp_match(lastHTMLData[inputType], expectedHTML,
|
| + `Testing '${inputType}' getData('text/html')`);
|
| + } else {
|
| + assert_equals(lastHTMLData[inputType], expectedHTML,
|
| + `Testing '${inputType}' getData('text/html')`);
|
| + }
|
| + }
|
| +
|
| + // Test Drag and Drop.
|
| + testDragDropDataTransfer('deleteByDrag', editable1, editable2, null, null);
|
| + testRunner.execCommand('undo');
|
| + testDragDropDataTransfer('insertFromDrop', editable1, editable2, '', /^<img.*greenbox\.png".*>$/);
|
| + testRunner.execCommand('undo');
|
| +}, 'Testing Drag and Drop dataTransfer');
|
| +
|
| +test(function() {
|
| + assert_not_equals(window.eventSender, undefined, 'This test requires eventSender.');
|
| + assert_not_equals(window.testRunner, undefined, 'This test requires testRunner.');
|
| +
|
| + const editable1 = document.getElementById('editable1');
|
| + const editable2 = document.getElementById('editable2');
|
| + var inputTypesToPrevent = [];
|
| + document.addEventListener('beforeinput', event => {
|
| + if (inputTypesToPrevent.indexOf(event.inputType) != -1)
|
| + event.preventDefault();
|
| + });
|
| +
|
| + function testDragDropPreventDefault(preventDefaultTypes, dragElement, dropElement, expectedDragElementChildren, expectedDropElementChildren) {
|
| + assert_equals(dragElement.children.length, 1);
|
| + inputTypesToPrevent = preventDefaultTypes;
|
| + simulateDragDrop(dragElement, dropElement);
|
| + assert_equals(dragElement.children.length, expectedDragElementChildren,
|
| + 'Testing preventDefault() on ${preventDefaultTypes} ${dragElement.id} children count');
|
| + assert_equals(dropElement.children.length, expectedDropElementChildren,
|
| + 'Testing preventDefault() on ${preventDefaultTypes} ${dropElement.id} children count');
|
| + inputTypesToPrevent = [];
|
| + }
|
| +
|
| + // Preventing single 'beforeinput' will only cancel DOM update for one event,
|
| + // the remaining DOM update will still update undo stack.
|
| + testDragDropPreventDefault(['deleteByDrag'], editable1, editable2, 1, 1);
|
| + testRunner.execCommand('undo');
|
| + testDragDropPreventDefault(['insertFromDrop'], editable1, editable2, 0, 0);
|
| + testRunner.execCommand('undo');
|
| +
|
| + // Adding 'insertHTML' command to undo stack.
|
| + editable2.focus();
|
| + document.execCommand('insertHTML', false, '<b>B</b><i>i</i>');
|
| + assert_equals(editable2.children.length, 2,
|
| + '"editable2" should have 2 children after "insertHTML" command');
|
| + // Canceling both |deleteByDrag| and |insertFromDrop| won't modify undo stack.
|
| + testDragDropPreventDefault(['deleteByDrag', 'insertFromDrop'], editable1, editable2, 1, 2);
|
| + // |undo| will undo last 'insertHTML' command.
|
| + testRunner.execCommand('undo');
|
| + assert_equals(editable2.children.length, 0,
|
| + '"editable2" should have 0 children after undo "insertHTML"');
|
| +}, 'Testing Drag and Drop preventDefault()');
|
| +
|
| +test(function() {
|
| + assert_not_equals(window.eventSender, undefined, 'This test requires eventSender.');
|
| + assert_not_equals(window.testRunner, undefined, 'This test requires testRunner.');
|
| +
|
| + const editable1 = document.getElementById('editable1');
|
| + const editable2 = document.getElementById('editable2');
|
| + var eventOrderRecorder = [];
|
| + [editable1, editable2].forEach(editable => {
|
| + editable.addEventListener('beforeinput', event =>
|
| + eventOrderRecorder.push(`beforeinput:${editable.id}:${event.inputType}`));
|
| + editable.addEventListener('input', event =>
|
| + eventOrderRecorder.push(`input:${editable.id}:${event.inputType}`));
|
| + editable.addEventListener('drop', event =>
|
| + eventOrderRecorder.push(`${editable.id}:drop`));
|
| + editable.addEventListener('dragend', event =>
|
| + eventOrderRecorder.push(`${editable.id}:dragend`));
|
| + });
|
| +
|
| + function testDragDropEventOrder(dragElement, dropElement, expectedOrder) {
|
| + assert_equals(dragElement.children.length, 1);
|
| + eventOrderRecorder = [];
|
| + simulateDragDrop(dragElement, dropElement);
|
| + assert_array_equals(eventOrderRecorder, expectedOrder,
|
| + `Testing drag ${dragElement.id} onto ${dropElement.id} actual order: ${eventOrderRecorder}`);
|
| + }
|
| +
|
| + function removeEditable1Listener() {
|
| + editable1.remove();
|
| + }
|
| +
|
| + function removeEditable2Listener() {
|
| + editable2.remove();
|
| + }
|
| +
|
| + // Testing remove drop target, |editable2| won't get 'beforeinput' as it's disconnected.
|
| + editable1.addEventListener('beforeinput', removeEditable2Listener);
|
| + testDragDropEventOrder(editable1, editable2,
|
| + ['editable2:drop', 'beforeinput:editable1:deleteByDrag', 'input:editable1:deleteByDrag', 'editable1:dragend']);
|
| + editable1.removeEventListener('beforeinput', removeEditable2Listener);
|
| + testRunner.execCommand('undo');
|
| + document.body.appendChild(editable2);
|
| +
|
| + // Testing remove drag target, |editable1| won't receive DOM updates after disconnected.
|
| + editable1.addEventListener('beforeinput', removeEditable1Listener);
|
| + testDragDropEventOrder(editable1, editable2,
|
| + ['editable2:drop', 'beforeinput:editable1:deleteByDrag', 'beforeinput:editable2:insertFromDrop',
|
| + 'input:editable2:insertFromDrop', 'editable1:dragend']);
|
| + editable1.removeEventListener('beforeinput', removeEditable1Listener);
|
| + testRunner.execCommand('undo');
|
| + document.body.appendChild(editable1);
|
| +}, 'Testing element removed by event handler');
|
| +</script>
|
| +</body>
|
| +</html>
|
|
|