Implement immediate action support for tel: and mailto: URLs
authortimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 20 Apr 2015 18:46:33 +0000 (18:46 +0000)
committertimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 20 Apr 2015 18:46:33 +0000 (18:46 +0000)
https://bugs.webkit.org/show_bug.cgi?id=143916
<rdar://problem/19721711>

Reviewed by Darin Adler.

* Shared/API/c/WKImmediateActionTypes.h:
* UIProcess/mac/WKImmediateActionController.mm:
(-[WKImmediateActionController _defaultAnimationController]):
(-[WKImmediateActionController _animationControllerForDataDetectedText]):
(-[WKImmediateActionController _animationControllerForDataDetectedLink]):
(-[WKImmediateActionController _menuItemForDataDetectedText]): Deleted.
Add _animationControllerForDataDetectedLink and use it when
building immediate actions for tel: and mailto: links.

* WebView/WebImmediateActionController.mm:
(-[WebImmediateActionController _defaultAnimationController]):
(-[WebImmediateActionController _animationControllerForDataDetectedText]):
(-[WebImmediateActionController _animationControllerForDataDetectedLink]):
(-[WebImmediateActionController _menuItemForDataDetectedText]): Deleted.
* WebView/WebUIDelegatePrivate.h:
Add _animationControllerForDataDetectedLink and use it when
building immediate actions for tel: and mailto: links.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@183019 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit/mac/ChangeLog
Source/WebKit/mac/WebView/WebImmediateActionController.mm
Source/WebKit/mac/WebView/WebUIDelegatePrivate.h
Source/WebKit2/ChangeLog
Source/WebKit2/Shared/API/c/WKImmediateActionTypes.h
Source/WebKit2/UIProcess/mac/WKImmediateActionController.mm

index a130596..250192a 100644 (file)
@@ -1,3 +1,20 @@
+2015-04-20  Tim Horton  <timothy_horton@apple.com>
+
+        Implement immediate action support for tel: and mailto: URLs
+        https://bugs.webkit.org/show_bug.cgi?id=143916
+        <rdar://problem/19721711>
+
+        Reviewed by Darin Adler.
+
+        * WebView/WebImmediateActionController.mm:
+        (-[WebImmediateActionController _defaultAnimationController]):
+        (-[WebImmediateActionController _animationControllerForDataDetectedText]):
+        (-[WebImmediateActionController _animationControllerForDataDetectedLink]):
+        (-[WebImmediateActionController _menuItemForDataDetectedText]): Deleted.
+        * WebView/WebUIDelegatePrivate.h:
+        Add _animationControllerForDataDetectedLink and use it when
+        building immediate actions for tel: and mailto: links.
+
 2015-04-17  Daniel Bates  <dabates@apple.com>
 
         REGRESSION: SVG does not support link dragging
