<!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>[180768] trunk/Source/WebKit2</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/180768">180768</a></dd>
<dt>Author</dt> <dd>enrica@apple.com</dd>
<dt>Date</dt> <dd>2015-02-27 10:50:20 -0800 (Fri, 27 Feb 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>[WK2] REGRESSION(<a href="http://trac.webkit.org/projects/webkit/changeset/180465">r180465</a>): WebKit::WebPage::editorState() triggers a layout.
https://bugs.webkit.org/show_bug.cgi?id=142015

Reviewed by Alexey Proskuryakov.

We no longer compute the font information at selection
when we update the editor state.
Instead, we request the font information only when the selection
changes and the font panel is visible.
I added an observer to be notified of the font panel visibility
changes to update NSFontManager to reflect the font at the
current selection.

* Shared/EditorState.cpp:
(WebKit::EditorState::encode):
(WebKit::EditorState::decode):
* Shared/EditorState.h:
(WebKit::EditorState::EditorState):
* UIProcess/API/mac/WKView.mm:
(-[WKView updateFontPanelIfNeeded]):
(-[WKView _selectionChanged]):
(-[WKView addWindowObserversForWindow:]):
(-[WKView removeWindowObservers]):
(-[WKView observeValueForKeyPath:ofObject:change:context:]):
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:
* UIProcess/mac/WebPageProxyMac.mm:
(WebKit::WebPageProxy::fontAtSelection):
(WebKit::WebPageProxy::fontAtSelectionCallback):
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:
* WebProcess/WebPage/mac/WebPageMac.mm:
(WebKit::WebPage::platformEditorState):
(WebKit::WebPage::fontAtSelection):</pre>

<h3>Modified Paths</h3>
<ul>
<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="#trunkSourceWebKit2UIProcessAPImacWKViewmm">trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebPageProxyh">trunk/Source/WebKit2/UIProcess/WebPageProxy.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebPageProxymessagesin">trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in</a></li>
<li><a href="#trunkSourceWebKit2UIProcessmacWebPageProxyMacmm">trunk/Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm</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>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (180767 => 180768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2015-02-27 18:43:48 UTC (rev 180767)
+++ trunk/Source/WebKit2/ChangeLog        2015-02-27 18:50:20 UTC (rev 180768)
</span><span class="lines">@@ -1,3 +1,40 @@
</span><ins>+2015-02-26  Enrica Casucci  &lt;enrica@apple.com&gt;
+
+        [WK2] REGRESSION(r180465): WebKit::WebPage::editorState() triggers a layout.
+        https://bugs.webkit.org/show_bug.cgi?id=142015
+
+        Reviewed by Alexey Proskuryakov.
+
+        We no longer compute the font information at selection
+        when we update the editor state.
+        Instead, we request the font information only when the selection
+        changes and the font panel is visible.
+        I added an observer to be notified of the font panel visibility
+        changes to update NSFontManager to reflect the font at the
+        current selection.
+
+        * Shared/EditorState.cpp:
+        (WebKit::EditorState::encode):
+        (WebKit::EditorState::decode):
+        * Shared/EditorState.h:
+        (WebKit::EditorState::EditorState):
+        * UIProcess/API/mac/WKView.mm:
+        (-[WKView updateFontPanelIfNeeded]):
+        (-[WKView _selectionChanged]):
+        (-[WKView addWindowObserversForWindow:]):
+        (-[WKView removeWindowObservers]):
+        (-[WKView observeValueForKeyPath:ofObject:change:context:]):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.messages.in:
+        * UIProcess/mac/WebPageProxyMac.mm:
+        (WebKit::WebPageProxy::fontAtSelection):
+        (WebKit::WebPageProxy::fontAtSelectionCallback):
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+        * WebProcess/WebPage/mac/WebPageMac.mm:
+        (WebKit::WebPage::platformEditorState):
+        (WebKit::WebPage::fontAtSelection):
+
</ins><span class="cx"> 2015-02-27  Brady Eidson  &lt;beidson@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Add API to remove a single content filter.
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedEditorStatecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/EditorState.cpp (180767 => 180768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/EditorState.cpp        2015-02-27 18:43:48 UTC (rev 180767)
+++ trunk/Source/WebKit2/Shared/EditorState.cpp        2015-02-27 18:50:20 UTC (rev 180768)
</span><span class="lines">@@ -42,12 +42,6 @@
</span><span class="cx">     encoder &lt;&lt; isInPlugin;
</span><span class="cx">     encoder &lt;&lt; hasComposition;
</span><span class="cx"> 
</span><del>-#if PLATFORM(MAC)
-    encoder &lt;&lt; fontName;
-    encoder &lt;&lt; fontSize;
-    encoder &lt;&lt; selectionHasMultipleFonts;
-#endif
-
</del><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">     encoder &lt;&lt; isReplaceAllowed;
</span><span class="cx">     encoder &lt;&lt; hasContent;
</span><span class="lines">@@ -96,17 +90,6 @@
</span><span class="cx">     if (!decoder.decode(result.hasComposition))
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><del>-#if PLATFORM(MAC)
-    if (!decoder.decode(result.fontName))
-        return false;
-
-    if (!decoder.decode(result.fontSize))
-        return false;
-
-    if (!decoder.decode(result.selectionHasMultipleFonts))
-        return false;
-#endif
-
</del><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">     if (!decoder.decode(result.isReplaceAllowed))
</span><span class="cx">         return false;
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedEditorStateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/EditorState.h (180767 => 180768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/EditorState.h        2015-02-27 18:43:48 UTC (rev 180767)
+++ trunk/Source/WebKit2/Shared/EditorState.h        2015-02-27 18:50:20 UTC (rev 180768)
</span><span class="lines">@@ -53,10 +53,6 @@
</span><span class="cx">         , isInPasswordField(false)
</span><span class="cx">         , isInPlugin(false)
</span><span class="cx">         , hasComposition(false)
</span><del>-#if PLATFORM(MAC)
-        , selectionHasMultipleFonts(false)
-        , fontSize(0)
-#endif
</del><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">         , isReplaceAllowed(false)
</span><span class="cx">         , hasContent(false)
</span><span class="lines">@@ -79,12 +75,6 @@
</span><span class="cx">     bool isInPlugin;
</span><span class="cx">     bool hasComposition;
</span><span class="cx"> 
</span><del>-#if PLATFORM(MAC)
-    bool selectionHasMultipleFonts;
-    String fontName;
-    double fontSize;
-#endif
-
</del><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">     bool isReplaceAllowed;
</span><span class="cx">     bool hasContent;
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPImacWKViewmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm (180767 => 180768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm        2015-02-27 18:43:48 UTC (rev 180767)
+++ trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm        2015-02-27 18:50:20 UTC (rev 180768)
</span><span class="lines">@@ -739,15 +739,25 @@
</span><span class="cx"> 
</span><span class="cx"> // Font panel support.
</span><span class="cx"> 
</span><del>-- (void)_selectionChanged
</del><ins>+- (void)updateFontPanelIfNeeded
</ins><span class="cx"> {
</span><span class="cx">     const EditorState&amp; editorState = _data-&gt;_page-&gt;editorState();
</span><span class="cx">     if (editorState.selectionIsNone || !editorState.isContentEditable)
</span><span class="cx">         return;
</span><del>-    NSFont *font = [NSFont fontWithName:editorState.fontName size:editorState.fontSize];
-    [[NSFontManager sharedFontManager] setSelectedFont:font isMultiple:editorState.selectionHasMultipleFonts];
</del><ins>+    if ([NSFontPanel sharedFontPanelExists] &amp;&amp; [[NSFontPanel sharedFontPanel] isVisible]) {
+        _data-&gt;_page-&gt;fontAtSelection([](const String&amp; fontName, double fontSize, bool selectionHasMultipleFonts, CallbackBase::Error error) {
+            NSFont *font = [NSFont fontWithName:fontName size:fontSize];
+            if (font)
+                [[NSFontManager sharedFontManager] setSelectedFont:font isMultiple:selectionHasMultipleFonts];
+        });
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (void)_selectionChanged
+{
+    [self updateFontPanelIfNeeded];
+}
+
</ins><span class="cx"> - (void)changeFont:(id)sender
</span><span class="cx"> {
</span><span class="cx">     NSFontManager *fontManager = [NSFontManager sharedFontManager];
</span><span class="lines">@@ -2509,6 +2519,10 @@
</span><span class="cx">                                                      name:@&quot;_NSWindowDidChangeContentsHostedInLayerSurfaceNotification&quot; object:window];
</span><span class="cx">         [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowDidChangeOcclusionState:)
</span><span class="cx">                                                      name:NSWindowDidChangeOcclusionStateNotification object:window];
</span><ins>+        [[NSFontPanel sharedFontPanel] addObserver:self
+                                        forKeyPath:@&quot;visible&quot;
+                                           options:NSKeyValueObservingOptionNew
+                                           context:nil];
</ins><span class="cx"> #if __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 101000
</span><span class="cx">         [window addObserver:self forKeyPath:@&quot;contentLayoutRect&quot; options:NSKeyValueObservingOptionInitial context:keyValueObservingContext];
</span><span class="cx">         [window addObserver:self forKeyPath:@&quot;titlebarAppearsTransparent&quot; options:NSKeyValueObservingOptionInitial context:keyValueObservingContext];
</span><span class="lines">@@ -2535,6 +2549,7 @@
</span><span class="cx">     [[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowDidChangeScreenNotification object:window];
</span><span class="cx">     [[NSNotificationCenter defaultCenter] removeObserver:self name:@&quot;_NSWindowDidChangeContentsHostedInLayerSurfaceNotification&quot; object:window];
</span><span class="cx">     [[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowDidChangeOcclusionStateNotification object:window];
</span><ins>+    [[NSFontPanel sharedFontPanel] removeObserver:self forKeyPath:@&quot;visible&quot; context:nil];
</ins><span class="cx"> #if __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 101000
</span><span class="cx">     [window removeObserver:self forKeyPath:@&quot;contentLayoutRect&quot; context:keyValueObservingContext];
</span><span class="cx">     [window removeObserver:self forKeyPath:@&quot;titlebarAppearsTransparent&quot; context:keyValueObservingContext];
</span><span class="lines">@@ -3714,8 +3729,15 @@
</span><span class="cx">         self._topContentInset = 0;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#endif
+
</ins><span class="cx"> - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
</span><span class="cx"> {
</span><ins>+    if ([NSFontPanel sharedFontPanelExists] &amp;&amp; object == [NSFontPanel sharedFontPanel]) {
+        [self updateFontPanelIfNeeded];
+        return;
+    }
+#if __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 101000
</ins><span class="cx">     if (context == keyValueObservingContext) {
</span><span class="cx">         if ([keyPath isEqualToString:@&quot;contentLayoutRect&quot;] || [keyPath isEqualToString:@&quot;titlebarAppearsTransparent&quot;])
</span><span class="cx">             [self _updateContentInsetsIfAutomatic];
</span><span class="lines">@@ -3723,9 +3745,9 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
</span><ins>+#endif
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-#endif
</del><span class="cx"> 
</span><span class="cx"> - (void)_didFirstVisuallyNonEmptyLayoutForMainFrame
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.h (180767 => 180768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.h        2015-02-27 18:43:48 UTC (rev 180767)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.h        2015-02-27 18:50:20 UTC (rev 180768)
</span><span class="lines">@@ -228,6 +228,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(MAC)
</span><span class="cx"> typedef GenericCallback&lt;const AttributedString&amp;, const EditingRange&amp;&gt; AttributedStringForCharacterRangeCallback;
</span><ins>+typedef GenericCallback&lt;const String&amp;, double, bool&gt; FontAtSelectionCallback;
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="lines">@@ -539,6 +540,7 @@
</span><span class="cx">     void insertDictatedTextAsync(const String&amp; text, const EditingRange&amp; replacementRange, const Vector&lt;WebCore::TextAlternativeWithRange&gt;&amp; dictationAlternatives, bool registerUndoGroup);
</span><span class="cx">     void attributedSubstringForCharacterRangeAsync(const EditingRange&amp;, std::function&lt;void (const AttributedString&amp;, const EditingRange&amp;, CallbackBase::Error)&gt;);
</span><span class="cx">     void setFont(const String&amp; fontFamily, double fontSize, uint64_t fontTraits);
</span><ins>+    void fontAtSelection(std::function&lt;void (const String&amp;, double, bool, CallbackBase::Error)&gt;);
</ins><span class="cx"> 
</span><span class="cx"> #if !USE(ASYNC_NSTEXTINPUTCLIENT)
</span><span class="cx">     bool insertText(const String&amp; text, const EditingRange&amp; replacementRange);
</span><span class="lines">@@ -1263,6 +1265,7 @@
</span><span class="cx">     void rectForCharacterRangeCallback(const WebCore::IntRect&amp;, const EditingRange&amp;, uint64_t);
</span><span class="cx"> #if PLATFORM(MAC)
</span><span class="cx">     void attributedStringForCharacterRangeCallback(const AttributedString&amp;, const EditingRange&amp;, uint64_t);
</span><ins>+    void fontAtSelectionCallback(const String&amp;, double, bool, uint64_t);
</ins><span class="cx"> #endif
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">     void gestureCallback(const WebCore::IntPoint&amp;, uint32_t, uint32_t, uint32_t, uint64_t);
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxymessagesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in (180767 => 180768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in        2015-02-27 18:43:48 UTC (rev 180767)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in        2015-02-27 18:50:20 UTC (rev 180768)
</span><span class="lines">@@ -171,6 +171,7 @@
</span><span class="cx">     RectForCharacterRangeCallback(WebCore::IntRect rect, struct WebKit::EditingRange actualRange, uint64_t callbackID)
</span><span class="cx"> #if PLATFORM(MAC)
</span><span class="cx">     AttributedStringForCharacterRangeCallback(struct WebKit::AttributedString string, struct WebKit::EditingRange actualRange, uint64_t callbackID)
</span><ins>+    FontAtSelectionCallback(String fontName, double fontSize, bool selectioHasMultipleFonts, uint64_t callbackID)
</ins><span class="cx"> #endif
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">     GestureCallback(WebCore::IntPoint point, uint32_t gestureType, uint32_t gestureState, uint32_t flags, uint64_t callbackID)
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessmacWebPageProxyMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm (180767 => 180768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm        2015-02-27 18:43:48 UTC (rev 180767)
+++ trunk/Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm        2015-02-27 18:50:20 UTC (rev 180768)
</span><span class="lines">@@ -330,6 +330,30 @@
</span><span class="cx">     callback-&gt;performCallbackWithReturnValue(string, actualRange);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebPageProxy::fontAtSelection(std::function&lt;void (const String&amp;, double, bool, CallbackBase::Error)&gt;callbackFunction)
+{
+    if (!isValid()) {
+        callbackFunction(String(), 0, false, CallbackBase::Error::Unknown);
+        return;
+    }
+    
+    uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process-&gt;throttler().backgroundActivityToken());
+    
+    process().send(Messages::WebPage::FontAtSelection(callbackID), m_pageID);
+}
+
+void WebPageProxy::fontAtSelectionCallback(const String&amp; fontName, double fontSize, bool selectionHasMultipleFonts, uint64_t callbackID)
+{
+    auto callback = m_callbacks.take&lt;FontAtSelectionCallback&gt;(callbackID);
+    if (!callback) {
+        // FIXME: Log error or assert.
+        // this can validly happen if a load invalidated the callback, though
+        return;
+    }
+    
+    callback-&gt;performCallbackWithReturnValue(fontName, fontSize, selectionHasMultipleFonts);
+}
+
</ins><span class="cx"> String WebPageProxy::stringSelectionForPasteboard()
</span><span class="cx"> {
</span><span class="cx">     String value;
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebPageh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h (180767 => 180768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h        2015-02-27 18:43:48 UTC (rev 180767)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h        2015-02-27 18:50:20 UTC (rev 180768)
</span><span class="lines">@@ -622,6 +622,7 @@
</span><span class="cx"> #if PLATFORM(MAC)
</span><span class="cx">     void insertDictatedTextAsync(const String&amp; text, const EditingRange&amp; replacementRange, const Vector&lt;WebCore::DictationAlternative&gt;&amp; dictationAlternativeLocations, bool registerUndoGroup = false);
</span><span class="cx">     void attributedSubstringForCharacterRangeAsync(const EditingRange&amp;, uint64_t callbackID);
</span><ins>+    void fontAtSelection(uint64_t callbackID);
</ins><span class="cx"> #if !USE(ASYNC_NSTEXTINPUTCLIENT)
</span><span class="cx">     void insertText(const String&amp; text, const EditingRange&amp; replacementRange, bool&amp; handled, EditorState&amp; newState);
</span><span class="cx">     void setComposition(const String&amp; text, Vector&lt;WebCore::CompositionUnderline&gt; underlines, const EditingRange&amp; selectionRange, const EditingRange&amp; replacementRange, EditorState&amp; newState);
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebPagemessagesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in (180767 => 180768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in        2015-02-27 18:43:48 UTC (rev 180767)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in        2015-02-27 18:50:20 UTC (rev 180768)
</span><span class="lines">@@ -360,6 +360,7 @@
</span><span class="cx"> #if PLATFORM(MAC)
</span><span class="cx">     InsertDictatedTextAsync(String text, struct WebKit::EditingRange replacementRange, Vector&lt;WebCore::DictationAlternative&gt; dictationAlternatives, bool registerUndoGroup)
</span><span class="cx">     AttributedSubstringForCharacterRangeAsync(struct WebKit::EditingRange range, uint64_t callbackID);
</span><ins>+    FontAtSelection(uint64_t callbackID);
</ins><span class="cx"> #endif
</span><span class="cx"> #if PLATFORM(MAC) &amp;&amp; !USE(ASYNC_NSTEXTINPUTCLIENT)
</span><span class="cx">     InsertText(String text, struct WebKit::EditingRange replacementRange) -&gt; (bool handled, struct WebKit::EditorState newState)
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPagemacWebPageMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm (180767 => 180768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm        2015-02-27 18:43:48 UTC (rev 180767)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm        2015-02-27 18:50:20 UTC (rev 180768)
</span><span class="lines">@@ -120,15 +120,6 @@
</span><span class="cx"> 
</span><span class="cx"> void WebPage::platformEditorState(Frame&amp; frame, EditorState&amp; result) const
</span><span class="cx"> {
</span><del>-    if (frame.selection().selection().isNone())
-        return;
-    
-    const Font* font = frame.editor().fontForSelection(result.selectionHasMultipleFonts);
-    NSFont *nsFont = font ? font-&gt;getNSFont() : nil;
-    if (nsFont) {
-        result.fontName = nsFont.fontName;
-        result.fontSize = nsFont.pointSize;
-    }
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> NSObject *WebPage::accessibilityObjectForMainFramePlugin()
</span><span class="lines">@@ -491,6 +482,24 @@
</span><span class="cx">     send(Messages::WebPageProxy::AttributedStringForCharacterRangeCallback(result, EditingRange(editingRange.location, [result.string length]), callbackID));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebPage::fontAtSelection(uint64_t callbackID)
+{
+    String fontName;
+    double fontSize = 0;
+    bool selectionHasMultipleFonts = false;
+    Frame&amp; frame = m_page-&gt;focusController().focusedOrMainFrame();
+    
+    if (!frame.selection().selection().isNone()) {
+        const Font* font = frame.editor().fontForSelection(selectionHasMultipleFonts);
+        NSFont *nsFont = font ? font-&gt;getNSFont() : nil;
+        if (nsFont) {
+            fontName = nsFont.fontName;
+            fontSize = nsFont.pointSize;
+        }
+    }
+    send(Messages::WebPageProxy::FontAtSelectionCallback(fontName, fontSize, selectionHasMultipleFonts, callbackID));
+}
+    
</ins><span class="cx"> void WebPage::performDictionaryLookupAtLocation(const FloatPoint&amp; floatPoint)
</span><span class="cx"> {
</span><span class="cx">     if (PluginView* pluginView = pluginViewForFrame(&amp;m_page-&gt;mainFrame())) {
</span></span></pre>
</div>
</div>

</body>
</html>