<!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>[195002] 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/195002">195002</a></dd>
<dt>Author</dt> <dd>bdakin@apple.com</dd>
<dt>Date</dt> <dd>2016-01-13 17:03:01 -0800 (Wed, 13 Jan 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>WK2: Request completion candidates when needed
https://bugs.webkit.org/show_bug.cgi?id=153040
-and corresponding-
rdar://problem/24155631

Reviewed by Enrica Casucci.

Source/WebCore:

Helper functions for stringForCandidateRequest() and 
handleAcceptedCandidate()
* editing/Editor.cpp:
(WebCore::candidateRangeForSelection):
(WebCore::candidateWouldReplaceText):

Request candidates for the word that is currently being typed so long as the 
candidate would replace that word. Otherwise, use String().
(WebCore::Editor::stringForCandidateRequest):

When a candidate has been accepted, insert the text.
(WebCore::Editor::handleAcceptedCandidate):
* editing/Editor.h:

Source/WebKit2:

Mac needs to support postLayoutData in order to have some layout-related 
editing information to request candidates. This patch re-shuffles some items 
in the struct so that they can be shared by Mac and iOS, and it adds 3 new 
items for Mac only.
* Shared/EditorState.cpp:
(WebKit::EditorState::encode):
(WebKit::EditorState::decode):
(WebKit::EditorState::PostLayoutData::encode):
(WebKit::EditorState::PostLayoutData::decode):
* Shared/EditorState.h:

Request and handle candidates here in WebViewImpl, and cache the 
m_lastStringForCandidateRequest so that we can ensure the results we receive 
were received in a timely enough manner that they are still for the same 
String.
* UIProcess/Cocoa/WebViewImpl.h:
* UIProcess/Cocoa/WebViewImpl.mm:
(WebKit::WebViewImpl::selectionDidChange):

When selection changes, request new candidates.
(WebKit::WebViewImpl::requestCandidatesForSelectionIfNeeded):

Once candidates have been received, we ask the sharedSpellChecker to show 
them.
(WebKit::WebViewImpl::handleRequestedCandidates):

If a candidate is accepted, we ask the WebProcess to accept it, so we start 
by converting the NSTextCheckingResult to a WebCore::TextCheckingResult.
(WebKit::textCheckingResultFromNSTextCheckingResult):
(WebKit::WebViewImpl::handleAcceptedCandidate):

Ask the WebProcess to handle accepting the candidate.
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::handleAcceptedCandidate):
* UIProcess/WebPageProxy.h:
* WebProcess/WebPage/WebPage.h:
(WebKit::WebPage:: handleAcceptedCandidate):
* WebProcess/WebPage/WebPage.messages.in:

Now that Mac has some postLayoutData in the EditorState, fill that in in 
platformEditorState().
* WebProcess/WebPage/mac/WebPageMac.mm:
(WebKit::WebPage::platformEditorState):

Ask WebCore::Editor to handle the accepted candidate.
(WebKit::WebPage::handleAcceptedCandidate):

LayoutTests:

Getting updated EditorState in platformEditorState causes some extra layout 
to happen, so now the layout test results for WK2 reflect the results that we 
already see on iOS for this test and they reflect the render tree as it is 
when you load the page in browser.
* platform/mac/fast/dom/focus-contenteditable-expected.txt:

