<!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>[182603] trunk/Source</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/182603">182603</a></dd>
<dt>Author</dt> <dd>cdumez@apple.com</dd>
<dt>Date</dt> <dd>2015-04-09 11:31:51 -0700 (Thu, 09 Apr 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>[WK2][iOS] editorState() should not cause a synchronous layout
https://bugs.webkit.org/show_bug.cgi?id=142536
&lt;rdar://problem/20041506&gt;

Reviewed by Enrica Casucci.

Source/WebCore:

Add didChangeSelectionAndUpdateLayout() callback to EditorClient
that is called at the end of FrameSelection::updateAndRevealSelection().

* editing/FrameSelection.cpp:
(WebCore::FrameSelection::updateAndRevealSelection):
* loader/EmptyClients.h:
* page/EditorClient.h:

Source/WebKit/mac:

Provide implementation for EditorClient::didChangeSelectionAndUpdateLayout().

* WebCoreSupport/WebEditorClient.h:

Source/WebKit/win:

Provide implementation for EditorClient::didChangeSelectionAndUpdateLayout().

* WebCoreSupport/WebEditorClient.h:

Source/WebKit2:

platformEditorState() on iOS does a synchronous layout to compute some
of the EditorState members (e.g. caretRectAtStart / caretRectAtEnd).
This is bad for performance as this is called every time the selection
is changed (which happens for e.g. when you set the value of a focused
HTMLInputElement).

This patch updates the behavior on iOS to only send a partial EditorState
on selection change so that the UIProcess gets most of the information
(the ones that do not require style recalc or layout) ASAP. A full Editor
state is then sent after the asynchronous layout is done.

With this change, I see a 38% improvement on Speedometer (26.4 +/- 0.37
-&gt; 36.5 +/- 0.54) on iPhone 6 Plus.

* Shared/EditorState.cpp:
(WebKit::EditorState::encode):
(WebKit::EditorState::decode):
(WebKit::EditorState::PostLayoutData::encode):
(WebKit::EditorState::PostLayoutData::decode):
* Shared/EditorState.h:
(WebKit::EditorState::EditorState): Deleted.
* UIProcess/ios/WKContentView.mm:
(-[WKContentView _didCommitLayerTree:]):
* UIProcess/ios/WKContentViewInteraction.mm:
(WebKit::WKSelectionDrawingInfo::WKSelectionDrawingInfo):
(-[WKContentView webSelectionRects]):
(-[WKContentView _addShortcut:]):
(-[WKContentView selectedText]):
(-[WKContentView isReplaceAllowed]):
(-[WKContentView _promptForReplace:]):
(-[WKContentView _transliterateChinese:]):
(-[WKContentView textStylingAtPosition:inDirection:]):
(-[WKContentView canPerformAction:withSender:]):
(-[WKContentView _showDictionary:]):
(-[WKContentView _characterBeforeCaretSelection]):
(-[WKContentView _characterInRelationToCaretSelection:]):
(-[WKContentView _selectionAtDocumentStart]):
(-[WKContentView selectedTextRange]):
(-[WKContentView hasContent]):
* WebProcess/WebCoreSupport/WebEditorClient.cpp:
(WebKit::WebEditorClient::didChangeSelectionAndUpdateLayout):
* WebProcess/WebCoreSupport/WebEditorClient.h:
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::editorState):
(WebKit::WebPage::didChangeSelection):
(WebKit::WebPage::sendPostLayoutEditorStateIfNeeded):
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/efl/WebPageEfl.cpp:
(WebKit::WebPage::platformEditorState):
* WebProcess/WebPage/gtk/WebPageGtk.cpp:
(WebKit::WebPage::platformEditorState):
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::platformEditorState):
* WebProcess/WebPage/mac/WebPageMac.mm:
(WebKit::WebPage::platformEditorState):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreeditingFrameSelectioncpp">trunk/Source/WebCore/editing/FrameSelection.cpp</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="#trunkSourceWebKitwinChangeLog">trunk/Source/WebKit/win/ChangeLog</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="#trunkSourceWebKit2SharedEditorStatecpp">trunk/Source/WebKit2/Shared/EditorState.cpp</a></li>
<li><a href="#trunkSourceWebKit2SharedEditorStateh">trunk/Source/WebKit2/Shared/EditorState.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosWKContentViewmm">trunk/Source/WebKit2/UIProcess/ios/WKContentView.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosWKContentViewInteractionmm">trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm</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>
<li><a href="#trunkSourceWebKit2WebProcessWebPageeflWebPageEflcpp">trunk/Source/WebKit2/WebProcess/WebPage/efl/WebPageEfl.cpp</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPagegtkWebPageGtkcpp">trunk/Source/WebKit2/WebProcess/WebPage/gtk/WebPageGtk.cpp</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageiosWebPageIOSmm">trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPagemacWebPageMacmm">trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (182602 => 182603)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-04-09 16:20:21 UTC (rev 182602)
+++ trunk/Source/WebCore/ChangeLog        2015-04-09 18:31:51 UTC (rev 182603)
</span><span class="lines">@@ -1,3 +1,19 @@
</span><ins>+2015-04-09  Chris Dumez  &lt;cdumez@apple.com&gt;
+
+        [WK2][iOS] editorState() should not cause a synchronous layout
+        https://bugs.webkit.org/show_bug.cgi?id=142536
+        &lt;rdar://problem/20041506&gt;
+
+        Reviewed by Enrica Casucci.
+
+        Add didChangeSelectionAndUpdateLayout() callback to EditorClient
+        that is called at the end of FrameSelection::updateAndRevealSelection().
+
+        * editing/FrameSelection.cpp:
+        (WebCore::FrameSelection::updateAndRevealSelection):
+        * loader/EmptyClients.h:
+        * page/EditorClient.h:
+
</ins><span class="cx"> 2015-04-08  Anders Carlsson  &lt;andersca@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Give each cache group a storage and use it in place of the singleton
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingFrameSelectioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/FrameSelection.cpp (182602 => 182603)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/FrameSelection.cpp        2015-04-09 16:20:21 UTC (rev 182602)
+++ trunk/Source/WebCore/editing/FrameSelection.cpp        2015-04-09 18:31:51 UTC (rev 182603)
</span><span class="lines">@@ -381,6 +381,8 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     notifyAccessibilityForSelectionChange();
</span><ins>+
+    m_frame-&gt;editor().client()-&gt;didChangeSelectionAndUpdateLayout();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void FrameSelection::updateDataDetectorsForSelection()
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderEmptyClientsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/EmptyClients.h (182602 => 182603)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/EmptyClients.h        2015-04-09 16:20:21 UTC (rev 182602)
+++ trunk/Source/WebCore/loader/EmptyClients.h        2015-04-09 18:31:51 UTC (rev 182603)
</span><span class="lines">@@ -446,6 +446,7 @@
</span><span class="cx">     virtual void didBeginEditing() override { }
</span><span class="cx">     virtual void respondToChangedContents() override { }
</span><span class="cx">     virtual void respondToChangedSelection(Frame*) override { }
</span><ins>+    virtual void didChangeSelectionAndUpdateLayout() override { }
</ins><span class="cx">     virtual void discardedComposition(Frame*) override { }
</span><span class="cx">     virtual void didEndEditing() override { }
</span><span class="cx">     virtual void willWriteSelectionToPasteboard(Range*) override { }
</span></span></pre></div>
<a id="trunkSourceWebCorepageEditorClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/EditorClient.h (182602 => 182603)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/EditorClient.h        2015-04-09 16:20:21 UTC (rev 182602)
+++ trunk/Source/WebCore/page/EditorClient.h        2015-04-09 18:31:51 UTC (rev 182603)
</span><span class="lines">@@ -93,6 +93,7 @@
</span><span class="cx">     virtual void didBeginEditing() = 0;
</span><span class="cx">     virtual void respondToChangedContents() = 0;
</span><span class="cx">     virtual void respondToChangedSelection(Frame*) = 0;
</span><ins>+    virtual void didChangeSelectionAndUpdateLayout() = 0;
</ins><span class="cx">     virtual void didEndEditing() = 0;
</span><span class="cx">     virtual void willWriteSelectionToPasteboard(Range*) = 0;
</span><span class="cx">     virtual void didWriteSelectionToPasteboard() = 0;
</span></span></pre></div>
<a id="trunkSourceWebKitmacChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/ChangeLog (182602 => 182603)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/ChangeLog        2015-04-09 16:20:21 UTC (rev 182602)
+++ trunk/Source/WebKit/mac/ChangeLog        2015-04-09 18:31:51 UTC (rev 182603)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2015-04-09  Chris Dumez  &lt;cdumez@apple.com&gt;
+
+        [WK2][iOS] editorState() should not cause a synchronous layout
+        https://bugs.webkit.org/show_bug.cgi?id=142536
+        &lt;rdar://problem/20041506&gt;
+
+        Reviewed by Enrica Casucci.
+
+        Provide implementation for EditorClient::didChangeSelectionAndUpdateLayout().
+
+        * WebCoreSupport/WebEditorClient.h:
+
</ins><span class="cx"> 2015-04-08  Brent Fulgham  &lt;bfulgham@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [Mac] WebKit is not honoring OS preferences for secondary click behaviors
</span></span></pre></div>
<a id="trunkSourceWebKitmacWebCoreSupportWebEditorClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/WebCoreSupport/WebEditorClient.h (182602 => 182603)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/WebCoreSupport/WebEditorClient.h        2015-04-09 16:20:21 UTC (rev 182602)
+++ trunk/Source/WebKit/mac/WebCoreSupport/WebEditorClient.h        2015-04-09 18:31:51 UTC (rev 182603)
</span><span class="lines">@@ -110,6 +110,7 @@
</span><span class="cx"> 
</span><span class="cx">     virtual void respondToChangedContents() override;
</span><span class="cx">     virtual void respondToChangedSelection(WebCore::Frame*) override;
</span><ins>+    virtual void didChangeSelectionAndUpdateLayout() override { }
</ins><span class="cx">     virtual void discardedComposition(WebCore::Frame*) override;
</span><span class="cx"> 
</span><span class="cx">     virtual void registerUndoStep(PassRefPtr&lt;WebCore::UndoStep&gt;) override;
</span></span></pre></div>
<a id="trunkSourceWebKitwinChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/win/ChangeLog (182602 => 182603)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/win/ChangeLog        2015-04-09 16:20:21 UTC (rev 182602)
+++ trunk/Source/WebKit/win/ChangeLog        2015-04-09 18:31:51 UTC (rev 182603)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2015-04-09  Chris Dumez  &lt;cdumez@apple.com&gt;
+
+        [WK2][iOS] editorState() should not cause a synchronous layout
+        https://bugs.webkit.org/show_bug.cgi?id=142536
+        &lt;rdar://problem/20041506&gt;
+
+        Reviewed by Enrica Casucci.
+
+        Provide implementation for EditorClient::didChangeSelectionAndUpdateLayout().
+
+        * WebCoreSupport/WebEditorClient.h:
+
</ins><span class="cx"> 2015-04-08  Brady Eidson  &lt;beidson@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Expose the &quot;Share&quot; menu for links, images, and media.
</span></span></pre></div>
<a id="trunkSourceWebKitwinWebCoreSupportWebEditorClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/win/WebCoreSupport/WebEditorClient.h (182602 => 182603)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/win/WebCoreSupport/WebEditorClient.h        2015-04-09 16:20:21 UTC (rev 182602)
+++ trunk/Source/WebKit/win/WebCoreSupport/WebEditorClient.h        2015-04-09 18:31:51 UTC (rev 182603)
</span><span class="lines">@@ -60,6 +60,7 @@
</span><span class="cx"> 
</span><span class="cx">     virtual void respondToChangedContents();
</span><span class="cx">     virtual void respondToChangedSelection(WebCore::Frame*);
</span><ins>+    virtual void didChangeSelectionAndUpdateLayout() override { }
</ins><span class="cx">     virtual void discardedComposition(WebCore::Frame*) override;
</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 (182602 => 182603)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2015-04-09 16:20:21 UTC (rev 182602)
+++ trunk/Source/WebKit2/ChangeLog        2015-04-09 18:31:51 UTC (rev 182603)
</span><span class="lines">@@ -1,3 +1,67 @@
</span><ins>+2015-04-09  Chris Dumez  &lt;cdumez@apple.com&gt;
+
+        [WK2][iOS] editorState() should not cause a synchronous layout
+        https://bugs.webkit.org/show_bug.cgi?id=142536
+        &lt;rdar://problem/20041506&gt;
+
+        Reviewed by Enrica Casucci.
+
+        platformEditorState() on iOS does a synchronous layout to compute some
+        of the EditorState members (e.g. caretRectAtStart / caretRectAtEnd).
+        This is bad for performance as this is called every time the selection
+        is changed (which happens for e.g. when you set the value of a focused
+        HTMLInputElement).
+
+        This patch updates the behavior on iOS to only send a partial EditorState
+        on selection change so that the UIProcess gets most of the information
+        (the ones that do not require style recalc or layout) ASAP. A full Editor
+        state is then sent after the asynchronous layout is done.
+
+        With this change, I see a 38% improvement on Speedometer (26.4 +/- 0.37
+        -&gt; 36.5 +/- 0.54) on iPhone 6 Plus.
+
+        * Shared/EditorState.cpp:
+        (WebKit::EditorState::encode):
+        (WebKit::EditorState::decode):
+        (WebKit::EditorState::PostLayoutData::encode):
+        (WebKit::EditorState::PostLayoutData::decode):
+        * Shared/EditorState.h:
+        (WebKit::EditorState::EditorState): Deleted.
+        * UIProcess/ios/WKContentView.mm:
+        (-[WKContentView _didCommitLayerTree:]):
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (WebKit::WKSelectionDrawingInfo::WKSelectionDrawingInfo):
+        (-[WKContentView webSelectionRects]):
+        (-[WKContentView _addShortcut:]):
+        (-[WKContentView selectedText]):
+        (-[WKContentView isReplaceAllowed]):
+        (-[WKContentView _promptForReplace:]):
+        (-[WKContentView _transliterateChinese:]):
+        (-[WKContentView textStylingAtPosition:inDirection:]):
+        (-[WKContentView canPerformAction:withSender:]):
+        (-[WKContentView _showDictionary:]):
+        (-[WKContentView _characterBeforeCaretSelection]):
+        (-[WKContentView _characterInRelationToCaretSelection:]):
+        (-[WKContentView _selectionAtDocumentStart]):
+        (-[WKContentView selectedTextRange]):
+        (-[WKContentView hasContent]):
+        * WebProcess/WebCoreSupport/WebEditorClient.cpp:
+        (WebKit::WebEditorClient::didChangeSelectionAndUpdateLayout):
+        * WebProcess/WebCoreSupport/WebEditorClient.h:
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::editorState):
+        (WebKit::WebPage::didChangeSelection):
+        (WebKit::WebPage::sendPostLayoutEditorStateIfNeeded):
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/efl/WebPageEfl.cpp:
+        (WebKit::WebPage::platformEditorState):
+        * WebProcess/WebPage/gtk/WebPageGtk.cpp:
+        (WebKit::WebPage::platformEditorState):
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::WebPage::platformEditorState):
+        * WebProcess/WebPage/mac/WebPageMac.mm:
+        (WebKit::WebPage::platformEditorState):
+
</ins><span class="cx"> 2015-04-09  Antti Koivisto  &lt;antti@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Network Cache: Crash in WebCore::CachedResource::tryReplaceEncodedData
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedEditorStatecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/EditorState.cpp (182602 => 182603)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/EditorState.cpp        2015-04-09 16:20:21 UTC (rev 182602)
+++ trunk/Source/WebKit2/Shared/EditorState.cpp        2015-04-09 18:31:51 UTC (rev 182603)
</span><span class="lines">@@ -41,22 +41,15 @@
</span><span class="cx">     encoder &lt;&lt; isInPasswordField;
</span><span class="cx">     encoder &lt;&lt; isInPlugin;
</span><span class="cx">     encoder &lt;&lt; hasComposition;
</span><ins>+    encoder &lt;&lt; isMissingPostLayoutData;
</ins><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS)
</span><del>-    encoder &lt;&lt; isReplaceAllowed;
-    encoder &lt;&lt; hasContent;
-    encoder &lt;&lt; characterAfterSelection;
-    encoder &lt;&lt; characterBeforeSelection;
-    encoder &lt;&lt; twoCharacterBeforeSelection;
-    encoder &lt;&lt; caretRectAtStart;
-    encoder &lt;&lt; caretRectAtEnd;
-    encoder &lt;&lt; selectionRects;
-    encoder &lt;&lt; selectedTextLength;
-    encoder &lt;&lt; wordAtSelection;
</del><ins>+    if (!isMissingPostLayoutData)
+        m_postLayoutData.encode(encoder);
+
</ins><span class="cx">     encoder &lt;&lt; firstMarkedRect;
</span><span class="cx">     encoder &lt;&lt; lastMarkedRect;
</span><span class="cx">     encoder &lt;&lt; markedText;
</span><del>-    encoder &lt;&lt; typingAttributes;
</del><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(GTK)
</span><span class="lines">@@ -90,43 +83,74 @@
</span><span class="cx">     if (!decoder.decode(result.hasComposition))
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><ins>+    if (!decoder.decode(result.isMissingPostLayoutData))
+        return false;
+
</ins><span class="cx"> #if PLATFORM(IOS)
</span><del>-    if (!decoder.decode(result.isReplaceAllowed))
</del><ins>+    if (!result.isMissingPostLayoutData) {
+        if (!PostLayoutData::decode(decoder, result.postLayoutData()))
+            return false;
+    }
+
+    if (!decoder.decode(result.firstMarkedRect))
</ins><span class="cx">         return false;
</span><del>-    if (!decoder.decode(result.hasContent))
</del><ins>+    if (!decoder.decode(result.lastMarkedRect))
</ins><span class="cx">         return false;
</span><del>-    if (!decoder.decode(result.characterAfterSelection))
</del><ins>+    if (!decoder.decode(result.markedText))
</ins><span class="cx">         return false;
</span><del>-    if (!decoder.decode(result.characterBeforeSelection))
</del><ins>+#endif
+
+#if PLATFORM(GTK)
+    if (!decoder.decode(result.cursorRect))
</ins><span class="cx">         return false;
</span><del>-    if (!decoder.decode(result.twoCharacterBeforeSelection))
</del><ins>+#endif
+
+    return true;
+}
+
+#if PLATFORM(IOS)
+void EditorState::PostLayoutData::encode(IPC::ArgumentEncoder&amp; encoder) const
+{
+    encoder &lt;&lt; selectionRects;
+    encoder &lt;&lt; caretRectAtStart;
+    encoder &lt;&lt; caretRectAtEnd;
+    encoder &lt;&lt; wordAtSelection;
+    encoder &lt;&lt; selectedTextLength;
+    encoder &lt;&lt; characterAfterSelection;
+    encoder &lt;&lt; characterBeforeSelection;
+    encoder &lt;&lt; twoCharacterBeforeSelection;
+    encoder &lt;&lt; typingAttributes;
+    encoder &lt;&lt; isReplaceAllowed;
+    encoder &lt;&lt; hasContent;
+}
+
+bool EditorState::PostLayoutData::decode(IPC::ArgumentDecoder&amp; decoder, PostLayoutData&amp; result)
+{
+    if (!decoder.decode(result.selectionRects))
</ins><span class="cx">         return false;
</span><span class="cx">     if (!decoder.decode(result.caretRectAtStart))
</span><span class="cx">         return false;
</span><span class="cx">     if (!decoder.decode(result.caretRectAtEnd))
</span><span class="cx">         return false;
</span><del>-    if (!decoder.decode(result.selectionRects))
</del><ins>+    if (!decoder.decode(result.wordAtSelection))
</ins><span class="cx">         return false;
</span><span class="cx">     if (!decoder.decode(result.selectedTextLength))
</span><span class="cx">         return false;
</span><del>-    if (!decoder.decode(result.wordAtSelection))
</del><ins>+    if (!decoder.decode(result.characterAfterSelection))
</ins><span class="cx">         return false;
</span><del>-    if (!decoder.decode(result.firstMarkedRect))
</del><ins>+    if (!decoder.decode(result.characterBeforeSelection))
</ins><span class="cx">         return false;
</span><del>-    if (!decoder.decode(result.lastMarkedRect))
</del><ins>+    if (!decoder.decode(result.twoCharacterBeforeSelection))
</ins><span class="cx">         return false;
</span><del>-    if (!decoder.decode(result.markedText))
-        return false;
</del><span class="cx">     if (!decoder.decode(result.typingAttributes))
</span><span class="cx">         return false;
</span><del>-#endif
-
-#if PLATFORM(GTK)
-    if (!decoder.decode(result.cursorRect))
</del><ins>+    if (!decoder.decode(result.isReplaceAllowed))
</ins><span class="cx">         return false;
</span><del>-#endif
</del><ins>+    if (!decoder.decode(result.hasContent))
+        return false;
</ins><span class="cx"> 
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><ins>+#endif
</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 (182602 => 182603)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/EditorState.h        2015-04-09 16:20:21 UTC (rev 182602)
+++ trunk/Source/WebKit2/Shared/EditorState.h        2015-04-09 18:31:51 UTC (rev 182603)
</span><span class="lines">@@ -44,52 +44,41 @@
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> struct EditorState {
</span><del>-    EditorState()
-        : shouldIgnoreCompositionSelectionChange(false)
-        , selectionIsNone(true)
-        , selectionIsRange(false)
-        , isContentEditable(false)
-        , isContentRichlyEditable(false)
-        , isInPasswordField(false)
-        , isInPlugin(false)
-        , hasComposition(false)
-#if PLATFORM(IOS)
-        , isReplaceAllowed(false)
-        , hasContent(false)
-        , characterAfterSelection(0)
-        , characterBeforeSelection(0)
-        , twoCharacterBeforeSelection(0)
-        , selectedTextLength(0)
-        , typingAttributes(AttributeNone)
-#endif
-    {
-    }
</del><ins>+    bool shouldIgnoreCompositionSelectionChange { false };
</ins><span class="cx"> 
</span><del>-    bool shouldIgnoreCompositionSelectionChange;
</del><ins>+    bool selectionIsNone { true }; // This will be false when there is a caret selection.
+    bool selectionIsRange { false };
+    bool isContentEditable { false };
+    bool isContentRichlyEditable { false };
+    bool isInPasswordField { false };
+    bool isInPlugin { false };
+    bool hasComposition { false };
+    bool isMissingPostLayoutData { false };
</ins><span class="cx"> 
</span><del>-    bool selectionIsNone; // This will be false when there is a caret selection.
-    bool selectionIsRange;
-    bool isContentEditable;
-    bool isContentRichlyEditable;
-    bool isInPasswordField;
-    bool isInPlugin;
-    bool hasComposition;
-
</del><span class="cx"> #if PLATFORM(IOS)
</span><del>-    bool isReplaceAllowed;
-    bool hasContent;
-    UChar32 characterAfterSelection;
-    UChar32 characterBeforeSelection;
-    UChar32 twoCharacterBeforeSelection;
-    WebCore::IntRect caretRectAtStart;
-    WebCore::IntRect caretRectAtEnd;
-    Vector&lt;WebCore::SelectionRect&gt; selectionRects;
-    uint64_t selectedTextLength;
-    String wordAtSelection;
</del><span class="cx">     WebCore::IntRect firstMarkedRect;
</span><span class="cx">     WebCore::IntRect lastMarkedRect;
</span><span class="cx">     String markedText;
</span><del>-    uint32_t typingAttributes;
</del><ins>+
+    struct PostLayoutData {
+        Vector&lt;WebCore::SelectionRect&gt; selectionRects;
+        WebCore::IntRect caretRectAtStart;
+        WebCore::IntRect caretRectAtEnd;
+        String wordAtSelection;
+        uint64_t selectedTextLength { 0 };
+        UChar32 characterAfterSelection { 0 };
+        UChar32 characterBeforeSelection { 0 };
+        UChar32 twoCharacterBeforeSelection { 0 };
+        uint32_t typingAttributes { AttributeNone };
+        bool isReplaceAllowed { false };
+        bool hasContent { false };
+
+        void encode(IPC::ArgumentEncoder&amp;) const;
+        static bool decode(IPC::ArgumentDecoder&amp;, PostLayoutData&amp;);
+    };
+
+    const PostLayoutData&amp; postLayoutData() const;
+    PostLayoutData&amp; postLayoutData();
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(GTK)
</span><span class="lines">@@ -98,8 +87,27 @@
</span><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><ins>+
+#if PLATFORM(IOS)
+private:
+    PostLayoutData m_postLayoutData;
+#endif
</ins><span class="cx"> };
</span><span class="cx"> 
</span><ins>+#if PLATFORM(IOS)
+inline auto EditorState::postLayoutData() -&gt; PostLayoutData&amp;
+{
+    ASSERT_WITH_MESSAGE(!isMissingPostLayoutData, &quot;Attempt to access post layout data before receiving it&quot;);
+    return m_postLayoutData;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline auto EditorState::postLayoutData() const -&gt; const PostLayoutData&amp;
+{
+    ASSERT_WITH_MESSAGE(!isMissingPostLayoutData, &quot;Attempt to access post layout data before receiving it&quot;);
+    return m_postLayoutData;
+}
+#endif
+
+}
+
</ins><span class="cx"> #endif // EditorState_h
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosWKContentViewmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/WKContentView.mm (182602 => 182603)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/WKContentView.mm        2015-04-09 16:20:21 UTC (rev 182602)
+++ trunk/Source/WebKit2/UIProcess/ios/WKContentView.mm        2015-04-09 18:31:51 UTC (rev 182603)
</span><span class="lines">@@ -490,7 +490,11 @@
</span><span class="cx">         [_webView _updateVisibleContentRects];
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    [self _updateChangedSelection];
</del><ins>+    // Updating the selection requires a full editor state. If the editor state is missing post layout
+    // data then it means there is a layout pending and we're going to be called again after the layout
+    // so we delay the selection update.
+    if (!_page-&gt;editorState().isMissingPostLayoutData)
+        [self _updateChangedSelection];
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (void)_setAcceleratedCompositingRootView:(UIView *)rootView
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosWKContentViewInteractionmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm (182602 => 182603)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm        2015-04-09 16:20:21 UTC (rev 182602)
+++ trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm        2015-04-09 18:31:51 UTC (rev 182603)
</span><span class="lines">@@ -85,8 +85,9 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     type = SelectionType::Range;
</span><del>-    caretRect = editorState.caretRectAtEnd;
-    selectionRects = editorState.selectionRects;
</del><ins>+    auto&amp; postLayoutData = editorState.postLayoutData();
+    caretRect = postLayoutData.caretRectAtEnd;
+    selectionRects = postLayoutData.selectionRects;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> inline bool operator==(const WKSelectionDrawingInfo&amp; a, const WKSelectionDrawingInfo&amp; b)
</span><span class="lines">@@ -986,13 +987,14 @@
</span><span class="cx"> 
</span><span class="cx"> - (NSArray *)webSelectionRects
</span><span class="cx"> {
</span><del>-    unsigned size = _page-&gt;editorState().selectionRects.size();
</del><ins>+    const auto&amp; selectionRects = _page-&gt;editorState().postLayoutData().selectionRects;
+    unsigned size = selectionRects.size();
</ins><span class="cx">     if (!size)
</span><span class="cx">         return nil;
</span><span class="cx"> 
</span><span class="cx">     NSMutableArray *webRects = [NSMutableArray arrayWithCapacity:size];
</span><span class="cx">     for (unsigned i = 0; i &lt; size; i++) {
</span><del>-        const WebCore::SelectionRect&amp; coreRect = _page-&gt;editorState().selectionRects[i];
</del><ins>+        const WebCore::SelectionRect&amp; coreRect = selectionRects[i];
</ins><span class="cx">         WebSelectionRect *webRect = [WebSelectionRect selectionRect];
</span><span class="cx">         webRect.rect = coreRect.rect();
</span><span class="cx">         webRect.writingDirection = coreRect.direction() == LTR ? WKWritingDirectionLeftToRight : WKWritingDirectionRightToLeft;
</span><span class="lines">@@ -1277,19 +1279,19 @@
</span><span class="cx"> - (void)_addShortcut:(id)sender
</span><span class="cx"> {
</span><span class="cx">     if (_textSelectionAssistant &amp;&amp; [_textSelectionAssistant respondsToSelector:@selector(showTextServiceFor:fromRect:)])
</span><del>-        [_textSelectionAssistant showTextServiceFor:[self selectedText] fromRect:_page-&gt;editorState().selectionRects[0].rect()];
</del><ins>+        [_textSelectionAssistant showTextServiceFor:[self selectedText] fromRect:_page-&gt;editorState().postLayoutData().selectionRects[0].rect()];
</ins><span class="cx">     else if (_webSelectionAssistant &amp;&amp; [_webSelectionAssistant respondsToSelector:@selector(showTextServiceFor:fromRect:)])
</span><del>-        [_webSelectionAssistant showTextServiceFor:[self selectedText] fromRect:_page-&gt;editorState().selectionRects[0].rect()];
</del><ins>+        [_webSelectionAssistant showTextServiceFor:[self selectedText] fromRect:_page-&gt;editorState().postLayoutData().selectionRects[0].rect()];
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (NSString *)selectedText
</span><span class="cx"> {
</span><del>-    return (NSString *)_page-&gt;editorState().wordAtSelection;
</del><ins>+    return (NSString *)_page-&gt;editorState().postLayoutData().wordAtSelection;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (BOOL)isReplaceAllowed
</span><span class="cx"> {
</span><del>-    return _page-&gt;editorState().isReplaceAllowed;
</del><ins>+    return _page-&gt;editorState().postLayoutData().isReplaceAllowed;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (void)replaceText:(NSString *)text withText:(NSString *)word
</span><span class="lines">@@ -1304,17 +1306,18 @@
</span><span class="cx"> 
</span><span class="cx"> - (void)_promptForReplace:(id)sender
</span><span class="cx"> {
</span><del>-    if (_page-&gt;editorState().wordAtSelection.isEmpty())
</del><ins>+    const auto&amp; wordAtSelection = _page-&gt;editorState().postLayoutData().wordAtSelection;
+    if (wordAtSelection.isEmpty())
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     if ([_textSelectionAssistant respondsToSelector:@selector(scheduleReplacementsForText:)])
</span><del>-        [_textSelectionAssistant scheduleReplacementsForText:_page-&gt;editorState().wordAtSelection];
</del><ins>+        [_textSelectionAssistant scheduleReplacementsForText:wordAtSelection];
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (void)_transliterateChinese:(id)sender
</span><span class="cx"> {
</span><span class="cx">     if ([_textSelectionAssistant respondsToSelector:@selector(scheduleChineseTransliterationForText:)])
</span><del>-        [_textSelectionAssistant scheduleChineseTransliterationForText:_page-&gt;editorState().wordAtSelection];
</del><ins>+        [_textSelectionAssistant scheduleChineseTransliterationForText:_page-&gt;editorState().postLayoutData().wordAtSelection];
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (void)_reanalyze:(id)sender
</span><span class="lines">@@ -1334,10 +1337,11 @@
</span><span class="cx"> 
</span><span class="cx">     NSMutableDictionary* result = [NSMutableDictionary dictionary];
</span><span class="cx"> 
</span><ins>+    auto typingAttributes = _page-&gt;editorState().postLayoutData().typingAttributes;
</ins><span class="cx">     CTFontSymbolicTraits symbolicTraits = 0;
</span><del>-    if (_page-&gt;editorState().typingAttributes &amp; AttributeBold)
</del><ins>+    if (typingAttributes &amp; AttributeBold)
</ins><span class="cx">         symbolicTraits |= kCTFontBoldTrait;
</span><del>-    if (_page-&gt;editorState().typingAttributes &amp; AttributeItalics)
</del><ins>+    if (typingAttributes &amp; AttributeItalics)
</ins><span class="cx">         symbolicTraits |= kCTFontTraitItalic;
</span><span class="cx"> 
</span><span class="cx">     // We chose a random font family and size.
</span><span class="lines">@@ -1351,7 +1355,7 @@
</span><span class="cx">     if (font)
</span><span class="cx">         [result setObject:(id)font.get() forKey:NSFontAttributeName];
</span><span class="cx">     
</span><del>-    if (_page-&gt;editorState().typingAttributes &amp; AttributeUnderline)
</del><ins>+    if (typingAttributes &amp; AttributeUnderline)
</ins><span class="cx">         [result setObject:[NSNumber numberWithInt:NSUnderlineStyleSingle] forKey:NSUnderlineStyleAttributeName];
</span><span class="cx"> 
</span><span class="cx">     return result;
</span><span class="lines">@@ -1389,7 +1393,7 @@
</span><span class="cx">         if (_page-&gt;editorState().isInPasswordField || !(hasWebSelection || _page-&gt;editorState().selectionIsRange))
</span><span class="cx">             return NO;
</span><span class="cx"> 
</span><del>-        NSUInteger textLength = _page-&gt;editorState().selectedTextLength;
</del><ins>+        NSUInteger textLength = _page-&gt;editorState().postLayoutData().selectedTextLength;
</ins><span class="cx">         // FIXME: We should be calling UIReferenceLibraryViewController to check if the length is
</span><span class="cx">         // acceptable, but the interface takes a string.
</span><span class="cx">         // &lt;rdar://problem/15254406&gt;
</span><span class="lines">@@ -1418,7 +1422,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (action == @selector(_promptForReplace:)) {
</span><del>-        if (!_page-&gt;editorState().selectionIsRange || !_page-&gt;editorState().isReplaceAllowed || ![[UIKeyboardImpl activeInstance] autocorrectSpellingEnabled])
</del><ins>+        if (!_page-&gt;editorState().selectionIsRange || !_page-&gt;editorState().postLayoutData().isReplaceAllowed || ![[UIKeyboardImpl activeInstance] autocorrectSpellingEnabled])
</ins><span class="cx">             return NO;
</span><span class="cx">         if ([[self selectedText] _containsCJScriptsOnly])
</span><span class="cx">             return NO;
</span><span class="lines">@@ -1426,13 +1430,13 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (action == @selector(_transliterateChinese:)) {
</span><del>-        if (!_page-&gt;editorState().selectionIsRange || !_page-&gt;editorState().isReplaceAllowed || ![[UIKeyboardImpl activeInstance] autocorrectSpellingEnabled])
</del><ins>+        if (!_page-&gt;editorState().selectionIsRange || !_page-&gt;editorState().postLayoutData().isReplaceAllowed || ![[UIKeyboardImpl activeInstance] autocorrectSpellingEnabled])
</ins><span class="cx">             return NO;
</span><span class="cx">         return UIKeyboardEnabledInputModesAllowChineseTransliterationForText([self selectedText]);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (action == @selector(_reanalyze:)) {
</span><del>-        if (!_page-&gt;editorState().selectionIsRange || !_page-&gt;editorState().isReplaceAllowed || ![[UIKeyboardImpl activeInstance] autocorrectSpellingEnabled])
</del><ins>+        if (!_page-&gt;editorState().selectionIsRange || !_page-&gt;editorState().postLayoutData().isReplaceAllowed || ![[UIKeyboardImpl activeInstance] autocorrectSpellingEnabled])
</ins><span class="cx">             return NO;
</span><span class="cx">         return UIKeyboardCurrentInputModeAllowsChineseOrJapaneseReanalysisForText([self selectedText]);
</span><span class="cx">     }
</span><span class="lines">@@ -1530,7 +1534,7 @@
</span><span class="cx"> 
</span><span class="cx"> - (void)_showDictionary:(NSString *)text
</span><span class="cx"> {
</span><del>-    CGRect presentationRect = _page-&gt;editorState().selectionRects[0].rect();
</del><ins>+    CGRect presentationRect = _page-&gt;editorState().postLayoutData().selectionRects[0].rect();
</ins><span class="cx">     if (_textSelectionAssistant)
</span><span class="cx">         [_textSelectionAssistant showDictionaryFor:text fromRect:presentationRect];
</span><span class="cx">     else
</span><span class="lines">@@ -1937,18 +1941,18 @@
</span><span class="cx"> 
</span><span class="cx"> - (UTF32Char)_characterBeforeCaretSelection
</span><span class="cx"> {
</span><del>-    return _page-&gt;editorState().characterBeforeSelection;
</del><ins>+    return _page-&gt;editorState().postLayoutData().characterBeforeSelection;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (UTF32Char)_characterInRelationToCaretSelection:(int)amount
</span><span class="cx"> {
</span><span class="cx">     switch (amount) {
</span><span class="cx">     case 0:
</span><del>-        return _page-&gt;editorState().characterAfterSelection;
</del><ins>+        return _page-&gt;editorState().postLayoutData().characterAfterSelection;
</ins><span class="cx">     case -1:
</span><del>-        return _page-&gt;editorState().characterBeforeSelection;
</del><ins>+        return _page-&gt;editorState().postLayoutData().characterBeforeSelection;
</ins><span class="cx">     case -2:
</span><del>-        return _page-&gt;editorState().twoCharacterBeforeSelection;
</del><ins>+        return _page-&gt;editorState().postLayoutData().twoCharacterBeforeSelection;
</ins><span class="cx">     default:
</span><span class="cx">         return 0;
</span><span class="cx">     }
</span><span class="lines">@@ -1956,7 +1960,7 @@
</span><span class="cx"> 
</span><span class="cx"> - (BOOL)_selectionAtDocumentStart
</span><span class="cx"> {
</span><del>-    return !_page-&gt;editorState().characterBeforeSelection;
</del><ins>+    return !_page-&gt;editorState().postLayoutData().characterBeforeSelection;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (CGRect)textFirstRect
</span><span class="lines">@@ -2130,8 +2134,9 @@
</span><span class="cx"> 
</span><span class="cx"> - (UITextRange *)selectedTextRange
</span><span class="cx"> {
</span><del>-    FloatRect startRect = _page-&gt;editorState().caretRectAtStart;
-    FloatRect endRect = _page-&gt;editorState().caretRectAtEnd;
</del><ins>+    auto&amp; postLayoutEditorStateData = _page-&gt;editorState().postLayoutData();
+    FloatRect startRect = postLayoutEditorStateData.caretRectAtStart;
+    FloatRect endRect = postLayoutEditorStateData.caretRectAtEnd;
</ins><span class="cx">     double inverseScale = [self inverseScale];
</span><span class="cx">     // We want to keep the original caret width, while the height scales with
</span><span class="cx">     // the content taking orientation into account.
</span><span class="lines">@@ -2159,7 +2164,7 @@
</span><span class="cx">                                  startRect:startRect
</span><span class="cx">                                    endRect:endRect
</span><span class="cx">                             selectionRects:[self webSelectionRects]
</span><del>-                        selectedTextLength:_page-&gt;editorState().selectedTextLength];
</del><ins>+                        selectedTextLength:postLayoutEditorStateData.selectedTextLength];
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (CGRect)caretRectForPosition:(UITextPosition *)position
</span><span class="lines">@@ -2680,7 +2685,7 @@
</span><span class="cx"> 
</span><span class="cx"> - (BOOL)hasContent
</span><span class="cx"> {
</span><del>-    return _page-&gt;editorState().hasContent;
</del><ins>+    return _page-&gt;editorState().postLayoutData().hasContent;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (void)selectAll
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebCoreSupportWebEditorClientcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.cpp (182602 => 182603)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.cpp        2015-04-09 16:20:21 UTC (rev 182602)
+++ trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.cpp        2015-04-09 18:31:51 UTC (rev 182603)
</span><span class="lines">@@ -190,6 +190,11 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebEditorClient::didChangeSelectionAndUpdateLayout()
+{
+    m_page-&gt;sendPostLayoutEditorStateIfNeeded();
+}
+
</ins><span class="cx"> void WebEditorClient::discardedComposition(Frame*)
</span><span class="cx"> {
</span><span class="cx">     m_page-&gt;discardedComposition();
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebCoreSupportWebEditorClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.h (182602 => 182603)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.h        2015-04-09 16:20:21 UTC (rev 182602)
+++ trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.h        2015-04-09 18:31:51 UTC (rev 182603)
</span><span class="lines">@@ -64,6 +64,7 @@
</span><span class="cx">     virtual void didBeginEditing() override;
</span><span class="cx">     virtual void respondToChangedContents() override;
</span><span class="cx">     virtual void respondToChangedSelection(WebCore::Frame*) override;
</span><ins>+    virtual void didChangeSelectionAndUpdateLayout() override;
</ins><span class="cx">     virtual void discardedComposition(WebCore::Frame*) override;
</span><span class="cx">     virtual void didEndEditing() override;
</span><span class="cx">     virtual void willWriteSelectionToPasteboard(WebCore::Range*) override;
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebPagecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp (182602 => 182603)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp        2015-04-09 16:20:21 UTC (rev 182602)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp        2015-04-09 18:31:51 UTC (rev 182603)
</span><span class="lines">@@ -739,7 +739,7 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-EditorState WebPage::editorState() const
</del><ins>+EditorState WebPage::editorState(IncludePostLayoutDataHint shouldIncludePostLayoutData) const
</ins><span class="cx"> {
</span><span class="cx">     Frame&amp; frame = m_page-&gt;focusController().focusedOrMainFrame();
</span><span class="cx"> 
</span><span class="lines">@@ -764,7 +764,7 @@
</span><span class="cx">     result.hasComposition = frame.editor().hasComposition();
</span><span class="cx">     result.shouldIgnoreCompositionSelectionChange = frame.editor().ignoreCompositionSelectionChange();
</span><span class="cx">     
</span><del>-    platformEditorState(frame, result);
</del><ins>+    platformEditorState(frame, result, shouldIncludePostLayoutData);
</ins><span class="cx"> 
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="lines">@@ -4365,19 +4365,29 @@
</span><span class="cx"> 
</span><span class="cx"> void WebPage::didChangeSelection()
</span><span class="cx"> {
</span><ins>+    Frame&amp; frame = m_page-&gt;focusController().focusedOrMainFrame();
+    FrameView* view = frame.view();
+    bool needsLayout = view &amp;&amp; view-&gt;needsLayout();
+
+    // If there is a layout pending, we should avoid populating EditorState that require layout to be done or it will
+    // trigger a synchronous layout every time the selection changes. sendPostLayoutEditorStateIfNeeded() will be called
+    // to send the full editor state after layout is done if we send a partial editor state here.
+    auto editorState = this-&gt;editorState(needsLayout ? IncludePostLayoutDataHint::No : IncludePostLayoutDataHint::Yes);
+    ASSERT_WITH_MESSAGE(needsLayout == (view &amp;&amp; view-&gt;needsLayout()), &quot;Calling editorState() should not cause a synchronous layout.&quot;);
+    m_isEditorStateMissingPostLayoutData = editorState.isMissingPostLayoutData;
+
</ins><span class="cx"> #if PLATFORM(MAC) &amp;&amp; USE(ASYNC_NSTEXTINPUTCLIENT)
</span><del>-    Frame&amp; frame = m_page-&gt;focusController().focusedOrMainFrame();
</del><span class="cx">     // Abandon the current inline input session if selection changed for any other reason but an input method direct action.
</span><span class="cx">     // FIXME: This logic should be in WebCore.
</span><span class="cx">     // FIXME: Many changes that affect composition node do not go through didChangeSelection(). We need to do something when DOM manipulation affects the composition, because otherwise input method's idea about it will be different from Editor's.
</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>+        send(Messages::WebPageProxy::CompositionWasCanceled(editorState));
</ins><span class="cx">     } else
</span><del>-        send(Messages::WebPageProxy::EditorStateChanged(editorState()));
</del><ins>+        send(Messages::WebPageProxy::EditorStateChanged(editorState));
</ins><span class="cx"> #else
</span><del>-    send(Messages::WebPageProxy::EditorStateChanged(editorState()), pageID(), IPC::DispatchMessageEvenWhenWaitingForSyncReply);
</del><ins>+    send(Messages::WebPageProxy::EditorStateChanged(editorState), pageID(), IPC::DispatchMessageEvenWhenWaitingForSyncReply);
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="lines">@@ -4385,6 +4395,15 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebPage::sendPostLayoutEditorStateIfNeeded()
+{
+    if (!m_isEditorStateMissingPostLayoutData)
+        return;
+
+    send(Messages::WebPageProxy::EditorStateChanged(editorState(IncludePostLayoutDataHint::Yes)), pageID(), IPC::DispatchMessageEvenWhenWaitingForSyncReply);
+    m_isEditorStateMissingPostLayoutData = false;
+}
+
</ins><span class="cx"> void WebPage::discardedComposition()
</span><span class="cx"> {
</span><span class="cx">     send(Messages::WebPageProxy::CompositionWasCanceled(editorState()));
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebPageh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h (182602 => 182603)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h        2015-04-09 16:20:21 UTC (rev 182602)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h        2015-04-09 18:31:51 UTC (rev 182603)
</span><span class="lines">@@ -327,7 +327,9 @@
</span><span class="cx">     WebCore::WebGLLoadPolicy resolveWebGLPolicyForURL(WebFrame*, const String&amp;);
</span><span class="cx"> #endif // ENABLE(WEBGL)
</span><span class="cx">     
</span><del>-    EditorState editorState() const;
</del><ins>+    enum class IncludePostLayoutDataHint { No, Yes };
+    EditorState editorState(IncludePostLayoutDataHint = IncludePostLayoutDataHint::Yes) const;
+    void sendPostLayoutEditorStateIfNeeded();
</ins><span class="cx"> 
</span><span class="cx">     String renderTreeExternalRepresentation() const;
</span><span class="cx">     String renderTreeExternalRepresentationForPrinting() const;
</span><span class="lines">@@ -878,7 +880,7 @@
</span><span class="cx"> 
</span><span class="cx">     void platformInitialize();
</span><span class="cx">     void platformDetach();
</span><del>-    void platformEditorState(WebCore::Frame&amp;, EditorState&amp; result) const;
</del><ins>+    void platformEditorState(WebCore::Frame&amp;, EditorState&amp; result, IncludePostLayoutDataHint) const;
</ins><span class="cx"> 
</span><span class="cx">     void didReceiveWebPageMessage(IPC::Connection&amp;, IPC::MessageDecoder&amp;);
</span><span class="cx">     void didReceiveSyncWebPageMessage(IPC::Connection&amp;, IPC::MessageDecoder&amp;, std::unique_ptr&lt;IPC::MessageEncoder&gt;&amp;);
</span><span class="lines">@@ -1353,6 +1355,7 @@
</span><span class="cx"> 
</span><span class="cx">     bool m_mainFrameProgressCompleted;
</span><span class="cx">     bool m_shouldDispatchFakeMouseMoveEvents;
</span><ins>+    bool m_isEditorStateMissingPostLayoutData { false };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebKit
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageeflWebPageEflcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/efl/WebPageEfl.cpp (182602 => 182603)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/efl/WebPageEfl.cpp        2015-04-09 16:20:21 UTC (rev 182602)
+++ trunk/Source/WebKit2/WebProcess/WebPage/efl/WebPageEfl.cpp        2015-04-09 18:31:51 UTC (rev 182603)
</span><span class="lines">@@ -82,7 +82,7 @@
</span><span class="cx">     notImplemented();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebPage::platformEditorState(Frame&amp;, EditorState&amp;) const
</del><ins>+void WebPage::platformEditorState(Frame&amp;, EditorState&amp;, IncludePostLayoutDataHint) const
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPagegtkWebPageGtkcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/gtk/WebPageGtk.cpp (182602 => 182603)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/gtk/WebPageGtk.cpp        2015-04-09 16:20:21 UTC (rev 182602)
+++ trunk/Source/WebKit2/WebProcess/WebPage/gtk/WebPageGtk.cpp        2015-04-09 18:31:51 UTC (rev 182603)
</span><span class="lines">@@ -68,7 +68,7 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebPage::platformEditorState(Frame&amp; frame, EditorState&amp; result) const
</del><ins>+void WebPage::platformEditorState(Frame&amp; frame, EditorState&amp; result, IncludePostLayoutDataHint) const
</ins><span class="cx"> {
</span><span class="cx">     result.cursorRect = frame.selection().absoluteCaretBounds();
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageiosWebPageIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm (182602 => 182603)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm        2015-04-09 16:20:21 UTC (rev 182602)
+++ trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm        2015-04-09 18:31:51 UTC (rev 182603)
</span><span class="lines">@@ -128,9 +128,8 @@
</span><span class="cx">     notImplemented();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebPage::platformEditorState(Frame&amp; frame, EditorState&amp; result) const
</del><ins>+void WebPage::platformEditorState(Frame&amp; frame, EditorState&amp; result, IncludePostLayoutDataHint shouldIncludePostLayoutData) const
</ins><span class="cx"> {
</span><del>-    const VisibleSelection&amp; selection = frame.selection().selection();
</del><span class="cx">     if (frame.editor().hasComposition()) {
</span><span class="cx">         RefPtr&lt;Range&gt; compositionRange = frame.editor().compositionRange();
</span><span class="cx">         Vector&lt;WebCore::SelectionRect&gt; compositionRects;
</span><span class="lines">@@ -145,34 +144,46 @@
</span><span class="cx">             result.markedText = plainTextReplacingNoBreakSpace(compositionRange.get());
</span><span class="cx">         }
</span><span class="cx">     }
</span><ins>+
+    // We only set the remaining EditorState entries if the layout is done. To compute these
+    // entries, we need the layout to be done and we don't want to trigger a synchronous
+    // layout as this would be bad for performance. If we have a composition, we send everything
+    // right away as the UIProcess needs the caretRects ASAP for marked text.
+    if (shouldIncludePostLayoutData == IncludePostLayoutDataHint::No &amp;&amp; !frame.editor().hasComposition()) {
+        result.isMissingPostLayoutData = true;
+        return;
+    }
+
+    auto&amp; postLayoutData = result.postLayoutData();
</ins><span class="cx">     FrameView* view = frame.view();
</span><ins>+    const VisibleSelection&amp; selection = frame.selection().selection();
</ins><span class="cx">     if (selection.isCaret()) {
</span><del>-        result.caretRectAtStart = view-&gt;contentsToRootView(frame.selection().absoluteCaretBounds());
-        result.caretRectAtEnd = result.caretRectAtStart;
</del><ins>+        postLayoutData.caretRectAtStart = view-&gt;contentsToRootView(frame.selection().absoluteCaretBounds());
+        postLayoutData.caretRectAtEnd = postLayoutData.caretRectAtStart;
</ins><span class="cx">         // FIXME: The following check should take into account writing direction.
</span><del>-        result.isReplaceAllowed = result.isContentEditable &amp;&amp; atBoundaryOfGranularity(selection.start(), WordGranularity, DirectionForward);
-        result.wordAtSelection = plainTextReplacingNoBreakSpace(wordRangeFromPosition(selection.start()).get());
</del><ins>+        postLayoutData.isReplaceAllowed = result.isContentEditable &amp;&amp; atBoundaryOfGranularity(selection.start(), WordGranularity, DirectionForward);
+        postLayoutData.wordAtSelection = plainTextReplacingNoBreakSpace(wordRangeFromPosition(selection.start()).get());
</ins><span class="cx">         if (selection.isContentEditable()) {
</span><del>-            charactersAroundPosition(selection.start(), result.characterAfterSelection, result.characterBeforeSelection, result.twoCharacterBeforeSelection);
</del><ins>+            charactersAroundPosition(selection.start(), postLayoutData.characterAfterSelection, postLayoutData.characterBeforeSelection, postLayoutData.twoCharacterBeforeSelection);
</ins><span class="cx">             Node* root = selection.rootEditableElement();
</span><del>-            result.hasContent = root &amp;&amp; root-&gt;hasChildNodes() &amp;&amp; !isEndOfEditableOrNonEditableContent(firstPositionInNode(root));
</del><ins>+            postLayoutData.hasContent = root &amp;&amp; root-&gt;hasChildNodes() &amp;&amp; !isEndOfEditableOrNonEditableContent(firstPositionInNode(root));
</ins><span class="cx">         }
</span><span class="cx">     } else if (selection.isRange()) {
</span><del>-        result.caretRectAtStart = view-&gt;contentsToRootView(VisiblePosition(selection.start()).absoluteCaretBounds());
-        result.caretRectAtEnd = view-&gt;contentsToRootView(VisiblePosition(selection.end()).absoluteCaretBounds());
</del><ins>+        postLayoutData.caretRectAtStart = view-&gt;contentsToRootView(VisiblePosition(selection.start()).absoluteCaretBounds());
+        postLayoutData.caretRectAtEnd = view-&gt;contentsToRootView(VisiblePosition(selection.end()).absoluteCaretBounds());
</ins><span class="cx">         RefPtr&lt;Range&gt; selectedRange = selection.toNormalizedRange();
</span><span class="cx">         String selectedText;
</span><span class="cx">         if (selectedRange) {
</span><del>-            selectedRange-&gt;collectSelectionRects(result.selectionRects);
-            convertSelectionRectsToRootView(view, result.selectionRects);
</del><ins>+            selectedRange-&gt;collectSelectionRects(postLayoutData.selectionRects);
+            convertSelectionRectsToRootView(view, postLayoutData.selectionRects);
</ins><span class="cx">             selectedText = plainTextReplacingNoBreakSpace(selectedRange.get(), TextIteratorDefaultBehavior, true);
</span><del>-            result.selectedTextLength = selectedText.length();
</del><ins>+            postLayoutData.selectedTextLength = selectedText.length();
</ins><span class="cx">             const int maxSelectedTextLength = 200;
</span><span class="cx">             if (selectedText.length() &lt;= maxSelectedTextLength)
</span><del>-                result.wordAtSelection = selectedText;
</del><ins>+                postLayoutData.wordAtSelection = selectedText;
</ins><span class="cx">         }
</span><span class="cx">         // FIXME: We should disallow replace when the string contains only CJ characters.
</span><del>-        result.isReplaceAllowed = result.isContentEditable &amp;&amp; !result.isInPasswordField &amp;&amp; !selectedText.containsOnlyWhitespace();
</del><ins>+        postLayoutData.isReplaceAllowed = result.isContentEditable &amp;&amp; !result.isInPasswordField &amp;&amp; !selectedText.containsOnlyWhitespace();
</ins><span class="cx">     }
</span><span class="cx">     if (!selection.isNone()) {
</span><span class="cx">         Node* nodeToRemove;
</span><span class="lines">@@ -181,18 +192,18 @@
</span><span class="cx">             CTFontSymbolicTraits traits = font ? CTFontGetSymbolicTraits(font) : 0;
</span><span class="cx">             
</span><span class="cx">             if (traits &amp; kCTFontTraitBold)
</span><del>-                result.typingAttributes |= AttributeBold;
</del><ins>+                postLayoutData.typingAttributes |= AttributeBold;
</ins><span class="cx">             if (traits &amp; kCTFontTraitItalic)
</span><del>-                result.typingAttributes |= AttributeItalics;
</del><ins>+                postLayoutData.typingAttributes |= AttributeItalics;
</ins><span class="cx">             
</span><span class="cx">             RefPtr&lt;EditingStyle&gt; typingStyle = frame.selection().typingStyle();
</span><span class="cx">             if (typingStyle &amp;&amp; typingStyle-&gt;style()) {
</span><span class="cx">                 String value = typingStyle-&gt;style()-&gt;getPropertyValue(CSSPropertyWebkitTextDecorationsInEffect);
</span><span class="cx">                 if (value.contains(&quot;underline&quot;))
</span><del>-                    result.typingAttributes |= AttributeUnderline;
</del><ins>+                    postLayoutData.typingAttributes |= AttributeUnderline;
</ins><span class="cx">             } else {
</span><span class="cx">                 if (style-&gt;textDecorationsInEffect() &amp; TextDecorationUnderline)
</span><del>-                    result.typingAttributes |= AttributeUnderline;
</del><ins>+                    postLayoutData.typingAttributes |= AttributeUnderline;
</ins><span class="cx">             }
</span><span class="cx">             
</span><span class="cx">             if (nodeToRemove)
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPagemacWebPageMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm (182602 => 182603)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm        2015-04-09 16:20:21 UTC (rev 182602)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm        2015-04-09 18:31:51 UTC (rev 182603)
</span><span class="lines">@@ -122,7 +122,7 @@
</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) const
</del><ins>+void WebPage::platformEditorState(Frame&amp; frame, EditorState&amp; result, IncludePostLayoutDataHint) const
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>