Title: [280178] trunk/Source
Revision
280178
Author
[email protected]
Date
2021-07-22 10:07:21 -0700 (Thu, 22 Jul 2021)

Log Message

Avoid Quick Note overlay when scrolling to show a highlight
https://bugs.webkit.org/show_bug.cgi?id=228172

Reviewed by Wenson Hsieh and Tim Horton.

When scrolling to show the selected highlight after clicking on one in the QuickNote overlay,
make sure to avoid the Quick Note overlay, so that the user can actually see the highlight.
This required calculating more information about the selection rect for iOS, and also piping through
information to have the selection rect be the entire rect, rather that just the caret and the end of selection.

Source/WebCore:

* Modules/highlight/AppHighlightStorage.cpp:
(WebCore::AppHighlightStorage::attemptToRestoreHighlightAndScroll):
* editing/Editor.cpp:
(WebCore::TemporarySelectionChange::setSelection):
* editing/Editor.h:
* editing/FrameSelection.cpp:
(WebCore::FrameSelection::setSelection):
(WebCore::FrameSelection::updateAndRevealSelection):
(WebCore::FrameSelection::selectionBounds const):
* editing/FrameSelection.h:

Source/WebKit:

* Platform/spi/Cocoa/SynapseSPI.h:
* UIProcess/API/ios/WKWebViewIOS.mm:
(-[WKWebView adjustScrollRect:]):
(-[WKWebView _scrollToRect:origin:minimumScrollDistance:]):
* UIProcess/Cocoa/WebPageProxyCocoa.mm:
(WebKit::WebPageProxy::appHighlightsNoteOverlayRect):
* UIProcess/WebPageProxy.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (280177 => 280178)


--- trunk/Source/WebCore/ChangeLog	2021-07-22 16:56:03 UTC (rev 280177)
+++ trunk/Source/WebCore/ChangeLog	2021-07-22 17:07:21 UTC (rev 280178)
@@ -1,3 +1,26 @@
+2021-07-22  Megan Gardner  <[email protected]>
+
+        Avoid Quick Note overlay when scrolling to show a highlight
+        https://bugs.webkit.org/show_bug.cgi?id=228172
+
+        Reviewed by Wenson Hsieh and Tim Horton.
+
+        When scrolling to show the selected highlight after clicking on one in the QuickNote overlay,
+        make sure to avoid the Quick Note overlay, so that the user can actually see the highlight. 
+        This required calculating more information about the selection rect for iOS, and also piping through
+        information to have the selection rect be the entire rect, rather that just the caret and the end of selection.
+
+        * Modules/highlight/AppHighlightStorage.cpp:
+        (WebCore::AppHighlightStorage::attemptToRestoreHighlightAndScroll):
+        * editing/Editor.cpp:
+        (WebCore::TemporarySelectionChange::setSelection):
+        * editing/Editor.h:
+        * editing/FrameSelection.cpp:
+        (WebCore::FrameSelection::setSelection):
+        (WebCore::FrameSelection::updateAndRevealSelection):
+        (WebCore::FrameSelection::selectionBounds const):
+        * editing/FrameSelection.h:
+
 2021-07-22  Sihui Liu  <[email protected]>
 
         [macOS Debug] Layout Test imported/w3c/web-platform-tests/IndexedDB/open-request-queue.html is a flaky timeout.

Modified: trunk/Source/WebCore/Modules/highlight/AppHighlightStorage.cpp (280177 => 280178)


--- trunk/Source/WebCore/Modules/highlight/AppHighlightStorage.cpp	2021-07-22 16:56:03 UTC (rev 280177)
+++ trunk/Source/WebCore/Modules/highlight/AppHighlightStorage.cpp	2021-07-22 17:07:21 UTC (rev 280178)
@@ -270,8 +270,8 @@
         auto textIndicator = TextIndicator::createWithRange(range.value(), { TextIndicatorOption::DoNotClipToVisibleRect }, WebCore::TextIndicatorPresentationTransition::Bounce);
         if (textIndicator)
             m_document->page()->chrome().client().setTextIndicator(textIndicator->data());
-        
-        TemporarySelectionChange selectionChange(*strongDocument, { range.value() }, { TemporarySelectionOption::DelegateMainFrameScroll, TemporarySelectionOption::SmoothScroll });
+
+        TemporarySelectionChange selectionChange(*strongDocument, { range.value() }, { TemporarySelectionOption::DelegateMainFrameScroll, TemporarySelectionOption::SmoothScroll, TemporarySelectionOption::RevealSelectionBounds });
     }
 
     return true;

