Crash under WKPageCreateSnapshotOfVisibleContent if there is no response from the...
[WebKit-https.git] / Source / WebKit2 / UIProcess / WebPageProxy.cpp
1 /*
2  * Copyright (C) 2010, 2011 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "WebPageProxy.h"
28
29 #include "AuthenticationChallengeProxy.h"
30 #include "AuthenticationDecisionListener.h"
31 #include "DataReference.h"
32 #include "DownloadProxy.h"
33 #include "DrawingAreaProxy.h"
34 #include "FindIndicator.h"
35 #include "MessageID.h"
36 #include "NativeWebKeyboardEvent.h"
37 #include "NativeWebMouseEvent.h"
38 #include "PageClient.h"
39 #include "PrintInfo.h"
40 #include "SessionState.h"
41 #include "StringPairVector.h"
42 #include "TextChecker.h"
43 #include "TextCheckerState.h"
44 #include "WKContextPrivate.h"
45 #include "WebBackForwardList.h"
46 #include "WebBackForwardListItem.h"
47 #include "WebCertificateInfo.h"
48 #include "WebContext.h"
49 #include "WebContextMenuProxy.h"
50 #include "WebContextUserMessageCoders.h"
51 #include "WebCoreArgumentCoders.h"
52 #include "WebData.h"
53 #include "WebEditCommandProxy.h"
54 #include "WebEvent.h"
55 #include "WebFormSubmissionListenerProxy.h"
56 #include "WebFramePolicyListenerProxy.h"
57 #include "WebFullScreenManagerProxy.h"
58 #include "WebInspectorProxy.h"
59 #include "WebOpenPanelResultListenerProxy.h"
60 #include "WebPageCreationParameters.h"
61 #include "WebPageGroup.h"
62 #include "WebPageGroupData.h"
63 #include "WebPageMessages.h"
64 #include "WebPopupItem.h"
65 #include "WebPopupMenuProxy.h"
66 #include "WebPreferences.h"
67 #include "WebProcessMessages.h"
68 #include "WebProcessProxy.h"
69 #include "WebProtectionSpace.h"
70 #include "WebSecurityOrigin.h"
71 #include "WebURLRequest.h"
72 #include <WebCore/DragData.h>
73 #include <WebCore/FloatRect.h>
74 #include <WebCore/FocusDirection.h>
75 #include <WebCore/MIMETypeRegistry.h>
76 #include <WebCore/WindowFeatures.h>
77 #include <stdio.h>
78
79 #if PLATFORM(WIN)
80 #include "WebDragSource.h"
81 #include <WebCore/BitmapInfo.h>
82 #include <WebCore/COMPtr.h>
83 #include <WebCore/WCDataObject.h>
84 #include <shlobj.h>
85 #endif
86
87 #ifndef NDEBUG
88 #include <wtf/RefCountedLeakCounter.h>
89 #endif
90
91 // This controls what strategy we use for mouse wheel coalesing.
92 #define MERGE_WHEEL_EVENTS 0
93
94 #define MESSAGE_CHECK(assertion) MESSAGE_CHECK_BASE(assertion, process()->connection())
95
96 using namespace WebCore;
97
98 namespace WebKit {
99
100 WKPageDebugPaintFlags WebPageProxy::s_debugPaintFlags = 0;
101
102 #ifndef NDEBUG
103 static WTF::RefCountedLeakCounter webPageProxyCounter("WebPageProxy");
104 #endif
105
106 PassRefPtr<WebPageProxy> WebPageProxy::create(PageClient* pageClient, PassRefPtr<WebProcessProxy> process, WebPageGroup* pageGroup, uint64_t pageID)
107 {
108     return adoptRef(new WebPageProxy(pageClient, process, pageGroup, pageID));
109 }
110
111 WebPageProxy::WebPageProxy(PageClient* pageClient, PassRefPtr<WebProcessProxy> process, WebPageGroup* pageGroup, uint64_t pageID)
112     : m_pageClient(pageClient)
113     , m_process(process)
114     , m_pageGroup(pageGroup)
115     , m_mainFrame(0)
116     , m_userAgent(standardUserAgent())
117     , m_geolocationPermissionRequestManager(this)
118     , m_estimatedProgress(0)
119     , m_isInWindow(m_pageClient->isViewInWindow())
120     , m_isVisible(m_pageClient->isViewVisible())
121     , m_backForwardList(WebBackForwardList::create(this))
122     , m_textZoomFactor(1)
123     , m_pageZoomFactor(1)
124     , m_viewScaleFactor(1)
125     , m_drawsBackground(true)
126     , m_drawsTransparentBackground(false)
127     , m_areMemoryCacheClientCallsEnabled(true)
128     , m_useFixedLayout(false)
129     , m_isValid(true)
130     , m_isClosed(false)
131     , m_isInPrintingMode(false)
132     , m_isPerformingDOMPrintOperation(false)
133     , m_inDecidePolicyForMIMEType(false)
134     , m_syncMimeTypePolicyActionIsValid(false)
135     , m_syncMimeTypePolicyAction(PolicyUse)
136     , m_syncMimeTypePolicyDownloadID(0)
137     , m_inDecidePolicyForNavigationAction(false)
138     , m_syncNavigationActionPolicyActionIsValid(false)
139     , m_syncNavigationActionPolicyAction(PolicyUse)
140     , m_syncNavigationActionPolicyDownloadID(0)
141     , m_processingWheelEvent(false)
142     , m_processingMouseMoveEvent(false)
143     , m_pageID(pageID)
144 #if PLATFORM(MAC)
145     , m_isSmartInsertDeleteEnabled(TextChecker::isSmartInsertDeleteEnabled())
146 #endif
147     , m_spellDocumentTag(0)
148     , m_hasSpellDocumentTag(false)
149     , m_pendingLearnOrIgnoreWordMessageCount(0)
150     , m_mainFrameHasCustomRepresentation(false)
151     , m_currentDragOperation(DragOperationNone)
152     , m_mainFrameHasHorizontalScrollbar(false)
153     , m_mainFrameHasVerticalScrollbar(false)
154     , m_mainFrameIsPinnedToLeftSide(false)
155     , m_mainFrameIsPinnedToRightSide(false)
156 {
157 #ifndef NDEBUG
158     webPageProxyCounter.increment();
159 #endif
160
161     WebContext::statistics().wkPageCount++;
162
163     m_pageGroup->addPage(this);
164 }
165
166 WebPageProxy::~WebPageProxy()
167 {
168     if (!m_isClosed)
169         close();
170
171     WebContext::statistics().wkPageCount--;
172
173     if (m_hasSpellDocumentTag)
174         TextChecker::closeSpellDocumentWithTag(m_spellDocumentTag);
175
176     m_pageGroup->removePage(this);
177
178 #ifndef NDEBUG
179     webPageProxyCounter.decrement();
180 #endif
181 }
182
183 WebProcessProxy* WebPageProxy::process() const
184 {
185     return m_process.get();
186 }
187
188 bool WebPageProxy::isValid()
189 {
190     // A page that has been explicitly closed is never valid.
191     if (m_isClosed)
192         return false;
193
194     return m_isValid;
195 }
196
197 void WebPageProxy::setDrawingArea(PassOwnPtr<DrawingAreaProxy> drawingArea)
198 {
199     if (drawingArea == m_drawingArea)
200         return;
201
202     m_drawingArea = drawingArea;
203 }
204
205 void WebPageProxy::initializeLoaderClient(const WKPageLoaderClient* loadClient)
206 {
207     m_loaderClient.initialize(loadClient);
208 }
209
210 void WebPageProxy::initializePolicyClient(const WKPagePolicyClient* policyClient)
211 {
212     m_policyClient.initialize(policyClient);
213 }
214
215 void WebPageProxy::initializeFormClient(const WKPageFormClient* formClient)
216 {
217     m_formClient.initialize(formClient);
218 }
219
220 void WebPageProxy::initializeResourceLoadClient(const WKPageResourceLoadClient* client)
221 {
222     m_resourceLoadClient.initialize(client);
223 }
224
225 void WebPageProxy::initializeUIClient(const WKPageUIClient* client)
226 {
227     if (!isValid())
228         return;
229
230     m_uiClient.initialize(client);
231
232     process()->send(Messages::WebPage::SetCanRunBeforeUnloadConfirmPanel(m_uiClient.canRunBeforeUnloadConfirmPanel()), m_pageID);
233     process()->send(Messages::WebPage::SetCanRunModal(m_uiClient.canRunModal()), m_pageID);
234 }
235
236 void WebPageProxy::initializeFindClient(const WKPageFindClient* client)
237 {
238     m_findClient.initialize(client);
239 }
240
241 void WebPageProxy::initializeContextMenuClient(const WKPageContextMenuClient* client)
242 {
243     m_contextMenuClient.initialize(client);
244 }
245
246 void WebPageProxy::reattachToWebProcess()
247 {
248     ASSERT(!isValid());
249
250     m_isValid = true;
251
252     m_process = m_process->context()->relaunchProcessIfNecessary();
253     process()->addExistingWebPage(this, m_pageID);
254
255     initializeWebPage();
256
257     m_pageClient->didRelaunchProcess();
258 }
259
260 void WebPageProxy::reattachToWebProcessWithItem(WebBackForwardListItem* item)
261 {
262     if (item && item != m_backForwardList->currentItem())
263         m_backForwardList->goToItem(item);
264     
265     reattachToWebProcess();
266
267     if (!item)
268         return;
269
270     SandboxExtension::Handle sandboxExtensionHandle;
271     initializeSandboxExtensionHandle(KURL(KURL(), item->url()), sandboxExtensionHandle);
272     process()->send(Messages::WebPage::GoToBackForwardItem(item->itemID(), sandboxExtensionHandle), m_pageID);
273 }
274
275 void WebPageProxy::initializeWebPage()
276 {
277     ASSERT(isValid());
278
279     BackForwardListItemVector items = m_backForwardList->entries();
280     for (size_t i = 0; i < items.size(); ++i)
281         process()->registerNewWebBackForwardListItem(items[i].get());
282
283     m_drawingArea = m_pageClient->createDrawingAreaProxy();
284     ASSERT(m_drawingArea);
285
286     process()->send(Messages::WebProcess::CreateWebPage(m_pageID, creationParameters()), 0);
287 }
288
289 void WebPageProxy::close()
290 {
291     if (!isValid())
292         return;
293
294     m_isClosed = true;
295
296     m_backForwardList->pageClosed();
297     m_pageClient->pageClosed();
298
299     process()->disconnectFramesFromPage(this);
300     m_mainFrame = 0;
301
302 #if ENABLE(INSPECTOR)
303     if (m_inspector) {
304         m_inspector->invalidate();
305         m_inspector = 0;
306     }
307 #endif
308
309 #if ENABLE(FULLSCREEN_API)
310     if (m_fullScreenManager) {
311         m_fullScreenManager->invalidate();
312         m_fullScreenManager = 0;
313     }
314 #endif
315
316     if (m_openPanelResultListener) {
317         m_openPanelResultListener->invalidate();
318         m_openPanelResultListener = 0;
319     }
320
321     m_geolocationPermissionRequestManager.invalidateRequests();
322
323     m_toolTip = String();
324
325     m_mainFrameHasHorizontalScrollbar = false;
326     m_mainFrameHasVerticalScrollbar = false;
327
328     m_mainFrameIsPinnedToLeftSide = false;
329     m_mainFrameIsPinnedToRightSide = false;
330
331     m_visibleScrollerThumbRect = IntRect();
332
333     invalidateCallbackMap(m_voidCallbacks);
334     invalidateCallbackMap(m_dataCallbacks);
335     invalidateCallbackMap(m_stringCallbacks);
336     m_loadDependentStringCallbackIDs.clear();
337     invalidateCallbackMap(m_scriptValueCallbacks);
338     invalidateCallbackMap(m_computedPagesCallbacks);
339
340     Vector<WebEditCommandProxy*> editCommandVector;
341     copyToVector(m_editCommandSet, editCommandVector);
342     m_editCommandSet.clear();
343     for (size_t i = 0, size = editCommandVector.size(); i < size; ++i)
344         editCommandVector[i]->invalidate();
345
346     m_activePopupMenu = 0;
347
348     m_estimatedProgress = 0.0;
349     
350     m_loaderClient.initialize(0);
351     m_policyClient.initialize(0);
352     m_uiClient.initialize(0);
353
354     m_drawingArea.clear();
355
356     process()->responsivenessTimer()->stop();
357
358     process()->send(Messages::WebPage::Close(), m_pageID);
359     process()->removeWebPage(m_pageID);
360 }
361
362 bool WebPageProxy::tryClose()
363 {
364     if (!isValid())
365         return true;
366
367     process()->send(Messages::WebPage::TryClose(), m_pageID);
368     return false;
369 }
370
371 void WebPageProxy::initializeSandboxExtensionHandle(const KURL& url, SandboxExtension::Handle& sandboxExtensionHandle)
372 {
373     if (!url.isLocalFile())
374         return;
375
376     // Don't give the inspector full access to the file system.
377     if (WebInspectorProxy::isInspectorPage(this))
378         return;
379
380     SandboxExtension::createHandle("/", SandboxExtension::ReadOnly, sandboxExtensionHandle);
381 }
382
383 void WebPageProxy::loadURL(const String& url)
384 {
385     setPendingAPIRequestURL(url);
386
387     if (!isValid())
388         reattachToWebProcess();
389
390     SandboxExtension::Handle sandboxExtensionHandle;
391     initializeSandboxExtensionHandle(KURL(KURL(), url), sandboxExtensionHandle);
392     process()->send(Messages::WebPage::LoadURL(url, sandboxExtensionHandle), m_pageID);
393 }
394
395 void WebPageProxy::loadURLRequest(WebURLRequest* urlRequest)
396 {
397     setPendingAPIRequestURL(urlRequest->resourceRequest().url());
398
399     if (!isValid())
400         reattachToWebProcess();
401
402     SandboxExtension::Handle sandboxExtensionHandle;
403     initializeSandboxExtensionHandle(urlRequest->resourceRequest().url(), sandboxExtensionHandle);
404     process()->send(Messages::WebPage::LoadURLRequest(urlRequest->resourceRequest(), sandboxExtensionHandle), m_pageID);
405 }
406
407 void WebPageProxy::loadHTMLString(const String& htmlString, const String& baseURL)
408 {
409     if (!isValid())
410         reattachToWebProcess();
411
412     process()->send(Messages::WebPage::LoadHTMLString(htmlString, baseURL), m_pageID);
413 }
414
415 void WebPageProxy::loadAlternateHTMLString(const String& htmlString, const String& baseURL, const String& unreachableURL)
416 {
417     if (!isValid())
418         reattachToWebProcess();
419
420     if (m_mainFrame)
421         m_mainFrame->setUnreachableURL(unreachableURL);
422
423     process()->send(Messages::WebPage::LoadAlternateHTMLString(htmlString, baseURL, unreachableURL), m_pageID);
424 }
425
426 void WebPageProxy::loadPlainTextString(const String& string)
427 {
428     if (!isValid())
429         reattachToWebProcess();
430
431     process()->send(Messages::WebPage::LoadPlainTextString(string), m_pageID);
432 }
433
434 void WebPageProxy::stopLoading()
435 {
436     if (!isValid())
437         return;
438     process()->send(Messages::WebPage::StopLoading(), m_pageID);
439 }
440
441 void WebPageProxy::reload(bool reloadFromOrigin)
442 {
443     if (m_backForwardList->currentItem())
444         setPendingAPIRequestURL(m_backForwardList->currentItem()->url());
445
446     if (!isValid()) {
447         reattachToWebProcessWithItem(m_backForwardList->currentItem());
448         return;
449     }
450
451     process()->send(Messages::WebPage::Reload(reloadFromOrigin), m_pageID);
452 }
453
454 void WebPageProxy::goForward()
455 {
456     if (isValid() && !canGoForward())
457         return;
458
459     WebBackForwardListItem* forwardItem = m_backForwardList->forwardItem();
460     if (forwardItem)
461         setPendingAPIRequestURL(forwardItem->url());
462
463     if (!isValid()) {
464         reattachToWebProcessWithItem(forwardItem);
465         return;
466     }
467
468     SandboxExtension::Handle sandboxExtensionHandle;
469     initializeSandboxExtensionHandle(KURL(KURL(), forwardItem->url()), sandboxExtensionHandle);
470     process()->send(Messages::WebPage::GoForward(forwardItem->itemID(), sandboxExtensionHandle), m_pageID);
471 }
472
473 bool WebPageProxy::canGoForward() const
474 {
475     return m_backForwardList->forwardItem();
476 }
477
478 void WebPageProxy::goBack()
479 {
480     if (isValid() && !canGoBack())
481         return;
482
483     WebBackForwardListItem* backItem = m_backForwardList->backItem();
484     if (backItem)
485         setPendingAPIRequestURL(backItem->url());
486
487     if (!isValid()) {
488         reattachToWebProcessWithItem(backItem);
489         return;
490     }
491
492     SandboxExtension::Handle sandboxExtensionHandle;
493     initializeSandboxExtensionHandle(KURL(KURL(), backItem->url()), sandboxExtensionHandle);
494     process()->send(Messages::WebPage::GoBack(backItem->itemID(), sandboxExtensionHandle), m_pageID);
495 }
496
497 bool WebPageProxy::canGoBack() const
498 {
499     return m_backForwardList->backItem();
500 }
501
502 void WebPageProxy::goToBackForwardItem(WebBackForwardListItem* item)
503 {
504     if (!isValid()) {
505         reattachToWebProcessWithItem(item);
506         return;
507     }
508     
509     setPendingAPIRequestURL(item->url());
510
511     SandboxExtension::Handle sandboxExtensionHandle;
512     initializeSandboxExtensionHandle(KURL(KURL(), item->url()), sandboxExtensionHandle);
513     process()->send(Messages::WebPage::GoToBackForwardItem(item->itemID(), sandboxExtensionHandle), m_pageID);
514 }
515
516 void WebPageProxy::didChangeBackForwardList(WebBackForwardListItem* added, Vector<RefPtr<APIObject> >* removed)
517 {
518     m_loaderClient.didChangeBackForwardList(this, added, removed);
519 }
520
521 void WebPageProxy::shouldGoToBackForwardListItem(uint64_t itemID, bool& shouldGoToBackForwardItem)
522 {
523     WebBackForwardListItem* item = process()->webBackForwardItem(itemID);
524     shouldGoToBackForwardItem = item && m_loaderClient.shouldGoToBackForwardListItem(this, item);
525 }
526     
527 bool WebPageProxy::canShowMIMEType(const String& mimeType) const
528 {
529     if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType))
530         return true;
531
532     if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType))
533         return true;
534
535     if (mimeType.startsWith("text/", false))
536         return !MIMETypeRegistry::isUnsupportedTextMIMEType(mimeType);
537
538     String newMimeType = mimeType;
539     PluginInfoStore::Plugin plugin = m_process->context()->pluginInfoStore()->findPlugin(newMimeType, KURL());
540     if (!plugin.path.isNull())
541         return true;
542
543     return false;
544 }
545
546 void WebPageProxy::setDrawsBackground(bool drawsBackground)
547 {
548     if (m_drawsBackground == drawsBackground)
549         return;
550
551     m_drawsBackground = drawsBackground;
552
553     if (isValid())
554         process()->send(Messages::WebPage::SetDrawsBackground(drawsBackground), m_pageID);
555 }
556
557 void WebPageProxy::setDrawsTransparentBackground(bool drawsTransparentBackground)
558 {
559     if (m_drawsTransparentBackground == drawsTransparentBackground)
560         return;
561
562     m_drawsTransparentBackground = drawsTransparentBackground;
563
564     if (isValid())
565         process()->send(Messages::WebPage::SetDrawsTransparentBackground(drawsTransparentBackground), m_pageID);
566 }
567
568 void WebPageProxy::viewWillStartLiveResize()
569 {
570     if (!isValid())
571         return;
572     process()->send(Messages::WebPage::ViewWillStartLiveResize(), m_pageID);
573 }
574
575 void WebPageProxy::viewWillEndLiveResize()
576 {
577     if (!isValid())
578         return;
579     process()->send(Messages::WebPage::ViewWillEndLiveResize(), m_pageID);
580 }
581
582 void WebPageProxy::setViewNeedsDisplay(const IntRect& rect)
583 {
584     m_pageClient->setViewNeedsDisplay(rect);
585 }
586
587 void WebPageProxy::displayView()
588 {
589     m_pageClient->displayView();
590 }
591
592 void WebPageProxy::scrollView(const IntRect& scrollRect, const IntSize& scrollOffset)
593 {
594     m_pageClient->scrollView(scrollRect, scrollOffset);
595 }
596
597 void WebPageProxy::viewStateDidChange(ViewStateFlags flags)
598 {
599     if (!isValid())
600         return;
601
602     if (flags & ViewIsFocused)
603         process()->send(Messages::WebPage::SetFocused(m_pageClient->isViewFocused()), m_pageID);
604
605     if (flags & ViewWindowIsActive)
606         process()->send(Messages::WebPage::SetActive(m_pageClient->isViewWindowActive()), m_pageID);
607
608     if (flags & ViewIsVisible) {
609         bool isVisible = m_pageClient->isViewVisible();
610         if (isVisible != m_isVisible) {
611             m_isVisible = isVisible;
612             m_drawingArea->visibilityDidChange();
613             m_drawingArea->setPageIsVisible(isVisible);
614         }
615     }
616
617     if (flags & ViewIsInWindow) {
618         bool isInWindow = m_pageClient->isViewInWindow();
619         if (m_isInWindow != isInWindow) {
620             m_isInWindow = isInWindow;
621             process()->send(Messages::WebPage::SetIsInWindow(isInWindow), m_pageID);
622         }
623     }
624
625     if (flags & (ViewWindowIsActive | ViewIsVisible))
626         updateBackingStoreDiscardableState();
627 }
628
629 IntSize WebPageProxy::viewSize() const
630 {
631     return m_pageClient->viewSize();
632 }
633
634 void WebPageProxy::setInitialFocus(bool forward)
635 {
636     if (!isValid())
637         return;
638     process()->send(Messages::WebPage::SetInitialFocus(forward), m_pageID);
639 }
640
641 void WebPageProxy::setWindowResizerSize(const IntSize& windowResizerSize)
642 {
643     if (!isValid())
644         return;
645     process()->send(Messages::WebPage::SetWindowResizerSize(windowResizerSize), m_pageID);
646 }
647
648 void WebPageProxy::validateCommand(const String& commandName, PassRefPtr<ValidateCommandCallback> callback)
649 {
650     if (!isValid()) {
651         callback->invalidate();
652         return;
653     }
654
655     uint64_t callbackID = callback->callbackID();
656     m_validateCommandCallbacks.set(callbackID, callback.get());
657     process()->send(Messages::WebPage::ValidateCommand(commandName, callbackID), m_pageID);
658 }
659     
660 void WebPageProxy::executeEditCommand(const String& commandName)
661 {
662     if (!isValid())
663         return;
664
665     process()->send(Messages::WebPage::ExecuteEditCommand(commandName), m_pageID);
666 }
667     
668 #if PLATFORM(WIN)
669 WebCore::IntRect WebPageProxy::firstRectForCharacterInSelectedRange(int characterPosition)
670 {
671     IntRect resultRect;
672     process()->sendSync(Messages::WebPage::FirstRectForCharacterInSelectedRange(characterPosition), Messages::WebPage::FirstRectForCharacterInSelectedRange::Reply(resultRect), m_pageID);
673     return resultRect;
674 }
675
676 String WebPageProxy::getSelectedText()
677 {
678     String text;
679     process()->sendSync(Messages::WebPage::GetSelectedText(), Messages::WebPage::GetSelectedText::Reply(text), m_pageID);
680     return text;
681 }
682
683 bool WebPageProxy::gestureWillBegin(const IntPoint& point)
684 {
685     bool canBeginPanning = false;
686     process()->sendSync(Messages::WebPage::GestureWillBegin(point), Messages::WebPage::GestureWillBegin::Reply(canBeginPanning), m_pageID);
687     return canBeginPanning;
688 }
689
690 void WebPageProxy::gestureDidScroll(const IntSize& size)
691 {
692     process()->send(Messages::WebPage::GestureDidScroll(size), m_pageID);
693 }
694
695 void WebPageProxy::gestureDidEnd()
696 {
697     process()->send(Messages::WebPage::GestureDidEnd(), m_pageID);
698 }
699
700 void WebPageProxy::setGestureReachedScrollingLimit(bool limitReached)
701 {
702     m_pageClient->setGestureReachedScrollingLimit(limitReached);
703 }
704 #endif
705
706 #if ENABLE(TILED_BACKING_STORE)
707 void WebPageProxy::setActualVisibleContentRect(const IntRect& rect)
708 {
709     if (!isValid())
710         return;
711
712     process()->send(Messages::WebPage::SetActualVisibleContentRect(rect), m_pageID);
713 }
714 #endif
715
716 void WebPageProxy::dragEntered(WebCore::DragData* dragData, const String& dragStorageName)
717 {
718     SandboxExtension::Handle sandboxExtensionHandle;
719     performDragControllerAction(DragControllerActionEntered, dragData, dragStorageName, sandboxExtensionHandle);
720 }
721
722 void WebPageProxy::dragUpdated(WebCore::DragData* dragData, const String& dragStorageName)
723 {
724     SandboxExtension::Handle sandboxExtensionHandle;
725     performDragControllerAction(DragControllerActionUpdated, dragData, dragStorageName, sandboxExtensionHandle);
726 }
727
728 void WebPageProxy::dragExited(WebCore::DragData* dragData, const String& dragStorageName)
729 {
730     SandboxExtension::Handle sandboxExtensionHandle;
731     performDragControllerAction(DragControllerActionExited, dragData, dragStorageName, sandboxExtensionHandle);
732 }
733
734 void WebPageProxy::performDrag(WebCore::DragData* dragData, const String& dragStorageName, const SandboxExtension::Handle& sandboxExtensionHandle)
735 {
736     performDragControllerAction(DragControllerActionPerformDrag, dragData, dragStorageName, sandboxExtensionHandle);
737 }
738
739 void WebPageProxy::performDragControllerAction(DragControllerAction action, WebCore::DragData* dragData, const String& dragStorageName, const SandboxExtension::Handle& sandboxExtensionHandle)
740 {
741     if (!isValid())
742         return;
743 #if PLATFORM(WIN)
744     // FIXME: We should pass the drag data map only on DragEnter.
745     process()->send(Messages::WebPage::PerformDragControllerAction(action, dragData->clientPosition(), dragData->globalPosition(),
746         dragData->draggingSourceOperationMask(), dragData->dragDataMap(), dragData->flags()), m_pageID);
747 #else
748     process()->send(Messages::WebPage::PerformDragControllerAction(action, dragData->clientPosition(), dragData->globalPosition(), dragData->draggingSourceOperationMask(), dragStorageName, dragData->flags(), sandboxExtensionHandle), m_pageID);
749 #endif
750 }
751
752 void WebPageProxy::didPerformDragControllerAction(uint64_t resultOperation)
753 {
754     m_currentDragOperation = static_cast<DragOperation>(resultOperation);
755 }
756
757 #if PLATFORM(WIN)
758
759 void WebPageProxy::startDragDrop(const IntPoint& imageOrigin, const IntPoint& dragPoint, uint64_t okEffect, 
760     const HashMap<UINT, Vector<String> >& dataMap, const IntSize& dragImageSize, const SharedMemory::Handle& dragImageHandle, bool isLinkDrag)
761 {
762     COMPtr<WCDataObject> dataObject;
763     WCDataObject::createInstance(&dataObject, dataMap);
764
765     RefPtr<SharedMemory> memoryBuffer = SharedMemory::create(dragImageHandle, SharedMemory::ReadOnly);
766     if (!memoryBuffer)
767         return;
768
769     RefPtr<WebDragSource> source = WebDragSource::createInstance();
770     if (!source)
771         return;
772
773     COMPtr<IDragSourceHelper> helper;
774     if (FAILED(::CoCreateInstance(CLSID_DragDropHelper, 0, CLSCTX_INPROC_SERVER, IID_IDragSourceHelper, reinterpret_cast<LPVOID*>(&helper))))
775         return;
776
777     BitmapInfo bitmapInfo = BitmapInfo::create(dragImageSize);
778     void* bits;
779     OwnPtr<HBITMAP> hbmp(::CreateDIBSection(0, &bitmapInfo, DIB_RGB_COLORS, &bits, 0, 0));
780     memcpy(bits, memoryBuffer->data(), memoryBuffer->size());
781
782     SHDRAGIMAGE sdi;
783     sdi.sizeDragImage.cx = bitmapInfo.bmiHeader.biWidth;
784     sdi.sizeDragImage.cy = bitmapInfo.bmiHeader.biHeight;
785     sdi.crColorKey = 0xffffffff;
786     sdi.hbmpDragImage = hbmp.leakPtr();
787     sdi.ptOffset.x = dragPoint.x() - imageOrigin.x();
788     sdi.ptOffset.y = dragPoint.y() - imageOrigin.y();
789     if (isLinkDrag)
790         sdi.ptOffset.y = bitmapInfo.bmiHeader.biHeight - sdi.ptOffset.y;
791
792     helper->InitializeFromBitmap(&sdi, dataObject.get());
793
794     DWORD effect = DROPEFFECT_NONE;
795
796     DragOperation operation = DragOperationNone;
797     if (::DoDragDrop(dataObject.get(), source.get(), okEffect, &effect) == DRAGDROP_S_DROP) {
798         if (effect & DROPEFFECT_COPY)
799             operation = DragOperationCopy;
800         else if (effect & DROPEFFECT_LINK)
801             operation = DragOperationLink;
802         else if (effect & DROPEFFECT_MOVE)
803             operation = DragOperationMove;
804     }
805     POINT globalPoint;
806     ::GetCursorPos(&globalPoint);
807     POINT localPoint = globalPoint;
808     ::ScreenToClient(m_pageClient->nativeWindow(), &localPoint);
809
810     dragEnded(localPoint, globalPoint, operation);
811 }
812 #endif
813
814 void WebPageProxy::dragEnded(const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition, uint64_t operation)
815 {
816     if (!isValid())
817         return;
818     process()->send(Messages::WebPage::DragEnded(clientPosition, globalPosition, operation), m_pageID);
819 }
820
821 void WebPageProxy::handleMouseEvent(const NativeWebMouseEvent& event)
822 {
823     if (!isValid())
824         return;
825
826     // NOTE: This does not start the responsiveness timer because mouse move should not indicate interaction.
827     if (event.type() != WebEvent::MouseMove)
828         process()->responsivenessTimer()->start();
829     else {
830         if (m_processingMouseMoveEvent) {
831             m_nextMouseMoveEvent = adoptPtr(new NativeWebMouseEvent(event));
832             return;
833         }
834
835         m_processingMouseMoveEvent = true;
836     }
837
838     // <https://bugs.webkit.org/show_bug.cgi?id=57904> We need to keep track of the mouse down event in the case where we
839     // display a popup menu for select elements. When the user changes the selected item,
840     // we fake a mouse up event by using this stored down event. This event gets cleared
841     // when the mouse up message is received from WebProcess.
842     if (event.type() == WebEvent::MouseDown)
843         m_currentlyProcessedMouseDownEvent = adoptPtr(new NativeWebMouseEvent(event));
844
845     process()->send(Messages::WebPage::MouseEvent(event), m_pageID);
846 }
847
848 static PassOwnPtr<WebWheelEvent> coalesceWheelEvents(WebWheelEvent* oldNextWheelEvent, const WebWheelEvent& newWheelEvent)
849 {
850 #if MERGE_WHEEL_EVENTS
851     // Merge model: Combine wheel event deltas (and wheel ticks) into a single wheel event.
852     if (!oldNextWheelEvent)
853         return adoptPtr(new WebWheelEvent(newWheelEvent));
854
855     if (oldNextWheelEvent->position() != newWheelEvent.position() || oldNextWheelEvent->modifiers() != newWheelEvent.modifiers() || oldNextWheelEvent->granularity() != newWheelEvent.granularity())
856         return adoptPtr(new WebWheelEvent(newWheelEvent));
857
858     FloatSize mergedDelta = oldNextWheelEvent->delta() + newWheelEvent.delta();
859     FloatSize mergedWheelTicks = oldNextWheelEvent->wheelTicks() + newWheelEvent.wheelTicks();
860
861     return adoptPtr(new WebWheelEvent(WebEvent::Wheel, newWheelEvent.position(), newWheelEvent.globalPosition(), mergedDelta, mergedWheelTicks, newWheelEvent.granularity(), newWheelEvent.modifiers(), newWheelEvent.timestamp()));
862 #else
863     // Simple model: Just keep the last event, dropping all interim events.
864     return adoptPtr(new WebWheelEvent(newWheelEvent));
865 #endif
866 }
867
868 void WebPageProxy::handleWheelEvent(const WebWheelEvent& event)
869 {
870     if (!isValid())
871         return;
872
873     if (m_processingWheelEvent) {
874         m_nextWheelEvent = coalesceWheelEvents(m_nextWheelEvent.get(), event);
875         return;
876     }
877
878     process()->responsivenessTimer()->start();
879     process()->send(Messages::WebPage::WheelEvent(event), m_pageID);
880     m_processingWheelEvent = true;
881 }
882
883 void WebPageProxy::handleKeyboardEvent(const NativeWebKeyboardEvent& event)
884 {
885     if (!isValid())
886         return;
887
888     m_keyEventQueue.append(event);
889
890     process()->responsivenessTimer()->start();
891     process()->send(Messages::WebPage::KeyEvent(event), m_pageID);
892 }
893
894 #if ENABLE(GESTURE_EVENTS)
895 void WebPageProxy::handleGestureEvent(const WebGestureEvent& event)
896 {
897     if (!isValid())
898         return;
899
900     process()->responsivenessTimer()->start();
901     process()->send(Messages::WebPage::GestureEvent(event), m_pageID);
902 }
903 #endif
904
905 #if ENABLE(TOUCH_EVENTS)
906 void WebPageProxy::handleTouchEvent(const WebTouchEvent& event)
907 {
908     if (!isValid())
909         return;
910     process()->send(Messages::WebPage::TouchEvent(event), m_pageID); 
911 }
912 #endif
913
914 void WebPageProxy::scrollBy(ScrollDirection direction, ScrollGranularity granularity)
915 {
916     if (!isValid())
917         return;
918
919     process()->send(Messages::WebPage::ScrollBy(direction, granularity), m_pageID);
920 }
921
922 void WebPageProxy::receivedPolicyDecision(PolicyAction action, WebFrameProxy* frame, uint64_t listenerID)
923 {
924     if (!isValid())
925         return;
926
927     uint64_t downloadID = 0;
928     if (action == PolicyDownload) {
929         // Create a download proxy.
930         downloadID = m_process->context()->createDownloadProxy()->downloadID();
931     }
932
933     // If we received a policy decision while in decidePolicyForMIMEType the decision will 
934     // be sent back to the web process by decidePolicyForMIMEType. 
935     if (m_inDecidePolicyForMIMEType) {
936         m_syncMimeTypePolicyActionIsValid = true;
937         m_syncMimeTypePolicyAction = action;
938         m_syncMimeTypePolicyDownloadID = downloadID;
939         return;
940     }
941
942     // If we received a policy decision while in decidePolicyForNavigationAction the decision will 
943     // be sent back to the web process by decidePolicyForNavigationAction. 
944     if (m_inDecidePolicyForNavigationAction) {
945         m_syncNavigationActionPolicyActionIsValid = true;
946         m_syncNavigationActionPolicyAction = action;
947         m_syncNavigationActionPolicyDownloadID = downloadID;
948         return;
949     }
950     
951     process()->send(Messages::WebPage::DidReceivePolicyDecision(frame->frameID(), listenerID, action, downloadID), m_pageID);
952 }
953
954 String WebPageProxy::pageTitle() const
955 {
956     // Return the null string if there is no main frame (e.g. nothing has been loaded in the page yet, WebProcess has
957     // crashed, page has been closed).
958     if (!m_mainFrame)
959         return String();
960
961     return m_mainFrame->title();
962 }
963
964 void WebPageProxy::setUserAgent(const String& userAgent)
965 {
966     if (m_userAgent == userAgent)
967         return;
968     m_userAgent = userAgent;
969
970     if (!isValid())
971         return;
972     process()->send(Messages::WebPage::SetUserAgent(m_userAgent), m_pageID);
973 }
974
975 void WebPageProxy::setApplicationNameForUserAgent(const String& applicationName)
976 {
977     if (m_applicationNameForUserAgent == applicationName)
978         return;
979
980     m_applicationNameForUserAgent = applicationName;
981     if (!m_customUserAgent.isEmpty())
982         return;
983
984     setUserAgent(standardUserAgent(m_applicationNameForUserAgent));
985 }
986
987 void WebPageProxy::setCustomUserAgent(const String& customUserAgent)
988 {
989     if (m_customUserAgent == customUserAgent)
990         return;
991
992     m_customUserAgent = customUserAgent;
993
994     if (m_customUserAgent.isEmpty()) {
995         setUserAgent(standardUserAgent(m_applicationNameForUserAgent));
996         return;
997     }
998
999     setUserAgent(m_customUserAgent);
1000 }
1001
1002 bool WebPageProxy::supportsTextEncoding() const
1003 {
1004     return !m_mainFrameHasCustomRepresentation && m_mainFrame && !m_mainFrame->isDisplayingStandaloneImageDocument();
1005 }
1006
1007 void WebPageProxy::setCustomTextEncodingName(const String& encodingName)
1008 {
1009     if (m_customTextEncodingName == encodingName)
1010         return;
1011     m_customTextEncodingName = encodingName;
1012
1013     if (!isValid())
1014         return;
1015     process()->send(Messages::WebPage::SetCustomTextEncodingName(encodingName), m_pageID);
1016 }
1017
1018 void WebPageProxy::terminateProcess()
1019 {
1020     if (!isValid())
1021         return;
1022
1023     process()->terminate();
1024 }
1025
1026 #if !USE(CF) || defined(BUILDING_QT__)
1027 PassRefPtr<WebData> WebPageProxy::sessionStateData(WebPageProxySessionStateFilterCallback, void* context) const
1028 {
1029     // FIXME: Return session state data for saving Page state.
1030     return 0;
1031 }
1032
1033 void WebPageProxy::restoreFromSessionStateData(WebData*)
1034 {
1035     // FIXME: Restore the Page from the passed in session state data.
1036 }
1037 #endif
1038
1039 bool WebPageProxy::supportsTextZoom() const
1040 {
1041     if (m_mainFrameHasCustomRepresentation)
1042         return false;
1043
1044     // FIXME: This should also return false for standalone media and plug-in documents.
1045     if (!m_mainFrame || m_mainFrame->isDisplayingStandaloneImageDocument())
1046         return false;
1047
1048     return true;
1049 }
1050  
1051 void WebPageProxy::setTextZoomFactor(double zoomFactor)
1052 {
1053     if (!isValid())
1054         return;
1055
1056     if (m_mainFrameHasCustomRepresentation)
1057         return;
1058
1059     if (m_textZoomFactor == zoomFactor)
1060         return;
1061
1062     m_textZoomFactor = zoomFactor;
1063     process()->send(Messages::WebPage::SetTextZoomFactor(m_textZoomFactor), m_pageID); 
1064 }
1065
1066 double WebPageProxy::pageZoomFactor() const
1067 {
1068     return m_mainFrameHasCustomRepresentation ? m_pageClient->customRepresentationZoomFactor() : m_pageZoomFactor;
1069 }
1070
1071 void WebPageProxy::setPageZoomFactor(double zoomFactor)
1072 {
1073     if (!isValid())
1074         return;
1075
1076     if (m_mainFrameHasCustomRepresentation) {
1077         m_pageClient->setCustomRepresentationZoomFactor(zoomFactor);
1078         return;
1079     }
1080
1081     if (m_pageZoomFactor == zoomFactor)
1082         return;
1083
1084     m_pageZoomFactor = zoomFactor;
1085     process()->send(Messages::WebPage::SetPageZoomFactor(m_pageZoomFactor), m_pageID); 
1086 }
1087
1088 void WebPageProxy::setPageAndTextZoomFactors(double pageZoomFactor, double textZoomFactor)
1089 {
1090     if (!isValid())
1091         return;
1092
1093     if (m_mainFrameHasCustomRepresentation) {
1094         m_pageClient->setCustomRepresentationZoomFactor(pageZoomFactor);
1095         return;
1096     }
1097
1098     if (m_pageZoomFactor == pageZoomFactor && m_textZoomFactor == textZoomFactor)
1099         return;
1100
1101     m_pageZoomFactor = pageZoomFactor;
1102     m_textZoomFactor = textZoomFactor;
1103     process()->send(Messages::WebPage::SetPageAndTextZoomFactors(m_pageZoomFactor, m_textZoomFactor), m_pageID); 
1104 }
1105
1106 void WebPageProxy::scaleWebView(double scale, const IntPoint& origin)
1107 {
1108     if (!isValid())
1109         return;
1110
1111     process()->send(Messages::WebPage::ScaleWebView(scale, origin), m_pageID);
1112 }
1113
1114 void WebPageProxy::setUseFixedLayout(bool fixed)
1115 {
1116     if (!isValid())
1117         return;
1118
1119     if (fixed == m_useFixedLayout)
1120         return;
1121
1122     m_useFixedLayout = fixed;
1123     if (!fixed)
1124         m_fixedLayoutSize = IntSize();
1125     process()->send(Messages::WebPage::SetUseFixedLayout(fixed), m_pageID);
1126 }
1127
1128 void WebPageProxy::setFixedLayoutSize(const IntSize& size)
1129 {
1130     if (!isValid())
1131         return;
1132
1133     if (size == m_fixedLayoutSize)
1134         return;
1135
1136     m_fixedLayoutSize = size;
1137     process()->send(Messages::WebPage::SetFixedLayoutSize(size), m_pageID);
1138 }
1139
1140 void WebPageProxy::viewScaleFactorDidChange(double scaleFactor)
1141 {
1142     m_viewScaleFactor = scaleFactor;
1143 }
1144
1145 void WebPageProxy::setMemoryCacheClientCallsEnabled(bool memoryCacheClientCallsEnabled)
1146 {
1147     if (!isValid())
1148         return;
1149
1150     if (m_areMemoryCacheClientCallsEnabled == memoryCacheClientCallsEnabled)
1151         return;
1152
1153     m_areMemoryCacheClientCallsEnabled = memoryCacheClientCallsEnabled;
1154     process()->send(Messages::WebPage::SetMemoryCacheMessagesEnabled(memoryCacheClientCallsEnabled), m_pageID);
1155 }
1156
1157 void WebPageProxy::findString(const String& string, FindOptions options, unsigned maxMatchCount)
1158 {
1159     if (m_mainFrameHasCustomRepresentation)
1160         m_pageClient->findStringInCustomRepresentation(string, options, maxMatchCount);
1161     else
1162         process()->send(Messages::WebPage::FindString(string, options, maxMatchCount), m_pageID);
1163 }
1164
1165 void WebPageProxy::hideFindUI()
1166 {
1167     process()->send(Messages::WebPage::HideFindUI(), m_pageID);
1168 }
1169
1170 void WebPageProxy::countStringMatches(const String& string, FindOptions options, unsigned maxMatchCount)
1171 {
1172     if (m_mainFrameHasCustomRepresentation) {
1173         m_pageClient->countStringMatchesInCustomRepresentation(string, options, maxMatchCount);
1174         return;
1175     }
1176
1177     if (!isValid())
1178         return;
1179
1180     process()->send(Messages::WebPage::CountStringMatches(string, options, maxMatchCount), m_pageID);
1181 }
1182
1183 void WebPageProxy::runJavaScriptInMainFrame(const String& script, PassRefPtr<ScriptValueCallback> prpCallback)
1184 {
1185     RefPtr<ScriptValueCallback> callback = prpCallback;
1186     if (!isValid()) {
1187         callback->invalidate();
1188         return;
1189     }
1190
1191     uint64_t callbackID = callback->callbackID();
1192     m_scriptValueCallbacks.set(callbackID, callback.get());
1193     process()->send(Messages::WebPage::RunJavaScriptInMainFrame(script, callbackID), m_pageID);
1194 }
1195
1196 void WebPageProxy::getRenderTreeExternalRepresentation(PassRefPtr<StringCallback> prpCallback)
1197 {
1198     RefPtr<StringCallback> callback = prpCallback;
1199     if (!isValid()) {
1200         callback->invalidate();
1201         return;
1202     }
1203     
1204     uint64_t callbackID = callback->callbackID();
1205     m_stringCallbacks.set(callbackID, callback.get());
1206     process()->send(Messages::WebPage::GetRenderTreeExternalRepresentation(callbackID), m_pageID);
1207 }
1208
1209 void WebPageProxy::getSourceForFrame(WebFrameProxy* frame, PassRefPtr<StringCallback> prpCallback)
1210 {
1211     RefPtr<StringCallback> callback = prpCallback;
1212     if (!isValid()) {
1213         callback->invalidate();
1214         return;
1215     }
1216     
1217     uint64_t callbackID = callback->callbackID();
1218     m_loadDependentStringCallbackIDs.add(callbackID);
1219     m_stringCallbacks.set(callbackID, callback.get());
1220     process()->send(Messages::WebPage::GetSourceForFrame(frame->frameID(), callbackID), m_pageID);
1221 }
1222
1223 void WebPageProxy::getContentsAsString(PassRefPtr<StringCallback> prpCallback)
1224 {
1225     RefPtr<StringCallback> callback = prpCallback;
1226     if (!isValid()) {
1227         callback->invalidate();
1228         return;
1229     }
1230     
1231     uint64_t callbackID = callback->callbackID();
1232     m_loadDependentStringCallbackIDs.add(callbackID);
1233     m_stringCallbacks.set(callbackID, callback.get());
1234     process()->send(Messages::WebPage::GetContentsAsString(callbackID), m_pageID);
1235 }
1236
1237 void WebPageProxy::getSelectionOrContentsAsString(PassRefPtr<StringCallback> prpCallback)
1238 {
1239     RefPtr<StringCallback> callback = prpCallback;
1240     if (!isValid()) {
1241         callback->invalidate();
1242         return;
1243     }
1244     
1245     uint64_t callbackID = callback->callbackID();
1246     m_stringCallbacks.set(callbackID, callback.get());
1247     process()->send(Messages::WebPage::GetSelectionOrContentsAsString(callbackID), m_pageID);
1248 }
1249
1250 void WebPageProxy::getMainResourceDataOfFrame(WebFrameProxy* frame, PassRefPtr<DataCallback> prpCallback)
1251 {
1252     RefPtr<DataCallback> callback = prpCallback;
1253     if (!isValid()) {
1254         callback->invalidate();
1255         return;
1256     }
1257     
1258     uint64_t callbackID = callback->callbackID();
1259     m_dataCallbacks.set(callbackID, callback.get());
1260     process()->send(Messages::WebPage::GetMainResourceDataOfFrame(frame->frameID(), callbackID), m_pageID);
1261 }
1262
1263 void WebPageProxy::getResourceDataFromFrame(WebFrameProxy* frame, WebURL* resourceURL, PassRefPtr<DataCallback> prpCallback)
1264 {
1265     RefPtr<DataCallback> callback = prpCallback;
1266     if (!isValid()) {
1267         callback->invalidate();
1268         return;
1269     }
1270     
1271     uint64_t callbackID = callback->callbackID();
1272     m_dataCallbacks.set(callbackID, callback.get());
1273     process()->send(Messages::WebPage::GetResourceDataFromFrame(frame->frameID(), resourceURL->string(), callbackID), m_pageID);
1274 }
1275
1276 void WebPageProxy::getWebArchiveOfFrame(WebFrameProxy* frame, PassRefPtr<DataCallback> prpCallback)
1277 {
1278     RefPtr<DataCallback> callback = prpCallback;
1279     if (!isValid()) {
1280         callback->invalidate();
1281         return;
1282     }
1283     
1284     uint64_t callbackID = callback->callbackID();
1285     m_dataCallbacks.set(callbackID, callback.get());
1286     process()->send(Messages::WebPage::GetWebArchiveOfFrame(frame->frameID(), callbackID), m_pageID);
1287 }
1288
1289 void WebPageProxy::forceRepaint(PassRefPtr<VoidCallback> prpCallback)
1290 {
1291     RefPtr<VoidCallback> callback = prpCallback;
1292     if (!isValid()) {
1293         callback->invalidate();
1294         return;
1295     }
1296
1297     uint64_t callbackID = callback->callbackID();
1298     m_voidCallbacks.set(callbackID, callback.get());
1299     process()->send(Messages::WebPage::ForceRepaint(callbackID), m_pageID); 
1300 }
1301
1302 void WebPageProxy::preferencesDidChange()
1303 {
1304     if (!isValid())
1305         return;
1306
1307     // FIXME: It probably makes more sense to send individual preference changes.
1308     // However, WebKitTestRunner depends on getting a preference change notification
1309     // even if nothing changed in UI process, so that overrides get removed.
1310
1311     // Preferences need to be updated during synchronous printing to make "print backgrounds" preference work when toggled from a print dialog checkbox.
1312     process()->send(Messages::WebPage::PreferencesDidChange(pageGroup()->preferences()->store()), m_pageID, m_isPerformingDOMPrintOperation ? CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply : 0);
1313 }
1314
1315 #if ENABLE(TILED_BACKING_STORE)
1316 void WebPageProxy::setResizesToContentsUsingLayoutSize(const WebCore::IntSize& targetLayoutSize)
1317 {
1318     process()->send(Messages::WebPage::SetResizesToContentsUsingLayoutSize(targetLayoutSize), m_pageID);
1319 }
1320 #endif
1321
1322 void WebPageProxy::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments)
1323 {
1324 #if PLATFORM(MAC) || PLATFORM(WIN) || PLATFORM(QT)
1325     if (messageID.is<CoreIPC::MessageClassDrawingAreaProxy>()) {
1326         m_drawingArea->didReceiveDrawingAreaProxyMessage(connection, messageID, arguments);
1327         return;
1328     }
1329 #endif
1330
1331     if (messageID.is<CoreIPC::MessageClassDrawingAreaProxyLegacy>()) {
1332         m_drawingArea->didReceiveMessage(connection, messageID, arguments);
1333         return;
1334     }
1335
1336 #if ENABLE(INSPECTOR)
1337     if (messageID.is<CoreIPC::MessageClassWebInspectorProxy>()) {
1338         if (WebInspectorProxy* inspector = this->inspector())
1339             inspector->didReceiveWebInspectorProxyMessage(connection, messageID, arguments);
1340         return;
1341     }
1342 #endif
1343
1344 #if ENABLE(FULLSCREEN_API)
1345     if (messageID.is<CoreIPC::MessageClassWebFullScreenManagerProxy>()) {
1346         fullScreenManager()->didReceiveMessage(connection, messageID, arguments);
1347         return;
1348     }
1349 #endif
1350
1351     didReceiveWebPageProxyMessage(connection, messageID, arguments);
1352 }
1353
1354 void WebPageProxy::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments, CoreIPC::ArgumentEncoder* reply)
1355 {
1356 #if ENABLE(INSPECTOR)
1357     if (messageID.is<CoreIPC::MessageClassWebInspectorProxy>()) {
1358         if (WebInspectorProxy* inspector = this->inspector())
1359             inspector->didReceiveSyncWebInspectorProxyMessage(connection, messageID, arguments, reply);
1360         return;
1361     }
1362 #endif
1363
1364 #if ENABLE(FULLSCREEN_API)
1365     if (messageID.is<CoreIPC::MessageClassWebFullScreenManagerProxy>()) {
1366         fullScreenManager()->didReceiveSyncMessage(connection, messageID, arguments, reply);
1367         return;
1368     }
1369 #endif
1370
1371     // FIXME: Do something with reply.
1372     didReceiveSyncWebPageProxyMessage(connection, messageID, arguments, reply);
1373 }
1374
1375 void WebPageProxy::didCreateMainFrame(uint64_t frameID)
1376 {
1377     MESSAGE_CHECK(!m_mainFrame);
1378     MESSAGE_CHECK(process()->canCreateFrame(frameID));
1379
1380     m_mainFrame = WebFrameProxy::create(this, frameID);
1381
1382     // Add the frame to the process wide map.
1383     process()->frameCreated(frameID, m_mainFrame.get());
1384 }
1385
1386 void WebPageProxy::didCreateSubframe(uint64_t frameID, uint64_t parentFrameID)
1387 {
1388     MESSAGE_CHECK(m_mainFrame);
1389
1390     WebFrameProxy* parentFrame = process()->webFrame(parentFrameID);
1391     MESSAGE_CHECK(parentFrame);
1392     MESSAGE_CHECK(parentFrame->isDescendantOf(m_mainFrame.get()));
1393
1394     MESSAGE_CHECK(process()->canCreateFrame(frameID));
1395     
1396     RefPtr<WebFrameProxy> subFrame = WebFrameProxy::create(this, frameID);
1397
1398     // Add the frame to the process wide map.
1399     process()->frameCreated(frameID, subFrame.get());
1400
1401     // Insert the frame into the frame hierarchy.
1402     parentFrame->appendChild(subFrame.get());
1403 }
1404
1405 static bool isDisconnectedFrame(WebFrameProxy* frame)
1406 {
1407     return !frame->page() || !frame->page()->mainFrame() || !frame->isDescendantOf(frame->page()->mainFrame());
1408 }
1409
1410 void WebPageProxy::didSaveFrameToPageCache(uint64_t frameID)
1411 {
1412     MESSAGE_CHECK(m_mainFrame);
1413
1414     WebFrameProxy* subframe = process()->webFrame(frameID);
1415     MESSAGE_CHECK(subframe);
1416
1417     if (isDisconnectedFrame(subframe))
1418         return;
1419
1420     MESSAGE_CHECK(subframe->isDescendantOf(m_mainFrame.get()));
1421
1422     subframe->didRemoveFromHierarchy();
1423 }
1424
1425 void WebPageProxy::didRestoreFrameFromPageCache(uint64_t frameID, uint64_t parentFrameID)
1426 {
1427     MESSAGE_CHECK(m_mainFrame);
1428
1429     WebFrameProxy* subframe = process()->webFrame(frameID);
1430     MESSAGE_CHECK(subframe);
1431     MESSAGE_CHECK(!subframe->parentFrame());
1432     MESSAGE_CHECK(subframe->page() == m_mainFrame->page());
1433
1434     WebFrameProxy* parentFrame = process()->webFrame(parentFrameID);
1435     MESSAGE_CHECK(parentFrame);
1436     MESSAGE_CHECK(parentFrame->isDescendantOf(m_mainFrame.get()));
1437
1438     // Insert the frame into the frame hierarchy.
1439     parentFrame->appendChild(subframe);
1440 }
1441
1442
1443 // Always start progress at initialProgressValue. This helps provide feedback as
1444 // soon as a load starts.
1445
1446 static const double initialProgressValue = 0.1;
1447
1448 double WebPageProxy::estimatedProgress() const
1449 {
1450     if (!pendingAPIRequestURL().isNull())
1451         return initialProgressValue;
1452     return m_estimatedProgress; 
1453 }
1454
1455 void WebPageProxy::didStartProgress()
1456 {
1457     m_estimatedProgress = initialProgressValue;
1458
1459     m_loaderClient.didStartProgress(this);
1460 }
1461
1462 void WebPageProxy::didChangeProgress(double value)
1463 {
1464     m_estimatedProgress = value;
1465
1466     m_loaderClient.didChangeProgress(this);
1467 }
1468
1469 void WebPageProxy::didFinishProgress()
1470 {
1471     m_estimatedProgress = 1.0;
1472
1473     m_loaderClient.didFinishProgress(this);
1474 }
1475
1476 void WebPageProxy::didStartProvisionalLoadForFrame(uint64_t frameID, const String& url, const String& unreachableURL, CoreIPC::ArgumentDecoder* arguments)
1477 {
1478     clearPendingAPIRequestURL();
1479
1480     RefPtr<APIObject> userData;
1481     WebContextUserMessageDecoder messageDecoder(userData, m_process->context());
1482     if (!arguments->decode(messageDecoder))
1483         return;
1484
1485     WebFrameProxy* frame = process()->webFrame(frameID);
1486     MESSAGE_CHECK(frame);
1487
1488     frame->setUnreachableURL(unreachableURL);
1489
1490     frame->didStartProvisionalLoad(url);
1491     m_loaderClient.didStartProvisionalLoadForFrame(this, frame, userData.get());
1492 }
1493
1494 void WebPageProxy::didReceiveServerRedirectForProvisionalLoadForFrame(uint64_t frameID, const String& url, CoreIPC::ArgumentDecoder* arguments)
1495 {
1496     RefPtr<APIObject> userData;
1497     WebContextUserMessageDecoder messageDecoder(userData, m_process->context());
1498     if (!arguments->decode(messageDecoder))
1499         return;
1500
1501     WebFrameProxy* frame = process()->webFrame(frameID);
1502     MESSAGE_CHECK(frame);
1503
1504     frame->didReceiveServerRedirectForProvisionalLoad(url);
1505
1506     m_loaderClient.didReceiveServerRedirectForProvisionalLoadForFrame(this, frame, userData.get());
1507 }
1508
1509 void WebPageProxy::didFailProvisionalLoadForFrame(uint64_t frameID, const ResourceError& error, CoreIPC::ArgumentDecoder* arguments)
1510 {
1511     RefPtr<APIObject> userData;
1512     WebContextUserMessageDecoder messageDecoder(userData, m_process->context());
1513     if (!arguments->decode(messageDecoder))
1514         return;
1515
1516     WebFrameProxy* frame = process()->webFrame(frameID);
1517     MESSAGE_CHECK(frame);
1518
1519     frame->didFailProvisionalLoad();
1520
1521     m_loaderClient.didFailProvisionalLoadWithErrorForFrame(this, frame, error, userData.get());
1522 }
1523
1524 void WebPageProxy::clearLoadDependentCallbacks()
1525 {
1526     Vector<uint64_t> callbackIDsCopy;
1527     copyToVector(m_loadDependentStringCallbackIDs, callbackIDsCopy);
1528     m_loadDependentStringCallbackIDs.clear();
1529
1530     for (size_t i = 0; i < callbackIDsCopy.size(); ++i) {
1531         RefPtr<StringCallback> callback = m_stringCallbacks.take(callbackIDsCopy[i]);
1532         if (callback)
1533             callback->invalidate();
1534     }
1535 }
1536
1537 void WebPageProxy::didCommitLoadForFrame(uint64_t frameID, const String& mimeType, bool frameHasCustomRepresentation, const PlatformCertificateInfo& certificateInfo, CoreIPC::ArgumentDecoder* arguments)
1538 {
1539     RefPtr<APIObject> userData;
1540     WebContextUserMessageDecoder messageDecoder(userData, m_process->context());
1541     if (!arguments->decode(messageDecoder))
1542         return;
1543
1544     WebFrameProxy* frame = process()->webFrame(frameID);
1545     MESSAGE_CHECK(frame);
1546
1547 #if PLATFORM(MAC)
1548     // FIXME (bug 59111): didCommitLoadForFrame comes too late when restoring a page from b/f cache, making us disable secure event mode in password fields.
1549     // FIXME (bug 59121): A load going on in one frame shouldn't affect typing in sibling frames.
1550     m_pageClient->resetTextInputState();
1551 #if !defined(BUILDING_ON_SNOW_LEOPARD)
1552     // FIXME: Should this be moved inside resetTextInputState()?
1553     dismissCorrectionPanel(ReasonForDismissingCorrectionPanelIgnored);
1554     m_pageClient->dismissDictionaryLookupPanel();
1555 #endif
1556 #endif
1557
1558     clearLoadDependentCallbacks();
1559
1560     frame->didCommitLoad(mimeType, certificateInfo);
1561
1562     if (frame->isMainFrame()) {
1563         m_mainFrameHasCustomRepresentation = frameHasCustomRepresentation;
1564         m_pageClient->didCommitLoadForMainFrame(frameHasCustomRepresentation);
1565     }
1566
1567     m_loaderClient.didCommitLoadForFrame(this, frame, userData.get());
1568 }
1569
1570 void WebPageProxy::didFinishDocumentLoadForFrame(uint64_t frameID, CoreIPC::ArgumentDecoder* arguments)
1571 {
1572     RefPtr<APIObject> userData;
1573     WebContextUserMessageDecoder messageDecoder(userData, m_process->context());
1574     if (!arguments->decode(messageDecoder))
1575         return;
1576
1577     WebFrameProxy* frame = process()->webFrame(frameID);
1578     MESSAGE_CHECK(frame);
1579
1580     m_loaderClient.didFinishDocumentLoadForFrame(this, frame, userData.get());
1581 }
1582
1583 void WebPageProxy::didFinishLoadForFrame(uint64_t frameID, CoreIPC::ArgumentDecoder* arguments)
1584 {
1585     RefPtr<APIObject> userData;
1586     WebContextUserMessageDecoder messageDecoder(userData, m_process->context());
1587     if (!arguments->decode(messageDecoder))
1588         return;
1589
1590     WebFrameProxy* frame = process()->webFrame(frameID);
1591     MESSAGE_CHECK(frame);
1592
1593     frame->didFinishLoad();
1594
1595     m_loaderClient.didFinishLoadForFrame(this, frame, userData.get());
1596 }
1597
1598 void WebPageProxy::didFailLoadForFrame(uint64_t frameID, const ResourceError& error, CoreIPC::ArgumentDecoder* arguments)
1599 {
1600     RefPtr<APIObject> userData;
1601     WebContextUserMessageDecoder messageDecoder(userData, m_process->context());
1602     if (!arguments->decode(messageDecoder))
1603         return;
1604
1605     WebFrameProxy* frame = process()->webFrame(frameID);
1606     MESSAGE_CHECK(frame);
1607
1608     clearLoadDependentCallbacks();
1609
1610     frame->didFailLoad();
1611
1612     m_loaderClient.didFailLoadWithErrorForFrame(this, frame, error, userData.get());
1613 }
1614
1615 void WebPageProxy::didSameDocumentNavigationForFrame(uint64_t frameID, uint32_t opaqueSameDocumentNavigationType, const String& url, CoreIPC::ArgumentDecoder* arguments)
1616 {
1617     RefPtr<APIObject> userData;
1618     WebContextUserMessageDecoder messageDecoder(userData, m_process->context());
1619     if (!arguments->decode(messageDecoder))
1620         return;
1621
1622     WebFrameProxy* frame = process()->webFrame(frameID);
1623     MESSAGE_CHECK(frame);
1624
1625     frame->didSameDocumentNavigation(url);
1626
1627     m_loaderClient.didSameDocumentNavigationForFrame(this, frame, static_cast<SameDocumentNavigationType>(opaqueSameDocumentNavigationType), userData.get());
1628 }
1629
1630 void WebPageProxy::didReceiveTitleForFrame(uint64_t frameID, const String& title, CoreIPC::ArgumentDecoder* arguments)
1631 {
1632     RefPtr<APIObject> userData;
1633     WebContextUserMessageDecoder messageDecoder(userData, m_process->context());
1634     if (!arguments->decode(messageDecoder))
1635         return;
1636
1637     WebFrameProxy* frame = process()->webFrame(frameID);
1638     MESSAGE_CHECK(frame);
1639
1640     frame->didChangeTitle(title);
1641     
1642     m_loaderClient.didReceiveTitleForFrame(this, title, frame, userData.get());
1643 }
1644
1645 void WebPageProxy::didFirstLayoutForFrame(uint64_t frameID, CoreIPC::ArgumentDecoder* arguments)
1646 {
1647     RefPtr<APIObject> userData;
1648     WebContextUserMessageDecoder messageDecoder(userData, m_process->context());
1649     if (!arguments->decode(messageDecoder))
1650         return;
1651
1652     WebFrameProxy* frame = process()->webFrame(frameID);
1653     MESSAGE_CHECK(frame);
1654
1655     m_loaderClient.didFirstLayoutForFrame(this, frame, userData.get());
1656 }
1657
1658 void WebPageProxy::didFirstVisuallyNonEmptyLayoutForFrame(uint64_t frameID, CoreIPC::ArgumentDecoder* arguments)
1659 {
1660     RefPtr<APIObject> userData;
1661     WebContextUserMessageDecoder messageDecoder(userData, m_process->context());
1662     if (!arguments->decode(messageDecoder))
1663         return;
1664
1665     WebFrameProxy* frame = process()->webFrame(frameID);
1666     MESSAGE_CHECK(frame);
1667
1668     m_loaderClient.didFirstVisuallyNonEmptyLayoutForFrame(this, frame, userData.get());
1669 }
1670
1671 void WebPageProxy::didRemoveFrameFromHierarchy(uint64_t frameID, CoreIPC::ArgumentDecoder* arguments)
1672 {
1673     RefPtr<APIObject> userData;
1674     WebContextUserMessageDecoder messageDecoder(userData, m_process->context());
1675     if (!arguments->decode(messageDecoder))
1676         return;
1677
1678     WebFrameProxy* frame = process()->webFrame(frameID);
1679     MESSAGE_CHECK(frame);
1680
1681     frame->didRemoveFromHierarchy();
1682
1683     m_loaderClient.didRemoveFrameFromHierarchy(this, frame, userData.get());
1684 }
1685
1686 void WebPageProxy::didDisplayInsecureContentForFrame(uint64_t frameID, CoreIPC::ArgumentDecoder* arguments)
1687 {
1688     RefPtr<APIObject> userData;
1689     WebContextUserMessageDecoder messageDecoder(userData, m_process->context());
1690     if (!arguments->decode(messageDecoder))
1691         return;
1692
1693     WebFrameProxy* frame = process()->webFrame(frameID);
1694     MESSAGE_CHECK(frame);
1695
1696     m_loaderClient.didDisplayInsecureContentForFrame(this, frame, userData.get());
1697 }
1698
1699 void WebPageProxy::didRunInsecureContentForFrame(uint64_t frameID, CoreIPC::ArgumentDecoder* arguments)
1700 {
1701     RefPtr<APIObject> userData;
1702     WebContextUserMessageDecoder messageDecoder(userData, m_process->context());
1703     if (!arguments->decode(messageDecoder))
1704         return;
1705
1706     WebFrameProxy* frame = process()->webFrame(frameID);
1707     MESSAGE_CHECK(frame);
1708
1709     m_loaderClient.didRunInsecureContentForFrame(this, frame, userData.get());
1710 }
1711
1712 void WebPageProxy::frameDidBecomeFrameSet(uint64_t frameID, bool value)
1713 {
1714     WebFrameProxy* frame = process()->webFrame(frameID);
1715     MESSAGE_CHECK(frame);
1716
1717     frame->setIsFrameSet(value);
1718     if (frame->isMainFrame())
1719         m_frameSetLargestFrame = value ? m_mainFrame : 0;
1720 }
1721
1722 // PolicyClient
1723 void WebPageProxy::decidePolicyForNavigationAction(uint64_t frameID, uint32_t opaqueNavigationType, uint32_t opaqueModifiers, int32_t opaqueMouseButton, const ResourceRequest& request, uint64_t listenerID, CoreIPC::ArgumentDecoder* arguments, bool& receivedPolicyAction, uint64_t& policyAction, uint64_t& downloadID)
1724 {
1725     RefPtr<APIObject> userData;
1726     WebContextUserMessageDecoder messageDecoder(userData, m_process->context());
1727     if (!arguments->decode(messageDecoder))
1728         return;
1729
1730     if (request.url() != pendingAPIRequestURL())
1731         clearPendingAPIRequestURL();
1732
1733     WebFrameProxy* frame = process()->webFrame(frameID);
1734     MESSAGE_CHECK(frame);
1735
1736     NavigationType navigationType = static_cast<NavigationType>(opaqueNavigationType);
1737     WebEvent::Modifiers modifiers = static_cast<WebEvent::Modifiers>(opaqueModifiers);
1738     WebMouseEvent::Button mouseButton = static_cast<WebMouseEvent::Button>(opaqueMouseButton);
1739     
1740     RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
1741
1742     ASSERT(!m_inDecidePolicyForNavigationAction);
1743
1744     m_inDecidePolicyForNavigationAction = true;
1745     m_syncNavigationActionPolicyActionIsValid = false;
1746     
1747     if (!m_policyClient.decidePolicyForNavigationAction(this, frame, navigationType, modifiers, mouseButton, request, listener.get(), userData.get()))
1748         listener->use();
1749
1750     m_inDecidePolicyForNavigationAction = false;
1751
1752     // Check if we received a policy decision already. If we did, we can just pass it back.
1753     receivedPolicyAction = m_syncNavigationActionPolicyActionIsValid;
1754     if (m_syncNavigationActionPolicyActionIsValid) {
1755         policyAction = m_syncNavigationActionPolicyAction;
1756         downloadID = m_syncNavigationActionPolicyDownloadID;
1757     }
1758 }
1759
1760 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::ArgumentDecoder* arguments)
1761 {
1762     RefPtr<APIObject> userData;
1763     WebContextUserMessageDecoder messageDecoder(userData, m_process->context());
1764     if (!arguments->decode(messageDecoder))
1765         return;
1766
1767     WebFrameProxy* frame = process()->webFrame(frameID);
1768     MESSAGE_CHECK(frame);
1769
1770     NavigationType navigationType = static_cast<NavigationType>(opaqueNavigationType);
1771     WebEvent::Modifiers modifiers = static_cast<WebEvent::Modifiers>(opaqueModifiers);
1772     WebMouseEvent::Button mouseButton = static_cast<WebMouseEvent::Button>(opaqueMouseButton);
1773
1774     RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
1775     if (!m_policyClient.decidePolicyForNewWindowAction(this, frame, navigationType, modifiers, mouseButton, request, frameName, listener.get(), userData.get()))
1776         listener->use();
1777 }
1778
1779 void WebPageProxy::decidePolicyForResponse(uint64_t frameID, const ResourceResponse& response, const ResourceRequest& request, uint64_t listenerID, CoreIPC::ArgumentDecoder* arguments, bool& receivedPolicyAction, uint64_t& policyAction, uint64_t& downloadID)
1780 {
1781     RefPtr<APIObject> userData;
1782     WebContextUserMessageDecoder messageDecoder(userData, m_process->context());
1783     if (!arguments->decode(messageDecoder))
1784         return;
1785
1786     WebFrameProxy* frame = process()->webFrame(frameID);
1787     MESSAGE_CHECK(frame);
1788
1789     RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
1790
1791     ASSERT(!m_inDecidePolicyForMIMEType);
1792
1793     m_inDecidePolicyForMIMEType = true;
1794     m_syncMimeTypePolicyActionIsValid = false;
1795
1796     if (!m_policyClient.decidePolicyForResponse(this, frame, response, request, listener.get(), userData.get()))
1797         listener->use();
1798
1799     m_inDecidePolicyForMIMEType = false;
1800
1801     // Check if we received a policy decision already. If we did, we can just pass it back.
1802     receivedPolicyAction = m_syncMimeTypePolicyActionIsValid;
1803     if (m_syncMimeTypePolicyActionIsValid) {
1804         policyAction = m_syncMimeTypePolicyAction;
1805         downloadID = m_syncMimeTypePolicyDownloadID;
1806     }
1807 }
1808
1809 void WebPageProxy::unableToImplementPolicy(uint64_t frameID, const WebCore::ResourceError& error, CoreIPC::ArgumentDecoder* arguments)
1810 {
1811     RefPtr<APIObject> userData;
1812     WebContextUserMessageDecoder messageDecoder(userData, m_process->context());
1813     if (!arguments->decode(messageDecoder))
1814         return;
1815     
1816     WebFrameProxy* frame = process()->webFrame(frameID);
1817     MESSAGE_CHECK(frame);
1818
1819     m_policyClient.unableToImplementPolicy(this, frame, error, userData.get());
1820 }
1821
1822 // FormClient
1823
1824 void WebPageProxy::willSubmitForm(uint64_t frameID, uint64_t sourceFrameID, const StringPairVector& textFieldValues, uint64_t listenerID, CoreIPC::ArgumentDecoder* arguments)
1825 {
1826     RefPtr<APIObject> userData;
1827     WebContextUserMessageDecoder messageDecoder(userData, m_process->context());
1828     if (!arguments->decode(messageDecoder))
1829         return;
1830
1831     WebFrameProxy* frame = process()->webFrame(frameID);
1832     MESSAGE_CHECK(frame);
1833
1834     WebFrameProxy* sourceFrame = process()->webFrame(sourceFrameID);
1835     MESSAGE_CHECK(sourceFrame);
1836
1837     RefPtr<WebFormSubmissionListenerProxy> listener = frame->setUpFormSubmissionListenerProxy(listenerID);
1838     if (!m_formClient.willSubmitForm(this, frame, sourceFrame, textFieldValues.stringPairVector(), userData.get(), listener.get()))
1839         listener->continueSubmission();
1840 }
1841
1842 // ResourceLoad Client
1843
1844 void WebPageProxy::didInitiateLoadForResource(uint64_t frameID, uint64_t resourceIdentifier, const ResourceRequest& request, bool pageIsProvisionallyLoading)
1845 {
1846     WebFrameProxy* frame = process()->webFrame(frameID);
1847     MESSAGE_CHECK(frame);
1848
1849     m_resourceLoadClient.didInitiateLoadForResource(this, frame, resourceIdentifier, request, pageIsProvisionallyLoading);
1850 }
1851
1852 void WebPageProxy::didSendRequestForResource(uint64_t frameID, uint64_t resourceIdentifier, const ResourceRequest& request, const ResourceResponse& redirectResponse)
1853 {
1854     WebFrameProxy* frame = process()->webFrame(frameID);
1855     MESSAGE_CHECK(frame);
1856
1857     m_resourceLoadClient.didSendRequestForResource(this, frame, resourceIdentifier, request, redirectResponse);
1858 }
1859
1860 void WebPageProxy::didReceiveResponseForResource(uint64_t frameID, uint64_t resourceIdentifier, const ResourceResponse& response)
1861 {
1862     WebFrameProxy* frame = process()->webFrame(frameID);
1863     MESSAGE_CHECK(frame);
1864
1865     m_resourceLoadClient.didReceiveResponseForResource(this, frame, resourceIdentifier, response);
1866 }
1867
1868 void WebPageProxy::didReceiveContentLengthForResource(uint64_t frameID, uint64_t resourceIdentifier, uint64_t contentLength)
1869 {
1870     WebFrameProxy* frame = process()->webFrame(frameID);
1871     MESSAGE_CHECK(frame);
1872
1873     m_resourceLoadClient.didReceiveContentLengthForResource(this, frame, resourceIdentifier, contentLength);
1874 }
1875
1876 void WebPageProxy::didFinishLoadForResource(uint64_t frameID, uint64_t resourceIdentifier)
1877 {
1878     WebFrameProxy* frame = process()->webFrame(frameID);
1879     MESSAGE_CHECK(frame);
1880
1881     m_resourceLoadClient.didFinishLoadForResource(this, frame, resourceIdentifier);
1882 }
1883
1884 void WebPageProxy::didFailLoadForResource(uint64_t frameID, uint64_t resourceIdentifier, const ResourceError& error)
1885 {
1886     WebFrameProxy* frame = process()->webFrame(frameID);
1887     MESSAGE_CHECK(frame);
1888
1889     m_resourceLoadClient.didFailLoadForResource(this, frame, resourceIdentifier, error);
1890 }
1891
1892 // UIClient
1893
1894 void WebPageProxy::createNewPage(const WindowFeatures& windowFeatures, uint32_t opaqueModifiers, int32_t opaqueMouseButton, uint64_t& newPageID, WebPageCreationParameters& newPageParameters)
1895 {
1896     RefPtr<WebPageProxy> newPage = m_uiClient.createNewPage(this, windowFeatures, static_cast<WebEvent::Modifiers>(opaqueModifiers), static_cast<WebMouseEvent::Button>(opaqueMouseButton));
1897     if (newPage) {
1898         newPageID = newPage->pageID();
1899         newPageParameters = newPage->creationParameters();
1900     } else
1901         newPageID = 0;
1902 }
1903     
1904 void WebPageProxy::showPage()
1905 {
1906     m_uiClient.showPage(this);
1907 }
1908
1909 void WebPageProxy::closePage()
1910 {
1911     m_uiClient.close(this);
1912 }
1913
1914 void WebPageProxy::runJavaScriptAlert(uint64_t frameID, const String& message)
1915 {
1916     WebFrameProxy* frame = process()->webFrame(frameID);
1917     MESSAGE_CHECK(frame);
1918
1919     // Since runJavaScriptAlert() can spin a nested run loop we need to turn off the responsiveness timer.
1920     process()->responsivenessTimer()->stop();
1921
1922     m_uiClient.runJavaScriptAlert(this, message, frame);
1923 }
1924
1925 void WebPageProxy::runJavaScriptConfirm(uint64_t frameID, const String& message, bool& result)
1926 {
1927     WebFrameProxy* frame = process()->webFrame(frameID);
1928     MESSAGE_CHECK(frame);
1929
1930     // Since runJavaScriptConfirm() can spin a nested run loop we need to turn off the responsiveness timer.
1931     process()->responsivenessTimer()->stop();
1932
1933     result = m_uiClient.runJavaScriptConfirm(this, message, frame);
1934 }
1935
1936 void WebPageProxy::runJavaScriptPrompt(uint64_t frameID, const String& message, const String& defaultValue, String& result)
1937 {
1938     WebFrameProxy* frame = process()->webFrame(frameID);
1939     MESSAGE_CHECK(frame);
1940
1941     // Since runJavaScriptPrompt() can spin a nested run loop we need to turn off the responsiveness timer.
1942     process()->responsivenessTimer()->stop();
1943
1944     result = m_uiClient.runJavaScriptPrompt(this, message, defaultValue, frame);
1945 }
1946
1947 void WebPageProxy::shouldInterruptJavaScript(bool& result)
1948 {
1949     // Since shouldInterruptJavaScript() can spin a nested run loop we need to turn off the responsiveness timer.
1950     process()->responsivenessTimer()->stop();
1951
1952     result = m_uiClient.shouldInterruptJavaScript(this);
1953 }
1954
1955 void WebPageProxy::setStatusText(const String& text)
1956 {
1957     m_uiClient.setStatusText(this, text);
1958 }
1959
1960 void WebPageProxy::mouseDidMoveOverElement(uint32_t opaqueModifiers, CoreIPC::ArgumentDecoder* arguments)
1961 {
1962     RefPtr<APIObject> userData;
1963     WebContextUserMessageDecoder messageDecoder(userData, m_process->context());
1964     if (!arguments->decode(messageDecoder))
1965         return;
1966
1967     WebEvent::Modifiers modifiers = static_cast<WebEvent::Modifiers>(opaqueModifiers);
1968
1969     m_uiClient.mouseDidMoveOverElement(this, modifiers, userData.get());
1970 }
1971
1972 void WebPageProxy::missingPluginButtonClicked(const String& mimeType, const String& url, const String& pluginsPageURL)
1973 {
1974     m_uiClient.missingPluginButtonClicked(this, mimeType, url, pluginsPageURL);
1975 }
1976
1977 void WebPageProxy::setToolbarsAreVisible(bool toolbarsAreVisible)
1978 {
1979     m_uiClient.setToolbarsAreVisible(this, toolbarsAreVisible);
1980 }
1981
1982 void WebPageProxy::getToolbarsAreVisible(bool& toolbarsAreVisible)
1983 {
1984     toolbarsAreVisible = m_uiClient.toolbarsAreVisible(this);
1985 }
1986
1987 void WebPageProxy::setMenuBarIsVisible(bool menuBarIsVisible)
1988 {
1989     m_uiClient.setMenuBarIsVisible(this, menuBarIsVisible);
1990 }
1991
1992 void WebPageProxy::getMenuBarIsVisible(bool& menuBarIsVisible)
1993 {
1994     menuBarIsVisible = m_uiClient.menuBarIsVisible(this);
1995 }
1996
1997 void WebPageProxy::setStatusBarIsVisible(bool statusBarIsVisible)
1998 {
1999     m_uiClient.setStatusBarIsVisible(this, statusBarIsVisible);
2000 }
2001
2002 void WebPageProxy::getStatusBarIsVisible(bool& statusBarIsVisible)
2003 {
2004     statusBarIsVisible = m_uiClient.statusBarIsVisible(this);
2005 }
2006
2007 void WebPageProxy::setIsResizable(bool isResizable)
2008 {
2009     m_uiClient.setIsResizable(this, isResizable);
2010 }
2011
2012 void WebPageProxy::getIsResizable(bool& isResizable)
2013 {
2014     isResizable = m_uiClient.isResizable(this);
2015 }
2016
2017 void WebPageProxy::setWindowFrame(const FloatRect& newWindowFrame)
2018 {
2019     m_uiClient.setWindowFrame(this, m_pageClient->convertToDeviceSpace(newWindowFrame));
2020 }
2021
2022 void WebPageProxy::getWindowFrame(FloatRect& newWindowFrame)
2023 {
2024     newWindowFrame = m_pageClient->convertToUserSpace(m_uiClient.windowFrame(this));
2025 }
2026
2027 void WebPageProxy::windowToScreen(const IntRect& viewRect, IntRect& result)
2028 {
2029     result = m_pageClient->windowToScreen(viewRect);
2030 }
2031     
2032 void WebPageProxy::runBeforeUnloadConfirmPanel(const String& message, uint64_t frameID, bool& shouldClose)
2033 {
2034     WebFrameProxy* frame = process()->webFrame(frameID);
2035     MESSAGE_CHECK(frame);
2036
2037     shouldClose = m_uiClient.runBeforeUnloadConfirmPanel(this, message, frame);
2038 }
2039
2040 #if ENABLE(TILED_BACKING_STORE)
2041 void WebPageProxy::pageDidRequestScroll(const IntPoint& point)
2042 {
2043     m_pageClient->pageDidRequestScroll(point);
2044 }
2045 #endif
2046
2047 void WebPageProxy::didChangeViewportData(const ViewportArguments& args)
2048 {
2049     m_pageClient->setViewportArguments(args);
2050 }
2051
2052 void WebPageProxy::pageDidScroll()
2053 {
2054     m_uiClient.pageDidScroll(this);
2055 }
2056
2057 void WebPageProxy::runOpenPanel(uint64_t frameID, const WebOpenPanelParameters::Data& data)
2058 {
2059     if (m_openPanelResultListener) {
2060         m_openPanelResultListener->invalidate();
2061         m_openPanelResultListener = 0;
2062     }
2063
2064     WebFrameProxy* frame = process()->webFrame(frameID);
2065     MESSAGE_CHECK(frame);
2066
2067     m_openPanelResultListener = WebOpenPanelResultListenerProxy::create(this);
2068
2069     // Since runOpenPanel() can spin a nested run loop we need to turn off the responsiveness timer.
2070     process()->responsivenessTimer()->stop();
2071
2072     if (!m_uiClient.runOpenPanel(this, frame, data, m_openPanelResultListener.get()))
2073         didCancelForOpenPanel();
2074 }
2075
2076 void WebPageProxy::printFrame(uint64_t frameID)
2077 {
2078     ASSERT(!m_isPerformingDOMPrintOperation);
2079     m_isPerformingDOMPrintOperation = true;
2080
2081     WebFrameProxy* frame = process()->webFrame(frameID);
2082     MESSAGE_CHECK(frame);
2083
2084     m_uiClient.printFrame(this, frame);
2085
2086     m_isPerformingDOMPrintOperation = false;
2087 }
2088
2089 #if PLATFORM(QT)
2090 void WebPageProxy::didChangeContentsSize(const WebCore::IntSize& size)
2091 {
2092     m_pageClient->didChangeContentsSize(size);
2093 }
2094
2095 void WebPageProxy::didFindZoomableArea(const WebCore::IntRect& area)
2096 {
2097     m_pageClient->didFindZoomableArea(area);
2098 }
2099
2100 void WebPageProxy::findZoomableAreaForPoint(const WebCore::IntPoint& point)
2101 {
2102     if (!isValid())
2103         return;
2104
2105     process()->send(Messages::WebPage::FindZoomableAreaForPoint(point), m_pageID);
2106 }
2107 #endif
2108
2109 void WebPageProxy::didDraw()
2110 {
2111     m_uiClient.didDraw(this);
2112 }
2113
2114 // Inspector
2115
2116 #if ENABLE(INSPECTOR)
2117
2118 WebInspectorProxy* WebPageProxy::inspector()
2119 {
2120     if (isClosed() || !isValid())
2121         return 0;
2122     if (!m_inspector)
2123         m_inspector = WebInspectorProxy::create(this);
2124     return m_inspector.get();
2125 }
2126
2127 #endif
2128
2129 #if ENABLE(FULLSCREEN_API)
2130 WebFullScreenManagerProxy* WebPageProxy::fullScreenManager()
2131 {
2132     if (!m_fullScreenManager)
2133         m_fullScreenManager = WebFullScreenManagerProxy::create(this);
2134     return m_fullScreenManager.get();
2135 }
2136 #endif
2137
2138 // BackForwardList
2139
2140 void WebPageProxy::backForwardAddItem(uint64_t itemID)
2141 {
2142     m_backForwardList->addItem(process()->webBackForwardItem(itemID));
2143 }
2144
2145 void WebPageProxy::backForwardGoToItem(uint64_t itemID)
2146 {
2147     m_backForwardList->goToItem(process()->webBackForwardItem(itemID));
2148 }
2149
2150 void WebPageProxy::backForwardItemAtIndex(int32_t index, uint64_t& itemID)
2151 {
2152     WebBackForwardListItem* item = m_backForwardList->itemAtIndex(index);
2153     itemID = item ? item->itemID() : 0;
2154 }
2155
2156 void WebPageProxy::backForwardBackListCount(int32_t& count)
2157 {
2158     count = m_backForwardList->backListCount();
2159 }
2160
2161 void WebPageProxy::backForwardForwardListCount(int32_t& count)
2162 {
2163     count = m_backForwardList->forwardListCount();
2164 }
2165
2166 void WebPageProxy::editorStateChanged(const EditorState& editorState)
2167 {
2168 #if PLATFORM(MAC)
2169     bool couldChangeSecureInputState = m_editorState.isInPasswordField != editorState.isInPasswordField || m_editorState.selectionIsNone;
2170 #endif
2171
2172     m_editorState = editorState;
2173
2174 #if PLATFORM(MAC)
2175     m_pageClient->updateTextInputState(couldChangeSecureInputState);
2176 #endif
2177 }
2178
2179 #if PLATFORM(WIN)
2180 void WebPageProxy::didChangeCompositionSelection(bool hasComposition)
2181 {
2182     m_pageClient->compositionSelectionChanged(hasComposition);
2183 }
2184
2185 void WebPageProxy::confirmComposition(const String& compositionString)
2186 {
2187     process()->send(Messages::WebPage::ConfirmComposition(compositionString), m_pageID);
2188 }
2189
2190 void WebPageProxy::setComposition(const String& compositionString, Vector<WebCore::CompositionUnderline>& underlines, int cursorPosition)
2191 {
2192     process()->send(Messages::WebPage::SetComposition(compositionString, underlines, cursorPosition), m_pageID);
2193 }
2194 #endif
2195     
2196 // Undo management
2197
2198 void WebPageProxy::registerEditCommandForUndo(uint64_t commandID, uint32_t editAction)
2199 {
2200     registerEditCommand(WebEditCommandProxy::create(commandID, static_cast<EditAction>(editAction), this), Undo);
2201 }
2202
2203 void WebPageProxy::canUndoRedo(uint32_t action, bool& result)
2204 {
2205     result = m_pageClient->canUndoRedo(static_cast<UndoOrRedo>(action));
2206 }
2207
2208 void WebPageProxy::executeUndoRedo(uint32_t action, bool& result)
2209 {
2210     m_pageClient->executeUndoRedo(static_cast<UndoOrRedo>(action));
2211     result = true;
2212 }
2213
2214 void WebPageProxy::clearAllEditCommands()
2215 {
2216     m_pageClient->clearAllEditCommands();
2217 }
2218
2219 void WebPageProxy::didCountStringMatches(const String& string, uint32_t matchCount)
2220 {
2221     m_findClient.didCountStringMatches(this, string, matchCount);
2222 }
2223
2224 void WebPageProxy::setFindIndicator(const FloatRect& selectionRectInWindowCoordinates, const Vector<FloatRect>& textRectsInSelectionRectCoordinates, const ShareableBitmap::Handle& contentImageHandle, bool fadeOut)
2225 {
2226     RefPtr<FindIndicator> findIndicator = FindIndicator::create(selectionRectInWindowCoordinates, textRectsInSelectionRectCoordinates, contentImageHandle);
2227     m_pageClient->setFindIndicator(findIndicator.release(), fadeOut);
2228 }
2229
2230 void WebPageProxy::didFindString(const String& string, uint32_t matchCount)
2231 {
2232     m_findClient.didFindString(this, string, matchCount);
2233 }
2234
2235 void WebPageProxy::didFailToFindString(const String& string)
2236 {
2237     m_findClient.didFailToFindString(this, string);
2238 }
2239
2240 void WebPageProxy::valueChangedForPopupMenu(WebPopupMenuProxy*, int32_t newSelectedIndex)
2241 {
2242     process()->send(Messages::WebPage::DidChangeSelectedIndexForActivePopupMenu(newSelectedIndex), m_pageID);
2243 }
2244
2245 void WebPageProxy::setTextFromItemForPopupMenu(WebPopupMenuProxy*, int32_t index)
2246 {
2247     process()->send(Messages::WebPage::SetTextForActivePopupMenu(index), m_pageID);
2248 }
2249
2250 NativeWebMouseEvent* WebPageProxy::currentlyProcessedMouseDownEvent()
2251 {
2252     return m_currentlyProcessedMouseDownEvent.get();
2253 }
2254
2255 void WebPageProxy::showPopupMenu(const IntRect& rect, uint64_t textDirection, const Vector<WebPopupItem>& items, int32_t selectedIndex, const PlatformPopupMenuData& data)
2256 {
2257     if (m_activePopupMenu) {
2258         m_activePopupMenu->hidePopupMenu();
2259         m_activePopupMenu->invalidate();
2260         m_activePopupMenu = 0;
2261     }
2262
2263     m_activePopupMenu = m_pageClient->createPopupMenuProxy(this);
2264
2265     // Since showPopupMenu() can spin a nested run loop we need to turn off the responsiveness timer.
2266     process()->responsivenessTimer()->stop();
2267
2268     RefPtr<WebPopupMenuProxy> protectedActivePopupMenu = m_activePopupMenu;
2269
2270     protectedActivePopupMenu->showPopupMenu(rect, static_cast<TextDirection>(textDirection), m_viewScaleFactor, items, data, selectedIndex);
2271     protectedActivePopupMenu->invalidate();
2272     protectedActivePopupMenu = 0;
2273 }
2274
2275 void WebPageProxy::hidePopupMenu()
2276 {
2277     if (!m_activePopupMenu)
2278         return;
2279
2280     m_activePopupMenu->hidePopupMenu();
2281     m_activePopupMenu->invalidate();
2282     m_activePopupMenu = 0;
2283 }
2284
2285 void WebPageProxy::showContextMenu(const IntPoint& menuLocation, const ContextMenuState& contextMenuState, const Vector<WebContextMenuItemData>& proposedItems, CoreIPC::ArgumentDecoder* arguments)
2286 {
2287     internalShowContextMenu(menuLocation, contextMenuState, proposedItems, arguments);
2288     
2289     // No matter the result of internalShowContextMenu, always notify the WebProcess that the menu is hidden so it starts handling mouse events again.
2290     process()->send(Messages::WebPage::ContextMenuHidden(), m_pageID);
2291 }
2292
2293 void WebPageProxy::internalShowContextMenu(const IntPoint& menuLocation, const ContextMenuState& contextMenuState, const Vector<WebContextMenuItemData>& proposedItems, CoreIPC::ArgumentDecoder* arguments)
2294 {
2295     RefPtr<APIObject> userData;
2296     WebContextUserMessageDecoder messageDecoder(userData, m_process->context());
2297     if (!arguments->decode(messageDecoder))
2298         return;
2299
2300     m_activeContextMenuState = contextMenuState;
2301
2302     if (m_activeContextMenu) {
2303         m_activeContextMenu->hideContextMenu();
2304         m_activeContextMenu = 0;
2305     }
2306
2307     m_activeContextMenu = m_pageClient->createContextMenuProxy(this);
2308
2309     // Since showContextMenu() can spin a nested run loop we need to turn off the responsiveness timer.
2310     process()->responsivenessTimer()->stop();
2311
2312     // Give the PageContextMenuClient one last swipe at changing the menu.
2313     Vector<WebContextMenuItemData> items;
2314     if (!m_contextMenuClient.getContextMenuFromProposedMenu(this, proposedItems, items, userData.get()))
2315         m_activeContextMenu->showContextMenu(menuLocation, proposedItems);
2316     else
2317         m_activeContextMenu->showContextMenu(menuLocation, items);
2318 }
2319
2320 void WebPageProxy::contextMenuItemSelected(const WebContextMenuItemData& item)
2321 {
2322     // Application custom items don't need to round-trip through to WebCore in the WebProcess.
2323     if (item.action() >= ContextMenuItemBaseApplicationTag) {
2324         m_contextMenuClient.customContextMenuItemSelected(this, item);
2325         return;
2326     }
2327
2328 #if PLATFORM(MAC)
2329     if (item.action() == ContextMenuItemTagSmartCopyPaste) {
2330         setSmartInsertDeleteEnabled(!isSmartInsertDeleteEnabled());
2331         return;
2332     }
2333     if (item.action() == ContextMenuItemTagSmartQuotes) {
2334         TextChecker::setAutomaticQuoteSubstitutionEnabled(!TextChecker::state().isAutomaticQuoteSubstitutionEnabled);
2335         process()->updateTextCheckerState();
2336         return;
2337     }
2338     if (item.action() == ContextMenuItemTagSmartDashes) {
2339         TextChecker::setAutomaticDashSubstitutionEnabled(!TextChecker::state().isAutomaticDashSubstitutionEnabled);
2340         process()->updateTextCheckerState();
2341         return;
2342     }
2343     if (item.action() == ContextMenuItemTagSmartLinks) {
2344         TextChecker::setAutomaticLinkDetectionEnabled(!TextChecker::state().isAutomaticLinkDetectionEnabled);
2345         process()->updateTextCheckerState();
2346         return;
2347     }
2348     if (item.action() == ContextMenuItemTagTextReplacement) {
2349         TextChecker::setAutomaticTextReplacementEnabled(!TextChecker::state().isAutomaticTextReplacementEnabled);
2350         process()->updateTextCheckerState();
2351         return;
2352     }
2353     if (item.action() == ContextMenuItemTagCorrectSpellingAutomatically) {
2354         TextChecker::setAutomaticSpellingCorrectionEnabled(!TextChecker::state().isAutomaticSpellingCorrectionEnabled);
2355         process()->updateTextCheckerState();
2356         return;        
2357     }
2358     if (item.action() == ContextMenuItemTagShowSubstitutions) {
2359         TextChecker::toggleSubstitutionsPanelIsShowing();
2360         return;
2361     }
2362 #endif
2363     if (item.action() == ContextMenuItemTagDownloadImageToDisk) {
2364         m_process->context()->download(this, KURL(KURL(), m_activeContextMenuState.absoluteImageURLString));
2365         return;    
2366     }
2367     if (item.action() == ContextMenuItemTagDownloadLinkToDisk) {
2368         m_process->context()->download(this, KURL(KURL(), m_activeContextMenuState.absoluteLinkURLString));
2369         return;
2370     }
2371     if (item.action() == ContextMenuItemTagCheckSpellingWhileTyping) {
2372         TextChecker::setContinuousSpellCheckingEnabled(!TextChecker::state().isContinuousSpellCheckingEnabled);
2373         process()->updateTextCheckerState();
2374         return;
2375     }
2376     if (item.action() == ContextMenuItemTagCheckGrammarWithSpelling) {
2377         TextChecker::setGrammarCheckingEnabled(!TextChecker::state().isGrammarCheckingEnabled);
2378         process()->updateTextCheckerState();
2379         return;
2380     }
2381     if (item.action() == ContextMenuItemTagShowSpellingPanel) {
2382         if (!TextChecker::spellingUIIsShowing())
2383             advanceToNextMisspelling(true);
2384         TextChecker::toggleSpellingUIIsShowing();
2385         return;
2386     }
2387     if (item.action() == ContextMenuItemTagLearnSpelling || item.action() == ContextMenuItemTagIgnoreSpelling)
2388         ++m_pendingLearnOrIgnoreWordMessageCount;
2389
2390     process()->send(Messages::WebPage::DidSelectItemFromActiveContextMenu(item), m_pageID);
2391 }
2392
2393 void WebPageProxy::didChooseFilesForOpenPanel(const Vector<String>& fileURLs)
2394 {
2395     if (!isValid())
2396         return;
2397
2398 #if ENABLE(WEB_PROCESS_SANDBOX)
2399     // FIXME: The sandbox extensions should be sent with the DidChooseFilesForOpenPanel message. This
2400     // is gated on a way of passing SandboxExtension::Handles in a Vector.
2401     for (size_t i = 0; i < fileURLs.size(); ++i) {
2402         SandboxExtension::Handle sandboxExtensionHandle;
2403         SandboxExtension::createHandle(fileURLs[i], SandboxExtension::ReadOnly, sandboxExtensionHandle);
2404         process()->send(Messages::WebPage::ExtendSandboxForFileFromOpenPanel(sandboxExtensionHandle), m_pageID);
2405     }
2406 #endif
2407
2408     process()->send(Messages::WebPage::DidChooseFilesForOpenPanel(fileURLs), m_pageID);
2409
2410     m_openPanelResultListener->invalidate();
2411     m_openPanelResultListener = 0;
2412 }
2413
2414 void WebPageProxy::didCancelForOpenPanel()
2415 {
2416     if (!isValid())
2417         return;
2418
2419     process()->send(Messages::WebPage::DidCancelForOpenPanel(), m_pageID);
2420     
2421     m_openPanelResultListener->invalidate();
2422     m_openPanelResultListener = 0;
2423 }
2424
2425 void WebPageProxy::advanceToNextMisspelling(bool startBeforeSelection) const
2426 {
2427     process()->send(Messages::WebPage::AdvanceToNextMisspelling(startBeforeSelection), m_pageID);
2428 }
2429
2430 void WebPageProxy::changeSpellingToWord(const String& word) const
2431 {
2432     if (word.isEmpty())
2433         return;
2434
2435     process()->send(Messages::WebPage::ChangeSpellingToWord(word), m_pageID);
2436 }
2437
2438 void WebPageProxy::registerEditCommand(PassRefPtr<WebEditCommandProxy> commandProxy, UndoOrRedo undoOrRedo)
2439 {
2440     m_pageClient->registerEditCommand(commandProxy, undoOrRedo);
2441 }
2442
2443 void WebPageProxy::addEditCommand(WebEditCommandProxy* command)
2444 {
2445     m_editCommandSet.add(command);
2446 }
2447
2448 void WebPageProxy::removeEditCommand(WebEditCommandProxy* command)
2449 {
2450     m_editCommandSet.remove(command);
2451
2452     if (!isValid())
2453         return;
2454     process()->send(Messages::WebPage::DidRemoveEditCommand(command->commandID()), m_pageID);
2455 }
2456
2457 bool WebPageProxy::isValidEditCommand(WebEditCommandProxy* command)
2458 {
2459     return m_editCommandSet.find(command) != m_editCommandSet.end();
2460 }
2461
2462 int64_t WebPageProxy::spellDocumentTag()
2463 {
2464     if (!m_hasSpellDocumentTag) {
2465         m_spellDocumentTag = TextChecker::uniqueSpellDocumentTag(this);
2466         m_hasSpellDocumentTag = true;
2467     }
2468
2469     return m_spellDocumentTag;
2470 }
2471
2472 #if USE(UNIFIED_TEXT_CHECKING)
2473
2474 void WebPageProxy::checkTextOfParagraph(const String& text, uint64_t checkingTypes, Vector<TextCheckingResult>& results)
2475 {
2476     results = TextChecker::checkTextOfParagraph(spellDocumentTag(), text.characters(), text.length(), checkingTypes);
2477 }
2478
2479 #endif
2480
2481 void WebPageProxy::checkSpellingOfString(const String& text, int32_t& misspellingLocation, int32_t& misspellingLength)
2482 {
2483     TextChecker::checkSpellingOfString(spellDocumentTag(), text.characters(), text.length(), misspellingLocation, misspellingLength);
2484 }
2485
2486 void WebPageProxy::checkGrammarOfString(const String& text, Vector<WebCore::GrammarDetail>& grammarDetails, int32_t& badGrammarLocation, int32_t& badGrammarLength)
2487 {
2488     TextChecker::checkGrammarOfString(spellDocumentTag(), text.characters(), text.length(), grammarDetails, badGrammarLocation, badGrammarLength);
2489 }
2490
2491 void WebPageProxy::spellingUIIsShowing(bool& isShowing)
2492 {
2493     isShowing = TextChecker::spellingUIIsShowing();
2494 }
2495
2496 void WebPageProxy::updateSpellingUIWithMisspelledWord(const String& misspelledWord)
2497 {
2498     TextChecker::updateSpellingUIWithMisspelledWord(spellDocumentTag(), misspelledWord);
2499 }
2500
2501 void WebPageProxy::updateSpellingUIWithGrammarString(const String& badGrammarPhrase, const GrammarDetail& grammarDetail)
2502 {
2503     TextChecker::updateSpellingUIWithGrammarString(spellDocumentTag(), badGrammarPhrase, grammarDetail);
2504 }
2505
2506 void WebPageProxy::getGuessesForWord(const String& word, const String& context, Vector<String>& guesses)
2507 {
2508     TextChecker::getGuessesForWord(spellDocumentTag(), word, context, guesses);
2509 }
2510
2511 void WebPageProxy::learnWord(const String& word)
2512 {
2513     MESSAGE_CHECK(m_pendingLearnOrIgnoreWordMessageCount);
2514     --m_pendingLearnOrIgnoreWordMessageCount;
2515
2516     TextChecker::learnWord(spellDocumentTag(), word);
2517 }
2518
2519 void WebPageProxy::ignoreWord(const String& word)
2520 {
2521     MESSAGE_CHECK(m_pendingLearnOrIgnoreWordMessageCount);
2522     --m_pendingLearnOrIgnoreWordMessageCount;
2523
2524     TextChecker::ignoreWord(spellDocumentTag(), word);
2525 }
2526
2527 // Other
2528
2529 void WebPageProxy::setFocus(bool focused)
2530 {
2531     if (focused)
2532         m_uiClient.focus(this);
2533     else
2534         m_uiClient.unfocus(this);
2535 }
2536
2537 void WebPageProxy::takeFocus(uint32_t direction)
2538 {
2539     m_uiClient.takeFocus(this, (static_cast<FocusDirection>(direction) == FocusDirectionForward) ? kWKFocusDirectionForward : kWKFocusDirectionBackward);
2540 }
2541
2542 void WebPageProxy::setToolTip(const String& toolTip)
2543 {
2544     String oldToolTip = m_toolTip;
2545     m_toolTip = toolTip;
2546     m_pageClient->toolTipChanged(oldToolTip, m_toolTip);
2547 }
2548
2549 void WebPageProxy::setCursor(const WebCore::Cursor& cursor)
2550 {
2551     m_pageClient->setCursor(cursor);
2552 }
2553
2554 void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled)
2555 {
2556     WebEvent::Type type = static_cast<WebEvent::Type>(opaqueType);
2557
2558     switch (type) {
2559     case WebEvent::NoType:
2560     case WebEvent::MouseMove:
2561         break;
2562
2563     case WebEvent::MouseDown:
2564     case WebEvent::MouseUp:
2565     case WebEvent::Wheel:
2566     case WebEvent::KeyDown:
2567     case WebEvent::KeyUp:
2568     case WebEvent::RawKeyDown:
2569     case WebEvent::Char:
2570 #if ENABLE(GESTURE_EVENTS)
2571     case WebEvent::GestureScrollBegin:
2572     case WebEvent::GestureScrollEnd:
2573 #endif
2574         process()->responsivenessTimer()->stop();
2575         break;
2576     }
2577
2578     switch (type) {
2579     case WebEvent::NoType:
2580         break;
2581     case WebEvent::MouseMove:
2582         m_processingMouseMoveEvent = false;
2583         if (m_nextMouseMoveEvent) {
2584             handleMouseEvent(*m_nextMouseMoveEvent);
2585             m_nextMouseMoveEvent = nullptr;
2586         }
2587         break;
2588     case WebEvent::MouseDown:
2589 #if ENABLE(GESTURE_EVENTS)
2590     case WebEvent::GestureScrollBegin:
2591     case WebEvent::GestureScrollEnd:
2592 #endif
2593         break;
2594     case WebEvent::MouseUp:
2595         m_currentlyProcessedMouseDownEvent = nullptr;
2596         break;
2597
2598     case WebEvent::Wheel: {
2599         m_processingWheelEvent = false;
2600         if (m_nextWheelEvent) {
2601             handleWheelEvent(*m_nextWheelEvent);
2602             m_nextWheelEvent = nullptr;
2603         }
2604         break;
2605     }
2606
2607     case WebEvent::KeyDown:
2608     case WebEvent::KeyUp:
2609     case WebEvent::RawKeyDown:
2610     case WebEvent::Char: {
2611         NativeWebKeyboardEvent event = m_keyEventQueue.first();
2612         MESSAGE_CHECK(type == event.type());
2613
2614         m_keyEventQueue.removeFirst();
2615
2616         m_pageClient->doneWithKeyEvent(event, handled);
2617
2618         if (handled)
2619             break;
2620
2621         if (m_uiClient.implementsDidNotHandleKeyEvent())
2622             m_uiClient.didNotHandleKeyEvent(this, event);
2623 #if PLATFORM(WIN)
2624         else
2625             ::TranslateMessage(event.nativeEvent());
2626 #endif
2627         break;
2628     }
2629     }
2630 }
2631
2632 void WebPageProxy::voidCallback(uint64_t callbackID)
2633 {
2634     RefPtr<VoidCallback> callback = m_voidCallbacks.take(callbackID);
2635     if (!callback) {
2636         // FIXME: Log error or assert.
2637         return;
2638     }
2639
2640     callback->performCallback();
2641 }
2642
2643 void WebPageProxy::dataCallback(const CoreIPC::DataReference& dataReference, uint64_t callbackID)
2644 {
2645     RefPtr<DataCallback> callback = m_dataCallbacks.take(callbackID);
2646     if (!callback) {
2647         // FIXME: Log error or assert.
2648         return;
2649     }
2650
2651     callback->performCallbackWithReturnValue(WebData::create(dataReference.data(), dataReference.size()).get());
2652 }
2653
2654 void WebPageProxy::stringCallback(const String& resultString, uint64_t callbackID)
2655 {
2656     RefPtr<StringCallback> callback = m_stringCallbacks.take(callbackID);
2657     if (!callback) {
2658         // FIXME: Log error or assert.
2659         // this can validly happen if a load invalidated the callback, though
2660         return;
2661     }
2662
2663     m_loadDependentStringCallbackIDs.remove(callbackID);
2664
2665     callback->performCallbackWithReturnValue(resultString.impl());
2666 }
2667
2668 void WebPageProxy::scriptValueCallback(const CoreIPC::DataReference& dataReference, uint64_t callbackID)
2669 {
2670     RefPtr<ScriptValueCallback> callback = m_scriptValueCallbacks.take(callbackID);
2671     if (!callback) {
2672         // FIXME: Log error or assert.
2673         return;
2674     }
2675
2676     Vector<uint8_t> data;
2677     data.reserveInitialCapacity(dataReference.size());
2678     data.append(dataReference.data(), dataReference.size());
2679
2680     callback->performCallbackWithReturnValue(data.size() ? WebSerializedScriptValue::adopt(data).get() : 0);
2681 }
2682
2683 void WebPageProxy::computedPagesCallback(const Vector<WebCore::IntRect>& pageRects, double totalScaleFactorForPrinting, uint64_t callbackID)
2684 {
2685     RefPtr<ComputedPagesCallback> callback = m_computedPagesCallbacks.take(callbackID);
2686     if (!callback) {
2687         // FIXME: Log error or assert.
2688         return;
2689     }
2690
2691     callback->performCallbackWithReturnValue(pageRects, totalScaleFactorForPrinting);
2692 }
2693
2694 void WebPageProxy::validateCommandCallback(const String& commandName, bool isEnabled, int state, uint64_t callbackID)
2695 {
2696     RefPtr<ValidateCommandCallback> callback = m_validateCommandCallbacks.take(callbackID);
2697     if (!callback) {
2698         // FIXME: Log error or assert.
2699         return;
2700     }
2701
2702     callback->performCallbackWithReturnValue(commandName.impl(), isEnabled, state);
2703 }
2704
2705 void WebPageProxy::focusedFrameChanged(uint64_t frameID)
2706 {
2707     if (!frameID) {
2708         m_focusedFrame = 0;
2709         return;
2710     }
2711
2712     WebFrameProxy* frame = process()->webFrame(frameID);
2713     MESSAGE_CHECK(frame);
2714
2715     m_focusedFrame = frame;
2716 }
2717
2718 void WebPageProxy::frameSetLargestFrameChanged(uint64_t frameID)
2719 {
2720     if (!frameID) {
2721         m_frameSetLargestFrame = 0;
2722         return;
2723     }
2724
2725     WebFrameProxy* frame = process()->webFrame(frameID);
2726     MESSAGE_CHECK(frame);
2727
2728     m_frameSetLargestFrame = frame;
2729 }
2730
2731 void WebPageProxy::processDidBecomeUnresponsive()
2732 {
2733     updateBackingStoreDiscardableState();
2734
2735     m_loaderClient.processDidBecomeUnresponsive(this);
2736 }
2737
2738 void WebPageProxy::processDidBecomeResponsive()
2739 {
2740     updateBackingStoreDiscardableState();
2741
2742     m_loaderClient.processDidBecomeResponsive(this);
2743 }
2744
2745 void WebPageProxy::processDidCrash()
2746 {
2747     ASSERT(m_pageClient);
2748
2749     m_isValid = false;
2750
2751     m_mainFrame = nullptr;
2752     m_drawingArea = nullptr;
2753
2754 #if ENABLE(INSPECTOR)
2755     if (m_inspector) {
2756         m_inspector->invalidate();
2757         m_inspector = nullptr;
2758     }
2759 #endif
2760
2761 #if ENABLE(FULLSCREEN_API)
2762     if (m_fullScreenManager) {
2763         m_fullScreenManager->invalidate();
2764         m_fullScreenManager = nullptr;
2765     }
2766 #endif
2767
2768     if (m_openPanelResultListener) {
2769         m_openPanelResultListener->invalidate();
2770         m_openPanelResultListener = nullptr;
2771     }
2772
2773     m_geolocationPermissionRequestManager.invalidateRequests();
2774
2775     m_toolTip = String();
2776
2777     m_mainFrameHasHorizontalScrollbar = false;
2778     m_mainFrameHasVerticalScrollbar = false;
2779
2780     m_mainFrameIsPinnedToLeftSide = false;
2781     m_mainFrameIsPinnedToRightSide = false;
2782
2783     m_visibleScrollerThumbRect = IntRect();
2784
2785     invalidateCallbackMap(m_voidCallbacks);
2786     invalidateCallbackMap(m_dataCallbacks);
2787     invalidateCallbackMap(m_stringCallbacks);
2788     m_loadDependentStringCallbackIDs.clear();
2789     invalidateCallbackMap(m_scriptValueCallbacks);
2790     invalidateCallbackMap(m_computedPagesCallbacks);
2791     invalidateCallbackMap(m_validateCommandCallbacks);
2792
2793     Vector<WebEditCommandProxy*> editCommandVector;
2794     copyToVector(m_editCommandSet, editCommandVector);
2795     m_editCommandSet.clear();
2796     for (size_t i = 0, size = editCommandVector.size(); i < size; ++i)
2797         editCommandVector[i]->invalidate();
2798     m_pageClient->clearAllEditCommands();
2799
2800     m_activePopupMenu = 0;
2801
2802     m_estimatedProgress = 0.0;
2803
2804     m_pendingLearnOrIgnoreWordMessageCount = 0;
2805
2806     m_pageClient->processDidCrash();
2807     m_loaderClient.processDidCrash(this);
2808
2809     // Can't expect DidReceiveEvent notifications from a crashed web process.
2810     m_keyEventQueue.clear();
2811     m_nextWheelEvent = nullptr;
2812     m_nextMouseMoveEvent = nullptr;
2813     m_currentlyProcessedMouseDownEvent = nullptr;
2814
2815 #if PLATFORM(MAC) && !defined(BUILDING_ON_SNOW_LEOPARD)
2816     dismissCorrectionPanel(ReasonForDismissingCorrectionPanelIgnored);
2817     m_pageClient->dismissDictionaryLookupPanel();
2818 #endif
2819
2820     process()->responsivenessTimer()->stop();
2821 }
2822
2823 WebPageCreationParameters WebPageProxy::creationParameters() const
2824 {
2825     WebPageCreationParameters parameters;
2826
2827     parameters.viewSize = m_pageClient->viewSize();
2828     parameters.isActive = m_pageClient->isViewWindowActive();
2829     parameters.isFocused = m_pageClient->isViewFocused();
2830     parameters.isVisible = m_pageClient->isViewVisible();
2831     parameters.isInWindow = m_pageClient->isViewInWindow();
2832     parameters.drawingAreaType = m_drawingArea->type();
2833     parameters.store = m_pageGroup->preferences()->store();
2834     parameters.pageGroupData = m_pageGroup->data();
2835     parameters.drawsBackground = m_drawsBackground;
2836     parameters.drawsTransparentBackground = m_drawsTransparentBackground;
2837     parameters.areMemoryCacheClientCallsEnabled = m_areMemoryCacheClientCallsEnabled;
2838     parameters.useFixedLayout = m_useFixedLayout;
2839     parameters.fixedLayoutSize = m_fixedLayoutSize;
2840     parameters.userAgent = userAgent();
2841     parameters.sessionState = SessionState(m_backForwardList->entries(), m_backForwardList->currentIndex());
2842     parameters.highestUsedBackForwardItemID = WebBackForwardListItem::highedUsedItemID();
2843     parameters.canRunBeforeUnloadConfirmPanel = m_uiClient.canRunBeforeUnloadConfirmPanel();
2844     parameters.canRunModal = m_uiClient.canRunModal();
2845     parameters.userSpaceScaleFactor = m_pageClient->userSpaceScaleFactor();
2846
2847 #if PLATFORM(MAC)
2848     parameters.isSmartInsertDeleteEnabled = m_isSmartInsertDeleteEnabled;
2849 #endif
2850
2851 #if PLATFORM(WIN)
2852     parameters.nativeWindow = m_pageClient->nativeWindow();
2853 #endif
2854
2855     return parameters;
2856 }
2857
2858 #if USE(ACCELERATED_COMPOSITING)
2859 void WebPageProxy::enterAcceleratedCompositingMode(const LayerTreeContext& layerTreeContext)
2860 {
2861     m_pageClient->enterAcceleratedCompositingMode(layerTreeContext);
2862 }
2863
2864 void WebPageProxy::exitAcceleratedCompositingMode()
2865 {
2866     m_pageClient->exitAcceleratedCompositingMode();
2867 }
2868 #endif // USE(ACCELERATED_COMPOSITING)
2869
2870 void WebPageProxy::backForwardClear()
2871 {
2872     m_backForwardList->clear();
2873 }
2874
2875 void WebPageProxy::canAuthenticateAgainstProtectionSpaceInFrame(uint64_t frameID, const WebCore::ProtectionSpace& coreProtectionSpace, bool& canAuthenticate)
2876 {
2877     WebFrameProxy* frame = process()->webFrame(frameID);
2878     MESSAGE_CHECK(frame);
2879
2880     RefPtr<WebProtectionSpace> protectionSpace = WebProtectionSpace::create(coreProtectionSpace);
2881     
2882     canAuthenticate = m_loaderClient.canAuthenticateAgainstProtectionSpaceInFrame(this, frame, protectionSpace.get());
2883 }
2884
2885 void WebPageProxy::didReceiveAuthenticationChallenge(uint64_t frameID, const WebCore::AuthenticationChallenge& coreChallenge, uint64_t challengeID)
2886 {
2887     WebFrameProxy* frame = process()->webFrame(frameID);
2888     MESSAGE_CHECK(frame);
2889
2890     RefPtr<AuthenticationChallengeProxy> authenticationChallenge = AuthenticationChallengeProxy::create(coreChallenge, challengeID, process());
2891     
2892     m_loaderClient.didReceiveAuthenticationChallengeInFrame(this, frame, authenticationChallenge.get());
2893 }
2894
2895 void WebPageProxy::exceededDatabaseQuota(uint64_t frameID, const String& originIdentifier, const String& databaseName, const String& displayName, uint64_t currentQuota, uint64_t currentUsage, uint64_t expectedUsage, uint64_t& newQuota)
2896 {
2897     WebFrameProxy* frame = process()->webFrame(frameID);
2898     MESSAGE_CHECK(frame);
2899
2900     RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::create(originIdentifier);
2901
2902     newQuota = m_uiClient.exceededDatabaseQuota(this, frame, origin.get(), databaseName, displayName, currentQuota, currentUsage, expectedUsage);
2903 }
2904
2905 void WebPageProxy::requestGeolocationPermissionForFrame(uint64_t geolocationID, uint64_t frameID, String originIdentifier)
2906 {
2907     WebFrameProxy* frame = process()->webFrame(frameID);
2908     MESSAGE_CHECK(frame);
2909
2910     RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::create(originIdentifier);
2911     RefPtr<GeolocationPermissionRequestProxy> request = m_geolocationPermissionRequestManager.createRequest(geolocationID);
2912
2913     if (!m_uiClient.decidePolicyForGeolocationPermissionRequest(this, frame, origin.get(), request.get()))
2914         request->deny();
2915 }
2916
2917 float WebPageProxy::headerHeight(WebFrameProxy* frame)
2918 {
2919     return m_uiClient.headerHeight(this, frame);
2920 }
2921
2922 float WebPageProxy::footerHeight(WebFrameProxy* frame)
2923 {
2924     return m_uiClient.footerHeight(this, frame);
2925 }
2926
2927 void WebPageProxy::drawHeader(WebFrameProxy* frame, const FloatRect& rect)
2928 {
2929     m_uiClient.drawHeader(this, frame, rect);
2930 }
2931
2932 void WebPageProxy::drawFooter(WebFrameProxy* frame, const FloatRect& rect)
2933 {
2934     m_uiClient.drawFooter(this, frame, rect);
2935 }
2936
2937 void WebPageProxy::didCompleteRubberBandForMainFrame(const IntSize& initialOverhang)
2938 {
2939     m_uiClient.didCompleteRubberBandForMainFrame(this, initialOverhang);
2940 }
2941
2942 void WebPageProxy::notifyScrollerThumbIsVisibleInRect(const IntRect& scrollerThumb)
2943 {
2944     m_visibleScrollerThumbRect = scrollerThumb;
2945 }
2946
2947 void WebPageProxy::didChangeScrollbarsForMainFrame(bool hasHorizontalScrollbar, bool hasVerticalScrollbar)
2948 {
2949     m_mainFrameHasHorizontalScrollbar = hasHorizontalScrollbar;
2950     m_mainFrameHasVerticalScrollbar = hasVerticalScrollbar;
2951
2952     m_pageClient->didChangeScrollbarsForMainFrame();
2953 }
2954
2955 void WebPageProxy::didChangeScrollOffsetPinningForMainFrame(bool pinnedToLeftSide, bool pinnedToRightSide)
2956 {
2957     m_mainFrameIsPinnedToLeftSide = pinnedToLeftSide;
2958     m_mainFrameIsPinnedToRightSide = pinnedToRightSide;
2959 }
2960
2961 void WebPageProxy::didFailToInitializePlugin(const String& mimeType)
2962 {
2963     m_loaderClient.didFailToInitializePlugin(this, mimeType);
2964 }
2965
2966 void WebPageProxy::didFinishLoadingDataForCustomRepresentation(const String& suggestedFilename, const CoreIPC::DataReference& dataReference)
2967 {
2968     m_pageClient->didFinishLoadingDataForCustomRepresentation(suggestedFilename, dataReference);
2969 }
2970
2971 void WebPageProxy::backForwardRemovedItem(uint64_t itemID)
2972 {
2973     process()->send(Messages::WebPage::DidRemoveBackForwardItem(itemID), m_pageID);
2974 }
2975
2976 void WebPageProxy::beginPrinting(WebFrameProxy* frame, const PrintInfo& printInfo)
2977 {
2978     if (m_isInPrintingMode)
2979         return;
2980
2981     m_isInPrintingMode = true;
2982     process()->send(Messages::WebPage::BeginPrinting(frame->frameID(), printInfo), m_pageID, m_isPerformingDOMPrintOperation ? CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply : 0);
2983 }
2984
2985 void WebPageProxy::endPrinting()
2986 {
2987     if (!m_isInPrintingMode)
2988         return;
2989
2990     m_isInPrintingMode = false;
2991     process()->send(Messages::WebPage::EndPrinting(), m_pageID, m_isPerformingDOMPrintOperation ? CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply : 0);
2992 }
2993
2994 void WebPageProxy::computePagesForPrinting(WebFrameProxy* frame, const PrintInfo& printInfo, PassRefPtr<ComputedPagesCallback> prpCallback)
2995 {
2996     RefPtr<ComputedPagesCallback> callback = prpCallback;
2997     if (!isValid()) {
2998         callback->invalidate();
2999         return;
3000     }
3001
3002     uint64_t callbackID = callback->callbackID();
3003     m_computedPagesCallbacks.set(callbackID, callback.get());
3004     m_isInPrintingMode = true;
3005     process()->send(Messages::WebPage::ComputePagesForPrinting(frame->frameID(), printInfo, callbackID), m_pageID, m_isPerformingDOMPrintOperation ? CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply : 0);
3006 }
3007
3008 #if PLATFORM(MAC) || PLATFORM(WIN)
3009 void WebPageProxy::drawRectToPDF(WebFrameProxy* frame, const IntRect& rect, PassRefPtr<DataCallback> prpCallback)
3010 {
3011     RefPtr<DataCallback> callback = prpCallback;
3012     if (!isValid()) {
3013         callback->invalidate();
3014         return;
3015     }
3016     
3017     uint64_t callbackID = callback->callbackID();
3018     m_dataCallbacks.set(callbackID, callback.get());
3019     process()->send(Messages::WebPage::DrawRectToPDF(frame->frameID(), rect, callbackID), m_pageID, m_isPerformingDOMPrintOperation ? CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply : 0);
3020 }
3021
3022 void WebPageProxy::drawPagesToPDF(WebFrameProxy* frame, uint32_t first, uint32_t count, PassRefPtr<DataCallback> prpCallback)
3023 {
3024     RefPtr<DataCallback> callback = prpCallback;
3025     if (!isValid()) {
3026         callback->invalidate();
3027         return;
3028     }
3029     
3030     uint64_t callbackID = callback->callbackID();
3031     m_dataCallbacks.set(callbackID, callback.get());
3032     process()->send(Messages::WebPage::DrawPagesToPDF(frame->frameID(), first, count, callbackID), m_pageID, m_isPerformingDOMPrintOperation ? CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply : 0);
3033 }
3034 #endif
3035
3036 void WebPageProxy::flashBackingStoreUpdates(const Vector<IntRect>& updateRects)
3037 {
3038     m_pageClient->flashBackingStoreUpdates(updateRects);
3039 }
3040
3041 void WebPageProxy::updateBackingStoreDiscardableState()
3042 {
3043     bool isDiscardable;
3044
3045     if (!process()->responsivenessTimer()->isResponsive())
3046         isDiscardable = false;
3047     else
3048         isDiscardable = !m_pageClient->isViewWindowActive() || !isViewVisible();
3049
3050     m_drawingArea->setBackingStoreIsDiscardable(isDiscardable);
3051 }
3052
3053 Color WebPageProxy::viewUpdatesFlashColor()
3054 {
3055     return Color(0, 200, 255);
3056 }
3057
3058 Color WebPageProxy::backingStoreUpdatesFlashColor()
3059 {
3060     return Color(200, 0, 255);
3061 }
3062
3063 void WebPageProxy::saveDataToFileInDownloadsFolder(const String& suggestedFilename, const String& mimeType, const String& originatingURLString, WebData* data)
3064 {
3065     m_uiClient.saveDataToFileInDownloadsFolder(this, suggestedFilename, mimeType, originatingURLString, data);
3066 }
3067
3068 void WebPageProxy::linkClicked(const String& url, const WebMouseEvent& event)
3069 {
3070     process()->send(Messages::WebPage::LinkClicked(url, event), m_pageID, 0);
3071 }
3072
3073 PassRefPtr<WebImage> WebPageProxy::createSnapshotOfVisibleContent()
3074 {
3075     ShareableBitmap::Handle snapshotHandle;
3076     // Do not wait for more than a second (arbitrary) for the WebProcess to get the snapshot so
3077     // that the UI Process is not permanently stuck waiting on a potentially crashing Web Process.
3078     static const double createSnapshotOfVisibleContentSyncMessageTimeout = 1.0;
3079     process()->sendSync(Messages::WebPage::CreateSnapshotOfVisibleContent(), Messages::WebPage::CreateSnapshotOfVisibleContent::Reply(snapshotHandle), m_pageID, createSnapshotOfVisibleContentSyncMessageTimeout);
3080     if (snapshotHandle.isNull())
3081         return 0;
3082     return WebImage::create(ShareableBitmap::create(snapshotHandle));
3083 }
3084
3085 #if PLATFORM(MAC)
3086
3087 void WebPageProxy::substitutionsPanelIsShowing(bool& isShowing)
3088 {
3089     isShowing = TextChecker::substitutionsPanelIsShowing();
3090 }
3091
3092 #if !defined(BUILDING_ON_SNOW_LEOPARD)
3093 void WebPageProxy::showCorrectionPanel(int32_t panelType, const WebCore::FloatRect& boundingBoxOfReplacedString, const String& replacedString, const String& replacementString, const Vector<String>& alternativeReplacementStrings)
3094 {
3095     m_pageClient->showCorrectionPanel((WebCore::CorrectionPanelInfo::PanelType)panelType, boundingBoxOfReplacedString, replacedString, replacementString, alternativeReplacementStrings);
3096 }
3097
3098 void WebPageProxy::dismissCorrectionPanel(int32_t reason)
3099 {
3100     m_pageClient->dismissCorrectionPanel((WebCore::ReasonForDismissingCorrectionPanel)reason);
3101 }
3102
3103 void WebPageProxy::dismissCorrectionPanelSoon(int32_t reason, String& result)
3104 {
3105     result = m_pageClient->dismissCorrectionPanelSoon((WebCore::ReasonForDismissingCorrectionPanel)reason);
3106 }
3107
3108 void WebPageProxy::recordAutocorrectionResponse(int32_t responseType, const String& replacedString, const String& replacementString)
3109 {
3110     m_pageClient->recordAutocorrectionResponse((WebCore::EditorClient::AutocorrectionResponseType)responseType, replacedString, replacementString);
3111 }
3112 #endif // !defined(BUILDING_ON_SNOW_LEOPARD)
3113
3114 void WebPageProxy::handleCorrectionPanelResult(const String& result)
3115 {
3116 #if !defined(BUILDING_ON_SNOW_LEOPARD)
3117     if (!isClosed())
3118         process()->send(Messages::WebPage::HandleCorrectionPanelResult(result), m_pageID, 0);
3119 #endif
3120 }
3121 #endif // PLATFORM(MAC)
3122
3123 } // namespace WebKit