Title: [228549] trunk/Source
Revision
228549
Author
[email protected]
Date
2018-02-15 19:08:06 -0800 (Thu, 15 Feb 2018)

Log Message

Support scrolling for non-editable web-selection and start autoscroll when near screen edges
https://bugs.webkit.org/show_bug.cgi?id=182815

Source/WebCore:

Reviewed by Tim Horton.

Adjust the position we are autoscrolling to so that when we are close to an edge, we will start autoscrolling
while we are still inside the view. Autoscrolling still happens when you drag past the edge of a view.

No new tests (This is difficult to test in this state, but when we switch assistants, test will also be added).

* page/EventHandler.h:
* page/ios/EventHandlerIOS.mm:
(WebCore::EventHandler::startSelectionAutoscroll):
(WebCore::EventHandler::cancelSelectionAutoscroll):
(WebCore::autoscrollAdjustmentFactorForScreenBoundaries):
(WebCore::EventHandler::targetPositionInWindowForSelectionAutoscroll const):
(WebCore::EventHandler::startTextAutoscroll): Deleted.
(WebCore::EventHandler::cancelTextAutoscroll): Deleted.

Source/WebKit:

Add support for autoscrolling during a selection. This also takes into account the edges of the screen
and starts autoscrolling when you get close, while still allowing autoscrolling when you are past the bounds
of the WebView.

Reviewed by Tim Horton.

* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView startAutoscroll:]):
(-[WKContentView resignFirstResponderForWebView]):
(-[WKContentView useSelectionAssistantWithGranularity:]):
(-[WKContentView selectedTextRange]):
* UIProcess/ios/WebPageProxyIOS.mm:
(WebKit::WebPageProxy::startAutoscrollAtPosition):
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::startAutoscrollAtPosition):
(WebKit::WebPage::cancelAutoscroll):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (228548 => 228549)


--- trunk/Source/WebCore/ChangeLog	2018-02-16 02:45:07 UTC (rev 228548)
+++ trunk/Source/WebCore/ChangeLog	2018-02-16 03:08:06 UTC (rev 228549)
@@ -1,3 +1,24 @@
+2018-02-15  Megan Gardner  <[email protected]>
+
+        Support scrolling for non-editable web-selection and start autoscroll when near screen edges
+        https://bugs.webkit.org/show_bug.cgi?id=182815
+
+        Reviewed by Tim Horton.
+
+        Adjust the position we are autoscrolling to so that when we are close to an edge, we will start autoscrolling
+        while we are still inside the view. Autoscrolling still happens when you drag past the edge of a view.
+
+        No new tests (This is difficult to test in this state, but when we switch assistants, test will also be added).
+
+        * page/EventHandler.h:
+        * page/ios/EventHandlerIOS.mm:
+        (WebCore::EventHandler::startSelectionAutoscroll):
+        (WebCore::EventHandler::cancelSelectionAutoscroll):
+        (WebCore::autoscrollAdjustmentFactorForScreenBoundaries):
+        (WebCore::EventHandler::targetPositionInWindowForSelectionAutoscroll const):
+        (WebCore::EventHandler::startTextAutoscroll): Deleted.
+        (WebCore::EventHandler::cancelTextAutoscroll): Deleted.
+
 2018-02-15  Youenn Fablet  <[email protected]>
 
         Log the error message when failing to open the database

Modified: trunk/Source/WebCore/page/EventHandler.h (228548 => 228549)


--- trunk/Source/WebCore/page/EventHandler.h	2018-02-16 02:45:07 UTC (rev 228548)
+++ trunk/Source/WebCore/page/EventHandler.h	2018-02-16 03:08:06 UTC (rev 228549)
@@ -338,8 +338,8 @@
 #endif
     
 #if PLATFORM(IOS)
-    WEBCORE_EXPORT void startTextAutoscroll(RenderObject* renderer, const FloatPoint& positionInWindow);
-    WEBCORE_EXPORT void cancelTextAutoscroll();
+    WEBCORE_EXPORT void startSelectionAutoscroll(RenderObject* renderer, const FloatPoint& positionInWindow);
+    WEBCORE_EXPORT void cancelSelectionAutoscroll();
     IntPoint m_targetAutoscrollPositionInWindow;
     bool m_isAutoscrolling { false };
 #endif

Modified: trunk/Source/WebCore/page/ios/EventHandlerIOS.mm (228548 => 228549)


--- trunk/Source/WebCore/page/ios/EventHandlerIOS.mm	2018-02-16 02:45:07 UTC (rev 228548)
+++ trunk/Source/WebCore/page/ios/EventHandlerIOS.mm	2018-02-16 03:08:06 UTC (rev 228549)
@@ -562,22 +562,76 @@
     return PlatformEventFactory::createPlatformMouseEvent(currentEvent());
 }
     