Modified: trunk/Source/WebCore/editing/Editor.cpp (280177 => 280178)


--- trunk/Source/WebCore/editing/Editor.cpp	2021-07-22 16:56:03 UTC (rev 280177)
+++ trunk/Source/WebCore/editing/Editor.cpp	2021-07-22 17:07:21 UTC (rev 280178)
@@ -269,6 +269,8 @@
         options.add(FrameSelection::DelegateMainFrameScroll);
     if (m_options & TemporarySelectionOption::SmoothScroll)
         options.add(FrameSelection::SmoothScroll);
+    if (m_options & TemporarySelectionOption::RevealSelectionBounds)
+        options.add(FrameSelection::RevealSelectionBounds);
     m_document->selection().setSelection(selection, options);
 }
 

Modified: trunk/Source/WebCore/editing/Editor.h (280177 => 280178)


--- trunk/Source/WebCore/editing/Editor.h	2021-07-22 16:56:03 UTC (rev 280177)
+++ trunk/Source/WebCore/editing/Editor.h	2021-07-22 17:07:21 UTC (rev 280178)
@@ -122,6 +122,8 @@
     SmoothScroll = 1 << 4,
     
     DelegateMainFrameScroll = 1 << 5,
+    
+    RevealSelectionBounds = 1 << 6,
 };
 
 class TemporarySelectionChange {

Modified: trunk/Source/WebCore/editing/FrameSelection.cpp (280177 => 280178)


--- trunk/Source/WebCore/editing/FrameSelection.cpp	2021-07-22 16:56:03 UTC (rev 280177)
+++ trunk/Source/WebCore/editing/FrameSelection.cpp	2021-07-22 17:07:21 UTC (rev 280178)
@@ -82,6 +82,7 @@
 #include "Color.h"
 #include "RenderObject.h"
 #include "RenderStyle.h"
+#include "SelectionGeometry.h"
 #endif
 
 namespace WebCore {
@@ -451,7 +452,7 @@
     if (frameView && frameView->layoutContext().isLayoutPending())
         return;
 
-    updateAndRevealSelection(intent, options.contains(SmoothScroll) ? ScrollBehavior::Smooth : ScrollBehavior::Instant);
+    updateAndRevealSelection(intent, options.contains(SmoothScroll) ? ScrollBehavior::Smooth : ScrollBehavior::Instant, options.contains(RevealSelectionBounds) ? RevealExtentOption::DoNotRevealExtent : RevealExtentOption::RevealExtent);
 
     if (options & IsUserTriggered) {
         if (auto* client = protectedDocument->editor().client())
@@ -478,7 +479,7 @@
         view->selection().clear();
 }
 
-void FrameSelection::updateAndRevealSelection(const AXTextStateChangeIntent& intent, ScrollBehavior scrollBehavior)
+void FrameSelection::updateAndRevealSelection(const AXTextStateChangeIntent& intent, ScrollBehavior scrollBehavior, RevealExtentOption revealExtent)
 {
     if (!m_pendingSelectionUpdate)
         return;
@@ -495,7 +496,7 @@
         else
             alignment = m_alwaysAlignCursorOnScrollWhenRevealingSelection ? ScrollAlignment::alignTopAlways : ScrollAlignment::alignToEdgeIfNeeded;
 
-        revealSelection(m_selectionRevealMode, alignment, RevealExtent, scrollBehavior);
+        revealSelection(m_selectionRevealMode, alignment, revealExtent, scrollBehavior);
     }
 
     notifyAccessibilityForSelectionChange(intent);
@@ -2325,14 +2326,27 @@
     if (!renderView)
         return LayoutRect();
 
+    if (!m_selection.range())
+        return LayoutRect();
+    
+#if PLATFORM(IOS_FAMILY)
+    auto selectionGeometries = RenderObject::collectSelectionGeometries(m_selection.range().value());
+    IntRect visibleSelectionRect;
+    for (auto geometry : selectionGeometries)
+        visibleSelectionRect.unite(geometry.rect());
+    
+    if (clipToVisibleContent == ClipToVisibleContent::No)
+        return visibleSelectionRect;
+#else
     auto& selection = renderView->selection();
+    auto visibleSelectionRect = selection.boundsClippedToVisibleContent();
+    
+    if (clipToVisibleContent == ClipToVisibleContent::No)
+        return selection.bounds();
+#endif
+    
+    return intersection(visibleSelectionRect, renderView->frameView().visibleContentRect(ScrollableArea::LegacyIOSDocumentVisibleRect));
 
-    if (clipToVisibleContent == ClipToVisibleContent::Yes) {
-        auto selectionRect = selection.boundsClippedToVisibleContent();
-        return intersection(selectionRect, renderView->frameView().visibleContentRect(ScrollableArea::LegacyIOSDocumentVisibleRect));
-    }
-
-    return selection.bounds();
 }
 
 void FrameSelection::getClippedVisibleTextRectangles(Vector<FloatRect>& rectangles, TextRectangleHeight textRectHeight) const

Modified: trunk/Source/WebCore/editing/FrameSelection.h (280177 => 280178)


--- trunk/Source/WebCore/editing/FrameSelection.h	2021-07-22 16:56:03 UTC (rev 280177)
+++ trunk/Source/WebCore/editing/FrameSelection.h	2021-07-22 17:07:21 UTC (rev 280178)
@@ -124,7 +124,8 @@
         RevealSelection = 1 << 7,
         RevealSelectionUpToMainFrame = 1 << 8,
         SmoothScroll = 1 << 9,
-        DelegateMainFrameScroll = 1 << 10
+        DelegateMainFrameScroll = 1 << 10,
+        RevealSelectionBounds = 1 << 11
     };
     static constexpr OptionSet<SetSelectionOption> defaultSetSelectionOptions(EUserTriggered = NotUserTriggered);
 
