2 * Copyright (C) 2010, 2011 Apple Inc. All rights reserved.
3 * Copyright (C) 2012 Intel Corporation. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
18 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24 * THE POSSIBILITY OF SUCH DAMAGE.
28 #include "WebPageProxy.h"
31 #include "APIFindClient.h"
32 #include "APIFormClient.h"
33 #include "APILoaderClient.h"
34 #include "APIPolicyClient.h"
35 #include "APIUIClient.h"
36 #include "APIURLRequest.h"
37 #include "AuthenticationChallengeProxy.h"
38 #include "AuthenticationDecisionListener.h"
39 #include "DataReference.h"
40 #include "DownloadProxy.h"
41 #include "DrawingAreaProxy.h"
42 #include "DrawingAreaProxyMessages.h"
43 #include "EventDispatcherMessages.h"
44 #include "FindIndicator.h"
46 #include "NativeWebKeyboardEvent.h"
47 #include "NativeWebMouseEvent.h"
48 #include "NativeWebWheelEvent.h"
49 #include "NavigationActionData.h"
50 #include "NotificationPermissionRequest.h"
51 #include "NotificationPermissionRequestManager.h"
52 #include "PageClient.h"
53 #include "PluginInformation.h"
54 #include "PluginProcessManager.h"
55 #include "PrintInfo.h"
56 #include "TextChecker.h"
57 #include "TextCheckerState.h"
58 #include "WKContextPrivate.h"
59 #include "WebBackForwardList.h"
60 #include "WebBackForwardListItem.h"
61 #include "WebCertificateInfo.h"
62 #include "WebContext.h"
63 #include "WebContextMenuProxy.h"
64 #include "WebContextUserMessageCoders.h"
65 #include "WebCoreArgumentCoders.h"
66 #include "WebEditCommandProxy.h"
68 #include "WebEventConversion.h"
69 #include "WebFormSubmissionListenerProxy.h"
70 #include "WebFramePolicyListenerProxy.h"
71 #include "WebFullScreenManagerProxy.h"
72 #include "WebFullScreenManagerProxyMessages.h"
73 #include "WebInspectorProxy.h"
74 #include "WebInspectorProxyMessages.h"
75 #include "WebNotificationManagerProxy.h"
76 #include "WebOpenPanelParameters.h"
77 #include "WebOpenPanelResultListenerProxy.h"
78 #include "WebPageCreationParameters.h"
79 #include "WebPageGroup.h"
80 #include "WebPageGroupData.h"
81 #include "WebPageMessages.h"
82 #include "WebPageProxyMessages.h"
83 #include "WebPopupItem.h"
84 #include "WebPopupMenuProxy.h"
85 #include "WebPreferences.h"
86 #include "WebProcessMessages.h"
87 #include "WebProcessProxy.h"
88 #include "WebProtectionSpace.h"
89 #include "WebSecurityOrigin.h"
90 #include "WebUserContentControllerProxy.h"
91 #include <WebCore/DragController.h>
92 #include <WebCore/DragData.h>
93 #include <WebCore/FloatRect.h>
94 #include <WebCore/FocusDirection.h>
95 #include <WebCore/MIMETypeRegistry.h>
96 #include <WebCore/RenderEmbeddedObject.h>
97 #include <WebCore/SerializedCryptoKeyWrap.h>
98 #include <WebCore/TextCheckerClient.h>
99 #include <WebCore/WindowFeatures.h>
101 #include <wtf/NeverDestroyed.h>
102 #include <wtf/text/StringView.h>
104 #if ENABLE(ASYNC_SCROLLING)
105 #include "RemoteScrollingCoordinatorProxy.h"
108 #if USE(COORDINATED_GRAPHICS)
109 #include "CoordinatedLayerTreeHostProxyMessages.h"
113 #include "ArgumentCodersGtk.h"
116 #if USE(SOUP) && !ENABLE(CUSTOM_PROTOCOLS)
117 #include "WebSoupRequestManagerProxy.h"
120 #if ENABLE(VIBRATION)
121 #include "WebVibrationProxy.h"
125 #include <wtf/RefCountedLeakCounter.h>
128 #if ENABLE(NETWORK_PROCESS)
129 #include "NetworkProcessMessages.h"
133 #include "ViewSnapshotStore.h"
134 #include <WebCore/RunLoopObserver.h>
138 #include "WebVideoFullscreenManagerProxy.h"
139 #include "WebVideoFullscreenManagerProxyMessages.h"
143 #include <WebCore/CairoUtilities.h>
146 // This controls what strategy we use for mouse wheel coalescing.
147 #define MERGE_WHEEL_EVENTS 1
149 #define MESSAGE_CHECK(assertion) MESSAGE_CHECK_BASE(assertion, m_process->connection())
150 #define MESSAGE_CHECK_URL(url) MESSAGE_CHECK_BASE(m_process->checkURLReceivedFromWebProcess(url), m_process->connection())
152 using namespace WebCore;
154 // Represents the number of wheel events we can hold in the queue before we start pushing them preemptively.
155 static const unsigned wheelEventQueueSizeThreshold = 10;
159 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, webPageProxyCounter, ("WebPageProxy"));
161 class ExceededDatabaseQuotaRecords {
162 WTF_MAKE_NONCOPYABLE(ExceededDatabaseQuotaRecords); WTF_MAKE_FAST_ALLOCATED;
163 friend class NeverDestroyed<ExceededDatabaseQuotaRecords>;
167 String originIdentifier;
170 uint64_t currentQuota;
171 uint64_t currentOriginUsage;
172 uint64_t currentDatabaseUsage;
173 uint64_t expectedUsage;
174 RefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply> reply;
177 static ExceededDatabaseQuotaRecords& shared();
179 std::unique_ptr<Record> createRecord(uint64_t frameID, String originIdentifier,
180 String databaseName, String displayName, uint64_t currentQuota,
181 uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage,
182 PassRefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply>);
184 void add(std::unique_ptr<Record>);
185 bool areBeingProcessed() const { return !!m_currentRecord; }
189 ExceededDatabaseQuotaRecords() { }
190 ~ExceededDatabaseQuotaRecords() { }
192 Deque<std::unique_ptr<Record>> m_records;
193 std::unique_ptr<Record> m_currentRecord;
196 ExceededDatabaseQuotaRecords& ExceededDatabaseQuotaRecords::shared()
198 static NeverDestroyed<ExceededDatabaseQuotaRecords> records;
202 std::unique_ptr<ExceededDatabaseQuotaRecords::Record> ExceededDatabaseQuotaRecords::createRecord(
203 uint64_t frameID, String originIdentifier, String databaseName, String displayName,
204 uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage,
205 uint64_t expectedUsage, PassRefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply> reply)
207 auto record = std::make_unique<Record>();
208 record->frameID = frameID;
209 record->originIdentifier = originIdentifier;
210 record->databaseName = databaseName;
211 record->displayName = displayName;
212 record->currentQuota = currentQuota;
213 record->currentOriginUsage = currentOriginUsage;
214 record->currentDatabaseUsage = currentDatabaseUsage;
215 record->expectedUsage = expectedUsage;
216 record->reply = reply;
217 return WTF::move(record);
220 void ExceededDatabaseQuotaRecords::add(std::unique_ptr<ExceededDatabaseQuotaRecords::Record> record)
222 m_records.append(WTF::move(record));
225 ExceededDatabaseQuotaRecords::Record* ExceededDatabaseQuotaRecords::next()
227 m_currentRecord = nullptr;
228 if (!m_records.isEmpty())
229 m_currentRecord = m_records.takeFirst();
230 return m_currentRecord.get();
234 static const char* webKeyboardEventTypeString(WebEvent::Type type)
237 case WebEvent::KeyDown:
240 case WebEvent::KeyUp:
243 case WebEvent::RawKeyDown:
250 ASSERT_NOT_REACHED();
254 #endif // !LOG_DISABLED
256 PassRefPtr<WebPageProxy> WebPageProxy::create(PageClient& pageClient, WebProcessProxy& process, uint64_t pageID, const WebPageConfiguration& configuration)
258 return adoptRef(new WebPageProxy(pageClient, process, pageID, configuration));
261 WebPageProxy::WebPageProxy(PageClient& pageClient, WebProcessProxy& process, uint64_t pageID, const WebPageConfiguration& configuration)
262 : m_pageClient(pageClient)
263 , m_loaderClient(std::make_unique<API::LoaderClient>())
264 , m_policyClient(std::make_unique<API::PolicyClient>())
265 , m_formClient(std::make_unique<API::FormClient>())
266 , m_uiClient(std::make_unique<API::UIClient>())
267 , m_findClient(std::make_unique<API::FindClient>())
269 , m_pageGroup(*configuration.pageGroup)
270 , m_preferences(*configuration.preferences)
271 , m_userContentController(configuration.userContentController)
272 , m_visitedLinkProvider(*configuration.visitedLinkProvider)
273 , m_mainFrame(nullptr)
274 , m_userAgent(standardUserAgent())
276 , m_deviceOrientation(0)
277 , m_dynamicViewportSizeUpdateWaitingForTarget(false)
278 , m_dynamicViewportSizeUpdateWaitingForLayerTreeCommit(false)
279 , m_dynamicViewportSizeUpdateLayerTreeTransactionID(0)
281 , m_geolocationPermissionRequestManager(*this)
282 , m_notificationPermissionRequestManager(*this)
283 , m_viewState(ViewState::NoFlags)
284 , m_viewWasEverInWindow(false)
285 , m_backForwardList(WebBackForwardList::create(*this))
286 , m_loadStateAtProcessExit(FrameLoadState::State::Finished)
287 #if PLATFORM(MAC) && !USE(ASYNC_NSTEXTINPUTCLIENT)
288 , m_temporarilyClosedComposition(false)
290 , m_textZoomFactor(1)
291 , m_pageZoomFactor(1)
292 , m_pageScaleFactor(1)
293 , m_intrinsicDeviceScaleFactor(1)
294 , m_customDeviceScaleFactor(0)
295 , m_topContentInset(0)
296 , m_layerHostingMode(LayerHostingMode::InProcess)
297 , m_drawsBackground(true)
298 , m_drawsTransparentBackground(false)
299 , m_useFixedLayout(false)
300 , m_suppressScrollbarAnimations(false)
301 , m_paginationMode(Pagination::Unpaginated)
302 , m_paginationBehavesLikeColumns(false)
304 , m_gapBetweenPages(0)
307 , m_canRunModal(false)
308 , m_isInPrintingMode(false)
309 , m_isPerformingDOMPrintOperation(false)
310 , m_inDecidePolicyForResponseSync(false)
311 , m_decidePolicyForResponseRequest(0)
312 , m_syncMimeTypePolicyActionIsValid(false)
313 , m_syncMimeTypePolicyAction(PolicyUse)
314 , m_syncMimeTypePolicyDownloadID(0)
315 , m_inDecidePolicyForNavigationAction(false)
316 , m_syncNavigationActionPolicyActionIsValid(false)
317 , m_syncNavigationActionPolicyAction(PolicyUse)
318 , m_syncNavigationActionPolicyDownloadID(0)
319 , m_processingMouseMoveEvent(false)
320 #if ENABLE(TOUCH_EVENTS)
321 , m_isTrackingTouchEvents(false)
324 , m_session(*configuration.session)
325 , m_isPageSuspended(false)
326 , m_addsVisitedLinks(true)
327 #if ENABLE(REMOTE_INSPECTOR)
328 , m_allowsRemoteInspection(true)
331 , m_isSmartInsertDeleteEnabled(TextChecker::isSmartInsertDeleteEnabled())
333 , m_spellDocumentTag(0)
334 , m_hasSpellDocumentTag(false)
335 , m_pendingLearnOrIgnoreWordMessageCount(0)
336 , m_mainFrameHasCustomContentProvider(false)
337 #if ENABLE(DRAG_SUPPORT)
338 , m_currentDragOperation(DragOperationNone)
339 , m_currentDragIsOverFileInput(false)
340 , m_currentDragNumberOfFilesToBeAccepted(0)
342 , m_pageLoadState(*this)
343 , m_delegatesScrolling(false)
344 , m_mainFrameHasHorizontalScrollbar(false)
345 , m_mainFrameHasVerticalScrollbar(false)
346 , m_canShortCircuitHorizontalWheelEvents(true)
347 , m_mainFrameIsPinnedToLeftSide(true)
348 , m_mainFrameIsPinnedToRightSide(true)
349 , m_mainFrameIsPinnedToTopSide(true)
350 , m_mainFrameIsPinnedToBottomSide(true)
351 , m_shouldUseImplicitRubberBandControl(false)
352 , m_rubberBandsAtLeft(true)
353 , m_rubberBandsAtRight(true)
354 , m_rubberBandsAtTop(true)
355 , m_rubberBandsAtBottom(true)
356 , m_enableVerticalRubberBanding(true)
357 , m_enableHorizontalRubberBanding(true)
358 , m_backgroundExtendsBeyondPage(false)
359 , m_shouldRecordNavigationSnapshots(false)
360 , m_isShowingNavigationGestureSnapshot(false)
362 , m_renderTreeSize(0)
363 , m_shouldSendEventsSynchronously(false)
364 , m_suppressVisibilityUpdates(false)
365 , m_autoSizingShouldExpandToViewHeight(false)
367 , m_mayStartMediaWhenInWindow(true)
368 , m_scrollPinningBehavior(DoNotPin)
370 , m_configurationPreferenceValues(configuration.preferenceValues)
371 , m_potentiallyChangedViewStateFlags(ViewState::NoFlags)
372 , m_viewStateChangeWantsReply(false)
374 if (m_process->state() == WebProcessProxy::State::Running) {
375 if (m_userContentController)
376 m_userContentController->addProcess(m_process.get());
377 m_visitedLinkProvider->addProcess(m_process.get());
381 updateActivityToken();
383 #if HAVE(OUT_OF_PROCESS_LAYER_HOSTING)
384 m_layerHostingMode = m_viewState & ViewState::IsInWindow ? m_pageClient.viewLayerHostingMode() : LayerHostingMode::OutOfProcess;
387 platformInitialize();
390 webPageProxyCounter.increment();
393 WebContext::statistics().wkPageCount++;
395 m_preferences->addPage(*this);
396 m_pageGroup->addPage(this);
398 #if ENABLE(INSPECTOR)
399 m_inspector = WebInspectorProxy::create(this);
401 #if ENABLE(FULLSCREEN_API)
402 m_fullScreenManager = WebFullScreenManagerProxy::create(*this, m_pageClient.fullScreenManagerProxyClient());
405 m_videoFullscreenManager = WebVideoFullscreenManagerProxy::create(*this);
407 #if ENABLE(VIBRATION)
408 m_vibration = WebVibrationProxy::create(this);
411 m_process->addMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID, *this);
413 // FIXME: If we ever expose the session storage size as a preference, we need to pass it here.
414 IPC::Connection* connection = m_process->state() == WebProcessProxy::State::Running ? m_process->connection() : nullptr;
415 m_process->context().storageManager().createSessionStorageNamespace(m_pageID, connection, std::numeric_limits<unsigned>::max());
416 setSession(*configuration.session);
419 const CFIndex viewStateChangeRunLoopOrder = (CFIndex)RunLoopObserver::WellKnownRunLoopOrders::CoreAnimationCommit - 1;
420 m_viewStateChangeDispatcher = RunLoopObserver::create(viewStateChangeRunLoopOrder, [this]() {
421 this->dispatchViewStateChange();
426 WebPageProxy::~WebPageProxy()
431 WebContext::statistics().wkPageCount--;
433 if (m_hasSpellDocumentTag)
434 TextChecker::closeSpellDocumentWithTag(m_spellDocumentTag);
436 m_preferences->removePage(*this);
437 m_pageGroup->removePage(this);
440 webPageProxyCounter.decrement();
444 PlatformProcessIdentifier WebPageProxy::processIdentifier() const
449 return m_process->processIdentifier();
452 bool WebPageProxy::isValid() const
454 // A page that has been explicitly closed is never valid.
461 void WebPageProxy::setPreferences(WebPreferences& preferences)
463 if (&preferences == &m_preferences.get())
466 m_preferences->removePage(*this);
467 m_preferences = preferences;
468 m_preferences->addPage(*this);
470 preferencesDidChange();
473 void WebPageProxy::setLoaderClient(std::unique_ptr<API::LoaderClient> loaderClient)
476 m_loaderClient = std::make_unique<API::LoaderClient>();
480 m_loaderClient = WTF::move(loaderClient);
483 void WebPageProxy::setPolicyClient(std::unique_ptr<API::PolicyClient> policyClient)
486 m_policyClient = std::make_unique<API::PolicyClient>();
490 m_policyClient = WTF::move(policyClient);
493 void WebPageProxy::setFormClient(std::unique_ptr<API::FormClient> formClient)
496 m_formClient = std::make_unique<API::FormClient>();
500 m_formClient = WTF::move(formClient);
503 void WebPageProxy::setUIClient(std::unique_ptr<API::UIClient> uiClient)
506 m_uiClient = std::make_unique<API::UIClient>();
510 m_uiClient = WTF::move(uiClient);
515 m_process->send(Messages::WebPage::SetCanRunBeforeUnloadConfirmPanel(m_uiClient->canRunBeforeUnloadConfirmPanel()), m_pageID);
516 setCanRunModal(m_uiClient->canRunModal());
519 void WebPageProxy::setFindClient(std::unique_ptr<API::FindClient> findClient)
522 m_findClient = std::make_unique<API::FindClient>();
526 m_findClient = WTF::move(findClient);
529 void WebPageProxy::initializeFindMatchesClient(const WKPageFindMatchesClientBase* client)
531 m_findMatchesClient.initialize(client);
534 #if ENABLE(CONTEXT_MENUS)
535 void WebPageProxy::initializeContextMenuClient(const WKPageContextMenuClientBase* client)
537 m_contextMenuClient.initialize(client);
541 void WebPageProxy::reattachToWebProcess()
545 ASSERT(m_process->state() == WebProcessProxy::State::Terminated);
549 if (m_process->context().processModel() == ProcessModelSharedSecondaryProcess)
550 m_process = m_process->context().ensureSharedWebProcess();
552 m_process = m_process->context().createNewWebProcessRespectingProcessCountLimit();
553 m_process->addExistingWebPage(this, m_pageID);
554 m_process->addMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID, *this);
557 updateActivityToken();
559 #if ENABLE(INSPECTOR)
560 m_inspector = WebInspectorProxy::create(this);
562 #if ENABLE(FULLSCREEN_API)
563 m_fullScreenManager = WebFullScreenManagerProxy::create(*this, m_pageClient.fullScreenManagerProxyClient());
566 m_videoFullscreenManager = WebVideoFullscreenManagerProxy::create(*this);
571 m_pageClient.didRelaunchProcess();
572 m_drawingArea->waitForBackingStoreUpdateOnNextPaint();
575 uint64_t WebPageProxy::reattachToWebProcessWithItem(WebBackForwardListItem* item)
580 if (item && item != m_backForwardList->currentItem())
581 m_backForwardList->goToItem(item);
583 reattachToWebProcess();
588 uint64_t navigationID = generateNavigationID();
590 m_process->send(Messages::WebPage::GoToBackForwardItem(navigationID, item->itemID()), m_pageID);
591 m_process->responsivenessTimer()->start();
596 void WebPageProxy::setSession(API::Session& session)
599 m_process->send(Messages::WebPage::SetSessionID(session.getID()), m_pageID);
601 #if ENABLE(NETWORK_PROCESS)
602 if (session.isEphemeral())
603 m_process->context().sendToNetworkingProcess(Messages::NetworkProcess::EnsurePrivateBrowsingSession(session.getID()));
607 void WebPageProxy::initializeWebPage()
611 BackForwardListItemVector items = m_backForwardList->entries();
612 for (size_t i = 0; i < items.size(); ++i)
613 m_process->registerNewWebBackForwardListItem(items[i].get());
615 m_drawingArea = m_pageClient.createDrawingAreaProxy();
616 ASSERT(m_drawingArea);
618 #if ENABLE(ASYNC_SCROLLING)
619 if (m_drawingArea->type() == DrawingAreaTypeRemoteLayerTree) {
620 m_scrollingCoordinatorProxy = std::make_unique<RemoteScrollingCoordinatorProxy>(*this);
622 // On iOS, main frame scrolls are sent in terms of visible rect updates.
623 m_scrollingCoordinatorProxy->setPropagatesMainFrameScrolls(false);
628 #if ENABLE(INSPECTOR_SERVER)
629 if (pageGroup().preferences().developerExtrasEnabled())
630 inspector()->enableRemoteInspection();
633 process().send(Messages::WebProcess::CreateWebPage(m_pageID, creationParameters()), 0);
636 send(Messages::WebPage::SetSmartInsertDeleteEnabled(m_isSmartInsertDeleteEnabled));
640 bool WebPageProxy::isProcessSuppressible() const
642 return (m_viewState & ViewState::IsVisuallyIdle) && m_preferences->pageVisibilityBasedProcessSuppressionEnabled();
645 void WebPageProxy::close()
652 if (m_process->state() == WebProcessProxy::State::Running) {
653 if (m_userContentController)
654 m_userContentController->removeProcess(m_process.get());
655 m_visitedLinkProvider->removeProcess(m_process.get());
658 m_backForwardList->pageClosed();
659 m_pageClient.pageClosed();
661 m_process->disconnectFramesFromPage(this);
663 resetState(ResetStateReason::PageInvalidated);
665 m_loaderClient = std::make_unique<API::LoaderClient>();
666 m_policyClient = std::make_unique<API::PolicyClient>();
667 m_formClient = std::make_unique<API::FormClient>();
668 m_uiClient = std::make_unique<API::UIClient>();
670 m_uiPopupMenuClient.initialize(0);
672 m_findClient = std::make_unique<API::FindClient>();
673 m_findMatchesClient.initialize(0);
674 #if ENABLE(CONTEXT_MENUS)
675 m_contextMenuClient.initialize(0);
678 m_process->send(Messages::WebPage::Close(), m_pageID);
679 m_process->removeWebPage(m_pageID);
680 m_process->removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID);
681 m_process->context().storageManager().destroySessionStorageNamespace(m_pageID);
682 m_process->context().supplement<WebNotificationManagerProxy>()->clearNotifications(this);
685 bool WebPageProxy::tryClose()
690 m_process->send(Messages::WebPage::TryClose(), m_pageID);
691 m_process->responsivenessTimer()->start();
695 bool WebPageProxy::maybeInitializeSandboxExtensionHandle(const URL& url, SandboxExtension::Handle& sandboxExtensionHandle)
697 if (!url.isLocalFile())
700 if (m_process->hasAssumedReadAccessToURL(url))
703 #if ENABLE(INSPECTOR)
704 // Inspector resources are in a directory with assumed access.
705 ASSERT_WITH_SECURITY_IMPLICATION(!WebInspectorProxy::isInspectorPage(*this));
708 SandboxExtension::createHandle("/", SandboxExtension::ReadOnly, sandboxExtensionHandle);
712 uint64_t WebPageProxy::loadRequest(const ResourceRequest& request, API::Object* userData)
717 uint64_t navigationID = generateNavigationID();
719 auto transaction = m_pageLoadState.transaction();
721 m_pageLoadState.setPendingAPIRequestURL(transaction, request.url());
724 reattachToWebProcess();
726 SandboxExtension::Handle sandboxExtensionHandle;
727 bool createdExtension = maybeInitializeSandboxExtensionHandle(request.url(), sandboxExtensionHandle);
728 if (createdExtension)
729 m_process->willAcquireUniversalFileReadSandboxExtension();
730 m_process->send(Messages::WebPage::LoadRequest(navigationID, request, sandboxExtensionHandle, WebContextUserMessageEncoder(userData, process())), m_pageID);
731 m_process->responsivenessTimer()->start();
736 void WebPageProxy::loadFile(const String& fileURLString, const String& resourceDirectoryURLString, API::Object* userData)
742 reattachToWebProcess();
744 URL fileURL = URL(URL(), fileURLString);
745 if (!fileURL.isLocalFile())
748 URL resourceDirectoryURL;
749 if (resourceDirectoryURLString.isNull())
750 resourceDirectoryURL = URL(ParsedURLString, ASCIILiteral("file:///"));
752 resourceDirectoryURL = URL(URL(), resourceDirectoryURLString);
753 if (!resourceDirectoryURL.isLocalFile())
757 String resourceDirectoryPath = resourceDirectoryURL.fileSystemPath();
759 SandboxExtension::Handle sandboxExtensionHandle;
760 SandboxExtension::createHandle(resourceDirectoryPath, SandboxExtension::ReadOnly, sandboxExtensionHandle);
761 m_process->assumeReadAccessToBaseURL(resourceDirectoryURL);
762 m_process->send(Messages::WebPage::LoadRequest(generateNavigationID(), fileURL, sandboxExtensionHandle, WebContextUserMessageEncoder(userData, process())), m_pageID);
763 m_process->responsivenessTimer()->start();
766 void WebPageProxy::loadData(API::Data* data, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData)
772 reattachToWebProcess();
774 m_process->assumeReadAccessToBaseURL(baseURL);
775 m_process->send(Messages::WebPage::LoadData(data->dataReference(), MIMEType, encoding, baseURL, WebContextUserMessageEncoder(userData, process())), m_pageID);
776 m_process->responsivenessTimer()->start();
779 uint64_t WebPageProxy::loadHTMLString(const String& htmlString, const String& baseURL, API::Object* userData)
784 uint64_t navigationID = generateNavigationID();
786 auto transaction = m_pageLoadState.transaction();
788 String pendingAPIRequestURL = baseURL.isEmpty() ? baseURL : ASCIILiteral("about:blank");
789 m_pageLoadState.setPendingAPIRequestURL(transaction, pendingAPIRequestURL);
792 reattachToWebProcess();
794 m_process->assumeReadAccessToBaseURL(baseURL);
795 m_process->send(Messages::WebPage::LoadHTMLString(navigationID, htmlString, baseURL, WebContextUserMessageEncoder(userData, process())), m_pageID);
796 m_process->responsivenessTimer()->start();
801 void WebPageProxy::loadAlternateHTMLString(const String& htmlString, const String& baseURL, const String& unreachableURL, API::Object* userData)
807 reattachToWebProcess();
809 auto transaction = m_pageLoadState.transaction();
811 m_pageLoadState.setUnreachableURL(transaction, unreachableURL);
814 m_mainFrame->setUnreachableURL(unreachableURL);
816 m_process->assumeReadAccessToBaseURL(baseURL);
817 m_process->send(Messages::WebPage::LoadAlternateHTMLString(htmlString, baseURL, unreachableURL, WebContextUserMessageEncoder(userData, process())), m_pageID);
818 m_process->responsivenessTimer()->start();
821 void WebPageProxy::loadPlainTextString(const String& string, API::Object* userData)
827 reattachToWebProcess();
829 m_process->send(Messages::WebPage::LoadPlainTextString(string, WebContextUserMessageEncoder(userData, process())), m_pageID);
830 m_process->responsivenessTimer()->start();
833 void WebPageProxy::loadWebArchiveData(API::Data* webArchiveData, API::Object* userData)
839 reattachToWebProcess();
841 m_process->send(Messages::WebPage::LoadWebArchiveData(webArchiveData->dataReference(), WebContextUserMessageEncoder(userData, process())), m_pageID);
842 m_process->responsivenessTimer()->start();
845 void WebPageProxy::stopLoading()
850 m_process->send(Messages::WebPage::StopLoading(), m_pageID);
851 m_process->responsivenessTimer()->start();
854 uint64_t WebPageProxy::reload(bool reloadFromOrigin)
856 SandboxExtension::Handle sandboxExtensionHandle;
858 if (m_backForwardList->currentItem()) {
859 String url = m_backForwardList->currentItem()->url();
860 auto transaction = m_pageLoadState.transaction();
861 m_pageLoadState.setPendingAPIRequestURL(transaction, url);
863 // We may not have an extension yet if back/forward list was reinstated after a WebProcess crash or a browser relaunch
864 bool createdExtension = maybeInitializeSandboxExtensionHandle(URL(URL(), url), sandboxExtensionHandle);
865 if (createdExtension)
866 m_process->willAcquireUniversalFileReadSandboxExtension();
870 return reattachToWebProcessWithItem(m_backForwardList->currentItem());
872 uint64_t navigationID = generateNavigationID();
874 m_process->send(Messages::WebPage::Reload(navigationID, reloadFromOrigin, sandboxExtensionHandle), m_pageID);
875 m_process->responsivenessTimer()->start();
880 void WebPageProxy::recordNavigationSnapshot()
882 if (!m_shouldRecordNavigationSnapshots)
886 ViewSnapshotStore::shared().recordSnapshot(*this);
890 uint64_t WebPageProxy::goForward()
892 WebBackForwardListItem* forwardItem = m_backForwardList->forwardItem();
896 auto transaction = m_pageLoadState.transaction();
898 m_pageLoadState.setPendingAPIRequestURL(transaction, forwardItem->url());
901 return reattachToWebProcessWithItem(forwardItem);
903 uint64_t navigationID = generateNavigationID();
905 m_process->send(Messages::WebPage::GoForward(navigationID, forwardItem->itemID()), m_pageID);
906 m_process->responsivenessTimer()->start();
911 uint64_t WebPageProxy::goBack()
913 WebBackForwardListItem* backItem = m_backForwardList->backItem();
917 auto transaction = m_pageLoadState.transaction();
919 m_pageLoadState.setPendingAPIRequestURL(transaction, backItem->url());
922 return reattachToWebProcessWithItem(backItem);
924 uint64_t navigationID = generateNavigationID();
926 m_process->send(Messages::WebPage::GoBack(navigationID, backItem->itemID()), m_pageID);
927 m_process->responsivenessTimer()->start();
932 uint64_t WebPageProxy::goToBackForwardItem(WebBackForwardListItem* item)
935 return reattachToWebProcessWithItem(item);
937 auto transaction = m_pageLoadState.transaction();
939 m_pageLoadState.setPendingAPIRequestURL(transaction, item->url());
941 uint64_t navigationID = generateNavigationID();
943 m_process->send(Messages::WebPage::GoToBackForwardItem(navigationID, item->itemID()), m_pageID);
944 m_process->responsivenessTimer()->start();
949 void WebPageProxy::tryRestoreScrollPosition()
954 m_process->send(Messages::WebPage::TryRestoreScrollPosition(), m_pageID);
957 void WebPageProxy::didChangeBackForwardList(WebBackForwardListItem* added, Vector<RefPtr<WebBackForwardListItem>> removed)
959 m_loaderClient->didChangeBackForwardList(this, added, WTF::move(removed));
961 auto transaction = m_pageLoadState.transaction();
963 m_pageLoadState.setCanGoBack(transaction, m_backForwardList->backItem());
964 m_pageLoadState.setCanGoForward(transaction, m_backForwardList->forwardItem());
967 m_pageClient.clearCustomSwipeViews();
971 void WebPageProxy::willGoToBackForwardListItem(uint64_t itemID, IPC::MessageDecoder& decoder)
973 RefPtr<API::Object> userData;
974 WebContextUserMessageDecoder messageDecoder(userData, process());
975 if (!decoder.decode(messageDecoder))
978 if (WebBackForwardListItem* item = m_process->webBackForwardItem(itemID))
979 m_loaderClient->willGoToBackForwardListItem(this, item, userData.get());
982 bool WebPageProxy::shouldKeepCurrentBackForwardListItemInList(WebBackForwardListItem* item)
984 return m_loaderClient->shouldKeepCurrentBackForwardListItemInList(this, item);
987 bool WebPageProxy::canShowMIMEType(const String& mimeType)
989 if (MIMETypeRegistry::canShowMIMEType(mimeType))
992 #if ENABLE(NETSCAPE_PLUGIN_API)
993 String newMimeType = mimeType;
994 PluginModuleInfo plugin = m_process->context().pluginInfoStore().findPlugin(newMimeType, URL());
995 if (!plugin.path.isNull() && m_preferences->pluginsEnabled())
997 #endif // ENABLE(NETSCAPE_PLUGIN_API)
1000 // On Mac, we can show PDFs.
1001 if (MIMETypeRegistry::isPDFOrPostScriptMIMEType(mimeType) && !WebContext::omitPDFSupport())
1003 #endif // PLATFORM(COCOA)
1008 #if ENABLE(REMOTE_INSPECTOR)
1009 void WebPageProxy::setAllowsRemoteInspection(bool allow)
1011 if (m_allowsRemoteInspection == allow)
1014 m_allowsRemoteInspection = allow;
1017 m_process->send(Messages::WebPage::SetAllowsRemoteInspection(allow), m_pageID);
1021 void WebPageProxy::setDrawsBackground(bool drawsBackground)
1023 if (m_drawsBackground == drawsBackground)
1026 m_drawsBackground = drawsBackground;
1029 m_process->send(Messages::WebPage::SetDrawsBackground(drawsBackground), m_pageID);
1032 void WebPageProxy::setDrawsTransparentBackground(bool drawsTransparentBackground)
1034 if (m_drawsTransparentBackground == drawsTransparentBackground)
1037 m_drawsTransparentBackground = drawsTransparentBackground;
1040 m_process->send(Messages::WebPage::SetDrawsTransparentBackground(drawsTransparentBackground), m_pageID);
1043 void WebPageProxy::setTopContentInset(float contentInset)
1045 if (m_topContentInset == contentInset)
1048 m_topContentInset = contentInset;
1051 m_process->send(Messages::WebPage::SetTopContentInset(contentInset), m_pageID);
1054 void WebPageProxy::setUnderlayColor(const Color& color)
1056 if (m_underlayColor == color)
1059 m_underlayColor = color;
1062 m_process->send(Messages::WebPage::SetUnderlayColor(color), m_pageID);
1065 void WebPageProxy::viewWillStartLiveResize()
1069 #if ENABLE(INPUT_TYPE_COLOR_POPOVER)
1073 m_process->send(Messages::WebPage::ViewWillStartLiveResize(), m_pageID);
1076 void WebPageProxy::viewWillEndLiveResize()
1080 m_process->send(Messages::WebPage::ViewWillEndLiveResize(), m_pageID);
1083 void WebPageProxy::setViewNeedsDisplay(const IntRect& rect)
1085 m_pageClient.setViewNeedsDisplay(rect);
1088 void WebPageProxy::displayView()
1090 m_pageClient.displayView();
1093 bool WebPageProxy::canScrollView()
1095 return m_pageClient.canScrollView();
1098 void WebPageProxy::scrollView(const IntRect& scrollRect, const IntSize& scrollOffset)
1100 m_pageClient.scrollView(scrollRect, scrollOffset);
1103 void WebPageProxy::requestScroll(const FloatPoint& scrollPosition, bool isProgrammaticScroll)
1105 m_pageClient.requestScroll(scrollPosition, isProgrammaticScroll);
1108 void WebPageProxy::updateViewState(ViewState::Flags flagsToUpdate)
1110 m_viewState &= ~flagsToUpdate;
1111 if (flagsToUpdate & ViewState::IsFocused && m_pageClient.isViewFocused())
1112 m_viewState |= ViewState::IsFocused;
1113 if (flagsToUpdate & ViewState::WindowIsActive && m_pageClient.isViewWindowActive())
1114 m_viewState |= ViewState::WindowIsActive;
1115 if (flagsToUpdate & ViewState::IsVisible && m_pageClient.isViewVisible())
1116 m_viewState |= ViewState::IsVisible;
1117 if (flagsToUpdate & ViewState::IsVisibleOrOccluded && m_pageClient.isViewVisibleOrOccluded())
1118 m_viewState |= ViewState::IsVisibleOrOccluded;
1119 if (flagsToUpdate & ViewState::IsInWindow && m_pageClient.isViewInWindow()) {
1120 m_viewState |= ViewState::IsInWindow;
1121 m_viewWasEverInWindow = true;
1123 if (flagsToUpdate & ViewState::IsVisuallyIdle && m_pageClient.isVisuallyIdle())
1124 m_viewState |= ViewState::IsVisuallyIdle;
1127 void WebPageProxy::viewStateDidChange(ViewState::Flags mayHaveChanged, bool wantsReply, ViewStateChangeDispatchMode dispatchMode)
1129 m_potentiallyChangedViewStateFlags |= mayHaveChanged;
1130 m_viewStateChangeWantsReply = m_viewStateChangeWantsReply || wantsReply;
1133 bool isNewlyInWindow = !isInWindow() && (mayHaveChanged & ViewState::IsInWindow) && m_pageClient.isViewInWindow();
1134 if (dispatchMode == ViewStateChangeDispatchMode::Immediate || isNewlyInWindow) {
1135 dispatchViewStateChange();
1138 m_viewStateChangeDispatcher->schedule();
1140 UNUSED_PARAM(dispatchMode);
1141 dispatchViewStateChange();
1145 void WebPageProxy::viewDidLeaveWindow()
1147 #if ENABLE(INPUT_TYPE_COLOR_POPOVER)
1148 // When leaving the current page, close the popover color well.
1153 // When leaving the current page, close the video fullscreen.
1154 if (m_videoFullscreenManager)
1155 m_videoFullscreenManager->requestHideAndExitFullscreen();
1159 void WebPageProxy::viewDidEnterWindow()
1161 LayerHostingMode layerHostingMode = m_pageClient.viewLayerHostingMode();
1162 if (m_layerHostingMode != layerHostingMode) {
1163 m_layerHostingMode = layerHostingMode;
1164 m_process->send(Messages::WebPage::SetLayerHostingMode(static_cast<unsigned>(layerHostingMode)), m_pageID);
1168 void WebPageProxy::dispatchViewStateChange()
1171 m_viewStateChangeDispatcher->invalidate();
1177 // If the visibility state may have changed, then so may the visually idle & occluded agnostic state.
1178 if (m_potentiallyChangedViewStateFlags & ViewState::IsVisible)
1179 m_potentiallyChangedViewStateFlags |= ViewState::IsVisibleOrOccluded | ViewState::IsVisuallyIdle;
1181 // Record the prior view state, update the flags that may have changed,
1182 // and check which flags have actually changed.
1183 ViewState::Flags previousViewState = m_viewState;
1184 updateViewState(m_potentiallyChangedViewStateFlags);
1185 ViewState::Flags changed = m_viewState ^ previousViewState;
1187 // We always want to wait for the Web process to reply if we've been in-window before and are coming back in-window.
1188 if (m_viewWasEverInWindow && (changed & ViewState::IsInWindow) && isInWindow())
1189 m_viewStateChangeWantsReply = true;
1192 m_process->send(Messages::WebPage::SetViewState(m_viewState, m_viewStateChangeWantsReply), m_pageID);
1194 // This must happen after the SetViewState message is sent, to ensure the page visibility event can fire.
1195 updateActivityToken();
1197 if (changed & ViewState::IsVisuallyIdle)
1198 m_process->pageSuppressibilityChanged(this);
1200 // If we've started the responsiveness timer as part of telling the web process to update the backing store
1201 // state, it might not send back a reply (since it won't paint anything if the web page is hidden) so we
1202 // stop the unresponsiveness timer here.
1203 if ((changed & ViewState::IsVisible) && !isViewVisible())
1204 m_process->responsivenessTimer()->stop();
1206 if (changed & ViewState::IsInWindow) {
1208 viewDidEnterWindow();
1210 viewDidLeaveWindow();
1213 updateBackingStoreDiscardableState();
1215 if (m_viewStateChangeWantsReply)
1216 waitForDidUpdateViewState();
1218 m_potentiallyChangedViewStateFlags = ViewState::NoFlags;
1219 m_viewStateChangeWantsReply = false;
1222 void WebPageProxy::updateActivityToken()
1225 if (!isViewVisible())
1226 m_activityToken = nullptr;
1227 else if (!m_activityToken)
1228 m_activityToken = std::make_unique<ProcessThrottler::ForegroundActivityToken>(m_process->throttler());
1232 void WebPageProxy::layerHostingModeDidChange()
1237 LayerHostingMode layerHostingMode = m_pageClient.viewLayerHostingMode();
1238 if (m_layerHostingMode == layerHostingMode)
1241 m_layerHostingMode = layerHostingMode;
1242 m_process->send(Messages::WebPage::SetLayerHostingMode(static_cast<unsigned>(layerHostingMode)), m_pageID);
1245 void WebPageProxy::waitForDidUpdateViewState()
1250 if (m_process->state() != WebProcessProxy::State::Running)
1253 // If we have previously timed out with no response from the WebProcess, don't block the UIProcess again until it starts responding.
1254 if (m_waitingForDidUpdateViewState)
1257 m_waitingForDidUpdateViewState = true;
1259 m_drawingArea->waitForDidUpdateViewState();
1262 IntSize WebPageProxy::viewSize() const
1264 return m_pageClient.viewSize();
1267 void WebPageProxy::setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent& keyboardEvent)
1271 m_process->send(Messages::WebPage::SetInitialFocus(forward, isKeyboardEventValid, keyboardEvent), m_pageID);
1274 void WebPageProxy::setWindowResizerSize(const IntSize& windowResizerSize)
1278 m_process->send(Messages::WebPage::SetWindowResizerSize(windowResizerSize), m_pageID);
1281 void WebPageProxy::clearSelection()
1285 m_process->send(Messages::WebPage::ClearSelection(), m_pageID);
1288 void WebPageProxy::validateCommand(const String& commandName, std::function<void (const String&, bool, int32_t, CallbackBase::Error)> callbackFunction)
1291 callbackFunction(String(), false, 0, CallbackBase::Error::Unknown);
1295 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), std::make_unique<ProcessThrottler::BackgroundActivityToken>(m_process->throttler()));
1296 m_process->send(Messages::WebPage::ValidateCommand(commandName, callbackID), m_pageID);
1299 void WebPageProxy::setMaintainsInactiveSelection(bool newValue)
1301 m_maintainsInactiveSelection = newValue;
1304 void WebPageProxy::executeEditCommand(const String& commandName)
1306 static NeverDestroyed<String> ignoreSpellingCommandName(ASCIILiteral("ignoreSpelling"));
1311 if (commandName == ignoreSpellingCommandName)
1312 ++m_pendingLearnOrIgnoreWordMessageCount;
1314 m_process->send(Messages::WebPage::ExecuteEditCommand(commandName), m_pageID);
1317 #if USE(TILED_BACKING_STORE)
1318 void WebPageProxy::commitPageTransitionViewport()
1323 process().send(Messages::WebPage::CommitPageTransitionViewport(), m_pageID);
1327 #if ENABLE(DRAG_SUPPORT)
1328 void WebPageProxy::dragEntered(DragData& dragData, const String& dragStorageName)
1330 SandboxExtension::Handle sandboxExtensionHandle;
1331 SandboxExtension::HandleArray sandboxExtensionHandleEmptyArray;
1332 performDragControllerAction(DragControllerActionEntered, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionHandleEmptyArray);
1335 void WebPageProxy::dragUpdated(DragData& dragData, const String& dragStorageName)
1337 SandboxExtension::Handle sandboxExtensionHandle;
1338 SandboxExtension::HandleArray sandboxExtensionHandleEmptyArray;
1339 performDragControllerAction(DragControllerActionUpdated, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionHandleEmptyArray);
1342 void WebPageProxy::dragExited(DragData& dragData, const String& dragStorageName)
1344 SandboxExtension::Handle sandboxExtensionHandle;
1345 SandboxExtension::HandleArray sandboxExtensionHandleEmptyArray;
1346 performDragControllerAction(DragControllerActionExited, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionHandleEmptyArray);
1349 void WebPageProxy::performDragOperation(DragData& dragData, const String& dragStorageName, const SandboxExtension::Handle& sandboxExtensionHandle, const SandboxExtension::HandleArray& sandboxExtensionsForUpload)
1351 performDragControllerAction(DragControllerActionPerformDragOperation, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionsForUpload);
1354 void WebPageProxy::performDragControllerAction(DragControllerAction action, DragData& dragData, const String& dragStorageName, const SandboxExtension::Handle& sandboxExtensionHandle, const SandboxExtension::HandleArray& sandboxExtensionsForUpload)
1359 UNUSED_PARAM(dragStorageName);
1360 UNUSED_PARAM(sandboxExtensionHandle);
1361 UNUSED_PARAM(sandboxExtensionsForUpload);
1362 m_process->send(Messages::WebPage::PerformDragControllerAction(action, dragData), m_pageID);
1364 m_process->send(Messages::WebPage::PerformDragControllerAction(action, dragData.clientPosition(), dragData.globalPosition(), dragData.draggingSourceOperationMask(), dragStorageName, dragData.flags(), sandboxExtensionHandle, sandboxExtensionsForUpload), m_pageID);
1368 void WebPageProxy::didPerformDragControllerAction(uint64_t dragOperation, bool mouseIsOverFileInput, unsigned numberOfItemsToBeAccepted)
1370 MESSAGE_CHECK(dragOperation <= DragOperationDelete);
1372 m_currentDragOperation = static_cast<DragOperation>(dragOperation);
1373 m_currentDragIsOverFileInput = mouseIsOverFileInput;
1374 m_currentDragNumberOfFilesToBeAccepted = numberOfItemsToBeAccepted;
1378 void WebPageProxy::startDrag(const DragData& dragData, const ShareableBitmap::Handle& dragImageHandle)
1380 RefPtr<ShareableBitmap> dragImage = 0;
1381 if (!dragImageHandle.isNull()) {
1382 dragImage = ShareableBitmap::create(dragImageHandle);
1387 m_pageClient.startDrag(dragData, dragImage.release());
1391 void WebPageProxy::dragEnded(const IntPoint& clientPosition, const IntPoint& globalPosition, uint64_t operation)
1395 m_process->send(Messages::WebPage::DragEnded(clientPosition, globalPosition, operation), m_pageID);
1397 #endif // ENABLE(DRAG_SUPPORT)
1399 void WebPageProxy::handleMouseEvent(const NativeWebMouseEvent& event)
1404 // NOTE: This does not start the responsiveness timer because mouse move should not indicate interaction.
1405 if (event.type() != WebEvent::MouseMove)
1406 m_process->responsivenessTimer()->start();
1408 if (m_processingMouseMoveEvent) {
1409 m_nextMouseMoveEvent = std::make_unique<NativeWebMouseEvent>(event);
1413 m_processingMouseMoveEvent = true;
1416 // <https://bugs.webkit.org/show_bug.cgi?id=57904> We need to keep track of the mouse down event in the case where we
1417 // display a popup menu for select elements. When the user changes the selected item,
1418 // we fake a mouse up event by using this stored down event. This event gets cleared
1419 // when the mouse up message is received from WebProcess.
1420 if (event.type() == WebEvent::MouseDown)
1421 m_currentlyProcessedMouseDownEvent = std::make_unique<NativeWebMouseEvent>(event);
1423 if (m_shouldSendEventsSynchronously) {
1424 bool handled = false;
1425 m_process->sendSync(Messages::WebPage::MouseEventSyncForTesting(event), Messages::WebPage::MouseEventSyncForTesting::Reply(handled), m_pageID);
1426 didReceiveEvent(event.type(), handled);
1428 m_process->send(Messages::WebPage::MouseEvent(event), m_pageID);
1431 #if MERGE_WHEEL_EVENTS
1432 static bool canCoalesce(const WebWheelEvent& a, const WebWheelEvent& b)
1434 if (a.position() != b.position())
1436 if (a.globalPosition() != b.globalPosition())
1438 if (a.modifiers() != b.modifiers())
1440 if (a.granularity() != b.granularity())
1443 if (a.phase() != b.phase())
1445 if (a.momentumPhase() != b.momentumPhase())
1447 if (a.hasPreciseScrollingDeltas() != b.hasPreciseScrollingDeltas())
1454 static WebWheelEvent coalesce(const WebWheelEvent& a, const WebWheelEvent& b)
1456 ASSERT(canCoalesce(a, b));
1458 FloatSize mergedDelta = a.delta() + b.delta();
1459 FloatSize mergedWheelTicks = a.wheelTicks() + b.wheelTicks();
1462 FloatSize mergedUnacceleratedScrollingDelta = a.unacceleratedScrollingDelta() + b.unacceleratedScrollingDelta();
1464 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());
1466 return WebWheelEvent(WebEvent::Wheel, b.position(), b.globalPosition(), mergedDelta, mergedWheelTicks, b.granularity(), b.modifiers(), b.timestamp());
1469 #endif // MERGE_WHEEL_EVENTS
1471 static WebWheelEvent coalescedWheelEvent(Deque<NativeWebWheelEvent>& queue, Vector<NativeWebWheelEvent>& coalescedEvents)
1473 ASSERT(!queue.isEmpty());
1474 ASSERT(coalescedEvents.isEmpty());
1476 #if MERGE_WHEEL_EVENTS
1477 NativeWebWheelEvent firstEvent = queue.takeFirst();
1478 coalescedEvents.append(firstEvent);
1480 WebWheelEvent event = firstEvent;
1481 while (!queue.isEmpty() && canCoalesce(event, queue.first())) {
1482 NativeWebWheelEvent firstEvent = queue.takeFirst();
1483 coalescedEvents.append(firstEvent);
1484 event = coalesce(event, firstEvent);
1489 while (!queue.isEmpty())
1490 coalescedEvents.append(queue.takeFirst());
1491 return coalescedEvents.last();
1495 void WebPageProxy::handleWheelEvent(const NativeWebWheelEvent& event)
1497 #if ENABLE(ASYNC_SCROLLING)
1498 if (m_scrollingCoordinatorProxy && m_scrollingCoordinatorProxy->handleWheelEvent(platform(event)))
1505 if (!m_currentlyProcessedWheelEvents.isEmpty()) {
1506 m_wheelEventQueue.append(event);
1507 if (m_wheelEventQueue.size() < wheelEventQueueSizeThreshold)
1509 // The queue has too many wheel events, so push a new event.
1512 if (!m_wheelEventQueue.isEmpty()) {
1513 processNextQueuedWheelEvent();
1517 auto coalescedWheelEvent = std::make_unique<Vector<NativeWebWheelEvent>>();
1518 coalescedWheelEvent->append(event);
1519 m_currentlyProcessedWheelEvents.append(WTF::move(coalescedWheelEvent));
1520 sendWheelEvent(event);
1523 void WebPageProxy::processNextQueuedWheelEvent()
1525 auto nextCoalescedEvent = std::make_unique<Vector<NativeWebWheelEvent>>();
1526 WebWheelEvent nextWheelEvent = coalescedWheelEvent(m_wheelEventQueue, *nextCoalescedEvent.get());
1527 m_currentlyProcessedWheelEvents.append(WTF::move(nextCoalescedEvent));
1528 sendWheelEvent(nextWheelEvent);
1531 void WebPageProxy::sendWheelEvent(const WebWheelEvent& event)
1533 m_process->responsivenessTimer()->start();
1535 if (m_shouldSendEventsSynchronously) {
1536 bool handled = false;
1537 m_process->sendSync(Messages::WebPage::WheelEventSyncForTesting(event), Messages::WebPage::WheelEventSyncForTesting::Reply(handled), m_pageID);
1538 didReceiveEvent(event.type(), handled);
1543 Messages::EventDispatcher::WheelEvent(
1546 shouldUseImplicitRubberBandControl() ? !m_backForwardList->backItem() : rubberBandsAtLeft(),
1547 shouldUseImplicitRubberBandControl() ? !m_backForwardList->forwardItem() : rubberBandsAtRight(),
1549 rubberBandsAtBottom()
1553 void WebPageProxy::handleKeyboardEvent(const NativeWebKeyboardEvent& event)
1558 LOG(KeyHandling, "WebPageProxy::handleKeyboardEvent: %s", webKeyboardEventTypeString(event.type()));
1560 m_keyEventQueue.append(event);
1562 m_process->responsivenessTimer()->start();
1563 if (m_shouldSendEventsSynchronously) {
1564 bool handled = false;
1565 m_process->sendSync(Messages::WebPage::KeyEventSyncForTesting(event), Messages::WebPage::KeyEventSyncForTesting::Reply(handled), m_pageID);
1566 didReceiveEvent(event.type(), handled);
1567 } else if (m_keyEventQueue.size() == 1) // Otherwise, sent from DidReceiveEvent message handler.
1568 m_process->send(Messages::WebPage::KeyEvent(event), m_pageID);
1571 uint64_t WebPageProxy::generateNavigationID()
1573 return ++m_navigationID;
1576 WebPreferencesStore WebPageProxy::preferencesStore() const
1578 if (m_configurationPreferenceValues.isEmpty())
1579 return m_preferences->store();
1581 WebPreferencesStore store = m_preferences->store();
1582 for (const auto& preference : m_configurationPreferenceValues)
1583 store.m_values.set(preference.key, preference.value);
1588 #if ENABLE(NETSCAPE_PLUGIN_API)
1589 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)
1591 MESSAGE_CHECK_URL(urlString);
1593 newMimeType = mimeType.lower();
1594 pluginLoadPolicy = PluginModuleLoadNormally;
1596 PluginData::AllowedPluginTypes allowedPluginTypes = allowOnlyApplicationPlugins ? PluginData::OnlyApplicationPlugins : PluginData::AllPlugins;
1597 PluginModuleInfo plugin = m_process->context().pluginInfoStore().findPlugin(newMimeType, URL(URL(), urlString), allowedPluginTypes);
1599 pluginProcessToken = 0;
1603 pluginLoadPolicy = PluginInfoStore::defaultLoadPolicyForPlugin(plugin);
1606 RefPtr<ImmutableDictionary> pluginInformation = createPluginInformationDictionary(plugin, frameURLString, String(), pageURLString, String(), String());
1607 pluginLoadPolicy = m_loaderClient->pluginLoadPolicy(this, static_cast<PluginModuleLoadPolicy>(pluginLoadPolicy), pluginInformation.get(), unavailabilityDescription);
1609 UNUSED_PARAM(frameURLString);
1610 UNUSED_PARAM(pageURLString);
1611 UNUSED_PARAM(unavailabilityDescription);
1614 PluginProcessSandboxPolicy pluginProcessSandboxPolicy = PluginProcessSandboxPolicyNormal;
1615 switch (pluginLoadPolicy) {
1616 case PluginModuleLoadNormally:
1617 pluginProcessSandboxPolicy = PluginProcessSandboxPolicyNormal;
1619 case PluginModuleLoadUnsandboxed:
1620 pluginProcessSandboxPolicy = PluginProcessSandboxPolicyUnsandboxed;
1623 case PluginModuleBlocked:
1624 pluginProcessToken = 0;
1628 pluginProcessToken = PluginProcessManager::shared().pluginProcessToken(plugin, static_cast<PluginProcessType>(processType), pluginProcessSandboxPolicy);
1631 #endif // ENABLE(NETSCAPE_PLUGIN_API)
1633 #if ENABLE(TOUCH_EVENTS)
1635 bool WebPageProxy::shouldStartTrackingTouchEvents(const WebTouchEvent& touchStartEvent) const
1637 #if ENABLE(ASYNC_SCROLLING)
1638 for (auto& touchPoint : touchStartEvent.touchPoints()) {
1639 if (m_scrollingCoordinatorProxy->isPointInNonFastScrollableRegion(touchPoint.location()))
1645 UNUSED_PARAM(touchStartEvent);
1646 #endif // ENABLE(ASYNC_SCROLLING)
1652 #if ENABLE(IOS_TOUCH_EVENTS)
1653 void WebPageProxy::handleTouchEventSynchronously(const NativeWebTouchEvent& event)
1658 if (event.type() == WebEvent::TouchStart)
1659 m_isTrackingTouchEvents = shouldStartTrackingTouchEvents(event);
1661 if (!m_isTrackingTouchEvents)
1664 m_process->responsivenessTimer()->start();
1665 bool handled = false;
1666 m_process->sendSync(Messages::WebPage::TouchEventSync(event), Messages::WebPage::TouchEventSync::Reply(handled), m_pageID);
1667 didReceiveEvent(event.type(), handled);
1668 m_pageClient.doneWithTouchEvent(event, handled);
1669 m_process->responsivenessTimer()->stop();
1671 if (event.allTouchPointsAreReleased())
1672 m_isTrackingTouchEvents = false;
1675 void WebPageProxy::handleTouchEventAsynchronously(const NativeWebTouchEvent& event)
1680 if (!m_isTrackingTouchEvents)
1683 m_process->send(Messages::EventDispatcher::TouchEvent(m_pageID, event), 0);
1685 if (event.allTouchPointsAreReleased())
1686 m_isTrackingTouchEvents = false;
1689 #elif ENABLE(TOUCH_EVENTS)
1690 void WebPageProxy::handleTouchEvent(const NativeWebTouchEvent& event)
1695 if (event.type() == WebEvent::TouchStart)
1696 m_isTrackingTouchEvents = shouldStartTrackingTouchEvents(event);
1698 if (!m_isTrackingTouchEvents)
1701 // If the page is suspended, which should be the case during panning, pinching
1702 // and animation on the page itself (kinetic scrolling, tap to zoom) etc, then
1703 // we do not send any of the events to the page even if is has listeners.
1704 if (!m_isPageSuspended) {
1705 m_touchEventQueue.append(event);
1706 m_process->responsivenessTimer()->start();
1707 if (m_shouldSendEventsSynchronously) {
1708 bool handled = false;
1709 m_process->sendSync(Messages::WebPage::TouchEventSyncForTesting(event), Messages::WebPage::TouchEventSyncForTesting::Reply(handled), m_pageID);
1710 didReceiveEvent(event.type(), handled);
1712 m_process->send(Messages::WebPage::TouchEvent(event), m_pageID);
1714 if (m_touchEventQueue.isEmpty()) {
1715 bool isEventHandled = false;
1716 m_pageClient.doneWithTouchEvent(event, isEventHandled);
1718 // We attach the incoming events to the newest queued event so that all
1719 // the events are delivered in the correct order when the event is dequed.
1720 QueuedTouchEvents& lastEvent = m_touchEventQueue.last();
1721 lastEvent.deferredTouchEvents.append(event);
1725 if (event.allTouchPointsAreReleased())
1726 m_isTrackingTouchEvents = false;
1728 #endif // ENABLE(TOUCH_EVENTS)
1730 void WebPageProxy::scrollBy(ScrollDirection direction, ScrollGranularity granularity)
1735 m_process->send(Messages::WebPage::ScrollBy(direction, granularity), m_pageID);
1738 void WebPageProxy::centerSelectionInVisibleArea()
1743 m_process->send(Messages::WebPage::CenterSelectionInVisibleArea(), m_pageID);
1746 void WebPageProxy::receivedPolicyDecision(PolicyAction action, WebFrameProxy* frame, uint64_t listenerID, uint64_t navigationID)
1751 auto transaction = m_pageLoadState.transaction();
1753 if (action == PolicyIgnore)
1754 m_pageLoadState.clearPendingAPIRequestURL(transaction);
1756 uint64_t downloadID = 0;
1757 if (action == PolicyDownload) {
1758 // Create a download proxy.
1759 DownloadProxy* download = m_process->context().createDownloadProxy();
1760 downloadID = download->downloadID();
1761 handleDownloadRequest(download);
1764 // If we received a policy decision while in decidePolicyForResponse the decision will
1765 // be sent back to the web process by decidePolicyForResponse.
1766 if (m_inDecidePolicyForResponseSync) {
1767 m_syncMimeTypePolicyActionIsValid = true;
1768 m_syncMimeTypePolicyAction = action;
1769 m_syncMimeTypePolicyDownloadID = downloadID;
1773 // If we received a policy decision while in decidePolicyForNavigationAction the decision will
1774 // be sent back to the web process by decidePolicyForNavigationAction.
1775 if (m_inDecidePolicyForNavigationAction) {
1776 m_syncNavigationActionPolicyActionIsValid = true;
1777 m_syncNavigationActionPolicyAction = action;
1778 m_syncNavigationActionPolicyDownloadID = downloadID;
1782 m_process->send(Messages::WebPage::DidReceivePolicyDecision(frame->frameID(), listenerID, action, navigationID, downloadID), m_pageID);
1785 void WebPageProxy::setUserAgent(const String& userAgent)
1787 if (m_userAgent == userAgent)
1789 m_userAgent = userAgent;
1793 m_process->send(Messages::WebPage::SetUserAgent(m_userAgent), m_pageID);
1796 void WebPageProxy::setApplicationNameForUserAgent(const String& applicationName)
1798 if (m_applicationNameForUserAgent == applicationName)
1801 m_applicationNameForUserAgent = applicationName;
1802 if (!m_customUserAgent.isEmpty())
1805 setUserAgent(standardUserAgent(m_applicationNameForUserAgent));
1808 void WebPageProxy::setCustomUserAgent(const String& customUserAgent)
1810 if (m_customUserAgent == customUserAgent)
1813 m_customUserAgent = customUserAgent;
1815 if (m_customUserAgent.isEmpty()) {
1816 setUserAgent(standardUserAgent(m_applicationNameForUserAgent));
1820 setUserAgent(m_customUserAgent);
1823 void WebPageProxy::resumeActiveDOMObjectsAndAnimations()
1825 if (!isValid() || !m_isPageSuspended)
1828 m_isPageSuspended = false;
1830 m_process->send(Messages::WebPage::ResumeActiveDOMObjectsAndAnimations(), m_pageID);
1833 void WebPageProxy::suspendActiveDOMObjectsAndAnimations()
1835 if (!isValid() || m_isPageSuspended)
1838 m_isPageSuspended = true;
1840 m_process->send(Messages::WebPage::SuspendActiveDOMObjectsAndAnimations(), m_pageID);
1843 bool WebPageProxy::supportsTextEncoding() const
1845 // FIXME (118840): We should probably only support this for text documents, not all non-image documents.
1846 return m_mainFrame && !m_mainFrame->isDisplayingStandaloneImageDocument();
1849 void WebPageProxy::setCustomTextEncodingName(const String& encodingName)
1851 if (m_customTextEncodingName == encodingName)
1853 m_customTextEncodingName = encodingName;
1857 m_process->send(Messages::WebPage::SetCustomTextEncodingName(encodingName), m_pageID);
1860 void WebPageProxy::terminateProcess()
1862 // NOTE: This uses a check of m_isValid rather than calling isValid() since
1863 // we want this to run even for pages being closed or that already closed.
1867 m_process->requestTermination();
1868 resetStateAfterProcessExited();
1871 SessionState WebPageProxy::sessionState(const std::function<bool (WebBackForwardListItem&)>& filter) const
1873 SessionState sessionState;
1875 sessionState.backForwardListState = m_backForwardList->backForwardListState(filter);
1877 String provisionalURLString = m_pageLoadState.pendingAPIRequestURL();
1878 if (provisionalURLString.isEmpty())
1879 provisionalURLString = m_pageLoadState.provisionalURL();
1881 if (!provisionalURLString.isEmpty())
1882 sessionState.provisionalURL = URL(URL(), provisionalURLString);
1884 return sessionState;
1887 uint64_t WebPageProxy::restoreFromSessionState(SessionState sessionState, bool navigate)
1889 bool hasBackForwardList = !!sessionState.backForwardListState.currentIndex;
1891 if (hasBackForwardList) {
1892 m_backForwardList->restoreFromState(WTF::move(sessionState.backForwardListState));
1894 for (const auto& entry : m_backForwardList->entries())
1895 process().registerNewWebBackForwardListItem(entry.get());
1897 process().send(Messages::WebPage::RestoreSession(m_backForwardList->itemStates()), m_pageID);
1901 // FIXME: Navigating should be separate from state restoration.
1903 if (!sessionState.provisionalURL.isNull())
1904 return loadRequest(sessionState.provisionalURL);
1906 if (hasBackForwardList) {
1907 // FIXME: Do we have to null check the back forward list item here?
1908 if (WebBackForwardListItem* item = m_backForwardList->currentItem())
1909 return goToBackForwardItem(item);
1916 bool WebPageProxy::supportsTextZoom() const
1918 // FIXME (118840): This should also return false for standalone media and plug-in documents.
1919 if (!m_mainFrame || m_mainFrame->isDisplayingStandaloneImageDocument())
1925 void WebPageProxy::setTextZoomFactor(double zoomFactor)
1930 if (m_textZoomFactor == zoomFactor)
1933 m_textZoomFactor = zoomFactor;
1934 m_process->send(Messages::WebPage::SetTextZoomFactor(m_textZoomFactor), m_pageID);
1937 void WebPageProxy::setPageZoomFactor(double zoomFactor)
1942 if (m_pageZoomFactor == zoomFactor)
1945 m_pageZoomFactor = zoomFactor;
1946 m_process->send(Messages::WebPage::SetPageZoomFactor(m_pageZoomFactor), m_pageID);
1949 void WebPageProxy::setPageAndTextZoomFactors(double pageZoomFactor, double textZoomFactor)
1954 if (m_pageZoomFactor == pageZoomFactor && m_textZoomFactor == textZoomFactor)
1957 m_pageZoomFactor = pageZoomFactor;
1958 m_textZoomFactor = textZoomFactor;
1959 m_process->send(Messages::WebPage::SetPageAndTextZoomFactors(m_pageZoomFactor, m_textZoomFactor), m_pageID);
1962 void WebPageProxy::scalePage(double scale, const IntPoint& origin)
1967 m_pageScaleFactor = scale;
1968 m_process->send(Messages::WebPage::ScalePage(scale, origin), m_pageID);
1971 void WebPageProxy::scalePageInViewCoordinates(double scale, const IntPoint& centerInViewCoordinates)
1976 m_pageScaleFactor = scale;
1977 m_process->send(Messages::WebPage::ScalePageInViewCoordinates(scale, centerInViewCoordinates), m_pageID);
1980 void WebPageProxy::setIntrinsicDeviceScaleFactor(float scaleFactor)
1982 if (m_intrinsicDeviceScaleFactor == scaleFactor)
1985 m_intrinsicDeviceScaleFactor = scaleFactor;
1988 m_drawingArea->deviceScaleFactorDidChange();
1991 void WebPageProxy::windowScreenDidChange(PlatformDisplayID displayID)
1996 m_process->send(Messages::WebPage::WindowScreenDidChange(displayID), m_pageID);
1999 float WebPageProxy::deviceScaleFactor() const
2001 if (m_customDeviceScaleFactor)
2002 return m_customDeviceScaleFactor;
2003 return m_intrinsicDeviceScaleFactor;
2006 void WebPageProxy::setCustomDeviceScaleFactor(float customScaleFactor)
2011 // FIXME: Remove this once we bump cairo requirements to support HiDPI.
2012 // https://bugs.webkit.org/show_bug.cgi?id=133378
2013 #if USE(CAIRO) && !HAVE(CAIRO_SURFACE_SET_DEVICE_SCALE)
2017 if (m_customDeviceScaleFactor == customScaleFactor)
2020 float oldScaleFactor = deviceScaleFactor();
2022 m_customDeviceScaleFactor = customScaleFactor;
2024 if (deviceScaleFactor() != oldScaleFactor)
2025 m_drawingArea->deviceScaleFactorDidChange();
2028 void WebPageProxy::setUseFixedLayout(bool fixed)
2033 // This check is fine as the value is initialized in the web
2034 // process as part of the creation parameters.
2035 if (fixed == m_useFixedLayout)
2038 m_useFixedLayout = fixed;
2040 m_fixedLayoutSize = IntSize();
2041 m_process->send(Messages::WebPage::SetUseFixedLayout(fixed), m_pageID);
2044 void WebPageProxy::setFixedLayoutSize(const IntSize& size)
2049 if (size == m_fixedLayoutSize)
2052 m_fixedLayoutSize = size;
2053 m_process->send(Messages::WebPage::SetFixedLayoutSize(size), m_pageID);
2056 void WebPageProxy::listenForLayoutMilestones(WebCore::LayoutMilestones milestones)
2061 m_process->send(Messages::WebPage::ListenForLayoutMilestones(milestones), m_pageID);
2064 void WebPageProxy::setSuppressScrollbarAnimations(bool suppressAnimations)
2069 if (suppressAnimations == m_suppressScrollbarAnimations)
2072 m_suppressScrollbarAnimations = suppressAnimations;
2073 m_process->send(Messages::WebPage::SetSuppressScrollbarAnimations(suppressAnimations), m_pageID);
2076 bool WebPageProxy::rubberBandsAtLeft() const
2078 return m_rubberBandsAtLeft;
2081 void WebPageProxy::setRubberBandsAtLeft(bool rubberBandsAtLeft)
2083 m_rubberBandsAtLeft = rubberBandsAtLeft;
2086 bool WebPageProxy::rubberBandsAtRight() const
2088 return m_rubberBandsAtRight;
2091 void WebPageProxy::setRubberBandsAtRight(bool rubberBandsAtRight)
2093 m_rubberBandsAtRight = rubberBandsAtRight;
2096 bool WebPageProxy::rubberBandsAtTop() const
2098 return m_rubberBandsAtTop;
2101 void WebPageProxy::setRubberBandsAtTop(bool rubberBandsAtTop)
2103 m_rubberBandsAtTop = rubberBandsAtTop;
2106 bool WebPageProxy::rubberBandsAtBottom() const
2108 return m_rubberBandsAtBottom;
2111 void WebPageProxy::setRubberBandsAtBottom(bool rubberBandsAtBottom)
2113 m_rubberBandsAtBottom = rubberBandsAtBottom;
2116 void WebPageProxy::setEnableVerticalRubberBanding(bool enableVerticalRubberBanding)
2118 if (enableVerticalRubberBanding == m_enableVerticalRubberBanding)
2121 m_enableVerticalRubberBanding = enableVerticalRubberBanding;
2125 m_process->send(Messages::WebPage::SetEnableVerticalRubberBanding(enableVerticalRubberBanding), m_pageID);
2128 bool WebPageProxy::verticalRubberBandingIsEnabled() const
2130 return m_enableVerticalRubberBanding;
2133 void WebPageProxy::setEnableHorizontalRubberBanding(bool enableHorizontalRubberBanding)
2135 if (enableHorizontalRubberBanding == m_enableHorizontalRubberBanding)
2138 m_enableHorizontalRubberBanding = enableHorizontalRubberBanding;
2142 m_process->send(Messages::WebPage::SetEnableHorizontalRubberBanding(enableHorizontalRubberBanding), m_pageID);
2145 bool WebPageProxy::horizontalRubberBandingIsEnabled() const
2147 return m_enableHorizontalRubberBanding;
2150 void WebPageProxy::setBackgroundExtendsBeyondPage(bool backgroundExtendsBeyondPage)
2152 if (backgroundExtendsBeyondPage == m_backgroundExtendsBeyondPage)
2155 m_backgroundExtendsBeyondPage = backgroundExtendsBeyondPage;
2159 m_process->send(Messages::WebPage::SetBackgroundExtendsBeyondPage(backgroundExtendsBeyondPage), m_pageID);
2162 bool WebPageProxy::backgroundExtendsBeyondPage() const
2164 return m_backgroundExtendsBeyondPage;
2167 void WebPageProxy::setPaginationMode(WebCore::Pagination::Mode mode)
2169 if (mode == m_paginationMode)
2172 m_paginationMode = mode;
2176 m_process->send(Messages::WebPage::SetPaginationMode(mode), m_pageID);
2179 void WebPageProxy::setPaginationBehavesLikeColumns(bool behavesLikeColumns)
2181 if (behavesLikeColumns == m_paginationBehavesLikeColumns)
2184 m_paginationBehavesLikeColumns = behavesLikeColumns;
2188 m_process->send(Messages::WebPage::SetPaginationBehavesLikeColumns(behavesLikeColumns), m_pageID);
2191 void WebPageProxy::setPageLength(double pageLength)
2193 if (pageLength == m_pageLength)
2196 m_pageLength = pageLength;
2200 m_process->send(Messages::WebPage::SetPageLength(pageLength), m_pageID);
2203 void WebPageProxy::setGapBetweenPages(double gap)
2205 if (gap == m_gapBetweenPages)
2208 m_gapBetweenPages = gap;
2212 m_process->send(Messages::WebPage::SetGapBetweenPages(gap), m_pageID);
2215 void WebPageProxy::pageScaleFactorDidChange(double scaleFactor)
2217 m_pageScaleFactor = scaleFactor;
2220 void WebPageProxy::pageZoomFactorDidChange(double zoomFactor)
2222 m_pageZoomFactor = zoomFactor;
2225 void WebPageProxy::findStringMatches(const String& string, FindOptions options, unsigned maxMatchCount)
2227 if (string.isEmpty()) {
2228 didFindStringMatches(string, Vector<Vector<WebCore::IntRect>> (), 0);
2232 m_process->send(Messages::WebPage::FindStringMatches(string, options, maxMatchCount), m_pageID);
2235 void WebPageProxy::findString(const String& string, FindOptions options, unsigned maxMatchCount)
2237 m_process->send(Messages::WebPage::FindString(string, options, maxMatchCount), m_pageID);
2240 void WebPageProxy::getImageForFindMatch(int32_t matchIndex)
2242 m_process->send(Messages::WebPage::GetImageForFindMatch(matchIndex), m_pageID);
2245 void WebPageProxy::selectFindMatch(int32_t matchIndex)
2247 m_process->send(Messages::WebPage::SelectFindMatch(matchIndex), m_pageID);
2250 void WebPageProxy::hideFindUI()
2252 m_process->send(Messages::WebPage::HideFindUI(), m_pageID);
2255 void WebPageProxy::countStringMatches(const String& string, FindOptions options, unsigned maxMatchCount)
2260 m_process->send(Messages::WebPage::CountStringMatches(string, options, maxMatchCount), m_pageID);
2263 void WebPageProxy::runJavaScriptInMainFrame(const String& script, std::function<void (WebSerializedScriptValue*, CallbackBase::Error)> callbackFunction)
2266 callbackFunction(nullptr, CallbackBase::Error::Unknown);
2270 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), std::make_unique<ProcessThrottler::BackgroundActivityToken>(m_process->throttler()));
2271 m_process->send(Messages::WebPage::RunJavaScriptInMainFrame(script, callbackID), m_pageID);
2274 void WebPageProxy::getRenderTreeExternalRepresentation(std::function<void (const String&, CallbackBase::Error)> callbackFunction)
2277 callbackFunction(String(), CallbackBase::Error::Unknown);
2281 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), std::make_unique<ProcessThrottler::BackgroundActivityToken>(m_process->throttler()));
2282 m_process->send(Messages::WebPage::GetRenderTreeExternalRepresentation(callbackID), m_pageID);
2285 void WebPageProxy::getSourceForFrame(WebFrameProxy* frame, std::function<void (const String&, CallbackBase::Error)> callbackFunction)
2288 callbackFunction(String(), CallbackBase::Error::Unknown);
2292 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), std::make_unique<ProcessThrottler::BackgroundActivityToken>(m_process->throttler()));
2293 m_loadDependentStringCallbackIDs.add(callbackID);
2294 m_process->send(Messages::WebPage::GetSourceForFrame(frame->frameID(), callbackID), m_pageID);
2297 void WebPageProxy::getContentsAsString(std::function<void (const String&, CallbackBase::Error)> callbackFunction)
2300 callbackFunction(String(), CallbackBase::Error::Unknown);
2304 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), std::make_unique<ProcessThrottler::BackgroundActivityToken>(m_process->throttler()));
2305 m_loadDependentStringCallbackIDs.add(callbackID);
2306 m_process->send(Messages::WebPage::GetContentsAsString(callbackID), m_pageID);
2309 void WebPageProxy::getBytecodeProfile(std::function<void (const String&, CallbackBase::Error)> callbackFunction)
2312 callbackFunction(String(), CallbackBase::Error::Unknown);
2316 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), std::make_unique<ProcessThrottler::BackgroundActivityToken>(m_process->throttler()));
2317 m_loadDependentStringCallbackIDs.add(callbackID);
2318 m_process->send(Messages::WebPage::GetBytecodeProfile(callbackID), m_pageID);
2322 void WebPageProxy::getContentsAsMHTMLData(std::function<void (API::Data*, CallbackBase::Error)> callbackFunction, bool useBinaryEncoding)
2325 callbackFunction(nullptr, CallbackBase::Error::Unknown);
2329 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), std::make_unique<ProcessThrottler::BackgroundActivityToken>(m_process->throttler()));
2330 m_process->send(Messages::WebPage::GetContentsAsMHTMLData(callbackID, useBinaryEncoding), m_pageID);
2334 void WebPageProxy::getSelectionOrContentsAsString(std::function<void (const String&, CallbackBase::Error)> callbackFunction)
2337 callbackFunction(String(), CallbackBase::Error::Unknown);
2341 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), std::make_unique<ProcessThrottler::BackgroundActivityToken>(m_process->throttler()));
2342 m_process->send(Messages::WebPage::GetSelectionOrContentsAsString(callbackID), m_pageID);
2345 void WebPageProxy::getSelectionAsWebArchiveData(std::function<void (API::Data*, CallbackBase::Error)> callbackFunction)
2348 callbackFunction(nullptr, CallbackBase::Error::Unknown);
2352 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), std::make_unique<ProcessThrottler::BackgroundActivityToken>(m_process->throttler()));
2353 m_process->send(Messages::WebPage::GetSelectionAsWebArchiveData(callbackID), m_pageID);
2356 void WebPageProxy::getMainResourceDataOfFrame(WebFrameProxy* frame, std::function<void (API::Data*, CallbackBase::Error)> callbackFunction)
2358 if (!isValid() || !frame) {
2359 callbackFunction(nullptr, CallbackBase::Error::Unknown);
2363 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), std::make_unique<ProcessThrottler::BackgroundActivityToken>(m_process->throttler()));
2364 m_process->send(Messages::WebPage::GetMainResourceDataOfFrame(frame->frameID(), callbackID), m_pageID);
2367 void WebPageProxy::getResourceDataFromFrame(WebFrameProxy* frame, API::URL* resourceURL, std::function<void (API::Data*, CallbackBase::Error)> callbackFunction)
2370 callbackFunction(nullptr, CallbackBase::Error::Unknown);
2374 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), std::make_unique<ProcessThrottler::BackgroundActivityToken>(m_process->throttler()));
2375 m_process->send(Messages::WebPage::GetResourceDataFromFrame(frame->frameID(), resourceURL->string(), callbackID), m_pageID);
2378 void WebPageProxy::getWebArchiveOfFrame(WebFrameProxy* frame, std::function<void (API::Data*, CallbackBase::Error)> callbackFunction)
2381 callbackFunction(nullptr, CallbackBase::Error::Unknown);
2385 uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), std::make_unique<ProcessThrottler::BackgroundActivityToken>(m_process->throttler()));
2386 m_process->send(Messages::WebPage::GetWebArchiveOfFrame(frame->frameID(), callbackID), m_pageID);
2389 void WebPageProxy::forceRepaint(PassRefPtr<VoidCallback> prpCallback)
2391 RefPtr<VoidCallback> callback = prpCallback;
2393 // FIXME: If the page is invalid we should not call the callback. It'd be better to just return false from forceRepaint.
2394 callback->invalidate(CallbackBase::Error::OwnerWasInvalidated);
2398 uint64_t callbackID = callback->callbackID();
2399 m_callbacks.put(callback);
2400 m_drawingArea->waitForBackingStoreUpdateOnNextPaint();
2401 m_process->send(Messages::WebPage::ForceRepaint(callbackID), m_pageID);
2404 void WebPageProxy::preferencesDidChange()
2409 #if ENABLE(INSPECTOR_SERVER)
2410 if (m_preferences->developerExtrasEnabled())
2411 inspector()->enableRemoteInspection();
2414 m_process->pagePreferencesChanged(this);
2416 m_pageClient.preferencesDidChange();
2418 // FIXME: It probably makes more sense to send individual preference changes.
2419 // However, WebKitTestRunner depends on getting a preference change notification
2420 // even if nothing changed in UI process, so that overrides get removed.
2422 // Preferences need to be updated during synchronous printing to make "print backgrounds" preference work when toggled from a print dialog checkbox.
2423 m_process->send(Messages::WebPage::PreferencesDidChange(preferencesStore()), m_pageID, m_isPerformingDOMPrintOperation ? IPC::DispatchMessageEvenWhenWaitingForSyncReply : 0);
2426 void WebPageProxy::didCreateMainFrame(uint64_t frameID)
2428 MESSAGE_CHECK(!m_mainFrame);
2429 MESSAGE_CHECK(m_process->canCreateFrame(frameID));
2431 m_mainFrame = WebFrameProxy::create(this, frameID);
2433 // Add the frame to the process wide map.
2434 m_process->frameCreated(frameID, m_mainFrame.get());
2437 void WebPageProxy::didCreateSubframe(uint64_t frameID)
2439 MESSAGE_CHECK(m_mainFrame);
2440 MESSAGE_CHECK(m_process->canCreateFrame(frameID));
2442 RefPtr<WebFrameProxy> subFrame = WebFrameProxy::create(this, frameID);
2444 // Add the frame to the process wide map.
2445 m_process->frameCreated(frameID, subFrame.get());
2448 double WebPageProxy::estimatedProgress() const
2450 return m_pageLoadState.estimatedProgress();
2453 void WebPageProxy::didStartProgress()
2455 auto transaction = m_pageLoadState.transaction();
2456 m_pageLoadState.didStartProgress(transaction);
2458 m_pageLoadState.commitChanges();
2459 m_loaderClient->didStartProgress(this);
2462 void WebPageProxy::didChangeProgress(double value)
2464 auto transaction = m_pageLoadState.transaction();
2465 m_pageLoadState.didChangeProgress(transaction, value);
2467 m_pageLoadState.commitChanges();
2468 m_loaderClient->didChangeProgress(this);
2471 void WebPageProxy::didFinishProgress()
2473 auto transaction = m_pageLoadState.transaction();
2474 m_pageLoadState.didFinishProgress(transaction);
2476 m_pageLoadState.commitChanges();
2477 m_loaderClient->didFinishProgress(this);
2480 void WebPageProxy::setNetworkRequestsInProgress(bool networkRequestsInProgress)
2482 auto transaction = m_pageLoadState.transaction();
2483 m_pageLoadState.setNetworkRequestsInProgress(transaction, networkRequestsInProgress);
2486 void WebPageProxy::didDestroyNavigation(uint64_t navigationID)
2488 m_loaderClient->didDestroyNavigation(this, navigationID);
2491 void WebPageProxy::didStartProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& url, const String& unreachableURL, IPC::MessageDecoder& decoder)
2493 auto transaction = m_pageLoadState.transaction();
2495 m_pageLoadState.clearPendingAPIRequestURL(transaction);
2497 RefPtr<API::Object> userData;
2498 WebContextUserMessageDecoder messageDecoder(userData, process());
2499 if (!decoder.decode(messageDecoder))
2502 WebFrameProxy* frame = m_process->webFrame(frameID);
2503 MESSAGE_CHECK(frame);
2504 MESSAGE_CHECK_URL(url);
2506 if (frame->isMainFrame())
2507 m_pageLoadState.didStartProvisionalLoad(transaction, url, unreachableURL);
2509 frame->setUnreachableURL(unreachableURL);
2510 frame->didStartProvisionalLoad(url);
2512 m_pageLoadState.commitChanges();
2513 m_loaderClient->didStartProvisionalLoadForFrame(this, frame, navigationID, userData.get());
2516 void WebPageProxy::didReceiveServerRedirectForProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& url, IPC::MessageDecoder& decoder)
2518 RefPtr<API::Object> userData;
2519 WebContextUserMessageDecoder messageDecoder(userData, process());
2520 if (!decoder.decode(messageDecoder))
2523 WebFrameProxy* frame = m_process->webFrame(frameID);
2524 MESSAGE_CHECK(frame);
2525 MESSAGE_CHECK_URL(url);
2527 auto transaction = m_pageLoadState.transaction();
2529 if (frame->isMainFrame())
2530 m_pageLoadState.didReceiveServerRedirectForProvisionalLoad(transaction, url);
2532 frame->didReceiveServerRedirectForProvisionalLoad(url);
2534 m_pageLoadState.commitChanges();
2535 m_loaderClient->didReceiveServerRedirectForProvisionalLoadForFrame(this, frame, navigationID, userData.get());
2538 void WebPageProxy::didFailProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, const ResourceError& error, IPC::MessageDecoder& decoder)
2540 RefPtr<API::Object> userData;
2541 WebContextUserMessageDecoder messageDecoder(userData, process());
2542 if (!decoder.decode(messageDecoder))
2545 WebFrameProxy* frame = m_process->webFrame(frameID);
2546 MESSAGE_CHECK(frame);
2548 auto transaction = m_pageLoadState.transaction();
2550 if (frame->isMainFrame())
2551 m_pageLoadState.didFailProvisionalLoad(transaction);
2553 frame->didFailProvisionalLoad();
2555 m_pageLoadState.commitChanges();
2556 m_loaderClient->didFailProvisionalLoadWithErrorForFrame(this, frame, navigationID, error, userData.get());
2559 void WebPageProxy::clearLoadDependentCallbacks()
2561 Vector<uint64_t> callbackIDsCopy;
2562 copyToVector(m_loadDependentStringCallbackIDs, callbackIDsCopy);
2563 m_loadDependentStringCallbackIDs.clear();
2565 for (size_t i = 0; i < callbackIDsCopy.size(); ++i) {
2566 auto callback = m_callbacks.take<StringCallback>(callbackIDsCopy[i]);
2568 callback->invalidate();
2572 void WebPageProxy::didCommitLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& mimeType, bool frameHasCustomContentProvider, uint32_t opaqueFrameLoadType, const WebCore::CertificateInfo& certificateInfo, IPC::MessageDecoder& decoder)
2574 RefPtr<API::Object> userData;
2575 WebContextUserMessageDecoder messageDecoder(userData, process());
2576 if (!decoder.decode(messageDecoder))
2579 WebFrameProxy* frame = m_process->webFrame(frameID);
2580 MESSAGE_CHECK(frame);
2582 auto transaction = m_pageLoadState.transaction();
2584 if (frame->isMainFrame())
2585 m_pageLoadState.didCommitLoad(transaction);
2588 // FIXME (bug 59111): didCommitLoadForFrame comes too late when restoring a page from b/f cache, making us disable secure event mode in password fields.
2589 // FIXME: A load going on in one frame shouldn't affect text editing in other frames on the page.
2590 m_pageClient.resetSecureInputState();
2591 dismissCorrectionPanel(ReasonForDismissingAlternativeTextIgnored);
2592 m_pageClient.dismissDictionaryLookupPanel();
2595 clearLoadDependentCallbacks();
2597 frame->didCommitLoad(mimeType, certificateInfo);
2599 if (frame->isMainFrame()) {
2600 m_mainFrameHasCustomContentProvider = frameHasCustomContentProvider;
2602 if (m_mainFrameHasCustomContentProvider) {
2603 // Always assume that the main frame is pinned here, since the custom representation view will handle
2604 // any wheel events and dispatch them to the WKView when necessary.
2605 m_mainFrameIsPinnedToLeftSide = true;
2606 m_mainFrameIsPinnedToRightSide = true;
2607 m_mainFrameIsPinnedToTopSide = true;
2608 m_mainFrameIsPinnedToBottomSide = true;
2610 m_uiClient->pinnedStateDidChange(*this);
2612 m_pageClient.didCommitLoadForMainFrame(mimeType, frameHasCustomContentProvider);
2615 // Even if WebPage has the default pageScaleFactor (and therefore doesn't reset it),
2616 // WebPageProxy's cache of the value can get out of sync (e.g. in the case where a
2617 // plugin is handling page scaling itself) so we should reset it to the default
2618 // for standard main frame loads.
2619 if (frame->isMainFrame() && static_cast<FrameLoadType>(opaqueFrameLoadType) == FrameLoadType::Standard)
2620 m_pageScaleFactor = 1;
2622 m_pageLoadState.commitChanges();
2623 m_loaderClient->didCommitLoadForFrame(this, frame, navigationID, userData.get());
2626 void WebPageProxy::didFinishDocumentLoadForFrame(uint64_t frameID, uint64_t navigationID, IPC::MessageDecoder& decoder)
2628 RefPtr<API::Object> userData;
2629 WebContextUserMessageDecoder messageDecoder(userData, process());
2630 if (!decoder.decode(messageDecoder))
2633 WebFrameProxy* frame = m_process->webFrame(frameID);
2634 MESSAGE_CHECK(frame);
2636 m_loaderClient->didFinishDocumentLoadForFrame(this, frame, navigationID, userData.get());
2639 void WebPageProxy::didFinishLoadForFrame(uint64_t frameID, uint64_t navigationID, IPC::MessageDecoder& decoder)
2641 RefPtr<API::Object> userData;
2642 WebContextUserMessageDecoder messageDecoder(userData, process());
2643 if (!decoder.decode(messageDecoder))
2646 WebFrameProxy* frame = m_process->webFrame(frameID);
2647 MESSAGE_CHECK(frame);
2649 auto transaction = m_pageLoadState.transaction();
2651 if (frame->isMainFrame())
2652 m_pageLoadState.didFinishLoad(transaction);
2654 frame->didFinishLoad();
2656 m_pageLoadState.commitChanges();
2657 m_loaderClient->didFinishLoadForFrame(this, frame, navigationID, userData.get());
2660 void WebPageProxy::didFailLoadForFrame(uint64_t frameID, uint64_t navigationID, const ResourceError& error, IPC::MessageDecoder& decoder)
2662 RefPtr<API::Object> userData;
2663 WebContextUserMessageDecoder messageDecoder(userData, process());
2664 if (!decoder.decode(messageDecoder))
2667 WebFrameProxy* frame = m_process->webFrame(frameID);
2668 MESSAGE_CHECK(frame);
2670 clearLoadDependentCallbacks();
2672 auto transaction = m_pageLoadState.transaction();
2674 if (frame->isMainFrame())
2675 m_pageLoadState.didFailLoad(transaction);
2677 frame->didFailLoad();
2679 m_pageLoadState.commitChanges();
2680 m_loaderClient->didFailLoadWithErrorForFrame(this, frame, navigationID, error, userData.get());
2683 void WebPageProxy::didSameDocumentNavigationForFrame(uint64_t frameID, uint64_t navigationID, uint32_t opaqueSameDocumentNavigationType, const String& url, IPC::MessageDecoder& decoder)
2685 RefPtr<API::Object> userData;
2686 WebContextUserMessageDecoder messageDecoder(userData, process());
2687 if (!decoder.decode(messageDecoder))
2690 WebFrameProxy* frame = m_process->webFrame(frameID);
2691 MESSAGE_CHECK(frame);
2692 MESSAGE_CHECK_URL(url);
2694 auto transaction = m_pageLoadState.transaction();
2696 if (frame->isMainFrame())
2697 m_pageLoadState.didSameDocumentNavigation(transaction, url);
2699 m_pageLoadState.clearPendingAPIRequestURL(transaction);
2700 frame->didSameDocumentNavigation(url);
2702 m_pageLoadState.commitChanges();
2703 m_loaderClient->didSameDocumentNavigationForFrame(this, frame, navigationID, static_cast<SameDocumentNavigationType>(opaqueSameDocumentNavigationType), userData.get());
2706 void WebPageProxy::didReceiveTitleForFrame(uint64_t frameID, const String& title, IPC::MessageDecoder& decoder)
2708 RefPtr<API::Object> userData;
2709 WebContextUserMessageDecoder messageDecoder(userData, process());
2710 if (!decoder.decode(messageDecoder))
2713 WebFrameProxy* frame = m_process->webFrame(frameID);
2714 MESSAGE_CHECK(frame);
2716 auto transaction = m_pageLoadState.transaction();
2718 if (frame->isMainFrame())
2719 m_pageLoadState.setTitle(transaction, title);
2721 frame->didChangeTitle(title);
2723 m_pageLoadState.commitChanges();
2724 m_loaderClient->didReceiveTitleForFrame(this, title, frame, userData.get());
2727 void WebPageProxy::didFirstLayoutForFrame(uint64_t frameID, IPC::MessageDecoder& decoder)
2729 RefPtr<API::Object> userData;
2730 WebContextUserMessageDecoder messageDecoder(userData, process());
2731 if (!decoder.decode(messageDecoder))
2734 WebFrameProxy* frame = m_process->webFrame(frameID);
2735 MESSAGE_CHECK(frame);
2737 m_loaderClient->didFirstLayoutForFrame(this, frame, userData.get());
2740 void WebPageProxy::didFirstVisuallyNonEmptyLayoutForFrame(uint64_t frameID, IPC::MessageDecoder& decoder)
2742 RefPtr<API::Object> userData;
2743 WebContextUserMessageDecoder messageDecoder(userData, process());
2744 if (!decoder.decode(messageDecoder))
2747 WebFrameProxy* frame = m_process->webFrame(frameID);
2748 MESSAGE_CHECK(frame);
2750 m_loaderClient->didFirstVisuallyNonEmptyLayoutForFrame(this, frame, userData.get());
2753 void WebPageProxy::didLayout(uint32_t layoutMilestones, IPC::MessageDecoder& decoder)
2755 RefPtr<API::Object> userData;
2756 WebContextUserMessageDecoder messageDecoder(userData, process());
2757 if (!decoder.decode(messageDecoder))
2760 m_loaderClient->didLayout(this, static_cast<LayoutMilestones>(layoutMilestones), userData.get());
2763 void WebPageProxy::didRemoveFrameFromHierarchy(uint64_t frameID, IPC::MessageDecoder& decoder)
2765 RefPtr<API::Object> userData;
2766 WebContextUserMessageDecoder messageDecoder(userData, process());
2767 if (!decoder.decode(messageDecoder))
2770 WebFrameProxy* frame = m_process->webFrame(frameID);
2771 MESSAGE_CHECK(frame);
2773 m_loaderClient->didRemoveFrameFromHierarchy(this, frame, userData.get());
2776 void WebPageProxy::didDisplayInsecureContentForFrame(uint64_t frameID, IPC::MessageDecoder& decoder)
2778 RefPtr<API::Object> userData;
2779 WebContextUserMessageDecoder messageDecoder(userData, process());
2780 if (!decoder.decode(messageDecoder))
2783 WebFrameProxy* frame = m_process->webFrame(frameID);
2784 MESSAGE_CHECK(frame);
2786 auto transaction = m_pageLoadState.transaction();
2787 m_pageLoadState.didDisplayOrRunInsecureContent(transaction);
2789 m_pageLoadState.commitChanges();
2790 m_loaderClient->didDisplayInsecureContentForFrame(this, frame, userData.get());
2793 void WebPageProxy::didRunInsecureContentForFrame(uint64_t frameID, IPC::MessageDecoder& decoder)
2795 RefPtr<API::Object> userData;
2796 WebContextUserMessageDecoder messageDecoder(userData, process());
2797 if (!decoder.decode(messageDecoder))
2800 WebFrameProxy* frame = m_process->webFrame(frameID);
2801 MESSAGE_CHECK(frame);
2803 auto transaction = m_pageLoadState.transaction();
2804 m_pageLoadState.didDisplayOrRunInsecureContent(transaction);
2806 m_pageLoadState.commitChanges();
2807 m_loaderClient->didRunInsecureContentForFrame(this, frame, userData.get());
2810 void WebPageProxy::didDetectXSSForFrame(uint64_t frameID, IPC::MessageDecoder& decoder)
2812 RefPtr<API::Object> userData;
2813 WebContextUserMessageDecoder messageDecoder(userData, process());
2814 if (!decoder.decode(messageDecoder))
2817 WebFrameProxy* frame = m_process->webFrame(frameID);
2818 MESSAGE_CHECK(frame);
2820 m_loaderClient->didDetectXSSForFrame(this, frame, userData.get());
2823 void WebPageProxy::frameDidBecomeFrameSet(uint64_t frameID, bool value)
2825 WebFrameProxy* frame = m_process->webFrame(frameID);
2826 MESSAGE_CHECK(frame);
2828 frame->setIsFrameSet(value);
2829 if (frame->isMainFrame())
2830 m_frameSetLargestFrame = value ? m_mainFrame : 0;
2833 void WebPageProxy::decidePolicyForNavigationAction(uint64_t frameID, uint64_t navigationID, const NavigationActionData& navigationActionData, uint64_t originatingFrameID, const WebCore::ResourceRequest& originalRequest, const ResourceRequest& request, uint64_t listenerID, IPC::MessageDecoder& decoder, bool& receivedPolicyAction, uint64_t& newNavigationID, uint64_t& policyAction, uint64_t& downloadID)
2835 RefPtr<API::Object> userData;
2836 WebContextUserMessageDecoder messageDecoder(userData, process());
2837 if (!decoder.decode(messageDecoder))
2840 auto transaction = m_pageLoadState.transaction();
2842 if (request.url() != m_pageLoadState.pendingAPIRequestURL())
2843 m_pageLoadState.clearPendingAPIRequestURL(transaction);
2845 WebFrameProxy* frame = m_process->webFrame(frameID);
2846 MESSAGE_CHECK(frame);
2847 MESSAGE_CHECK_URL(request.url());
2848 MESSAGE_CHECK_URL(originalRequest.url());
2850 WebFrameProxy* originatingFrame = m_process->webFrame(originatingFrameID);
2852 RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
2853 if (!navigationID && frame->isMainFrame()) {
2854 newNavigationID = generateNavigationID();
2855 listener->setNavigationID(newNavigationID);
2858 #if USE(CONTENT_FILTERING)
2859 if (frame->contentFilterDidHandleNavigationAction(request)) {
2860 receivedPolicyAction = true;
2861 policyAction = PolicyIgnore;
2866 ASSERT(!m_inDecidePolicyForNavigationAction);
2868 m_inDecidePolicyForNavigationAction = true;
2869 m_syncNavigationActionPolicyActionIsValid = false;
2871 m_policyClient->decidePolicyForNavigationAction(this, frame, navigationActionData, originatingFrame, originalRequest, request, WTF::move(listener), userData.get());
2873 m_inDecidePolicyForNavigationAction = false;
2875 // Check if we received a policy decision already. If we did, we can just pass it back.
2876 receivedPolicyAction = m_syncNavigationActionPolicyActionIsValid;
2877 if (m_syncNavigationActionPolicyActionIsValid) {
2878 policyAction = m_syncNavigationActionPolicyAction;
2879 downloadID = m_syncNavigationActionPolicyDownloadID;
2883 void WebPageProxy::decidePolicyForNewWindowAction(uint64_t frameID, const NavigationActionData& navigationActionData, const ResourceRequest& request, const String& frameName, uint64_t listenerID, IPC::MessageDecoder& decoder)
2885 RefPtr<API::Object> userData;
2886 WebContextUserMessageDecoder messageDecoder(userData, process());
2887 if (!decoder.decode(messageDecoder))
2890 WebFrameProxy* frame = m_process->webFrame(frameID);
2891 MESSAGE_CHECK(frame);
2892 MESSAGE_CHECK_URL(request.url());
2894 RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
2896 m_policyClient->decidePolicyForNewWindowAction(this, frame, navigationActionData, request, frameName, WTF::move(listener), userData.get());
2899 void WebPageProxy::decidePolicyForResponse(uint64_t frameID, const ResourceResponse& response, const ResourceRequest& request, bool canShowMIMEType, uint64_t listenerID, IPC::MessageDecoder& decoder)
2901 RefPtr<API::Object> userData;
2902 WebContextUserMessageDecoder messageDecoder(userData, process());
2903 if (!decoder.decode(messageDecoder))
2906 WebFrameProxy* frame = m_process->webFrame(frameID);
2907 MESSAGE_CHECK(frame);
2908 MESSAGE_CHECK_URL(request.url());
2909 MESSAGE_CHECK_URL(response.url());
2911 RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
2913 m_policyClient->decidePolicyForResponse(this, frame, response, request, canShowMIMEType, WTF::move(listener), userData.get());
2916 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)
2918 ASSERT(!m_inDecidePolicyForResponseSync);
2920 m_inDecidePolicyForResponseSync = true;
2921 m_decidePolicyForResponseRequest = &request;
2922 m_syncMimeTypePolicyActionIsValid = false;
2924 decidePolicyForResponse(frameID, response, request, canShowMIMEType, listenerID, decoder);
2926 m_inDecidePolicyForResponseSync = false;
2927 m_decidePolicyForResponseRequest = 0;
2929 // Check if we received a policy decision already. If we did, we can just pass it back.
2930 receivedPolicyAction = m_syncMimeTypePolicyActionIsValid;
2931 if (m_syncMimeTypePolicyActionIsValid) {
2932 policyAction = m_syncMimeTypePolicyAction;
2933 downloadID = m_syncMimeTypePolicyDownloadID;
2937 void WebPageProxy::unableToImplementPolicy(uint64_t frameID, const ResourceError& error, IPC::MessageDecoder& decoder)
2939 RefPtr<API::Object> userData;
2940 WebContextUserMessageDecoder messageDecoder(userData, process());
2941 if (!decoder.decode(messageDecoder))
2944 WebFrameProxy* frame = m_process->webFrame(frameID);
2945 MESSAGE_CHECK(frame);
2947 m_policyClient->unableToImplementPolicy(this, frame, error, userData.get());
2952 void WebPageProxy::willSubmitForm(uint64_t frameID, uint64_t sourceFrameID, const Vector<std::pair<String, String>>& textFieldValues, uint64_t listenerID, IPC::MessageDecoder& decoder)
2954 RefPtr<API::Object> userData;
2955 WebContextUserMessageDecoder messageDecoder(userData, process());
2956 if (!decoder.decode(messageDecoder))
2959 WebFrameProxy* frame = m_process->webFrame(frameID);
2960 MESSAGE_CHECK(frame);
2962 WebFrameProxy* sourceFrame = m_process->webFrame(sourceFrameID);
2963 MESSAGE_CHECK(sourceFrame);
2965 RefPtr<WebFormSubmissionListenerProxy> listener = frame->setUpFormSubmissionListenerProxy(listenerID);
2966 if (!m_formClient->willSubmitForm(this, frame, sourceFrame, textFieldValues, userData.get(), listener.get()))
2967 listener->continueSubmission();
2972 void WebPageProxy::createNewPage(uint64_t frameID, const ResourceRequest& request, const WindowFeatures& windowFeatures, const NavigationActionData& navigationActionData, uint64_t& newPageID, WebPageCreationParameters& newPageParameters)
2974 WebFrameProxy* frame = m_process->webFrame(frameID);
2975 MESSAGE_CHECK(frame);
2977 RefPtr<WebPageProxy> newPage = m_uiClient->createNewPage(this, frame, request, windowFeatures, navigationActionData);
2983 newPageID = newPage->pageID();
2984 newPageParameters = newPage->creationParameters();
2985 process().context().storageManager().cloneSessionStorageNamespace(m_pageID, newPage->pageID());
2988 void WebPageProxy::showPage()
2990 m_uiClient->showPage(this);
2993 void WebPageProxy::closePage(bool stopResponsivenessTimer)
2995 if (stopResponsivenessTimer)
2996 m_process->responsivenessTimer()->stop();
2998 m_pageClient.clearAllEditCommands();
2999 m_uiClient->close(this);
3002 void WebPageProxy::runJavaScriptAlert(uint64_t frameID, const String& message, RefPtr<Messages::WebPageProxy::RunJavaScriptAlert::DelayedReply> reply)
3004 WebFrameProxy* frame = m_process->webFrame(frameID);
3005 MESSAGE_CHECK(frame);
3007 // Since runJavaScriptAlert() can spin a nested run loop we need to turn off the responsiveness timer.
3008 m_process->responsivenessTimer()->stop();
3010 m_uiClient->runJavaScriptAlert(this, message, frame, [reply]{ reply->send(); });
3013 void WebPageProxy::runJavaScriptConfirm(uint64_t frameID, const String& message, RefPtr<Messages::WebPageProxy::RunJavaScriptConfirm::DelayedReply> reply)
3015 WebFrameProxy* frame = m_process->webFrame(frameID);
3016 MESSAGE_CHECK(frame);
3018 // Since runJavaScriptConfirm() can spin a nested run loop we need to turn off the responsiveness timer.
3019 m_process->responsivenessTimer()->stop();
3021 m_uiClient->runJavaScriptConfirm(this, message, frame, [reply](bool result) { reply->send(result); });
3024 void WebPageProxy::runJavaScriptPrompt(uint64_t frameID, const String& message, const String& defaultValue, RefPtr<Messages::WebPageProxy::RunJavaScriptPrompt::DelayedReply> reply)
3026 WebFrameProxy* frame = m_process->webFrame(frameID);
3027 MESSAGE_CHECK(frame);
3029 // Since runJavaScriptPrompt() can spin a nested run loop we need to turn off the responsiveness timer.
3030 m_process->responsivenessTimer()->stop();
3032 m_uiClient->runJavaScriptPrompt(this, message, defaultValue, frame, [reply](const String& result) { reply->send(result); });
3035 void WebPageProxy::shouldInterruptJavaScript(bool& result)
3037 // Since shouldInterruptJavaScript() can spin a nested run loop we need to turn off the responsiveness timer.
3038 m_process->responsivenessTimer()->stop();
3040 result = m_uiClient->shouldInterruptJavaScript(this);
3043 void WebPageProxy::setStatusText(const String& text)
3045 m_uiClient->setStatusText(this, text);
3048 void WebPageProxy::mouseDidMoveOverElement(const WebHitTestResult::Data& hitTestResultData, uint32_t opaqueModifiers, IPC::MessageDecoder& decoder)
3050 RefPtr<API::Object> userData;
3051 WebContextUserMessageDecoder messageDecoder(userData, process());
3052 if (!decoder.decode(messageDecoder))
3055 WebEvent::Modifiers modifiers = static_cast<WebEvent::Modifiers>(opaqueModifiers);
3057 m_uiClient->mouseDidMoveOverElement(this, hitTestResultData, modifiers, userData.get());
3060 void WebPageProxy::connectionWillOpen(IPC::Connection* connection)
3062 ASSERT(connection == m_process->connection());
3064 m_process->context().storageManager().setAllowedSessionStorageNamespaceConnection(m_pageID, connection);
3067 void WebPageProxy::connectionWillClose(IPC::Connection* connection)
3069 ASSERT_UNUSED(connection, connection == m_process->connection());
3071 m_process->context().storageManager().setAllowedSessionStorageNamespaceConnection(m_pageID, 0);
3074 void WebPageProxy::processDidFinishLaunching()
3076 if (m_userContentController)
3077 m_userContentController->addProcess(m_process.get());
3078 m_visitedLinkProvider->addProcess(m_process.get());
3081 #if ENABLE(NETSCAPE_PLUGIN_API)
3082 void WebPageProxy::unavailablePluginButtonClicked(uint32_t opaquePluginUnavailabilityReason, const String& mimeType, const String& pluginURLString, const String& pluginspageAttributeURLString, const String& frameURLString, const String& pageURLString)
3084 MESSAGE_CHECK_URL(pluginURLString);
3085 MESSAGE_CHECK_URL(pluginspageAttributeURLString);
3086 MESSAGE_CHECK_URL(frameURLString);
3087 MESSAGE_CHECK_URL(pageURLString);
3089 RefPtr<ImmutableDictionary> pluginInformation;
3090 String newMimeType = mimeType;
3091 PluginModuleInfo plugin = m_process->context().pluginInfoStore().findPlugin(newMimeType, URL(URL(), pluginURLString));
3092 pluginInformation = createPluginInformationDictionary(plugin, frameURLString, mimeType, pageURLString, pluginspageAttributeURLString, pluginURLString);
3094 WKPluginUnavailabilityReason pluginUnavailabilityReason = kWKPluginUnavailabilityReasonPluginMissing;
3095 switch (static_cast<RenderEmbeddedObject::PluginUnavailabilityReason>(opaquePluginUnavailabilityReason)) {
3096 case RenderEmbeddedObject::PluginMissing:
3097 pluginUnavailabilityReason = kWKPluginUnavailabilityReasonPluginMissing;
3099 case RenderEmbeddedObject::InsecurePluginVersion:
3100 pluginUnavailabilityReason = kWKPluginUnavailabilityReasonInsecurePluginVersion;
3102 case RenderEmbeddedObject::PluginCrashed:
3103 pluginUnavailabilityReason = kWKPluginUnavailabilityReasonPluginCrashed;
3105 case RenderEmbeddedObject::PluginBlockedByContentSecurityPolicy:
3106 ASSERT_NOT_REACHED();
3109 m_uiClient->unavailablePluginButtonClicked(this, pluginUnavailabilityReason, pluginInformation.get());
3111 #endif // ENABLE(NETSCAPE_PLUGIN_API)
3114 void WebPageProxy::webGLPolicyForURL(const String& url, uint32_t& loadPolicy)
3116 loadPolicy = static_cast<uint32_t>(m_loaderClient->webGLLoadPolicy(this, url));
3119 void WebPageProxy::resolveWebGLPolicyForURL(const String& url, uint32_t& loadPolicy)
3121 loadPolicy = static_cast<uint32_t>(m_loaderClient->resolveWebGLLoadPolicy(this, url));
3123 #endif // ENABLE(WEBGL)
3125 void WebPageProxy::setToolbarsAreVisible(bool toolbarsAreVisible)
3127 m_uiClient->setToolbarsAreVisible(this, toolbarsAreVisible);
3130 void WebPageProxy::getToolbarsAreVisible(bool& toolbarsAreVisible)
3132 toolbarsAreVisible = m_uiClient->toolbarsAreVisible(this);
3135 void WebPageProxy::setMenuBarIsVisible(bool menuBarIsVisible)
3137 m_uiClient->setMenuBarIsVisible(this, menuBarIsVisible);
3140 void WebPageProxy::getMenuBarIsVisible(bool& menuBarIsVisible)
3142 menuBarIsVisible = m_uiClient->menuBarIsVisible(this);
3145 void WebPageProxy::setStatusBarIsVisible(bool statusBarIsVisible)
3147 m_uiClient->setStatusBarIsVisible(this, statusBarIsVisible);
3150 void WebPageProxy::getStatusBarIsVisible(bool& statusBarIsVisible)
3152 statusBarIsVisible = m_uiClient->statusBarIsVisible(this);
3155 void WebPageProxy::setIsResizable(bool isResizable)
3157 m_uiClient->setIsResizable(this, isResizable);
3160 void WebPageProxy::getIsResizable(bool& isResizable)
3162 isResizable = m_uiClient->isResizable(this);
3165 void WebPageProxy::setWindowFrame(const FloatRect& newWindowFrame)
3167 m_uiClient->setWindowFrame(this, m_pageClient.convertToDeviceSpace(newWindowFrame));
3170 void WebPageProxy::getWindowFrame(FloatRect& newWindowFrame)
3172 newWindowFrame = m_pageClient.convertToUserSpace(m_uiClient->windowFrame(this));
3175 void WebPageProxy::screenToRootView(const IntPoint& screenPoint, IntPoint& windowPoint)
3177 windowPoint = m_pageClient.screenToRootView(screenPoint);
3180 void WebPageProxy::rootViewToScreen(const IntRect& viewRect, IntRect& result)
3182 result = m_pageClient.rootViewToScreen(viewRect);
3186 void WebPageProxy::accessibilityScreenToRootView(const IntPoint& screenPoint, IntPoint& windowPoint)
3188 windowPoint = m_pageClient.accessibilityScreenToRootView(screenPoint);
3191 void WebPageProxy::rootViewToAccessibilityScreen(const IntRect& viewRect, IntRect& result)
3193 result = m_pageClient.rootViewToAccessibilityScreen(viewRect);
3197 void WebPageProxy::runBeforeUnloadConfirmPanel(const String& message, uint64_t frameID, bool& shouldClose)
3199 WebFrameProxy* frame = m_process->webFrame(frameID);
3200 MESSAGE_CHECK(frame);
3202 // Since runBeforeUnloadConfirmPanel() can spin a nested run loop we need to turn off the responsiveness timer.
3203 m_process->responsivenessTimer()->stop();
3205 shouldClose = m_uiClient->runBeforeUnloadConfirmPanel(this, message, frame);
3208 #if USE(TILED_BACKING_STORE)
3209 void WebPageProxy::pageDidRequestScroll(const IntPoint& point)
3211 m_pageClient.pageDidRequestScroll(point);
3214 void WebPageProxy::pageTransitionViewportReady()
3216 m_pageClient.pageTransitionViewportReady();
3219 void WebPageProxy::didRenderFrame(const WebCore::IntSize& contentsSize, const WebCore::IntRect& coveredRect)
3221 m_pageClient.didRenderFrame(contentsSize, coveredRect);
3226 void WebPageProxy::didChangeViewportProperties(const ViewportAttributes& attr)
3228 m_pageClient.didChangeViewportProperties(attr);
3231 void WebPageProxy::pageDidScroll()
3233 m_uiClient->pageDidScroll(this);
3235 dismissCorrectionPanel(ReasonForDismissingAlternativeTextIgnored);
3239 void WebPageProxy::runOpenPanel(uint64_t frameID, const FileChooserSettings& settings)
3241 if (m_openPanelResultListener) {
3242 m_openPanelResultListener->invalidate();
3243 m_openPanelResultListener = 0;
3246 WebFrameProxy* frame = m_process->webFrame(frameID);
3247 MESSAGE_CHECK(frame);
3249 RefPtr<WebOpenPanelParameters> parameters = WebOpenPanelParameters::create(settings);
3250 m_openPanelResultListener = WebOpenPanelResultListenerProxy::create(this);
3252 // Since runOpenPanel() can spin a nested run loop we need to turn off the responsiveness timer.
3253 m_process->responsivenessTimer()->stop();
3255 if (!m_uiClient->runOpenPanel(this, frame, parameters.get(), m_openPanelResultListener.get())) {
3256 if (!m_pageClient.handleRunOpenPanel(this, frame, parameters.get(), m_openPanelResultListener.get()))
3257 didCancelForOpenPanel();
3261 void WebPageProxy::printFrame(uint64_t frameID)
3263 ASSERT(!m_isPerformingDOMPrintOperation);
3264 m_isPerformingDOMPrintOperation = true;
3266 WebFrameProxy* frame = m_process->webFrame(frameID);
3267 MESSAGE_CHECK(frame);
3269 m_uiClient->printFrame(this, frame);
3271 endPrinting(); // Send a message synchronously while m_isPerformingDOMPrintOperation is still true.
3272 m_isPerformingDOMPrintOperation = false;
3275 void WebPageProxy::printMainFrame()
3277 printFrame(m_mainFrame->frameID());
3280 void WebPageProxy::setMediaVolume(float volume)
3282 if (volume == m_mediaVolume)
3285 m_mediaVolume = volume;
3290 m_process->send(Messages::WebPage::SetMediaVolume(volume), m_pageID);
3293 void WebPageProxy::setMayStartMediaWhenInWindow(bool mayStartMedia)
3295 if (mayStartMedia == m_mayStartMediaWhenInWindow)
3298 m_mayStartMediaWhenInWindow = mayStartMedia;
3303 process().send(Messages::WebPage::SetMayStartMediaWhenInWindow(mayStartMedia), m_pageID);
3306 void WebPageProxy::handleDownloadRequest(DownloadProxy* download)
3308 m_pageClient.handleDownloadRequest(download);
3312 void WebPageProxy::didChangeContentSize(const IntSize& size)
3314 m_pageClient.didChangeContentSize(size);
3318 #if ENABLE(INPUT_TYPE_COLOR)
3319 void WebPageProxy::showColorPicker(const WebCore::Color& initialColor, const IntRect& elementRect)
3321 #if ENABLE(INPUT_TYPE_COLOR_POPOVER)
3322 // A new popover color well needs to be created (and the previous one destroyed) for
3323 // each activation of a color element.
3327 m_colorPicker = m_pageClient.createColorPicker(this, initialColor, elementRect);
3328 m_colorPicker->showColorPicker(initialColor);
3331 void WebPageProxy::setColorPickerColor(const WebCore::Color& color)
3333 ASSERT(m_colorPicker);
3335 m_colorPicker->setSelectedColor(color);
3338 void WebPageProxy::endColorPicker()
3340 ASSERT(m_colorPicker);
3342 m_colorPicker->endPicker();
3345 void WebPageProxy::didChooseColor(const WebCore::Color& color)
3350 m_process->send(Messages::WebPage::DidChooseColor(color), m_pageID);
3353 void WebPageProxy::didEndColorPicker()
3358 if (m_colorPicker) {
3359 m_colorPicker->invalidate();
3360 m_colorPicker = nullptr;
3363 m_process->send(Messages::WebPage::DidEndColorPicker(), m_pageID);
3367 void WebPageProxy::didDraw()
3369 m_uiClient->didDraw(this);
3374 #if ENABLE(INSPECTOR)
3376 WebInspectorProxy* WebPageProxy::inspector()
3378 if (isClosed() || !isValid())
3380 return m_inspector.get();
3385 #if ENABLE(FULLSCREEN_API)
3386 WebFullScreenManagerProxy* WebPageProxy::fullScreenManager()
3388 return m_fullScreenManager.get();
3393 RefPtr<WebVideoFullscreenManagerProxy> WebPageProxy::videoFullscreenManager()
3395 return m_videoFullscreenManager;
3401 void WebPageProxy::backForwardAddItem(uint64_t itemID)
3403 m_backForwardList->addItem(m_process->webBackForwardItem(itemID));
3406 void WebPageProxy::backForwardGoToItem(uint64_t itemID, SandboxExtension::Handle& sandboxExtensionHandle)
3408 WebBackForwardListItem* item = m_process->webBackForwardItem(itemID);
3412 bool createdExtension = maybeInitializeSandboxExtensionHandle(URL(URL(), item->url()), sandboxExtensionHandle);
3413 if (createdExtension)
3414 m_process->willAcquireUniversalFileReadSandboxExtension();
3415 m_backForwardList->goToItem(item);
3418 void WebPageProxy::backForwardItemAtIndex(int32_t index, uint64_t& itemID)
3420 WebBackForwardListItem* item = m_backForwardList->itemAtIndex(index);
3421 itemID = item ? item->itemID() : 0;
3424 void WebPageProxy::backForwardBackListCount(int32_t& count)
3426 count = m_backForwardList->backListCount();
3429 void WebPageProxy::backForwardForwardListCount(int32_t& count)
3431 count = m_backForwardList->forwardListCount();
3434 void WebPageProxy::editorStateChanged(const EditorState& editorState)
3437 bool couldChangeSecureInputState = m_editorState.isInPasswordField != editorState.isInPasswordField || m_editorState.selectionIsNone;
3439 #if PLATFORM(MAC) && !USE(ASYNC_NSTEXTINPUTCLIENT)
3440 bool closedComposition = !editorState.shouldIgnoreCompositionSelectionChange && !editorState.hasComposition && (m_editorState.hasComposition || m_temporarilyClosedComposition);
3441 m_temporarilyClosedComposition = editorState.shouldIgnoreCompositionSelectionChange && (m_temporarilyClosedComposition || m_editorState.hasComposition) && !editorState.hasComposition;
3444 m_editorState = editorState;
3447 // Selection being none is a temporary state when editing. Flipping secure input state too quickly was causing trouble (not fully understood).
3448 if (couldChangeSecureInputState && !editorState.selectionIsNone)
3449 m_pageClient.updateSecureInputState();
3452 if (editorState.shouldIgnoreCompositionSelectionChange)
3455 #if PLATFORM(MAC) && !USE(ASYNC_NSTEXTINPUTCLIENT)
3456 if (closedComposition)
3457 m_pageClient.notifyInputContextAboutDiscardedComposition();
3458 if (editorState.hasComposition) {
3459 // Abandon the current inline input session if selection changed for any other reason but an input method changing the composition.
3460 // FIXME: This logic should be in WebCore, no need to round-trip to UI process to cancel the composition.
3461 cancelComposition();
3462 m_pageClient.notifyInputContextAboutDiscardedComposition();
3465 // We always need to notify the client on iOS to make sure the selection is redrawn,
3466 // even during composition to support phrase boundary gesture.
3467 notifyRevealedSelection();
3468 #elif PLATFORM(EFL) || PLATFORM(GTK)
3469 m_pageClient.updateTextInputState();
3473 void WebPageProxy::compositionWasCanceled(const EditorState& editorState)
3476 m_pageClient.notifyInputContextAboutDiscardedComposition();
3478 editorStateChanged(editorState);
3483 void WebPageProxy::registerEditCommandForUndo(uint64_t commandID, uint32_t editAction)
3485 registerEditCommand(WebEditCommandProxy::create(commandID, static_cast<EditAction>(editAction), this), Undo);
3488 void WebPageProxy::registerInsertionUndoGrouping()
3490 #if USE(INSERTION_UNDO_GROUPING)
3491 m_pageClient.registerInsertionUndoGrouping();
3495 void WebPageProxy::canUndoRedo(uint32_t action, bool& result)
3497 result = m_pageClient.canUndoRedo(static_cast<UndoOrRedo>(action));
3500 void WebPageProxy::executeUndoRedo(uint32_t action, bool& result)
3502 m_pageClient.executeUndoRedo(static_cast<UndoOrRedo>(action));
3506 void WebPageProxy::clearAllEditCommands()
3508 m_pageClient.clearAllEditCommands();
3511 void WebPageProxy::didCountStringMatches(const String& string, uint32_t matchCount)
3513 m_findClient->didCountStringMatches(this, string, matchCount);
3516 void WebPageProxy::didGetImageForFindMatch(const ShareableBitmap::Handle& contentImageHandle, uint32_t matchIndex)
3518 m_findMatchesClient.didGetImageForMatchResult(this, WebImage::create(ShareableBitmap::create(contentImageHandle)).get(), matchIndex);
3521 void WebPageProxy::setFindIndicator(const FloatRect& selectionRectInWindowCoordinates, const Vector<FloatRect>& textRectsInSelectionRectCoordinates, float contentImageScaleFactor, const ShareableBitmap::Handle& contentImageHandle, bool fadeOut, bool animate)
3523 RefPtr<FindIndicator> findIndicator = FindIndicator::create(selectionRectInWindowCoordinates, textRectsInSelectionRectCoordinates, contentImageScaleFactor, contentImageHandle);
3524 m_pageClient.setFindIndicator(findIndicator.release(), fadeOut, animate);
3527 void WebPageProxy::didFindString(const String& string, uint32_t matchCount, int32_t matchIndex)
3529 m_findClient->didFindString(this, string, matchCount, matchIndex);
3532 void WebPageProxy::didFindStringMatches(const String& string, const Vector<Vector<WebCore::IntRect>>& matchRects, int32_t firstIndexAfterSelection)
3534 Vector<RefPtr<API::Object>> matches;
3535 matches.reserveInitialCapacity(matchRects.size());
3537 for (const auto& rects : matchRects) {
3538 Vector<RefPtr<API::Object>> apiRects;
3539 apiRects.reserveInitialCapacity(rects.size());
3541 for (const auto& rect : rects)
3542 apiRects.uncheckedAppend(API::Rect::create(toAPI(rect)));
3544 matches.uncheckedAppend(API::Array::create(WTF::move(apiRects)));
3547 m_findMatchesClient.didFindStringMatches(this, string, API::Array::create(WTF::move(matches)).get(), firstIndexAfterSelection);
3550 void WebPageProxy::didFailToFindString(const String& string)
3552 m_findClient->didFailToFindString(this, string);
3555 bool WebPageProxy::sendMessage(std::unique_ptr<IPC::MessageEncoder> encoder, unsigned messageSendFlags)
3557 return m_process->sendMessage(WTF::move(encoder), messageSendFlags);
3560 IPC::Connection* WebPageProxy::messageSenderConnection()
3562 return m_process->connection();
3565 uint64_t WebPageProxy::messageSenderDestinationID()
3570 void WebPageProxy::valueChangedForPopupMenu(WebPopupMenuProxy*, int32_t newSelectedIndex)
3572 m_process->send(Messages::WebPage::DidChangeSelectedIndexForActivePopupMenu(newSelectedIndex), m_pageID);
3575 void WebPageProxy::setTextFromItemForPopupMenu(WebPopupMenuProxy*, int32_t index)
3577 m_process->send(Messages::WebPage::SetTextForActivePopupMenu(index), m_pageID);
3580 NativeWebMouseEvent* WebPageProxy::currentlyProcessedMouseDownEvent()
3582 return m_currentlyProcessedMouseDownEvent.get();
3585 void WebPageProxy::postMessageToInjectedBundle(const String& messageName, API::Object* messageBody)
3587 process().send(Messages::WebPage::PostInjectedBundleMessage(messageName, WebContextUserMessageEncoder(messageBody, process())), m_pageID);
3591 void WebPageProxy::failedToShowPopupMenu()
3593 m_process->send(Messages::WebPage::FailedToShowPopupMenu(), m_pageID);
3597 void WebPageProxy::showPopupMenu(const IntRect& rect, uint64_t textDirection, const Vector<WebPopupItem>& items, int32_t selectedIndex, const PlatformPopupMenuData& data)
3599 if (m_activePopupMenu) {
3601 m_uiPopupMenuClient.hidePopupMenu(this);
3603 m_activePopupMenu->hidePopupMenu();
3605 m_activePopupMenu->invalidate();
3606 m_activePopupMenu = 0;
3609 m_activePopupMenu = m_pageClient.createPopupMenuProxy(this);
3611 if (!m_activePopupMenu)
3614 // Since showPopupMenu() can spin a nested run loop we need to turn off the responsiveness timer.
3615 m_process->responsivenessTimer()->stop();
3619 m_uiPopupMenuClient.showPopupMenu(this, m_activePopupMenu.get(), rect, static_cast<TextDirection>(textDirection), m_pageScaleFactor, items, selectedIndex);
3621 RefPtr<WebPopupMenuProxy> protectedActivePopupMenu = m_activePopupMenu;
3623 protectedActivePopupMenu->showPopupMenu(rect, static_cast<TextDirection>(textDirection), m_pageScaleFactor, items, data, selectedIndex);
3625 // Since Efl doesn't use a nested mainloop to show the popup and get the answer, we need to keep the client pointer valid.
3626 // FIXME: The above comment doesn't make any sense since this code is compiled out for EFL.
3627 protectedActivePopupMenu->invalidate();
3628 protectedActivePopupMenu = 0;
3632 void WebPageProxy::hidePopupMenu()
3634 if (!m_activePopupMenu)
3638 m_uiPopupMenuClient.hidePopupMenu(this);
3640 m_activePopupMenu->hidePopupMenu();
3642 m_activePopupMenu->invalidate();
3643 m_activePopupMenu = 0;
3646 #if ENABLE(CONTEXT_MENUS)
3647 void WebPageProxy::showContextMenu(const IntPoint& menuLocation, const ContextMenuContextData& contextMenuContextData, const Vector<WebContextMenuItemData>& proposedItems, IPC::MessageDecoder& decoder)
3649 internalShowContextMenu(menuLocation, contextMenuContextData, proposedItems, ContextMenuClientEligibility::EligibleForClient, &decoder);
3651 // No matter the result of internalShowContextMenu, always notify the WebProcess that the menu is hidden so it starts handling mouse events again.
3652 m_process->send(Messages::WebPage::ContextMenuHidden(), m_pageID);
3655 void WebPageProxy::internalShowContextMenu(const IntPoint& menuLocation, const ContextMenuContextData& contextMenuContextData, const Vector<WebContextMenuItemData>& proposedItems, ContextMenuClientEligibility clientEligibility, IPC::MessageDecoder* decoder)
3657 RefPtr<API::Object> userData;
3658 WebContextUserMessageDecoder messageDecoder(userData, process());
3659 if (decoder && !decoder->decode(messageDecoder))
3662 m_activeContextMenuContextData = contextMenuContextData;
3664 if (!m_contextMenuClient.hideContextMenu(this) && m_activeContextMenu) {
3665 m_activeContextMenu->hideContextMenu();
3666 m_activeContextMenu = 0;
3669 m_activeContextMenu = m_pageClient.createContextMenuProxy(this);
3670 if (!m_activeContextMenu)
3673 // Since showContextMenu() can spin a nested run loop we need to turn off the responsiveness timer.
3674 m_process->responsivenessTimer()->stop();
3676 // Unless this is an image control, give the PageContextMenuClient one last swipe at changing the menu.
3677 Vector<WebContextMenuItemData> items;
3678 bool useProposedItems = true;
3679 bool askClientToChangeMenu = clientEligibility == ContextMenuClientEligibility::EligibleForClient;
3680 #if ENABLE(SERVICE_CONTROLS)
3681 if (!contextMenuContextData.controlledImageHandle().isNull())
3682 askClientToChangeMenu = false;
3685 if (askClientToChangeMenu && m_contextMenuClient.getContextMenuFromProposedMenu(this, proposedItems, items, contextMenuContextData.webHitTestResultData(), userData.get()))
3686 useProposedItems = false;
3688 const Vector<WebContextMenuItemData>& itemsToShow = useProposedItems ? proposedItems : items;
3689 if (!m_contextMenuClient.showContextMenu(this, menuLocation, itemsToShow))
3690 m_activeContextMenu->showContextMenu(menuLocation, itemsToShow, contextMenuContextData);
3692 m_contextMenuClient.contextMenuDismissed(this);
3695 void WebPageProxy::contextMenuItemSelected(const WebContextMenuItemData& item)
3697 // Application custom items don't need to round-trip through to WebCore in the WebProcess.
3698 if (item.action() >= ContextMenuItemBaseApplicationTag) {
3699 m_contextMenuClient.customContextMenuItemSelected(this, item);
3704 if (item.action() == ContextMenuItemTagSmartCopyPaste) {
3705 setSmartInsertDeleteEnabled(!isSmartInsertDeleteEnabled());
3708 if (item.action() == ContextMenuItemTagSmartQuotes) {
3709 TextChecker::setAutomaticQuoteSubstitutionEnabled(!TextChecker::state().isAutomaticQuoteSubstitutionEnabled);
3710 m_process->updateTextCheckerState();
3713 if (item.action() == ContextMenuItemTagSmartDashes) {
3714 TextChecker::setAutomaticDashSubstitutionEnabled(!TextChecker::state().isAutomaticDashSubstitutionEnabled);
3715 m_process->updateTextCheckerState();
3718 if (item.action() == ContextMenuItemTagSmartLinks) {
3719 TextChecker::setAutomaticLinkDetectionEnabled(!TextChecker::state().isAutomaticLinkDetectionEnabled);
3720 m_process->updateTextCheckerState();
3723 if (item.action() == ContextMenuItemTagTextReplacement) {
3724 TextChecker::setAutomaticTextReplacementEnabled(!TextChecker::state().isAutomaticTextReplacementEnabled);
3725 m_process->updateTextCheckerState();
3728 if (item.action() == ContextMenuItemTagCorrectSpellingAutomatically) {
3729 TextChecker::setAutomaticSpellingCorrectionEnabled(!TextChecker::state().isAutomaticSpellingCorrectionEnabled);
3730 m_process->updateTextCheckerState();
3733 if (item.action() == ContextMenuItemTagShowSubstitutions) {
3734 TextChecker::toggleSubstitutionsPanelIsShowing();
3738 if (item.action() == ContextMenuItemTagDownloadImageToDisk) {
3739 m_process->context().download(this, URL(URL(), m_activeContextMenuContextData.webHitTestResultData().absoluteImageURL));
3742 if (item.action() == ContextMenuItemTagDownloadLinkToDisk) {
3743 m_process->context().download(this, URL(URL(), m_activeContextMenuContextData.webHitTestResultData().absoluteLinkURL));
3746 if (item.action() == ContextMenuItemTagDownloadMediaToDisk) {
3747 m_process->context().download(this, URL(URL(), m_activeContextMenuContextData.webHitTestResultData().absoluteMediaURL));
3750 if (item.action() == ContextMenuItemTagCheckSpellingWhileTyping) {
3751 TextChecker::setContinuousSpellCheckingEnabled(!TextChecker::state().isContinuousSpellCheckingEnabled);
3752 m_process->updateTextCheckerState();
3755 if (item.action() == ContextMenuItemTagCheckGrammarWithSpelling) {
3756 TextChecker::setGrammarCheckingEnabled(!TextChecker::state().isGrammarCheckingEnabled);
3757 m_process->updateTextCheckerState();
3760 if (item.action() == ContextMenuItemTagShowSpellingPanel) {
3761 if (!TextChecker::spellingUIIsShowing())
3762 advanceToNextMisspelling(true);
3763 TextChecker::toggleSpellingUIIsShowing();
3766 if (item.action() == ContextMenuItemTagLearnSpelling || item.action() == ContextMenuItemTagIgnoreSpelling)
3767 ++m_pendingLearnOrIgnoreWordMessageCount;
3769 m_process->send(Messages::WebPage::DidSelectItemFromActiveContextMenu(item), m_pageID);
3771 #endif // ENABLE(CONTEXT_MENUS)
3774 void WebPageProxy::didChooseFilesForOpenPanelWithDisplayStringAndIcon(const Vector<String>& fileURLs, const String& displayString, const API::Data* iconData)
3779 #if ENABLE(SANDBOX_EXTENSIONS)
3780 // FIXME: The sandbox extensions should be sent with the DidChooseFilesForOpenPanel message. This
3781 // is gated on a way of passing SandboxExtension::Handles in a Vector.
3782 for (size_t i = 0; i < fileURLs.size(); ++i) {
3783 SandboxExtension::Handle sandboxExtensionHandle;
3784 SandboxExtension::createHandle(fileURLs[i], SandboxExtension::ReadOnly, sandboxExtensionHandle);
3785 m_process->send(Messages::WebPage::ExtendSandboxForFileFromOpenPanel(sandboxExtensionHandle), m_pageID);
3789 m_process->send(Messages::WebPage::DidChooseFilesForOpenPanelWithDisplayStringAndIcon(fileURLs, displayString, iconData ? iconData->dataReference() : IPC::DataReference()), m_pageID);
3791 m_openPanelResultListener->invalidate();
3792 m_openPanelResultListener = nullptr;
3796 void WebPageProxy::didChooseFilesForOpenPanel(const Vector<String>& fileURLs)
3801 #if ENABLE(SANDBOX_EXTENSIONS)
3802 // FIXME: The sandbox extensions should be sent with the DidChooseFilesForOpenPanel message. This
3803 // is gated on a way of passing SandboxExtension::Handles in a Vector.
3804 for (size_t i = 0; i < fileURLs.size(); ++i) {
3805 SandboxExtension::Handle sandboxExtensionHandle;
3806 SandboxExtension::createHandle(fileURLs[i], SandboxExtension::ReadOnly, sandboxExtensionHandle);
3807 m_process->send(Messages::WebPage::ExtendSandboxForFileFromOpenPanel(sandboxExtensionHandle), m_pageID);
3811 m_process->send(Messages::WebPage::DidChooseFilesForOpenPanel(fileURLs), m_pageID);
3813 m_openPanelResultListener->invalidate();
3814 m_openPanelResultListener = 0;
3817 void WebPageProxy::didCancelForOpenPanel()
3822 m_process->send(Messages::WebPage::DidCancelForOpenPanel(), m_pageID);
3824 m_openPanelResultListener->invalidate();
3825 m_openPanelResultListener = 0;
3828 void WebPageProxy::advanceToNextMisspelling(bool startBeforeSelection)
3830 m_process->send(Messages::WebPage::AdvanceToNextMisspelling(startBeforeSelection), m_pageID);
3833 void WebPageProxy::changeSpellingToWord(const String& word)
3838 m_process->send(Messages::WebPage::ChangeSpellingToWord(word), m_pageID);
3841 void WebPageProxy::registerEditCommand(PassRefPtr<WebEditCommandProxy> commandProxy, UndoOrRedo undoOrRedo)
3843 m_pageClient.registerEditCommand(commandProxy, undoOrRedo);
3846 void WebPageProxy::addEditCommand(WebEditCommandProxy* command)
3848 m_editCommandSet.add(command);
3851 void WebPageProxy::removeEditCommand(WebEditCommandProxy* command)
3853 m_editCommandSet.remove(command);
3857 m_process->send(Messages::WebPage::DidRemoveEditCommand(command->commandID()), m_pageID);
3860 bool WebPageProxy::isValidEditCommand(WebEditCommandProxy* command)
3862 return m_editCommandSet.find(command) != m_editCommandSet.end();
3865 int64_t WebPageProxy::spellDocumentTag()
3867 if (!m_hasSpellDocumentTag) {
3868 m_spellDocumentTag = TextChecker::uniqueSpellDocumentTag(this);
3869 m_hasSpellDocumentTag = true;
3872 return m_spellDocumentTag;
3875 #if USE(UNIFIED_TEXT_CHECKING)
3876 void WebPageProxy::checkTextOfParagraph(const String& text, uint64_t checkingTypes, Vector<TextCheckingResult>& results)
3878 results = TextChecker::checkTextOfParagraph(spellDocumentTag(), text, checkingTypes);
3882 void WebPageProxy::checkSpellingOfString(const String& text, int32_t& misspellingLocation, int32_t& misspellingLength)
3884 TextChecker::checkSpellingOfString(spellDocumentTag(), text, misspellingLocation, misspellingLength);
3887 void WebPageProxy::checkGrammarOfString(const String& text, Vector<GrammarDetail>& grammarDetails, int32_t& badGrammarLocation, int32_t& badGrammarLength)
3889 TextChecker::checkGrammarOfString(spellDocumentTag(), text, grammarDetails, badGrammarLocation, badGrammarLength);
3892 void WebPageProxy::spellingUIIsShowing(bool& isShowing)
3894 isShowing = TextChecker::spellingUIIsShowing();
3897 void WebPageProxy::updateSpellingUIWithMisspelledWord(const String& misspelledWord)
3899 TextChecker::updateSpellingUIWithMisspelledWord(spellDocumentTag(), misspelledWord);
3902 void WebPageProxy::updateSpellingUIWithGrammarString(const String& badGrammarPhrase, const GrammarDetail& grammarDetail)
3904 TextChecker::updateSpellingUIWithGrammarString(spellDocumentTag(), badGrammarPhrase, grammarDetail);
3907 void WebPageProxy::getGuessesForWord(const String& word, const String& context, Vector<String>& guesses)
3909 TextChecker::getGuessesForWord(spellDocumentTag(), word, context, guesses);
3912 void WebPageProxy::learnWord(const String& word)
3914 MESSAGE_CHECK(m_pendingLearnOrIgnoreWordMessageCount);
3915 --m_pendingLearnOrIgnoreWordMessageCount;
3917 TextChecker::learnWord(spellDocumentTag(), word);
3920 void WebPageProxy::ignoreWord(const String& word)
3922 MESSAGE_CHECK(m_pendingLearnOrIgnoreWordMessageCount);
3923 --m_pendingLearnOrIgnoreWordMessageCount;
3925 TextChecker::ignoreWord(spellDocumentTag(), word);
3928 void WebPageProxy::requestCheckingOfString(uint64_t requestID, const TextCheckingRequestData& request)
3930 TextChecker::requestCheckingOfString(TextCheckerCompletion::create(requestID, request, this));
3933 void WebPageProxy::didFinishCheckingText(uint64_t requestID, const Vector<WebCore::TextCheckingResult>& result)
3935 m_process->send(Messages::WebPage::DidFinishCheckingText(requestID, result), m_pageID);
3938 void WebPageProxy::didCancelCheckingText(uint64_t requestID)
3940 m_process->send(Messages::WebPage::DidCancelCheckingText(requestID), m_pageID);
3944 void WebPageProxy::setFocus(bool focused)
3947 m_uiClient->focus(this);
3949 m_uiClient->unfocus(this);
3952 void WebPageProxy::takeFocus(uint32_t direction)
3954 m_uiClient->takeFocus(this, (static_cast<FocusDirection>(direction) == FocusDirectionForward) ? kWKFocusDirectionForward : kWKFocusDirectionBackward);
3957 void WebPageProxy::setToolTip(const String& toolTip)
3959 String oldToolTip = m_toolTip;
3960 m_toolTip = toolTip;
3961 m_pageClient.toolTipChanged(oldToolTip, m_toolTip);
3964 void WebPageProxy::setCursor(const WebCore::Cursor& cursor)
3966 // The Web process may have asked to change the cursor when the view was in an active window, but
3967 // if it is no longer in a window or the window is not active, then the cursor should not change.
3968 if (m_pageClient.isViewWindowActive())
3969 m_pageClient.setCursor(cursor);
3972 void WebPageProxy::setCursorHiddenUntilMouseMoves(bool hiddenUntilMouseMoves)
3974 m_pageClient.setCursorHiddenUntilMouseMoves(hiddenUntilMouseMoves);
3977 void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled)
3979 WebEvent::Type type = static_cast<WebEvent::Type>(opaqueType);
3982 case WebEvent::NoType:
3983 case WebEvent::MouseMove:
3986 case WebEvent::MouseDown:
3987 case WebEvent::MouseUp:
3988 case WebEvent::Wheel:
3989 case WebEvent::KeyDown:
3990 case WebEvent::KeyUp:
3991 case WebEvent::RawKeyDown:
3992 case WebEvent::Char:
3993 #if ENABLE(TOUCH_EVENTS)
3994 case WebEvent::TouchStart:
3995 case WebEvent::TouchMove:
3996 case WebEvent::TouchEnd:
3997 case WebEvent::TouchCancel:
3999 m_process->responsivenessTimer()->stop();
4004 case WebEvent::NoType:
4006 case WebEvent::MouseMove:
4007 m_processingMouseMoveEvent = false;
4008 if (m_nextMouseMoveEvent) {
4009 handleMouseEvent(*m_nextMouseMoveEvent);
4010 m_nextMouseMoveEvent = nullptr;
4013 case WebEvent::MouseDown:
4015 case WebEvent::MouseUp:
4016 m_currentlyProcessedMouseDownEvent = nullptr;
4019 case WebEvent::Wheel: {
4020 MESSAGE_CHECK(!m_currentlyProcessedWheelEvents.isEmpty());
4022 std::unique_ptr<Vector<NativeWebWheelEvent>> oldestCoalescedEvent = m_currentlyProcessedWheelEvents.takeFirst();
4024 // FIXME: Dispatch additional events to the didNotHandleWheelEvent client function.
4026 if (m_uiClient->implementsDidNotHandleWheelEvent())
4027 m_uiClient->didNotHandleWheelEvent(this, oldestCoalescedEvent->last());
4029 m_pageClient.wheelEventWasNotHandledByWebCore(oldestCoalescedEvent->last());
4033 if (!m_wheelEventQueue.isEmpty())
4034 processNextQueuedWheelEvent();
4038 case WebEvent::KeyDown:
4039 case WebEvent::KeyUp:
4040 case WebEvent::RawKeyDown:
4041 case WebEvent::Char: {
4042 LOG(KeyHandling, "WebPageProxy::didReceiveEvent: %s", webKeyboardEventTypeString(type));
4044 MESSAGE_CHECK(!m_keyEventQueue.isEmpty());
4045 NativeWebKeyboardEvent event = m_keyEventQueue.takeFirst();
4047 MESSAGE_CHECK(type == event.type());
4049 if (!m_keyEventQueue.isEmpty())
4050 m_process->send(Messages::WebPage::KeyEvent(m_keyEventQueue.first()), m_pageID);
4052 m_pageClient.doneWithKeyEvent(event, handled);
4056 if (m_uiClient->implementsDidNotHandleKeyEvent())
4057 m_uiClient->didNotHandleKeyEvent(this, event);
4060 #if ENABLE(IOS_TOUCH_EVENTS)
4061 case WebEvent::TouchStart:
4062 case WebEvent::TouchMove:
4063 case WebEvent::TouchEnd:
4064 case WebEvent::TouchCancel:
4066 #elif ENABLE(TOUCH_EVENTS)
4067 case WebEvent::TouchStart:
4068 case WebEvent::TouchMove:
4069 case WebEvent::TouchEnd:
4070 case WebEvent::TouchCancel: {
4071 MESSAGE_CHECK(!m_touchEventQueue.isEmpty());
4072 QueuedTouchEvents queuedEvents = m_touchEventQueue.takeFirst();
4074 MESSAGE_CHECK(type == queuedEvents.forwardedEvent.type());
4076 m_pageClient.doneWithTouchEvent(queuedEvents.forwardedEvent, handled);
4077 for (size_t i = 0; i < queuedEvents.deferredTouchEvents.size(); ++i) {
4078 bool isEventHandled = false;
4079 m_pageClient.doneWithTouchEvent(queuedEvents.deferredTouchEvents.at(i), isEventHandled);
4087 void WebPageProxy::stopResponsivenessTimer()
4089 m_process->responsivenessTimer()->stop();
4092 void WebPageProxy::voidCallback(uint64_t callbackID)
4094 auto callback = m_callbacks.take<VoidCallback>(callbackID);
4096 // FIXME: Log error or assert.
4100 callback->performCallback();
4103 void WebPageProxy::dataCallback(const IPC::DataReference& dataReference, uint64_t callbackID)
4105 auto callback = m_callbacks.take<DataCallback>(callbackID);
4107 // FIXME: Log error or assert.
4111 callback->performCallbackWithReturnValue(API::Data::create(dataReference.data(), dataReference.size()).get());
4114 void WebPageProxy::imageCallback(const ShareableBitmap::Handle& bitmapHandle, uint64_t callbackID)
4116 auto callback = m_callbacks.take<ImageCallback>(callbackID);
4118 // FIXME: Log error or assert.
4122 callback->performCallbackWithReturnValue(bitmapHandle);
4125 void WebPageProxy::stringCallback(const String& resultString, uint64_t callbackID)
4127 auto callback = m_callbacks.take<StringCallback>(callbackID);
4129 // FIXME: Log error or assert.
4130 // this can validly happen if a load invalidated the callback, though
4134 m_loadDependentStringCallbackIDs.remove(callbackID);
4136 callback->performCallbackWithReturnValue(resultString.impl());
4139 void WebPageProxy::scriptValueCallback(const IPC::DataReference& dataReference, uint64_t callbackID)
4141 auto callback = m_callbacks.take<ScriptValueCallback>(callbackID);
4143 // FIXME: Log error or assert.
4147 Vector<uint8_t> data;
4148 data.reserveInitialCapacity(dataReference.size());
4149 data.append(dataReference.data(), dataReference.size());
4151 callback->performCallbackWithReturnValue(data.size() ? WebSerializedScriptValue::adopt(data).get() : 0);
4154 void WebPageProxy::computedPagesCallback(const Vector<IntRect>& pageRects, double totalScaleFactorForPrinting, uint64_t callbackID)
4156 auto callback = m_callbacks.take<ComputedPagesCallback>(callbackID);
4158 // FIXME: Log error or assert.
4162 callback->performCallbackWithReturnValue(pageRects, totalScaleFactorForPrinting);
4165 void WebPageProxy::validateCommandCallback(const String& commandName, bool isEnabled, int state, uint64_t callbackID)
4167 auto callback = m_callbacks.take<ValidateCommandCallback>(callbackID);
4169 // FIXME: Log error or assert.
4173 callback->performCallbackWithReturnValue(commandName.impl(), isEnabled, state);
4176 void WebPageProxy::unsignedCallback(uint64_t result, uint64_t callbackID)
4178 auto callback = m_callbacks.take<UnsignedCallback>(callbackID);
4180 // FIXME: Log error or assert.
4181 // this can validly happen if a load invalidated the callback, though
4185 callback->performCallbackWithReturnValue(result);
4188 void WebPageProxy::editingRangeCallback(const EditingRange& range, uint64_t callbackID)
4190 MESSAGE_CHECK(range.isValid());
4192 auto callback = m_callbacks.take<EditingRangeCallback>(callbackID);
4194 // FIXME: Log error or assert.
4195 // this can validly happen if a load invalidated the callback, though
4199 callback->performCallbackWithReturnValue(range);
4202 void WebPageProxy::rectForCharacterRangeCallback(const IntRect& rect, const EditingRange& actualRange, uint64_t callbackID)
4204 MESSAGE_CHECK(actualRange.isValid());
4206 auto callback = m_callbacks.take<RectForCharacterRangeCallback>(callbackID);
4208 // FIXME: Log error or assert.
4209 // this can validly happen if a load invalidated the callback, though
4213 callback->performCallbackWithReturnValue(rect, actualRange);
4217 void WebPageProxy::printFinishedCallback(const ResourceError& printError, uint64_t callbackID)
4219 auto callback = m_callbacks.take<PrintFinishedCallback>(callbackID);
4221 // FIXME: Log error or assert.
4225 RefPtr<API::Error> error = API::Error::create(printError);
4226 callback->performCallbackWithReturnValue(error.get());
4230 void WebPageProxy::focusedFrameChanged(uint64_t frameID)
4237 WebFrameProxy* frame = m_process->webFrame(frameID);
4238 MESSAGE_CHECK(frame);
4240 m_focusedFrame = frame;
4243 void WebPageProxy::frameSetLargestFrameChanged(uint64_t frameID)
4246 m_frameSetLargestFrame = 0;
4250 WebFrameProxy* frame = m_process->webFrame(frameID);
4251 MESSAGE_CHECK(frame);
4253 m_frameSetLargestFrame = frame;
4256 void WebPageProxy::processDidBecomeUnresponsive()
4261 updateBackingStoreDiscardableState();
4263 m_loaderClient->processDidBecomeUnresponsive(this);
4266 void WebPageProxy::interactionOccurredWhileProcessUnresponsive()
4271 m_loaderClient->interactionOccurredWhileProcessUnresponsive(this);
4274 void WebPageProxy::processDidBecomeResponsive()
4279 updateBackingStoreDiscardableState();
4281 m_loaderClient->processDidBecomeResponsive(this);
4284 void WebPageProxy::processDidCrash()
4288 // There is a nested transaction in resetStateAfterProcessExited() that we don't want to commit before the client call.
4289 PageLoadState::Transaction transaction = m_pageLoadState.transaction();
4291 resetStateAfterProcessExited();
4293 m_loaderClient->processDidCrash(this);
4296 void WebPageProxy::resetState(ResetStateReason resetStateReason)