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