<!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>[278331] trunk/Source/WebCore</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/278331">278331</a></dd>
<dt>Author</dt> <dd>wenson_hsieh@apple.com</dd>
<dt>Date</dt> <dd>2021-06-01 15:36:56 -0700 (Tue, 01 Jun 2021)</dd>
</dl>

<h3>Log Message</h3>
<pre>[macOS] Data detector highlights should appear when hovering inside image overlays
https://bugs.webkit.org/show_bug.cgi?id=226507

Reviewed by Tim Horton.

Refactor some logic in ImageOverlayController, such that the overlay is installed if _either_ selection painting
is required, or data detector highlights for the image overlay host element exist; additionally, add plumbing to
allow the ImageOverlayController to install a page overlay when the element under the mouse is inside an image
overlay.

* dom/Document.cpp:
(WebCore::Document::willBeRemovedFromFrame):

Drive-by fix: use `imageOverlayControllerIfExists` instead of `imageOverlayController` to avoid unnecessarily
creating a new ImageOverlayController when detaching a Document.

* page/EventHandler.cpp:
(WebCore::EventHandler::clear):

Refactor logic for clearing out `m_elementUnderMouse` into a separate helper, and call it from these two places.
This new helper clears out `m_elementUnderMouse` and additionally notifies the page's image overlay controller
(only if it has already been constructed).

(WebCore::EventHandler::updateMouseEventTargetNode):

Call out to the page's image overlay controller when changing `m_elementUnderMouse`.

(WebCore::EventHandler::clearElementUnderMouse):
* page/EventHandler.h:
* page/ImageOverlayController.cpp:
(WebCore::ImageOverlayController::selectionQuadsDidChange):

Refactor ImageOverlayController so that it only installs its page overlay if either:
1. Selection painting is needed for selected text inside an image overlay, or...
2. The cursor is over an image overlay host element with data detection results.

To achieve this, we maintain a weak pointer to the image overlay host that contains the selection separately
from the weak pointer to the image overlay host that contains data detectors, and is the element currently under
the mouse cursor.

Drive-by fix: also ignore selection updates due to temporary selections triggered as a result of gathering
dictionary popup info.

(WebCore::ImageOverlayController::documentDetached):
(WebCore::ImageOverlayController::uninstallPageOverlay):
(WebCore::ImageOverlayController::uninstallPageOverlayIfNeeded):

Split this into two functions: `uninstallPageOverlayIfNeeded`, which removes and destroys the PageOverlay if
it is no longer needed (i.e. the overlay is required for neither selection painting nor data detectors).

(WebCore::ImageOverlayController::willMoveToPage):
(WebCore::ImageOverlayController::drawRect):
(WebCore::ImageOverlayController::elementUnderMouseDidChange):
* page/ImageOverlayController.h:

Rename `m_imageOverlayBounds` to `m_selectionClipRect` to make it clear that this is only used during selection
painting, and rename `m_overlaySelectionQuads` to just `m_selectionQuads` for conciseness.

* page/Page.h:
(WebCore::Page::imageOverlayControllerIfExists):

Add a version of this getter that does not initialize the ImageOverlayController if it didn't already exist. See
call sites in EventHandler and Document.

* page/mac/ImageOverlayControllerMac.mm:
(WebCore::ImageOverlayController::clearDataDetectorHighlights):

Additionally clear out `m_hostElementForDataDetectors`.

(WebCore::ImageOverlayController::elementUnderMouseDidChange):

