Title: [227355] branches/safari-605-branch/Source/WebKit
Revision
227355
Author
megan_gard...@apple.com
Date
2018-01-22 13:49:34 -0800 (Mon, 22 Jan 2018)

Log Message

Cherry-pick r227274. rdar://problem/36722660

    2018-01-20  Andy Estes  <aes...@apple.com>

    [Apple Pay] Stop eagerly loading PassKit.framework
    https://bugs.webkit.org/show_bug.cgi?id=181911
    <rdar://problem/36555369>

    Reviewed by Tim Horton.

    * Shared/WebPageCreationParameters.cpp:
    (WebKit::WebPageCreationParameters::encode const):
    (WebKit::WebPageCreationParameters::decode):
    * Shared/WebPageCreationParameters.h:

    Removed availablePaymentNetworks from WebPageCreationParameters.

    * UIProcess/API/C/WKPreferences.cpp:
    (WKPreferencesSetApplePayEnabled):
    * UIProcess/API/Cocoa/WKWebView.mm:
    (-[WKWebView _initializeWithConfiguration:]):

    Stopped calling WebPaymentCoordinatorProxy::platformSupportsPayments().

    * UIProcess/ApplePay/WebPaymentCoordinatorProxy.cpp:
    (WebKit::WebPaymentCoordinatorProxy::availablePaymentNetworks):
    * UIProcess/ApplePay/WebPaymentCoordinatorProxy.h:
    * UIProcess/ApplePay/WebPaymentCoordinatorProxy.messages.in:

    Added message AvailablePaymentNetworks, which synchronously returns a Vector of payment
    networks.

    * UIProcess/ApplePay/cocoa/WebPaymentCoordinatorProxyCocoa.mm:
    (WebKit::WebPaymentCoordinatorProxy::platformCanMakePayments):

    Returned false if PassKitLibrary() fails.

    (WebKit::WebPaymentCoordinatorProxy::platformCanMakePaymentsWithActiveCard):
    (WebKit::WebPaymentCoordinatorProxy::platformOpenPaymentSetup):

    Called completionHandler with false if PassKitLibrary() fails.

    (WebKit::WebPaymentCoordinatorProxy::platformAvailablePaymentNetworks):
    (WebKit::WebPaymentCoordinatorProxy::availablePaymentNetworks):

    Renamed availablePaymentNetworks to platformAvailablePaymentNetworks

    (WebKit::WebPaymentCoordinatorProxy::platformSupportsPayments): Deleted.

    * UIProcess/ApplePay/mac/WebPaymentCoordinatorProxyMac.mm:
    (WebKit::WebPaymentCoordinatorProxy::platformShowPaymentUI):

    Called completionHandler with false if PassKitLibrary() fails.

    * UIProcess/WebPageProxy.cpp:
    (WebKit::WebPageProxy::creationParameters):

    Stopped calling WebPaymentCoordinatorProxy::availablePaymentNetworks().

    * WebProcess/ApplePay/WebPaymentCoordinator.cpp:
    (WebKit::WebPaymentCoordinator::availablePaymentNetworks):
    (WebKit::WebPaymentCoordinator::validatedPaymentNetwork):
    * WebProcess/ApplePay/WebPaymentCoordinator.h:

    Implemented PaymentCoordinatorClient::validatedPaymentNetwork(). m_availablePaymentNetworks
    starts off as std::nullopt, but is initialized by sending the AvailablePaymentNetworks sync
    message the first time it's accessed.

    * WebProcess/WebPage/WebPage.cpp:
    (WebKit::WebPage::WebPage):

    Stopped setting PageConfiguration::availablePaymentNetworks.

Patch by Jason Marcell <jmarc...@apple.com> on 2018-01-22

Modified Paths

Diff

Modified: branches/safari-605-branch/Source/WebKit/ChangeLog (227354 => 227355)


--- branches/safari-605-branch/Source/WebKit/ChangeLog	2018-01-22 21:32:58 UTC (rev 227354)
+++ branches/safari-605-branch/Source/WebKit/ChangeLog	2018-01-22 21:49:34 UTC (rev 227355)
@@ -290,6 +290,20 @@
 
 2018-01-19  Megan Gardner  <megan_gard...@apple.com>
 
+        Temporarily restore block selection code conditionally
+        https://bugs.webkit.org/show_bug.cgi?id=181895
+        <rdar://problem/36567325>
+
+        Reviewed by Tim Horton.
+
+        We need to restore this code temporarily to avoid a crash.
+
+        * Platform/spi/ios/UIKitSPI.h:
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView changeBlockSelectionWithTouchAt:withSelectionTouch:forHandle:]):
+
+2018-01-19  Megan Gardner  <megan_gard...@apple.com>
+
         Present WKFileUploadPanel on correct ViewController
         https://bugs.webkit.org/show_bug.cgi?id=181884
         <rdar://problem/35114892>

Modified: branches/safari-605-branch/Source/WebKit/Platform/spi/ios/UIKitSPI.h (227354 => 227355)


--- branches/safari-605-branch/Source/WebKit/Platform/spi/ios/UIKitSPI.h	2018-01-22 21:32:58 UTC (rev 227354)
+++ branches/safari-605-branch/Source/WebKit/Platform/spi/ios/UIKitSPI.h	2018-01-22 21:49:34 UTC (rev 227355)
@@ -542,6 +542,9 @@
 @end
 
 @interface UIWKSelectionAssistant ()
