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