<!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>[211471] 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/211471">211471</a></dd>
<dt>Author</dt> <dd>wenson_hsieh@apple.com</dd>
<dt>Date</dt> <dd>2017-01-31 23:46:31 -0800 (Tue, 31 Jan 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>Regression (Safari 10.1): Pressing Return in a contenteditable no longer inserts a line break under certain conditions
https://bugs.webkit.org/show_bug.cgi?id=167525
&lt;rdar://problem/30270210&gt;

Reviewed by Ryosuke Niwa.

Source/WebCore:

Test: fast/events/input-events-insert-newlines-after-mutation.html

Reverts an unintended change made while refactoring code for input events that caused input events to be
dispatched immediately rather than on the scoped queue. Normally, input events are dispatched in
CompositeEditCommand::apply after the end of the scope, but TypingCommands may fire input events *from within*
the scope by calling typingAddedToOpenCommand.

Instead, TypingCommands should always dispatch events
synchronously after the end of the scoped queue in CompositeEditCommand::apply, but this is a riskier change
than we should currently allow, so we should revert to our old behavior for the time being.

* editing/Editor.cpp:

LayoutTests:

Adds a new test covering newline insertion with mutation observers and an input event handler. Also rebaselines
a drag and drop test to account for dispatching input events on the scoped queue.

* fast/events/input-events-drag-and-drop-expected.txt:
* fast/events/input-events-insert-newlines-after-mutation-expected.txt: Added.
* fast/events/input-events-insert-newlines-after-mutation.html: Added.
* platform/ios-simulator/TestExpectations:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsfasteventsinputeventsdraganddropexpectedtxt">trunk/LayoutTests/fast/events/input-events-drag-and-drop-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="#trunkSourceWebCoreeditingEditorcpp">trunk/Source/WebCore/editing/Editor.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfasteventsinputeventsinsertnewlinesaftermutationexpectedtxt">trunk/LayoutTests/fast/events/input-events-insert-newlines-after-mutation-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfasteventsinputeventsinsertnewlinesaftermutationhtml">trunk/LayoutTests/fast/events/input-events-insert-newlines-after-mutation.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (211470 => 211471)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2017-02-01 06:07:51 UTC (rev 211470)
+++ trunk/LayoutTests/ChangeLog        2017-02-01 07:46:31 UTC (rev 211471)
</span><span class="lines">@@ -1,3 +1,19 @@
</span><ins>+2017-01-31  Wenson Hsieh  &lt;wenson_hsieh@apple.com&gt;
+
+        Regression (Safari 10.1): Pressing Return in a contenteditable no longer inserts a line break under certain conditions
+        https://bugs.webkit.org/show_bug.cgi?id=167525
+        &lt;rdar://problem/30270210&gt;
+
+        Reviewed by Ryosuke Niwa.
+
+        Adds a new test covering newline insertion with mutation observers and an input event handler. Also rebaselines
+        a drag and drop test to account for dispatching input events on the scoped queue.
+
+        * fast/events/input-events-drag-and-drop-expected.txt:
+        * fast/events/input-events-insert-newlines-after-mutation-expected.txt: Added.
+        * fast/events/input-events-insert-newlines-after-mutation.html: Added.
+        * platform/ios-simulator/TestExpectations:
+
</ins><span class="cx"> 2017-01-31  Ryan Haddad  &lt;ryanhaddad@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Marking gamepad/gamepad-visibility-1.html as flaky.
</span></span></pre></div>
<a id="trunkLayoutTestsfasteventsinputeventsdraganddropexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/events/input-events-drag-and-drop-expected.txt (211470 => 211471)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/events/input-events-drag-and-drop-expected.txt        2017-02-01 06:07:51 UTC (rev 211470)
+++ trunk/LayoutTests/fast/events/input-events-drag-and-drop-expected.txt        2017-02-01 07:46:31 UTC (rev 211471)
</span><span class="lines">@@ -3,8 +3,8 @@
</span><span class="cx"> 
</span><span class="cx"> Performing drag and drop
</span><span class="cx"> (source): type=beforeinput, inputType=deleteByDrag, data=`null`
</span><ins>+(destination): type=beforeinput, inputType=insertFromDrop, data=`Input events!`
</ins><span class="cx"> (source): type=input, inputType=deleteByDrag, data=`null`
</span><del>-(destination): type=beforeinput, inputType=insertFromDrop, data=`Input events!`
</del><span class="cx"> (destination): type=input, inputType=insertFromDrop, data=`Input events!`
</span><span class="cx"> 
</span><span class="cx"> Undoing drag and drop
</span></span></pre></div>
<a id="trunkLayoutTestsfasteventsinputeventsinsertnewlinesaftermutationexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/events/input-events-insert-newlines-after-mutation-expected.txt (0 => 211471)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/events/input-events-insert-newlines-after-mutation-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/events/input-events-insert-newlines-after-mutation-expected.txt        2017-02-01 07:46:31 UTC (rev 211471)
</span><span class="lines">@@ -0,0 +1,6 @@
</span><ins>+
+
+
+
+
+To manually test this, press enter multiple times in the editable area. Newlines should be inserted.
</ins></span></pre></div>
<a id="trunkLayoutTestsfasteventsinputeventsinsertnewlinesaftermutationhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/events/input-events-insert-newlines-after-mutation.html (0 => 211471)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/events/input-events-insert-newlines-after-mutation.html                                (rev 0)
+++ trunk/LayoutTests/fast/events/input-events-insert-newlines-after-mutation.html        2017-02-01 07:46:31 UTC (rev 211471)
</span><span class="lines">@@ -0,0 +1,52 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script&gt;
+    (() =&gt; {
+        addEventListener(&quot;input&quot;, () =&gt; { });
+        addEventListener(&quot;DOMContentLoaded&quot;, () =&gt; {
+            let editor = document.getElementById(&quot;editor&quot;);
+            function render() {
+                mutationObserver.disconnect();
+                editor.innerHTML = editor.innerHTML;
+                getSelection().collapse(editor.firstElementChild, 1);
+                mutationObserver.observe(editor, {
+                    childList: true,
+                    attributes: true,
+                    characterData: true,
+                    subtree: true
+                });
+            }
+
+            var mutationObserver = new MutationObserver(render);
+            editor.focus();
+            render();
+
+            function typeNewlines(remaining) {
+                if (!eventSender)
+                    return;
+
+                eventSender.keyDown(&quot;\n&quot;, []);
+                if (remaining == 0)
+                    testRunner.notifyDone();
+                else {
+                    setTimeout(() =&gt; {
+                        typeNewlines(remaining - 1);
+                    }, 100);
+                }
+            }
+
+            typeNewlines(3);
+        });
+    })();
+&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;div id=&quot;editor&quot; contenteditable&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;/div&gt;
+&lt;div&gt;To manually test this, press enter multiple times in the editable area. Newlines should be inserted.&lt;/div&gt;
+&lt;/body&gt;
+&lt;script&gt;
+    testRunner.dumpAsText();
+    testRunner.waitUntilDone();
+&lt;/script&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsplatformiossimulatorTestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/ios-simulator/TestExpectations (211470 => 211471)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/ios-simulator/TestExpectations        2017-02-01 06:07:51 UTC (rev 211470)
+++ trunk/LayoutTests/platform/ios-simulator/TestExpectations        2017-02-01 07:46:31 UTC (rev 211471)
</span><span class="lines">@@ -1233,6 +1233,7 @@
</span><span class="cx"> fast/events/input-events-paste-rich-datatransfer.html [ Failure ]
</span><span class="cx"> fast/events/input-events-spell-checking-datatransfer.html [ Failure ]
</span><span class="cx"> fast/events/input-events-selection-forecolor-data.html [ Failure ]
</span><ins>+fast/events/input-events-insert-newlines-after-mutation.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></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (211470 => 211471)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2017-02-01 06:07:51 UTC (rev 211470)
+++ trunk/Source/WebCore/ChangeLog        2017-02-01 07:46:31 UTC (rev 211471)
</span><span class="lines">@@ -1,3 +1,24 @@
</span><ins>+2017-01-31  Wenson Hsieh  &lt;wenson_hsieh@apple.com&gt;
+
+        Regression (Safari 10.1): Pressing Return in a contenteditable no longer inserts a line break under certain conditions
+        https://bugs.webkit.org/show_bug.cgi?id=167525
+        &lt;rdar://problem/30270210&gt;
+
+        Reviewed by Ryosuke Niwa.
+
+        Test: fast/events/input-events-insert-newlines-after-mutation.html
+
+        Reverts an unintended change made while refactoring code for input events that caused input events to be
+        dispatched immediately rather than on the scoped queue. Normally, input events are dispatched in
+        CompositeEditCommand::apply after the end of the scope, but TypingCommands may fire input events *from within*
+        the scope by calling typingAddedToOpenCommand.
+
+        Instead, TypingCommands should always dispatch events
+        synchronously after the end of the scoped queue in CompositeEditCommand::apply, but this is a riskier change
+        than we should currently allow, so we should revert to our old behavior for the time being.
+
+        * editing/Editor.cpp:
+
</ins><span class="cx"> 2017-01-31  Zalan Bujtas  &lt;zalan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Simple line layout: Do not assert on zero length/width trailing whitespace.
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingEditorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/Editor.cpp (211470 => 211471)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/Editor.cpp        2017-02-01 06:07:51 UTC (rev 211470)
+++ trunk/Source/WebCore/editing/Editor.cpp        2017-02-01 07:46:31 UTC (rev 211471)
</span><span class="lines">@@ -117,9 +117,13 @@
</span><span class="cx"> static void dispatchInputEvent(Element&amp; element, const AtomicString&amp; inputType, const String&amp; data = { }, RefPtr&lt;DataTransfer&gt;&amp;&amp; dataTransfer = nullptr, const Vector&lt;RefPtr&lt;StaticRange&gt;&gt;&amp; targetRanges = { })
</span><span class="cx"> {
</span><span class="cx">     auto* settings = element.document().settings();
</span><del>-    if (settings &amp;&amp; settings-&gt;inputEventsEnabled())
-        element.dispatchEvent(InputEvent::create(eventNames().inputEvent, inputType, true, false, element.document().defaultView(), data, WTFMove(dataTransfer), targetRanges, 0));
-    else
</del><ins>+    if (settings &amp;&amp; settings-&gt;inputEventsEnabled()) {
+        // FIXME: We should not be dispatching to the scoped queue here. Normally, input events are dispatched in CompositeEditCommand::apply after the end of the scope,
+        // but TypingCommands are special in that existing TypingCommands that are applied again fire input events *from within* the scope by calling typingAddedToOpenCommand.
+        // Instead, TypingCommands should always dispatch events synchronously after the end of the scoped queue in CompositeEditCommand::apply. To work around this for the
+        // time being, just revert back to calling dispatchScopedEvent.
+        element.dispatchScopedEvent(InputEvent::create(eventNames().inputEvent, inputType, true, false, element.document().defaultView(), data, WTFMove(dataTransfer), targetRanges, 0));
+    } else
</ins><span class="cx">         element.dispatchInputEvent();
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>