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