Add a mechanism to customize the long press action.
authorenrica@apple.com <enrica@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 4 Mar 2016 23:55:55 +0000 (23:55 +0000)
committerenrica@apple.com <enrica@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 4 Mar 2016 23:55:55 +0000 (23:55 +0000)
https://bugs.webkit.org/show_bug.cgi?id=154995
rdar://problem/24823732

Reviewed by Tim Horton.

Source/WebCore:

We want to allow long press on attachment elements as well.

* WebCore.xcodeproj/project.pbxproj: Making HTMLAttachmentElement.h private.
* html/HTMLAttachmentElement.h: Adding exported functions.

Source/WebKit2:

Adding a new private delegate method to allow clients to
replace the action sheet displayed for images and links.
The change also adds support for attachment elements.

* Shared/ios/InteractionInformationAtPosition.h:
* Shared/ios/InteractionInformationAtPosition.mm:
(WebKit::InteractionInformationAtPosition::encode):
(WebKit::InteractionInformationAtPosition::decode):
* UIProcess/API/Cocoa/WKUIDelegatePrivate.h:
* UIProcess/API/Cocoa/_WKActivatedElementInfo.h:
* UIProcess/ios/WKActionSheetAssistant.h:
* UIProcess/ios/WKActionSheetAssistant.mm:
(-[WKActionSheetAssistant showImageSheet]):
(-[WKActionSheetAssistant showLinkSheet]):
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView _showImageSheet]):
(-[WKContentView _showAttachmentSheet]):
(-[WKContentView _showLinkSheet]):
(-[WKContentView _actionForLongPress]):
(-[WKContentView actionSheetAssistant:shouldIncludeAppLinkActionsForElement:]):
(-[WKContentView actionSheetAssistant:showCustomSheetForElement:]):
(-[WKContentView actionSheetAssistant:decideActionsForElement:defaultActions:]):
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::getPositionInformation):

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

12 files changed:
Source/WebCore/ChangeLog
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/html/HTMLAttachmentElement.h
Source/WebKit2/ChangeLog
Source/WebKit2/Shared/ios/InteractionInformationAtPosition.h
Source/WebKit2/Shared/ios/InteractionInformationAtPosition.mm
Source/WebKit2/UIProcess/API/Cocoa/WKUIDelegatePrivate.h
Source/WebKit2/UIProcess/API/Cocoa/_WKActivatedElementInfo.h
Source/WebKit2/UIProcess/ios/WKActionSheetAssistant.h
Source/WebKit2/UIProcess/ios/WKActionSheetAssistant.mm
Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm
Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm

index 26227b7..3276220 100644 (file)
@@ -1,3 +1,16 @@
+2016-03-03  Enrica Casucci  <enrica@apple.com>
+
+        Add a mechanism to customize the long press action.
+        https://bugs.webkit.org/show_bug.cgi?id=154995
+        rdar://problem/24823732
+
+        Reviewed by Tim Horton.
+
+        We want to allow long press on attachment elements as well.
+
+        * WebCore.xcodeproj/project.pbxproj: Making HTMLAttachmentElement.h private.
+        * html/HTMLAttachmentElement.h: Adding exported functions.
+
 2016-03-04  Andreas Kling  <akling@apple.com>
 
         [iOS] Throw away compiled RegExp code when navigating to a new page.
index dc63015..cb74f56 100644 (file)
                7C5343FC17B74B63004232F0 /* JSMediaQueryListListener.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C5343FA17B74B63004232F0 /* JSMediaQueryListListener.cpp */; };
                7C5343FD17B74B63004232F0 /* JSMediaQueryListListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C5343FB17B74B63004232F0 /* JSMediaQueryListListener.h */; };
                7C5F28FB1A827D8400C0F31F /* HTMLAttachmentElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C5F28F91A827D8400C0F31F /* HTMLAttachmentElement.cpp */; };
-               7C5F28FC1A827D8400C0F31F /* HTMLAttachmentElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C5F28FA1A827D8400C0F31F /* HTMLAttachmentElement.h */; };
+               7C5F28FC1A827D8400C0F31F /* HTMLAttachmentElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C5F28FA1A827D8400C0F31F /* HTMLAttachmentElement.h */; settings = {ATTRIBUTES = (Private, ); }; };
                7C73FB07191EF417007DE061 /* UserMessageHandlersNamespace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C73FB05191EF416007DE061 /* UserMessageHandlersNamespace.cpp */; };
                7C73FB08191EF417007DE061 /* UserMessageHandlersNamespace.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C73FB06191EF417007DE061 /* UserMessageHandlersNamespace.h */; settings = {ATTRIBUTES = (Private, ); }; };
                7C73FB0C191EF5A8007DE061 /* JSUserMessageHandlersNamespace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C73FB0A191EF5A8007DE061 /* JSUserMessageHandlersNamespace.cpp */; };
