setCustomSwipeViews inside didChangeBackForwardList client callback is ignored
[WebKit-https.git] / Source / WebKit2 / UIProcess / WebPageProxy.cpp
1 /*
2  * Copyright (C) 2010, 2011 Apple Inc. All rights reserved.
3  * Copyright (C) 2012 Intel Corporation. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
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.
13  *
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.
25  */
26
27 #include "config.h"
28 #include "WebPageProxy.h"
29
30 #include "APIArray.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"
45 #include "Logging.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"
67 #include "WebEvent.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>
100 #include <stdio.h>
101 #include <wtf/NeverDestroyed.h>
102 #include <wtf/text/StringView.h>
103
104 #if ENABLE(ASYNC_SCROLLING)
105 #include "RemoteScrollingCoordinatorProxy.h"
106 #endif
107
108 #if USE(COORDINATED_GRAPHICS)
109 #include "CoordinatedLayerTreeHostProxyMessages.h"
110 #endif
111
112 #if PLATFORM(GTK)
113 #include "ArgumentCodersGtk.h"
114 #endif
115
116 #if USE(SOUP) && !ENABLE(CUSTOM_PROTOCOLS)
117 #include "WebSoupRequestManagerProxy.h"
118 #endif
119
120 #if ENABLE(VIBRATION)
121 #include "WebVibrationProxy.h"
122 #endif
123
124 #ifndef NDEBUG
125 #include <wtf/RefCountedLeakCounter.h>
126 #endif
127
128 #if ENABLE(NETWORK_PROCESS)
129 #include "NetworkProcessMessages.h"
130 #endif
131
132 #if PLATFORM(COCOA)
133 #include "ViewSnapshotStore.h"
134 #include <WebCore/RunLoopObserver.h>
135 #endif
136
137 #if PLATFORM(IOS)
138 #include "WebVideoFullscreenManagerProxy.h"
139 #include "WebVideoFullscreenManagerProxyMessages.h"
140 #endif
141
142 #if USE(CAIRO)
143 #include <WebCore/CairoUtilities.h>
144 #endif
145
146 // This controls what strategy we use for mouse wheel coalescing.
147 #define MERGE_WHEEL_EVENTS 1
148
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())
151
152 using namespace WebCore;
153
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;
156
157 namespace WebKit {
158
159 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, webPageProxyCounter, ("WebPageProxy"));
160
161 class ExceededDatabaseQuotaRecords {
162     WTF_MAKE_NONCOPYABLE(ExceededDatabaseQuotaRecords); WTF_MAKE_FAST_ALLOCATED;
163     friend class NeverDestroyed<ExceededDatabaseQuotaRecords>;
164 public:
165     struct Record {
166         uint64_t frameID;
167         String originIdentifier;
168         String databaseName;
169         String displayName;
170         uint64_t currentQuota;
171         uint64_t currentOriginUsage;
172         uint64_t currentDatabaseUsage;
173         uint64_t expectedUsage;
174         RefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply> reply;
175     };
176
177     static ExceededDatabaseQuotaRecords& shared();
178
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>);
183
184     void add(std::unique_ptr<Record>);
185     bool areBeingProcessed() const { return !!m_currentRecord; }
186     Record* next();
187
188 private:
189     ExceededDatabaseQuotaRecords() { }
190     ~ExceededDatabaseQuotaRecords() { }
191
192     Deque<std::unique_ptr<Record>> m_records;
193     std::unique_ptr<Record> m_currentRecord;
194 };
195
196 ExceededDatabaseQuotaRecords& ExceededDatabaseQuotaRecords::shared()
197 {
198     static NeverDestroyed<ExceededDatabaseQuotaRecords> records;
199     return records;
200 }
201
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)
206 {
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);
218 }
219
220 void ExceededDatabaseQuotaRecords::add(std::unique_ptr<ExceededDatabaseQuotaRecords::Record> record)
221 {
222     m_records.append(WTF::move(record));
223 }
224
225 ExceededDatabaseQuotaRecords::Record* ExceededDatabaseQuotaRecords::next()
226 {
227     m_currentRecord = nullptr;
228     if (!m_records.isEmpty())
229         m_currentRecord = m_records.takeFirst();
230     return m_currentRecord.get();
231 }
232
233 #if !LOG_DISABLED
234 static const char* webKeyboardEventTypeString(WebEvent::Type type)
235 {
236     switch (type) {
237     case WebEvent::KeyDown:
238         return "KeyDown";
239     
240     case WebEvent::KeyUp:
241         return "KeyUp";
242     
243     case WebEvent::RawKeyDown:
244         return "RawKeyDown";
245     
246     case WebEvent::Char:
247         return "Char";
248     
249     default:
250         ASSERT_NOT_REACHED();
251         return "<unknown>";
252     }
253 }
254 #endif // !LOG_DISABLED
255
256 PassRefPtr<WebPageProxy> WebPageProxy::create(PageClient& pageClient, WebProcessProxy& process, uint64_t pageID, const WebPageConfiguration& configuration)
257 {
258     return adoptRef(new WebPageProxy(pageClient, process, pageID, configuration));
259 }
260
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>())
268     , m_process(process)
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())
275 #if PLATFORM(IOS)
276     , m_deviceOrientation(0)
277     , m_dynamicViewportSizeUpdateWaitingForTarget(false)
278     , m_dynamicViewportSizeUpdateWaitingForLayerTreeCommit(false)
279     , m_dynamicViewportSizeUpdateLayerTreeTransactionID(0)
280 #endif
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)
289 #endif
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)
303     , m_pageLength(0)
304     , m_gapBetweenPages(0)
305     , m_isValid(true)
306     , m_isClosed(false)
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)
322 #endif
323     , m_pageID(pageID)
324     , m_session(*configuration.session)
325     , m_isPageSuspended(false)
326     , m_addsVisitedLinks(true)
327 #if ENABLE(REMOTE_INSPECTOR)
328     , m_allowsRemoteInspection(true)
329 #endif
330 #if PLATFORM(COCOA)
331     , m_isSmartInsertDeleteEnabled(TextChecker::isSmartInsertDeleteEnabled())
332 #endif
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)
341 #endif
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)
361     , m_pageCount(0)
362     , m_renderTreeSize(0)
363     , m_shouldSendEventsSynchronously(false)
364     , m_suppressVisibilityUpdates(false)
365     , m_autoSizingShouldExpandToViewHeight(false)
366     , m_mediaVolume(1)
367     , m_mayStartMediaWhenInWindow(true)
368     , m_scrollPinningBehavior(DoNotPin)
369     , m_navigationID(0)
370     , m_configurationPreferenceValues(configuration.preferenceValues)
371     , m_potentiallyChangedViewStateFlags(ViewState::NoFlags)
372     , m_viewStateChangeWantsReply(false)
373 {
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());
378     }
379
380     updateViewState();
381     updateActivityToken();
382     
383 #if HAVE(OUT_OF_PROCESS_LAYER_HOSTING)
384     m_layerHostingMode = m_viewState & ViewState::IsInWindow ? m_pageClient.viewLayerHostingMode() : LayerHostingMode::OutOfProcess;
385 #endif
386
387     platformInitialize();
388
389 #ifndef NDEBUG
390     webPageProxyCounter.increment();
391 #endif
392
393     WebContext::statistics().wkPageCount++;
394
395     m_preferences->addPage(*this);
396     m_pageGroup->addPage(this);
397
398 #if ENABLE(INSPECTOR)
399     m_inspector = WebInspectorProxy::create(this);
400 #endif
401 #if ENABLE(FULLSCREEN_API)
402     m_fullScreenManager = WebFullScreenManagerProxy::create(*this, m_pageClient.fullScreenManagerProxyClient());
403 #endif
404 #if PLATFORM(IOS)
405     m_videoFullscreenManager = WebVideoFullscreenManagerProxy::create(*this);
406 #endif
407 #if ENABLE(VIBRATION)
408     m_vibration = WebVibrationProxy::create(this);
409 #endif
410
411     m_process->addMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID, *this);
412
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);
417
418 #if PLATFORM(COCOA)
419     const CFIndex viewStateChangeRunLoopOrder = (CFIndex)RunLoopObserver::WellKnownRunLoopOrders::CoreAnimationCommit - 1;
420     m_viewStateChangeDispatcher = RunLoopObserver::create(viewStateChangeRunLoopOrder, [this]() {
421         this->dispatchViewStateChange();
422     });
423 #endif
424 }
425
426 WebPageProxy::~WebPageProxy()
427 {
428     if (!m_isClosed)
429         close();
430
431     WebContext::statistics().wkPageCount--;
432
433     if (m_hasSpellDocumentTag)
434         TextChecker::closeSpellDocumentWithTag(m_spellDocumentTag);
435
436     m_preferences->removePage(*this);
437     m_pageGroup->removePage(this);
438
439 #ifndef NDEBUG
440     webPageProxyCounter.decrement();
441 #endif
442 }
443
444 PlatformProcessIdentifier WebPageProxy::processIdentifier() const
445 {
446     if (m_isClosed)
447         return 0;
448
449     return m_process->processIdentifier();
450 }
451
452 bool WebPageProxy::isValid() const
453 {
454     // A page that has been explicitly closed is never valid.
455     if (m_isClosed)
456         return false;
457
458     return m_isValid;
459 }
460
461 void WebPageProxy::setPreferences(WebPreferences& preferences)
462 {
463     if (&preferences == &m_preferences.get())
464         return;
465
466     m_preferences->removePage(*this);
467     m_preferences = preferences;
468     m_preferences->addPage(*this);
469
470     preferencesDidChange();
471 }
472
473 void WebPageProxy::setLoaderClient(std::unique_ptr<API::LoaderClient> loaderClient)
474 {
475     if (!loaderClient) {
476         m_loaderClient = std::make_unique<API::LoaderClient>();
477         return;
478     }
479
480     m_loaderClient = WTF::move(loaderClient);
481 }
482
483 void WebPageProxy::setPolicyClient(std::unique_ptr<API::PolicyClient> policyClient)
484 {
485     if (!policyClient) {
486         m_policyClient = std::make_unique<API::PolicyClient>();
487         return;
488     }
489
490     m_policyClient = WTF::move(policyClient);
491 }
492
493 void WebPageProxy::setFormClient(std::unique_ptr<API::FormClient> formClient)
494 {
495     if (!formClient) {
496         m_formClient = std::make_unique<API::FormClient>();
497         return;
498     }
499
500     m_formClient = WTF::move(formClient);
501 }
502
503 void WebPageProxy::setUIClient(std::unique_ptr<API::UIClient> uiClient)
504 {
505     if (!uiClient) {
506         m_uiClient = std::make_unique<API::UIClient>();
507         return;
508     }
509
510     m_uiClient = WTF::move(uiClient);
511
512     if (!isValid())
513         return;
514
515     m_process->send(Messages::WebPage::SetCanRunBeforeUnloadConfirmPanel(m_uiClient->canRunBeforeUnloadConfirmPanel()), m_pageID);
516     setCanRunModal(m_uiClient->canRunModal());
517 }
518
519 void WebPageProxy::setFindClient(std::unique_ptr<API::FindClient> findClient)
520 {
521     if (!findClient) {
522         m_findClient = std::make_unique<API::FindClient>();
523         return;
524     }
525     
526     m_findClient = WTF::move(findClient);
527 }
528
529 void WebPageProxy::initializeFindMatchesClient(const WKPageFindMatchesClientBase* client)
530 {
531     m_findMatchesClient.initialize(client);
532 }
533
534 #if ENABLE(CONTEXT_MENUS)
535 void WebPageProxy::initializeContextMenuClient(const WKPageContextMenuClientBase* client)
536 {
537     m_contextMenuClient.initialize(client);
538 }
539 #endif
540
541 void WebPageProxy::reattachToWebProcess()
542 {
543     ASSERT(!m_isClosed);
544     ASSERT(!isValid());
545     ASSERT(m_process->state() == WebProcessProxy::State::Terminated);
546
547     m_isValid = true;
548
549     if (m_process->context().processModel() == ProcessModelSharedSecondaryProcess)
550         m_process = m_process->context().ensureSharedWebProcess();
551     else
552         m_process = m_process->context().createNewWebProcessRespectingProcessCountLimit();
553     m_process->addExistingWebPage(this, m_pageID);
554     m_process->addMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID, *this);
555
556     updateViewState();
557     updateActivityToken();
558
559 #if ENABLE(INSPECTOR)
560     m_inspector = WebInspectorProxy::create(this);
561 #endif
562 #if ENABLE(FULLSCREEN_API)
563     m_fullScreenManager = WebFullScreenManagerProxy::create(*this, m_pageClient.fullScreenManagerProxyClient());
564 #endif
565 #if PLATFORM(IOS)
566     m_videoFullscreenManager = WebVideoFullscreenManagerProxy::create(*this);
567 #endif
568
569     initializeWebPage();
570
571     m_pageClient.didRelaunchProcess();
572     m_drawingArea->waitForBackingStoreUpdateOnNextPaint();
573 }
574
575 uint64_t WebPageProxy::reattachToWebProcessWithItem(WebBackForwardListItem* item)
576 {
577     if (m_isClosed)
578         return 0;
579
580     if (item && item != m_backForwardList->currentItem())
581         m_backForwardList->goToItem(item);
582     
583     reattachToWebProcess();
584
585     if (!item)
586         return 0;
587
588     uint64_t navigationID = generateNavigationID();
589
590     m_process->send(Messages::WebPage::GoToBackForwardItem(navigationID, item->itemID()), m_pageID);
591     m_process->responsivenessTimer()->start();
592
593     return navigationID;
594 }
595
596 void WebPageProxy::setSession(API::Session& session)
597 {
598     m_session = session;
599     m_process->send(Messages::WebPage::SetSessionID(session.getID()), m_pageID);
600
601 #if ENABLE(NETWORK_PROCESS)
602     if (session.isEphemeral())
603         m_process->context().sendToNetworkingProcess(Messages::NetworkProcess::EnsurePrivateBrowsingSession(session.getID()));
604 #endif
605 }
606
607 void WebPageProxy::initializeWebPage()
608 {
609     ASSERT(isValid());
610
611     BackForwardListItemVector items = m_backForwardList->entries();
612     for (size_t i = 0; i < items.size(); ++i)
613         m_process->registerNewWebBackForwardListItem(items[i].get());
614
615     m_drawingArea = m_pageClient.createDrawingAreaProxy();
616     ASSERT(m_drawingArea);
617
618 #if ENABLE(ASYNC_SCROLLING)
619     if (m_drawingArea->type() == DrawingAreaTypeRemoteLayerTree) {
620         m_scrollingCoordinatorProxy = std::make_unique<RemoteScrollingCoordinatorProxy>(*this);
621 #if PLATFORM(IOS)
622         // On iOS, main frame scrolls are sent in terms of visible rect updates.
623         m_scrollingCoordinatorProxy->setPropagatesMainFrameScrolls(false);
624 #endif
625     }
626 #endif
627
628 #if ENABLE(INSPECTOR_SERVER)
629     if (pageGroup().preferences().developerExtrasEnabled())
630         inspector()->enableRemoteInspection();
631 #endif
632
633     process().send(Messages::WebProcess::CreateWebPage(m_pageID, creationParameters()), 0);
634
635 #if PLATFORM(COCOA)
636     send(Messages::WebPage::SetSmartInsertDeleteEnabled(m_isSmartInsertDeleteEnabled));
637 #endif
638 }
639
640 bool WebPageProxy::isProcessSuppressible() const
641 {
642     return (m_viewState & ViewState::IsVisuallyIdle) && m_preferences->pageVisibilityBasedProcessSuppressionEnabled();
643 }
644
645 void WebPageProxy::close()
646 {
647     if (!isValid())
648         return;
649
650     m_isClosed = true;
651
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());
656     }
657
658     m_backForwardList->pageClosed();
659     m_pageClient.pageClosed();
660
661     m_process->disconnectFramesFromPage(this);
662
663     resetState(ResetStateReason::PageInvalidated);
664
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>();
669 #if PLATFORM(EFL)
670     m_uiPopupMenuClient.initialize(0);
671 #endif
672     m_findClient = std::make_unique<API::FindClient>();
673     m_findMatchesClient.initialize(0);
674 #if ENABLE(CONTEXT_MENUS)
675     m_contextMenuClient.initialize(0);
676 #endif
677
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);
683 }
684
685 bool WebPageProxy::tryClose()
686 {
687     if (!isValid())
688         return true;
689
690     m_process->send(Messages::WebPage::TryClose(), m_pageID);
691     m_process->responsivenessTimer()->start();
692     return false;
693 }
694
695 bool WebPageProxy::maybeInitializeSandboxExtensionHandle(const URL& url, SandboxExtension::Handle& sandboxExtensionHandle)
696 {
697     if (!url.isLocalFile())
698         return false;
699
700     if (m_process->hasAssumedReadAccessToURL(url))
701         return false;
702
703 #if ENABLE(INSPECTOR)
704     // Inspector resources are in a directory with assumed access.
705     ASSERT_WITH_SECURITY_IMPLICATION(!WebInspectorProxy::isInspectorPage(*this));
706 #endif
707
708     SandboxExtension::createHandle("/", SandboxExtension::ReadOnly, sandboxExtensionHandle);
709     return true;
710 }
711
712 uint64_t WebPageProxy::loadRequest(const ResourceRequest& request, API::Object* userData)
713 {
714     if (m_isClosed)
715         return 0;
716
717     uint64_t navigationID = generateNavigationID();
718
719     auto transaction = m_pageLoadState.transaction();
720
721     m_pageLoadState.setPendingAPIRequestURL(transaction, request.url());
722
723     if (!isValid())
724         reattachToWebProcess();
725
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();
732
733     return navigationID;
734 }
735
736 void WebPageProxy::loadFile(const String& fileURLString, const String& resourceDirectoryURLString, API::Object* userData)
737 {
738     if (m_isClosed)
739         return;
740
741     if (!isValid())
742         reattachToWebProcess();
743
744     URL fileURL = URL(URL(), fileURLString);
745     if (!fileURL.isLocalFile())
746         return;
747
748     URL resourceDirectoryURL;
749     if (resourceDirectoryURLString.isNull())
750         resourceDirectoryURL = URL(ParsedURLString, ASCIILiteral("file:///"));
751     else {
752         resourceDirectoryURL = URL(URL(), resourceDirectoryURLString);
753         if (!resourceDirectoryURL.isLocalFile())
754             return;
755     }
756
757     String resourceDirectoryPath = resourceDirectoryURL.fileSystemPath();
758
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();
764 }
765
766 void WebPageProxy::loadData(API::Data* data, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData)
767 {
768     if (m_isClosed)
769         return;
770
771     if (!isValid())
772         reattachToWebProcess();
773
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();
777 }
778
779 uint64_t WebPageProxy::loadHTMLString(const String& htmlString, const String& baseURL, API::Object* userData)
780 {
781     if (m_isClosed)
782         return 0;
783
784     uint64_t navigationID = generateNavigationID();
785
786     auto transaction = m_pageLoadState.transaction();
787
788     String pendingAPIRequestURL = baseURL.isEmpty() ? baseURL : ASCIILiteral("about:blank");
789     m_pageLoadState.setPendingAPIRequestURL(transaction, pendingAPIRequestURL);
790
791     if (!isValid())
792         reattachToWebProcess();
793
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();
797
798     return navigationID;
799 }
800
801 void WebPageProxy::loadAlternateHTMLString(const String& htmlString, const String& baseURL, const String& unreachableURL, API::Object* userData)
802 {
803     if (m_isClosed)
804         return;
805
806     if (!isValid())
807         reattachToWebProcess();
808
809     auto transaction = m_pageLoadState.transaction();
810
811     m_pageLoadState.setUnreachableURL(transaction, unreachableURL);
812
813     if (m_mainFrame)
814         m_mainFrame->setUnreachableURL(unreachableURL);
815
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();
819 }
820
821 void WebPageProxy::loadPlainTextString(const String& string, API::Object* userData)
822 {
823     if (m_isClosed)
824         return;
825
826     if (!isValid())
827         reattachToWebProcess();
828
829     m_process->send(Messages::WebPage::LoadPlainTextString(string, WebContextUserMessageEncoder(userData, process())), m_pageID);
830     m_process->responsivenessTimer()->start();
831 }
832
833 void WebPageProxy::loadWebArchiveData(API::Data* webArchiveData, API::Object* userData)
834 {
835     if (m_isClosed)
836         return;
837
838     if (!isValid())
839         reattachToWebProcess();
840
841     m_process->send(Messages::WebPage::LoadWebArchiveData(webArchiveData->dataReference(), WebContextUserMessageEncoder(userData, process())), m_pageID);
842     m_process->responsivenessTimer()->start();
843 }
844
845 void WebPageProxy::stopLoading()
846 {
847     if (!isValid())
848         return;
849
850     m_process->send(Messages::WebPage::StopLoading(), m_pageID);
851     m_process->responsivenessTimer()->start();
852 }
853
854 uint64_t WebPageProxy::reload(bool reloadFromOrigin)
855 {
856     SandboxExtension::Handle sandboxExtensionHandle;
857
858     if (m_backForwardList->currentItem()) {
859         String url = m_backForwardList->currentItem()->url();
860         auto transaction = m_pageLoadState.transaction();
861         m_pageLoadState.setPendingAPIRequestURL(transaction, url);
862
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();
867     }
868
869     if (!isValid())
870         return reattachToWebProcessWithItem(m_backForwardList->currentItem());
871
872     uint64_t navigationID = generateNavigationID();
873
874     m_process->send(Messages::WebPage::Reload(navigationID, reloadFromOrigin, sandboxExtensionHandle), m_pageID);
875     m_process->responsivenessTimer()->start();
876
877     return navigationID;
878 }
879
880 void WebPageProxy::recordNavigationSnapshot()
881 {
882     if (!m_shouldRecordNavigationSnapshots)
883         return;
884
885 #if PLATFORM(COCOA)
886     ViewSnapshotStore::shared().recordSnapshot(*this);
887 #endif
888 }
889
890 uint64_t WebPageProxy::goForward()
891 {
892     WebBackForwardListItem* forwardItem = m_backForwardList->forwardItem();
893     if (!forwardItem)
894         return 0;
895
896     auto transaction = m_pageLoadState.transaction();
897
898     m_pageLoadState.setPendingAPIRequestURL(transaction, forwardItem->url());
899
900     if (!isValid())
901         return reattachToWebProcessWithItem(forwardItem);
902
903     uint64_t navigationID = m_backForwardList->currentItem()->itemIsInSameDocument(*forwardItem) ? 0 : generateNavigationID();
904
905     m_process->send(Messages::WebPage::GoForward(navigationID, forwardItem->itemID()), m_pageID);
906     m_process->responsivenessTimer()->start();
907
908     return navigationID;
909 }
910
911 uint64_t WebPageProxy::goBack()
912 {
913     WebBackForwardListItem* backItem = m_backForwardList->backItem();
914     if (!backItem)
915         return 0;
916
917     auto transaction = m_pageLoadState.transaction();
918
919     m_pageLoadState.setPendingAPIRequestURL(transaction, backItem->url());
920
921     if (!isValid())
922         return reattachToWebProcessWithItem(backItem);
923
924     uint64_t navigationID = m_backForwardList->currentItem()->itemIsInSameDocument(*backItem) ? 0 : generateNavigationID();
925
926     m_process->send(Messages::WebPage::GoBack(navigationID, backItem->itemID()), m_pageID);
927     m_process->responsivenessTimer()->start();
928
929     return navigationID;
930 }
931
932 uint64_t WebPageProxy::goToBackForwardItem(WebBackForwardListItem* item)
933 {
934     if (!isValid())
935         return reattachToWebProcessWithItem(item);
936
937     auto transaction = m_pageLoadState.transaction();
938
939     m_pageLoadState.setPendingAPIRequestURL(transaction, item->url());
940
941     uint64_t navigationID = m_backForwardList->currentItem()->itemIsInSameDocument(*item) ? 0 : generateNavigationID();
942
943     m_process->send(Messages::WebPage::GoToBackForwardItem(navigationID, item->itemID()), m_pageID);
944     m_process->responsivenessTimer()->start();
945
946     return navigationID;
947 }
948
949 void WebPageProxy::tryRestoreScrollPosition()
950 {
951     if (!isValid())
952         return;
953
954     m_process->send(Messages::WebPage::TryRestoreScrollPosition(), m_pageID);
955 }
956
957 void WebPageProxy::didChangeBackForwardList(WebBackForwardListItem* added, Vector<RefPtr<WebBackForwardListItem>> removed)
958 {
959     m_loaderClient->didChangeBackForwardList(this, added, WTF::move(removed));
960
961     auto transaction = m_pageLoadState.transaction();
962
963     m_pageLoadState.setCanGoBack(transaction, m_backForwardList->backItem());
964     m_pageLoadState.setCanGoForward(transaction, m_backForwardList->forwardItem());
965 }
966
967 void WebPageProxy::willGoToBackForwardListItem(uint64_t itemID, IPC::MessageDecoder& decoder)
968 {
969     RefPtr<API::Object> userData;
970     WebContextUserMessageDecoder messageDecoder(userData, process());
971     if (!decoder.decode(messageDecoder))
972         return;
973
974     if (WebBackForwardListItem* item = m_process->webBackForwardItem(itemID))
975         m_loaderClient->willGoToBackForwardListItem(this, item, userData.get());
976 }
977
978 bool WebPageProxy::shouldKeepCurrentBackForwardListItemInList(WebBackForwardListItem* item)
979 {
980     return m_loaderClient->shouldKeepCurrentBackForwardListItemInList(this, item);
981 }
982
983 bool WebPageProxy::canShowMIMEType(const String& mimeType)
984 {
985     if (MIMETypeRegistry::canShowMIMEType(mimeType))
986         return true;
987
988 #if ENABLE(NETSCAPE_PLUGIN_API)
989     String newMimeType = mimeType;
990     PluginModuleInfo plugin = m_process->context().pluginInfoStore().findPlugin(newMimeType, URL());
991     if (!plugin.path.isNull() && m_preferences->pluginsEnabled())
992         return true;
993 #endif // ENABLE(NETSCAPE_PLUGIN_API)
994
995 #if PLATFORM(COCOA)
996     // On Mac, we can show PDFs.
997     if (MIMETypeRegistry::isPDFOrPostScriptMIMEType(mimeType) && !WebContext::omitPDFSupport())
998         return true;
999 #endif // PLATFORM(COCOA)
1000
1001     return false;
1002 }
1003
1004 #if ENABLE(REMOTE_INSPECTOR)
1005 void WebPageProxy::setAllowsRemoteInspection(bool allow)
1006 {
1007     if (m_allowsRemoteInspection == allow)
1008         return;
1009
1010     m_allowsRemoteInspection = allow;
1011
1012     if (isValid())
1013         m_process->send(Messages::WebPage::SetAllowsRemoteInspection(allow), m_pageID);
1014 }
1015 #endif
1016
1017 void WebPageProxy::setDrawsBackground(bool drawsBackground)
1018 {
1019     if (m_drawsBackground == drawsBackground)
1020         return;
1021
1022     m_drawsBackground = drawsBackground;
1023
1024     if (isValid())
1025         m_process->send(Messages::WebPage::SetDrawsBackground(drawsBackground), m_pageID);
1026 }
1027
1028 void WebPageProxy::setDrawsTransparentBackground(bool drawsTransparentBackground)
1029 {
1030     if (m_drawsTransparentBackground == drawsTransparentBackground)
1031         return;
1032
1033     m_drawsTransparentBackground = drawsTransparentBackground;
1034
1035     if (isValid())
1036         m_process->send(Messages::WebPage::SetDrawsTransparentBackground(drawsTransparentBackground), m_pageID);
1037 }
1038
1039 void WebPageProxy::setTopContentInset(float contentInset)
1040 {
1041     if (m_topContentInset == contentInset)
1042         return;
1043
1044     m_topContentInset = contentInset;
1045
1046     if (isValid())
1047         m_process->send(Messages::WebPage::SetTopContentInset(contentInset), m_pageID);
1048 }
1049
1050 void WebPageProxy::setUnderlayColor(const Color& color)
1051 {
1052     if (m_underlayColor == color)
1053         return;
1054
1055     m_underlayColor = color;
1056
1057     if (isValid())
1058         m_process->send(Messages::WebPage::SetUnderlayColor(color), m_pageID);
1059 }
1060
1061 void WebPageProxy::viewWillStartLiveResize()
1062 {
1063     if (!isValid())
1064         return;
1065 #if ENABLE(INPUT_TYPE_COLOR_POPOVER)
1066     if (m_colorPicker)
1067         endColorPicker();
1068 #endif
1069     m_process->send(Messages::WebPage::ViewWillStartLiveResize(), m_pageID);
1070 }
1071
1072 void WebPageProxy::viewWillEndLiveResize()
1073 {
1074     if (!isValid())
1075         return;
1076     m_process->send(Messages::WebPage::ViewWillEndLiveResize(), m_pageID);
1077 }
1078
1079 void WebPageProxy::setViewNeedsDisplay(const IntRect& rect)
1080 {
1081     m_pageClient.setViewNeedsDisplay(rect);
1082 }
1083
1084 void WebPageProxy::displayView()
1085 {
1086     m_pageClient.displayView();
1087 }
1088
1089 bool WebPageProxy::canScrollView()
1090 {
1091     return m_pageClient.canScrollView();
1092 }
1093
1094 void WebPageProxy::scrollView(const IntRect& scrollRect, const IntSize& scrollOffset)
1095 {
1096     m_pageClient.scrollView(scrollRect, scrollOffset);
1097 }
1098
1099 void WebPageProxy::requestScroll(const FloatPoint& scrollPosition, bool isProgrammaticScroll)
1100 {
1101     m_pageClient.requestScroll(scrollPosition, isProgrammaticScroll);
1102 }
1103
1104 void WebPageProxy::updateViewState(ViewState::Flags flagsToUpdate)
1105 {
1106     m_viewState &= ~flagsToUpdate;
1107     if (flagsToUpdate & ViewState::IsFocused && m_pageClient.isViewFocused())
1108         m_viewState |= ViewState::IsFocused;
1109     if (flagsToUpdate & ViewState::WindowIsActive && m_pageClient.isViewWindowActive())
1110         m_viewState |= ViewState::WindowIsActive;
1111     if (flagsToUpdate & ViewState::IsVisible && m_pageClient.isViewVisible())
1112         m_viewState |= ViewState::IsVisible;
1113     if (flagsToUpdate & ViewState::IsVisibleOrOccluded && m_pageClient.isViewVisibleOrOccluded())
1114         m_viewState |= ViewState::IsVisibleOrOccluded;
1115     if (flagsToUpdate & ViewState::IsInWindow && m_pageClient.isViewInWindow()) {
1116         m_viewState |= ViewState::IsInWindow;
1117         m_viewWasEverInWindow = true;
1118     }
1119     if (flagsToUpdate & ViewState::IsVisuallyIdle && m_pageClient.isVisuallyIdle())
1120         m_viewState |= ViewState::IsVisuallyIdle;
1121 }
1122
1123 void WebPageProxy::viewStateDidChange(ViewState::Flags mayHaveChanged, bool wantsReply, ViewStateChangeDispatchMode dispatchMode)
1124 {
1125     m_potentiallyChangedViewStateFlags |= mayHaveChanged;
1126     m_viewStateChangeWantsReply = m_viewStateChangeWantsReply || wantsReply;
1127
1128 #if PLATFORM(COCOA)
1129     bool isNewlyInWindow = !isInWindow() && (mayHaveChanged & ViewState::IsInWindow) && m_pageClient.isViewInWindow();
1130     if (dispatchMode == ViewStateChangeDispatchMode::Immediate || isNewlyInWindow) {
1131         dispatchViewStateChange();
1132         return;
1133     }
1134     m_viewStateChangeDispatcher->schedule();
1135 #else
1136     UNUSED_PARAM(dispatchMode);
1137     dispatchViewStateChange();
1138 #endif
1139 }
1140
1141 void WebPageProxy::viewDidLeaveWindow()
1142 {
1143 #if ENABLE(INPUT_TYPE_COLOR_POPOVER)
1144     // When leaving the current page, close the popover color well.
1145     if (m_colorPicker)
1146         endColorPicker();
1147 #endif
1148 #if PLATFORM(IOS)
1149     // When leaving the current page, close the video fullscreen.
1150     if (m_videoFullscreenManager)
1151         m_videoFullscreenManager->requestHideAndExitFullscreen();
1152 #endif
1153 }
1154
1155 void WebPageProxy::viewDidEnterWindow()
1156 {
1157     LayerHostingMode layerHostingMode = m_pageClient.viewLayerHostingMode();
1158     if (m_layerHostingMode != layerHostingMode) {
1159         m_layerHostingMode = layerHostingMode;
1160         m_process->send(Messages::WebPage::SetLayerHostingMode(static_cast<unsigned>(layerHostingMode)), m_pageID);
1161     }
1162 }
1163
1164 void WebPageProxy::dispatchViewStateChange()
1165 {
1166 #if PLATFORM(COCOA)
1167     m_viewStateChangeDispatcher->invalidate();
1168 #endif
1169
1170     if (!isValid())
1171         return;
1172
1173     // If the visibility state may have changed, then so may the visually idle & occluded agnostic state.
1174     if (m_potentiallyChangedViewStateFlags & ViewState::IsVisible)
1175         m_potentiallyChangedViewStateFlags |= ViewState::IsVisibleOrOccluded | ViewState::IsVisuallyIdle;
1176
1177     // Record the prior view state, update the flags that may have changed,
1178     // and check which flags have actually changed.
1179     ViewState::Flags previousViewState = m_viewState;
1180     updateViewState(m_potentiallyChangedViewStateFlags);
1181     ViewState::Flags changed = m_viewState ^ previousViewState;
1182
1183     // We always want to wait for the Web process to reply if we've been in-window before and are coming back in-window.
1184     if (m_viewWasEverInWindow && (changed & ViewState::IsInWindow) && isInWindow())
1185         m_viewStateChangeWantsReply = true;
1186
1187     if (changed || m_viewStateChangeWantsReply)
1188         m_process->send(Messages::WebPage::SetViewState(m_viewState, m_viewStateChangeWantsReply), m_pageID);
1189
1190     // This must happen after the SetViewState message is sent, to ensure the page visibility event can fire.
1191     updateActivityToken();
1192
1193     if (changed & ViewState::IsVisuallyIdle)
1194         m_process->pageSuppressibilityChanged(this);
1195
1196     // If we've started the responsiveness timer as part of telling the web process to update the backing store
1197     // state, it might not send back a reply (since it won't paint anything if the web page is hidden) so we
1198     // stop the unresponsiveness timer here.
1199     if ((changed & ViewState::IsVisible) && !isViewVisible())
1200         m_process->responsivenessTimer()->stop();
1201
1202     if (changed & ViewState::IsInWindow) {
1203         if (isInWindow())
1204             viewDidEnterWindow();
1205         else
1206             viewDidLeaveWindow();
1207     }
1208
1209     updateBackingStoreDiscardableState();
1210
1211     if (m_viewStateChangeWantsReply)
1212         waitForDidUpdateViewState();
1213
1214     m_potentiallyChangedViewStateFlags = ViewState::NoFlags;
1215     m_viewStateChangeWantsReply = false;
1216 }
1217
1218 void WebPageProxy::updateActivityToken()
1219 {
1220 #if PLATFORM(IOS)
1221     if (!isViewVisible())
1222         m_activityToken = nullptr;
1223     else if (!m_activityToken)
1224         m_activityToken = std::make_unique<ProcessThrottler::ForegroundActivityToken>(m_process->throttler());
1225 #endif
1226 }
1227
1228 void WebPageProxy::layerHostingModeDidChange()
1229 {
1230     if (!isValid())
1231         return;
1232
1233     LayerHostingMode layerHostingMode = m_pageClient.viewLayerHostingMode();
1234     if (m_layerHostingMode == layerHostingMode)
1235         return;
1236
1237     m_layerHostingMode = layerHostingMode;
1238     m_process->send(Messages::WebPage::SetLayerHostingMode(static_cast<unsigned>(layerHostingMode)), m_pageID);
1239 }
1240
1241 void WebPageProxy::waitForDidUpdateViewState()
1242 {
1243     if (!isValid())
1244         return;
1245
1246     if (m_process->state() != WebProcessProxy::State::Running)
1247         return;
1248
1249     // If we have previously timed out with no response from the WebProcess, don't block the UIProcess again until it starts responding.
1250     if (m_waitingForDidUpdateViewState)
1251         return;
1252
1253     m_waitingForDidUpdateViewState = true;
1254
1255     m_drawingArea->waitForDidUpdateViewState();
1256 }
1257
1258 IntSize WebPageProxy::viewSize() const
1259 {
1260     return m_pageClient.viewSize();
1261 }
1262
1263 void WebPageProxy::setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent& keyboardEvent)
1264 {
1265     if (!isValid())
1266         return;
1267     m_process->send(Messages::WebPage::SetInitialFocus(forward, isKeyboardEventValid, keyboardEvent), m_pageID);
1268 }
1269
1270 void WebPageProxy::setWindowResizerSize(const IntSize& windowResizerSize)
1271 {
1272     if (!isValid())
1273         return;
1274     m_process->send(Messages::WebPage::SetWindowResizerSize(windowResizerSize), m_pageID);
1275 }
1276     
1277 void WebPageProxy::clearSelection()
1278 {
1279     if (!isValid())
1280         return;
1281     m_process->send(Messages::WebPage::ClearSelection(), m_pageID);
1282 }
1283
1284 void WebPageProxy::validateCommand(const String& commandName, std::function<void (const String&, bool, int32_t, CallbackBase::Error)> callbackFunction)
1285 {
1286     if (!isValid()) {
1287         callbackFunction(String(), false, 0, CallbackBase::Error::Unknown);
1288         return;
1289     }
1290
1291     uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), std::make_unique<ProcessThrottler::BackgroundActivityToken>(m_process->throttler()));
1292     m_process->send(Messages::WebPage::ValidateCommand(commandName, callbackID), m_pageID);
1293 }
1294
1295 void WebPageProxy::setMaintainsInactiveSelection(bool newValue)
1296 {
1297     m_maintainsInactiveSelection = newValue;
1298 }
1299     
1300 void WebPageProxy::executeEditCommand(const String& commandName)
1301 {
1302     static NeverDestroyed<String> ignoreSpellingCommandName(ASCIILiteral("ignoreSpelling"));
1303
1304     if (!isValid())
1305         return;
1306
1307     if (commandName == ignoreSpellingCommandName)
1308         ++m_pendingLearnOrIgnoreWordMessageCount;
1309
1310     m_process->send(Messages::WebPage::ExecuteEditCommand(commandName), m_pageID);
1311 }
1312
1313 #if !PLATFORM(IOS)
1314 void WebPageProxy::didCommitLayerTree(const RemoteLayerTreeTransaction&)
1315 {
1316 }
1317 #endif
1318
1319 #if USE(TILED_BACKING_STORE)
1320 void WebPageProxy::commitPageTransitionViewport()
1321 {
1322     if (!isValid())
1323         return;
1324
1325     process().send(Messages::WebPage::CommitPageTransitionViewport(), m_pageID);
1326 }
1327 #endif
1328
1329 #if ENABLE(DRAG_SUPPORT)
1330 void WebPageProxy::dragEntered(DragData& dragData, const String& dragStorageName)
1331 {
1332     SandboxExtension::Handle sandboxExtensionHandle;
1333     SandboxExtension::HandleArray sandboxExtensionHandleEmptyArray;
1334     performDragControllerAction(DragControllerActionEntered, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionHandleEmptyArray);
1335 }
1336
1337 void WebPageProxy::dragUpdated(DragData& dragData, const String& dragStorageName)
1338 {
1339     SandboxExtension::Handle sandboxExtensionHandle;
1340     SandboxExtension::HandleArray sandboxExtensionHandleEmptyArray;
1341     performDragControllerAction(DragControllerActionUpdated, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionHandleEmptyArray);
1342 }
1343
1344 void WebPageProxy::dragExited(DragData& dragData, const String& dragStorageName)
1345 {
1346     SandboxExtension::Handle sandboxExtensionHandle;
1347     SandboxExtension::HandleArray sandboxExtensionHandleEmptyArray;
1348     performDragControllerAction(DragControllerActionExited, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionHandleEmptyArray);
1349 }
1350
1351 void WebPageProxy::performDragOperation(DragData& dragData, const String& dragStorageName, const SandboxExtension::Handle& sandboxExtensionHandle, const SandboxExtension::HandleArray& sandboxExtensionsForUpload)
1352 {
1353     performDragControllerAction(DragControllerActionPerformDragOperation, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionsForUpload);
1354 }
1355
1356 void WebPageProxy::performDragControllerAction(DragControllerAction action, DragData& dragData, const String& dragStorageName, const SandboxExtension::Handle& sandboxExtensionHandle, const SandboxExtension::HandleArray& sandboxExtensionsForUpload)
1357 {
1358     if (!isValid())
1359         return;
1360 #if PLATFORM(GTK)
1361     UNUSED_PARAM(dragStorageName);
1362     UNUSED_PARAM(sandboxExtensionHandle);
1363     UNUSED_PARAM(sandboxExtensionsForUpload);
1364     m_process->send(Messages::WebPage::PerformDragControllerAction(action, dragData), m_pageID);
1365 #else
1366     m_process->send(Messages::WebPage::PerformDragControllerAction(action, dragData.clientPosition(), dragData.globalPosition(), dragData.draggingSourceOperationMask(), dragStorageName, dragData.flags(), sandboxExtensionHandle, sandboxExtensionsForUpload), m_pageID);
1367 #endif
1368 }
1369
1370 void WebPageProxy::didPerformDragControllerAction(uint64_t dragOperation, bool mouseIsOverFileInput, unsigned numberOfItemsToBeAccepted)
1371 {
1372     MESSAGE_CHECK(dragOperation <= DragOperationDelete);
1373
1374     m_currentDragOperation = static_cast<DragOperation>(dragOperation);
1375     m_currentDragIsOverFileInput = mouseIsOverFileInput;
1376     m_currentDragNumberOfFilesToBeAccepted = numberOfItemsToBeAccepted;
1377 }
1378
1379 #if PLATFORM(GTK)
1380 void WebPageProxy::startDrag(const DragData& dragData, const ShareableBitmap::Handle& dragImageHandle)
1381 {
1382     RefPtr<ShareableBitmap> dragImage = 0;
1383     if (!dragImageHandle.isNull()) {
1384         dragImage = ShareableBitmap::create(dragImageHandle);
1385         if (!dragImage)
1386             return;
1387     }
1388
1389     m_pageClient.startDrag(dragData, dragImage.release());
1390 }
1391 #endif
1392
1393 void WebPageProxy::dragEnded(const IntPoint& clientPosition, const IntPoint& globalPosition, uint64_t operation)
1394 {
1395     if (!isValid())
1396         return;
1397     m_process->send(Messages::WebPage::DragEnded(clientPosition, globalPosition, operation), m_pageID);
1398 }
1399 #endif // ENABLE(DRAG_SUPPORT)
1400
1401 void WebPageProxy::handleMouseEvent(const NativeWebMouseEvent& event)
1402 {
1403     if (!isValid())
1404         return;
1405
1406     // NOTE: This does not start the responsiveness timer because mouse move should not indicate interaction.
1407     if (event.type() != WebEvent::MouseMove)
1408         m_process->responsivenessTimer()->start();
1409     else {
1410         if (m_processingMouseMoveEvent) {
1411             m_nextMouseMoveEvent = std::make_unique<NativeWebMouseEvent>(event);
1412             return;
1413         }
1414
1415         m_processingMouseMoveEvent = true;
1416     }
1417
1418     // <https://bugs.webkit.org/show_bug.cgi?id=57904> We need to keep track of the mouse down event in the case where we
1419     // display a popup menu for select elements. When the user changes the selected item,
1420     // we fake a mouse up event by using this stored down event. This event gets cleared
1421     // when the mouse up message is received from WebProcess.
1422     if (event.type() == WebEvent::MouseDown)
1423         m_currentlyProcessedMouseDownEvent = std::make_unique<NativeWebMouseEvent>(event);
1424
1425     if (m_shouldSendEventsSynchronously) {
1426         bool handled = false;
1427         m_process->sendSync(Messages::WebPage::MouseEventSyncForTesting(event), Messages::WebPage::MouseEventSyncForTesting::Reply(handled), m_pageID);
1428         didReceiveEvent(event.type(), handled);
1429     } else
1430         m_process->send(Messages::WebPage::MouseEvent(event), m_pageID);
1431 }
1432
1433 #if MERGE_WHEEL_EVENTS
1434 static bool canCoalesce(const WebWheelEvent& a, const WebWheelEvent& b)
1435 {
1436     if (a.position() != b.position())
1437         return false;
1438     if (a.globalPosition() != b.globalPosition())
1439         return false;
1440     if (a.modifiers() != b.modifiers())
1441         return false;
1442     if (a.granularity() != b.granularity())
1443         return false;
1444 #if PLATFORM(COCOA)
1445     if (a.phase() != b.phase())
1446         return false;
1447     if (a.momentumPhase() != b.momentumPhase())
1448         return false;
1449     if (a.hasPreciseScrollingDeltas() != b.hasPreciseScrollingDeltas())
1450         return false;
1451 #endif
1452
1453     return true;
1454 }
1455
1456 static WebWheelEvent coalesce(const WebWheelEvent& a, const WebWheelEvent& b)
1457 {
1458     ASSERT(canCoalesce(a, b));
1459
1460     FloatSize mergedDelta = a.delta() + b.delta();
1461     FloatSize mergedWheelTicks = a.wheelTicks() + b.wheelTicks();
1462
1463 #if PLATFORM(COCOA)
1464     FloatSize mergedUnacceleratedScrollingDelta = a.unacceleratedScrollingDelta() + b.unacceleratedScrollingDelta();
1465
1466     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());
1467 #else
1468     return WebWheelEvent(WebEvent::Wheel, b.position(), b.globalPosition(), mergedDelta, mergedWheelTicks, b.granularity(), b.modifiers(), b.timestamp());
1469 #endif
1470 }
1471 #endif // MERGE_WHEEL_EVENTS
1472
1473 static WebWheelEvent coalescedWheelEvent(Deque<NativeWebWheelEvent>& queue, Vector<NativeWebWheelEvent>& coalescedEvents)
1474 {
1475     ASSERT(!queue.isEmpty());
1476     ASSERT(coalescedEvents.isEmpty());
1477
1478 #if MERGE_WHEEL_EVENTS
1479     NativeWebWheelEvent firstEvent = queue.takeFirst();
1480     coalescedEvents.append(firstEvent);
1481
1482     WebWheelEvent event = firstEvent;
1483     while (!queue.isEmpty() && canCoalesce(event, queue.first())) {
1484         NativeWebWheelEvent firstEvent = queue.takeFirst();
1485         coalescedEvents.append(firstEvent);
1486         event = coalesce(event, firstEvent);
1487     }
1488
1489     return event;
1490 #else
1491     while (!queue.isEmpty())
1492         coalescedEvents.append(queue.takeFirst());
1493     return coalescedEvents.last();
1494 #endif
1495 }
1496
1497 void WebPageProxy::handleWheelEvent(const NativeWebWheelEvent& event)
1498 {
1499 #if ENABLE(ASYNC_SCROLLING)
1500     if (m_scrollingCoordinatorProxy && m_scrollingCoordinatorProxy->handleWheelEvent(platform(event)))
1501         return;
1502 #endif
1503
1504     if (!isValid())
1505         return;
1506
1507     if (!m_currentlyProcessedWheelEvents.isEmpty()) {
1508         m_wheelEventQueue.append(event);
1509         if (m_wheelEventQueue.size() < wheelEventQueueSizeThreshold)
1510             return;
1511         // The queue has too many wheel events, so push a new event.
1512     }
1513
1514     if (!m_wheelEventQueue.isEmpty()) {
1515         processNextQueuedWheelEvent();
1516         return;
1517     }
1518
1519     auto coalescedWheelEvent = std::make_unique<Vector<NativeWebWheelEvent>>();
1520     coalescedWheelEvent->append(event);
1521     m_currentlyProcessedWheelEvents.append(WTF::move(coalescedWheelEvent));
1522     sendWheelEvent(event);
1523 }
1524
1525 void WebPageProxy::processNextQueuedWheelEvent()
1526 {
1527     auto nextCoalescedEvent = std::make_unique<Vector<NativeWebWheelEvent>>();
1528     WebWheelEvent nextWheelEvent = coalescedWheelEvent(m_wheelEventQueue, *nextCoalescedEvent.get());
1529     m_currentlyProcessedWheelEvents.append(WTF::move(nextCoalescedEvent));
1530     sendWheelEvent(nextWheelEvent);
1531 }
1532
1533 void WebPageProxy::sendWheelEvent(const WebWheelEvent& event)
1534 {
1535     m_process->responsivenessTimer()->start();
1536
1537     if (m_shouldSendEventsSynchronously) {
1538         bool handled = false;
1539         m_process->sendSync(Messages::WebPage::WheelEventSyncForTesting(event), Messages::WebPage::WheelEventSyncForTesting::Reply(handled), m_pageID);
1540         didReceiveEvent(event.type(), handled);
1541         return;
1542     }
1543
1544     m_process->send(
1545         Messages::EventDispatcher::WheelEvent(
1546             m_pageID,
1547             event,
1548             shouldUseImplicitRubberBandControl() ? !m_backForwardList->backItem() : rubberBandsAtLeft(),
1549             shouldUseImplicitRubberBandControl() ? !m_backForwardList->forwardItem() : rubberBandsAtRight(),
1550             rubberBandsAtTop(),
1551             rubberBandsAtBottom()
1552         ), 0);
1553 }
1554
1555 void WebPageProxy::handleKeyboardEvent(const NativeWebKeyboardEvent& event)
1556 {
1557     if (!isValid())
1558         return;
1559     
1560     LOG(KeyHandling, "WebPageProxy::handleKeyboardEvent: %s", webKeyboardEventTypeString(event.type()));
1561
1562     m_keyEventQueue.append(event);
1563
1564     m_process->responsivenessTimer()->start();
1565     if (m_shouldSendEventsSynchronously) {
1566         bool handled = false;
1567         m_process->sendSync(Messages::WebPage::KeyEventSyncForTesting(event), Messages::WebPage::KeyEventSyncForTesting::Reply(handled), m_pageID);
1568         didReceiveEvent(event.type(), handled);
1569     } else if (m_keyEventQueue.size() == 1) // Otherwise, sent from DidReceiveEvent message handler.
1570         m_process->send(Messages::WebPage::KeyEvent(event), m_pageID);
1571 }
1572
1573 uint64_t WebPageProxy::generateNavigationID()
1574 {
1575     return ++m_navigationID;
1576 }
1577
1578 WebPreferencesStore WebPageProxy::preferencesStore() const
1579 {
1580     if (m_configurationPreferenceValues.isEmpty())
1581         return m_preferences->store();
1582
1583     WebPreferencesStore store = m_preferences->store();
1584     for (const auto& preference : m_configurationPreferenceValues)
1585         store.m_values.set(preference.key, preference.value);
1586
1587     return store;
1588 }
1589
1590 #if ENABLE(NETSCAPE_PLUGIN_API)
1591 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)
1592 {
1593     MESSAGE_CHECK_URL(urlString);
1594
1595     newMimeType = mimeType.lower();
1596     pluginLoadPolicy = PluginModuleLoadNormally;
1597
1598     PluginData::AllowedPluginTypes allowedPluginTypes = allowOnlyApplicationPlugins ? PluginData::OnlyApplicationPlugins : PluginData::AllPlugins;
1599     PluginModuleInfo plugin = m_process->context().pluginInfoStore().findPlugin(newMimeType, URL(URL(), urlString), allowedPluginTypes);
1600     if (!plugin.path) {
1601         pluginProcessToken = 0;
1602         return;
1603     }
1604
1605     pluginLoadPolicy = PluginInfoStore::defaultLoadPolicyForPlugin(plugin);
1606
1607 #if PLATFORM(COCOA)
1608     RefPtr<ImmutableDictionary> pluginInformation = createPluginInformationDictionary(plugin, frameURLString, String(), pageURLString, String(), String());
1609     pluginLoadPolicy = m_loaderClient->pluginLoadPolicy(this, static_cast<PluginModuleLoadPolicy>(pluginLoadPolicy), pluginInformation.get(), unavailabilityDescription);
1610 #else
1611     UNUSED_PARAM(frameURLString);
1612     UNUSED_PARAM(pageURLString);
1613     UNUSED_PARAM(unavailabilityDescription);
1614 #endif
1615
1616     PluginProcessSandboxPolicy pluginProcessSandboxPolicy = PluginProcessSandboxPolicyNormal;
1617     switch (pluginLoadPolicy) {
1618     case PluginModuleLoadNormally:
1619         pluginProcessSandboxPolicy = PluginProcessSandboxPolicyNormal;
1620         break;
1621     case PluginModuleLoadUnsandboxed:
1622         pluginProcessSandboxPolicy = PluginProcessSandboxPolicyUnsandboxed;
1623         break;
1624
1625     case PluginModuleBlocked:
1626         pluginProcessToken = 0;
1627         return;
1628     }
1629
1630     pluginProcessToken = PluginProcessManager::shared().pluginProcessToken(plugin, static_cast<PluginProcessType>(processType), pluginProcessSandboxPolicy);
1631 }
1632
1633 #endif // ENABLE(NETSCAPE_PLUGIN_API)
1634
1635 #if ENABLE(TOUCH_EVENTS)
1636
1637 bool WebPageProxy::shouldStartTrackingTouchEvents(const WebTouchEvent& touchStartEvent) const
1638 {
1639 #if ENABLE(ASYNC_SCROLLING)
1640     for (auto& touchPoint : touchStartEvent.touchPoints()) {
1641         if (m_scrollingCoordinatorProxy->isPointInNonFastScrollableRegion(touchPoint.location()))
1642             return true;
1643     }
1644
1645     return false;
1646 #else
1647     UNUSED_PARAM(touchStartEvent);
1648 #endif // ENABLE(ASYNC_SCROLLING)
1649     return true;
1650 }
1651
1652 #endif
1653
1654 #if ENABLE(IOS_TOUCH_EVENTS)
1655 void WebPageProxy::handleTouchEventSynchronously(const NativeWebTouchEvent& event)
1656 {
1657     if (!isValid())
1658         return;
1659
1660     if (event.type() == WebEvent::TouchStart)
1661         m_isTrackingTouchEvents = shouldStartTrackingTouchEvents(event);
1662
1663     if (!m_isTrackingTouchEvents)
1664         return;
1665
1666     m_process->responsivenessTimer()->start();
1667     bool handled = false;
1668     m_process->sendSync(Messages::WebPage::TouchEventSync(event), Messages::WebPage::TouchEventSync::Reply(handled), m_pageID);
1669     didReceiveEvent(event.type(), handled);
1670     m_pageClient.doneWithTouchEvent(event, handled);
1671     m_process->responsivenessTimer()->stop();
1672
1673     if (event.allTouchPointsAreReleased())
1674         m_isTrackingTouchEvents = false;
1675 }
1676
1677 void WebPageProxy::handleTouchEventAsynchronously(const NativeWebTouchEvent& event)
1678 {
1679     if (!isValid())
1680         return;
1681
1682     if (!m_isTrackingTouchEvents)
1683         return;
1684
1685     m_process->send(Messages::EventDispatcher::TouchEvent(m_pageID, event), 0);
1686
1687     if (event.allTouchPointsAreReleased())
1688         m_isTrackingTouchEvents = false;
1689 }
1690
1691 #elif ENABLE(TOUCH_EVENTS)
1692 void WebPageProxy::handleTouchEvent(const NativeWebTouchEvent& event)
1693 {
1694     if (!isValid())
1695         return;
1696
1697     if (event.type() == WebEvent::TouchStart)
1698         m_isTrackingTouchEvents = shouldStartTrackingTouchEvents(event);
1699
1700     if (!m_isTrackingTouchEvents)
1701         return;
1702
1703     // If the page is suspended, which should be the case during panning, pinching
1704     // and animation on the page itself (kinetic scrolling, tap to zoom) etc, then
1705     // we do not send any of the events to the page even if is has listeners.
1706     if (!m_isPageSuspended) {
1707         m_touchEventQueue.append(event);
1708         m_process->responsivenessTimer()->start();
1709         if (m_shouldSendEventsSynchronously) {
1710             bool handled = false;
1711             m_process->sendSync(Messages::WebPage::TouchEventSyncForTesting(event), Messages::WebPage::TouchEventSyncForTesting::Reply(handled), m_pageID);
1712             didReceiveEvent(event.type(), handled);
1713         } else
1714             m_process->send(Messages::WebPage::TouchEvent(event), m_pageID);
1715     } else {
1716         if (m_touchEventQueue.isEmpty()) {
1717             bool isEventHandled = false;
1718             m_pageClient.doneWithTouchEvent(event, isEventHandled);
1719         } else {
1720             // We attach the incoming events to the newest queued event so that all
1721             // the events are delivered in the correct order when the event is dequed.
1722             QueuedTouchEvents& lastEvent = m_touchEventQueue.last();
1723             lastEvent.deferredTouchEvents.append(event);
1724         }
1725     }
1726
1727     if (event.allTouchPointsAreReleased())
1728         m_isTrackingTouchEvents = false;
1729 }
1730 #endif // ENABLE(TOUCH_EVENTS)
1731
1732 void WebPageProxy::scrollBy(ScrollDirection direction, ScrollGranularity granularity)
1733 {
1734     if (!isValid())
1735         return;
1736
1737     m_process->send(Messages::WebPage::ScrollBy(direction, granularity), m_pageID);
1738 }
1739
1740 void WebPageProxy::centerSelectionInVisibleArea()
1741 {
1742     if (!isValid())
1743         return;
1744
1745     m_process->send(Messages::WebPage::CenterSelectionInVisibleArea(), m_pageID);
1746 }
1747
1748 void WebPageProxy::receivedPolicyDecision(PolicyAction action, WebFrameProxy* frame, uint64_t listenerID, uint64_t navigationID)
1749 {
1750     if (!isValid())
1751         return;
1752
1753     auto transaction = m_pageLoadState.transaction();
1754
1755     if (action == PolicyIgnore)
1756         m_pageLoadState.clearPendingAPIRequestURL(transaction);
1757
1758     uint64_t downloadID = 0;
1759     if (action == PolicyDownload) {
1760         // Create a download proxy.
1761         DownloadProxy* download = m_process->context().createDownloadProxy();
1762         downloadID = download->downloadID();
1763         handleDownloadRequest(download);
1764     }
1765
1766     // If we received a policy decision while in decidePolicyForResponse the decision will
1767     // be sent back to the web process by decidePolicyForResponse.
1768     if (m_inDecidePolicyForResponseSync) {
1769         m_syncMimeTypePolicyActionIsValid = true;
1770         m_syncMimeTypePolicyAction = action;
1771         m_syncMimeTypePolicyDownloadID = downloadID;
1772         return;
1773     }
1774
1775     // If we received a policy decision while in decidePolicyForNavigationAction the decision will 
1776     // be sent back to the web process by decidePolicyForNavigationAction. 
1777     if (m_inDecidePolicyForNavigationAction) {
1778         m_syncNavigationActionPolicyActionIsValid = true;
1779         m_syncNavigationActionPolicyAction = action;
1780         m_syncNavigationActionPolicyDownloadID = downloadID;
1781         return;
1782     }
1783     
1784     m_process->send(Messages::WebPage::DidReceivePolicyDecision(frame->frameID(), listenerID, action, navigationID, downloadID), m_pageID);
1785 }
1786
1787 void WebPageProxy::setUserAgent(const String& userAgent)
1788 {
1789     if (m_userAgent == userAgent)
1790         return;
1791     m_userAgent = userAgent;
1792
1793     if (!isValid())
1794         return;
1795     m_process->send(Messages::WebPage::SetUserAgent(m_userAgent), m_pageID);
1796 }
1797
1798 void WebPageProxy::setApplicationNameForUserAgent(const String& applicationName)
1799 {
1800     if (m_applicationNameForUserAgent == applicationName)
1801         return;
1802
1803     m_applicationNameForUserAgent = applicationName;
1804     if (!m_customUserAgent.isEmpty())
1805         return;
1806
1807     setUserAgent(standardUserAgent(m_applicationNameForUserAgent));
1808 }
1809
1810 void WebPageProxy::setCustomUserAgent(const String& customUserAgent)
1811 {
1812     if (m_customUserAgent == customUserAgent)
1813         return;
1814
1815     m_customUserAgent = customUserAgent;
1816
1817     if (m_customUserAgent.isEmpty()) {
1818         setUserAgent(standardUserAgent(m_applicationNameForUserAgent));
1819         return;
1820     }
1821
1822     setUserAgent(m_customUserAgent);
1823 }
1824
1825 void WebPageProxy::resumeActiveDOMObjectsAndAnimations()
1826 {
1827     if (!isValid() || !m_isPageSuspended)
1828         return;
1829
1830     m_isPageSuspended = false;
1831
1832     m_process->send(Messages::WebPage::ResumeActiveDOMObjectsAndAnimations(), m_pageID);
1833 }
1834
1835 void WebPageProxy::suspendActiveDOMObjectsAndAnimations()
1836 {
1837     if (!isValid() || m_isPageSuspended)
1838         return;
1839
1840     m_isPageSuspended = true;
1841
1842     m_process->send(Messages::WebPage::SuspendActiveDOMObjectsAndAnimations(), m_pageID);
1843 }
1844
1845 bool WebPageProxy::supportsTextEncoding() const
1846 {
1847     // FIXME (118840): We should probably only support this for text documents, not all non-image documents.
1848     return m_mainFrame && !m_mainFrame->isDisplayingStandaloneImageDocument();
1849 }
1850
1851 void WebPageProxy::setCustomTextEncodingName(const String& encodingName)
1852 {
1853     if (m_customTextEncodingName == encodingName)
1854         return;
1855     m_customTextEncodingName = encodingName;
1856
1857     if (!isValid())
1858         return;
1859     m_process->send(Messages::WebPage::SetCustomTextEncodingName(encodingName), m_pageID);
1860 }
1861
1862 void WebPageProxy::terminateProcess()
1863 {
1864     // NOTE: This uses a check of m_isValid rather than calling isValid() since
1865     // we want this to run even for pages being closed or that already closed.
1866     if (!m_isValid)
1867         return;
1868
1869     m_process->requestTermination();
1870     resetStateAfterProcessExited();
1871 }
1872
1873 SessionState WebPageProxy::sessionState(const std::function<bool (WebBackForwardListItem&)>& filter) const
1874 {
1875     SessionState sessionState;
1876
1877     sessionState.backForwardListState = m_backForwardList->backForwardListState(filter);
1878
1879     String provisionalURLString = m_pageLoadState.pendingAPIRequestURL();
1880     if (provisionalURLString.isEmpty())
1881         provisionalURLString = m_pageLoadState.provisionalURL();
1882
1883     if (!provisionalURLString.isEmpty())
1884         sessionState.provisionalURL = URL(URL(), provisionalURLString);
1885
1886     return sessionState;
1887 }
1888
1889 uint64_t WebPageProxy::restoreFromSessionState(SessionState sessionState, bool navigate)
1890 {
1891     bool hasBackForwardList = !!sessionState.backForwardListState.currentIndex;
1892
1893     if (hasBackForwardList) {
1894         m_backForwardList->restoreFromState(WTF::move(sessionState.backForwardListState));
1895
1896         for (const auto& entry : m_backForwardList->entries())
1897             process().registerNewWebBackForwardListItem(entry.get());
1898
1899         process().send(Messages::WebPage::RestoreSession(m_backForwardList->itemStates()), m_pageID);
1900     }
1901
1902     if (navigate) {
1903         // FIXME: Navigating should be separate from state restoration.
1904
1905         if (!sessionState.provisionalURL.isNull())
1906             return loadRequest(sessionState.provisionalURL);
1907
1908         if (hasBackForwardList) {
1909             // FIXME: Do we have to null check the back forward list item here?
1910             if (WebBackForwardListItem* item = m_backForwardList->currentItem())
1911                 return goToBackForwardItem(item);
1912         }
1913     }
1914
1915     return 0;
1916 }
1917
1918 bool WebPageProxy::supportsTextZoom() const
1919 {
1920     // FIXME (118840): This should also return false for standalone media and plug-in documents.
1921     if (!m_mainFrame || m_mainFrame->isDisplayingStandaloneImageDocument())
1922         return false;
1923
1924     return true;
1925 }
1926  
1927 void WebPageProxy::setTextZoomFactor(double zoomFactor)
1928 {
1929     if (!isValid())
1930         return;
1931
1932     if (m_textZoomFactor == zoomFactor)
1933         return;
1934
1935     m_textZoomFactor = zoomFactor;
1936     m_process->send(Messages::WebPage::SetTextZoomFactor(m_textZoomFactor), m_pageID); 
1937 }
1938
1939 void WebPageProxy::setPageZoomFactor(double zoomFactor)
1940 {
1941     if (!isValid())
1942         return;
1943
1944     if (m_pageZoomFactor == zoomFactor)
1945         return;
1946
1947     m_pageZoomFactor = zoomFactor;
1948     m_process->send(Messages::WebPage::SetPageZoomFactor(m_pageZoomFactor), m_pageID); 
1949 }
1950
1951 void WebPageProxy::setPageAndTextZoomFactors(double pageZoomFactor, double textZoomFactor)
1952 {
1953     if (!isValid())
1954         return;
1955
1956     if (m_pageZoomFactor == pageZoomFactor && m_textZoomFactor == textZoomFactor)
1957         return;
1958
1959     m_pageZoomFactor = pageZoomFactor;
1960     m_textZoomFactor = textZoomFactor;
1961     m_process->send(Messages::WebPage::SetPageAndTextZoomFactors(m_pageZoomFactor, m_textZoomFactor), m_pageID); 
1962 }
1963
1964 void WebPageProxy::scalePage(double scale, const IntPoint& origin)
1965 {
1966     if (!isValid())
1967         return;
1968
1969     m_pageScaleFactor = scale;
1970     m_process->send(Messages::WebPage::ScalePage(scale, origin), m_pageID);
1971 }
1972
1973 void WebPageProxy::scalePageInViewCoordinates(double scale, const IntPoint& centerInViewCoordinates)
1974 {
1975     if (!isValid())
1976         return;
1977
1978     m_pageScaleFactor = scale;
1979     m_process->send(Messages::WebPage::ScalePageInViewCoordinates(scale, centerInViewCoordinates), m_pageID);
1980 }
1981
1982 void WebPageProxy::setIntrinsicDeviceScaleFactor(float scaleFactor)
1983 {
1984     if (m_intrinsicDeviceScaleFactor == scaleFactor)
1985         return;
1986
1987     m_intrinsicDeviceScaleFactor = scaleFactor;
1988
1989     if (m_drawingArea)
1990         m_drawingArea->deviceScaleFactorDidChange();
1991 }
1992
1993 void WebPageProxy::windowScreenDidChange(PlatformDisplayID displayID)
1994 {
1995     if (!isValid())
1996         return;
1997
1998     m_process->send(Messages::WebPage::WindowScreenDidChange(displayID), m_pageID);
1999 }
2000
2001 float WebPageProxy::deviceScaleFactor() const
2002 {
2003     if (m_customDeviceScaleFactor)
2004         return m_customDeviceScaleFactor;
2005     return m_intrinsicDeviceScaleFactor;
2006 }
2007
2008 void WebPageProxy::setCustomDeviceScaleFactor(float customScaleFactor)
2009 {
2010     if (!isValid())
2011         return;
2012
2013     // FIXME: Remove this once we bump cairo requirements to support HiDPI.
2014     // https://bugs.webkit.org/show_bug.cgi?id=133378
2015 #if USE(CAIRO) && !HAVE(CAIRO_SURFACE_SET_DEVICE_SCALE)
2016     return;
2017 #endif
2018
2019     if (m_customDeviceScaleFactor == customScaleFactor)
2020         return;
2021
2022     float oldScaleFactor = deviceScaleFactor();
2023
2024     m_customDeviceScaleFactor = customScaleFactor;
2025
2026     if (deviceScaleFactor() != oldScaleFactor)
2027         m_drawingArea->deviceScaleFactorDidChange();
2028 }
2029
2030 void WebPageProxy::setUseFixedLayout(bool fixed)
2031 {
2032     if (!isValid())
2033         return;
2034
2035     // This check is fine as the value is initialized in the web
2036     // process as part of the creation parameters.
2037     if (fixed == m_useFixedLayout)
2038         return;
2039
2040     m_useFixedLayout = fixed;
2041     if (!fixed)
2042         m_fixedLayoutSize = IntSize();
2043     m_process->send(Messages::WebPage::SetUseFixedLayout(fixed), m_pageID);
2044 }
2045
2046 void WebPageProxy::setFixedLayoutSize(const IntSize& size)
2047 {
2048     if (!isValid())
2049         return;
2050
2051     if (size == m_fixedLayoutSize)
2052         return;
2053
2054     m_fixedLayoutSize = size;
2055     m_process->send(Messages::WebPage::SetFixedLayoutSize(size), m_pageID);
2056 }
2057
2058 void WebPageProxy::listenForLayoutMilestones(WebCore::LayoutMilestones milestones)
2059 {
2060     if (!isValid())
2061         return;
2062
2063     m_process->send(Messages::WebPage::ListenForLayoutMilestones(milestones), m_pageID);
2064 }
2065
2066 void WebPageProxy::setSuppressScrollbarAnimations(bool suppressAnimations)
2067 {
2068     if (!isValid())
2069         return;
2070
2071     if (suppressAnimations == m_suppressScrollbarAnimations)
2072         return;
2073
2074     m_suppressScrollbarAnimations = suppressAnimations;
2075     m_process->send(Messages::WebPage::SetSuppressScrollbarAnimations(suppressAnimations), m_pageID);
2076 }
2077
2078 bool WebPageProxy::rubberBandsAtLeft() const
2079 {
2080     return m_rubberBandsAtLeft;
2081 }
2082
2083 void WebPageProxy::setRubberBandsAtLeft(bool rubberBandsAtLeft)
2084 {
2085     m_rubberBandsAtLeft = rubberBandsAtLeft;
2086 }
2087
2088 bool WebPageProxy::rubberBandsAtRight() const
2089 {
2090     return m_rubberBandsAtRight;
2091 }
2092
2093 void WebPageProxy::setRubberBandsAtRight(bool rubberBandsAtRight)
2094 {
2095     m_rubberBandsAtRight = rubberBandsAtRight;
2096 }
2097
2098 bool WebPageProxy::rubberBandsAtTop() const
2099 {
2100     return m_rubberBandsAtTop;
2101 }
2102
2103 void WebPageProxy::setRubberBandsAtTop(bool rubberBandsAtTop)
2104 {
2105     m_rubberBandsAtTop = rubberBandsAtTop;
2106 }
2107
2108 bool WebPageProxy::rubberBandsAtBottom() const
2109 {
2110     return m_rubberBandsAtBottom;
2111 }
2112
2113 void WebPageProxy::setRubberBandsAtBottom(bool rubberBandsAtBottom)
2114 {
2115     m_rubberBandsAtBottom = rubberBandsAtBottom;
2116 }
2117     
2118 void WebPageProxy::setEnableVerticalRubberBanding(bool enableVerticalRubberBanding)
2119 {
2120     if (enableVerticalRubberBanding == m_enableVerticalRubberBanding)
2121         return;
2122
2123     m_enableVerticalRubberBanding = enableVerticalRubberBanding;
2124
2125     if (!isValid())
2126         return;
2127     m_process->send(Messages::WebPage::SetEnableVerticalRubberBanding(enableVerticalRubberBanding), m_pageID);
2128 }
2129     
2130 bool WebPageProxy::verticalRubberBandingIsEnabled() const
2131 {
2132     return m_enableVerticalRubberBanding;
2133 }
2134     
2135 void WebPageProxy::setEnableHorizontalRubberBanding(bool enableHorizontalRubberBanding)
2136 {
2137     if (enableHorizontalRubberBanding == m_enableHorizontalRubberBanding)
2138         return;
2139
2140     m_enableHorizontalRubberBanding = enableHorizontalRubberBanding;
2141
2142     if (!isValid())
2143         return;
2144     m_process->send(Messages::WebPage::SetEnableHorizontalRubberBanding(enableHorizontalRubberBanding), m_pageID);
2145 }
2146     
2147 bool WebPageProxy::horizontalRubberBandingIsEnabled() const
2148 {
2149     return m_enableHorizontalRubberBanding;
2150 }
2151
2152 void WebPageProxy::setBackgroundExtendsBeyondPage(bool backgroundExtendsBeyondPage)
2153 {
2154     if (backgroundExtendsBeyondPage == m_backgroundExtendsBeyondPage)
2155         return;
2156
2157     m_backgroundExtendsBeyondPage = backgroundExtendsBeyondPage;
2158
2159     if (!isValid())
2160         return;
2161     m_process->send(Messages::WebPage::SetBackgroundExtendsBeyondPage(backgroundExtendsBeyondPage), m_pageID);
2162 }
2163
2164 bool WebPageProxy::backgroundExtendsBeyondPage() const
2165 {
2166     return m_backgroundExtendsBeyondPage;
2167 }
2168
2169 void WebPageProxy::setPaginationMode(WebCore::Pagination::Mode mode)
2170 {
2171     if (mode == m_paginationMode)
2172         return;
2173
2174     m_paginationMode = mode;
2175
2176     if (!isValid())
2177         return;
2178     m_process->send(Messages::WebPage::SetPaginationMode(mode), m_pageID);
2179 }
2180
2181 void WebPageProxy::setPaginationBehavesLikeColumns(bool behavesLikeColumns)
2182 {
2183     if (behavesLikeColumns == m_paginationBehavesLikeColumns)
2184         return;
2185
2186     m_paginationBehavesLikeColumns = behavesLikeColumns;
2187
2188     if (!isValid())
2189         return;
2190     m_process->send(Messages::WebPage::SetPaginationBehavesLikeColumns(behavesLikeColumns), m_pageID);
2191 }
2192
2193 void WebPageProxy::setPageLength(double pageLength)
2194 {
2195     if (pageLength == m_pageLength)
2196         return;
2197
2198     m_pageLength = pageLength;
2199
2200     if (!isValid())
2201         return;
2202     m_process->send(Messages::WebPage::SetPageLength(pageLength), m_pageID);
2203 }
2204
2205 void WebPageProxy::setGapBetweenPages(double gap)
2206 {
2207     if (gap == m_gapBetweenPages)
2208         return;
2209
2210     m_gapBetweenPages = gap;
2211
2212     if (!isValid())
2213         return;
2214     m_process->send(Messages::WebPage::SetGapBetweenPages(gap), m_pageID);
2215 }
2216
2217 void WebPageProxy::pageScaleFactorDidChange(double scaleFactor)
2218 {
2219     m_pageScaleFactor = scaleFactor;
2220 }
2221
2222 void WebPageProxy::pageZoomFactorDidChange(double zoomFactor)
2223 {
2224     m_pageZoomFactor = zoomFactor;
2225 }
2226
2227 void WebPageProxy::findStringMatches(const String& string, FindOptions options, unsigned maxMatchCount)
2228 {
2229     if (string.isEmpty()) {
2230         didFindStringMatches(string, Vector<Vector<WebCore::IntRect>> (), 0);
2231         return;
2232     }
2233
2234     m_process->send(Messages::WebPage::FindStringMatches(string, options, maxMatchCount), m_pageID);
2235 }
2236
2237 void WebPageProxy::findString(const String& string, FindOptions options, unsigned maxMatchCount)
2238 {
2239     m_process->send(Messages::WebPage::FindString(string, options, maxMatchCount), m_pageID);
2240 }
2241
2242 void WebPageProxy::getImageForFindMatch(int32_t matchIndex)
2243 {
2244     m_process->send(Messages::WebPage::GetImageForFindMatch(matchIndex), m_pageID);
2245 }
2246
2247 void WebPageProxy::selectFindMatch(int32_t matchIndex)
2248 {
2249     m_process->send(Messages::WebPage::SelectFindMatch(matchIndex), m_pageID);
2250 }
2251
2252 void WebPageProxy::hideFindUI()
2253 {
2254     m_process->send(Messages::WebPage::HideFindUI(), m_pageID);
2255 }
2256
2257 void WebPageProxy::countStringMatches(const String& string, FindOptions options, unsigned maxMatchCount)
2258 {
2259     if (!isValid())
2260         return;
2261
2262     m_process->send(Messages::WebPage::CountStringMatches(string, options, maxMatchCount), m_pageID);
2263 }
2264
2265 void WebPageProxy::runJavaScriptInMainFrame(const String& script, std::function<void (WebSerializedScriptValue*, CallbackBase::Error)> callbackFunction)
2266 {
2267     if (!isValid()) {
2268         callbackFunction(nullptr, CallbackBase::Error::Unknown);
2269         return;
2270     }
2271
2272     uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), std::make_unique<ProcessThrottler::BackgroundActivityToken>(m_process->throttler()));
2273     m_process->send(Messages::WebPage::RunJavaScriptInMainFrame(script, callbackID), m_pageID);
2274 }
2275
2276 void WebPageProxy::getRenderTreeExternalRepresentation(std::function<void (const String&, CallbackBase::Error)> callbackFunction)
2277 {
2278     if (!isValid()) {
2279         callbackFunction(String(), CallbackBase::Error::Unknown);
2280         return;
2281     }
2282     
2283     uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), std::make_unique<ProcessThrottler::BackgroundActivityToken>(m_process->throttler()));
2284     m_process->send(Messages::WebPage::GetRenderTreeExternalRepresentation(callbackID), m_pageID);
2285 }
2286
2287 void WebPageProxy::getSourceForFrame(WebFrameProxy* frame, std::function<void (const String&, CallbackBase::Error)> callbackFunction)
2288 {
2289     if (!isValid()) {
2290         callbackFunction(String(), CallbackBase::Error::Unknown);
2291         return;
2292     }
2293     
2294     uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), std::make_unique<ProcessThrottler::BackgroundActivityToken>(m_process->throttler()));
2295     m_loadDependentStringCallbackIDs.add(callbackID);
2296     m_process->send(Messages::WebPage::GetSourceForFrame(frame->frameID(), callbackID), m_pageID);
2297 }
2298
2299 void WebPageProxy::getContentsAsString(std::function<void (const String&, CallbackBase::Error)> callbackFunction)
2300 {
2301     if (!isValid()) {
2302         callbackFunction(String(), CallbackBase::Error::Unknown);
2303         return;
2304     }
2305     
2306     uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), std::make_unique<ProcessThrottler::BackgroundActivityToken>(m_process->throttler()));
2307     m_loadDependentStringCallbackIDs.add(callbackID);
2308     m_process->send(Messages::WebPage::GetContentsAsString(callbackID), m_pageID);
2309 }
2310
2311 void WebPageProxy::getBytecodeProfile(std::function<void (const String&, CallbackBase::Error)> callbackFunction)
2312 {
2313     if (!isValid()) {
2314         callbackFunction(String(), CallbackBase::Error::Unknown);
2315         return;
2316     }
2317     
2318     uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), std::make_unique<ProcessThrottler::BackgroundActivityToken>(m_process->throttler()));
2319     m_loadDependentStringCallbackIDs.add(callbackID);
2320     m_process->send(Messages::WebPage::GetBytecodeProfile(callbackID), m_pageID);
2321 }
2322     
2323 #if ENABLE(MHTML)
2324 void WebPageProxy::getContentsAsMHTMLData(std::function<void (API::Data*, CallbackBase::Error)> callbackFunction, bool useBinaryEncoding)
2325 {
2326     if (!isValid()) {
2327         callbackFunction(nullptr, CallbackBase::Error::Unknown);
2328         return;
2329     }
2330
2331     uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), std::make_unique<ProcessThrottler::BackgroundActivityToken>(m_process->throttler()));
2332     m_process->send(Messages::WebPage::GetContentsAsMHTMLData(callbackID, useBinaryEncoding), m_pageID);
2333 }
2334 #endif
2335
2336 void WebPageProxy::getSelectionOrContentsAsString(std::function<void (const String&, CallbackBase::Error)> callbackFunction)
2337 {
2338     if (!isValid()) {
2339         callbackFunction(String(), CallbackBase::Error::Unknown);
2340         return;
2341     }
2342     
2343     uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), std::make_unique<ProcessThrottler::BackgroundActivityToken>(m_process->throttler()));
2344     m_process->send(Messages::WebPage::GetSelectionOrContentsAsString(callbackID), m_pageID);
2345 }
2346
2347 void WebPageProxy::getSelectionAsWebArchiveData(std::function<void (API::Data*, CallbackBase::Error)> callbackFunction)
2348 {
2349     if (!isValid()) {
2350         callbackFunction(nullptr, CallbackBase::Error::Unknown);
2351         return;
2352     }
2353     
2354     uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), std::make_unique<ProcessThrottler::BackgroundActivityToken>(m_process->throttler()));
2355     m_process->send(Messages::WebPage::GetSelectionAsWebArchiveData(callbackID), m_pageID);
2356 }
2357
2358 void WebPageProxy::getMainResourceDataOfFrame(WebFrameProxy* frame, std::function<void (API::Data*, CallbackBase::Error)> callbackFunction)
2359 {
2360     if (!isValid() || !frame) {
2361         callbackFunction(nullptr, CallbackBase::Error::Unknown);
2362         return;
2363     }
2364     
2365     uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), std::make_unique<ProcessThrottler::BackgroundActivityToken>(m_process->throttler()));
2366     m_process->send(Messages::WebPage::GetMainResourceDataOfFrame(frame->frameID(), callbackID), m_pageID);
2367 }
2368
2369 void WebPageProxy::getResourceDataFromFrame(WebFrameProxy* frame, API::URL* resourceURL, std::function<void (API::Data*, CallbackBase::Error)> callbackFunction)
2370 {
2371     if (!isValid()) {
2372         callbackFunction(nullptr, CallbackBase::Error::Unknown);
2373         return;
2374     }
2375     
2376     uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), std::make_unique<ProcessThrottler::BackgroundActivityToken>(m_process->throttler()));
2377     m_process->send(Messages::WebPage::GetResourceDataFromFrame(frame->frameID(), resourceURL->string(), callbackID), m_pageID);
2378 }
2379
2380 void WebPageProxy::getWebArchiveOfFrame(WebFrameProxy* frame, std::function<void (API::Data*, CallbackBase::Error)> callbackFunction)
2381 {
2382     if (!isValid()) {
2383         callbackFunction(nullptr, CallbackBase::Error::Unknown);
2384         return;
2385     }
2386     
2387     uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), std::make_unique<ProcessThrottler::BackgroundActivityToken>(m_process->throttler()));
2388     m_process->send(Messages::WebPage::GetWebArchiveOfFrame(frame->frameID(), callbackID), m_pageID);
2389 }
2390
2391 void WebPageProxy::forceRepaint(PassRefPtr<VoidCallback> prpCallback)
2392 {
2393     RefPtr<VoidCallback> callback = prpCallback;
2394     if (!isValid()) {
2395         // FIXME: If the page is invalid we should not call the callback. It'd be better to just return false from forceRepaint.
2396         callback->invalidate(CallbackBase::Error::OwnerWasInvalidated);
2397         return;
2398     }
2399
2400     uint64_t callbackID = callback->callbackID();
2401     m_callbacks.put(callback);
2402     m_drawingArea->waitForBackingStoreUpdateOnNextPaint();
2403     m_process->send(Messages::WebPage::ForceRepaint(callbackID), m_pageID); 
2404 }
2405
2406 void WebPageProxy::preferencesDidChange()
2407 {
2408     if (!isValid())
2409         return;
2410
2411 #if ENABLE(INSPECTOR_SERVER)
2412     if (m_preferences->developerExtrasEnabled())
2413         inspector()->enableRemoteInspection();
2414 #endif
2415
2416     m_process->pagePreferencesChanged(this);
2417
2418     m_pageClient.preferencesDidChange();
2419
2420     // FIXME: It probably makes more sense to send individual preference changes.
2421     // However, WebKitTestRunner depends on getting a preference change notification
2422     // even if nothing changed in UI process, so that overrides get removed.
2423
2424     // Preferences need to be updated during synchronous printing to make "print backgrounds" preference work when toggled from a print dialog checkbox.
2425     m_process->send(Messages::WebPage::PreferencesDidChange(preferencesStore()), m_pageID, m_isPerformingDOMPrintOperation ? IPC::DispatchMessageEvenWhenWaitingForSyncReply : 0);
2426 }
2427
2428 void WebPageProxy::didCreateMainFrame(uint64_t frameID)
2429 {
2430     MESSAGE_CHECK(!m_mainFrame);
2431     MESSAGE_CHECK(m_process->canCreateFrame(frameID));
2432
2433     m_mainFrame = WebFrameProxy::create(this, frameID);
2434
2435     // Add the frame to the process wide map.
2436     m_process->frameCreated(frameID, m_mainFrame.get());
2437 }
2438
2439 void WebPageProxy::didCreateSubframe(uint64_t frameID)
2440 {
2441     MESSAGE_CHECK(m_mainFrame);
2442     MESSAGE_CHECK(m_process->canCreateFrame(frameID));
2443     
2444     RefPtr<WebFrameProxy> subFrame = WebFrameProxy::create(this, frameID);
2445
2446     // Add the frame to the process wide map.
2447     m_process->frameCreated(frameID, subFrame.get());
2448 }
2449
2450 double WebPageProxy::estimatedProgress() const
2451 {
2452     return m_pageLoadState.estimatedProgress();
2453 }
2454
2455 void WebPageProxy::didStartProgress()
2456 {
2457     auto transaction = m_pageLoadState.transaction();
2458     m_pageLoadState.didStartProgress(transaction);
2459
2460     m_pageLoadState.commitChanges();
2461     m_loaderClient->didStartProgress(this);
2462 }
2463
2464 void WebPageProxy::didChangeProgress(double value)
2465 {
2466     auto transaction = m_pageLoadState.transaction();
2467     m_pageLoadState.didChangeProgress(transaction, value);
2468
2469     m_pageLoadState.commitChanges();
2470     m_loaderClient->didChangeProgress(this);
2471 }
2472
2473 void WebPageProxy::didFinishProgress()
2474 {
2475     auto transaction = m_pageLoadState.transaction();
2476     m_pageLoadState.didFinishProgress(transaction);
2477
2478     m_pageLoadState.commitChanges();
2479     m_loaderClient->didFinishProgress(this);
2480 }
2481
2482 void WebPageProxy::setNetworkRequestsInProgress(bool networkRequestsInProgress)
2483 {
2484     auto transaction = m_pageLoadState.transaction();
2485     m_pageLoadState.setNetworkRequestsInProgress(transaction, networkRequestsInProgress);
2486 }
2487
2488 void WebPageProxy::didDestroyNavigation(uint64_t navigationID)
2489 {
2490     m_loaderClient->didDestroyNavigation(this, navigationID);
2491 }
2492
2493 void WebPageProxy::didStartProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& url, const String& unreachableURL, IPC::MessageDecoder& decoder)
2494 {
2495     auto transaction = m_pageLoadState.transaction();
2496
2497     m_pageLoadState.clearPendingAPIRequestURL(transaction);
2498
2499     RefPtr<API::Object> userData;
2500     WebContextUserMessageDecoder messageDecoder(userData, process());
2501     if (!decoder.decode(messageDecoder))
2502         return;
2503
2504     WebFrameProxy* frame = m_process->webFrame(frameID);
2505     MESSAGE_CHECK(frame);
2506     MESSAGE_CHECK_URL(url);
2507
2508     if (frame->isMainFrame())
2509         m_pageLoadState.didStartProvisionalLoad(transaction, url, unreachableURL);
2510
2511     frame->setUnreachableURL(unreachableURL);
2512     frame->didStartProvisionalLoad(url);
2513
2514     m_pageLoadState.commitChanges();
2515     m_loaderClient->didStartProvisionalLoadForFrame(this, frame, navigationID, userData.get());
2516 }
2517
2518 void WebPageProxy::didReceiveServerRedirectForProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& url, IPC::MessageDecoder& decoder)
2519 {
2520     RefPtr<API::Object> userData;
2521     WebContextUserMessageDecoder messageDecoder(userData, process());
2522     if (!decoder.decode(messageDecoder))
2523         return;
2524
2525     WebFrameProxy* frame = m_process->webFrame(frameID);
2526     MESSAGE_CHECK(frame);
2527     MESSAGE_CHECK_URL(url);
2528
2529     auto transaction = m_pageLoadState.transaction();
2530
2531     if (frame->isMainFrame())
2532         m_pageLoadState.didReceiveServerRedirectForProvisionalLoad(transaction, url);
2533
2534     frame->didReceiveServerRedirectForProvisionalLoad(url);
2535
2536     m_pageLoadState.commitChanges();
2537     m_loaderClient->didReceiveServerRedirectForProvisionalLoadForFrame(this, frame, navigationID, userData.get());
2538 }
2539
2540 void WebPageProxy::didFailProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, const ResourceError& error, IPC::MessageDecoder& decoder)
2541 {
2542     RefPtr<API::Object> userData;
2543     WebContextUserMessageDecoder messageDecoder(userData, process());
2544     if (!decoder.decode(messageDecoder))
2545         return;
2546
2547     WebFrameProxy* frame = m_process->webFrame(frameID);
2548     MESSAGE_CHECK(frame);
2549
2550     auto transaction = m_pageLoadState.transaction();
2551
2552     if (frame->isMainFrame())
2553         m_pageLoadState.didFailProvisionalLoad(transaction);
2554
2555     frame->didFailProvisionalLoad();
2556
2557     m_pageLoadState.commitChanges();
2558     m_loaderClient->didFailProvisionalLoadWithErrorForFrame(this, frame, navigationID, error, userData.get());
2559 }
2560
2561 void WebPageProxy::clearLoadDependentCallbacks()
2562 {
2563     Vector<uint64_t> callbackIDsCopy;
2564     copyToVector(m_loadDependentStringCallbackIDs, callbackIDsCopy);
2565     m_loadDependentStringCallbackIDs.clear();
2566
2567     for (size_t i = 0; i < callbackIDsCopy.size(); ++i) {
2568         auto callback = m_callbacks.take<StringCallback>(callbackIDsCopy[i]);
2569         if (callback)
2570             callback->invalidate();
2571     }
2572 }
2573
2574 void WebPageProxy::didCommitLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& mimeType, bool frameHasCustomContentProvider, uint32_t opaqueFrameLoadType, const WebCore::CertificateInfo& certificateInfo, IPC::MessageDecoder& decoder)
2575 {
2576     RefPtr<API::Object> userData;
2577     WebContextUserMessageDecoder messageDecoder(userData, process());
2578     if (!decoder.decode(messageDecoder))
2579         return;
2580
2581     WebFrameProxy* frame = m_process->webFrame(frameID);
2582     MESSAGE_CHECK(frame);
2583
2584     auto transaction = m_pageLoadState.transaction();
2585
2586     if (frame->isMainFrame())
2587         m_pageLoadState.didCommitLoad(transaction);
2588
2589 #if USE(APPKIT)
2590     // FIXME (bug 59111): didCommitLoadForFrame comes too late when restoring a page from b/f cache, making us disable secure event mode in password fields.
2591     // FIXME: A load going on in one frame shouldn't affect text editing in other frames on the page.
2592     m_pageClient.resetSecureInputState();
2593     dismissCorrectionPanel(ReasonForDismissingAlternativeTextIgnored);
2594     m_pageClient.dismissDictionaryLookupPanel();
2595 #endif
2596
2597     clearLoadDependentCallbacks();
2598
2599     frame->didCommitLoad(mimeType, certificateInfo);
2600
2601     if (frame->isMainFrame()) {
2602         m_mainFrameHasCustomContentProvider = frameHasCustomContentProvider;
2603
2604         if (m_mainFrameHasCustomContentProvider) {
2605             // Always assume that the main frame is pinned here, since the custom representation view will handle
2606             // any wheel events and dispatch them to the WKView when necessary.
2607             m_mainFrameIsPinnedToLeftSide = true;
2608             m_mainFrameIsPinnedToRightSide = true;
2609             m_mainFrameIsPinnedToTopSide = true;
2610             m_mainFrameIsPinnedToBottomSide = true;
2611
2612             m_uiClient->pinnedStateDidChange(*this);
2613         }
2614         m_pageClient.didCommitLoadForMainFrame(mimeType, frameHasCustomContentProvider);
2615     }
2616
2617     // Even if WebPage has the default pageScaleFactor (and therefore doesn't reset it),
2618     // WebPageProxy's cache of the value can get out of sync (e.g. in the case where a
2619     // plugin is handling page scaling itself) so we should reset it to the default
2620     // for standard main frame loads.
2621     if (frame->isMainFrame() && static_cast<FrameLoadType>(opaqueFrameLoadType) == FrameLoadType::Standard)
2622         m_pageScaleFactor = 1;
2623
2624     m_pageLoadState.commitChanges();
2625     m_loaderClient->didCommitLoadForFrame(this, frame, navigationID, userData.get());
2626 }
2627
2628 void WebPageProxy::didFinishDocumentLoadForFrame(uint64_t frameID, uint64_t navigationID, IPC::MessageDecoder& decoder)
2629 {
2630     RefPtr<API::Object> userData;
2631     WebContextUserMessageDecoder messageDecoder(userData, process());
2632     if (!decoder.decode(messageDecoder))
2633         return;
2634
2635     WebFrameProxy* frame = m_process->webFrame(frameID);
2636     MESSAGE_CHECK(frame);
2637
2638     m_loaderClient->didFinishDocumentLoadForFrame(this, frame, navigationID, userData.get());
2639 }
2640
2641 void WebPageProxy::didFinishLoadForFrame(uint64_t frameID, uint64_t navigationID, IPC::MessageDecoder& decoder)
2642 {
2643     RefPtr<API::Object> userData;
2644     WebContextUserMessageDecoder messageDecoder(userData, process());
2645     if (!decoder.decode(messageDecoder))
2646         return;
2647
2648     WebFrameProxy* frame = m_process->webFrame(frameID);
2649     MESSAGE_CHECK(frame);
2650
2651     auto transaction = m_pageLoadState.transaction();
2652
2653     if (frame->isMainFrame())
2654         m_pageLoadState.didFinishLoad(transaction);
2655
2656     frame->didFinishLoad();
2657
2658     m_pageLoadState.commitChanges();
2659     m_loaderClient->didFinishLoadForFrame(this, frame, navigationID, userData.get());
2660 }
2661
2662 void WebPageProxy::didFailLoadForFrame(uint64_t frameID, uint64_t navigationID, const ResourceError& error, IPC::MessageDecoder& decoder)
2663 {
2664     RefPtr<API::Object> userData;
2665     WebContextUserMessageDecoder messageDecoder(userData, process());
2666     if (!decoder.decode(messageDecoder))
2667         return;
2668
2669     WebFrameProxy* frame = m_process->webFrame(frameID);
2670     MESSAGE_CHECK(frame);
2671
2672     clearLoadDependentCallbacks();
2673
2674     auto transaction = m_pageLoadState.transaction();
2675
2676     if (frame->isMainFrame())
2677         m_pageLoadState.didFailLoad(transaction);
2678
2679     frame->didFailLoad();
2680
2681     m_pageLoadState.commitChanges();
2682     m_loaderClient->didFailLoadWithErrorForFrame(this, frame, navigationID, error, userData.get());
2683 }
2684
2685 void WebPageProxy::didSameDocumentNavigationForFrame(uint64_t frameID, uint64_t navigationID, uint32_t opaqueSameDocumentNavigationType, const String& url, IPC::MessageDecoder& decoder)
2686 {
2687     RefPtr<API::Object> userData;
2688     WebContextUserMessageDecoder messageDecoder(userData, process());
2689     if (!decoder.decode(messageDecoder))
2690         return;
2691
2692     WebFrameProxy* frame = m_process->webFrame(frameID);
2693     MESSAGE_CHECK(frame);
2694     MESSAGE_CHECK_URL(url);
2695
2696     auto transaction = m_pageLoadState.transaction();
2697
2698     if (frame->isMainFrame())
2699         m_pageLoadState.didSameDocumentNavigation(transaction, url);
2700
2701     m_pageLoadState.clearPendingAPIRequestURL(transaction);
2702     frame->didSameDocumentNavigation(url);
2703
2704     m_pageLoadState.commitChanges();
2705     m_loaderClient->didSameDocumentNavigationForFrame(this, frame, navigationID, static_cast<SameDocumentNavigationType>(opaqueSameDocumentNavigationType), userData.get());
2706 }
2707
2708 void WebPageProxy::didReceiveTitleForFrame(uint64_t frameID, const String& title, IPC::MessageDecoder& decoder)
2709 {
2710     RefPtr<API::Object> userData;
2711     WebContextUserMessageDecoder messageDecoder(userData, process());
2712     if (!decoder.decode(messageDecoder))
2713         return;
2714
2715     WebFrameProxy* frame = m_process->webFrame(frameID);
2716     MESSAGE_CHECK(frame);
2717
2718     auto transaction = m_pageLoadState.transaction();
2719
2720     if (frame->isMainFrame())
2721         m_pageLoadState.setTitle(transaction, title);
2722
2723     frame->didChangeTitle(title);
2724     
2725     m_pageLoadState.commitChanges();
2726     m_loaderClient->didReceiveTitleForFrame(this, title, frame, userData.get());
2727 }
2728
2729 void WebPageProxy::didFirstLayoutForFrame(uint64_t frameID, IPC::MessageDecoder& decoder)
2730 {
2731     RefPtr<API::Object> userData;
2732     WebContextUserMessageDecoder messageDecoder(userData, process());
2733     if (!decoder.decode(messageDecoder))
2734         return;
2735
2736     WebFrameProxy* frame = m_process->webFrame(frameID);
2737     MESSAGE_CHECK(frame);
2738
2739     m_loaderClient->didFirstLayoutForFrame(this, frame, userData.get());
2740 }
2741
2742 void WebPageProxy::didFirstVisuallyNonEmptyLayoutForFrame(uint64_t frameID, IPC::MessageDecoder& decoder)
2743 {
2744     RefPtr<API::Object> userData;
2745     WebContextUserMessageDecoder messageDecoder(userData, process());
2746     if (!decoder.decode(messageDecoder))
2747         return;
2748
2749     WebFrameProxy* frame = m_process->webFrame(frameID);
2750     MESSAGE_CHECK(frame);
2751
2752     m_loaderClient->didFirstVisuallyNonEmptyLayoutForFrame(this, frame, userData.get());
2753 }
2754
2755 void WebPageProxy::didLayout(uint32_t layoutMilestones, IPC::MessageDecoder& decoder)
2756 {
2757     RefPtr<API::Object> userData;
2758     WebContextUserMessageDecoder messageDecoder(userData, process());
2759     if (!decoder.decode(messageDecoder))
2760         return;
2761
2762     m_loaderClient->didLayout(this, static_cast<LayoutMilestones>(layoutMilestones), userData.get());
2763 }
2764
2765 void WebPageProxy::didRemoveFrameFromHierarchy(uint64_t frameID, IPC::MessageDecoder& decoder)
2766 {
2767     RefPtr<API::Object> userData;
2768     WebContextUserMessageDecoder messageDecoder(userData, process());
2769     if (!decoder.decode(messageDecoder))
2770         return;
2771
2772     WebFrameProxy* frame = m_process->webFrame(frameID);
2773     MESSAGE_CHECK(frame);
2774
2775     m_loaderClient->didRemoveFrameFromHierarchy(this, frame, userData.get());
2776 }
2777
2778 void WebPageProxy::didDisplayInsecureContentForFrame(uint64_t frameID, IPC::MessageDecoder& decoder)
2779 {
2780     RefPtr<API::Object> userData;
2781     WebContextUserMessageDecoder messageDecoder(userData, process());
2782     if (!decoder.decode(messageDecoder))
2783         return;
2784
2785     WebFrameProxy* frame = m_process->webFrame(frameID);
2786     MESSAGE_CHECK(frame);
2787
2788     auto transaction = m_pageLoadState.transaction();
2789     m_pageLoadState.didDisplayOrRunInsecureContent(transaction);
2790
2791     m_pageLoadState.commitChanges();
2792     m_loaderClient->didDisplayInsecureContentForFrame(this, frame, userData.get());
2793 }
2794
2795 void WebPageProxy::didRunInsecureContentForFrame(uint64_t frameID, IPC::MessageDecoder& decoder)
2796 {
2797     RefPtr<API::Object> userData;
2798     WebContextUserMessageDecoder messageDecoder(userData, process());
2799     if (!decoder.decode(messageDecoder))
2800         return;
2801
2802     WebFrameProxy* frame = m_process->webFrame(frameID);
2803     MESSAGE_CHECK(frame);
2804
2805     auto transaction = m_pageLoadState.transaction();
2806     m_pageLoadState.didDisplayOrRunInsecureContent(transaction);
2807
2808     m_pageLoadState.commitChanges();
2809     m_loaderClient->didRunInsecureContentForFrame(this, frame, userData.get());
2810 }
2811
2812 void WebPageProxy::didDetectXSSForFrame(uint64_t frameID, IPC::MessageDecoder& decoder)
2813 {
2814     RefPtr<API::Object> userData;
2815     WebContextUserMessageDecoder messageDecoder(userData, process());
2816     if (!decoder.decode(messageDecoder))
2817         return;
2818
2819     WebFrameProxy* frame = m_process->webFrame(frameID);
2820     MESSAGE_CHECK(frame);
2821
2822     m_loaderClient->didDetectXSSForFrame(this, frame, userData.get());
2823 }
2824
2825 void WebPageProxy::frameDidBecomeFrameSet(uint64_t frameID, bool value)
2826 {
2827     WebFrameProxy* frame = m_process->webFrame(frameID);
2828     MESSAGE_CHECK(frame);
2829
2830     frame->setIsFrameSet(value);
2831     if (frame->isMainFrame())
2832         m_frameSetLargestFrame = value ? m_mainFrame : 0;
2833 }
2834
2835 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)
2836 {
2837     RefPtr<API::Object> userData;
2838     WebContextUserMessageDecoder messageDecoder(userData, process());
2839     if (!decoder.decode(messageDecoder))
2840         return;
2841
2842     auto transaction = m_pageLoadState.transaction();
2843
2844     if (request.url() != m_pageLoadState.pendingAPIRequestURL())
2845         m_pageLoadState.clearPendingAPIRequestURL(transaction);
2846
2847     WebFrameProxy* frame = m_process->webFrame(frameID);
2848     MESSAGE_CHECK(frame);
2849     MESSAGE_CHECK_URL(request.url());
2850     MESSAGE_CHECK_URL(originalRequest.url());
2851
2852     WebFrameProxy* originatingFrame = m_process->webFrame(originatingFrameID);
2853     
2854     RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
2855     if (!navigationID && frame->isMainFrame()) {
2856         newNavigationID = generateNavigationID();
2857         listener->setNavigationID(newNavigationID);
2858     }
2859
2860 #if ENABLE(CONTENT_FILTERING)
2861     if (frame->contentFilterDidHandleNavigationAction(request)) {
2862         receivedPolicyAction = true;
2863         policyAction = PolicyIgnore;
2864         return;
2865     }
2866 #endif
2867
2868     ASSERT(!m_inDecidePolicyForNavigationAction);
2869
2870     m_inDecidePolicyForNavigationAction = true;
2871     m_syncNavigationActionPolicyActionIsValid = false;
2872
2873     m_policyClient->decidePolicyForNavigationAction(this, frame, navigationActionData, originatingFrame, originalRequest, request, WTF::move(listener), userData.get());
2874
2875     m_inDecidePolicyForNavigationAction = false;
2876
2877     // Check if we received a policy decision already. If we did, we can just pass it back.
2878     receivedPolicyAction = m_syncNavigationActionPolicyActionIsValid;
2879     if (m_syncNavigationActionPolicyActionIsValid) {
2880         policyAction = m_syncNavigationActionPolicyAction;
2881         downloadID = m_syncNavigationActionPolicyDownloadID;
2882     }
2883 }
2884
2885 void WebPageProxy::decidePolicyForNewWindowAction(uint64_t frameID, const NavigationActionData& navigationActionData, const ResourceRequest& request, const String& frameName, uint64_t listenerID, IPC::MessageDecoder& decoder)
2886 {
2887     RefPtr<API::Object> userData;
2888     WebContextUserMessageDecoder messageDecoder(userData, process());
2889     if (!decoder.decode(messageDecoder))
2890         return;
2891
2892     WebFrameProxy* frame = m_process->webFrame(frameID);
2893     MESSAGE_CHECK(frame);
2894     MESSAGE_CHECK_URL(request.url());
2895
2896     RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
2897
2898     m_policyClient->decidePolicyForNewWindowAction(this, frame, navigationActionData, request, frameName, WTF::move(listener), userData.get());
2899 }
2900
2901 void WebPageProxy::decidePolicyForResponse(uint64_t frameID, const ResourceResponse& response, const ResourceRequest& request, bool canShowMIMEType, uint64_t listenerID, IPC::MessageDecoder& decoder)
2902 {
2903     RefPtr<API::Object> userData;
2904     WebContextUserMessageDecoder messageDecoder(userData, process());
2905     if (!decoder.decode(messageDecoder))
2906         return;
2907
2908     WebFrameProxy* frame = m_process->webFrame(frameID);
2909     MESSAGE_CHECK(frame);
2910     MESSAGE_CHECK_URL(request.url());
2911     MESSAGE_CHECK_URL(response.url());
2912
2913     RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
2914
2915     m_policyClient->decidePolicyForResponse(this, frame, response, request, canShowMIMEType, WTF::move(listener), userData.get());
2916 }
2917
2918 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)
2919 {
2920     ASSERT(!m_inDecidePolicyForResponseSync);
2921
2922     m_inDecidePolicyForResponseSync = true;
2923     m_decidePolicyForResponseRequest = &request;
2924     m_syncMimeTypePolicyActionIsValid = false;
2925
2926     decidePolicyForResponse(frameID, response, request, canShowMIMEType, listenerID, decoder);
2927
2928     m_inDecidePolicyForResponseSync = false;
2929     m_decidePolicyForResponseRequest = 0;
2930
2931     // Check if we received a policy decision already. If we did, we can just pass it back.
2932     receivedPolicyAction = m_syncMimeTypePolicyActionIsValid;
2933     if (m_syncMimeTypePolicyActionIsValid) {
2934         policyAction = m_syncMimeTypePolicyAction;
2935         downloadID = m_syncMimeTypePolicyDownloadID;
2936     }
2937 }
2938
2939 void WebPageProxy::unableToImplementPolicy(uint64_t frameID, const ResourceError& error, IPC::MessageDecoder& decoder)
2940 {
2941     RefPtr<API::Object> userData;
2942     WebContextUserMessageDecoder messageDecoder(userData, process());
2943     if (!decoder.decode(messageDecoder))
2944         return;
2945     
2946     WebFrameProxy* frame = m_process->webFrame(frameID);
2947     MESSAGE_CHECK(frame);
2948
2949     m_policyClient->unableToImplementPolicy(this, frame, error, userData.get());
2950 }
2951
2952 // FormClient
2953
2954 void WebPageProxy::willSubmitForm(uint64_t frameID, uint64_t sourceFrameID, const Vector<std::pair<String, String>>& textFieldValues, uint64_t listenerID, IPC::MessageDecoder& decoder)
2955 {
2956     RefPtr<API::Object> userData;
2957     WebContextUserMessageDecoder messageDecoder(userData, process());
2958     if (!decoder.decode(messageDecoder))
2959         return;
2960
2961     WebFrameProxy* frame = m_process->webFrame(frameID);
2962     MESSAGE_CHECK(frame);
2963
2964     WebFrameProxy* sourceFrame = m_process->webFrame(sourceFrameID);
2965     MESSAGE_CHECK(sourceFrame);
2966
2967     RefPtr<WebFormSubmissionListenerProxy> listener = frame->setUpFormSubmissionListenerProxy(listenerID);
2968     if (!m_formClient->willSubmitForm(this, frame, sourceFrame, textFieldValues, userData.get(), listener.get()))
2969         listener->continueSubmission();
2970 }
2971
2972 // UIClient
2973
2974 void WebPageProxy::createNewPage(uint64_t frameID, const ResourceRequest& request, const WindowFeatures& windowFeatures, const NavigationActionData& navigationActionData, uint64_t& newPageID, WebPageCreationParameters& newPageParameters)
2975 {
2976     WebFrameProxy* frame = m_process->webFrame(frameID);
2977     MESSAGE_CHECK(frame);
2978
2979     RefPtr<WebPageProxy> newPage = m_uiClient->createNewPage(this, frame, request, windowFeatures, navigationActionData);
2980     if (!newPage) {
2981         newPageID = 0;
2982         return;
2983     }
2984
2985     newPageID = newPage->pageID();
2986     newPageParameters = newPage->creationParameters();
2987     process().context().storageManager().cloneSessionStorageNamespace(m_pageID, newPage->pageID());
2988 }
2989     
2990 void WebPageProxy::showPage()
2991 {
2992     m_uiClient->showPage(this);
2993 }
2994
2995 void WebPageProxy::closePage(bool stopResponsivenessTimer)
2996 {
2997     if (stopResponsivenessTimer)
2998         m_process->responsivenessTimer()->stop();
2999
3000     m_pageClient.clearAllEditCommands();
3001     m_uiClient->close(this);
3002 }
3003
3004 void WebPageProxy::runJavaScriptAlert(uint64_t frameID, const String& message, RefPtr<Messages::WebPageProxy::RunJavaScriptAlert::DelayedReply> reply)
3005 {
3006     WebFrameProxy* frame = m_process->webFrame(frameID);
3007     MESSAGE_CHECK(frame);
3008
3009     // Since runJavaScriptAlert() can spin a nested run loop we need to turn off the responsiveness timer.
3010     m_process->responsivenessTimer()->stop();
3011
3012     m_uiClient->runJavaScriptAlert(this, message, frame, [reply]{ reply->send(); });
3013 }
3014
3015 void WebPageProxy::runJavaScriptConfirm(uint64_t frameID, const String& message, RefPtr<Messages::WebPageProxy::RunJavaScriptConfirm::DelayedReply> reply)
3016 {
3017     WebFrameProxy* frame = m_process->webFrame(frameID);
3018     MESSAGE_CHECK(frame);
3019
3020     // Since runJavaScriptConfirm() can spin a nested run loop we need to turn off the responsiveness timer.
3021     m_process->responsivenessTimer()->stop();
3022
3023     m_uiClient->runJavaScriptConfirm(this, message, frame, [reply](bool result) { reply->send(result); });
3024 }
3025
3026 void WebPageProxy::runJavaScriptPrompt(uint64_t frameID, const String& message, const String& defaultValue, RefPtr<Messages::WebPageProxy::RunJavaScriptPrompt::DelayedReply> reply)
3027 {
3028     WebFrameProxy* frame = m_process->webFrame(frameID);
3029     MESSAGE_CHECK(frame);
3030
3031     // Since runJavaScriptPrompt() can spin a nested run loop we need to turn off the responsiveness timer.
3032     m_process->responsivenessTimer()->stop();
3033
3034     m_uiClient->runJavaScriptPrompt(this, message, defaultValue, frame, [reply](const String& result) { reply->send(result); });
3035 }
3036
3037 void WebPageProxy::shouldInterruptJavaScript(bool& result)
3038 {
3039     // Since shouldInterruptJavaScript() can spin a nested run loop we need to turn off the responsiveness timer.
3040     m_process->responsivenessTimer()->stop();
3041
3042     result = m_uiClient->shouldInterruptJavaScript(this);
3043 }
3044
3045 void WebPageProxy::setStatusText(const String& text)
3046 {
3047     m_uiClient->setStatusText(this, text);
3048 }
3049
3050 void WebPageProxy::mouseDidMoveOverElement(const WebHitTestResult::Data& hitTestResultData, uint32_t opaqueModifiers, IPC::MessageDecoder& decoder)
3051 {
3052     RefPtr<API::Object> userData;
3053     WebContextUserMessageDecoder messageDecoder(userData, process());
3054     if (!decoder.decode(messageDecoder))
3055         return;
3056
3057     WebEvent::Modifiers modifiers = static_cast<WebEvent::Modifiers>(opaqueModifiers);
3058
3059     m_uiClient->mouseDidMoveOverElement(this, hitTestResultData, modifiers, userData.get());
3060 }
3061
3062 void WebPageProxy::connectionWillOpen(IPC::Connection* connection)
3063 {
3064     ASSERT(connection == m_process->connection());
3065
3066     m_process->context().storageManager().setAllowedSessionStorageNamespaceConnection(m_pageID, connection);
3067 }
3068
3069 void WebPageProxy::connectionWillClose(IPC::Connection* connection)
3070 {
3071     ASSERT_UNUSED(connection, connection == m_process->connection());
3072
3073     m_process->context().storageManager().setAllowedSessionStorageNamespaceConnection(m_pageID, 0);
3074 }
3075
3076 void WebPageProxy::processDidFinishLaunching()
3077 {
3078     if (m_userContentController)
3079         m_userContentController->addProcess(m_process.get());
3080     m_visitedLinkProvider->addProcess(m_process.get());
3081 }
3082
3083 #if ENABLE(NETSCAPE_PLUGIN_API)
3084 void WebPageProxy::unavailablePluginButtonClicked(uint32_t opaquePluginUnavailabilityReason, const String& mimeType, const String& pluginURLString, const String& pluginspageAttributeURLString, const String& frameURLString, const String& pageURLString)
3085 {
3086     MESSAGE_CHECK_URL(pluginURLString);
3087     MESSAGE_CHECK_URL(pluginspageAttributeURLString);
3088     MESSAGE_CHECK_URL(frameURLString);
3089     MESSAGE_CHECK_URL(pageURLString);
3090
3091     RefPtr<ImmutableDictionary> pluginInformation;
3092     String newMimeType = mimeType;
3093     PluginModuleInfo plugin = m_process->context().pluginInfoStore().findPlugin(newMimeType, URL(URL(), pluginURLString));
3094     pluginInformation = createPluginInformationDictionary(plugin, frameURLString, mimeType, pageURLString, pluginspageAttributeURLString, pluginURLString);
3095
3096     WKPluginUnavailabilityReason pluginUnavailabilityReason = kWKPluginUnavailabilityReasonPluginMissing;
3097     switch (static_cast<RenderEmbeddedObject::PluginUnavailabilityReason>(opaquePluginUnavailabilityReason)) {
3098     case RenderEmbeddedObject::PluginMissing:
3099         pluginUnavailabilityReason = kWKPluginUnavailabilityReasonPluginMissing;
3100         break;
3101     case RenderEmbeddedObject::InsecurePluginVersion:
3102         pluginUnavailabilityReason = kWKPluginUnavailabilityReasonInsecurePluginVersion;
3103         break;
3104     case RenderEmbeddedObject::PluginCrashed:
3105         pluginUnavailabilityReason = kWKPluginUnavailabilityReasonPluginCrashed;
3106         break;
3107     case RenderEmbeddedObject::PluginBlockedByContentSecurityPolicy:
3108         ASSERT_NOT_REACHED();
3109     }
3110
3111     m_uiClient->unavailablePluginButtonClicked(this, pluginUnavailabilityReason, pluginInformation.get());
3112 }
3113 #endif // ENABLE(NETSCAPE_PLUGIN_API)
3114
3115 #if ENABLE(WEBGL)
3116 void WebPageProxy::webGLPolicyForURL(const String& url, uint32_t& loadPolicy)
3117 {
3118     loadPolicy = static_cast<uint32_t>(m_loaderClient->webGLLoadPolicy(this, url));
3119 }
3120
3121 void WebPageProxy::resolveWebGLPolicyForURL(const String& url, uint32_t& loadPolicy)
3122 {
3123     loadPolicy = static_cast<uint32_t>(m_loaderClient->resolveWebGLLoadPolicy(this, url));
3124 }
3125 #endif // ENABLE(WEBGL)
3126
3127 void WebPageProxy::setToolbarsAreVisible(bool toolbarsAreVisible)
3128 {
3129     m_uiClient->setToolbarsAreVisible(this, toolbarsAreVisible);
3130 }
3131
3132 void WebPageProxy::getToolbarsAreVisible(bool& toolbarsAreVisible)
3133 {
3134     toolbarsAreVisible = m_uiClient->toolbarsAreVisible(this);
3135 }
3136
3137 void WebPageProxy::setMenuBarIsVisible(bool menuBarIsVisible)
3138 {
3139     m_uiClient->setMenuBarIsVisible(this, menuBarIsVisible);
3140 }
3141
3142 void WebPageProxy::getMenuBarIsVisible(bool& menuBarIsVisible)
3143 {
3144     menuBarIsVisible = m_uiClient->menuBarIsVisible(this);
3145 }
3146
3147 void WebPageProxy::setStatusBarIsVisible(bool statusBarIsVisible)
3148 {
3149     m_uiClient->setStatusBarIsVisible(this, statusBarIsVisible);
3150 }
3151
3152 void WebPageProxy::getStatusBarIsVisible(bool& statusBarIsVisible)
3153 {
3154     statusBarIsVisible = m_uiClient->statusBarIsVisible(this);
3155 }
3156
3157 void WebPageProxy::setIsResizable(bool isResizable)
3158 {
3159     m_uiClient->setIsResizable(this, isResizable);
3160 }
3161
3162 void WebPageProxy::getIsResizable(bool& isResizable)
3163 {
3164     isResizable = m_uiClient->isResizable(this);
3165 }
3166
3167 void WebPageProxy::setWindowFrame(const FloatRect& newWindowFrame)
3168 {
3169     m_uiClient->setWindowFrame(this, m_pageClient.convertToDeviceSpace(newWindowFrame));
3170 }
3171
3172 void WebPageProxy::getWindowFrame(FloatRect& newWindowFrame)
3173 {
3174     newWindowFrame = m_pageClient.convertToUserSpace(m_uiClient->windowFrame(this));
3175 }
3176     
3177 void WebPageProxy::screenToRootView(const IntPoint& screenPoint, IntPoint& windowPoint)
3178 {
3179     windowPoint = m_pageClient.screenToRootView(screenPoint);
3180 }
3181     
3182 void WebPageProxy::rootViewToScreen(const IntRect& viewRect, IntRect& result)
3183 {
3184     result = m_pageClient.rootViewToScreen(viewRect);
3185 }
3186     
3187 #if PLATFORM(IOS)
3188 void WebPageProxy::accessibilityScreenToRootView(const IntPoint& screenPoint, IntPoint& windowPoint)
3189 {
3190     windowPoint = m_pageClient.accessibilityScreenToRootView(screenPoint);
3191 }
3192
3193 void WebPageProxy::rootViewToAccessibilityScreen(const IntRect& viewRect, IntRect& result)
3194 {
3195     result = m_pageClient.rootViewToAccessibilityScreen(viewRect);
3196 }
3197 #endif
3198     
3199 void WebPageProxy::runBeforeUnloadConfirmPanel(const String& message, uint64_t frameID, bool& shouldClose)
3200 {
3201     WebFrameProxy* frame = m_process->webFrame(frameID);
3202     MESSAGE_CHECK(frame);
3203
3204     // Since runBeforeUnloadConfirmPanel() can spin a nested run loop we need to turn off the responsiveness timer.
3205     m_process->responsivenessTimer()->stop();
3206
3207     shouldClose = m_uiClient->runBeforeUnloadConfirmPanel(this, message, frame);
3208 }
3209
3210 #if USE(TILED_BACKING_STORE)
3211 void WebPageProxy::pageDidRequestScroll(const IntPoint& point)
3212 {
3213     m_pageClient.pageDidRequestScroll(point);
3214 }
3215
3216 void WebPageProxy::pageTransitionViewportReady()
3217 {
3218     m_pageClient.pageTransitionViewportReady();
3219 }
3220
3221 void WebPageProxy::didRenderFrame(const WebCore::IntSize& contentsSize, const WebCore::IntRect& coveredRect)
3222 {
3223     m_pageClient.didRenderFrame(contentsSize, coveredRect);
3224 }
3225
3226 #endif
3227
3228 void WebPageProxy::didChangeViewportProperties(const ViewportAttributes& attr)
3229 {
3230     m_pageClient.didChangeViewportProperties(attr);
3231 }
3232
3233 void WebPageProxy::pageDidScroll()
3234 {
3235     m_uiClient->pageDidScroll(this);
3236 #if PLATFORM(MAC)
3237     dismissCorrectionPanel(ReasonForDismissingAlternativeTextIgnored);
3238 #endif
3239 }
3240
3241 void WebPageProxy::runOpenPanel(uint64_t frameID, const FileChooserSettings& settings)
3242 {
3243     if (m_openPanelResultListener) {
3244         m_openPanelResultListener->invalidate();
3245         m_openPanelResultListener = 0;
3246     }
3247
3248     WebFrameProxy* frame = m_process->webFrame(frameID);
3249     MESSAGE_CHECK(frame);
3250
3251     RefPtr<WebOpenPanelParameters> parameters = WebOpenPanelParameters::create(settings);
3252     m_openPanelResultListener = WebOpenPanelResultListenerProxy::create(this);
3253
3254     // Since runOpenPanel() can spin a nested run loop we need to turn off the responsiveness timer.
3255     m_process->responsivenessTimer()->stop();
3256
3257     if (!m_uiClient->runOpenPanel(this, frame, parameters.get(), m_openPanelResultListener.get())) {
3258         if (!m_pageClient.handleRunOpenPanel(this, frame, parameters.get(), m_openPanelResultListener.get()))
3259             didCancelForOpenPanel();
3260     }
3261 }
3262
3263 void WebPageProxy::printFrame(uint64_t frameID)
3264 {
3265     ASSERT(!m_isPerformingDOMPrintOperation);
3266     m_isPerformingDOMPrintOperation = true;
3267
3268     WebFrameProxy* frame = m_process->webFrame(frameID);
3269     MESSAGE_CHECK(frame);
3270
3271     m_uiClient->printFrame(this, frame);
3272
3273     endPrinting(); // Send a message synchronously while m_isPerformingDOMPrintOperation is still true.
3274     m_isPerformingDOMPrintOperation = false;
3275 }
3276
3277 void WebPageProxy::printMainFrame()
3278 {
3279     printFrame(m_mainFrame->frameID());
3280 }
3281
3282 void WebPageProxy::setMediaVolume(float volume)
3283 {
3284     if (volume == m_mediaVolume)
3285         return;
3286     
3287     m_mediaVolume = volume;
3288     
3289     if (!isValid())
3290         return;
3291     
3292     m_process->send(Messages::WebPage::SetMediaVolume(volume), m_pageID);    
3293 }
3294
3295 void WebPageProxy::setMayStartMediaWhenInWindow(bool mayStartMedia)
3296 {
3297     if (mayStartMedia == m_mayStartMediaWhenInWindow)
3298         return;
3299
3300     m_mayStartMediaWhenInWindow = mayStartMedia;
3301
3302     if (!isValid())
3303         return;
3304
3305     process().send(Messages::WebPage::SetMayStartMediaWhenInWindow(mayStartMedia), m_pageID);
3306 }
3307
3308 void WebPageProxy::handleDownloadRequest(DownloadProxy* download)
3309 {
3310     m_pageClient.handleDownloadRequest(download);
3311 }
3312
3313 #if PLATFORM(EFL)
3314 void WebPageProxy::didChangeContentSize(const IntSize& size)
3315 {
3316     m_pageClient.didChangeContentSize(size);
3317 }
3318 #endif
3319
3320 #if ENABLE(INPUT_TYPE_COLOR)
3321 void WebPageProxy::showColorPicker(const WebCore::Color& initialColor, const IntRect& elementRect)
3322 {
3323 #if ENABLE(INPUT_TYPE_COLOR_POPOVER)
3324     // A new popover color well needs to be created (and the previous one destroyed) for
3325     // each activation of a color element.
3326     m_colorPicker = 0;
3327 #endif
3328     if (!m_colorPicker)
3329         m_colorPicker = m_pageClient.createColorPicker(this, initialColor, elementRect);
3330     m_colorPicker->showColorPicker(initialColor);
3331 }
3332
3333 void WebPageProxy::setColorPickerColor(const WebCore::Color& color)
3334 {
3335     ASSERT(m_colorPicker);
3336
3337     m_colorPicker->setSelectedColor(color);
3338 }
3339
3340 void WebPageProxy::endColorPicker()
3341 {
3342     ASSERT(m_colorPicker);
3343
3344     m_colorPicker->endPicker();
3345 }
3346
3347 void WebPageProxy::didChooseColor(const WebCore::Color& color)
3348 {
3349     if (!isValid())
3350         return;
3351
3352     m_process->send(Messages::WebPage::DidChooseColor(color), m_pageID);
3353 }
3354
3355 void WebPageProxy::didEndColorPicker()
3356 {
3357     if (!isValid())
3358         return;
3359
3360     if (m_colorPicker) {
3361         m_colorPicker->invalidate();
3362         m_colorPicker = nullptr;
3363     }
3364
3365     m_process->send(Messages::WebPage::DidEndColorPicker(), m_pageID);
3366 }
3367 #endif
3368
3369 void WebPageProxy::didDraw()
3370 {
3371     m_uiClient->didDraw(this);
3372 }
3373
3374 // Inspector
3375
3376 #if ENABLE(INSPECTOR)
3377
3378 WebInspectorProxy* WebPageProxy::inspector()
3379 {
3380     if (isClosed() || !isValid())
3381         return 0;
3382     return m_inspector.get();
3383 }
3384
3385 #endif
3386
3387 #if ENABLE(FULLSCREEN_API)
3388 WebFullScreenManagerProxy* WebPageProxy::fullScreenManager()
3389 {
3390     return m_fullScreenManager.get();
3391 }
3392 #endif
3393     
3394 #if PLATFORM(IOS)
3395 RefPtr<WebVideoFullscreenManagerProxy> WebPageProxy::videoFullscreenManager()
3396 {
3397     return m_videoFullscreenManager;
3398 }
3399 #endif
3400
3401 // BackForwardList
3402
3403 void WebPageProxy::backForwardAddItem(uint64_t itemID)
3404 {
3405     m_backForwardList->addItem(m_process->webBackForwardItem(itemID));
3406 }
3407
3408 void WebPageProxy::backForwardGoToItem(uint64_t itemID, SandboxExtension::Handle& sandboxExtensionHandle)
3409 {
3410     WebBackForwardListItem* item = m_process->webBackForwardItem(itemID);
3411     if (!item)
3412         return;
3413
3414     bool createdExtension = maybeInitializeSandboxExtensionHandle(URL(URL(), item->url()), sandboxExtensionHandle);
3415     if (createdExtension)
3416         m_process->willAcquireUniversalFileReadSandboxExtension();
3417     m_backForwardList->goToItem(item);
3418 }
3419
3420 void WebPageProxy::backForwardItemAtIndex(int32_t index, uint64_t& itemID)
3421 {
3422     WebBackForwardListItem* item = m_backForwardList->itemAtIndex(index);
3423     itemID = item ? item->itemID() : 0;
3424 }
3425
3426 void WebPageProxy::backForwardBackListCount(int32_t& count)
3427 {
3428     count = m_backForwardList->backListCount();
3429 }
3430
3431 void WebPageProxy::backForwardForwardListCount(int32_t& count)
3432 {
3433     count = m_backForwardList->forwardListCount();
3434 }
3435
3436 void WebPageProxy::editorStateChanged(const EditorState& editorState)
3437 {
3438 #if PLATFORM(COCOA)
3439     bool couldChangeSecureInputState = m_editorState.isInPasswordField != editorState.isInPasswordField || m_editorState.selectionIsNone;
3440 #endif
3441 #if PLATFORM(MAC) && !USE(ASYNC_NSTEXTINPUTCLIENT)
3442     bool closedComposition = !editorState.shouldIgnoreCompositionSelectionChange && !editorState.hasComposition && (m_editorState.hasComposition || m_temporarilyClosedComposition);
3443     m_temporarilyClosedComposition = editorState.shouldIgnoreCompositionSelectionChange && (m_temporarilyClosedComposition || m_editorState.hasComposition) && !editorState.hasComposition;
3444 #endif
3445
3446     m_editorState = editorState;
3447
3448 #if PLATFORM(COCOA)
3449     // Selection being none is a temporary state when editing. Flipping secure input state too quickly was causing trouble (not fully understood).
3450     if (couldChangeSecureInputState && !editorState.selectionIsNone)
3451         m_pageClient.updateSecureInputState();
3452 #endif
3453
3454     if (editorState.shouldIgnoreCompositionSelectionChange)
3455         return;
3456
3457 #if PLATFORM(MAC) && !USE(ASYNC_NSTEXTINPUTCLIENT)
3458     if (closedComposition)
3459         m_pageClient.notifyInputContextAboutDiscardedComposition();
3460     if (editorState.hasComposition) {
3461         // Abandon the current inline input session if selection changed for any other reason but an input method changing the composition.
3462         // FIXME: This logic should be in WebCore, no need to round-trip to UI process to cancel the composition.
3463         cancelComposition();
3464         m_pageClient.notifyInputContextAboutDiscardedComposition();
3465     }
3466 #elif PLATFORM(IOS)
3467     // We always need to notify the client on iOS to make sure the selection is redrawn,
3468     // even during composition to support phrase boundary gesture.
3469     notifyRevealedSelection();
3470 #elif PLATFORM(EFL) || PLATFORM(GTK)
3471     m_pageClient.updateTextInputState();
3472 #endif
3473 }
3474
3475 void WebPageProxy::compositionWasCanceled(const EditorState& editorState)
3476 {
3477 #if PLATFORM(COCOA)
3478     m_pageClient.notifyInputContextAboutDiscardedComposition();
3479 #endif
3480     editorStateChanged(editorState);
3481 }
3482
3483 // Undo management
3484
3485 void WebPageProxy::registerEditCommandForUndo(uint64_t commandID, uint32_t editAction)
3486 {
3487     registerEditCommand(WebEditCommandProxy::create(commandID, static_cast<EditAction>(editAction), this), Undo);
3488 }
3489     
3490 void WebPageProxy::registerInsertionUndoGrouping()
3491 {
3492 #if USE(INSERTION_UNDO_GROUPING)
3493     m_pageClient.registerInsertionUndoGrouping();
3494 #endif
3495 }
3496
3497 void WebPageProxy::canUndoRedo(uint32_t action, bool& result)
3498 {
3499     result = m_pageClient.canUndoRedo(static_cast<UndoOrRedo>(action));
3500 }
3501
3502 void WebPageProxy::executeUndoRedo(uint32_t action, bool& result)
3503 {
3504     m_pageClient.executeUndoRedo(static_cast<UndoOrRedo>(action));
3505     result = true;
3506 }
3507
3508 void WebPageProxy::clearAllEditCommands()
3509 {
3510     m_pageClient.clearAllEditCommands();
3511 }
3512
3513 void WebPageProxy::didCountStringMatches(const String& string, uint32_t matchCount)
3514 {
3515     m_findClient->didCountStringMatches(this, string, matchCount);
3516 }
3517
3518 void WebPageProxy::didGetImageForFindMatch(const ShareableBitmap::Handle& contentImageHandle, uint32_t matchIndex)
3519 {
3520     m_findMatchesClient.didGetImageForMatchResult(this, WebImage::create(ShareableBitmap::create(contentImageHandle)).get(), matchIndex);
3521 }
3522
3523 void WebPageProxy::setFindIndicator(const FloatRect& selectionRectInWindowCoordinates, const Vector<FloatRect>& textRectsInSelectionRectCoordinates, float contentImageScaleFactor, const ShareableBitmap::Handle& contentImageHandle, bool fadeOut, bool animate)
3524 {
3525     RefPtr<FindIndicator> findIndicator = FindIndicator::create(selectionRectInWindowCoordinates, textRectsInSelectionRectCoordinates, contentImageScaleFactor, contentImageHandle);
3526     m_pageClient.setFindIndicator(findIndicator.release(), fadeOut, animate);
3527 }
3528
3529 void WebPageProxy::didFindString(const String& string, uint32_t matchCount, int32_t matchIndex)
3530 {
3531     m_findClient->didFindString(this, string, matchCount, matchIndex);
3532 }
3533
3534 void WebPageProxy::didFindStringMatches(const String& string, const Vector<Vector<WebCore::IntRect>>& matchRects, int32_t firstIndexAfterSelection)
3535 {
3536     Vector<RefPtr<API::Object>> matches;
3537     matches.reserveInitialCapacity(matchRects.size());
3538
3539     for (const auto& rects : matchRects) {
3540         Vector<RefPtr<API::Object>> apiRects;
3541         apiRects.reserveInitialCapacity(rects.size());
3542
3543         for (const auto& rect : rects)
3544             apiRects.uncheckedAppend(API::Rect::create(toAPI(rect)));
3545
3546         matches.uncheckedAppend(API::Array::create(WTF::move(apiRects)));
3547     }
3548
3549     m_findMatchesClient.didFindStringMatches(this, string, API::Array::create(WTF::move(matches)).get(), firstIndexAfterSelection);
3550 }
3551
3552 void WebPageProxy::didFailToFindString(const String& string)
3553 {
3554     m_findClient->didFailToFindString(this, string);
3555 }
3556
3557 bool WebPageProxy::sendMessage(std::unique_ptr<IPC::MessageEncoder> encoder, unsigned messageSendFlags)
3558 {
3559     return m_process->sendMessage(WTF::move(encoder), messageSendFlags);
3560 }
3561
3562 IPC::Connection* WebPageProxy::messageSenderConnection()
3563 {
3564     return m_process->connection();
3565 }
3566
3567 uint64_t WebPageProxy::messageSenderDestinationID()
3568 {
3569     return m_pageID;
3570 }
3571
3572 void WebPageProxy::valueChangedForPopupMenu(WebPopupMenuProxy*, int32_t newSelectedIndex)
3573 {
3574     m_process->send(Messages::WebPage::DidChangeSelectedIndexForActivePopupMenu(newSelectedIndex), m_pageID);
3575 }
3576
3577 void WebPageProxy::setTextFromItemForPopupMenu(WebPopupMenuProxy*, int32_t index)
3578 {
3579     m_process->send(Messages::WebPage::SetTextForActivePopupMenu(index), m_pageID);
3580 }
3581
3582 NativeWebMouseEvent* WebPageProxy::currentlyProcessedMouseDownEvent()
3583 {
3584     return m_currentlyProcessedMouseDownEvent.get();
3585 }
3586
3587 void WebPageProxy::postMessageToInjectedBundle(const String& messageName, API::Object* messageBody)
3588 {
3589     process().send(Messages::WebPage::PostInjectedBundleMessage(messageName, WebContextUserMessageEncoder(messageBody, process())), m_pageID);
3590 }
3591
3592 #if PLATFORM(GTK)
3593 void WebPageProxy::failedToShowPopupMenu()
3594 {
3595     m_process->send(Messages::WebPage::FailedToShowPopupMenu(), m_pageID);
3596 }
3597 #endif
3598
3599 void WebPageProxy::showPopupMenu(const IntRect& rect, uint64_t textDirection, const Vector<WebPopupItem>& items, int32_t selectedIndex, const PlatformPopupMenuData& data)
3600 {
3601     if (m_activePopupMenu) {
3602 #if PLATFORM(EFL)
3603         m_uiPopupMenuClient.hidePopupMenu(this);
3604 #else
3605         m_activePopupMenu->hidePopupMenu();
3606 #endif
3607         m_activePopupMenu->invalidate();
3608         m_activePopupMenu = 0;
3609     }
3610
3611     m_activePopupMenu = m_pageClient.createPopupMenuProxy(this);
3612
3613     if (!m_activePopupMenu)
3614         return;
3615
3616     // Since showPopupMenu() can spin a nested run loop we need to turn off the responsiveness timer.
3617     m_process->responsivenessTimer()->stop();
3618
3619 #if PLATFORM(EFL)
3620     UNUSED_PARAM(data);
3621     m_uiPopupMenuClient.showPopupMenu(this, m_activePopupMenu.get(), rect, static_cast<TextDirection>(textDirection), m_pageScaleFactor, items, selectedIndex);
3622 #else
3623     RefPtr<WebPopupMenuProxy> protectedActivePopupMenu = m_activePopupMenu;
3624
3625     protectedActivePopupMenu->showPopupMenu(rect, static_cast<TextDirection>(textDirection), m_pageScaleFactor, items, data, selectedIndex);
3626
3627     // Since Efl doesn't use a nested mainloop to show the popup and get the answer, we need to keep the client pointer valid.
3628     // FIXME: The above comment doesn't make any sense since this code is compiled out for EFL.
3629     protectedActivePopupMenu->invalidate();
3630     protectedActivePopupMenu = 0;
3631 #endif
3632 }
3633
3634 void WebPageProxy::hidePopupMenu()
3635 {
3636     if (!m_activePopupMenu)
3637         return;
3638
3639 #if PLATFORM(EFL)
3640     m_uiPopupMenuClient.hidePopupMenu(this);