index 8681b29..76825e7 100644 (file)
@@ -214,30 +214,42 @@ using namespace WebCore;
 {
     NSURL *url = _hitTestResult.absoluteLinkURL();
     NSString *absoluteURLString = [url absoluteString];
-    if (url && WebCore::protocolIsInHTTPFamily(absoluteURLString) && _hitTestResult.URLElement()) {
-        _type = WebImmediateActionLinkPreview;
-
-        RefPtr<Range> linkRange = rangeOfContents(*_hitTestResult.URLElement());
-        RefPtr<TextIndicator> linkTextIndicator = TextIndicator::createWithRange(*linkRange, TextIndicatorPresentationTransition::FadeIn);
-        [_webView _setTextIndicator:linkTextIndicator.get() fadeOut:NO];
-
-        RetainPtr<QLPreviewMenuItem> qlPreviewLinkItem = [NSMenuItem standardQuickLookMenuItem];
-        [qlPreviewLinkItem setPreviewStyle:QLPreviewStylePopover];
-        [qlPreviewLinkItem setDelegate:self];
-        _currentQLPreviewMenuItem = qlPreviewLinkItem.get();
-        return (id <NSImmediateActionAnimationController>)qlPreviewLinkItem.get();
+    if (url && _hitTestResult.URLElement()) {
+        if (protocolIs(absoluteURLString, "mailto")) {
+            _type = WebImmediateActionMailtoLink;
+            return [self _animationControllerForDataDetectedLink];
+        }
+
+        if (protocolIs(absoluteURLString, "tel")) {
+            _type = WebImmediateActionTelLink;
+            return [self _animationControllerForDataDetectedLink];
+        }
+
+        if (WebCore::protocolIsInHTTPFamily(absoluteURLString)) {
+            _type = WebImmediateActionLinkPreview;
+
+            RefPtr<Range> linkRange = rangeOfContents(*_hitTestResult.URLElement());
+            RefPtr<TextIndicator> indicator = TextIndicator::createWithRange(*linkRange, TextIndicatorPresentationTransition::FadeIn);
+            [_webView _setTextIndicator:indicator.get() fadeOut:NO];
+
+            QLPreviewMenuItem *item = [NSMenuItem standardQuickLookMenuItem];
+            item.previewStyle = QLPreviewStylePopover;
+            item.delegate = self;
+            _currentQLPreviewMenuItem = item;
+            return (id <NSImmediateActionAnimationController>)item;
+        }
     }
 
     Node* node = _hitTestResult.innerNode();
     if ((node && node->isTextNode()) || _hitTestResult.isOverTextInsideFormControlElement()) {
-        if (NSMenuItem *immediateActionItem = [self _menuItemForDataDetectedText]) {
+        if (auto animationController = [self _animationControllerForDataDetectedText]) {
             _type = WebImmediateActionDataDetectedItem;
-            return (id<NSImmediateActionAnimationController>)immediateActionItem;
+            return animationController;
         }
 
-        if (id<NSImmediateActionAnimationController> defaultTextController = [self _animationControllerForText]) {
+        if (auto animationController = [self _animationControllerForText]) {
             _type = WebImmediateActionText;
-            return defaultTextController;
+            return animationController;
         }
     }
 
@@ -337,7 +349,7 @@ static IntRect elementBoundingBoxInWindowCoordinatesFromNode(Node* node)
 
 #pragma mark Data Detectors actions
 
-- (NSMenuItem *)_menuItemForDataDetectedText
+- (id <NSImmediateActionAnimationController>)_animationControllerForDataDetectedText
 {
     RefPtr<Range> detectedDataRange;
     FloatRect detectedDataBoundingBox;
@@ -385,6 +397,37 @@ static IntRect elementBoundingBoxInWindowCoordinatesFromNode(Node* node)
     return menuItems.lastObject;
 }
 
+- (id <NSImmediateActionAnimationController>)_animationControllerForDataDetectedLink
+{
+    RetainPtr<DDActionContext> actionContext = adoptNS([allocDDActionContextInstance() init]);
+
+    if (!actionContext)
+        return nil;
+
+    [actionContext setAltMode:YES];
+    [actionContext setImmediate:YES];
+
+    RefPtr<Range> linkRange = rangeOfContents(*_hitTestResult.URLElement());
+    if (!linkRange)
+        return nullptr;
+    RefPtr<TextIndicator> indicator = TextIndicator::createWithRange(*linkRange, TextIndicatorPresentationTransition::FadeIn);
+
+    _currentActionContext = [actionContext contextForView:_webView altMode:YES interactionStartedHandler:^() {
+    } interactionChangedHandler:^() {
+        [_webView _setTextIndicator:indicator.get() fadeOut:NO];
+    } interactionStoppedHandler:^() {
+        [_webView _clearTextIndicator];
+    }];
+
+    [_currentActionContext setHighlightFrame:[_webView.window convertRectToScreen:elementBoundingBoxInWindowCoordinatesFromNode(_hitTestResult.URLElement())]];
+
+    NSArray *menuItems = [[getDDActionsManagerClass() sharedManager] menuItemsForTargetURL:_hitTestResult.absoluteLinkURL() actionContext:_currentActionContext.get()];
+    if (menuItems.count != 1)
+        return nil;
+    
+    return menuItems.lastObject;
+}
+
 #pragma mark Text action
 
 static DictionaryPopupInfo dictionaryPopupInfoForRange(Frame* frame, Range& range, NSDictionary *options, TextIndicatorPresentationTransition presentationTransition)
index 667a789..b61c773 100644 (file)
@@ -149,7 +149,9 @@ typedef enum {
     WebImmediateActionNone = 0,
     WebImmediateActionLinkPreview,
     WebImmediateActionDataDetectedItem,
-    WebImmediateActionText
+    WebImmediateActionText,
+    WebImmediateActionMailtoLink,
+    WebImmediateActionTelLink
 } WebImmediateActionType;
 
 // Message Sources.
index 4dc18fc..fa8216b 100644 (file)
@@ -1,3 +1,20 @@
+2015-04-20  Tim Horton  <timothy_horton@apple.com>
+
+        Implement immediate action support for tel: and mailto: URLs
+        https://bugs.webkit.org/show_bug.cgi?id=143916
+        <rdar://problem/19721711>
+
+        Reviewed by Darin Adler.
+
+        * Shared/API/c/WKImmediateActionTypes.h:
+        * UIProcess/mac/WKImmediateActionController.mm:
+        (-[WKImmediateActionController _defaultAnimationController]):
+        (-[WKImmediateActionController _animationControllerForDataDetectedText]):
+        (-[WKImmediateActionController _animationControllerForDataDetectedLink]):
+        (-[WKImmediateActionController _menuItemForDataDetectedText]): Deleted.
+        Add _animationControllerForDataDetectedLink and use it when
+        building immediate actions for tel: and mailto: links.
+
 2015-04-20  Alex Christensen  <achristensen@webkit.org>
 
         Properly report errors from _WKUserContentExtensionStore.
index d380077..34fb368 100644 (file)
@@ -37,6 +37,8 @@ enum {
     kWKImmediateActionLinkPreview,
     kWKImmediateActionDataDetectedItem,
     kWKImmediateActionLookupText,
+    kWKImmediateActionMailtoLink,
+    kWKImmediateActionTelLink
 };
 typedef uint32_t _WKImmediateActionType;
 
index c4c8bea..531ad1d 100644 (file)
@@ -274,28 +274,41 @@ using namespace WebKit;
         return nil;
 
     String absoluteLinkURL = hitTestResult->absoluteLinkURL();
-    if (!absoluteLinkURL.isEmpty() && WebCore::protocolIsInHTTPFamily(absoluteLinkURL)) {
-        _type = kWKImmediateActionLinkPreview;
+    if (!absoluteLinkURL.isEmpty()) {
+        if (protocolIs(absoluteLinkURL, "mailto")) {
+            _type = kWKImmediateActionMailtoLink;
+            return [self _animationControllerForDataDetectedLink];
+        }
+
+        if (protocolIs(absoluteLinkURL, "tel")) {
+            _type = kWKImmediateActionTelLink;
+            return [self _animationControllerForDataDetectedLink];
+        }
+
+        if (WebCore::protocolIsInHTTPFamily(absoluteLinkURL)) {
+            _type = kWKImmediateActionLinkPreview;
 
-        if (TextIndicator *textIndicator = _hitTestResultData.linkTextIndicator.get())
-            _page->setTextIndicator(textIndicator->data(), false);
+            QLPreviewMenuItem *item = [NSMenuItem standardQuickLookMenuItem];
+            item.previewStyle = QLPreviewStylePopover;
+            item.delegate = self;
+            _currentQLPreviewMenuItem = item;
 
-        RetainPtr<QLPreviewMenuItem> qlPreviewLinkItem = [NSMenuItem standardQuickLookMenuItem];
-        [qlPreviewLinkItem setPreviewStyle:QLPreviewStylePopover];
-        [qlPreviewLinkItem setDelegate:self];
-        _currentQLPreviewMenuItem = qlPreviewLinkItem.get();
-        return (id<NSImmediateActionAnimationController>)qlPreviewLinkItem.get();
+            if (TextIndicator *textIndicator = _hitTestResultData.linkTextIndicator.get())
+                _page->setTextIndicator(textIndicator->data(), false);
+
+            return (id<NSImmediateActionAnimationController>)item;
+        }
     }
 
     if (hitTestResult->isTextNode() || hitTestResult->isOverTextInsideFormControlElement()) {
-        if (NSMenuItem *immediateActionItem = [self _menuItemForDataDetectedText]) {
+        if (auto animationController = [self _animationControllerForDataDetectedText]) {
             _type = kWKImmediateActionDataDetectedItem;
-            return (id<NSImmediateActionAnimationController>)immediateActionItem;
+            return animationController;
         }
 
-        if (id<NSImmediateActionAnimationController> textAnimationController = [self _animationControllerForText]) {
+        if (auto animationController = [self _animationControllerForText]) {
             _type = kWKImmediateActionLookupText;
-            return textAnimationController;
+            return animationController;
         }
     }
 
@@ -374,7 +387,7 @@ using namespace WebKit;
 
 #pragma mark Data Detectors actions
 
-- (NSMenuItem *)_menuItemForDataDetectedText
+- (id<NSImmediateActionAnimationController>)_animationControllerForDataDetectedText
 {
     DDActionContext *actionContext = _hitTestResultData.detectedDataActionContext.get();
     if (!actionContext)
@@ -407,7 +420,37 @@ using namespace WebKit;
     if (menuItems.count != 1)
         return nil;
 
-    return menuItems.lastObject;
+    return (id<NSImmediateActionAnimationController>)menuItems.lastObject;
+}
+
+- (id<NSImmediateActionAnimationController>)_animationControllerForDataDetectedLink
+{
+    RetainPtr<DDActionContext> actionContext = adoptNS([allocDDActionContextInstance() init]);
+
+    if (!actionContext)
+        return nil;
+
+    [actionContext setAltMode:YES];
+    [actionContext setImmediate:YES];
+
+    RefPtr<WebPageProxy> page = _page;
+    _currentActionContext = [actionContext contextForView:_wkView altMode:YES interactionStartedHandler:^() {
+    } interactionChangedHandler:^() {
+        if (_hitTestResultData.linkTextIndicator)
+            page->setTextIndicator(_hitTestResultData.linkTextIndicator->data(), false);
+    } interactionStoppedHandler:^() {
+        [self _clearImmediateActionState];
+    }];
+
+    [_currentActionContext setHighlightFrame:[_wkView.window convertRectToScreen:[_wkView convertRect:_hitTestResultData.elementBoundingBox toView:nil]]];
+
+    RefPtr<WebHitTestResult> hitTestResult = [self _webHitTestResult];
+    NSArray *menuItems = [[getDDActionsManagerClass() sharedManager] menuItemsForTargetURL:hitTestResult->absoluteLinkURL() actionContext:_currentActionContext.get()];
+
+    if (menuItems.count != 1)
+        return nil;
+
+    return (id<NSImmediateActionAnimationController>)menuItems.lastObject;
 }
 
 #pragma mark Text action