f4918b67ec127c43642fbecfa0ca00c13d3a716d
[WebKit-https.git] / Source / WebKit2 / UIProcess / ios / PageClientImplIOS.mm
1 /*
2  * Copyright (C) 2012, 2013 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)
30
31 #import "APIData.h"
32 #import "DataReference.h"
33 #import "DownloadProxy.h"
34 #import "InteractionInformationAtPosition.h"
35 #import "NativeWebKeyboardEvent.h"
36 #import "NavigationState.h"
37 #import "UIKitSPI.h"
38 #import "ViewSnapshotStore.h"
39 #import "WKContentView.h"
40 #import "WKContentViewInteraction.h"
41 #import "WKGeolocationProviderIOS.h"
42 #import "WKProcessPoolInternal.h"
43 #import "WKViewPrivate.h"
44 #import "WKWebViewConfigurationInternal.h"
45 #import "WKWebViewContentProviderRegistry.h"
46 #import "WKWebViewInternal.h"
47 #import "WebContextMenuProxy.h"
48 #import "WebEditCommandProxy.h"
49 #import "WebProcessProxy.h"
50 #import "_WKDownloadInternal.h"
51 #import <WebCore/NotImplemented.h>
52 #import <WebCore/PlatformScreen.h>
53 #import <WebCore/SharedBuffer.h>
54 #import <WebCore/TextIndicator.h>
55
56 #define MESSAGE_CHECK(assertion) MESSAGE_CHECK_BASE(assertion, m_webView->_page->process().connection())
57
58 using namespace WebCore;
59 using namespace WebKit;
60
61 @interface WKEditCommandObjC : NSObject
62 {
63     RefPtr<WebEditCommandProxy> m_command;
64 }
65 - (id)initWithWebEditCommandProxy:(PassRefPtr<WebEditCommandProxy>)command;
66 - (WebEditCommandProxy*)command;
67 @end
68
69 @interface WKEditorUndoTargetObjC : NSObject
70 - (void)undoEditing:(id)sender;
71 - (void)redoEditing:(id)sender;
72 @end
73
74 @implementation WKEditCommandObjC
75
76 - (id)initWithWebEditCommandProxy:(PassRefPtr<WebEditCommandProxy>)command
77 {
78     self = [super init];
79     if (!self)
80         return nil;
81     
82     m_command = command;
83     return self;
84 }
85
86 - (WebEditCommandProxy *)command
87 {
88     return m_command.get();
89 }
90
91 @end
92
93 @implementation WKEditorUndoTargetObjC
94
95 - (void)undoEditing:(id)sender
96 {
97     ASSERT([sender isKindOfClass:[WKEditCommandObjC class]]);
98     [sender command]->unapply();
99 }
100
101 - (void)redoEditing:(id)sender
102 {
103     ASSERT([sender isKindOfClass:[WKEditCommandObjC class]]);
104     [sender command]->reapply();
105 }
106
107 @end
108
109 namespace WebKit {
110
111 PageClientImpl::PageClientImpl(WKContentView *contentView, WKWebView *webView)
112     : m_contentView(contentView)
113     , m_webView(webView)
114     , m_wkView(nil)
115     , m_undoTarget(adoptNS([[WKEditorUndoTargetObjC alloc] init]))
116 {
117 }
118
119 PageClientImpl::PageClientImpl(WKContentView *contentView, WKView *wkView)
120     : m_contentView(contentView)
121     , m_webView(nil)
122     , m_wkView(wkView)
123     , m_undoTarget(adoptNS([[WKEditorUndoTargetObjC alloc] init]))
124 {
125 }
126
127 PageClientImpl::~PageClientImpl()
128 {
129 }
130
131 std::unique_ptr<DrawingAreaProxy> PageClientImpl::createDrawingAreaProxy()
132 {
133     return [m_contentView _createDrawingAreaProxy];
134 }
135
136 void PageClientImpl::setViewNeedsDisplay(const IntRect& rect)
137 {
138     ASSERT_NOT_REACHED();
139 }
140
141 void PageClientImpl::displayView()
142 {
143     ASSERT_NOT_REACHED();
144 }
145
146 bool PageClientImpl::canScrollView()
147 {
148     notImplemented();
149     return false;
150 }
151
152 void PageClientImpl::scrollView(const IntRect&, const IntSize&)
153 {
154     ASSERT_NOT_REACHED();
155 }
156
157 void PageClientImpl::requestScroll(const FloatPoint& scrollPosition, const IntPoint& scrollOrigin, bool isProgrammaticScroll)
158 {
159     UNUSED_PARAM(isProgrammaticScroll);
160     [m_webView _scrollToContentOffset:scrollPosition scrollOrigin:scrollOrigin];
161 }
162
163 IntSize PageClientImpl::viewSize()
164 {
165     if (UIScrollView *scroller = [m_contentView _scroller])
166         return IntSize(scroller.bounds.size);
167
168     return IntSize(m_contentView.bounds.size);
169 }
170
171 bool PageClientImpl::isViewWindowActive()
172 {
173     // FIXME: https://bugs.webkit.org/show_bug.cgi?id=133098
174     return isViewVisible() || (m_webView && m_webView->_activeFocusedStateRetainCount);
175 }
176
177 bool PageClientImpl::isViewFocused()
178 {
179     // FIXME: https://bugs.webkit.org/show_bug.cgi?id=133098
180     return isViewWindowActive() || (m_webView && m_webView->_activeFocusedStateRetainCount);
181 }
182
183 bool PageClientImpl::isViewVisible()
184 {
185     if (isViewInWindow() && !m_contentView.isBackground)
186         return true;
187     
188     if ([m_webView _isShowingVideoPictureInPicture])
189         return true;
190     
191     if ([m_webView _mayAutomaticallyShowVideoPictureInPicture])
192         return true;
193     
194     return false;
195 }
196
197 bool PageClientImpl::isViewInWindow()
198 {
199     // FIXME: in WebKitTestRunner, m_webView is nil, so check the content view instead.
200     if (m_webView)
201         return [m_webView window];
202
203     return [m_contentView window];
204 }
205
206 bool PageClientImpl::isViewVisibleOrOccluded()
207 {
208     return isViewVisible();
209 }
210
211 bool PageClientImpl::isVisuallyIdle()
212 {
213     return !isViewVisible();
214 }
215
216 void PageClientImpl::processDidExit()
217 {
218     [m_contentView _processDidExit];
219     [m_webView _processDidExit];
220 }
221
222 void PageClientImpl::didRelaunchProcess()
223 {
224     [m_contentView _didRelaunchProcess];
225     [m_webView _didRelaunchProcess];
226     [m_wkView _didRelaunchProcess];
227 }
228
229 void PageClientImpl::pageClosed()
230 {
231     notImplemented();
232 }
233
234 void PageClientImpl::preferencesDidChange()
235 {
236     notImplemented();
237 }
238
239 void PageClientImpl::toolTipChanged(const String&, const String&)
240 {
241     notImplemented();
242 }
243
244 bool PageClientImpl::decidePolicyForGeolocationPermissionRequest(WebFrameProxy& frame, API::SecurityOrigin& origin, GeolocationPermissionRequestProxy& request)
245 {
246     [[wrapper(m_webView->_page->process().processPool()) _geolocationProvider] decidePolicyForGeolocationRequestFromOrigin:origin.securityOrigin() frame:frame request:request view:m_webView];
247     return true;
248 }
249
250 void PageClientImpl::didCommitLoadForMainFrame(const String& mimeType, bool useCustomContentProvider)
251 {
252     [m_webView _setHasCustomContentView:useCustomContentProvider loadedMIMEType:mimeType];
253     [m_contentView _didCommitLoadForMainFrame];
254 }
255
256 void PageClientImpl::handleDownloadRequest(DownloadProxy* download)
257 {
258     ASSERT_ARG(download, download);
259     ASSERT([download->wrapper() isKindOfClass:[_WKDownload class]]);
260     [static_cast<_WKDownload *>(download->wrapper()) setOriginatingWebView:m_webView];
261 }
262
263 void PageClientImpl::didChangeContentSize(const WebCore::IntSize&)
264 {
265     notImplemented();
266 }
267
268 void PageClientImpl::didChangeViewportMetaTagWidth(float newWidth)
269 {
270     [m_webView _setViewportMetaTagWidth:newWidth];
271 }
272
273 double PageClientImpl::minimumZoomScale() const
274 {
275     if (UIScrollView *scroller = [m_webView scrollView])
276         return scroller.minimumZoomScale;
277
278     return 1;
279 }
280
281 WebCore::FloatRect PageClientImpl::documentRect() const
282 {
283     return [m_contentView bounds];
284 }
285
286 void PageClientImpl::setCursor(const Cursor&)
287 {
288     notImplemented();
289 }
290
291 void PageClientImpl::setCursorHiddenUntilMouseMoves(bool)
292 {
293     notImplemented();
294 }
295
296 void PageClientImpl::didChangeViewportProperties(const ViewportAttributes&)
297 {
298     notImplemented();
299 }
300
301 void PageClientImpl::registerEditCommand(PassRefPtr<WebEditCommandProxy> prpCommand, WebPageProxy::UndoOrRedo undoOrRedo)
302 {
303     RefPtr<WebEditCommandProxy> command = prpCommand;
304     
305     RetainPtr<WKEditCommandObjC> commandObjC = adoptNS([[WKEditCommandObjC alloc] initWithWebEditCommandProxy:command]);
306     String actionName = WebEditCommandProxy::nameForEditAction(command->editAction());
307     
308     NSUndoManager *undoManager = [m_contentView undoManager];
309     [undoManager registerUndoWithTarget:m_undoTarget.get() selector:((undoOrRedo == WebPageProxy::Undo) ? @selector(undoEditing:) : @selector(redoEditing:)) object:commandObjC.get()];
310     if (!actionName.isEmpty())
311         [undoManager setActionName:(NSString *)actionName];
312 }
313
314 #if USE(INSERTION_UNDO_GROUPING)
315 void PageClientImpl::registerInsertionUndoGrouping()
316 {
317     notImplemented();
318 }
319 #endif
320
321 void PageClientImpl::clearAllEditCommands()
322 {
323     [[m_contentView undoManager] removeAllActionsWithTarget:m_undoTarget.get()];
324 }
325
326 bool PageClientImpl::canUndoRedo(WebPageProxy::UndoOrRedo undoOrRedo)
327 {
328     return (undoOrRedo == WebPageProxy::Undo) ? [[m_contentView undoManager] canUndo] : [[m_contentView undoManager] canRedo];
329 }
330
331 void PageClientImpl::executeUndoRedo(WebPageProxy::UndoOrRedo undoOrRedo)
332 {
333     return (undoOrRedo == WebPageProxy::Undo) ? [[m_contentView undoManager] undo] : [[m_contentView undoManager] redo];
334 }
335
336 void PageClientImpl::accessibilityWebProcessTokenReceived(const IPC::DataReference& data)
337 {
338     NSData *remoteToken = [NSData dataWithBytes:data.data() length:data.size()];
339     [m_contentView _setAccessibilityWebProcessToken:remoteToken];
340 }
341
342 bool PageClientImpl::interpretKeyEvent(const NativeWebKeyboardEvent& event, bool isCharEvent)
343 {
344     return [m_contentView _interpretKeyEvent:event.nativeEvent() isCharEvent:isCharEvent];
345 }
346
347 void PageClientImpl::positionInformationDidChange(const InteractionInformationAtPosition& info)
348 {
349     [m_contentView _positionInformationDidChange:info];
350 }
351
352 void PageClientImpl::saveImageToLibrary(PassRefPtr<SharedBuffer> imageBuffer)
353 {
354     RetainPtr<NSData> imageData = imageBuffer->createNSData();
355     UIImageDataWriteToSavedPhotosAlbum(imageData.get(), nil, NULL, NULL);
356 }
357
358 bool PageClientImpl::executeSavedCommandBySelector(const String&)
359 {
360     notImplemented();
361     return false;
362 }
363
364 void PageClientImpl::setDragImage(const IntPoint&, PassRefPtr<ShareableBitmap>, bool)
365 {
366     notImplemented();
367 }
368
369 void PageClientImpl::selectionDidChange()
370 {
371     [m_contentView _selectionChanged];
372 }
373
374 void PageClientImpl::updateSecureInputState()
375 {
376     notImplemented();
377 }
378
379 void PageClientImpl::resetSecureInputState()
380 {
381     notImplemented();
382 }
383
384 void PageClientImpl::notifyInputContextAboutDiscardedComposition()
385 {
386     notImplemented();
387 }
388
389 void PageClientImpl::makeFirstResponder()
390 {
391     notImplemented();
392 }
393
394 FloatRect PageClientImpl::convertToDeviceSpace(const FloatRect& rect)
395 {
396     notImplemented();
397     return FloatRect();
398 }
399
400 FloatRect PageClientImpl::convertToUserSpace(const FloatRect& rect)
401 {
402     notImplemented();
403     return FloatRect();
404 }
405
406 IntPoint PageClientImpl::screenToRootView(const IntPoint& point)
407 {
408     return IntPoint([m_contentView convertPoint:point fromView:nil]);
409 }
410
411 IntRect PageClientImpl::rootViewToScreen(const IntRect& rect)
412 {
413     return enclosingIntRect([m_contentView convertRect:rect toView:nil]);
414 }
415     
416 IntPoint PageClientImpl::accessibilityScreenToRootView(const IntPoint& point)
417 {
418     CGPoint rootViewPoint = point;
419     if ([m_contentView respondsToSelector:@selector(accessibilityConvertPointFromSceneReferenceCoordinates:)])
420         rootViewPoint = [m_contentView accessibilityConvertPointFromSceneReferenceCoordinates:rootViewPoint];
421     return IntPoint(rootViewPoint);
422 }
423     
424 IntRect PageClientImpl::rootViewToAccessibilityScreen(const IntRect& rect)
425 {
426     CGRect rootViewRect = rect;
427     if ([m_contentView respondsToSelector:@selector(accessibilityConvertRectToSceneReferenceCoordinates:)])
428         rootViewRect = [m_contentView accessibilityConvertRectToSceneReferenceCoordinates:rootViewRect];
429     return enclosingIntRect(rootViewRect);
430 }
431     
432 void PageClientImpl::doneWithKeyEvent(const NativeWebKeyboardEvent& event, bool)
433 {
434     [m_contentView _didHandleKeyEvent:event.nativeEvent()];
435 }
436
437 #if ENABLE(TOUCH_EVENTS)
438 void PageClientImpl::doneWithTouchEvent(const NativeWebTouchEvent& nativeWebtouchEvent, bool eventHandled)
439 {
440     [m_contentView _webTouchEvent:nativeWebtouchEvent preventsNativeGestures:eventHandled];
441 }
442 #endif
443
444 RefPtr<WebPopupMenuProxy> PageClientImpl::createPopupMenuProxy(WebPageProxy*)
445 {
446     notImplemented();
447     return nullptr;
448 }
449
450 RefPtr<WebContextMenuProxy> PageClientImpl::createContextMenuProxy(WebPageProxy*)
451 {
452     notImplemented();
453     return nullptr;
454 }
455
456 void PageClientImpl::setTextIndicator(Ref<TextIndicator> textIndicator, TextIndicatorWindowLifetime)
457 {
458 }
459
460 void PageClientImpl::clearTextIndicator(TextIndicatorWindowDismissalAnimation)
461 {
462 }
463
464 void PageClientImpl::setTextIndicatorAnimationProgress(float)
465 {
466 }
467
468 void PageClientImpl::enterAcceleratedCompositingMode(const LayerTreeContext& layerTreeContext)
469 {
470 }
471
472 void PageClientImpl::exitAcceleratedCompositingMode()
473 {
474     notImplemented();
475 }
476
477 void PageClientImpl::updateAcceleratedCompositingMode(const LayerTreeContext&)
478 {
479 }
480
481 void PageClientImpl::setAcceleratedCompositingRootLayer(LayerOrView *rootLayer)
482 {
483     [m_contentView _setAcceleratedCompositingRootView:rootLayer];
484 }
485
486 LayerOrView *PageClientImpl::acceleratedCompositingRootLayer() const
487 {
488     notImplemented();
489     return nullptr;
490 }
491
492 PassRefPtr<ViewSnapshot> PageClientImpl::takeViewSnapshot()
493 {
494     return [m_webView _takeViewSnapshot];
495 }
496
497 void PageClientImpl::wheelEventWasNotHandledByWebCore(const NativeWebWheelEvent& event)
498 {
499     notImplemented();
500 }
501
502 void PageClientImpl::commitPotentialTapFailed()
503 {
504     [m_contentView _commitPotentialTapFailed];
505 }
506
507 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)
508 {
509     [m_contentView _didGetTapHighlightForRequest:requestID color:color quads:highlightedQuads topLeftRadius:topLeftRadius topRightRadius:topRightRadius bottomLeftRadius:bottomLeftRadius bottomRightRadius:bottomRightRadius];
510 }
511
512 void PageClientImpl::didCommitLayerTree(const RemoteLayerTreeTransaction& layerTreeTransaction)
513 {
514     [m_contentView _didCommitLayerTree:layerTreeTransaction];
515 }
516
517 void PageClientImpl::dynamicViewportUpdateChangedTarget(double newScale, const WebCore::FloatPoint& newScrollPosition, uint64_t nextValidLayerTreeTransactionID)
518 {
519     [m_webView _dynamicViewportUpdateChangedTargetToScale:newScale position:newScrollPosition nextValidLayerTreeTransactionID:nextValidLayerTreeTransactionID];
520 }
521
522 void PageClientImpl::couldNotRestorePageState()
523 {
524     [m_webView _couldNotRestorePageState];
525 }
526
527 void PageClientImpl::restorePageState(const WebCore::FloatRect& exposedRect, double scale)
528 {
529     [m_webView _restorePageStateToExposedRect:exposedRect scale:scale];
530 }
531
532 void PageClientImpl::restorePageCenterAndScale(const WebCore::FloatPoint& center, double scale)
533 {
534     [m_webView _restorePageStateToUnobscuredCenter:center scale:scale];
535 }
536
537 void PageClientImpl::startAssistingNode(const AssistedNodeInformation& nodeInformation, bool userIsInteracting, bool blurPreviousNode, API::Object* userData)
538 {
539     MESSAGE_CHECK(!userData || userData->type() == API::Object::Type::Data);
540
541     NSObject <NSSecureCoding> *userObject = nil;
542     if (API::Data* data = static_cast<API::Data*>(userData)) {
543         auto nsData = adoptNS([[NSData alloc] initWithBytesNoCopy:const_cast<void*>(static_cast<const void*>(data->bytes())) length:data->size() freeWhenDone:NO]);
544         auto unarchiver = adoptNS([[NSKeyedUnarchiver alloc] initForReadingWithData:nsData.get()]);
545         [unarchiver setRequiresSecureCoding:YES];
546         @try {
547             userObject = [unarchiver decodeObjectOfClass:[NSObject class] forKey:@"userObject"];
548         } @catch (NSException *exception) {
549             LOG_ERROR("Failed to decode user data: %@", exception);
550         }
551     }
552
553     [m_contentView _startAssistingNode:nodeInformation userIsInteracting:userIsInteracting blurPreviousNode:blurPreviousNode userObject:userObject];
554 }
555
556 bool PageClientImpl::isAssistingNode()
557 {
558     return [m_contentView isAssistingNode];
559 }
560
561 void PageClientImpl::stopAssistingNode()
562 {
563     [m_contentView _stopAssistingNode];
564 }
565
566 void PageClientImpl::didUpdateBlockSelectionWithTouch(uint32_t touch, uint32_t flags, float growThreshold, float shrinkThreshold)
567 {
568     [m_contentView _didUpdateBlockSelectionWithTouch:(SelectionTouch)touch withFlags:(SelectionFlags)flags growThreshold:growThreshold shrinkThreshold:shrinkThreshold];
569 }
570
571 void PageClientImpl::showPlaybackTargetPicker(bool hasVideo, const IntRect& elementRect)
572 {
573     [m_contentView _showPlaybackTargetPicker:hasVideo fromRect:elementRect];
574 }
575
576 bool PageClientImpl::handleRunOpenPanel(WebPageProxy*, WebFrameProxy*, WebOpenPanelParameters* parameters, WebOpenPanelResultListenerProxy* listener)
577 {
578     [m_contentView _showRunOpenPanel:parameters resultListener:listener];
579     return true;
580 }
581
582 void PageClientImpl::showInspectorHighlight(const WebCore::Highlight& highlight)
583 {
584     [m_contentView _showInspectorHighlight:highlight];
585 }
586
587 void PageClientImpl::hideInspectorHighlight()
588 {
589     [m_contentView _hideInspectorHighlight];
590 }
591
592 void PageClientImpl::showInspectorIndication()
593 {
594     [m_contentView setShowingInspectorIndication:YES];
595 }
596
597 void PageClientImpl::hideInspectorIndication()
598 {
599     [m_contentView setShowingInspectorIndication:NO];
600 }
601
602 void PageClientImpl::enableInspectorNodeSearch()
603 {
604     [m_contentView _enableInspectorNodeSearch];
605 }
606
607 void PageClientImpl::disableInspectorNodeSearch()
608 {
609     [m_contentView _disableInspectorNodeSearch];
610 }
611
612 #if ENABLE(FULLSCREEN_API)
613
614 WebFullScreenManagerProxyClient& PageClientImpl::fullScreenManagerProxyClient()
615 {
616     return *this;
617 }
618
619 // WebFullScreenManagerProxyClient
620
621 void PageClientImpl::closeFullScreenManager()
622 {
623 }
624
625 bool PageClientImpl::isFullScreen()
626 {
627     return false;
628 }
629
630 void PageClientImpl::enterFullScreen()
631 {
632 }
633
634 void PageClientImpl::exitFullScreen()
635 {
636 }
637
638 void PageClientImpl::beganEnterFullScreen(const IntRect&, const IntRect&)
639 {
640 }
641
642 void PageClientImpl::beganExitFullScreen(const IntRect&, const IntRect&)
643 {
644 }
645
646 #endif // ENABLE(FULLSCREEN_API)
647
648 void PageClientImpl::didFinishLoadingDataForCustomContentProvider(const String& suggestedFilename, const IPC::DataReference& dataReference)
649 {
650     RetainPtr<NSData> data = adoptNS([[NSData alloc] initWithBytes:dataReference.data() length:dataReference.size()]);
651     [m_webView _didFinishLoadingDataForCustomContentProviderWithSuggestedFilename:suggestedFilename data:data.get()];
652 }
653
654 void PageClientImpl::zoomToRect(FloatRect rect, double minimumScale, double maximumScale)
655 {
656     [m_contentView _zoomToRect:rect withOrigin:rect.center() fitEntireRect:YES minimumScale:minimumScale maximumScale:maximumScale minimumScrollDistance:0];
657 }
658
659 void PageClientImpl::overflowScrollViewWillStartPanGesture()
660 {
661     [m_contentView scrollViewWillStartPanOrPinchGesture];
662 }
663
664 void PageClientImpl::overflowScrollViewDidScroll()
665 {
666     [m_contentView _didScroll];
667 }
668
669 void PageClientImpl::overflowScrollWillStartScroll()
670 {
671     [m_contentView _overflowScrollingWillBegin];
672 }
673
674 void PageClientImpl::overflowScrollDidEndScroll()
675 {
676     [m_contentView _overflowScrollingDidEnd];
677 }
678
679 void PageClientImpl::didFinishDrawingPagesToPDF(const IPC::DataReference& pdfData)
680 {
681     RetainPtr<CFDataRef> data = adoptCF(CFDataCreate(kCFAllocatorDefault, pdfData.data(), pdfData.size()));
682     RetainPtr<CGDataProviderRef> dataProvider = adoptCF(CGDataProviderCreateWithCFData(data.get()));
683     m_webView._printedDocument = adoptCF(CGPDFDocumentCreateWithProvider(dataProvider.get())).get();
684 }
685
686 Vector<String> PageClientImpl::mimeTypesWithCustomContentProviders()
687 {
688     return m_webView.configuration._contentProviderRegistry._mimeTypesWithCustomContentProviders;
689 }
690
691 void PageClientImpl::navigationGestureDidBegin()
692 {
693     [m_webView _navigationGestureDidBegin];
694     NavigationState::fromWebPage(*m_webView->_page).navigationGestureDidBegin();
695 }
696
697 void PageClientImpl::navigationGestureWillEnd(bool willNavigate, WebBackForwardListItem& item)
698 {
699     NavigationState::fromWebPage(*m_webView->_page).navigationGestureWillEnd(willNavigate, item);
700 }
701
702 void PageClientImpl::navigationGestureDidEnd(bool willNavigate, WebBackForwardListItem& item)
703 {
704     NavigationState::fromWebPage(*m_webView->_page).navigationGestureDidEnd(willNavigate, item);
705     [m_webView _navigationGestureDidEnd];
706 }
707
708 void PageClientImpl::navigationGestureDidEnd()
709 {
710     [m_webView _navigationGestureDidEnd];
711 }
712
713 void PageClientImpl::willRecordNavigationSnapshot(WebBackForwardListItem& item)
714 {
715     NavigationState::fromWebPage(*m_webView->_page).willRecordNavigationSnapshot(item);
716 }
717
718 void PageClientImpl::didFirstVisuallyNonEmptyLayoutForMainFrame()
719 {
720 }
721
722 void PageClientImpl::didFinishLoadForMainFrame()
723 {
724     [m_webView _didFinishLoadForMainFrame];
725 }
726
727 void PageClientImpl::didFailLoadForMainFrame()
728 {
729     [m_webView _didFailLoadForMainFrame];
730 }
731
732 void PageClientImpl::didSameDocumentNavigationForMainFrame(SameDocumentNavigationType navigationType)
733 {
734     [m_webView _didSameDocumentNavigationForMainFrame:navigationType];
735 }
736
737 void PageClientImpl::didChangeBackgroundColor()
738 {
739     [m_webView _updateScrollViewBackground];
740 }
741
742 void PageClientImpl::refView()
743 {
744     [m_contentView retain];
745     [m_webView retain];
746     [m_wkView retain];
747 }
748
749 void PageClientImpl::derefView()
750 {
751     [m_contentView release];
752     [m_webView release];
753     [m_wkView release];
754 }
755
756 } // namespace WebKit
757
758 #endif // PLATFORM(IOS)