-void EventHandler::startTextAutoscroll(RenderObject* renderer, const FloatPoint& positionInWindow)
+void EventHandler::startSelectionAutoscroll(RenderObject* renderer, const FloatPoint& positionInWindow)
 {
-    m_targetAutoscrollPositionInWindow = roundedIntPoint(positionInWindow);
+    Ref<Frame> protectedFrame(m_frame);
+
+    m_targetAutoscrollPositionInWindow = protectedFrame->view()->contentsToView(roundedIntPoint(positionInWindow));
+    
     m_isAutoscrolling = true;
     m_autoscrollController->startAutoscrollForSelection(renderer);
 }
 
-void EventHandler::cancelTextAutoscroll()
+void EventHandler::cancelSelectionAutoscroll()
 {
     m_isAutoscrolling = false;
     m_autoscrollController->stopAutoscrollTimer();
 }
+
+static IntSize autoscrollAdjustmentFactorForScreenBoundaries(const IntPoint& screenPoint, const FloatRect& screenRect)
+{
+    // If the window is at the edge of the screen, and the touch position is also at that edge of the screen,
+    // we need to adjust the autoscroll amount in order for the user to be able to autoscroll in that direction.
+    // We can pretend that the touch position is slightly beyond the edge of the screen, and then autoscrolling
+    // will occur as expected. This function figures out just how much to adjust the autoscroll amount by
+    // in order to get autoscrolling to feel natural in this situation.
     
+    IntSize adjustmentFactor;
+    
+#define EDGE_DISTANCE_THRESHOLD 100
+
+    float screenLeftEdge = screenRect.x();
+    float insetScreenLeftEdge = screenLeftEdge + EDGE_DISTANCE_THRESHOLD;
+    float screenRightEdge = screenRect.maxX();
+    float insetScreenRightEdge = screenRightEdge - EDGE_DISTANCE_THRESHOLD;
+    if (screenPoint.x() >= screenLeftEdge && screenPoint.x() < insetScreenLeftEdge) {
+        float distanceFromEdge = screenPoint.x() - screenLeftEdge - EDGE_DISTANCE_THRESHOLD;
+        if (distanceFromEdge < 0)
+            adjustmentFactor.setWidth(-EDGE_DISTANCE_THRESHOLD);
+    } else if (screenPoint.x() >= insetScreenRightEdge && screenPoint.x() < screenRightEdge) {
+        float distanceFromEdge = EDGE_DISTANCE_THRESHOLD - (screenRightEdge - screenPoint.x());
+        if (distanceFromEdge > 0)
+            adjustmentFactor.setWidth(EDGE_DISTANCE_THRESHOLD);
+    }
+    
+    float screenTopEdge = screenRect.y();
+    float insetScreenTopEdge = screenTopEdge + EDGE_DISTANCE_THRESHOLD;
+    float screenBottomEdge = screenRect.maxY();
+    float insetScreenBottomEdge = screenBottomEdge - EDGE_DISTANCE_THRESHOLD;
+    
+    if (screenPoint.y() >= screenTopEdge && screenPoint.y() < insetScreenTopEdge) {
+        float distanceFromEdge = screenPoint.y() - screenTopEdge - EDGE_DISTANCE_THRESHOLD;
+        if (distanceFromEdge < 0)
+            adjustmentFactor.setHeight(-EDGE_DISTANCE_THRESHOLD);
+    } else if (screenPoint.y() >= insetScreenBottomEdge && screenPoint.y() < screenBottomEdge) {
+        float distanceFromEdge = EDGE_DISTANCE_THRESHOLD - (screenBottomEdge - screenPoint.y());
+        if (distanceFromEdge > 0)
+            adjustmentFactor.setHeight(EDGE_DISTANCE_THRESHOLD);
+    }
+    
+    return adjustmentFactor;
+}
+    
 IntPoint EventHandler::targetPositionInWindowForSelectionAutoscroll() const
 {
-    return m_targetAutoscrollPositionInWindow;
+    Ref<Frame> protectedFrame(m_frame);
+    
+    FloatRect unobscuredContentRect = protectedFrame->view()->unobscuredContentRect();
+    
+    // Manually need to convert viewToContents, as it will be skipped because delegatedScrolling is on iOS
+    IntPoint contentPosition = protectedFrame->view()->viewToContents(protectedFrame->view()->convertFromContainingWindow(m_targetAutoscrollPositionInWindow));
+    IntSize adjustPosition = autoscrollAdjustmentFactorForScreenBoundaries(contentPosition, unobscuredContentRect);
+    return contentPosition + adjustPosition;
 }
     
 bool EventHandler::shouldUpdateAutoscroll()

Modified: trunk/Source/WebKit/ChangeLog (228548 => 228549)


