<!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>[208014] 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/208014">208014</a></dd>
<dt>Author</dt> <dd>wenson_hsieh@apple.com</dd>
<dt>Date</dt> <dd>2016-10-27 15:46:46 -0700 (Thu, 27 Oct 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Support &quot;insertFromDrop&quot; and &quot;deleteByDrag&quot; for the InputEvent spec
https://bugs.webkit.org/show_bug.cgi?id=163948
&lt;rdar://problem/28921433&gt;

Reviewed by Darin Adler.

Source/WebCore:

Implements support for &quot;insertFromDrop&quot; and &quot;deleteByDrag&quot; inputTypes. These are fired when dragging and
dropping text in editable areas. To do this, we introduce EditActionInsertFromDrop and EditActionDeleteByDrag
(renamed from EditActionDrag, which is no longer necessary after this patch).

When moving text from an editable element to another, we will use a DeleteSelectionCommand to delete the text
from the source element and a ReplaceSelectionCommand to insert the text into the destination element. This
means that we currently fire two input events on the source and destination elements (i.e. given by the start
and end selections) after both child editing commands of the MoveSelectionCommand have been applied. Instead, we
need to fire events in this order:

1. beforeinput (&quot;deleteByDrag&quot;) on the source
2. Update DOM
3. input (&quot;deleteByDrag&quot;) on the source

4. beforeinput (&quot;insertFromDrop&quot;) on the destination
5. Update DOM
6. input (&quot;insertFromDrop&quot;) on the destination

To accomplish this, we allow an edit command to defer dispatching input events to its child commands via
CompositeEditCommand::shouldDispatchInputEvents, which the MoveSelectionCommand overrides. Additionally,
when applying the MoveSelectionCommand, we now apply() the child DeleteSelectionCommand and
ReplaceSelectionCommand instead of using doApply(). This allows these children to separately dispatch input
events, and also handle preventDefault() separately.

Tests: fast/events/before-input-events-prevent-drag-and-drop.html
       fast/events/input-events-drag-and-drop.html
       fast/events/input-events-insert-by-drop.html

* editing/CompositeEditCommand.cpp:
(WebCore::CompositeEditCommand::apply):
(WebCore::CompositeEditCommand::composition):

Searches for the top-level command and returns its composition. Also ASSERTs that the m_command of all child
commands along the way is null. In places where we used to ASSERT that command.composition() should be null, we
now perform the assertion here instead.

* editing/CompositeEditCommand.h:
(WebCore::CompositeEditCommand::shouldDispatchInputEvents):

This is true by default, which means that if apply() is called for a composite edit command that does not
override this to return false, it will try to dispatch input events. In most cases, the parent command will call
on the child command to doApply(), bypassing this check.

(WebCore::CompositeEditCommand::composition): Deleted.
* editing/EditAction.h:
* editing/EditCommand.cpp:
(WebCore::inputTypeNameForEditingAction):
(WebCore::EditCommand::isEditingTextAreaOrTextInput):
(WebCore::EditCommand::setStartingSelection):
(WebCore::EditCommand::setEndingSelection):
(WebCore::EditCommand::setParent):
* editing/Editor.cpp:
(WebCore::Editor::willApplyEditing):
(WebCore::Editor::appliedEditing):

After applying editing, only adjust the current selection and notify clients of selection change if the applied
command was a top-level command; otherwise, these actions should wait until all child commands of the top-level
command have been applied. In particular, we should not register the applied command as an undo step.

* editing/MoveSelectionCommand.cpp:
(WebCore::MoveSelectionCommand::doApply):
(WebCore::MoveSelectionCommand::editingAction):
* editing/MoveSelectionCommand.h:
* page/DragController.cpp:
(WebCore::DragController::concludeEditDrag):

For the cases where we're not deleting text from the drag source (i.e. we're just applying a
ReplaceSelectionCommand) pass in EditActionInsertFromDrop as the EditAction when creating the command.

Source/WebKit/mac:

Add support for new drag and drop-related EditAction enum values.

* WebCoreSupport/WebEditorClient.mm:
(undoNameForEditAction):

Source/WebKit/win:

Add support for new drag and drop-related EditAction enum values.

* WebCoreSupport/WebEditorClient.cpp:
(undoNameForEditAction):

Source/WebKit2:

Add support for new drag and drop-related EditAction enum values.

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

LayoutTests:

Adds 3 new layout tests verifying that when dragging and dropping (both from a contenteditable to another
contenteditable and from non-editable content into a contenteditable) beforeinput and input events are fired in
the right order with the right data and inputTypes, and that undoing/redoing still considers the drag and drop
command as a single unit. Also tests that both deleting text by dragging and inserting text by dropping are
preventable.

