1/* 2 * Copyright (C) 2010, 2011 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 "AttributedString.h" 32#import "ColorSpaceData.h" 33#import "DataReference.h" 34#import "DictionaryPopupInfo.h" 35#import "DownloadProxy.h" 36#import "FindIndicator.h" 37#import "NativeWebKeyboardEvent.h" 38#import "NativeWebWheelEvent.h" 39#import "NavigationState.h" 40#import "StringUtilities.h" 41#import "ViewSnapshotStore.h" 42#import "WKAPICast.h" 43#import "WKFullScreenWindowController.h" 44#import "WKStringCF.h" 45#import "WKViewInternal.h" 46#import "WKWebViewInternal.h" 47#import "WebColorPickerMac.h" 48#import "WebContextMenuProxyMac.h" 49#import "WebEditCommandProxy.h" 50#import "WebPopupMenuProxyMac.h" 51#import "WindowServerConnection.h" 52#import "_WKDownloadInternal.h" 53#import "_WKThumbnailView.h" 54#import <WebCore/AlternativeTextUIController.h> 55#import <WebCore/BitmapImage.h> 56#import <WebCore/Cursor.h> 57#import <WebCore/FloatRect.h> 58#import <WebCore/GraphicsContext.h> 59#import <WebCore/Image.h> 60#import <WebCore/KeyboardEvent.h> 61#import <WebCore/NotImplemented.h> 62#import <WebCore/SharedBuffer.h> 63#import <WebCore/TextUndoInsertionMarkupMac.h> 64#import <WebKitSystemInterface.h> 65#import <wtf/text/CString.h> 66#import <wtf/text/WTFString.h> 67 68#if USE(DICTATION_ALTERNATIVES) 69#import <AppKit/NSTextAlternatives.h> 70#endif 71 72@interface NSApplication (WebNSApplicationDetails) 73- (NSCursor *)_cursorRectCursor; 74@end 75 76#if HAVE(OUT_OF_PROCESS_LAYER_HOSTING) 77@interface NSWindow (WebNSWindowDetails) 78- (BOOL)_hostsLayersInWindowServer; 79@end 80#endif 81 82using namespace WebCore; 83using namespace WebKit; 84 85@interface WKEditCommandObjC : NSObject 86{ 87 RefPtr<WebEditCommandProxy> m_command; 88} 89- (id)initWithWebEditCommandProxy:(PassRefPtr<WebEditCommandProxy>)command; 90- (WebEditCommandProxy*)command; 91@end 92 93@interface WKEditorUndoTargetObjC : NSObject 94- (void)undoEditing:(id)sender; 95- (void)redoEditing:(id)sender; 96@end 97 98@implementation WKEditCommandObjC 99 100- (id)initWithWebEditCommandProxy:(PassRefPtr<WebEditCommandProxy>)command 101{ 102 self = [super init]; 103 if (!self) 104 return nil; 105 106 m_command = command; 107 return self; 108} 109 110- (WebEditCommandProxy*)command 111{ 112 return m_command.get(); 113} 114 115@end 116 117@implementation WKEditorUndoTargetObjC 118 119- (void)undoEditing:(id)sender 120{ 121 ASSERT([sender isKindOfClass:[WKEditCommandObjC class]]); 122 [sender command]->unapply(); 123} 124 125- (void)redoEditing:(id)sender 126{ 127 ASSERT([sender isKindOfClass:[WKEditCommandObjC class]]); 128 [sender command]->reapply(); 129} 130 131@end 132 133namespace WebKit { 134 135PageClientImpl::PageClientImpl(WKView* wkView, WKWebView *webView) 136 : m_wkView(wkView) 137 , m_webView(webView) 138 , m_undoTarget(adoptNS([[WKEditorUndoTargetObjC alloc] init])) 139#if USE(DICTATION_ALTERNATIVES) 140 , m_alternativeTextUIController(adoptPtr(new AlternativeTextUIController)) 141#endif 142{ 143#if !WK_API_ENABLED 144 ASSERT_UNUSED(m_webView, !m_webView); 145#endif 146} 147 148PageClientImpl::~PageClientImpl() 149{ 150} 151 152std::unique_ptr<DrawingAreaProxy> PageClientImpl::createDrawingAreaProxy() 153{ 154 return [m_wkView _createDrawingAreaProxy]; 155} 156 157void PageClientImpl::setViewNeedsDisplay(const WebCore::IntRect& rect) 158{ 159 ASSERT_NOT_REACHED(); 160} 161 162void PageClientImpl::displayView() 163{ 164 ASSERT_NOT_REACHED(); 165} 166 167bool PageClientImpl::canScrollView() 168{ 169 return false; 170} 171 172void PageClientImpl::scrollView(const IntRect& scrollRect, const IntSize& scrollOffset) 173{ 174 ASSERT_NOT_REACHED(); 175} 176 177void PageClientImpl::requestScroll(const FloatPoint& scrollPosition, bool isProgrammaticScroll) 178{ 179 ASSERT_NOT_REACHED(); 180} 181 182IntSize PageClientImpl::viewSize() 183{ 184 return IntSize([m_wkView bounds].size); 185} 186 187NSView *PageClientImpl::activeView() const 188{ 189#if WK_API_ENABLED 190 return m_wkView._thumbnailView ? (NSView *)m_wkView._thumbnailView : (NSView *)m_wkView; 191#else 192 return m_wkView; 193#endif 194} 195 196bool PageClientImpl::isViewWindowActive() 197{ 198 NSWindow *activeViewWindow = activeView().window; 199 return activeViewWindow.isKeyWindow || [NSApp keyWindow] == activeViewWindow; 200} 201 202bool PageClientImpl::isViewFocused() 203{ 204 return [m_wkView _isFocused]; 205} 206 207void PageClientImpl::makeFirstResponder() 208{ 209 [[m_wkView window] makeFirstResponder:m_wkView]; 210} 211 212bool PageClientImpl::isViewVisible() 213{ 214 NSView *activeView = this->activeView(); 215 NSWindow *activeViewWindow = activeView.window; 216 217 if (!activeViewWindow) 218 return false; 219 220 if (!activeViewWindow.isVisible) 221 return false; 222 223#if __MAC_OS_X_VERSION_MIN_REQUIRED <= 1080 224 // Mountain Lion and previous do not support occlusion notifications, and as such will 225 // continue to report as "visible" when not on the active space. 226 if (!activeViewWindow.isOnActiveSpace) 227 return false; 228#endif 229 230 if (activeView.isHiddenOrHasHiddenAncestor) 231 return false; 232 233#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 234 if ([m_wkView windowOcclusionDetectionEnabled] && (activeViewWindow.occlusionState & NSWindowOcclusionStateVisible) != NSWindowOcclusionStateVisible) 235 return false; 236#endif 237 238 return true; 239} 240 241bool PageClientImpl::isViewVisibleOrOccluded() 242{ 243 return activeView().window.isVisible; 244} 245 246bool PageClientImpl::isViewInWindow() 247{ 248 return activeView().window; 249} 250 251bool PageClientImpl::isVisuallyIdle() 252{ 253 return WindowServerConnection::shared().applicationWindowModificationsHaveStopped() || !isViewVisible(); 254} 255 256LayerHostingMode PageClientImpl::viewLayerHostingMode() 257{ 258#if HAVE(OUT_OF_PROCESS_LAYER_HOSTING) 259 if ([activeView().window _hostsLayersInWindowServer]) 260 return LayerHostingMode::OutOfProcess; 261#endif 262 return LayerHostingMode::InProcess; 263} 264 265void PageClientImpl::viewWillMoveToAnotherWindow() 266{ 267 clearAllEditCommands(); 268} 269 270ColorSpaceData PageClientImpl::colorSpace() 271{ 272 return [m_wkView _colorSpace]; 273} 274 275void PageClientImpl::processDidExit() 276{ 277 [m_wkView _processDidExit]; 278} 279 280void PageClientImpl::pageClosed() 281{ 282 [m_wkView _pageClosed]; 283#if USE(DICTATION_ALTERNATIVES) 284 m_alternativeTextUIController->clear(); 285#endif 286} 287 288void PageClientImpl::didRelaunchProcess() 289{ 290 [m_wkView _didRelaunchProcess]; 291} 292 293void PageClientImpl::preferencesDidChange() 294{ 295 [m_wkView _preferencesDidChange]; 296} 297 298void PageClientImpl::toolTipChanged(const String& oldToolTip, const String& newToolTip) 299{ 300 [m_wkView _toolTipChangedFrom:nsStringFromWebCoreString(oldToolTip) to:nsStringFromWebCoreString(newToolTip)]; 301} 302 303void PageClientImpl::didCommitLoadForMainFrame(const String& mimeType, bool useCustomContentProvider) 304{ 305} 306 307void PageClientImpl::didFinishLoadingDataForCustomContentProvider(const String& suggestedFilename, const IPC::DataReference& dataReference) 308{ 309} 310 311void PageClientImpl::handleDownloadRequest(DownloadProxy* download) 312{ 313 ASSERT_ARG(download, download); 314#if WK_API_ENABLED 315 ASSERT([download->wrapper() isKindOfClass:[_WKDownload class]]); 316 [static_cast<_WKDownload *>(download->wrapper()) setOriginatingWebView:m_webView]; 317#endif 318} 319 320void PageClientImpl::setCursor(const WebCore::Cursor& cursor) 321{ 322 // FIXME: Would be nice to share this code with WebKit1's WebChromeClient. 323 324 if ([NSApp _cursorRectCursor]) 325 return; 326 327 if (!m_wkView) 328 return; 329 330 NSWindow *window = [m_wkView window]; 331 if (!window) 332 return; 333 334 if ([window windowNumber] != [NSWindow windowNumberAtPoint:[NSEvent mouseLocation] belowWindowWithWindowNumber:0]) 335 return; 336 337 NSCursor *platformCursor = cursor.platformCursor(); 338 if ([NSCursor currentCursor] == platformCursor) 339 return; 340 341 [platformCursor set]; 342} 343 344void PageClientImpl::setCursorHiddenUntilMouseMoves(bool hiddenUntilMouseMoves) 345{ 346 [NSCursor setHiddenUntilMouseMoves:hiddenUntilMouseMoves]; 347} 348 349void PageClientImpl::didChangeViewportProperties(const WebCore::ViewportAttributes&) 350{ 351} 352 353void PageClientImpl::registerEditCommand(PassRefPtr<WebEditCommandProxy> prpCommand, WebPageProxy::UndoOrRedo undoOrRedo) 354{ 355 RefPtr<WebEditCommandProxy> command = prpCommand; 356 357 RetainPtr<WKEditCommandObjC> commandObjC = adoptNS([[WKEditCommandObjC alloc] initWithWebEditCommandProxy:command]); 358 String actionName = WebEditCommandProxy::nameForEditAction(command->editAction()); 359 360 NSUndoManager *undoManager = [m_wkView undoManager]; 361 [undoManager registerUndoWithTarget:m_undoTarget.get() selector:((undoOrRedo == WebPageProxy::Undo) ? @selector(undoEditing:) : @selector(redoEditing:)) object:commandObjC.get()]; 362 if (!actionName.isEmpty()) 363 [undoManager setActionName:(NSString *)actionName]; 364} 365 366#if USE(INSERTION_UNDO_GROUPING) 367void PageClientImpl::registerInsertionUndoGrouping() 368{ 369 registerInsertionUndoGroupingWithUndoManager([m_wkView undoManager]); 370} 371#endif 372 373void PageClientImpl::clearAllEditCommands() 374{ 375 [[m_wkView undoManager] removeAllActionsWithTarget:m_undoTarget.get()]; 376} 377 378bool PageClientImpl::canUndoRedo(WebPageProxy::UndoOrRedo undoOrRedo) 379{ 380 return (undoOrRedo == WebPageProxy::Undo) ? [[m_wkView undoManager] canUndo] : [[m_wkView undoManager] canRedo]; 381} 382 383void PageClientImpl::executeUndoRedo(WebPageProxy::UndoOrRedo undoOrRedo) 384{ 385 return (undoOrRedo == WebPageProxy::Undo) ? [[m_wkView undoManager] undo] : [[m_wkView undoManager] redo]; 386} 387 388void PageClientImpl::setDragImage(const IntPoint& clientPosition, PassRefPtr<ShareableBitmap> dragImage, bool isLinkDrag) 389{ 390 RetainPtr<CGImageRef> dragCGImage = dragImage->makeCGImage(); 391 RetainPtr<NSImage> dragNSImage = adoptNS([[NSImage alloc] initWithCGImage:dragCGImage.get() size:dragImage->size()]); 392 393 [m_wkView _setDragImage:dragNSImage.get() at:clientPosition linkDrag:isLinkDrag]; 394} 395 396void PageClientImpl::setPromisedData(const String& pasteboardName, PassRefPtr<SharedBuffer> imageBuffer, const String& filename, const String& extension, const String& title, const String& url, const String& visibleUrl, PassRefPtr<SharedBuffer> archiveBuffer) 397{ 398 RefPtr<Image> image = BitmapImage::create(); 399 image->setData(imageBuffer.get(), true); 400 [m_wkView _setPromisedData:image.get() withFileName:filename withExtension:extension withTitle:title withURL:url withVisibleURL:visibleUrl withArchive:archiveBuffer.get() forPasteboard:pasteboardName]; 401} 402 403void PageClientImpl::updateSecureInputState() 404{ 405 [m_wkView _updateSecureInputState]; 406} 407 408void PageClientImpl::resetSecureInputState() 409{ 410 [m_wkView _resetSecureInputState]; 411} 412 413void PageClientImpl::notifyInputContextAboutDiscardedComposition() 414{ 415 [m_wkView _notifyInputContextAboutDiscardedComposition]; 416} 417 418FloatRect PageClientImpl::convertToDeviceSpace(const FloatRect& rect) 419{ 420 return [m_wkView _convertToDeviceSpace:rect]; 421} 422 423FloatRect PageClientImpl::convertToUserSpace(const FloatRect& rect) 424{ 425 return [m_wkView _convertToUserSpace:rect]; 426} 427 428IntPoint PageClientImpl::screenToRootView(const IntPoint& point) 429{ 430#pragma clang diagnostic push 431#pragma clang diagnostic ignored "-Wdeprecated-declarations" 432 NSPoint windowCoord = [[m_wkView window] convertScreenToBase:point]; 433#pragma clang diagnostic pop 434 return IntPoint([m_wkView convertPoint:windowCoord fromView:nil]); 435} 436 437IntRect PageClientImpl::rootViewToScreen(const IntRect& rect) 438{ 439 NSRect tempRect = rect; 440 tempRect = [m_wkView convertRect:tempRect toView:nil]; 441#pragma clang diagnostic push 442#pragma clang diagnostic ignored "-Wdeprecated-declarations" 443 tempRect.origin = [[m_wkView window] convertBaseToScreen:tempRect.origin]; 444#pragma clang diagnostic pop 445 return enclosingIntRect(tempRect); 446} 447 448void PageClientImpl::doneWithKeyEvent(const NativeWebKeyboardEvent& event, bool eventWasHandled) 449{ 450 [m_wkView _doneWithKeyEvent:event.nativeEvent() eventWasHandled:eventWasHandled]; 451} 452 453PassRefPtr<WebPopupMenuProxy> PageClientImpl::createPopupMenuProxy(WebPageProxy* page) 454{ 455 return WebPopupMenuProxyMac::create(m_wkView, page); 456} 457 458PassRefPtr<WebContextMenuProxy> PageClientImpl::createContextMenuProxy(WebPageProxy* page) 459{ 460 return WebContextMenuProxyMac::create(m_wkView, page); 461} 462 463#if ENABLE(INPUT_TYPE_COLOR) 464PassRefPtr<WebColorPicker> PageClientImpl::createColorPicker(WebPageProxy* page, const WebCore::Color& initialColor, const WebCore::IntRect& rect) 465{ 466 return WebColorPickerMac::create(page, initialColor, rect, wkView()); 467} 468#endif 469 470void PageClientImpl::setFindIndicator(PassRefPtr<FindIndicator> findIndicator, bool fadeOut, bool animate) 471{ 472 [m_wkView _setFindIndicator:findIndicator fadeOut:fadeOut animate:animate]; 473} 474 475void PageClientImpl::accessibilityWebProcessTokenReceived(const IPC::DataReference& data) 476{ 477 NSData* remoteToken = [NSData dataWithBytes:data.data() length:data.size()]; 478 [m_wkView _setAccessibilityWebProcessToken:remoteToken]; 479} 480 481void PageClientImpl::enterAcceleratedCompositingMode(const LayerTreeContext& layerTreeContext) 482{ 483 ASSERT(!layerTreeContext.isEmpty()); 484 485 CALayer *renderLayer = WKMakeRenderLayer(layerTreeContext.contextID); 486 [m_wkView _setAcceleratedCompositingModeRootLayer:renderLayer]; 487} 488 489void PageClientImpl::exitAcceleratedCompositingMode() 490{ 491 [m_wkView _setAcceleratedCompositingModeRootLayer:nil]; 492} 493 494void PageClientImpl::updateAcceleratedCompositingMode(const LayerTreeContext& layerTreeContext) 495{ 496 ASSERT(!layerTreeContext.isEmpty()); 497 498 CALayer *renderLayer = WKMakeRenderLayer(layerTreeContext.contextID); 499 [m_wkView _setAcceleratedCompositingModeRootLayer:renderLayer]; 500} 501 502void PageClientImpl::setAcceleratedCompositingRootLayer(CALayer *rootLayer) 503{ 504 [m_wkView _setAcceleratedCompositingModeRootLayer:rootLayer]; 505} 506 507CALayer *PageClientImpl::acceleratedCompositingRootLayer() const 508{ 509 return m_wkView._acceleratedCompositingModeRootLayer; 510} 511 512PassRefPtr<ViewSnapshot> PageClientImpl::takeViewSnapshot() 513{ 514 return [m_wkView _takeViewSnapshot]; 515} 516 517void PageClientImpl::wheelEventWasNotHandledByWebCore(const NativeWebWheelEvent& event) 518{ 519 [m_wkView _wheelEventWasNotHandledByWebCore:event.nativeEvent()]; 520} 521 522void PageClientImpl::pluginFocusOrWindowFocusChanged(uint64_t pluginComplexTextInputIdentifier, bool pluginHasFocusAndWindowHasFocus) 523{ 524 [m_wkView _pluginFocusOrWindowFocusChanged:pluginHasFocusAndWindowHasFocus pluginComplexTextInputIdentifier:pluginComplexTextInputIdentifier]; 525} 526 527void PageClientImpl::setPluginComplexTextInputState(uint64_t pluginComplexTextInputIdentifier, PluginComplexTextInputState pluginComplexTextInputState) 528{ 529 [m_wkView _setPluginComplexTextInputState:pluginComplexTextInputState pluginComplexTextInputIdentifier:pluginComplexTextInputIdentifier]; 530} 531 532void PageClientImpl::didPerformDictionaryLookup(const AttributedString& text, const DictionaryPopupInfo& dictionaryPopupInfo) 533{ 534 RetainPtr<NSAttributedString> attributedString = text.string; 535 NSPoint textBaselineOrigin = dictionaryPopupInfo.origin; 536 537 // Convert to screen coordinates. 538 textBaselineOrigin = [m_wkView convertPoint:textBaselineOrigin toView:nil]; 539 textBaselineOrigin = [m_wkView.window convertRectToScreen:NSMakeRect(textBaselineOrigin.x, textBaselineOrigin.y, 0, 0)].origin; 540 541 WKShowWordDefinitionWindow(attributedString.get(), textBaselineOrigin, (NSDictionary *)dictionaryPopupInfo.options.get()); 542} 543 544void PageClientImpl::dismissDictionaryLookupPanel() 545{ 546 // FIXME: We don't know which panel we are dismissing, it may not even be in the current page (see <rdar://problem/13875766>). 547 WKHideWordDefinitionWindow(); 548} 549 550void PageClientImpl::showCorrectionPanel(AlternativeTextType type, const FloatRect& boundingBoxOfReplacedString, const String& replacedString, const String& replacementString, const Vector<String>& alternativeReplacementStrings) 551{ 552#if USE(AUTOCORRECTION_PANEL) 553 if (!isViewVisible() || !isViewInWindow()) 554 return; 555 m_correctionPanel.show(m_wkView, type, boundingBoxOfReplacedString, replacedString, replacementString, alternativeReplacementStrings); 556#endif 557} 558 559void PageClientImpl::dismissCorrectionPanel(ReasonForDismissingAlternativeText reason) 560{ 561#if USE(AUTOCORRECTION_PANEL) 562 m_correctionPanel.dismiss(reason); 563#endif 564} 565 566String PageClientImpl::dismissCorrectionPanelSoon(WebCore::ReasonForDismissingAlternativeText reason) 567{ 568#if USE(AUTOCORRECTION_PANEL) 569 return m_correctionPanel.dismiss(reason); 570#else 571 return String(); 572#endif 573} 574 575void PageClientImpl::recordAutocorrectionResponse(AutocorrectionResponseType responseType, const String& replacedString, const String& replacementString) 576{ 577 NSCorrectionResponse response = responseType == AutocorrectionReverted ? NSCorrectionResponseReverted : NSCorrectionResponseEdited; 578 CorrectionPanel::recordAutocorrectionResponse(m_wkView, response, replacedString, replacementString); 579} 580 581void PageClientImpl::recommendedScrollbarStyleDidChange(int32_t newStyle) 582{ 583 NSArray *trackingAreas = [m_wkView trackingAreas]; 584 NSUInteger count = [trackingAreas count]; 585 ASSERT(count == 1); 586 587 for (NSUInteger i = 0; i < count; ++i) 588 [m_wkView removeTrackingArea:[trackingAreas objectAtIndex:i]]; 589 590 // Now re-create a tracking area with the appropriate options given the new scrollbar style 591 NSTrackingAreaOptions options = NSTrackingMouseMoved | NSTrackingMouseEnteredAndExited | NSTrackingInVisibleRect; 592 if (newStyle == NSScrollerStyleLegacy) 593 options |= NSTrackingActiveAlways; 594 else 595 options |= NSTrackingActiveInKeyWindow; 596 597 NSTrackingArea *trackingArea = [[NSTrackingArea alloc] initWithRect:[m_wkView frame] 598 options:options 599 owner:m_wkView 600 userInfo:nil]; 601 [m_wkView addTrackingArea:trackingArea]; 602 [trackingArea release]; 603} 604 605void PageClientImpl::intrinsicContentSizeDidChange(const IntSize& intrinsicContentSize) 606{ 607 [m_wkView _setIntrinsicContentSize:intrinsicContentSize]; 608} 609 610bool PageClientImpl::executeSavedCommandBySelector(const String& selectorString) 611{ 612 return [m_wkView _executeSavedCommandBySelector:NSSelectorFromString(selectorString)]; 613} 614 615#if USE(DICTATION_ALTERNATIVES) 616uint64_t PageClientImpl::addDictationAlternatives(const RetainPtr<NSTextAlternatives>& alternatives) 617{ 618 return m_alternativeTextUIController->addAlternatives(alternatives); 619} 620 621void PageClientImpl::removeDictationAlternatives(uint64_t dictationContext) 622{ 623 m_alternativeTextUIController->removeAlternatives(dictationContext); 624} 625 626void PageClientImpl::showDictationAlternativeUI(const WebCore::FloatRect& boundingBoxOfDictatedText, uint64_t dictationContext) 627{ 628 if (!isViewVisible() || !isViewInWindow()) 629 return; 630 m_alternativeTextUIController->showAlternatives(m_wkView, boundingBoxOfDictatedText, dictationContext, ^(NSString* acceptedAlternative){ 631 [m_wkView handleAcceptedAlternativeText:acceptedAlternative]; 632 }); 633} 634 635Vector<String> PageClientImpl::dictationAlternatives(uint64_t dictationContext) 636{ 637 return m_alternativeTextUIController->alternativesForContext(dictationContext); 638} 639#endif 640 641#if ENABLE(FULLSCREEN_API) 642 643WebFullScreenManagerProxyClient& PageClientImpl::fullScreenManagerProxyClient() 644{ 645 return *this; 646} 647 648// WebFullScreenManagerProxyClient 649 650void PageClientImpl::closeFullScreenManager() 651{ 652 [m_wkView _closeFullScreenWindowController]; 653} 654 655bool PageClientImpl::isFullScreen() 656{ 657 if (!m_wkView._hasFullScreenWindowController) 658 return false; 659 660 return m_wkView._fullScreenWindowController.isFullScreen; 661} 662 663void PageClientImpl::enterFullScreen() 664{ 665 [m_wkView._fullScreenWindowController enterFullScreen:nil]; 666} 667 668void PageClientImpl::exitFullScreen() 669{ 670 [m_wkView._fullScreenWindowController exitFullScreen]; 671} 672 673void PageClientImpl::beganEnterFullScreen(const IntRect& initialFrame, const IntRect& finalFrame) 674{ 675 [m_wkView._fullScreenWindowController beganEnterFullScreenWithInitialFrame:initialFrame finalFrame:finalFrame]; 676} 677 678void PageClientImpl::beganExitFullScreen(const IntRect& initialFrame, const IntRect& finalFrame) 679{ 680 [m_wkView._fullScreenWindowController beganExitFullScreenWithInitialFrame:initialFrame finalFrame:finalFrame]; 681} 682 683#endif // ENABLE(FULLSCREEN_API) 684 685void PageClientImpl::navigationGestureDidBegin() 686{ 687#if WK_API_ENABLED 688 if (m_webView) 689 NavigationState::fromWebPage(*m_webView->_page).navigationGestureDidBegin(); 690#endif 691} 692 693void PageClientImpl::navigationGestureWillEnd(bool willNavigate, WebBackForwardListItem& item) 694{ 695#if WK_API_ENABLED 696 if (m_webView) 697 NavigationState::fromWebPage(*m_webView->_page).navigationGestureWillEnd(willNavigate, item); 698#else 699 UNUSED_PARAM(willNavigate); 700 UNUSED_PARAM(item); 701#endif 702} 703 704void PageClientImpl::navigationGestureDidEnd(bool willNavigate, WebBackForwardListItem& item) 705{ 706#if WK_API_ENABLED 707 if (m_webView) 708 NavigationState::fromWebPage(*m_webView->_page).navigationGestureDidEnd(willNavigate, item); 709#else 710 UNUSED_PARAM(willNavigate); 711 UNUSED_PARAM(item); 712#endif 713} 714 715void PageClientImpl::willRecordNavigationSnapshot(WebBackForwardListItem& item) 716{ 717#if WK_API_ENABLED 718 if (m_webView) 719 NavigationState::fromWebPage(*m_webView->_page).willRecordNavigationSnapshot(item); 720#else 721 UNUSED_PARAM(item); 722#endif 723} 724 725void PageClientImpl::didFirstVisuallyNonEmptyLayoutForMainFrame() 726{ 727 [m_wkView _didFirstVisuallyNonEmptyLayoutForMainFrame]; 728} 729 730void PageClientImpl::didFinishLoadForMainFrame() 731{ 732 [m_wkView _didFinishLoadForMainFrame]; 733} 734 735void PageClientImpl::didSameDocumentNavigationForMainFrame(SameDocumentNavigationType type) 736{ 737 [m_wkView _didSameDocumentNavigationForMainFrame:type]; 738} 739 740void PageClientImpl::removeNavigationGestureSnapshot() 741{ 742 [m_wkView _removeNavigationGestureSnapshot]; 743} 744 745CGRect PageClientImpl::boundsOfLayerInLayerBackedWindowCoordinates(CALayer *layer) const 746{ 747 CALayer *windowContentLayer = static_cast<NSView *>(m_wkView.window.contentView).layer; 748 ASSERT(windowContentLayer); 749 750 return [windowContentLayer convertRect:layer.bounds fromLayer:layer]; 751} 752 753} // namespace WebKit 754 755#endif // PLATFORM(MAC) 756