Tapping and holding a link should have a share option
[WebKit-https.git] / Source / WebKit2 / UIProcess / API / Cocoa / _WKElementAction.mm
1 /*
2  * Copyright (C) 2014 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #import "config.h"
27 #import "_WKElementActionInternal.h"
28
29 #if WK_API_ENABLED
30
31 #if PLATFORM(IOS)
32
33 #import "GestureTypes.h"
34 #import "WKActionSheetAssistant.h"
35 #import "WKContentViewInteraction.h"
36 #import "_WKActivatedElementInfoInternal.h"
37 #import <WebCore/LocalizedStrings.h>
38 #import <WebCore/SoftLinking.h>
39 #import <wtf/RetainPtr.h>
40 #import <wtf/text/WTFString.h>
41
42 #if HAVE(SAFARI_SERVICES_FRAMEWORK)
43 #import <SafariServices/SSReadingList.h>
44 SOFT_LINK_FRAMEWORK(SafariServices);
45 SOFT_LINK_CLASS(SafariServices, SSReadingList);
46 #endif
47
48 typedef void (^WKElementActionHandlerInternal)(WKActionSheetAssistant *, _WKActivatedElementInfo *);
49
50 @implementation _WKElementAction  {
51     RetainPtr<NSString> _title;
52     WKElementActionHandlerInternal _actionHandler;
53     WKElementActionDismissalHandler _dismissalHandler;
54     __weak WKActionSheetAssistant *_defaultActionSheetAssistant;
55 }
56
57 - (id)_initWithTitle:(NSString *)title actionHandler:(WKElementActionHandlerInternal)handler type:(_WKElementActionType)type assistant:(WKActionSheetAssistant *)assistant
58 {
59     if (!(self = [super init]))
60         return nil;
61
62     _title = adoptNS([title copy]);
63     _type = type;
64     _actionHandler = [handler copy];
65     _defaultActionSheetAssistant = assistant;
66     return self;
67 }
68
69 - (void)dealloc
70 {
71     [_actionHandler release];
72     [_dismissalHandler release];
73
74     [super dealloc];
75 }
76
77 + (instancetype)elementActionWithTitle:(NSString *)title actionHandler:(WKElementActionHandler)handler
78 {
79     return [[[self alloc] _initWithTitle:title actionHandler:^(WKActionSheetAssistant *, _WKActivatedElementInfo *actionInfo) { handler(actionInfo); }
80         type:_WKElementActionTypeCustom assistant:nil] autorelease];
81 }
82
83 #if HAVE(SAFARI_SERVICES_FRAMEWORK)
84 static void addToReadingList(NSURL *targetURL, NSString *title)
85 {
86     if (!title || [title length] == 0)
87         title = [targetURL absoluteString];
88
89     [[getSSReadingListClass() defaultReadingList] addReadingListItemWithURL:targetURL title:title previewText:nil error:nil];
90 }
91 #endif
92
93 + (instancetype)_elementActionWithType:(_WKElementActionType)type title:(NSString *)title actionHandler:(WKElementActionHandler)actionHandler
94 {
95     WKElementActionHandlerInternal handler = ^(WKActionSheetAssistant *, _WKActivatedElementInfo *actionInfo) { actionHandler(actionInfo); };
96     return [[[self alloc] _initWithTitle:title actionHandler:handler type:type assistant:nil] autorelease];
97 }
98
99 + (instancetype)_elementActionWithType:(_WKElementActionType)type customTitle:(NSString *)customTitle assistant:(WKActionSheetAssistant *)assistant
100 {
101     NSString *title;
102     WKElementActionHandlerInternal handler;
103     switch (type) {
104     case _WKElementActionTypeCopy:
105         title = WEB_UI_STRING_KEY("Copy", "Copy (ActionSheet)", "Title for Copy Link or Image action button");
106         handler = ^(WKActionSheetAssistant *assistant, _WKActivatedElementInfo *actionInfo) {
107             [assistant.delegate actionSheetAssistant:assistant performAction:WebKit::SheetAction::Copy];
108         };
109         break;
110     case _WKElementActionTypeOpen:
111         title = WEB_UI_STRING("Open", "Title for Open Link action button");
112         handler = ^(WKActionSheetAssistant *assistant, _WKActivatedElementInfo *actionInfo) {
113             [assistant.delegate actionSheetAssistant:assistant openElementAtLocation:actionInfo._interactionLocation];
114         };
115         break;
116     case _WKElementActionTypeSaveImage:
117         title = WEB_UI_STRING("Save Image", "Title for Save Image action button");
118         handler = ^(WKActionSheetAssistant *assistant, _WKActivatedElementInfo *actionInfo) {
119             [assistant.delegate actionSheetAssistant:assistant performAction:WebKit::SheetAction::SaveImage];
120         };
121         break;
122 #if HAVE(SAFARI_SERVICES_FRAMEWORK)
123     case _WKElementActionTypeAddToReadingList:
124         title = WEB_UI_STRING("Add to Reading List", "Title for Add to Reading List action button");
125         handler = ^(WKActionSheetAssistant *, _WKActivatedElementInfo *actionInfo) {
126             addToReadingList(actionInfo.URL, actionInfo.title);
127         };
128         break;
129 #endif
130     case _WKElementActionTypeShare:
131         title = WEB_UI_STRING("Share…", "Title for Share action button");
132         handler = ^(WKActionSheetAssistant *assistant, _WKActivatedElementInfo *actionInfo) {
133             [assistant.delegate actionSheetAssistant:assistant shareElementWithURL:actionInfo.URL rect:actionInfo.boundingRect];
134         };
135         break;
136     default:
137         [NSException raise:NSInvalidArgumentException format:@"There is no standard web element action of type %ld.", (long)type];
138         return nil;
139     }
140
141     return [[[self alloc] _initWithTitle:(customTitle ? customTitle : title) actionHandler:handler type:type assistant:assistant] autorelease];
142 }
143
144 + (instancetype)_elementActionWithType:(_WKElementActionType)type assistant:(WKActionSheetAssistant *)assistant
145 {
146     return [self _elementActionWithType:type customTitle:nil assistant:assistant];
147 }
148
149 + (instancetype)elementActionWithType:(_WKElementActionType)type customTitle:(NSString *)customTitle
150 {
151     return [self _elementActionWithType:type customTitle:customTitle assistant:nil];
152 }
153
154 + (instancetype)elementActionWithType:(_WKElementActionType)type
155 {
156     return [self elementActionWithType:type customTitle:nil];
157 }
158
159 - (NSString *)title
160 {
161     return _title.get();
162 }
163
164 - (void)_runActionWithElementInfo:(_WKActivatedElementInfo *)info forActionSheetAssistant:(WKActionSheetAssistant *)assistant
165 {
166     _actionHandler(assistant, info);
167 }
168
169 - (void)runActionWithElementInfo:(_WKActivatedElementInfo *)info
170 {
171     [self _runActionWithElementInfo:info forActionSheetAssistant:_defaultActionSheetAssistant];
172 }
173
174 @end
175
176 #endif // PLATFORM(IOS)
177
178 #endif // WK_API_ENABLED