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 132using namespace JSC; 133using namespace WebCore; 134 135namespace WebKit { 136 137#ifndef NDEBUG 138static WTF::RefCountedLeakCounter webPageCounter("WebPage"); 139#endif 140 141PassRefPtr<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 151WebPage::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 235WebPage::~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 253void WebPage::dummy(bool&) 254{ 255} 256 257CoreIPC::Connection* WebPage::connection() const 258{ 259 return WebProcess::shared().connection(); 260} 261 262void WebPage::initializeInjectedBundleContextMenuClient(WKBundlePageContextMenuClient* client) 263{ 264 m_contextMenuClient.initialize(client); 265} 266 267void WebPage::initializeInjectedBundleEditorClient(WKBundlePageEditorClient* client) 268{ 269 m_editorClient.initialize(client); 270} 271 272void WebPage::initializeInjectedBundleFormClient(WKBundlePageFormClient* client) 273{ 274 m_formClient.initialize(client); 275} 276 277void WebPage::initializeInjectedBundleLoaderClient(WKBundlePageLoaderClient* client) 278{ 279 m_loaderClient.initialize(client); 280} 281 282void WebPage::initializeInjectedBundlePolicyClient(WKBundlePagePolicyClient* client) 283{ 284 m_policyClient.initialize(client); 285} 286 287void WebPage::initializeInjectedBundleResourceLoadClient(WKBundlePageResourceLoadClient* client) 288{ 289 m_resourceLoadClient.initialize(client); 290} 291 292void WebPage::initializeInjectedBundleUIClient(WKBundlePageUIClient* client) 293{ 294 m_uiClient.initialize(client); 295} 296 297#if ENABLE(FULLSCREEN_API) 298void WebPage::initializeInjectedBundleFullScreenClient(WKBundlePageFullScreenClient* client) 299{ 300 m_fullScreenClient.initialize(client); 301} 302#endif 303 304PassRefPtr<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 324EditorState 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 340String WebPage::renderTreeExternalRepresentation() const 341{ 342 return externalRepresentation(m_mainFrame->coreFrame(), RenderAsTextBehaviorNormal); 343} 344 345void 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 353bool 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 363void WebPage::clearMainFrameName() 364{ 365 mainFrame()->coreFrame()->tree()->clearName(); 366} 367 368#if USE(ACCELERATED_COMPOSITING) 369void WebPage::enterAcceleratedCompositingMode(GraphicsLayer* layer) 370{ 371 m_drawingArea->setRootCompositingLayer(layer); 372} 373 374void WebPage::exitAcceleratedCompositingMode() 375{ 376 m_drawingArea->setRootCompositingLayer(0); 377} 378#endif 379 380void 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 426void WebPage::tryClose() 427{ 428 if (!m_mainFrame->coreFrame()->loader()->shouldClose()) 429 return; 430 431 sendClose(); 432} 433 434void WebPage::sendClose() 435{ 436 send(Messages::WebPageProxy::ClosePage()); 437} 438 439void WebPage::loadURL(const String& url, const SandboxExtension::Handle& sandboxExtensionHandle) 440{ 441 loadURLRequest(ResourceRequest(KURL(KURL(), url)), sandboxExtensionHandle); 442} 443 444void 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 450void 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 457void 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 464void 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 472void 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 478void 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 492void 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 501void WebPage::stopLoading() 502{ 503 m_mainFrame->coreFrame()->loader()->stopForUserCancel(); 504} 505 506void WebPage::setDefersLoading(bool defersLoading) 507{ 508 m_page->setDefersLoading(defersLoading); 509} 510 511void WebPage::reload(bool reloadFromOrigin) 512{ 513 m_mainFrame->coreFrame()->loader()->reload(reloadFromOrigin); 514} 515 516void 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 527void 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 538void 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 549void WebPage::layoutIfNeeded() 550{ 551 if (m_mainFrame->coreFrame()->view()) 552 m_mainFrame->coreFrame()->view()->updateLayoutAndStyleIfNeededRecursive(); 553} 554 555void 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) 576void WebPage::setActualVisibleContentRect(const IntRect& rect) 577{ 578 Frame* frame = m_page->mainFrame(); 579 580 frame->view()->setActualVisibleContentRect(rect); 581} 582 583void 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 604void 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 621void 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 642void 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 650void 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 660double WebPage::textZoomFactor() const 661{ 662 Frame* frame = m_mainFrame->coreFrame(); 663 if (!frame) 664 return 1; 665 return frame->textZoomFactor(); 666} 667 668void 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 676double WebPage::pageZoomFactor() const 677{ 678 Frame* frame = m_mainFrame->coreFrame(); 679 if (!frame) 680 return 1; 681 return frame->pageZoomFactor(); 682} 683 684void 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 692void 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 700void 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 710double WebPage::viewScaleFactor() const 711{ 712 Frame* frame = m_mainFrame->coreFrame(); 713 if (!frame) 714 return 1; 715 return frame->pageScaleFactor(); 716} 717 718void 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 733void 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 747void 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 771void 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 787PassRefPtr<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 811PassRefPtr<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 843PassRefPtr<WebImage> WebPage::snapshotInDocumentCoordinates(const IntRect& rect, ImageOptions options) 844{ 845 return scaledSnapshotInDocumentCoordinates(rect, 1, options); 846} 847 848void 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) 859void WebPage::pageDidRequestScroll(const IntPoint& point) 860{ 861 send(Messages::WebPageProxy::PageDidRequestScroll(point)); 862} 863#endif 864 865WebContextMenu* WebPage::contextMenu() 866{ 867 if (!m_contextMenu) 868 m_contextMenu = WebContextMenu::create(this); 869 return m_contextMenu.get(); 870} 871 872// Events 873 874static 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. 879const WebEvent* WebPage::currentEvent() 880{ 881 return g_currentEvent; 882} 883 884class CurrentEvent { 885public: 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 897private: 898 const WebEvent* m_previousCurrentEvent; 899}; 900 901static 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 915static 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 950void 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 974static 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 984void 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 992static 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 1002void 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) 1015static 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 1025void 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 1034void 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 1048void WebPage::executeEditCommand(const String& commandName) 1049{ 1050 executeEditingCommand(commandName, String()); 1051} 1052 1053uint64_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 1077void 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) 1084static 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 1093void 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 1103void WebPage::scroll(Page* page, ScrollDirection direction, ScrollGranularity granularity) 1104{ 1105 page->focusController()->focusedOrMainFrame()->eventHandler()->scrollRecursively(direction, granularity); 1106} 1107 1108void WebPage::logicalScroll(Page* page, ScrollLogicalDirection direction, ScrollGranularity granularity) 1109{ 1110 page->focusController()->focusedOrMainFrame()->eventHandler()->logicalScrollRecursively(direction, granularity); 1111} 1112 1113void WebPage::scrollBy(uint32_t scrollDirection, uint32_t scrollGranularity) 1114{ 1115 scroll(m_page.get(), static_cast<ScrollDirection>(scrollDirection), static_cast<ScrollGranularity>(scrollGranularity)); 1116} 1117 1118void 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 1129void 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 1145void 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 1162void 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 1174void 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 1186void 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 1194void 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 1204void 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 1218void 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 1229void 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 1237void WebPage::show() 1238{ 1239 send(Messages::WebPageProxy::ShowPage()); 1240} 1241 1242void WebPage::setUserAgent(const String& userAgent) 1243{ 1244 m_userAgent = userAgent; 1245} 1246 1247IntRect 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 1254IntRect 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 1269KeyboardUIMode WebPage::keyboardUIMode() 1270{ 1271 bool fullKeyboardAccessEnabled = WebProcess::shared().fullKeyboardAccessEnabled(); 1272 return static_cast<KeyboardUIMode>((fullKeyboardAccessEnabled ? KeyboardAccessFull : KeyboardAccessDefault) | (m_tabToLinks ? KeyboardAccessTabsToLinks : 0)); 1273} 1274 1275void 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 1295void WebPage::getContentsAsString(uint64_t callbackID) 1296{ 1297 String resultString = m_mainFrame->contentsAsString(); 1298 send(Messages::WebPageProxy::StringCallback(resultString, callbackID)); 1299} 1300 1301void WebPage::getRenderTreeExternalRepresentation(uint64_t callbackID) 1302{ 1303 String resultString = renderTreeExternalRepresentation(); 1304 send(Messages::WebPageProxy::StringCallback(resultString, callbackID)); 1305} 1306 1307void 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 1315void 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 1324void 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 1339void 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 1356void 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 1373void WebPage::forceRepaintWithoutCallback() 1374{ 1375 m_drawingArea->forceRepaint(); 1376} 1377 1378void WebPage::forceRepaint(uint64_t callbackID) 1379{ 1380 forceRepaintWithoutCallback(); 1381 send(Messages::WebPageProxy::VoidCallback(callbackID)); 1382} 1383 1384void WebPage::preferencesDidChange(const WebPreferencesStore& store) 1385{ 1386 WebPreferencesStore::removeTestRunnerOverrides(); 1387 updatePreferences(store); 1388} 1389 1390void 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) 1465WebInspector* 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) 1476WebFullScreenManager* 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) 1485bool 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) 1517void 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 1547void 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 1591void 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 1606void WebPage::willPerformLoadDragDestinationAction() 1607{ 1608 m_sandboxExtensionTracker.willPerformLoadDragDestinationAction(m_pendingDropSandboxExtension.release()); 1609} 1610 1611WebEditCommand* WebPage::webEditCommand(uint64_t commandID) 1612{ 1613 return m_editCommandMap.get(commandID).get(); 1614} 1615 1616void WebPage::addWebEditCommand(uint64_t commandID, WebEditCommand* command) 1617{ 1618 m_editCommandMap.set(commandID, command); 1619} 1620 1621void WebPage::removeWebEditCommand(uint64_t commandID) 1622{ 1623 m_editCommandMap.remove(commandID); 1624} 1625 1626void WebPage::unapplyEditCommand(uint64_t commandID) 1627{ 1628 WebEditCommand* command = webEditCommand(commandID); 1629 if (!command) 1630 return; 1631 1632 command->command()->unapply(); 1633} 1634 1635void 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 1646void WebPage::didRemoveEditCommand(uint64_t commandID) 1647{ 1648 removeWebEditCommand(commandID); 1649} 1650 1651void WebPage::setActivePopupMenu(WebPopupMenu* menu) 1652{ 1653 m_activePopupMenu = menu; 1654} 1655 1656void WebPage::setActiveOpenPanelResultListener(PassRefPtr<WebOpenPanelResultListener> openPanelResultListener) 1657{ 1658 m_activeOpenPanelResultListener = openPanelResultListener; 1659} 1660 1661bool WebPage::findStringFromInjectedBundle(const String& target, FindOptions options) 1662{ 1663 return m_page->findString(target, options); 1664} 1665 1666void WebPage::findString(const String& string, uint32_t options, uint32_t maxMatchCount) 1667{ 1668 m_findController.findString(string, static_cast<FindOptions>(options), maxMatchCount); 1669} 1670 1671void WebPage::hideFindUI() 1672{ 1673 m_findController.hideFindUI(); 1674} 1675 1676void WebPage::countStringMatches(const String& string, uint32_t options, uint32_t maxMatchCount) 1677{ 1678 m_findController.countStringMatches(string, static_cast<FindOptions>(options), maxMatchCount); 1679} 1680 1681void WebPage::didChangeSelectedIndexForActivePopupMenu(int32_t newIndex) 1682{ 1683 if (!m_activePopupMenu) 1684 return; 1685 1686 m_activePopupMenu->didChangeSelectedIndex(newIndex); 1687 m_activePopupMenu = 0; 1688} 1689 1690void 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 1699void WebPage::didCancelForOpenPanel() 1700{ 1701 m_activeOpenPanelResultListener = 0; 1702} 1703 1704#if ENABLE(WEB_PROCESS_SANDBOX) 1705void WebPage::extendSandboxForFileFromOpenPanel(const SandboxExtension::Handle& handle) 1706{ 1707 SandboxExtension::create(handle)->consumePermanently(); 1708} 1709#endif 1710 1711void WebPage::didReceiveGeolocationPermissionDecision(uint64_t geolocationID, bool allowed) 1712{ 1713 m_geolocationPermissionRequestManager.didReceiveGeolocationPermissionDecision(geolocationID, allowed); 1714} 1715 1716void WebPage::advanceToNextMisspelling(bool startBeforeSelection) 1717{ 1718 Frame* frame = m_page->focusController()->focusedOrMainFrame(); 1719 frame->editor()->advanceToNextMisspelling(startBeforeSelection); 1720} 1721 1722void WebPage::changeSpellingToWord(const String& word) 1723{ 1724 replaceSelectionWithText(m_page->focusController()->focusedOrMainFrame(), word); 1725} 1726 1727void 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 1735void 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) 1744void WebPage::uppercaseWord() 1745{ 1746 m_page->focusController()->focusedOrMainFrame()->editor()->uppercaseWord(); 1747} 1748 1749void WebPage::lowercaseWord() 1750{ 1751 m_page->focusController()->focusedOrMainFrame()->editor()->lowercaseWord(); 1752} 1753 1754void WebPage::capitalizeWord() 1755{ 1756 m_page->focusController()->focusedOrMainFrame()->editor()->capitalizeWord(); 1757} 1758#endif 1759 1760void WebPage::setTextForActivePopupMenu(int32_t index) 1761{ 1762 if (!m_activePopupMenu) 1763 return; 1764 1765 m_activePopupMenu->setTextForIndex(index); 1766} 1767 1768void WebPage::didSelectItemFromActiveContextMenu(const WebContextMenuItemData& item) 1769{ 1770 ASSERT(m_contextMenu); 1771 m_contextMenu->itemSelected(item); 1772 m_contextMenu = 0; 1773} 1774 1775void 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 1785bool WebPage::mainFrameHasCustomRepresentation() const 1786{ 1787 return static_cast<WebFrameLoaderClient*>(mainFrame()->coreFrame()->loader()->client())->frameHasCustomRepresentation(); 1788} 1789 1790void 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 1810void WebPage::addPluginView(PluginView* pluginView) 1811{ 1812 ASSERT(!m_pluginViews.contains(pluginView)); 1813 1814 m_pluginViews.add(pluginView); 1815} 1816 1817void WebPage::removePluginView(PluginView* pluginView) 1818{ 1819 ASSERT(m_pluginViews.contains(pluginView)); 1820 1821 m_pluginViews.remove(pluginView); 1822} 1823 1824void 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 1833void 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 1846bool WebPage::windowIsFocused() const 1847{ 1848 return m_page->focusController()->isActive(); 1849} 1850 1851void 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 1885CoreIPC::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 1890InjectedBundleBackForwardList* WebPage::backForwardList() 1891{ 1892 if (!m_backForwardList) 1893 m_backForwardList = InjectedBundleBackForwardList::create(this); 1894 return m_backForwardList.get(); 1895} 1896 1897#if PLATFORM(QT) 1898void 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 1916WebPage::SandboxExtensionTracker::~SandboxExtensionTracker() 1917{ 1918 invalidate(); 1919} 1920 1921void 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 1939void WebPage::SandboxExtensionTracker::willPerformLoadDragDestinationAction(PassRefPtr<SandboxExtension> pendingDropSandboxExtension) 1940{ 1941 setPendingProvisionalSandboxExtension(pendingDropSandboxExtension); 1942} 1943 1944void WebPage::SandboxExtensionTracker::beginLoad(WebFrame* frame, const SandboxExtension::Handle& handle) 1945{ 1946 ASSERT(frame->isMainFrame()); 1947 1948 setPendingProvisionalSandboxExtension(SandboxExtension::create(handle)); 1949} 1950 1951void 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 1963static 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 1985void 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 2004void 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 2019void 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 2031bool 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 2044void WebPage::setCustomTextEncodingName(const String& encoding) 2045{ 2046 m_page->mainFrame()->loader()->reloadWithOverrideEncoding(encoding); 2047} 2048 2049void WebPage::didRemoveBackForwardItem(uint64_t itemID) 2050{ 2051 WebBackForwardListProxy::removeItem(itemID); 2052} 2053 2054#if PLATFORM(MAC) 2055 2056bool WebPage::isSpeaking() 2057{ 2058 bool result; 2059 return sendSync(Messages::WebPageProxy::GetIsSpeaking(), Messages::WebPageProxy::GetIsSpeaking::Reply(result)) && result; 2060} 2061 2062void WebPage::speak(const String& string) 2063{ 2064 send(Messages::WebPageProxy::Speak(string)); 2065} 2066 2067void WebPage::stopSpeaking() 2068{ 2069 send(Messages::WebPageProxy::StopSpeaking()); 2070} 2071 2072#endif 2073 2074void 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 2093void WebPage::endPrinting() 2094{ 2095 m_printContext = nullptr; 2096} 2097 2098void 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) 2118void 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 2150void 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 2188void 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 2201void WebPage::setMemoryCacheMessagesEnabled(bool memoryCacheMessagesEnabled) 2202{ 2203 m_page->setMemoryCacheClientCallsEnabled(memoryCacheMessagesEnabled); 2204} 2205 2206#if !PLATFORM(MAC) 2207void WebPage::platformDragEnded() 2208{ 2209} 2210#endif 2211 2212bool 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) 2220void 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 2229void 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 2234void 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 2239void 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