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