<!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>[208406] 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/208406">208406</a></dd>
<dt>Author</dt> <dd>wenson_hsieh@apple.com</dd>
<dt>Date</dt> <dd>2016-11-04 16:55:00 -0700 (Fri, 04 Nov 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Safari does not emit composition end if blurred for dead key / Japanese IME
https://bugs.webkit.org/show_bug.cgi?id=164369
&lt;rdar://problem/29050439&gt;

Reviewed by Ryosuke Niwa.

Source/WebCore:

On Mac, _before_ changing selection, try to finalize the composition by calling Editor::cancelComposition early.
This is because the focused element may have changed after performing the selection change, so we would
otherwise be dispatching the `compositionend` to the new focused element (or no compositionend at all) instead
of the element with the composition.

Doing this allows us to match Chrome and Firefox behavior. After canceling the composition, we then need to also
clear the system IME state. We do this on Mac WK1/WK2 through the cancelComposition() codepath, which ends up
calling into -discardMarkedText, which resets the marked text state. Some minor refactoring was performed to
accomplish this -- currently, discardedComposition sends a CompositionWasCanceled message over to the UI process
that discards the marked text, and then updates the editor state. This patch splits this into two separate
steps -- see the WebKit2 ChangeLog for more details.

Test: fast/events/ime-compositionend-on-selection-change.html

* editing/Editor.cpp:
(WebCore::Editor::selectionWillChange):
* editing/Editor.h:
* editing/FrameSelection.cpp:
(WebCore::FrameSelection::setSelectionWithoutUpdatingAppearance):
* editing/mac/EditorMac.mm:
(WebCore::Editor::selectionWillChange):
* loader/EmptyClients.h:
* page/EditorClient.h:

Source/WebKit/mac:

When canceling a composition, make sure that we clear the system IME state.

* WebCoreSupport/WebEditorClient.h:
* WebCoreSupport/WebEditorClient.mm:
(WebEditorClient::canceledComposition):

Source/WebKit/win:

Add a stub implementation of canceledComposition.

* WebCoreSupport/WebEditorClient.cpp:
(WebEditorClient::canceledComposition):
* WebCoreSupport/WebEditorClient.h:

Source/WebKit2:

Split WebPage::discardedComposition into two steps, where we first discard marked text and then update the
editor state. This allows the codepath where we cancel the composition early (before setting the selection) to
discard marked text without also forcing an editor state update at the same time. The editor state is later
updated in WebPage::didChangeSelection.

* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::compositionWasCanceled):
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:
* WebProcess/WebCoreSupport/WebEditorClient.cpp:
(WebKit::WebEditorClient::canceledComposition):
* WebProcess/WebCoreSupport/WebEditorClient.h:
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::didChangeSelection):
(WebKit::WebPage::discardedComposition):
(WebKit::WebPage::canceledComposition):
* WebProcess/WebPage/WebPage.h:

LayoutTests:

Adds a new test verifying that we dispatch `compositionend` events in various circumstances:
    1. After composing in an editable area and then focusing another editable area.
    2. After composing in an editable area and then blur()-ing.
    3. After composing in an editable area and then changing the selection.

There should be no behavior change for other platforms, so no new tests are needed there with this change.

