blob: 883043978c4ec7864d019d3d7911094621f511ad [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<title>InputEvent: cancelable</title>
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<style>
div {
width: 100px;
height: 100px;
}
</style>
</head>
<body>
<div id="editable" contenteditable></div>
<div id="editable1" contenteditable>EditableText</div>
<div id="editable2" contenteditable></div>
<script>
function simulateDragDrop(dragElement, dropElement) {
if (dragElement.select) {
dragElement.select();
} else {
var selection = window.getSelection();
selection.collapse(dragElement, 0);
selection.extend(dragElement, 1);
}
eventSender.mouseMoveTo(dragElement.offsetLeft + dragElement.offsetWidth / 2,
dragElement.offsetTop + dragElement.offsetHeight / 2);
eventSender.mouseDown();
eventSender.leapForward(600);
eventSender.mouseMoveTo(dropElement.offsetLeft + dropElement.offsetWidth / 2,
dropElement.offsetTop + dropElement.offsetHeight / 2);
eventSender.mouseUp();
}
async_test(t => {
assert_not_equals(window.eventSender, undefined, 'This test requires eventSender.');
assert_not_equals(window.testRunner, undefined, 'This test requires testRunner.');
assert_not_equals(internals, undefined, 'This test requires internals.');
assert_not_equals(textInputController, undefined, 'This test requires textInputController.');
const editable = document.getElementById('editable');
const editable1 = document.getElementById('editable1');
const editable2 = document.getElementById('editable2');
const kNoncancelableInputTypes = [
'insertCompositionText',
];
let lastBeforeInputType = '';
let doCancel = false;
document.addEventListener('beforeinput', t.step_func(event => {
lastBeforeInputType = event.inputType;
assert_equals(kNoncancelableInputTypes.indexOf(event.inputType) === -1, event.cancelable);
if (doCancel) event.preventDefault();
}));
function testKeyDown(key, modifiers, inputType) {
lastBeforeInputType = '';
doCancel = false;
eventSender.keyDown(key, modifiers);
assert_equals(inputType, lastBeforeInputType, `${modifiers.toString()}+${key} should produce input type: ${inputType}`);
}
function testCommand(command, inputType) {
lastBeforeInputType = '';
doCancel = false;
testRunner.execCommand(command);
assert_equals(inputType, lastBeforeInputType, `${command} should produce input type: ${inputType}`);
}
function sendCancel(key, inputType) {
lastBeforeInputType = '';
doCancel = true;
eventSender.keyDown(key, []);
}
// Typing
editable.focus();
testKeyDown('a', [], 'insertText');
testKeyDown('6', [], 'insertText');
testKeyDown('l', ['shiftKey'], 'insertText');
testKeyDown('w', ['shiftKey'], 'insertText');
testKeyDown('Enter', [], 'insertParagraph');
testKeyDown('Enter', ['shiftKey'], 'insertLineBreak');
editable.innerText = '';
testKeyDown('a', [], 'insertText');
assert_equals(editable.innerText, 'a');
sendCancel('b', 'insertText');
assert_equals(editable.innerText, 'a');
// Deletion
const isMacOS = navigator.platform.indexOf('Mac') === 0;
const deleteWordModifier = isMacOS ? 'altKey' : 'ctrlKey';
editable.innerHTML = 'abc def</br>123 456';
const selection = window.getSelection();
selection.collapse(editable, 1); // End of first line.
testKeyDown('Backspace', [], 'deleteContentBackward');
testKeyDown('Delete', [], 'deleteContentForward');
testKeyDown('Backspace', [deleteWordModifier], 'deleteWordBackward');
testKeyDown('Delete', [deleteWordModifier], 'deleteWordForward');
testCommand('deleteToBeginningOfLine', 'deleteSoftLineBackward');
testCommand('deleteToEndOfLine', 'deleteSoftLineForward');
testCommand('deleteToBeginningOfParagraph', 'deleteHardLineBackward');
testCommand('deleteToEndOfParagraph', 'deleteHardLineForward');
editable.innerText = '';
testKeyDown('a', [], 'insertText');
assert_equals(editable.innerText, 'a');
sendCancel('Backspace', 'deleteContentBackward');
assert_equals(editable.innerText, 'a');
// Format
editable.innerHTML = 'abc';
selection.collapse(editable, 0);
selection.extend(editable, 1);
testCommand('bold', 'formatBold');
testCommand('italic', 'formatItalic');
testCommand('underline', 'formatUnderline');
testCommand('strikeThrough', 'formatStrikeThrough');
testCommand('superscript', 'formatSuperscript');
testCommand('subscript', 'formatSubscript');
// Cut and paste
editable.innerHTML = 'abc';
selection.collapse(editable, 0);
selection.extend(editable, 1);
testKeyDown('Cut', [], 'deleteByCut');
testKeyDown('Paste', [], 'insertFromPaste');
// Drag and drop
simulateDragDrop(editable1, editable2);
assert_equals('insertFromDrop', lastBeforeInputType);
// Undo and redo
testCommand('undo', 'historyUndo');
testCommand('redo', 'historyRedo');
// Spell-checker
editable.innerHTML = 'appla';
selection.collapse(editable, 0);
selection.extend(editable, 1);
internals.setMarker(document, selection.getRangeAt(0), 'Spelling');
internals.replaceMisspelled(document, 'apple');
assert_equals('insertReplacementText', lastBeforeInputType);
// IME
editable.innerHTML = 'wo';
selection.collapse(editable, 0);
selection.extend(editable, 1);
textInputController.setComposition('word');
assert_equals('insertCompositionText', lastBeforeInputType);
t.done();
}, 'Text input and IME related input types are non-cancelable.');
</script>
</body>
</html>