0575c43ede56411ee56146aa8011ddcffef4509b
[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 "APILoaderClient.h"
32 #include "APIPolicyClient.h"
33 #include "APIUIClient.h"
34 #include "APIURLRequest.h"
35 #include "AuthenticationChallengeProxy.h"
36 #include "AuthenticationDecisionListener.h"
37 #include "DataReference.h"
38 #include "DownloadProxy.h"
39 #include "DrawingAreaProxy.h"
40 #include "DrawingAreaProxyMessages.h"
41 #include "EventDispatcherMessages.h"
42 #include "FindIndicator.h"
43 #include "Logging.h"
44 #include "NativeWebKeyboardEvent.h"
45 #include "NativeWebMouseEvent.h"
46 #include "NativeWebWheelEvent.h"
47 #include "NavigationActionData.h"
48 #include "NotificationPermissionRequest.h"
49 #include "NotificationPermissionRequestManager.h"
50 #include "PageClient.h"
51 #include "PluginInformation.h"
52 #include "PluginProcessManager.h"
53 #include "PrintInfo.h"
54 #include "SessionState.h"
55 #include "TextChecker.h"
56 #include "TextCheckerState.h"
57 #include "WKContextPrivate.h"
58 #include "WebBackForwardList.h"
59 #include "WebBackForwardListItem.h"
60 #include "WebCertificateInfo.h"
61 #include "WebContext.h"
62 #include "WebContextMenuProxy.h"
63 #include "WebContextUserMessageCoders.h"
64 #include "WebCoreArgumentCoders.h"
65 #include "WebEditCommandProxy.h"
66 #include "WebEvent.h"
67 #include "WebEventConversion.h"
68 #include "WebFormSubmissionListenerProxy.h"
69 #include "WebFramePolicyListenerProxy.h"
70 #include "WebFullScreenManagerProxy.h"
71 #include "WebFullScreenManagerProxyMessages.h"
72 #include "WebInspectorProxy.h"
73 #include "WebInspectorProxyMessages.h"
74 #include "WebNotificationManagerProxy.h"
75 #include "WebOpenPanelParameters.h"
76 #include "WebOpenPanelResultListenerProxy.h"
77 #include "WebPageCreationParameters.h"
78 #include "WebPageGroup.h"
79 #include "WebPageGroupData.h"
80 #include "WebPageMessages.h"
81 #include "WebPageProxyMessages.h"
82 #include "WebPopupItem.h"
83 #include "WebPopupMenuProxy.h"
84 #include "WebPreferences.h"
85 #include "WebProcessMessages.h"
86 #include "WebProcessProxy.h"
87 #include "WebProtectionSpace.h"
88 #include "WebSecurityOrigin.h"
89 #include <WebCore/DragController.h>
90 #include <WebCore/DragData.h>
91 #include <WebCore/DragSession.h>
92 #include <WebCore/FloatRect.h>
93 #include <WebCore/FocusDirection.h>
94 #include <WebCore/MIMETypeRegistry.h>
95 #include <WebCore/RenderEmbeddedObject.h>
96 #include <WebCore/SerializedCryptoKeyWrap.h>
97 #include <WebCore/TextCheckerClient.h>
98 #include <WebCore/WindowFeatures.h>
99 #include <stdio.h>
100 #include <wtf/NeverDestroyed.h>
101 #include <wtf/text/StringView.h>
102
103 #if ENABLE(ASYNC_SCROLLING)
104 #include "RemoteScrollingCoordinatorProxy.h"
105 #endif
106
107 #if USE(COORDINATED_GRAPHICS)
108 #include "CoordinatedLayerTreeHostProxyMessages.h"
109 #endif
110
111 #if PLATFORM(GTK)
112 #include "ArgumentCodersGtk.h"
113 #endif
114
115 #if USE(SOUP) && !ENABLE(CUSTOM_PROTOCOLS)
116 #include "WebSoupRequestManagerProxy.h"
117 #endif
118
119 #if ENABLE(VIBRATION)
120 #include "WebVibrationProxy.h"
121 #endif
122
123 #ifndef NDEBUG
124 #include <wtf/RefCountedLeakCounter.h>
125 #endif
126
127 #if ENABLE(NETWORK_PROCESS)
128 #include "NetworkProcessMessages.h"
129 #endif
130
131 #if PLATFORM(COCOA)
132 #include "ViewSnapshotStore.h"
133 #endif
134
135 #if PLATFORM(IOS)
136 #include "WebVideoFullscreenManagerProxy.h"
137 #include "WebVideoFullscreenManagerProxyMessages.h"
138 #endif
139
140 // This controls what strategy we use for mouse wheel coalescing.
141 #define MERGE_WHEEL_EVENTS 1
142
143 #define MESSAGE_CHECK(assertion) MESSAGE_CHECK_BASE(assertion, m_process->connection())
144 #define MESSAGE_CHECK_URL(url) MESSAGE_CHECK_BASE(m_process->checkURLReceivedFromWebProcess(url), m_process->connection())
145
146 using namespace WebCore;
147
148 // Represents the number of wheel events we can hold in the queue before we start pushing them preemptively.
149 static const unsigned wheelEventQueueSizeThreshold = 10;
150
151 namespace WebKit {
152
153 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, webPageProxyCounter, ("WebPageProxy"));
154
155 class ExceededDatabaseQuotaRecords {
156     WTF_MAKE_NONCOPYABLE(ExceededDatabaseQuotaRecords); WTF_MAKE_FAST_ALLOCATED;
157     friend class NeverDestroyed<ExceededDatabaseQuotaRecords>;
158 public:
159     struct Record {
160         uint64_t frameID;
161         String originIdentifier;
162         String databaseName;
163         String displayName;
164         uint64_t currentQuota;
165         uint64_t currentOriginUsage;
166         uint64_t currentDatabaseUsage;
167         uint64_t expectedUsage;
168         RefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply> reply;
169     };
170
171     static ExceededDatabaseQuotaRecords& shared();
172
173     PassOwnPtr<Record> createRecord(uint64_t frameID, String originIdentifier,
174         String databaseName, String displayName, uint64_t currentQuota,
175         uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage, 
176         PassRefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply>);
177
178     void add(PassOwnPtr<Record>);
179     bool areBeingProcessed() const { return m_currentRecord; }
180     Record* next();
181
182 private:
183     ExceededDatabaseQuotaRecords() { }
184     ~ExceededDatabaseQuotaRecords() { }
185
186     Deque<OwnPtr<Record>> m_records;
187     OwnPtr<Record> m_currentRecord;
188 };
189
190 ExceededDatabaseQuotaRecords& ExceededDatabaseQuotaRecords::shared()
191 {
192     static NeverDestroyed<ExceededDatabaseQuotaRecords> records;
193     return records;
194 }
195
196 PassOwnPtr<ExceededDatabaseQuotaRecords::Record> ExceededDatabaseQuotaRecords::createRecord(
197     uint64_t frameID, String originIdentifier, String databaseName, String displayName,
198     uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage,
199     uint64_t expectedUsage, PassRefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply> reply)
200 {
201     OwnPtr<Record> record = adoptPtr(new Record);
202     record->frameID = frameID;
203     record->originIdentifier = originIdentifier;
204     record->databaseName = databaseName;
205     record->displayName = displayName;
206     record->currentQuota = currentQuota;
207     record->currentOriginUsage = currentOriginUsage;
208     record->currentDatabaseUsage = currentDatabaseUsage;
209     record->expectedUsage = expectedUsage;
210     record->reply = reply;
211     return record.release();
212 }
213
214 void ExceededDatabaseQuotaRecords::add(PassOwnPtr<ExceededDatabaseQuotaRecords::Record> record)
215 {
216     m_records.append(record);
217 }
218
219 ExceededDatabaseQuotaRecords::Record* ExceededDatabaseQuotaRecords::next()
220 {
221     m_currentRecord.clear();
222     if (!m_records.isEmpty())
223         m_currentRecord = m_records.takeFirst();
224     return m_currentRecord.get();
225 }
226
227 #if !LOG_DISABLED
228 static const char* webKeyboardEventTypeString(WebEvent::Type type)
229 {
230     switch (type) {
231     case WebEvent::KeyDown:
232         return "KeyDown";
233     
234     case WebEvent::KeyUp:
235         return "KeyUp";
236     
237     case WebEvent::RawKeyDown:
238         return "RawKeyDown";
239     
240     case WebEvent::Char:
241         return "Char";
242     
243     default:
244         ASSERT_NOT_REACHED();
245         return "<unknown>";
246     }
247 }
248 #endif // !LOG_DISABLED
249
250 PassRefPtr<WebPageProxy> WebPageProxy::create(PageClient& pageClient, WebProcessProxy& process, uint64_t pageID, const WebPageConfiguration& configuration)
251 {
252     return adoptRef(new WebPageProxy(pageClient, process, pageID, configuration));
253 }
254
255 WebPageProxy::WebPageProxy(PageClient& pageClient, WebProcessProxy& process, uint64_t pageID, const WebPageConfiguration& configuration)
256     : m_pageClient(pageClient)
257     , m_loaderClient(std::make_unique<API::LoaderClient>())
258     , m_policyClient(std::make_unique<API::PolicyClient>())
259     , m_uiClient(std::make_unique<API::UIClient>())
260     , m_process(process)
261     , m_pageGroup(*configuration.pageGroup)
262     , m_preferences(*configuration.preferences)
263     , m_visitedLinkProvider(*configuration.visitedLinkProvider)
264     , m_mainFrame(nullptr)
265     , m_userAgent(standardUserAgent())
266     , m_geolocationPermissionRequestManager(*this)
267     , m_notificationPermissionRequestManager(*this)
268     , m_viewState(ViewState::NoFlags)
269     , m_backForwardList(WebBackForwardList::create(*this))
270     , m_loadStateAtProcessExit(FrameLoadState::State::Finished)
271     , m_temporarilyClosedComposition(false)
272     , m_textZoomFactor(1)
273     , m_pageZoomFactor(1)
274     , m_pageScaleFactor(1)
275     , m_intrinsicDeviceScaleFactor(1)
276     , m_customDeviceScaleFactor(0)
277     , m_layerHostingMode(LayerHostingMode::InProcess)
278     , m_drawsBackground(true)
279     , m_drawsTransparentBackground(false)
280     , m_areMemoryCacheClientCallsEnabled(true)
281     , m_useFixedLayout(false)
282     , m_suppressScrollbarAnimations(false)
283     , m_paginationMode(Pagination::Unpaginated)
284     , m_paginationBehavesLikeColumns(false)
285     , m_pageLength(0)
286     , m_gapBetweenPages(0)
287     , m_isValid(true)
288     , m_isClosed(false)
289     , m_canRunModal(false)
290     , m_isInPrintingMode(false)
291     , m_isPerformingDOMPrintOperation(false)
292     , m_inDecidePolicyForResponseSync(false)
293     , m_decidePolicyForResponseRequest(0)
294     , m_syncMimeTypePolicyActionIsValid(false)
295     , m_syncMimeTypePolicyAction(PolicyUse)
296     , m_syncMimeTypePolicyDownloadID(0)
297     , m_inDecidePolicyForNavigationAction(false)
298     , m_syncNavigationActionPolicyActionIsValid(false)
299     , m_syncNavigationActionPolicyAction(PolicyUse)
300     , m_syncNavigationActionPolicyDownloadID(0)
301     , m_processingMouseMoveEvent(false)
302 #if ENABLE(TOUCH_EVENTS)
303     , m_isTrackingTouchEvents(false)
304 #endif
305     , m_pageID(pageID)
306     , m_session(*configuration.session)
307     , m_isPageSuspended(false)
308 #if ENABLE(REMOTE_INSPECTOR)
309     , m_allowsRemoteInspection(true)
310 #endif
311 #if PLATFORM(COCOA)
312     , m_isSmartInsertDeleteEnabled(TextChecker::isSmartInsertDeleteEnabled())
313 #endif
314     , m_spellDocumentTag(0)
315     , m_hasSpellDocumentTag(false)
316     , m_pendingLearnOrIgnoreWordMessageCount(0)
317     , m_mainFrameHasCustomContentProvider(false)
318     , m_delegatesScrolling(false)
319     , m_mainFrameHasHorizontalScrollbar(false)
320     , m_mainFrameHasVerticalScrollbar(false)
321     , m_canShortCircuitHorizontalWheelEvents(true)
322     , m_mainFrameIsPinnedToLeftSide(false)
323     , m_mainFrameIsPinnedToRightSide(false)
324     , m_mainFrameIsPinnedToTopSide(false)
325     , m_mainFrameIsPinnedToBottomSide(false)
326     , m_shouldUseImplicitRubberBandControl(false)
327     , m_rubberBandsAtLeft(true)
328     , m_rubberBandsAtRight(true)
329     , m_rubberBandsAtTop(true)
330     , m_rubberBandsAtBottom(true)
331     , m_backgroundExtendsBeyondPage(false)
332     , m_shouldRecordNavigationSnapshots(false)
333     , m_pageCount(0)
334     , m_renderTreeSize(0)
335     , m_shouldSendEventsSynchronously(false)
336     , m_suppressVisibilityUpdates(false)
337     , m_autoSizingShouldExpandToViewHeight(false)
338     , m_mediaVolume(1)
339     , m_mayStartMediaWhenInWindow(true)
340     , m_waitingForDidUpdateViewState(false)
341     , m_scrollPinningBehavior(DoNotPin)
342     , m_navigationID(0)
343 {
344     if (m_process->state() == WebProcessProxy::State::Running)
345         m_visitedLinkProvider->addProcess(m_process.get());
346
347     updateViewState();
348
349 #if HAVE(OUT_OF_PROCESS_LAYER_HOSTING)
350     m_layerHostingMode = m_viewState & ViewState::IsInWindow ? m_pageClient.viewLayerHostingMode() : LayerHostingMode::OutOfProcess;
351 #endif
352
353     platformInitialize();
354
355 #ifndef NDEBUG
356     webPageProxyCounter.increment();
357 #endif
358
359     WebContext::statistics().wkPageCount++;
360
361     m_preferences->addPage(*this);
362     m_pageGroup->addPage(this);
363
364 #if ENABLE(INSPECTOR)
365     m_inspector = WebInspectorProxy::create(this);
366 #endif
367 #if ENABLE(FULLSCREEN_API)
368     m_fullScreenManager = WebFullScreenManagerProxy::create(*this, m_pageClient.fullScreenManagerProxyClient());
369 #endif
370 #if PLATFORM(IOS)
371     m_videoFullscreenManager = WebVideoFullscreenManagerProxy::create(*this);
372 #endif
373 #if ENABLE(VIBRATION)
374     m_vibration = WebVibrationProxy::create(this);
375 #endif
376
377     m_process->addMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID, *this);
378
379     // FIXME: If we ever expose the session storage size as a preference, we need to pass it here.
380     IPC::Connection* connection = m_process->state() == WebProcessProxy::State::Running ? m_process->connection() : nullptr;
381     m_process->context().storageManager().createSessionStorageNamespace(m_pageID, connection, std::numeric_limits<unsigned>::max());
382     setSession(*configuration.session);
383 }
384
385 WebPageProxy::~WebPageProxy()
386 {
387     if (!m_isClosed)
388         close();
389
390     WebContext::statistics().wkPageCount--;
391
392     if (m_hasSpellDocumentTag)
393         TextChecker::closeSpellDocumentWithTag(m_spellDocumentTag);
394
395     m_preferences->removePage(*this);
396     m_pageGroup->removePage(this);
397
398 #ifndef NDEBUG
399     webPageProxyCounter.decrement();
400 #endif
401 }
402
403 PlatformProcessIdentifier WebPageProxy::processIdentifier() const
404 {
405     if (m_isClosed)
406         return 0;
407
408     return m_process->processIdentifier();
409 }
410
411 bool WebPageProxy::isValid() const
412 {
413     // A page that has been explicitly closed is never valid.
414     if (m_isClosed)
415         return false;
416
417     return m_isValid;
418 }
419
420 void WebPageProxy::setPreferences(WebPreferences& preferences)
421 {
422     if (&preferences == &m_preferences.get())
423         return;
424
425     m_preferences->removePage(*this);
426     m_preferences = preferences;
427     m_preferences->addPage(*this);
428
429     preferencesDidChange();
430 }
431
432 void WebPageProxy::setLoaderClient(std::unique_ptr<API::LoaderClient> loaderClient)
433 {
434     if (!loaderClient) {
435         m_loaderClient = std::make_unique<API::LoaderClient>();
436         return;
437     }
438
439     m_loaderClient = std::move(loaderClient);
440 }
441
442 void WebPageProxy::setPolicyClient(std::unique_ptr<API::PolicyClient> policyClient)
443 {
444     if (!policyClient) {
445         m_policyClient = std::make_unique<API::PolicyClient>();
446         return;
447     }
448
449     m_policyClient = std::move(policyClient);
450 }
451
452 void WebPageProxy::initializeFormClient(const WKPageFormClientBase* formClient)
453 {
454     m_formClient.initialize(formClient);
455 }
456
457 void WebPageProxy::setUIClient(std::unique_ptr<API::UIClient> uiClient)
458 {
459     if (!uiClient) {
460         m_uiClient = std::make_unique<API::UIClient>();
461         return;
462     }
463
464     m_uiClient = std::move(uiClient);
465
466     if (!isValid())
467         return;
468
469     m_process->send(Messages::WebPage::SetCanRunBeforeUnloadConfirmPanel(m_uiClient->canRunBeforeUnloadConfirmPanel()), m_pageID);
470     setCanRunModal(m_uiClient->canRunModal());
471 }
472
473 void WebPageProxy::initializeFindClient(const WKPageFindClientBase* client)
474 {
475     m_findClient.initialize(client);
476 }
477
478 void WebPageProxy::initializeFindMatchesClient(const WKPageFindMatchesClientBase* client)
479 {
480     m_findMatchesClient.initialize(client);
481 }
482
483 #if ENABLE(CONTEXT_MENUS)
484 void WebPageProxy::initializeContextMenuClient(const WKPageContextMenuClientBase* client)
485 {
486     m_contextMenuClient.initialize(client);
487 }
488 #endif
489
490 void WebPageProxy::reattachToWebProcess()
491 {
492     ASSERT(!isValid());
493     ASSERT(m_process->state() == WebProcessProxy::State::Terminated);
494
495     updateViewState();
496
497     m_isValid = true;
498
499     if (m_process->context().processModel() == ProcessModelSharedSecondaryProcess)
500         m_process = m_process->context().ensureSharedWebProcess();
501     else
502         m_process = m_process->context().createNewWebProcessRespectingProcessCountLimit();
503     m_process->addExistingWebPage(this, m_pageID);
504     m_process->addMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID, *this);
505
506 #if ENABLE(INSPECTOR)
507     m_inspector = WebInspectorProxy::create(this);
508 #endif
509 #if ENABLE(FULLSCREEN_API)
510     m_fullScreenManager = WebFullScreenManagerProxy::create(*this, m_pageClient.fullScreenManagerProxyClient());
511 #endif
512
513     initializeWebPage();
514
515     m_pageClient.didRelaunchProcess();
516     m_drawingArea->waitForBackingStoreUpdateOnNextPaint();
517 }
518
519 void WebPageProxy::reattachToWebProcessWithItem(WebBackForwardListItem* item)
520 {
521     if (item && item != m_backForwardList->currentItem())
522         m_backForwardList->goToItem(item);
523     
524     reattachToWebProcess();
525
526     if (!item)
527         return;
528
529     m_process->send(Messages::WebPage::GoToBackForwardItem(item->itemID()), m_pageID);
530     m_process->responsivenessTimer()->start();
531 }
532
533 void WebPageProxy::setSession(API::Session& session)
534 {
535     m_session = session;
536     m_process->send(Messages::WebPage::SetSessionID(session.getID()), m_pageID);
537
538 #if ENABLE(NETWORK_PROCESS)
539     if (session.isEphemeral())
540         m_process->context().sendToNetworkingProcess(Messages::NetworkProcess::EnsurePrivateBrowsingSession(session.getID()));
541 #endif
542 }
543
544 void WebPageProxy::initializeWebPage()
545 {
546     ASSERT(isValid());
547
548     BackForwardListItemVector items = m_backForwardList->entries();
549     for (size_t i = 0; i < items.size(); ++i)
550         m_process->registerNewWebBackForwardListItem(items[i].get());
551
552     m_drawingArea = m_pageClient.createDrawingAreaProxy();
553     ASSERT(m_drawingArea);
554
555 #if ENABLE(ASYNC_SCROLLING)
556     if (m_drawingArea->type() == DrawingAreaTypeRemoteLayerTree)
557         m_scrollingCoordinatorProxy = std::make_unique<RemoteScrollingCoordinatorProxy>(*this);
558 #endif
559
560 #if ENABLE(INSPECTOR_SERVER)
561     if (pageGroup().preferences().developerExtrasEnabled())
562         inspector()->enableRemoteInspection();
563 #endif
564
565     process().send(Messages::WebProcess::CreateWebPage(m_pageID, creationParameters()), 0);
566
567 #if PLATFORM(COCOA)
568     send(Messages::WebPage::SetSmartInsertDeleteEnabled(m_isSmartInsertDeleteEnabled));
569 #endif
570 }
571
572 bool WebPageProxy::isProcessSuppressible() const
573 {
574     return (m_viewState & ViewState::IsVisuallyIdle) && m_preferences->pageVisibilityBasedProcessSuppressionEnabled();
575 }
576
577 void WebPageProxy::close()
578 {
579     if (!isValid())
580         return;
581
582     m_isClosed = true;
583
584     if (m_process->state() == WebProcessProxy::State::Running)
585         m_visitedLinkProvider->removeProcess(m_process.get());
586
587     m_backForwardList->pageClosed();
588     m_pageClient.pageClosed();
589
590     m_process->disconnectFramesFromPage(this);
591
592     resetState();
593
594     m_loaderClient = std::make_unique<API::LoaderClient>();
595     m_policyClient = std::make_unique<API::PolicyClient>();
596     m_formClient.initialize(0);
597     m_uiClient = std::make_unique<API::UIClient>();
598 #if PLATFORM(EFL)
599     m_uiPopupMenuClient.initialize(0);
600 #endif
601     m_findClient.initialize(0);
602     m_findMatchesClient.initialize(0);
603 #if ENABLE(CONTEXT_MENUS)
604     m_contextMenuClient.initialize(0);
605 #endif
606
607     m_process->send(Messages::WebPage::Close(), m_pageID);
608     m_process->removeWebPage(m_pageID);
609     m_process->removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID);
610     m_process->context().storageManager().destroySessionStorageNamespace(m_pageID);
611     m_process->context().supplement<WebNotificationManagerProxy>()->clearNotifications(this);
612 }
613
614 bool WebPageProxy::tryClose()
615 {
616     if (!isValid())
617         return true;
618
619     m_process->send(Messages::WebPage::TryClose(), m_pageID);
620     m_process->responsivenessTimer()->start();
621     return false;
622 }
623
624 bool WebPageProxy::maybeInitializeSandboxExtensionHandle(const URL& url, SandboxExtension::Handle& sandboxExtensionHandle)
625 {
626     if (!url.isLocalFile())
627         return false;
628
629 #if ENABLE(INSPECTOR)
630     // Don't give the inspector full access to the file system.
631     if (WebInspectorProxy::isInspectorPage(*this))
632         return false;
633 #endif
634
635     SandboxExtension::createHandle("/", SandboxExtension::ReadOnly, sandboxExtensionHandle);
636     return true;
637 }
638
639 uint64_t WebPageProxy::loadRequest(const ResourceRequest& request, API::Object* userData)
640 {
641     uint64_t navigationID = generateNavigationID();
642
643     auto transaction = m_pageLoadState.transaction();
644
645     m_pageLoadState.setPendingAPIRequestURL(transaction, request.url());
646
647     if (!isValid())
648         reattachToWebProcess();
649
650     SandboxExtension::Handle sandboxExtensionHandle;
651     bool createdExtension = maybeInitializeSandboxExtensionHandle(request.url(), sandboxExtensionHandle);
652     if (createdExtension)
653         m_process->willAcquireUniversalFileReadSandboxExtension();
654     m_process->send(Messages::WebPage::LoadRequest(navigationID, request, sandboxExtensionHandle, WebContextUserMessageEncoder(userData, process())), m_pageID);
655     m_process->responsivenessTimer()->start();
656
657     return navigationID;
658 }
659
660 void WebPageProxy::loadFile(const String& fileURLString, const String& resourceDirectoryURLString, API::Object* userData)
661 {
662     if (!isValid())
663         reattachToWebProcess();
664
665     URL fileURL = URL(URL(), fileURLString);
666     if (!fileURL.isLocalFile())
667         return;
668
669     URL resourceDirectoryURL;
670     if (resourceDirectoryURLString.isNull())
671         resourceDirectoryURL = URL(ParsedURLString, ASCIILiteral("file:///"));
672     else {
673         resourceDirectoryURL = URL(URL(), resourceDirectoryURLString);
674         if (!resourceDirectoryURL.isLocalFile())
675             return;
676     }
677
678     String resourceDirectoryPath = resourceDirectoryURL.fileSystemPath();
679
680     SandboxExtension::Handle sandboxExtensionHandle;
681     SandboxExtension::createHandle(resourceDirectoryPath, SandboxExtension::ReadOnly, sandboxExtensionHandle);
682     m_process->assumeReadAccessToBaseURL(resourceDirectoryURL);
683     m_process->send(Messages::WebPage::LoadRequest(generateNavigationID(), fileURL, sandboxExtensionHandle, WebContextUserMessageEncoder(userData, process())), m_pageID);
684     m_process->responsivenessTimer()->start();
685 }
686
687 void WebPageProxy::loadData(API::Data* data, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData)
688 {
689     if (!isValid())
690         reattachToWebProcess();
691
692     m_process->assumeReadAccessToBaseURL(baseURL);
693     m_process->send(Messages::WebPage::LoadData(data->dataReference(), MIMEType, encoding, baseURL, WebContextUserMessageEncoder(userData, process())), m_pageID);
694     m_process->responsivenessTimer()->start();
695 }
696
697 void WebPageProxy::loadHTMLString(const String& htmlString, const String& baseURL, API::Object* userData)
698 {
699     if (!isValid())
700         reattachToWebProcess();
701
702     m_process->assumeReadAccessToBaseURL(baseURL);
703     m_process->send(Messages::WebPage::LoadHTMLString(htmlString, baseURL, WebContextUserMessageEncoder(userData, process())), m_pageID);
704     m_process->responsivenessTimer()->start();
705 }
706
707 void WebPageProxy::loadAlternateHTMLString(const String& htmlString, const String& baseURL, const String& unreachableURL, API::Object* userData)
708 {
709     if (!isValid())
710         reattachToWebProcess();
711
712     auto transaction = m_pageLoadState.transaction();
713
714     m_pageLoadState.setUnreachableURL(transaction, unreachableURL);
715
716     if (m_mainFrame)
717         m_mainFrame->setUnreachableURL(unreachableURL);
718
719     m_process->assumeReadAccessToBaseURL(baseURL);
720     m_process->send(Messages::WebPage::LoadAlternateHTMLString(htmlString, baseURL, unreachableURL, WebContextUserMessageEncoder(userData, process())), m_pageID);
721     m_process->responsivenessTimer()->start();
722 }
723
724 void WebPageProxy::loadPlainTextString(const String& string, API::Object* userData)
725 {
726     if (!isValid())
727         reattachToWebProcess();
728
729     m_process->send(Messages::WebPage::LoadPlainTextString(string, WebContextUserMessageEncoder(userData, process())), m_pageID);
730     m_process->responsivenessTimer()->start();
731 }
732
733 void WebPageProxy::loadWebArchiveData(API::Data* webArchiveData, API::Object* userData)
734 {
735     if (!isValid())
736         reattachToWebProcess();
737
738     m_process->send(Messages::WebPage::LoadWebArchiveData(webArchiveData->dataReference(), WebContextUserMessageEncoder(userData, process())), m_pageID);
739     m_process->responsivenessTimer()->start();
740 }
741
742 void WebPageProxy::stopLoading()
743 {
744     if (!isValid())
745         return;
746
747     m_process->send(Messages::WebPage::StopLoading(), m_pageID);
748     m_process->responsivenessTimer()->start();
749 }
750
751 void WebPageProxy::reload(bool reloadFromOrigin)
752 {
753     SandboxExtension::Handle sandboxExtensionHandle;
754
755     if (m_backForwardList->currentItem()) {
756         String url = m_backForwardList->currentItem()->url();
757         auto transaction = m_pageLoadState.transaction();
758         m_pageLoadState.setPendingAPIRequestURL(transaction, url);
759
760         // We may not have an extension yet if back/forward list was reinstated after a WebProcess crash or a browser relaunch
761         bool createdExtension = maybeInitializeSandboxExtensionHandle(URL(URL(), url), sandboxExtensionHandle);
762         if (createdExtension)
763             m_process->willAcquireUniversalFileReadSandboxExtension();
764     }
765
766     if (!isValid()) {
767         reattachToWebProcessWithItem(m_backForwardList->currentItem());
768         return;
769     }
770
771     m_process->send(Messages::WebPage::Reload(generateNavigationID(), reloadFromOrigin, sandboxExtensionHandle), m_pageID);
772     m_process->responsivenessTimer()->start();
773 }
774
775 void WebPageProxy::recordNavigationSnapshot()
776 {
777     if (!m_shouldRecordNavigationSnapshots)
778         return;
779
780 #if PLATFORM(COCOA)
781     ViewSnapshotStore::shared().recordSnapshot(*this);
782 #endif
783 }
784
785 void WebPageProxy::goForward()
786 {
787     WebBackForwardListItem* forwardItem = m_backForwardList->forwardItem();
788     if (!forwardItem)
789         return;
790
791     recordNavigationSnapshot();
792
793     auto transaction = m_pageLoadState.transaction();
794
795     m_pageLoadState.setPendingAPIRequestURL(transaction, forwardItem->url());
796
797     if (!isValid()) {
798         reattachToWebProcessWithItem(forwardItem);
799         return;
800     }
801
802     m_process->send(Messages::WebPage::GoForward(forwardItem->itemID()), m_pageID);
803     m_process->responsivenessTimer()->start();
804 }
805
806 void WebPageProxy::goBack()
807 {
808     WebBackForwardListItem* backItem = m_backForwardList->backItem();
809     if (!backItem)
810         return;
811
812     recordNavigationSnapshot();
813
814     auto transaction = m_pageLoadState.transaction();
815
816     m_pageLoadState.setPendingAPIRequestURL(transaction, backItem->url());
817
818     if (!isValid()) {
819         reattachToWebProcessWithItem(backItem);
820         return;
821     }
822
823     m_process->send(Messages::WebPage::GoBack(backItem->itemID()), m_pageID);
824     m_process->responsivenessTimer()->start();
825 }
826
827 void WebPageProxy::goToBackForwardItem(WebBackForwardListItem* item)
828 {
829     if (!isValid()) {
830         reattachToWebProcessWithItem(item);
831         return;
832     }
833
834     recordNavigationSnapshot();
835     
836     auto transaction = m_pageLoadState.transaction();
837
838     m_pageLoadState.setPendingAPIRequestURL(transaction, item->url());
839
840     m_process->send(Messages::WebPage::GoToBackForwardItem(item->itemID()), m_pageID);
841     m_process->responsivenessTimer()->start();
842 }
843
844 void WebPageProxy::tryRestoreScrollPosition()
845 {
846     if (!isValid())
847         return;
848
849     m_process->send(Messages::WebPage::TryRestoreScrollPosition(), m_pageID);
850 }
851
852 void WebPageProxy::didChangeBackForwardList(WebBackForwardListItem* added, Vector<RefPtr<WebBackForwardListItem>> removed)
853 {
854     m_loaderClient->didChangeBackForwardList(this, added, std::move(removed));
855
856 #if PLATFORM(MAC)
857     m_pageClient.clearCustomSwipeViews();
858 #endif
859 }
860
861 void WebPageProxy::willGoToBackForwardListItem(uint64_t itemID, IPC::MessageDecoder& decoder)
862 {
863     RefPtr<API::Object> userData;
864     WebContextUserMessageDecoder messageDecoder(userData, process());
865     if (!decoder.decode(messageDecoder))
866         return;
867
868     if (WebBackForwardListItem* item = m_process->webBackForwardItem(itemID))
869         m_loaderClient->willGoToBackForwardListItem(this, item, userData.get());
870 }
871
872 bool WebPageProxy::canShowMIMEType(const String& mimeType)
873 {
874     if (MIMETypeRegistry::canShowMIMEType(mimeType))
875         return true;
876
877 #if ENABLE(NETSCAPE_PLUGIN_API)
878     String newMimeType = mimeType;
879     PluginModuleInfo plugin = m_process->context().pluginInfoStore().findPlugin(newMimeType, URL());
880     if (!plugin.path.isNull() && m_preferences->pluginsEnabled())
881         return true;
882 #endif // ENABLE(NETSCAPE_PLUGIN_API)
883
884 #if PLATFORM(COCOA)
885     // On Mac, we can show PDFs.
886     if (MIMETypeRegistry::isPDFOrPostScriptMIMEType(mimeType) && !WebContext::omitPDFSupport())
887         return true;
888 #endif // PLATFORM(COCOA)
889
890     return false;
891 }
892
893 #if ENABLE(REMOTE_INSPECTOR)
894 void WebPageProxy::setAllowsRemoteInspection(bool allow)
895 {
896     if (m_allowsRemoteInspection == allow)
897         return;
898
899     m_allowsRemoteInspection = allow;
900
901     if (isValid())
902         m_process->send(Messages::WebPage::SetAllowsRemoteInspection(allow), m_pageID);
903 }
904 #endif
905
906 void WebPageProxy::setDrawsBackground(bool drawsBackground)
907 {
908     if (m_drawsBackground == drawsBackground)
909         return;
910
911     m_drawsBackground = drawsBackground;
912
913     if (isValid())
914         m_process->send(Messages::WebPage::SetDrawsBackground(drawsBackground), m_pageID);
915 }
916
917 void WebPageProxy::setDrawsTransparentBackground(bool drawsTransparentBackground)
918 {
919     if (m_drawsTransparentBackground == drawsTransparentBackground)
920         return;
921
922     m_drawsTransparentBackground = drawsTransparentBackground;
923
924     if (isValid())
925         m_process->send(Messages::WebPage::SetDrawsTransparentBackground(drawsTransparentBackground), m_pageID);
926 }
927
928 void WebPageProxy::setUnderlayColor(const Color& color)
929 {
930     if (m_underlayColor == color)
931         return;
932
933     m_underlayColor = color;
934
935     if (isValid())
936         m_process->send(Messages::WebPage::SetUnderlayColor(color), m_pageID);
937 }
938
939 void WebPageProxy::viewWillStartLiveResize()
940 {
941     if (!isValid())
942         return;
943 #if ENABLE(INPUT_TYPE_COLOR_POPOVER)
944     if (m_colorPicker)
945         endColorPicker();
946 #endif
947     m_process->send(Messages::WebPage::ViewWillStartLiveResize(), m_pageID);
948 }
949
950 void WebPageProxy::viewWillEndLiveResize()
951 {
952     if (!isValid())
953         return;
954     m_process->send(Messages::WebPage::ViewWillEndLiveResize(), m_pageID);
955 }
956
957 void WebPageProxy::setViewNeedsDisplay(const IntRect& rect)
958 {
959     m_pageClient.setViewNeedsDisplay(rect);
960 }
961
962 void WebPageProxy::displayView()
963 {
964     m_pageClient.displayView();
965 }
966
967 bool WebPageProxy::canScrollView()
968 {
969     return m_pageClient.canScrollView();
970 }
971
972 void WebPageProxy::scrollView(const IntRect& scrollRect, const IntSize& scrollOffset)
973 {
974     m_pageClient.scrollView(scrollRect, scrollOffset);
975 }
976
977 void WebPageProxy::updateViewState(ViewState::Flags flagsToUpdate)
978 {
979     m_viewState &= ~flagsToUpdate;
980     if (flagsToUpdate & ViewState::IsFocused && m_pageClient.isViewFocused())
981         m_viewState |= ViewState::IsFocused;
982     if (flagsToUpdate & ViewState::WindowIsActive && m_pageClient.isViewWindowActive())
983         m_viewState |= ViewState::WindowIsActive;
984     if (flagsToUpdate & ViewState::IsVisible && m_pageClient.isViewVisible())
985         m_viewState |= ViewState::IsVisible;
986     if (flagsToUpdate & ViewState::IsVisibleOrOccluded && m_pageClient.isViewVisibleOrOccluded())
987         m_viewState |= ViewState::IsVisibleOrOccluded;
988     if (flagsToUpdate & ViewState::IsInWindow && m_pageClient.isViewInWindow())
989         m_viewState |= ViewState::IsInWindow;
990     if (flagsToUpdate & ViewState::IsVisuallyIdle && m_pageClient.isVisuallyIdle())
991         m_viewState |= ViewState::IsVisuallyIdle;
992 }
993
994 void WebPageProxy::viewStateDidChange(ViewState::Flags mayHaveChanged, WantsReplyOrNot wantsReply)
995 {
996     if (!isValid())
997         return;
998
999     // If the visibility state may have changed, then so may the visually idle & occluded agnostic state.
1000     if (mayHaveChanged & ViewState::IsVisible)
1001         mayHaveChanged |= ViewState::IsVisibleOrOccluded | ViewState::IsVisuallyIdle;
1002
1003     // Record the prior view state, update the flags that may have changed,
1004     // and check which flags have actually changed.
1005     ViewState::Flags previousViewState = m_viewState;
1006     updateViewState(mayHaveChanged);
1007     ViewState::Flags changed = m_viewState ^ previousViewState;
1008
1009     if (changed)
1010         m_process->send(Messages::WebPage::SetViewState(m_viewState, wantsReply == WantsReplyOrNot::DoesWantReply), m_pageID);
1011
1012     if (changed & ViewState::IsVisuallyIdle)
1013         m_process->pageSuppressibilityChanged(this);
1014
1015     // If we've started the responsiveness timer as part of telling the web process to update the backing store
1016     // state, it might not send back a reply (since it won't paint anything if the web page is hidden) so we
1017     // stop the unresponsiveness timer here.
1018     if ((changed & ViewState::IsVisible) && !isViewVisible())
1019         m_process->responsivenessTimer()->stop();
1020
1021     if ((mayHaveChanged & ViewState::IsInWindow) && (m_viewState & ViewState::IsInWindow)) {
1022         LayerHostingMode layerHostingMode = m_pageClient.viewLayerHostingMode();
1023         if (m_layerHostingMode != layerHostingMode) {
1024             m_layerHostingMode = layerHostingMode;
1025             m_process->send(Messages::WebPage::SetLayerHostingMode(static_cast<unsigned>(layerHostingMode)), m_pageID);
1026         }
1027     }
1028
1029 #if ENABLE(INPUT_TYPE_COLOR_POPOVER)
1030     if ((mayHaveChanged & ViewState::IsInWindow) && !(m_viewState & ViewState::IsInWindow)) {
1031         // When leaving the current page, close the popover color well.
1032         if (m_colorPicker)
1033             endColorPicker();
1034     }
1035 #endif
1036
1037     if (changed & ViewState::IsInWindow)
1038         process().updateProcessState();
1039
1040     updateBackingStoreDiscardableState();
1041 }
1042
1043 void WebPageProxy::waitForDidUpdateViewState()
1044 {
1045     // If we have previously timed out with no response from the WebProcess, don't block the UIProcess again until it starts responding.
1046     if (m_waitingForDidUpdateViewState)
1047         return;
1048
1049     if (!isValid())
1050         return;
1051
1052     m_waitingForDidUpdateViewState = true;
1053
1054     if (m_process->state() != WebProcessProxy::State::Launching) {
1055         auto viewStateUpdateTimeout = std::chrono::milliseconds(250);
1056         m_process->connection()->waitForAndDispatchImmediately<Messages::WebPageProxy::DidUpdateViewState>(m_pageID, viewStateUpdateTimeout);
1057     }
1058 }
1059
1060 IntSize WebPageProxy::viewSize() const
1061 {
1062     return m_pageClient.viewSize();
1063 }
1064
1065 void WebPageProxy::setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent& keyboardEvent)
1066 {
1067     if (!isValid())
1068         return;
1069     m_process->send(Messages::WebPage::SetInitialFocus(forward, isKeyboardEventValid, keyboardEvent), m_pageID);
1070 }
1071
1072 void WebPageProxy::setWindowResizerSize(const IntSize& windowResizerSize)
1073 {
1074     if (!isValid())
1075         return;
1076     m_process->send(Messages::WebPage::SetWindowResizerSize(windowResizerSize), m_pageID);
1077 }
1078     
1079 void WebPageProxy::clearSelection()
1080 {
1081     if (!isValid())
1082         return;
1083     m_process->send(Messages::WebPage::ClearSelection(), m_pageID);
1084 }
1085
1086 void WebPageProxy::validateCommand(const String& commandName, PassRefPtr<ValidateCommandCallback> callback)
1087 {
1088     if (!isValid()) {
1089         callback->invalidate();
1090         return;
1091     }
1092
1093     uint64_t callbackID = callback->callbackID();
1094     m_validateCommandCallbacks.set(callbackID, callback);
1095     m_process->send(Messages::WebPage::ValidateCommand(commandName, callbackID), m_pageID);
1096 }
1097
1098 void WebPageProxy::setMaintainsInactiveSelection(bool newValue)
1099 {
1100     m_maintainsInactiveSelection = newValue;
1101 }
1102     
1103 void WebPageProxy::executeEditCommand(const String& commandName)
1104 {
1105     static NeverDestroyed<String> ignoreSpellingCommandName(ASCIILiteral("ignoreSpelling"));
1106
1107     if (!isValid())
1108         return;
1109
1110     if (commandName == ignoreSpellingCommandName)
1111         ++m_pendingLearnOrIgnoreWordMessageCount;
1112
1113     m_process->send(Messages::WebPage::ExecuteEditCommand(commandName), m_pageID);
1114 }
1115     
1116 #if USE(TILED_BACKING_STORE)
1117 void WebPageProxy::commitPageTransitionViewport()
1118 {
1119     if (!isValid())
1120         return;
1121
1122     process().send(Messages::WebPage::CommitPageTransitionViewport(), m_pageID);
1123 }
1124 #endif
1125
1126 #if ENABLE(DRAG_SUPPORT)
1127 void WebPageProxy::dragEntered(DragData& dragData, const String& dragStorageName)
1128 {
1129     SandboxExtension::Handle sandboxExtensionHandle;
1130     SandboxExtension::HandleArray sandboxExtensionHandleEmptyArray;
1131     performDragControllerAction(DragControllerActionEntered, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionHandleEmptyArray);
1132 }
1133
1134 void WebPageProxy::dragUpdated(DragData& dragData, const String& dragStorageName)
1135 {
1136     SandboxExtension::Handle sandboxExtensionHandle;
1137     SandboxExtension::HandleArray sandboxExtensionHandleEmptyArray;
1138     performDragControllerAction(DragControllerActionUpdated, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionHandleEmptyArray);
1139 }
1140
1141 void WebPageProxy::dragExited(DragData& dragData, const String& dragStorageName)
1142 {
1143     SandboxExtension::Handle sandboxExtensionHandle;
1144     SandboxExtension::HandleArray sandboxExtensionHandleEmptyArray;
1145     performDragControllerAction(DragControllerActionExited, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionHandleEmptyArray);
1146 }
1147
1148 void WebPageProxy::performDrag(DragData& dragData, const String& dragStorageName, const SandboxExtension::Handle& sandboxExtensionHandle, const SandboxExtension::HandleArray& sandboxExtensionsForUpload)
1149 {
1150     performDragControllerAction(DragControllerActionPerformDrag, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionsForUpload);
1151 }
1152
1153 void WebPageProxy::performDragControllerAction(DragControllerAction action, DragData& dragData, const String& dragStorageName, const SandboxExtension::Handle& sandboxExtensionHandle, const SandboxExtension::HandleArray& sandboxExtensionsForUpload)
1154 {
1155     if (!isValid())
1156         return;
1157 #if PLATFORM(GTK)
1158     UNUSED_PARAM(dragStorageName);
1159     UNUSED_PARAM(sandboxExtensionHandle);
1160     UNUSED_PARAM(sandboxExtensionsForUpload);
1161     m_process->send(Messages::WebPage::PerformDragControllerAction(action, dragData), m_pageID);
1162 #else
1163     m_process->send(Messages::WebPage::PerformDragControllerAction(action, dragData.clientPosition(), dragData.globalPosition(), dragData.draggingSourceOperationMask(), dragStorageName, dragData.flags(), sandboxExtensionHandle, sandboxExtensionsForUpload), m_pageID);
1164 #endif
1165 }
1166
1167 void WebPageProxy::didPerformDragControllerAction(WebCore::DragSession dragSession)
1168 {
1169     m_currentDragSession = dragSession;
1170 }
1171
1172 #if PLATFORM(GTK)
1173 void WebPageProxy::startDrag(const DragData& dragData, const ShareableBitmap::Handle& dragImageHandle)
1174 {
1175     RefPtr<ShareableBitmap> dragImage = 0;
1176     if (!dragImageHandle.isNull()) {
1177         dragImage = ShareableBitmap::create(dragImageHandle);
1178         if (!dragImage)
1179             return;
1180     }
1181
1182     m_pageClient.startDrag(dragData, dragImage.release());
1183 }
1184 #endif
1185
1186 void WebPageProxy::dragEnded(const IntPoint& clientPosition, const IntPoint& globalPosition, uint64_t operation)
1187 {
1188     if (!isValid())
1189         return;
1190     m_process->send(Messages::WebPage::DragEnded(clientPosition, globalPosition, operation), m_pageID);
1191 }
1192 #endif // ENABLE(DRAG_SUPPORT)
1193
1194 void WebPageProxy::handleMouseEvent(const NativeWebMouseEvent& event)
1195 {
1196     if (!isValid())
1197         return;
1198
1199     // NOTE: This does not start the responsiveness timer because mouse move should not indicate interaction.
1200     if (event.type() != WebEvent::MouseMove)
1201         m_process->responsivenessTimer()->start();
1202     else {
1203         if (m_processingMouseMoveEvent) {
1204             m_nextMouseMoveEvent = adoptPtr(new NativeWebMouseEvent(event));
1205             return;
1206         }
1207
1208         m_processingMouseMoveEvent = true;
1209     }
1210
1211     // <https://bugs.webkit.org/show_bug.cgi?id=57904> We need to keep track of the mouse down event in the case where we
1212     // display a popup menu for select elements. When the user changes the selected item,
1213     // we fake a mouse up event by using this stored down event. This event gets cleared
1214     // when the mouse up message is received from WebProcess.
1215     if (event.type() == WebEvent::MouseDown)
1216         m_currentlyProcessedMouseDownEvent = adoptPtr(new NativeWebMouseEvent(event));
1217
1218     if (m_shouldSendEventsSynchronously) {
1219         bool handled = false;
1220         m_process->sendSync(Messages::WebPage::MouseEventSyncForTesting(event), Messages::WebPage::MouseEventSyncForTesting::Reply(handled), m_pageID);
1221         didReceiveEvent(event.type(), handled);
1222     } else
1223         m_process->send(Messages::WebPage::MouseEvent(event), m_pageID);
1224 }
1225
1226 #if MERGE_WHEEL_EVENTS
1227 static bool canCoalesce(const WebWheelEvent& a, const WebWheelEvent& b)
1228 {
1229     if (a.position() != b.position())
1230         return false;
1231     if (a.globalPosition() != b.globalPosition())
1232         return false;
1233     if (a.modifiers() != b.modifiers())
1234         return false;
1235     if (a.granularity() != b.granularity())
1236         return false;
1237 #if PLATFORM(COCOA)
1238     if (a.phase() != b.phase())
1239         return false;
1240     if (a.momentumPhase() != b.momentumPhase())
1241         return false;
1242     if (a.hasPreciseScrollingDeltas() != b.hasPreciseScrollingDeltas())
1243         return false;
1244 #endif
1245
1246     return true;
1247 }
1248
1249 static WebWheelEvent coalesce(const WebWheelEvent& a, const WebWheelEvent& b)
1250 {
1251     ASSERT(canCoalesce(a, b));
1252
1253     FloatSize mergedDelta = a.delta() + b.delta();
1254     FloatSize mergedWheelTicks = a.wheelTicks() + b.wheelTicks();
1255
1256 #if PLATFORM(COCOA)
1257     FloatSize mergedUnacceleratedScrollingDelta = a.unacceleratedScrollingDelta() + b.unacceleratedScrollingDelta();
1258
1259     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());
1260 #else
1261     return WebWheelEvent(WebEvent::Wheel, b.position(), b.globalPosition(), mergedDelta, mergedWheelTicks, b.granularity(), b.modifiers(), b.timestamp());
1262 #endif
1263 }
1264 #endif // MERGE_WHEEL_EVENTS
1265
1266 static WebWheelEvent coalescedWheelEvent(Deque<NativeWebWheelEvent>& queue, Vector<NativeWebWheelEvent>& coalescedEvents)
1267 {
1268     ASSERT(!queue.isEmpty());
1269     ASSERT(coalescedEvents.isEmpty());
1270
1271 #if MERGE_WHEEL_EVENTS
1272     NativeWebWheelEvent firstEvent = queue.takeFirst();
1273     coalescedEvents.append(firstEvent);
1274
1275     WebWheelEvent event = firstEvent;
1276     while (!queue.isEmpty() && canCoalesce(event, queue.first())) {
1277         NativeWebWheelEvent firstEvent = queue.takeFirst();
1278         coalescedEvents.append(firstEvent);
1279         event = coalesce(event, firstEvent);
1280     }
1281
1282     return event;
1283 #else
1284     while (!queue.isEmpty())
1285         coalescedEvents.append(queue.takeFirst());
1286     return coalescedEvents.last();
1287 #endif
1288 }
1289
1290 void WebPageProxy::handleWheelEvent(const NativeWebWheelEvent& event)
1291 {
1292 #if ENABLE(ASYNC_SCROLLING)
1293     if (m_scrollingCoordinatorProxy && m_scrollingCoordinatorProxy->handleWheelEvent(platform(event)))
1294         return;
1295 #endif
1296
1297     if (!isValid())
1298         return;
1299
1300     if (!m_currentlyProcessedWheelEvents.isEmpty()) {
1301         m_wheelEventQueue.append(event);
1302         if (m_wheelEventQueue.size() < wheelEventQueueSizeThreshold)
1303             return;
1304         // The queue has too many wheel events, so push a new event.
1305     }
1306
1307     if (!m_wheelEventQueue.isEmpty()) {
1308         processNextQueuedWheelEvent();
1309         return;
1310     }
1311
1312     OwnPtr<Vector<NativeWebWheelEvent>> coalescedWheelEvent = adoptPtr(new Vector<NativeWebWheelEvent>);
1313     coalescedWheelEvent->append(event);
1314     m_currentlyProcessedWheelEvents.append(coalescedWheelEvent.release());
1315     sendWheelEvent(event);
1316 }
1317
1318 void WebPageProxy::processNextQueuedWheelEvent()
1319 {
1320     OwnPtr<Vector<NativeWebWheelEvent>> nextCoalescedEvent = adoptPtr(new Vector<NativeWebWheelEvent>);
1321     WebWheelEvent nextWheelEvent = coalescedWheelEvent(m_wheelEventQueue, *nextCoalescedEvent.get());
1322     m_currentlyProcessedWheelEvents.append(nextCoalescedEvent.release());
1323     sendWheelEvent(nextWheelEvent);
1324 }
1325
1326 void WebPageProxy::sendWheelEvent(const WebWheelEvent& event)
1327 {
1328     m_process->responsivenessTimer()->start();
1329
1330     if (m_shouldSendEventsSynchronously) {
1331         bool handled = false;
1332         m_process->sendSync(Messages::WebPage::WheelEventSyncForTesting(event), Messages::WebPage::WheelEventSyncForTesting::Reply(handled), m_pageID);
1333         didReceiveEvent(event.type(), handled);
1334         return;
1335     }
1336
1337     m_process->send(
1338         Messages::EventDispatcher::WheelEvent(
1339             m_pageID,
1340             event,
1341             shouldUseImplicitRubberBandControl() ? !m_backForwardList->backItem() : rubberBandsAtLeft(),
1342             shouldUseImplicitRubberBandControl() ? !m_backForwardList->forwardItem() : rubberBandsAtRight(),
1343             rubberBandsAtTop(),
1344             rubberBandsAtBottom()
1345         ), 0);
1346 }
1347
1348 void WebPageProxy::handleKeyboardEvent(const NativeWebKeyboardEvent& event)
1349 {
1350     if (!isValid())
1351         return;
1352     
1353     LOG(KeyHandling, "WebPageProxy::handleKeyboardEvent: %s", webKeyboardEventTypeString(event.type()));
1354
1355     m_keyEventQueue.append(event);
1356
1357     m_process->responsivenessTimer()->start();
1358     if (m_shouldSendEventsSynchronously) {
1359         bool handled = false;
1360         m_process->sendSync(Messages::WebPage::KeyEventSyncForTesting(event), Messages::WebPage::KeyEventSyncForTesting::Reply(handled), m_pageID);
1361         didReceiveEvent(event.type(), handled);
1362     } else if (m_keyEventQueue.size() == 1) // Otherwise, sent from DidReceiveEvent message handler.
1363         m_process->send(Messages::WebPage::KeyEvent(event), m_pageID);
1364 }
1365
1366 uint64_t WebPageProxy::generateNavigationID()
1367 {
1368     return ++m_navigationID;
1369 }
1370
1371 #if ENABLE(NETSCAPE_PLUGIN_API)
1372 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)
1373 {
1374     MESSAGE_CHECK_URL(urlString);
1375
1376     newMimeType = mimeType.lower();
1377     pluginLoadPolicy = PluginModuleLoadNormally;
1378
1379     PluginData::AllowedPluginTypes allowedPluginTypes = allowOnlyApplicationPlugins ? PluginData::OnlyApplicationPlugins : PluginData::AllPlugins;
1380     PluginModuleInfo plugin = m_process->context().pluginInfoStore().findPlugin(newMimeType, URL(URL(), urlString), allowedPluginTypes);
1381     if (!plugin.path) {
1382         pluginProcessToken = 0;
1383         return;
1384     }
1385
1386     pluginLoadPolicy = PluginInfoStore::defaultLoadPolicyForPlugin(plugin);
1387
1388 #if PLATFORM(COCOA)
1389     RefPtr<ImmutableDictionary> pluginInformation = createPluginInformationDictionary(plugin, frameURLString, String(), pageURLString, String(), String());
1390     pluginLoadPolicy = m_loaderClient->pluginLoadPolicy(this, static_cast<PluginModuleLoadPolicy>(pluginLoadPolicy), pluginInformation.get(), unavailabilityDescription);
1391 #else
1392     UNUSED_PARAM(frameURLString);
1393     UNUSED_PARAM(pageURLString);
1394     UNUSED_PARAM(unavailabilityDescription);
1395 #endif
1396
1397     PluginProcessSandboxPolicy pluginProcessSandboxPolicy = PluginProcessSandboxPolicyNormal;
1398     switch (pluginLoadPolicy) {
1399     case PluginModuleLoadNormally:
1400         pluginProcessSandboxPolicy = PluginProcessSandboxPolicyNormal;
1401         break;
1402     case PluginModuleLoadUnsandboxed:
1403         pluginProcessSandboxPolicy = PluginProcessSandboxPolicyUnsandboxed;
1404         break;
1405
1406     case PluginModuleBlocked:
1407         pluginProcessToken = 0;
1408         return;
1409     }
1410
1411     pluginProcessToken = PluginProcessManager::shared().pluginProcessToken(plugin, static_cast<PluginProcessType>(processType), pluginProcessSandboxPolicy);
1412 }
1413
1414 #endif // ENABLE(NETSCAPE_PLUGIN_API)
1415
1416 #if ENABLE(TOUCH_EVENTS)
1417
1418 bool WebPageProxy::shouldStartTrackingTouchEvents(const WebTouchEvent& touchStartEvent) const
1419 {
1420 #if ENABLE(ASYNC_SCROLLING)
1421     for (auto& touchPoint : touchStartEvent.touchPoints()) {
1422         if (m_scrollingCoordinatorProxy->isPointInNonFastScrollableRegion(touchPoint.location()))
1423             return true;
1424     }
1425
1426     return false;
1427 #else
1428     UNUSED_PARAM(touchStartEvent);
1429 #endif // ENABLE(ASYNC_SCROLLING)
1430     return true;
1431 }
1432
1433 void WebPageProxy::handleTouchEvent(const NativeWebTouchEvent& event)
1434 {
1435     if (!isValid())
1436         return;
1437
1438     if (event.type() == WebEvent::TouchStart)
1439         m_isTrackingTouchEvents = shouldStartTrackingTouchEvents(event);
1440
1441     if (!m_isTrackingTouchEvents)
1442         return;
1443
1444     // If the page is suspended, which should be the case during panning, pinching
1445     // and animation on the page itself (kinetic scrolling, tap to zoom) etc, then
1446     // we do not send any of the events to the page even if is has listeners.
1447     if (!m_isPageSuspended) {
1448         m_touchEventQueue.append(event);
1449         m_process->responsivenessTimer()->start();
1450         if (m_shouldSendEventsSynchronously) {
1451             bool handled = false;
1452             m_process->sendSync(Messages::WebPage::TouchEventSyncForTesting(event), Messages::WebPage::TouchEventSyncForTesting::Reply(handled), m_pageID);
1453             didReceiveEvent(event.type(), handled);
1454         } else
1455             m_process->send(Messages::WebPage::TouchEvent(event), m_pageID);
1456     } else {
1457         if (m_touchEventQueue.isEmpty()) {
1458             bool isEventHandled = false;
1459             m_pageClient.doneWithTouchEvent(event, isEventHandled);
1460         } else {
1461             // We attach the incoming events to the newest queued event so that all
1462             // the events are delivered in the correct order when the event is dequed.
1463             QueuedTouchEvents& lastEvent = m_touchEventQueue.last();
1464             lastEvent.deferredTouchEvents.append(event);
1465         }
1466     }
1467
1468     if (event.type() == WebEvent::TouchEnd || event.type() == WebEvent::TouchCancel)
1469         m_isTrackingTouchEvents = false;
1470 }
1471 #endif // ENABLE(TOUCH_EVENTS)
1472
1473 void WebPageProxy::scrollBy(ScrollDirection direction, ScrollGranularity granularity)
1474 {
1475     if (!isValid())
1476         return;
1477
1478     m_process->send(Messages::WebPage::ScrollBy(direction, granularity), m_pageID);
1479 }
1480
1481 void WebPageProxy::centerSelectionInVisibleArea()
1482 {
1483     if (!isValid())
1484         return;
1485
1486     m_process->send(Messages::WebPage::CenterSelectionInVisibleArea(), m_pageID);
1487 }
1488
1489 void WebPageProxy::receivedPolicyDecision(PolicyAction action, WebFrameProxy* frame, uint64_t listenerID)
1490 {
1491     if (!isValid())
1492         return;
1493
1494     auto transaction = m_pageLoadState.transaction();
1495
1496     if (action == PolicyIgnore)
1497         m_pageLoadState.clearPendingAPIRequestURL(transaction);
1498
1499     uint64_t downloadID = 0;
1500     if (action == PolicyDownload) {
1501         // Create a download proxy.
1502         DownloadProxy* download = m_process->context().createDownloadProxy();
1503         downloadID = download->downloadID();
1504 #if PLATFORM(EFL) || PLATFORM(GTK)
1505         // Our design does not suppport downloads without a WebPage.
1506         handleDownloadRequest(download);
1507 #endif
1508     }
1509
1510     // If we received a policy decision while in decidePolicyForResponse the decision will
1511     // be sent back to the web process by decidePolicyForResponse.
1512     if (m_inDecidePolicyForResponseSync) {
1513         m_syncMimeTypePolicyActionIsValid = true;
1514         m_syncMimeTypePolicyAction = action;
1515         m_syncMimeTypePolicyDownloadID = downloadID;
1516         return;
1517     }
1518
1519     // If we received a policy decision while in decidePolicyForNavigationAction the decision will 
1520     // be sent back to the web process by decidePolicyForNavigationAction. 
1521     if (m_inDecidePolicyForNavigationAction) {
1522         m_syncNavigationActionPolicyActionIsValid = true;
1523         m_syncNavigationActionPolicyAction = action;
1524         m_syncNavigationActionPolicyDownloadID = downloadID;
1525         return;
1526     }
1527     
1528     m_process->send(Messages::WebPage::DidReceivePolicyDecision(frame->frameID(), listenerID, action, downloadID), m_pageID);
1529 }
1530
1531 void WebPageProxy::setUserAgent(const String& userAgent)
1532 {
1533     if (m_userAgent == userAgent)
1534         return;
1535     m_userAgent = userAgent;
1536
1537     if (!isValid())
1538         return;
1539     m_process->send(Messages::WebPage::SetUserAgent(m_userAgent), m_pageID);
1540 }
1541
1542 void WebPageProxy::setApplicationNameForUserAgent(const String& applicationName)
1543 {
1544     if (m_applicationNameForUserAgent == applicationName)
1545         return;
1546
1547     m_applicationNameForUserAgent = applicationName;
1548     if (!m_customUserAgent.isEmpty())
1549         return;
1550
1551     setUserAgent(standardUserAgent(m_applicationNameForUserAgent));
1552 }
1553
1554 void WebPageProxy::setCustomUserAgent(const String& customUserAgent)
1555 {
1556     if (m_customUserAgent == customUserAgent)
1557         return;
1558
1559     m_customUserAgent = customUserAgent;
1560
1561     if (m_customUserAgent.isEmpty()) {
1562         setUserAgent(standardUserAgent(m_applicationNameForUserAgent));
1563         return;
1564     }
1565
1566     setUserAgent(m_customUserAgent);
1567 }
1568
1569 void WebPageProxy::resumeActiveDOMObjectsAndAnimations()
1570 {
1571     if (!isValid() || !m_isPageSuspended)
1572         return;
1573
1574     m_isPageSuspended = false;
1575
1576     m_process->send(Messages::WebPage::ResumeActiveDOMObjectsAndAnimations(), m_pageID);
1577 }
1578
1579 void WebPageProxy::suspendActiveDOMObjectsAndAnimations()
1580 {
1581     if (!isValid() || m_isPageSuspended)
1582         return;
1583
1584     m_isPageSuspended = true;
1585
1586     m_process->send(Messages::WebPage::SuspendActiveDOMObjectsAndAnimations(), m_pageID);
1587 }
1588
1589 bool WebPageProxy::supportsTextEncoding() const
1590 {
1591     // FIXME (118840): We should probably only support this for text documents, not all non-image documents.
1592     return m_mainFrame && !m_mainFrame->isDisplayingStandaloneImageDocument();
1593 }
1594
1595 void WebPageProxy::setCustomTextEncodingName(const String& encodingName)
1596 {
1597     if (m_customTextEncodingName == encodingName)
1598         return;
1599     m_customTextEncodingName = encodingName;
1600
1601     if (!isValid())
1602         return;
1603     m_process->send(Messages::WebPage::SetCustomTextEncodingName(encodingName), m_pageID);
1604 }
1605
1606 void WebPageProxy::terminateProcess()
1607 {
1608     // NOTE: This uses a check of m_isValid rather than calling isValid() since
1609     // we want this to run even for pages being closed or that already closed.
1610     if (!m_isValid)
1611         return;
1612
1613     m_process->requestTermination();
1614     resetStateAfterProcessExited();
1615 }
1616
1617 #if !USE(CF)
1618 PassRefPtr<API::Data> WebPageProxy::sessionStateData(WebPageProxySessionStateFilterCallback, void* /*context*/) const
1619 {
1620     // FIXME: Return session state data for saving Page state.
1621     return 0;
1622 }
1623
1624 void WebPageProxy::restoreFromSessionStateData(API::Data*)
1625 {
1626     // FIXME: Restore the Page from the passed in session state data.
1627 }
1628 #endif
1629
1630 bool WebPageProxy::supportsTextZoom() const
1631 {
1632     // FIXME (118840): This should also return false for standalone media and plug-in documents.
1633     if (!m_mainFrame || m_mainFrame->isDisplayingStandaloneImageDocument())
1634         return false;
1635
1636     return true;
1637 }
1638  
1639 void WebPageProxy::setTextZoomFactor(double zoomFactor)
1640 {
1641     if (!isValid())
1642         return;
1643
1644     if (m_textZoomFactor == zoomFactor)
1645         return;
1646
1647     m_textZoomFactor = zoomFactor;
1648     m_process->send(Messages::WebPage::SetTextZoomFactor(m_textZoomFactor), m_pageID); 
1649 }
1650
1651 void WebPageProxy::setPageZoomFactor(double zoomFactor)
1652 {
1653     if (!isValid())
1654         return;
1655
1656     if (m_pageZoomFactor == zoomFactor)
1657         return;
1658
1659     m_pageZoomFactor = zoomFactor;
1660     m_process->send(Messages::WebPage::SetPageZoomFactor(m_pageZoomFactor), m_pageID); 
1661 }
1662
1663 void WebPageProxy::setPageAndTextZoomFactors(double pageZoomFactor, double textZoomFactor)
1664 {
1665     if (!isValid())
1666         return;
1667
1668     if (m_pageZoomFactor == pageZoomFactor && m_textZoomFactor == textZoomFactor)
1669         return;
1670
1671     m_pageZoomFactor = pageZoomFactor;
1672     m_textZoomFactor = textZoomFactor;
1673     m_process->send(Messages::WebPage::SetPageAndTextZoomFactors(m_pageZoomFactor, m_textZoomFactor), m_pageID); 
1674 }
1675
1676 void WebPageProxy::scalePage(double scale, const IntPoint& origin)
1677 {
1678     if (!isValid())
1679         return;
1680
1681     m_pageScaleFactor = scale;
1682     m_process->send(Messages::WebPage::ScalePage(scale, origin), m_pageID);
1683 }
1684
1685 void WebPageProxy::setIntrinsicDeviceScaleFactor(float scaleFactor)
1686 {
1687     if (m_intrinsicDeviceScaleFactor == scaleFactor)
1688         return;
1689
1690     m_intrinsicDeviceScaleFactor = scaleFactor;
1691
1692     if (m_drawingArea)
1693         m_drawingArea->deviceScaleFactorDidChange();
1694 }
1695
1696 void WebPageProxy::windowScreenDidChange(PlatformDisplayID displayID)
1697 {
1698     if (!isValid())
1699         return;
1700
1701     m_process->send(Messages::WebPage::WindowScreenDidChange(displayID), m_pageID);
1702 }
1703
1704 float WebPageProxy::deviceScaleFactor() const
1705 {
1706     if (m_customDeviceScaleFactor)
1707         return m_customDeviceScaleFactor;
1708     return m_intrinsicDeviceScaleFactor;
1709 }
1710
1711 void WebPageProxy::setCustomDeviceScaleFactor(float customScaleFactor)
1712 {
1713     if (!isValid())
1714         return;
1715
1716     if (m_customDeviceScaleFactor == customScaleFactor)
1717         return;
1718
1719     float oldScaleFactor = deviceScaleFactor();
1720
1721     m_customDeviceScaleFactor = customScaleFactor;
1722
1723     if (deviceScaleFactor() != oldScaleFactor)
1724         m_drawingArea->deviceScaleFactorDidChange();
1725 }
1726
1727 void WebPageProxy::setUseFixedLayout(bool fixed)
1728 {
1729     if (!isValid())
1730         return;
1731
1732     // This check is fine as the value is initialized in the web
1733     // process as part of the creation parameters.
1734     if (fixed == m_useFixedLayout)
1735         return;
1736
1737     m_useFixedLayout = fixed;
1738     if (!fixed)
1739         m_fixedLayoutSize = IntSize();
1740     m_process->send(Messages::WebPage::SetUseFixedLayout(fixed), m_pageID);
1741 }
1742
1743 void WebPageProxy::setFixedLayoutSize(const IntSize& size)
1744 {
1745     if (!isValid())
1746         return;
1747
1748     if (size == m_fixedLayoutSize)
1749         return;
1750
1751     m_fixedLayoutSize = size;
1752     m_process->send(Messages::WebPage::SetFixedLayoutSize(size), m_pageID);
1753 }
1754
1755 void WebPageProxy::listenForLayoutMilestones(WebCore::LayoutMilestones milestones)
1756 {
1757     if (!isValid())
1758         return;
1759
1760     m_process->send(Messages::WebPage::ListenForLayoutMilestones(milestones), m_pageID);
1761 }
1762
1763 void WebPageProxy::setSuppressScrollbarAnimations(bool suppressAnimations)
1764 {
1765     if (!isValid())
1766         return;
1767
1768     if (suppressAnimations == m_suppressScrollbarAnimations)
1769         return;
1770
1771     m_suppressScrollbarAnimations = suppressAnimations;
1772     m_process->send(Messages::WebPage::SetSuppressScrollbarAnimations(suppressAnimations), m_pageID);
1773 }
1774
1775 bool WebPageProxy::rubberBandsAtLeft() const
1776 {
1777     return m_rubberBandsAtLeft;
1778 }
1779
1780 void WebPageProxy::setRubberBandsAtLeft(bool rubberBandsAtLeft)
1781 {
1782     m_rubberBandsAtLeft = rubberBandsAtLeft;
1783 }
1784
1785 bool WebPageProxy::rubberBandsAtRight() const
1786 {
1787     return m_rubberBandsAtRight;
1788 }
1789
1790 void WebPageProxy::setRubberBandsAtRight(bool rubberBandsAtRight)
1791 {
1792     m_rubberBandsAtRight = rubberBandsAtRight;
1793 }
1794
1795 bool WebPageProxy::rubberBandsAtTop() const
1796 {
1797     return m_rubberBandsAtTop;
1798 }
1799
1800 void WebPageProxy::setRubberBandsAtTop(bool rubberBandsAtTop)
1801 {
1802     m_rubberBandsAtTop = rubberBandsAtTop;
1803 }
1804
1805 bool WebPageProxy::rubberBandsAtBottom() const
1806 {
1807     return m_rubberBandsAtBottom;
1808 }
1809
1810 void WebPageProxy::setRubberBandsAtBottom(bool rubberBandsAtBottom)
1811 {
1812     m_rubberBandsAtBottom = rubberBandsAtBottom;
1813 }
1814
1815 void WebPageProxy::setBackgroundExtendsBeyondPage(bool backgroundExtendsBeyondPage)
1816 {
1817     if (backgroundExtendsBeyondPage == m_backgroundExtendsBeyondPage)
1818         return;
1819
1820     m_backgroundExtendsBeyondPage = backgroundExtendsBeyondPage;
1821
1822     if (!isValid())
1823         return;
1824     m_process->send(Messages::WebPage::SetBackgroundExtendsBeyondPage(backgroundExtendsBeyondPage), m_pageID);
1825 }
1826
1827 bool WebPageProxy::backgroundExtendsBeyondPage() const
1828 {
1829     return m_backgroundExtendsBeyondPage;
1830 }
1831
1832 void WebPageProxy::setPaginationMode(WebCore::Pagination::Mode mode)
1833 {
1834     if (mode == m_paginationMode)
1835         return;
1836
1837     m_paginationMode = mode;
1838
1839     if (!isValid())
1840         return;
1841     m_process->send(Messages::WebPage::SetPaginationMode(mode), m_pageID);
1842 }
1843
1844 void WebPageProxy::setPaginationBehavesLikeColumns(bool behavesLikeColumns)
1845 {
1846     if (behavesLikeColumns == m_paginationBehavesLikeColumns)
1847         return;
1848
1849     m_paginationBehavesLikeColumns = behavesLikeColumns;
1850
1851     if (!isValid())
1852         return;
1853     m_process->send(Messages::WebPage::SetPaginationBehavesLikeColumns(behavesLikeColumns), m_pageID);
1854 }
1855
1856 void WebPageProxy::setPageLength(double pageLength)
1857 {
1858     if (pageLength == m_pageLength)
1859         return;
1860
1861     m_pageLength = pageLength;
1862
1863     if (!isValid())
1864         return;
1865     m_process->send(Messages::WebPage::SetPageLength(pageLength), m_pageID);
1866 }
1867
1868 void WebPageProxy::setGapBetweenPages(double gap)
1869 {
1870     if (gap == m_gapBetweenPages)
1871         return;
1872
1873     m_gapBetweenPages = gap;
1874
1875     if (!isValid())
1876         return;
1877     m_process->send(Messages::WebPage::SetGapBetweenPages(gap), m_pageID);
1878 }
1879
1880 void WebPageProxy::pageScaleFactorDidChange(double scaleFactor)
1881 {
1882     m_pageScaleFactor = scaleFactor;
1883 }
1884
1885 void WebPageProxy::pageZoomFactorDidChange(double zoomFactor)
1886 {
1887     m_pageZoomFactor = zoomFactor;
1888 }
1889
1890 void WebPageProxy::setMemoryCacheClientCallsEnabled(bool memoryCacheClientCallsEnabled)
1891 {
1892     if (!isValid())
1893         return;
1894
1895     if (m_areMemoryCacheClientCallsEnabled == memoryCacheClientCallsEnabled)
1896         return;
1897
1898     m_areMemoryCacheClientCallsEnabled = memoryCacheClientCallsEnabled;
1899     m_process->send(Messages::WebPage::SetMemoryCacheMessagesEnabled(memoryCacheClientCallsEnabled), m_pageID);
1900 }
1901
1902 void WebPageProxy::findStringMatches(const String& string, FindOptions options, unsigned maxMatchCount)
1903 {
1904     if (string.isEmpty()) {
1905         didFindStringMatches(string, Vector<Vector<WebCore::IntRect>> (), 0);
1906         return;
1907     }
1908
1909     m_process->send(Messages::WebPage::FindStringMatches(string, options, maxMatchCount), m_pageID);
1910 }
1911
1912 void WebPageProxy::findString(const String& string, FindOptions options, unsigned maxMatchCount)
1913 {
1914     m_process->send(Messages::WebPage::FindString(string, options, maxMatchCount), m_pageID);
1915 }
1916
1917 void WebPageProxy::getImageForFindMatch(int32_t matchIndex)
1918 {
1919     m_process->send(Messages::WebPage::GetImageForFindMatch(matchIndex), m_pageID);
1920 }
1921
1922 void WebPageProxy::selectFindMatch(int32_t matchIndex)
1923 {
1924     m_process->send(Messages::WebPage::SelectFindMatch(matchIndex), m_pageID);
1925 }
1926
1927 void WebPageProxy::hideFindUI()
1928 {
1929     m_process->send(Messages::WebPage::HideFindUI(), m_pageID);
1930 }
1931
1932 void WebPageProxy::countStringMatches(const String& string, FindOptions options, unsigned maxMatchCount)
1933 {
1934     if (!isValid())
1935         return;
1936
1937     m_process->send(Messages::WebPage::CountStringMatches(string, options, maxMatchCount), m_pageID);
1938 }
1939
1940 void WebPageProxy::runJavaScriptInMainFrame(const String& script, PassRefPtr<ScriptValueCallback> prpCallback)
1941 {
1942     RefPtr<ScriptValueCallback> callback = prpCallback;
1943     if (!isValid()) {
1944         callback->invalidate();
1945         return;
1946     }
1947
1948     uint64_t callbackID = callback->callbackID();
1949     m_scriptValueCallbacks.set(callbackID, callback);
1950     m_process->send(Messages::WebPage::RunJavaScriptInMainFrame(script, callbackID), m_pageID);
1951 }
1952
1953 void WebPageProxy::getRenderTreeExternalRepresentation(PassRefPtr<StringCallback> prpCallback)
1954 {
1955     RefPtr<StringCallback> callback = prpCallback;
1956     if (!isValid()) {
1957         callback->invalidate();
1958         return;
1959     }
1960     
1961     uint64_t callbackID = callback->callbackID();
1962     m_stringCallbacks.set(callbackID, callback);
1963     m_process->send(Messages::WebPage::GetRenderTreeExternalRepresentation(callbackID), m_pageID);
1964 }
1965
1966 void WebPageProxy::getSourceForFrame(WebFrameProxy* frame, PassRefPtr<StringCallback> prpCallback)
1967 {
1968     RefPtr<StringCallback> callback = prpCallback;
1969     if (!isValid()) {
1970         callback->invalidate();
1971         return;
1972     }
1973     
1974     uint64_t callbackID = callback->callbackID();
1975     m_loadDependentStringCallbackIDs.add(callbackID);
1976     m_stringCallbacks.set(callbackID, callback);
1977     m_process->send(Messages::WebPage::GetSourceForFrame(frame->frameID(), callbackID), m_pageID);
1978 }
1979
1980 void WebPageProxy::getContentsAsString(PassRefPtr<StringCallback> prpCallback)
1981 {
1982     RefPtr<StringCallback> callback = prpCallback;
1983     if (!isValid()) {
1984         callback->invalidate();
1985         return;
1986     }
1987     
1988     uint64_t callbackID = callback->callbackID();
1989     m_loadDependentStringCallbackIDs.add(callbackID);
1990     m_stringCallbacks.set(callbackID, callback);
1991     m_process->send(Messages::WebPage::GetContentsAsString(callbackID), m_pageID);
1992 }
1993
1994 void WebPageProxy::getBytecodeProfile(PassRefPtr<StringCallback> prpCallback)
1995 {
1996     RefPtr<StringCallback> callback = prpCallback;
1997     if (!isValid()) {
1998         callback->invalidate();
1999         return;
2000     }
2001     
2002     uint64_t callbackID = callback->callbackID();
2003     m_loadDependentStringCallbackIDs.add(callbackID);
2004     m_stringCallbacks.set(callbackID, callback);
2005     m_process->send(Messages::WebPage::GetBytecodeProfile(callbackID), m_pageID);
2006 }
2007     
2008 #if ENABLE(MHTML)
2009 void WebPageProxy::getContentsAsMHTMLData(PassRefPtr<DataCallback> prpCallback, bool useBinaryEncoding)
2010 {
2011     RefPtr<DataCallback> callback = prpCallback;
2012     if (!isValid()) {
2013         callback->invalidate();
2014         return;
2015     }
2016
2017     uint64_t callbackID = callback->callbackID();
2018     m_dataCallbacks.set(callbackID, callback);
2019     m_process->send(Messages::WebPage::GetContentsAsMHTMLData(callbackID, useBinaryEncoding), m_pageID);
2020 }
2021 #endif
2022
2023 void WebPageProxy::getSelectionOrContentsAsString(PassRefPtr<StringCallback> prpCallback)
2024 {
2025     RefPtr<StringCallback> callback = prpCallback;
2026     if (!isValid()) {
2027         callback->invalidate();
2028         return;
2029     }
2030     
2031     uint64_t callbackID = callback->callbackID();
2032     m_stringCallbacks.set(callbackID, callback);
2033     m_process->send(Messages::WebPage::GetSelectionOrContentsAsString(callbackID), m_pageID);
2034 }
2035
2036 void WebPageProxy::getSelectionAsWebArchiveData(PassRefPtr<DataCallback> prpCallback)
2037 {
2038     RefPtr<DataCallback> callback = prpCallback;
2039     if (!isValid()) {
2040         callback->invalidate();
2041         return;
2042     }
2043     
2044     uint64_t callbackID = callback->callbackID();
2045     m_dataCallbacks.set(callbackID, callback);
2046     m_process->send(Messages::WebPage::GetSelectionAsWebArchiveData(callbackID), m_pageID);
2047 }
2048
2049 void WebPageProxy::getMainResourceDataOfFrame(WebFrameProxy* frame, PassRefPtr<DataCallback> prpCallback)
2050 {
2051     RefPtr<DataCallback> callback = prpCallback;
2052     if (!isValid()) {
2053         callback->invalidate();
2054         return;
2055     }
2056     
2057     uint64_t callbackID = callback->callbackID();
2058     m_dataCallbacks.set(callbackID, callback);
2059     m_process->send(Messages::WebPage::GetMainResourceDataOfFrame(frame->frameID(), callbackID), m_pageID);
2060 }
2061
2062 void WebPageProxy::getResourceDataFromFrame(WebFrameProxy* frame, API::URL* resourceURL, PassRefPtr<DataCallback> prpCallback)
2063 {
2064     RefPtr<DataCallback> callback = prpCallback;
2065     if (!isValid()) {
2066         callback->invalidate();
2067         return;
2068     }
2069     
2070     uint64_t callbackID = callback->callbackID();
2071     m_dataCallbacks.set(callbackID, callback);
2072     m_process->send(Messages::WebPage::GetResourceDataFromFrame(frame->frameID(), resourceURL->string(), callbackID), m_pageID);
2073 }
2074
2075 void WebPageProxy::getWebArchiveOfFrame(WebFrameProxy* frame, PassRefPtr<DataCallback> prpCallback)
2076 {
2077     RefPtr<DataCallback> callback = prpCallback;
2078     if (!isValid()) {
2079         callback->invalidate();
2080         return;
2081     }
2082     
2083     uint64_t callbackID = callback->callbackID();
2084     m_dataCallbacks.set(callbackID, callback);
2085     m_process->send(Messages::WebPage::GetWebArchiveOfFrame(frame->frameID(), callbackID), m_pageID);
2086 }
2087
2088 void WebPageProxy::forceRepaint(PassRefPtr<VoidCallback> prpCallback)
2089 {
2090     RefPtr<VoidCallback> callback = prpCallback;
2091     if (!isValid()) {
2092         callback->invalidate();
2093         return;
2094     }
2095
2096     uint64_t callbackID = callback->callbackID();
2097     m_voidCallbacks.set(callbackID, callback);
2098     m_drawingArea->waitForBackingStoreUpdateOnNextPaint();
2099     m_process->send(Messages::WebPage::ForceRepaint(callbackID), m_pageID); 
2100 }
2101
2102 void WebPageProxy::preferencesDidChange()
2103 {
2104     if (!isValid())
2105         return;
2106
2107 #if ENABLE(INSPECTOR_SERVER)
2108     if (m_preferences->developerExtrasEnabled())
2109         inspector()->enableRemoteInspection();
2110 #endif
2111
2112     m_process->pagePreferencesChanged(this);
2113
2114     m_pageClient.preferencesDidChange();
2115
2116     // FIXME: It probably makes more sense to send individual preference changes.
2117     // However, WebKitTestRunner depends on getting a preference change notification
2118     // even if nothing changed in UI process, so that overrides get removed.
2119
2120     // Preferences need to be updated during synchronous printing to make "print backgrounds" preference work when toggled from a print dialog checkbox.
2121     m_process->send(Messages::WebPage::PreferencesDidChange(m_preferences->store()), m_pageID, m_isPerformingDOMPrintOperation ? IPC::DispatchMessageEvenWhenWaitingForSyncReply : 0);
2122 }
2123
2124 void WebPageProxy::didCreateMainFrame(uint64_t frameID)
2125 {
2126     MESSAGE_CHECK(!m_mainFrame);
2127     MESSAGE_CHECK(m_process->canCreateFrame(frameID));
2128
2129     m_mainFrame = WebFrameProxy::create(this, frameID);
2130
2131     // Add the frame to the process wide map.
2132     m_process->frameCreated(frameID, m_mainFrame.get());
2133 }
2134
2135 void WebPageProxy::didCreateSubframe(uint64_t frameID)
2136 {
2137     MESSAGE_CHECK(m_mainFrame);
2138     MESSAGE_CHECK(m_process->canCreateFrame(frameID));
2139     
2140     RefPtr<WebFrameProxy> subFrame = WebFrameProxy::create(this, frameID);
2141
2142     // Add the frame to the process wide map.
2143     m_process->frameCreated(frameID, subFrame.get());
2144 }
2145
2146 double WebPageProxy::estimatedProgress() const
2147 {
2148     return m_pageLoadState.estimatedProgress();
2149 }
2150
2151 void WebPageProxy::didStartProgress()
2152 {
2153     auto transaction = m_pageLoadState.transaction();
2154     m_pageLoadState.didStartProgress(transaction);
2155
2156     m_pageLoadState.commitChanges();
2157     m_loaderClient->didStartProgress(this);
2158 }
2159
2160 void WebPageProxy::didChangeProgress(double value)
2161 {
2162     auto transaction = m_pageLoadState.transaction();
2163     m_pageLoadState.didChangeProgress(transaction, value);
2164
2165     m_pageLoadState.commitChanges();
2166     m_loaderClient->didChangeProgress(this);
2167 }
2168
2169 void WebPageProxy::didFinishProgress()
2170 {
2171     auto transaction = m_pageLoadState.transaction();
2172     m_pageLoadState.didFinishProgress(transaction);
2173
2174     m_pageLoadState.commitChanges();
2175     m_loaderClient->didFinishProgress(this);
2176 }
2177
2178 void WebPageProxy::didStartProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& url, const String& unreachableURL, IPC::MessageDecoder& decoder)
2179 {
2180     auto transaction = m_pageLoadState.transaction();
2181
2182     m_pageLoadState.clearPendingAPIRequestURL(transaction);
2183
2184     RefPtr<API::Object> userData;
2185     WebContextUserMessageDecoder messageDecoder(userData, process());
2186     if (!decoder.decode(messageDecoder))
2187         return;
2188
2189     WebFrameProxy* frame = m_process->webFrame(frameID);
2190     MESSAGE_CHECK(frame);
2191     MESSAGE_CHECK_URL(url);
2192
2193     if (frame->isMainFrame()) {
2194         recordNavigationSnapshot();
2195         m_pageLoadState.didStartProvisionalLoad(transaction, url, unreachableURL);
2196     }
2197
2198     frame->setUnreachableURL(unreachableURL);
2199     frame->didStartProvisionalLoad(url);
2200
2201     m_pageLoadState.commitChanges();
2202     m_loaderClient->didStartProvisionalLoadForFrame(this, frame, navigationID, userData.get());
2203 }
2204
2205 void WebPageProxy::didReceiveServerRedirectForProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& url, IPC::MessageDecoder& decoder)
2206 {
2207     RefPtr<API::Object> userData;
2208     WebContextUserMessageDecoder messageDecoder(userData, process());
2209     if (!decoder.decode(messageDecoder))
2210         return;
2211
2212     WebFrameProxy* frame = m_process->webFrame(frameID);
2213     MESSAGE_CHECK(frame);
2214     MESSAGE_CHECK_URL(url);
2215
2216     auto transaction = m_pageLoadState.transaction();
2217
2218     if (frame->isMainFrame())
2219         m_pageLoadState.didReceiveServerRedirectForProvisionalLoad(transaction, url);
2220
2221     frame->didReceiveServerRedirectForProvisionalLoad(url);
2222
2223     m_pageLoadState.commitChanges();
2224     m_loaderClient->didReceiveServerRedirectForProvisionalLoadForFrame(this, frame, navigationID, userData.get());
2225 }
2226
2227 void WebPageProxy::didFailProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, const ResourceError& error, IPC::MessageDecoder& decoder)
2228 {
2229     RefPtr<API::Object> userData;
2230     WebContextUserMessageDecoder messageDecoder(userData, process());
2231     if (!decoder.decode(messageDecoder))
2232         return;
2233
2234     WebFrameProxy* frame = m_process->webFrame(frameID);
2235     MESSAGE_CHECK(frame);
2236
2237     auto transaction = m_pageLoadState.transaction();
2238
2239     if (frame->isMainFrame())
2240         m_pageLoadState.didFailProvisionalLoad(transaction);
2241
2242     frame->didFailProvisionalLoad();
2243
2244     m_pageLoadState.commitChanges();
2245     m_loaderClient->didFailProvisionalLoadWithErrorForFrame(this, frame, navigationID, error, userData.get());
2246 }
2247
2248 void WebPageProxy::clearLoadDependentCallbacks()
2249 {
2250     Vector<uint64_t> callbackIDsCopy;
2251     copyToVector(m_loadDependentStringCallbackIDs, callbackIDsCopy);
2252     m_loadDependentStringCallbackIDs.clear();
2253
2254     for (size_t i = 0; i < callbackIDsCopy.size(); ++i) {
2255         RefPtr<StringCallback> callback = m_stringCallbacks.take(callbackIDsCopy[i]);
2256         if (callback)
2257             callback->invalidate();
2258     }
2259 }
2260
2261 void WebPageProxy::didCommitLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& mimeType, bool frameHasCustomContentProvider, uint32_t opaqueFrameLoadType, const WebCore::CertificateInfo& certificateInfo, IPC::MessageDecoder& decoder)
2262 {
2263     RefPtr<API::Object> userData;
2264     WebContextUserMessageDecoder messageDecoder(userData, process());
2265     if (!decoder.decode(messageDecoder))
2266         return;
2267
2268     WebFrameProxy* frame = m_process->webFrame(frameID);
2269     MESSAGE_CHECK(frame);
2270
2271     auto transaction = m_pageLoadState.transaction();
2272
2273     if (frame->isMainFrame())
2274         m_pageLoadState.didCommitLoad(transaction);
2275
2276 #if USE(APPKIT)
2277     // FIXME (bug 59111): didCommitLoadForFrame comes too late when restoring a page from b/f cache, making us disable secure event mode in password fields.
2278     // FIXME: A load going on in one frame shouldn't affect text editing in other frames on the page.
2279     m_pageClient.resetSecureInputState();
2280     dismissCorrectionPanel(ReasonForDismissingAlternativeTextIgnored);
2281     m_pageClient.dismissDictionaryLookupPanel();
2282 #endif
2283
2284     clearLoadDependentCallbacks();
2285
2286     frame->didCommitLoad(mimeType, certificateInfo);
2287
2288     if (frame->isMainFrame()) {
2289         m_mainFrameHasCustomContentProvider = frameHasCustomContentProvider;
2290
2291         if (m_mainFrameHasCustomContentProvider) {
2292             // Always assume that the main frame is pinned here, since the custom representation view will handle
2293             // any wheel events and dispatch them to the WKView when necessary.
2294             m_mainFrameIsPinnedToLeftSide = true;
2295             m_mainFrameIsPinnedToRightSide = true;
2296             m_mainFrameIsPinnedToTopSide = true;
2297             m_mainFrameIsPinnedToBottomSide = true;
2298         }
2299         m_pageClient.didCommitLoadForMainFrame(mimeType, frameHasCustomContentProvider);
2300     }
2301
2302     // Even if WebPage has the default pageScaleFactor (and therefore doesn't reset it),
2303     // WebPageProxy's cache of the value can get out of sync (e.g. in the case where a
2304     // plugin is handling page scaling itself) so we should reset it to the default
2305     // for standard main frame loads.
2306     if (frame->isMainFrame() && static_cast<FrameLoadType>(opaqueFrameLoadType) == FrameLoadTypeStandard)
2307         m_pageScaleFactor = 1;
2308
2309     m_pageLoadState.commitChanges();
2310     m_loaderClient->didCommitLoadForFrame(this, frame, navigationID, userData.get());
2311 }
2312
2313 void WebPageProxy::didFinishDocumentLoadForFrame(uint64_t frameID, IPC::MessageDecoder& decoder)
2314 {
2315     RefPtr<API::Object> userData;
2316     WebContextUserMessageDecoder messageDecoder(userData, process());
2317     if (!decoder.decode(messageDecoder))
2318         return;
2319
2320     WebFrameProxy* frame = m_process->webFrame(frameID);
2321     MESSAGE_CHECK(frame);
2322
2323     m_loaderClient->didFinishDocumentLoadForFrame(this, frame, userData.get());
2324 }
2325
2326 void WebPageProxy::didFinishLoadForFrame(uint64_t frameID, uint64_t navigationID, IPC::MessageDecoder& decoder)
2327 {
2328     RefPtr<API::Object> userData;
2329     WebContextUserMessageDecoder messageDecoder(userData, process());
2330     if (!decoder.decode(messageDecoder))
2331         return;
2332
2333     WebFrameProxy* frame = m_process->webFrame(frameID);
2334     MESSAGE_CHECK(frame);
2335
2336     auto transaction = m_pageLoadState.transaction();
2337
2338     if (frame->isMainFrame())
2339         m_pageLoadState.didFinishLoad(transaction);
2340
2341     frame->didFinishLoad();
2342
2343     m_pageLoadState.commitChanges();
2344     m_loaderClient->didFinishLoadForFrame(this, frame, navigationID, userData.get());
2345 }
2346
2347 void WebPageProxy::didFailLoadForFrame(uint64_t frameID, uint64_t navigationID, const ResourceError& error, IPC::MessageDecoder& decoder)
2348 {
2349     RefPtr<API::Object> userData;
2350     WebContextUserMessageDecoder messageDecoder(userData, process());
2351     if (!decoder.decode(messageDecoder))
2352         return;
2353
2354     WebFrameProxy* frame = m_process->webFrame(frameID);
2355     MESSAGE_CHECK(frame);
2356
2357     clearLoadDependentCallbacks();
2358
2359     auto transaction = m_pageLoadState.transaction();
2360
2361     if (frame->isMainFrame())
2362         m_pageLoadState.didFailLoad(transaction);
2363
2364     frame->didFailLoad();
2365
2366     m_pageLoadState.commitChanges();
2367     m_loaderClient->didFailLoadWithErrorForFrame(this, frame, navigationID, error, userData.get());
2368 }
2369
2370 void WebPageProxy::didSameDocumentNavigationForFrame(uint64_t frameID, uint32_t opaqueSameDocumentNavigationType, const String& url, IPC::MessageDecoder& decoder)
2371 {
2372     RefPtr<API::Object> userData;
2373     WebContextUserMessageDecoder messageDecoder(userData, process());
2374     if (!decoder.decode(messageDecoder))
2375         return;
2376
2377     WebFrameProxy* frame = m_process->webFrame(frameID);
2378     MESSAGE_CHECK(frame);
2379     MESSAGE_CHECK_URL(url);
2380
2381     auto transaction = m_pageLoadState.transaction();
2382
2383     if (frame->isMainFrame())
2384         m_pageLoadState.didSameDocumentNavigation(transaction, url);
2385
2386     m_pageLoadState.clearPendingAPIRequestURL(transaction);
2387     frame->didSameDocumentNavigation(url);
2388
2389     m_pageLoadState.commitChanges();
2390     m_loaderClient->didSameDocumentNavigationForFrame(this, frame, static_cast<SameDocumentNavigationType>(opaqueSameDocumentNavigationType), userData.get());
2391 }
2392
2393 void WebPageProxy::didReceiveTitleForFrame(uint64_t frameID, const String& title, IPC::MessageDecoder& decoder)
2394 {
2395     RefPtr<API::Object> userData;
2396     WebContextUserMessageDecoder messageDecoder(userData, process());
2397     if (!decoder.decode(messageDecoder))
2398         return;
2399
2400     WebFrameProxy* frame = m_process->webFrame(frameID);
2401     MESSAGE_CHECK(frame);
2402
2403     auto transaction = m_pageLoadState.transaction();
2404
2405     if (frame->isMainFrame())
2406         m_pageLoadState.setTitle(transaction, title);
2407
2408     frame->didChangeTitle(title);
2409     
2410     m_pageLoadState.commitChanges();
2411     m_loaderClient->didReceiveTitleForFrame(this, title, frame, userData.get());
2412 }
2413
2414 void WebPageProxy::didFirstLayoutForFrame(uint64_t frameID, IPC::MessageDecoder& decoder)
2415 {
2416     RefPtr<API::Object> userData;
2417     WebContextUserMessageDecoder messageDecoder(userData, process());
2418     if (!decoder.decode(messageDecoder))
2419         return;
2420
2421     WebFrameProxy* frame = m_process->webFrame(frameID);
2422     MESSAGE_CHECK(frame);
2423
2424     m_loaderClient->didFirstLayoutForFrame(this, frame, userData.get());
2425 }
2426
2427 void WebPageProxy::didFirstVisuallyNonEmptyLayoutForFrame(uint64_t frameID, IPC::MessageDecoder& decoder)
2428 {
2429     RefPtr<API::Object> userData;
2430     WebContextUserMessageDecoder messageDecoder(userData, process());
2431     if (!decoder.decode(messageDecoder))
2432         return;
2433
2434     WebFrameProxy* frame = m_process->webFrame(frameID);
2435     MESSAGE_CHECK(frame);
2436
2437     m_loaderClient->didFirstVisuallyNonEmptyLayoutForFrame(this, frame, userData.get());
2438 }
2439
2440 void WebPageProxy::didLayout(uint32_t layoutMilestones, IPC::MessageDecoder& decoder)
2441 {
2442     RefPtr<API::Object> userData;
2443     WebContextUserMessageDecoder messageDecoder(userData, process());
2444     if (!decoder.decode(messageDecoder))
2445         return;
2446
2447     m_loaderClient->didLayout(this, static_cast<LayoutMilestones>(layoutMilestones), userData.get());
2448 }
2449
2450 void WebPageProxy::didRemoveFrameFromHierarchy(uint64_t frameID, IPC::MessageDecoder& decoder)
2451 {
2452     RefPtr<API::Object> userData;
2453     WebContextUserMessageDecoder messageDecoder(userData, process());
2454     if (!decoder.decode(messageDecoder))
2455         return;
2456
2457     WebFrameProxy* frame = m_process->webFrame(frameID);
2458     MESSAGE_CHECK(frame);
2459
2460     m_loaderClient->didRemoveFrameFromHierarchy(this, frame, userData.get());
2461 }
2462
2463 void WebPageProxy::didDisplayInsecureContentForFrame(uint64_t frameID, IPC::MessageDecoder& decoder)
2464 {
2465     RefPtr<API::Object> userData;
2466     WebContextUserMessageDecoder messageDecoder(userData, process());
2467     if (!decoder.decode(messageDecoder))
2468         return;
2469
2470     WebFrameProxy* frame = m_process->webFrame(frameID);
2471     MESSAGE_CHECK(frame);
2472
2473     auto transaction = m_pageLoadState.transaction();
2474     m_pageLoadState.didDisplayOrRunInsecureContent(transaction);
2475
2476     m_pageLoadState.commitChanges();
2477     m_loaderClient->didDisplayInsecureContentForFrame(this, frame, userData.get());
2478 }
2479
2480 void WebPageProxy::didRunInsecureContentForFrame(uint64_t frameID, IPC::MessageDecoder& decoder)
2481 {
2482     RefPtr<API::Object> userData;
2483     WebContextUserMessageDecoder messageDecoder(userData, process());
2484     if (!decoder.decode(messageDecoder))
2485         return;
2486
2487     WebFrameProxy* frame = m_process->webFrame(frameID);
2488     MESSAGE_CHECK(frame);
2489
2490     auto transaction = m_pageLoadState.transaction();
2491     m_pageLoadState.didDisplayOrRunInsecureContent(transaction);
2492
2493     m_pageLoadState.commitChanges();
2494     m_loaderClient->didRunInsecureContentForFrame(this, frame, userData.get());
2495 }
2496
2497 void WebPageProxy::didDetectXSSForFrame(uint64_t frameID, IPC::MessageDecoder& decoder)
2498 {
2499     RefPtr<API::Object> userData;
2500     WebContextUserMessageDecoder messageDecoder(userData, process());
2501     if (!decoder.decode(messageDecoder))
2502         return;
2503
2504     WebFrameProxy* frame = m_process->webFrame(frameID);
2505     MESSAGE_CHECK(frame);
2506
2507     m_loaderClient->didDetectXSSForFrame(this, frame, userData.get());
2508 }
2509
2510 void WebPageProxy::frameDidBecomeFrameSet(uint64_t frameID, bool value)
2511 {
2512     WebFrameProxy* frame = m_process->webFrame(frameID);
2513     MESSAGE_CHECK(frame);
2514
2515     frame->setIsFrameSet(value);
2516     if (frame->isMainFrame())
2517         m_frameSetLargestFrame = value ? m_mainFrame : 0;
2518 }
2519
2520 void WebPageProxy::decidePolicyForNavigationAction(uint64_t frameID, const NavigationActionData& navigationActionData, uint64_t originatingFrameID, const WebCore::ResourceRequest& originalRequest, const ResourceRequest& request, uint64_t listenerID, IPC::MessageDecoder& decoder, bool& receivedPolicyAction, uint64_t& policyAction, uint64_t& downloadID)
2521 {
2522     RefPtr<API::Object> userData;
2523     WebContextUserMessageDecoder messageDecoder(userData, process());
2524     if (!decoder.decode(messageDecoder))
2525         return;
2526
2527     auto transaction = m_pageLoadState.transaction();
2528
2529     if (request.url() != m_pageLoadState.pendingAPIRequestURL())
2530         m_pageLoadState.clearPendingAPIRequestURL(transaction);
2531
2532     WebFrameProxy* frame = m_process->webFrame(frameID);
2533     MESSAGE_CHECK(frame);
2534     MESSAGE_CHECK_URL(request.url());
2535     MESSAGE_CHECK_URL(originalRequest.url());
2536
2537     WebFrameProxy* originatingFrame = m_process->webFrame(originatingFrameID);
2538     
2539     RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
2540
2541     ASSERT(!m_inDecidePolicyForNavigationAction);
2542
2543     m_inDecidePolicyForNavigationAction = true;
2544     m_syncNavigationActionPolicyActionIsValid = false;
2545
2546     m_policyClient->decidePolicyForNavigationAction(this, frame, navigationActionData, originatingFrame, originalRequest, request, std::move(listener), userData.get());
2547
2548     m_inDecidePolicyForNavigationAction = false;
2549
2550     // Check if we received a policy decision already. If we did, we can just pass it back.
2551     receivedPolicyAction = m_syncNavigationActionPolicyActionIsValid;
2552     if (m_syncNavigationActionPolicyActionIsValid) {
2553         policyAction = m_syncNavigationActionPolicyAction;
2554         downloadID = m_syncNavigationActionPolicyDownloadID;
2555     }
2556 }
2557
2558 void WebPageProxy::decidePolicyForNewWindowAction(uint64_t frameID, const NavigationActionData& navigationActionData, const ResourceRequest& request, const String& frameName, uint64_t listenerID, IPC::MessageDecoder& decoder)
2559 {
2560     RefPtr<API::Object> userData;
2561     WebContextUserMessageDecoder messageDecoder(userData, process());
2562     if (!decoder.decode(messageDecoder))
2563         return;
2564
2565     WebFrameProxy* frame = m_process->webFrame(frameID);
2566     MESSAGE_CHECK(frame);
2567     MESSAGE_CHECK_URL(request.url());
2568
2569     RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
2570
2571     m_policyClient->decidePolicyForNewWindowAction(this, frame, navigationActionData, request, frameName, std::move(listener), userData.get());
2572 }
2573
2574 void WebPageProxy::decidePolicyForResponse(uint64_t frameID, const ResourceResponse& response, const ResourceRequest& request, bool canShowMIMEType, uint64_t listenerID, IPC::MessageDecoder& decoder)
2575 {
2576     RefPtr<API::Object> userData;
2577     WebContextUserMessageDecoder messageDecoder(userData, process());
2578     if (!decoder.decode(messageDecoder))
2579         return;
2580
2581     WebFrameProxy* frame = m_process->webFrame(frameID);
2582     MESSAGE_CHECK(frame);
2583     MESSAGE_CHECK_URL(request.url());
2584     MESSAGE_CHECK_URL(response.url());
2585
2586     RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
2587
2588     m_policyClient->decidePolicyForResponse(this, frame, response, request, canShowMIMEType, std::move(listener), userData.get());
2589 }
2590
2591 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)
2592 {
2593     ASSERT(!m_inDecidePolicyForResponseSync);
2594
2595     m_inDecidePolicyForResponseSync = true;
2596     m_decidePolicyForResponseRequest = &request;
2597     m_syncMimeTypePolicyActionIsValid = false;
2598
2599     decidePolicyForResponse(frameID, response, request, canShowMIMEType, listenerID, decoder);
2600
2601     m_inDecidePolicyForResponseSync = false;
2602     m_decidePolicyForResponseRequest = 0;
2603
2604     // Check if we received a policy decision already. If we did, we can just pass it back.
2605     receivedPolicyAction = m_syncMimeTypePolicyActionIsValid;
2606     if (m_syncMimeTypePolicyActionIsValid) {
2607         policyAction = m_syncMimeTypePolicyAction;
2608         downloadID = m_syncMimeTypePolicyDownloadID;
2609     }
2610 }
2611
2612 void WebPageProxy::unableToImplementPolicy(uint64_t frameID, const ResourceError& error, IPC::MessageDecoder& decoder)
2613 {
2614     RefPtr<API::Object> userData;
2615     WebContextUserMessageDecoder messageDecoder(userData, process());
2616     if (!decoder.decode(messageDecoder))
2617         return;
2618     
2619     WebFrameProxy* frame = m_process->webFrame(frameID);
2620     MESSAGE_CHECK(frame);
2621
2622     m_policyClient->unableToImplementPolicy(this, frame, error, userData.get());
2623 }
2624
2625 // FormClient
2626
2627 void WebPageProxy::willSubmitForm(uint64_t frameID, uint64_t sourceFrameID, const Vector<std::pair<String, String>>& textFieldValues, uint64_t listenerID, IPC::MessageDecoder& decoder)
2628 {
2629     RefPtr<API::Object> userData;
2630     WebContextUserMessageDecoder messageDecoder(userData, process());
2631     if (!decoder.decode(messageDecoder))
2632         return;
2633
2634     WebFrameProxy* frame = m_process->webFrame(frameID);
2635     MESSAGE_CHECK(frame);
2636
2637     WebFrameProxy* sourceFrame = m_process->webFrame(sourceFrameID);
2638     MESSAGE_CHECK(sourceFrame);
2639
2640     RefPtr<WebFormSubmissionListenerProxy> listener = frame->setUpFormSubmissionListenerProxy(listenerID);
2641     if (!m_formClient.willSubmitForm(this, frame, sourceFrame, textFieldValues, userData.get(), listener.get()))
2642         listener->continueSubmission();
2643 }
2644
2645 // UIClient
2646
2647 void WebPageProxy::createNewPage(const ResourceRequest& request, const WindowFeatures& windowFeatures, uint32_t opaqueModifiers, int32_t opaqueMouseButton, uint64_t& newPageID, WebPageCreationParameters& newPageParameters)
2648 {
2649     RefPtr<WebPageProxy> newPage = m_uiClient->createNewPage(this, request, windowFeatures, static_cast<WebEvent::Modifiers>(opaqueModifiers), static_cast<WebMouseEvent::Button>(opaqueMouseButton));
2650     if (!newPage) {
2651         newPageID = 0;
2652         return;
2653     }
2654
2655     newPageID = newPage->pageID();
2656     newPageParameters = newPage->creationParameters();
2657     process().context().storageManager().cloneSessionStorageNamespace(m_pageID, newPage->pageID());
2658 }
2659     
2660 void WebPageProxy::showPage()
2661 {
2662     m_uiClient->showPage(this);
2663 }
2664
2665 void WebPageProxy::closePage(bool stopResponsivenessTimer)
2666 {
2667     if (stopResponsivenessTimer)
2668         m_process->responsivenessTimer()->stop();
2669
2670     m_pageClient.clearAllEditCommands();
2671     m_uiClient->close(this);
2672 }
2673
2674 void WebPageProxy::runJavaScriptAlert(uint64_t frameID, const String& message, RefPtr<Messages::WebPageProxy::RunJavaScriptAlert::DelayedReply> reply)
2675 {
2676     WebFrameProxy* frame = m_process->webFrame(frameID);
2677     MESSAGE_CHECK(frame);
2678
2679     // Since runJavaScriptAlert() can spin a nested run loop we need to turn off the responsiveness timer.
2680     m_process->responsivenessTimer()->stop();
2681
2682     m_uiClient->runJavaScriptAlert(this, message, frame, [reply]{ reply->send(); });
2683 }
2684
2685 void WebPageProxy::runJavaScriptConfirm(uint64_t frameID, const String& message, RefPtr<Messages::WebPageProxy::RunJavaScriptConfirm::DelayedReply> reply)
2686 {
2687     WebFrameProxy* frame = m_process->webFrame(frameID);
2688     MESSAGE_CHECK(frame);
2689
2690     // Since runJavaScriptConfirm() can spin a nested run loop we need to turn off the responsiveness timer.
2691     m_process->responsivenessTimer()->stop();
2692
2693     m_uiClient->runJavaScriptConfirm(this, message, frame, [reply](bool result) { reply->send(result); });
2694 }
2695
2696 void WebPageProxy::runJavaScriptPrompt(uint64_t frameID, const String& message, const String& defaultValue, RefPtr<Messages::WebPageProxy::RunJavaScriptPrompt::DelayedReply> reply)
2697 {
2698     WebFrameProxy* frame = m_process->webFrame(frameID);
2699     MESSAGE_CHECK(frame);
2700
2701     // Since runJavaScriptPrompt() can spin a nested run loop we need to turn off the responsiveness timer.
2702     m_process->responsivenessTimer()->stop();
2703
2704     m_uiClient->runJavaScriptPrompt(this, message, defaultValue, frame, [reply](const String& result) { reply->send(result); });
2705 }
2706
2707 void WebPageProxy::shouldInterruptJavaScript(bool& result)
2708 {
2709     // Since shouldInterruptJavaScript() can spin a nested run loop we need to turn off the responsiveness timer.
2710     m_process->responsivenessTimer()->stop();
2711
2712     result = m_uiClient->shouldInterruptJavaScript(this);
2713 }
2714
2715 void WebPageProxy::setStatusText(const String& text)
2716 {
2717     m_uiClient->setStatusText(this, text);
2718 }
2719
2720 void WebPageProxy::mouseDidMoveOverElement(const WebHitTestResult::Data& hitTestResultData, uint32_t opaqueModifiers, IPC::MessageDecoder& decoder)
2721 {
2722     RefPtr<API::Object> userData;
2723     WebContextUserMessageDecoder messageDecoder(userData, process());
2724     if (!decoder.decode(messageDecoder))
2725         return;
2726
2727     WebEvent::Modifiers modifiers = static_cast<WebEvent::Modifiers>(opaqueModifiers);
2728
2729     m_uiClient->mouseDidMoveOverElement(this, hitTestResultData, modifiers, userData.get());
2730 }
2731
2732 void WebPageProxy::connectionWillOpen(IPC::Connection* connection)
2733 {
2734     ASSERT(connection == m_process->connection());
2735
2736     m_visitedLinkProvider->addProcess(m_process.get());
2737
2738     m_process->context().storageManager().setAllowedSessionStorageNamespaceConnection(m_pageID, connection);
2739 }
2740
2741 void WebPageProxy::connectionWillClose(IPC::Connection* connection)
2742 {
2743     ASSERT_UNUSED(connection, connection == m_process->connection());
2744
2745     m_process->context().storageManager().setAllowedSessionStorageNamespaceConnection(m_pageID, 0);
2746 }
2747
2748 #if ENABLE(NETSCAPE_PLUGIN_API)
2749 void WebPageProxy::unavailablePluginButtonClicked(uint32_t opaquePluginUnavailabilityReason, const String& mimeType, const String& pluginURLString, const String& pluginspageAttributeURLString, const String& frameURLString, const String& pageURLString)
2750 {
2751     MESSAGE_CHECK_URL(pluginURLString);
2752     MESSAGE_CHECK_URL(pluginspageAttributeURLString);
2753     MESSAGE_CHECK_URL(frameURLString);
2754     MESSAGE_CHECK_URL(pageURLString);
2755
2756     RefPtr<ImmutableDictionary> pluginInformation;
2757     String newMimeType = mimeType;
2758     PluginModuleInfo plugin = m_process->context().pluginInfoStore().findPlugin(newMimeType, URL(URL(), pluginURLString));
2759     pluginInformation = createPluginInformationDictionary(plugin, frameURLString, mimeType, pageURLString, pluginspageAttributeURLString, pluginURLString);
2760
2761     WKPluginUnavailabilityReason pluginUnavailabilityReason = kWKPluginUnavailabilityReasonPluginMissing;
2762     switch (static_cast<RenderEmbeddedObject::PluginUnavailabilityReason>(opaquePluginUnavailabilityReason)) {
2763     case RenderEmbeddedObject::PluginMissing:
2764         pluginUnavailabilityReason = kWKPluginUnavailabilityReasonPluginMissing;
2765         break;
2766     case RenderEmbeddedObject::InsecurePluginVersion:
2767         pluginUnavailabilityReason = kWKPluginUnavailabilityReasonInsecurePluginVersion;
2768         break;
2769     case RenderEmbeddedObject::PluginCrashed:
2770         pluginUnavailabilityReason = kWKPluginUnavailabilityReasonPluginCrashed;
2771         break;
2772     case RenderEmbeddedObject::PluginBlockedByContentSecurityPolicy:
2773         ASSERT_NOT_REACHED();
2774     }
2775
2776     m_uiClient->unavailablePluginButtonClicked(this, pluginUnavailabilityReason, pluginInformation.get());
2777 }
2778 #endif // ENABLE(NETSCAPE_PLUGIN_API)
2779
2780 #if ENABLE(WEBGL)
2781 void WebPageProxy::webGLPolicyForURL(const String& url, uint32_t& loadPolicy)
2782 {
2783     loadPolicy = static_cast<uint32_t>(m_loaderClient->webGLLoadPolicy(this, url));
2784 }
2785
2786 void WebPageProxy::resolveWebGLPolicyForURL(const String& url, uint32_t& loadPolicy)
2787 {
2788     loadPolicy = static_cast<uint32_t>(m_loaderClient->resolveWebGLLoadPolicy(this, url));
2789 }
2790 #endif // ENABLE(WEBGL)
2791
2792 void WebPageProxy::setToolbarsAreVisible(bool toolbarsAreVisible)
2793 {
2794     m_uiClient->setToolbarsAreVisible(this, toolbarsAreVisible);
2795 }
2796
2797 void WebPageProxy::getToolbarsAreVisible(bool& toolbarsAreVisible)
2798 {
2799     toolbarsAreVisible = m_uiClient->toolbarsAreVisible(this);
2800 }
2801
2802 void WebPageProxy::setMenuBarIsVisible(bool menuBarIsVisible)
2803 {
2804     m_uiClient->setMenuBarIsVisible(this, menuBarIsVisible);
2805 }
2806
2807 void WebPageProxy::getMenuBarIsVisible(bool& menuBarIsVisible)
2808 {
2809     menuBarIsVisible = m_uiClient->menuBarIsVisible(this);
2810 }
2811
2812 void WebPageProxy::setStatusBarIsVisible(bool statusBarIsVisible)
2813 {
2814     m_uiClient->setStatusBarIsVisible(this, statusBarIsVisible);
2815 }
2816
2817 void WebPageProxy::getStatusBarIsVisible(bool& statusBarIsVisible)
2818 {
2819     statusBarIsVisible = m_uiClient->statusBarIsVisible(this);
2820 }
2821
2822 void WebPageProxy::setIsResizable(bool isResizable)
2823 {
2824     m_uiClient->setIsResizable(this, isResizable);
2825 }
2826
2827 void WebPageProxy::getIsResizable(bool& isResizable)
2828 {
2829     isResizable = m_uiClient->isResizable(this);
2830 }
2831
2832 void WebPageProxy::setWindowFrame(const FloatRect& newWindowFrame)
2833 {
2834     m_uiClient->setWindowFrame(this, m_pageClient.convertToDeviceSpace(newWindowFrame));
2835 }
2836
2837 void WebPageProxy::getWindowFrame(FloatRect& newWindowFrame)
2838 {
2839     newWindowFrame = m_pageClient.convertToUserSpace(m_uiClient->windowFrame(this));
2840 }
2841     
2842 void WebPageProxy::screenToRootView(const IntPoint& screenPoint, IntPoint& windowPoint)
2843 {
2844     windowPoint = m_pageClient.screenToRootView(screenPoint);
2845 }
2846     
2847 void WebPageProxy::rootViewToScreen(const IntRect& viewRect, IntRect& result)
2848 {
2849     result = m_pageClient.rootViewToScreen(viewRect);
2850 }
2851     
2852 void WebPageProxy::runBeforeUnloadConfirmPanel(const String& message, uint64_t frameID, bool& shouldClose)
2853 {
2854     WebFrameProxy* frame = m_process->webFrame(frameID);
2855     MESSAGE_CHECK(frame);
2856
2857     // Since runBeforeUnloadConfirmPanel() can spin a nested run loop we need to turn off the responsiveness timer.
2858     m_process->responsivenessTimer()->stop();
2859
2860     shouldClose = m_uiClient->runBeforeUnloadConfirmPanel(this, message, frame);
2861 }
2862
2863 #if USE(TILED_BACKING_STORE)
2864 void WebPageProxy::pageDidRequestScroll(const IntPoint& point)
2865 {
2866     m_pageClient.pageDidRequestScroll(point);
2867 }
2868
2869 void WebPageProxy::pageTransitionViewportReady()
2870 {
2871     m_pageClient.pageTransitionViewportReady();
2872 }
2873
2874 void WebPageProxy::didRenderFrame(const WebCore::IntSize& contentsSize, const WebCore::IntRect& coveredRect)
2875 {
2876     m_pageClient.didRenderFrame(contentsSize, coveredRect);
2877 }
2878
2879 #endif
2880
2881 void WebPageProxy::didChangeViewportProperties(const ViewportAttributes& attr)
2882 {
2883     m_pageClient.didChangeViewportProperties(attr);
2884 }
2885
2886 void WebPageProxy::pageDidScroll()
2887 {
2888     m_uiClient->pageDidScroll(this);
2889 #if PLATFORM(MAC)
2890     dismissCorrectionPanel(ReasonForDismissingAlternativeTextIgnored);
2891 #endif
2892 }
2893
2894 void WebPageProxy::runOpenPanel(uint64_t frameID, const FileChooserSettings& settings)
2895 {
2896     if (m_openPanelResultListener) {
2897         m_openPanelResultListener->invalidate();
2898         m_openPanelResultListener = 0;
2899     }
2900
2901     WebFrameProxy* frame = m_process->webFrame(frameID);
2902     MESSAGE_CHECK(frame);
2903
2904     RefPtr<WebOpenPanelParameters> parameters = WebOpenPanelParameters::create(settings);
2905     m_openPanelResultListener = WebOpenPanelResultListenerProxy::create(this);
2906
2907     // Since runOpenPanel() can spin a nested run loop we need to turn off the responsiveness timer.
2908     m_process->responsivenessTimer()->stop();
2909
2910     if (!m_uiClient->runOpenPanel(this, frame, parameters.get(), m_openPanelResultListener.get()))
2911         didCancelForOpenPanel();
2912 }
2913
2914 void WebPageProxy::printFrame(uint64_t frameID)
2915 {
2916     ASSERT(!m_isPerformingDOMPrintOperation);
2917     m_isPerformingDOMPrintOperation = true;
2918
2919     WebFrameProxy* frame = m_process->webFrame(frameID);
2920     MESSAGE_CHECK(frame);
2921
2922     m_uiClient->printFrame(this, frame);
2923
2924     endPrinting(); // Send a message synchronously while m_isPerformingDOMPrintOperation is still true.
2925     m_isPerformingDOMPrintOperation = false;
2926 }
2927
2928 void WebPageProxy::printMainFrame()
2929 {
2930     printFrame(m_mainFrame->frameID());
2931 }
2932
2933 void WebPageProxy::setMediaVolume(float volume)
2934 {
2935     if (volume == m_mediaVolume)
2936         return;
2937     
2938     m_mediaVolume = volume;
2939     
2940     if (!isValid())
2941         return;
2942     
2943     m_process->send(Messages::WebPage::SetMediaVolume(volume), m_pageID);    
2944 }
2945
2946 void WebPageProxy::setMayStartMediaWhenInWindow(bool mayStartMedia)
2947 {
2948     if (mayStartMedia == m_mayStartMediaWhenInWindow)
2949         return;
2950
2951     m_mayStartMediaWhenInWindow = mayStartMedia;
2952
2953     if (!isValid())
2954         return;
2955
2956     process().send(Messages::WebPage::SetMayStartMediaWhenInWindow(mayStartMedia), m_pageID);
2957 }
2958
2959 #if PLATFORM(EFL) || PLATFORM(GTK)
2960 void WebPageProxy::handleDownloadRequest(DownloadProxy* download)
2961 {
2962     m_pageClient.handleDownloadRequest(download);
2963 }
2964 #endif // PLATFORM(EFL) || PLATFORM(GTK)
2965
2966 #if PLATFORM(EFL)
2967 void WebPageProxy::didChangeContentSize(const IntSize& size)
2968 {
2969     m_pageClient.didChangeContentSize(size);
2970 }
2971 #endif
2972
2973 #if ENABLE(INPUT_TYPE_COLOR)
2974 void WebPageProxy::showColorPicker(const WebCore::Color& initialColor, const IntRect& elementRect)
2975 {
2976 #if ENABLE(INPUT_TYPE_COLOR_POPOVER)
2977     // A new popover color well needs to be created (and the previous one destroyed) for
2978     // each activation of a color element.
2979     m_colorPicker = 0;
2980 #endif
2981     if (!m_colorPicker)
2982         m_colorPicker = m_pageClient.createColorPicker(this, initialColor, elementRect);
2983     m_colorPicker->showColorPicker(initialColor);
2984 }
2985
2986 void WebPageProxy::setColorPickerColor(const WebCore::Color& color)
2987 {
2988     ASSERT(m_colorPicker);
2989
2990     m_colorPicker->setSelectedColor(color);
2991 }
2992
2993 void WebPageProxy::endColorPicker()
2994 {
2995     ASSERT(m_colorPicker);
2996
2997     m_colorPicker->endPicker();
2998 }
2999
3000 void WebPageProxy::didChooseColor(const WebCore::Color& color)
3001 {
3002     if (!isValid())
3003         return;
3004
3005     m_process->send(Messages::WebPage::DidChooseColor(color), m_pageID);
3006 }
3007
3008 void WebPageProxy::didEndColorPicker()
3009 {
3010     if (!isValid())
3011         return;
3012
3013     if (m_colorPicker) {
3014         m_colorPicker->invalidate();
3015         m_colorPicker = nullptr;
3016     }
3017
3018     m_process->send(Messages::WebPage::DidEndColorPicker(), m_pageID);
3019 }
3020 #endif
3021
3022 void WebPageProxy::didDraw()
3023 {
3024     m_uiClient->didDraw(this);
3025 }
3026
3027 // Inspector
3028
3029 #if ENABLE(INSPECTOR)
3030
3031 WebInspectorProxy* WebPageProxy::inspector()
3032 {
3033     if (isClosed() || !isValid())
3034         return 0;
3035     return m_inspector.get();
3036 }
3037
3038 #endif
3039
3040 #if ENABLE(FULLSCREEN_API)
3041 WebFullScreenManagerProxy* WebPageProxy::fullScreenManager()
3042 {
3043     return m_fullScreenManager.get();
3044 }
3045 #endif
3046     
3047 #if PLATFORM(IOS)
3048 RefPtr<WebVideoFullscreenManagerProxy> WebPageProxy::videoFullscreenManager()
3049 {
3050     return m_videoFullscreenManager;
3051 }
3052 #endif
3053
3054 // BackForwardList
3055
3056 void WebPageProxy::backForwardAddItem(uint64_t itemID)
3057 {
3058     m_backForwardList->addItem(m_process->webBackForwardItem(itemID));
3059 }
3060
3061 void WebPageProxy::backForwardGoToItem(uint64_t itemID, SandboxExtension::Handle& sandboxExtensionHandle)
3062 {
3063     WebBackForwardListItem* item = m_process->webBackForwardItem(itemID);
3064     if (!item)
3065         return;
3066
3067     bool createdExtension = maybeInitializeSandboxExtensionHandle(URL(URL(), item->url()), sandboxExtensionHandle);
3068     if (createdExtension)
3069         m_process->willAcquireUniversalFileReadSandboxExtension();
3070     m_backForwardList->goToItem(item);
3071 }
3072
3073 void WebPageProxy::backForwardItemAtIndex(int32_t index, uint64_t& itemID)
3074 {
3075     WebBackForwardListItem* item = m_backForwardList->itemAtIndex(index);
3076     itemID = item ? item->itemID() : 0;
3077 }
3078
3079 void WebPageProxy::backForwardBackListCount(int32_t& count)
3080 {
3081     count = m_backForwardList->backListCount();
3082 }
3083
3084 void WebPageProxy::backForwardForwardListCount(int32_t& count)
3085 {
3086     count = m_backForwardList->forwardListCount();
3087 }
3088
3089 void WebPageProxy::editorStateChanged(const EditorState& editorState)
3090 {
3091 #if PLATFORM(COCOA)
3092     bool couldChangeSecureInputState = m_editorState.isInPasswordField != editorState.isInPasswordField || m_editorState.selectionIsNone;
3093     bool closedComposition = !editorState.shouldIgnoreCompositionSelectionChange && !editorState.hasComposition && (m_editorState.hasComposition || m_temporarilyClosedComposition);
3094     m_temporarilyClosedComposition = editorState.shouldIgnoreCompositionSelectionChange && (m_temporarilyClosedComposition || m_editorState.hasComposition) && !editorState.hasComposition;
3095 #endif
3096
3097     m_editorState = editorState;
3098
3099 #if PLATFORM(COCOA)
3100     // Selection being none is a temporary state when editing. Flipping secure input state too quickly was causing trouble (not fully understood).
3101     if (couldChangeSecureInputState && !editorState.selectionIsNone)
3102         m_pageClient.updateSecureInputState();
3103
3104     if (editorState.shouldIgnoreCompositionSelectionChange)
3105         return;
3106
3107     if (closedComposition)
3108         m_pageClient.notifyInputContextAboutDiscardedComposition();
3109     if (editorState.hasComposition) {
3110         // Abandon the current inline input session if selection changed for any other reason but an input method changing the composition.
3111         // FIXME: This logic should be in WebCore, no need to round-trip to UI process to cancel the composition.
3112         cancelComposition();
3113         m_pageClient.notifyInputContextAboutDiscardedComposition();
3114     }
3115 #if PLATFORM(IOS)
3116     else {
3117         // We need to notify the client on iOS to make sure the selection is redrawn.
3118         notifyRevealedSelection();
3119     }
3120 #endif
3121 #elif PLATFORM(EFL) || PLATFORM(GTK)
3122     m_pageClient.updateTextInputState();
3123 #endif
3124 }
3125
3126 // Undo management
3127
3128 void WebPageProxy::registerEditCommandForUndo(uint64_t commandID, uint32_t editAction)
3129 {
3130     registerEditCommand(WebEditCommandProxy::create(commandID, static_cast<EditAction>(editAction), this), Undo);
3131 }
3132
3133 void WebPageProxy::canUndoRedo(uint32_t action, bool& result)
3134 {
3135     result = m_pageClient.canUndoRedo(static_cast<UndoOrRedo>(action));
3136 }
3137
3138 void WebPageProxy::executeUndoRedo(uint32_t action, bool& result)
3139 {
3140     m_pageClient.executeUndoRedo(static_cast<UndoOrRedo>(action));
3141     result = true;
3142 }
3143
3144 void WebPageProxy::clearAllEditCommands()
3145 {
3146     m_pageClient.clearAllEditCommands();
3147 }
3148
3149 void WebPageProxy::didCountStringMatches(const String& string, uint32_t matchCount)
3150 {
3151     m_findClient.didCountStringMatches(this, string, matchCount);
3152 }
3153
3154 void WebPageProxy::didGetImageForFindMatch(const ShareableBitmap::Handle& contentImageHandle, uint32_t matchIndex)
3155 {
3156     m_findMatchesClient.didGetImageForMatchResult(this, WebImage::create(ShareableBitmap::create(contentImageHandle)).get(), matchIndex);
3157 }
3158
3159 void WebPageProxy::setFindIndicator(const FloatRect& selectionRectInWindowCoordinates, const Vector<FloatRect>& textRectsInSelectionRectCoordinates, float contentImageScaleFactor, const ShareableBitmap::Handle& contentImageHandle, bool fadeOut, bool animate)
3160 {
3161     RefPtr<FindIndicator> findIndicator = FindIndicator::create(selectionRectInWindowCoordinates, textRectsInSelectionRectCoordinates, contentImageScaleFactor, contentImageHandle);
3162     m_pageClient.setFindIndicator(findIndicator.release(), fadeOut, animate);
3163 }
3164
3165 void WebPageProxy::didFindString(const String& string, uint32_t matchCount)
3166 {
3167     m_findClient.didFindString(this, string, matchCount);
3168 }
3169
3170 void WebPageProxy::didFindStringMatches(const String& string, Vector<Vector<WebCore::IntRect>> matchRects, int32_t firstIndexAfterSelection)
3171 {
3172     Vector<RefPtr<API::Object>> matches;
3173     matches.reserveInitialCapacity(matchRects.size());
3174
3175     for (const auto& rects : matchRects) {
3176         Vector<RefPtr<API::Object>> apiRects;
3177         apiRects.reserveInitialCapacity(rects.size());
3178
3179         for (const auto& rect : rects)
3180             apiRects.uncheckedAppend(API::Rect::create(toAPI(rect)));
3181
3182         matches.uncheckedAppend(API::Array::create(std::move(apiRects)));
3183     }
3184
3185     m_findMatchesClient.didFindStringMatches(this, string, API::Array::create(std::move(matches)).get(), firstIndexAfterSelection);
3186 }
3187
3188 void WebPageProxy::didFailToFindString(const String& string)
3189 {
3190     m_findClient.didFailToFindString(this, string);
3191 }
3192
3193 bool WebPageProxy::sendMessage(std::unique_ptr<IPC::MessageEncoder> encoder, unsigned messageSendFlags)
3194 {
3195     return m_process->sendMessage(std::move(encoder), messageSendFlags);
3196 }
3197
3198 IPC::Connection* WebPageProxy::messageSenderConnection()
3199 {
3200     return m_process->connection();
3201 }
3202
3203 uint64_t WebPageProxy::messageSenderDestinationID()
3204 {
3205     return m_pageID;
3206 }
3207
3208 void WebPageProxy::valueChangedForPopupMenu(WebPopupMenuProxy*, int32_t newSelectedIndex)
3209 {
3210     m_process->send(Messages::WebPage::DidChangeSelectedIndexForActivePopupMenu(newSelectedIndex), m_pageID);
3211 }
3212
3213 void WebPageProxy::setTextFromItemForPopupMenu(WebPopupMenuProxy*, int32_t index)
3214 {
3215     m_process->send(Messages::WebPage::SetTextForActivePopupMenu(index), m_pageID);
3216 }
3217
3218 NativeWebMouseEvent* WebPageProxy::currentlyProcessedMouseDownEvent()
3219 {
3220     return m_currentlyProcessedMouseDownEvent.get();
3221 }
3222
3223 void WebPageProxy::postMessageToInjectedBundle(const String& messageName, API::Object* messageBody)
3224 {
3225     process().send(Messages::WebPage::PostInjectedBundleMessage(messageName, WebContextUserMessageEncoder(messageBody, process())), m_pageID);
3226 }
3227
3228 #if PLATFORM(GTK)
3229 void WebPageProxy::failedToShowPopupMenu()
3230 {
3231     m_process->send(Messages::WebPage::FailedToShowPopupMenu(), m_pageID);
3232 }
3233 #endif
3234
3235 void WebPageProxy::showPopupMenu(const IntRect& rect, uint64_t textDirection, const Vector<WebPopupItem>& items, int32_t selectedIndex, const PlatformPopupMenuData& data)
3236 {
3237     if (m_activePopupMenu) {
3238 #if PLATFORM(EFL)
3239         m_uiPopupMenuClient.hidePopupMenu(this);
3240 #else
3241         m_activePopupMenu->hidePopupMenu();
3242 #endif
3243         m_activePopupMenu->invalidate();
3244         m_activePopupMenu = 0;
3245     }
3246
3247     m_activePopupMenu = m_pageClient.createPopupMenuProxy(this);
3248
3249     if (!m_activePopupMenu)
3250         return;
3251
3252     // Since showPopupMenu() can spin a nested run loop we need to turn off the responsiveness timer.
3253     m_process->responsivenessTimer()->stop();
3254
3255 #if PLATFORM(EFL)
3256     UNUSED_PARAM(data);
3257     m_uiPopupMenuClient.showPopupMenu(this, m_activePopupMenu.get(), rect, static_cast<TextDirection>(textDirection), m_pageScaleFactor, items, selectedIndex);
3258 #else
3259     RefPtr<WebPopupMenuProxy> protectedActivePopupMenu = m_activePopupMenu;
3260
3261     protectedActivePopupMenu->showPopupMenu(rect, static_cast<TextDirection>(textDirection), m_pageScaleFactor, items, data, selectedIndex);
3262
3263     // Since Efl doesn't use a nested mainloop to show the popup and get the answer, we need to keep the client pointer valid.
3264     // FIXME: The above comment doesn't make any sense since this code is compiled out for EFL.
3265     protectedActivePopupMenu->invalidate();
3266     protectedActivePopupMenu = 0;
3267 #endif
3268 }
3269
3270 void WebPageProxy::hidePopupMenu()
3271 {
3272     if (!m_activePopupMenu)
3273         return;
3274
3275 #if PLATFORM(EFL)
3276     m_uiPopupMenuClient.hidePopupMenu(this);
3277 #else
3278     m_activePopupMenu->hidePopupMenu();
3279 #endif
3280     m_activePopupMenu->invalidate();
3281     m_activePopupMenu = 0;
3282 }
3283
3284 #if ENABLE(CONTEXT_MENUS)
3285 void WebPageProxy::showContextMenu(const IntPoint& menuLocation, const ContextMenuContextData& contextMenuContextData, const Vector<WebContextMenuItemData>& proposedItems, IPC::MessageDecoder& decoder)
3286 {
3287     internalShowContextMenu(menuLocation, contextMenuContextData, proposedItems, decoder);
3288     
3289     // No matter the result of internalShowContextMenu, always notify the WebProcess that the menu is hidden so it starts handling mouse events again.
3290     m_process->send(Messages::WebPage::ContextMenuHidden(), m_pageID);
3291 }
3292
3293 void WebPageProxy::internalShowContextMenu(const IntPoint& menuLocation, const ContextMenuContextData& contextMenuContextData, const Vector<WebContextMenuItemData>& proposedItems, IPC::MessageDecoder& decoder)
3294 {
3295     RefPtr<API::Object> userData;
3296     WebContextUserMessageDecoder messageDecoder(userData, process());
3297     if (!decoder.decode(messageDecoder))
3298         return;
3299
3300     m_activeContextMenuContextData = contextMenuContextData;
3301
3302     if (!m_contextMenuClient.hideContextMenu(this) && m_activeContextMenu) {
3303         m_activeContextMenu->hideContextMenu();
3304         m_activeContextMenu = 0;
3305     }
3306
3307     m_activeContextMenu = m_pageClient.createContextMenuProxy(this);
3308     if (!m_activeContextMenu)
3309         return;
3310
3311     // Since showContextMenu() can spin a nested run loop we need to turn off the responsiveness timer.
3312     m_process->responsivenessTimer()->stop();
3313
3314     // Unless this is an image control, give the PageContextMenuClient one last swipe at changing the menu.
3315     Vector<WebContextMenuItemData> items;
3316     bool useProposedItems = true;
3317     bool askClientToChangeMenu = true;
3318 #if ENABLE(IMAGE_CONTROLS)
3319     if (!contextMenuContextData.controlledImageHandle().isNull())
3320         askClientToChangeMenu = false;
3321 #endif
3322
3323     if (askClientToChangeMenu && m_contextMenuClient.getContextMenuFromProposedMenu(this, proposedItems, items, contextMenuContextData.webHitTestResultData(), userData.get()))
3324         useProposedItems = false;
3325     
3326     const Vector<WebContextMenuItemData>& itemsToShow = useProposedItems ? proposedItems : items;
3327     if (!m_contextMenuClient.showContextMenu(this, menuLocation, itemsToShow))
3328         m_activeContextMenu->showContextMenu(menuLocation, itemsToShow, contextMenuContextData);
3329
3330     m_contextMenuClient.contextMenuDismissed(this);
3331 }
3332
3333 #if ENABLE(IMAGE_CONTROLS)
3334 void WebPageProxy::replaceControlledImage(PassRefPtr<ShareableBitmap> newBitmap)
3335 {
3336     RefPtr<ShareableBitmap> bitmap = newBitmap;
3337     ShareableBitmap::Handle bitmapHandle;
3338     bitmap->createHandle(bitmapHandle);
3339     m_process->send(Messages::WebPage::ReplaceControlledImage(bitmapHandle), m_pageID);
3340 }
3341 #endif
3342
3343 void WebPageProxy::contextMenuItemSelected(const WebContextMenuItemData& item)
3344 {
3345     // Application custom items don't need to round-trip through to WebCore in the WebProcess.
3346     if (item.action() >= ContextMenuItemBaseApplicationTag) {
3347         m_contextMenuClient.customContextMenuItemSelected(this, item);
3348         return;
3349     }
3350
3351 #if PLATFORM(COCOA)
3352     if (item.action() == ContextMenuItemTagSmartCopyPaste) {
3353         setSmartInsertDeleteEnabled(!isSmartInsertDeleteEnabled());
3354         return;
3355     }
3356     if (item.action() == ContextMenuItemTagSmartQuotes) {
3357         TextChecker::setAutomaticQuoteSubstitutionEnabled(!TextChecker::state().isAutomaticQuoteSubstitutionEnabled);
3358         m_process->updateTextCheckerState();
3359         return;
3360     }
3361     if (item.action() == ContextMenuItemTagSmartDashes) {
3362         TextChecker::setAutomaticDashSubstitutionEnabled(!TextChecker::state().isAutomaticDashSubstitutionEnabled);
3363         m_process->updateTextCheckerState();
3364         return;
3365     }
3366     if (item.action() == ContextMenuItemTagSmartLinks) {
3367         TextChecker::setAutomaticLinkDetectionEnabled(!TextChecker::state().isAutomaticLinkDetectionEnabled);
3368         m_process->updateTextCheckerState();
3369         return;
3370     }
3371     if (item.action() == ContextMenuItemTagTextReplacement) {
3372         TextChecker::setAutomaticTextReplacementEnabled(!TextChecker::state().isAutomaticTextReplacementEnabled);
3373         m_process->updateTextCheckerState();
3374         return;
3375     }
3376     if (item.action() == ContextMenuItemTagCorrectSpellingAutomatically) {
3377         TextChecker::setAutomaticSpellingCorrectionEnabled(!TextChecker::state().isAutomaticSpellingCorrectionEnabled);
3378         m_process->updateTextCheckerState();
3379         return;        
3380     }
3381     if (item.action() == ContextMenuItemTagShowSubstitutions) {
3382         TextChecker::toggleSubstitutionsPanelIsShowing();
3383         return;
3384     }
3385 #endif
3386     if (item.action() == ContextMenuItemTagDownloadImageToDisk) {
3387         m_process->context().download(this, URL(URL(), m_activeContextMenuContextData.webHitTestResultData().absoluteImageURL));
3388         return;    
3389     }
3390     if (item.action() == ContextMenuItemTagDownloadLinkToDisk) {
3391         m_process->context().download(this, URL(URL(), m_activeContextMenuContextData.webHitTestResultData().absoluteLinkURL));
3392         return;
3393     }
3394     if (item.action() == ContextMenuItemTagDownloadMediaToDisk) {
3395         m_process->context().download(this, URL(URL(), m_activeContextMenuContextData.webHitTestResultData().absoluteMediaURL));
3396         return;
3397     }
3398     if (item.action() == ContextMenuItemTagCheckSpellingWhileTyping) {
3399         TextChecker::setContinuousSpellCheckingEnabled(!TextChecker::state().isContinuousSpellCheckingEnabled);
3400         m_process->updateTextCheckerState();
3401         return;
3402     }
3403     if (item.action() == ContextMenuItemTagCheckGrammarWithSpelling) {
3404         TextChecker::setGrammarCheckingEnabled(!TextChecker::state().isGrammarCheckingEnabled);
3405         m_process->updateTextCheckerState();
3406         return;
3407     }
3408     if (item.action() == ContextMenuItemTagShowSpellingPanel) {
3409         if (!TextChecker::spellingUIIsShowing())
3410             advanceToNextMisspelling(true);
3411         TextChecker::toggleSpellingUIIsShowing();
3412         return;
3413     }
3414     if (item.action() == ContextMenuItemTagLearnSpelling || item.action() == ContextMenuItemTagIgnoreSpelling)
3415         ++m_pendingLearnOrIgnoreWordMessageCount;
3416
3417     m_process->send(Messages::WebPage::DidSelectItemFromActiveContextMenu(item), m_pageID);
3418 }
3419 #endif // ENABLE(CONTEXT_MENUS)
3420
3421 void WebPageProxy::didChooseFilesForOpenPanel(const Vector<String>& fileURLs)
3422 {
3423     if (!isValid())
3424         return;
3425
3426 #if ENABLE(WEB_PROCESS_SANDBOX)
3427     // FIXME: The sandbox extensions should be sent with the DidChooseFilesForOpenPanel message. This
3428     // is gated on a way of passing SandboxExtension::Handles in a Vector.
3429     for (size_t i = 0; i < fileURLs.size(); ++i) {
3430         SandboxExtension::Handle sandboxExtensionHandle;
3431         SandboxExtension::createHandle(fileURLs[i], SandboxExtension::ReadOnly, sandboxExtensionHandle);
3432         m_process->send(Messages::WebPage::ExtendSandboxForFileFromOpenPanel(sandboxExtensionHandle), m_pageID);
3433     }
3434 #endif
3435
3436     m_process->send(Messages::WebPage::DidChooseFilesForOpenPanel(fileURLs), m_pageID);
3437
3438     m_openPanelResultListener->invalidate();
3439     m_openPanelResultListener = 0;
3440 }
3441
3442 void WebPageProxy::didCancelForOpenPanel()
3443 {
3444     if (!isValid())
3445         return;
3446
3447     m_process->send(Messages::WebPage::DidCancelForOpenPanel(), m_pageID);
3448     
3449     m_openPanelResultListener->invalidate();
3450     m_openPanelResultListener = 0;
3451 }
3452
3453 void WebPageProxy::advanceToNextMisspelling(bool startBeforeSelection)
3454 {
3455     m_process->send(Messages::WebPage::AdvanceToNextMisspelling(startBeforeSelection), m_pageID);
3456 }
3457
3458 void WebPageProxy::changeSpellingToWord(const String& word)
3459 {
3460     if (word.isEmpty())
3461         return;
3462
3463     m_process->send(Messages::WebPage::ChangeSpellingToWord(word), m_pageID);
3464 }
3465
3466 void WebPageProxy::registerEditCommand(PassRefPtr<WebEditCommandProxy> commandProxy, UndoOrRedo undoOrRedo)
3467 {
3468     m_pageClient.registerEditCommand(commandProxy, undoOrRedo);
3469 }
3470
3471 void WebPageProxy::addEditCommand(WebEditCommandProxy* command)
3472 {
3473     m_editCommandSet.add(command);
3474 }
3475
3476 void WebPageProxy::removeEditCommand(WebEditCommandProxy* command)
3477 {
3478     m_editCommandSet.remove(command);
3479
3480     if (!isValid())
3481         return;
3482     m_process->send(Messages::WebPage::DidRemoveEditCommand(command->commandID()), m_pageID);
3483 }
3484
3485 bool WebPageProxy::isValidEditCommand(WebEditCommandProxy* command)
3486 {
3487     return m_editCommandSet.find(command) != m_editCommandSet.end();
3488 }
3489
3490 int64_t WebPageProxy::spellDocumentTag()
3491 {
3492     if (!m_hasSpellDocumentTag) {
3493         m_spellDocumentTag = TextChecker::uniqueSpellDocumentTag(this);
3494         m_hasSpellDocumentTag = true;
3495     }
3496
3497     return m_spellDocumentTag;
3498 }
3499
3500 #if USE(UNIFIED_TEXT_CHECKING)
3501 void WebPageProxy::checkTextOfParagraph(const String& text, uint64_t checkingTypes, Vector<TextCheckingResult>& results)
3502 {
3503     results = TextChecker::checkTextOfParagraph(spellDocumentTag(), text, checkingTypes);
3504 }
3505 #endif
3506
3507 void WebPageProxy::checkSpellingOfString(const String& text, int32_t& misspellingLocation, int32_t& misspellingLength)
3508 {
3509     TextChecker::checkSpellingOfString(spellDocumentTag(), text, misspellingLocation, misspellingLength);
3510 }
3511
3512 void WebPageProxy::checkGrammarOfString(const String& text, Vector<GrammarDetail>& grammarDetails, int32_t& badGrammarLocation, int32_t& badGrammarLength)
3513 {
3514     TextChecker::checkGrammarOfString(spellDocumentTag(), text, grammarDetails, badGrammarLocation, badGrammarLength);
3515 }
3516
3517 void WebPageProxy::spellingUIIsShowing(bool& isShowing)
3518 {
3519     isShowing = TextChecker::spellingUIIsShowing();
3520 }
3521
3522 void WebPageProxy::updateSpellingUIWithMisspelledWord(const String& misspelledWord)
3523 {
3524     TextChecker::updateSpellingUIWithMisspelledWord(spellDocumentTag(), misspelledWord);
3525 }
3526
3527 void WebPageProxy::updateSpellingUIWithGrammarString(const String& badGrammarPhrase, const GrammarDetail& grammarDetail)
3528 {
3529     TextChecker::updateSpellingUIWithGrammarString(spellDocumentTag(), badGrammarPhrase, grammarDetail);
3530 }
3531
3532 void WebPageProxy::getGuessesForWord(const String& word, const String& context, Vector<String>& guesses)
3533 {
3534     TextChecker::getGuessesForWord(spellDocumentTag(), word, context, guesses);
3535 }
3536
3537 void WebPageProxy::learnWord(const String& word)
3538 {
3539     MESSAGE_CHECK(m_pendingLearnOrIgnoreWordMessageCount);
3540     --m_pendingLearnOrIgnoreWordMessageCount;
3541
3542     TextChecker::learnWord(spellDocumentTag(), word);
3543 }
3544
3545 void WebPageProxy::ignoreWord(const String& word)
3546 {
3547     MESSAGE_CHECK(m_pendingLearnOrIgnoreWordMessageCount);
3548     --m_pendingLearnOrIgnoreWordMessageCount;
3549
3550     TextChecker::ignoreWord(spellDocumentTag(), word);
3551 }
3552
3553 void WebPageProxy::requestCheckingOfString(uint64_t requestID, const TextCheckingRequestData& request)
3554 {
3555     TextChecker::requestCheckingOfString(TextCheckerCompletion::create(requestID, request, this));
3556 }
3557
3558 void WebPageProxy::didFinishCheckingText(uint64_t requestID, const Vector<WebCore::TextCheckingResult>& result)
3559 {
3560     m_process->send(Messages::WebPage::DidFinishCheckingText(requestID, result), m_pageID);
3561 }
3562
3563 void WebPageProxy::didCancelCheckingText(uint64_t requestID)
3564 {
3565     m_process->send(Messages::WebPage::DidCancelCheckingText(requestID), m_pageID);
3566 }
3567 // Other
3568
3569 void WebPageProxy::setFocus(bool focused)
3570 {
3571     if (focused)
3572         m_uiClient->focus(this);
3573     else
3574         m_uiClient->unfocus(this);
3575 }
3576
3577 void WebPageProxy::takeFocus(uint32_t direction)
3578 {
3579     m_uiClient->takeFocus(this, (static_cast<FocusDirection>(direction) == FocusDirectionForward) ? kWKFocusDirectionForward : kWKFocusDirectionBackward);
3580 }
3581
3582 void WebPageProxy::setToolTip(const String& toolTip)
3583 {
3584     String oldToolTip = m_toolTip;
3585     m_toolTip = toolTip;
3586     m_pageClient.toolTipChanged(oldToolTip, m_toolTip);
3587 }
3588
3589 void WebPageProxy::setCursor(const WebCore::Cursor& cursor)
3590 {
3591     // The Web process may have asked to change the cursor when the view was in an active window, but
3592     // if it is no longer in a window or the window is not active, then the cursor should not change.
3593     if (m_pageClient.isViewWindowActive())
3594         m_pageClient.setCursor(cursor);
3595 }
3596
3597 void WebPageProxy::setCursorHiddenUntilMouseMoves(bool hiddenUntilMouseMoves)
3598 {
3599     m_pageClient.setCursorHiddenUntilMouseMoves(hiddenUntilMouseMoves);
3600 }
3601
3602 void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled)
3603 {
3604     WebEvent::Type type = static_cast<WebEvent::Type>(opaqueType);
3605
3606     switch (type) {
3607     case WebEvent::NoType:
3608     case WebEvent::MouseMove:
3609         break;
3610
3611     case WebEvent::MouseDown:
3612     case WebEvent::MouseUp:
3613     case WebEvent::Wheel:
3614     case WebEvent::KeyDown:
3615     case WebEvent::KeyUp:
3616     case WebEvent::RawKeyDown:
3617     case WebEvent::Char:
3618 #if ENABLE(TOUCH_EVENTS)
3619     case WebEvent::TouchStart:
3620     case WebEvent::TouchMove:
3621     case WebEvent::TouchEnd:
3622     case WebEvent::TouchCancel:
3623 #endif
3624         m_process->responsivenessTimer()->stop();
3625         break;
3626     }
3627
3628     switch (type) {
3629     case WebEvent::NoType:
3630         break;
3631     case WebEvent::MouseMove:
3632         m_processingMouseMoveEvent = false;
3633         if (m_nextMouseMoveEvent) {
3634             handleMouseEvent(*m_nextMouseMoveEvent);
3635             m_nextMouseMoveEvent = nullptr;
3636         }
3637         break;
3638     case WebEvent::MouseDown:
3639         break;
3640     case WebEvent::MouseUp:
3641         m_currentlyProcessedMouseDownEvent = nullptr;
3642         break;
3643
3644     case WebEvent::Wheel: {
3645         ASSERT(!m_currentlyProcessedWheelEvents.isEmpty());
3646
3647         OwnPtr<Vector<NativeWebWheelEvent>> oldestCoalescedEvent = m_currentlyProcessedWheelEvents.takeFirst();
3648
3649         // FIXME: Dispatch additional events to the didNotHandleWheelEvent client function.
3650         if (!handled) {
3651             if (m_uiClient->implementsDidNotHandleWheelEvent())
3652                 m_uiClient->didNotHandleWheelEvent(this, oldestCoalescedEvent->last());
3653 #if PLATFORM(COCOA)
3654             m_pageClient.wheelEventWasNotHandledByWebCore(oldestCoalescedEvent->last());
3655 #endif
3656         }
3657
3658         if (!m_wheelEventQueue.isEmpty())
3659             processNextQueuedWheelEvent();
3660         break;
3661     }
3662
3663     case WebEvent::KeyDown:
3664     case WebEvent::KeyUp:
3665     case WebEvent::RawKeyDown:
3666     case WebEvent::Char: {
3667         LOG(KeyHandling, "WebPageProxy::didReceiveEvent: %s", webKeyboardEventTypeString(type));
3668
3669         NativeWebKeyboardEvent event = m_keyEventQueue.first();
3670         MESSAGE_CHECK(type == event.type());
3671
3672         m_keyEventQueue.removeFirst();
3673
3674         if (!m_keyEventQueue.isEmpty())
3675             m_process->send(Messages::WebPage::KeyEvent(m_keyEventQueue.first()), m_pageID);
3676
3677         m_pageClient.doneWithKeyEvent(event, handled);
3678         if (handled)
3679             break;
3680
3681         if (m_uiClient->implementsDidNotHandleKeyEvent())
3682             m_uiClient->didNotHandleKeyEvent(this, event);
3683         break;
3684     }
3685 #if ENABLE(TOUCH_EVENTS)
3686     case WebEvent::TouchStart:
3687     case WebEvent::TouchMove:
3688     case WebEvent::TouchEnd:
3689     case WebEvent::TouchCancel: {
3690         QueuedTouchEvents queuedEvents = m_touchEventQueue.first();
3691         MESSAGE_CHECK(type == queuedEvents.forwardedEvent.type());
3692         m_touchEventQueue.removeFirst();
3693
3694         m_pageClient.doneWithTouchEvent(queuedEvents.forwardedEvent, handled);
3695         for (size_t i = 0; i < queuedEvents.deferredTouchEvents.size(); ++i) {
3696             bool isEventHandled = false;
3697             m_pageClient.doneWithTouchEvent(queuedEvents.deferredTouchEvents.at(i), isEventHandled);
3698         }
3699         break;
3700     }
3701 #endif
3702     }
3703 }
3704
3705 void WebPageProxy::stopResponsivenessTimer()
3706 {
3707     m_process->responsivenessTimer()->stop();
3708 }
3709
3710 void WebPageProxy::voidCallback(uint64_t callbackID)
3711 {
3712     RefPtr<VoidCallback> callback = m_voidCallbacks.take(callbackID);
3713     if (!callback) {
3714         // FIXME: Log error or assert.
3715         return;
3716     }
3717
3718     callback->performCallback();
3719 }
3720
3721 void WebPageProxy::dataCallback(const IPC::DataReference& dataReference, uint64_t callbackID)
3722 {
3723     RefPtr<DataCallback> callback = m_dataCallbacks.take(callbackID);
3724     if (!callback) {
3725         // FIXME: Log error or assert.
3726         return;
3727     }
3728
3729     callback->performCallbackWithReturnValue(API::Data::create(dataReference.data(), dataReference.size()).get());
3730 }
3731
3732 void WebPageProxy::imageCallback(const ShareableBitmap::Handle& bitmapHandle, uint64_t callbackID)
3733 {
3734     RefPtr<ImageCallback> callback = m_imageCallbacks.take(callbackID);
3735     if (!callback) {
3736         // FIXME: Log error or assert.
3737         return;
3738     }
3739
3740     callback->performCallbackWithReturnValue(bitmapHandle);
3741 }
3742
3743 void WebPageProxy::stringCallback(const String& resultString, uint64_t callbackID)
3744 {
3745     RefPtr<StringCallback> callback = m_stringCallbacks.take(callbackID);
3746     if (!callback) {
3747         // FIXME: Log error or assert.
3748         // this can validly happen if a load invalidated the callback, though
3749         return;
3750     }
3751
3752     m_loadDependentStringCallbackIDs.remove(callbackID);
3753
3754     callback->performCallbackWithReturnValue(resultString.impl());
3755 }
3756
3757 void WebPageProxy::scriptValueCallback(const IPC::DataReference& dataReference, uint64_t callbackID)
3758 {
3759     RefPtr<ScriptValueCallback> callback = m_scriptValueCallbacks.take(callbackID);
3760     if (!callback) {
3761         // FIXME: Log error or assert.
3762         return;
3763     }
3764
3765     Vector<uint8_t> data;
3766     data.reserveInitialCapacity(dataReference.size());
3767     data.append(dataReference.data(), dataReference.size());
3768
3769     callback->performCallbackWithReturnValue(data.size() ? WebSerializedScriptValue::adopt(data).get() : 0);
3770 }
3771
3772 void WebPageProxy::computedPagesCallback(const Vector<IntRect>& pageRects, double totalScaleFactorForPrinting, uint64_t callbackID)
3773 {
3774     RefPtr<ComputedPagesCallback> callback = m_computedPagesCallbacks.take(callbackID);
3775     if (!callback) {
3776         // FIXME: Log error or assert.
3777         return;
3778     }
3779
3780     callback->performCallbackWithReturnValue(pageRects, totalScaleFactorForPrinting);
3781 }
3782
3783 void WebPageProxy::validateCommandCallback(const String& commandName, bool isEnabled, int state, uint64_t callbackID)
3784 {
3785     RefPtr<ValidateCommandCallback> callback = m_validateCommandCallbacks.take(callbackID);
3786     if (!callback) {
3787         // FIXME: Log error or assert.
3788         return;
3789     }
3790
3791     callback->performCallbackWithReturnValue(commandName.impl(), isEnabled, state);
3792 }
3793
3794 void WebPageProxy::unsignedCallback(uint64_t result, uint64_t callbackID)
3795 {
3796     RefPtr<UnsignedCallback> callback = m_unsignedCallbacks.take(callbackID);
3797     if (!callback) {
3798         // FIXME: Log error or assert.
3799         // this can validly happen if a load invalidated the callback, though
3800         return;
3801     }
3802
3803     callback->performCallbackWithReturnValue(result);
3804 }
3805
3806 void WebPageProxy::editingRangeCallback(const EditingRange& range, uint64_t callbackID)
3807 {
3808     MESSAGE_CHECK(range.isValid());
3809
3810     RefPtr<EditingRangeCallback> callback = m_editingRangeCallbacks.take(callbackID);
3811     if (!callback) {
3812         // FIXME: Log error or assert.
3813         // this can validly happen if a load invalidated the callback, though
3814         return;
3815     }
3816
3817     callback->performCallbackWithReturnValue(range);
3818 }
3819
3820 void WebPageProxy::rectForCharacterRangeCallback(const IntRect& rect, const EditingRange& actualRange, uint64_t callbackID)
3821 {
3822     MESSAGE_CHECK(actualRange.isValid());
3823
3824     RefPtr<RectForCharacterRangeCallback> callback = m_rectForCharacterRangeCallbacks.take(callbackID);
3825     if (!callback) {
3826         // FIXME: Log error or assert.
3827         // this can validly happen if a load invalidated the callback, though
3828         return;
3829     }
3830
3831     callback->performCallbackWithReturnValue(rect, actualRange);
3832 }
3833
3834 #if PLATFORM(GTK)
3835 void WebPageProxy::printFinishedCallback(const ResourceError& printError, uint64_t callbackID)
3836 {
3837     RefPtr<PrintFinishedCallback> callback = m_printFinishedCallbacks.take(callbackID);
3838     if (!callback) {
3839         // FIXME: Log error or assert.
3840         return;
3841     }
3842
3843     RefPtr<API::Error> error = API::Error::create(printError);
3844     callback->performCallbackWithReturnValue(error.get());
3845 }
3846 #endif
3847
3848 void WebPageProxy::focusedFrameChanged(uint64_t frameID)
3849 {
3850     if (!frameID) {
3851         m_focusedFrame = 0;
3852         return;
3853     }
3854
3855     WebFrameProxy* frame = m_process->webFrame(frameID);
3856     MESSAGE_CHECK(frame);
3857
3858     m_focusedFrame = frame;
3859 }
3860
3861 void WebPageProxy::frameSetLargestFrameChanged(uint64_t frameID)
3862 {
3863     if (!frameID) {
3864         m_frameSetLargestFrame = 0;
3865         return;
3866     }
3867
3868     WebFrameProxy* frame = m_process->webFrame(frameID);
3869     MESSAGE_CHECK(frame);
3870
3871     m_frameSetLargestFrame = frame;
3872 }
3873
3874 void WebPageProxy::processDidBecomeUnresponsive()
3875 {
3876     if (!isValid())
3877         return;
3878
3879     updateBackingStoreDiscardableState();
3880
3881     m_loaderClient->processDidBecomeUnresponsive(this);
3882 }
3883
3884 void WebPageProxy::interactionOccurredWhileProcessUnresponsive()
3885 {
3886     if (!isValid())
3887         return;
3888
3889     m_loaderClient->interactionOccurredWhileProcessUnresponsive(this);
3890 }
3891
3892 void WebPageProxy::processDidBecomeResponsive()
3893 {
3894     if (!isValid())
3895         return;
3896     
3897     updateBackingStoreDiscardableState();
3898
3899     m_loaderClient->processDidBecomeResponsive(this);
3900 }
3901
3902 void WebPageProxy::processDidCrash()
3903 {
3904     ASSERT(m_isValid);
3905
3906     resetStateAfterProcessExited();
3907
3908     // FIXME: Should we do this when the process exits cleanly, instead of just upon crashing?
3909     auto transaction = m_pageLoadState.transaction();
3910     m_pageLoadState.reset(transaction);
3911
3912     m_loaderClient->processDidCrash(this);
3913 }
3914
3915 void WebPageProxy::resetState()
3916 {
3917     m_mainFrame = nullptr;
3918     m_drawingArea = nullptr;
3919
3920 #if ENABLE(INSPECTOR)
3921     if (m_inspector) {
3922         m_inspector->invalidate();
3923         m_inspector = nullptr;
3924     }
3925 #endif
3926
3927 #if ENABLE(FULLSCREEN_API)
3928     if (m_fullScreenManager) {
3929         m_fullScreenManager->invalidate();
3930         m_fullScreenManager = nullptr;
3931     }
3932 #endif
3933
3934 #if ENABLE(VIBRATION)
3935     m_vibration->invalidate();
3936 #endif
3937
3938     if (m_openPanelResultListener) {
3939         m_openPanelResultListener->invalidate();
3940         m_openPanelResultListener = nullptr;
3941     }
3942
3943 #if ENABLE(INPUT_TYPE_COLOR)
3944     if (m_colorPicker) {
3945         m_colorPicker->invalidate();
3946         m_colorPicker = nullptr;
3947     }
3948 #endif
3949
3950 #if ENABLE(GEOLOCATION)
3951     m_geolocationPermissionRequestManager.invalidateRequests();
3952 #endif
3953
3954     m_notificationPermissionRequestManager.invalidateRequests();
3955
3956     m_toolTip = String();
3957
3958     m_mainFrameHasHorizontalScrollbar = false;
3959     m_mainFrameHasVerticalScrollbar = false;
3960
3961     m_mainFrameIsPinnedToLeftSide = false;
3962     m_mainFrameIsPinnedToRightSide = false;
3963     m_mainFrameIsPinnedToTopSide = false;
3964     m_mainFrameIsPinnedToBottomSide = false;
3965
3966     m_visibleScrollerThumbRect = IntRect();
3967
3968     invalidateCallbackMap(m_voidCallbacks);
3969     invalidateCallbackMap(m_dataCallbacks);
3970     invalidateCallbackMap(m_imageCallbacks);
3971     invalidateCallbackMap(m_stringCallbacks);
3972     m_loadDependentStringCallbackIDs.clear();
3973     invalidateCallbackMap(m_scriptValueCallbacks);
3974     invalidateCallbackMap(m_computedPagesCallbacks);
3975     invalidateCallbackMap(m_validateCommandCallbacks);
3976     invalidateCallbackMap(m_unsignedCallbacks);
3977     invalidateCallbackMap(m_editingRangeCallbacks);
3978     invalidateCallbackMap(m_rectForCharacterRangeCallbacks);
3979 #if PLATFORM(MAC)
3980     invalidateCallbackMap(m_attributedStringForCharacterRangeCallbacks);
3981 #endif
3982 #if PLATFORM(IOS)
3983     invalidateCallbackMap(m_gestureCallbacks);
3984     invalidateCallbackMap(m_touchesCallbacks);
3985     invalidateCallbackMap(m_autocorrectionCallbacks);
3986     invalidateCallbackMap(m_autocorrectionContextCallbacks);
3987 #endif
3988 #if PLATFORM(GTK)
3989     invalidateCallbackMap(m_printFinishedCallbacks);
3990 #endif
3991
3992     Vector<WebEditCommandProxy*> editCommandVector;
3993     copyToVector(m_editCommandSet, editCommandVector);
3994     m_editCommandSet.clear();
3995     for (size_t i = 0, size = editCommandVector.size(); i < size; ++i)
3996         editCommandVector[i]->invalidate();
3997
3998     m_activePopupMenu = 0;
3999 }
4000
4001 void WebPageProxy::resetStateAfterProcessExited()
4002 {
4003     if (!isValid())
4004         return;
4005
4006     // FIXME: It's weird that resetStateAfterProcessExited() is called even though the process is launching.
4007     ASSERT(m_process->state() == WebProcessProxy::State::Launching || m_process->state() == WebProcessProxy::State::Terminated);
4008
4009     if (m_process->state() == WebProcessProxy::State::Terminated)
4010         m_visitedLinkProvider->removeProcess(m_process.get());
4011
4012     m_process->removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID);
4013
4014     m_isValid = false;
4015     m_isPageSuspended = false;
4016     m_waitingForDidUpdateViewState = false;
4017
4018     if (m_mainFrame) {
4019         m_urlAtProcessExit = m_mainFrame->url();
4020         m_loadStateAtProcessExit = m_mainFrame->frameLoadState().m_state;
4021     }
4022
4023     resetState();
4024
4025     m_pageClient.processDidExit();
4026
4027     m_pageClient.clearAllEditCommands();
4028     m_pendingLearnOrIgnoreWordMessageCount = 0;
4029
4030     // Can't expect DidReceiveEvent notifications from a crashed web process.
4031     m_keyEventQueue.clear();
4032     m_wheelEventQueue.clear();
4033     m_currentlyProcessedWheelEvents.clear();
4034
4035     m_nextMouseMoveEvent = nullptr;
4036     m_currentlyProcessedMouseDownEvent = nullptr;
4037
4038     m_processingMouseMoveEvent = false;
4039
4040 #if ENABLE(TOUCH_EVENTS)
4041     m_touchEventQueue.clear();
4042 #endif
4043
4044     // FIXME: Reset m_editorState.
4045     // FIXME: Notify input methods about abandoned composition.
4046     m_temporarilyClosedComposition = false;
4047
4048 #if PLATFORM(MAC)
4049     dismissCorrectionPanel(ReasonForDismissingAlternativeTextIgnored);
4050     m_pageClient.dismissDictionaryLookupPanel();
4051 #endif
4052 }
4053
4054 WebPageCreationParameters WebPageProxy::creationParameters()
4055 {
4056     WebPageCreationParameters parameters;
4057
4058     parameters.viewSize = m_pageClient.viewSize();
4059     parameters.viewState = m_viewState;
4060     parameters.drawingAreaType = m_drawingArea->type();
4061     parameters.store = m_preferences->store();
4062     parameters.pageGroupData = m_pageGroup->data();
4063     parameters.drawsBackground = m_drawsBackground;
4064     parameters.drawsTransparentBackground = m_drawsTransparentBackground;
4065     parameters.underlayColor = m_underlayColor;
4066     parameters.areMemoryCacheClientCallsEnabled = m_areMemoryCacheClientCallsEnabled;
4067     parameters.useFixedLayout = m_useFixedLayout;
4068     parameters.fixedLayoutSize = m_fixedLayoutSize;
4069     parameters.suppressScrollbarAnimations = m_suppressScrollbarAnimations;
4070     parameters.paginationMode = m_paginationMode;
4071     parameters.paginationBehavesLikeColumns = m_paginationBehavesLikeColumns;
4072     parameters.pageLength = m_pageLength;
4073     parameters.gapBetweenPages = m_gapBetweenPages;
4074     parameters.userAgent = userAgent();
4075     parameters.sessionState = SessionState(m_backForwardList->entries(), m_backForwardList->currentIndex());
4076     parameters.highestUsedBackForwardItemID = WebBackForwardListItem::highedUsedItemID();
4077     parameters.visitedLinkTableID = m_visitedLinkProvider->identifier();
4078     parameters.canRunBeforeUnloadConfirmPanel = m_uiClient->canRunBeforeUnloadConfirmPanel();
4079     parameters.canRunModal = m_canRunModal;
4080     parameters.deviceScaleFactor = deviceScaleFactor();
4081     parameters.mediaVolume = m_mediaVolume;
4082     parameters.mayStartMediaWhenInWindow = m_mayStartMediaWhenInWindow;
4083     parameters.minimumLayoutSize = m_minimumLayoutSize;
4084     parameters.autoSizingShouldExpandToViewHeight = m_autoSizingShouldExpandToViewHeight;
4085     parameters.scrollPinningBehavior = m_scrollPinningBehavior;
4086     parameters.backgroundExtendsBeyondPage = m_backgroundExtendsBeyondPage;
4087     parameters.layerHostingMode = m_layerHostingMode;
4088 #if ENABLE(REMOTE_INSPECTOR)
4089     parameters.allowsRemoteInspection = m_allowsRemoteInspection;
4090 #endif
4091 #if PLATFORM(MAC)
4092     parameters.colorSpace = m_pageClient.colorSpace();
4093 #endif
4094 #if PLATFORM(IOS)
4095     parameters.viewportScreenSize = viewportScreenSize();
4096 #endif
4097
4098     return parameters;
4099 }
4100
4101 void WebPageProxy::enterAcceleratedCompositingMode(const LayerTreeContext& layerTreeContext)
4102 {
4103     m_pageClient.enterAcceleratedCompositingMode(layerTreeContext);
4104 }
4105
4106 void WebPageProxy::exitAcceleratedCompositingMode()
4107 {
4108     m_pageClient.exitAcceleratedCompositingMode();
4109 }
4110
4111 void WebPageProxy::updateAcceleratedCompositingMode(const LayerTreeContext& layerTreeContext)
4112 {
4113     m_pageClient.updateAcceleratedCompositingMode(layerTreeContext);
4114 }
4115
4116 void WebPageProxy::backForwardClear()
4117 {
4118     m_backForwardList->clear();
4119 }
4120
4121 void WebPageProxy::canAuthenticateAgainstProtectionSpaceInFrame(uint64_t frameID, const ProtectionSpace& coreProtectionSpace, bool& canAuthenticate)
4122 {
4123     WebFrameProxy* frame = m_process->webFrame(frameID);
4124     MESSAGE_CHECK(frame);
4125
4126     RefPtr<WebProtectionSpace> protectionSpace = WebProtectionSpace::create(coreProtectionSpace);
4127
4128     canAuthenticate = m_loaderClient->canAuthenticateAgainstProtectionSpaceInFrame(this, frame, protectionSpace.get());
4129 }
4130
4131 void WebPageProxy::didReceiveAuthenticationChallenge(uint64_t frameID, const AuthenticationChallenge& coreChallenge, uint64_t challengeID)
4132 {
4133     didReceiveAuthenticationChallengeProxy(frameID, AuthenticationChallengeProxy::create(coreChallenge, challengeID, m_process->connection()));
4134 }
4135
4136 void WebPageProxy::didReceiveAuthenticationChallengeProxy(uint64_t frameID, PassRefPtr<AuthenticationChallengeProxy> prpAuthenticationChallenge)
4137 {
4138     ASSERT(prpAuthenticationChallenge);
4139
4140     WebFrameProxy* frame = m_process->webFrame(frameID);
4141     MESSAGE_CHECK(frame);
4142
4143     RefPtr<AuthenticationChallengeProxy> authenticationChallenge = prpAuthenticationChallenge;
4144     m_loaderClient->didReceiveAuthenticationChallengeInFrame(this, frame, authenticationChallenge.get());
4145 }
4146
4147 void WebPageProxy::exceededDatabaseQuota(uint64_t frameID, const String& originIdentifier, const String& databaseName, const String& displayName, uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage, PassRefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply> reply)
4148 {
4149     ExceededDatabaseQuotaRecords& records = ExceededDatabaseQuotaRecords::shared();
4150     OwnPtr<ExceededDatabaseQuotaRecords::Record> newRecord =  records.createRecord(frameID,
4151         originIdentifier, databaseName, displayName, currentQuota, currentOriginUsage,
4152         currentDatabaseUsage, expectedUsage, reply);
4153     records.add(newRecord.release());
4154
4155     if (records.areBeingProcessed())
4156         return;
4157
4158     ExceededDatabaseQuotaRecords::Record* record = records.next();
4159     while (record) {
4160         WebFrameProxy* frame = m_process->webFrame(record->frameID);
4161         MESSAGE_CHECK(frame);
4162
4163         RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::createFromDatabaseIdentifier(record->originIdentifier);
4164
4165         uint64_t newQuota = m_uiClient->exceededDatabaseQuota(this, frame, origin.get(),
4166             record->databaseName, record->displayName, record->currentQuota,
4167             record->currentOriginUsage, record->currentDatabaseUsage, record->expectedUsage);
4168
4169         record->reply->send(newQuota);
4170         record = records.next();
4171     }
4172 }
4173
4174 void WebPageProxy::requestGeolocationPermissionForFrame(uint64_t geolocationID, uint64_t frameID, String originIdentifier)
4175 {
4176     WebFrameProxy* frame = m_process->webFrame(frameID);
4177     MESSAGE_CHECK(frame);
4178
4179     // FIXME: Geolocation should probably be using toString() as its string representation instead of databaseIdentifier().
4180     RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::createFromDatabaseIdentifier(originIdentifier);
4181     RefPtr<GeolocationPermissionRequestProxy> request = m_geolocationPermissionRequestManager.createRequest(geolocationID);
4182
4183     if (m_uiClient->decidePolicyForGeolocationPermissionRequest(this, frame, origin.get(), request.get()))
4184         return;
4185
4186     if (m_pageClient.decidePolicyForGeolocationPermissionRequest(*frame, *origin, *request))
4187         return;
4188
4189     request->deny();
4190 }
4191
4192 void WebPageProxy::requestNotificationPermission(uint64_t requestID, const String& originString)
4193 {
4194     if (!isRequestIDValid(requestID))
4195         return;
4196
4197     RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::createFromString(originString);
4198     RefPtr<NotificationPermissionRequest> request = m_notificationPermissionRequestManager.createRequest(requestID);
4199     
4200     if (!m_uiClient->decidePolicyForNotificationPermissionRequest(this, origin.get(), request.get()))
4201         request->deny();
4202 }
4203
4204 void WebPageProxy::showNotification(const String& title, const String& body, const String& iconURL, const String& tag, const String& lang, const String& dir, const String& originString, uint64_t notificationID)
4205 {
4206     m_process->context().supplement<WebNotificationManagerProxy>()->show(this, title, body, iconURL, tag, lang, dir, originString, notificationID);
4207 }
4208
4209 void WebPageProxy::cancelNotification(uint64_t notificationID)
4210 {
4211     m_process->context().supplement<WebNotificationManagerProxy>()->cancel(this, notificationID);
4212 }
4213
4214 void WebPageProxy::clearNotifications(const Vector<uint64_t>& notificationIDs)
4215 {
4216     m_process->context().supplement<WebNotificationManagerProxy>()->clearNotifications(this, notificationIDs);
4217 }
4218
4219 void WebPageProxy::didDestroyNotification(uint64_t notificationID)
4220 {
4221     m_process->context().supplement<WebNotificationManagerProxy>()->didDestroyNotification(this, notificationID);
4222 }
4223
4224 float WebPageProxy::headerHeight(WebFrameProxy* frame)
4225 {
4226     if (frame->isDisplayingPDFDocument())
4227         return 0;
4228     return m_uiClient->headerHeight(this, frame);
4229 }
4230
4231 float WebPageProxy::footerHeight(WebFrameProxy* frame)
4232 {
4233     if (frame->isDisplayingPDFDocument())
4234         return 0;
4235     return m_uiClient->footerHeight(this, frame);
4236 }
4237
4238 void WebPageProxy::drawHeader(WebFrameProxy* frame, const FloatRect& rect)
4239 {
4240     if (frame->isDisplayingPDFDocument())
4241         return;
4242     m_uiClient->drawHeader(this, frame, rect);
4243 }
4244
4245 void WebPageProxy::drawFooter(WebFrameProxy* frame, const FloatRect& rect)
4246 {
4247     if (frame->isDisplayingPDFDocument())
4248         return;
4249     m_uiClient->drawFooter(this, frame, rect);
4250 }
4251
4252 void WebPageProxy::runModal()
4253 {
4254     // Since runModal() can (and probably will) spin a nested run loop we need to turn off the responsiveness timer.
4255     m_process->responsivenessTimer()->stop();
4256
4257     // Our Connection's run loop might have more messages waiting to be handled after this RunModal message.
4258     // To make sure they are handled inside of the the nested modal run loop we must first signal the Connection's
4259     // run loop so we're guaranteed that it has a chance to wake up.
4260     // See http://webkit.org/b/89590 for more discussion.
4261     m_process->connection()->wakeUpRunLoop();
4262
4263     m_uiClient->runModal(this);
4264 }
4265
4266 void WebPageProxy::notifyScrollerThumbIsVisibleInRect(const IntRect& scrollerThumb)
4267 {
4268     m_visibleScrollerThumbRect = scrollerThumb;
4269 }
4270
4271 void WebPageProxy::recommendedScrollbarStyleDidChange(int32_t newStyle)
4272 {
4273 #if USE(APPKIT)
4274     m_pageClient.recommendedScrollbarStyleDidChange(newStyle);
4275 #else
4276     UNUSED_PARAM(newStyle);
4277 #endif
4278 }
4279
4280 void WebPageProxy::didChangeScrollbarsForMainFrame(bool hasHorizontalScrollbar, bool hasVerticalScrollbar)
4281 {
4282     m_mainFrameHasHorizontalScrollbar = hasHorizontalScrollbar;
4283     m_mainFrameHasVerticalScrollbar = hasVerticalScrollbar;
4284 }
4285
4286 void WebPageProxy::didChangeScrollOffsetPinningForMainFrame(bool pinnedToLeftSide, bool pinnedToRightSide, bool pinnedToTopSide, bool pinnedToBottomSide)
4287 {
4288     m_mainFrameIsPinnedToLeftSide = pinnedToLeftSide;
4289     m_mainFrameIsPinnedToRightSide = pinnedToRightSide;
4290     m_mainFrameIsPinnedToTopSide = pinnedToTopSide;
4291     m_mainFrameIsPinnedToBottomSide = pinnedToBottomSide;
4292 }
4293
4294 void WebPageProxy::didChangePageCount(unsigned pageCount)
4295 {
4296     m_pageCount = pageCount;
4297 }
4298
4299 void WebPageProxy::pageExtendedBackgroundColorDidChange(Color backgroundColor)