@@ -263,7 +264,7 @@
     void updateFromAssociatedLiveRange();
 
 private:
-    void updateAndRevealSelection(const AXTextStateChangeIntent&, ScrollBehavior = ScrollBehavior::Instant);
+    void updateAndRevealSelection(const AXTextStateChangeIntent&, ScrollBehavior = ScrollBehavior::Instant, RevealExtentOption = RevealExtentOption::RevealExtent);
     void updateDataDetectorsForSelection();
 
     bool setSelectionWithoutUpdatingAppearance(const VisibleSelection&, OptionSet<SetSelectionOption>, CursorAlignOnScroll, TextGranularity);

Modified: trunk/Source/WebKit/ChangeLog (280177 => 280178)


--- trunk/Source/WebKit/ChangeLog	2021-07-22 16:56:03 UTC (rev 280177)
+++ trunk/Source/WebKit/ChangeLog	2021-07-22 17:07:21 UTC (rev 280178)
@@ -1,3 +1,23 @@
+2021-07-22  Megan Gardner  <[email protected]>
+
+        Avoid Quick Note overlay when scrolling to show a highlight
+        https://bugs.webkit.org/show_bug.cgi?id=228172
+
+        Reviewed by Wenson Hsieh and Tim Horton.
+
+        When scrolling to show the selected highlight after clicking on one in the QuickNote overlay,
+        make sure to avoid the Quick Note overlay, so that the user can actually see the highlight. 
+        This required calculating more information about the selection rect for iOS, and also piping through
+        information to have the selection rect be the entire rect, rather that just the caret and the end of selection.
+
+        * Platform/spi/Cocoa/SynapseSPI.h:
+        * UIProcess/API/ios/WKWebViewIOS.mm:
+        (-[WKWebView adjustScrollRect:]):
+        (-[WKWebView _scrollToRect:origin:minimumScrollDistance:]):
+        * UIProcess/Cocoa/WebPageProxyCocoa.mm:
+        (WebKit::WebPageProxy::appHighlightsNoteOverlayRect):
+        * UIProcess/WebPageProxy.h:
+
 2021-07-22  Philippe Normand  <[email protected]>
 
         [GLib] Expose API to access/modify capture devices states

Modified: trunk/Source/WebKit/Platform/spi/Cocoa/SynapseSPI.h (280177 => 280178)


--- trunk/Source/WebKit/Platform/spi/Cocoa/SynapseSPI.h	2021-07-22 16:56:03 UTC (rev 280177)
+++ trunk/Source/WebKit/Platform/spi/Cocoa/SynapseSPI.h	2021-07-22 17:07:21 UTC (rev 280178)
@@ -37,6 +37,8 @@
 
 @property (nonatomic, readonly, getter=isVisible) BOOL visible;
 