index cc431ba..07abac2 100644 (file)
@@ -37,10 +37,10 @@ class File;
 class HTMLAttachmentElement final : public HTMLElement {
 public:
     static Ref<HTMLAttachmentElement> create(const QualifiedName&, Document&);
-    File* file() const;
+    WEBCORE_EXPORT File* file() const;
     void setFile(File*);
 
-    String attachmentTitle() const;
+    WEBCORE_EXPORT String attachmentTitle() const;
     String attachmentType() const;
 
 private:
index ad3b20a..02f6292 100644 (file)
@@ -1,3 +1,36 @@
+2016-03-03  Enrica Casucci  <enrica@apple.com>
+
+        Add a mechanism to customize the long press action.
+        https://bugs.webkit.org/show_bug.cgi?id=154995
+        rdar://problem/24823732
+
+        Reviewed by Tim Horton.
+
+        Adding a new private delegate method to allow clients to
+        replace the action sheet displayed for images and links.
+        The change also adds support for attachment elements.
+
+        * Shared/ios/InteractionInformationAtPosition.h:
+        * Shared/ios/InteractionInformationAtPosition.mm:
+        (WebKit::InteractionInformationAtPosition::encode):
+        (WebKit::InteractionInformationAtPosition::decode):
+        * UIProcess/API/Cocoa/WKUIDelegatePrivate.h:
+        * UIProcess/API/Cocoa/_WKActivatedElementInfo.h:
+        * UIProcess/ios/WKActionSheetAssistant.h:
+        * UIProcess/ios/WKActionSheetAssistant.mm:
+        (-[WKActionSheetAssistant showImageSheet]):
+        (-[WKActionSheetAssistant showLinkSheet]):
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView _showImageSheet]):
+        (-[WKContentView _showAttachmentSheet]):
+        (-[WKContentView _showLinkSheet]):
+        (-[WKContentView _actionForLongPress]):
+        (-[WKContentView actionSheetAssistant:shouldIncludeAppLinkActionsForElement:]):
+        (-[WKContentView actionSheetAssistant:showCustomSheetForElement:]):
+        (-[WKContentView actionSheetAssistant:decideActionsForElement:defaultActions:]):
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::WebPage::getPositionInformation):
+
 2016-03-04  Brent Fulgham  <bfulgham@apple.com>
 
         [WK2] Gather resource load statistics
