2 * Copyright (C) 2010, 2011, 2015 Apple Inc. All rights reserved.
3 * Copyright (C) 2012 Intel Corporation. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
28 #include "WebPageProxy.h"
31 #include "APIContextMenuClient.h"
32 #include "APIFindClient.h"
33 #include "APIFormClient.h"
34 #include "APIFrameInfo.h"
35 #include "APIGeometry.h"
36 #include "APIHistoryClient.h"
37 #include "APIHitTestResult.h"
38 #include "APILegacyContextHistoryClient.h"
39 #include "APILoaderClient.h"
40 #include "APINavigation.h"
41 #include "APINavigationAction.h"
42 #include "APINavigationClient.h"
43 #include "APINavigationResponse.h"
44 #include "APIPageConfiguration.h"
45 #include "APIPolicyClient.h"
46 #include "APISecurityOrigin.h"
47 #include "APIUIClient.h"
48 #include "APIURLRequest.h"
49 #include "AuthenticationChallengeProxy.h"
50 #include "AuthenticationDecisionListener.h"
51 #include "DataReference.h"
52 #include "DownloadProxy.h"
53 #include "DrawingAreaProxy.h"
54 #include "DrawingAreaProxyMessages.h"
55 #include "EventDispatcherMessages.h"
57 #include "NativeWebKeyboardEvent.h"
58 #include "NativeWebMouseEvent.h"
59 #include "NativeWebWheelEvent.h"
60 #include "NavigationActionData.h"
61 #include "NotificationPermissionRequest.h"
62 #include "NotificationPermissionRequestManager.h"
63 #include "PageClient.h"
64 #include "PluginInformation.h"
65 #include "PluginProcessManager.h"
66 #include "PrintInfo.h"
67 #include "TextChecker.h"
68 #include "TextCheckerState.h"
69 #include "UserMediaPermissionRequestProxy.h"
70 #include "WKContextPrivate.h"
71 #include "WebBackForwardList.h"
72 #include "WebBackForwardListItem.h"
73 #include "WebCertificateInfo.h"
74 #include "WebContextMenuItem.h"
75 #include "WebContextMenuProxy.h"
76 #include "WebCoreArgumentCoders.h"
77 #include "WebEditCommandProxy.h"
79 #include "WebEventConversion.h"
80 #include "WebFormSubmissionListenerProxy.h"
81 #include "WebFramePolicyListenerProxy.h"
82 #include "WebFullScreenManagerProxy.h"
83 #include "WebFullScreenManagerProxyMessages.h"
85 #include "WebInspectorProxy.h"
86 #include "WebInspectorProxyMessages.h"
87 #include "WebNavigationState.h"
88 #include "WebNotificationManagerProxy.h"
89 #include "WebOpenPanelParameters.h"
90 #include "WebOpenPanelResultListenerProxy.h"
91 #include "WebPageCreationParameters.h"
92 #include "WebPageGroup.h"
93 #include "WebPageGroupData.h"
94 #include "WebPageMessages.h"
95 #include "WebPageProxyMessages.h"
96 #include "WebPopupItem.h"
97 #include "WebPopupMenuProxy.h"
98 #include "WebPreferences.h"
99 #include "WebProcessMessages.h"
100 #include "WebProcessPool.h"
101 #include "WebProcessProxy.h"
102 #include "WebProtectionSpace.h"
103 #include "WebUserContentControllerProxy.h"
104 #include "WebsiteDataStore.h"
105 #include <WebCore/BitmapImage.h>
106 #include <WebCore/DiagnosticLoggingClient.h>
107 #include <WebCore/DragController.h>
108 #include <WebCore/DragData.h>
109 #include <WebCore/FloatRect.h>
110 #include <WebCore/FocusDirection.h>
111 #include <WebCore/MIMETypeRegistry.h>
112 #include <WebCore/RenderEmbeddedObject.h>
113 #include <WebCore/SerializedCryptoKeyWrap.h>
114 #include <WebCore/TextCheckerClient.h>
115 #include <WebCore/TextIndicator.h>
116 #include <WebCore/URL.h>
117 #include <WebCore/WindowFeatures.h>
119 #include <wtf/NeverDestroyed.h>
120 #include <wtf/text/StringView.h>
122 #if ENABLE(ASYNC_SCROLLING)
123 #include "RemoteScrollingCoordinatorProxy.h"
126 #if USE(COORDINATED_GRAPHICS_MULTIPROCESS)
127 #include "CoordinatedLayerTreeHostProxyMessages.h"
130 #if ENABLE(VIBRATION)
131 #include "WebVibrationProxy.h"
135 #include <wtf/RefCountedLeakCounter.h>
138 #if ENABLE(NETWORK_PROCESS)
139 #include "NetworkProcessMessages.h"
143 #include "RemoteLayerTreeDrawingAreaProxy.h"
144 #include "RemoteLayerTreeScrollingPerformanceData.h"
145 #include "ViewSnapshotStore.h"
146 #include <WebCore/MachSendRight.h>
147 #include <WebCore/RunLoopObserver.h>
148 #include <WebCore/TextIndicatorWindow.h>
152 #include "WebVideoFullscreenManagerProxy.h"
153 #include "WebVideoFullscreenManagerProxyMessages.h"
157 #include <WebCore/CairoUtilities.h>
160 #if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
161 #include <WebCore/MediaPlaybackTarget.h>
162 #include <WebCore/WebMediaSessionManager.h>
165 #if ENABLE(MEDIA_SESSION)
166 #include "WebMediaSessionFocusManager.h"
167 #include "WebMediaSessionMetadata.h"
168 #include <WebCore/MediaSessionMetadata.h>
171 // This controls what strategy we use for mouse wheel coalescing.
172 #define MERGE_WHEEL_EVENTS 1
174 #define MESSAGE_CHECK(assertion) MESSAGE_CHECK_BASE(assertion, m_process->connection())
175 #define MESSAGE_CHECK_URL(url) MESSAGE_CHECK_BASE(m_process->checkURLReceivedFromWebProcess(url), m_process->connection())
177 using namespace WebCore;
179 // Represents the number of wheel events we can hold in the queue before we start pushing them preemptively.
180 static const unsigned wheelEventQueueSizeThreshold = 10;
184 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, webPageProxyCounter, ("WebPageProxy"));
186 class ExceededDatabaseQuotaRecords {
187 WTF_MAKE_NONCOPYABLE(ExceededDatabaseQuotaRecords); WTF_MAKE_FAST_ALLOCATED;
188 friend class NeverDestroyed<ExceededDatabaseQuotaRecords>;
192 String originIdentifier;
195 uint64_t currentQuota;
196 uint64_t currentOriginUsage;
197 uint64_t currentDatabaseUsage;
198 uint64_t expectedUsage;
199 RefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply> reply;
202 static ExceededDatabaseQuotaRecords& singleton();
204 std::unique_ptr<Record> createRecord(uint64_t frameID, String originIdentifier,
205 String databaseName, String displayName, uint64_t currentQuota,
206 uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage,
207 PassRefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply>);
209 void add(std::unique_ptr<Record>);
210 bool areBeingProcessed() const { return !!m_currentRecord; }
214 ExceededDatabaseQuotaRecords() { }
215 ~ExceededDatabaseQuotaRecords() { }
217 Deque<std::unique_ptr<Record>> m_records;
218 std::unique_ptr<Record> m_currentRecord;
221 ExceededDatabaseQuotaRecords& ExceededDatabaseQuotaRecords::singleton()
223 static NeverDestroyed<ExceededDatabaseQuotaRecords> records;
227 std::unique_ptr<ExceededDatabaseQuotaRecords::Record> ExceededDatabaseQuotaRecords::createRecord(
228 uint64_t frameID, String originIdentifier, String databaseName, String displayName,
229 uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage,
230 uint64_t expectedUsage, PassRefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply> reply)
232 auto record = std::make_unique<Record>();
233 record->frameID = frameID;
234 record->originIdentifier = originIdentifier;
235 record->databaseName = databaseName;
236 record->displayName = displayName;
237 record->currentQuota = currentQuota;
238 record->currentOriginUsage = currentOriginUsage;
239 record->currentDatabaseUsage = currentDatabaseUsage;
240 record->expectedUsage = expectedUsage;
241 record->reply = reply;
242 return WTF::move(record);
245 void ExceededDatabaseQuotaRecords::add(std::unique_ptr<ExceededDatabaseQuotaRecords::Record> record)
247 m_records.append(WTF::move(record));
250 ExceededDatabaseQuotaRecords::Record* ExceededDatabaseQuotaRecords::next()
252 m_currentRecord = nullptr;
253 if (!m_records.isEmpty())
254 m_currentRecord = m_records.takeFirst();
255 return m_currentRecord.get();
259 static const char* webKeyboardEventTypeString(WebEvent::Type type)
262 case WebEvent::KeyDown:
265 case WebEvent::KeyUp:
268 case WebEvent::RawKeyDown:
275 ASSERT_NOT_REACHED();
279 #endif // !LOG_DISABLED
281 class PageClientProtector {
282 WTF_MAKE_NONCOPYABLE(PageClientProtector);
284 PageClientProtector(PageClient& pageClient)
285 : m_pageClient(pageClient)
287 m_pageClient.refView();
290 ~PageClientProtector()
292 m_pageClient.derefView();
296 PageClient& m_pageClient;
299 Ref<WebPageProxy> WebPageProxy::create(PageClient& pageClient, WebProcessProxy& process, uint64_t pageID, Ref<API::PageConfiguration>&& configuration)
301 return adoptRef(*new WebPageProxy(pageClient, process, pageID, WTF::move(configuration)));
304 WebPageProxy::WebPageProxy(PageClient& pageClient, WebProcessProxy& process, uint64_t pageID, Ref<API::PageConfiguration>&& configuration)
305 : m_pageClient(pageClient)
306 , m_configuration(WTF::move(configuration))
307 , m_loaderClient(std::make_unique<API::LoaderClient>())
308 , m_policyClient(std::make_unique<API::PolicyClient>())
309 , m_formClient(std::make_unique<API::FormClient>())
310 , m_uiClient(std::make_unique<API::UIClient>())
311 , m_findClient(std::make_unique<API::FindClient>())
312 , m_diagnosticLoggingClient(std::make_unique<API::DiagnosticLoggingClient>())
313 #if ENABLE(CONTEXT_MENUS)
314 , m_contextMenuClient(std::make_unique<API::ContextMenuClient>())
316 , m_navigationState(std::make_unique<WebNavigationState>())
318 , m_pageGroup(*m_configuration->pageGroup())
319 , m_preferences(*m_configuration->preferences())
320 , m_userContentController(m_configuration->userContentController())
321 , m_visitedLinkStore(*m_configuration->visitedLinkStore())
322 , m_websiteDataStore(m_configuration->websiteDataStore()->websiteDataStore())
323 , m_mainFrame(nullptr)
324 , m_userAgent(standardUserAgent())
325 , m_treatsSHA1CertificatesAsInsecure(m_configuration->treatsSHA1SignedCertificatesAsInsecure())
327 , m_hasReceivedLayerTreeTransactionAfterDidCommitLoad(true)
328 , m_firstLayerTreeTransactionIdAfterDidCommitLoad(0)
329 , m_deviceOrientation(0)
330 , m_dynamicViewportSizeUpdateWaitingForTarget(false)
331 , m_dynamicViewportSizeUpdateWaitingForLayerTreeCommit(false)
332 , m_dynamicViewportSizeUpdateLayerTreeTransactionID(0)
333 , m_layerTreeTransactionIdAtLastTouchStart(0)
334 , m_hasNetworkRequestsOnSuspended(false)
336 , m_geolocationPermissionRequestManager(*this)
337 , m_notificationPermissionRequestManager(*this)
338 , m_userMediaPermissionRequestManager(*this)
339 , m_viewState(ViewState::NoFlags)
340 , m_viewWasEverInWindow(false)
342 , m_alwaysRunsAtForegroundPriority(m_configuration->alwaysRunsAtForegroundPriority())
344 , m_backForwardList(WebBackForwardList::create(*this))
345 , m_maintainsInactiveSelection(false)
346 , m_isEditable(false)
347 #if PLATFORM(MAC) && !USE(ASYNC_NSTEXTINPUTCLIENT)
348 , m_temporarilyClosedComposition(false)
350 , m_textZoomFactor(1)
351 , m_pageZoomFactor(1)
352 , m_pageScaleFactor(1)
353 , m_pluginZoomFactor(1)
354 , m_pluginScaleFactor(1)
355 , m_intrinsicDeviceScaleFactor(1)
356 , m_customDeviceScaleFactor(0)
357 , m_topContentInset(0)
358 , m_layerHostingMode(LayerHostingMode::InProcess)
359 , m_drawsBackground(true)
360 , m_drawsTransparentBackground(false)
361 , m_useFixedLayout(false)
362 , m_suppressScrollbarAnimations(false)
363 , m_paginationMode(Pagination::Unpaginated)
364 , m_paginationBehavesLikeColumns(false)
366 , m_gapBetweenPages(0)
369 , m_canRunModal(false)
370 , m_isInPrintingMode(false)
371 , m_isPerformingDOMPrintOperation(false)
372 , m_inDecidePolicyForResponseSync(false)
373 , m_decidePolicyForResponseRequest(0)
374 , m_syncMimeTypePolicyActionIsValid(false)
375 , m_syncMimeTypePolicyAction(PolicyUse)
376 , m_syncMimeTypePolicyDownloadID(0)
377 , m_inDecidePolicyForNavigationAction(false)
378 , m_syncNavigationActionPolicyActionIsValid(false)
379 , m_syncNavigationActionPolicyAction(PolicyUse)
380 , m_syncNavigationActionPolicyDownloadID(0)
381 , m_processingMouseMoveEvent(false)
382 #if ENABLE(TOUCH_EVENTS)
383 , m_isTrackingTouchEvents(false)
386 , m_sessionID(m_configuration->sessionID())
387 , m_isPageSuspended(false)
388 , m_addsVisitedLinks(true)
389 #if ENABLE(REMOTE_INSPECTOR)
390 , m_allowsRemoteInspection(true)
393 , m_isSmartInsertDeleteEnabled(TextChecker::isSmartInsertDeleteEnabled())
396 , m_backgroundColor(Color::white)
398 , m_spellDocumentTag(0)
399 , m_hasSpellDocumentTag(false)
400 , m_pendingLearnOrIgnoreWordMessageCount(0)
401 , m_mainFrameHasCustomContentProvider(false)
402 #if ENABLE(DRAG_SUPPORT)
403 , m_currentDragOperation(DragOperationNone)
404 , m_currentDragIsOverFileInput(false)
405 , m_currentDragNumberOfFilesToBeAccepted(0)
407 , m_pageLoadState(*this)
408 , m_delegatesScrolling(false)
409 , m_mainFrameHasHorizontalScrollbar(false)
410 , m_mainFrameHasVerticalScrollbar(false)
411 , m_canShortCircuitHorizontalWheelEvents(true)
412 , m_mainFrameIsPinnedToLeftSide(true)
413 , m_mainFrameIsPinnedToRightSide(true)
414 , m_mainFrameIsPinnedToTopSide(true)
415 , m_mainFrameIsPinnedToBottomSide(true)
416 , m_shouldUseImplicitRubberBandControl(false)
417 , m_rubberBandsAtLeft(true)
418 , m_rubberBandsAtRight(true)
419 , m_rubberBandsAtTop(true)
420 , m_rubberBandsAtBottom(true)
421 , m_enableVerticalRubberBanding(true)
422 , m_enableHorizontalRubberBanding(true)
423 , m_backgroundExtendsBeyondPage(false)
424 , m_shouldRecordNavigationSnapshots(false)
425 , m_isShowingNavigationGestureSnapshot(false)
427 , m_renderTreeSize(0)
428 , m_sessionRestorationRenderTreeSize(0)
429 , m_wantsSessionRestorationRenderTreeSizeThresholdEvent(false)
430 , m_hitRenderTreeSizeThreshold(false)
431 , m_suppressVisibilityUpdates(false)
432 , m_autoSizingShouldExpandToViewHeight(false)
435 , m_mayStartMediaWhenInWindow(true)
436 , m_waitingForDidUpdateViewState(false)
438 , m_scrollPerformanceDataCollectionEnabled(false)
440 , m_scrollPinningBehavior(DoNotPin)
442 , m_configurationPreferenceValues(m_configuration->preferenceValues())
443 , m_potentiallyChangedViewStateFlags(ViewState::NoFlags)
444 , m_viewStateChangeWantsSynchronousReply(false)
446 m_webProcessLifetimeTracker.addObserver(m_visitedLinkStore);
447 m_webProcessLifetimeTracker.addObserver(m_websiteDataStore);
449 if (m_process->state() == WebProcessProxy::State::Running) {
450 if (m_userContentController)
451 m_process->addWebUserContentControllerProxy(*m_userContentController);
452 m_process->addVisitedLinkStore(m_visitedLinkStore);
456 updateActivityToken();
457 updateProccessSuppressionState();
459 #if HAVE(OUT_OF_PROCESS_LAYER_HOSTING)
460 m_layerHostingMode = m_viewState & ViewState::IsInWindow ? m_pageClient.viewLayerHostingMode() : LayerHostingMode::OutOfProcess;
463 platformInitialize();
466 webPageProxyCounter.increment();
469 WebProcessPool::statistics().wkPageCount++;
471 m_preferences->addPage(*this);
472 m_pageGroup->addPage(this);
474 m_inspector = WebInspectorProxy::create(this);
475 #if ENABLE(FULLSCREEN_API)
476 m_fullScreenManager = WebFullScreenManagerProxy::create(*this, m_pageClient.fullScreenManagerProxyClient());
479 m_videoFullscreenManager = WebVideoFullscreenManagerProxy::create(*this);
481 #if ENABLE(VIBRATION)
482 m_vibration = WebVibrationProxy::create(this);
485 m_process->addMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID, *this);
487 #if ENABLE(NETWORK_PROCESS)
488 if (m_sessionID.isEphemeral())
489 m_process->processPool().sendToNetworkingProcess(Messages::NetworkProcess::EnsurePrivateBrowsingSession(m_sessionID));
493 const CFIndex viewStateChangeRunLoopOrder = (CFIndex)RunLoopObserver::WellKnownRunLoopOrders::CoreAnimationCommit - 1;
494 m_viewStateChangeDispatcher = RunLoopObserver::create(viewStateChangeRunLoopOrder, [this] {
495 this->dispatchViewStateChange();
500 WebPageProxy::~WebPageProxy()
502 ASSERT(m_process->webPage(m_pageID) != this);
504 for (WebPageProxy* page : m_process->pages())
505 ASSERT(page != this);
511 WebProcessPool::statistics().wkPageCount--;
513 if (m_hasSpellDocumentTag)
514 TextChecker::closeSpellDocumentWithTag(m_spellDocumentTag);
516 m_preferences->removePage(*this);
517 m_pageGroup->removePage(this);
520 webPageProxyCounter.decrement();
524 const API::PageConfiguration& WebPageProxy::configuration() const
526 return m_configuration.get();
529 PlatformProcessIdentifier WebPageProxy::processIdentifier() const
534 return m_process->processIdentifier();
537 bool WebPageProxy::isValid() const
539 // A page that has been explicitly closed is never valid.
546 void WebPageProxy::setPreferences(WebPreferences& preferences)
548 if (&preferences == m_preferences.ptr())
551 m_preferences->removePage(*this);
552 m_preferences = preferences;
553 m_preferences->addPage(*this);
555 preferencesDidChange();
558 void WebPageProxy::setHistoryClient(std::unique_ptr<API::HistoryClient> historyClient)
560 m_historyClient = WTF::move(historyClient);
563 void WebPageProxy::setNavigationClient(std::unique_ptr<API::NavigationClient> navigationClient)
565 m_navigationClient = WTF::move(navigationClient);
568 void WebPageProxy::setLoaderClient(std::unique_ptr<API::LoaderClient> loaderClient)
571 m_loaderClient = std::make_unique<API::LoaderClient>();
575 m_loaderClient = WTF::move(loaderClient);
578 void WebPageProxy::setPolicyClient(std::unique_ptr<API::PolicyClient> policyClient)
581 m_policyClient = std::make_unique<API::PolicyClient>();
585 m_policyClient = WTF::move(policyClient);
588 void WebPageProxy::setFormClient(std::unique_ptr<API::FormClient> formClient)
591 m_formClient = std::make_unique<API::FormClient>();
595 m_formClient = WTF::move(formClient);
598 void WebPageProxy::setUIClient(std::unique_ptr<API::UIClient> uiClient)
601 m_uiClient = std::make_unique<API::UIClient>();
605 m_uiClient = WTF::move(uiClient);
610 m_process->send(Messages::WebPage::SetCanRunBeforeUnloadConfirmPanel(m_uiClient->canRunBeforeUnloadConfirmPanel()), m_pageID);
611 setCanRunModal(m_uiClient->canRunModal());
614 void WebPageProxy::setFindClient(std::unique_ptr<API::FindClient> findClient)
617 m_findClient = std::make_unique<API::FindClient>();
621 m_findClient = WTF::move(findClient);
624 void WebPageProxy::initializeFindMatchesClient(const WKPageFindMatchesClientBase* client)
626 m_findMatchesClient.initialize(client);
629 void WebPageProxy::setDiagnosticLoggingClient(std::unique_ptr<API::DiagnosticLoggingClient> diagnosticLoggingClient)
631 if (!diagnosticLoggingClient) {
632 m_diagnosticLoggingClient = std::make_unique<API::DiagnosticLoggingClient>();
636 m_diagnosticLoggingClient = WTF::move(diagnosticLoggingClient);
639 #if ENABLE(CONTEXT_MENUS)
640 void WebPageProxy::setContextMenuClient(std::unique_ptr<API::ContextMenuClient> contextMenuClient)
642 if (!contextMenuClient) {
643 m_contextMenuClient = std::make_unique<API::ContextMenuClient>();
647 m_contextMenuClient = WTF::move(contextMenuClient);
651 void WebPageProxy::setInjectedBundleClient(const WKPageInjectedBundleClientBase* client)
654 m_injectedBundleClient = nullptr;
658 m_injectedBundleClient = std::make_unique<WebPageInjectedBundleClient>();
659 m_injectedBundleClient->initialize(client);
662 void WebPageProxy::handleMessage(IPC::Connection& connection, const String& messageName, const WebKit::UserData& messageBody)
664 auto* webProcessProxy = WebProcessProxy::fromConnection(&connection);
665 if (!webProcessProxy || !m_injectedBundleClient)
667 m_injectedBundleClient->didReceiveMessageFromInjectedBundle(this, messageName, webProcessProxy->transformHandlesToObjects(messageBody.object()).get());
670 void WebPageProxy::handleSynchronousMessage(IPC::Connection& connection, const String& messageName, const UserData& messageBody, UserData& returnUserData)
672 if (!WebProcessProxy::fromConnection(&connection) || !m_injectedBundleClient)
675 RefPtr<API::Object> returnData;
676 m_injectedBundleClient->didReceiveSynchronousMessageFromInjectedBundle(this, messageName, WebProcessProxy::fromConnection(&connection)->transformHandlesToObjects(messageBody.object()).get(), returnData);
677 returnUserData = UserData(WebProcessProxy::fromConnection(&connection)->transformObjectsToHandles(returnData.get()));
681 void WebPageProxy::reattachToWebProcess()
685 ASSERT(m_process->state() == WebProcessProxy::State::Terminated);
688 m_process->removeWebPage(m_pageID);
689 m_process->removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID);
691 if (m_process->processPool().processModel() == ProcessModelSharedSecondaryProcess)
692 m_process = m_process->processPool().ensureSharedWebProcess();
694 m_process = m_process->processPool().createNewWebProcessRespectingProcessCountLimit();
696 ASSERT(m_process->state() != ChildProcessProxy::State::Terminated);
697 if (m_process->state() == ChildProcessProxy::State::Running)
698 processDidFinishLaunching();
699 m_process->addExistingWebPage(this, m_pageID);
700 m_process->addMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID, *this);
703 updateActivityToken();
705 m_inspector = WebInspectorProxy::create(this);
706 #if ENABLE(FULLSCREEN_API)
707 m_fullScreenManager = WebFullScreenManagerProxy::create(*this, m_pageClient.fullScreenManagerProxyClient());
710 m_videoFullscreenManager = WebVideoFullscreenManagerProxy::create(*this);
715 m_pageClient.didRelaunchProcess();
716 m_drawingArea->waitForBackingStoreUpdateOnNextPaint();
719 RefPtr<API::Navigation> WebPageProxy::reattachToWebProcessForReload()
725 reattachToWebProcess();
727 if (!m_backForwardList->currentItem())
730 auto navigation = m_navigationState->createReloadNavigation();
732 // We allow stale content when reloading a WebProcess that's been killed or crashed.
733 m_process->send(Messages::WebPage::GoToBackForwardItem(navigation->navigationID(), m_backForwardList->currentItem()->itemID()), m_pageID);
734 m_process->responsivenessTimer()->start();
736 return WTF::move(navigation);
739 RefPtr<API::Navigation> WebPageProxy::reattachToWebProcessWithItem(WebBackForwardListItem* item)
744 if (item && item != m_backForwardList->currentItem())
745 m_backForwardList->goToItem(item);
748 reattachToWebProcess();
753 auto navigation = m_navigationState->createBackForwardNavigation();
755 m_process->send(Messages::WebPage::GoToBackForwardItem(navigation->navigationID(), item->itemID()), m_pageID);
756 m_process->responsivenessTimer()->start();
758 return WTF::move(navigation);
761 void WebPageProxy::setSessionID(SessionID sessionID)
766 m_sessionID = sessionID;
767 m_process->send(Messages::WebPage::SetSessionID(sessionID), m_pageID);
769 #if ENABLE(NETWORK_PROCESS)
770 if (sessionID.isEphemeral())
771 m_process->processPool().sendToNetworkingProcess(Messages::NetworkProcess::EnsurePrivateBrowsingSession(sessionID));
775 void WebPageProxy::initializeWebPage()
779 BackForwardListItemVector items = m_backForwardList->entries();
780 for (size_t i = 0; i < items.size(); ++i)
781 m_process->registerNewWebBackForwardListItem(items[i].get());
783 m_drawingArea = m_pageClient.createDrawingAreaProxy();
784 ASSERT(m_drawingArea);
786 #if ENABLE(ASYNC_SCROLLING)
787 if (m_drawingArea->type() == DrawingAreaTypeRemoteLayerTree) {
788 m_scrollingCoordinatorProxy = std::make_unique<RemoteScrollingCoordinatorProxy>(*this);
790 // On iOS, main frame scrolls are sent in terms of visible rect updates.
791 m_scrollingCoordinatorProxy->setPropagatesMainFrameScrolls(false);
796 #if ENABLE(INSPECTOR_SERVER)
797 if (m_preferences->developerExtrasEnabled())
798 inspector()->enableRemoteInspection();
801 process().send(Messages::WebProcess::CreateWebPage(m_pageID, creationParameters()), 0);
804 send(Messages::WebPage::SetSmartInsertDeleteEnabled(m_isSmartInsertDeleteEnabled));
808 void WebPageProxy::close()
815 if (m_activePopupMenu)
816 m_activePopupMenu->cancelTracking();
818 #if ENABLE(CONTEXT_MENUS)
819 if (m_activeContextMenu)
820 m_activeContextMenu->cancelTracking();
823 m_backForwardList->pageClosed();
824 m_pageClient.pageClosed();
826 m_process->disconnectFramesFromPage(this);
828 resetState(ResetStateReason::PageInvalidated);
830 m_loaderClient = std::make_unique<API::LoaderClient>();
831 m_policyClient = std::make_unique<API::PolicyClient>();
832 m_formClient = std::make_unique<API::FormClient>();
833 m_uiClient = std::make_unique<API::UIClient>();
835 m_uiPopupMenuClient.initialize(nullptr);
837 m_findClient = std::make_unique<API::FindClient>();
838 m_findMatchesClient.initialize(nullptr);
839 m_diagnosticLoggingClient = std::make_unique<API::DiagnosticLoggingClient>();
840 #if ENABLE(CONTEXT_MENUS)
841 m_contextMenuClient = std::make_unique<API::ContextMenuClient>();
844 m_webProcessLifetimeTracker.pageWasInvalidated();
846 m_process->send(Messages::WebPage::Close(), m_pageID);
847 m_process->removeWebPage(m_pageID);
848 m_process->removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID);
849 m_process->processPool().supplement<WebNotificationManagerProxy>()->clearNotifications(this);
852 bool WebPageProxy::tryClose()
857 m_process->send(Messages::WebPage::TryClose(), m_pageID);
858 m_process->responsivenessTimer()->start();
862 bool WebPageProxy::maybeInitializeSandboxExtensionHandle(const URL& url, SandboxExtension::Handle& sandboxExtensionHandle)
864 if (!url.isLocalFile())
867 if (m_process->hasAssumedReadAccessToURL(url))
870 // Inspector resources are in a directory with assumed access.
871 ASSERT_WITH_SECURITY_IMPLICATION(!WebInspectorProxy::isInspectorPage(*this));
873 SandboxExtension::createHandle("/", SandboxExtension::ReadOnly, sandboxExtensionHandle);
877 RefPtr<API::Navigation> WebPageProxy::loadRequest(const ResourceRequest& request, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy, API::Object* userData)
882 auto navigation = m_navigationState->createLoadRequestNavigation(request);
884 auto transaction = m_pageLoadState.transaction();
886 m_pageLoadState.setPendingAPIRequestURL(transaction, request.url());
889 reattachToWebProcess();
891 SandboxExtension::Handle sandboxExtensionHandle;
892 bool createdExtension = maybeInitializeSandboxExtensionHandle(request.url(), sandboxExtensionHandle);
893 if (createdExtension)
894 m_process->willAcquireUniversalFileReadSandboxExtension();
895 m_process->send(Messages::WebPage::LoadRequest(navigation->navigationID(), request, sandboxExtensionHandle, (uint64_t)shouldOpenExternalURLsPolicy, UserData(process().transformObjectsToHandles(userData).get())), m_pageID);
896 m_process->responsivenessTimer()->start();
898 return WTF::move(navigation);
901 RefPtr<API::Navigation> WebPageProxy::loadFile(const String& fileURLString, const String& resourceDirectoryURLString, API::Object* userData)
907 reattachToWebProcess();
909 URL fileURL = URL(URL(), fileURLString);
910 if (!fileURL.isLocalFile())
913 URL resourceDirectoryURL;
914 if (resourceDirectoryURLString.isNull())
915 resourceDirectoryURL = URL(ParsedURLString, ASCIILiteral("file:///"));
917 resourceDirectoryURL = URL(URL(), resourceDirectoryURLString);
918 if (!resourceDirectoryURL.isLocalFile())
922 auto navigation = m_navigationState->createLoadRequestNavigation(ResourceRequest(fileURL));
924 auto transaction = m_pageLoadState.transaction();
926 m_pageLoadState.setPendingAPIRequestURL(transaction, fileURLString);
928 String resourceDirectoryPath = resourceDirectoryURL.fileSystemPath();
930 SandboxExtension::Handle sandboxExtensionHandle;
931 SandboxExtension::createHandle(resourceDirectoryPath, SandboxExtension::ReadOnly, sandboxExtensionHandle);
932 m_process->assumeReadAccessToBaseURL(resourceDirectoryURL);
933 m_process->send(Messages::WebPage::LoadRequest(navigation->navigationID(), fileURL, sandboxExtensionHandle, (uint64_t)ShouldOpenExternalURLsPolicy::ShouldNotAllow, UserData(process().transformObjectsToHandles(userData).get())), m_pageID);
934 m_process->responsivenessTimer()->start();
936 return WTF::move(navigation);
939 RefPtr<API::Navigation> WebPageProxy::loadData(API::Data* data, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData)
944 auto navigation = m_navigationState->createLoadDataNavigation();
946 auto transaction = m_pageLoadState.transaction();
948 m_pageLoadState.setPendingAPIRequestURL(transaction, !baseURL.isEmpty() ? baseURL : ASCIILiteral("about:blank"));
951 reattachToWebProcess();
953 m_process->assumeReadAccessToBaseURL(baseURL);
954 m_process->send(Messages::WebPage::LoadData(navigation->navigationID(), data->dataReference(), MIMEType, encoding, baseURL, UserData(process().transformObjectsToHandles(userData).get())), m_pageID);
955 m_process->responsivenessTimer()->start();
957 return WTF::move(navigation);
960 // FIXME: Get rid of loadHTMLString and just use loadData instead.
961 RefPtr<API::Navigation> WebPageProxy::loadHTMLString(const String& htmlString, const String& baseURL, API::Object* userData)
966 auto navigation = m_navigationState->createLoadDataNavigation();
968 auto transaction = m_pageLoadState.transaction();
970 m_pageLoadState.setPendingAPIRequestURL(transaction, !baseURL.isEmpty() ? baseURL : ASCIILiteral("about:blank"));
973 reattachToWebProcess();
975 m_process->assumeReadAccessToBaseURL(baseURL);
976 m_process->send(Messages::WebPage::LoadHTMLString(navigation->navigationID(), htmlString, baseURL, UserData(process().transformObjectsToHandles(userData).get())), m_pageID);
977 m_process->responsivenessTimer()->start();
979 return WTF::move(navigation);
982 void WebPageProxy::loadAlternateHTMLString(const String& htmlString, const String& baseURL, const String& unreachableURL, API::Object* userData)
988 reattachToWebProcess();
990 auto transaction = m_pageLoadState.transaction();
992 m_pageLoadState.setUnreachableURL(transaction, unreachableURL);
995 m_mainFrame->setUnreachableURL(unreachableURL);
997 m_process->assumeReadAccessToBaseURL(baseURL);
998 m_process->assumeReadAccessToBaseURL(unreachableURL);
999 m_process->send(Messages::WebPage::LoadAlternateHTMLString(htmlString, baseURL, unreachableURL, m_failingProvisionalLoadURL, UserData(process().transformObjectsToHandles(userData).get())), m_pageID);
1000 m_process->responsivenessTimer()->start();
1003 void WebPageProxy::loadPlainTextString(const String& string, API::Object* userData)
1009 reattachToWebProcess();
1011 m_process->send(Messages::WebPage::LoadPlainTextString(string, UserData(process().transformObjectsToHandles(userData).get())), m_pageID);
1012 m_process->responsivenessTimer()->start();
1015 void WebPageProxy::loadWebArchiveData(API::Data* webArchiveData, API::Object* userData)
1021 reattachToWebProcess();
1023 m_process->send(Messages::WebPage::LoadWebArchiveData(webArchiveData->dataReference(), UserData(process().transformObjectsToHandles(userData).get())), m_pageID);
1024 m_process->responsivenessTimer()->start();
1027 void WebPageProxy::navigateToPDFLinkWithSimulatedClick(const String& url, IntPoint documentPoint, IntPoint screenPoint)
1032 if (WebCore::protocolIsJavaScript(url))
1036 reattachToWebProcess();
1038 m_process->send(Messages::WebPage::NavigateToPDFLinkWithSimulatedClick(url, documentPoint, screenPoint), m_pageID);
1039 m_process->responsivenessTimer()->start();
1042 void WebPageProxy::stopLoading()
1047 m_process->send(Messages::WebPage::StopLoading(), m_pageID);
1048 m_process->responsivenessTimer()->start();
1051 RefPtr<API::Navigation> WebPageProxy::reload(bool reloadFromOrigin)
1053 SandboxExtension::Handle sandboxExtensionHandle;
1055 if (m_backForwardList->currentItem()) {
1056 String url = m_backForwardList->currentItem()->url();
1057 auto transaction = m_pageLoadState.transaction();
1058 m_pageLoadState.setPendingAPIRequestURL(transaction, url);
1060 // We may not have an extension yet if back/forward list was reinstated after a WebProcess crash or a browser relaunch
1061 bool createdExtension = maybeInitializeSandboxExtensionHandle(URL(URL(), url), sandboxExtensionHandle);
1062 if (createdExtension)
1063 m_process->willAcquireUniversalFileReadSandboxExtension();
1067 return reattachToWebProcessForReload();
1069 auto navigation = m_navigationState->createReloadNavigation();
1071 m_process->send(Messages::WebPage::Reload(navigation->navigationID(), reloadFromOrigin, sandboxExtensionHandle), m_pageID);
1072 m_process->responsivenessTimer()->start();
1074 return WTF::move(navigation);
1077 void WebPageProxy::recordNavigationSnapshot()
1079 if (WebBackForwardListItem* item = m_backForwardList->currentItem())
1080 recordNavigationSnapshot(*item);
1083 void WebPageProxy::recordNavigationSnapshot(WebBackForwardListItem& item)
1085 if (!m_shouldRecordNavigationSnapshots || m_suppressNavigationSnapshotting)
1089 ViewSnapshotStore::singleton().recordSnapshot(*this, item);
1095 RefPtr<API::Navigation> WebPageProxy::goForward()
1097 WebBackForwardListItem* forwardItem = m_backForwardList->forwardItem();
1101 auto transaction = m_pageLoadState.transaction();
1103 m_pageLoadState.setPendingAPIRequestURL(transaction, forwardItem->url());
1106 return reattachToWebProcessWithItem(forwardItem);
1108 RefPtr<API::Navigation> navigation;
1109 if (!m_backForwardList->currentItem()->itemIsInSameDocument(*forwardItem))
1110 navigation = m_navigationState->createBackForwardNavigation();
1112 m_process->send(Messages::WebPage::GoForward(navigation ? navigation->navigationID() : 0, forwardItem->itemID()), m_pageID);
1113 m_process->responsivenessTimer()->start();
1118 RefPtr<API::Navigation> WebPageProxy::goBack()
1120 WebBackForwardListItem* backItem = m_backForwardList->backItem();
1124 auto transaction = m_pageLoadState.transaction();
1126 m_pageLoadState.setPendingAPIRequestURL(transaction, backItem->url());
1129 return reattachToWebProcessWithItem(backItem);
1131 RefPtr<API::Navigation> navigation;
1132 if (!m_backForwardList->currentItem()->itemIsInSameDocument(*backItem))
1133 navigation = m_navigationState->createBackForwardNavigation();
1135 m_process->send(Messages::WebPage::GoBack(navigation ? navigation->navigationID() : 0, backItem->itemID()), m_pageID);
1136 m_process->responsivenessTimer()->start();
1141 RefPtr<API::Navigation> WebPageProxy::goToBackForwardItem(WebBackForwardListItem* item)
1144 return reattachToWebProcessWithItem(item);
1146 auto transaction = m_pageLoadState.transaction();
1148 m_pageLoadState.setPendingAPIRequestURL(transaction, item->url());
1150 RefPtr<API::Navigation> navigation;
1151 if (!m_backForwardList->currentItem()->itemIsInSameDocument(*item))
1152 navigation = m_navigationState->createBackForwardNavigation();
1154 m_process->send(Messages::WebPage::GoToBackForwardItem(navigation ? navigation->navigationID() : 0, item->itemID()), m_pageID);
1155 m_process->responsivenessTimer()->start();
1160 void WebPageProxy::tryRestoreScrollPosition()
1165 m_process->send(Messages::WebPage::TryRestoreScrollPosition(), m_pageID);
1168 void WebPageProxy::didChangeBackForwardList(WebBackForwardListItem* added, Vector<RefPtr<WebBackForwardListItem>> removed)
1170 PageClientProtector protector(m_pageClient);
1172 m_loaderClient->didChangeBackForwardList(*this, added, WTF::move(removed));
1174 auto transaction = m_pageLoadState.transaction();
1176 m_pageLoadState.setCanGoBack(transaction, m_backForwardList->backItem());
1177 m_pageLoadState.setCanGoForward(transaction, m_backForwardList->forwardItem());
1180 void WebPageProxy::willGoToBackForwardListItem(uint64_t itemID, const UserData& userData)
1182 PageClientProtector protector(m_pageClient);
1184 if (WebBackForwardListItem* item = m_process->webBackForwardItem(itemID))
1185 m_loaderClient->willGoToBackForwardListItem(*this, item, m_process->transformHandlesToObjects(userData.object()).get());
1188 bool WebPageProxy::shouldKeepCurrentBackForwardListItemInList(WebBackForwardListItem* item)
1190 PageClientProtector protector(m_pageClient);
1192 return m_loaderClient->shouldKeepCurrentBackForwardListItemInList(*this, item);
1195 bool WebPageProxy::canShowMIMEType(const String& mimeType)
1197 if (MIMETypeRegistry::canShowMIMEType(mimeType))
1200 #if ENABLE(NETSCAPE_PLUGIN_API)
1201 String newMimeType = mimeType;
1202 PluginModuleInfo plugin = m_process->processPool().pluginInfoStore().findPlugin(newMimeType, URL());
1203 if (!plugin.path.isNull() && m_preferences->pluginsEnabled())
1205 #endif // ENABLE(NETSCAPE_PLUGIN_API)
1208 // On Mac, we can show PDFs.
1209 if (MIMETypeRegistry::isPDFOrPostScriptMIMEType(mimeType) && !WebProcessPool::omitPDFSupport())
1211 #endif // PLATFORM(COCOA)
1216 #if ENABLE(REMOTE_INSPECTOR)
1217 void WebPageProxy::setAllowsRemoteInspection(bool allow)
1219 if (m_allowsRemoteInspection == allow)
1222 m_allowsRemoteInspection = allow;
1225 m_process->send(Messages::WebPage::SetAllowsRemoteInspection(allow), m_pageID);
1229 void WebPageProxy::setDrawsBackground(bool drawsBackground)
1231 if (m_drawsBackground == drawsBackground)
1234 m_drawsBackground = drawsBackground;
1237 m_process->send(Messages::WebPage::SetDrawsBackground(drawsBackground), m_pageID);
1240 void WebPageProxy::setDrawsTransparentBackground(bool drawsTransparentBackground)
1242 if (m_drawsTransparentBackground == drawsTransparentBackground)
1245 m_drawsTransparentBackground = drawsTransparentBackground;
1248 m_process->send(Messages::WebPage::SetDrawsTransparentBackground(drawsTransparentBackground), m_pageID);
1251 void WebPageProxy::setTopContentInset(float contentInset)
1253 if (m_topContentInset == contentInset)
1256 m_topContentInset = contentInset;
1259 m_process->send(Messages::WebPage::SetTopContentInset(contentInset), m_pageID);
1262 void WebPageProxy::setUnderlayColor(const Color& color)
1264 if (m_underlayColor == color)
1267 m_underlayColor = color;
1270 m_process->send(Messages::WebPage::SetUnderlayColor(color), m_pageID);
1273 void WebPageProxy::viewWillStartLiveResize()
1277 #if ENABLE(INPUT_TYPE_COLOR_POPOVER)
1281 m_process->send(Messages::WebPage::ViewWillStartLiveResize(), m_pageID);
1284 void WebPageProxy::viewWillEndLiveResize()
1288 m_process->send(Messages::WebPage::ViewWillEndLiveResize(), m_pageID);
1291 void WebPageProxy::setViewNeedsDisplay(const IntRect& rect)
1293 m_pageClient.setViewNeedsDisplay(rect);
1296 void WebPageProxy::displayView()
1298 m_pageClient.displayView();
1301 bool WebPageProxy::canScrollView()
1303 return m_pageClient.canScrollView();
1306 void WebPageProxy::scrollView(const IntRect& scrollRect, const IntSize& scrollOffset)
1308 m_pageClient.scrollView(scrollRect, scrollOffset);
1311 void WebPageProxy::requestScroll(const FloatPoint& scrollPosition, const IntPoint& scrollOrigin, bool isProgrammaticScroll)
1313 m_pageClient.requestScroll(scrollPosition, scrollOrigin, isProgrammaticScroll);
1316 void WebPageProxy::setSuppressVisibilityUpdates(bool flag)
1318 if (m_suppressVisibilityUpdates == flag)
1320 m_suppressVisibilityUpdates = flag;
1322 if (!m_suppressVisibilityUpdates) {
1324 m_viewStateChangeDispatcher->schedule();
1326 dispatchViewStateChange();
1331 void WebPageProxy::updateViewState(ViewState::Flags flagsToUpdate)
1333 m_viewState &= ~flagsToUpdate;
1334 if (flagsToUpdate & ViewState::IsFocused && m_pageClient.isViewFocused())
1335 m_viewState |= ViewState::IsFocused;
1336 if (flagsToUpdate & ViewState::WindowIsActive && m_pageClient.isViewWindowActive())
1337 m_viewState |= ViewState::WindowIsActive;
1338 if (flagsToUpdate & ViewState::IsVisible && m_pageClient.isViewVisible())
1339 m_viewState |= ViewState::IsVisible;
1340 if (flagsToUpdate & ViewState::IsVisibleOrOccluded && m_pageClient.isViewVisibleOrOccluded())
1341 m_viewState |= ViewState::IsVisibleOrOccluded;
1342 if (flagsToUpdate & ViewState::IsInWindow && m_pageClient.isViewInWindow())
1343 m_viewState |= ViewState::IsInWindow;
1344 if (flagsToUpdate & ViewState::IsVisuallyIdle && m_pageClient.isVisuallyIdle())
1345 m_viewState |= ViewState::IsVisuallyIdle;
1348 void WebPageProxy::viewStateDidChange(ViewState::Flags mayHaveChanged, bool wantsSynchronousReply, ViewStateChangeDispatchMode dispatchMode)
1350 m_potentiallyChangedViewStateFlags |= mayHaveChanged;
1351 m_viewStateChangeWantsSynchronousReply = m_viewStateChangeWantsSynchronousReply || wantsSynchronousReply;
1353 if (m_suppressVisibilityUpdates && dispatchMode != ViewStateChangeDispatchMode::Immediate)
1357 bool isNewlyInWindow = !isInWindow() && (mayHaveChanged & ViewState::IsInWindow) && m_pageClient.isViewInWindow();
1358 if (dispatchMode == ViewStateChangeDispatchMode::Immediate || isNewlyInWindow) {
1359 dispatchViewStateChange();
1362 m_viewStateChangeDispatcher->schedule();
1364 UNUSED_PARAM(dispatchMode);
1365 dispatchViewStateChange();
1369 void WebPageProxy::viewDidLeaveWindow()
1371 #if ENABLE(INPUT_TYPE_COLOR_POPOVER)
1372 // When leaving the current page, close the popover color well.
1377 // When leaving the current page, close the video fullscreen.
1378 if (m_videoFullscreenManager)
1379 m_videoFullscreenManager->requestHideAndExitFullscreen();
1383 void WebPageProxy::viewDidEnterWindow()
1385 LayerHostingMode layerHostingMode = m_pageClient.viewLayerHostingMode();
1386 if (m_layerHostingMode != layerHostingMode) {
1387 m_layerHostingMode = layerHostingMode;
1388 m_process->send(Messages::WebPage::SetLayerHostingMode(static_cast<unsigned>(layerHostingMode)), m_pageID);
1392 void WebPageProxy::dispatchViewStateChange()
1395 m_viewStateChangeDispatcher->invalidate();
1401 // If the visibility state may have changed, then so may the visually idle & occluded agnostic state.
1402 if (m_potentiallyChangedViewStateFlags & ViewState::IsVisible)
1403 m_potentiallyChangedViewStateFlags |= ViewState::IsVisibleOrOccluded | ViewState::IsVisuallyIdle;
1405 // Record the prior view state, update the flags that may have changed,
1406 // and check which flags have actually changed.
1407 ViewState::Flags previousViewState = m_viewState;
1408 updateViewState(m_potentiallyChangedViewStateFlags);
1409 ViewState::Flags changed = m_viewState ^ previousViewState;
1411 bool isNowInWindow = (changed & ViewState::IsInWindow) && isInWindow();
1412 // We always want to wait for the Web process to reply if we've been in-window before and are coming back in-window.
1413 if (m_viewWasEverInWindow && isNowInWindow && m_drawingArea->hasVisibleContent())
1414 m_viewStateChangeWantsSynchronousReply = true;
1416 // Don't wait synchronously if the view state is not visible. (This matters in particular on iOS, where a hidden page may be suspended.)
1417 if (!(m_viewState & ViewState::IsVisible))
1418 m_viewStateChangeWantsSynchronousReply = false;
1420 if (changed || m_viewStateChangeWantsSynchronousReply || !m_nextViewStateChangeCallbacks.isEmpty())
1421 m_process->send(Messages::WebPage::SetViewState(m_viewState, m_viewStateChangeWantsSynchronousReply, m_nextViewStateChangeCallbacks), m_pageID);
1423 m_nextViewStateChangeCallbacks.clear();
1425 // This must happen after the SetViewState message is sent, to ensure the page visibility event can fire.
1426 updateActivityToken();
1428 // If we've started the responsiveness timer as part of telling the web process to update the backing store
1429 // state, it might not send back a reply (since it won't paint anything if the web page is hidden) so we
1430 // stop the unresponsiveness timer here.
1431 if ((changed & ViewState::IsVisible) && !isViewVisible())
1432 m_process->responsivenessTimer()->stop();
1434 if (changed & ViewState::IsInWindow) {
1436 viewDidEnterWindow();
1438 viewDidLeaveWindow();
1441 updateBackingStoreDiscardableState();
1443 if (m_viewStateChangeWantsSynchronousReply)
1444 waitForDidUpdateViewState();
1446 m_potentiallyChangedViewStateFlags = ViewState::NoFlags;
1447 m_viewStateChangeWantsSynchronousReply = false;
1448 m_viewWasEverInWindow |= isNowInWindow;
1451 void WebPageProxy::updateActivityToken()
1453 if (m_viewState & ViewState::IsVisuallyIdle)
1454 m_pageIsUserObservableCount = nullptr;
1455 else if (!m_pageIsUserObservableCount)
1456 m_pageIsUserObservableCount = m_process->processPool().userObservablePageCount();
1459 if (!isViewVisible() && !m_alwaysRunsAtForegroundPriority)
1460 m_activityToken = nullptr;
1461 else if (!m_activityToken)
1462 m_activityToken = m_process->throttler().foregroundActivityToken();
1466 void WebPageProxy::updateProccessSuppressionState()
1468 if (m_preferences->pageVisibilityBasedProcessSuppressionEnabled())
1469 m_preventProcessSuppressionCount = nullptr;
1470 else if (!m_preventProcessSuppressionCount)
1471 m_preventProcessSuppressionCount = m_process->processPool().processSuppressionDisabledForPageCount();
1474 void WebPageProxy::layerHostingModeDidChange()
1479 LayerHostingMode layerHostingMode = m_pageClient.viewLayerHostingMode();
1480 if (m_layerHostingMode == layerHostingMode)
1483 m_layerHostingMode = layerHostingMode;
1484 m_process->send(Messages::WebPage::SetLayerHostingMode(static_cast<unsigned>(layerHostingMode)), m_pageID);
1487 void WebPageProxy::waitForDidUpdateViewState()
1492 if (m_process->state() != WebProcessProxy::State::Running)
1495 // If we have previously timed out with no response from the WebProcess, don't block the UIProcess again until it starts responding.
1496 if (m_waitingForDidUpdateViewState)
1500 // Hail Mary check. Should not be possible (dispatchViewStateChange should force async if not visible,
1501 // and if visible we should be holding an assertion) - but we should never block on a suspended process.
1502 if (!m_activityToken) {
1503 ASSERT_NOT_REACHED();
1508 m_waitingForDidUpdateViewState = true;
1510 m_drawingArea->waitForDidUpdateViewState();
1513 IntSize WebPageProxy::viewSize() const
1515 return m_pageClient.viewSize();
1518 void WebPageProxy::setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent& keyboardEvent, std::function<void (CallbackBase::Error)> callbackFunction)
1521 callbackFunction(CallbackBase::Error::OwnerWasInvalidated);
1525 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
1526 m_process->send(Messages::WebPage::SetInitialFocus(forward, isKeyboardEventValid, keyboardEvent, callbackID), m_pageID);
1529 void WebPageProxy::clearSelection()
1533 m_process->send(Messages::WebPage::ClearSelection(), m_pageID);
1536 void WebPageProxy::restoreSelectionInFocusedEditableElement()
1540 m_process->send(Messages::WebPage::RestoreSelectionInFocusedEditableElement(), m_pageID);
1543 void WebPageProxy::validateCommand(const String& commandName, std::function<void (const String&, bool, int32_t, CallbackBase::Error)> callbackFunction)
1546 callbackFunction(String(), false, 0, CallbackBase::Error::Unknown);
1550 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
1551 m_process->send(Messages::WebPage::ValidateCommand(commandName, callbackID), m_pageID);
1554 void WebPageProxy::setMaintainsInactiveSelection(bool newValue)
1556 m_maintainsInactiveSelection = newValue;
1559 void WebPageProxy::executeEditCommand(const String& commandName, const String& argument)
1561 static NeverDestroyed<String> ignoreSpellingCommandName(ASCIILiteral("ignoreSpelling"));
1566 if (commandName == ignoreSpellingCommandName)
1567 ++m_pendingLearnOrIgnoreWordMessageCount;
1569 m_process->send(Messages::WebPage::ExecuteEditCommand(commandName, argument), m_pageID);
1572 void WebPageProxy::setEditable(bool editable)
1574 if (editable == m_isEditable)
1579 m_isEditable = editable;
1580 m_process->send(Messages::WebPage::SetEditable(editable), m_pageID);
1584 void WebPageProxy::didCommitLayerTree(const RemoteLayerTreeTransaction&)
1589 #if ENABLE(DRAG_SUPPORT)
1590 void WebPageProxy::dragEntered(DragData& dragData, const String& dragStorageName)
1592 SandboxExtension::Handle sandboxExtensionHandle;
1593 SandboxExtension::HandleArray sandboxExtensionHandleEmptyArray;
1594 performDragControllerAction(DragControllerActionEntered, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionHandleEmptyArray);
1597 void WebPageProxy::dragUpdated(DragData& dragData, const String& dragStorageName)
1599 SandboxExtension::Handle sandboxExtensionHandle;
1600 SandboxExtension::HandleArray sandboxExtensionHandleEmptyArray;
1601 performDragControllerAction(DragControllerActionUpdated, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionHandleEmptyArray);
1604 void WebPageProxy::dragExited(DragData& dragData, const String& dragStorageName)
1606 SandboxExtension::Handle sandboxExtensionHandle;
1607 SandboxExtension::HandleArray sandboxExtensionHandleEmptyArray;
1608 performDragControllerAction(DragControllerActionExited, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionHandleEmptyArray);
1611 void WebPageProxy::performDragOperation(DragData& dragData, const String& dragStorageName, const SandboxExtension::Handle& sandboxExtensionHandle, const SandboxExtension::HandleArray& sandboxExtensionsForUpload)
1613 performDragControllerAction(DragControllerActionPerformDragOperation, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionsForUpload);
1616 void WebPageProxy::performDragControllerAction(DragControllerAction action, DragData& dragData, const String& dragStorageName, const SandboxExtension::Handle& sandboxExtensionHandle, const SandboxExtension::HandleArray& sandboxExtensionsForUpload)
1621 UNUSED_PARAM(dragStorageName);
1622 UNUSED_PARAM(sandboxExtensionHandle);
1623 UNUSED_PARAM(sandboxExtensionsForUpload);
1625 String url = dragData.asURL();
1627 m_process->assumeReadAccessToBaseURL(url);
1628 m_process->send(Messages::WebPage::PerformDragControllerAction(action, dragData), m_pageID);
1630 m_process->send(Messages::WebPage::PerformDragControllerAction(action, dragData.clientPosition(), dragData.globalPosition(), dragData.draggingSourceOperationMask(), dragStorageName, dragData.flags(), sandboxExtensionHandle, sandboxExtensionsForUpload), m_pageID);
1634 void WebPageProxy::didPerformDragControllerAction(uint64_t dragOperation, bool mouseIsOverFileInput, unsigned numberOfItemsToBeAccepted)
1636 MESSAGE_CHECK(dragOperation <= DragOperationDelete);
1638 m_currentDragOperation = static_cast<DragOperation>(dragOperation);
1639 m_currentDragIsOverFileInput = mouseIsOverFileInput;
1640 m_currentDragNumberOfFilesToBeAccepted = numberOfItemsToBeAccepted;
1644 void WebPageProxy::startDrag(const DragData& dragData, const ShareableBitmap::Handle& dragImageHandle)
1646 RefPtr<ShareableBitmap> dragImage = 0;
1647 if (!dragImageHandle.isNull()) {
1648 dragImage = ShareableBitmap::create(dragImageHandle);
1653 m_pageClient.startDrag(dragData, dragImage.release());
1657 void WebPageProxy::dragEnded(const IntPoint& clientPosition, const IntPoint& globalPosition, uint64_t operation)
1661 m_process->send(Messages::WebPage::DragEnded(clientPosition, globalPosition, operation), m_pageID);
1663 #endif // ENABLE(DRAG_SUPPORT)
1665 void WebPageProxy::handleMouseEvent(const NativeWebMouseEvent& event)
1670 // NOTE: This does not start the responsiveness timer because mouse move should not indicate interaction.
1671 if (event.type() != WebEvent::MouseMove)
1672 m_process->responsivenessTimer()->start();
1674 if (m_processingMouseMoveEvent) {
1675 m_nextMouseMoveEvent = std::make_unique<NativeWebMouseEvent>(event);
1679 m_processingMouseMoveEvent = true;
1682 // <https://bugs.webkit.org/show_bug.cgi?id=57904> We need to keep track of the mouse down event in the case where we
1683 // display a popup menu for select elements. When the user changes the selected item,
1684 // we fake a mouse up event by using this stored down event. This event gets cleared
1685 // when the mouse up message is received from WebProcess.
1686 if (event.type() == WebEvent::MouseDown)
1687 m_currentlyProcessedMouseDownEvent = std::make_unique<NativeWebMouseEvent>(event);
1689 m_process->send(Messages::WebPage::MouseEvent(event), m_pageID);
1692 #if MERGE_WHEEL_EVENTS
1693 static bool canCoalesce(const WebWheelEvent& a, const WebWheelEvent& b)
1695 if (a.position() != b.position())
1697 if (a.globalPosition() != b.globalPosition())
1699 if (a.modifiers() != b.modifiers())
1701 if (a.granularity() != b.granularity())
1704 if (a.phase() != b.phase())
1706 if (a.momentumPhase() != b.momentumPhase())
1708 if (a.hasPreciseScrollingDeltas() != b.hasPreciseScrollingDeltas())
1715 static WebWheelEvent coalesce(const WebWheelEvent& a, const WebWheelEvent& b)
1717 ASSERT(canCoalesce(a, b));
1719 FloatSize mergedDelta = a.delta() + b.delta();
1720 FloatSize mergedWheelTicks = a.wheelTicks() + b.wheelTicks();
1723 FloatSize mergedUnacceleratedScrollingDelta = a.unacceleratedScrollingDelta() + b.unacceleratedScrollingDelta();
1725 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());
1727 return WebWheelEvent(WebEvent::Wheel, b.position(), b.globalPosition(), mergedDelta, mergedWheelTicks, b.granularity(), b.modifiers(), b.timestamp());
1730 #endif // MERGE_WHEEL_EVENTS
1732 static WebWheelEvent coalescedWheelEvent(Deque<NativeWebWheelEvent>& queue, Vector<NativeWebWheelEvent>& coalescedEvents)
1734 ASSERT(!queue.isEmpty());
1735 ASSERT(coalescedEvents.isEmpty());
1737 #if MERGE_WHEEL_EVENTS
1738 NativeWebWheelEvent firstEvent = queue.takeFirst();
1739 coalescedEvents.append(firstEvent);
1741 WebWheelEvent event = firstEvent;
1742 while (!queue.isEmpty() && canCoalesce(event, queue.first())) {
1743 NativeWebWheelEvent firstEvent = queue.takeFirst();
1744 coalescedEvents.append(firstEvent);
1745 event = coalesce(event, firstEvent);
1750 while (!queue.isEmpty())
1751 coalescedEvents.append(queue.takeFirst());
1752 return coalescedEvents.last();
1756 void WebPageProxy::handleWheelEvent(const NativeWebWheelEvent& event)
1758 #if ENABLE(ASYNC_SCROLLING)
1759 if (m_scrollingCoordinatorProxy && m_scrollingCoordinatorProxy->handleWheelEvent(platform(event)))
1766 if (!m_currentlyProcessedWheelEvents.isEmpty()) {
1767 m_wheelEventQueue.append(event);
1768 if (m_wheelEventQueue.size() < wheelEventQueueSizeThreshold)
1770 // The queue has too many wheel events, so push a new event.
1773 if (!m_wheelEventQueue.isEmpty()) {
1774 processNextQueuedWheelEvent();
1778 auto coalescedWheelEvent = std::make_unique<Vector<NativeWebWheelEvent>>();
1779 coalescedWheelEvent->append(event);
1780 m_currentlyProcessedWheelEvents.append(WTF::move(coalescedWheelEvent));
1781 sendWheelEvent(event);
1784 void WebPageProxy::processNextQueuedWheelEvent()
1786 auto nextCoalescedEvent = std::make_unique<Vector<NativeWebWheelEvent>>();
1787 WebWheelEvent nextWheelEvent = coalescedWheelEvent(m_wheelEventQueue, *nextCoalescedEvent.get());
1788 m_currentlyProcessedWheelEvents.append(WTF::move(nextCoalescedEvent));
1789 sendWheelEvent(nextWheelEvent);
1792 void WebPageProxy::sendWheelEvent(const WebWheelEvent& event)
1794 m_process->responsivenessTimer()->start();
1797 Messages::EventDispatcher::WheelEvent(
1800 shouldUseImplicitRubberBandControl() ? !m_backForwardList->backItem() : rubberBandsAtLeft(),
1801 shouldUseImplicitRubberBandControl() ? !m_backForwardList->forwardItem() : rubberBandsAtRight(),
1803 rubberBandsAtBottom()
1807 void WebPageProxy::handleKeyboardEvent(const NativeWebKeyboardEvent& event)
1812 LOG(KeyHandling, "WebPageProxy::handleKeyboardEvent: %s", webKeyboardEventTypeString(event.type()));
1814 m_keyEventQueue.append(event);
1816 m_process->responsivenessTimer()->start();
1817 if (m_keyEventQueue.size() == 1) // Otherwise, sent from DidReceiveEvent message handler.
1818 m_process->send(Messages::WebPage::KeyEvent(event), m_pageID);
1821 WebPreferencesStore WebPageProxy::preferencesStore() const
1823 if (m_configurationPreferenceValues.isEmpty())
1824 return m_preferences->store();
1826 WebPreferencesStore store = m_preferences->store();
1827 for (const auto& preference : m_configurationPreferenceValues)
1828 store.m_values.set(preference.key, preference.value);
1833 #if ENABLE(NETSCAPE_PLUGIN_API)
1834 void 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)
1836 PageClientProtector protector(m_pageClient);
1838 MESSAGE_CHECK_URL(urlString);
1840 newMimeType = mimeType.lower();
1841 pluginLoadPolicy = PluginModuleLoadNormally;
1843 PluginData::AllowedPluginTypes allowedPluginTypes = allowOnlyApplicationPlugins ? PluginData::OnlyApplicationPlugins : PluginData::AllPlugins;
1844 PluginModuleInfo plugin = m_process->processPool().pluginInfoStore().findPlugin(newMimeType, URL(URL(), urlString), allowedPluginTypes);
1846 pluginProcessToken = 0;
1850 pluginLoadPolicy = PluginInfoStore::defaultLoadPolicyForPlugin(plugin);
1853 RefPtr<API::Dictionary> pluginInformation = createPluginInformationDictionary(plugin, frameURLString, String(), pageURLString, String(), String());
1854 if (m_navigationClient)
1855 pluginLoadPolicy = m_navigationClient->decidePolicyForPluginLoad(*this, static_cast<PluginModuleLoadPolicy>(pluginLoadPolicy), pluginInformation.get(), unavailabilityDescription);
1857 pluginLoadPolicy = m_loaderClient->pluginLoadPolicy(*this, static_cast<PluginModuleLoadPolicy>(pluginLoadPolicy), pluginInformation.get(), unavailabilityDescription);
1859 UNUSED_PARAM(frameURLString);
1860 UNUSED_PARAM(pageURLString);
1861 UNUSED_PARAM(unavailabilityDescription);
1864 PluginProcessSandboxPolicy pluginProcessSandboxPolicy = PluginProcessSandboxPolicyNormal;
1865 switch (pluginLoadPolicy) {
1866 case PluginModuleLoadNormally:
1867 pluginProcessSandboxPolicy = PluginProcessSandboxPolicyNormal;
1869 case PluginModuleLoadUnsandboxed:
1870 pluginProcessSandboxPolicy = PluginProcessSandboxPolicyUnsandboxed;
1873 case PluginModuleBlockedForSecurity:
1874 case PluginModuleBlockedForCompatibility:
1875 pluginProcessToken = 0;
1879 pluginProcessToken = PluginProcessManager::singleton().pluginProcessToken(plugin, static_cast<PluginProcessType>(processType), pluginProcessSandboxPolicy);
1882 #endif // ENABLE(NETSCAPE_PLUGIN_API)
1884 #if ENABLE(TOUCH_EVENTS)
1886 bool WebPageProxy::shouldStartTrackingTouchEvents(const WebTouchEvent& touchStartEvent) const
1888 #if ENABLE(ASYNC_SCROLLING)
1889 for (auto& touchPoint : touchStartEvent.touchPoints()) {
1890 if (m_scrollingCoordinatorProxy->isPointInNonFastScrollableRegion(touchPoint.location()))
1896 UNUSED_PARAM(touchStartEvent);
1897 #endif // ENABLE(ASYNC_SCROLLING)
1903 #if ENABLE(IOS_TOUCH_EVENTS)
1904 void WebPageProxy::handleTouchEventSynchronously(const NativeWebTouchEvent& event)
1909 if (event.type() == WebEvent::TouchStart) {
1910 m_isTrackingTouchEvents = shouldStartTrackingTouchEvents(event);
1911 m_layerTreeTransactionIdAtLastTouchStart = downcast<RemoteLayerTreeDrawingAreaProxy>(*drawingArea()).lastCommittedLayerTreeTransactionID();
1914 if (!m_isTrackingTouchEvents)
1917 m_process->responsivenessTimer()->start();
1918 bool handled = false;
1919 m_process->sendSync(Messages::WebPage::TouchEventSync(event), Messages::WebPage::TouchEventSync::Reply(handled), m_pageID);
1920 didReceiveEvent(event.type(), handled);
1921 m_pageClient.doneWithTouchEvent(event, handled);
1922 m_process->responsivenessTimer()->stop();
1924 if (event.allTouchPointsAreReleased())
1925 m_isTrackingTouchEvents = false;
1928 void WebPageProxy::handleTouchEventAsynchronously(const NativeWebTouchEvent& event)
1933 if (!m_isTrackingTouchEvents)
1936 m_process->send(Messages::EventDispatcher::TouchEvent(m_pageID, event), 0);
1938 if (event.allTouchPointsAreReleased())
1939 m_isTrackingTouchEvents = false;
1942 #elif ENABLE(TOUCH_EVENTS)
1943 void WebPageProxy::handleTouchEvent(const NativeWebTouchEvent& event)
1948 if (event.type() == WebEvent::TouchStart)
1949 m_isTrackingTouchEvents = shouldStartTrackingTouchEvents(event);
1951 if (!m_isTrackingTouchEvents)
1954 // If the page is suspended, which should be the case during panning, pinching
1955 // and animation on the page itself (kinetic scrolling, tap to zoom) etc, then
1956 // we do not send any of the events to the page even if is has listeners.
1957 if (!m_isPageSuspended) {
1958 m_touchEventQueue.append(event);
1959 m_process->responsivenessTimer()->start();
1960 m_process->send(Messages::WebPage::TouchEvent(event), m_pageID);
1962 if (m_touchEventQueue.isEmpty()) {
1963 bool isEventHandled = false;
1964 m_pageClient.doneWithTouchEvent(event, isEventHandled);
1966 // We attach the incoming events to the newest queued event so that all
1967 // the events are delivered in the correct order when the event is dequed.
1968 QueuedTouchEvents& lastEvent = m_touchEventQueue.last();
1969 lastEvent.deferredTouchEvents.append(event);
1973 if (event.allTouchPointsAreReleased())
1974 m_isTrackingTouchEvents = false;
1976 #endif // ENABLE(TOUCH_EVENTS)
1978 void WebPageProxy::scrollBy(ScrollDirection direction, ScrollGranularity granularity)
1983 m_process->send(Messages::WebPage::ScrollBy(direction, granularity), m_pageID);
1986 void WebPageProxy::centerSelectionInVisibleArea()
1991 m_process->send(Messages::WebPage::CenterSelectionInVisibleArea(), m_pageID);
1994 void WebPageProxy::receivedPolicyDecision(PolicyAction action, WebFrameProxy* frame, uint64_t listenerID, API::Navigation* navigation)
1999 auto transaction = m_pageLoadState.transaction();
2001 if (action == PolicyIgnore)
2002 m_pageLoadState.clearPendingAPIRequestURL(transaction);
2004 uint64_t downloadID = 0;
2005 if (action == PolicyDownload) {
2006 // Create a download proxy.
2007 // FIXME: We should ensure that the downloadRequest is never empty.
2008 const ResourceRequest& downloadRequest = m_decidePolicyForResponseRequest ? *m_decidePolicyForResponseRequest : ResourceRequest();
2009 DownloadProxy* download = m_process->processPool().createDownloadProxy(downloadRequest);
2010 downloadID = download->downloadID();
2011 handleDownloadRequest(download);
2014 // If we received a policy decision while in decidePolicyForResponse the decision will
2015 // be sent back to the web process by decidePolicyForResponse.
2016 if (m_inDecidePolicyForResponseSync) {
2017 m_syncMimeTypePolicyActionIsValid = true;
2018 m_syncMimeTypePolicyAction = action;
2019 m_syncMimeTypePolicyDownloadID = downloadID;
2023 // If we received a policy decision while in decidePolicyForNavigationAction the decision will
2024 // be sent back to the web process by decidePolicyForNavigationAction.
2025 if (m_inDecidePolicyForNavigationAction) {
2026 m_syncNavigationActionPolicyActionIsValid = true;
2027 m_syncNavigationActionPolicyAction = action;
2028 m_syncNavigationActionPolicyDownloadID = downloadID;
2032 m_process->send(Messages::WebPage::DidReceivePolicyDecision(frame->frameID(), listenerID, action, navigation ? navigation->navigationID() : 0, downloadID), m_pageID);
2035 void WebPageProxy::setUserAgent(const String& userAgent)
2037 if (m_userAgent == userAgent)
2039 m_userAgent = userAgent;
2043 m_process->send(Messages::WebPage::SetUserAgent(m_userAgent), m_pageID);
2046 void WebPageProxy::setApplicationNameForUserAgent(const String& applicationName)
2048 if (m_applicationNameForUserAgent == applicationName)
2051 m_applicationNameForUserAgent = applicationName;
2052 if (!m_customUserAgent.isEmpty())
2055 setUserAgent(standardUserAgent(m_applicationNameForUserAgent));
2058 void WebPageProxy::setCustomUserAgent(const String& customUserAgent)
2060 if (m_customUserAgent == customUserAgent)
2063 m_customUserAgent = customUserAgent;
2065 if (m_customUserAgent.isEmpty()) {
2066 setUserAgent(standardUserAgent(m_applicationNameForUserAgent));
2070 setUserAgent(m_customUserAgent);
2073 void WebPageProxy::resumeActiveDOMObjectsAndAnimations()
2075 if (!isValid() || !m_isPageSuspended)
2078 m_isPageSuspended = false;
2080 m_process->send(Messages::WebPage::ResumeActiveDOMObjectsAndAnimations(), m_pageID);
2083 void WebPageProxy::suspendActiveDOMObjectsAndAnimations()
2085 if (!isValid() || m_isPageSuspended)
2088 m_isPageSuspended = true;
2090 m_process->send(Messages::WebPage::SuspendActiveDOMObjectsAndAnimations(), m_pageID);
2093 bool WebPageProxy::supportsTextEncoding() const
2095 // FIXME (118840): We should probably only support this for text documents, not all non-image documents.
2096 return m_mainFrame && !m_mainFrame->isDisplayingStandaloneImageDocument();
2099 void WebPageProxy::setCustomTextEncodingName(const String& encodingName)
2101 if (m_customTextEncodingName == encodingName)
2103 m_customTextEncodingName = encodingName;
2107 m_process->send(Messages::WebPage::SetCustomTextEncodingName(encodingName), m_pageID);
2110 void WebPageProxy::terminateProcess()
2112 // requestTermination() is a no-op for launching processes, so we get into an inconsistent state by calling resetStateAfterProcessExited().
2113 // FIXME: A client can terminate the page at any time, so we should do something more meaningful than assert and fall apart in release builds.
2114 // See also <https://bugs.webkit.org/show_bug.cgi?id=136012>.
2115 ASSERT(m_process->state() != WebProcessProxy::State::Launching);
2117 // NOTE: This uses a check of m_isValid rather than calling isValid() since
2118 // we want this to run even for pages being closed or that already closed.
2122 m_process->requestTermination();
2123 resetStateAfterProcessExited();
2126 SessionState WebPageProxy::sessionState(const std::function<bool (WebBackForwardListItem&)>& filter) const
2128 SessionState sessionState;
2130 sessionState.backForwardListState = m_backForwardList->backForwardListState(filter);
2132 String provisionalURLString = m_pageLoadState.pendingAPIRequestURL();
2133 if (provisionalURLString.isEmpty())
2134 provisionalURLString = m_pageLoadState.provisionalURL();
2136 if (!provisionalURLString.isEmpty())
2137 sessionState.provisionalURL = URL(URL(), provisionalURLString);
2139 sessionState.renderTreeSize = renderTreeSize();
2140 return sessionState;
2143 RefPtr<API::Navigation> WebPageProxy::restoreFromSessionState(SessionState sessionState, bool navigate)
2145 m_sessionRestorationRenderTreeSize = 0;
2146 m_hitRenderTreeSizeThreshold = false;
2148 bool hasBackForwardList = !!sessionState.backForwardListState.currentIndex;
2150 if (hasBackForwardList) {
2151 m_backForwardList->restoreFromState(WTF::move(sessionState.backForwardListState));
2153 for (const auto& entry : m_backForwardList->entries())
2154 process().registerNewWebBackForwardListItem(entry.get());
2156 process().send(Messages::WebPage::RestoreSession(m_backForwardList->itemStates()), m_pageID);
2158 // The back / forward list was restored from a sessionState so we don't want to snapshot the current
2159 // page when navigating away. Suppress navigation snapshotting until the next load has committed.
2160 m_suppressNavigationSnapshotting = true;
2163 // FIXME: Navigating should be separate from state restoration.
2165 m_sessionRestorationRenderTreeSize = sessionState.renderTreeSize;
2166 if (!m_sessionRestorationRenderTreeSize)
2167 m_hitRenderTreeSizeThreshold = true; // If we didn't get data on renderTreeSize, just don't fire the milestone.
2169 if (!sessionState.provisionalURL.isNull())
2170 return loadRequest(sessionState.provisionalURL);
2172 if (hasBackForwardList) {
2173 // FIXME: Do we have to null check the back forward list item here?
2174 if (WebBackForwardListItem* item = m_backForwardList->currentItem())
2175 return goToBackForwardItem(item);
2182 bool WebPageProxy::supportsTextZoom() const
2184 // FIXME (118840): This should also return false for standalone media and plug-in documents.
2185 if (!m_mainFrame || m_mainFrame->isDisplayingStandaloneImageDocument())
2191 void WebPageProxy::setTextZoomFactor(double zoomFactor)
2196 if (m_textZoomFactor == zoomFactor)
2199 m_textZoomFactor = zoomFactor;
2200 m_process->send(Messages::WebPage::SetTextZoomFactor(m_textZoomFactor), m_pageID);
2203 void WebPageProxy::setPageZoomFactor(double zoomFactor)
2208 if (m_pageZoomFactor == zoomFactor)
2211 m_pageZoomFactor = zoomFactor;
2212 m_process->send(Messages::WebPage::SetPageZoomFactor(m_pageZoomFactor), m_pageID);
2215 void WebPageProxy::setPageAndTextZoomFactors(double pageZoomFactor, double textZoomFactor)
2220 if (m_pageZoomFactor == pageZoomFactor && m_textZoomFactor == textZoomFactor)
2223 m_pageZoomFactor = pageZoomFactor;
2224 m_textZoomFactor = textZoomFactor;
2225 m_process->send(Messages::WebPage::SetPageAndTextZoomFactors(m_pageZoomFactor, m_textZoomFactor), m_pageID);
2228 double WebPageProxy::pageZoomFactor() const
2230 // Zoom factor for non-PDF pages persists across page loads. We maintain a separate member variable for PDF
2231 // zoom which ensures that we don't use the PDF zoom for a normal page.
2232 if (m_mainFrame && m_mainFrame->isDisplayingPDFDocument())
2233 return m_pluginZoomFactor;
2234 return m_pageZoomFactor;
2237 double WebPageProxy::pageScaleFactor() const
2239 // PDF documents use zoom and scale factors to size themselves appropriately in the window. We store them
2240 // separately but decide which to return based on the main frame.
2241 if (m_mainFrame && m_mainFrame->isDisplayingPDFDocument())
2242 return m_pluginScaleFactor;
2243 return m_pageScaleFactor;
2246 void WebPageProxy::scalePage(double scale, const IntPoint& origin)
2253 m_pageScaleFactor = scale;
2254 m_process->send(Messages::WebPage::ScalePage(scale, origin), m_pageID);
2257 void WebPageProxy::scalePageInViewCoordinates(double scale, const IntPoint& centerInViewCoordinates)
2264 m_pageScaleFactor = scale;
2265 m_process->send(Messages::WebPage::ScalePageInViewCoordinates(scale, centerInViewCoordinates), m_pageID);
2268 void WebPageProxy::scaleView(double scale)
2275 m_viewScaleFactor = scale;
2276 m_process->send(Messages::WebPage::ScaleView(scale), m_pageID);
2279 void WebPageProxy::setIntrinsicDeviceScaleFactor(float scaleFactor)
2281 if (m_intrinsicDeviceScaleFactor == scaleFactor)
2284 m_intrinsicDeviceScaleFactor = scaleFactor;
2287 m_drawingArea->deviceScaleFactorDidChange();
2290 void WebPageProxy::windowScreenDidChange(PlatformDisplayID displayID)
2295 m_process->send(Messages::WebPage::WindowScreenDidChange(displayID), m_pageID);
2298 float WebPageProxy::deviceScaleFactor() const
2300 if (m_customDeviceScaleFactor)
2301 return m_customDeviceScaleFactor;
2302 return m_intrinsicDeviceScaleFactor;
2305 void WebPageProxy::setCustomDeviceScaleFactor(float customScaleFactor)
2310 // FIXME: Remove this once we bump cairo requirements to support HiDPI.
2311 // https://bugs.webkit.org/show_bug.cgi?id=133378
2312 #if USE(CAIRO) && !HAVE(CAIRO_SURFACE_SET_DEVICE_SCALE)
2316 if (m_customDeviceScaleFactor == customScaleFactor)
2319 float oldScaleFactor = deviceScaleFactor();
2321 m_customDeviceScaleFactor = customScaleFactor;
2323 if (deviceScaleFactor() != oldScaleFactor)
2324 m_drawingArea->deviceScaleFactorDidChange();
2327 void WebPageProxy::setUseFixedLayout(bool fixed)
2332 // This check is fine as the value is initialized in the web
2333 // process as part of the creation parameters.
2334 if (fixed == m_useFixedLayout)
2337 m_useFixedLayout = fixed;
2339 m_fixedLayoutSize = IntSize();
2340 m_process->send(Messages::WebPage::SetUseFixedLayout(fixed), m_pageID);
2343 void WebPageProxy::setFixedLayoutSize(const IntSize& size)
2348 if (size == m_fixedLayoutSize)
2351 m_fixedLayoutSize = size;
2352 m_process->send(Messages::WebPage::SetFixedLayoutSize(size), m_pageID);
2355 void WebPageProxy::listenForLayoutMilestones(WebCore::LayoutMilestones milestones)
2360 m_wantsSessionRestorationRenderTreeSizeThresholdEvent = milestones & WebCore::ReachedSessionRestorationRenderTreeSizeThreshold;
2362 m_process->send(Messages::WebPage::ListenForLayoutMilestones(milestones), m_pageID);
2365 void WebPageProxy::setSuppressScrollbarAnimations(bool suppressAnimations)
2370 if (suppressAnimations == m_suppressScrollbarAnimations)
2373 m_suppressScrollbarAnimations = suppressAnimations;
2374 m_process->send(Messages::WebPage::SetSuppressScrollbarAnimations(suppressAnimations), m_pageID);
2377 bool WebPageProxy::rubberBandsAtLeft() const
2379 return m_rubberBandsAtLeft;
2382 void WebPageProxy::setRubberBandsAtLeft(bool rubberBandsAtLeft)
2384 m_rubberBandsAtLeft = rubberBandsAtLeft;
2387 bool WebPageProxy::rubberBandsAtRight() const
2389 return m_rubberBandsAtRight;
2392 void WebPageProxy::setRubberBandsAtRight(bool rubberBandsAtRight)
2394 m_rubberBandsAtRight = rubberBandsAtRight;
2397 bool WebPageProxy::rubberBandsAtTop() const
2399 return m_rubberBandsAtTop;
2402 void WebPageProxy::setRubberBandsAtTop(bool rubberBandsAtTop)
2404 m_rubberBandsAtTop = rubberBandsAtTop;
2407 bool WebPageProxy::rubberBandsAtBottom() const
2409 return m_rubberBandsAtBottom;
2412 void WebPageProxy::setRubberBandsAtBottom(bool rubberBandsAtBottom)
2414 m_rubberBandsAtBottom = rubberBandsAtBottom;
2417 void WebPageProxy::setEnableVerticalRubberBanding(bool enableVerticalRubberBanding)
2419 if (enableVerticalRubberBanding == m_enableVerticalRubberBanding)
2422 m_enableVerticalRubberBanding = enableVerticalRubberBanding;
2426 m_process->send(Messages::WebPage::SetEnableVerticalRubberBanding(enableVerticalRubberBanding), m_pageID);
2429 bool WebPageProxy::verticalRubberBandingIsEnabled() const
2431 return m_enableVerticalRubberBanding;
2434 void WebPageProxy::setEnableHorizontalRubberBanding(bool enableHorizontalRubberBanding)
2436 if (enableHorizontalRubberBanding == m_enableHorizontalRubberBanding)
2439 m_enableHorizontalRubberBanding = enableHorizontalRubberBanding;
2443 m_process->send(Messages::WebPage::SetEnableHorizontalRubberBanding(enableHorizontalRubberBanding), m_pageID);
2446 bool WebPageProxy::horizontalRubberBandingIsEnabled() const
2448 return m_enableHorizontalRubberBanding;
2451 void WebPageProxy::setBackgroundExtendsBeyondPage(bool backgroundExtendsBeyondPage)
2453 if (backgroundExtendsBeyondPage == m_backgroundExtendsBeyondPage)
2456 m_backgroundExtendsBeyondPage = backgroundExtendsBeyondPage;
2460 m_process->send(Messages::WebPage::SetBackgroundExtendsBeyondPage(backgroundExtendsBeyondPage), m_pageID);
2463 bool WebPageProxy::backgroundExtendsBeyondPage() const
2465 return m_backgroundExtendsBeyondPage;
2468 void WebPageProxy::setPaginationMode(WebCore::Pagination::Mode mode)
2470 if (mode == m_paginationMode)
2473 m_paginationMode = mode;
2477 m_process->send(Messages::WebPage::SetPaginationMode(mode), m_pageID);
2480 void WebPageProxy::setPaginationBehavesLikeColumns(bool behavesLikeColumns)
2482 if (behavesLikeColumns == m_paginationBehavesLikeColumns)
2485 m_paginationBehavesLikeColumns = behavesLikeColumns;
2489 m_process->send(Messages::WebPage::SetPaginationBehavesLikeColumns(behavesLikeColumns), m_pageID);
2492 void WebPageProxy::setPageLength(double pageLength)
2494 if (pageLength == m_pageLength)
2497 m_pageLength = pageLength;
2501 m_process->send(Messages::WebPage::SetPageLength(pageLength), m_pageID);
2504 void WebPageProxy::setGapBetweenPages(double gap)
2506 if (gap == m_gapBetweenPages)
2509 m_gapBetweenPages = gap;
2513 m_process->send(Messages::WebPage::SetGapBetweenPages(gap), m_pageID);
2516 void WebPageProxy::pageScaleFactorDidChange(double scaleFactor)
2518 m_pageScaleFactor = scaleFactor;
2521 void WebPageProxy::pluginScaleFactorDidChange(double pluginScaleFactor)
2523 m_pluginScaleFactor = pluginScaleFactor;
2526 void WebPageProxy::pluginZoomFactorDidChange(double pluginZoomFactor)
2528 m_pluginZoomFactor = pluginZoomFactor;
2531 void WebPageProxy::findStringMatches(const String& string, FindOptions options, unsigned maxMatchCount)
2533 if (string.isEmpty()) {
2534 didFindStringMatches(string, Vector<Vector<WebCore::IntRect>> (), 0);
2538 m_process->send(Messages::WebPage::FindStringMatches(string, options, maxMatchCount), m_pageID);
2541 void WebPageProxy::findString(const String& string, FindOptions options, unsigned maxMatchCount)
2543 m_process->send(Messages::WebPage::FindString(string, options, maxMatchCount), m_pageID);
2546 void WebPageProxy::getImageForFindMatch(int32_t matchIndex)
2548 m_process->send(Messages::WebPage::GetImageForFindMatch(matchIndex), m_pageID);
2551 void WebPageProxy::selectFindMatch(int32_t matchIndex)
2553 m_process->send(Messages::WebPage::SelectFindMatch(matchIndex), m_pageID);
2556 void WebPageProxy::hideFindUI()
2558 m_process->send(Messages::WebPage::HideFindUI(), m_pageID);
2561 void WebPageProxy::countStringMatches(const String& string, FindOptions options, unsigned maxMatchCount)
2566 m_process->send(Messages::WebPage::CountStringMatches(string, options, maxMatchCount), m_pageID);
2569 void WebPageProxy::runJavaScriptInMainFrame(const String& script, std::function<void (API::SerializedScriptValue*, bool hadException, CallbackBase::Error)> callbackFunction)
2572 callbackFunction(nullptr, false, CallbackBase::Error::Unknown);
2576 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2577 m_process->send(Messages::WebPage::RunJavaScriptInMainFrame(script, callbackID), m_pageID);
2580 void WebPageProxy::getRenderTreeExternalRepresentation(std::function<void (const String&, CallbackBase::Error)> callbackFunction)
2583 callbackFunction(String(), CallbackBase::Error::Unknown);
2587 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2588 m_process->send(Messages::WebPage::GetRenderTreeExternalRepresentation(callbackID), m_pageID);
2591 void WebPageProxy::getSourceForFrame(WebFrameProxy* frame, std::function<void (const String&, CallbackBase::Error)> callbackFunction)
2594 callbackFunction(String(), CallbackBase::Error::Unknown);
2598 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2599 m_loadDependentStringCallbackIDs.add(callbackID);
2600 m_process->send(Messages::WebPage::GetSourceForFrame(frame->frameID(), callbackID), m_pageID);
2603 void WebPageProxy::getContentsAsString(std::function<void (const String&, CallbackBase::Error)> callbackFunction)
2606 callbackFunction(String(), CallbackBase::Error::Unknown);
2610 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2611 m_loadDependentStringCallbackIDs.add(callbackID);
2612 m_process->send(Messages::WebPage::GetContentsAsString(callbackID), m_pageID);
2615 void WebPageProxy::getBytecodeProfile(std::function<void (const String&, CallbackBase::Error)> callbackFunction)
2618 callbackFunction(String(), CallbackBase::Error::Unknown);
2622 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2623 m_loadDependentStringCallbackIDs.add(callbackID);
2624 m_process->send(Messages::WebPage::GetBytecodeProfile(callbackID), m_pageID);
2628 void WebPageProxy::getContentsAsMHTMLData(std::function<void (API::Data*, CallbackBase::Error)> callbackFunction, bool useBinaryEncoding)
2631 callbackFunction(nullptr, CallbackBase::Error::Unknown);
2635 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2636 m_process->send(Messages::WebPage::GetContentsAsMHTMLData(callbackID, useBinaryEncoding), m_pageID);
2640 void WebPageProxy::getSelectionOrContentsAsString(std::function<void (const String&, CallbackBase::Error)> callbackFunction)
2643 callbackFunction(String(), CallbackBase::Error::Unknown);
2647 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2648 m_process->send(Messages::WebPage::GetSelectionOrContentsAsString(callbackID), m_pageID);
2651 void WebPageProxy::getSelectionAsWebArchiveData(std::function<void (API::Data*, CallbackBase::Error)> callbackFunction)
2654 callbackFunction(nullptr, CallbackBase::Error::Unknown);
2658 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2659 m_process->send(Messages::WebPage::GetSelectionAsWebArchiveData(callbackID), m_pageID);
2662 void WebPageProxy::getMainResourceDataOfFrame(WebFrameProxy* frame, std::function<void (API::Data*, CallbackBase::Error)> callbackFunction)
2664 if (!isValid() || !frame) {
2665 callbackFunction(nullptr, CallbackBase::Error::Unknown);
2669 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2670 m_process->send(Messages::WebPage::GetMainResourceDataOfFrame(frame->frameID(), callbackID), m_pageID);
2673 void WebPageProxy::getResourceDataFromFrame(WebFrameProxy* frame, API::URL* resourceURL, std::function<void (API::Data*, CallbackBase::Error)> callbackFunction)
2676 callbackFunction(nullptr, CallbackBase::Error::Unknown);
2680 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2681 m_process->send(Messages::WebPage::GetResourceDataFromFrame(frame->frameID(), resourceURL->string(), callbackID), m_pageID);
2684 void WebPageProxy::getWebArchiveOfFrame(WebFrameProxy* frame, std::function<void (API::Data*, CallbackBase::Error)> callbackFunction)
2687 callbackFunction(nullptr, CallbackBase::Error::Unknown);
2691 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2692 m_process->send(Messages::WebPage::GetWebArchiveOfFrame(frame->frameID(), callbackID), m_pageID);
2695 void WebPageProxy::forceRepaint(PassRefPtr<VoidCallback> prpCallback)
2697 RefPtr<VoidCallback> callback = prpCallback;
2699 // FIXME: If the page is invalid we should not call the callback. It'd be better to just return false from forceRepaint.
2700 callback->invalidate(CallbackBase::Error::OwnerWasInvalidated);
2704 uint64_t callbackID = callback->callbackID();
2705 m_callbacks.put(callback);
2706 m_drawingArea->waitForBackingStoreUpdateOnNextPaint();
2707 m_process->send(Messages::WebPage::ForceRepaint(callbackID), m_pageID);
2710 void WebPageProxy::preferencesDidChange()
2715 #if ENABLE(INSPECTOR_SERVER)
2716 if (m_preferences->developerExtrasEnabled())
2717 inspector()->enableRemoteInspection();
2720 updateProccessSuppressionState();
2722 m_pageClient.preferencesDidChange();
2724 // FIXME: It probably makes more sense to send individual preference changes.
2725 // However, WebKitTestRunner depends on getting a preference change notification
2726 // even if nothing changed in UI process, so that overrides get removed.
2728 // Preferences need to be updated during synchronous printing to make "print backgrounds" preference work when toggled from a print dialog checkbox.
2729 m_process->send(Messages::WebPage::PreferencesDidChange(preferencesStore()), m_pageID, m_isPerformingDOMPrintOperation ? IPC::DispatchMessageEvenWhenWaitingForSyncReply : 0);
2732 void WebPageProxy::didCreateMainFrame(uint64_t frameID)
2734 PageClientProtector protector(m_pageClient);
2736 MESSAGE_CHECK(!m_mainFrame);
2737 MESSAGE_CHECK(m_process->canCreateFrame(frameID));
2739 m_mainFrame = WebFrameProxy::create(this, frameID);
2741 // Add the frame to the process wide map.
2742 m_process->frameCreated(frameID, m_mainFrame.get());
2745 void WebPageProxy::didCreateSubframe(uint64_t frameID)
2747 PageClientProtector protector(m_pageClient);
2749 MESSAGE_CHECK(m_mainFrame);
2750 MESSAGE_CHECK(m_process->canCreateFrame(frameID));
2752 RefPtr<WebFrameProxy> subFrame = WebFrameProxy::create(this, frameID);
2754 // Add the frame to the process wide map.
2755 m_process->frameCreated(frameID, subFrame.get());
2758 double WebPageProxy::estimatedProgress() const
2760 return m_pageLoadState.estimatedProgress();
2763 void WebPageProxy::didStartProgress()
2765 PageClientProtector protector(m_pageClient);
2767 auto transaction = m_pageLoadState.transaction();
2768 m_pageLoadState.didStartProgress(transaction);
2770 m_pageLoadState.commitChanges();
2771 m_loaderClient->didStartProgress(*this);
2774 void WebPageProxy::didChangeProgress(double value)
2776 PageClientProtector protector(m_pageClient);
2778 auto transaction = m_pageLoadState.transaction();
2779 m_pageLoadState.didChangeProgress(transaction, value);
2781 m_pageLoadState.commitChanges();
2782 m_loaderClient->didChangeProgress(*this);
2785 void WebPageProxy::didFinishProgress()
2787 PageClientProtector protector(m_pageClient);
2789 auto transaction = m_pageLoadState.transaction();
2790 m_pageLoadState.didFinishProgress(transaction);
2792 m_pageLoadState.commitChanges();
2793 m_loaderClient->didFinishProgress(*this);
2796 void WebPageProxy::setNetworkRequestsInProgress(bool networkRequestsInProgress)
2798 auto transaction = m_pageLoadState.transaction();
2799 m_pageLoadState.setNetworkRequestsInProgress(transaction, networkRequestsInProgress);
2802 void WebPageProxy::didDestroyNavigation(uint64_t navigationID)
2804 PageClientProtector protector(m_pageClient);
2806 // FIXME: Message check the navigationID.
2807 m_navigationState->didDestroyNavigation(navigationID);
2810 void WebPageProxy::didStartProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& url, const String& unreachableURL, const UserData& userData)
2812 PageClientProtector protector(m_pageClient);
2814 auto transaction = m_pageLoadState.transaction();
2816 m_pageLoadState.clearPendingAPIRequestURL(transaction);
2818 WebFrameProxy* frame = m_process->webFrame(frameID);
2819 MESSAGE_CHECK(frame);
2820 MESSAGE_CHECK_URL(url);
2822 // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
2823 RefPtr<API::Navigation> navigation;
2824 if (frame->isMainFrame() && navigationID)
2825 navigation = &navigationState().navigation(navigationID);
2827 if (frame->isMainFrame())
2828 m_pageLoadState.didStartProvisionalLoad(transaction, url, unreachableURL);
2830 frame->setUnreachableURL(unreachableURL);
2831 frame->didStartProvisionalLoad(url);
2833 m_pageLoadState.commitChanges();
2834 if (m_navigationClient) {
2835 if (frame->isMainFrame())
2836 m_navigationClient->didStartProvisionalNavigation(*this, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
2838 m_loaderClient->didStartProvisionalLoadForFrame(*this, *frame, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
2841 void WebPageProxy::didReceiveServerRedirectForProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& url, const UserData& userData)
2843 PageClientProtector protector(m_pageClient);
2845 WebFrameProxy* frame = m_process->webFrame(frameID);
2846 MESSAGE_CHECK(frame);
2847 MESSAGE_CHECK_URL(url);
2849 // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
2850 RefPtr<API::Navigation> navigation;
2851 if (frame->isMainFrame() && navigationID)
2852 navigation = &navigationState().navigation(navigationID);
2854 auto transaction = m_pageLoadState.transaction();
2856 if (frame->isMainFrame())
2857 m_pageLoadState.didReceiveServerRedirectForProvisionalLoad(transaction, url);
2859 frame->didReceiveServerRedirectForProvisionalLoad(url);
2861 m_pageLoadState.commitChanges();
2862 if (m_navigationClient) {
2863 if (frame->isMainFrame())
2864 m_navigationClient->didReceiveServerRedirectForProvisionalNavigation(*this, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
2866 m_loaderClient->didReceiveServerRedirectForProvisionalLoadForFrame(*this, *frame, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
2869 void WebPageProxy::didChangeProvisionalURLForFrame(uint64_t frameID, uint64_t, const String& url)
2871 PageClientProtector protector(m_pageClient);
2873 WebFrameProxy* frame = m_process->webFrame(frameID);
2874 MESSAGE_CHECK(frame);
2875 MESSAGE_CHECK(frame->frameLoadState().state() == FrameLoadState::State::Provisional);
2876 MESSAGE_CHECK_URL(url);
2878 auto transaction = m_pageLoadState.transaction();
2880 // Internally, we handle this the same way we handle a server redirect. There are no client callbacks
2881 // for this, but if this is the main frame, clients may observe a change to the page's URL.
2882 if (frame->isMainFrame())
2883 m_pageLoadState.didReceiveServerRedirectForProvisionalLoad(transaction, url);
2885 frame->didReceiveServerRedirectForProvisionalLoad(url);
2888 void WebPageProxy::didFailProvisionalLoadForFrame(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, const String& provisionalURL, const ResourceError& error, const UserData& userData)
2890 PageClientProtector protector(m_pageClient);
2892 WebFrameProxy* frame = m_process->webFrame(frameID);
2893 MESSAGE_CHECK(frame);
2895 // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
2896 RefPtr<API::Navigation> navigation;
2897 if (frame->isMainFrame() && navigationID)
2898 navigation = navigationState().takeNavigation(navigationID);
2900 auto transaction = m_pageLoadState.transaction();
2902 if (frame->isMainFrame())
2903 m_pageLoadState.didFailProvisionalLoad(transaction);
2905 frame->didFailProvisionalLoad();
2907 m_pageLoadState.commitChanges();
2909 ASSERT(!m_failingProvisionalLoadURL);
2910 m_failingProvisionalLoadURL = provisionalURL;
2912 if (m_navigationClient) {
2913 if (frame->isMainFrame())
2914 m_navigationClient->didFailProvisionalNavigationWithError(*this, *frame, navigation.get(), error, m_process->transformHandlesToObjects(userData.object()).get());
2916 // FIXME: Get the main frame's current navigation.
2917 m_navigationClient->didFailProvisionalLoadInSubframeWithError(*this, *frame, frameSecurityOrigin, nullptr, error, m_process->transformHandlesToObjects(userData.object()).get());
2920 m_loaderClient->didFailProvisionalLoadWithErrorForFrame(*this, *frame, navigation.get(), error, m_process->transformHandlesToObjects(userData.object()).get());
2922 m_failingProvisionalLoadURL = { };
2925 void WebPageProxy::clearLoadDependentCallbacks()
2927 Vector<uint64_t> callbackIDsCopy;
2928 copyToVector(m_loadDependentStringCallbackIDs, callbackIDsCopy);
2929 m_loadDependentStringCallbackIDs.clear();
2931 for (size_t i = 0; i < callbackIDsCopy.size(); ++i) {
2932 auto callback = m_callbacks.take<StringCallback>(callbackIDsCopy[i]);
2934 callback->invalidate();
2938 void WebPageProxy::didCommitLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& mimeType, bool frameHasCustomContentProvider, uint32_t opaqueFrameLoadType, const WebCore::CertificateInfo& certificateInfo, bool containsPluginDocument, const UserData& userData)
2940 PageClientProtector protector(m_pageClient);
2942 WebFrameProxy* frame = m_process->webFrame(frameID);
2943 MESSAGE_CHECK(frame);
2945 // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
2946 RefPtr<API::Navigation> navigation;
2947 if (frame->isMainFrame() && navigationID)
2948 navigation = &navigationState().navigation(navigationID);
2951 if (frame->isMainFrame()) {
2952 m_hasReceivedLayerTreeTransactionAfterDidCommitLoad = false;
2953 m_firstLayerTreeTransactionIdAfterDidCommitLoad = downcast<RemoteLayerTreeDrawingAreaProxy>(*drawingArea()).nextLayerTreeTransactionID();
2957 auto transaction = m_pageLoadState.transaction();
2958 bool markPageInsecure = m_treatsSHA1CertificatesAsInsecure && certificateInfo.containsNonRootSHA1SignedCertificate();
2959 Ref<WebCertificateInfo> webCertificateInfo = WebCertificateInfo::create(certificateInfo);
2960 if (frame->isMainFrame()) {
2961 m_pageLoadState.didCommitLoad(transaction, webCertificateInfo, markPageInsecure);
2962 m_suppressNavigationSnapshotting = false;
2963 } else if (markPageInsecure)
2964 m_pageLoadState.didDisplayOrRunInsecureContent(transaction);
2967 // FIXME (bug 59111): didCommitLoadForFrame comes too late when restoring a page from b/f cache, making us disable secure event mode in password fields.
2968 // FIXME: A load going on in one frame shouldn't affect text editing in other frames on the page.
2969 m_pageClient.resetSecureInputState();
2970 m_pageClient.dismissContentRelativeChildWindows();
2973 clearLoadDependentCallbacks();
2975 frame->didCommitLoad(mimeType, webCertificateInfo, containsPluginDocument);
2977 if (frame->isMainFrame()) {
2978 m_mainFrameHasCustomContentProvider = frameHasCustomContentProvider;
2980 if (m_mainFrameHasCustomContentProvider) {
2981 // Always assume that the main frame is pinned here, since the custom representation view will handle
2982 // any wheel events and dispatch them to the WKView when necessary.
2983 m_mainFrameIsPinnedToLeftSide = true;
2984 m_mainFrameIsPinnedToRightSide = true;
2985 m_mainFrameIsPinnedToTopSide = true;
2986 m_mainFrameIsPinnedToBottomSide = true;
2988 m_uiClient->pinnedStateDidChange(*this);
2990 m_pageClient.didCommitLoadForMainFrame(mimeType, frameHasCustomContentProvider);
2993 // Even if WebPage has the default pageScaleFactor (and therefore doesn't reset it),
2994 // WebPageProxy's cache of the value can get out of sync (e.g. in the case where a
2995 // plugin is handling page scaling itself) so we should reset it to the default
2996 // for standard main frame loads.
2997 if (frame->isMainFrame() && static_cast<FrameLoadType>(opaqueFrameLoadType) == FrameLoadType::Standard) {
2998 m_pageScaleFactor = 1;
2999 m_pluginScaleFactor = 1;
3002 m_pageLoadState.commitChanges();
3003 if (m_navigationClient) {
3004 if (frame->isMainFrame())
3005 m_navigationClient->didCommitNavigation(*this, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
3007 m_loaderClient->didCommitLoadForFrame(*this, *frame, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
3010 void WebPageProxy::didFinishDocumentLoadForFrame(uint64_t frameID, uint64_t navigationID, const UserData& userData)
3012 PageClientProtector protector(m_pageClient);
3014 WebFrameProxy* frame = m_process->webFrame(frameID);
3015 MESSAGE_CHECK(frame);
3017 // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
3018 RefPtr<API::Navigation> navigation;
3019 if (frame->isMainFrame() && navigationID)
3020 navigation = &navigationState().navigation(navigationID);
3022 if (m_navigationClient) {
3023 if (frame->isMainFrame())
3024 m_navigationClient->didFinishDocumentLoad(*this, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
3026 m_loaderClient->didFinishDocumentLoadForFrame(*this, *frame, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
3029 void WebPageProxy::didFinishLoadForFrame(uint64_t frameID, uint64_t navigationID, const UserData& userData)
3031 PageClientProtector protector(m_pageClient);
3033 WebFrameProxy* frame = m_process->webFrame(frameID);
3034 MESSAGE_CHECK(frame);
3036 // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
3037 RefPtr<API::Navigation> navigation;
3038 if (frame->isMainFrame() && navigationID)
3039 navigation = &navigationState().navigation(navigationID);
3041 auto transaction = m_pageLoadState.transaction();
3043 bool isMainFrame = frame->isMainFrame();
3045 m_pageLoadState.didFinishLoad(transaction);
3047 frame->didFinishLoad();
3049 m_pageLoadState.commitChanges();
3050 if (m_navigationClient) {
3052 m_navigationClient->didFinishNavigation(*this, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
3054 m_loaderClient->didFinishLoadForFrame(*this, *frame, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
3057 m_pageClient.didFinishLoadForMainFrame();
3060 void WebPageProxy::didFailLoadForFrame(uint64_t frameID, uint64_t navigationID, const ResourceError& error, const UserData& userData)
3062 PageClientProtector protector(m_pageClient);
3064 WebFrameProxy* frame = m_process->webFrame(frameID);
3065 MESSAGE_CHECK(frame);
3067 // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
3068 RefPtr<API::Navigation> navigation;
3069 if (frame->isMainFrame() && navigationID)
3070 navigation = &navigationState().navigation(navigationID);
3072 clearLoadDependentCallbacks();
3074 auto transaction = m_pageLoadState.transaction();
3076 bool isMainFrame = frame->isMainFrame();
3079 m_pageLoadState.didFailLoad(transaction);
3081 frame->didFailLoad();
3083 m_pageLoadState.commitChanges();
3084 if (m_navigationClient) {
3085 if (frame->isMainFrame())
3086 m_navigationClient->didFailNavigationWithError(*this, *frame, navigation.get(), error, m_process->transformHandlesToObjects(userData.object()).get());
3088 m_loaderClient->didFailLoadWithErrorForFrame(*this, *frame, navigation.get(), error, m_process->transformHandlesToObjects(userData.object()).get());
3091 m_pageClient.didFailLoadForMainFrame();
3094 void WebPageProxy::didSameDocumentNavigationForFrame(uint64_t frameID, uint64_t navigationID, uint32_t opaqueSameDocumentNavigationType, const String& url, const UserData& userData)
3096 PageClientProtector protector(m_pageClient);
3098 WebFrameProxy* frame = m_process->webFrame(frameID);
3099 MESSAGE_CHECK(frame);
3100 MESSAGE_CHECK_URL(url);
3102 // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
3103 RefPtr<API::Navigation> navigation;
3104 if (frame->isMainFrame() && navigationID)
3105 navigation = &navigationState().navigation(navigationID);
3107 auto transaction = m_pageLoadState.transaction();
3109 bool isMainFrame = frame->isMainFrame();
3111 m_pageLoadState.didSameDocumentNavigation(transaction, url);
3113 m_pageLoadState.clearPendingAPIRequestURL(transaction);
3114 frame->didSameDocumentNavigation(url);
3116 m_pageLoadState.commitChanges();
3118 SameDocumentNavigationType navigationType = static_cast<SameDocumentNavigationType>(opaqueSameDocumentNavigationType);
3119 if (m_navigationClient) {
3121 m_navigationClient->didSameDocumentNavigation(*this, navigation.get(), navigationType, m_process->transformHandlesToObjects(userData.object()).get());
3123 m_loaderClient->didSameDocumentNavigationForFrame(*this, *frame, navigation.get(), navigationType, m_process->transformHandlesToObjects(userData.object()).get());
3126 m_pageClient.didSameDocumentNavigationForMainFrame(navigationType);
3129 void WebPageProxy::didReceiveTitleForFrame(uint64_t frameID, const String& title, const UserData& userData)
3131 PageClientProtector protector(m_pageClient);
3133 WebFrameProxy* frame = m_process->webFrame(frameID);
3134 MESSAGE_CHECK(frame);
3136 auto transaction = m_pageLoadState.transaction();
3138 if (frame->isMainFrame())
3139 m_pageLoadState.setTitle(transaction, title);
3141 frame->didChangeTitle(title);
3143 m_pageLoadState.commitChanges();
3144 m_loaderClient->didReceiveTitleForFrame(*this, title, *frame, m_process->transformHandlesToObjects(userData.object()).get());
3147 void WebPageProxy::didFirstLayoutForFrame(uint64_t frameID, const UserData& userData)
3149 PageClientProtector protector(m_pageClient);
3151 WebFrameProxy* frame = m_process->webFrame(frameID);
3152 MESSAGE_CHECK(frame);
3154 m_loaderClient->didFirstLayoutForFrame(*this, *frame, m_process->transformHandlesToObjects(userData.object()).get());
3157 void WebPageProxy::didFirstVisuallyNonEmptyLayoutForFrame(uint64_t frameID, const UserData& userData)
3159 PageClientProtector protector(m_pageClient);
3161 WebFrameProxy* frame = m_process->webFrame(frameID);
3162 MESSAGE_CHECK(frame);
3164 m_loaderClient->didFirstVisuallyNonEmptyLayoutForFrame(*this, *frame, m_process->transformHandlesToObjects(userData.object()).get());
3166 if (frame->isMainFrame())
3167 m_pageClient.didFirstVisuallyNonEmptyLayoutForMainFrame();
3170 void WebPageProxy::didLayoutForCustomContentProvider()
3172 didLayout(DidFirstLayout | DidFirstVisuallyNonEmptyLayout | DidHitRelevantRepaintedObjectsAreaThreshold);
3175 void WebPageProxy::didLayout(uint32_t layoutMilestones)
3177 PageClientProtector protector(m_pageClient);
3179 if (m_navigationClient)
3180 m_navigationClient->renderingProgressDidChange(*this, static_cast<LayoutMilestones>(layoutMilestones));
3182 m_loaderClient->didLayout(*this, static_cast<LayoutMilestones>(layoutMilestones));
3185 void WebPageProxy::didRemoveFrameFromHierarchy(uint64_t frameID, const UserData& userData)
3187 PageClientProtector protector(m_pageClient);
3189 WebFrameProxy* frame = m_process->webFrame(frameID);
3190 MESSAGE_CHECK(frame);
3192 m_loaderClient->didRemoveFrameFromHierarchy(*this, *frame, m_process->transformHandlesToObjects(userData.object()).get());
3195 void WebPageProxy::didDisplayInsecureContentForFrame(uint64_t frameID, const UserData& userData)
3197 PageClientProtector protector(m_pageClient);
3199 WebFrameProxy* frame = m_process->webFrame(frameID);
3200 MESSAGE_CHECK(frame);
3202 auto transaction = m_pageLoadState.transaction();
3203 m_pageLoadState.didDisplayOrRunInsecureContent(transaction);
3205 m_pageLoadState.commitChanges();
3206 m_loaderClient->didDisplayInsecureContentForFrame(*this, *frame, m_process->transformHandlesToObjects(userData.object()).get());
3209 void WebPageProxy::didRunInsecureContentForFrame(uint64_t frameID, const UserData& userData)
3211 PageClientProtector protector(m_pageClient);
3213 WebFrameProxy* frame = m_process->webFrame(frameID);
3214 MESSAGE_CHECK(frame);
3216 auto transaction = m_pageLoadState.transaction();
3217 m_pageLoadState.didDisplayOrRunInsecureContent(transaction);
3219 m_pageLoadState.commitChanges();
3220 m_loaderClient->didRunInsecureContentForFrame(*this, *frame, m_process->transformHandlesToObjects(userData.object()).get());
3223 void WebPageProxy::didDetectXSSForFrame(uint64_t frameID, const UserData& userData)
3225 PageClientProtector protector(m_pageClient);
3227 WebFrameProxy* frame = m_process->webFrame(frameID);
3228 MESSAGE_CHECK(frame);
3230 m_loaderClient->didDetectXSSForFrame(*this, *frame, m_process->transformHandlesToObjects(userData.object()).get());
3233 void WebPageProxy::frameDidBecomeFrameSet(uint64_t frameID, bool value)
3235 PageClientProtector protector(m_pageClient);
3237 WebFrameProxy* frame = m_process->webFrame(frameID);
3238 MESSAGE_CHECK(frame);
3240 frame->setIsFrameSet(value);
3241 if (frame->isMainFrame())
3242 m_frameSetLargestFrame = value ? m_mainFrame : 0;
3245 void WebPageProxy::decidePolicyForNavigationAction(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, const NavigationActionData& navigationActionData, uint64_t originatingFrameID, const SecurityOriginData& originatingFrameSecurityOrigin, const WebCore::ResourceRequest& originalRequest, const ResourceRequest& request, uint64_t listenerID, const UserData& userData, bool& receivedPolicyAction, uint64_t& newNavigationID, uint64_t& policyAction, uint64_t& downloadID)
3247 PageClientProtector protector(m_pageClient);
3249 auto transaction = m_pageLoadState.transaction();
3251 if (request.url() != m_pageLoadState.pendingAPIRequestURL())
3252 m_pageLoadState.clearPendingAPIRequestURL(transaction);
3254 WebFrameProxy* frame = m_process->webFrame(frameID);
3255 MESSAGE_CHECK(frame);
3256 MESSAGE_CHECK_URL(request.url());
3257 MESSAGE_CHECK_URL(originalRequest.url());
3259 WebFrameProxy* originatingFrame = m_process->webFrame(originatingFrameID);
3261 Ref<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
3262 if (!navigationID && frame->isMainFrame()) {
3263 auto navigation = m_navigationState->createLoadRequestNavigation(request);
3264 newNavigationID = navigation->navigationID();
3265 listener->setNavigation(WTF::move(navigation));
3268 #if ENABLE(CONTENT_FILTERING)
3269 if (frame->didHandleContentFilterUnblockNavigation(request)) {
3270 receivedPolicyAction = true;
3271 policyAction = PolicyIgnore;
3276 ASSERT(!m_inDecidePolicyForNavigationAction);
3278 m_inDecidePolicyForNavigationAction = true;
3279 m_syncNavigationActionPolicyActionIsValid = false;
3281 if (m_navigationClient) {
3282 RefPtr<API::FrameInfo> destinationFrameInfo;
3283 RefPtr<API::FrameInfo> sourceFrameInfo;
3286 destinationFrameInfo = API::FrameInfo::create(*frame, frameSecurityOrigin.securityOrigin());
3288 if (originatingFrame == frame)
3289 sourceFrameInfo = destinationFrameInfo;
3290 else if (originatingFrame)
3291 sourceFrameInfo = API::FrameInfo::create(*originatingFrame, originatingFrameSecurityOrigin.securityOrigin());
3293 bool shouldOpenAppLinks = !m_shouldSuppressAppLinksInNextNavigationPolicyDecision && (!destinationFrameInfo || destinationFrameInfo->isMainFrame()) && !protocolHostAndPortAreEqual(URL(ParsedURLString, m_mainFrame->url()), request.url());
3295 auto navigationAction = API::NavigationAction::create(navigationActionData, sourceFrameInfo.get(), destinationFrameInfo.get(), request, originalRequest.url(), shouldOpenAppLinks);
3297 m_navigationClient->decidePolicyForNavigationAction(*this, navigationAction.get(), WTF::move(listener), m_process->transformHandlesToObjects(userData.object()).get());
3299 m_policyClient->decidePolicyForNavigationAction(*this, frame, navigationActionData, originatingFrame, originalRequest, request, WTF::move(listener), m_process->transformHandlesToObjects(userData.object()).get());
3301 m_shouldSuppressAppLinksInNextNavigationPolicyDecision = false;
3302 m_inDecidePolicyForNavigationAction = false;
3304 // Check if we received a policy decision already. If we did, we can just pass it back.
3305 receivedPolicyAction = m_syncNavigationActionPolicyActionIsValid;
3306 if (m_syncNavigationActionPolicyActionIsValid) {
3307 policyAction = m_syncNavigationActionPolicyAction;
3308 downloadID = m_syncNavigationActionPolicyDownloadID;
3312 void WebPageProxy::decidePolicyForNewWindowAction(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, const NavigationActionData& navigationActionData, const ResourceRequest& request, const String& frameName, uint64_t listenerID, const UserData& userData)
3314 PageClientProtector protector(m_pageClient);
3316 WebFrameProxy* frame = m_process->webFrame(frameID);
3317 MESSAGE_CHECK(frame);
3318 MESSAGE_CHECK_URL(request.url());
3320 Ref<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
3322 if (m_navigationClient) {
3323 RefPtr<API::FrameInfo> sourceFrameInfo;
3325 sourceFrameInfo = API::FrameInfo::create(*frame, frameSecurityOrigin.securityOrigin());
3327 bool shouldOpenAppLinks = !protocolHostAndPortAreEqual(URL(ParsedURLString, m_mainFrame->url()), request.url());
3328 auto navigationAction = API::NavigationAction::create(navigationActionData, sourceFrameInfo.get(), nullptr, request, request.url(), shouldOpenAppLinks);
3330 m_navigationClient->decidePolicyForNavigationAction(*this, navigationAction.get(), WTF::move(listener), m_process->transformHandlesToObjects(userData.object()).get());
3333 m_policyClient->decidePolicyForNewWindowAction(*this, *frame, navigationActionData, request, frameName, WTF::move(listener), m_process->transformHandlesToObjects(userData.object()).get());
3336 void WebPageProxy::decidePolicyForResponse(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, const ResourceResponse& response, const ResourceRequest& request, bool canShowMIMEType, uint64_t listenerID, const UserData& userData)
3338 PageClientProtector protector(m_pageClient);
3340 WebFrameProxy* frame = m_process->webFrame(frameID);
3341 MESSAGE_CHECK(frame);
3342 MESSAGE_CHECK_URL(request.url());
3343 MESSAGE_CHECK_URL(response.url());
3345 Ref<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
3347 if (m_navigationClient) {
3348 auto navigationResponse = API::NavigationResponse::create(API::FrameInfo::create(*frame, frameSecurityOrigin.securityOrigin()).get(), request, response, canShowMIMEType);
3349 m_navigationClient->decidePolicyForNavigationResponse(*this, navigationResponse.get(), WTF::move(listener), m_process->transformHandlesToObjects(userData.object()).get());
3351 m_policyClient->decidePolicyForResponse(*this, *frame, response, request, canShowMIMEType, WTF::move(listener), m_process->transformHandlesToObjects(userData.object()).get());
3354 void WebPageProxy::decidePolicyForResponseSync(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, const ResourceResponse& response, const ResourceRequest& request, bool canShowMIMEType, uint64_t listenerID, const UserData& userData, bool& receivedPolicyAction, uint64_t& policyAction, uint64_t& downloadID)
3356 PageClientProtector protector(m_pageClient);
3358 ASSERT(!m_inDecidePolicyForResponseSync);
3360 m_inDecidePolicyForResponseSync = true;
3361 m_decidePolicyForResponseRequest = &request;
3362 m_syncMimeTypePolicyActionIsValid = false;
3364 decidePolicyForResponse(frameID, frameSecurityOrigin, response, request, canShowMIMEType, listenerID, userData);
3366 m_inDecidePolicyForResponseSync = false;
3367 m_decidePolicyForResponseRequest = 0;
3369 // Check if we received a policy decision already. If we did, we can just pass it back.
3370 receivedPolicyAction = m_syncMimeTypePolicyActionIsValid;
3371 if (m_syncMimeTypePolicyActionIsValid) {
3372 policyAction = m_syncMimeTypePolicyAction;
3373 downloadID = m_syncMimeTypePolicyDownloadID;
3377 void WebPageProxy::unableToImplementPolicy(uint64_t frameID, const ResourceError& error, const UserData& userData)
3379 PageClientProtector protector(m_pageClient);
3381 WebFrameProxy* frame = m_process->webFrame(frameID);
3382 MESSAGE_CHECK(frame);
3384 m_policyClient->unableToImplementPolicy(*this, *frame, error, m_process->transformHandlesToObjects(userData.object()).get());
3389 void WebPageProxy::willSubmitForm(uint64_t frameID, uint64_t sourceFrameID, const Vector<std::pair<String, String>>& textFieldValues, uint64_t listenerID, const UserData& userData)
3391 WebFrameProxy* frame = m_process->webFrame(frameID);
3392 MESSAGE_CHECK(frame);
3394 WebFrameProxy* sourceFrame = m_process->webFrame(sourceFrameID);
3395 MESSAGE_CHECK(sourceFrame);
3397 Ref<WebFormSubmissionListenerProxy> listener = frame->setUpFormSubmissionListenerProxy(listenerID);
3398 m_formClient->willSubmitForm(*this, *frame, *sourceFrame, textFieldValues, m_process->transformHandlesToObjects(userData.object()).get(), listener.get());
3401 void WebPageProxy::didNavigateWithNavigationData(const WebNavigationDataStore& store, uint64_t frameID)
3403 PageClientProtector protector(m_pageClient);
3405 WebFrameProxy* frame = m_process->webFrame(frameID);
3406 MESSAGE_CHECK(frame);
3407 MESSAGE_CHECK(frame->page() == this);
3409 if (m_historyClient) {
3410 if (frame->isMainFrame())
3411 m_historyClient->didNavigateWithNavigationData(*this, store);
3413 m_loaderClient->didNavigateWithNavigationData(*this, store, *frame);
3414 process().processPool().historyClient().didNavigateWithNavigationData(process().processPool(), *this, store, *frame);
3417 void WebPageProxy::didPerformClientRedirect(const String& sourceURLString, const String& destinationURLString, uint64_t frameID)
3419 PageClientProtector protector(m_pageClient);
3421 if (sourceURLString.isEmpty() || destinationURLString.isEmpty())
3424 WebFrameProxy* frame = m_process->webFrame(frameID);
3425 MESSAGE_CHECK(frame);
3426 MESSAGE_CHECK(frame->page() == this);
3428 MESSAGE_CHECK_URL(sourceURLString);
3429 MESSAGE_CHECK_URL(destinationURLString);
3431 if (m_historyClient) {
3432 if (frame->isMainFrame())
3433 m_historyClient->didPerformClientRedirect(*this, sourceURLString, destinationURLString);
3435 m_loaderClient->didPerformClientRedirect(*this, sourceURLString, destinationURLString, *frame);
3436 process().processPool().historyClient().didPerformClientRedirect(process().processPool(), *this, sourceURLString, destinationURLString, *frame);
3439 void WebPageProxy::didPerformServerRedirect(const String& sourceURLString, const String& destinationURLString, uint64_t frameID)
3441 PageClientProtector protector(m_pageClient);
3443 if (sourceURLString.isEmpty() || destinationURLString.isEmpty())
3446 WebFrameProxy* frame = m_process->webFrame(frameID);
3447 MESSAGE_CHECK(frame);
3448 MESSAGE_CHECK(frame->page() == this);
3450 MESSAGE_CHECK_URL(sourceURLString);
3451 MESSAGE_CHECK_URL(destinationURLString);
3453 if (m_historyClient) {
3454 if (frame->isMainFrame())
3455 m_historyClient->didPerformServerRedirect(*this, sourceURLString, destinationURLString);
3457 m_loaderClient->didPerformServerRedirect(*this, sourceURLString, destinationURLString, *frame);
3458 process().processPool().historyClient().didPerformServerRedirect(process().processPool(), *this, sourceURLString, destinationURLString, *frame);
3461 void WebPageProxy::didUpdateHistoryTitle(const String& title, const String& url, uint64_t frameID)
3463 PageClientProtector protector(m_pageClient);
3465 WebFrameProxy* frame = m_process->webFrame(frameID);
3466 MESSAGE_CHECK(frame);
3467 MESSAGE_CHECK(frame->page() == this);
3469 MESSAGE_CHECK_URL(url);
3471 if (m_historyClient) {
3472 if (frame->isMainFrame())
3473 m_historyClient->didUpdateHistoryTitle(*this, title, url);
3475 m_loaderClient->didUpdateHistoryTitle(*this, title, url, *frame);
3476 process().processPool().historyClient().didUpdateHistoryTitle(process().processPool(), *this, title, url, *frame);
3481 void WebPageProxy::createNewPage(uint64_t frameID, const SecurityOriginData& securityOriginData, const ResourceRequest& request, const WindowFeatures& windowFeatures, const NavigationActionData& navigationActionData, uint64_t& newPageID, WebPageCreationParameters& newPageParameters)
3483 WebFrameProxy* frame = m_process->webFrame(frameID);
3484 MESSAGE_CHECK(frame);
3486 auto mainFrameURL = m_mainFrame->url();
3488 RefPtr<WebPageProxy> newPage = m_uiClient->createNewPage(this, frame, securityOriginData, request, windowFeatures, navigationActionData);
3494 newPageID = newPage->pageID();
3495 newPageParameters = newPage->creationParameters();
3497 WebsiteDataStore::cloneSessionData(*this, *newPage);
3498 newPage->m_shouldSuppressAppLinksInNextNavigationPolicyDecision = protocolHostAndPortAreEqual(URL(ParsedURLString, mainFrameURL), request.url());
3501 void WebPageProxy::showPage()
3503 m_uiClient->showPage(this);
3506 void WebPageProxy::fullscreenMayReturnToInline()
3508 m_uiClient->fullscreenMayReturnToInline(this);
3511 void WebPageProxy::didEnterFullscreen()
3513 m_uiClient->didEnterFullscreen(this);
3516 void WebPageProxy::didExitFullscreen()
3518 m_uiClient->didExitFullscreen(this);
3521 void WebPageProxy::closePage(bool stopResponsivenessTimer)
3523 if (stopResponsivenessTimer)
3524 m_process->responsivenessTimer()->stop();
3526 m_pageClient.clearAllEditCommands();
3527 m_uiClient->close(this);
3530 void WebPageProxy::runJavaScriptAlert(uint64_t frameID, const SecurityOriginData& securityOrigin, const String& message, RefPtr<Messages::WebPageProxy::RunJavaScriptAlert::DelayedReply> reply)
3532 WebFrameProxy* frame = m_process->webFrame(frameID);
3533 MESSAGE_CHECK(frame);
3535 // Since runJavaScriptAlert() can spin a nested run loop we need to turn off the responsiveness timer.
3536 m_process->responsivenessTimer()->stop();
3538 m_uiClient->runJavaScriptAlert(this, message, frame, securityOrigin, [reply]{ reply->send(); });
3541 void WebPageProxy::runJavaScriptConfirm(uint64_t frameID, const SecurityOriginData& securityOrigin, const String& message, RefPtr<Messages::WebPageProxy::RunJavaScriptConfirm::DelayedReply> reply)
3543 WebFrameProxy* frame = m_process->webFrame(frameID);
3544 MESSAGE_CHECK(frame);
3546 // Since runJavaScriptConfirm() can spin a nested run loop we need to turn off the responsiveness timer.
3547 m_process->responsivenessTimer()->stop();
3549 m_uiClient->runJavaScriptConfirm(this, message, frame, securityOrigin, [reply](bool result) { reply->send(result); });
3552 void WebPageProxy::runJavaScriptPrompt(uint64_t frameID, const SecurityOriginData& securityOrigin, const String& message, const String& defaultValue, RefPtr<Messages::WebPageProxy::RunJavaScriptPrompt::DelayedReply> reply)
3554 WebFrameProxy* frame = m_process->webFrame(frameID);
3555 MESSAGE_CHECK(frame);
3557 // Since runJavaScriptPrompt() can spin a nested run loop we need to turn off the responsiveness timer.
3558 m_process->responsivenessTimer()->stop();
3560 m_uiClient->runJavaScriptPrompt(this, message, defaultValue, frame, securityOrigin, [reply](const String& result) { reply->send(result); });
3563 void WebPageProxy::setStatusText(const String& text)
3565 m_uiClient->setStatusText(this, text);
3568 void WebPageProxy::mouseDidMoveOverElement(const WebHitTestResultData& hitTestResultData, uint32_t opaqueModifiers, const UserData& userData)
3570 m_lastMouseMoveHitTestResult = API::HitTestResult::create(hitTestResultData);
3572 WebEvent::Modifiers modifiers = static_cast<WebEvent::Modifiers>(opaqueModifiers);
3574 m_uiClient->mouseDidMoveOverElement(this, hitTestResultData, modifiers, m_process->transformHandlesToObjects(userData.object()).get());
3577 void WebPageProxy::didBeginTrackingPotentialLongMousePress(const IntPoint& mouseDownPosition, const WebHitTestResultData& hitTestResultData, const UserData& userData)
3579 m_uiClient->didBeginTrackingPotentialLongMousePress(this, mouseDownPosition, hitTestResultData, m_process->transformHandlesToObjects(userData.object()).get());
3582 void WebPageProxy::didRecognizeLongMousePress(const UserData& userData)
3584 m_uiClient->didRecognizeLongMousePress(this, m_process->transformHandlesToObjects(userData.object()).get());
3587 void WebPageProxy::didCancelTrackingPotentialLongMousePress(const UserData& userData)
3589 m_uiClient->didCancelTrackingPotentialLongMousePress(this, m_process->transformHandlesToObjects(userData.object()).get());
3592 void WebPageProxy::connectionWillOpen(IPC::Connection& connection)
3594 ASSERT(&connection == m_process->connection());
3596 m_webProcessLifetimeTracker.connectionWillOpen(connection);
3599 void WebPageProxy::webProcessWillShutDown()
3601 m_webProcessLifetimeTracker.webProcessWillShutDown();
3604 void WebPageProxy::processDidFinishLaunching()
3606 ASSERT(m_process->state() == WebProcessProxy::State::Running);
3608 if (m_userContentController)
3609 m_process->addWebUserContentControllerProxy(*m_userContentController);
3610 m_process->addVisitedLinkStore(m_visitedLinkStore);
3613 #if ENABLE(NETSCAPE_PLUGIN_API)
3614 void WebPageProxy::unavailablePluginButtonClicked(uint32_t opaquePluginUnavailabilityReason, const String& mimeType, const String& pluginURLString, const String& pluginspageAttributeURLString, const String& frameURLString, const String& pageURLString)
3616 MESSAGE_CHECK_URL(pluginURLString);
3617 MESSAGE_CHECK_URL(pluginspageAttributeURLString);
3618 MESSAGE_CHECK_URL(frameURLString);
3619 MESSAGE_CHECK_URL(pageURLString);
3621 RefPtr<API::Dictionary> pluginInformation;
3622 String newMimeType = mimeType;
3623 PluginModuleInfo plugin = m_process->processPool().pluginInfoStore().findPlugin(newMimeType, URL(URL(), pluginURLString));
3624 pluginInformation = createPluginInformationDictionary(plugin, frameURLString, mimeType, pageURLString, pluginspageAttributeURLString, pluginURLString);
3626 WKPluginUnavailabilityReason pluginUnavailabilityReason = kWKPluginUnavailabilityReasonPluginMissing;
3627 switch (static_cast<RenderEmbeddedObject::PluginUnavailabilityReason>(opaquePluginUnavailabilityReason)) {
3628 case RenderEmbeddedObject::PluginMissing:
3629 pluginUnavailabilityReason = kWKPluginUnavailabilityReasonPluginMissing;
3631 case RenderEmbeddedObject::InsecurePluginVersion:
3632 pluginUnavailabilityReason = kWKPluginUnavailabilityReasonInsecurePluginVersion;
3634 case RenderEmbeddedObject::PluginCrashed:
3635 pluginUnavailabilityReason = kWKPluginUnavailabilityReasonPluginCrashed;
3637 case RenderEmbeddedObject::PluginBlockedByContentSecurityPolicy:
3638 ASSERT_NOT_REACHED();
3641 m_uiClient->unavailablePluginButtonClicked(this, pluginUnavailabilityReason, pluginInformation.get());
3643 #endif // ENABLE(NETSCAPE_PLUGIN_API)
3646 void WebPageProxy::webGLPolicyForURL(const String& url, uint32_t& loadPolicy)
3648 loadPolicy = static_cast<uint32_t>(m_loaderClient->webGLLoadPolicy(*this, url));
3651 void WebPageProxy::resolveWebGLPolicyForURL(const String& url, uint32_t& loadPolicy)
3653 loadPolicy = static_cast<uint32_t>(m_loaderClient->resolveWebGLLoadPolicy(*this, url));
3655 #endif // ENABLE(WEBGL)
3657 void WebPageProxy::setToolbarsAreVisible(bool toolbarsAreVisible)
3659 m_uiClient->setToolbarsAreVisible(this, toolbarsAreVisible);
3662 void WebPageProxy::getToolbarsAreVisible(bool& toolbarsAreVisible)
3664 toolbarsAreVisible = m_uiClient->toolbarsAreVisible(this);
3667 void WebPageProxy::setMenuBarIsVisible(bool menuBarIsVisible)
3669 m_uiClient->setMenuBarIsVisible(this, menuBarIsVisible);
3672 void WebPageProxy::getMenuBarIsVisible(bool& menuBarIsVisible)
3674 menuBarIsVisible = m_uiClient->menuBarIsVisible(this);
3677 void WebPageProxy::setStatusBarIsVisible(bool statusBarIsVisible)
3679 m_uiClient->setStatusBarIsVisible(this, statusBarIsVisible);
3682 void WebPageProxy::getStatusBarIsVisible(bool& statusBarIsVisible)
3684 statusBarIsVisible = m_uiClient->statusBarIsVisible(this);
3687 void WebPageProxy::setIsResizable(bool isResizable)
3689 m_uiClient->setIsResizable(this, isResizable);
3692 void WebPageProxy::getIsResizable(bool& isResizable)
3694 isResizable = m_uiClient->isResizable(this);
3697 void WebPageProxy::setWindowFrame(const FloatRect& newWindowFrame)
3699 m_uiClient->setWindowFrame(this, m_pageClient.convertToDeviceSpace(newWindowFrame));
3702 void WebPageProxy::getWindowFrame(FloatRect& newWindowFrame)
3704 newWindowFrame = m_pageClient.convertToUserSpace(m_uiClient->windowFrame(this));
3707 void WebPageProxy::screenToRootView(const IntPoint& screenPoint, IntPoint& windowPoint)
3709 windowPoint = m_pageClient.screenToRootView(screenPoint);
3712 void WebPageProxy::rootViewToScreen(const IntRect& viewRect, IntRect& result)
3714 result = m_pageClient.rootViewToScreen(viewRect);
3718 void WebPageProxy::accessibilityScreenToRootView(const IntPoint& screenPoint, IntPoint& windowPoint)
3720 windowPoint = m_pageClient.accessibilityScreenToRootView(screenPoint);
3723 void WebPageProxy::rootViewToAccessibilityScreen(const IntRect& viewRect, IntRect& result)
3725 result = m_pageClient.rootViewToAccessibilityScreen(viewRect);
3729 void WebPageProxy::runBeforeUnloadConfirmPanel(const String& message, uint64_t frameID, bool& shouldClose)
3731 WebFrameProxy* frame = m_process->webFrame(frameID);
3732 MESSAGE_CHECK(frame);
3734 // Since runBeforeUnloadConfirmPanel() can spin a nested run loop we need to turn off the responsiveness timer.
3735 m_process->responsivenessTimer()->stop();
3737 shouldClose = m_uiClient->runBeforeUnloadConfirmPanel(this, message, frame);
3740 #if USE(COORDINATED_GRAPHICS_MULTIPROCESS)
3741 void WebPageProxy::pageDidRequestScroll(const IntPoint& point)
3743 m_pageClient.pageDidRequestScroll(point);
3746 void WebPageProxy::pageTransitionViewportReady()
3748 m_pageClient.pageTransitionViewportReady();
3751 void WebPageProxy::didRenderFrame(const WebCore::IntSize& contentsSize, const WebCore::IntRect& coveredRect)
3753 m_pageClient.didRenderFrame(contentsSize, coveredRect);
3756 void WebPageProxy::commitPageTransitionViewport()
3761 process().send(Messages::WebPage::CommitPageTransitionViewport(), m_pageID);
3765 void WebPageProxy::didChangeViewportProperties(const ViewportAttributes& attr)
3767 m_pageClient.didChangeViewportProperties(attr);
3770 void WebPageProxy::pageDidScroll()
3772 m_uiClient->pageDidScroll(this);
3775 void WebPageProxy::runOpenPanel(uint64_t frameID, const FileChooserSettings& settings)
3777 if (m_openPanelResultListener) {
3778 m_openPanelResultListener->invalidate();
3779 m_openPanelResultListener = nullptr;
3782 WebFrameProxy* frame = m_process->webFrame(frameID);
3783 MESSAGE_CHECK(frame);
3785 RefPtr<WebOpenPanelParameters> parameters = WebOpenPanelParameters::create(settings);
3786 m_openPanelResultListener = WebOpenPanelResultListenerProxy::create(this);
3788 // Since runOpenPanel() can spin a nested run loop we need to turn off the responsiveness timer.
3789 m_process->responsivenessTimer()->stop();
3791 if (!m_uiClient->runOpenPanel(this, frame, parameters.get(), m_openPanelResultListener.get())) {
3792 if (!m_pageClient.handleRunOpenPanel(this, frame, parameters.get(), m_openPanelResultListener.get()))
3793 didCancelForOpenPanel();
3797 void WebPageProxy::printFrame(uint64_t frameID)
3799 ASSERT(!m_isPerformingDOMPrintOperation);
3800 m_isPerformingDOMPrintOperation = true;
3802 WebFrameProxy* frame = m_process->webFrame(frameID);
3803 MESSAGE_CHECK(frame);
3805 m_uiClient->printFrame(this, frame);
3807 endPrinting(); // Send a message synchronously while m_isPerformingDOMPrintOperation is still true.
3808 m_isPerformingDOMPrintOperation = false;
3811 void WebPageProxy::printMainFrame()
3813 printFrame(m_mainFrame->frameID());
3816 void WebPageProxy::setMediaVolume(float volume)
3818 if (volume == m_mediaVolume)
3821 m_mediaVolume = volume;
3826 m_process->send(Messages::WebPage::SetMediaVolume(volume), m_pageID);
3829 void WebPageProxy::setMuted(bool muted)
3831 if (m_muted == muted)
3839 m_process->send(Messages::WebPage::SetMuted(muted), m_pageID);
3842 #if ENABLE(MEDIA_SESSION)
3843 void WebPageProxy::handleMediaEvent(MediaEventType eventType)
3848 m_process->send(Messages::WebPage::HandleMediaEvent(eventType), m_pageID);
3851 void WebPageProxy::setVolumeOfMediaElement(double volume, uint64_t elementID)
3856 m_process->send(Messages::WebPage::SetVolumeOfMediaElement(volume, elementID), m_pageID);
3860 void WebPageProxy::setMayStartMediaWhenInWindow(bool mayStartMedia)
3862 if (mayStartMedia == m_mayStartMediaWhenInWindow)
3865 m_mayStartMediaWhenInWindow = mayStartMedia;
3870 process().send(Messages::WebPage::SetMayStartMediaWhenInWindow(mayStartMedia), m_pageID);
3873 void WebPageProxy::handleDownloadRequest(DownloadProxy* download)
3875 m_pageClient.handleDownloadRequest(download);
3878 void WebPageProxy::didChangeContentSize(const IntSize& size)
3880 m_pageClient.didChangeContentSize(size);
3883 #if ENABLE(INPUT_TYPE_COLOR)
3884 void WebPageProxy::showColorPicker(const WebCore::Color& initialColor, const IntRect& elementRect)
3886 #if ENABLE(INPUT_TYPE_COLOR_POPOVER)
3887 // A new popover color well needs to be created (and the previous one destroyed) for
3888 // each activation of a color element.
3889 m_colorPicker = nullptr;
3892 m_colorPicker = m_pageClient.createColorPicker(this, initialColor, elementRect);
3893 m_colorPicker->showColorPicker(initialColor);
3896 void WebPageProxy::setColorPickerColor(const WebCore::Color& color)
3898 ASSERT(m_colorPicker);
3900 m_colorPicker->setSelectedColor(color);
3903 void WebPageProxy::endColorPicker()
3905 ASSERT(m_colorPicker);
3907 m_colorPicker->endPicker();
3910 void WebPageProxy::didChooseColor(const WebCore::Color& color)
3915 m_process->send(Messages::WebPage::DidChooseColor(color), m_pageID);
3918 void WebPageProxy::didEndColorPicker()
3923 if (m_colorPicker) {
3924 m_colorPicker->invalidate();
3925 m_colorPicker = nullptr;
3928 m_process->send(Messages::WebPage::DidEndColorPicker(), m_pageID);
3933 WebInspectorProxy* WebPageProxy::inspector()
3935 if (isClosed() || !isValid())
3937 return m_inspector.get();
3940 #if ENABLE(FULLSCREEN_API)
3941 WebFullScreenManagerProxy* WebPageProxy::fullScreenManager()
3943 return m_fullScreenManager.get();
3948 RefPtr<WebVideoFullscreenManagerProxy> WebPageProxy::videoFullscreenManager()
3950 return m_videoFullscreenManager;
3953 bool WebPageProxy::allowsMediaDocumentInlinePlayback() const
3955 return m_allowsMediaDocumentInlinePlayback;
3958 void WebPageProxy::setAllowsMediaDocumentInlinePlayback(bool allows)
3960 if (m_allowsMediaDocumentInlinePlayback == allows)
3962 m_allowsMediaDocumentInlinePlayback = allows;
3964 m_process->send(Messages::WebPage::SetAllowsMediaDocumentInlinePlayback(allows), m_pageID);
3970 void WebPageProxy::backForwardAddItem(uint64_t itemID)
3972 m_backForwardList->addItem(m_process->webBackForwardItem(itemID));
3975 void WebPageProxy::backForwardGoToItem(uint64_t itemID, SandboxExtension::Handle& sandboxExtensionHandle)
3977 WebBackForwardListItem* item = m_process->webBackForwardItem(itemID);
3981 bool createdExtension = maybeInitializeSandboxExtensionHandle(URL(URL(), item->url()), sandboxExtensionHandle);
3982 if (createdExtension)
3983 m_process->willAcquireUniversalFileReadSandboxExtension();
3984 m_backForwardList->goToItem(item);
3987 void WebPageProxy::backForwardItemAtIndex(int32_t index, uint64_t& itemID)
3989 WebBackForwardListItem* item = m_backForwardList->itemAtIndex(index);
3990 itemID = item ? item->itemID() : 0;
3993 void WebPageProxy::backForwardBackListCount(int32_t& count)
3995 count = m_backForwardList->backListCount();
3998 void WebPageProxy::backForwardForwardListCount(int32_t& count)
4000 count = m_backForwardList->forwardListCount();
4003 void WebPageProxy::compositionWasCanceled(const EditorState& editorState)
4006 m_pageClient.notifyInputContextAboutDiscardedComposition();
4008 editorStateChanged(editorState);
4013 void WebPageProxy::registerEditCommandForUndo(uint64_t commandID, uint32_t editAction)
4015 registerEditCommand(WebEditCommandProxy::create(commandID, static_cast<EditAction>(editAction), this), Undo);
4018 void WebPageProxy::registerInsertionUndoGrouping()
4020 #if USE(INSERTION_UNDO_GROUPING)
4021 m_pageClient.registerInsertionUndoGrouping();
4025 void WebPageProxy::canUndoRedo(uint32_t action, bool& result)
4027 result = m_pageClient.canUndoRedo(static_cast<UndoOrRedo>(action));
4030 void WebPageProxy::executeUndoRedo(uint32_t action, bool& result)
4032 m_pageClient.executeUndoRedo(static_cast<UndoOrRedo>(action));
4036 void WebPageProxy::clearAllEditCommands()
4038 m_pageClient.clearAllEditCommands();
4041 void WebPageProxy::didCountStringMatches(const String& string, uint32_t matchCount)
4043 m_findClient->didCountStringMatches(this, string, matchCount);
4046 void WebPageProxy::didGetImageForFindMatch(const ShareableBitmap::Handle& contentImageHandle, uint32_t matchIndex)
4048 m_findMatchesClient.didGetImageForMatchResult(this, WebImage::create(ShareableBitmap::create(contentImageHandle)).get(), matchIndex);
4051 void WebPageProxy::setTextIndicator(const TextIndicatorData& indicatorData, uint64_t lifetime)
4053 // FIXME: Make TextIndicatorWindow a platform-independent presentational thing ("TextIndicatorPresentation"?).
4055 m_pageClient.setTextIndicator(TextIndicator::create(indicatorData), static_cast<TextIndicatorWindowLifetime>(lifetime));
4057 ASSERT_NOT_REACHED();
4061 void WebPageProxy::clearTextIndicator()
4064 m_pageClient.clearTextIndicator(TextIndicatorWindowDismissalAnimation::FadeOut);
4066 ASSERT_NOT_REACHED();
4070 void WebPageProxy::setTextIndicatorAnimationProgress(float progress)
4073 m_pageClient.setTextIndicatorAnimationProgress(progress);
4075 ASSERT_NOT_REACHED();
4079 void WebPageProxy::didFindString(const String& string, uint32_t matchCount, int32_t matchIndex)
4081 m_findClient->didFindString(this, string, matchCount, matchIndex);
4084 void WebPageProxy::didFindStringMatches(const String& string, const Vector<Vector<WebCore::IntRect>>& matchRects, int32_t firstIndexAfterSelection)
4086 Vector<RefPtr<API::Object>> matches;
4087 matches.reserveInitialCapacity(matchRects.size());
4089 for (const auto& rects : matchRects) {
4090 Vector<RefPtr<API::Object>> apiRects;
4091 apiRects.reserveInitialCapacity(rects.size());
4093 for (const auto& rect : rects)
4094 apiRects.uncheckedAppend(API::Rect::create(toAPI(rect)));
4096 matches.uncheckedAppend(API::Array::create(WTF::move(apiRects)));
4099 m_findMatchesClient.didFindStringMatches(this, string, API::Array::create(WTF::move(matches)).ptr(), firstIndexAfterSelection);
4102 void WebPageProxy::didFailToFindString(const String& string)
4104 m_findClient->didFailToFindString(this, string);
4107 bool WebPageProxy::sendMessage(std::unique_ptr<IPC::MessageEncoder> encoder, unsigned messageSendFlags)
4109 return m_process->sendMessage(WTF::move(encoder), messageSendFlags);
4112 IPC::Connection* WebPageProxy::messageSenderConnection()
4114 return m_process->connection();
4117 uint64_t WebPageProxy::messageSenderDestinationID()
4122 void WebPageProxy::valueChangedForPopupMenu(WebPopupMenuProxy*, int32_t newSelectedIndex)
4124 m_process->send(Messages::WebPage::DidChangeSelectedIndexForActivePopupMenu(newSelectedIndex), m_pageID);
4127 void WebPageProxy::setTextFromItemForPopupMenu(WebPopupMenuProxy*, int32_t index)
4129 m_process->send(Messages::WebPage::SetTextForActivePopupMenu(index), m_pageID);
4132 NativeWebMouseEvent* WebPageProxy::currentlyProcessedMouseDownEvent()
4134 return m_currentlyProcessedMouseDownEvent.get();
4137 void WebPageProxy::postMessageToInjectedBundle(const String& messageName, API::Object* messageBody)
4139 process().send(Messages::WebPage::PostInjectedBundleMessage(messageName, UserData(process().transformObjectsToHandles(messageBody).get())), m_pageID);
4143 void WebPageProxy::failedToShowPopupMenu()
4145 m_process->send(Messages::WebPage::FailedToShowPopupMenu(), m_pageID);
4149 void WebPageProxy::showPopupMenu(const IntRect& rect, uint64_t textDirection, const Vector<WebPopupItem>& items, int32_t selectedIndex, const PlatformPopupMenuData& data)
4151 if (m_activePopupMenu) {
4153 m_uiPopupMenuClient.hidePopupMenu(this);
4155 m_activePopupMenu->hidePopupMenu();
4157 m_activePopupMenu->invalidate();
4158 m_activePopupMenu = nullptr;
4161 m_activePopupMenu = m_pageClient.createPopupMenuProxy(this);
4163 if (!m_activePopupMenu)
4166 // Since showPopupMenu() can spin a nested run loop we need to turn off the responsiveness timer.
4167 m_process->responsivenessTimer()->stop();
4171 m_uiPopupMenuClient.showPopupMenu(this, m_activePopupMenu.get(), rect, static_cast<TextDirection>(textDirection), m_pageScaleFactor, items, selectedIndex);
4174 // Showing a popup menu runs a nested runloop, which can handle messages that cause |this| to get closed.
4175 Ref<WebPageProxy> protect(*this);
4176 m_activePopupMenu->showPopupMenu(rect, static_cast<TextDirection>(textDirection), m_pageScaleFactor, items, data, selectedIndex);
4180 void WebPageProxy::hidePopupMenu()
4182 if (!m_activePopupMenu)
4186 m_uiPopupMenuClient.hidePopupMenu(this);
4188 m_activePopupMenu->hidePopupMenu();
4190 m_activePopupMenu->invalidate();
4191 m_activePopupMenu = nullptr;
4194 #if ENABLE(CONTEXT_MENUS)
4195 void WebPageProxy::showContextMenu(const IntPoint& menuLocation, const ContextMenuContextData& contextMenuContextData, const Vector<WebContextMenuItemData>& proposedItems, const UserData& userData)
4197 // Showing a context menu runs a nested runloop, which can handle messages that cause |this| to get closed.
4198 Ref<WebPageProxy> protect(*this);
4200 internalShowContextMenu(menuLocation, contextMenuContextData, proposedItems, ContextMenuClientEligibility::EligibleForClient, userData);
4202 // No matter the result of internalShowContextMenu, always notify the WebProcess that the menu is hidden so it starts handling mouse events again.
4203 m_process->send(Messages::WebPage::ContextMenuHidden(), m_pageID);
4206 void WebPageProxy::internalShowContextMenu(const IntPoint& menuLocation, const ContextMenuContextData& contextMenuContextData, const Vector<WebContextMenuItemData>& proposedItems, ContextMenuClientEligibility clientEligibility, const UserData& userData)
4208 m_activeContextMenuContextData = contextMenuContextData;
4210 if (!m_contextMenuClient->hideContextMenu(*this) && m_activeContextMenu) {
4211 m_activeContextMenu->hideContextMenu();
4212 m_activeContextMenu = nullptr;
4215 m_activeContextMenu = m_pageClient.createContextMenuProxy(this);
4216 if (!m_activeContextMenu)
4219 // Since showContextMenu() can spin a nested run loop we need to turn off the responsiveness timer.
4220 m_process->responsivenessTimer()->stop();
4222 // Unless this is an image control, give the PageContextMenuClient one last swipe at changing the menu.
4223 bool askClientToChangeMenu = clientEligibility == ContextMenuClientEligibility::EligibleForClient;
4224 #if ENABLE(SERVICE_CONTROLS)
4225 if (contextMenuContextData.controlledImage())
4226 askClientToChangeMenu = false;
4229 Vector<RefPtr<WebContextMenuItem>> proposedAPIItems;
4230 for (auto& item : proposedItems) {
4231 if (item.action() != ContextMenuItemTagShareMenu) {
4232 proposedAPIItems.append(WebContextMenuItem::create(item));
4236 ContextMenuItem coreItem = platformInitializeShareMenuItem(contextMenuContextData);
4237 if (!coreItem.isNull())
4238 proposedAPIItems.append(WebContextMenuItem::create(coreItem));
4241 Vector<RefPtr<WebContextMenuItem>> clientItems;
4242 bool useProposedItems = true;
4244 if (askClientToChangeMenu && m_contextMenuClient->getContextMenuFromProposedMenu(*this, proposedAPIItems, clientItems, contextMenuContextData.webHitTestResultData(), m_process->transformHandlesToObjects(userData.object()).get()))
4245 useProposedItems = false;
4247 const Vector<RefPtr<WebContextMenuItem>>& itemsToShow = useProposedItems ? proposedAPIItems : clientItems;
4248 if (!m_contextMenuClient->showContextMenu(*this, menuLocation, itemsToShow))
4249 m_activeContextMenu->showContextMenu(menuLocation, itemsToShow, contextMenuContextData);
4251 m_contextMenuClient->contextMenuDismissed(*this);
4254 #if !ENABLE(SERVICE_CONTROLS)
4255 ContextMenuItem WebPageProxy::platformInitializeShareMenuItem(const ContextMenuContextData&)
4257 return ContextMenuItem();
4261 void WebPageProxy::contextMenuItemSelected(const WebContextMenuItemData& item)
4263 // Application custom items don't need to round-trip through to WebCore in the WebProcess.
4264 if (item.action() >= ContextMenuItemBaseApplicationTag) {
4265 m_contextMenuClient->customContextMenuItemSelected(*this, item);