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