* fast/events/before-input-events-prevent-drag-and-drop-expected.txt: Added.
* fast/events/before-input-events-prevent-drag-and-drop.html: Added.
* fast/events/input-events-drag-and-drop-expected.txt: Added.
* fast/events/input-events-drag-and-drop.html: Added.
* fast/events/input-events-insert-by-drop-expected.txt: Added.
* fast/events/input-events-insert-by-drop.html: Added.
* platform/ios-simulator/TestExpectations:
* platform/mac-wk2/TestExpectations:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsplatformiossimulatorTestExpectations">trunk/LayoutTests/platform/ios-simulator/TestExpectations</a></li>
<li><a href="#trunkLayoutTestsplatformmacwk2TestExpectations">trunk/LayoutTests/platform/mac-wk2/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="#trunkSourceWebCoreeditingMoveSelectionCommandcpp">trunk/Source/WebCore/editing/MoveSelectionCommand.cpp</a></li>
<li><a href="#trunkSourceWebCoreeditingMoveSelectionCommandh">trunk/Source/WebCore/editing/MoveSelectionCommand.h</a></li>
<li><a href="#trunkSourceWebCorepageDragControllercpp">trunk/Source/WebCore/page/DragController.cpp</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="#trunkSourceWebKitwinChangeLog">trunk/Source/WebKit/win/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitwinWebCoreSupportWebEditorClientcpp">trunk/Source/WebKit/win/WebCoreSupport/WebEditorClient.cpp</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="#trunkLayoutTestsfasteventsbeforeinputeventspreventdraganddropexpectedtxt">trunk/LayoutTests/fast/events/before-input-events-prevent-drag-and-drop-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfasteventsbeforeinputeventspreventdraganddrophtml">trunk/LayoutTests/fast/events/before-input-events-prevent-drag-and-drop.html</a></li>
<li><a href="#trunkLayoutTestsfasteventsinputeventsdraganddropexpectedtxt">trunk/LayoutTests/fast/events/input-events-drag-and-drop-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfasteventsinputeventsdraganddrophtml">trunk/LayoutTests/fast/events/input-events-drag-and-drop.html</a></li>
<li><a href="#trunkLayoutTestsfasteventsinputeventsinsertbydropexpectedtxt">trunk/LayoutTests/fast/events/input-events-insert-by-drop-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfasteventsinputeventsinsertbydrophtml">trunk/LayoutTests/fast/events/input-events-insert-by-drop.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (208013 => 208014)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-10-27 22:37:21 UTC (rev 208013)
+++ trunk/LayoutTests/ChangeLog        2016-10-27 22:46:46 UTC (rev 208014)
</span><span class="lines">@@ -1,3 +1,26 @@
</span><ins>+2016-10-27  Wenson Hsieh  &lt;wenson_hsieh@apple.com&gt;
+
+        Support &quot;insertFromDrop&quot; and &quot;deleteByDrag&quot; for the InputEvent spec
+        https://bugs.webkit.org/show_bug.cgi?id=163948
+        &lt;rdar://problem/28921433&gt;
+
+        Reviewed by Darin Adler.
+
+        Adds 3 new layout tests verifying that when dragging and dropping (both from a contenteditable to another
+        contenteditable and from non-editable content into a contenteditable) beforeinput and input events are fired in
+        the right order with the right data and inputTypes, and that undoing/redoing still considers the drag and drop
+        command as a single unit. Also tests that both deleting text by dragging and inserting text by dropping are
+        preventable.
+
+        * fast/events/before-input-events-prevent-drag-and-drop-expected.txt: Added.
+        * fast/events/before-input-events-prevent-drag-and-drop.html: Added.
+        * fast/events/input-events-drag-and-drop-expected.txt: Added.
+        * fast/events/input-events-drag-and-drop.html: Added.
+        * fast/events/input-events-insert-by-drop-expected.txt: Added.
+        * fast/events/input-events-insert-by-drop.html: Added.
+        * platform/ios-simulator/TestExpectations:
+        * platform/mac-wk2/TestExpectations:
+
</ins><span class="cx"> 2016-10-27  Devin Rousso  &lt;dcrousso+webkit@gmail.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: Create general model object Collection class
</span></span></pre></div>
<a id="trunkLayoutTestsfasteventsbeforeinputeventspreventdraganddropexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/events/before-input-events-prevent-drag-and-drop-expected.txt (0 => 208014)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/events/before-input-events-prevent-drag-and-drop-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/events/before-input-events-prevent-drag-and-drop-expected.txt        2016-10-27 22:46:46 UTC (rev 208014)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+To manually test this, drag the text in the first editing area into the second. The first area should retain the text, the second area should be blank, and the third area should show an HTML representation of the first area with style information.
+
+Source:
+
+input events
+Destination:
+
+HTML content:
+
+&lt;span style=&quot;color: rgb(0, 0, 0); font-family: monospace; font-size: 108px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: center; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; display: inline !important; float: none;&quot;&gt;input events&lt;/span&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsfasteventsbeforeinputeventspreventdraganddrophtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/events/before-input-events-prevent-drag-and-drop.html (0 => 208014)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/events/before-input-events-prevent-drag-and-drop.html                                (rev 0)
+++ trunk/LayoutTests/fast/events/before-input-events-prevent-drag-and-drop.html        2016-10-27 22:46:46 UTC (rev 208014)
</span><span class="lines">@@ -0,0 +1,69 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;body&gt;
+    &lt;style&gt;
+    #source, #destination, #copy {
+        width: 100vw;
+        height: 20vh;
+        border: blue dashed 1px;
+        font-size: 18vh;
+        position: absolute;
+        opacity: 0.5;
+        text-align: center;
+    }
+    #source {
+        top: 0vh;
+    }
+    #destination {
+        top: 20vh;
+    }
+    &lt;/style&gt;
+    &lt;p&gt;To manually test this, drag the text in the first editing area into the second. The first area should retain the
+    text, the second area should be blank, and the third area should show an HTML representation of the first area with
+    style information.&lt;/p&gt;
+    &lt;p&gt;Source:&lt;/p&gt;
+    &lt;div id=&quot;source&quot; contenteditable onbeforeinput=handleBeforeInput(event)&gt;&lt;code&gt;input events&lt;/code&gt;&lt;/div&gt;
+    &lt;p&gt;Destination:&lt;/p&gt;
+    &lt;div id=&quot;destination&quot; contenteditable onbeforeinput=handleBeforeInput(event)&gt;&lt;/div&gt;
+    &lt;p&gt;HTML content:&lt;/p&gt;
+    &lt;div id=&quot;result&quot;&gt;&lt;/div&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;
+        if (window.internals &amp;&amp; window.testRunner) {
+            internals.settings.setInputEventsEnabled(true);
+            testRunner.dumpAsText();
+        }
+
+        source.focus();
+        document.execCommand(&quot;selectAll&quot;);
+
+        if (window.eventSender) {
+            moveToCenter(source);
+            eventSender.leapForward(500);
+            eventSender.mouseDown();
+            eventSender.leapForward(1000);
+            moveToCenter(destination);
+            eventSender.leapForward(500);
+            eventSender.mouseUp();
+        }
+
+        function handleBeforeInput(event)
+        {
+            if (event.inputType === &quot;insertFromDrop&quot;) {
+                result.textContent = event.dataTransfer.getData(&quot;text/html&quot;);
+                event.preventDefault();
+                return;
+            }
+
+            if (event.inputType === &quot;deleteByDrag&quot;)
+                event.preventDefault();
+        }
+
+        function moveToCenter(element)
+        {
+            let x = element.offsetParent.offsetLeft + element.offsetLeft + element.offsetWidth / 2;
+            let y = element.offsetParent.offsetTop + element.offsetTop + element.offsetHeight / 2;
+            eventSender.mouseMoveTo(x, y);
+        }
+    &lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsfasteventsinputeventsdraganddropexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/events/input-events-drag-and-drop-expected.txt (0 => 208014)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/events/input-events-drag-and-drop-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/events/input-events-drag-and-drop-expected.txt        2016-10-27 22:46:46 UTC (rev 208014)
</span><span class="lines">@@ -0,0 +1,17 @@
</span><ins>+To manually test this, drag the text in the first input into the second, then undo (cmd-z) and observe the output. You should see two deleteByDrag events (beforeinput and input) followed by two insertFromDrop events. After undoing, you should see two historyUndo events, and redoing should output two historyRedo events.
+
+
+Performing drag and drop
+(source): type=beforeinput, inputType=deleteByDrag, data=`null`
+(source): type=input, inputType=deleteByDrag, data=`null`
+(destination): type=beforeinput, inputType=insertFromDrop, data=`Input events!`
+(destination): type=input, inputType=insertFromDrop, data=`Input events!`
+
+Undoing drag and drop
+(destination): type=beforeinput, inputType=historyUndo, data=`null`
+(destination): type=input, inputType=historyUndo, data=`null`
+
+Redoing drag and drop
+(destination): type=beforeinput, inputType=historyRedo, data=`null`
+(destination): type=input, inputType=historyRedo, data=`null`
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfasteventsinputeventsdraganddrophtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/events/input-events-drag-and-drop.html (0 => 208014)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/events/input-events-drag-and-drop.html                                (rev 0)
+++ trunk/LayoutTests/fast/events/input-events-drag-and-drop.html        2016-10-27 22:46:46 UTC (rev 208014)
</span><span class="lines">@@ -0,0 +1,68 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;body&gt;
+    &lt;style&gt;
+    #source, #destination {
+        width: 100vw;
+        height: 50vh;
+        border: blue dashed 1px;
+        font-size: 40vh;
+        position: absolute;
+        opacity: 0.5;
+    }
+    #source {
+        top: 0vh;
+    }
+    #destination {
+        top: 50vh;
+    }
+    &lt;/style&gt;
+    &lt;p&gt;To manually test this, drag the text in the first input into the second, then undo (cmd-z) and observe the
+    output. You should see two deleteByDrag events (beforeinput and input) followed by two insertFromDrop events. After
+    undoing, you should see two historyUndo events, and redoing should output two historyRedo events.&lt;/p&gt;
+    &lt;input id=&quot;source&quot; onbeforeinput=logInputEvent(event) oninput=logInputEvent(event) value=&quot;Input events!&quot;&gt;&lt;/input&gt;
+    &lt;input id=&quot;destination&quot; onbeforeinput=logInputEvent(event) oninput=logInputEvent(event)&gt;&lt;/input&gt;
+    &lt;div id=&quot;output&quot;&gt;&lt;/div&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;
+        let write = s =&gt; output.innerHTML += s + &quot;&lt;br&gt;&quot;;
+        if (window.internals &amp;&amp; window.testRunner) {
+            internals.settings.setInputEventsEnabled(true);
+            testRunner.dumpAsText();
+        }
+
+        source.focus();
+        document.execCommand(&quot;selectAll&quot;);
+
+        if (window.eventSender) {
+            write(&quot;Performing drag and drop&quot;);
+            moveToCenter(source);
+            eventSender.leapForward(500);
+            eventSender.mouseDown();
+            eventSender.leapForward(1000);
+            moveToCenter(destination);
+            eventSender.leapForward(500);
+            eventSender.mouseUp();
+
+            write(&quot;&quot;);
+            write(&quot;Undoing drag and drop&quot;);
+            document.execCommand(&quot;Undo&quot;);
+
+            write(&quot;&quot;);
+            write(&quot;Redoing drag and drop&quot;);
+            document.execCommand(&quot;Redo&quot;);
+        }
+
+        function logInputEvent(event)
+        {
+            write(`(${event.target.id}): type=${event.type}, inputType=${event.inputType}, data=\`${event.data}\``);
+        }
+
+        function moveToCenter(element)
+        {
+            let x = element.offsetParent.offsetLeft + element.offsetLeft + element.offsetWidth / 2;
+            let y = element.offsetParent.offsetTop + element.offsetTop + element.offsetHeight / 2;
+            eventSender.mouseMoveTo(x, y);
+        }
+    &lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsfasteventsinputeventsinsertbydropexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/events/input-events-insert-by-drop-expected.txt (0 => 208014)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/events/input-events-insert-by-drop-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/events/input-events-insert-by-drop-expected.txt        2016-10-27 22:46:46 UTC (rev 208014)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+To manually test this, drag the text into the contenteditable, and then into the textarea. Observe the output. You should see a pair of insertFromDrop events dispatched on richDestination followed by another pair of insertFromDrop events dispatched on plainDestination.
+
+WebKit
+WebKit
+
+(richDestination): type=beforeinput, inputType=insertFromDrop, data=&quot;null&quot; dataTransfer={rich:WebKit plain:WebKit}
+(richDestination): type=input, inputType=insertFromDrop, data=&quot;null&quot; dataTransfer={rich:WebKit plain:WebKit}
+(plainDestination): type=beforeinput, inputType=insertFromDrop, data=&quot;WebKit&quot; dataTransfer=(null)
+(plainDestination): type=input, inputType=insertFromDrop, data=&quot;WebKit&quot; dataTransfer=(null)
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfasteventsinputeventsinsertbydrophtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/events/input-events-insert-by-drop.html (0 => 208014)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/events/input-events-insert-by-drop.html                                (rev 0)
+++ trunk/LayoutTests/fast/events/input-events-insert-by-drop.html        2016-10-27 22:46:46 UTC (rev 208014)
</span><span class="lines">@@ -0,0 +1,76 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;body&gt;
+    &lt;style&gt;
+        #source, #richDestination, #plainDestination {
+            font-size: 30px;
+            border: 1px blue dashed;
+            width: 100px;
+        }
+    &lt;/style&gt;
+    &lt;p&gt;To manually test this, drag the text into the contenteditable, and then into the textarea. Observe the output.
+    You should see a pair of insertFromDrop events dispatched on richDestination followed by another pair of
+    insertFromDrop events dispatched on plainDestination.&lt;/p&gt;
+    &lt;div id=&quot;source&quot;&gt;WebKit&lt;/div&gt;
+    &lt;div id=&quot;richDestination&quot; contenteditable onbeforeinput=logInputEvent(event) oninput=logInputEvent(event)&gt;&lt;/div&gt;
+    &lt;textarea id=&quot;plainDestination&quot; onbeforeinput=logInputEvent(event) oninput=logInputEvent(event)&gt;&lt;/textarea&gt;
+    &lt;div id=&quot;output&quot;&gt;&lt;/div&gt;
+    &lt;script type=&quot;text/javascript&quot;&gt;
+        if (window.internals &amp;&amp; window.testRunner) {
+            internals.settings.setInputEventsEnabled(true);
+            testRunner.dumpAsText();
+        }
+
+        if (window.eventSender) {
+            moveToCenter(source);
+            doubleClick();
+            eventSender.leapForward(1000);
+
+            eventSender.mouseDown();
+            eventSender.leapForward(1000);
+            moveToCenter(richDestination);
+            eventSender.leapForward(1000);
+            eventSender.mouseUp();
+            eventSender.leapForward(1000);
+
+            moveToCenter(source);
+            doubleClick();
+            eventSender.leapForward(1000);
+
+            eventSender.mouseDown();
+            eventSender.leapForward(1000);
+            moveToCenter(plainDestination);
+            eventSender.leapForward(1000);
+            eventSender.mouseUp();
+        }
+
+        function dataTransferToString(dataTransfer)
+        {
+            if (!dataTransfer)
+                return &quot;(null)&quot;
+
+            return `{rich:${dataTransfer.getData(&quot;text/html&quot;)} plain:${dataTransfer.getData(&quot;text/plain&quot;)}}`;
+        }
+
+        function logInputEvent(event)
+        {
+            output.innerHTML += `(${event.target.id}): type=${event.type}, inputType=${event.inputType}, data=&quot;${event.data}&quot; dataTransfer=${dataTransferToString(event.dataTransfer)}&lt;br&gt;`;
+        }
+
+        function doubleClick() {
+            eventSender.mouseDown();
+            eventSender.mouseUp();
+            eventSender.leapForward(100);
+            eventSender.mouseDown();
+            eventSender.mouseUp();
+        }
+
+        function moveToCenter(element)
+        {
+            let x = element.offsetParent.offsetLeft + element.offsetLeft + element.offsetWidth / 2;
+            let y = element.offsetParent.offsetTop + element.offsetTop + element.offsetHeight / 2;
+            eventSender.mouseMoveTo(x, y);
+        }
+    &lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsplatformiossimulatorTestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/ios-simulator/TestExpectations (208013 => 208014)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/ios-simulator/TestExpectations        2016-10-27 22:37:21 UTC (rev 208013)
+++ trunk/LayoutTests/platform/ios-simulator/TestExpectations        2016-10-27 22:46:46 UTC (rev 208014)
</span><span class="lines">@@ -1205,6 +1205,8 @@
</span><span class="cx"> fast/events/frame-tab-focus.html [ Failure ]
</span><span class="cx"> fast/events/ime-composition-events-001.html [ Failure ]
</span><span class="cx"> fast/events/inputText-never-fired-on-keydown-cancel.html [ Failure ]
</span><ins>+fast/events/input-events-drag-and-drop.html [ Failure ]
+fast/events/input-events-insert-by-drop.html [ Failure ]
</ins><span class="cx"> fast/events/input-events-fired-when-typing.html [ Failure ]
</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="lines">@@ -1226,6 +1228,7 @@
</span><span class="cx"> fast/events/before-input-delete-empty-list-target-ranges.html [ Failure ]
</span><span class="cx"> fast/events/before-input-events-prevent-recomposition.html [ Failure ]
</span><span class="cx"> fast/events/before-input-events-prevent-insert-composition.html [ Failure ]
</span><ins>+fast/events/before-input-events-prevent-drag-and-drop.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="trunkLayoutTestsplatformmacwk2TestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac-wk2/TestExpectations (208013 => 208014)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac-wk2/TestExpectations        2016-10-27 22:37:21 UTC (rev 208013)
+++ trunk/LayoutTests/platform/mac-wk2/TestExpectations        2016-10-27 22:46:46 UTC (rev 208014)
</span><span class="lines">@@ -173,6 +173,10 @@
</span><span class="cx"> fast/events/drag-selects-image.html
</span><span class="cx"> fast/events/remove-target-with-shadow-in-drag.html
</span><span class="cx"> 
</span><ins>+fast/events/before-input-events-prevent-drag-and-drop.html [ Failure ]
+fast/events/input-events-drag-and-drop.html [ Failure ]
+fast/events/input-events-insert-by-drop.html [ Failure ]
+
</ins><span class="cx"> webkit.org/b/81833 fast/events/drag-and-drop-link-into-focused-contenteditable.html [ Failure ]
</span><span class="cx"> 
</span><span class="cx"> # Missing functionality of textInputController
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (208013 => 208014)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-10-27 22:37:21 UTC (rev 208013)
+++ trunk/Source/WebCore/ChangeLog        2016-10-27 22:46:46 UTC (rev 208014)
</span><span class="lines">@@ -1,3 +1,80 @@
</span><ins>+2016-10-27  Wenson Hsieh  &lt;wenson_hsieh@apple.com&gt;
+
+        Support &quot;insertFromDrop&quot; and &quot;deleteByDrag&quot; for the InputEvent spec
+        https://bugs.webkit.org/show_bug.cgi?id=163948
+        &lt;rdar://problem/28921433&gt;
+
+        Reviewed by Darin Adler.
+
+        Implements support for &quot;insertFromDrop&quot; and &quot;deleteByDrag&quot; inputTypes. These are fired when dragging and
+        dropping text in editable areas. To do this, we introduce EditActionInsertFromDrop and EditActionDeleteByDrag
+        (renamed from EditActionDrag, which is no longer necessary after this patch).
+
+        When moving text from an editable element to another, we will use a DeleteSelectionCommand to delete the text
+        from the source element and a ReplaceSelectionCommand to insert the text into the destination element. This
+        means that we currently fire two input events on the source and destination elements (i.e. given by the start
+        and end selections) after both child editing commands of the MoveSelectionCommand have been applied. Instead, we
+        need to fire events in this order:
+
+        1. beforeinput (&quot;deleteByDrag&quot;) on the source
+        2. Update DOM
+        3. input (&quot;deleteByDrag&quot;) on the source
+
+        4. beforeinput (&quot;insertFromDrop&quot;) on the destination
+        5. Update DOM
+        6. input (&quot;insertFromDrop&quot;) on the destination
+
+        To accomplish this, we allow an edit command to defer dispatching input events to its child commands via
+        CompositeEditCommand::shouldDispatchInputEvents, which the MoveSelectionCommand overrides. Additionally,
+        when applying the MoveSelectionCommand, we now apply() the child DeleteSelectionCommand and
+        ReplaceSelectionCommand instead of using doApply(). This allows these children to separately dispatch input
+        events, and also handle preventDefault() separately.
+
+        Tests: fast/events/before-input-events-prevent-drag-and-drop.html
+               fast/events/input-events-drag-and-drop.html
+               fast/events/input-events-insert-by-drop.html
+
+        * editing/CompositeEditCommand.cpp:
+        (WebCore::CompositeEditCommand::apply):
+        (WebCore::CompositeEditCommand::composition):
+
+        Searches for the top-level command and returns its composition. Also ASSERTs that the m_command of all child
+        commands along the way is null. In places where we used to ASSERT that command.composition() should be null, we
+        now perform the assertion here instead.
+
+        * editing/CompositeEditCommand.h:
+        (WebCore::CompositeEditCommand::shouldDispatchInputEvents):
+
+        This is true by default, which means that if apply() is called for a composite edit command that does not
+        override this to return false, it will try to dispatch input events. In most cases, the parent command will call
+        on the child command to doApply(), bypassing this check.
+
+        (WebCore::CompositeEditCommand::composition): Deleted.
+        * editing/EditAction.h:
+        * editing/EditCommand.cpp:
+        (WebCore::inputTypeNameForEditingAction):
+        (WebCore::EditCommand::isEditingTextAreaOrTextInput):
+        (WebCore::EditCommand::setStartingSelection):
+        (WebCore::EditCommand::setEndingSelection):
+        (WebCore::EditCommand::setParent):
+        * editing/Editor.cpp:
+        (WebCore::Editor::willApplyEditing):
+        (WebCore::Editor::appliedEditing):
+
+        After applying editing, only adjust the current selection and notify clients of selection change if the applied
+        command was a top-level command; otherwise, these actions should wait until all child commands of the top-level
+        command have been applied. In particular, we should not register the applied command as an undo step.
+
+        * editing/MoveSelectionCommand.cpp:
+        (WebCore::MoveSelectionCommand::doApply):
+        (WebCore::MoveSelectionCommand::editingAction):
+        * editing/MoveSelectionCommand.h:
+        * page/DragController.cpp:
+        (WebCore::DragController::concludeEditDrag):
+
+        For the cases where we're not deleting text from the drag source (i.e. we're just applying a
+        ReplaceSelectionCommand) pass in EditActionInsertFromDrop as the EditAction when creating the command.
+
</ins><span class="cx"> 2016-10-27  Per Arne Vollan  &lt;pvollan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [Win][Direct2D] Implement GraphicsContext::releaseWindowsContext.
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingCompositeEditCommandcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/CompositeEditCommand.cpp (208013 => 208014)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/CompositeEditCommand.cpp        2016-10-27 22:37:21 UTC (rev 208013)
+++ trunk/Source/WebCore/editing/CompositeEditCommand.cpp        2016-10-27 22:46:46 UTC (rev 208014)
</span><span class="lines">@@ -343,12 +343,13 @@
</span><span class="cx">         case EditActionTypingInsertPendingComposition:
</span><span class="cx">         case EditActionTypingInsertFinalComposition:
</span><span class="cx">         case EditActionPaste:
</span><del>-        case EditActionDrag:
</del><ins>+        case EditActionDeleteByDrag:
</ins><span class="cx">         case EditActionSetWritingDirection:
</span><span class="cx">         case EditActionCut:
</span><span class="cx">         case EditActionUnspecified:
</span><span class="cx">         case EditActionInsert:
</span><span class="cx">         case EditActionInsertReplacement:
</span><ins>+        case EditActionInsertFromDrop:
</ins><span class="cx">         case EditActionDelete:
</span><span class="cx">         case EditActionDictation:
</span><span class="cx">             break;
</span><span class="lines">@@ -405,6 +406,17 @@
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+EditCommandComposition* CompositeEditCommand::composition() const
+{
+    for (auto* command = this; command; command = command-&gt;parent()) {
+        if (auto composition = command-&gt;m_composition) {
+            ASSERT(!command-&gt;parent());
+            return composition.get();
+        }
+    }
+    return nullptr;
+}
+
</ins><span class="cx"> EditCommandComposition* CompositeEditCommand::ensureComposition()
</span><span class="cx"> {
</span><span class="cx">     CompositeEditCommand* command = this;
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingCompositeEditCommandh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/CompositeEditCommand.h (208013 => 208014)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/CompositeEditCommand.h        2016-10-27 22:37:21 UTC (rev 208013)
+++ trunk/Source/WebCore/editing/CompositeEditCommand.h        2016-10-27 22:46:46 UTC (rev 208014)
</span><span class="lines">@@ -105,7 +105,7 @@
</span><span class="cx"> 
</span><span class="cx">     void apply();
</span><span class="cx">     bool isFirstCommand(EditCommand* command) { return !m_commands.isEmpty() &amp;&amp; m_commands.first() == command; }
</span><del>-    EditCommandComposition* composition() { return m_composition.get(); }
</del><ins>+    EditCommandComposition* composition() const;
</ins><span class="cx">     EditCommandComposition* ensureComposition();
</span><span class="cx"> 
</span><span class="cx">     virtual bool isCreateLinkCommand() const;
</span><span class="lines">@@ -118,6 +118,7 @@
</span><span class="cx">     virtual String inputEventTypeName() const;
</span><span class="cx">     virtual String inputEventData() const { return { }; }
</span><span class="cx">     virtual bool isBeforeInputEventCancelable() const { return true; }
</span><ins>+    virtual bool shouldDispatchInputEvents() const { return true; }
</ins><span class="cx">     Vector&lt;RefPtr&lt;StaticRange&gt;&gt; targetRangesForBindings() const;
</span><span class="cx">     virtual RefPtr&lt;DataTransfer&gt; inputEventDataTransfer() const;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingEditActionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/EditAction.h (208013 => 208014)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/EditAction.h        2016-10-27 22:37:21 UTC (rev 208013)
+++ trunk/Source/WebCore/editing/EditAction.h        2016-10-27 22:46:46 UTC (rev 208014)
</span><span class="lines">@@ -31,6 +31,7 @@
</span><span class="cx">         EditActionUnspecified,
</span><span class="cx">         EditActionInsert,
</span><span class="cx">         EditActionInsertReplacement,
</span><ins>+        EditActionInsertFromDrop,
</ins><span class="cx">         EditActionSetColor,
</span><span class="cx">         EditActionSetBackgroundColor,
</span><span class="cx">         EditActionTurnOffKerning,
</span><span class="lines">@@ -55,7 +56,7 @@
</span><span class="cx">         EditActionUnderline,
</span><span class="cx">         EditActionOutline,
</span><span class="cx">         EditActionUnscript,
</span><del>-        EditActionDrag,
</del><ins>+        EditActionDeleteByDrag,
</ins><span class="cx">         EditActionCut,
</span><span class="cx">         EditActionBold,
</span><span class="cx">         EditActionItalics,
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingEditCommandcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/EditCommand.cpp (208013 => 208014)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/EditCommand.cpp        2016-10-27 22:37:21 UTC (rev 208013)
+++ trunk/Source/WebCore/editing/EditCommand.cpp        2016-10-27 22:46:46 UTC (rev 208014)
</span><span class="lines">@@ -58,7 +58,7 @@
</span><span class="cx">         return ASCIILiteral(&quot;formatUnderline&quot;);
</span><span class="cx">     case EditActionSetColor:
</span><span class="cx">         return ASCIILiteral(&quot;formatForeColor&quot;);
</span><del>-    case EditActionDrag:
</del><ins>+    case EditActionDeleteByDrag:
</ins><span class="cx">         return ASCIILiteral(&quot;deleteByDrag&quot;);
</span><span class="cx">     case EditActionCut:
</span><span class="cx">         return ASCIILiteral(&quot;deleteByCut&quot;);
</span><span class="lines">@@ -92,6 +92,8 @@
</span><span class="cx">         return ASCIILiteral(&quot;insertText&quot;);
</span><span class="cx">     case EditActionInsertReplacement:
</span><span class="cx">         return ASCIILiteral(&quot;insertReplacementText&quot;);
</span><ins>+    case EditActionInsertFromDrop:
+        return ASCIILiteral(&quot;insertFromDrop&quot;);
</ins><span class="cx">     case EditActionTypingInsertLineBreak:
</span><span class="cx">         return ASCIILiteral(&quot;insertLineBreak&quot;);
</span><span class="cx">     case EditActionTypingInsertParagraph:
</span><span class="lines">@@ -178,10 +180,8 @@
</span><span class="cx"> void EditCommand::setStartingSelection(const VisibleSelection&amp; s)
</span><span class="cx"> {
</span><span class="cx">     for (EditCommand* cmd = this; ; cmd = cmd-&gt;m_parent) {
</span><del>-        if (EditCommandComposition* composition = compositionIfPossible(cmd)) {
-            ASSERT(cmd-&gt;isTopLevelCommand());
</del><ins>+        if (auto* composition = compositionIfPossible(cmd))
</ins><span class="cx">             composition-&gt;setStartingSelection(s);
</span><del>-        }
</del><span class="cx">         cmd-&gt;m_startingSelection = s;
</span><span class="cx">         if (!cmd-&gt;m_parent || cmd-&gt;m_parent-&gt;isFirstCommand(cmd))
</span><span class="cx">             break;
</span><span class="lines">@@ -191,10 +191,8 @@
</span><span class="cx"> void EditCommand::setEndingSelection(const VisibleSelection &amp;s)
</span><span class="cx"> {
</span><span class="cx">     for (EditCommand* cmd = this; cmd; cmd = cmd-&gt;m_parent) {
</span><del>-        if (EditCommandComposition* composition = compositionIfPossible(cmd)) {
-            ASSERT(cmd-&gt;isTopLevelCommand());
</del><ins>+        if (auto* composition = compositionIfPossible(cmd))
</ins><span class="cx">             composition-&gt;setEndingSelection(s);
</span><del>-        }
</del><span class="cx">         cmd-&gt;m_endingSelection = s;
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="lines">@@ -202,7 +200,6 @@
</span><span class="cx"> void EditCommand::setParent(CompositeEditCommand* parent)
</span><span class="cx"> {
</span><span class="cx">     ASSERT((parent &amp;&amp; !m_parent) || (!parent &amp;&amp; m_parent));
</span><del>-    ASSERT(!parent || !isCompositeEditCommand() || !toCompositeEditCommand(this)-&gt;composition());
</del><span class="cx">     m_parent = parent;
</span><span class="cx">     if (parent) {
</span><span class="cx">         m_startingSelection = parent-&gt;m_endingSelection;
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingEditorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/Editor.cpp (208013 => 208014)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/Editor.cpp        2016-10-27 22:37:21 UTC (rev 208013)
+++ trunk/Source/WebCore/editing/Editor.cpp        2016-10-27 22:46:46 UTC (rev 208014)
</span><span class="lines">@@ -1083,6 +1083,9 @@
</span><span class="cx"> 
</span><span class="cx"> bool Editor::willApplyEditing(CompositeEditCommand&amp; command, Vector&lt;RefPtr&lt;StaticRange&gt;&gt;&amp;&amp; targetRanges) const
</span><span class="cx"> {
</span><ins>+    if (!command.shouldDispatchInputEvents())
+        return true;
+
</ins><span class="cx">     auto* composition = command.composition();
</span><span class="cx">     if (!composition)
</span><span class="cx">         return true;
</span><span class="lines">@@ -1102,31 +1105,36 @@
</span><span class="cx"> 
</span><span class="cx">     notifyTextFromControls(composition-&gt;startingRootEditableElement(), composition-&gt;endingRootEditableElement());
</span><span class="cx"> 
</span><del>-    // Don't clear the typing style with this selection change.  We do those things elsewhere if necessary.
-    FrameSelection::SetSelectionOptions options = cmd-&gt;isDictationCommand() ? FrameSelection::DictationTriggered : 0;
-    
-    changeSelectionAfterCommand(newSelection, options);
-    dispatchInputEvents(composition-&gt;startingRootEditableElement(), composition-&gt;endingRootEditableElement(), cmd-&gt;inputEventTypeName(), cmd-&gt;inputEventData(), cmd-&gt;inputEventDataTransfer());
</del><ins>+    if (cmd-&gt;isTopLevelCommand()) {
+        // Don't clear the typing style with this selection change. We do those things elsewhere if necessary.
+        FrameSelection::SetSelectionOptions options = cmd-&gt;isDictationCommand() ? FrameSelection::DictationTriggered : 0;
</ins><span class="cx"> 
</span><del>-    updateEditorUINowIfScheduled();
-    
-    m_alternativeTextController-&gt;respondToAppliedEditing(cmd.get());
</del><ins>+        changeSelectionAfterCommand(newSelection, options);
+    }
</ins><span class="cx"> 
</span><del>-    if (!cmd-&gt;preservesTypingStyle())
-        m_frame.selection().clearTypingStyle();
</del><ins>+    if (cmd-&gt;shouldDispatchInputEvents())
+        dispatchInputEvents(composition-&gt;startingRootEditableElement(), composition-&gt;endingRootEditableElement(), cmd-&gt;inputEventTypeName(), cmd-&gt;inputEventData(), cmd-&gt;inputEventDataTransfer());
</ins><span class="cx"> 
</span><del>-    // Command will be equal to last edit command only in the case of typing
-    if (m_lastEditCommand.get() == cmd)
-        ASSERT(cmd-&gt;isTypingCommand());
-    else {
-        // Only register a new undo command if the command passed in is
-        // different from the last command
-        m_lastEditCommand = cmd;
-        if (client())
-            client()-&gt;registerUndoStep(m_lastEditCommand-&gt;ensureComposition());
</del><ins>+    if (cmd-&gt;isTopLevelCommand()) {
+        updateEditorUINowIfScheduled();
+
+        m_alternativeTextController-&gt;respondToAppliedEditing(cmd.get());
+
+        if (!cmd-&gt;preservesTypingStyle())
+            m_frame.selection().clearTypingStyle();
+
+        // Command will be equal to last edit command only in the case of typing
+        if (m_lastEditCommand.get() == cmd)
+            ASSERT(cmd-&gt;isTypingCommand());
+        else {
+            // Only register a new undo command if the command passed in is
+            // different from the last command
+            m_lastEditCommand = cmd;
+            if (client())
+                client()-&gt;registerUndoStep(m_lastEditCommand-&gt;ensureComposition());
+        }
+        respondToChangedContents(newSelection);
</ins><span class="cx">     }
</span><del>-
-    respondToChangedContents(newSelection);
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool Editor::willUnapplyEditing(const EditCommandComposition&amp; composition) const
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingMoveSelectionCommandcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/MoveSelectionCommand.cpp (208013 => 208014)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/MoveSelectionCommand.cpp        2016-10-27 22:37:21 UTC (rev 208013)
+++ trunk/Source/WebCore/editing/MoveSelectionCommand.cpp        2016-10-27 22:46:46 UTC (rev 208014)
</span><span class="lines">@@ -26,6 +26,7 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;MoveSelectionCommand.h&quot;
</span><span class="cx"> 
</span><ins>+#include &quot;DeleteSelectionCommand.h&quot;
</ins><span class="cx"> #include &quot;DocumentFragment.h&quot;
</span><span class="cx"> #include &quot;ReplaceSelectionCommand.h&quot;
</span><span class="cx"> 
</span><span class="lines">@@ -60,7 +61,12 @@
</span><span class="cx">             pos.moveToOffset(pos.offsetInContainerNode() + selectionStart.offsetInContainerNode());
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    deleteSelection(m_smartDelete);
</del><ins>+    {
+        auto deleteSelection = DeleteSelectionCommand::create(document(), m_smartDelete, true, false, true, true, EditActionDeleteByDrag);
+        deleteSelection-&gt;setParent(this);
+        deleteSelection-&gt;apply();
+        m_commands.append(WTFMove(deleteSelection));
+    }
</ins><span class="cx"> 
</span><span class="cx">     // If the node for the destination has been removed as a result of the deletion,
</span><span class="cx">     // set the destination to the ending point after the deletion.
</span><span class="lines">@@ -72,6 +78,7 @@
</span><span class="cx">     cleanupAfterDeletion(pos);
</span><span class="cx"> 
</span><span class="cx">     setEndingSelection(VisibleSelection(pos, endingSelection().affinity(), endingSelection().isDirectional()));
</span><ins>+    setStartingSelection(endingSelection());
</ins><span class="cx">     if (!pos.anchorNode()-&gt;inDocument()) {
</span><span class="cx">         // Document was modified out from under us.
</span><span class="cx">         return;
</span><span class="lines">@@ -79,12 +86,18 @@
</span><span class="cx">     ReplaceSelectionCommand::CommandOptions options = ReplaceSelectionCommand::SelectReplacement | ReplaceSelectionCommand::PreventNesting;
</span><span class="cx">     if (m_smartInsert)
</span><span class="cx">         options |= ReplaceSelectionCommand::SmartReplace;
</span><del>-    applyCommandToComposite(ReplaceSelectionCommand::create(document(), WTFMove(m_fragment), options));
</del><ins>+
+    {
+        auto replaceSelection = ReplaceSelectionCommand::create(document(), WTFMove(m_fragment), options, EditActionInsertFromDrop);
+        replaceSelection-&gt;setParent(this);
+        replaceSelection-&gt;apply();
+        m_commands.append(WTFMove(replaceSelection));
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> EditAction MoveSelectionCommand::editingAction() const
</span><span class="cx"> {
</span><del>-    return EditActionDrag;
</del><ins>+    return EditActionDeleteByDrag;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingMoveSelectionCommandh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/MoveSelectionCommand.h (208013 => 208014)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/MoveSelectionCommand.h        2016-10-27 22:37:21 UTC (rev 208013)
+++ trunk/Source/WebCore/editing/MoveSelectionCommand.h        2016-10-27 22:46:46 UTC (rev 208014)
</span><span class="lines">@@ -44,6 +44,7 @@
</span><span class="cx"> 
</span><span class="cx">     virtual void doApply();
</span><span class="cx">     virtual EditAction editingAction() const;
</span><ins>+    bool shouldDispatchInputEvents() const final { return false; }
</ins><span class="cx">     
</span><span class="cx">     RefPtr&lt;DocumentFragment&gt; m_fragment;
</span><span class="cx">     Position m_position;
</span></span></pre></div>
<a id="trunkSourceWebCorepageDragControllercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/DragController.cpp (208013 => 208014)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/DragController.cpp        2016-10-27 22:37:21 UTC (rev 208013)
+++ trunk/Source/WebCore/page/DragController.cpp        2016-10-27 22:46:46 UTC (rev 208014)
</span><span class="lines">@@ -532,7 +532,7 @@
</span><span class="cx">                     options |= ReplaceSelectionCommand::SmartReplace;
</span><span class="cx">                 if (chosePlainText)
</span><span class="cx">                     options |= ReplaceSelectionCommand::MatchStyle;
</span><del>-                applyCommand(ReplaceSelectionCommand::create(*m_documentUnderMouse, WTFMove(fragment), options));
</del><ins>+                applyCommand(ReplaceSelectionCommand::create(*m_documentUnderMouse, WTFMove(fragment), options, EditActionInsertFromDrop));
</ins><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx">     } else {
</span><span class="lines">@@ -543,7 +543,7 @@
</span><span class="cx"> 
</span><span class="cx">         m_client.willPerformDragDestinationAction(DragDestinationActionEdit, dragData);
</span><span class="cx">         if (setSelectionToDragCaret(innerFrame.get(), dragCaret, range, point))
</span><del>-            applyCommand(ReplaceSelectionCommand::create(*m_documentUnderMouse, createFragmentFromText(*range, text),  ReplaceSelectionCommand::SelectReplacement | ReplaceSelectionCommand::MatchStyle | ReplaceSelectionCommand::PreventNesting));
</del><ins>+            applyCommand(ReplaceSelectionCommand::create(*m_documentUnderMouse, createFragmentFromText(*range, text),  ReplaceSelectionCommand::SelectReplacement | ReplaceSelectionCommand::MatchStyle | ReplaceSelectionCommand::PreventNesting, EditActionInsertFromDrop));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (rootEditableElement) {
</span></span></pre></div>
<a id="trunkSourceWebKitmacChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/ChangeLog (208013 => 208014)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/ChangeLog        2016-10-27 22:37:21 UTC (rev 208013)
+++ trunk/Source/WebKit/mac/ChangeLog        2016-10-27 22:46:46 UTC (rev 208014)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2016-10-27  Wenson Hsieh  &lt;wenson_hsieh@apple.com&gt;
+
+        Support &quot;insertFromDrop&quot; and &quot;deleteByDrag&quot; for the InputEvent spec
+        https://bugs.webkit.org/show_bug.cgi?id=163948
+        &lt;rdar://problem/28921433&gt;
+
+        Reviewed by Darin Adler.
+
+        Add support for new drag and drop-related EditAction enum values.
+
+        * WebCoreSupport/WebEditorClient.mm:
+        (undoNameForEditAction):
+
</ins><span class="cx"> 2016-10-27  Dan Bernstein  &lt;mitz@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Reapplied the configuration changes from r207934 without breaking iOS builds.
</span></span></pre></div>
<a id="trunkSourceWebKitmacWebCoreSupportWebEditorClientmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/WebCoreSupport/WebEditorClient.mm (208013 => 208014)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/WebCoreSupport/WebEditorClient.mm        2016-10-27 22:37:21 UTC (rev 208013)
+++ trunk/Source/WebKit/mac/WebCoreSupport/WebEditorClient.mm        2016-10-27 22:46:46 UTC (rev 208014)
</span><span class="lines">@@ -564,6 +564,7 @@
</span><span class="cx">         case EditActionUnspecified: return nil;
</span><span class="cx">         case EditActionInsert: return nil;
</span><span class="cx">         case EditActionInsertReplacement: return nil;
</span><ins>+        case EditActionInsertFromDrop: return nil;
</ins><span class="cx">         case EditActionSetColor: return UI_STRING_KEY_INTERNAL(&quot;Set Color&quot;, &quot;Set Color (Undo action name)&quot;, &quot;Undo action name&quot;);
</span><span class="cx">         case EditActionSetBackgroundColor: return UI_STRING_KEY_INTERNAL(&quot;Set Background Color&quot;, &quot;Set Background Color (Undo action name)&quot;, &quot;Undo action name&quot;);
</span><span class="cx">         case EditActionTurnOffKerning: return UI_STRING_KEY_INTERNAL(&quot;Turn Off Kerning&quot;, &quot;Turn Off Kerning (Undo action name)&quot;, &quot;Undo action name&quot;);
</span><span class="lines">@@ -588,7 +589,7 @@
</span><span class="cx">         case EditActionUnderline: return UI_STRING_KEY_INTERNAL(&quot;Underline&quot;, &quot;Underline (Undo action name)&quot;, &quot;Undo action name&quot;);
</span><span class="cx">         case EditActionOutline: return UI_STRING_KEY_INTERNAL(&quot;Outline&quot;, &quot;Outline (Undo action name)&quot;, &quot;Undo action name&quot;);
</span><span class="cx">         case EditActionUnscript: return UI_STRING_KEY_INTERNAL(&quot;Unscript&quot;, &quot;Unscript (Undo action name)&quot;, &quot;Undo action name&quot;);
</span><del>-        case EditActionDrag: return UI_STRING_KEY_INTERNAL(&quot;Drag&quot;, &quot;Drag (Undo action name)&quot;, &quot;Undo action name&quot;);
</del><ins>+        case EditActionDeleteByDrag: return UI_STRING_KEY_INTERNAL(&quot;Drag&quot;, &quot;Drag (Undo action name)&quot;, &quot;Undo action name&quot;);
</ins><span class="cx">         case EditActionCut: return UI_STRING_KEY_INTERNAL(&quot;Cut&quot;, &quot;Cut (Undo action name)&quot;, &quot;Undo action name&quot;);
</span><span class="cx">         case EditActionPaste: return UI_STRING_KEY_INTERNAL(&quot;Paste&quot;, &quot;Paste (Undo action name)&quot;, &quot;Undo action name&quot;);
</span><span class="cx">         case EditActionPasteFont: return UI_STRING_KEY_INTERNAL(&quot;Paste Font&quot;, &quot;Paste Font (Undo action name)&quot;, &quot;Undo action name&quot;);
</span></span></pre></div>
<a id="trunkSourceWebKitwinChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/win/ChangeLog (208013 => 208014)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/win/ChangeLog        2016-10-27 22:37:21 UTC (rev 208013)
+++ trunk/Source/WebKit/win/ChangeLog        2016-10-27 22:46:46 UTC (rev 208014)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2016-10-27  Wenson Hsieh  &lt;wenson_hsieh@apple.com&gt;
+
+        Support &quot;insertFromDrop&quot; and &quot;deleteByDrag&quot; for the InputEvent spec
+        https://bugs.webkit.org/show_bug.cgi?id=163948
+        &lt;rdar://problem/28921433&gt;
+
+        Reviewed by Darin Adler.
+
+        Add support for new drag and drop-related EditAction enum values.
+
+        * WebCoreSupport/WebEditorClient.cpp:
+        (undoNameForEditAction):
+
</ins><span class="cx"> 2016-10-26  Brian Burg  &lt;bburg@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: remove unused bool return value from FrontendChannel::sendMessageToFrontend
</span></span></pre></div>
<a id="trunkSourceWebKitwinWebCoreSupportWebEditorClientcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/win/WebCoreSupport/WebEditorClient.cpp (208013 => 208014)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/win/WebCoreSupport/WebEditorClient.cpp        2016-10-27 22:37:21 UTC (rev 208013)
+++ trunk/Source/WebKit/win/WebCoreSupport/WebEditorClient.cpp        2016-10-27 22:46:46 UTC (rev 208014)
</span><span class="lines">@@ -592,7 +592,7 @@
</span><span class="cx">     case EditActionUnderline: return WEB_UI_STRING_KEY(&quot;Underline&quot;, &quot;Underline (Undo action name)&quot;, &quot;Undo action name&quot;);
</span><span class="cx">     case EditActionOutline: return WEB_UI_STRING_KEY(&quot;Outline&quot;, &quot;Outline (Undo action name)&quot;, &quot;Undo action name&quot;);
</span><span class="cx">     case EditActionUnscript: return WEB_UI_STRING_KEY(&quot;Unscript&quot;, &quot;Unscript (Undo action name)&quot;, &quot;Undo action name&quot;);
</span><del>-    case EditActionDrag: return WEB_UI_STRING_KEY(&quot;Drag&quot;, &quot;Drag (Undo action name)&quot;, &quot;Undo action name&quot;);
</del><ins>+    case EditActionDeleteByDrag: return WEB_UI_STRING_KEY(&quot;Drag&quot;, &quot;Drag (Undo action name)&quot;, &quot;Undo action name&quot;);
</ins><span class="cx">     case EditActionCut: return WEB_UI_STRING_KEY(&quot;Cut&quot;, &quot;Cut (Undo action name)&quot;, &quot;Undo action name&quot;);
</span><span class="cx">     case EditActionPaste: return WEB_UI_STRING_KEY(&quot;Paste&quot;, &quot;Paste (Undo action name)&quot;, &quot;Undo action name&quot;);
</span><span class="cx">     case EditActionPasteFont: return WEB_UI_STRING_KEY(&quot;Paste Font&quot;, &quot;Paste Font (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 (208013 => 208014)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2016-10-27 22:37:21 UTC (rev 208013)
+++ trunk/Source/WebKit2/ChangeLog        2016-10-27 22:46:46 UTC (rev 208014)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2016-10-27  Wenson Hsieh  &lt;wenson_hsieh@apple.com&gt;
+
+        Support &quot;insertFromDrop&quot; and &quot;deleteByDrag&quot; for the InputEvent spec
+        https://bugs.webkit.org/show_bug.cgi?id=163948
+        &lt;rdar://problem/28921433&gt;
+
+        Reviewed by Darin Adler.
+
+        Add support for new drag and drop-related EditAction enum values.
+
+        * UIProcess/WebEditCommandProxy.cpp:
+        (WebKit::WebEditCommandProxy::nameForEditAction):
+
</ins><span class="cx"> 2016-10-26  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Replace IDBKeyPath with a WTF::Variant
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebEditCommandProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebEditCommandProxy.cpp (208013 => 208014)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebEditCommandProxy.cpp        2016-10-27 22:37:21 UTC (rev 208013)
+++ trunk/Source/WebKit2/UIProcess/WebEditCommandProxy.cpp        2016-10-27 22:46:46 UTC (rev 208014)
</span><span class="lines">@@ -73,10 +73,9 @@
</span><span class="cx">     // FIXME: This is identical to code in WebKit's WebEditorClient class; would be nice to share the strings instead of having two copies.
</span><span class="cx">     switch (editAction) {
</span><span class="cx">     case EditActionUnspecified:
</span><del>-        return String();
</del><span class="cx">     case EditActionInsert:
</span><del>-        return String();
</del><span class="cx">     case EditActionInsertReplacement:
</span><ins>+    case EditActionInsertFromDrop:
</ins><span class="cx">         return String();
</span><span class="cx">     case EditActionSetColor:
</span><span class="cx">         return WEB_UI_STRING_KEY(&quot;Set Color&quot;, &quot;Set Color (Undo action name)&quot;, &quot;Undo action name&quot;);
</span><span class="lines">@@ -126,7 +125,7 @@
</span><span class="cx">         return WEB_UI_STRING_KEY(&quot;Outline&quot;, &quot;Outline (Undo action name)&quot;, &quot;Undo action name&quot;);
</span><span class="cx">     case EditActionUnscript:
</span><span class="cx">         return WEB_UI_STRING_KEY(&quot;Unscript&quot;, &quot;Unscript (Undo action name)&quot;, &quot;Undo action name&quot;);
</span><del>-    case EditActionDrag:
</del><ins>+    case EditActionDeleteByDrag:
</ins><span class="cx">         return WEB_UI_STRING_KEY(&quot;Drag&quot;, &quot;Drag (Undo action name)&quot;, &quot;Undo action name&quot;);
</span><span class="cx">     case EditActionCut:
</span><span class="cx">         return WEB_UI_STRING_KEY(&quot;Cut&quot;, &quot;Cut (Undo action name)&quot;, &quot;Undo action name&quot;);
</span></span></pre>
</div>
</div>

</body>
</html>