WebKit 1 is not affected by these new results, so this adds WK-1 only results 
that match the old Mac results.
* platform/mac-wk1/fast/dom: Added.
* platform/mac-wk1/fast/dom/focus-contenteditable-expected.txt: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsplatformmacfastdomfocuscontenteditableexpectedtxt">trunk/LayoutTests/platform/mac/fast/dom/focus-contenteditable-expected.txt</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="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2SharedEditorStatecpp">trunk/Source/WebKit2/Shared/EditorState.cpp</a></li>
<li><a href="#trunkSourceWebKit2SharedEditorStateh">trunk/Source/WebKit2/Shared/EditorState.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessCocoaWebViewImplh">trunk/Source/WebKit2/UIProcess/Cocoa/WebViewImpl.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessCocoaWebViewImplmm">trunk/Source/WebKit2/UIProcess/Cocoa/WebViewImpl.mm</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="#trunkSourceWebKit2WebProcessWebPageWebPageh">trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageWebPagemessagesin">trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPagemacWebPageMacmm">trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li>trunk/LayoutTests/platform/mac-wk1/fast/dom/</li>
<li><a href="#trunkLayoutTestsplatformmacwk1fastdomfocuscontenteditableexpectedtxt">trunk/LayoutTests/platform/mac-wk1/fast/dom/focus-contenteditable-expected.txt</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (195001 => 195002)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-01-14 00:29:55 UTC (rev 195001)
+++ trunk/LayoutTests/ChangeLog        2016-01-14 01:03:01 UTC (rev 195002)
</span><span class="lines">@@ -1,3 +1,23 @@
</span><ins>+2016-01-13  Beth Dakin  &lt;bdakin@apple.com&gt;
+
+        WK2: Request completion candidates when needed
+        https://bugs.webkit.org/show_bug.cgi?id=153040
+        -and corresponding-
+        rdar://problem/24155631
+
+        Reviewed by Enrica Casucci.
+
+        Getting updated EditorState in platformEditorState causes some extra layout 
+        to happen, so now the layout test results for WK2 reflect the results that we 
+        already see on iOS for this test and they reflect the render tree as it is 
+        when you load the page in browser.
+        * platform/mac/fast/dom/focus-contenteditable-expected.txt:
+
+        WebKit 1 is not affected by these new results, so this adds WK-1 only results 
+        that match the old Mac results.
+        * platform/mac-wk1/fast/dom: Added.
+        * platform/mac-wk1/fast/dom/focus-contenteditable-expected.txt: Added.
+
</ins><span class="cx"> 2016-01-12  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         formaction must return document's address when formaction is missing
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmacfastdomfocuscontenteditableexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac/fast/dom/focus-contenteditable-expected.txt (195001 => 195002)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac/fast/dom/focus-contenteditable-expected.txt        2016-01-14 00:29:55 UTC (rev 195001)
+++ trunk/LayoutTests/platform/mac/fast/dom/focus-contenteditable-expected.txt        2016-01-14 01:03:01 UTC (rev 195002)
</span><span class="lines">@@ -6,7 +6,7 @@
</span><span class="cx">       RenderBlock (anonymous) at (0,0) size 769x36
</span><span class="cx">         RenderText {#text} at (0,0) size 509x18
</span><span class="cx">           text run at (0,0) width 509: &quot;This test will try to call focus() on a contenteditable div, and then a normal div. &quot;
</span><del>-        RenderBR {BR} at (508,14) size 1x0
</del><ins>+        RenderBR {BR} at (0,0) size 0x0
</ins><span class="cx">         RenderText {#text} at (0,18) size 379x18
</span><span class="cx">           text run at (0,18) width 379: &quot;The window should scroll to reveal the contenteditable div.&quot;
</span><span class="cx">       RenderBlock {DIV} at (0,36) size 500x800
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmacwk1fastdomfocuscontenteditableexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/platform/mac-wk1/fast/dom/focus-contenteditable-expected.txt (0 => 195002)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac-wk1/fast/dom/focus-contenteditable-expected.txt                                (rev 0)
+++ trunk/LayoutTests/platform/mac-wk1/fast/dom/focus-contenteditable-expected.txt        2016-01-14 01:03:01 UTC (rev 195002)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+layer at (0,0) size 785x894
+  RenderView at (0,0) size 785x600
+layer at (0,0) size 785x894
+  RenderBlock {HTML} at (0,0) size 785x894
+    RenderBody {BODY} at (8,8) size 769x878
+      RenderBlock (anonymous) at (0,0) size 769x36
+        RenderText {#text} at (0,0) size 509x18
+          text run at (0,0) width 509: &quot;This test will try to call focus() on a contenteditable div, and then a normal div. &quot;
+        RenderBR {BR} at (508,14) size 1x0
+        RenderText {#text} at (0,18) size 379x18
+          text run at (0,18) width 379: &quot;The window should scroll to reveal the contenteditable div.&quot;
+      RenderBlock {DIV} at (0,36) size 500x800
+      RenderBlock {DIV} at (0,836) size 769x24 [border: (3px solid #000000)]
+        RenderText {#text} at (3,3) size 125x18
+          text run at (3,3) width 125: &quot;contentEditable div&quot;
+      RenderBlock {DIV} at (0,860) size 769x18
+        RenderText {#text} at (0,0) size 78x18
+          text run at (0,0) width 78: &quot;Test Passed.&quot;
+      RenderBlock {DIV} at (0,878) size 769x0
+caret: position 0 of child 0 {#text} of child 5 {DIV} of body
+scrolled to 0,276
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (195001 => 195002)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-01-14 00:29:55 UTC (rev 195001)
+++ trunk/Source/WebCore/ChangeLog        2016-01-14 01:03:01 UTC (rev 195002)
</span><span class="lines">@@ -1,3 +1,26 @@
</span><ins>+2016-01-13  Beth Dakin  &lt;bdakin@apple.com&gt;
+
+        WK2: Request completion candidates when needed
+        https://bugs.webkit.org/show_bug.cgi?id=153040
+        -and corresponding-
+        rdar://problem/24155631
+
+        Reviewed by Enrica Casucci.
+
+        Helper functions for stringForCandidateRequest() and 
+        handleAcceptedCandidate()
+        * editing/Editor.cpp:
+        (WebCore::candidateRangeForSelection):
+        (WebCore::candidateWouldReplaceText):
+
+        Request candidates for the word that is currently being typed so long as the 
+        candidate would replace that word. Otherwise, use String().
+        (WebCore::Editor::stringForCandidateRequest):
+
+        When a candidate has been accepted, insert the text.
+        (WebCore::Editor::handleAcceptedCandidate):
+        * editing/Editor.h:
+
</ins><span class="cx"> 2016-01-13  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Addressing post-review comments after r194566
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingEditorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/Editor.cpp (195001 => 195002)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/Editor.cpp        2016-01-14 00:29:55 UTC (rev 195001)
+++ trunk/Source/WebCore/editing/Editor.cpp        2016-01-14 01:03:01 UTC (rev 195002)
</span><span class="lines">@@ -3533,6 +3533,43 @@
</span><span class="cx">     return checkingTypes;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static RefPtr&lt;Range&gt; candidateRangeForSelection(Frame&amp; frame)
+{
+    const VisibleSelection&amp; selection = frame.selection().selection();
+    return selection.isCaret() ? wordRangeFromPosition(selection.start()) : frame.selection().toNormalizedRange();
+}
+
+static bool candidateWouldReplaceText(const VisibleSelection&amp; selection)
+{
+    // If the character behind the caret in the current selection is anything but a space or a newline then we should
+    // replace the whole current word with the candidate.
+    UChar32 characterAfterSelection, characterBeforeSelection, twoCharacterBeforeSelection = 0;
+    charactersAroundPosition(selection.visibleStart(), characterAfterSelection, characterBeforeSelection, twoCharacterBeforeSelection);
+    return !(characterBeforeSelection == '\0' || characterBeforeSelection == '\n' || characterBeforeSelection == ' ');
+}
+
+String Editor::stringForCandidateRequest() const
+{
+    const VisibleSelection&amp; selection = m_frame.selection().selection();
+    RefPtr&lt;Range&gt; rangeForCurrentlyTypedString = candidateRangeForSelection(m_frame);
+    if (rangeForCurrentlyTypedString &amp;&amp; candidateWouldReplaceText(selection))
+        return plainText(rangeForCurrentlyTypedString.get());
+
+    return String();
+}
+
+void Editor::handleAcceptedCandidate(TextCheckingResult acceptedCandidate)
+{
+    const VisibleSelection&amp; selection = m_frame.selection().selection();
+    RefPtr&lt;Range&gt; candidateRange = candidateRangeForSelection(m_frame);
+
+    if (candidateWouldReplaceText(selection))
+        m_frame.selection().setSelectedRange(candidateRange.get(), UPSTREAM, true);
+
+    insertText(acceptedCandidate.replacement, 0);
+    insertText(String(&quot; &quot;), 0);
+}
+
</ins><span class="cx"> bool Editor::unifiedTextCheckerEnabled() const
</span><span class="cx"> {
</span><span class="cx">     return WebCore::unifiedTextCheckerEnabled(&amp;m_frame);
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingEditorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/Editor.h (195001 => 195002)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/Editor.h        2016-01-14 00:29:55 UTC (rev 195001)
+++ trunk/Source/WebCore/editing/Editor.h        2016-01-14 01:03:01 UTC (rev 195002)
</span><span class="lines">@@ -455,6 +455,9 @@
</span><span class="cx">     const Vector&lt;RefPtr&lt;Range&gt;&gt;&amp; detectedTelephoneNumberRanges() const { return m_detectedTelephoneNumberRanges; }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+    WEBCORE_EXPORT String stringForCandidateRequest() const;
+    WEBCORE_EXPORT void handleAcceptedCandidate(TextCheckingResult);
+
</ins><span class="cx"> private:
</span><span class="cx">     class WebContentReader;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (195001 => 195002)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2016-01-14 00:29:55 UTC (rev 195001)
+++ trunk/Source/WebKit2/ChangeLog        2016-01-14 01:03:01 UTC (rev 195002)
</span><span class="lines">@@ -1,3 +1,59 @@
</span><ins>+2016-01-13  Beth Dakin  &lt;bdakin@apple.com&gt;
+
+        WK2: Request completion candidates when needed
+        https://bugs.webkit.org/show_bug.cgi?id=153040
+        -and corresponding-
+        rdar://problem/24155631
+
+        Reviewed by Enrica Casucci.
+
+        Mac needs to support postLayoutData in order to have some layout-related 
+        editing information to request candidates. This patch re-shuffles some items 
+        in the struct so that they can be shared by Mac and iOS, and it adds 3 new 
+        items for Mac only.
+        * Shared/EditorState.cpp:
+        (WebKit::EditorState::encode):
+        (WebKit::EditorState::decode):
+        (WebKit::EditorState::PostLayoutData::encode):
+        (WebKit::EditorState::PostLayoutData::decode):
+        * Shared/EditorState.h:
+
+        Request and handle candidates here in WebViewImpl, and cache the 
+        m_lastStringForCandidateRequest so that we can ensure the results we receive 
+        were received in a timely enough manner that they are still for the same 
+        String.
+        * UIProcess/Cocoa/WebViewImpl.h:
+        * UIProcess/Cocoa/WebViewImpl.mm:
+        (WebKit::WebViewImpl::selectionDidChange):
+
+        When selection changes, request new candidates.
+        (WebKit::WebViewImpl::requestCandidatesForSelectionIfNeeded):
+
+        Once candidates have been received, we ask the sharedSpellChecker to show 
+        them.
+        (WebKit::WebViewImpl::handleRequestedCandidates):
+
+        If a candidate is accepted, we ask the WebProcess to accept it, so we start 
+        by converting the NSTextCheckingResult to a WebCore::TextCheckingResult.
+        (WebKit::textCheckingResultFromNSTextCheckingResult):
+        (WebKit::WebViewImpl::handleAcceptedCandidate):
+
+        Ask the WebProcess to handle accepting the candidate.
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::handleAcceptedCandidate):
+        * UIProcess/WebPageProxy.h:
+        * WebProcess/WebPage/WebPage.h:
+        (WebKit::WebPage:: handleAcceptedCandidate):
+        * WebProcess/WebPage/WebPage.messages.in:
+
+        Now that Mac has some postLayoutData in the EditorState, fill that in in 
+        platformEditorState().
+        * WebProcess/WebPage/mac/WebPageMac.mm:
+        (WebKit::WebPage::platformEditorState):
+
+        Ask WebCore::Editor to handle the accepted candidate.
+        (WebKit::WebPage::handleAcceptedCandidate):
+
</ins><span class="cx"> 2016-01-12  Geoffrey Garen  &lt;ggaren@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         WebKit2 should have an API for eagerly querying whether the web process is responsive
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedEditorStatecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/EditorState.cpp (195001 => 195002)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/EditorState.cpp        2016-01-14 00:29:55 UTC (rev 195001)
+++ trunk/Source/WebKit2/Shared/EditorState.cpp        2016-01-14 01:03:01 UTC (rev 195002)
</span><span class="lines">@@ -43,7 +43,7 @@
</span><span class="cx">     encoder &lt;&lt; hasComposition;
</span><span class="cx">     encoder &lt;&lt; isMissingPostLayoutData;
</span><span class="cx"> 
</span><del>-#if PLATFORM(IOS) || PLATFORM(GTK)
</del><ins>+#if PLATFORM(IOS) || PLATFORM(GTK) || PLATFORM(MAC)
</ins><span class="cx">     if (!isMissingPostLayoutData)
</span><span class="cx">         m_postLayoutData.encode(encoder);
</span><span class="cx"> #endif
</span><span class="lines">@@ -84,7 +84,7 @@
</span><span class="cx">     if (!decoder.decode(result.isMissingPostLayoutData))
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><del>-#if PLATFORM(IOS) || PLATFORM(GTK)
</del><ins>+#if PLATFORM(IOS) || PLATFORM(GTK) || PLATFORM(MAC)
</ins><span class="cx">     if (!result.isMissingPostLayoutData) {
</span><span class="cx">         if (!PostLayoutData::decode(decoder, result.postLayoutData()))
</span><span class="cx">             return false;
</span><span class="lines">@@ -103,42 +103,55 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-#if PLATFORM(IOS) || PLATFORM(GTK)
</del><ins>+#if PLATFORM(IOS) || PLATFORM(GTK) || PLATFORM(MAC)
</ins><span class="cx"> void EditorState::PostLayoutData::encode(IPC::ArgumentEncoder&amp; encoder) const
</span><span class="cx"> {
</span><ins>+#if PLATFORM(IOS) || PLATFORM(GTK)
</ins><span class="cx">     encoder &lt;&lt; typingAttributes;
</span><span class="cx">     encoder &lt;&lt; caretRectAtStart;
</span><ins>+#endif
+#if PLATFORM(IOS) || PLATFORM(MAC)
+    encoder &lt;&lt; selectionClipRect;
+    encoder &lt;&lt; selectedTextLength;
+#endif
</ins><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">     encoder &lt;&lt; caretRectAtEnd;
</span><del>-    encoder &lt;&lt; selectionClipRect;
</del><span class="cx">     encoder &lt;&lt; selectionRects;
</span><span class="cx">     encoder &lt;&lt; wordAtSelection;
</span><del>-    encoder &lt;&lt; selectedTextLength;
</del><span class="cx">     encoder &lt;&lt; characterAfterSelection;
</span><span class="cx">     encoder &lt;&lt; characterBeforeSelection;
</span><span class="cx">     encoder &lt;&lt; twoCharacterBeforeSelection;
</span><span class="cx">     encoder &lt;&lt; isReplaceAllowed;
</span><span class="cx">     encoder &lt;&lt; hasContent;
</span><span class="cx"> #endif
</span><ins>+#if PLATFORM(MAC)
+    encoder &lt;&lt; candidateRequestStartPosition;
+    encoder &lt;&lt; paragraphContextForCandidateRequest;
+    encoder &lt;&lt; stringForCandidateRequest;
+#endif
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool EditorState::PostLayoutData::decode(IPC::ArgumentDecoder&amp; decoder, PostLayoutData&amp; result)
</span><span class="cx"> {
</span><ins>+#if PLATFORM(IOS) || PLATFORM(GTK)
</ins><span class="cx">     if (!decoder.decode(result.typingAttributes))
</span><span class="cx">         return false;
</span><span class="cx">     if (!decoder.decode(result.caretRectAtStart))
</span><span class="cx">         return false;
</span><ins>+#endif
+#if PLATFORM(IOS) || PLATFORM(MAC)
+    if (!decoder.decode(result.selectionClipRect))
+        return false;
+    if (!decoder.decode(result.selectedTextLength))
+        return false;
+#endif
</ins><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">     if (!decoder.decode(result.caretRectAtEnd))
</span><span class="cx">         return false;
</span><del>-    if (!decoder.decode(result.selectionClipRect))
-        return false;
</del><span class="cx">     if (!decoder.decode(result.selectionRects))
</span><span class="cx">         return false;
</span><span class="cx">     if (!decoder.decode(result.wordAtSelection))
</span><span class="cx">         return false;
</span><del>-    if (!decoder.decode(result.selectedTextLength))
-        return false;
</del><span class="cx">     if (!decoder.decode(result.characterAfterSelection))
</span><span class="cx">         return false;
</span><span class="cx">     if (!decoder.decode(result.characterBeforeSelection))
</span><span class="lines">@@ -150,9 +163,19 @@
</span><span class="cx">     if (!decoder.decode(result.hasContent))
</span><span class="cx">         return false;
</span><span class="cx"> #endif
</span><ins>+#if PLATFORM(MAC)
+    if (!decoder.decode(result.candidateRequestStartPosition))
+        return false;
</ins><span class="cx"> 
</span><ins>+    if (!decoder.decode(result.paragraphContextForCandidateRequest))
+        return false;
+
+    if (!decoder.decode(result.stringForCandidateRequest))
+        return false;
+#endif
+
</ins><span class="cx">     return true;
</span><span class="cx"> }
</span><del>-#endif
</del><ins>+#endif // PLATFORM(IOS) || PLATFORM(GTK) || PLATFORM(MAC)
</ins><span class="cx"> 
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedEditorStateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/EditorState.h (195001 => 195002)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/EditorState.h        2016-01-14 00:29:55 UTC (rev 195001)
+++ trunk/Source/WebKit2/Shared/EditorState.h        2016-01-14 01:03:01 UTC (rev 195002)
</span><span class="lines">@@ -62,22 +62,31 @@
</span><span class="cx">     String markedText;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if PLATFORM(IOS) || PLATFORM(GTK) || PLATFORM(MAC)
+    struct PostLayoutData {
</ins><span class="cx"> #if PLATFORM(IOS) || PLATFORM(GTK)
</span><del>-    struct PostLayoutData {
</del><span class="cx">         uint32_t typingAttributes { AttributeNone };
</span><span class="cx">         WebCore::IntRect caretRectAtStart;
</span><ins>+#endif
+#if PLATFORM(IOS) || PLATFORM(MAC)
+        WebCore::IntRect selectionClipRect;
+        uint64_t selectedTextLength { 0 };
+#endif
</ins><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">         WebCore::IntRect caretRectAtEnd;
</span><del>-        WebCore::IntRect selectionClipRect;
</del><span class="cx">         Vector&lt;WebCore::SelectionRect&gt; selectionRects;
</span><span class="cx">         String wordAtSelection;
</span><del>-        uint64_t selectedTextLength { 0 };
</del><span class="cx">         UChar32 characterAfterSelection { 0 };
</span><span class="cx">         UChar32 characterBeforeSelection { 0 };
</span><span class="cx">         UChar32 twoCharacterBeforeSelection { 0 };
</span><span class="cx">         bool isReplaceAllowed { false };
</span><span class="cx">         bool hasContent { false };
</span><span class="cx"> #endif
</span><ins>+#if PLATFORM(MAC)
+        uint64_t candidateRequestStartPosition { 0 };
+        String paragraphContextForCandidateRequest;
+        String stringForCandidateRequest;
+#endif
</ins><span class="cx"> 
</span><span class="cx">         void encode(IPC::ArgumentEncoder&amp;) const;
</span><span class="cx">         static bool decode(IPC::ArgumentDecoder&amp;, PostLayoutData&amp;);
</span><span class="lines">@@ -85,18 +94,18 @@
</span><span class="cx"> 
</span><span class="cx">     const PostLayoutData&amp; postLayoutData() const;
</span><span class="cx">     PostLayoutData&amp; postLayoutData();
</span><del>-#endif // PLATFORM(IOS) || PLATFORM(GTK)
</del><ins>+#endif // PLATFORM(IOS) || PLATFORM(GTK) || PLATFORM(MAC)
</ins><span class="cx"> 
</span><span class="cx">     void encode(IPC::ArgumentEncoder&amp;) const;
</span><span class="cx">     static bool decode(IPC::ArgumentDecoder&amp;, EditorState&amp;);
</span><span class="cx"> 
</span><del>-#if PLATFORM(IOS) || PLATFORM(GTK)
</del><ins>+#if PLATFORM(IOS) || PLATFORM(GTK) || PLATFORM(MAC)
</ins><span class="cx"> private:
</span><span class="cx">     PostLayoutData m_postLayoutData;
</span><span class="cx"> #endif
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-#if PLATFORM(IOS) || PLATFORM(GTK)
</del><ins>+#if PLATFORM(IOS) || PLATFORM(GTK) || PLATFORM(MAC)
</ins><span class="cx"> inline auto EditorState::postLayoutData() -&gt; PostLayoutData&amp;
</span><span class="cx"> {
</span><span class="cx">     ASSERT_WITH_MESSAGE(!isMissingPostLayoutData, &quot;Attempt to access post layout data before receiving it&quot;);
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessCocoaWebViewImplh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/Cocoa/WebViewImpl.h (195001 => 195002)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/Cocoa/WebViewImpl.h        2016-01-14 00:29:55 UTC (rev 195001)
+++ trunk/Source/WebKit2/UIProcess/Cocoa/WebViewImpl.h        2016-01-14 01:03:01 UTC (rev 195002)
</span><span class="lines">@@ -294,6 +294,10 @@
</span><span class="cx">     void lowercaseWord();
</span><span class="cx">     void capitalizeWord();
</span><span class="cx"> 
</span><ins>+#if __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 101200
+    void requestCandidatesForSelectionIfNeeded();
+#endif
+
</ins><span class="cx">     void preferencesDidChange();
</span><span class="cx"> 
</span><span class="cx">     void setTextIndicator(WebCore::TextIndicator&amp;, WebCore::TextIndicatorWindowLifetime = WebCore::TextIndicatorWindowLifetime::Permanent);
</span><span class="lines">@@ -498,6 +502,11 @@
</span><span class="cx"> 
</span><span class="cx">     Vector&lt;NSTouch *&gt; touchesOrderedByAge();
</span><span class="cx"> 
</span><ins>+#if __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 101200
+    void handleRequestedCandidates(NSInteger sequenceNumber, NSArray&lt;NSTextCheckingResult *&gt; *candidates);
+    void handleAcceptedCandidate(NSTextCheckingResult *acceptedCandidate);
+#endif
+
</ins><span class="cx">     NSView &lt;WebViewImplDelegate&gt; *m_view;
</span><span class="cx">     std::unique_ptr&lt;PageClient&gt; m_pageClient;
</span><span class="cx">     Ref&lt;WebPageProxy&gt; m_page;
</span><span class="lines">@@ -610,6 +619,10 @@
</span><span class="cx"> 
</span><span class="cx">     Vector&lt;RetainPtr&lt;id &lt;NSObject, NSCopying&gt;&gt;&gt; m_activeTouchIdentities;
</span><span class="cx">     RetainPtr&lt;NSArray&gt; m_lastTouches;
</span><ins>+
+#if __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 101200
+    String m_lastStringForCandidateRequest;
+#endif
</ins><span class="cx"> };
</span><span class="cx">     
</span><span class="cx"> } // namespace WebKit
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessCocoaWebViewImplmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/Cocoa/WebViewImpl.mm (195001 => 195002)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/Cocoa/WebViewImpl.mm        2016-01-14 00:29:55 UTC (rev 195001)
+++ trunk/Source/WebKit2/UIProcess/Cocoa/WebViewImpl.mm        2016-01-14 01:03:01 UTC (rev 195002)
</span><span class="lines">@@ -75,6 +75,7 @@
</span><span class="cx"> #import &lt;WebCore/LookupSPI.h&gt;
</span><span class="cx"> #import &lt;WebCore/NSApplicationSPI.h&gt;
</span><span class="cx"> #import &lt;WebCore/NSImmediateActionGestureRecognizerSPI.h&gt;
</span><ins>+#import &lt;WebCore/NSSpellCheckerSPI.h&gt;
</ins><span class="cx"> #import &lt;WebCore/NSTextFinderSPI.h&gt;
</span><span class="cx"> #import &lt;WebCore/NSWindowSPI.h&gt;
</span><span class="cx"> #import &lt;WebCore/PlatformEventFactoryMac.h&gt;
</span><span class="lines">@@ -1723,6 +1724,10 @@
</span><span class="cx"> void WebViewImpl::selectionDidChange()
</span><span class="cx"> {
</span><span class="cx">     updateFontPanelIfNeeded();
</span><ins>+#if __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 101200
+    if (!m_page-&gt;editorState().isMissingPostLayoutData)
+        requestCandidatesForSelectionIfNeeded();
+#endif
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebViewImpl::startObservingFontPanel()
</span><span class="lines">@@ -2088,6 +2093,90 @@
</span><span class="cx">     m_page-&gt;capitalizeWord();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 101200
+void WebViewImpl::requestCandidatesForSelectionIfNeeded()
+{
+    const EditorState&amp; editorState = m_page-&gt;editorState();
+    if (!editorState.isContentEditable)
+        return;
+
+    auto&amp; postLayoutData = editorState.postLayoutData();
+    m_lastStringForCandidateRequest = postLayoutData.stringForCandidateRequest;
+
+    NSRange rangeForCandidates = NSMakeRange(postLayoutData.candidateRequestStartPosition, postLayoutData.selectedTextLength);
+    NSTextCheckingTypes checkingTypes = NSTextCheckingTypeSpelling | NSTextCheckingTypeReplacement | NSTextCheckingTypeCorrection;
+    auto weakThis = createWeakPtr();
+    [[NSSpellChecker sharedSpellChecker] requestCandidatesForSelectedRange:rangeForCandidates inString:postLayoutData.paragraphContextForCandidateRequest types:checkingTypes options:nil inSpellDocumentWithTag:spellCheckerDocumentTag() completionHandler:[weakThis](NSInteger sequenceNumber, NSArray&lt;NSTextCheckingResult *&gt; *candidates) {
+        dispatch_async(dispatch_get_main_queue(), ^{
+            if (!weakThis)
+                return;
+            weakThis-&gt;handleRequestedCandidates(sequenceNumber, candidates);
+        });
+    }];
+}
+
+void WebViewImpl::handleRequestedCandidates(NSInteger sequenceNumber, NSArray&lt;NSTextCheckingResult *&gt; *candidates)
+{
+    const EditorState&amp; editorState = m_page-&gt;editorState();
+    if (!editorState.isContentEditable)
+        return;
+
+    auto&amp; postLayoutData = editorState.postLayoutData();
+    if (m_lastStringForCandidateRequest != postLayoutData.stringForCandidateRequest)
+        return;
+
+    auto weakEditor = m_weakPtrFactory.createWeakPtr();
+    [[NSSpellChecker sharedSpellChecker] showCandidates:candidates forString:postLayoutData.stringForCandidateRequest inRect:postLayoutData.selectionClipRect view:m_view completionHandler:[weakEditor](NSTextCheckingResult *acceptedCandidate) {
+        dispatch_async(dispatch_get_main_queue(), ^{
+            if (!weakEditor)
+                return;
+            weakEditor-&gt;handleAcceptedCandidate(acceptedCandidate);
+        });
+    }];
+}
+
+static WebCore::TextCheckingResult textCheckingResultFromNSTextCheckingResult(NSTextCheckingResult *nsResult)
+{
+    WebCore::TextCheckingResult result;
+
+    // FIXME: Right now we only request candidates for spelling, replacement, and correction, but we plan to
+    // support more types, and we will have to update this at that time.
+    switch ([nsResult resultType]) {
+    case NSTextCheckingTypeSpelling:
+        result.type = WebCore::TextCheckingTypeSpelling;
+        break;
+    case NSTextCheckingTypeReplacement:
+        result.type = WebCore::TextCheckingTypeReplacement;
+        break;
+    case NSTextCheckingTypeCorrection:
+        result.type = WebCore::TextCheckingTypeCorrection;
+        break;
+    default:
+        result.type = WebCore::TextCheckingTypeNone;
+    }
+
+    NSRange resultRange = [nsResult range];
+    result.location = resultRange.location;
+    result.length = resultRange.length;
+    result.replacement = [nsResult replacementString];
+
+    return result;
+}
+
+void WebViewImpl::handleAcceptedCandidate(NSTextCheckingResult *acceptedCandidate)
+{
+    const EditorState&amp; editorState = m_page-&gt;editorState();
+    if (!editorState.isContentEditable)
+        return;
+
+    auto&amp; postLayoutData = editorState.postLayoutData();
+    if (m_lastStringForCandidateRequest != postLayoutData.stringForCandidateRequest)
+        return;
+
+    m_page-&gt;handleAcceptedCandidate(textCheckingResultFromNSTextCheckingResult(acceptedCandidate));
+}
+#endif // __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 101200
+
</ins><span class="cx"> void WebViewImpl::preferencesDidChange()
</span><span class="cx"> {
</span><span class="cx">     BOOL needsViewFrameInWindowCoordinates = m_page-&gt;preferences().pluginsEnabled();
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp (195001 => 195002)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp        2016-01-14 00:29:55 UTC (rev 195001)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp        2016-01-14 01:03:01 UTC (rev 195002)
</span><span class="lines">@@ -6010,6 +6010,11 @@
</span><span class="cx">     uint64_t callbackID = m_callbacks.put(voidCallback.release());
</span><span class="cx">     m_nextViewStateChangeCallbacks.append(callbackID);
</span><span class="cx"> }
</span><ins>+
+void WebPageProxy::handleAcceptedCandidate(WebCore::TextCheckingResult acceptedCandidate)
+{
+    m_process-&gt;send(Messages::WebPage::HandleAcceptedCandidate(acceptedCandidate), m_pageID);
+}
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> void WebPageProxy::imageOrMediaDocumentSizeChanged(const WebCore::IntSize&amp; newSize)
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.h (195001 => 195002)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.h        2016-01-14 00:29:55 UTC (rev 195001)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.h        2016-01-14 01:03:01 UTC (rev 195002)
</span><span class="lines">@@ -1027,6 +1027,8 @@
</span><span class="cx">     void* immediateActionAnimationControllerForHitTestResult(RefPtr&lt;API::HitTestResult&gt;, uint64_t, RefPtr&lt;API::Object&gt;);
</span><span class="cx"> 
</span><span class="cx">     void installViewStateChangeCompletionHandler(void(^completionHandler)());
</span><ins>+
+    void handleAcceptedCandidate(WebCore::TextCheckingResult);
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(EFL) &amp;&amp; HAVE(ACCESSIBILITY) &amp;&amp; defined(HAVE_ECORE_X)
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebPageh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h (195001 => 195002)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h        2016-01-14 00:29:55 UTC (rev 195001)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h        2016-01-14 01:03:01 UTC (rev 195002)
</span><span class="lines">@@ -1142,6 +1142,8 @@
</span><span class="cx">     void dataDetectorsDidPresentUI(WebCore::PageOverlay::PageOverlayID);
</span><span class="cx">     void dataDetectorsDidChangeUI(WebCore::PageOverlay::PageOverlayID);
</span><span class="cx">     void dataDetectorsDidHideUI(WebCore::PageOverlay::PageOverlayID);
</span><ins>+
+    void handleAcceptedCandidate(WebCore::TextCheckingResult);
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     void setShouldDispatchFakeMouseMoveEvents(bool dispatch) { m_shouldDispatchFakeMouseMoveEvents = dispatch; }
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebPagemessagesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in (195001 => 195002)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in        2016-01-14 00:29:55 UTC (rev 195001)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in        2016-01-14 01:03:01 UTC (rev 195002)
</span><span class="lines">@@ -404,6 +404,7 @@
</span><span class="cx">     DataDetectorsDidPresentUI(WebCore::PageOverlay::PageOverlayID pageOverlay)
</span><span class="cx">     DataDetectorsDidChangeUI(WebCore::PageOverlay::PageOverlayID pageOverlay)
</span><span class="cx">     DataDetectorsDidHideUI(WebCore::PageOverlay::PageOverlayID pageOverlay)
</span><ins>+    HandleAcceptedCandidate(struct WebCore::TextCheckingResult acceptedCandidate)
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     SetShouldDispatchFakeMouseMoveEvents(bool shouldDispatchFakeMouseMoveEvents)
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPagemacWebPageMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm (195001 => 195002)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm        2016-01-14 00:29:55 UTC (rev 195001)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm        2016-01-14 01:03:01 UTC (rev 195002)
</span><span class="lines">@@ -118,10 +118,45 @@
</span><span class="cx">     [m_mockAccessibilityElement setWebPage:nullptr];
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebPage::platformEditorState(Frame&amp; frame, EditorState&amp; result, IncludePostLayoutDataHint) const
</del><ins>+void WebPage::platformEditorState(Frame&amp; frame, EditorState&amp; result, IncludePostLayoutDataHint shouldIncludePostLayoutData) const
</ins><span class="cx"> {
</span><ins>+    if (shouldIncludePostLayoutData == IncludePostLayoutDataHint::No) {
+        result.isMissingPostLayoutData = true;
+        return;
+    }
+
+    const VisibleSelection&amp; selection = frame.selection().selection();
+    RefPtr&lt;Range&gt; selectedRange = selection.toNormalizedRange();
+    if (!selectedRange)
+        return;
+
+    auto&amp; postLayoutData = result.postLayoutData();
+    VisiblePosition selectionStart = selection.visibleStart();
+    VisiblePosition selectionEnd = selection.visibleEnd();
+    VisiblePosition paragraphStart = startOfParagraph(selectionStart);
+    VisiblePosition paragraphEnd = endOfParagraph(selectionEnd);
+
+    postLayoutData.candidateRequestStartPosition = TextIterator::rangeLength(makeRange(paragraphStart, selectionStart).get());
+    postLayoutData.selectedTextLength = TextIterator::rangeLength(makeRange(paragraphStart, selectionEnd).get()) - postLayoutData.candidateRequestStartPosition;
+    postLayoutData.paragraphContextForCandidateRequest = plainText(makeRange(paragraphStart, paragraphEnd).get());
+    postLayoutData.stringForCandidateRequest = frame.editor().stringForCandidateRequest();
+
+    IntRect rectForSelectionCandidates;
+    Vector&lt;FloatQuad&gt; quads;
+    selectedRange-&gt;absoluteTextQuads(quads);
+    if (!quads.isEmpty())
+        postLayoutData.selectionClipRect = frame.view()-&gt;contentsToWindow(quads[0].enclosingBoundingBox());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebPage::handleAcceptedCandidate(WebCore::TextCheckingResult acceptedCandidate)
+{
+    Frame* frame = m_page-&gt;focusController().focusedFrame();
+    if (!frame)
+        return;
+
+    frame-&gt;editor().handleAcceptedCandidate(acceptedCandidate);
+}
+
</ins><span class="cx"> NSObject *WebPage::accessibilityObjectForMainFramePlugin()
</span><span class="cx"> {
</span><span class="cx">     if (!m_page)
</span></span></pre>
</div>
</div>

</body>
</html>