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