summaryrefslogtreecommitdiff
path: root/Source/WebKit2/UIProcess/WebPageProxy.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebKit2/UIProcess/WebPageProxy.cpp
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WebKit2/UIProcess/WebPageProxy.cpp')
-rw-r--r--Source/WebKit2/UIProcess/WebPageProxy.cpp4453
1 files changed, 3433 insertions, 1020 deletions
diff --git a/Source/WebKit2/UIProcess/WebPageProxy.cpp b/Source/WebKit2/UIProcess/WebPageProxy.cpp
index bb8578dc7..721bd41f2 100644
--- a/Source/WebKit2/UIProcess/WebPageProxy.cpp
+++ b/Source/WebKit2/UIProcess/WebPageProxy.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2010, 2011, 2015-2016 Apple Inc. All rights reserved.
* Copyright (C) 2012 Intel Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -28,8 +28,27 @@
#include "WebPageProxy.h"
#include "APIArray.h"
+#include "APIContextMenuClient.h"
+#include "APIFindClient.h"
+#include "APIFindMatchesClient.h"
+#include "APIFormClient.h"
+#include "APIFrameInfo.h"
+#include "APIFullscreenClient.h"
+#include "APIGeometry.h"
+#include "APIHistoryClient.h"
+#include "APIHitTestResult.h"
+#include "APIIconLoadingClient.h"
+#include "APILegacyContextHistoryClient.h"
#include "APILoaderClient.h"
+#include "APINavigation.h"
+#include "APINavigationAction.h"
+#include "APINavigationClient.h"
+#include "APINavigationResponse.h"
+#include "APIOpenPanelParameters.h"
+#include "APIPageConfiguration.h"
#include "APIPolicyClient.h"
+#include "APISecurityOrigin.h"
+#include "APIUIClient.h"
#include "APIURLRequest.h"
#include "AuthenticationChallengeProxy.h"
#include "AuthenticationDecisionListener.h"
@@ -38,29 +57,30 @@
#include "DrawingAreaProxy.h"
#include "DrawingAreaProxyMessages.h"
#include "EventDispatcherMessages.h"
-#include "FindIndicator.h"
+#include "LoadParameters.h"
#include "Logging.h"
+#include "NativeWebGestureEvent.h"
#include "NativeWebKeyboardEvent.h"
#include "NativeWebMouseEvent.h"
#include "NativeWebWheelEvent.h"
#include "NavigationActionData.h"
+#include "NetworkProcessMessages.h"
#include "NotificationPermissionRequest.h"
#include "NotificationPermissionRequestManager.h"
#include "PageClient.h"
#include "PluginInformation.h"
#include "PluginProcessManager.h"
#include "PrintInfo.h"
-#include "SessionState.h"
#include "TextChecker.h"
#include "TextCheckerState.h"
+#include "UserMediaPermissionRequestProxy.h"
#include "WKContextPrivate.h"
+#include "WebAutomationSession.h"
#include "WebBackForwardList.h"
#include "WebBackForwardListItem.h"
#include "WebCertificateInfo.h"
-#include "WebColorPickerResultListenerProxy.h"
-#include "WebContext.h"
+#include "WebContextMenuItem.h"
#include "WebContextMenuProxy.h"
-#include "WebContextUserMessageCoders.h"
#include "WebCoreArgumentCoders.h"
#include "WebEditCommandProxy.h"
#include "WebEvent.h"
@@ -69,8 +89,10 @@
#include "WebFramePolicyListenerProxy.h"
#include "WebFullScreenManagerProxy.h"
#include "WebFullScreenManagerProxyMessages.h"
+#include "WebImage.h"
#include "WebInspectorProxy.h"
-#include "WebInspectorProxyMessages.h"
+#include "WebInspectorUtilities.h"
+#include "WebNavigationState.h"
#include "WebNotificationManagerProxy.h"
#include "WebOpenPanelResultListenerProxy.h"
#include "WebPageCreationParameters.h"
@@ -78,41 +100,42 @@
#include "WebPageGroupData.h"
#include "WebPageMessages.h"
#include "WebPageProxyMessages.h"
+#include "WebPaymentCoordinatorProxy.h"
#include "WebPopupItem.h"
#include "WebPopupMenuProxy.h"
#include "WebPreferences.h"
#include "WebProcessMessages.h"
+#include "WebProcessPool.h"
#include "WebProcessProxy.h"
#include "WebProtectionSpace.h"
-#include "WebSecurityOrigin.h"
+#include "WebUserContentControllerProxy.h"
+#include "WebsiteDataStore.h"
+#include <WebCore/BitmapImage.h>
+#include <WebCore/DiagnosticLoggingClient.h>
#include <WebCore/DragController.h>
#include <WebCore/DragData.h>
-#include <WebCore/DragSession.h>
+#include <WebCore/EventNames.h>
#include <WebCore/FloatRect.h>
#include <WebCore/FocusDirection.h>
+#include <WebCore/JSDOMBinding.h>
+#include <WebCore/JSDOMExceptionHandling.h>
#include <WebCore/MIMETypeRegistry.h>
#include <WebCore/RenderEmbeddedObject.h>
+#include <WebCore/SerializedCryptoKeyWrap.h>
#include <WebCore/TextCheckerClient.h>
+#include <WebCore/TextIndicator.h>
+#include <WebCore/URL.h>
+#include <WebCore/ValidationBubble.h>
#include <WebCore/WindowFeatures.h>
-#include <wtf/NeverDestroyed.h>
#include <stdio.h>
+#include <wtf/NeverDestroyed.h>
+#include <wtf/text/StringBuilder.h>
+#include <wtf/text/StringView.h>
#if ENABLE(ASYNC_SCROLLING)
#include "RemoteScrollingCoordinatorProxy.h"
#endif
-#if USE(COORDINATED_GRAPHICS)
-#include "CoordinatedLayerTreeHostProxyMessages.h"
-#endif
-
-#if PLATFORM(GTK)
-#include "ArgumentCodersGtk.h"
-#endif
-
-#if USE(SOUP) && !ENABLE(CUSTOM_PROTOCOLS)
-#include "WebSoupRequestManagerProxy.h"
-#endif
-
#if ENABLE(VIBRATION)
#include "WebVibrationProxy.h"
#endif
@@ -121,24 +144,52 @@
#include <wtf/RefCountedLeakCounter.h>
#endif
-#if ENABLE(NETWORK_PROCESS)
-#include "NetworkProcessMessages.h"
+#if PLATFORM(COCOA)
+#include "RemoteLayerTreeDrawingAreaProxy.h"
+#include "RemoteLayerTreeScrollingPerformanceData.h"
+#include "ViewSnapshotStore.h"
+#include "WebVideoFullscreenManagerProxy.h"
+#include "WebVideoFullscreenManagerProxyMessages.h"
+#include <WebCore/MachSendRight.h>
+#include <WebCore/RunLoopObserver.h>
+#include <WebCore/TextIndicatorWindow.h>
#endif
-#if PLATFORM(MAC)
-#include "ViewSnapshotStore.h"
+#if PLATFORM(GTK)
+#include "WebSelectionData.h"
#endif
#if USE(CAIRO)
#include <WebCore/CairoUtilities.h>
#endif
+#if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
+#include <WebCore/MediaPlaybackTarget.h>
+#include <WebCore/WebMediaSessionManager.h>
+#endif
+
+#if ENABLE(MEDIA_SESSION)
+#include "WebMediaSessionFocusManager.h"
+#include "WebMediaSessionMetadata.h"
+#include <WebCore/MediaSessionMetadata.h>
+#endif
+
+#if PLATFORM(IOS) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
+#include "WebPlaybackSessionManagerProxy.h"
+#endif
+
+#if ENABLE(MEDIA_STREAM)
+#include <WebCore/MediaConstraintsImpl.h>
+#endif
+
// This controls what strategy we use for mouse wheel coalescing.
#define MERGE_WHEEL_EVENTS 1
#define MESSAGE_CHECK(assertion) MESSAGE_CHECK_BASE(assertion, m_process->connection())
#define MESSAGE_CHECK_URL(url) MESSAGE_CHECK_BASE(m_process->checkURLReceivedFromWebProcess(url), m_process->connection())
+#define RELEASE_LOG_IF_ALLOWED(...) RELEASE_LOG_IF(isAlwaysOnLoggingAllowed(), ProcessSuspension, __VA_ARGS__)
+
using namespace WebCore;
// Represents the number of wheel events we can hold in the queue before we start pushing them preemptively.
@@ -164,37 +215,37 @@ public:
RefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply> reply;
};
- static ExceededDatabaseQuotaRecords& shared();
+ static ExceededDatabaseQuotaRecords& singleton();
- PassOwnPtr<Record> createRecord(uint64_t frameID, String originIdentifier,
+ std::unique_ptr<Record> createRecord(uint64_t frameID, String originIdentifier,
String databaseName, String displayName, uint64_t currentQuota,
uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage,
PassRefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply>);
- void add(PassOwnPtr<Record>);
- bool areBeingProcessed() const { return m_currentRecord; }
+ void add(std::unique_ptr<Record>);
+ bool areBeingProcessed() const { return !!m_currentRecord; }
Record* next();
private:
ExceededDatabaseQuotaRecords() { }
~ExceededDatabaseQuotaRecords() { }
- Deque<OwnPtr<Record>> m_records;
- OwnPtr<Record> m_currentRecord;
+ Deque<std::unique_ptr<Record>> m_records;
+ std::unique_ptr<Record> m_currentRecord;
};
-ExceededDatabaseQuotaRecords& ExceededDatabaseQuotaRecords::shared()
+ExceededDatabaseQuotaRecords& ExceededDatabaseQuotaRecords::singleton()
{
static NeverDestroyed<ExceededDatabaseQuotaRecords> records;
return records;
}
-PassOwnPtr<ExceededDatabaseQuotaRecords::Record> ExceededDatabaseQuotaRecords::createRecord(
+std::unique_ptr<ExceededDatabaseQuotaRecords::Record> ExceededDatabaseQuotaRecords::createRecord(
uint64_t frameID, String originIdentifier, String databaseName, String displayName,
uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage,
uint64_t expectedUsage, PassRefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply> reply)
{
- OwnPtr<Record> record = adoptPtr(new Record);
+ auto record = std::make_unique<Record>();
record->frameID = frameID;
record->originIdentifier = originIdentifier;
record->databaseName = databaseName;
@@ -204,17 +255,17 @@ PassOwnPtr<ExceededDatabaseQuotaRecords::Record> ExceededDatabaseQuotaRecords::c
record->currentDatabaseUsage = currentDatabaseUsage;
record->expectedUsage = expectedUsage;
record->reply = reply;
- return record.release();
+ return record;
}
-void ExceededDatabaseQuotaRecords::add(PassOwnPtr<ExceededDatabaseQuotaRecords::Record> record)
+void ExceededDatabaseQuotaRecords::add(std::unique_ptr<ExceededDatabaseQuotaRecords::Record> record)
{
- m_records.append(record);
+ m_records.append(WTFMove(record));
}
ExceededDatabaseQuotaRecords::Record* ExceededDatabaseQuotaRecords::next()
{
- m_currentRecord.clear();
+ m_currentRecord = nullptr;
if (!m_records.isEmpty())
m_currentRecord = m_records.takeFirst();
return m_currentRecord.get();
@@ -243,40 +294,85 @@ static const char* webKeyboardEventTypeString(WebEvent::Type type)
}
#endif // !LOG_DISABLED
-PassRefPtr<WebPageProxy> WebPageProxy::create(PageClient& pageClient, WebProcessProxy& process, uint64_t pageID, const WebPageConfiguration& configuration)
+class PageClientProtector {
+ WTF_MAKE_NONCOPYABLE(PageClientProtector);
+public:
+ PageClientProtector(PageClient& pageClient)
+ : m_pageClient(pageClient)
+ {
+ m_pageClient.refView();
+ }
+
+ ~PageClientProtector()
+ {
+ m_pageClient.derefView();
+ }
+
+private:
+ PageClient& m_pageClient;
+};
+
+Ref<WebPageProxy> WebPageProxy::create(PageClient& pageClient, WebProcessProxy& process, uint64_t pageID, Ref<API::PageConfiguration>&& configuration)
{
- return adoptRef(new WebPageProxy(pageClient, process, pageID, configuration));
+ return adoptRef(*new WebPageProxy(pageClient, process, pageID, WTFMove(configuration)));
}
-WebPageProxy::WebPageProxy(PageClient& pageClient, WebProcessProxy& process, uint64_t pageID, const WebPageConfiguration& configuration)
+WebPageProxy::WebPageProxy(PageClient& pageClient, WebProcessProxy& process, uint64_t pageID, Ref<API::PageConfiguration>&& configuration)
: m_pageClient(pageClient)
+ , m_configuration(WTFMove(configuration))
, m_loaderClient(std::make_unique<API::LoaderClient>())
, m_policyClient(std::make_unique<API::PolicyClient>())
+ , m_formClient(std::make_unique<API::FormClient>())
+ , m_uiClient(std::make_unique<API::UIClient>())
+ , m_findClient(std::make_unique<API::FindClient>())
+ , m_findMatchesClient(std::make_unique<API::FindMatchesClient>())
+ , m_diagnosticLoggingClient(std::make_unique<API::DiagnosticLoggingClient>())
+#if ENABLE(CONTEXT_MENUS)
+ , m_contextMenuClient(std::make_unique<API::ContextMenuClient>())
+#endif
+ , m_navigationState(std::make_unique<WebNavigationState>())
, m_process(process)
- , m_pageGroup(*configuration.pageGroup)
+ , m_pageGroup(*m_configuration->pageGroup())
+ , m_preferences(*m_configuration->preferences())
+ , m_userContentController(*m_configuration->userContentController())
+ , m_visitedLinkStore(*m_configuration->visitedLinkStore())
+ , m_websiteDataStore(m_configuration->websiteDataStore()->websiteDataStore())
, m_mainFrame(nullptr)
, m_userAgent(standardUserAgent())
+ , m_overrideContentSecurityPolicy { m_configuration->overrideContentSecurityPolicy() }
+ , m_treatsSHA1CertificatesAsInsecure(m_configuration->treatsSHA1SignedCertificatesAsInsecure())
+#if ENABLE(FULLSCREEN_API)
+ , m_fullscreenClient(std::make_unique<API::FullscreenClient>())
+#endif
, m_geolocationPermissionRequestManager(*this)
, m_notificationPermissionRequestManager(*this)
- , m_viewState(ViewState::NoFlags)
+ , m_activityState(ActivityState::NoFlags)
+ , m_viewWasEverInWindow(false)
+#if PLATFORM(IOS)
+ , m_alwaysRunsAtForegroundPriority(m_configuration->alwaysRunsAtForegroundPriority())
+#endif
+ , m_initialCapitalizationEnabled(m_configuration->initialCapitalizationEnabled())
, m_backForwardList(WebBackForwardList::create(*this))
- , m_loadStateAtProcessExit(FrameLoadState::State::Finished)
- , m_temporarilyClosedComposition(false)
+ , m_maintainsInactiveSelection(false)
+ , m_waitsForPaintAfterViewDidMoveToWindow(m_configuration->waitsForPaintAfterViewDidMoveToWindow())
+ , m_isEditable(false)
, m_textZoomFactor(1)
, m_pageZoomFactor(1)
, m_pageScaleFactor(1)
+ , m_pluginZoomFactor(1)
+ , m_pluginScaleFactor(1)
, m_intrinsicDeviceScaleFactor(1)
, m_customDeviceScaleFactor(0)
- , m_layerHostingMode(LayerHostingModeDefault)
+ , m_topContentInset(0)
+ , m_layerHostingMode(LayerHostingMode::InProcess)
, m_drawsBackground(true)
- , m_drawsTransparentBackground(false)
- , m_areMemoryCacheClientCallsEnabled(true)
, m_useFixedLayout(false)
, m_suppressScrollbarAnimations(false)
, m_paginationMode(Pagination::Unpaginated)
, m_paginationBehavesLikeColumns(false)
, m_pageLength(0)
, m_gapBetweenPages(0)
+ , m_paginationLineGridEnabled(false)
, m_isValid(true)
, m_isClosed(false)
, m_canRunModal(false)
@@ -292,47 +388,76 @@ WebPageProxy::WebPageProxy(PageClient& pageClient, WebProcessProxy& process, uin
, m_syncNavigationActionPolicyAction(PolicyUse)
, m_syncNavigationActionPolicyDownloadID(0)
, m_processingMouseMoveEvent(false)
-#if ENABLE(TOUCH_EVENTS)
- , m_needTouchEvents(false)
-#endif
, m_pageID(pageID)
- , m_session(*configuration.session)
+ , m_sessionID(m_configuration->sessionID())
, m_isPageSuspended(false)
-#if PLATFORM(MAC)
+ , m_addsVisitedLinks(true)
+ , m_controlledByAutomation(m_configuration->isControlledByAutomation())
+#if ENABLE(REMOTE_INSPECTOR)
+ , m_allowsRemoteInspection(true)
+#endif
+#if PLATFORM(COCOA)
, m_isSmartInsertDeleteEnabled(TextChecker::isSmartInsertDeleteEnabled())
#endif
+#if PLATFORM(GTK)
+ , m_backgroundColor(Color::white)
+#endif
, m_spellDocumentTag(0)
, m_hasSpellDocumentTag(false)
, m_pendingLearnOrIgnoreWordMessageCount(0)
+ , m_mainFrameHasCustomContentProvider(false)
+#if ENABLE(DRAG_SUPPORT)
+ , m_currentDragOperation(DragOperationNone)
+ , m_currentDragIsOverFileInput(false)
+ , m_currentDragNumberOfFilesToBeAccepted(0)
+#endif
+ , m_pageLoadState(*this)
+ , m_delegatesScrolling(false)
, m_mainFrameHasHorizontalScrollbar(false)
, m_mainFrameHasVerticalScrollbar(false)
, m_canShortCircuitHorizontalWheelEvents(true)
- , m_mainFrameIsPinnedToLeftSide(false)
- , m_mainFrameIsPinnedToRightSide(false)
- , m_mainFrameIsPinnedToTopSide(false)
- , m_mainFrameIsPinnedToBottomSide(false)
- , m_useLegacyImplicitRubberBandControl(false)
+ , m_mainFrameIsPinnedToLeftSide(true)
+ , m_mainFrameIsPinnedToRightSide(true)
+ , m_mainFrameIsPinnedToTopSide(true)
+ , m_mainFrameIsPinnedToBottomSide(true)
+ , m_shouldUseImplicitRubberBandControl(false)
, m_rubberBandsAtLeft(true)
, m_rubberBandsAtRight(true)
, m_rubberBandsAtTop(true)
, m_rubberBandsAtBottom(true)
+ , m_enableVerticalRubberBanding(true)
+ , m_enableHorizontalRubberBanding(true)
, m_backgroundExtendsBeyondPage(false)
- , m_mainFrameInViewSourceMode(false)
, m_shouldRecordNavigationSnapshots(false)
+ , m_isShowingNavigationGestureSnapshot(false)
, m_pageCount(0)
, m_renderTreeSize(0)
- , m_shouldSendEventsSynchronously(false)
+ , m_sessionRestorationRenderTreeSize(0)
+ , m_hitRenderTreeSizeThreshold(false)
, m_suppressVisibilityUpdates(false)
, m_autoSizingShouldExpandToViewHeight(false)
, m_mediaVolume(1)
, m_mayStartMediaWhenInWindow(true)
- , m_waitingForDidUpdateViewState(false)
+ , m_waitingForDidUpdateActivityState(false)
+#if PLATFORM(COCOA)
+ , m_scrollPerformanceDataCollectionEnabled(false)
+#endif
, m_scrollPinningBehavior(DoNotPin)
-{
- updateViewState();
-
-#if HAVE(LAYER_HOSTING_IN_WINDOW_SERVER)
- m_layerHostingMode = m_viewState & ViewState::IsInWindow ? m_pageClient.viewLayerHostingMode() : LayerHostingModeInWindowServer;
+ , m_navigationID(0)
+ , m_configurationPreferenceValues(m_configuration->preferenceValues())
+ , m_potentiallyChangedActivityStateFlags(ActivityState::NoFlags)
+ , m_activityStateChangeWantsSynchronousReply(false)
+ , m_weakPtrFactory(this)
+{
+ m_webProcessLifetimeTracker.addObserver(m_visitedLinkStore);
+ m_webProcessLifetimeTracker.addObserver(m_websiteDataStore);
+
+ updateActivityState();
+ updateThrottleState();
+ updateHiddenPageThrottlingAutoIncreases();
+
+#if HAVE(OUT_OF_PROCESS_LAYER_HOSTING)
+ m_layerHostingMode = m_activityState & ActivityState::IsInWindow ? m_pageClient.viewLayerHostingMode() : LayerHostingMode::OutOfProcess;
#endif
platformInitialize();
@@ -341,37 +466,59 @@ WebPageProxy::WebPageProxy(PageClient& pageClient, WebProcessProxy& process, uin
webPageProxyCounter.increment();
#endif
- WebContext::statistics().wkPageCount++;
+ WebProcessPool::statistics().wkPageCount++;
+ m_preferences->addPage(*this);
m_pageGroup->addPage(this);
-#if ENABLE(INSPECTOR)
m_inspector = WebInspectorProxy::create(this);
-#endif
#if ENABLE(FULLSCREEN_API)
m_fullScreenManager = WebFullScreenManagerProxy::create(*this, m_pageClient.fullScreenManagerProxyClient());
#endif
+#if PLATFORM(IOS) && HAVE(AVKIT) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
+ m_playbackSessionManager = WebPlaybackSessionManagerProxy::create(*this);
+ m_videoFullscreenManager = WebVideoFullscreenManagerProxy::create(*this, *m_playbackSessionManager);
+#endif
#if ENABLE(VIBRATION)
m_vibration = WebVibrationProxy::create(this);
#endif
+#if ENABLE(APPLE_PAY)
+ m_paymentCoordinator = std::make_unique<WebPaymentCoordinatorProxy>(*this);
+#endif
+
m_process->addMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID, *this);
- // FIXME: If we ever expose the session storage size as a preference, we need to pass it here.
- m_process->context().storageManager().createSessionStorageNamespace(m_pageID, m_process->isValid() ? m_process->connection() : 0, std::numeric_limits<unsigned>::max());
- setSession(*configuration.session);
+ if (m_sessionID.isEphemeral()) {
+ m_process->processPool().sendToNetworkingProcess(Messages::NetworkProcess::EnsurePrivateBrowsingSession(m_sessionID));
+ m_process->processPool().sendToAllProcesses(Messages::WebProcess::EnsurePrivateBrowsingSession(m_sessionID));
+ }
+
+#if PLATFORM(COCOA)
+ const CFIndex activityStateChangeRunLoopOrder = (CFIndex)RunLoopObserver::WellKnownRunLoopOrders::CoreAnimationCommit - 1;
+ m_activityStateChangeDispatcher = std::make_unique<RunLoopObserver>(activityStateChangeRunLoopOrder, [this] {
+ this->dispatchActivityStateChange();
+ });
+#endif
}
WebPageProxy::~WebPageProxy()
{
+ ASSERT(m_process->webPage(m_pageID) != this);
+#if !ASSERT_DISABLED
+ for (WebPageProxy* page : m_process->pages())
+ ASSERT(page != this);
+#endif
+
if (!m_isClosed)
close();
- WebContext::statistics().wkPageCount--;
+ WebProcessPool::statistics().wkPageCount--;
if (m_hasSpellDocumentTag)
TextChecker::closeSpellDocumentWithTag(m_spellDocumentTag);
+ m_preferences->removePage(*this);
m_pageGroup->removePage(this);
#ifndef NDEBUG
@@ -379,7 +526,12 @@ WebPageProxy::~WebPageProxy()
#endif
}
-PlatformProcessIdentifier WebPageProxy::processIdentifier() const
+const API::PageConfiguration& WebPageProxy::configuration() const
+{
+ return m_configuration.get();
+}
+
+pid_t WebPageProxy::processIdentifier() const
{
if (m_isClosed)
return 0;
@@ -396,20 +548,26 @@ bool WebPageProxy::isValid() const
return m_isValid;
}
-PassRefPtr<API::Array> WebPageProxy::relatedPages() const
+void WebPageProxy::setPreferences(WebPreferences& preferences)
{
- // pages() returns a list of pages in WebProcess, so this page may or may not be among them - a client can use a reference to WebPageProxy after the page has closed.
- Vector<WebPageProxy*> pages = m_process->pages();
+ if (&preferences == m_preferences.ptr())
+ return;
- Vector<RefPtr<API::Object>> result;
- result.reserveInitialCapacity(pages.size());
+ m_preferences->removePage(*this);
+ m_preferences = preferences;
+ m_preferences->addPage(*this);
- for (const auto& page : pages) {
- if (page != this)
- result.uncheckedAppend(page);
- }
+ preferencesDidChange();
+}
+
+void WebPageProxy::setHistoryClient(std::unique_ptr<API::HistoryClient> historyClient)
+{
+ m_historyClient = WTFMove(historyClient);
+}
- return API::Array::create(std::move(result));
+void WebPageProxy::setNavigationClient(std::unique_ptr<API::NavigationClient> navigationClient)
+{
+ m_navigationClient = WTFMove(navigationClient);
}
void WebPageProxy::setLoaderClient(std::unique_ptr<API::LoaderClient> loaderClient)
@@ -419,7 +577,7 @@ void WebPageProxy::setLoaderClient(std::unique_ptr<API::LoaderClient> loaderClie
return;
}
- m_loaderClient = std::move(loaderClient);
+ m_loaderClient = WTFMove(loaderClient);
}
void WebPageProxy::setPolicyClient(std::unique_ptr<API::PolicyClient> policyClient)
@@ -429,65 +587,158 @@ void WebPageProxy::setPolicyClient(std::unique_ptr<API::PolicyClient> policyClie
return;
}
- m_policyClient = std::move(policyClient);
+ m_policyClient = WTFMove(policyClient);
}
-void WebPageProxy::initializeFormClient(const WKPageFormClientBase* formClient)
+void WebPageProxy::setFormClient(std::unique_ptr<API::FormClient> formClient)
{
- m_formClient.initialize(formClient);
+ if (!formClient) {
+ m_formClient = std::make_unique<API::FormClient>();
+ return;
+ }
+
+ m_formClient = WTFMove(formClient);
}
-void WebPageProxy::initializeUIClient(const WKPageUIClientBase* client)
+void WebPageProxy::setUIClient(std::unique_ptr<API::UIClient> uiClient)
{
+ if (!uiClient) {
+ m_uiClient = std::make_unique<API::UIClient>();
+ return;
+ }
+
+ m_uiClient = WTFMove(uiClient);
+
if (!isValid())
return;
- m_uiClient.initialize(client);
+ m_process->send(Messages::WebPage::SetCanRunBeforeUnloadConfirmPanel(m_uiClient->canRunBeforeUnloadConfirmPanel()), m_pageID);
+ setCanRunModal(m_uiClient->canRunModal());
+}
- m_process->send(Messages::WebPage::SetCanRunBeforeUnloadConfirmPanel(m_uiClient.canRunBeforeUnloadConfirmPanel()), m_pageID);
- setCanRunModal(m_uiClient.canRunModal());
+void WebPageProxy::setIconLoadingClient(std::unique_ptr<API::IconLoadingClient> iconLoadingClient)
+{
+ bool hasClient = iconLoadingClient.get();
+ if (!iconLoadingClient)
+ m_iconLoadingClient = std::make_unique<API::IconLoadingClient>();
+ else
+ m_iconLoadingClient = WTFMove(iconLoadingClient);
+
+ if (!isValid())
+ return;
+
+ m_process->send(Messages::WebPage::SetUseIconLoadingClient(hasClient), m_pageID);
}
-void WebPageProxy::initializeFindClient(const WKPageFindClientBase* client)
+void WebPageProxy::setFindClient(std::unique_ptr<API::FindClient> findClient)
{
- m_findClient.initialize(client);
+ if (!findClient) {
+ m_findClient = std::make_unique<API::FindClient>();
+ return;
+ }
+
+ m_findClient = WTFMove(findClient);
}
-void WebPageProxy::initializeFindMatchesClient(const WKPageFindMatchesClientBase* client)
+void WebPageProxy::setFindMatchesClient(std::unique_ptr<API::FindMatchesClient> findMatchesClient)
{
- m_findMatchesClient.initialize(client);
+ if (!findMatchesClient) {
+ m_findMatchesClient = std::make_unique<API::FindMatchesClient>();
+ return;
+ }
+
+ m_findMatchesClient = WTFMove(findMatchesClient);
+}
+
+void WebPageProxy::setDiagnosticLoggingClient(std::unique_ptr<API::DiagnosticLoggingClient> diagnosticLoggingClient)
+{
+ if (!diagnosticLoggingClient) {
+ m_diagnosticLoggingClient = std::make_unique<API::DiagnosticLoggingClient>();
+ return;
+ }
+
+ m_diagnosticLoggingClient = WTFMove(diagnosticLoggingClient);
}
#if ENABLE(CONTEXT_MENUS)
-void WebPageProxy::initializeContextMenuClient(const WKPageContextMenuClientBase* client)
+void WebPageProxy::setContextMenuClient(std::unique_ptr<API::ContextMenuClient> contextMenuClient)
{
- m_contextMenuClient.initialize(client);
+ if (!contextMenuClient) {
+ m_contextMenuClient = std::make_unique<API::ContextMenuClient>();
+ return;
+ }
+
+ m_contextMenuClient = WTFMove(contextMenuClient);
}
#endif
+void WebPageProxy::setInjectedBundleClient(const WKPageInjectedBundleClientBase* client)
+{
+ if (!client) {
+ m_injectedBundleClient = nullptr;
+ return;
+ }
+
+ m_injectedBundleClient = std::make_unique<WebPageInjectedBundleClient>();
+ m_injectedBundleClient->initialize(client);
+}
+
+void WebPageProxy::handleMessage(IPC::Connection& connection, const String& messageName, const WebKit::UserData& messageBody)
+{
+ ASSERT(m_process->connection() == &connection);
+
+ if (!m_injectedBundleClient)
+ return;
+
+ m_injectedBundleClient->didReceiveMessageFromInjectedBundle(this, messageName, m_process->transformHandlesToObjects(messageBody.object()).get());
+}
+
+void WebPageProxy::handleSynchronousMessage(IPC::Connection& connection, const String& messageName, const UserData& messageBody, UserData& returnUserData)
+{
+ ASSERT(m_process->connection() == &connection);
+
+ if (!m_injectedBundleClient)
+ return;
+
+ RefPtr<API::Object> returnData;
+ m_injectedBundleClient->didReceiveSynchronousMessageFromInjectedBundle(this, messageName, m_process->transformHandlesToObjects(messageBody.object()).get(), returnData);
+ returnUserData = UserData(m_process->transformObjectsToHandles(returnData.get()));
+}
+
void WebPageProxy::reattachToWebProcess()
{
+ ASSERT(!m_isClosed);
ASSERT(!isValid());
- ASSERT(!m_process->isValid());
- ASSERT(!m_process->isLaunching());
-
- updateViewState();
+ ASSERT(m_process->state() == WebProcessProxy::State::Terminated);
m_isValid = true;
+ m_wasKilledForBeingUnresponsiveWhileInBackground = false;
+ m_process->removeWebPage(m_pageID);
+ m_process->removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID);
- if (m_process->context().processModel() == ProcessModelSharedSecondaryProcess)
- m_process = m_process->context().ensureSharedWebProcess();
- else
- m_process = m_process->context().createNewWebProcessRespectingProcessCountLimit();
+ m_process = m_process->processPool().createNewWebProcessRespectingProcessCountLimit();
+
+ ASSERT(m_process->state() != ChildProcessProxy::State::Terminated);
+ if (m_process->state() == ChildProcessProxy::State::Running)
+ processDidFinishLaunching();
m_process->addExistingWebPage(this, m_pageID);
m_process->addMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID, *this);
-#if ENABLE(INSPECTOR)
+ updateActivityState();
+ updateThrottleState();
+
m_inspector = WebInspectorProxy::create(this);
-#endif
#if ENABLE(FULLSCREEN_API)
m_fullScreenManager = WebFullScreenManagerProxy::create(*this, m_pageClient.fullScreenManagerProxyClient());
#endif
+#if PLATFORM(IOS) && HAVE(AVKIT) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
+ m_playbackSessionManager = WebPlaybackSessionManagerProxy::create(*this);
+ m_videoFullscreenManager = WebVideoFullscreenManagerProxy::create(*this, *m_playbackSessionManager);
+#endif
+
+#if ENABLE(APPLE_PAY)
+ m_paymentCoordinator = std::make_unique<WebPaymentCoordinatorProxy>(*this);
+#endif
initializeWebPage();
@@ -495,28 +746,46 @@ void WebPageProxy::reattachToWebProcess()
m_drawingArea->waitForBackingStoreUpdateOnNextPaint();
}
-void WebPageProxy::reattachToWebProcessWithItem(WebBackForwardListItem* item)
+RefPtr<API::Navigation> WebPageProxy::reattachToWebProcessForReload()
{
- if (item && item != m_backForwardList->currentItem())
- m_backForwardList->goToItem(item);
+ if (m_isClosed)
+ return nullptr;
+ ASSERT(!isValid());
reattachToWebProcess();
- if (!item)
- return;
+ if (!m_backForwardList->currentItem())
+ return nullptr;
+
+ auto navigation = m_navigationState->createReloadNavigation();
- m_process->send(Messages::WebPage::GoToBackForwardItem(item->itemID()), m_pageID);
- m_process->responsivenessTimer()->start();
+ // We allow stale content when reloading a WebProcess that's been killed or crashed.
+ m_process->send(Messages::WebPage::GoToBackForwardItem(navigation->navigationID(), m_backForwardList->currentItem()->itemID()), m_pageID);
+ m_process->responsivenessTimer().start();
+
+ return WTFMove(navigation);
}
-void WebPageProxy::setSession(API::Session& session)
+RefPtr<API::Navigation> WebPageProxy::reattachToWebProcessWithItem(WebBackForwardListItem* item)
{
- m_session = session;
- m_process->send(Messages::WebPage::SetSessionID(session.getID()), m_pageID);
+ if (m_isClosed)
+ return nullptr;
-#if ENABLE(NETWORK_PROCESS)
- m_process->context().sendToNetworkingProcess(Messages::NetworkProcess::EnsurePrivateBrowsingSession(session.getID()));
-#endif
+ ASSERT(!isValid());
+ reattachToWebProcess();
+
+ if (!item)
+ return nullptr;
+
+ if (item != m_backForwardList->currentItem())
+ m_backForwardList->goToItem(item);
+
+ auto navigation = m_navigationState->createBackForwardNavigation();
+
+ m_process->send(Messages::WebPage::GoToBackForwardItem(navigation->navigationID(), item->itemID()), m_pageID);
+ m_process->responsivenessTimer().start();
+
+ return WTFMove(navigation);
}
void WebPageProxy::initializeWebPage()
@@ -531,59 +800,86 @@ void WebPageProxy::initializeWebPage()
ASSERT(m_drawingArea);
#if ENABLE(ASYNC_SCROLLING)
- if (m_drawingArea->type() == DrawingAreaTypeRemoteLayerTree)
+ if (m_drawingArea->type() == DrawingAreaTypeRemoteLayerTree) {
m_scrollingCoordinatorProxy = std::make_unique<RemoteScrollingCoordinatorProxy>(*this);
+#if PLATFORM(IOS)
+ // On iOS, main frame scrolls are sent in terms of visible rect updates.
+ m_scrollingCoordinatorProxy->setPropagatesMainFrameScrolls(false);
+#endif
+ }
#endif
#if ENABLE(INSPECTOR_SERVER)
- if (pageGroup().preferences()->developerExtrasEnabled())
+ if (m_preferences->developerExtrasEnabled())
inspector()->enableRemoteInspection();
#endif
process().send(Messages::WebProcess::CreateWebPage(m_pageID, creationParameters()), 0);
-#if PLATFORM(MAC)
- send(Messages::WebPage::SetSmartInsertDeleteEnabled(m_isSmartInsertDeleteEnabled));
-#endif
+ m_needsToFinishInitializingWebPageAfterProcessLaunch = true;
+ finishInitializingWebPageAfterProcessLaunch();
}
-bool WebPageProxy::isProcessSuppressible() const
+void WebPageProxy::finishInitializingWebPageAfterProcessLaunch()
{
- return (m_viewState & ViewState::IsVisuallyIdle) && m_pageGroup->preferences()->pageVisibilityBasedProcessSuppressionEnabled();
+ if (!m_needsToFinishInitializingWebPageAfterProcessLaunch)
+ return;
+ if (m_process->state() != WebProcessProxy::State::Running)
+ return;
+
+ m_needsToFinishInitializingWebPageAfterProcessLaunch = false;
+
+ m_process->addWebUserContentControllerProxy(m_userContentController);
+ m_process->addVisitedLinkStore(m_visitedLinkStore);
}
void WebPageProxy::close()
{
- if (!isValid())
+ if (m_isClosed)
return;
m_isClosed = true;
+ if (m_activePopupMenu)
+ m_activePopupMenu->cancelTracking();
+
+#if ENABLE(CONTEXT_MENUS)
+ m_activeContextMenu = nullptr;
+#endif
+
m_backForwardList->pageClosed();
m_pageClient.pageClosed();
m_process->disconnectFramesFromPage(this);
- resetState();
+ resetState(ResetStateReason::PageInvalidated);
- m_loaderClient = nullptr;
- m_policyClient = nullptr;
- m_formClient.initialize(0);
- m_uiClient.initialize(0);
-#if PLATFORM(EFL)
- m_uiPopupMenuClient.initialize(0);
-#endif
- m_findClient.initialize(0);
- m_findMatchesClient.initialize(0);
+ m_loaderClient = std::make_unique<API::LoaderClient>();
+ m_navigationClient = nullptr;
+ m_policyClient = std::make_unique<API::PolicyClient>();
+ m_formClient = std::make_unique<API::FormClient>();
+ m_uiClient = std::make_unique<API::UIClient>();
+ m_findClient = std::make_unique<API::FindClient>();
+ m_findMatchesClient = std::make_unique<API::FindMatchesClient>();
+ m_diagnosticLoggingClient = std::make_unique<API::DiagnosticLoggingClient>();
#if ENABLE(CONTEXT_MENUS)
- m_contextMenuClient.initialize(0);
+ m_contextMenuClient = std::make_unique<API::ContextMenuClient>();
#endif
+ m_webProcessLifetimeTracker.pageWasInvalidated();
+
m_process->send(Messages::WebPage::Close(), m_pageID);
m_process->removeWebPage(m_pageID);
m_process->removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID);
- m_process->context().storageManager().destroySessionStorageNamespace(m_pageID);
- m_process->context().supplement<WebNotificationManagerProxy>()->clearNotifications(this);
+ m_process->processPool().supplement<WebNotificationManagerProxy>()->clearNotifications(this);
+
+ // Null out related WebPageProxy to avoid leaks.
+ m_configuration->setRelatedPage(nullptr);
+
+#if PLATFORM(IOS)
+ // Make sure we don't hold a process assertion after getting closed.
+ m_activityToken = nullptr;
+#endif
}
bool WebPageProxy::tryClose()
@@ -591,8 +887,13 @@ bool WebPageProxy::tryClose()
if (!isValid())
return true;
+ // Close without delay if the process allows it. Our goal is to terminate
+ // the process, so we check a per-process status bit.
+ if (m_process->isSuddenTerminationEnabled())
+ return true;
+
m_process->send(Messages::WebPage::TryClose(), m_pageID);
- m_process->responsivenessTimer()->start();
+ m_process->responsivenessTimer().start();
return false;
}
@@ -604,17 +905,26 @@ bool WebPageProxy::maybeInitializeSandboxExtensionHandle(const URL& url, Sandbox
if (m_process->hasAssumedReadAccessToURL(url))
return false;
-#if ENABLE(INSPECTOR)
// Inspector resources are in a directory with assumed access.
- ASSERT_WITH_SECURITY_IMPLICATION(!WebInspectorProxy::isInspectorPage(*this));
-#endif
+ ASSERT_WITH_SECURITY_IMPLICATION(!WebKit::isInspectorPage(*this));
SandboxExtension::createHandle("/", SandboxExtension::ReadOnly, sandboxExtensionHandle);
return true;
}
-void WebPageProxy::loadRequest(const ResourceRequest& request, API::Object* userData)
+#if !PLATFORM(COCOA)
+void WebPageProxy::addPlatformLoadParameters(LoadParameters&)
{
+}
+#endif
+
+RefPtr<API::Navigation> WebPageProxy::loadRequest(const ResourceRequest& request, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy, API::Object* userData)
+{
+ if (m_isClosed)
+ return nullptr;
+
+ auto navigation = m_navigationState->createLoadRequestNavigation(request);
+
auto transaction = m_pageLoadState.transaction();
m_pageLoadState.setPendingAPIRequestURL(transaction, request.url());
@@ -622,22 +932,33 @@ void WebPageProxy::loadRequest(const ResourceRequest& request, API::Object* user
if (!isValid())
reattachToWebProcess();
- SandboxExtension::Handle sandboxExtensionHandle;
- bool createdExtension = maybeInitializeSandboxExtensionHandle(request.url(), sandboxExtensionHandle);
+ LoadParameters loadParameters;
+ loadParameters.navigationID = navigation->navigationID();
+ loadParameters.request = request;
+ loadParameters.shouldOpenExternalURLsPolicy = (uint64_t)shouldOpenExternalURLsPolicy;
+ loadParameters.userData = UserData(process().transformObjectsToHandles(userData).get());
+ bool createdExtension = maybeInitializeSandboxExtensionHandle(request.url(), loadParameters.sandboxExtensionHandle);
if (createdExtension)
m_process->willAcquireUniversalFileReadSandboxExtension();
- m_process->send(Messages::WebPage::LoadRequest(request, sandboxExtensionHandle, WebContextUserMessageEncoder(userData, process())), m_pageID);
- m_process->responsivenessTimer()->start();
+ addPlatformLoadParameters(loadParameters);
+
+ m_process->send(Messages::WebPage::LoadRequest(loadParameters), m_pageID);
+ m_process->responsivenessTimer().start();
+
+ return WTFMove(navigation);
}
-void WebPageProxy::loadFile(const String& fileURLString, const String& resourceDirectoryURLString, API::Object* userData)
+RefPtr<API::Navigation> WebPageProxy::loadFile(const String& fileURLString, const String& resourceDirectoryURLString, API::Object* userData)
{
+ if (m_isClosed)
+ return nullptr;
+
if (!isValid())
reattachToWebProcess();
URL fileURL = URL(URL(), fileURLString);
if (!fileURL.isLocalFile())
- return;
+ return nullptr;
URL resourceDirectoryURL;
if (resourceDirectoryURLString.isNull())
@@ -645,71 +966,187 @@ void WebPageProxy::loadFile(const String& fileURLString, const String& resourceD
else {
resourceDirectoryURL = URL(URL(), resourceDirectoryURLString);
if (!resourceDirectoryURL.isLocalFile())
- return;
+ return nullptr;
}
+ auto navigation = m_navigationState->createLoadRequestNavigation(ResourceRequest(fileURL));
+
+ auto transaction = m_pageLoadState.transaction();
+
+ m_pageLoadState.setPendingAPIRequestURL(transaction, fileURLString);
+
String resourceDirectoryPath = resourceDirectoryURL.fileSystemPath();
- SandboxExtension::Handle sandboxExtensionHandle;
- SandboxExtension::createHandle(resourceDirectoryPath, SandboxExtension::ReadOnly, sandboxExtensionHandle);
+ LoadParameters loadParameters;
+ loadParameters.navigationID = navigation->navigationID();
+ loadParameters.request = fileURL;
+ loadParameters.shouldOpenExternalURLsPolicy = (uint64_t)ShouldOpenExternalURLsPolicy::ShouldNotAllow;
+ loadParameters.userData = UserData(process().transformObjectsToHandles(userData).get());
+ SandboxExtension::createHandle(resourceDirectoryPath, SandboxExtension::ReadOnly, loadParameters.sandboxExtensionHandle);
+ addPlatformLoadParameters(loadParameters);
+
m_process->assumeReadAccessToBaseURL(resourceDirectoryURL);
- m_process->send(Messages::WebPage::LoadRequest(fileURL, sandboxExtensionHandle, WebContextUserMessageEncoder(userData, process())), m_pageID);
- m_process->responsivenessTimer()->start();
+ m_process->send(Messages::WebPage::LoadRequest(loadParameters), m_pageID);
+ m_process->responsivenessTimer().start();
+
+ return WTFMove(navigation);
}
-void WebPageProxy::loadData(API::Data* data, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData)
+RefPtr<API::Navigation> WebPageProxy::loadData(API::Data* data, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData)
{
+ if (m_isClosed)
+ return nullptr;
+
+ auto navigation = m_navigationState->createLoadDataNavigation();
+
+ auto transaction = m_pageLoadState.transaction();
+
+ m_pageLoadState.setPendingAPIRequestURL(transaction, !baseURL.isEmpty() ? baseURL : blankURL().string());
+
if (!isValid())
reattachToWebProcess();
+ LoadParameters loadParameters;
+ loadParameters.navigationID = navigation->navigationID();
+ loadParameters.data = data->dataReference();
+ loadParameters.MIMEType = MIMEType;
+ loadParameters.encodingName = encoding;
+ loadParameters.baseURLString = baseURL;
+ loadParameters.userData = UserData(process().transformObjectsToHandles(userData).get());
+ addPlatformLoadParameters(loadParameters);
+
m_process->assumeReadAccessToBaseURL(baseURL);
- m_process->send(Messages::WebPage::LoadData(data->dataReference(), MIMEType, encoding, baseURL, WebContextUserMessageEncoder(userData, process())), m_pageID);
- m_process->responsivenessTimer()->start();
+ m_process->send(Messages::WebPage::LoadData(loadParameters), m_pageID);
+ m_process->responsivenessTimer().start();
+
+ return WTFMove(navigation);
}
-void WebPageProxy::loadHTMLString(const String& htmlString, const String& baseURL, API::Object* userData)
+// FIXME: Get rid of loadHTMLString and just use loadData instead.
+RefPtr<API::Navigation> WebPageProxy::loadHTMLString(const String& htmlString, const String& baseURL, API::Object* userData)
{
+ if (m_isClosed)
+ return nullptr;
+
+ auto navigation = m_navigationState->createLoadDataNavigation();
+
+ auto transaction = m_pageLoadState.transaction();
+
+ m_pageLoadState.setPendingAPIRequestURL(transaction, !baseURL.isEmpty() ? baseURL : blankURL().string());
+
if (!isValid())
reattachToWebProcess();
+ LoadParameters loadParameters;
+ loadParameters.navigationID = navigation->navigationID();
+ loadParameters.string = htmlString;
+ loadParameters.MIMEType = ASCIILiteral("text/html");
+ loadParameters.baseURLString = baseURL;
+ loadParameters.userData = UserData(process().transformObjectsToHandles(userData).get());
+ addPlatformLoadParameters(loadParameters);
+
m_process->assumeReadAccessToBaseURL(baseURL);
- m_process->send(Messages::WebPage::LoadHTMLString(htmlString, baseURL, WebContextUserMessageEncoder(userData, process())), m_pageID);
- m_process->responsivenessTimer()->start();
+ m_process->send(Messages::WebPage::LoadString(loadParameters), m_pageID);
+ m_process->responsivenessTimer().start();
+
+ return WTFMove(navigation);
}
void WebPageProxy::loadAlternateHTMLString(const String& htmlString, const String& baseURL, const String& unreachableURL, API::Object* userData)
{
+ // When the UIProcess is in the process of handling a failing provisional load, do not attempt to
+ // start a second alternative HTML load as this will prevent the page load state from being
+ // handled properly.
+ if (m_isClosed || m_isLoadingAlternateHTMLStringForFailingProvisionalLoad)
+ return;
+
+ if (!m_failingProvisionalLoadURL.isEmpty())
+ m_isLoadingAlternateHTMLStringForFailingProvisionalLoad = true;
+
if (!isValid())
reattachToWebProcess();
auto transaction = m_pageLoadState.transaction();
+ m_pageLoadState.setPendingAPIRequestURL(transaction, unreachableURL);
m_pageLoadState.setUnreachableURL(transaction, unreachableURL);
if (m_mainFrame)
m_mainFrame->setUnreachableURL(unreachableURL);
+ LoadParameters loadParameters;
+ loadParameters.navigationID = 0;
+ loadParameters.string = htmlString;
+ loadParameters.baseURLString = baseURL;
+ loadParameters.unreachableURLString = unreachableURL;
+ loadParameters.provisionalLoadErrorURLString = m_failingProvisionalLoadURL;
+ loadParameters.userData = UserData(process().transformObjectsToHandles(userData).get());
+ addPlatformLoadParameters(loadParameters);
+
m_process->assumeReadAccessToBaseURL(baseURL);
- m_process->send(Messages::WebPage::LoadAlternateHTMLString(htmlString, baseURL, unreachableURL, WebContextUserMessageEncoder(userData, process())), m_pageID);
- m_process->responsivenessTimer()->start();
+ m_process->assumeReadAccessToBaseURL(unreachableURL);
+ m_process->send(Messages::WebPage::LoadAlternateHTMLString(loadParameters), m_pageID);
+ m_process->responsivenessTimer().start();
}
void WebPageProxy::loadPlainTextString(const String& string, API::Object* userData)
{
+ if (m_isClosed)
+ return;
+
if (!isValid())
reattachToWebProcess();
- m_process->send(Messages::WebPage::LoadPlainTextString(string, WebContextUserMessageEncoder(userData, process())), m_pageID);
- m_process->responsivenessTimer()->start();
+ auto transaction = m_pageLoadState.transaction();
+ m_pageLoadState.setPendingAPIRequestURL(transaction, blankURL().string());
+
+ LoadParameters loadParameters;
+ loadParameters.navigationID = 0;
+ loadParameters.string = string;
+ loadParameters.MIMEType = ASCIILiteral("text/plain");
+ loadParameters.userData = UserData(process().transformObjectsToHandles(userData).get());
+ addPlatformLoadParameters(loadParameters);
+
+ m_process->send(Messages::WebPage::LoadString(loadParameters), m_pageID);
+ m_process->responsivenessTimer().start();
}
void WebPageProxy::loadWebArchiveData(API::Data* webArchiveData, API::Object* userData)
{
+ if (m_isClosed)
+ return;
+
if (!isValid())
reattachToWebProcess();
- m_process->send(Messages::WebPage::LoadWebArchiveData(webArchiveData->dataReference(), WebContextUserMessageEncoder(userData, process())), m_pageID);
- m_process->responsivenessTimer()->start();
+ auto transaction = m_pageLoadState.transaction();
+ m_pageLoadState.setPendingAPIRequestURL(transaction, blankURL().string());
+
+ LoadParameters loadParameters;
+ loadParameters.navigationID = 0;
+ loadParameters.data = webArchiveData->dataReference();
+ loadParameters.MIMEType = ASCIILiteral("application/x-webarchive");
+ loadParameters.encodingName = ASCIILiteral("utf-16");
+ loadParameters.userData = UserData(process().transformObjectsToHandles(userData).get());
+ addPlatformLoadParameters(loadParameters);
+
+ m_process->send(Messages::WebPage::LoadData(loadParameters), m_pageID);
+ m_process->responsivenessTimer().start();
+}
+
+void WebPageProxy::navigateToPDFLinkWithSimulatedClick(const String& url, IntPoint documentPoint, IntPoint screenPoint)
+{
+ if (m_isClosed)
+ return;
+
+ if (WebCore::protocolIsJavaScript(url))
+ return;
+
+ if (!isValid())
+ reattachToWebProcess();
+
+ m_process->send(Messages::WebPage::NavigateToPDFLinkWithSimulatedClick(url, documentPoint, screenPoint), m_pageID);
+ m_process->responsivenessTimer().start();
}
void WebPageProxy::stopLoading()
@@ -718,15 +1155,18 @@ void WebPageProxy::stopLoading()
return;
m_process->send(Messages::WebPage::StopLoading(), m_pageID);
- m_process->responsivenessTimer()->start();
+ m_process->responsivenessTimer().start();
}
-void WebPageProxy::reload(bool reloadFromOrigin)
+RefPtr<API::Navigation> WebPageProxy::reload(bool reloadFromOrigin, bool contentBlockersEnabled)
{
SandboxExtension::Handle sandboxExtensionHandle;
- if (m_backForwardList->currentItem()) {
- String url = m_backForwardList->currentItem()->url();
+ String url = m_pageLoadState.activeURL();
+ if (url.isEmpty() && m_backForwardList->currentItem())
+ url = m_backForwardList->currentItem()->url();
+
+ if (!url.isEmpty()) {
auto transaction = m_pageLoadState.transaction();
m_pageLoadState.setPendingAPIRequestURL(transaction, url);
@@ -736,82 +1176,101 @@ void WebPageProxy::reload(bool reloadFromOrigin)
m_process->willAcquireUniversalFileReadSandboxExtension();
}
- if (!isValid()) {
- reattachToWebProcessWithItem(m_backForwardList->currentItem());
+ if (!isValid())
+ return reattachToWebProcessForReload();
+
+ auto navigation = m_navigationState->createReloadNavigation();
+
+ m_process->send(Messages::WebPage::Reload(navigation->navigationID(), reloadFromOrigin, contentBlockersEnabled, sandboxExtensionHandle), m_pageID);
+ m_process->responsivenessTimer().start();
+
+ return WTFMove(navigation);
+}
+
+void WebPageProxy::recordAutomaticNavigationSnapshot()
+{
+ if (m_suppressAutomaticNavigationSnapshotting)
return;
- }
- m_process->send(Messages::WebPage::Reload(reloadFromOrigin, sandboxExtensionHandle), m_pageID);
- m_process->responsivenessTimer()->start();
+ if (WebBackForwardListItem* item = m_backForwardList->currentItem())
+ recordNavigationSnapshot(*item);
}
-void WebPageProxy::recordNavigationSnapshot()
+void WebPageProxy::recordNavigationSnapshot(WebBackForwardListItem& item)
{
if (!m_shouldRecordNavigationSnapshots)
return;
-#if PLATFORM(MAC) && !PLATFORM(IOS)
- ViewSnapshotStore::shared().recordSnapshot(*this);
+#if PLATFORM(COCOA)
+ ViewSnapshotStore::singleton().recordSnapshot(*this, item);
+#else
+ UNUSED_PARAM(item);
#endif
}
-void WebPageProxy::goForward()
+RefPtr<API::Navigation> WebPageProxy::goForward()
{
WebBackForwardListItem* forwardItem = m_backForwardList->forwardItem();
if (!forwardItem)
- return;
-
- recordNavigationSnapshot();
+ return nullptr;
auto transaction = m_pageLoadState.transaction();
m_pageLoadState.setPendingAPIRequestURL(transaction, forwardItem->url());
- if (!isValid()) {
- reattachToWebProcessWithItem(forwardItem);
- return;
- }
+ if (!isValid())
+ return reattachToWebProcessWithItem(forwardItem);
- m_process->send(Messages::WebPage::GoForward(forwardItem->itemID()), m_pageID);
- m_process->responsivenessTimer()->start();
+ RefPtr<API::Navigation> navigation;
+ if (!m_backForwardList->currentItem()->itemIsInSameDocument(*forwardItem))
+ navigation = m_navigationState->createBackForwardNavigation();
+
+ m_process->send(Messages::WebPage::GoForward(navigation ? navigation->navigationID() : 0, forwardItem->itemID()), m_pageID);
+ m_process->responsivenessTimer().start();
+
+ return navigation;
}
-void WebPageProxy::goBack()
+RefPtr<API::Navigation> WebPageProxy::goBack()
{
WebBackForwardListItem* backItem = m_backForwardList->backItem();
if (!backItem)
- return;
-
- recordNavigationSnapshot();
+ return nullptr;
auto transaction = m_pageLoadState.transaction();
m_pageLoadState.setPendingAPIRequestURL(transaction, backItem->url());
- if (!isValid()) {
- reattachToWebProcessWithItem(backItem);
- return;
- }
+ if (!isValid())
+ return reattachToWebProcessWithItem(backItem);
+
+ RefPtr<API::Navigation> navigation;
+ if (!m_backForwardList->currentItem()->itemIsInSameDocument(*backItem))
+ navigation = m_navigationState->createBackForwardNavigation();
+
+ m_process->send(Messages::WebPage::GoBack(navigation ? navigation->navigationID() : 0, backItem->itemID()), m_pageID);
+ m_process->responsivenessTimer().start();
- m_process->send(Messages::WebPage::GoBack(backItem->itemID()), m_pageID);
- m_process->responsivenessTimer()->start();
+ return navigation;
}
-void WebPageProxy::goToBackForwardItem(WebBackForwardListItem* item)
+RefPtr<API::Navigation> WebPageProxy::goToBackForwardItem(WebBackForwardListItem* item)
{
- if (!isValid()) {
- reattachToWebProcessWithItem(item);
- return;
- }
+ if (!isValid())
+ return reattachToWebProcessWithItem(item);
- recordNavigationSnapshot();
-
auto transaction = m_pageLoadState.transaction();
m_pageLoadState.setPendingAPIRequestURL(transaction, item->url());
- m_process->send(Messages::WebPage::GoToBackForwardItem(item->itemID()), m_pageID);
- m_process->responsivenessTimer()->start();
+ RefPtr<API::Navigation> navigation;
+ if (!m_backForwardList->currentItem()->itemIsInSameDocument(*item))
+ navigation = m_navigationState->createBackForwardNavigation();
+
+ m_process->send(Messages::WebPage::GoToBackForwardItem(navigation ? navigation->navigationID() : 0, item->itemID()), m_pageID);
+ m_process->responsivenessTimer().start();
+
+ return navigation;
}
void WebPageProxy::tryRestoreScrollPosition()
@@ -822,20 +1281,31 @@ void WebPageProxy::tryRestoreScrollPosition()
m_process->send(Messages::WebPage::TryRestoreScrollPosition(), m_pageID);
}
-void WebPageProxy::didChangeBackForwardList(WebBackForwardListItem* added, Vector<RefPtr<API::Object>>* removed)
+void WebPageProxy::didChangeBackForwardList(WebBackForwardListItem* added, Vector<RefPtr<WebBackForwardListItem>> removed)
{
- m_loaderClient->didChangeBackForwardList(this, added, removed);
+ PageClientProtector protector(m_pageClient);
+
+ m_loaderClient->didChangeBackForwardList(*this, added, WTFMove(removed));
+
+ auto transaction = m_pageLoadState.transaction();
+
+ m_pageLoadState.setCanGoBack(transaction, m_backForwardList->backItem());
+ m_pageLoadState.setCanGoForward(transaction, m_backForwardList->forwardItem());
}
-void WebPageProxy::willGoToBackForwardListItem(uint64_t itemID, IPC::MessageDecoder& decoder)
+void WebPageProxy::willGoToBackForwardListItem(uint64_t itemID, const UserData& userData)
{
- RefPtr<API::Object> userData;
- WebContextUserMessageDecoder messageDecoder(userData, process());
- if (!decoder.decode(messageDecoder))
- return;
+ PageClientProtector protector(m_pageClient);
if (WebBackForwardListItem* item = m_process->webBackForwardItem(itemID))
- m_loaderClient->willGoToBackForwardListItem(this, item, userData.get());
+ m_loaderClient->willGoToBackForwardListItem(*this, item, m_process->transformHandlesToObjects(userData.object()).get());
+}
+
+bool WebPageProxy::shouldKeepCurrentBackForwardListItemInList(WebBackForwardListItem* item)
+{
+ PageClientProtector protector(m_pageClient);
+
+ return m_loaderClient->shouldKeepCurrentBackForwardListItemInList(*this, item);
}
bool WebPageProxy::canShowMIMEType(const String& mimeType)
@@ -845,20 +1315,56 @@ bool WebPageProxy::canShowMIMEType(const String& mimeType)
#if ENABLE(NETSCAPE_PLUGIN_API)
String newMimeType = mimeType;
- PluginModuleInfo plugin = m_process->context().pluginInfoStore().findPlugin(newMimeType, URL());
- if (!plugin.path.isNull() && m_pageGroup->preferences()->pluginsEnabled())
+ PluginModuleInfo plugin = m_process->processPool().pluginInfoStore().findPlugin(newMimeType, URL());
+ if (!plugin.path.isNull() && m_preferences->pluginsEnabled())
return true;
#endif // ENABLE(NETSCAPE_PLUGIN_API)
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
// On Mac, we can show PDFs.
- if (MIMETypeRegistry::isPDFOrPostScriptMIMEType(mimeType) && !WebContext::omitPDFSupport())
+ if (MIMETypeRegistry::isPDFOrPostScriptMIMEType(mimeType) && !WebProcessPool::omitPDFSupport())
return true;
-#endif // PLATFORM(MAC)
+#endif // PLATFORM(COCOA)
return false;
}
+void WebPageProxy::setControlledByAutomation(bool controlled)
+{
+ if (m_controlledByAutomation == controlled)
+ return;
+
+ m_controlledByAutomation = controlled;
+
+ if (isValid())
+ m_process->send(Messages::WebPage::SetControlledByAutomation(controlled), m_pageID);
+}
+
+#if ENABLE(REMOTE_INSPECTOR)
+void WebPageProxy::setAllowsRemoteInspection(bool allow)
+{
+ if (m_allowsRemoteInspection == allow)
+ return;
+
+ m_allowsRemoteInspection = allow;
+
+ if (isValid())
+ m_process->send(Messages::WebPage::SetAllowsRemoteInspection(allow), m_pageID);
+}
+
+void WebPageProxy::setRemoteInspectionNameOverride(const String& name)
+{
+ if (m_remoteInspectionNameOverride == name)
+ return;
+
+ m_remoteInspectionNameOverride = name;
+
+ if (isValid())
+ m_process->send(Messages::WebPage::SetRemoteInspectionNameOverride(m_remoteInspectionNameOverride), m_pageID);
+}
+
+#endif
+
void WebPageProxy::setDrawsBackground(bool drawsBackground)
{
if (m_drawsBackground == drawsBackground)
@@ -870,15 +1376,23 @@ void WebPageProxy::setDrawsBackground(bool drawsBackground)
m_process->send(Messages::WebPage::SetDrawsBackground(drawsBackground), m_pageID);
}
-void WebPageProxy::setDrawsTransparentBackground(bool drawsTransparentBackground)
+void WebPageProxy::setTopContentInset(float contentInset)
{
- if (m_drawsTransparentBackground == drawsTransparentBackground)
+ if (m_topContentInset == contentInset)
return;
- m_drawsTransparentBackground = drawsTransparentBackground;
+ m_topContentInset = contentInset;
- if (isValid())
- m_process->send(Messages::WebPage::SetDrawsTransparentBackground(drawsTransparentBackground), m_pageID);
+ if (!isValid())
+ return;
+#if HAVE(COREANIMATION_FENCES)
+ MachSendRight fence = m_drawingArea->createFence();
+
+ auto fenceAttachment = IPC::Attachment(fence.leakSendRight(), MACH_MSG_TYPE_MOVE_SEND);
+ m_process->send(Messages::WebPage::SetTopContentInsetFenced(contentInset, fenceAttachment), m_pageID);
+#else
+ m_process->send(Messages::WebPage::SetTopContentInset(contentInset), m_pageID);
+#endif
}
void WebPageProxy::setUnderlayColor(const Color& color)
@@ -896,7 +1410,7 @@ void WebPageProxy::viewWillStartLiveResize()
{
if (!isValid())
return;
-#if ENABLE(INPUT_TYPE_COLOR_POPOVER)
+#if ENABLE(INPUT_TYPE_COLOR_POPOVER) && ENABLE(INPUT_TYPE_COLOR)
if (m_colorPicker)
endColorPicker();
#endif
@@ -910,102 +1424,269 @@ void WebPageProxy::viewWillEndLiveResize()
m_process->send(Messages::WebPage::ViewWillEndLiveResize(), m_pageID);
}
-void WebPageProxy::setViewNeedsDisplay(const IntRect& rect)
+void WebPageProxy::setViewNeedsDisplay(const Region& region)
{
- m_pageClient.setViewNeedsDisplay(rect);
+ m_pageClient.setViewNeedsDisplay(region);
}
-void WebPageProxy::displayView()
+void WebPageProxy::requestScroll(const FloatPoint& scrollPosition, const IntPoint& scrollOrigin, bool isProgrammaticScroll)
{
- m_pageClient.displayView();
+ m_pageClient.requestScroll(scrollPosition, scrollOrigin, isProgrammaticScroll);
}
-bool WebPageProxy::canScrollView()
+void WebPageProxy::setSuppressVisibilityUpdates(bool flag)
{
- return m_pageClient.canScrollView();
+ if (m_suppressVisibilityUpdates == flag)
+ return;
+ m_suppressVisibilityUpdates = flag;
+
+ if (!m_suppressVisibilityUpdates) {
+#if PLATFORM(COCOA)
+ m_activityStateChangeDispatcher->schedule();
+#else
+ dispatchActivityStateChange();
+#endif
+ }
+}
+
+void WebPageProxy::updateActivityState(ActivityState::Flags flagsToUpdate)
+{
+ m_activityState &= ~flagsToUpdate;
+ if (flagsToUpdate & ActivityState::IsFocused && m_pageClient.isViewFocused())
+ m_activityState |= ActivityState::IsFocused;
+ if (flagsToUpdate & ActivityState::WindowIsActive && m_pageClient.isViewWindowActive())
+ m_activityState |= ActivityState::WindowIsActive;
+ if (flagsToUpdate & ActivityState::IsVisible && m_pageClient.isViewVisible())
+ m_activityState |= ActivityState::IsVisible;
+ if (flagsToUpdate & ActivityState::IsVisibleOrOccluded && m_pageClient.isViewVisibleOrOccluded())
+ m_activityState |= ActivityState::IsVisibleOrOccluded;
+ if (flagsToUpdate & ActivityState::IsInWindow && m_pageClient.isViewInWindow())
+ m_activityState |= ActivityState::IsInWindow;
+ if (flagsToUpdate & ActivityState::IsVisuallyIdle && m_pageClient.isVisuallyIdle())
+ m_activityState |= ActivityState::IsVisuallyIdle;
+ if (flagsToUpdate & ActivityState::IsAudible && m_mediaState & MediaProducer::IsPlayingAudio && !(m_mutedState & MediaProducer::AudioIsMuted))
+ m_activityState |= ActivityState::IsAudible;
+ if (flagsToUpdate & ActivityState::IsLoading && m_pageLoadState.isLoading())
+ m_activityState |= ActivityState::IsLoading;
+}
+
+void WebPageProxy::activityStateDidChange(ActivityState::Flags mayHaveChanged, bool wantsSynchronousReply, ActivityStateChangeDispatchMode dispatchMode)
+{
+ m_potentiallyChangedActivityStateFlags |= mayHaveChanged;
+ m_activityStateChangeWantsSynchronousReply = m_activityStateChangeWantsSynchronousReply || wantsSynchronousReply;
+
+ if (m_suppressVisibilityUpdates && dispatchMode != ActivityStateChangeDispatchMode::Immediate)
+ return;
+
+#if PLATFORM(COCOA)
+ bool isNewlyInWindow = !isInWindow() && (mayHaveChanged & ActivityState::IsInWindow) && m_pageClient.isViewInWindow();
+ if (dispatchMode == ActivityStateChangeDispatchMode::Immediate || isNewlyInWindow) {
+ dispatchActivityStateChange();
+ return;
+ }
+ m_activityStateChangeDispatcher->schedule();
+#else
+ UNUSED_PARAM(dispatchMode);
+ dispatchActivityStateChange();
+#endif
}
-void WebPageProxy::scrollView(const IntRect& scrollRect, const IntSize& scrollOffset)
+void WebPageProxy::viewDidLeaveWindow()
{
- m_pageClient.scrollView(scrollRect, scrollOffset);
+#if ENABLE(INPUT_TYPE_COLOR_POPOVER) && ENABLE(INPUT_TYPE_COLOR)
+ // When leaving the current page, close the popover color well.
+ if (m_colorPicker)
+ endColorPicker();
+#endif
+#if PLATFORM(IOS) && HAVE(AVKIT) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
+ // When leaving the current page, close the video fullscreen.
+ if (m_videoFullscreenManager)
+ m_videoFullscreenManager->requestHideAndExitFullscreen();
+#endif
}
-void WebPageProxy::updateViewState(ViewState::Flags flagsToUpdate)
+void WebPageProxy::viewDidEnterWindow()
{
- m_viewState &= ~flagsToUpdate;
- if (flagsToUpdate & ViewState::IsFocused && m_pageClient.isViewFocused())
- m_viewState |= ViewState::IsFocused;
- if (flagsToUpdate & ViewState::WindowIsActive && m_pageClient.isViewWindowActive())
- m_viewState |= ViewState::WindowIsActive;
- if (flagsToUpdate & ViewState::IsVisible && m_pageClient.isViewVisible())
- m_viewState |= ViewState::IsVisible;
- if (flagsToUpdate & ViewState::IsInWindow && m_pageClient.isViewInWindow())
- m_viewState |= ViewState::IsInWindow;
- if (flagsToUpdate & ViewState::IsVisuallyIdle && m_pageClient.isVisuallyIdle())
- m_viewState |= ViewState::IsVisuallyIdle;
+ LayerHostingMode layerHostingMode = m_pageClient.viewLayerHostingMode();
+ if (m_layerHostingMode != layerHostingMode) {
+ m_layerHostingMode = layerHostingMode;
+ m_process->send(Messages::WebPage::SetLayerHostingMode(layerHostingMode), m_pageID);
+ }
}
-void WebPageProxy::viewStateDidChange(ViewState::Flags mayHaveChanged, WantsReplyOrNot wantsReply)
+void WebPageProxy::reloadAfterBeingKilledInBackground()
{
- if (!isValid())
+ ASSERT(!isValid());
+
+ RELEASE_LOG_IF_ALLOWED("%p - Reloading tab that was killed in the background", this);
+
+ // Only report as a crash if the page was ever visible, otherwise silently reload.
+ if (m_hasEverBeenVisible)
+ processDidCrash();
+ else
+ reattachToWebProcessForReload();
+}
+
+void WebPageProxy::dispatchActivityStateChange()
+{
+#if PLATFORM(COCOA)
+ m_activityStateChangeDispatcher->invalidate();
+#endif
+
+ if (!isValid()) {
+ if (m_potentiallyChangedActivityStateFlags & ActivityState::IsVisible && m_wasKilledForBeingUnresponsiveWhileInBackground)
+ reloadAfterBeingKilledInBackground();
return;
+ }
- // If the visibility state may have changed, then so may the visually idle.
- if (mayHaveChanged & ViewState::IsVisible)
- mayHaveChanged |= ViewState::IsVisuallyIdle;
+ // If the visibility state may have changed, then so may the visually idle & occluded agnostic state.
+ if (m_potentiallyChangedActivityStateFlags & ActivityState::IsVisible)
+ m_potentiallyChangedActivityStateFlags |= ActivityState::IsVisibleOrOccluded | ActivityState::IsVisuallyIdle;
// Record the prior view state, update the flags that may have changed,
// and check which flags have actually changed.
- ViewState::Flags previousViewState = m_viewState;
- updateViewState(mayHaveChanged);
- ViewState::Flags changed = m_viewState ^ previousViewState;
-
- if (changed)
- m_process->send(Messages::WebPage::SetViewState(m_viewState, wantsReply == WantsReplyOrNot::DoesWantReply), m_pageID);
-
- if (changed & ViewState::IsVisuallyIdle)
- m_process->pageSuppressibilityChanged(this);
-
- // If we've started the responsiveness timer as part of telling the web process to update the backing store
- // state, it might not send back a reply (since it won't paint anything if the web page is hidden) so we
- // stop the unresponsiveness timer here.
- if ((changed & ViewState::IsVisible) && !isViewVisible())
- m_process->responsivenessTimer()->stop();
-
- if ((mayHaveChanged & ViewState::IsInWindow) && (m_viewState & ViewState::IsInWindow)) {
- LayerHostingMode layerHostingMode = m_pageClient.viewLayerHostingMode();
- if (m_layerHostingMode != layerHostingMode) {
- m_layerHostingMode = layerHostingMode;
- m_process->send(Messages::WebPage::SetLayerHostingMode(layerHostingMode), m_pageID);
+ ActivityState::Flags previousActivityState = m_activityState;
+ updateActivityState(m_potentiallyChangedActivityStateFlags);
+ ActivityState::Flags changed = m_activityState ^ previousActivityState;
+
+ bool isNowInWindow = (changed & ActivityState::IsInWindow) && isInWindow();
+ // We always want to wait for the Web process to reply if we've been in-window before and are coming back in-window.
+ if (m_viewWasEverInWindow && isNowInWindow) {
+ if (m_drawingArea->hasVisibleContent() && m_waitsForPaintAfterViewDidMoveToWindow && !m_shouldSkipWaitingForPaintAfterNextViewDidMoveToWindow)
+ m_activityStateChangeWantsSynchronousReply = true;
+ m_shouldSkipWaitingForPaintAfterNextViewDidMoveToWindow = false;
+ }
+
+ // Don't wait synchronously if the view state is not visible. (This matters in particular on iOS, where a hidden page may be suspended.)
+ if (!(m_activityState & ActivityState::IsVisible))
+ m_activityStateChangeWantsSynchronousReply = false;
+
+ if (changed || m_activityStateChangeWantsSynchronousReply || !m_nextActivityStateChangeCallbacks.isEmpty())
+ m_process->send(Messages::WebPage::SetActivityState(m_activityState, m_activityStateChangeWantsSynchronousReply, m_nextActivityStateChangeCallbacks), m_pageID);
+
+ m_nextActivityStateChangeCallbacks.clear();
+
+ // This must happen after the SetActivityState message is sent, to ensure the page visibility event can fire.
+ updateThrottleState();
+
+#if ENABLE(POINTER_LOCK)
+ if (((changed & ActivityState::IsVisible) && !isViewVisible()) || ((changed & ActivityState::WindowIsActive) && !m_pageClient.isViewWindowActive())
+ || ((changed & ActivityState::IsFocused) && !(m_activityState & ActivityState::IsFocused)))
+ requestPointerUnlock();
+#endif
+
+ if (changed & ActivityState::IsVisible) {
+ if (isViewVisible()) {
+ m_hasEverBeenVisible = true;
+ m_visiblePageToken = m_process->visiblePageToken();
+ } else {
+ m_visiblePageToken = nullptr;
+
+ // If we've started the responsiveness timer as part of telling the web process to update the backing store
+ // state, it might not send back a reply (since it won't paint anything if the web page is hidden) so we
+ // stop the unresponsiveness timer here.
+ m_process->responsivenessTimer().stop();
}
}
-#if ENABLE(INPUT_TYPE_COLOR_POPOVER)
- if ((mayHaveChanged & ViewState::IsInWindow) && !(m_viewState & ViewState::IsInWindow)) {
- // When leaving the current page, close the popover color well.
- if (m_colorPicker)
- endColorPicker();
+ if (changed & ActivityState::IsInWindow) {
+ if (isInWindow())
+ viewDidEnterWindow();
+ else
+ viewDidLeaveWindow();
}
-#endif
updateBackingStoreDiscardableState();
+
+ if (m_activityStateChangeWantsSynchronousReply)
+ waitForDidUpdateActivityState();
+
+ m_potentiallyChangedActivityStateFlags = ActivityState::NoFlags;
+ m_activityStateChangeWantsSynchronousReply = false;
+ m_viewWasEverInWindow |= isNowInWindow;
}
-void WebPageProxy::waitForDidUpdateViewState()
+bool WebPageProxy::isAlwaysOnLoggingAllowed() const
{
- // If we have previously timed out with no response from the WebProcess, don't block the UIProcess again until it starts responding.
- if (m_waitingForDidUpdateViewState)
+ return sessionID().isAlwaysOnLoggingAllowed();
+}
+
+void WebPageProxy::updateThrottleState()
+{
+ bool processSuppressionEnabled = m_preferences->pageVisibilityBasedProcessSuppressionEnabled();
+
+ // If process suppression is not enabled take a token on the process pool to disable suppression of support processes.
+ if (!processSuppressionEnabled)
+ m_preventProcessSuppressionCount = m_process->processPool().processSuppressionDisabledForPageCount();
+ else if (!m_preventProcessSuppressionCount)
+ m_preventProcessSuppressionCount = nullptr;
+
+ if (m_activityState & ActivityState::IsVisuallyIdle)
+ m_pageIsUserObservableCount = nullptr;
+ else if (!m_pageIsUserObservableCount)
+ m_pageIsUserObservableCount = m_process->processPool().userObservablePageCount();
+
+#if PLATFORM(IOS)
+ if (!isViewVisible() && !m_alwaysRunsAtForegroundPriority) {
+ if (m_activityToken) {
+ RELEASE_LOG_IF_ALLOWED("%p - UIProcess is releasing a foreground assertion because the view is no longer visible", this);
+ m_activityToken = nullptr;
+ }
+ } else if (!m_activityToken) {
+ if (isViewVisible())
+ RELEASE_LOG_IF_ALLOWED("%p - UIProcess is taking a foreground assertion because the view is visible", this);
+ else
+ RELEASE_LOG_IF_ALLOWED("%p - UIProcess is taking a foreground assertion even though the view is not visible because m_alwaysRunsAtForegroundPriority is true", this);
+ m_activityToken = m_process->throttler().foregroundActivityToken();
+ }
+#endif
+}
+
+void WebPageProxy::updateHiddenPageThrottlingAutoIncreases()
+{
+ if (!m_preferences->hiddenPageDOMTimerThrottlingAutoIncreases())
+ m_hiddenPageDOMTimerThrottlingAutoIncreasesCount = nullptr;
+ else if (!m_hiddenPageDOMTimerThrottlingAutoIncreasesCount)
+ m_hiddenPageDOMTimerThrottlingAutoIncreasesCount = m_process->processPool().hiddenPageThrottlingAutoIncreasesCount();
+}
+
+void WebPageProxy::layerHostingModeDidChange()
+{
+ if (!isValid())
return;
+ LayerHostingMode layerHostingMode = m_pageClient.viewLayerHostingMode();
+ if (m_layerHostingMode == layerHostingMode)
+ return;
+
+ m_layerHostingMode = layerHostingMode;
+ m_process->send(Messages::WebPage::SetLayerHostingMode(layerHostingMode), m_pageID);
+}
+
+void WebPageProxy::waitForDidUpdateActivityState()
+{
if (!isValid())
return;
- m_waitingForDidUpdateViewState = true;
+ if (m_process->state() != WebProcessProxy::State::Running)
+ return;
+
+ // If we have previously timed out with no response from the WebProcess, don't block the UIProcess again until it starts responding.
+ if (m_waitingForDidUpdateActivityState)
+ return;
- if (!m_process->isLaunching()) {
- auto viewStateUpdateTimeout = std::chrono::milliseconds(250);
- m_process->connection()->waitForAndDispatchImmediately<Messages::WebPageProxy::DidUpdateViewState>(m_pageID, viewStateUpdateTimeout);
+#if PLATFORM(IOS)
+ // Hail Mary check. Should not be possible (dispatchActivityStateChange should force async if not visible,
+ // and if visible we should be holding an assertion) - but we should never block on a suspended process.
+ if (!m_activityToken) {
+ ASSERT_NOT_REACHED();
+ return;
}
+#endif
+
+ m_waitingForDidUpdateActivityState = true;
+
+ m_drawingArea->waitForDidUpdateActivityState();
}
IntSize WebPageProxy::viewSize() const
@@ -1013,36 +1694,39 @@ IntSize WebPageProxy::viewSize() const
return m_pageClient.viewSize();
}
-void WebPageProxy::setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent& keyboardEvent)
+void WebPageProxy::setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent& keyboardEvent, std::function<void (CallbackBase::Error)> callbackFunction)
{
- if (!isValid())
+ if (!isValid()) {
+ callbackFunction(CallbackBase::Error::OwnerWasInvalidated);
return;
- m_process->send(Messages::WebPage::SetInitialFocus(forward, isKeyboardEventValid, keyboardEvent), m_pageID);
+ }
+
+ uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
+ m_process->send(Messages::WebPage::SetInitialFocus(forward, isKeyboardEventValid, keyboardEvent, callbackID), m_pageID);
}
-void WebPageProxy::setWindowResizerSize(const IntSize& windowResizerSize)
+void WebPageProxy::clearSelection()
{
if (!isValid())
return;
- m_process->send(Messages::WebPage::SetWindowResizerSize(windowResizerSize), m_pageID);
+ m_process->send(Messages::WebPage::ClearSelection(), m_pageID);
}
-
-void WebPageProxy::clearSelection()
+
+void WebPageProxy::restoreSelectionInFocusedEditableElement()
{
if (!isValid())
return;
- m_process->send(Messages::WebPage::ClearSelection(), m_pageID);
+ m_process->send(Messages::WebPage::RestoreSelectionInFocusedEditableElement(), m_pageID);
}
-void WebPageProxy::validateCommand(const String& commandName, PassRefPtr<ValidateCommandCallback> callback)
+void WebPageProxy::validateCommand(const String& commandName, std::function<void (const String&, bool, int32_t, CallbackBase::Error)> callbackFunction)
{
if (!isValid()) {
- callback->invalidate();
+ callbackFunction(String(), false, 0, CallbackBase::Error::Unknown);
return;
}
- uint64_t callbackID = callback->callbackID();
- m_validateCommandCallbacks.set(callbackID, callback.get());
+ uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
m_process->send(Messages::WebPage::ValidateCommand(commandName, callbackID), m_pageID);
}
@@ -1051,7 +1735,7 @@ void WebPageProxy::setMaintainsInactiveSelection(bool newValue)
m_maintainsInactiveSelection = newValue;
}
-void WebPageProxy::executeEditCommand(const String& commandName)
+void WebPageProxy::executeEditCommand(const String& commandName, const String& argument)
{
static NeverDestroyed<String> ignoreSpellingCommandName(ASCIILiteral("ignoreSpelling"));
@@ -1061,16 +1745,27 @@ void WebPageProxy::executeEditCommand(const String& commandName)
if (commandName == ignoreSpellingCommandName)
++m_pendingLearnOrIgnoreWordMessageCount;
- m_process->send(Messages::WebPage::ExecuteEditCommand(commandName), m_pageID);
+ m_process->send(Messages::WebPage::ExecuteEditCommand(commandName, argument), m_pageID);
}
-
-#if USE(TILED_BACKING_STORE)
-void WebPageProxy::commitPageTransitionViewport()
+
+void WebPageProxy::setEditable(bool editable)
{
+ if (editable == m_isEditable)
+ return;
if (!isValid())
return;
- process().send(Messages::WebPage::CommitPageTransitionViewport(), m_pageID);
+ m_isEditable = editable;
+ m_process->send(Messages::WebPage::SetEditable(editable), m_pageID);
+}
+
+#if !PLATFORM(IOS)
+void WebPageProxy::didCommitLayerTree(const RemoteLayerTreeTransaction&)
+{
+}
+
+void WebPageProxy::layerTreeCommitComplete()
+{
}
#endif
@@ -1096,9 +1791,9 @@ void WebPageProxy::dragExited(DragData& dragData, const String& dragStorageName)
performDragControllerAction(DragControllerActionExited, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionHandleEmptyArray);
}
-void WebPageProxy::performDrag(DragData& dragData, const String& dragStorageName, const SandboxExtension::Handle& sandboxExtensionHandle, const SandboxExtension::HandleArray& sandboxExtensionsForUpload)
+void WebPageProxy::performDragOperation(DragData& dragData, const String& dragStorageName, const SandboxExtension::Handle& sandboxExtensionHandle, const SandboxExtension::HandleArray& sandboxExtensionsForUpload)
{
- performDragControllerAction(DragControllerActionPerformDrag, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionsForUpload);
+ performDragControllerAction(DragControllerActionPerformDragOperation, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionsForUpload);
}
void WebPageProxy::performDragControllerAction(DragControllerAction action, DragData& dragData, const String& dragStorageName, const SandboxExtension::Handle& sandboxExtensionHandle, const SandboxExtension::HandleArray& sandboxExtensionsForUpload)
@@ -1106,31 +1801,38 @@ void WebPageProxy::performDragControllerAction(DragControllerAction action, Drag
if (!isValid())
return;
#if PLATFORM(GTK)
- String url = dragData.asURL(nullptr);
+ UNUSED_PARAM(dragStorageName);
+ UNUSED_PARAM(sandboxExtensionHandle);
+ UNUSED_PARAM(sandboxExtensionsForUpload);
+
+ String url = dragData.asURL();
if (!url.isEmpty())
m_process->assumeReadAccessToBaseURL(url);
- m_process->send(Messages::WebPage::PerformDragControllerAction(action, dragData), m_pageID);
+
+ ASSERT(dragData.platformData());
+ WebSelectionData selection(*dragData.platformData());
+ m_process->send(Messages::WebPage::PerformDragControllerAction(action, dragData.clientPosition(), dragData.globalPosition(), dragData.draggingSourceOperationMask(), selection, dragData.flags()), m_pageID);
#else
- m_process->send(Messages::WebPage::PerformDragControllerAction(action, dragData.clientPosition(), dragData.globalPosition(), dragData.draggingSourceOperationMask(), dragStorageName, dragData.flags(), sandboxExtensionHandle, sandboxExtensionsForUpload), m_pageID);
+ m_process->send(Messages::WebPage::PerformDragControllerAction(action, dragData, sandboxExtensionHandle, sandboxExtensionsForUpload), m_pageID);
#endif
}
-void WebPageProxy::didPerformDragControllerAction(WebCore::DragSession dragSession)
+void WebPageProxy::didPerformDragControllerAction(uint64_t dragOperation, bool mouseIsOverFileInput, unsigned numberOfItemsToBeAccepted)
{
- m_currentDragSession = dragSession;
+ MESSAGE_CHECK(dragOperation <= DragOperationDelete);
+
+ m_currentDragOperation = static_cast<DragOperation>(dragOperation);
+ m_currentDragIsOverFileInput = mouseIsOverFileInput;
+ m_currentDragNumberOfFilesToBeAccepted = numberOfItemsToBeAccepted;
}
#if PLATFORM(GTK)
-void WebPageProxy::startDrag(const DragData& dragData, const ShareableBitmap::Handle& dragImageHandle)
+void WebPageProxy::startDrag(WebSelectionData&& selection, uint64_t dragOperation, const ShareableBitmap::Handle& dragImageHandle)
{
- RefPtr<ShareableBitmap> dragImage = 0;
- if (!dragImageHandle.isNull()) {
- dragImage = ShareableBitmap::create(dragImageHandle);
- if (!dragImage)
- return;
- }
+ RefPtr<ShareableBitmap> dragImage = !dragImageHandle.isNull() ? ShareableBitmap::create(dragImageHandle) : nullptr;
+ m_pageClient.startDrag(WTFMove(selection.selectionData), static_cast<WebCore::DragOperation>(dragOperation), WTFMove(dragImage));
- m_pageClient.startDrag(dragData, dragImage.release());
+ m_process->send(Messages::WebPage::DidStartDrag(), m_pageID);
}
#endif
@@ -1140,6 +1842,12 @@ void WebPageProxy::dragEnded(const IntPoint& clientPosition, const IntPoint& glo
return;
m_process->send(Messages::WebPage::DragEnded(clientPosition, globalPosition, operation), m_pageID);
}
+
+void WebPageProxy::dragCancelled()
+{
+ if (isValid())
+ m_process->send(Messages::WebPage::DragCancelled(), m_pageID);
+}
#endif // ENABLE(DRAG_SUPPORT)
void WebPageProxy::handleMouseEvent(const NativeWebMouseEvent& event)
@@ -1147,12 +1855,15 @@ void WebPageProxy::handleMouseEvent(const NativeWebMouseEvent& event)
if (!isValid())
return;
+ if (m_pageClient.windowIsFrontWindowUnderMouse(event))
+ setToolTip(String());
+
// NOTE: This does not start the responsiveness timer because mouse move should not indicate interaction.
if (event.type() != WebEvent::MouseMove)
- m_process->responsivenessTimer()->start();
+ m_process->responsivenessTimer().start();
else {
if (m_processingMouseMoveEvent) {
- m_nextMouseMoveEvent = adoptPtr(new NativeWebMouseEvent(event));
+ m_nextMouseMoveEvent = std::make_unique<NativeWebMouseEvent>(event);
return;
}
@@ -1164,14 +1875,9 @@ void WebPageProxy::handleMouseEvent(const NativeWebMouseEvent& event)
// we fake a mouse up event by using this stored down event. This event gets cleared
// when the mouse up message is received from WebProcess.
if (event.type() == WebEvent::MouseDown)
- m_currentlyProcessedMouseDownEvent = adoptPtr(new NativeWebMouseEvent(event));
+ m_currentlyProcessedMouseDownEvent = std::make_unique<NativeWebMouseEvent>(event);
- if (m_shouldSendEventsSynchronously) {
- bool handled = false;
- m_process->sendSync(Messages::WebPage::MouseEventSyncForTesting(event), Messages::WebPage::MouseEventSyncForTesting::Reply(handled), m_pageID);
- didReceiveEvent(event.type(), handled);
- } else
- m_process->send(Messages::WebPage::MouseEvent(event), m_pageID);
+ m_process->send(Messages::WebPage::MouseEvent(event), m_pageID);
}
#if MERGE_WHEEL_EVENTS
@@ -1185,7 +1891,7 @@ static bool canCoalesce(const WebWheelEvent& a, const WebWheelEvent& b)
return false;
if (a.granularity() != b.granularity())
return false;
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
if (a.phase() != b.phase())
return false;
if (a.momentumPhase() != b.momentumPhase())
@@ -1204,7 +1910,7 @@ static WebWheelEvent coalesce(const WebWheelEvent& a, const WebWheelEvent& b)
FloatSize mergedDelta = a.delta() + b.delta();
FloatSize mergedWheelTicks = a.wheelTicks() + b.wheelTicks();
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
FloatSize mergedUnacceleratedScrollingDelta = a.unacceleratedScrollingDelta() + b.unacceleratedScrollingDelta();
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());
@@ -1248,6 +1954,8 @@ void WebPageProxy::handleWheelEvent(const NativeWebWheelEvent& event)
if (!isValid())
return;
+ hideValidationMessage();
+
if (!m_currentlyProcessedWheelEvents.isEmpty()) {
m_wheelEventQueue.append(event);
if (m_wheelEventQueue.size() < wheelEventQueueSizeThreshold)
@@ -1260,40 +1968,35 @@ void WebPageProxy::handleWheelEvent(const NativeWebWheelEvent& event)
return;
}
- OwnPtr<Vector<NativeWebWheelEvent>> coalescedWheelEvent = adoptPtr(new Vector<NativeWebWheelEvent>);
+ auto coalescedWheelEvent = std::make_unique<Vector<NativeWebWheelEvent>>();
coalescedWheelEvent->append(event);
- m_currentlyProcessedWheelEvents.append(coalescedWheelEvent.release());
+ m_currentlyProcessedWheelEvents.append(WTFMove(coalescedWheelEvent));
sendWheelEvent(event);
}
void WebPageProxy::processNextQueuedWheelEvent()
{
- OwnPtr<Vector<NativeWebWheelEvent>> nextCoalescedEvent = adoptPtr(new Vector<NativeWebWheelEvent>);
+ auto nextCoalescedEvent = std::make_unique<Vector<NativeWebWheelEvent>>();
WebWheelEvent nextWheelEvent = coalescedWheelEvent(m_wheelEventQueue, *nextCoalescedEvent.get());
- m_currentlyProcessedWheelEvents.append(nextCoalescedEvent.release());
+ m_currentlyProcessedWheelEvents.append(WTFMove(nextCoalescedEvent));
sendWheelEvent(nextWheelEvent);
}
void WebPageProxy::sendWheelEvent(const WebWheelEvent& event)
{
- m_process->responsivenessTimer()->start();
-
- if (m_shouldSendEventsSynchronously) {
- bool handled = false;
- m_process->sendSync(Messages::WebPage::WheelEventSyncForTesting(event), Messages::WebPage::WheelEventSyncForTesting::Reply(handled), m_pageID);
- didReceiveEvent(event.type(), handled);
- return;
- }
-
m_process->send(
Messages::EventDispatcher::WheelEvent(
m_pageID,
event,
- m_useLegacyImplicitRubberBandControl ? !m_backForwardList->backItem() : rubberBandsAtLeft(),
- m_useLegacyImplicitRubberBandControl ? !m_backForwardList->forwardItem() : rubberBandsAtRight(),
+ shouldUseImplicitRubberBandControl() ? !m_backForwardList->backItem() : rubberBandsAtLeft(),
+ shouldUseImplicitRubberBandControl() ? !m_backForwardList->forwardItem() : rubberBandsAtRight(),
rubberBandsAtTop(),
rubberBandsAtBottom()
), 0);
+
+ // Manually ping the web process to check for responsiveness since our wheel
+ // event will dispatch to a non-main thread, which always responds.
+ m_process->isResponsive(nullptr);
}
void WebPageProxy::handleKeyboardEvent(const NativeWebKeyboardEvent& event)
@@ -1305,25 +2008,37 @@ void WebPageProxy::handleKeyboardEvent(const NativeWebKeyboardEvent& event)
m_keyEventQueue.append(event);
- m_process->responsivenessTimer()->start();
- if (m_shouldSendEventsSynchronously) {
- bool handled = false;
- m_process->sendSync(Messages::WebPage::KeyEventSyncForTesting(event), Messages::WebPage::KeyEventSyncForTesting::Reply(handled), m_pageID);
- didReceiveEvent(event.type(), handled);
- } else if (m_keyEventQueue.size() == 1) // Otherwise, sent from DidReceiveEvent message handler.
+ m_process->responsivenessTimer().start();
+ if (m_keyEventQueue.size() == 1) { // Otherwise, sent from DidReceiveEvent message handler.
+ LOG(KeyHandling, " UI process: sent keyEvent from handleKeyboardEvent");
m_process->send(Messages::WebPage::KeyEvent(event), m_pageID);
+ }
+}
+
+WebPreferencesStore WebPageProxy::preferencesStore() const
+{
+ if (m_configurationPreferenceValues.isEmpty())
+ return m_preferences->store();
+
+ WebPreferencesStore store = m_preferences->store();
+ for (const auto& preference : m_configurationPreferenceValues)
+ store.m_values.set(preference.key, preference.value);
+
+ return store;
}
#if ENABLE(NETSCAPE_PLUGIN_API)
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)
{
+ PageClientProtector protector(m_pageClient);
+
MESSAGE_CHECK_URL(urlString);
- newMimeType = mimeType.lower();
+ newMimeType = mimeType.convertToASCIILowercase();
pluginLoadPolicy = PluginModuleLoadNormally;
PluginData::AllowedPluginTypes allowedPluginTypes = allowOnlyApplicationPlugins ? PluginData::OnlyApplicationPlugins : PluginData::AllPlugins;
- PluginModuleInfo plugin = m_process->context().pluginInfoStore().findPlugin(newMimeType, URL(URL(), urlString), allowedPluginTypes);
+ PluginModuleInfo plugin = m_process->processPool().pluginInfoStore().findPlugin(newMimeType, URL(URL(), urlString), allowedPluginTypes);
if (!plugin.path) {
pluginProcessToken = 0;
return;
@@ -1331,9 +2046,12 @@ void WebPageProxy::findPlugin(const String& mimeType, uint32_t processType, cons
pluginLoadPolicy = PluginInfoStore::defaultLoadPolicyForPlugin(plugin);
-#if PLATFORM(MAC)
- RefPtr<ImmutableDictionary> pluginInformation = createPluginInformationDictionary(plugin, frameURLString, String(), pageURLString, String(), String());
- pluginLoadPolicy = m_loaderClient->pluginLoadPolicy(this, static_cast<PluginModuleLoadPolicy>(pluginLoadPolicy), pluginInformation.get(), unavailabilityDescription);
+#if PLATFORM(COCOA)
+ RefPtr<API::Dictionary> pluginInformation = createPluginInformationDictionary(plugin, frameURLString, String(), pageURLString, String(), String());
+ if (m_navigationClient)
+ pluginLoadPolicy = m_navigationClient->decidePolicyForPluginLoad(*this, static_cast<PluginModuleLoadPolicy>(pluginLoadPolicy), pluginInformation.get(), unavailabilityDescription);
+ else
+ pluginLoadPolicy = m_loaderClient->pluginLoadPolicy(*this, static_cast<PluginModuleLoadPolicy>(pluginLoadPolicy), pluginInformation.get(), unavailabilityDescription);
#else
UNUSED_PARAM(frameURLString);
UNUSED_PARAM(pageURLString);
@@ -1349,34 +2067,178 @@ void WebPageProxy::findPlugin(const String& mimeType, uint32_t processType, cons
pluginProcessSandboxPolicy = PluginProcessSandboxPolicyUnsandboxed;
break;
- case PluginModuleBlocked:
+ case PluginModuleBlockedForSecurity:
+ case PluginModuleBlockedForCompatibility:
pluginProcessToken = 0;
return;
}
- pluginProcessToken = PluginProcessManager::shared().pluginProcessToken(plugin, static_cast<PluginProcessType>(processType), pluginProcessSandboxPolicy);
+ pluginProcessToken = PluginProcessManager::singleton().pluginProcessToken(plugin, static_cast<PluginProcessType>(processType), pluginProcessSandboxPolicy);
}
#endif // ENABLE(NETSCAPE_PLUGIN_API)
#if ENABLE(TOUCH_EVENTS)
+
+static TrackingType mergeTrackingTypes(TrackingType a, TrackingType b)
+{
+ if (static_cast<uintptr_t>(b) > static_cast<uintptr_t>(a))
+ return b;
+ return a;
+}
+
+void WebPageProxy::updateTouchEventTracking(const WebTouchEvent& touchStartEvent)
+{
+#if ENABLE(ASYNC_SCROLLING)
+ const EventNames& names = eventNames();
+ for (auto& touchPoint : touchStartEvent.touchPoints()) {
+ IntPoint location = touchPoint.location();
+ auto updateTrackingType = [this, location](TrackingType& trackingType, const AtomicString& eventName) {
+ if (trackingType == TrackingType::Synchronous)
+ return;
+
+ TrackingType trackingTypeForLocation = m_scrollingCoordinatorProxy->eventTrackingTypeForPoint(eventName, location);
+
+ trackingType = mergeTrackingTypes(trackingType, trackingTypeForLocation);
+ };
+ updateTrackingType(m_touchEventTracking.touchForceChangedTracking, names.touchforcechangeEvent);
+ updateTrackingType(m_touchEventTracking.touchStartTracking, names.touchstartEvent);
+ updateTrackingType(m_touchEventTracking.touchMoveTracking, names.touchmoveEvent);
+ updateTrackingType(m_touchEventTracking.touchEndTracking, names.touchendEvent);
+ }
+#else
+ UNUSED_PARAM(touchStartEvent);
+ m_touchEventTracking.touchForceChangedTracking = TrackingType::Synchronous;
+ m_touchEventTracking.touchStartTracking = TrackingType::Synchronous;
+ m_touchEventTracking.touchMoveTracking = TrackingType::Synchronous;
+ m_touchEventTracking.touchEndTracking = TrackingType::Synchronous;
+#endif // ENABLE(ASYNC_SCROLLING)
+}
+
+TrackingType WebPageProxy::touchEventTrackingType(const WebTouchEvent& touchStartEvent) const
+{
+ // We send all events if any type is needed, we just do it asynchronously for the types that are not tracked.
+ //
+ // Touch events define a sequence with strong dependencies. For example, we can expect
+ // a TouchMove to only appear after a TouchStart, and the ids of the touch points is consistent between
+ // the two.
+ //
+ // WebCore should not have to set up its state correctly after some events were dismissed.
+ // For example, we don't want to send a TouchMoved without a TouchPressed.
+ // We send everything, WebCore updates its internal state and dispatch what is needed to the page.
+ TrackingType globalTrackingType = m_touchEventTracking.isTrackingAnything() ? TrackingType::Asynchronous : TrackingType::NotTracking;
+
+ globalTrackingType = mergeTrackingTypes(globalTrackingType, m_touchEventTracking.touchForceChangedTracking);
+ for (auto& touchPoint : touchStartEvent.touchPoints()) {
+ switch (touchPoint.state()) {
+ case WebPlatformTouchPoint::TouchReleased:
+ globalTrackingType = mergeTrackingTypes(globalTrackingType, m_touchEventTracking.touchEndTracking);
+ break;
+ case WebPlatformTouchPoint::TouchPressed:
+ globalTrackingType = mergeTrackingTypes(globalTrackingType, m_touchEventTracking.touchStartTracking);
+ break;
+ case WebPlatformTouchPoint::TouchMoved:
+ case WebPlatformTouchPoint::TouchStationary:
+ globalTrackingType = mergeTrackingTypes(globalTrackingType, m_touchEventTracking.touchMoveTracking);
+ break;
+ case WebPlatformTouchPoint::TouchCancelled:
+ globalTrackingType = mergeTrackingTypes(globalTrackingType, TrackingType::Asynchronous);
+ break;
+ }
+ }
+
+ return globalTrackingType;
+}
+
+#endif
+
+#if ENABLE(MAC_GESTURE_EVENTS)
+void WebPageProxy::handleGestureEvent(const NativeWebGestureEvent& event)
+{
+ if (!isValid())
+ return;
+
+ m_gestureEventQueue.append(event);
+ // FIXME: Consider doing some coalescing here.
+ m_process->responsivenessTimer().start();
+
+ m_process->send(Messages::EventDispatcher::GestureEvent(m_pageID, event), 0);
+}
+#endif
+
+#if ENABLE(IOS_TOUCH_EVENTS)
+void WebPageProxy::handleTouchEventSynchronously(NativeWebTouchEvent& event)
+{
+ if (!isValid())
+ return;
+
+ if (event.type() == WebEvent::TouchStart) {
+ updateTouchEventTracking(event);
+ m_layerTreeTransactionIdAtLastTouchStart = downcast<RemoteLayerTreeDrawingAreaProxy>(*drawingArea()).lastCommittedLayerTreeTransactionID();
+ }
+
+ TrackingType touchEventsTrackingType = touchEventTrackingType(event);
+ if (touchEventsTrackingType == TrackingType::NotTracking)
+ return;
+
+ if (touchEventsTrackingType == TrackingType::Asynchronous) {
+ // We can end up here if a native gesture has not started but the event handlers are passive.
+ //
+ // The client of WebPageProxy asks the event to be sent synchronously since the touch event
+ // can prevent a native gesture.
+ // But, here we know that all events handlers that can handle this events are passive.
+ // We can use asynchronous dispatch and pretend to the client that the page does nothing with the events.
+ event.setCanPreventNativeGestures(false);
+ handleTouchEventAsynchronously(event);
+ didReceiveEvent(event.type(), false);
+ return;
+ }
+
+ m_process->responsivenessTimer().start();
+ bool handled = false;
+ m_process->sendSync(Messages::WebPage::TouchEventSync(event), Messages::WebPage::TouchEventSync::Reply(handled), m_pageID);
+ didReceiveEvent(event.type(), handled);
+ m_pageClient.doneWithTouchEvent(event, handled);
+ m_process->responsivenessTimer().stop();
+
+ if (event.allTouchPointsAreReleased())
+ m_touchEventTracking.reset();
+}
+
+void WebPageProxy::handleTouchEventAsynchronously(const NativeWebTouchEvent& event)
+{
+ if (!isValid())
+ return;
+
+ TrackingType touchEventsTrackingType = touchEventTrackingType(event);
+ if (touchEventsTrackingType == TrackingType::NotTracking)
+ return;
+
+ m_process->send(Messages::EventDispatcher::TouchEvent(m_pageID, event), 0);
+
+ if (event.allTouchPointsAreReleased())
+ m_touchEventTracking.reset();
+}
+
+#elif ENABLE(TOUCH_EVENTS)
void WebPageProxy::handleTouchEvent(const NativeWebTouchEvent& event)
{
if (!isValid())
return;
+ if (event.type() == WebEvent::TouchStart)
+ updateTouchEventTracking(event);
+
+ if (touchEventTrackingType(event) == TrackingType::NotTracking)
+ return;
+
// If the page is suspended, which should be the case during panning, pinching
// and animation on the page itself (kinetic scrolling, tap to zoom) etc, then
// we do not send any of the events to the page even if is has listeners.
- if (m_needTouchEvents && !m_isPageSuspended) {
+ if (!m_isPageSuspended) {
m_touchEventQueue.append(event);
- m_process->responsivenessTimer()->start();
- if (m_shouldSendEventsSynchronously) {
- bool handled = false;
- m_process->sendSync(Messages::WebPage::TouchEventSyncForTesting(event), Messages::WebPage::TouchEventSyncForTesting::Reply(handled), m_pageID);
- didReceiveEvent(event.type(), handled);
- } else
- m_process->send(Messages::WebPage::TouchEvent(event), m_pageID);
+ m_process->responsivenessTimer().start();
+ m_process->send(Messages::WebPage::TouchEvent(event), m_pageID);
} else {
if (m_touchEventQueue.isEmpty()) {
bool isEventHandled = false;
@@ -1388,8 +2250,11 @@ void WebPageProxy::handleTouchEvent(const NativeWebTouchEvent& event)
lastEvent.deferredTouchEvents.append(event);
}
}
+
+ if (event.allTouchPointsAreReleased())
+ m_touchEventTracking.reset();
}
-#endif
+#endif // ENABLE(TOUCH_EVENTS)
void WebPageProxy::scrollBy(ScrollDirection direction, ScrollGranularity granularity)
{
@@ -1407,7 +2272,7 @@ void WebPageProxy::centerSelectionInVisibleArea()
m_process->send(Messages::WebPage::CenterSelectionInVisibleArea(), m_pageID);
}
-void WebPageProxy::receivedPolicyDecision(PolicyAction action, WebFrameProxy* frame, uint64_t listenerID)
+void WebPageProxy::receivedPolicyDecision(PolicyAction action, WebFrameProxy& frame, uint64_t listenerID, API::Navigation* navigation, const WebsitePolicies& websitePolicies)
{
if (!isValid())
return;
@@ -1417,15 +2282,19 @@ void WebPageProxy::receivedPolicyDecision(PolicyAction action, WebFrameProxy* fr
if (action == PolicyIgnore)
m_pageLoadState.clearPendingAPIRequestURL(transaction);
- uint64_t downloadID = 0;
+#if ENABLE(DOWNLOAD_ATTRIBUTE)
+ if (m_syncNavigationActionHasDownloadAttribute && action == PolicyUse)
+ action = PolicyDownload;
+#endif
+
+ DownloadID downloadID = { };
if (action == PolicyDownload) {
// Create a download proxy.
- DownloadProxy* download = m_process->context().createDownloadProxy();
+ // FIXME: We should ensure that the downloadRequest is never empty.
+ const ResourceRequest& downloadRequest = m_decidePolicyForResponseRequest ? *m_decidePolicyForResponseRequest : ResourceRequest();
+ DownloadProxy* download = m_process->processPool().createDownloadProxy(downloadRequest);
downloadID = download->downloadID();
-#if PLATFORM(EFL) || PLATFORM(GTK)
- // Our design does not suppport downloads without a WebPage.
handleDownloadRequest(download);
-#endif
}
// If we received a policy decision while in decidePolicyForResponse the decision will
@@ -1443,10 +2312,11 @@ void WebPageProxy::receivedPolicyDecision(PolicyAction action, WebFrameProxy* fr
m_syncNavigationActionPolicyActionIsValid = true;
m_syncNavigationActionPolicyAction = action;
m_syncNavigationActionPolicyDownloadID = downloadID;
+ m_syncNavigationActionPolicyWebsitePolicies = websitePolicies;
return;
}
- m_process->send(Messages::WebPage::DidReceivePolicyDecision(frame->frameID(), listenerID, action, downloadID), m_pageID);
+ m_process->send(Messages::WebPage::DidReceivePolicyDecision(frame.frameID(), listenerID, action, navigation ? navigation->navigationID() : 0, downloadID), m_pageID);
}
void WebPageProxy::setUserAgent(const String& userAgent)
@@ -1524,7 +2394,7 @@ void WebPageProxy::setCustomTextEncodingName(const String& encodingName)
m_process->send(Messages::WebPage::SetCustomTextEncodingName(encodingName), m_pageID);
}
-void WebPageProxy::terminateProcess()
+void WebPageProxy::terminateProcess(TerminationReason terminationReason)
{
// NOTE: This uses a check of m_isValid rather than calling isValid() since
// we want this to run even for pages being closed or that already closed.
@@ -1533,20 +2403,68 @@ void WebPageProxy::terminateProcess()
m_process->requestTermination();
resetStateAfterProcessExited();
+ m_wasKilledForBeingUnresponsiveWhileInBackground = terminationReason == TerminationReason::UnresponsiveWhileInBackground;
}
-#if !USE(CF)
-PassRefPtr<API::Data> WebPageProxy::sessionStateData(WebPageProxySessionStateFilterCallback, void* /*context*/) const
+SessionState WebPageProxy::sessionState(const std::function<bool (WebBackForwardListItem&)>& filter) const
{
- // FIXME: Return session state data for saving Page state.
- return 0;
+ SessionState sessionState;
+
+ sessionState.backForwardListState = m_backForwardList->backForwardListState(filter);
+
+ String provisionalURLString = m_pageLoadState.pendingAPIRequestURL();
+ if (provisionalURLString.isEmpty())
+ provisionalURLString = m_pageLoadState.provisionalURL();
+
+ if (!provisionalURLString.isEmpty())
+ sessionState.provisionalURL = URL(URL(), provisionalURLString);
+
+ sessionState.renderTreeSize = renderTreeSize();
+ return sessionState;
}
-void WebPageProxy::restoreFromSessionStateData(API::Data*)
+RefPtr<API::Navigation> WebPageProxy::restoreFromSessionState(SessionState sessionState, bool navigate)
{
- // FIXME: Restore the Page from the passed in session state data.
+ m_sessionRestorationRenderTreeSize = 0;
+ m_hitRenderTreeSizeThreshold = false;
+
+ bool hasBackForwardList = !!sessionState.backForwardListState.currentIndex;
+
+ if (hasBackForwardList) {
+ m_backForwardList->restoreFromState(WTFMove(sessionState.backForwardListState));
+
+ for (const auto& entry : m_backForwardList->entries())
+ process().registerNewWebBackForwardListItem(entry.get());
+
+ process().send(Messages::WebPage::RestoreSession(m_backForwardList->itemStates()), m_pageID);
+
+ auto transaction = m_pageLoadState.transaction();
+ m_pageLoadState.setCanGoBack(transaction, m_backForwardList->backItem());
+ m_pageLoadState.setCanGoForward(transaction, m_backForwardList->forwardItem());
+
+ // The back / forward list was restored from a sessionState so we don't want to snapshot the current
+ // page when navigating away. Suppress navigation snapshotting until the next load has committed
+ m_suppressAutomaticNavigationSnapshotting = true;
+ }
+
+ // FIXME: Navigating should be separate from state restoration.
+ if (navigate) {
+ m_sessionRestorationRenderTreeSize = sessionState.renderTreeSize;
+ if (!m_sessionRestorationRenderTreeSize)
+ m_hitRenderTreeSizeThreshold = true; // If we didn't get data on renderTreeSize, just don't fire the milestone.
+
+ if (!sessionState.provisionalURL.isNull())
+ return loadRequest(sessionState.provisionalURL);
+
+ if (hasBackForwardList) {
+ // FIXME: Do we have to null check the back forward list item here?
+ if (WebBackForwardListItem* item = m_backForwardList->currentItem())
+ return goToBackForwardItem(item);
+ }
+ }
+
+ return nullptr;
}
-#endif
bool WebPageProxy::supportsTextZoom() const
{
@@ -1577,6 +2495,8 @@ void WebPageProxy::setPageZoomFactor(double zoomFactor)
if (m_pageZoomFactor == zoomFactor)
return;
+ hideValidationMessage();
+
m_pageZoomFactor = zoomFactor;
m_process->send(Messages::WebPage::SetPageZoomFactor(m_pageZoomFactor), m_pageID);
}
@@ -1589,13 +2509,35 @@ void WebPageProxy::setPageAndTextZoomFactors(double pageZoomFactor, double textZ
if (m_pageZoomFactor == pageZoomFactor && m_textZoomFactor == textZoomFactor)
return;
+ hideValidationMessage();
+
m_pageZoomFactor = pageZoomFactor;
m_textZoomFactor = textZoomFactor;
m_process->send(Messages::WebPage::SetPageAndTextZoomFactors(m_pageZoomFactor, m_textZoomFactor), m_pageID);
}
+double WebPageProxy::pageZoomFactor() const
+{
+ // Zoom factor for non-PDF pages persists across page loads. We maintain a separate member variable for PDF
+ // zoom which ensures that we don't use the PDF zoom for a normal page.
+ if (m_mainFramePluginHandlesPageScaleGesture)
+ return m_pluginZoomFactor;
+ return m_pageZoomFactor;
+}
+
+double WebPageProxy::pageScaleFactor() const
+{
+ // PDF documents use zoom and scale factors to size themselves appropriately in the window. We store them
+ // separately but decide which to return based on the main frame.
+ if (m_mainFramePluginHandlesPageScaleGesture)
+ return m_pluginScaleFactor;
+ return m_pageScaleFactor;
+}
+
void WebPageProxy::scalePage(double scale, const IntPoint& origin)
{
+ ASSERT(scale > 0);
+
if (!isValid())
return;
@@ -1603,6 +2545,28 @@ void WebPageProxy::scalePage(double scale, const IntPoint& origin)
m_process->send(Messages::WebPage::ScalePage(scale, origin), m_pageID);
}
+void WebPageProxy::scalePageInViewCoordinates(double scale, const IntPoint& centerInViewCoordinates)
+{
+ ASSERT(scale > 0);
+
+ if (!isValid())
+ return;
+
+ m_pageScaleFactor = scale;
+ m_process->send(Messages::WebPage::ScalePageInViewCoordinates(scale, centerInViewCoordinates), m_pageID);
+}
+
+void WebPageProxy::scaleView(double scale)
+{
+ ASSERT(scale > 0);
+
+ if (!isValid())
+ return;
+
+ m_viewScaleFactor = scale;
+ m_process->send(Messages::WebPage::ScaleView(scale), m_pageID);
+}
+
void WebPageProxy::setIntrinsicDeviceScaleFactor(float scaleFactor)
{
if (m_intrinsicDeviceScaleFactor == scaleFactor)
@@ -1651,6 +2615,14 @@ void WebPageProxy::setCustomDeviceScaleFactor(float customScaleFactor)
m_drawingArea->deviceScaleFactorDidChange();
}
+void WebPageProxy::accessibilitySettingsDidChange()
+{
+ if (!isValid())
+ return;
+
+ m_process->send(Messages::WebPage::AccessibilitySettingsDidChange(), m_pageID);
+}
+
void WebPageProxy::setUseFixedLayout(bool fixed)
{
if (!isValid())
@@ -1683,17 +2655,14 @@ void WebPageProxy::listenForLayoutMilestones(WebCore::LayoutMilestones milestone
{
if (!isValid())
return;
+
+ if (milestones == m_observedLayoutMilestones)
+ return;
+ m_observedLayoutMilestones = milestones;
m_process->send(Messages::WebPage::ListenForLayoutMilestones(milestones), m_pageID);
}
-void WebPageProxy::setVisibilityStatePrerender()
-{
- if (!isValid())
- return;
- m_process->send(Messages::WebPage::SetVisibilityStatePrerender(), m_pageID);
-}
-
void WebPageProxy::setSuppressScrollbarAnimations(bool suppressAnimations)
{
if (!isValid())
@@ -1745,6 +2714,40 @@ void WebPageProxy::setRubberBandsAtBottom(bool rubberBandsAtBottom)
{
m_rubberBandsAtBottom = rubberBandsAtBottom;
}
+
+void WebPageProxy::setEnableVerticalRubberBanding(bool enableVerticalRubberBanding)
+{
+ if (enableVerticalRubberBanding == m_enableVerticalRubberBanding)
+ return;
+
+ m_enableVerticalRubberBanding = enableVerticalRubberBanding;
+
+ if (!isValid())
+ return;
+ m_process->send(Messages::WebPage::SetEnableVerticalRubberBanding(enableVerticalRubberBanding), m_pageID);
+}
+
+bool WebPageProxy::verticalRubberBandingIsEnabled() const
+{
+ return m_enableVerticalRubberBanding;
+}
+
+void WebPageProxy::setEnableHorizontalRubberBanding(bool enableHorizontalRubberBanding)
+{
+ if (enableHorizontalRubberBanding == m_enableHorizontalRubberBanding)
+ return;
+
+ m_enableHorizontalRubberBanding = enableHorizontalRubberBanding;
+
+ if (!isValid())
+ return;
+ m_process->send(Messages::WebPage::SetEnableHorizontalRubberBanding(enableHorizontalRubberBanding), m_pageID);
+}
+
+bool WebPageProxy::horizontalRubberBandingIsEnabled() const
+{
+ return m_enableHorizontalRubberBanding;
+}
void WebPageProxy::setBackgroundExtendsBeyondPage(bool backgroundExtendsBeyondPage)
{
@@ -1811,26 +2814,31 @@ void WebPageProxy::setGapBetweenPages(double gap)
m_process->send(Messages::WebPage::SetGapBetweenPages(gap), m_pageID);
}
+void WebPageProxy::setPaginationLineGridEnabled(bool lineGridEnabled)
+{
+ if (lineGridEnabled == m_paginationLineGridEnabled)
+ return;
+
+ m_paginationLineGridEnabled = lineGridEnabled;
+
+ if (!isValid())
+ return;
+ m_process->send(Messages::WebPage::SetPaginationLineGridEnabled(lineGridEnabled), m_pageID);
+}
+
void WebPageProxy::pageScaleFactorDidChange(double scaleFactor)
{
m_pageScaleFactor = scaleFactor;
}
-void WebPageProxy::pageZoomFactorDidChange(double zoomFactor)
+void WebPageProxy::pluginScaleFactorDidChange(double pluginScaleFactor)
{
- m_pageZoomFactor = zoomFactor;
+ m_pluginScaleFactor = pluginScaleFactor;
}
-void WebPageProxy::setMemoryCacheClientCallsEnabled(bool memoryCacheClientCallsEnabled)
+void WebPageProxy::pluginZoomFactorDidChange(double pluginZoomFactor)
{
- if (!isValid())
- return;
-
- if (m_areMemoryCacheClientCallsEnabled == memoryCacheClientCallsEnabled)
- return;
-
- m_areMemoryCacheClientCallsEnabled = memoryCacheClientCallsEnabled;
- m_process->send(Messages::WebPage::SetMemoryCacheMessagesEnabled(memoryCacheClientCallsEnabled), m_pageID);
+ m_pluginZoomFactor = pluginZoomFactor;
}
void WebPageProxy::findStringMatches(const String& string, FindOptions options, unsigned maxMatchCount)
@@ -1871,137 +2879,154 @@ void WebPageProxy::countStringMatches(const String& string, FindOptions options,
m_process->send(Messages::WebPage::CountStringMatches(string, options, maxMatchCount), m_pageID);
}
-void WebPageProxy::runJavaScriptInMainFrame(const String& script, PassRefPtr<ScriptValueCallback> prpCallback)
+void WebPageProxy::runJavaScriptInMainFrame(const String& script, std::function<void (API::SerializedScriptValue*, bool hadException, const ExceptionDetails&, CallbackBase::Error)> callbackFunction)
{
- RefPtr<ScriptValueCallback> callback = prpCallback;
if (!isValid()) {
- callback->invalidate();
+ callbackFunction(nullptr, false, { }, CallbackBase::Error::Unknown);
return;
}
- uint64_t callbackID = callback->callbackID();
- m_scriptValueCallbacks.set(callbackID, callback.get());
+ uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
m_process->send(Messages::WebPage::RunJavaScriptInMainFrame(script, callbackID), m_pageID);
}
-void WebPageProxy::getRenderTreeExternalRepresentation(PassRefPtr<StringCallback> prpCallback)
+void WebPageProxy::getRenderTreeExternalRepresentation(std::function<void (const String&, CallbackBase::Error)> callbackFunction)
{
- RefPtr<StringCallback> callback = prpCallback;
if (!isValid()) {
- callback->invalidate();
+ callbackFunction(String(), CallbackBase::Error::Unknown);
return;
}
- uint64_t callbackID = callback->callbackID();
- m_stringCallbacks.set(callbackID, callback.get());
+ uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
m_process->send(Messages::WebPage::GetRenderTreeExternalRepresentation(callbackID), m_pageID);
}
-void WebPageProxy::getSourceForFrame(WebFrameProxy* frame, PassRefPtr<StringCallback> prpCallback)
+void WebPageProxy::getSourceForFrame(WebFrameProxy* frame, std::function<void (const String&, CallbackBase::Error)> callbackFunction)
{
- RefPtr<StringCallback> callback = prpCallback;
if (!isValid()) {
- callback->invalidate();
+ callbackFunction(String(), CallbackBase::Error::Unknown);
return;
}
- uint64_t callbackID = callback->callbackID();
+ uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
m_loadDependentStringCallbackIDs.add(callbackID);
- m_stringCallbacks.set(callbackID, callback.get());
m_process->send(Messages::WebPage::GetSourceForFrame(frame->frameID(), callbackID), m_pageID);
}
-void WebPageProxy::getContentsAsString(PassRefPtr<StringCallback> prpCallback)
+void WebPageProxy::getContentsAsString(std::function<void (const String&, CallbackBase::Error)> callbackFunction)
{
- RefPtr<StringCallback> callback = prpCallback;
if (!isValid()) {
- callback->invalidate();
+ callbackFunction(String(), CallbackBase::Error::Unknown);
return;
}
- uint64_t callbackID = callback->callbackID();
+ uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
m_loadDependentStringCallbackIDs.add(callbackID);
- m_stringCallbacks.set(callbackID, callback.get());
m_process->send(Messages::WebPage::GetContentsAsString(callbackID), m_pageID);
}
+void WebPageProxy::getBytecodeProfile(std::function<void (const String&, CallbackBase::Error)> callbackFunction)
+{
+ if (!isValid()) {
+ callbackFunction(String(), CallbackBase::Error::Unknown);
+ return;
+ }
+
+ uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
+ m_loadDependentStringCallbackIDs.add(callbackID);
+ m_process->send(Messages::WebPage::GetBytecodeProfile(callbackID), m_pageID);
+}
+
+void WebPageProxy::getSamplingProfilerOutput(std::function<void (const String&, CallbackBase::Error)> callbackFunction)
+{
+ if (!isValid()) {
+ callbackFunction(String(), CallbackBase::Error::Unknown);
+ return;
+ }
+
+ uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
+ m_loadDependentStringCallbackIDs.add(callbackID);
+ m_process->send(Messages::WebPage::GetSamplingProfilerOutput(callbackID), m_pageID);
+}
+
+void WebPageProxy::isWebProcessResponsive(std::function<void (bool isWebProcessResponsive)> callbackFunction)
+{
+ if (!isValid()) {
+ RunLoop::main().dispatch([callbackFunction = WTFMove(callbackFunction)] {
+ bool isWebProcessResponsive = true;
+ callbackFunction(isWebProcessResponsive);
+ });
+ return;
+ }
+
+ m_process->isResponsive(callbackFunction);
+}
+
#if ENABLE(MHTML)
-void WebPageProxy::getContentsAsMHTMLData(PassRefPtr<DataCallback> prpCallback, bool useBinaryEncoding)
+void WebPageProxy::getContentsAsMHTMLData(std::function<void (API::Data*, CallbackBase::Error)> callbackFunction)
{
- RefPtr<DataCallback> callback = prpCallback;
if (!isValid()) {
- callback->invalidate();
+ callbackFunction(nullptr, CallbackBase::Error::Unknown);
return;
}
- uint64_t callbackID = callback->callbackID();
- m_dataCallbacks.set(callbackID, callback.get());
- m_process->send(Messages::WebPage::GetContentsAsMHTMLData(callbackID, useBinaryEncoding), m_pageID);
+ uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
+ m_process->send(Messages::WebPage::GetContentsAsMHTMLData(callbackID), m_pageID);
}
#endif
-void WebPageProxy::getSelectionOrContentsAsString(PassRefPtr<StringCallback> prpCallback)
+void WebPageProxy::getSelectionOrContentsAsString(std::function<void (const String&, CallbackBase::Error)> callbackFunction)
{
- RefPtr<StringCallback> callback = prpCallback;
if (!isValid()) {
- callback->invalidate();
+ callbackFunction(String(), CallbackBase::Error::Unknown);
return;
}
- uint64_t callbackID = callback->callbackID();
- m_stringCallbacks.set(callbackID, callback.get());
+ uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
m_process->send(Messages::WebPage::GetSelectionOrContentsAsString(callbackID), m_pageID);
}
-void WebPageProxy::getSelectionAsWebArchiveData(PassRefPtr<DataCallback> prpCallback)
+void WebPageProxy::getSelectionAsWebArchiveData(std::function<void (API::Data*, CallbackBase::Error)> callbackFunction)
{
- RefPtr<DataCallback> callback = prpCallback;
if (!isValid()) {
- callback->invalidate();
+ callbackFunction(nullptr, CallbackBase::Error::Unknown);
return;
}
- uint64_t callbackID = callback->callbackID();
- m_dataCallbacks.set(callbackID, callback.get());
+ uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
m_process->send(Messages::WebPage::GetSelectionAsWebArchiveData(callbackID), m_pageID);
}
-void WebPageProxy::getMainResourceDataOfFrame(WebFrameProxy* frame, PassRefPtr<DataCallback> prpCallback)
+void WebPageProxy::getMainResourceDataOfFrame(WebFrameProxy* frame, std::function<void (API::Data*, CallbackBase::Error)> callbackFunction)
{
- RefPtr<DataCallback> callback = prpCallback;
- if (!isValid()) {
- callback->invalidate();
+ if (!isValid() || !frame) {
+ callbackFunction(nullptr, CallbackBase::Error::Unknown);
return;
}
- uint64_t callbackID = callback->callbackID();
- m_dataCallbacks.set(callbackID, callback.get());
+ uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
m_process->send(Messages::WebPage::GetMainResourceDataOfFrame(frame->frameID(), callbackID), m_pageID);
}
-void WebPageProxy::getResourceDataFromFrame(WebFrameProxy* frame, API::URL* resourceURL, PassRefPtr<DataCallback> prpCallback)
+void WebPageProxy::getResourceDataFromFrame(WebFrameProxy* frame, API::URL* resourceURL, std::function<void (API::Data*, CallbackBase::Error)> callbackFunction)
{
- RefPtr<DataCallback> callback = prpCallback;
if (!isValid()) {
- callback->invalidate();
+ callbackFunction(nullptr, CallbackBase::Error::Unknown);
return;
}
- uint64_t callbackID = callback->callbackID();
- m_dataCallbacks.set(callbackID, callback.get());
+ uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
m_process->send(Messages::WebPage::GetResourceDataFromFrame(frame->frameID(), resourceURL->string(), callbackID), m_pageID);
}
-void WebPageProxy::getWebArchiveOfFrame(WebFrameProxy* frame, PassRefPtr<DataCallback> prpCallback)
+void WebPageProxy::getWebArchiveOfFrame(WebFrameProxy* frame, std::function<void (API::Data*, CallbackBase::Error)> callbackFunction)
{
- RefPtr<DataCallback> callback = prpCallback;
if (!isValid()) {
- callback->invalidate();
+ callbackFunction(nullptr, CallbackBase::Error::Unknown);
return;
}
- uint64_t callbackID = callback->callbackID();
- m_dataCallbacks.set(callbackID, callback.get());
+ uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
m_process->send(Messages::WebPage::GetWebArchiveOfFrame(frame->frameID(), callbackID), m_pageID);
}
@@ -2009,27 +3034,57 @@ void WebPageProxy::forceRepaint(PassRefPtr<VoidCallback> prpCallback)
{
RefPtr<VoidCallback> callback = prpCallback;
if (!isValid()) {
- callback->invalidate();
+ // FIXME: If the page is invalid we should not call the callback. It'd be better to just return false from forceRepaint.
+ callback->invalidate(CallbackBase::Error::OwnerWasInvalidated);
return;
}
- uint64_t callbackID = callback->callbackID();
- m_voidCallbacks.set(callbackID, callback.get());
+ std::function<void (CallbackBase::Error)> didForceRepaintCallback = [this, callback](CallbackBase::Error error) {
+ if (error != CallbackBase::Error::None) {
+ callback->invalidate(error);
+ return;
+ }
+
+ if (!isValid()) {
+ callback->invalidate(CallbackBase::Error::OwnerWasInvalidated);
+ return;
+ }
+
+ callAfterNextPresentationUpdate([callback](CallbackBase::Error error) {
+ if (error != CallbackBase::Error::None) {
+ callback->invalidate(error);
+ return;
+ }
+
+ callback->performCallback();
+ });
+ };
+
+ uint64_t callbackID = m_callbacks.put(didForceRepaintCallback, m_process->throttler().backgroundActivityToken());
m_drawingArea->waitForBackingStoreUpdateOnNextPaint();
m_process->send(Messages::WebPage::ForceRepaint(callbackID), m_pageID);
}
+static OptionSet<IPC::SendOption> printingSendOptions(bool isPerformingDOMPrintOperation)
+{
+ if (isPerformingDOMPrintOperation)
+ return IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply;
+
+ return { };
+}
+
void WebPageProxy::preferencesDidChange()
{
if (!isValid())
return;
#if ENABLE(INSPECTOR_SERVER)
- if (m_pageGroup->preferences()->developerExtrasEnabled())
+ if (m_preferences->developerExtrasEnabled())
inspector()->enableRemoteInspection();
#endif
- m_process->pagePreferencesChanged(this);
+ updateThrottleState();
+ updateHiddenPageThrottlingAutoIncreases();
m_pageClient.preferencesDidChange();
@@ -2038,11 +3093,13 @@ void WebPageProxy::preferencesDidChange()
// even if nothing changed in UI process, so that overrides get removed.
// Preferences need to be updated during synchronous printing to make "print backgrounds" preference work when toggled from a print dialog checkbox.
- m_process->send(Messages::WebPage::PreferencesDidChange(pageGroup().preferences()->store()), m_pageID, m_isPerformingDOMPrintOperation ? IPC::DispatchMessageEvenWhenWaitingForSyncReply : 0);
+ m_process->send(Messages::WebPage::PreferencesDidChange(preferencesStore()), m_pageID, printingSendOptions(m_isPerformingDOMPrintOperation));
}
void WebPageProxy::didCreateMainFrame(uint64_t frameID)
{
+ PageClientProtector protector(m_pageClient);
+
MESSAGE_CHECK(!m_mainFrame);
MESSAGE_CHECK(m_process->canCreateFrame(frameID));
@@ -2054,6 +3111,8 @@ void WebPageProxy::didCreateMainFrame(uint64_t frameID)
void WebPageProxy::didCreateSubframe(uint64_t frameID)
{
+ PageClientProtector protector(m_pageClient);
+
MESSAGE_CHECK(m_mainFrame);
MESSAGE_CHECK(m_process->canCreateFrame(frameID));
@@ -2070,69 +3129,103 @@ double WebPageProxy::estimatedProgress() const
void WebPageProxy::didStartProgress()
{
+ PageClientProtector protector(m_pageClient);
+
auto transaction = m_pageLoadState.transaction();
m_pageLoadState.didStartProgress(transaction);
m_pageLoadState.commitChanges();
- m_loaderClient->didStartProgress(this);
+ m_loaderClient->didStartProgress(*this);
}
void WebPageProxy::didChangeProgress(double value)
{
+ PageClientProtector protector(m_pageClient);
+
auto transaction = m_pageLoadState.transaction();
m_pageLoadState.didChangeProgress(transaction, value);
m_pageLoadState.commitChanges();
- m_loaderClient->didChangeProgress(this);
+ m_loaderClient->didChangeProgress(*this);
}
void WebPageProxy::didFinishProgress()
{
+ PageClientProtector protector(m_pageClient);
+
auto transaction = m_pageLoadState.transaction();
m_pageLoadState.didFinishProgress(transaction);
m_pageLoadState.commitChanges();
- m_loaderClient->didFinishProgress(this);
+ m_loaderClient->didFinishProgress(*this);
}
-void WebPageProxy::didStartProvisionalLoadForFrame(uint64_t frameID, const String& url, const String& unreachableURL, IPC::MessageDecoder& decoder)
+void WebPageProxy::setNetworkRequestsInProgress(bool networkRequestsInProgress)
{
auto transaction = m_pageLoadState.transaction();
+ m_pageLoadState.setNetworkRequestsInProgress(transaction, networkRequestsInProgress);
+}
- m_pageLoadState.clearPendingAPIRequestURL(transaction);
+void WebPageProxy::hasInsecureContent(HasInsecureContent& hasInsecureContent)
+{
+ hasInsecureContent = m_pageLoadState.committedHasInsecureContent() ? HasInsecureContent::Yes : HasInsecureContent::No;
+}
- RefPtr<API::Object> userData;
- WebContextUserMessageDecoder messageDecoder(userData, process());
- if (!decoder.decode(messageDecoder))
- return;
+void WebPageProxy::didDestroyNavigation(uint64_t navigationID)
+{
+ PageClientProtector protector(m_pageClient);
+
+ // FIXME: Message check the navigationID.
+ m_navigationState->didDestroyNavigation(navigationID);
+}
+
+void WebPageProxy::didStartProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& url, const String& unreachableURL, const UserData& userData)
+{
+ PageClientProtector protector(m_pageClient);
+
+ auto transaction = m_pageLoadState.transaction();
+
+ m_pageLoadState.clearPendingAPIRequestURL(transaction);
WebFrameProxy* frame = m_process->webFrame(frameID);
MESSAGE_CHECK(frame);
MESSAGE_CHECK_URL(url);
+ // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
+ RefPtr<API::Navigation> navigation;
+ if (frame->isMainFrame() && navigationID)
+ navigation = &navigationState().navigation(navigationID);
+
if (frame->isMainFrame()) {
- recordNavigationSnapshot();
m_pageLoadState.didStartProvisionalLoad(transaction, url, unreachableURL);
+ m_pageClient.didStartProvisionalLoadForMainFrame();
+ hideValidationMessage();
}
frame->setUnreachableURL(unreachableURL);
frame->didStartProvisionalLoad(url);
m_pageLoadState.commitChanges();
- m_loaderClient->didStartProvisionalLoadForFrame(this, frame, userData.get());
+ if (m_navigationClient) {
+ if (frame->isMainFrame())
+ m_navigationClient->didStartProvisionalNavigation(*this, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
+ } else
+ m_loaderClient->didStartProvisionalLoadForFrame(*this, *frame, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
}
-void WebPageProxy::didReceiveServerRedirectForProvisionalLoadForFrame(uint64_t frameID, const String& url, IPC::MessageDecoder& decoder)
+void WebPageProxy::didReceiveServerRedirectForProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& url, const UserData& userData)
{
- RefPtr<API::Object> userData;
- WebContextUserMessageDecoder messageDecoder(userData, process());
- if (!decoder.decode(messageDecoder))
- return;
+ PageClientProtector protector(m_pageClient);
WebFrameProxy* frame = m_process->webFrame(frameID);
MESSAGE_CHECK(frame);
MESSAGE_CHECK_URL(url);
+ // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
+ RefPtr<API::Navigation> navigation;
+ if (frame->isMainFrame() && navigationID)
+ navigation = &navigationState().navigation(navigationID);
+
auto transaction = m_pageLoadState.transaction();
if (frame->isMainFrame())
@@ -2141,28 +3234,69 @@ void WebPageProxy::didReceiveServerRedirectForProvisionalLoadForFrame(uint64_t f
frame->didReceiveServerRedirectForProvisionalLoad(url);
m_pageLoadState.commitChanges();
- m_loaderClient->didReceiveServerRedirectForProvisionalLoadForFrame(this, frame, userData.get());
+ if (m_navigationClient) {
+ if (frame->isMainFrame())
+ m_navigationClient->didReceiveServerRedirectForProvisionalNavigation(*this, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
+ } else
+ m_loaderClient->didReceiveServerRedirectForProvisionalLoadForFrame(*this, *frame, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
}
-void WebPageProxy::didFailProvisionalLoadForFrame(uint64_t frameID, const ResourceError& error, IPC::MessageDecoder& decoder)
+void WebPageProxy::didChangeProvisionalURLForFrame(uint64_t frameID, uint64_t, const String& url)
{
- RefPtr<API::Object> userData;
- WebContextUserMessageDecoder messageDecoder(userData, process());
- if (!decoder.decode(messageDecoder))
- return;
+ PageClientProtector protector(m_pageClient);
WebFrameProxy* frame = m_process->webFrame(frameID);
MESSAGE_CHECK(frame);
+ MESSAGE_CHECK(frame->frameLoadState().state() == FrameLoadState::State::Provisional);
+ MESSAGE_CHECK_URL(url);
auto transaction = m_pageLoadState.transaction();
+ // Internally, we handle this the same way we handle a server redirect. There are no client callbacks
+ // for this, but if this is the main frame, clients may observe a change to the page's URL.
if (frame->isMainFrame())
+ m_pageLoadState.didReceiveServerRedirectForProvisionalLoad(transaction, url);
+
+ frame->didReceiveServerRedirectForProvisionalLoad(url);
+}
+
+void WebPageProxy::didFailProvisionalLoadForFrame(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, const String& provisionalURL, const ResourceError& error, const UserData& userData)
+{
+ PageClientProtector protector(m_pageClient);
+
+ WebFrameProxy* frame = m_process->webFrame(frameID);
+ MESSAGE_CHECK(frame);
+
+ // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
+ RefPtr<API::Navigation> navigation;
+ if (frame->isMainFrame() && navigationID)
+ navigation = navigationState().takeNavigation(navigationID);
+
+ auto transaction = m_pageLoadState.transaction();
+
+ if (frame->isMainFrame()) {
m_pageLoadState.didFailProvisionalLoad(transaction);
+ m_pageClient.didFailProvisionalLoadForMainFrame();
+ }
frame->didFailProvisionalLoad();
m_pageLoadState.commitChanges();
- m_loaderClient->didFailProvisionalLoadWithErrorForFrame(this, frame, error, userData.get());
+
+ ASSERT(!m_failingProvisionalLoadURL);
+ m_failingProvisionalLoadURL = provisionalURL;
+
+ if (m_navigationClient) {
+ if (frame->isMainFrame())
+ m_navigationClient->didFailProvisionalNavigationWithError(*this, *frame, navigation.get(), error, m_process->transformHandlesToObjects(userData.object()).get());
+ else {
+ // FIXME: Get the main frame's current navigation.
+ m_navigationClient->didFailProvisionalLoadInSubframeWithError(*this, *frame, frameSecurityOrigin, nullptr, error, m_process->transformHandlesToObjects(userData.object()).get());
+ }
+ } else
+ m_loaderClient->didFailProvisionalLoadWithErrorForFrame(*this, *frame, navigation.get(), error, m_process->transformHandlesToObjects(userData.object()).get());
+
+ m_failingProvisionalLoadURL = { };
}
void WebPageProxy::clearLoadDependentCallbacks()
@@ -2172,138 +3306,232 @@ void WebPageProxy::clearLoadDependentCallbacks()
m_loadDependentStringCallbackIDs.clear();
for (size_t i = 0; i < callbackIDsCopy.size(); ++i) {
- RefPtr<StringCallback> callback = m_stringCallbacks.take(callbackIDsCopy[i]);
+ auto callback = m_callbacks.take<StringCallback>(callbackIDsCopy[i]);
if (callback)
callback->invalidate();
}
}
-void WebPageProxy::didCommitLoadForFrame(uint64_t frameID, const String& mimeType, uint32_t opaqueFrameLoadType, const WebCore::CertificateInfo& certificateInfo, IPC::MessageDecoder& decoder)
+void WebPageProxy::didCommitLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& mimeType, bool frameHasCustomContentProvider, uint32_t opaqueFrameLoadType, const WebCore::CertificateInfo& certificateInfo, bool containsPluginDocument, std::optional<HasInsecureContent> hasInsecureContent, const UserData& userData)
{
- RefPtr<API::Object> userData;
- WebContextUserMessageDecoder messageDecoder(userData, process());
- if (!decoder.decode(messageDecoder))
- return;
+ PageClientProtector protector(m_pageClient);
WebFrameProxy* frame = m_process->webFrame(frameID);
MESSAGE_CHECK(frame);
- auto transaction = m_pageLoadState.transaction();
+ // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
+ RefPtr<API::Navigation> navigation;
+ if (frame->isMainFrame() && navigationID)
+ navigation = &navigationState().navigation(navigationID);
+#if PLATFORM(IOS)
if (frame->isMainFrame()) {
- m_pageLoadState.didCommitLoad(transaction);
- m_pageClient.didCommitLoadForMainFrame();
+ m_hasReceivedLayerTreeTransactionAfterDidCommitLoad = false;
+ m_firstLayerTreeTransactionIdAfterDidCommitLoad = downcast<RemoteLayerTreeDrawingAreaProxy>(*drawingArea()).nextLayerTreeTransactionID();
}
+#endif
+
+ auto transaction = m_pageLoadState.transaction();
+ Ref<WebCertificateInfo> webCertificateInfo = WebCertificateInfo::create(certificateInfo);
+ bool markPageInsecure = hasInsecureContent ? hasInsecureContent.value() == HasInsecureContent::Yes : m_treatsSHA1CertificatesAsInsecure && certificateInfo.containsNonRootSHA1SignedCertificate();
+
+ if (frame->isMainFrame()) {
+ m_pageLoadState.didCommitLoad(transaction, webCertificateInfo, markPageInsecure);
+ m_suppressAutomaticNavigationSnapshotting = false;
+ } else if (markPageInsecure)
+ m_pageLoadState.didDisplayOrRunInsecureContent(transaction);
#if USE(APPKIT)
// FIXME (bug 59111): didCommitLoadForFrame comes too late when restoring a page from b/f cache, making us disable secure event mode in password fields.
// FIXME: A load going on in one frame shouldn't affect text editing in other frames on the page.
m_pageClient.resetSecureInputState();
- dismissCorrectionPanel(ReasonForDismissingAlternativeTextIgnored);
- m_pageClient.dismissDictionaryLookupPanel();
+ m_pageClient.dismissContentRelativeChildWindows();
#endif
clearLoadDependentCallbacks();
- frame->didCommitLoad(mimeType, certificateInfo);
+ frame->didCommitLoad(mimeType, webCertificateInfo, containsPluginDocument);
+
+ if (frame->isMainFrame()) {
+ m_mainFrameHasCustomContentProvider = frameHasCustomContentProvider;
+
+ if (m_mainFrameHasCustomContentProvider) {
+ // Always assume that the main frame is pinned here, since the custom representation view will handle
+ // any wheel events and dispatch them to the WKView when necessary.
+ m_mainFrameIsPinnedToLeftSide = true;
+ m_mainFrameIsPinnedToRightSide = true;
+ m_mainFrameIsPinnedToTopSide = true;
+ m_mainFrameIsPinnedToBottomSide = true;
+
+ m_uiClient->pinnedStateDidChange(*this);
+ }
+ m_pageClient.didCommitLoadForMainFrame(mimeType, frameHasCustomContentProvider);
+ }
// Even if WebPage has the default pageScaleFactor (and therefore doesn't reset it),
// WebPageProxy's cache of the value can get out of sync (e.g. in the case where a
// plugin is handling page scaling itself) so we should reset it to the default
// for standard main frame loads.
- if (frame->isMainFrame() && static_cast<FrameLoadType>(opaqueFrameLoadType) == FrameLoadTypeStandard)
- m_pageScaleFactor = 1;
+ if (frame->isMainFrame()) {
+ if (static_cast<FrameLoadType>(opaqueFrameLoadType) == FrameLoadType::Standard) {
+ m_pageScaleFactor = 1;
+ m_pluginScaleFactor = 1;
+ m_mainFramePluginHandlesPageScaleGesture = false;
+ }
+ }
+
+#if ENABLE(POINTER_LOCK)
+ if (frame->isMainFrame())
+ requestPointerUnlock();
+#endif
m_pageLoadState.commitChanges();
- m_loaderClient->didCommitLoadForFrame(this, frame, userData.get());
+ if (m_navigationClient) {
+ if (frame->isMainFrame())
+ m_navigationClient->didCommitNavigation(*this, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
+ } else
+ m_loaderClient->didCommitLoadForFrame(*this, *frame, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
}
-void WebPageProxy::didFinishDocumentLoadForFrame(uint64_t frameID, IPC::MessageDecoder& decoder)
+void WebPageProxy::didFinishDocumentLoadForFrame(uint64_t frameID, uint64_t navigationID, const UserData& userData)
{
- RefPtr<API::Object> userData;
- WebContextUserMessageDecoder messageDecoder(userData, process());
- if (!decoder.decode(messageDecoder))
- return;
+ PageClientProtector protector(m_pageClient);
WebFrameProxy* frame = m_process->webFrame(frameID);
MESSAGE_CHECK(frame);
- m_loaderClient->didFinishDocumentLoadForFrame(this, frame, userData.get());
+ // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
+ RefPtr<API::Navigation> navigation;
+ if (frame->isMainFrame() && navigationID)
+ navigation = &navigationState().navigation(navigationID);
+
+ if (m_navigationClient) {
+ if (frame->isMainFrame())
+ m_navigationClient->didFinishDocumentLoad(*this, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
+ } else
+ m_loaderClient->didFinishDocumentLoadForFrame(*this, *frame, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
}
-void WebPageProxy::didFinishLoadForFrame(uint64_t frameID, IPC::MessageDecoder& decoder)
+void WebPageProxy::didFinishLoadForFrame(uint64_t frameID, uint64_t navigationID, const UserData& userData)
{
- RefPtr<API::Object> userData;
- WebContextUserMessageDecoder messageDecoder(userData, process());
- if (!decoder.decode(messageDecoder))
- return;
+ PageClientProtector protector(m_pageClient);
WebFrameProxy* frame = m_process->webFrame(frameID);
MESSAGE_CHECK(frame);
+ // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
+ RefPtr<API::Navigation> navigation;
+ if (frame->isMainFrame() && navigationID)
+ navigation = &navigationState().navigation(navigationID);
+
auto transaction = m_pageLoadState.transaction();
- if (frame->isMainFrame())
+ bool isMainFrame = frame->isMainFrame();
+ if (isMainFrame)
m_pageLoadState.didFinishLoad(transaction);
+ if (isMainFrame && m_controlledByAutomation) {
+ if (auto* automationSession = process().processPool().automationSession())
+ automationSession->navigationOccurredForPage(*this);
+ }
+
frame->didFinishLoad();
m_pageLoadState.commitChanges();
- m_loaderClient->didFinishLoadForFrame(this, frame, userData.get());
+ if (m_navigationClient) {
+ if (isMainFrame)
+ m_navigationClient->didFinishNavigation(*this, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
+ } else
+ m_loaderClient->didFinishLoadForFrame(*this, *frame, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get());
+
+ if (isMainFrame)
+ m_pageClient.didFinishLoadForMainFrame();
+
+ m_isLoadingAlternateHTMLStringForFailingProvisionalLoad = false;
}
-void WebPageProxy::didFailLoadForFrame(uint64_t frameID, const ResourceError& error, IPC::MessageDecoder& decoder)
+void WebPageProxy::didFailLoadForFrame(uint64_t frameID, uint64_t navigationID, const ResourceError& error, const UserData& userData)
{
- RefPtr<API::Object> userData;
- WebContextUserMessageDecoder messageDecoder(userData, process());
- if (!decoder.decode(messageDecoder))
- return;
+ PageClientProtector protector(m_pageClient);
WebFrameProxy* frame = m_process->webFrame(frameID);
MESSAGE_CHECK(frame);
+ // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
+ RefPtr<API::Navigation> navigation;
+ if (frame->isMainFrame() && navigationID)
+ navigation = &navigationState().navigation(navigationID);
+
clearLoadDependentCallbacks();
auto transaction = m_pageLoadState.transaction();
- if (frame->isMainFrame())
+ bool isMainFrame = frame->isMainFrame();
+
+ if (isMainFrame)
m_pageLoadState.didFailLoad(transaction);
+ if (isMainFrame && m_controlledByAutomation) {
+ if (auto* automationSession = process().processPool().automationSession())
+ automationSession->navigationOccurredForPage(*this);
+ }
+
frame->didFailLoad();
m_pageLoadState.commitChanges();
- m_loaderClient->didFailLoadWithErrorForFrame(this, frame, error, userData.get());
+ if (m_navigationClient) {
+ if (frame->isMainFrame())
+ m_navigationClient->didFailNavigationWithError(*this, *frame, navigation.get(), error, m_process->transformHandlesToObjects(userData.object()).get());
+ } else
+ m_loaderClient->didFailLoadWithErrorForFrame(*this, *frame, navigation.get(), error, m_process->transformHandlesToObjects(userData.object()).get());
+
+ if (isMainFrame)
+ m_pageClient.didFailLoadForMainFrame();
}
-void WebPageProxy::didSameDocumentNavigationForFrame(uint64_t frameID, uint32_t opaqueSameDocumentNavigationType, const String& url, IPC::MessageDecoder& decoder)
+void WebPageProxy::didSameDocumentNavigationForFrame(uint64_t frameID, uint64_t navigationID, uint32_t opaqueSameDocumentNavigationType, const String& url, const UserData& userData)
{
- RefPtr<API::Object> userData;
- WebContextUserMessageDecoder messageDecoder(userData, process());
- if (!decoder.decode(messageDecoder))
- return;
+ PageClientProtector protector(m_pageClient);
WebFrameProxy* frame = m_process->webFrame(frameID);
MESSAGE_CHECK(frame);
MESSAGE_CHECK_URL(url);
+ // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache.
+ RefPtr<API::Navigation> navigation;
+ if (frame->isMainFrame() && navigationID)
+ navigation = &navigationState().navigation(navigationID);
+
auto transaction = m_pageLoadState.transaction();
- if (frame->isMainFrame())
+ bool isMainFrame = frame->isMainFrame();
+ if (isMainFrame)
m_pageLoadState.didSameDocumentNavigation(transaction, url);
+ if (isMainFrame && m_controlledByAutomation) {
+ if (auto* automationSession = process().processPool().automationSession())
+ automationSession->navigationOccurredForPage(*this);
+ }
+
m_pageLoadState.clearPendingAPIRequestURL(transaction);
frame->didSameDocumentNavigation(url);
m_pageLoadState.commitChanges();
- m_loaderClient->didSameDocumentNavigationForFrame(this, frame, static_cast<SameDocumentNavigationType>(opaqueSameDocumentNavigationType), userData.get());
+
+ SameDocumentNavigationType navigationType = static_cast<SameDocumentNavigationType>(opaqueSameDocumentNavigationType);
+ if (m_navigationClient) {
+ if (isMainFrame)
+ m_navigationClient->didSameDocumentNavigation(*this, navigation.get(), navigationType, m_process->transformHandlesToObjects(userData.object()).get());
+ } else
+ m_loaderClient->didSameDocumentNavigationForFrame(*this, *frame, navigation.get(), navigationType, m_process->transformHandlesToObjects(userData.object()).get());
+
+ if (isMainFrame)
+ m_pageClient.didSameDocumentNavigationForMainFrame(navigationType);
}
-void WebPageProxy::didReceiveTitleForFrame(uint64_t frameID, const String& title, IPC::MessageDecoder& decoder)
+void WebPageProxy::didReceiveTitleForFrame(uint64_t frameID, const String& title, const UserData& userData)
{
- RefPtr<API::Object> userData;
- WebContextUserMessageDecoder messageDecoder(userData, process());
- if (!decoder.decode(messageDecoder))
- return;
+ PageClientProtector protector(m_pageClient);
WebFrameProxy* frame = m_process->webFrame(frameID);
MESSAGE_CHECK(frame);
@@ -2316,64 +3544,50 @@ void WebPageProxy::didReceiveTitleForFrame(uint64_t frameID, const String& title
frame->didChangeTitle(title);
m_pageLoadState.commitChanges();
- m_loaderClient->didReceiveTitleForFrame(this, title, frame, userData.get());
+ m_loaderClient->didReceiveTitleForFrame(*this, title, *frame, m_process->transformHandlesToObjects(userData.object()).get());
}
-void WebPageProxy::didFirstLayoutForFrame(uint64_t frameID, IPC::MessageDecoder& decoder)
+void WebPageProxy::didFirstLayoutForFrame(uint64_t frameID, const UserData& userData)
{
- RefPtr<API::Object> userData;
- WebContextUserMessageDecoder messageDecoder(userData, process());
- if (!decoder.decode(messageDecoder))
- return;
+ PageClientProtector protector(m_pageClient);
WebFrameProxy* frame = m_process->webFrame(frameID);
MESSAGE_CHECK(frame);
- m_loaderClient->didFirstLayoutForFrame(this, frame, userData.get());
+ m_loaderClient->didFirstLayoutForFrame(*this, *frame, m_process->transformHandlesToObjects(userData.object()).get());
}
-void WebPageProxy::didFirstVisuallyNonEmptyLayoutForFrame(uint64_t frameID, IPC::MessageDecoder& decoder)
+void WebPageProxy::didFirstVisuallyNonEmptyLayoutForFrame(uint64_t frameID, const UserData& userData)
{
- RefPtr<API::Object> userData;
- WebContextUserMessageDecoder messageDecoder(userData, process());
- if (!decoder.decode(messageDecoder))
- return;
+ PageClientProtector protector(m_pageClient);
WebFrameProxy* frame = m_process->webFrame(frameID);
MESSAGE_CHECK(frame);
- m_loaderClient->didFirstVisuallyNonEmptyLayoutForFrame(this, frame, userData.get());
+ m_loaderClient->didFirstVisuallyNonEmptyLayoutForFrame(*this, *frame, m_process->transformHandlesToObjects(userData.object()).get());
+
+ if (frame->isMainFrame())
+ m_pageClient.didFirstVisuallyNonEmptyLayoutForMainFrame();
}
-void WebPageProxy::didLayout(uint32_t layoutMilestones, IPC::MessageDecoder& decoder)
+void WebPageProxy::didLayoutForCustomContentProvider()
{
- RefPtr<API::Object> userData;
- WebContextUserMessageDecoder messageDecoder(userData, process());
- if (!decoder.decode(messageDecoder))
- return;
-
- m_loaderClient->didLayout(this, static_cast<LayoutMilestones>(layoutMilestones), userData.get());
+ didReachLayoutMilestone(DidFirstLayout | DidFirstVisuallyNonEmptyLayout | DidHitRelevantRepaintedObjectsAreaThreshold);
}
-void WebPageProxy::didRemoveFrameFromHierarchy(uint64_t frameID, IPC::MessageDecoder& decoder)
+void WebPageProxy::didReachLayoutMilestone(uint32_t layoutMilestones)
{
- RefPtr<API::Object> userData;
- WebContextUserMessageDecoder messageDecoder(userData, process());
- if (!decoder.decode(messageDecoder))
- return;
+ PageClientProtector protector(m_pageClient);
- WebFrameProxy* frame = m_process->webFrame(frameID);
- MESSAGE_CHECK(frame);
-
- m_loaderClient->didRemoveFrameFromHierarchy(this, frame, userData.get());
+ if (m_navigationClient)
+ m_navigationClient->renderingProgressDidChange(*this, static_cast<LayoutMilestones>(layoutMilestones));
+ else
+ m_loaderClient->didReachLayoutMilestone(*this, static_cast<LayoutMilestones>(layoutMilestones));
}
-void WebPageProxy::didDisplayInsecureContentForFrame(uint64_t frameID, IPC::MessageDecoder& decoder)
+void WebPageProxy::didDisplayInsecureContentForFrame(uint64_t frameID, const UserData& userData)
{
- RefPtr<API::Object> userData;
- WebContextUserMessageDecoder messageDecoder(userData, process());
- if (!decoder.decode(messageDecoder))
- return;
+ PageClientProtector protector(m_pageClient);
WebFrameProxy* frame = m_process->webFrame(frameID);
MESSAGE_CHECK(frame);
@@ -2382,15 +3596,12 @@ void WebPageProxy::didDisplayInsecureContentForFrame(uint64_t frameID, IPC::Mess
m_pageLoadState.didDisplayOrRunInsecureContent(transaction);
m_pageLoadState.commitChanges();
- m_loaderClient->didDisplayInsecureContentForFrame(this, frame, userData.get());
+ m_loaderClient->didDisplayInsecureContentForFrame(*this, *frame, m_process->transformHandlesToObjects(userData.object()).get());
}
-void WebPageProxy::didRunInsecureContentForFrame(uint64_t frameID, IPC::MessageDecoder& decoder)
+void WebPageProxy::didRunInsecureContentForFrame(uint64_t frameID, const UserData& userData)
{
- RefPtr<API::Object> userData;
- WebContextUserMessageDecoder messageDecoder(userData, process());
- if (!decoder.decode(messageDecoder))
- return;
+ PageClientProtector protector(m_pageClient);
WebFrameProxy* frame = m_process->webFrame(frameID);
MESSAGE_CHECK(frame);
@@ -2399,24 +3610,28 @@ void WebPageProxy::didRunInsecureContentForFrame(uint64_t frameID, IPC::MessageD
m_pageLoadState.didDisplayOrRunInsecureContent(transaction);
m_pageLoadState.commitChanges();
- m_loaderClient->didRunInsecureContentForFrame(this, frame, userData.get());
+ m_loaderClient->didRunInsecureContentForFrame(*this, *frame, m_process->transformHandlesToObjects(userData.object()).get());
}
-void WebPageProxy::didDetectXSSForFrame(uint64_t frameID, IPC::MessageDecoder& decoder)
+void WebPageProxy::didDetectXSSForFrame(uint64_t frameID, const UserData& userData)
{
- RefPtr<API::Object> userData;
- WebContextUserMessageDecoder messageDecoder(userData, process());
- if (!decoder.decode(messageDecoder))
- return;
+ PageClientProtector protector(m_pageClient);
WebFrameProxy* frame = m_process->webFrame(frameID);
MESSAGE_CHECK(frame);
- m_loaderClient->didDetectXSSForFrame(this, frame, userData.get());
+ m_loaderClient->didDetectXSSForFrame(*this, *frame, m_process->transformHandlesToObjects(userData.object()).get());
+}
+
+void WebPageProxy::mainFramePluginHandlesPageScaleGestureDidChange(bool mainFramePluginHandlesPageScaleGesture)
+{
+ m_mainFramePluginHandlesPageScaleGesture = mainFramePluginHandlesPageScaleGesture;
}
void WebPageProxy::frameDidBecomeFrameSet(uint64_t frameID, bool value)
{
+ PageClientProtector protector(m_pageClient);
+
WebFrameProxy* frame = m_process->webFrame(frameID);
MESSAGE_CHECK(frame);
@@ -2425,12 +3640,9 @@ void WebPageProxy::frameDidBecomeFrameSet(uint64_t frameID, bool value)
m_frameSetLargestFrame = value ? m_mainFrame : 0;
}
-void WebPageProxy::decidePolicyForNavigationAction(uint64_t frameID, const NavigationActionData& navigationActionData, uint64_t originatingFrameID, const WebCore::ResourceRequest& originalRequest, const ResourceRequest& request, uint64_t listenerID, IPC::MessageDecoder& decoder, bool& receivedPolicyAction, uint64_t& policyAction, uint64_t& downloadID)
+void WebPageProxy::decidePolicyForNavigationAction(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, const NavigationActionData& navigationActionData, uint64_t originatingFrameID, const SecurityOriginData& originatingFrameSecurityOrigin, const WebCore::ResourceRequest& originalRequest, const ResourceRequest& request, uint64_t listenerID, const UserData& userData, bool& receivedPolicyAction, uint64_t& newNavigationID, uint64_t& policyAction, DownloadID& downloadID, WebsitePolicies& websitePolicies)
{
- RefPtr<API::Object> userData;
- WebContextUserMessageDecoder messageDecoder(userData, process());
- if (!decoder.decode(messageDecoder))
- return;
+ PageClientProtector protector(m_pageClient);
auto transaction = m_pageLoadState.transaction();
@@ -2444,15 +3656,51 @@ void WebPageProxy::decidePolicyForNavigationAction(uint64_t frameID, const Navig
WebFrameProxy* originatingFrame = m_process->webFrame(originatingFrameID);
- RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
+ Ref<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
+ if (!navigationID && frame->isMainFrame()) {
+ auto navigation = m_navigationState->createLoadRequestNavigation(request);
+ newNavigationID = navigation->navigationID();
+ listener->setNavigation(WTFMove(navigation));
+ }
+
+#if ENABLE(CONTENT_FILTERING)
+ if (frame->didHandleContentFilterUnblockNavigation(request)) {
+ receivedPolicyAction = true;
+ policyAction = PolicyIgnore;
+ return;
+ }
+#endif
ASSERT(!m_inDecidePolicyForNavigationAction);
m_inDecidePolicyForNavigationAction = true;
m_syncNavigationActionPolicyActionIsValid = false;
+#if ENABLE(DOWNLOAD_ATTRIBUTE)
+ m_syncNavigationActionHasDownloadAttribute = !navigationActionData.downloadAttribute.isNull();
+#endif
+
+ if (m_navigationClient) {
+ RefPtr<API::FrameInfo> destinationFrameInfo;
+ RefPtr<API::FrameInfo> sourceFrameInfo;
- m_policyClient->decidePolicyForNavigationAction(this, frame, navigationActionData, originatingFrame, originalRequest, request, listener.get(), userData.get());
+ if (frame)
+ destinationFrameInfo = API::FrameInfo::create(*frame, frameSecurityOrigin.securityOrigin());
+ if (originatingFrame == frame)
+ sourceFrameInfo = destinationFrameInfo;
+ else if (originatingFrame)
+ sourceFrameInfo = API::FrameInfo::create(*originatingFrame, originatingFrameSecurityOrigin.securityOrigin());
+
+ auto userInitiatedActivity = m_process->userInitiatedActivity(navigationActionData.userGestureTokenIdentifier);
+ bool shouldOpenAppLinks = !m_shouldSuppressAppLinksInNextNavigationPolicyDecision && (!destinationFrameInfo || destinationFrameInfo->isMainFrame()) && !hostsAreEqual(URL(ParsedURLString, m_mainFrame->url()), request.url()) && navigationActionData.navigationType != WebCore::NavigationType::BackForward;
+
+ auto navigationAction = API::NavigationAction::create(navigationActionData, sourceFrameInfo.get(), destinationFrameInfo.get(), request, originalRequest.url(), shouldOpenAppLinks, WTFMove(userInitiatedActivity));
+
+ m_navigationClient->decidePolicyForNavigationAction(*this, navigationAction.get(), WTFMove(listener), m_process->transformHandlesToObjects(userData.object()).get());
+ } else
+ m_policyClient->decidePolicyForNavigationAction(*this, frame, navigationActionData, originatingFrame, originalRequest, request, WTFMove(listener), m_process->transformHandlesToObjects(userData.object()).get());
+
+ m_shouldSuppressAppLinksInNextNavigationPolicyDecision = false;
m_inDecidePolicyForNavigationAction = false;
// Check if we received a policy decision already. If we did, we can just pass it back.
@@ -2460,51 +3708,64 @@ void WebPageProxy::decidePolicyForNavigationAction(uint64_t frameID, const Navig
if (m_syncNavigationActionPolicyActionIsValid) {
policyAction = m_syncNavigationActionPolicyAction;
downloadID = m_syncNavigationActionPolicyDownloadID;
+ websitePolicies = m_syncNavigationActionPolicyWebsitePolicies;
}
}
-void WebPageProxy::decidePolicyForNewWindowAction(uint64_t frameID, const NavigationActionData& navigationActionData, const ResourceRequest& request, const String& frameName, uint64_t listenerID, IPC::MessageDecoder& decoder)
+void WebPageProxy::decidePolicyForNewWindowAction(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, const NavigationActionData& navigationActionData, const ResourceRequest& request, const String& frameName, uint64_t listenerID, const UserData& userData)
{
- RefPtr<API::Object> userData;
- WebContextUserMessageDecoder messageDecoder(userData, process());
- if (!decoder.decode(messageDecoder))
- return;
+ PageClientProtector protector(m_pageClient);
WebFrameProxy* frame = m_process->webFrame(frameID);
MESSAGE_CHECK(frame);
MESSAGE_CHECK_URL(request.url());
- RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
+ Ref<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
- m_policyClient->decidePolicyForNewWindowAction(this, frame, navigationActionData.navigationType, navigationActionData.modifiers, navigationActionData.mouseButton, request, frameName, listener.get(), userData.get());
+ if (m_navigationClient) {
+ RefPtr<API::FrameInfo> sourceFrameInfo;
+ if (frame)
+ sourceFrameInfo = API::FrameInfo::create(*frame, frameSecurityOrigin.securityOrigin());
+
+ auto userInitiatedActivity = m_process->userInitiatedActivity(navigationActionData.userGestureTokenIdentifier);
+ bool shouldOpenAppLinks = !hostsAreEqual(URL(ParsedURLString, m_mainFrame->url()), request.url());
+ auto navigationAction = API::NavigationAction::create(navigationActionData, sourceFrameInfo.get(), nullptr, request, request.url(), shouldOpenAppLinks, WTFMove(userInitiatedActivity));
+
+ m_navigationClient->decidePolicyForNavigationAction(*this, navigationAction.get(), WTFMove(listener), m_process->transformHandlesToObjects(userData.object()).get());
+
+ } else
+ m_policyClient->decidePolicyForNewWindowAction(*this, *frame, navigationActionData, request, frameName, WTFMove(listener), m_process->transformHandlesToObjects(userData.object()).get());
}
-void WebPageProxy::decidePolicyForResponse(uint64_t frameID, const ResourceResponse& response, const ResourceRequest& request, bool canShowMIMEType, uint64_t listenerID, IPC::MessageDecoder& decoder)
+void WebPageProxy::decidePolicyForResponse(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, const ResourceResponse& response, const ResourceRequest& request, bool canShowMIMEType, uint64_t listenerID, const UserData& userData)
{
- RefPtr<API::Object> userData;
- WebContextUserMessageDecoder messageDecoder(userData, process());
- if (!decoder.decode(messageDecoder))
- return;
+ PageClientProtector protector(m_pageClient);
WebFrameProxy* frame = m_process->webFrame(frameID);
MESSAGE_CHECK(frame);
MESSAGE_CHECK_URL(request.url());
MESSAGE_CHECK_URL(response.url());
- RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
+ Ref<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
- m_policyClient->decidePolicyForResponse(this, frame, response, request, canShowMIMEType, listener.get(), userData.get());
+ if (m_navigationClient) {
+ auto navigationResponse = API::NavigationResponse::create(API::FrameInfo::create(*frame, frameSecurityOrigin.securityOrigin()).get(), request, response, canShowMIMEType);
+ m_navigationClient->decidePolicyForNavigationResponse(*this, navigationResponse.get(), WTFMove(listener), m_process->transformHandlesToObjects(userData.object()).get());
+ } else
+ m_policyClient->decidePolicyForResponse(*this, *frame, response, request, canShowMIMEType, WTFMove(listener), m_process->transformHandlesToObjects(userData.object()).get());
}
-void WebPageProxy::decidePolicyForResponseSync(uint64_t frameID, const ResourceResponse& response, const ResourceRequest& request, bool canShowMIMEType, uint64_t listenerID, IPC::MessageDecoder& decoder, bool& receivedPolicyAction, uint64_t& policyAction, uint64_t& downloadID)
+void WebPageProxy::decidePolicyForResponseSync(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, const ResourceResponse& response, const ResourceRequest& request, bool canShowMIMEType, uint64_t listenerID, const UserData& userData, bool& receivedPolicyAction, uint64_t& policyAction, DownloadID& downloadID)
{
+ PageClientProtector protector(m_pageClient);
+
ASSERT(!m_inDecidePolicyForResponseSync);
m_inDecidePolicyForResponseSync = true;
m_decidePolicyForResponseRequest = &request;
m_syncMimeTypePolicyActionIsValid = false;
- decidePolicyForResponse(frameID, response, request, canShowMIMEType, listenerID, decoder);
+ decidePolicyForResponse(frameID, frameSecurityOrigin, response, request, canShowMIMEType, listenerID, userData);
m_inDecidePolicyForResponseSync = false;
m_decidePolicyForResponseRequest = 0;
@@ -2517,44 +3778,118 @@ void WebPageProxy::decidePolicyForResponseSync(uint64_t frameID, const ResourceR
}
}
-void WebPageProxy::unableToImplementPolicy(uint64_t frameID, const ResourceError& error, IPC::MessageDecoder& decoder)
+void WebPageProxy::unableToImplementPolicy(uint64_t frameID, const ResourceError& error, const UserData& userData)
{
- RefPtr<API::Object> userData;
- WebContextUserMessageDecoder messageDecoder(userData, process());
- if (!decoder.decode(messageDecoder))
- return;
-
+ PageClientProtector protector(m_pageClient);
+
WebFrameProxy* frame = m_process->webFrame(frameID);
MESSAGE_CHECK(frame);
- m_policyClient->unableToImplementPolicy(this, frame, error, userData.get());
+ m_policyClient->unableToImplementPolicy(*this, *frame, error, m_process->transformHandlesToObjects(userData.object()).get());
}
// FormClient
-void WebPageProxy::willSubmitForm(uint64_t frameID, uint64_t sourceFrameID, const Vector<std::pair<String, String>>& textFieldValues, uint64_t listenerID, IPC::MessageDecoder& decoder)
+void WebPageProxy::willSubmitForm(uint64_t frameID, uint64_t sourceFrameID, const Vector<std::pair<String, String>>& textFieldValues, uint64_t listenerID, const UserData& userData)
{
- RefPtr<API::Object> userData;
- WebContextUserMessageDecoder messageDecoder(userData, process());
- if (!decoder.decode(messageDecoder))
- return;
-
WebFrameProxy* frame = m_process->webFrame(frameID);
MESSAGE_CHECK(frame);
WebFrameProxy* sourceFrame = m_process->webFrame(sourceFrameID);
MESSAGE_CHECK(sourceFrame);
- RefPtr<WebFormSubmissionListenerProxy> listener = frame->setUpFormSubmissionListenerProxy(listenerID);
- if (!m_formClient.willSubmitForm(this, frame, sourceFrame, textFieldValues, userData.get(), listener.get()))
- listener->continueSubmission();
+ Ref<WebFormSubmissionListenerProxy> listener = frame->setUpFormSubmissionListenerProxy(listenerID);
+ m_formClient->willSubmitForm(*this, *frame, *sourceFrame, textFieldValues, m_process->transformHandlesToObjects(userData.object()).get(), listener.get());
+}
+
+void WebPageProxy::didNavigateWithNavigationData(const WebNavigationDataStore& store, uint64_t frameID)
+{
+ PageClientProtector protector(m_pageClient);
+
+ WebFrameProxy* frame = m_process->webFrame(frameID);
+ MESSAGE_CHECK(frame);
+ MESSAGE_CHECK(frame->page() == this);
+
+ if (m_historyClient) {
+ if (frame->isMainFrame())
+ m_historyClient->didNavigateWithNavigationData(*this, store);
+ } else
+ m_loaderClient->didNavigateWithNavigationData(*this, store, *frame);
+ process().processPool().historyClient().didNavigateWithNavigationData(process().processPool(), *this, store, *frame);
+}
+
+void WebPageProxy::didPerformClientRedirect(const String& sourceURLString, const String& destinationURLString, uint64_t frameID)
+{
+ PageClientProtector protector(m_pageClient);
+
+ if (sourceURLString.isEmpty() || destinationURLString.isEmpty())
+ return;
+
+ WebFrameProxy* frame = m_process->webFrame(frameID);
+ MESSAGE_CHECK(frame);
+ MESSAGE_CHECK(frame->page() == this);
+
+ MESSAGE_CHECK_URL(sourceURLString);
+ MESSAGE_CHECK_URL(destinationURLString);
+
+ if (m_historyClient) {
+ if (frame->isMainFrame())
+ m_historyClient->didPerformClientRedirect(*this, sourceURLString, destinationURLString);
+ } else
+ m_loaderClient->didPerformClientRedirect(*this, sourceURLString, destinationURLString, *frame);
+ process().processPool().historyClient().didPerformClientRedirect(process().processPool(), *this, sourceURLString, destinationURLString, *frame);
+}
+
+void WebPageProxy::didPerformServerRedirect(const String& sourceURLString, const String& destinationURLString, uint64_t frameID)
+{
+ PageClientProtector protector(m_pageClient);
+
+ if (sourceURLString.isEmpty() || destinationURLString.isEmpty())
+ return;
+
+ WebFrameProxy* frame = m_process->webFrame(frameID);
+ MESSAGE_CHECK(frame);
+ MESSAGE_CHECK(frame->page() == this);
+
+ MESSAGE_CHECK_URL(sourceURLString);
+ MESSAGE_CHECK_URL(destinationURLString);
+
+ if (m_historyClient) {
+ if (frame->isMainFrame())
+ m_historyClient->didPerformServerRedirect(*this, sourceURLString, destinationURLString);
+ } else
+ m_loaderClient->didPerformServerRedirect(*this, sourceURLString, destinationURLString, *frame);
+ process().processPool().historyClient().didPerformServerRedirect(process().processPool(), *this, sourceURLString, destinationURLString, *frame);
+}
+
+void WebPageProxy::didUpdateHistoryTitle(const String& title, const String& url, uint64_t frameID)
+{
+ PageClientProtector protector(m_pageClient);
+
+ WebFrameProxy* frame = m_process->webFrame(frameID);
+ MESSAGE_CHECK(frame);
+ MESSAGE_CHECK(frame->page() == this);
+
+ MESSAGE_CHECK_URL(url);
+
+ if (m_historyClient) {
+ if (frame->isMainFrame())
+ m_historyClient->didUpdateHistoryTitle(*this, title, url);
+ } else
+ m_loaderClient->didUpdateHistoryTitle(*this, title, url, *frame);
+ process().processPool().historyClient().didUpdateHistoryTitle(process().processPool(), *this, title, url, *frame);
}
// UIClient
-void WebPageProxy::createNewPage(const ResourceRequest& request, const WindowFeatures& windowFeatures, uint32_t opaqueModifiers, int32_t opaqueMouseButton, uint64_t& newPageID, WebPageCreationParameters& newPageParameters)
+void WebPageProxy::createNewPage(uint64_t frameID, const SecurityOriginData& securityOriginData, const ResourceRequest& request, const WindowFeatures& windowFeatures, const NavigationActionData& navigationActionData, uint64_t& newPageID, WebPageCreationParameters& newPageParameters)
{
- RefPtr<WebPageProxy> newPage = m_uiClient.createNewPage(this, request, windowFeatures, static_cast<WebEvent::Modifiers>(opaqueModifiers), static_cast<WebMouseEvent::Button>(opaqueMouseButton));
+ WebFrameProxy* frame = m_process->webFrame(frameID);
+ MESSAGE_CHECK(frame);
+
+ auto mainFrameURL = m_mainFrame->url();
+
+ RefPtr<WebPageProxy> newPage = m_uiClient->createNewPage(this, frame, securityOriginData, request, windowFeatures, navigationActionData);
if (!newPage) {
newPageID = 0;
return;
@@ -2562,93 +3897,107 @@ void WebPageProxy::createNewPage(const ResourceRequest& request, const WindowFea
newPageID = newPage->pageID();
newPageParameters = newPage->creationParameters();
- process().context().storageManager().cloneSessionStorageNamespace(m_pageID, newPage->pageID());
+
+ WebsiteDataStore::cloneSessionData(*this, *newPage);
+ newPage->m_shouldSuppressAppLinksInNextNavigationPolicyDecision = hostsAreEqual(URL(ParsedURLString, mainFrameURL), request.url());
}
void WebPageProxy::showPage()
{
- m_uiClient.showPage(this);
+ m_uiClient->showPage(this);
+}
+
+void WebPageProxy::fullscreenMayReturnToInline()
+{
+ m_uiClient->fullscreenMayReturnToInline(this);
+}
+
+void WebPageProxy::didEnterFullscreen()
+{
+ m_uiClient->didEnterFullscreen(this);
+}
+
+void WebPageProxy::didExitFullscreen()
+{
+ m_uiClient->didExitFullscreen(this);
}
void WebPageProxy::closePage(bool stopResponsivenessTimer)
{
if (stopResponsivenessTimer)
- m_process->responsivenessTimer()->stop();
+ m_process->responsivenessTimer().stop();
m_pageClient.clearAllEditCommands();
- m_uiClient.close(this);
+ m_uiClient->close(this);
}
-void WebPageProxy::runJavaScriptAlert(uint64_t frameID, const String& message)
+void WebPageProxy::runJavaScriptAlert(uint64_t frameID, const SecurityOriginData& securityOrigin, const String& message, Ref<Messages::WebPageProxy::RunJavaScriptAlert::DelayedReply>&& reply)
{
WebFrameProxy* frame = m_process->webFrame(frameID);
MESSAGE_CHECK(frame);
// Since runJavaScriptAlert() can spin a nested run loop we need to turn off the responsiveness timer.
- m_process->responsivenessTimer()->stop();
+ m_process->responsivenessTimer().stop();
- m_uiClient.runJavaScriptAlert(this, message, frame);
+ m_uiClient->runJavaScriptAlert(this, message, frame, securityOrigin, [reply = WTFMove(reply)] {
+ reply->send();
+ });
}
-void WebPageProxy::runJavaScriptConfirm(uint64_t frameID, const String& message, bool& result)
+void WebPageProxy::runJavaScriptConfirm(uint64_t frameID, const SecurityOriginData& securityOrigin, const String& message, Ref<Messages::WebPageProxy::RunJavaScriptConfirm::DelayedReply>&& reply)
{
WebFrameProxy* frame = m_process->webFrame(frameID);
MESSAGE_CHECK(frame);
// Since runJavaScriptConfirm() can spin a nested run loop we need to turn off the responsiveness timer.
- m_process->responsivenessTimer()->stop();
+ m_process->responsivenessTimer().stop();
- result = m_uiClient.runJavaScriptConfirm(this, message, frame);
+ m_uiClient->runJavaScriptConfirm(this, message, frame, securityOrigin, [reply = WTFMove(reply)](bool result) {
+ reply->send(result);
+ });
}
-void WebPageProxy::runJavaScriptPrompt(uint64_t frameID, const String& message, const String& defaultValue, String& result)
+void WebPageProxy::runJavaScriptPrompt(uint64_t frameID, const SecurityOriginData& securityOrigin, const String& message, const String& defaultValue, RefPtr<Messages::WebPageProxy::RunJavaScriptPrompt::DelayedReply> reply)
{
WebFrameProxy* frame = m_process->webFrame(frameID);
MESSAGE_CHECK(frame);
// Since runJavaScriptPrompt() can spin a nested run loop we need to turn off the responsiveness timer.
- m_process->responsivenessTimer()->stop();
-
- result = m_uiClient.runJavaScriptPrompt(this, message, defaultValue, frame);
-}
-
-void WebPageProxy::shouldInterruptJavaScript(bool& result)
-{
- // Since shouldInterruptJavaScript() can spin a nested run loop we need to turn off the responsiveness timer.
- m_process->responsivenessTimer()->stop();
+ m_process->responsivenessTimer().stop();
- result = m_uiClient.shouldInterruptJavaScript(this);
+ m_uiClient->runJavaScriptPrompt(this, message, defaultValue, frame, securityOrigin, [reply](const String& result) { reply->send(result); });
}
void WebPageProxy::setStatusText(const String& text)
{
- m_uiClient.setStatusText(this, text);
+ m_uiClient->setStatusText(this, text);
}
-void WebPageProxy::mouseDidMoveOverElement(const WebHitTestResult::Data& hitTestResultData, uint32_t opaqueModifiers, IPC::MessageDecoder& decoder)
+void WebPageProxy::mouseDidMoveOverElement(const WebHitTestResultData& hitTestResultData, uint32_t opaqueModifiers, const UserData& userData)
{
- RefPtr<API::Object> userData;
- WebContextUserMessageDecoder messageDecoder(userData, process());
- if (!decoder.decode(messageDecoder))
- return;
+ m_lastMouseMoveHitTestResult = API::HitTestResult::create(hitTestResultData);
WebEvent::Modifiers modifiers = static_cast<WebEvent::Modifiers>(opaqueModifiers);
- m_uiClient.mouseDidMoveOverElement(this, hitTestResultData, modifiers, userData.get());
+ m_uiClient->mouseDidMoveOverElement(this, hitTestResultData, modifiers, m_process->transformHandlesToObjects(userData.object()).get());
}
-void WebPageProxy::connectionWillOpen(IPC::Connection* connection)
+void WebPageProxy::connectionWillOpen(IPC::Connection& connection)
{
- ASSERT(connection == m_process->connection());
+ ASSERT(&connection == m_process->connection());
- m_process->context().storageManager().setAllowedSessionStorageNamespaceConnection(m_pageID, connection);
+ m_webProcessLifetimeTracker.connectionWillOpen(connection);
}
-void WebPageProxy::connectionWillClose(IPC::Connection* connection)
+void WebPageProxy::webProcessWillShutDown()
{
- ASSERT_UNUSED(connection, connection == m_process->connection());
+ m_webProcessLifetimeTracker.webProcessWillShutDown();
+}
- m_process->context().storageManager().setAllowedSessionStorageNamespaceConnection(m_pageID, 0);
+void WebPageProxy::processDidFinishLaunching()
+{
+ ASSERT(m_process->state() == WebProcessProxy::State::Running);
+ finishInitializingWebPageAfterProcessLaunch();
}
#if ENABLE(NETSCAPE_PLUGIN_API)
@@ -2659,9 +4008,9 @@ void WebPageProxy::unavailablePluginButtonClicked(uint32_t opaquePluginUnavailab
MESSAGE_CHECK_URL(frameURLString);
MESSAGE_CHECK_URL(pageURLString);
- RefPtr<ImmutableDictionary> pluginInformation;
+ RefPtr<API::Dictionary> pluginInformation;
String newMimeType = mimeType;
- PluginModuleInfo plugin = m_process->context().pluginInfoStore().findPlugin(newMimeType, URL(URL(), pluginURLString));
+ PluginModuleInfo plugin = m_process->processPool().pluginInfoStore().findPlugin(newMimeType, URL(URL(), pluginURLString));
pluginInformation = createPluginInformationDictionary(plugin, frameURLString, mimeType, pageURLString, pluginspageAttributeURLString, pluginURLString);
WKPluginUnavailabilityReason pluginUnavailabilityReason = kWKPluginUnavailabilityReasonPluginMissing;
@@ -2679,105 +4028,104 @@ void WebPageProxy::unavailablePluginButtonClicked(uint32_t opaquePluginUnavailab
ASSERT_NOT_REACHED();
}
- m_uiClient.unavailablePluginButtonClicked(this, pluginUnavailabilityReason, pluginInformation.get());
+ m_uiClient->unavailablePluginButtonClicked(this, pluginUnavailabilityReason, pluginInformation.get());
}
#endif // ENABLE(NETSCAPE_PLUGIN_API)
#if ENABLE(WEBGL)
void WebPageProxy::webGLPolicyForURL(const String& url, uint32_t& loadPolicy)
{
- loadPolicy = static_cast<uint32_t>(m_loaderClient->webGLLoadPolicy(this, url));
+ loadPolicy = static_cast<uint32_t>(m_loaderClient->webGLLoadPolicy(*this, url));
+}
+
+void WebPageProxy::resolveWebGLPolicyForURL(const String& url, uint32_t& loadPolicy)
+{
+ loadPolicy = static_cast<uint32_t>(m_loaderClient->resolveWebGLLoadPolicy(*this, url));
}
#endif // ENABLE(WEBGL)
void WebPageProxy::setToolbarsAreVisible(bool toolbarsAreVisible)
{
- m_uiClient.setToolbarsAreVisible(this, toolbarsAreVisible);
+ m_uiClient->setToolbarsAreVisible(this, toolbarsAreVisible);
}
void WebPageProxy::getToolbarsAreVisible(bool& toolbarsAreVisible)
{
- toolbarsAreVisible = m_uiClient.toolbarsAreVisible(this);
+ toolbarsAreVisible = m_uiClient->toolbarsAreVisible(this);
}
void WebPageProxy::setMenuBarIsVisible(bool menuBarIsVisible)
{
- m_uiClient.setMenuBarIsVisible(this, menuBarIsVisible);
+ m_uiClient->setMenuBarIsVisible(this, menuBarIsVisible);
}
void WebPageProxy::getMenuBarIsVisible(bool& menuBarIsVisible)
{
- menuBarIsVisible = m_uiClient.menuBarIsVisible(this);
+ menuBarIsVisible = m_uiClient->menuBarIsVisible(this);
}
void WebPageProxy::setStatusBarIsVisible(bool statusBarIsVisible)
{
- m_uiClient.setStatusBarIsVisible(this, statusBarIsVisible);
+ m_uiClient->setStatusBarIsVisible(this, statusBarIsVisible);
}
void WebPageProxy::getStatusBarIsVisible(bool& statusBarIsVisible)
{
- statusBarIsVisible = m_uiClient.statusBarIsVisible(this);
+ statusBarIsVisible = m_uiClient->statusBarIsVisible(this);
}
void WebPageProxy::setIsResizable(bool isResizable)
{
- m_uiClient.setIsResizable(this, isResizable);
+ m_uiClient->setIsResizable(this, isResizable);
}
void WebPageProxy::getIsResizable(bool& isResizable)
{
- isResizable = m_uiClient.isResizable(this);
+ isResizable = m_uiClient->isResizable(this);
}
void WebPageProxy::setWindowFrame(const FloatRect& newWindowFrame)
{
- m_uiClient.setWindowFrame(this, m_pageClient.convertToDeviceSpace(newWindowFrame));
+ m_uiClient->setWindowFrame(this, m_pageClient.convertToDeviceSpace(newWindowFrame));
}
void WebPageProxy::getWindowFrame(FloatRect& newWindowFrame)
{
- newWindowFrame = m_pageClient.convertToUserSpace(m_uiClient.windowFrame(this));
+ newWindowFrame = m_pageClient.convertToUserSpace(m_uiClient->windowFrame(this));
}
-void WebPageProxy::screenToWindow(const IntPoint& screenPoint, IntPoint& windowPoint)
+void WebPageProxy::screenToRootView(const IntPoint& screenPoint, IntPoint& windowPoint)
{
- windowPoint = m_pageClient.screenToWindow(screenPoint);
+ windowPoint = m_pageClient.screenToRootView(screenPoint);
}
-void WebPageProxy::windowToScreen(const IntRect& viewRect, IntRect& result)
+void WebPageProxy::rootViewToScreen(const IntRect& viewRect, IntRect& result)
{
- result = m_pageClient.windowToScreen(viewRect);
+ result = m_pageClient.rootViewToScreen(viewRect);
}
-void WebPageProxy::runBeforeUnloadConfirmPanel(const String& message, uint64_t frameID, bool& shouldClose)
+#if PLATFORM(IOS)
+void WebPageProxy::accessibilityScreenToRootView(const IntPoint& screenPoint, IntPoint& windowPoint)
{
- WebFrameProxy* frame = m_process->webFrame(frameID);
- MESSAGE_CHECK(frame);
-
- // Since runBeforeUnloadConfirmPanel() can spin a nested run loop we need to turn off the responsiveness timer.
- m_process->responsivenessTimer()->stop();
-
- shouldClose = m_uiClient.runBeforeUnloadConfirmPanel(this, message, frame);
+ windowPoint = m_pageClient.accessibilityScreenToRootView(screenPoint);
}
-#if USE(TILED_BACKING_STORE)
-void WebPageProxy::pageDidRequestScroll(const IntPoint& point)
+void WebPageProxy::rootViewToAccessibilityScreen(const IntRect& viewRect, IntRect& result)
{
- m_pageClient.pageDidRequestScroll(point);
+ result = m_pageClient.rootViewToAccessibilityScreen(viewRect);
}
+#endif
-void WebPageProxy::pageTransitionViewportReady()
+void WebPageProxy::runBeforeUnloadConfirmPanel(const String& message, uint64_t frameID, RefPtr<Messages::WebPageProxy::RunBeforeUnloadConfirmPanel::DelayedReply> reply)
{
- m_pageClient.pageTransitionViewportReady();
-}
+ WebFrameProxy* frame = m_process->webFrame(frameID);
+ MESSAGE_CHECK(frame);
-void WebPageProxy::didRenderFrame(const WebCore::IntSize& contentsSize, const WebCore::IntRect& coveredRect)
-{
- m_pageClient.didRenderFrame(contentsSize, coveredRect);
-}
+ // Since runBeforeUnloadConfirmPanel() can spin a nested run loop we need to turn off the responsiveness timer.
+ m_process->responsivenessTimer().stop();
-#endif
+ m_uiClient->runBeforeUnloadConfirmPanel(this, message, frame, [reply](bool result) { reply->send(result); });
+}
void WebPageProxy::didChangeViewportProperties(const ViewportAttributes& attr)
{
@@ -2786,30 +4134,37 @@ void WebPageProxy::didChangeViewportProperties(const ViewportAttributes& attr)
void WebPageProxy::pageDidScroll()
{
- m_uiClient.pageDidScroll(this);
-#if !PLATFORM(IOS) && PLATFORM(MAC)
- dismissCorrectionPanel(ReasonForDismissingAlternativeTextIgnored);
+ m_uiClient->pageDidScroll(this);
+
+#if PLATFORM(IOS)
+ // Do not hide the validation message if the scrolling was caused by the keyboard showing up.
+ if (m_isKeyboardAnimatingIn)
+ return;
#endif
+ hideValidationMessage();
}
-void WebPageProxy::runOpenPanel(uint64_t frameID, const FileChooserSettings& settings)
+void WebPageProxy::runOpenPanel(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, const FileChooserSettings& settings)
{
if (m_openPanelResultListener) {
m_openPanelResultListener->invalidate();
- m_openPanelResultListener = 0;
+ m_openPanelResultListener = nullptr;
}
WebFrameProxy* frame = m_process->webFrame(frameID);
MESSAGE_CHECK(frame);
- RefPtr<WebOpenPanelParameters> parameters = WebOpenPanelParameters::create(settings);
+ Ref<API::OpenPanelParameters> parameters = API::OpenPanelParameters::create(settings);
m_openPanelResultListener = WebOpenPanelResultListenerProxy::create(this);
// Since runOpenPanel() can spin a nested run loop we need to turn off the responsiveness timer.
- m_process->responsivenessTimer()->stop();
+ m_process->responsivenessTimer().stop();
- if (!m_uiClient.runOpenPanel(this, frame, parameters.get(), m_openPanelResultListener.get()))
- didCancelForOpenPanel();
+
+ if (!m_uiClient->runOpenPanel(this, frame, frameSecurityOrigin, parameters.ptr(), m_openPanelResultListener.get())) {
+ if (!m_pageClient.handleRunOpenPanel(this, frame, parameters.ptr(), m_openPanelResultListener.get()))
+ didCancelForOpenPanel();
+ }
}
void WebPageProxy::printFrame(uint64_t frameID)
@@ -2820,7 +4175,7 @@ void WebPageProxy::printFrame(uint64_t frameID)
WebFrameProxy* frame = m_process->webFrame(frameID);
MESSAGE_CHECK(frame);
- m_uiClient.printFrame(this, frame);
+ m_uiClient->printFrame(this, frame);
endPrinting(); // Send a message synchronously while m_isPerformingDOMPrintOperation is still true.
m_isPerformingDOMPrintOperation = false;
@@ -2844,6 +4199,39 @@ void WebPageProxy::setMediaVolume(float volume)
m_process->send(Messages::WebPage::SetMediaVolume(volume), m_pageID);
}
+void WebPageProxy::setMuted(WebCore::MediaProducer::MutedStateFlags state)
+{
+ if (m_mutedState == state)
+ return;
+
+ m_mutedState = state;
+
+ if (!isValid())
+ return;
+
+ m_process->send(Messages::WebPage::SetMuted(state), m_pageID);
+
+ activityStateDidChange(ActivityState::IsAudible);
+}
+
+#if ENABLE(MEDIA_SESSION)
+void WebPageProxy::handleMediaEvent(MediaEventType eventType)
+{
+ if (!isValid())
+ return;
+
+ m_process->send(Messages::WebPage::HandleMediaEvent(eventType), m_pageID);
+}
+
+void WebPageProxy::setVolumeOfMediaElement(double volume, uint64_t elementID)
+{
+ if (!isValid())
+ return;
+
+ m_process->send(Messages::WebPage::SetVolumeOfMediaElement(volume, elementID), m_pageID);
+}
+#endif
+
void WebPageProxy::setMayStartMediaWhenInWindow(bool mayStartMedia)
{
if (mayStartMedia == m_mayStartMediaWhenInWindow)
@@ -2857,26 +4245,15 @@ void WebPageProxy::setMayStartMediaWhenInWindow(bool mayStartMedia)
process().send(Messages::WebPage::SetMayStartMediaWhenInWindow(mayStartMedia), m_pageID);
}
-#if PLATFORM(EFL) || PLATFORM(GTK)
void WebPageProxy::handleDownloadRequest(DownloadProxy* download)
{
m_pageClient.handleDownloadRequest(download);
}
-#endif // PLATFORM(EFL) || PLATFORM(GTK)
-#if PLATFORM(EFL) || PLATFORM(IOS)
void WebPageProxy::didChangeContentSize(const IntSize& size)
{
m_pageClient.didChangeContentSize(size);
}
-#endif
-
-#if ENABLE(TOUCH_EVENTS)
-void WebPageProxy::needTouchEvents(bool needTouchEvents)
-{
- m_needTouchEvents = needTouchEvents;
-}
-#endif
#if ENABLE(INPUT_TYPE_COLOR)
void WebPageProxy::showColorPicker(const WebCore::Color& initialColor, const IntRect& elementRect)
@@ -2884,7 +4261,7 @@ void WebPageProxy::showColorPicker(const WebCore::Color& initialColor, const Int
#if ENABLE(INPUT_TYPE_COLOR_POPOVER)
// A new popover color well needs to be created (and the previous one destroyed) for
// each activation of a color element.
- m_colorPicker = 0;
+ m_colorPicker = nullptr;
#endif
if (!m_colorPicker)
m_colorPicker = m_pageClient.createColorPicker(this, initialColor, elementRect);
@@ -2918,40 +4295,80 @@ void WebPageProxy::didEndColorPicker()
if (!isValid())
return;
+#if ENABLE(INPUT_TYPE_COLOR)
if (m_colorPicker) {
m_colorPicker->invalidate();
m_colorPicker = nullptr;
}
+#endif
m_process->send(Messages::WebPage::DidEndColorPicker(), m_pageID);
}
#endif
-void WebPageProxy::didDraw()
-{
- m_uiClient.didDraw(this);
-}
-
// Inspector
-
-#if ENABLE(INSPECTOR)
-
-WebInspectorProxy* WebPageProxy::inspector()
+WebInspectorProxy* WebPageProxy::inspector() const
{
if (isClosed() || !isValid())
return 0;
return m_inspector.get();
}
-#endif
-
#if ENABLE(FULLSCREEN_API)
WebFullScreenManagerProxy* WebPageProxy::fullScreenManager()
{
return m_fullScreenManager.get();
}
+
+void WebPageProxy::setFullscreenClient(std::unique_ptr<API::FullscreenClient> client)
+{
+ m_fullscreenClient = WTFMove(client);
+}
+#endif
+
+#if (PLATFORM(IOS) && HAVE(AVKIT)) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
+WebPlaybackSessionManagerProxy* WebPageProxy::playbackSessionManager()
+{
+ return m_playbackSessionManager.get();
+}
+
+WebVideoFullscreenManagerProxy* WebPageProxy::videoFullscreenManager()
+{
+ return m_videoFullscreenManager.get();
+}
+#endif
+
+#if PLATFORM(IOS)
+bool WebPageProxy::allowsMediaDocumentInlinePlayback() const
+{
+ return m_allowsMediaDocumentInlinePlayback;
+}
+
+void WebPageProxy::setAllowsMediaDocumentInlinePlayback(bool allows)
+{
+ if (m_allowsMediaDocumentInlinePlayback == allows)
+ return;
+ m_allowsMediaDocumentInlinePlayback = allows;
+
+ m_process->send(Messages::WebPage::SetAllowsMediaDocumentInlinePlayback(allows), m_pageID);
+}
#endif
+void WebPageProxy::setHasHadSelectionChangesFromUserInteraction(bool hasHadUserSelectionChanges)
+{
+ m_hasHadSelectionChangesFromUserInteraction = hasHadUserSelectionChanges;
+}
+
+void WebPageProxy::setNeedsHiddenContentEditableQuirk(bool needsHiddenContentEditableQuirk)
+{
+ m_needsHiddenContentEditableQuirk = needsHiddenContentEditableQuirk;
+}
+
+void WebPageProxy::setNeedsPlainTextQuirk(bool needsPlainTextQuirk)
+{
+ m_needsPlainTextQuirk = needsPlainTextQuirk;
+}
+
// BackForwardList
void WebPageProxy::backForwardAddItem(uint64_t itemID)
@@ -2987,40 +4404,10 @@ void WebPageProxy::backForwardForwardListCount(int32_t& count)
count = m_backForwardList->forwardListCount();
}
-void WebPageProxy::editorStateChanged(const EditorState& editorState)
+void WebPageProxy::compositionWasCanceled()
{
-#if PLATFORM(MAC)
- bool couldChangeSecureInputState = m_editorState.isInPasswordField != editorState.isInPasswordField || m_editorState.selectionIsNone;
- bool closedComposition = !editorState.shouldIgnoreCompositionSelectionChange && !editorState.hasComposition && (m_editorState.hasComposition || m_temporarilyClosedComposition);
- m_temporarilyClosedComposition = editorState.shouldIgnoreCompositionSelectionChange && (m_temporarilyClosedComposition || m_editorState.hasComposition) && !editorState.hasComposition;
-#endif
-
- m_editorState = editorState;
-
-#if PLATFORM(MAC)
- // Selection being none is a temporary state when editing. Flipping secure input state too quickly was causing trouble (not fully understood).
- if (couldChangeSecureInputState && !editorState.selectionIsNone)
- m_pageClient.updateSecureInputState();
-
- if (editorState.shouldIgnoreCompositionSelectionChange)
- return;
-
- if (closedComposition)
- m_pageClient.notifyInputContextAboutDiscardedComposition();
- if (editorState.hasComposition) {
- // Abandon the current inline input session if selection changed for any other reason but an input method changing the composition.
- // FIXME: This logic should be in WebCore, no need to round-trip to UI process to cancel the composition.
- cancelComposition();
- m_pageClient.notifyInputContextAboutDiscardedComposition();
- }
-#if PLATFORM(IOS)
- else {
- // We need to notify the client on iOS to make sure the selection is redrawn.
- notifyRevealedSelection();
- }
-#endif
-#elif PLATFORM(EFL) || PLATFORM(GTK)
- m_pageClient.updateTextInputState();
+#if PLATFORM(COCOA)
+ m_pageClient.notifyInputContextAboutDiscardedComposition();
#endif
}
@@ -3030,6 +4417,13 @@ void WebPageProxy::registerEditCommandForUndo(uint64_t commandID, uint32_t editA
{
registerEditCommand(WebEditCommandProxy::create(commandID, static_cast<EditAction>(editAction), this), Undo);
}
+
+void WebPageProxy::registerInsertionUndoGrouping()
+{
+#if USE(INSERTION_UNDO_GROUPING)
+ m_pageClient.registerInsertionUndoGrouping();
+#endif
+}
void WebPageProxy::canUndoRedo(uint32_t action, bool& result)
{
@@ -3049,51 +4443,65 @@ void WebPageProxy::clearAllEditCommands()
void WebPageProxy::didCountStringMatches(const String& string, uint32_t matchCount)
{
- m_findClient.didCountStringMatches(this, string, matchCount);
+ m_findClient->didCountStringMatches(this, string, matchCount);
}
void WebPageProxy::didGetImageForFindMatch(const ShareableBitmap::Handle& contentImageHandle, uint32_t matchIndex)
{
- m_findMatchesClient.didGetImageForMatchResult(this, WebImage::create(ShareableBitmap::create(contentImageHandle)).get(), matchIndex);
+ auto bitmap = ShareableBitmap::create(contentImageHandle);
+ if (!bitmap) {
+ ASSERT_NOT_REACHED();
+ return;
+ }
+ m_findMatchesClient->didGetImageForMatchResult(this, WebImage::create(bitmap.releaseNonNull()).ptr(), matchIndex);
}
-void WebPageProxy::setFindIndicator(const FloatRect& selectionRectInWindowCoordinates, const Vector<FloatRect>& textRectsInSelectionRectCoordinates, float contentImageScaleFactor, const ShareableBitmap::Handle& contentImageHandle, bool fadeOut, bool animate)
+void WebPageProxy::setTextIndicator(const TextIndicatorData& indicatorData, uint64_t lifetime)
{
- RefPtr<FindIndicator> findIndicator = FindIndicator::create(selectionRectInWindowCoordinates, textRectsInSelectionRectCoordinates, contentImageScaleFactor, contentImageHandle);
- m_pageClient.setFindIndicator(findIndicator.release(), fadeOut, animate);
+ // FIXME: Make TextIndicatorWindow a platform-independent presentational thing ("TextIndicatorPresentation"?).
+#if PLATFORM(COCOA)
+ m_pageClient.setTextIndicator(TextIndicator::create(indicatorData), static_cast<TextIndicatorWindowLifetime>(lifetime));
+#else
+ ASSERT_NOT_REACHED();
+#endif
}
-void WebPageProxy::didFindString(const String& string, uint32_t matchCount)
+void WebPageProxy::clearTextIndicator()
{
- m_findClient.didFindString(this, string, matchCount);
+#if PLATFORM(COCOA)
+ m_pageClient.clearTextIndicator(TextIndicatorWindowDismissalAnimation::FadeOut);
+#else
+ ASSERT_NOT_REACHED();
+#endif
}
-void WebPageProxy::didFindStringMatches(const String& string, Vector<Vector<WebCore::IntRect>> matchRects, int32_t firstIndexAfterSelection)
+void WebPageProxy::setTextIndicatorAnimationProgress(float progress)
{
- Vector<RefPtr<API::Object>> matches;
- matches.reserveInitialCapacity(matchRects.size());
-
- for (const auto& rects : matchRects) {
- Vector<RefPtr<API::Object>> apiRects;
- apiRects.reserveInitialCapacity(rects.size());
-
- for (const auto& rect : rects)
- apiRects.uncheckedAppend(API::Rect::create(toAPI(rect)));
+#if PLATFORM(COCOA)
+ m_pageClient.setTextIndicatorAnimationProgress(progress);
+#else
+ ASSERT_NOT_REACHED();
+#endif
+}
- matches.uncheckedAppend(API::Array::create(std::move(apiRects)));
- }
+void WebPageProxy::didFindString(const String& string, const Vector<WebCore::IntRect>& matchRects, uint32_t matchCount, int32_t matchIndex)
+{
+ m_findClient->didFindString(this, string, matchRects, matchCount, matchIndex);
+}
- m_findMatchesClient.didFindStringMatches(this, string, API::Array::create(std::move(matches)).get(), firstIndexAfterSelection);
+void WebPageProxy::didFindStringMatches(const String& string, const Vector<Vector<WebCore::IntRect>>& matchRects, int32_t firstIndexAfterSelection)
+{
+ m_findMatchesClient->didFindStringMatches(this, string, matchRects, firstIndexAfterSelection);
}
void WebPageProxy::didFailToFindString(const String& string)
{
- m_findClient.didFailToFindString(this, string);
+ m_findClient->didFailToFindString(this, string);
}
-bool WebPageProxy::sendMessage(std::unique_ptr<IPC::MessageEncoder> encoder, unsigned messageSendFlags)
+bool WebPageProxy::sendMessage(std::unique_ptr<IPC::Encoder> encoder, OptionSet<IPC::SendOption> sendOptions)
{
- return m_process->sendMessage(std::move(encoder), messageSendFlags);
+ return m_process->sendMessage(WTFMove(encoder), sendOptions);
}
IPC::Connection* WebPageProxy::messageSenderConnection()
@@ -3123,7 +4531,7 @@ NativeWebMouseEvent* WebPageProxy::currentlyProcessedMouseDownEvent()
void WebPageProxy::postMessageToInjectedBundle(const String& messageName, API::Object* messageBody)
{
- process().send(Messages::WebPage::PostInjectedBundleMessage(messageName, WebContextUserMessageEncoder(messageBody, process())), m_pageID);
+ process().send(Messages::WebPage::PostInjectedBundleMessage(messageName, UserData(process().transformObjectsToHandles(messageBody).get())), m_pageID);
}
#if PLATFORM(GTK)
@@ -3136,36 +4544,22 @@ void WebPageProxy::failedToShowPopupMenu()
void WebPageProxy::showPopupMenu(const IntRect& rect, uint64_t textDirection, const Vector<WebPopupItem>& items, int32_t selectedIndex, const PlatformPopupMenuData& data)
{
if (m_activePopupMenu) {
-#if PLATFORM(EFL)
- m_uiPopupMenuClient.hidePopupMenu(this);
-#else
m_activePopupMenu->hidePopupMenu();
-#endif
m_activePopupMenu->invalidate();
- m_activePopupMenu = 0;
+ m_activePopupMenu = nullptr;
}
- m_activePopupMenu = m_pageClient.createPopupMenuProxy(this);
+ m_activePopupMenu = m_pageClient.createPopupMenuProxy(*this);
if (!m_activePopupMenu)
return;
// Since showPopupMenu() can spin a nested run loop we need to turn off the responsiveness timer.
- m_process->responsivenessTimer()->stop();
-
-#if PLATFORM(EFL)
- UNUSED_PARAM(data);
- m_uiPopupMenuClient.showPopupMenu(this, m_activePopupMenu.get(), rect, static_cast<TextDirection>(textDirection), m_pageScaleFactor, items, selectedIndex);
-#else
- RefPtr<WebPopupMenuProxy> protectedActivePopupMenu = m_activePopupMenu;
-
- protectedActivePopupMenu->showPopupMenu(rect, static_cast<TextDirection>(textDirection), m_pageScaleFactor, items, data, selectedIndex);
+ m_process->responsivenessTimer().stop();
- // Since Efl doesn't use a nested mainloop to show the popup and get the answer, we need to keep the client pointer valid.
- // FIXME: The above comment doesn't make any sense since this code is compiled out for EFL.
- protectedActivePopupMenu->invalidate();
- protectedActivePopupMenu = 0;
-#endif
+ // Showing a popup menu runs a nested runloop, which can handle messages that cause |this| to get closed.
+ Ref<WebPageProxy> protect(*this);
+ m_activePopupMenu->showPopupMenu(rect, static_cast<TextDirection>(textDirection), m_pageScaleFactor, items, data, selectedIndex);
}
void WebPageProxy::hidePopupMenu()
@@ -3173,65 +4567,46 @@ void WebPageProxy::hidePopupMenu()
if (!m_activePopupMenu)
return;
-#if PLATFORM(EFL)
- m_uiPopupMenuClient.hidePopupMenu(this);
-#else
m_activePopupMenu->hidePopupMenu();
-#endif
m_activePopupMenu->invalidate();
- m_activePopupMenu = 0;
+ m_activePopupMenu = nullptr;
}
#if ENABLE(CONTEXT_MENUS)
-void WebPageProxy::showContextMenu(const IntPoint& menuLocation, const WebHitTestResult::Data& hitTestResultData, const Vector<WebContextMenuItemData>& proposedItems, IPC::MessageDecoder& decoder)
+void WebPageProxy::showContextMenu(const ContextMenuContextData& contextMenuContextData, const UserData& userData)
{
- internalShowContextMenu(menuLocation, hitTestResultData, proposedItems, decoder);
+ // Showing a context menu runs a nested runloop, which can handle messages that cause |this| to get closed.
+ Ref<WebPageProxy> protect(*this);
+
+ internalShowContextMenu(contextMenuContextData, userData);
// No matter the result of internalShowContextMenu, always notify the WebProcess that the menu is hidden so it starts handling mouse events again.
m_process->send(Messages::WebPage::ContextMenuHidden(), m_pageID);
}
-void WebPageProxy::internalShowContextMenu(const IntPoint& menuLocation, const WebHitTestResult::Data& hitTestResultData, const Vector<WebContextMenuItemData>& proposedItems, IPC::MessageDecoder& decoder)
+void WebPageProxy::internalShowContextMenu(const ContextMenuContextData& contextMenuContextData, const UserData& userData)
{
- RefPtr<API::Object> userData;
- WebContextUserMessageDecoder messageDecoder(userData, process());
- if (!decoder.decode(messageDecoder))
- return;
-
- m_activeContextMenuHitTestResultData = hitTestResultData;
-
- if (!m_contextMenuClient.hideContextMenu(this) && m_activeContextMenu) {
- m_activeContextMenu->hideContextMenu();
- m_activeContextMenu = 0;
- }
+ m_activeContextMenuContextData = contextMenuContextData;
- m_activeContextMenu = m_pageClient.createContextMenuProxy(this);
+ m_activeContextMenu = m_pageClient.createContextMenuProxy(*this, contextMenuContextData, userData);
if (!m_activeContextMenu)
return;
// Since showContextMenu() can spin a nested run loop we need to turn off the responsiveness timer.
- m_process->responsivenessTimer()->stop();
-
- // Give the PageContextMenuClient one last swipe at changing the menu.
- Vector<WebContextMenuItemData> items;
- if (!m_contextMenuClient.getContextMenuFromProposedMenu(this, proposedItems, items, hitTestResultData, userData.get())) {
- if (!m_contextMenuClient.showContextMenu(this, menuLocation, proposedItems))
- m_activeContextMenu->showContextMenu(menuLocation, proposedItems);
- } else if (!m_contextMenuClient.showContextMenu(this, menuLocation, items))
- m_activeContextMenu->showContextMenu(menuLocation, items);
-
- m_contextMenuClient.contextMenuDismissed(this);
+ m_process->responsivenessTimer().stop();
+
+ m_activeContextMenu->show();
}
void WebPageProxy::contextMenuItemSelected(const WebContextMenuItemData& item)
{
// Application custom items don't need to round-trip through to WebCore in the WebProcess.
if (item.action() >= ContextMenuItemBaseApplicationTag) {
- m_contextMenuClient.customContextMenuItemSelected(this, item);
+ m_contextMenuClient->customContextMenuItemSelected(*this, item);
return;
}
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
if (item.action() == ContextMenuItemTagSmartCopyPaste) {
setSmartInsertDeleteEnabled(!isSmartInsertDeleteEnabled());
return;
@@ -3267,15 +4642,16 @@ void WebPageProxy::contextMenuItemSelected(const WebContextMenuItemData& item)
}
#endif
if (item.action() == ContextMenuItemTagDownloadImageToDisk) {
- m_process->context().download(this, URL(URL(), m_activeContextMenuHitTestResultData.absoluteImageURL));
+ m_process->processPool().download(this, URL(URL(), m_activeContextMenuContextData.webHitTestResultData().absoluteImageURL));
return;
}
if (item.action() == ContextMenuItemTagDownloadLinkToDisk) {
- m_process->context().download(this, URL(URL(), m_activeContextMenuHitTestResultData.absoluteLinkURL));
+ auto& hitTestResult = m_activeContextMenuContextData.webHitTestResultData();
+ m_process->processPool().download(this, URL(URL(), hitTestResult.absoluteLinkURL), hitTestResult.linkSuggestedFilename);
return;
}
if (item.action() == ContextMenuItemTagDownloadMediaToDisk) {
- m_process->context().download(this, URL(URL(), m_activeContextMenuHitTestResultData.absoluteMediaURL));
+ m_process->processPool().download(this, URL(URL(), m_activeContextMenuContextData.webHitTestResultData().absoluteMediaURL));
return;
}
if (item.action() == ContextMenuItemTagCheckSpellingWhileTyping) {
@@ -3299,14 +4675,20 @@ void WebPageProxy::contextMenuItemSelected(const WebContextMenuItemData& item)
m_process->send(Messages::WebPage::DidSelectItemFromActiveContextMenu(item), m_pageID);
}
+
+void WebPageProxy::handleContextMenuKeyEvent()
+{
+ m_process->send(Messages::WebPage::ContextMenuForKeyEvent(), m_pageID);
+}
#endif // ENABLE(CONTEXT_MENUS)
-void WebPageProxy::didChooseFilesForOpenPanel(const Vector<String>& fileURLs)
+#if PLATFORM(IOS)
+void WebPageProxy::didChooseFilesForOpenPanelWithDisplayStringAndIcon(const Vector<String>& fileURLs, const String& displayString, const API::Data* iconData)
{
if (!isValid())
return;
-#if ENABLE(WEB_PROCESS_SANDBOX)
+#if ENABLE(SANDBOX_EXTENSIONS)
// FIXME: The sandbox extensions should be sent with the DidChooseFilesForOpenPanel message. This
// is gated on a way of passing SandboxExtension::Handles in a Vector.
for (size_t i = 0; i < fileURLs.size(); ++i) {
@@ -3316,10 +4698,38 @@ void WebPageProxy::didChooseFilesForOpenPanel(const Vector<String>& fileURLs)
}
#endif
+ m_process->send(Messages::WebPage::DidChooseFilesForOpenPanelWithDisplayStringAndIcon(fileURLs, displayString, iconData ? iconData->dataReference() : IPC::DataReference()), m_pageID);
+
+ m_openPanelResultListener->invalidate();
+ m_openPanelResultListener = nullptr;
+}
+#endif
+
+void WebPageProxy::didChooseFilesForOpenPanel(const Vector<String>& fileURLs)
+{
+ if (!isValid())
+ return;
+
+#if ENABLE(SANDBOX_EXTENSIONS)
+ // FIXME: The sandbox extensions should be sent with the DidChooseFilesForOpenPanel message. This
+ // is gated on a way of passing SandboxExtension::Handles in a Vector.
+ for (size_t i = 0; i < fileURLs.size(); ++i) {
+ SandboxExtension::Handle sandboxExtensionHandle;
+ bool createdExtension = SandboxExtension::createHandle(fileURLs[i], SandboxExtension::ReadOnly, sandboxExtensionHandle);
+ if (!createdExtension) {
+ // This can legitimately fail if a directory containing the file is deleted after the file was chosen.
+ // We also have reports of cases where this likely fails for some unknown reason, <rdar://problem/10156710>.
+ WTFLogAlways("WebPageProxy::didChooseFilesForOpenPanel: could not create a sandbox extension for '%s'\n", fileURLs[i].utf8().data());
+ continue;
+ }
+ m_process->send(Messages::WebPage::ExtendSandboxForFileFromOpenPanel(sandboxExtensionHandle), m_pageID);
+ }
+#endif
+
m_process->send(Messages::WebPage::DidChooseFilesForOpenPanel(fileURLs), m_pageID);
m_openPanelResultListener->invalidate();
- m_openPanelResultListener = 0;
+ m_openPanelResultListener = nullptr;
}
void WebPageProxy::didCancelForOpenPanel()
@@ -3330,7 +4740,7 @@ void WebPageProxy::didCancelForOpenPanel()
m_process->send(Messages::WebPage::DidCancelForOpenPanel(), m_pageID);
m_openPanelResultListener->invalidate();
- m_openPanelResultListener = 0;
+ m_openPanelResultListener = nullptr;
}
void WebPageProxy::advanceToNextMisspelling(bool startBeforeSelection)
@@ -3381,20 +4791,20 @@ int64_t WebPageProxy::spellDocumentTag()
}
#if USE(UNIFIED_TEXT_CHECKING)
-void WebPageProxy::checkTextOfParagraph(const String& text, uint64_t checkingTypes, Vector<TextCheckingResult>& results)
+void WebPageProxy::checkTextOfParagraph(const String& text, uint64_t checkingTypes, int32_t insertionPoint, Vector<TextCheckingResult>& results)
{
- results = TextChecker::checkTextOfParagraph(spellDocumentTag(), text.deprecatedCharacters(), text.length(), checkingTypes);
+ results = TextChecker::checkTextOfParagraph(spellDocumentTag(), text, insertionPoint, checkingTypes, m_initialCapitalizationEnabled);
}
#endif
void WebPageProxy::checkSpellingOfString(const String& text, int32_t& misspellingLocation, int32_t& misspellingLength)
{
- TextChecker::checkSpellingOfString(spellDocumentTag(), text.deprecatedCharacters(), text.length(), misspellingLocation, misspellingLength);
+ TextChecker::checkSpellingOfString(spellDocumentTag(), text, misspellingLocation, misspellingLength);
}
void WebPageProxy::checkGrammarOfString(const String& text, Vector<GrammarDetail>& grammarDetails, int32_t& badGrammarLocation, int32_t& badGrammarLength)
{
- TextChecker::checkGrammarOfString(spellDocumentTag(), text.deprecatedCharacters(), text.length(), grammarDetails, badGrammarLocation, badGrammarLength);
+ TextChecker::checkGrammarOfString(spellDocumentTag(), text, grammarDetails, badGrammarLocation, badGrammarLength);
}
void WebPageProxy::spellingUIIsShowing(bool& isShowing)
@@ -3412,9 +4822,9 @@ void WebPageProxy::updateSpellingUIWithGrammarString(const String& badGrammarPhr
TextChecker::updateSpellingUIWithGrammarString(spellDocumentTag(), badGrammarPhrase, grammarDetail);
}
-void WebPageProxy::getGuessesForWord(const String& word, const String& context, Vector<String>& guesses)
+void WebPageProxy::getGuessesForWord(const String& word, const String& context, int32_t insertionPoint, Vector<String>& guesses)
{
- TextChecker::getGuessesForWord(spellDocumentTag(), word, context, guesses);
+ TextChecker::getGuessesForWord(spellDocumentTag(), word, context, insertionPoint, guesses, m_initialCapitalizationEnabled);
}
void WebPageProxy::learnWord(const String& word)
@@ -3433,9 +4843,9 @@ void WebPageProxy::ignoreWord(const String& word)
TextChecker::ignoreWord(spellDocumentTag(), word);
}
-void WebPageProxy::requestCheckingOfString(uint64_t requestID, const TextCheckingRequestData& request)
+void WebPageProxy::requestCheckingOfString(uint64_t requestID, const TextCheckingRequestData& request, int32_t insertionPoint)
{
- TextChecker::requestCheckingOfString(TextCheckerCompletion::create(requestID, request, this));
+ TextChecker::requestCheckingOfString(TextCheckerCompletion::create(requestID, request, this), insertionPoint);
}
void WebPageProxy::didFinishCheckingText(uint64_t requestID, const Vector<WebCore::TextCheckingResult>& result)
@@ -3452,14 +4862,14 @@ void WebPageProxy::didCancelCheckingText(uint64_t requestID)
void WebPageProxy::setFocus(bool focused)
{
if (focused)
- m_uiClient.focus(this);
+ m_uiClient->focus(this);
else
- m_uiClient.unfocus(this);
+ m_uiClient->unfocus(this);
}
void WebPageProxy::takeFocus(uint32_t direction)
{
- m_uiClient.takeFocus(this, (static_cast<FocusDirection>(direction) == FocusDirectionForward) ? kWKFocusDirectionForward : kWKFocusDirectionBackward);
+ m_uiClient->takeFocus(this, (static_cast<FocusDirection>(direction) == FocusDirectionForward) ? kWKFocusDirectionForward : kWKFocusDirectionBackward);
}
void WebPageProxy::setToolTip(const String& toolTip)
@@ -3489,11 +4899,14 @@ void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled)
switch (type) {
case WebEvent::NoType:
case WebEvent::MouseMove:
+ case WebEvent::Wheel:
break;
case WebEvent::MouseDown:
case WebEvent::MouseUp:
- case WebEvent::Wheel:
+ case WebEvent::MouseForceChanged:
+ case WebEvent::MouseForceDown:
+ case WebEvent::MouseForceUp:
case WebEvent::KeyDown:
case WebEvent::KeyUp:
case WebEvent::RawKeyDown:
@@ -3504,7 +4917,12 @@ void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled)
case WebEvent::TouchEnd:
case WebEvent::TouchCancel:
#endif
- m_process->responsivenessTimer()->stop();
+#if ENABLE(MAC_GESTURE_EVENTS)
+ case WebEvent::GestureStart:
+ case WebEvent::GestureChange:
+ case WebEvent::GestureEnd:
+#endif
+ m_process->responsivenessTimer().stop();
break;
}
@@ -3513,29 +4931,29 @@ void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled)
break;
case WebEvent::MouseMove:
m_processingMouseMoveEvent = false;
- if (m_nextMouseMoveEvent) {
- handleMouseEvent(*m_nextMouseMoveEvent);
- m_nextMouseMoveEvent = nullptr;
- }
+ if (m_nextMouseMoveEvent)
+ handleMouseEvent(*std::exchange(m_nextMouseMoveEvent, nullptr));
break;
case WebEvent::MouseDown:
break;
case WebEvent::MouseUp:
m_currentlyProcessedMouseDownEvent = nullptr;
break;
+ case WebEvent::MouseForceChanged:
+ case WebEvent::MouseForceDown:
+ case WebEvent::MouseForceUp:
+ break;
case WebEvent::Wheel: {
MESSAGE_CHECK(!m_currentlyProcessedWheelEvents.isEmpty());
- OwnPtr<Vector<NativeWebWheelEvent>> oldestCoalescedEvent = m_currentlyProcessedWheelEvents.takeFirst();
+ std::unique_ptr<Vector<NativeWebWheelEvent>> oldestCoalescedEvent = m_currentlyProcessedWheelEvents.takeFirst();
// FIXME: Dispatch additional events to the didNotHandleWheelEvent client function.
if (!handled) {
- if (m_uiClient.implementsDidNotHandleWheelEvent())
- m_uiClient.didNotHandleWheelEvent(this, oldestCoalescedEvent->last());
-#if PLATFORM(MAC)
+ if (m_uiClient->implementsDidNotHandleWheelEvent())
+ m_uiClient->didNotHandleWheelEvent(this, oldestCoalescedEvent->last());
m_pageClient.wheelEventWasNotHandledByWebCore(oldestCoalescedEvent->last());
-#endif
}
if (!m_wheelEventQueue.isEmpty())
@@ -3547,25 +4965,55 @@ void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled)
case WebEvent::KeyUp:
case WebEvent::RawKeyDown:
case WebEvent::Char: {
- LOG(KeyHandling, "WebPageProxy::didReceiveEvent: %s", webKeyboardEventTypeString(type));
+ LOG(KeyHandling, "WebPageProxy::didReceiveEvent: %s (queue empty %d)", webKeyboardEventTypeString(type), m_keyEventQueue.isEmpty());
MESSAGE_CHECK(!m_keyEventQueue.isEmpty());
NativeWebKeyboardEvent event = m_keyEventQueue.takeFirst();
MESSAGE_CHECK(type == event.type());
- if (!m_keyEventQueue.isEmpty())
+ if (!m_keyEventQueue.isEmpty()) {
+ LOG(KeyHandling, " UI process: sent keyEvent from didReceiveEvent");
m_process->send(Messages::WebPage::KeyEvent(m_keyEventQueue.first()), m_pageID);
+ } else {
+ if (auto* automationSession = process().processPool().automationSession())
+ automationSession->keyboardEventsFlushedForPage(*this);
+ }
+
+ // The call to doneWithKeyEvent may close this WebPage.
+ // Protect against this being destroyed.
+ Ref<WebPageProxy> protect(*this);
m_pageClient.doneWithKeyEvent(event, handled);
if (handled)
break;
- if (m_uiClient.implementsDidNotHandleKeyEvent())
- m_uiClient.didNotHandleKeyEvent(this, event);
+ if (m_uiClient->implementsDidNotHandleKeyEvent())
+ m_uiClient->didNotHandleKeyEvent(this, event);
break;
}
-#if ENABLE(TOUCH_EVENTS)
+#if ENABLE(MAC_GESTURE_EVENTS)
+ case WebEvent::GestureStart:
+ case WebEvent::GestureChange:
+ case WebEvent::GestureEnd: {
+ MESSAGE_CHECK(!m_gestureEventQueue.isEmpty());
+ NativeWebGestureEvent event = m_gestureEventQueue.takeFirst();
+
+ MESSAGE_CHECK(type == event.type());
+
+ if (!handled)
+ m_pageClient.gestureEventWasNotHandledByWebCore(event);
+ break;
+ }
+ break;
+#endif
+#if ENABLE(IOS_TOUCH_EVENTS)
+ case WebEvent::TouchStart:
+ case WebEvent::TouchMove:
+ case WebEvent::TouchEnd:
+ case WebEvent::TouchCancel:
+ break;
+#elif ENABLE(TOUCH_EVENTS)
case WebEvent::TouchStart:
case WebEvent::TouchMove:
case WebEvent::TouchEnd:
@@ -3588,12 +5036,12 @@ void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled)
void WebPageProxy::stopResponsivenessTimer()
{
- m_process->responsivenessTimer()->stop();
+ m_process->responsivenessTimer().stop();
}
void WebPageProxy::voidCallback(uint64_t callbackID)
{
- RefPtr<VoidCallback> callback = m_voidCallbacks.take(callbackID);
+ auto callback = m_callbacks.take<VoidCallback>(callbackID);
if (!callback) {
// FIXME: Log error or assert.
return;
@@ -3604,18 +5052,18 @@ void WebPageProxy::voidCallback(uint64_t callbackID)
void WebPageProxy::dataCallback(const IPC::DataReference& dataReference, uint64_t callbackID)
{
- RefPtr<DataCallback> callback = m_dataCallbacks.take(callbackID);
+ auto callback = m_callbacks.take<DataCallback>(callbackID);
if (!callback) {
// FIXME: Log error or assert.
return;
}
- callback->performCallbackWithReturnValue(API::Data::create(dataReference.data(), dataReference.size()).get());
+ callback->performCallbackWithReturnValue(API::Data::create(dataReference.data(), dataReference.size()).ptr());
}
void WebPageProxy::imageCallback(const ShareableBitmap::Handle& bitmapHandle, uint64_t callbackID)
{
- RefPtr<ImageCallback> callback = m_imageCallbacks.take(callbackID);
+ auto callback = m_callbacks.take<ImageCallback>(callbackID);
if (!callback) {
// FIXME: Log error or assert.
return;
@@ -3626,7 +5074,7 @@ void WebPageProxy::imageCallback(const ShareableBitmap::Handle& bitmapHandle, ui
void WebPageProxy::stringCallback(const String& resultString, uint64_t callbackID)
{
- RefPtr<StringCallback> callback = m_stringCallbacks.take(callbackID);
+ auto callback = m_callbacks.take<StringCallback>(callbackID);
if (!callback) {
// FIXME: Log error or assert.
// this can validly happen if a load invalidated the callback, though
@@ -3638,11 +5086,30 @@ void WebPageProxy::stringCallback(const String& resultString, uint64_t callbackI
callback->performCallbackWithReturnValue(resultString.impl());
}
-void WebPageProxy::scriptValueCallback(const IPC::DataReference& dataReference, uint64_t callbackID)
+void WebPageProxy::invalidateStringCallback(uint64_t callbackID)
{
- RefPtr<ScriptValueCallback> callback = m_scriptValueCallbacks.take(callbackID);
+ auto callback = m_callbacks.take<StringCallback>(callbackID);
if (!callback) {
// FIXME: Log error or assert.
+ // this can validly happen if a load invalidated the callback, though
+ return;
+ }
+
+ m_loadDependentStringCallbackIDs.remove(callbackID);
+
+ callback->invalidate();
+}
+
+void WebPageProxy::scriptValueCallback(const IPC::DataReference& dataReference, bool hadException, const ExceptionDetails& details, uint64_t callbackID)
+{
+ auto callback = m_callbacks.take<ScriptValueCallback>(callbackID);
+ if (!callback) {
+ // FIXME: Log error or assert.
+ return;
+ }
+
+ if (dataReference.isEmpty()) {
+ callback->performCallbackWithReturnValue(nullptr, hadException, details);
return;
}
@@ -3650,12 +5117,12 @@ void WebPageProxy::scriptValueCallback(const IPC::DataReference& dataReference,
data.reserveInitialCapacity(dataReference.size());
data.append(dataReference.data(), dataReference.size());
- callback->performCallbackWithReturnValue(data.size() ? WebSerializedScriptValue::adopt(data).get() : 0);
+ callback->performCallbackWithReturnValue(API::SerializedScriptValue::adopt(WTFMove(data)).ptr(), hadException, details);
}
void WebPageProxy::computedPagesCallback(const Vector<IntRect>& pageRects, double totalScaleFactorForPrinting, uint64_t callbackID)
{
- RefPtr<ComputedPagesCallback> callback = m_computedPagesCallbacks.take(callbackID);
+ auto callback = m_callbacks.take<ComputedPagesCallback>(callbackID);
if (!callback) {
// FIXME: Log error or assert.
return;
@@ -3666,7 +5133,7 @@ void WebPageProxy::computedPagesCallback(const Vector<IntRect>& pageRects, doubl
void WebPageProxy::validateCommandCallback(const String& commandName, bool isEnabled, int state, uint64_t callbackID)
{
- RefPtr<ValidateCommandCallback> callback = m_validateCommandCallbacks.take(callbackID);
+ auto callback = m_callbacks.take<ValidateCommandCallback>(callbackID);
if (!callback) {
// FIXME: Log error or assert.
return;
@@ -3675,24 +5142,106 @@ void WebPageProxy::validateCommandCallback(const String& commandName, bool isEna
callback->performCallbackWithReturnValue(commandName.impl(), isEnabled, state);
}
+void WebPageProxy::unsignedCallback(uint64_t result, uint64_t callbackID)
+{
+ auto callback = m_callbacks.take<UnsignedCallback>(callbackID);
+ if (!callback) {
+ // FIXME: Log error or assert.
+ // this can validly happen if a load invalidated the callback, though
+ return;
+ }
+
+ callback->performCallbackWithReturnValue(result);
+}
+
+void WebPageProxy::editingRangeCallback(const EditingRange& range, uint64_t callbackID)
+{
+ MESSAGE_CHECK(range.isValid());
+
+ auto callback = m_callbacks.take<EditingRangeCallback>(callbackID);
+ if (!callback) {
+ // FIXME: Log error or assert.
+ // this can validly happen if a load invalidated the callback, though
+ return;
+ }
+
+ callback->performCallbackWithReturnValue(range);
+}
+
+#if PLATFORM(COCOA)
+void WebPageProxy::machSendRightCallback(const MachSendRight& sendRight, uint64_t callbackID)
+{
+ auto callback = m_callbacks.take<MachSendRightCallback>(callbackID);
+ if (!callback)
+ return;
+
+ callback->performCallbackWithReturnValue(sendRight);
+}
+#endif
+
+void WebPageProxy::logDiagnosticMessage(const String& message, const String& description, WebCore::ShouldSample shouldSample)
+{
+ if (!DiagnosticLoggingClient::shouldLogAfterSampling(shouldSample))
+ return;
+
+ m_diagnosticLoggingClient->logDiagnosticMessage(this, message, description);
+}
+
+void WebPageProxy::logDiagnosticMessageWithResult(const String& message, const String& description, uint32_t result, WebCore::ShouldSample shouldSample)
+{
+ if (!DiagnosticLoggingClient::shouldLogAfterSampling(shouldSample))
+ return;
+
+ m_diagnosticLoggingClient->logDiagnosticMessageWithResult(this, message, description, static_cast<WebCore::DiagnosticLoggingResultType>(result));
+}
+
+void WebPageProxy::logDiagnosticMessageWithValue(const String& message, const String& description, double value, unsigned significantFigures, ShouldSample shouldSample)
+{
+ if (!DiagnosticLoggingClient::shouldLogAfterSampling(shouldSample))
+ return;
+
+ m_diagnosticLoggingClient->logDiagnosticMessageWithValue(this, message, description, String::number(value, significantFigures));
+}
+
+void WebPageProxy::logDiagnosticMessageWithEnhancedPrivacy(const String& message, const String& description, ShouldSample shouldSample)
+{
+ if (!DiagnosticLoggingClient::shouldLogAfterSampling(shouldSample))
+ return;
+
+ m_diagnosticLoggingClient->logDiagnosticMessageWithEnhancedPrivacy(this, message, description);
+}
+
+void WebPageProxy::rectForCharacterRangeCallback(const IntRect& rect, const EditingRange& actualRange, uint64_t callbackID)
+{
+ MESSAGE_CHECK(actualRange.isValid());
+
+ auto callback = m_callbacks.take<RectForCharacterRangeCallback>(callbackID);
+ if (!callback) {
+ // FIXME: Log error or assert.
+ // this can validly happen if a load invalidated the callback, though
+ return;
+ }
+
+ callback->performCallbackWithReturnValue(rect, actualRange);
+}
+
#if PLATFORM(GTK)
void WebPageProxy::printFinishedCallback(const ResourceError& printError, uint64_t callbackID)
{
- RefPtr<PrintFinishedCallback> callback = m_printFinishedCallbacks.take(callbackID);
+ auto callback = m_callbacks.take<PrintFinishedCallback>(callbackID);
if (!callback) {
// FIXME: Log error or assert.
return;
}
- RefPtr<API::Error> error = API::Error::create(printError);
- callback->performCallbackWithReturnValue(error.get());
+ callback->performCallbackWithReturnValue(API::Error::create(printError).ptr());
}
#endif
void WebPageProxy::focusedFrameChanged(uint64_t frameID)
{
if (!frameID) {
- m_focusedFrame = 0;
+ m_focusedFrame = nullptr;
return;
}
@@ -3705,7 +5254,7 @@ void WebPageProxy::focusedFrameChanged(uint64_t frameID)
void WebPageProxy::frameSetLargestFrameChanged(uint64_t frameID)
{
if (!frameID) {
- m_frameSetLargestFrame = 0;
+ m_frameSetLargestFrame = nullptr;
return;
}
@@ -3722,53 +5271,93 @@ void WebPageProxy::processDidBecomeUnresponsive()
updateBackingStoreDiscardableState();
- m_loaderClient->processDidBecomeUnresponsive(this);
+ if (m_navigationClient)
+ m_navigationClient->processDidBecomeUnresponsive(*this);
+ else
+ m_loaderClient->processDidBecomeUnresponsive(*this);
}
-void WebPageProxy::interactionOccurredWhileProcessUnresponsive()
+void WebPageProxy::processDidBecomeResponsive()
{
if (!isValid())
return;
+
+ updateBackingStoreDiscardableState();
- m_loaderClient->interactionOccurredWhileProcessUnresponsive(this);
+ if (m_navigationClient)
+ m_navigationClient->processDidBecomeResponsive(*this);
+ else
+ m_loaderClient->processDidBecomeResponsive(*this);
}
-void WebPageProxy::processDidBecomeResponsive()
+void WebPageProxy::willChangeProcessIsResponsive()
{
- if (!isValid())
- return;
-
- updateBackingStoreDiscardableState();
+ m_pageLoadState.willChangeProcessIsResponsive();
+}
- m_loaderClient->processDidBecomeResponsive(this);
+void WebPageProxy::didChangeProcessIsResponsive()
+{
+ m_pageLoadState.didChangeProcessIsResponsive();
}
void WebPageProxy::processDidCrash()
{
ASSERT(m_isValid);
+ // There is a nested transaction in resetStateAfterProcessExited() that we don't want to commit before the client call.
+ PageLoadState::Transaction transaction = m_pageLoadState.transaction();
+
resetStateAfterProcessExited();
- auto transaction = m_pageLoadState.transaction();
+ navigationState().clearAllNavigations();
- m_pageLoadState.reset(transaction);
+ if (m_navigationClient)
+ m_navigationClient->processDidCrash(*this);
+ else
+ m_loaderClient->processDidCrash(*this);
- m_pageClient.processDidCrash();
+ if (m_controlledByAutomation) {
+ if (auto* automationSession = process().processPool().automationSession())
+ automationSession->terminate();
+ }
+}
+
+#if PLATFORM(IOS)
+void WebPageProxy::processWillBecomeSuspended()
+{
+ if (!isValid())
+ return;
+
+ m_hasNetworkRequestsOnSuspended = m_pageLoadState.networkRequestsInProgress();
+ if (m_hasNetworkRequestsOnSuspended)
+ setNetworkRequestsInProgress(false);
+}
+
+void WebPageProxy::processWillBecomeForeground()
+{
+ if (!isValid())
+ return;
- m_loaderClient->processDidCrash(this);
+ if (m_hasNetworkRequestsOnSuspended) {
+ setNetworkRequestsInProgress(true);
+ m_hasNetworkRequestsOnSuspended = false;
+ }
}
+#endif
-void WebPageProxy::resetState()
+void WebPageProxy::resetState(ResetStateReason resetStateReason)
{
m_mainFrame = nullptr;
+#if PLATFORM(COCOA)
+ m_scrollingPerformanceData = nullptr;
+#endif
m_drawingArea = nullptr;
+ hideValidationMessage();
-#if ENABLE(INSPECTOR)
if (m_inspector) {
m_inspector->invalidate();
m_inspector = nullptr;
}
-#endif
#if ENABLE(FULLSCREEN_API)
if (m_fullScreenManager) {
@@ -3786,6 +5375,10 @@ void WebPageProxy::resetState()
m_openPanelResultListener = nullptr;
}
+#if ENABLE(TOUCH_EVENTS)
+ m_touchEventTracking.reset();
+#endif
+
#if ENABLE(INPUT_TYPE_COLOR)
if (m_colorPicker) {
m_colorPicker->invalidate();
@@ -3797,6 +5390,10 @@ void WebPageProxy::resetState()
m_geolocationPermissionRequestManager.invalidateRequests();
#endif
+#if ENABLE(MEDIA_STREAM)
+ m_userMediaPermissionRequestManager = nullptr;
+#endif
+
m_notificationPermissionRequestManager.invalidateRequests();
m_toolTip = String();
@@ -3804,38 +5401,70 @@ void WebPageProxy::resetState()
m_mainFrameHasHorizontalScrollbar = false;
m_mainFrameHasVerticalScrollbar = false;
- m_mainFrameIsPinnedToLeftSide = false;
- m_mainFrameIsPinnedToRightSide = false;
- m_mainFrameIsPinnedToTopSide = false;
- m_mainFrameIsPinnedToBottomSide = false;
+ m_mainFrameIsPinnedToLeftSide = true;
+ m_mainFrameIsPinnedToRightSide = true;
+ m_mainFrameIsPinnedToTopSide = true;
+ m_mainFrameIsPinnedToBottomSide = true;
m_visibleScrollerThumbRect = IntRect();
- invalidateCallbackMap(m_voidCallbacks);
- invalidateCallbackMap(m_dataCallbacks);
- invalidateCallbackMap(m_imageCallbacks);
- invalidateCallbackMap(m_stringCallbacks);
- m_loadDependentStringCallbackIDs.clear();
- invalidateCallbackMap(m_scriptValueCallbacks);
- invalidateCallbackMap(m_computedPagesCallbacks);
- invalidateCallbackMap(m_validateCommandCallbacks);
+#if (PLATFORM(IOS) && HAVE(AVKIT)) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
+ if (m_playbackSessionManager) {
+ m_playbackSessionManager->invalidate();
+ m_playbackSessionManager = nullptr;
+ }
+ if (m_videoFullscreenManager) {
+ m_videoFullscreenManager->invalidate();
+ m_videoFullscreenManager = nullptr;
+ }
+#endif
+
#if PLATFORM(IOS)
- invalidateCallbackMap(m_gestureCallbacks);
- invalidateCallbackMap(m_touchesCallbacks);
- invalidateCallbackMap(m_autocorrectionCallbacks);
- invalidateCallbackMap(m_autocorrectionContextCallbacks);
+ m_firstLayerTreeTransactionIdAfterDidCommitLoad = 0;
+ m_lastVisibleContentRectUpdate = VisibleContentRectUpdateInfo();
+ m_dynamicViewportSizeUpdateWaitingForTarget = false;
+ m_dynamicViewportSizeUpdateWaitingForLayerTreeCommit = false;
+ m_dynamicViewportSizeUpdateLayerTreeTransactionID = 0;
+ m_layerTreeTransactionIdAtLastTouchStart = 0;
+ m_hasNetworkRequestsOnSuspended = false;
+ m_isKeyboardAnimatingIn = false;
+ m_isScrollingOrZooming = false;
#endif
-#if PLATFORM(GTK)
- invalidateCallbackMap(m_printFinishedCallbacks);
+
+#if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
+ m_pageClient.mediaSessionManager().removeAllPlaybackTargetPickerClients(*this);
+#endif
+
+#if ENABLE(APPLE_PAY)
+ m_paymentCoordinator = nullptr;
#endif
+ CallbackBase::Error error;
+ switch (resetStateReason) {
+ case ResetStateReason::PageInvalidated:
+ error = CallbackBase::Error::OwnerWasInvalidated;
+ break;
+
+ case ResetStateReason::WebProcessExited:
+ error = CallbackBase::Error::ProcessExited;
+ break;
+ }
+
+ m_callbacks.invalidate(error);
+ m_loadDependentStringCallbackIDs.clear();
+
Vector<WebEditCommandProxy*> editCommandVector;
copyToVector(m_editCommandSet, editCommandVector);
m_editCommandSet.clear();
for (size_t i = 0, size = editCommandVector.size(); i < size; ++i)
editCommandVector[i]->invalidate();
- m_activePopupMenu = 0;
+ m_activePopupMenu = nullptr;
+ m_mediaState = MediaProducer::IsNotPlaying;
+
+#if ENABLE(POINTER_LOCK)
+ requestPointerUnlock();
+#endif
}
void WebPageProxy::resetStateAfterProcessExited()
@@ -3843,18 +5472,25 @@ void WebPageProxy::resetStateAfterProcessExited()
if (!isValid())
return;
- m_process->removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID);
+ // FIXME: It's weird that resetStateAfterProcessExited() is called even though the process is launching.
+ ASSERT(m_process->state() == WebProcessProxy::State::Launching || m_process->state() == WebProcessProxy::State::Terminated);
+
+#if PLATFORM(IOS)
+ m_activityToken = nullptr;
+#endif
+ m_pageIsUserObservableCount = nullptr;
+ m_visiblePageToken = nullptr;
m_isValid = false;
m_isPageSuspended = false;
- m_waitingForDidUpdateViewState = false;
- if (m_mainFrame) {
- m_urlAtProcessExit = m_mainFrame->url();
- m_loadStateAtProcessExit = m_mainFrame->frameLoadState().m_state;
- }
+ m_needsToFinishInitializingWebPageAfterProcessLaunch = false;
+
+ m_editorState = EditorState();
- resetState();
+ m_pageClient.processDidExit();
+
+ resetState(ResetStateReason::WebProcessExited);
m_pageClient.clearAllEditCommands();
m_pendingLearnOrIgnoreWordMessageCount = 0;
@@ -3869,19 +5505,18 @@ void WebPageProxy::resetStateAfterProcessExited()
m_processingMouseMoveEvent = false;
-#if ENABLE(TOUCH_EVENTS)
- m_needTouchEvents = false;
+#if ENABLE(TOUCH_EVENTS) && !ENABLE(IOS_TOUCH_EVENTS)
m_touchEventQueue.clear();
#endif
- // FIXME: Reset m_editorState.
- // FIXME: Notify input methods about abandoned composition.
- m_temporarilyClosedComposition = false;
-
-#if !PLATFORM(IOS) && PLATFORM(MAC)
- dismissCorrectionPanel(ReasonForDismissingAlternativeTextIgnored);
- m_pageClient.dismissDictionaryLookupPanel();
+#if PLATFORM(MAC)
+ m_pageClient.dismissContentRelativeChildWindows();
#endif
+
+ PageLoadState::Transaction transaction = m_pageLoadState.transaction();
+ m_pageLoadState.reset(transaction);
+
+ m_process->responsivenessTimer().processTerminated();
}
WebPageCreationParameters WebPageProxy::creationParameters()
@@ -3889,14 +5524,13 @@ WebPageCreationParameters WebPageProxy::creationParameters()
WebPageCreationParameters parameters;
parameters.viewSize = m_pageClient.viewSize();
- parameters.viewState = m_viewState;
+ parameters.activityState = m_activityState;
parameters.drawingAreaType = m_drawingArea->type();
- parameters.store = m_pageGroup->preferences()->store();
+ parameters.store = preferencesStore();
parameters.pageGroupData = m_pageGroup->data();
parameters.drawsBackground = m_drawsBackground;
- parameters.drawsTransparentBackground = m_drawsTransparentBackground;
+ parameters.isEditable = m_isEditable;
parameters.underlayColor = m_underlayColor;
- parameters.areMemoryCacheClientCallsEnabled = m_areMemoryCacheClientCallsEnabled;
parameters.useFixedLayout = m_useFixedLayout;
parameters.fixedLayoutSize = m_fixedLayoutSize;
parameters.suppressScrollbarAnimations = m_suppressScrollbarAnimations;
@@ -3904,28 +5538,63 @@ WebPageCreationParameters WebPageProxy::creationParameters()
parameters.paginationBehavesLikeColumns = m_paginationBehavesLikeColumns;
parameters.pageLength = m_pageLength;
parameters.gapBetweenPages = m_gapBetweenPages;
+ parameters.paginationLineGridEnabled = m_paginationLineGridEnabled;
parameters.userAgent = userAgent();
- parameters.sessionState = SessionState(m_backForwardList->entries(), m_backForwardList->currentIndex());
- parameters.highestUsedBackForwardItemID = WebBackForwardListItem::highedUsedItemID();
- parameters.canRunBeforeUnloadConfirmPanel = m_uiClient.canRunBeforeUnloadConfirmPanel();
+ parameters.itemStates = m_backForwardList->itemStates();
+ parameters.sessionID = m_sessionID;
+ parameters.highestUsedBackForwardItemID = WebBackForwardListItem::highestUsedItemID();
+ parameters.userContentControllerID = m_userContentController->identifier();
+ parameters.visitedLinkTableID = m_visitedLinkStore->identifier();
+ parameters.websiteDataStoreID = m_websiteDataStore->identifier();
+ parameters.canRunBeforeUnloadConfirmPanel = m_uiClient->canRunBeforeUnloadConfirmPanel();
parameters.canRunModal = m_canRunModal;
parameters.deviceScaleFactor = deviceScaleFactor();
+ parameters.viewScaleFactor = m_viewScaleFactor;
+ parameters.topContentInset = m_topContentInset;
parameters.mediaVolume = m_mediaVolume;
+ parameters.muted = m_mutedState;
parameters.mayStartMediaWhenInWindow = m_mayStartMediaWhenInWindow;
parameters.minimumLayoutSize = m_minimumLayoutSize;
parameters.autoSizingShouldExpandToViewHeight = m_autoSizingShouldExpandToViewHeight;
parameters.scrollPinningBehavior = m_scrollPinningBehavior;
+ if (m_scrollbarOverlayStyle)
+ parameters.scrollbarOverlayStyle = m_scrollbarOverlayStyle.value();
+ else
+ parameters.scrollbarOverlayStyle = std::nullopt;
parameters.backgroundExtendsBeyondPage = m_backgroundExtendsBeyondPage;
parameters.layerHostingMode = m_layerHostingMode;
-
-#if PLATFORM(MAC) && !PLATFORM(IOS)
+ parameters.controlledByAutomation = m_controlledByAutomation;
+#if ENABLE(REMOTE_INSPECTOR)
+ parameters.allowsRemoteInspection = m_allowsRemoteInspection;
+ parameters.remoteInspectionNameOverride = m_remoteInspectionNameOverride;
+#endif
+#if PLATFORM(MAC)
parameters.colorSpace = m_pageClient.colorSpace();
#endif
+#if PLATFORM(IOS)
+ parameters.screenSize = screenSize();
+ parameters.availableScreenSize = availableScreenSize();
+ parameters.textAutosizingWidth = textAutosizingWidth();
+ parameters.mimeTypesWithCustomContentProviders = m_pageClient.mimeTypesWithCustomContentProviders();
+ parameters.ignoresViewportScaleLimits = m_forceAlwaysUserScalable;
+#endif
+
+#if PLATFORM(MAC)
+ parameters.appleMailPaginationQuirkEnabled = appleMailPaginationQuirkEnabled();
+#else
+ parameters.appleMailPaginationQuirkEnabled = false;
+#endif
+#if PLATFORM(COCOA)
+ parameters.smartInsertDeleteEnabled = m_isSmartInsertDeleteEnabled;
+#endif
+ parameters.shouldScaleViewToFitDocument = m_shouldScaleViewToFitDocument;
+ parameters.userInterfaceLayoutDirection = m_pageClient.userInterfaceLayoutDirection();
+ parameters.observedLayoutMilestones = m_observedLayoutMilestones;
+ parameters.overrideContentSecurityPolicy = m_overrideContentSecurityPolicy;
return parameters;
}
-#if USE(ACCELERATED_COMPOSITING)
void WebPageProxy::enterAcceleratedCompositingMode(const LayerTreeContext& layerTreeContext)
{
m_pageClient.enterAcceleratedCompositingMode(layerTreeContext);
@@ -3940,21 +5609,37 @@ void WebPageProxy::updateAcceleratedCompositingMode(const LayerTreeContext& laye
{
m_pageClient.updateAcceleratedCompositingMode(layerTreeContext);
}
-#endif // USE(ACCELERATED_COMPOSITING)
void WebPageProxy::backForwardClear()
{
m_backForwardList->clear();
}
-void WebPageProxy::canAuthenticateAgainstProtectionSpaceInFrame(uint64_t frameID, const ProtectionSpace& coreProtectionSpace, bool& canAuthenticate)
+#if ENABLE(GAMEPAD)
+
+void WebPageProxy::gamepadActivity(const Vector<GamepadData>& gamepadDatas, bool shouldMakeGamepadsVisible)
{
+ m_process->send(Messages::WebPage::GamepadActivity(gamepadDatas, shouldMakeGamepadsVisible), m_pageID);
+}
+
+#endif
+
+void WebPageProxy::canAuthenticateAgainstProtectionSpace(uint64_t loaderID, uint64_t frameID, const ProtectionSpace& coreProtectionSpace)
+{
+#if USE(PROTECTION_SPACE_AUTH_CALLBACK)
WebFrameProxy* frame = m_process->webFrame(frameID);
MESSAGE_CHECK(frame);
RefPtr<WebProtectionSpace> protectionSpace = WebProtectionSpace::create(coreProtectionSpace);
- canAuthenticate = m_loaderClient->canAuthenticateAgainstProtectionSpaceInFrame(this, frame, protectionSpace.get());
+ bool canAuthenticate;
+ if (m_navigationClient)
+ canAuthenticate = m_navigationClient->canAuthenticateAgainstProtectionSpace(*this, protectionSpace.get());
+ else
+ canAuthenticate = m_loaderClient->canAuthenticateAgainstProtectionSpaceInFrame(*this, *frame, protectionSpace.get());
+
+ m_process->processPool().sendToNetworkingProcess(Messages::NetworkProcess::ContinueCanAuthenticateAgainstProtectionSpace(loaderID, canAuthenticate));
+#endif
}
void WebPageProxy::didReceiveAuthenticationChallenge(uint64_t frameID, const AuthenticationChallenge& coreChallenge, uint64_t challengeID)
@@ -3970,16 +5655,19 @@ void WebPageProxy::didReceiveAuthenticationChallengeProxy(uint64_t frameID, Pass
MESSAGE_CHECK(frame);
RefPtr<AuthenticationChallengeProxy> authenticationChallenge = prpAuthenticationChallenge;
- m_loaderClient->didReceiveAuthenticationChallengeInFrame(this, frame, authenticationChallenge.get());
+ if (m_navigationClient)
+ m_navigationClient->didReceiveAuthenticationChallenge(*this, authenticationChallenge.get());
+ else
+ m_loaderClient->didReceiveAuthenticationChallengeInFrame(*this, *frame, authenticationChallenge.get());
}
void WebPageProxy::exceededDatabaseQuota(uint64_t frameID, const String& originIdentifier, const String& databaseName, const String& displayName, uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage, PassRefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply> reply)
{
- ExceededDatabaseQuotaRecords& records = ExceededDatabaseQuotaRecords::shared();
- OwnPtr<ExceededDatabaseQuotaRecords::Record> newRecord = records.createRecord(frameID,
+ ExceededDatabaseQuotaRecords& records = ExceededDatabaseQuotaRecords::singleton();
+ std::unique_ptr<ExceededDatabaseQuotaRecords::Record> newRecord = records.createRecord(frameID,
originIdentifier, databaseName, displayName, currentQuota, currentOriginUsage,
currentDatabaseUsage, expectedUsage, reply);
- records.add(newRecord.release());
+ records.add(WTFMove(newRecord));
if (records.areBeingProcessed())
return;
@@ -3989,27 +5677,33 @@ void WebPageProxy::exceededDatabaseQuota(uint64_t frameID, const String& originI
WebFrameProxy* frame = m_process->webFrame(record->frameID);
MESSAGE_CHECK(frame);
- RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::createFromDatabaseIdentifier(record->originIdentifier);
-
- uint64_t newQuota = m_uiClient.exceededDatabaseQuota(this, frame, origin.get(),
+ RefPtr<API::SecurityOrigin> origin = API::SecurityOrigin::create(SecurityOriginData::fromDatabaseIdentifier(record->originIdentifier)->securityOrigin());
+ auto currentReply = record->reply;
+ m_uiClient->exceededDatabaseQuota(this, frame, origin.get(),
record->databaseName, record->displayName, record->currentQuota,
- record->currentOriginUsage, record->currentDatabaseUsage, record->expectedUsage);
+ record->currentOriginUsage, record->currentDatabaseUsage, record->expectedUsage,
+ [currentReply](unsigned long long newQuota) { currentReply->send(newQuota); });
- record->reply->send(newQuota);
record = records.next();
}
}
+void WebPageProxy::reachedApplicationCacheOriginQuota(const String& originIdentifier, uint64_t currentQuota, uint64_t totalBytesNeeded, PassRefPtr<Messages::WebPageProxy::ReachedApplicationCacheOriginQuota::DelayedReply> reply)
+{
+ Ref<SecurityOrigin> securityOrigin = SecurityOriginData::fromDatabaseIdentifier(originIdentifier)->securityOrigin();
+ m_uiClient->reachedApplicationCacheOriginQuota(this, securityOrigin.get(), currentQuota, totalBytesNeeded, [reply](unsigned long long newQuota) { reply->send(newQuota); });
+}
+
void WebPageProxy::requestGeolocationPermissionForFrame(uint64_t geolocationID, uint64_t frameID, String originIdentifier)
{
WebFrameProxy* frame = m_process->webFrame(frameID);
MESSAGE_CHECK(frame);
// FIXME: Geolocation should probably be using toString() as its string representation instead of databaseIdentifier().
- RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::createFromDatabaseIdentifier(originIdentifier);
+ RefPtr<API::SecurityOrigin> origin = API::SecurityOrigin::create(SecurityOriginData::fromDatabaseIdentifier(originIdentifier)->securityOrigin());
RefPtr<GeolocationPermissionRequestProxy> request = m_geolocationPermissionRequestManager.createRequest(geolocationID);
- if (m_uiClient.decidePolicyForGeolocationPermissionRequest(this, frame, origin.get(), request.get()))
+ if (m_uiClient->decidePolicyForGeolocationPermissionRequest(this, frame, origin.get(), request.get()))
return;
if (m_pageClient.decidePolicyForGeolocationPermissionRequest(*frame, *origin, *request))
@@ -4018,70 +5712,119 @@ void WebPageProxy::requestGeolocationPermissionForFrame(uint64_t geolocationID,
request->deny();
}
+#if ENABLE(MEDIA_STREAM)
+UserMediaPermissionRequestManagerProxy& WebPageProxy::userMediaPermissionRequestManager()
+{
+ if (m_userMediaPermissionRequestManager)
+ return *m_userMediaPermissionRequestManager;
+
+ m_userMediaPermissionRequestManager = std::make_unique<UserMediaPermissionRequestManagerProxy>(*this);
+ return *m_userMediaPermissionRequestManager;
+}
+#endif
+
+void WebPageProxy::requestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier, const WebCore::MediaConstraintsData& audioConstraintsData, const WebCore::MediaConstraintsData& videoConstraintsData)
+{
+#if ENABLE(MEDIA_STREAM)
+ MESSAGE_CHECK(m_process->webFrame(frameID));
+
+ userMediaPermissionRequestManager().requestUserMediaPermissionForFrame(userMediaID, frameID, userMediaDocumentOriginIdentifier, topLevelDocumentOriginIdentifier, audioConstraintsData, videoConstraintsData);
+#else
+ UNUSED_PARAM(userMediaID);
+ UNUSED_PARAM(frameID);
+ UNUSED_PARAM(userMediaDocumentOriginIdentifier);
+ UNUSED_PARAM(topLevelDocumentOriginIdentifier);
+ UNUSED_PARAM(audioConstraintsData);
+ UNUSED_PARAM(videoConstraintsData);
+#endif
+}
+
+void WebPageProxy::enumerateMediaDevicesForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier)
+{
+#if ENABLE(MEDIA_STREAM)
+ WebFrameProxy* frame = m_process->webFrame(frameID);
+ MESSAGE_CHECK(frame);
+
+ userMediaPermissionRequestManager().enumerateMediaDevicesForFrame(userMediaID, frameID, userMediaDocumentOriginIdentifier, topLevelDocumentOriginIdentifier);
+#else
+ UNUSED_PARAM(userMediaID);
+ UNUSED_PARAM(frameID);
+ UNUSED_PARAM(userMediaDocumentOriginIdentifier);
+ UNUSED_PARAM(topLevelDocumentOriginIdentifier);
+#endif
+}
+
+void WebPageProxy::clearUserMediaState()
+{
+#if ENABLE(MEDIA_STREAM)
+ userMediaPermissionRequestManager().clearCachedState();
+#endif
+}
+
void WebPageProxy::requestNotificationPermission(uint64_t requestID, const String& originString)
{
if (!isRequestIDValid(requestID))
return;
- RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::createFromString(originString);
+ RefPtr<API::SecurityOrigin> origin = API::SecurityOrigin::createFromString(originString);
RefPtr<NotificationPermissionRequest> request = m_notificationPermissionRequestManager.createRequest(requestID);
- if (!m_uiClient.decidePolicyForNotificationPermissionRequest(this, origin.get(), request.get()))
+ if (!m_uiClient->decidePolicyForNotificationPermissionRequest(this, origin.get(), request.get()))
request->deny();
}
void WebPageProxy::showNotification(const String& title, const String& body, const String& iconURL, const String& tag, const String& lang, const String& dir, const String& originString, uint64_t notificationID)
{
- m_process->context().supplement<WebNotificationManagerProxy>()->show(this, title, body, iconURL, tag, lang, dir, originString, notificationID);
+ m_process->processPool().supplement<WebNotificationManagerProxy>()->show(this, title, body, iconURL, tag, lang, dir, originString, notificationID);
}
void WebPageProxy::cancelNotification(uint64_t notificationID)
{
- m_process->context().supplement<WebNotificationManagerProxy>()->cancel(this, notificationID);
+ m_process->processPool().supplement<WebNotificationManagerProxy>()->cancel(this, notificationID);
}
void WebPageProxy::clearNotifications(const Vector<uint64_t>& notificationIDs)
{
- m_process->context().supplement<WebNotificationManagerProxy>()->clearNotifications(this, notificationIDs);
+ m_process->processPool().supplement<WebNotificationManagerProxy>()->clearNotifications(this, notificationIDs);
}
void WebPageProxy::didDestroyNotification(uint64_t notificationID)
{
- m_process->context().supplement<WebNotificationManagerProxy>()->didDestroyNotification(this, notificationID);
+ m_process->processPool().supplement<WebNotificationManagerProxy>()->didDestroyNotification(this, notificationID);
}
float WebPageProxy::headerHeight(WebFrameProxy* frame)
{
if (frame->isDisplayingPDFDocument())
return 0;
- return m_uiClient.headerHeight(this, frame);
+ return m_uiClient->headerHeight(this, frame);
}
float WebPageProxy::footerHeight(WebFrameProxy* frame)
{
if (frame->isDisplayingPDFDocument())
return 0;
- return m_uiClient.footerHeight(this, frame);
+ return m_uiClient->footerHeight(this, frame);
}
void WebPageProxy::drawHeader(WebFrameProxy* frame, const FloatRect& rect)
{
if (frame->isDisplayingPDFDocument())
return;
- m_uiClient.drawHeader(this, frame, rect);
+ m_uiClient->drawHeader(this, frame, rect);
}
void WebPageProxy::drawFooter(WebFrameProxy* frame, const FloatRect& rect)
{
if (frame->isDisplayingPDFDocument())
return;
- m_uiClient.drawFooter(this, frame, rect);
+ m_uiClient->drawFooter(this, frame, rect);
}
void WebPageProxy::runModal()
{
// Since runModal() can (and probably will) spin a nested run loop we need to turn off the responsiveness timer.
- m_process->responsivenessTimer()->stop();
+ m_process->responsivenessTimer().stop();
// Our Connection's run loop might have more messages waiting to be handled after this RunModal message.
// To make sure they are handled inside of the the nested modal run loop we must first signal the Connection's
@@ -4089,7 +5832,7 @@ void WebPageProxy::runModal()
// See http://webkit.org/b/89590 for more discussion.
m_process->connection()->wakeUpRunLoop();
- m_uiClient.runModal(this);
+ m_uiClient->runModal(this);
}
void WebPageProxy::notifyScrollerThumbIsVisibleInRect(const IntRect& scrollerThumb)
@@ -4100,7 +5843,7 @@ void WebPageProxy::notifyScrollerThumbIsVisibleInRect(const IntRect& scrollerThu
void WebPageProxy::recommendedScrollbarStyleDidChange(int32_t newStyle)
{
#if USE(APPKIT)
- m_pageClient.recommendedScrollbarStyleDidChange(newStyle);
+ m_pageClient.recommendedScrollbarStyleDidChange(static_cast<WebCore::ScrollbarStyle>(newStyle));
#else
UNUSED_PARAM(newStyle);
#endif
@@ -4118,6 +5861,8 @@ void WebPageProxy::didChangeScrollOffsetPinningForMainFrame(bool pinnedToLeftSid
m_mainFrameIsPinnedToRightSide = pinnedToRightSide;
m_mainFrameIsPinnedToTopSide = pinnedToTopSide;
m_mainFrameIsPinnedToBottomSide = pinnedToBottomSide;
+
+ m_uiClient->pinnedStateDidChange(*this);
}
void WebPageProxy::didChangePageCount(unsigned pageCount)
@@ -4125,19 +5870,24 @@ void WebPageProxy::didChangePageCount(unsigned pageCount)
m_pageCount = pageCount;
}
+void WebPageProxy::pageExtendedBackgroundColorDidChange(const Color& backgroundColor)
+{
+ m_pageExtendedBackgroundColor = backgroundColor;
+}
+
#if ENABLE(NETSCAPE_PLUGIN_API)
void WebPageProxy::didFailToInitializePlugin(const String& mimeType, const String& frameURLString, const String& pageURLString)
{
- m_loaderClient->didFailToInitializePlugin(this, createPluginInformationDictionary(mimeType, frameURLString, pageURLString).get());
+ m_loaderClient->didFailToInitializePlugin(*this, createPluginInformationDictionary(mimeType, frameURLString, pageURLString).ptr());
}
void WebPageProxy::didBlockInsecurePluginVersion(const String& mimeType, const String& pluginURLString, const String& frameURLString, const String& pageURLString, bool replacementObscured)
{
- RefPtr<ImmutableDictionary> pluginInformation;
+ RefPtr<API::Dictionary> pluginInformation;
-#if PLATFORM(MAC) && ENABLE(NETSCAPE_PLUGIN_API)
+#if PLATFORM(COCOA) && ENABLE(NETSCAPE_PLUGIN_API)
String newMimeType = mimeType;
- PluginModuleInfo plugin = m_process->context().pluginInfoStore().findPlugin(newMimeType, URL(URL(), pluginURLString));
+ PluginModuleInfo plugin = m_process->processPool().pluginInfoStore().findPlugin(newMimeType, URL(URL(), pluginURLString));
pluginInformation = createPluginInformationDictionary(plugin, frameURLString, mimeType, pageURLString, String(), String(), replacementObscured);
#else
UNUSED_PARAM(mimeType);
@@ -4147,7 +5897,7 @@ void WebPageProxy::didBlockInsecurePluginVersion(const String& mimeType, const S
UNUSED_PARAM(replacementObscured);
#endif
- m_loaderClient->didBlockInsecurePluginVersion(this, pluginInformation.get());
+ m_loaderClient->didBlockInsecurePluginVersion(*this, pluginInformation.get());
}
#endif // ENABLE(NETSCAPE_PLUGIN_API)
@@ -4156,8 +5906,19 @@ bool WebPageProxy::willHandleHorizontalScrollEvents() const
return !m_canShortCircuitHorizontalWheelEvents;
}
+void WebPageProxy::updateWebsitePolicies(const WebsitePolicies& websitePolicies)
+{
+ m_process->send(Messages::WebPage::UpdateWebsitePolicies(websitePolicies), m_pageID);
+}
+
+void WebPageProxy::didFinishLoadingDataForCustomContentProvider(const String& suggestedFilename, const IPC::DataReference& dataReference)
+{
+ m_pageClient.didFinishLoadingDataForCustomContentProvider(suggestedFilename, dataReference);
+}
+
void WebPageProxy::backForwardRemovedItem(uint64_t itemID)
{
+ m_process->removeBackForwardItem(itemID);
m_process->send(Messages::WebPage::DidRemoveBackForwardItem(itemID), m_pageID);
}
@@ -4169,7 +5930,7 @@ void WebPageProxy::setCanRunModal(bool canRunModal)
// It's only possible to change the state for a WebPage which
// already qualifies for running modal child web pages, otherwise
// there's no other possibility than not allowing it.
- m_canRunModal = m_uiClient.canRunModal() && canRunModal;
+ m_canRunModal = m_uiClient->canRunModal() && canRunModal;
m_process->send(Messages::WebPage::SetCanRunModal(m_canRunModal), m_pageID);
}
@@ -4184,7 +5945,7 @@ void WebPageProxy::beginPrinting(WebFrameProxy* frame, const PrintInfo& printInf
return;
m_isInPrintingMode = true;
- m_process->send(Messages::WebPage::BeginPrinting(frame->frameID(), printInfo), m_pageID, m_isPerformingDOMPrintOperation ? IPC::DispatchMessageEvenWhenWaitingForSyncReply : 0);
+ m_process->send(Messages::WebPage::BeginPrinting(frame->frameID(), printInfo), m_pageID, printingSendOptions(m_isPerformingDOMPrintOperation));
}
void WebPageProxy::endPrinting()
@@ -4193,7 +5954,7 @@ void WebPageProxy::endPrinting()
return;
m_isInPrintingMode = false;
- m_process->send(Messages::WebPage::EndPrinting(), m_pageID, m_isPerformingDOMPrintOperation ? IPC::DispatchMessageEvenWhenWaitingForSyncReply : 0);
+ m_process->send(Messages::WebPage::EndPrinting(), m_pageID, printingSendOptions(m_isPerformingDOMPrintOperation));
}
void WebPageProxy::computePagesForPrinting(WebFrameProxy* frame, const PrintInfo& printInfo, PassRefPtr<ComputedPagesCallback> prpCallback)
@@ -4205,12 +5966,12 @@ void WebPageProxy::computePagesForPrinting(WebFrameProxy* frame, const PrintInfo
}
uint64_t callbackID = callback->callbackID();
- m_computedPagesCallbacks.set(callbackID, callback.get());
+ m_callbacks.put(callback);
m_isInPrintingMode = true;
- m_process->send(Messages::WebPage::ComputePagesForPrinting(frame->frameID(), printInfo, callbackID), m_pageID, m_isPerformingDOMPrintOperation ? IPC::DispatchMessageEvenWhenWaitingForSyncReply : 0);
+ m_process->send(Messages::WebPage::ComputePagesForPrinting(frame->frameID(), printInfo, callbackID), m_pageID, printingSendOptions(m_isPerformingDOMPrintOperation));
}
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
void WebPageProxy::drawRectToImage(WebFrameProxy* frame, const PrintInfo& printInfo, const IntRect& rect, const WebCore::IntSize& imageSize, PassRefPtr<ImageCallback> prpCallback)
{
RefPtr<ImageCallback> callback = prpCallback;
@@ -4220,8 +5981,8 @@ void WebPageProxy::drawRectToImage(WebFrameProxy* frame, const PrintInfo& printI
}
uint64_t callbackID = callback->callbackID();
- m_imageCallbacks.set(callbackID, callback.get());
- m_process->send(Messages::WebPage::DrawRectToImage(frame->frameID(), printInfo, rect, imageSize, callbackID), m_pageID, m_isPerformingDOMPrintOperation ? IPC::DispatchMessageEvenWhenWaitingForSyncReply : 0);
+ m_callbacks.put(callback);
+ m_process->send(Messages::WebPage::DrawRectToImage(frame->frameID(), printInfo, rect, imageSize, callbackID), m_pageID, printingSendOptions(m_isPerformingDOMPrintOperation));
}
void WebPageProxy::drawPagesToPDF(WebFrameProxy* frame, const PrintInfo& printInfo, uint32_t first, uint32_t count, PassRefPtr<DataCallback> prpCallback)
@@ -4233,8 +5994,8 @@ void WebPageProxy::drawPagesToPDF(WebFrameProxy* frame, const PrintInfo& printIn
}
uint64_t callbackID = callback->callbackID();
- m_dataCallbacks.set(callbackID, callback.get());
- m_process->send(Messages::WebPage::DrawPagesToPDF(frame->frameID(), printInfo, first, count, callbackID), m_pageID, m_isPerformingDOMPrintOperation ? IPC::DispatchMessageEvenWhenWaitingForSyncReply : 0);
+ m_callbacks.put(callback);
+ m_process->send(Messages::WebPage::DrawPagesToPDF(frame->frameID(), printInfo, first, count, callbackID), m_pageID, printingSendOptions(m_isPerformingDOMPrintOperation));
}
#elif PLATFORM(GTK)
void WebPageProxy::drawPagesForPrinting(WebFrameProxy* frame, const PrintInfo& printInfo, PassRefPtr<PrintFinishedCallback> didPrintCallback)
@@ -4246,9 +6007,9 @@ void WebPageProxy::drawPagesForPrinting(WebFrameProxy* frame, const PrintInfo& p
}
uint64_t callbackID = callback->callbackID();
- m_printFinishedCallbacks.set(callbackID, callback.get());
+ m_callbacks.put(callback);
m_isInPrintingMode = true;
- m_process->send(Messages::WebPage::DrawPagesForPrinting(frame->frameID(), printInfo, callbackID), m_pageID, m_isPerformingDOMPrintOperation ? IPC::DispatchMessageEvenWhenWaitingForSyncReply : 0);
+ m_process->send(Messages::WebPage::DrawPagesForPrinting(frame->frameID(), printInfo, callbackID), m_pageID, printingSendOptions(m_isPerformingDOMPrintOperation));
}
#endif
@@ -4258,7 +6019,7 @@ void WebPageProxy::updateBackingStoreDiscardableState()
bool isDiscardable;
- if (!m_process->responsivenessTimer()->isResponsive())
+ if (!m_process->responsivenessTimer().isResponsive())
isDiscardable = false;
else
isDiscardable = !m_pageClient.isViewWindowActive() || !isViewVisible();
@@ -4268,7 +6029,7 @@ void WebPageProxy::updateBackingStoreDiscardableState()
void WebPageProxy::saveDataToFileInDownloadsFolder(const String& suggestedFilename, const String& mimeType, const String& originatingURLString, API::Data* data)
{
- m_uiClient.saveDataToFileInDownloadsFolder(this, suggestedFilename, mimeType, originatingURLString, data);
+ m_uiClient->saveDataToFileInDownloadsFolder(this, suggestedFilename, mimeType, originatingURLString, data);
}
void WebPageProxy::savePDFToFileInDownloadsFolder(const String& suggestedFilename, const String& originatingURLString, const IPC::DataReference& dataReference)
@@ -4276,9 +6037,8 @@ void WebPageProxy::savePDFToFileInDownloadsFolder(const String& suggestedFilenam
if (!suggestedFilename.endsWith(".pdf", false))
return;
- RefPtr<API::Data> data = API::Data::create(dataReference.data(), dataReference.size());
-
- saveDataToFileInDownloadsFolder(suggestedFilename, "application/pdf", originatingURLString, data.get());
+ saveDataToFileInDownloadsFolder(suggestedFilename, "application/pdf", originatingURLString,
+ API::Data::create(dataReference.data(), dataReference.size()).ptr());
}
void WebPageProxy::setMinimumLayoutSize(const IntSize& minimumLayoutSize)
@@ -4291,7 +6051,7 @@ void WebPageProxy::setMinimumLayoutSize(const IntSize& minimumLayoutSize)
if (!isValid())
return;
- m_process->send(Messages::WebPage::SetMinimumLayoutSize(minimumLayoutSize), m_pageID, 0);
+ m_process->send(Messages::WebPage::SetMinimumLayoutSize(minimumLayoutSize), m_pageID);
m_drawingArea->minimumLayoutSizeDidChange();
#if USE(APPKIT)
@@ -4310,10 +6070,44 @@ void WebPageProxy::setAutoSizingShouldExpandToViewHeight(bool shouldExpand)
if (!isValid())
return;
- m_process->send(Messages::WebPage::SetAutoSizingShouldExpandToViewHeight(shouldExpand), m_pageID, 0);
+ m_process->send(Messages::WebPage::SetAutoSizingShouldExpandToViewHeight(shouldExpand), m_pageID);
}
-#if !PLATFORM(IOS) && PLATFORM(MAC)
+#if USE(AUTOMATIC_TEXT_REPLACEMENT)
+
+void WebPageProxy::toggleSmartInsertDelete()
+{
+ if (TextChecker::isTestingMode())
+ TextChecker::setSmartInsertDeleteEnabled(!TextChecker::isSmartInsertDeleteEnabled());
+}
+
+void WebPageProxy::toggleAutomaticQuoteSubstitution()
+{
+ if (TextChecker::isTestingMode())
+ TextChecker::setAutomaticQuoteSubstitutionEnabled(!TextChecker::state().isAutomaticQuoteSubstitutionEnabled);
+}
+
+void WebPageProxy::toggleAutomaticLinkDetection()
+{
+ if (TextChecker::isTestingMode())
+ TextChecker::setAutomaticLinkDetectionEnabled(!TextChecker::state().isAutomaticLinkDetectionEnabled);
+}
+
+void WebPageProxy::toggleAutomaticDashSubstitution()
+{
+ if (TextChecker::isTestingMode())
+ TextChecker::setAutomaticDashSubstitutionEnabled(!TextChecker::state().isAutomaticDashSubstitutionEnabled);
+}
+
+void WebPageProxy::toggleAutomaticTextReplacement()
+{
+ if (TextChecker::isTestingMode())
+ TextChecker::setAutomaticTextReplacementEnabled(!TextChecker::state().isAutomaticTextReplacementEnabled);
+}
+
+#endif
+
+#if PLATFORM(MAC)
void WebPageProxy::substitutionsPanelIsShowing(bool& isShowing)
{
@@ -4335,15 +6129,15 @@ void WebPageProxy::dismissCorrectionPanelSoon(int32_t reason, String& result)
result = m_pageClient.dismissCorrectionPanelSoon((ReasonForDismissingAlternativeText)reason);
}
-void WebPageProxy::recordAutocorrectionResponse(int32_t responseType, const String& replacedString, const String& replacementString)
+void WebPageProxy::recordAutocorrectionResponse(int32_t response, const String& replacedString, const String& replacementString)
{
- m_pageClient.recordAutocorrectionResponse((AutocorrectionResponseType)responseType, replacedString, replacementString);
+ m_pageClient.recordAutocorrectionResponse(static_cast<AutocorrectionResponse>(response), replacedString, replacementString);
}
void WebPageProxy::handleAlternativeTextUIResult(const String& result)
{
if (!isClosed())
- m_process->send(Messages::WebPage::HandleAlternativeTextUIResult(result), m_pageID, 0);
+ m_process->send(Messages::WebPage::HandleAlternativeTextUIResult(result), m_pageID);
}
#if USE(DICTATION_ALTERNATIVES)
@@ -4363,19 +6157,17 @@ void WebPageProxy::dictationAlternatives(uint64_t dictationContext, Vector<Strin
}
#endif
-#endif // !PLATFORM(IOS) && PLATFORM(MAC)
-
-#if PLATFORM(MAC)
-RetainPtr<CGImageRef> WebPageProxy::takeViewSnapshot()
+void WebPageProxy::setEditableElementIsFocused(bool editableElementIsFocused)
{
- return m_pageClient.takeViewSnapshot();
+ m_pageClient.setEditableElementIsFocused(editableElementIsFocused);
}
-#endif
-#if USE(SOUP) && !ENABLE(CUSTOM_PROTOCOLS)
-void WebPageProxy::didReceiveURIRequest(String uriString, uint64_t requestID)
+#endif // PLATFORM(MAC)
+
+#if PLATFORM(COCOA)
+PassRefPtr<ViewSnapshot> WebPageProxy::takeViewSnapshot()
{
- m_process->context().supplement<WebSoupRequestManagerProxy>()->didReceiveURIRequest(uriString, this, requestID);
+ return m_pageClient.takeViewSnapshot();
}
#endif
@@ -4406,17 +6198,6 @@ void WebPageProxy::cancelComposition()
}
#endif // PLATFORM(GTK)
-void WebPageProxy::setMainFrameInViewSourceMode(bool mainFrameInViewSourceMode)
-{
- if (m_mainFrameInViewSourceMode == mainFrameInViewSourceMode)
- return;
-
- m_mainFrameInViewSourceMode = mainFrameInViewSourceMode;
-
- if (isValid())
- m_process->send(Messages::WebPage::SetMainFrameInViewSourceMode(mainFrameInViewSourceMode), m_pageID);
-}
-
void WebPageProxy::didSaveToPageCache()
{
m_process->didSaveToPageCache();
@@ -4433,4 +6214,636 @@ void WebPageProxy::setScrollPinningBehavior(ScrollPinningBehavior pinning)
m_process->send(Messages::WebPage::SetScrollPinningBehavior(pinning), m_pageID);
}
+void WebPageProxy::setOverlayScrollbarStyle(std::optional<WebCore::ScrollbarOverlayStyle> scrollbarStyle)
+{
+ if (!m_scrollbarOverlayStyle && !scrollbarStyle)
+ return;
+
+ if ((m_scrollbarOverlayStyle && scrollbarStyle) && m_scrollbarOverlayStyle.value() == scrollbarStyle.value())
+ return;
+
+ m_scrollbarOverlayStyle = scrollbarStyle;
+
+ std::optional<uint32_t> scrollbarStyleForMessage;
+ if (scrollbarStyle)
+ scrollbarStyleForMessage = static_cast<ScrollbarOverlayStyle>(scrollbarStyle.value());
+
+ if (isValid())
+ m_process->send(Messages::WebPage::SetScrollbarOverlayStyle(scrollbarStyleForMessage), m_pageID);
+}
+
+#if ENABLE(SUBTLE_CRYPTO)
+void WebPageProxy::wrapCryptoKey(const Vector<uint8_t>& key, bool& succeeded, Vector<uint8_t>& wrappedKey)
+{
+ PageClientProtector protector(m_pageClient);
+
+ Vector<uint8_t> masterKey;
+
+ if (m_navigationClient) {
+ if (RefPtr<API::Data> keyData = m_navigationClient->webCryptoMasterKey(*this))
+ masterKey = keyData->dataReference().vector();
+ } else if (!getDefaultWebCryptoMasterKey(masterKey)) {
+ succeeded = false;
+ return;
+ }
+
+ succeeded = wrapSerializedCryptoKey(masterKey, key, wrappedKey);
+}
+
+void WebPageProxy::unwrapCryptoKey(const Vector<uint8_t>& wrappedKey, bool& succeeded, Vector<uint8_t>& key)
+{
+ PageClientProtector protector(m_pageClient);
+
+ Vector<uint8_t> masterKey;
+
+ if (m_navigationClient) {
+ if (RefPtr<API::Data> keyData = m_navigationClient->webCryptoMasterKey(*this))
+ masterKey = keyData->dataReference().vector();
+ } else if (!getDefaultWebCryptoMasterKey(masterKey)) {
+ succeeded = false;
+ return;
+ }
+
+ succeeded = unwrapSerializedCryptoKey(masterKey, wrappedKey, key);
+}
+#endif
+
+void WebPageProxy::addMIMETypeWithCustomContentProvider(const String& mimeType)
+{
+ m_process->send(Messages::WebPage::AddMIMETypeWithCustomContentProvider(mimeType), m_pageID);
+}
+
+#if PLATFORM(COCOA)
+
+void WebPageProxy::insertTextAsync(const String& text, const EditingRange& replacementRange, bool registerUndoGroup, EditingRangeIsRelativeTo editingRangeIsRelativeTo, bool suppressSelectionUpdate)
+{
+ if (!isValid())
+ return;
+
+ process().send(Messages::WebPage::InsertTextAsync(text, replacementRange, registerUndoGroup, static_cast<uint32_t>(editingRangeIsRelativeTo), suppressSelectionUpdate), m_pageID);
+}
+
+void WebPageProxy::getMarkedRangeAsync(std::function<void (EditingRange, CallbackBase::Error)> callbackFunction)
+{
+ if (!isValid()) {
+ callbackFunction(EditingRange(), CallbackBase::Error::Unknown);
+ return;
+ }
+
+ uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
+ process().send(Messages::WebPage::GetMarkedRangeAsync(callbackID), m_pageID);
+}
+
+void WebPageProxy::getSelectedRangeAsync(std::function<void (EditingRange, CallbackBase::Error)> callbackFunction)
+{
+ if (!isValid()) {
+ callbackFunction(EditingRange(), CallbackBase::Error::Unknown);
+ return;
+ }
+
+ uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
+ process().send(Messages::WebPage::GetSelectedRangeAsync(callbackID), m_pageID);
+}
+
+void WebPageProxy::characterIndexForPointAsync(const WebCore::IntPoint& point, std::function<void (uint64_t, CallbackBase::Error)> callbackFunction)
+{
+ if (!isValid()) {
+ callbackFunction(0, CallbackBase::Error::Unknown);
+ return;
+ }
+
+ uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
+ process().send(Messages::WebPage::CharacterIndexForPointAsync(point, callbackID), m_pageID);
+}
+
+void WebPageProxy::firstRectForCharacterRangeAsync(const EditingRange& range, std::function<void (const WebCore::IntRect&, const EditingRange&, CallbackBase::Error)> callbackFunction)
+{
+ if (!isValid()) {
+ callbackFunction(WebCore::IntRect(), EditingRange(), CallbackBase::Error::Unknown);
+ return;
+ }
+
+ uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
+ process().send(Messages::WebPage::FirstRectForCharacterRangeAsync(range, callbackID), m_pageID);
+}
+
+void WebPageProxy::setCompositionAsync(const String& text, Vector<CompositionUnderline> underlines, const EditingRange& selectionRange, const EditingRange& replacementRange)
+{
+ if (!isValid()) {
+ // If this fails, we should call -discardMarkedText on input context to notify the input method.
+ // This will happen naturally later, as part of reloading the page.
+ return;
+ }
+
+ process().send(Messages::WebPage::SetCompositionAsync(text, underlines, selectionRange, replacementRange), m_pageID);
+}
+
+void WebPageProxy::confirmCompositionAsync()
+{
+ if (!isValid())
+ return;
+
+ process().send(Messages::WebPage::ConfirmCompositionAsync(), m_pageID);
+}
+
+void WebPageProxy::setScrollPerformanceDataCollectionEnabled(bool enabled)
+{
+ if (enabled == m_scrollPerformanceDataCollectionEnabled)
+ return;
+
+ m_scrollPerformanceDataCollectionEnabled = enabled;
+
+ if (m_scrollPerformanceDataCollectionEnabled && !m_scrollingPerformanceData)
+ m_scrollingPerformanceData = std::make_unique<RemoteLayerTreeScrollingPerformanceData>(downcast<RemoteLayerTreeDrawingAreaProxy>(*m_drawingArea));
+ else if (!m_scrollPerformanceDataCollectionEnabled)
+ m_scrollingPerformanceData = nullptr;
+}
+#endif
+
+void WebPageProxy::takeSnapshot(IntRect rect, IntSize bitmapSize, SnapshotOptions options, std::function<void (const ShareableBitmap::Handle&, CallbackBase::Error)> callbackFunction)
+{
+ if (!isValid()) {
+ callbackFunction(ShareableBitmap::Handle(), CallbackBase::Error::Unknown);
+ return;
+ }
+
+ uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
+ m_process->send(Messages::WebPage::TakeSnapshot(rect, bitmapSize, options, callbackID), m_pageID);
+}
+
+void WebPageProxy::navigationGestureDidBegin()
+{
+ PageClientProtector protector(m_pageClient);
+
+ m_isShowingNavigationGestureSnapshot = true;
+ m_pageClient.navigationGestureDidBegin();
+
+ if (m_navigationClient)
+ m_navigationClient->didBeginNavigationGesture(*this);
+ else
+ m_loaderClient->navigationGestureDidBegin(*this);
+}
+
+void WebPageProxy::navigationGestureWillEnd(bool willNavigate, WebBackForwardListItem& item)
+{
+ PageClientProtector protector(m_pageClient);
+
+ m_pageClient.navigationGestureWillEnd(willNavigate, item);
+
+ if (m_navigationClient)
+ m_navigationClient->willEndNavigationGesture(*this, willNavigate, item);
+ else
+ m_loaderClient->navigationGestureWillEnd(*this, willNavigate, item);
+}
+
+void WebPageProxy::navigationGestureDidEnd(bool willNavigate, WebBackForwardListItem& item)
+{
+ PageClientProtector protector(m_pageClient);
+
+ m_pageClient.navigationGestureDidEnd(willNavigate, item);
+
+ if (m_navigationClient)
+ m_navigationClient->didEndNavigationGesture(*this, willNavigate, item);
+ else
+ m_loaderClient->navigationGestureDidEnd(*this, willNavigate, item);
+}
+
+void WebPageProxy::navigationGestureDidEnd()
+{
+ PageClientProtector protector(m_pageClient);
+
+ m_pageClient.navigationGestureDidEnd();
+}
+
+void WebPageProxy::willRecordNavigationSnapshot(WebBackForwardListItem& item)
+{
+ PageClientProtector protector(m_pageClient);
+
+ m_pageClient.willRecordNavigationSnapshot(item);
+}
+
+void WebPageProxy::navigationGestureSnapshotWasRemoved()
+{
+ m_isShowingNavigationGestureSnapshot = false;
+
+ m_pageClient.didRemoveNavigationGestureSnapshot();
+
+ if (m_navigationClient)
+ m_navigationClient->didRemoveNavigationGestureSnapshot(*this);
+}
+
+void WebPageProxy::isPlayingMediaDidChange(MediaProducer::MediaStateFlags state, uint64_t sourceElementID)
+{
+#if ENABLE(MEDIA_SESSION)
+ WebMediaSessionFocusManager* focusManager = process().processPool().supplement<WebMediaSessionFocusManager>();
+ ASSERT(focusManager);
+ focusManager->updatePlaybackAttributesFromMediaState(this, sourceElementID, state);
+#endif
+
+ if (state == m_mediaState)
+ return;
+
+#if ENABLE(MEDIA_STREAM)
+ WebCore::MediaProducer::MediaStateFlags oldMediaStateHasActiveCapture = m_mediaState & (WebCore::MediaProducer::HasActiveAudioCaptureDevice | WebCore::MediaProducer::HasActiveVideoCaptureDevice);
+ WebCore::MediaProducer::MediaStateFlags newMediaStateHasActiveCapture = state & (WebCore::MediaProducer::HasActiveAudioCaptureDevice | WebCore::MediaProducer::HasActiveVideoCaptureDevice);
+#endif
+
+ MediaProducer::MediaStateFlags playingMediaMask = MediaProducer::IsPlayingAudio | MediaProducer::IsPlayingVideo;
+ MediaProducer::MediaStateFlags oldState = m_mediaState;
+ m_mediaState = state;
+
+#if ENABLE(MEDIA_STREAM)
+ if (!oldMediaStateHasActiveCapture && newMediaStateHasActiveCapture) {
+ m_uiClient->didBeginCaptureSession();
+ userMediaPermissionRequestManager().startedCaptureSession();
+ } else if (oldMediaStateHasActiveCapture && !newMediaStateHasActiveCapture) {
+ m_uiClient->didEndCaptureSession();
+ userMediaPermissionRequestManager().endedCaptureSession();
+ }
+#endif
+
+ activityStateDidChange(ActivityState::IsAudible);
+
+ playingMediaMask |= MediaProducer::HasActiveAudioCaptureDevice | MediaProducer::HasActiveVideoCaptureDevice;
+ if ((oldState & playingMediaMask) != (m_mediaState & playingMediaMask))
+ m_uiClient->isPlayingAudioDidChange(*this);
+#if PLATFORM(MAC)
+ if ((oldState & MediaProducer::HasAudioOrVideo) != (m_mediaState & MediaProducer::HasAudioOrVideo))
+ videoControlsManagerDidChange();
+#endif
+}
+
+#if PLATFORM(MAC)
+void WebPageProxy::videoControlsManagerDidChange()
+{
+ m_pageClient.videoControlsManagerDidChange();
+}
+
+bool WebPageProxy::hasActiveVideoForControlsManager() const
+{
+#if ENABLE(VIDEO_PRESENTATION_MODE)
+ return m_playbackSessionManager && m_playbackSessionManager->controlsManagerInterface();
+#else
+ return false;
+#endif
+}
+
+void WebPageProxy::requestControlledElementID() const
+{
+#if ENABLE(VIDEO_PRESENTATION_MODE)
+ if (m_playbackSessionManager)
+ m_playbackSessionManager->requestControlledElementID();
+#endif
+}
+
+void WebPageProxy::handleControlledElementIDResponse(const String& identifier) const
+{
+ m_pageClient.handleControlledElementIDResponse(identifier);
+}
+
+bool WebPageProxy::isPlayingVideoInEnhancedFullscreen() const
+{
+#if ENABLE(VIDEO_PRESENTATION_MODE)
+ return m_videoFullscreenManager && m_videoFullscreenManager->isPlayingVideoInEnhancedFullscreen();
+#else
+ return false;
+#endif
+}
+#endif
+
+#if PLATFORM(COCOA)
+void WebPageProxy::requestActiveNowPlayingSessionInfo()
+{
+ m_process->send(Messages::WebPage::RequestActiveNowPlayingSessionInfo(), m_pageID);
+}
+
+void WebPageProxy::handleActiveNowPlayingSessionInfoResponse(bool hasActiveSession, const String& title, double duration, double elapsedTime) const
+{
+ m_pageClient.handleActiveNowPlayingSessionInfoResponse(hasActiveSession, title, duration, elapsedTime);
+}
+#endif
+
+#if ENABLE(MEDIA_SESSION)
+void WebPageProxy::hasMediaSessionWithActiveMediaElementsDidChange(bool state)
+{
+ m_hasMediaSessionWithActiveMediaElements = state;
+}
+
+void WebPageProxy::mediaSessionMetadataDidChange(const WebCore::MediaSessionMetadata& metadata)
+{
+ Ref<WebMediaSessionMetadata> webMetadata = WebMediaSessionMetadata::create(metadata);
+ m_uiClient->mediaSessionMetadataDidChange(*this, webMetadata.ptr());
+}
+
+void WebPageProxy::focusedContentMediaElementDidChange(uint64_t elementID)
+{
+ WebMediaSessionFocusManager* focusManager = process().processPool().supplement<WebMediaSessionFocusManager>();
+ ASSERT(focusManager);
+ focusManager->setFocusedMediaElement(*this, elementID);
+}
+#endif
+
+void WebPageProxy::didPlayMediaPreventedFromPlayingWithoutUserGesture()
+{
+ m_uiClient->didPlayMediaPreventedFromPlayingWithoutUserGesture(*this);
+}
+
+#if PLATFORM(MAC)
+void WebPageProxy::removeNavigationGestureSnapshot()
+{
+ m_pageClient.removeNavigationGestureSnapshot();
+}
+
+void WebPageProxy::performImmediateActionHitTestAtLocation(FloatPoint point)
+{
+ m_process->send(Messages::WebPage::PerformImmediateActionHitTestAtLocation(point), m_pageID);
+}
+
+void WebPageProxy::immediateActionDidUpdate()
+{
+ m_process->send(Messages::WebPage::ImmediateActionDidUpdate(), m_pageID);
+}
+
+void WebPageProxy::immediateActionDidCancel()
+{
+ m_process->send(Messages::WebPage::ImmediateActionDidCancel(), m_pageID);
+}
+
+void WebPageProxy::immediateActionDidComplete()
+{
+ m_process->send(Messages::WebPage::ImmediateActionDidComplete(), m_pageID);
+}
+
+void WebPageProxy::didPerformImmediateActionHitTest(const WebHitTestResultData& result, bool contentPreventsDefault, const UserData& userData)
+{
+ m_pageClient.didPerformImmediateActionHitTest(result, contentPreventsDefault, m_process->transformHandlesToObjects(userData.object()).get());
+}
+
+void* WebPageProxy::immediateActionAnimationControllerForHitTestResult(RefPtr<API::HitTestResult> hitTestResult, uint64_t type, RefPtr<API::Object> userData)
+{
+ return m_pageClient.immediateActionAnimationControllerForHitTestResult(hitTestResult, type, userData);
+}
+
+void WebPageProxy::installActivityStateChangeCompletionHandler(void (^completionHandler)())
+{
+ if (!isValid()) {
+ completionHandler();
+ return;
+ }
+
+ auto copiedCompletionHandler = Block_copy(completionHandler);
+ auto voidCallback = VoidCallback::create([copiedCompletionHandler] (CallbackBase::Error) {
+ copiedCompletionHandler();
+ Block_release(copiedCompletionHandler);
+ }, m_process->throttler().backgroundActivityToken());
+ uint64_t callbackID = m_callbacks.put(WTFMove(voidCallback));
+ m_nextActivityStateChangeCallbacks.append(callbackID);
+}
+
+void WebPageProxy::handleAcceptedCandidate(WebCore::TextCheckingResult acceptedCandidate)
+{
+ m_process->send(Messages::WebPage::HandleAcceptedCandidate(acceptedCandidate), m_pageID);
+}
+
+void WebPageProxy::didHandleAcceptedCandidate()
+{
+ m_pageClient.didHandleAcceptedCandidate();
+}
+
+void WebPageProxy::setHeaderBannerHeightForTesting(int height)
+{
+ m_process->send(Messages::WebPage::SetHeaderBannerHeightForTesting(height), m_pageID);
+}
+
+void WebPageProxy::setFooterBannerHeightForTesting(int height)
+{
+ m_process->send(Messages::WebPage::SetFooterBannerHeightForTesting(height), m_pageID);
+}
+
+#endif
+
+void WebPageProxy::imageOrMediaDocumentSizeChanged(const WebCore::IntSize& newSize)
+{
+ m_uiClient->imageOrMediaDocumentSizeChanged(newSize);
+}
+
+void WebPageProxy::setShouldDispatchFakeMouseMoveEvents(bool shouldDispatchFakeMouseMoveEvents)
+{
+ m_process->send(Messages::WebPage::SetShouldDispatchFakeMouseMoveEvents(shouldDispatchFakeMouseMoveEvents), m_pageID);
+}
+
+void WebPageProxy::handleAutoFillButtonClick(const UserData& userData)
+{
+ m_uiClient->didClickAutoFillButton(*this, m_process->transformHandlesToObjects(userData.object()).get());
+}
+
+#if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
+void WebPageProxy::addPlaybackTargetPickerClient(uint64_t contextId)
+{
+ m_pageClient.mediaSessionManager().addPlaybackTargetPickerClient(*this, contextId);
+}
+
+void WebPageProxy::removePlaybackTargetPickerClient(uint64_t contextId)
+{
+ m_pageClient.mediaSessionManager().removePlaybackTargetPickerClient(*this, contextId);
+}
+
+void WebPageProxy::showPlaybackTargetPicker(uint64_t contextId, const WebCore::FloatRect& rect, bool hasVideo)
+{
+ m_pageClient.mediaSessionManager().showPlaybackTargetPicker(*this, contextId, m_pageClient.rootViewToScreen(IntRect(rect)), hasVideo);
+}
+
+void WebPageProxy::playbackTargetPickerClientStateDidChange(uint64_t contextId, WebCore::MediaProducer::MediaStateFlags state)
+{
+ m_pageClient.mediaSessionManager().clientStateDidChange(*this, contextId, state);
+}
+
+void WebPageProxy::setMockMediaPlaybackTargetPickerEnabled(bool enabled)
+{
+ m_pageClient.mediaSessionManager().setMockMediaPlaybackTargetPickerEnabled(enabled);
+}
+
+void WebPageProxy::setMockMediaPlaybackTargetPickerState(const String& name, WebCore::MediaPlaybackTargetContext::State state)
+{
+ m_pageClient.mediaSessionManager().setMockMediaPlaybackTargetPickerState(name, state);
+}
+
+void WebPageProxy::setPlaybackTarget(uint64_t contextId, Ref<MediaPlaybackTarget>&& target)
+{
+ if (!isValid())
+ return;
+
+ m_process->send(Messages::WebPage::PlaybackTargetSelected(contextId, target->targetContext()), m_pageID);
+}
+
+void WebPageProxy::externalOutputDeviceAvailableDidChange(uint64_t contextId, bool available)
+{
+ if (!isValid())
+ return;
+
+ m_process->send(Messages::WebPage::PlaybackTargetAvailabilityDidChange(contextId, available), m_pageID);
+}
+
+void WebPageProxy::setShouldPlayToPlaybackTarget(uint64_t contextId, bool shouldPlay)
+{
+ if (!isValid())
+ return;
+
+ m_process->send(Messages::WebPage::SetShouldPlayToPlaybackTarget(contextId, shouldPlay), m_pageID);
+}
+#endif
+
+void WebPageProxy::didChangeBackgroundColor()
+{
+ m_pageClient.didChangeBackgroundColor();
+}
+
+void WebPageProxy::clearWheelEventTestTrigger()
+{
+ if (!isValid())
+ return;
+
+ m_process->send(Messages::WebPage::ClearWheelEventTestTrigger(), m_pageID);
+}
+
+void WebPageProxy::callAfterNextPresentationUpdate(std::function<void (CallbackBase::Error)> callback)
+{
+ if (!isValid() || !m_drawingArea) {
+ callback(CallbackBase::Error::OwnerWasInvalidated);
+ return;
+ }
+
+ m_drawingArea->dispatchAfterEnsuringDrawing(callback);
+}
+
+void WebPageProxy::setShouldScaleViewToFitDocument(bool shouldScaleViewToFitDocument)
+{
+ if (m_shouldScaleViewToFitDocument == shouldScaleViewToFitDocument)
+ return;
+
+ m_shouldScaleViewToFitDocument = shouldScaleViewToFitDocument;
+
+ if (!isValid())
+ return;
+
+ m_process->send(Messages::WebPage::SetShouldScaleViewToFitDocument(shouldScaleViewToFitDocument), m_pageID);
+}
+
+void WebPageProxy::didRestoreScrollPosition()
+{
+ m_pageClient.didRestoreScrollPosition();
+}
+
+void WebPageProxy::getLoadDecisionForIcon(const WebCore::LinkIcon& icon, uint64_t loadIdentifier)
+{
+ if (!m_iconLoadingClient)
+ return;
+
+ m_iconLoadingClient->getLoadDecisionForIcon(icon, [this, protectedThis = RefPtr<WebPageProxy>(this), loadIdentifier](std::function<void (API::Data*, CallbackBase::Error)> callbackFunction) {
+ if (!isValid()) {
+ if (callbackFunction)
+ callbackFunction(nullptr, CallbackBase::Error::Unknown);
+ return;
+ }
+
+ bool decision = (bool)callbackFunction;
+ uint64_t newCallbackIdentifier = decision ? m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken()) : 0;
+
+ m_process->send(Messages::WebPage::DidGetLoadDecisionForIcon(decision, loadIdentifier, newCallbackIdentifier), m_pageID);
+ });
+}
+
+void WebPageProxy::finishedLoadingIcon(uint64_t callbackIdentifier, const IPC::DataReference& data)
+{
+ dataCallback(data, callbackIdentifier);
+}
+
+void WebPageProxy::setResourceCachingDisabled(bool disabled)
+{
+ if (m_isResourceCachingDisabled == disabled)
+ return;
+
+ m_isResourceCachingDisabled = disabled;
+
+ if (!isValid())
+ return;
+
+ m_process->send(Messages::WebPage::SetResourceCachingDisabled(disabled), m_pageID);
+}
+
+WebCore::UserInterfaceLayoutDirection WebPageProxy::userInterfaceLayoutDirection()
+{
+ return m_pageClient.userInterfaceLayoutDirection();
+}
+
+void WebPageProxy::setUserInterfaceLayoutDirection(WebCore::UserInterfaceLayoutDirection userInterfaceLayoutDirection)
+{
+ if (!isValid())
+ return;
+
+ m_process->send(Messages::WebPage::SetUserInterfaceLayoutDirection(static_cast<uint32_t>(userInterfaceLayoutDirection)), m_pageID);
+}
+
+void WebPageProxy::hideValidationMessage()
+{
+#if PLATFORM(COCOA)
+ m_validationBubble = nullptr;
+#endif
+}
+
+#if ENABLE(POINTER_LOCK)
+void WebPageProxy::requestPointerLock()
+{
+ ASSERT(!m_isPointerLockPending);
+ ASSERT(!m_isPointerLocked);
+ m_isPointerLockPending = true;
+
+ if (!isViewVisible() || !(m_activityState & ActivityState::IsFocused)) {
+ didDenyPointerLock();
+ return;
+ }
+ m_uiClient->requestPointerLock(this);
+}
+
+void WebPageProxy::didAllowPointerLock()
+{
+ ASSERT(m_isPointerLockPending && !m_isPointerLocked);
+ m_isPointerLocked = true;
+ m_isPointerLockPending = false;
+#if PLATFORM(MAC)
+ CGDisplayHideCursor(CGMainDisplayID());
+ CGAssociateMouseAndMouseCursorPosition(false);
+#endif
+ m_process->send(Messages::WebPage::DidAcquirePointerLock(), m_pageID);
+}
+
+void WebPageProxy::didDenyPointerLock()
+{
+ ASSERT(m_isPointerLockPending && !m_isPointerLocked);
+ m_isPointerLockPending = false;
+ m_process->send(Messages::WebPage::DidNotAcquirePointerLock(), m_pageID);
+}
+
+void WebPageProxy::requestPointerUnlock()
+{
+ if (m_isPointerLocked) {
+#if PLATFORM(MAC)
+ CGAssociateMouseAndMouseCursorPosition(true);
+ CGDisplayShowCursor(CGMainDisplayID());
+#endif
+ m_uiClient->didLosePointerLock(this);
+ m_process->send(Messages::WebPage::DidLosePointerLock(), m_pageID);
+ }
+
+ if (m_isPointerLockPending) {
+ m_uiClient->didLosePointerLock(this);
+ m_process->send(Messages::WebPage::DidNotAcquirePointerLock(), m_pageID);
+ }
+
+ m_isPointerLocked = false;
+ m_isPointerLockPending = false;
+}
+#endif
+
+
} // namespace WebKit