Skip to content
Permalink
Browse files
Support InputEvent.inputType for the new InputEvent spec
https://bugs.webkit.org/show_bug.cgi?id=163025
<rdar://problem/28658092>

Reviewed by Darin Adler.

Source/WebCore:

Adds support for the inputType attribute of InputEvent. To do this, we introduce a helper to
map EditActions to inputType names, and also split out ambiguous EditActions (such as
EditActionTyping) into more specific subtypes (such as EditActionTypingDeleteBackward,
EditActionTypingInsertParagraph, etc.), each of which corresponds to an inputType.

In places where we create CompositeEditCommands, we now pass in these specific EditActions
where appropriate, and when dispatching `beforeinput` and `input` events, we ask the
CompositeEditCommand for its input type name, which it derives from its editingAction.

Tests: fast/events/before-input-prevent-biu.html
       fast/events/before-input-prevent-cut.html
       fast/events/before-input-prevent-paste.html
       fast/events/before-input-prevent-typing.html
       fast/events/before-input-prevent-undo.html

* dom/InputEvent.h:
* dom/Node.cpp:
(WebCore::Node::dispatchInputEvent):
* dom/Node.h:
* editing/CompositeEditCommand.cpp:
(WebCore::CompositeEditCommand::apply):
(WebCore::CompositeEditCommand::inputEventTypeName):

Allows a CompositeEditCommand to specify the inputType its corresponding `beforeinput` and `input` events
should have.

* editing/CompositeEditCommand.h:
(WebCore::CompositeEditCommand::shouldStopCaretBlinking): Deleted.
* editing/EditAction.h:
* editing/EditCommand.cpp:
(WebCore::inputTypeNameForEditingAction):
* editing/EditCommand.h:
* editing/Editor.cpp:
(WebCore::Editor::willApplyEditing):
(WebCore::Editor::appliedEditing):
(WebCore::Editor::willUnapplyEditing):
(WebCore::Editor::unappliedEditing):
(WebCore::Editor::willReapplyEditing):
(WebCore::Editor::reappliedEditing):
(WebCore::Editor::computeAndSetTypingStyle):
* editing/InsertListCommand.cpp:
(WebCore::InsertListCommand::editingAction):
* editing/InsertListCommand.h:
(WebCore::InsertListCommand::preservesTypingStyle): Deleted.
(WebCore::InsertListCommand::editingAction): Deleted.
* editing/ReplaceRangeWithTextCommand.cpp:
(WebCore::ReplaceRangeWithTextCommand::ReplaceRangeWithTextCommand):
* editing/SpellingCorrectionCommand.cpp:
(WebCore::SpellingCorrectionCommand::SpellingCorrectionCommand):
* editing/TypingCommand.cpp:
(WebCore::editActionForTypingCommand):
(WebCore::TypingCommand::TypingCommand):
(WebCore::TypingCommand::inputEventTypeName):

The editingAction() of a TypingCommand is the first editing action the TypingCommand was initialized using.
Since subsequent typing commands update the last open typing command, we override inputEventTypeName here to
use the last updated editing action rather than the default (initial) editing action.

(WebCore::TypingCommand::willAddTypingToOpenCommand):
(WebCore::TypingCommand::insertTextRunWithoutNewlines):
(WebCore::TypingCommand::insertParagraphSeparator):
* editing/TypingCommand.h:

Source/WebKit/mac:

Accounts for some changes to the EditAction enum in nameForEditAction. See WebCore ChangeLog
entry for more details.

* WebCoreSupport/WebEditorClient.mm:
(undoNameForEditAction):

Source/WebKit/win:

* WebCoreSupport/WebEditorClient.cpp:
(undoNameForEditAction):

Source/WebKit2:

Accounts for some changes to the EditAction enum in nameForEditAction. Some former edit
actions, such as EditActionTyping, have been split out into its more specific subtypes,
so we preserve shipping behavior by treating all of the new subtypes the same way as the
original type.

* UIProcess/WebEditCommandProxy.cpp:
(WebKit::WebEditCommandProxy::nameForEditAction):

LayoutTests:

Adds new layout tests to check that various actions, such as cutting, pasting and undoing can
be prevented via the InputEvent fired in a `beforechange` handler.

