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 "APILegacyContextHistoryClient.h"
38 #include "APILoaderClient.h"
39 #include "APINavigation.h"
40 #include "APINavigationAction.h"
41 #include "APINavigationClient.h"
42 #include "APINavigationResponse.h"
43 #include "APIPolicyClient.h"
44 #include "APISecurityOrigin.h"
45 #include "APIUIClient.h"
46 #include "APIURLRequest.h"
47 #include "AuthenticationChallengeProxy.h"
48 #include "AuthenticationDecisionListener.h"
49 #include "DataReference.h"
50 #include "DownloadProxy.h"
51 #include "DrawingAreaProxy.h"
52 #include "DrawingAreaProxyMessages.h"
53 #include "EventDispatcherMessages.h"
55 #include "NativeWebKeyboardEvent.h"
56 #include "NativeWebMouseEvent.h"
57 #include "NativeWebWheelEvent.h"
58 #include "NavigationActionData.h"
59 #include "NotificationPermissionRequest.h"
60 #include "NotificationPermissionRequestManager.h"
61 #include "PageClient.h"
62 #include "PluginInformation.h"
63 #include "PluginProcessManager.h"
64 #include "PrintInfo.h"
65 #include "TextChecker.h"
66 #include "TextCheckerState.h"
67 #include "UserMediaPermissionRequestProxy.h"
68 #include "WKContextPrivate.h"
69 #include "WebBackForwardList.h"
70 #include "WebBackForwardListItem.h"
71 #include "WebCertificateInfo.h"
72 #include "WebContextMenuItem.h"
73 #include "WebContextMenuProxy.h"
74 #include "WebCoreArgumentCoders.h"
75 #include "WebEditCommandProxy.h"
77 #include "WebEventConversion.h"
78 #include "WebFormSubmissionListenerProxy.h"
79 #include "WebFramePolicyListenerProxy.h"
80 #include "WebFullScreenManagerProxy.h"
81 #include "WebFullScreenManagerProxyMessages.h"
83 #include "WebInspectorProxy.h"
84 #include "WebInspectorProxyMessages.h"
85 #include "WebNavigationState.h"
86 #include "WebNotificationManagerProxy.h"
87 #include "WebOpenPanelParameters.h"
88 #include "WebOpenPanelResultListenerProxy.h"
89 #include "WebPageCreationParameters.h"
90 #include "WebPageGroup.h"
91 #include "WebPageGroupData.h"
92 #include "WebPageMessages.h"
93 #include "WebPageProxyMessages.h"
94 #include "WebPopupItem.h"
95 #include "WebPopupMenuProxy.h"
96 #include "WebPreferences.h"
97 #include "WebProcessMessages.h"
98 #include "WebProcessPool.h"
99 #include "WebProcessProxy.h"
100 #include "WebProtectionSpace.h"
101 #include "WebUserContentControllerProxy.h"
102 #include "WebsiteDataStore.h"
103 #include <WebCore/BitmapImage.h>
104 #include <WebCore/DragController.h>
105 #include <WebCore/DragData.h>
106 #include <WebCore/FloatRect.h>
107 #include <WebCore/FocusDirection.h>
108 #include <WebCore/MIMETypeRegistry.h>
109 #include <WebCore/RenderEmbeddedObject.h>
110 #include <WebCore/SerializedCryptoKeyWrap.h>
111 #include <WebCore/TextCheckerClient.h>
112 #include <WebCore/TextIndicator.h>
113 #include <WebCore/URL.h>
114 #include <WebCore/WindowFeatures.h>
116 #include <wtf/NeverDestroyed.h>
117 #include <wtf/RandomNumber.h>
118 #include <wtf/text/StringView.h>
120 #if ENABLE(ASYNC_SCROLLING)
121 #include "RemoteScrollingCoordinatorProxy.h"
124 #if USE(COORDINATED_GRAPHICS_MULTIPROCESS)
125 #include "CoordinatedLayerTreeHostProxyMessages.h"
128 #if ENABLE(VIBRATION)
129 #include "WebVibrationProxy.h"
133 #include <wtf/RefCountedLeakCounter.h>
136 #if ENABLE(NETWORK_PROCESS)
137 #include "NetworkProcessMessages.h"
141 #include "RemoteLayerTreeDrawingAreaProxy.h"
142 #include "RemoteLayerTreeScrollingPerformanceData.h"
143 #include "ViewSnapshotStore.h"
144 #include <WebCore/MachSendRight.h>
145 #include <WebCore/RunLoopObserver.h>
149 #include "WebVideoFullscreenManagerProxy.h"
150 #include "WebVideoFullscreenManagerProxyMessages.h"
154 #include <WebCore/CairoUtilities.h>
157 #if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
158 #include <WebCore/MediaPlaybackTarget.h>
159 #include <WebCore/WebMediaSessionManager.h>
162 // This controls what strategy we use for mouse wheel coalescing.
163 #define MERGE_WHEEL_EVENTS 1
165 #define MESSAGE_CHECK(assertion) MESSAGE_CHECK_BASE(assertion, m_process->connection())
166 #define MESSAGE_CHECK_URL(url) MESSAGE_CHECK_BASE(m_process->checkURLReceivedFromWebProcess(url), m_process->connection())
168 using namespace WebCore;
170 // Represents the number of wheel events we can hold in the queue before we start pushing them preemptively.
171 static const unsigned wheelEventQueueSizeThreshold = 10;
175 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, webPageProxyCounter, ("WebPageProxy"));
177 class ExceededDatabaseQuotaRecords {
178 WTF_MAKE_NONCOPYABLE(ExceededDatabaseQuotaRecords); WTF_MAKE_FAST_ALLOCATED;
179 friend class NeverDestroyed<ExceededDatabaseQuotaRecords>;
183 String originIdentifier;
186 uint64_t currentQuota;
187 uint64_t currentOriginUsage;
188 uint64_t currentDatabaseUsage;
189 uint64_t expectedUsage;
190 RefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply> reply;
193 static ExceededDatabaseQuotaRecords& singleton();
195 std::unique_ptr<Record> createRecord(uint64_t frameID, String originIdentifier,
196 String databaseName, String displayName, uint64_t currentQuota,
197 uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage,
198 PassRefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply>);
200 void add(std::unique_ptr<Record>);
201 bool areBeingProcessed() const { return !!m_currentRecord; }
205 ExceededDatabaseQuotaRecords() { }
206 ~ExceededDatabaseQuotaRecords() { }
208 Deque<std::unique_ptr<Record>> m_records;
209 std::unique_ptr<Record> m_currentRecord;
212 ExceededDatabaseQuotaRecords& ExceededDatabaseQuotaRecords::singleton()
214 static NeverDestroyed<ExceededDatabaseQuotaRecords> records;
218 std::unique_ptr<ExceededDatabaseQuotaRecords::Record> ExceededDatabaseQuotaRecords::createRecord(
219 uint64_t frameID, String originIdentifier, String databaseName, String displayName,
220 uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage,
221 uint64_t expectedUsage, PassRefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply> reply)
223 auto record = std::make_unique<Record>();
224 record->frameID = frameID;
225 record->originIdentifier = originIdentifier;
226 record->databaseName = databaseName;
227 record->displayName = displayName;
228 record->currentQuota = currentQuota;
229 record->currentOriginUsage = currentOriginUsage;
230 record->currentDatabaseUsage = currentDatabaseUsage;
231 record->expectedUsage = expectedUsage;
232 record->reply = reply;
233 return WTF::move(record);
236 void ExceededDatabaseQuotaRecords::add(std::unique_ptr<ExceededDatabaseQuotaRecords::Record> record)
238 m_records.append(WTF::move(record));
241 ExceededDatabaseQuotaRecords::Record* ExceededDatabaseQuotaRecords::next()
243 m_currentRecord = nullptr;
244 if (!m_records.isEmpty())
245 m_currentRecord = m_records.takeFirst();
246 return m_currentRecord.get();
250 static const char* webKeyboardEventTypeString(WebEvent::Type type)
253 case WebEvent::KeyDown:
256 case WebEvent::KeyUp:
259 case WebEvent::RawKeyDown:
266 ASSERT_NOT_REACHED();
270 #endif // !LOG_DISABLED
272 Ref<WebPageProxy> WebPageProxy::create(PageClient& pageClient, WebProcessProxy& process, uint64_t pageID, const WebPageConfiguration& configuration)
274 return adoptRef(*new WebPageProxy(pageClient, process, pageID, configuration));
277 WebPageProxy::WebPageProxy(PageClient& pageClient, WebProcessProxy& process, uint64_t pageID, const WebPageConfiguration& configuration)
278 : m_pageClient(pageClient)
279 , m_loaderClient(std::make_unique<API::LoaderClient>())
280 , m_policyClient(std::make_unique<API::PolicyClient>())
281 , m_formClient(std::make_unique<API::FormClient>())
282 , m_uiClient(std::make_unique<API::UIClient>())
283 , m_findClient(std::make_unique<API::FindClient>())
284 , m_diagnosticLoggingClient(std::make_unique<API::DiagnosticLoggingClient>())
285 #if ENABLE(CONTEXT_MENUS)
286 , m_contextMenuClient(std::make_unique<API::ContextMenuClient>())
288 , m_navigationState(std::make_unique<WebNavigationState>())
290 , m_pageGroup(*configuration.pageGroup)
291 , m_preferences(*configuration.preferences)
292 , m_userContentController(configuration.userContentController)
293 , m_visitedLinkProvider(*configuration.visitedLinkProvider)
294 , m_websiteDataStore(*configuration.websiteDataStore)
295 , m_mainFrame(nullptr)
296 , m_userAgent(standardUserAgent())
297 , m_treatsSHA1CertificatesAsInsecure(configuration.treatsSHA1SignedCertificatesAsInsecure)
299 , m_hasReceivedLayerTreeTransactionAfterDidCommitLoad(true)
300 , m_firstLayerTreeTransactionIdAfterDidCommitLoad(0)
301 , m_deviceOrientation(0)
302 , m_dynamicViewportSizeUpdateWaitingForTarget(false)
303 , m_dynamicViewportSizeUpdateWaitingForLayerTreeCommit(false)
304 , m_dynamicViewportSizeUpdateLayerTreeTransactionID(0)
305 , m_layerTreeTransactionIdAtLastTouchStart(0)
307 , m_geolocationPermissionRequestManager(*this)
308 , m_notificationPermissionRequestManager(*this)
309 , m_userMediaPermissionRequestManager(*this)
310 , m_viewState(ViewState::NoFlags)
311 , m_viewWasEverInWindow(false)
312 , m_backForwardList(WebBackForwardList::create(*this))
313 , m_maintainsInactiveSelection(false)
314 , m_isEditable(false)
315 #if PLATFORM(MAC) && !USE(ASYNC_NSTEXTINPUTCLIENT)
316 , m_temporarilyClosedComposition(false)
318 , m_textZoomFactor(1)
319 , m_pageZoomFactor(1)
320 , m_pageScaleFactor(1)
321 , m_pluginZoomFactor(1)
322 , m_pluginScaleFactor(1)
323 , m_intrinsicDeviceScaleFactor(1)
324 , m_customDeviceScaleFactor(0)
325 , m_topContentInset(0)
326 , m_layerHostingMode(LayerHostingMode::InProcess)
327 , m_drawsBackground(true)
328 , m_drawsTransparentBackground(false)
329 , m_useFixedLayout(false)
330 , m_suppressScrollbarAnimations(false)
331 , m_paginationMode(Pagination::Unpaginated)
332 , m_paginationBehavesLikeColumns(false)
334 , m_gapBetweenPages(0)
337 , m_canRunModal(false)
338 , m_isInPrintingMode(false)
339 , m_isPerformingDOMPrintOperation(false)
340 , m_inDecidePolicyForResponseSync(false)
341 , m_decidePolicyForResponseRequest(0)
342 , m_syncMimeTypePolicyActionIsValid(false)
343 , m_syncMimeTypePolicyAction(PolicyUse)
344 , m_syncMimeTypePolicyDownloadID(0)
345 , m_inDecidePolicyForNavigationAction(false)
346 , m_syncNavigationActionPolicyActionIsValid(false)
347 , m_syncNavigationActionPolicyAction(PolicyUse)
348 , m_syncNavigationActionPolicyDownloadID(0)
349 , m_processingMouseMoveEvent(false)
350 #if ENABLE(TOUCH_EVENTS)
351 , m_isTrackingTouchEvents(false)
354 , m_sessionID(configuration.sessionID)
355 , m_isPageSuspended(false)
356 , m_addsVisitedLinks(true)
357 #if ENABLE(REMOTE_INSPECTOR)
358 , m_allowsRemoteInspection(true)
361 , m_isSmartInsertDeleteEnabled(TextChecker::isSmartInsertDeleteEnabled())
364 , m_backgroundColor(Color::white)
366 , m_spellDocumentTag(0)
367 , m_hasSpellDocumentTag(false)
368 , m_pendingLearnOrIgnoreWordMessageCount(0)
369 , m_mainFrameHasCustomContentProvider(false)
370 #if ENABLE(DRAG_SUPPORT)
371 , m_currentDragOperation(DragOperationNone)
372 , m_currentDragIsOverFileInput(false)
373 , m_currentDragNumberOfFilesToBeAccepted(0)
375 , m_pageLoadState(*this)
376 , m_delegatesScrolling(false)
377 , m_mainFrameHasHorizontalScrollbar(false)
378 , m_mainFrameHasVerticalScrollbar(false)
379 , m_canShortCircuitHorizontalWheelEvents(true)
380 , m_mainFrameIsPinnedToLeftSide(true)
381 , m_mainFrameIsPinnedToRightSide(true)
382 , m_mainFrameIsPinnedToTopSide(true)
383 , m_mainFrameIsPinnedToBottomSide(true)
384 , m_shouldUseImplicitRubberBandControl(false)
385 , m_rubberBandsAtLeft(true)
386 , m_rubberBandsAtRight(true)
387 , m_rubberBandsAtTop(true)
388 , m_rubberBandsAtBottom(true)
389 , m_enableVerticalRubberBanding(true)
390 , m_enableHorizontalRubberBanding(true)
391 , m_backgroundExtendsBeyondPage(false)
392 , m_shouldRecordNavigationSnapshots(false)
393 , m_isShowingNavigationGestureSnapshot(false)
395 , m_renderTreeSize(0)
396 , m_sessionRestorationRenderTreeSize(0)
397 , m_wantsSessionRestorationRenderTreeSizeThresholdEvent(false)
398 , m_hitRenderTreeSizeThreshold(false)
399 , m_shouldSendEventsSynchronously(false)
400 , m_suppressVisibilityUpdates(false)
401 , m_autoSizingShouldExpandToViewHeight(false)
404 , m_mayStartMediaWhenInWindow(true)
405 , m_waitingForDidUpdateViewState(false)
407 , m_scrollPerformanceDataCollectionEnabled(false)
409 , m_scrollPinningBehavior(DoNotPin)
411 , m_configurationPreferenceValues(configuration.preferenceValues)
412 , m_potentiallyChangedViewStateFlags(ViewState::NoFlags)
413 , m_viewStateChangeWantsSynchronousReply(false)
415 m_webProcessLifetimeTracker.addObserver(m_visitedLinkProvider);
416 m_webProcessLifetimeTracker.addObserver(m_websiteDataStore);
418 if (m_process->state() == WebProcessProxy::State::Running) {
419 if (m_userContentController)
420 m_process->addWebUserContentControllerProxy(*m_userContentController);
421 m_process->addVisitedLinkProvider(m_visitedLinkProvider);
425 updateActivityToken();
426 updateProccessSuppressionState();
428 #if HAVE(OUT_OF_PROCESS_LAYER_HOSTING)
429 m_layerHostingMode = m_viewState & ViewState::IsInWindow ? m_pageClient.viewLayerHostingMode() : LayerHostingMode::OutOfProcess;
432 platformInitialize();
435 webPageProxyCounter.increment();
438 WebProcessPool::statistics().wkPageCount++;
440 m_preferences->addPage(*this);
441 m_pageGroup->addPage(this);
443 m_inspector = WebInspectorProxy::create(this);
444 #if ENABLE(FULLSCREEN_API)
445 m_fullScreenManager = WebFullScreenManagerProxy::create(*this, m_pageClient.fullScreenManagerProxyClient());
448 m_videoFullscreenManager = WebVideoFullscreenManagerProxy::create(*this);
450 #if ENABLE(VIBRATION)
451 m_vibration = WebVibrationProxy::create(this);
454 m_process->addMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID, *this);
456 #if ENABLE(NETWORK_PROCESS)
457 if (m_sessionID.isEphemeral())
458 m_process->processPool().sendToNetworkingProcess(Messages::NetworkProcess::EnsurePrivateBrowsingSession(m_sessionID));
462 const CFIndex viewStateChangeRunLoopOrder = (CFIndex)RunLoopObserver::WellKnownRunLoopOrders::CoreAnimationCommit - 1;
463 m_viewStateChangeDispatcher = RunLoopObserver::create(viewStateChangeRunLoopOrder, [this] {
464 this->dispatchViewStateChange();
469 WebPageProxy::~WebPageProxy()
471 ASSERT(m_process->webPage(m_pageID) != this);
473 for (WebPageProxy* page : m_process->pages())
474 ASSERT(page != this);
480 WebProcessPool::statistics().wkPageCount--;
482 if (m_hasSpellDocumentTag)
483 TextChecker::closeSpellDocumentWithTag(m_spellDocumentTag);
485 m_preferences->removePage(*this);
486 m_pageGroup->removePage(this);
489 webPageProxyCounter.decrement();
493 PlatformProcessIdentifier WebPageProxy::processIdentifier() const
498 return m_process->processIdentifier();
501 bool WebPageProxy::isValid() const
503 // A page that has been explicitly closed is never valid.
510 void WebPageProxy::setPreferences(WebPreferences& preferences)
512 if (&preferences == m_preferences.ptr())
515 m_preferences->removePage(*this);
516 m_preferences = preferences;
517 m_preferences->addPage(*this);
519 preferencesDidChange();
522 void WebPageProxy::setHistoryClient(std::unique_ptr<API::HistoryClient> historyClient)
524 m_historyClient = WTF::move(historyClient);
527 void WebPageProxy::setNavigationClient(std::unique_ptr<API::NavigationClient> navigationClient)
529 m_navigationClient = WTF::move(navigationClient);
532 void WebPageProxy::setLoaderClient(std::unique_ptr<API::LoaderClient> loaderClient)
535 m_loaderClient = std::make_unique<API::LoaderClient>();
539 m_loaderClient = WTF::move(loaderClient);
542 void WebPageProxy::setPolicyClient(std::unique_ptr<API::PolicyClient> policyClient)
545 m_policyClient = std::make_unique<API::PolicyClient>();
549 m_policyClient = WTF::move(policyClient);
552 void WebPageProxy::setFormClient(std::unique_ptr<API::FormClient> formClient)
555 m_formClient = std::make_unique<API::FormClient>();
559 m_formClient = WTF::move(formClient);
562 void WebPageProxy::setUIClient(std::unique_ptr<API::UIClient> uiClient)
565 m_uiClient = std::make_unique<API::UIClient>();
569 m_uiClient = WTF::move(uiClient);
574 m_process->send(Messages::WebPage::SetCanRunBeforeUnloadConfirmPanel(m_uiClient->canRunBeforeUnloadConfirmPanel()), m_pageID);
575 setCanRunModal(m_uiClient->canRunModal());
578 void WebPageProxy::setFindClient(std::unique_ptr<API::FindClient> findClient)
581 m_findClient = std::make_unique<API::FindClient>();
585 m_findClient = WTF::move(findClient);
588 void WebPageProxy::initializeFindMatchesClient(const WKPageFindMatchesClientBase* client)
590 m_findMatchesClient.initialize(client);
593 void WebPageProxy::setDiagnosticLoggingClient(std::unique_ptr<API::DiagnosticLoggingClient> diagnosticLoggingClient)
595 if (!diagnosticLoggingClient) {
596 m_diagnosticLoggingClient = std::make_unique<API::DiagnosticLoggingClient>();
600 m_diagnosticLoggingClient = WTF::move(diagnosticLoggingClient);
603 #if ENABLE(CONTEXT_MENUS)
604 void WebPageProxy::setContextMenuClient(std::unique_ptr<API::ContextMenuClient> contextMenuClient)
606 if (!contextMenuClient) {
607 m_contextMenuClient = std::make_unique<API::ContextMenuClient>();
611 m_contextMenuClient = WTF::move(contextMenuClient);
615 void WebPageProxy::setInjectedBundleClient(const WKPageInjectedBundleClientBase* client)
618 m_injectedBundleClient = nullptr;
622 m_injectedBundleClient = std::make_unique<WebPageInjectedBundleClient>();
623 m_injectedBundleClient->initialize(client);
626 void WebPageProxy::handleMessage(IPC::Connection& connection, const String& messageName, const WebKit::UserData& messageBody)
628 auto* webProcessProxy = WebProcessProxy::fromConnection(&connection);
629 if (!webProcessProxy || !m_injectedBundleClient)
631 m_injectedBundleClient->didReceiveMessageFromInjectedBundle(this, messageName, webProcessProxy->transformHandlesToObjects(messageBody.object()).get());
634 void WebPageProxy::handleSynchronousMessage(IPC::Connection& connection, const String& messageName, const UserData& messageBody, UserData& returnUserData)
636 if (!WebProcessProxy::fromConnection(&connection) || !m_injectedBundleClient)
639 RefPtr<API::Object> returnData;
640 m_injectedBundleClient->didReceiveSynchronousMessageFromInjectedBundle(this, messageName, WebProcessProxy::fromConnection(&connection)->transformHandlesToObjects(messageBody.object()).get(), returnData);
641 returnUserData = UserData(WebProcessProxy::fromConnection(&connection)->transformObjectsToHandles(returnData.get()));
645 void WebPageProxy::reattachToWebProcess()
649 ASSERT(m_process->state() == WebProcessProxy::State::Terminated);
652 m_process->removeWebPage(m_pageID);
653 m_process->removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID);
655 if (m_process->processPool().processModel() == ProcessModelSharedSecondaryProcess)
656 m_process = m_process->processPool().ensureSharedWebProcess();
658 m_process = m_process->processPool().createNewWebProcessRespectingProcessCountLimit();
660 ASSERT(m_process->state() != ChildProcessProxy::State::Terminated);
661 if (m_process->state() == ChildProcessProxy::State::Running)
662 processDidFinishLaunching();
663 m_process->addExistingWebPage(this, m_pageID);
664 m_process->addMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID, *this);
667 updateActivityToken();
669 m_inspector = WebInspectorProxy::create(this);
670 #if ENABLE(FULLSCREEN_API)
671 m_fullScreenManager = WebFullScreenManagerProxy::create(*this, m_pageClient.fullScreenManagerProxyClient());
674 m_videoFullscreenManager = WebVideoFullscreenManagerProxy::create(*this);
679 m_pageClient.didRelaunchProcess();
680 m_drawingArea->waitForBackingStoreUpdateOnNextPaint();
683 RefPtr<API::Navigation> WebPageProxy::reattachToWebProcessForReload()
689 reattachToWebProcess();
691 if (!m_backForwardList->currentItem())
694 auto navigation = m_navigationState->createReloadNavigation();
696 // We allow stale content when reloading a WebProcess that's been killed or crashed.
697 m_process->send(Messages::WebPage::GoToBackForwardItem(navigation->navigationID(), m_backForwardList->currentItem()->itemID()), m_pageID);
698 m_process->responsivenessTimer()->start();
700 return WTF::move(navigation);
703 RefPtr<API::Navigation> WebPageProxy::reattachToWebProcessWithItem(WebBackForwardListItem* item)
708 if (item && item != m_backForwardList->currentItem())
709 m_backForwardList->goToItem(item);
712 reattachToWebProcess();
717 auto navigation = m_navigationState->createBackForwardNavigation();
719 m_process->send(Messages::WebPage::GoToBackForwardItem(navigation->navigationID(), item->itemID()), m_pageID);
720 m_process->responsivenessTimer()->start();
722 return WTF::move(navigation);
725 void WebPageProxy::setSessionID(SessionID sessionID)
730 m_sessionID = sessionID;
731 m_process->send(Messages::WebPage::SetSessionID(sessionID), m_pageID);
733 #if ENABLE(NETWORK_PROCESS)
734 if (sessionID.isEphemeral())
735 m_process->processPool().sendToNetworkingProcess(Messages::NetworkProcess::EnsurePrivateBrowsingSession(sessionID));
739 void WebPageProxy::initializeWebPage()
743 BackForwardListItemVector items = m_backForwardList->entries();
744 for (size_t i = 0; i < items.size(); ++i)
745 m_process->registerNewWebBackForwardListItem(items[i].get());
747 m_drawingArea = m_pageClient.createDrawingAreaProxy();
748 ASSERT(m_drawingArea);
750 #if ENABLE(ASYNC_SCROLLING)
751 if (m_drawingArea->type() == DrawingAreaTypeRemoteLayerTree) {
752 m_scrollingCoordinatorProxy = std::make_unique<RemoteScrollingCoordinatorProxy>(*this);
754 // On iOS, main frame scrolls are sent in terms of visible rect updates.
755 m_scrollingCoordinatorProxy->setPropagatesMainFrameScrolls(false);
760 #if ENABLE(INSPECTOR_SERVER)
761 if (m_preferences->developerExtrasEnabled())
762 inspector()->enableRemoteInspection();
765 process().send(Messages::WebProcess::CreateWebPage(m_pageID, creationParameters()), 0);
768 send(Messages::WebPage::SetSmartInsertDeleteEnabled(m_isSmartInsertDeleteEnabled));
772 void WebPageProxy::close()
779 if (m_activePopupMenu)
780 m_activePopupMenu->cancelTracking();
782 #if ENABLE(CONTEXT_MENUS)
783 if (m_activeContextMenu)
784 m_activeContextMenu->cancelTracking();
787 m_backForwardList->pageClosed();
788 m_pageClient.pageClosed();
790 m_process->disconnectFramesFromPage(this);
792 resetState(ResetStateReason::PageInvalidated);
794 m_loaderClient = std::make_unique<API::LoaderClient>();
795 m_policyClient = std::make_unique<API::PolicyClient>();
796 m_formClient = std::make_unique<API::FormClient>();
797 m_uiClient = std::make_unique<API::UIClient>();
799 m_uiPopupMenuClient.initialize(nullptr);
801 m_findClient = std::make_unique<API::FindClient>();
802 m_findMatchesClient.initialize(nullptr);
803 m_diagnosticLoggingClient = std::make_unique<API::DiagnosticLoggingClient>();
804 #if ENABLE(CONTEXT_MENUS)
805 m_contextMenuClient = std::make_unique<API::ContextMenuClient>();
808 m_webProcessLifetimeTracker.pageWasInvalidated();
810 m_process->send(Messages::WebPage::Close(), m_pageID);
811 m_process->removeWebPage(m_pageID);
812 m_process->removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID);
813 m_process->processPool().supplement<WebNotificationManagerProxy>()->clearNotifications(this);
816 bool WebPageProxy::tryClose()
821 m_process->send(Messages::WebPage::TryClose(), m_pageID);
822 m_process->responsivenessTimer()->start();
826 bool WebPageProxy::maybeInitializeSandboxExtensionHandle(const URL& url, SandboxExtension::Handle& sandboxExtensionHandle)
828 if (!url.isLocalFile())
831 if (m_process->hasAssumedReadAccessToURL(url))
834 // Inspector resources are in a directory with assumed access.
835 ASSERT_WITH_SECURITY_IMPLICATION(!WebInspectorProxy::isInspectorPage(*this));
837 SandboxExtension::createHandle("/", SandboxExtension::ReadOnly, sandboxExtensionHandle);
841 RefPtr<API::Navigation> WebPageProxy::loadRequest(const ResourceRequest& request, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy, API::Object* userData)
846 auto navigation = m_navigationState->createLoadRequestNavigation(request);
848 auto transaction = m_pageLoadState.transaction();
850 m_pageLoadState.setPendingAPIRequestURL(transaction, request.url());
853 reattachToWebProcess();
855 SandboxExtension::Handle sandboxExtensionHandle;
856 bool createdExtension = maybeInitializeSandboxExtensionHandle(request.url(), sandboxExtensionHandle);
857 if (createdExtension)
858 m_process->willAcquireUniversalFileReadSandboxExtension();
859 m_process->send(Messages::WebPage::LoadRequest(navigation->navigationID(), request, sandboxExtensionHandle, (uint64_t)shouldOpenExternalURLsPolicy, UserData(process().transformObjectsToHandles(userData).get())), m_pageID);
860 m_process->responsivenessTimer()->start();
862 return WTF::move(navigation);
865 RefPtr<API::Navigation> WebPageProxy::loadFile(const String& fileURLString, const String& resourceDirectoryURLString, API::Object* userData)
871 reattachToWebProcess();
873 URL fileURL = URL(URL(), fileURLString);
874 if (!fileURL.isLocalFile())
877 URL resourceDirectoryURL;
878 if (resourceDirectoryURLString.isNull())
879 resourceDirectoryURL = URL(ParsedURLString, ASCIILiteral("file:///"));
881 resourceDirectoryURL = URL(URL(), resourceDirectoryURLString);
882 if (!resourceDirectoryURL.isLocalFile())
886 auto navigation = m_navigationState->createLoadRequestNavigation(ResourceRequest(fileURL));
888 auto transaction = m_pageLoadState.transaction();
890 m_pageLoadState.setPendingAPIRequestURL(transaction, fileURLString);
892 String resourceDirectoryPath = resourceDirectoryURL.fileSystemPath();
894 SandboxExtension::Handle sandboxExtensionHandle;
895 SandboxExtension::createHandle(resourceDirectoryPath, SandboxExtension::ReadOnly, sandboxExtensionHandle);
896 m_process->assumeReadAccessToBaseURL(resourceDirectoryURL);
897 m_process->send(Messages::WebPage::LoadRequest(navigation->navigationID(), fileURL, sandboxExtensionHandle, (uint64_t)ShouldOpenExternalURLsPolicy::ShouldNotAllow, UserData(process().transformObjectsToHandles(userData).get())), m_pageID);
898 m_process->responsivenessTimer()->start();
900 return WTF::move(navigation);
903 RefPtr<API::Navigation> WebPageProxy::loadData(API::Data* data, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData)
908 auto navigation = m_navigationState->createLoadDataNavigation();
910 auto transaction = m_pageLoadState.transaction();
912 m_pageLoadState.setPendingAPIRequestURL(transaction, !baseURL.isEmpty() ? baseURL : ASCIILiteral("about:blank"));
915 reattachToWebProcess();
917 m_process->assumeReadAccessToBaseURL(baseURL);
918 m_process->send(Messages::WebPage::LoadData(data->dataReference(), MIMEType, encoding, baseURL, UserData(process().transformObjectsToHandles(userData).get())), m_pageID);
919 m_process->responsivenessTimer()->start();
921 return WTF::move(navigation);
924 // FIXME: Get rid of loadHTMLString and just use loadData instead.
925 RefPtr<API::Navigation> WebPageProxy::loadHTMLString(const String& htmlString, const String& baseURL, API::Object* userData)
930 auto navigation = m_navigationState->createLoadDataNavigation();
932 auto transaction = m_pageLoadState.transaction();
934 m_pageLoadState.setPendingAPIRequestURL(transaction, !baseURL.isEmpty() ? baseURL : ASCIILiteral("about:blank"));
937 reattachToWebProcess();
939 m_process->assumeReadAccessToBaseURL(baseURL);
940 m_process->send(Messages::WebPage::LoadHTMLString(navigation->navigationID(), htmlString, baseURL, UserData(process().transformObjectsToHandles(userData).get())), m_pageID);
941 m_process->responsivenessTimer()->start();
943 return WTF::move(navigation);
946 void WebPageProxy::loadAlternateHTMLString(const String& htmlString, const String& baseURL, const String& unreachableURL, API::Object* userData)
952 reattachToWebProcess();
954 auto transaction = m_pageLoadState.transaction();
956 m_pageLoadState.setUnreachableURL(transaction, unreachableURL);
959 m_mainFrame->setUnreachableURL(unreachableURL);
961 m_process->assumeReadAccessToBaseURL(baseURL);
962 m_process->assumeReadAccessToBaseURL(unreachableURL);
963 m_process->send(Messages::WebPage::LoadAlternateHTMLString(htmlString, baseURL, unreachableURL, m_failingProvisionalLoadURL, UserData(process().transformObjectsToHandles(userData).get())), m_pageID);
964 m_process->responsivenessTimer()->start();
967 void WebPageProxy::loadPlainTextString(const String& string, API::Object* userData)
973 reattachToWebProcess();
975 m_process->send(Messages::WebPage::LoadPlainTextString(string, UserData(process().transformObjectsToHandles(userData).get())), m_pageID);
976 m_process->responsivenessTimer()->start();
979 void WebPageProxy::loadWebArchiveData(API::Data* webArchiveData, API::Object* userData)
985 reattachToWebProcess();
987 m_process->send(Messages::WebPage::LoadWebArchiveData(webArchiveData->dataReference(), UserData(process().transformObjectsToHandles(userData).get())), m_pageID);
988 m_process->responsivenessTimer()->start();
991 void WebPageProxy::navigateToPDFLinkWithSimulatedClick(const String& url, IntPoint documentPoint, IntPoint screenPoint)
996 if (WebCore::protocolIsJavaScript(url))
1000 reattachToWebProcess();
1002 m_process->send(Messages::WebPage::NavigateToPDFLinkWithSimulatedClick(url, documentPoint, screenPoint), m_pageID);
1003 m_process->responsivenessTimer()->start();
1006 void WebPageProxy::stopLoading()
1011 m_process->send(Messages::WebPage::StopLoading(), m_pageID);
1012 m_process->responsivenessTimer()->start();
1015 RefPtr<API::Navigation> WebPageProxy::reload(bool reloadFromOrigin)
1017 SandboxExtension::Handle sandboxExtensionHandle;
1019 if (m_backForwardList->currentItem()) {
1020 String url = m_backForwardList->currentItem()->url();
1021 auto transaction = m_pageLoadState.transaction();
1022 m_pageLoadState.setPendingAPIRequestURL(transaction, url);
1024 // We may not have an extension yet if back/forward list was reinstated after a WebProcess crash or a browser relaunch
1025 bool createdExtension = maybeInitializeSandboxExtensionHandle(URL(URL(), url), sandboxExtensionHandle);
1026 if (createdExtension)
1027 m_process->willAcquireUniversalFileReadSandboxExtension();
1031 return reattachToWebProcessForReload();
1033 auto navigation = m_navigationState->createReloadNavigation();
1035 m_process->send(Messages::WebPage::Reload(navigation->navigationID(), reloadFromOrigin, sandboxExtensionHandle), m_pageID);
1036 m_process->responsivenessTimer()->start();
1038 return WTF::move(navigation);
1041 void WebPageProxy::recordNavigationSnapshot()
1043 if (WebBackForwardListItem* item = m_backForwardList->currentItem())
1044 recordNavigationSnapshot(*item);
1047 void WebPageProxy::recordNavigationSnapshot(WebBackForwardListItem& item)
1049 if (!m_shouldRecordNavigationSnapshots)
1053 ViewSnapshotStore::singleton().recordSnapshot(*this, item);
1059 RefPtr<API::Navigation> WebPageProxy::goForward()
1061 WebBackForwardListItem* forwardItem = m_backForwardList->forwardItem();
1065 auto transaction = m_pageLoadState.transaction();
1067 m_pageLoadState.setPendingAPIRequestURL(transaction, forwardItem->url());
1070 return reattachToWebProcessWithItem(forwardItem);
1072 RefPtr<API::Navigation> navigation;
1073 if (!m_backForwardList->currentItem()->itemIsInSameDocument(*forwardItem))
1074 navigation = m_navigationState->createBackForwardNavigation();
1076 m_process->send(Messages::WebPage::GoForward(navigation ? navigation->navigationID() : 0, forwardItem->itemID()), m_pageID);
1077 m_process->responsivenessTimer()->start();
1082 RefPtr<API::Navigation> WebPageProxy::goBack()
1084 WebBackForwardListItem* backItem = m_backForwardList->backItem();
1088 auto transaction = m_pageLoadState.transaction();
1090 m_pageLoadState.setPendingAPIRequestURL(transaction, backItem->url());
1093 return reattachToWebProcessWithItem(backItem);
1095 RefPtr<API::Navigation> navigation;
1096 if (!m_backForwardList->currentItem()->itemIsInSameDocument(*backItem))
1097 navigation = m_navigationState->createBackForwardNavigation();
1099 m_process->send(Messages::WebPage::GoBack(navigation ? navigation->navigationID() : 0, backItem->itemID()), m_pageID);
1100 m_process->responsivenessTimer()->start();
1105 RefPtr<API::Navigation> WebPageProxy::goToBackForwardItem(WebBackForwardListItem* item)
1108 return reattachToWebProcessWithItem(item);
1110 auto transaction = m_pageLoadState.transaction();
1112 m_pageLoadState.setPendingAPIRequestURL(transaction, item->url());
1114 RefPtr<API::Navigation> navigation;
1115 if (!m_backForwardList->currentItem()->itemIsInSameDocument(*item))
1116 navigation = m_navigationState->createBackForwardNavigation();
1118 m_process->send(Messages::WebPage::GoToBackForwardItem(navigation ? navigation->navigationID() : 0, item->itemID()), m_pageID);
1119 m_process->responsivenessTimer()->start();
1124 void WebPageProxy::tryRestoreScrollPosition()
1129 m_process->send(Messages::WebPage::TryRestoreScrollPosition(), m_pageID);
1132 void WebPageProxy::didChangeBackForwardList(WebBackForwardListItem* added, Vector<RefPtr<WebBackForwardListItem>> removed)
1134 m_loaderClient->didChangeBackForwardList(*this, added, WTF::move(removed));
1136 auto transaction = m_pageLoadState.transaction();
1138 m_pageLoadState.setCanGoBack(transaction, m_backForwardList->backItem());
1139 m_pageLoadState.setCanGoForward(transaction, m_backForwardList->forwardItem());
1142 void WebPageProxy::willGoToBackForwardListItem(uint64_t itemID, const UserData& userData)
1144 if (WebBackForwardListItem* item = m_process->webBackForwardItem(itemID))
1145 m_loaderClient->willGoToBackForwardListItem(*this, item, m_process->transformHandlesToObjects(userData.object()).get());
1148 bool WebPageProxy::shouldKeepCurrentBackForwardListItemInList(WebBackForwardListItem* item)
1150 return m_loaderClient->shouldKeepCurrentBackForwardListItemInList(*this, item);
1153 bool WebPageProxy::canShowMIMEType(const String& mimeType)
1155 if (MIMETypeRegistry::canShowMIMEType(mimeType))
1158 #if ENABLE(NETSCAPE_PLUGIN_API)
1159 String newMimeType = mimeType;
1160 PluginModuleInfo plugin = m_process->processPool().pluginInfoStore().findPlugin(newMimeType, URL());
1161 if (!plugin.path.isNull() && m_preferences->pluginsEnabled())
1163 #endif // ENABLE(NETSCAPE_PLUGIN_API)
1166 // On Mac, we can show PDFs.
1167 if (MIMETypeRegistry::isPDFOrPostScriptMIMEType(mimeType) && !WebProcessPool::omitPDFSupport())
1169 #endif // PLATFORM(COCOA)
1174 #if ENABLE(REMOTE_INSPECTOR)
1175 void WebPageProxy::setAllowsRemoteInspection(bool allow)
1177 if (m_allowsRemoteInspection == allow)
1180 m_allowsRemoteInspection = allow;
1183 m_process->send(Messages::WebPage::SetAllowsRemoteInspection(allow), m_pageID);
1187 void WebPageProxy::setDrawsBackground(bool drawsBackground)
1189 if (m_drawsBackground == drawsBackground)
1192 m_drawsBackground = drawsBackground;
1195 m_process->send(Messages::WebPage::SetDrawsBackground(drawsBackground), m_pageID);
1198 void WebPageProxy::setDrawsTransparentBackground(bool drawsTransparentBackground)
1200 if (m_drawsTransparentBackground == drawsTransparentBackground)
1203 m_drawsTransparentBackground = drawsTransparentBackground;
1206 m_process->send(Messages::WebPage::SetDrawsTransparentBackground(drawsTransparentBackground), m_pageID);
1209 void WebPageProxy::setTopContentInset(float contentInset)
1211 if (m_topContentInset == contentInset)
1214 m_topContentInset = contentInset;
1217 m_process->send(Messages::WebPage::SetTopContentInset(contentInset), m_pageID);
1220 void WebPageProxy::setUnderlayColor(const Color& color)
1222 if (m_underlayColor == color)
1225 m_underlayColor = color;
1228 m_process->send(Messages::WebPage::SetUnderlayColor(color), m_pageID);
1231 void WebPageProxy::viewWillStartLiveResize()
1235 #if ENABLE(INPUT_TYPE_COLOR_POPOVER)
1239 m_process->send(Messages::WebPage::ViewWillStartLiveResize(), m_pageID);
1242 void WebPageProxy::viewWillEndLiveResize()
1246 m_process->send(Messages::WebPage::ViewWillEndLiveResize(), m_pageID);
1249 void WebPageProxy::setViewNeedsDisplay(const IntRect& rect)
1251 m_pageClient.setViewNeedsDisplay(rect);
1254 void WebPageProxy::displayView()
1256 m_pageClient.displayView();
1259 bool WebPageProxy::canScrollView()
1261 return m_pageClient.canScrollView();
1264 void WebPageProxy::scrollView(const IntRect& scrollRect, const IntSize& scrollOffset)
1266 m_pageClient.scrollView(scrollRect, scrollOffset);
1269 void WebPageProxy::requestScroll(const FloatPoint& scrollPosition, bool isProgrammaticScroll)
1271 m_pageClient.requestScroll(scrollPosition, isProgrammaticScroll);
1274 void WebPageProxy::setSuppressVisibilityUpdates(bool flag)
1276 if (m_suppressVisibilityUpdates == flag)
1278 m_suppressVisibilityUpdates = flag;
1280 if (!m_suppressVisibilityUpdates) {
1282 m_viewStateChangeDispatcher->schedule();
1284 dispatchViewStateChange();
1289 void WebPageProxy::updateViewState(ViewState::Flags flagsToUpdate)
1291 m_viewState &= ~flagsToUpdate;
1292 if (flagsToUpdate & ViewState::IsFocused && m_pageClient.isViewFocused())
1293 m_viewState |= ViewState::IsFocused;
1294 if (flagsToUpdate & ViewState::WindowIsActive && m_pageClient.isViewWindowActive())
1295 m_viewState |= ViewState::WindowIsActive;
1296 if (flagsToUpdate & ViewState::IsVisible && m_pageClient.isViewVisible())
1297 m_viewState |= ViewState::IsVisible;
1298 if (flagsToUpdate & ViewState::IsVisibleOrOccluded && m_pageClient.isViewVisibleOrOccluded())
1299 m_viewState |= ViewState::IsVisibleOrOccluded;
1300 if (flagsToUpdate & ViewState::IsInWindow && m_pageClient.isViewInWindow()) {
1301 m_viewState |= ViewState::IsInWindow;
1302 m_viewWasEverInWindow = true;
1304 if (flagsToUpdate & ViewState::IsVisuallyIdle && m_pageClient.isVisuallyIdle())
1305 m_viewState |= ViewState::IsVisuallyIdle;
1308 void WebPageProxy::viewStateDidChange(ViewState::Flags mayHaveChanged, bool wantsSynchronousReply, ViewStateChangeDispatchMode dispatchMode)
1310 m_potentiallyChangedViewStateFlags |= mayHaveChanged;
1311 m_viewStateChangeWantsSynchronousReply = m_viewStateChangeWantsSynchronousReply || wantsSynchronousReply;
1313 if (m_suppressVisibilityUpdates && dispatchMode != ViewStateChangeDispatchMode::Immediate)
1317 bool isNewlyInWindow = !isInWindow() && (mayHaveChanged & ViewState::IsInWindow) && m_pageClient.isViewInWindow();
1318 if (dispatchMode == ViewStateChangeDispatchMode::Immediate || isNewlyInWindow) {
1319 dispatchViewStateChange();
1322 m_viewStateChangeDispatcher->schedule();
1324 UNUSED_PARAM(dispatchMode);
1325 dispatchViewStateChange();
1329 void WebPageProxy::viewDidLeaveWindow()
1331 #if ENABLE(INPUT_TYPE_COLOR_POPOVER)
1332 // When leaving the current page, close the popover color well.
1337 // When leaving the current page, close the video fullscreen.
1338 if (m_videoFullscreenManager)
1339 m_videoFullscreenManager->requestHideAndExitFullscreen();
1343 void WebPageProxy::viewDidEnterWindow()
1345 LayerHostingMode layerHostingMode = m_pageClient.viewLayerHostingMode();
1346 if (m_layerHostingMode != layerHostingMode) {
1347 m_layerHostingMode = layerHostingMode;
1348 m_process->send(Messages::WebPage::SetLayerHostingMode(static_cast<unsigned>(layerHostingMode)), m_pageID);
1352 void WebPageProxy::dispatchViewStateChange()
1355 m_viewStateChangeDispatcher->invalidate();
1361 // If the visibility state may have changed, then so may the visually idle & occluded agnostic state.
1362 if (m_potentiallyChangedViewStateFlags & ViewState::IsVisible)
1363 m_potentiallyChangedViewStateFlags |= ViewState::IsVisibleOrOccluded | ViewState::IsVisuallyIdle;
1365 // Record the prior view state, update the flags that may have changed,
1366 // and check which flags have actually changed.
1367 ViewState::Flags previousViewState = m_viewState;
1368 updateViewState(m_potentiallyChangedViewStateFlags);
1369 ViewState::Flags changed = m_viewState ^ previousViewState;
1371 // We always want to wait for the Web process to reply if we've been in-window before and are coming back in-window.
1372 if (m_viewWasEverInWindow && (changed & ViewState::IsInWindow) && isInWindow())
1373 m_viewStateChangeWantsSynchronousReply = true;
1375 // Don't wait synchronously if the view state is not visible. (This matters in particular on iOS, where a hidden page may be suspended.)
1376 if (!(m_viewState & ViewState::IsVisible))
1377 m_viewStateChangeWantsSynchronousReply = false;
1379 if (changed || m_viewStateChangeWantsSynchronousReply || !m_nextViewStateChangeCallbacks.isEmpty())
1380 m_process->send(Messages::WebPage::SetViewState(m_viewState, m_viewStateChangeWantsSynchronousReply, m_nextViewStateChangeCallbacks), m_pageID);
1382 m_nextViewStateChangeCallbacks.clear();
1384 // This must happen after the SetViewState message is sent, to ensure the page visibility event can fire.
1385 updateActivityToken();
1387 // If we've started the responsiveness timer as part of telling the web process to update the backing store
1388 // state, it might not send back a reply (since it won't paint anything if the web page is hidden) so we
1389 // stop the unresponsiveness timer here.
1390 if ((changed & ViewState::IsVisible) && !isViewVisible())
1391 m_process->responsivenessTimer()->stop();
1393 if (changed & ViewState::IsInWindow) {
1395 viewDidEnterWindow();
1397 viewDidLeaveWindow();
1400 updateBackingStoreDiscardableState();
1402 if (m_viewStateChangeWantsSynchronousReply)
1403 waitForDidUpdateViewState();
1405 m_potentiallyChangedViewStateFlags = ViewState::NoFlags;
1406 m_viewStateChangeWantsSynchronousReply = false;
1409 void WebPageProxy::updateActivityToken()
1411 if (m_viewState & ViewState::IsVisuallyIdle)
1412 m_pageIsUserObservableCount = nullptr;
1413 else if (!m_pageIsUserObservableCount)
1414 m_pageIsUserObservableCount = m_process->processPool().userObservablePageCount();
1417 if (!isViewVisible())
1418 m_activityToken = nullptr;
1419 else if (!m_activityToken)
1420 m_activityToken = m_process->throttler().foregroundActivityToken();
1424 void WebPageProxy::updateProccessSuppressionState()
1426 if (m_preferences->pageVisibilityBasedProcessSuppressionEnabled())
1427 m_preventProcessSuppressionCount = nullptr;
1428 else if (!m_preventProcessSuppressionCount)
1429 m_preventProcessSuppressionCount = m_process->processPool().processSuppressionDisabledForPageCount();
1432 void WebPageProxy::layerHostingModeDidChange()
1437 LayerHostingMode layerHostingMode = m_pageClient.viewLayerHostingMode();
1438 if (m_layerHostingMode == layerHostingMode)
1441 m_layerHostingMode = layerHostingMode;
1442 m_process->send(Messages::WebPage::SetLayerHostingMode(static_cast<unsigned>(layerHostingMode)), m_pageID);
1445 void WebPageProxy::waitForDidUpdateViewState()
1450 if (m_process->state() != WebProcessProxy::State::Running)
1453 // If we have previously timed out with no response from the WebProcess, don't block the UIProcess again until it starts responding.
1454 if (m_waitingForDidUpdateViewState)
1458 // Hail Mary check. Should not be possible (dispatchViewStateChange should force async if not visible,
1459 // and if visible we should be holding an assertion) - but we should never block on a suspended process.
1460 if (!m_activityToken) {
1461 ASSERT_NOT_REACHED();
1466 m_waitingForDidUpdateViewState = true;
1468 m_drawingArea->waitForDidUpdateViewState();
1471 IntSize WebPageProxy::viewSize() const
1473 return m_pageClient.viewSize();
1476 void WebPageProxy::setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent& keyboardEvent, std::function<void (CallbackBase::Error)> callbackFunction)
1479 callbackFunction(CallbackBase::Error::OwnerWasInvalidated);
1483 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
1484 m_process->send(Messages::WebPage::SetInitialFocus(forward, isKeyboardEventValid, keyboardEvent, callbackID), m_pageID);
1487 void WebPageProxy::setWindowResizerSize(const IntSize& windowResizerSize)
1491 m_process->send(Messages::WebPage::SetWindowResizerSize(windowResizerSize), m_pageID);
1494 void WebPageProxy::clearSelection()
1498 m_process->send(Messages::WebPage::ClearSelection(), m_pageID);
1501 void WebPageProxy::restoreSelectionInFocusedEditableElement()
1505 m_process->send(Messages::WebPage::RestoreSelectionInFocusedEditableElement(), m_pageID);
1508 void WebPageProxy::validateCommand(const String& commandName, std::function<void (const String&, bool, int32_t, CallbackBase::Error)> callbackFunction)
1511 callbackFunction(String(), false, 0, CallbackBase::Error::Unknown);
1515 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
1516 m_process->send(Messages::WebPage::ValidateCommand(commandName, callbackID), m_pageID);
1519 void WebPageProxy::setMaintainsInactiveSelection(bool newValue)
1521 m_maintainsInactiveSelection = newValue;
1524 void WebPageProxy::executeEditCommand(const String& commandName)
1526 static NeverDestroyed<String> ignoreSpellingCommandName(ASCIILiteral("ignoreSpelling"));
1531 if (commandName == ignoreSpellingCommandName)
1532 ++m_pendingLearnOrIgnoreWordMessageCount;
1534 m_process->send(Messages::WebPage::ExecuteEditCommand(commandName), m_pageID);
1537 void WebPageProxy::setEditable(bool editable)
1539 if (editable == m_isEditable)
1544 m_isEditable = editable;
1545 m_process->send(Messages::WebPage::SetEditable(editable), m_pageID);
1549 void WebPageProxy::didCommitLayerTree(const RemoteLayerTreeTransaction&)
1554 #if USE(COORDINATED_GRAPHICS_MULTIPROCESS)
1555 void WebPageProxy::commitPageTransitionViewport()
1560 process().send(Messages::WebPage::CommitPageTransitionViewport(), m_pageID);
1564 #if ENABLE(DRAG_SUPPORT)
1565 void WebPageProxy::dragEntered(DragData& dragData, const String& dragStorageName)
1567 SandboxExtension::Handle sandboxExtensionHandle;
1568 SandboxExtension::HandleArray sandboxExtensionHandleEmptyArray;
1569 performDragControllerAction(DragControllerActionEntered, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionHandleEmptyArray);
1572 void WebPageProxy::dragUpdated(DragData& dragData, const String& dragStorageName)
1574 SandboxExtension::Handle sandboxExtensionHandle;
1575 SandboxExtension::HandleArray sandboxExtensionHandleEmptyArray;
1576 performDragControllerAction(DragControllerActionUpdated, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionHandleEmptyArray);
1579 void WebPageProxy::dragExited(DragData& dragData, const String& dragStorageName)
1581 SandboxExtension::Handle sandboxExtensionHandle;
1582 SandboxExtension::HandleArray sandboxExtensionHandleEmptyArray;
1583 performDragControllerAction(DragControllerActionExited, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionHandleEmptyArray);
1586 void WebPageProxy::performDragOperation(DragData& dragData, const String& dragStorageName, const SandboxExtension::Handle& sandboxExtensionHandle, const SandboxExtension::HandleArray& sandboxExtensionsForUpload)
1588 performDragControllerAction(DragControllerActionPerformDragOperation, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionsForUpload);
1591 void WebPageProxy::performDragControllerAction(DragControllerAction action, DragData& dragData, const String& dragStorageName, const SandboxExtension::Handle& sandboxExtensionHandle, const SandboxExtension::HandleArray& sandboxExtensionsForUpload)
1596 UNUSED_PARAM(dragStorageName);
1597 UNUSED_PARAM(sandboxExtensionHandle);
1598 UNUSED_PARAM(sandboxExtensionsForUpload);
1600 String url = dragData.asURL();
1602 m_process->assumeReadAccessToBaseURL(url);
1603 m_process->send(Messages::WebPage::PerformDragControllerAction(action, dragData), m_pageID);
1605 m_process->send(Messages::WebPage::PerformDragControllerAction(action, dragData.clientPosition(), dragData.globalPosition(), dragData.draggingSourceOperationMask(), dragStorageName, dragData.flags(), sandboxExtensionHandle, sandboxExtensionsForUpload), m_pageID);
1609 void WebPageProxy::didPerformDragControllerAction(uint64_t dragOperation, bool mouseIsOverFileInput, unsigned numberOfItemsToBeAccepted)
1611 MESSAGE_CHECK(dragOperation <= DragOperationDelete);
1613 m_currentDragOperation = static_cast<DragOperation>(dragOperation);
1614 m_currentDragIsOverFileInput = mouseIsOverFileInput;
1615 m_currentDragNumberOfFilesToBeAccepted = numberOfItemsToBeAccepted;
1619 void WebPageProxy::startDrag(const DragData& dragData, const ShareableBitmap::Handle& dragImageHandle)
1621 RefPtr<ShareableBitmap> dragImage = 0;
1622 if (!dragImageHandle.isNull()) {
1623 dragImage = ShareableBitmap::create(dragImageHandle);
1628 m_pageClient.startDrag(dragData, dragImage.release());
1632 void WebPageProxy::dragEnded(const IntPoint& clientPosition, const IntPoint& globalPosition, uint64_t operation)
1636 m_process->send(Messages::WebPage::DragEnded(clientPosition, globalPosition, operation), m_pageID);
1638 #endif // ENABLE(DRAG_SUPPORT)
1640 void WebPageProxy::handleMouseEvent(const NativeWebMouseEvent& event)
1645 // NOTE: This does not start the responsiveness timer because mouse move should not indicate interaction.
1646 if (event.type() != WebEvent::MouseMove)
1647 m_process->responsivenessTimer()->start();
1649 if (m_processingMouseMoveEvent) {
1650 m_nextMouseMoveEvent = std::make_unique<NativeWebMouseEvent>(event);
1654 m_processingMouseMoveEvent = true;
1657 // <https://bugs.webkit.org/show_bug.cgi?id=57904> We need to keep track of the mouse down event in the case where we
1658 // display a popup menu for select elements. When the user changes the selected item,
1659 // we fake a mouse up event by using this stored down event. This event gets cleared
1660 // when the mouse up message is received from WebProcess.
1661 if (event.type() == WebEvent::MouseDown)
1662 m_currentlyProcessedMouseDownEvent = std::make_unique<NativeWebMouseEvent>(event);
1664 if (m_shouldSendEventsSynchronously) {
1665 bool handled = false;
1666 m_process->sendSync(Messages::WebPage::MouseEventSyncForTesting(event), Messages::WebPage::MouseEventSyncForTesting::Reply(handled), m_pageID);
1667 didReceiveEvent(event.type(), handled);
1669 m_process->send(Messages::WebPage::MouseEvent(event), m_pageID);
1672 #if MERGE_WHEEL_EVENTS
1673 static bool canCoalesce(const WebWheelEvent& a, const WebWheelEvent& b)
1675 if (a.position() != b.position())
1677 if (a.globalPosition() != b.globalPosition())
1679 if (a.modifiers() != b.modifiers())
1681 if (a.granularity() != b.granularity())
1684 if (a.phase() != b.phase())
1686 if (a.momentumPhase() != b.momentumPhase())
1688 if (a.hasPreciseScrollingDeltas() != b.hasPreciseScrollingDeltas())
1695 static WebWheelEvent coalesce(const WebWheelEvent& a, const WebWheelEvent& b)
1697 ASSERT(canCoalesce(a, b));
1699 FloatSize mergedDelta = a.delta() + b.delta();
1700 FloatSize mergedWheelTicks = a.wheelTicks() + b.wheelTicks();
1703 FloatSize mergedUnacceleratedScrollingDelta = a.unacceleratedScrollingDelta() + b.unacceleratedScrollingDelta();
1705 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());
1707 return WebWheelEvent(WebEvent::Wheel, b.position(), b.globalPosition(), mergedDelta, mergedWheelTicks, b.granularity(), b.modifiers(), b.timestamp());
1710 #endif // MERGE_WHEEL_EVENTS
1712 static WebWheelEvent coalescedWheelEvent(Deque<NativeWebWheelEvent>& queue, Vector<NativeWebWheelEvent>& coalescedEvents)
1714 ASSERT(!queue.isEmpty());
1715 ASSERT(coalescedEvents.isEmpty());
1717 #if MERGE_WHEEL_EVENTS
1718 NativeWebWheelEvent firstEvent = queue.takeFirst();
1719 coalescedEvents.append(firstEvent);
1721 WebWheelEvent event = firstEvent;
1722 while (!queue.isEmpty() && canCoalesce(event, queue.first())) {
1723 NativeWebWheelEvent firstEvent = queue.takeFirst();
1724 coalescedEvents.append(firstEvent);
1725 event = coalesce(event, firstEvent);
1730 while (!queue.isEmpty())
1731 coalescedEvents.append(queue.takeFirst());
1732 return coalescedEvents.last();
1736 void WebPageProxy::handleWheelEvent(const NativeWebWheelEvent& event)
1738 #if ENABLE(ASYNC_SCROLLING)
1739 if (m_scrollingCoordinatorProxy && m_scrollingCoordinatorProxy->handleWheelEvent(platform(event)))
1746 if (!m_currentlyProcessedWheelEvents.isEmpty()) {
1747 m_wheelEventQueue.append(event);
1748 if (m_wheelEventQueue.size() < wheelEventQueueSizeThreshold)
1750 // The queue has too many wheel events, so push a new event.
1753 if (!m_wheelEventQueue.isEmpty()) {
1754 processNextQueuedWheelEvent();
1758 auto coalescedWheelEvent = std::make_unique<Vector<NativeWebWheelEvent>>();
1759 coalescedWheelEvent->append(event);
1760 m_currentlyProcessedWheelEvents.append(WTF::move(coalescedWheelEvent));
1761 sendWheelEvent(event);
1764 void WebPageProxy::processNextQueuedWheelEvent()
1766 auto nextCoalescedEvent = std::make_unique<Vector<NativeWebWheelEvent>>();
1767 WebWheelEvent nextWheelEvent = coalescedWheelEvent(m_wheelEventQueue, *nextCoalescedEvent.get());
1768 m_currentlyProcessedWheelEvents.append(WTF::move(nextCoalescedEvent));
1769 sendWheelEvent(nextWheelEvent);
1772 void WebPageProxy::sendWheelEvent(const WebWheelEvent& event)
1774 m_process->responsivenessTimer()->start();
1776 if (m_shouldSendEventsSynchronously) {
1777 bool handled = false;
1778 m_process->sendSync(Messages::WebPage::WheelEventSyncForTesting(event), Messages::WebPage::WheelEventSyncForTesting::Reply(handled), m_pageID);
1779 didReceiveEvent(event.type(), handled);
1784 Messages::EventDispatcher::WheelEvent(
1787 shouldUseImplicitRubberBandControl() ? !m_backForwardList->backItem() : rubberBandsAtLeft(),
1788 shouldUseImplicitRubberBandControl() ? !m_backForwardList->forwardItem() : rubberBandsAtRight(),
1790 rubberBandsAtBottom()
1794 void WebPageProxy::handleKeyboardEvent(const NativeWebKeyboardEvent& event)
1799 LOG(KeyHandling, "WebPageProxy::handleKeyboardEvent: %s", webKeyboardEventTypeString(event.type()));
1801 m_keyEventQueue.append(event);
1803 m_process->responsivenessTimer()->start();
1804 if (m_shouldSendEventsSynchronously) {
1805 bool handled = false;
1806 m_process->sendSync(Messages::WebPage::KeyEventSyncForTesting(event), Messages::WebPage::KeyEventSyncForTesting::Reply(handled), m_pageID);
1807 didReceiveEvent(event.type(), handled);
1808 } else if (m_keyEventQueue.size() == 1) // Otherwise, sent from DidReceiveEvent message handler.
1809 m_process->send(Messages::WebPage::KeyEvent(event), m_pageID);
1812 WebPreferencesStore WebPageProxy::preferencesStore() const
1814 if (m_configurationPreferenceValues.isEmpty())
1815 return m_preferences->store();
1817 WebPreferencesStore store = m_preferences->store();
1818 for (const auto& preference : m_configurationPreferenceValues)
1819 store.m_values.set(preference.key, preference.value);
1824 #if ENABLE(NETSCAPE_PLUGIN_API)
1825 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)
1827 MESSAGE_CHECK_URL(urlString);
1829 newMimeType = mimeType.lower();
1830 pluginLoadPolicy = PluginModuleLoadNormally;
1832 PluginData::AllowedPluginTypes allowedPluginTypes = allowOnlyApplicationPlugins ? PluginData::OnlyApplicationPlugins : PluginData::AllPlugins;
1833 PluginModuleInfo plugin = m_process->processPool().pluginInfoStore().findPlugin(newMimeType, URL(URL(), urlString), allowedPluginTypes);
1835 pluginProcessToken = 0;
1839 pluginLoadPolicy = PluginInfoStore::defaultLoadPolicyForPlugin(plugin);
1842 RefPtr<API::Dictionary> pluginInformation = createPluginInformationDictionary(plugin, frameURLString, String(), pageURLString, String(), String());
1843 if (m_navigationClient)
1844 pluginLoadPolicy = m_navigationClient->decidePolicyForPluginLoad(*this, static_cast<PluginModuleLoadPolicy>(pluginLoadPolicy), pluginInformation.get(), unavailabilityDescription);
1846 pluginLoadPolicy = m_loaderClient->pluginLoadPolicy(*this, static_cast<PluginModuleLoadPolicy>(pluginLoadPolicy), pluginInformation.get(), unavailabilityDescription);
1848 UNUSED_PARAM(frameURLString);
1849 UNUSED_PARAM(pageURLString);
1850 UNUSED_PARAM(unavailabilityDescription);
1853 PluginProcessSandboxPolicy pluginProcessSandboxPolicy = PluginProcessSandboxPolicyNormal;
1854 switch (pluginLoadPolicy) {
1855 case PluginModuleLoadNormally:
1856 pluginProcessSandboxPolicy = PluginProcessSandboxPolicyNormal;
1858 case PluginModuleLoadUnsandboxed:
1859 pluginProcessSandboxPolicy = PluginProcessSandboxPolicyUnsandboxed;
1862 case PluginModuleBlocked:
1863 pluginProcessToken = 0;
1867 pluginProcessToken = PluginProcessManager::singleton().pluginProcessToken(plugin, static_cast<PluginProcessType>(processType), pluginProcessSandboxPolicy);
1870 #endif // ENABLE(NETSCAPE_PLUGIN_API)
1872 #if ENABLE(TOUCH_EVENTS)
1874 bool WebPageProxy::shouldStartTrackingTouchEvents(const WebTouchEvent& touchStartEvent) const
1876 #if ENABLE(ASYNC_SCROLLING)
1877 for (auto& touchPoint : touchStartEvent.touchPoints()) {
1878 if (m_scrollingCoordinatorProxy->isPointInNonFastScrollableRegion(touchPoint.location()))
1884 UNUSED_PARAM(touchStartEvent);
1885 #endif // ENABLE(ASYNC_SCROLLING)
1891 #if ENABLE(IOS_TOUCH_EVENTS)
1892 void WebPageProxy::handleTouchEventSynchronously(const NativeWebTouchEvent& event)
1897 if (event.type() == WebEvent::TouchStart) {
1898 m_isTrackingTouchEvents = shouldStartTrackingTouchEvents(event);
1899 m_layerTreeTransactionIdAtLastTouchStart = downcast<RemoteLayerTreeDrawingAreaProxy>(*drawingArea()).lastCommittedLayerTreeTransactionID();
1902 if (!m_isTrackingTouchEvents)
1905 m_process->responsivenessTimer()->start();
1906 bool handled = false;
1907 m_process->sendSync(Messages::WebPage::TouchEventSync(event), Messages::WebPage::TouchEventSync::Reply(handled), m_pageID);
1908 didReceiveEvent(event.type(), handled);
1909 m_pageClient.doneWithTouchEvent(event, handled);
1910 m_process->responsivenessTimer()->stop();
1912 if (event.allTouchPointsAreReleased())
1913 m_isTrackingTouchEvents = false;
1916 void WebPageProxy::handleTouchEventAsynchronously(const NativeWebTouchEvent& event)
1921 if (!m_isTrackingTouchEvents)
1924 m_process->send(Messages::EventDispatcher::TouchEvent(m_pageID, event), 0);
1926 if (event.allTouchPointsAreReleased())
1927 m_isTrackingTouchEvents = false;
1930 #elif ENABLE(TOUCH_EVENTS)
1931 void WebPageProxy::handleTouchEvent(const NativeWebTouchEvent& event)
1936 if (event.type() == WebEvent::TouchStart)
1937 m_isTrackingTouchEvents = shouldStartTrackingTouchEvents(event);
1939 if (!m_isTrackingTouchEvents)
1942 // If the page is suspended, which should be the case during panning, pinching
1943 // and animation on the page itself (kinetic scrolling, tap to zoom) etc, then
1944 // we do not send any of the events to the page even if is has listeners.
1945 if (!m_isPageSuspended) {
1946 m_touchEventQueue.append(event);
1947 m_process->responsivenessTimer()->start();
1948 if (m_shouldSendEventsSynchronously) {
1949 bool handled = false;
1950 m_process->sendSync(Messages::WebPage::TouchEventSyncForTesting(event), Messages::WebPage::TouchEventSyncForTesting::Reply(handled), m_pageID);
1951 didReceiveEvent(event.type(), handled);
1953 m_process->send(Messages::WebPage::TouchEvent(event), m_pageID);
1955 if (m_touchEventQueue.isEmpty()) {
1956 bool isEventHandled = false;
1957 m_pageClient.doneWithTouchEvent(event, isEventHandled);
1959 // We attach the incoming events to the newest queued event so that all
1960 // the events are delivered in the correct order when the event is dequed.
1961 QueuedTouchEvents& lastEvent = m_touchEventQueue.last();
1962 lastEvent.deferredTouchEvents.append(event);
1966 if (event.allTouchPointsAreReleased())
1967 m_isTrackingTouchEvents = false;
1969 #endif // ENABLE(TOUCH_EVENTS)
1971 void WebPageProxy::scrollBy(ScrollDirection direction, ScrollGranularity granularity)
1976 m_process->send(Messages::WebPage::ScrollBy(direction, granularity), m_pageID);
1979 void WebPageProxy::centerSelectionInVisibleArea()
1984 m_process->send(Messages::WebPage::CenterSelectionInVisibleArea(), m_pageID);
1987 void WebPageProxy::receivedPolicyDecision(PolicyAction action, WebFrameProxy* frame, uint64_t listenerID, API::Navigation* navigation)
1992 auto transaction = m_pageLoadState.transaction();
1994 if (action == PolicyIgnore)
1995 m_pageLoadState.clearPendingAPIRequestURL(transaction);
1997 uint64_t downloadID = 0;
1998 if (action == PolicyDownload) {
1999 // Create a download proxy.
2000 // FIXME: We should ensure that the downloadRequest is never empty.
2001 const ResourceRequest& downloadRequest = m_decidePolicyForResponseRequest ? *m_decidePolicyForResponseRequest : ResourceRequest();
2002 DownloadProxy* download = m_process->processPool().createDownloadProxy(downloadRequest);
2003 downloadID = download->downloadID();
2004 handleDownloadRequest(download);
2007 // If we received a policy decision while in decidePolicyForResponse the decision will
2008 // be sent back to the web process by decidePolicyForResponse.
2009 if (m_inDecidePolicyForResponseSync) {
2010 m_syncMimeTypePolicyActionIsValid = true;
2011 m_syncMimeTypePolicyAction = action;
2012 m_syncMimeTypePolicyDownloadID = downloadID;
2016 // If we received a policy decision while in decidePolicyForNavigationAction the decision will
2017 // be sent back to the web process by decidePolicyForNavigationAction.
2018 if (m_inDecidePolicyForNavigationAction) {
2019 m_syncNavigationActionPolicyActionIsValid = true;
2020 m_syncNavigationActionPolicyAction = action;
2021 m_syncNavigationActionPolicyDownloadID = downloadID;
2025 m_process->send(Messages::WebPage::DidReceivePolicyDecision(frame->frameID(), listenerID, action, navigation ? navigation->navigationID() : 0, downloadID), m_pageID);
2028 void WebPageProxy::setUserAgent(const String& userAgent)
2030 if (m_userAgent == userAgent)
2032 m_userAgent = userAgent;
2036 m_process->send(Messages::WebPage::SetUserAgent(m_userAgent), m_pageID);
2039 void WebPageProxy::setApplicationNameForUserAgent(const String& applicationName)
2041 if (m_applicationNameForUserAgent == applicationName)
2044 m_applicationNameForUserAgent = applicationName;
2045 if (!m_customUserAgent.isEmpty())
2048 setUserAgent(standardUserAgent(m_applicationNameForUserAgent));
2051 void WebPageProxy::setCustomUserAgent(const String& customUserAgent)
2053 if (m_customUserAgent == customUserAgent)
2056 m_customUserAgent = customUserAgent;
2058 if (m_customUserAgent.isEmpty()) {
2059 setUserAgent(standardUserAgent(m_applicationNameForUserAgent));
2063 setUserAgent(m_customUserAgent);
2066 void WebPageProxy::resumeActiveDOMObjectsAndAnimations()
2068 if (!isValid() || !m_isPageSuspended)
2071 m_isPageSuspended = false;
2073 m_process->send(Messages::WebPage::ResumeActiveDOMObjectsAndAnimations(), m_pageID);
2076 void WebPageProxy::suspendActiveDOMObjectsAndAnimations()
2078 if (!isValid() || m_isPageSuspended)
2081 m_isPageSuspended = true;
2083 m_process->send(Messages::WebPage::SuspendActiveDOMObjectsAndAnimations(), m_pageID);
2086 bool WebPageProxy::supportsTextEncoding() const
2088 // FIXME (118840): We should probably only support this for text documents, not all non-image documents.
2089 return m_mainFrame && !m_mainFrame->isDisplayingStandaloneImageDocument();
2092 void WebPageProxy::setCustomTextEncodingName(const String& encodingName)
2094 if (m_customTextEncodingName == encodingName)
2096 m_customTextEncodingName = encodingName;
2100 m_process->send(Messages::WebPage::SetCustomTextEncodingName(encodingName), m_pageID);
2103 void WebPageProxy::terminateProcess()
2105 // requestTermination() is a no-op for launching processes, so we get into an inconsistent state by calling resetStateAfterProcessExited().
2106 // 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.
2107 // See also <https://bugs.webkit.org/show_bug.cgi?id=136012>.
2108 ASSERT(m_process->state() != WebProcessProxy::State::Launching);
2110 // NOTE: This uses a check of m_isValid rather than calling isValid() since
2111 // we want this to run even for pages being closed or that already closed.
2115 m_process->requestTermination();
2116 resetStateAfterProcessExited();
2119 SessionState WebPageProxy::sessionState(const std::function<bool (WebBackForwardListItem&)>& filter) const
2121 SessionState sessionState;
2123 sessionState.backForwardListState = m_backForwardList->backForwardListState(filter);
2125 String provisionalURLString = m_pageLoadState.pendingAPIRequestURL();
2126 if (provisionalURLString.isEmpty())
2127 provisionalURLString = m_pageLoadState.provisionalURL();
2129 if (!provisionalURLString.isEmpty())
2130 sessionState.provisionalURL = URL(URL(), provisionalURLString);
2132 sessionState.renderTreeSize = renderTreeSize();
2133 return sessionState;
2136 RefPtr<API::Navigation> WebPageProxy::restoreFromSessionState(SessionState sessionState, bool navigate)
2138 m_sessionRestorationRenderTreeSize = 0;
2139 m_hitRenderTreeSizeThreshold = false;
2141 bool hasBackForwardList = !!sessionState.backForwardListState.currentIndex;
2143 if (hasBackForwardList) {
2144 m_backForwardList->restoreFromState(WTF::move(sessionState.backForwardListState));
2146 for (const auto& entry : m_backForwardList->entries())
2147 process().registerNewWebBackForwardListItem(entry.get());
2149 process().send(Messages::WebPage::RestoreSession(m_backForwardList->itemStates()), m_pageID);
2152 // FIXME: Navigating should be separate from state restoration.
2154 m_sessionRestorationRenderTreeSize = sessionState.renderTreeSize;
2155 if (!m_sessionRestorationRenderTreeSize)
2156 m_hitRenderTreeSizeThreshold = true; // If we didn't get data on renderTreeSize, just don't fire the milestone.
2158 if (!sessionState.provisionalURL.isNull())
2159 return loadRequest(sessionState.provisionalURL);
2161 if (hasBackForwardList) {
2162 // FIXME: Do we have to null check the back forward list item here?
2163 if (WebBackForwardListItem* item = m_backForwardList->currentItem())
2164 return goToBackForwardItem(item);
2171 bool WebPageProxy::supportsTextZoom() const
2173 // FIXME (118840): This should also return false for standalone media and plug-in documents.
2174 if (!m_mainFrame || m_mainFrame->isDisplayingStandaloneImageDocument())
2180 void WebPageProxy::setTextZoomFactor(double zoomFactor)
2185 if (m_textZoomFactor == zoomFactor)
2188 m_textZoomFactor = zoomFactor;
2189 m_process->send(Messages::WebPage::SetTextZoomFactor(m_textZoomFactor), m_pageID);
2192 void WebPageProxy::setPageZoomFactor(double zoomFactor)
2197 if (m_pageZoomFactor == zoomFactor)
2200 m_pageZoomFactor = zoomFactor;
2201 m_process->send(Messages::WebPage::SetPageZoomFactor(m_pageZoomFactor), m_pageID);
2204 void WebPageProxy::setPageAndTextZoomFactors(double pageZoomFactor, double textZoomFactor)
2209 if (m_pageZoomFactor == pageZoomFactor && m_textZoomFactor == textZoomFactor)
2212 m_pageZoomFactor = pageZoomFactor;
2213 m_textZoomFactor = textZoomFactor;
2214 m_process->send(Messages::WebPage::SetPageAndTextZoomFactors(m_pageZoomFactor, m_textZoomFactor), m_pageID);
2217 double WebPageProxy::pageZoomFactor() const
2219 // Zoom factor for non-PDF pages persists across page loads. We maintain a separate member variable for PDF
2220 // zoom which ensures that we don't use the PDF zoom for a normal page.
2221 if (m_mainFrame && m_mainFrame->isDisplayingPDFDocument())
2222 return m_pluginZoomFactor;
2223 return m_pageZoomFactor;
2226 double WebPageProxy::pageScaleFactor() const
2228 // PDF documents use zoom and scale factors to size themselves appropriately in the window. We store them
2229 // separately but decide which to return based on the main frame.
2230 if (m_mainFrame && m_mainFrame->isDisplayingPDFDocument())
2231 return m_pluginScaleFactor;
2232 return m_pageScaleFactor;
2235 void WebPageProxy::scalePage(double scale, const IntPoint& origin)
2242 m_pageScaleFactor = scale;
2243 m_process->send(Messages::WebPage::ScalePage(scale, origin), m_pageID);
2246 void WebPageProxy::scalePageInViewCoordinates(double scale, const IntPoint& centerInViewCoordinates)
2253 m_pageScaleFactor = scale;
2254 m_process->send(Messages::WebPage::ScalePageInViewCoordinates(scale, centerInViewCoordinates), m_pageID);
2257 void WebPageProxy::scaleView(double scale)
2264 m_viewScaleFactor = scale;
2265 m_process->send(Messages::WebPage::ScaleView(scale), m_pageID);
2269 void WebPageProxy::scaleViewAndUpdateGeometryFenced(double scale, IntSize viewSize, std::function<void (const MachSendRight&, CallbackBase::Error)> callback)
2272 callback(MachSendRight(), CallbackBase::Error::OwnerWasInvalidated);
2276 m_viewScaleFactor = scale;
2278 m_drawingArea->willSendUpdateGeometry();
2279 uint64_t callbackID = m_callbacks.put(WTF::move(callback), m_process->throttler().backgroundActivityToken());
2280 m_process->send(Messages::WebPage::ScaleViewAndUpdateGeometryFenced(scale, viewSize, callbackID), m_pageID);
2284 void WebPageProxy::setIntrinsicDeviceScaleFactor(float scaleFactor)
2286 if (m_intrinsicDeviceScaleFactor == scaleFactor)
2289 m_intrinsicDeviceScaleFactor = scaleFactor;
2292 m_drawingArea->deviceScaleFactorDidChange();
2295 void WebPageProxy::windowScreenDidChange(PlatformDisplayID displayID)
2300 m_process->send(Messages::WebPage::WindowScreenDidChange(displayID), m_pageID);
2303 float WebPageProxy::deviceScaleFactor() const
2305 if (m_customDeviceScaleFactor)
2306 return m_customDeviceScaleFactor;
2307 return m_intrinsicDeviceScaleFactor;
2310 void WebPageProxy::setCustomDeviceScaleFactor(float customScaleFactor)
2315 // FIXME: Remove this once we bump cairo requirements to support HiDPI.
2316 // https://bugs.webkit.org/show_bug.cgi?id=133378
2317 #if USE(CAIRO) && !HAVE(CAIRO_SURFACE_SET_DEVICE_SCALE)
2321 if (m_customDeviceScaleFactor == customScaleFactor)
2324 float oldScaleFactor = deviceScaleFactor();
2326 m_customDeviceScaleFactor = customScaleFactor;
2328 if (deviceScaleFactor() != oldScaleFactor)
2329 m_drawingArea->deviceScaleFactorDidChange();
2332 void WebPageProxy::setUseFixedLayout(bool fixed)
2337 // This check is fine as the value is initialized in the web
2338 // process as part of the creation parameters.
2339 if (fixed == m_useFixedLayout)
2342 m_useFixedLayout = fixed;
2344 m_fixedLayoutSize = IntSize();
2345 m_process->send(Messages::WebPage::SetUseFixedLayout(fixed), m_pageID);
2348 void WebPageProxy::setFixedLayoutSize(const IntSize& size)
2353 if (size == m_fixedLayoutSize)
2356 m_fixedLayoutSize = size;
2357 m_process->send(Messages::WebPage::SetFixedLayoutSize(size), m_pageID);
2360 void WebPageProxy::listenForLayoutMilestones(WebCore::LayoutMilestones milestones)
2365 m_wantsSessionRestorationRenderTreeSizeThresholdEvent = milestones & WebCore::ReachedSessionRestorationRenderTreeSizeThreshold;
2367 m_process->send(Messages::WebPage::ListenForLayoutMilestones(milestones), m_pageID);
2370 void WebPageProxy::setSuppressScrollbarAnimations(bool suppressAnimations)
2375 if (suppressAnimations == m_suppressScrollbarAnimations)
2378 m_suppressScrollbarAnimations = suppressAnimations;
2379 m_process->send(Messages::WebPage::SetSuppressScrollbarAnimations(suppressAnimations), m_pageID);
2382 bool WebPageProxy::rubberBandsAtLeft() const
2384 return m_rubberBandsAtLeft;
2387 void WebPageProxy::setRubberBandsAtLeft(bool rubberBandsAtLeft)
2389 m_rubberBandsAtLeft = rubberBandsAtLeft;
2392 bool WebPageProxy::rubberBandsAtRight() const
2394 return m_rubberBandsAtRight;
2397 void WebPageProxy::setRubberBandsAtRight(bool rubberBandsAtRight)
2399 m_rubberBandsAtRight = rubberBandsAtRight;
2402 bool WebPageProxy::rubberBandsAtTop() const
2404 return m_rubberBandsAtTop;
2407 void WebPageProxy::setRubberBandsAtTop(bool rubberBandsAtTop)
2409 m_rubberBandsAtTop = rubberBandsAtTop;
2412 bool WebPageProxy::rubberBandsAtBottom() const
2414 return m_rubberBandsAtBottom;
2417 void WebPageProxy::setRubberBandsAtBottom(bool rubberBandsAtBottom)
2419 m_rubberBandsAtBottom = rubberBandsAtBottom;
2422 void WebPageProxy::setEnableVerticalRubberBanding(bool enableVerticalRubberBanding)
2424 if (enableVerticalRubberBanding == m_enableVerticalRubberBanding)
2427 m_enableVerticalRubberBanding = enableVerticalRubberBanding;
2431 m_process->send(Messages::WebPage::SetEnableVerticalRubberBanding(enableVerticalRubberBanding), m_pageID);
2434 bool WebPageProxy::verticalRubberBandingIsEnabled() const
2436 return m_enableVerticalRubberBanding;
2439 void WebPageProxy::setEnableHorizontalRubberBanding(bool enableHorizontalRubberBanding)
2441 if (enableHorizontalRubberBanding == m_enableHorizontalRubberBanding)
2444 m_enableHorizontalRubberBanding = enableHorizontalRubberBanding;
2448 m_process->send(Messages::WebPage::SetEnableHorizontalRubberBanding(enableHorizontalRubberBanding), m_pageID);
2451 bool WebPageProxy::horizontalRubberBandingIsEnabled() const
2453 return m_enableHorizontalRubberBanding;
2456 void WebPageProxy::setBackgroundExtendsBeyondPage(bool backgroundExtendsBeyondPage)
2458 if (backgroundExtendsBeyondPage == m_backgroundExtendsBeyondPage)
2461 m_backgroundExtendsBeyondPage = backgroundExtendsBeyondPage;
2465 m_process->send(Messages::WebPage::SetBackgroundExtendsBeyondPage(backgroundExtendsBeyondPage), m_pageID);
2468 bool WebPageProxy::backgroundExtendsBeyondPage() const
2470 return m_backgroundExtendsBeyondPage;
2473 void WebPageProxy::setPaginationMode(WebCore::Pagination::Mode mode)
2475 if (mode == m_paginationMode)
2478 m_paginationMode = mode;
2482 m_process->send(Messages::WebPage::SetPaginationMode(mode), m_pageID);
2485 void WebPageProxy::setPaginationBehavesLikeColumns(bool behavesLikeColumns)
2487 if (behavesLikeColumns == m_paginationBehavesLikeColumns)
2490 m_paginationBehavesLikeColumns = behavesLikeColumns;
2494 m_process->send(Messages::WebPage::SetPaginationBehavesLikeColumns(behavesLikeColumns), m_pageID);
2497 void WebPageProxy::setPageLength(double pageLength)
2499 if (pageLength == m_pageLength)
2502 m_pageLength = pageLength;
2506 m_process->send(Messages::WebPage::SetPageLength(pageLength), m_pageID);
2509 void WebPageProxy::setGapBetweenPages(double gap)
2511 if (gap == m_gapBetweenPages)
2514 m_gapBetweenPages = gap;
2518 m_process->send(Messages::WebPage::SetGapBetweenPages(gap), m_pageID);
2521 void WebPageProxy::pageScaleFactorDidChange(double scaleFactor)
2523 m_pageScaleFactor = scaleFactor;
2526 void WebPageProxy::pluginScaleFactorDidChange(double pluginScaleFactor)
2528 m_pluginScaleFactor = pluginScaleFactor;
2531 void WebPageProxy::pluginZoomFactorDidChange(double pluginZoomFactor)
2533 m_pluginZoomFactor = pluginZoomFactor;
2536 void WebPageProxy::findStringMatches(const String& string, FindOptions options, unsigned maxMatchCount)
2538 if (string.isEmpty()) {
2539 didFindStringMatches(string, Vector<Vector<WebCore::IntRect>> (), 0);
2543 m_process->send(Messages::WebPage::FindStringMatches(string, options, maxMatchCount), m_pageID);
2546 void WebPageProxy::findString(const String& string, FindOptions options, unsigned maxMatchCount)
2548 m_process->send(Messages::WebPage::FindString(string, options, maxMatchCount), m_pageID);
2551 void WebPageProxy::getImageForFindMatch(int32_t matchIndex)
2553 m_process->send(Messages::WebPage::GetImageForFindMatch(matchIndex), m_pageID);
2556 void WebPageProxy::selectFindMatch(int32_t matchIndex)
2558 m_process->send(Messages::WebPage::SelectFindMatch(matchIndex), m_pageID);
2561 void WebPageProxy::hideFindUI()
2563 m_process->send(Messages::WebPage::HideFindUI(), m_pageID);
2566 void WebPageProxy::countStringMatches(const String& string, FindOptions options, unsigned maxMatchCount)
2571 m_process->send(Messages::WebPage::CountStringMatches(string, options, maxMatchCount), m_pageID);
2574 void WebPageProxy::runJavaScriptInMainFrame(const String& script, std::function<void (API::SerializedScriptValue*, CallbackBase::Error)> callbackFunction)
2577 callbackFunction(nullptr, CallbackBase::Error::Unknown);
2581 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2582 m_process->send(Messages::WebPage::RunJavaScriptInMainFrame(script, callbackID), m_pageID);
2585 void WebPageProxy::getRenderTreeExternalRepresentation(std::function<void (const String&, CallbackBase::Error)> callbackFunction)
2588 callbackFunction(String(), CallbackBase::Error::Unknown);
2592 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2593 m_process->send(Messages::WebPage::GetRenderTreeExternalRepresentation(callbackID), m_pageID);
2596 void WebPageProxy::getSourceForFrame(WebFrameProxy* frame, std::function<void (const String&, CallbackBase::Error)> callbackFunction)
2599 callbackFunction(String(), CallbackBase::Error::Unknown);
2603 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2604 m_loadDependentStringCallbackIDs.add(callbackID);
2605 m_process->send(Messages::WebPage::GetSourceForFrame(frame->frameID(), callbackID), m_pageID);
2608 void WebPageProxy::getContentsAsString(std::function<void (const String&, CallbackBase::Error)> callbackFunction)
2611 callbackFunction(String(), CallbackBase::Error::Unknown);
2615 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2616 m_loadDependentStringCallbackIDs.add(callbackID);
2617 m_process->send(Messages::WebPage::GetContentsAsString(callbackID), m_pageID);
2620 void WebPageProxy::getBytecodeProfile(std::function<void (const String&, CallbackBase::Error)> callbackFunction)
2623 callbackFunction(String(), CallbackBase::Error::Unknown);
2627 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2628 m_loadDependentStringCallbackIDs.add(callbackID);
2629 m_process->send(Messages::WebPage::GetBytecodeProfile(callbackID), m_pageID);
2633 void WebPageProxy::getContentsAsMHTMLData(std::function<void (API::Data*, CallbackBase::Error)> callbackFunction, bool useBinaryEncoding)
2636 callbackFunction(nullptr, CallbackBase::Error::Unknown);
2640 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2641 m_process->send(Messages::WebPage::GetContentsAsMHTMLData(callbackID, useBinaryEncoding), m_pageID);
2645 void WebPageProxy::getSelectionOrContentsAsString(std::function<void (const String&, CallbackBase::Error)> callbackFunction)
2648 callbackFunction(String(), CallbackBase::Error::Unknown);
2652 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2653 m_process->send(Messages::WebPage::GetSelectionOrContentsAsString(callbackID), m_pageID);
2656 void WebPageProxy::getSelectionAsWebArchiveData(std::function<void (API::Data*, CallbackBase::Error)> callbackFunction)
2659 callbackFunction(nullptr, CallbackBase::Error::Unknown);
2663 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2664 m_process->send(Messages::WebPage::GetSelectionAsWebArchiveData(callbackID), m_pageID);
2667 void WebPageProxy::getMainResourceDataOfFrame(WebFrameProxy* frame, std::function<void (API::Data*, CallbackBase::Error)> callbackFunction)
2669 if (!isValid() || !frame) {
2670 callbackFunction(nullptr, CallbackBase::Error::Unknown);
2674 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2675 m_process->send(Messages::WebPage::GetMainResourceDataOfFrame(frame->frameID(), callbackID), m_pageID);
2678 void WebPageProxy::getResourceDataFromFrame(WebFrameProxy* frame, API::URL* resourceURL, std::function<void (API::Data*, CallbackBase::Error)> callbackFunction)
2681 callbackFunction(nullptr, CallbackBase::Error::Unknown);
2685 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2686 m_process->send(Messages::WebPage::GetResourceDataFromFrame(frame->frameID(), resourceURL->string(), callbackID), m_pageID);
2689 void WebPageProxy::getWebArchiveOfFrame(WebFrameProxy* frame, std::function<void (API::Data*, CallbackBase::Error)> callbackFunction)
2692 callbackFunction(nullptr, CallbackBase::Error::Unknown);
2696 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2697 m_process->send(Messages::WebPage::GetWebArchiveOfFrame(frame->frameID(), callbackID), m_pageID);
2700 void WebPageProxy::forceRepaint(PassRefPtr<VoidCallback> prpCallback)
2702 RefPtr<VoidCallback> callback = prpCallback;
2704 // FIXME: If the page is invalid we should not call the callback. It'd be better to just return false from forceRepaint.
2705 callback->invalidate(CallbackBase::Error::OwnerWasInvalidated);
2709 uint64_t callbackID = callback->callbackID();
2710 m_callbacks.put(callback);
2711 m_drawingArea->waitForBackingStoreUpdateOnNextPaint();
2712 m_process->send(Messages::WebPage::ForceRepaint(callbackID), m_pageID);
2715 void WebPageProxy::preferencesDidChange()
2720 #if ENABLE(INSPECTOR_SERVER)
2721 if (m_preferences->developerExtrasEnabled())
2722 inspector()->enableRemoteInspection();
2725 updateProccessSuppressionState();
2727 m_pageClient.preferencesDidChange();
2729 // FIXME: It probably makes more sense to send individual preference changes.
2730 // However, WebKitTestRunner depends on getting a preference change notification
2731 // even if nothing changed in UI process, so that overrides get removed.
2733 // Preferences need to be updated during synchronous printing to make "print backgrounds" preference work when toggled from a print dialog checkbox.
2734 m_process->send(Messages::WebPage::PreferencesDidChange(preferencesStore()), m_pageID, m_isPerformingDOMPrintOperation ? IPC::DispatchMessageEvenWhenWaitingForSyncReply : 0);
2737 void WebPageProxy::didCreateMainFrame(uint64_t frameID)
2739 MESSAGE_CHECK(!m_mainFrame);
2740 MESSAGE_CHECK(m_process->canCreateFrame(frameID));
2742 m_mainFrame = WebFrameProxy::create(this, frameID);
2744 // Add the frame to the process wide map.
2745 m_process->frameCreated(frameID, m_mainFrame.get());
2748 void WebPageProxy::didCreateSubframe(uint64_t frameID)
2750 MESSAGE_CHECK(m_mainFrame);
2751 MESSAGE_CHECK(m_process->canCreateFrame(frameID));
2753 RefPtr<WebFrameProxy> subFrame = WebFrameProxy::create(this, frameID);
2755 // Add the frame to the process wide map.
2756 m_process->frameCreated(frameID, subFrame.get());
2759 double WebPageProxy::estimatedProgress() const
2761 return m_pageLoadState.estimatedProgress();
2764 void WebPageProxy::didStartProgress()
2766 auto transaction = m_pageLoadState.transaction();
2767 m_pageLoadState.didStartProgress(transaction);
2769 m_pageLoadState.commitChanges();
2770 m_loaderClient->didStartProgress(*this);
2773 void WebPageProxy::didChangeProgress(double value)
2775 auto transaction = m_pageLoadState.transaction();
2776 m_pageLoadState.didChangeProgress(transaction, value);
2778 m_pageLoadState.commitChanges();
2779 m_loaderClient->didChangeProgress(*this);
2782 void WebPageProxy::didFinishProgress()
2784 auto transaction = m_pageLoadState.transaction();
2785 m_pageLoadState.didFinishProgress(transaction);
2787 m_pageLoadState.commitChanges();
2788 m_loaderClient->didFinishProgress(*this);
2791 void WebPageProxy::setNetworkRequestsInProgress(bool networkRequestsInProgress)
2793 auto transaction = m_pageLoadState.transaction();
2794 m_pageLoadState.setNetworkRequestsInProgress(transaction, networkRequestsInProgress);
2797 void WebPageProxy::didDestroyNavigation(uint64_t navigationID)
2799 // FIXME: Message check the navigationID.
2800 m_navigationState->didDestroyNavigation(navigationID);
2803 void WebPageProxy::didStartProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& url, const String& unreachableURL, const UserData& userData)
2805 auto transaction = m_pageLoadState.transaction();
2807 m_pageLoadState.clearPendingAPIRequestURL(transaction);
2809 WebFrameProxy* frame = m_process->webFrame(frameID);
2810 MESSAGE_CHECK(frame);
2811 MESSAGE_CHECK_URL(url);
2813 // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
2814 RefPtr<API::Navigation> navigation;
2815 if (frame->isMainFrame() && navigationID)
2816 navigation = &navigationState().navigation(navigationID);
2818 if (frame->isMainFrame())
2819 m_pageLoadState.didStartProvisionalLoad(transaction, url, unreachableURL);
2821 frame->setUnreachableURL(unreachableURL);
2822 frame->didStartProvisionalLoad(url);
2824 m_pageLoadState.commitChanges();
2825 if (m_navigationClient) {
2826 if (frame->isMainFrame())
2827 m_navigationClient->didStartProvisionalNavigation(*this, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
2829 m_loaderClient->didStartProvisionalLoadForFrame(*this, *frame, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
2832 void WebPageProxy::didReceiveServerRedirectForProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& url, const UserData& userData)
2834 WebFrameProxy* frame = m_process->webFrame(frameID);
2835 MESSAGE_CHECK(frame);
2836 MESSAGE_CHECK_URL(url);
2838 // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
2839 RefPtr<API::Navigation> navigation;
2840 if (frame->isMainFrame() && navigationID)
2841 navigation = &navigationState().navigation(navigationID);
2843 auto transaction = m_pageLoadState.transaction();
2845 if (frame->isMainFrame())
2846 m_pageLoadState.didReceiveServerRedirectForProvisionalLoad(transaction, url);
2848 frame->didReceiveServerRedirectForProvisionalLoad(url);
2850 m_pageLoadState.commitChanges();
2851 if (m_navigationClient) {
2852 if (frame->isMainFrame())
2853 m_navigationClient->didReceiveServerRedirectForProvisionalNavigation(*this, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
2855 m_loaderClient->didReceiveServerRedirectForProvisionalLoadForFrame(*this, *frame, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
2858 void WebPageProxy::didChangeProvisionalURLForFrame(uint64_t frameID, uint64_t, const String& url)
2860 WebFrameProxy* frame = m_process->webFrame(frameID);
2861 MESSAGE_CHECK(frame);
2862 MESSAGE_CHECK(frame->frameLoadState().state() == FrameLoadState::State::Provisional);
2863 MESSAGE_CHECK_URL(url);
2865 auto transaction = m_pageLoadState.transaction();
2867 // Internally, we handle this the same way we handle a server redirect. There are no client callbacks
2868 // for this, but if this is the main frame, clients may observe a change to the page's URL.
2869 if (frame->isMainFrame())
2870 m_pageLoadState.didReceiveServerRedirectForProvisionalLoad(transaction, url);
2872 frame->didReceiveServerRedirectForProvisionalLoad(url);
2875 void WebPageProxy::didFailProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& provisionalURL, const ResourceError& error, const UserData& userData)
2877 WebFrameProxy* frame = m_process->webFrame(frameID);
2878 MESSAGE_CHECK(frame);
2880 // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
2881 RefPtr<API::Navigation> navigation;
2882 if (frame->isMainFrame() && navigationID)
2883 navigation = navigationState().takeNavigation(navigationID);
2885 auto transaction = m_pageLoadState.transaction();
2887 if (frame->isMainFrame())
2888 m_pageLoadState.didFailProvisionalLoad(transaction);
2890 frame->didFailProvisionalLoad();
2892 m_pageLoadState.commitChanges();
2894 ASSERT(!m_failingProvisionalLoadURL);
2895 m_failingProvisionalLoadURL = provisionalURL;
2897 if (m_navigationClient) {
2898 if (frame->isMainFrame())
2899 m_navigationClient->didFailProvisionalNavigationWithError(*this, *frame, navigation.get(), error, m_process->transformHandlesToObjects(userData.object()).get());
2901 // FIXME: Get the main frame's current navigation.
2902 m_navigationClient->didFailProvisionalLoadInSubframeWithError(*this, *frame, nullptr, error, m_process->transformHandlesToObjects(userData.object()).get());
2905 m_loaderClient->didFailProvisionalLoadWithErrorForFrame(*this, *frame, navigation.get(), error, m_process->transformHandlesToObjects(userData.object()).get());
2907 m_failingProvisionalLoadURL = { };
2910 void WebPageProxy::clearLoadDependentCallbacks()
2912 Vector<uint64_t> callbackIDsCopy;
2913 copyToVector(m_loadDependentStringCallbackIDs, callbackIDsCopy);
2914 m_loadDependentStringCallbackIDs.clear();
2916 for (size_t i = 0; i < callbackIDsCopy.size(); ++i) {
2917 auto callback = m_callbacks.take<StringCallback>(callbackIDsCopy[i]);
2919 callback->invalidate();
2923 void WebPageProxy::didCommitLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& mimeType, bool frameHasCustomContentProvider, uint32_t opaqueFrameLoadType, const WebCore::CertificateInfo& certificateInfo, const UserData& userData)
2925 WebFrameProxy* frame = m_process->webFrame(frameID);
2926 MESSAGE_CHECK(frame);
2928 // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
2929 RefPtr<API::Navigation> navigation;
2930 if (frame->isMainFrame() && navigationID)
2931 navigation = &navigationState().navigation(navigationID);
2934 if (frame->isMainFrame()) {
2935 m_hasReceivedLayerTreeTransactionAfterDidCommitLoad = false;
2936 m_firstLayerTreeTransactionIdAfterDidCommitLoad = downcast<RemoteLayerTreeDrawingAreaProxy>(*drawingArea()).nextLayerTreeTransactionID();
2940 auto transaction = m_pageLoadState.transaction();
2942 if (frame->isMainFrame()) {
2943 bool hasInsecureCertificateChain = m_treatsSHA1CertificatesAsInsecure && certificateInfo.containsNonRootSHA1SignedCertificate();
2944 m_pageLoadState.didCommitLoad(transaction, hasInsecureCertificateChain);
2948 // FIXME (bug 59111): didCommitLoadForFrame comes too late when restoring a page from b/f cache, making us disable secure event mode in password fields.
2949 // FIXME: A load going on in one frame shouldn't affect text editing in other frames on the page.
2950 m_pageClient.resetSecureInputState();
2951 m_pageClient.dismissContentRelativeChildWindows();
2954 clearLoadDependentCallbacks();
2956 frame->didCommitLoad(mimeType, certificateInfo);
2958 if (frame->isMainFrame()) {
2959 m_mainFrameHasCustomContentProvider = frameHasCustomContentProvider;
2961 if (m_mainFrameHasCustomContentProvider) {
2962 // Always assume that the main frame is pinned here, since the custom representation view will handle
2963 // any wheel events and dispatch them to the WKView when necessary.
2964 m_mainFrameIsPinnedToLeftSide = true;
2965 m_mainFrameIsPinnedToRightSide = true;
2966 m_mainFrameIsPinnedToTopSide = true;
2967 m_mainFrameIsPinnedToBottomSide = true;
2969 m_uiClient->pinnedStateDidChange(*this);
2971 m_pageClient.didCommitLoadForMainFrame(mimeType, frameHasCustomContentProvider);
2974 // Even if WebPage has the default pageScaleFactor (and therefore doesn't reset it),
2975 // WebPageProxy's cache of the value can get out of sync (e.g. in the case where a
2976 // plugin is handling page scaling itself) so we should reset it to the default
2977 // for standard main frame loads.
2978 if (frame->isMainFrame() && static_cast<FrameLoadType>(opaqueFrameLoadType) == FrameLoadType::Standard) {
2979 m_pageScaleFactor = 1;
2980 m_pluginScaleFactor = 1;
2983 m_pageLoadState.commitChanges();
2984 if (m_navigationClient) {
2985 if (frame->isMainFrame())
2986 m_navigationClient->didCommitNavigation(*this, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
2988 m_loaderClient->didCommitLoadForFrame(*this, *frame, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
2991 void WebPageProxy::didFinishDocumentLoadForFrame(uint64_t frameID, uint64_t navigationID, const UserData& userData)
2993 WebFrameProxy* frame = m_process->webFrame(frameID);
2994 MESSAGE_CHECK(frame);
2996 // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
2997 RefPtr<API::Navigation> navigation;
2998 if (frame->isMainFrame() && navigationID)
2999 navigation = &navigationState().navigation(navigationID);
3001 if (m_navigationClient) {
3002 if (frame->isMainFrame())
3003 m_navigationClient->didFinishDocumentLoad(*this, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
3005 m_loaderClient->didFinishDocumentLoadForFrame(*this, *frame, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
3008 void WebPageProxy::didFinishLoadForFrame(uint64_t frameID, uint64_t navigationID, const UserData& userData)
3010 WebFrameProxy* frame = m_process->webFrame(frameID);
3011 MESSAGE_CHECK(frame);
3013 // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
3014 RefPtr<API::Navigation> navigation;
3015 if (frame->isMainFrame() && navigationID)
3016 navigation = &navigationState().navigation(navigationID);
3018 auto transaction = m_pageLoadState.transaction();
3020 bool isMainFrame = frame->isMainFrame();
3022 m_pageLoadState.didFinishLoad(transaction);
3024 frame->didFinishLoad();
3026 m_pageLoadState.commitChanges();
3027 if (m_navigationClient) {
3029 m_navigationClient->didFinishNavigation(*this, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
3031 m_loaderClient->didFinishLoadForFrame(*this, *frame, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
3034 m_pageClient.didFinishLoadForMainFrame();
3037 void WebPageProxy::didFailLoadForFrame(uint64_t frameID, uint64_t navigationID, const ResourceError& error, const UserData& userData)
3039 WebFrameProxy* frame = m_process->webFrame(frameID);
3040 MESSAGE_CHECK(frame);
3042 // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
3043 RefPtr<API::Navigation> navigation;
3044 if (frame->isMainFrame() && navigationID)
3045 navigation = &navigationState().navigation(navigationID);
3047 clearLoadDependentCallbacks();
3049 auto transaction = m_pageLoadState.transaction();
3051 if (frame->isMainFrame())
3052 m_pageLoadState.didFailLoad(transaction);
3054 frame->didFailLoad();
3056 m_pageLoadState.commitChanges();
3057 if (m_navigationClient) {
3058 if (frame->isMainFrame())
3059 m_navigationClient->didFailNavigationWithError(*this, *frame, navigation.get(), error, m_process->transformHandlesToObjects(userData.object()).get());
3061 m_loaderClient->didFailLoadWithErrorForFrame(*this, *frame, navigation.get(), error, m_process->transformHandlesToObjects(userData.object()).get());
3063 // Notify the PageClient that the main frame finished loading. The WebView / GestureController need to know the load has
3064 // finished (e.g. to clear the back swipe snapshot).
3065 if (frame->isMainFrame())
3066 m_pageClient.didFinishLoadForMainFrame();
3069 void WebPageProxy::didSameDocumentNavigationForFrame(uint64_t frameID, uint64_t navigationID, uint32_t opaqueSameDocumentNavigationType, const String& url, const UserData& userData)
3071 WebFrameProxy* frame = m_process->webFrame(frameID);
3072 MESSAGE_CHECK(frame);
3073 MESSAGE_CHECK_URL(url);
3075 // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
3076 RefPtr<API::Navigation> navigation;
3077 if (frame->isMainFrame() && navigationID)
3078 navigation = &navigationState().navigation(navigationID);
3080 auto transaction = m_pageLoadState.transaction();
3082 bool isMainFrame = frame->isMainFrame();
3084 m_pageLoadState.didSameDocumentNavigation(transaction, url);
3086 m_pageLoadState.clearPendingAPIRequestURL(transaction);
3087 frame->didSameDocumentNavigation(url);
3089 m_pageLoadState.commitChanges();
3091 SameDocumentNavigationType navigationType = static_cast<SameDocumentNavigationType>(opaqueSameDocumentNavigationType);
3092 if (m_navigationClient) {
3094 m_navigationClient->didSameDocumentNavigation(*this, navigation.get(), navigationType, m_process->transformHandlesToObjects(userData.object()).get());
3096 m_loaderClient->didSameDocumentNavigationForFrame(*this, *frame, navigation.get(), navigationType, m_process->transformHandlesToObjects(userData.object()).get());
3099 m_pageClient.didSameDocumentNavigationForMainFrame(navigationType);
3102 void WebPageProxy::didReceiveTitleForFrame(uint64_t frameID, const String& title, const UserData& userData)
3104 WebFrameProxy* frame = m_process->webFrame(frameID);
3105 MESSAGE_CHECK(frame);
3107 auto transaction = m_pageLoadState.transaction();
3109 if (frame->isMainFrame())
3110 m_pageLoadState.setTitle(transaction, title);
3112 frame->didChangeTitle(title);
3114 m_pageLoadState.commitChanges();
3115 m_loaderClient->didReceiveTitleForFrame(*this, title, *frame, m_process->transformHandlesToObjects(userData.object()).get());
3118 void WebPageProxy::didFirstLayoutForFrame(uint64_t frameID, const UserData& userData)
3120 WebFrameProxy* frame = m_process->webFrame(frameID);
3121 MESSAGE_CHECK(frame);
3123 m_loaderClient->didFirstLayoutForFrame(*this, *frame, m_process->transformHandlesToObjects(userData.object()).get());
3126 void WebPageProxy::didFirstVisuallyNonEmptyLayoutForFrame(uint64_t frameID, const UserData& userData)
3128 WebFrameProxy* frame = m_process->webFrame(frameID);
3129 MESSAGE_CHECK(frame);
3131 m_loaderClient->didFirstVisuallyNonEmptyLayoutForFrame(*this, *frame, m_process->transformHandlesToObjects(userData.object()).get());
3133 if (frame->isMainFrame())
3134 m_pageClient.didFirstVisuallyNonEmptyLayoutForMainFrame();
3137 void WebPageProxy::didLayoutForCustomContentProvider()
3139 LayoutMilestones milestones = DidFirstLayout | DidFirstVisuallyNonEmptyLayout | DidHitRelevantRepaintedObjectsAreaThreshold;
3140 if (m_navigationClient)
3141 m_navigationClient->renderingProgressDidChange(*this, milestones, nullptr);
3143 m_loaderClient->didLayout(*this, milestones, nullptr);
3146 void WebPageProxy::didLayout(uint32_t layoutMilestones, const UserData& userData)
3148 if (m_navigationClient)
3149 m_navigationClient->renderingProgressDidChange(*this, static_cast<LayoutMilestones>(layoutMilestones), m_process->transformHandlesToObjects(userData.object()).get());
3151 m_loaderClient->didLayout(*this, static_cast<LayoutMilestones>(layoutMilestones), m_process->transformHandlesToObjects(userData.object()).get());
3154 void WebPageProxy::didRemoveFrameFromHierarchy(uint64_t frameID, const UserData& userData)
3156 WebFrameProxy* frame = m_process->webFrame(frameID);
3157 MESSAGE_CHECK(frame);
3159 m_loaderClient->didRemoveFrameFromHierarchy(*this, *frame, m_process->transformHandlesToObjects(userData.object()).get());
3162 void WebPageProxy::didDisplayInsecureContentForFrame(uint64_t frameID, const UserData& userData)
3164 WebFrameProxy* frame = m_process->webFrame(frameID);
3165 MESSAGE_CHECK(frame);
3167 auto transaction = m_pageLoadState.transaction();
3168 m_pageLoadState.didDisplayOrRunInsecureContent(transaction);
3170 m_pageLoadState.commitChanges();
3171 m_loaderClient->didDisplayInsecureContentForFrame(*this, *frame, m_process->transformHandlesToObjects(userData.object()).get());
3174 void WebPageProxy::didRunInsecureContentForFrame(uint64_t frameID, const UserData& userData)
3176 WebFrameProxy* frame = m_process->webFrame(frameID);
3177 MESSAGE_CHECK(frame);
3179 auto transaction = m_pageLoadState.transaction();
3180 m_pageLoadState.didDisplayOrRunInsecureContent(transaction);
3182 m_pageLoadState.commitChanges();
3183 m_loaderClient->didRunInsecureContentForFrame(*this, *frame, m_process->transformHandlesToObjects(userData.object()).get());
3186 void WebPageProxy::didDetectXSSForFrame(uint64_t frameID, const UserData& userData)
3188 WebFrameProxy* frame = m_process->webFrame(frameID);
3189 MESSAGE_CHECK(frame);
3191 m_loaderClient->didDetectXSSForFrame(*this, *frame, m_process->transformHandlesToObjects(userData.object()).get());
3194 void WebPageProxy::frameDidBecomeFrameSet(uint64_t frameID, bool value)
3196 WebFrameProxy* frame = m_process->webFrame(frameID);
3197 MESSAGE_CHECK(frame);
3199 frame->setIsFrameSet(value);
3200 if (frame->isMainFrame())
3201 m_frameSetLargestFrame = value ? m_mainFrame : 0;
3204 void WebPageProxy::decidePolicyForNavigationAction(uint64_t frameID, uint64_t navigationID, const NavigationActionData& navigationActionData, uint64_t originatingFrameID, const WebCore::ResourceRequest& originalRequest, const ResourceRequest& request, uint64_t listenerID, const UserData& userData, bool& receivedPolicyAction, uint64_t& newNavigationID, uint64_t& policyAction, uint64_t& downloadID)
3206 auto transaction = m_pageLoadState.transaction();
3208 if (request.url() != m_pageLoadState.pendingAPIRequestURL())
3209 m_pageLoadState.clearPendingAPIRequestURL(transaction);
3211 WebFrameProxy* frame = m_process->webFrame(frameID);
3212 MESSAGE_CHECK(frame);
3213 MESSAGE_CHECK_URL(request.url());
3214 MESSAGE_CHECK_URL(originalRequest.url());
3216 WebFrameProxy* originatingFrame = m_process->webFrame(originatingFrameID);
3218 Ref<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
3219 if (!navigationID && frame->isMainFrame()) {
3220 auto navigation = m_navigationState->createLoadRequestNavigation(request);
3221 newNavigationID = navigation->navigationID();
3222 listener->setNavigation(WTF::move(navigation));
3225 #if ENABLE(CONTENT_FILTERING)
3226 if (frame->didHandleContentFilterUnblockNavigation(request)) {
3227 receivedPolicyAction = true;
3228 policyAction = PolicyIgnore;
3233 ASSERT(!m_inDecidePolicyForNavigationAction);
3235 m_inDecidePolicyForNavigationAction = true;
3236 m_syncNavigationActionPolicyActionIsValid = false;
3238 if (m_navigationClient) {
3239 RefPtr<API::FrameInfo> destinationFrameInfo;
3240 RefPtr<API::FrameInfo> sourceFrameInfo;
3243 destinationFrameInfo = API::FrameInfo::create(*frame);
3245 if (originatingFrame == frame)
3246 sourceFrameInfo = destinationFrameInfo;
3247 else if (originatingFrame)
3248 sourceFrameInfo = API::FrameInfo::create(*originatingFrame);
3250 auto navigationAction = API::NavigationAction::create(navigationActionData, sourceFrameInfo.get(), destinationFrameInfo.get(), request, originalRequest.url());
3252 m_navigationClient->decidePolicyForNavigationAction(*this, navigationAction.get(), WTF::move(listener), m_process->transformHandlesToObjects(userData.object()).get());
3254 m_policyClient->decidePolicyForNavigationAction(*this, frame, navigationActionData, originatingFrame, originalRequest, request, WTF::move(listener), m_process->transformHandlesToObjects(userData.object()).get());
3256 m_inDecidePolicyForNavigationAction = false;
3258 // Check if we received a policy decision already. If we did, we can just pass it back.
3259 receivedPolicyAction = m_syncNavigationActionPolicyActionIsValid;
3260 if (m_syncNavigationActionPolicyActionIsValid) {
3261 policyAction = m_syncNavigationActionPolicyAction;
3262 downloadID = m_syncNavigationActionPolicyDownloadID;
3266 void WebPageProxy::decidePolicyForNewWindowAction(uint64_t frameID, const NavigationActionData& navigationActionData, const ResourceRequest& request, const String& frameName, uint64_t listenerID, const UserData& userData)
3268 WebFrameProxy* frame = m_process->webFrame(frameID);
3269 MESSAGE_CHECK(frame);
3270 MESSAGE_CHECK_URL(request.url());
3272 Ref<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
3274 if (m_navigationClient) {
3275 RefPtr<API::FrameInfo> sourceFrameInfo;
3277 sourceFrameInfo = API::FrameInfo::create(*frame);
3279 auto navigationAction = API::NavigationAction::create(navigationActionData, sourceFrameInfo.get(), nullptr, request, request.url());
3281 m_navigationClient->decidePolicyForNavigationAction(*this, navigationAction.get(), WTF::move(listener), m_process->transformHandlesToObjects(userData.object()).get());
3284 m_policyClient->decidePolicyForNewWindowAction(*this, *frame, navigationActionData, request, frameName, WTF::move(listener), m_process->transformHandlesToObjects(userData.object()).get());
3287 void WebPageProxy::decidePolicyForResponse(uint64_t frameID, const ResourceResponse& response, const ResourceRequest& request, bool canShowMIMEType, uint64_t listenerID, const UserData& userData)
3289 WebFrameProxy* frame = m_process->webFrame(frameID);
3290 MESSAGE_CHECK(frame);
3291 MESSAGE_CHECK_URL(request.url());
3292 MESSAGE_CHECK_URL(response.url());
3294 Ref<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
3296 if (m_navigationClient) {
3297 auto navigationResponse = API::NavigationResponse::create(API::FrameInfo::create(*frame).get(), request, response, canShowMIMEType);
3298 m_navigationClient->decidePolicyForNavigationResponse(*this, navigationResponse.get(), WTF::move(listener), m_process->transformHandlesToObjects(userData.object()).get());
3300 m_policyClient->decidePolicyForResponse(*this, *frame, response, request, canShowMIMEType, WTF::move(listener), m_process->transformHandlesToObjects(userData.object()).get());
3303 void WebPageProxy::decidePolicyForResponseSync(uint64_t frameID, const ResourceResponse& response, const ResourceRequest& request, bool canShowMIMEType, uint64_t listenerID, const UserData& userData, bool& receivedPolicyAction, uint64_t& policyAction, uint64_t& downloadID)
3305 ASSERT(!m_inDecidePolicyForResponseSync);
3307 m_inDecidePolicyForResponseSync = true;
3308 m_decidePolicyForResponseRequest = &request;
3309 m_syncMimeTypePolicyActionIsValid = false;
3311 decidePolicyForResponse(frameID, response, request, canShowMIMEType, listenerID, userData);
3313 m_inDecidePolicyForResponseSync = false;
3314 m_decidePolicyForResponseRequest = 0;
3316 // Check if we received a policy decision already. If we did, we can just pass it back.
3317 receivedPolicyAction = m_syncMimeTypePolicyActionIsValid;
3318 if (m_syncMimeTypePolicyActionIsValid) {
3319 policyAction = m_syncMimeTypePolicyAction;
3320 downloadID = m_syncMimeTypePolicyDownloadID;
3324 void WebPageProxy::unableToImplementPolicy(uint64_t frameID, const ResourceError& error, const UserData& userData)
3326 WebFrameProxy* frame = m_process->webFrame(frameID);
3327 MESSAGE_CHECK(frame);
3329 m_policyClient->unableToImplementPolicy(*this, *frame, error, m_process->transformHandlesToObjects(userData.object()).get());
3334 void WebPageProxy::willSubmitForm(uint64_t frameID, uint64_t sourceFrameID, const Vector<std::pair<String, String>>& textFieldValues, uint64_t listenerID, const UserData& userData)
3336 WebFrameProxy* frame = m_process->webFrame(frameID);
3337 MESSAGE_CHECK(frame);
3339 WebFrameProxy* sourceFrame = m_process->webFrame(sourceFrameID);
3340 MESSAGE_CHECK(sourceFrame);
3342 Ref<WebFormSubmissionListenerProxy> listener = frame->setUpFormSubmissionListenerProxy(listenerID);
3343 m_formClient->willSubmitForm(*this, *frame, *sourceFrame, textFieldValues, m_process->transformHandlesToObjects(userData.object()).get(), listener.get());
3346 void WebPageProxy::didNavigateWithNavigationData(const WebNavigationDataStore& store, uint64_t frameID)
3348 WebFrameProxy* frame = m_process->webFrame(frameID);
3349 MESSAGE_CHECK(frame);
3350 MESSAGE_CHECK(frame->page() == this);
3352 if (m_historyClient) {
3353 if (frame->isMainFrame())
3354 m_historyClient->didNavigateWithNavigationData(*this, store);
3356 m_loaderClient->didNavigateWithNavigationData(*this, store, *frame);
3357 process().processPool().historyClient().didNavigateWithNavigationData(process().processPool(), *this, store, *frame);
3360 void WebPageProxy::didPerformClientRedirect(const String& sourceURLString, const String& destinationURLString, uint64_t frameID)
3362 if (sourceURLString.isEmpty() || destinationURLString.isEmpty())
3365 WebFrameProxy* frame = m_process->webFrame(frameID);
3366 MESSAGE_CHECK(frame);
3367 MESSAGE_CHECK(frame->page() == this);
3369 MESSAGE_CHECK_URL(sourceURLString);
3370 MESSAGE_CHECK_URL(destinationURLString);
3372 if (m_historyClient) {
3373 if (frame->isMainFrame())
3374 m_historyClient->didPerformClientRedirect(*this, sourceURLString, destinationURLString);
3376 m_loaderClient->didPerformClientRedirect(*this, sourceURLString, destinationURLString, *frame);
3377 process().processPool().historyClient().didPerformClientRedirect(process().processPool(), *this, sourceURLString, destinationURLString, *frame);
3380 void WebPageProxy::didPerformServerRedirect(const String& sourceURLString, const String& destinationURLString, uint64_t frameID)
3382 if (sourceURLString.isEmpty() || destinationURLString.isEmpty())
3385 WebFrameProxy* frame = m_process->webFrame(frameID);
3386 MESSAGE_CHECK(frame);
3387 MESSAGE_CHECK(frame->page() == this);
3389 MESSAGE_CHECK_URL(sourceURLString);
3390 MESSAGE_CHECK_URL(destinationURLString);
3392 if (m_historyClient) {
3393 if (frame->isMainFrame())
3394 m_historyClient->didPerformServerRedirect(*this, sourceURLString, destinationURLString);
3396 m_loaderClient->didPerformServerRedirect(*this, sourceURLString, destinationURLString, *frame);
3397 process().processPool().historyClient().didPerformServerRedirect(process().processPool(), *this, sourceURLString, destinationURLString, *frame);
3400 void WebPageProxy::didUpdateHistoryTitle(const String& title, const String& url, uint64_t frameID)
3402 WebFrameProxy* frame = m_process->webFrame(frameID);
3403 MESSAGE_CHECK(frame);
3404 MESSAGE_CHECK(frame->page() == this);
3406 MESSAGE_CHECK_URL(url);
3408 if (m_historyClient) {
3409 if (frame->isMainFrame())
3410 m_historyClient->didUpdateHistoryTitle(*this, title, url);
3412 m_loaderClient->didUpdateHistoryTitle(*this, title, url, *frame);
3413 process().processPool().historyClient().didUpdateHistoryTitle(process().processPool(), *this, title, url, *frame);
3418 void WebPageProxy::createNewPage(uint64_t frameID, const ResourceRequest& request, const WindowFeatures& windowFeatures, const NavigationActionData& navigationActionData, uint64_t& newPageID, WebPageCreationParameters& newPageParameters)
3420 WebFrameProxy* frame = m_process->webFrame(frameID);
3421 MESSAGE_CHECK(frame);
3423 RefPtr<WebPageProxy> newPage = m_uiClient->createNewPage(this, frame, request, windowFeatures, navigationActionData);
3429 newPageID = newPage->pageID();
3430 newPageParameters = newPage->creationParameters();
3432 WebsiteDataStore::cloneSessionData(*this, *newPage);
3435 void WebPageProxy::showPage()
3437 m_uiClient->showPage(this);
3440 void WebPageProxy::fullscreenMayReturnToInline()
3442 m_uiClient->fullscreenMayReturnToInline(this);
3445 void WebPageProxy::didEnterFullscreen()
3447 m_uiClient->didEnterFullscreen(this);
3450 void WebPageProxy::didExitFullscreen()
3452 m_uiClient->didExitFullscreen(this);
3455 void WebPageProxy::closePage(bool stopResponsivenessTimer)
3457 if (stopResponsivenessTimer)
3458 m_process->responsivenessTimer()->stop();
3460 m_pageClient.clearAllEditCommands();
3461 m_uiClient->close(this);
3464 void WebPageProxy::runJavaScriptAlert(uint64_t frameID, const String& message, RefPtr<Messages::WebPageProxy::RunJavaScriptAlert::DelayedReply> reply)
3466 WebFrameProxy* frame = m_process->webFrame(frameID);
3467 MESSAGE_CHECK(frame);
3469 // Since runJavaScriptAlert() can spin a nested run loop we need to turn off the responsiveness timer.
3470 m_process->responsivenessTimer()->stop();
3472 m_uiClient->runJavaScriptAlert(this, message, frame, [reply]{ reply->send(); });
3475 void WebPageProxy::runJavaScriptConfirm(uint64_t frameID, const String& message, RefPtr<Messages::WebPageProxy::RunJavaScriptConfirm::DelayedReply> reply)
3477 WebFrameProxy* frame = m_process->webFrame(frameID);
3478 MESSAGE_CHECK(frame);
3480 // Since runJavaScriptConfirm() can spin a nested run loop we need to turn off the responsiveness timer.
3481 m_process->responsivenessTimer()->stop();
3483 m_uiClient->runJavaScriptConfirm(this, message, frame, [reply](bool result) { reply->send(result); });
3486 void WebPageProxy::runJavaScriptPrompt(uint64_t frameID, const String& message, const String& defaultValue, RefPtr<Messages::WebPageProxy::RunJavaScriptPrompt::DelayedReply> reply)
3488 WebFrameProxy* frame = m_process->webFrame(frameID);
3489 MESSAGE_CHECK(frame);
3491 // Since runJavaScriptPrompt() can spin a nested run loop we need to turn off the responsiveness timer.
3492 m_process->responsivenessTimer()->stop();
3494 m_uiClient->runJavaScriptPrompt(this, message, defaultValue, frame, [reply](const String& result) { reply->send(result); });
3497 void WebPageProxy::shouldInterruptJavaScript(bool& result)
3499 // Since shouldInterruptJavaScript() can spin a nested run loop we need to turn off the responsiveness timer.
3500 m_process->responsivenessTimer()->stop();
3502 result = m_uiClient->shouldInterruptJavaScript(this);
3505 void WebPageProxy::setStatusText(const String& text)
3507 m_uiClient->setStatusText(this, text);
3510 void WebPageProxy::mouseDidMoveOverElement(const WebHitTestResult::Data& hitTestResultData, uint32_t opaqueModifiers, const UserData& userData)
3512 m_lastMouseMoveHitTestResult = WebHitTestResult::create(hitTestResultData);
3514 WebEvent::Modifiers modifiers = static_cast<WebEvent::Modifiers>(opaqueModifiers);
3516 m_uiClient->mouseDidMoveOverElement(this, hitTestResultData, modifiers, m_process->transformHandlesToObjects(userData.object()).get());
3519 void WebPageProxy::didBeginTrackingPotentialLongMousePress(const IntPoint& mouseDownPosition, const WebHitTestResult::Data& hitTestResultData, const UserData& userData)
3521 m_uiClient->didBeginTrackingPotentialLongMousePress(this, mouseDownPosition, hitTestResultData, m_process->transformHandlesToObjects(userData.object()).get());
3524 void WebPageProxy::didRecognizeLongMousePress(const UserData& userData)
3526 m_uiClient->didRecognizeLongMousePress(this, m_process->transformHandlesToObjects(userData.object()).get());
3529 void WebPageProxy::didCancelTrackingPotentialLongMousePress(const UserData& userData)
3531 m_uiClient->didCancelTrackingPotentialLongMousePress(this, m_process->transformHandlesToObjects(userData.object()).get());
3534 void WebPageProxy::connectionWillOpen(IPC::Connection& connection)
3536 ASSERT(&connection == m_process->connection());
3538 m_webProcessLifetimeTracker.connectionWillOpen(connection);
3541 void WebPageProxy::webProcessWillShutDown()
3543 m_webProcessLifetimeTracker.webProcessWillShutDown();
3546 void WebPageProxy::processDidFinishLaunching()
3548 ASSERT(m_process->state() == WebProcessProxy::State::Running);
3550 if (m_userContentController)
3551 m_process->addWebUserContentControllerProxy(*m_userContentController);
3552 m_process->addVisitedLinkProvider(m_visitedLinkProvider);
3555 #if ENABLE(NETSCAPE_PLUGIN_API)
3556 void WebPageProxy::unavailablePluginButtonClicked(uint32_t opaquePluginUnavailabilityReason, const String& mimeType, const String& pluginURLString, const String& pluginspageAttributeURLString, const String& frameURLString, const String& pageURLString)
3558 MESSAGE_CHECK_URL(pluginURLString);
3559 MESSAGE_CHECK_URL(pluginspageAttributeURLString);
3560 MESSAGE_CHECK_URL(frameURLString);
3561 MESSAGE_CHECK_URL(pageURLString);
3563 RefPtr<API::Dictionary> pluginInformation;
3564 String newMimeType = mimeType;
3565 PluginModuleInfo plugin = m_process->processPool().pluginInfoStore().findPlugin(newMimeType, URL(URL(), pluginURLString));
3566 pluginInformation = createPluginInformationDictionary(plugin, frameURLString, mimeType, pageURLString, pluginspageAttributeURLString, pluginURLString);
3568 WKPluginUnavailabilityReason pluginUnavailabilityReason = kWKPluginUnavailabilityReasonPluginMissing;
3569 switch (static_cast<RenderEmbeddedObject::PluginUnavailabilityReason>(opaquePluginUnavailabilityReason)) {
3570 case RenderEmbeddedObject::PluginMissing:
3571 pluginUnavailabilityReason = kWKPluginUnavailabilityReasonPluginMissing;
3573 case RenderEmbeddedObject::InsecurePluginVersion:
3574 pluginUnavailabilityReason = kWKPluginUnavailabilityReasonInsecurePluginVersion;
3576 case RenderEmbeddedObject::PluginCrashed:
3577 pluginUnavailabilityReason = kWKPluginUnavailabilityReasonPluginCrashed;
3579 case RenderEmbeddedObject::PluginBlockedByContentSecurityPolicy:
3580 ASSERT_NOT_REACHED();
3583 m_uiClient->unavailablePluginButtonClicked(this, pluginUnavailabilityReason, pluginInformation.get());
3585 #endif // ENABLE(NETSCAPE_PLUGIN_API)
3588 void WebPageProxy::webGLPolicyForURL(const String& url, uint32_t& loadPolicy)