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