<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[207698] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/207698">207698</a></dd>
<dt>Author</dt> <dd>wenson_hsieh@apple.com</dd>
<dt>Date</dt> <dd>2016-10-21 16:06:05 -0700 (Fri, 21 Oct 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Support (insertFrom|deleteBy)Composition and (insert|delete)CompositionText inputTypes for InputEvents
https://bugs.webkit.org/show_bug.cgi?id=163460
&lt;rdar://problem/28784142&gt;

Reviewed by Darin Adler.

Source/WebCore:

Adds basic support for the composition inputTypes in the InputEvent spec. See w3.org/TR/input-events,
github.com/w3c/input-events/issues/41 and github.com/w3c/input-events/issues/42 for more details. While input
events are fired in the correct order with respect to each other, additional work will be required to ensure
that input events are fired in the correct order with respect to composition(start|update|end) events and
textInput events. This is held off until the expected ordering of events is officially defined in the spec.

Tests: fast/events/before-input-events-prevent-insert-composition.html
       fast/events/before-input-events-prevent-recomposition.html
       fast/events/input-events-ime-composition.html
       fast/events/input-events-ime-recomposition.html

* editing/CompositeEditCommand.cpp:
(WebCore::CompositeEditCommand::apply):
* editing/CompositeEditCommand.h:
(WebCore::CompositeEditCommand::isBeforeInputEventCancelable):

Adds a new virtual method hook for subclasses to mark their `beforeinput` events as non-cancelable (see
TypingCommand::isBeforeInputEventCancelable). By default, `beforeinput` events are cancelable.

* editing/EditAction.h:

Adds 4 new EditActions corresponding to the 4 composition-related inputTypes. These are:
EditActionTypingDeletePendingComposition    =&gt; &quot;deleteCompositionText&quot;
EditActionTypingDeleteFinalComposition      =&gt; &quot;deleteByComposition&quot;
EditActionTypingInsertPendingComposition    =&gt; &quot;insertCompositionText&quot;
EditActionTypingInsertFinalComposition      =&gt; &quot;insertFromComposition&quot;

* editing/EditCommand.cpp:
(WebCore::inputTypeNameForEditingAction):
* editing/Editor.cpp:
(WebCore::dispatchBeforeInputEvent):
(WebCore::dispatchBeforeInputEvents):
(WebCore::Editor::willApplyEditing):
(WebCore::Editor::insertTextWithoutSendingTextEvent):
(WebCore::Editor::setComposition):

In setComposition(text, mode), tweak the logic for committing a composition to always delete the selection
before inserting the final composition text. In setComposition(text, underlines, start, end), catch the case
where we're beginning to recompose an existing range in the DOM and delete the recomposed text first.

* editing/TypingCommand.cpp:
(WebCore::editActionForTypingCommand):
(WebCore::TypingCommand::TypingCommand):
(WebCore::TypingCommand::deleteSelection):

Adds a TextCompositionType parameter so that call sites (see Editor::setComposition) can indicate what state the
edited composition is in. This allows us to differentiate between deletion of finalized composition text in
preparation of recomposing a range in the DOM, and deletion of composition text that has not yet been committed
in preparation for inserting a finalized composition into the DOM.

(WebCore::TypingCommand::deleteKeyPressed):
(WebCore::TypingCommand::forwardDeleteKeyPressed):
(WebCore::TypingCommand::insertText):
(WebCore::TypingCommand::insertLineBreak):
(WebCore::TypingCommand::insertParagraphSeparatorInQuotedContent):
(WebCore::TypingCommand::insertParagraphSeparator):
(WebCore::TypingCommand::isBeforeInputEventCancelable):
(WebCore::TypingCommand::inputEventData):
(WebCore::TypingCommand::willAddTypingToOpenCommand):
* editing/TypingCommand.h:

Source/WebKit/mac:

Handle new EditAction types for inserting/deleting pending/final compositions.

* WebCoreSupport/WebEditorClient.mm:
(undoNameForEditAction):

Source/WebKit2:

Handle new EditAction types for inserting/deleting pending/final compositions.

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

LayoutTests:

Adds 4 new layout tests to verify that composition events are dispatched as expected when using IME, and that
input events of type &quot;insertFromComposition&quot; and &quot;deleteByComposition&quot; can be prevented.

Also rebaselines an existing WK1 editing test (text-input-controller.html) to account for how we now delete the
existing composition text before inserting the finalized composition text in Editor::setComposition. This means
that there are a few more delegate calls than there were before (as seen in the expected output), although the
resulting behavior is still the same.

* editing/mac/input/text-input-controller-expected.txt:
* fast/events/before-input-events-prevent-insert-composition.html: Added.
* fast/events/before-input-events-prevent-recomposition.html: Added.
* fast/events/input-events-ime-composition.html: Added.
* fast/events/input-events-ime-recomposition.html: Added.
* platform/ios-simulator/TestExpectations:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestseditingmacinputtextinputcontrollerexpectedtxt">trunk/LayoutTests/editing/mac/input/text-input-controller-expected.txt</a></li>
<li><a href="#trunkLayoutTestsplatformiossimulatorTestExpectations">trunk/LayoutTests/platform/ios-simulator/TestExpectations</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreeditingCompositeEditCommandcpp">trunk/Source/WebCore/editing/CompositeEditCommand.cpp</a></li>
<li><a href="#trunkSourceWebCoreeditingCompositeEditCommandh">trunk/Source/WebCore/editing/CompositeEditCommand.h</a></li>
<li><a href="#trunkSourceWebCoreeditingEditActionh">trunk/Source/WebCore/editing/EditAction.h</a></li>
<li><a href="#trunkSourceWebCoreeditingEditCommandcpp">trunk/Source/WebCore/editing/EditCommand.cpp</a></li>
<li><a href="#trunkSourceWebCoreeditingEditorcpp">trunk/Source/WebCore/editing/Editor.cpp</a></li>
<li><a href="#trunkSourceWebCoreeditingTypingCommandcpp">trunk/Source/WebCore/editing/TypingCommand.cpp</a></li>
<li><a href="#trunkSourceWebCoreeditingTypingCommandh">trunk/Source/WebCore/editing/TypingCommand.h</a></li>
<li><a href="#trunkSourceWebKitmacChangeLog">trunk/Source/WebKit/mac/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitmacWebCoreSupportWebEditorClientmm">trunk/Source/WebKit/mac/WebCoreSupport/WebEditorClient.mm</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebEditCommandProxycpp">trunk/Source/WebKit2/UIProcess/WebEditCommandProxy.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfasteventsbeforeinputeventspreventinsertcompositionexpectedtxt">trunk/LayoutTests/fast/events/before-input-events-prevent-insert-composition-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfasteventsbeforeinputeventspreventinsertcompositionhtml">trunk/LayoutTests/fast/events/before-input-events-prevent-insert-composition.html</a></li>
<li><a href="#trunkLayoutTestsfasteventsbeforeinputeventspreventrecompositionexpectedtxt">trunk/LayoutTests/fast/events/before-input-events-prevent-recomposition-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfasteventsbeforeinputeventspreventrecompositionhtml">trunk/LayoutTests/fast/events/before-input-events-prevent-recomposition.html</a></li>
<li><a href="#trunkLayoutTestsfasteventsinputeventsimecompositionexpectedtxt">trunk/LayoutTests/fast/events/input-events-ime-composition-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfasteventsinputeventsimecompositionhtml">trunk/LayoutTests/fast/events/input-events-ime-composition.html</a></li>
<li><a href="#trunkLayoutTestsfasteventsinputeventsimerecompositionexpectedtxt">trunk/LayoutTests/fast/events/input-events-ime-recomposition-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfasteventsinputeventsimerecompositionhtml">trunk/LayoutTests/fast/events/input-events-ime-recomposition.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (207697 => 207698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-10-21 22:38:22 UTC (rev 207697)
+++ trunk/LayoutTests/ChangeLog        2016-10-21 23:06:05 UTC (rev 207698)
</span><span class="lines">@@ -1,3 +1,26 @@
</span><ins>+2016-10-21  Wenson Hsieh  &lt;wenson_hsieh@apple.com&gt;
+
+        Support (insertFrom|deleteBy)Composition and (insert|delete)CompositionText inputTypes for InputEvents
+        https://bugs.webkit.org/show_bug.cgi?id=163460
+        &lt;rdar://problem/28784142&gt;
+
+        Reviewed by Darin Adler.
+
+        Adds 4 new layout tests to verify that composition events are dispatched as expected when using IME, and that
+        input events of type &quot;insertFromComposition&quot; and &quot;deleteByComposition&quot; can be prevented.
+
+        Also rebaselines an existing WK1 editing test (text-input-controller.html) to account for how we now delete the
+        existing composition text before inserting the finalized composition text in Editor::setComposition. This means
+        that there are a few more delegate calls than there were before (as seen in the expected output), although the
+        resulting behavior is still the same.
+
+        * editing/mac/input/text-input-controller-expected.txt:
+        * fast/events/before-input-events-prevent-insert-composition.html: Added.
+        * fast/events/before-input-events-prevent-recomposition.html: Added.
+        * fast/events/input-events-ime-composition.html: Added.
+        * fast/events/input-events-ime-recomposition.html: Added.
+        * platform/ios-simulator/TestExpectations:
+
</ins><span class="cx"> 2016-10-20  Dean Jackson  &lt;dino@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         SVG should not paint selection within a mask
</span></span></pre></div>
<a id="trunkLayoutTestseditingmacinputtextinputcontrollerexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/editing/mac/input/text-input-controller-expected.txt (207697 => 207698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/editing/mac/input/text-input-controller-expected.txt        2016-10-21 22:38:22 UTC (rev 207697)
+++ trunk/LayoutTests/editing/mac/input/text-input-controller-expected.txt        2016-10-21 23:06:05 UTC (rev 207698)
</span><span class="lines">@@ -22,11 +22,14 @@
</span><span class="cx"> EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of DIV &gt; BODY &gt; HTML &gt; #document to 0 of DIV &gt; BODY &gt; HTML &gt; #document toDOMRange:range from 0 of #text &gt; DIV &gt; BODY &gt; HTML &gt; #document to 7 of #text &gt; DIV &gt; BODY &gt; HTML &gt; #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
</span><span class="cx"> EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
</span><span class="cx"> EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
</span><del>-EDITING DELEGATE: shouldInsertText:Success replacingDOMRange:range from 0 of #text &gt; DIV &gt; BODY &gt; HTML &gt; #document to 7 of #text &gt; DIV &gt; BODY &gt; HTML &gt; #document givenAction:WebViewInsertActionTyped
</del><span class="cx"> EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
</span><del>-EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of DIV &gt; BODY &gt; HTML &gt; #document to 0 of DIV &gt; BODY &gt; HTML &gt; #document toDOMRange:range from 7 of #text &gt; DIV &gt; BODY &gt; HTML &gt; #document to 7 of #text &gt; DIV &gt; BODY &gt; HTML &gt; #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
</del><ins>+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of DIV &gt; BODY &gt; HTML &gt; #document to 0 of DIV &gt; BODY &gt; HTML &gt; #document toDOMRange:range from 0 of DIV &gt; BODY &gt; HTML &gt; #document to 0 of DIV &gt; BODY &gt; HTML &gt; #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
</ins><span class="cx"> EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
</span><span class="cx"> EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
</span><ins>+EDITING DELEGATE: shouldInsertText:Success replacingDOMRange:range from 0 of DIV &gt; BODY &gt; HTML &gt; #document to 0 of DIV &gt; BODY &gt; HTML &gt; #document givenAction:WebViewInsertActionTyped
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 7 of #text &gt; DIV &gt; BODY &gt; HTML &gt; #document to 7 of #text &gt; DIV &gt; BODY &gt; HTML &gt; #document toDOMRange:range from 7 of #text &gt; DIV &gt; BODY &gt; HTML &gt; #document to 7 of #text &gt; DIV &gt; BODY &gt; HTML &gt; #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
</ins><span class="cx"> EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 7 of #text &gt; DIV &gt; BODY &gt; HTML &gt; #document to 7 of #text &gt; DIV &gt; BODY &gt; HTML &gt; #document toDOMRange:range from 0 of #text &gt; DIV &gt; BODY &gt; HTML &gt; #document to 7 of #text &gt; DIV &gt; BODY &gt; HTML &gt; #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
</span><span class="cx"> EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
</span><span class="cx"> Success
</span></span></pre></div>
<a id="trunkLayoutTestsfasteventsbeforeinputeventspreventinsertcompositionexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/events/before-input-events-prevent-insert-composition-expected.txt (0 => 207698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/events/before-input-events-prevent-insert-composition-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/events/before-input-events-prevent-insert-composition-expected.txt        2016-10-21 23:06:05 UTC (rev 207698)
</span><span class="lines">@@ -0,0 +1,13 @@
</span><ins>+To manually test this, try to insert text using IME. No text should be committed to the input.
+
+after trying to commit a typed composition:
+|   &lt;shadow:root&gt;
+|     &lt;div&gt;
+|       contenteditable=&quot;plaintext-only&quot;
+|       &lt;br&gt;
+
+after trying to commit a selected composition:
+|   &lt;shadow:root&gt;
+|     &lt;div&gt;
+|       contenteditable=&quot;plaintext-only&quot;
+|       &lt;br&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsfasteventsbeforeinputeventspreventinsertcompositionhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/events/before-input-events-prevent-insert-composition.html (0 => 207698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/events/before-input-events-prevent-insert-composition.html                                (rev 0)
+++ trunk/LayoutTests/fast/events/before-input-events-prevent-insert-composition.html        2016-10-21 23:06:05 UTC (rev 207698)
</span><span class="lines">@@ -0,0 +1,34 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;body&gt;
+    &lt;input id=&quot;editable&quot; contenteditable onbeforeinput=preventInsertFromComposition(event)&gt;&lt;/input&gt;
+    &lt;script src=&quot;../../resources/dump-as-markup.js&quot;&gt;&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;
+        Markup.description(&quot;To manually test this, try to insert text using IME. No text should be committed to the input.&quot;);
+        if (window.internals)
+            internals.settings.setInputEventsEnabled(true);
+
+        editable.focus();
+
+        if (window.textInputController) {
+            textInputController.setMarkedText(&quot;a&quot;, 1, 0);
+            textInputController.setMarkedText(&quot;ab&quot;, 2, 0);
+            textInputController.setMarkedText(&quot;abc&quot;, 3, 0);
+            textInputController.insertText(&quot;abc&quot;);
+            Markup.dump(&quot;editable&quot;, &quot;after trying to commit a typed composition&quot;);
+            textInputController.setMarkedText(&quot;a&quot;, 1, 0);
+            textInputController.setMarkedText(&quot;ab&quot;, 2, 0);
+            textInputController.setMarkedText(&quot;cde&quot;, 0, 3);
+            textInputController.setMarkedText(&quot;fg&quot;, 0, 2);
+            textInputController.insertText(&quot;fg&quot;);
+            Markup.dump(&quot;editable&quot;, &quot;after trying to commit a selected composition&quot;);
+        }
+
+        function preventInsertFromComposition(event)
+        {
+            if (event.inputType == &quot;insertFromComposition&quot;)
+                event.preventDefault();
+        }
+    &lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkLayoutTestsfasteventsbeforeinputeventspreventrecompositionexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/events/before-input-events-prevent-recomposition-expected.txt (0 => 207698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/events/before-input-events-prevent-recomposition-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/events/before-input-events-prevent-recomposition-expected.txt        2016-10-21 23:06:05 UTC (rev 207698)
</span><span class="lines">@@ -0,0 +1,25 @@
</span><ins>+To manually test this, try to recompose text. The original text should not be modified.
+
+initial composition text:
+|   &lt;shadow:root&gt;
+|     &lt;div&gt;
+|       contenteditable=&quot;plaintext-only&quot;
+|       &quot;foo&quot;
+
+after preventing recomposition:
+|   &lt;shadow:root&gt;
+|     &lt;div&gt;
+|       contenteditable=&quot;plaintext-only&quot;
+|       &quot;foofoo&quot;
+
+after selecting a new composition string:
+|   &lt;shadow:root&gt;
+|     &lt;div&gt;
+|       contenteditable=&quot;plaintext-only&quot;
+|       &quot;foogarply&quot;
+
+after committing the new composition string:
+|   &lt;shadow:root&gt;
+|     &lt;div&gt;
+|       contenteditable=&quot;plaintext-only&quot;
+|       &quot;foogarply&quot;
</ins></span></pre></div>
<a id="trunkLayoutTestsfasteventsbeforeinputeventspreventrecompositionhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/events/before-input-events-prevent-recomposition.html (0 => 207698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/events/before-input-events-prevent-recomposition.html                                (rev 0)
+++ trunk/LayoutTests/fast/events/before-input-events-prevent-recomposition.html        2016-10-21 23:06:05 UTC (rev 207698)
</span><span class="lines">@@ -0,0 +1,30 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;body&gt;
+    &lt;input id=&quot;editable&quot; contenteditable onbeforeinput=preventDeleteByComposition(event) value=&quot;foo&quot;&gt;&lt;/input&gt;
+    &lt;script src=&quot;../../resources/dump-as-markup.js&quot;&gt;&lt;/script&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;
+        Markup.description(&quot;To manually test this, try to recompose text. The original text should not be modified.&quot;);
+        if (window.internals)
+            internals.settings.setInputEventsEnabled(true);
+
+        editable.focus();
+
+        if (window.textInputController) {
+            Markup.dump(&quot;editable&quot;, &quot;initial composition text&quot;);
+            textInputController.setMarkedText(&quot;foo&quot;, 0, 3);
+            Markup.dump(&quot;editable&quot;, &quot;after preventing recomposition&quot;);
+            textInputController.setMarkedText(&quot;garply&quot;, 0, 6);
+            Markup.dump(&quot;editable&quot;, &quot;after selecting a new composition string&quot;);
+            textInputController.insertText(&quot;garply&quot;);
+            Markup.dump(&quot;editable&quot;, &quot;after committing the new composition string&quot;);
+        }
+
+        function preventDeleteByComposition(event)
+        {
+            if (event.inputType == &quot;deleteByComposition&quot;)
+                event.preventDefault();
+        }
+    &lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkLayoutTestsfasteventsinputeventsimecompositionexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/events/input-events-ime-composition-expected.txt (0 => 207698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/events/input-events-ime-composition-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/events/input-events-ime-composition-expected.txt        2016-10-21 23:06:05 UTC (rev 207698)
</span><span class="lines">@@ -0,0 +1,55 @@
</span><ins>+To manually test this, insert text via IME and observe the resulting debug messages.
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+* * * First case: typing a new composition * * *
+beforeinput(inputType = 'insertCompositionText', data = 'a', cancelable = false)
+input(inputType = 'insertCompositionText', data = 'a', cancelable = false)
+beforeinput(inputType = 'insertCompositionText', data = 'ab', cancelable = false)
+input(inputType = 'insertCompositionText', data = 'ab', cancelable = false)
+beforeinput(inputType = 'insertCompositionText', data = 'abc', cancelable = false)
+input(inputType = 'insertCompositionText', data = 'abc', cancelable = false)
+beforeinput(inputType = 'deleteCompositionText', data = 'null', cancelable = false)
+input(inputType = 'deleteCompositionText', data = 'null', cancelable = false)
+beforeinput(inputType = 'insertFromComposition', data = 'abc', cancelable = true)
+input(inputType = 'insertFromComposition', data = 'abc', cancelable = false)
+* * * Second case: canceling a new composition * * *
+beforeinput(inputType = 'insertCompositionText', data = 'a', cancelable = false)
+input(inputType = 'insertCompositionText', data = 'a', cancelable = false)
+beforeinput(inputType = 'insertCompositionText', data = 'ab', cancelable = false)
+input(inputType = 'insertCompositionText', data = 'ab', cancelable = false)
+beforeinput(inputType = 'insertCompositionText', data = ' ', cancelable = false)
+input(inputType = 'insertCompositionText', data = ' ', cancelable = false)
+beforeinput(inputType = 'deleteCompositionText', data = 'null', cancelable = false)
+input(inputType = 'deleteCompositionText', data = 'null', cancelable = false)
+* * * Third case: replacing a composition * * *
+beforeinput(inputType = 'insertCompositionText', data = 'a', cancelable = false)
+input(inputType = 'insertCompositionText', data = 'a', cancelable = false)
+beforeinput(inputType = 'insertCompositionText', data = 'ab', cancelable = false)
+input(inputType = 'insertCompositionText', data = 'ab', cancelable = false)
+beforeinput(inputType = 'insertCompositionText', data = 'cde', cancelable = false)
+input(inputType = 'insertCompositionText', data = 'cde', cancelable = false)
+beforeinput(inputType = 'insertCompositionText', data = 'fg', cancelable = false)
+input(inputType = 'insertCompositionText', data = 'fg', cancelable = false)
+beforeinput(inputType = 'deleteCompositionText', data = 'null', cancelable = false)
+input(inputType = 'deleteCompositionText', data = 'null', cancelable = false)
+beforeinput(inputType = 'insertFromComposition', data = 'fg', cancelable = true)
+input(inputType = 'insertFromComposition', data = 'fg', cancelable = false)
+* * * Fourth case: partially committing a composition * * *
+beforeinput(inputType = 'insertCompositionText', data = 'a', cancelable = false)
+input(inputType = 'insertCompositionText', data = 'a', cancelable = false)
+beforeinput(inputType = 'insertCompositionText', data = 'aa', cancelable = false)
+input(inputType = 'insertCompositionText', data = 'aa', cancelable = false)
+beforeinput(inputType = 'insertCompositionText', data = 'aaa', cancelable = false)
+input(inputType = 'insertCompositionText', data = 'aaa', cancelable = false)
+beforeinput(inputType = 'deleteCompositionText', data = 'null', cancelable = false)
+input(inputType = 'deleteCompositionText', data = 'null', cancelable = false)
+beforeinput(inputType = 'insertFromComposition', data = 'a', cancelable = true)
+input(inputType = 'insertFromComposition', data = 'a', cancelable = false)
+beforeinput(inputType = 'insertCompositionText', data = 'aa', cancelable = false)
+input(inputType = 'insertCompositionText', data = 'aa', cancelable = false)
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfasteventsinputeventsimecompositionhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/events/input-events-ime-composition.html (0 => 207698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/events/input-events-ime-composition.html                                (rev 0)
+++ trunk/LayoutTests/fast/events/input-events-ime-composition.html        2016-10-21 23:06:05 UTC (rev 207698)
</span><span class="lines">@@ -0,0 +1,48 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+    &lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+    &lt;input id=&quot;editable&quot; contenteditable onbeforeinput=logInputEvent(event) oninput=logInputEvent(event)&gt;&lt;/input&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;
+        description(&quot;To manually test this, insert text via IME and observe the resulting debug messages.&quot;);
+        if (window.internals)
+            internals.settings.setInputEventsEnabled(true);
+
+        editable.focus();
+
+        if (window.testRunner &amp;&amp; window.textInputController) {
+            testRunner.dumpAsText();
+            debug(&quot;* * * First case: typing a new composition * * *&quot;);
+            textInputController.setMarkedText(&quot;a&quot;, 1, 0);
+            textInputController.setMarkedText(&quot;ab&quot;, 2, 0);
+            textInputController.setMarkedText(&quot;abc&quot;, 3, 0);
+            textInputController.insertText(&quot;abc&quot;);
+            debug(&quot;* * * Second case: canceling a new composition * * *&quot;);
+            textInputController.setMarkedText(&quot;a&quot;, 1, 0);
+            textInputController.setMarkedText(&quot;ab&quot;, 2, 0);
+            textInputController.setMarkedText(&quot; &quot;, 0, 1);
+            textInputController.setMarkedText(&quot;&quot;, 0, 0);
+            debug(&quot;* * * Third case: replacing a composition * * *&quot;);
+            textInputController.setMarkedText(&quot;a&quot;, 1, 0);
+            textInputController.setMarkedText(&quot;ab&quot;, 2, 0);
+            textInputController.setMarkedText(&quot;cde&quot;, 0, 3);
+            textInputController.setMarkedText(&quot;fg&quot;, 0, 2);
+            textInputController.insertText(&quot;fg&quot;);
+            debug(&quot;* * * Fourth case: partially committing a composition * * *&quot;);
+            textInputController.setMarkedText(&quot;a&quot;, 1, 0);
+            textInputController.setMarkedText(&quot;aa&quot;, 2, 0);
+            textInputController.setMarkedText(&quot;aaa&quot;, 3, 0);
+            textInputController.insertText(&quot;a&quot;);
+            textInputController.setMarkedText(&quot;aa&quot;, 2, 0);
+        }
+
+        function logInputEvent(event)
+        {
+            debug(`${event.type}(inputType = '${event.inputType}', data = '${event.data}', cancelable = ${event.cancelable})`);
+        }
+    &lt;/script&gt;
+    &lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkLayoutTestsfasteventsinputeventsimerecompositionexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/events/input-events-ime-recomposition-expected.txt (0 => 207698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/events/input-events-ime-recomposition-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/events/input-events-ime-recomposition-expected.txt        2016-10-21 23:06:05 UTC (rev 207698)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+To manually test this, recompose existing text via IME and observe the resulting debug messages.
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+beforeinput(inputType = 'deleteByComposition', data = 'null', cancelable = true)
+input(inputType = 'deleteByComposition', data = 'null', cancelable = false)
+beforeinput(inputType = 'insertCompositionText', data = 'abc', cancelable = false)
+input(inputType = 'insertCompositionText', data = 'abc', cancelable = false)
+beforeinput(inputType = 'insertCompositionText', data = 'def', cancelable = false)
+input(inputType = 'insertCompositionText', data = 'def', cancelable = false)
+beforeinput(inputType = 'insertCompositionText', data = 'ghi', cancelable = false)
+input(inputType = 'insertCompositionText', data = 'ghi', cancelable = false)
+beforeinput(inputType = 'deleteCompositionText', data = 'null', cancelable = false)
+input(inputType = 'deleteCompositionText', data = 'null', cancelable = false)
+beforeinput(inputType = 'insertFromComposition', data = 'ghi', cancelable = true)
+input(inputType = 'insertFromComposition', data = 'ghi', cancelable = false)
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfasteventsinputeventsimerecompositionhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/events/input-events-ime-recomposition.html (0 => 207698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/events/input-events-ime-recomposition.html                                (rev 0)
+++ trunk/LayoutTests/fast/events/input-events-ime-recomposition.html        2016-10-21 23:06:05 UTC (rev 207698)
</span><span class="lines">@@ -0,0 +1,30 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+    &lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+    &lt;input id=&quot;editable&quot; contenteditable value=&quot;abc&quot; onbeforeinput=logInputEvent(event) oninput=logInputEvent(event)&gt;&lt;/input&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;
+        description(&quot;To manually test this, recompose existing text via IME and observe the resulting debug messages.&quot;);
+        if (window.internals)
+            internals.settings.setInputEventsEnabled(true);
+
+        editable.focus();
+
+        if (window.testRunner &amp;&amp; window.textInputController) {
+            testRunner.dumpAsText();
+            textInputController.setMarkedText(&quot;abc&quot;, 0, 3);
+            textInputController.setMarkedText(&quot;def&quot;, 0, 3);
+            textInputController.setMarkedText(&quot;ghi&quot;, 0, 3);
+            textInputController.insertText(&quot;ghi&quot;);
+        }
+
+        function logInputEvent(event)
+        {
+            debug(`${event.type}(inputType = '${event.inputType}', data = '${event.data}', cancelable = ${event.cancelable})`);
+        }
+    &lt;/script&gt;
+    &lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkLayoutTestsplatformiossimulatorTestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/ios-simulator/TestExpectations (207697 => 207698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/ios-simulator/TestExpectations        2016-10-21 22:38:22 UTC (rev 207697)
+++ trunk/LayoutTests/platform/ios-simulator/TestExpectations        2016-10-21 23:06:05 UTC (rev 207698)
</span><span class="lines">@@ -1209,6 +1209,8 @@
</span><span class="cx"> fast/events/input-events-paste-data.html [ Failure ]
</span><span class="cx"> fast/events/input-events-typing-data.html [ Failure ]
</span><span class="cx"> fast/events/input-events-forecolor-data.html [ Failure ]
</span><ins>+fast/events/input-events-ime-recomposition.html [ Failure ]
+fast/events/input-events-ime-composition.html [ Failure ]
</ins><span class="cx"> fast/events/before-input-events-prevent-default.html [ Failure ]
</span><span class="cx"> fast/events/before-input-events-prevent-default-in-textfield.html [ Failure ]
</span><span class="cx"> fast/events/before-input-events-different-start-end-elements.html [ Failure ]
</span><span class="lines">@@ -1220,6 +1222,8 @@
</span><span class="cx"> fast/events/before-input-delete-text-target-ranges.html [ Failure ]
</span><span class="cx"> fast/events/before-input-replace-text-target-ranges.html [ Failure ]
</span><span class="cx"> fast/events/before-input-delete-empty-list-target-ranges.html [ Failure ]
</span><ins>+fast/events/before-input-events-prevent-recomposition.html [ Failure ]
+fast/events/before-input-events-prevent-insert-composition.html [ Failure ]
</ins><span class="cx"> fast/events/key-events-in-input-button.html [ Failure ]
</span><span class="cx"> fast/events/keydown-1.html [ Failure ]
</span><span class="cx"> fast/events/keydown-leftright-keys.html [ Failure ]
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (207697 => 207698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-10-21 22:38:22 UTC (rev 207697)
+++ trunk/Source/WebCore/ChangeLog        2016-10-21 23:06:05 UTC (rev 207698)
</span><span class="lines">@@ -1,3 +1,72 @@
</span><ins>+2016-10-21  Wenson Hsieh  &lt;wenson_hsieh@apple.com&gt;
+
+        Support (insertFrom|deleteBy)Composition and (insert|delete)CompositionText inputTypes for InputEvents
+        https://bugs.webkit.org/show_bug.cgi?id=163460
+        &lt;rdar://problem/28784142&gt;
+
+        Reviewed by Darin Adler.
+
+        Adds basic support for the composition inputTypes in the InputEvent spec. See w3.org/TR/input-events,
+        github.com/w3c/input-events/issues/41 and github.com/w3c/input-events/issues/42 for more details. While input
+        events are fired in the correct order with respect to each other, additional work will be required to ensure
+        that input events are fired in the correct order with respect to composition(start|update|end) events and
+        textInput events. This is held off until the expected ordering of events is officially defined in the spec.
+
+        Tests: fast/events/before-input-events-prevent-insert-composition.html
+               fast/events/before-input-events-prevent-recomposition.html
+               fast/events/input-events-ime-composition.html
+               fast/events/input-events-ime-recomposition.html
+
+        * editing/CompositeEditCommand.cpp:
+        (WebCore::CompositeEditCommand::apply):
+        * editing/CompositeEditCommand.h:
+        (WebCore::CompositeEditCommand::isBeforeInputEventCancelable):
+
+        Adds a new virtual method hook for subclasses to mark their `beforeinput` events as non-cancelable (see
+        TypingCommand::isBeforeInputEventCancelable). By default, `beforeinput` events are cancelable.
+
+        * editing/EditAction.h:
+
+        Adds 4 new EditActions corresponding to the 4 composition-related inputTypes. These are:
+        EditActionTypingDeletePendingComposition    =&gt; &quot;deleteCompositionText&quot;
+        EditActionTypingDeleteFinalComposition      =&gt; &quot;deleteByComposition&quot;
+        EditActionTypingInsertPendingComposition    =&gt; &quot;insertCompositionText&quot;
+        EditActionTypingInsertFinalComposition      =&gt; &quot;insertFromComposition&quot;
+
+        * editing/EditCommand.cpp:
+        (WebCore::inputTypeNameForEditingAction):
+        * editing/Editor.cpp:
+        (WebCore::dispatchBeforeInputEvent):
+        (WebCore::dispatchBeforeInputEvents):
+        (WebCore::Editor::willApplyEditing):
+        (WebCore::Editor::insertTextWithoutSendingTextEvent):
+        (WebCore::Editor::setComposition):
+
+        In setComposition(text, mode), tweak the logic for committing a composition to always delete the selection
+        before inserting the final composition text. In setComposition(text, underlines, start, end), catch the case
+        where we're beginning to recompose an existing range in the DOM and delete the recomposed text first.
+
+        * editing/TypingCommand.cpp:
+        (WebCore::editActionForTypingCommand):
+        (WebCore::TypingCommand::TypingCommand):
+        (WebCore::TypingCommand::deleteSelection):
+
+        Adds a TextCompositionType parameter so that call sites (see Editor::setComposition) can indicate what state the
+        edited composition is in. This allows us to differentiate between deletion of finalized composition text in
+        preparation of recomposing a range in the DOM, and deletion of composition text that has not yet been committed
+        in preparation for inserting a finalized composition into the DOM.
+
+        (WebCore::TypingCommand::deleteKeyPressed):
+        (WebCore::TypingCommand::forwardDeleteKeyPressed):
+        (WebCore::TypingCommand::insertText):
+        (WebCore::TypingCommand::insertLineBreak):
+        (WebCore::TypingCommand::insertParagraphSeparatorInQuotedContent):
+        (WebCore::TypingCommand::insertParagraphSeparator):
+        (WebCore::TypingCommand::isBeforeInputEventCancelable):
+        (WebCore::TypingCommand::inputEventData):
+        (WebCore::TypingCommand::willAddTypingToOpenCommand):
+        * editing/TypingCommand.h:
+
</ins><span class="cx"> 2016-10-21  Dave Hyatt  &lt;hyatt@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [CSS Parser] Make sure shadow user agent sheets parse in UASheetMode
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingCompositeEditCommandcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/CompositeEditCommand.cpp (207697 => 207698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/CompositeEditCommand.cpp        2016-10-21 22:38:22 UTC (rev 207697)
+++ trunk/Source/WebCore/editing/CompositeEditCommand.cpp        2016-10-21 23:06:05 UTC (rev 207698)
</span><span class="lines">@@ -334,9 +334,13 @@
</span><span class="cx">         case EditActionTypingDeleteWordForward:
</span><span class="cx">         case EditActionTypingDeleteLineBackward:
</span><span class="cx">         case EditActionTypingDeleteLineForward:
</span><ins>+        case EditActionTypingDeletePendingComposition:
+        case EditActionTypingDeleteFinalComposition:
</ins><span class="cx">         case EditActionTypingInsertText:
</span><span class="cx">         case EditActionTypingInsertLineBreak:
</span><span class="cx">         case EditActionTypingInsertParagraph:
</span><ins>+        case EditActionTypingInsertPendingComposition:
+        case EditActionTypingInsertFinalComposition:
</ins><span class="cx">         case EditActionPaste:
</span><span class="cx">         case EditActionDrag:
</span><span class="cx">         case EditActionSetWritingDirection:
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingCompositeEditCommandh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/CompositeEditCommand.h (207697 => 207698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/CompositeEditCommand.h        2016-10-21 22:38:22 UTC (rev 207697)
+++ trunk/Source/WebCore/editing/CompositeEditCommand.h        2016-10-21 23:06:05 UTC (rev 207698)
</span><span class="lines">@@ -116,6 +116,7 @@
</span><span class="cx">     virtual bool shouldStopCaretBlinking() const { return false; }
</span><span class="cx">     virtual String inputEventTypeName() const;
</span><span class="cx">     virtual String inputEventData() const { return { }; }
</span><ins>+    virtual bool isBeforeInputEventCancelable() const { return true; }
</ins><span class="cx">     Vector&lt;RefPtr&lt;StaticRange&gt;&gt; targetRangesForBindings() const;
</span><span class="cx"> 
</span><span class="cx"> protected:
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingEditActionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/EditAction.h (207697 => 207698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/EditAction.h        2016-10-21 22:38:22 UTC (rev 207697)
+++ trunk/Source/WebCore/editing/EditAction.h        2016-10-21 23:06:05 UTC (rev 207698)
</span><span class="lines">@@ -71,9 +71,13 @@
</span><span class="cx">         EditActionTypingDeleteWordForward,
</span><span class="cx">         EditActionTypingDeleteLineBackward,
</span><span class="cx">         EditActionTypingDeleteLineForward,
</span><ins>+        EditActionTypingDeletePendingComposition,
+        EditActionTypingDeleteFinalComposition,
</ins><span class="cx">         EditActionTypingInsertText,
</span><span class="cx">         EditActionTypingInsertLineBreak,
</span><span class="cx">         EditActionTypingInsertParagraph,
</span><ins>+        EditActionTypingInsertPendingComposition,
+        EditActionTypingInsertFinalComposition,
</ins><span class="cx">         EditActionCreateLink,
</span><span class="cx">         EditActionUnlink,
</span><span class="cx">         EditActionFormatBlock,
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingEditCommandcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/EditCommand.cpp (207697 => 207698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/EditCommand.cpp        2016-10-21 22:38:22 UTC (rev 207697)
+++ trunk/Source/WebCore/editing/EditCommand.cpp        2016-10-21 23:06:05 UTC (rev 207698)
</span><span class="lines">@@ -83,6 +83,10 @@
</span><span class="cx">         return ASCIILiteral(&quot;deleteHardLineBackward&quot;);
</span><span class="cx">     case EditActionTypingDeleteLineForward:
</span><span class="cx">         return ASCIILiteral(&quot;deleteHardLineForward&quot;);
</span><ins>+    case EditActionTypingDeletePendingComposition:
+        return ASCIILiteral(&quot;deleteCompositionText&quot;);
+    case EditActionTypingDeleteFinalComposition:
+        return ASCIILiteral(&quot;deleteByComposition&quot;);
</ins><span class="cx">     case EditActionInsert:
</span><span class="cx">     case EditActionTypingInsertText:
</span><span class="cx">         return ASCIILiteral(&quot;insertText&quot;);
</span><span class="lines">@@ -96,6 +100,10 @@
</span><span class="cx">         return ASCIILiteral(&quot;insertOrderedList&quot;);
</span><span class="cx">     case EditActionInsertUnorderedList:
</span><span class="cx">         return ASCIILiteral(&quot;insertUnorderedList&quot;);
</span><ins>+    case EditActionTypingInsertPendingComposition:
+        return ASCIILiteral(&quot;insertCompositionText&quot;);
+    case EditActionTypingInsertFinalComposition:
+        return ASCIILiteral(&quot;insertFromComposition&quot;);
</ins><span class="cx">     case EditActionIndent:
</span><span class="cx">         return ASCIILiteral(&quot;formatIndent&quot;);
</span><span class="cx">     case EditActionOutdent:
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingEditorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/Editor.cpp (207697 => 207698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/Editor.cpp        2016-10-21 22:38:22 UTC (rev 207697)
+++ trunk/Source/WebCore/editing/Editor.cpp        2016-10-21 23:06:05 UTC (rev 207698)
</span><span class="lines">@@ -111,13 +111,13 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-static bool dispatchBeforeInputEvent(Element&amp; element, const AtomicString&amp; inputType, const String&amp; data = { }, const Vector&lt;RefPtr&lt;StaticRange&gt;&gt;&amp; targetRanges = { })
</del><ins>+static bool dispatchBeforeInputEvent(Element&amp; element, const AtomicString&amp; inputType, const String&amp; data = { }, const Vector&lt;RefPtr&lt;StaticRange&gt;&gt;&amp; targetRanges = { }, bool cancelable = true)
</ins><span class="cx"> {
</span><span class="cx">     auto* settings = element.document().settings();
</span><span class="cx">     if (!settings || !settings-&gt;inputEventsEnabled())
</span><span class="cx">         return true;
</span><span class="cx"> 
</span><del>-    return element.dispatchEvent(InputEvent::create(eventNames().beforeinputEvent, inputType, true, true, element.document().defaultView(), data, targetRanges, 0));
</del><ins>+    return element.dispatchEvent(InputEvent::create(eventNames().beforeinputEvent, inputType, true, cancelable, element.document().defaultView(), data, targetRanges, 0));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static void dispatchInputEvent(Element&amp; element, const AtomicString&amp; inputType, const String&amp; data = { }, const Vector&lt;RefPtr&lt;StaticRange&gt;&gt;&amp; targetRanges = { })
</span><span class="lines">@@ -124,7 +124,7 @@
</span><span class="cx"> {
</span><span class="cx">     auto* settings = element.document().settings();
</span><span class="cx">     if (settings &amp;&amp; settings-&gt;inputEventsEnabled())
</span><del>-        element.dispatchScopedEvent(InputEvent::create(eventNames().inputEvent, inputType, true, false, element.document().defaultView(), data, targetRanges, 0));
</del><ins>+        element.dispatchEvent(InputEvent::create(eventNames().inputEvent, inputType, true, false, element.document().defaultView(), data, targetRanges, 0));
</ins><span class="cx">     else
</span><span class="cx">         element.dispatchInputEvent();
</span><span class="cx"> }
</span><span class="lines">@@ -1063,13 +1063,13 @@
</span><span class="cx">         endingTextControl-&gt;didEditInnerTextValue();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static bool dispatchBeforeInputEvents(RefPtr&lt;Element&gt; startRoot, RefPtr&lt;Element&gt; endRoot, const AtomicString&amp; inputTypeName, const String&amp; data = { }, const Vector&lt;RefPtr&lt;StaticRange&gt;&gt;&amp; targetRanges = { })
</del><ins>+static bool dispatchBeforeInputEvents(RefPtr&lt;Element&gt; startRoot, RefPtr&lt;Element&gt; endRoot, const AtomicString&amp; inputTypeName, const String&amp; data = { }, const Vector&lt;RefPtr&lt;StaticRange&gt;&gt;&amp; targetRanges = { }, bool cancelable = true)
</ins><span class="cx"> {
</span><span class="cx">     bool continueWithDefaultBehavior = true;
</span><span class="cx">     if (startRoot)
</span><del>-        continueWithDefaultBehavior &amp;= dispatchBeforeInputEvent(*startRoot, inputTypeName, data, targetRanges);
</del><ins>+        continueWithDefaultBehavior &amp;= dispatchBeforeInputEvent(*startRoot, inputTypeName, data, targetRanges, cancelable);
</ins><span class="cx">     if (endRoot &amp;&amp; endRoot != startRoot)
</span><del>-        continueWithDefaultBehavior &amp;= dispatchBeforeInputEvent(*endRoot, inputTypeName, data, targetRanges);
</del><ins>+        continueWithDefaultBehavior &amp;= dispatchBeforeInputEvent(*endRoot, inputTypeName, data, targetRanges, cancelable);
</ins><span class="cx">     return continueWithDefaultBehavior;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -1087,7 +1087,7 @@
</span><span class="cx">     if (!composition)
</span><span class="cx">         return true;
</span><span class="cx"> 
</span><del>-    return dispatchBeforeInputEvents(composition-&gt;startingRootEditableElement(), composition-&gt;endingRootEditableElement(), command.inputEventTypeName(), command.inputEventData(), targetRanges);
</del><ins>+    return dispatchBeforeInputEvents(composition-&gt;startingRootEditableElement(), composition-&gt;endingRootEditableElement(), command.inputEventTypeName(), command.inputEventData(), targetRanges, command.isBeforeInputEventCancelable());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Editor::appliedEditing(PassRefPtr&lt;CompositeEditCommand&gt; cmd)
</span><span class="lines">@@ -1261,7 +1261,7 @@
</span><span class="cx">                     options |= TypingCommand::SelectInsertedText;
</span><span class="cx">                 if (autocorrectionWasApplied)
</span><span class="cx">                     options |= TypingCommand::RetainAutocorrectionIndicator;
</span><del>-                TypingCommand::insertText(document, text, selection, options, triggeringEvent &amp;&amp; triggeringEvent-&gt;isComposition() ? TypingCommand::TextCompositionConfirm : TypingCommand::TextCompositionNone);
</del><ins>+                TypingCommand::insertText(document, text, selection, options, triggeringEvent &amp;&amp; triggeringEvent-&gt;isComposition() ? TypingCommand::TextCompositionFinal : TypingCommand::TextCompositionNone);
</ins><span class="cx">             }
</span><span class="cx"> 
</span><span class="cx">             // Reveal the current selection
</span><span class="lines">@@ -1832,10 +1832,11 @@
</span><span class="cx">         target-&gt;dispatchEvent(event);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // If text is empty, then delete the old composition here.  If text is non-empty, InsertTextCommand::input
-    // will delete the old composition with an optimized replace operation.
-    if (text.isEmpty() &amp;&amp; mode != CancelComposition)
-        TypingCommand::deleteSelection(document(), 0);
</del><ins>+    // Always delete the current composition before inserting the finalized composition text if we're confirming our composition.
+    // Our default behavior (if the beforeinput event is not prevented) is to insert the finalized composition text back in.
+    // We pass TypingCommand::TextCompositionPending here to indicate that we are deleting the pending composition.
+    if (mode != CancelComposition)
+        TypingCommand::deleteSelection(document(), 0, TypingCommand::TextCompositionPending);
</ins><span class="cx"> 
</span><span class="cx">     m_compositionNode = nullptr;
</span><span class="cx">     m_customCompositionUnderlines.clear();
</span><span class="lines">@@ -1868,6 +1869,18 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    String originalText = selectedText();
+    bool isStartingToRecomposeExistingRange = !text.isEmpty() &amp;&amp; selectionStart &lt; selectionEnd &amp;&amp; !hasComposition();
+    if (isStartingToRecomposeExistingRange) {
+        // We pass TypingCommand::TextCompositionFinal here to indicate that we are removing composition text that has been finalized.
+        TypingCommand::deleteSelection(document(), 0, TypingCommand::TextCompositionFinal);
+        const VisibleSelection&amp; currentSelection = m_frame.selection().selection();
+        if (currentSelection.isRange()) {
+            // If deletion was prevented, then we need to collapse the selection to the end so that the original text will not be recomposed.
+            m_frame.selection().setSelection({ currentSelection.end(), currentSelection.end() });
+        }
+    }
+
</ins><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">     client()-&gt;startDelayingAndCoalescingContentChangeNotifications();
</span><span class="cx"> #endif
</span><span class="lines">@@ -1894,7 +1907,7 @@
</span><span class="cx">             // We should send a compositionstart event only when the given text is not empty because this
</span><span class="cx">             // function doesn't create a composition node when the text is empty.
</span><span class="cx">             if (!text.isEmpty()) {
</span><del>-                target-&gt;dispatchEvent(CompositionEvent::create(eventNames().compositionstartEvent, document().domWindow(), selectedText()));
</del><ins>+                target-&gt;dispatchEvent(CompositionEvent::create(eventNames().compositionstartEvent, document().domWindow(), originalText));
</ins><span class="cx">                 event = CompositionEvent::create(eventNames().compositionupdateEvent, document().domWindow(), text);
</span><span class="cx">             }
</span><span class="cx">         } else {
</span><span class="lines">@@ -1910,13 +1923,13 @@
</span><span class="cx">     // If text is empty, then delete the old composition here.  If text is non-empty, InsertTextCommand::input
</span><span class="cx">     // will delete the old composition with an optimized replace operation.
</span><span class="cx">     if (text.isEmpty())
</span><del>-        TypingCommand::deleteSelection(document(), TypingCommand::PreventSpellChecking);
</del><ins>+        TypingCommand::deleteSelection(document(), TypingCommand::PreventSpellChecking, TypingCommand::TextCompositionPending);
</ins><span class="cx"> 
</span><span class="cx">     m_compositionNode = nullptr;
</span><span class="cx">     m_customCompositionUnderlines.clear();
</span><span class="cx"> 
</span><span class="cx">     if (!text.isEmpty()) {
</span><del>-        TypingCommand::insertText(document(), text, TypingCommand::SelectInsertedText | TypingCommand::PreventSpellChecking, TypingCommand::TextCompositionUpdate);
</del><ins>+        TypingCommand::insertText(document(), text, TypingCommand::SelectInsertedText | TypingCommand::PreventSpellChecking, TypingCommand::TextCompositionPending);
</ins><span class="cx"> 
</span><span class="cx">         // Find out what node has the composition now.
</span><span class="cx">         Position base = m_frame.selection().selection().base().downstream();
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingTypingCommandcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/TypingCommand.cpp (207697 => 207698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/TypingCommand.cpp        2016-10-21 22:38:22 UTC (rev 207697)
+++ trunk/Source/WebCore/editing/TypingCommand.cpp        2016-10-21 23:06:05 UTC (rev 207698)
</span><span class="lines">@@ -77,8 +77,24 @@
</span><span class="cx">     const String&amp; m_text;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-static inline EditAction editActionForTypingCommand(TypingCommand::ETypingCommand command, TextGranularity granularity)
</del><ins>+static inline EditAction editActionForTypingCommand(TypingCommand::ETypingCommand command, TextGranularity granularity, TypingCommand::TextCompositionType compositionType)
</ins><span class="cx"> {
</span><ins>+    if (compositionType == TypingCommand::TextCompositionPending) {
+        if (command == TypingCommand::InsertText)
+            return EditActionTypingInsertPendingComposition;
+        if (command == TypingCommand::DeleteSelection)
+            return EditActionTypingDeletePendingComposition;
+        ASSERT_NOT_REACHED();
+    }
+
+    if (compositionType == TypingCommand::TextCompositionFinal) {
+        if (command == TypingCommand::InsertText)
+            return EditActionTypingInsertFinalComposition;
+        if (command == TypingCommand::DeleteSelection)
+            return EditActionTypingDeleteFinalComposition;
+        ASSERT_NOT_REACHED();
+    }
+
</ins><span class="cx">     switch (command) {
</span><span class="cx">     case TypingCommand::DeleteSelection:
</span><span class="cx">         return EditActionTypingDeleteSelection;
</span><span class="lines">@@ -124,7 +140,7 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> TypingCommand::TypingCommand(Document&amp; document, ETypingCommand commandType, const String &amp;textToInsert, Options options, TextGranularity granularity, TextCompositionType compositionType)
</span><del>-    : TextInsertionBaseCommand(document, editActionForTypingCommand(commandType, granularity))
</del><ins>+    : TextInsertionBaseCommand(document, editActionForTypingCommand(commandType, granularity, compositionType))
</ins><span class="cx">     , m_commandType(commandType)
</span><span class="cx">     , m_textToInsert(textToInsert)
</span><span class="cx">     , m_currentTextToInsert(textToInsert)
</span><span class="lines">@@ -142,7 +158,7 @@
</span><span class="cx">     updatePreservesTypingStyle(m_commandType);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void TypingCommand::deleteSelection(Document&amp; document, Options options)
</del><ins>+void TypingCommand::deleteSelection(Document&amp; document, Options options, TextCompositionType compositionType)
</ins><span class="cx"> {
</span><span class="cx">     Frame* frame = document.frame();
</span><span class="cx">     ASSERT(frame);
</span><span class="lines">@@ -151,12 +167,13 @@
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     if (RefPtr&lt;TypingCommand&gt; lastTypingCommand = lastTypingCommandIfStillOpenForTyping(*frame)) {
</span><ins>+        lastTypingCommand-&gt;setCompositionType(compositionType);
</ins><span class="cx">         lastTypingCommand-&gt;setShouldPreventSpellChecking(options &amp; PreventSpellChecking);
</span><span class="cx">         lastTypingCommand-&gt;deleteSelection(options &amp; SmartDelete);
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    TypingCommand::create(document, DeleteSelection, emptyString(), options)-&gt;apply();
</del><ins>+    TypingCommand::create(document, DeleteSelection, emptyString(), options, compositionType)-&gt;apply();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void TypingCommand::deleteKeyPressed(Document&amp; document, Options options, TextGranularity granularity)
</span><span class="lines">@@ -164,6 +181,7 @@
</span><span class="cx">     if (granularity == CharacterGranularity) {
</span><span class="cx">         if (RefPtr&lt;TypingCommand&gt; lastTypingCommand = lastTypingCommandIfStillOpenForTyping(*document.frame())) {
</span><span class="cx">             updateSelectionIfDifferentFromCurrentSelection(lastTypingCommand.get(), document.frame());
</span><ins>+            lastTypingCommand-&gt;setCompositionType(TextCompositionNone);
</ins><span class="cx">             lastTypingCommand-&gt;setShouldPreventSpellChecking(options &amp; PreventSpellChecking);
</span><span class="cx">             lastTypingCommand-&gt;deleteKeyPressed(granularity, options &amp; AddsToKillRing);
</span><span class="cx">             return;
</span><span class="lines">@@ -180,6 +198,7 @@
</span><span class="cx">     if (granularity == CharacterGranularity) {
</span><span class="cx">         if (RefPtr&lt;TypingCommand&gt; lastTypingCommand = lastTypingCommandIfStillOpenForTyping(*frame)) {
</span><span class="cx">             updateSelectionIfDifferentFromCurrentSelection(lastTypingCommand.get(), frame);
</span><ins>+            lastTypingCommand-&gt;setCompositionType(TextCompositionNone);
</ins><span class="cx">             lastTypingCommand-&gt;setShouldPreventSpellChecking(options &amp; PreventSpellChecking);
</span><span class="cx">             lastTypingCommand-&gt;forwardDeleteKeyPressed(granularity, options &amp; AddsToKillRing);
</span><span class="cx">             return;
</span><span class="lines">@@ -221,7 +240,7 @@
</span><span class="cx"> 
</span><span class="cx">     VisibleSelection currentSelection = frame-&gt;selection().selection();
</span><span class="cx"> 
</span><del>-    String newText = dispatchBeforeTextInsertedEvent(text, selectionForInsertion, compositionType == TextCompositionUpdate);
</del><ins>+    String newText = dispatchBeforeTextInsertedEvent(text, selectionForInsertion, compositionType == TextCompositionPending);
</ins><span class="cx">     
</span><span class="cx">     // Set the starting and ending selection appropriately if we are using a selection
</span><span class="cx">     // that is different from the current selection.  In the future, we should change EditCommand
</span><span class="lines">@@ -246,6 +265,7 @@
</span><span class="cx"> void TypingCommand::insertLineBreak(Document&amp; document, Options options)
</span><span class="cx"> {
</span><span class="cx">     if (RefPtr&lt;TypingCommand&gt; lastTypingCommand = lastTypingCommandIfStillOpenForTyping(*document.frame())) {
</span><ins>+        lastTypingCommand-&gt;setCompositionType(TextCompositionNone);
</ins><span class="cx">         lastTypingCommand-&gt;setShouldRetainAutocorrectionIndicator(options &amp; RetainAutocorrectionIndicator);
</span><span class="cx">         lastTypingCommand-&gt;insertLineBreakAndNotifyAccessibility();
</span><span class="cx">         return;
</span><span class="lines">@@ -257,6 +277,7 @@
</span><span class="cx"> void TypingCommand::insertParagraphSeparatorInQuotedContent(Document&amp; document)
</span><span class="cx"> {
</span><span class="cx">     if (RefPtr&lt;TypingCommand&gt; lastTypingCommand = lastTypingCommandIfStillOpenForTyping(*document.frame())) {
</span><ins>+        lastTypingCommand-&gt;setCompositionType(TextCompositionNone);
</ins><span class="cx">         lastTypingCommand-&gt;insertParagraphSeparatorInQuotedContentAndNotifyAccessibility();
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="lines">@@ -267,6 +288,7 @@
</span><span class="cx"> void TypingCommand::insertParagraphSeparator(Document&amp; document, Options options)
</span><span class="cx"> {
</span><span class="cx">     if (RefPtr&lt;TypingCommand&gt; lastTypingCommand = lastTypingCommandIfStillOpenForTyping(*document.frame())) {
</span><ins>+        lastTypingCommand-&gt;setCompositionType(TextCompositionNone);
</ins><span class="cx">         lastTypingCommand-&gt;setShouldRetainAutocorrectionIndicator(options &amp; RetainAutocorrectionIndicator);
</span><span class="cx">         lastTypingCommand-&gt;insertParagraphSeparatorAndNotifyAccessibility();
</span><span class="cx">         return;
</span><span class="lines">@@ -367,12 +389,21 @@
</span><span class="cx">     return inputTypeNameForEditingAction(m_currentTypingEditAction);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool TypingCommand::isBeforeInputEventCancelable() const
+{
+    return m_currentTypingEditAction != EditActionTypingInsertPendingComposition &amp;&amp; m_currentTypingEditAction != EditActionTypingDeletePendingComposition;
+}
+
</ins><span class="cx"> String TypingCommand::inputEventData() const
</span><span class="cx"> {
</span><del>-    if (m_currentTypingEditAction == EditActionTypingInsertText)
</del><ins>+    switch (m_currentTypingEditAction) {
+    case EditActionTypingInsertText:
+    case EditActionTypingInsertPendingComposition:
+    case EditActionTypingInsertFinalComposition:
</ins><span class="cx">         return m_currentTextToInsert;
</span><del>-
-    return CompositeEditCommand::inputEventData();
</del><ins>+    default:
+        return CompositeEditCommand::inputEventData();
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void TypingCommand::didApplyCommand()
</span><span class="lines">@@ -438,7 +469,7 @@
</span><span class="cx"> bool TypingCommand::willAddTypingToOpenCommand(ETypingCommand commandType, TextGranularity granularity, const String&amp; text, RefPtr&lt;Range&gt;&amp;&amp; range)
</span><span class="cx"> {
</span><span class="cx">     m_currentTextToInsert = text;
</span><del>-    m_currentTypingEditAction = editActionForTypingCommand(commandType, granularity);
</del><ins>+    m_currentTypingEditAction = editActionForTypingCommand(commandType, granularity, m_compositionType);
</ins><span class="cx"> 
</span><span class="cx">     if (!shouldDeferWillApplyCommandUntilAddingTypingCommand())
</span><span class="cx">         return true;
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingTypingCommandh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/TypingCommand.h (207697 => 207698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/TypingCommand.h        2016-10-21 22:38:22 UTC (rev 207697)
+++ trunk/Source/WebCore/editing/TypingCommand.h        2016-10-21 23:06:05 UTC (rev 207698)
</span><span class="lines">@@ -44,8 +44,8 @@
</span><span class="cx"> 
</span><span class="cx">     enum TextCompositionType {
</span><span class="cx">         TextCompositionNone,
</span><del>-        TextCompositionUpdate,
-        TextCompositionConfirm
</del><ins>+        TextCompositionPending,
+        TextCompositionFinal,
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     enum Option {
</span><span class="lines">@@ -57,7 +57,7 @@
</span><span class="cx">     };
</span><span class="cx">     typedef unsigned Options;
</span><span class="cx"> 
</span><del>-    static void deleteSelection(Document&amp;, Options = 0);
</del><ins>+    static void deleteSelection(Document&amp;, Options = 0, TextCompositionType = TextCompositionNone);
</ins><span class="cx">     static void deleteKeyPressed(Document&amp;, Options = 0, TextGranularity = CharacterGranularity);
</span><span class="cx">     static void forwardDeleteKeyPressed(Document&amp;, Options = 0, TextGranularity = CharacterGranularity);
</span><span class="cx">     static void insertText(Document&amp;, const String&amp;, Options, TextCompositionType = TextCompositionNone);
</span><span class="lines">@@ -85,9 +85,9 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    static Ref&lt;TypingCommand&gt; create(Document&amp; document, ETypingCommand command, const String&amp; text = emptyString(), Options options = 0, TextGranularity granularity = CharacterGranularity)
</del><ins>+    static Ref&lt;TypingCommand&gt; create(Document&amp; document, ETypingCommand command, const String&amp; text = emptyString(), Options options = 0, TextGranularity granularity = CharacterGranularity, TextCompositionType compositionType = TextCompositionNone)
</ins><span class="cx">     {
</span><del>-        return adoptRef(*new TypingCommand(document, command, text, options, granularity, TextCompositionNone));
</del><ins>+        return adoptRef(*new TypingCommand(document, command, text, options, granularity, compositionType));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     static Ref&lt;TypingCommand&gt; create(Document&amp; document, ETypingCommand command, const String&amp; text, Options options, TextCompositionType compositionType)
</span><span class="lines">@@ -118,6 +118,7 @@
</span><span class="cx"> 
</span><span class="cx">     String inputEventTypeName() const final;
</span><span class="cx">     String inputEventData() const final;
</span><ins>+    bool isBeforeInputEventCancelable() const final;
</ins><span class="cx"> 
</span><span class="cx">     static void updateSelectionIfDifferentFromCurrentSelection(TypingCommand*, Frame*);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKitmacChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/ChangeLog (207697 => 207698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/ChangeLog        2016-10-21 22:38:22 UTC (rev 207697)
+++ trunk/Source/WebKit/mac/ChangeLog        2016-10-21 23:06:05 UTC (rev 207698)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2016-10-21  Wenson Hsieh  &lt;wenson_hsieh@apple.com&gt;
+
+        Support (insertFrom|deleteBy)Composition and (insert|delete)CompositionText inputTypes for InputEvents
+        https://bugs.webkit.org/show_bug.cgi?id=163460
+        &lt;rdar://problem/28784142&gt;
+
+        Reviewed by Darin Adler.
+
+        Handle new EditAction types for inserting/deleting pending/final compositions.
+
+        * WebCoreSupport/WebEditorClient.mm:
+        (undoNameForEditAction):
+
</ins><span class="cx"> 2016-10-21  Jeremy Jones  &lt;jeremyj@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Implement basic pointer lock behavior for WebKit and WebKit2.
</span></span></pre></div>
<a id="trunkSourceWebKitmacWebCoreSupportWebEditorClientmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/WebCoreSupport/WebEditorClient.mm (207697 => 207698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/WebCoreSupport/WebEditorClient.mm        2016-10-21 22:38:22 UTC (rev 207697)
+++ trunk/Source/WebKit/mac/WebCoreSupport/WebEditorClient.mm        2016-10-21 23:06:05 UTC (rev 207698)
</span><span class="lines">@@ -600,9 +600,13 @@
</span><span class="cx">         case EditActionTypingDeleteWordForward:
</span><span class="cx">         case EditActionTypingDeleteLineBackward:
</span><span class="cx">         case EditActionTypingDeleteLineForward:
</span><ins>+        case EditActionTypingDeletePendingComposition:
+        case EditActionTypingDeleteFinalComposition:
</ins><span class="cx">         case EditActionTypingInsertText:
</span><span class="cx">         case EditActionTypingInsertLineBreak:
</span><span class="cx">         case EditActionTypingInsertParagraph:
</span><ins>+        case EditActionTypingInsertPendingComposition:
+        case EditActionTypingInsertFinalComposition:
</ins><span class="cx">             return UI_STRING_KEY_INTERNAL(&quot;Typing&quot;, &quot;Typing (Undo action name)&quot;, &quot;Undo action name&quot;);
</span><span class="cx">         case EditActionCreateLink: return UI_STRING_KEY_INTERNAL(&quot;Create Link&quot;, &quot;Create Link (Undo action name)&quot;, &quot;Undo action name&quot;);
</span><span class="cx">         case EditActionUnlink: return UI_STRING_KEY_INTERNAL(&quot;Unlink&quot;, &quot;Unlink (Undo action name)&quot;, &quot;Undo action name&quot;);
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (207697 => 207698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2016-10-21 22:38:22 UTC (rev 207697)
+++ trunk/Source/WebKit2/ChangeLog        2016-10-21 23:06:05 UTC (rev 207698)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2016-10-21  Wenson Hsieh  &lt;wenson_hsieh@apple.com&gt;
+
+        Support (insertFrom|deleteBy)Composition and (insert|delete)CompositionText inputTypes for InputEvents
+        https://bugs.webkit.org/show_bug.cgi?id=163460
+        &lt;rdar://problem/28784142&gt;
+
+        Reviewed by Darin Adler.
+
+        Handle new EditAction types for inserting/deleting pending/final compositions.
+
+        * UIProcess/WebEditCommandProxy.cpp:
+        (WebKit::WebEditCommandProxy::nameForEditAction):
+
</ins><span class="cx"> 2016-10-21  Jeremy Jones  &lt;jeremyj@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Implement basic pointer lock behavior for WebKit and WebKit2.
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebEditCommandProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebEditCommandProxy.cpp (207697 => 207698)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebEditCommandProxy.cpp        2016-10-21 22:38:22 UTC (rev 207697)
+++ trunk/Source/WebKit2/UIProcess/WebEditCommandProxy.cpp        2016-10-21 23:06:05 UTC (rev 207698)
</span><span class="lines">@@ -151,9 +151,13 @@
</span><span class="cx">     case EditActionTypingDeleteWordForward:
</span><span class="cx">     case EditActionTypingDeleteLineBackward:
</span><span class="cx">     case EditActionTypingDeleteLineForward:
</span><ins>+    case EditActionTypingDeletePendingComposition:
+    case EditActionTypingDeleteFinalComposition:
</ins><span class="cx">     case EditActionTypingInsertText:
</span><span class="cx">     case EditActionTypingInsertLineBreak:
</span><span class="cx">     case EditActionTypingInsertParagraph:
</span><ins>+    case EditActionTypingInsertPendingComposition:
+    case EditActionTypingInsertFinalComposition:
</ins><span class="cx">         return WEB_UI_STRING_KEY(&quot;Typing&quot;, &quot;Typing (Undo action name)&quot;, &quot;Undo action name&quot;);
</span><span class="cx">     case EditActionCreateLink:
</span><span class="cx">         return WEB_UI_STRING_KEY(&quot;Create Link&quot;, &quot;Create Link (Undo action name)&quot;, &quot;Undo action name&quot;);
</span></span></pre>
</div>
</div>

</body>
</html>