2 * Copyright (C) 2010, 2011, 2015 Apple Inc. All rights reserved.
3 * Copyright (C) 2012 Intel Corporation. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
18 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24 * THE POSSIBILITY OF SUCH DAMAGE.
28 #include "WebPageProxy.h"
31 #include "APIContextMenuClient.h"
32 #include "APIFindClient.h"
33 #include "APIFormClient.h"
34 #include "APIFrameInfo.h"
35 #include "APIGeometry.h"
36 #include "APIHistoryClient.h"
37 #include "APILegacyContextHistoryClient.h"
38 #include "APILoaderClient.h"
39 #include "APINavigation.h"
40 #include "APINavigationAction.h"
41 #include "APINavigationClient.h"
42 #include "APINavigationResponse.h"
43 #include "APIPolicyClient.h"
44 #include "APISecurityOrigin.h"
45 #include "APIUIClient.h"
46 #include "APIURLRequest.h"
47 #include "AuthenticationChallengeProxy.h"
48 #include "AuthenticationDecisionListener.h"
49 #include "DataReference.h"
50 #include "DownloadProxy.h"
51 #include "DrawingAreaProxy.h"
52 #include "DrawingAreaProxyMessages.h"
53 #include "EventDispatcherMessages.h"
55 #include "NativeWebKeyboardEvent.h"
56 #include "NativeWebMouseEvent.h"
57 #include "NativeWebWheelEvent.h"
58 #include "NavigationActionData.h"
59 #include "NotificationPermissionRequest.h"
60 #include "NotificationPermissionRequestManager.h"
61 #include "PageClient.h"
62 #include "PluginInformation.h"
63 #include "PluginProcessManager.h"
64 #include "PrintInfo.h"
65 #include "TextChecker.h"
66 #include "TextCheckerState.h"
67 #include "UserMediaPermissionRequestProxy.h"
68 #include "WKContextPrivate.h"
69 #include "WebBackForwardList.h"
70 #include "WebBackForwardListItem.h"
71 #include "WebCertificateInfo.h"
72 #include "WebContextMenuItem.h"
73 #include "WebContextMenuProxy.h"
74 #include "WebCoreArgumentCoders.h"
75 #include "WebEditCommandProxy.h"
77 #include "WebEventConversion.h"
78 #include "WebFormSubmissionListenerProxy.h"
79 #include "WebFramePolicyListenerProxy.h"
80 #include "WebFullScreenManagerProxy.h"
81 #include "WebFullScreenManagerProxyMessages.h"
83 #include "WebInspectorProxy.h"
84 #include "WebInspectorProxyMessages.h"
85 #include "WebNavigationState.h"
86 #include "WebNotificationManagerProxy.h"
87 #include "WebOpenPanelParameters.h"
88 #include "WebOpenPanelResultListenerProxy.h"
89 #include "WebPageCreationParameters.h"
90 #include "WebPageGroup.h"
91 #include "WebPageGroupData.h"
92 #include "WebPageMessages.h"
93 #include "WebPageProxyMessages.h"
94 #include "WebPopupItem.h"
95 #include "WebPopupMenuProxy.h"
96 #include "WebPreferences.h"
97 #include "WebProcessMessages.h"
98 #include "WebProcessPool.h"
99 #include "WebProcessProxy.h"
100 #include "WebProtectionSpace.h"
101 #include "WebUserContentControllerProxy.h"
102 #include "WebsiteDataStore.h"
103 #include <WebCore/BitmapImage.h>
104 #include <WebCore/DragController.h>
105 #include <WebCore/DragData.h>
106 #include <WebCore/FloatRect.h>
107 #include <WebCore/FocusDirection.h>
108 #include <WebCore/MIMETypeRegistry.h>
109 #include <WebCore/RenderEmbeddedObject.h>
110 #include <WebCore/SerializedCryptoKeyWrap.h>
111 #include <WebCore/TextCheckerClient.h>
112 #include <WebCore/TextIndicator.h>
113 #include <WebCore/WindowFeatures.h>
115 #include <wtf/NeverDestroyed.h>
116 #include <wtf/RandomNumber.h>
117 #include <wtf/text/StringView.h>
119 #if ENABLE(ASYNC_SCROLLING)
120 #include "RemoteScrollingCoordinatorProxy.h"
123 #if USE(COORDINATED_GRAPHICS_MULTIPROCESS)
124 #include "CoordinatedLayerTreeHostProxyMessages.h"
127 #if ENABLE(VIBRATION)
128 #include "WebVibrationProxy.h"
132 #include <wtf/RefCountedLeakCounter.h>
135 #if ENABLE(NETWORK_PROCESS)
136 #include "NetworkProcessMessages.h"
140 #include "RemoteLayerTreeDrawingAreaProxy.h"
141 #include "RemoteLayerTreeScrollingPerformanceData.h"
142 #include "ViewSnapshotStore.h"
143 #include <WebCore/RunLoopObserver.h>
147 #include "WebVideoFullscreenManagerProxy.h"
148 #include "WebVideoFullscreenManagerProxyMessages.h"
152 #include <WebCore/CairoUtilities.h>
155 #if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
156 #include <WebCore/MediaPlaybackTarget.h>
159 // This controls what strategy we use for mouse wheel coalescing.
160 #define MERGE_WHEEL_EVENTS 1
162 #define MESSAGE_CHECK(assertion) MESSAGE_CHECK_BASE(assertion, m_process->connection())
163 #define MESSAGE_CHECK_URL(url) MESSAGE_CHECK_BASE(m_process->checkURLReceivedFromWebProcess(url), m_process->connection())
165 using namespace WebCore;
167 // Represents the number of wheel events we can hold in the queue before we start pushing them preemptively.
168 static const unsigned wheelEventQueueSizeThreshold = 10;
172 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, webPageProxyCounter, ("WebPageProxy"));
174 class ExceededDatabaseQuotaRecords {
175 WTF_MAKE_NONCOPYABLE(ExceededDatabaseQuotaRecords); WTF_MAKE_FAST_ALLOCATED;
176 friend class NeverDestroyed<ExceededDatabaseQuotaRecords>;
180 String originIdentifier;
183 uint64_t currentQuota;
184 uint64_t currentOriginUsage;
185 uint64_t currentDatabaseUsage;
186 uint64_t expectedUsage;
187 RefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply> reply;
190 static ExceededDatabaseQuotaRecords& singleton();
192 std::unique_ptr<Record> createRecord(uint64_t frameID, String originIdentifier,
193 String databaseName, String displayName, uint64_t currentQuota,
194 uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage,
195 PassRefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply>);
197 void add(std::unique_ptr<Record>);
198 bool areBeingProcessed() const { return !!m_currentRecord; }
202 ExceededDatabaseQuotaRecords() { }
203 ~ExceededDatabaseQuotaRecords() { }
205 Deque<std::unique_ptr<Record>> m_records;
206 std::unique_ptr<Record> m_currentRecord;
209 ExceededDatabaseQuotaRecords& ExceededDatabaseQuotaRecords::singleton()
211 static NeverDestroyed<ExceededDatabaseQuotaRecords> records;
215 std::unique_ptr<ExceededDatabaseQuotaRecords::Record> ExceededDatabaseQuotaRecords::createRecord(
216 uint64_t frameID, String originIdentifier, String databaseName, String displayName,
217 uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage,
218 uint64_t expectedUsage, PassRefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply> reply)
220 auto record = std::make_unique<Record>();
221 record->frameID = frameID;
222 record->originIdentifier = originIdentifier;
223 record->databaseName = databaseName;
224 record->displayName = displayName;
225 record->currentQuota = currentQuota;
226 record->currentOriginUsage = currentOriginUsage;
227 record->currentDatabaseUsage = currentDatabaseUsage;
228 record->expectedUsage = expectedUsage;
229 record->reply = reply;
230 return WTF::move(record);
233 void ExceededDatabaseQuotaRecords::add(std::unique_ptr<ExceededDatabaseQuotaRecords::Record> record)
235 m_records.append(WTF::move(record));
238 ExceededDatabaseQuotaRecords::Record* ExceededDatabaseQuotaRecords::next()
240 m_currentRecord = nullptr;
241 if (!m_records.isEmpty())
242 m_currentRecord = m_records.takeFirst();
243 return m_currentRecord.get();
247 static const char* webKeyboardEventTypeString(WebEvent::Type type)
250 case WebEvent::KeyDown:
253 case WebEvent::KeyUp:
256 case WebEvent::RawKeyDown:
263 ASSERT_NOT_REACHED();
267 #endif // !LOG_DISABLED
269 Ref<WebPageProxy> WebPageProxy::create(PageClient& pageClient, WebProcessProxy& process, uint64_t pageID, const WebPageConfiguration& configuration)
271 return adoptRef(*new WebPageProxy(pageClient, process, pageID, configuration));
274 WebPageProxy::WebPageProxy(PageClient& pageClient, WebProcessProxy& process, uint64_t pageID, const WebPageConfiguration& configuration)
275 : m_pageClient(pageClient)
276 , m_loaderClient(std::make_unique<API::LoaderClient>())
277 , m_policyClient(std::make_unique<API::PolicyClient>())
278 , m_formClient(std::make_unique<API::FormClient>())
279 , m_uiClient(std::make_unique<API::UIClient>())
280 , m_findClient(std::make_unique<API::FindClient>())
281 , m_diagnosticLoggingClient(std::make_unique<API::DiagnosticLoggingClient>())
282 #if ENABLE(CONTEXT_MENUS)
283 , m_contextMenuClient(std::make_unique<API::ContextMenuClient>())
285 , m_navigationState(std::make_unique<WebNavigationState>())
287 , m_pageGroup(*configuration.pageGroup)
288 , m_preferences(*configuration.preferences)
289 , m_userContentController(configuration.userContentController)
290 , m_visitedLinkProvider(*configuration.visitedLinkProvider)
291 , m_websiteDataStore(*configuration.websiteDataStore)
292 , m_mainFrame(nullptr)
293 , m_userAgent(standardUserAgent())
294 , m_treatsSHA1CertificatesAsInsecure(configuration.treatsSHA1SignedCertificatesAsInsecure)
296 , m_hasReceivedLayerTreeTransactionAfterDidCommitLoad(true)
297 , m_firstLayerTreeTransactionIdAfterDidCommitLoad(0)
298 , m_deviceOrientation(0)
299 , m_dynamicViewportSizeUpdateWaitingForTarget(false)
300 , m_dynamicViewportSizeUpdateWaitingForLayerTreeCommit(false)
301 , m_dynamicViewportSizeUpdateLayerTreeTransactionID(0)
302 , m_layerTreeTransactionIdAtLastTouchStart(0)
304 , m_geolocationPermissionRequestManager(*this)
305 , m_notificationPermissionRequestManager(*this)
306 , m_userMediaPermissionRequestManager(*this)
307 , m_viewState(ViewState::NoFlags)
308 , m_viewWasEverInWindow(false)
309 , m_backForwardList(WebBackForwardList::create(*this))
310 , m_maintainsInactiveSelection(false)
311 , m_isEditable(false)
312 #if PLATFORM(MAC) && !USE(ASYNC_NSTEXTINPUTCLIENT)
313 , m_temporarilyClosedComposition(false)
315 , m_textZoomFactor(1)
316 , m_pageZoomFactor(1)
317 , m_pageScaleFactor(1)
318 , m_pluginZoomFactor(1)
319 , m_pluginScaleFactor(1)
320 , m_intrinsicDeviceScaleFactor(1)
321 , m_customDeviceScaleFactor(0)
322 , m_topContentInset(0)
323 , m_layerHostingMode(LayerHostingMode::InProcess)
324 , m_drawsBackground(true)
325 , m_drawsTransparentBackground(false)
326 , m_useFixedLayout(false)
327 , m_suppressScrollbarAnimations(false)
328 , m_paginationMode(Pagination::Unpaginated)
329 , m_paginationBehavesLikeColumns(false)
331 , m_gapBetweenPages(0)
334 , m_canRunModal(false)
335 , m_isInPrintingMode(false)
336 , m_isPerformingDOMPrintOperation(false)
337 , m_inDecidePolicyForResponseSync(false)
338 , m_decidePolicyForResponseRequest(0)
339 , m_syncMimeTypePolicyActionIsValid(false)
340 , m_syncMimeTypePolicyAction(PolicyUse)
341 , m_syncMimeTypePolicyDownloadID(0)
342 , m_inDecidePolicyForNavigationAction(false)
343 , m_syncNavigationActionPolicyActionIsValid(false)
344 , m_syncNavigationActionPolicyAction(PolicyUse)
345 , m_syncNavigationActionPolicyDownloadID(0)
346 , m_processingMouseMoveEvent(false)
347 #if ENABLE(TOUCH_EVENTS)
348 , m_isTrackingTouchEvents(false)
351 , m_sessionID(configuration.sessionID)
352 , m_isPageSuspended(false)
353 , m_addsVisitedLinks(true)
354 #if ENABLE(REMOTE_INSPECTOR)
355 , m_allowsRemoteInspection(true)
358 , m_isSmartInsertDeleteEnabled(TextChecker::isSmartInsertDeleteEnabled())
361 , m_backgroundColor(Color::white)
363 , m_spellDocumentTag(0)
364 , m_hasSpellDocumentTag(false)
365 , m_pendingLearnOrIgnoreWordMessageCount(0)
366 , m_mainFrameHasCustomContentProvider(false)
367 #if ENABLE(DRAG_SUPPORT)
368 , m_currentDragOperation(DragOperationNone)
369 , m_currentDragIsOverFileInput(false)
370 , m_currentDragNumberOfFilesToBeAccepted(0)
372 , m_pageLoadState(*this)
373 , m_delegatesScrolling(false)
374 , m_mainFrameHasHorizontalScrollbar(false)
375 , m_mainFrameHasVerticalScrollbar(false)
376 , m_canShortCircuitHorizontalWheelEvents(true)
377 , m_mainFrameIsPinnedToLeftSide(true)
378 , m_mainFrameIsPinnedToRightSide(true)
379 , m_mainFrameIsPinnedToTopSide(true)
380 , m_mainFrameIsPinnedToBottomSide(true)
381 , m_shouldUseImplicitRubberBandControl(false)
382 , m_rubberBandsAtLeft(true)
383 , m_rubberBandsAtRight(true)
384 , m_rubberBandsAtTop(true)
385 , m_rubberBandsAtBottom(true)
386 , m_enableVerticalRubberBanding(true)
387 , m_enableHorizontalRubberBanding(true)
388 , m_backgroundExtendsBeyondPage(false)
389 , m_shouldRecordNavigationSnapshots(false)
390 , m_isShowingNavigationGestureSnapshot(false)
392 , m_renderTreeSize(0)
393 , m_sessionRestorationRenderTreeSize(0)
394 , m_wantsSessionRestorationRenderTreeSizeThresholdEvent(false)
395 , m_hitRenderTreeSizeThreshold(false)
396 , m_shouldSendEventsSynchronously(false)
397 , m_suppressVisibilityUpdates(false)
398 , m_autoSizingShouldExpandToViewHeight(false)
401 , m_mayStartMediaWhenInWindow(true)
402 , m_waitingForDidUpdateViewState(false)
404 , m_scrollPerformanceDataCollectionEnabled(false)
406 , m_scrollPinningBehavior(DoNotPin)
408 , m_configurationPreferenceValues(configuration.preferenceValues)
409 , m_potentiallyChangedViewStateFlags(ViewState::NoFlags)
410 , m_viewStateChangeWantsSynchronousReply(false)
411 , m_isPlayingAudio(false)
413 m_webProcessLifetimeTracker.addObserver(m_visitedLinkProvider);
414 m_webProcessLifetimeTracker.addObserver(m_websiteDataStore);
416 if (m_process->state() == WebProcessProxy::State::Running) {
417 if (m_userContentController)
418 m_process->addWebUserContentControllerProxy(*m_userContentController);
419 m_process->addVisitedLinkProvider(m_visitedLinkProvider);
423 updateActivityToken();
424 updateProccessSuppressionState();
426 #if HAVE(OUT_OF_PROCESS_LAYER_HOSTING)
427 m_layerHostingMode = m_viewState & ViewState::IsInWindow ? m_pageClient.viewLayerHostingMode() : LayerHostingMode::OutOfProcess;
430 platformInitialize();
433 webPageProxyCounter.increment();
436 WebProcessPool::statistics().wkPageCount++;
438 m_preferences->addPage(*this);
439 m_pageGroup->addPage(this);
441 m_inspector = WebInspectorProxy::create(this);
442 #if ENABLE(FULLSCREEN_API)
443 m_fullScreenManager = WebFullScreenManagerProxy::create(*this, m_pageClient.fullScreenManagerProxyClient());
446 m_videoFullscreenManager = WebVideoFullscreenManagerProxy::create(*this);
448 #if ENABLE(VIBRATION)
449 m_vibration = WebVibrationProxy::create(this);
452 m_process->addMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID, *this);
454 #if ENABLE(NETWORK_PROCESS)
455 if (m_sessionID.isEphemeral())
456 m_process->processPool().sendToNetworkingProcess(Messages::NetworkProcess::EnsurePrivateBrowsingSession(m_sessionID));
460 const CFIndex viewStateChangeRunLoopOrder = (CFIndex)RunLoopObserver::WellKnownRunLoopOrders::CoreAnimationCommit - 1;
461 m_viewStateChangeDispatcher = RunLoopObserver::create(viewStateChangeRunLoopOrder, [this] {
462 this->dispatchViewStateChange();
467 WebPageProxy::~WebPageProxy()
469 ASSERT(m_process->webPage(m_pageID) != this);
471 for (WebPageProxy* page : m_process->pages())
472 ASSERT(page != this);
478 WebProcessPool::statistics().wkPageCount--;
480 if (m_hasSpellDocumentTag)
481 TextChecker::closeSpellDocumentWithTag(m_spellDocumentTag);
483 m_preferences->removePage(*this);
484 m_pageGroup->removePage(this);
487 webPageProxyCounter.decrement();
491 PlatformProcessIdentifier WebPageProxy::processIdentifier() const
496 return m_process->processIdentifier();
499 bool WebPageProxy::isValid() const
501 // A page that has been explicitly closed is never valid.
508 void WebPageProxy::setPreferences(WebPreferences& preferences)
510 if (&preferences == m_preferences.ptr())
513 m_preferences->removePage(*this);
514 m_preferences = preferences;
515 m_preferences->addPage(*this);
517 preferencesDidChange();
520 void WebPageProxy::setHistoryClient(std::unique_ptr<API::HistoryClient> historyClient)
522 m_historyClient = WTF::move(historyClient);
525 void WebPageProxy::setNavigationClient(std::unique_ptr<API::NavigationClient> navigationClient)
527 m_navigationClient = WTF::move(navigationClient);
530 void WebPageProxy::setLoaderClient(std::unique_ptr<API::LoaderClient> loaderClient)
533 m_loaderClient = std::make_unique<API::LoaderClient>();
537 m_loaderClient = WTF::move(loaderClient);
540 void WebPageProxy::setPolicyClient(std::unique_ptr<API::PolicyClient> policyClient)
543 m_policyClient = std::make_unique<API::PolicyClient>();
547 m_policyClient = WTF::move(policyClient);
550 void WebPageProxy::setFormClient(std::unique_ptr<API::FormClient> formClient)
553 m_formClient = std::make_unique<API::FormClient>();
557 m_formClient = WTF::move(formClient);
560 void WebPageProxy::setUIClient(std::unique_ptr<API::UIClient> uiClient)
563 m_uiClient = std::make_unique<API::UIClient>();
567 m_uiClient = WTF::move(uiClient);
572 m_process->send(Messages::WebPage::SetCanRunBeforeUnloadConfirmPanel(m_uiClient->canRunBeforeUnloadConfirmPanel()), m_pageID);
573 setCanRunModal(m_uiClient->canRunModal());
576 void WebPageProxy::setFindClient(std::unique_ptr<API::FindClient> findClient)
579 m_findClient = std::make_unique<API::FindClient>();
583 m_findClient = WTF::move(findClient);
586 void WebPageProxy::initializeFindMatchesClient(const WKPageFindMatchesClientBase* client)
588 m_findMatchesClient.initialize(client);
591 void WebPageProxy::setDiagnosticLoggingClient(std::unique_ptr<API::DiagnosticLoggingClient> diagnosticLoggingClient)
593 if (!diagnosticLoggingClient) {
594 m_diagnosticLoggingClient = std::make_unique<API::DiagnosticLoggingClient>();
598 m_diagnosticLoggingClient = WTF::move(diagnosticLoggingClient);
601 #if ENABLE(CONTEXT_MENUS)
602 void WebPageProxy::setContextMenuClient(std::unique_ptr<API::ContextMenuClient> contextMenuClient)
604 if (!contextMenuClient) {
605 m_contextMenuClient = std::make_unique<API::ContextMenuClient>();
609 m_contextMenuClient = WTF::move(contextMenuClient);
613 void WebPageProxy::setInjectedBundleClient(const WKPageInjectedBundleClientBase* client)
616 m_injectedBundleClient = nullptr;
620 m_injectedBundleClient = std::make_unique<WebPageInjectedBundleClient>();
621 m_injectedBundleClient->initialize(client);
624 void WebPageProxy::handleMessage(IPC::Connection& connection, const String& messageName, const WebKit::UserData& messageBody)
626 auto* webProcessProxy = WebProcessProxy::fromConnection(&connection);
627 if (!webProcessProxy || !m_injectedBundleClient)
629 m_injectedBundleClient->didReceiveMessageFromInjectedBundle(this, messageName, webProcessProxy->transformHandlesToObjects(messageBody.object()).get());
632 void WebPageProxy::handleSynchronousMessage(IPC::Connection& connection, const String& messageName, const UserData& messageBody, UserData& returnUserData)
634 if (!WebProcessProxy::fromConnection(&connection) || !m_injectedBundleClient)
637 RefPtr<API::Object> returnData;
638 m_injectedBundleClient->didReceiveSynchronousMessageFromInjectedBundle(this, messageName, WebProcessProxy::fromConnection(&connection)->transformHandlesToObjects(messageBody.object()).get(), returnData);
639 returnUserData = UserData(WebProcessProxy::fromConnection(&connection)->transformObjectsToHandles(returnData.get()));
643 void WebPageProxy::reattachToWebProcess()
647 ASSERT(m_process->state() == WebProcessProxy::State::Terminated);
650 m_process->removeWebPage(m_pageID);
651 m_process->removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID);
653 if (m_process->processPool().processModel() == ProcessModelSharedSecondaryProcess)
654 m_process = m_process->processPool().ensureSharedWebProcess();
656 m_process = m_process->processPool().createNewWebProcessRespectingProcessCountLimit();
658 ASSERT(m_process->state() != ChildProcessProxy::State::Terminated);
659 if (m_process->state() == ChildProcessProxy::State::Running)
660 processDidFinishLaunching();
661 m_process->addExistingWebPage(this, m_pageID);
662 m_process->addMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID, *this);
665 updateActivityToken();
667 m_inspector = WebInspectorProxy::create(this);
668 #if ENABLE(FULLSCREEN_API)
669 m_fullScreenManager = WebFullScreenManagerProxy::create(*this, m_pageClient.fullScreenManagerProxyClient());
672 m_videoFullscreenManager = WebVideoFullscreenManagerProxy::create(*this);
677 m_pageClient.didRelaunchProcess();
678 m_drawingArea->waitForBackingStoreUpdateOnNextPaint();
681 RefPtr<API::Navigation> WebPageProxy::reattachToWebProcessForReload()
687 reattachToWebProcess();
689 if (!m_backForwardList->currentItem())
692 auto navigation = m_navigationState->createReloadNavigation();
694 // We allow stale content when reloading a WebProcess that's been killed or crashed.
695 m_process->send(Messages::WebPage::GoToBackForwardItem(navigation->navigationID(), m_backForwardList->currentItem()->itemID()), m_pageID);
696 m_process->responsivenessTimer()->start();
698 return WTF::move(navigation);
701 RefPtr<API::Navigation> WebPageProxy::reattachToWebProcessWithItem(WebBackForwardListItem* item)
706 if (item && item != m_backForwardList->currentItem())
707 m_backForwardList->goToItem(item);
710 reattachToWebProcess();
715 auto navigation = m_navigationState->createBackForwardNavigation();
717 m_process->send(Messages::WebPage::GoToBackForwardItem(navigation->navigationID(), item->itemID()), m_pageID);
718 m_process->responsivenessTimer()->start();
720 return WTF::move(navigation);
723 void WebPageProxy::setSessionID(SessionID sessionID)
728 m_sessionID = sessionID;
729 m_process->send(Messages::WebPage::SetSessionID(sessionID), m_pageID);
731 #if ENABLE(NETWORK_PROCESS)
732 if (sessionID.isEphemeral())
733 m_process->processPool().sendToNetworkingProcess(Messages::NetworkProcess::EnsurePrivateBrowsingSession(sessionID));
737 void WebPageProxy::initializeWebPage()
741 BackForwardListItemVector items = m_backForwardList->entries();
742 for (size_t i = 0; i < items.size(); ++i)
743 m_process->registerNewWebBackForwardListItem(items[i].get());
745 m_drawingArea = m_pageClient.createDrawingAreaProxy();
746 ASSERT(m_drawingArea);
748 #if ENABLE(ASYNC_SCROLLING)
749 if (m_drawingArea->type() == DrawingAreaTypeRemoteLayerTree) {
750 m_scrollingCoordinatorProxy = std::make_unique<RemoteScrollingCoordinatorProxy>(*this);
752 // On iOS, main frame scrolls are sent in terms of visible rect updates.
753 m_scrollingCoordinatorProxy->setPropagatesMainFrameScrolls(false);
758 #if ENABLE(INSPECTOR_SERVER)
759 if (m_preferences->developerExtrasEnabled())
760 inspector()->enableRemoteInspection();
763 process().send(Messages::WebProcess::CreateWebPage(m_pageID, creationParameters()), 0);
766 send(Messages::WebPage::SetSmartInsertDeleteEnabled(m_isSmartInsertDeleteEnabled));
770 void WebPageProxy::close()
777 if (m_activePopupMenu)
778 m_activePopupMenu->cancelTracking();
780 #if ENABLE(CONTEXT_MENUS)
781 if (m_activeContextMenu)
782 m_activeContextMenu->cancelTracking();
785 m_backForwardList->pageClosed();
786 m_pageClient.pageClosed();
788 m_process->disconnectFramesFromPage(this);
790 resetState(ResetStateReason::PageInvalidated);
792 m_loaderClient = std::make_unique<API::LoaderClient>();
793 m_policyClient = std::make_unique<API::PolicyClient>();
794 m_formClient = std::make_unique<API::FormClient>();
795 m_uiClient = std::make_unique<API::UIClient>();
797 m_uiPopupMenuClient.initialize(nullptr);
799 m_findClient = std::make_unique<API::FindClient>();
800 m_findMatchesClient.initialize(nullptr);
801 m_diagnosticLoggingClient = std::make_unique<API::DiagnosticLoggingClient>();
802 #if ENABLE(CONTEXT_MENUS)
803 m_contextMenuClient = std::make_unique<API::ContextMenuClient>();
806 m_webProcessLifetimeTracker.pageWasInvalidated();
808 m_process->send(Messages::WebPage::Close(), m_pageID);
809 m_process->removeWebPage(m_pageID);
810 m_process->removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID);
811 m_process->processPool().supplement<WebNotificationManagerProxy>()->clearNotifications(this);
814 bool WebPageProxy::tryClose()
819 m_process->send(Messages::WebPage::TryClose(), m_pageID);
820 m_process->responsivenessTimer()->start();
824 bool WebPageProxy::maybeInitializeSandboxExtensionHandle(const URL& url, SandboxExtension::Handle& sandboxExtensionHandle)
826 if (!url.isLocalFile())
829 if (m_process->hasAssumedReadAccessToURL(url))
832 // Inspector resources are in a directory with assumed access.
833 ASSERT_WITH_SECURITY_IMPLICATION(!WebInspectorProxy::isInspectorPage(*this));
835 SandboxExtension::createHandle("/", SandboxExtension::ReadOnly, sandboxExtensionHandle);
839 RefPtr<API::Navigation> WebPageProxy::loadRequest(const ResourceRequest& request, API::Object* userData)
844 auto navigation = m_navigationState->createLoadRequestNavigation(request);
846 auto transaction = m_pageLoadState.transaction();
848 m_pageLoadState.setPendingAPIRequestURL(transaction, request.url());
851 reattachToWebProcess();
853 SandboxExtension::Handle sandboxExtensionHandle;
854 bool createdExtension = maybeInitializeSandboxExtensionHandle(request.url(), sandboxExtensionHandle);
855 if (createdExtension)
856 m_process->willAcquireUniversalFileReadSandboxExtension();
857 m_process->send(Messages::WebPage::LoadRequest(navigation->navigationID(), request, sandboxExtensionHandle, UserData(process().transformObjectsToHandles(userData).get())), m_pageID);
858 m_process->responsivenessTimer()->start();
860 return WTF::move(navigation);
863 RefPtr<API::Navigation> WebPageProxy::loadFile(const String& fileURLString, const String& resourceDirectoryURLString, API::Object* userData)
869 reattachToWebProcess();
871 URL fileURL = URL(URL(), fileURLString);
872 if (!fileURL.isLocalFile())
875 URL resourceDirectoryURL;
876 if (resourceDirectoryURLString.isNull())
877 resourceDirectoryURL = URL(ParsedURLString, ASCIILiteral("file:///"));
879 resourceDirectoryURL = URL(URL(), resourceDirectoryURLString);
880 if (!resourceDirectoryURL.isLocalFile())
884 auto navigation = m_navigationState->createLoadRequestNavigation(ResourceRequest(fileURL));
886 auto transaction = m_pageLoadState.transaction();
888 m_pageLoadState.setPendingAPIRequestURL(transaction, fileURLString);
890 String resourceDirectoryPath = resourceDirectoryURL.fileSystemPath();
892 SandboxExtension::Handle sandboxExtensionHandle;
893 SandboxExtension::createHandle(resourceDirectoryPath, SandboxExtension::ReadOnly, sandboxExtensionHandle);
894 m_process->assumeReadAccessToBaseURL(resourceDirectoryURL);
895 m_process->send(Messages::WebPage::LoadRequest(navigation->navigationID(), fileURL, sandboxExtensionHandle, UserData(process().transformObjectsToHandles(userData).get())), m_pageID);
896 m_process->responsivenessTimer()->start();
898 return WTF::move(navigation);
901 RefPtr<API::Navigation> WebPageProxy::loadData(API::Data* data, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData)
906 auto navigation = m_navigationState->createLoadDataNavigation();
908 auto transaction = m_pageLoadState.transaction();
910 m_pageLoadState.setPendingAPIRequestURL(transaction, !baseURL.isEmpty() ? baseURL : ASCIILiteral("about:blank"));
913 reattachToWebProcess();
915 m_process->assumeReadAccessToBaseURL(baseURL);
916 m_process->send(Messages::WebPage::LoadData(data->dataReference(), MIMEType, encoding, baseURL, UserData(process().transformObjectsToHandles(userData).get())), m_pageID);
917 m_process->responsivenessTimer()->start();
919 return WTF::move(navigation);
922 // FIXME: Get rid of loadHTMLString and just use loadData instead.
923 RefPtr<API::Navigation> WebPageProxy::loadHTMLString(const String& htmlString, const String& baseURL, API::Object* userData)
928 auto navigation = m_navigationState->createLoadDataNavigation();
930 auto transaction = m_pageLoadState.transaction();
932 m_pageLoadState.setPendingAPIRequestURL(transaction, !baseURL.isEmpty() ? baseURL : ASCIILiteral("about:blank"));
935 reattachToWebProcess();
937 m_process->assumeReadAccessToBaseURL(baseURL);
938 m_process->send(Messages::WebPage::LoadHTMLString(navigation->navigationID(), htmlString, baseURL, UserData(process().transformObjectsToHandles(userData).get())), m_pageID);
939 m_process->responsivenessTimer()->start();
941 return WTF::move(navigation);
944 void WebPageProxy::loadAlternateHTMLString(const String& htmlString, const String& baseURL, const String& unreachableURL, API::Object* userData)
950 reattachToWebProcess();
952 auto transaction = m_pageLoadState.transaction();
954 m_pageLoadState.setUnreachableURL(transaction, unreachableURL);
957 m_mainFrame->setUnreachableURL(unreachableURL);
959 m_process->assumeReadAccessToBaseURL(baseURL);
960 m_process->assumeReadAccessToBaseURL(unreachableURL);
961 m_process->send(Messages::WebPage::LoadAlternateHTMLString(htmlString, baseURL, unreachableURL, UserData(process().transformObjectsToHandles(userData).get())), m_pageID);
962 m_process->responsivenessTimer()->start();
965 void WebPageProxy::loadPlainTextString(const String& string, API::Object* userData)
971 reattachToWebProcess();
973 m_process->send(Messages::WebPage::LoadPlainTextString(string, UserData(process().transformObjectsToHandles(userData).get())), m_pageID);
974 m_process->responsivenessTimer()->start();
977 void WebPageProxy::loadWebArchiveData(API::Data* webArchiveData, API::Object* userData)
983 reattachToWebProcess();
985 m_process->send(Messages::WebPage::LoadWebArchiveData(webArchiveData->dataReference(), UserData(process().transformObjectsToHandles(userData).get())), m_pageID);
986 m_process->responsivenessTimer()->start();
989 void WebPageProxy::navigateToURLWithSimulatedClick(const String& url, IntPoint documentPoint, IntPoint screenPoint)
995 reattachToWebProcess();
997 m_process->send(Messages::WebPage::NavigateToURLWithSimulatedClick(url, documentPoint, screenPoint), m_pageID);
998 m_process->responsivenessTimer()->start();
1001 void WebPageProxy::stopLoading()
1006 m_process->send(Messages::WebPage::StopLoading(), m_pageID);
1007 m_process->responsivenessTimer()->start();
1010 RefPtr<API::Navigation> WebPageProxy::reload(bool reloadFromOrigin)
1012 SandboxExtension::Handle sandboxExtensionHandle;
1014 if (m_backForwardList->currentItem()) {
1015 String url = m_backForwardList->currentItem()->url();
1016 auto transaction = m_pageLoadState.transaction();
1017 m_pageLoadState.setPendingAPIRequestURL(transaction, url);
1019 // We may not have an extension yet if back/forward list was reinstated after a WebProcess crash or a browser relaunch
1020 bool createdExtension = maybeInitializeSandboxExtensionHandle(URL(URL(), url), sandboxExtensionHandle);
1021 if (createdExtension)
1022 m_process->willAcquireUniversalFileReadSandboxExtension();
1026 return reattachToWebProcessForReload();
1028 auto navigation = m_navigationState->createReloadNavigation();
1030 m_process->send(Messages::WebPage::Reload(navigation->navigationID(), reloadFromOrigin, sandboxExtensionHandle), m_pageID);
1031 m_process->responsivenessTimer()->start();
1033 return WTF::move(navigation);
1036 void WebPageProxy::recordNavigationSnapshot()
1038 if (WebBackForwardListItem* item = m_backForwardList->currentItem())
1039 recordNavigationSnapshot(*item);
1042 void WebPageProxy::recordNavigationSnapshot(WebBackForwardListItem& item)
1044 if (!m_shouldRecordNavigationSnapshots)
1048 ViewSnapshotStore::singleton().recordSnapshot(*this, item);
1054 RefPtr<API::Navigation> WebPageProxy::goForward()
1056 WebBackForwardListItem* forwardItem = m_backForwardList->forwardItem();
1060 auto transaction = m_pageLoadState.transaction();
1062 m_pageLoadState.setPendingAPIRequestURL(transaction, forwardItem->url());
1065 return reattachToWebProcessWithItem(forwardItem);
1067 RefPtr<API::Navigation> navigation;
1068 if (!m_backForwardList->currentItem()->itemIsInSameDocument(*forwardItem))
1069 navigation = m_navigationState->createBackForwardNavigation();
1071 m_process->send(Messages::WebPage::GoForward(navigation ? navigation->navigationID() : 0, forwardItem->itemID()), m_pageID);
1072 m_process->responsivenessTimer()->start();
1077 RefPtr<API::Navigation> WebPageProxy::goBack()
1079 WebBackForwardListItem* backItem = m_backForwardList->backItem();
1083 auto transaction = m_pageLoadState.transaction();
1085 m_pageLoadState.setPendingAPIRequestURL(transaction, backItem->url());
1088 return reattachToWebProcessWithItem(backItem);
1090 RefPtr<API::Navigation> navigation;
1091 if (!m_backForwardList->currentItem()->itemIsInSameDocument(*backItem))
1092 navigation = m_navigationState->createBackForwardNavigation();
1094 m_process->send(Messages::WebPage::GoBack(navigation ? navigation->navigationID() : 0, backItem->itemID()), m_pageID);
1095 m_process->responsivenessTimer()->start();
1100 RefPtr<API::Navigation> WebPageProxy::goToBackForwardItem(WebBackForwardListItem* item)
1103 return reattachToWebProcessWithItem(item);
1105 auto transaction = m_pageLoadState.transaction();
1107 m_pageLoadState.setPendingAPIRequestURL(transaction, item->url());
1109 RefPtr<API::Navigation> navigation;
1110 if (!m_backForwardList->currentItem()->itemIsInSameDocument(*item))
1111 navigation = m_navigationState->createBackForwardNavigation();
1113 m_process->send(Messages::WebPage::GoToBackForwardItem(navigation ? navigation->navigationID() : 0, item->itemID()), m_pageID);
1114 m_process->responsivenessTimer()->start();
1119 void WebPageProxy::tryRestoreScrollPosition()
1124 m_process->send(Messages::WebPage::TryRestoreScrollPosition(), m_pageID);
1127 void WebPageProxy::didChangeBackForwardList(WebBackForwardListItem* added, Vector<RefPtr<WebBackForwardListItem>> removed)
1129 m_loaderClient->didChangeBackForwardList(*this, added, WTF::move(removed));
1131 auto transaction = m_pageLoadState.transaction();
1133 m_pageLoadState.setCanGoBack(transaction, m_backForwardList->backItem());
1134 m_pageLoadState.setCanGoForward(transaction, m_backForwardList->forwardItem());
1137 void WebPageProxy::willGoToBackForwardListItem(uint64_t itemID, const UserData& userData)
1139 if (WebBackForwardListItem* item = m_process->webBackForwardItem(itemID))
1140 m_loaderClient->willGoToBackForwardListItem(*this, item, m_process->transformHandlesToObjects(userData.object()).get());
1143 bool WebPageProxy::shouldKeepCurrentBackForwardListItemInList(WebBackForwardListItem* item)
1145 return m_loaderClient->shouldKeepCurrentBackForwardListItemInList(*this, item);
1148 bool WebPageProxy::canShowMIMEType(const String& mimeType)
1150 if (MIMETypeRegistry::canShowMIMEType(mimeType))
1153 #if ENABLE(NETSCAPE_PLUGIN_API)
1154 String newMimeType = mimeType;
1155 PluginModuleInfo plugin = m_process->processPool().pluginInfoStore().findPlugin(newMimeType, URL());
1156 if (!plugin.path.isNull() && m_preferences->pluginsEnabled())
1158 #endif // ENABLE(NETSCAPE_PLUGIN_API)
1161 // On Mac, we can show PDFs.
1162 if (MIMETypeRegistry::isPDFOrPostScriptMIMEType(mimeType) && !WebProcessPool::omitPDFSupport())
1164 #endif // PLATFORM(COCOA)
1169 #if ENABLE(REMOTE_INSPECTOR)
1170 void WebPageProxy::setAllowsRemoteInspection(bool allow)
1172 if (m_allowsRemoteInspection == allow)
1175 m_allowsRemoteInspection = allow;
1178 m_process->send(Messages::WebPage::SetAllowsRemoteInspection(allow), m_pageID);
1182 void WebPageProxy::setDrawsBackground(bool drawsBackground)
1184 if (m_drawsBackground == drawsBackground)
1187 m_drawsBackground = drawsBackground;
1190 m_process->send(Messages::WebPage::SetDrawsBackground(drawsBackground), m_pageID);
1193 void WebPageProxy::setDrawsTransparentBackground(bool drawsTransparentBackground)
1195 if (m_drawsTransparentBackground == drawsTransparentBackground)
1198 m_drawsTransparentBackground = drawsTransparentBackground;
1201 m_process->send(Messages::WebPage::SetDrawsTransparentBackground(drawsTransparentBackground), m_pageID);
1204 void WebPageProxy::setTopContentInset(float contentInset)
1206 if (m_topContentInset == contentInset)
1209 m_topContentInset = contentInset;
1212 m_process->send(Messages::WebPage::SetTopContentInset(contentInset), m_pageID);
1215 void WebPageProxy::setUnderlayColor(const Color& color)
1217 if (m_underlayColor == color)
1220 m_underlayColor = color;
1223 m_process->send(Messages::WebPage::SetUnderlayColor(color), m_pageID);
1226 void WebPageProxy::viewWillStartLiveResize()
1230 #if ENABLE(INPUT_TYPE_COLOR_POPOVER)
1234 m_process->send(Messages::WebPage::ViewWillStartLiveResize(), m_pageID);
1237 void WebPageProxy::viewWillEndLiveResize()
1241 m_process->send(Messages::WebPage::ViewWillEndLiveResize(), m_pageID);
1244 void WebPageProxy::setViewNeedsDisplay(const IntRect& rect)
1246 m_pageClient.setViewNeedsDisplay(rect);
1249 void WebPageProxy::displayView()
1251 m_pageClient.displayView();
1254 bool WebPageProxy::canScrollView()
1256 return m_pageClient.canScrollView();
1259 void WebPageProxy::scrollView(const IntRect& scrollRect, const IntSize& scrollOffset)
1261 m_pageClient.scrollView(scrollRect, scrollOffset);
1264 void WebPageProxy::requestScroll(const FloatPoint& scrollPosition, bool isProgrammaticScroll)
1266 m_pageClient.requestScroll(scrollPosition, isProgrammaticScroll);
1269 void WebPageProxy::setSuppressVisibilityUpdates(bool flag)
1271 if (m_suppressVisibilityUpdates == flag)
1273 m_suppressVisibilityUpdates = flag;
1275 if (!m_suppressVisibilityUpdates) {
1277 m_viewStateChangeDispatcher->schedule();
1279 dispatchViewStateChange();
1284 void WebPageProxy::updateViewState(ViewState::Flags flagsToUpdate)
1286 m_viewState &= ~flagsToUpdate;
1287 if (flagsToUpdate & ViewState::IsFocused && m_pageClient.isViewFocused())
1288 m_viewState |= ViewState::IsFocused;
1289 if (flagsToUpdate & ViewState::WindowIsActive && m_pageClient.isViewWindowActive())
1290 m_viewState |= ViewState::WindowIsActive;
1291 if (flagsToUpdate & ViewState::IsVisible && m_pageClient.isViewVisible())
1292 m_viewState |= ViewState::IsVisible;
1293 if (flagsToUpdate & ViewState::IsVisibleOrOccluded && m_pageClient.isViewVisibleOrOccluded())
1294 m_viewState |= ViewState::IsVisibleOrOccluded;
1295 if (flagsToUpdate & ViewState::IsInWindow && m_pageClient.isViewInWindow()) {
1296 m_viewState |= ViewState::IsInWindow;
1297 m_viewWasEverInWindow = true;
1299 if (flagsToUpdate & ViewState::IsVisuallyIdle && m_pageClient.isVisuallyIdle())
1300 m_viewState |= ViewState::IsVisuallyIdle;
1303 void WebPageProxy::viewStateDidChange(ViewState::Flags mayHaveChanged, bool wantsSynchronousReply, ViewStateChangeDispatchMode dispatchMode)
1305 m_potentiallyChangedViewStateFlags |= mayHaveChanged;
1306 m_viewStateChangeWantsSynchronousReply = m_viewStateChangeWantsSynchronousReply || wantsSynchronousReply;
1308 if (m_suppressVisibilityUpdates && dispatchMode != ViewStateChangeDispatchMode::Immediate)
1312 bool isNewlyInWindow = !isInWindow() && (mayHaveChanged & ViewState::IsInWindow) && m_pageClient.isViewInWindow();
1313 if (dispatchMode == ViewStateChangeDispatchMode::Immediate || isNewlyInWindow) {
1314 dispatchViewStateChange();
1317 m_viewStateChangeDispatcher->schedule();
1319 UNUSED_PARAM(dispatchMode);
1320 dispatchViewStateChange();
1324 void WebPageProxy::viewDidLeaveWindow()
1326 #if ENABLE(INPUT_TYPE_COLOR_POPOVER)
1327 // When leaving the current page, close the popover color well.
1332 // When leaving the current page, close the video fullscreen.
1333 if (m_videoFullscreenManager)
1334 m_videoFullscreenManager->requestHideAndExitFullscreen();
1338 void WebPageProxy::viewDidEnterWindow()
1340 LayerHostingMode layerHostingMode = m_pageClient.viewLayerHostingMode();
1341 if (m_layerHostingMode != layerHostingMode) {
1342 m_layerHostingMode = layerHostingMode;
1343 m_process->send(Messages::WebPage::SetLayerHostingMode(static_cast<unsigned>(layerHostingMode)), m_pageID);
1347 void WebPageProxy::dispatchViewStateChange()
1350 m_viewStateChangeDispatcher->invalidate();
1356 // If the visibility state may have changed, then so may the visually idle & occluded agnostic state.
1357 if (m_potentiallyChangedViewStateFlags & ViewState::IsVisible)
1358 m_potentiallyChangedViewStateFlags |= ViewState::IsVisibleOrOccluded | ViewState::IsVisuallyIdle;
1360 // Record the prior view state, update the flags that may have changed,
1361 // and check which flags have actually changed.
1362 ViewState::Flags previousViewState = m_viewState;
1363 updateViewState(m_potentiallyChangedViewStateFlags);
1364 ViewState::Flags changed = m_viewState ^ previousViewState;
1366 // We always want to wait for the Web process to reply if we've been in-window before and are coming back in-window.
1367 if (m_viewWasEverInWindow && (changed & ViewState::IsInWindow) && isInWindow())
1368 m_viewStateChangeWantsSynchronousReply = true;
1370 if (changed || m_viewStateChangeWantsSynchronousReply || !m_nextViewStateChangeCallbacks.isEmpty())
1371 m_process->send(Messages::WebPage::SetViewState(m_viewState, m_viewStateChangeWantsSynchronousReply, m_nextViewStateChangeCallbacks), m_pageID);
1373 m_nextViewStateChangeCallbacks.clear();
1375 // This must happen after the SetViewState message is sent, to ensure the page visibility event can fire.
1376 updateActivityToken();
1378 // If we've started the responsiveness timer as part of telling the web process to update the backing store
1379 // state, it might not send back a reply (since it won't paint anything if the web page is hidden) so we
1380 // stop the unresponsiveness timer here.
1381 if ((changed & ViewState::IsVisible) && !isViewVisible())
1382 m_process->responsivenessTimer()->stop();
1384 if (changed & ViewState::IsInWindow) {
1386 viewDidEnterWindow();
1388 viewDidLeaveWindow();
1391 updateBackingStoreDiscardableState();
1393 if (m_viewStateChangeWantsSynchronousReply)
1394 waitForDidUpdateViewState();
1396 m_potentiallyChangedViewStateFlags = ViewState::NoFlags;
1397 m_viewStateChangeWantsSynchronousReply = false;
1400 void WebPageProxy::updateActivityToken()
1402 if (m_viewState & ViewState::IsVisuallyIdle)
1403 m_pageIsUserObservableCount = nullptr;
1404 else if (!m_pageIsUserObservableCount)
1405 m_pageIsUserObservableCount = m_process->processPool().userObservablePageCount();
1408 if (!isViewVisible())
1409 m_activityToken = nullptr;
1410 else if (!m_activityToken)
1411 m_activityToken = m_process->throttler().foregroundActivityToken();
1415 void WebPageProxy::updateProccessSuppressionState()
1417 if (m_preferences->pageVisibilityBasedProcessSuppressionEnabled())
1418 m_preventProcessSuppressionCount = nullptr;
1419 else if (!m_preventProcessSuppressionCount)
1420 m_preventProcessSuppressionCount = m_process->processPool().processSuppressionDisabledForPageCount();
1423 void WebPageProxy::layerHostingModeDidChange()
1428 LayerHostingMode layerHostingMode = m_pageClient.viewLayerHostingMode();
1429 if (m_layerHostingMode == layerHostingMode)
1432 m_layerHostingMode = layerHostingMode;
1433 m_process->send(Messages::WebPage::SetLayerHostingMode(static_cast<unsigned>(layerHostingMode)), m_pageID);
1436 void WebPageProxy::waitForDidUpdateViewState()
1441 if (m_process->state() != WebProcessProxy::State::Running)
1444 // If we have previously timed out with no response from the WebProcess, don't block the UIProcess again until it starts responding.
1445 if (m_waitingForDidUpdateViewState)
1448 m_waitingForDidUpdateViewState = true;
1450 m_drawingArea->waitForDidUpdateViewState();
1453 IntSize WebPageProxy::viewSize() const
1455 return m_pageClient.viewSize();
1458 void WebPageProxy::setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent& keyboardEvent, std::function<void (CallbackBase::Error)> callbackFunction)
1461 callbackFunction(CallbackBase::Error::OwnerWasInvalidated);
1465 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
1466 m_process->send(Messages::WebPage::SetInitialFocus(forward, isKeyboardEventValid, keyboardEvent, callbackID), m_pageID);
1469 void WebPageProxy::setWindowResizerSize(const IntSize& windowResizerSize)
1473 m_process->send(Messages::WebPage::SetWindowResizerSize(windowResizerSize), m_pageID);
1476 void WebPageProxy::clearSelection()
1480 m_process->send(Messages::WebPage::ClearSelection(), m_pageID);
1483 void WebPageProxy::restoreSelectionInFocusedEditableElement()
1487 m_process->send(Messages::WebPage::RestoreSelectionInFocusedEditableElement(), m_pageID);
1490 void WebPageProxy::validateCommand(const String& commandName, std::function<void (const String&, bool, int32_t, CallbackBase::Error)> callbackFunction)
1493 callbackFunction(String(), false, 0, CallbackBase::Error::Unknown);
1497 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
1498 m_process->send(Messages::WebPage::ValidateCommand(commandName, callbackID), m_pageID);
1501 void WebPageProxy::setMaintainsInactiveSelection(bool newValue)
1503 m_maintainsInactiveSelection = newValue;
1506 void WebPageProxy::executeEditCommand(const String& commandName)
1508 static NeverDestroyed<String> ignoreSpellingCommandName(ASCIILiteral("ignoreSpelling"));
1513 if (commandName == ignoreSpellingCommandName)
1514 ++m_pendingLearnOrIgnoreWordMessageCount;
1516 m_process->send(Messages::WebPage::ExecuteEditCommand(commandName), m_pageID);
1519 void WebPageProxy::setEditable(bool editable)
1521 if (editable == m_isEditable)
1526 m_isEditable = editable;
1527 m_process->send(Messages::WebPage::SetEditable(editable), m_pageID);
1531 void WebPageProxy::didCommitLayerTree(const RemoteLayerTreeTransaction&)
1536 #if USE(COORDINATED_GRAPHICS_MULTIPROCESS)
1537 void WebPageProxy::commitPageTransitionViewport()
1542 process().send(Messages::WebPage::CommitPageTransitionViewport(), m_pageID);
1546 #if ENABLE(DRAG_SUPPORT)
1547 void WebPageProxy::dragEntered(DragData& dragData, const String& dragStorageName)
1549 SandboxExtension::Handle sandboxExtensionHandle;
1550 SandboxExtension::HandleArray sandboxExtensionHandleEmptyArray;
1551 performDragControllerAction(DragControllerActionEntered, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionHandleEmptyArray);
1554 void WebPageProxy::dragUpdated(DragData& dragData, const String& dragStorageName)
1556 SandboxExtension::Handle sandboxExtensionHandle;
1557 SandboxExtension::HandleArray sandboxExtensionHandleEmptyArray;
1558 performDragControllerAction(DragControllerActionUpdated, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionHandleEmptyArray);
1561 void WebPageProxy::dragExited(DragData& dragData, const String& dragStorageName)
1563 SandboxExtension::Handle sandboxExtensionHandle;
1564 SandboxExtension::HandleArray sandboxExtensionHandleEmptyArray;
1565 performDragControllerAction(DragControllerActionExited, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionHandleEmptyArray);
1568 void WebPageProxy::performDragOperation(DragData& dragData, const String& dragStorageName, const SandboxExtension::Handle& sandboxExtensionHandle, const SandboxExtension::HandleArray& sandboxExtensionsForUpload)
1570 performDragControllerAction(DragControllerActionPerformDragOperation, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionsForUpload);
1573 void WebPageProxy::performDragControllerAction(DragControllerAction action, DragData& dragData, const String& dragStorageName, const SandboxExtension::Handle& sandboxExtensionHandle, const SandboxExtension::HandleArray& sandboxExtensionsForUpload)
1578 UNUSED_PARAM(dragStorageName);
1579 UNUSED_PARAM(sandboxExtensionHandle);
1580 UNUSED_PARAM(sandboxExtensionsForUpload);
1582 String url = dragData.asURL();
1584 m_process->assumeReadAccessToBaseURL(url);
1585 m_process->send(Messages::WebPage::PerformDragControllerAction(action, dragData), m_pageID);
1587 m_process->send(Messages::WebPage::PerformDragControllerAction(action, dragData.clientPosition(), dragData.globalPosition(), dragData.draggingSourceOperationMask(), dragStorageName, dragData.flags(), sandboxExtensionHandle, sandboxExtensionsForUpload), m_pageID);
1591 void WebPageProxy::didPerformDragControllerAction(uint64_t dragOperation, bool mouseIsOverFileInput, unsigned numberOfItemsToBeAccepted)
1593 MESSAGE_CHECK(dragOperation <= DragOperationDelete);
1595 m_currentDragOperation = static_cast<DragOperation>(dragOperation);
1596 m_currentDragIsOverFileInput = mouseIsOverFileInput;
1597 m_currentDragNumberOfFilesToBeAccepted = numberOfItemsToBeAccepted;
1601 void WebPageProxy::startDrag(const DragData& dragData, const ShareableBitmap::Handle& dragImageHandle)
1603 RefPtr<ShareableBitmap> dragImage = 0;
1604 if (!dragImageHandle.isNull()) {
1605 dragImage = ShareableBitmap::create(dragImageHandle);
1610 m_pageClient.startDrag(dragData, dragImage.release());
1614 void WebPageProxy::dragEnded(const IntPoint& clientPosition, const IntPoint& globalPosition, uint64_t operation)
1618 m_process->send(Messages::WebPage::DragEnded(clientPosition, globalPosition, operation), m_pageID);
1620 #endif // ENABLE(DRAG_SUPPORT)
1622 void WebPageProxy::handleMouseEvent(const NativeWebMouseEvent& event)
1627 // NOTE: This does not start the responsiveness timer because mouse move should not indicate interaction.
1628 if (event.type() != WebEvent::MouseMove)
1629 m_process->responsivenessTimer()->start();
1631 if (m_processingMouseMoveEvent) {
1632 m_nextMouseMoveEvent = std::make_unique<NativeWebMouseEvent>(event);
1636 m_processingMouseMoveEvent = true;
1639 // <https://bugs.webkit.org/show_bug.cgi?id=57904> We need to keep track of the mouse down event in the case where we
1640 // display a popup menu for select elements. When the user changes the selected item,
1641 // we fake a mouse up event by using this stored down event. This event gets cleared
1642 // when the mouse up message is received from WebProcess.
1643 if (event.type() == WebEvent::MouseDown)
1644 m_currentlyProcessedMouseDownEvent = std::make_unique<NativeWebMouseEvent>(event);
1646 if (m_shouldSendEventsSynchronously) {
1647 bool handled = false;
1648 m_process->sendSync(Messages::WebPage::MouseEventSyncForTesting(event), Messages::WebPage::MouseEventSyncForTesting::Reply(handled), m_pageID);
1649 didReceiveEvent(event.type(), handled);
1651 m_process->send(Messages::WebPage::MouseEvent(event), m_pageID);
1654 #if MERGE_WHEEL_EVENTS
1655 static bool canCoalesce(const WebWheelEvent& a, const WebWheelEvent& b)
1657 if (a.position() != b.position())
1659 if (a.globalPosition() != b.globalPosition())
1661 if (a.modifiers() != b.modifiers())
1663 if (a.granularity() != b.granularity())
1666 if (a.phase() != b.phase())
1668 if (a.momentumPhase() != b.momentumPhase())
1670 if (a.hasPreciseScrollingDeltas() != b.hasPreciseScrollingDeltas())
1677 static WebWheelEvent coalesce(const WebWheelEvent& a, const WebWheelEvent& b)
1679 ASSERT(canCoalesce(a, b));
1681 FloatSize mergedDelta = a.delta() + b.delta();
1682 FloatSize mergedWheelTicks = a.wheelTicks() + b.wheelTicks();
1685 FloatSize mergedUnacceleratedScrollingDelta = a.unacceleratedScrollingDelta() + b.unacceleratedScrollingDelta();
1687 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());
1689 return WebWheelEvent(WebEvent::Wheel, b.position(), b.globalPosition(), mergedDelta, mergedWheelTicks, b.granularity(), b.modifiers(), b.timestamp());
1692 #endif // MERGE_WHEEL_EVENTS
1694 static WebWheelEvent coalescedWheelEvent(Deque<NativeWebWheelEvent>& queue, Vector<NativeWebWheelEvent>& coalescedEvents)
1696 ASSERT(!queue.isEmpty());
1697 ASSERT(coalescedEvents.isEmpty());
1699 #if MERGE_WHEEL_EVENTS
1700 NativeWebWheelEvent firstEvent = queue.takeFirst();
1701 coalescedEvents.append(firstEvent);
1703 WebWheelEvent event = firstEvent;
1704 while (!queue.isEmpty() && canCoalesce(event, queue.first())) {
1705 NativeWebWheelEvent firstEvent = queue.takeFirst();
1706 coalescedEvents.append(firstEvent);
1707 event = coalesce(event, firstEvent);
1712 while (!queue.isEmpty())
1713 coalescedEvents.append(queue.takeFirst());
1714 return coalescedEvents.last();
1718 void WebPageProxy::handleWheelEvent(const NativeWebWheelEvent& event)
1720 #if ENABLE(ASYNC_SCROLLING)
1721 if (m_scrollingCoordinatorProxy && m_scrollingCoordinatorProxy->handleWheelEvent(platform(event)))
1728 if (!m_currentlyProcessedWheelEvents.isEmpty()) {
1729 m_wheelEventQueue.append(event);
1730 if (m_wheelEventQueue.size() < wheelEventQueueSizeThreshold)
1732 // The queue has too many wheel events, so push a new event.
1735 if (!m_wheelEventQueue.isEmpty()) {
1736 processNextQueuedWheelEvent();
1740 auto coalescedWheelEvent = std::make_unique<Vector<NativeWebWheelEvent>>();
1741 coalescedWheelEvent->append(event);
1742 m_currentlyProcessedWheelEvents.append(WTF::move(coalescedWheelEvent));
1743 sendWheelEvent(event);
1746 void WebPageProxy::processNextQueuedWheelEvent()
1748 auto nextCoalescedEvent = std::make_unique<Vector<NativeWebWheelEvent>>();
1749 WebWheelEvent nextWheelEvent = coalescedWheelEvent(m_wheelEventQueue, *nextCoalescedEvent.get());
1750 m_currentlyProcessedWheelEvents.append(WTF::move(nextCoalescedEvent));
1751 sendWheelEvent(nextWheelEvent);
1754 void WebPageProxy::sendWheelEvent(const WebWheelEvent& event)
1756 m_process->responsivenessTimer()->start();
1758 if (m_shouldSendEventsSynchronously) {
1759 bool handled = false;
1760 m_process->sendSync(Messages::WebPage::WheelEventSyncForTesting(event), Messages::WebPage::WheelEventSyncForTesting::Reply(handled), m_pageID);
1761 didReceiveEvent(event.type(), handled);
1766 Messages::EventDispatcher::WheelEvent(
1769 shouldUseImplicitRubberBandControl() ? !m_backForwardList->backItem() : rubberBandsAtLeft(),
1770 shouldUseImplicitRubberBandControl() ? !m_backForwardList->forwardItem() : rubberBandsAtRight(),
1772 rubberBandsAtBottom()
1776 void WebPageProxy::handleKeyboardEvent(const NativeWebKeyboardEvent& event)
1781 LOG(KeyHandling, "WebPageProxy::handleKeyboardEvent: %s", webKeyboardEventTypeString(event.type()));
1783 m_keyEventQueue.append(event);
1785 m_process->responsivenessTimer()->start();
1786 if (m_shouldSendEventsSynchronously) {
1787 bool handled = false;
1788 m_process->sendSync(Messages::WebPage::KeyEventSyncForTesting(event), Messages::WebPage::KeyEventSyncForTesting::Reply(handled), m_pageID);
1789 didReceiveEvent(event.type(), handled);
1790 } else if (m_keyEventQueue.size() == 1) // Otherwise, sent from DidReceiveEvent message handler.
1791 m_process->send(Messages::WebPage::KeyEvent(event), m_pageID);
1794 WebPreferencesStore WebPageProxy::preferencesStore() const
1796 if (m_configurationPreferenceValues.isEmpty())
1797 return m_preferences->store();
1799 WebPreferencesStore store = m_preferences->store();
1800 for (const auto& preference : m_configurationPreferenceValues)
1801 store.m_values.set(preference.key, preference.value);
1806 #if ENABLE(NETSCAPE_PLUGIN_API)
1807 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)
1809 MESSAGE_CHECK_URL(urlString);
1811 newMimeType = mimeType.lower();
1812 pluginLoadPolicy = PluginModuleLoadNormally;
1814 PluginData::AllowedPluginTypes allowedPluginTypes = allowOnlyApplicationPlugins ? PluginData::OnlyApplicationPlugins : PluginData::AllPlugins;
1815 PluginModuleInfo plugin = m_process->processPool().pluginInfoStore().findPlugin(newMimeType, URL(URL(), urlString), allowedPluginTypes);
1817 pluginProcessToken = 0;
1821 pluginLoadPolicy = PluginInfoStore::defaultLoadPolicyForPlugin(plugin);
1824 RefPtr<API::Dictionary> pluginInformation = createPluginInformationDictionary(plugin, frameURLString, String(), pageURLString, String(), String());
1825 if (m_navigationClient)
1826 pluginLoadPolicy = m_navigationClient->decidePolicyForPluginLoad(*this, static_cast<PluginModuleLoadPolicy>(pluginLoadPolicy), pluginInformation.get(), unavailabilityDescription);
1828 pluginLoadPolicy = m_loaderClient->pluginLoadPolicy(*this, static_cast<PluginModuleLoadPolicy>(pluginLoadPolicy), pluginInformation.get(), unavailabilityDescription);
1830 UNUSED_PARAM(frameURLString);
1831 UNUSED_PARAM(pageURLString);
1832 UNUSED_PARAM(unavailabilityDescription);
1835 PluginProcessSandboxPolicy pluginProcessSandboxPolicy = PluginProcessSandboxPolicyNormal;
1836 switch (pluginLoadPolicy) {
1837 case PluginModuleLoadNormally:
1838 pluginProcessSandboxPolicy = PluginProcessSandboxPolicyNormal;
1840 case PluginModuleLoadUnsandboxed:
1841 pluginProcessSandboxPolicy = PluginProcessSandboxPolicyUnsandboxed;
1844 case PluginModuleBlocked:
1845 pluginProcessToken = 0;
1849 pluginProcessToken = PluginProcessManager::singleton().pluginProcessToken(plugin, static_cast<PluginProcessType>(processType), pluginProcessSandboxPolicy);
1852 #endif // ENABLE(NETSCAPE_PLUGIN_API)
1854 #if ENABLE(TOUCH_EVENTS)
1856 bool WebPageProxy::shouldStartTrackingTouchEvents(const WebTouchEvent& touchStartEvent) const
1858 #if ENABLE(ASYNC_SCROLLING)
1859 for (auto& touchPoint : touchStartEvent.touchPoints()) {
1860 if (m_scrollingCoordinatorProxy->isPointInNonFastScrollableRegion(touchPoint.location()))
1866 UNUSED_PARAM(touchStartEvent);
1867 #endif // ENABLE(ASYNC_SCROLLING)
1873 #if ENABLE(IOS_TOUCH_EVENTS)
1874 void WebPageProxy::handleTouchEventSynchronously(const NativeWebTouchEvent& event)
1879 if (event.type() == WebEvent::TouchStart) {
1880 m_isTrackingTouchEvents = shouldStartTrackingTouchEvents(event);
1881 m_layerTreeTransactionIdAtLastTouchStart = downcast<RemoteLayerTreeDrawingAreaProxy>(*drawingArea()).lastCommittedLayerTreeTransactionID();
1884 if (!m_isTrackingTouchEvents)
1887 m_process->responsivenessTimer()->start();
1888 bool handled = false;
1889 m_process->sendSync(Messages::WebPage::TouchEventSync(event), Messages::WebPage::TouchEventSync::Reply(handled), m_pageID);
1890 didReceiveEvent(event.type(), handled);
1891 m_pageClient.doneWithTouchEvent(event, handled);
1892 m_process->responsivenessTimer()->stop();
1894 if (event.allTouchPointsAreReleased())
1895 m_isTrackingTouchEvents = false;
1898 void WebPageProxy::handleTouchEventAsynchronously(const NativeWebTouchEvent& event)
1903 if (!m_isTrackingTouchEvents)
1906 m_process->send(Messages::EventDispatcher::TouchEvent(m_pageID, event), 0);
1908 if (event.allTouchPointsAreReleased())
1909 m_isTrackingTouchEvents = false;
1912 #elif ENABLE(TOUCH_EVENTS)
1913 void WebPageProxy::handleTouchEvent(const NativeWebTouchEvent& event)
1918 if (event.type() == WebEvent::TouchStart)
1919 m_isTrackingTouchEvents = shouldStartTrackingTouchEvents(event);
1921 if (!m_isTrackingTouchEvents)
1924 // If the page is suspended, which should be the case during panning, pinching
1925 // and animation on the page itself (kinetic scrolling, tap to zoom) etc, then
1926 // we do not send any of the events to the page even if is has listeners.
1927 if (!m_isPageSuspended) {
1928 m_touchEventQueue.append(event);
1929 m_process->responsivenessTimer()->start();
1930 if (m_shouldSendEventsSynchronously) {
1931 bool handled = false;
1932 m_process->sendSync(Messages::WebPage::TouchEventSyncForTesting(event), Messages::WebPage::TouchEventSyncForTesting::Reply(handled), m_pageID);
1933 didReceiveEvent(event.type(), handled);
1935 m_process->send(Messages::WebPage::TouchEvent(event), m_pageID);
1937 if (m_touchEventQueue.isEmpty()) {
1938 bool isEventHandled = false;
1939 m_pageClient.doneWithTouchEvent(event, isEventHandled);
1941 // We attach the incoming events to the newest queued event so that all
1942 // the events are delivered in the correct order when the event is dequed.
1943 QueuedTouchEvents& lastEvent = m_touchEventQueue.last();
1944 lastEvent.deferredTouchEvents.append(event);
1948 if (event.allTouchPointsAreReleased())
1949 m_isTrackingTouchEvents = false;
1951 #endif // ENABLE(TOUCH_EVENTS)
1953 void WebPageProxy::scrollBy(ScrollDirection direction, ScrollGranularity granularity)
1958 m_process->send(Messages::WebPage::ScrollBy(direction, granularity), m_pageID);
1961 void WebPageProxy::centerSelectionInVisibleArea()
1966 m_process->send(Messages::WebPage::CenterSelectionInVisibleArea(), m_pageID);
1969 void WebPageProxy::receivedPolicyDecision(PolicyAction action, WebFrameProxy* frame, uint64_t listenerID, API::Navigation* navigation)
1974 auto transaction = m_pageLoadState.transaction();
1976 if (action == PolicyIgnore)
1977 m_pageLoadState.clearPendingAPIRequestURL(transaction);
1979 uint64_t downloadID = 0;
1980 if (action == PolicyDownload) {
1981 // Create a download proxy.
1982 // FIXME: We should ensure that the downloadRequest is never empty.
1983 const ResourceRequest& downloadRequest = m_decidePolicyForResponseRequest ? *m_decidePolicyForResponseRequest : ResourceRequest();
1984 DownloadProxy* download = m_process->processPool().createDownloadProxy(downloadRequest);
1985 downloadID = download->downloadID();
1986 handleDownloadRequest(download);
1989 // If we received a policy decision while in decidePolicyForResponse the decision will
1990 // be sent back to the web process by decidePolicyForResponse.
1991 if (m_inDecidePolicyForResponseSync) {
1992 m_syncMimeTypePolicyActionIsValid = true;
1993 m_syncMimeTypePolicyAction = action;
1994 m_syncMimeTypePolicyDownloadID = downloadID;
1998 // If we received a policy decision while in decidePolicyForNavigationAction the decision will
1999 // be sent back to the web process by decidePolicyForNavigationAction.
2000 if (m_inDecidePolicyForNavigationAction) {
2001 m_syncNavigationActionPolicyActionIsValid = true;
2002 m_syncNavigationActionPolicyAction = action;
2003 m_syncNavigationActionPolicyDownloadID = downloadID;
2007 m_process->send(Messages::WebPage::DidReceivePolicyDecision(frame->frameID(), listenerID, action, navigation ? navigation->navigationID() : 0, downloadID), m_pageID);
2010 void WebPageProxy::setUserAgent(const String& userAgent)
2012 if (m_userAgent == userAgent)
2014 m_userAgent = userAgent;
2018 m_process->send(Messages::WebPage::SetUserAgent(m_userAgent), m_pageID);
2021 void WebPageProxy::setApplicationNameForUserAgent(const String& applicationName)
2023 if (m_applicationNameForUserAgent == applicationName)
2026 m_applicationNameForUserAgent = applicationName;
2027 if (!m_customUserAgent.isEmpty())
2030 setUserAgent(standardUserAgent(m_applicationNameForUserAgent));
2033 void WebPageProxy::setCustomUserAgent(const String& customUserAgent)
2035 if (m_customUserAgent == customUserAgent)
2038 m_customUserAgent = customUserAgent;
2040 if (m_customUserAgent.isEmpty()) {
2041 setUserAgent(standardUserAgent(m_applicationNameForUserAgent));
2045 setUserAgent(m_customUserAgent);
2048 void WebPageProxy::resumeActiveDOMObjectsAndAnimations()
2050 if (!isValid() || !m_isPageSuspended)
2053 m_isPageSuspended = false;
2055 m_process->send(Messages::WebPage::ResumeActiveDOMObjectsAndAnimations(), m_pageID);
2058 void WebPageProxy::suspendActiveDOMObjectsAndAnimations()
2060 if (!isValid() || m_isPageSuspended)
2063 m_isPageSuspended = true;
2065 m_process->send(Messages::WebPage::SuspendActiveDOMObjectsAndAnimations(), m_pageID);
2068 bool WebPageProxy::supportsTextEncoding() const
2070 // FIXME (118840): We should probably only support this for text documents, not all non-image documents.
2071 return m_mainFrame && !m_mainFrame->isDisplayingStandaloneImageDocument();
2074 void WebPageProxy::setCustomTextEncodingName(const String& encodingName)
2076 if (m_customTextEncodingName == encodingName)
2078 m_customTextEncodingName = encodingName;
2082 m_process->send(Messages::WebPage::SetCustomTextEncodingName(encodingName), m_pageID);
2085 void WebPageProxy::terminateProcess()
2087 // requestTermination() is a no-op for launching processes, so we get into an inconsistent state by calling resetStateAfterProcessExited().
2088 // FIXME: A client can terminate the page at any time, so we should do something more meaningful than assert and fall apart in release builds.
2089 // See also <https://bugs.webkit.org/show_bug.cgi?id=136012>.
2090 ASSERT(m_process->state() != WebProcessProxy::State::Launching);
2092 // NOTE: This uses a check of m_isValid rather than calling isValid() since
2093 // we want this to run even for pages being closed or that already closed.
2097 m_process->requestTermination();
2098 resetStateAfterProcessExited();
2101 SessionState WebPageProxy::sessionState(const std::function<bool (WebBackForwardListItem&)>& filter) const
2103 SessionState sessionState;
2105 sessionState.backForwardListState = m_backForwardList->backForwardListState(filter);
2107 String provisionalURLString = m_pageLoadState.pendingAPIRequestURL();
2108 if (provisionalURLString.isEmpty())
2109 provisionalURLString = m_pageLoadState.provisionalURL();
2111 if (!provisionalURLString.isEmpty())
2112 sessionState.provisionalURL = URL(URL(), provisionalURLString);
2114 sessionState.renderTreeSize = renderTreeSize();
2115 return sessionState;
2118 RefPtr<API::Navigation> WebPageProxy::restoreFromSessionState(SessionState sessionState, bool navigate)
2120 m_sessionRestorationRenderTreeSize = 0;
2121 m_hitRenderTreeSizeThreshold = false;
2123 bool hasBackForwardList = !!sessionState.backForwardListState.currentIndex;
2125 if (hasBackForwardList) {
2126 m_backForwardList->restoreFromState(WTF::move(sessionState.backForwardListState));
2128 for (const auto& entry : m_backForwardList->entries())
2129 process().registerNewWebBackForwardListItem(entry.get());
2131 process().send(Messages::WebPage::RestoreSession(m_backForwardList->itemStates()), m_pageID);
2134 // FIXME: Navigating should be separate from state restoration.
2136 m_sessionRestorationRenderTreeSize = sessionState.renderTreeSize;
2137 if (!m_sessionRestorationRenderTreeSize)
2138 m_hitRenderTreeSizeThreshold = true; // If we didn't get data on renderTreeSize, just don't fire the milestone.
2140 if (!sessionState.provisionalURL.isNull())
2141 return loadRequest(sessionState.provisionalURL);
2143 if (hasBackForwardList) {
2144 // FIXME: Do we have to null check the back forward list item here?
2145 if (WebBackForwardListItem* item = m_backForwardList->currentItem())
2146 return goToBackForwardItem(item);
2153 bool WebPageProxy::supportsTextZoom() const
2155 // FIXME (118840): This should also return false for standalone media and plug-in documents.
2156 if (!m_mainFrame || m_mainFrame->isDisplayingStandaloneImageDocument())
2162 void WebPageProxy::setTextZoomFactor(double zoomFactor)
2167 if (m_textZoomFactor == zoomFactor)
2170 m_textZoomFactor = zoomFactor;
2171 m_process->send(Messages::WebPage::SetTextZoomFactor(m_textZoomFactor), m_pageID);
2174 void WebPageProxy::setPageZoomFactor(double zoomFactor)
2179 if (m_pageZoomFactor == zoomFactor)
2182 m_pageZoomFactor = zoomFactor;
2183 m_process->send(Messages::WebPage::SetPageZoomFactor(m_pageZoomFactor), m_pageID);
2186 void WebPageProxy::setPageAndTextZoomFactors(double pageZoomFactor, double textZoomFactor)
2191 if (m_pageZoomFactor == pageZoomFactor && m_textZoomFactor == textZoomFactor)
2194 m_pageZoomFactor = pageZoomFactor;
2195 m_textZoomFactor = textZoomFactor;
2196 m_process->send(Messages::WebPage::SetPageAndTextZoomFactors(m_pageZoomFactor, m_textZoomFactor), m_pageID);
2199 double WebPageProxy::pageZoomFactor() const
2201 // Zoom factor for non-PDF pages persists across page loads. We maintain a separate member variable for PDF
2202 // zoom which ensures that we don't use the PDF zoom for a normal page.
2203 if (m_mainFrame && m_mainFrame->isDisplayingPDFDocument())
2204 return m_pluginZoomFactor;
2205 return m_pageZoomFactor;
2208 double WebPageProxy::pageScaleFactor() const
2210 // PDF documents use zoom and scale factors to size themselves appropriately in the window. We store them
2211 // separately but decide which to return based on the main frame.
2212 if (m_mainFrame && m_mainFrame->isDisplayingPDFDocument())
2213 return m_pluginScaleFactor;
2214 return m_pageScaleFactor;
2217 void WebPageProxy::scalePage(double scale, const IntPoint& origin)
2224 m_pageScaleFactor = scale;
2225 m_process->send(Messages::WebPage::ScalePage(scale, origin), m_pageID);
2228 void WebPageProxy::scalePageInViewCoordinates(double scale, const IntPoint& centerInViewCoordinates)
2235 m_pageScaleFactor = scale;
2236 m_process->send(Messages::WebPage::ScalePageInViewCoordinates(scale, centerInViewCoordinates), m_pageID);
2239 void WebPageProxy::scaleView(double scale)
2246 m_viewScaleFactor = scale;
2247 m_process->send(Messages::WebPage::ScaleView(scale), m_pageID);
2250 void WebPageProxy::setIntrinsicDeviceScaleFactor(float scaleFactor)
2252 if (m_intrinsicDeviceScaleFactor == scaleFactor)
2255 m_intrinsicDeviceScaleFactor = scaleFactor;
2258 m_drawingArea->deviceScaleFactorDidChange();
2261 void WebPageProxy::windowScreenDidChange(PlatformDisplayID displayID)
2266 m_process->send(Messages::WebPage::WindowScreenDidChange(displayID), m_pageID);
2269 float WebPageProxy::deviceScaleFactor() const
2271 if (m_customDeviceScaleFactor)
2272 return m_customDeviceScaleFactor;
2273 return m_intrinsicDeviceScaleFactor;
2276 void WebPageProxy::setCustomDeviceScaleFactor(float customScaleFactor)
2281 // FIXME: Remove this once we bump cairo requirements to support HiDPI.
2282 // https://bugs.webkit.org/show_bug.cgi?id=133378
2283 #if USE(CAIRO) && !HAVE(CAIRO_SURFACE_SET_DEVICE_SCALE)
2287 if (m_customDeviceScaleFactor == customScaleFactor)
2290 float oldScaleFactor = deviceScaleFactor();
2292 m_customDeviceScaleFactor = customScaleFactor;
2294 if (deviceScaleFactor() != oldScaleFactor)
2295 m_drawingArea->deviceScaleFactorDidChange();
2298 void WebPageProxy::setUseFixedLayout(bool fixed)
2303 // This check is fine as the value is initialized in the web
2304 // process as part of the creation parameters.
2305 if (fixed == m_useFixedLayout)
2308 m_useFixedLayout = fixed;
2310 m_fixedLayoutSize = IntSize();
2311 m_process->send(Messages::WebPage::SetUseFixedLayout(fixed), m_pageID);
2314 void WebPageProxy::setFixedLayoutSize(const IntSize& size)
2319 if (size == m_fixedLayoutSize)
2322 m_fixedLayoutSize = size;
2323 m_process->send(Messages::WebPage::SetFixedLayoutSize(size), m_pageID);
2326 void WebPageProxy::listenForLayoutMilestones(WebCore::LayoutMilestones milestones)
2331 m_wantsSessionRestorationRenderTreeSizeThresholdEvent = milestones & WebCore::ReachedSessionRestorationRenderTreeSizeThreshold;
2333 m_process->send(Messages::WebPage::ListenForLayoutMilestones(milestones), m_pageID);
2336 void WebPageProxy::setSuppressScrollbarAnimations(bool suppressAnimations)
2341 if (suppressAnimations == m_suppressScrollbarAnimations)
2344 m_suppressScrollbarAnimations = suppressAnimations;
2345 m_process->send(Messages::WebPage::SetSuppressScrollbarAnimations(suppressAnimations), m_pageID);
2348 bool WebPageProxy::rubberBandsAtLeft() const
2350 return m_rubberBandsAtLeft;
2353 void WebPageProxy::setRubberBandsAtLeft(bool rubberBandsAtLeft)
2355 m_rubberBandsAtLeft = rubberBandsAtLeft;
2358 bool WebPageProxy::rubberBandsAtRight() const
2360 return m_rubberBandsAtRight;
2363 void WebPageProxy::setRubberBandsAtRight(bool rubberBandsAtRight)
2365 m_rubberBandsAtRight = rubberBandsAtRight;
2368 bool WebPageProxy::rubberBandsAtTop() const
2370 return m_rubberBandsAtTop;
2373 void WebPageProxy::setRubberBandsAtTop(bool rubberBandsAtTop)
2375 m_rubberBandsAtTop = rubberBandsAtTop;
2378 bool WebPageProxy::rubberBandsAtBottom() const
2380 return m_rubberBandsAtBottom;
2383 void WebPageProxy::setRubberBandsAtBottom(bool rubberBandsAtBottom)
2385 m_rubberBandsAtBottom = rubberBandsAtBottom;
2388 void WebPageProxy::setEnableVerticalRubberBanding(bool enableVerticalRubberBanding)
2390 if (enableVerticalRubberBanding == m_enableVerticalRubberBanding)
2393 m_enableVerticalRubberBanding = enableVerticalRubberBanding;
2397 m_process->send(Messages::WebPage::SetEnableVerticalRubberBanding(enableVerticalRubberBanding), m_pageID);
2400 bool WebPageProxy::verticalRubberBandingIsEnabled() const
2402 return m_enableVerticalRubberBanding;
2405 void WebPageProxy::setEnableHorizontalRubberBanding(bool enableHorizontalRubberBanding)
2407 if (enableHorizontalRubberBanding == m_enableHorizontalRubberBanding)
2410 m_enableHorizontalRubberBanding = enableHorizontalRubberBanding;
2414 m_process->send(Messages::WebPage::SetEnableHorizontalRubberBanding(enableHorizontalRubberBanding), m_pageID);
2417 bool WebPageProxy::horizontalRubberBandingIsEnabled() const
2419 return m_enableHorizontalRubberBanding;
2422 void WebPageProxy::setBackgroundExtendsBeyondPage(bool backgroundExtendsBeyondPage)
2424 if (backgroundExtendsBeyondPage == m_backgroundExtendsBeyondPage)
2427 m_backgroundExtendsBeyondPage = backgroundExtendsBeyondPage;
2431 m_process->send(Messages::WebPage::SetBackgroundExtendsBeyondPage(backgroundExtendsBeyondPage), m_pageID);
2434 bool WebPageProxy::backgroundExtendsBeyondPage() const
2436 return m_backgroundExtendsBeyondPage;
2439 void WebPageProxy::setPaginationMode(WebCore::Pagination::Mode mode)
2441 if (mode == m_paginationMode)
2444 m_paginationMode = mode;
2448 m_process->send(Messages::WebPage::SetPaginationMode(mode), m_pageID);
2451 void WebPageProxy::setPaginationBehavesLikeColumns(bool behavesLikeColumns)
2453 if (behavesLikeColumns == m_paginationBehavesLikeColumns)
2456 m_paginationBehavesLikeColumns = behavesLikeColumns;
2460 m_process->send(Messages::WebPage::SetPaginationBehavesLikeColumns(behavesLikeColumns), m_pageID);
2463 void WebPageProxy::setPageLength(double pageLength)
2465 if (pageLength == m_pageLength)
2468 m_pageLength = pageLength;
2472 m_process->send(Messages::WebPage::SetPageLength(pageLength), m_pageID);
2475 void WebPageProxy::setGapBetweenPages(double gap)
2477 if (gap == m_gapBetweenPages)
2480 m_gapBetweenPages = gap;
2484 m_process->send(Messages::WebPage::SetGapBetweenPages(gap), m_pageID);
2487 void WebPageProxy::pageScaleFactorDidChange(double scaleFactor)
2489 m_pageScaleFactor = scaleFactor;
2492 void WebPageProxy::pluginScaleFactorDidChange(double pluginScaleFactor)
2494 m_pluginScaleFactor = pluginScaleFactor;
2497 void WebPageProxy::pluginZoomFactorDidChange(double pluginZoomFactor)
2499 m_pluginZoomFactor = pluginZoomFactor;
2502 void WebPageProxy::findStringMatches(const String& string, FindOptions options, unsigned maxMatchCount)
2504 if (string.isEmpty()) {
2505 didFindStringMatches(string, Vector<Vector<WebCore::IntRect>> (), 0);
2509 m_process->send(Messages::WebPage::FindStringMatches(string, options, maxMatchCount), m_pageID);
2512 void WebPageProxy::findString(const String& string, FindOptions options, unsigned maxMatchCount)
2514 m_process->send(Messages::WebPage::FindString(string, options, maxMatchCount), m_pageID);
2517 void WebPageProxy::getImageForFindMatch(int32_t matchIndex)
2519 m_process->send(Messages::WebPage::GetImageForFindMatch(matchIndex), m_pageID);
2522 void WebPageProxy::selectFindMatch(int32_t matchIndex)
2524 m_process->send(Messages::WebPage::SelectFindMatch(matchIndex), m_pageID);
2527 void WebPageProxy::hideFindUI()
2529 m_process->send(Messages::WebPage::HideFindUI(), m_pageID);
2532 void WebPageProxy::countStringMatches(const String& string, FindOptions options, unsigned maxMatchCount)
2537 m_process->send(Messages::WebPage::CountStringMatches(string, options, maxMatchCount), m_pageID);
2540 void WebPageProxy::runJavaScriptInMainFrame(const String& script, std::function<void (API::SerializedScriptValue*, CallbackBase::Error)> callbackFunction)
2543 callbackFunction(nullptr, CallbackBase::Error::Unknown);
2547 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2548 m_process->send(Messages::WebPage::RunJavaScriptInMainFrame(script, callbackID), m_pageID);
2551 void WebPageProxy::getRenderTreeExternalRepresentation(std::function<void (const String&, CallbackBase::Error)> callbackFunction)
2554 callbackFunction(String(), CallbackBase::Error::Unknown);
2558 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2559 m_process->send(Messages::WebPage::GetRenderTreeExternalRepresentation(callbackID), m_pageID);
2562 void WebPageProxy::getSourceForFrame(WebFrameProxy* frame, std::function<void (const String&, CallbackBase::Error)> callbackFunction)
2565 callbackFunction(String(), CallbackBase::Error::Unknown);
2569 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2570 m_loadDependentStringCallbackIDs.add(callbackID);
2571 m_process->send(Messages::WebPage::GetSourceForFrame(frame->frameID(), callbackID), m_pageID);
2574 void WebPageProxy::getContentsAsString(std::function<void (const String&, CallbackBase::Error)> callbackFunction)
2577 callbackFunction(String(), CallbackBase::Error::Unknown);
2581 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2582 m_loadDependentStringCallbackIDs.add(callbackID);
2583 m_process->send(Messages::WebPage::GetContentsAsString(callbackID), m_pageID);
2586 void WebPageProxy::getBytecodeProfile(std::function<void (const String&, CallbackBase::Error)> callbackFunction)
2589 callbackFunction(String(), CallbackBase::Error::Unknown);
2593 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2594 m_loadDependentStringCallbackIDs.add(callbackID);
2595 m_process->send(Messages::WebPage::GetBytecodeProfile(callbackID), m_pageID);
2599 void WebPageProxy::getContentsAsMHTMLData(std::function<void (API::Data*, CallbackBase::Error)> callbackFunction, bool useBinaryEncoding)
2602 callbackFunction(nullptr, CallbackBase::Error::Unknown);
2606 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2607 m_process->send(Messages::WebPage::GetContentsAsMHTMLData(callbackID, useBinaryEncoding), m_pageID);
2611 void WebPageProxy::getSelectionOrContentsAsString(std::function<void (const String&, CallbackBase::Error)> callbackFunction)
2614 callbackFunction(String(), CallbackBase::Error::Unknown);
2618 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2619 m_process->send(Messages::WebPage::GetSelectionOrContentsAsString(callbackID), m_pageID);
2622 void WebPageProxy::getSelectionAsWebArchiveData(std::function<void (API::Data*, CallbackBase::Error)> callbackFunction)
2625 callbackFunction(nullptr, CallbackBase::Error::Unknown);
2629 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2630 m_process->send(Messages::WebPage::GetSelectionAsWebArchiveData(callbackID), m_pageID);
2633 void WebPageProxy::getMainResourceDataOfFrame(WebFrameProxy* frame, std::function<void (API::Data*, CallbackBase::Error)> callbackFunction)
2635 if (!isValid() || !frame) {
2636 callbackFunction(nullptr, CallbackBase::Error::Unknown);
2640 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2641 m_process->send(Messages::WebPage::GetMainResourceDataOfFrame(frame->frameID(), callbackID), m_pageID);
2644 void WebPageProxy::getResourceDataFromFrame(WebFrameProxy* frame, API::URL* resourceURL, std::function<void (API::Data*, CallbackBase::Error)> callbackFunction)
2647 callbackFunction(nullptr, CallbackBase::Error::Unknown);
2651 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2652 m_process->send(Messages::WebPage::GetResourceDataFromFrame(frame->frameID(), resourceURL->string(), callbackID), m_pageID);
2655 void WebPageProxy::getWebArchiveOfFrame(WebFrameProxy* frame, std::function<void (API::Data*, CallbackBase::Error)> callbackFunction)
2658 callbackFunction(nullptr, CallbackBase::Error::Unknown);
2662 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2663 m_process->send(Messages::WebPage::GetWebArchiveOfFrame(frame->frameID(), callbackID), m_pageID);
2666 void WebPageProxy::forceRepaint(PassRefPtr<VoidCallback> prpCallback)
2668 RefPtr<VoidCallback> callback = prpCallback;
2670 // FIXME: If the page is invalid we should not call the callback. It'd be better to just return false from forceRepaint.
2671 callback->invalidate(CallbackBase::Error::OwnerWasInvalidated);
2675 uint64_t callbackID = callback->callbackID();
2676 m_callbacks.put(callback);
2677 m_drawingArea->waitForBackingStoreUpdateOnNextPaint();
2678 m_process->send(Messages::WebPage::ForceRepaint(callbackID), m_pageID);
2681 void WebPageProxy::preferencesDidChange()
2686 #if ENABLE(INSPECTOR_SERVER)
2687 if (m_preferences->developerExtrasEnabled())
2688 inspector()->enableRemoteInspection();
2691 updateProccessSuppressionState();
2693 m_pageClient.preferencesDidChange();
2695 // FIXME: It probably makes more sense to send individual preference changes.
2696 // However, WebKitTestRunner depends on getting a preference change notification
2697 // even if nothing changed in UI process, so that overrides get removed.
2699 // Preferences need to be updated during synchronous printing to make "print backgrounds" preference work when toggled from a print dialog checkbox.
2700 m_process->send(Messages::WebPage::PreferencesDidChange(preferencesStore()), m_pageID, m_isPerformingDOMPrintOperation ? IPC::DispatchMessageEvenWhenWaitingForSyncReply : 0);
2703 void WebPageProxy::didCreateMainFrame(uint64_t frameID)
2705 MESSAGE_CHECK(!m_mainFrame);
2706 MESSAGE_CHECK(m_process->canCreateFrame(frameID));
2708 m_mainFrame = WebFrameProxy::create(this, frameID);
2710 // Add the frame to the process wide map.
2711 m_process->frameCreated(frameID, m_mainFrame.get());
2714 void WebPageProxy::didCreateSubframe(uint64_t frameID)
2716 MESSAGE_CHECK(m_mainFrame);
2717 MESSAGE_CHECK(m_process->canCreateFrame(frameID));
2719 RefPtr<WebFrameProxy> subFrame = WebFrameProxy::create(this, frameID);
2721 // Add the frame to the process wide map.
2722 m_process->frameCreated(frameID, subFrame.get());
2725 double WebPageProxy::estimatedProgress() const
2727 return m_pageLoadState.estimatedProgress();
2730 void WebPageProxy::didStartProgress()
2732 auto transaction = m_pageLoadState.transaction();
2733 m_pageLoadState.didStartProgress(transaction);
2735 m_pageLoadState.commitChanges();
2736 m_loaderClient->didStartProgress(*this);
2739 void WebPageProxy::didChangeProgress(double value)
2741 auto transaction = m_pageLoadState.transaction();
2742 m_pageLoadState.didChangeProgress(transaction, value);
2744 m_pageLoadState.commitChanges();
2745 m_loaderClient->didChangeProgress(*this);
2748 void WebPageProxy::didFinishProgress()
2750 auto transaction = m_pageLoadState.transaction();
2751 m_pageLoadState.didFinishProgress(transaction);
2753 m_pageLoadState.commitChanges();
2754 m_loaderClient->didFinishProgress(*this);
2757 void WebPageProxy::setNetworkRequestsInProgress(bool networkRequestsInProgress)
2759 auto transaction = m_pageLoadState.transaction();
2760 m_pageLoadState.setNetworkRequestsInProgress(transaction, networkRequestsInProgress);
2763 void WebPageProxy::didDestroyNavigation(uint64_t navigationID)
2765 // FIXME: Message check the navigationID.
2766 m_navigationState->didDestroyNavigation(navigationID);
2769 void WebPageProxy::didStartProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& url, const String& unreachableURL, const UserData& userData)
2771 auto transaction = m_pageLoadState.transaction();
2773 m_pageLoadState.clearPendingAPIRequestURL(transaction);
2775 WebFrameProxy* frame = m_process->webFrame(frameID);
2776 MESSAGE_CHECK(frame);
2777 MESSAGE_CHECK_URL(url);
2779 // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
2780 RefPtr<API::Navigation> navigation;
2781 if (frame->isMainFrame() && navigationID)
2782 navigation = &navigationState().navigation(navigationID);
2784 if (frame->isMainFrame())
2785 m_pageLoadState.didStartProvisionalLoad(transaction, url, unreachableURL);
2787 frame->setUnreachableURL(unreachableURL);
2788 frame->didStartProvisionalLoad(url);
2790 m_pageLoadState.commitChanges();
2791 if (m_navigationClient) {
2792 if (frame->isMainFrame())
2793 m_navigationClient->didStartProvisionalNavigation(*this, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
2795 m_loaderClient->didStartProvisionalLoadForFrame(*this, *frame, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
2798 void WebPageProxy::didReceiveServerRedirectForProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& url, const UserData& userData)
2800 WebFrameProxy* frame = m_process->webFrame(frameID);
2801 MESSAGE_CHECK(frame);
2802 MESSAGE_CHECK_URL(url);
2804 // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
2805 RefPtr<API::Navigation> navigation;
2806 if (frame->isMainFrame() && navigationID)
2807 navigation = &navigationState().navigation(navigationID);
2809 auto transaction = m_pageLoadState.transaction();
2811 if (frame->isMainFrame())
2812 m_pageLoadState.didReceiveServerRedirectForProvisionalLoad(transaction, url);
2814 frame->didReceiveServerRedirectForProvisionalLoad(url);
2816 m_pageLoadState.commitChanges();
2817 if (m_navigationClient) {
2818 if (frame->isMainFrame())
2819 m_navigationClient->didReceiveServerRedirectForProvisionalNavigation(*this, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
2821 m_loaderClient->didReceiveServerRedirectForProvisionalLoadForFrame(*this, *frame, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
2824 void WebPageProxy::didFailProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, const ResourceError& error, const UserData& userData)
2826 WebFrameProxy* frame = m_process->webFrame(frameID);
2827 MESSAGE_CHECK(frame);
2829 // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
2830 RefPtr<API::Navigation> navigation;
2831 if (frame->isMainFrame() && navigationID)
2832 navigation = navigationState().takeNavigation(navigationID);
2834 auto transaction = m_pageLoadState.transaction();
2836 if (frame->isMainFrame())
2837 m_pageLoadState.didFailProvisionalLoad(transaction);
2839 frame->didFailProvisionalLoad();
2841 m_pageLoadState.commitChanges();
2842 if (m_navigationClient) {
2843 if (frame->isMainFrame())
2844 m_navigationClient->didFailProvisionalNavigationWithError(*this, *frame, navigation.get(), error, m_process->transformHandlesToObjects(userData.object()).get());
2846 // FIXME: Get the main frame's current navigation.
2847 m_navigationClient->didFailProvisionalLoadInSubframeWithError(*this, *frame, nullptr, error, m_process->transformHandlesToObjects(userData.object()).get());
2850 m_loaderClient->didFailProvisionalLoadWithErrorForFrame(*this, *frame, navigation.get(), error, m_process->transformHandlesToObjects(userData.object()).get());
2853 void WebPageProxy::clearLoadDependentCallbacks()
2855 Vector<uint64_t> callbackIDsCopy;
2856 copyToVector(m_loadDependentStringCallbackIDs, callbackIDsCopy);
2857 m_loadDependentStringCallbackIDs.clear();
2859 for (size_t i = 0; i < callbackIDsCopy.size(); ++i) {
2860 auto callback = m_callbacks.take<StringCallback>(callbackIDsCopy[i]);
2862 callback->invalidate();
2866 void WebPageProxy::didCommitLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& mimeType, bool frameHasCustomContentProvider, uint32_t opaqueFrameLoadType, const WebCore::CertificateInfo& certificateInfo, const UserData& userData)
2868 WebFrameProxy* frame = m_process->webFrame(frameID);
2869 MESSAGE_CHECK(frame);
2871 // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
2872 RefPtr<API::Navigation> navigation;
2873 if (frame->isMainFrame() && navigationID)
2874 navigation = &navigationState().navigation(navigationID);
2877 if (frame->isMainFrame()) {
2878 m_hasReceivedLayerTreeTransactionAfterDidCommitLoad = false;
2879 m_firstLayerTreeTransactionIdAfterDidCommitLoad = downcast<RemoteLayerTreeDrawingAreaProxy>(*drawingArea()).nextLayerTreeTransactionID();
2883 auto transaction = m_pageLoadState.transaction();
2885 if (frame->isMainFrame()) {
2886 bool hasInsecureCertificateChain = m_treatsSHA1CertificatesAsInsecure && certificateInfo.containsNonRootSHA1SignedCertificate();
2887 m_pageLoadState.didCommitLoad(transaction, hasInsecureCertificateChain);
2891 // FIXME (bug 59111): didCommitLoadForFrame comes too late when restoring a page from b/f cache, making us disable secure event mode in password fields.
2892 // FIXME: A load going on in one frame shouldn't affect text editing in other frames on the page.
2893 m_pageClient.resetSecureInputState();
2894 m_pageClient.dismissContentRelativeChildWindows();
2897 clearLoadDependentCallbacks();
2899 frame->didCommitLoad(mimeType, certificateInfo);
2901 if (frame->isMainFrame()) {
2902 m_mainFrameHasCustomContentProvider = frameHasCustomContentProvider;
2904 if (m_mainFrameHasCustomContentProvider) {
2905 // Always assume that the main frame is pinned here, since the custom representation view will handle
2906 // any wheel events and dispatch them to the WKView when necessary.
2907 m_mainFrameIsPinnedToLeftSide = true;
2908 m_mainFrameIsPinnedToRightSide = true;
2909 m_mainFrameIsPinnedToTopSide = true;
2910 m_mainFrameIsPinnedToBottomSide = true;
2912 m_uiClient->pinnedStateDidChange(*this);
2914 m_pageClient.didCommitLoadForMainFrame(mimeType, frameHasCustomContentProvider);
2917 // Even if WebPage has the default pageScaleFactor (and therefore doesn't reset it),
2918 // WebPageProxy's cache of the value can get out of sync (e.g. in the case where a
2919 // plugin is handling page scaling itself) so we should reset it to the default
2920 // for standard main frame loads.
2921 if (frame->isMainFrame() && static_cast<FrameLoadType>(opaqueFrameLoadType) == FrameLoadType::Standard) {
2922 m_pageScaleFactor = 1;
2923 m_pluginScaleFactor = 1;
2926 m_pageLoadState.commitChanges();
2927 if (m_navigationClient) {
2928 if (frame->isMainFrame())
2929 m_navigationClient->didCommitNavigation(*this, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
2931 m_loaderClient->didCommitLoadForFrame(*this, *frame, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
2934 void WebPageProxy::didFinishDocumentLoadForFrame(uint64_t frameID, uint64_t navigationID, const UserData& userData)
2936 WebFrameProxy* frame = m_process->webFrame(frameID);
2937 MESSAGE_CHECK(frame);
2939 // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
2940 RefPtr<API::Navigation> navigation;
2941 if (frame->isMainFrame() && navigationID)
2942 navigation = &navigationState().navigation(navigationID);
2944 if (m_navigationClient) {
2945 if (frame->isMainFrame())
2946 m_navigationClient->didFinishDocumentLoad(*this, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
2948 m_loaderClient->didFinishDocumentLoadForFrame(*this, *frame, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
2951 void WebPageProxy::didFinishLoadForFrame(uint64_t frameID, uint64_t navigationID, const UserData& userData)
2953 WebFrameProxy* frame = m_process->webFrame(frameID);
2954 MESSAGE_CHECK(frame);
2956 // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
2957 RefPtr<API::Navigation> navigation;
2958 if (frame->isMainFrame() && navigationID)
2959 navigation = &navigationState().navigation(navigationID);
2961 auto transaction = m_pageLoadState.transaction();
2963 bool isMainFrame = frame->isMainFrame();
2965 m_pageLoadState.didFinishLoad(transaction);
2967 frame->didFinishLoad();
2969 m_pageLoadState.commitChanges();
2970 if (m_navigationClient) {
2972 m_navigationClient->didFinishNavigation(*this, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
2974 m_loaderClient->didFinishLoadForFrame(*this, *frame, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
2977 m_pageClient.didFinishLoadForMainFrame();
2980 void WebPageProxy::didFailLoadForFrame(uint64_t frameID, uint64_t navigationID, const ResourceError& error, const UserData& userData)
2982 WebFrameProxy* frame = m_process->webFrame(frameID);
2983 MESSAGE_CHECK(frame);
2985 // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
2986 RefPtr<API::Navigation> navigation;
2987 if (frame->isMainFrame() && navigationID)
2988 navigation = &navigationState().navigation(navigationID);
2990 clearLoadDependentCallbacks();
2992 auto transaction = m_pageLoadState.transaction();
2994 if (frame->isMainFrame())
2995 m_pageLoadState.didFailLoad(transaction);
2997 frame->didFailLoad();
2999 m_pageLoadState.commitChanges();
3000 if (m_navigationClient) {
3001 if (frame->isMainFrame())
3002 m_navigationClient->didFailNavigationWithError(*this, *frame, navigation.get(), error, m_process->transformHandlesToObjects(userData.object()).get());
3004 m_loaderClient->didFailLoadWithErrorForFrame(*this, *frame, navigation.get(), error, m_process->transformHandlesToObjects(userData.object()).get());
3007 void WebPageProxy::didSameDocumentNavigationForFrame(uint64_t frameID, uint64_t navigationID, uint32_t opaqueSameDocumentNavigationType, const String& url, const UserData& userData)
3009 WebFrameProxy* frame = m_process->webFrame(frameID);
3010 MESSAGE_CHECK(frame);
3011 MESSAGE_CHECK_URL(url);
3013 // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
3014 RefPtr<API::Navigation> navigation;
3015 if (frame->isMainFrame() && navigationID)
3016 navigation = &navigationState().navigation(navigationID);
3018 auto transaction = m_pageLoadState.transaction();
3020 bool isMainFrame = frame->isMainFrame();
3022 m_pageLoadState.didSameDocumentNavigation(transaction, url);
3024 m_pageLoadState.clearPendingAPIRequestURL(transaction);
3025 frame->didSameDocumentNavigation(url);
3027 m_pageLoadState.commitChanges();
3029 SameDocumentNavigationType navigationType = static_cast<SameDocumentNavigationType>(opaqueSameDocumentNavigationType);
3030 if (m_navigationClient) {
3032 m_navigationClient->didSameDocumentNavigation(*this, navigation.get(), navigationType, m_process->transformHandlesToObjects(userData.object()).get());
3034 m_loaderClient->didSameDocumentNavigationForFrame(*this, *frame, navigation.get(), navigationType, m_process->transformHandlesToObjects(userData.object()).get());
3037 m_pageClient.didSameDocumentNavigationForMainFrame(navigationType);
3040 void WebPageProxy::didReceiveTitleForFrame(uint64_t frameID, const String& title, const UserData& userData)
3042 WebFrameProxy* frame = m_process->webFrame(frameID);
3043 MESSAGE_CHECK(frame);
3045 auto transaction = m_pageLoadState.transaction();
3047 if (frame->isMainFrame())
3048 m_pageLoadState.setTitle(transaction, title);
3050 frame->didChangeTitle(title);
3052 m_pageLoadState.commitChanges();
3053 m_loaderClient->didReceiveTitleForFrame(*this, title, *frame, m_process->transformHandlesToObjects(userData.object()).get());
3056 void WebPageProxy::didFirstLayoutForFrame(uint64_t frameID, const UserData& userData)
3058 WebFrameProxy* frame = m_process->webFrame(frameID);
3059 MESSAGE_CHECK(frame);
3061 m_loaderClient->didFirstLayoutForFrame(*this, *frame, m_process->transformHandlesToObjects(userData.object()).get());
3064 void WebPageProxy::didFirstVisuallyNonEmptyLayoutForFrame(uint64_t frameID, const UserData& userData)
3066 WebFrameProxy* frame = m_process->webFrame(frameID);
3067 MESSAGE_CHECK(frame);
3069 m_loaderClient->didFirstVisuallyNonEmptyLayoutForFrame(*this, *frame, m_process->transformHandlesToObjects(userData.object()).get());
3071 if (frame->isMainFrame())
3072 m_pageClient.didFirstVisuallyNonEmptyLayoutForMainFrame();
3075 void WebPageProxy::didLayout(uint32_t layoutMilestones, const UserData& userData)
3077 if (m_navigationClient)
3078 m_navigationClient->renderingProgressDidChange(*this, static_cast<LayoutMilestones>(layoutMilestones), m_process->transformHandlesToObjects(userData.object()).get());
3080 m_loaderClient->didLayout(*this, static_cast<LayoutMilestones>(layoutMilestones), m_process->transformHandlesToObjects(userData.object()).get());
3083 void WebPageProxy::didRemoveFrameFromHierarchy(uint64_t frameID, const UserData& userData)
3085 WebFrameProxy* frame = m_process->webFrame(frameID);
3086 MESSAGE_CHECK(frame);
3088 m_loaderClient->didRemoveFrameFromHierarchy(*this, *frame, m_process->transformHandlesToObjects(userData.object()).get());
3091 void WebPageProxy::didDisplayInsecureContentForFrame(uint64_t frameID, const UserData& userData)
3093 WebFrameProxy* frame = m_process->webFrame(frameID);
3094 MESSAGE_CHECK(frame);
3096 auto transaction = m_pageLoadState.transaction();
3097 m_pageLoadState.didDisplayOrRunInsecureContent(transaction);
3099 m_pageLoadState.commitChanges();
3100 m_loaderClient->didDisplayInsecureContentForFrame(*this, *frame, m_process->transformHandlesToObjects(userData.object()).get());
3103 void WebPageProxy::didRunInsecureContentForFrame(uint64_t frameID, const UserData& userData)
3105 WebFrameProxy* frame = m_process->webFrame(frameID);
3106 MESSAGE_CHECK(frame);
3108 auto transaction = m_pageLoadState.transaction();
3109 m_pageLoadState.didDisplayOrRunInsecureContent(transaction);
3111 m_pageLoadState.commitChanges();
3112 m_loaderClient->didRunInsecureContentForFrame(*this, *frame, m_process->transformHandlesToObjects(userData.object()).get());
3115 void WebPageProxy::didDetectXSSForFrame(uint64_t frameID, const UserData& userData)
3117 WebFrameProxy* frame = m_process->webFrame(frameID);
3118 MESSAGE_CHECK(frame);
3120 m_loaderClient->didDetectXSSForFrame(*this, *frame, m_process->transformHandlesToObjects(userData.object()).get());
3123 void WebPageProxy::frameDidBecomeFrameSet(uint64_t frameID, bool value)
3125 WebFrameProxy* frame = m_process->webFrame(frameID);
3126 MESSAGE_CHECK(frame);
3128 frame->setIsFrameSet(value);
3129 if (frame->isMainFrame())
3130 m_frameSetLargestFrame = value ? m_mainFrame : 0;
3133 void WebPageProxy::decidePolicyForNavigationAction(uint64_t frameID, uint64_t navigationID, const NavigationActionData& navigationActionData, uint64_t originatingFrameID, const WebCore::ResourceRequest& originalRequest, const ResourceRequest& request, uint64_t listenerID, const UserData& userData, bool& receivedPolicyAction, uint64_t& newNavigationID, uint64_t& policyAction, uint64_t& downloadID)
3135 auto transaction = m_pageLoadState.transaction();
3137 if (request.url() != m_pageLoadState.pendingAPIRequestURL())
3138 m_pageLoadState.clearPendingAPIRequestURL(transaction);
3140 WebFrameProxy* frame = m_process->webFrame(frameID);
3141 MESSAGE_CHECK(frame);
3142 MESSAGE_CHECK_URL(request.url());
3143 MESSAGE_CHECK_URL(originalRequest.url());
3145 WebFrameProxy* originatingFrame = m_process->webFrame(originatingFrameID);
3147 Ref<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
3148 if (!navigationID && frame->isMainFrame()) {
3149 auto navigation = m_navigationState->createLoadRequestNavigation(request);
3150 newNavigationID = navigation->navigationID();
3151 listener->setNavigation(WTF::move(navigation));
3154 #if ENABLE(CONTENT_FILTERING)
3155 if (frame->didHandleContentFilterUnblockNavigation(request)) {
3156 receivedPolicyAction = true;
3157 policyAction = PolicyIgnore;
3162 ASSERT(!m_inDecidePolicyForNavigationAction);
3164 m_inDecidePolicyForNavigationAction = true;
3165 m_syncNavigationActionPolicyActionIsValid = false;
3167 if (m_navigationClient) {
3168 RefPtr<API::FrameInfo> destinationFrameInfo;
3169 RefPtr<API::FrameInfo> sourceFrameInfo;
3172 destinationFrameInfo = API::FrameInfo::create(*frame);
3174 if (originatingFrame == frame)
3175 sourceFrameInfo = destinationFrameInfo;
3176 else if (originatingFrame)
3177 sourceFrameInfo = API::FrameInfo::create(*originatingFrame);
3179 auto navigationAction = API::NavigationAction::create(navigationActionData, sourceFrameInfo.get(), destinationFrameInfo.get(), request, originalRequest.url());
3181 m_navigationClient->decidePolicyForNavigationAction(*this, navigationAction.get(), WTF::move(listener), m_process->transformHandlesToObjects(userData.object()).get());
3183 m_policyClient->decidePolicyForNavigationAction(*this, frame, navigationActionData, originatingFrame, originalRequest, request, WTF::move(listener), m_process->transformHandlesToObjects(userData.object()).get());
3185 m_inDecidePolicyForNavigationAction = false;
3187 // Check if we received a policy decision already. If we did, we can just pass it back.
3188 receivedPolicyAction = m_syncNavigationActionPolicyActionIsValid;
3189 if (m_syncNavigationActionPolicyActionIsValid) {
3190 policyAction = m_syncNavigationActionPolicyAction;
3191 downloadID = m_syncNavigationActionPolicyDownloadID;
3195 void WebPageProxy::decidePolicyForNewWindowAction(uint64_t frameID, const NavigationActionData& navigationActionData, const ResourceRequest& request, const String& frameName, uint64_t listenerID, const UserData& userData)
3197 WebFrameProxy* frame = m_process->webFrame(frameID);
3198 MESSAGE_CHECK(frame);
3199 MESSAGE_CHECK_URL(request.url());
3201 Ref<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
3203 if (m_navigationClient) {
3204 RefPtr<API::FrameInfo> sourceFrameInfo;
3206 sourceFrameInfo = API::FrameInfo::create(*frame);
3208 auto navigationAction = API::NavigationAction::create(navigationActionData, sourceFrameInfo.get(), nullptr, request, request.url());
3210 m_navigationClient->decidePolicyForNavigationAction(*this, navigationAction.get(), WTF::move(listener), m_process->transformHandlesToObjects(userData.object()).get());
3213 m_policyClient->decidePolicyForNewWindowAction(*this, *frame, navigationActionData, request, frameName, WTF::move(listener), m_process->transformHandlesToObjects(userData.object()).get());
3216 void WebPageProxy::decidePolicyForResponse(uint64_t frameID, const ResourceResponse& response, const ResourceRequest& request, bool canShowMIMEType, uint64_t listenerID, const UserData& userData)
3218 WebFrameProxy* frame = m_process->webFrame(frameID);
3219 MESSAGE_CHECK(frame);
3220 MESSAGE_CHECK_URL(request.url());
3221 MESSAGE_CHECK_URL(response.url());
3223 Ref<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
3225 if (m_navigationClient) {
3226 auto navigationResponse = API::NavigationResponse::create(API::FrameInfo::create(*frame).get(), request, response, canShowMIMEType);
3227 m_navigationClient->decidePolicyForNavigationResponse(*this, navigationResponse.get(), WTF::move(listener), m_process->transformHandlesToObjects(userData.object()).get());
3229 m_policyClient->decidePolicyForResponse(*this, *frame, response, request, canShowMIMEType, WTF::move(listener), m_process->transformHandlesToObjects(userData.object()).get());
3232 void WebPageProxy::decidePolicyForResponseSync(uint64_t frameID, const ResourceResponse& response, const ResourceRequest& request, bool canShowMIMEType, uint64_t listenerID, const UserData& userData, bool& receivedPolicyAction, uint64_t& policyAction, uint64_t& downloadID)
3234 ASSERT(!m_inDecidePolicyForResponseSync);
3236 m_inDecidePolicyForResponseSync = true;
3237 m_decidePolicyForResponseRequest = &request;
3238 m_syncMimeTypePolicyActionIsValid = false;
3240 decidePolicyForResponse(frameID, response, request, canShowMIMEType, listenerID, userData);
3242 m_inDecidePolicyForResponseSync = false;
3243 m_decidePolicyForResponseRequest = 0;
3245 // Check if we received a policy decision already. If we did, we can just pass it back.
3246 receivedPolicyAction = m_syncMimeTypePolicyActionIsValid;
3247 if (m_syncMimeTypePolicyActionIsValid) {
3248 policyAction = m_syncMimeTypePolicyAction;
3249 downloadID = m_syncMimeTypePolicyDownloadID;
3253 void WebPageProxy::unableToImplementPolicy(uint64_t frameID, const ResourceError& error, const UserData& userData)
3255 WebFrameProxy* frame = m_process->webFrame(frameID);
3256 MESSAGE_CHECK(frame);
3258 m_policyClient->unableToImplementPolicy(*this, *frame, error, m_process->transformHandlesToObjects(userData.object()).get());
3263 void WebPageProxy::willSubmitForm(uint64_t frameID, uint64_t sourceFrameID, const Vector<std::pair<String, String>>& textFieldValues, uint64_t listenerID, const UserData& userData)
3265 WebFrameProxy* frame = m_process->webFrame(frameID);
3266 MESSAGE_CHECK(frame);
3268 WebFrameProxy* sourceFrame = m_process->webFrame(sourceFrameID);
3269 MESSAGE_CHECK(sourceFrame);
3271 Ref<WebFormSubmissionListenerProxy> listener = frame->setUpFormSubmissionListenerProxy(listenerID);
3272 m_formClient->willSubmitForm(*this, *frame, *sourceFrame, textFieldValues, m_process->transformHandlesToObjects(userData.object()).get(), listener.get());
3275 void WebPageProxy::didNavigateWithNavigationData(const WebNavigationDataStore& store, uint64_t frameID)
3277 WebFrameProxy* frame = m_process->webFrame(frameID);
3278 MESSAGE_CHECK(frame);
3279 MESSAGE_CHECK(frame->page() == this);
3281 if (m_historyClient) {
3282 if (frame->isMainFrame())
3283 m_historyClient->didNavigateWithNavigationData(*this, store);
3285 m_loaderClient->didNavigateWithNavigationData(*this, store, *frame);
3286 process().processPool().historyClient().didNavigateWithNavigationData(process().processPool(), *this, store, *frame);
3289 void WebPageProxy::didPerformClientRedirect(const String& sourceURLString, const String& destinationURLString, uint64_t frameID)
3291 if (sourceURLString.isEmpty() || destinationURLString.isEmpty())
3294 WebFrameProxy* frame = m_process->webFrame(frameID);
3295 MESSAGE_CHECK(frame);
3296 MESSAGE_CHECK(frame->page() == this);
3298 MESSAGE_CHECK_URL(sourceURLString);
3299 MESSAGE_CHECK_URL(destinationURLString);
3301 if (m_historyClient) {
3302 if (frame->isMainFrame())
3303 m_historyClient->didPerformClientRedirect(*this, sourceURLString, destinationURLString);
3305 m_loaderClient->didPerformClientRedirect(*this, sourceURLString, destinationURLString, *frame);
3306 process().processPool().historyClient().didPerformClientRedirect(process().processPool(), *this, sourceURLString, destinationURLString, *frame);
3309 void WebPageProxy::didPerformServerRedirect(const String& sourceURLString, const String& destinationURLString, uint64_t frameID)
3311 if (sourceURLString.isEmpty() || destinationURLString.isEmpty())
3314 WebFrameProxy* frame = m_process->webFrame(frameID);
3315 MESSAGE_CHECK(frame);
3316 MESSAGE_CHECK(frame->page() == this);
3318 MESSAGE_CHECK_URL(sourceURLString);
3319 MESSAGE_CHECK_URL(destinationURLString);
3321 if (m_historyClient) {
3322 if (frame->isMainFrame())
3323 m_historyClient->didPerformServerRedirect(*this, sourceURLString, destinationURLString);
3325 m_loaderClient->didPerformServerRedirect(*this, sourceURLString, destinationURLString, *frame);
3326 process().processPool().historyClient().didPerformServerRedirect(process().processPool(), *this, sourceURLString, destinationURLString, *frame);
3329 void WebPageProxy::didUpdateHistoryTitle(const String& title, const String& url, uint64_t frameID)
3331 WebFrameProxy* frame = m_process->webFrame(frameID);
3332 MESSAGE_CHECK(frame);
3333 MESSAGE_CHECK(frame->page() == this);
3335 MESSAGE_CHECK_URL(url);
3337 if (m_historyClient) {
3338 if (frame->isMainFrame())
3339 m_historyClient->didUpdateHistoryTitle(*this, title, url);
3341 m_loaderClient->didUpdateHistoryTitle(*this, title, url, *frame);
3342 process().processPool().historyClient().didUpdateHistoryTitle(process().processPool(), *this, title, url, *frame);
3347 void WebPageProxy::createNewPage(uint64_t frameID, const ResourceRequest& request, const WindowFeatures& windowFeatures, const NavigationActionData& navigationActionData, uint64_t& newPageID, WebPageCreationParameters& newPageParameters)
3349 WebFrameProxy* frame = m_process->webFrame(frameID);
3350 MESSAGE_CHECK(frame);
3352 RefPtr<WebPageProxy> newPage = m_uiClient->createNewPage(this, frame, request, windowFeatures, navigationActionData);
3358 newPageID = newPage->pageID();
3359 newPageParameters = newPage->creationParameters();
3361 WebsiteDataStore::cloneSessionData(*this, *newPage);
3364 void WebPageProxy::showPage()
3366 m_uiClient->showPage(this);
3369 void WebPageProxy::fullscreenMayReturnToInline()
3371 m_uiClient->fullscreenMayReturnToInline(this);
3374 void WebPageProxy::didEnterFullscreen()
3376 m_uiClient->didEnterFullscreen(this);
3379 void WebPageProxy::didExitFullscreen()
3381 m_uiClient->didExitFullscreen(this);
3384 void WebPageProxy::closePage(bool stopResponsivenessTimer)
3386 if (stopResponsivenessTimer)
3387 m_process->responsivenessTimer()->stop();
3389 m_pageClient.clearAllEditCommands();
3390 m_uiClient->close(this);
3393 void WebPageProxy::runJavaScriptAlert(uint64_t frameID, const String& message, RefPtr<Messages::WebPageProxy::RunJavaScriptAlert::DelayedReply> reply)
3395 WebFrameProxy* frame = m_process->webFrame(frameID);
3396 MESSAGE_CHECK(frame);
3398 // Since runJavaScriptAlert() can spin a nested run loop we need to turn off the responsiveness timer.
3399 m_process->responsivenessTimer()->stop();
3401 m_uiClient->runJavaScriptAlert(this, message, frame, [reply]{ reply->send(); });
3404 void WebPageProxy::runJavaScriptConfirm(uint64_t frameID, const String& message, RefPtr<Messages::WebPageProxy::RunJavaScriptConfirm::DelayedReply> reply)
3406 WebFrameProxy* frame = m_process->webFrame(frameID);
3407 MESSAGE_CHECK(frame);
3409 // Since runJavaScriptConfirm() can spin a nested run loop we need to turn off the responsiveness timer.
3410 m_process->responsivenessTimer()->stop();
3412 m_uiClient->runJavaScriptConfirm(this, message, frame, [reply](bool result) { reply->send(result); });
3415 void WebPageProxy::runJavaScriptPrompt(uint64_t frameID, const String& message, const String& defaultValue, RefPtr<Messages::WebPageProxy::RunJavaScriptPrompt::DelayedReply> reply)
3417 WebFrameProxy* frame = m_process->webFrame(frameID);
3418 MESSAGE_CHECK(frame);
3420 // Since runJavaScriptPrompt() can spin a nested run loop we need to turn off the responsiveness timer.
3421 m_process->responsivenessTimer()->stop();
3423 m_uiClient->runJavaScriptPrompt(this, message, defaultValue, frame, [reply](const String& result) { reply->send(result); });
3426 void WebPageProxy::shouldInterruptJavaScript(bool& result)
3428 // Since shouldInterruptJavaScript() can spin a nested run loop we need to turn off the responsiveness timer.
3429 m_process->responsivenessTimer()->stop();
3431 result = m_uiClient->shouldInterruptJavaScript(this);
3434 void WebPageProxy::setStatusText(const String& text)
3436 m_uiClient->setStatusText(this, text);
3439 void WebPageProxy::mouseDidMoveOverElement(const WebHitTestResult::Data& hitTestResultData, uint32_t opaqueModifiers, const UserData& userData)
3441 m_lastMouseMoveHitTestResult = WebHitTestResult::create(hitTestResultData);
3443 WebEvent::Modifiers modifiers = static_cast<WebEvent::Modifiers>(opaqueModifiers);
3445 m_uiClient->mouseDidMoveOverElement(this, hitTestResultData, modifiers, m_process->transformHandlesToObjects(userData.object()).get());
3448 void WebPageProxy::didBeginTrackingPotentialLongMousePress(const IntPoint& mouseDownPosition, const WebHitTestResult::Data& hitTestResultData, const UserData& userData)
3450 m_uiClient->didBeginTrackingPotentialLongMousePress(this, mouseDownPosition, hitTestResultData, m_process->transformHandlesToObjects(userData.object()).get());
3453 void WebPageProxy::didRecognizeLongMousePress(const UserData& userData)
3455 m_uiClient->didRecognizeLongMousePress(this, m_process->transformHandlesToObjects(userData.object()).get());
3458 void WebPageProxy::didCancelTrackingPotentialLongMousePress(const UserData& userData)
3460 m_uiClient->didCancelTrackingPotentialLongMousePress(this, m_process->transformHandlesToObjects(userData.object()).get());
3463 void WebPageProxy::connectionWillOpen(IPC::Connection& connection)
3465 ASSERT(&connection == m_process->connection());
3467 m_webProcessLifetimeTracker.connectionWillOpen(connection);
3470 void WebPageProxy::connectionDidClose(IPC::Connection& connection)
3472 ASSERT_UNUSED(connection, &connection == m_process->connection());
3474 m_webProcessLifetimeTracker.connectionDidClose(connection);
3477 void WebPageProxy::processDidFinishLaunching()
3479 ASSERT(m_process->state() == WebProcessProxy::State::Running);
3481 if (m_userContentController)
3482 m_process->addWebUserContentControllerProxy(*m_userContentController);
3483 m_process->addVisitedLinkProvider(m_visitedLinkProvider);
3486 #if ENABLE(NETSCAPE_PLUGIN_API)
3487 void WebPageProxy::unavailablePluginButtonClicked(uint32_t opaquePluginUnavailabilityReason, const String& mimeType, const String& pluginURLString, const String& pluginspageAttributeURLString, const String& frameURLString, const String& pageURLString)
3489 MESSAGE_CHECK_URL(pluginURLString);
3490 MESSAGE_CHECK_URL(pluginspageAttributeURLString);
3491 MESSAGE_CHECK_URL(frameURLString);
3492 MESSAGE_CHECK_URL(pageURLString);
3494 RefPtr<API::Dictionary> pluginInformation;
3495 String newMimeType = mimeType;
3496 PluginModuleInfo plugin = m_process->processPool().pluginInfoStore().findPlugin(newMimeType, URL(URL(), pluginURLString));
3497 pluginInformation = createPluginInformationDictionary(plugin, frameURLString, mimeType, pageURLString, pluginspageAttributeURLString, pluginURLString);
3499 WKPluginUnavailabilityReason pluginUnavailabilityReason = kWKPluginUnavailabilityReasonPluginMissing;
3500 switch (static_cast<RenderEmbeddedObject::PluginUnavailabilityReason>(opaquePluginUnavailabilityReason)) {
3501 case RenderEmbeddedObject::PluginMissing:
3502 pluginUnavailabilityReason = kWKPluginUnavailabilityReasonPluginMissing;
3504 case RenderEmbeddedObject::InsecurePluginVersion:
3505 pluginUnavailabilityReason = kWKPluginUnavailabilityReasonInsecurePluginVersion;
3507 case RenderEmbeddedObject::PluginCrashed:
3508 pluginUnavailabilityReason = kWKPluginUnavailabilityReasonPluginCrashed;
3510 case RenderEmbeddedObject::PluginBlockedByContentSecurityPolicy:
3511 ASSERT_NOT_REACHED();
3514 m_uiClient->unavailablePluginButtonClicked(this, pluginUnavailabilityReason, pluginInformation.get());
3516 #endif // ENABLE(NETSCAPE_PLUGIN_API)
3519 void WebPageProxy::webGLPolicyForURL(const String& url, uint32_t& loadPolicy)
3521 loadPolicy = static_cast<uint32_t>(m_loaderClient->webGLLoadPolicy(*this, url));
3524 void WebPageProxy::resolveWebGLPolicyForURL(const String& url, uint32_t& loadPolicy)
3526 loadPolicy = static_cast<uint32_t>(m_loaderClient->resolveWebGLLoadPolicy(*this, url));
3528 #endif // ENABLE(WEBGL)
3530 void WebPageProxy::setToolbarsAreVisible(bool toolbarsAreVisible)
3532 m_uiClient->setToolbarsAreVisible(this, toolbarsAreVisible);
3535 void WebPageProxy::getToolbarsAreVisible(bool& toolbarsAreVisible)
3537 toolbarsAreVisible = m_uiClient->toolbarsAreVisible(this);
3540 void WebPageProxy::setMenuBarIsVisible(bool menuBarIsVisible)
3542 m_uiClient->setMenuBarIsVisible(this, menuBarIsVisible);
3545 void WebPageProxy::getMenuBarIsVisible(bool& menuBarIsVisible)
3547 menuBarIsVisible = m_uiClient->menuBarIsVisible(this);
3550 void WebPageProxy::setStatusBarIsVisible(bool statusBarIsVisible)
3552 m_uiClient->setStatusBarIsVisible(this, statusBarIsVisible);
3555 void WebPageProxy::getStatusBarIsVisible(bool& statusBarIsVisible)
3557 statusBarIsVisible = m_uiClient->statusBarIsVisible(this);
3560 void WebPageProxy::setIsResizable(bool isResizable)
3562 m_uiClient->setIsResizable(this, isResizable);
3565 void WebPageProxy::getIsResizable(bool& isResizable)
3567 isResizable = m_uiClient->isResizable(this);
3570 void WebPageProxy::setWindowFrame(const FloatRect& newWindowFrame)
3572 m_uiClient->setWindowFrame(this, m_pageClient.convertToDeviceSpace(newWindowFrame));
3575 void WebPageProxy::getWindowFrame(FloatRect& newWindowFrame)
3577 newWindowFrame = m_pageClient.convertToUserSpace(m_uiClient->windowFrame(this));
3580 void WebPageProxy::screenToRootView(const IntPoint& screenPoint, IntPoint& windowPoint)
3582 windowPoint = m_pageClient.screenToRootView(screenPoint);
3585 void WebPageProxy::rootViewToScreen(const IntRect& viewRect, IntRect& result)
3587 result = m_pageClient.rootViewToScreen(viewRect);
3591 void WebPageProxy::accessibilityScreenToRootView(const IntPoint& screenPoint, IntPoint& windowPoint)
3593 windowPoint = m_pageClient.accessibilityScreenToRootView(screenPoint);
3596 void WebPageProxy::rootViewToAccessibilityScreen(const IntRect& viewRect, IntRect& result)
3598 result = m_pageClient.rootViewToAccessibilityScreen(viewRect);
3602 void WebPageProxy::runBeforeUnloadConfirmPanel(const String& message, uint64_t frameID, bool& shouldClose)
3604 WebFrameProxy* frame = m_process->webFrame(frameID);
3605 MESSAGE_CHECK(frame);
3607 // Since runBeforeUnloadConfirmPanel() can spin a nested run loop we need to turn off the responsiveness timer.
3608 m_process->responsivenessTimer()->stop();
3610 shouldClose = m_uiClient->runBeforeUnloadConfirmPanel(this, message, frame);
3613 #if USE(COORDINATED_GRAPHICS_MULTIPROCESS)
3614 void WebPageProxy::pageDidRequestScroll(const IntPoint& point)
3616 m_pageClient.pageDidRequestScroll(point);
3619 void WebPageProxy::pageTransitionViewportReady()
3621 m_pageClient.pageTransitionViewportReady();
3624 void WebPageProxy::didRenderFrame(const WebCore::IntSize& contentsSize, const WebCore::IntRect& coveredRect)
3626 m_pageClient.didRenderFrame(contentsSize, coveredRect);
3631 void WebPageProxy::didChangeViewportProperties(const ViewportAttributes& attr)
3633 m_pageClient.didChangeViewportProperties(attr);
3636 void WebPageProxy::pageDidScroll()
3638 m_uiClient->pageDidScroll(this);
3640 m_pageClient.dismissContentRelativeChildWindows();
3644 void WebPageProxy::runOpenPanel(uint64_t frameID, const FileChooserSettings& settings)
3646 if (m_openPanelResultListener) {
3647 m_openPanelResultListener->invalidate();
3648 m_openPanelResultListener = 0;
3651 WebFrameProxy* frame = m_process->webFrame(frameID);
3652 MESSAGE_CHECK(frame);
3654 RefPtr<WebOpenPanelParameters> parameters = WebOpenPanelParameters::create(settings);
3655 m_openPanelResultListener = WebOpenPanelResultListenerProxy::create(this);
3657 // Since runOpenPanel() can spin a nested run loop we need to turn off the responsiveness timer.
3658 m_process->responsivenessTimer()->stop();
3660 if (!m_uiClient->runOpenPanel(this, frame, parameters.get(), m_openPanelResultListener.get())) {
3661 if (!m_pageClient.handleRunOpenPanel(this, frame, parameters.get(), m_openPanelResultListener.get()))
3662 didCancelForOpenPanel();
3666 void WebPageProxy::printFrame(uint64_t frameID)
3668 ASSERT(!m_isPerformingDOMPrintOperation);
3669 m_isPerformingDOMPrintOperation = true;
3671 WebFrameProxy* frame = m_process->webFrame(frameID);
3672 MESSAGE_CHECK(frame);
3674 m_uiClient->printFrame(this, frame);
3676 endPrinting(); // Send a message synchronously while m_isPerformingDOMPrintOperation is still true.
3677 m_isPerformingDOMPrintOperation = false;
3680 void WebPageProxy::printMainFrame()
3682 printFrame(m_mainFrame->frameID());
3685 void WebPageProxy::setMediaVolume(float volume)
3687 if (volume == m_mediaVolume)
3690 m_mediaVolume = volume;
3695 m_process->send(Messages::WebPage::SetMediaVolume(volume), m_pageID);
3698 void WebPageProxy::setMuted(bool muted)
3700 if (m_muted == muted)
3708 m_process->send(Messages::WebPage::SetMuted(muted), m_pageID);
3711 void WebPageProxy::setMayStartMediaWhenInWindow(bool mayStartMedia)
3713 if (mayStartMedia == m_mayStartMediaWhenInWindow)
3716 m_mayStartMediaWhenInWindow = mayStartMedia;
3721 process().send(Messages::WebPage::SetMayStartMediaWhenInWindow(mayStartMedia), m_pageID);
3724 void WebPageProxy::handleDownloadRequest(DownloadProxy* download)
3726 m_pageClient.handleDownloadRequest(download);
3729 void WebPageProxy::didChangeContentSize(const IntSize& size)
3731 m_pageClient.didChangeContentSize(size);
3734 #if ENABLE(INPUT_TYPE_COLOR)
3735 void WebPageProxy::showColorPicker(const WebCore::Color& initialColor, const IntRect& elementRect)
3737 #if ENABLE(INPUT_TYPE_COLOR_POPOVER)
3738 // A new popover color well needs to be created (and the previous one destroyed) for
3739 // each activation of a color element.
3743 m_colorPicker = m_pageClient.createColorPicker(this, initialColor, elementRect);
3744 m_colorPicker->showColorPicker(initialColor);
3747 void WebPageProxy::setColorPickerColor(const WebCore::Color& color)
3749 ASSERT(m_colorPicker);
3751 m_colorPicker->setSelectedColor(color);
3754 void WebPageProxy::endColorPicker()
3756 ASSERT(m_colorPicker);
3758 m_colorPicker->endPicker();
3761 void WebPageProxy::didChooseColor(const WebCore::Color& color)
3766 m_process->send(Messages::WebPage::DidChooseColor(color), m_pageID);
3769 void WebPageProxy::didEndColorPicker()
3774 if (m_colorPicker) {
3775 m_colorPicker->invalidate();
3776 m_colorPicker = nullptr;
3779 m_process->send(Messages::WebPage::DidEndColorPicker(), m_pageID);
3783 void WebPageProxy::didDraw()
3785 m_uiClient->didDraw(this);
3789 WebInspectorProxy* WebPageProxy::inspector()
3791 if (isClosed() || !isValid())
3793 return m_inspector.get();
3796 #if ENABLE(FULLSCREEN_API)
3797 WebFullScreenManagerProxy* WebPageProxy::fullScreenManager()
3799 return m_fullScreenManager.get();
3804 RefPtr<WebVideoFullscreenManagerProxy> WebPageProxy::videoFullscreenManager()
3806 return m_videoFullscreenManager;
3812 void WebPageProxy::backForwardAddItem(uint64_t itemID)
3814 m_backForwardList->addItem(m_process->webBackForwardItem(itemID));
3817 void WebPageProxy::backForwardGoToItem(uint64_t itemID, SandboxExtension::Handle& sandboxExtensionHandle)
3819 WebBackForwardListItem* item = m_process->webBackForwardItem(itemID);
3823 bool createdExtension = maybeInitializeSandboxExtensionHandle(URL(URL(), item->url()), sandboxExtensionHandle);
3824 if (createdExtension)
3825 m_process->willAcquireUniversalFileReadSandboxExtension();
3826 m_backForwardList->goToItem(item);
3829 void WebPageProxy::backForwardItemAtIndex(int32_t index, uint64_t& itemID)
3831 WebBackForwardListItem* item = m_backForwardList->itemAtIndex(index);
3832 itemID = item ? item->itemID() : 0;
3835 void WebPageProxy::backForwardBackListCount(int32_t& count)
3837 count = m_backForwardList->backListCount();
3840 void WebPageProxy::backForwardForwardListCount(int32_t& count)
3842 count = m_backForwardList->forwardListCount();
3845 void WebPageProxy::compositionWasCanceled(const EditorState& editorState)
3848 m_pageClient.notifyInputContextAboutDiscardedComposition();
3850 editorStateChanged(editorState);
3855 void WebPageProxy::registerEditCommandForUndo(uint64_t commandID, uint32_t editAction)
3857 registerEditCommand(WebEditCommandProxy::create(commandID, static_cast<EditAction>(editAction), this), Undo);
3860 void WebPageProxy::registerInsertionUndoGrouping()
3862 #if USE(INSERTION_UNDO_GROUPING)
3863 m_pageClient.registerInsertionUndoGrouping();
3867 void WebPageProxy::canUndoRedo(uint32_t action, bool& result)
3869 result = m_pageClient.canUndoRedo(static_cast<UndoOrRedo>(action));
3872 void WebPageProxy::executeUndoRedo(uint32_t action, bool& result)
3874 m_pageClient.executeUndoRedo(static_cast<UndoOrRedo>(action));
3878 void WebPageProxy::clearAllEditCommands()
3880 m_pageClient.clearAllEditCommands();
3883 void WebPageProxy::didCountStringMatches(const String& string, uint32_t matchCount)
3885 m_findClient->didCountStringMatches(this, string, matchCount);
3888 void WebPageProxy::didGetImageForFindMatch(const ShareableBitmap::Handle& contentImageHandle, uint32_t matchIndex)
3890 m_findMatchesClient.didGetImageForMatchResult(this, WebImage::create(ShareableBitmap::create(contentImageHandle)).get(), matchIndex);
3893 void WebPageProxy::setTextIndicator(const TextIndicatorData& indicatorData, bool fadeOut)
3895 m_pageClient.setTextIndicator(TextIndicator::create(indicatorData), fadeOut);
3898 void WebPageProxy::clearTextIndicator()
3900 m_pageClient.setTextIndicator(nullptr, false);
3903 void WebPageProxy::setTextIndicatorAnimationProgress(float progress)
3905 m_pageClient.setTextIndicatorAnimationProgress(progress);
3908 void WebPageProxy::didFindString(const String& string, uint32_t matchCount, int32_t matchIndex)
3910 m_findClient->didFindString(this, string, matchCount, matchIndex);
3913 void WebPageProxy::didFindStringMatches(const String& string, const Vector<Vector<WebCore::IntRect>>& matchRects, int32_t firstIndexAfterSelection)
3915 Vector<RefPtr<API::Object>> matches;
3916 matches.reserveInitialCapacity(matchRects.size());
3918 for (const auto& rects : matchRects) {
3919 Vector<RefPtr<API::Object>> apiRects;
3920 apiRects.reserveInitialCapacity(rects.size());
3922 for (const auto& rect : rects)
3923 apiRects.uncheckedAppend(API::Rect::create(toAPI(rect)));
3925 matches.uncheckedAppend(API::Array::create(WTF::move(apiRects)));
3928 m_findMatchesClient.didFindStringMatches(this, string, API::Array::create(WTF::move(matches)).get(), firstIndexAfterSelection);
3931 void WebPageProxy::didFailToFindString(const String& string)
3933 m_findClient->didFailToFindString(this, string);
3936 bool WebPageProxy::sendMessage(std::unique_ptr<IPC::MessageEncoder> encoder, unsigned messageSendFlags)
3938 return m_process->sendMessage(WTF::move(encoder), messageSendFlags);
3941 IPC::Connection* WebPageProxy::messageSenderConnection()
3943 return m_process->connection();
3946 uint64_t WebPageProxy::messageSenderDestinationID()
3951 void WebPageProxy::valueChangedForPopupMenu(WebPopupMenuProxy*, int32_t newSelectedIndex)
3953 m_process->send(Messages::WebPage::DidChangeSelectedIndexForActivePopupMenu(newSelectedIndex), m_pageID);
3956 void WebPageProxy::setTextFromItemForPopupMenu(WebPopupMenuProxy*, int32_t index)
3958 m_process->send(Messages::WebPage::SetTextForActivePopupMenu(index), m_pageID);
3961 NativeWebMouseEvent* WebPageProxy::currentlyProcessedMouseDownEvent()
3963 return m_currentlyProcessedMouseDownEvent.get();
3966 void WebPageProxy::postMessageToInjectedBundle(const String& messageName, API::Object* messageBody)
3968 process().send(Messages::WebPage::PostInjectedBundleMessage(messageName, UserData(process().transformObjectsToHandles(messageBody).get())), m_pageID);
3972 void WebPageProxy::failedToShowPopupMenu()
3974 m_process->send(Messages::WebPage::FailedToShowPopupMenu(), m_pageID);
3978 void WebPageProxy::showPopupMenu(const IntRect& rect, uint64_t textDirection, const Vector<WebPopupItem>& items, int32_t selectedIndex, const PlatformPopupMenuData& data)
3980 if (m_activePopupMenu) {
3982 m_uiPopupMenuClient.hidePopupMenu(this);
3984 m_activePopupMenu->hidePopupMenu();
3986 m_activePopupMenu->invalidate();
3987 m_activePopupMenu = nullptr;
3990 m_activePopupMenu = m_pageClient.createPopupMenuProxy(this);
3992 if (!m_activePopupMenu)
3995 // Since showPopupMenu() can spin a nested run loop we need to turn off the responsiveness timer.
3996 m_process->responsivenessTimer()->stop();
4000 m_uiPopupMenuClient.showPopupMenu(this, m_activePopupMenu.get(), rect, static_cast<TextDirection>(textDirection), m_pageScaleFactor, items, selectedIndex);
4003 // Showing a popup menu runs a nested runloop, which can handle messages that cause |this| to get closed.
4004 Ref<WebPageProxy> protect(*this);
4005 m_activePopupMenu->showPopupMenu(rect, static_cast<TextDirection>(textDirection), m_pageScaleFactor, items, data, selectedIndex);
4009 void WebPageProxy::hidePopupMenu()
4011 if (!m_activePopupMenu)
4015 m_uiPopupMenuClient.hidePopupMenu(this);
4017 m_activePopupMenu->hidePopupMenu();
4019 m_activePopupMenu->invalidate();
4020 m_activePopupMenu = nullptr;
4023 #if ENABLE(CONTEXT_MENUS)
4024 void WebPageProxy::showContextMenu(const IntPoint& menuLocation, const ContextMenuContextData& contextMenuContextData, const Vector<WebContextMenuItemData>& proposedItems, const UserData& userData)
4026 // Showing a context menu runs a nested runloop, which can handle messages that cause |this| to get closed.
4027 Ref<WebPageProxy> protect(*this);
4029 internalShowContextMenu(menuLocation, contextMenuContextData, proposedItems, ContextMenuClientEligibility::EligibleForClient, userData);
4031 // No matter the result of internalShowContextMenu, always notify the WebProcess that the menu is hidden so it starts handling mouse events again.
4032 m_process->send(Messages::WebPage::ContextMenuHidden(), m_pageID);
4035 void WebPageProxy::internalShowContextMenu(const IntPoint& menuLocation, const ContextMenuContextData& contextMenuContextData, const Vector<WebContextMenuItemData>& proposedItems, ContextMenuClientEligibility clientEligibility, const UserData& userData)
4037 m_activeContextMenuContextData = contextMenuContextData;
4039 if (!m_contextMenuClient->hideContextMenu(*this) && m_activeContextMenu) {
4040 m_activeContextMenu->hideContextMenu();
4041 m_activeContextMenu = nullptr;
4044 m_activeContextMenu = m_pageClient.createContextMenuProxy(this);
4045 if (!m_activeContextMenu)
4048 // Since showContextMenu() can spin a nested run loop we need to turn off the responsiveness timer.
4049 m_process->responsivenessTimer()->stop();
4051 // Unless this is an image control, give the PageContextMenuClient one last swipe at changing the menu.
4052 bool askClientToChangeMenu = clientEligibility == ContextMenuClientEligibility::EligibleForClient;
4053 #if ENABLE(SERVICE_CONTROLS)
4054 if (contextMenuContextData.controlledImage())
4055 askClientToChangeMenu = false;
4058 Vector<RefPtr<WebContextMenuItem>> proposedAPIItems;
4059 for (auto& item : proposedItems) {
4060 if (item.action() != ContextMenuItemTagShareMenu) {
4061 proposedAPIItems.append(WebContextMenuItem::create(item));
4065 // Create the real Share menu item
4066 URL absoluteLinkURL;
4067 if (!contextMenuContextData.webHitTestResultData().absoluteLinkURL.isEmpty())
4068 absoluteLinkURL = URL(ParsedURLString, contextMenuContextData.webHitTestResultData().absoluteLinkURL);
4070 URL downloadableMediaURL;
4071 if (!contextMenuContextData.webHitTestResultData().absoluteMediaURL.isEmpty() && contextMenuContextData.webHitTestResultData().isDownloadableMedia)
4072 downloadableMediaURL = URL(ParsedURLString, contextMenuContextData.webHitTestResultData().absoluteMediaURL);
4074 RefPtr<Image> image;
4075 if (contextMenuContextData.webHitTestResultData().imageSharedMemory && contextMenuContextData.webHitTestResultData().imageSize) {
4076 image = BitmapImage::create();
4077 RefPtr<SharedBuffer> imageData = SharedBuffer::create((unsigned char*)contextMenuContextData.webHitTestResultData().imageSharedMemory->data(), contextMenuContextData.webHitTestResultData().imageSize);
4078 image->setData(imageData.release(), true);
4081 ContextMenuItem coreItem = ContextMenuItem::shareMenuItem(absoluteLinkURL, downloadableMediaURL, image.get(), contextMenuContextData.selectedText());
4082 if (!coreItem.isNull()) {
4083 platformInitializeShareMenuItem(coreItem);
4084 proposedAPIItems.append(WebContextMenuItem::create(coreItem));
4088 Vector<RefPtr<WebContextMenuItem>> clientItems;
4089 bool useProposedItems = true;
4091 if (askClientToChangeMenu && m_contextMenuClient->getContextMenuFromProposedMenu(*this, proposedAPIItems, clientItems, contextMenuContextData.webHitTestResultData(), m_process->transformHandlesToObjects(userData.object()).get()))
4092 useProposedItems = false;
4094 const Vector<RefPtr<WebContextMenuItem>>& itemsToShow = useProposedItems ? proposedAPIItems : clientItems;
4095 if (!m_contextMenuClient->showContextMenu(*this, menuLocation, itemsToShow))
4096 m_activeContextMenu->showContextMenu(menuLocation, itemsToShow, contextMenuContextData);
4098 m_contextMenuClient->contextMenuDismissed(*this);
4102 void WebPageProxy::platformInitializeShareMenuItem(ContextMenuItem&)
4107 void WebPageProxy::contextMenuItemSelected(const WebContextMenuItemData& item)
4109 // Application custom items don't need to round-trip through to WebCore in the WebProcess.
4110 if (item.action() >= ContextMenuItemBaseApplicationTag) {
4111 m_contextMenuClient->customContextMenuItemSelected(*this, item);
4116 if (item.action() == ContextMenuItemTagSmartCopyPaste) {
4117 setSmartInsertDeleteEnabled(!isSmartInsertDeleteEnabled());
4120 if (item.action() == ContextMenuItemTagSmartQuotes) {
4121 TextChecker::setAutomaticQuoteSubstitutionEnabled(!TextChecker::state().isAutomaticQuoteSubstitutionEnabled);
4122 m_process->updateTextCheckerState();
4125 if (item.action() == ContextMenuItemTagSmartDashes) {
4126 TextChecker::setAutomaticDashSubstitutionEnabled(!TextChecker::state().isAutomaticDashSubstitutionEnabled);
4127 m_process->updateTextCheckerState();
4130 if (item.action() == ContextMenuItemTagSmartLinks) {
4131 TextChecker::setAutomaticLinkDetectionEnabled(!TextChecker::state().isAutomaticLinkDetectionEnabled);
4132 m_process->updateTextCheckerState();
4135 if (item.action() == ContextMenuItemTagTextReplacement) {
4136 TextChecker::setAutomaticTextReplacementEnabled(!TextChecker::state().isAutomaticTextReplacementEnabled);
4137 m_process->updateTextCheckerState();
4140 if (item.action() == ContextMenuItemTagCorrectSpellingAutomatically) {
4141 TextChecker::setAutomaticSpellingCorrectionEnabled(!TextChecker::state().isAutomaticSpellingCorrectionEnabled);
4142 m_process->updateTextCheckerState();
4145 if (item.action() == ContextMenuItemTagShowSubstitutions) {
4146 TextChecker::toggleSubstitutionsPanelIsShowing();
4150 if (item.action() == ContextMenuItemTagDownloadImageToDisk) {
4151 m_process->processPool().download(this, URL(URL(), m_activeContextMenuContextData.webHitTestResultData().absoluteImageURL));
4154 if (item.action() == ContextMenuItemTagDownloadLinkToDisk) {
4155 m_process->processPool().download(this, URL(URL(), m_activeContextMenuContextData.webHitTestResultData().absoluteLinkURL));
4158 if (item.action() == ContextMenuItemTagDownloadMediaToDisk) {
4159 m_process->processPool().download(this, URL(URL(), m_activeContextMenuContextData.webHitTestResultData().absoluteMediaURL));
4162 if (item.action() == ContextMenuItemTagCheckSpellingWhileTyping) {
4163 TextChecker::setContinuousSpellCheckingEnabled(!TextChecker::state().isContinuousSpellCheckingEnabled);
4164 m_process->updateTextCheckerState();
4167 if (item.action() == ContextMenuItemTagCheckGrammarWithSpelling) {
4168 TextChecker::setGrammarCheckingEnabled(!TextChecker::state().isGrammarCheckingEnabled);
4169 m_process->updateTextCheckerState();
4172 if (item.action() == ContextMenuItemTagShowSpellingPanel) {
4173 if (!TextChecker::spellingUIIsShowing())
4174 advanceToNextMisspelling(true);
4175 TextChecker::toggleSpellingUIIsShowing();
4178 if (item.action() == ContextMenuItemTagLearnSpelling || item.action() == ContextMenuItemTagIgnoreSpelling)
4179 ++m_pendingLearnOrIgnoreWordMessageCount;
4181 m_process->send(Messages::WebPage::DidSelectItemFromActiveContextMenu(item), m_pageID);
4183 #endif // ENABLE(CONTEXT_MENUS)
4186 void WebPageProxy::didChooseFilesForOpenPanelWithDisplayStringAndIcon(const Vector<String>& fileURLs, const String& displayString, const API::Data* iconData)
4191 #if ENABLE(SANDBOX_EXTENSIONS)
4192 // FIXME: The sandbox extensions should be sent with the DidChooseFilesForOpenPanel message. This
4193 // is gated on a way of passing SandboxExtension::Handles in a Vector.
4194 for (size_t i = 0; i < fileURLs.size(); ++i) {
4195 SandboxExtension::Handle sandboxExtensionHandle;
4196 SandboxExtension::createHandle(fileURLs[i], SandboxExtension::ReadOnly, sandboxExtensionHandle);
4197 m_process->send(Messages::WebPage::ExtendSandboxForFileFromOpenPanel(sandboxExtensionHandle), m_pageID);
4201 m_process->send(Messages::WebPage::DidChooseFilesForOpenPanelWithDisplayStringAndIcon(fileURLs, displayString, iconData ? iconData->dataReference() : IPC::DataReference()), m_pageID);
4203 m_openPanelResultListener->invalidate();
4204 m_openPanelResultListener = nullptr;
4208 void WebPageProxy::didChooseFilesForOpenPanel(const Vector<String>& fileURLs)
4213 #if ENABLE(SANDBOX_EXTENSIONS)
4214 // FIXME: The sandbox extensions should be sent with the DidChooseFilesForOpenPanel message. This
4215 // is gated on a way of passing SandboxExtension::Handles in a Vector.
4216 for (size_t i = 0; i < fileURLs.size(); ++i) {
4217 SandboxExtension::Handle sandboxExtensionHandle;
4218 SandboxExtension::createHandle(fileURLs[i], SandboxExtension::ReadOnly, sandboxExtensionHandle);
4219 m_process->send(Messages::WebPage::ExtendSandboxForFileFromOpenPanel(sandboxExtensionHandle), m_pageID);
4223 m_process->send(Messages::WebPage::DidChooseFilesForOpenPanel(fileURLs), m_pageID);
4225 m_openPanelResultListener->invalidate();
4226 m_openPanelResultListener = 0;
4229 void WebPageProxy::didCancelForOpenPanel()
4234 m_process->send(Messages::WebPage::DidCancelForOpenPanel(), m_pageID);
4236 m_openPanelResultListener->invalidate();
4237 m_openPanelResultListener = 0;
4240 void WebPageProxy::advanceToNextMisspelling(bool startBeforeSelection)
4242 m_process->send(Messages::WebPage::AdvanceToNextMisspelling(startBeforeSelection), m_pageID);
4245 void WebPageProxy::changeSpellingToWord(const String& word)
4250 m_process->send(Messages::WebPage::ChangeSpellingToWord(word), m_pageID);