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