* fast/events/ime-compositionend-on-selection-change-expected.txt: Added.
* fast/events/ime-compositionend-on-selection-change.html: Added.
* platform/ios-simulator/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="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreeditingEditorcpp">trunk/Source/WebCore/editing/Editor.cpp</a></li>
<li><a href="#trunkSourceWebCoreeditingEditorh">trunk/Source/WebCore/editing/Editor.h</a></li>
<li><a href="#trunkSourceWebCoreeditingFrameSelectioncpp">trunk/Source/WebCore/editing/FrameSelection.cpp</a></li>
<li><a href="#trunkSourceWebCoreeditingmacEditorMacmm">trunk/Source/WebCore/editing/mac/EditorMac.mm</a></li>
<li><a href="#trunkSourceWebCoreloaderEmptyClientsh">trunk/Source/WebCore/loader/EmptyClients.h</a></li>
<li><a href="#trunkSourceWebCorepageEditorClienth">trunk/Source/WebCore/page/EditorClient.h</a></li>
<li><a href="#trunkSourceWebKitmacChangeLog">trunk/Source/WebKit/mac/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitmacWebCoreSupportWebEditorClienth">trunk/Source/WebKit/mac/WebCoreSupport/WebEditorClient.h</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="#trunkSourceWebKitwinWebCoreSupportWebEditorClienth">trunk/Source/WebKit/win/WebCoreSupport/WebEditorClient.h</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebPageProxycpp">trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebPageProxyh">trunk/Source/WebKit2/UIProcess/WebPageProxy.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebPageProxymessagesin">trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebCoreSupportWebEditorClientcpp">trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.cpp</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebCoreSupportWebEditorClienth">trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.h</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageWebPagecpp">trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageWebPageh">trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfasteventsimecompositionendonselectionchangeexpectedtxt">trunk/LayoutTests/fast/events/ime-compositionend-on-selection-change-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfasteventsimecompositionendonselectionchangehtml">trunk/LayoutTests/fast/events/ime-compositionend-on-selection-change.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (208405 => 208406)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-11-04 23:27:19 UTC (rev 208405)
+++ trunk/LayoutTests/ChangeLog        2016-11-04 23:55:00 UTC (rev 208406)
</span><span class="lines">@@ -1,3 +1,22 @@
</span><ins>+2016-11-04  Wenson Hsieh  &lt;wenson_hsieh@apple.com&gt;
+
+        Safari does not emit composition end if blurred for dead key / Japanese IME
+        https://bugs.webkit.org/show_bug.cgi?id=164369
+        &lt;rdar://problem/29050439&gt;
+
+        Reviewed by Ryosuke Niwa.
+
+        Adds a new test verifying that we dispatch `compositionend` events in various circumstances:
+            1. After composing in an editable area and then focusing another editable area.
+            2. After composing in an editable area and then blur()-ing.
+            3. After composing in an editable area and then changing the selection.
+
+        There should be no behavior change for other platforms, so no new tests are needed there with this change.
+
+        * fast/events/ime-compositionend-on-selection-change-expected.txt: Added.
+        * fast/events/ime-compositionend-on-selection-change.html: Added.
+        * platform/ios-simulator/TestExpectations:
+
</ins><span class="cx"> 2016-11-04  Brady Eidson  &lt;beidson@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         IndexedDB 2.0: Clean up more transaction abort and exception throwing behavior from IDBObjectStore.
</span></span></pre></div>
<a id="trunkLayoutTestsfasteventsimecompositionendonselectionchangeexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/events/ime-compositionend-on-selection-change-expected.txt (0 => 208406)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/events/ime-compositionend-on-selection-change-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/events/ime-compositionend-on-selection-change-expected.txt        2016-11-04 23:55:00 UTC (rev 208406)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+To manually test, start editing a composition in the input field and focus the contenteditable without committing the composition. A compositionend event should be logged, with the event target being the input field. Next, insert a pending composition in the contenteditable and focus the input. A compositionend should be logged, with the event target being the contenteditable. Then insert a pending composition in the input field and focus the document. A compositionend event should be logged with the target being the input field. Lastly, insert a pending composition in the rich contenteditable and click and drag to select all the text in the contenteditable. A compositionend event should be fired on the contenteditable.
+
+
+defb
+
+1. Editing the plain input field
+Focusing the rich contenteditable
+PASS: Dispatched compositionend on &lt;INPUT id=&quot;plain&quot;&gt;
+
+2. Editing the rich contenteditable
+Focusing the plain input field
+PASS: Dispatched compositionend on &lt;DIV id=&quot;rich&quot;&gt;
+
+3. Editing the plain input field again
+Blurring the plain input field
+PASS: Dispatched compositionend on &lt;INPUT id=&quot;plain&quot;&gt;
+
+4. Editing the rich contenteditable again
+Changing selection within the rich contenteditable
+PASS: Dispatched compositionend on &lt;DIV id=&quot;rich&quot;&gt;
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfasteventsimecompositionendonselectionchangehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/events/ime-compositionend-on-selection-change.html (0 => 208406)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/events/ime-compositionend-on-selection-change.html                                (rev 0)
+++ trunk/LayoutTests/fast/events/ime-compositionend-on-selection-change.html        2016-11-04 23:55:00 UTC (rev 208406)
</span><span class="lines">@@ -0,0 +1,57 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;body&gt;
+    &lt;p&gt;To manually test, start editing a composition in the input field and focus the contenteditable without committing
+    the composition. A compositionend event should be logged, with the event target being the input field. Next, insert
+    a pending composition in the contenteditable and focus the input. A compositionend should be logged, with the event
+    target being the contenteditable. Then insert a pending composition in the input field and focus the document. A
+    compositionend event should be logged with the target being the input field. Lastly, insert a pending composition in
+    the rich contenteditable and click and drag to select all the text in the contenteditable. A compositionend event
+    should be fired on the contenteditable.&lt;/p&gt;
+    &lt;input id=&quot;plain&quot;&gt;&lt;/input&gt;
+    &lt;div id=&quot;rich&quot; contenteditable style=&quot;border: 1px dashed&quot;&gt;&lt;/div&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}&lt;br&gt;`;
+        plain.addEventListener(&quot;compositionend&quot;, logCompositionEnd);
+        rich.addEventListener(&quot;compositionend&quot;, logCompositionEnd);
+        plain.focus();
+
+        if (window.testRunner &amp;&amp; window.textInputController) {
+            testRunner.dumpAsText();
+
+            write(&quot;&quot;);
+            write(&quot;1. Editing the plain input field&quot;);
+            textInputController.setMarkedText(&quot;a&quot;, 1, 0);
+            write(&quot;   Focusing the rich contenteditable&quot;);
+            rich.focus();
+
+            write(&quot;&quot;);
+            write(&quot;2. Editing the rich contenteditable&quot;);
+            textInputController.setMarkedText(&quot;b&quot;, 1, 0);
+            write(&quot;   Focusing the plain input field&quot;);
+            plain.focus();
+
+            write(&quot;&quot;);
+            write(&quot;3. Editing the plain input field again&quot;);
+            textInputController.setMarkedText(&quot;c&quot;, 1, 0);
+            write(&quot;   Blurring the plain input field&quot;);
+            plain.blur();
+
+            write(&quot;&quot;);
+            write(&quot;4. Editing the rich contenteditable again&quot;);
+            rich.focus();
+            textInputController.setMarkedText(&quot;d&quot;, 1, 0);
+            textInputController.setMarkedText(&quot;de&quot;, 2, 0);
+            textInputController.setMarkedText(&quot;def&quot;, 3, 0);
+            write(&quot;   Changing selection within the rich contenteditable&quot;);
+            document.execCommand(&quot;SelectAll&quot;);
+        }
+
+        function logCompositionEnd(event)
+        {
+            write(`PASS: Dispatched compositionend on &amp;lt;${event.target.tagName} id=&quot;${event.target.id}&quot;&amp;gt;`);
+        }
+    &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 (208405 => 208406)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/ios-simulator/TestExpectations        2016-11-04 23:27:19 UTC (rev 208405)
+++ trunk/LayoutTests/platform/ios-simulator/TestExpectations        2016-11-04 23:55:00 UTC (rev 208406)
</span><span class="lines">@@ -1200,6 +1200,7 @@
</span><span class="cx"> fast/events/frame-scroll-fake-mouse-move.html [ Failure ]
</span><span class="cx"> fast/events/frame-tab-focus.html [ Failure ]
</span><span class="cx"> fast/events/ime-composition-events-001.html [ Failure ]
</span><ins>+fast/events/ime-compositionend-on-selection-change.html [ Failure ]
</ins><span class="cx"> fast/events/inputText-never-fired-on-keydown-cancel.html [ Failure ]
</span><span class="cx"> fast/events/input-events-drag-and-drop.html [ Failure ]
</span><span class="cx"> fast/events/input-events-insert-by-drop.html [ Failure ]
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (208405 => 208406)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-11-04 23:27:19 UTC (rev 208405)
+++ trunk/Source/WebCore/ChangeLog        2016-11-04 23:55:00 UTC (rev 208406)
</span><span class="lines">@@ -1,3 +1,35 @@
</span><ins>+2016-11-04  Wenson Hsieh  &lt;wenson_hsieh@apple.com&gt;
+
+        Safari does not emit composition end if blurred for dead key / Japanese IME
+        https://bugs.webkit.org/show_bug.cgi?id=164369
+        &lt;rdar://problem/29050439&gt;
+
+        Reviewed by Ryosuke Niwa.
+
+        On Mac, _before_ changing selection, try to finalize the composition by calling Editor::cancelComposition early.
+        This is because the focused element may have changed after performing the selection change, so we would
+        otherwise be dispatching the `compositionend` to the new focused element (or no compositionend at all) instead
+        of the element with the composition.
+
+        Doing this allows us to match Chrome and Firefox behavior. After canceling the composition, we then need to also
+        clear the system IME state. We do this on Mac WK1/WK2 through the cancelComposition() codepath, which ends up
+        calling into -discardMarkedText, which resets the marked text state. Some minor refactoring was performed to
+        accomplish this -- currently, discardedComposition sends a CompositionWasCanceled message over to the UI process
+        that discards the marked text, and then updates the editor state. This patch splits this into two separate
+        steps -- see the WebKit2 ChangeLog for more details.
+
+        Test: fast/events/ime-compositionend-on-selection-change.html
+
+        * editing/Editor.cpp:
+        (WebCore::Editor::selectionWillChange):
+        * editing/Editor.h:
+        * editing/FrameSelection.cpp:
+        (WebCore::FrameSelection::setSelectionWithoutUpdatingAppearance):
+        * editing/mac/EditorMac.mm:
+        (WebCore::Editor::selectionWillChange):
+        * loader/EmptyClients.h:
+        * page/EditorClient.h:
+
</ins><span class="cx"> 2016-11-04  Brady Eidson  &lt;beidson@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         IndexedDB 2.0: Clean up more transaction abort and exception throwing behavior from IDBObjectStore.
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingEditorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/Editor.cpp (208405 => 208406)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/Editor.cpp        2016-11-04 23:27:19 UTC (rev 208405)
+++ trunk/Source/WebCore/editing/Editor.cpp        2016-11-04 23:55:00 UTC (rev 208406)
</span><span class="lines">@@ -3244,6 +3244,12 @@
</span><span class="cx">     document().markers().repaintMarkers(DocumentMarker::TextMatch);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if !PLATFORM(MAC)
+void Editor::selectionWillChange()
+{
+}
+#endif
+
</ins><span class="cx"> void Editor::respondToChangedSelection(const VisibleSelection&amp;, FrameSelection::SetSelectionOptions options)
</span><span class="cx"> {
</span><span class="cx"> #if PLATFORM(IOS)
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingEditorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/Editor.h (208405 => 208406)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/Editor.h        2016-11-04 23:27:19 UTC (rev 208405)
+++ trunk/Source/WebCore/editing/Editor.h        2016-11-04 23:55:00 UTC (rev 208406)
</span><span class="lines">@@ -390,6 +390,7 @@
</span><span class="cx"> 
</span><span class="cx">     WEBCORE_EXPORT IntRect firstRectForRange(Range*) const;
</span><span class="cx"> 
</span><ins>+    void selectionWillChange();
</ins><span class="cx">     void respondToChangedSelection(const VisibleSelection&amp; oldSelection, FrameSelection::SetSelectionOptions);
</span><span class="cx">     WEBCORE_EXPORT void updateEditorUINowIfScheduled();
</span><span class="cx">     bool shouldChangeSelection(const VisibleSelection&amp; oldSelection, const VisibleSelection&amp; newSelection, EAffinity, bool stillSelecting) const;
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingFrameSelectioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/FrameSelection.cpp (208405 => 208406)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/FrameSelection.cpp        2016-11-04 23:27:19 UTC (rev 208405)
+++ trunk/Source/WebCore/editing/FrameSelection.cpp        2016-11-04 23:55:00 UTC (rev 208406)
</span><span class="lines">@@ -305,6 +305,10 @@
</span><span class="cx">         clearTypingStyle();
</span><span class="cx"> 
</span><span class="cx">     VisibleSelection oldSelection = m_selection;
</span><ins>+    bool didMutateSelection = oldSelection != newSelection;
+    if (didMutateSelection)
+        m_frame-&gt;editor().selectionWillChange();
+
</ins><span class="cx">     m_selection = newSelection;
</span><span class="cx"> 
</span><span class="cx">     // Selection offsets should increase when LF is inserted before the caret in InsertLineBreakCommand. See &lt;https://webkit.org/b/56061&gt;.
</span><span class="lines">@@ -311,7 +315,7 @@
</span><span class="cx">     if (HTMLTextFormControlElement* textControl = enclosingTextFormControl(newSelection.start()))
</span><span class="cx">         textControl-&gt;selectionChanged(options &amp; FireSelectEvent);
</span><span class="cx"> 
</span><del>-    if (oldSelection == newSelection)
</del><ins>+    if (!didMutateSelection)
</ins><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="cx">     setCaretRectNeedsUpdate();
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingmacEditorMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/mac/EditorMac.mm (208405 => 208406)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/mac/EditorMac.mm        2016-11-04 23:27:19 UTC (rev 208405)
+++ trunk/Source/WebCore/editing/mac/EditorMac.mm        2016-11-04 23:55:00 UTC (rev 208406)
</span><span class="lines">@@ -428,6 +428,15 @@
</span><span class="cx">     pasteboardURL.userVisibleForm = client()-&gt;userVisibleString(pasteboardURL.url);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void Editor::selectionWillChange()
+{
+    if (!hasComposition() || ignoreCompositionSelectionChange() || m_frame.selection().isNone())
+        return;
+
+    cancelComposition();
+    client()-&gt;canceledComposition();
+}
+
</ins><span class="cx"> String Editor::plainTextFromPasteboard(const PasteboardPlainText&amp; text)
</span><span class="cx"> {
</span><span class="cx">     String string = text.text;
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderEmptyClientsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/EmptyClients.h (208405 => 208406)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/EmptyClients.h        2016-11-04 23:27:19 UTC (rev 208405)
+++ trunk/Source/WebCore/loader/EmptyClients.h        2016-11-04 23:55:00 UTC (rev 208406)
</span><span class="lines">@@ -468,6 +468,7 @@
</span><span class="cx">     void didChangeSelectionAndUpdateLayout() override { }
</span><span class="cx">     void updateEditorStateAfterLayoutIfEditabilityChanged() override { }
</span><span class="cx">     void discardedComposition(Frame*) override { }
</span><ins>+    void canceledComposition() override { }
</ins><span class="cx">     void didEndEditing() override { }
</span><span class="cx">     void willWriteSelectionToPasteboard(Range*) override { }
</span><span class="cx">     void didWriteSelectionToPasteboard() override { }
</span></span></pre></div>
<a id="trunkSourceWebCorepageEditorClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/EditorClient.h (208405 => 208406)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/EditorClient.h        2016-11-04 23:27:19 UTC (rev 208405)
+++ trunk/Source/WebCore/page/EditorClient.h        2016-11-04 23:55:00 UTC (rev 208406)
</span><span class="lines">@@ -102,6 +102,7 @@
</span><span class="cx">     // Notify an input method that a composition was voluntarily discarded by WebCore, so that it could clean up too.
</span><span class="cx">     // This function is not called when a composition is closed per a request from an input method.
</span><span class="cx">     virtual void discardedComposition(Frame*) = 0;
</span><ins>+    virtual void canceledComposition() = 0;
</ins><span class="cx"> 
</span><span class="cx">     virtual void registerUndoStep(PassRefPtr&lt;UndoStep&gt;) = 0;
</span><span class="cx">     virtual void registerRedoStep(PassRefPtr&lt;UndoStep&gt;) = 0;
</span></span></pre></div>
<a id="trunkSourceWebKitmacChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/ChangeLog (208405 => 208406)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/ChangeLog        2016-11-04 23:27:19 UTC (rev 208405)
+++ trunk/Source/WebKit/mac/ChangeLog        2016-11-04 23:55:00 UTC (rev 208406)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2016-11-04  Wenson Hsieh  &lt;wenson_hsieh@apple.com&gt;
+
+        Safari does not emit composition end if blurred for dead key / Japanese IME
+        https://bugs.webkit.org/show_bug.cgi?id=164369
+        &lt;rdar://problem/29050439&gt;
+
+        Reviewed by Ryosuke Niwa.
+
+        When canceling a composition, make sure that we clear the system IME state.
+
+        * WebCoreSupport/WebEditorClient.h:
+        * WebCoreSupport/WebEditorClient.mm:
+        (WebEditorClient::canceledComposition):
+
</ins><span class="cx"> 2016-11-04  Said Abou-Hallawa  &lt;sabouhallawa@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Add a setting and preferences to enable/disable async image decoding
</span></span></pre></div>
<a id="trunkSourceWebKitmacWebCoreSupportWebEditorClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/WebCoreSupport/WebEditorClient.h (208405 => 208406)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/WebCoreSupport/WebEditorClient.h        2016-11-04 23:27:19 UTC (rev 208405)
+++ trunk/Source/WebKit/mac/WebCoreSupport/WebEditorClient.h        2016-11-04 23:55:00 UTC (rev 208406)
</span><span class="lines">@@ -113,6 +113,7 @@
</span><span class="cx">     void didChangeSelectionAndUpdateLayout() final { }
</span><span class="cx">     void updateEditorStateAfterLayoutIfEditabilityChanged() final;
</span><span class="cx">     void discardedComposition(WebCore::Frame*) final;
</span><ins>+    void canceledComposition() final;
</ins><span class="cx"> 
</span><span class="cx">     void registerUndoStep(PassRefPtr&lt;WebCore::UndoStep&gt;) final;
</span><span class="cx">     void registerRedoStep(PassRefPtr&lt;WebCore::UndoStep&gt;) final;
</span></span></pre></div>
<a id="trunkSourceWebKitmacWebCoreSupportWebEditorClientmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/WebCoreSupport/WebEditorClient.mm (208405 => 208406)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/WebCoreSupport/WebEditorClient.mm        2016-11-04 23:27:19 UTC (rev 208405)
+++ trunk/Source/WebKit/mac/WebCoreSupport/WebEditorClient.mm        2016-11-04 23:55:00 UTC (rev 208406)
</span><span class="lines">@@ -375,6 +375,13 @@
</span><span class="cx">     // The effects of this function are currently achieved via -[WebHTMLView _updateSelectionForInputManager].
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebEditorClient::canceledComposition()
+{
+#if !PLATFORM(IOS)
+    [[NSTextInputContext currentInputContext] discardMarkedText];
+#endif
+}
+
</ins><span class="cx"> void WebEditorClient::didEndEditing()
</span><span class="cx"> {
</span><span class="cx"> #if !PLATFORM(IOS)
</span></span></pre></div>
<a id="trunkSourceWebKitwinChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/win/ChangeLog (208405 => 208406)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/win/ChangeLog        2016-11-04 23:27:19 UTC (rev 208405)
+++ trunk/Source/WebKit/win/ChangeLog        2016-11-04 23:55:00 UTC (rev 208406)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2016-11-04  Wenson Hsieh  &lt;wenson_hsieh@apple.com&gt;
+
+        Safari does not emit composition end if blurred for dead key / Japanese IME
+        https://bugs.webkit.org/show_bug.cgi?id=164369
+        &lt;rdar://problem/29050439&gt;
+
+        Reviewed by Ryosuke Niwa.
+
+        Add a stub implementation of canceledComposition.
+
+        * WebCoreSupport/WebEditorClient.cpp:
+        (WebEditorClient::canceledComposition):
+        * WebCoreSupport/WebEditorClient.h:
+
</ins><span class="cx"> 2016-11-04  Per Arne Vollan  &lt;pvollan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [Win] Page visibility tests are timing out.
</span></span></pre></div>
<a id="trunkSourceWebKitwinWebCoreSupportWebEditorClientcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/win/WebCoreSupport/WebEditorClient.cpp (208405 => 208406)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/win/WebCoreSupport/WebEditorClient.cpp        2016-11-04 23:27:19 UTC (rev 208405)
+++ trunk/Source/WebKit/win/WebCoreSupport/WebEditorClient.cpp        2016-11-04 23:55:00 UTC (rev 208406)
</span><span class="lines">@@ -242,6 +242,11 @@
</span><span class="cx">     notImplemented();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebEditorClient::canceledComposition()
+{
+    notImplemented();
+}
+
</ins><span class="cx"> void WebEditorClient::didEndEditing()
</span><span class="cx"> {
</span><span class="cx">     static _bstr_t webViewDidEndEditingNotificationName(WebViewDidEndEditingNotification);
</span></span></pre></div>
<a id="trunkSourceWebKitwinWebCoreSupportWebEditorClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/win/WebCoreSupport/WebEditorClient.h (208405 => 208406)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/win/WebCoreSupport/WebEditorClient.h        2016-11-04 23:27:19 UTC (rev 208405)
+++ trunk/Source/WebKit/win/WebCoreSupport/WebEditorClient.h        2016-11-04 23:55:00 UTC (rev 208406)
</span><span class="lines">@@ -58,6 +58,7 @@
</span><span class="cx">     virtual void respondToChangedSelection(WebCore::Frame*);
</span><span class="cx">     void didChangeSelectionAndUpdateLayout() final { }
</span><span class="cx">     void updateEditorStateAfterLayoutIfEditabilityChanged() final { } 
</span><ins>+    void canceledComposition() final;
</ins><span class="cx">     void discardedComposition(WebCore::Frame*) final;
</span><span class="cx"> 
</span><span class="cx">     bool shouldDeleteRange(WebCore::Range*);
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (208405 => 208406)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2016-11-04 23:27:19 UTC (rev 208405)
+++ trunk/Source/WebKit2/ChangeLog        2016-11-04 23:55:00 UTC (rev 208406)
</span><span class="lines">@@ -1,3 +1,29 @@
</span><ins>+2016-11-04  Wenson Hsieh  &lt;wenson_hsieh@apple.com&gt;
+
+        Safari does not emit composition end if blurred for dead key / Japanese IME
+        https://bugs.webkit.org/show_bug.cgi?id=164369
+        &lt;rdar://problem/29050439&gt;
+
+        Reviewed by Ryosuke Niwa.
+
+        Split WebPage::discardedComposition into two steps, where we first discard marked text and then update the
+        editor state. This allows the codepath where we cancel the composition early (before setting the selection) to
+        discard marked text without also forcing an editor state update at the same time. The editor state is later
+        updated in WebPage::didChangeSelection.
+
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::compositionWasCanceled):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.messages.in:
+        * WebProcess/WebCoreSupport/WebEditorClient.cpp:
+        (WebKit::WebEditorClient::canceledComposition):
+        * WebProcess/WebCoreSupport/WebEditorClient.h:
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::didChangeSelection):
+        (WebKit::WebPage::discardedComposition):
+        (WebKit::WebPage::canceledComposition):
+        * WebProcess/WebPage/WebPage.h:
+
</ins><span class="cx"> 2016-11-04  Alex Christensen  &lt;achristensen@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, rolling out r208293.
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp (208405 => 208406)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp        2016-11-04 23:27:19 UTC (rev 208405)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp        2016-11-04 23:55:00 UTC (rev 208406)
</span><span class="lines">@@ -4379,12 +4379,11 @@
</span><span class="cx">     count = m_backForwardList-&gt;forwardListCount();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebPageProxy::compositionWasCanceled(const EditorState&amp; editorState)
</del><ins>+void WebPageProxy::compositionWasCanceled()
</ins><span class="cx"> {
</span><span class="cx"> #if PLATFORM(COCOA)
</span><span class="cx">     m_pageClient.notifyInputContextAboutDiscardedComposition();
</span><span class="cx"> #endif
</span><del>-    editorStateChanged(editorState);
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // Undo management
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.h (208405 => 208406)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.h        2016-11-04 23:27:19 UTC (rev 208405)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.h        2016-11-04 23:55:00 UTC (rev 208406)
</span><span class="lines">@@ -1320,7 +1320,7 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     void editorStateChanged(const EditorState&amp;);
</span><del>-    void compositionWasCanceled(const EditorState&amp;);
</del><ins>+    void compositionWasCanceled();
</ins><span class="cx">     void setHasHadSelectionChangesFromUserInteraction(bool);
</span><span class="cx">     void setNeedsHiddenContentEditableQuirk(bool);
</span><span class="cx">     void setNeedsPlainTextQuirk(bool);
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxymessagesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in (208405 => 208406)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in        2016-11-04 23:27:19 UTC (rev 208405)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in        2016-11-04 23:55:00 UTC (rev 208406)
</span><span class="lines">@@ -240,7 +240,7 @@
</span><span class="cx"> 
</span><span class="cx">     # Editor notifications
</span><span class="cx">     EditorStateChanged(struct WebKit::EditorState editorState)
</span><del>-    CompositionWasCanceled(struct WebKit::EditorState editorState)
</del><ins>+    CompositionWasCanceled()
</ins><span class="cx">     SetHasHadSelectionChangesFromUserInteraction(bool hasHadUserSelectionChanges)
</span><span class="cx">     SetNeedsHiddenContentEditableQuirk(bool needsHiddenContentEditableQuirk)
</span><span class="cx">     SetNeedsPlainTextQuirk(bool needsPlainTextQuirk)
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebCoreSupportWebEditorClientcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.cpp (208405 => 208406)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.cpp        2016-11-04 23:27:19 UTC (rev 208405)
+++ trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.cpp        2016-11-04 23:55:00 UTC (rev 208406)
</span><span class="lines">@@ -211,6 +211,11 @@
</span><span class="cx">     m_page-&gt;discardedComposition();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebEditorClient::canceledComposition()
+{
+    m_page-&gt;canceledComposition();
+}
+
</ins><span class="cx"> void WebEditorClient::didEndEditing()
</span><span class="cx"> {
</span><span class="cx">     static NeverDestroyed&lt;String&gt; WebViewDidEndEditingNotification(ASCIILiteral(&quot;WebViewDidEndEditingNotification&quot;));
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebCoreSupportWebEditorClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.h (208405 => 208406)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.h        2016-11-04 23:27:19 UTC (rev 208405)
+++ trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.h        2016-11-04 23:55:00 UTC (rev 208406)
</span><span class="lines">@@ -65,6 +65,7 @@
</span><span class="cx">     void didChangeSelectionAndUpdateLayout() final;
</span><span class="cx">     void updateEditorStateAfterLayoutIfEditabilityChanged() final;
</span><span class="cx">     void discardedComposition(WebCore::Frame*) final;
</span><ins>+    void canceledComposition() final;
</ins><span class="cx">     void didEndEditing() final;
</span><span class="cx">     void willWriteSelectionToPasteboard(WebCore::Range*) final;
</span><span class="cx">     void didWriteSelectionToPasteboard() final;
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebPagecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp (208405 => 208406)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp        2016-11-04 23:27:19 UTC (rev 208405)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp        2016-11-04 23:55:00 UTC (rev 208406)
</span><span class="lines">@@ -4898,7 +4898,7 @@
</span><span class="cx">     // FIXME: We can't cancel composition when selection changes to NoSelection, but we probably should.
</span><span class="cx">     if (frame.editor().hasComposition() &amp;&amp; !frame.editor().ignoreCompositionSelectionChange() &amp;&amp; !frame.selection().isNone()) {
</span><span class="cx">         frame.editor().cancelComposition();
</span><del>-        send(Messages::WebPageProxy::CompositionWasCanceled(editorState));
</del><ins>+        discardedComposition();
</ins><span class="cx">     } else
</span><span class="cx">         send(Messages::WebPageProxy::EditorStateChanged(editorState));
</span><span class="cx"> #else
</span><span class="lines">@@ -4983,9 +4983,15 @@
</span><span class="cx"> 
</span><span class="cx"> void WebPage::discardedComposition()
</span><span class="cx"> {
</span><del>-    send(Messages::WebPageProxy::CompositionWasCanceled(editorState()));
</del><ins>+    send(Messages::WebPageProxy::CompositionWasCanceled());
+    send(Messages::WebPageProxy::EditorStateChanged(editorState()));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebPage::canceledComposition()
+{
+    send(Messages::WebPageProxy::CompositionWasCanceled());
+}
+
</ins><span class="cx"> void WebPage::setMinimumLayoutSize(const IntSize&amp; minimumLayoutSize)
</span><span class="cx"> {
</span><span class="cx">     if (m_minimumLayoutSize == minimumLayoutSize)
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebPageh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h (208405 => 208406)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h        2016-11-04 23:27:19 UTC (rev 208405)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h        2016-11-04 23:55:00 UTC (rev 208406)
</span><span class="lines">@@ -659,6 +659,7 @@
</span><span class="cx">     void didApplyStyle();
</span><span class="cx">     void didChangeSelection();
</span><span class="cx">     void discardedComposition();
</span><ins>+    void canceledComposition();
</ins><span class="cx"> 
</span><span class="cx"> #if PLATFORM(COCOA)
</span><span class="cx">     void registerUIProcessAccessibilityTokens(const IPC::DataReference&amp; elemenToken, const IPC::DataReference&amp; windowToken);
</span></span></pre>
</div>
</div>

</body>
</html>