2 * Copyright (C) 2010-2017 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 "APIFindMatchesClient.h"
34 #include "APIFormClient.h"
35 #include "APIFrameInfo.h"
36 #include "APIFullscreenClient.h"
37 #include "APIGeometry.h"
38 #include "APIHistoryClient.h"
39 #include "APIHitTestResult.h"
40 #include "APIIconLoadingClient.h"
41 #include "APILegacyContextHistoryClient.h"
42 #include "APILoaderClient.h"
43 #include "APINavigation.h"
44 #include "APINavigationAction.h"
45 #include "APINavigationClient.h"
46 #include "APINavigationResponse.h"
47 #include "APIOpenPanelParameters.h"
48 #include "APIPageConfiguration.h"
49 #include "APIPolicyClient.h"
50 #include "APISecurityOrigin.h"
51 #include "APIUIClient.h"
52 #include "APIURLRequest.h"
53 #include "AuthenticationChallengeProxy.h"
54 #include "AuthenticationDecisionListener.h"
55 #include "DataReference.h"
56 #include "DownloadProxy.h"
57 #include "DrawingAreaProxy.h"
58 #include "DrawingAreaProxyMessages.h"
59 #include "EventDispatcherMessages.h"
60 #include "FrameInfoData.h"
61 #include "LoadParameters.h"
63 #include "NativeWebGestureEvent.h"
64 #include "NativeWebKeyboardEvent.h"
65 #include "NativeWebMouseEvent.h"
66 #include "NativeWebWheelEvent.h"
67 #include "NavigationActionData.h"
68 #include "NetworkProcessMessages.h"
69 #include "NotificationPermissionRequest.h"
70 #include "NotificationPermissionRequestManager.h"
71 #include "OptionalCallbackID.h"
72 #include "PageClient.h"
73 #include "PluginInformation.h"
74 #include "PluginProcessManager.h"
75 #include "PrintInfo.h"
76 #include "TextChecker.h"
77 #include "TextCheckerState.h"
78 #include "UserMediaPermissionRequestProxy.h"
79 #include "UserMediaProcessManager.h"
80 #include "WKContextPrivate.h"
81 #include "WebAutomationSession.h"
82 #include "WebBackForwardList.h"
83 #include "WebBackForwardListItem.h"
84 #include "WebCertificateInfo.h"
85 #include "WebContextMenuItem.h"
86 #include "WebContextMenuProxy.h"
87 #include "WebCoreArgumentCoders.h"
88 #include "WebEditCommandProxy.h"
90 #include "WebEventConversion.h"
91 #include "WebFormSubmissionListenerProxy.h"
92 #include "WebFramePolicyListenerProxy.h"
93 #include "WebFullScreenManagerProxy.h"
94 #include "WebFullScreenManagerProxyMessages.h"
96 #include "WebInspectorProxy.h"
97 #include "WebInspectorUtilities.h"
98 #include "WebNavigationState.h"
99 #include "WebNotificationManagerProxy.h"
100 #include "WebOpenPanelResultListenerProxy.h"
101 #include "WebPageCreationParameters.h"
102 #include "WebPageGroup.h"
103 #include "WebPageGroupData.h"
104 #include "WebPageMessages.h"
105 #include "WebPageProxyMessages.h"
106 #include "WebPaymentCoordinatorProxy.h"
107 #include "WebPopupItem.h"
108 #include "WebPopupMenuProxy.h"
109 #include "WebPreferences.h"
110 #include "WebProcessMessages.h"
111 #include "WebProcessPool.h"
112 #include "WebProcessProxy.h"
113 #include "WebProtectionSpace.h"
114 #include "WebURLSchemeHandler.h"
115 #include "WebUserContentControllerProxy.h"
116 #include "WebsiteDataStore.h"
117 #include <WebCore/BitmapImage.h>
118 #include <WebCore/DiagnosticLoggingClient.h>
119 #include <WebCore/DiagnosticLoggingKeys.h>
120 #include <WebCore/DragController.h>
121 #include <WebCore/DragData.h>
122 #include <WebCore/EventNames.h>
123 #include <WebCore/FloatRect.h>
124 #include <WebCore/FocusDirection.h>
125 #include <WebCore/JSDOMBinding.h>
126 #include <WebCore/JSDOMExceptionHandling.h>
127 #include <WebCore/LengthBox.h>
128 #include <WebCore/MIMETypeRegistry.h>
129 #include <WebCore/PerformanceLoggingClient.h>
130 #include <WebCore/PublicSuffix.h>
131 #include <WebCore/RenderEmbeddedObject.h>
132 #include <WebCore/SerializedCryptoKeyWrap.h>
133 #include <WebCore/TextCheckerClient.h>
134 #include <WebCore/TextIndicator.h>
135 #include <WebCore/URL.h>
136 #include <WebCore/URLParser.h>
137 #include <WebCore/ValidationBubble.h>
138 #include <WebCore/WindowFeatures.h>
140 #include <wtf/NeverDestroyed.h>
141 #include <wtf/SystemTracing.h>
142 #include <wtf/text/StringView.h>
144 #if ENABLE(ASYNC_SCROLLING)
145 #include "RemoteScrollingCoordinatorProxy.h"
149 #include <wtf/RefCountedLeakCounter.h>
153 #include "RemoteLayerTreeDrawingAreaProxy.h"
154 #include "RemoteLayerTreeScrollingPerformanceData.h"
155 #include "VideoFullscreenManagerProxy.h"
156 #include "VideoFullscreenManagerProxyMessages.h"
157 #include "ViewSnapshotStore.h"
158 #include <WebCore/MachSendRight.h>
159 #include <WebCore/RunLoopObserver.h>
160 #include <WebCore/TextIndicatorWindow.h>
164 #include "WebSelectionData.h"
168 #include <WebCore/CairoUtilities.h>
171 #if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
172 #include <WebCore/MediaPlaybackTarget.h>
173 #include <WebCore/WebMediaSessionManager.h>
176 #if ENABLE(MEDIA_SESSION)
177 #include "WebMediaSessionFocusManager.h"
178 #include "WebMediaSessionMetadata.h"
179 #include <WebCore/MediaSessionMetadata.h>
182 #if PLATFORM(IOS) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
183 #include "PlaybackSessionManagerProxy.h"
186 #if ENABLE(MEDIA_STREAM)
187 #include <WebCore/MediaConstraints.h>
190 // This controls what strategy we use for mouse wheel coalescing.
191 #define MERGE_WHEEL_EVENTS 1
193 #define MESSAGE_CHECK(assertion) MESSAGE_CHECK_BASE(assertion, m_process->connection())
194 #define MESSAGE_CHECK_URL(url) MESSAGE_CHECK_BASE(m_process->checkURLReceivedFromWebProcess(url), m_process->connection())
196 #define RELEASE_LOG_IF_ALLOWED(channel, ...) RELEASE_LOG_IF(isAlwaysOnLoggingAllowed(), channel, __VA_ARGS__)
198 using namespace WebCore;
200 // Represents the number of wheel events we can hold in the queue before we start pushing them preemptively.
201 static const unsigned wheelEventQueueSizeThreshold = 10;
205 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, webPageProxyCounter, ("WebPageProxy"));
207 class ExceededDatabaseQuotaRecords {
208 WTF_MAKE_NONCOPYABLE(ExceededDatabaseQuotaRecords); WTF_MAKE_FAST_ALLOCATED;
209 friend class NeverDestroyed<ExceededDatabaseQuotaRecords>;
213 String originIdentifier;
216 uint64_t currentQuota;
217 uint64_t currentOriginUsage;
218 uint64_t currentDatabaseUsage;
219 uint64_t expectedUsage;
220 RefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply> reply;
223 static ExceededDatabaseQuotaRecords& singleton();
225 std::unique_ptr<Record> createRecord(uint64_t frameID, String originIdentifier,
226 String databaseName, String displayName, uint64_t currentQuota,
227 uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage,
228 Ref<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply>&&);
230 void add(std::unique_ptr<Record>);
231 bool areBeingProcessed() const { return !!m_currentRecord; }
235 ExceededDatabaseQuotaRecords() { }
236 ~ExceededDatabaseQuotaRecords() { }
238 Deque<std::unique_ptr<Record>> m_records;
239 std::unique_ptr<Record> m_currentRecord;
242 ExceededDatabaseQuotaRecords& ExceededDatabaseQuotaRecords::singleton()
244 static NeverDestroyed<ExceededDatabaseQuotaRecords> records;
248 std::unique_ptr<ExceededDatabaseQuotaRecords::Record> ExceededDatabaseQuotaRecords::createRecord(
249 uint64_t frameID, String originIdentifier, String databaseName, String displayName,
250 uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage,
251 uint64_t expectedUsage, Ref<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply>&& reply)
253 auto record = std::make_unique<Record>();
254 record->frameID = frameID;
255 record->originIdentifier = originIdentifier;
256 record->databaseName = databaseName;
257 record->displayName = displayName;
258 record->currentQuota = currentQuota;
259 record->currentOriginUsage = currentOriginUsage;
260 record->currentDatabaseUsage = currentDatabaseUsage;
261 record->expectedUsage = expectedUsage;
262 record->reply = WTFMove(reply);
266 void ExceededDatabaseQuotaRecords::add(std::unique_ptr<ExceededDatabaseQuotaRecords::Record> record)
268 m_records.append(WTFMove(record));
271 ExceededDatabaseQuotaRecords::Record* ExceededDatabaseQuotaRecords::next()
273 m_currentRecord = nullptr;
274 if (!m_records.isEmpty())
275 m_currentRecord = m_records.takeFirst();
276 return m_currentRecord.get();
280 static const char* webKeyboardEventTypeString(WebEvent::Type type)
283 case WebEvent::KeyDown:
286 case WebEvent::KeyUp:
289 case WebEvent::RawKeyDown:
296 ASSERT_NOT_REACHED();
300 #endif // !LOG_DISABLED
302 class PageClientProtector {
303 WTF_MAKE_NONCOPYABLE(PageClientProtector);
305 PageClientProtector(PageClient& pageClient)
306 : m_pageClient(pageClient)
308 m_pageClient.refView();
311 ~PageClientProtector()
313 m_pageClient.derefView();
317 PageClient& m_pageClient;
320 Ref<WebPageProxy> WebPageProxy::create(PageClient& pageClient, WebProcessProxy& process, uint64_t pageID, Ref<API::PageConfiguration>&& configuration)
322 return adoptRef(*new WebPageProxy(pageClient, process, pageID, WTFMove(configuration)));
325 WebPageProxy::WebPageProxy(PageClient& pageClient, WebProcessProxy& process, uint64_t pageID, Ref<API::PageConfiguration>&& configuration)
326 : m_pageClient(pageClient)
327 , m_configuration(WTFMove(configuration))
328 , m_loaderClient(std::make_unique<API::LoaderClient>())
329 , m_policyClient(std::make_unique<API::PolicyClient>())
330 , m_iconLoadingClient(std::make_unique<API::IconLoadingClient>())
331 , m_formClient(std::make_unique<API::FormClient>())
332 , m_uiClient(std::make_unique<API::UIClient>())
333 , m_findClient(std::make_unique<API::FindClient>())
334 , m_findMatchesClient(std::make_unique<API::FindMatchesClient>())
335 #if ENABLE(CONTEXT_MENUS)
336 , m_contextMenuClient(std::make_unique<API::ContextMenuClient>())
338 , m_navigationState(std::make_unique<WebNavigationState>())
340 , m_pageGroup(*m_configuration->pageGroup())
341 , m_preferences(*m_configuration->preferences())
342 , m_userContentController(*m_configuration->userContentController())
343 , m_visitedLinkStore(*m_configuration->visitedLinkStore())
344 , m_websiteDataStore(m_configuration->websiteDataStore()->websiteDataStore())
345 , m_userAgent(standardUserAgent())
346 , m_overrideContentSecurityPolicy { m_configuration->overrideContentSecurityPolicy() }
347 , m_treatsSHA1CertificatesAsInsecure(m_configuration->treatsSHA1SignedCertificatesAsInsecure())
348 #if ENABLE(FULLSCREEN_API)
349 , m_fullscreenClient(std::make_unique<API::FullscreenClient>())
351 , m_geolocationPermissionRequestManager(*this)
352 , m_notificationPermissionRequestManager(*this)
354 , m_alwaysRunsAtForegroundPriority(m_configuration->alwaysRunsAtForegroundPriority())
356 , m_initialCapitalizationEnabled(m_configuration->initialCapitalizationEnabled())
357 , m_cpuLimit(m_configuration->cpuLimit())
358 , m_backForwardList(WebBackForwardList::create(*this))
359 , m_waitsForPaintAfterViewDidMoveToWindow(m_configuration->waitsForPaintAfterViewDidMoveToWindow())
361 , m_sessionID(m_configuration->sessionID())
362 , m_controlledByAutomation(m_configuration->isControlledByAutomation())
364 , m_isSmartInsertDeleteEnabled(TextChecker::isSmartInsertDeleteEnabled())
366 , m_pageLoadState(*this)
367 , m_configurationPreferenceValues(m_configuration->preferenceValues())
368 , m_weakPtrFactory(this)
370 m_webProcessLifetimeTracker.addObserver(m_visitedLinkStore);
371 m_webProcessLifetimeTracker.addObserver(m_websiteDataStore);
373 updateActivityState();
374 updateThrottleState();
375 updateHiddenPageThrottlingAutoIncreases();
377 #if HAVE(OUT_OF_PROCESS_LAYER_HOSTING)
378 m_layerHostingMode = m_activityState & ActivityState::IsInWindow ? m_pageClient.viewLayerHostingMode() : LayerHostingMode::OutOfProcess;
381 platformInitialize();
384 webPageProxyCounter.increment();
387 WebProcessPool::statistics().wkPageCount++;
389 m_preferences->addPage(*this);
390 m_pageGroup->addPage(this);
392 m_inspector = WebInspectorProxy::create(this);
393 #if ENABLE(FULLSCREEN_API)
394 m_fullScreenManager = WebFullScreenManagerProxy::create(*this, m_pageClient.fullScreenManagerProxyClient());
396 #if PLATFORM(IOS) && HAVE(AVKIT) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
397 m_playbackSessionManager = PlaybackSessionManagerProxy::create(*this);
398 m_videoFullscreenManager = VideoFullscreenManagerProxy::create(*this, *m_playbackSessionManager);
401 #if ENABLE(APPLE_PAY)
402 m_paymentCoordinator = std::make_unique<WebPaymentCoordinatorProxy>(*this);
405 m_process->addMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID, *this);
408 const CFIndex activityStateChangeRunLoopOrder = (CFIndex)RunLoopObserver::WellKnownRunLoopOrders::CoreAnimationCommit - 1;
409 m_activityStateChangeDispatcher = std::make_unique<RunLoopObserver>(activityStateChangeRunLoopOrder, [this] {
410 this->dispatchActivityStateChange();
415 WebPageProxy::~WebPageProxy()
417 ASSERT(m_process->webPage(m_pageID) != this);
419 for (WebPageProxy* page : m_process->pages())
420 ASSERT(page != this);
426 WebProcessPool::statistics().wkPageCount--;
428 if (m_hasSpellDocumentTag)
429 TextChecker::closeSpellDocumentWithTag(m_spellDocumentTag);
431 m_preferences->removePage(*this);
432 m_pageGroup->removePage(this);
435 webPageProxyCounter.decrement();
439 const API::PageConfiguration& WebPageProxy::configuration() const
441 return m_configuration.get();
444 pid_t WebPageProxy::processIdentifier() const
449 return m_process->processIdentifier();
452 bool WebPageProxy::isValid() const
454 // A page that has been explicitly closed is never valid.
461 void WebPageProxy::setPreferences(WebPreferences& preferences)
463 if (&preferences == m_preferences.ptr())
466 m_preferences->removePage(*this);
467 m_preferences = preferences;
468 m_preferences->addPage(*this);
470 preferencesDidChange();
473 void WebPageProxy::setHistoryClient(std::unique_ptr<API::HistoryClient>&& historyClient)
475 m_historyClient = WTFMove(historyClient);
478 void WebPageProxy::setNavigationClient(std::unique_ptr<API::NavigationClient>&& navigationClient)
480 m_navigationClient = WTFMove(navigationClient);
483 void WebPageProxy::setLoaderClient(std::unique_ptr<API::LoaderClient>&& loaderClient)
486 m_loaderClient = std::make_unique<API::LoaderClient>();
490 m_loaderClient = WTFMove(loaderClient);
493 void WebPageProxy::setPolicyClient(std::unique_ptr<API::PolicyClient>&& policyClient)
496 m_policyClient = std::make_unique<API::PolicyClient>();
500 m_policyClient = WTFMove(policyClient);
503 void WebPageProxy::setFormClient(std::unique_ptr<API::FormClient>&& formClient)
506 m_formClient = std::make_unique<API::FormClient>();
510 m_formClient = WTFMove(formClient);
513 void WebPageProxy::setUIClient(std::unique_ptr<API::UIClient>&& uiClient)
516 m_uiClient = std::make_unique<API::UIClient>();
520 m_uiClient = WTFMove(uiClient);
525 m_process->send(Messages::WebPage::SetCanRunBeforeUnloadConfirmPanel(m_uiClient->canRunBeforeUnloadConfirmPanel()), m_pageID);
526 setCanRunModal(m_uiClient->canRunModal());
529 void WebPageProxy::setIconLoadingClient(std::unique_ptr<API::IconLoadingClient>&& iconLoadingClient)
531 bool hasClient = iconLoadingClient.get();
532 if (!iconLoadingClient)
533 m_iconLoadingClient = std::make_unique<API::IconLoadingClient>();
535 m_iconLoadingClient = WTFMove(iconLoadingClient);
540 m_process->send(Messages::WebPage::SetUseIconLoadingClient(hasClient), m_pageID);
543 void WebPageProxy::setFindClient(std::unique_ptr<API::FindClient>&& findClient)
546 m_findClient = std::make_unique<API::FindClient>();
550 m_findClient = WTFMove(findClient);
553 void WebPageProxy::setFindMatchesClient(std::unique_ptr<API::FindMatchesClient>&& findMatchesClient)
555 if (!findMatchesClient) {
556 m_findMatchesClient = std::make_unique<API::FindMatchesClient>();
560 m_findMatchesClient = WTFMove(findMatchesClient);
563 void WebPageProxy::setDiagnosticLoggingClient(std::unique_ptr<API::DiagnosticLoggingClient>&& diagnosticLoggingClient)
565 m_diagnosticLoggingClient = WTFMove(diagnosticLoggingClient);
568 #if ENABLE(CONTEXT_MENUS)
569 void WebPageProxy::setContextMenuClient(std::unique_ptr<API::ContextMenuClient>&& contextMenuClient)
571 if (!contextMenuClient) {
572 m_contextMenuClient = std::make_unique<API::ContextMenuClient>();
576 m_contextMenuClient = WTFMove(contextMenuClient);
580 void WebPageProxy::setInjectedBundleClient(const WKPageInjectedBundleClientBase* client)
583 m_injectedBundleClient = nullptr;
587 m_injectedBundleClient = std::make_unique<WebPageInjectedBundleClient>();
588 m_injectedBundleClient->initialize(client);
591 void WebPageProxy::handleMessage(IPC::Connection& connection, const String& messageName, const WebKit::UserData& messageBody)
593 ASSERT(m_process->connection() == &connection);
595 if (!m_injectedBundleClient)
598 m_injectedBundleClient->didReceiveMessageFromInjectedBundle(this, messageName, m_process->transformHandlesToObjects(messageBody.object()).get());
601 void WebPageProxy::handleSynchronousMessage(IPC::Connection& connection, const String& messageName, const UserData& messageBody, UserData& returnUserData)
603 ASSERT(m_process->connection() == &connection);
605 if (!m_injectedBundleClient)
608 RefPtr<API::Object> returnData;
609 m_injectedBundleClient->didReceiveSynchronousMessageFromInjectedBundle(this, messageName, m_process->transformHandlesToObjects(messageBody.object()).get(), returnData);
610 returnUserData = UserData(m_process->transformObjectsToHandles(returnData.get()));
613 void WebPageProxy::reattachToWebProcess()
617 ASSERT(m_process->state() == WebProcessProxy::State::Terminated);
620 m_process->removeWebPage(*this, m_pageID);
621 m_process->removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID);
623 m_process = m_process->processPool().createNewWebProcessRespectingProcessCountLimit(m_websiteDataStore.get());
625 ASSERT(m_process->state() != ChildProcessProxy::State::Terminated);
626 if (m_process->state() == ChildProcessProxy::State::Running)
627 processDidFinishLaunching();
628 m_process->addExistingWebPage(*this, m_pageID);
629 m_process->addMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID, *this);
631 updateActivityState();
632 updateThrottleState();
634 m_inspector = WebInspectorProxy::create(this);
635 #if ENABLE(FULLSCREEN_API)
636 m_fullScreenManager = WebFullScreenManagerProxy::create(*this, m_pageClient.fullScreenManagerProxyClient());
638 #if PLATFORM(IOS) && HAVE(AVKIT) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
639 m_playbackSessionManager = PlaybackSessionManagerProxy::create(*this);
640 m_videoFullscreenManager = VideoFullscreenManagerProxy::create(*this, *m_playbackSessionManager);
643 #if ENABLE(APPLE_PAY)
644 m_paymentCoordinator = std::make_unique<WebPaymentCoordinatorProxy>(*this);
649 m_pageClient.didRelaunchProcess();
650 m_drawingArea->waitForBackingStoreUpdateOnNextPaint();
653 RefPtr<API::Navigation> WebPageProxy::reattachToWebProcessForReload()
659 reattachToWebProcess();
661 if (!m_backForwardList->currentItem())
664 auto navigation = m_navigationState->createReloadNavigation();
666 // We allow stale content when reloading a WebProcess that's been killed or crashed.
667 m_process->send(Messages::WebPage::GoToBackForwardItem(navigation->navigationID(), m_backForwardList->currentItem()->itemID()), m_pageID);
668 m_process->responsivenessTimer().start();
670 return WTFMove(navigation);
673 RefPtr<API::Navigation> WebPageProxy::reattachToWebProcessWithItem(WebBackForwardListItem* item)
679 reattachToWebProcess();
684 if (item != m_backForwardList->currentItem())
685 m_backForwardList->goToItem(item);
687 auto navigation = m_navigationState->createBackForwardNavigation();
689 m_process->send(Messages::WebPage::GoToBackForwardItem(navigation->navigationID(), item->itemID()), m_pageID);
690 m_process->responsivenessTimer().start();
692 return WTFMove(navigation);
695 void WebPageProxy::initializeWebPage()
699 BackForwardListItemVector items = m_backForwardList->entries();
700 for (size_t i = 0; i < items.size(); ++i)
701 m_process->registerNewWebBackForwardListItem(items[i].get());
703 m_drawingArea = m_pageClient.createDrawingAreaProxy();
704 ASSERT(m_drawingArea);
706 #if ENABLE(ASYNC_SCROLLING)
707 if (m_drawingArea->type() == DrawingAreaTypeRemoteLayerTree) {
708 m_scrollingCoordinatorProxy = std::make_unique<RemoteScrollingCoordinatorProxy>(*this);
710 // On iOS, main frame scrolls are sent in terms of visible rect updates.
711 m_scrollingCoordinatorProxy->setPropagatesMainFrameScrolls(false);
716 process().send(Messages::WebProcess::CreateWebPage(m_pageID, creationParameters()), 0);
718 m_needsToFinishInitializingWebPageAfterProcessLaunch = true;
719 finishInitializingWebPageAfterProcessLaunch();
722 void WebPageProxy::finishInitializingWebPageAfterProcessLaunch()
724 if (!m_needsToFinishInitializingWebPageAfterProcessLaunch)
726 if (m_process->state() != WebProcessProxy::State::Running)
729 m_needsToFinishInitializingWebPageAfterProcessLaunch = false;
730 m_process->addVisitedLinkStore(m_visitedLinkStore);
733 void WebPageProxy::close()
740 if (m_activePopupMenu)
741 m_activePopupMenu->cancelTracking();
743 if (m_controlledByAutomation) {
744 if (auto* automationSession = process().processPool().automationSession())
745 automationSession->willClosePage(*this);
748 #if ENABLE(CONTEXT_MENUS)
749 m_activeContextMenu = nullptr;
752 m_backForwardList->pageClosed();
753 m_pageClient.pageClosed();
755 m_process->disconnectFramesFromPage(this);
757 resetState(ResetStateReason::PageInvalidated);
759 m_loaderClient = std::make_unique<API::LoaderClient>();
760 m_navigationClient = nullptr;
761 m_policyClient = std::make_unique<API::PolicyClient>();
762 m_iconLoadingClient = std::make_unique<API::IconLoadingClient>();
763 m_formClient = std::make_unique<API::FormClient>();
764 m_uiClient = std::make_unique<API::UIClient>();
765 m_findClient = std::make_unique<API::FindClient>();
766 m_findMatchesClient = std::make_unique<API::FindMatchesClient>();
767 m_diagnosticLoggingClient = nullptr;
768 #if ENABLE(CONTEXT_MENUS)
769 m_contextMenuClient = std::make_unique<API::ContextMenuClient>();
771 #if ENABLE(FULLSCREEN_API)
772 m_fullscreenClient = std::make_unique<API::FullscreenClient>();
775 m_webProcessLifetimeTracker.pageWasInvalidated();
777 m_process->send(Messages::WebPage::Close(), m_pageID);
778 m_process->removeWebPage(*this, m_pageID);
779 m_process->removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID);
780 m_process->processPool().supplement<WebNotificationManagerProxy>()->clearNotifications(this);
782 // Null out related WebPageProxy to avoid leaks.
783 m_configuration->setRelatedPage(nullptr);
786 // Make sure we don't hold a process assertion after getting closed.
787 m_activityToken = nullptr;
790 stopAllURLSchemeTasks();
793 bool WebPageProxy::tryClose()
798 // Close without delay if the process allows it. Our goal is to terminate
799 // the process, so we check a per-process status bit.
800 if (m_process->isSuddenTerminationEnabled())
803 m_process->send(Messages::WebPage::TryClose(), m_pageID);
804 m_process->responsivenessTimer().start();
808 bool WebPageProxy::maybeInitializeSandboxExtensionHandle(const URL& url, SandboxExtension::Handle& sandboxExtensionHandle)
810 if (!url.isLocalFile())
813 if (m_process->hasAssumedReadAccessToURL(url))
816 // Inspector resources are in a directory with assumed access.
817 ASSERT_WITH_SECURITY_IMPLICATION(!WebKit::isInspectorPage(*this));
819 SandboxExtension::createHandle("/", SandboxExtension::ReadOnly, sandboxExtensionHandle);
824 void WebPageProxy::addPlatformLoadParameters(LoadParameters&)
829 RefPtr<API::Navigation> WebPageProxy::loadRequest(ResourceRequest&& request, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy, API::Object* userData)
834 auto navigation = m_navigationState->createLoadRequestNavigation(ResourceRequest(request));
836 auto transaction = m_pageLoadState.transaction();
838 auto url = request.url();
839 m_pageLoadState.setPendingAPIRequestURL(transaction, url);
842 reattachToWebProcess();
844 LoadParameters loadParameters;
845 loadParameters.navigationID = navigation->navigationID();
846 loadParameters.request = WTFMove(request);
847 loadParameters.shouldOpenExternalURLsPolicy = (uint64_t)shouldOpenExternalURLsPolicy;
848 loadParameters.userData = UserData(process().transformObjectsToHandles(userData).get());
849 bool createdExtension = maybeInitializeSandboxExtensionHandle(url, loadParameters.sandboxExtensionHandle);
850 if (createdExtension)
851 m_process->willAcquireUniversalFileReadSandboxExtension();
852 addPlatformLoadParameters(loadParameters);
854 m_process->send(Messages::WebPage::LoadRequest(loadParameters), m_pageID);
855 m_process->responsivenessTimer().start();
857 return WTFMove(navigation);
860 RefPtr<API::Navigation> WebPageProxy::loadFile(const String& fileURLString, const String& resourceDirectoryURLString, API::Object* userData)
866 reattachToWebProcess();
868 URL fileURL = URL(URL(), fileURLString);
869 if (!fileURL.isLocalFile())
872 URL resourceDirectoryURL;
873 if (resourceDirectoryURLString.isNull())
874 resourceDirectoryURL = URL(ParsedURLString, ASCIILiteral("file:///"));
876 resourceDirectoryURL = URL(URL(), resourceDirectoryURLString);
877 if (!resourceDirectoryURL.isLocalFile())
881 auto navigation = m_navigationState->createLoadRequestNavigation(ResourceRequest(fileURL));
883 auto transaction = m_pageLoadState.transaction();
885 m_pageLoadState.setPendingAPIRequestURL(transaction, fileURLString);
887 String resourceDirectoryPath = resourceDirectoryURL.fileSystemPath();
889 LoadParameters loadParameters;
890 loadParameters.navigationID = navigation->navigationID();
891 loadParameters.request = fileURL;
892 loadParameters.shouldOpenExternalURLsPolicy = (uint64_t)ShouldOpenExternalURLsPolicy::ShouldNotAllow;
893 loadParameters.userData = UserData(process().transformObjectsToHandles(userData).get());
894 SandboxExtension::createHandle(resourceDirectoryPath, SandboxExtension::ReadOnly, loadParameters.sandboxExtensionHandle);
895 addPlatformLoadParameters(loadParameters);
897 m_process->assumeReadAccessToBaseURL(resourceDirectoryURL);
898 m_process->send(Messages::WebPage::LoadRequest(loadParameters), m_pageID);
899 m_process->responsivenessTimer().start();
901 return WTFMove(navigation);
904 RefPtr<API::Navigation> WebPageProxy::loadData(API::Data* data, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData)
909 auto navigation = m_navigationState->createLoadDataNavigation();
911 auto transaction = m_pageLoadState.transaction();
913 m_pageLoadState.setPendingAPIRequestURL(transaction, !baseURL.isEmpty() ? baseURL : blankURL().string());
916 reattachToWebProcess();
918 LoadParameters loadParameters;
919 loadParameters.navigationID = navigation->navigationID();
920 loadParameters.data = data->dataReference();
921 loadParameters.MIMEType = MIMEType;
922 loadParameters.encodingName = encoding;
923 loadParameters.baseURLString = baseURL;
924 loadParameters.userData = UserData(process().transformObjectsToHandles(userData).get());
925 addPlatformLoadParameters(loadParameters);
927 m_process->assumeReadAccessToBaseURL(baseURL);
928 m_process->send(Messages::WebPage::LoadData(loadParameters), m_pageID);
929 m_process->responsivenessTimer().start();
931 return WTFMove(navigation);
934 // FIXME: Get rid of loadHTMLString and just use loadData instead.
935 RefPtr<API::Navigation> WebPageProxy::loadHTMLString(const String& htmlString, const String& baseURL, API::Object* userData)
940 auto navigation = m_navigationState->createLoadDataNavigation();
942 auto transaction = m_pageLoadState.transaction();
944 m_pageLoadState.setPendingAPIRequestURL(transaction, !baseURL.isEmpty() ? baseURL : blankURL().string());
947 reattachToWebProcess();
949 LoadParameters loadParameters;
950 loadParameters.navigationID = navigation->navigationID();
951 loadParameters.string = htmlString;
952 loadParameters.MIMEType = ASCIILiteral("text/html");
953 loadParameters.baseURLString = baseURL;
954 loadParameters.userData = UserData(process().transformObjectsToHandles(userData).get());
955 addPlatformLoadParameters(loadParameters);
957 m_process->assumeReadAccessToBaseURL(baseURL);
958 m_process->send(Messages::WebPage::LoadString(loadParameters), m_pageID);
959 m_process->responsivenessTimer().start();
961 return WTFMove(navigation);
964 void WebPageProxy::loadAlternateHTMLString(const String& htmlString, const WebCore::URL& baseURL, const WebCore::URL& unreachableURL, API::Object* userData)
966 // When the UIProcess is in the process of handling a failing provisional load, do not attempt to
967 // start a second alternative HTML load as this will prevent the page load state from being
969 if (m_isClosed || m_isLoadingAlternateHTMLStringForFailingProvisionalLoad)
972 if (!m_failingProvisionalLoadURL.isEmpty())
973 m_isLoadingAlternateHTMLStringForFailingProvisionalLoad = true;
976 reattachToWebProcess();
978 auto transaction = m_pageLoadState.transaction();
980 m_pageLoadState.setPendingAPIRequestURL(transaction, unreachableURL);
981 m_pageLoadState.setUnreachableURL(transaction, unreachableURL);
984 m_mainFrame->setUnreachableURL(unreachableURL);
986 LoadParameters loadParameters;
987 loadParameters.navigationID = 0;
988 loadParameters.string = htmlString;
989 loadParameters.baseURLString = baseURL;
990 loadParameters.unreachableURLString = unreachableURL;
991 loadParameters.provisionalLoadErrorURLString = m_failingProvisionalLoadURL;
992 loadParameters.userData = UserData(process().transformObjectsToHandles(userData).get());
993 addPlatformLoadParameters(loadParameters);
995 m_process->assumeReadAccessToBaseURL(baseURL);
996 m_process->assumeReadAccessToBaseURL(unreachableURL);
997 m_process->send(Messages::WebPage::LoadAlternateHTMLString(loadParameters), m_pageID);
998 m_process->responsivenessTimer().start();
1001 void WebPageProxy::loadPlainTextString(const String& string, API::Object* userData)
1007 reattachToWebProcess();
1009 auto transaction = m_pageLoadState.transaction();
1010 m_pageLoadState.setPendingAPIRequestURL(transaction, blankURL().string());
1012 LoadParameters loadParameters;
1013 loadParameters.navigationID = 0;
1014 loadParameters.string = string;
1015 loadParameters.MIMEType = ASCIILiteral("text/plain");
1016 loadParameters.userData = UserData(process().transformObjectsToHandles(userData).get());
1017 addPlatformLoadParameters(loadParameters);
1019 m_process->send(Messages::WebPage::LoadString(loadParameters), m_pageID);
1020 m_process->responsivenessTimer().start();
1023 void WebPageProxy::loadWebArchiveData(API::Data* webArchiveData, API::Object* userData)
1029 reattachToWebProcess();
1031 auto transaction = m_pageLoadState.transaction();
1032 m_pageLoadState.setPendingAPIRequestURL(transaction, blankURL().string());
1034 LoadParameters loadParameters;
1035 loadParameters.navigationID = 0;
1036 loadParameters.data = webArchiveData->dataReference();
1037 loadParameters.MIMEType = ASCIILiteral("application/x-webarchive");
1038 loadParameters.encodingName = ASCIILiteral("utf-16");
1039 loadParameters.userData = UserData(process().transformObjectsToHandles(userData).get());
1040 addPlatformLoadParameters(loadParameters);
1042 m_process->send(Messages::WebPage::LoadData(loadParameters), m_pageID);
1043 m_process->responsivenessTimer().start();
1046 void WebPageProxy::navigateToPDFLinkWithSimulatedClick(const String& url, IntPoint documentPoint, IntPoint screenPoint)
1051 if (WebCore::protocolIsJavaScript(url))
1055 reattachToWebProcess();
1057 m_process->send(Messages::WebPage::NavigateToPDFLinkWithSimulatedClick(url, documentPoint, screenPoint), m_pageID);
1058 m_process->responsivenessTimer().start();
1061 void WebPageProxy::stopLoading()
1066 m_process->send(Messages::WebPage::StopLoading(), m_pageID);
1067 m_process->responsivenessTimer().start();
1070 RefPtr<API::Navigation> WebPageProxy::reload(OptionSet<WebCore::ReloadOption> options)
1072 SandboxExtension::Handle sandboxExtensionHandle;
1074 String url = m_pageLoadState.activeURL();
1075 if (url.isEmpty() && m_backForwardList->currentItem())
1076 url = m_backForwardList->currentItem()->url();
1078 if (!url.isEmpty()) {
1079 auto transaction = m_pageLoadState.transaction();
1080 m_pageLoadState.setPendingAPIRequestURL(transaction, url);
1082 // We may not have an extension yet if back/forward list was reinstated after a WebProcess crash or a browser relaunch
1083 bool createdExtension = maybeInitializeSandboxExtensionHandle(URL(URL(), url), sandboxExtensionHandle);
1084 if (createdExtension)
1085 m_process->willAcquireUniversalFileReadSandboxExtension();
1089 return reattachToWebProcessForReload();
1091 auto navigation = m_navigationState->createReloadNavigation();
1093 m_process->send(Messages::WebPage::Reload(navigation->navigationID(), options.toRaw(), sandboxExtensionHandle), m_pageID);
1094 m_process->responsivenessTimer().start();
1096 return WTFMove(navigation);
1099 void WebPageProxy::recordAutomaticNavigationSnapshot()
1101 if (m_suppressAutomaticNavigationSnapshotting)
1104 if (WebBackForwardListItem* item = m_backForwardList->currentItem())
1105 recordNavigationSnapshot(*item);
1108 void WebPageProxy::recordNavigationSnapshot(WebBackForwardListItem& item)
1110 if (!m_shouldRecordNavigationSnapshots)
1114 ViewSnapshotStore::singleton().recordSnapshot(*this, item);
1120 RefPtr<API::Navigation> WebPageProxy::goForward()
1122 WebBackForwardListItem* forwardItem = m_backForwardList->forwardItem();
1126 auto transaction = m_pageLoadState.transaction();
1128 m_pageLoadState.setPendingAPIRequestURL(transaction, forwardItem->url());
1131 return reattachToWebProcessWithItem(forwardItem);
1133 RefPtr<API::Navigation> navigation;
1134 if (!m_backForwardList->currentItem()->itemIsInSameDocument(*forwardItem))
1135 navigation = m_navigationState->createBackForwardNavigation();
1137 m_process->send(Messages::WebPage::GoForward(navigation ? navigation->navigationID() : 0, forwardItem->itemID()), m_pageID);
1138 m_process->responsivenessTimer().start();
1143 RefPtr<API::Navigation> WebPageProxy::goBack()
1145 WebBackForwardListItem* backItem = m_backForwardList->backItem();
1149 auto transaction = m_pageLoadState.transaction();
1151 m_pageLoadState.setPendingAPIRequestURL(transaction, backItem->url());
1154 return reattachToWebProcessWithItem(backItem);
1156 RefPtr<API::Navigation> navigation;
1157 if (!m_backForwardList->currentItem()->itemIsInSameDocument(*backItem))
1158 navigation = m_navigationState->createBackForwardNavigation();
1160 m_process->send(Messages::WebPage::GoBack(navigation ? navigation->navigationID() : 0, backItem->itemID()), m_pageID);
1161 m_process->responsivenessTimer().start();
1166 RefPtr<API::Navigation> WebPageProxy::goToBackForwardItem(WebBackForwardListItem* item)
1169 return reattachToWebProcessWithItem(item);
1171 auto transaction = m_pageLoadState.transaction();
1173 m_pageLoadState.setPendingAPIRequestURL(transaction, item->url());
1175 RefPtr<API::Navigation> navigation;
1176 if (!m_backForwardList->currentItem()->itemIsInSameDocument(*item))
1177 navigation = m_navigationState->createBackForwardNavigation();
1179 m_process->send(Messages::WebPage::GoToBackForwardItem(navigation ? navigation->navigationID() : 0, item->itemID()), m_pageID);
1180 m_process->responsivenessTimer().start();
1185 void WebPageProxy::tryRestoreScrollPosition()
1190 m_process->send(Messages::WebPage::TryRestoreScrollPosition(), m_pageID);
1193 void WebPageProxy::didChangeBackForwardList(WebBackForwardListItem* added, Vector<RefPtr<WebBackForwardListItem>> removed)
1195 PageClientProtector protector(m_pageClient);
1197 m_loaderClient->didChangeBackForwardList(*this, added, WTFMove(removed));
1199 auto transaction = m_pageLoadState.transaction();
1201 m_pageLoadState.setCanGoBack(transaction, m_backForwardList->backItem());
1202 m_pageLoadState.setCanGoForward(transaction, m_backForwardList->forwardItem());
1205 void WebPageProxy::willGoToBackForwardListItem(uint64_t itemID, const UserData& userData)
1207 PageClientProtector protector(m_pageClient);
1209 if (WebBackForwardListItem* item = m_process->webBackForwardItem(itemID))
1210 m_loaderClient->willGoToBackForwardListItem(*this, item, m_process->transformHandlesToObjects(userData.object()).get());
1213 bool WebPageProxy::shouldKeepCurrentBackForwardListItemInList(WebBackForwardListItem* item)
1215 PageClientProtector protector(m_pageClient);
1217 return m_loaderClient->shouldKeepCurrentBackForwardListItemInList(*this, item);
1220 bool WebPageProxy::canShowMIMEType(const String& mimeType)
1222 if (MIMETypeRegistry::canShowMIMEType(mimeType))
1225 #if ENABLE(NETSCAPE_PLUGIN_API)
1226 String newMimeType = mimeType;
1227 PluginModuleInfo plugin = m_process->processPool().pluginInfoStore().findPlugin(newMimeType, URL());
1228 if (!plugin.path.isNull() && m_preferences->pluginsEnabled())
1230 #endif // ENABLE(NETSCAPE_PLUGIN_API)
1233 // On Mac, we can show PDFs.
1234 if (MIMETypeRegistry::isPDFOrPostScriptMIMEType(mimeType) && !WebProcessPool::omitPDFSupport())
1236 #endif // PLATFORM(COCOA)
1241 void WebPageProxy::setControlledByAutomation(bool controlled)
1243 if (m_controlledByAutomation == controlled)
1246 m_controlledByAutomation = controlled;
1249 m_process->send(Messages::WebPage::SetControlledByAutomation(controlled), m_pageID);
1252 #if ENABLE(REMOTE_INSPECTOR)
1253 void WebPageProxy::setAllowsRemoteInspection(bool allow)
1255 if (m_allowsRemoteInspection == allow)
1258 m_allowsRemoteInspection = allow;
1261 m_process->send(Messages::WebPage::SetAllowsRemoteInspection(allow), m_pageID);
1264 void WebPageProxy::setRemoteInspectionNameOverride(const String& name)
1266 if (m_remoteInspectionNameOverride == name)
1269 m_remoteInspectionNameOverride = name;
1272 m_process->send(Messages::WebPage::SetRemoteInspectionNameOverride(m_remoteInspectionNameOverride), m_pageID);
1277 void WebPageProxy::setDrawsBackground(bool drawsBackground)
1279 if (m_drawsBackground == drawsBackground)
1282 m_drawsBackground = drawsBackground;
1285 m_process->send(Messages::WebPage::SetDrawsBackground(drawsBackground), m_pageID);
1288 void WebPageProxy::setTopContentInset(float contentInset)
1290 if (m_topContentInset == contentInset)
1293 m_topContentInset = contentInset;
1298 MachSendRight fence = m_drawingArea->createFence();
1300 auto fenceAttachment = IPC::Attachment(fence.leakSendRight(), MACH_MSG_TYPE_MOVE_SEND);
1301 m_process->send(Messages::WebPage::SetTopContentInsetFenced(contentInset, fenceAttachment), m_pageID);
1303 m_process->send(Messages::WebPage::SetTopContentInset(contentInset), m_pageID);
1307 void WebPageProxy::setUnderlayColor(const Color& color)
1309 if (m_underlayColor == color)
1312 m_underlayColor = color;
1315 m_process->send(Messages::WebPage::SetUnderlayColor(color), m_pageID);
1318 void WebPageProxy::viewWillStartLiveResize()
1322 #if ENABLE(INPUT_TYPE_COLOR_POPOVER) && ENABLE(INPUT_TYPE_COLOR)
1326 m_process->send(Messages::WebPage::ViewWillStartLiveResize(), m_pageID);
1329 void WebPageProxy::viewWillEndLiveResize()
1333 m_process->send(Messages::WebPage::ViewWillEndLiveResize(), m_pageID);
1336 void WebPageProxy::setViewNeedsDisplay(const Region& region)
1338 m_pageClient.setViewNeedsDisplay(region);
1341 void WebPageProxy::requestScroll(const FloatPoint& scrollPosition, const IntPoint& scrollOrigin, bool isProgrammaticScroll)
1343 m_pageClient.requestScroll(scrollPosition, scrollOrigin, isProgrammaticScroll);
1346 WebCore::FloatPoint WebPageProxy::viewScrollPosition() const
1348 return m_pageClient.viewScrollPosition();
1351 void WebPageProxy::setSuppressVisibilityUpdates(bool flag)
1353 if (m_suppressVisibilityUpdates == flag)
1355 m_suppressVisibilityUpdates = flag;
1357 if (!m_suppressVisibilityUpdates) {
1359 m_activityStateChangeDispatcher->schedule();
1361 dispatchActivityStateChange();
1366 void WebPageProxy::updateActivityState(ActivityState::Flags flagsToUpdate)
1368 m_activityState &= ~flagsToUpdate;
1369 if (flagsToUpdate & ActivityState::IsFocused && m_pageClient.isViewFocused())
1370 m_activityState |= ActivityState::IsFocused;
1371 if (flagsToUpdate & ActivityState::WindowIsActive && m_pageClient.isViewWindowActive())
1372 m_activityState |= ActivityState::WindowIsActive;
1373 if (flagsToUpdate & ActivityState::IsVisible && m_pageClient.isViewVisible())
1374 m_activityState |= ActivityState::IsVisible;
1375 if (flagsToUpdate & ActivityState::IsVisibleOrOccluded && m_pageClient.isViewVisibleOrOccluded())
1376 m_activityState |= ActivityState::IsVisibleOrOccluded;
1377 if (flagsToUpdate & ActivityState::IsInWindow && m_pageClient.isViewInWindow())
1378 m_activityState |= ActivityState::IsInWindow;
1379 if (flagsToUpdate & ActivityState::IsVisuallyIdle && m_pageClient.isVisuallyIdle())
1380 m_activityState |= ActivityState::IsVisuallyIdle;
1381 if (flagsToUpdate & ActivityState::IsAudible && m_mediaState & MediaProducer::IsPlayingAudio && !(m_mutedState & MediaProducer::AudioIsMuted))
1382 m_activityState |= ActivityState::IsAudible;
1383 if (flagsToUpdate & ActivityState::IsLoading && m_pageLoadState.isLoading())
1384 m_activityState |= ActivityState::IsLoading;
1385 if (flagsToUpdate & ActivityState::IsCapturingMedia && m_mediaState & (MediaProducer::HasActiveAudioCaptureDevice | MediaProducer::HasActiveVideoCaptureDevice))
1386 m_activityState |= ActivityState::IsCapturingMedia;
1389 void WebPageProxy::activityStateDidChange(ActivityState::Flags mayHaveChanged, bool wantsSynchronousReply, ActivityStateChangeDispatchMode dispatchMode)
1391 m_potentiallyChangedActivityStateFlags |= mayHaveChanged;
1392 m_activityStateChangeWantsSynchronousReply = m_activityStateChangeWantsSynchronousReply || wantsSynchronousReply;
1394 if (m_suppressVisibilityUpdates && dispatchMode != ActivityStateChangeDispatchMode::Immediate)
1398 bool isNewlyInWindow = !isInWindow() && (mayHaveChanged & ActivityState::IsInWindow) && m_pageClient.isViewInWindow();
1399 if (dispatchMode == ActivityStateChangeDispatchMode::Immediate || isNewlyInWindow) {
1400 dispatchActivityStateChange();
1403 m_activityStateChangeDispatcher->schedule();
1405 UNUSED_PARAM(dispatchMode);
1406 dispatchActivityStateChange();
1410 void WebPageProxy::viewDidLeaveWindow()
1412 #if ENABLE(INPUT_TYPE_COLOR_POPOVER) && ENABLE(INPUT_TYPE_COLOR)
1413 // When leaving the current page, close the popover color well.
1417 #if PLATFORM(IOS) && HAVE(AVKIT) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
1418 // When leaving the current page, close the video fullscreen.
1419 if (m_videoFullscreenManager)
1420 m_videoFullscreenManager->requestHideAndExitFullscreen();
1424 void WebPageProxy::viewDidEnterWindow()
1426 LayerHostingMode layerHostingMode = m_pageClient.viewLayerHostingMode();
1427 if (m_layerHostingMode != layerHostingMode) {
1428 m_layerHostingMode = layerHostingMode;
1429 m_process->send(Messages::WebPage::SetLayerHostingMode(layerHostingMode), m_pageID);
1433 void WebPageProxy::dispatchActivityStateChange()
1436 m_activityStateChangeDispatcher->invalidate();
1442 // If the visibility state may have changed, then so may the visually idle & occluded agnostic state.
1443 if (m_potentiallyChangedActivityStateFlags & ActivityState::IsVisible)
1444 m_potentiallyChangedActivityStateFlags |= ActivityState::IsVisibleOrOccluded | ActivityState::IsVisuallyIdle;
1446 // Record the prior view state, update the flags that may have changed,
1447 // and check which flags have actually changed.
1448 ActivityState::Flags previousActivityState = m_activityState;
1449 updateActivityState(m_potentiallyChangedActivityStateFlags);
1450 ActivityState::Flags changed = m_activityState ^ previousActivityState;
1452 if ((m_potentiallyChangedActivityStateFlags & ActivityState::IsVisible) && isViewVisible())
1453 viewIsBecomingVisible();
1455 bool isNowInWindow = (changed & ActivityState::IsInWindow) && isInWindow();
1456 // We always want to wait for the Web process to reply if we've been in-window before and are coming back in-window.
1457 if (m_viewWasEverInWindow && isNowInWindow) {
1458 if (m_drawingArea->hasVisibleContent() && m_waitsForPaintAfterViewDidMoveToWindow && !m_shouldSkipWaitingForPaintAfterNextViewDidMoveToWindow)
1459 m_activityStateChangeWantsSynchronousReply = true;
1460 m_shouldSkipWaitingForPaintAfterNextViewDidMoveToWindow = false;
1463 // Don't wait synchronously if the view state is not visible. (This matters in particular on iOS, where a hidden page may be suspended.)
1464 if (!(m_activityState & ActivityState::IsVisible))
1465 m_activityStateChangeWantsSynchronousReply = false;
1467 if (changed || m_activityStateChangeWantsSynchronousReply || !m_nextActivityStateChangeCallbacks.isEmpty())
1468 m_process->send(Messages::WebPage::SetActivityState(m_activityState, m_activityStateChangeWantsSynchronousReply, m_nextActivityStateChangeCallbacks), m_pageID);
1470 m_nextActivityStateChangeCallbacks.clear();
1472 // This must happen after the SetActivityState message is sent, to ensure the page visibility event can fire.
1473 updateThrottleState();
1475 #if ENABLE(POINTER_LOCK)
1476 if (((changed & ActivityState::IsVisible) && !isViewVisible()) || ((changed & ActivityState::WindowIsActive) && !m_pageClient.isViewWindowActive())
1477 || ((changed & ActivityState::IsFocused) && !(m_activityState & ActivityState::IsFocused)))
1478 requestPointerUnlock();
1481 if (changed & ActivityState::IsVisible) {
1482 if (isViewVisible())
1483 m_visiblePageToken = m_process->visiblePageToken();
1485 m_visiblePageToken = nullptr;
1487 // If we've started the responsiveness timer as part of telling the web process to update the backing store
1488 // state, it might not send back a reply (since it won't paint anything if the web page is hidden) so we
1489 // stop the unresponsiveness timer here.
1490 m_process->responsivenessTimer().stop();
1494 if (changed & ActivityState::IsInWindow) {
1496 viewDidEnterWindow();
1498 viewDidLeaveWindow();
1501 updateBackingStoreDiscardableState();
1503 if (m_activityStateChangeWantsSynchronousReply)
1504 waitForDidUpdateActivityState();
1506 m_potentiallyChangedActivityStateFlags = ActivityState::NoFlags;
1507 m_activityStateChangeWantsSynchronousReply = false;
1508 m_viewWasEverInWindow |= isNowInWindow;
1511 bool WebPageProxy::isAlwaysOnLoggingAllowed() const
1513 return sessionID().isAlwaysOnLoggingAllowed();
1516 void WebPageProxy::updateThrottleState()
1518 bool processSuppressionEnabled = m_preferences->pageVisibilityBasedProcessSuppressionEnabled();
1520 // If process suppression is not enabled take a token on the process pool to disable suppression of support processes.
1521 if (!processSuppressionEnabled)
1522 m_preventProcessSuppressionCount = m_process->processPool().processSuppressionDisabledForPageCount();
1523 else if (!m_preventProcessSuppressionCount)
1524 m_preventProcessSuppressionCount = nullptr;
1526 if (m_activityState & ActivityState::IsVisuallyIdle)
1527 m_pageIsUserObservableCount = nullptr;
1528 else if (!m_pageIsUserObservableCount)
1529 m_pageIsUserObservableCount = m_process->processPool().userObservablePageCount();
1532 bool isCapturingMedia = m_activityState & ActivityState::IsCapturingMedia;
1533 bool isAudible = m_activityState & ActivityState::IsAudible;
1534 if (!isViewVisible() && !m_alwaysRunsAtForegroundPriority && !isCapturingMedia && !isAudible) {
1535 if (m_activityToken) {
1536 RELEASE_LOG_IF_ALLOWED(ProcessSuspension, "%p - UIProcess is releasing a foreground assertion because the view is no longer visible", this);
1537 m_activityToken = nullptr;
1539 } else if (!m_activityToken) {
1540 if (isViewVisible())
1541 RELEASE_LOG_IF_ALLOWED(ProcessSuspension, "%p - UIProcess is taking a foreground assertion because the view is visible", this);
1543 RELEASE_LOG_IF_ALLOWED(ProcessSuspension, "%p - UIProcess is taking a foreground assertion because we are playing audio", this);
1544 else if (isCapturingMedia)
1545 RELEASE_LOG_IF_ALLOWED(ProcessSuspension, "%p - UIProcess is taking a foreground assertion because media capture is active", this);
1547 RELEASE_LOG_IF_ALLOWED(ProcessSuspension, "%p - UIProcess is taking a foreground assertion even though the view is not visible because m_alwaysRunsAtForegroundPriority is true", this);
1548 m_activityToken = m_process->throttler().foregroundActivityToken();
1553 void WebPageProxy::updateHiddenPageThrottlingAutoIncreases()
1555 if (!m_preferences->hiddenPageDOMTimerThrottlingAutoIncreases())
1556 m_hiddenPageDOMTimerThrottlingAutoIncreasesCount = nullptr;
1557 else if (!m_hiddenPageDOMTimerThrottlingAutoIncreasesCount)
1558 m_hiddenPageDOMTimerThrottlingAutoIncreasesCount = m_process->processPool().hiddenPageThrottlingAutoIncreasesCount();
1561 void WebPageProxy::layerHostingModeDidChange()
1566 LayerHostingMode layerHostingMode = m_pageClient.viewLayerHostingMode();
1567 if (m_layerHostingMode == layerHostingMode)
1570 m_layerHostingMode = layerHostingMode;
1571 m_process->send(Messages::WebPage::SetLayerHostingMode(layerHostingMode), m_pageID);
1574 void WebPageProxy::waitForDidUpdateActivityState()
1579 if (m_process->state() != WebProcessProxy::State::Running)
1582 // If we have previously timed out with no response from the WebProcess, don't block the UIProcess again until it starts responding.
1583 if (m_waitingForDidUpdateActivityState)
1587 // Hail Mary check. Should not be possible (dispatchActivityStateChange should force async if not visible,
1588 // and if visible we should be holding an assertion) - but we should never block on a suspended process.
1589 if (!m_activityToken) {
1590 ASSERT_NOT_REACHED();
1595 m_waitingForDidUpdateActivityState = true;
1597 m_drawingArea->waitForDidUpdateActivityState();
1600 IntSize WebPageProxy::viewSize() const
1602 return m_pageClient.viewSize();
1605 void WebPageProxy::setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent& keyboardEvent, WTF::Function<void (CallbackBase::Error)>&& callbackFunction)
1608 callbackFunction(CallbackBase::Error::OwnerWasInvalidated);
1612 auto callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
1613 m_process->send(Messages::WebPage::SetInitialFocus(forward, isKeyboardEventValid, keyboardEvent, callbackID), m_pageID);
1616 void WebPageProxy::clearSelection()
1620 m_process->send(Messages::WebPage::ClearSelection(), m_pageID);
1623 void WebPageProxy::restoreSelectionInFocusedEditableElement()
1627 m_process->send(Messages::WebPage::RestoreSelectionInFocusedEditableElement(), m_pageID);
1630 void WebPageProxy::validateCommand(const String& commandName, WTF::Function<void (const String&, bool, int32_t, CallbackBase::Error)>&& callbackFunction)
1633 callbackFunction(String(), false, 0, CallbackBase::Error::Unknown);
1637 auto callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
1638 m_process->send(Messages::WebPage::ValidateCommand(commandName, callbackID), m_pageID);
1641 void WebPageProxy::setMaintainsInactiveSelection(bool newValue)
1643 m_maintainsInactiveSelection = newValue;
1646 void WebPageProxy::executeEditCommand(const String& commandName, const String& argument, WTF::Function<void(CallbackBase::Error)>&& callbackFunction)
1649 callbackFunction(CallbackBase::Error::Unknown);
1653 auto callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
1654 m_process->send(Messages::WebPage::ExecuteEditCommandWithCallback(commandName, argument, callbackID), m_pageID);
1657 void WebPageProxy::executeEditCommand(const String& commandName, const String& argument)
1659 static NeverDestroyed<String> ignoreSpellingCommandName(MAKE_STATIC_STRING_IMPL("ignoreSpelling"));
1664 if (commandName == ignoreSpellingCommandName)
1665 ++m_pendingLearnOrIgnoreWordMessageCount;
1667 m_process->send(Messages::WebPage::ExecuteEditCommand(commandName, argument), m_pageID);
1670 void WebPageProxy::setEditable(bool editable)
1672 if (editable == m_isEditable)
1677 m_isEditable = editable;
1678 m_process->send(Messages::WebPage::SetEditable(editable), m_pageID);
1681 void WebPageProxy::setMediaStreamCaptureMuted(bool muted)
1684 setMuted(m_mutedState | WebCore::MediaProducer::CaptureDevicesAreMuted);
1686 setMuted(m_mutedState & ~WebCore::MediaProducer::CaptureDevicesAreMuted);
1689 void WebPageProxy::activateMediaStreamCaptureInPage()
1691 #if ENABLE(MEDIA_STREAM)
1692 UserMediaProcessManager::singleton().muteCaptureMediaStreamsExceptIn(*this);
1694 setMuted(m_mutedState & ~WebCore::MediaProducer::CaptureDevicesAreMuted);
1698 void WebPageProxy::didCommitLayerTree(const RemoteLayerTreeTransaction&)
1702 void WebPageProxy::layerTreeCommitComplete()
1707 #if ENABLE(DRAG_SUPPORT)
1708 void WebPageProxy::dragEntered(DragData& dragData, const String& dragStorageName)
1710 SandboxExtension::Handle sandboxExtensionHandle;
1711 SandboxExtension::HandleArray sandboxExtensionHandleEmptyArray;
1712 performDragControllerAction(DragControllerAction::Entered, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionHandleEmptyArray);
1715 void WebPageProxy::dragUpdated(DragData& dragData, const String& dragStorageName)
1717 SandboxExtension::Handle sandboxExtensionHandle;
1718 SandboxExtension::HandleArray sandboxExtensionHandleEmptyArray;
1719 performDragControllerAction(DragControllerAction::Updated, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionHandleEmptyArray);
1722 void WebPageProxy::dragExited(DragData& dragData, const String& dragStorageName)
1724 SandboxExtension::Handle sandboxExtensionHandle;
1725 SandboxExtension::HandleArray sandboxExtensionHandleEmptyArray;
1726 performDragControllerAction(DragControllerAction::Exited, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionHandleEmptyArray);
1729 void WebPageProxy::performDragOperation(DragData& dragData, const String& dragStorageName, const SandboxExtension::Handle& sandboxExtensionHandle, const SandboxExtension::HandleArray& sandboxExtensionsForUpload)
1731 performDragControllerAction(DragControllerAction::PerformDragOperation, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionsForUpload);
1734 void WebPageProxy::performDragControllerAction(DragControllerAction action, DragData& dragData, const String& dragStorageName, const SandboxExtension::Handle& sandboxExtensionHandle, const SandboxExtension::HandleArray& sandboxExtensionsForUpload)
1739 UNUSED_PARAM(dragStorageName);
1740 UNUSED_PARAM(sandboxExtensionHandle);
1741 UNUSED_PARAM(sandboxExtensionsForUpload);
1743 String url = dragData.asURL();
1745 m_process->assumeReadAccessToBaseURL(url);
1747 ASSERT(dragData.platformData());
1748 WebSelectionData selection(*dragData.platformData());
1749 m_process->send(Messages::WebPage::PerformDragControllerAction(action, dragData.clientPosition(), dragData.globalPosition(), dragData.draggingSourceOperationMask(), selection, dragData.flags()), m_pageID);
1751 m_process->send(Messages::WebPage::PerformDragControllerAction(action, dragData, sandboxExtensionHandle, sandboxExtensionsForUpload), m_pageID);
1755 void WebPageProxy::didPerformDragControllerAction(uint64_t dragOperation, bool mouseIsOverFileInput, unsigned numberOfItemsToBeAccepted, const IntRect& insertionRect)
1757 MESSAGE_CHECK(dragOperation <= DragOperationDelete);
1759 m_currentDragOperation = static_cast<DragOperation>(dragOperation);
1760 m_currentDragIsOverFileInput = mouseIsOverFileInput;
1761 m_currentDragNumberOfFilesToBeAccepted = numberOfItemsToBeAccepted;
1762 setDragCaretRect(insertionRect);
1766 void WebPageProxy::startDrag(WebSelectionData&& selection, uint64_t dragOperation, const ShareableBitmap::Handle& dragImageHandle)
1768 RefPtr<ShareableBitmap> dragImage = !dragImageHandle.isNull() ? ShareableBitmap::create(dragImageHandle) : nullptr;
1769 m_pageClient.startDrag(WTFMove(selection.selectionData), static_cast<WebCore::DragOperation>(dragOperation), WTFMove(dragImage));
1775 void WebPageProxy::dragEnded(const IntPoint& clientPosition, const IntPoint& globalPosition, uint64_t operation)
1779 m_process->send(Messages::WebPage::DragEnded(clientPosition, globalPosition, operation), m_pageID);
1780 setDragCaretRect({ });
1783 void WebPageProxy::didStartDrag()
1786 m_process->send(Messages::WebPage::DidStartDrag(), m_pageID);
1789 void WebPageProxy::dragCancelled()
1792 m_process->send(Messages::WebPage::DragCancelled(), m_pageID);
1795 void WebPageProxy::didEndDragging()
1797 resetCurrentDragInformation();
1800 void WebPageProxy::resetCurrentDragInformation()
1802 m_currentDragOperation = WebCore::DragOperationNone;
1803 m_currentDragIsOverFileInput = false;
1804 m_currentDragNumberOfFilesToBeAccepted = 0;
1805 setDragCaretRect({ });
1808 #if !ENABLE(DATA_INTERACTION)
1810 void WebPageProxy::setDragCaretRect(const IntRect& dragCaretRect)
1812 m_currentDragCaretRect = dragCaretRect;
1817 #endif // ENABLE(DRAG_SUPPORT)
1819 void WebPageProxy::handleMouseEvent(const NativeWebMouseEvent& event)
1824 if (m_pageClient.windowIsFrontWindowUnderMouse(event))
1825 setToolTip(String());
1827 // NOTE: This does not start the responsiveness timer because mouse move should not indicate interaction.
1828 if (event.type() != WebEvent::MouseMove)
1829 m_process->responsivenessTimer().start();
1831 if (m_processingMouseMoveEvent) {
1832 m_nextMouseMoveEvent = std::make_unique<NativeWebMouseEvent>(event);
1836 m_processingMouseMoveEvent = true;
1839 // <https://bugs.webkit.org/show_bug.cgi?id=57904> We need to keep track of the mouse down event in the case where we
1840 // display a popup menu for select elements. When the user changes the selected item,
1841 // we fake a mouse up event by using this stored down event. This event gets cleared
1842 // when the mouse up message is received from WebProcess.
1843 if (event.type() == WebEvent::MouseDown)
1844 m_currentlyProcessedMouseDownEvent = std::make_unique<NativeWebMouseEvent>(event);
1846 m_process->send(Messages::WebPage::MouseEvent(event), m_pageID);
1849 #if MERGE_WHEEL_EVENTS
1850 static bool canCoalesce(const WebWheelEvent& a, const WebWheelEvent& b)
1852 if (a.position() != b.position())
1854 if (a.globalPosition() != b.globalPosition())
1856 if (a.modifiers() != b.modifiers())
1858 if (a.granularity() != b.granularity())
1861 if (a.phase() != b.phase())
1863 if (a.momentumPhase() != b.momentumPhase())
1865 if (a.hasPreciseScrollingDeltas() != b.hasPreciseScrollingDeltas())
1872 static WebWheelEvent coalesce(const WebWheelEvent& a, const WebWheelEvent& b)
1874 ASSERT(canCoalesce(a, b));
1876 FloatSize mergedDelta = a.delta() + b.delta();
1877 FloatSize mergedWheelTicks = a.wheelTicks() + b.wheelTicks();
1880 FloatSize mergedUnacceleratedScrollingDelta = a.unacceleratedScrollingDelta() + b.unacceleratedScrollingDelta();
1882 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());
1884 return WebWheelEvent(WebEvent::Wheel, b.position(), b.globalPosition(), mergedDelta, mergedWheelTicks, b.granularity(), b.modifiers(), b.timestamp());
1887 #endif // MERGE_WHEEL_EVENTS
1889 static WebWheelEvent coalescedWheelEvent(Deque<NativeWebWheelEvent>& queue, Vector<NativeWebWheelEvent>& coalescedEvents)
1891 ASSERT(!queue.isEmpty());
1892 ASSERT(coalescedEvents.isEmpty());
1894 #if MERGE_WHEEL_EVENTS
1895 NativeWebWheelEvent firstEvent = queue.takeFirst();
1896 coalescedEvents.append(firstEvent);
1898 WebWheelEvent event = firstEvent;
1899 while (!queue.isEmpty() && canCoalesce(event, queue.first())) {
1900 NativeWebWheelEvent firstEvent = queue.takeFirst();
1901 coalescedEvents.append(firstEvent);
1902 event = coalesce(event, firstEvent);
1907 while (!queue.isEmpty())
1908 coalescedEvents.append(queue.takeFirst());
1909 return coalescedEvents.last();
1913 void WebPageProxy::handleWheelEvent(const NativeWebWheelEvent& event)
1915 #if ENABLE(ASYNC_SCROLLING)
1916 if (m_scrollingCoordinatorProxy && m_scrollingCoordinatorProxy->handleWheelEvent(platform(event)))
1923 hideValidationMessage();
1925 if (!m_currentlyProcessedWheelEvents.isEmpty()) {
1926 m_wheelEventQueue.append(event);
1927 if (!shouldProcessWheelEventNow(event))
1929 // The queue has too many wheel events, so push a new event.
1932 if (!m_wheelEventQueue.isEmpty()) {
1933 processNextQueuedWheelEvent();
1937 auto coalescedWheelEvent = std::make_unique<Vector<NativeWebWheelEvent>>();
1938 coalescedWheelEvent->append(event);
1939 m_currentlyProcessedWheelEvents.append(WTFMove(coalescedWheelEvent));
1940 sendWheelEvent(event);
1943 void WebPageProxy::processNextQueuedWheelEvent()
1945 auto nextCoalescedEvent = std::make_unique<Vector<NativeWebWheelEvent>>();
1946 WebWheelEvent nextWheelEvent = coalescedWheelEvent(m_wheelEventQueue, *nextCoalescedEvent.get());
1947 m_currentlyProcessedWheelEvents.append(WTFMove(nextCoalescedEvent));
1948 sendWheelEvent(nextWheelEvent);
1951 void WebPageProxy::sendWheelEvent(const WebWheelEvent& event)
1954 Messages::EventDispatcher::WheelEvent(
1957 shouldUseImplicitRubberBandControl() ? !m_backForwardList->backItem() : rubberBandsAtLeft(),
1958 shouldUseImplicitRubberBandControl() ? !m_backForwardList->forwardItem() : rubberBandsAtRight(),
1960 rubberBandsAtBottom()
1963 // Manually ping the web process to check for responsiveness since our wheel
1964 // event will dispatch to a non-main thread, which always responds.
1965 m_process->isResponsive(nullptr);
1968 bool WebPageProxy::shouldProcessWheelEventNow(const WebWheelEvent& event) const
1971 // Don't queue events representing a non-trivial scrolling phase to
1972 // avoid having them trapped in the queue, potentially preventing a
1973 // scrolling session to beginning or end correctly.
1974 // This is only needed by platforms whose WebWheelEvent has this phase
1975 // information (Cocoa and GTK+) but Cocoa was fine without it.
1976 if (event.phase() == WebWheelEvent::Phase::PhaseNone
1977 || event.phase() == WebWheelEvent::Phase::PhaseChanged
1978 || event.momentumPhase() == WebWheelEvent::Phase::PhaseNone
1979 || event.momentumPhase() == WebWheelEvent::Phase::PhaseChanged)
1982 UNUSED_PARAM(event);
1984 if (m_wheelEventQueue.size() >= wheelEventQueueSizeThreshold)
1989 void WebPageProxy::handleKeyboardEvent(const NativeWebKeyboardEvent& event)
1994 LOG(KeyHandling, "WebPageProxy::handleKeyboardEvent: %s", webKeyboardEventTypeString(event.type()));
1996 m_keyEventQueue.append(event);
1998 m_process->responsivenessTimer().start();
1999 if (m_keyEventQueue.size() == 1) { // Otherwise, sent from DidReceiveEvent message handler.
2000 LOG(KeyHandling, " UI process: sent keyEvent from handleKeyboardEvent");
2001 m_process->send(Messages::WebPage::KeyEvent(event), m_pageID);
2005 WebPreferencesStore WebPageProxy::preferencesStore() const
2007 if (m_configurationPreferenceValues.isEmpty())
2008 return m_preferences->store();
2010 WebPreferencesStore store = m_preferences->store();
2011 for (const auto& preference : m_configurationPreferenceValues)
2012 store.m_values.set(preference.key, preference.value);
2017 #if ENABLE(NETSCAPE_PLUGIN_API)
2018 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)
2020 PageClientProtector protector(m_pageClient);
2022 MESSAGE_CHECK_URL(urlString);
2024 newMimeType = mimeType.convertToASCIILowercase();
2025 pluginLoadPolicy = PluginModuleLoadNormally;
2027 PluginData::AllowedPluginTypes allowedPluginTypes = allowOnlyApplicationPlugins ? PluginData::OnlyApplicationPlugins : PluginData::AllPlugins;
2028 PluginModuleInfo plugin = m_process->processPool().pluginInfoStore().findPlugin(newMimeType, URL(URL(), urlString), allowedPluginTypes);
2030 pluginProcessToken = 0;
2034 pluginLoadPolicy = PluginInfoStore::defaultLoadPolicyForPlugin(plugin);
2037 RefPtr<API::Dictionary> pluginInformation = createPluginInformationDictionary(plugin, frameURLString, String(), pageURLString, String(), String());
2038 if (m_navigationClient)
2039 pluginLoadPolicy = m_navigationClient->decidePolicyForPluginLoad(*this, static_cast<PluginModuleLoadPolicy>(pluginLoadPolicy), pluginInformation.get(), unavailabilityDescription);
2041 pluginLoadPolicy = m_loaderClient->pluginLoadPolicy(*this, static_cast<PluginModuleLoadPolicy>(pluginLoadPolicy), pluginInformation.get(), unavailabilityDescription);
2043 UNUSED_PARAM(frameURLString);
2044 UNUSED_PARAM(pageURLString);
2045 UNUSED_PARAM(unavailabilityDescription);
2048 PluginProcessSandboxPolicy pluginProcessSandboxPolicy = PluginProcessSandboxPolicyNormal;
2049 switch (pluginLoadPolicy) {
2050 case PluginModuleLoadNormally:
2051 pluginProcessSandboxPolicy = PluginProcessSandboxPolicyNormal;
2053 case PluginModuleLoadUnsandboxed:
2054 pluginProcessSandboxPolicy = PluginProcessSandboxPolicyUnsandboxed;
2057 case PluginModuleBlockedForSecurity:
2058 case PluginModuleBlockedForCompatibility:
2059 pluginProcessToken = 0;
2063 pluginProcessToken = PluginProcessManager::singleton().pluginProcessToken(plugin, static_cast<PluginProcessType>(processType), pluginProcessSandboxPolicy);
2066 #endif // ENABLE(NETSCAPE_PLUGIN_API)
2068 #if ENABLE(TOUCH_EVENTS)
2070 static TrackingType mergeTrackingTypes(TrackingType a, TrackingType b)
2072 if (static_cast<uintptr_t>(b) > static_cast<uintptr_t>(a))
2077 void WebPageProxy::updateTouchEventTracking(const WebTouchEvent& touchStartEvent)
2079 #if ENABLE(ASYNC_SCROLLING)
2080 const EventNames& names = eventNames();
2081 for (auto& touchPoint : touchStartEvent.touchPoints()) {
2082 IntPoint location = touchPoint.location();
2083 auto updateTrackingType = [this, location](TrackingType& trackingType, const AtomicString& eventName) {
2084 if (trackingType == TrackingType::Synchronous)
2087 TrackingType trackingTypeForLocation = m_scrollingCoordinatorProxy->eventTrackingTypeForPoint(eventName, location);
2089 trackingType = mergeTrackingTypes(trackingType, trackingTypeForLocation);
2091 updateTrackingType(m_touchEventTracking.touchForceChangedTracking, names.touchforcechangeEvent);
2092 updateTrackingType(m_touchEventTracking.touchStartTracking, names.touchstartEvent);
2093 updateTrackingType(m_touchEventTracking.touchMoveTracking, names.touchmoveEvent);
2094 updateTrackingType(m_touchEventTracking.touchEndTracking, names.touchendEvent);
2097 UNUSED_PARAM(touchStartEvent);
2098 m_touchEventTracking.touchForceChangedTracking = TrackingType::Synchronous;
2099 m_touchEventTracking.touchStartTracking = TrackingType::Synchronous;
2100 m_touchEventTracking.touchMoveTracking = TrackingType::Synchronous;
2101 m_touchEventTracking.touchEndTracking = TrackingType::Synchronous;
2102 #endif // ENABLE(ASYNC_SCROLLING)
2105 TrackingType WebPageProxy::touchEventTrackingType(const WebTouchEvent& touchStartEvent) const
2107 // We send all events if any type is needed, we just do it asynchronously for the types that are not tracked.
2109 // Touch events define a sequence with strong dependencies. For example, we can expect
2110 // a TouchMove to only appear after a TouchStart, and the ids of the touch points is consistent between
2113 // WebCore should not have to set up its state correctly after some events were dismissed.
2114 // For example, we don't want to send a TouchMoved without a TouchPressed.
2115 // We send everything, WebCore updates its internal state and dispatch what is needed to the page.
2116 TrackingType globalTrackingType = m_touchEventTracking.isTrackingAnything() ? TrackingType::Asynchronous : TrackingType::NotTracking;
2118 globalTrackingType = mergeTrackingTypes(globalTrackingType, m_touchEventTracking.touchForceChangedTracking);
2119 for (auto& touchPoint : touchStartEvent.touchPoints()) {
2120 switch (touchPoint.state()) {
2121 case WebPlatformTouchPoint::TouchReleased:
2122 globalTrackingType = mergeTrackingTypes(globalTrackingType, m_touchEventTracking.touchEndTracking);
2124 case WebPlatformTouchPoint::TouchPressed:
2125 globalTrackingType = mergeTrackingTypes(globalTrackingType, m_touchEventTracking.touchStartTracking);
2127 case WebPlatformTouchPoint::TouchMoved:
2128 case WebPlatformTouchPoint::TouchStationary:
2129 globalTrackingType = mergeTrackingTypes(globalTrackingType, m_touchEventTracking.touchMoveTracking);
2131 case WebPlatformTouchPoint::TouchCancelled:
2132 globalTrackingType = mergeTrackingTypes(globalTrackingType, TrackingType::Asynchronous);
2137 return globalTrackingType;
2142 #if ENABLE(MAC_GESTURE_EVENTS)
2143 void WebPageProxy::handleGestureEvent(const NativeWebGestureEvent& event)
2148 m_gestureEventQueue.append(event);
2149 // FIXME: Consider doing some coalescing here.
2150 m_process->responsivenessTimer().start();
2152 m_process->send(Messages::EventDispatcher::GestureEvent(m_pageID, event), 0);
2156 #if ENABLE(IOS_TOUCH_EVENTS)
2157 void WebPageProxy::handleTouchEventSynchronously(NativeWebTouchEvent& event)
2162 TraceScope scope(SyncTouchEventStart, SyncTouchEventEnd);
2164 if (event.type() == WebEvent::TouchStart)
2165 updateTouchEventTracking(event);
2167 TrackingType touchEventsTrackingType = touchEventTrackingType(event);
2168 if (touchEventsTrackingType == TrackingType::NotTracking)
2171 if (touchEventsTrackingType == TrackingType::Asynchronous) {
2172 // We can end up here if a native gesture has not started but the event handlers are passive.
2174 // The client of WebPageProxy asks the event to be sent synchronously since the touch event
2175 // can prevent a native gesture.
2176 // But, here we know that all events handlers that can handle this events are passive.
2177 // We can use asynchronous dispatch and pretend to the client that the page does nothing with the events.
2178 event.setCanPreventNativeGestures(false);
2179 handleTouchEventAsynchronously(event);
2180 didReceiveEvent(event.type(), false);
2184 m_process->responsivenessTimer().start();
2185 bool handled = false;
2186 m_process->sendSync(Messages::WebPage::TouchEventSync(event), Messages::WebPage::TouchEventSync::Reply(handled), m_pageID);
2187 didReceiveEvent(event.type(), handled);
2188 m_pageClient.doneWithTouchEvent(event, handled);
2189 m_process->responsivenessTimer().stop();
2191 if (event.allTouchPointsAreReleased())
2192 m_touchEventTracking.reset();
2195 void WebPageProxy::handleTouchEventAsynchronously(const NativeWebTouchEvent& event)
2200 TrackingType touchEventsTrackingType = touchEventTrackingType(event);
2201 if (touchEventsTrackingType == TrackingType::NotTracking)
2204 m_process->send(Messages::EventDispatcher::TouchEvent(m_pageID, event), 0);
2206 if (event.allTouchPointsAreReleased())
2207 m_touchEventTracking.reset();
2210 #elif ENABLE(TOUCH_EVENTS)
2211 void WebPageProxy::handleTouchEvent(const NativeWebTouchEvent& event)
2216 if (event.type() == WebEvent::TouchStart)
2217 updateTouchEventTracking(event);
2219 if (touchEventTrackingType(event) == TrackingType::NotTracking)
2222 // If the page is suspended, which should be the case during panning, pinching
2223 // and animation on the page itself (kinetic scrolling, tap to zoom) etc, then
2224 // we do not send any of the events to the page even if is has listeners.
2225 if (!m_isPageSuspended) {
2226 m_touchEventQueue.append(event);
2227 m_process->responsivenessTimer().start();
2228 m_process->send(Messages::WebPage::TouchEvent(event), m_pageID);
2230 if (m_touchEventQueue.isEmpty()) {
2231 bool isEventHandled = false;
2232 m_pageClient.doneWithTouchEvent(event, isEventHandled);
2234 // We attach the incoming events to the newest queued event so that all
2235 // the events are delivered in the correct order when the event is dequed.
2236 QueuedTouchEvents& lastEvent = m_touchEventQueue.last();
2237 lastEvent.deferredTouchEvents.append(event);
2241 if (event.allTouchPointsAreReleased())
2242 m_touchEventTracking.reset();
2244 #endif // ENABLE(TOUCH_EVENTS)
2246 void WebPageProxy::scrollBy(ScrollDirection direction, ScrollGranularity granularity)
2251 m_process->send(Messages::WebPage::ScrollBy(direction, granularity), m_pageID);
2254 void WebPageProxy::centerSelectionInVisibleArea()
2259 m_process->send(Messages::WebPage::CenterSelectionInVisibleArea(), m_pageID);
2262 void WebPageProxy::receivedPolicyDecision(PolicyAction action, WebFrameProxy& frame, uint64_t listenerID, API::Navigation* navigation, const WebsitePolicies& websitePolicies)
2267 auto transaction = m_pageLoadState.transaction();
2269 if (action == PolicyIgnore)
2270 m_pageLoadState.clearPendingAPIRequestURL(transaction);
2272 #if ENABLE(DOWNLOAD_ATTRIBUTE)
2273 if (m_syncNavigationActionHasDownloadAttribute && action == PolicyUse)
2274 action = PolicyDownload;
2277 DownloadID downloadID = { };
2278 if (action == PolicyDownload) {
2279 // Create a download proxy.
2280 auto* download = m_process->processPool().createDownloadProxy(m_decidePolicyForResponseRequest, this);
2281 downloadID = download->downloadID();
2282 handleDownloadRequest(download);
2283 m_decidePolicyForResponseRequest = { };
2286 // If we received a policy decision while in decidePolicyForResponse the decision will
2287 // be sent back to the web process by decidePolicyForResponse.
2288 if (m_responsePolicyReply) {
2289 m_responsePolicyReply->send(action, downloadID);
2290 ASSERT(!m_newNavigationID);
2291 m_responsePolicyReply = nullptr;
2295 // If we received a policy decision while in decidePolicyForNavigationAction the decision will
2296 // be sent back to the web process by decidePolicyForNavigationAction.
2297 if (m_navigationActionPolicyReply) {
2298 m_navigationActionPolicyReply->send(m_newNavigationID, action, downloadID, websitePolicies);
2299 m_newNavigationID = 0;
2300 m_navigationActionPolicyReply = nullptr;
2304 m_process->send(Messages::WebPage::DidReceivePolicyDecision(frame.frameID(), listenerID, action, navigation ? navigation->navigationID() : 0, downloadID), m_pageID);
2307 void WebPageProxy::setUserAgent(const String& userAgent)
2309 if (m_userAgent == userAgent)
2311 m_userAgent = userAgent;
2315 m_process->send(Messages::WebPage::SetUserAgent(m_userAgent), m_pageID);
2318 void WebPageProxy::setApplicationNameForUserAgent(const String& applicationName)
2320 if (m_applicationNameForUserAgent == applicationName)
2323 m_applicationNameForUserAgent = applicationName;
2324 if (!m_customUserAgent.isEmpty())
2327 setUserAgent(standardUserAgent(m_applicationNameForUserAgent));
2330 void WebPageProxy::setCustomUserAgent(const String& customUserAgent)
2332 if (m_customUserAgent == customUserAgent)
2335 m_customUserAgent = customUserAgent;
2337 if (m_customUserAgent.isEmpty()) {
2338 setUserAgent(standardUserAgent(m_applicationNameForUserAgent));
2342 setUserAgent(m_customUserAgent);
2345 void WebPageProxy::resumeActiveDOMObjectsAndAnimations()
2347 if (!isValid() || !m_isPageSuspended)
2350 m_isPageSuspended = false;
2352 m_process->send(Messages::WebPage::ResumeActiveDOMObjectsAndAnimations(), m_pageID);
2355 void WebPageProxy::suspendActiveDOMObjectsAndAnimations()
2357 if (!isValid() || m_isPageSuspended)
2360 m_isPageSuspended = true;
2362 m_process->send(Messages::WebPage::SuspendActiveDOMObjectsAndAnimations(), m_pageID);
2365 bool WebPageProxy::supportsTextEncoding() const
2367 // FIXME (118840): We should probably only support this for text documents, not all non-image documents.
2368 return m_mainFrame && !m_mainFrame->isDisplayingStandaloneImageDocument();
2371 void WebPageProxy::setCustomTextEncodingName(const String& encodingName)
2373 if (m_customTextEncodingName == encodingName)
2375 m_customTextEncodingName = encodingName;
2379 m_process->send(Messages::WebPage::SetCustomTextEncodingName(encodingName), m_pageID);
2382 SessionState WebPageProxy::sessionState(WTF::Function<bool (WebBackForwardListItem&)>&& filter) const
2384 SessionState sessionState;
2386 sessionState.backForwardListState = m_backForwardList->backForwardListState(WTFMove(filter));
2388 String provisionalURLString = m_pageLoadState.pendingAPIRequestURL();
2389 if (provisionalURLString.isEmpty())
2390 provisionalURLString = m_pageLoadState.provisionalURL();
2392 if (!provisionalURLString.isEmpty())
2393 sessionState.provisionalURL = URL(URL(), provisionalURLString);
2395 sessionState.renderTreeSize = renderTreeSize();
2396 return sessionState;
2399 RefPtr<API::Navigation> WebPageProxy::restoreFromSessionState(SessionState sessionState, bool navigate)
2401 m_sessionRestorationRenderTreeSize = 0;
2402 m_hitRenderTreeSizeThreshold = false;
2404 bool hasBackForwardList = !!sessionState.backForwardListState.currentIndex;
2406 if (hasBackForwardList) {
2407 m_backForwardList->restoreFromState(WTFMove(sessionState.backForwardListState));
2409 for (const auto& entry : m_backForwardList->entries())
2410 process().registerNewWebBackForwardListItem(entry.get());
2412 process().send(Messages::WebPage::RestoreSession(m_backForwardList->itemStates()), m_pageID);
2414 auto transaction = m_pageLoadState.transaction();
2415 m_pageLoadState.setCanGoBack(transaction, m_backForwardList->backItem());
2416 m_pageLoadState.setCanGoForward(transaction, m_backForwardList->forwardItem());
2418 // The back / forward list was restored from a sessionState so we don't want to snapshot the current
2419 // page when navigating away. Suppress navigation snapshotting until the next load has committed
2420 m_suppressAutomaticNavigationSnapshotting = true;
2423 // FIXME: Navigating should be separate from state restoration.
2425 m_sessionRestorationRenderTreeSize = sessionState.renderTreeSize;
2426 if (!m_sessionRestorationRenderTreeSize)
2427 m_hitRenderTreeSizeThreshold = true; // If we didn't get data on renderTreeSize, just don't fire the milestone.
2429 if (!sessionState.provisionalURL.isNull())
2430 return loadRequest(sessionState.provisionalURL);
2432 if (hasBackForwardList) {
2433 // FIXME: Do we have to null check the back forward list item here?
2434 if (WebBackForwardListItem* item = m_backForwardList->currentItem())
2435 return goToBackForwardItem(item);
2442 bool WebPageProxy::supportsTextZoom() const
2444 // FIXME (118840): This should also return false for standalone media and plug-in documents.
2445 if (!m_mainFrame || m_mainFrame->isDisplayingStandaloneImageDocument())
2451 void WebPageProxy::setTextZoomFactor(double zoomFactor)
2456 if (m_textZoomFactor == zoomFactor)
2459 m_textZoomFactor = zoomFactor;
2460 m_process->send(Messages::WebPage::SetTextZoomFactor(m_textZoomFactor), m_pageID);
2463 void WebPageProxy::setPageZoomFactor(double zoomFactor)
2468 if (m_pageZoomFactor == zoomFactor)
2471 hideValidationMessage();
2473 m_pageZoomFactor = zoomFactor;
2474 m_process->send(Messages::WebPage::SetPageZoomFactor(m_pageZoomFactor), m_pageID);
2477 void WebPageProxy::setPageAndTextZoomFactors(double pageZoomFactor, double textZoomFactor)
2482 if (m_pageZoomFactor == pageZoomFactor && m_textZoomFactor == textZoomFactor)
2485 hideValidationMessage();
2487 m_pageZoomFactor = pageZoomFactor;
2488 m_textZoomFactor = textZoomFactor;
2489 m_process->send(Messages::WebPage::SetPageAndTextZoomFactors(m_pageZoomFactor, m_textZoomFactor), m_pageID);
2492 double WebPageProxy::pageZoomFactor() const
2494 // Zoom factor for non-PDF pages persists across page loads. We maintain a separate member variable for PDF
2495 // zoom which ensures that we don't use the PDF zoom for a normal page.
2496 if (m_mainFramePluginHandlesPageScaleGesture)
2497 return m_pluginZoomFactor;
2498 return m_pageZoomFactor;
2501 double WebPageProxy::pageScaleFactor() const
2503 // PDF documents use zoom and scale factors to size themselves appropriately in the window. We store them
2504 // separately but decide which to return based on the main frame.
2505 if (m_mainFramePluginHandlesPageScaleGesture)
2506 return m_pluginScaleFactor;
2507 return m_pageScaleFactor;
2510 void WebPageProxy::scalePage(double scale, const IntPoint& origin)
2517 m_pageScaleFactor = scale;
2518 m_process->send(Messages::WebPage::ScalePage(scale, origin), m_pageID);
2521 void WebPageProxy::scalePageInViewCoordinates(double scale, const IntPoint& centerInViewCoordinates)
2528 m_pageScaleFactor = scale;
2529 m_process->send(Messages::WebPage::ScalePageInViewCoordinates(scale, centerInViewCoordinates), m_pageID);
2532 void WebPageProxy::scaleView(double scale)
2539 m_viewScaleFactor = scale;
2540 m_process->send(Messages::WebPage::ScaleView(scale), m_pageID);
2543 void WebPageProxy::setIntrinsicDeviceScaleFactor(float scaleFactor)
2545 if (m_intrinsicDeviceScaleFactor == scaleFactor)
2548 m_intrinsicDeviceScaleFactor = scaleFactor;
2551 m_drawingArea->deviceScaleFactorDidChange();
2554 void WebPageProxy::windowScreenDidChange(PlatformDisplayID displayID)
2559 m_process->send(Messages::WebPage::WindowScreenDidChange(displayID), m_pageID);
2562 float WebPageProxy::deviceScaleFactor() const
2564 if (m_customDeviceScaleFactor)
2565 return m_customDeviceScaleFactor;
2566 return m_intrinsicDeviceScaleFactor;
2569 void WebPageProxy::setCustomDeviceScaleFactor(float customScaleFactor)
2574 // FIXME: Remove this once we bump cairo requirements to support HiDPI.
2575 // https://bugs.webkit.org/show_bug.cgi?id=133378
2576 #if USE(CAIRO) && !HAVE(CAIRO_SURFACE_SET_DEVICE_SCALE)
2580 if (m_customDeviceScaleFactor == customScaleFactor)
2583 float oldScaleFactor = deviceScaleFactor();
2585 m_customDeviceScaleFactor = customScaleFactor;
2587 if (deviceScaleFactor() != oldScaleFactor)
2588 m_drawingArea->deviceScaleFactorDidChange();
2591 void WebPageProxy::accessibilitySettingsDidChange()
2596 m_process->send(Messages::WebPage::AccessibilitySettingsDidChange(), m_pageID);
2599 void WebPageProxy::setUseFixedLayout(bool fixed)
2604 // This check is fine as the value is initialized in the web
2605 // process as part of the creation parameters.
2606 if (fixed == m_useFixedLayout)
2609 m_useFixedLayout = fixed;
2611 m_fixedLayoutSize = IntSize();
2612 m_process->send(Messages::WebPage::SetUseFixedLayout(fixed), m_pageID);
2615 void WebPageProxy::setFixedLayoutSize(const IntSize& size)
2620 if (size == m_fixedLayoutSize)
2623 m_fixedLayoutSize = size;
2624 m_process->send(Messages::WebPage::SetFixedLayoutSize(size), m_pageID);
2627 void WebPageProxy::listenForLayoutMilestones(WebCore::LayoutMilestones milestones)
2632 if (milestones == m_observedLayoutMilestones)
2635 m_observedLayoutMilestones = milestones;
2636 m_process->send(Messages::WebPage::ListenForLayoutMilestones(milestones), m_pageID);
2639 void WebPageProxy::setSuppressScrollbarAnimations(bool suppressAnimations)
2644 if (suppressAnimations == m_suppressScrollbarAnimations)
2647 m_suppressScrollbarAnimations = suppressAnimations;
2648 m_process->send(Messages::WebPage::SetSuppressScrollbarAnimations(suppressAnimations), m_pageID);
2651 bool WebPageProxy::rubberBandsAtLeft() const
2653 return m_rubberBandsAtLeft;
2656 void WebPageProxy::setRubberBandsAtLeft(bool rubberBandsAtLeft)
2658 m_rubberBandsAtLeft = rubberBandsAtLeft;
2661 bool WebPageProxy::rubberBandsAtRight() const
2663 return m_rubberBandsAtRight;
2666 void WebPageProxy::setRubberBandsAtRight(bool rubberBandsAtRight)
2668 m_rubberBandsAtRight = rubberBandsAtRight;
2671 bool WebPageProxy::rubberBandsAtTop() const
2673 return m_rubberBandsAtTop;
2676 void WebPageProxy::setRubberBandsAtTop(bool rubberBandsAtTop)
2678 m_rubberBandsAtTop = rubberBandsAtTop;
2681 bool WebPageProxy::rubberBandsAtBottom() const
2683 return m_rubberBandsAtBottom;
2686 void WebPageProxy::setRubberBandsAtBottom(bool rubberBandsAtBottom)
2688 m_rubberBandsAtBottom = rubberBandsAtBottom;
2691 void WebPageProxy::setEnableVerticalRubberBanding(bool enableVerticalRubberBanding)
2693 if (enableVerticalRubberBanding == m_enableVerticalRubberBanding)
2696 m_enableVerticalRubberBanding = enableVerticalRubberBanding;
2700 m_process->send(Messages::WebPage::SetEnableVerticalRubberBanding(enableVerticalRubberBanding), m_pageID);
2703 bool WebPageProxy::verticalRubberBandingIsEnabled() const
2705 return m_enableVerticalRubberBanding;
2708 void WebPageProxy::setEnableHorizontalRubberBanding(bool enableHorizontalRubberBanding)
2710 if (enableHorizontalRubberBanding == m_enableHorizontalRubberBanding)
2713 m_enableHorizontalRubberBanding = enableHorizontalRubberBanding;
2717 m_process->send(Messages::WebPage::SetEnableHorizontalRubberBanding(enableHorizontalRubberBanding), m_pageID);
2720 bool WebPageProxy::horizontalRubberBandingIsEnabled() const
2722 return m_enableHorizontalRubberBanding;
2725 void WebPageProxy::setBackgroundExtendsBeyondPage(bool backgroundExtendsBeyondPage)
2727 if (backgroundExtendsBeyondPage == m_backgroundExtendsBeyondPage)
2730 m_backgroundExtendsBeyondPage = backgroundExtendsBeyondPage;
2734 m_process->send(Messages::WebPage::SetBackgroundExtendsBeyondPage(backgroundExtendsBeyondPage), m_pageID);
2737 bool WebPageProxy::backgroundExtendsBeyondPage() const
2739 return m_backgroundExtendsBeyondPage;
2742 void WebPageProxy::setPaginationMode(WebCore::Pagination::Mode mode)
2744 if (mode == m_paginationMode)
2747 m_paginationMode = mode;
2751 m_process->send(Messages::WebPage::SetPaginationMode(mode), m_pageID);
2754 void WebPageProxy::setPaginationBehavesLikeColumns(bool behavesLikeColumns)
2756 if (behavesLikeColumns == m_paginationBehavesLikeColumns)
2759 m_paginationBehavesLikeColumns = behavesLikeColumns;
2763 m_process->send(Messages::WebPage::SetPaginationBehavesLikeColumns(behavesLikeColumns), m_pageID);
2766 void WebPageProxy::setPageLength(double pageLength)
2768 if (pageLength == m_pageLength)
2771 m_pageLength = pageLength;
2775 m_process->send(Messages::WebPage::SetPageLength(pageLength), m_pageID);
2778 void WebPageProxy::setGapBetweenPages(double gap)
2780 if (gap == m_gapBetweenPages)
2783 m_gapBetweenPages = gap;
2787 m_process->send(Messages::WebPage::SetGapBetweenPages(gap), m_pageID);
2790 void WebPageProxy::setPaginationLineGridEnabled(bool lineGridEnabled)
2792 if (lineGridEnabled == m_paginationLineGridEnabled)
2795 m_paginationLineGridEnabled = lineGridEnabled;
2799 m_process->send(Messages::WebPage::SetPaginationLineGridEnabled(lineGridEnabled), m_pageID);
2802 void WebPageProxy::pageScaleFactorDidChange(double scaleFactor)
2804 m_pageScaleFactor = scaleFactor;
2807 void WebPageProxy::pluginScaleFactorDidChange(double pluginScaleFactor)
2809 m_pluginScaleFactor = pluginScaleFactor;
2812 void WebPageProxy::pluginZoomFactorDidChange(double pluginZoomFactor)
2814 m_pluginZoomFactor = pluginZoomFactor;
2817 void WebPageProxy::findStringMatches(const String& string, FindOptions options, unsigned maxMatchCount)
2819 if (string.isEmpty()) {
2820 didFindStringMatches(string, Vector<Vector<WebCore::IntRect>> (), 0);
2824 m_process->send(Messages::WebPage::FindStringMatches(string, options, maxMatchCount), m_pageID);
2827 void WebPageProxy::findString(const String& string, FindOptions options, unsigned maxMatchCount)
2829 m_process->send(Messages::WebPage::FindString(string, options, maxMatchCount), m_pageID);
2832 void WebPageProxy::getImageForFindMatch(int32_t matchIndex)
2834 m_process->send(Messages::WebPage::GetImageForFindMatch(matchIndex), m_pageID);
2837 void WebPageProxy::selectFindMatch(int32_t matchIndex)
2839 m_process->send(Messages::WebPage::SelectFindMatch(matchIndex), m_pageID);
2842 void WebPageProxy::hideFindUI()
2844 m_process->send(Messages::WebPage::HideFindUI(), m_pageID);
2847 void WebPageProxy::countStringMatches(const String& string, FindOptions options, unsigned maxMatchCount)
2852 m_process->send(Messages::WebPage::CountStringMatches(string, options, maxMatchCount), m_pageID);
2855 void WebPageProxy::runJavaScriptInMainFrame(const String& script, bool forceUserGesture, WTF::Function<void (API::SerializedScriptValue*, bool hadException, const ExceptionDetails&, CallbackBase::Error)>&& callbackFunction)
2858 callbackFunction(nullptr, false, { }, CallbackBase::Error::Unknown);
2862 auto callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
2863 m_process->send(Messages::WebPage::RunJavaScriptInMainFrame(script, forceUserGesture, callbackID), m_pageID);
2866 void WebPageProxy::getRenderTreeExternalRepresentation(WTF::Function<void (const String&, CallbackBase::Error)>&& callbackFunction)
2869 callbackFunction(String(), CallbackBase::Error::Unknown);
2873 auto callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
2874 m_process->send(Messages::WebPage::GetRenderTreeExternalRepresentation(callbackID), m_pageID);
2877 void WebPageProxy::getSourceForFrame(WebFrameProxy* frame, WTF::Function<void (const String&, CallbackBase::Error)>&& callbackFunction)
2880 callbackFunction(String(), CallbackBase::Error::Unknown);
2884 auto callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
2885 m_loadDependentStringCallbackIDs.add(callbackID);
2886 m_process->send(Messages::WebPage::GetSourceForFrame(frame->frameID(), callbackID), m_pageID);
2889 void WebPageProxy::getContentsAsString(WTF::Function<void (const String&, CallbackBase::Error)>&& callbackFunction)
2892 callbackFunction(String(), CallbackBase::Error::Unknown);
2896 auto callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
2897 m_loadDependentStringCallbackIDs.add(callbackID);
2898 m_process->send(Messages::WebPage::GetContentsAsString(callbackID), m_pageID);
2901 void WebPageProxy::getBytecodeProfile(WTF::Function<void (const String&, CallbackBase::Error)>&& callbackFunction)
2904 callbackFunction(String(), CallbackBase::Error::Unknown);
2908 auto callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
2909 m_loadDependentStringCallbackIDs.add(callbackID);
2910 m_process->send(Messages::WebPage::GetBytecodeProfile(callbackID), m_pageID);
2913 void WebPageProxy::getSamplingProfilerOutput(WTF::Function<void (const String&, CallbackBase::Error)>&& callbackFunction)
2916 callbackFunction(String(), CallbackBase::Error::Unknown);
2920 auto callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
2921 m_loadDependentStringCallbackIDs.add(callbackID);
2922 m_process->send(Messages::WebPage::GetSamplingProfilerOutput(callbackID), m_pageID);
2925 void WebPageProxy::isWebProcessResponsive(WTF::Function<void (bool isWebProcessResponsive)>&& callbackFunction)
2928 RunLoop::main().dispatch([callbackFunction = WTFMove(callbackFunction)] {
2929 bool isWebProcessResponsive = true;
2930 callbackFunction(isWebProcessResponsive);
2935 m_process->isResponsive(WTFMove(callbackFunction));
2939 void WebPageProxy::getContentsAsMHTMLData(Function<void (API::Data*, CallbackBase::Error)>&& callbackFunction)
2942 callbackFunction(nullptr, CallbackBase::Error::Unknown);
2946 auto callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
2947 m_process->send(Messages::WebPage::GetContentsAsMHTMLData(callbackID), m_pageID);
2951 void WebPageProxy::getSelectionOrContentsAsString(WTF::Function<void (const String&, CallbackBase::Error)>&& callbackFunction)
2954 callbackFunction(String(), CallbackBase::Error::Unknown);
2958 auto callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
2959 m_process->send(Messages::WebPage::GetSelectionOrContentsAsString(callbackID), m_pageID);
2962 void WebPageProxy::getSelectionAsWebArchiveData(Function<void (API::Data*, CallbackBase::Error)>&& callbackFunction)
2965 callbackFunction(nullptr, CallbackBase::Error::Unknown);
2969 auto callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
2970 m_process->send(Messages::WebPage::GetSelectionAsWebArchiveData(callbackID), m_pageID);
2973 void WebPageProxy::getMainResourceDataOfFrame(WebFrameProxy* frame, Function<void (API::Data*, CallbackBase::Error)>&& callbackFunction)
2975 if (!isValid() || !frame) {
2976 callbackFunction(nullptr, CallbackBase::Error::Unknown);
2980 auto callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
2981 m_process->send(Messages::WebPage::GetMainResourceDataOfFrame(frame->frameID(), callbackID), m_pageID);
2984 void WebPageProxy::getResourceDataFromFrame(WebFrameProxy* frame, API::URL* resourceURL, Function<void (API::Data*, CallbackBase::Error)>&& callbackFunction)
2987 callbackFunction(nullptr, CallbackBase::Error::Unknown);
2991 auto callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
2992 m_process->send(Messages::WebPage::GetResourceDataFromFrame(frame->frameID(), resourceURL->string(), callbackID), m_pageID);
2995 void WebPageProxy::getWebArchiveOfFrame(WebFrameProxy* frame, Function<void (API::Data*, CallbackBase::Error)>&& callbackFunction)
2998 callbackFunction(nullptr, CallbackBase::Error::Unknown);
3002 auto callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
3003 m_process->send(Messages::WebPage::GetWebArchiveOfFrame(frame->frameID(), callbackID), m_pageID);
3006 void WebPageProxy::forceRepaint(RefPtr<VoidCallback>&& callback)
3009 // FIXME: If the page is invalid we should not call the callback. It'd be better to just return false from forceRepaint.
3010 callback->invalidate(CallbackBase::Error::OwnerWasInvalidated);
3014 Function<void(CallbackBase::Error)> didForceRepaintCallback = [this, callback = WTFMove(callback)](CallbackBase::Error error) mutable {
3015 if (error != CallbackBase::Error::None) {
3016 callback->invalidate(error);
3021 callback->invalidate(CallbackBase::Error::OwnerWasInvalidated);
3025 callAfterNextPresentationUpdate([callback = WTFMove(callback)](CallbackBase::Error error) {
3026 if (error != CallbackBase::Error::None) {
3027 callback->invalidate(error);
3031 callback->performCallback();
3035 auto callbackID = m_callbacks.put(WTFMove(didForceRepaintCallback), m_process->throttler().backgroundActivityToken());
3036 m_drawingArea->waitForBackingStoreUpdateOnNextPaint();
3037 m_process->send(Messages::WebPage::ForceRepaint(callbackID), m_pageID);
3040 static OptionSet<IPC::SendOption> printingSendOptions(bool isPerformingDOMPrintOperation)
3042 if (isPerformingDOMPrintOperation)
3043 return IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply;
3048 void WebPageProxy::preferencesDidChange()
3053 updateThrottleState();
3054 updateHiddenPageThrottlingAutoIncreases();
3056 m_pageClient.preferencesDidChange();
3058 // FIXME: It probably makes more sense to send individual preference changes.
3059 // However, WebKitTestRunner depends on getting a preference change notification
3060 // even if nothing changed in UI process, so that overrides get removed.
3062 // Preferences need to be updated during synchronous printing to make "print backgrounds" preference work when toggled from a print dialog checkbox.
3063 m_process->send(Messages::WebPage::PreferencesDidChange(preferencesStore()), m_pageID, printingSendOptions(m_isPerformingDOMPrintOperation));
3066 void WebPageProxy::didCreateMainFrame(uint64_t frameID)
3068 PageClientProtector protector(m_pageClient);
3070 MESSAGE_CHECK(!m_mainFrame);
3071 MESSAGE_CHECK(m_process->canCreateFrame(frameID));
3073 m_mainFrame = WebFrameProxy::create(this, frameID);
3075 // Add the frame to the process wide map.
3076 m_process->frameCreated(frameID, m_mainFrame.get());
3079 void WebPageProxy::didCreateSubframe(uint64_t frameID)
3081 PageClientProtector protector(m_pageClient);
3083 MESSAGE_CHECK(m_mainFrame);
3084 MESSAGE_CHECK(m_process->canCreateFrame(frameID));
3086 RefPtr<WebFrameProxy> subFrame = WebFrameProxy::create(this, frameID);
3088 // Add the frame to the process wide map.
3089 m_process->frameCreated(frameID, subFrame.get());
3092 double WebPageProxy::estimatedProgress() const
3094 return m_pageLoadState.estimatedProgress();
3097 void WebPageProxy::didStartProgress()
3099 PageClientProtector protector(m_pageClient);
3101 auto transaction = m_pageLoadState.transaction();
3102 m_pageLoadState.didStartProgress(transaction);
3104 m_pageLoadState.commitChanges();
3105 m_loaderClient->didStartProgress(*this);
3108 void WebPageProxy::didChangeProgress(double value)
3110 PageClientProtector protector(m_pageClient);
3112 auto transaction = m_pageLoadState.transaction();
3113 m_pageLoadState.didChangeProgress(transaction, value);
3115 m_pageLoadState.commitChanges();
3116 m_loaderClient->didChangeProgress(*this);
3119 void WebPageProxy::didFinishProgress()
3121 PageClientProtector protector(m_pageClient);
3123 auto transaction = m_pageLoadState.transaction();
3124 m_pageLoadState.didFinishProgress(transaction);
3126 m_pageLoadState.commitChanges();
3127 m_loaderClient->didFinishProgress(*this);
3130 void WebPageProxy::setNetworkRequestsInProgress(bool networkRequestsInProgress)
3132 auto transaction = m_pageLoadState.transaction();
3133 m_pageLoadState.setNetworkRequestsInProgress(transaction, networkRequestsInProgress);
3136 void WebPageProxy::hasInsecureContent(HasInsecureContent& hasInsecureContent)
3138 hasInsecureContent = m_pageLoadState.committedHasInsecureContent() ? HasInsecureContent::Yes : HasInsecureContent::No;
3141 void WebPageProxy::didDestroyNavigation(uint64_t navigationID)
3143 PageClientProtector protector(m_pageClient);
3145 // FIXME: Message check the navigationID.
3146 m_navigationState->didDestroyNavigation(navigationID);
3149 void WebPageProxy::didStartProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, WebCore::URL&& url, WebCore::URL&& unreachableURL, const UserData& userData)
3151 PageClientProtector protector(m_pageClient);
3153 auto transaction = m_pageLoadState.transaction();
3155 m_pageLoadState.clearPendingAPIRequestURL(transaction);
3157 WebFrameProxy* frame = m_process->webFrame(frameID);
3158 MESSAGE_CHECK(frame);
3159 MESSAGE_CHECK_URL(url);
3161 // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
3162 RefPtr<API::Navigation> navigation;
3163 if (frame->isMainFrame() && navigationID)
3164 navigation = &navigationState().navigation(navigationID);
3166 if (frame->isMainFrame()) {
3167 m_pageLoadState.didStartProvisionalLoad(transaction, url, unreachableURL);
3168 m_pageClient.didStartProvisionalLoadForMainFrame();
3169 hideValidationMessage();
3172 frame->setUnreachableURL(unreachableURL);
3173 frame->didStartProvisionalLoad(url);
3175 m_pageLoadState.commitChanges();
3176 if (m_navigationClient) {
3177 if (frame->isMainFrame())
3178 m_navigationClient->didStartProvisionalNavigation(*this, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
3180 m_loaderClient->didStartProvisionalLoadForFrame(*this, *frame, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
3183 void WebPageProxy::didReceiveServerRedirectForProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, WebCore::URL&& url, const UserData& userData)
3185 PageClientProtector protector(m_pageClient);
3187 WebFrameProxy* frame = m_process->webFrame(frameID);
3188 MESSAGE_CHECK(frame);
3189 MESSAGE_CHECK_URL(url);
3191 // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
3192 RefPtr<API::Navigation> navigation;
3193 if (frame->isMainFrame() && navigationID)
3194 navigation = &navigationState().navigation(navigationID);
3196 auto transaction = m_pageLoadState.transaction();
3198 if (frame->isMainFrame())
3199 m_pageLoadState.didReceiveServerRedirectForProvisionalLoad(transaction, url);
3201 frame->didReceiveServerRedirectForProvisionalLoad(url);
3203 m_pageLoadState.commitChanges();
3204 if (m_navigationClient) {
3205 if (frame->isMainFrame())
3206 m_navigationClient->didReceiveServerRedirectForProvisionalNavigation(*this, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
3208 m_loaderClient->didReceiveServerRedirectForProvisionalLoadForFrame(*this, *frame, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
3211 void WebPageProxy::willPerformClientRedirectForFrame(uint64_t frameID, const String& url, double delay)
3213 PageClientProtector protector(m_pageClient);
3215 WebFrameProxy* frame = m_process->webFrame(frameID);
3216 MESSAGE_CHECK(frame);
3218 if (m_navigationClient) {
3219 if (frame->isMainFrame())
3220 m_navigationClient->willPerformClientRedirect(*this, url, delay);
3224 void WebPageProxy::didCancelClientRedirectForFrame(uint64_t frameID)
3226 PageClientProtector protector(m_pageClient);
3228 WebFrameProxy* frame = m_process->webFrame(frameID);
3229 MESSAGE_CHECK(frame);
3231 if (m_navigationClient) {
3232 if (frame->isMainFrame())
3233 m_navigationClient->didCancelClientRedirect(*this);
3237 void WebPageProxy::didChangeProvisionalURLForFrame(uint64_t frameID, uint64_t, WebCore::URL&& url)
3239 PageClientProtector protector(m_pageClient);
3241 WebFrameProxy* frame = m_process->webFrame(frameID);
3242 MESSAGE_CHECK(frame);
3243 MESSAGE_CHECK(frame->frameLoadState().state() == FrameLoadState::State::Provisional);
3244 MESSAGE_CHECK_URL(url);
3246 auto transaction = m_pageLoadState.transaction();
3248 // Internally, we handle this the same way we handle a server redirect. There are no client callbacks
3249 // for this, but if this is the main frame, clients may observe a change to the page's URL.
3250 if (frame->isMainFrame())
3251 m_pageLoadState.didReceiveServerRedirectForProvisionalLoad(transaction, url);
3253 frame->didReceiveServerRedirectForProvisionalLoad(url);
3256 void WebPageProxy::didFailProvisionalLoadForFrame(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, const String& provisionalURL, const ResourceError& error, const UserData& userData)
3258 PageClientProtector protector(m_pageClient);
3260 WebFrameProxy* frame = m_process->webFrame(frameID);
3261 MESSAGE_CHECK(frame);
3263 // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
3264 RefPtr<API::Navigation> navigation;
3265 if (frame->isMainFrame() && navigationID)
3266 navigation = navigationState().takeNavigation(navigationID);
3268 auto transaction = m_pageLoadState.transaction();
3270 if (frame->isMainFrame()) {
3271 m_pageLoadState.didFailProvisionalLoad(transaction);
3272 m_pageClient.didFailProvisionalLoadForMainFrame();
3275 frame->didFailProvisionalLoad();
3277 m_pageLoadState.commitChanges();
3279 ASSERT(!m_failingProvisionalLoadURL);
3280 m_failingProvisionalLoadURL = provisionalURL;
3282 if (m_navigationClient) {
3283 if (frame->isMainFrame())
3284 m_navigationClient->didFailProvisionalNavigationWithError(*this, *frame, navigation.get(), error, m_process->transformHandlesToObjects(userData.object()).get());
3286 // FIXME: Get the main frame's current navigation.
3287 m_navigationClient->didFailProvisionalLoadInSubframeWithError(*this, *frame, frameSecurityOrigin, nullptr, error, m_process->transformHandlesToObjects(userData.object()).get());
3290 m_loaderClient->didFailProvisionalLoadWithErrorForFrame(*this, *frame, navigation.get(), error, m_process->transformHandlesToObjects(userData.object()).get());
3292 m_failingProvisionalLoadURL = { };
3295 void WebPageProxy::clearLoadDependentCallbacks()
3297 HashSet<CallbackID> loadDependentStringCallbackIDs = WTFMove(m_loadDependentStringCallbackIDs);
3298 for (auto& callbackID : loadDependentStringCallbackIDs) {
3299 if (auto callback = m_callbacks.take<StringCallback>(callbackID))
3300 callback->invalidate();
3304 void WebPageProxy::didCommitLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& mimeType, bool frameHasCustomContentProvider, uint32_t opaqueFrameLoadType, const WebCore::CertificateInfo& certificateInfo, bool containsPluginDocument, std::optional<HasInsecureContent> hasInsecureContent, const UserData& userData)
3306 PageClientProtector protector(m_pageClient);
3308 WebFrameProxy* frame = m_process->webFrame(frameID);
3309 MESSAGE_CHECK(frame);
3311 // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
3312 RefPtr<API::Navigation> navigation;
3313 if (frame->isMainFrame() && navigationID)
3314 navigation = &navigationState().navigation(navigationID);
3317 if (frame->isMainFrame()) {
3318 m_hasReceivedLayerTreeTransactionAfterDidCommitLoad = false;
3319 m_firstLayerTreeTransactionIdAfterDidCommitLoad = downcast<RemoteLayerTreeDrawingAreaProxy>(*drawingArea()).nextLayerTreeTransactionID();
3323 auto transaction = m_pageLoadState.transaction();
3324 Ref<WebCertificateInfo> webCertificateInfo = WebCertificateInfo::create(certificateInfo);
3325 bool markPageInsecure = hasInsecureContent ? hasInsecureContent.value() == HasInsecureContent::Yes : m_treatsSHA1CertificatesAsInsecure && certificateInfo.containsNonRootSHA1SignedCertificate();
3327 if (frame->isMainFrame()) {
3328 m_pageLoadState.didCommitLoad(transaction, webCertificateInfo, markPageInsecure);
3329 m_suppressAutomaticNavigationSnapshotting = false;
3330 } else if (markPageInsecure)
3331 m_pageLoadState.didDisplayOrRunInsecureContent(transaction);
3334 // FIXME (bug 59111): didCommitLoadForFrame comes too late when restoring a page from b/f cache, making us disable secure event mode in password fields.
3335 // FIXME: A load going on in one frame shouldn't affect text editing in other frames on the page.
3336 m_pageClient.resetSecureInputState();
3339 clearLoadDependentCallbacks();
3341 frame->didCommitLoad(mimeType, webCertificateInfo, containsPluginDocument);
3343 if (frame->isMainFrame()) {
3344 m_mainFrameHasCustomContentProvider = frameHasCustomContentProvider;
3346 if (m_mainFrameHasCustomContentProvider) {
3347 // Always assume that the main frame is pinned here, since the custom representation view will handle
3348 // any wheel events and dispatch them to the WKView when necessary.
3349 m_mainFrameIsPinnedToLeftSide = true;
3350 m_mainFrameIsPinnedToRightSide = true;
3351 m_mainFrameIsPinnedToTopSide = true;
3352 m_mainFrameIsPinnedToBottomSide = true;
3354 m_uiClient->pinnedStateDidChange(*this);
3356 m_pageClient.didCommitLoadForMainFrame(mimeType, frameHasCustomContentProvider);
3359 // Even if WebPage has the default pageScaleFactor (and therefore doesn't reset it),
3360 // WebPageProxy's cache of the value can get out of sync (e.g. in the case where a
3361 // plugin is handling page scaling itself) so we should reset it to the default
3362 // for standard main frame loads.
3363 if (frame->isMainFrame()) {
3364 if (static_cast<FrameLoadType>(opaqueFrameLoadType) == FrameLoadType::Standard) {
3365 m_pageScaleFactor = 1;
3366 m_pluginScaleFactor = 1;
3367 m_mainFramePluginHandlesPageScaleGesture = false;
3371 #if ENABLE(POINTER_LOCK)
3372 if (frame->isMainFrame())
3373 requestPointerUnlock();
3376 m_pageLoadState.commitChanges();
3377 if (m_navigationClient) {
3378 if (frame->isMainFrame())
3379 m_navigationClient->didCommitNavigation(*this, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
3381 m_loaderClient->didCommitLoadForFrame(*this, *frame, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
3384 void WebPageProxy::didFinishDocumentLoadForFrame(uint64_t frameID, uint64_t navigationID, const UserData& userData)
3386 PageClientProtector protector(m_pageClient);
3388 WebFrameProxy* frame = m_process->webFrame(frameID);
3389 MESSAGE_CHECK(frame);
3391 if (m_controlledByAutomation) {
3392 if (auto* automationSession = process().processPool().automationSession())
3393 automationSession->documentLoadedForFrame(*frame);
3396 // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
3397 RefPtr<API::Navigation> navigation;
3398 if (frame->isMainFrame() && navigationID)
3399 navigation = &navigationState().navigation(navigationID);
3401 if (m_navigationClient) {
3402 if (frame->isMainFrame())
3403 m_navigationClient->didFinishDocumentLoad(*this, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
3405 m_loaderClient->didFinishDocumentLoadForFrame(*this, *frame, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
3408 void WebPageProxy::didFinishLoadForFrame(uint64_t frameID, uint64_t navigationID, const UserData& userData)
3410 PageClientProtector protector(m_pageClient);
3412 WebFrameProxy* frame = m_process->webFrame(frameID);
3413 MESSAGE_CHECK(frame);
3415 // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
3416 RefPtr<API::Navigation> navigation;
3417 if (frame->isMainFrame() && navigationID)
3418 navigation = &navigationState().navigation(navigationID);
3420 auto transaction = m_pageLoadState.transaction();
3422 bool isMainFrame = frame->isMainFrame();
3424 m_pageLoadState.didFinishLoad(transaction);
3426 if (m_controlledByAutomation) {
3427 if (auto* automationSession = process().processPool().automationSession())
3428 automationSession->navigationOccurredForFrame(*frame);
3431 frame->didFinishLoad();
3433 m_pageLoadState.commitChanges();
3434 if (m_navigationClient) {
3436 m_navigationClient->didFinishNavigation(*this, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
3438 m_loaderClient->didFinishLoadForFrame(*this, *frame, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
3441 m_pageClient.didFinishLoadForMainFrame();
3443 m_isLoadingAlternateHTMLStringForFailingProvisionalLoad = false;
3446 void WebPageProxy::didFailLoadForFrame(uint64_t frameID, uint64_t navigationID, const ResourceError& error, const UserData& userData)
3448 PageClientProtector protector(m_pageClient);
3450 WebFrameProxy* frame = m_process->webFrame(frameID);
3451 MESSAGE_CHECK(frame);
3453 // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
3454 RefPtr<API::Navigation> navigation;
3455 if (frame->isMainFrame() && navigationID)
3456 navigation = &navigationState().navigation(navigationID);
3458 clearLoadDependentCallbacks();
3460 auto transaction = m_pageLoadState.transaction();
3462 bool isMainFrame = frame->isMainFrame();
3465 m_pageLoadState.didFailLoad(transaction);
3467 if (m_controlledByAutomation) {
3468 if (auto* automationSession = process().processPool().automationSession())
3469 automationSession->navigationOccurredForFrame(*frame);
3472 frame->didFailLoad();
3474 m_pageLoadState.commitChanges();
3475 if (m_navigationClient) {
3476 if (frame->isMainFrame())
3477 m_navigationClient->didFailNavigationWithError(*this, *frame, navigation.get(), error, m_process->transformHandlesToObjects(userData.object()).get());
3479 m_loaderClient->didFailLoadWithErrorForFrame(*this, *frame, navigation.get(), error, m_process->transformHandlesToObjects(userData.object()).get());
3482 m_pageClient.didFailLoadForMainFrame();
3485 void WebPageProxy::didSameDocumentNavigationForFrame(uint64_t frameID, uint64_t navigationID, uint32_t opaqueSameDocumentNavigationType, WebCore::URL&& url, const UserData& userData)
3487 PageClientProtector protector(m_pageClient);
3489 WebFrameProxy* frame = m_process->webFrame(frameID);
3490 MESSAGE_CHECK(frame);
3491 MESSAGE_CHECK_URL(url);
3493 // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
3494 RefPtr<API::Navigation> navigation;
3495 if (frame->isMainFrame() && navigationID)
3496 navigation = &navigationState().navigation(navigationID);
3498 auto transaction = m_pageLoadState.transaction();
3500 bool isMainFrame = frame->isMainFrame();
3502 m_pageLoadState.didSameDocumentNavigation(transaction, url);
3504 if (m_controlledByAutomation) {
3505 if (auto* automationSession = process().processPool().automationSession())
3506 automationSession->navigationOccurredForFrame(*frame);
3509 m_pageLoadState.clearPendingAPIRequestURL(transaction);
3510 frame->didSameDocumentNavigation(url);
3512 m_pageLoadState.commitChanges();
3514 SameDocumentNavigationType navigationType = static_cast<SameDocumentNavigationType>(opaqueSameDocumentNavigationType);
3515 if (m_navigationClient) {
3517 m_navigationClient->didSameDocumentNavigation(*this, navigation.get(), navigationType, m_process->transformHandlesToObjects(userData.object()).get());
3519 m_loaderClient->didSameDocumentNavigationForFrame(*this, *frame, navigation.get(), navigationType, m_process->transformHandlesToObjects(userData.object()).get());
3522 m_pageClient.didSameDocumentNavigationForMainFrame(navigationType);
3525 void WebPageProxy::didChangeMainDocument(uint64_t frameID)
3527 #if ENABLE(MEDIA_STREAM)
3528 userMediaPermissionRequestManager().resetAccess(frameID);
3530 UNUSED_PARAM(frameID);
3534 void WebPageProxy::viewIsBecomingVisible()
3536 #if ENABLE(MEDIA_STREAM)
3537 userMediaPermissionRequestManager().processPregrantedRequests();
3541 void WebPageProxy::didReceiveTitleForFrame(uint64_t frameID, const String& title, const UserData& userData)
3543 PageClientProtector protector(m_pageClient);
3545 WebFrameProxy* frame = m_process->webFrame(frameID);
3546 MESSAGE_CHECK(frame);
3548 auto transaction = m_pageLoadState.transaction();
3550 if (frame->isMainFrame())
3551 m_pageLoadState.setTitle(transaction, title);
3553 frame->didChangeTitle(title);
3555 m_pageLoadState.commitChanges();
3556 m_loaderClient->didReceiveTitleForFrame(*this, title, *frame, m_process->transformHandlesToObjects(userData.object()).get());
3559 void WebPageProxy::didFirstLayoutForFrame(uint64_t frameID, const UserData& userData)
3561 PageClientProtector protector(m_pageClient);
3563 WebFrameProxy* frame = m_process->webFrame(frameID);
3564 MESSAGE_CHECK(frame);
3566 m_loaderClient->didFirstLayoutForFrame(*this, *frame, m_process->transformHandlesToObjects(userData.object()).get());
3569 void WebPageProxy::didFirstVisuallyNonEmptyLayoutForFrame(uint64_t frameID, const UserData& userData)
3571 PageClientProtector protector(m_pageClient);
3573 WebFrameProxy* frame = m_process->webFrame(frameID);
3574 MESSAGE_CHECK(frame);
3576 m_loaderClient->didFirstVisuallyNonEmptyLayoutForFrame(*this, *frame, m_process->transformHandlesToObjects(userData.object()).get());
3578 if (frame->isMainFrame())
3579 m_pageClient.didFirstVisuallyNonEmptyLayoutForMainFrame();
3582 void WebPageProxy::didLayoutForCustomContentProvider()
3584 didReachLayoutMilestone(DidFirstLayout | DidFirstVisuallyNonEmptyLayout | DidHitRelevantRepaintedObjectsAreaThreshold);
3587 void WebPageProxy::didReachLayoutMilestone(uint32_t layoutMilestones)
3589 PageClientProtector protector(m_pageClient);
3591 if (m_navigationClient)
3592 m_navigationClient->renderingProgressDidChange(*this, static_cast<LayoutMilestones>(layoutMilestones));
3594 m_loaderClient->didReachLayoutMilestone(*this, static_cast<LayoutMilestones>(layoutMilestones));
3597 void WebPageProxy::didDisplayInsecureContentForFrame(uint64_t frameID, const UserData& userData)
3599 PageClientProtector protector(m_pageClient);
3601 WebFrameProxy* frame = m_process->webFrame(frameID);
3602 MESSAGE_CHECK(frame);
3604 auto transaction = m_pageLoadState.transaction();
3605 m_pageLoadState.didDisplayOrRunInsecureContent(transaction);
3607 m_pageLoadState.commitChanges();
3608 m_loaderClient->didDisplayInsecureContentForFrame(*this, *frame, m_process->transformHandlesToObjects(userData.object()).get());
3611 void WebPageProxy::didRunInsecureContentForFrame(uint64_t frameID, const UserData& userData)
3613 PageClientProtector protector(m_pageClient);
3615 WebFrameProxy* frame = m_process->webFrame(frameID);
3616 MESSAGE_CHECK(frame);
3618 auto transaction = m_pageLoadState.transaction();
3619 m_pageLoadState.didDisplayOrRunInsecureContent(transaction);
3621 m_pageLoadState.commitChanges();
3622 m_loaderClient->didRunInsecureContentForFrame(*this, *frame, m_process->transformHandlesToObjects(userData.object()).get());
3625 void WebPageProxy::didDetectXSSForFrame(uint64_t frameID, const UserData& userData)
3627 PageClientProtector protector(m_pageClient);
3629 WebFrameProxy* frame = m_process->webFrame(frameID);
3630 MESSAGE_CHECK(frame);
3632 m_loaderClient->didDetectXSSForFrame(*this, *frame, m_process->transformHandlesToObjects(userData.object()).get());
3635 void WebPageProxy::mainFramePluginHandlesPageScaleGestureDidChange(bool mainFramePluginHandlesPageScaleGesture)
3637 m_mainFramePluginHandlesPageScaleGesture = mainFramePluginHandlesPageScaleGesture;
3640 void WebPageProxy::frameDidBecomeFrameSet(uint64_t frameID, bool value)
3642 PageClientProtector protector(m_pageClient);
3644 WebFrameProxy* frame = m_process->webFrame(frameID);
3645 MESSAGE_CHECK(frame);
3647 frame->setIsFrameSet(value);
3648 if (frame->isMainFrame())
3649 m_frameSetLargestFrame = value ? m_mainFrame : 0;
3652 void WebPageProxy::decidePolicyForNavigationAction(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, NavigationActionData&& navigationActionData, const FrameInfoData& originatingFrameInfoData, uint64_t originatingPageID, const WebCore::ResourceRequest& originalRequest, ResourceRequest&& request, uint64_t listenerID, const UserData& userData, Ref<Messages::WebPageProxy::DecidePolicyForNavigationAction::DelayedReply>&& reply)
3654 PageClientProtector protector(m_pageClient);
3656 auto transaction = m_pageLoadState.transaction();
3658 bool fromAPI = request.url() == m_pageLoadState.pendingAPIRequestURL();
3660 m_pageLoadState.clearPendingAPIRequestURL(transaction);
3662 WebFrameProxy* frame = m_process->webFrame(frameID);
3663 MESSAGE_CHECK(frame);
3664 MESSAGE_CHECK_URL(request.url());
3665 MESSAGE_CHECK_URL(originalRequest.url());
3667 m_newNavigationID = 0;
3668 Ref<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
3669 if (!navigationID && frame->isMainFrame()) {
3670 auto navigation = m_navigationState->createLoadRequestNavigation(ResourceRequest(request));
3671 m_newNavigationID = navigation->navigationID();
3672 listener->setNavigation(WTFMove(navigation));
3675 #if ENABLE(CONTENT_FILTERING)
3676 if (frame->didHandleContentFilterUnblockNavigation(request)) {
3677 reply->send(m_newNavigationID, PolicyIgnore, { }, { });
3678 m_newNavigationID = 0;
3683 #if ENABLE(DOWNLOAD_ATTRIBUTE)
3684 m_syncNavigationActionHasDownloadAttribute = !navigationActionData.downloadAttribute.isNull();
3686 m_navigationActionPolicyReply = WTFMove(reply);
3688 WebFrameProxy* originatingFrame = m_process->webFrame(originatingFrameInfoData.frameID);
3690 if (m_navigationClient) {
3691 auto destinationFrameInfo = API::FrameInfo::create(*frame, frameSecurityOrigin.securityOrigin());
3692 RefPtr<API::FrameInfo> sourceFrameInfo;
3693 if (!fromAPI && originatingFrame == frame)
3694 sourceFrameInfo = destinationFrameInfo.copyRef();
3696 sourceFrameInfo = API::FrameInfo::create(originatingFrameInfoData, originatingPageID ? m_process->webPage(originatingPageID) : nullptr);
3698 auto userInitiatedActivity = m_process->userInitiatedActivity(navigationActionData.userGestureTokenIdentifier);
3699 bool shouldOpenAppLinks = !m_shouldSuppressAppLinksInNextNavigationPolicyDecision && destinationFrameInfo->isMainFrame() && !hostsAreEqual(URL(ParsedURLString, m_mainFrame->url()), request.url()) && navigationActionData.navigationType != WebCore::NavigationType::BackForward;
3701 auto navigationAction = API::NavigationAction::create(WTFMove(navigationActionData), sourceFrameInfo.get(), destinationFrameInfo.ptr(), WTFMove(request), originalRequest.url(), shouldOpenAppLinks, WTFMove(userInitiatedActivity));
3703 m_navigationClient->decidePolicyForNavigationAction(*this, WTFMove(navigationAction), WTFMove(listener), m_process->transformHandlesToObjects(userData.object()).get());
3705 m_policyClient->decidePolicyForNavigationAction(*this, frame, WTFMove(navigationActionData), originatingFrame, originalRequest, WTFMove(request), WTFMove(listener), m_process->transformHandlesToObjects(userData.object()).get());
3707 m_shouldSuppressAppLinksInNextNavigationPolicyDecision = false;
3710 void WebPageProxy::decidePolicyForNewWindowAction(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, NavigationActionData&& navigationActionData, ResourceRequest&& request, const String& frameName, uint64_t listenerID, const UserData& userData)
3712 PageClientProtector protector(m_pageClient);
3714 WebFrameProxy* frame = m_process->webFrame(frameID);
3715 MESSAGE_CHECK(frame);
3716 MESSAGE_CHECK_URL(request.url());
3718 Ref<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
3720 if (m_navigationClient) {
3721 RefPtr<API::FrameInfo> sourceFrameInfo;
3723 sourceFrameInfo = API::FrameInfo::create(*frame, frameSecurityOrigin.securityOrigin());
3725 auto userInitiatedActivity = m_process->userInitiatedActivity(navigationActionData.userGestureTokenIdentifier);
3726 bool shouldOpenAppLinks = !hostsAreEqual(URL(ParsedURLString, m_mainFrame->url()), request.url());
3727 auto navigationAction = API::NavigationAction::create(WTFMove(navigationActionData), sourceFrameInfo.get(), nullptr, WTFMove(request), request.url(), shouldOpenAppLinks, WTFMove(userInitiatedActivity));
3729 m_navigationClient->decidePolicyForNavigationAction(*this, navigationAction.get(), WTFMove(listener), m_process->transformHandlesToObjects(userData.object()).get());
3732 m_policyClient->decidePolicyForNewWindowAction(*this, *frame, navigationActionData, request, frameName, WTFMove(listener), m_process->transformHandlesToObjects(userData.object()).get());
3735 void WebPageProxy::decidePolicyForResponse(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, const ResourceResponse& response, const ResourceRequest& request, bool canShowMIMEType, uint64_t listenerID, const UserData& userData)
3737 PageClientProtector protector(m_pageClient);
3739 WebFrameProxy* frame = m_process->webFrame(frameID);
3740 MESSAGE_CHECK(frame);
3741 MESSAGE_CHECK_URL(request.url());
3742 MESSAGE_CHECK_URL(response.url());
3744 Ref<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
3746 if (m_navigationClient) {
3747 auto navigationResponse = API::NavigationResponse::create(API::FrameInfo::create(*frame, frameSecurityOrigin.securityOrigin()).get(), request, response, canShowMIMEType);
3748 m_navigationClient->decidePolicyForNavigationResponse(*this, navigationResponse.get(), WTFMove(listener), m_process->transformHandlesToObjects(userData.object()).get());
3750 m_policyClient->decidePolicyForResponse(*this, *frame, response, request, canShowMIMEType, WTFMove(listener), m_process->transformHandlesToObjects(userData.object()).get());
3753 void WebPageProxy::decidePolicyForResponseSync(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, const ResourceResponse& response, const ResourceRequest& request, bool canShowMIMEType, uint64_t listenerID, const UserData& userData, Ref<Messages::WebPageProxy::DecidePolicyForResponseSync::DelayedReply>&& reply)
3755 PageClientProtector protector(m_pageClient);
3757 m_decidePolicyForResponseRequest = request;
3758 m_responsePolicyReply = WTFMove(reply);
3760 decidePolicyForResponse(frameID, frameSecurityOrigin, response, request, canShowMIMEType, listenerID, userData);
3763 void WebPageProxy::unableToImplementPolicy(uint64_t frameID, const ResourceError& error, const UserData& userData)
3765 PageClientProtector protector(m_pageClient);
3767 WebFrameProxy* frame = m_process->webFrame(frameID);
3768 MESSAGE_CHECK(frame);
3770 m_policyClient->unableToImplementPolicy(*this, *frame, error, m_process->transformHandlesToObjects(userData.object()).get());
3775 void WebPageProxy::willSubmitForm(uint64_t frameID, uint64_t sourceFrameID, const Vector<std::pair<String, String>>& textFieldValues, uint64_t listenerID, const UserData& userData)
3777 WebFrameProxy* frame = m_process->webFrame(frameID);
3778 MESSAGE_CHECK(frame);
3780 WebFrameProxy* sourceFrame = m_process->webFrame(sourceFrameID);
3781 MESSAGE_CHECK(sourceFrame);
3783 Ref<WebFormSubmissionListenerProxy> listener = frame->setUpFormSubmissionListenerProxy(listenerID);
3784 m_formClient->willSubmitForm(*this, *frame, *sourceFrame, textFieldValues, m_process->transformHandlesToObjects(userData.object()).get(), listener.get());
3787 void WebPageProxy::didNavigateWithNavigationData(const WebNavigationDataStore& store, uint64_t frameID)
3789 PageClientProtector protector(m_pageClient);
3791 WebFrameProxy* frame = m_process->webFrame(frameID);
3792 MESSAGE_CHECK(frame);
3793 MESSAGE_CHECK(frame->page() == this);
3795 if (m_historyClient) {
3796 if (frame->isMainFrame())
3797 m_historyClient->didNavigateWithNavigationData(*this, store);
3799 m_loaderClient->didNavigateWithNavigationData(*this, store, *frame);
3800 process().processPool().historyClient().didNavigateWithNavigationData(process().processPool(), *this, store, *frame);
3803 void WebPageProxy::didPerformClientRedirect(const String& sourceURLString, const String& destinationURLString, uint64_t frameID)
3805 PageClientProtector protector(m_pageClient);
3807 if (sourceURLString.isEmpty() || destinationURLString.isEmpty())
3810 WebFrameProxy* frame = m_process->webFrame(frameID);
3811 MESSAGE_CHECK(frame);
3812 MESSAGE_CHECK(frame->page() == this);
3814 MESSAGE_CHECK_URL(sourceURLString);
3815 MESSAGE_CHECK_URL(destinationURLString);
3817 if (m_historyClient) {
3818 if (frame->isMainFrame())
3819 m_historyClient->didPerformClientRedirect(*this, sourceURLString, destinationURLString);
3821 m_loaderClient->didPerformClientRedirect(*this, sourceURLString, destinationURLString, *frame);
3822 process().processPool().historyClient().didPerformClientRedirect(process().processPool(), *this, sourceURLString, destinationURLString, *frame);
3825 void WebPageProxy::didPerformServerRedirect(const String& sourceURLString, const String& destinationURLString, uint64_t frameID)
3827 PageClientProtector protector(m_pageClient);
3829 if (sourceURLString.isEmpty() || destinationURLString.isEmpty())
3832 WebFrameProxy* frame = m_process->webFrame(frameID);
3833 MESSAGE_CHECK(frame);
3834 MESSAGE_CHECK(frame->page() == this);
3836 MESSAGE_CHECK_URL(sourceURLString);
3837 MESSAGE_CHECK_URL(destinationURLString);
3839 if (m_historyClient) {
3840 if (frame->isMainFrame())
3841 m_historyClient->didPerformServerRedirect(*this, sourceURLString, destinationURLString);
3843 m_loaderClient->didPerformServerRedirect(*this, sourceURLString, destinationURLString, *frame);
3844 process().processPool().historyClient().didPerformServerRedirect(process().processPool(), *this, sourceURLString, destinationURLString, *frame);
3847 void WebPageProxy::didUpdateHistoryTitle(const String& title, const String& url, uint64_t frameID)
3849 PageClientProtector protector(m_pageClient);
3851 WebFrameProxy* frame = m_process->webFrame(frameID);
3852 MESSAGE_CHECK(frame);
3853 MESSAGE_CHECK(frame->page() == this);
3855 MESSAGE_CHECK_URL(url);
3857 if (m_historyClient) {
3858 if (frame->isMainFrame())
3859 m_historyClient->didUpdateHistoryTitle(*this, title, url);
3861 m_loaderClient->didUpdateHistoryTitle(*this, title, url, *frame);
3862 process().processPool().historyClient().didUpdateHistoryTitle(process().processPool(), *this, title, url, *frame);
3867 void WebPageProxy::createNewPage(const FrameInfoData& originatingFrameInfoData, uint64_t originatingPageID, ResourceRequest&& request, WindowFeatures&& windowFeatures, NavigationActionData&& navigationActionData, Ref<Messages::WebPageProxy::CreateNewPage::DelayedReply>&& reply)
3869 MESSAGE_CHECK(m_process->webFrame(originatingFrameInfoData.frameID));
3870 auto originatingFrameInfo = API::FrameInfo::create(originatingFrameInfoData, m_process->webPage(originatingPageID));
3872 auto mainFrameURL = m_mainFrame->url();
3874 m_uiClient->createNewPage(*this, WTFMove(originatingFrameInfo), WTFMove(request), WTFMove(windowFeatures), WTFMove(navigationActionData), [this, protectedThis = RefPtr<WebPageProxy>(this), mainFrameURL, request, reply = WTFMove(reply)](RefPtr<WebPageProxy> newPage) {
3876 reply->send(0, { });
3880 reply->send(newPage->pageID(), newPage->creationParameters());
3882 WebsiteDataStore::cloneSessionData(*this, *newPage);
3883 newPage->m_shouldSuppressAppLinksInNextNavigationPolicyDecision = hostsAreEqual(URL(ParsedURLString, mainFrameURL), request.url());
3887 void WebPageProxy::showPage()
3889 m_uiClient->showPage(this);
3892 void WebPageProxy::fullscreenMayReturnToInline()
3894 m_uiClient->fullscreenMayReturnToInline(this);
3897 void WebPageProxy::didEnterFullscreen()
3899 m_uiClient->didEnterFullscreen(this);
3902 void WebPageProxy::didExitFullscreen()
3904 m_uiClient->didExitFullscreen(this);
3907 void WebPageProxy::closePage(bool stopResponsivenessTimer)
3909 if (stopResponsivenessTimer)
3910 m_process->responsivenessTimer().stop();
3912 m_pageClient.clearAllEditCommands();
3913 m_uiClient->close(this);
3916 void WebPageProxy::runJavaScriptAlert(uint64_t frameID, const SecurityOriginData& securityOrigin, const String& message, Ref<Messages::WebPageProxy::RunJavaScriptAlert::DelayedReply>&& reply)
3918 WebFrameProxy* frame = m_process->webFrame(frameID);
3919 MESSAGE_CHECK(frame);
3921 // Since runJavaScriptAlert() can spin a nested run loop we need to turn off the responsiveness timer.
3922 m_process->responsivenessTimer().stop();
3924 if (m_controlledByAutomation) {
3925 if (auto* automationSession = process().processPool().automationSession())
3926 automationSession->willShowJavaScriptDialog(*this);
3928 m_uiClient->runJavaScriptAlert(this, message, frame, securityOrigin, [reply = WTFMove(reply)] {
3933 void WebPageProxy::runJavaScriptConfirm(uint64_t frameID, const SecurityOriginData& securityOrigin, const String& message, Ref<Messages::WebPageProxy::RunJavaScriptConfirm::DelayedReply>&& reply)
3935 WebFrameProxy* frame = m_process->webFrame(frameID);
3936 MESSAGE_CHECK(frame);
3938 // Since runJavaScriptConfirm() can spin a nested run loop we need to turn off the responsiveness timer.
3939 m_process->responsivenessTimer().stop();
3941 if (m_controlledByAutomation) {
3942 if (auto* automationSession = process().processPool().automationSession())
3943 automationSession->willShowJavaScriptDialog(*this);
3946 m_uiClient->runJavaScriptConfirm(this, message, frame, securityOrigin, [reply = WTFMove(reply)](bool result) {
3947 reply->send(result);
3951 void WebPageProxy::runJavaScriptPrompt(uint64_t frameID, const SecurityOriginData& securityOrigin, const String& message, const String& defaultValue, Ref<Messages::WebPageProxy::RunJavaScriptPrompt::DelayedReply>&& reply)
3953 WebFrameProxy* frame = m_process->webFrame(frameID);
3954 MESSAGE_CHECK(frame);
3956 // Since runJavaScriptPrompt() can spin a nested run loop we need to turn off the responsiveness timer.
3957 m_process->responsivenessTimer().stop();
3959 if (m_controlledByAutomation) {
3960 if (auto* automationSession = process().processPool().automationSession())
3961 automationSession->willShowJavaScriptDialog(*this);
3964 m_uiClient->runJavaScriptPrompt(this, message, defaultValue, frame, securityOrigin, [reply = WTFMove(reply)](const String& result) {
3965 reply->send(result);
3969 void WebPageProxy::setStatusText(const String& text)
3971 m_uiClient->setStatusText(this, text);
3974 void WebPageProxy::mouseDidMoveOverElement(WebHitTestResultData&& hitTestResultData, uint32_t opaqueModifiers, UserData&& userData)
3976 m_lastMouseMoveHitTestResult = API::HitTestResult::create(hitTestResultData);
3978 WebEvent::Modifiers modifiers = static_cast<WebEvent::Modifiers>(opaqueModifiers);
3980 m_uiClient->mouseDidMoveOverElement(*this, hitTestResultData, modifiers, m_process->transformHandlesToObjects(userData.object()).get());
3983 void WebPageProxy::connectionWillOpen(IPC::Connection& connection)
3985 ASSERT(&connection == m_process->connection());
3987 m_webProcessLifetimeTracker.connectionWillOpen(connection);
3990 void WebPageProxy::webProcessWillShutDown()
3992 m_webProcessLifetimeTracker.webProcessWillShutDown();
3995 void WebPageProxy::processDidFinishLaunching()
3997 ASSERT(m_process->state() == WebProcessProxy::State::Running);
3998 finishInitializingWebPageAfterProcessLaunch();
4001 #if ENABLE(NETSCAPE_PLUGIN_API)
4002 void WebPageProxy::unavailablePluginButtonClicked(uint32_t opaquePluginUnavailabilityReason, const String& mimeType, const String& pluginURLString, const String& pluginspageAttributeURLString, const String& frameURLString, const String& pageURLString)
4004 MESSAGE_CHECK_URL(pluginURLString);
4005 MESSAGE_CHECK_URL(pluginspageAttributeURLString);
4006 MESSAGE_CHECK_URL(frameURLString);
4007 MESSAGE_CHECK_URL(pageURLString);
4009 String newMimeType = mimeType;
4010 PluginModuleInfo plugin = m_process->processPool().pluginInfoStore().findPlugin(newMimeType, URL(URL(), pluginURLString));
4011 auto pluginInformation = createPluginInformationDictionary(plugin, frameURLString, mimeType, pageURLString, pluginspageAttributeURLString, pluginURLString);
4013 WKPluginUnavailabilityReason pluginUnavailabilityReason = kWKPluginUnavailabilityReasonPluginMissing;
4014 switch (static_cast<RenderEmbeddedObject::PluginUnavailabilityReason>(opaquePluginUnavailabilityReason)) {
4015 case RenderEmbeddedObject::PluginMissing:
4016 pluginUnavailabilityReason = kWKPluginUnavailabilityReasonPluginMissing;
4018 case RenderEmbeddedObject::InsecurePluginVersion:
4019 pluginUnavailabilityReason = kWKPluginUnavailabilityReasonInsecurePluginVersion;
4021 case RenderEmbeddedObject::PluginCrashed:
4022 pluginUnavailabilityReason = kWKPluginUnavailabilityReasonPluginCrashed;
4024 case RenderEmbeddedObject::PluginBlockedByContentSecurityPolicy:
4025 ASSERT_NOT_REACHED();
4028 m_uiClient->unavailablePluginButtonClicked(*this, pluginUnavailabilityReason, pluginInformation.get());
4030 #endif // ENABLE(NETSCAPE_PLUGIN_API)
4033 void WebPageProxy::webGLPolicyForURL(URL&& url, Ref<Messages::WebPageProxy::WebGLPolicyForURL::DelayedReply>&& reply)
4035 if (m_navigationClient) {
4036 m_navigationClient->webGLLoadPolicy(*this, url, [reply = WTFMove(reply)](WebGLLoadPolicy policy) {
4037 reply->send(static_cast<uint32_t>(policy));
4040 reply->send(static_cast<uint32_t>(m_loaderClient->webGLLoadPolicy(*this, url)));
4043 void WebPageProxy::resolveWebGLPolicyForURL(URL&& url, Ref<Messages::WebPageProxy::ResolveWebGLPolicyForURL::DelayedReply>&& reply)
4045 if (m_navigationClient) {
4046 m_navigationClient->resolveWebGLLoadPolicy(*this, url, [reply = WTFMove(reply)](WebGLLoadPolicy policy) {
4047 reply->send(static_cast<uint32_t>(policy));
4050 reply->send(static_cast<uint32_t>(m_loaderClient->resolveWebGLLoadPolicy(*this, url)));
4052 #endif // ENABLE(WEBGL)
4054 void WebPageProxy::setToolbarsAreVisible(bool toolbarsAreVisible)
4056 m_uiClient->setToolbarsAreVisible(*this, toolbarsAreVisible);
4059 void WebPageProxy::getToolbarsAreVisible(Ref<Messages::WebPageProxy::GetToolbarsAreVisible::DelayedReply>&& reply)
4061 m_uiClient->toolbarsAreVisible(*this, [reply = WTFMove(reply)](bool visible) {
4062 reply->send(visible);
4066 void WebPageProxy::setMenuBarIsVisible(bool menuBarIsVisible)
4068 m_uiClient->setMenuBarIsVisible(*this, menuBarIsVisible);
4071 void WebPageProxy::getMenuBarIsVisible(Ref<Messages::WebPageProxy::GetMenuBarIsVisible::DelayedReply>&& reply)
4073 m_uiClient->menuBarIsVisible(*this, [reply = WTFMove(reply)] (bool visible) {
4074 reply->send(visible);
4078 void WebPageProxy::setStatusBarIsVisible(bool statusBarIsVisible)
4080 m_uiClient->setStatusBarIsVisible(*this, statusBarIsVisible);
4083 void WebPageProxy::getStatusBarIsVisible(Ref<Messages::WebPageProxy::GetStatusBarIsVisible::DelayedReply>&& reply)
4085 m_uiClient->statusBarIsVisible(*this, [reply = WTFMove(reply)] (bool visible) {
4086 reply->send(visible);
4090 void WebPageProxy::setIsResizable(bool isResizable)
4092 m_uiClient->setIsResizable(*this, isResizable);
4095 void WebPageProxy::setWindowFrame(const FloatRect& newWindowFrame)
4097 m_uiClient->setWindowFrame(*this, m_pageClient.convertToDeviceSpace(newWindowFrame));
4100 void WebPageProxy::getWindowFrame(Ref<Messages::WebPageProxy::GetWindowFrame::DelayedReply>&& reply)
4102 m_uiClient->windowFrame(*this, [this, protectedThis = makeRef(*this), reply = WTFMove(reply)] (FloatRect frame) {
4103 reply->send(m_pageClient.convertToUserSpace(frame));
4107 void WebPageProxy::getWindowFrameWithCallback(Function<void(FloatRect)>&& completionHandler)
4109 m_uiClient->windowFrame(*this, WTFMove(completionHandler));
4112 void WebPageProxy::screenToRootView(const IntPoint& screenPoint, Ref<Messages::WebPageProxy::ScreenToRootView::DelayedReply>&& reply)
4114 reply->send(m_pageClient.screenToRootView(screenPoint));
4117 void WebPageProxy::rootViewToScreen(const IntRect& viewRect, Ref<Messages::WebPageProxy::RootViewToScreen::DelayedReply>&& reply)
4119 reply->send(m_pageClient.rootViewToScreen(viewRect));
4123 void WebPageProxy::accessibilityScreenToRootView(const IntPoint& screenPoint, IntPoint& windowPoint)
4125 windowPoint = m_pageClient.accessibilityScreenToRootView(screenPoint);
4128 void WebPageProxy::rootViewToAccessibilityScreen(const IntRect& viewRect, IntRect& result)
4130 result = m_pageClient.rootViewToAccessibilityScreen(viewRect);
4134 void WebPageProxy::runBeforeUnloadConfirmPanel(uint64_t frameID, const SecurityOriginData& securityOrigin, const String& message, RefPtr<Messages::WebPageProxy::RunBeforeUnloadConfirmPanel::DelayedReply> reply)
4136 WebFrameProxy* frame = m_process->webFrame(frameID);
4137 MESSAGE_CHECK(frame);
4139 // Since runBeforeUnloadConfirmPanel() can spin a nested run loop we need to turn off the responsiveness timer.
4140 m_process->responsivenessTimer().stop();
4142 if (m_controlledByAutomation) {
4143 if (auto* automationSession = process().processPool().automationSession())
4144 automationSession->willShowJavaScriptDialog(*this);
4147 m_uiClient->runBeforeUnloadConfirmPanel(this, message, frame, securityOrigin, [reply](bool result) { reply->send(result); });
4150 void WebPageProxy::didChangeViewportProperties(const ViewportAttributes& attr)
4152 m_pageClient.didChangeViewportProperties(attr);
4155 void WebPageProxy::pageDidScroll()
4157 m_uiClient->pageDidScroll(this);
4160 // Do not hide the validation message if the scrolling was caused by the keyboard showing up.
4161 if (m_isKeyboardAnimatingIn)
4164 hideValidationMessage();
4167 void WebPageProxy::runOpenPanel(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, const FileChooserSettings& settings)
4169 if (m_openPanelResultListener) {
4170 m_openPanelResultListener->invalidate();
4171 m_openPanelResultListener = nullptr;
4174 WebFrameProxy* frame = m_process->webFrame(frameID);
4175 MESSAGE_CHECK(frame);
4177 Ref<API::OpenPanelParameters> parameters = API::OpenPanelParameters::create(settings);
4178 m_openPanelResultListener = WebOpenPanelResultListenerProxy::create(this);
4180 if (m_controlledByAutomation) {
4181 if (auto* automationSession = process().processPool().automationSession())
4182 automationSession->handleRunOpenPanel(*this, *frame, parameters.get(), *m_openPanelResultListener);
4184 // Don't show a file chooser, since automation will be unable to interact with it.
4188 // Since runOpenPanel() can spin a nested run loop we need to turn off the responsiveness timer.
4189 m_process->responsivenessTimer().stop();
4191 if (!m_uiClient->runOpenPanel(this, frame, frameSecurityOrigin, parameters.ptr(), m_openPanelResultListener.get())) {
4192 if (!m_pageClient.handleRunOpenPanel(this, frame, parameters.ptr(), m_openPanelResultListener.get()))
4193 didCancelForOpenPanel();
4197 void WebPageProxy::printFrame(uint64_t frameID)
4199 ASSERT(!m_isPerformingDOMPrintOperation);
4200 m_isPerformingDOMPrintOperation = true;
4202 WebFrameProxy* frame = m_process->webFrame(frameID);
4203 MESSAGE_CHECK(frame);
4205 m_uiClient->printFrame(*this, *frame);
4207 endPrinting(); // Send a message synchronously while m_isPerformingDOMPrintOperation is still true.
4208 m_isPerformingDOMPrintOperation = false;
4211 void WebPageProxy::printMainFrame()
4213 printFrame(m_mainFrame->frameID());
4216 void WebPageProxy::setMediaVolume(float volume)
4218 if (volume == m_mediaVolume)
4221 m_mediaVolume = volume;
4226 m_process->send(Messages::WebPage::SetMediaVolume(volume), m_pageID);
4229 void WebPageProxy::setMuted(WebCore::MediaProducer::MutedStateFlags state)