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