[LFC][IFC] Make InlineTextItem reusable when 'segment break' behavior changes
[WebKit-https.git] / Source / WebKit / UIProcess / ios / PageClientImplIOS.mm
1 /*
2  * Copyright (C) 2012-2016 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 "PageClientImplIOS.h"
28
29 #if PLATFORM(IOS_FAMILY)
30
31 #import "APIData.h"
32 #import "DataReference.h"
33 #import "DownloadProxy.h"
34 #import "DrawingAreaProxy.h"
35 #import "InteractionInformationAtPosition.h"
36 #import "NativeWebKeyboardEvent.h"
37 #import "NavigationState.h"
38 #import "StringUtilities.h"
39 #import "UIKitSPI.h"
40 #import "UndoOrRedo.h"
41 #import "ViewSnapshotStore.h"
42 #import "WKContentView.h"
43 #import "WKContentViewInteraction.h"
44 #import "WKDrawingView.h"
45 #import "WKEditCommand.h"
46 #import "WKGeolocationProviderIOS.h"
47 #import "WKPasswordView.h"
48 #import "WKProcessPoolInternal.h"
49 #import "WKWebViewConfigurationInternal.h"
50 #import "WKWebViewContentProviderRegistry.h"
51 #import "WKWebViewInternal.h"
52 #import "WebContextMenuProxy.h"
53 #import "WebDataListSuggestionsDropdownIOS.h"
54 #import "WebEditCommandProxy.h"
55 #import "WebProcessProxy.h"
56 #import "_WKDownloadInternal.h"
57 #import <WebCore/DOMPasteAccess.h>
58 #import <WebCore/DictionaryLookup.h>
59 #import <WebCore/NotImplemented.h>
60 #import <WebCore/PlatformScreen.h>
61 #import <WebCore/PromisedAttachmentInfo.h>
62 #import <WebCore/ShareData.h>
63 #import <WebCore/SharedBuffer.h>
64 #import <WebCore/TextIndicator.h>
65 #import <WebCore/ValidationBubble.h>
66 #import <pal/spi/cocoa/NSKeyedArchiverSPI.h>
67 #import <wtf/BlockPtr.h>
68
69 #define MESSAGE_CHECK(assertion) MESSAGE_CHECK_BASE(assertion, m_webView.get()->_page->process().connection())
70
71 namespace WebKit {
72 using namespace WebCore;
73
74 PageClientImpl::PageClientImpl(WKContentView *contentView, WKWebView *webView)
75     : PageClientImplCocoa(webView)
76     , m_contentView(contentView)
77     , m_undoTarget(adoptNS([[WKEditorUndoTarget alloc] init]))
78 {
79 }
80
81 PageClientImpl::~PageClientImpl()
82 {
83 }
84
85 std::unique_ptr<DrawingAreaProxy> PageClientImpl::createDrawingAreaProxy(WebProcessProxy& process)
86 {
87     return [m_contentView _createDrawingAreaProxy:process];
88 }
89
90 void PageClientImpl::setViewNeedsDisplay(const Region&)
91 {
92     ASSERT_NOT_REACHED();
93 }
94
95 void PageClientImpl::requestScroll(const FloatPoint& scrollPosition, const IntPoint& scrollOrigin)
96 {
97     [m_webView _scrollToContentScrollPosition:scrollPosition scrollOrigin:scrollOrigin];
98 }
99
100 WebCore::FloatPoint PageClientImpl::viewScrollPosition()
101 {
102     if (UIScrollView *scroller = [m_contentView _scroller])
103         return scroller.contentOffset;
104
105     return { };
106 }
107
108 IntSize PageClientImpl::viewSize()
109 {
110     if (UIScrollView *scroller = [m_contentView _scroller])
111         return IntSize(scroller.bounds.size);
112
113     return IntSize(m_contentView.bounds.size);
114 }
115
116 bool PageClientImpl::isViewWindowActive()
117 {
118     // FIXME: https://bugs.webkit.org/show_bug.cgi?id=133098
119     return isViewVisible() || [m_webView _isRetainingActiveFocusedState];
120 }
121
122 bool PageClientImpl::isViewFocused()
123 {
124     return (isViewInWindow() && ![m_webView _isBackground] && [m_webView _contentViewIsFirstResponder]) || [m_webView _isRetainingActiveFocusedState];
125 }
126
127 bool PageClientImpl::isViewVisible()
128 {
129     if (isViewInWindow() && ![m_webView _isBackground])
130         return true;
131     
132     if ([m_webView _isShowingVideoPictureInPicture])
133         return true;
134     
135     if ([m_webView _mayAutomaticallyShowVideoPictureInPicture])
136         return true;
137     
138     return false;
139 }
140
141 bool PageClientImpl::isViewInWindow()
142 {
143     // FIXME: in WebKitTestRunner, m_webView is nil, so check the content view instead.
144     if (auto webView = m_webView.get())
145         return [webView window];
146
147     return [m_contentView window];
148 }
149
150 bool PageClientImpl::isViewVisibleOrOccluded()
151 {
152     return isViewVisible();
153 }
154
155 bool PageClientImpl::isVisuallyIdle()
156 {
157     return !isViewVisible();
158 }
159
160 void PageClientImpl::processDidExit()
161 {
162     [m_contentView _processDidExit];
163     [m_webView _processDidExit];
164 }
165
166 void PageClientImpl::processWillSwap()
167 {
168     [m_contentView _processWillSwap];
169     [m_webView _processWillSwap];
170 }
171
172 void PageClientImpl::didRelaunchProcess()
173 {
174     [m_contentView _didRelaunchProcess];
175     [m_webView _didRelaunchProcess];
176 }
177
178 #if HAVE(VISIBILITY_PROPAGATION_VIEW)
179 void PageClientImpl::didCreateContextForVisibilityPropagation(LayerHostingContextID)
180 {
181     [m_contentView _processDidCreateContextForVisibilityPropagation];
182 }
183 #endif
184
185 void PageClientImpl::pageClosed()
186 {
187     notImplemented();
188 }
189
190 void PageClientImpl::preferencesDidChange()
191 {
192     notImplemented();
193 }
194
195 void PageClientImpl::toolTipChanged(const String&, const String&)
196 {
197     notImplemented();
198 }
199
200 void PageClientImpl::didNotHandleTapAsClick(const WebCore::IntPoint& point)
201 {
202     [m_contentView _didNotHandleTapAsClick:point];
203 }
204     
205 void PageClientImpl::didCompleteSyntheticClick()
206 {
207     [m_contentView _didCompleteSyntheticClick];
208 }
209
210 void PageClientImpl::decidePolicyForGeolocationPermissionRequest(WebFrameProxy& frame, API::SecurityOrigin& origin, Function<void(bool)>& completionHandler)
211 {
212     [[wrapper(m_webView.get()->_page->process().processPool()) _geolocationProvider] decidePolicyForGeolocationRequestFromOrigin:origin.securityOrigin() frame:frame completionHandler:std::exchange(completionHandler, nullptr) view:m_webView.get().get()];
213 }
214
215 void PageClientImpl::didStartProvisionalLoadForMainFrame()
216 {
217     [m_webView _didStartProvisionalLoadForMainFrame];
218     [m_contentView _didStartProvisionalLoadForMainFrame];
219     [m_webView _hidePasswordView];
220 }
221
222 void PageClientImpl::didFailProvisionalLoadForMainFrame()
223 {
224     [m_webView _hidePasswordView];
225 }
226
227 void PageClientImpl::didCommitLoadForMainFrame(const String& mimeType, bool useCustomContentProvider)
228 {
229     [m_webView _hidePasswordView];
230     [m_webView _setHasCustomContentView:useCustomContentProvider loadedMIMEType:mimeType];
231     [m_contentView _didCommitLoadForMainFrame];
232 }
233
234 void PageClientImpl::handleDownloadRequest(DownloadProxy&)
235 {
236 }
237
238 void PageClientImpl::didChangeContentSize(const WebCore::IntSize&)
239 {
240     notImplemented();
241 }
242
243 void PageClientImpl::disableDoubleTapGesturesDuringTapIfNecessary(uint64_t requestID)
244 {
245     [m_contentView _disableDoubleTapGesturesDuringTapIfNecessary:requestID];
246 }
247
248 void PageClientImpl::handleSmartMagnificationInformationForPotentialTap(uint64_t requestID, const WebCore::FloatRect& renderRect, bool fitEntireRect, double viewportMinimumScale, double viewportMaximumScale)
249 {
250     [m_contentView _handleSmartMagnificationInformationForPotentialTap:requestID renderRect:renderRect fitEntireRect:fitEntireRect viewportMinimumScale:viewportMinimumScale viewportMaximumScale:viewportMaximumScale];
251 }
252
253 double PageClientImpl::minimumZoomScale() const
254 {
255     if (UIScrollView *scroller = [m_webView scrollView])
256         return scroller.minimumZoomScale;
257
258     return 1;
259 }
260
261 WebCore::FloatRect PageClientImpl::documentRect() const
262 {
263     return [m_contentView bounds];
264 }
265
266 void PageClientImpl::setCursor(const Cursor&)
267 {
268     notImplemented();
269 }
270
271 void PageClientImpl::setCursorHiddenUntilMouseMoves(bool)
272 {
273     notImplemented();
274 }
275
276 void PageClientImpl::didChangeViewportProperties(const ViewportAttributes&)
277 {
278     notImplemented();
279 }
280
281 void PageClientImpl::registerEditCommand(Ref<WebEditCommandProxy>&& command, UndoOrRedo undoOrRedo)
282 {
283     auto actionName = command->label();
284     auto commandObjC = adoptNS([[WKEditCommand alloc] initWithWebEditCommandProxy:WTFMove(command)]);
285     
286     NSUndoManager *undoManager = [m_contentView undoManager];
287     [undoManager registerUndoWithTarget:m_undoTarget.get() selector:((undoOrRedo == UndoOrRedo::Undo) ? @selector(undoEditing:) : @selector(redoEditing:)) object:commandObjC.get()];
288     if (!actionName.isEmpty())
289         [undoManager setActionName:(NSString *)actionName];
290 }
291
292 #if USE(INSERTION_UNDO_GROUPING)
293 void PageClientImpl::registerInsertionUndoGrouping()
294 {
295     notImplemented();
296 }
297 #endif
298
299 void PageClientImpl::clearAllEditCommands()
300 {
301     [[m_contentView undoManager] removeAllActionsWithTarget:m_undoTarget.get()];
302 }
303
304 bool PageClientImpl::canUndoRedo(UndoOrRedo undoOrRedo)
305 {
306     return (undoOrRedo == UndoOrRedo::Undo) ? [[m_contentView undoManager] canUndo] : [[m_contentView undoManager] canRedo];
307 }
308
309 void PageClientImpl::executeUndoRedo(UndoOrRedo undoOrRedo)
310 {
311     return (undoOrRedo == UndoOrRedo::Undo) ? [[m_contentView undoManager] undo] : [[m_contentView undoManager] redo];
312 }
313
314 void PageClientImpl::accessibilityWebProcessTokenReceived(const IPC::DataReference& data)
315 {
316     NSData *remoteToken = [NSData dataWithBytes:data.data() length:data.size()];
317     [m_contentView _setAccessibilityWebProcessToken:remoteToken];
318 }
319
320 bool PageClientImpl::interpretKeyEvent(const NativeWebKeyboardEvent& event, bool isCharEvent)
321 {
322     return [m_contentView _interpretKeyEvent:event.nativeEvent() isCharEvent:isCharEvent];
323 }
324
325 void PageClientImpl::positionInformationDidChange(const InteractionInformationAtPosition& info)
326 {
327     [m_contentView _positionInformationDidChange:info];
328 }
329
330 void PageClientImpl::saveImageToLibrary(Ref<SharedBuffer>&& imageBuffer)
331 {
332     RetainPtr<NSData> imageData = imageBuffer->createNSData();
333     UIImageDataWriteToSavedPhotosAlbum(imageData.get(), nil, NULL, NULL);
334 }
335
336 bool PageClientImpl::executeSavedCommandBySelector(const String&)
337 {
338     notImplemented();
339     return false;
340 }
341
342 void PageClientImpl::selectionDidChange()
343 {
344     [m_contentView _selectionChanged];
345 }
346
347 void PageClientImpl::updateSecureInputState()
348 {
349     notImplemented();
350 }
351
352 void PageClientImpl::resetSecureInputState()
353 {
354     notImplemented();
355 }
356
357 void PageClientImpl::notifyInputContextAboutDiscardedComposition()
358 {
359     notImplemented();
360 }
361
362 void PageClientImpl::assistiveTechnologyMakeFirstResponder()
363 {
364     notImplemented();
365 }
366
367 void PageClientImpl::makeFirstResponder()
368 {
369     notImplemented();
370 }
371
372 FloatRect PageClientImpl::convertToDeviceSpace(const FloatRect& rect)
373 {
374     return rect;
375 }
376
377 FloatRect PageClientImpl::convertToUserSpace(const FloatRect& rect)
378 {
379     return rect;
380 }
381
382 IntPoint PageClientImpl::screenToRootView(const IntPoint& point)
383 {
384     return IntPoint([m_contentView convertPoint:point fromView:nil]);
385 }
386
387 IntRect PageClientImpl::rootViewToScreen(const IntRect& rect)
388 {
389     return enclosingIntRect([m_contentView convertRect:rect toView:nil]);
390 }
391     
392 IntPoint PageClientImpl::accessibilityScreenToRootView(const IntPoint& point)
393 {
394     CGPoint rootViewPoint = point;
395     if ([m_contentView respondsToSelector:@selector(accessibilityConvertPointFromSceneReferenceCoordinates:)])
396         rootViewPoint = [m_contentView accessibilityConvertPointFromSceneReferenceCoordinates:rootViewPoint];
397     return IntPoint(rootViewPoint);
398 }
399     
400 IntRect PageClientImpl::rootViewToAccessibilityScreen(const IntRect& rect)
401 {
402     CGRect rootViewRect = rect;
403     if ([m_contentView respondsToSelector:@selector(accessibilityConvertRectToSceneReferenceCoordinates:)])
404         rootViewRect = [m_contentView accessibilityConvertRectToSceneReferenceCoordinates:rootViewRect];
405     return enclosingIntRect(rootViewRect);
406 }
407     
408 void PageClientImpl::doneWithKeyEvent(const NativeWebKeyboardEvent& event, bool eventWasHandled)
409 {
410     [m_contentView _didHandleKeyEvent:event.nativeEvent() eventWasHandled:eventWasHandled];
411 }
412
413 #if ENABLE(TOUCH_EVENTS)
414 void PageClientImpl::doneWithTouchEvent(const NativeWebTouchEvent& nativeWebtouchEvent, bool eventHandled)
415 {
416     [m_contentView _webTouchEvent:nativeWebtouchEvent preventsNativeGestures:eventHandled];
417 }
418 #endif
419
420 RefPtr<WebPopupMenuProxy> PageClientImpl::createPopupMenuProxy(WebPageProxy&)
421 {
422     return nullptr;
423 }
424
425 void PageClientImpl::setTextIndicator(Ref<TextIndicator> textIndicator, TextIndicatorWindowLifetime)
426 {
427 }
428
429 void PageClientImpl::clearTextIndicator(TextIndicatorWindowDismissalAnimation)
430 {
431 }
432
433 void PageClientImpl::setTextIndicatorAnimationProgress(float)
434 {
435 }
436
437 void PageClientImpl::enterAcceleratedCompositingMode(const LayerTreeContext& layerTreeContext)
438 {
439 }
440
441 void PageClientImpl::showSafeBrowsingWarning(const SafeBrowsingWarning& warning, CompletionHandler<void(Variant<WebKit::ContinueUnsafeLoad, URL>&&)>&& completionHandler)
442 {
443     if (auto webView = m_webView.get())
444         [webView _showSafeBrowsingWarning:warning completionHandler:WTFMove(completionHandler)];
445     else
446         completionHandler(ContinueUnsafeLoad::No);
447 }
448
449 void PageClientImpl::clearSafeBrowsingWarning()
450 {
451     [m_webView _clearSafeBrowsingWarning];
452 }
453
454 void PageClientImpl::clearSafeBrowsingWarningIfForMainFrameNavigation()
455 {
456     [m_webView _clearSafeBrowsingWarningIfForMainFrameNavigation];
457 }
458
459 void PageClientImpl::exitAcceleratedCompositingMode()
460 {
461     notImplemented();
462 }
463
464 void PageClientImpl::updateAcceleratedCompositingMode(const LayerTreeContext&)
465 {
466 }
467
468 void PageClientImpl::didPerformDictionaryLookup(const DictionaryPopupInfo& dictionaryPopupInfo)
469 {
470 #if ENABLE(REVEAL)
471     DictionaryLookup::showPopup(dictionaryPopupInfo, m_contentView, nullptr);
472 #else
473     UNUSED_PARAM(dictionaryPopupInfo);
474 #endif // ENABLE(REVEAL)
475 }
476
477 bool PageClientImpl::effectiveAppearanceIsDark() const
478 {
479     return [m_webView _effectiveAppearanceIsDark];
480 }
481
482 bool PageClientImpl::effectiveUserInterfaceLevelIsElevated() const
483 {
484     return [m_webView _effectiveUserInterfaceLevelIsElevated];
485 }
486
487 void PageClientImpl::setRemoteLayerTreeRootNode(RemoteLayerTreeNode* rootNode)
488 {
489     [m_contentView _setAcceleratedCompositingRootView:rootNode ? rootNode->uiView() : nil];
490 }
491
492 CALayer *PageClientImpl::acceleratedCompositingRootLayer() const
493 {
494     notImplemented();
495     return nullptr;
496 }
497
498 RefPtr<ViewSnapshot> PageClientImpl::takeViewSnapshot()
499 {
500     return [m_webView _takeViewSnapshot];
501 }
502
503 void PageClientImpl::wheelEventWasNotHandledByWebCore(const NativeWebWheelEvent& event)
504 {
505     notImplemented();
506 }
507
508 void PageClientImpl::commitPotentialTapFailed()
509 {
510     [m_contentView _commitPotentialTapFailed];
511 }
512
513 void PageClientImpl::didGetTapHighlightGeometries(uint64_t requestID, const WebCore::Color& color, const Vector<WebCore::FloatQuad>& highlightedQuads, const WebCore::IntSize& topLeftRadius, const WebCore::IntSize& topRightRadius, const WebCore::IntSize& bottomLeftRadius, const WebCore::IntSize& bottomRightRadius, bool nodeHasBuiltInClickHandling)
514 {
515     [m_contentView _didGetTapHighlightForRequest:requestID color:color quads:highlightedQuads topLeftRadius:topLeftRadius topRightRadius:topRightRadius bottomLeftRadius:bottomLeftRadius bottomRightRadius:bottomRightRadius nodeHasBuiltInClickHandling:nodeHasBuiltInClickHandling];
516 }
517
518 void PageClientImpl::didCommitLayerTree(const RemoteLayerTreeTransaction& layerTreeTransaction)
519 {
520     [m_contentView _didCommitLayerTree:layerTreeTransaction];
521 }
522
523 void PageClientImpl::layerTreeCommitComplete()
524 {
525     [m_contentView _layerTreeCommitComplete];
526 }
527
528 void PageClientImpl::couldNotRestorePageState()
529 {
530     [m_webView _couldNotRestorePageState];
531 }
532
533 void PageClientImpl::restorePageState(Optional<WebCore::FloatPoint> scrollPosition, const WebCore::FloatPoint& scrollOrigin, const WebCore::FloatBoxExtent& obscuredInsetsOnSave, double scale)
534 {
535     [m_webView _restorePageScrollPosition:scrollPosition scrollOrigin:scrollOrigin previousObscuredInset:obscuredInsetsOnSave scale:scale];
536 }
537
538 void PageClientImpl::restorePageCenterAndScale(Optional<WebCore::FloatPoint> center, double scale)
539 {
540     [m_webView _restorePageStateToUnobscuredCenter:center scale:scale];
541 }
542
543 void PageClientImpl::elementDidFocus(const FocusedElementInformation& nodeInformation, bool userIsInteracting, bool blurPreviousNode, OptionSet<WebCore::ActivityState::Flag> activityStateChanges, API::Object* userData)
544 {
545     MESSAGE_CHECK(!userData || userData->type() == API::Object::Type::Data);
546
547     NSObject <NSSecureCoding> *userObject = nil;
548     if (API::Data* data = static_cast<API::Data*>(userData)) {
549         auto nsData = adoptNS([[NSData alloc] initWithBytesNoCopy:const_cast<void*>(static_cast<const void*>(data->bytes())) length:data->size() freeWhenDone:NO]);
550         auto unarchiver = secureUnarchiverFromData(nsData.get());
551         @try {
552             userObject = [unarchiver decodeObjectOfClass:[NSObject class] forKey:@"userObject"];
553         } @catch (NSException *exception) {
554             LOG_ERROR("Failed to decode user data: %@", exception);
555         }
556     }
557
558     [m_contentView _elementDidFocus:nodeInformation userIsInteracting:userIsInteracting blurPreviousNode:blurPreviousNode activityStateChanges:activityStateChanges userObject:userObject];
559 }
560
561 void PageClientImpl::updateInputContextAfterBlurringAndRefocusingElement()
562 {
563     [m_contentView _updateInputContextAfterBlurringAndRefocusingElement];
564 }
565
566 bool PageClientImpl::isFocusingElement()
567 {
568     return [m_contentView isFocusingElement];
569 }
570
571 void PageClientImpl::elementDidBlur()
572 {
573     [m_contentView _elementDidBlur];
574 }
575
576 void PageClientImpl::focusedElementDidChangeInputMode(WebCore::InputMode mode)
577 {
578     [m_contentView _didUpdateInputMode:mode];
579 }
580
581 void PageClientImpl::didReceiveEditorStateUpdateAfterFocus()
582 {
583     [m_contentView _didReceiveEditorStateUpdateAfterFocus];
584 }
585
586 void PageClientImpl::showPlaybackTargetPicker(bool hasVideo, const IntRect& elementRect, WebCore::RouteSharingPolicy policy, const String& contextUID)
587 {
588     [m_contentView _showPlaybackTargetPicker:hasVideo fromRect:elementRect routeSharingPolicy:policy routingContextUID:contextUID];
589 }
590
591 bool PageClientImpl::handleRunOpenPanel(WebPageProxy*, WebFrameProxy*, API::OpenPanelParameters* parameters, WebOpenPanelResultListenerProxy* listener)
592 {
593     [m_contentView _showRunOpenPanel:parameters resultListener:listener];
594     return true;
595 }
596
597 bool PageClientImpl::showShareSheet(const ShareDataWithParsedURL& shareData, WTF::CompletionHandler<void(bool)>&& completionHandler)
598 {
599     [m_contentView _showShareSheet:shareData inRect:WTF::nullopt completionHandler:WTFMove(completionHandler)];
600     return true;
601 }
602
603 void PageClientImpl::showInspectorHighlight(const WebCore::Highlight& highlight)
604 {
605     [m_contentView _showInspectorHighlight:highlight];
606 }
607
608 void PageClientImpl::hideInspectorHighlight()
609 {
610     [m_contentView _hideInspectorHighlight];
611 }
612
613 void PageClientImpl::showInspectorIndication()
614 {
615     [m_contentView setShowingInspectorIndication:YES];
616 }
617
618 void PageClientImpl::hideInspectorIndication()
619 {
620     [m_contentView setShowingInspectorIndication:NO];
621 }
622
623 void PageClientImpl::enableInspectorNodeSearch()
624 {
625     [m_contentView _enableInspectorNodeSearch];
626 }
627
628 void PageClientImpl::disableInspectorNodeSearch()
629 {
630     [m_contentView _disableInspectorNodeSearch];
631 }
632
633 #if ENABLE(FULLSCREEN_API)
634
635 WebFullScreenManagerProxyClient& PageClientImpl::fullScreenManagerProxyClient()
636 {
637     return *this;
638 }
639
640 // WebFullScreenManagerProxyClient
641
642 void PageClientImpl::closeFullScreenManager()
643 {
644     [m_webView closeFullScreenWindowController];
645 }
646
647 bool PageClientImpl::isFullScreen()
648 {
649     if (![m_webView hasFullScreenWindowController])
650         return false;
651
652     return [m_webView fullScreenWindowController].isFullScreen;
653 }
654
655 void PageClientImpl::enterFullScreen()
656 {
657     [[m_webView fullScreenWindowController] enterFullScreen];
658 }
659
660 void PageClientImpl::exitFullScreen()
661 {
662     [[m_webView fullScreenWindowController] exitFullScreen];
663 }
664
665 void PageClientImpl::beganEnterFullScreen(const IntRect& initialFrame, const IntRect& finalFrame)
666 {
667     [[m_webView fullScreenWindowController] beganEnterFullScreenWithInitialFrame:initialFrame finalFrame:finalFrame];
668 }
669
670 void PageClientImpl::beganExitFullScreen(const IntRect& initialFrame, const IntRect& finalFrame)
671 {
672     [[m_webView fullScreenWindowController] beganExitFullScreenWithInitialFrame:initialFrame finalFrame:finalFrame];
673 }
674
675 #endif // ENABLE(FULLSCREEN_API)
676
677 void PageClientImpl::didFinishLoadingDataForCustomContentProvider(const String& suggestedFilename, const IPC::DataReference& dataReference)
678 {
679     RetainPtr<NSData> data = adoptNS([[NSData alloc] initWithBytes:dataReference.data() length:dataReference.size()]);
680     [m_webView _didFinishLoadingDataForCustomContentProviderWithSuggestedFilename:suggestedFilename data:data.get()];
681 }
682
683 void PageClientImpl::scrollingNodeScrollViewWillStartPanGesture()
684 {
685     [m_contentView scrollViewWillStartPanOrPinchGesture];
686 }
687
688 void PageClientImpl::scrollingNodeScrollViewDidScroll()
689 {
690     [m_contentView _didScroll];
691 }
692
693 void PageClientImpl::scrollingNodeScrollWillStartScroll()
694 {
695     [m_contentView _scrollingNodeScrollingWillBegin];
696 }
697
698 void PageClientImpl::scrollingNodeScrollDidEndScroll()
699 {
700     [m_contentView _scrollingNodeScrollingDidEnd];
701 }
702
703 Vector<String> PageClientImpl::mimeTypesWithCustomContentProviders()
704 {
705     return [m_webView _contentProviderRegistry]._mimeTypesWithCustomContentProviders;
706 }
707
708 void PageClientImpl::navigationGestureDidBegin()
709 {
710     [m_webView _navigationGestureDidBegin];
711     NavigationState::fromWebPage(*m_webView.get()->_page).navigationGestureDidBegin();
712 }
713
714 void PageClientImpl::navigationGestureWillEnd(bool willNavigate, WebBackForwardListItem& item)
715 {
716     NavigationState::fromWebPage(*m_webView.get()->_page).navigationGestureWillEnd(willNavigate, item);
717 }
718
719 void PageClientImpl::navigationGestureDidEnd(bool willNavigate, WebBackForwardListItem& item)
720 {
721     NavigationState::fromWebPage(*m_webView.get()->_page).navigationGestureDidEnd(willNavigate, item);
722     [m_webView _navigationGestureDidEnd];
723 }
724
725 void PageClientImpl::navigationGestureDidEnd()
726 {
727     [m_webView _navigationGestureDidEnd];
728 }
729
730 void PageClientImpl::willRecordNavigationSnapshot(WebBackForwardListItem& item)
731 {
732     NavigationState::fromWebPage(*m_webView.get()->_page).willRecordNavigationSnapshot(item);
733 }
734
735 void PageClientImpl::didRemoveNavigationGestureSnapshot()
736 {
737     NavigationState::fromWebPage(*m_webView.get()->_page).navigationGestureSnapshotWasRemoved();
738 }
739
740 void PageClientImpl::didFirstVisuallyNonEmptyLayoutForMainFrame()
741 {
742 }
743
744 void PageClientImpl::didFinishLoadForMainFrame()
745 {
746     [m_webView _didFinishLoadForMainFrame];
747 }
748
749 void PageClientImpl::didFailLoadForMainFrame()
750 {
751     [m_webView _didFailLoadForMainFrame];
752 }
753
754 void PageClientImpl::didSameDocumentNavigationForMainFrame(SameDocumentNavigationType navigationType)
755 {
756     [m_webView _didSameDocumentNavigationForMainFrame:navigationType];
757 }
758
759 void PageClientImpl::didChangeBackgroundColor()
760 {
761     [m_webView _updateScrollViewBackground];
762 }
763
764 void PageClientImpl::videoControlsManagerDidChange()
765 {
766     [m_webView _videoControlsManagerDidChange];
767 }
768
769 void PageClientImpl::refView()
770 {
771     [m_contentView retain];
772     [m_webView retain];
773 }
774
775 void PageClientImpl::derefView()
776 {
777     [m_contentView release];
778     [m_webView release];
779 }
780
781 void PageClientImpl::didRestoreScrollPosition()
782 {
783 }
784
785 WebCore::UserInterfaceLayoutDirection PageClientImpl::userInterfaceLayoutDirection()
786 {
787     if (!m_webView)
788         return WebCore::UserInterfaceLayoutDirection::LTR;
789     return ([UIView userInterfaceLayoutDirectionForSemanticContentAttribute:[m_webView semanticContentAttribute]] == UIUserInterfaceLayoutDirectionLeftToRight) ? WebCore::UserInterfaceLayoutDirection::LTR : WebCore::UserInterfaceLayoutDirection::RTL;
790 }
791
792 Ref<ValidationBubble> PageClientImpl::createValidationBubble(const String& message, const ValidationBubble::Settings& settings)
793 {
794     return ValidationBubble::create(m_contentView, message, settings);
795 }
796
797 #if ENABLE(INPUT_TYPE_COLOR)
798 RefPtr<WebColorPicker> PageClientImpl::createColorPicker(WebPageProxy*, const WebCore::Color& initialColor, const WebCore::IntRect&, Vector<WebCore::Color>&&)
799 {
800     return nullptr;
801 }
802 #endif
803
804 #if ENABLE(DATALIST_ELEMENT)
805 RefPtr<WebDataListSuggestionsDropdown> PageClientImpl::createDataListSuggestionsDropdown(WebPageProxy& page)
806 {
807     return WebDataListSuggestionsDropdownIOS::create(page, m_contentView);
808 }
809 #endif
810
811 #if ENABLE(DATA_INTERACTION)
812 void PageClientImpl::didPerformDragOperation(bool handled)
813 {
814     [m_contentView _didPerformDragOperation:handled];
815 }
816
817 void PageClientImpl::didHandleDragStartRequest(bool started)
818 {
819     [m_contentView _didHandleDragStartRequest:started];
820 }
821
822 void PageClientImpl::didHandleAdditionalDragItemsRequest(bool added)
823 {
824     [m_contentView _didHandleAdditionalDragItemsRequest:added];
825 }
826
827 void PageClientImpl::startDrag(const DragItem& item, const ShareableBitmap::Handle& image)
828 {
829     [m_contentView _startDrag:ShareableBitmap::create(image)->makeCGImageCopy() item:item];
830 }
831
832 void PageClientImpl::willReceiveEditDragSnapshot()
833 {
834     [m_contentView _willReceiveEditDragSnapshot];
835 }
836
837 void PageClientImpl::didReceiveEditDragSnapshot(Optional<TextIndicatorData> data)
838 {
839     [m_contentView _didReceiveEditDragSnapshot:data];
840 }
841
842 void PageClientImpl::didChangeDragCaretRect(const IntRect& previousCaretRect, const IntRect& caretRect)
843 {
844     [m_contentView _didChangeDragCaretRect:previousCaretRect currentRect:caretRect];
845 }
846 #endif
847
848 #if USE(QUICK_LOOK)
849 void PageClientImpl::requestPasswordForQuickLookDocument(const String& fileName, WTF::Function<void(const String&)>&& completionHandler)
850 {
851     auto passwordHandler = makeBlockPtr([completionHandler = WTFMove(completionHandler)](NSString *password) {
852         completionHandler(password);
853     });
854
855     if (WKPasswordView *passwordView = [m_webView _passwordView]) {
856         ASSERT(fileName == String { passwordView.documentName });
857         [passwordView showPasswordFailureAlert];
858         passwordView.userDidEnterPassword = passwordHandler.get();
859         return;
860     }
861
862     [m_webView _showPasswordViewWithDocumentName:fileName passwordHandler:passwordHandler.get()];
863     NavigationState::fromWebPage(*m_webView.get()->_page).didRequestPasswordForQuickLookDocument();
864 }
865 #endif
866
867 void PageClientImpl::requestDOMPasteAccess(const WebCore::IntRect& elementRect, const String& originIdentifier, CompletionHandler<void(WebCore::DOMPasteAccessResponse)>&& completionHandler)
868 {
869     [m_contentView _requestDOMPasteAccessWithElementRect:elementRect originIdentifier:originIdentifier completionHandler:WTFMove(completionHandler)];
870 }
871
872 #if HAVE(PENCILKIT)
873 RetainPtr<WKDrawingView> PageClientImpl::createDrawingView(WebCore::GraphicsLayer::EmbeddedViewID embeddedViewID)
874 {
875     return adoptNS([[WKDrawingView alloc] initWithEmbeddedViewID:embeddedViewID contentView:m_contentView]);
876 }
877 #endif
878
879 #if ENABLE(POINTER_EVENTS)
880 void PageClientImpl::cancelPointersForGestureRecognizer(UIGestureRecognizer* gestureRecognizer)
881 {
882     [m_contentView cancelPointersForGestureRecognizer:gestureRecognizer];
883 }
884
885 WTF::Optional<unsigned> PageClientImpl::activeTouchIdentifierForGestureRecognizer(UIGestureRecognizer* gestureRecognizer)
886 {
887     return [m_contentView activeTouchIdentifierForGestureRecognizer:gestureRecognizer];
888 }
889 #endif
890
891 void PageClientImpl::handleAutocorrectionContext(const WebAutocorrectionContext& context)
892 {
893     [m_contentView _handleAutocorrectionContext:context];
894 }
895
896 } // namespace WebKit
897
898 #endif // PLATFORM(IOS_FAMILY)
899
900 #undef MESSAGE_CHECK