+#if __IPHONE_OS_VERSION_MAX_ALLOWED < 120000
+- (void)blockSelectionChangedWithTouch:(UIWKSelectionTouch)touch withFlags:(UIWKSelectionFlags)flags growThreshold:(CGFloat)grow shrinkThreshold:(CGFloat)shrink;
+#endif
 - (BOOL)shouldHandleSingleTapAtPoint:(CGPoint)point;
 - (void)selectionChangedWithGestureAt:(CGPoint)point withGesture:(UIWKGestureType)gestureType withState:(UIGestureRecognizerState)gestureState withFlags:(UIWKSelectionFlags)flags;
 - (void)selectionChangedWithTouchAt:(CGPoint)point withSelectionTouch:(UIWKSelectionTouch)touch withFlags:(UIWKSelectionFlags)flags;
@@ -590,6 +593,15 @@
 @property (nonatomic, readonly, assign) UITapGestureRecognizer *singleTapGesture;
 @end
 
+#if __IPHONE_OS_VERSION_MAX_ALLOWED < 120000
+typedef NS_ENUM(NSInteger, UIWKHandlePosition) {
+    UIWKHandleTop = 0,
+    UIWKHandleRight = 1,
+    UIWKHandleBottom = 2,
+    UIWKHandleLeft = 3,
+};
+#endif
+
 @protocol UIWKInteractionViewProtocol
 - (void)changeSelectionWithGestureAt:(CGPoint)point withGesture:(UIWKGestureType)gestureType withState:(UIGestureRecognizerState)state;
 - (void)changeSelectionWithTouchAt:(CGPoint)point withSelectionTouch:(UIWKSelectionTouch)touch baseIsStart:(BOOL)baseIsStart withFlags:(UIWKSelectionFlags)flags;
@@ -614,6 +626,9 @@
 - (void)_cancelLongPressGestureRecognizer;
 
 @optional
+#if __IPHONE_OS_VERSION_MAX_ALLOWED < 120000
+- (void)changeBlockSelectionWithTouchAt:(CGPoint)point withSelectionTouch:(UIWKSelectionTouch)touch forHandle:(UIWKHandlePosition)handle;
+#endif
 
 - (void)clearSelection;
 - (void)replaceDictatedText:(NSString *)oldText withText:(NSString *)newText;

Modified: branches/safari-605-branch/Source/WebKit/UIProcess/PageClient.h (227354 => 227355)


--- branches/safari-605-branch/Source/WebKit/UIProcess/PageClient.h	2018-01-22 21:32:58 UTC (rev 227354)
+++ branches/safari-605-branch/Source/WebKit/UIProcess/PageClient.h	2018-01-22 21:49:34 UTC (rev 227355)
@@ -296,6 +296,9 @@
     virtual bool interpretKeyEvent(const NativeWebKeyboardEvent&, bool isCharEvent) = 0;
     virtual void positionInformationDidChange(const InteractionInformationAtPosition&) = 0;
     virtual void saveImageToLibrary(Ref<WebCore::SharedBuffer>&&) = 0;
+#if __IPHONE_OS_VERSION_MAX_ALLOWED < 120000
+    virtual void didUpdateBlockSelectionWithTouch(uint32_t touch, uint32_t flags, float growThreshold, float shrinkThreshold) = 0;
+#endif
     virtual void showPlaybackTargetPicker(bool hasVideo, const WebCore::IntRect& elementRect) = 0;
     virtual void disableDoubleTapGesturesDuringTapIfNecessary(uint64_t requestID) = 0;
     virtual double minimumZoomScale() const = 0;

Modified: branches/safari-605-branch/Source/WebKit/UIProcess/WebPageProxy.h (227354 => 227355)


--- branches/safari-605-branch/Source/WebKit/UIProcess/WebPageProxy.h	2018-01-22 21:32:58 UTC (rev 227354)
+++ branches/safari-605-branch/Source/WebKit/UIProcess/WebPageProxy.h	2018-01-22 21:49:34 UTC (rev 227355)
@@ -538,6 +538,9 @@
     void selectWithGesture(const WebCore::IntPoint, WebCore::TextGranularity, uint32_t gestureType, uint32_t gestureState, bool isInteractingWithAssistedNode, WTF::Function<void (const WebCore::IntPoint&, uint32_t, uint32_t, uint32_t, CallbackBase::Error)>&&);
     void updateSelectionWithTouches(const WebCore::IntPoint, uint32_t touches, bool baseIsStart, WTF::Function<void (const WebCore::IntPoint&, uint32_t, uint32_t, CallbackBase::Error)>&&);
     void selectWithTwoTouches(const WebCore::IntPoint from, const WebCore::IntPoint to, uint32_t gestureType, uint32_t gestureState, WTF::Function<void (const WebCore::IntPoint&, uint32_t, uint32_t, uint32_t, CallbackBase::Error)>&&);
+#if __IPHONE_OS_VERSION_MAX_ALLOWED < 120000
+    void updateBlockSelectionWithTouch(const WebCore::IntPoint, uint32_t touch, uint32_t handlePosition);
+#endif
     void extendSelection(WebCore::TextGranularity);
     void selectWordBackward();
     void moveSelectionByOffset(int32_t offset, WTF::Function<void (CallbackBase::Error)>&&);
@@ -562,6 +565,9 @@
     void stopInteraction();
     void performActionOnElement(uint32_t action);
     void saveImageToLibrary(const SharedMemory::Handle& imageHandle, uint64_t imageSize);
