Index: third_party/WebKit/LayoutTests/fast/events/inputevents/beforeinput-remove-iframe-crash.html |
diff --git a/third_party/WebKit/LayoutTests/fast/events/inputevents/beforeinput-remove-iframe-crash.html b/third_party/WebKit/LayoutTests/fast/events/inputevents/beforeinput-remove-iframe-crash.html |
new file mode 100644 |
index 0000000000000000000000000000000000000000..e3624859ae994f2c6f4f60790be9cd2098b0e74c |
--- /dev/null |
+++ b/third_party/WebKit/LayoutTests/fast/events/inputevents/beforeinput-remove-iframe-crash.html |
@@ -0,0 +1,76 @@ |
+<!DOCTYPE html> |
+<html> |
+<head> |
+<title>InputEvent: beforeinput shouldn't crash in removed iframe</title> |
+<script src="../../../resources/testharness.js"></script> |
+<script src="../../../resources/testharnessreport.js"></script> |
+</head> |
+<body> |
+<script> |
+test(function() { |
+ assert_not_equals(window.eventSender, undefined, 'This test requires eventSender.'); |
+ assert_not_equals(window.testRunner, undefined, 'This test requires testRunner.'); |
+ |
+ function testBeforeInputCrash(expectedBeforeInputCount, beforeInputTrigger, comments) { |
+ const iframe = document.createElement('iframe'); |
+ const html = '<p id="editable" contenteditable>Foo</p>'; |
+ document.body.appendChild(iframe); |
+ const childDocument = iframe.contentDocument; |
+ childDocument.open(); |
yosin_UTC9
2016/08/24 02:11:44
nit: You could write:
childDocument.body.innerHTML
chongz
2016/08/24 02:42:01
Done.
|
+ childDocument.write(html); |
+ childDocument.close(); |
+ |
+ var actualBeforeInputCount = 0; |
+ const editable = childDocument.getElementById('editable'); |
+ editable.addEventListener('beforeinput', event => { |
+ actualBeforeInputCount++; |
+ if (actualBeforeInputCount == expectedBeforeInputCount && iframe.parentNode) { |
yosin_UTC9
2016/08/24 02:11:44
nit: We don't need to have {} for one statement th
chongz
2016/08/24 02:42:01
Done.
|
+ iframe.parentNode.removeChild(iframe); |
yosin_UTC9
2016/08/24 02:11:44
nit: iframe.remove() is shorter.
chongz
2016/08/24 02:42:01
Done.
|
+ } |
+ }); |
+ |
+ editable.focus(); |
+ beforeInputTrigger(childDocument, editable); |
+ |
+ if (iframe.parentNode) { |
yosin_UTC9
2016/08/24 02:11:44
nit: We don't need to have {} for one statement th
chongz
2016/08/24 02:42:01
Done.
|
+ iframe.parentNode.removeChild(iframe); |
yosin_UTC9
2016/08/24 02:11:44
nit: iframe.remove() is shorter.
chongz
2016/08/24 02:42:01
Done.
|
+ } |
+ assert_equals(actualBeforeInputCount, expectedBeforeInputCount, comments); |
+ } |
+ |
+ // Text command. |
+ testBeforeInputCrash(1, () => eventSender.keyDown('a'), 'Testing insertText "a"'); |
+ testBeforeInputCrash(1, () => eventSender.keyDown('Enter', ['shiftKey']), 'Testing insertLineBreak'); |
+ testBeforeInputCrash(1, () => eventSender.keyDown('Delete'), 'Testing deleteCharacterForward'); |
+ |
+ // Styling command. |
+ testBeforeInputCrash(1, (childDocument, editable) => { |
+ var selection = childDocument.getSelection(); |
+ selection.collapse(editable, 0); |
+ selection.extend(editable, 1); |
+ testRunner.execCommand('bold'); |
+ }, 'Testing bold'); |
+ |
+ // Cut & Paste. |
+ testBeforeInputCrash(1, (childDocument, editable) => { |
+ var selection = childDocument.getSelection(); |
+ selection.collapse(editable, 0); |
+ selection.extend(editable, 1); |
+ eventSender.keyDown('Cut'); |
+ }, 'Testing deleteByCut'); |
+ testBeforeInputCrash(1, () => eventSender.keyDown('Paste'), 'Testing insertFromPaste'); |
+ |
+ // Undo & Redo. |
+ testBeforeInputCrash(2, () => { |
+ eventSender.keyDown('a'); |
+ testRunner.execCommand('undo'); |
+ }, 'Testing undo'); |
+ testBeforeInputCrash(3, () => { |
+ eventSender.keyDown('a'); |
+ testRunner.execCommand('undo'); |
+ testRunner.execCommand('redo'); |
+ }, 'Testing redo'); |
+}, 'Testing beforeinput in removed iframe'); |
+</script> |
+</body> |
+</html> |