1/* 2 * Copyright (C) 2010, 2011, 2012, 2013 Apple Inc. All rights reserved. 3 * Copyright (C) 2012 Intel Corporation. All rights reserved. 4 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 17 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 19 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 25 * THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28#include "config.h" 29#include "WebPage.h" 30 31#include "Arguments.h" 32#include "DataReference.h" 33#include "DecoderAdapter.h" 34#include "DrawingArea.h" 35#include "DrawingAreaMessages.h" 36#include "InjectedBundle.h" 37#include "InjectedBundleBackForwardList.h" 38#include "InjectedBundleUserMessageCoders.h" 39#include "LayerTreeHost.h" 40#include "Logging.h" 41#include "NetscapePlugin.h" 42#include "NotificationPermissionRequestManager.h" 43#include "PageBanner.h" 44#include "PageOverlay.h" 45#include "PluginProcessAttributes.h" 46#include "PluginProxy.h" 47#include "PluginView.h" 48#include "PrintInfo.h" 49#include "SessionState.h" 50#include "ShareableBitmap.h" 51#include "WebAlternativeTextClient.h" 52#include "WebBackForwardList.h" 53#include "WebBackForwardListItem.h" 54#include "WebBackForwardListProxy.h" 55#include "WebChromeClient.h" 56#include "WebColorChooser.h" 57#include "WebContextMenu.h" 58#include "WebContextMenuClient.h" 59#include "WebContextMessages.h" 60#include "WebCoreArgumentCoders.h" 61#include "WebDragClient.h" 62#include "WebEditorClient.h" 63#include "WebEvent.h" 64#include "WebEventConversion.h" 65#include "WebFrame.h" 66#include "WebFullScreenManager.h" 67#include "WebFullScreenManagerMessages.h" 68#include "WebGeolocationClient.h" 69#include "WebGeometry.h" 70#include "WebImage.h" 71#include "WebInspector.h" 72#include "WebInspectorClient.h" 73#include "WebInspectorMessages.h" 74#include "WebNotificationClient.h" 75#include "WebOpenPanelResultListener.h" 76#include "WebPageCreationParameters.h" 77#include "WebPageGroupProxy.h" 78#include "WebPageMessages.h" 79#include "WebPageProxyMessages.h" 80#include "WebPlugInClient.h" 81#include "WebPopupMenu.h" 82#include "WebPreferencesStore.h" 83#include "WebProcess.h" 84#include "WebProcessProxyMessages.h" 85#include <JavaScriptCore/APICast.h> 86#include <WebCore/ArchiveResource.h> 87#include <WebCore/Chrome.h> 88#include <WebCore/ContextMenuController.h> 89#include <WebCore/DatabaseManager.h> 90#include <WebCore/DocumentFragment.h> 91#include <WebCore/DocumentLoader.h> 92#include <WebCore/DocumentMarkerController.h> 93#include <WebCore/DragController.h> 94#include <WebCore/DragData.h> 95#include <WebCore/DragSession.h> 96#include <WebCore/EventHandler.h> 97#include <WebCore/FocusController.h> 98#include <WebCore/FormState.h> 99#include <WebCore/Frame.h> 100#include <WebCore/FrameLoadRequest.h> 101#include <WebCore/FrameLoaderTypes.h> 102#include <WebCore/FrameView.h> 103#include <WebCore/HTMLFormElement.h> 104#include <WebCore/HTMLInputElement.h> 105#include <WebCore/HTMLPlugInElement.h> 106#include <WebCore/HTMLPlugInImageElement.h> 107#include <WebCore/HistoryController.h> 108#include <WebCore/HistoryItem.h> 109#include <WebCore/JSDOMWindow.h> 110#include <WebCore/KeyboardEvent.h> 111#include <WebCore/MIMETypeRegistry.h> 112#include <WebCore/MouseEvent.h> 113#include <WebCore/Page.h> 114#include <WebCore/PlatformKeyboardEvent.h> 115#include <WebCore/PluginDocument.h> 116#include <WebCore/PrintContext.h> 117#include <WebCore/Range.h> 118#include <WebCore/RenderLayer.h> 119#include <WebCore/RenderTreeAsText.h> 120#include <WebCore/RenderView.h> 121#include <WebCore/ResourceBuffer.h> 122#include <WebCore/ResourceRequest.h> 123#include <WebCore/ResourceResponse.h> 124#include <WebCore/RunLoop.h> 125#include <WebCore/RuntimeEnabledFeatures.h> 126#include <WebCore/SchemeRegistry.h> 127#include <WebCore/ScriptController.h> 128#include <WebCore/ScriptValue.h> 129#include <WebCore/SerializedScriptValue.h> 130#include <WebCore/Settings.h> 131#include <WebCore/SharedBuffer.h> 132#include <WebCore/SubstituteData.h> 133#include <WebCore/TextIterator.h> 134#include <WebCore/VisiblePosition.h> 135#include <WebCore/markup.h> 136#include <runtime/JSCJSValue.h> 137#include <runtime/JSLock.h> 138#include <runtime/Operations.h> 139 140#if ENABLE(MHTML) 141#include <WebCore/MHTMLArchive.h> 142#endif 143 144#if ENABLE(PLUGIN_PROCESS) 145#if PLATFORM(MAC) 146#include "MachPort.h" 147#endif 148#endif 149 150#if ENABLE(BATTERY_STATUS) 151#include "WebBatteryClient.h" 152#endif 153 154#if ENABLE(NETWORK_INFO) 155#include "WebNetworkInfoClient.h" 156#endif 157 158#if ENABLE(VIBRATION) 159#include "WebVibrationClient.h" 160#endif 161 162#if ENABLE(PROXIMITY_EVENTS) 163#include "WebDeviceProximityClient.h" 164#endif 165 166#if PLATFORM(MAC) 167#include "SimplePDFPlugin.h" 168#if ENABLE(PDFKIT_PLUGIN) 169#include "PDFPlugin.h" 170#endif 171#include <WebCore/LegacyWebArchive.h> 172#endif 173 174#if PLATFORM(QT) 175#if ENABLE(DEVICE_ORIENTATION) && HAVE(QTSENSORS) 176#include "DeviceMotionClientQt.h" 177#include "DeviceOrientationClientQt.h" 178#endif 179#include "HitTestResult.h" 180#include <QMimeData> 181#endif 182 183#if PLATFORM(GTK) 184#include <gtk/gtk.h> 185#include "DataObjectGtk.h" 186#include "WebPrintOperationGtk.h" 187#endif 188 189#ifndef NDEBUG 190#include <wtf/RefCountedLeakCounter.h> 191#endif 192 193#if USE(COORDINATED_GRAPHICS) 194#include "CoordinatedLayerTreeHostMessages.h" 195#endif 196 197using namespace JSC; 198using namespace WebCore; 199 200namespace WebKit { 201 202class SendStopResponsivenessTimer { 203public: 204 SendStopResponsivenessTimer(WebPage* page) 205 : m_page(page) 206 { 207 } 208 209 ~SendStopResponsivenessTimer() 210 { 211 m_page->send(Messages::WebPageProxy::StopResponsivenessTimer()); 212 } 213 214private: 215 WebPage* m_page; 216}; 217 218DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, webPageCounter, ("WebPage")); 219 220PassRefPtr<WebPage> WebPage::create(uint64_t pageID, const WebPageCreationParameters& parameters) 221{ 222 RefPtr<WebPage> page = adoptRef(new WebPage(pageID, parameters)); 223 224 if (page->pageGroup()->isVisibleToInjectedBundle() && WebProcess::shared().injectedBundle()) 225 WebProcess::shared().injectedBundle()->didCreatePage(page.get()); 226 227 return page.release(); 228} 229 230WebPage::WebPage(uint64_t pageID, const WebPageCreationParameters& parameters) 231 : m_viewSize(parameters.viewSize) 232 , m_hasSeenPlugin(false) 233 , m_useFixedLayout(false) 234 , m_drawsBackground(true) 235 , m_drawsTransparentBackground(false) 236 , m_isInRedo(false) 237 , m_isClosed(false) 238 , m_tabToLinks(false) 239 , m_asynchronousPluginInitializationEnabled(false) 240 , m_asynchronousPluginInitializationEnabledForAllPlugins(false) 241 , m_artificialPluginInitializationDelayEnabled(false) 242 , m_scrollingPerformanceLoggingEnabled(false) 243 , m_mainFrameIsScrollable(true) 244#if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC) 245 , m_readyToFindPrimarySnapshottedPlugin(false) 246 , m_didFindPrimarySnapshottedPlugin(false) 247 , m_numberOfPrimarySnapshotDetectionAttempts(0) 248 , m_determinePrimarySnapshottedPlugInTimer(RunLoop::main(), this, &WebPage::determinePrimarySnapshottedPlugInTimerFired) 249#endif 250#if PLATFORM(MAC) 251 , m_pdfPluginEnabled(false) 252 , m_hasCachedWindowFrame(false) 253 , m_windowIsVisible(false) 254 , m_layerHostingMode(parameters.layerHostingMode) 255 , m_keyboardEventBeingInterpreted(0) 256#elif PLATFORM(GTK) 257 , m_accessibilityObject(0) 258#endif 259 , m_setCanStartMediaTimer(RunLoop::main(), this, &WebPage::setCanStartMediaTimerFired) 260 , m_sendDidUpdateInWindowStateTimer(RunLoop::main(), this, &WebPage::didUpdateInWindowStateTimerFired) 261 , m_findController(this) 262#if ENABLE(TOUCH_EVENTS) 263#if PLATFORM(QT) 264 , m_tapHighlightController(this) 265#endif 266#endif 267#if ENABLE(INPUT_TYPE_COLOR) 268 , m_activeColorChooser(0) 269#endif 270#if ENABLE(GEOLOCATION) 271 , m_geolocationPermissionRequestManager(this) 272#endif 273 , m_pageID(pageID) 274 , m_canRunBeforeUnloadConfirmPanel(parameters.canRunBeforeUnloadConfirmPanel) 275 , m_canRunModal(parameters.canRunModal) 276 , m_isRunningModal(false) 277 , m_cachedMainFrameIsPinnedToLeftSide(false) 278 , m_cachedMainFrameIsPinnedToRightSide(false) 279 , m_cachedMainFrameIsPinnedToTopSide(false) 280 , m_cachedMainFrameIsPinnedToBottomSide(false) 281 , m_canShortCircuitHorizontalWheelEvents(false) 282 , m_numWheelEventHandlers(0) 283 , m_cachedPageCount(0) 284 , m_autoSizingShouldExpandToViewHeight(false) 285#if ENABLE(CONTEXT_MENUS) 286 , m_isShowingContextMenu(false) 287#endif 288 , m_willGoToBackForwardItemCallbackEnabled(true) 289#if ENABLE(PAGE_VISIBILITY_API) 290 , m_visibilityState(WebCore::PageVisibilityStateVisible) 291#endif 292 , m_inspectorClient(0) 293 , m_backgroundColor(Color::white) 294 , m_maximumRenderingSuppressionToken(0) 295 , m_scrollPinningBehavior(DoNotPin) 296{ 297 ASSERT(m_pageID); 298 // FIXME: This is a non-ideal location for this Setting and 299 // 4ms should be adopted project-wide now, https://bugs.webkit.org/show_bug.cgi?id=61214 300 Settings::setDefaultMinDOMTimerInterval(0.004); 301 302 Page::PageClients pageClients; 303 pageClients.chromeClient = new WebChromeClient(this); 304#if ENABLE(CONTEXT_MENUS) 305 pageClients.contextMenuClient = new WebContextMenuClient(this); 306#endif 307 pageClients.editorClient = new WebEditorClient(this); 308#if ENABLE(DRAG_SUPPORT) 309 pageClients.dragClient = new WebDragClient(this); 310#endif 311 pageClients.backForwardClient = WebBackForwardListProxy::create(this); 312#if ENABLE(INSPECTOR) 313 m_inspectorClient = new WebInspectorClient(this); 314 pageClients.inspectorClient = m_inspectorClient; 315#endif 316#if USE(AUTOCORRECTION_PANEL) 317 pageClients.alternativeTextClient = new WebAlternativeTextClient(this); 318#endif 319 pageClients.plugInClient = new WebPlugInClient(this); 320 321 m_page = adoptPtr(new Page(pageClients)); 322 323#if ENABLE(BATTERY_STATUS) 324 WebCore::provideBatteryTo(m_page.get(), new WebBatteryClient(this)); 325#endif 326#if ENABLE(GEOLOCATION) 327 WebCore::provideGeolocationTo(m_page.get(), new WebGeolocationClient(this)); 328#endif 329#if ENABLE(DEVICE_ORIENTATION) && PLATFORM(QT) && HAVE(QTSENSORS) 330 WebCore::provideDeviceMotionTo(m_page.get(), new DeviceMotionClientQt); 331 WebCore::provideDeviceOrientationTo(m_page.get(), new DeviceOrientationClientQt); 332#endif 333#if ENABLE(NETWORK_INFO) 334 WebCore::provideNetworkInfoTo(m_page.get(), new WebNetworkInfoClient(this)); 335#endif 336#if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS) 337 WebCore::provideNotification(m_page.get(), new WebNotificationClient(this)); 338#endif 339#if ENABLE(VIBRATION) 340 WebCore::provideVibrationTo(m_page.get(), new WebVibrationClient(this)); 341#endif 342#if ENABLE(PROXIMITY_EVENTS) 343 WebCore::provideDeviceProximityTo(m_page.get(), new WebDeviceProximityClient(this)); 344#endif 345 346 m_page->setCanStartMedia(false); 347 m_mayStartMediaWhenInWindow = parameters.mayStartMediaWhenInWindow; 348 349 m_pageGroup = WebProcess::shared().webPageGroup(parameters.pageGroupData); 350 m_page->setGroupName(m_pageGroup->identifier()); 351 m_page->setDeviceScaleFactor(parameters.deviceScaleFactor); 352 353 m_drawingArea = DrawingArea::create(this, parameters); 354 m_drawingArea->setPaintingEnabled(false); 355 356 updatePreferences(parameters.store); 357 platformInitialize(); 358 359 m_mainFrame = WebFrame::createMainFrame(this); 360 361 setUseFixedLayout(parameters.useFixedLayout); 362 363 setDrawsBackground(parameters.drawsBackground); 364 setDrawsTransparentBackground(parameters.drawsTransparentBackground); 365 366 setUnderlayColor(parameters.underlayColor); 367 368 setPaginationMode(parameters.paginationMode); 369 setPaginationBehavesLikeColumns(parameters.paginationBehavesLikeColumns); 370 setPageLength(parameters.pageLength); 371 setGapBetweenPages(parameters.gapBetweenPages); 372 373 setMemoryCacheMessagesEnabled(parameters.areMemoryCacheClientCallsEnabled); 374 375 setActive(parameters.isActive); 376 setFocused(parameters.isFocused); 377 378 // Page defaults to in-window, but setIsInWindow depends on it being a valid indicator of actually having been put into a window. 379 if (!parameters.isInWindow) 380 m_page->setIsInWindow(false); 381 else 382 WebProcess::shared().pageDidEnterWindow(m_pageID); 383 384 setIsInWindow(parameters.isInWindow); 385 386 setMinimumLayoutSize(parameters.minimumLayoutSize); 387 setAutoSizingShouldExpandToViewHeight(parameters.autoSizingShouldExpandToViewHeight); 388 389 setScrollPinningBehavior(parameters.scrollPinningBehavior); 390 391 m_userAgent = parameters.userAgent; 392 393 WebBackForwardListProxy::setHighestItemIDFromUIProcess(parameters.highestUsedBackForwardItemID); 394 395 if (!parameters.sessionState.isEmpty()) 396 restoreSession(parameters.sessionState); 397 398 m_drawingArea->setPaintingEnabled(true); 399 400 setMediaVolume(parameters.mediaVolume); 401 402 // We use the DidFirstLayout milestone to determine when to unfreeze the layer tree. 403 m_page->addLayoutMilestones(DidFirstLayout); 404 405 WebProcess::shared().addMessageReceiver(Messages::WebPage::messageReceiverName(), m_pageID, this); 406 407 // FIXME: This should be done in the object constructors, and the objects themselves should be message receivers. 408 WebProcess::shared().addMessageReceiver(Messages::DrawingArea::messageReceiverName(), m_pageID, this); 409#if USE(COORDINATED_GRAPHICS) 410 WebProcess::shared().addMessageReceiver(Messages::CoordinatedLayerTreeHost::messageReceiverName(), m_pageID, this); 411#endif 412#if ENABLE(INSPECTOR) 413 WebProcess::shared().addMessageReceiver(Messages::WebInspector::messageReceiverName(), m_pageID, this); 414#endif 415#if ENABLE(FULLSCREEN_API) 416 WebProcess::shared().addMessageReceiver(Messages::WebFullScreenManager::messageReceiverName(), m_pageID, this); 417#endif 418 419#ifndef NDEBUG 420 webPageCounter.increment(); 421#endif 422} 423 424WebPage::~WebPage() 425{ 426 if (m_backForwardList) 427 m_backForwardList->detach(); 428 429 ASSERT(!m_page); 430 431 m_sandboxExtensionTracker.invalidate(); 432 433 for (HashSet<PluginView*>::const_iterator it = m_pluginViews.begin(), end = m_pluginViews.end(); it != end; ++it) 434 (*it)->webPageDestroyed(); 435 436 if (m_headerBanner) 437 m_headerBanner->detachFromPage(); 438 if (m_footerBanner) 439 m_footerBanner->detachFromPage(); 440 441 WebProcess::shared().removeMessageReceiver(Messages::WebPage::messageReceiverName(), m_pageID); 442 443 // FIXME: This should be done in the object destructors, and the objects themselves should be message receivers. 444 WebProcess::shared().removeMessageReceiver(Messages::DrawingArea::messageReceiverName(), m_pageID); 445#if USE(COORDINATED_GRAPHICS) 446 WebProcess::shared().removeMessageReceiver(Messages::CoordinatedLayerTreeHost::messageReceiverName(), m_pageID); 447#endif 448#if ENABLE(INSPECTOR) 449 WebProcess::shared().removeMessageReceiver(Messages::WebInspector::messageReceiverName(), m_pageID); 450#endif 451#if ENABLE(FULLSCREEN_API) 452 WebProcess::shared().removeMessageReceiver(Messages::WebFullScreenManager::messageReceiverName(), m_pageID); 453#endif 454 455#ifndef NDEBUG 456 webPageCounter.decrement(); 457#endif 458} 459 460void WebPage::dummy(bool&) 461{ 462} 463 464CoreIPC::Connection* WebPage::messageSenderConnection() 465{ 466 return WebProcess::shared().parentProcessConnection(); 467} 468 469uint64_t WebPage::messageSenderDestinationID() 470{ 471 return pageID(); 472} 473 474#if ENABLE(CONTEXT_MENUS) 475void WebPage::initializeInjectedBundleContextMenuClient(WKBundlePageContextMenuClient* client) 476{ 477 m_contextMenuClient.initialize(client); 478} 479#endif 480 481void WebPage::initializeInjectedBundleEditorClient(WKBundlePageEditorClient* client) 482{ 483 m_editorClient.initialize(client); 484} 485 486void WebPage::initializeInjectedBundleFormClient(WKBundlePageFormClient* client) 487{ 488 m_formClient.initialize(client); 489} 490 491void WebPage::initializeInjectedBundleLoaderClient(WKBundlePageLoaderClient* client) 492{ 493 // It would be nice to get rid of this code and transition all clients to using didLayout instead of 494 // didFirstLayoutInFrame and didFirstVisuallyNonEmptyLayoutInFrame. In the meantime, this is required 495 // for backwards compatibility. 496 LayoutMilestones milestones = 0; 497 if (client) { 498 if (client->didFirstLayoutForFrame) 499 milestones |= WebCore::DidFirstLayout; 500 if (client->didFirstVisuallyNonEmptyLayoutForFrame) 501 milestones |= WebCore::DidFirstVisuallyNonEmptyLayout; 502 if (client->didNewFirstVisuallyNonEmptyLayout) 503 milestones |= WebCore::DidHitRelevantRepaintedObjectsAreaThreshold; 504 } 505 506 if (milestones) 507 listenForLayoutMilestones(milestones); 508 509 m_loaderClient.initialize(client); 510} 511 512void WebPage::initializeInjectedBundlePolicyClient(WKBundlePagePolicyClient* client) 513{ 514 m_policyClient.initialize(client); 515} 516 517void WebPage::initializeInjectedBundleResourceLoadClient(WKBundlePageResourceLoadClient* client) 518{ 519 m_resourceLoadClient.initialize(client); 520} 521 522void WebPage::initializeInjectedBundleUIClient(WKBundlePageUIClient* client) 523{ 524 m_uiClient.initialize(client); 525} 526 527#if ENABLE(FULLSCREEN_API) 528void WebPage::initializeInjectedBundleFullScreenClient(WKBundlePageFullScreenClient* client) 529{ 530 m_fullScreenClient.initialize(client); 531} 532#endif 533 534void WebPage::initializeInjectedBundleDiagnosticLoggingClient(WKBundlePageDiagnosticLoggingClient* client) 535{ 536 m_logDiagnosticMessageClient.initialize(client); 537} 538 539#if ENABLE(NETSCAPE_PLUGIN_API) 540PassRefPtr<Plugin> WebPage::createPlugin(WebFrame* frame, HTMLPlugInElement* pluginElement, const Plugin::Parameters& parameters, String& newMIMEType) 541{ 542 String frameURLString = frame->coreFrame()->loader()->documentLoader()->responseURL().string(); 543 String pageURLString = m_page->mainFrame()->loader()->documentLoader()->responseURL().string(); 544 PluginProcessType processType = pluginElement->displayState() == HTMLPlugInElement::WaitingForSnapshot ? PluginProcessTypeSnapshot : PluginProcessTypeNormal; 545 546 bool allowOnlyApplicationPlugins = !frame->coreFrame()->loader()->subframeLoader()->allowPlugins(NotAboutToInstantiatePlugin); 547 548 uint64_t pluginProcessToken; 549 uint32_t pluginLoadPolicy; 550 String unavailabilityDescription; 551 if (!sendSync(Messages::WebPageProxy::FindPlugin(parameters.mimeType, static_cast<uint32_t>(processType), parameters.url.string(), frameURLString, pageURLString, allowOnlyApplicationPlugins), Messages::WebPageProxy::FindPlugin::Reply(pluginProcessToken, newMIMEType, pluginLoadPolicy, unavailabilityDescription))) { 552 return 0; 553 } 554 555 switch (static_cast<PluginModuleLoadPolicy>(pluginLoadPolicy)) { 556 case PluginModuleLoadNormally: 557 case PluginModuleLoadUnsandboxed: 558 break; 559 560 case PluginModuleBlocked: 561 bool replacementObscured = false; 562 if (pluginElement->renderer()->isEmbeddedObject()) { 563 RenderEmbeddedObject* renderObject = toRenderEmbeddedObject(pluginElement->renderer()); 564 renderObject->setPluginUnavailabilityReasonWithDescription(RenderEmbeddedObject::InsecurePluginVersion, unavailabilityDescription); 565 replacementObscured = renderObject->isReplacementObscured(); 566 renderObject->setUnavailablePluginIndicatorIsHidden(replacementObscured); 567 } 568 569 send(Messages::WebPageProxy::DidBlockInsecurePluginVersion(parameters.mimeType, parameters.url.string(), frameURLString, pageURLString, replacementObscured)); 570 return 0; 571 } 572 573 if (!pluginProcessToken) { 574#if PLATFORM(MAC) 575 String path = parameters.url.path(); 576 if (MIMETypeRegistry::isPDFOrPostScriptMIMEType(parameters.mimeType) || (parameters.mimeType.isEmpty() && (path.endsWith(".pdf", false) || path.endsWith(".ps", false)))) { 577#if ENABLE(PDFKIT_PLUGIN) 578 if (shouldUsePDFPlugin()) 579 return PDFPlugin::create(frame); 580#endif 581 return SimplePDFPlugin::create(frame); 582 } 583#else 584 UNUSED_PARAM(frame); 585#endif 586 return 0; 587 } 588 589 bool isRestartedProcess = (pluginElement->displayState() == HTMLPlugInElement::Restarting || pluginElement->displayState() == HTMLPlugInElement::RestartingWithPendingMouseClick); 590 return PluginProxy::create(pluginProcessToken, isRestartedProcess); 591} 592 593#endif // ENABLE(NETSCAPE_PLUGIN_API) 594 595EditorState WebPage::editorState() const 596{ 597 Frame* frame = m_page->focusController()->focusedOrMainFrame(); 598 ASSERT(frame); 599 600 EditorState result; 601 602 if (PluginView* pluginView = focusedPluginViewForFrame(frame)) { 603 if (!pluginView->getSelectionString().isNull()) { 604 result.selectionIsNone = false; 605 result.selectionIsRange = true; 606 result.isInPlugin = true; 607 return result; 608 } 609 } 610 611 result.selectionIsNone = frame->selection()->isNone(); 612 result.selectionIsRange = frame->selection()->isRange(); 613 result.isContentEditable = frame->selection()->isContentEditable(); 614 result.isContentRichlyEditable = frame->selection()->isContentRichlyEditable(); 615 result.isInPasswordField = frame->selection()->isInPasswordField(); 616 result.hasComposition = frame->editor().hasComposition(); 617 result.shouldIgnoreCompositionSelectionChange = frame->editor().ignoreCompositionSelectionChange(); 618 619#if PLATFORM(QT) 620 size_t location = 0; 621 size_t length = 0; 622 623 Element* selectionRoot = frame->selection()->rootEditableElementRespectingShadowTree(); 624 Element* scope = selectionRoot ? selectionRoot : frame->document()->documentElement(); 625 626 if (!scope) 627 return result; 628 629 if (scope->hasTagName(HTMLNames::inputTag)) { 630 HTMLInputElement* input = static_cast<HTMLInputElement*>(scope); 631 if (input->isTelephoneField()) 632 result.inputMethodHints |= Qt::ImhDialableCharactersOnly; 633 else if (input->isNumberField()) 634 result.inputMethodHints |= Qt::ImhDigitsOnly; 635 else if (input->isEmailField()) { 636 result.inputMethodHints |= Qt::ImhEmailCharactersOnly; 637 result.inputMethodHints |= Qt::ImhNoAutoUppercase; 638 } else if (input->isURLField()) { 639 result.inputMethodHints |= Qt::ImhUrlCharactersOnly; 640 result.inputMethodHints |= Qt::ImhNoAutoUppercase; 641 } else if (input->isPasswordField()) { 642 // Set ImhHiddenText flag for password fields. The Qt platform 643 // is responsible for determining which widget will receive input 644 // method events for password fields. 645 result.inputMethodHints |= Qt::ImhHiddenText; 646 result.inputMethodHints |= Qt::ImhNoAutoUppercase; 647 result.inputMethodHints |= Qt::ImhNoPredictiveText; 648 result.inputMethodHints |= Qt::ImhSensitiveData; 649 } 650 } 651 652 if (selectionRoot) 653 result.editorRect = frame->view()->contentsToWindow(selectionRoot->pixelSnappedBoundingBox()); 654 655 RefPtr<Range> range; 656 if (result.hasComposition && (range = frame->editor().compositionRange())) { 657 frame->editor().getCompositionSelection(result.anchorPosition, result.cursorPosition); 658 659 result.compositionRect = frame->view()->contentsToWindow(range->boundingBox()); 660 } 661 662 if (!result.hasComposition && !result.selectionIsNone && (range = frame->selection()->selection().firstRange())) { 663 TextIterator::getLocationAndLengthFromRange(scope, range.get(), location, length); 664 bool baseIsFirst = frame->selection()->selection().isBaseFirst(); 665 666 result.cursorPosition = (baseIsFirst) ? location + length : location; 667 result.anchorPosition = (baseIsFirst) ? location : location + length; 668 result.selectedText = range->text(); 669 } 670 671 if (range) 672 result.cursorRect = frame->view()->contentsToWindow(frame->editor().firstRectForRange(range.get())); 673 674 // FIXME: We should only transfer innerText when it changes and do this on the UI side. 675 if (result.isContentEditable && !result.isInPasswordField) { 676 result.surroundingText = scope->innerText(); 677 if (result.hasComposition) { 678 // The anchor is always the left position when they represent a composition. 679 result.surroundingText.remove(result.anchorPosition, result.cursorPosition - result.anchorPosition); 680 } 681 } 682#endif 683 684#if PLATFORM(GTK) 685 result.cursorRect = frame->selection()->absoluteCaretBounds(); 686#endif 687 688 return result; 689} 690 691String WebPage::renderTreeExternalRepresentation() const 692{ 693 return externalRepresentation(m_mainFrame->coreFrame(), RenderAsTextBehaviorNormal); 694} 695 696String WebPage::renderTreeExternalRepresentationForPrinting() const 697{ 698 return externalRepresentation(m_mainFrame->coreFrame(), RenderAsTextPrintingMode); 699} 700 701uint64_t WebPage::renderTreeSize() const 702{ 703 if (!m_page) 704 return 0; 705 return m_page->renderTreeSize().treeSize; 706} 707 708void WebPage::setTracksRepaints(bool trackRepaints) 709{ 710 if (FrameView* view = mainFrameView()) 711 view->setTracksRepaints(trackRepaints); 712} 713 714bool WebPage::isTrackingRepaints() const 715{ 716 if (FrameView* view = mainFrameView()) 717 return view->isTrackingRepaints(); 718 719 return false; 720} 721 722void WebPage::resetTrackedRepaints() 723{ 724 if (FrameView* view = mainFrameView()) 725 view->resetTrackedRepaints(); 726} 727 728PassRefPtr<ImmutableArray> WebPage::trackedRepaintRects() 729{ 730 FrameView* view = mainFrameView(); 731 if (!view) 732 return ImmutableArray::create(); 733 734 const Vector<IntRect>& rects = view->trackedRepaintRects(); 735 size_t size = rects.size(); 736 if (!size) 737 return ImmutableArray::create(); 738 739 Vector<RefPtr<APIObject>> vector; 740 vector.reserveInitialCapacity(size); 741 742 for (size_t i = 0; i < size; ++i) 743 vector.uncheckedAppend(WebRect::create(toAPI(rects[i]))); 744 745 return ImmutableArray::adopt(vector); 746} 747 748PluginView* WebPage::focusedPluginViewForFrame(Frame* frame) 749{ 750 if (!frame->document()->isPluginDocument()) 751 return 0; 752 753 PluginDocument* pluginDocument = static_cast<PluginDocument*>(frame->document()); 754 755 if (pluginDocument->focusedElement() != pluginDocument->pluginElement()) 756 return 0; 757 758 PluginView* pluginView = static_cast<PluginView*>(pluginDocument->pluginWidget()); 759 return pluginView; 760} 761 762PluginView* WebPage::pluginViewForFrame(Frame* frame) 763{ 764 if (!frame->document()->isPluginDocument()) 765 return 0; 766 767 PluginDocument* pluginDocument = static_cast<PluginDocument*>(frame->document()); 768 PluginView* pluginView = static_cast<PluginView*>(pluginDocument->pluginWidget()); 769 return pluginView; 770} 771 772void WebPage::executeEditingCommand(const String& commandName, const String& argument) 773{ 774 Frame* frame = m_page->focusController()->focusedOrMainFrame(); 775 if (!frame) 776 return; 777 778 if (PluginView* pluginView = focusedPluginViewForFrame(frame)) { 779 pluginView->handleEditingCommand(commandName, argument); 780 return; 781 } 782 783 frame->editor().command(commandName).execute(argument); 784} 785 786bool WebPage::isEditingCommandEnabled(const String& commandName) 787{ 788 Frame* frame = m_page->focusController()->focusedOrMainFrame(); 789 if (!frame) 790 return false; 791 792 if (PluginView* pluginView = focusedPluginViewForFrame(frame)) 793 return pluginView->isEditingCommandEnabled(commandName); 794 795 Editor::Command command = frame->editor().command(commandName); 796 return command.isSupported() && command.isEnabled(); 797} 798 799void WebPage::clearMainFrameName() 800{ 801 if (Frame* frame = mainFrame()) 802 frame->tree()->clearName(); 803} 804 805#if USE(ACCELERATED_COMPOSITING) 806void WebPage::enterAcceleratedCompositingMode(GraphicsLayer* layer) 807{ 808 m_drawingArea->setRootCompositingLayer(layer); 809} 810 811void WebPage::exitAcceleratedCompositingMode() 812{ 813 m_drawingArea->setRootCompositingLayer(0); 814} 815#endif 816 817void WebPage::close() 818{ 819 if (m_isClosed) 820 return; 821 822 m_isClosed = true; 823 824 // If there is still no URL, then we never loaded anything in this page, so nothing to report. 825 if (!mainWebFrame()->url().isEmpty()) 826 reportUsedFeatures(); 827 828 if (pageGroup()->isVisibleToInjectedBundle() && WebProcess::shared().injectedBundle()) 829 WebProcess::shared().injectedBundle()->willDestroyPage(this); 830 831#if ENABLE(INSPECTOR) 832 m_inspector = 0; 833#endif 834#if ENABLE(FULLSCREEN_API) 835 m_fullScreenManager = 0; 836#endif 837 838 if (m_activePopupMenu) { 839 m_activePopupMenu->disconnectFromPage(); 840 m_activePopupMenu = 0; 841 } 842 843 if (m_activeOpenPanelResultListener) { 844 m_activeOpenPanelResultListener->disconnectFromPage(); 845 m_activeOpenPanelResultListener = 0; 846 } 847 848#if ENABLE(INPUT_TYPE_COLOR) 849 if (m_activeColorChooser) { 850 m_activeColorChooser->disconnectFromPage(); 851 m_activeColorChooser = 0; 852 } 853#endif 854 855 m_sandboxExtensionTracker.invalidate(); 856 857#if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC) 858 m_determinePrimarySnapshottedPlugInTimer.stop(); 859#endif 860 861#if ENABLE(CONTEXT_MENUS) 862 m_contextMenuClient.initialize(0); 863#endif 864 m_editorClient.initialize(0); 865 m_formClient.initialize(0); 866 m_loaderClient.initialize(0); 867 m_policyClient.initialize(0); 868 m_resourceLoadClient.initialize(0); 869 m_uiClient.initialize(0); 870#if ENABLE(FULLSCREEN_API) 871 m_fullScreenClient.initialize(0); 872#endif 873 m_logDiagnosticMessageClient.initialize(0); 874 875 m_underlayPage = nullptr; 876 m_printContext = nullptr; 877 m_mainFrame->coreFrame()->loader()->detachFromParent(); 878 m_page = nullptr; 879 m_drawingArea = nullptr; 880 881 bool isRunningModal = m_isRunningModal; 882 m_isRunningModal = false; 883 884 // The WebPage can be destroyed by this call. 885 WebProcess::shared().removeWebPage(m_pageID); 886 887 if (isRunningModal) 888 RunLoop::main()->stop(); 889} 890 891void WebPage::tryClose() 892{ 893 SendStopResponsivenessTimer stopper(this); 894 895 if (!m_mainFrame->coreFrame()->loader()->shouldClose()) { 896 send(Messages::WebPageProxy::StopResponsivenessTimer()); 897 return; 898 } 899 900 send(Messages::WebPageProxy::ClosePage(true)); 901} 902 903void WebPage::sendClose() 904{ 905 send(Messages::WebPageProxy::ClosePage(false)); 906} 907 908void WebPage::loadURL(const String& url, const SandboxExtension::Handle& sandboxExtensionHandle, CoreIPC::MessageDecoder& decoder) 909{ 910 loadURLRequest(ResourceRequest(KURL(KURL(), url)), sandboxExtensionHandle, decoder); 911} 912 913void WebPage::loadURLRequest(const ResourceRequest& request, const SandboxExtension::Handle& sandboxExtensionHandle, CoreIPC::MessageDecoder& decoder) 914{ 915 SendStopResponsivenessTimer stopper(this); 916 917 RefPtr<APIObject> userData; 918 InjectedBundleUserMessageDecoder userMessageDecoder(userData); 919 if (!decoder.decode(userMessageDecoder)) 920 return; 921 922 m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), sandboxExtensionHandle); 923 924 // Let the InjectedBundle know we are about to start the load, passing the user data from the UIProcess 925 // to all the client to set up any needed state. 926 m_loaderClient.willLoadURLRequest(this, request, userData.get()); 927 928 // Initate the load in WebCore. 929 m_mainFrame->coreFrame()->loader()->load(FrameLoadRequest(m_mainFrame->coreFrame(), request)); 930} 931 932void WebPage::loadDataImpl(PassRefPtr<SharedBuffer> sharedBuffer, const String& MIMEType, const String& encodingName, const KURL& baseURL, const KURL& unreachableURL, CoreIPC::MessageDecoder& decoder) 933{ 934 SendStopResponsivenessTimer stopper(this); 935 936 RefPtr<APIObject> userData; 937 InjectedBundleUserMessageDecoder userMessageDecoder(userData); 938 if (!decoder.decode(userMessageDecoder)) 939 return; 940 941 ResourceRequest request(baseURL); 942 SubstituteData substituteData(sharedBuffer, MIMEType, encodingName, unreachableURL); 943 944 // Let the InjectedBundle know we are about to start the load, passing the user data from the UIProcess 945 // to all the client to set up any needed state. 946 m_loaderClient.willLoadDataRequest(this, request, substituteData.content(), substituteData.mimeType(), substituteData.textEncoding(), substituteData.failingURL(), userData.get()); 947 948 // Initate the load in WebCore. 949 m_mainFrame->coreFrame()->loader()->load(FrameLoadRequest(m_mainFrame->coreFrame(), request, substituteData)); 950} 951 952void WebPage::loadData(const CoreIPC::DataReference& data, const String& MIMEType, const String& encodingName, const String& baseURLString, CoreIPC::MessageDecoder& decoder) 953{ 954 RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(data.data()), data.size()); 955 KURL baseURL = baseURLString.isEmpty() ? blankURL() : KURL(KURL(), baseURLString); 956 loadDataImpl(sharedBuffer, MIMEType, encodingName, baseURL, KURL(), decoder); 957} 958 959void WebPage::loadHTMLString(const String& htmlString, const String& baseURLString, CoreIPC::MessageDecoder& decoder) 960{ 961 RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(htmlString.characters()), htmlString.length() * sizeof(UChar)); 962 KURL baseURL = baseURLString.isEmpty() ? blankURL() : KURL(KURL(), baseURLString); 963 loadDataImpl(sharedBuffer, "text/html", "utf-16", baseURL, KURL(), decoder); 964} 965 966void WebPage::loadAlternateHTMLString(const String& htmlString, const String& baseURLString, const String& unreachableURLString, CoreIPC::MessageDecoder& decoder) 967{ 968 RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(htmlString.characters()), htmlString.length() * sizeof(UChar)); 969 KURL baseURL = baseURLString.isEmpty() ? blankURL() : KURL(KURL(), baseURLString); 970 KURL unreachableURL = unreachableURLString.isEmpty() ? KURL() : KURL(KURL(), unreachableURLString); 971 loadDataImpl(sharedBuffer, "text/html", "utf-16", baseURL, unreachableURL, decoder); 972} 973 974void WebPage::loadPlainTextString(const String& string, CoreIPC::MessageDecoder& decoder) 975{ 976 RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(string.characters()), string.length() * sizeof(UChar)); 977 loadDataImpl(sharedBuffer, "text/plain", "utf-16", blankURL(), KURL(), decoder); 978} 979 980void WebPage::loadWebArchiveData(const CoreIPC::DataReference& webArchiveData, CoreIPC::MessageDecoder& decoder) 981{ 982 RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(webArchiveData.data()), webArchiveData.size() * sizeof(uint8_t)); 983 loadDataImpl(sharedBuffer, "application/x-webarchive", "utf-16", blankURL(), KURL(), decoder); 984} 985 986void WebPage::linkClicked(const String& url, const WebMouseEvent& event) 987{ 988 Frame* frame = m_page->mainFrame(); 989 if (!frame) 990 return; 991 992 RefPtr<Event> coreEvent; 993 if (event.type() != WebEvent::NoType) 994 coreEvent = MouseEvent::create(eventNames().clickEvent, frame->document()->defaultView(), platform(event), 0, 0); 995 996 frame->loader()->loadFrameRequest(FrameLoadRequest(frame, ResourceRequest(url)), false, false, coreEvent.get(), 0, MaybeSendReferrer); 997} 998 999void WebPage::stopLoadingFrame(uint64_t frameID) 1000{ 1001 WebFrame* frame = WebProcess::shared().webFrame(frameID); 1002 if (!frame) 1003 return; 1004 1005 frame->coreFrame()->loader()->stopForUserCancel(); 1006} 1007 1008void WebPage::stopLoading() 1009{ 1010 SendStopResponsivenessTimer stopper(this); 1011 1012 m_mainFrame->coreFrame()->loader()->stopForUserCancel(); 1013} 1014 1015void WebPage::setDefersLoading(bool defersLoading) 1016{ 1017 m_page->setDefersLoading(defersLoading); 1018} 1019 1020void WebPage::reload(bool reloadFromOrigin, const SandboxExtension::Handle& sandboxExtensionHandle) 1021{ 1022 SendStopResponsivenessTimer stopper(this); 1023 1024 m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), sandboxExtensionHandle); 1025 m_mainFrame->coreFrame()->loader()->reload(reloadFromOrigin); 1026} 1027 1028void WebPage::goForward(uint64_t backForwardItemID) 1029{ 1030 SendStopResponsivenessTimer stopper(this); 1031 1032 HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID); 1033 ASSERT(item); 1034 if (!item) 1035 return; 1036 1037 m_page->goToItem(item, FrameLoadTypeForward); 1038} 1039 1040void WebPage::goBack(uint64_t backForwardItemID) 1041{ 1042 SendStopResponsivenessTimer stopper(this); 1043 1044 HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID); 1045 ASSERT(item); 1046 if (!item) 1047 return; 1048 1049 m_page->goToItem(item, FrameLoadTypeBack); 1050} 1051 1052void WebPage::goToBackForwardItem(uint64_t backForwardItemID) 1053{ 1054 SendStopResponsivenessTimer stopper(this); 1055 1056 HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID); 1057 ASSERT(item); 1058 if (!item) 1059 return; 1060 1061 m_page->goToItem(item, FrameLoadTypeIndexedBackForward); 1062} 1063 1064void WebPage::tryRestoreScrollPosition() 1065{ 1066 m_page->mainFrame()->loader()->history()->restoreScrollPositionAndViewState(); 1067} 1068 1069void WebPage::layoutIfNeeded() 1070{ 1071 if (m_mainFrame->coreFrame()->view()) 1072 m_mainFrame->coreFrame()->view()->updateLayoutAndStyleIfNeededRecursive(); 1073 1074 if (m_underlayPage) { 1075 if (FrameView *frameView = m_underlayPage->mainFrameView()) 1076 frameView->updateLayoutAndStyleIfNeededRecursive(); 1077 } 1078} 1079 1080WebPage* WebPage::fromCorePage(Page* page) 1081{ 1082 return static_cast<WebChromeClient*>(page->chrome().client())->page(); 1083} 1084 1085void WebPage::setSize(const WebCore::IntSize& viewSize) 1086{ 1087 FrameView* view = m_page->mainFrame()->view(); 1088 1089 if (m_viewSize == viewSize) 1090 return; 1091 1092 view->resize(viewSize); 1093 view->setNeedsLayout(); 1094 m_drawingArea->setNeedsDisplay(); 1095 1096 m_viewSize = viewSize; 1097 1098#if USE(TILED_BACKING_STORE) 1099 if (view->useFixedLayout()) 1100 sendViewportAttributesChanged(); 1101#endif 1102} 1103 1104#if USE(TILED_BACKING_STORE) 1105void WebPage::setFixedVisibleContentRect(const IntRect& rect) 1106{ 1107 ASSERT(m_useFixedLayout); 1108 1109 m_page->mainFrame()->view()->setFixedVisibleContentRect(rect); 1110} 1111 1112void WebPage::sendViewportAttributesChanged() 1113{ 1114 ASSERT(m_useFixedLayout); 1115 1116 // Viewport properties have no impact on zero sized fixed viewports. 1117 if (m_viewSize.isEmpty()) 1118 return; 1119 1120 // Recalculate the recommended layout size, when the available size (device pixel) changes. 1121 Settings* settings = m_page->settings(); 1122 1123 int minimumLayoutFallbackWidth = std::max(settings->layoutFallbackWidth(), m_viewSize.width()); 1124 1125 // If unset we use the viewport dimensions. This fits with the behavior of desktop browsers. 1126 int deviceWidth = (settings->deviceWidth() > 0) ? settings->deviceWidth() : m_viewSize.width(); 1127 int deviceHeight = (settings->deviceHeight() > 0) ? settings->deviceHeight() : m_viewSize.height(); 1128 1129 ViewportAttributes attr = computeViewportAttributes(m_page->viewportArguments(), minimumLayoutFallbackWidth, deviceWidth, deviceHeight, 1, m_viewSize); 1130 1131 FrameView* view = m_page->mainFrame()->view(); 1132 1133 // If no layout was done yet set contentFixedOrigin to (0,0). 1134 IntPoint contentFixedOrigin = view->didFirstLayout() ? view->fixedVisibleContentRect().location() : IntPoint(); 1135 1136 // Put the width and height to the viewport width and height. In css units however. 1137 // Use FloatSize to avoid truncated values during scale. 1138 FloatSize contentFixedSize = m_viewSize; 1139 1140#if ENABLE(CSS_DEVICE_ADAPTATION) 1141 // CSS viewport descriptors might be applied to already affected viewport size 1142 // if the page enables/disables stylesheets, so need to keep initial viewport size. 1143 view->setInitialViewportSize(roundedIntSize(contentFixedSize)); 1144#endif 1145 1146 contentFixedSize.scale(1 / attr.initialScale); 1147 setFixedVisibleContentRect(IntRect(contentFixedOrigin, roundedIntSize(contentFixedSize))); 1148 1149 attr.initialScale = m_page->viewportArguments().zoom; // Resets auto (-1) if no value was set by user. 1150 1151 // This also takes care of the relayout. 1152 setFixedLayoutSize(roundedIntSize(attr.layoutSize)); 1153 1154 send(Messages::WebPageProxy::DidChangeViewportProperties(attr)); 1155} 1156#endif 1157 1158void WebPage::scrollMainFrameIfNotAtMaxScrollPosition(const IntSize& scrollOffset) 1159{ 1160 Frame* frame = m_page->mainFrame(); 1161 1162 IntPoint scrollPosition = frame->view()->scrollPosition(); 1163 IntPoint maximumScrollPosition = frame->view()->maximumScrollPosition(); 1164 1165 // If the current scroll position in a direction is the max scroll position 1166 // we don't want to scroll at all. 1167 IntSize newScrollOffset; 1168 if (scrollPosition.x() < maximumScrollPosition.x()) 1169 newScrollOffset.setWidth(scrollOffset.width()); 1170 if (scrollPosition.y() < maximumScrollPosition.y()) 1171 newScrollOffset.setHeight(scrollOffset.height()); 1172 1173 if (newScrollOffset.isZero()) 1174 return; 1175 1176 frame->view()->setScrollPosition(frame->view()->scrollPosition() + newScrollOffset); 1177} 1178 1179void WebPage::drawRect(GraphicsContext& graphicsContext, const IntRect& rect) 1180{ 1181 GraphicsContextStateSaver stateSaver(graphicsContext); 1182 graphicsContext.clip(rect); 1183 1184 if (m_underlayPage) { 1185 m_underlayPage->drawRect(graphicsContext, rect); 1186 1187 graphicsContext.beginTransparencyLayer(1); 1188 m_mainFrame->coreFrame()->view()->paint(&graphicsContext, rect); 1189 graphicsContext.endTransparencyLayer(); 1190 return; 1191 } 1192 1193 m_mainFrame->coreFrame()->view()->paint(&graphicsContext, rect); 1194} 1195 1196void WebPage::drawPageOverlay(PageOverlay* pageOverlay, GraphicsContext& graphicsContext, const IntRect& rect) 1197{ 1198 ASSERT(pageOverlay); 1199 1200 GraphicsContextStateSaver stateSaver(graphicsContext); 1201 graphicsContext.clip(rect); 1202 pageOverlay->drawRect(graphicsContext, rect); 1203} 1204 1205double WebPage::textZoomFactor() const 1206{ 1207 Frame* frame = m_mainFrame->coreFrame(); 1208 if (!frame) 1209 return 1; 1210 return frame->textZoomFactor(); 1211} 1212 1213void WebPage::setTextZoomFactor(double zoomFactor) 1214{ 1215 PluginView* pluginView = pluginViewForFrame(m_page->mainFrame()); 1216 if (pluginView && pluginView->handlesPageScaleFactor()) 1217 return; 1218 1219 Frame* frame = m_mainFrame->coreFrame(); 1220 if (!frame) 1221 return; 1222 frame->setTextZoomFactor(static_cast<float>(zoomFactor)); 1223} 1224 1225double WebPage::pageZoomFactor() const 1226{ 1227 PluginView* pluginView = pluginViewForFrame(m_page->mainFrame()); 1228 if (pluginView && pluginView->handlesPageScaleFactor()) 1229 return pluginView->pageScaleFactor(); 1230 1231 Frame* frame = m_mainFrame->coreFrame(); 1232 if (!frame) 1233 return 1; 1234 return frame->pageZoomFactor(); 1235} 1236 1237void WebPage::setPageZoomFactor(double zoomFactor) 1238{ 1239 PluginView* pluginView = pluginViewForFrame(m_page->mainFrame()); 1240 if (pluginView && pluginView->handlesPageScaleFactor()) { 1241 pluginView->setPageScaleFactor(zoomFactor, IntPoint()); 1242 return; 1243 } 1244 1245 Frame* frame = m_mainFrame->coreFrame(); 1246 if (!frame) 1247 return; 1248 frame->setPageZoomFactor(static_cast<float>(zoomFactor)); 1249} 1250 1251void WebPage::setPageAndTextZoomFactors(double pageZoomFactor, double textZoomFactor) 1252{ 1253 PluginView* pluginView = pluginViewForFrame(m_page->mainFrame()); 1254 if (pluginView && pluginView->handlesPageScaleFactor()) { 1255 pluginView->setPageScaleFactor(pageZoomFactor, IntPoint()); 1256 return; 1257 } 1258 1259 Frame* frame = m_mainFrame->coreFrame(); 1260 if (!frame) 1261 return; 1262 return frame->setPageAndTextZoomFactors(static_cast<float>(pageZoomFactor), static_cast<float>(textZoomFactor)); 1263} 1264 1265void WebPage::windowScreenDidChange(uint64_t displayID) 1266{ 1267 m_page->windowScreenDidChange(static_cast<PlatformDisplayID>(displayID)); 1268} 1269 1270void WebPage::scalePage(double scale, const IntPoint& origin) 1271{ 1272 PluginView* pluginView = pluginViewForFrame(m_page->mainFrame()); 1273 if (pluginView && pluginView->handlesPageScaleFactor()) { 1274 pluginView->setPageScaleFactor(scale, origin); 1275 return; 1276 } 1277 1278 m_page->setPageScaleFactor(scale, origin); 1279 1280 for (HashSet<PluginView*>::const_iterator it = m_pluginViews.begin(), end = m_pluginViews.end(); it != end; ++it) 1281 (*it)->pageScaleFactorDidChange(); 1282 1283 if (m_drawingArea->layerTreeHost()) 1284 m_drawingArea->layerTreeHost()->deviceOrPageScaleFactorChanged(); 1285 1286 send(Messages::WebPageProxy::PageScaleFactorDidChange(scale)); 1287} 1288 1289double WebPage::pageScaleFactor() const 1290{ 1291 PluginView* pluginView = pluginViewForFrame(m_page->mainFrame()); 1292 if (pluginView && pluginView->handlesPageScaleFactor()) 1293 return pluginView->pageScaleFactor(); 1294 1295 return m_page->pageScaleFactor(); 1296} 1297 1298void WebPage::setDeviceScaleFactor(float scaleFactor) 1299{ 1300 if (scaleFactor == m_page->deviceScaleFactor()) 1301 return; 1302 1303 m_page->setDeviceScaleFactor(scaleFactor); 1304 1305 // Tell all our plug-in views that the device scale factor changed. 1306#if PLATFORM(MAC) 1307 for (HashSet<PluginView*>::const_iterator it = m_pluginViews.begin(), end = m_pluginViews.end(); it != end; ++it) 1308 (*it)->setDeviceScaleFactor(scaleFactor); 1309 1310 updateHeaderAndFooterLayersForDeviceScaleChange(scaleFactor); 1311#endif 1312 1313 if (m_findController.isShowingOverlay()) { 1314 // We must have updated layout to get the selection rects right. 1315 layoutIfNeeded(); 1316 m_findController.deviceScaleFactorDidChange(); 1317 } 1318 1319 if (m_drawingArea->layerTreeHost()) 1320 m_drawingArea->layerTreeHost()->deviceOrPageScaleFactorChanged(); 1321} 1322 1323float WebPage::deviceScaleFactor() const 1324{ 1325 return m_page->deviceScaleFactor(); 1326} 1327 1328void WebPage::setUseFixedLayout(bool fixed) 1329{ 1330 // Do not overwrite current settings if initially setting it to false. 1331 if (m_useFixedLayout == fixed) 1332 return; 1333 m_useFixedLayout = fixed; 1334 1335 m_page->settings()->setFixedElementsLayoutRelativeToFrame(fixed); 1336#if USE(COORDINATED_GRAPHICS) 1337 m_page->settings()->setAcceleratedCompositingForFixedPositionEnabled(fixed); 1338 m_page->settings()->setFixedPositionCreatesStackingContext(fixed); 1339 m_page->settings()->setApplyPageScaleFactorInCompositor(fixed); 1340 m_page->settings()->setScrollingCoordinatorEnabled(fixed); 1341#endif 1342 1343#if USE(TILED_BACKING_STORE) && ENABLE(SMOOTH_SCROLLING) 1344 // Delegated scrolling will be enabled when the FrameView is created if fixed layout is enabled. 1345 // Ensure we don't do animated scrolling in the WebProcess in that case. 1346 m_page->settings()->setScrollAnimatorEnabled(!fixed); 1347#endif 1348 1349 FrameView* view = mainFrameView(); 1350 if (!view) 1351 return; 1352 1353#if USE(TILED_BACKING_STORE) 1354 view->setDelegatesScrolling(fixed); 1355 view->setPaintsEntireContents(fixed); 1356#endif 1357 view->setUseFixedLayout(fixed); 1358 if (!fixed) 1359 setFixedLayoutSize(IntSize()); 1360} 1361 1362void WebPage::setFixedLayoutSize(const IntSize& size) 1363{ 1364 FrameView* view = mainFrameView(); 1365 if (!view || view->fixedLayoutSize() == size) 1366 return; 1367 1368 view->setFixedLayoutSize(size); 1369 // Do not force it until the first layout, this would then become our first layout prematurely. 1370 if (view->didFirstLayout()) 1371 view->forceLayout(); 1372} 1373 1374void WebPage::listenForLayoutMilestones(uint32_t milestones) 1375{ 1376 if (!m_page) 1377 return; 1378 m_page->addLayoutMilestones(static_cast<LayoutMilestones>(milestones)); 1379} 1380 1381void WebPage::setSuppressScrollbarAnimations(bool suppressAnimations) 1382{ 1383 m_page->setShouldSuppressScrollbarAnimations(suppressAnimations); 1384} 1385 1386void WebPage::setRubberBandsAtBottom(bool rubberBandsAtBottom) 1387{ 1388 m_page->setRubberBandsAtBottom(rubberBandsAtBottom); 1389} 1390 1391void WebPage::setRubberBandsAtTop(bool rubberBandsAtTop) 1392{ 1393 m_page->setRubberBandsAtTop(rubberBandsAtTop); 1394} 1395 1396void WebPage::setPaginationMode(uint32_t mode) 1397{ 1398 Pagination pagination = m_page->pagination(); 1399 pagination.mode = static_cast<Pagination::Mode>(mode); 1400 m_page->setPagination(pagination); 1401} 1402 1403void WebPage::setPaginationBehavesLikeColumns(bool behavesLikeColumns) 1404{ 1405 Pagination pagination = m_page->pagination(); 1406 pagination.behavesLikeColumns = behavesLikeColumns; 1407 m_page->setPagination(pagination); 1408} 1409 1410void WebPage::setPageLength(double pageLength) 1411{ 1412 Pagination pagination = m_page->pagination(); 1413 pagination.pageLength = pageLength; 1414 m_page->setPagination(pagination); 1415} 1416 1417void WebPage::setGapBetweenPages(double gap) 1418{ 1419 Pagination pagination = m_page->pagination(); 1420 pagination.gap = gap; 1421 m_page->setPagination(pagination); 1422} 1423 1424void WebPage::postInjectedBundleMessage(const String& messageName, CoreIPC::MessageDecoder& decoder) 1425{ 1426 InjectedBundle* injectedBundle = WebProcess::shared().injectedBundle(); 1427 if (!injectedBundle) 1428 return; 1429 1430 RefPtr<APIObject> messageBody; 1431 InjectedBundleUserMessageDecoder messageBodyDecoder(messageBody); 1432 if (!decoder.decode(messageBodyDecoder)) 1433 return; 1434 1435 injectedBundle->didReceiveMessageToPage(this, messageName, messageBody.get()); 1436} 1437 1438void WebPage::installPageOverlay(PassRefPtr<PageOverlay> pageOverlay, bool shouldFadeIn) 1439{ 1440 RefPtr<PageOverlay> overlay = pageOverlay; 1441 1442 if (m_pageOverlays.contains(overlay.get())) 1443 return; 1444 1445 m_pageOverlays.append(overlay); 1446 overlay->setPage(this); 1447 1448 if (shouldFadeIn) 1449 overlay->startFadeInAnimation(); 1450 1451 m_drawingArea->didInstallPageOverlay(overlay.get()); 1452} 1453 1454void WebPage::uninstallPageOverlay(PageOverlay* pageOverlay, bool shouldFadeOut) 1455{ 1456 size_t existingOverlayIndex = m_pageOverlays.find(pageOverlay); 1457 if (existingOverlayIndex == notFound) 1458 return; 1459 1460 if (shouldFadeOut) { 1461 pageOverlay->startFadeOutAnimation(); 1462 return; 1463 } 1464 1465 pageOverlay->setPage(0); 1466 m_pageOverlays.remove(existingOverlayIndex); 1467 1468 m_drawingArea->didUninstallPageOverlay(pageOverlay); 1469} 1470 1471void WebPage::setHeaderPageBanner(PassRefPtr<PageBanner> pageBanner) 1472{ 1473 if (m_headerBanner) 1474 m_headerBanner->detachFromPage(); 1475 1476 m_headerBanner = pageBanner; 1477 1478 if (m_headerBanner) 1479 m_headerBanner->addToPage(PageBanner::Header, this); 1480} 1481 1482PageBanner* WebPage::headerPageBanner() 1483{ 1484 return m_headerBanner.get(); 1485} 1486 1487void WebPage::setFooterPageBanner(PassRefPtr<PageBanner> pageBanner) 1488{ 1489 if (m_footerBanner) 1490 m_footerBanner->detachFromPage(); 1491 1492 m_footerBanner = pageBanner; 1493 1494 if (m_footerBanner) 1495 m_footerBanner->addToPage(PageBanner::Footer, this); 1496} 1497 1498PageBanner* WebPage::footerPageBanner() 1499{ 1500 return m_footerBanner.get(); 1501} 1502 1503void WebPage::hidePageBanners() 1504{ 1505 if (m_headerBanner) 1506 m_headerBanner->hide(); 1507 if (m_footerBanner) 1508 m_footerBanner->hide(); 1509} 1510 1511void WebPage::showPageBanners() 1512{ 1513 if (m_headerBanner) 1514 m_headerBanner->showIfHidden(); 1515 if (m_footerBanner) 1516 m_footerBanner->showIfHidden(); 1517} 1518 1519PassRefPtr<WebImage> WebPage::scaledSnapshotWithOptions(const IntRect& rect, double scaleFactor, SnapshotOptions options) 1520{ 1521 Frame* coreFrame = m_mainFrame->coreFrame(); 1522 if (!coreFrame) 1523 return 0; 1524 1525 FrameView* frameView = coreFrame->view(); 1526 if (!frameView) 1527 return 0; 1528 1529 IntSize bitmapSize = rect.size(); 1530 float combinedScaleFactor = scaleFactor * corePage()->deviceScaleFactor(); 1531 bitmapSize.scale(combinedScaleFactor); 1532 1533 RefPtr<WebImage> snapshot = WebImage::create(bitmapSize, snapshotOptionsToImageOptions(options)); 1534 if (!snapshot->bitmap()) 1535 return 0; 1536 1537 OwnPtr<WebCore::GraphicsContext> graphicsContext = snapshot->bitmap()->createGraphicsContext(); 1538 1539 graphicsContext->clearRect(IntRect(IntPoint(), bitmapSize)); 1540 1541 graphicsContext->applyDeviceScaleFactor(combinedScaleFactor); 1542 graphicsContext->translate(-rect.x(), -rect.y()); 1543 1544 FrameView::SelectionInSnaphot shouldPaintSelection = FrameView::IncludeSelection; 1545 if (options & SnapshotOptionsExcludeSelectionHighlighting) 1546 shouldPaintSelection = FrameView::ExcludeSelection; 1547 1548 FrameView::CoordinateSpaceForSnapshot coordinateSpace = FrameView::DocumentCoordinates; 1549 if (options & SnapshotOptionsInViewCoordinates) 1550 coordinateSpace = FrameView::ViewCoordinates; 1551 1552 frameView->paintContentsForSnapshot(graphicsContext.get(), rect, shouldPaintSelection, coordinateSpace); 1553 1554 if (options & SnapshotOptionsPaintSelectionRectangle) { 1555 FloatRect selectionRectangle = m_mainFrame->coreFrame()->selection()->bounds(); 1556 graphicsContext->setStrokeColor(Color(0xFF, 0, 0), ColorSpaceDeviceRGB); 1557 graphicsContext->strokeRect(selectionRectangle, 1); 1558 } 1559 1560 return snapshot.release(); 1561} 1562 1563void WebPage::pageDidScroll() 1564{ 1565 m_uiClient.pageDidScroll(this); 1566 1567 send(Messages::WebPageProxy::PageDidScroll()); 1568} 1569 1570#if USE(TILED_BACKING_STORE) 1571void WebPage::pageDidRequestScroll(const IntPoint& point) 1572{ 1573 send(Messages::WebPageProxy::PageDidRequestScroll(point)); 1574} 1575#endif 1576 1577#if ENABLE(CONTEXT_MENUS) 1578WebContextMenu* WebPage::contextMenu() 1579{ 1580 if (!m_contextMenu) 1581 m_contextMenu = WebContextMenu::create(this); 1582 return m_contextMenu.get(); 1583} 1584 1585WebContextMenu* WebPage::contextMenuAtPointInWindow(const IntPoint& point) 1586{ 1587 corePage()->contextMenuController()->clearContextMenu(); 1588 1589 // Simulate a mouse click to generate the correct menu. 1590 PlatformMouseEvent mouseEvent(point, point, RightButton, PlatformEvent::MousePressed, 1, false, false, false, false, currentTime()); 1591 bool handled = corePage()->mainFrame()->eventHandler()->sendContextMenuEvent(mouseEvent); 1592 if (!handled) 1593 return 0; 1594 1595 return contextMenu(); 1596} 1597#endif 1598 1599// Events 1600 1601static const WebEvent* g_currentEvent = 0; 1602 1603// FIXME: WebPage::currentEvent is used by the plug-in code to avoid having to convert from DOM events back to 1604// WebEvents. When we get the event handling sorted out, this should go away and the Widgets should get the correct 1605// platform events passed to the event handler code. 1606const WebEvent* WebPage::currentEvent() 1607{ 1608 return g_currentEvent; 1609} 1610 1611class CurrentEvent { 1612public: 1613 explicit CurrentEvent(const WebEvent& event) 1614 : m_previousCurrentEvent(g_currentEvent) 1615 { 1616 g_currentEvent = &event; 1617 } 1618 1619 ~CurrentEvent() 1620 { 1621 g_currentEvent = m_previousCurrentEvent; 1622 } 1623 1624private: 1625 const WebEvent* m_previousCurrentEvent; 1626}; 1627 1628#if ENABLE(CONTEXT_MENUS) 1629static bool isContextClick(const PlatformMouseEvent& event) 1630{ 1631 if (event.button() == WebCore::RightButton) 1632 return true; 1633 1634#if PLATFORM(MAC) 1635 // FIXME: this really should be about OSX-style UI, not about the Mac port 1636 if (event.button() == WebCore::LeftButton && event.ctrlKey()) 1637 return true; 1638#endif 1639 1640 return false; 1641} 1642 1643static bool handleContextMenuEvent(const PlatformMouseEvent& platformMouseEvent, WebPage* page) 1644{ 1645 IntPoint point = page->corePage()->mainFrame()->view()->windowToContents(platformMouseEvent.position()); 1646 HitTestResult result = page->corePage()->mainFrame()->eventHandler()->hitTestResultAtPoint(point); 1647 1648 Frame* frame = page->corePage()->mainFrame(); 1649 if (result.innerNonSharedNode()) 1650 frame = result.innerNonSharedNode()->document()->frame(); 1651 1652 bool handled = frame->eventHandler()->sendContextMenuEvent(platformMouseEvent); 1653 if (handled) 1654 page->contextMenu()->show(); 1655 1656 return handled; 1657} 1658#endif 1659 1660static bool handleMouseEvent(const WebMouseEvent& mouseEvent, WebPage* page, bool onlyUpdateScrollbars) 1661{ 1662 Frame* frame = page->corePage()->mainFrame(); 1663 if (!frame->view()) 1664 return false; 1665 1666 PlatformMouseEvent platformMouseEvent = platform(mouseEvent); 1667 1668 switch (platformMouseEvent.type()) { 1669 case PlatformEvent::MousePressed: { 1670#if ENABLE(CONTEXT_MENUS) 1671 if (isContextClick(platformMouseEvent)) 1672 page->corePage()->contextMenuController()->clearContextMenu(); 1673#endif 1674 1675 bool handled = frame->eventHandler()->handleMousePressEvent(platformMouseEvent); 1676#if ENABLE(CONTEXT_MENUS) 1677 if (isContextClick(platformMouseEvent)) 1678 handled = handleContextMenuEvent(platformMouseEvent, page); 1679#endif 1680 return handled; 1681 } 1682 case PlatformEvent::MouseReleased: 1683 return frame->eventHandler()->handleMouseReleaseEvent(platformMouseEvent); 1684 1685 case PlatformEvent::MouseMoved: 1686 if (onlyUpdateScrollbars) 1687 return frame->eventHandler()->passMouseMovedEventToScrollbars(platformMouseEvent); 1688 return frame->eventHandler()->mouseMoved(platformMouseEvent); 1689 default: 1690 ASSERT_NOT_REACHED(); 1691 return false; 1692 } 1693} 1694 1695void WebPage::mouseEvent(const WebMouseEvent& mouseEvent) 1696{ 1697#if ENABLE(CONTEXT_MENUS) 1698 // Don't try to handle any pending mouse events if a context menu is showing. 1699 if (m_isShowingContextMenu) { 1700 send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(mouseEvent.type()), false)); 1701 return; 1702 } 1703#endif 1704 bool handled = false; 1705 if (m_pageOverlays.size()) { 1706 // Let the page overlay handle the event. 1707 PageOverlayList::reverse_iterator end = m_pageOverlays.rend(); 1708 for (PageOverlayList::reverse_iterator it = m_pageOverlays.rbegin(); it != end; ++it) 1709 if ((handled = (*it)->mouseEvent(mouseEvent))) 1710 break; 1711 } 1712 1713 if (!handled && m_headerBanner) 1714 handled = m_headerBanner->mouseEvent(mouseEvent); 1715 if (!handled && m_footerBanner) 1716 handled = m_footerBanner->mouseEvent(mouseEvent); 1717 1718 if (!handled && canHandleUserEvents()) { 1719 CurrentEvent currentEvent(mouseEvent); 1720 1721 // We need to do a full, normal hit test during this mouse event if the page is active or if a mouse 1722 // button is currently pressed. It is possible that neither of those things will be true since on 1723 // Lion when legacy scrollbars are enabled, WebKit receives mouse events all the time. If it is one 1724 // of those cases where the page is not active and the mouse is not pressed, then we can fire a more 1725 // efficient scrollbars-only version of the event. 1726 bool onlyUpdateScrollbars = !(m_page->focusController()->isActive() || (mouseEvent.button() != WebMouseEvent::NoButton)); 1727 handled = handleMouseEvent(mouseEvent, this, onlyUpdateScrollbars); 1728 } 1729 1730 send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(mouseEvent.type()), handled)); 1731} 1732 1733void WebPage::mouseEventSyncForTesting(const WebMouseEvent& mouseEvent, bool& handled) 1734{ 1735 handled = false; 1736 1737 if (m_pageOverlays.size()) { 1738 PageOverlayList::reverse_iterator end = m_pageOverlays.rend(); 1739 for (PageOverlayList::reverse_iterator it = m_pageOverlays.rbegin(); it != end; ++it) 1740 if ((handled = (*it)->mouseEvent(mouseEvent))) 1741 break; 1742 } 1743 if (!handled && m_headerBanner) 1744 handled = m_headerBanner->mouseEvent(mouseEvent); 1745 if (!handled && m_footerBanner) 1746 handled = m_footerBanner->mouseEvent(mouseEvent); 1747 1748 if (!handled) { 1749 CurrentEvent currentEvent(mouseEvent); 1750 1751 // We need to do a full, normal hit test during this mouse event if the page is active or if a mouse 1752 // button is currently pressed. It is possible that neither of those things will be true since on 1753 // Lion when legacy scrollbars are enabled, WebKit receives mouse events all the time. If it is one 1754 // of those cases where the page is not active and the mouse is not pressed, then we can fire a more 1755 // efficient scrollbars-only version of the event. 1756 bool onlyUpdateScrollbars = !(m_page->focusController()->isActive() || (mouseEvent.button() != WebMouseEvent::NoButton)); 1757 handled = handleMouseEvent(mouseEvent, this, onlyUpdateScrollbars); 1758 } 1759} 1760 1761static bool handleWheelEvent(const WebWheelEvent& wheelEvent, Page* page) 1762{ 1763 Frame* frame = page->mainFrame(); 1764 if (!frame->view()) 1765 return false; 1766 1767 PlatformWheelEvent platformWheelEvent = platform(wheelEvent); 1768 return frame->eventHandler()->handleWheelEvent(platformWheelEvent); 1769} 1770 1771void WebPage::wheelEvent(const WebWheelEvent& wheelEvent) 1772{ 1773 bool handled = false; 1774 1775 if (canHandleUserEvents()) { 1776 CurrentEvent currentEvent(wheelEvent); 1777 1778 handled = handleWheelEvent(wheelEvent, m_page.get()); 1779 } 1780 send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(wheelEvent.type()), handled)); 1781} 1782 1783void WebPage::wheelEventSyncForTesting(const WebWheelEvent& wheelEvent, bool& handled) 1784{ 1785 CurrentEvent currentEvent(wheelEvent); 1786 1787 handled = handleWheelEvent(wheelEvent, m_page.get()); 1788} 1789 1790static bool handleKeyEvent(const WebKeyboardEvent& keyboardEvent, Page* page) 1791{ 1792 if (!page->mainFrame()->view()) 1793 return false; 1794 1795 if (keyboardEvent.type() == WebEvent::Char && keyboardEvent.isSystemKey()) 1796 return page->focusController()->focusedOrMainFrame()->eventHandler()->handleAccessKey(platform(keyboardEvent)); 1797 return page->focusController()->focusedOrMainFrame()->eventHandler()->keyEvent(platform(keyboardEvent)); 1798} 1799 1800void WebPage::keyEvent(const WebKeyboardEvent& keyboardEvent) 1801{ 1802 bool handled = false; 1803 1804 if (canHandleUserEvents()) { 1805 CurrentEvent currentEvent(keyboardEvent); 1806 1807 handled = handleKeyEvent(keyboardEvent, m_page.get()); 1808 // FIXME: Platform default behaviors should be performed during normal DOM event dispatch (in most cases, in default keydown event handler). 1809 if (!handled) 1810 handled = performDefaultBehaviorForKeyEvent(keyboardEvent); 1811 } 1812 send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(keyboardEvent.type()), handled)); 1813} 1814 1815void WebPage::keyEventSyncForTesting(const WebKeyboardEvent& keyboardEvent, bool& handled) 1816{ 1817 CurrentEvent currentEvent(keyboardEvent); 1818 1819 handled = handleKeyEvent(keyboardEvent, m_page.get()); 1820 if (!handled) 1821 handled = performDefaultBehaviorForKeyEvent(keyboardEvent); 1822} 1823 1824#if ENABLE(GESTURE_EVENTS) 1825static bool handleGestureEvent(const WebGestureEvent& gestureEvent, Page* page) 1826{ 1827 Frame* frame = page->mainFrame(); 1828 if (!frame->view()) 1829 return false; 1830 1831 PlatformGestureEvent platformGestureEvent = platform(gestureEvent); 1832 return frame->eventHandler()->handleGestureEvent(platformGestureEvent); 1833} 1834 1835void WebPage::gestureEvent(const WebGestureEvent& gestureEvent) 1836{ 1837 bool handled = false; 1838 1839 if (canHandleUserEvents()) { 1840 CurrentEvent currentEvent(gestureEvent); 1841 1842 handled = handleGestureEvent(gestureEvent, m_page.get()); 1843 } 1844 send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(gestureEvent.type()), handled)); 1845} 1846#endif 1847 1848WKTypeRef WebPage::pageOverlayCopyAccessibilityAttributeValue(WKStringRef attribute, WKTypeRef parameter) 1849{ 1850 if (!m_pageOverlays.size()) 1851 return 0; 1852 PageOverlayList::reverse_iterator end = m_pageOverlays.rend(); 1853 for (PageOverlayList::reverse_iterator it = m_pageOverlays.rbegin(); it != end; ++it) { 1854 WKTypeRef value = (*it)->copyAccessibilityAttributeValue(attribute, parameter); 1855 if (value) 1856 return value; 1857 } 1858 return 0; 1859} 1860 1861WKArrayRef WebPage::pageOverlayCopyAccessibilityAttributesNames(bool parameterizedNames) 1862{ 1863 if (!m_pageOverlays.size()) 1864 return 0; 1865 PageOverlayList::reverse_iterator end = m_pageOverlays.rend(); 1866 for (PageOverlayList::reverse_iterator it = m_pageOverlays.rbegin(); it != end; ++it) { 1867 WKArrayRef value = (*it)->copyAccessibilityAttributeNames(parameterizedNames); 1868 if (value) 1869 return value; 1870 } 1871 return 0; 1872} 1873 1874void WebPage::validateCommand(const String& commandName, uint64_t callbackID) 1875{ 1876 bool isEnabled = false; 1877 int32_t state = 0; 1878 Frame* frame = m_page->focusController()->focusedOrMainFrame(); 1879 if (frame) { 1880 if (PluginView* pluginView = focusedPluginViewForFrame(frame)) 1881 isEnabled = pluginView->isEditingCommandEnabled(commandName); 1882 else { 1883 Editor::Command command = frame->editor().command(commandName); 1884 state = command.state(); 1885 isEnabled = command.isSupported() && command.isEnabled(); 1886 } 1887 } 1888 1889 send(Messages::WebPageProxy::ValidateCommandCallback(commandName, isEnabled, state, callbackID)); 1890} 1891 1892void WebPage::executeEditCommand(const String& commandName) 1893{ 1894 executeEditingCommand(commandName, String()); 1895} 1896 1897uint64_t WebPage::restoreSession(const SessionState& sessionState) 1898{ 1899 const BackForwardListItemVector& list = sessionState.list(); 1900 size_t size = list.size(); 1901 uint64_t currentItemID = 0; 1902 for (size_t i = 0; i < size; ++i) { 1903 WebBackForwardListItem* webItem = list[i].get(); 1904 DecoderAdapter decoder(webItem->backForwardData().data(), webItem->backForwardData().size()); 1905 1906 RefPtr<HistoryItem> item = HistoryItem::decodeBackForwardTree(webItem->url(), webItem->title(), webItem->originalURL(), decoder); 1907 if (!item) { 1908 LOG_ERROR("Failed to decode a HistoryItem from session state data."); 1909 return 0; 1910 } 1911 1912 if (i == sessionState.currentIndex()) 1913 currentItemID = webItem->itemID(); 1914 1915 WebBackForwardListProxy::addItemFromUIProcess(list[i]->itemID(), item.release()); 1916 } 1917 ASSERT(currentItemID); 1918 return currentItemID; 1919} 1920 1921void WebPage::restoreSessionAndNavigateToCurrentItem(const SessionState& sessionState) 1922{ 1923 if (uint64_t currentItemID = restoreSession(sessionState)) 1924 goToBackForwardItem(currentItemID); 1925} 1926 1927#if ENABLE(TOUCH_EVENTS) 1928#if PLATFORM(QT) 1929void WebPage::highlightPotentialActivation(const IntPoint& point, const IntSize& area) 1930{ 1931 if (point == IntPoint::zero()) { 1932 // An empty point deactivates the highlighting. 1933 tapHighlightController().hideHighlight(); 1934 } else { 1935 Frame* mainframe = m_page->mainFrame(); 1936 Node* activationNode = 0; 1937 Node* adjustedNode = 0; 1938 IntPoint adjustedPoint; 1939 1940#if ENABLE(TOUCH_ADJUSTMENT) 1941 if (!mainframe->eventHandler()->bestClickableNodeForTouchPoint(point, IntSize(area.width() / 2, area.height() / 2), adjustedPoint, adjustedNode)) 1942 return; 1943 1944#else 1945 HitTestResult result = mainframe->eventHandler()->hitTestResultAtPoint(mainframe->view()->windowToContents(point), HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::IgnoreClipping | HitTestRequest::DisallowShadowContent); 1946 adjustedNode = result.innerNode(); 1947#endif 1948 // Find the node to highlight. This is not the same as the node responding the tap gesture, because many 1949 // pages has a global click handler and we do not want to highlight the body. 1950 for (Node* node = adjustedNode; node; node = node->parentOrShadowHostNode()) { 1951 if (node->isDocumentNode() || node->isFrameOwnerElement()) 1952 break; 1953 1954 // We always highlight focusable (form-elements), image links or content-editable elements. 1955 if ((node->isElementNode() && toElement(node)->isMouseFocusable()) || node->isLink() || node->isContentEditable()) 1956 activationNode = node; 1957 else if (node->willRespondToMouseClickEvents()) { 1958 // Highlight elements with default mouse-click handlers, but highlight only inline elements with 1959 // scripted event-handlers. 1960 if (!node->Node::willRespondToMouseClickEvents() || (node->renderer() && node->renderer()->isInline())) 1961 activationNode = node; 1962 } 1963 1964 if (activationNode) 1965 break; 1966 } 1967 1968 if (activationNode) 1969 tapHighlightController().highlight(activationNode); 1970 } 1971} 1972#endif 1973 1974static bool handleTouchEvent(const WebTouchEvent& touchEvent, Page* page) 1975{ 1976 Frame* frame = page->mainFrame(); 1977 if (!frame->view()) 1978 return false; 1979 1980 return frame->eventHandler()->handleTouchEvent(platform(touchEvent)); 1981} 1982 1983void WebPage::touchEvent(const WebTouchEvent& touchEvent) 1984{ 1985 bool handled = false; 1986 1987 if (canHandleUserEvents()) { 1988 CurrentEvent currentEvent(touchEvent); 1989 1990 handled = handleTouchEvent(touchEvent, m_page.get()); 1991 } 1992 send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(touchEvent.type()), handled)); 1993} 1994 1995void WebPage::touchEventSyncForTesting(const WebTouchEvent& touchEvent, bool& handled) 1996{ 1997 CurrentEvent currentEvent(touchEvent); 1998 handled = handleTouchEvent(touchEvent, m_page.get()); 1999} 2000#endif 2001 2002bool WebPage::scroll(Page* page, ScrollDirection direction, ScrollGranularity granularity) 2003{ 2004 return page->focusController()->focusedOrMainFrame()->eventHandler()->scrollRecursively(direction, granularity); 2005} 2006 2007bool WebPage::logicalScroll(Page* page, ScrollLogicalDirection direction, ScrollGranularity granularity) 2008{ 2009 return page->focusController()->focusedOrMainFrame()->eventHandler()->logicalScrollRecursively(direction, granularity); 2010} 2011 2012bool WebPage::scrollBy(uint32_t scrollDirection, uint32_t scrollGranularity) 2013{ 2014 return scroll(m_page.get(), static_cast<ScrollDirection>(scrollDirection), static_cast<ScrollGranularity>(scrollGranularity)); 2015} 2016 2017void WebPage::centerSelectionInVisibleArea() 2018{ 2019 Frame* frame = m_page->focusController()->focusedOrMainFrame(); 2020 if (!frame) 2021 return; 2022 2023 frame->selection()->revealSelection(ScrollAlignment::alignCenterAlways); 2024 m_findController.showFindIndicatorInSelection(); 2025} 2026 2027void WebPage::setActive(bool isActive) 2028{ 2029 m_page->focusController()->setActive(isActive); 2030 2031#if PLATFORM(MAC) 2032 // Tell all our plug-in views that the window focus changed. 2033 for (HashSet<PluginView*>::const_iterator it = m_pluginViews.begin(), end = m_pluginViews.end(); it != end; ++it) 2034 (*it)->setWindowIsFocused(isActive); 2035#endif 2036} 2037 2038void WebPage::setDrawsBackground(bool drawsBackground) 2039{ 2040 if (m_drawsBackground == drawsBackground) 2041 return; 2042 2043 m_drawsBackground = drawsBackground; 2044 2045 for (Frame* coreFrame = m_mainFrame->coreFrame(); coreFrame; coreFrame = coreFrame->tree()->traverseNext()) { 2046 if (FrameView* view = coreFrame->view()) 2047 view->setTransparent(!drawsBackground); 2048 } 2049 2050 m_drawingArea->pageBackgroundTransparencyChanged(); 2051 m_drawingArea->setNeedsDisplay(); 2052} 2053 2054void WebPage::setDrawsTransparentBackground(bool drawsTransparentBackground) 2055{ 2056 if (m_drawsTransparentBackground == drawsTransparentBackground) 2057 return; 2058 2059 m_drawsTransparentBackground = drawsTransparentBackground; 2060 2061 Color backgroundColor = drawsTransparentBackground ? Color::transparent : Color::white; 2062 for (Frame* coreFrame = m_mainFrame->coreFrame(); coreFrame; coreFrame = coreFrame->tree()->traverseNext()) { 2063 if (FrameView* view = coreFrame->view()) 2064 view->setBaseBackgroundColor(backgroundColor); 2065 } 2066 2067 m_drawingArea->pageBackgroundTransparencyChanged(); 2068 m_drawingArea->setNeedsDisplay(); 2069} 2070 2071void WebPage::viewWillStartLiveResize() 2072{ 2073 if (!m_page) 2074 return; 2075 2076 // FIXME: This should propagate to all ScrollableAreas. 2077 if (Frame* frame = m_page->focusController()->focusedOrMainFrame()) { 2078 if (FrameView* view = frame->view()) 2079 view->willStartLiveResize(); 2080 } 2081} 2082 2083void WebPage::viewWillEndLiveResize() 2084{ 2085 if (!m_page) 2086 return; 2087 2088 // FIXME: This should propagate to all ScrollableAreas. 2089 if (Frame* frame = m_page->focusController()->focusedOrMainFrame()) { 2090 if (FrameView* view = frame->view()) 2091 view->willEndLiveResize(); 2092 } 2093} 2094 2095void WebPage::setFocused(bool isFocused) 2096{ 2097 m_page->focusController()->setFocused(isFocused); 2098} 2099 2100void WebPage::setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent& event) 2101{ 2102 if (!m_page || !m_page->focusController()) 2103 return; 2104 2105 Frame* frame = m_page->focusController()->focusedOrMainFrame(); 2106 frame->document()->setFocusedElement(0); 2107 2108 if (isKeyboardEventValid && event.type() == WebEvent::KeyDown) { 2109 PlatformKeyboardEvent platformEvent(platform(event)); 2110 platformEvent.disambiguateKeyDownEvent(PlatformEvent::RawKeyDown); 2111 m_page->focusController()->setInitialFocus(forward ? FocusDirectionForward : FocusDirectionBackward, KeyboardEvent::create(platformEvent, frame->document()->defaultView()).get()); 2112 return; 2113 } 2114 2115 m_page->focusController()->setInitialFocus(forward ? FocusDirectionForward : FocusDirectionBackward, 0); 2116} 2117 2118void WebPage::setWindowResizerSize(const IntSize& windowResizerSize) 2119{ 2120 if (m_windowResizerSize == windowResizerSize) 2121 return; 2122 2123 m_windowResizerSize = windowResizerSize; 2124 2125 for (Frame* coreFrame = m_mainFrame->coreFrame(); coreFrame; coreFrame = coreFrame->tree()->traverseNext()) { 2126 FrameView* view = coreFrame->view(); 2127 if (view) 2128 view->windowResizerRectChanged(); 2129 } 2130} 2131 2132void WebPage::setCanStartMediaTimerFired() 2133{ 2134 if (m_page) 2135 m_page->setCanStartMedia(true); 2136} 2137 2138#if !PLATFORM(MAC) 2139void WebPage::didUpdateInWindowStateTimerFired() 2140{ 2141 send(Messages::WebPageProxy::DidUpdateInWindowState()); 2142} 2143#endif 2144 2145inline bool WebPage::canHandleUserEvents() const 2146{ 2147#if USE(TILED_BACKING_STORE) 2148 // Should apply only if the area was frozen by didStartPageTransition(). 2149 return !m_drawingArea->layerTreeStateIsFrozen(); 2150#endif 2151 return true; 2152} 2153 2154void WebPage::setIsInWindow(bool isInWindow, bool wantsDidUpdateViewInWindowState) 2155{ 2156 bool pageWasInWindow = m_page->isInWindow(); 2157 2158 if (!isInWindow) { 2159 m_setCanStartMediaTimer.stop(); 2160 m_page->setCanStartMedia(false); 2161 m_page->willMoveOffscreen(); 2162 2163 if (pageWasInWindow) 2164 WebProcess::shared().pageWillLeaveWindow(m_pageID); 2165 } else { 2166 // Defer the call to Page::setCanStartMedia() since it ends up sending a synchronous message to the UI process 2167 // in order to get plug-in connections, and the UI process will be waiting for the Web process to update the backing 2168 // store after moving the view into a window, until it times out and paints white. See <rdar://problem/9242771>. 2169 if (m_mayStartMediaWhenInWindow) 2170 m_setCanStartMediaTimer.startOneShot(0); 2171 2172 m_page->didMoveOnscreen(); 2173 2174 if (!pageWasInWindow) 2175 WebProcess::shared().pageDidEnterWindow(m_pageID); 2176 } 2177 2178 m_page->setIsInWindow(isInWindow); 2179 2180 if (wantsDidUpdateViewInWindowState) 2181 m_sendDidUpdateInWindowStateTimer.startOneShot(0); 2182} 2183 2184void WebPage::didReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, uint32_t policyAction, uint64_t downloadID) 2185{ 2186 WebFrame* frame = WebProcess::shared().webFrame(frameID); 2187 if (!frame) 2188 return; 2189 frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), downloadID); 2190} 2191 2192void WebPage::didStartPageTransition() 2193{ 2194 m_drawingArea->setLayerTreeStateIsFrozen(true); 2195} 2196 2197void WebPage::didCompletePageTransition() 2198{ 2199#if USE(TILED_BACKING_STORE) 2200 if (m_mainFrame->coreFrame()->view()->delegatesScrolling()) 2201 // Wait until the UI process sent us the visible rect it wants rendered. 2202 send(Messages::WebPageProxy::PageTransitionViewportReady()); 2203 else 2204#endif 2205 2206 m_drawingArea->setLayerTreeStateIsFrozen(false); 2207} 2208 2209void WebPage::show() 2210{ 2211 send(Messages::WebPageProxy::ShowPage()); 2212} 2213 2214void WebPage::setUserAgent(const String& userAgent) 2215{ 2216 m_userAgent = userAgent; 2217} 2218 2219void WebPage::suspendActiveDOMObjectsAndAnimations() 2220{ 2221 m_page->suspendActiveDOMObjectsAndAnimations(); 2222} 2223 2224void WebPage::resumeActiveDOMObjectsAndAnimations() 2225{ 2226 m_page->resumeActiveDOMObjectsAndAnimations(); 2227} 2228 2229IntPoint WebPage::screenToWindow(const IntPoint& point) 2230{ 2231 IntPoint windowPoint; 2232 sendSync(Messages::WebPageProxy::ScreenToWindow(point), Messages::WebPageProxy::ScreenToWindow::Reply(windowPoint)); 2233 return windowPoint; 2234} 2235 2236IntRect WebPage::windowToScreen(const IntRect& rect) 2237{ 2238 IntRect screenRect; 2239 sendSync(Messages::WebPageProxy::WindowToScreen(rect), Messages::WebPageProxy::WindowToScreen::Reply(screenRect)); 2240 return screenRect; 2241} 2242 2243IntRect WebPage::windowResizerRect() const 2244{ 2245 if (m_windowResizerSize.isEmpty()) 2246 return IntRect(); 2247 2248 IntSize frameViewSize; 2249 if (Frame* coreFrame = m_mainFrame->coreFrame()) { 2250 if (FrameView* view = coreFrame->view()) 2251 frameViewSize = view->size(); 2252 } 2253 2254 return IntRect(frameViewSize.width() - m_windowResizerSize.width(), frameViewSize.height() - m_windowResizerSize.height(), 2255 m_windowResizerSize.width(), m_windowResizerSize.height()); 2256} 2257 2258KeyboardUIMode WebPage::keyboardUIMode() 2259{ 2260 bool fullKeyboardAccessEnabled = WebProcess::shared().fullKeyboardAccessEnabled(); 2261 return static_cast<KeyboardUIMode>((fullKeyboardAccessEnabled ? KeyboardAccessFull : KeyboardAccessDefault) | (m_tabToLinks ? KeyboardAccessTabsToLinks : 0)); 2262} 2263 2264void WebPage::runJavaScriptInMainFrame(const String& script, uint64_t callbackID) 2265{ 2266 // NOTE: We need to be careful when running scripts that the objects we depend on don't 2267 // disappear during script execution. 2268 2269 // Retain the SerializedScriptValue at this level so it (and the internal data) lives 2270 // long enough for the DataReference to be encoded by the sent message. 2271 RefPtr<SerializedScriptValue> serializedResultValue; 2272 CoreIPC::DataReference dataReference; 2273 2274 JSLockHolder lock(JSDOMWindow::commonVM()); 2275 if (JSValue resultValue = m_mainFrame->coreFrame()->script()->executeScript(script, true).jsValue()) { 2276 if ((serializedResultValue = SerializedScriptValue::create(m_mainFrame->jsContext(), toRef(m_mainFrame->coreFrame()->script()->globalObject(mainThreadNormalWorld())->globalExec(), resultValue), 0))) 2277 dataReference = serializedResultValue->data(); 2278 } 2279 2280 send(Messages::WebPageProxy::ScriptValueCallback(dataReference, callbackID)); 2281} 2282 2283void WebPage::getContentsAsString(uint64_t callbackID) 2284{ 2285 String resultString = m_mainFrame->contentsAsString(); 2286 send(Messages::WebPageProxy::StringCallback(resultString, callbackID)); 2287} 2288 2289#if ENABLE(MHTML) 2290void WebPage::getContentsAsMHTMLData(uint64_t callbackID, bool useBinaryEncoding) 2291{ 2292 CoreIPC::DataReference dataReference; 2293 2294 RefPtr<SharedBuffer> buffer = useBinaryEncoding 2295 ? MHTMLArchive::generateMHTMLDataUsingBinaryEncoding(m_page.get()) 2296 : MHTMLArchive::generateMHTMLData(m_page.get()); 2297 2298 if (buffer) 2299 dataReference = CoreIPC::DataReference(reinterpret_cast<const uint8_t*>(buffer->data()), buffer->size()); 2300 2301 send(Messages::WebPageProxy::DataCallback(dataReference, callbackID)); 2302} 2303#endif 2304 2305void WebPage::getRenderTreeExternalRepresentation(uint64_t callbackID) 2306{ 2307 String resultString = renderTreeExternalRepresentation(); 2308 send(Messages::WebPageProxy::StringCallback(resultString, callbackID)); 2309} 2310 2311static Frame* frameWithSelection(Page* page) 2312{ 2313 for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext()) { 2314 if (frame->selection()->isRange()) 2315 return frame; 2316 } 2317 2318 return 0; 2319} 2320 2321void WebPage::getSelectionAsWebArchiveData(uint64_t callbackID) 2322{ 2323 CoreIPC::DataReference dataReference; 2324 2325#if PLATFORM(MAC) 2326 RefPtr<LegacyWebArchive> archive; 2327 RetainPtr<CFDataRef> data; 2328 2329 Frame* frame = frameWithSelection(m_page.get()); 2330 if (frame) { 2331 archive = LegacyWebArchive::createFromSelection(frame); 2332 data = archive->rawDataRepresentation(); 2333 dataReference = CoreIPC::DataReference(CFDataGetBytePtr(data.get()), CFDataGetLength(data.get())); 2334 } 2335#endif 2336 2337 send(Messages::WebPageProxy::DataCallback(dataReference, callbackID)); 2338} 2339 2340void WebPage::getSelectionOrContentsAsString(uint64_t callbackID) 2341{ 2342 String resultString = m_mainFrame->selectionAsString(); 2343 if (resultString.isEmpty()) 2344 resultString = m_mainFrame->contentsAsString(); 2345 send(Messages::WebPageProxy::StringCallback(resultString, callbackID)); 2346} 2347 2348void WebPage::getSourceForFrame(uint64_t frameID, uint64_t callbackID) 2349{ 2350 String resultString; 2351 if (WebFrame* frame = WebProcess::shared().webFrame(frameID)) 2352 resultString = frame->source(); 2353 2354 send(Messages::WebPageProxy::StringCallback(resultString, callbackID)); 2355} 2356 2357void WebPage::getMainResourceDataOfFrame(uint64_t frameID, uint64_t callbackID) 2358{ 2359 CoreIPC::DataReference dataReference; 2360 2361 RefPtr<ResourceBuffer> buffer; 2362 RefPtr<SharedBuffer> pdfResource; 2363 if (WebFrame* frame = WebProcess::shared().webFrame(frameID)) { 2364 if (PluginView* pluginView = pluginViewForFrame(frame->coreFrame())) { 2365 if ((pdfResource = pluginView->liveResourceData())) 2366 dataReference = CoreIPC::DataReference(reinterpret_cast<const uint8_t*>(pdfResource->data()), pdfResource->size()); 2367 } 2368 2369 if (dataReference.isEmpty()) { 2370 if (DocumentLoader* loader = frame->coreFrame()->loader()->documentLoader()) { 2371 if ((buffer = loader->mainResourceData())) 2372 dataReference = CoreIPC::DataReference(reinterpret_cast<const uint8_t*>(buffer->data()), buffer->size()); 2373 } 2374 } 2375 } 2376 2377 send(Messages::WebPageProxy::DataCallback(dataReference, callbackID)); 2378} 2379 2380static PassRefPtr<SharedBuffer> resourceDataForFrame(Frame* frame, const KURL& resourceURL) 2381{ 2382 DocumentLoader* loader = frame->loader()->documentLoader(); 2383 if (!loader) 2384 return 0; 2385 2386 RefPtr<ArchiveResource> subresource = loader->subresource(resourceURL); 2387 if (!subresource) 2388 return 0; 2389 2390 return subresource->data(); 2391} 2392 2393void WebPage::getResourceDataFromFrame(uint64_t frameID, const String& resourceURLString, uint64_t callbackID) 2394{ 2395 CoreIPC::DataReference dataReference; 2396 KURL resourceURL(KURL(), resourceURLString); 2397 2398 RefPtr<SharedBuffer> buffer; 2399 if (WebFrame* frame = WebProcess::shared().webFrame(frameID)) { 2400 buffer = resourceDataForFrame(frame->coreFrame(), resourceURL); 2401 if (!buffer) { 2402 // Try to get the resource data from the cache. 2403 buffer = cachedResponseDataForURL(resourceURL); 2404 } 2405 2406 if (buffer) 2407 dataReference = CoreIPC::DataReference(reinterpret_cast<const uint8_t*>(buffer->data()), buffer->size()); 2408 } 2409 2410 send(Messages::WebPageProxy::DataCallback(dataReference, callbackID)); 2411} 2412 2413void WebPage::getWebArchiveOfFrame(uint64_t frameID, uint64_t callbackID) 2414{ 2415 CoreIPC::DataReference dataReference; 2416 2417#if PLATFORM(MAC) 2418 RetainPtr<CFDataRef> data; 2419 if (WebFrame* frame = WebProcess::shared().webFrame(frameID)) { 2420 if ((data = frame->webArchiveData(0, 0))) 2421 dataReference = CoreIPC::DataReference(CFDataGetBytePtr(data.get()), CFDataGetLength(data.get())); 2422 } 2423#else 2424 UNUSED_PARAM(frameID); 2425#endif 2426 2427 send(Messages::WebPageProxy::DataCallback(dataReference, callbackID)); 2428} 2429 2430void WebPage::forceRepaintWithoutCallback() 2431{ 2432 m_drawingArea->forceRepaint(); 2433} 2434 2435void WebPage::forceRepaint(uint64_t callbackID) 2436{ 2437 if (m_drawingArea->forceRepaintAsync(callbackID)) 2438 return; 2439 2440 forceRepaintWithoutCallback(); 2441 send(Messages::WebPageProxy::VoidCallback(callbackID)); 2442} 2443 2444void WebPage::preferencesDidChange(const WebPreferencesStore& store) 2445{ 2446 WebPreferencesStore::removeTestRunnerOverrides(); 2447 updatePreferences(store); 2448} 2449 2450void WebPage::updatePreferences(const WebPreferencesStore& store) 2451{ 2452 Settings* settings = m_page->settings(); 2453 2454 m_tabToLinks = store.getBoolValueForKey(WebPreferencesKey::tabsToLinksKey()); 2455 m_asynchronousPluginInitializationEnabled = store.getBoolValueForKey(WebPreferencesKey::asynchronousPluginInitializationEnabledKey()); 2456 m_asynchronousPluginInitializationEnabledForAllPlugins = store.getBoolValueForKey(WebPreferencesKey::asynchronousPluginInitializationEnabledForAllPluginsKey()); 2457 m_artificialPluginInitializationDelayEnabled = store.getBoolValueForKey(WebPreferencesKey::artificialPluginInitializationDelayEnabledKey()); 2458 2459 m_scrollingPerformanceLoggingEnabled = store.getBoolValueForKey(WebPreferencesKey::scrollingPerformanceLoggingEnabledKey()); 2460 2461#if PLATFORM(MAC) 2462 m_pdfPluginEnabled = store.getBoolValueForKey(WebPreferencesKey::pdfPluginEnabledKey()); 2463#endif 2464 2465 // FIXME: This should be generated from macro expansion for all preferences, 2466 // but we currently don't match the naming of WebCore exactly so we are 2467 // handrolling the boolean and integer preferences until that is fixed. 2468 2469#define INITIALIZE_SETTINGS(KeyUpper, KeyLower, TypeName, Type, DefaultValue) settings->set##KeyUpper(store.get##TypeName##ValueForKey(WebPreferencesKey::KeyLower##Key())); 2470 2471 FOR_EACH_WEBKIT_STRING_PREFERENCE(INITIALIZE_SETTINGS) 2472 2473#undef INITIALIZE_SETTINGS 2474 2475 settings->setScriptEnabled(store.getBoolValueForKey(WebPreferencesKey::javaScriptEnabledKey())); 2476 settings->setScriptMarkupEnabled(store.getBoolValueForKey(WebPreferencesKey::javaScriptMarkupEnabledKey())); 2477 settings->setLoadsImagesAutomatically(store.getBoolValueForKey(WebPreferencesKey::loadsImagesAutomaticallyKey())); 2478 settings->setLoadsSiteIconsIgnoringImageLoadingSetting(store.getBoolValueForKey(WebPreferencesKey::loadsSiteIconsIgnoringImageLoadingPreferenceKey())); 2479 settings->setPluginsEnabled(store.getBoolValueForKey(WebPreferencesKey::pluginsEnabledKey())); 2480 settings->setJavaEnabled(store.getBoolValueForKey(WebPreferencesKey::javaEnabledKey())); 2481 settings->setJavaEnabledForLocalFiles(store.getBoolValueForKey(WebPreferencesKey::javaEnabledForLocalFilesKey())); 2482 settings->setOfflineWebApplicationCacheEnabled(store.getBoolValueForKey(WebPreferencesKey::offlineWebApplicationCacheEnabledKey())); 2483 settings->setLocalStorageEnabled(store.getBoolValueForKey(WebPreferencesKey::localStorageEnabledKey())); 2484 settings->setXSSAuditorEnabled(store.getBoolValueForKey(WebPreferencesKey::xssAuditorEnabledKey())); 2485 settings->setFrameFlatteningEnabled(store.getBoolValueForKey(WebPreferencesKey::frameFlatteningEnabledKey())); 2486 settings->setPrivateBrowsingEnabled(store.getBoolValueForKey(WebPreferencesKey::privateBrowsingEnabledKey())); 2487 settings->setDeveloperExtrasEnabled(store.getBoolValueForKey(WebPreferencesKey::developerExtrasEnabledKey())); 2488 settings->setJavaScriptExperimentsEnabled(store.getBoolValueForKey(WebPreferencesKey::javaScriptExperimentsEnabledKey())); 2489 settings->setTextAreasAreResizable(store.getBoolValueForKey(WebPreferencesKey::textAreasAreResizableKey())); 2490 settings->setNeedsSiteSpecificQuirks(store.getBoolValueForKey(WebPreferencesKey::needsSiteSpecificQuirksKey())); 2491 settings->setJavaScriptCanOpenWindowsAutomatically(store.getBoolValueForKey(WebPreferencesKey::javaScriptCanOpenWindowsAutomaticallyKey())); 2492 settings->setForceFTPDirectoryListings(store.getBoolValueForKey(WebPreferencesKey::forceFTPDirectoryListingsKey())); 2493 settings->setDNSPrefetchingEnabled(store.getBoolValueForKey(WebPreferencesKey::dnsPrefetchingEnabledKey())); 2494#if ENABLE(WEB_ARCHIVE) 2495 settings->setWebArchiveDebugModeEnabled(store.getBoolValueForKey(WebPreferencesKey::webArchiveDebugModeEnabledKey())); 2496#endif 2497 settings->setLocalFileContentSniffingEnabled(store.getBoolValueForKey(WebPreferencesKey::localFileContentSniffingEnabledKey())); 2498 settings->setUsesPageCache(store.getBoolValueForKey(WebPreferencesKey::usesPageCacheKey())); 2499 settings->setPageCacheSupportsPlugins(store.getBoolValueForKey(WebPreferencesKey::pageCacheSupportsPluginsKey())); 2500 settings->setAuthorAndUserStylesEnabled(store.getBoolValueForKey(WebPreferencesKey::authorAndUserStylesEnabledKey())); 2501 settings->setPaginateDuringLayoutEnabled(store.getBoolValueForKey(WebPreferencesKey::paginateDuringLayoutEnabledKey())); 2502 settings->setDOMPasteAllowed(store.getBoolValueForKey(WebPreferencesKey::domPasteAllowedKey())); 2503 settings->setJavaScriptCanAccessClipboard(store.getBoolValueForKey(WebPreferencesKey::javaScriptCanAccessClipboardKey())); 2504 settings->setShouldPrintBackgrounds(store.getBoolValueForKey(WebPreferencesKey::shouldPrintBackgroundsKey())); 2505 settings->setWebSecurityEnabled(store.getBoolValueForKey(WebPreferencesKey::webSecurityEnabledKey())); 2506 settings->setAllowUniversalAccessFromFileURLs(store.getBoolValueForKey(WebPreferencesKey::allowUniversalAccessFromFileURLsKey())); 2507 settings->setAllowFileAccessFromFileURLs(store.getBoolValueForKey(WebPreferencesKey::allowFileAccessFromFileURLsKey())); 2508 2509 settings->setMinimumFontSize(store.getUInt32ValueForKey(WebPreferencesKey::minimumFontSizeKey())); 2510 settings->setMinimumLogicalFontSize(store.getUInt32ValueForKey(WebPreferencesKey::minimumLogicalFontSizeKey())); 2511 settings->setDefaultFontSize(store.getUInt32ValueForKey(WebPreferencesKey::defaultFontSizeKey())); 2512 settings->setDefaultFixedFontSize(store.getUInt32ValueForKey(WebPreferencesKey::defaultFixedFontSizeKey())); 2513 settings->setScreenFontSubstitutionEnabled(store.getBoolValueForKey(WebPreferencesKey::screenFontSubstitutionEnabledKey()) 2514#if PLATFORM(MAC) 2515 || WebProcess::shared().shouldForceScreenFontSubstitution() 2516#endif 2517 ); 2518 settings->setLayoutFallbackWidth(store.getUInt32ValueForKey(WebPreferencesKey::layoutFallbackWidthKey())); 2519 settings->setDeviceWidth(store.getUInt32ValueForKey(WebPreferencesKey::deviceWidthKey())); 2520 settings->setDeviceHeight(store.getUInt32ValueForKey(WebPreferencesKey::deviceHeightKey())); 2521 settings->setEditableLinkBehavior(static_cast<WebCore::EditableLinkBehavior>(store.getUInt32ValueForKey(WebPreferencesKey::editableLinkBehaviorKey()))); 2522 settings->setShowsToolTipOverTruncatedText(store.getBoolValueForKey(WebPreferencesKey::showsToolTipOverTruncatedTextKey())); 2523 2524 settings->setAcceleratedCompositingForOverflowScrollEnabled(store.getBoolValueForKey(WebPreferencesKey::acceleratedCompositingForOverflowScrollEnabledKey())); 2525 settings->setAcceleratedCompositingEnabled(store.getBoolValueForKey(WebPreferencesKey::acceleratedCompositingEnabledKey()) && LayerTreeHost::supportsAcceleratedCompositing()); 2526 settings->setAcceleratedDrawingEnabled(store.getBoolValueForKey(WebPreferencesKey::acceleratedDrawingEnabledKey()) && LayerTreeHost::supportsAcceleratedCompositing()); 2527 settings->setCanvasUsesAcceleratedDrawing(store.getBoolValueForKey(WebPreferencesKey::canvasUsesAcceleratedDrawingKey()) && LayerTreeHost::supportsAcceleratedCompositing()); 2528 settings->setShowDebugBorders(store.getBoolValueForKey(WebPreferencesKey::compositingBordersVisibleKey())); 2529 settings->setShowRepaintCounter(store.getBoolValueForKey(WebPreferencesKey::compositingRepaintCountersVisibleKey())); 2530 settings->setShowTiledScrollingIndicator(store.getBoolValueForKey(WebPreferencesKey::tiledScrollingIndicatorVisibleKey())); 2531 settings->setAggressiveTileRetentionEnabled(store.getBoolValueForKey(WebPreferencesKey::aggressiveTileRetentionEnabledKey())); 2532 settings->setCSSCustomFilterEnabled(store.getBoolValueForKey(WebPreferencesKey::cssCustomFilterEnabledKey())); 2533 RuntimeEnabledFeatures::setCSSRegionsEnabled(store.getBoolValueForKey(WebPreferencesKey::cssRegionsEnabledKey())); 2534 RuntimeEnabledFeatures::setCSSCompositingEnabled(store.getBoolValueForKey(WebPreferencesKey::cssCompositingEnabledKey())); 2535 settings->setCSSGridLayoutEnabled(store.getBoolValueForKey(WebPreferencesKey::cssGridLayoutEnabledKey())); 2536 settings->setRegionBasedColumnsEnabled(store.getBoolValueForKey(WebPreferencesKey::regionBasedColumnsEnabledKey())); 2537 settings->setWebGLEnabled(store.getBoolValueForKey(WebPreferencesKey::webGLEnabledKey())); 2538 settings->setAccelerated2dCanvasEnabled(store.getBoolValueForKey(WebPreferencesKey::accelerated2dCanvasEnabledKey())); 2539 settings->setMediaPlaybackRequiresUserGesture(store.getBoolValueForKey(WebPreferencesKey::mediaPlaybackRequiresUserGestureKey())); 2540 settings->setMediaPlaybackAllowsInline(store.getBoolValueForKey(WebPreferencesKey::mediaPlaybackAllowsInlineKey())); 2541 settings->setMockScrollbarsEnabled(store.getBoolValueForKey(WebPreferencesKey::mockScrollbarsEnabledKey())); 2542 settings->setHyperlinkAuditingEnabled(store.getBoolValueForKey(WebPreferencesKey::hyperlinkAuditingEnabledKey())); 2543 settings->setRequestAnimationFrameEnabled(store.getBoolValueForKey(WebPreferencesKey::requestAnimationFrameEnabledKey())); 2544#if ENABLE(SMOOTH_SCROLLING) 2545 settings->setScrollAnimatorEnabled(store.getBoolValueForKey(WebPreferencesKey::scrollAnimatorEnabledKey())); 2546#endif 2547 settings->setInteractiveFormValidationEnabled(store.getBoolValueForKey(WebPreferencesKey::interactiveFormValidationEnabledKey())); 2548 2549#if ENABLE(SQL_DATABASE) 2550 DatabaseManager::manager().setIsAvailable(store.getBoolValueForKey(WebPreferencesKey::databasesEnabledKey())); 2551#endif 2552 2553#if ENABLE(FULLSCREEN_API) 2554 settings->setFullScreenEnabled(store.getBoolValueForKey(WebPreferencesKey::fullScreenEnabledKey())); 2555#endif 2556 2557#if USE(AVFOUNDATION) 2558 settings->setAVFoundationEnabled(store.getBoolValueForKey(WebPreferencesKey::isAVFoundationEnabledKey())); 2559#endif 2560 2561#if PLATFORM(MAC) 2562 settings->setQTKitEnabled(store.getBoolValueForKey(WebPreferencesKey::isQTKitEnabledKey())); 2563#endif 2564 2565#if ENABLE(WEB_AUDIO) 2566 settings->setWebAudioEnabled(store.getBoolValueForKey(WebPreferencesKey::webAudioEnabledKey())); 2567#endif 2568 2569 settings->setApplicationChromeMode(store.getBoolValueForKey(WebPreferencesKey::applicationChromeModeKey())); 2570 settings->setSuppressesIncrementalRendering(store.getBoolValueForKey(WebPreferencesKey::suppressesIncrementalRenderingKey())); 2571 settings->setIncrementalRenderingSuppressionTimeoutInSeconds(store.getDoubleValueForKey(WebPreferencesKey::incrementalRenderingSuppressionTimeoutKey())); 2572 settings->setBackspaceKeyNavigationEnabled(store.getBoolValueForKey(WebPreferencesKey::backspaceKeyNavigationEnabledKey())); 2573 settings->setWantsBalancedSetDefersLoadingBehavior(store.getBoolValueForKey(WebPreferencesKey::wantsBalancedSetDefersLoadingBehaviorKey())); 2574 settings->setCaretBrowsingEnabled(store.getBoolValueForKey(WebPreferencesKey::caretBrowsingEnabledKey())); 2575 2576#if ENABLE(VIDEO_TRACK) 2577 settings->setShouldDisplaySubtitles(store.getBoolValueForKey(WebPreferencesKey::shouldDisplaySubtitlesKey())); 2578 settings->setShouldDisplayCaptions(store.getBoolValueForKey(WebPreferencesKey::shouldDisplayCaptionsKey())); 2579 settings->setShouldDisplayTextDescriptions(store.getBoolValueForKey(WebPreferencesKey::shouldDisplayTextDescriptionsKey())); 2580#endif 2581 2582#if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS) 2583 settings->setNotificationsEnabled(store.getBoolValueForKey(WebPreferencesKey::notificationsEnabledKey())); 2584#endif 2585 2586 settings->setShouldRespectImageOrientation(store.getBoolValueForKey(WebPreferencesKey::shouldRespectImageOrientationKey())); 2587 settings->setStorageBlockingPolicy(static_cast<SecurityOrigin::StorageBlockingPolicy>(store.getUInt32ValueForKey(WebPreferencesKey::storageBlockingPolicyKey()))); 2588 settings->setCookieEnabled(store.getBoolValueForKey(WebPreferencesKey::cookieEnabledKey())); 2589 2590 settings->setDiagnosticLoggingEnabled(store.getBoolValueForKey(WebPreferencesKey::diagnosticLoggingEnabledKey())); 2591 2592 settings->setScrollingPerformanceLoggingEnabled(m_scrollingPerformanceLoggingEnabled); 2593 2594 settings->setPlugInSnapshottingEnabled(store.getBoolValueForKey(WebPreferencesKey::plugInSnapshottingEnabledKey())); 2595 settings->setSnapshotAllPlugIns(store.getBoolValueForKey(WebPreferencesKey::snapshotAllPlugInsKey())); 2596 settings->setAutostartOriginPlugInSnapshottingEnabled(store.getBoolValueForKey(WebPreferencesKey::autostartOriginPlugInSnapshottingEnabledKey())); 2597 settings->setPrimaryPlugInSnapshotDetectionEnabled(store.getBoolValueForKey(WebPreferencesKey::primaryPlugInSnapshotDetectionEnabledKey())); 2598 settings->setUsesEncodingDetector(store.getBoolValueForKey(WebPreferencesKey::usesEncodingDetectorKey())); 2599 2600#if ENABLE(TEXT_AUTOSIZING) 2601 settings->setTextAutosizingEnabled(store.getBoolValueForKey(WebPreferencesKey::textAutosizingEnabledKey())); 2602#endif 2603 2604 settings->setLogsPageMessagesToSystemConsoleEnabled(store.getBoolValueForKey(WebPreferencesKey::logsPageMessagesToSystemConsoleEnabledKey())); 2605 settings->setAsynchronousSpellCheckingEnabled(store.getBoolValueForKey(WebPreferencesKey::asynchronousSpellCheckingEnabledKey())); 2606 2607 settings->setSmartInsertDeleteEnabled(store.getBoolValueForKey(WebPreferencesKey::smartInsertDeleteEnabledKey())); 2608 settings->setSelectTrailingWhitespaceEnabled(store.getBoolValueForKey(WebPreferencesKey::selectTrailingWhitespaceEnabledKey())); 2609 settings->setShowsURLsInToolTips(store.getBoolValueForKey(WebPreferencesKey::showsURLsInToolTipsEnabledKey())); 2610 2611 settings->setEnableInheritURIQueryComponent(store.getBoolValueForKey(WebPreferencesKey::enableInheritURIQueryComponentKey())); 2612 2613#if ENABLE(HIDDEN_PAGE_DOM_TIMER_THROTTLING) 2614 settings->setHiddenPageDOMTimerThrottlingEnabled(store.getBoolValueForKey(WebPreferencesKey::hiddenPageDOMTimerThrottlingEnabledKey())); 2615#endif 2616#if ENABLE(PAGE_VISIBILITY_API) 2617 settings->setHiddenPageCSSAnimationSuspensionEnabled(store.getBoolValueForKey(WebPreferencesKey::hiddenPageCSSAnimationSuspensionEnabledKey())); 2618#endif 2619 2620 settings->setLowPowerVideoAudioBufferSizeEnabled(store.getBoolValueForKey(WebPreferencesKey::lowPowerVideoAudioBufferSizeEnabledKey())); 2621 2622 settings->setUseLegacyTextAlignPositionedElementBehavior(store.getBoolValueForKey(WebPreferencesKey::useLegacyTextAlignPositionedElementBehaviorKey())); 2623 2624 platformPreferencesDidChange(store); 2625 2626 if (m_drawingArea) 2627 m_drawingArea->updatePreferences(store); 2628} 2629 2630#if ENABLE(INSPECTOR) 2631WebInspector* WebPage::inspector() 2632{ 2633 if (m_isClosed) 2634 return 0; 2635 if (!m_inspector) 2636 m_inspector = WebInspector::create(this, m_inspectorClient); 2637 return m_inspector.get(); 2638} 2639#endif 2640 2641#if ENABLE(FULLSCREEN_API) 2642WebFullScreenManager* WebPage::fullScreenManager() 2643{ 2644 if (!m_fullScreenManager) 2645 m_fullScreenManager = WebFullScreenManager::create(this); 2646 return m_fullScreenManager.get(); 2647} 2648#endif 2649 2650NotificationPermissionRequestManager* WebPage::notificationPermissionRequestManager() 2651{ 2652 if (m_notificationPermissionRequestManager) 2653 return m_notificationPermissionRequestManager.get(); 2654 2655 m_notificationPermissionRequestManager = NotificationPermissionRequestManager::create(this); 2656 return m_notificationPermissionRequestManager.get(); 2657} 2658 2659#if !PLATFORM(GTK) && !PLATFORM(MAC) 2660bool WebPage::handleEditingKeyboardEvent(KeyboardEvent* evt) 2661{ 2662 Node* node = evt->target()->toNode(); 2663 ASSERT(node); 2664 Frame* frame = node->document()->frame(); 2665 ASSERT(frame); 2666 2667 const PlatformKeyboardEvent* keyEvent = evt->keyEvent(); 2668 if (!keyEvent) 2669 return false; 2670 2671 Editor::Command command = frame->editor().command(interpretKeyEvent(evt)); 2672 2673 if (keyEvent->type() == PlatformEvent::RawKeyDown) { 2674 // WebKit doesn't have enough information about mode to decide how commands that just insert text if executed via Editor should be treated, 2675 // so we leave it upon WebCore to either handle them immediately (e.g. Tab that changes focus) or let a keypress event be generated 2676 // (e.g. Tab that inserts a Tab character, or Enter). 2677 return !command.isTextInsertion() && command.execute(evt); 2678 } 2679 2680 if (command.execute(evt)) 2681 return true; 2682 2683 // Don't allow text insertion for nodes that cannot edit. 2684 if (!frame->editor().canEdit()) 2685 return false; 2686 2687 // Don't insert null or control characters as they can result in unexpected behaviour 2688 if (evt->charCode() < ' ') 2689 return false; 2690 2691 return frame->editor().insertText(evt->keyEvent()->text(), evt); 2692} 2693#endif 2694 2695#if ENABLE(DRAG_SUPPORT) 2696 2697#if PLATFORM(QT) || PLATFORM(GTK) 2698void WebPage::performDragControllerAction(uint64_t action, WebCore::DragData dragData) 2699{ 2700 if (!m_page) { 2701 send(Messages::WebPageProxy::DidPerformDragControllerAction(WebCore::DragSession())); 2702#if PLATFORM(QT) 2703 QMimeData* data = const_cast<QMimeData*>(dragData.platformData()); 2704 delete data; 2705#elif PLATFORM(GTK) 2706 DataObjectGtk* data = const_cast<DataObjectGtk*>(dragData.platformData()); 2707 data->deref(); 2708#endif 2709 return; 2710 } 2711 2712 switch (action) { 2713 case DragControllerActionEntered: 2714 send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController()->dragEntered(&dragData))); 2715 break; 2716 2717 case DragControllerActionUpdated: 2718 send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController()->dragUpdated(&dragData))); 2719 break; 2720 2721 case DragControllerActionExited: 2722 m_page->dragController()->dragExited(&dragData); 2723 break; 2724 2725 case DragControllerActionPerformDrag: { 2726 m_page->dragController()->performDrag(&dragData); 2727 break; 2728 } 2729 2730 default: 2731 ASSERT_NOT_REACHED(); 2732 } 2733 // DragData does not delete its platformData so we need to do that here. 2734#if PLATFORM(QT) 2735 QMimeData* data = const_cast<QMimeData*>(dragData.platformData()); 2736 delete data; 2737#elif PLATFORM(GTK) 2738 DataObjectGtk* data = const_cast<DataObjectGtk*>(dragData.platformData()); 2739 data->deref(); 2740#endif 2741} 2742 2743#else 2744void WebPage::performDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, const String& dragStorageName, uint32_t flags, const SandboxExtension::Handle& sandboxExtensionHandle, const SandboxExtension::HandleArray& sandboxExtensionsHandleArray) 2745{ 2746 if (!m_page) { 2747 send(Messages::WebPageProxy::DidPerformDragControllerAction(WebCore::DragSession())); 2748 return; 2749 } 2750 2751 DragData dragData(dragStorageName, clientPosition, globalPosition, static_cast<DragOperation>(draggingSourceOperationMask), static_cast<DragApplicationFlags>(flags)); 2752 switch (action) { 2753 case DragControllerActionEntered: 2754 send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController()->dragEntered(&dragData))); 2755 break; 2756 2757 case DragControllerActionUpdated: 2758 send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController()->dragUpdated(&dragData))); 2759 break; 2760 2761 case DragControllerActionExited: 2762 m_page->dragController()->dragExited(&dragData); 2763 break; 2764 2765 case DragControllerActionPerformDrag: { 2766 ASSERT(!m_pendingDropSandboxExtension); 2767 2768 m_pendingDropSandboxExtension = SandboxExtension::create(sandboxExtensionHandle); 2769 for (size_t i = 0; i < sandboxExtensionsHandleArray.size(); i++) { 2770 if (RefPtr<SandboxExtension> extension = SandboxExtension::create(sandboxExtensionsHandleArray[i])) 2771 m_pendingDropExtensionsForFileUpload.append(extension); 2772 } 2773 2774 m_page->dragController()->performDrag(&dragData); 2775 2776 // If we started loading a local file, the sandbox extension tracker would have adopted this 2777 // pending drop sandbox extension. If not, we'll play it safe and clear it. 2778 m_pendingDropSandboxExtension = nullptr; 2779 2780 m_pendingDropExtensionsForFileUpload.clear(); 2781 break; 2782 } 2783 2784 default: 2785 ASSERT_NOT_REACHED(); 2786 } 2787} 2788#endif 2789 2790void WebPage::dragEnded(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t operation) 2791{ 2792 IntPoint adjustedClientPosition(clientPosition.x() + m_page->dragController()->dragOffset().x(), clientPosition.y() + m_page->dragController()->dragOffset().y()); 2793 IntPoint adjustedGlobalPosition(globalPosition.x() + m_page->dragController()->dragOffset().x(), globalPosition.y() + m_page->dragController()->dragOffset().y()); 2794 2795 m_page->dragController()->dragEnded(); 2796 FrameView* view = m_page->mainFrame()->view(); 2797 if (!view) 2798 return; 2799 // FIXME: These are fake modifier keys here, but they should be real ones instead. 2800 PlatformMouseEvent event(adjustedClientPosition, adjustedGlobalPosition, LeftButton, PlatformEvent::MouseMoved, 0, false, false, false, false, currentTime()); 2801 m_page->mainFrame()->eventHandler()->dragSourceEndedAt(event, (DragOperation)operation); 2802} 2803 2804void WebPage::willPerformLoadDragDestinationAction() 2805{ 2806 m_sandboxExtensionTracker.willPerformLoadDragDestinationAction(m_pendingDropSandboxExtension.release()); 2807} 2808 2809void WebPage::mayPerformUploadDragDestinationAction() 2810{ 2811 for (size_t i = 0; i < m_pendingDropExtensionsForFileUpload.size(); i++) 2812 m_pendingDropExtensionsForFileUpload[i]->consumePermanently(); 2813 m_pendingDropExtensionsForFileUpload.clear(); 2814} 2815 2816#endif // ENABLE(DRAG_SUPPORT) 2817 2818WebUndoStep* WebPage::webUndoStep(uint64_t stepID) 2819{ 2820 return m_undoStepMap.get(stepID); 2821} 2822 2823void WebPage::addWebUndoStep(uint64_t stepID, WebUndoStep* entry) 2824{ 2825 m_undoStepMap.set(stepID, entry); 2826} 2827 2828void WebPage::removeWebEditCommand(uint64_t stepID) 2829{ 2830 m_undoStepMap.remove(stepID); 2831} 2832 2833void WebPage::unapplyEditCommand(uint64_t stepID) 2834{ 2835 WebUndoStep* step = webUndoStep(stepID); 2836 if (!step) 2837 return; 2838 2839 step->step()->unapply(); 2840} 2841 2842void WebPage::reapplyEditCommand(uint64_t stepID) 2843{ 2844 WebUndoStep* step = webUndoStep(stepID); 2845 if (!step) 2846 return; 2847 2848 m_isInRedo = true; 2849 step->step()->reapply(); 2850 m_isInRedo = false; 2851} 2852 2853void WebPage::didRemoveEditCommand(uint64_t commandID) 2854{ 2855 removeWebEditCommand(commandID); 2856} 2857 2858void WebPage::setActivePopupMenu(WebPopupMenu* menu) 2859{ 2860 m_activePopupMenu = menu; 2861} 2862 2863#if ENABLE(INPUT_TYPE_COLOR) 2864void WebPage::setActiveColorChooser(WebColorChooser* colorChooser) 2865{ 2866 m_activeColorChooser = colorChooser; 2867} 2868 2869void WebPage::didEndColorChooser() 2870{ 2871 m_activeColorChooser->didEndChooser(); 2872} 2873 2874void WebPage::didChooseColor(const WebCore::Color& color) 2875{ 2876 m_activeColorChooser->didChooseColor(color); 2877} 2878#endif 2879 2880void WebPage::setActiveOpenPanelResultListener(PassRefPtr<WebOpenPanelResultListener> openPanelResultListener) 2881{ 2882 m_activeOpenPanelResultListener = openPanelResultListener; 2883} 2884 2885bool WebPage::findStringFromInjectedBundle(const String& target, FindOptions options) 2886{ 2887 return m_page->findString(target, options); 2888} 2889 2890void WebPage::findString(const String& string, uint32_t options, uint32_t maxMatchCount) 2891{ 2892 m_findController.findString(string, static_cast<FindOptions>(options), maxMatchCount); 2893} 2894 2895void WebPage::findStringMatches(const String& string, uint32_t options, uint32_t maxMatchCount) 2896{ 2897 m_findController.findStringMatches(string, static_cast<FindOptions>(options), maxMatchCount); 2898} 2899 2900void WebPage::getImageForFindMatch(uint32_t matchIndex) 2901{ 2902 m_findController.getImageForFindMatch(matchIndex); 2903} 2904 2905void WebPage::selectFindMatch(uint32_t matchIndex) 2906{ 2907 m_findController.selectFindMatch(matchIndex); 2908} 2909 2910void WebPage::hideFindUI() 2911{ 2912 m_findController.hideFindUI(); 2913} 2914 2915void WebPage::countStringMatches(const String& string, uint32_t options, uint32_t maxMatchCount) 2916{ 2917 m_findController.countStringMatches(string, static_cast<FindOptions>(options), maxMatchCount); 2918} 2919 2920void WebPage::didChangeSelectedIndexForActivePopupMenu(int32_t newIndex) 2921{ 2922 changeSelectedIndex(newIndex); 2923 m_activePopupMenu = 0; 2924} 2925 2926void WebPage::changeSelectedIndex(int32_t index) 2927{ 2928 if (!m_activePopupMenu) 2929 return; 2930 2931 m_activePopupMenu->didChangeSelectedIndex(index); 2932} 2933 2934void WebPage::didChooseFilesForOpenPanel(const Vector<String>& files) 2935{ 2936 if (!m_activeOpenPanelResultListener) 2937 return; 2938 2939 m_activeOpenPanelResultListener->didChooseFiles(files); 2940 m_activeOpenPanelResultListener = 0; 2941} 2942 2943void WebPage::didCancelForOpenPanel() 2944{ 2945 m_activeOpenPanelResultListener = 0; 2946} 2947 2948#if ENABLE(WEB_PROCESS_SANDBOX) 2949void WebPage::extendSandboxForFileFromOpenPanel(const SandboxExtension::Handle& handle) 2950{ 2951 SandboxExtension::create(handle)->consumePermanently(); 2952} 2953#endif 2954 2955#if ENABLE(GEOLOCATION) 2956void WebPage::didReceiveGeolocationPermissionDecision(uint64_t geolocationID, bool allowed) 2957{ 2958 m_geolocationPermissionRequestManager.didReceiveGeolocationPermissionDecision(geolocationID, allowed); 2959} 2960#endif 2961 2962void WebPage::didReceiveNotificationPermissionDecision(uint64_t notificationID, bool allowed) 2963{ 2964 notificationPermissionRequestManager()->didReceiveNotificationPermissionDecision(notificationID, allowed); 2965} 2966 2967void WebPage::advanceToNextMisspelling(bool startBeforeSelection) 2968{ 2969 Frame* frame = m_page->focusController()->focusedOrMainFrame(); 2970 frame->editor().advanceToNextMisspelling(startBeforeSelection); 2971} 2972 2973void WebPage::changeSpellingToWord(const String& word) 2974{ 2975 replaceSelectionWithText(m_page->focusController()->focusedOrMainFrame(), word); 2976} 2977 2978void WebPage::unmarkAllMisspellings() 2979{ 2980 for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) { 2981 if (Document* document = frame->document()) 2982 document->markers()->removeMarkers(DocumentMarker::Spelling); 2983 } 2984} 2985 2986void WebPage::unmarkAllBadGrammar() 2987{ 2988 for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) { 2989 if (Document* document = frame->document()) 2990 document->markers()->removeMarkers(DocumentMarker::Grammar); 2991 } 2992} 2993 2994#if USE(APPKIT) 2995void WebPage::uppercaseWord() 2996{ 2997 m_page->focusController()->focusedOrMainFrame()->editor().uppercaseWord(); 2998} 2999 3000void WebPage::lowercaseWord() 3001{ 3002 m_page->focusController()->focusedOrMainFrame()->editor().lowercaseWord(); 3003} 3004 3005void WebPage::capitalizeWord() 3006{ 3007 m_page->focusController()->focusedOrMainFrame()->editor().capitalizeWord(); 3008} 3009#endif 3010 3011void WebPage::setTextForActivePopupMenu(int32_t index) 3012{ 3013 if (!m_activePopupMenu) 3014 return; 3015 3016 m_activePopupMenu->setTextForIndex(index); 3017} 3018 3019#if PLATFORM(GTK) 3020void WebPage::failedToShowPopupMenu() 3021{ 3022 if (!m_activePopupMenu) 3023 return; 3024 3025 m_activePopupMenu->client()->popupDidHide(); 3026} 3027#endif 3028 3029#if ENABLE(CONTEXT_MENUS) 3030void WebPage::didSelectItemFromActiveContextMenu(const WebContextMenuItemData& item) 3031{ 3032 if (!m_contextMenu) 3033 return; 3034 3035 m_contextMenu->itemSelected(item); 3036 m_contextMenu = 0; 3037} 3038#endif 3039 3040void WebPage::replaceSelectionWithText(Frame* frame, const String& text) 3041{ 3042 bool selectReplacement = true; 3043 bool smartReplace = false; 3044 return frame->editor().replaceSelectionWithText(text, selectReplacement, smartReplace); 3045} 3046 3047void WebPage::clearSelection() 3048{ 3049 m_page->focusController()->focusedOrMainFrame()->selection()->clear(); 3050} 3051 3052bool WebPage::mainFrameHasCustomRepresentation() const 3053{ 3054 if (Frame* frame = mainFrame()) { 3055 WebFrameLoaderClient* webFrameLoaderClient = toWebFrameLoaderClient(frame->loader()->client()); 3056 ASSERT(webFrameLoaderClient); 3057 return webFrameLoaderClient->frameHasCustomRepresentation(); 3058 } 3059 3060 return false; 3061} 3062 3063void WebPage::didChangeScrollOffsetForMainFrame() 3064{ 3065 Frame* frame = m_page->mainFrame(); 3066 IntPoint scrollPosition = frame->view()->scrollPosition(); 3067 IntPoint maximumScrollPosition = frame->view()->maximumScrollPosition(); 3068 IntPoint minimumScrollPosition = frame->view()->minimumScrollPosition(); 3069 3070 bool isPinnedToLeftSide = (scrollPosition.x() <= minimumScrollPosition.x()); 3071 bool isPinnedToRightSide = (scrollPosition.x() >= maximumScrollPosition.x()); 3072 bool isPinnedToTopSide = (scrollPosition.y() <= minimumScrollPosition.y()); 3073 bool isPinnedToBottomSide = (scrollPosition.y() >= maximumScrollPosition.y()); 3074 3075 if (isPinnedToLeftSide != m_cachedMainFrameIsPinnedToLeftSide || isPinnedToRightSide != m_cachedMainFrameIsPinnedToRightSide || isPinnedToTopSide != m_cachedMainFrameIsPinnedToTopSide || isPinnedToBottomSide != m_cachedMainFrameIsPinnedToBottomSide) { 3076 send(Messages::WebPageProxy::DidChangeScrollOffsetPinningForMainFrame(isPinnedToLeftSide, isPinnedToRightSide, isPinnedToTopSide, isPinnedToBottomSide)); 3077 3078 m_cachedMainFrameIsPinnedToLeftSide = isPinnedToLeftSide; 3079 m_cachedMainFrameIsPinnedToRightSide = isPinnedToRightSide; 3080 m_cachedMainFrameIsPinnedToTopSide = isPinnedToTopSide; 3081 m_cachedMainFrameIsPinnedToBottomSide = isPinnedToBottomSide; 3082 } 3083} 3084 3085void WebPage::mainFrameDidLayout() 3086{ 3087 unsigned pageCount = m_page->pageCount(); 3088 if (pageCount != m_cachedPageCount) { 3089 send(Messages::WebPageProxy::DidChangePageCount(pageCount)); 3090 m_cachedPageCount = pageCount; 3091 } 3092 3093#if USE(TILED_BACKING_STORE) && USE(ACCELERATED_COMPOSITING) 3094 if (m_drawingArea && m_drawingArea->layerTreeHost()) { 3095 double red, green, blue, alpha; 3096 m_mainFrame->getDocumentBackgroundColor(&red, &green, &blue, &alpha); 3097 RGBA32 rgba = makeRGBA32FromFloats(red, green, blue, alpha); 3098 if (m_backgroundColor.rgb() != rgba) { 3099 m_backgroundColor.setRGB(rgba); 3100 m_drawingArea->layerTreeHost()->setBackgroundColor(m_backgroundColor); 3101 } 3102 } 3103#endif 3104} 3105 3106void WebPage::addPluginView(PluginView* pluginView) 3107{ 3108 ASSERT(!m_pluginViews.contains(pluginView)); 3109 3110 m_pluginViews.add(pluginView); 3111 m_hasSeenPlugin = true; 3112#if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC) 3113 LOG(Plugins, "Primary Plug-In Detection: triggering detection from addPluginView(%p)", pluginView); 3114 m_determinePrimarySnapshottedPlugInTimer.startOneShot(0); 3115#endif 3116} 3117 3118void WebPage::removePluginView(PluginView* pluginView) 3119{ 3120 ASSERT(m_pluginViews.contains(pluginView)); 3121 3122 m_pluginViews.remove(pluginView); 3123#if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC) 3124 LOG(Plugins, "Primary Plug-In Detection: removePluginView(%p)", pluginView); 3125#endif 3126} 3127 3128void WebPage::sendSetWindowFrame(const FloatRect& windowFrame) 3129{ 3130#if PLATFORM(MAC) 3131 m_hasCachedWindowFrame = false; 3132#endif 3133 send(Messages::WebPageProxy::SetWindowFrame(windowFrame)); 3134} 3135 3136#if PLATFORM(MAC) 3137void WebPage::setWindowIsVisible(bool windowIsVisible) 3138{ 3139 m_windowIsVisible = windowIsVisible; 3140 3141 corePage()->focusController()->setContainingWindowIsVisible(windowIsVisible); 3142 3143 // Tell all our plug-in views that the window visibility changed. 3144 for (HashSet<PluginView*>::const_iterator it = m_pluginViews.begin(), end = m_pluginViews.end(); it != end; ++it) 3145 (*it)->setWindowIsVisible(windowIsVisible); 3146} 3147 3148void WebPage::windowAndViewFramesChanged(const FloatRect& windowFrameInScreenCoordinates, const FloatRect& windowFrameInUnflippedScreenCoordinates, const FloatRect& viewFrameInWindowCoordinates, const FloatPoint& accessibilityViewCoordinates) 3149{ 3150 m_windowFrameInScreenCoordinates = windowFrameInScreenCoordinates; 3151 m_windowFrameInUnflippedScreenCoordinates = windowFrameInUnflippedScreenCoordinates; 3152 m_viewFrameInWindowCoordinates = viewFrameInWindowCoordinates; 3153 m_accessibilityPosition = accessibilityViewCoordinates; 3154 3155 // Tell all our plug-in views that the window and view frames have changed. 3156 for (HashSet<PluginView*>::const_iterator it = m_pluginViews.begin(), end = m_pluginViews.end(); it != end; ++it) 3157 (*it)->windowAndViewFramesChanged(enclosingIntRect(windowFrameInScreenCoordinates), enclosingIntRect(viewFrameInWindowCoordinates)); 3158 3159 m_hasCachedWindowFrame = !m_windowFrameInUnflippedScreenCoordinates.isEmpty(); 3160} 3161#endif 3162 3163void WebPage::viewExposedRectChanged(const FloatRect& exposedRect, bool clipsToExposedRect) 3164{ 3165 m_drawingArea->setExposedRect(exposedRect); 3166 m_drawingArea->setClipsToExposedRect(clipsToExposedRect); 3167} 3168 3169void WebPage::setMainFrameIsScrollable(bool isScrollable) 3170{ 3171 m_mainFrameIsScrollable = isScrollable; 3172 m_drawingArea->mainFrameScrollabilityChanged(isScrollable); 3173 3174 if (FrameView* frameView = m_mainFrame->coreFrame()->view()) { 3175 frameView->setCanHaveScrollbars(isScrollable); 3176 frameView->setProhibitsScrolling(!isScrollable); 3177 } 3178} 3179 3180bool WebPage::windowIsFocused() const 3181{ 3182 return m_page->focusController()->isActive(); 3183} 3184 3185bool WebPage::windowAndWebPageAreFocused() const 3186{ 3187#if PLATFORM(MAC) 3188 if (!m_windowIsVisible) 3189 return false; 3190#endif 3191 return m_page->focusController()->isFocused() && m_page->focusController()->isActive(); 3192} 3193 3194void WebPage::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageDecoder& decoder) 3195{ 3196 if (decoder.messageReceiverName() == Messages::DrawingArea::messageReceiverName()) { 3197 if (m_drawingArea) 3198 m_drawingArea->didReceiveDrawingAreaMessage(connection, decoder); 3199 return; 3200 } 3201 3202#if USE(TILED_BACKING_STORE) && USE(ACCELERATED_COMPOSITING) 3203 if (decoder.messageReceiverName() == Messages::CoordinatedLayerTreeHost::messageReceiverName()) { 3204 if (m_drawingArea) 3205 m_drawingArea->didReceiveCoordinatedLayerTreeHostMessage(connection, decoder); 3206 return; 3207 } 3208#endif 3209 3210#if ENABLE(INSPECTOR) 3211 if (decoder.messageReceiverName() == Messages::WebInspector::messageReceiverName()) { 3212 if (WebInspector* inspector = this->inspector()) 3213 inspector->didReceiveWebInspectorMessage(connection, decoder); 3214 return; 3215 } 3216#endif 3217 3218#if ENABLE(FULLSCREEN_API) 3219 if (decoder.messageReceiverName() == Messages::WebFullScreenManager::messageReceiverName()) { 3220 fullScreenManager()->didReceiveMessage(connection, decoder); 3221 return; 3222 } 3223#endif 3224 3225 didReceiveWebPageMessage(connection, decoder); 3226} 3227 3228void WebPage::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageDecoder& decoder, OwnPtr<CoreIPC::MessageEncoder>& replyEncoder) 3229{ 3230 didReceiveSyncWebPageMessage(connection, decoder, replyEncoder); 3231} 3232 3233InjectedBundleBackForwardList* WebPage::backForwardList() 3234{ 3235 if (!m_backForwardList) 3236 m_backForwardList = InjectedBundleBackForwardList::create(this); 3237 return m_backForwardList.get(); 3238} 3239 3240#if PLATFORM(QT) 3241#if ENABLE(TOUCH_ADJUSTMENT) 3242void WebPage::findZoomableAreaForPoint(const WebCore::IntPoint& point, const WebCore::IntSize& area) 3243{ 3244 Node* node = 0; 3245 IntRect zoomableArea; 3246 bool foundAreaForTouchPoint = m_mainFrame->coreFrame()->eventHandler()->bestZoomableAreaForTouchPoint(point, IntSize(area.width() / 2, area.height() / 2), zoomableArea, node); 3247 3248 if (!foundAreaForTouchPoint) 3249 return; 3250 3251 ASSERT(node); 3252 3253 if (node->document() && node->document()->view()) 3254 zoomableArea = node->document()->view()->contentsToWindow(zoomableArea); 3255 3256 send(Messages::WebPageProxy::DidFindZoomableArea(point, zoomableArea)); 3257} 3258 3259#else 3260void WebPage::findZoomableAreaForPoint(const WebCore::IntPoint& point, const WebCore::IntSize& area) 3261{ 3262 UNUSED_PARAM(area); 3263 Frame* mainframe = m_mainFrame->coreFrame(); 3264 HitTestResult result = mainframe->eventHandler()->hitTestResultAtPoint(mainframe->view()->windowToContents(point), HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::IgnoreClipping | HitTestRequest::DisallowShadowContent); 3265 3266 Node* node = result.innerNode(); 3267 3268 if (!node) 3269 return; 3270 3271 IntRect zoomableArea = node->getRect(); 3272 3273 while (true) { 3274 bool found = !node->isTextNode() && !node->isShadowRoot(); 3275 3276 // No candidate found, bail out. 3277 if (!found && !node->parentNode()) 3278 return; 3279 3280 // Candidate found, and it is a better candidate than its parent. 3281 // NB: A parent is considered a better candidate iff the node is 3282 // contained by it and it is the only child. 3283 if (found && (!node->parentNode() || node->parentNode()->childNodeCount() != 1)) 3284 break; 3285 3286 node = node->parentNode(); 3287 zoomableArea.unite(node->getRect()); 3288 } 3289 3290 if (node->document() && node->document()->frame() && node->document()->frame()->view()) { 3291 const ScrollView* view = node->document()->frame()->view(); 3292 zoomableArea = view->contentsToWindow(zoomableArea); 3293 } 3294 3295 send(Messages::WebPageProxy::DidFindZoomableArea(point, zoomableArea)); 3296} 3297#endif 3298#endif 3299 3300WebPage::SandboxExtensionTracker::~SandboxExtensionTracker() 3301{ 3302 invalidate(); 3303} 3304 3305void WebPage::SandboxExtensionTracker::invalidate() 3306{ 3307 m_pendingProvisionalSandboxExtension = nullptr; 3308 3309 if (m_provisionalSandboxExtension) { 3310 m_provisionalSandboxExtension->revoke(); 3311 m_provisionalSandboxExtension = nullptr; 3312 } 3313 3314 if (m_committedSandboxExtension) { 3315 m_committedSandboxExtension->revoke(); 3316 m_committedSandboxExtension = nullptr; 3317 } 3318} 3319 3320void WebPage::SandboxExtensionTracker::willPerformLoadDragDestinationAction(PassRefPtr<SandboxExtension> pendingDropSandboxExtension) 3321{ 3322 setPendingProvisionalSandboxExtension(pendingDropSandboxExtension); 3323} 3324 3325void WebPage::SandboxExtensionTracker::beginLoad(WebFrame* frame, const SandboxExtension::Handle& handle) 3326{ 3327 ASSERT_UNUSED(frame, frame->isMainFrame()); 3328 3329 setPendingProvisionalSandboxExtension(SandboxExtension::create(handle)); 3330} 3331 3332void WebPage::SandboxExtensionTracker::setPendingProvisionalSandboxExtension(PassRefPtr<SandboxExtension> pendingProvisionalSandboxExtension) 3333{ 3334 m_pendingProvisionalSandboxExtension = pendingProvisionalSandboxExtension; 3335} 3336 3337static bool shouldReuseCommittedSandboxExtension(WebFrame* frame) 3338{ 3339 ASSERT(frame->isMainFrame()); 3340 3341 FrameLoader* frameLoader = frame->coreFrame()->loader(); 3342 FrameLoadType frameLoadType = frameLoader->loadType(); 3343 3344 // If the page is being reloaded, it should reuse whatever extension is committed. 3345 if (frameLoadType == FrameLoadTypeReload || frameLoadType == FrameLoadTypeReloadFromOrigin) 3346 return true; 3347 3348 DocumentLoader* documentLoader = frameLoader->documentLoader(); 3349 DocumentLoader* provisionalDocumentLoader = frameLoader->provisionalDocumentLoader(); 3350 if (!documentLoader || !provisionalDocumentLoader) 3351 return false; 3352 3353 if (documentLoader->url().isLocalFile() && provisionalDocumentLoader->url().isLocalFile()) 3354 return true; 3355 3356 return false; 3357} 3358 3359void WebPage::SandboxExtensionTracker::didStartProvisionalLoad(WebFrame* frame) 3360{ 3361 if (!frame->isMainFrame()) 3362 return; 3363 3364 // We should only reuse the commited sandbox extension if it is not null. It can be 3365 // null if the last load was for an error page. 3366 if (m_committedSandboxExtension && shouldReuseCommittedSandboxExtension(frame)) 3367 m_pendingProvisionalSandboxExtension = m_committedSandboxExtension; 3368 3369 ASSERT(!m_provisionalSandboxExtension); 3370 3371 m_provisionalSandboxExtension = m_pendingProvisionalSandboxExtension.release(); 3372 if (!m_provisionalSandboxExtension) 3373 return; 3374 3375 ASSERT(!m_provisionalSandboxExtension || frame->coreFrame()->loader()->provisionalDocumentLoader()->url().isLocalFile()); 3376 3377 m_provisionalSandboxExtension->consume(); 3378} 3379 3380void WebPage::SandboxExtensionTracker::didCommitProvisionalLoad(WebFrame* frame) 3381{ 3382 if (!frame->isMainFrame()) 3383 return; 3384 3385 if (m_committedSandboxExtension) 3386 m_committedSandboxExtension->revoke(); 3387 3388 m_committedSandboxExtension = m_provisionalSandboxExtension.release(); 3389 3390 // We can also have a non-null m_pendingProvisionalSandboxExtension if a new load is being started. 3391 // This extension is not cleared, because it does not pertain to the failed load, and will be needed. 3392} 3393 3394void WebPage::SandboxExtensionTracker::didFailProvisionalLoad(WebFrame* frame) 3395{ 3396 if (!frame->isMainFrame()) 3397 return; 3398 3399 if (!m_provisionalSandboxExtension) 3400 return; 3401 3402 m_provisionalSandboxExtension->revoke(); 3403 m_provisionalSandboxExtension = nullptr; 3404 3405 // We can also have a non-null m_pendingProvisionalSandboxExtension if a new load is being started 3406 // (notably, if the current one fails because the new one cancels it). This extension is not cleared, 3407 // because it does not pertain to the failed load, and will be needed. 3408} 3409 3410bool WebPage::hasLocalDataForURL(const KURL& url) 3411{ 3412 if (url.isLocalFile()) 3413 return true; 3414 3415 FrameLoader* frameLoader = m_page->mainFrame()->loader(); 3416 DocumentLoader* documentLoader = frameLoader ? frameLoader->documentLoader() : 0; 3417 if (documentLoader && documentLoader->subresource(url)) 3418 return true; 3419 3420 return platformHasLocalDataForURL(url); 3421} 3422 3423void WebPage::setCustomTextEncodingName(const String& encoding) 3424{ 3425 m_page->mainFrame()->loader()->reloadWithOverrideEncoding(encoding); 3426} 3427 3428void WebPage::didRemoveBackForwardItem(uint64_t itemID) 3429{ 3430 WebBackForwardListProxy::removeItem(itemID); 3431} 3432 3433#if PLATFORM(MAC) 3434 3435bool WebPage::isSpeaking() 3436{ 3437 bool result; 3438 return sendSync(Messages::WebPageProxy::GetIsSpeaking(), Messages::WebPageProxy::GetIsSpeaking::Reply(result)) && result; 3439} 3440 3441void WebPage::speak(const String& string) 3442{ 3443 send(Messages::WebPageProxy::Speak(string)); 3444} 3445 3446void WebPage::stopSpeaking() 3447{ 3448 send(Messages::WebPageProxy::StopSpeaking()); 3449} 3450 3451#endif 3452 3453#if PLATFORM(MAC) 3454RetainPtr<PDFDocument> WebPage::pdfDocumentForPrintingFrame(Frame* coreFrame) 3455{ 3456 Document* document = coreFrame->document(); 3457 if (!document) 3458 return 0; 3459 3460 if (!document->isPluginDocument()) 3461 return 0; 3462 3463 PluginView* pluginView = static_cast<PluginView*>(toPluginDocument(document)->pluginWidget()); 3464 if (!pluginView) 3465 return 0; 3466 3467 return pluginView->pdfDocumentForPrinting(); 3468} 3469#endif // PLATFORM(MAC) 3470 3471void WebPage::beginPrinting(uint64_t frameID, const PrintInfo& printInfo) 3472{ 3473 WebFrame* frame = WebProcess::shared().webFrame(frameID); 3474 if (!frame) 3475 return; 3476 3477 Frame* coreFrame = frame->coreFrame(); 3478 if (!coreFrame) 3479 return; 3480 3481#if PLATFORM(MAC) 3482 if (pdfDocumentForPrintingFrame(coreFrame)) 3483 return; 3484#endif // PLATFORM(MAC) 3485 3486 if (!m_printContext) 3487 m_printContext = adoptPtr(new PrintContext(coreFrame)); 3488 3489 drawingArea()->setLayerTreeStateIsFrozen(true); 3490 m_printContext->begin(printInfo.availablePaperWidth, printInfo.availablePaperHeight); 3491 3492 float fullPageHeight; 3493 m_printContext->computePageRects(FloatRect(0, 0, printInfo.availablePaperWidth, printInfo.availablePaperHeight), 0, 0, printInfo.pageSetupScaleFactor, fullPageHeight, true); 3494 3495#if PLATFORM(GTK) 3496 if (!m_printOperation) 3497 m_printOperation = WebPrintOperationGtk::create(this, printInfo); 3498#endif 3499} 3500 3501void WebPage::endPrinting() 3502{ 3503 drawingArea()->setLayerTreeStateIsFrozen(false); 3504#if PLATFORM(GTK) 3505 m_printOperation = 0; 3506#endif 3507 m_printContext = nullptr; 3508} 3509 3510void WebPage::computePagesForPrinting(uint64_t frameID, const PrintInfo& printInfo, uint64_t callbackID) 3511{ 3512 Vector<IntRect> resultPageRects; 3513 double resultTotalScaleFactorForPrinting = 1; 3514 3515 beginPrinting(frameID, printInfo); 3516 3517 if (m_printContext) { 3518 resultPageRects = m_printContext->pageRects(); 3519 resultTotalScaleFactorForPrinting = m_printContext->computeAutomaticScaleFactor(FloatSize(printInfo.availablePaperWidth, printInfo.availablePaperHeight)) * printInfo.pageSetupScaleFactor; 3520 } 3521#if PLATFORM(MAC) 3522 else 3523 computePagesForPrintingPDFDocument(frameID, printInfo, resultPageRects); 3524#endif // PLATFORM(MAC) 3525 3526 // If we're asked to print, we should actually print at least a blank page. 3527 if (resultPageRects.isEmpty()) 3528 resultPageRects.append(IntRect(0, 0, 1, 1)); 3529 3530 send(Messages::WebPageProxy::ComputedPagesCallback(resultPageRects, resultTotalScaleFactorForPrinting, callbackID)); 3531} 3532 3533#if PLATFORM(MAC) 3534void WebPage::drawRectToImage(uint64_t frameID, const PrintInfo& printInfo, const IntRect& rect, const WebCore::IntSize& imageSize, uint64_t callbackID) 3535{ 3536 WebFrame* frame = WebProcess::shared().webFrame(frameID); 3537 Frame* coreFrame = frame ? frame->coreFrame() : 0; 3538 3539 RefPtr<WebImage> image; 3540 3541#if USE(CG) 3542 if (coreFrame) { 3543#if PLATFORM(MAC) 3544 ASSERT(coreFrame->document()->printing() || pdfDocumentForPrintingFrame(coreFrame)); 3545#else 3546 ASSERT(coreFrame->document()->printing()); 3547#endif 3548 3549 RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(imageSize, ShareableBitmap::SupportsAlpha); 3550 OwnPtr<GraphicsContext> graphicsContext = bitmap->createGraphicsContext(); 3551 3552 float printingScale = static_cast<float>(imageSize.width()) / rect.width(); 3553 graphicsContext->scale(FloatSize(printingScale, printingScale)); 3554 3555#if PLATFORM(MAC) 3556 if (RetainPtr<PDFDocument> pdfDocument = pdfDocumentForPrintingFrame(coreFrame)) { 3557 ASSERT(!m_printContext); 3558 graphicsContext->scale(FloatSize(1, -1)); 3559 graphicsContext->translate(0, -rect.height()); 3560 drawPDFDocument(graphicsContext->platformContext(), pdfDocument.get(), printInfo, rect); 3561 } else 3562#endif 3563 { 3564 m_printContext->spoolRect(*graphicsContext, rect); 3565 } 3566 3567 image = WebImage::create(bitmap.release()); 3568 } 3569#endif 3570 3571 ShareableBitmap::Handle handle; 3572 3573 if (image) 3574 image->bitmap()->createHandle(handle, SharedMemory::ReadOnly); 3575 3576 send(Messages::WebPageProxy::ImageCallback(handle, callbackID)); 3577} 3578 3579void WebPage::drawPagesToPDF(uint64_t frameID, const PrintInfo& printInfo, uint32_t first, uint32_t count, uint64_t callbackID) 3580{ 3581 WebFrame* frame = WebProcess::shared().webFrame(frameID); 3582 Frame* coreFrame = frame ? frame->coreFrame() : 0; 3583 3584 RetainPtr<CFMutableDataRef> pdfPageData = adoptCF(CFDataCreateMutable(0, 0)); 3585 3586#if USE(CG) 3587 if (coreFrame) { 3588 3589#if PLATFORM(MAC) 3590 ASSERT(coreFrame->document()->printing() || pdfDocumentForPrintingFrame(coreFrame)); 3591#else 3592 ASSERT(coreFrame->document()->printing()); 3593#endif 3594 3595 // FIXME: Use CGDataConsumerCreate with callbacks to avoid copying the data. 3596 RetainPtr<CGDataConsumerRef> pdfDataConsumer = adoptCF(CGDataConsumerCreateWithCFData(pdfPageData.get())); 3597 3598 CGRect mediaBox = (m_printContext && m_printContext->pageCount()) ? m_printContext->pageRect(0) : CGRectMake(0, 0, printInfo.availablePaperWidth, printInfo.availablePaperHeight); 3599 RetainPtr<CGContextRef> context = adoptCF(CGPDFContextCreate(pdfDataConsumer.get(), &mediaBox, 0)); 3600 3601#if PLATFORM(MAC) 3602 if (RetainPtr<PDFDocument> pdfDocument = pdfDocumentForPrintingFrame(coreFrame)) { 3603 ASSERT(!m_printContext); 3604 drawPagesToPDFFromPDFDocument(context.get(), pdfDocument.get(), printInfo, first, count); 3605 } else 3606#endif 3607 { 3608 size_t pageCount = m_printContext->pageCount(); 3609 for (uint32_t page = first; page < first + count; ++page) { 3610 if (page >= pageCount) 3611 break; 3612 3613 RetainPtr<CFDictionaryRef> pageInfo = adoptCF(CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); 3614 CGPDFContextBeginPage(context.get(), pageInfo.get()); 3615 3616 GraphicsContext ctx(context.get()); 3617 ctx.scale(FloatSize(1, -1)); 3618 ctx.translate(0, -m_printContext->pageRect(page).height()); 3619 m_printContext->spoolPage(ctx, page, m_printContext->pageRect(page).width()); 3620 3621 CGPDFContextEndPage(context.get()); 3622 } 3623 } 3624 CGPDFContextClose(context.get()); 3625 } 3626#endif 3627 3628 send(Messages::WebPageProxy::DataCallback(CoreIPC::DataReference(CFDataGetBytePtr(pdfPageData.get()), CFDataGetLength(pdfPageData.get())), callbackID)); 3629} 3630 3631#elif PLATFORM(GTK) 3632 3633void WebPage::drawPagesForPrinting(uint64_t frameID, const PrintInfo& printInfo, uint64_t callbackID) 3634{ 3635 beginPrinting(frameID, printInfo); 3636 if (m_printContext && m_printOperation) { 3637 m_printOperation->startPrint(m_printContext.get(), callbackID); 3638 return; 3639 } 3640 3641 send(Messages::WebPageProxy::VoidCallback(callbackID)); 3642} 3643#endif 3644 3645void WebPage::savePDFToFileInDownloadsFolder(const String& suggestedFilename, const String& originatingURLString, const uint8_t* data, unsigned long size) 3646{ 3647 send(Messages::WebPageProxy::SavePDFToFileInDownloadsFolder(suggestedFilename, originatingURLString, CoreIPC::DataReference(data, size))); 3648} 3649 3650#if PLATFORM(MAC) 3651void WebPage::savePDFToTemporaryFolderAndOpenWithNativeApplication(const String& suggestedFilename, const String& originatingURLString, const uint8_t* data, unsigned long size, const String& pdfUUID) 3652{ 3653 send(Messages::WebPageProxy::SavePDFToTemporaryFolderAndOpenWithNativeApplication(suggestedFilename, originatingURLString, CoreIPC::DataReference(data, size), pdfUUID)); 3654} 3655#endif 3656 3657void WebPage::setMediaVolume(float volume) 3658{ 3659 m_page->setMediaVolume(volume); 3660} 3661 3662void WebPage::setMayStartMediaWhenInWindow(bool mayStartMedia) 3663{ 3664 if (mayStartMedia == m_mayStartMediaWhenInWindow) 3665 return; 3666 3667 m_mayStartMediaWhenInWindow = mayStartMedia; 3668 if (m_mayStartMediaWhenInWindow && m_page->isOnscreen()) 3669 m_setCanStartMediaTimer.startOneShot(0); 3670} 3671 3672void WebPage::runModal() 3673{ 3674 if (m_isClosed) 3675 return; 3676 if (m_isRunningModal) 3677 return; 3678 3679 m_isRunningModal = true; 3680 send(Messages::WebPageProxy::RunModal()); 3681 RunLoop::run(); 3682 ASSERT(!m_isRunningModal); 3683} 3684 3685void WebPage::setMemoryCacheMessagesEnabled(bool memoryCacheMessagesEnabled) 3686{ 3687 m_page->setMemoryCacheClientCallsEnabled(memoryCacheMessagesEnabled); 3688} 3689 3690bool WebPage::canHandleRequest(const WebCore::ResourceRequest& request) 3691{ 3692 if (SchemeRegistry::shouldLoadURLSchemeAsEmptyDocument(request.url().protocol())) 3693 return true; 3694 3695#if ENABLE(BLOB) 3696 if (request.url().protocolIs("blob")) 3697 return true; 3698#endif 3699 3700 return platformCanHandleRequest(request); 3701} 3702 3703#if USE(TILED_BACKING_STORE) 3704void WebPage::commitPageTransitionViewport() 3705{ 3706 m_drawingArea->setLayerTreeStateIsFrozen(false); 3707} 3708#endif 3709 3710#if PLATFORM(MAC) 3711void WebPage::handleAlternativeTextUIResult(const String& result) 3712{ 3713 Frame* frame = m_page->focusController()->focusedOrMainFrame(); 3714 if (!frame) 3715 return; 3716 frame->editor().handleAlternativeTextUIResult(result); 3717} 3718#endif 3719 3720void WebPage::simulateMouseDown(int button, WebCore::IntPoint position, int clickCount, WKEventModifiers modifiers, double time) 3721{ 3722 mouseEvent(WebMouseEvent(WebMouseEvent::MouseDown, static_cast<WebMouseEvent::Button>(button), position, position, 0, 0, 0, clickCount, static_cast<WebMouseEvent::Modifiers>(modifiers), time)); 3723} 3724 3725void WebPage::simulateMouseUp(int button, WebCore::IntPoint position, int clickCount, WKEventModifiers modifiers, double time) 3726{ 3727 mouseEvent(WebMouseEvent(WebMouseEvent::MouseUp, static_cast<WebMouseEvent::Button>(button), position, position, 0, 0, 0, clickCount, static_cast<WebMouseEvent::Modifiers>(modifiers), time)); 3728} 3729 3730void WebPage::simulateMouseMotion(WebCore::IntPoint position, double time) 3731{ 3732 mouseEvent(WebMouseEvent(WebMouseEvent::MouseMove, WebMouseEvent::NoButton, position, position, 0, 0, 0, 0, WebMouseEvent::Modifiers(), time)); 3733} 3734 3735void WebPage::setCompositionForTesting(const String& compositionString, uint64_t from, uint64_t length) 3736{ 3737 Frame* frame = m_page->focusController()->focusedOrMainFrame(); 3738 if (!frame || !frame->editor().canEdit()) 3739 return; 3740 3741 Vector<CompositionUnderline> underlines; 3742 underlines.append(CompositionUnderline(0, compositionString.length(), Color(Color::black), false)); 3743 frame->editor().setComposition(compositionString, underlines, from, from + length); 3744} 3745 3746bool WebPage::hasCompositionForTesting() 3747{ 3748 Frame* frame = m_page->focusController()->focusedOrMainFrame(); 3749 return frame && frame->editor().hasComposition(); 3750} 3751 3752void WebPage::confirmCompositionForTesting(const String& compositionString) 3753{ 3754 Frame* frame = m_page->focusController()->focusedOrMainFrame(); 3755 if (!frame || !frame->editor().canEdit()) 3756 return; 3757 3758 if (compositionString.isNull()) 3759 frame->editor().confirmComposition(); 3760 frame->editor().confirmComposition(compositionString); 3761} 3762 3763void WebPage::numWheelEventHandlersChanged(unsigned numWheelEventHandlers) 3764{ 3765 if (m_numWheelEventHandlers == numWheelEventHandlers) 3766 return; 3767 3768 m_numWheelEventHandlers = numWheelEventHandlers; 3769 recomputeShortCircuitHorizontalWheelEventsState(); 3770} 3771 3772static bool hasEnabledHorizontalScrollbar(ScrollableArea* scrollableArea) 3773{ 3774 if (Scrollbar* scrollbar = scrollableArea->horizontalScrollbar()) 3775 return scrollbar->enabled(); 3776 3777 return false; 3778} 3779 3780static bool pageContainsAnyHorizontalScrollbars(Frame* mainFrame) 3781{ 3782 if (FrameView* frameView = mainFrame->view()) { 3783 if (hasEnabledHorizontalScrollbar(frameView)) 3784 return true; 3785 } 3786 3787 for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext()) { 3788 FrameView* frameView = frame->view(); 3789 if (!frameView) 3790 continue; 3791 3792 const HashSet<ScrollableArea*>* scrollableAreas = frameView->scrollableAreas(); 3793 if (!scrollableAreas) 3794 continue; 3795 3796 for (HashSet<ScrollableArea*>::const_iterator it = scrollableAreas->begin(), end = scrollableAreas->end(); it != end; ++it) { 3797 ScrollableArea* scrollableArea = *it; 3798 if (!scrollableArea->scrollbarsCanBeActive()) 3799 continue; 3800 3801 if (hasEnabledHorizontalScrollbar(scrollableArea)) 3802 return true; 3803 } 3804 } 3805 3806 return false; 3807} 3808 3809void WebPage::recomputeShortCircuitHorizontalWheelEventsState() 3810{ 3811 bool canShortCircuitHorizontalWheelEvents = !m_numWheelEventHandlers; 3812 3813 if (canShortCircuitHorizontalWheelEvents) { 3814 // Check if we have any horizontal scroll bars on the page. 3815 if (pageContainsAnyHorizontalScrollbars(mainFrame())) 3816 canShortCircuitHorizontalWheelEvents = false; 3817 } 3818 3819 if (m_canShortCircuitHorizontalWheelEvents == canShortCircuitHorizontalWheelEvents) 3820 return; 3821 3822 m_canShortCircuitHorizontalWheelEvents = canShortCircuitHorizontalWheelEvents; 3823 send(Messages::WebPageProxy::SetCanShortCircuitHorizontalWheelEvents(m_canShortCircuitHorizontalWheelEvents)); 3824} 3825 3826Frame* WebPage::mainFrame() const 3827{ 3828 return m_page ? m_page->mainFrame() : 0; 3829} 3830 3831FrameView* WebPage::mainFrameView() const 3832{ 3833 if (Frame* frame = mainFrame()) 3834 return frame->view(); 3835 3836 return 0; 3837} 3838 3839#if ENABLE(PAGE_VISIBILITY_API) || ENABLE(HIDDEN_PAGE_DOM_TIMER_THROTTLING) 3840void WebPage::setVisibilityState(uint32_t visibilityState, bool isInitialState) 3841{ 3842 if (!m_page) 3843 return; 3844 3845 WebCore::PageVisibilityState state = static_cast<WebCore::PageVisibilityState>(visibilityState); 3846 3847#if ENABLE(PAGE_VISIBILITY_API) 3848 if (m_visibilityState == state) 3849 return; 3850 3851 FrameView* view = m_page->mainFrame() ? m_page->mainFrame()->view() : 0; 3852 3853 if (state == WebCore::PageVisibilityStateVisible) { 3854 m_page->didMoveOnscreen(); 3855 if (view) 3856 view->show(); 3857 } 3858 3859 m_page->setVisibilityState(state, isInitialState); 3860 m_visibilityState = state; 3861 3862 if (state == WebCore::PageVisibilityStateHidden) { 3863 m_page->willMoveOffscreen(); 3864 if (view) 3865 view->hide(); 3866 } 3867#endif 3868 3869#if ENABLE(HIDDEN_PAGE_DOM_TIMER_THROTTLING) && !ENABLE(PAGE_VISIBILITY_API) 3870 m_page->setVisibilityState(state, isInitialState); 3871#endif 3872} 3873#endif 3874 3875void WebPage::setThrottled(bool isThrottled) 3876{ 3877 if (m_page) 3878 m_page->setThrottled(isThrottled); 3879} 3880 3881void WebPage::setScrollingPerformanceLoggingEnabled(bool enabled) 3882{ 3883 m_scrollingPerformanceLoggingEnabled = enabled; 3884 3885 FrameView* frameView = m_mainFrame->coreFrame()->view(); 3886 if (!frameView) 3887 return; 3888 3889 frameView->setScrollingPerformanceLoggingEnabled(enabled); 3890} 3891 3892bool WebPage::canPluginHandleResponse(const ResourceResponse& response) 3893{ 3894#if ENABLE(NETSCAPE_PLUGIN_API) 3895 uint32_t pluginLoadPolicy; 3896 bool allowOnlyApplicationPlugins = !m_mainFrame->coreFrame()->loader()->subframeLoader()->allowPlugins(NotAboutToInstantiatePlugin); 3897 3898 uint64_t pluginProcessToken; 3899 String newMIMEType; 3900 String unavailabilityDescription; 3901 if (!sendSync(Messages::WebPageProxy::FindPlugin(response.mimeType(), PluginProcessTypeNormal, response.url().string(), response.url().string(), response.url().string(), allowOnlyApplicationPlugins), Messages::WebPageProxy::FindPlugin::Reply(pluginProcessToken, newMIMEType, pluginLoadPolicy, unavailabilityDescription))) 3902 return false; 3903 3904 return pluginLoadPolicy != PluginModuleBlocked && pluginProcessToken; 3905#else 3906 return false; 3907#endif 3908} 3909 3910bool WebPage::shouldUseCustomRepresentationForResponse(const ResourceResponse& response) 3911{ 3912 if (!m_mimeTypesWithCustomRepresentations.contains(response.mimeType())) 3913 return false; 3914 3915 // If a plug-in exists that claims to support this response, it should take precedence over the custom representation. 3916 return !canPluginHandleResponse(response); 3917} 3918 3919#if PLATFORM(QT) || PLATFORM(GTK) 3920static Frame* targetFrameForEditing(WebPage* page) 3921{ 3922 Frame* targetFrame = page->corePage()->focusController()->focusedOrMainFrame(); 3923 3924 if (!targetFrame) 3925 return 0; 3926 3927 Editor& editor = targetFrame->editor(); 3928 if (!editor.canEdit()) 3929 return 0; 3930 3931 if (editor.hasComposition()) { 3932 // We should verify the parent node of this IME composition node are 3933 // editable because JavaScript may delete a parent node of the composition 3934 // node. In this case, WebKit crashes while deleting texts from the parent 3935 // node, which doesn't exist any longer. 3936 if (PassRefPtr<Range> range = editor.compositionRange()) { 3937 Node* node = range->startContainer(); 3938 if (!node || !node->isContentEditable()) 3939 return 0; 3940 } 3941 } 3942 return targetFrame; 3943} 3944 3945void WebPage::confirmComposition(const String& compositionString, int64_t selectionStart, int64_t selectionLength) 3946{ 3947 Frame* targetFrame = targetFrameForEditing(this); 3948 if (!targetFrame) { 3949 send(Messages::WebPageProxy::EditorStateChanged(editorState())); 3950 return; 3951 } 3952 3953 targetFrame->editor().confirmComposition(compositionString); 3954 3955 if (selectionStart == -1) { 3956 send(Messages::WebPageProxy::EditorStateChanged(editorState())); 3957 return; 3958 } 3959 3960 Element* scope = targetFrame->selection()->rootEditableElement(); 3961 RefPtr<Range> selectionRange = TextIterator::rangeFromLocationAndLength(scope, selectionStart, selectionLength); 3962 ASSERT_WITH_MESSAGE(selectionRange, "Invalid selection: [%lld:%lld] in text of length %d", static_cast<long long>(selectionStart), static_cast<long long>(selectionLength), scope->innerText().length()); 3963 3964 if (selectionRange) { 3965 VisibleSelection selection(selectionRange.get(), SEL_DEFAULT_AFFINITY); 3966 targetFrame->selection()->setSelection(selection); 3967 } 3968 send(Messages::WebPageProxy::EditorStateChanged(editorState())); 3969} 3970 3971void WebPage::setComposition(const String& text, Vector<CompositionUnderline> underlines, uint64_t selectionStart, uint64_t selectionEnd, uint64_t replacementStart, uint64_t replacementLength) 3972{ 3973 Frame* targetFrame = targetFrameForEditing(this); 3974 if (!targetFrame || !targetFrame->selection()->isContentEditable()) { 3975 send(Messages::WebPageProxy::EditorStateChanged(editorState())); 3976 return; 3977 } 3978 3979 if (replacementLength > 0) { 3980 // The layout needs to be uptodate before setting a selection 3981 targetFrame->document()->updateLayout(); 3982 3983 Element* scope = targetFrame->selection()->rootEditableElement(); 3984 RefPtr<Range> replacementRange = TextIterator::rangeFromLocationAndLength(scope, replacementStart, replacementLength); 3985 targetFrame->editor().setIgnoreCompositionSelectionChange(true); 3986 targetFrame->selection()->setSelection(VisibleSelection(replacementRange.get(), SEL_DEFAULT_AFFINITY)); 3987 targetFrame->editor().setIgnoreCompositionSelectionChange(false); 3988 } 3989 3990 targetFrame->editor().setComposition(text, underlines, selectionStart, selectionEnd); 3991 send(Messages::WebPageProxy::EditorStateChanged(editorState())); 3992} 3993 3994void WebPage::cancelComposition() 3995{ 3996 if (Frame* targetFrame = targetFrameForEditing(this)) 3997 targetFrame->editor().cancelComposition(); 3998 send(Messages::WebPageProxy::EditorStateChanged(editorState())); 3999} 4000#endif 4001 4002void WebPage::didChangeSelection() 4003{ 4004 send(Messages::WebPageProxy::EditorStateChanged(editorState())); 4005} 4006 4007void WebPage::setMainFrameInViewSourceMode(bool inViewSourceMode) 4008{ 4009 m_mainFrame->coreFrame()->setInViewSourceMode(inViewSourceMode); 4010} 4011 4012void WebPage::setMinimumLayoutSize(const IntSize& minimumLayoutSize) 4013{ 4014 if (m_minimumLayoutSize == minimumLayoutSize) 4015 return; 4016 4017 m_minimumLayoutSize = minimumLayoutSize; 4018 if (minimumLayoutSize.width() <= 0) { 4019 corePage()->mainFrame()->view()->enableAutoSizeMode(false, IntSize(), IntSize()); 4020 return; 4021 } 4022 4023 int minimumLayoutWidth = minimumLayoutSize.width(); 4024 int minimumLayoutHeight = std::max(minimumLayoutSize.height(), 1); 4025 4026 int maximumSize = std::numeric_limits<int>::max(); 4027 4028 corePage()->mainFrame()->view()->enableAutoSizeMode(true, IntSize(minimumLayoutWidth, minimumLayoutHeight), IntSize(maximumSize, maximumSize)); 4029} 4030 4031void WebPage::setAutoSizingShouldExpandToViewHeight(bool shouldExpand) 4032{ 4033 if (m_autoSizingShouldExpandToViewHeight == shouldExpand) 4034 return; 4035 4036 m_autoSizingShouldExpandToViewHeight = shouldExpand; 4037 4038 corePage()->mainFrame()->view()->setAutoSizeFixedMinimumHeight(shouldExpand ? m_viewSize.height() : 0); 4039} 4040 4041bool WebPage::isSmartInsertDeleteEnabled() 4042{ 4043 return m_page->settings()->smartInsertDeleteEnabled(); 4044} 4045 4046void WebPage::setSmartInsertDeleteEnabled(bool enabled) 4047{ 4048 if (m_page->settings()->smartInsertDeleteEnabled() != enabled) { 4049 m_page->settings()->setSmartInsertDeleteEnabled(enabled); 4050 setSelectTrailingWhitespaceEnabled(!enabled); 4051 } 4052} 4053 4054bool WebPage::isSelectTrailingWhitespaceEnabled() 4055{ 4056 return m_page->settings()->selectTrailingWhitespaceEnabled(); 4057} 4058 4059void WebPage::setSelectTrailingWhitespaceEnabled(bool enabled) 4060{ 4061 if (m_page->settings()->selectTrailingWhitespaceEnabled() != enabled) { 4062 m_page->settings()->setSelectTrailingWhitespaceEnabled(enabled); 4063 setSmartInsertDeleteEnabled(!enabled); 4064 } 4065} 4066 4067bool WebPage::canShowMIMEType(const String& MIMEType) const 4068{ 4069 if (MIMETypeRegistry::canShowMIMEType(MIMEType)) 4070 return true; 4071 4072 if (PluginData* pluginData = m_page->pluginData()) { 4073 if (pluginData->supportsMimeType(MIMEType, PluginData::AllPlugins) && corePage()->mainFrame()->loader()->subframeLoader()->allowPlugins(NotAboutToInstantiatePlugin)) 4074 return true; 4075 4076 // We can use application plugins even if plugins aren't enabled. 4077 if (pluginData->supportsMimeType(MIMEType, PluginData::OnlyApplicationPlugins)) 4078 return true; 4079 } 4080 4081 return false; 4082} 4083 4084void WebPage::addTextCheckingRequest(uint64_t requestID, PassRefPtr<TextCheckingRequest> request) 4085{ 4086 m_pendingTextCheckingRequestMap.add(requestID, request); 4087} 4088 4089void WebPage::didFinishCheckingText(uint64_t requestID, const Vector<TextCheckingResult>& result) 4090{ 4091 TextCheckingRequest* request = m_pendingTextCheckingRequestMap.get(requestID); 4092 if (!request) 4093 return; 4094 4095 request->didSucceed(result); 4096 m_pendingTextCheckingRequestMap.remove(requestID); 4097} 4098 4099void WebPage::didCancelCheckingText(uint64_t requestID) 4100{ 4101 TextCheckingRequest* request = m_pendingTextCheckingRequestMap.get(requestID); 4102 if (!request) 4103 return; 4104 4105 request->didCancel(); 4106 m_pendingTextCheckingRequestMap.remove(requestID); 4107} 4108 4109void WebPage::didCommitLoad(WebFrame* frame) 4110{ 4111 if (!frame->isMainFrame()) 4112 return; 4113 4114 // If previous URL is invalid, then it's not a real page that's being navigated away from. 4115 // Most likely, this is actually the first load to be committed in this page. 4116 if (frame->coreFrame()->loader()->previousURL().isValid()) 4117 reportUsedFeatures(); 4118 4119 // Only restore the scale factor for standard frame loads (of the main frame). 4120 if (frame->coreFrame()->loader()->loadType() == FrameLoadTypeStandard) { 4121 Page* page = frame->coreFrame()->page(); 4122 if (page && page->pageScaleFactor() != 1) 4123 scalePage(1, IntPoint()); 4124 } 4125 4126#if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC) 4127 resetPrimarySnapshottedPlugIn(); 4128#endif 4129 4130 WebProcess::shared().updateActivePages(); 4131} 4132 4133void WebPage::didFinishLoad(WebFrame* frame) 4134{ 4135#if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC) 4136 if (!frame->isMainFrame()) 4137 return; 4138 4139 m_readyToFindPrimarySnapshottedPlugin = true; 4140 LOG(Plugins, "Primary Plug-In Detection: triggering detection from didFinishLoad (marking as ready to detect)."); 4141 m_determinePrimarySnapshottedPlugInTimer.startOneShot(0); 4142#else 4143 UNUSED_PARAM(frame); 4144#endif 4145} 4146 4147#if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC) 4148static int primarySnapshottedPlugInSearchLimit = 3000; 4149static int primarySnapshottedPlugInSearchGap = 200; 4150static float primarySnapshottedPlugInSearchBucketSize = 1.1; 4151static int primarySnapshottedPlugInMinimumWidth = 400; 4152static int primarySnapshottedPlugInMinimumHeight = 300; 4153static unsigned maxPrimarySnapshottedPlugInDetectionAttempts = 2; 4154static int deferredPrimarySnapshottedPlugInDetectionDelay = 3; 4155 4156#if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC) 4157void WebPage::determinePrimarySnapshottedPlugInTimerFired() 4158{ 4159 if (!m_page) 4160 return; 4161 4162 Settings* settings = m_page->settings(); 4163 if (!settings->snapshotAllPlugIns() && settings->primaryPlugInSnapshotDetectionEnabled()) 4164 determinePrimarySnapshottedPlugIn(); 4165} 4166#endif 4167 4168void WebPage::determinePrimarySnapshottedPlugIn() 4169{ 4170 if (!m_page->settings()->plugInSnapshottingEnabled()) 4171 return; 4172 4173 LOG(Plugins, "Primary Plug-In Detection: began."); 4174 4175 if (!m_readyToFindPrimarySnapshottedPlugin) { 4176 LOG(Plugins, "Primary Plug-In Detection: exiting - not ready to find plugins."); 4177 return; 4178 } 4179 4180 if (!m_hasSeenPlugin) { 4181 LOG(Plugins, "Primary Plug-In Detection: exiting - we never saw a plug-in get added to the page."); 4182 return; 4183 } 4184 4185 if (m_didFindPrimarySnapshottedPlugin) { 4186 LOG(Plugins, "Primary Plug-In Detection: exiting - we've already found a primary plug-in."); 4187 return; 4188 } 4189 4190 ++m_numberOfPrimarySnapshotDetectionAttempts; 4191 4192 RenderView* renderView = corePage()->mainFrame()->view()->renderView(); 4193 4194 IntRect searchRect = IntRect(IntPoint(), corePage()->mainFrame()->view()->contentsSize()); 4195 searchRect.intersect(IntRect(IntPoint(), IntSize(primarySnapshottedPlugInSearchLimit, primarySnapshottedPlugInSearchLimit))); 4196 4197 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::AllowChildFrameContent | HitTestRequest::IgnoreClipping | HitTestRequest::DisallowShadowContent); 4198 4199 HashSet<RenderObject*> seenRenderers; 4200 HTMLPlugInImageElement* candidatePlugIn = 0; 4201 unsigned candidatePlugInArea = 0; 4202 4203 for (int x = searchRect.x(); x <= searchRect.width(); x += primarySnapshottedPlugInSearchGap) { 4204 for (int y = searchRect.y(); y <= searchRect.height(); y += primarySnapshottedPlugInSearchGap) { 4205 HitTestResult hitTestResult = HitTestResult(LayoutPoint(x, y)); 4206 renderView->hitTest(request, hitTestResult); 4207 4208 Element* element = hitTestResult.innerElement(); 4209 if (!element) 4210 continue; 4211 4212 RenderObject* renderer = element->renderer(); 4213 if (!renderer || !renderer->isBox()) 4214 continue; 4215 4216 RenderBox* renderBox = toRenderBox(renderer); 4217 4218 if (!seenRenderers.add(renderer).isNewEntry) 4219 continue; 4220 4221 if (!element->isPluginElement()) 4222 continue; 4223 4224 HTMLPlugInElement* plugInElement = toHTMLPlugInElement(element); 4225 if (!plugInElement->isPlugInImageElement()) 4226 continue; 4227 4228 HTMLPlugInImageElement* plugInImageElement = toHTMLPlugInImageElement(plugInElement); 4229 4230 if (plugInElement->displayState() == HTMLPlugInElement::Playing) 4231 continue; 4232 4233 if (renderBox->contentWidth() < primarySnapshottedPlugInMinimumWidth || renderBox->contentHeight() < primarySnapshottedPlugInMinimumHeight) 4234 continue; 4235 4236 LayoutUnit contentArea = renderBox->contentWidth() * renderBox->contentHeight(); 4237 4238 if (contentArea > candidatePlugInArea * primarySnapshottedPlugInSearchBucketSize) { 4239 candidatePlugIn = plugInImageElement; 4240 candidatePlugInArea = contentArea; 4241 } 4242 } 4243 } 4244 4245 if (!candidatePlugIn) { 4246 LOG(Plugins, "Primary Plug-In Detection: fail - did not find a candidate plug-in."); 4247 if (m_numberOfPrimarySnapshotDetectionAttempts < maxPrimarySnapshottedPlugInDetectionAttempts) { 4248 LOG(Plugins, "Primary Plug-In Detection: will attempt again in %ds.", deferredPrimarySnapshottedPlugInDetectionDelay); 4249 m_determinePrimarySnapshottedPlugInTimer.startOneShot(deferredPrimarySnapshottedPlugInDetectionDelay); 4250 } 4251 return; 4252 } 4253 4254 LOG(Plugins, "Primary Plug-In Detection: success - found a candidate plug-in - inform it."); 4255 m_didFindPrimarySnapshottedPlugin = true; 4256 m_primaryPlugInPageOrigin = m_page->mainFrame()->document()->baseURL().host(); 4257 m_primaryPlugInOrigin = candidatePlugIn->loadedUrl().host(); 4258 m_primaryPlugInMimeType = candidatePlugIn->loadedMimeType(); 4259 4260 candidatePlugIn->setIsPrimarySnapshottedPlugIn(true); 4261} 4262 4263void WebPage::resetPrimarySnapshottedPlugIn() 4264{ 4265 m_readyToFindPrimarySnapshottedPlugin = false; 4266 m_didFindPrimarySnapshottedPlugin = false; 4267 m_numberOfPrimarySnapshotDetectionAttempts = 0; 4268 m_hasSeenPlugin = false; 4269} 4270 4271bool WebPage::matchesPrimaryPlugIn(const String& pageOrigin, const String& pluginOrigin, const String& mimeType) const 4272{ 4273 if (!m_didFindPrimarySnapshottedPlugin) 4274 return false; 4275 4276 return (pageOrigin == m_primaryPlugInPageOrigin && pluginOrigin == m_primaryPlugInOrigin && mimeType == m_primaryPlugInMimeType); 4277} 4278#endif // ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC) 4279 4280PassRefPtr<Range> WebPage::currentSelectionAsRange() 4281{ 4282 Frame* frame = frameWithSelection(m_page.get()); 4283 if (!frame) 4284 return 0; 4285 4286 return frame->selection()->toNormalizedRange(); 4287} 4288 4289void WebPage::reportUsedFeatures() 4290{ 4291 // FIXME: Feature names should not be hardcoded. 4292 const BitVector* features = m_page->featureObserver()->accumulatedFeatureBits(); 4293 Vector<String> namedFeatures; 4294 if (features && features->quickGet(FeatureObserver::SharedWorkerStart)) 4295 namedFeatures.append("SharedWorker"); 4296 4297 m_loaderClient.featuresUsedInPage(this, namedFeatures); 4298} 4299 4300unsigned WebPage::extendIncrementalRenderingSuppression() 4301{ 4302 unsigned token = m_maximumRenderingSuppressionToken + 1; 4303 while (!HashSet<unsigned>::isValidValue(token) || m_activeRenderingSuppressionTokens.contains(token)) 4304 token++; 4305 4306 m_activeRenderingSuppressionTokens.add(token); 4307 m_page->mainFrame()->view()->setVisualUpdatesAllowedByClient(false); 4308 4309 m_maximumRenderingSuppressionToken = token; 4310 4311 return token; 4312} 4313 4314void WebPage::stopExtendingIncrementalRenderingSuppression(unsigned token) 4315{ 4316 if (!m_activeRenderingSuppressionTokens.contains(token)) 4317 return; 4318 4319 m_activeRenderingSuppressionTokens.remove(token); 4320 m_page->mainFrame()->view()->setVisualUpdatesAllowedByClient(!shouldExtendIncrementalRenderingSuppression()); 4321} 4322 4323void WebPage::setScrollPinningBehavior(uint32_t pinning) 4324{ 4325 m_scrollPinningBehavior = static_cast<ScrollPinningBehavior>(pinning); 4326 m_page->mainFrame()->view()->setScrollPinningBehavior(m_scrollPinningBehavior); 4327} 4328 4329} // namespace WebKit 4330