+#if __IPHONE_OS_VERSION_MAX_ALLOWED < 120000
+    void didUpdateBlockSelectionWithTouch(uint32_t touch, uint32_t flags, float growThreshold, float shrinkThreshold);
+#endif
     void focusNextAssistedNode(bool isForward, WTF::Function<void (CallbackBase::Error)>&&);
     void setAssistedNodeValue(const String&);
     void setAssistedNodeValueAsNumber(double);

Modified: branches/safari-605-branch/Source/WebKit/UIProcess/WebPageProxy.messages.in (227354 => 227355)


--- branches/safari-605-branch/Source/WebKit/UIProcess/WebPageProxy.messages.in	2018-01-22 21:32:58 UTC (rev 227354)
+++ branches/safari-605-branch/Source/WebKit/UIProcess/WebPageProxy.messages.in	2018-01-22 21:49:34 UTC (rev 227355)
@@ -182,6 +182,9 @@
     SelectionContextCallback(String selectedText, String beforeText, String afterText, WebKit::CallbackID callbackID)
     InterpretKeyEvent(struct WebKit::EditorState state, bool isCharEvent) -> (bool handled)
     DidReceivePositionInformation(struct WebKit::InteractionInformationAtPosition information)
+#if __IPHONE_OS_VERSION_MAX_ALLOWED < 120000
+    DidUpdateBlockSelectionWithTouch(uint32_t touch, uint32_t flags, float growThreshold, float shrinkThreshold)
+#endif
     SaveImageToLibrary(WebKit::SharedMemory::Handle handle, uint64_t size)
     ShowPlaybackTargetPicker(bool hasVideo, WebCore::IntRect elementRect)
     CommitPotentialTapFailed()

Modified: branches/safari-605-branch/Source/WebKit/UIProcess/ios/PageClientImplIOS.h (227354 => 227355)


--- branches/safari-605-branch/Source/WebKit/UIProcess/ios/PageClientImplIOS.h	2018-01-22 21:32:58 UTC (rev 227354)
+++ branches/safari-605-branch/Source/WebKit/UIProcess/ios/PageClientImplIOS.h	2018-01-22 21:49:34 UTC (rev 227355)
@@ -132,6 +132,9 @@
     bool interpretKeyEvent(const NativeWebKeyboardEvent&, bool isCharEvent) override;
     void positionInformationDidChange(const InteractionInformationAtPosition&) override;
     void saveImageToLibrary(Ref<WebCore::SharedBuffer>&&) override;
+#if __IPHONE_OS_VERSION_MAX_ALLOWED < 120000
+    void didUpdateBlockSelectionWithTouch(uint32_t touch, uint32_t flags, float growThreshold, float shrinkThreshold) override;
+#endif
     void showPlaybackTargetPicker(bool hasVideo, const WebCore::IntRect& elementRect) override;
 
     bool handleRunOpenPanel(WebPageProxy*, WebFrameProxy*, API::OpenPanelParameters*, WebOpenPanelResultListenerProxy*) override;

Modified: branches/safari-605-branch/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm (227354 => 227355)


--- branches/safari-605-branch/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm	2018-01-22 21:32:58 UTC (rev 227354)
+++ branches/safari-605-branch/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm	2018-01-22 21:49:34 UTC (rev 227355)
@@ -561,6 +561,14 @@
 {
     [m_contentView _stopAssistingNode];
 }
+    
+#if __IPHONE_OS_VERSION_MAX_ALLOWED < 120000
+void PageClientImpl::didUpdateBlockSelectionWithTouch(uint32_t touch, uint32_t flags, float growThreshold, float shrinkThreshold)
+{
+    [m_contentView _didUpdateBlockSelectionWithTouch:(SelectionTouch)touch withFlags:(SelectionFlags)flags growThreshold:growThreshold shrinkThreshold:shrinkThreshold];
+}
+#endif
+    
 
 void PageClientImpl::showPlaybackTargetPicker(bool hasVideo, const IntRect& elementRect)
 {

Modified: branches/safari-605-branch/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h (227354 => 227355)


--- branches/safari-605-branch/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h	2018-01-22 21:32:58 UTC (rev 227354)
+++ branches/safari-605-branch/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h	2018-01-22 21:49:34 UTC (rev 227355)
@@ -295,6 +295,9 @@
 - (void)_didEndScrollingOrZooming;
 - (void)_overflowScrollingWillBegin;
 - (void)_overflowScrollingDidEnd;
+#if __IPHONE_OS_VERSION_MAX_ALLOWED < 120000
+- (void)_didUpdateBlockSelectionWithTouch:(WebKit::SelectionTouch)touch withFlags:(WebKit::SelectionFlags)flags growThreshold:(CGFloat)growThreshold shrinkThreshold:(CGFloat)shrinkThreshold;
+#endif
 - (void)_showPlaybackTargetPicker:(BOOL)hasVideo fromRect:(const WebCore::IntRect&)elementRect;
 - (void)_showRunOpenPanel:(API::OpenPanelParameters*)parameters resultListener:(WebKit::WebOpenPanelResultListenerProxy*)listener;
 - (void)accessoryDone;

Modified: branches/safari-605-branch/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (227354 => 227355)


--- branches/safari-605-branch/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2018-01-22 21:32:58 UTC (rev 227354)
+++ branches/safari-605-branch/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2018-01-22 21:49:34 UTC (rev 227355)
@@ -2502,6 +2502,22 @@
     return static_cast<UIWKSelectionFlags>(uiFlags);
 }
 
