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