<!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>[172636] 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/172636">172636</a></dd>
<dt>Author</dt> <dd>timothy_horton@apple.com</dd>
<dt>Date</dt> <dd>2014-08-15 11:47:51 -0700 (Fri, 15 Aug 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Service overlays stay fixed when &lt;iframe&gt; scrolls
https://bugs.webkit.org/show_bug.cgi?id=135959
&lt;rdar://problem/17957716&gt;

Reviewed by Enrica Casucci.

* WebProcess/WebPage/PageOverlay.cpp:
(WebKit::PageOverlay::didScrollFrame):
* WebProcess/WebPage/PageOverlay.h:
(WebKit::PageOverlay::Client::didScrollFrame):
* WebProcess/WebPage/PageOverlayController.cpp:
(WebKit::PageOverlayController::didScrollFrame):
Push didScrollFrame down to the overlays.

* WebProcess/WebPage/ServicesOverlayController.h:
* WebProcess/WebPage/mac/ServicesOverlayController.mm:
(WebKit::ServicesOverlayController::Highlight::createForSelection):
Hold on to the selection's Range so we can use it to compare Highlights later.

(WebKit::ServicesOverlayController::Highlight::Highlight):
(WebKit::ServicesOverlayController::Highlight::setDDHighlight):
Factor the code to set up and paint the highlight out, so that we can
set a new DDHighlightRef on a Highlight and the layer moves/reshapes/repaints.

(WebKit::ServicesOverlayController::buildPhoneNumberHighlights):
(WebKit::ServicesOverlayController::buildSelectionHighlight):
(WebKit::ServicesOverlayController::replaceHighlightsOfTypePreservingEquivalentHighlights):
Factor replaceHighlightsOfTypePreservingEquivalentHighlights out
so that we can use it for buildSelectionHighlight as well.

Steal the DDHighlightRef from the new Highlight when re-using an old one
so that the newly computed rects are used instead of the old ones.

(WebKit::ServicesOverlayController::highlightsAreEquivalent):
We will always have a Range now, so we can always check equivalence using it.

(WebKit::ServicesOverlayController::didScrollFrame):
Rebuild all highlights upon subframe scroll, as they might have moved.
We could optimize this in the future, but for now it's cheap enough
and rare enough that it doesn't matter.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPagePageOverlaycpp">trunk/Source/WebKit2/WebProcess/WebPage/PageOverlay.cpp</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPagePageOverlayh">trunk/Source/WebKit2/WebProcess/WebPage/PageOverlay.h</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPagePageOverlayControllercpp">trunk/Source/WebKit2/WebProcess/WebPage/PageOverlayController.cpp</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageServicesOverlayControllerh">trunk/Source/WebKit2/WebProcess/WebPage/ServicesOverlayController.h</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPagemacServicesOverlayControllermm">trunk/Source/WebKit2/WebProcess/WebPage/mac/ServicesOverlayController.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (172635 => 172636)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2014-08-15 18:42:24 UTC (rev 172635)
+++ trunk/Source/WebKit2/ChangeLog        2014-08-15 18:47:51 UTC (rev 172636)
</span><span class="lines">@@ -1,5 +1,48 @@
</span><span class="cx"> 2014-08-15  Tim Horton  &lt;timothy_horton@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Service overlays stay fixed when &lt;iframe&gt; scrolls
+        https://bugs.webkit.org/show_bug.cgi?id=135959
+        &lt;rdar://problem/17957716&gt;
+
+        Reviewed by Enrica Casucci.
+
+        * WebProcess/WebPage/PageOverlay.cpp:
+        (WebKit::PageOverlay::didScrollFrame):
+        * WebProcess/WebPage/PageOverlay.h:
+        (WebKit::PageOverlay::Client::didScrollFrame):
+        * WebProcess/WebPage/PageOverlayController.cpp:
+        (WebKit::PageOverlayController::didScrollFrame):
+        Push didScrollFrame down to the overlays.
+
+        * WebProcess/WebPage/ServicesOverlayController.h:
+        * WebProcess/WebPage/mac/ServicesOverlayController.mm:
+        (WebKit::ServicesOverlayController::Highlight::createForSelection):
+        Hold on to the selection's Range so we can use it to compare Highlights later.
+
+        (WebKit::ServicesOverlayController::Highlight::Highlight):
+        (WebKit::ServicesOverlayController::Highlight::setDDHighlight):
+        Factor the code to set up and paint the highlight out, so that we can
+        set a new DDHighlightRef on a Highlight and the layer moves/reshapes/repaints.
+
+        (WebKit::ServicesOverlayController::buildPhoneNumberHighlights):
+        (WebKit::ServicesOverlayController::buildSelectionHighlight):
+        (WebKit::ServicesOverlayController::replaceHighlightsOfTypePreservingEquivalentHighlights):
+        Factor replaceHighlightsOfTypePreservingEquivalentHighlights out
+        so that we can use it for buildSelectionHighlight as well.
+
+        Steal the DDHighlightRef from the new Highlight when re-using an old one
+        so that the newly computed rects are used instead of the old ones.
+
+        (WebKit::ServicesOverlayController::highlightsAreEquivalent):
+        We will always have a Range now, so we can always check equivalence using it.
+
+        (WebKit::ServicesOverlayController::didScrollFrame):
+        Rebuild all highlights upon subframe scroll, as they might have moved.
+        We could optimize this in the future, but for now it's cheap enough
+        and rare enough that it doesn't matter.
+
+2014-08-15  Tim Horton  &lt;timothy_horton@apple.com&gt;
+
</ins><span class="cx">         REGRESSION (WebKit2 Gestures): White flash when swiping back to cnn.com's homepage from an article
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=135951
</span><span class="cx">         &lt;rdar://problem/18006149&gt;
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPagePageOverlaycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/PageOverlay.cpp (172635 => 172636)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/PageOverlay.cpp        2014-08-15 18:42:24 UTC (rev 172635)
+++ trunk/Source/WebKit2/WebProcess/WebPage/PageOverlay.cpp        2014-08-15 18:47:51 UTC (rev 172636)
</span><span class="lines">@@ -170,6 +170,11 @@
</span><span class="cx">     return m_client-&gt;mouseEvent(this, mouseEvent);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void PageOverlay::didScrollFrame(Frame* frame)
+{
+    m_client-&gt;didScrollFrame(this, frame);
+}
+
</ins><span class="cx"> WKTypeRef PageOverlay::copyAccessibilityAttributeValue(WKStringRef attribute, WKTypeRef parameter)
</span><span class="cx"> {
</span><span class="cx">     return m_client-&gt;copyAccessibilityAttributeValue(this, attribute, parameter);
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPagePageOverlayh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/PageOverlay.h (172635 => 172636)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/PageOverlay.h        2014-08-15 18:42:24 UTC (rev 172635)
+++ trunk/Source/WebKit2/WebProcess/WebPage/PageOverlay.h        2014-08-15 18:47:51 UTC (rev 172636)
</span><span class="lines">@@ -34,12 +34,14 @@
</span><span class="cx"> #include &lt;wtf/RunLoop.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><ins>+class Frame;
</ins><span class="cx"> class GraphicsContext;
</span><span class="cx"> class GraphicsLayer;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> namespace WebKit {
</span><span class="cx"> 
</span><ins>+class WebFrame;
</ins><span class="cx"> class WebMouseEvent;
</span><span class="cx"> class WebPage;
</span><span class="cx"> 
</span><span class="lines">@@ -55,6 +57,7 @@
</span><span class="cx">         virtual void didMoveToWebPage(PageOverlay*, WebPage*) = 0;
</span><span class="cx">         virtual void drawRect(PageOverlay*, WebCore::GraphicsContext&amp;, const WebCore::IntRect&amp; dirtyRect) = 0;
</span><span class="cx">         virtual bool mouseEvent(PageOverlay*, const WebMouseEvent&amp;) = 0;
</span><ins>+        virtual void didScrollFrame(PageOverlay*, WebCore::Frame*) { }
</ins><span class="cx"> 
</span><span class="cx">         virtual WKTypeRef copyAccessibilityAttributeValue(PageOverlay*, WKStringRef /* attribute */, WKTypeRef /* parameter */) { return 0; }
</span><span class="cx">         virtual WKArrayRef copyAccessibilityAttributeNames(PageOverlay*, bool /* parameterizedNames */) { return 0; }
</span><span class="lines">@@ -74,6 +77,7 @@
</span><span class="cx"> 
</span><span class="cx">     void drawRect(WebCore::GraphicsContext&amp;, const WebCore::IntRect&amp; dirtyRect);
</span><span class="cx">     bool mouseEvent(const WebMouseEvent&amp;);
</span><ins>+    void didScrollFrame(WebCore::Frame*);
</ins><span class="cx"> 
</span><span class="cx">     WKTypeRef copyAccessibilityAttributeValue(WKStringRef attribute, WKTypeRef parameter);
</span><span class="cx">     WKArrayRef copyAccessibilityAttributeNames(bool parameterizedNames);
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPagePageOverlayControllercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/PageOverlayController.cpp (172635 => 172636)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/PageOverlayController.cpp        2014-08-15 18:42:24 UTC (rev 172635)
+++ trunk/Source/WebKit2/WebProcess/WebPage/PageOverlayController.cpp        2014-08-15 18:47:51 UTC (rev 172636)
</span><span class="lines">@@ -218,6 +218,7 @@
</span><span class="cx">     for (auto&amp; overlayAndLayer : m_overlayGraphicsLayers) {
</span><span class="cx">         if (overlayAndLayer.key-&gt;overlayType() == PageOverlay::OverlayType::View || !frame-&gt;isMainFrame())
</span><span class="cx">             overlayAndLayer.value-&gt;setNeedsDisplay();
</span><ins>+        overlayAndLayer.key-&gt;didScrollFrame(frame);
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageServicesOverlayControllerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/ServicesOverlayController.h (172635 => 172636)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/ServicesOverlayController.h        2014-08-15 18:42:24 UTC (rev 172635)
+++ trunk/Source/WebKit2/WebProcess/WebPage/ServicesOverlayController.h        2014-08-15 18:47:51 UTC (rev 172636)
</span><span class="lines">@@ -59,7 +59,7 @@
</span><span class="cx">     class Highlight : public RefCounted&lt;Highlight&gt;, private WebCore::GraphicsLayerClient {
</span><span class="cx">         WTF_MAKE_NONCOPYABLE(Highlight);
</span><span class="cx">     public:
</span><del>-        static PassRefPtr&lt;Highlight&gt; createForSelection(ServicesOverlayController&amp;, RetainPtr&lt;DDHighlightRef&gt;);
</del><ins>+        static PassRefPtr&lt;Highlight&gt; createForSelection(ServicesOverlayController&amp;, RetainPtr&lt;DDHighlightRef&gt;, PassRefPtr&lt;WebCore::Range&gt;);
</ins><span class="cx">         static PassRefPtr&lt;Highlight&gt; createForTelephoneNumber(ServicesOverlayController&amp;, RetainPtr&lt;DDHighlightRef&gt;, PassRefPtr&lt;WebCore::Range&gt;);
</span><span class="cx">         ~Highlight();
</span><span class="cx"> 
</span><span class="lines">@@ -78,6 +78,8 @@
</span><span class="cx">         void fadeIn();
</span><span class="cx">         void fadeOut();
</span><span class="cx"> 
</span><ins>+        void setDDHighlight(DDHighlightRef);
+
</ins><span class="cx">     private:
</span><span class="cx">         explicit Highlight(ServicesOverlayController&amp;, Type, RetainPtr&lt;DDHighlightRef&gt;, PassRefPtr&lt;WebCore::Range&gt;);
</span><span class="cx"> 
</span><span class="lines">@@ -102,12 +104,14 @@
</span><span class="cx">     virtual void didMoveToWebPage(PageOverlay*, WebPage*) override;
</span><span class="cx">     virtual void drawRect(PageOverlay*, WebCore::GraphicsContext&amp;, const WebCore::IntRect&amp; dirtyRect) override;
</span><span class="cx">     virtual bool mouseEvent(PageOverlay*, const WebMouseEvent&amp;) override;
</span><ins>+    virtual void didScrollFrame(PageOverlay*, WebCore::Frame*) override;
</ins><span class="cx"> 
</span><span class="cx">     void createOverlayIfNeeded();
</span><span class="cx">     void handleClick(const WebCore::IntPoint&amp;, Highlight&amp;);
</span><span class="cx"> 
</span><span class="cx">     void drawHighlight(Highlight&amp;, WebCore::GraphicsContext&amp;);
</span><span class="cx"> 
</span><ins>+    void replaceHighlightsOfTypePreservingEquivalentHighlights(HashSet&lt;RefPtr&lt;Highlight&gt;&gt;&amp;, Highlight::Type);
</ins><span class="cx">     void removeAllPotentialHighlightsOfType(Highlight::Type);
</span><span class="cx">     void buildPhoneNumberHighlights();
</span><span class="cx">     void buildSelectionHighlight();
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPagemacServicesOverlayControllermm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/ServicesOverlayController.mm (172635 => 172636)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/mac/ServicesOverlayController.mm        2014-08-15 18:42:24 UTC (rev 172635)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/ServicesOverlayController.mm        2014-08-15 18:47:51 UTC (rev 172636)
</span><span class="lines">@@ -71,9 +71,9 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebKit {
</span><span class="cx"> 
</span><del>-PassRefPtr&lt;ServicesOverlayController::Highlight&gt; ServicesOverlayController::Highlight::createForSelection(ServicesOverlayController&amp; controller, RetainPtr&lt;DDHighlightRef&gt; ddHighlight)
</del><ins>+PassRefPtr&lt;ServicesOverlayController::Highlight&gt; ServicesOverlayController::Highlight::createForSelection(ServicesOverlayController&amp; controller, RetainPtr&lt;DDHighlightRef&gt; ddHighlight, PassRefPtr&lt;Range&gt; range)
</ins><span class="cx"> {
</span><del>-    return adoptRef(new Highlight(controller, Type::Selection, ddHighlight, nullptr));
</del><ins>+    return adoptRef(new Highlight(controller, Type::Selection, ddHighlight, range));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> PassRefPtr&lt;ServicesOverlayController::Highlight&gt; ServicesOverlayController::Highlight::createForTelephoneNumber(ServicesOverlayController&amp; controller, RetainPtr&lt;DDHighlightRef&gt; ddHighlight, PassRefPtr&lt;Range&gt; range)
</span><span class="lines">@@ -82,22 +82,18 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> ServicesOverlayController::Highlight::Highlight(ServicesOverlayController&amp; controller, Type type, RetainPtr&lt;DDHighlightRef&gt; ddHighlight, PassRefPtr&lt;WebCore::Range&gt; range)
</span><del>-    : m_ddHighlight(ddHighlight)
-    , m_range(range)
</del><ins>+    : m_range(range)
</ins><span class="cx">     , m_type(type)
</span><span class="cx">     , m_controller(&amp;controller)
</span><span class="cx"> {
</span><del>-    ASSERT(m_ddHighlight);
-    ASSERT(type != Type::TelephoneNumber || m_range);
</del><ins>+    ASSERT(ddHighlight);
+    ASSERT(m_range);
</ins><span class="cx"> 
</span><span class="cx">     DrawingArea* drawingArea = controller.webPage().drawingArea();
</span><span class="cx">     m_graphicsLayer = GraphicsLayer::create(drawingArea ? drawingArea-&gt;graphicsLayerFactory() : nullptr, *this);
</span><span class="cx">     m_graphicsLayer-&gt;setDrawsContent(true);
</span><del>-    m_graphicsLayer-&gt;setNeedsDisplay();
</del><span class="cx"> 
</span><del>-    CGRect highlightBoundingRect = DDHighlightGetBoundingRect(ddHighlight.get());
-    m_graphicsLayer-&gt;setPosition(FloatPoint(highlightBoundingRect.origin));
-    m_graphicsLayer-&gt;setSize(FloatSize(highlightBoundingRect.size));
</del><ins>+    setDDHighlight(ddHighlight.get());
</ins><span class="cx"> 
</span><span class="cx">     // Set directly on the PlatformCALayer so that when we leave the 'from' value implicit
</span><span class="cx">     // in our animations, we get the right initial value regardless of flush timing.
</span><span class="lines">@@ -112,6 +108,23 @@
</span><span class="cx">         m_controller-&gt;willDestroyHighlight(this);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void ServicesOverlayController::Highlight::setDDHighlight(DDHighlightRef highlight)
+{
+    if (!m_controller)
+        return;
+
+    m_ddHighlight = highlight;
+
+    if (!m_ddHighlight)
+        return;
+
+    CGRect highlightBoundingRect = DDHighlightGetBoundingRect(m_ddHighlight.get());
+    m_graphicsLayer-&gt;setPosition(FloatPoint(highlightBoundingRect.origin));
+    m_graphicsLayer-&gt;setSize(FloatSize(highlightBoundingRect.size));
+
+    m_graphicsLayer-&gt;setNeedsDisplay();
+}
+
</ins><span class="cx"> void ServicesOverlayController::Highlight::invalidate()
</span><span class="cx"> {
</span><span class="cx">     layer()-&gt;removeFromParent();
</span><span class="lines">@@ -486,34 +499,14 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // If any old Highlights are equivalent (by Range) to a new Highlight, reuse the old
-    // one so that any metadata is retained.
-    HashSet&lt;RefPtr&lt;Highlight&gt;&gt; reusedPotentialHighlights;
</del><ins>+    replaceHighlightsOfTypePreservingEquivalentHighlights(newPotentialHighlights, Highlight::Type::TelephoneNumber);
</ins><span class="cx"> 
</span><del>-    for (auto&amp; oldHighlight : m_potentialHighlights) {
-        if (oldHighlight-&gt;type() != Highlight::Type::TelephoneNumber)
-            continue;
-
-        for (auto&amp; newHighlight : newPotentialHighlights) {
-            if (highlightsAreEquivalent(oldHighlight.get(), newHighlight.get())) {
-                reusedPotentialHighlights.add(oldHighlight);
-                newPotentialHighlights.remove(newHighlight);
-                break;
-            }
-        }
-    }
-
-    removeAllPotentialHighlightsOfType(Highlight::Type::TelephoneNumber);
-
-    m_potentialHighlights.add(newPotentialHighlights.begin(), newPotentialHighlights.end());
-    m_potentialHighlights.add(reusedPotentialHighlights.begin(), reusedPotentialHighlights.end());
-
</del><span class="cx">     didRebuildPotentialHighlights();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ServicesOverlayController::buildSelectionHighlight()
</span><span class="cx"> {
</span><del>-    removeAllPotentialHighlightsOfType(Highlight::Type::Selection);
</del><ins>+    HashSet&lt;RefPtr&lt;Highlight&gt;&gt; newPotentialHighlights;
</ins><span class="cx"> 
</span><span class="cx">     Vector&lt;CGRect&gt; cgRects;
</span><span class="cx">     cgRects.reserveCapacity(m_currentSelectionRects.size());
</span><span class="lines">@@ -534,13 +527,43 @@
</span><span class="cx">             CGRect visibleRect = m_webPage.corePage()-&gt;mainFrame().view()-&gt;visibleContentRect();
</span><span class="cx">             RetainPtr&lt;DDHighlightRef&gt; ddHighlight = adoptCF(DDHighlightCreateWithRectsInVisibleRectWithStyleAndDirection(nullptr, cgRects.begin(), cgRects.size(), visibleRect, DDHighlightNoOutlineWithArrow, YES, NSWritingDirectionNatural, NO, YES));
</span><span class="cx">             
</span><del>-            m_potentialHighlights.add(Highlight::createForSelection(*this, ddHighlight));
</del><ins>+            newPotentialHighlights.add(Highlight::createForSelection(*this, ddHighlight, selectionRange));
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    replaceHighlightsOfTypePreservingEquivalentHighlights(newPotentialHighlights, Highlight::Type::Selection);
+
</ins><span class="cx">     didRebuildPotentialHighlights();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void ServicesOverlayController::replaceHighlightsOfTypePreservingEquivalentHighlights(HashSet&lt;RefPtr&lt;Highlight&gt;&gt;&amp; newPotentialHighlights, Highlight::Type type)
+{
+    // If any old Highlights are equivalent (by Range) to a new Highlight, reuse the old
+    // one so that any metadata is retained.
+    HashSet&lt;RefPtr&lt;Highlight&gt;&gt; reusedPotentialHighlights;
+
+    for (auto&amp; oldHighlight : m_potentialHighlights) {
+        if (oldHighlight-&gt;type() != type)
+            continue;
+
+        for (auto&amp; newHighlight : newPotentialHighlights) {
+            if (highlightsAreEquivalent(oldHighlight.get(), newHighlight.get())) {
+                oldHighlight-&gt;setDDHighlight(newHighlight-&gt;ddHighlight());
+
+                reusedPotentialHighlights.add(oldHighlight);
+                newPotentialHighlights.remove(newHighlight);
+
+                break;
+            }
+        }
+    }
+
+    removeAllPotentialHighlightsOfType(type);
+
+    m_potentialHighlights.add(newPotentialHighlights.begin(), newPotentialHighlights.end());
+    m_potentialHighlights.add(reusedPotentialHighlights.begin(), reusedPotentialHighlights.end());
+}
+
</ins><span class="cx"> bool ServicesOverlayController::hasRelevantSelectionServices()
</span><span class="cx"> {
</span><span class="cx">     return (m_isTextOnly &amp;&amp; WebProcess::shared().hasSelectionServices()) || WebProcess::shared().hasRichContentServices();
</span><span class="lines">@@ -590,7 +613,7 @@
</span><span class="cx">     if (!a || !b)
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><del>-    if (a-&gt;type() == Highlight::Type::TelephoneNumber &amp;&amp; b-&gt;type() == Highlight::Type::TelephoneNumber &amp;&amp; areRangesEqual(a-&gt;range(), b-&gt;range()))
</del><ins>+    if (areRangesEqual(a-&gt;range(), b-&gt;range()))
</ins><span class="cx">         return true;
</span><span class="cx"> 
</span><span class="cx">     return false;
</span><span class="lines">@@ -740,6 +763,18 @@
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void ServicesOverlayController::didScrollFrame(PageOverlay*, Frame* frame)
+{
+    if (frame-&gt;isMainFrame())
+        return;
+
+    buildPhoneNumberHighlights();
+    buildSelectionHighlight();
+
+    bool mouseIsOverActiveHighlightButton;
+    determineActiveHighlight(mouseIsOverActiveHighlightButton);
+}
+
</ins><span class="cx"> void ServicesOverlayController::handleClick(const IntPoint&amp; clickPoint, Highlight&amp; highlight)
</span><span class="cx"> {
</span><span class="cx">     FrameView* frameView = m_webPage.mainFrameView();
</span></span></pre>
</div>
</div>

</body>
</html>