+#if __IPHONE_OS_VERSION_MAX_ALLOWED < 120000
+static inline SelectionHandlePosition toSelectionHandlePosition(UIWKHandlePosition position)
+{
+    switch (position) {
+    case UIWKHandleTop:
+        return SelectionHandlePosition::Top;
+    case UIWKHandleRight:
+        return SelectionHandlePosition::Right;
+    case UIWKHandleBottom:
+        return SelectionHandlePosition::Bottom;
+    case UIWKHandleLeft:
+        return SelectionHandlePosition::Left;
+    }
+}
+#endif
+
 static inline WebCore::TextGranularity toWKTextGranularity(UITextGranularity granularity)
 {
     switch (granularity) {
@@ -2560,6 +2576,15 @@
         [(UIWKTextInteractionAssistant *)[view interactionAssistant] selectionChangedWithTouchAt:(CGPoint)point withSelectionTouch:toUIWKSelectionTouch((SelectionTouch)touch) withFlags:static_cast<UIWKSelectionFlags>(flags)];
 }
 
+#if __IPHONE_OS_VERSION_MAX_ALLOWED < 120000
+- (void)_didUpdateBlockSelectionWithTouch:(SelectionTouch)touch withFlags:(SelectionFlags)flags growThreshold:(CGFloat)growThreshold shrinkThreshold:(CGFloat)shrinkThreshold
+{
+    [_webSelectionAssistant blockSelectionChangedWithTouch:toUIWKSelectionTouch(touch) withFlags:toUIWKSelectionFlags(flags) growThreshold:growThreshold shrinkThreshold:shrinkThreshold];
+    if (touch != SelectionTouch::Started && touch != SelectionTouch::Moved)
+        _usingGestureForSelection = NO;
+}
+#endif
+
 - (BOOL)_isInteractingWithAssistedNode
 {
     return _textSelectionAssistant != nil;
@@ -2607,6 +2632,19 @@
     });
 }
 
+#if __IPHONE_OS_VERSION_MAX_ALLOWED < 120000
+- (void)changeBlockSelectionWithTouchAt:(CGPoint)point withSelectionTouch:(UIWKSelectionTouch)touch forHandle:(UIWKHandlePosition)handle
+{
+    // This was only readded to avoid a crash due to incompatibilities with certain version of UIKit.
+    // This should be removed ASAP.
+    // The selection will be properly updated with the next update, selection still functions
+    // without this function doing anything.
+    
+    _usingGestureForSelection = YES;
+    _page->updateBlockSelectionWithTouch(WebCore::IntPoint(point), static_cast<uint32_t>(toSelectionTouch(touch)), static_cast<uint32_t>(toSelectionHandlePosition(handle)));
+}
+#endif
+
 - (void)moveByOffset:(NSInteger)offset
 {
     if (!offset)

Modified: branches/safari-605-branch/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm (227354 => 227355)


--- branches/safari-605-branch/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm	2018-01-22 21:32:58 UTC (rev 227354)
+++ branches/safari-605-branch/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm	2018-01-22 21:49:34 UTC (rev 227355)
@@ -651,6 +651,18 @@
     auto buffer = SharedBuffer::create(static_cast<unsigned char*>(sharedMemoryBuffer->data()), imageSize);
     m_pageClient.saveImageToLibrary(WTFMove(buffer));
 }