* fast/events/before-input-prevent-biu-expected.txt: Added.
* fast/events/before-input-prevent-biu.html: Added.
* fast/events/before-input-prevent-cut-expected.txt: Added.
* fast/events/before-input-prevent-cut.html: Added.
* fast/events/before-input-prevent-paste-expected.txt: Added.
* fast/events/before-input-prevent-paste.html: Added.
* fast/events/before-input-prevent-typing-expected.txt: Added.
* fast/events/before-input-prevent-typing.html: Added.
* fast/events/before-input-prevent-undo-expected.txt: Added.
* fast/events/before-input-prevent-undo.html: Added.
* platform/ios-simulator/TestExpectations:


Canonical link: https://commits.webkit.org/181027@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@206979 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
whsieh committed Oct 10, 2016
1 parent aeddebc commit b8db88f6abf44081df33d53d9b6f86a1f785ae59
Showing with 645 additions and 33 deletions.
  1. +23 −0 LayoutTests/ChangeLog
  2. +7 −0 LayoutTests/fast/events/before-input-prevent-biu-expected.txt
  3. +39 −0 LayoutTests/fast/events/before-input-prevent-biu.html
  4. +19 −0 LayoutTests/fast/events/before-input-prevent-cut-expected.txt
  5. +41 −0 LayoutTests/fast/events/before-input-prevent-cut.html
  6. +26 −0 LayoutTests/fast/events/before-input-prevent-paste-expected.txt
  7. +47 −0 LayoutTests/fast/events/before-input-prevent-paste.html
  8. +16 −0 LayoutTests/fast/events/before-input-prevent-typing-expected.txt
  9. +53 −0 LayoutTests/fast/events/before-input-prevent-typing.html
  10. +13 −0 LayoutTests/fast/events/before-input-prevent-undo-expected.txt
  11. +34 −0 LayoutTests/fast/events/before-input-prevent-undo.html
  12. +5 −0 LayoutTests/platform/ios-simulator/TestExpectations
  13. +71 −0 Source/WebCore/ChangeLog
  14. +2 −2 Source/WebCore/dom/InputEvent.h
  15. +1 −1 Source/WebCore/dom/Node.cpp
  16. +1 −1 Source/WebCore/dom/Node.h
  17. +16 −1 Source/WebCore/editing/CompositeEditCommand.cpp
  18. +1 −0 Source/WebCore/editing/CompositeEditCommand.h
  19. +13 −2 Source/WebCore/editing/EditAction.h
  20. +63 −0 Source/WebCore/editing/EditCommand.cpp
  21. +3 −1 Source/WebCore/editing/EditCommand.h
  22. +9 −8 Source/WebCore/editing/Editor.cpp
  23. +5 −0 Source/WebCore/editing/InsertListCommand.cpp
  24. +4 −4 Source/WebCore/editing/InsertListCommand.h
  25. +1 −1 Source/WebCore/editing/ReplaceRangeWithTextCommand.cpp
  26. +1 −1 Source/WebCore/editing/SpellingCorrectionCommand.cpp
  27. +41 −4 Source/WebCore/editing/TypingCommand.cpp
  28. +3 −0 Source/WebCore/editing/TypingCommand.h
  29. +14 −0 Source/WebKit/mac/ChangeLog
  30. +15 −2 Source/WebKit/mac/WebCoreSupport/WebEditorClient.mm
  31. +11 −0 Source/WebKit/win/ChangeLog
  32. +17 −3 Source/WebKit/win/WebCoreSupport/WebEditorClient.cpp
  33. +16 −0 Source/WebKit2/ChangeLog
  34. +14 −2 Source/WebKit2/UIProcess/WebEditCommandProxy.cpp
@@ -1,3 +1,26 @@
2016-10-09 Wenson Hsieh <wenson_hsieh@apple.com>

Support InputEvent.inputType for the new InputEvent spec
https://bugs.webkit.org/show_bug.cgi?id=163025
<rdar://problem/28658092>

Reviewed by Darin Adler.

Adds new layout tests to check that various actions, such as cutting, pasting and undoing can
be prevented via the InputEvent fired in a `beforechange` handler.

* fast/events/before-input-prevent-biu-expected.txt: Added.
* fast/events/before-input-prevent-biu.html: Added.
* fast/events/before-input-prevent-cut-expected.txt: Added.
* fast/events/before-input-prevent-cut.html: Added.
* fast/events/before-input-prevent-paste-expected.txt: Added.
* fast/events/before-input-prevent-paste.html: Added.
* fast/events/before-input-prevent-typing-expected.txt: Added.
* fast/events/before-input-prevent-typing.html: Added.
* fast/events/before-input-prevent-undo-expected.txt: Added.
* fast/events/before-input-prevent-undo.html: Added.
* platform/ios-simulator/TestExpectations:

