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