+    
+#if __IPHONE_OS_VERSION_MAX_ALLOWED < 120000
+void WebPageProxy::updateBlockSelectionWithTouch(const WebCore::IntPoint point, uint32_t touch, uint32_t handlePosition)
+{
+    m_process->send(Messages::WebPage::UpdateBlockSelectionWithTouch(point, touch, handlePosition), m_pageID);
+}
+    
+void WebPageProxy::didUpdateBlockSelectionWithTouch(uint32_t touch, uint32_t flags, float growThreshold, float shrinkThreshold)
+{
+    m_pageClient.didUpdateBlockSelectionWithTouch(touch, flags, growThreshold, shrinkThreshold);
+}
+#endif
 
 void WebPageProxy::applicationDidEnterBackground()
 {

Modified: branches/safari-605-branch/Source/WebKit/WebProcess/WebPage/WebPage.h (227354 => 227355)


--- branches/safari-605-branch/Source/WebKit/WebProcess/WebPage/WebPage.h	2018-01-22 21:32:58 UTC (rev 227354)
+++ branches/safari-605-branch/Source/WebKit/WebProcess/WebPage/WebPage.h	2018-01-22 21:49:34 UTC (rev 227355)
@@ -569,6 +569,9 @@
     void blurAssistedNode();
     void selectWithGesture(const WebCore::IntPoint&, uint32_t granularity, uint32_t gestureType, uint32_t gestureState, bool isInteractingWithAssistedNode, CallbackID);
     void updateSelectionWithTouches(const WebCore::IntPoint&, uint32_t touches, bool baseIsStart, CallbackID);
+#if __IPHONE_OS_VERSION_MAX_ALLOWED < 120000
+    void updateBlockSelectionWithTouch(const WebCore::IntPoint&, uint32_t touch, uint32_t handlePosition);
+#endif
     void selectWithTwoTouches(const WebCore::IntPoint& from, const WebCore::IntPoint& to, uint32_t gestureType, uint32_t gestureState, CallbackID);
     void extendSelection(uint32_t granularity);
     void selectWordBackward();
@@ -1085,6 +1088,12 @@
 
     static void convertSelectionRectsToRootView(WebCore::FrameView*, Vector<WebCore::SelectionRect>&);
     RefPtr<WebCore::Range> rangeForWebSelectionAtPosition(const WebCore::IntPoint&, const WebCore::VisiblePosition&, SelectionFlags&);
+#if __IPHONE_OS_VERSION_MAX_ALLOWED < 120000
+    RefPtr<WebCore::Range> rangeForBlockAtPoint(const WebCore::IntPoint&);
+    void computeExpandAndShrinkThresholdsForHandle(const WebCore::IntPoint&, SelectionHandlePosition, float& growThreshold, float& shrinkThreshold);
+    Ref<WebCore::Range> expandedRangeFromHandle(WebCore::Range&, SelectionHandlePosition);
+    Ref<WebCore::Range> contractedRangeFromHandle(WebCore::Range& currentRange, SelectionHandlePosition, SelectionFlags&);
+#endif
     void getAssistedNodeInformation(AssistedNodeInformation&);
     void platformInitializeAccessibility();
     void handleSyntheticClick(WebCore::Node* nodeRespondingToClick, const WebCore::FloatPoint& location);
@@ -1093,7 +1102,10 @@
     void resetTextAutosizing();
     WebCore::VisiblePosition visiblePositionInFocusedNodeForPoint(const WebCore::Frame&, const WebCore::IntPoint&, bool isInteractingWithAssistedNode);
     RefPtr<WebCore::Range> rangeForGranularityAtPoint(WebCore::Frame&, const WebCore::IntPoint&, uint32_t granularity, bool isInteractingWithAssistedNode);
+#if __IPHONE_OS_VERSION_MAX_ALLOWED < 120000
+    RefPtr<WebCore::Range> changeBlockSelection(const WebCore::IntPoint&, SelectionHandlePosition, float& growThreshold, float& shrinkThreshold, SelectionFlags&);
 #endif
+#endif
 
 #if PLATFORM(IOS) && ENABLE(DATA_INTERACTION)
     void requestStartDataInteraction(const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition);

Modified: branches/safari-605-branch/Source/WebKit/WebProcess/WebPage/WebPage.messages.in (227354 => 227355)


--- branches/safari-605-branch/Source/WebKit/WebProcess/WebPage/WebPage.messages.in	2018-01-22 21:32:58 UTC (rev 227354)
+++ branches/safari-605-branch/Source/WebKit/WebProcess/WebPage/WebPage.messages.in	2018-01-22 21:49:34 UTC (rev 227355)
@@ -57,6 +57,9 @@
     BlurAssistedNode()
     SelectWithGesture(WebCore::IntPoint point, uint32_t granularity, uint32_t gestureType, uint32_t gestureState, bool isInteractingWithAssistedNode, WebKit::CallbackID callbackID)
     UpdateSelectionWithTouches(WebCore::IntPoint point, uint32_t touches, bool baseIsStart, WebKit::CallbackID callbackID)
+#if __IPHONE_OS_VERSION_MAX_ALLOWED < 120000
+    UpdateBlockSelectionWithTouch(WebCore::IntPoint point, uint32_t touch, uint32_t handlePosition)
+#endif
     SelectWithTwoTouches(WebCore::IntPoint from, WebCore::IntPoint to, uint32_t gestureType, uint32_t gestureState, WebKit::CallbackID callbackID)
     ExtendSelection(uint32_t granularity)
     SelectWordBackward()

Modified: branches/safari-605-branch/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm (227354 => 227355)


--- branches/safari-605-branch/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm	2018-01-22 21:32:58 UTC (rev 227354)
+++ branches/safari-605-branch/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm	2018-01-22 21:49:34 UTC (rev 227355)
@@ -1055,6 +1055,364 @@
     return range->collapsed() ? nullptr : range;
 }
 
