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