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 #include "config.h" 27 #include "WebPage.h" 28 29 #include "Arguments.h" 30 #include "DataReference.h" 31 #include "DecoderAdapter.h" 32 #include "DrawingArea.h" 33 #include "InjectedBundle.h" 34 #include "InjectedBundleBackForwardList.h" 35 #include "LayerTreeHost.h" 36 #include "MessageID.h" 37 #include "NetscapePlugin.h" 38 #include "PageOverlay.h" 39 #include "PluginProxy.h" 40 #include "PluginView.h" 41 #include "PrintInfo.h" 42 #include "RunLoop.h" 43 #include "SessionState.h" 44 #include "ShareableBitmap.h" 45 #include "WebBackForwardList.h" 46 #include "WebBackForwardListItem.h" 47 #include "WebBackForwardListProxy.h" 48 #include "WebChromeClient.h" 49 #include "WebContextMenu.h" 50 #include "WebContextMenuClient.h" 51 #include "WebContextMessages.h" 52 #include "WebCoreArgumentCoders.h" 53 #include "WebDragClient.h" 54 #include "WebEditorClient.h" 55 #include "WebEvent.h" 56 #include "WebEventConversion.h" 57 #include "WebFrame.h" 58 #include "WebFullScreenManager.h" 59 #include "WebGeolocationClient.h" 60 #include "WebImage.h" 61 #include "WebInspector.h" 62 #include "WebInspectorClient.h" 63 #include "WebOpenPanelResultListener.h" 64 #include "WebPageCreationParameters.h" 65 #include "WebPageGroupProxy.h" 66 #include "WebPageProxyMessages.h" 67 #include "WebPopupMenu.h" 68 #include "WebPreferencesStore.h" 69 #include "WebProcess.h" 70 #include "WebProcessProxyMessages.h" 71 #include <JavaScriptCore/APICast.h> 72 #include <WebCore/AbstractDatabase.h> 73 #include <WebCore/ArchiveResource.h> 74 #include <WebCore/Chrome.h> 75 #include <WebCore/ContextMenuController.h> 76 #include <WebCore/DocumentFragment.h> 77 #include <WebCore/DocumentLoader.h> 78 #include <WebCore/DocumentMarkerController.h> 79 #include <WebCore/DragController.h> 80 #include <WebCore/DragData.h> 81 #include <WebCore/EditingBehavior.h> 82 #include <WebCore/EventHandler.h> 83 #include <WebCore/FocusController.h> 84 #include <WebCore/FormState.h> 85 #include <WebCore/Frame.h> 86 #include <WebCore/FrameLoadRequest.h> 87 #include <WebCore/FrameLoaderTypes.h> 88 #include <WebCore/FrameView.h> 89 #include <WebCore/HTMLFormElement.h> 90 #include <WebCore/HistoryItem.h> 91 #include <WebCore/KeyboardEvent.h> 92 #include <WebCore/MouseEvent.h> 93 #include <WebCore/Page.h> 94 #include <WebCore/PlatformKeyboardEvent.h> 95 #include <WebCore/PrintContext.h> 96 #include <WebCore/RenderLayer.h> 97 #include <WebCore/RenderTreeAsText.h> 98 #include <WebCore/RenderView.h> 99 #include <WebCore/ReplaceSelectionCommand.h> 100 #include <WebCore/ResourceRequest.h> 101 #include <WebCore/SchemeRegistry.h> 102 #include <WebCore/SerializedScriptValue.h> 103 #include <WebCore/Settings.h> 104 #include <WebCore/SharedBuffer.h> 105 #include <WebCore/SubstituteData.h> 106 #include <WebCore/TextIterator.h> 107 #include <WebCore/markup.h> 108 #include <runtime/JSLock.h> 109 #include <runtime/JSValue.h> 110 111 #include <WebCore/Range.h> 112 #include <WebCore/VisiblePosition.h> 113 114 #if PLATFORM(MAC) || PLATFORM(WIN) 115 #include <WebCore/LegacyWebArchive.h> 116 #endif 117 118 #if ENABLE(PLUGIN_PROCESS) 119 #if PLATFORM(MAC) 120 #include "MachPort.h" 121 #endif 122 #endif 123 124 #if PLATFORM(QT) 125 #include "HitTestResult.h" 126 #endif 127 128 #ifndef NDEBUG 129 #include <wtf/RefCountedLeakCounter.h> 130 #endif 131 132 using namespace JSC; 133 using namespace WebCore; 134 135 namespace WebKit { 136 137 #ifndef NDEBUG 138 static WTF::RefCountedLeakCounter webPageCounter("WebPage"); 139 #endif 140 141 PassRefPtr<WebPage> WebPage::create(uint64_t pageID, const WebPageCreationParameters& parameters) 142 { 143 RefPtr<WebPage> page = adoptRef(new WebPage(pageID, parameters)); 144 145 if (page->pageGroup()->isVisibleToInjectedBundle() && WebProcess::shared().injectedBundle()) 146 WebProcess::shared().injectedBundle()->didCreatePage(page.get()); 147 148 return page.release(); 149 } 150 151 WebPage::WebPage(uint64_t pageID, const WebPageCreationParameters& parameters) 152 : m_viewSize(parameters.viewSize) 153 , m_drawsBackground(true) 154 , m_drawsTransparentBackground(false) 155 , m_isInRedo(false) 156 , m_isClosed(false) 157 , m_tabToLinks(false) 158 #if PLATFORM(MAC) 159 , m_windowIsVisible(false) 160 , m_isSmartInsertDeleteEnabled(parameters.isSmartInsertDeleteEnabled) 161 , m_keyboardEventBeingInterpreted(0) 162 #elif PLATFORM(WIN) 163 , m_nativeWindow(parameters.nativeWindow) 164 #endif 165 , m_findController(this) 166 , m_geolocationPermissionRequestManager(this) 167 , m_pageID(pageID) 168 , m_canRunBeforeUnloadConfirmPanel(parameters.canRunBeforeUnloadConfirmPanel) 169 , m_canRunModal(parameters.canRunModal) 170 , m_isRunningModal(false) 171 , m_userSpaceScaleFactor(parameters.userSpaceScaleFactor) 172 , m_cachedMainFrameIsPinnedToLeftSide(false) 173 , m_cachedMainFrameIsPinnedToRightSide(false) 174 , m_isShowingContextMenu(false) 175 #if PLATFORM(WIN) 176 , m_gestureReachedScrollingLimit(false) 177 #endif 178 { 179 ASSERT(m_pageID); 180 181 Page::PageClients pageClients; 182 pageClients.chromeClient = new WebChromeClient(this); 183 pageClients.contextMenuClient = new WebContextMenuClient(this); 184 pageClients.editorClient = new WebEditorClient(this); 185 pageClients.dragClient = new WebDragClient(this); 186 pageClients.backForwardClient = WebBackForwardListProxy::create(this); 187 #if ENABLE(CLIENT_BASED_GEOLOCATION) 188 pageClients.geolocationClient = new WebGeolocationClient(this); 189 #endif 190 #if ENABLE(INSPECTOR) 191 pageClients.inspectorClient = new WebInspectorClient(this); 192 #endif 193 m_page = adoptPtr(new Page(pageClients)); 194 195 // Qt does not yet call setIsInWindow. Until it does, just leave 196 // this line out so plug-ins and video will work. Eventually all platforms 197 // should call setIsInWindow and this comment and #if should be removed, 198 // leaving behind the setCanStartMedia call. 199 #if !PLATFORM(QT) 200 m_page->setCanStartMedia(false); 201 #endif 202 203 updatePreferences(parameters.store); 204 205 m_pageGroup = WebProcess::shared().webPageGroup(parameters.pageGroupData); 206 m_page->setGroupName(m_pageGroup->identifier()); 207 208 platformInitialize(); 209 Settings::setDefaultMinDOMTimerInterval(0.004); 210 211 m_drawingArea = DrawingArea::create(this, parameters); 212 m_mainFrame = WebFrame::createMainFrame(this); 213 214 setDrawsBackground(parameters.drawsBackground); 215 setDrawsTransparentBackground(parameters.drawsTransparentBackground); 216 217 setMemoryCacheMessagesEnabled(parameters.areMemoryCacheClientCallsEnabled); 218 219 setActive(parameters.isActive); 220 setFocused(parameters.isFocused); 221 setIsInWindow(parameters.isInWindow); 222 223 m_userAgent = parameters.userAgent; 224 225 WebBackForwardListProxy::setHighestItemIDFromUIProcess(parameters.highestUsedBackForwardItemID); 226 227 if (!parameters.sessionState.isEmpty()) 228 restoreSession(parameters.sessionState); 229 230 #ifndef NDEBUG 231 webPageCounter.increment(); 232 #endif 233 } 234 235 WebPage::~WebPage() 236 { 237 if (m_backForwardList) 238 m_backForwardList->detach(); 239 240 ASSERT(!m_page); 241 242 m_sandboxExtensionTracker.invalidate(); 243 244 #if PLATFORM(MAC) 245 ASSERT(m_pluginViews.isEmpty()); 246 #endif 247 248 #ifndef NDEBUG 249 webPageCounter.decrement(); 250 #endif 251 } 252 253 void WebPage::dummy(bool&) 254 { 255 } 256 257 CoreIPC::Connection* WebPage::connection() const 258 { 259 return WebProcess::shared().connection(); 260 } 261 262 void WebPage::initializeInjectedBundleContextMenuClient(WKBundlePageContextMenuClient* client) 263 { 264 m_contextMenuClient.initialize(client); 265 } 266 267 void WebPage::initializeInjectedBundleEditorClient(WKBundlePageEditorClient* client) 268 { 269 m_editorClient.initialize(client); 270 } 271 272 void WebPage::initializeInjectedBundleFormClient(WKBundlePageFormClient* client) 273 { 274 m_formClient.initialize(client); 275 } 276 277 void WebPage::initializeInjectedBundleLoaderClient(WKBundlePageLoaderClient* client) 278 { 279 m_loaderClient.initialize(client); 280 } 281 282 void WebPage::initializeInjectedBundlePolicyClient(WKBundlePagePolicyClient* client) 283 { 284 m_policyClient.initialize(client); 285 } 286 287 void WebPage::initializeInjectedBundleResourceLoadClient(WKBundlePageResourceLoadClient* client) 288 { 289 m_resourceLoadClient.initialize(client); 290 } 291 292 void WebPage::initializeInjectedBundleUIClient(WKBundlePageUIClient* client) 293 { 294 m_uiClient.initialize(client); 295 } 296 297 #if ENABLE(FULLSCREEN_API) 298 void WebPage::initializeInjectedBundleFullScreenClient(WKBundlePageFullScreenClient* client) 299 { 300 m_fullScreenClient.initialize(client); 301 } 302 #endif 303 304 PassRefPtr<Plugin> WebPage::createPlugin(const Plugin::Parameters& parameters) 305 { 306 String pluginPath; 307 308 if (!WebProcess::shared().connection()->sendSync( 309 Messages::WebContext::GetPluginPath(parameters.mimeType, parameters.url.string()), 310 Messages::WebContext::GetPluginPath::Reply(pluginPath), 0)) { 311 return 0; 312 } 313 314 if (pluginPath.isNull()) 315 return 0; 316 317 #if ENABLE(PLUGIN_PROCESS) 318 return PluginProxy::create(pluginPath); 319 #else 320 return NetscapePlugin::create(NetscapePluginModule::getOrCreate(pluginPath)); 321 #endif 322 } 323 324 EditorState WebPage::editorState() const 325 { 326 Frame* frame = m_page->focusController()->focusedOrMainFrame(); 327 ASSERT(frame); 328 329 EditorState result; 330 result.selectionIsNone = frame->selection()->isNone(); 331 result.selectionIsRange = frame->selection()->isRange(); 332 result.isContentEditable = frame->selection()->isContentEditable(); 333 result.isContentRichlyEditable = frame->selection()->isContentRichlyEditable(); 334 result.isInPasswordField = frame->selection()->isInPasswordField(); 335 result.hasComposition = frame->editor()->hasComposition(); 336 337 return result; 338 } 339 340 String WebPage::renderTreeExternalRepresentation() const 341 { 342 return externalRepresentation(m_mainFrame->coreFrame(), RenderAsTextBehaviorNormal); 343 } 344 345 void WebPage::executeEditingCommand(const String& commandName, const String& argument) 346 { 347 Frame* frame = m_page->focusController()->focusedOrMainFrame(); 348 if (!frame) 349 return; 350 frame->editor()->command(commandName).execute(argument); 351 } 352 353 bool WebPage::isEditingCommandEnabled(const String& commandName) 354 { 355 Frame* frame = m_page->focusController()->focusedOrMainFrame(); 356 if (!frame) 357 return false; 358 359 Editor::Command command = frame->editor()->command(commandName); 360 return command.isSupported() && command.isEnabled(); 361 } 362 363 void WebPage::clearMainFrameName() 364 { 365 mainFrame()->coreFrame()->tree()->clearName(); 366 } 367 368 #if USE(ACCELERATED_COMPOSITING) 369 void WebPage::enterAcceleratedCompositingMode(GraphicsLayer* layer) 370 { 371 m_drawingArea->setRootCompositingLayer(layer); 372 } 373 374 void WebPage::exitAcceleratedCompositingMode() 375 { 376 m_drawingArea->setRootCompositingLayer(0); 377 } 378 #endif 379 380 void WebPage::close() 381 { 382 if (m_isClosed) 383 return; 384 385 m_isClosed = true; 386 387 if (pageGroup()->isVisibleToInjectedBundle() && WebProcess::shared().injectedBundle()) 388 WebProcess::shared().injectedBundle()->willDestroyPage(this); 389 390 #if ENABLE(INSPECTOR) 391 m_inspector = 0; 392 #endif 393 #if ENABLE(FULLSCREEN_API) 394 m_fullScreenManager = 0; 395 #endif 396 397 if (m_activePopupMenu) { 398 m_activePopupMenu->disconnectFromPage(); 399 m_activePopupMenu = 0; 400 } 401 402 if (m_activeOpenPanelResultListener) { 403 m_activeOpenPanelResultListener->disconnectFromPage(); 404 m_activeOpenPanelResultListener = 0; 405 } 406 407 m_sandboxExtensionTracker.invalidate(); 408 409 m_printContext = nullptr; 410 411 m_mainFrame->coreFrame()->loader()->detachFromParent(); 412 m_page.clear(); 413 414 m_drawingArea.clear(); 415 416 bool isRunningModal = m_isRunningModal; 417 m_isRunningModal = false; 418 419 // The WebPage can be destroyed by this call. 420 WebProcess::shared().removeWebPage(m_pageID); 421 422 if (isRunningModal) 423 WebProcess::shared().runLoop()->stop(); 424 } 425 426 void WebPage::tryClose() 427 { 428 if (!m_mainFrame->coreFrame()->loader()->shouldClose()) 429 return; 430 431 sendClose(); 432 } 433 434 void WebPage::sendClose() 435 { 436 send(Messages::WebPageProxy::ClosePage()); 437 } 438 439 void WebPage::loadURL(const String& url, const SandboxExtension::Handle& sandboxExtensionHandle) 440 { 441 loadURLRequest(ResourceRequest(KURL(KURL(), url)), sandboxExtensionHandle); 442 } 443 444 void WebPage::loadURLRequest(const ResourceRequest& request, const SandboxExtension::Handle& sandboxExtensionHandle) 445 { 446 m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), sandboxExtensionHandle); 447 m_mainFrame->coreFrame()->loader()->load(request, false); 448 } 449 450 void WebPage::loadData(PassRefPtr<SharedBuffer> sharedBuffer, const String& MIMEType, const String& encodingName, const KURL& baseURL, const KURL& unreachableURL) 451 { 452 ResourceRequest request(baseURL); 453 SubstituteData substituteData(sharedBuffer, MIMEType, encodingName, unreachableURL); 454 m_mainFrame->coreFrame()->loader()->load(request, substituteData, false); 455 } 456 457 void WebPage::loadHTMLString(const String& htmlString, const String& baseURLString) 458 { 459 RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(htmlString.characters()), htmlString.length() * sizeof(UChar)); 460 KURL baseURL = baseURLString.isEmpty() ? blankURL() : KURL(KURL(), baseURLString); 461 loadData(sharedBuffer, "text/html", "utf-16", baseURL, KURL()); 462 } 463 464 void WebPage::loadAlternateHTMLString(const String& htmlString, const String& baseURLString, const String& unreachableURLString) 465 { 466 RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(htmlString.characters()), htmlString.length() * sizeof(UChar)); 467 KURL baseURL = baseURLString.isEmpty() ? blankURL() : KURL(KURL(), baseURLString); 468 KURL unreachableURL = unreachableURLString.isEmpty() ? KURL() : KURL(KURL(), unreachableURLString); 469 loadData(sharedBuffer, "text/html", "utf-16", baseURL, unreachableURL); 470 } 471 472 void WebPage::loadPlainTextString(const String& string) 473 { 474 RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(string.characters()), string.length() * sizeof(UChar)); 475 loadData(sharedBuffer, "text/plain", "utf-16", blankURL(), KURL()); 476 } 477 478 void WebPage::linkClicked(const String& url, const WebMouseEvent& event) 479 { 480 Frame* frame = m_page->mainFrame(); 481 if (!frame) 482 return; 483 484 RefPtr<Event> coreEvent; 485 if (event.type() != WebEvent::NoType) 486 coreEvent = MouseEvent::create(eventNames().clickEvent, frame->document()->defaultView(), platform(event), 0, 0); 487 488 frame->loader()->loadFrameRequest(FrameLoadRequest(frame->document()->securityOrigin(), ResourceRequest(url)), 489 false, false, coreEvent.get(), 0, SendReferrer); 490 } 491 492 void WebPage::stopLoadingFrame(uint64_t frameID) 493 { 494 WebFrame* frame = WebProcess::shared().webFrame(frameID); 495 if (!frame) 496 return; 497 498 frame->coreFrame()->loader()->stopForUserCancel(); 499 } 500 501 void WebPage::stopLoading() 502 { 503 m_mainFrame->coreFrame()->loader()->stopForUserCancel(); 504 } 505 506 void WebPage::setDefersLoading(bool defersLoading) 507 { 508 m_page->setDefersLoading(defersLoading); 509 } 510 511 void WebPage::reload(bool reloadFromOrigin) 512 { 513 m_mainFrame->coreFrame()->loader()->reload(reloadFromOrigin); 514 } 515 516 void WebPage::goForward(uint64_t backForwardItemID, const SandboxExtension::Handle& sandboxExtensionHandle) 517 { 518 HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID); 519 ASSERT(item); 520 if (!item) 521 return; 522 523 m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), sandboxExtensionHandle); 524 m_page->goToItem(item, FrameLoadTypeForward); 525 } 526 527 void WebPage::goBack(uint64_t backForwardItemID, const SandboxExtension::Handle& sandboxExtensionHandle) 528 { 529 HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID); 530 ASSERT(item); 531 if (!item) 532 return; 533 534 m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), sandboxExtensionHandle); 535 m_page->goToItem(item, FrameLoadTypeBack); 536 } 537 538 void WebPage::goToBackForwardItem(uint64_t backForwardItemID, const SandboxExtension::Handle& sandboxExtensionHandle) 539 { 540 HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID); 541 ASSERT(item); 542 if (!item) 543 return; 544 545 m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), sandboxExtensionHandle); 546 m_page->goToItem(item, FrameLoadTypeIndexedBackForward); 547 } 548 549 void WebPage::layoutIfNeeded() 550 { 551 if (m_mainFrame->coreFrame()->view()) 552 m_mainFrame->coreFrame()->view()->updateLayoutAndStyleIfNeededRecursive(); 553 } 554 555 void WebPage::setSize(const WebCore::IntSize& viewSize) 556 { 557 #if ENABLE(TILED_BACKING_STORE) 558 // If we are resizing to content ignore external attempts. 559 if (!m_resizesToContentsLayoutSize.isEmpty()) 560 return; 561 #endif 562 563 if (m_viewSize == viewSize) 564 return; 565 566 Frame* frame = m_page->mainFrame(); 567 568 frame->view()->resize(viewSize); 569 frame->view()->setNeedsLayout(); 570 m_drawingArea->setNeedsDisplay(IntRect(IntPoint(0, 0), viewSize)); 571 572 m_viewSize = viewSize; 573 } 574 575 #if ENABLE(TILED_BACKING_STORE) 576 void WebPage::setActualVisibleContentRect(const IntRect& rect) 577 { 578 Frame* frame = m_page->mainFrame(); 579 580 frame->view()->setActualVisibleContentRect(rect); 581 } 582 583 void WebPage::setResizesToContentsUsingLayoutSize(const IntSize& targetLayoutSize) 584 { 585 if (m_resizesToContentsLayoutSize == targetLayoutSize) 586 return; 587 588 m_resizesToContentsLayoutSize = targetLayoutSize; 589 590 Frame* frame = m_page->mainFrame(); 591 if (m_resizesToContentsLayoutSize.isEmpty()) { 592 frame->view()->setDelegatesScrolling(false); 593 frame->view()->setUseFixedLayout(false); 594 frame->view()->setPaintsEntireContents(false); 595 } else { 596 frame->view()->setDelegatesScrolling(true); 597 frame->view()->setUseFixedLayout(true); 598 frame->view()->setPaintsEntireContents(true); 599 frame->view()->setFixedLayoutSize(m_resizesToContentsLayoutSize); 600 } 601 frame->view()->forceLayout(); 602 } 603 604 void WebPage::resizeToContentsIfNeeded() 605 { 606 if (m_resizesToContentsLayoutSize.isEmpty()) 607 return; 608 609 Frame* frame = m_page->mainFrame(); 610 611 IntSize contentSize = frame->view()->contentsSize(); 612 if (contentSize == m_viewSize) 613 return; 614 615 m_viewSize = contentSize; 616 frame->view()->resize(m_viewSize); 617 frame->view()->setNeedsLayout(); 618 } 619 #endif 620 621 void WebPage::scrollMainFrameIfNotAtMaxScrollPosition(const IntSize& scrollOffset) 622 { 623 Frame* frame = m_page->mainFrame(); 624 625 IntPoint scrollPosition = frame->view()->scrollPosition(); 626 IntPoint maximumScrollPosition = frame->view()->maximumScrollPosition(); 627 628 // If the current scroll position in a direction is the max scroll position 629 // we don't want to scroll at all. 630 IntSize newScrollOffset; 631 if (scrollPosition.x() < maximumScrollPosition.x()) 632 newScrollOffset.setWidth(scrollOffset.width()); 633 if (scrollPosition.y() < maximumScrollPosition.y()) 634 newScrollOffset.setHeight(scrollOffset.height()); 635 636 if (newScrollOffset.isZero()) 637 return; 638 639 frame->view()->setScrollPosition(frame->view()->scrollPosition() + newScrollOffset); 640 } 641 642 void WebPage::drawRect(GraphicsContext& graphicsContext, const IntRect& rect) 643 { 644 graphicsContext.save(); 645 graphicsContext.clip(rect); 646 m_mainFrame->coreFrame()->view()->paint(&graphicsContext, rect); 647 graphicsContext.restore(); 648 } 649 650 void WebPage::drawPageOverlay(GraphicsContext& graphicsContext, const IntRect& rect) 651 { 652 ASSERT(m_pageOverlay); 653 654 graphicsContext.save(); 655 graphicsContext.clip(rect); 656 m_pageOverlay->drawRect(graphicsContext, rect); 657 graphicsContext.restore(); 658 } 659 660 double WebPage::textZoomFactor() const 661 { 662 Frame* frame = m_mainFrame->coreFrame(); 663 if (!frame) 664 return 1; 665 return frame->textZoomFactor(); 666 } 667 668 void WebPage::setTextZoomFactor(double zoomFactor) 669 { 670 Frame* frame = m_mainFrame->coreFrame(); 671 if (!frame) 672 return; 673 frame->setTextZoomFactor(static_cast<float>(zoomFactor)); 674 } 675 676 double WebPage::pageZoomFactor() const 677 { 678 Frame* frame = m_mainFrame->coreFrame(); 679 if (!frame) 680 return 1; 681 return frame->pageZoomFactor(); 682 } 683 684 void WebPage::setPageZoomFactor(double zoomFactor) 685 { 686 Frame* frame = m_mainFrame->coreFrame(); 687 if (!frame) 688 return; 689 frame->setPageZoomFactor(static_cast<float>(zoomFactor)); 690 } 691 692 void WebPage::setPageAndTextZoomFactors(double pageZoomFactor, double textZoomFactor) 693 { 694 Frame* frame = m_mainFrame->coreFrame(); 695 if (!frame) 696 return; 697 return frame->setPageAndTextZoomFactors(static_cast<float>(pageZoomFactor), static_cast<float>(textZoomFactor)); 698 } 699 700 void WebPage::scaleWebView(double scale, const IntPoint& origin) 701 { 702 Frame* frame = m_mainFrame->coreFrame(); 703 if (!frame) 704 return; 705 frame->scalePage(scale, origin); 706 707 send(Messages::WebPageProxy::ViewScaleFactorDidChange(scale)); 708 } 709 710 double WebPage::viewScaleFactor() const 711 { 712 Frame* frame = m_mainFrame->coreFrame(); 713 if (!frame) 714 return 1; 715 return frame->pageScaleFactor(); 716 } 717 718 void WebPage::setUseFixedLayout(bool fixed) 719 { 720 Frame* frame = m_mainFrame->coreFrame(); 721 if (!frame) 722 return; 723 724 FrameView* view = frame->view(); 725 if (!view) 726 return; 727 728 view->setUseFixedLayout(fixed); 729 if (!fixed) 730 view->setFixedLayoutSize(IntSize()); 731 } 732 733 void WebPage::setFixedLayoutSize(const IntSize& size) 734 { 735 Frame* frame = m_mainFrame->coreFrame(); 736 if (!frame) 737 return; 738 739 FrameView* view = frame->view(); 740 if (!view) 741 return; 742 743 view->setFixedLayoutSize(size); 744 view->forceLayout(); 745 } 746 747 void WebPage::installPageOverlay(PassRefPtr<PageOverlay> pageOverlay) 748 { 749 bool shouldFadeIn = true; 750 751 if (m_pageOverlay) { 752 m_pageOverlay->setPage(0); 753 754 if (pageOverlay) { 755 // We're installing a page overlay when a page overlay is already active. 756 // In this case we don't want to fade in the new overlay. 757 shouldFadeIn = false; 758 } 759 } 760 761 m_pageOverlay = pageOverlay; 762 m_pageOverlay->setPage(this); 763 764 if (shouldFadeIn) 765 m_pageOverlay->startFadeInAnimation(); 766 767 m_drawingArea->didInstallPageOverlay(); 768 m_pageOverlay->setNeedsDisplay(); 769 } 770 771 void WebPage::uninstallPageOverlay(PageOverlay* pageOverlay, bool fadeOut) 772 { 773 if (pageOverlay != m_pageOverlay) 774 return; 775 776 if (fadeOut) { 777 m_pageOverlay->startFadeOutAnimation(); 778 return; 779 } 780 781 m_pageOverlay->setPage(0); 782 m_pageOverlay = nullptr; 783 784 m_drawingArea->didUninstallPageOverlay(); 785 } 786 787 PassRefPtr<WebImage> WebPage::snapshotInViewCoordinates(const IntRect& rect, ImageOptions options) 788 { 789 FrameView* frameView = m_mainFrame->coreFrame()->view(); 790 if (!frameView) 791 return 0; 792 793 frameView->updateLayoutAndStyleIfNeededRecursive(); 794 795 PaintBehavior oldBehavior = frameView->paintBehavior(); 796 frameView->setPaintBehavior(oldBehavior | PaintBehaviorFlattenCompositingLayers); 797 798 RefPtr<WebImage> snapshot = WebImage::create(rect.size(), options); 799 OwnPtr<WebCore::GraphicsContext> graphicsContext = snapshot->bitmap()->createGraphicsContext(); 800 801 graphicsContext->save(); 802 graphicsContext->translate(-rect.x(), -rect.y()); 803 frameView->paint(graphicsContext.get(), rect); 804 graphicsContext->restore(); 805 806 frameView->setPaintBehavior(oldBehavior); 807 808 return snapshot.release(); 809 } 810 811 PassRefPtr<WebImage> WebPage::scaledSnapshotInDocumentCoordinates(const IntRect& rect, double scaleFactor, ImageOptions options) 812 { 813 FrameView* frameView = m_mainFrame->coreFrame()->view(); 814 if (!frameView) 815 return 0; 816 817 frameView->updateLayoutAndStyleIfNeededRecursive(); 818 819 PaintBehavior oldBehavior = frameView->paintBehavior(); 820 frameView->setPaintBehavior(oldBehavior | PaintBehaviorFlattenCompositingLayers); 821 822 bool scale = scaleFactor != 1; 823 IntSize size = rect.size(); 824 if (scale) 825 size = IntSize(ceil(rect.width() * scaleFactor), ceil(rect.height() * scaleFactor)); 826 827 RefPtr<WebImage> snapshot = WebImage::create(size, options); 828 OwnPtr<WebCore::GraphicsContext> graphicsContext = snapshot->bitmap()->createGraphicsContext(); 829 graphicsContext->save(); 830 831 if (scale) 832 graphicsContext->scale(FloatSize(scaleFactor, scaleFactor)); 833 834 graphicsContext->translate(-rect.x(), -rect.y()); 835 frameView->paintContents(graphicsContext.get(), rect); 836 graphicsContext->restore(); 837 838 frameView->setPaintBehavior(oldBehavior); 839 840 return snapshot.release(); 841 } 842 843 PassRefPtr<WebImage> WebPage::snapshotInDocumentCoordinates(const IntRect& rect, ImageOptions options) 844 { 845 return scaledSnapshotInDocumentCoordinates(rect, 1, options); 846 } 847 848 void WebPage::pageDidScroll() 849 { 850 // Hide the find indicator. 851 m_findController.hideFindIndicator(); 852 853 m_uiClient.pageDidScroll(this); 854 855 send(Messages::WebPageProxy::PageDidScroll()); 856 } 857 858 #if ENABLE(TILED_BACKING_STORE) 859 void WebPage::pageDidRequestScroll(const IntPoint& point) 860 { 861 send(Messages::WebPageProxy::PageDidRequestScroll(point)); 862 } 863 #endif 864 865 WebContextMenu* WebPage::contextMenu() 866 { 867 if (!m_contextMenu) 868 m_contextMenu = WebContextMenu::create(this); 869 return m_contextMenu.get(); 870 } 871 872 // Events 873 874 static const WebEvent* g_currentEvent = 0; 875 876 // FIXME: WebPage::currentEvent is used by the plug-in code to avoid having to convert from DOM events back to 877 // WebEvents. When we get the event handling sorted out, this should go away and the Widgets should get the correct 878 // platform events passed to the event handler code. 879 const WebEvent* WebPage::currentEvent() 880 { 881 return g_currentEvent; 882 } 883 884 class CurrentEvent { 885 public: 886 explicit CurrentEvent(const WebEvent& event) 887 : m_previousCurrentEvent(g_currentEvent) 888 { 889 g_currentEvent = &event; 890 } 891 892 ~CurrentEvent() 893 { 894 g_currentEvent = m_previousCurrentEvent; 895 } 896 897 private: 898 const WebEvent* m_previousCurrentEvent; 899 }; 900 901 static bool isContextClick(const PlatformMouseEvent& event) 902 { 903 if (event.button() == WebCore::RightButton) 904 return true; 905 906 #if PLATFORM(MAC) 907 // FIXME: this really should be about OSX-style UI, not about the Mac port 908 if (event.button() == WebCore::LeftButton && event.ctrlKey()) 909 return true; 910 #endif 911 912 return false; 913 } 914 915 static bool handleMouseEvent(const WebMouseEvent& mouseEvent, Page* page) 916 { 917 Frame* frame = page->mainFrame(); 918 if (!frame->view()) 919 return false; 920 921 PlatformMouseEvent platformMouseEvent = platform(mouseEvent); 922 923 switch (platformMouseEvent.eventType()) { 924 case WebCore::MouseEventPressed: 925 { 926 if (isContextClick(platformMouseEvent)) 927 page->contextMenuController()->clearContextMenu(); 928 929 bool handled = frame->eventHandler()->handleMousePressEvent(platformMouseEvent); 930 931 if (isContextClick(platformMouseEvent)) { 932 handled = frame->eventHandler()->sendContextMenuEvent(platformMouseEvent); 933 if (handled) 934 page->chrome()->showContextMenu(); 935 } 936 937 return handled; 938 } 939 case WebCore::MouseEventReleased: 940 return frame->eventHandler()->handleMouseReleaseEvent(platformMouseEvent); 941 case WebCore::MouseEventMoved: 942 return frame->eventHandler()->mouseMoved(platformMouseEvent); 943 944 default: 945 ASSERT_NOT_REACHED(); 946 return false; 947 } 948 } 949 950 void WebPage::mouseEvent(const WebMouseEvent& mouseEvent) 951 { 952 // Don't try to handle any pending mouse events if a context menu is showing. 953 if (m_isShowingContextMenu) { 954 send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(mouseEvent.type()), false)); 955 return; 956 } 957 958 bool handled = false; 959 960 if (m_pageOverlay) { 961 // Let the page overlay handle the event. 962 handled = m_pageOverlay->mouseEvent(mouseEvent); 963 } 964 965 if (!handled) { 966 CurrentEvent currentEvent(mouseEvent); 967 968 handled = handleMouseEvent(mouseEvent, m_page.get()); 969 } 970 971 send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(mouseEvent.type()), handled)); 972 } 973 974 static bool handleWheelEvent(const WebWheelEvent& wheelEvent, Page* page) 975 { 976 Frame* frame = page->mainFrame(); 977 if (!frame->view()) 978 return false; 979 980 PlatformWheelEvent platformWheelEvent = platform(wheelEvent); 981 return frame->eventHandler()->handleWheelEvent(platformWheelEvent); 982 } 983 984 void WebPage::wheelEvent(const WebWheelEvent& wheelEvent) 985 { 986 CurrentEvent currentEvent(wheelEvent); 987 988 bool handled = handleWheelEvent(wheelEvent, m_page.get()); 989 send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(wheelEvent.type()), handled)); 990 } 991 992 static bool handleKeyEvent(const WebKeyboardEvent& keyboardEvent, Page* page) 993 { 994 if (!page->mainFrame()->view()) 995 return false; 996 997 if (keyboardEvent.type() == WebEvent::Char && keyboardEvent.isSystemKey()) 998 return page->focusController()->focusedOrMainFrame()->eventHandler()->handleAccessKey(platform(keyboardEvent)); 999 return page->focusController()->focusedOrMainFrame()->eventHandler()->keyEvent(platform(keyboardEvent)); 1000 } 1001 1002 void WebPage::keyEvent(const WebKeyboardEvent& keyboardEvent) 1003 { 1004 CurrentEvent currentEvent(keyboardEvent); 1005 1006 bool handled = handleKeyEvent(keyboardEvent, m_page.get()); 1007 // FIXME: Platform default behaviors should be performed during normal DOM event dispatch (in most cases, in default keydown event handler). 1008 if (!handled) 1009 handled = performDefaultBehaviorForKeyEvent(keyboardEvent); 1010 1011 send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(keyboardEvent.type()), handled)); 1012 } 1013 1014 #if ENABLE(GESTURE_EVENTS) 1015 static bool handleGestureEvent(const WebGestureEvent& gestureEvent, Page* page) 1016 { 1017 Frame* frame = page->mainFrame(); 1018 if (!frame->view()) 1019 return false; 1020 1021 PlatformGestureEvent platformGestureEvent = platform(gestureEvent); 1022 return frame->eventHandler()->handleGestureEvent(platformGestureEvent); 1023 } 1024 1025 void WebPage::gestureEvent(const WebGestureEvent& gestureEvent) 1026 { 1027 CurrentEvent currentEvent(gestureEvent); 1028 1029 bool handled = handleGestureEvent(gestureEvent, m_page.get()); 1030 send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(gestureEvent.type()), handled)); 1031 } 1032 #endif 1033 1034 void WebPage::validateCommand(const String& commandName, uint64_t callbackID) 1035 { 1036 bool isEnabled = false; 1037 int32_t state = 0; 1038 Frame* frame = m_page->focusController()->focusedOrMainFrame(); 1039 if (frame) { 1040 Editor::Command command = frame->editor()->command(commandName); 1041 state = command.state(); 1042 isEnabled = command.isSupported() && command.isEnabled(); 1043 } 1044 1045 send(Messages::WebPageProxy::ValidateCommandCallback(commandName, isEnabled, state, callbackID)); 1046 } 1047 1048 void WebPage::executeEditCommand(const String& commandName) 1049 { 1050 executeEditingCommand(commandName, String()); 1051 } 1052 1053 uint64_t WebPage::restoreSession(const SessionState& sessionState) 1054 { 1055 const BackForwardListItemVector& list = sessionState.list(); 1056 size_t size = list.size(); 1057 uint64_t currentItemID = 0; 1058 for (size_t i = 0; i < size; ++i) { 1059 WebBackForwardListItem* webItem = list[i].get(); 1060 DecoderAdapter decoder(webItem->backForwardData().data(), webItem->backForwardData().size()); 1061 1062 RefPtr<HistoryItem> item = HistoryItem::decodeBackForwardTree(webItem->url(), webItem->title(), webItem->originalURL(), decoder); 1063 if (!item) { 1064 LOG_ERROR("Failed to decode a HistoryItem from session state data."); 1065 return 0; 1066 } 1067 1068 if (i == sessionState.currentIndex()) 1069 currentItemID = webItem->itemID(); 1070 1071 WebBackForwardListProxy::addItemFromUIProcess(list[i]->itemID(), item.release()); 1072 } 1073 ASSERT(currentItemID); 1074 return currentItemID; 1075 } 1076 1077 void WebPage::restoreSessionAndNavigateToCurrentItem(const SessionState& sessionState, const SandboxExtension::Handle& sandboxExtensionHandle) 1078 { 1079 if (uint64_t currentItemID = restoreSession(sessionState)) 1080 goToBackForwardItem(currentItemID, sandboxExtensionHandle); 1081 } 1082 1083 #if ENABLE(TOUCH_EVENTS) 1084 static bool handleTouchEvent(const WebTouchEvent& touchEvent, Page* page) 1085 { 1086 Frame* frame = page->mainFrame(); 1087 if (!frame->view()) 1088 return false; 1089 1090 return frame->eventHandler()->handleTouchEvent(platform(touchEvent)); 1091 } 1092 1093 void WebPage::touchEvent(const WebTouchEvent& touchEvent) 1094 { 1095 CurrentEvent currentEvent(touchEvent); 1096 1097 bool handled = handleTouchEvent(touchEvent, m_page.get()); 1098 1099 send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(touchEvent.type()), handled)); 1100 } 1101 #endif 1102 1103 void WebPage::scroll(Page* page, ScrollDirection direction, ScrollGranularity granularity) 1104 { 1105 page->focusController()->focusedOrMainFrame()->eventHandler()->scrollRecursively(direction, granularity); 1106 } 1107 1108 void WebPage::logicalScroll(Page* page, ScrollLogicalDirection direction, ScrollGranularity granularity) 1109 { 1110 page->focusController()->focusedOrMainFrame()->eventHandler()->logicalScrollRecursively(direction, granularity); 1111 } 1112 1113 void WebPage::scrollBy(uint32_t scrollDirection, uint32_t scrollGranularity) 1114 { 1115 scroll(m_page.get(), static_cast<ScrollDirection>(scrollDirection), static_cast<ScrollGranularity>(scrollGranularity)); 1116 } 1117 1118 void WebPage::setActive(bool isActive) 1119 { 1120 m_page->focusController()->setActive(isActive); 1121 1122 #if PLATFORM(MAC) 1123 // Tell all our plug-in views that the window focus changed. 1124 for (HashSet<PluginView*>::const_iterator it = m_pluginViews.begin(), end = m_pluginViews.end(); it != end; ++it) 1125 (*it)->setWindowIsFocused(isActive); 1126 #endif 1127 } 1128 1129 void WebPage::setDrawsBackground(bool drawsBackground) 1130 { 1131 if (m_drawsBackground == drawsBackground) 1132 return; 1133 1134 m_drawsBackground = drawsBackground; 1135 1136 for (Frame* coreFrame = m_mainFrame->coreFrame(); coreFrame; coreFrame = coreFrame->tree()->traverseNext()) { 1137 if (FrameView* view = coreFrame->view()) 1138 view->setTransparent(!drawsBackground); 1139 } 1140 1141 m_drawingArea->pageBackgroundTransparencyChanged(); 1142 m_drawingArea->setNeedsDisplay(IntRect(IntPoint(0, 0), m_viewSize)); 1143 } 1144 1145 void WebPage::setDrawsTransparentBackground(bool drawsTransparentBackground) 1146 { 1147 if (m_drawsTransparentBackground == drawsTransparentBackground) 1148 return; 1149 1150 m_drawsTransparentBackground = drawsTransparentBackground; 1151 1152 Color backgroundColor = drawsTransparentBackground ? Color::transparent : Color::white; 1153 for (Frame* coreFrame = m_mainFrame->coreFrame(); coreFrame; coreFrame = coreFrame->tree()->traverseNext()) { 1154 if (FrameView* view = coreFrame->view()) 1155 view->setBaseBackgroundColor(backgroundColor); 1156 } 1157 1158 m_drawingArea->pageBackgroundTransparencyChanged(); 1159 m_drawingArea->setNeedsDisplay(IntRect(IntPoint(0, 0), m_viewSize)); 1160 } 1161 1162 void WebPage::viewWillStartLiveResize() 1163 { 1164 if (!m_page) 1165 return; 1166 1167 // FIXME: This should propagate to all ScrollableAreas. 1168 if (Frame* frame = m_page->focusController()->focusedOrMainFrame()) { 1169 if (FrameView* view = frame->view()) 1170 view->willStartLiveResize(); 1171 } 1172 } 1173 1174 void WebPage::viewWillEndLiveResize() 1175 { 1176 if (!m_page) 1177 return; 1178 1179 // FIXME: This should propagate to all ScrollableAreas. 1180 if (Frame* frame = m_page->focusController()->focusedOrMainFrame()) { 1181 if (FrameView* view = frame->view()) 1182 view->willEndLiveResize(); 1183 } 1184 } 1185 1186 void WebPage::setFocused(bool isFocused) 1187 { 1188 if (!isFocused && m_page->focusController()->focusedOrMainFrame()->editor()->behavior().shouldClearSelectionWhenLosingWebPageFocus()) 1189 m_page->focusController()->focusedOrMainFrame()->selection()->clear(); 1190 1191 m_page->focusController()->setFocused(isFocused); 1192 } 1193 1194 void WebPage::setInitialFocus(bool forward) 1195 { 1196 if (!m_page || !m_page->focusController()) 1197 return; 1198 1199 Frame* frame = m_page->focusController()->focusedOrMainFrame(); 1200 frame->document()->setFocusedNode(0); 1201 m_page->focusController()->setInitialFocus(forward ? FocusDirectionForward : FocusDirectionBackward, 0); 1202 } 1203 1204 void WebPage::setWindowResizerSize(const IntSize& windowResizerSize) 1205 { 1206 if (m_windowResizerSize == windowResizerSize) 1207 return; 1208 1209 m_windowResizerSize = windowResizerSize; 1210 1211 for (Frame* coreFrame = m_mainFrame->coreFrame(); coreFrame; coreFrame = coreFrame->tree()->traverseNext()) { 1212 FrameView* view = coreFrame->view(); 1213 if (view) 1214 view->windowResizerRectChanged(); 1215 } 1216 } 1217 1218 void WebPage::setIsInWindow(bool isInWindow) 1219 { 1220 if (!isInWindow) { 1221 m_page->setCanStartMedia(false); 1222 m_page->willMoveOffscreen(); 1223 } else { 1224 m_page->setCanStartMedia(true); 1225 m_page->didMoveOnscreen(); 1226 } 1227 } 1228 1229 void WebPage::didReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, uint32_t policyAction, uint64_t downloadID) 1230 { 1231 WebFrame* frame = WebProcess::shared().webFrame(frameID); 1232 if (!frame) 1233 return; 1234 frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), downloadID); 1235 } 1236 1237 void WebPage::show() 1238 { 1239 send(Messages::WebPageProxy::ShowPage()); 1240 } 1241 1242 void WebPage::setUserAgent(const String& userAgent) 1243 { 1244 m_userAgent = userAgent; 1245 } 1246 1247 IntRect WebPage::windowToScreen(const IntRect& rect) 1248 { 1249 IntRect screenRect; 1250 sendSync(Messages::WebPageProxy::WindowToScreen(rect), Messages::WebPageProxy::WindowToScreen::Reply(screenRect)); 1251 return screenRect; 1252 } 1253 1254 IntRect WebPage::windowResizerRect() const 1255 { 1256 if (m_windowResizerSize.isEmpty()) 1257 return IntRect(); 1258 1259 IntSize frameViewSize; 1260 if (Frame* coreFrame = m_mainFrame->coreFrame()) { 1261 if (FrameView* view = coreFrame->view()) 1262 frameViewSize = view->size(); 1263 } 1264 1265 return IntRect(frameViewSize.width() - m_windowResizerSize.width(), frameViewSize.height() - m_windowResizerSize.height(), 1266 m_windowResizerSize.width(), m_windowResizerSize.height()); 1267 } 1268 1269 KeyboardUIMode WebPage::keyboardUIMode() 1270 { 1271 bool fullKeyboardAccessEnabled = WebProcess::shared().fullKeyboardAccessEnabled(); 1272 return static_cast<KeyboardUIMode>((fullKeyboardAccessEnabled ? KeyboardAccessFull : KeyboardAccessDefault) | (m_tabToLinks ? KeyboardAccessTabsToLinks : 0)); 1273 } 1274 1275 void WebPage::runJavaScriptInMainFrame(const String& script, uint64_t callbackID) 1276 { 1277 // NOTE: We need to be careful when running scripts that the objects we depend on don't 1278 // disappear during script execution. 1279 1280 // Retain the SerializedScriptValue at this level so it (and the internal data) lives 1281 // long enough for the DataReference to be encoded by the sent message. 1282 RefPtr<SerializedScriptValue> serializedResultValue; 1283 CoreIPC::DataReference dataReference; 1284 1285 JSLock lock(SilenceAssertionsOnly); 1286 if (JSValue resultValue = m_mainFrame->coreFrame()->script()->executeScript(script, true).jsValue()) { 1287 if ((serializedResultValue = SerializedScriptValue::create(m_mainFrame->jsContext(), 1288 toRef(m_mainFrame->coreFrame()->script()->globalObject(mainThreadNormalWorld())->globalExec(), resultValue), 0))) 1289 dataReference = CoreIPC::DataReference(serializedResultValue->data().data(), serializedResultValue->data().size()); 1290 } 1291 1292 send(Messages::WebPageProxy::ScriptValueCallback(dataReference, callbackID)); 1293 } 1294 1295 void WebPage::getContentsAsString(uint64_t callbackID) 1296 { 1297 String resultString = m_mainFrame->contentsAsString(); 1298 send(Messages::WebPageProxy::StringCallback(resultString, callbackID)); 1299 } 1300 1301 void WebPage::getRenderTreeExternalRepresentation(uint64_t callbackID) 1302 { 1303 String resultString = renderTreeExternalRepresentation(); 1304 send(Messages::WebPageProxy::StringCallback(resultString, callbackID)); 1305 } 1306 1307 void WebPage::getSelectionOrContentsAsString(uint64_t callbackID) 1308 { 1309 String resultString = m_mainFrame->selectionAsString(); 1310 if (resultString.isEmpty()) 1311 resultString = m_mainFrame->contentsAsString(); 1312 send(Messages::WebPageProxy::StringCallback(resultString, callbackID)); 1313 } 1314 1315 void WebPage::getSourceForFrame(uint64_t frameID, uint64_t callbackID) 1316 { 1317 String resultString; 1318 if (WebFrame* frame = WebProcess::shared().webFrame(frameID)) 1319 resultString = frame->source(); 1320 1321 send(Messages::WebPageProxy::StringCallback(resultString, callbackID)); 1322 } 1323 1324 void WebPage::getMainResourceDataOfFrame(uint64_t frameID, uint64_t callbackID) 1325 { 1326 CoreIPC::DataReference dataReference; 1327 1328 RefPtr<SharedBuffer> buffer; 1329 if (WebFrame* frame = WebProcess::shared().webFrame(frameID)) { 1330 if (DocumentLoader* loader = frame->coreFrame()->loader()->documentLoader()) { 1331 if ((buffer = loader->mainResourceData())) 1332 dataReference = CoreIPC::DataReference(reinterpret_cast<const uint8_t*>(buffer->data()), buffer->size()); 1333 } 1334 } 1335 1336 send(Messages::WebPageProxy::DataCallback(dataReference, callbackID)); 1337 } 1338 1339 void WebPage::getResourceDataFromFrame(uint64_t frameID, const String& resourceURL, uint64_t callbackID) 1340 { 1341 CoreIPC::DataReference dataReference; 1342 1343 RefPtr<SharedBuffer> buffer; 1344 if (WebFrame* frame = WebProcess::shared().webFrame(frameID)) { 1345 if (DocumentLoader* loader = frame->coreFrame()->loader()->documentLoader()) { 1346 if (RefPtr<ArchiveResource> subresource = loader->subresource(KURL(KURL(), resourceURL))) { 1347 if ((buffer = subresource->data())) 1348 dataReference = CoreIPC::DataReference(reinterpret_cast<const uint8_t*>(buffer->data()), buffer->size()); 1349 } 1350 } 1351 } 1352 1353 send(Messages::WebPageProxy::DataCallback(dataReference, callbackID)); 1354 } 1355 1356 void WebPage::getWebArchiveOfFrame(uint64_t frameID, uint64_t callbackID) 1357 { 1358 CoreIPC::DataReference dataReference; 1359 1360 #if PLATFORM(MAC) || PLATFORM(WIN) 1361 RetainPtr<CFDataRef> data; 1362 if (WebFrame* frame = WebProcess::shared().webFrame(frameID)) { 1363 if (RefPtr<LegacyWebArchive> archive = LegacyWebArchive::create(frame->coreFrame()->document())) { 1364 if ((data = archive->rawDataRepresentation())) 1365 dataReference = CoreIPC::DataReference(CFDataGetBytePtr(data.get()), CFDataGetLength(data.get())); 1366 } 1367 } 1368 #endif 1369 1370 send(Messages::WebPageProxy::DataCallback(dataReference, callbackID)); 1371 } 1372 1373 void WebPage::forceRepaintWithoutCallback() 1374 { 1375 m_drawingArea->forceRepaint(); 1376 } 1377 1378 void WebPage::forceRepaint(uint64_t callbackID) 1379 { 1380 forceRepaintWithoutCallback(); 1381 send(Messages::WebPageProxy::VoidCallback(callbackID)); 1382 } 1383 1384 void WebPage::preferencesDidChange(const WebPreferencesStore& store) 1385 { 1386 WebPreferencesStore::removeTestRunnerOverrides(); 1387 updatePreferences(store); 1388 } 1389 1390 void WebPage::updatePreferences(const WebPreferencesStore& store) 1391 { 1392 Settings* settings = m_page->settings(); 1393 1394 m_tabToLinks = store.getBoolValueForKey(WebPreferencesKey::tabsToLinksKey()); 1395 1396 // FIXME: This should be generated from macro expansion for all preferences, 1397 // but we currently don't match the naming of WebCore exactly so we are 1398 // handrolling the boolean and integer preferences until that is fixed. 1399 1400 #define INITIALIZE_SETTINGS(KeyUpper, KeyLower, TypeName, Type, DefaultValue) settings->set##KeyUpper(store.get##TypeName##ValueForKey(WebPreferencesKey::KeyLower##Key())); 1401 1402 FOR_EACH_WEBKIT_STRING_PREFERENCE(INITIALIZE_SETTINGS) 1403 1404 #undef INITIALIZE_SETTINGS 1405 1406 settings->setJavaScriptEnabled(store.getBoolValueForKey(WebPreferencesKey::javaScriptEnabledKey())); 1407 settings->setLoadsImagesAutomatically(store.getBoolValueForKey(WebPreferencesKey::loadsImagesAutomaticallyKey())); 1408 settings->setLoadsSiteIconsIgnoringImageLoadingSetting(store.getBoolValueForKey(WebPreferencesKey::loadsSiteIconsIgnoringImageLoadingPreferenceKey())); 1409 settings->setPluginsEnabled(store.getBoolValueForKey(WebPreferencesKey::pluginsEnabledKey())); 1410 settings->setJavaEnabled(store.getBoolValueForKey(WebPreferencesKey::javaEnabledKey())); 1411 settings->setOfflineWebApplicationCacheEnabled(store.getBoolValueForKey(WebPreferencesKey::offlineWebApplicationCacheEnabledKey())); 1412 settings->setLocalStorageEnabled(store.getBoolValueForKey(WebPreferencesKey::localStorageEnabledKey())); 1413 settings->setXSSAuditorEnabled(store.getBoolValueForKey(WebPreferencesKey::xssAuditorEnabledKey())); 1414 settings->setFrameFlatteningEnabled(store.getBoolValueForKey(WebPreferencesKey::frameFlatteningEnabledKey())); 1415 settings->setPrivateBrowsingEnabled(store.getBoolValueForKey(WebPreferencesKey::privateBrowsingEnabledKey())); 1416 settings->setDeveloperExtrasEnabled(store.getBoolValueForKey(WebPreferencesKey::developerExtrasEnabledKey())); 1417 settings->setTextAreasAreResizable(store.getBoolValueForKey(WebPreferencesKey::textAreasAreResizableKey())); 1418 settings->setNeedsSiteSpecificQuirks(store.getBoolValueForKey(WebPreferencesKey::needsSiteSpecificQuirksKey())); 1419 settings->setJavaScriptCanOpenWindowsAutomatically(store.getBoolValueForKey(WebPreferencesKey::javaScriptCanOpenWindowsAutomaticallyKey())); 1420 settings->setForceFTPDirectoryListings(store.getBoolValueForKey(WebPreferencesKey::forceFTPDirectoryListingsKey())); 1421 settings->setDNSPrefetchingEnabled(store.getBoolValueForKey(WebPreferencesKey::dnsPrefetchingEnabledKey())); 1422 #if ENABLE(WEB_ARCHIVE) 1423 settings->setWebArchiveDebugModeEnabled(store.getBoolValueForKey(WebPreferencesKey::webArchiveDebugModeEnabledKey())); 1424 #endif 1425 settings->setLocalFileContentSniffingEnabled(store.getBoolValueForKey(WebPreferencesKey::localFileContentSniffingEnabledKey())); 1426 settings->setUsesPageCache(store.getBoolValueForKey(WebPreferencesKey::usesPageCacheKey())); 1427 settings->setAuthorAndUserStylesEnabled(store.getBoolValueForKey(WebPreferencesKey::authorAndUserStylesEnabledKey())); 1428 settings->setPaginateDuringLayoutEnabled(store.getBoolValueForKey(WebPreferencesKey::paginateDuringLayoutEnabledKey())); 1429 settings->setDOMPasteAllowed(store.getBoolValueForKey(WebPreferencesKey::domPasteAllowedKey())); 1430 settings->setJavaScriptCanAccessClipboard(store.getBoolValueForKey(WebPreferencesKey::javaScriptCanAccessClipboardKey())); 1431 settings->setShouldPrintBackgrounds(store.getBoolValueForKey(WebPreferencesKey::shouldPrintBackgroundsKey())); 1432 settings->setWebSecurityEnabled(store.getBoolValueForKey(WebPreferencesKey::webSecurityEnabledKey())); 1433 settings->setAllowUniversalAccessFromFileURLs(store.getBoolValueForKey(WebPreferencesKey::allowUniversalAccessFromFileURLsKey())); 1434 settings->setAllowFileAccessFromFileURLs(store.getBoolValueForKey(WebPreferencesKey::allowFileAccessFromFileURLsKey())); 1435 1436 settings->setMinimumFontSize(store.getUInt32ValueForKey(WebPreferencesKey::minimumFontSizeKey())); 1437 settings->setMinimumLogicalFontSize(store.getUInt32ValueForKey(WebPreferencesKey::minimumLogicalFontSizeKey())); 1438 settings->setDefaultFontSize(store.getUInt32ValueForKey(WebPreferencesKey::defaultFontSizeKey())); 1439 settings->setDefaultFixedFontSize(store.getUInt32ValueForKey(WebPreferencesKey::defaultFixedFontSizeKey())); 1440 settings->setEditableLinkBehavior(static_cast<WebCore::EditableLinkBehavior>(store.getUInt32ValueForKey(WebPreferencesKey::editableLinkBehaviorKey()))); 1441 1442 settings->setAcceleratedCompositingEnabled(store.getBoolValueForKey(WebPreferencesKey::acceleratedCompositingEnabledKey()) && LayerTreeHost::supportsAcceleratedCompositing()); 1443 settings->setAcceleratedDrawingEnabled(store.getBoolValueForKey(WebPreferencesKey::acceleratedDrawingEnabledKey()) && LayerTreeHost::supportsAcceleratedCompositing()); 1444 settings->setCanvasUsesAcceleratedDrawing(store.getBoolValueForKey(WebPreferencesKey::canvasUsesAcceleratedDrawingKey()) && LayerTreeHost::supportsAcceleratedCompositing()); 1445 settings->setShowDebugBorders(store.getBoolValueForKey(WebPreferencesKey::compositingBordersVisibleKey())); 1446 settings->setShowRepaintCounter(store.getBoolValueForKey(WebPreferencesKey::compositingRepaintCountersVisibleKey())); 1447 settings->setWebGLEnabled(store.getBoolValueForKey(WebPreferencesKey::webGLEnabledKey())); 1448 1449 #if ENABLE(DATABASE) 1450 AbstractDatabase::setIsAvailable(store.getBoolValueForKey(WebPreferencesKey::databasesEnabledKey())); 1451 #endif 1452 1453 #if ENABLE(FULLSCREEN_API) 1454 settings->setFullScreenEnabled(store.getBoolValueForKey(WebPreferencesKey::fullScreenEnabledKey())); 1455 #endif 1456 1457 #if ENABLE(DOM_STORAGE) 1458 settings->setLocalStorageDatabasePath(WebProcess::shared().localStorageDirectory()); 1459 #endif 1460 1461 platformPreferencesDidChange(store); 1462 } 1463 1464 #if ENABLE(INSPECTOR) 1465 WebInspector* WebPage::inspector() 1466 { 1467 if (m_isClosed) 1468 return 0; 1469 if (!m_inspector) 1470 m_inspector = WebInspector::create(this); 1471 return m_inspector.get(); 1472 } 1473 #endif 1474 1475 #if ENABLE(FULLSCREEN_API) 1476 WebFullScreenManager* WebPage::fullScreenManager() 1477 { 1478 if (!m_fullScreenManager) 1479 m_fullScreenManager = WebFullScreenManager::create(this); 1480 return m_fullScreenManager.get(); 1481 } 1482 #endif 1483 1484 #if !PLATFORM(GTK) && !PLATFORM(MAC) 1485 bool WebPage::handleEditingKeyboardEvent(KeyboardEvent* evt) 1486 { 1487 Node* node = evt->target()->toNode(); 1488 ASSERT(node); 1489 Frame* frame = node->document()->frame(); 1490 ASSERT(frame); 1491 1492 const PlatformKeyboardEvent* keyEvent = evt->keyEvent(); 1493 if (!keyEvent) 1494 return false; 1495 1496 Editor::Command command = frame->editor()->command(interpretKeyEvent(evt)); 1497 1498 if (keyEvent->type() == PlatformKeyboardEvent::RawKeyDown) { 1499 // WebKit doesn't have enough information about mode to decide how commands that just insert text if executed via Editor should be treated, 1500 // so we leave it upon WebCore to either handle them immediately (e.g. Tab that changes focus) or let a keypress event be generated 1501 // (e.g. Tab that inserts a Tab character, or Enter). 1502 return !command.isTextInsertion() && command.execute(evt); 1503 } 1504 1505 if (command.execute(evt)) 1506 return true; 1507 1508 // Don't insert null or control characters as they can result in unexpected behaviour 1509 if (evt->charCode() < ' ') 1510 return false; 1511 1512 return frame->editor()->insertText(evt->keyEvent()->text(), evt); 1513 } 1514 #endif 1515 1516 #if PLATFORM(WIN) 1517 void WebPage::performDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, const WebCore::DragDataMap& dataMap, uint32_t flags) 1518 { 1519 if (!m_page) { 1520 send(Messages::WebPageProxy::DidPerformDragControllerAction(DragOperationNone)); 1521 return; 1522 } 1523 1524 DragData dragData(dataMap, clientPosition, globalPosition, static_cast<DragOperation>(draggingSourceOperationMask), static_cast<DragApplicationFlags>(flags)); 1525 switch (action) { 1526 case DragControllerActionEntered: 1527 send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController()->dragEntered(&dragData))); 1528 break; 1529 1530 case DragControllerActionUpdated: 1531 send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController()->dragUpdated(&dragData))); 1532 break; 1533 1534 case DragControllerActionExited: 1535 m_page->dragController()->dragExited(&dragData); 1536 break; 1537 1538 case DragControllerActionPerformDrag: 1539 m_page->dragController()->performDrag(&dragData); 1540 break; 1541 1542 default: 1543 ASSERT_NOT_REACHED(); 1544 } 1545 } 1546 #else 1547 void WebPage::performDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, const String& dragStorageName, uint32_t flags, const SandboxExtension::Handle& sandboxExtensionHandle) 1548 { 1549 if (!m_page) { 1550 send(Messages::WebPageProxy::DidPerformDragControllerAction(DragOperationNone)); 1551 return; 1552 } 1553 1554 DragData dragData(dragStorageName, clientPosition, globalPosition, static_cast<DragOperation>(draggingSourceOperationMask), static_cast<DragApplicationFlags>(flags)); 1555 switch (action) { 1556 case DragControllerActionEntered: 1557 send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController()->dragEntered(&dragData))); 1558 break; 1559 1560 case DragControllerActionUpdated: 1561 send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController()->dragUpdated(&dragData))); 1562 break; 1563 1564 case DragControllerActionExited: 1565 m_page->dragController()->dragExited(&dragData); 1566 break; 1567 1568 case DragControllerActionPerformDrag: { 1569 ASSERT(!m_pendingDropSandboxExtension); 1570 1571 m_pendingDropSandboxExtension = SandboxExtension::create(sandboxExtensionHandle); 1572 1573 m_page->dragController()->performDrag(&dragData); 1574 1575 // If we started loading a local file, the sandbox extension tracker would have adopted this 1576 // pending drop sandbox extension. If not, we'll play it safe and invalidate it. 1577 if (m_pendingDropSandboxExtension) { 1578 m_pendingDropSandboxExtension->invalidate(); 1579 m_pendingDropSandboxExtension = nullptr; 1580 } 1581 1582 break; 1583 } 1584 1585 default: 1586 ASSERT_NOT_REACHED(); 1587 } 1588 } 1589 #endif 1590 1591 void WebPage::dragEnded(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t operation) 1592 { 1593 IntPoint adjustedClientPosition(clientPosition.x() + m_page->dragController()->dragOffset().x(), clientPosition.y() + m_page->dragController()->dragOffset().y()); 1594 IntPoint adjustedGlobalPosition(globalPosition.x() + m_page->dragController()->dragOffset().x(), globalPosition.y() + m_page->dragController()->dragOffset().y()); 1595 1596 platformDragEnded(); 1597 m_page->dragController()->dragEnded(); 1598 FrameView* view = m_page->mainFrame()->view(); 1599 if (!view) 1600 return; 1601 // FIXME: These are fake modifier keys here, but they should be real ones instead. 1602 PlatformMouseEvent event(adjustedClientPosition, adjustedGlobalPosition, LeftButton, MouseEventMoved, 0, false, false, false, false, currentTime()); 1603 m_page->mainFrame()->eventHandler()->dragSourceEndedAt(event, (DragOperation)operation); 1604 } 1605 1606 void WebPage::willPerformLoadDragDestinationAction() 1607 { 1608 m_sandboxExtensionTracker.willPerformLoadDragDestinationAction(m_pendingDropSandboxExtension.release()); 1609 } 1610 1611 WebEditCommand* WebPage::webEditCommand(uint64_t commandID) 1612 { 1613 return m_editCommandMap.get(commandID).get(); 1614 } 1615 1616 void WebPage::addWebEditCommand(uint64_t commandID, WebEditCommand* command) 1617 { 1618 m_editCommandMap.set(commandID, command); 1619 } 1620 1621 void WebPage::removeWebEditCommand(uint64_t commandID) 1622 { 1623 m_editCommandMap.remove(commandID); 1624 } 1625 1626 void WebPage::unapplyEditCommand(uint64_t commandID) 1627 { 1628 WebEditCommand* command = webEditCommand(commandID); 1629 if (!command) 1630 return; 1631 1632 command->command()->unapply(); 1633 } 1634 1635 void WebPage::reapplyEditCommand(uint64_t commandID) 1636 { 1637 WebEditCommand* command = webEditCommand(commandID); 1638 if (!command) 1639 return; 1640 1641 m_isInRedo = true; 1642 command->command()->reapply(); 1643 m_isInRedo = false; 1644 } 1645 1646 void WebPage::didRemoveEditCommand(uint64_t commandID) 1647 { 1648 removeWebEditCommand(commandID); 1649 } 1650 1651 void WebPage::setActivePopupMenu(WebPopupMenu* menu) 1652 { 1653 m_activePopupMenu = menu; 1654 } 1655 1656 void WebPage::setActiveOpenPanelResultListener(PassRefPtr<WebOpenPanelResultListener> openPanelResultListener) 1657 { 1658 m_activeOpenPanelResultListener = openPanelResultListener; 1659 } 1660 1661 bool WebPage::findStringFromInjectedBundle(const String& target, FindOptions options) 1662 { 1663 return m_page->findString(target, options); 1664 } 1665 1666 void WebPage::findString(const String& string, uint32_t options, uint32_t maxMatchCount) 1667 { 1668 m_findController.findString(string, static_cast<FindOptions>(options), maxMatchCount); 1669 } 1670 1671 void WebPage::hideFindUI() 1672 { 1673 m_findController.hideFindUI(); 1674 } 1675 1676 void WebPage::countStringMatches(const String& string, uint32_t options, uint32_t maxMatchCount) 1677 { 1678 m_findController.countStringMatches(string, static_cast<FindOptions>(options), maxMatchCount); 1679 } 1680 1681 void WebPage::didChangeSelectedIndexForActivePopupMenu(int32_t newIndex) 1682 { 1683 if (!m_activePopupMenu) 1684 return; 1685 1686 m_activePopupMenu->didChangeSelectedIndex(newIndex); 1687 m_activePopupMenu = 0; 1688 } 1689 1690 void WebPage::didChooseFilesForOpenPanel(const Vector<String>& files) 1691 { 1692 if (!m_activeOpenPanelResultListener) 1693 return; 1694 1695 m_activeOpenPanelResultListener->didChooseFiles(files); 1696 m_activeOpenPanelResultListener = 0; 1697 } 1698 1699 void WebPage::didCancelForOpenPanel() 1700 { 1701 m_activeOpenPanelResultListener = 0; 1702 } 1703 1704 #if ENABLE(WEB_PROCESS_SANDBOX) 1705 void WebPage::extendSandboxForFileFromOpenPanel(const SandboxExtension::Handle& handle) 1706 { 1707 SandboxExtension::create(handle)->consumePermanently(); 1708 } 1709 #endif 1710 1711 void WebPage::didReceiveGeolocationPermissionDecision(uint64_t geolocationID, bool allowed) 1712 { 1713 m_geolocationPermissionRequestManager.didReceiveGeolocationPermissionDecision(geolocationID, allowed); 1714 } 1715 1716 void WebPage::advanceToNextMisspelling(bool startBeforeSelection) 1717 { 1718 Frame* frame = m_page->focusController()->focusedOrMainFrame(); 1719 frame->editor()->advanceToNextMisspelling(startBeforeSelection); 1720 } 1721 1722 void WebPage::changeSpellingToWord(const String& word) 1723 { 1724 replaceSelectionWithText(m_page->focusController()->focusedOrMainFrame(), word); 1725 } 1726 1727 void WebPage::unmarkAllMisspellings() 1728 { 1729 for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) { 1730 if (Document* document = frame->document()) 1731 document->markers()->removeMarkers(DocumentMarker::Spelling); 1732 } 1733 } 1734 1735 void WebPage::unmarkAllBadGrammar() 1736 { 1737 for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) { 1738 if (Document* document = frame->document()) 1739 document->markers()->removeMarkers(DocumentMarker::Grammar); 1740 } 1741 } 1742 1743 #if PLATFORM(MAC) 1744 void WebPage::uppercaseWord() 1745 { 1746 m_page->focusController()->focusedOrMainFrame()->editor()->uppercaseWord(); 1747 } 1748 1749 void WebPage::lowercaseWord() 1750 { 1751 m_page->focusController()->focusedOrMainFrame()->editor()->lowercaseWord(); 1752 } 1753 1754 void WebPage::capitalizeWord() 1755 { 1756 m_page->focusController()->focusedOrMainFrame()->editor()->capitalizeWord(); 1757 } 1758 #endif 1759 1760 void WebPage::setTextForActivePopupMenu(int32_t index) 1761 { 1762 if (!m_activePopupMenu) 1763 return; 1764 1765 m_activePopupMenu->setTextForIndex(index); 1766 } 1767 1768 void WebPage::didSelectItemFromActiveContextMenu(const WebContextMenuItemData& item) 1769 { 1770 ASSERT(m_contextMenu); 1771 m_contextMenu->itemSelected(item); 1772 m_contextMenu = 0; 1773 } 1774 1775 void WebPage::replaceSelectionWithText(Frame* frame, const String& text) 1776 { 1777 if (frame->selection()->isNone()) 1778 return; 1779 1780 RefPtr<DocumentFragment> textFragment = createFragmentFromText(frame->selection()->toNormalizedRange().get(), text); 1781 applyCommand(ReplaceSelectionCommand::create(frame->document(), textFragment.release(), ReplaceSelectionCommand::SelectReplacement | ReplaceSelectionCommand::MatchStyle | ReplaceSelectionCommand::PreventNesting)); 1782 frame->selection()->revealSelection(ScrollAlignment::alignToEdgeIfNeeded); 1783 } 1784 1785 bool WebPage::mainFrameHasCustomRepresentation() const 1786 { 1787 return static_cast<WebFrameLoaderClient*>(mainFrame()->coreFrame()->loader()->client())->frameHasCustomRepresentation(); 1788 } 1789 1790 void WebPage::didChangeScrollOffsetForMainFrame() 1791 { 1792 Frame* frame = m_page->mainFrame(); 1793 IntPoint scrollPosition = frame->view()->scrollPosition(); 1794 IntPoint maximumScrollPosition = frame->view()->maximumScrollPosition(); 1795 IntPoint minimumScrollPosition = frame->view()->minimumScrollPosition(); 1796 1797 bool isPinnedToLeftSide = (scrollPosition.x() <= minimumScrollPosition.x()); 1798 bool isPinnedToRightSide = (scrollPosition.x() >= maximumScrollPosition.x()); 1799 1800 if (isPinnedToLeftSide != m_cachedMainFrameIsPinnedToLeftSide || isPinnedToRightSide != m_cachedMainFrameIsPinnedToRightSide) { 1801 send(Messages::WebPageProxy::DidChangeScrollOffsetPinningForMainFrame(isPinnedToLeftSide, isPinnedToRightSide)); 1802 1803 m_cachedMainFrameIsPinnedToLeftSide = isPinnedToLeftSide; 1804 m_cachedMainFrameIsPinnedToRightSide = isPinnedToRightSide; 1805 } 1806 } 1807 1808 #if PLATFORM(MAC) 1809 1810 void WebPage::addPluginView(PluginView* pluginView) 1811 { 1812 ASSERT(!m_pluginViews.contains(pluginView)); 1813 1814 m_pluginViews.add(pluginView); 1815 } 1816 1817 void WebPage::removePluginView(PluginView* pluginView) 1818 { 1819 ASSERT(m_pluginViews.contains(pluginView)); 1820 1821 m_pluginViews.remove(pluginView); 1822 } 1823 1824 void WebPage::setWindowIsVisible(bool windowIsVisible) 1825 { 1826 m_windowIsVisible = windowIsVisible; 1827 1828 // Tell all our plug-in views that the window visibility changed. 1829 for (HashSet<PluginView*>::const_iterator it = m_pluginViews.begin(), end = m_pluginViews.end(); it != end; ++it) 1830 (*it)->setWindowIsVisible(windowIsVisible); 1831 } 1832 1833 void WebPage::windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates, const WebCore::IntPoint& accessibilityViewCoordinates) 1834 { 1835 m_windowFrameInScreenCoordinates = windowFrameInScreenCoordinates; 1836 m_viewFrameInWindowCoordinates = viewFrameInWindowCoordinates; 1837 m_accessibilityPosition = accessibilityViewCoordinates; 1838 1839 // Tell all our plug-in views that the window and view frames have changed. 1840 for (HashSet<PluginView*>::const_iterator it = m_pluginViews.begin(), end = m_pluginViews.end(); it != end; ++it) 1841 (*it)->windowAndViewFramesChanged(windowFrameInScreenCoordinates, viewFrameInWindowCoordinates); 1842 } 1843 1844 #endif 1845 1846 bool WebPage::windowIsFocused() const 1847 { 1848 return m_page->focusController()->isActive(); 1849 } 1850 1851 void WebPage::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments) 1852 { 1853 if (messageID.is<CoreIPC::MessageClassDrawingAreaLegacy>()) { 1854 if (m_drawingArea) 1855 m_drawingArea->didReceiveMessage(connection, messageID, arguments); 1856 return; 1857 } 1858 1859 #if PLATFORM(MAC) || PLATFORM(WIN) 1860 if (messageID.is<CoreIPC::MessageClassDrawingArea>()) { 1861 if (m_drawingArea) 1862 m_drawingArea->didReceiveDrawingAreaMessage(connection, messageID, arguments); 1863 return; 1864 } 1865 #endif 1866 1867 #if ENABLE(INSPECTOR) 1868 if (messageID.is<CoreIPC::MessageClassWebInspector>()) { 1869 if (WebInspector* inspector = this->inspector()) 1870 inspector->didReceiveWebInspectorMessage(connection, messageID, arguments); 1871 return; 1872 } 1873 #endif 1874 1875 #if ENABLE(FULLSCREEN_API) 1876 if (messageID.is<CoreIPC::MessageClassWebFullScreenManager>()) { 1877 fullScreenManager()->didReceiveMessage(connection, messageID, arguments); 1878 return; 1879 } 1880 #endif 1881 1882 didReceiveWebPageMessage(connection, messageID, arguments); 1883 } 1884 1885 CoreIPC::SyncReplyMode WebPage::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments, CoreIPC::ArgumentEncoder* reply) 1886 { 1887 return didReceiveSyncWebPageMessage(connection, messageID, arguments, reply); 1888 } 1889 1890 InjectedBundleBackForwardList* WebPage::backForwardList() 1891 { 1892 if (!m_backForwardList) 1893 m_backForwardList = InjectedBundleBackForwardList::create(this); 1894 return m_backForwardList.get(); 1895 } 1896 1897 #if PLATFORM(QT) 1898 void WebPage::findZoomableAreaForPoint(const WebCore::IntPoint& point) 1899 { 1900 const int minimumZoomTargetWidth = 100; 1901 1902 Frame* mainframe = m_mainFrame->coreFrame(); 1903 HitTestResult result = mainframe->eventHandler()->hitTestResultAtPoint(mainframe->view()->windowToContents(point), /*allowShadowContent*/ false, /*ignoreClipping*/ true); 1904 1905 Node* node = result.innerNode(); 1906 while (node && node->getRect().width() < minimumZoomTargetWidth) 1907 node = node->parentNode(); 1908 1909 IntRect zoomableArea; 1910 if (node) 1911 zoomableArea = node->getRect(); 1912 send(Messages::WebPageProxy::DidFindZoomableArea(zoomableArea)); 1913 } 1914 #endif 1915 1916 WebPage::SandboxExtensionTracker::~SandboxExtensionTracker() 1917 { 1918 invalidate(); 1919 } 1920 1921 void WebPage::SandboxExtensionTracker::invalidate() 1922 { 1923 if (m_pendingProvisionalSandboxExtension) { 1924 m_pendingProvisionalSandboxExtension->invalidate(); 1925 m_pendingProvisionalSandboxExtension = 0; 1926 } 1927 1928 if (m_provisionalSandboxExtension) { 1929 m_provisionalSandboxExtension->invalidate(); 1930 m_provisionalSandboxExtension = 0; 1931 } 1932 1933 if (m_committedSandboxExtension) { 1934 m_committedSandboxExtension->invalidate(); 1935 m_committedSandboxExtension = 0; 1936 } 1937 } 1938 1939 void WebPage::SandboxExtensionTracker::willPerformLoadDragDestinationAction(PassRefPtr<SandboxExtension> pendingDropSandboxExtension) 1940 { 1941 setPendingProvisionalSandboxExtension(pendingDropSandboxExtension); 1942 } 1943 1944 void WebPage::SandboxExtensionTracker::beginLoad(WebFrame* frame, const SandboxExtension::Handle& handle) 1945 { 1946 ASSERT(frame->isMainFrame()); 1947 1948 setPendingProvisionalSandboxExtension(SandboxExtension::create(handle)); 1949 } 1950 1951 void WebPage::SandboxExtensionTracker::setPendingProvisionalSandboxExtension(PassRefPtr<SandboxExtension> pendingProvisionalSandboxExtension) 1952 { 1953 // If we get two beginLoad calls in succession, without a provisional load starting, then 1954 // m_pendingProvisionalSandboxExtension will be non-null. Invalidate and null out the extension if that is the case. 1955 if (m_pendingProvisionalSandboxExtension) { 1956 m_pendingProvisionalSandboxExtension->invalidate(); 1957 m_pendingProvisionalSandboxExtension = nullptr; 1958 } 1959 1960 m_pendingProvisionalSandboxExtension = pendingProvisionalSandboxExtension; 1961 } 1962 1963 static bool shouldReuseCommittedSandboxExtension(WebFrame* frame) 1964 { 1965 ASSERT(frame->isMainFrame()); 1966 1967 FrameLoader* frameLoader = frame->coreFrame()->loader(); 1968 FrameLoadType frameLoadType = frameLoader->loadType(); 1969 1970 // If the page is being reloaded, it should reuse whatever extension is committed. 1971 if (frameLoadType == FrameLoadTypeReload || frameLoadType == FrameLoadTypeReloadFromOrigin) 1972 return true; 1973 1974 DocumentLoader* documentLoader = frameLoader->documentLoader(); 1975 DocumentLoader* provisionalDocumentLoader = frameLoader->provisionalDocumentLoader(); 1976 if (!documentLoader || !provisionalDocumentLoader) 1977 return false; 1978 1979 if (documentLoader->url().isLocalFile() && provisionalDocumentLoader->url().isLocalFile()) 1980 return true; 1981 1982 return false; 1983 } 1984 1985 void WebPage::SandboxExtensionTracker::didStartProvisionalLoad(WebFrame* frame) 1986 { 1987 if (!frame->isMainFrame()) 1988 return; 1989 1990 if (shouldReuseCommittedSandboxExtension(frame)) { 1991 m_pendingProvisionalSandboxExtension = m_committedSandboxExtension.release(); 1992 ASSERT(!m_committedSandboxExtension); 1993 } 1994 1995 ASSERT(!m_provisionalSandboxExtension); 1996 1997 m_provisionalSandboxExtension = m_pendingProvisionalSandboxExtension.release(); 1998 if (!m_provisionalSandboxExtension) 1999 return; 2000 2001 m_provisionalSandboxExtension->consume(); 2002 } 2003 2004 void WebPage::SandboxExtensionTracker::didCommitProvisionalLoad(WebFrame* frame) 2005 { 2006 if (!frame->isMainFrame()) 2007 return; 2008 2009 ASSERT(!m_pendingProvisionalSandboxExtension); 2010 2011 // The provisional load has been committed. Invalidate the currently committed sandbox 2012 // extension and make the provisional sandbox extension the committed sandbox extension. 2013 if (m_committedSandboxExtension) 2014 m_committedSandboxExtension->invalidate(); 2015 2016 m_committedSandboxExtension = m_provisionalSandboxExtension.release(); 2017 } 2018 2019 void WebPage::SandboxExtensionTracker::didFailProvisionalLoad(WebFrame* frame) 2020 { 2021 if (!frame->isMainFrame()) 2022 return; 2023 2024 if (!m_provisionalSandboxExtension) 2025 return; 2026 2027 m_provisionalSandboxExtension->invalidate(); 2028 m_provisionalSandboxExtension = nullptr; 2029 } 2030 2031 bool WebPage::hasLocalDataForURL(const KURL& url) 2032 { 2033 if (url.isLocalFile()) 2034 return true; 2035 2036 FrameLoader* frameLoader = m_page->mainFrame()->loader(); 2037 DocumentLoader* documentLoader = frameLoader ? frameLoader->documentLoader() : 0; 2038 if (documentLoader && documentLoader->subresource(url)) 2039 return true; 2040 2041 return platformHasLocalDataForURL(url); 2042 } 2043 2044 void WebPage::setCustomTextEncodingName(const String& encoding) 2045 { 2046 m_page->mainFrame()->loader()->reloadWithOverrideEncoding(encoding); 2047 } 2048 2049 void WebPage::didRemoveBackForwardItem(uint64_t itemID) 2050 { 2051 WebBackForwardListProxy::removeItem(itemID); 2052 } 2053 2054 #if PLATFORM(MAC) 2055 2056 bool WebPage::isSpeaking() 2057 { 2058 bool result; 2059 return sendSync(Messages::WebPageProxy::GetIsSpeaking(), Messages::WebPageProxy::GetIsSpeaking::Reply(result)) && result; 2060 } 2061 2062 void WebPage::speak(const String& string) 2063 { 2064 send(Messages::WebPageProxy::Speak(string)); 2065 } 2066 2067 void WebPage::stopSpeaking() 2068 { 2069 send(Messages::WebPageProxy::StopSpeaking()); 2070 } 2071 2072 #endif 2073 2074 void WebPage::beginPrinting(uint64_t frameID, const PrintInfo& printInfo) 2075 { 2076 WebFrame* frame = WebProcess::shared().webFrame(frameID); 2077 if (!frame) 2078 return; 2079 2080 Frame* coreFrame = frame->coreFrame(); 2081 if (!coreFrame) 2082 return; 2083 2084 if (!m_printContext) 2085 m_printContext = adoptPtr(new PrintContext(coreFrame)); 2086 2087 m_printContext->begin(printInfo.availablePaperWidth, printInfo.availablePaperHeight); 2088 2089 float fullPageHeight; 2090 m_printContext->computePageRects(FloatRect(0, 0, printInfo.availablePaperWidth, printInfo.availablePaperHeight), 0, 0, printInfo.pageSetupScaleFactor, fullPageHeight, true); 2091 } 2092 2093 void WebPage::endPrinting() 2094 { 2095 m_printContext = nullptr; 2096 } 2097 2098 void WebPage::computePagesForPrinting(uint64_t frameID, const PrintInfo& printInfo, uint64_t callbackID) 2099 { 2100 Vector<IntRect> resultPageRects; 2101 double resultTotalScaleFactorForPrinting = 1; 2102 2103 beginPrinting(frameID, printInfo); 2104 2105 if (m_printContext) { 2106 resultPageRects = m_printContext->pageRects(); 2107 resultTotalScaleFactorForPrinting = m_printContext->computeAutomaticScaleFactor(FloatSize(printInfo.availablePaperWidth, printInfo.availablePaperHeight)) * printInfo.pageSetupScaleFactor; 2108 } 2109 2110 // If we're asked to print, we should actually print at least a blank page. 2111 if (resultPageRects.isEmpty()) 2112 resultPageRects.append(IntRect(0, 0, 1, 1)); 2113 2114 send(Messages::WebPageProxy::ComputedPagesCallback(resultPageRects, resultTotalScaleFactorForPrinting, callbackID)); 2115 } 2116 2117 #if PLATFORM(MAC) || PLATFORM(WIN) 2118 void WebPage::drawRectToPDF(uint64_t frameID, const WebCore::IntRect& rect, uint64_t callbackID) 2119 { 2120 WebFrame* frame = WebProcess::shared().webFrame(frameID); 2121 Frame* coreFrame = frame ? frame->coreFrame() : 0; 2122 2123 RetainPtr<CFMutableDataRef> pdfPageData(AdoptCF, CFDataCreateMutable(0, 0)); 2124 2125 if (coreFrame) { 2126 ASSERT(coreFrame->document()->printing()); 2127 2128 #if USE(CG) 2129 // FIXME: Use CGDataConsumerCreate with callbacks to avoid copying the data. 2130 RetainPtr<CGDataConsumerRef> pdfDataConsumer(AdoptCF, CGDataConsumerCreateWithCFData(pdfPageData.get())); 2131 2132 CGRect mediaBox = CGRectMake(0, 0, rect.width(), rect.height()); 2133 RetainPtr<CGContextRef> context(AdoptCF, CGPDFContextCreate(pdfDataConsumer.get(), &mediaBox, 0)); 2134 RetainPtr<CFDictionaryRef> pageInfo(AdoptCF, CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); 2135 CGPDFContextBeginPage(context.get(), pageInfo.get()); 2136 2137 GraphicsContext ctx(context.get()); 2138 ctx.scale(FloatSize(1, -1)); 2139 ctx.translate(0, -rect.height()); 2140 m_printContext->spoolRect(ctx, rect); 2141 2142 CGPDFContextEndPage(context.get()); 2143 CGPDFContextClose(context.get()); 2144 #endif 2145 } 2146 2147 send(Messages::WebPageProxy::DataCallback(CoreIPC::DataReference(CFDataGetBytePtr(pdfPageData.get()), CFDataGetLength(pdfPageData.get())), callbackID)); 2148 } 2149 2150 void WebPage::drawPagesToPDF(uint64_t frameID, uint32_t first, uint32_t count, uint64_t callbackID) 2151 { 2152 WebFrame* frame = WebProcess::shared().webFrame(frameID); 2153 Frame* coreFrame = frame ? frame->coreFrame() : 0; 2154 2155 RetainPtr<CFMutableDataRef> pdfPageData(AdoptCF, CFDataCreateMutable(0, 0)); 2156 2157 if (coreFrame) { 2158 ASSERT(coreFrame->document()->printing()); 2159 2160 #if USE(CG) 2161 // FIXME: Use CGDataConsumerCreate with callbacks to avoid copying the data. 2162 RetainPtr<CGDataConsumerRef> pdfDataConsumer(AdoptCF, CGDataConsumerCreateWithCFData(pdfPageData.get())); 2163 2164 CGRect mediaBox = m_printContext->pageCount() ? m_printContext->pageRect(0) : CGRectMake(0, 0, 1, 1); 2165 RetainPtr<CGContextRef> context(AdoptCF, CGPDFContextCreate(pdfDataConsumer.get(), &mediaBox, 0)); 2166 for (uint32_t page = first; page < first + count; ++page) { 2167 if (page >= m_printContext->pageCount()) 2168 break; 2169 2170 RetainPtr<CFDictionaryRef> pageInfo(AdoptCF, CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); 2171 CGPDFContextBeginPage(context.get(), pageInfo.get()); 2172 2173 GraphicsContext ctx(context.get()); 2174 ctx.scale(FloatSize(1, -1)); 2175 ctx.translate(0, -m_printContext->pageRect(page).height()); 2176 m_printContext->spoolPage(ctx, page, m_printContext->pageRect(page).width()); 2177 2178 CGPDFContextEndPage(context.get()); 2179 } 2180 CGPDFContextClose(context.get()); 2181 #endif 2182 } 2183 2184 send(Messages::WebPageProxy::DataCallback(CoreIPC::DataReference(CFDataGetBytePtr(pdfPageData.get()), CFDataGetLength(pdfPageData.get())), callbackID)); 2185 } 2186 #endif 2187 2188 void WebPage::runModal() 2189 { 2190 if (m_isClosed) 2191 return; 2192 if (m_isRunningModal) 2193 return; 2194 2195 m_isRunningModal = true; 2196 send(Messages::WebPageProxy::RunModal()); 2197 RunLoop::run(); 2198 ASSERT(!m_isRunningModal); 2199 } 2200 2201 void WebPage::setMemoryCacheMessagesEnabled(bool memoryCacheMessagesEnabled) 2202 { 2203 m_page->setMemoryCacheClientCallsEnabled(memoryCacheMessagesEnabled); 2204 } 2205 2206 #if !PLATFORM(MAC) 2207 void WebPage::platformDragEnded() 2208 { 2209 } 2210 #endif 2211 2212 bool WebPage::canHandleRequest(const WebCore::ResourceRequest& request) 2213 { 2214 if (SchemeRegistry::shouldLoadURLSchemeAsEmptyDocument(request.url().protocol())) 2215 return true; 2216 return platformCanHandleRequest(request); 2217 } 2218 2219 #if PLATFORM(MAC) && !defined(BUILDING_ON_SNOW_LEOPARD) 2220 void WebPage::handleCorrectionPanelResult(const String& result) 2221 { 2222 Frame* frame = m_page->focusController()->focusedOrMainFrame(); 2223 if (!frame) 2224 return; 2225 frame->editor()->handleCorrectionPanelResult(result); 2226 } 2227 #endif 2228 2229 void WebPage::simulateMouseDown(int button, WebCore::IntPoint position, int clickCount, WKEventModifiers modifiers, double time) 2230 { 2231 mouseEvent(WebMouseEvent(WebMouseEvent::MouseDown, static_cast<WebMouseEvent::Button>(button), position, position, 0, 0, 0, clickCount, static_cast<WebMouseEvent::Modifiers>(modifiers), time)); 2232 } 2233 2234 void WebPage::simulateMouseUp(int button, WebCore::IntPoint position, int clickCount, WKEventModifiers modifiers, double time) 2235 { 2236 mouseEvent(WebMouseEvent(WebMouseEvent::MouseUp, static_cast<WebMouseEvent::Button>(button), position, position, 0, 0, 0, clickCount, static_cast<WebMouseEvent::Modifiers>(modifiers), time)); 2237 } 2238 2239 void WebPage::simulateMouseMotion(WebCore::IntPoint position, double time) 2240 { 2241 mouseEvent(WebMouseEvent(WebMouseEvent::MouseMove, WebMouseEvent::NoButton, position, position, 0, 0, 0, 0, WebMouseEvent::Modifiers(), time)); 2242 } 2243 2244 } // namespace WebKit 2245