--- trunk/Source/WebKit/ChangeLog	2018-02-16 02:45:07 UTC (rev 228548)
+++ trunk/Source/WebKit/ChangeLog	2018-02-16 03:08:06 UTC (rev 228549)
@@ -1,3 +1,25 @@
+2018-02-15  Megan Gardner  <[email protected]>
+
+        Support scrolling for non-editable web-selection and start autoscroll when near screen edges
+        https://bugs.webkit.org/show_bug.cgi?id=182815
+
+        Add support for autoscrolling during a selection. This also takes into account the edges of the screen
+        and starts autoscrolling when you get close, while still allowing autoscrolling when you are past the bounds
+        of the WebView.
+
+        Reviewed by Tim Horton.
+
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView startAutoscroll:]):
+        (-[WKContentView resignFirstResponderForWebView]):
+        (-[WKContentView useSelectionAssistantWithGranularity:]):
+        (-[WKContentView selectedTextRange]):
+        * UIProcess/ios/WebPageProxyIOS.mm:
+        (WebKit::WebPageProxy::startAutoscrollAtPosition):
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::WebPage::startAutoscrollAtPosition):
+        (WebKit::WebPage::cancelAutoscroll):
+
 2018-02-15  John Wilander  <[email protected]>
 
         Resource Load Statistics: Make sure WebResourceLoadStatisticsStore::mergeWithDataFromDecoder() can ingest older plist versions and not reset the database

Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (228548 => 228549)


--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2018-02-16 02:45:07 UTC (rev 228548)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2018-02-16 03:08:06 UTC (rev 228549)
@@ -762,9 +762,9 @@
 
 
 #pragma mark - UITextAutoscrolling
-- (void)startAutoscroll:(CGPoint)point
+- (void)startAutoscroll:(CGPoint)pointInDocument
 {
-    _page->startAutoscrollAtPosition(point);
+    _page->startAutoscrollAtPosition(pointInDocument);
 }
 
 - (void)cancelAutoscroll
@@ -917,7 +917,6 @@
     // and do nothing if the return value is NO.
 
     _resigningFirstResponder = YES;
-
     if (!_webView->_activeFocusedStateRetainCount) {
         // We need to complete the editing operation before we blur the element.
         [_inputPeripheral endEditing];
@@ -3133,7 +3132,7 @@
 
 - (UITextRange *)selectedTextRange
 {
-    if (_page->editorState().selectionIsNone)
+    if (_page->editorState().selectionIsNone || _page->editorState().isMissingPostLayoutData)
         return nil;
     auto& postLayoutEditorStateData = _page->editorState().postLayoutData();
     FloatRect startRect = postLayoutEditorStateData.caretRectAtStart;

Modified: trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm (228548 => 228549)


--- trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm	2018-02-16 02:45:07 UTC (rev 228548)
+++ trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm	2018-02-16 03:08:06 UTC (rev 228549)
@@ -734,9 +734,9 @@
     m_process->send(Messages::WebPage::StoreSelectionForAccessibility(shouldStore), m_pageID);
 }
 
-void WebPageProxy::startAutoscrollAtPosition(const WebCore::FloatPoint& position)
+void WebPageProxy::startAutoscrollAtPosition(const WebCore::FloatPoint& positionInWindow)
 {
-    m_process->send(Messages::WebPage::StartAutoscrollAtPosition(position), m_pageID);
+    m_process->send(Messages::WebPage::StartAutoscrollAtPosition(positionInWindow), m_pageID);
 }
     
 void WebPageProxy::cancelAutoscroll()

Modified: trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm (228548 => 228549)


--- trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm	2018-02-16 02:45:07 UTC (rev 228548)
+++ trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm	2018-02-16 03:08:06 UTC (rev 228549)
@@ -1824,12 +1824,23 @@
 void WebPage::startAutoscrollAtPosition(const WebCore::FloatPoint& positionInWindow)
 {
     if (m_assistedNode && m_assistedNode->renderer())
-        m_page->mainFrame().eventHandler().startTextAutoscroll(m_assistedNode->renderer(), positionInWindow);
+        m_page->mainFrame().eventHandler().startSelectionAutoscroll(m_assistedNode->renderer(), positionInWindow);
+    else {
+        Frame& frame = m_page->focusController().focusedOrMainFrame();
+        VisibleSelection selection = frame.selection().selection();
+        if (selection.isRange()) {
+            RefPtr<Range> range = frame.selection().toNormalizedRange();
+            Node& node = range->startContainer();
+            auto* renderer = node.renderer();
+            if (renderer)
+                m_page->mainFrame().eventHandler().startSelectionAutoscroll(renderer, positionInWindow);
+        }
+    }
 }
     
 void WebPage::cancelAutoscroll()
 {
-    m_page->mainFrame().eventHandler().cancelTextAutoscroll();
+    m_page->mainFrame().eventHandler().cancelSelectionAutoscroll();
 }
 
 void WebPage::getRectsForGranularityWithSelectionOffset(uint32_t granularity, int32_t offset, CallbackID callbackID)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to