Update data detector highlights whenever the element under the mouse is over content inside an image overlay.
Note that we effectively ignore this method call in the case where we're clearing out `m_elementUnderMouse` for
a different Document than the one containing `m_hostElementForDataDetectors`, which prevents us from erroneously
hiding data detectors when `m_elementUnderMouse` is removed or otherwise cleared out in a different Document.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoredomDocumentcpp">trunk/Source/WebCore/dom/Document.cpp</a></li>
<li><a href="#trunkSourceWebCorepageEventHandlercpp">trunk/Source/WebCore/page/EventHandler.cpp</a></li>
<li><a href="#trunkSourceWebCorepageEventHandlerh">trunk/Source/WebCore/page/EventHandler.h</a></li>
<li><a href="#trunkSourceWebCorepageImageOverlayControllercpp">trunk/Source/WebCore/page/ImageOverlayController.cpp</a></li>
<li><a href="#trunkSourceWebCorepageImageOverlayControllerh">trunk/Source/WebCore/page/ImageOverlayController.h</a></li>
<li><a href="#trunkSourceWebCorepagePageh">trunk/Source/WebCore/page/Page.h</a></li>
<li><a href="#trunkSourceWebCorepagemacImageOverlayControllerMacmm">trunk/Source/WebCore/page/mac/ImageOverlayControllerMac.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (278330 => 278331)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2021-06-01 22:36:13 UTC (rev 278330)
+++ trunk/Source/WebCore/ChangeLog      2021-06-01 22:36:56 UTC (rev 278331)
</span><span class="lines">@@ -1,3 +1,81 @@
</span><ins>+2021-06-01  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [macOS] Data detector highlights should appear when hovering inside image overlays
+        https://bugs.webkit.org/show_bug.cgi?id=226507
+
+        Reviewed by Tim Horton.
+
+        Refactor some logic in ImageOverlayController, such that the overlay is installed if _either_ selection painting
+        is required, or data detector highlights for the image overlay host element exist; additionally, add plumbing to
+        allow the ImageOverlayController to install a page overlay when the element under the mouse is inside an image
+        overlay.
+
+        * dom/Document.cpp:
+        (WebCore::Document::willBeRemovedFromFrame):
+
+        Drive-by fix: use `imageOverlayControllerIfExists` instead of `imageOverlayController` to avoid unnecessarily
+        creating a new ImageOverlayController when detaching a Document.
+
+        * page/EventHandler.cpp:
+        (WebCore::EventHandler::clear):
+
+        Refactor logic for clearing out `m_elementUnderMouse` into a separate helper, and call it from these two places.
+        This new helper clears out `m_elementUnderMouse` and additionally notifies the page's image overlay controller
+        (only if it has already been constructed).
+
+        (WebCore::EventHandler::updateMouseEventTargetNode):
+
+        Call out to the page's image overlay controller when changing `m_elementUnderMouse`.
+
+        (WebCore::EventHandler::clearElementUnderMouse):
+        * page/EventHandler.h:
+        * page/ImageOverlayController.cpp:
+        (WebCore::ImageOverlayController::selectionQuadsDidChange):
+
+        Refactor ImageOverlayController so that it only installs its page overlay if either:
+        1. Selection painting is needed for selected text inside an image overlay, or...
+        2. The cursor is over an image overlay host element with data detection results.
+
+        To achieve this, we maintain a weak pointer to the image overlay host that contains the selection separately
+        from the weak pointer to the image overlay host that contains data detectors, and is the element currently under
+        the mouse cursor.
+
+        Drive-by fix: also ignore selection updates due to temporary selections triggered as a result of gathering
+        dictionary popup info.
+
+        (WebCore::ImageOverlayController::documentDetached):
+        (WebCore::ImageOverlayController::uninstallPageOverlay):
+        (WebCore::ImageOverlayController::uninstallPageOverlayIfNeeded):
+
+        Split this into two functions: `uninstallPageOverlayIfNeeded`, which removes and destroys the PageOverlay if
+        it is no longer needed (i.e. the overlay is required for neither selection painting nor data detectors).
+
+        (WebCore::ImageOverlayController::willMoveToPage):
+        (WebCore::ImageOverlayController::drawRect):
+        (WebCore::ImageOverlayController::elementUnderMouseDidChange):
+        * page/ImageOverlayController.h:
+
+        Rename `m_imageOverlayBounds` to `m_selectionClipRect` to make it clear that this is only used during selection
+        painting, and rename `m_overlaySelectionQuads` to just `m_selectionQuads` for conciseness.
+
+        * page/Page.h:
+        (WebCore::Page::imageOverlayControllerIfExists):
+
+        Add a version of this getter that does not initialize the ImageOverlayController if it didn't already exist. See
+        call sites in EventHandler and Document.
+
+        * page/mac/ImageOverlayControllerMac.mm:
+        (WebCore::ImageOverlayController::clearDataDetectorHighlights):
+
+        Additionally clear out `m_hostElementForDataDetectors`.
+
+        (WebCore::ImageOverlayController::elementUnderMouseDidChange):
+
+        Update data detector highlights whenever the element under the mouse is over content inside an image overlay.
+        Note that we effectively ignore this method call in the case where we're clearing out `m_elementUnderMouse` for
+        a different Document than the one containing `m_hostElementForDataDetectors`, which prevents us from erroneously
+        hiding data detectors when `m_elementUnderMouse` is removed or otherwise cleared out in a different Document.
+
</ins><span class="cx"> 2021-06-01  Chris Dumez  <cdumez@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Fix unsafe access to m_upload in XMLHttpRequest::virtualHasPendingActivity()
</span></span></pre></div>
<a id="trunkSourceWebCoredomDocumentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Document.cpp (278330 => 278331)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Document.cpp    2021-06-01 22:36:13 UTC (rev 278330)
+++ trunk/Source/WebCore/dom/Document.cpp       2021-06-01 22:36:56 UTC (rev 278331)
</span><span class="lines">@@ -2621,7 +2621,8 @@
</span><span class="cx"> #if ENABLE(POINTER_LOCK)
</span><span class="cx">         page->pointerLockController().documentDetached(*this);
</span><span class="cx"> #endif
</span><del>-        page->imageOverlayController().documentDetached(*this);
</del><ins>+        if (auto* imageOverlayController = page->imageOverlayControllerIfExists())
+            imageOverlayController->documentDetached(*this);
</ins><span class="cx">         if (auto* validationMessageClient = page->validationMessageClient())
</span><span class="cx">             validationMessageClient->documentDetached(*this);
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceWebCorepageEventHandlercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/EventHandler.cpp (278330 => 278331)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/EventHandler.cpp       2021-06-01 22:36:13 UTC (rev 278330)
+++ trunk/Source/WebCore/page/EventHandler.cpp  2021-06-01 22:36:56 UTC (rev 278331)
</span><span class="lines">@@ -65,6 +65,7 @@
</span><span class="cx"> #include "HitTestRequest.h"
</span><span class="cx"> #include "HitTestResult.h"
</span><span class="cx"> #include "Image.h"
</span><ins>+#include "ImageOverlayController.h"
</ins><span class="cx"> #include "InspectorInstrumentation.h"
</span><span class="cx"> #include "KeyboardEvent.h"
</span><span class="cx"> #include "Logging.h"
</span><span class="lines">@@ -370,7 +371,7 @@
</span><span class="cx">     m_imageExtractionTimer.stop();
</span><span class="cx"> #endif
</span><span class="cx">     m_resizeLayer = nullptr;
</span><del>-    m_elementUnderMouse = nullptr;
</del><ins>+    clearElementUnderMouse();
</ins><span class="cx">     m_lastElementUnderMouse = nullptr;
</span><span class="cx">     m_lastMouseMoveEventSubframe = nullptr;
</span><span class="cx">     m_lastScrollbarUnderMouse = nullptr;
</span><span class="lines">@@ -2547,6 +2548,9 @@
</span><span class="cx">     }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+    if (auto* page = m_frame.page())
+        page->imageOverlayController().elementUnderMouseDidChange(m_frame, m_elementUnderMouse.get());
+
</ins><span class="cx">     ASSERT_IMPLIES(m_elementUnderMouse, &m_elementUnderMouse->document() == m_frame.document());
</span><span class="cx">     ASSERT_IMPLIES(m_lastElementUnderMouse, &m_lastElementUnderMouse->document() == m_frame.document());
</span><span class="cx"> 
</span><span class="lines">@@ -2606,7 +2610,7 @@
</span><span class="cx"> #if ENABLE(IMAGE_EXTRACTION)
</span><span class="cx">             m_imageExtractionTimer.stop();
</span><span class="cx"> #endif
</span><del>-            m_elementUnderMouse = nullptr;
</del><ins>+            clearElementUnderMouse();
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         m_lastElementUnderMouse = m_elementUnderMouse;
</span><span class="lines">@@ -2613,6 +2617,24 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void EventHandler::clearElementUnderMouse()
+{
+    if (!m_elementUnderMouse)
+        return;
+
+    m_elementUnderMouse = nullptr;
+
+    auto* page = m_frame.page();
+    if (!page)
+        return;
+
+    auto* imageOverlayController = page->imageOverlayControllerIfExists();
+    if (!imageOverlayController)
+        return;
+
+    imageOverlayController->elementUnderMouseDidChange(m_frame, nullptr);
+}
+
</ins><span class="cx"> void EventHandler::notifyScrollableAreasOfMouseEvents(const AtomString& eventType, Element* lastElementUnderMouse, Element* elementUnderMouse)
</span><span class="cx"> {
</span><span class="cx">     auto* frameView = m_frame.view();
</span></span></pre></div>
<a id="trunkSourceWebCorepageEventHandlerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/EventHandler.h (278330 => 278331)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/EventHandler.h 2021-06-01 22:36:13 UTC (rev 278330)
+++ trunk/Source/WebCore/page/EventHandler.h    2021-06-01 22:36:56 UTC (rev 278331)
</span><span class="lines">@@ -519,6 +519,7 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     void clearLatchedState();
</span><ins>+    void clearElementUnderMouse();
</ins><span class="cx"> 
</span><span class="cx">     bool shouldSendMouseEventsToInactiveWindows() const;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorepageImageOverlayControllercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/ImageOverlayController.cpp (278330 => 278331)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/ImageOverlayController.cpp     2021-06-01 22:36:13 UTC (rev 278330)
+++ trunk/Source/WebCore/page/ImageOverlayController.cpp        2021-06-01 22:36:56 UTC (rev 278331)
</span><span class="lines">@@ -58,9 +58,14 @@
</span><span class="cx">     if (!m_page || !m_page->chrome().client().needsImageOverlayControllerForSelectionPainting())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    if (frame.editor().ignoreSelectionChanges())
</del><ins>+    if (frame.editor().ignoreSelectionChanges() || frame.editor().isGettingDictionaryPopupInfo())
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><ins>+    m_hostElementForSelection = nullptr;
+    m_selectionQuads.clear();
+    m_selectionBackgroundColor = Color::transparentBlack;
+    m_selectionClipRect = { };
+
</ins><span class="cx">     auto overlayHost = ([&] () -> RefPtr<HTMLElement> {
</span><span class="cx">         auto selectedRange = frame.selection().selection().range();
</span><span class="cx">         if (!selectedRange)
</span><span class="lines">@@ -86,22 +91,17 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (shouldUsePageOverlayToPaintSelection(*overlayHostRenderer)) {
-        m_overlaySelectionQuads = quads;
-        m_selectionBackgroundColor = overlayHostRenderer->selectionBackgroundColor();
-    } else {
-        m_overlaySelectionQuads.clear();
-        m_selectionBackgroundColor = Color::transparentBlack;
</del><ins>+    if (!shouldUsePageOverlayToPaintSelection(*overlayHostRenderer)) {
+        uninstallPageOverlayIfNeeded();
+        return;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    m_imageOverlayBounds = overlayHostRenderer->absoluteBoundingBoxRect();
</del><ins>+    m_hostElementForSelection = makeWeakPtr(*overlayHost);
+    m_selectionQuads = quads;
+    m_selectionBackgroundColor = overlayHostRenderer->selectionBackgroundColor();
+    m_selectionClipRect = overlayHostRenderer->absoluteBoundingBoxRect();
</ins><span class="cx"> 
</span><del>-#if PLATFORM(MAC)
-    updateDataDetectorHighlights(*overlayHost);
-#endif
-
-    if (auto& overlay = installPageOverlayIfNeeded(); !m_overlaySelectionQuads.isEmpty())
-        overlay.setNeedsDisplay();
</del><ins>+    installPageOverlayIfNeeded().setNeedsDisplay();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool ImageOverlayController::shouldUsePageOverlayToPaintSelection(const RenderElement& renderer)
</span><span class="lines">@@ -113,8 +113,15 @@
</span><span class="cx"> 
</span><span class="cx"> void ImageOverlayController::documentDetached(const Document& document)
</span><span class="cx"> {
</span><del>-    if (&document == m_currentOverlayDocument)
-        uninstallPageOverlayIfNeeded();
</del><ins>+    if (m_hostElementForSelection && &document == &m_hostElementForSelection->document())
+        m_hostElementForSelection = nullptr;
+
+#if PLATFORM(MAC)
+    if (m_hostElementForDataDetectors && &document == &m_hostElementForDataDetectors->document())
+        m_hostElementForDataDetectors = nullptr;
+#endif
+
+    uninstallPageOverlayIfNeeded();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> PageOverlay& ImageOverlayController::installPageOverlayIfNeeded()
</span><span class="lines">@@ -127,12 +134,12 @@
</span><span class="cx">     return *m_overlay;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ImageOverlayController::uninstallPageOverlayIfNeeded()
</del><ins>+void ImageOverlayController::uninstallPageOverlay()
</ins><span class="cx"> {
</span><del>-    m_imageOverlayBounds = { };
-    m_overlaySelectionQuads.clear();
</del><ins>+    m_hostElementForSelection = nullptr;
+    m_selectionQuads.clear();
</ins><span class="cx">     m_selectionBackgroundColor = Color::transparentBlack;
</span><del>-    m_currentOverlayDocument = nullptr;
</del><ins>+    m_selectionClipRect = { };
</ins><span class="cx"> 
</span><span class="cx"> #if PLATFORM(MAC)
</span><span class="cx">     clearDataDetectorHighlights();
</span><span class="lines">@@ -145,10 +152,23 @@
</span><span class="cx">     m_page->pageOverlayController().uninstallPageOverlay(*overlayToUninstall, PageOverlay::FadeMode::DoNotFade);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void ImageOverlayController::uninstallPageOverlayIfNeeded()
+{
+    if (m_hostElementForSelection)
+        return;
+
+#if PLATFORM(MAC)
+    if (m_hostElementForDataDetectors)
+        return;
+#endif
+
+    uninstallPageOverlay();
+}
+
</ins><span class="cx"> void ImageOverlayController::willMoveToPage(PageOverlay&, Page* page)
</span><span class="cx"> {
</span><span class="cx">     if (!page)
</span><del>-        uninstallPageOverlayIfNeeded();
</del><ins>+        uninstallPageOverlay();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ImageOverlayController::drawRect(PageOverlay& pageOverlay, GraphicsContext& context, const IntRect& dirtyRect)
</span><span class="lines">@@ -161,11 +181,11 @@
</span><span class="cx">     GraphicsContextStateSaver stateSaver(context);
</span><span class="cx">     context.clearRect(dirtyRect);
</span><span class="cx"> 
</span><del>-    if (m_overlaySelectionQuads.isEmpty())
</del><ins>+    if (m_selectionQuads.isEmpty())
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     Path coalescedSelectionPath;
</span><del>-    for (auto& quad : m_overlaySelectionQuads) {
</del><ins>+    for (auto& quad : m_selectionQuads) {
</ins><span class="cx">         coalescedSelectionPath.moveTo(quad.p1());
</span><span class="cx">         coalescedSelectionPath.addLineTo(quad.p2());
</span><span class="cx">         coalescedSelectionPath.addLineTo(quad.p3());
</span><span class="lines">@@ -175,7 +195,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     context.setFillColor(m_selectionBackgroundColor);
</span><del>-    context.clip(m_imageOverlayBounds);
</del><ins>+    context.clip(m_selectionClipRect);
</ins><span class="cx">     context.fillPath(coalescedSelectionPath);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -186,6 +206,10 @@
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void ImageOverlayController::elementUnderMouseDidChange(Frame&, Element*)
+{
+}
+
</ins><span class="cx"> #endif // !PLATFORM(MAC)
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorepageImageOverlayControllerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/ImageOverlayController.h (278330 => 278331)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/ImageOverlayController.h       2021-06-01 22:36:13 UTC (rev 278330)
+++ trunk/Source/WebCore/page/ImageOverlayController.h  2021-06-01 22:36:56 UTC (rev 278331)
</span><span class="lines">@@ -38,6 +38,7 @@
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> class Document;
</span><ins>+class Element;
</ins><span class="cx"> class Frame;
</span><span class="cx"> class GraphicsContext;
</span><span class="cx"> class HTMLElement;
</span><span class="lines">@@ -57,6 +58,8 @@
</span><span class="cx">     explicit ImageOverlayController(Page&);
</span><span class="cx"> 
</span><span class="cx">     void selectionQuadsDidChange(Frame&, const Vector<FloatQuad>&);
</span><ins>+    void elementUnderMouseDidChange(Frame&, Element*);
+
</ins><span class="cx">     void documentDetached(const Document&);
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="lines">@@ -69,6 +72,7 @@
</span><span class="cx"> 
</span><span class="cx">     PageOverlay& installPageOverlayIfNeeded();
</span><span class="cx">     void uninstallPageOverlayIfNeeded();
</span><ins>+    void uninstallPageOverlay();
</ins><span class="cx"> 
</span><span class="cx"> #if PLATFORM(MAC)
</span><span class="cx">     void updateDataDetectorHighlights(const HTMLElement&);
</span><span class="lines">@@ -78,13 +82,14 @@
</span><span class="cx">     DataDetectorHighlight* activeHighlight() const final { return m_activeDataDetectorHighlight.get(); }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+    void platformUpdateElementUnderMouse(Frame&, Element* elementUnderMouse);
</ins><span class="cx">     bool platformHandleMouseEvent(const PlatformMouseEvent&);
</span><span class="cx"> 
</span><span class="cx">     WeakPtr<Page> m_page;
</span><span class="cx">     RefPtr<PageOverlay> m_overlay;
</span><del>-    WeakPtr<Document> m_currentOverlayDocument;
-    Vector<FloatQuad> m_overlaySelectionQuads;
-    LayoutRect m_imageOverlayBounds;
</del><ins>+    WeakPtr<HTMLElement> m_hostElementForSelection;
+    Vector<FloatQuad> m_selectionQuads;
+    LayoutRect m_selectionClipRect;
</ins><span class="cx">     Color m_selectionBackgroundColor { Color::transparentBlack };
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(MAC)
</span><span class="lines">@@ -91,6 +96,7 @@
</span><span class="cx">     using ContainerAndHighlight = std::pair<WeakPtr<HTMLElement>, Ref<DataDetectorHighlight>>;
</span><span class="cx">     Vector<ContainerAndHighlight> m_dataDetectorContainersAndHighlights;
</span><span class="cx">     RefPtr<DataDetectorHighlight> m_activeDataDetectorHighlight;
</span><ins>+    WeakPtr<HTMLElement> m_hostElementForDataDetectors;
</ins><span class="cx"> #endif
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorepagePageh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/Page.h (278330 => 278331)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/Page.h 2021-06-01 22:36:13 UTC (rev 278330)
+++ trunk/Source/WebCore/page/Page.h    2021-06-01 22:36:56 UTC (rev 278331)
</span><span class="lines">@@ -508,6 +508,7 @@
</span><span class="cx">     ServicesOverlayController& servicesOverlayController() { return *m_servicesOverlayController; }
</span><span class="cx"> #endif
</span><span class="cx">     ImageOverlayController& imageOverlayController() { return *m_imageOverlayController; }
</span><ins>+    ImageOverlayController* imageOverlayControllerIfExists() { return m_imageOverlayController.get(); }
</ins><span class="cx"> 
</span><span class="cx"> #if ENABLE(WHEEL_EVENT_LATCHING)
</span><span class="cx">     ScrollLatchingController& scrollLatchingController();
</span></span></pre></div>
<a id="trunkSourceWebCorepagemacImageOverlayControllerMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/mac/ImageOverlayControllerMac.mm (278330 => 278331)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/mac/ImageOverlayControllerMac.mm       2021-06-01 22:36:13 UTC (rev 278330)
+++ trunk/Source/WebCore/page/mac/ImageOverlayControllerMac.mm  2021-06-01 22:36:56 UTC (rev 278331)
</span><span class="lines">@@ -176,10 +176,56 @@
</span><span class="cx"> 
</span><span class="cx"> void ImageOverlayController::clearDataDetectorHighlights()
</span><span class="cx"> {
</span><ins>+    m_hostElementForDataDetectors = nullptr;
</ins><span class="cx">     m_dataDetectorContainersAndHighlights.clear();
</span><span class="cx">     m_activeDataDetectorHighlight = nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void ImageOverlayController::elementUnderMouseDidChange(Frame& frame, Element* elementUnderMouse)
+{
+    if (m_activeDataDetectorHighlight)
+        return;
+
+    if (!elementUnderMouse && m_hostElementForDataDetectors && frame.document() != &m_hostElementForDataDetectors->document())
+        return;
+
+    if (!elementUnderMouse || !HTMLElement::isInsideImageOverlay(*elementUnderMouse)) {
+        m_hostElementForDataDetectors = nullptr;
+        uninstallPageOverlayIfNeeded();
+        return;
+    }
+
+    auto shadowHost = elementUnderMouse->shadowHost();
+    if (!is<HTMLElement>(shadowHost)) {
+        ASSERT_NOT_REACHED();
+        m_hostElementForDataDetectors = nullptr;
+        uninstallPageOverlayIfNeeded();
+        return;
+    }
+
+    auto imageOverlayHost = makeRef(downcast<HTMLElement>(*shadowHost));
+    if (!imageOverlayHost->hasImageOverlay()) {
+        ASSERT_NOT_REACHED();
+        m_hostElementForDataDetectors = nullptr;
+        uninstallPageOverlayIfNeeded();
+        return;
+    }
+
+    if (m_hostElementForDataDetectors == imageOverlayHost.ptr())
+        return;
+
+    updateDataDetectorHighlights(imageOverlayHost.get());
+
+    if (m_dataDetectorContainersAndHighlights.isEmpty()) {
+        m_hostElementForDataDetectors = nullptr;
+        uninstallPageOverlayIfNeeded();
+        return;
+    }
+
+    m_hostElementForDataDetectors = makeWeakPtr(imageOverlayHost.get());
+    installPageOverlayIfNeeded();
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // PLATFORM(MAC)
</span></span></pre>
</div>
</div>

</body>
</html>