76d29c9b09589e8463a92171fb453431b38dac7c
[WebKit-https.git] / Source / WebKit2 / UIProcess / mac / PageClientImpl.mm
1 /*
2  * Copyright (C) 2010, 2011, 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 "PageClientImpl.h"
28
29 #if PLATFORM(MAC)
30
31 #import "APIHitTestResult.h"
32 #import "ColorSpaceData.h"
33 #import "DataReference.h"
34 #import "DownloadProxy.h"
35 #import "DrawingAreaProxy.h"
36 #import "NativeWebGestureEvent.h"
37 #import "NativeWebKeyboardEvent.h"
38 #import "NativeWebMouseEvent.h"
39 #import "NativeWebWheelEvent.h"
40 #import "NavigationState.h"
41 #import "StringUtilities.h"
42 #import "ViewGestureController.h"
43 #import "ViewSnapshotStore.h"
44 #import "WKAPICast.h"
45 #import "WKFullScreenWindowController.h"
46 #import "WKStringCF.h"
47 #import "WKViewInternal.h"
48 #import "WKWebViewInternal.h"
49 #import "WebColorPickerMac.h"
50 #import "WebContextMenuProxyMac.h"
51 #import "WebEditCommandProxy.h"
52 #import "WebPopupMenuProxyMac.h"
53 #import "WebViewImpl.h"
54 #import "WindowServerConnection.h"
55 #import "_WKDownloadInternal.h"
56 #import "_WKHitTestResultInternal.h"
57 #import "_WKThumbnailView.h"
58 #import <WebCore/AlternativeTextUIController.h>
59 #import <WebCore/BitmapImage.h>
60 #import <WebCore/Cursor.h>
61 #import <WebCore/DictionaryLookup.h>
62 #import <WebCore/FloatRect.h>
63 #import <WebCore/GraphicsContext.h>
64 #import <WebCore/Image.h>
65 #import <WebCore/KeyboardEvent.h>
66 #import <WebCore/NotImplemented.h>
67 #import <WebCore/SharedBuffer.h>
68 #import <WebCore/TextIndicator.h>
69 #import <WebCore/TextIndicatorWindow.h>
70 #import <WebCore/TextUndoInsertionMarkupMac.h>
71 #import <WebCore/ValidationBubble.h>
72 #import <WebKitSystemInterface.h>
73 #import <wtf/text/CString.h>
74 #import <wtf/text/WTFString.h>
75
76 #if USE(DICTATION_ALTERNATIVES)
77 #import <AppKit/NSTextAlternatives.h>
78 #endif
79
80 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
81 #include <WebCore/WebMediaSessionManager.h>
82 #endif
83
84 @interface NSApplication (WebNSApplicationDetails)
85 - (NSCursor *)_cursorRectCursor;
86 @end
87
88 #if HAVE(OUT_OF_PROCESS_LAYER_HOSTING)
89 @interface NSWindow (WebNSWindowDetails)
90 - (BOOL)_hostsLayersInWindowServer;
91 @end
92 #endif
93
94 using namespace WebCore;
95 using namespace WebKit;
96
97 namespace WebKit {
98
99 PageClientImpl::PageClientImpl(NSView* view, WKWebView *webView)
100     : m_view(view)
101     , m_webView(webView)
102 #if USE(DICTATION_ALTERNATIVES)
103     , m_alternativeTextUIController(std::make_unique<AlternativeTextUIController>())
104 #endif
105 {
106 #if !WK_API_ENABLED
107     ASSERT_UNUSED(m_webView, !m_webView);
108 #endif
109 }
110
111 PageClientImpl::~PageClientImpl()
112 {
113 }
114
115 std::unique_ptr<DrawingAreaProxy> PageClientImpl::createDrawingAreaProxy()
116 {
117     return m_impl->createDrawingAreaProxy();
118 }
119
120 void PageClientImpl::setViewNeedsDisplay(const WebCore::Region&)
121 {
122     ASSERT_NOT_REACHED();
123 }
124
125 void PageClientImpl::requestScroll(const FloatPoint& scrollPosition, const IntPoint& scrollOrigin, bool isProgrammaticScroll)
126 {
127 }
128
129 WebCore::FloatPoint PageClientImpl::viewScrollPosition()
130 {
131     return { };
132 }
133
134 IntSize PageClientImpl::viewSize()
135 {
136     return IntSize([m_view bounds].size);
137 }
138
139 NSView *PageClientImpl::activeView() const
140 {
141 #if WK_API_ENABLED
142     return (m_impl && m_impl->thumbnailView()) ? (NSView *)m_impl->thumbnailView() : m_view;
143 #else
144     return m_view;
145 #endif
146 }
147
148 NSWindow *PageClientImpl::activeWindow() const
149 {
150 #if WK_API_ENABLED
151     if (m_impl && m_impl->thumbnailView())
152         return m_impl->thumbnailView().window;
153 #endif
154     if (m_impl && m_impl->targetWindowForMovePreparation())
155         return m_impl->targetWindowForMovePreparation();
156     return m_view.window;
157 }
158
159 bool PageClientImpl::isViewWindowActive()
160 {
161     NSWindow *activeViewWindow = activeWindow();
162     return activeViewWindow.isKeyWindow || [NSApp keyWindow] == activeViewWindow;
163 }
164
165 bool PageClientImpl::isViewFocused()
166 {
167     // FIXME: This is called from the WebPageProxy constructor before we have a WebViewImpl.
168     // Once WebViewImpl and PageClient merge, this won't be a problem.
169     if (!m_impl)
170         return NO;
171
172     return m_impl->isFocused();
173 }
174
175 void PageClientImpl::makeFirstResponder()
176 {
177     if (m_shouldSuppressFirstResponderChanges)
178         return;
179
180      [[m_view window] makeFirstResponder:m_view];
181 }
182     
183 bool PageClientImpl::isViewVisible()
184 {
185     NSView *activeView = this->activeView();
186     NSWindow *activeViewWindow = activeWindow();
187
188     if (!activeViewWindow)
189         return false;
190
191     if (!activeViewWindow.isVisible)
192         return false;
193
194     if (activeView.isHiddenOrHasHiddenAncestor)
195         return false;
196
197     if (m_impl->windowOcclusionDetectionEnabled() && (activeViewWindow.occlusionState & NSWindowOcclusionStateVisible) != NSWindowOcclusionStateVisible)
198         return false;
199
200     return true;
201 }
202
203 bool PageClientImpl::isViewVisibleOrOccluded()
204 {
205     return activeWindow().isVisible;
206 }
207
208 bool PageClientImpl::isViewInWindow()
209 {
210     return activeWindow();
211 }
212
213 bool PageClientImpl::isVisuallyIdle()
214 {
215     return WindowServerConnection::singleton().applicationWindowModificationsHaveStopped() || !isViewVisible();
216 }
217
218 LayerHostingMode PageClientImpl::viewLayerHostingMode()
219 {
220 #if HAVE(OUT_OF_PROCESS_LAYER_HOSTING)
221     if ([activeWindow() _hostsLayersInWindowServer])
222         return LayerHostingMode::OutOfProcess;
223 #endif
224     return LayerHostingMode::InProcess;
225 }
226
227 void PageClientImpl::viewWillMoveToAnotherWindow()
228 {
229     clearAllEditCommands();
230 }
231
232 ColorSpaceData PageClientImpl::colorSpace()
233 {
234     return m_impl->colorSpace();
235 }
236
237 void PageClientImpl::processDidExit()
238 {
239     m_impl->processDidExit();
240 }
241
242 void PageClientImpl::pageClosed()
243 {
244     m_impl->pageClosed();
245 #if USE(DICTATION_ALTERNATIVES)
246     m_alternativeTextUIController->clear();
247 #endif
248 }
249
250 void PageClientImpl::didRelaunchProcess()
251 {
252     m_impl->didRelaunchProcess();
253 }
254
255 void PageClientImpl::preferencesDidChange()
256 {
257     m_impl->preferencesDidChange();
258 }
259
260 void PageClientImpl::toolTipChanged(const String& oldToolTip, const String& newToolTip)
261 {
262     m_impl->toolTipChanged(oldToolTip, newToolTip);
263 }
264
265 void PageClientImpl::didCommitLoadForMainFrame(const String& mimeType, bool useCustomContentProvider)
266 {
267     m_impl->updateSupportsArbitraryLayoutModes();
268     m_impl->dismissContentRelativeChildWindowsWithAnimation(true);
269 }
270
271 void PageClientImpl::didFinishLoadingDataForCustomContentProvider(const String& suggestedFilename, const IPC::DataReference& dataReference)
272 {
273 }
274
275 void PageClientImpl::handleDownloadRequest(DownloadProxy* download)
276 {
277     ASSERT_ARG(download, download);
278 #if WK_API_ENABLED
279     ASSERT([download->wrapper() isKindOfClass:[_WKDownload class]]);
280     [static_cast<_WKDownload *>(download->wrapper()) setOriginatingWebView:m_webView];
281 #endif
282 }
283
284 void PageClientImpl::didChangeContentSize(const WebCore::IntSize& newSize)
285 {
286     m_impl->didChangeContentSize(newSize);
287 }
288
289 void PageClientImpl::setCursor(const WebCore::Cursor& cursor)
290 {
291     // FIXME: Would be nice to share this code with WebKit1's WebChromeClient.
292
293     if ([NSApp _cursorRectCursor])
294         return;
295
296     if (!m_view)
297         return;
298
299     NSWindow *window = [m_view window];
300     if (!window)
301         return;
302
303     if ([window windowNumber] != [NSWindow windowNumberAtPoint:[NSEvent mouseLocation] belowWindowWithWindowNumber:0])
304         return;
305
306     NSCursor *platformCursor = cursor.platformCursor();
307     if ([NSCursor currentCursor] == platformCursor)
308         return;
309
310     [platformCursor set];
311 }
312
313 void PageClientImpl::setCursorHiddenUntilMouseMoves(bool hiddenUntilMouseMoves)
314 {
315     [NSCursor setHiddenUntilMouseMoves:hiddenUntilMouseMoves];
316 }
317
318 void PageClientImpl::didChangeViewportProperties(const WebCore::ViewportAttributes&)
319 {
320 }
321
322 void PageClientImpl::registerEditCommand(Ref<WebEditCommandProxy>&& command, WebPageProxy::UndoOrRedo undoOrRedo)
323 {
324     m_impl->registerEditCommand(WTFMove(command), undoOrRedo);
325 }
326
327 #if USE(INSERTION_UNDO_GROUPING)
328 void PageClientImpl::registerInsertionUndoGrouping()
329 {
330     registerInsertionUndoGroupingWithUndoManager([m_view undoManager]);
331 }
332 #endif
333
334 void PageClientImpl::clearAllEditCommands()
335 {
336     m_impl->clearAllEditCommands();
337 }
338
339 bool PageClientImpl::canUndoRedo(WebPageProxy::UndoOrRedo undoOrRedo)
340 {
341     return (undoOrRedo == WebPageProxy::Undo) ? [[m_view undoManager] canUndo] : [[m_view undoManager] canRedo];
342 }
343
344 void PageClientImpl::executeUndoRedo(WebPageProxy::UndoOrRedo undoOrRedo)
345 {
346     return (undoOrRedo == WebPageProxy::Undo) ? [[m_view undoManager] undo] : [[m_view undoManager] redo];
347 }
348
349 void PageClientImpl::setDragImage(const IntPoint& clientPosition, Ref<ShareableBitmap>&& dragImage, DragSourceAction action)
350 {
351     RetainPtr<CGImageRef> dragCGImage = dragImage->makeCGImage();
352     RetainPtr<NSImage> dragNSImage = adoptNS([[NSImage alloc] initWithCGImage:dragCGImage.get() size:dragImage->size()]);
353     IntSize size([dragNSImage size]);
354     size.scale(1.0 / m_impl->page().deviceScaleFactor());
355     [dragNSImage setSize:size];
356
357     m_impl->dragImageForView(m_view, dragNSImage.get(), clientPosition, action == DragSourceActionLink);
358 }
359
360 void PageClientImpl::setPromisedDataForImage(const String& pasteboardName, Ref<SharedBuffer>&& imageBuffer, const String& filename, const String& extension, const String& title, const String& url, const String& visibleURL, RefPtr<SharedBuffer>&& archiveBuffer)
361 {
362     RefPtr<Image> image = BitmapImage::create();
363     image->setData(WTFMove(imageBuffer), true);
364     m_impl->setPromisedDataForImage(image.get(), filename, extension, title, url, visibleURL, archiveBuffer.get(), pasteboardName);
365 }
366
367 #if ENABLE(ATTACHMENT_ELEMENT)
368 void PageClientImpl::setPromisedDataForAttachment(const String& pasteboardName, const String& filename, const String& extension, const String& title, const String& url, const String& visibleURL)
369 {
370     m_impl->setPromisedDataForAttachment(filename, extension, title, url, visibleURL, pasteboardName);
371 }
372 #endif
373
374 void PageClientImpl::updateSecureInputState()
375 {
376     m_impl->updateSecureInputState();
377 }
378
379 void PageClientImpl::resetSecureInputState()
380 {
381     m_impl->resetSecureInputState();
382 }
383
384 void PageClientImpl::notifyInputContextAboutDiscardedComposition()
385 {
386     m_impl->notifyInputContextAboutDiscardedComposition();
387 }
388
389 FloatRect PageClientImpl::convertToDeviceSpace(const FloatRect& rect)
390 {
391     return toDeviceSpace(rect, [m_view window]);
392 }
393
394 FloatRect PageClientImpl::convertToUserSpace(const FloatRect& rect)
395 {
396     return toUserSpace(rect, [m_view window]);
397 }
398    
399 IntPoint PageClientImpl::screenToRootView(const IntPoint& point)
400 {
401 #pragma clang diagnostic push
402 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
403     NSPoint windowCoord = [[m_view window] convertScreenToBase:point];
404 #pragma clang diagnostic pop
405     return IntPoint([m_view convertPoint:windowCoord fromView:nil]);
406 }
407     
408 IntRect PageClientImpl::rootViewToScreen(const IntRect& rect)
409 {
410     NSRect tempRect = rect;
411     tempRect = [m_view convertRect:tempRect toView:nil];
412 #pragma clang diagnostic push
413 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
414     tempRect.origin = [[m_view window] convertBaseToScreen:tempRect.origin];
415 #pragma clang diagnostic pop
416     return enclosingIntRect(tempRect);
417 }
418
419 IntRect PageClientImpl::rootViewToWindow(const WebCore::IntRect& rect)
420 {
421     NSRect tempRect = rect;
422     tempRect = [m_view convertRect:tempRect toView:nil];
423     return enclosingIntRect(tempRect);
424 }
425
426 void PageClientImpl::doneWithKeyEvent(const NativeWebKeyboardEvent& event, bool eventWasHandled)
427 {
428     m_impl->doneWithKeyEvent(event.nativeEvent(), eventWasHandled);
429 }
430
431 RefPtr<WebPopupMenuProxy> PageClientImpl::createPopupMenuProxy(WebPageProxy& page)
432 {
433     return WebPopupMenuProxyMac::create(m_view, page);
434 }
435
436 #if ENABLE(CONTEXT_MENUS)
437 RefPtr<WebContextMenuProxy> PageClientImpl::createContextMenuProxy(WebPageProxy& page, const ContextMenuContextData& context, const UserData& userData)
438 {
439     return WebContextMenuProxyMac::create(m_view, page, context, userData);
440 }
441 #endif
442
443 #if ENABLE(INPUT_TYPE_COLOR)
444 RefPtr<WebColorPicker> PageClientImpl::createColorPicker(WebPageProxy* page, const WebCore::Color& initialColor,  const WebCore::IntRect& rect)
445 {
446     return WebColorPickerMac::create(page, initialColor, rect, m_view);
447 }
448 #endif
449
450 Ref<ValidationBubble> PageClientImpl::createValidationBubble(const String& message, const ValidationBubble::Settings& settings)
451 {
452     return ValidationBubble::create(m_view, message, settings);
453 }
454
455 void PageClientImpl::setTextIndicator(Ref<TextIndicator> textIndicator, WebCore::TextIndicatorWindowLifetime lifetime)
456 {
457     m_impl->setTextIndicator(textIndicator.get(), lifetime);
458 }
459
460 void PageClientImpl::clearTextIndicator(WebCore::TextIndicatorWindowDismissalAnimation dismissalAnimation)
461 {
462     m_impl->clearTextIndicatorWithAnimation(dismissalAnimation);
463 }
464
465 void PageClientImpl::setTextIndicatorAnimationProgress(float progress)
466 {
467     m_impl->setTextIndicatorAnimationProgress(progress);
468 }
469
470 void PageClientImpl::accessibilityWebProcessTokenReceived(const IPC::DataReference& data)
471 {
472     m_impl->setAccessibilityWebProcessToken([NSData dataWithBytes:data.data() length:data.size()]);
473 }
474     
475 void PageClientImpl::enterAcceleratedCompositingMode(const LayerTreeContext& layerTreeContext)
476 {
477     ASSERT(!layerTreeContext.isEmpty());
478
479     CALayer *renderLayer = WKMakeRenderLayer(layerTreeContext.contextID);
480     m_impl->setAcceleratedCompositingRootLayer(renderLayer);
481 }
482
483 void PageClientImpl::exitAcceleratedCompositingMode()
484 {
485     m_impl->setAcceleratedCompositingRootLayer(nil);
486 }
487
488 void PageClientImpl::updateAcceleratedCompositingMode(const LayerTreeContext& layerTreeContext)
489 {
490     ASSERT(!layerTreeContext.isEmpty());
491
492     CALayer *renderLayer = WKMakeRenderLayer(layerTreeContext.contextID);
493     m_impl->setAcceleratedCompositingRootLayer(renderLayer);
494 }
495
496 void PageClientImpl::setAcceleratedCompositingRootLayer(CALayer *rootLayer)
497 {
498     m_impl->setAcceleratedCompositingRootLayer(rootLayer);
499 }
500
501 CALayer *PageClientImpl::acceleratedCompositingRootLayer() const
502 {
503     return m_impl->acceleratedCompositingRootLayer();
504 }
505
506 RefPtr<ViewSnapshot> PageClientImpl::takeViewSnapshot()
507 {
508     return m_impl->takeViewSnapshot();
509 }
510
511 void PageClientImpl::selectionDidChange()
512 {
513     m_impl->selectionDidChange();
514 }
515
516 void PageClientImpl::wheelEventWasNotHandledByWebCore(const NativeWebWheelEvent& event)
517 {
518     if (auto gestureController = m_impl->gestureController())
519         gestureController->wheelEventWasNotHandledByWebCore(event.nativeEvent());
520 }
521
522 #if ENABLE(MAC_GESTURE_EVENTS)
523 void PageClientImpl::gestureEventWasNotHandledByWebCore(const NativeWebGestureEvent& event)
524 {
525     m_impl->gestureEventWasNotHandledByWebCore(event.nativeEvent());
526 }
527 #endif
528
529 void PageClientImpl::pluginFocusOrWindowFocusChanged(uint64_t pluginComplexTextInputIdentifier, bool pluginHasFocusAndWindowHasFocus)
530 {
531     m_impl->pluginFocusOrWindowFocusChanged(pluginHasFocusAndWindowHasFocus, pluginComplexTextInputIdentifier);
532 }
533
534 void PageClientImpl::setPluginComplexTextInputState(uint64_t pluginComplexTextInputIdentifier, PluginComplexTextInputState pluginComplexTextInputState)
535 {
536     m_impl->setPluginComplexTextInputStateAndIdentifier(pluginComplexTextInputState, pluginComplexTextInputIdentifier);
537 }
538
539 void PageClientImpl::didPerformDictionaryLookup(const DictionaryPopupInfo& dictionaryPopupInfo)
540 {
541     m_impl->prepareForDictionaryLookup();
542
543     DictionaryLookup::showPopup(dictionaryPopupInfo, m_view, [this](TextIndicator& textIndicator) {
544         m_impl->setTextIndicator(textIndicator, TextIndicatorWindowLifetime::Permanent);
545     });
546 }
547
548 void PageClientImpl::showCorrectionPanel(AlternativeTextType type, const FloatRect& boundingBoxOfReplacedString, const String& replacedString, const String& replacementString, const Vector<String>& alternativeReplacementStrings)
549 {
550 #if USE(AUTOCORRECTION_PANEL)
551     if (!isViewVisible() || !isViewInWindow())
552         return;
553     m_correctionPanel.show(m_view, *m_impl, type, boundingBoxOfReplacedString, replacedString, replacementString, alternativeReplacementStrings);
554 #endif
555 }
556
557 void PageClientImpl::dismissCorrectionPanel(ReasonForDismissingAlternativeText reason)
558 {
559 #if USE(AUTOCORRECTION_PANEL)
560     m_correctionPanel.dismiss(reason);
561 #endif
562 }
563
564 String PageClientImpl::dismissCorrectionPanelSoon(WebCore::ReasonForDismissingAlternativeText reason)
565 {
566 #if USE(AUTOCORRECTION_PANEL)
567     return m_correctionPanel.dismiss(reason);
568 #else
569     return String();
570 #endif
571 }
572
573 static inline NSCorrectionResponse toCorrectionResponse(AutocorrectionResponse response)
574 {
575     switch (response) {
576     case WebCore::AutocorrectionResponse::Reverted:
577         return NSCorrectionResponseReverted;
578     case WebCore::AutocorrectionResponse::Edited:
579         return NSCorrectionResponseEdited;
580     case WebCore::AutocorrectionResponse::Accepted:
581         return NSCorrectionResponseAccepted;
582     }
583
584     ASSERT_NOT_REACHED();
585     return NSCorrectionResponseAccepted;
586 }
587
588 void PageClientImpl::recordAutocorrectionResponse(AutocorrectionResponse response, const String& replacedString, const String& replacementString)
589 {
590     CorrectionPanel::recordAutocorrectionResponse(m_impl->spellCheckerDocumentTag(), toCorrectionResponse(response), replacedString, replacementString);
591 }
592
593 void PageClientImpl::recommendedScrollbarStyleDidChange(ScrollbarStyle newStyle)
594 {
595     // Now re-create a tracking area with the appropriate options given the new scrollbar style
596     NSTrackingAreaOptions options = NSTrackingMouseMoved | NSTrackingMouseEnteredAndExited | NSTrackingInVisibleRect | NSTrackingCursorUpdate;
597     if (newStyle == ScrollbarStyle::AlwaysVisible)
598         options |= NSTrackingActiveAlways;
599     else
600         options |= NSTrackingActiveInKeyWindow;
601
602     RetainPtr<NSTrackingArea> trackingArea = adoptNS([[NSTrackingArea alloc] initWithRect:[m_view frame] options:options owner:m_view userInfo:nil]);
603     m_impl->setPrimaryTrackingArea(trackingArea.get());
604 }
605
606 void PageClientImpl::intrinsicContentSizeDidChange(const IntSize& intrinsicContentSize)
607 {
608     m_impl->setIntrinsicContentSize(intrinsicContentSize);
609 }
610
611 bool PageClientImpl::executeSavedCommandBySelector(const String& selectorString)
612 {
613     return m_impl->executeSavedCommandBySelector(NSSelectorFromString(selectorString));
614 }
615
616 #if USE(DICTATION_ALTERNATIVES)
617 uint64_t PageClientImpl::addDictationAlternatives(const RetainPtr<NSTextAlternatives>& alternatives)
618 {
619     return m_alternativeTextUIController->addAlternatives(alternatives);
620 }
621
622 void PageClientImpl::removeDictationAlternatives(uint64_t dictationContext)
623 {
624     m_alternativeTextUIController->removeAlternatives(dictationContext);
625 }
626
627 void PageClientImpl::showDictationAlternativeUI(const WebCore::FloatRect& boundingBoxOfDictatedText, uint64_t dictationContext)
628 {
629     if (!isViewVisible() || !isViewInWindow())
630         return;
631     m_alternativeTextUIController->showAlternatives(m_view, boundingBoxOfDictatedText, dictationContext, ^(NSString *acceptedAlternative) {
632         m_impl->handleAcceptedAlternativeText(acceptedAlternative);
633     });
634 }
635
636 Vector<String> PageClientImpl::dictationAlternatives(uint64_t dictationContext)
637 {
638     return m_alternativeTextUIController->alternativesForContext(dictationContext);
639 }
640 #endif
641
642 void PageClientImpl::setEditableElementIsFocused(bool editableElementIsFocused)
643 {
644     m_impl->setEditableElementIsFocused(editableElementIsFocused);
645 }
646
647 #if ENABLE(FULLSCREEN_API)
648
649 WebFullScreenManagerProxyClient& PageClientImpl::fullScreenManagerProxyClient()
650 {
651     return *this;
652 }
653
654 // WebFullScreenManagerProxyClient
655
656 void PageClientImpl::closeFullScreenManager()
657 {
658     m_impl->closeFullScreenWindowController();
659 }
660
661 bool PageClientImpl::isFullScreen()
662 {
663     if (!m_impl->hasFullScreenWindowController())
664         return false;
665
666     return m_impl->fullScreenWindowController().isFullScreen;
667 }
668
669 void PageClientImpl::enterFullScreen()
670 {
671     [m_impl->fullScreenWindowController() enterFullScreen:nil];
672 }
673
674 void PageClientImpl::exitFullScreen()
675 {
676     [m_impl->fullScreenWindowController() exitFullScreen];
677 }
678
679 void PageClientImpl::beganEnterFullScreen(const IntRect& initialFrame, const IntRect& finalFrame)
680 {
681     [m_impl->fullScreenWindowController() beganEnterFullScreenWithInitialFrame:initialFrame finalFrame:finalFrame];
682     m_impl->updateSupportsArbitraryLayoutModes();
683 }
684
685 void PageClientImpl::beganExitFullScreen(const IntRect& initialFrame, const IntRect& finalFrame)
686 {
687     [m_impl->fullScreenWindowController() beganExitFullScreenWithInitialFrame:initialFrame finalFrame:finalFrame];
688     m_impl->updateSupportsArbitraryLayoutModes();
689 }
690
691 #endif // ENABLE(FULLSCREEN_API)
692
693 void PageClientImpl::navigationGestureDidBegin()
694 {
695     m_impl->dismissContentRelativeChildWindowsWithAnimation(true);
696
697 #if WK_API_ENABLED
698     if (m_webView)
699         NavigationState::fromWebPage(*m_webView->_page).navigationGestureDidBegin();
700 #endif
701 }
702
703 void PageClientImpl::navigationGestureWillEnd(bool willNavigate, WebBackForwardListItem& item)
704 {
705 #if WK_API_ENABLED
706     if (m_webView)
707         NavigationState::fromWebPage(*m_webView->_page).navigationGestureWillEnd(willNavigate, item);
708 #else
709     UNUSED_PARAM(willNavigate);
710     UNUSED_PARAM(item);
711 #endif
712 }
713
714 void PageClientImpl::navigationGestureDidEnd(bool willNavigate, WebBackForwardListItem& item)
715 {
716 #if WK_API_ENABLED
717     if (m_webView)
718         NavigationState::fromWebPage(*m_webView->_page).navigationGestureDidEnd(willNavigate, item);
719 #else
720     UNUSED_PARAM(willNavigate);
721     UNUSED_PARAM(item);
722 #endif
723 }
724
725 void PageClientImpl::navigationGestureDidEnd()
726 {
727 }
728
729 void PageClientImpl::willRecordNavigationSnapshot(WebBackForwardListItem& item)
730 {
731 #if WK_API_ENABLED
732     if (m_webView)
733         NavigationState::fromWebPage(*m_webView->_page).willRecordNavigationSnapshot(item);
734 #else
735     UNUSED_PARAM(item);
736 #endif
737 }
738
739 void PageClientImpl::didRemoveNavigationGestureSnapshot()
740 {
741 #if WK_API_ENABLED
742     if (m_webView)
743         NavigationState::fromWebPage(*m_webView->_page).navigationGestureSnapshotWasRemoved();
744 #endif
745 }
746
747 void PageClientImpl::didFirstVisuallyNonEmptyLayoutForMainFrame()
748 {
749     if (auto gestureController = m_impl->gestureController())
750         gestureController->didFirstVisuallyNonEmptyLayoutForMainFrame();
751 }
752
753 void PageClientImpl::didFinishLoadForMainFrame()
754 {
755     if (auto gestureController = m_impl->gestureController())
756         gestureController->didFinishLoadForMainFrame();
757 }
758
759 void PageClientImpl::didFailLoadForMainFrame()
760 {
761     if (auto gestureController = m_impl->gestureController())
762         gestureController->didFailLoadForMainFrame();
763 }
764
765 void PageClientImpl::didSameDocumentNavigationForMainFrame(SameDocumentNavigationType type)
766 {
767     if (auto gestureController = m_impl->gestureController())
768         gestureController->didSameDocumentNavigationForMainFrame(type);
769 }
770
771 void PageClientImpl::handleControlledElementIDResponse(const String& identifier)
772 {
773 #if WK_API_ENABLED
774     [m_webView _handleControlledElementIDResponse:nsStringFromWebCoreString(identifier)];
775 #endif
776 }
777
778 void PageClientImpl::handleActiveNowPlayingSessionInfoResponse(bool hasActiveSession, const String& title, double duration, double elapsedTime)
779 {
780 #if WK_API_ENABLED
781     [m_webView _handleActiveNowPlayingSessionInfoResponse:hasActiveSession title:nsStringFromWebCoreString(title) duration:duration elapsedTime:elapsedTime];
782 #endif
783 }
784
785 void PageClientImpl::didChangeBackgroundColor()
786 {
787     notImplemented();
788 }
789
790 CGRect PageClientImpl::boundsOfLayerInLayerBackedWindowCoordinates(CALayer *layer) const
791 {
792     CALayer *windowContentLayer = static_cast<NSView *>(m_view.window.contentView).layer;
793     ASSERT(windowContentLayer);
794
795     return [windowContentLayer convertRect:layer.bounds fromLayer:layer];
796 }
797
798 void PageClientImpl::didPerformImmediateActionHitTest(const WebHitTestResultData& result, bool contentPreventsDefault, API::Object* userData)
799 {
800     m_impl->didPerformImmediateActionHitTest(result, contentPreventsDefault, userData);
801 }
802
803 void* PageClientImpl::immediateActionAnimationControllerForHitTestResult(RefPtr<API::HitTestResult> hitTestResult, uint64_t type, RefPtr<API::Object> userData)
804 {
805     return m_impl->immediateActionAnimationControllerForHitTestResult(hitTestResult.get(), type, userData.get());
806 }
807
808 void PageClientImpl::didHandleAcceptedCandidate()
809 {
810     m_impl->didHandleAcceptedCandidate();
811 }
812
813 void PageClientImpl::videoControlsManagerDidChange()
814 {
815     m_impl->videoControlsManagerDidChange();
816 }
817
818 void PageClientImpl::showPlatformContextMenu(NSMenu *menu, IntPoint location)
819 {
820     [menu popUpMenuPositioningItem:nil atLocation:location inView:m_view];
821 }
822
823 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
824 WebCore::WebMediaSessionManager& PageClientImpl::mediaSessionManager()
825 {
826     return WebMediaSessionManager::shared();
827 }
828 #endif
829
830 void PageClientImpl::refView()
831 {
832     CFRetain(m_view);
833 }
834
835 void PageClientImpl::derefView()
836 {
837     CFRelease(m_view);
838 }
839
840 void PageClientImpl::startWindowDrag()
841 {
842     m_impl->startWindowDrag();
843 }
844
845 NSWindow *PageClientImpl::platformWindow()
846 {
847     return m_impl->window();
848 }
849
850 #if WK_API_ENABLED
851 NSView *PageClientImpl::inspectorAttachmentView()
852 {
853     return m_impl->inspectorAttachmentView();
854 }
855
856 _WKRemoteObjectRegistry *PageClientImpl::remoteObjectRegistry()
857 {
858     return m_impl->remoteObjectRegistry();
859 }
860 #endif
861
862 void PageClientImpl::didRestoreScrollPosition()
863 {
864     m_impl->didRestoreScrollPosition();
865 }
866
867 bool PageClientImpl::windowIsFrontWindowUnderMouse(const NativeWebMouseEvent& event)
868 {
869     return m_impl->windowIsFrontWindowUnderMouse(event.nativeEvent());
870 }
871
872 WebCore::UserInterfaceLayoutDirection PageClientImpl::userInterfaceLayoutDirection()
873 {
874     if (!m_view)
875         return WebCore::UserInterfaceLayoutDirection::LTR;
876     return (m_view.userInterfaceLayoutDirection == NSUserInterfaceLayoutDirectionLeftToRight) ? WebCore::UserInterfaceLayoutDirection::LTR : WebCore::UserInterfaceLayoutDirection::RTL;
877 }
878
879 } // namespace WebKit
880
881 #endif // PLATFORM(MAC)