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