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