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