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