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