[iOS] Cmd-C doesn't copy text from WKWebView
[WebKit-https.git] / Source / WebKit2 / UIProcess / ios / WKContentViewInteraction.h
1 /*
2  * Copyright (C) 2012-2017 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 #if PLATFORM(IOS)
27
28 #import "WKContentView.h"
29
30 #import "AssistedNodeInformation.h"
31 #import "EditorState.h"
32 #import "GestureTypes.h"
33 #import "InteractionInformationAtPosition.h"
34 #import "UIKitSPI.h"
35 #import "WKActionSheetAssistant.h"
36 #import "WKAirPlayRoutePicker.h"
37 #import "WKFileUploadPanel.h"
38 #import "WKFormPeripheral.h"
39 #import "WKSyntheticClickTapGestureRecognizer.h"
40 #import <UIKit/UIView.h>
41 #import <WebCore/Color.h>
42 #import <WebCore/FloatQuad.h>
43 #import <wtf/BlockPtr.h>
44 #import <wtf/Forward.h>
45 #import <wtf/Vector.h>
46 #import <wtf/text/WTFString.h>
47
48 #if USE(APPLE_INTERNAL_SDK) && __has_include(<WebKitAdditions/WKContentViewInteractionAdditions.h>)
49 #import <WebKitAdditions/WKContentViewInteractionAdditions.h>
50 #endif
51
52 namespace API {
53 class OpenPanelParameters;
54 }
55
56 namespace WebCore {
57 class Color;
58 class FloatQuad;
59 class IntSize;
60 class TextStream;
61 }
62
63 namespace WebKit {
64 class InputViewUpdateDeferrer;
65 class NativeWebTouchEvent;
66 class SmartMagnificationController;
67 class WebOpenPanelResultListenerProxy;
68 class WebPageProxy;
69 }
70
71 @class WKActionSheetAssistant;
72 @class WKFormInputSession;
73 @class WKInspectorNodeSearchGestureRecognizer;
74 @class WebEvent;
75 @class _UIHighlightView;
76 @class _UIWebHighlightLongPressGestureRecognizer;
77
78 #if ENABLE(DATA_INTERACTION)
79 @class WKDataInteractionCaretView;
80 #endif
81
82 typedef void (^UIWKAutocorrectionCompletionHandler)(UIWKAutocorrectionRects *rectsForInput);
83 typedef void (^UIWKAutocorrectionContextHandler)(UIWKAutocorrectionContext *autocorrectionContext);
84 typedef void (^UIWKDictationContextHandler)(NSString *selectedText, NSString *beforeText, NSString *afterText);
85 typedef void (^UIWKSelectionCompletionHandler)(void);
86 typedef void (^UIWKSelectionWithDirectionCompletionHandler)(BOOL selectionEndIsMoving);
87 typedef void (^UIWKKeyWebEventCompletionHandler)(::WebEvent *theEvent, BOOL wasHandled);
88
89 typedef BlockPtr<void(WebKit::InteractionInformationAtPosition)> InteractionInformationCallback;
90 typedef std::pair<WebKit::InteractionInformationRequest, InteractionInformationCallback> InteractionInformationRequestAndCallback;
91
92 #define FOR_EACH_WKCONTENTVIEW_ACTION(M) \
93     M(_addShortcut) \
94     M(_arrowKey) \
95     M(_define) \
96     M(_lookup) \
97     M(_promptForReplace) \
98     M(_reanalyze) \
99     M(_share) \
100     M(_showTextStyleOptions) \
101     M(_transliterateChinese) \
102     M(copy) \
103     M(cut) \
104     M(paste) \
105     M(replace) \
106     M(select) \
107     M(selectAll) \
108     M(toggleBoldface) \
109     M(toggleItalics) \
110     M(toggleUnderline)
111
112 namespace WebKit {
113
114 struct WKSelectionDrawingInfo {
115     enum class SelectionType { None, Plugin, Range };
116     WKSelectionDrawingInfo();
117     explicit WKSelectionDrawingInfo(const EditorState&);
118     SelectionType type;
119     WebCore::IntRect caretRect;
120     Vector<WebCore::SelectionRect> selectionRects;
121 };
122
123 WebCore::TextStream& operator<<(WebCore::TextStream&, const WKSelectionDrawingInfo&);
124
125 struct WKAutoCorrectionData {
126     String fontName;
127     CGFloat fontSize;
128     uint64_t fontTraits;
129     CGRect textFirstRect;
130     CGRect textLastRect;
131     UIWKAutocorrectionCompletionHandler autocorrectionHandler;
132     UIWKAutocorrectionContextHandler autocorrectionContextHandler;
133 };
134
135 }
136
137 @interface WKContentView () {
138     RetainPtr<UIWebTouchEventsGestureRecognizer> _touchEventGestureRecognizer;
139
140     BOOL _canSendTouchEventsAsynchronously;
141
142     RetainPtr<WKSyntheticClickTapGestureRecognizer> _singleTapGestureRecognizer;
143     RetainPtr<_UIWebHighlightLongPressGestureRecognizer> _highlightLongPressGestureRecognizer;
144     RetainPtr<UILongPressGestureRecognizer> _longPressGestureRecognizer;
145     RetainPtr<UITapGestureRecognizer> _doubleTapGestureRecognizer;
146     RetainPtr<UITapGestureRecognizer> _nonBlockingDoubleTapGestureRecognizer;
147     RetainPtr<UITapGestureRecognizer> _twoFingerDoubleTapGestureRecognizer;
148     RetainPtr<UITapGestureRecognizer> _twoFingerSingleTapGestureRecognizer;
149     RetainPtr<WKInspectorNodeSearchGestureRecognizer> _inspectorNodeSearchGestureRecognizer;
150
151     RetainPtr<UIWKTextInteractionAssistant> _textSelectionAssistant;
152     RetainPtr<UIWKSelectionAssistant> _webSelectionAssistant;
153     BOOL _suppressAssistantSelectionView;
154
155     RetainPtr<UITextInputTraits> _traits;
156     RetainPtr<UIWebFormAccessory> _formAccessoryView;
157     RetainPtr<_UIHighlightView> _highlightView;
158     RetainPtr<UIView> _interactionViewsContainerView;
159     RetainPtr<NSString> _markedText;
160     RetainPtr<WKActionSheetAssistant> _actionSheetAssistant;
161     RetainPtr<WKAirPlayRoutePicker> _airPlayRoutePicker;
162     RetainPtr<WKFormInputSession> _formInputSession;
163     RetainPtr<WKFileUploadPanel> _fileUploadPanel;
164     RetainPtr<UIGestureRecognizer> _previewGestureRecognizer;
165     RetainPtr<UIGestureRecognizer> _previewSecondaryGestureRecognizer;
166 #if HAVE(LINK_PREVIEW)
167     RetainPtr<UIPreviewItemController> _previewItemController;
168 #endif
169
170     std::unique_ptr<WebKit::SmartMagnificationController> _smartMagnificationController;
171
172     id <UITextInputDelegate> _inputDelegate;
173
174     uint64_t _latestTapID;
175     struct TapHighlightInformation {
176         WebCore::Color color;
177         Vector<WebCore::FloatQuad> quads;
178         WebCore::IntSize topLeftRadius;
179         WebCore::IntSize topRightRadius;
180         WebCore::IntSize bottomLeftRadius;
181         WebCore::IntSize bottomRightRadius;
182     };
183     TapHighlightInformation _tapHighlightInformation;
184
185     WebKit::WKAutoCorrectionData _autocorrectionData;
186     WebKit::InteractionInformationAtPosition _positionInformation;
187     WebKit::AssistedNodeInformation _assistedNodeInformation;
188     RetainPtr<NSObject<WKFormPeripheral>> _inputPeripheral;
189     RetainPtr<UIEvent> _uiEventBeingResent;
190     UIWKKeyWebEventCompletionHandler _keyWebEventHandler;
191
192     CGPoint _lastInteractionLocation;
193     uint64_t _layerTreeTransactionIdAtLastTouchStart;
194
195     WebKit::WKSelectionDrawingInfo _lastSelectionDrawingInfo;
196
197     std::optional<WebKit::InteractionInformationRequest> _outstandingPositionInformationRequest;
198
199     uint64_t _positionInformationCallbackDepth;
200     Vector<std::optional<InteractionInformationRequestAndCallback>> _pendingPositionInformationHandlers;
201     
202     std::unique_ptr<WebKit::InputViewUpdateDeferrer> _inputViewUpdateDeferrer;
203
204     BOOL _isEditable;
205     BOOL _showingTextStyleOptions;
206     BOOL _hasValidPositionInformation;
207     BOOL _isTapHighlightIDValid;
208     BOOL _potentialTapInProgress;
209     BOOL _isDoubleTapPending;
210     BOOL _highlightLongPressCanClick;
211     BOOL _hasTapHighlightForPotentialTap;
212     BOOL _selectionNeedsUpdate;
213     BOOL _shouldRestoreSelection;
214     BOOL _usingGestureForSelection;
215     BOOL _inspectorNodeSearchEnabled;
216     BOOL _didAccessoryTabInitiateFocus;
217     BOOL _isExpectingFastSingleTapCommit;
218     BOOL _showDebugTapHighlightsForFastClicking;
219
220     BOOL _becomingFirstResponder;
221     BOOL _resigningFirstResponder;
222     BOOL _needsDeferredEndScrollingSelectionUpdate;
223
224 #if ENABLE(DATA_INTERACTION)
225     WebKit::WKDataInteractionState _dataInteractionState;
226     RetainPtr<WKDataInteraction> _dataInteraction;
227     RetainPtr<WKDataOperation> _dataOperation;
228     CGPoint _deferredActionSheetRequestLocation;
229 #endif
230 }
231
232 @end
233
234 @interface WKContentView (WKInteraction) <UIGestureRecognizerDelegate, UIWebTouchEventsGestureRecognizerDelegate, UITextInputPrivate, UIWebFormAccessoryDelegate, UIWKInteractionViewProtocol, WKFileUploadPanelDelegate, WKActionSheetAssistantDelegate
235 #if ENABLE(DATA_INTERACTION)
236     , WKDataInteractionDelegate, WKDataOperationDelegate
237 #endif
238 >
239
240 @property (nonatomic, readonly) CGPoint lastInteractionLocation;
241 @property (nonatomic, readonly) BOOL isEditable;
242 @property (nonatomic, readonly) BOOL shouldHideSelectionWhenScrolling;
243 @property (nonatomic, readonly) const WebKit::InteractionInformationAtPosition& positionInformation;
244 @property (nonatomic, readonly) const WebKit::WKAutoCorrectionData& autocorrectionData;
245 @property (nonatomic, readonly) const WebKit::AssistedNodeInformation& assistedNodeInformation;
246 @property (nonatomic, readonly) UIWebFormAccessory *formAccessoryView;
247 @property (nonatomic) BOOL suppressAssistantSelectionView;
248
249 - (void)setupInteraction;
250 - (void)cleanupInteraction;
251
252 - (void)scrollViewWillStartPanOrPinchGesture;
253
254 - (BOOL)canBecomeFirstResponderForWebView;
255 - (BOOL)becomeFirstResponderForWebView;
256 - (BOOL)resignFirstResponderForWebView;
257 - (BOOL)canPerformActionForWebView:(SEL)action withSender:(id)sender;
258
259 #define DECLARE_WKCONTENTVIEW_ACTION_FOR_WEB_VIEW(_action) \
260     - (void)_action ## ForWebView:(id)sender;
261 FOR_EACH_WKCONTENTVIEW_ACTION(DECLARE_WKCONTENTVIEW_ACTION_FOR_WEB_VIEW)
262 #undef DECLARE_WKCONTENTVIEW_ACTION_FOR_WEB_VIEW
263
264 #if ENABLE(TOUCH_EVENTS)
265 - (void)_webTouchEvent:(const WebKit::NativeWebTouchEvent&)touchEvent preventsNativeGestures:(BOOL)preventsDefault;
266 #endif
267 - (void)_commitPotentialTapFailed;
268 - (void)_didNotHandleTapAsClick:(const WebCore::IntPoint&)point;
269 - (void)_didCompleteSyntheticClick;
270 - (void)_didGetTapHighlightForRequest:(uint64_t)requestID color:(const WebCore::Color&)color quads:(const Vector<WebCore::FloatQuad>&)highlightedQuads topLeftRadius:(const WebCore::IntSize&)topLeftRadius topRightRadius:(const WebCore::IntSize&)topRightRadius bottomLeftRadius:(const WebCore::IntSize&)bottomLeftRadius bottomRightRadius:(const WebCore::IntSize&)bottomRightRadius;
271
272 - (BOOL)_mayDisableDoubleTapGesturesDuringSingleTap;
273 - (void)_disableDoubleTapGesturesDuringTapIfNecessary:(uint64_t)requestID;
274 - (void)_startAssistingNode:(const WebKit::AssistedNodeInformation&)information userIsInteracting:(BOOL)userIsInteracting blurPreviousNode:(BOOL)blurPreviousNode userObject:(NSObject <NSSecureCoding> *)userObject;
275 - (void)_stopAssistingNode;
276 - (void)_selectionChanged;
277 - (void)_updateChangedSelection;
278 - (BOOL)_interpretKeyEvent:(::WebEvent *)theEvent isCharEvent:(BOOL)isCharEvent;
279 - (void)_positionInformationDidChange:(const WebKit::InteractionInformationAtPosition&)info;
280 - (void)_attemptClickAtLocation:(CGPoint)location;
281 - (void)_willStartScrollingOrZooming;
282 - (void)_didScroll;
283 - (void)_didEndScrollingOrZooming;
284 - (void)_overflowScrollingWillBegin;
285 - (void)_overflowScrollingDidEnd;
286 - (void)_didUpdateBlockSelectionWithTouch:(WebKit::SelectionTouch)touch withFlags:(WebKit::SelectionFlags)flags growThreshold:(CGFloat)growThreshold shrinkThreshold:(CGFloat)shrinkThreshold;
287 - (void)_showPlaybackTargetPicker:(BOOL)hasVideo fromRect:(const WebCore::IntRect&)elementRect;
288 - (void)_showRunOpenPanel:(API::OpenPanelParameters*)parameters resultListener:(WebKit::WebOpenPanelResultListenerProxy*)listener;
289 - (void)accessoryDone;
290 - (void)_didHandleKeyEvent:(::WebEvent *)event eventWasHandled:(BOOL)eventWasHandled;
291 - (Vector<WebKit::OptionItem>&) assistedNodeSelectOptions;
292 - (void)_enableInspectorNodeSearch;
293 - (void)_disableInspectorNodeSearch;
294 - (void)_becomeFirstResponderWithSelectionMovingForward:(BOOL)selectingForward completionHandler:(void (^)(BOOL didBecomeFirstResponder))completionHandler;
295 - (void)_setDoubleTapGesturesEnabled:(BOOL)enabled;
296 #if ENABLE(DATA_DETECTION)
297 - (NSArray *)_dataDetectionResults;
298 #endif
299 - (NSArray<NSValue *> *)_uiTextSelectionRects;
300 - (void)accessibilityRetrieveSpeakSelectionContent;
301 - (void)_accessibilityRetrieveRectsEnclosingSelectionOffset:(NSInteger)offset withGranularity:(UITextGranularity)granularity;
302 - (void)_accessibilityRetrieveRectsAtSelectionOffset:(NSInteger)offset withText:(NSString *)text;
303
304 @property (nonatomic, readonly) WebKit::InteractionInformationAtPosition currentPositionInformation;
305 - (void)doAfterPositionInformationUpdate:(void (^)(WebKit::InteractionInformationAtPosition))action forRequest:(WebKit::InteractionInformationRequest)request;
306 - (void)ensurePositionInformationIsUpToDate:(WebKit::InteractionInformationRequest)request;
307
308 #if ENABLE(DATA_INTERACTION)
309 - (void)_didPerformDataInteractionControllerOperation:(BOOL)handled;
310 - (void)_didHandleStartDataInteractionRequest:(BOOL)started;
311 - (void)_startDataInteractionWithImage:(RetainPtr<CGImageRef>)image withIndicatorData:(std::optional<WebCore::TextIndicatorData>)indicatorData atClientPosition:(CGPoint)clientPosition anchorPoint:(CGPoint)anchorPoint action:(uint64_t)action;
312 - (void)_didConcludeEditDataInteraction:(std::optional<WebCore::TextIndicatorData>)data;
313 - (void)_didChangeDataInteractionCaretRect:(CGRect)previousRect currentRect:(CGRect)rect;
314
315 - (void)_simulateDataInteractionEntered:(id)info;
316 - (BOOL)_simulateDataInteractionUpdated:(id)info;
317 - (void)_simulateDataInteractionPerformOperation:(id)info;
318 - (void)_simulateDataInteractionEnded:(id)info;
319 - (void)_simulateDataInteractionSessionDidEnd:(id)session;
320 - (void)_simulateWillBeginDataInteractionWithSession:(id)session;
321 - (NSArray *)_simulatedItemsForSession:(id)session;
322 - (void)_simulatePrepareForDataInteractionSession:(id)session completion:(dispatch_block_t)completion;
323 #endif
324
325 @end
326
327 @interface WKContentView (WKTesting)
328
329 - (void)selectFormAccessoryPickerRow:(NSInteger)rowIndex;
330 - (NSDictionary *)_contentsOfUserInterfaceItem:(NSString *)userInterfaceItem;
331
332 @end
333
334 #if HAVE(LINK_PREVIEW)
335 @interface WKContentView (WKInteractionPreview) <UIPreviewItemDelegate>
336
337 - (void)_registerPreview;
338 - (void)_unregisterPreview;
339 @end
340 #endif
341
342 #endif // PLATFORM(IOS)