1/* 2 * Copyright (C) 2010, 2011 Apple Inc. All rights reserved. 3 * Copyright (C) 2012 Intel Corporation. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 18 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 24 * THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include "config.h" 28#include "WebPageProxy.h" 29 30#include "AuthenticationChallengeProxy.h" 31#include "AuthenticationDecisionListener.h" 32#include "DataReference.h" 33#include "DownloadProxy.h" 34#include "DrawingAreaProxy.h" 35#include "DrawingAreaProxyMessages.h" 36#include "EventDispatcherMessages.h" 37#include "FindIndicator.h" 38#include "ImmutableArray.h" 39#include "Logging.h" 40#include "NativeWebKeyboardEvent.h" 41#include "NativeWebMouseEvent.h" 42#include "NativeWebWheelEvent.h" 43#include "NotificationPermissionRequest.h" 44#include "NotificationPermissionRequestManager.h" 45#include "PageClient.h" 46#include "PluginInformation.h" 47#include "PluginProcessManager.h" 48#include "PrintInfo.h" 49#include "SessionState.h" 50#include "TextChecker.h" 51#include "TextCheckerState.h" 52#include "WKContextPrivate.h" 53#include "WebBackForwardList.h" 54#include "WebBackForwardListItem.h" 55#include "WebCertificateInfo.h" 56#include "WebColorPickerResultListenerProxy.h" 57#include "WebContext.h" 58#include "WebContextMenuProxy.h" 59#include "WebContextUserMessageCoders.h" 60#include "WebCoreArgumentCoders.h" 61#include "WebData.h" 62#include "WebEditCommandProxy.h" 63#include "WebEvent.h" 64#include "WebFormSubmissionListenerProxy.h" 65#include "WebFramePolicyListenerProxy.h" 66#include "WebFullScreenManagerProxy.h" 67#include "WebFullScreenManagerProxyMessages.h" 68#include "WebInspectorProxy.h" 69#include "WebInspectorProxyMessages.h" 70#include "WebNotificationManagerProxy.h" 71#include "WebOpenPanelResultListenerProxy.h" 72#include "WebPageCreationParameters.h" 73#include "WebPageGroup.h" 74#include "WebPageGroupData.h" 75#include "WebPageMessages.h" 76#include "WebPageProxyMessages.h" 77#include "WebPopupItem.h" 78#include "WebPopupMenuProxy.h" 79#include "WebPreferences.h" 80#include "WebProcessMessages.h" 81#include "WebProcessProxy.h" 82#include "WebProtectionSpace.h" 83#include "WebSecurityOrigin.h" 84#include "WebURLRequest.h" 85#include <WebCore/DragController.h> 86#include <WebCore/DragData.h> 87#include <WebCore/DragSession.h> 88#include <WebCore/FloatRect.h> 89#include <WebCore/FocusDirection.h> 90#include <WebCore/MIMETypeRegistry.h> 91#include <WebCore/RenderEmbeddedObject.h> 92#include <WebCore/TextCheckerClient.h> 93#include <WebCore/WindowFeatures.h> 94#include <stdio.h> 95 96#if USE(COORDINATED_GRAPHICS) 97#include "CoordinatedLayerTreeHostProxyMessages.h" 98#endif 99 100#if PLATFORM(QT) 101#include "ArgumentCodersQt.h" 102#endif 103 104#if PLATFORM(GTK) 105#include "ArgumentCodersGtk.h" 106#endif 107 108#if USE(SOUP) 109#include "WebSoupRequestManagerProxy.h" 110#endif 111 112#if ENABLE(VIBRATION) 113#include "WebVibrationProxy.h" 114#endif 115 116#ifndef NDEBUG 117#include <wtf/RefCountedLeakCounter.h> 118#endif 119 120// This controls what strategy we use for mouse wheel coalescing. 121#define MERGE_WHEEL_EVENTS 1 122 123#define MESSAGE_CHECK(assertion) MESSAGE_CHECK_BASE(assertion, m_process->connection()) 124#define MESSAGE_CHECK_URL(url) MESSAGE_CHECK_BASE(m_process->checkURLReceivedFromWebProcess(url), m_process->connection()) 125 126using namespace WebCore; 127 128// Represents the number of wheel events we can hold in the queue before we start pushing them preemptively. 129static const unsigned wheelEventQueueSizeThreshold = 10; 130 131namespace WebKit { 132 133WKPageDebugPaintFlags WebPageProxy::s_debugPaintFlags = 0; 134 135DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, webPageProxyCounter, ("WebPageProxy")); 136 137class ExceededDatabaseQuotaRecords { 138 WTF_MAKE_NONCOPYABLE(ExceededDatabaseQuotaRecords); WTF_MAKE_FAST_ALLOCATED; 139public: 140 struct Record { 141 uint64_t frameID; 142 String originIdentifier; 143 String databaseName; 144 String displayName; 145 uint64_t currentQuota; 146 uint64_t currentOriginUsage; 147 uint64_t currentDatabaseUsage; 148 uint64_t expectedUsage; 149 RefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply> reply; 150 }; 151 152 static ExceededDatabaseQuotaRecords& shared(); 153 154 PassOwnPtr<Record> createRecord(uint64_t frameID, String originIdentifier, 155 String databaseName, String displayName, uint64_t currentQuota, 156 uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage, 157 PassRefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply>); 158 159 void add(PassOwnPtr<Record>); 160 bool areBeingProcessed() const { return m_currentRecord; } 161 Record* next(); 162 163private: 164 ExceededDatabaseQuotaRecords() { } 165 ~ExceededDatabaseQuotaRecords() { } 166 167 Deque<OwnPtr<Record>> m_records; 168 OwnPtr<Record> m_currentRecord; 169}; 170 171ExceededDatabaseQuotaRecords& ExceededDatabaseQuotaRecords::shared() 172{ 173 DEFINE_STATIC_LOCAL(ExceededDatabaseQuotaRecords, records, ()); 174 return records; 175} 176 177PassOwnPtr<ExceededDatabaseQuotaRecords::Record> ExceededDatabaseQuotaRecords::createRecord( 178 uint64_t frameID, String originIdentifier, String databaseName, String displayName, 179 uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, 180 uint64_t expectedUsage, PassRefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply> reply) 181{ 182 OwnPtr<Record> record = adoptPtr(new Record); 183 record->frameID = frameID; 184 record->originIdentifier = originIdentifier; 185 record->databaseName = databaseName; 186 record->displayName = displayName; 187 record->currentQuota = currentQuota; 188 record->currentOriginUsage = currentOriginUsage; 189 record->currentDatabaseUsage = currentDatabaseUsage; 190 record->expectedUsage = expectedUsage; 191 record->reply = reply; 192 return record.release(); 193} 194 195void ExceededDatabaseQuotaRecords::add(PassOwnPtr<ExceededDatabaseQuotaRecords::Record> record) 196{ 197 m_records.append(record); 198} 199 200ExceededDatabaseQuotaRecords::Record* ExceededDatabaseQuotaRecords::next() 201{ 202 m_currentRecord.clear(); 203 if (!m_records.isEmpty()) 204 m_currentRecord = m_records.takeFirst(); 205 return m_currentRecord.get(); 206} 207 208#if !LOG_DISABLED 209static const char* webKeyboardEventTypeString(WebEvent::Type type) 210{ 211 switch (type) { 212 case WebEvent::KeyDown: 213 return "KeyDown"; 214 215 case WebEvent::KeyUp: 216 return "KeyUp"; 217 218 case WebEvent::RawKeyDown: 219 return "RawKeyDown"; 220 221 case WebEvent::Char: 222 return "Char"; 223 224 default: 225 ASSERT_NOT_REACHED(); 226 return "<unknown>"; 227 } 228} 229#endif // !LOG_DISABLED 230 231PassRefPtr<WebPageProxy> WebPageProxy::create(PageClient* pageClient, PassRefPtr<WebProcessProxy> process, WebPageGroup* pageGroup, uint64_t pageID) 232{ 233 return adoptRef(new WebPageProxy(pageClient, process, pageGroup, pageID)); 234} 235 236WebPageProxy::WebPageProxy(PageClient* pageClient, PassRefPtr<WebProcessProxy> process, WebPageGroup* pageGroup, uint64_t pageID) 237 : m_pageClient(pageClient) 238 , m_process(process) 239 , m_pageGroup(pageGroup) 240 , m_mainFrame(0) 241 , m_userAgent(standardUserAgent()) 242 , m_geolocationPermissionRequestManager(this) 243 , m_notificationPermissionRequestManager(this) 244 , m_estimatedProgress(0) 245 , m_isInWindow(m_pageClient->isViewInWindow()) 246 , m_isVisible(m_pageClient->isViewVisible()) 247 , m_backForwardList(WebBackForwardList::create(this)) 248 , m_loadStateAtProcessExit(WebFrameProxy::LoadStateFinished) 249 , m_temporarilyClosedComposition(false) 250 , m_textZoomFactor(1) 251 , m_pageZoomFactor(1) 252 , m_pageScaleFactor(1) 253 , m_intrinsicDeviceScaleFactor(1) 254 , m_customDeviceScaleFactor(0) 255#if HAVE(LAYER_HOSTING_IN_WINDOW_SERVER) 256 , m_layerHostingMode(LayerHostingModeInWindowServer) 257#else 258 , m_layerHostingMode(LayerHostingModeDefault) 259#endif 260 , m_drawsBackground(true) 261 , m_drawsTransparentBackground(false) 262 , m_areMemoryCacheClientCallsEnabled(true) 263 , m_useFixedLayout(false) 264 , m_suppressScrollbarAnimations(false) 265 , m_paginationMode(Pagination::Unpaginated) 266 , m_paginationBehavesLikeColumns(false) 267 , m_pageLength(0) 268 , m_gapBetweenPages(0) 269 , m_isValid(true) 270 , m_isClosed(false) 271 , m_canRunModal(false) 272 , m_isInPrintingMode(false) 273 , m_isPerformingDOMPrintOperation(false) 274 , m_inDecidePolicyForResponseSync(false) 275 , m_decidePolicyForResponseRequest(0) 276 , m_syncMimeTypePolicyActionIsValid(false) 277 , m_syncMimeTypePolicyAction(PolicyUse) 278 , m_syncMimeTypePolicyDownloadID(0) 279 , m_inDecidePolicyForNavigationAction(false) 280 , m_syncNavigationActionPolicyActionIsValid(false) 281 , m_syncNavigationActionPolicyAction(PolicyUse) 282 , m_syncNavigationActionPolicyDownloadID(0) 283 , m_processingMouseMoveEvent(false) 284#if ENABLE(TOUCH_EVENTS) 285 , m_needTouchEvents(false) 286#endif 287 , m_pageID(pageID) 288 , m_isPageSuspended(false) 289#if PLATFORM(MAC) 290 , m_isSmartInsertDeleteEnabled(TextChecker::isSmartInsertDeleteEnabled()) 291#endif 292 , m_spellDocumentTag(0) 293 , m_hasSpellDocumentTag(false) 294 , m_pendingLearnOrIgnoreWordMessageCount(0) 295 , m_mainFrameHasCustomRepresentation(false) 296 , m_mainFrameHasHorizontalScrollbar(false) 297 , m_mainFrameHasVerticalScrollbar(false) 298 , m_canShortCircuitHorizontalWheelEvents(true) 299 , m_mainFrameIsPinnedToLeftSide(false) 300 , m_mainFrameIsPinnedToRightSide(false) 301 , m_mainFrameIsPinnedToTopSide(false) 302 , m_mainFrameIsPinnedToBottomSide(false) 303 , m_rubberBandsAtBottom(false) 304 , m_rubberBandsAtTop(false) 305 , m_mainFrameInViewSourceMode(false) 306 , m_pageCount(0) 307 , m_renderTreeSize(0) 308 , m_shouldSendEventsSynchronously(false) 309 , m_suppressVisibilityUpdates(false) 310 , m_autoSizingShouldExpandToViewHeight(false) 311 , m_mediaVolume(1) 312 , m_mayStartMediaWhenInWindow(true) 313 , m_waitingForDidUpdateInWindowState(false) 314#if PLATFORM(MAC) 315 , m_exposedRectChangedTimer(this, &WebPageProxy::exposedRectChangedTimerFired) 316 , m_clipsToExposedRect(false) 317 , m_lastSentClipsToExposedRect(false) 318#endif 319#if ENABLE(PAGE_VISIBILITY_API) 320 , m_visibilityState(PageVisibilityStateVisible) 321#endif 322 , m_scrollPinningBehavior(DoNotPin) 323{ 324#if ENABLE(PAGE_VISIBILITY_API) 325 if (!m_isVisible) 326 m_visibilityState = PageVisibilityStateHidden; 327#endif 328#ifndef NDEBUG 329 webPageProxyCounter.increment(); 330#endif 331 332 WebContext::statistics().wkPageCount++; 333 334 m_pageGroup->addPage(this); 335 336#if ENABLE(INSPECTOR) 337 m_inspector = WebInspectorProxy::create(this); 338#endif 339#if ENABLE(FULLSCREEN_API) 340 m_fullScreenManager = WebFullScreenManagerProxy::create(this); 341#endif 342#if ENABLE(VIBRATION) 343 m_vibration = WebVibrationProxy::create(this); 344#endif 345#if ENABLE(THREADED_SCROLLING) 346 m_rubberBandsAtBottom = true; 347 m_rubberBandsAtTop = true; 348#endif 349 350 m_process->addMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID, this); 351 352 // FIXME: If we ever expose the session storage size as a preference, we need to pass it here. 353 m_process->context()->storageManager().createSessionStorageNamespace(m_pageID, m_process->isValid() ? m_process->connection() : 0, std::numeric_limits<unsigned>::max()); 354} 355 356WebPageProxy::~WebPageProxy() 357{ 358 if (!m_isClosed) 359 close(); 360 361 WebContext::statistics().wkPageCount--; 362 363 if (m_hasSpellDocumentTag) 364 TextChecker::closeSpellDocumentWithTag(m_spellDocumentTag); 365 366 m_pageGroup->removePage(this); 367 368#ifndef NDEBUG 369 webPageProxyCounter.decrement(); 370#endif 371} 372 373WebProcessProxy* WebPageProxy::process() const 374{ 375 return m_process.get(); 376} 377 378PlatformProcessIdentifier WebPageProxy::processIdentifier() const 379{ 380 if (m_isClosed) 381 return 0; 382 383 return m_process->processIdentifier(); 384} 385 386bool WebPageProxy::isValid() const 387{ 388 // A page that has been explicitly closed is never valid. 389 if (m_isClosed) 390 return false; 391 392 return m_isValid; 393} 394 395PassRefPtr<ImmutableArray> WebPageProxy::relatedPages() const 396{ 397 // pages() returns a list of pages in WebProcess, so this page may or may not be among them - a client can use a reference to WebPageProxy after the page has closed. 398 Vector<WebPageProxy*> pages = m_process->pages(); 399 400 Vector<RefPtr<APIObject>> result; 401 result.reserveCapacity(pages.size()); 402 for (size_t i = 0; i < pages.size(); ++i) { 403 if (pages[i] != this) 404 result.append(pages[i]); 405 } 406 407 return ImmutableArray::adopt(result); 408} 409 410void WebPageProxy::initializeLoaderClient(const WKPageLoaderClient* loadClient) 411{ 412 m_loaderClient.initialize(loadClient); 413 414 if (!loadClient) 415 return; 416 417 // It would be nice to get rid of this code and transition all clients to using didLayout instead of 418 // didFirstLayoutInFrame and didFirstVisuallyNonEmptyLayoutInFrame. In the meantime, this is required 419 // for backwards compatibility. 420 WebCore::LayoutMilestones milestones = 0; 421 if (loadClient->didFirstLayoutForFrame) 422 milestones |= WebCore::DidFirstLayout; 423 if (loadClient->didFirstVisuallyNonEmptyLayoutForFrame) 424 milestones |= WebCore::DidFirstVisuallyNonEmptyLayout; 425 if (loadClient->didNewFirstVisuallyNonEmptyLayout) 426 milestones |= WebCore::DidHitRelevantRepaintedObjectsAreaThreshold; 427 428 if (milestones) 429 m_process->send(Messages::WebPage::ListenForLayoutMilestones(milestones), m_pageID); 430 431 m_process->send(Messages::WebPage::SetWillGoToBackForwardItemCallbackEnabled(loadClient->version > 0), m_pageID); 432} 433 434void WebPageProxy::initializePolicyClient(const WKPagePolicyClient* policyClient) 435{ 436 m_policyClient.initialize(policyClient); 437} 438 439void WebPageProxy::initializeFormClient(const WKPageFormClient* formClient) 440{ 441 m_formClient.initialize(formClient); 442} 443 444void WebPageProxy::initializeUIClient(const WKPageUIClient* client) 445{ 446 if (!isValid()) 447 return; 448 449 m_uiClient.initialize(client); 450 451 m_process->send(Messages::WebPage::SetCanRunBeforeUnloadConfirmPanel(m_uiClient.canRunBeforeUnloadConfirmPanel()), m_pageID); 452 setCanRunModal(m_uiClient.canRunModal()); 453} 454 455void WebPageProxy::initializeFindClient(const WKPageFindClient* client) 456{ 457 m_findClient.initialize(client); 458} 459 460void WebPageProxy::initializeFindMatchesClient(const WKPageFindMatchesClient* client) 461{ 462 m_findMatchesClient.initialize(client); 463} 464 465#if ENABLE(CONTEXT_MENUS) 466void WebPageProxy::initializeContextMenuClient(const WKPageContextMenuClient* client) 467{ 468 m_contextMenuClient.initialize(client); 469} 470#endif 471 472void WebPageProxy::reattachToWebProcess() 473{ 474 ASSERT(!isValid()); 475 ASSERT(m_process); 476 ASSERT(!m_process->isValid()); 477 ASSERT(!m_process->isLaunching()); 478 479 m_isValid = true; 480 481 if (m_process->context()->processModel() == ProcessModelSharedSecondaryProcess) 482 m_process = m_process->context()->ensureSharedWebProcess(); 483 else 484 m_process = m_process->context()->createNewWebProcessRespectingProcessCountLimit(); 485 m_process->addExistingWebPage(this, m_pageID); 486 m_process->addMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID, this); 487 488#if ENABLE(INSPECTOR) 489 m_inspector = WebInspectorProxy::create(this); 490#endif 491#if ENABLE(FULLSCREEN_API) 492 m_fullScreenManager = WebFullScreenManagerProxy::create(this); 493#endif 494 495 initializeWebPage(); 496 497 m_pageClient->didRelaunchProcess(); 498 m_drawingArea->waitForBackingStoreUpdateOnNextPaint(); 499} 500 501void WebPageProxy::reattachToWebProcessWithItem(WebBackForwardListItem* item) 502{ 503 if (item && item != m_backForwardList->currentItem()) 504 m_backForwardList->goToItem(item); 505 506 reattachToWebProcess(); 507 508 if (!item) 509 return; 510 511 m_process->send(Messages::WebPage::GoToBackForwardItem(item->itemID()), m_pageID); 512 m_process->responsivenessTimer()->start(); 513} 514 515void WebPageProxy::initializeWebPage() 516{ 517 ASSERT(isValid()); 518 519 BackForwardListItemVector items = m_backForwardList->entries(); 520 for (size_t i = 0; i < items.size(); ++i) 521 m_process->registerNewWebBackForwardListItem(items[i].get()); 522 523 m_drawingArea = m_pageClient->createDrawingAreaProxy(); 524 ASSERT(m_drawingArea); 525 526#if ENABLE(INSPECTOR_SERVER) 527 if (m_pageGroup->preferences()->developerExtrasEnabled()) 528 inspector()->enableRemoteInspection(); 529#endif 530 531 m_process->send(Messages::WebProcess::CreateWebPage(m_pageID, creationParameters()), 0); 532 533#if ENABLE(PAGE_VISIBILITY_API) 534 m_process->send(Messages::WebPage::SetVisibilityState(m_visibilityState, /* isInitialState */ true), m_pageID); 535#elif ENABLE(HIDDEN_PAGE_DOM_TIMER_THROTTLING) 536 m_process->send(Messages::WebPage::SetVisibilityState(m_isVisible ? PageVisibilityStateVisible : PageVisibilityStateHidden, /* isInitialState */ true), m_pageID); 537#endif 538 539#if PLATFORM(MAC) 540 m_process->send(Messages::WebPage::SetSmartInsertDeleteEnabled(m_isSmartInsertDeleteEnabled), m_pageID); 541#endif 542} 543 544void WebPageProxy::close() 545{ 546 if (!isValid()) 547 return; 548 549 m_isClosed = true; 550 551 m_backForwardList->pageClosed(); 552 m_pageClient->pageClosed(); 553 554 m_process->disconnectFramesFromPage(this); 555 m_mainFrame = 0; 556 557#if ENABLE(INSPECTOR) 558 if (m_inspector) { 559 m_inspector->invalidate(); 560 m_inspector = 0; 561 } 562#endif 563 564#if ENABLE(FULLSCREEN_API) 565 if (m_fullScreenManager) { 566 m_fullScreenManager->invalidate(); 567 m_fullScreenManager = 0; 568 } 569#endif 570 571#if ENABLE(VIBRATION) 572 m_vibration->invalidate(); 573#endif 574 575 if (m_openPanelResultListener) { 576 m_openPanelResultListener->invalidate(); 577 m_openPanelResultListener = 0; 578 } 579 580#if ENABLE(INPUT_TYPE_COLOR) 581 if (m_colorChooser) { 582 m_colorChooser->invalidate(); 583 m_colorChooser = nullptr; 584 } 585 586 if (m_colorPickerResultListener) { 587 m_colorPickerResultListener->invalidate(); 588 m_colorPickerResultListener = nullptr; 589 } 590#endif 591 592#if ENABLE(GEOLOCATION) 593 m_geolocationPermissionRequestManager.invalidateRequests(); 594#endif 595 596 m_notificationPermissionRequestManager.invalidateRequests(); 597 m_process->context()->supplement<WebNotificationManagerProxy>()->clearNotifications(this); 598 599 m_toolTip = String(); 600 601 m_mainFrameHasHorizontalScrollbar = false; 602 m_mainFrameHasVerticalScrollbar = false; 603 604 m_mainFrameIsPinnedToLeftSide = false; 605 m_mainFrameIsPinnedToRightSide = false; 606 m_mainFrameIsPinnedToTopSide = false; 607 m_mainFrameIsPinnedToBottomSide = false; 608 609 m_visibleScrollerThumbRect = IntRect(); 610 611 invalidateCallbackMap(m_voidCallbacks); 612 invalidateCallbackMap(m_dataCallbacks); 613 invalidateCallbackMap(m_imageCallbacks); 614 invalidateCallbackMap(m_stringCallbacks); 615 m_loadDependentStringCallbackIDs.clear(); 616 invalidateCallbackMap(m_scriptValueCallbacks); 617 invalidateCallbackMap(m_computedPagesCallbacks); 618#if PLATFORM(GTK) 619 invalidateCallbackMap(m_printFinishedCallbacks); 620#endif 621 622 Vector<WebEditCommandProxy*> editCommandVector; 623 copyToVector(m_editCommandSet, editCommandVector); 624 m_editCommandSet.clear(); 625 for (size_t i = 0, size = editCommandVector.size(); i < size; ++i) 626 editCommandVector[i]->invalidate(); 627 628 m_activePopupMenu = 0; 629 630 m_estimatedProgress = 0.0; 631 632 m_loaderClient.initialize(0); 633 m_policyClient.initialize(0); 634 m_uiClient.initialize(0); 635#if PLATFORM(EFL) 636 m_uiPopupMenuClient.initialize(0); 637#endif 638 639 m_drawingArea = nullptr; 640 641#if PLATFORM(MAC) 642 m_exposedRectChangedTimer.stop(); 643#endif 644 645 m_process->send(Messages::WebPage::Close(), m_pageID); 646 m_process->removeWebPage(m_pageID); 647 m_process->removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID); 648 m_process->context()->storageManager().destroySessionStorageNamespace(m_pageID); 649} 650 651bool WebPageProxy::tryClose() 652{ 653 if (!isValid()) 654 return true; 655 656 m_process->send(Messages::WebPage::TryClose(), m_pageID); 657 m_process->responsivenessTimer()->start(); 658 return false; 659} 660 661bool WebPageProxy::maybeInitializeSandboxExtensionHandle(const KURL& url, SandboxExtension::Handle& sandboxExtensionHandle) 662{ 663 if (!url.isLocalFile()) 664 return false; 665 666 if (m_process->hasAssumedReadAccessToURL(url)) 667 return false; 668 669#if ENABLE(INSPECTOR) 670 // Inspector resources are in a directory with assumed access. 671 ASSERT_WITH_SECURITY_IMPLICATION(!WebInspectorProxy::isInspectorPage(this)); 672#endif 673 674 SandboxExtension::createHandle("/", SandboxExtension::ReadOnly, sandboxExtensionHandle); 675 return true; 676} 677 678void WebPageProxy::loadURL(const String& url, APIObject* userData) 679{ 680 setPendingAPIRequestURL(url); 681 682 if (!isValid()) 683 reattachToWebProcess(); 684 685 SandboxExtension::Handle sandboxExtensionHandle; 686 bool createdExtension = maybeInitializeSandboxExtensionHandle(KURL(KURL(), url), sandboxExtensionHandle); 687 if (createdExtension) 688 m_process->willAcquireUniversalFileReadSandboxExtension(); 689 m_process->send(Messages::WebPage::LoadURL(url, sandboxExtensionHandle, WebContextUserMessageEncoder(userData)), m_pageID); 690 m_process->responsivenessTimer()->start(); 691} 692 693void WebPageProxy::loadURLRequest(WebURLRequest* urlRequest, APIObject* userData) 694{ 695 setPendingAPIRequestURL(urlRequest->resourceRequest().url()); 696 697 if (!isValid()) 698 reattachToWebProcess(); 699 700 SandboxExtension::Handle sandboxExtensionHandle; 701 bool createdExtension = maybeInitializeSandboxExtensionHandle(urlRequest->resourceRequest().url(), sandboxExtensionHandle); 702 if (createdExtension) 703 m_process->willAcquireUniversalFileReadSandboxExtension(); 704 m_process->send(Messages::WebPage::LoadURLRequest(urlRequest->resourceRequest(), sandboxExtensionHandle, WebContextUserMessageEncoder(userData)), m_pageID); 705 m_process->responsivenessTimer()->start(); 706} 707 708void WebPageProxy::loadFile(const String& fileURLString, const String& resourceDirectoryURLString, APIObject* userData) 709{ 710 if (!isValid()) 711 reattachToWebProcess(); 712 713 KURL fileURL = KURL(KURL(), fileURLString); 714 if (!fileURL.isLocalFile()) 715 return; 716 717 KURL resourceDirectoryURL; 718 if (resourceDirectoryURLString.isNull()) 719 resourceDirectoryURL = KURL(ParsedURLString, ASCIILiteral("file:///")); 720 else { 721 resourceDirectoryURL = KURL(KURL(), resourceDirectoryURLString); 722 if (!resourceDirectoryURL.isLocalFile()) 723 return; 724 } 725 726 String resourceDirectoryPath = resourceDirectoryURL.fileSystemPath(); 727 728 SandboxExtension::Handle sandboxExtensionHandle; 729 SandboxExtension::createHandle(resourceDirectoryPath, SandboxExtension::ReadOnly, sandboxExtensionHandle); 730 m_process->assumeReadAccessToBaseURL(resourceDirectoryURL); 731 m_process->send(Messages::WebPage::LoadURL(fileURL, sandboxExtensionHandle, WebContextUserMessageEncoder(userData)), m_pageID); 732 m_process->responsivenessTimer()->start(); 733} 734 735void WebPageProxy::loadData(WebData* data, const String& MIMEType, const String& encoding, const String& baseURL, APIObject* userData) 736{ 737 if (!isValid()) 738 reattachToWebProcess(); 739 740 m_process->assumeReadAccessToBaseURL(baseURL); 741 m_process->send(Messages::WebPage::LoadData(data->dataReference(), MIMEType, encoding, baseURL, WebContextUserMessageEncoder(userData)), m_pageID); 742 m_process->responsivenessTimer()->start(); 743} 744 745void WebPageProxy::loadHTMLString(const String& htmlString, const String& baseURL, APIObject* userData) 746{ 747 if (!isValid()) 748 reattachToWebProcess(); 749 750 m_process->assumeReadAccessToBaseURL(baseURL); 751 m_process->send(Messages::WebPage::LoadHTMLString(htmlString, baseURL, WebContextUserMessageEncoder(userData)), m_pageID); 752 m_process->responsivenessTimer()->start(); 753} 754 755void WebPageProxy::loadAlternateHTMLString(const String& htmlString, const String& baseURL, const String& unreachableURL, APIObject* userData) 756{ 757 if (!isValid()) 758 reattachToWebProcess(); 759 760 if (m_mainFrame) 761 m_mainFrame->setUnreachableURL(unreachableURL); 762 763 m_process->assumeReadAccessToBaseURL(baseURL); 764 m_process->send(Messages::WebPage::LoadAlternateHTMLString(htmlString, baseURL, unreachableURL, WebContextUserMessageEncoder(userData)), m_pageID); 765 m_process->responsivenessTimer()->start(); 766} 767 768void WebPageProxy::loadPlainTextString(const String& string, APIObject* userData) 769{ 770 if (!isValid()) 771 reattachToWebProcess(); 772 773 m_process->send(Messages::WebPage::LoadPlainTextString(string, WebContextUserMessageEncoder(userData)), m_pageID); 774 m_process->responsivenessTimer()->start(); 775} 776 777void WebPageProxy::loadWebArchiveData(const WebData* webArchiveData, APIObject* userData) 778{ 779 if (!isValid()) 780 reattachToWebProcess(); 781 782 m_process->send(Messages::WebPage::LoadWebArchiveData(webArchiveData->dataReference(), WebContextUserMessageEncoder(userData)), m_pageID); 783 m_process->responsivenessTimer()->start(); 784} 785 786void WebPageProxy::stopLoading() 787{ 788 if (!isValid()) 789 return; 790 791 m_process->send(Messages::WebPage::StopLoading(), m_pageID); 792 m_process->responsivenessTimer()->start(); 793} 794 795void WebPageProxy::reload(bool reloadFromOrigin) 796{ 797 SandboxExtension::Handle sandboxExtensionHandle; 798 799 if (m_backForwardList->currentItem()) { 800 String url = m_backForwardList->currentItem()->url(); 801 setPendingAPIRequestURL(url); 802 803 // We may not have an extension yet if back/forward list was reinstated after a WebProcess crash or a browser relaunch 804 bool createdExtension = maybeInitializeSandboxExtensionHandle(KURL(KURL(), url), sandboxExtensionHandle); 805 if (createdExtension) 806 m_process->willAcquireUniversalFileReadSandboxExtension(); 807 } 808 809 if (!isValid()) { 810 reattachToWebProcessWithItem(m_backForwardList->currentItem()); 811 return; 812 } 813 814 m_process->send(Messages::WebPage::Reload(reloadFromOrigin, sandboxExtensionHandle), m_pageID); 815 m_process->responsivenessTimer()->start(); 816} 817 818void WebPageProxy::goForward() 819{ 820 if (isValid() && !canGoForward()) 821 return; 822 823 WebBackForwardListItem* forwardItem = m_backForwardList->forwardItem(); 824 if (!forwardItem) 825 return; 826 827 setPendingAPIRequestURL(forwardItem->url()); 828 829 if (!isValid()) { 830 reattachToWebProcessWithItem(forwardItem); 831 return; 832 } 833 834 m_process->send(Messages::WebPage::GoForward(forwardItem->itemID()), m_pageID); 835 m_process->responsivenessTimer()->start(); 836} 837 838bool WebPageProxy::canGoForward() const 839{ 840 return m_backForwardList->forwardItem(); 841} 842 843void WebPageProxy::goBack() 844{ 845 if (isValid() && !canGoBack()) 846 return; 847 848 WebBackForwardListItem* backItem = m_backForwardList->backItem(); 849 if (!backItem) 850 return; 851 852 setPendingAPIRequestURL(backItem->url()); 853 854 if (!isValid()) { 855 reattachToWebProcessWithItem(backItem); 856 return; 857 } 858 859 m_process->send(Messages::WebPage::GoBack(backItem->itemID()), m_pageID); 860 m_process->responsivenessTimer()->start(); 861} 862 863bool WebPageProxy::canGoBack() const 864{ 865 return m_backForwardList->backItem(); 866} 867 868void WebPageProxy::goToBackForwardItem(WebBackForwardListItem* item) 869{ 870 if (!isValid()) { 871 reattachToWebProcessWithItem(item); 872 return; 873 } 874 875 setPendingAPIRequestURL(item->url()); 876 877 m_process->send(Messages::WebPage::GoToBackForwardItem(item->itemID()), m_pageID); 878 m_process->responsivenessTimer()->start(); 879} 880 881void WebPageProxy::tryRestoreScrollPosition() 882{ 883 if (!isValid()) 884 return; 885 886 m_process->send(Messages::WebPage::TryRestoreScrollPosition(), m_pageID); 887} 888 889void WebPageProxy::didChangeBackForwardList(WebBackForwardListItem* added, Vector<RefPtr<APIObject>>* removed) 890{ 891 m_loaderClient.didChangeBackForwardList(this, added, removed); 892} 893 894void WebPageProxy::shouldGoToBackForwardListItem(uint64_t itemID, bool& shouldGoToBackForwardItem) 895{ 896 WebBackForwardListItem* item = m_process->webBackForwardItem(itemID); 897 shouldGoToBackForwardItem = item && m_loaderClient.shouldGoToBackForwardListItem(this, item); 898} 899 900void WebPageProxy::willGoToBackForwardListItem(uint64_t itemID, CoreIPC::MessageDecoder& decoder) 901{ 902 RefPtr<APIObject> userData; 903 WebContextUserMessageDecoder messageDecoder(userData, m_process.get()); 904 if (!decoder.decode(messageDecoder)) 905 return; 906 907 if (WebBackForwardListItem* item = m_process->webBackForwardItem(itemID)) 908 m_loaderClient.willGoToBackForwardListItem(this, item, userData.get()); 909} 910 911String WebPageProxy::activeURL() const 912{ 913 // If there is a currently pending url, it is the active URL, 914 // even when there's no main frame yet, as it might be the 915 // first API request. 916 if (!m_pendingAPIRequestURL.isNull()) 917 return m_pendingAPIRequestURL; 918 919 if (!m_mainFrame) 920 return String(); 921 922 if (!m_mainFrame->unreachableURL().isEmpty()) 923 return m_mainFrame->unreachableURL(); 924 925 switch (m_mainFrame->loadState()) { 926 case WebFrameProxy::LoadStateProvisional: 927 return m_mainFrame->provisionalURL(); 928 case WebFrameProxy::LoadStateCommitted: 929 case WebFrameProxy::LoadStateFinished: 930 return m_mainFrame->url(); 931 } 932 933 ASSERT_NOT_REACHED(); 934 return String(); 935} 936 937String WebPageProxy::provisionalURL() const 938{ 939 if (!m_mainFrame) 940 return String(); 941 return m_mainFrame->provisionalURL(); 942} 943 944String WebPageProxy::committedURL() const 945{ 946 if (!m_mainFrame) 947 return String(); 948 949 return m_mainFrame->url(); 950} 951 952bool WebPageProxy::canShowMIMEType(const String& mimeType) const 953{ 954 if (MIMETypeRegistry::canShowMIMEType(mimeType)) 955 return true; 956 957#if ENABLE(NETSCAPE_PLUGIN_API) 958 String newMimeType = mimeType; 959 PluginModuleInfo plugin = m_process->context()->pluginInfoStore().findPlugin(newMimeType, KURL()); 960 if (!plugin.path.isNull() && m_pageGroup->preferences()->pluginsEnabled()) 961 return true; 962#endif // ENABLE(NETSCAPE_PLUGIN_API) 963 964#if PLATFORM(MAC) 965 // On Mac, we can show PDFs. 966 if (MIMETypeRegistry::isPDFOrPostScriptMIMEType(mimeType) && !WebContext::omitPDFSupport()) 967 return true; 968#endif // PLATFORM(MAC) 969 970 return false; 971} 972 973void WebPageProxy::setDrawsBackground(bool drawsBackground) 974{ 975 if (m_drawsBackground == drawsBackground) 976 return; 977 978 m_drawsBackground = drawsBackground; 979 980 if (isValid()) 981 m_process->send(Messages::WebPage::SetDrawsBackground(drawsBackground), m_pageID); 982} 983 984void WebPageProxy::setDrawsTransparentBackground(bool drawsTransparentBackground) 985{ 986 if (m_drawsTransparentBackground == drawsTransparentBackground) 987 return; 988 989 m_drawsTransparentBackground = drawsTransparentBackground; 990 991 if (isValid()) 992 m_process->send(Messages::WebPage::SetDrawsTransparentBackground(drawsTransparentBackground), m_pageID); 993} 994 995void WebPageProxy::setUnderlayColor(const Color& color) 996{ 997 if (m_underlayColor == color) 998 return; 999 1000 m_underlayColor = color; 1001 1002 if (isValid()) 1003 m_process->send(Messages::WebPage::SetUnderlayColor(color), m_pageID); 1004} 1005 1006void WebPageProxy::viewWillStartLiveResize() 1007{ 1008 if (!isValid()) 1009 return; 1010 m_process->send(Messages::WebPage::ViewWillStartLiveResize(), m_pageID); 1011} 1012 1013void WebPageProxy::viewWillEndLiveResize() 1014{ 1015 if (!isValid()) 1016 return; 1017 m_process->send(Messages::WebPage::ViewWillEndLiveResize(), m_pageID); 1018} 1019 1020void WebPageProxy::setViewNeedsDisplay(const IntRect& rect) 1021{ 1022 m_pageClient->setViewNeedsDisplay(rect); 1023} 1024 1025void WebPageProxy::displayView() 1026{ 1027 m_pageClient->displayView(); 1028} 1029 1030bool WebPageProxy::canScrollView() 1031{ 1032 return m_pageClient->canScrollView(); 1033} 1034 1035void WebPageProxy::scrollView(const IntRect& scrollRect, const IntSize& scrollOffset) 1036{ 1037 m_pageClient->scrollView(scrollRect, scrollOffset); 1038} 1039 1040void WebPageProxy::viewInWindowStateDidChange(WantsReplyOrNot wantsReply) 1041{ 1042 if (!isValid()) 1043 return; 1044 1045 bool isInWindow = m_pageClient->isViewInWindow(); 1046 if (m_isInWindow != isInWindow) { 1047 m_isInWindow = isInWindow; 1048 m_process->send(Messages::WebPage::SetIsInWindow(isInWindow, wantsReply == WantsReplyOrNot::DoesWantReply), m_pageID); 1049 } 1050 1051 if (isInWindow) { 1052 LayerHostingMode layerHostingMode = m_pageClient->viewLayerHostingMode(); 1053 if (m_layerHostingMode != layerHostingMode) { 1054 m_layerHostingMode = layerHostingMode; 1055 m_drawingArea->layerHostingModeDidChange(); 1056 } 1057 } 1058} 1059 1060void WebPageProxy::viewStateDidChange(ViewStateFlags flags) 1061{ 1062 if (!isValid()) 1063 return; 1064 1065 if (flags & ViewIsFocused) 1066 m_process->send(Messages::WebPage::SetFocused(m_pageClient->isViewFocused()), m_pageID); 1067 1068 if (flags & ViewWindowIsActive) 1069 m_process->send(Messages::WebPage::SetActive(m_pageClient->isViewWindowActive()), m_pageID); 1070 1071 if (flags & ViewIsVisible) { 1072 bool isVisible = m_pageClient->isViewVisible(); 1073 if (isVisible != m_isVisible) { 1074 m_isVisible = isVisible; 1075 m_process->pageVisibilityChanged(this); 1076 m_drawingArea->visibilityDidChange(); 1077 1078 if (!m_isVisible) { 1079 // If we've started the responsiveness timer as part of telling the web process to update the backing store 1080 // state, it might not send back a reply (since it won't paint anything if the web page is hidden) so we 1081 // stop the unresponsiveness timer here. 1082 m_process->responsivenessTimer()->stop(); 1083 } 1084 1085#if ENABLE(HIDDEN_PAGE_DOM_TIMER_THROTTLING) && !ENABLE(PAGE_VISIBILITY_API) 1086 PageVisibilityState visibilityState = m_isVisible ? PageVisibilityStateVisible : PageVisibilityStateHidden; 1087 m_process->send(Messages::WebPage::SetVisibilityState(visibilityState, false), m_pageID); 1088#endif 1089 } 1090 } 1091 1092 if (flags & ViewIsInWindow) 1093 viewInWindowStateDidChange(); 1094 1095#if ENABLE(PAGE_VISIBILITY_API) 1096 PageVisibilityState visibilityState = PageVisibilityStateHidden; 1097 1098 if (m_isVisible) 1099 visibilityState = PageVisibilityStateVisible; 1100 1101 if (visibilityState != m_visibilityState) { 1102 m_visibilityState = visibilityState; 1103 m_process->send(Messages::WebPage::SetVisibilityState(visibilityState, false), m_pageID); 1104 } 1105#endif 1106 1107 updateBackingStoreDiscardableState(); 1108} 1109 1110void WebPageProxy::waitForDidUpdateInWindowState() 1111{ 1112 // If we have previously timed out with no response from the WebProcess, don't block the UIProcess again until it starts responding. 1113 if (m_waitingForDidUpdateInWindowState) 1114 return; 1115 1116 if (!isValid()) 1117 return; 1118 1119 m_waitingForDidUpdateInWindowState = true; 1120 1121 if (!m_process->isLaunching()) { 1122 const double inWindowStateUpdateTimeout = 0.25; 1123 m_process->connection()->waitForAndDispatchImmediately<Messages::WebPageProxy::DidUpdateInWindowState>(m_pageID, inWindowStateUpdateTimeout); 1124 } 1125} 1126 1127IntSize WebPageProxy::viewSize() const 1128{ 1129 return m_pageClient->viewSize(); 1130} 1131 1132void WebPageProxy::setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent& keyboardEvent) 1133{ 1134 if (!isValid()) 1135 return; 1136 m_process->send(Messages::WebPage::SetInitialFocus(forward, isKeyboardEventValid, keyboardEvent), m_pageID); 1137} 1138 1139void WebPageProxy::setWindowResizerSize(const IntSize& windowResizerSize) 1140{ 1141 if (!isValid()) 1142 return; 1143 m_process->send(Messages::WebPage::SetWindowResizerSize(windowResizerSize), m_pageID); 1144} 1145 1146void WebPageProxy::clearSelection() 1147{ 1148 if (!isValid()) 1149 return; 1150 m_process->send(Messages::WebPage::ClearSelection(), m_pageID); 1151} 1152 1153void WebPageProxy::validateCommand(const String& commandName, PassRefPtr<ValidateCommandCallback> callback) 1154{ 1155 if (!isValid()) { 1156 callback->invalidate(); 1157 return; 1158 } 1159 1160 uint64_t callbackID = callback->callbackID(); 1161 m_validateCommandCallbacks.set(callbackID, callback.get()); 1162 m_process->send(Messages::WebPage::ValidateCommand(commandName, callbackID), m_pageID); 1163} 1164 1165void WebPageProxy::setMaintainsInactiveSelection(bool newValue) 1166{ 1167 m_maintainsInactiveSelection = newValue; 1168} 1169 1170void WebPageProxy::executeEditCommand(const String& commandName) 1171{ 1172 if (!isValid()) 1173 return; 1174 1175 DEFINE_STATIC_LOCAL(String, ignoreSpellingCommandName, (ASCIILiteral("ignoreSpelling"))); 1176 if (commandName == ignoreSpellingCommandName) 1177 ++m_pendingLearnOrIgnoreWordMessageCount; 1178 1179 m_process->send(Messages::WebPage::ExecuteEditCommand(commandName), m_pageID); 1180} 1181 1182#if USE(TILED_BACKING_STORE) 1183void WebPageProxy::commitPageTransitionViewport() 1184{ 1185 if (!isValid()) 1186 return; 1187 1188 process()->send(Messages::WebPage::CommitPageTransitionViewport(), m_pageID); 1189} 1190#endif 1191 1192#if ENABLE(DRAG_SUPPORT) 1193void WebPageProxy::dragEntered(DragData* dragData, const String& dragStorageName) 1194{ 1195 SandboxExtension::Handle sandboxExtensionHandle; 1196 SandboxExtension::HandleArray sandboxExtensionHandleEmptyArray; 1197 performDragControllerAction(DragControllerActionEntered, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionHandleEmptyArray); 1198} 1199 1200void WebPageProxy::dragUpdated(DragData* dragData, const String& dragStorageName) 1201{ 1202 SandboxExtension::Handle sandboxExtensionHandle; 1203 SandboxExtension::HandleArray sandboxExtensionHandleEmptyArray; 1204 performDragControllerAction(DragControllerActionUpdated, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionHandleEmptyArray); 1205} 1206 1207void WebPageProxy::dragExited(DragData* dragData, const String& dragStorageName) 1208{ 1209 SandboxExtension::Handle sandboxExtensionHandle; 1210 SandboxExtension::HandleArray sandboxExtensionHandleEmptyArray; 1211 performDragControllerAction(DragControllerActionExited, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionHandleEmptyArray); 1212} 1213 1214void WebPageProxy::performDrag(DragData* dragData, const String& dragStorageName, const SandboxExtension::Handle& sandboxExtensionHandle, const SandboxExtension::HandleArray& sandboxExtensionsForUpload) 1215{ 1216 performDragControllerAction(DragControllerActionPerformDrag, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionsForUpload); 1217} 1218 1219void WebPageProxy::performDragControllerAction(DragControllerAction action, DragData* dragData, const String& dragStorageName, const SandboxExtension::Handle& sandboxExtensionHandle, const SandboxExtension::HandleArray& sandboxExtensionsForUpload) 1220{ 1221 if (!isValid()) 1222 return; 1223#if PLATFORM(QT) || PLATFORM(GTK) 1224 m_process->send(Messages::WebPage::PerformDragControllerAction(action, *dragData), m_pageID); 1225#else 1226 m_process->send(Messages::WebPage::PerformDragControllerAction(action, dragData->clientPosition(), dragData->globalPosition(), dragData->draggingSourceOperationMask(), dragStorageName, dragData->flags(), sandboxExtensionHandle, sandboxExtensionsForUpload), m_pageID); 1227#endif 1228} 1229 1230void WebPageProxy::didPerformDragControllerAction(WebCore::DragSession dragSession) 1231{ 1232 m_currentDragSession = dragSession; 1233} 1234 1235#if PLATFORM(QT) || PLATFORM(GTK) 1236void WebPageProxy::startDrag(const DragData& dragData, const ShareableBitmap::Handle& dragImageHandle) 1237{ 1238 RefPtr<ShareableBitmap> dragImage = 0; 1239 if (!dragImageHandle.isNull()) { 1240 dragImage = ShareableBitmap::create(dragImageHandle); 1241 if (!dragImage) 1242 return; 1243 } 1244 1245 m_pageClient->startDrag(dragData, dragImage.release()); 1246} 1247#endif 1248 1249void WebPageProxy::dragEnded(const IntPoint& clientPosition, const IntPoint& globalPosition, uint64_t operation) 1250{ 1251 if (!isValid()) 1252 return; 1253 m_process->send(Messages::WebPage::DragEnded(clientPosition, globalPosition, operation), m_pageID); 1254} 1255#endif // ENABLE(DRAG_SUPPORT) 1256 1257void WebPageProxy::handleMouseEvent(const NativeWebMouseEvent& event) 1258{ 1259 if (!isValid()) 1260 return; 1261 1262 // NOTE: This does not start the responsiveness timer because mouse move should not indicate interaction. 1263 if (event.type() != WebEvent::MouseMove) 1264 m_process->responsivenessTimer()->start(); 1265 else { 1266 if (m_processingMouseMoveEvent) { 1267 m_nextMouseMoveEvent = adoptPtr(new NativeWebMouseEvent(event)); 1268 return; 1269 } 1270 1271 m_processingMouseMoveEvent = true; 1272 } 1273 1274 // <https://bugs.webkit.org/show_bug.cgi?id=57904> We need to keep track of the mouse down event in the case where we 1275 // display a popup menu for select elements. When the user changes the selected item, 1276 // we fake a mouse up event by using this stored down event. This event gets cleared 1277 // when the mouse up message is received from WebProcess. 1278 if (event.type() == WebEvent::MouseDown) 1279 m_currentlyProcessedMouseDownEvent = adoptPtr(new NativeWebMouseEvent(event)); 1280 1281 if (m_shouldSendEventsSynchronously) { 1282 bool handled = false; 1283 m_process->sendSync(Messages::WebPage::MouseEventSyncForTesting(event), Messages::WebPage::MouseEventSyncForTesting::Reply(handled), m_pageID); 1284 didReceiveEvent(event.type(), handled); 1285 } else 1286 m_process->send(Messages::WebPage::MouseEvent(event), m_pageID); 1287} 1288 1289#if MERGE_WHEEL_EVENTS 1290static bool canCoalesce(const WebWheelEvent& a, const WebWheelEvent& b) 1291{ 1292 if (a.position() != b.position()) 1293 return false; 1294 if (a.globalPosition() != b.globalPosition()) 1295 return false; 1296 if (a.modifiers() != b.modifiers()) 1297 return false; 1298 if (a.granularity() != b.granularity()) 1299 return false; 1300#if PLATFORM(MAC) 1301 if (a.phase() != b.phase()) 1302 return false; 1303 if (a.momentumPhase() != b.momentumPhase()) 1304 return false; 1305 if (a.hasPreciseScrollingDeltas() != b.hasPreciseScrollingDeltas()) 1306 return false; 1307#endif 1308 1309 return true; 1310} 1311 1312static WebWheelEvent coalesce(const WebWheelEvent& a, const WebWheelEvent& b) 1313{ 1314 ASSERT(canCoalesce(a, b)); 1315 1316 FloatSize mergedDelta = a.delta() + b.delta(); 1317 FloatSize mergedWheelTicks = a.wheelTicks() + b.wheelTicks(); 1318 1319#if PLATFORM(MAC) 1320 FloatSize mergedUnacceleratedScrollingDelta = a.unacceleratedScrollingDelta() + b.unacceleratedScrollingDelta(); 1321 1322 return WebWheelEvent(WebEvent::Wheel, b.position(), b.globalPosition(), mergedDelta, mergedWheelTicks, b.granularity(), b.directionInvertedFromDevice(), b.phase(), b.momentumPhase(), b.hasPreciseScrollingDeltas(), b.scrollCount(), mergedUnacceleratedScrollingDelta, b.modifiers(), b.timestamp()); 1323#else 1324 return WebWheelEvent(WebEvent::Wheel, b.position(), b.globalPosition(), mergedDelta, mergedWheelTicks, b.granularity(), b.modifiers(), b.timestamp()); 1325#endif 1326} 1327#endif // MERGE_WHEEL_EVENTS 1328 1329static WebWheelEvent coalescedWheelEvent(Deque<NativeWebWheelEvent>& queue, Vector<NativeWebWheelEvent>& coalescedEvents) 1330{ 1331 ASSERT(!queue.isEmpty()); 1332 ASSERT(coalescedEvents.isEmpty()); 1333 1334#if MERGE_WHEEL_EVENTS 1335 NativeWebWheelEvent firstEvent = queue.takeFirst(); 1336 coalescedEvents.append(firstEvent); 1337 1338 WebWheelEvent event = firstEvent; 1339 while (!queue.isEmpty() && canCoalesce(event, queue.first())) { 1340 NativeWebWheelEvent firstEvent = queue.takeFirst(); 1341 coalescedEvents.append(firstEvent); 1342 event = coalesce(event, firstEvent); 1343 } 1344 1345 return event; 1346#else 1347 while (!queue.isEmpty()) 1348 coalescedEvents.append(queue.takeFirst()); 1349 return coalescedEvents.last(); 1350#endif 1351} 1352 1353void WebPageProxy::handleWheelEvent(const NativeWebWheelEvent& event) 1354{ 1355 if (!isValid()) 1356 return; 1357 1358 if (!m_currentlyProcessedWheelEvents.isEmpty()) { 1359 m_wheelEventQueue.append(event); 1360 if (m_wheelEventQueue.size() < wheelEventQueueSizeThreshold) 1361 return; 1362 // The queue has too many wheel events, so push a new event. 1363 } 1364 1365 if (!m_wheelEventQueue.isEmpty()) { 1366 processNextQueuedWheelEvent(); 1367 return; 1368 } 1369 1370 OwnPtr<Vector<NativeWebWheelEvent>> coalescedWheelEvent = adoptPtr(new Vector<NativeWebWheelEvent>); 1371 coalescedWheelEvent->append(event); 1372 m_currentlyProcessedWheelEvents.append(coalescedWheelEvent.release()); 1373 sendWheelEvent(event); 1374} 1375 1376void WebPageProxy::processNextQueuedWheelEvent() 1377{ 1378 OwnPtr<Vector<NativeWebWheelEvent>> nextCoalescedEvent = adoptPtr(new Vector<NativeWebWheelEvent>); 1379 WebWheelEvent nextWheelEvent = coalescedWheelEvent(m_wheelEventQueue, *nextCoalescedEvent.get()); 1380 m_currentlyProcessedWheelEvents.append(nextCoalescedEvent.release()); 1381 sendWheelEvent(nextWheelEvent); 1382} 1383 1384void WebPageProxy::sendWheelEvent(const WebWheelEvent& event) 1385{ 1386 m_process->responsivenessTimer()->start(); 1387 1388 if (m_shouldSendEventsSynchronously) { 1389 bool handled = false; 1390 m_process->sendSync(Messages::WebPage::WheelEventSyncForTesting(event), Messages::WebPage::WheelEventSyncForTesting::Reply(handled), m_pageID); 1391 didReceiveEvent(event.type(), handled); 1392 return; 1393 } 1394 1395 m_process->send(Messages::EventDispatcher::WheelEvent(m_pageID, event, canGoBack(), canGoForward()), 0); 1396} 1397 1398void WebPageProxy::handleKeyboardEvent(const NativeWebKeyboardEvent& event) 1399{ 1400 if (!isValid()) 1401 return; 1402 1403 LOG(KeyHandling, "WebPageProxy::handleKeyboardEvent: %s", webKeyboardEventTypeString(event.type())); 1404 1405 m_keyEventQueue.append(event); 1406 1407 m_process->responsivenessTimer()->start(); 1408 if (m_shouldSendEventsSynchronously) { 1409 bool handled = false; 1410 m_process->sendSync(Messages::WebPage::KeyEventSyncForTesting(event), Messages::WebPage::KeyEventSyncForTesting::Reply(handled), m_pageID); 1411 didReceiveEvent(event.type(), handled); 1412 } else if (m_keyEventQueue.size() == 1) // Otherwise, sent from DidReceiveEvent message handler. 1413 m_process->send(Messages::WebPage::KeyEvent(event), m_pageID); 1414} 1415 1416#if ENABLE(NETSCAPE_PLUGIN_API) 1417void WebPageProxy::findPlugin(const String& mimeType, uint32_t processType, const String& urlString, const String& frameURLString, const String& pageURLString, bool allowOnlyApplicationPlugins, uint64_t& pluginProcessToken, String& newMimeType, uint32_t& pluginLoadPolicy, String& unavailabilityDescription) 1418{ 1419 MESSAGE_CHECK_URL(urlString); 1420 1421 newMimeType = mimeType.lower(); 1422 pluginLoadPolicy = PluginModuleLoadNormally; 1423 1424 PluginData::AllowedPluginTypes allowedPluginTypes = allowOnlyApplicationPlugins ? PluginData::OnlyApplicationPlugins : PluginData::AllPlugins; 1425 PluginModuleInfo plugin = m_process->context()->pluginInfoStore().findPlugin(newMimeType, KURL(KURL(), urlString), allowedPluginTypes); 1426 if (!plugin.path) { 1427 pluginProcessToken = 0; 1428 return; 1429 } 1430 1431 pluginLoadPolicy = PluginInfoStore::defaultLoadPolicyForPlugin(plugin); 1432 1433#if PLATFORM(MAC) 1434 RefPtr<ImmutableDictionary> pluginInformation = createPluginInformationDictionary(plugin, frameURLString, String(), pageURLString, String(), String()); 1435 pluginLoadPolicy = m_loaderClient.pluginLoadPolicy(this, static_cast<PluginModuleLoadPolicy>(pluginLoadPolicy), pluginInformation.get(), unavailabilityDescription); 1436#else 1437 UNUSED_PARAM(frameURLString); 1438 UNUSED_PARAM(pageURLString); 1439#endif 1440 1441 PluginProcessSandboxPolicy pluginProcessSandboxPolicy = PluginProcessSandboxPolicyNormal; 1442 switch (pluginLoadPolicy) { 1443 case PluginModuleLoadNormally: 1444 pluginProcessSandboxPolicy = PluginProcessSandboxPolicyNormal; 1445 break; 1446 case PluginModuleLoadUnsandboxed: 1447 pluginProcessSandboxPolicy = PluginProcessSandboxPolicyUnsandboxed; 1448 break; 1449 1450 case PluginModuleBlocked: 1451 pluginProcessToken = 0; 1452 return; 1453 } 1454 1455 pluginProcessToken = PluginProcessManager::shared().pluginProcessToken(plugin, static_cast<PluginProcessType>(processType), pluginProcessSandboxPolicy); 1456} 1457 1458#endif // ENABLE(NETSCAPE_PLUGIN_API) 1459 1460#if ENABLE(GESTURE_EVENTS) 1461void WebPageProxy::handleGestureEvent(const WebGestureEvent& event) 1462{ 1463 if (!isValid()) 1464 return; 1465 1466 m_gestureEventQueue.append(event); 1467 1468 m_process->responsivenessTimer()->start(); 1469 m_process->send(Messages::EventDispatcher::GestureEvent(m_pageID, event), 0); 1470} 1471#endif 1472 1473#if ENABLE(TOUCH_EVENTS) 1474#if PLATFORM(QT) 1475void WebPageProxy::handlePotentialActivation(const IntPoint& touchPoint, const IntSize& touchArea) 1476{ 1477 m_process->send(Messages::WebPage::HighlightPotentialActivation(touchPoint, touchArea), m_pageID); 1478} 1479#endif 1480 1481void WebPageProxy::handleTouchEvent(const NativeWebTouchEvent& event) 1482{ 1483 if (!isValid()) 1484 return; 1485 1486 // If the page is suspended, which should be the case during panning, pinching 1487 // and animation on the page itself (kinetic scrolling, tap to zoom) etc, then 1488 // we do not send any of the events to the page even if is has listeners. 1489 if (m_needTouchEvents && !m_isPageSuspended) { 1490 m_touchEventQueue.append(event); 1491 m_process->responsivenessTimer()->start(); 1492 if (m_shouldSendEventsSynchronously) { 1493 bool handled = false; 1494 m_process->sendSync(Messages::WebPage::TouchEventSyncForTesting(event), Messages::WebPage::TouchEventSyncForTesting::Reply(handled), m_pageID); 1495 didReceiveEvent(event.type(), handled); 1496 } else 1497 m_process->send(Messages::WebPage::TouchEvent(event), m_pageID); 1498 } else { 1499 if (m_touchEventQueue.isEmpty()) { 1500 bool isEventHandled = false; 1501 m_pageClient->doneWithTouchEvent(event, isEventHandled); 1502 } else { 1503 // We attach the incoming events to the newest queued event so that all 1504 // the events are delivered in the correct order when the event is dequed. 1505 QueuedTouchEvents& lastEvent = m_touchEventQueue.last(); 1506 lastEvent.deferredTouchEvents.append(event); 1507 } 1508 } 1509} 1510#endif 1511 1512void WebPageProxy::scrollBy(ScrollDirection direction, ScrollGranularity granularity) 1513{ 1514 if (!isValid()) 1515 return; 1516 1517 m_process->send(Messages::WebPage::ScrollBy(direction, granularity), m_pageID); 1518} 1519 1520void WebPageProxy::centerSelectionInVisibleArea() 1521{ 1522 if (!isValid()) 1523 return; 1524 1525 m_process->send(Messages::WebPage::CenterSelectionInVisibleArea(), m_pageID); 1526} 1527 1528void WebPageProxy::receivedPolicyDecision(PolicyAction action, WebFrameProxy* frame, uint64_t listenerID) 1529{ 1530 if (!isValid()) 1531 return; 1532 1533 if (action == PolicyIgnore) 1534 clearPendingAPIRequestURL(); 1535 1536 uint64_t downloadID = 0; 1537 if (action == PolicyDownload) { 1538 // Create a download proxy. 1539 DownloadProxy* download = m_process->context()->createDownloadProxy(); 1540 downloadID = download->downloadID(); 1541#if PLATFORM(QT) || PLATFORM(EFL) || PLATFORM(GTK) 1542 // Our design does not suppport downloads without a WebPage. 1543 handleDownloadRequest(download); 1544#endif 1545 } 1546 1547 // If we received a policy decision while in decidePolicyForResponse the decision will 1548 // be sent back to the web process by decidePolicyForResponse. 1549 if (m_inDecidePolicyForResponseSync) { 1550 m_syncMimeTypePolicyActionIsValid = true; 1551 m_syncMimeTypePolicyAction = action; 1552 m_syncMimeTypePolicyDownloadID = downloadID; 1553 return; 1554 } 1555 1556 // If we received a policy decision while in decidePolicyForNavigationAction the decision will 1557 // be sent back to the web process by decidePolicyForNavigationAction. 1558 if (m_inDecidePolicyForNavigationAction) { 1559 m_syncNavigationActionPolicyActionIsValid = true; 1560 m_syncNavigationActionPolicyAction = action; 1561 m_syncNavigationActionPolicyDownloadID = downloadID; 1562 return; 1563 } 1564 1565 m_process->send(Messages::WebPage::DidReceivePolicyDecision(frame->frameID(), listenerID, action, downloadID), m_pageID); 1566} 1567 1568String WebPageProxy::pageTitle() const 1569{ 1570 // Return the null string if there is no main frame (e.g. nothing has been loaded in the page yet, WebProcess has 1571 // crashed, page has been closed). 1572 if (!m_mainFrame) 1573 return String(); 1574 1575 return m_mainFrame->title(); 1576} 1577 1578void WebPageProxy::setUserAgent(const String& userAgent) 1579{ 1580 if (m_userAgent == userAgent) 1581 return; 1582 m_userAgent = userAgent; 1583 1584 if (!isValid()) 1585 return; 1586 m_process->send(Messages::WebPage::SetUserAgent(m_userAgent), m_pageID); 1587} 1588 1589void WebPageProxy::setApplicationNameForUserAgent(const String& applicationName) 1590{ 1591 if (m_applicationNameForUserAgent == applicationName) 1592 return; 1593 1594 m_applicationNameForUserAgent = applicationName; 1595 if (!m_customUserAgent.isEmpty()) 1596 return; 1597 1598 setUserAgent(standardUserAgent(m_applicationNameForUserAgent)); 1599} 1600 1601void WebPageProxy::setCustomUserAgent(const String& customUserAgent) 1602{ 1603 if (m_customUserAgent == customUserAgent) 1604 return; 1605 1606 m_customUserAgent = customUserAgent; 1607 1608 if (m_customUserAgent.isEmpty()) { 1609 setUserAgent(standardUserAgent(m_applicationNameForUserAgent)); 1610 return; 1611 } 1612 1613 setUserAgent(m_customUserAgent); 1614} 1615 1616void WebPageProxy::resumeActiveDOMObjectsAndAnimations() 1617{ 1618 if (!isValid() || !m_isPageSuspended) 1619 return; 1620 1621 m_isPageSuspended = false; 1622 1623 m_process->send(Messages::WebPage::ResumeActiveDOMObjectsAndAnimations(), m_pageID); 1624} 1625 1626void WebPageProxy::suspendActiveDOMObjectsAndAnimations() 1627{ 1628 if (!isValid() || m_isPageSuspended) 1629 return; 1630 1631 m_isPageSuspended = true; 1632 1633 m_process->send(Messages::WebPage::SuspendActiveDOMObjectsAndAnimations(), m_pageID); 1634} 1635 1636bool WebPageProxy::supportsTextEncoding() const 1637{ 1638 return !m_mainFrameHasCustomRepresentation && m_mainFrame && !m_mainFrame->isDisplayingStandaloneImageDocument(); 1639} 1640 1641void WebPageProxy::setCustomTextEncodingName(const String& encodingName) 1642{ 1643 if (m_customTextEncodingName == encodingName) 1644 return; 1645 m_customTextEncodingName = encodingName; 1646 1647 if (!isValid()) 1648 return; 1649 m_process->send(Messages::WebPage::SetCustomTextEncodingName(encodingName), m_pageID); 1650} 1651 1652void WebPageProxy::terminateProcess() 1653{ 1654 // NOTE: This uses a check of m_isValid rather than calling isValid() since 1655 // we want this to run even for pages being closed or that already closed. 1656 if (!m_isValid) 1657 return; 1658 1659 m_process->requestTermination(); 1660 resetStateAfterProcessExited(); 1661} 1662 1663#if !USE(CF) || defined(BUILDING_QT__) 1664PassRefPtr<WebData> WebPageProxy::sessionStateData(WebPageProxySessionStateFilterCallback, void* /*context*/) const 1665{ 1666 // FIXME: Return session state data for saving Page state. 1667 return 0; 1668} 1669 1670void WebPageProxy::restoreFromSessionStateData(WebData*) 1671{ 1672 // FIXME: Restore the Page from the passed in session state data. 1673} 1674#endif 1675 1676bool WebPageProxy::supportsTextZoom() const 1677{ 1678 if (m_mainFrameHasCustomRepresentation) 1679 return false; 1680 1681 // FIXME: This should also return false for standalone media and plug-in documents. 1682 if (!m_mainFrame || m_mainFrame->isDisplayingStandaloneImageDocument()) 1683 return false; 1684 1685 return true; 1686} 1687 1688void WebPageProxy::setTextZoomFactor(double zoomFactor) 1689{ 1690 if (!isValid()) 1691 return; 1692 1693 if (m_mainFrameHasCustomRepresentation) 1694 return; 1695 1696 if (m_textZoomFactor == zoomFactor) 1697 return; 1698 1699 m_textZoomFactor = zoomFactor; 1700 m_process->send(Messages::WebPage::SetTextZoomFactor(m_textZoomFactor), m_pageID); 1701} 1702 1703double WebPageProxy::pageZoomFactor() const 1704{ 1705 return m_mainFrameHasCustomRepresentation ? m_pageClient->customRepresentationZoomFactor() : m_pageZoomFactor; 1706} 1707 1708void WebPageProxy::setPageZoomFactor(double zoomFactor) 1709{ 1710 if (!isValid()) 1711 return; 1712 1713 if (m_mainFrameHasCustomRepresentation) { 1714 m_pageClient->setCustomRepresentationZoomFactor(zoomFactor); 1715 return; 1716 } 1717 1718 if (m_pageZoomFactor == zoomFactor) 1719 return; 1720 1721 m_pageZoomFactor = zoomFactor; 1722 m_process->send(Messages::WebPage::SetPageZoomFactor(m_pageZoomFactor), m_pageID); 1723} 1724 1725void WebPageProxy::setPageAndTextZoomFactors(double pageZoomFactor, double textZoomFactor) 1726{ 1727 if (!isValid()) 1728 return; 1729 1730 if (m_mainFrameHasCustomRepresentation) { 1731 m_pageClient->setCustomRepresentationZoomFactor(pageZoomFactor); 1732 return; 1733 } 1734 1735 if (m_pageZoomFactor == pageZoomFactor && m_textZoomFactor == textZoomFactor) 1736 return; 1737 1738 m_pageZoomFactor = pageZoomFactor; 1739 m_textZoomFactor = textZoomFactor; 1740 m_process->send(Messages::WebPage::SetPageAndTextZoomFactors(m_pageZoomFactor, m_textZoomFactor), m_pageID); 1741} 1742 1743void WebPageProxy::scalePage(double scale, const IntPoint& origin) 1744{ 1745 if (!isValid()) 1746 return; 1747 1748 m_process->send(Messages::WebPage::ScalePage(scale, origin), m_pageID); 1749} 1750 1751void WebPageProxy::setIntrinsicDeviceScaleFactor(float scaleFactor) 1752{ 1753 if (m_intrinsicDeviceScaleFactor == scaleFactor) 1754 return; 1755 1756 m_intrinsicDeviceScaleFactor = scaleFactor; 1757 1758 if (m_drawingArea) 1759 m_drawingArea->deviceScaleFactorDidChange(); 1760} 1761 1762void WebPageProxy::windowScreenDidChange(PlatformDisplayID displayID) 1763{ 1764 if (!isValid()) 1765 return; 1766 1767 m_process->send(Messages::WebPage::WindowScreenDidChange(displayID), m_pageID); 1768} 1769 1770float WebPageProxy::deviceScaleFactor() const 1771{ 1772 if (m_customDeviceScaleFactor) 1773 return m_customDeviceScaleFactor; 1774 return m_intrinsicDeviceScaleFactor; 1775} 1776 1777void WebPageProxy::setCustomDeviceScaleFactor(float customScaleFactor) 1778{ 1779 if (!isValid()) 1780 return; 1781 1782 if (m_customDeviceScaleFactor == customScaleFactor) 1783 return; 1784 1785 float oldScaleFactor = deviceScaleFactor(); 1786 1787 m_customDeviceScaleFactor = customScaleFactor; 1788 1789 if (deviceScaleFactor() != oldScaleFactor) 1790 m_drawingArea->deviceScaleFactorDidChange(); 1791} 1792 1793void WebPageProxy::setUseFixedLayout(bool fixed) 1794{ 1795 if (!isValid()) 1796 return; 1797 1798 // This check is fine as the value is initialized in the web 1799 // process as part of the creation parameters. 1800 if (fixed == m_useFixedLayout) 1801 return; 1802 1803 m_useFixedLayout = fixed; 1804 if (!fixed) 1805 m_fixedLayoutSize = IntSize(); 1806 m_process->send(Messages::WebPage::SetUseFixedLayout(fixed), m_pageID); 1807} 1808 1809void WebPageProxy::setFixedLayoutSize(const IntSize& size) 1810{ 1811 if (!isValid()) 1812 return; 1813 1814 if (size == m_fixedLayoutSize) 1815 return; 1816 1817 m_fixedLayoutSize = size; 1818 m_process->send(Messages::WebPage::SetFixedLayoutSize(size), m_pageID); 1819} 1820 1821void WebPageProxy::listenForLayoutMilestones(WebCore::LayoutMilestones milestones) 1822{ 1823 if (!isValid()) 1824 return; 1825 1826 m_process->send(Messages::WebPage::ListenForLayoutMilestones(milestones), m_pageID); 1827} 1828 1829void WebPageProxy::setVisibilityState(WebCore::PageVisibilityState visibilityState, bool isInitialState) 1830{ 1831 if (!isValid()) 1832 return; 1833 1834#if ENABLE(PAGE_VISIBILITY_API) 1835 if (visibilityState != m_visibilityState || isInitialState) { 1836 m_visibilityState = visibilityState; 1837 m_process->send(Messages::WebPage::SetVisibilityState(visibilityState, isInitialState), m_pageID); 1838 } 1839#endif 1840} 1841 1842void WebPageProxy::setSuppressScrollbarAnimations(bool suppressAnimations) 1843{ 1844 if (!isValid()) 1845 return; 1846 1847 if (suppressAnimations == m_suppressScrollbarAnimations) 1848 return; 1849 1850 m_suppressScrollbarAnimations = suppressAnimations; 1851 m_process->send(Messages::WebPage::SetSuppressScrollbarAnimations(suppressAnimations), m_pageID); 1852} 1853 1854void WebPageProxy::setRubberBandsAtBottom(bool rubberBandsAtBottom) 1855{ 1856 if (rubberBandsAtBottom == m_rubberBandsAtBottom) 1857 return; 1858 1859 m_rubberBandsAtBottom = rubberBandsAtBottom; 1860 1861 if (!isValid()) 1862 return; 1863 1864 m_process->send(Messages::WebPage::SetRubberBandsAtBottom(rubberBandsAtBottom), m_pageID); 1865} 1866 1867void WebPageProxy::setRubberBandsAtTop(bool rubberBandsAtTop) 1868{ 1869 if (rubberBandsAtTop == m_rubberBandsAtTop) 1870 return; 1871 1872 m_rubberBandsAtTop = rubberBandsAtTop; 1873 1874 if (!isValid()) 1875 return; 1876 1877 m_process->send(Messages::WebPage::SetRubberBandsAtTop(rubberBandsAtTop), m_pageID); 1878} 1879 1880void WebPageProxy::setPaginationMode(WebCore::Pagination::Mode mode) 1881{ 1882 if (mode == m_paginationMode) 1883 return; 1884 1885 m_paginationMode = mode; 1886 1887 if (!isValid()) 1888 return; 1889 m_process->send(Messages::WebPage::SetPaginationMode(mode), m_pageID); 1890} 1891 1892void WebPageProxy::setPaginationBehavesLikeColumns(bool behavesLikeColumns) 1893{ 1894 if (behavesLikeColumns == m_paginationBehavesLikeColumns) 1895 return; 1896 1897 m_paginationBehavesLikeColumns = behavesLikeColumns; 1898 1899 if (!isValid()) 1900 return; 1901 m_process->send(Messages::WebPage::SetPaginationBehavesLikeColumns(behavesLikeColumns), m_pageID); 1902} 1903 1904void WebPageProxy::setPageLength(double pageLength) 1905{ 1906 if (pageLength == m_pageLength) 1907 return; 1908 1909 m_pageLength = pageLength; 1910 1911 if (!isValid()) 1912 return; 1913 m_process->send(Messages::WebPage::SetPageLength(pageLength), m_pageID); 1914} 1915 1916void WebPageProxy::setGapBetweenPages(double gap) 1917{ 1918 if (gap == m_gapBetweenPages) 1919 return; 1920 1921 m_gapBetweenPages = gap; 1922 1923 if (!isValid()) 1924 return; 1925 m_process->send(Messages::WebPage::SetGapBetweenPages(gap), m_pageID); 1926} 1927 1928void WebPageProxy::pageScaleFactorDidChange(double scaleFactor) 1929{ 1930 m_pageScaleFactor = scaleFactor; 1931} 1932 1933void WebPageProxy::pageZoomFactorDidChange(double zoomFactor) 1934{ 1935 m_pageZoomFactor = zoomFactor; 1936} 1937 1938void WebPageProxy::setMemoryCacheClientCallsEnabled(bool memoryCacheClientCallsEnabled) 1939{ 1940 if (!isValid()) 1941 return; 1942 1943 if (m_areMemoryCacheClientCallsEnabled == memoryCacheClientCallsEnabled) 1944 return; 1945 1946 m_areMemoryCacheClientCallsEnabled = memoryCacheClientCallsEnabled; 1947 m_process->send(Messages::WebPage::SetMemoryCacheMessagesEnabled(memoryCacheClientCallsEnabled), m_pageID); 1948} 1949 1950void WebPageProxy::findStringMatches(const String& string, FindOptions options, unsigned maxMatchCount) 1951{ 1952 if (string.isEmpty()) { 1953 didFindStringMatches(string, Vector<Vector<WebCore::IntRect>> (), 0); 1954 return; 1955 } 1956 1957 m_process->send(Messages::WebPage::FindStringMatches(string, options, maxMatchCount), m_pageID); 1958} 1959 1960void WebPageProxy::findString(const String& string, FindOptions options, unsigned maxMatchCount) 1961{ 1962 if (m_mainFrameHasCustomRepresentation) 1963 m_pageClient->findStringInCustomRepresentation(string, options, maxMatchCount); 1964 else 1965 m_process->send(Messages::WebPage::FindString(string, options, maxMatchCount), m_pageID); 1966} 1967 1968void WebPageProxy::getImageForFindMatch(int32_t matchIndex) 1969{ 1970 m_process->send(Messages::WebPage::GetImageForFindMatch(matchIndex), m_pageID); 1971} 1972 1973void WebPageProxy::selectFindMatch(int32_t matchIndex) 1974{ 1975 m_process->send(Messages::WebPage::SelectFindMatch(matchIndex), m_pageID); 1976} 1977 1978void WebPageProxy::hideFindUI() 1979{ 1980 m_process->send(Messages::WebPage::HideFindUI(), m_pageID); 1981} 1982 1983void WebPageProxy::countStringMatches(const String& string, FindOptions options, unsigned maxMatchCount) 1984{ 1985 if (m_mainFrameHasCustomRepresentation) { 1986 m_pageClient->countStringMatchesInCustomRepresentation(string, options, maxMatchCount); 1987 return; 1988 } 1989 1990 if (!isValid()) 1991 return; 1992 1993 m_process->send(Messages::WebPage::CountStringMatches(string, options, maxMatchCount), m_pageID); 1994} 1995 1996void WebPageProxy::runJavaScriptInMainFrame(const String& script, PassRefPtr<ScriptValueCallback> prpCallback) 1997{ 1998 RefPtr<ScriptValueCallback> callback = prpCallback; 1999 if (!isValid()) { 2000 callback->invalidate(); 2001 return; 2002 } 2003 2004 uint64_t callbackID = callback->callbackID(); 2005 m_scriptValueCallbacks.set(callbackID, callback.get()); 2006 m_process->send(Messages::WebPage::RunJavaScriptInMainFrame(script, callbackID), m_pageID); 2007} 2008 2009void WebPageProxy::getRenderTreeExternalRepresentation(PassRefPtr<StringCallback> prpCallback) 2010{ 2011 RefPtr<StringCallback> callback = prpCallback; 2012 if (!isValid()) { 2013 callback->invalidate(); 2014 return; 2015 } 2016 2017 uint64_t callbackID = callback->callbackID(); 2018 m_stringCallbacks.set(callbackID, callback.get()); 2019 m_process->send(Messages::WebPage::GetRenderTreeExternalRepresentation(callbackID), m_pageID); 2020} 2021 2022void WebPageProxy::getSourceForFrame(WebFrameProxy* frame, PassRefPtr<StringCallback> prpCallback) 2023{ 2024 RefPtr<StringCallback> callback = prpCallback; 2025 if (!isValid()) { 2026 callback->invalidate(); 2027 return; 2028 } 2029 2030 uint64_t callbackID = callback->callbackID(); 2031 m_loadDependentStringCallbackIDs.add(callbackID); 2032 m_stringCallbacks.set(callbackID, callback.get()); 2033 m_process->send(Messages::WebPage::GetSourceForFrame(frame->frameID(), callbackID), m_pageID); 2034} 2035 2036void WebPageProxy::getContentsAsString(PassRefPtr<StringCallback> prpCallback) 2037{ 2038 RefPtr<StringCallback> callback = prpCallback; 2039 if (!isValid()) { 2040 callback->invalidate(); 2041 return; 2042 } 2043 2044 uint64_t callbackID = callback->callbackID(); 2045 m_loadDependentStringCallbackIDs.add(callbackID); 2046 m_stringCallbacks.set(callbackID, callback.get()); 2047 m_process->send(Messages::WebPage::GetContentsAsString(callbackID), m_pageID); 2048} 2049 2050#if ENABLE(MHTML) 2051void WebPageProxy::getContentsAsMHTMLData(PassRefPtr<DataCallback> prpCallback, bool useBinaryEncoding) 2052{ 2053 RefPtr<DataCallback> callback = prpCallback; 2054 if (!isValid()) { 2055 callback->invalidate(); 2056 return; 2057 } 2058 2059 uint64_t callbackID = callback->callbackID(); 2060 m_dataCallbacks.set(callbackID, callback.get()); 2061 m_process->send(Messages::WebPage::GetContentsAsMHTMLData(callbackID, useBinaryEncoding), m_pageID); 2062} 2063#endif 2064 2065void WebPageProxy::getSelectionOrContentsAsString(PassRefPtr<StringCallback> prpCallback) 2066{ 2067 RefPtr<StringCallback> callback = prpCallback; 2068 if (!isValid()) { 2069 callback->invalidate(); 2070 return; 2071 } 2072 2073 uint64_t callbackID = callback->callbackID(); 2074 m_stringCallbacks.set(callbackID, callback.get()); 2075 m_process->send(Messages::WebPage::GetSelectionOrContentsAsString(callbackID), m_pageID); 2076} 2077 2078void WebPageProxy::getSelectionAsWebArchiveData(PassRefPtr<DataCallback> prpCallback) 2079{ 2080 RefPtr<DataCallback> callback = prpCallback; 2081 if (!isValid()) { 2082 callback->invalidate(); 2083 return; 2084 } 2085 2086 uint64_t callbackID = callback->callbackID(); 2087 m_dataCallbacks.set(callbackID, callback.get()); 2088 m_process->send(Messages::WebPage::GetSelectionAsWebArchiveData(callbackID), m_pageID); 2089} 2090 2091void WebPageProxy::getMainResourceDataOfFrame(WebFrameProxy* frame, PassRefPtr<DataCallback> prpCallback) 2092{ 2093 RefPtr<DataCallback> callback = prpCallback; 2094 if (!isValid()) { 2095 callback->invalidate(); 2096 return; 2097 } 2098 2099 uint64_t callbackID = callback->callbackID(); 2100 m_dataCallbacks.set(callbackID, callback.get()); 2101 m_process->send(Messages::WebPage::GetMainResourceDataOfFrame(frame->frameID(), callbackID), m_pageID); 2102} 2103 2104void WebPageProxy::getResourceDataFromFrame(WebFrameProxy* frame, WebURL* resourceURL, PassRefPtr<DataCallback> prpCallback) 2105{ 2106 RefPtr<DataCallback> callback = prpCallback; 2107 if (!isValid()) { 2108 callback->invalidate(); 2109 return; 2110 } 2111 2112 uint64_t callbackID = callback->callbackID(); 2113 m_dataCallbacks.set(callbackID, callback.get()); 2114 m_process->send(Messages::WebPage::GetResourceDataFromFrame(frame->frameID(), resourceURL->string(), callbackID), m_pageID); 2115} 2116 2117void WebPageProxy::getWebArchiveOfFrame(WebFrameProxy* frame, PassRefPtr<DataCallback> prpCallback) 2118{ 2119 RefPtr<DataCallback> callback = prpCallback; 2120 if (!isValid()) { 2121 callback->invalidate(); 2122 return; 2123 } 2124 2125 uint64_t callbackID = callback->callbackID(); 2126 m_dataCallbacks.set(callbackID, callback.get()); 2127 m_process->send(Messages::WebPage::GetWebArchiveOfFrame(frame->frameID(), callbackID), m_pageID); 2128} 2129 2130void WebPageProxy::forceRepaint(PassRefPtr<VoidCallback> prpCallback) 2131{ 2132 RefPtr<VoidCallback> callback = prpCallback; 2133 if (!isValid()) { 2134 callback->invalidate(); 2135 return; 2136 } 2137 2138 uint64_t callbackID = callback->callbackID(); 2139 m_voidCallbacks.set(callbackID, callback.get()); 2140 m_drawingArea->waitForBackingStoreUpdateOnNextPaint(); 2141 m_process->send(Messages::WebPage::ForceRepaint(callbackID), m_pageID); 2142} 2143 2144void WebPageProxy::preferencesDidChange() 2145{ 2146 if (!isValid()) 2147 return; 2148 2149#if ENABLE(INSPECTOR_SERVER) 2150 if (m_pageGroup->preferences()->developerExtrasEnabled()) 2151 inspector()->enableRemoteInspection(); 2152#endif 2153 2154 m_process->pagePreferencesChanged(this); 2155 2156 m_pageClient->preferencesDidChange(); 2157 2158 // FIXME: It probably makes more sense to send individual preference changes. 2159 // However, WebKitTestRunner depends on getting a preference change notification 2160 // even if nothing changed in UI process, so that overrides get removed. 2161 2162 // Preferences need to be updated during synchronous printing to make "print backgrounds" preference work when toggled from a print dialog checkbox. 2163 m_process->send(Messages::WebPage::PreferencesDidChange(pageGroup()->preferences()->store()), m_pageID, m_isPerformingDOMPrintOperation ? CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply : 0); 2164} 2165 2166void WebPageProxy::didCreateMainFrame(uint64_t frameID) 2167{ 2168 MESSAGE_CHECK(!m_mainFrame); 2169 MESSAGE_CHECK(m_process->canCreateFrame(frameID)); 2170 2171 m_mainFrame = WebFrameProxy::create(this, frameID); 2172 2173 // Add the frame to the process wide map. 2174 m_process->frameCreated(frameID, m_mainFrame.get()); 2175} 2176 2177void WebPageProxy::didCreateSubframe(uint64_t frameID) 2178{ 2179 MESSAGE_CHECK(m_mainFrame); 2180 MESSAGE_CHECK(m_process->canCreateFrame(frameID)); 2181 2182 RefPtr<WebFrameProxy> subFrame = WebFrameProxy::create(this, frameID); 2183 2184 // Add the frame to the process wide map. 2185 m_process->frameCreated(frameID, subFrame.get()); 2186} 2187 2188// Always start progress at initialProgressValue. This helps provide feedback as 2189// soon as a load starts. 2190 2191static const double initialProgressValue = 0.1; 2192 2193double WebPageProxy::estimatedProgress() const 2194{ 2195 if (!pendingAPIRequestURL().isNull()) 2196 return initialProgressValue; 2197 return m_estimatedProgress; 2198} 2199 2200void WebPageProxy::didStartProgress() 2201{ 2202 m_estimatedProgress = initialProgressValue; 2203 2204 m_loaderClient.didStartProgress(this); 2205} 2206 2207void WebPageProxy::didChangeProgress(double value) 2208{ 2209 m_estimatedProgress = value; 2210 2211 m_loaderClient.didChangeProgress(this); 2212} 2213 2214void WebPageProxy::didFinishProgress() 2215{ 2216 m_estimatedProgress = 1.0; 2217 2218 m_loaderClient.didFinishProgress(this); 2219} 2220 2221void WebPageProxy::didStartProvisionalLoadForFrame(uint64_t frameID, const String& url, const String& unreachableURL, CoreIPC::MessageDecoder& decoder) 2222{ 2223 clearPendingAPIRequestURL(); 2224 2225 RefPtr<APIObject> userData; 2226 WebContextUserMessageDecoder messageDecoder(userData, m_process.get()); 2227 if (!decoder.decode(messageDecoder)) 2228 return; 2229 2230 WebFrameProxy* frame = m_process->webFrame(frameID); 2231 MESSAGE_CHECK(frame); 2232 MESSAGE_CHECK_URL(url); 2233 2234 frame->setUnreachableURL(unreachableURL); 2235 2236 frame->didStartProvisionalLoad(url); 2237 m_loaderClient.didStartProvisionalLoadForFrame(this, frame, userData.get()); 2238} 2239 2240void WebPageProxy::didReceiveServerRedirectForProvisionalLoadForFrame(uint64_t frameID, const String& url, CoreIPC::MessageDecoder& decoder) 2241{ 2242 RefPtr<APIObject> userData; 2243 WebContextUserMessageDecoder messageDecoder(userData, m_process.get()); 2244 if (!decoder.decode(messageDecoder)) 2245 return; 2246 2247 WebFrameProxy* frame = m_process->webFrame(frameID); 2248 MESSAGE_CHECK(frame); 2249 MESSAGE_CHECK_URL(url); 2250 2251 frame->didReceiveServerRedirectForProvisionalLoad(url); 2252 2253 m_loaderClient.didReceiveServerRedirectForProvisionalLoadForFrame(this, frame, userData.get()); 2254} 2255 2256void WebPageProxy::didFailProvisionalLoadForFrame(uint64_t frameID, const ResourceError& error, CoreIPC::MessageDecoder& decoder) 2257{ 2258 RefPtr<APIObject> userData; 2259 WebContextUserMessageDecoder messageDecoder(userData, m_process.get()); 2260 if (!decoder.decode(messageDecoder)) 2261 return; 2262 2263 WebFrameProxy* frame = m_process->webFrame(frameID); 2264 MESSAGE_CHECK(frame); 2265 2266 frame->didFailProvisionalLoad(); 2267 2268 m_loaderClient.didFailProvisionalLoadWithErrorForFrame(this, frame, error, userData.get()); 2269} 2270 2271void WebPageProxy::clearLoadDependentCallbacks() 2272{ 2273 Vector<uint64_t> callbackIDsCopy; 2274 copyToVector(m_loadDependentStringCallbackIDs, callbackIDsCopy); 2275 m_loadDependentStringCallbackIDs.clear(); 2276 2277 for (size_t i = 0; i < callbackIDsCopy.size(); ++i) { 2278 RefPtr<StringCallback> callback = m_stringCallbacks.take(callbackIDsCopy[i]); 2279 if (callback) 2280 callback->invalidate(); 2281 } 2282} 2283 2284void WebPageProxy::didCommitLoadForFrame(uint64_t frameID, const String& mimeType, bool frameHasCustomRepresentation, uint32_t opaqueFrameLoadType, const PlatformCertificateInfo& certificateInfo, CoreIPC::MessageDecoder& decoder) 2285{ 2286 RefPtr<APIObject> userData; 2287 WebContextUserMessageDecoder messageDecoder(userData, m_process.get()); 2288 if (!decoder.decode(messageDecoder)) 2289 return; 2290 2291 WebFrameProxy* frame = m_process->webFrame(frameID); 2292 MESSAGE_CHECK(frame); 2293 2294#if PLATFORM(MAC) 2295 // FIXME (bug 59111): didCommitLoadForFrame comes too late when restoring a page from b/f cache, making us disable secure event mode in password fields. 2296 // FIXME: A load going on in one frame shouldn't affect text editing in other frames on the page. 2297 m_pageClient->resetSecureInputState(); 2298 dismissCorrectionPanel(ReasonForDismissingAlternativeTextIgnored); 2299 m_pageClient->dismissDictionaryLookupPanel(); 2300#endif 2301 2302 clearLoadDependentCallbacks(); 2303 2304 frame->didCommitLoad(mimeType, certificateInfo); 2305 2306 if (frame->isMainFrame()) { 2307 m_mainFrameHasCustomRepresentation = frameHasCustomRepresentation; 2308 2309 if (m_mainFrameHasCustomRepresentation) { 2310 // Always assume that the main frame is pinned here, since the custom representation view will handle 2311 // any wheel events and dispatch them to the WKView when necessary. 2312 m_mainFrameIsPinnedToLeftSide = true; 2313 m_mainFrameIsPinnedToRightSide = true; 2314 m_mainFrameIsPinnedToTopSide = true; 2315 m_mainFrameIsPinnedToBottomSide = true; 2316 } 2317 m_pageClient->didCommitLoadForMainFrame(frameHasCustomRepresentation); 2318 } 2319 2320 // Even if WebPage has the default pageScaleFactor (and therefore doesn't reset it), 2321 // WebPageProxy's cache of the value can get out of sync (e.g. in the case where a 2322 // plugin is handling page scaling itself) so we should reset it to the default 2323 // for standard main frame loads. 2324 if (frame->isMainFrame() && static_cast<FrameLoadType>(opaqueFrameLoadType) == FrameLoadTypeStandard) 2325 m_pageScaleFactor = 1; 2326 2327 m_loaderClient.didCommitLoadForFrame(this, frame, userData.get()); 2328} 2329 2330void WebPageProxy::didFinishDocumentLoadForFrame(uint64_t frameID, CoreIPC::MessageDecoder& decoder) 2331{ 2332 RefPtr<APIObject> userData; 2333 WebContextUserMessageDecoder messageDecoder(userData, m_process.get()); 2334 if (!decoder.decode(messageDecoder)) 2335 return; 2336 2337 WebFrameProxy* frame = m_process->webFrame(frameID); 2338 MESSAGE_CHECK(frame); 2339 2340 m_loaderClient.didFinishDocumentLoadForFrame(this, frame, userData.get()); 2341} 2342 2343void WebPageProxy::didFinishLoadForFrame(uint64_t frameID, CoreIPC::MessageDecoder& decoder) 2344{ 2345 RefPtr<APIObject> userData; 2346 WebContextUserMessageDecoder messageDecoder(userData, m_process.get()); 2347 if (!decoder.decode(messageDecoder)) 2348 return; 2349 2350 WebFrameProxy* frame = m_process->webFrame(frameID); 2351 MESSAGE_CHECK(frame); 2352 2353 frame->didFinishLoad(); 2354 2355 m_loaderClient.didFinishLoadForFrame(this, frame, userData.get()); 2356} 2357 2358void WebPageProxy::didFailLoadForFrame(uint64_t frameID, const ResourceError& error, CoreIPC::MessageDecoder& decoder) 2359{ 2360 RefPtr<APIObject> userData; 2361 WebContextUserMessageDecoder messageDecoder(userData, m_process.get()); 2362 if (!decoder.decode(messageDecoder)) 2363 return; 2364 2365 WebFrameProxy* frame = m_process->webFrame(frameID); 2366 MESSAGE_CHECK(frame); 2367 2368 clearLoadDependentCallbacks(); 2369 2370 frame->didFailLoad(); 2371 2372 m_loaderClient.didFailLoadWithErrorForFrame(this, frame, error, userData.get()); 2373} 2374 2375void WebPageProxy::didSameDocumentNavigationForFrame(uint64_t frameID, uint32_t opaqueSameDocumentNavigationType, const String& url, CoreIPC::MessageDecoder& decoder) 2376{ 2377 RefPtr<APIObject> userData; 2378 WebContextUserMessageDecoder messageDecoder(userData, m_process.get()); 2379 if (!decoder.decode(messageDecoder)) 2380 return; 2381 2382 WebFrameProxy* frame = m_process->webFrame(frameID); 2383 MESSAGE_CHECK(frame); 2384 MESSAGE_CHECK_URL(url); 2385 2386 clearPendingAPIRequestURL(); 2387 frame->didSameDocumentNavigation(url); 2388 2389 m_loaderClient.didSameDocumentNavigationForFrame(this, frame, static_cast<SameDocumentNavigationType>(opaqueSameDocumentNavigationType), userData.get()); 2390} 2391 2392void WebPageProxy::didReceiveTitleForFrame(uint64_t frameID, const String& title, CoreIPC::MessageDecoder& decoder) 2393{ 2394 RefPtr<APIObject> userData; 2395 WebContextUserMessageDecoder messageDecoder(userData, m_process.get()); 2396 if (!decoder.decode(messageDecoder)) 2397 return; 2398 2399 WebFrameProxy* frame = m_process->webFrame(frameID); 2400 MESSAGE_CHECK(frame); 2401 2402 frame->didChangeTitle(title); 2403 2404 m_loaderClient.didReceiveTitleForFrame(this, title, frame, userData.get()); 2405} 2406 2407void WebPageProxy::didFirstLayoutForFrame(uint64_t frameID, CoreIPC::MessageDecoder& decoder) 2408{ 2409 RefPtr<APIObject> userData; 2410 WebContextUserMessageDecoder messageDecoder(userData, m_process.get()); 2411 if (!decoder.decode(messageDecoder)) 2412 return; 2413 2414 WebFrameProxy* frame = m_process->webFrame(frameID); 2415 MESSAGE_CHECK(frame); 2416 2417 m_loaderClient.didFirstLayoutForFrame(this, frame, userData.get()); 2418} 2419 2420void WebPageProxy::didFirstVisuallyNonEmptyLayoutForFrame(uint64_t frameID, CoreIPC::MessageDecoder& decoder) 2421{ 2422 RefPtr<APIObject> userData; 2423 WebContextUserMessageDecoder messageDecoder(userData, m_process.get()); 2424 if (!decoder.decode(messageDecoder)) 2425 return; 2426 2427 WebFrameProxy* frame = m_process->webFrame(frameID); 2428 MESSAGE_CHECK(frame); 2429 2430 m_loaderClient.didFirstVisuallyNonEmptyLayoutForFrame(this, frame, userData.get()); 2431} 2432 2433void WebPageProxy::didNewFirstVisuallyNonEmptyLayout(CoreIPC::MessageDecoder& decoder) 2434{ 2435 RefPtr<APIObject> userData; 2436 WebContextUserMessageDecoder messageDecoder(userData, m_process.get()); 2437 if (!decoder.decode(messageDecoder)) 2438 return; 2439 2440 m_loaderClient.didNewFirstVisuallyNonEmptyLayout(this, userData.get()); 2441} 2442 2443void WebPageProxy::didLayout(uint32_t layoutMilestones, CoreIPC::MessageDecoder& decoder) 2444{ 2445 RefPtr<APIObject> userData; 2446 WebContextUserMessageDecoder messageDecoder(userData, m_process.get()); 2447 if (!decoder.decode(messageDecoder)) 2448 return; 2449 2450 m_loaderClient.didLayout(this, static_cast<LayoutMilestones>(layoutMilestones), userData.get()); 2451} 2452 2453void WebPageProxy::didRemoveFrameFromHierarchy(uint64_t frameID, CoreIPC::MessageDecoder& decoder) 2454{ 2455 RefPtr<APIObject> userData; 2456 WebContextUserMessageDecoder messageDecoder(userData, m_process.get()); 2457 if (!decoder.decode(messageDecoder)) 2458 return; 2459 2460 WebFrameProxy* frame = m_process->webFrame(frameID); 2461 MESSAGE_CHECK(frame); 2462 2463 m_loaderClient.didRemoveFrameFromHierarchy(this, frame, userData.get()); 2464} 2465 2466void WebPageProxy::didDisplayInsecureContentForFrame(uint64_t frameID, CoreIPC::MessageDecoder& decoder) 2467{ 2468 RefPtr<APIObject> userData; 2469 WebContextUserMessageDecoder messageDecoder(userData, m_process.get()); 2470 if (!decoder.decode(messageDecoder)) 2471 return; 2472 2473 WebFrameProxy* frame = m_process->webFrame(frameID); 2474 MESSAGE_CHECK(frame); 2475 2476 m_loaderClient.didDisplayInsecureContentForFrame(this, frame, userData.get()); 2477} 2478 2479void WebPageProxy::didRunInsecureContentForFrame(uint64_t frameID, CoreIPC::MessageDecoder& decoder) 2480{ 2481 RefPtr<APIObject> userData; 2482 WebContextUserMessageDecoder messageDecoder(userData, m_process.get()); 2483 if (!decoder.decode(messageDecoder)) 2484 return; 2485 2486 WebFrameProxy* frame = m_process->webFrame(frameID); 2487 MESSAGE_CHECK(frame); 2488 2489 m_loaderClient.didRunInsecureContentForFrame(this, frame, userData.get()); 2490} 2491 2492void WebPageProxy::didDetectXSSForFrame(uint64_t frameID, CoreIPC::MessageDecoder& decoder) 2493{ 2494 RefPtr<APIObject> userData; 2495 WebContextUserMessageDecoder messageDecoder(userData, m_process.get()); 2496 if (!decoder.decode(messageDecoder)) 2497 return; 2498 2499 WebFrameProxy* frame = m_process->webFrame(frameID); 2500 MESSAGE_CHECK(frame); 2501 2502 m_loaderClient.didDetectXSSForFrame(this, frame, userData.get()); 2503} 2504 2505void WebPageProxy::frameDidBecomeFrameSet(uint64_t frameID, bool value) 2506{ 2507 WebFrameProxy* frame = m_process->webFrame(frameID); 2508 MESSAGE_CHECK(frame); 2509 2510 frame->setIsFrameSet(value); 2511 if (frame->isMainFrame()) 2512 m_frameSetLargestFrame = value ? m_mainFrame : 0; 2513} 2514 2515// PolicyClient 2516void WebPageProxy::decidePolicyForNavigationAction(uint64_t frameID, uint32_t opaqueNavigationType, uint32_t opaqueModifiers, int32_t opaqueMouseButton, const ResourceRequest& request, uint64_t listenerID, CoreIPC::MessageDecoder& decoder, bool& receivedPolicyAction, uint64_t& policyAction, uint64_t& downloadID) 2517{ 2518 RefPtr<APIObject> userData; 2519 WebContextUserMessageDecoder messageDecoder(userData, m_process.get()); 2520 if (!decoder.decode(messageDecoder)) 2521 return; 2522 2523 if (request.url() != pendingAPIRequestURL()) 2524 clearPendingAPIRequestURL(); 2525 2526 WebFrameProxy* frame = m_process->webFrame(frameID); 2527 MESSAGE_CHECK(frame); 2528 MESSAGE_CHECK_URL(request.url()); 2529 2530 NavigationType navigationType = static_cast<NavigationType>(opaqueNavigationType); 2531 WebEvent::Modifiers modifiers = static_cast<WebEvent::Modifiers>(opaqueModifiers); 2532 WebMouseEvent::Button mouseButton = static_cast<WebMouseEvent::Button>(opaqueMouseButton); 2533 2534 RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID); 2535 2536 ASSERT(!m_inDecidePolicyForNavigationAction); 2537 2538 m_inDecidePolicyForNavigationAction = true; 2539 m_syncNavigationActionPolicyActionIsValid = false; 2540 2541 if (!m_policyClient.decidePolicyForNavigationAction(this, frame, navigationType, modifiers, mouseButton, request, listener.get(), userData.get())) 2542 listener->use(); 2543 2544 m_inDecidePolicyForNavigationAction = false; 2545 2546 // Check if we received a policy decision already. If we did, we can just pass it back. 2547 receivedPolicyAction = m_syncNavigationActionPolicyActionIsValid; 2548 if (m_syncNavigationActionPolicyActionIsValid) { 2549 policyAction = m_syncNavigationActionPolicyAction; 2550 downloadID = m_syncNavigationActionPolicyDownloadID; 2551 } 2552} 2553 2554void WebPageProxy::decidePolicyForNewWindowAction(uint64_t frameID, uint32_t opaqueNavigationType, uint32_t opaqueModifiers, int32_t opaqueMouseButton, const ResourceRequest& request, const String& frameName, uint64_t listenerID, CoreIPC::MessageDecoder& decoder) 2555{ 2556 RefPtr<APIObject> userData; 2557 WebContextUserMessageDecoder messageDecoder(userData, m_process.get()); 2558 if (!decoder.decode(messageDecoder)) 2559 return; 2560 2561 WebFrameProxy* frame = m_process->webFrame(frameID); 2562 MESSAGE_CHECK(frame); 2563 MESSAGE_CHECK_URL(request.url()); 2564 2565 NavigationType navigationType = static_cast<NavigationType>(opaqueNavigationType); 2566 WebEvent::Modifiers modifiers = static_cast<WebEvent::Modifiers>(opaqueModifiers); 2567 WebMouseEvent::Button mouseButton = static_cast<WebMouseEvent::Button>(opaqueMouseButton); 2568 2569 RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID); 2570 if (!m_policyClient.decidePolicyForNewWindowAction(this, frame, navigationType, modifiers, mouseButton, request, frameName, listener.get(), userData.get())) 2571 listener->use(); 2572} 2573 2574void WebPageProxy::decidePolicyForResponse(uint64_t frameID, const ResourceResponse& response, const ResourceRequest& request, uint64_t listenerID, CoreIPC::MessageDecoder& decoder) 2575{ 2576 RefPtr<APIObject> userData; 2577 WebContextUserMessageDecoder messageDecoder(userData, m_process.get()); 2578 if (!decoder.decode(messageDecoder)) 2579 return; 2580 2581 WebFrameProxy* frame = m_process->webFrame(frameID); 2582 MESSAGE_CHECK(frame); 2583 MESSAGE_CHECK_URL(request.url()); 2584 MESSAGE_CHECK_URL(response.url()); 2585 2586 RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID); 2587 2588 if (!m_policyClient.decidePolicyForResponse(this, frame, response, request, listener.get(), userData.get())) 2589 listener->use(); 2590} 2591 2592void WebPageProxy::decidePolicyForResponseSync(uint64_t frameID, const ResourceResponse& response, const ResourceRequest& request, uint64_t listenerID, CoreIPC::MessageDecoder& decoder, bool& receivedPolicyAction, uint64_t& policyAction, uint64_t& downloadID) 2593{ 2594 ASSERT(!m_inDecidePolicyForResponseSync); 2595 2596 m_inDecidePolicyForResponseSync = true; 2597 m_decidePolicyForResponseRequest = &request; 2598 m_syncMimeTypePolicyActionIsValid = false; 2599 2600 decidePolicyForResponse(frameID, response, request, listenerID, decoder); 2601 2602 m_inDecidePolicyForResponseSync = false; 2603 m_decidePolicyForResponseRequest = 0; 2604 2605 // Check if we received a policy decision already. If we did, we can just pass it back. 2606 receivedPolicyAction = m_syncMimeTypePolicyActionIsValid; 2607 if (m_syncMimeTypePolicyActionIsValid) { 2608 policyAction = m_syncMimeTypePolicyAction; 2609 downloadID = m_syncMimeTypePolicyDownloadID; 2610 } 2611} 2612 2613void WebPageProxy::unableToImplementPolicy(uint64_t frameID, const ResourceError& error, CoreIPC::MessageDecoder& decoder) 2614{ 2615 RefPtr<APIObject> userData; 2616 WebContextUserMessageDecoder messageDecoder(userData, m_process.get()); 2617 if (!decoder.decode(messageDecoder)) 2618 return; 2619 2620 WebFrameProxy* frame = m_process->webFrame(frameID); 2621 MESSAGE_CHECK(frame); 2622 2623 m_policyClient.unableToImplementPolicy(this, frame, error, userData.get()); 2624} 2625 2626// FormClient 2627 2628void WebPageProxy::willSubmitForm(uint64_t frameID, uint64_t sourceFrameID, const Vector<std::pair<String, String>>& textFieldValues, uint64_t listenerID, CoreIPC::MessageDecoder& decoder) 2629{ 2630 RefPtr<APIObject> userData; 2631 WebContextUserMessageDecoder messageDecoder(userData, m_process.get()); 2632 if (!decoder.decode(messageDecoder)) 2633 return; 2634 2635 WebFrameProxy* frame = m_process->webFrame(frameID); 2636 MESSAGE_CHECK(frame); 2637 2638 WebFrameProxy* sourceFrame = m_process->webFrame(sourceFrameID); 2639 MESSAGE_CHECK(sourceFrame); 2640 2641 RefPtr<WebFormSubmissionListenerProxy> listener = frame->setUpFormSubmissionListenerProxy(listenerID); 2642 if (!m_formClient.willSubmitForm(this, frame, sourceFrame, textFieldValues, userData.get(), listener.get())) 2643 listener->continueSubmission(); 2644} 2645 2646// UIClient 2647 2648void WebPageProxy::createNewPage(const ResourceRequest& request, const WindowFeatures& windowFeatures, uint32_t opaqueModifiers, int32_t opaqueMouseButton, uint64_t& newPageID, WebPageCreationParameters& newPageParameters) 2649{ 2650 RefPtr<WebPageProxy> newPage = m_uiClient.createNewPage(this, request, windowFeatures, static_cast<WebEvent::Modifiers>(opaqueModifiers), static_cast<WebMouseEvent::Button>(opaqueMouseButton)); 2651 if (!newPage) { 2652 newPageID = 0; 2653 return; 2654 } 2655 2656 newPageID = newPage->pageID(); 2657 newPageParameters = newPage->creationParameters(); 2658 process()->context()->storageManager().cloneSessionStorageNamespace(m_pageID, newPage->pageID()); 2659} 2660 2661void WebPageProxy::showPage() 2662{ 2663 m_uiClient.showPage(this); 2664} 2665 2666void WebPageProxy::closePage(bool stopResponsivenessTimer) 2667{ 2668 if (stopResponsivenessTimer) 2669 m_process->responsivenessTimer()->stop(); 2670 2671 m_pageClient->clearAllEditCommands(); 2672 m_uiClient.close(this); 2673} 2674 2675void WebPageProxy::runJavaScriptAlert(uint64_t frameID, const String& message) 2676{ 2677 WebFrameProxy* frame = m_process->webFrame(frameID); 2678 MESSAGE_CHECK(frame); 2679 2680 // Since runJavaScriptAlert() can spin a nested run loop we need to turn off the responsiveness timer. 2681 m_process->responsivenessTimer()->stop(); 2682 2683 m_uiClient.runJavaScriptAlert(this, message, frame); 2684} 2685 2686void WebPageProxy::runJavaScriptConfirm(uint64_t frameID, const String& message, bool& result) 2687{ 2688 WebFrameProxy* frame = m_process->webFrame(frameID); 2689 MESSAGE_CHECK(frame); 2690 2691 // Since runJavaScriptConfirm() can spin a nested run loop we need to turn off the responsiveness timer. 2692 m_process->responsivenessTimer()->stop(); 2693 2694 result = m_uiClient.runJavaScriptConfirm(this, message, frame); 2695} 2696 2697void WebPageProxy::runJavaScriptPrompt(uint64_t frameID, const String& message, const String& defaultValue, String& result) 2698{ 2699 WebFrameProxy* frame = m_process->webFrame(frameID); 2700 MESSAGE_CHECK(frame); 2701 2702 // Since runJavaScriptPrompt() can spin a nested run loop we need to turn off the responsiveness timer. 2703 m_process->responsivenessTimer()->stop(); 2704 2705 result = m_uiClient.runJavaScriptPrompt(this, message, defaultValue, frame); 2706} 2707 2708void WebPageProxy::shouldInterruptJavaScript(bool& result) 2709{ 2710 // Since shouldInterruptJavaScript() can spin a nested run loop we need to turn off the responsiveness timer. 2711 m_process->responsivenessTimer()->stop(); 2712 2713 result = m_uiClient.shouldInterruptJavaScript(this); 2714} 2715 2716void WebPageProxy::setStatusText(const String& text) 2717{ 2718 m_uiClient.setStatusText(this, text); 2719} 2720 2721void WebPageProxy::mouseDidMoveOverElement(const WebHitTestResult::Data& hitTestResultData, uint32_t opaqueModifiers, CoreIPC::MessageDecoder& decoder) 2722{ 2723 RefPtr<APIObject> userData; 2724 WebContextUserMessageDecoder messageDecoder(userData, m_process.get()); 2725 if (!decoder.decode(messageDecoder)) 2726 return; 2727 2728 WebEvent::Modifiers modifiers = static_cast<WebEvent::Modifiers>(opaqueModifiers); 2729 2730 m_uiClient.mouseDidMoveOverElement(this, hitTestResultData, modifiers, userData.get()); 2731} 2732 2733void WebPageProxy::connectionWillOpen(CoreIPC::Connection* connection) 2734{ 2735 ASSERT(connection == m_process->connection()); 2736 2737 m_process->context()->storageManager().setAllowedSessionStorageNamespaceConnection(m_pageID, connection); 2738} 2739 2740void WebPageProxy::connectionWillClose(CoreIPC::Connection* connection) 2741{ 2742 ASSERT_UNUSED(connection, connection == m_process->connection()); 2743 2744 m_process->context()->storageManager().setAllowedSessionStorageNamespaceConnection(m_pageID, 0); 2745} 2746 2747void WebPageProxy::unavailablePluginButtonClicked(uint32_t opaquePluginUnavailabilityReason, const String& mimeType, const String& pluginURLString, const String& pluginspageAttributeURLString, const String& frameURLString, const String& pageURLString) 2748{ 2749 MESSAGE_CHECK_URL(pluginURLString); 2750 MESSAGE_CHECK_URL(pluginspageAttributeURLString); 2751 MESSAGE_CHECK_URL(frameURLString); 2752 MESSAGE_CHECK_URL(pageURLString); 2753 2754 RefPtr<ImmutableDictionary> pluginInformation; 2755#if ENABLE(NETSCAPE_PLUGIN_API) 2756 String newMimeType = mimeType; 2757 PluginModuleInfo plugin = m_process->context()->pluginInfoStore().findPlugin(newMimeType, KURL(KURL(), pluginURLString)); 2758 pluginInformation = createPluginInformationDictionary(plugin, frameURLString, mimeType, pageURLString, pluginspageAttributeURLString, pluginURLString); 2759#endif 2760 2761 WKPluginUnavailabilityReason pluginUnavailabilityReason = kWKPluginUnavailabilityReasonPluginMissing; 2762 switch (static_cast<RenderEmbeddedObject::PluginUnavailabilityReason>(opaquePluginUnavailabilityReason)) { 2763 case RenderEmbeddedObject::PluginMissing: 2764 pluginUnavailabilityReason = kWKPluginUnavailabilityReasonPluginMissing; 2765 break; 2766 case RenderEmbeddedObject::InsecurePluginVersion: 2767 pluginUnavailabilityReason = kWKPluginUnavailabilityReasonInsecurePluginVersion; 2768 break; 2769 case RenderEmbeddedObject::PluginCrashed: 2770 pluginUnavailabilityReason = kWKPluginUnavailabilityReasonPluginCrashed; 2771 break; 2772 case RenderEmbeddedObject::PluginBlockedByContentSecurityPolicy: 2773 ASSERT_NOT_REACHED(); 2774 } 2775 2776 m_uiClient.unavailablePluginButtonClicked(this, pluginUnavailabilityReason, pluginInformation.get()); 2777} 2778 2779void WebPageProxy::setToolbarsAreVisible(bool toolbarsAreVisible) 2780{ 2781 m_uiClient.setToolbarsAreVisible(this, toolbarsAreVisible); 2782} 2783 2784void WebPageProxy::getToolbarsAreVisible(bool& toolbarsAreVisible) 2785{ 2786 toolbarsAreVisible = m_uiClient.toolbarsAreVisible(this); 2787} 2788 2789void WebPageProxy::setMenuBarIsVisible(bool menuBarIsVisible) 2790{ 2791 m_uiClient.setMenuBarIsVisible(this, menuBarIsVisible); 2792} 2793 2794void WebPageProxy::getMenuBarIsVisible(bool& menuBarIsVisible) 2795{ 2796 menuBarIsVisible = m_uiClient.menuBarIsVisible(this); 2797} 2798 2799void WebPageProxy::setStatusBarIsVisible(bool statusBarIsVisible) 2800{ 2801 m_uiClient.setStatusBarIsVisible(this, statusBarIsVisible); 2802} 2803 2804void WebPageProxy::getStatusBarIsVisible(bool& statusBarIsVisible) 2805{ 2806 statusBarIsVisible = m_uiClient.statusBarIsVisible(this); 2807} 2808 2809void WebPageProxy::setIsResizable(bool isResizable) 2810{ 2811 m_uiClient.setIsResizable(this, isResizable); 2812} 2813 2814void WebPageProxy::getIsResizable(bool& isResizable) 2815{ 2816 isResizable = m_uiClient.isResizable(this); 2817} 2818 2819void WebPageProxy::setWindowFrame(const FloatRect& newWindowFrame) 2820{ 2821 m_uiClient.setWindowFrame(this, m_pageClient->convertToDeviceSpace(newWindowFrame)); 2822} 2823 2824void WebPageProxy::getWindowFrame(FloatRect& newWindowFrame) 2825{ 2826 newWindowFrame = m_pageClient->convertToUserSpace(m_uiClient.windowFrame(this)); 2827} 2828 2829void WebPageProxy::screenToWindow(const IntPoint& screenPoint, IntPoint& windowPoint) 2830{ 2831 windowPoint = m_pageClient->screenToWindow(screenPoint); 2832} 2833 2834void WebPageProxy::windowToScreen(const IntRect& viewRect, IntRect& result) 2835{ 2836 result = m_pageClient->windowToScreen(viewRect); 2837} 2838 2839void WebPageProxy::runBeforeUnloadConfirmPanel(const String& message, uint64_t frameID, bool& shouldClose) 2840{ 2841 WebFrameProxy* frame = m_process->webFrame(frameID); 2842 MESSAGE_CHECK(frame); 2843 2844 // Since runBeforeUnloadConfirmPanel() can spin a nested run loop we need to turn off the responsiveness timer. 2845 m_process->responsivenessTimer()->stop(); 2846 2847 shouldClose = m_uiClient.runBeforeUnloadConfirmPanel(this, message, frame); 2848} 2849 2850#if USE(TILED_BACKING_STORE) 2851void WebPageProxy::pageDidRequestScroll(const IntPoint& point) 2852{ 2853 m_pageClient->pageDidRequestScroll(point); 2854} 2855 2856void WebPageProxy::pageTransitionViewportReady() 2857{ 2858 m_pageClient->pageTransitionViewportReady(); 2859} 2860 2861void WebPageProxy::didRenderFrame(const WebCore::IntSize& contentsSize, const WebCore::IntRect& coveredRect) 2862{ 2863 m_pageClient->didRenderFrame(contentsSize, coveredRect); 2864} 2865 2866#endif 2867 2868void WebPageProxy::didChangeViewportProperties(const ViewportAttributes& attr) 2869{ 2870 m_pageClient->didChangeViewportProperties(attr); 2871} 2872 2873void WebPageProxy::pageDidScroll() 2874{ 2875 m_uiClient.pageDidScroll(this); 2876#if PLATFORM(MAC) 2877 dismissCorrectionPanel(ReasonForDismissingAlternativeTextIgnored); 2878#endif 2879} 2880 2881void WebPageProxy::runOpenPanel(uint64_t frameID, const FileChooserSettings& settings) 2882{ 2883 if (m_openPanelResultListener) { 2884 m_openPanelResultListener->invalidate(); 2885 m_openPanelResultListener = 0; 2886 } 2887 2888 WebFrameProxy* frame = m_process->webFrame(frameID); 2889 MESSAGE_CHECK(frame); 2890 2891 RefPtr<WebOpenPanelParameters> parameters = WebOpenPanelParameters::create(settings); 2892 m_openPanelResultListener = WebOpenPanelResultListenerProxy::create(this); 2893 2894 // Since runOpenPanel() can spin a nested run loop we need to turn off the responsiveness timer. 2895 m_process->responsivenessTimer()->stop(); 2896 2897 if (!m_uiClient.runOpenPanel(this, frame, parameters.get(), m_openPanelResultListener.get())) 2898 didCancelForOpenPanel(); 2899} 2900 2901void WebPageProxy::printFrame(uint64_t frameID) 2902{ 2903 ASSERT(!m_isPerformingDOMPrintOperation); 2904 m_isPerformingDOMPrintOperation = true; 2905 2906 WebFrameProxy* frame = m_process->webFrame(frameID); 2907 MESSAGE_CHECK(frame); 2908 2909 m_uiClient.printFrame(this, frame); 2910 2911 endPrinting(); // Send a message synchronously while m_isPerformingDOMPrintOperation is still true. 2912 m_isPerformingDOMPrintOperation = false; 2913} 2914 2915void WebPageProxy::printMainFrame() 2916{ 2917 printFrame(m_mainFrame->frameID()); 2918} 2919 2920void WebPageProxy::setMediaVolume(float volume) 2921{ 2922 if (volume == m_mediaVolume) 2923 return; 2924 2925 m_mediaVolume = volume; 2926 2927 if (!isValid()) 2928 return; 2929 2930 m_process->send(Messages::WebPage::SetMediaVolume(volume), m_pageID); 2931} 2932 2933void WebPageProxy::setMayStartMediaWhenInWindow(bool mayStartMedia) 2934{ 2935 if (mayStartMedia == m_mayStartMediaWhenInWindow) 2936 return; 2937 2938 m_mayStartMediaWhenInWindow = mayStartMedia; 2939 2940 if (!isValid()) 2941 return; 2942 2943 process()->send(Messages::WebPage::SetMayStartMediaWhenInWindow(mayStartMedia), m_pageID); 2944} 2945 2946#if PLATFORM(QT) || PLATFORM(EFL) || PLATFORM(GTK) 2947void WebPageProxy::handleDownloadRequest(DownloadProxy* download) 2948{ 2949 m_pageClient->handleDownloadRequest(download); 2950} 2951#endif // PLATFORM(QT) || PLATFORM(EFL) || PLATFORM(GTK) 2952 2953#if PLATFORM(QT) || PLATFORM(EFL) 2954void WebPageProxy::didChangeContentsSize(const IntSize& size) 2955{ 2956 m_pageClient->didChangeContentsSize(size); 2957} 2958#endif 2959 2960#if ENABLE(TOUCH_EVENTS) 2961void WebPageProxy::needTouchEvents(bool needTouchEvents) 2962{ 2963 m_needTouchEvents = needTouchEvents; 2964} 2965#endif 2966 2967#if ENABLE(INPUT_TYPE_COLOR) 2968void WebPageProxy::showColorChooser(const WebCore::Color& initialColor, const IntRect& elementRect) 2969{ 2970 ASSERT(!m_colorChooser); 2971 2972 if (m_colorPickerResultListener) { 2973 m_colorPickerResultListener->invalidate(); 2974 m_colorPickerResultListener = nullptr; 2975 } 2976 2977 m_colorPickerResultListener = WebColorPickerResultListenerProxy::create(this); 2978 m_colorChooser = WebColorChooserProxy::create(this); 2979 2980 if (m_uiClient.showColorPicker(this, initialColor.serialized(), m_colorPickerResultListener.get())) 2981 return; 2982 2983 m_colorChooser = m_pageClient->createColorChooserProxy(this, initialColor, elementRect); 2984 if (!m_colorChooser) 2985 didEndColorChooser(); 2986} 2987 2988void WebPageProxy::setColorChooserColor(const WebCore::Color& color) 2989{ 2990 ASSERT(m_colorChooser); 2991 2992 m_colorChooser->setSelectedColor(color); 2993} 2994 2995void WebPageProxy::endColorChooser() 2996{ 2997 ASSERT(m_colorChooser); 2998 2999 m_colorChooser->endChooser(); 3000} 3001 3002void WebPageProxy::didChooseColor(const WebCore::Color& color) 3003{ 3004 if (!isValid()) 3005 return; 3006 3007 m_process->send(Messages::WebPage::DidChooseColor(color), m_pageID); 3008} 3009 3010void WebPageProxy::didEndColorChooser() 3011{ 3012 if (!isValid()) 3013 return; 3014 3015 if (m_colorChooser) { 3016 m_colorChooser->invalidate(); 3017 m_colorChooser = nullptr; 3018 } 3019 3020 m_process->send(Messages::WebPage::DidEndColorChooser(), m_pageID); 3021 3022 m_colorPickerResultListener->invalidate(); 3023 m_colorPickerResultListener = nullptr; 3024 3025 m_uiClient.hideColorPicker(this); 3026} 3027#endif 3028 3029void WebPageProxy::didDraw() 3030{ 3031 m_uiClient.didDraw(this); 3032} 3033 3034// Inspector 3035 3036#if ENABLE(INSPECTOR) 3037 3038WebInspectorProxy* WebPageProxy::inspector() 3039{ 3040 if (isClosed() || !isValid()) 3041 return 0; 3042 return m_inspector.get(); 3043} 3044 3045#endif 3046 3047#if ENABLE(FULLSCREEN_API) 3048WebFullScreenManagerProxy* WebPageProxy::fullScreenManager() 3049{ 3050 return m_fullScreenManager.get(); 3051} 3052#endif 3053 3054// BackForwardList 3055 3056void WebPageProxy::backForwardAddItem(uint64_t itemID) 3057{ 3058 m_backForwardList->addItem(m_process->webBackForwardItem(itemID)); 3059} 3060 3061void WebPageProxy::backForwardGoToItem(uint64_t itemID, SandboxExtension::Handle& sandboxExtensionHandle) 3062{ 3063 WebBackForwardListItem* item = m_process->webBackForwardItem(itemID); 3064 if (!item) 3065 return; 3066 3067 bool createdExtension = maybeInitializeSandboxExtensionHandle(KURL(KURL(), item->url()), sandboxExtensionHandle); 3068 if (createdExtension) 3069 m_process->willAcquireUniversalFileReadSandboxExtension(); 3070 m_backForwardList->goToItem(item); 3071} 3072 3073void WebPageProxy::backForwardItemAtIndex(int32_t index, uint64_t& itemID) 3074{ 3075 WebBackForwardListItem* item = m_backForwardList->itemAtIndex(index); 3076 itemID = item ? item->itemID() : 0; 3077} 3078 3079void WebPageProxy::backForwardBackListCount(int32_t& count) 3080{ 3081 count = m_backForwardList->backListCount(); 3082} 3083 3084void WebPageProxy::backForwardForwardListCount(int32_t& count) 3085{ 3086 count = m_backForwardList->forwardListCount(); 3087} 3088 3089void WebPageProxy::editorStateChanged(const EditorState& editorState) 3090{ 3091#if PLATFORM(MAC) 3092 bool couldChangeSecureInputState = m_editorState.isInPasswordField != editorState.isInPasswordField || m_editorState.selectionIsNone; 3093 bool closedComposition = !editorState.shouldIgnoreCompositionSelectionChange && !editorState.hasComposition && (m_editorState.hasComposition || m_temporarilyClosedComposition); 3094 m_temporarilyClosedComposition = editorState.shouldIgnoreCompositionSelectionChange && (m_temporarilyClosedComposition || m_editorState.hasComposition) && !editorState.hasComposition; 3095#endif 3096 3097 m_editorState = editorState; 3098 3099#if PLATFORM(MAC) 3100 // Selection being none is a temporary state when editing. Flipping secure input state too quickly was causing trouble (not fully understood). 3101 if (couldChangeSecureInputState && !editorState.selectionIsNone) 3102 m_pageClient->updateSecureInputState(); 3103 3104 if (editorState.shouldIgnoreCompositionSelectionChange) 3105 return; 3106 3107 if (closedComposition) 3108 m_pageClient->notifyInputContextAboutDiscardedComposition(); 3109 if (editorState.hasComposition) { 3110 // Abandon the current inline input session if selection changed for any other reason but an input method changing the composition. 3111 // FIXME: This logic should be in WebCore, no need to round-trip to UI process to cancel the composition. 3112 cancelComposition(); 3113 m_pageClient->notifyInputContextAboutDiscardedComposition(); 3114 } 3115#elif PLATFORM(QT) || PLATFORM(EFL) || PLATFORM(GTK) 3116 m_pageClient->updateTextInputState(); 3117#endif 3118} 3119 3120// Undo management 3121 3122void WebPageProxy::registerEditCommandForUndo(uint64_t commandID, uint32_t editAction) 3123{ 3124 registerEditCommand(WebEditCommandProxy::create(commandID, static_cast<EditAction>(editAction), this), Undo); 3125} 3126 3127void WebPageProxy::canUndoRedo(uint32_t action, bool& result) 3128{ 3129 result = m_pageClient->canUndoRedo(static_cast<UndoOrRedo>(action)); 3130} 3131 3132void WebPageProxy::executeUndoRedo(uint32_t action, bool& result) 3133{ 3134 m_pageClient->executeUndoRedo(static_cast<UndoOrRedo>(action)); 3135 result = true; 3136} 3137 3138void WebPageProxy::clearAllEditCommands() 3139{ 3140 m_pageClient->clearAllEditCommands(); 3141} 3142 3143void WebPageProxy::didCountStringMatches(const String& string, uint32_t matchCount) 3144{ 3145 m_findClient.didCountStringMatches(this, string, matchCount); 3146} 3147 3148void WebPageProxy::didGetImageForFindMatch(const ShareableBitmap::Handle& contentImageHandle, uint32_t matchIndex) 3149{ 3150 m_findMatchesClient.didGetImageForMatchResult(this, WebImage::create(ShareableBitmap::create(contentImageHandle)).get(), matchIndex); 3151} 3152 3153void WebPageProxy::setFindIndicator(const FloatRect& selectionRectInWindowCoordinates, const Vector<FloatRect>& textRectsInSelectionRectCoordinates, float contentImageScaleFactor, const ShareableBitmap::Handle& contentImageHandle, bool fadeOut, bool animate) 3154{ 3155 RefPtr<FindIndicator> findIndicator = FindIndicator::create(selectionRectInWindowCoordinates, textRectsInSelectionRectCoordinates, contentImageScaleFactor, contentImageHandle); 3156 m_pageClient->setFindIndicator(findIndicator.release(), fadeOut, animate); 3157} 3158 3159void WebPageProxy::didFindString(const String& string, uint32_t matchCount) 3160{ 3161 m_findClient.didFindString(this, string, matchCount); 3162} 3163 3164void WebPageProxy::didFindStringMatches(const String& string, Vector<Vector<WebCore::IntRect>> matchRects, int32_t firstIndexAfterSelection) 3165{ 3166 Vector<RefPtr<APIObject>> matches; 3167 matches.reserveInitialCapacity(matchRects.size()); 3168 3169 for (size_t i = 0; i < matchRects.size(); ++i) { 3170 const Vector<WebCore::IntRect>& rects = matchRects[i]; 3171 size_t numRects = matchRects[i].size(); 3172 Vector<RefPtr<APIObject>> apiRects; 3173 apiRects.reserveInitialCapacity(numRects); 3174 3175 for (size_t i = 0; i < numRects; ++i) 3176 apiRects.uncheckedAppend(WebRect::create(toAPI(rects[i]))); 3177 matches.uncheckedAppend(ImmutableArray::adopt(apiRects)); 3178 } 3179 m_findMatchesClient.didFindStringMatches(this, string, ImmutableArray::adopt(matches).get(), firstIndexAfterSelection); 3180} 3181 3182void WebPageProxy::didFailToFindString(const String& string) 3183{ 3184 m_findClient.didFailToFindString(this, string); 3185} 3186 3187void WebPageProxy::valueChangedForPopupMenu(WebPopupMenuProxy*, int32_t newSelectedIndex) 3188{ 3189 m_process->send(Messages::WebPage::DidChangeSelectedIndexForActivePopupMenu(newSelectedIndex), m_pageID); 3190} 3191 3192void WebPageProxy::setTextFromItemForPopupMenu(WebPopupMenuProxy*, int32_t index) 3193{ 3194 m_process->send(Messages::WebPage::SetTextForActivePopupMenu(index), m_pageID); 3195} 3196 3197NativeWebMouseEvent* WebPageProxy::currentlyProcessedMouseDownEvent() 3198{ 3199 return m_currentlyProcessedMouseDownEvent.get(); 3200} 3201 3202void WebPageProxy::postMessageToInjectedBundle(const String& messageName, APIObject* messageBody) 3203{ 3204 process()->send(Messages::WebPage::PostInjectedBundleMessage(messageName, WebContextUserMessageEncoder(messageBody)), m_pageID); 3205} 3206 3207#if PLATFORM(GTK) 3208void WebPageProxy::failedToShowPopupMenu() 3209{ 3210 m_process->send(Messages::WebPage::FailedToShowPopupMenu(), m_pageID); 3211} 3212#endif 3213 3214void WebPageProxy::showPopupMenu(const IntRect& rect, uint64_t textDirection, const Vector<WebPopupItem>& items, int32_t selectedIndex, const PlatformPopupMenuData& data) 3215{ 3216 if (m_activePopupMenu) { 3217#if PLATFORM(EFL) 3218 m_uiPopupMenuClient.hidePopupMenu(this); 3219#else 3220 m_activePopupMenu->hidePopupMenu(); 3221#endif 3222 m_activePopupMenu->invalidate(); 3223 m_activePopupMenu = 0; 3224 } 3225 3226 m_activePopupMenu = m_pageClient->createPopupMenuProxy(this); 3227 3228 if (!m_activePopupMenu) 3229 return; 3230 3231 // Since showPopupMenu() can spin a nested run loop we need to turn off the responsiveness timer. 3232 m_process->responsivenessTimer()->stop(); 3233 3234#if PLATFORM(EFL) 3235 UNUSED_PARAM(data); 3236 m_uiPopupMenuClient.showPopupMenu(this, m_activePopupMenu.get(), rect, static_cast<TextDirection>(textDirection), m_pageScaleFactor, items, selectedIndex); 3237#else 3238 RefPtr<WebPopupMenuProxy> protectedActivePopupMenu = m_activePopupMenu; 3239 3240 protectedActivePopupMenu->showPopupMenu(rect, static_cast<TextDirection>(textDirection), m_pageScaleFactor, items, data, selectedIndex); 3241 3242 // Since Qt and Efl doesn't use a nested mainloop to show the popup and get the answer, we need to keep the client pointer valid. 3243#if !PLATFORM(QT) 3244 protectedActivePopupMenu->invalidate(); 3245#endif 3246 protectedActivePopupMenu = 0; 3247#endif 3248} 3249 3250void WebPageProxy::hidePopupMenu() 3251{ 3252 if (!m_activePopupMenu) 3253 return; 3254 3255#if PLATFORM(EFL) 3256 m_uiPopupMenuClient.hidePopupMenu(this); 3257#else 3258 m_activePopupMenu->hidePopupMenu(); 3259#endif 3260 m_activePopupMenu->invalidate(); 3261 m_activePopupMenu = 0; 3262} 3263 3264#if ENABLE(CONTEXT_MENUS) 3265void WebPageProxy::showContextMenu(const IntPoint& menuLocation, const WebHitTestResult::Data& hitTestResultData, const Vector<WebContextMenuItemData>& proposedItems, CoreIPC::MessageDecoder& decoder) 3266{ 3267 internalShowContextMenu(menuLocation, hitTestResultData, proposedItems, decoder); 3268 3269 // No matter the result of internalShowContextMenu, always notify the WebProcess that the menu is hidden so it starts handling mouse events again. 3270 m_process->send(Messages::WebPage::ContextMenuHidden(), m_pageID); 3271} 3272 3273void WebPageProxy::internalShowContextMenu(const IntPoint& menuLocation, const WebHitTestResult::Data& hitTestResultData, const Vector<WebContextMenuItemData>& proposedItems, CoreIPC::MessageDecoder& decoder) 3274{ 3275 RefPtr<APIObject> userData; 3276 WebContextUserMessageDecoder messageDecoder(userData, m_process.get()); 3277 if (!decoder.decode(messageDecoder)) 3278 return; 3279 3280 m_activeContextMenuHitTestResultData = hitTestResultData; 3281 3282 if (!m_contextMenuClient.hideContextMenu(this) && m_activeContextMenu) { 3283 m_activeContextMenu->hideContextMenu(); 3284 m_activeContextMenu = 0; 3285 } 3286 3287 m_activeContextMenu = m_pageClient->createContextMenuProxy(this); 3288 if (!m_activeContextMenu) 3289 return; 3290 3291 // Since showContextMenu() can spin a nested run loop we need to turn off the responsiveness timer. 3292 m_process->responsivenessTimer()->stop(); 3293 3294 // Give the PageContextMenuClient one last swipe at changing the menu. 3295 Vector<WebContextMenuItemData> items; 3296 if (!m_contextMenuClient.getContextMenuFromProposedMenu(this, proposedItems, items, hitTestResultData, userData.get())) { 3297 if (!m_contextMenuClient.showContextMenu(this, menuLocation, proposedItems)) 3298 m_activeContextMenu->showContextMenu(menuLocation, proposedItems); 3299 } else if (!m_contextMenuClient.showContextMenu(this, menuLocation, items)) 3300 m_activeContextMenu->showContextMenu(menuLocation, items); 3301 3302 m_contextMenuClient.contextMenuDismissed(this); 3303} 3304 3305void WebPageProxy::contextMenuItemSelected(const WebContextMenuItemData& item) 3306{ 3307 // Application custom items don't need to round-trip through to WebCore in the WebProcess. 3308 if (item.action() >= ContextMenuItemBaseApplicationTag) { 3309 m_contextMenuClient.customContextMenuItemSelected(this, item); 3310 return; 3311 } 3312 3313#if PLATFORM(MAC) 3314 if (item.action() == ContextMenuItemTagSmartCopyPaste) { 3315 setSmartInsertDeleteEnabled(!isSmartInsertDeleteEnabled()); 3316 return; 3317 } 3318 if (item.action() == ContextMenuItemTagSmartQuotes) { 3319 TextChecker::setAutomaticQuoteSubstitutionEnabled(!TextChecker::state().isAutomaticQuoteSubstitutionEnabled); 3320 m_process->updateTextCheckerState(); 3321 return; 3322 } 3323 if (item.action() == ContextMenuItemTagSmartDashes) { 3324 TextChecker::setAutomaticDashSubstitutionEnabled(!TextChecker::state().isAutomaticDashSubstitutionEnabled); 3325 m_process->updateTextCheckerState(); 3326 return; 3327 } 3328 if (item.action() == ContextMenuItemTagSmartLinks) { 3329 TextChecker::setAutomaticLinkDetectionEnabled(!TextChecker::state().isAutomaticLinkDetectionEnabled); 3330 m_process->updateTextCheckerState(); 3331 return; 3332 } 3333 if (item.action() == ContextMenuItemTagTextReplacement) { 3334 TextChecker::setAutomaticTextReplacementEnabled(!TextChecker::state().isAutomaticTextReplacementEnabled); 3335 m_process->updateTextCheckerState(); 3336 return; 3337 } 3338 if (item.action() == ContextMenuItemTagCorrectSpellingAutomatically) { 3339 TextChecker::setAutomaticSpellingCorrectionEnabled(!TextChecker::state().isAutomaticSpellingCorrectionEnabled); 3340 m_process->updateTextCheckerState(); 3341 return; 3342 } 3343 if (item.action() == ContextMenuItemTagShowSubstitutions) { 3344 TextChecker::toggleSubstitutionsPanelIsShowing(); 3345 return; 3346 } 3347#endif 3348 if (item.action() == ContextMenuItemTagDownloadImageToDisk) { 3349 m_process->context()->download(this, KURL(KURL(), m_activeContextMenuHitTestResultData.absoluteImageURL)); 3350 return; 3351 } 3352 if (item.action() == ContextMenuItemTagDownloadLinkToDisk) { 3353 m_process->context()->download(this, KURL(KURL(), m_activeContextMenuHitTestResultData.absoluteLinkURL)); 3354 return; 3355 } 3356 if (item.action() == ContextMenuItemTagDownloadMediaToDisk) { 3357 m_process->context()->download(this, KURL(KURL(), m_activeContextMenuHitTestResultData.absoluteMediaURL)); 3358 return; 3359 } 3360 if (item.action() == ContextMenuItemTagCheckSpellingWhileTyping) { 3361 TextChecker::setContinuousSpellCheckingEnabled(!TextChecker::state().isContinuousSpellCheckingEnabled); 3362 m_process->updateTextCheckerState(); 3363 return; 3364 } 3365 if (item.action() == ContextMenuItemTagCheckGrammarWithSpelling) { 3366 TextChecker::setGrammarCheckingEnabled(!TextChecker::state().isGrammarCheckingEnabled); 3367 m_process->updateTextCheckerState(); 3368 return; 3369 } 3370 if (item.action() == ContextMenuItemTagShowSpellingPanel) { 3371 if (!TextChecker::spellingUIIsShowing()) 3372 advanceToNextMisspelling(true); 3373 TextChecker::toggleSpellingUIIsShowing(); 3374 return; 3375 } 3376 if (item.action() == ContextMenuItemTagLearnSpelling || item.action() == ContextMenuItemTagIgnoreSpelling) 3377 ++m_pendingLearnOrIgnoreWordMessageCount; 3378 3379 m_process->send(Messages::WebPage::DidSelectItemFromActiveContextMenu(item), m_pageID); 3380} 3381#endif // ENABLE(CONTEXT_MENUS) 3382 3383void WebPageProxy::didChooseFilesForOpenPanel(const Vector<String>& fileURLs) 3384{ 3385 if (!isValid()) 3386 return; 3387 3388#if ENABLE(WEB_PROCESS_SANDBOX) 3389 // FIXME: The sandbox extensions should be sent with the DidChooseFilesForOpenPanel message. This 3390 // is gated on a way of passing SandboxExtension::Handles in a Vector. 3391 for (size_t i = 0; i < fileURLs.size(); ++i) { 3392 SandboxExtension::Handle sandboxExtensionHandle; 3393 SandboxExtension::createHandle(fileURLs[i], SandboxExtension::ReadOnly, sandboxExtensionHandle); 3394 m_process->send(Messages::WebPage::ExtendSandboxForFileFromOpenPanel(sandboxExtensionHandle), m_pageID); 3395 } 3396#endif 3397 3398 m_process->send(Messages::WebPage::DidChooseFilesForOpenPanel(fileURLs), m_pageID); 3399 3400 m_openPanelResultListener->invalidate(); 3401 m_openPanelResultListener = 0; 3402} 3403 3404void WebPageProxy::didCancelForOpenPanel() 3405{ 3406 if (!isValid()) 3407 return; 3408 3409 m_process->send(Messages::WebPage::DidCancelForOpenPanel(), m_pageID); 3410 3411 m_openPanelResultListener->invalidate(); 3412 m_openPanelResultListener = 0; 3413} 3414 3415void WebPageProxy::advanceToNextMisspelling(bool startBeforeSelection) const 3416{ 3417 m_process->send(Messages::WebPage::AdvanceToNextMisspelling(startBeforeSelection), m_pageID); 3418} 3419 3420void WebPageProxy::changeSpellingToWord(const String& word) const 3421{ 3422 if (word.isEmpty()) 3423 return; 3424 3425 m_process->send(Messages::WebPage::ChangeSpellingToWord(word), m_pageID); 3426} 3427 3428void WebPageProxy::registerEditCommand(PassRefPtr<WebEditCommandProxy> commandProxy, UndoOrRedo undoOrRedo) 3429{ 3430 m_pageClient->registerEditCommand(commandProxy, undoOrRedo); 3431} 3432 3433void WebPageProxy::addEditCommand(WebEditCommandProxy* command) 3434{ 3435 m_editCommandSet.add(command); 3436} 3437 3438void WebPageProxy::removeEditCommand(WebEditCommandProxy* command) 3439{ 3440 m_editCommandSet.remove(command); 3441 3442 if (!isValid()) 3443 return; 3444 m_process->send(Messages::WebPage::DidRemoveEditCommand(command->commandID()), m_pageID); 3445} 3446 3447bool WebPageProxy::isValidEditCommand(WebEditCommandProxy* command) 3448{ 3449 return m_editCommandSet.find(command) != m_editCommandSet.end(); 3450} 3451 3452int64_t WebPageProxy::spellDocumentTag() 3453{ 3454 if (!m_hasSpellDocumentTag) { 3455 m_spellDocumentTag = TextChecker::uniqueSpellDocumentTag(this); 3456 m_hasSpellDocumentTag = true; 3457 } 3458 3459 return m_spellDocumentTag; 3460} 3461 3462#if USE(UNIFIED_TEXT_CHECKING) 3463void WebPageProxy::checkTextOfParagraph(const String& text, uint64_t checkingTypes, Vector<TextCheckingResult>& results) 3464{ 3465 results = TextChecker::checkTextOfParagraph(spellDocumentTag(), text.characters(), text.length(), checkingTypes); 3466} 3467#endif 3468 3469void WebPageProxy::checkSpellingOfString(const String& text, int32_t& misspellingLocation, int32_t& misspellingLength) 3470{ 3471 TextChecker::checkSpellingOfString(spellDocumentTag(), text.characters(), text.length(), misspellingLocation, misspellingLength); 3472} 3473 3474void WebPageProxy::checkGrammarOfString(const String& text, Vector<GrammarDetail>& grammarDetails, int32_t& badGrammarLocation, int32_t& badGrammarLength) 3475{ 3476 TextChecker::checkGrammarOfString(spellDocumentTag(), text.characters(), text.length(), grammarDetails, badGrammarLocation, badGrammarLength); 3477} 3478 3479void WebPageProxy::spellingUIIsShowing(bool& isShowing) 3480{ 3481 isShowing = TextChecker::spellingUIIsShowing(); 3482} 3483 3484void WebPageProxy::updateSpellingUIWithMisspelledWord(const String& misspelledWord) 3485{ 3486 TextChecker::updateSpellingUIWithMisspelledWord(spellDocumentTag(), misspelledWord); 3487} 3488 3489void WebPageProxy::updateSpellingUIWithGrammarString(const String& badGrammarPhrase, const GrammarDetail& grammarDetail) 3490{ 3491 TextChecker::updateSpellingUIWithGrammarString(spellDocumentTag(), badGrammarPhrase, grammarDetail); 3492} 3493 3494void WebPageProxy::getGuessesForWord(const String& word, const String& context, Vector<String>& guesses) 3495{ 3496 TextChecker::getGuessesForWord(spellDocumentTag(), word, context, guesses); 3497} 3498 3499void WebPageProxy::learnWord(const String& word) 3500{ 3501 MESSAGE_CHECK(m_pendingLearnOrIgnoreWordMessageCount); 3502 --m_pendingLearnOrIgnoreWordMessageCount; 3503 3504 TextChecker::learnWord(spellDocumentTag(), word); 3505} 3506 3507void WebPageProxy::ignoreWord(const String& word) 3508{ 3509 MESSAGE_CHECK(m_pendingLearnOrIgnoreWordMessageCount); 3510 --m_pendingLearnOrIgnoreWordMessageCount; 3511 3512 TextChecker::ignoreWord(spellDocumentTag(), word); 3513} 3514 3515void WebPageProxy::requestCheckingOfString(uint64_t requestID, const TextCheckingRequestData& request) 3516{ 3517 TextChecker::requestCheckingOfString(TextCheckerCompletion::create(requestID, request, this)); 3518} 3519 3520void WebPageProxy::didFinishCheckingText(uint64_t requestID, const Vector<WebCore::TextCheckingResult>& result) const 3521{ 3522 m_process->send(Messages::WebPage::DidFinishCheckingText(requestID, result), m_pageID); 3523} 3524 3525void WebPageProxy::didCancelCheckingText(uint64_t requestID) const 3526{ 3527 m_process->send(Messages::WebPage::DidCancelCheckingText(requestID), m_pageID); 3528} 3529// Other 3530 3531void WebPageProxy::setFocus(bool focused) 3532{ 3533 if (focused) 3534 m_uiClient.focus(this); 3535 else 3536 m_uiClient.unfocus(this); 3537} 3538 3539void WebPageProxy::takeFocus(uint32_t direction) 3540{ 3541 m_uiClient.takeFocus(this, (static_cast<FocusDirection>(direction) == FocusDirectionForward) ? kWKFocusDirectionForward : kWKFocusDirectionBackward); 3542} 3543 3544void WebPageProxy::setToolTip(const String& toolTip) 3545{ 3546 String oldToolTip = m_toolTip; 3547 m_toolTip = toolTip; 3548 m_pageClient->toolTipChanged(oldToolTip, m_toolTip); 3549} 3550 3551void WebPageProxy::setCursor(const WebCore::Cursor& cursor) 3552{ 3553 // The Web process may have asked to change the cursor when the view was in an active window, but 3554 // if it is no longer in a window or the window is not active, then the cursor should not change. 3555 if (m_pageClient->isViewWindowActive()) 3556 m_pageClient->setCursor(cursor); 3557} 3558 3559void WebPageProxy::setCursorHiddenUntilMouseMoves(bool hiddenUntilMouseMoves) 3560{ 3561 m_pageClient->setCursorHiddenUntilMouseMoves(hiddenUntilMouseMoves); 3562} 3563 3564void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled) 3565{ 3566 WebEvent::Type type = static_cast<WebEvent::Type>(opaqueType); 3567 3568 switch (type) { 3569 case WebEvent::NoType: 3570 case WebEvent::MouseMove: 3571 break; 3572 3573 case WebEvent::MouseDown: 3574 case WebEvent::MouseUp: 3575 case WebEvent::Wheel: 3576 case WebEvent::KeyDown: 3577 case WebEvent::KeyUp: 3578 case WebEvent::RawKeyDown: 3579 case WebEvent::Char: 3580#if ENABLE(GESTURE_EVENTS) 3581 case WebEvent::GestureScrollBegin: 3582 case WebEvent::GestureScrollEnd: 3583 case WebEvent::GestureSingleTap: 3584#endif 3585#if ENABLE(TOUCH_EVENTS) 3586 case WebEvent::TouchStart: 3587 case WebEvent::TouchMove: 3588 case WebEvent::TouchEnd: 3589 case WebEvent::TouchCancel: 3590#endif 3591 m_process->responsivenessTimer()->stop(); 3592 break; 3593 } 3594 3595 switch (type) { 3596 case WebEvent::NoType: 3597 break; 3598 case WebEvent::MouseMove: 3599 m_processingMouseMoveEvent = false; 3600 if (m_nextMouseMoveEvent) { 3601 handleMouseEvent(*m_nextMouseMoveEvent); 3602 m_nextMouseMoveEvent = nullptr; 3603 } 3604 break; 3605 case WebEvent::MouseDown: 3606 break; 3607#if ENABLE(GESTURE_EVENTS) 3608 case WebEvent::GestureScrollBegin: 3609 case WebEvent::GestureScrollEnd: 3610 case WebEvent::GestureSingleTap: { 3611 WebGestureEvent event = m_gestureEventQueue.first(); 3612 MESSAGE_CHECK(type == event.type()); 3613 3614 m_gestureEventQueue.removeFirst(); 3615 m_pageClient->doneWithGestureEvent(event, handled); 3616 break; 3617 } 3618#endif 3619 case WebEvent::MouseUp: 3620 m_currentlyProcessedMouseDownEvent = nullptr; 3621 break; 3622 3623 case WebEvent::Wheel: { 3624 MESSAGE_CHECK(!m_currentlyProcessedWheelEvents.isEmpty()); 3625 3626 OwnPtr<Vector<NativeWebWheelEvent>> oldestCoalescedEvent = m_currentlyProcessedWheelEvents.takeFirst(); 3627 3628 // FIXME: Dispatch additional events to the didNotHandleWheelEvent client function. 3629 if (!handled && m_uiClient.implementsDidNotHandleWheelEvent()) 3630 m_uiClient.didNotHandleWheelEvent(this, oldestCoalescedEvent->last()); 3631 3632 if (!m_wheelEventQueue.isEmpty()) 3633 processNextQueuedWheelEvent(); 3634 break; 3635 } 3636 3637 case WebEvent::KeyDown: 3638 case WebEvent::KeyUp: 3639 case WebEvent::RawKeyDown: 3640 case WebEvent::Char: { 3641 LOG(KeyHandling, "WebPageProxy::didReceiveEvent: %s", webKeyboardEventTypeString(type)); 3642 3643 MESSAGE_CHECK(!m_keyEventQueue.isEmpty()); 3644 NativeWebKeyboardEvent event = m_keyEventQueue.takeFirst(); 3645 3646 MESSAGE_CHECK(type == event.type()); 3647 3648 if (!m_keyEventQueue.isEmpty()) 3649 m_process->send(Messages::WebPage::KeyEvent(m_keyEventQueue.first()), m_pageID); 3650 3651 m_pageClient->doneWithKeyEvent(event, handled); 3652 if (handled) 3653 break; 3654 3655 if (m_uiClient.implementsDidNotHandleKeyEvent()) 3656 m_uiClient.didNotHandleKeyEvent(this, event); 3657 break; 3658 } 3659#if ENABLE(TOUCH_EVENTS) 3660 case WebEvent::TouchStart: 3661 case WebEvent::TouchMove: 3662 case WebEvent::TouchEnd: 3663 case WebEvent::TouchCancel: { 3664 MESSAGE_CHECK(!m_touchEventQueue.isEmpty()); 3665 QueuedTouchEvents queuedEvents = m_touchEventQueue.takeFirst(); 3666 3667 MESSAGE_CHECK(type == queuedEvents.forwardedEvent.type()); 3668 3669 m_pageClient->doneWithTouchEvent(queuedEvents.forwardedEvent, handled); 3670 for (size_t i = 0; i < queuedEvents.deferredTouchEvents.size(); ++i) { 3671 bool isEventHandled = false; 3672 m_pageClient->doneWithTouchEvent(queuedEvents.deferredTouchEvents.at(i), isEventHandled); 3673 } 3674 break; 3675 } 3676#endif 3677 } 3678} 3679 3680void WebPageProxy::stopResponsivenessTimer() 3681{ 3682 m_process->responsivenessTimer()->stop(); 3683} 3684 3685void WebPageProxy::voidCallback(uint64_t callbackID) 3686{ 3687 RefPtr<VoidCallback> callback = m_voidCallbacks.take(callbackID); 3688 if (!callback) { 3689 // FIXME: Log error or assert. 3690 return; 3691 } 3692 3693 callback->performCallback(); 3694} 3695 3696void WebPageProxy::dataCallback(const CoreIPC::DataReference& dataReference, uint64_t callbackID) 3697{ 3698 RefPtr<DataCallback> callback = m_dataCallbacks.take(callbackID); 3699 if (!callback) { 3700 // FIXME: Log error or assert. 3701 return; 3702 } 3703 3704 callback->performCallbackWithReturnValue(WebData::create(dataReference.data(), dataReference.size()).get()); 3705} 3706 3707void WebPageProxy::imageCallback(const ShareableBitmap::Handle& bitmapHandle, uint64_t callbackID) 3708{ 3709 RefPtr<ImageCallback> callback = m_imageCallbacks.take(callbackID); 3710 if (!callback) { 3711 // FIXME: Log error or assert. 3712 return; 3713 } 3714 3715 callback->performCallbackWithReturnValue(bitmapHandle); 3716} 3717 3718void WebPageProxy::stringCallback(const String& resultString, uint64_t callbackID) 3719{ 3720 RefPtr<StringCallback> callback = m_stringCallbacks.take(callbackID); 3721 if (!callback) { 3722 // FIXME: Log error or assert. 3723 // this can validly happen if a load invalidated the callback, though 3724 return; 3725 } 3726 3727 m_loadDependentStringCallbackIDs.remove(callbackID); 3728 3729 callback->performCallbackWithReturnValue(resultString.impl()); 3730} 3731 3732void WebPageProxy::scriptValueCallback(const CoreIPC::DataReference& dataReference, uint64_t callbackID) 3733{ 3734 RefPtr<ScriptValueCallback> callback = m_scriptValueCallbacks.take(callbackID); 3735 if (!callback) { 3736 // FIXME: Log error or assert. 3737 return; 3738 } 3739 3740 Vector<uint8_t> data; 3741 data.reserveInitialCapacity(dataReference.size()); 3742 data.append(dataReference.data(), dataReference.size()); 3743 3744 callback->performCallbackWithReturnValue(data.size() ? WebSerializedScriptValue::adopt(data).get() : 0); 3745} 3746 3747void WebPageProxy::computedPagesCallback(const Vector<IntRect>& pageRects, double totalScaleFactorForPrinting, uint64_t callbackID) 3748{ 3749 RefPtr<ComputedPagesCallback> callback = m_computedPagesCallbacks.take(callbackID); 3750 if (!callback) { 3751 // FIXME: Log error or assert. 3752 return; 3753 } 3754 3755 callback->performCallbackWithReturnValue(pageRects, totalScaleFactorForPrinting); 3756} 3757 3758void WebPageProxy::validateCommandCallback(const String& commandName, bool isEnabled, int state, uint64_t callbackID) 3759{ 3760 RefPtr<ValidateCommandCallback> callback = m_validateCommandCallbacks.take(callbackID); 3761 if (!callback) { 3762 // FIXME: Log error or assert. 3763 return; 3764 } 3765 3766 callback->performCallbackWithReturnValue(commandName.impl(), isEnabled, state); 3767} 3768 3769#if PLATFORM(GTK) 3770void WebPageProxy::printFinishedCallback(const ResourceError& printError, uint64_t callbackID) 3771{ 3772 RefPtr<PrintFinishedCallback> callback = m_printFinishedCallbacks.take(callbackID); 3773 if (!callback) { 3774 // FIXME: Log error or assert. 3775 return; 3776 } 3777 3778 RefPtr<WebError> error = WebError::create(printError); 3779 callback->performCallbackWithReturnValue(error.get()); 3780} 3781#endif 3782 3783void WebPageProxy::focusedFrameChanged(uint64_t frameID) 3784{ 3785 if (!frameID) { 3786 m_focusedFrame = 0; 3787 return; 3788 } 3789 3790 WebFrameProxy* frame = m_process->webFrame(frameID); 3791 MESSAGE_CHECK(frame); 3792 3793 m_focusedFrame = frame; 3794} 3795 3796void WebPageProxy::frameSetLargestFrameChanged(uint64_t frameID) 3797{ 3798 if (!frameID) { 3799 m_frameSetLargestFrame = 0; 3800 return; 3801 } 3802 3803 WebFrameProxy* frame = m_process->webFrame(frameID); 3804 MESSAGE_CHECK(frame); 3805 3806 m_frameSetLargestFrame = frame; 3807} 3808 3809void WebPageProxy::processDidBecomeUnresponsive() 3810{ 3811 if (!isValid()) 3812 return; 3813 3814 updateBackingStoreDiscardableState(); 3815 3816 m_loaderClient.processDidBecomeUnresponsive(this); 3817} 3818 3819void WebPageProxy::interactionOccurredWhileProcessUnresponsive() 3820{ 3821 if (!isValid()) 3822 return; 3823 3824 m_loaderClient.interactionOccurredWhileProcessUnresponsive(this); 3825} 3826 3827void WebPageProxy::processDidBecomeResponsive() 3828{ 3829 if (!isValid()) 3830 return; 3831 3832 updateBackingStoreDiscardableState(); 3833 3834 m_loaderClient.processDidBecomeResponsive(this); 3835} 3836 3837void WebPageProxy::processDidCrash() 3838{ 3839 ASSERT(m_isValid); 3840 3841 resetStateAfterProcessExited(); 3842 3843 m_pageClient->processDidCrash(); 3844 m_loaderClient.processDidCrash(this); 3845} 3846 3847void WebPageProxy::resetStateAfterProcessExited() 3848{ 3849 if (!isValid()) 3850 return; 3851 3852 ASSERT(m_pageClient); 3853 m_process->removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID); 3854 3855 m_isValid = false; 3856 m_isPageSuspended = false; 3857 m_waitingForDidUpdateInWindowState = false; 3858 3859 if (m_mainFrame) { 3860 m_urlAtProcessExit = m_mainFrame->url(); 3861 m_loadStateAtProcessExit = m_mainFrame->loadState(); 3862 } 3863 3864 m_mainFrame = nullptr; 3865 m_drawingArea = nullptr; 3866 3867#if ENABLE(INSPECTOR) 3868 m_inspector->invalidate(); 3869 m_inspector = nullptr; 3870#endif 3871 3872#if ENABLE(FULLSCREEN_API) 3873 m_fullScreenManager->invalidate(); 3874 m_fullScreenManager = nullptr; 3875#endif 3876 3877#if ENABLE(VIBRATION) 3878 m_vibration->invalidate(); 3879#endif 3880 3881 if (m_openPanelResultListener) { 3882 m_openPanelResultListener->invalidate(); 3883 m_openPanelResultListener = nullptr; 3884 } 3885 3886#if ENABLE(INPUT_TYPE_COLOR) 3887 if (m_colorChooser) { 3888 m_colorChooser->invalidate(); 3889 m_colorChooser = nullptr; 3890 } 3891 3892 if (m_colorPickerResultListener) { 3893 m_colorPickerResultListener->invalidate(); 3894 m_colorPickerResultListener = nullptr; 3895 } 3896#endif 3897 3898#if ENABLE(GEOLOCATION) 3899 m_geolocationPermissionRequestManager.invalidateRequests(); 3900#endif 3901 3902 m_notificationPermissionRequestManager.invalidateRequests(); 3903 3904 m_toolTip = String(); 3905 3906 m_mainFrameHasHorizontalScrollbar = false; 3907 m_mainFrameHasVerticalScrollbar = false; 3908 3909 m_mainFrameIsPinnedToLeftSide = false; 3910 m_mainFrameIsPinnedToRightSide = false; 3911 m_mainFrameIsPinnedToTopSide = false; 3912 m_mainFrameIsPinnedToBottomSide = false; 3913 3914 m_visibleScrollerThumbRect = IntRect(); 3915 3916 invalidateCallbackMap(m_voidCallbacks); 3917 invalidateCallbackMap(m_dataCallbacks); 3918 invalidateCallbackMap(m_stringCallbacks); 3919 m_loadDependentStringCallbackIDs.clear(); 3920 invalidateCallbackMap(m_scriptValueCallbacks); 3921 invalidateCallbackMap(m_computedPagesCallbacks); 3922 invalidateCallbackMap(m_validateCommandCallbacks); 3923#if PLATFORM(GTK) 3924 invalidateCallbackMap(m_printFinishedCallbacks); 3925#endif 3926 3927 Vector<WebEditCommandProxy*> editCommandVector; 3928 copyToVector(m_editCommandSet, editCommandVector); 3929 m_editCommandSet.clear(); 3930 for (size_t i = 0, size = editCommandVector.size(); i < size; ++i) 3931 editCommandVector[i]->invalidate(); 3932 m_pageClient->clearAllEditCommands(); 3933 3934 m_activePopupMenu = 0; 3935 3936 m_estimatedProgress = 0.0; 3937 3938 m_pendingLearnOrIgnoreWordMessageCount = 0; 3939 3940 // If the call out to the loader client didn't cause the web process to be relaunched, 3941 // we'll call setNeedsDisplay on the view so that we won't have the old contents showing. 3942 // If the call did cause the web process to be relaunched, we'll keep the old page contents showing 3943 // until the new web process has painted its contents. 3944 setViewNeedsDisplay(IntRect(IntPoint(), viewSize())); 3945 3946 // Can't expect DidReceiveEvent notifications from a crashed web process. 3947#if ENABLE(GESTURE_EVENTS) 3948 m_gestureEventQueue.clear(); 3949#endif 3950 m_keyEventQueue.clear(); 3951 m_wheelEventQueue.clear(); 3952 m_currentlyProcessedWheelEvents.clear(); 3953 3954 m_nextMouseMoveEvent = nullptr; 3955 m_currentlyProcessedMouseDownEvent = nullptr; 3956 3957 m_processingMouseMoveEvent = false; 3958 3959#if ENABLE(TOUCH_EVENTS) 3960 m_needTouchEvents = false; 3961 m_touchEventQueue.clear(); 3962#endif 3963 3964 // FIXME: Reset m_editorState. 3965 // FIXME: Notify input methods about abandoned composition. 3966 m_temporarilyClosedComposition = false; 3967 3968#if PLATFORM(MAC) 3969 dismissCorrectionPanel(ReasonForDismissingAlternativeTextIgnored); 3970 m_pageClient->dismissDictionaryLookupPanel(); 3971#endif 3972} 3973 3974WebPageCreationParameters WebPageProxy::creationParameters() const 3975{ 3976 WebPageCreationParameters parameters; 3977 3978 parameters.viewSize = m_pageClient->viewSize(); 3979 parameters.isActive = m_pageClient->isViewWindowActive(); 3980 parameters.isFocused = m_pageClient->isViewFocused(); 3981 parameters.isVisible = m_pageClient->isViewVisible(); 3982 parameters.isInWindow = m_pageClient->isViewInWindow(); 3983 parameters.drawingAreaType = m_drawingArea->type(); 3984 parameters.store = m_pageGroup->preferences()->store(); 3985 parameters.pageGroupData = m_pageGroup->data(); 3986 parameters.drawsBackground = m_drawsBackground; 3987 parameters.drawsTransparentBackground = m_drawsTransparentBackground; 3988 parameters.underlayColor = m_underlayColor; 3989 parameters.areMemoryCacheClientCallsEnabled = m_areMemoryCacheClientCallsEnabled; 3990 parameters.useFixedLayout = m_useFixedLayout; 3991 parameters.fixedLayoutSize = m_fixedLayoutSize; 3992 parameters.suppressScrollbarAnimations = m_suppressScrollbarAnimations; 3993 parameters.paginationMode = m_paginationMode; 3994 parameters.paginationBehavesLikeColumns = m_paginationBehavesLikeColumns; 3995 parameters.pageLength = m_pageLength; 3996 parameters.gapBetweenPages = m_gapBetweenPages; 3997 parameters.userAgent = userAgent(); 3998 parameters.sessionState = SessionState(m_backForwardList->entries(), m_backForwardList->currentIndex()); 3999 parameters.highestUsedBackForwardItemID = WebBackForwardListItem::highedUsedItemID(); 4000 parameters.canRunBeforeUnloadConfirmPanel = m_uiClient.canRunBeforeUnloadConfirmPanel(); 4001 parameters.canRunModal = m_canRunModal; 4002 parameters.deviceScaleFactor = deviceScaleFactor(); 4003 parameters.mediaVolume = m_mediaVolume; 4004 parameters.mayStartMediaWhenInWindow = m_mayStartMediaWhenInWindow; 4005 parameters.minimumLayoutSize = m_minimumLayoutSize; 4006 parameters.autoSizingShouldExpandToViewHeight = m_autoSizingShouldExpandToViewHeight; 4007 parameters.scrollPinningBehavior = m_scrollPinningBehavior; 4008 4009#if PLATFORM(MAC) 4010 parameters.layerHostingMode = m_layerHostingMode; 4011 parameters.colorSpace = m_pageClient->colorSpace(); 4012#endif 4013 4014 return parameters; 4015} 4016 4017#if USE(ACCELERATED_COMPOSITING) 4018void WebPageProxy::enterAcceleratedCompositingMode(const LayerTreeContext& layerTreeContext) 4019{ 4020 m_pageClient->enterAcceleratedCompositingMode(layerTreeContext); 4021} 4022 4023void WebPageProxy::exitAcceleratedCompositingMode() 4024{ 4025 m_pageClient->exitAcceleratedCompositingMode(); 4026} 4027 4028void WebPageProxy::updateAcceleratedCompositingMode(const LayerTreeContext& layerTreeContext) 4029{ 4030 m_pageClient->updateAcceleratedCompositingMode(layerTreeContext); 4031} 4032#endif // USE(ACCELERATED_COMPOSITING) 4033 4034void WebPageProxy::backForwardClear() 4035{ 4036 m_backForwardList->clear(); 4037} 4038 4039void WebPageProxy::canAuthenticateAgainstProtectionSpaceInFrame(uint64_t frameID, const ProtectionSpace& coreProtectionSpace, bool& canAuthenticate) 4040{ 4041 WebFrameProxy* frame = m_process->webFrame(frameID); 4042 MESSAGE_CHECK(frame); 4043 4044 RefPtr<WebProtectionSpace> protectionSpace = WebProtectionSpace::create(coreProtectionSpace); 4045 4046 canAuthenticate = m_loaderClient.canAuthenticateAgainstProtectionSpaceInFrame(this, frame, protectionSpace.get()); 4047} 4048 4049void WebPageProxy::didReceiveAuthenticationChallenge(uint64_t frameID, const AuthenticationChallenge& coreChallenge, uint64_t challengeID) 4050{ 4051 didReceiveAuthenticationChallengeProxy(frameID, AuthenticationChallengeProxy::create(coreChallenge, challengeID, m_process->connection())); 4052} 4053 4054void WebPageProxy::didReceiveAuthenticationChallengeProxy(uint64_t frameID, PassRefPtr<AuthenticationChallengeProxy> prpAuthenticationChallenge) 4055{ 4056 ASSERT(prpAuthenticationChallenge); 4057 4058 WebFrameProxy* frame = m_process->webFrame(frameID); 4059 MESSAGE_CHECK(frame); 4060 4061 RefPtr<AuthenticationChallengeProxy> authenticationChallenge = prpAuthenticationChallenge; 4062 m_loaderClient.didReceiveAuthenticationChallengeInFrame(this, frame, authenticationChallenge.get()); 4063} 4064 4065void WebPageProxy::exceededDatabaseQuota(uint64_t frameID, const String& originIdentifier, const String& databaseName, const String& displayName, uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage, PassRefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply> reply) 4066{ 4067 ExceededDatabaseQuotaRecords& records = ExceededDatabaseQuotaRecords::shared(); 4068 OwnPtr<ExceededDatabaseQuotaRecords::Record> newRecord = records.createRecord(frameID, 4069 originIdentifier, databaseName, displayName, currentQuota, currentOriginUsage, 4070 currentDatabaseUsage, expectedUsage, reply); 4071 records.add(newRecord.release()); 4072 4073 if (records.areBeingProcessed()) 4074 return; 4075 4076 ExceededDatabaseQuotaRecords::Record* record = records.next(); 4077 while (record) { 4078 WebFrameProxy* frame = m_process->webFrame(record->frameID); 4079 MESSAGE_CHECK(frame); 4080 4081 RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::createFromDatabaseIdentifier(record->originIdentifier); 4082 4083 uint64_t newQuota = m_uiClient.exceededDatabaseQuota(this, frame, origin.get(), 4084 record->databaseName, record->displayName, record->currentQuota, 4085 record->currentOriginUsage, record->currentDatabaseUsage, record->expectedUsage); 4086 4087 record->reply->send(newQuota); 4088 record = records.next(); 4089 } 4090} 4091 4092void WebPageProxy::requestGeolocationPermissionForFrame(uint64_t geolocationID, uint64_t frameID, String originIdentifier) 4093{ 4094 WebFrameProxy* frame = m_process->webFrame(frameID); 4095 MESSAGE_CHECK(frame); 4096 4097 // FIXME: Geolocation should probably be using toString() as its string representation instead of databaseIdentifier(). 4098 RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::createFromDatabaseIdentifier(originIdentifier); 4099 RefPtr<GeolocationPermissionRequestProxy> request = m_geolocationPermissionRequestManager.createRequest(geolocationID); 4100 4101 if (!m_uiClient.decidePolicyForGeolocationPermissionRequest(this, frame, origin.get(), request.get())) 4102 request->deny(); 4103} 4104 4105void WebPageProxy::requestNotificationPermission(uint64_t requestID, const String& originString) 4106{ 4107 if (!isRequestIDValid(requestID)) 4108 return; 4109 4110 RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::createFromString(originString); 4111 RefPtr<NotificationPermissionRequest> request = m_notificationPermissionRequestManager.createRequest(requestID); 4112 4113 if (!m_uiClient.decidePolicyForNotificationPermissionRequest(this, origin.get(), request.get())) 4114 request->deny(); 4115} 4116 4117void WebPageProxy::showNotification(const String& title, const String& body, const String& iconURL, const String& tag, const String& lang, const String& dir, const String& originString, uint64_t notificationID) 4118{ 4119 m_process->context()->supplement<WebNotificationManagerProxy>()->show(this, title, body, iconURL, tag, lang, dir, originString, notificationID); 4120} 4121 4122void WebPageProxy::cancelNotification(uint64_t notificationID) 4123{ 4124 m_process->context()->supplement<WebNotificationManagerProxy>()->cancel(this, notificationID); 4125} 4126 4127void WebPageProxy::clearNotifications(const Vector<uint64_t>& notificationIDs) 4128{ 4129 m_process->context()->supplement<WebNotificationManagerProxy>()->clearNotifications(this, notificationIDs); 4130} 4131 4132void WebPageProxy::didDestroyNotification(uint64_t notificationID) 4133{ 4134 m_process->context()->supplement<WebNotificationManagerProxy>()->didDestroyNotification(this, notificationID); 4135} 4136 4137float WebPageProxy::headerHeight(WebFrameProxy* frame) 4138{ 4139 if (frame->isDisplayingPDFDocument()) 4140 return 0; 4141 return m_uiClient.headerHeight(this, frame); 4142} 4143 4144float WebPageProxy::footerHeight(WebFrameProxy* frame) 4145{ 4146 if (frame->isDisplayingPDFDocument()) 4147 return 0; 4148 return m_uiClient.footerHeight(this, frame); 4149} 4150 4151void WebPageProxy::drawHeader(WebFrameProxy* frame, const FloatRect& rect) 4152{ 4153 if (frame->isDisplayingPDFDocument()) 4154 return; 4155 m_uiClient.drawHeader(this, frame, rect); 4156} 4157 4158void WebPageProxy::drawFooter(WebFrameProxy* frame, const FloatRect& rect) 4159{ 4160 if (frame->isDisplayingPDFDocument()) 4161 return; 4162 m_uiClient.drawFooter(this, frame, rect); 4163} 4164 4165void WebPageProxy::runModal() 4166{ 4167 // Since runModal() can (and probably will) spin a nested run loop we need to turn off the responsiveness timer. 4168 m_process->responsivenessTimer()->stop(); 4169 4170 // Our Connection's run loop might have more messages waiting to be handled after this RunModal message. 4171 // To make sure they are handled inside of the the nested modal run loop we must first signal the Connection's 4172 // run loop so we're guaranteed that it has a chance to wake up. 4173 // See http://webkit.org/b/89590 for more discussion. 4174 m_process->connection()->wakeUpRunLoop(); 4175 4176 m_uiClient.runModal(this); 4177} 4178 4179void WebPageProxy::notifyScrollerThumbIsVisibleInRect(const IntRect& scrollerThumb) 4180{ 4181 m_visibleScrollerThumbRect = scrollerThumb; 4182} 4183 4184void WebPageProxy::recommendedScrollbarStyleDidChange(int32_t newStyle) 4185{ 4186#if PLATFORM(MAC) 4187 m_pageClient->recommendedScrollbarStyleDidChange(newStyle); 4188#else 4189 UNUSED_PARAM(newStyle); 4190#endif 4191} 4192 4193void WebPageProxy::didChangeScrollbarsForMainFrame(bool hasHorizontalScrollbar, bool hasVerticalScrollbar) 4194{ 4195 m_mainFrameHasHorizontalScrollbar = hasHorizontalScrollbar; 4196 m_mainFrameHasVerticalScrollbar = hasVerticalScrollbar; 4197} 4198 4199void WebPageProxy::didChangeScrollOffsetPinningForMainFrame(bool pinnedToLeftSide, bool pinnedToRightSide, bool pinnedToTopSide, bool pinnedToBottomSide) 4200{ 4201 m_mainFrameIsPinnedToLeftSide = pinnedToLeftSide; 4202 m_mainFrameIsPinnedToRightSide = pinnedToRightSide; 4203 m_mainFrameIsPinnedToTopSide = pinnedToTopSide; 4204 m_mainFrameIsPinnedToBottomSide = pinnedToBottomSide; 4205} 4206 4207void WebPageProxy::didChangePageCount(unsigned pageCount) 4208{ 4209 m_pageCount = pageCount; 4210} 4211 4212void WebPageProxy::didFailToInitializePlugin(const String& mimeType, const String& frameURLString, const String& pageURLString) 4213{ 4214 m_loaderClient.didFailToInitializePlugin(this, createPluginInformationDictionary(mimeType, frameURLString, pageURLString).get()); 4215} 4216 4217void WebPageProxy::didBlockInsecurePluginVersion(const String& mimeType, const String& pluginURLString, const String& frameURLString, const String& pageURLString, bool replacementObscured) 4218{ 4219 RefPtr<ImmutableDictionary> pluginInformation; 4220 4221#if PLATFORM(MAC) && ENABLE(NETSCAPE_PLUGIN_API) 4222 String newMimeType = mimeType; 4223 PluginModuleInfo plugin = m_process->context()->pluginInfoStore().findPlugin(newMimeType, KURL(KURL(), pluginURLString)); 4224 pluginInformation = createPluginInformationDictionary(plugin, frameURLString, mimeType, pageURLString, String(), String(), replacementObscured); 4225#else 4226 UNUSED_PARAM(pluginURLString); 4227#endif 4228 4229 m_loaderClient.didBlockInsecurePluginVersion(this, pluginInformation.get()); 4230} 4231 4232bool WebPageProxy::willHandleHorizontalScrollEvents() const 4233{ 4234 return !m_canShortCircuitHorizontalWheelEvents; 4235} 4236 4237void WebPageProxy::didFinishLoadingDataForCustomRepresentation(const String& suggestedFilename, const CoreIPC::DataReference& dataReference) 4238{ 4239 m_pageClient->didFinishLoadingDataForCustomRepresentation(suggestedFilename, dataReference); 4240} 4241 4242void WebPageProxy::backForwardRemovedItem(uint64_t itemID) 4243{ 4244 m_process->send(Messages::WebPage::DidRemoveBackForwardItem(itemID), m_pageID); 4245} 4246 4247void WebPageProxy::setCanRunModal(bool canRunModal) 4248{ 4249 if (!isValid()) 4250 return; 4251 4252 // It's only possible to change the state for a WebPage which 4253 // already qualifies for running modal child web pages, otherwise 4254 // there's no other possibility than not allowing it. 4255 m_canRunModal = m_uiClient.canRunModal() && canRunModal; 4256 m_process->send(Messages::WebPage::SetCanRunModal(m_canRunModal), m_pageID); 4257} 4258 4259bool WebPageProxy::canRunModal() 4260{ 4261 return isValid() ? m_canRunModal : false; 4262} 4263 4264void WebPageProxy::beginPrinting(WebFrameProxy* frame, const PrintInfo& printInfo) 4265{ 4266 if (m_isInPrintingMode) 4267 return; 4268 4269 m_isInPrintingMode = true; 4270 m_process->send(Messages::WebPage::BeginPrinting(frame->frameID(), printInfo), m_pageID, m_isPerformingDOMPrintOperation ? CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply : 0); 4271} 4272 4273void WebPageProxy::endPrinting() 4274{ 4275 if (!m_isInPrintingMode) 4276 return; 4277 4278 m_isInPrintingMode = false; 4279 m_process->send(Messages::WebPage::EndPrinting(), m_pageID, m_isPerformingDOMPrintOperation ? CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply : 0); 4280} 4281 4282void WebPageProxy::computePagesForPrinting(WebFrameProxy* frame, const PrintInfo& printInfo, PassRefPtr<ComputedPagesCallback> prpCallback) 4283{ 4284 RefPtr<ComputedPagesCallback> callback = prpCallback; 4285 if (!isValid()) { 4286 callback->invalidate(); 4287 return; 4288 } 4289 4290 uint64_t callbackID = callback->callbackID(); 4291 m_computedPagesCallbacks.set(callbackID, callback.get()); 4292 m_isInPrintingMode = true; 4293 m_process->send(Messages::WebPage::ComputePagesForPrinting(frame->frameID(), printInfo, callbackID), m_pageID, m_isPerformingDOMPrintOperation ? CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply : 0); 4294} 4295 4296#if PLATFORM(MAC) 4297void WebPageProxy::drawRectToImage(WebFrameProxy* frame, const PrintInfo& printInfo, const IntRect& rect, const WebCore::IntSize& imageSize, PassRefPtr<ImageCallback> prpCallback) 4298{ 4299 RefPtr<ImageCallback> callback = prpCallback; 4300 if (!isValid()) { 4301 callback->invalidate(); 4302 return; 4303 } 4304 4305 uint64_t callbackID = callback->callbackID(); 4306 m_imageCallbacks.set(callbackID, callback.get()); 4307 m_process->send(Messages::WebPage::DrawRectToImage(frame->frameID(), printInfo, rect, imageSize, callbackID), m_pageID, m_isPerformingDOMPrintOperation ? CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply : 0); 4308} 4309 4310void WebPageProxy::drawPagesToPDF(WebFrameProxy* frame, const PrintInfo& printInfo, uint32_t first, uint32_t count, PassRefPtr<DataCallback> prpCallback) 4311{ 4312 RefPtr<DataCallback> callback = prpCallback; 4313 if (!isValid()) { 4314 callback->invalidate(); 4315 return; 4316 } 4317 4318 uint64_t callbackID = callback->callbackID(); 4319 m_dataCallbacks.set(callbackID, callback.get()); 4320 m_process->send(Messages::WebPage::DrawPagesToPDF(frame->frameID(), printInfo, first, count, callbackID), m_pageID, m_isPerformingDOMPrintOperation ? CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply : 0); 4321} 4322#elif PLATFORM(GTK) 4323void WebPageProxy::drawPagesForPrinting(WebFrameProxy* frame, const PrintInfo& printInfo, PassRefPtr<PrintFinishedCallback> didPrintCallback) 4324{ 4325 RefPtr<PrintFinishedCallback> callback = didPrintCallback; 4326 if (!isValid()) { 4327 callback->invalidate(); 4328 return; 4329 } 4330 4331 uint64_t callbackID = callback->callbackID(); 4332 m_printFinishedCallbacks.set(callbackID, callback.get()); 4333 m_isInPrintingMode = true; 4334 m_process->send(Messages::WebPage::DrawPagesForPrinting(frame->frameID(), printInfo, callbackID), m_pageID, m_isPerformingDOMPrintOperation ? CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply : 0); 4335} 4336#endif 4337 4338void WebPageProxy::flashBackingStoreUpdates(const Vector<IntRect>& updateRects) 4339{ 4340 m_pageClient->flashBackingStoreUpdates(updateRects); 4341} 4342 4343void WebPageProxy::updateBackingStoreDiscardableState() 4344{ 4345 ASSERT(isValid()); 4346 4347 bool isDiscardable; 4348 4349 if (!m_process->responsivenessTimer()->isResponsive()) 4350 isDiscardable = false; 4351 else 4352 isDiscardable = !m_pageClient->isViewWindowActive() || !isViewVisible(); 4353 4354 m_drawingArea->setBackingStoreIsDiscardable(isDiscardable); 4355} 4356 4357Color WebPageProxy::viewUpdatesFlashColor() 4358{ 4359 return Color(0, 200, 255); 4360} 4361 4362Color WebPageProxy::backingStoreUpdatesFlashColor() 4363{ 4364 return Color(200, 0, 255); 4365} 4366 4367void WebPageProxy::saveDataToFileInDownloadsFolder(const String& suggestedFilename, const String& mimeType, const String& originatingURLString, WebData* data) 4368{ 4369 m_uiClient.saveDataToFileInDownloadsFolder(this, suggestedFilename, mimeType, originatingURLString, data); 4370} 4371 4372void WebPageProxy::savePDFToFileInDownloadsFolder(const String& suggestedFilename, const String& originatingURLString, const CoreIPC::DataReference& data) 4373{ 4374 if (!suggestedFilename.endsWith(".pdf", false)) 4375 return; 4376 4377 RefPtr<WebData> webData = WebData::create(data.data(), data.size()); 4378 4379 saveDataToFileInDownloadsFolder(suggestedFilename, "application/pdf", originatingURLString, webData.get()); 4380} 4381 4382void WebPageProxy::linkClicked(const String& url, const WebMouseEvent& event) 4383{ 4384 m_process->send(Messages::WebPage::LinkClicked(url, event), m_pageID, 0); 4385} 4386 4387void WebPageProxy::setMinimumLayoutSize(const IntSize& minimumLayoutSize) 4388{ 4389 if (m_minimumLayoutSize == minimumLayoutSize) 4390 return; 4391 4392 m_minimumLayoutSize = minimumLayoutSize; 4393 4394 if (!isValid()) 4395 return; 4396 4397 m_process->send(Messages::WebPage::SetMinimumLayoutSize(minimumLayoutSize), m_pageID, 0); 4398 m_drawingArea->minimumLayoutSizeDidChange(); 4399 4400#if PLATFORM(MAC) 4401 if (m_minimumLayoutSize.width() <= 0) 4402 intrinsicContentSizeDidChange(IntSize(-1, -1)); 4403#endif 4404} 4405 4406void WebPageProxy::setAutoSizingShouldExpandToViewHeight(bool shouldExpand) 4407{ 4408 if (m_autoSizingShouldExpandToViewHeight == shouldExpand) 4409 return; 4410 4411 m_autoSizingShouldExpandToViewHeight = shouldExpand; 4412 4413 if (!isValid()) 4414 return; 4415 4416 m_process->send(Messages::WebPage::SetAutoSizingShouldExpandToViewHeight(shouldExpand), m_pageID, 0); 4417} 4418 4419#if PLATFORM(MAC) 4420 4421void WebPageProxy::substitutionsPanelIsShowing(bool& isShowing) 4422{ 4423 isShowing = TextChecker::substitutionsPanelIsShowing(); 4424} 4425 4426void WebPageProxy::showCorrectionPanel(int32_t panelType, const FloatRect& boundingBoxOfReplacedString, const String& replacedString, const String& replacementString, const Vector<String>& alternativeReplacementStrings) 4427{ 4428 m_pageClient->showCorrectionPanel((AlternativeTextType)panelType, boundingBoxOfReplacedString, replacedString, replacementString, alternativeReplacementStrings); 4429} 4430 4431void WebPageProxy::dismissCorrectionPanel(int32_t reason) 4432{ 4433 m_pageClient->dismissCorrectionPanel((ReasonForDismissingAlternativeText)reason); 4434} 4435 4436void WebPageProxy::dismissCorrectionPanelSoon(int32_t reason, String& result) 4437{ 4438 result = m_pageClient->dismissCorrectionPanelSoon((ReasonForDismissingAlternativeText)reason); 4439} 4440 4441void WebPageProxy::recordAutocorrectionResponse(int32_t responseType, const String& replacedString, const String& replacementString) 4442{ 4443 m_pageClient->recordAutocorrectionResponse((AutocorrectionResponseType)responseType, replacedString, replacementString); 4444} 4445 4446void WebPageProxy::handleAlternativeTextUIResult(const String& result) 4447{ 4448 if (!isClosed()) 4449 m_process->send(Messages::WebPage::HandleAlternativeTextUIResult(result), m_pageID, 0); 4450} 4451 4452#if USE(DICTATION_ALTERNATIVES) 4453void WebPageProxy::showDictationAlternativeUI(const WebCore::FloatRect& boundingBoxOfDictatedText, uint64_t dictationContext) 4454{ 4455 m_pageClient->showDictationAlternativeUI(boundingBoxOfDictatedText, dictationContext); 4456} 4457 4458void WebPageProxy::removeDictationAlternatives(uint64_t dictationContext) 4459{ 4460 m_pageClient->removeDictationAlternatives(dictationContext); 4461} 4462 4463void WebPageProxy::dictationAlternatives(uint64_t dictationContext, Vector<String>& result) 4464{ 4465 result = m_pageClient->dictationAlternatives(dictationContext); 4466} 4467#endif 4468 4469#endif // PLATFORM(MAC) 4470 4471#if USE(SOUP) 4472void WebPageProxy::didReceiveURIRequest(String uriString, uint64_t requestID) 4473{ 4474 m_process->context()->supplement<WebSoupRequestManagerProxy>()->didReceiveURIRequest(uriString, this, requestID); 4475} 4476#endif 4477 4478#if PLATFORM(QT) || PLATFORM(GTK) 4479void WebPageProxy::setComposition(const String& text, Vector<CompositionUnderline> underlines, uint64_t selectionStart, uint64_t selectionEnd, uint64_t replacementRangeStart, uint64_t replacementRangeEnd) 4480{ 4481 // FIXME: We need to find out how to proper handle the crashes case. 4482 if (!isValid()) 4483 return; 4484 4485 process()->send(Messages::WebPage::SetComposition(text, underlines, selectionStart, selectionEnd, replacementRangeStart, replacementRangeEnd), m_pageID); 4486} 4487 4488void WebPageProxy::confirmComposition(const String& compositionString, int64_t selectionStart, int64_t selectionLength) 4489{ 4490 if (!isValid()) 4491 return; 4492 4493 process()->send(Messages::WebPage::ConfirmComposition(compositionString, selectionStart, selectionLength), m_pageID); 4494} 4495 4496void WebPageProxy::cancelComposition() 4497{ 4498 if (!isValid()) 4499 return; 4500 4501 process()->send(Messages::WebPage::CancelComposition(), m_pageID); 4502} 4503#endif // PLATFORM(QT) || PLATFORM(GTK) 4504 4505void WebPageProxy::setMainFrameInViewSourceMode(bool mainFrameInViewSourceMode) 4506{ 4507 if (m_mainFrameInViewSourceMode == mainFrameInViewSourceMode) 4508 return; 4509 4510 m_mainFrameInViewSourceMode = mainFrameInViewSourceMode; 4511 4512 if (isValid()) 4513 m_process->send(Messages::WebPage::SetMainFrameInViewSourceMode(mainFrameInViewSourceMode), m_pageID); 4514} 4515 4516void WebPageProxy::didSaveToPageCache() 4517{ 4518 m_process->didSaveToPageCache(); 4519} 4520 4521void WebPageProxy::setScrollPinningBehavior(ScrollPinningBehavior pinning) 4522{ 4523 if (m_scrollPinningBehavior == pinning) 4524 return; 4525 4526 m_scrollPinningBehavior = pinning; 4527 4528 if (isValid()) 4529 m_process->send(Messages::WebPage::SetScrollPinningBehavior(pinning), m_pageID); 4530} 4531 4532} // namespace WebKit 4533