+@property (nonatomic, readonly) CGRect visibleFrame;
+
 - (instancetype)initWithHandler:(nullable SYNotesActivationObserverHandler)handler;
 
 @end

Modified: trunk/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm (280177 => 280178)


--- trunk/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm	2021-07-22 16:56:03 UTC (rev 280177)
+++ trunk/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm	2021-07-22 17:07:21 UTC (rev 280178)
@@ -83,6 +83,7 @@
 
 static const Seconds delayBeforeNoVisibleContentsRectsLogging = 1_s;
 static const Seconds delayBeforeNoCommitsLogging = 5_s;
+static const unsigned highlightMargin = 5;
 
 static int32_t deviceOrientationForUIInterfaceOrientation(UIInterfaceOrientation orientation)
 {
@@ -1153,6 +1154,39 @@
     }
 }
 
+- (float)_adjustScrollRectToAvoidHighlightOverlay:(WebCore::FloatRect)targetRect
+{
+#if ENABLE(APP_HIGHLIGHTS)
+    WebCore::FloatRect overlayRect = [self convertRect:_page->appHighlightsOverlayRect() fromCoordinateSpace:self.window.screen.coordinateSpace];
+    
+    if (CGRectIsNull(overlayRect))
+        return 0;
+        
+    overlayRect.expand(highlightMargin, highlightMargin);
+    
+    if (!targetRect.intersects(overlayRect))
+        return 0;
+    
+    float topGap = overlayRect.y() - [self bounds].origin.y;
+    float bottomGap = (self.bounds.size.height + self.bounds.origin.y) - overlayRect.maxY();
+    
+    float midScreen = self.center.y;
+
+    if (topGap > bottomGap) {
+        auto midGap = topGap / 2 + self.bounds.origin.y;
+        auto diff = midScreen - midGap;
+        return diff;
+    }
+    
+    auto midGap = bottomGap / 2 + self.bounds.origin.y;
+    auto diff = midGap - midScreen;
+    return diff;
+#else
+    return 0;
+#endif
+}
+
+
 - (BOOL)_scrollToRect:(WebCore::FloatRect)targetRect origin:(WebCore::FloatPoint)origin minimumScrollDistance:(float)minimumScrollDistance
 {
     if (![_scrollView isScrollEnabled])
@@ -1187,6 +1221,15 @@
     scrollViewOffsetDelta.scale(contentZoomScale(self));
 
     float scrollDistance = scrollViewOffsetDelta.diagonalLength();
+    
+    WebCore::FloatRect startRect = targetRect;
+    WebCore::FloatRect convertedStartRect = [self convertRect:startRect fromView:self._currentContentView];
+    convertedStartRect.move(-scrollViewOffsetDelta);
+
+    float additionalOffset = [self _adjustScrollRectToAvoidHighlightOverlay:convertedStartRect];
+
+    scrollViewOffsetDelta += WebCore::FloatSize(0, additionalOffset);
+    
     if (scrollDistance < minimumScrollDistance)
         return NO;
 

Modified: trunk/Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm (280177 => 280178)


--- trunk/Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm	2021-07-22 16:56:03 UTC (rev 280177)
+++ trunk/Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm	2021-07-22 17:07:21 UTC (rev 280178)
@@ -603,6 +603,13 @@
     return [m_appHighlightsObserver isVisible];
 }
 
+CGRect WebPageProxy::appHighlightsOverlayRect()
+{
+    if (!m_appHighlightsObserver)
+        setUpHighlightsObserver();
+    return [m_appHighlightsObserver visibleFrame];
+}
+
 void WebPageProxy::setUpHighlightsObserver()
 {
     if (m_appHighlightsObserver)

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (280177 => 280178)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.h	2021-07-22 16:56:03 UTC (rev 280177)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h	2021-07-22 17:07:21 UTC (rev 280178)
@@ -1910,6 +1910,7 @@
     void restoreAppHighlightsAndScrollToIndex(const Vector<Ref<WebKit::SharedMemory>>& highlights, const std::optional<unsigned> index);
     void setAppHighlightsVisibility(const WebCore::HighlightVisibility);
     bool appHighlightsVisibility();
+    CGRect appHighlightsOverlayRect();
 #endif
 
 #if ENABLE(MEDIA_STREAM)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to