index aae5176..0ff3b3e 100644 (file)
@@ -45,6 +45,7 @@ struct InteractionInformationAtPosition {
     bool touchCalloutEnabled { true };
     bool isLink { false };
     bool isImage { false };
+    bool isAttachment { false };
     bool isAnimatedImage { false };
     bool isElement { false };
 #if ENABLE(DATA_DETECTION)
index cd64c7c..cb654d7 100644 (file)
@@ -48,6 +48,7 @@ void InteractionInformationAtPosition::encode(IPC::ArgumentEncoder& encoder) con
     encoder << touchCalloutEnabled;
     encoder << isLink;
     encoder << isImage;
+    encoder << isAttachment;
     encoder << isAnimatedImage;
     encoder << isElement;
     encoder << url;
@@ -98,6 +99,9 @@ bool InteractionInformationAtPosition::decode(IPC::ArgumentDecoder& decoder, Int
     if (!decoder.decode(result.isImage))
         return false;
 
+    if (!decoder.decode(result.isAttachment))
+        return false;
+    
     if (!decoder.decode(result.isAnimatedImage))
         return false;
     
index cb10896..55b9606 100644 (file)
@@ -71,6 +71,7 @@ struct UIEdgeInsets;
 - (void)_webView:(WKWebView *)webView commitPreviewedImageWithURL:(NSURL *)imageURL WK_AVAILABLE(NA, 9_0);
 - (void)_webView:(WKWebView *)webView didDismissPreviewViewController:(UIViewController *)previewedViewController committing:(BOOL)committing WK_AVAILABLE(NA, 9_0);
 - (void)_webView:(WKWebView *)webView didDismissPreviewViewController:(UIViewController *)previewedViewController WK_AVAILABLE(NA, 9_0);
+- (BOOL)_webView:(WKWebView *)webView showCustomSheetForElement:(_WKActivatedElementInfo *)element WK_AVAILABLE(NA, WK_IOS_TBA);
 - (UIEdgeInsets)_webView:(WKWebView *)webView finalObscuredInsetsForScrollView:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset WK_AVAILABLE(NA, 9_0);
 - (UIViewController *)_webView:(WKWebView *)webView previewViewControllerForURL:(NSURL *)url defaultActions:(WK_ARRAY(_WKElementAction *) *)actions elementInfo:(_WKActivatedElementInfo *)elementInfo WK_AVAILABLE(NA, 9_0);
 - (UIViewController *)_webView:(WKWebView *)webView previewViewControllerForAnimatedImageAtURL:(NSURL *)url defaultActions:(WK_ARRAY(_WKElementAction *) *)actions elementInfo:(_WKActivatedElementInfo *)elementInfo imageSize:(CGSize)imageSize WK_AVAILABLE(NA, 9_0);
index 9860157..44fc350 100644 (file)
@@ -36,6 +36,7 @@
 typedef NS_ENUM(NSInteger, _WKActivatedElementType) {
     _WKActivatedElementTypeLink,
     _WKActivatedElementTypeImage,
+    _WKActivatedElementTypeAttachment WK_ENUM_AVAILABLE(WK_MAC_TBA, WK_IOS_TBA),
 } WK_ENUM_AVAILABLE(10_10, 8_0);
 
 WK_CLASS_AVAILABLE(10_10, 8_0)
index c855e2d..e05aee0 100644 (file)
@@ -52,6 +52,7 @@ struct InteractionInformationAtPosition;
 - (RetainPtr<NSArray>)actionSheetAssistant:(WKActionSheetAssistant *)assistant decideActionsForElement:(_WKActivatedElementInfo *)element defaultActions:(RetainPtr<NSArray>)defaultActions;
 
 @optional
+- (BOOL)actionSheetAssistant:(WKActionSheetAssistant *)assistant showCustomSheetForElement:(_WKActivatedElementInfo *)element;
 - (void)updatePositionInformationForActionSheetAssistant:(WKActionSheetAssistant *)assistant;
 - (void)actionSheetAssistant:(WKActionSheetAssistant *)assistant willStartInteractionWithElement:(_WKActivatedElementInfo *)element;
 - (void)actionSheetAssistantDidStopInteraction:(WKActionSheetAssistant *)assistant;
index 8321135..6e7f2b8 100644 (file)
@@ -281,6 +281,8 @@ static LSAppLink *appLinkForURL(NSURL *url)
 
     NSURL *targetURL = [NSURL _web_URLWithWTFString:positionInformation.url];
     auto elementInfo = adoptNS([[_WKActivatedElementInfo alloc] _initWithType:_WKActivatedElementTypeImage URL:targetURL location:positionInformation.point title:positionInformation.title rect:positionInformation.bounds image:positionInformation.image.get()]);
+    if ([delegate respondsToSelector:@selector(actionSheetAssistant:showCustomSheetForElement:)] && [delegate actionSheetAssistant:self showCustomSheetForElement:elementInfo.get()])
+        return;
     auto defaultActions = [self defaultActionsForImageSheet:elementInfo.get()];
 
     RetainPtr<NSArray> actions = [delegate actionSheetAssistant:self decideActionsForElement:elementInfo.get() defaultActions:WTFMove(defaultActions)];
@@ -395,6 +397,9 @@ static LSAppLink *appLinkForURL(NSURL *url)
         return;
 
     auto elementInfo = adoptNS([[_WKActivatedElementInfo alloc] _initWithType:_WKActivatedElementTypeLink URL:targetURL location:positionInformation.point title:positionInformation.title rect:positionInformation.bounds image:positionInformation.image.get()]);
+    if ([delegate respondsToSelector:@selector(actionSheetAssistant:showCustomSheetForElement:)] && [delegate actionSheetAssistant:self showCustomSheetForElement:elementInfo.get()])
+        return;
+
     auto defaultActions = [self defaultActionsForLinkSheet:elementInfo.get()];
 
     RetainPtr<NSArray> actions = [delegate actionSheetAssistant:self decideActionsForElement:elementInfo.get() defaultActions:WTFMove(defaultActions)];
index 92c698f..c40805b 100644 (file)
@@ -1083,6 +1083,14 @@ static inline bool isSamePair(UIGestureRecognizer *a, UIGestureRecognizer *b, UI
     [_actionSheetAssistant showImageSheet];
 }
 
+- (void)_showAttachmentSheet
+{
+    id <WKUIDelegatePrivate> uiDelegate = static_cast<id <WKUIDelegatePrivate>>([_webView UIDelegate]);
+    
+    if ([uiDelegate respondsToSelector:@selector(_webView:showCustomSheetForElement:)])
+        [uiDelegate _webView:_webView showCustomSheetForElement:[[_WKActivatedElementInfo alloc] _initWithType:_WKActivatedElementTypeAttachment URL:[NSURL _web_URLWithWTFString:_positionInformation.url] location:_positionInformation.point title:_positionInformation.title rect:_positionInformation.bounds image:nil]];
+}
+
 - (void)_showLinkSheet
 {
     [_actionSheetAssistant showLinkSheet];
@@ -1107,6 +1115,9 @@ static inline bool isSamePair(UIGestureRecognizer *a, UIGestureRecognizer *b, UI
             return @selector(_showDataDetectorsSheet);
         return @selector(_showLinkSheet);
     }
+    
+    if (_positionInformation.isAttachment)
+        return @selector(_showAttachmentSheet);
 
     return nil;
 }
@@ -3545,6 +3556,21 @@ static bool isAssistableInputType(InputType type)
 }
 #endif
 
+- (BOOL)actionSheetAssistant:(WKActionSheetAssistant *)assistant showCustomSheetForElement:(_WKActivatedElementInfo *)element
+{
+    id <WKUIDelegatePrivate> uiDelegate = static_cast<id <WKUIDelegatePrivate>>([_webView UIDelegate]);
+    
+    if ([uiDelegate respondsToSelector:@selector(_webView:showCustomSheetForElement:)]) {
+        if ([uiDelegate _webView:_webView showCustomSheetForElement:element]) {
+            // Prevent tap-and-hold and drag.
+            [UIApp _cancelAllTouches];
+            return YES;
+        }
+    }
+
+    return NO;
+}
+
 - (RetainPtr<NSArray>)actionSheetAssistant:(WKActionSheetAssistant *)assistant decideActionsForElement:(_WKActivatedElementInfo *)element defaultActions:(RetainPtr<NSArray>)defaultActions
 {
     return _page->uiClient().actionsForElement(element, WTFMove(defaultActions));
index 945907d..557cfea 100644 (file)
 #import <WebCore/Element.h>
 #import <WebCore/ElementAncestorIterator.h>
 #import <WebCore/EventHandler.h>
+#import <WebCore/File.h>
 #import <WebCore/FloatQuad.h>
 #import <WebCore/FocusController.h>
 #import <WebCore/Frame.h>
 #import <WebCore/FrameLoaderClient.h>
 #import <WebCore/FrameView.h>
 #import <WebCore/GeometryUtilities.h>
+#import <WebCore/HTMLAttachmentElement.h>
 #import <WebCore/HTMLElementTypeHelpers.h>
 #import <WebCore/HTMLFormElement.h>
 #import <WebCore/HTMLImageElement.h>
@@ -2243,8 +2245,16 @@ void WebPage::getPositionInformation(const IntPoint& point, InteractionInformati
             m_page->focusController().setFocusedFrame(result.innerNodeFrame());
             info.bounds = renderer->absoluteBoundingBoxRect(true);
             // We don't want to select blocks that are larger than 97% of the visible area of the document.
-            const static CGFloat factor = 0.97;
-            info.isSelectable = renderer->style().userSelect() != SELECT_NONE && info.bounds.height() < result.innerNodeFrame()->view()->unobscuredContentRect().height() * factor;
+            if (is<HTMLAttachmentElement>(*hitNode)) {
+                info.isAttachment = true;
+                const HTMLAttachmentElement& attachment = downcast<HTMLAttachmentElement>(*hitNode);
+                info.title = attachment.attachmentTitle();
+                if (attachment.file())
+                    info.url = downcast<HTMLAttachmentElement>(*hitNode).file()->path();
+            } else {
+                const static CGFloat factor = 0.97;
+                info.isSelectable = renderer->style().userSelect() != SELECT_NONE && info.bounds.height() < result.innerNodeFrame()->view()->unobscuredContentRect().height() * factor;
+            }
         }
     }
 }