Changeset 261457 in webkit


Ignore:
Timestamp:
May 10, 2020 12:28:11 PM (4 years ago)
Author:
timothy_horton@apple.com
Message:

Clicking a tel:// link on iPad with a trackpad presents different UI than tapping on it
https://bugs.webkit.org/show_bug.cgi?id=211686
<rdar://problem/57941589>

Reviewed by Wenson Hsieh.

Source/WebCore:

  • dom/MouseRelatedEvent.h:
  • editing/cocoa/DataDetection.h:
  • editing/cocoa/DataDetection.mm:

(WebCore::DataDetection::canPresentDataDetectorsUIForElement):
(WebCore::DataDetection::shouldCancelDefaultAction): Deleted.
Rename shouldCancelDefaultAction to canPresentDataDetectorsUIForElement.
This bit indicates whether a given element should invoke DD UI instead of
doing its default action, so either name is OK, but it feels better to
have it in the affirmative direction.

  • html/HTMLAnchorElement.cpp:

(WebCore::HTMLAnchorElement::handleClick):
Determine if tapping on an anchor should invoke DataDetectors UI instead
of performing the default action, and short-circuit if that is possible.

  • loader/EmptyClients.h:
  • page/ChromeClient.h:

Source/WebKit:

Previously, iOS WebKit had code in handleTap, handleTwoFingerTapAtPoint, and commitPotentialTap,
which introspected the hit element /before/ dispatching the tap (or synthetic click) to the DOM,
short circuiting all normal event handling machinery in order to prevent the default action
and present the Data Detectors UI for the given link.

There's one immediate problem with this, which is that there is no similar code in the direct
click event handler path, which we now use for trackpad/mouse input on iPad. There's also a
secondary problem (which we have not seen in practice), which is that pages cannot preventDefault
to avoid launching the Data Detectors UI on a link, like they could to prevent an ordinary
link from being followed.

In order to resolve both issues and reduce duplication of logic, move the code that introspects
the element and invokes Data Detectors UI from high-level WebKit event dispatch code (where it
doesn't really belong) down to WebCore's default click event handler for anchors, right next to
the code that would ordinarily cause a navigation. This way, no matter how we get here, whether
by synthetic click or real click, we'll invoke the Data Detectors UI.

One alternative considered at length: we could actually let the navigation happen, and instead
handle the switch in navigation policy code, but there are a few reasons that did not seem ideal:
1) We'd need to plumb platform-specific data structures through a ton of FrameLoader code.
2) Clients often block non-HTTP(S) navigations, so in order to keep the feature functional,

we'd have to disregard the client's policy decision, defeating much of the purpose of making
use of the navigation mechanism in the first place.

  • UIProcess/PageClient.h:
  • UIProcess/WebPageProxy.h:
  • UIProcess/WebPageProxy.messages.in:
  • UIProcess/ios/PageClientImplIOS.h:
  • UIProcess/ios/PageClientImplIOS.mm:

(WebKit::PageClientImpl::showDataDetectorsUIForPositionInformation):

  • UIProcess/ios/WebPageProxyIOS.mm:

(WebKit::WebPageProxy::showDataDetectorsUIForPositionInformation):

  • WebProcess/WebCoreSupport/WebChromeClient.h:
  • WebProcess/WebCoreSupport/ios/WebChromeClientIOS.mm:

(WebKit::WebChromeClient::showDataDetectorsUIForElement):
Plumb showDataDetectorsUIForPositionInformation from iOS WebKit's ChromeClient
implementation all the way to WKContentView.

  • UIProcess/ios/WKActionSheetAssistant.h:
  • UIProcess/ios/WKActionSheetAssistant.mm:

(-[WKActionSheetAssistant showDataDetectorsUIForPositionInformation:]):
(-[WKActionSheetAssistant contextMenuInteraction:configurationForMenuAtLocation:]):
(-[WKActionSheetAssistant contextMenuInteraction:previewForHighlightingMenuWithConfiguration:]):
(-[WKActionSheetAssistant showDataDetectorsSheet]): Deleted.
Make it possible to push InteractionInformationAtPosition into WKActionSheetAssistant,
instead of having it always pull a fresh one upon invocation, so that we can use the
position information passed along with the showDataDetectorsUIForPositionInformation message.

(-[WKActionSheetAssistant _contextMenuInteraction:overrideSuggestedActionsForConfiguration:]):
(-[WKActionSheetAssistant suggestedActionsForContextMenuWithPositionInformation:]):
Fix an existing bug where Data Detectors context menus would show extra default actions,
by moving our implementation of the -_contextMenuInteraction:overrideSuggestedActionsForConfiguration:
delegate here, sharing it with WKContentViewInteraction.

In a future patch, we should reconsider having three separate UIContextMenuInteractions.

Also, remove the contextMenuPresentationLocationForActionSheetAssistant: delegate,
since it will be wrong in the case of pushed-in position information, and instead
use the position information's original hit test point.

  • UIProcess/ios/WKContentViewInteraction.h:
  • UIProcess/ios/WKContentViewInteraction.mm:

(-[WKContentView _showDataDetectorsUI]):
(-[WKContentView _showDataDetectorsUIForPositionInformation:]):
(-[WKContentView _actionForLongPressFromPositionInformation:]):
(-[WKContentView _didNotHandleTapAsClick:]):
(-[WKContentView dataDetectionContextForPositionInformation:]):
(-[WKContentView dataDetectionContextForActionSheetAssistant:positionInformation:]):
(-[WKContentView _showDataDetectorsSheet]): Deleted.
(-[WKContentView currentPositionInformation]): Deleted.
(-[WKContentView dataDetectionContextForActionSheetAssistant:]): Deleted.
Instead of exposing an unnecessary -currentPositionInformation getter on WKActionSheetAssistant,
provide it as an argument to the WKActionSheetAssistantDelegate methods that actually need it.