2016-10-09 Gyuyoung Kim <gyuyoung.kim@navercorp.com>

[EFL] Gardening timout tests, failure tests on Oct. 10th.
@@ -0,0 +1,7 @@
To manually test this, turn on bold, italic and underline via the context menu, and then type some text into the contenteditable. The text should be italicized and underlined, but not bold.

after typing:
| "abc"
| <i>
| <u>
| "def<#selection-caret>"
@@ -0,0 +1,39 @@
<!DOCTYPE html>
<html>
<body>
<div id="editable" contenteditable onbeforeinput=handleBeforeInput(event)></div>
<script src="../../resources/dump-as-markup.js"></script>
<script type="text/javascript">
Markup.description(`To manually test this, turn on bold, italic and underline via the context menu, and then type some text into the contenteditable. The text should be italicized and underlined, but not bold.`);

(function() {
if (!window.internals || !window.eventSender || !window.testRunner)
return;

internals.settings.setInputEventsEnabled(true);
document.querySelector("#editable").focus();

eventSender.keyDown("a", []);
eventSender.keyDown("b", []);
eventSender.keyDown("c", []);

testRunner.execCommand("ToggleBold");
testRunner.execCommand("ToggleItalic");
testRunner.execCommand("ToggleUnderline");

eventSender.keyDown("d", []);
eventSender.keyDown("e", []);
eventSender.keyDown("f", []);
Markup.dump("editable", "after typing");

})();

function handleBeforeInput(event)
{
if (event.inputType === "formatBold")
event.preventDefault();
}
</script>
</body>

</html>
@@ -0,0 +1,19 @@
To manually test this, select the text in the input and attempt to cut. The value of the input should not change.

initial value:
| <shadow:root>
| <div>
| contenteditable="plaintext-only"
| "helloworld"

after prevented cut:
| <shadow:root>
| <div>
| contenteditable="plaintext-only"
| "helloworld"

after allowed cut:
| <shadow:root>
| <div>
| contenteditable="plaintext-only"
| <br>
@@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<body>
<input id="field" onfocus=handleFocus() value="helloworld" onbeforeinput=handleBeforeInput(event)></div>
<script src="../../resources/dump-as-markup.js"></script>
<script>
Markup.description(`To manually test this, select the text in the input and attempt to cut. The value of the input should not change.`);

var allowCut = false;
(function() {
if (!window.internals || !window.eventSender || !window.testRunner)
return;

internals.settings.setInputEventsEnabled(true);
document.querySelector("#field").focus();
})();

function handleBeforeInput(event)
{
if (allowCut)
return;

if (event.inputType === "deleteByCut")
event.preventDefault();
}

function handleFocus()
{
document.querySelector("#field").select();
Markup.dump("field", "initial value");

testRunner.execCommand("Cut");
Markup.dump("field", "after prevented cut");

allowCut = true;
testRunner.execCommand("Cut");
Markup.dump("field", "after allowed cut");
}
</script>
</body>
</html>
@@ -0,0 +1,26 @@
To manually test this, copy any text and try to paste into the input field. The value of the input should not change.

initial value:
| <shadow:root>
| <div>
| contenteditable="plaintext-only"
| "helloworld"

after the cut:
| <shadow:root>
| <div>
| contenteditable="plaintext-only"
| <br>

after prevented paste:
| <shadow:root>
| <div>
| contenteditable="plaintext-only"
| <br>

after allowed paste:
| <shadow:root>
| <div>
| contenteditable="plaintext-only"
| "helloworld"
| <br>
@@ -0,0 +1,47 @@
<!DOCTYPE html>
<html>

<body>
<input id="field" onfocus=handleFocus() value="helloworld" onbeforeinput=handleBeforeInput(event)></div>
<script src="../../resources/dump-as-markup.js"></script>
<script>
Markup.description(`To manually test this, copy any text and try to paste into the input field. The value of the input should not change.`);

var allowPaste = false;
(function() {
if (!window.internals || !window.eventSender || !window.testRunner)
return;

internals.settings.setInputEventsEnabled(true);
document.querySelector("input").focus();
})();

function handleBeforeInput(event)
{
if (allowPaste)
return;

if (event.inputType == "insertFromPaste")
event.preventDefault();
}