+#if __IPHONE_OS_VERSION_MAX_ALLOWED < 120000
+static bool canShrinkToTextSelection(Range& range)
+{
+    if (range.startContainer().isTextNode() && range.endContainer().isTextNode())
+        return true;
+    return canShrinkToTextSelection(range.commonAncestorContainer());
+}
+static const int maxHitTests = 10;
+
+static inline float distanceBetweenRectsForPosition(IntRect& first, IntRect& second, SelectionHandlePosition handlePosition)
+{
+    switch (handlePosition) {
+    case SelectionHandlePosition::Top:
+        return abs(first.y() - second.y());
+    case SelectionHandlePosition::Right:
+        return abs(first.maxX() - second.maxX());
+    case SelectionHandlePosition::Bottom:
+        return abs(first.maxY() - second.maxY());
+    case SelectionHandlePosition::Left:
+        return abs(first.x() - second.x());
+    }
+}
+
+static inline bool rectsEssentiallyTheSame(IntRect& first, IntRect& second, float allowablePercentDifference)
+{
+    const float minMagnitudeRatio = 1.0 - allowablePercentDifference;
+    const float maxDisplacementRatio = allowablePercentDifference;
+    
+    float xOriginShiftRatio = abs(first.x() - second.x()) / std::min(first.width(), second.width());
+    float yOriginShiftRatio = abs(first.y() - second.y()) / std::min(first.height(), second.height());
+    
+    float widthRatio = std::min(first.width() / second.width(), second.width() / first.width());
+    float heightRatio = std::min(first.height() / second.height(), second.height() / first.height());
+    return ((widthRatio > minMagnitudeRatio && xOriginShiftRatio < maxDisplacementRatio) && (heightRatio > minMagnitudeRatio && yOriginShiftRatio < maxDisplacementRatio));
+}
+
+static inline RefPtr<Range> unionDOMRanges(Range* rangeA, Range* rangeB)
+{
+    if (!rangeB)
+        return rangeA;
+    if (!rangeA)
+        return rangeB;
+    
+    auto startToStartComparison = rangeA->compareBoundaryPoints(Range::START_TO_START, *rangeB);
+    if (startToStartComparison.hasException())
+        return nullptr;
+    
+    auto endToEndComparison = rangeA->compareBoundaryPoints(Range::END_TO_END, *rangeB);
+    if (endToEndComparison.hasException())
+        return nullptr;
+    
+    auto* start = startToStartComparison.releaseReturnValue() <= 0 ? rangeA : rangeB;
+    auto* end = endToEndComparison.releaseReturnValue() <= 0 ? rangeB : rangeA;
+    
+    return Range::create(rangeA->ownerDocument(), &start->startContainer(), start->startOffset(), &end->endContainer(), end->endOffset());
+}
+
+static inline IntPoint computeEdgeCenter(const IntRect& box, SelectionHandlePosition handlePosition)
+{
+    switch (handlePosition) {
+    case SelectionHandlePosition::Top:
+        return IntPoint(box.x() + box.width() / 2, box.y());
+    case SelectionHandlePosition::Right:
+        return IntPoint(box.maxX(), box.y() + box.height() / 2);
+    case SelectionHandlePosition::Bottom:
+        return IntPoint(box.x() + box.width() / 2, box.maxY());
+    case SelectionHandlePosition::Left:
+        return IntPoint(box.x(), box.y() + box.height() / 2);
+    }
+}
+
+Ref<Range> WebPage::expandedRangeFromHandle(Range& currentRange, SelectionHandlePosition handlePosition)
+{
+    IntRect currentBox = selectionBoxForRange(&currentRange);
+    IntPoint edgeCenter = computeEdgeCenter(currentBox, handlePosition);
+    static const float maxDistance = 1000;
+    const float multiple = powf(maxDistance, 1.0 / (maxHitTests - 1));
+    float distance = 1;
+    
+    RefPtr<Range> bestRange;
+    IntRect bestRect;
+    
+    while (distance < maxDistance) {
+        if (bestRange) {
+            if (distanceBetweenRectsForPosition(bestRect, currentBox, handlePosition) < distance) {
+                // Break early, we're unlikely to do any better.
+                break;
+            }
+        }
+        
+        IntPoint testPoint = edgeCenter;
+        switch (handlePosition) {
+        case SelectionHandlePosition::Top:
+            testPoint.move(0, -distance);
+            break;
+        case SelectionHandlePosition::Right:
+            testPoint.move(distance, 0);
+            break;
+        case SelectionHandlePosition::Bottom:
+            testPoint.move(0, distance);
+            break;
+        case SelectionHandlePosition::Left:
+            testPoint.move(-distance, 0);
+            break;
+        }
+        
+        distance = ceilf(distance * multiple);
+        
+        RefPtr<Range> newRange;
+        RefPtr<Range> rangeAtPosition = rangeForBlockAtPoint(testPoint);
+        if (!rangeAtPosition || &currentRange.ownerDocument() != &rangeAtPosition->ownerDocument())
+            continue;
+        
+        if (rangeAtPosition->contains(currentRange))
+            newRange = rangeAtPosition;
+        else if (currentRange.contains(*rangeAtPosition.get()))
+            newRange = &currentRange;
+        else
+            newRange = unionDOMRanges(&currentRange, rangeAtPosition.get());
+        
+        IntRect copyRect = selectionBoxForRange(newRange.get());
+        
+        // Is it different and bigger than the current?
+        bool isBetterChoice = !(rectsEssentiallyTheSame(copyRect, currentBox, .05));
+        if (isBetterChoice) {
+            switch (handlePosition) {
+            case SelectionHandlePosition::Top:
+            case SelectionHandlePosition::Bottom:
+                isBetterChoice = (copyRect.height() > currentBox.height());
+                break;
+            case SelectionHandlePosition::Right:
+            case SelectionHandlePosition::Left:
+                isBetterChoice = (copyRect.width() > currentBox.width());
+                break;
+            }
+            
+        }
+        
+        if (bestRange && isBetterChoice) {
+            // Furtherore, is it smaller than the best we've found so far?
+            switch (handlePosition) {
+            case SelectionHandlePosition::Top:
+            case SelectionHandlePosition::Bottom:
+                isBetterChoice = (copyRect.height() < bestRect.height());
+                break;
+            case SelectionHandlePosition::Right:
+            case SelectionHandlePosition::Left:
+                isBetterChoice = (copyRect.width() < bestRect.width());
+                break;
+            }
+        }
+        
+        if (isBetterChoice) {
+            bestRange = newRange;
+            bestRect = copyRect;
+        }
+    }
+    
+    if (bestRange)
+        return bestRange.releaseNonNull();
+    
+    return currentRange;
+}
+
+Ref<Range> WebPage::contractedRangeFromHandle(Range& currentRange, SelectionHandlePosition handlePosition, SelectionFlags& flags)
+{
+    // Shrinking with a base and extent will always give better results. If we only have a single element,
+    // see if we can break that down to a base and extent. Shrinking base and extent is comparatively straightforward.
+    // Shrinking down to another element is unlikely to move just one edge, but we can try that as a fallback.
+    
+    IntRect currentBox = selectionBoxForRange(&currentRange);
+    IntPoint edgeCenter = computeEdgeCenter(currentBox, handlePosition);
+    
+    float maxDistance;
+    
+    switch (handlePosition) {
+    case SelectionHandlePosition::Top:
+    case SelectionHandlePosition::Bottom:
+        maxDistance = currentBox.height();
+        break;
+    case SelectionHandlePosition::Right:
+    case SelectionHandlePosition::Left:
+        maxDistance = currentBox.width();
+        break;
+    }
+    
+    const float multiple = powf(maxDistance - 1, 1.0 / (maxHitTests - 1));
+    float distance = 1;
+    RefPtr<Range> bestRange;
+    IntRect bestRect;
+    
+    while (distance < maxDistance) {
+        if (bestRange) {
+            float shrankDistance;
+            switch (handlePosition) {
+            case SelectionHandlePosition::Top:
+            case SelectionHandlePosition::Bottom:
+                shrankDistance = abs(currentBox.height() - bestRect.height());
+                break;
+            case SelectionHandlePosition::Right:
+            case SelectionHandlePosition::Left:
+                shrankDistance = abs(currentBox.width() - bestRect.width());
+                break;
+            }
+            if (shrankDistance > distance) {
+                // Certainly not going to do any better than that.
+                break;
+            }
+        }
+        
+        IntPoint testPoint = edgeCenter;
+        switch (handlePosition) {
+        case SelectionHandlePosition::Top:
+            testPoint.move(0, distance);
+            break;
+        case SelectionHandlePosition::Right:
+            testPoint.move(-distance, 0);
+            break;
+        case SelectionHandlePosition::Bottom:
+            testPoint.move(0, -distance);
+            break;
+        case SelectionHandlePosition::Left:
+            testPoint.move(distance, 0);
+            break;
+        }
+        
+        distance *= multiple;
+        
+        RefPtr<Range> newRange = rangeForBlockAtPoint(testPoint);
+        if (!newRange || &newRange->ownerDocument() != &currentRange.ownerDocument())
+            continue;
+        
+        if (handlePosition == SelectionHandlePosition::Top || handlePosition == SelectionHandlePosition::Left)
+            newRange = Range::create(newRange->startContainer().document(), newRange->endPosition(), currentRange.endPosition());
+        else
+            newRange = Range::create(newRange->startContainer().document(), currentRange.startPosition(), newRange->startPosition());
+        
+        IntRect copyRect = selectionBoxForRange(newRange.get());
+        if (copyRect.isEmpty()) {
+            // If the new range is an empty rectangle, we try the block at the current point
+            // and see if that has a rectangle that is a better choice.
+            newRange = rangeForBlockAtPoint(testPoint);
+            copyRect = selectionBoxForRange(newRange.get());
+        }
+        bool isBetterChoice;
+        switch (handlePosition) {
+        case SelectionHandlePosition::Top:
+        case SelectionHandlePosition::Bottom:
+            isBetterChoice = (copyRect.height() < currentBox.height());
+            if (copyRect.height() == currentBox.height())
+                isBetterChoice = canShrinkToTextSelection(*newRange.get());
+            break;
+        case SelectionHandlePosition::Left:
+        case SelectionHandlePosition::Right:
+            isBetterChoice = (copyRect.width() > bestRect.width());
+            break;
+        }
+        
+        isBetterChoice = isBetterChoice && !areRangesEqual(newRange.get(), &currentRange);
+        if (bestRange && isBetterChoice) {
+            switch (handlePosition) {
+            case SelectionHandlePosition::Top:
+            case SelectionHandlePosition::Bottom:
+                isBetterChoice = (copyRect.height() > bestRect.height());
+                break;
+            case SelectionHandlePosition::Left:
+            case SelectionHandlePosition::Right:
+                isBetterChoice = (copyRect.width() > bestRect.width());
+                break;
+            }
+        }
+        if (isBetterChoice) {
+            bestRange = newRange;
+            bestRect = copyRect;
+        }
+        
+    }
+    
+    if (!bestRange)
+        bestRange = &currentRange;
+    
+    // If we can shrink down to text only, the only reason we wouldn't is that
+    // there are multiple sub-element blocks beneath us. If we didn't find
+    // multiple sub-element blocks, don't shrink to a sub-element block.
+    
+    if (canShrinkToTextSelection(*bestRange.get()))
+        flags = None;
+    
+    return bestRange.releaseNonNull();
+}
+
+void WebPage::computeExpandAndShrinkThresholdsForHandle(const IntPoint& point, SelectionHandlePosition handlePosition, float& growThreshold, float& shrinkThreshold)
+{
+    Frame& frame = m_page->focusController().focusedOrMainFrame();
+    RefPtr<Range> currentRange = m_currentBlockSelection ? m_currentBlockSelection.get() : frame.selection().selection().toNormalizedRange();
+    
+    if (!currentRange)
+        return;
+    
+    Ref<Range> expandedRange = expandedRangeFromHandle(*currentRange, handlePosition);
+    SelectionFlags flags;
+    RefPtr<Range> contractedRange = contractedRangeFromHandle(*currentRange, handlePosition, flags);
+    
+    IntRect currentBounds = selectionBoxForRange(currentRange.get());
+    IntRect expandedBounds = selectionBoxForRange(expandedRange.ptr());
+    IntRect contractedBounds = selectionBoxForRange(contractedRange.get());
+    
+    float current;
+    float expanded;
+    float contracted;
+    float maxThreshold;
+    float minThreshold;
+    
+    switch (handlePosition) {
+    case SelectionHandlePosition::Top: {
+        current = currentBounds.y();
+        expanded = expandedBounds.y();
+        contracted = contractedBounds.y();
+        maxThreshold = FLT_MIN;
+        minThreshold = FLT_MAX;
+        break;
+    }
+    case SelectionHandlePosition::Right: {
+        current = currentBounds.maxX();
+        expanded = expandedBounds.maxX();
+        contracted = contractedBounds.maxX();
+        maxThreshold = FLT_MAX;
+        minThreshold = FLT_MIN;
+        break;
+    }
+    case SelectionHandlePosition::Bottom: {
+        current = currentBounds.maxY();
+        expanded = expandedBounds.maxY();
+        contracted = contractedBounds.maxY();
+        maxThreshold = FLT_MAX;
+        minThreshold = FLT_MIN;
+        break;
+    }
+    case SelectionHandlePosition::Left: {
+        current = currentBounds.x();
+        expanded = expandedBounds.x();
+        contracted = contractedBounds.x();
+        maxThreshold = FLT_MIN;
+        minThreshold = FLT_MAX;
+        break;
+    }
+    }
+    
+    static const float fractionToGrow = 0.3;
+    
+    growThreshold = current + (expanded - current) * fractionToGrow;
+    shrinkThreshold = current + (contracted - current) * (1 - fractionToGrow);
+    if (areRangesEqual(expandedRange.ptr(), currentRange.get()))
+        growThreshold = maxThreshold;
+    
+}
+#endif
+
 void WebPage::selectWithGesture(const IntPoint& point, uint32_t granularity, uint32_t gestureType, uint32_t gestureState, bool isInteractingWithAssistedNode, CallbackID callbackID)
 {
     auto& frame = m_page->focusController().focusedOrMainFrame();
@@ -1269,7 +1627,90 @@
 
     return (base < extent) ? Range::create(*frame->document(), base, extent) : Range::create(*frame->document(), extent, base);
 }
