<!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>[172552] branches/safari-600.1-branch/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/172552">172552</a></dd>
<dt>Author</dt> <dd>lforschler@apple.com</dd>
<dt>Date</dt> <dd>2014-08-13 20:19:02 -0700 (Wed, 13 Aug 2014)</dd>
</dl>
<h3>Log Message</h3>
<pre>Merged <a href="http://trac.webkit.org/projects/webkit/changeset/172382">r172382</a>. <rdar://problem/17935736></pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#branchessafari6001branchSourceWebKit2ChangeLog">branches/safari-600.1-branch/Source/WebKit2/ChangeLog</a></li>
<li><a href="#branchessafari6001branchSourceWebKit2WebProcessWebPageServicesOverlayControllerh">branches/safari-600.1-branch/Source/WebKit2/WebProcess/WebPage/ServicesOverlayController.h</a></li>
<li><a href="#branchessafari6001branchSourceWebKit2WebProcessWebPagemacServicesOverlayControllermm">branches/safari-600.1-branch/Source/WebKit2/WebProcess/WebPage/mac/ServicesOverlayController.mm</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchessafari6001branchSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-600.1-branch/Source/WebKit2/ChangeLog (172551 => 172552)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-600.1-branch/Source/WebKit2/ChangeLog        2014-08-14 03:12:57 UTC (rev 172551)
+++ branches/safari-600.1-branch/Source/WebKit2/ChangeLog        2014-08-14 03:19:02 UTC (rev 172552)
</span><span class="lines">@@ -1,3 +1,124 @@
</span><ins>+2014-08-13 Lucas Forschler <lforschler@apple.com>
+
+ Merge r172382
+
+ 2014-08-10 Tim Horton <timothy_horton@apple.com>
+
+ Refactor ServiceOverlayController in preparation for fading between highlights
+ https://bugs.webkit.org/show_bug.cgi?id=135787
+ <rdar://problem/17935736>
+
+ Reviewed by Brady Eidson.
+
+ Rework ServicesOverlayController so that we always keep a set of generic
+ "potential highlights", which are refcounted Highlight objects and
+ wrap a DDHighlightRef, as well as a type (Selection or TelephoneNumber),
+ Range (only used in the case of TelephoneNumber), and potentially more
+ things in the future (like, say, fade state!).
+
+ We eagerly update the list of potential highlights when the selection or set
+ of detected telephone numbers changes, and use this information to install
+ or uninstall the page overlay as needed.
+
+ When we need to recompute the "active" highlight from this set (for example,
+ we need to handle a mouse event or paint the highlight), we look through
+ the set of potential highlights and decide. This moves the "active" highlight
+ decision logic into one small and confined place.
+
+ * WebProcess/WebPage/ServicesOverlayController.h:
+ (WebKit::ServicesOverlayController::Highlight):
+ Add the new aforementioned refcounted Highlight class.
+ Rename m_lastHoveredHighlightChangeTime to m_lastActiveHighlightChangeTime.
+ Make m_webPage a reference.
+ The rest is just added/removed/adjusted functions for the refactoring.
+
+ (WebKit::TelephoneNumberData::TelephoneNumberData): Deleted.
+ * WebProcess/WebPage/mac/ServicesOverlayController.mm:
+ (WebKit::ServicesOverlayController::Highlight::createForSelection):
+ (WebKit::ServicesOverlayController::Highlight::createForTelephoneNumber):
+ Create Highlights for the two different highlight types.
+
+ (WebKit::ServicesOverlayController::ServicesOverlayController):
+ (WebKit::ServicesOverlayController::willMoveToWebPage):
+ Our WebPage pointer is always valid because it owns us; don't clear it.
+ We need to keep it around so that we can uninstall the overlay and
+ install it again later, anyway.
+
+ (WebKit::ServicesOverlayController::selectionRectsDidChange):
+ (WebKit::ServicesOverlayController::selectedTelephoneNumberRangesChanged):
+ When selection rects or detected telephone numbers change, rebuild potential highlights.
+ This will have the side-effect of installing the overlay if needed.
+
+ (WebKit::ServicesOverlayController::mouseIsOverHighlight):
+ Make this function take a Highlight instead of a DDHighlightRef.
+
+ (WebKit::ServicesOverlayController::remainingTimeUntilHighlightShouldBeShown):
+ Make this function take a Highlight instead of a DDHighlightRef.
+
+ (WebKit::ServicesOverlayController::drawHighlight):
+ Make this function take a Highlight instead of a DDHighlightRef.
+ There's no reason to do the translation separately from the layer blit,
+ also allowing us to avoid the StateSaver.
+
+ (WebKit::ServicesOverlayController::drawRect):
+ drawRect now always paints the active highlight, instead of duplicating
+ logic about which highlight should be active.
+ Also, it will update the active highlight before painting.
+ We no longer need to re-determine whether the active highlight's phone
+ number range is still a valid phone number range, because we rebuild
+ the potential highlights whenever the set of phone number ranges changes.
+
+ (WebKit::ServicesOverlayController::clearActiveHighlight):
+ Mostly an adoption of new names.
+
+ (WebKit::ServicesOverlayController::removeAllPotentialHighlightsOfType):
+ Run through the list of potential highlights and remove any of the given type.
+ The two highlight building functions use this helper to clear the old ones before building.
+
+ (WebKit::ServicesOverlayController::buildPhoneNumberHighlights):
+ (WebKit::ServicesOverlayController::buildSelectionHighlight):
+ Rebuild the list of potential highlights, replacing all highlights of
+ the given type with new ones.
+
+ (WebKit::ServicesOverlayController::hasRelevantSelectionServices):
+ Factor out the code that decides whether our current selection is
+ viable for servicing based on whether we have plain-text and/or rich-text services.
+
+ (WebKit::ServicesOverlayController::didRebuildPotentialHighlights):
+ When rebuilding potential highlights, if we have no potential highlights at all,
+ uninstall the page overlay; we don't need mouse tracking and don't need to
+ paint anything. This improves memory use and compositing performance significantly,
+ where previously we were leaving the overlay up forever after creating it.
+
+ If we have either detected telephone numbers or relevant selection services,
+ create and install the overlay if it doesn't already exist.
+
+ (WebKit::ServicesOverlayController::createOverlayIfNeeded):
+ This just moved from elsehwere, except that it now uses FadeMode::DoNotFade.
+ It doesn't make sense to fade on install/uninstall (which happens even before hover)
+ but not on changing the active highlight; fading will be re-addressed in the next patch.
+
+ (WebKit::ServicesOverlayController::highlightsAreEquivalent):
+ Determine whether two highlights are equivalent. While we may have
+ created a new Highlight at rebuild time, if two telephone number
+ highlights have equivalent ranges, there's no need to 'transition' to the new one.
+
+ (WebKit::ServicesOverlayController::determineActiveHighlight):
+ Run through the list of services, and try to find one that is hovered.
+ We prefer telephone number highlights to selection highlights, and
+ we will never make a selection highlight active if it is both
+ not serviceable and there are no telephone numbers to show in the combined menu.
+ This is the centralized location for determination of which highlight
+ should be considered active. If the active highlight changed, update
+ the time since last change and cancel the mouse-down tracking.
+
+ (WebKit::ServicesOverlayController::mouseEvent):
+ Adjust some comments to be more explanatory.
+ A bunch of code moved out of here and into determineActiveHighlight.
+
+ (WebKit::ServicesOverlayController::handleClick):
+ Adjust to take a reference and use Highlight instead of DDHighlightRef.
+
</ins><span class="cx"> 2014-08-12 Matthew Hanson <matthew_hanson@apple.com>
</span><span class="cx">
</span><span class="cx"> Rollout 172395. <rdar://problem/17837670>
</span></span></pre></div>
<a id="branchessafari6001branchSourceWebKit2WebProcessWebPageServicesOverlayControllerh"></a>
<div class="modfile"><h4>Modified: branches/safari-600.1-branch/Source/WebKit2/WebProcess/WebPage/ServicesOverlayController.h (172551 => 172552)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-600.1-branch/Source/WebKit2/WebProcess/WebPage/ServicesOverlayController.h        2014-08-14 03:12:57 UTC (rev 172551)
+++ branches/safari-600.1-branch/Source/WebKit2/WebProcess/WebPage/ServicesOverlayController.h        2014-08-14 03:19:02 UTC (rev 172552)
</span><span class="lines">@@ -31,6 +31,7 @@
</span><span class="cx"> #include "PageOverlay.h"
</span><span class="cx"> #include <WebCore/Range.h>
</span><span class="cx"> #include <WebCore/Timer.h>
</span><ins>+#include <wtf/RefCounted.h>
</ins><span class="cx">
</span><span class="cx"> typedef void* DDHighlightRef;
</span><span class="cx">
</span><span class="lines">@@ -44,19 +45,6 @@
</span><span class="cx">
</span><span class="cx"> class WebPage;
</span><span class="cx">
</span><del>-typedef void* DDHighlightRef;
-
-struct TelephoneNumberData {
- TelephoneNumberData(RetainPtr<DDHighlightRef> highlight, PassRefPtr<WebCore::Range> range)
- : highlight(highlight)
- , range(range)
- {
- }
-
- RetainPtr<DDHighlightRef> highlight;
- RefPtr<WebCore::Range> range;
-};
-
</del><span class="cx"> class ServicesOverlayController : private PageOverlay::Client {
</span><span class="cx"> public:
</span><span class="cx"> ServicesOverlayController(WebPage&);
</span><span class="lines">@@ -66,49 +54,81 @@
</span><span class="cx"> void selectionRectsDidChange(const Vector<WebCore::LayoutRect>&, const Vector<WebCore::GapRects>&, bool isTextOnly);
</span><span class="cx">
</span><span class="cx"> private:
</span><del>- void createOverlayIfNeeded();
- void handleClick(const WebCore::IntPoint&, DDHighlightRef);
- void clearHighlightState();
</del><ins>+ class Highlight : public RefCounted<Highlight> {
+ WTF_MAKE_NONCOPYABLE(Highlight);
+ public:
+ static PassRefPtr<Highlight> createForSelection(RetainPtr<DDHighlightRef>);
+ static PassRefPtr<Highlight> createForTelephoneNumber(RetainPtr<DDHighlightRef>, PassRefPtr<WebCore::Range>);
</ins><span class="cx">
</span><ins>+ DDHighlightRef ddHighlight() const { return m_ddHighlight.get(); }
+ WebCore::Range* range() const { return m_range.get(); }
+
+ enum class Type {
+ TelephoneNumber,
+ Selection
+ };
+ Type type() const { return m_type; }
+
+ private:
+ explicit Highlight(Type type, RetainPtr<DDHighlightRef> ddHighlight, PassRefPtr<WebCore::Range> range)
+ : m_ddHighlight(ddHighlight)
+ , m_range(range)
+ , m_type(type)
+ {
+ ASSERT(m_ddHighlight);
+ ASSERT(type != Type::TelephoneNumber || m_range);
+ }
+
+ RetainPtr<DDHighlightRef> m_ddHighlight;
+ RefPtr<WebCore::Range> m_range;
+ Type m_type;
+ };
+
+ // PageOverlay::Client
</ins><span class="cx"> virtual void pageOverlayDestroyed(PageOverlay*) override;
</span><span class="cx"> virtual void willMoveToWebPage(PageOverlay*, WebPage*) override;
</span><span class="cx"> virtual void didMoveToWebPage(PageOverlay*, WebPage*) override;
</span><span class="cx"> virtual void drawRect(PageOverlay*, WebCore::GraphicsContext&, const WebCore::IntRect& dirtyRect) override;
</span><span class="cx"> virtual bool mouseEvent(PageOverlay*, const WebMouseEvent&) override;
</span><span class="cx">
</span><del>- bool drawTelephoneNumberHighlightIfVisible(WebCore::GraphicsContext&, const WebCore::IntRect& dirtyRect);
- void drawSelectionHighlight(WebCore::GraphicsContext&, const WebCore::IntRect& dirtyRect);
- void drawHighlight(DDHighlightRef, WebCore::GraphicsContext&);
</del><ins>+ void createOverlayIfNeeded();
+ void handleClick(const WebCore::IntPoint&, Highlight&);
</ins><span class="cx">
</span><del>- void establishHoveredTelephoneHighlight(bool& mouseIsOverButton);
- void maybeCreateSelectionHighlight();
</del><ins>+ void drawHighlight(Highlight&, WebCore::GraphicsContext&);
</ins><span class="cx">
</span><del>- void clearSelectionHighlight();
- void clearHoveredTelephoneNumberHighlight();
</del><ins>+ void removeAllPotentialHighlightsOfType(Highlight::Type);
+ void buildPhoneNumberHighlights();
+ void buildSelectionHighlight();
+ void didRebuildPotentialHighlights();
</ins><span class="cx">
</span><del>- bool mouseIsOverHighlight(DDHighlightRef, bool& mouseIsOverButton) const;
</del><ins>+ void determineActiveHighlight(bool& mouseIsOverButton);
+ void clearActiveHighlight();
+
+ bool hasRelevantSelectionServices();
+
+ bool mouseIsOverHighlight(Highlight&, bool& mouseIsOverButton) const;
</ins><span class="cx"> std::chrono::milliseconds remainingTimeUntilHighlightShouldBeShown() const;
</span><span class="cx"> void repaintHighlightTimerFired(WebCore::Timer<ServicesOverlayController>&);
</span><span class="cx">
</span><del>- WebPage* m_webPage;
</del><ins>+ static bool highlightsAreEquivalent(const Highlight* a, const Highlight* b);
+
+ WebPage& m_webPage;
</ins><span class="cx"> PageOverlay* m_servicesOverlay;
</span><del>-
</del><ins>+
+ RefPtr<Highlight> m_activeHighlight;
+ HashSet<RefPtr<Highlight>> m_potentialHighlights;
+
+ Vector<RefPtr<WebCore::Range>> m_currentTelephoneNumberRanges;
</ins><span class="cx"> Vector<WebCore::LayoutRect> m_currentSelectionRects;
</span><del>- RetainPtr<DDHighlightRef> m_selectionHighlight;
</del><span class="cx"> bool m_isTextOnly;
</span><ins>+
</ins><span class="cx"> std::chrono::steady_clock::time_point m_lastSelectionChangeTime;
</span><del>- std::chrono::steady_clock::time_point m_lastHoveredHighlightChangeTime;
</del><ins>+ std::chrono::steady_clock::time_point m_lastActiveHighlightChangeTime;
</ins><span class="cx">
</span><del>- Vector<RefPtr<WebCore::Range>> m_currentTelephoneNumberRanges;
- Vector<RetainPtr<DDHighlightRef>> m_telephoneNumberHighlights;
- std::unique_ptr<TelephoneNumberData> m_hoveredTelephoneNumberData;
</del><ins>+ RefPtr<Highlight> m_currentMouseDownOnButtonHighlight;
+ WebCore::IntPoint m_mousePosition;
</ins><span class="cx">
</span><del>- RetainPtr<DDHighlightRef> m_currentHoveredHighlight;
- RetainPtr<DDHighlightRef> m_currentMouseDownOnButtonHighlight;
-
</del><span class="cx"> WebCore::Timer<ServicesOverlayController> m_repaintHighlightTimer;
</span><del>-
- WebCore::IntPoint m_mousePosition;
</del><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> } // namespace WebKit
</span></span></pre></div>
<a id="branchessafari6001branchSourceWebKit2WebProcessWebPagemacServicesOverlayControllermm"></a>
<div class="modfile"><h4>Modified: branches/safari-600.1-branch/Source/WebKit2/WebProcess/WebPage/mac/ServicesOverlayController.mm (172551 => 172552)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-600.1-branch/Source/WebKit2/WebProcess/WebPage/mac/ServicesOverlayController.mm        2014-08-14 03:12:57 UTC (rev 172551)
+++ branches/safari-600.1-branch/Source/WebKit2/WebProcess/WebPage/mac/ServicesOverlayController.mm        2014-08-14 03:19:02 UTC (rev 172552)
</span><span class="lines">@@ -63,6 +63,16 @@
</span><span class="cx">
</span><span class="cx"> namespace WebKit {
</span><span class="cx">
</span><ins>+PassRefPtr<ServicesOverlayController::Highlight> ServicesOverlayController::Highlight::createForSelection(RetainPtr<DDHighlightRef> ddHighlight)
+{
+ return adoptRef(new Highlight(Type::Selection, ddHighlight, nullptr));
+}
+
+PassRefPtr<ServicesOverlayController::Highlight> ServicesOverlayController::Highlight::createForTelephoneNumber(RetainPtr<DDHighlightRef> ddHighlight, PassRefPtr<Range> range)
+{
+ return adoptRef(new Highlight(Type::TelephoneNumber, ddHighlight, range));
+}
+
</ins><span class="cx"> static IntRect textQuadsToBoundingRectForRange(Range& range)
</span><span class="cx"> {
</span><span class="cx"> Vector<FloatQuad> textQuads;
</span><span class="lines">@@ -74,7 +84,7 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> ServicesOverlayController::ServicesOverlayController(WebPage& webPage)
</span><del>- : m_webPage(&webPage)
</del><ins>+ : m_webPage(webPage)
</ins><span class="cx"> , m_servicesOverlay(nullptr)
</span><span class="cx"> , m_isTextOnly(false)
</span><span class="cx"> , m_repaintHighlightTimer(this, &ServicesOverlayController::repaintHighlightTimerFired)
</span><span class="lines">@@ -99,31 +109,12 @@
</span><span class="cx">
</span><span class="cx"> ASSERT(m_servicesOverlay);
</span><span class="cx"> m_servicesOverlay = nullptr;
</span><del>-
- ASSERT(m_webPage);
- m_webPage = nullptr;
</del><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void ServicesOverlayController::didMoveToWebPage(PageOverlay*, WebPage*)
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void ServicesOverlayController::createOverlayIfNeeded()
-{
- if (m_servicesOverlay) {
- m_servicesOverlay->setNeedsDisplay();
- return;
- }
-
- if (m_currentTelephoneNumberRanges.isEmpty() && (!WebProcess::shared().hasSelectionServices() || m_currentSelectionRects.isEmpty()))
- return;
-
- RefPtr<PageOverlay> overlay = PageOverlay::create(this, PageOverlay::OverlayType::Document);
- m_servicesOverlay = overlay.get();
- m_webPage->installPageOverlay(overlay.release(), PageOverlay::FadeMode::Fade);
- m_servicesOverlay->setNeedsDisplay();
-}
-
</del><span class="cx"> static const uint8_t AlignmentNone = 0;
</span><span class="cx"> static const uint8_t AlignmentLeft = 1 << 0;
</span><span class="cx"> static const uint8_t AlignmentRight = 1 << 1;
</span><span class="lines">@@ -215,7 +206,6 @@
</span><span class="cx"> void ServicesOverlayController::selectionRectsDidChange(const Vector<LayoutRect>& rects, const Vector<GapRects>& gapRects, bool isTextOnly)
</span><span class="cx"> {
</span><span class="cx"> #if __MAC_OS_X_VERSION_MIN_REQUIRED > 1090
</span><del>- clearSelectionHighlight();
</del><span class="cx"> m_currentSelectionRects = rects;
</span><span class="cx"> m_isTextOnly = isTextOnly;
</span><span class="cx">
</span><span class="lines">@@ -228,7 +218,7 @@
</span><span class="cx">
</span><span class="cx"> LOG(Services, "ServicesOverlayController - Selection rects changed - Now have %lu\n", rects.size());
</span><span class="cx">
</span><del>- createOverlayIfNeeded();
</del><ins>+ buildSelectionHighlight();
</ins><span class="cx"> #else
</span><span class="cx"> UNUSED_PARAM(rects);
</span><span class="cx"> #endif
</span><span class="lines">@@ -239,95 +229,17 @@
</span><span class="cx"> #if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED > 1090
</span><span class="cx"> LOG(Services, "ServicesOverlayController - Telephone number ranges changed - Had %lu, now have %lu\n", m_currentTelephoneNumberRanges.size(), ranges.size());
</span><span class="cx"> m_currentTelephoneNumberRanges = ranges;
</span><del>- m_telephoneNumberHighlights.clear();
- m_telephoneNumberHighlights.resize(ranges.size());
</del><span class="cx">
</span><del>- createOverlayIfNeeded();
</del><ins>+ buildPhoneNumberHighlights();
</ins><span class="cx"> #else
</span><span class="cx"> UNUSED_PARAM(ranges);
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void ServicesOverlayController::clearHighlightState()
</del><ins>+bool ServicesOverlayController::mouseIsOverHighlight(Highlight& highlight, bool& mouseIsOverButton) const
</ins><span class="cx"> {
</span><del>- clearSelectionHighlight();
- clearHoveredTelephoneNumberHighlight();
-
- m_telephoneNumberHighlights.clear();
-}
-
-void ServicesOverlayController::drawRect(PageOverlay* overlay, WebCore::GraphicsContext& graphicsContext, const WebCore::IntRect& dirtyRect)
-{
- if (m_currentSelectionRects.isEmpty() && m_currentTelephoneNumberRanges.isEmpty()) {
- clearHighlightState();
- return;
- }
-
- if (drawTelephoneNumberHighlightIfVisible(graphicsContext, dirtyRect))
- return;
-
- drawSelectionHighlight(graphicsContext, dirtyRect);
-}
-
-void ServicesOverlayController::drawSelectionHighlight(WebCore::GraphicsContext& graphicsContext, const WebCore::IntRect& dirtyRect)
-{
- // It's possible to end up drawing the selection highlight before we've actually received the selection rects.
- // If that happens we'll end up here again once we have the rects.
- if (m_currentSelectionRects.isEmpty())
- return;
-
- // If there are no appropriate installed selection services and we have no phone numbers detected, then we have nothing to draw.
- if ((!WebProcess::shared().hasSelectionServices() || (!WebProcess::shared().hasRichContentServices() && !m_isTextOnly)) && m_currentTelephoneNumberRanges.isEmpty())
- return;
-
- if (!m_selectionHighlight)
- maybeCreateSelectionHighlight();
-
- if (m_selectionHighlight)
- drawHighlight(m_selectionHighlight.get(), graphicsContext);
-}
-
-bool ServicesOverlayController::drawTelephoneNumberHighlightIfVisible(WebCore::GraphicsContext& graphicsContext, const WebCore::IntRect& dirtyRect)
-{
- // Make sure the hovered telephone number highlight is still hovered.
- if (m_hoveredTelephoneNumberData) {
- Boolean onButton;
- if (!DDHighlightPointIsOnHighlight(m_hoveredTelephoneNumberData->highlight.get(), (CGPoint)m_mousePosition, &onButton))
- clearHoveredTelephoneNumberHighlight();
-
- bool foundMatchingRange = false;
-
- // Make sure the hovered highlight still corresponds to a current telephone number range.
- for (auto& range : m_currentTelephoneNumberRanges) {
- if (areRangesEqual(range.get(), m_hoveredTelephoneNumberData->range.get())) {
- foundMatchingRange = true;
- break;
- }
- }
-
- if (!foundMatchingRange)
- clearHoveredTelephoneNumberHighlight();
- }
-
- // Found out which - if any - telephone number is hovered.
- if (!m_hoveredTelephoneNumberData) {
- bool mouseIsOverButton;
- establishHoveredTelephoneHighlight(mouseIsOverButton);
- }
-
- // If a telephone number is actually hovered, draw it.
- if (m_hoveredTelephoneNumberData) {
- drawHighlight(m_hoveredTelephoneNumberData->highlight.get(), graphicsContext);
- return true;
- }
-
- return false;
-}
-
-bool ServicesOverlayController::mouseIsOverHighlight(DDHighlightRef highlight, bool& mouseIsOverButton) const
-{
</del><span class="cx"> Boolean onButton;
</span><del>- bool hovered = DDHighlightPointIsOnHighlight(highlight, (CGPoint)m_mousePosition, &onButton);
</del><ins>+ bool hovered = DDHighlightPointIsOnHighlight(highlight.ddHighlight(), (CGPoint)m_mousePosition, &onButton);
</ins><span class="cx"> mouseIsOverButton = onButton;
</span><span class="cx"> return hovered;
</span><span class="cx"> }
</span><span class="lines">@@ -336,16 +248,16 @@
</span><span class="cx"> {
</span><span class="cx"> // Highlight hysteresis is only for selection services, because telephone number highlights are already much more stable
</span><span class="cx"> // by virtue of being expanded to include the entire telephone number.
</span><del>- if (m_hoveredTelephoneNumberData)
</del><ins>+ if (m_activeHighlight->type() == Highlight::Type::TelephoneNumber)
</ins><span class="cx"> return std::chrono::milliseconds::zero();
</span><span class="cx">
</span><span class="cx"> std::chrono::steady_clock::duration minimumTimeUntilHighlightShouldBeShown = 200_ms;
</span><span class="cx">
</span><span class="cx"> auto now = std::chrono::steady_clock::now();
</span><span class="cx"> auto timeSinceLastSelectionChange = now - m_lastSelectionChangeTime;
</span><del>- auto timeSinceMouseOverSelection = now - m_lastHoveredHighlightChangeTime;
</del><ins>+ auto timeSinceHighlightBecameActive = now - m_lastActiveHighlightChangeTime;
</ins><span class="cx">
</span><del>- return std::chrono::duration_cast<std::chrono::milliseconds>(std::max(minimumTimeUntilHighlightShouldBeShown - timeSinceLastSelectionChange, minimumTimeUntilHighlightShouldBeShown - timeSinceMouseOverSelection));
</del><ins>+ return std::chrono::duration_cast<std::chrono::milliseconds>(std::max(minimumTimeUntilHighlightShouldBeShown - timeSinceLastSelectionChange, minimumTimeUntilHighlightShouldBeShown - timeSinceHighlightBecameActive));
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void ServicesOverlayController::repaintHighlightTimerFired(WebCore::Timer<ServicesOverlayController>&)
</span><span class="lines">@@ -354,10 +266,8 @@
</span><span class="cx"> m_servicesOverlay->setNeedsDisplay();
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void ServicesOverlayController::drawHighlight(DDHighlightRef highlight, WebCore::GraphicsContext& graphicsContext)
</del><ins>+void ServicesOverlayController::drawHighlight(Highlight& highlight, WebCore::GraphicsContext& graphicsContext)
</ins><span class="cx"> {
</span><del>- ASSERT(highlight);
-
</del><span class="cx"> bool mouseIsOverButton;
</span><span class="cx"> if (!mouseIsOverHighlight(highlight, mouseIsOverButton)) {
</span><span class="cx"> LOG(Services, "ServicesOverlayController::drawHighlight - Mouse is not over highlight, so drawing nothing");
</span><span class="lines">@@ -372,86 +282,74 @@
</span><span class="cx">
</span><span class="cx"> CGContextRef cgContext = graphicsContext.platformContext();
</span><span class="cx">
</span><del>- CGLayerRef highlightLayer = DDHighlightGetLayerWithContext(highlight, cgContext);
- CGRect highlightBoundingRect = DDHighlightGetBoundingRect(highlight);
-
- GraphicsContextStateSaver stateSaver(graphicsContext);
</del><ins>+ CGLayerRef highlightLayer = DDHighlightGetLayerWithContext(highlight.ddHighlight(), cgContext);
+ CGRect highlightBoundingRect = DDHighlightGetBoundingRect(highlight.ddHighlight());
</ins><span class="cx">
</span><del>- graphicsContext.translate(toFloatSize(highlightBoundingRect.origin));
</del><ins>+ CGContextDrawLayerInRect(cgContext, highlightBoundingRect, highlightLayer);
+}
</ins><span class="cx">
</span><del>- CGRect highlightDrawRect = highlightBoundingRect;
- highlightDrawRect.origin.x = 0;
- highlightDrawRect.origin.y = 0;
-
- CGContextDrawLayerInRect(cgContext, highlightDrawRect, highlightLayer);
</del><ins>+void ServicesOverlayController::drawRect(PageOverlay* overlay, WebCore::GraphicsContext& graphicsContext, const WebCore::IntRect& dirtyRect)
+{
+ bool mouseIsOverButton;
+ determineActiveHighlight(mouseIsOverButton);
+
+ if (m_activeHighlight)
+ drawHighlight(*m_activeHighlight, graphicsContext);
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-void ServicesOverlayController::clearSelectionHighlight()
</del><ins>+void ServicesOverlayController::clearActiveHighlight()
</ins><span class="cx"> {
</span><del>- if (!m_selectionHighlight)
</del><ins>+ if (!m_activeHighlight)
</ins><span class="cx"> return;
</span><span class="cx">
</span><del>- if (m_currentHoveredHighlight == m_selectionHighlight)
- m_currentHoveredHighlight = nullptr;
- if (m_currentMouseDownOnButtonHighlight == m_selectionHighlight)
</del><ins>+ if (m_currentMouseDownOnButtonHighlight == m_activeHighlight)
</ins><span class="cx"> m_currentMouseDownOnButtonHighlight = nullptr;
</span><del>- m_selectionHighlight = nullptr;
</del><ins>+ m_activeHighlight = nullptr;
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-void ServicesOverlayController::clearHoveredTelephoneNumberHighlight()
</del><ins>+void ServicesOverlayController::removeAllPotentialHighlightsOfType(Highlight::Type type)
</ins><span class="cx"> {
</span><del>- if (!m_hoveredTelephoneNumberData)
- return;
</del><ins>+ Vector<RefPtr<Highlight>> highlightsToRemove;
+ for (auto& highlight : m_potentialHighlights) {
+ if (highlight->type() == type)
+ highlightsToRemove.append(highlight);
+ }
</ins><span class="cx">
</span><del>- if (m_currentHoveredHighlight == m_hoveredTelephoneNumberData->highlight)
- m_currentHoveredHighlight = nullptr;
- if (m_currentMouseDownOnButtonHighlight == m_hoveredTelephoneNumberData->highlight)
- m_currentMouseDownOnButtonHighlight = nullptr;
- m_hoveredTelephoneNumberData = nullptr;
</del><ins>+ while (!highlightsToRemove.isEmpty())
+ m_potentialHighlights.remove(highlightsToRemove.takeLast());
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-void ServicesOverlayController::establishHoveredTelephoneHighlight(bool& mouseIsOverButton)
</del><ins>+void ServicesOverlayController::buildPhoneNumberHighlights()
</ins><span class="cx"> {
</span><del>- ASSERT(m_currentTelephoneNumberRanges.size() == m_telephoneNumberHighlights.size());
</del><ins>+ removeAllPotentialHighlightsOfType(Highlight::Type::TelephoneNumber);
</ins><span class="cx">
</span><span class="cx"> for (unsigned i = 0; i < m_currentTelephoneNumberRanges.size(); ++i) {
</span><del>- if (!m_telephoneNumberHighlights[i]) {
- // FIXME: This will choke if the range wraps around the edge of the view.
- // What should we do in that case?
- IntRect rect = textQuadsToBoundingRectForRange(*m_currentTelephoneNumberRanges[i]);
</del><ins>+ // FIXME: This will choke if the range wraps around the edge of the view.
+ // What should we do in that case?
+ IntRect rect = textQuadsToBoundingRectForRange(*m_currentTelephoneNumberRanges[i]);
</ins><span class="cx">
</span><del>- // Convert to the main document's coordinate space.
- // FIXME: It's a little crazy to call contentsToWindow and then windowToContents in order to get the right coordinate space.
- // We should consider adding conversion functions to ScrollView for contentsToDocument(). Right now, contentsToRootView() is
- // not equivalent to what we need when you have a topContentInset or a header banner.
- FrameView* viewForRange = m_currentTelephoneNumberRanges[i]->ownerDocument().view();
- if (!viewForRange)
- continue;
- FrameView& mainFrameView = *m_webPage->corePage()->mainFrame().view();
- rect.setLocation(mainFrameView.windowToContents(viewForRange->contentsToWindow(rect.location())));
-
- CGRect cgRect = rect;
- m_telephoneNumberHighlights[i] = adoptCF(DDHighlightCreateWithRectsInVisibleRectWithStyleAndDirection(nullptr, &cgRect, 1, mainFrameView.visibleContentRect(), DDHighlightOutlineWithArrow, YES, NSWritingDirectionNatural, NO, YES));
- }
-
- if (!mouseIsOverHighlight(m_telephoneNumberHighlights[i].get(), mouseIsOverButton))
</del><ins>+ // Convert to the main document's coordinate space.
+ // FIXME: It's a little crazy to call contentsToWindow and then windowToContents in order to get the right coordinate space.
+ // We should consider adding conversion functions to ScrollView for contentsToDocument(). Right now, contentsToRootView() is
+ // not equivalent to what we need when you have a topContentInset or a header banner.
+ FrameView* viewForRange = m_currentTelephoneNumberRanges[i]->ownerDocument().view();
+ if (!viewForRange)
</ins><span class="cx"> continue;
</span><ins>+ FrameView& mainFrameView = *m_webPage.corePage()->mainFrame().view();
+ rect.setLocation(mainFrameView.windowToContents(viewForRange->contentsToWindow(rect.location())));
</ins><span class="cx">
</span><del>- if (!m_hoveredTelephoneNumberData || m_hoveredTelephoneNumberData->highlight != m_telephoneNumberHighlights[i])
- m_hoveredTelephoneNumberData = std::make_unique<TelephoneNumberData>(m_telephoneNumberHighlights[i], m_currentTelephoneNumberRanges[i]);
</del><ins>+ CGRect cgRect = rect;
+ RetainPtr<DDHighlightRef> ddHighlight = adoptCF(DDHighlightCreateWithRectsInVisibleRectWithStyleAndDirection(nullptr, &cgRect, 1, mainFrameView.visibleContentRect(), DDHighlightOutlineWithArrow, YES, NSWritingDirectionNatural, NO, YES));
</ins><span class="cx">
</span><del>- m_servicesOverlay->setNeedsDisplay();
- return;
</del><ins>+ m_potentialHighlights.add(Highlight::createForTelephoneNumber(ddHighlight, m_currentTelephoneNumberRanges[i]));
</ins><span class="cx"> }
</span><span class="cx">
</span><del>- clearHoveredTelephoneNumberHighlight();
- mouseIsOverButton = false;
</del><ins>+ didRebuildPotentialHighlights();
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-void ServicesOverlayController::maybeCreateSelectionHighlight()
</del><ins>+void ServicesOverlayController::buildSelectionHighlight()
</ins><span class="cx"> {
</span><del>- ASSERT(!m_selectionHighlight);
- ASSERT(m_servicesOverlay);
</del><ins>+ removeAllPotentialHighlightsOfType(Highlight::Type::Selection);
</ins><span class="cx">
</span><span class="cx"> Vector<CGRect> cgRects;
</span><span class="cx"> cgRects.reserveCapacity(m_currentSelectionRects.size());
</span><span class="lines">@@ -460,105 +358,163 @@
</span><span class="cx"> cgRects.append((CGRect)pixelSnappedIntRect(rect));
</span><span class="cx">
</span><span class="cx"> if (!cgRects.isEmpty()) {
</span><del>- CGRect visibleRect = m_webPage->corePage()->mainFrame().view()->visibleContentRect();
- m_selectionHighlight = adoptCF(DDHighlightCreateWithRectsInVisibleRectWithStyleAndDirection(nullptr, cgRects.begin(), cgRects.size(), visibleRect, DDHighlightNoOutlineWithArrow, YES, NSWritingDirectionNatural, NO, YES));
</del><ins>+ CGRect visibleRect = m_webPage.corePage()->mainFrame().view()->visibleContentRect();
+ RetainPtr<DDHighlightRef> ddHighlight = adoptCF(DDHighlightCreateWithRectsInVisibleRectWithStyleAndDirection(nullptr, cgRects.begin(), cgRects.size(), visibleRect, DDHighlightNoOutlineWithArrow, YES, NSWritingDirectionNatural, NO, YES));
+
+ m_potentialHighlights.add(Highlight::createForSelection(ddHighlight));
+ }
</ins><span class="cx">
</span><ins>+ didRebuildPotentialHighlights();
+}
+
+bool ServicesOverlayController::hasRelevantSelectionServices()
+{
+ return (m_isTextOnly && WebProcess::shared().hasSelectionServices()) || WebProcess::shared().hasRichContentServices();
+}
+
+void ServicesOverlayController::didRebuildPotentialHighlights()
+{
+ if (m_potentialHighlights.isEmpty()) {
+ if (m_servicesOverlay)
+ m_webPage.uninstallPageOverlay(m_servicesOverlay);
+ return;
+ }
+
+ if (m_currentTelephoneNumberRanges.isEmpty() && !hasRelevantSelectionServices())
+ return;
+
+ createOverlayIfNeeded();
+}
+
+void ServicesOverlayController::createOverlayIfNeeded()
+{
+ if (m_servicesOverlay) {
</ins><span class="cx"> m_servicesOverlay->setNeedsDisplay();
</span><ins>+ return;
</ins><span class="cx"> }
</span><ins>+
+ RefPtr<PageOverlay> overlay = PageOverlay::create(this, PageOverlay::OverlayType::Document);
+ m_servicesOverlay = overlay.get();
+ m_webPage.installPageOverlay(overlay.release(), PageOverlay::FadeMode::DoNotFade);
+ m_servicesOverlay->setNeedsDisplay();
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-bool ServicesOverlayController::mouseEvent(PageOverlay*, const WebMouseEvent& event)
</del><ins>+bool ServicesOverlayController::highlightsAreEquivalent(const Highlight* a, const Highlight* b)
</ins><span class="cx"> {
</span><del>- m_mousePosition = m_webPage->corePage()->mainFrame().view()->rootViewToContents(event.position());
</del><ins>+ if (a == b)
+ return true;
</ins><span class="cx">
</span><del>- DDHighlightRef oldHoveredHighlight = m_currentHoveredHighlight.get();
</del><ins>+ if (!a || !b)
+ return false;
</ins><span class="cx">
</span><del>- bool mouseIsOverButton = false;
- establishHoveredTelephoneHighlight(mouseIsOverButton);
- if (m_hoveredTelephoneNumberData) {
- ASSERT(m_hoveredTelephoneNumberData->highlight);
- m_currentHoveredHighlight = m_hoveredTelephoneNumberData->highlight;
- } else {
- if (!m_selectionHighlight)
- maybeCreateSelectionHighlight();
</del><ins>+ if (a->type() == Highlight::Type::TelephoneNumber && b->type() == Highlight::Type::TelephoneNumber && areRangesEqual(a->range(), b->range()))
+ return true;
</ins><span class="cx">
</span><del>- if (m_selectionHighlight && mouseIsOverHighlight(m_selectionHighlight.get(), mouseIsOverButton))
- m_currentHoveredHighlight = m_selectionHighlight;
- else
- m_currentHoveredHighlight = nullptr;
</del><ins>+ return false;
+}
+
+void ServicesOverlayController::determineActiveHighlight(bool& mouseIsOverActiveHighlightButton)
+{
+ mouseIsOverActiveHighlightButton = false;
+
+ RefPtr<Highlight> oldActiveHighlight = m_activeHighlight.release();
+
+ for (auto& highlight : m_potentialHighlights) {
+ if (highlight->type() == Highlight::Type::Selection) {
+ // If we've already found a new active highlight, and it's
+ // a telephone number highlight, prefer that over this selection highlight.
+ if (m_activeHighlight && m_activeHighlight->type() == Highlight::Type::TelephoneNumber)
+ continue;
+
+ // If this highlight has no compatible services, it can't be active, unless we have telephone number highlights to show in the combined menu.
+ if (m_currentTelephoneNumberRanges.isEmpty() && !hasRelevantSelectionServices())
+ continue;
+ }
+
+ // If this highlight isn't hovered, it can't be active.
+ bool mouseIsOverButton;
+ if (!mouseIsOverHighlight(*highlight, mouseIsOverButton))
+ continue;
+
+ m_activeHighlight = highlight;
+ mouseIsOverActiveHighlightButton = mouseIsOverButton;
</ins><span class="cx"> }
</span><span class="cx">
</span><del>- if (oldHoveredHighlight != m_currentHoveredHighlight) {
- m_lastHoveredHighlightChangeTime = std::chrono::steady_clock::now();
</del><ins>+ if (!highlightsAreEquivalent(oldActiveHighlight.get(), m_activeHighlight.get())) {
+ m_lastActiveHighlightChangeTime = std::chrono::steady_clock::now();
</ins><span class="cx"> m_servicesOverlay->setNeedsDisplay();
</span><ins>+ m_currentMouseDownOnButtonHighlight = nullptr;
</ins><span class="cx"> }
</span><ins>+}
</ins><span class="cx">
</span><del>- // If this event has nothing to do with the left button, it clears the current mouse down tracking and we're done processing it.
</del><ins>+bool ServicesOverlayController::mouseEvent(PageOverlay*, const WebMouseEvent& event)
+{
+ m_mousePosition = m_webPage.corePage()->mainFrame().view()->rootViewToContents(event.position());
+
+ bool mouseIsOverActiveHighlightButton = false;
+ determineActiveHighlight(mouseIsOverActiveHighlightButton);
+
+ // Cancel the potential click if any button other than the left button changes state, and ignore the event.
</ins><span class="cx"> if (event.button() != WebMouseEvent::LeftButton) {
</span><span class="cx"> m_currentMouseDownOnButtonHighlight = nullptr;
</span><span class="cx"> return false;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- // Check and see if the mouse went up and we have a current mouse down highlight button.
</del><ins>+ // If the mouse lifted while still over the highlight button that it went down on, then that is a click.
</ins><span class="cx"> if (event.type() == WebEvent::MouseUp) {
</span><del>- RetainPtr<DDHighlightRef> mouseDownHighlight = std::move(m_currentMouseDownOnButtonHighlight);
</del><ins>+ RefPtr<Highlight> mouseDownHighlight = m_currentMouseDownOnButtonHighlight;
+ m_currentMouseDownOnButtonHighlight = nullptr;
</ins><span class="cx">
</span><del>- // If the mouse lifted while still over the highlight button that it went down on, then that is a click.
- if (mouseIsOverButton && mouseDownHighlight && remainingTimeUntilHighlightShouldBeShown() <= std::chrono::steady_clock::duration::zero()) {
- handleClick(m_mousePosition, mouseDownHighlight.get());
</del><ins>+ if (mouseIsOverActiveHighlightButton && mouseDownHighlight && remainingTimeUntilHighlightShouldBeShown() <= std::chrono::steady_clock::duration::zero()) {
+ handleClick(m_mousePosition, *mouseDownHighlight);
</ins><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> return false;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- // Check and see if the mouse moved within the confines of the DD highlight button.
</del><ins>+ // If the mouse moved outside of the button tracking a potential click, stop tracking the click.
</ins><span class="cx"> if (event.type() == WebEvent::MouseMove) {
</span><del>- // Moving with the mouse button down is okay as long as the mouse never leaves the highlight button.
- if (m_currentMouseDownOnButtonHighlight && mouseIsOverButton)
</del><ins>+ if (m_currentMouseDownOnButtonHighlight && mouseIsOverActiveHighlightButton)
</ins><span class="cx"> return true;
</span><span class="cx">
</span><span class="cx"> m_currentMouseDownOnButtonHighlight = nullptr;
</span><span class="cx"> return false;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- // Check and see if the mouse went down over a DD highlight button.
</del><ins>+ // If the mouse went down over the active highlight's button, track this as a potential click.
</ins><span class="cx"> if (event.type() == WebEvent::MouseDown) {
</span><del>- if (m_currentHoveredHighlight && mouseIsOverButton) {
- m_currentMouseDownOnButtonHighlight = m_currentHoveredHighlight;
</del><ins>+ if (m_activeHighlight && mouseIsOverActiveHighlightButton) {
+ m_currentMouseDownOnButtonHighlight = m_activeHighlight;
</ins><span class="cx"> m_servicesOverlay->setNeedsDisplay();
</span><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> return false;
</span><span class="cx"> }
</span><del>-
</del><ins>+
</ins><span class="cx"> return false;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void ServicesOverlayController::handleClick(const WebCore::IntPoint& clickPoint, DDHighlightRef highlight)
</del><ins>+void ServicesOverlayController::handleClick(const WebCore::IntPoint& clickPoint, Highlight& highlight)
</ins><span class="cx"> {
</span><del>- ASSERT(highlight);
-
- FrameView* frameView = m_webPage->mainFrameView();
</del><ins>+ FrameView* frameView = m_webPage.mainFrameView();
</ins><span class="cx"> if (!frameView)
</span><span class="cx"> return;
</span><span class="cx">
</span><span class="cx"> IntPoint windowPoint = frameView->contentsToWindow(clickPoint);
</span><span class="cx">
</span><del>- if (highlight == m_selectionHighlight) {
</del><ins>+ if (highlight.type() == Highlight::Type::Selection) {
</ins><span class="cx"> Vector<String> selectedTelephoneNumbers;
</span><span class="cx"> selectedTelephoneNumbers.reserveCapacity(m_currentTelephoneNumberRanges.size());
</span><span class="cx"> for (auto& range : m_currentTelephoneNumberRanges)
</span><span class="cx"> selectedTelephoneNumbers.append(range->text());
</span><span class="cx">
</span><del>- m_webPage->handleSelectionServiceClick(m_webPage->corePage()->mainFrame().selection(), selectedTelephoneNumbers, windowPoint);
- } else if (m_hoveredTelephoneNumberData && m_hoveredTelephoneNumberData->highlight == highlight)
- m_webPage->handleTelephoneNumberClick(m_hoveredTelephoneNumberData->range->text(), windowPoint);
- else
- ASSERT_NOT_REACHED();
</del><ins>+ m_webPage.handleSelectionServiceClick(m_webPage.corePage()->mainFrame().selection(), selectedTelephoneNumbers, windowPoint);
+ } else if (highlight.type() == Highlight::Type::TelephoneNumber)
+ m_webPage.handleTelephoneNumberClick(highlight.range()->text(), windowPoint);
</ins><span class="cx"> }
</span><del>-
</del><ins>+
</ins><span class="cx"> } // namespace WebKit
</span><span class="cx">
</span><span class="cx"> #endif // #if ENABLE(SERVICE_CONTROLS) || ENABLE(TELEPHONE_NUMBER_DETECTION) && PLATFORM(MAC)
</span></span></pre>
</div>
</div>
</body>
</html>