function handleFocus()
{
document.querySelector("input").select();

Markup.dump("field", "initial value");

testRunner.execCommand("Cut");
Markup.dump("field", "after the cut");

testRunner.execCommand("Paste");
Markup.dump("field", "after prevented paste");

allowPaste = true;
testRunner.execCommand("Paste");
Markup.dump("field", "after allowed paste");
}
</script>
</body>

</html>
@@ -0,0 +1,16 @@
To manually test this, ensure that typing or attempting to delete text via the Delete key does not change the DOM.

initially:
| "<#selection-caret>def"

after attempting to type (typing is allowed):
| "abc<#selection-caret>def"

after attempting to type (typing is prohibited):
| "abc<#selection-caret>def"

after attempting to delete (deleting is prohibited):
| "abc<#selection-caret>def"

after attempting to delete (deleting is allowed):
| "a<#selection-caret>ef"
@@ -0,0 +1,53 @@
<!DOCTYPE html>
<html>
<body>
<div id="editable" contenteditable onbeforeinput=handleBeforeInput(event)>def</div>
<script src="../../resources/dump-as-markup.js"></script>
<script type="text/javascript">
Markup.description(`To manually test this, ensure that typing or attempting to delete text via the Delete key does not change the DOM.`);

var allowTyping = !!window.eventSender;
(function() {
if (!window.internals || !window.eventSender || !window.testRunner)
return;

internals.settings.setInputEventsEnabled(true);
document.querySelector("#editable").focus();

Markup.dump("editable", "initially");

eventSender.keyDown("a", []);
eventSender.keyDown("b", []);
eventSender.keyDown("c", []);
Markup.dump("editable", "after attempting to type (typing is allowed)");

allowTyping = false;
eventSender.keyDown("d", []);
eventSender.keyDown("e", []);
eventSender.keyDown("f", []);
Markup.dump("editable", "after attempting to type (typing is prohibited)");

testRunner.execCommand("DeleteForward");
testRunner.execCommand("DeleteBackward");
testRunner.execCommand("DeleteForward");
Markup.dump("editable", "after attempting to delete (deleting is prohibited)");
allowTyping = true;

testRunner.execCommand("DeleteBackward");
testRunner.execCommand("DeleteForward");
testRunner.execCommand("DeleteBackward");
Markup.dump("editable", "after attempting to delete (deleting is allowed)");
})();

function handleBeforeInput(event)
{
if (allowTyping)
return;

if (event.inputType === "insertText" || event.inputType === "deleteContentBackward" || event.inputType === "deleteContentForward")
event.preventDefault();
}
</script>
</body>

</html>
@@ -0,0 +1,13 @@
To manually test this, type some into the input field below and try to undo. The value of the text field should not change after attempting to undo.

initial value:
| <shadow:root>
| <div>
| contenteditable="plaintext-only"
| "abc"

after prevented undo:
| <shadow:root>
| <div>
| contenteditable="plaintext-only"
| "abc"
@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>

<body>
<input id="field" onbeforeinput=handleBeforeInput(event)></input>
<script src="../../resources/dump-as-markup.js"></script>
<script>
Markup.description(`To manually test this, type some into the input field below and try to undo. The value of the text field should not change after attempting to undo.`);

(function() {
if (!window.internals || !window.eventSender || !window.testRunner)
return;

internals.settings.setInputEventsEnabled(true);
document.querySelector("#field").focus();

eventSender.keyDown("a", []);
eventSender.keyDown("b", []);
eventSender.keyDown("c", []);
Markup.dump("field", "initial value");

testRunner.execCommand("Undo");
Markup.dump("field", "after prevented undo");
})();

function handleBeforeInput(event)
{
if (event.inputType === "historyUndo")
event.preventDefault();
}
</script>
</body>

</html>
@@ -1201,6 +1201,11 @@ fast/events/input-events-fired-when-typing.html [ Failure ]
fast/events/before-input-events-prevent-default.html [ Failure ]
fast/events/before-input-events-prevent-default-in-textfield.html [ Failure ]
fast/events/before-input-events-different-start-end-elements.html [ Failure ]
fast/events/before-input-prevent-biu.html [ Failure ]
fast/events/before-input-prevent-cut.html [ Failure ]
fast/events/before-input-prevent-paste.html [ Failure ]
fast/events/before-input-prevent-undo.html [ Failure ]
fast/events/before-input-prevent-typing.html [ Failure ]
fast/events/key-events-in-input-button.html [ Failure ]
fast/events/keydown-1.html [ Failure ]
fast/events/keydown-leftright-keys.html [ Failure ]

0 comments on commit b8db88f

Please sign in to comment.