+    
+#if __IPHONE_OS_VERSION_MAX_ALLOWED < 120000
 
+RefPtr<Range> WebPage::rangeForBlockAtPoint(const IntPoint& point)
+{
+    HitTestResult result = m_page->mainFrame().eventHandler().hitTestResultAtPoint((point), HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowUserAgentShadowContent | HitTestRequest::IgnoreClipping);
+
+    Node* currentNode = result.innerNode();
+    RefPtr<Range> range;
+
+    if (currentNode->isTextNode()) {
+        range = enclosingTextUnitOfGranularity(m_page->focusController().focusedOrMainFrame().visiblePositionForPoint(point), ParagraphGranularity, DirectionForward);
+        if (range && !range->collapsed())
+            return range;
+    }
+
+    if (!currentNode->isElementNode())
+        currentNode = currentNode->parentElement();
+
+    if (!currentNode)
+        return nullptr;
+
+    range = Range::create(currentNode->document());
+    range->selectNodeContents(*currentNode);
+    return range;
+}
+    
+static inline bool shouldExpand(SelectionHandlePosition handlePosition, const IntRect& rect, const IntPoint& point)
+{
+    switch (handlePosition) {
+    case SelectionHandlePosition::Top:
+        return (point.y() < rect.y());
+    case SelectionHandlePosition::Left:
+        return (point.x() < rect.x());
+    case SelectionHandlePosition::Right:
+        return (point.x() > rect.maxX());
+    case SelectionHandlePosition::Bottom:
+        return (point.y() > rect.maxY());
+    }
+}
+
+RefPtr<WebCore::Range> WebPage::changeBlockSelection(const IntPoint& point, SelectionHandlePosition handlePosition, float& growThreshold, float& shrinkThreshold, SelectionFlags& flags)
+{
+    Frame& frame = m_page->focusController().focusedOrMainFrame();
+    RefPtr<Range> currentRange = m_currentBlockSelection ? m_currentBlockSelection.get() : frame.selection().selection().toNormalizedRange();
+    if (!currentRange)
+        return nullptr;
+    RefPtr<Range> newRange = shouldExpand(handlePosition, selectionBoxForRange(currentRange.get()), point) ? expandedRangeFromHandle(*currentRange, handlePosition) : contractedRangeFromHandle(*currentRange, handlePosition, flags);
+    
+    if (newRange) {
+        m_currentBlockSelection = newRange;
+        frame.selection().setSelectedRange(newRange.get(), VP_DEFAULT_AFFINITY, true, UserTriggered);
+    }
+    
+    computeExpandAndShrinkThresholdsForHandle(point, handlePosition, growThreshold, shrinkThreshold);
+    return newRange;
+}
+
+void WebPage::updateBlockSelectionWithTouch(const IntPoint& point, uint32_t touch, uint32_t handlePosition)
+{
+    Frame& frame = m_page->focusController().focusedOrMainFrame();
+    IntPoint adjustedPoint = frame.view()->rootViewToContents(point);
+    
+    float growThreshold = 0;
+    float shrinkThreshold = 0;
+    SelectionFlags flags = None;
+    
+    switch (static_cast<SelectionTouch>(touch)) {
+    case SelectionTouch::Started:
+        computeExpandAndShrinkThresholdsForHandle(adjustedPoint, static_cast<SelectionHandlePosition>(handlePosition), growThreshold, shrinkThreshold);
+        break;
+    case SelectionTouch::Ended:
+        break;
+    case SelectionTouch::Moved:
+        changeBlockSelection(adjustedPoint, static_cast<SelectionHandlePosition>(handlePosition), growThreshold, shrinkThreshold, flags);
+        break;
+    default:
+        return;
+    }
+    
+    send(Messages::WebPageProxy::DidUpdateBlockSelectionWithTouch(touch, static_cast<uint32_t>(flags), growThreshold, shrinkThreshold));
+}
+#endif
+
 void WebPage::clearSelection()
 {
     m_currentBlockSelection = nullptr;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to