(-[WKContentView contextMenuPresentationLocationForActionSheetAssistant:]): Deleted.
(-[WKContentView _contextMenuInteraction:overrideSuggestedActionsForConfiguration:]):
Adopt WKActionSheetAssistant's suggestedActions mechanism so we can share code.

  • UIProcess/ios/WKPDFView.mm:

(-[WKPDFView _showActionSheetForURL:atLocation:withAnnotationRect:]):
(-[WKPDFView dataDetectionContextForActionSheetAssistant:positionInformation:]):
(-[WKPDFView dataDetectionContextForActionSheetAssistant:]): Deleted.
Adapt to some WKActionSheetAssistantDelegate changes.

  • WebProcess/WebPage/WebPage.h:
  • WebProcess/WebPage/ios/WebPageIOS.mm:

(WebKit::WebPage::handleTap):
(WebKit::WebPage::handleTwoFingerTapAtPoint):
(WebKit::WebPage::commitPotentialTap):
Remove the aforementioned short-circuiting paths for Data Detectors links.

Source/WebKitLegacy/ios:

  • WebCoreSupport/WebChromeClientIOS.h:
Location:
trunk/Source
Files:
25 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r261453 r261457  
     12020-05-10  Tim Horton  <timothy_horton@apple.com>
     2
     3        Clicking a tel:// link on iPad with a trackpad presents different UI than tapping on it
     4        https://bugs.webkit.org/show_bug.cgi?id=211686
     5        <rdar://problem/57941589>
     6
     7        Reviewed by Wenson Hsieh.
     8
     9        * dom/MouseRelatedEvent.h:
     10        * editing/cocoa/DataDetection.h:
     11        * editing/cocoa/DataDetection.mm:
     12        (WebCore::DataDetection::canPresentDataDetectorsUIForElement):
     13        (WebCore::DataDetection::shouldCancelDefaultAction): Deleted.
     14        Rename shouldCancelDefaultAction to canPresentDataDetectorsUIForElement.
     15        This bit indicates whether a given element should invoke DD UI instead of
     16        doing its default action, so either name is OK, but it feels better to
     17        have it in the affirmative direction.
     18
     19        * html/HTMLAnchorElement.cpp:
     20        (WebCore::HTMLAnchorElement::handleClick):
     21        Determine if tapping on an anchor should invoke DataDetectors UI instead
     22        of performing the default action, and short-circuit if that is possible.
     23
     24        * loader/EmptyClients.h:
     25        * page/ChromeClient.h:
     26
    1272020-05-09  Wenson Hsieh  <wenson_hsieh@apple.com>
    228
  • trunk/Source/WebCore/dom/MouseRelatedEvent.h

    r250060 r261457  
    6262    int pageX() const final;
    6363    int pageY() const final;
    64     FloatPoint locationInRootViewCoordinates() const;
     64    WEBCORE_EXPORT FloatPoint locationInRootViewCoordinates() const;
    6565    virtual const LayoutPoint& pageLocation() const;
    6666    WEBCORE_EXPORT int x() const;
  • trunk/Source/WebCore/editing/cocoa/DataDetection.h

    r260753 r261457  
    6868    WEBCORE_EXPORT static bool isDataDetectorLink(Element&);
    6969    WEBCORE_EXPORT static String dataDetectorIdentifier(Element&);
    70     WEBCORE_EXPORT static bool shouldCancelDefaultAction(Element&);
     70    WEBCORE_EXPORT static bool canPresentDataDetectorsUIForElement(Element&);
    7171    WEBCORE_EXPORT static bool requiresExtendedContext(Element&);
    7272#endif
  • trunk/Source/WebCore/editing/cocoa/DataDetection.mm

    r261153 r261457  
    184184}
    185185
    186 bool DataDetection::shouldCancelDefaultAction(Element& element)
     186bool DataDetection::canPresentDataDetectorsUIForElement(Element& element)
    187187{
    188188    if (!isDataDetectorLink(element))
  • trunk/Source/WebCore/html/HTMLAnchorElement.cpp

    r261013 r261457  
    2626
    2727#include "AdClickAttribution.h"
     28#include "Chrome.h"
     29#include "ChromeClient.h"
    2830#include "DOMTokenList.h"
    2931#include "ElementIterator.h"
     
    5860#include <wtf/text/StringConcatenateNumbers.h>
    5961
     62#if PLATFORM(COCOA)
     63#include "DataDetection.h"
     64#endif
     65
    6066namespace WebCore {
    6167
     
    467473    URL completedURL = document().completeURL(url.toString());
    468474
     475#if ENABLE(DATA_DETECTION) && PLATFORM(IOS_FAMILY)
     476    if (DataDetection::isDataDetectorLink(*this) && DataDetection::canPresentDataDetectorsUIForElement(*this)) {
     477        if (auto* page = document().page()) {
     478            if (page->chrome().client().showDataDetectorsUIForElement(*this, event))
     479                return;
     480        }
     481    }
     482#endif
     483
    469484    String downloadAttribute;
    470485#if ENABLE(DOWNLOAD_ATTRIBUTE)
  • trunk/Source/WebCore/loader/EmptyClients.h

    r259330 r261457  
    179179    void removeScrollingLayer(Node*, PlatformLayer*, PlatformLayer*) final { }
    180180
    181     void webAppOrientationsUpdated() final { };
    182     void showPlaybackTargetPicker(bool, RouteSharingPolicy, const String&) final { };
     181    void webAppOrientationsUpdated() final { }
     182    void showPlaybackTargetPicker(bool, RouteSharingPolicy, const String&) final { }
     183
     184    bool showDataDetectorsUIForElement(const Element&, const Event&) final { return false; }
    183185#endif // PLATFORM(IOS_FAMILY)
    184186
  • trunk/Source/WebCore/page/ChromeClient.h

    r261398 r261457  
    273273    virtual void webAppOrientationsUpdated() = 0;
    274274    virtual void showPlaybackTargetPicker(bool hasVideo, RouteSharingPolicy, const String&) = 0;
     275
     276    virtual bool showDataDetectorsUIForElement(const Element&, const Event&) = 0;
    275277#endif
    276278
  • trunk/Source/WebKit/ChangeLog

    r261454 r261457  
     12020-05-10  Tim Horton  <timothy_horton@apple.com>
     2
     3        Clicking a tel:// link on iPad with a trackpad presents different UI than tapping on it
     4        https://bugs.webkit.org/show_bug.cgi?id=211686
     5        <rdar://problem/57941589>
     6
     7        Reviewed by Wenson Hsieh.
     8
     9        Previously, iOS WebKit had code in handleTap, handleTwoFingerTapAtPoint, and commitPotentialTap,
     10        which introspected the hit element /before/ dispatching the tap (or synthetic click) to the DOM,
     11        short circuiting all normal event handling machinery in order to prevent the default action
     12        and present the Data Detectors UI for the given link.
     13
     14        There's one immediate problem with this, which is that there is no similar code in the direct
     15        click event handler path, which we now use for trackpad/mouse input on iPad. There's also a
     16        secondary problem (which we have not seen in practice), which is that pages cannot preventDefault
     17        to avoid launching the Data Detectors UI on a link, like they could to prevent an ordinary
     18        link from being followed.
     19
     20        In order to resolve both issues and reduce duplication of logic, move the code that introspects
     21        the element and invokes Data Detectors UI from high-level WebKit event dispatch code (where it
     22        doesn't really belong) down to WebCore's default click event handler for anchors, right next to
     23        the code that would ordinarily cause a navigation. This way, no matter how we get here, whether
     24        by synthetic click or real click, we'll invoke the Data Detectors UI.
     25
     26        One alternative considered at length: we could actually let the navigation happen, and instead
     27        handle the switch in navigation policy code, but there are a few reasons that did not seem ideal:
     28        1) We'd need to plumb platform-specific data structures through a ton of FrameLoader code.
     29        2) Clients often block non-HTTP(S) navigations, so in order to keep the feature functional,
     30           we'd have to disregard the client's policy decision, defeating much of the purpose of making
     31           use of the navigation mechanism in the first place.
     32
     33        * UIProcess/PageClient.h:
     34        * UIProcess/WebPageProxy.h:
     35        * UIProcess/WebPageProxy.messages.in:
     36        * UIProcess/ios/PageClientImplIOS.h:
     37        * UIProcess/ios/PageClientImplIOS.mm:
     38        (WebKit::PageClientImpl::showDataDetectorsUIForPositionInformation):
     39        * UIProcess/ios/WebPageProxyIOS.mm:
     40        (WebKit::WebPageProxy::showDataDetectorsUIForPositionInformation):
     41        * WebProcess/WebCoreSupport/WebChromeClient.h:
     42        * WebProcess/WebCoreSupport/ios/WebChromeClientIOS.mm:
     43        (WebKit::WebChromeClient::showDataDetectorsUIForElement):
     44        Plumb showDataDetectorsUIForPositionInformation from iOS WebKit's ChromeClient
     45        implementation all the way to WKContentView.
     46
     47        * UIProcess/ios/WKActionSheetAssistant.h:
     48        * UIProcess/ios/WKActionSheetAssistant.mm:
     49        (-[WKActionSheetAssistant showDataDetectorsUIForPositionInformation:]):
     50        (-[WKActionSheetAssistant contextMenuInteraction:configurationForMenuAtLocation:]):
     51        (-[WKActionSheetAssistant contextMenuInteraction:previewForHighlightingMenuWithConfiguration:]):
     52        (-[WKActionSheetAssistant showDataDetectorsSheet]): Deleted.
     53        Make it possible to push InteractionInformationAtPosition into WKActionSheetAssistant,
     54        instead of having it always pull a fresh one upon invocation, so that we can use the
     55        position information passed along with the showDataDetectorsUIForPositionInformation message.
     56
     57        (-[WKActionSheetAssistant _contextMenuInteraction:overrideSuggestedActionsForConfiguration:]):
     58        (-[WKActionSheetAssistant suggestedActionsForContextMenuWithPositionInformation:]):
     59        Fix an existing bug where Data Detectors context menus would show extra default actions,
     60        by moving our implementation of the -_contextMenuInteraction:overrideSuggestedActionsForConfiguration:
     61        delegate here, sharing it with WKContentViewInteraction.
     62
     63        In a future patch, we should reconsider having three separate UIContextMenuInteractions.
     64
     65        Also, remove the contextMenuPresentationLocationForActionSheetAssistant: delegate,
     66        since it will be wrong in the case of pushed-in position information, and instead
     67        use the position information's original hit test point.
     68
     69        * UIProcess/ios/WKContentViewInteraction.h:
     70        * UIProcess/ios/WKContentViewInteraction.mm:
     71        (-[WKContentView _showDataDetectorsUI]):
     72        (-[WKContentView _showDataDetectorsUIForPositionInformation:]):
     73        (-[WKContentView _actionForLongPressFromPositionInformation:]):
     74        (-[WKContentView _didNotHandleTapAsClick:]):
     75        (-[WKContentView dataDetectionContextForPositionInformation:]):
     76        (-[WKContentView dataDetectionContextForActionSheetAssistant:positionInformation:]):
     77        (-[WKContentView _showDataDetectorsSheet]): Deleted.
     78        (-[WKContentView currentPositionInformation]): Deleted.
     79        (-[WKContentView dataDetectionContextForActionSheetAssistant:]): Deleted.
     80        Instead of exposing an unnecessary -currentPositionInformation getter on WKActionSheetAssistant,
     81        provide it as an argument to the WKActionSheetAssistantDelegate methods that actually need it.
     82
     83        (-[WKContentView contextMenuPresentationLocationForActionSheetAssistant:]): Deleted.
     84        (-[WKContentView _contextMenuInteraction:overrideSuggestedActionsForConfiguration:]):
     85        Adopt WKActionSheetAssistant's suggestedActions mechanism so we can share code.
     86
     87        * UIProcess/ios/WKPDFView.mm:
     88        (-[WKPDFView _showActionSheetForURL:atLocation:withAnnotationRect:]):
     89        (-[WKPDFView dataDetectionContextForActionSheetAssistant:positionInformation:]):
     90        (-[WKPDFView dataDetectionContextForActionSheetAssistant:]): Deleted.
     91        Adapt to some WKActionSheetAssistantDelegate changes.
     92
     93        * WebProcess/WebPage/WebPage.h:
     94        * WebProcess/WebPage/ios/WebPageIOS.mm:
     95        (WebKit::WebPage::handleTap):
     96        (WebKit::WebPage::handleTwoFingerTapAtPoint):
     97        (WebKit::WebPage::commitPotentialTap):
     98        Remove the aforementioned short-circuiting paths for Data Detectors links.
    1992020-05-09  David Kilzer  <ddkilzer@apple.com>
    2100
  • trunk/Source/WebKit/UIProcess/PageClient.h

    r261320 r261457  
    413413    virtual void saveImageToLibrary(Ref<WebCore::SharedBuffer>&&) = 0;
    414414    virtual void showPlaybackTargetPicker(bool hasVideo, const WebCore::IntRect& elementRect, WebCore::RouteSharingPolicy, const String&) = 0;
     415    virtual void showDataDetectorsUIForPositionInformation(const InteractionInformationAtPosition&) = 0;
    415416    virtual void disableDoubleTapGesturesDuringTapIfNecessary(uint64_t requestID) = 0;
    416417    virtual void handleSmartMagnificationInformationForPotentialTap(uint64_t requestID, const WebCore::FloatRect& renderRect, bool fitEntireRect, double viewportMinimumScale, double viewportMaximumScale, bool nodeIsRootLevel) = 0;
  • trunk/Source/WebKit/UIProcess/WebPageProxy.h

    r261407 r261457  
    820820    void requestDocumentEditingContext(WebKit::DocumentEditingContextRequest, CompletionHandler<void(WebKit::DocumentEditingContext)>&&);
    821821    void generateSyntheticEditingCommand(SyntheticEditingCommandType);
     822    void showDataDetectorsUIForPositionInformation(const InteractionInformationAtPosition&);
    822823#if ENABLE(DRAG_SUPPORT)
    823824    void didHandleDragStartRequest(bool started);
  • trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in

    r261203 r261457  
    427427    UpdateStringForFind(String findString)
    428428    HandleAutocorrectionContext(struct WebKit::WebAutocorrectionContext context)
     429
     430    ShowDataDetectorsUIForPositionInformation(struct WebKit::InteractionInformationAtPosition information)
    429431#endif
    430432
  • trunk/Source/WebKit/UIProcess/ios/PageClientImplIOS.h

    r261232 r261457  
    169169    void saveImageToLibrary(Ref<WebCore::SharedBuffer>&&) override;
    170170    void showPlaybackTargetPicker(bool hasVideo, const WebCore::IntRect& elementRect, WebCore::RouteSharingPolicy, const String&) override;
     171    void showDataDetectorsUIForPositionInformation(const InteractionInformationAtPosition&) override;
    171172
    172173    bool handleRunOpenPanel(WebPageProxy*, WebFrameProxy*, const FrameInfoData&, API::OpenPanelParameters*, WebOpenPanelResultListenerProxy*) override;
  • trunk/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm

    r261320 r261457  
    948948}
    949949
     950void PageClientImpl::showDataDetectorsUIForPositionInformation(const InteractionInformationAtPosition& positionInformation)
     951{
     952    [m_contentView _showDataDetectorsUIForPositionInformation:positionInformation];
     953}
     954
    950955} // namespace WebKit
    951956
  • trunk/Source/WebKit/UIProcess/ios/WKActionSheetAssistant.h

    r261303 r261457  
    3737}
    3838
     39@class UIMenuElement;
    3940@class UITargetedPreview;
    4041@class WKActionSheetAssistant;
     
    6162- (void)actionSheetAssistant:(WKActionSheetAssistant *)assistant willStartInteractionWithElement:(_WKActivatedElementInfo *)element;
    6263- (void)actionSheetAssistantDidStopInteraction:(WKActionSheetAssistant *)assistant;
    63 - (NSDictionary *)dataDetectionContextForActionSheetAssistant:(WKActionSheetAssistant *)assistant;
     64- (NSDictionary *)dataDetectionContextForActionSheetAssistant:(WKActionSheetAssistant *)assistant positionInformation:(const WebKit::InteractionInformationAtPosition&)positionInformation;
    6465- (NSString *)selectedTextForActionSheetAssistant:(WKActionSheetAssistant *)assistant;
    6566- (void)actionSheetAssistant:(WKActionSheetAssistant *)assistant getAlternateURLForImage:(UIImage *)image completion:(void (^)(NSURL *alternateURL, NSDictionary *userInfo))completion;
    66 - (CGPoint)contextMenuPresentationLocationForActionSheetAssistant:(WKActionSheetAssistant *)assistant;
    6767#if USE(UICONTEXTMENU)
    6868- (UITargetedPreview *)createTargetedContextMenuHintForActionSheetAssistant:(WKActionSheetAssistant *)assistant;
     
    8383- (void)showLinkSheet;
    8484- (void)showImageSheet;
    85 - (void)showDataDetectorsSheet;
     85- (void)showDataDetectorsUIForPositionInformation:(const WebKit::InteractionInformationAtPosition&)positionInformation;
    8686- (void)cleanupSheet;
    8787- (void)updateSheetPosition;
     
    9191- (void)interactionDidStartWithPositionInformation:(const WebKit::InteractionInformationAtPosition&)information;
    9292- (NSArray *)currentAvailableActionTitles;
    93 - (Optional<WebKit::InteractionInformationAtPosition>)currentPositionInformation;
     93- (NSArray<UIMenuElement *> *)suggestedActionsForContextMenuWithPositionInformation:(const WebKit::InteractionInformationAtPosition&)positionInformation;
    9494@end
    9595
  • trunk/Source/WebKit/UIProcess/ios/WKActionSheetAssistant.mm

    r261303 r261457  
    661661#endif
    662662
    663 - (void)showDataDetectorsSheet
     663- (void)showDataDetectorsUIForPositionInformation:(const WebKit::InteractionInformationAtPosition&)positionInformation
    664664{
    665665#if ENABLE(DATA_DETECTION)
     
    667667        return;
    668668
    669     if (![self synchronouslyRetrievePositionInformation])
    670         return;
     669    _positionInformation = positionInformation;
    671670
    672671    if (!WebCore::DataDetection::canBePresentedByDataDetectors(_positionInformation->url))
     
    681680    NSString *textAtSelection = nil;
    682681
    683     if ([_delegate respondsToSelector:@selector(dataDetectionContextForActionSheetAssistant:)])
    684         context = [_delegate dataDetectionContextForActionSheetAssistant:self];
     682    if ([_delegate respondsToSelector:@selector(dataDetectionContextForActionSheetAssistant:positionInformation:)])
     683        context = [_delegate dataDetectionContextForActionSheetAssistant:self positionInformation:*_positionInformation];
    685684    if ([_delegate respondsToSelector:@selector(selectedTextForActionSheetAssistant:)])
    686685        textAtSelection = [_delegate selectedTextForActionSheetAssistant:self];
     
    697696        return;
    698697   
    699 #if ENABLE(DATA_DETECTION) && USE(UICONTEXTMENU) && HAVE(UICONTEXTMENU_LOCATION)
    700     auto delegate = _delegate.get();
    701     if ([delegate respondsToSelector:@selector(contextMenuPresentationLocationForActionSheetAssistant:)]) {
    702         [self ensureContextMenuInteraction];
    703         [_dataDetectorContextMenuInteraction _presentMenuAtLocation:[delegate contextMenuPresentationLocationForActionSheetAssistant:self]];
    704         return;
    705     }
    706 #endif
    707 
     698#if USE(UICONTEXTMENU) && HAVE(UICONTEXTMENU_LOCATION)
     699    [self ensureContextMenuInteraction];
     700    [_dataDetectorContextMenuInteraction _presentMenuAtLocation:_positionInformation->request.point];
     701#else
    708702    NSMutableArray *elementActions = [NSMutableArray array];
    709703    for (NSUInteger actionNumber = 0; actionNumber < [dataDetectorsActions count]; actionNumber++) {
     
    724718        [self cleanupSheet];
    725719#endif
     720#endif // ENABLE(DATA_DETECTION)
    726721}
    727722
     
    733728    NSString *textAtSelection = nil;
    734729
    735     if ([_delegate respondsToSelector:@selector(dataDetectionContextForActionSheetAssistant:)])
    736         context = [_delegate dataDetectionContextForActionSheetAssistant:self];
     730    if ([_delegate respondsToSelector:@selector(dataDetectionContextForActionSheetAssistant:positionInformation:)])
     731        context = [_delegate dataDetectionContextForActionSheetAssistant:self positionInformation:*_positionInformation];
    737732    if ([_delegate respondsToSelector:@selector(selectedTextForActionSheetAssistant:)])
    738733        textAtSelection = [_delegate selectedTextForActionSheetAssistant:self];
     
    740735    NSDictionary *newContext = nil;
    741736    DDResultRef ddResult = [controller resultForURL:_positionInformation->url identifier:_positionInformation->dataDetectorIdentifier selectedText:textAtSelection results:_positionInformation->dataDetectorResults.get() context:context extendedContext:&newContext];
    742 
    743737
    744738    CGRect sourceRect;
     
    759753{
    760754    auto delegate = _delegate.get();
    761     CGPoint center = CGPointZero;
     755    CGPoint center = _positionInformation->request.point;
    762756   
    763757    if ([delegate respondsToSelector:@selector(createTargetedContextMenuHintForActionSheetAssistant:)])
    764758        return [delegate createTargetedContextMenuHintForActionSheetAssistant:self];
    765759   
    766     if ([delegate respondsToSelector:@selector(contextMenuPresentationLocationForActionSheetAssistant:)])
    767         center = [delegate contextMenuPresentationLocationForActionSheetAssistant:self];
    768760    RetainPtr<UIPreviewParameters> unusedPreviewParameters = adoptNS([[UIPreviewParameters alloc] init]);
    769761    RetainPtr<UIPreviewTarget> previewTarget = adoptNS([[UIPreviewTarget alloc] initWithContainer:_view.getAutoreleased() center:center]);
     
    785777    }];
    786778}
     779
     780static NSArray<UIMenuElement *> *menuElementsFromDefaultActions(RetainPtr<NSArray> defaultElementActions, RetainPtr<_WKActivatedElementInfo> elementInfo)
     781{
     782    if (![defaultElementActions count])
     783        return nil;
     784
     785    auto actions = [NSMutableArray arrayWithCapacity:[defaultElementActions count]];
     786    for (_WKElementAction *elementAction in defaultElementActions.get())
     787        [actions addObject:[elementAction uiActionForElementInfo:elementInfo.get()]];
     788
     789    return actions;
     790}
     791
     792- (NSArray<UIMenuElement *> *)_contextMenuInteraction:(UIContextMenuInteraction *)interaction overrideSuggestedActionsForConfiguration:(UIContextMenuConfiguration *)configuration
     793{
     794    if (!_positionInformation)
     795        return nil;
     796    return [self suggestedActionsForContextMenuWithPositionInformation:*_positionInformation];
     797}
     798
     799- (NSArray<UIMenuElement *> *)suggestedActionsForContextMenuWithPositionInformation:(const WebKit::InteractionInformationAtPosition&)positionInformation
     800{
     801    auto elementInfo = adoptNS([[_WKActivatedElementInfo alloc] _initWithInteractionInformationAtPosition:positionInformation userInfo:nil]);
     802    RetainPtr<NSArray<_WKElementAction *>> defaultActionsFromAssistant = positionInformation.isLink ? [self defaultActionsForLinkSheet:elementInfo.get()] : [self defaultActionsForImageSheet:elementInfo.get()];
     803    return menuElementsFromDefaultActions(defaultActionsFromAssistant, elementInfo);
     804
     805}
     806
    787807#endif
    788808
  • trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h

    r261303 r261457  
    531531- (WKFormInputSession *)_formInputSession;
    532532- (void)_didChangeWebViewEditability;
    533 - (NSDictionary *)dataDetectionContextForPositionInformation:(WebKit::InteractionInformationAtPosition)positionInformation;
     533- (NSDictionary *)dataDetectionContextForPositionInformation:(const WebKit::InteractionInformationAtPosition&)positionInformation;
     534- (void)_showDataDetectorsUIForPositionInformation:(const WebKit::InteractionInformationAtPosition&)positionInformation;
    534535
    535536- (void)willFinishIgnoringCalloutBarFadeAfterPerformingAction;
     
    550551- (void)_requestDOMPasteAccessWithElementRect:(const WebCore::IntRect&)elementRect originIdentifier:(const String&)originIdentifier completionHandler:(CompletionHandler<void(WebCore::DOMPasteAccessResponse)>&&)completionHandler;
    551552
    552 @property (nonatomic, readonly) WebKit::InteractionInformationAtPosition currentPositionInformation;
    553553- (void)doAfterPositionInformationUpdate:(void (^)(WebKit::InteractionInformationAtPosition))action forRequest:(WebKit::InteractionInformationRequest)request;
    554554- (BOOL)ensurePositionInformationIsUpToDate:(WebKit::InteractionInformationRequest)request;
  • trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm

    r261361 r261457  
    21492149}
    21502150
    2151 - (void)_showDataDetectorsSheet
    2152 {
    2153     [_actionSheetAssistant showDataDetectorsSheet];
     2151- (void)_showDataDetectorsUI
     2152{
     2153    [self _showDataDetectorsUIForPositionInformation:_positionInformation];
     2154}
     2155
     2156- (void)_showDataDetectorsUIForPositionInformation:(const WebKit::InteractionInformationAtPosition&)positionInformation
     2157{
     2158    [_actionSheetAssistant showDataDetectorsUIForPositionInformation:positionInformation];
    21542159}
    21552160
     
    21682173#if ENABLE(DATA_DETECTION)
    21692174        if (WebCore::DataDetection::canBePresentedByDataDetectors(positionInformation.url))
    2170             return @selector(_showDataDetectorsSheet);
     2175            return @selector(_showDataDetectorsUI);
    21712176#endif
    21722177        return @selector(_showLinkSheet);
     
    21812186{
    21822187    return [self _actionForLongPressFromPositionInformation:_positionInformation];
    2183 }
    2184 
    2185 - (WebKit::InteractionInformationAtPosition)currentPositionInformation
    2186 {
    2187     return _positionInformation;
    21882188}
    21892189
     
    27232723{
    27242724    [self _resetInputViewDeferral];
    2725 
    2726     // FIXME: we should also take into account whether or not the UI delegate
    2727     // has handled this notification.
    2728 #if ENABLE(DATA_DETECTION)
    2729     if (_hasValidPositionInformation && point == _positionInformation.request.point && _positionInformation.isDataDetectorLink) {
    2730         [self _showDataDetectorsSheet];
    2731         return;
    2732     }
    2733 #endif
    27342725
    27352726    if (!_isDoubleTapPending)
     
    69056896}
    69066897
    6907 - (NSDictionary *)dataDetectionContextForPositionInformation:(WebKit::InteractionInformationAtPosition)positionInformation
     6898- (NSDictionary *)dataDetectionContextForPositionInformation:(const WebKit::InteractionInformationAtPosition&)positionInformation
    69086899{
    69096900    RetainPtr<NSMutableDictionary> context;
     
    69346925}
    69356926
    6936 - (NSDictionary *)dataDetectionContextForActionSheetAssistant:(WKActionSheetAssistant *)assistant
    6937 {
    6938     return [self dataDetectionContextForPositionInformation:assistant.currentPositionInformation.valueOr(_positionInformation)];
     6927- (NSDictionary *)dataDetectionContextForActionSheetAssistant:(WKActionSheetAssistant *)assistant positionInformation:(const WebKit::InteractionInformationAtPosition&)positionInformation
     6928{
     6929    return [self dataDetectionContextForPositionInformation:positionInformation];
    69396930}
    69406931
     
    69536944    } else
    69546945        completion(nil, nil);
    6955 }
    6956 
    6957 - (CGPoint)contextMenuPresentationLocationForActionSheetAssistant:(WKActionSheetAssistant *)assistant
    6958 {
    6959     return [self lastInteractionLocation];
    69606946}
    69616947
     
    92129198- (NSArray<UIMenuElement *> *)_contextMenuInteraction:(UIContextMenuInteraction *)interaction overrideSuggestedActionsForConfiguration:(UIContextMenuConfiguration *)configuration
    92139199{
    9214     if (_contextMenuActionProviderDelegateNeedsOverride) {
    9215         auto elementInfo = adoptNS([[_WKActivatedElementInfo alloc] _initWithInteractionInformationAtPosition:_positionInformation userInfo:nil]);
    9216         RetainPtr<NSArray<_WKElementAction *>> defaultActionsFromAssistant = _positionInformation.isLink ? [_actionSheetAssistant defaultActionsForLinkSheet:elementInfo.get()] : [_actionSheetAssistant defaultActionsForImageSheet:elementInfo.get()];
    9217         return menuElementsFromDefaultActions(defaultActionsFromAssistant, elementInfo);
    9218     }
    92199200    // If we're here we're in the legacy path, which ignores the suggested actions anyway.
    9220     return nil;
     9201    if (!_contextMenuActionProviderDelegateNeedsOverride)
     9202        return nil;
     9203
     9204    return [_actionSheetAssistant suggestedActionsForContextMenuWithPositionInformation:_positionInformation];
    92219205}
    92229206
  • trunk/Source/WebKit/UIProcess/ios/WKPDFView.mm

    r261168 r261457  
    486486
    487487    _positionInformation = WTFMove(positionInformation);
     488
    488489#if ENABLE(DATA_DETECTION)
    489     if (WebCore::DataDetection::canBePresentedByDataDetectors(_positionInformation.url))
    490         [_actionSheetAssistant showDataDetectorsSheet];
    491     else
     490    if (WebCore::DataDetection::canBePresentedByDataDetectors(_positionInformation.url)) {
     491        [_actionSheetAssistant showDataDetectorsUIForPositionInformation:positionInformation];
     492        return;
     493    }
    492494#endif
    493         [_actionSheetAssistant showLinkSheet];
     495
     496    [_actionSheetAssistant showLinkSheet];
    494497}
    495498
     
    583586}
    584587
    585 - (NSDictionary *)dataDetectionContextForActionSheetAssistant:(WKActionSheetAssistant *)assistant
     588- (NSDictionary *)dataDetectionContextForActionSheetAssistant:(WKActionSheetAssistant *)assistant positionInformation:(const WebKit::InteractionInformationAtPosition&)positionInformation
    586589{
    587590    auto webView = _webView.getAutoreleased();
  • trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm

    r261299 r261457  
    16221622}
    16231623
     1624void WebPageProxy::showDataDetectorsUIForPositionInformation(const InteractionInformationAtPosition& positionInfo)
     1625{
     1626    pageClient().showDataDetectorsUIForPositionInformation(positionInfo);
     1627}
     1628
     1629
    16241630} // namespace WebKit
    16251631
  • trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h

    r261398 r261457  
    186186
    187187    bool shouldUseMouseEventForSelection(const WebCore::PlatformMouseEvent&) final;
     188
     189    bool showDataDetectorsUIForElement(const WebCore::Element&, const WebCore::Event&) final;
    188190#endif
    189191
  • trunk/Source/WebKit/WebProcess/WebCoreSupport/ios/WebChromeClientIOS.mm

    r260820 r261457  
    3131#import "DrawingArea.h"
    3232#import "EditableImageControllerMessages.h"
     33#import "InteractionInformationAtPosition.h"
     34#import "InteractionInformationRequest.h"
    3335#import "UIKitSPI.h"
    3436#import "WebCoreArgumentCoders.h"
     
    4042#import <WebCore/ContentChangeObserver.h>
    4143#import <WebCore/Icon.h>
     44#import <WebCore/MouseEvent.h>
    4245#import <WebCore/NotImplemented.h>
    4346#import <WebCore/PlatformMouseEvent.h>
     
    194197}
    195198
     199bool WebChromeClient::showDataDetectorsUIForElement(const Element& element, const Event& event)
     200{
     201    if (!event.isMouseEvent())
     202        return false;
     203
     204    // FIXME: Ideally, we would be able to generate InteractionInformationAtPosition without re-hit-testing the element.
     205    auto& mouseEvent = downcast<MouseEvent>(event);
     206    auto positionInformation = m_page.positionInformation(InteractionInformationRequest { roundedIntPoint(mouseEvent.locationInRootViewCoordinates()) });
     207    m_page.send(Messages::WebPageProxy::ShowDataDetectorsUIForPositionInformation(positionInformation));
     208    return true;
     209}
     210
    196211} // namespace WebKit
    197212
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.h

    r261398 r261457  
    12931293    static WebCore::IntRect absoluteInteractionBoundsForElement(const WebCore::Element&);
    12941294    static WebCore::IntRect rootViewInteractionBoundsForElement(const WebCore::Element&);
     1295
     1296    InteractionInformationAtPosition positionInformation(const InteractionInformationRequest&);
     1297   
    12951298#endif // PLATFORM(IOS_FAMILY)
    12961299
     
    13691372
    13701373    void sendPositionInformation(InteractionInformationAtPosition&&);
    1371     InteractionInformationAtPosition positionInformation(const InteractionInformationRequest&);
    13721374    RefPtr<ShareableBitmap> shareableBitmapSnapshotForNode(WebCore::Element&);
    13731375    WebAutocorrectionContext autocorrectionContext();
  • trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm

    r261398 r261457  
    870870    if (!frameRespondingToClick || lastLayerTreeTransactionId < WebFrame::fromCoreFrame(*frameRespondingToClick)->firstLayerTreeTransactionIDAfterDidCommitLoad())
    871871        send(Messages::WebPageProxy::DidNotHandleTapAsClick(adjustedIntPoint));
    872 #if ENABLE(DATA_DETECTION)
    873     else if (is<Element>(*nodeRespondingToClick) && DataDetection::shouldCancelDefaultAction(downcast<Element>(*nodeRespondingToClick))) {
    874         InteractionInformationRequest request(adjustedIntPoint);
    875         requestPositionInformation(request);
    876         send(Messages::WebPageProxy::DidNotHandleTapAsClick(adjustedIntPoint));
    877     }
    878 #endif
    879872    else
    880873        handleSyntheticClick(*nodeRespondingToClick, adjustedPoint, modifiers);
     
    10781071    }
    10791072    sendTapHighlightForNodeIfNecessary(requestID, nodeRespondingToClick);
    1080 #if ENABLE(DATA_DETECTION)
    1081     if (is<Element>(*nodeRespondingToClick) && DataDetection::shouldCancelDefaultAction(downcast<Element>(*nodeRespondingToClick))) {
    1082         InteractionInformationRequest request(roundedIntPoint(adjustedPoint));
    1083         requestPositionInformation(request);
    1084         send(Messages::WebPageProxy::DidNotHandleTapAsClick(roundedIntPoint(adjustedPoint)));
    1085     } else
    1086 #endif
    1087         completeSyntheticClick(*nodeRespondingToClick, adjustedPoint, modifiers, WebCore::TwoFingerTap);
     1073    completeSyntheticClick(*nodeRespondingToClick, adjustedPoint, modifiers, WebCore::TwoFingerTap);
    10881074}
    10891075
     
    11691155    }
    11701156
    1171     if (m_potentialTapNode == nodeRespondingToClick) {
    1172 #if ENABLE(DATA_DETECTION)
    1173         if (is<Element>(*nodeRespondingToClick) && DataDetection::shouldCancelDefaultAction(downcast<Element>(*nodeRespondingToClick))) {
    1174             InteractionInformationRequest request(roundedIntPoint(m_potentialTapLocation));
    1175             requestPositionInformation(request);
    1176             commitPotentialTapFailed();
    1177         } else
    1178 #endif
    1179             handleSyntheticClick(*nodeRespondingToClick, adjustedPoint, modifiers, pointerId);
    1180     } else
     1157    if (m_potentialTapNode == nodeRespondingToClick)
     1158        handleSyntheticClick(*nodeRespondingToClick, adjustedPoint, modifiers, pointerId);
     1159    else
    11811160        commitPotentialTapFailed();
    11821161
  • trunk/Source/WebKitLegacy/ios/ChangeLog

    r260725 r261457  
     12020-05-10  Tim Horton  <timothy_horton@apple.com>
     2
     3        Clicking a tel:// link on iPad with a trackpad presents different UI than tapping on it
     4        https://bugs.webkit.org/show_bug.cgi?id=211686
     5        <rdar://problem/57941589>
     6
     7        Reviewed by Wenson Hsieh.
     8
     9        * WebCoreSupport/WebChromeClientIOS.h:
     10
    1112020-04-11  Darin Adler  <darin@apple.com>
    212
  • trunk/Source/WebKitLegacy/ios/WebCoreSupport/WebChromeClientIOS.h

    r253636 r261457  
    9898    RefPtr<WebCore::Icon> createIconForFiles(const Vector<String>& filenames) final;
    9999
     100    bool showDataDetectorsUIForElement(const WebCore::Element&, const WebCore::Event&) final { return false; }
     101
    100102#if ENABLE(ORIENTATION_EVENTS)
    101103    int deviceOrientation() const final;
Note: See TracChangeset for help on using the changeset viewer.