WebKit2: Implement TextChecker on Windows
[WebKit-https.git] / Source / WebKit2 / UIProcess / WebPageProxy.cpp
1 /*
2  * Copyright (C) 2010, 2011 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "WebPageProxy.h"
28
29 #include "AuthenticationChallengeProxy.h"
30 #include "AuthenticationDecisionListener.h"
31 #include "DataReference.h"
32 #include "DrawingAreaProxy.h"
33 #include "FindIndicator.h"
34 #include "MessageID.h"
35 #include "NativeWebKeyboardEvent.h"
36 #include "PageClient.h"
37 #include "PrintInfo.h"
38 #include "SessionState.h"
39 #include "StringPairVector.h"
40 #include "TextChecker.h"
41 #include "TextCheckerState.h"
42 #include "WKContextPrivate.h"
43 #include "WebBackForwardList.h"
44 #include "WebBackForwardListItem.h"
45 #include "WebCertificateInfo.h"
46 #include "WebContext.h"
47 #include "WebContextMenuProxy.h"
48 #include "WebContextUserMessageCoders.h"
49 #include "WebCoreArgumentCoders.h"
50 #include "WebData.h"
51 #include "WebEditCommandProxy.h"
52 #include "WebEvent.h"
53 #include "WebFormSubmissionListenerProxy.h"
54 #include "WebFramePolicyListenerProxy.h"
55 #include "WebFullScreenManagerProxy.h"
56 #include "WebInspectorProxy.h"
57 #include "WebOpenPanelResultListenerProxy.h"
58 #include "WebPageCreationParameters.h"
59 #include "WebPageGroup.h"
60 #include "WebPageGroupData.h"
61 #include "WebPageMessages.h"
62 #include "WebPopupItem.h"
63 #include "WebPopupMenuProxy.h"
64 #include "WebPreferences.h"
65 #include "WebProcessMessages.h"
66 #include "WebProcessProxy.h"
67 #include "WebProtectionSpace.h"
68 #include "WebSecurityOrigin.h"
69 #include "WebURLRequest.h"
70 #include <WebCore/DragData.h>
71 #include <WebCore/FloatRect.h>
72 #include <WebCore/MIMETypeRegistry.h>
73 #include <WebCore/WindowFeatures.h>
74 #include <stdio.h>
75
76 #if PLATFORM(WIN)
77 #include "WebDragSource.h"
78 #include <WebCore/BitmapInfo.h>
79 #include <WebCore/COMPtr.h>
80 #include <WebCore/WCDataObject.h>
81 #include <shlobj.h>
82 #endif
83
84 #ifndef NDEBUG
85 #include <wtf/RefCountedLeakCounter.h>
86 #endif
87
88 // This controls what strategy we use for mouse wheel coalesing.
89 #define MERGE_WHEEL_EVENTS 0
90
91 #define MESSAGE_CHECK(assertion) MESSAGE_CHECK_BASE(assertion, process()->connection())
92
93 using namespace WebCore;
94
95 namespace WebKit {
96
97 WKPageDebugPaintFlags WebPageProxy::s_debugPaintFlags = 0;
98
99 #ifndef NDEBUG
100 static WTF::RefCountedLeakCounter webPageProxyCounter("WebPageProxy");
101 #endif
102
103 PassRefPtr<WebPageProxy> WebPageProxy::create(PageClient* pageClient, WebContext* context, WebPageGroup* pageGroup, uint64_t pageID)
104 {
105     return adoptRef(new WebPageProxy(pageClient, context, pageGroup, pageID));
106 }
107
108 WebPageProxy::WebPageProxy(PageClient* pageClient, WebContext* context, WebPageGroup* pageGroup, uint64_t pageID)
109     : m_pageClient(pageClient)
110     , m_context(context)
111     , m_pageGroup(pageGroup)
112     , m_mainFrame(0)
113     , m_userAgent(standardUserAgent())
114     , m_geolocationPermissionRequestManager(this)
115     , m_estimatedProgress(0)
116     , m_isInWindow(m_pageClient->isViewInWindow())
117     , m_isVisible(m_pageClient->isViewVisible())
118     , m_backForwardList(WebBackForwardList::create(this))
119     , m_textZoomFactor(1)
120     , m_pageZoomFactor(1)
121     , m_viewScaleFactor(1)
122     , m_drawsBackground(true)
123     , m_drawsTransparentBackground(false)
124     , m_areMemoryCacheClientCallsEnabled(true)
125     , m_useFixedLayout(false)
126     , m_isValid(true)
127     , m_isClosed(false)
128     , m_isInPrintingMode(false)
129     , m_isPerformingDOMPrintOperation(false)
130     , m_inDecidePolicyForMIMEType(false)
131     , m_syncMimeTypePolicyActionIsValid(false)
132     , m_syncMimeTypePolicyAction(PolicyUse)
133     , m_syncMimeTypePolicyDownloadID(0)
134     , m_inDecidePolicyForNavigationAction(false)
135     , m_syncNavigationActionPolicyActionIsValid(false)
136     , m_syncNavigationActionPolicyAction(PolicyUse)
137     , m_syncNavigationActionPolicyDownloadID(0)
138     , m_processingWheelEvent(false)
139     , m_processingMouseMoveEvent(false)
140     , m_pageID(pageID)
141 #if PLATFORM(MAC)
142     , m_isSmartInsertDeleteEnabled(TextChecker::isSmartInsertDeleteEnabled())
143 #endif
144     , m_spellDocumentTag(0)
145     , m_hasSpellDocumentTag(false)
146     , m_pendingLearnOrIgnoreWordMessageCount(0)
147     , m_mainFrameHasCustomRepresentation(false)
148     , m_currentDragOperation(DragOperationNone)
149     , m_mainFrameHasHorizontalScrollbar(false)
150     , m_mainFrameHasVerticalScrollbar(false)
151     , m_mainFrameIsPinnedToLeftSide(false)
152     , m_mainFrameIsPinnedToRightSide(false)
153 {
154 #ifndef NDEBUG
155     webPageProxyCounter.increment();
156 #endif
157
158     WebContext::statistics().wkPageCount++;
159
160     m_pageGroup->addPage(this);
161 }
162
163 WebPageProxy::~WebPageProxy()
164 {
165     WebContext::statistics().wkPageCount--;
166
167     if (m_hasSpellDocumentTag)
168         TextChecker::closeSpellDocumentWithTag(m_spellDocumentTag);
169
170     m_pageGroup->removePage(this);
171
172 #ifndef NDEBUG
173     webPageProxyCounter.decrement();
174 #endif
175 }
176
177 WebProcessProxy* WebPageProxy::process() const
178 {
179     return m_context->process();
180 }
181
182 bool WebPageProxy::isValid()
183 {
184     // A page that has been explicitly closed is never valid.
185     if (m_isClosed)
186         return false;
187
188     return m_isValid;
189 }
190
191 void WebPageProxy::setDrawingArea(PassOwnPtr<DrawingAreaProxy> drawingArea)
192 {
193     if (drawingArea == m_drawingArea)
194         return;
195
196     m_drawingArea = drawingArea;
197 }
198
199 void WebPageProxy::initializeLoaderClient(const WKPageLoaderClient* loadClient)
200 {
201     m_loaderClient.initialize(loadClient);
202 }
203
204 void WebPageProxy::initializePolicyClient(const WKPagePolicyClient* policyClient)
205 {
206     m_policyClient.initialize(policyClient);
207 }
208
209 void WebPageProxy::initializeFormClient(const WKPageFormClient* formClient)
210 {
211     m_formClient.initialize(formClient);
212 }
213
214 void WebPageProxy::initializeResourceLoadClient(const WKPageResourceLoadClient* client)
215 {
216     m_resourceLoadClient.initialize(client);
217 }
218
219 void WebPageProxy::initializeUIClient(const WKPageUIClient* client)
220 {
221     if (!isValid())
222         return;
223
224     m_uiClient.initialize(client);
225
226     process()->send(Messages::WebPage::SetCanRunBeforeUnloadConfirmPanel(m_uiClient.canRunBeforeUnloadConfirmPanel()), m_pageID);
227     process()->send(Messages::WebPage::SetCanRunModal(m_uiClient.canRunModal()), m_pageID);
228 }
229
230 void WebPageProxy::initializeFindClient(const WKPageFindClient* client)
231 {
232     m_findClient.initialize(client);
233 }
234
235 void WebPageProxy::initializeContextMenuClient(const WKPageContextMenuClient* client)
236 {
237     m_contextMenuClient.initialize(client);
238 }
239
240 void WebPageProxy::reattachToWebProcess()
241 {
242     m_isValid = true;
243
244     context()->relaunchProcessIfNecessary();
245     process()->addExistingWebPage(this, m_pageID);
246
247     initializeWebPage();
248
249     m_pageClient->didRelaunchProcess();
250 }
251
252 void WebPageProxy::reattachToWebProcessWithItem(WebBackForwardListItem* item)
253 {
254     if (item && item != m_backForwardList->currentItem())
255         m_backForwardList->goToItem(item);
256     
257     reattachToWebProcess();
258
259     if (!item)
260         return;
261
262     SandboxExtension::Handle sandboxExtensionHandle;
263     initializeSandboxExtensionHandle(KURL(KURL(), item->url()), sandboxExtensionHandle);
264     process()->send(Messages::WebPage::GoToBackForwardItem(item->itemID(), sandboxExtensionHandle), m_pageID);
265 }
266
267 void WebPageProxy::initializeWebPage()
268 {
269     ASSERT(isValid());
270
271     BackForwardListItemVector items = m_backForwardList->entries();
272     for (size_t i = 0; i < items.size(); ++i)
273         process()->registerNewWebBackForwardListItem(items[i].get());
274
275     m_drawingArea = m_pageClient->createDrawingAreaProxy();
276     ASSERT(m_drawingArea);
277
278     process()->send(Messages::WebProcess::CreateWebPage(m_pageID, creationParameters()), 0);
279 }
280
281 void WebPageProxy::close()
282 {
283     if (!isValid())
284         return;
285
286     m_isClosed = true;
287
288     m_backForwardList->pageClosed();
289     m_pageClient->pageClosed();
290
291     process()->disconnectFramesFromPage(this);
292     m_mainFrame = 0;
293
294 #if ENABLE(INSPECTOR)
295     if (m_inspector) {
296         m_inspector->invalidate();
297         m_inspector = 0;
298     }
299 #endif
300
301 #if ENABLE(FULLSCREEN_API)
302     if (m_fullScreenManager) {
303         m_fullScreenManager->invalidate();
304         m_fullScreenManager = 0;
305     }
306 #endif
307
308     if (m_openPanelResultListener) {
309         m_openPanelResultListener->invalidate();
310         m_openPanelResultListener = 0;
311     }
312
313     m_geolocationPermissionRequestManager.invalidateRequests();
314
315     m_toolTip = String();
316
317     m_mainFrameHasHorizontalScrollbar = false;
318     m_mainFrameHasVerticalScrollbar = false;
319
320     m_mainFrameIsPinnedToLeftSide = false;
321     m_mainFrameIsPinnedToRightSide = false;
322
323     invalidateCallbackMap(m_voidCallbacks);
324     invalidateCallbackMap(m_dataCallbacks);
325     invalidateCallbackMap(m_stringCallbacks);
326     m_loadDependentStringCallbackIDs.clear();
327     invalidateCallbackMap(m_scriptValueCallbacks);
328     invalidateCallbackMap(m_computedPagesCallbacks);
329
330     Vector<WebEditCommandProxy*> editCommandVector;
331     copyToVector(m_editCommandSet, editCommandVector);
332     m_editCommandSet.clear();
333     for (size_t i = 0, size = editCommandVector.size(); i < size; ++i)
334         editCommandVector[i]->invalidate();
335
336     m_activePopupMenu = 0;
337
338     m_estimatedProgress = 0.0;
339     
340     m_loaderClient.initialize(0);
341     m_policyClient.initialize(0);
342     m_uiClient.initialize(0);
343
344     m_drawingArea.clear();
345
346     process()->send(Messages::WebPage::Close(), m_pageID);
347     process()->removeWebPage(m_pageID);
348 }
349
350 bool WebPageProxy::tryClose()
351 {
352     if (!isValid())
353         return true;
354
355     process()->send(Messages::WebPage::TryClose(), m_pageID);
356     return false;
357 }
358
359 void WebPageProxy::initializeSandboxExtensionHandle(const KURL& url, SandboxExtension::Handle& sandboxExtensionHandle)
360 {
361     if (!url.isLocalFile())
362         return;
363
364     // Don't give the inspector full access to the file system.
365     if (WebInspectorProxy::isInspectorPage(this))
366         return;
367
368     SandboxExtension::createHandle("/", SandboxExtension::ReadOnly, sandboxExtensionHandle);
369 }
370
371 void WebPageProxy::loadURL(const String& url)
372 {
373     setPendingAPIRequestURL(url);
374
375     if (!isValid())
376         reattachToWebProcess();
377
378     SandboxExtension::Handle sandboxExtensionHandle;
379     initializeSandboxExtensionHandle(KURL(KURL(), url), sandboxExtensionHandle);
380     process()->send(Messages::WebPage::LoadURL(url, sandboxExtensionHandle), m_pageID);
381 }
382
383 void WebPageProxy::loadURLRequest(WebURLRequest* urlRequest)
384 {
385     setPendingAPIRequestURL(urlRequest->resourceRequest().url());
386
387     if (!isValid())
388         reattachToWebProcess();
389
390     SandboxExtension::Handle sandboxExtensionHandle;
391     initializeSandboxExtensionHandle(urlRequest->resourceRequest().url(), sandboxExtensionHandle);
392     process()->send(Messages::WebPage::LoadURLRequest(urlRequest->resourceRequest(), sandboxExtensionHandle), m_pageID);
393 }
394
395 void WebPageProxy::loadHTMLString(const String& htmlString, const String& baseURL)
396 {
397     if (!isValid())
398         reattachToWebProcess();
399
400     process()->send(Messages::WebPage::LoadHTMLString(htmlString, baseURL), m_pageID);
401 }
402
403 void WebPageProxy::loadAlternateHTMLString(const String& htmlString, const String& baseURL, const String& unreachableURL)
404 {
405     if (!isValid())
406         reattachToWebProcess();
407
408     if (m_mainFrame)
409         m_mainFrame->setUnreachableURL(unreachableURL);
410
411     process()->send(Messages::WebPage::LoadAlternateHTMLString(htmlString, baseURL, unreachableURL), m_pageID);
412 }
413
414 void WebPageProxy::loadPlainTextString(const String& string)
415 {
416     if (!isValid())
417         reattachToWebProcess();
418
419     process()->send(Messages::WebPage::LoadPlainTextString(string), m_pageID);
420 }
421
422 void WebPageProxy::stopLoading()
423 {
424     if (!isValid())
425         return;
426     process()->send(Messages::WebPage::StopLoading(), m_pageID);
427 }
428
429 void WebPageProxy::reload(bool reloadFromOrigin)
430 {
431     if (m_backForwardList->currentItem())
432         setPendingAPIRequestURL(m_backForwardList->currentItem()->url());
433
434     if (!isValid()) {
435         reattachToWebProcessWithItem(m_backForwardList->currentItem());
436         return;
437     }
438
439     process()->send(Messages::WebPage::Reload(reloadFromOrigin), m_pageID);
440 }
441
442 void WebPageProxy::goForward()
443 {
444     if (isValid() && !canGoForward())
445         return;
446
447     WebBackForwardListItem* forwardItem = m_backForwardList->forwardItem();
448     if (forwardItem)
449         setPendingAPIRequestURL(forwardItem->url());
450
451     if (!isValid()) {
452         reattachToWebProcessWithItem(forwardItem);
453         return;
454     }
455
456     SandboxExtension::Handle sandboxExtensionHandle;
457     initializeSandboxExtensionHandle(KURL(KURL(), forwardItem->url()), sandboxExtensionHandle);
458     process()->send(Messages::WebPage::GoForward(forwardItem->itemID(), sandboxExtensionHandle), m_pageID);
459 }
460
461 bool WebPageProxy::canGoForward() const
462 {
463     return m_backForwardList->forwardItem();
464 }
465
466 void WebPageProxy::goBack()
467 {
468     if (isValid() && !canGoBack())
469         return;
470
471     WebBackForwardListItem* backItem = m_backForwardList->backItem();
472     if (backItem)
473         setPendingAPIRequestURL(backItem->url());
474
475     if (!isValid()) {
476         reattachToWebProcessWithItem(backItem);
477         return;
478     }
479
480     SandboxExtension::Handle sandboxExtensionHandle;
481     initializeSandboxExtensionHandle(KURL(KURL(), backItem->url()), sandboxExtensionHandle);
482     process()->send(Messages::WebPage::GoBack(backItem->itemID(), sandboxExtensionHandle), m_pageID);
483 }
484
485 bool WebPageProxy::canGoBack() const
486 {
487     return m_backForwardList->backItem();
488 }
489
490 void WebPageProxy::goToBackForwardItem(WebBackForwardListItem* item)
491 {
492     if (!isValid()) {
493         reattachToWebProcessWithItem(item);
494         return;
495     }
496     
497     setPendingAPIRequestURL(item->url());
498
499     SandboxExtension::Handle sandboxExtensionHandle;
500     initializeSandboxExtensionHandle(KURL(KURL(), item->url()), sandboxExtensionHandle);
501     process()->send(Messages::WebPage::GoToBackForwardItem(item->itemID(), sandboxExtensionHandle), m_pageID);
502 }
503
504 void WebPageProxy::didChangeBackForwardList(WebBackForwardListItem* added, Vector<RefPtr<APIObject> >* removed)
505 {
506     m_loaderClient.didChangeBackForwardList(this, added, removed);
507 }
508
509 void WebPageProxy::shouldGoToBackForwardListItem(uint64_t itemID, bool& shouldGoToBackForwardItem)
510 {
511     WebBackForwardListItem* item = process()->webBackForwardItem(itemID);
512     shouldGoToBackForwardItem = item && m_loaderClient.shouldGoToBackForwardListItem(this, item);
513 }
514     
515 bool WebPageProxy::canShowMIMEType(const String& mimeType) const
516 {
517     if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType))
518         return true;
519
520     if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType))
521         return true;
522
523     if (mimeType.startsWith("text/", false))
524         return !MIMETypeRegistry::isUnsupportedTextMIMEType(mimeType);
525
526     String newMimeType = mimeType;
527     PluginInfoStore::Plugin plugin = context()->pluginInfoStore()->findPlugin(newMimeType, KURL());
528     if (!plugin.path.isNull())
529         return true;
530
531     return false;
532 }
533
534 void WebPageProxy::setDrawsBackground(bool drawsBackground)
535 {
536     if (m_drawsBackground == drawsBackground)
537         return;
538
539     m_drawsBackground = drawsBackground;
540
541     if (isValid())
542         process()->send(Messages::WebPage::SetDrawsBackground(drawsBackground), m_pageID);
543 }
544
545 void WebPageProxy::setDrawsTransparentBackground(bool drawsTransparentBackground)
546 {
547     if (m_drawsTransparentBackground == drawsTransparentBackground)
548         return;
549
550     m_drawsTransparentBackground = drawsTransparentBackground;
551
552     if (isValid())
553         process()->send(Messages::WebPage::SetDrawsTransparentBackground(drawsTransparentBackground), m_pageID);
554 }
555
556 void WebPageProxy::viewWillStartLiveResize()
557 {
558     if (!isValid())
559         return;
560     process()->send(Messages::WebPage::ViewWillStartLiveResize(), m_pageID);
561 }
562
563 void WebPageProxy::viewWillEndLiveResize()
564 {
565     if (!isValid())
566         return;
567     process()->send(Messages::WebPage::ViewWillEndLiveResize(), m_pageID);
568 }
569
570 void WebPageProxy::setViewNeedsDisplay(const IntRect& rect)
571 {
572     m_pageClient->setViewNeedsDisplay(rect);
573 }
574
575 void WebPageProxy::displayView()
576 {
577     m_pageClient->displayView();
578 }
579
580 void WebPageProxy::scrollView(const IntRect& scrollRect, const IntSize& scrollOffset)
581 {
582     m_pageClient->scrollView(scrollRect, scrollOffset);
583 }
584
585 void WebPageProxy::viewStateDidChange(ViewStateFlags flags)
586 {
587     if (!isValid())
588         return;
589
590     if (flags & ViewIsFocused)
591         process()->send(Messages::WebPage::SetFocused(m_pageClient->isViewFocused()), m_pageID);
592
593     if (flags & ViewWindowIsActive)
594         process()->send(Messages::WebPage::SetActive(m_pageClient->isViewWindowActive()), m_pageID);
595
596     if (flags & ViewIsVisible) {
597         bool isVisible = m_pageClient->isViewVisible();
598         if (isVisible != m_isVisible) {
599             m_isVisible = isVisible;
600             m_drawingArea->visibilityDidChange();
601             m_drawingArea->setPageIsVisible(isVisible);
602         }
603     }
604
605     if (flags & ViewIsInWindow) {
606         bool isInWindow = m_pageClient->isViewInWindow();
607         if (m_isInWindow != isInWindow) {
608             m_isInWindow = isInWindow;
609             process()->send(Messages::WebPage::SetIsInWindow(isInWindow), m_pageID);
610         }
611     }
612
613     if (flags & (ViewWindowIsActive | ViewIsVisible))
614         m_drawingArea->setBackingStoreIsDiscardable(!m_pageClient->isViewWindowActive() || !isViewVisible());
615 }
616
617 IntSize WebPageProxy::viewSize() const
618 {
619     return m_pageClient->viewSize();
620 }
621
622 void WebPageProxy::setInitialFocus(bool forward)
623 {
624     if (!isValid())
625         return;
626     process()->send(Messages::WebPage::SetInitialFocus(forward), m_pageID);
627 }
628
629 void WebPageProxy::setWindowResizerSize(const IntSize& windowResizerSize)
630 {
631     if (!isValid())
632         return;
633     process()->send(Messages::WebPage::SetWindowResizerSize(windowResizerSize), m_pageID);
634 }
635
636 void WebPageProxy::validateCommand(const String& commandName, PassRefPtr<ValidateCommandCallback> callback)
637 {
638     if (!isValid()) {
639         callback->invalidate();
640         return;
641     }
642
643     uint64_t callbackID = callback->callbackID();
644     m_validateCommandCallbacks.set(callbackID, callback.get());
645     process()->send(Messages::WebPage::ValidateCommand(commandName, callbackID), m_pageID);
646 }
647     
648 void WebPageProxy::executeEditCommand(const String& commandName)
649 {
650     if (!isValid())
651         return;
652
653     process()->send(Messages::WebPage::ExecuteEditCommand(commandName), m_pageID);
654 }
655     
656 #if PLATFORM(WIN)
657 WebCore::IntRect WebPageProxy::firstRectForCharacterInSelectedRange(int characterPosition)
658 {
659     IntRect resultRect;
660     process()->sendSync(Messages::WebPage::FirstRectForCharacterInSelectedRange(characterPosition), Messages::WebPage::FirstRectForCharacterInSelectedRange::Reply(resultRect), m_pageID);
661     return resultRect;
662 }
663
664 String WebPageProxy::getSelectedText()
665 {
666     String text;
667     process()->sendSync(Messages::WebPage::GetSelectedText(), Messages::WebPage::GetSelectedText::Reply(text), m_pageID);
668     return text;
669 }
670
671 bool WebPageProxy::gestureWillBegin(const IntPoint& point)
672 {
673     bool canBeginPanning = false;
674     process()->sendSync(Messages::WebPage::GestureWillBegin(point), Messages::WebPage::GestureWillBegin::Reply(canBeginPanning), m_pageID);
675     return canBeginPanning;
676 }
677
678 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() == ContextMenuItemTagShowSpellingPanel) {
2306         TextChecker::toggleSpellingUIIsShowing();
2307         return;
2308     }
2309     if (item.action() == ContextMenuItemTagLearnSpelling || item.action() == ContextMenuItemTagIgnoreSpelling)
2310         ++m_pendingLearnOrIgnoreWordMessageCount;
2311
2312     process()->send(Messages::WebPage::DidSelectItemFromActiveContextMenu(item), m_pageID);
2313 }
2314
2315 void WebPageProxy::didChooseFilesForOpenPanel(const Vector<String>& fileURLs)
2316 {
2317     if (!isValid())
2318         return;
2319
2320 #if ENABLE(WEB_PROCESS_SANDBOX)
2321     // FIXME: The sandbox extensions should be sent with the DidChooseFilesForOpenPanel message. This
2322     // is gated on a way of passing SandboxExtension::Handles in a Vector.
2323     for (size_t i = 0; i < fileURLs.size(); ++i) {
2324         SandboxExtension::Handle sandboxExtensionHandle;
2325         SandboxExtension::createHandle(fileURLs[i], SandboxExtension::ReadOnly, sandboxExtensionHandle);
2326         process()->send(Messages::WebPage::ExtendSandboxForFileFromOpenPanel(sandboxExtensionHandle), m_pageID);
2327     }
2328 #endif
2329
2330     process()->send(Messages::WebPage::DidChooseFilesForOpenPanel(fileURLs), m_pageID);
2331
2332     m_openPanelResultListener->invalidate();
2333     m_openPanelResultListener = 0;
2334 }
2335
2336 void WebPageProxy::didCancelForOpenPanel()
2337 {
2338     if (!isValid())
2339         return;
2340
2341     process()->send(Messages::WebPage::DidCancelForOpenPanel(), m_pageID);
2342     
2343     m_openPanelResultListener->invalidate();
2344     m_openPanelResultListener = 0;
2345 }
2346
2347 void WebPageProxy::advanceToNextMisspelling(bool startBeforeSelection)
2348 {
2349     process()->send(Messages::WebPage::AdvanceToNextMisspelling(startBeforeSelection), m_pageID);
2350 }
2351
2352 void WebPageProxy::changeSpellingToWord(const String& word)
2353 {
2354     if (word.isEmpty())
2355         return;
2356
2357     process()->send(Messages::WebPage::ChangeSpellingToWord(word), m_pageID);
2358 }
2359
2360 void WebPageProxy::unmarkAllMisspellings()
2361 {
2362     process()->send(Messages::WebPage::UnmarkAllMisspellings(), m_pageID);
2363 }
2364
2365 void WebPageProxy::unmarkAllBadGrammar()
2366 {
2367     process()->send(Messages::WebPage::UnmarkAllBadGrammar(), m_pageID);
2368 }
2369
2370 void WebPageProxy::registerEditCommand(PassRefPtr<WebEditCommandProxy> commandProxy, UndoOrRedo undoOrRedo)
2371 {
2372     m_pageClient->registerEditCommand(commandProxy, undoOrRedo);
2373 }
2374
2375 void WebPageProxy::addEditCommand(WebEditCommandProxy* command)
2376 {
2377     m_editCommandSet.add(command);
2378 }
2379
2380 void WebPageProxy::removeEditCommand(WebEditCommandProxy* command)
2381 {
2382     m_editCommandSet.remove(command);
2383
2384     if (!isValid())
2385         return;
2386     process()->send(Messages::WebPage::DidRemoveEditCommand(command->commandID()), m_pageID);
2387 }
2388
2389 bool WebPageProxy::isValidEditCommand(WebEditCommandProxy* command)
2390 {
2391     return m_editCommandSet.find(command) != m_editCommandSet.end();
2392 }
2393
2394 int64_t WebPageProxy::spellDocumentTag()
2395 {
2396     if (!m_hasSpellDocumentTag) {
2397         m_spellDocumentTag = TextChecker::uniqueSpellDocumentTag();
2398         m_hasSpellDocumentTag = true;
2399     }
2400
2401     return m_spellDocumentTag;
2402 }
2403
2404 #if USE(UNIFIED_TEXT_CHECKING)
2405
2406 void WebPageProxy::checkTextOfParagraph(const String& text, uint64_t checkingTypes, Vector<TextCheckingResult>& results)
2407 {
2408     results = TextChecker::checkTextOfParagraph(spellDocumentTag(), text.characters(), text.length(), checkingTypes);
2409 }
2410
2411 #endif
2412
2413 void WebPageProxy::checkSpellingOfString(const String& text, int32_t& misspellingLocation, int32_t& misspellingLength)
2414 {
2415     TextChecker::checkSpellingOfString(spellDocumentTag(), text.characters(), text.length(), misspellingLocation, misspellingLength);
2416 }
2417
2418 void WebPageProxy::checkGrammarOfString(const String& text, Vector<WebCore::GrammarDetail>& grammarDetails, int32_t& badGrammarLocation, int32_t& badGrammarLength)
2419 {
2420     TextChecker::checkGrammarOfString(spellDocumentTag(), text.characters(), text.length(), grammarDetails, badGrammarLocation, badGrammarLength);
2421 }
2422
2423 void WebPageProxy::spellingUIIsShowing(bool& isShowing)
2424 {
2425     isShowing = TextChecker::spellingUIIsShowing();
2426 }
2427
2428 void WebPageProxy::updateSpellingUIWithMisspelledWord(const String& misspelledWord)
2429 {
2430     TextChecker::updateSpellingUIWithMisspelledWord(misspelledWord);
2431 }
2432
2433 void WebPageProxy::updateSpellingUIWithGrammarString(const String& badGrammarPhrase, const GrammarDetail& grammarDetail)
2434 {
2435     TextChecker::updateSpellingUIWithGrammarString(badGrammarPhrase, grammarDetail);
2436 }
2437
2438 void WebPageProxy::getGuessesForWord(const String& word, const String& context, Vector<String>& guesses)
2439 {
2440     TextChecker::getGuessesForWord(spellDocumentTag(), word, context, guesses);
2441 }
2442
2443 void WebPageProxy::learnWord(const String& word)
2444 {
2445     MESSAGE_CHECK(m_pendingLearnOrIgnoreWordMessageCount);
2446     --m_pendingLearnOrIgnoreWordMessageCount;
2447
2448     TextChecker::learnWord(word);
2449 }
2450
2451 void WebPageProxy::ignoreWord(const String& word)
2452 {
2453     MESSAGE_CHECK(m_pendingLearnOrIgnoreWordMessageCount);
2454     --m_pendingLearnOrIgnoreWordMessageCount;
2455
2456     TextChecker::ignoreWord(spellDocumentTag(), word);
2457 }
2458
2459 // Other
2460
2461 void WebPageProxy::setFocus(bool focused)
2462 {
2463     m_pageClient->setFocus(focused);
2464 }
2465
2466 void WebPageProxy::takeFocus(bool direction)
2467 {
2468     m_pageClient->takeFocus(direction);
2469 }
2470
2471 void WebPageProxy::setToolTip(const String& toolTip)
2472 {
2473     String oldToolTip = m_toolTip;
2474     m_toolTip = toolTip;
2475     m_pageClient->toolTipChanged(oldToolTip, m_toolTip);
2476 }
2477
2478 void WebPageProxy::setCursor(const WebCore::Cursor& cursor)
2479 {
2480     m_pageClient->setCursor(cursor);
2481 }
2482
2483 void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled)
2484 {
2485     WebEvent::Type type = static_cast<WebEvent::Type>(opaqueType);
2486
2487     switch (type) {
2488     case WebEvent::NoType:
2489     case WebEvent::MouseMove:
2490         break;
2491
2492     case WebEvent::MouseDown:
2493     case WebEvent::MouseUp:
2494     case WebEvent::Wheel:
2495     case WebEvent::KeyDown:
2496     case WebEvent::KeyUp:
2497     case WebEvent::RawKeyDown:
2498     case WebEvent::Char:
2499 #if ENABLE(GESTURE_EVENTS)
2500     case WebEvent::GestureScrollBegin:
2501     case WebEvent::GestureScrollEnd:
2502 #endif
2503         process()->responsivenessTimer()->stop();
2504         break;
2505     }
2506
2507     switch (type) {
2508     case WebEvent::NoType:
2509         break;
2510     case WebEvent::MouseMove:
2511         m_processingMouseMoveEvent = false;
2512         if (m_nextMouseMoveEvent) {
2513             handleMouseEvent(*m_nextMouseMoveEvent);
2514             m_nextMouseMoveEvent = nullptr;
2515         }
2516         break;
2517     case WebEvent::MouseDown:
2518     case WebEvent::MouseUp:
2519 #if ENABLE(GESTURE_EVENTS)
2520     case WebEvent::GestureScrollBegin:
2521     case WebEvent::GestureScrollEnd:
2522 #endif
2523         break;
2524
2525     case WebEvent::Wheel: {
2526         m_processingWheelEvent = false;
2527         if (m_nextWheelEvent) {
2528             handleWheelEvent(*m_nextWheelEvent);
2529             m_nextWheelEvent = nullptr;
2530         }
2531         break;
2532     }
2533
2534     case WebEvent::KeyDown:
2535     case WebEvent::KeyUp:
2536     case WebEvent::RawKeyDown:
2537     case WebEvent::Char: {
2538         NativeWebKeyboardEvent event = m_keyEventQueue.first();
2539         MESSAGE_CHECK(type == event.type());
2540
2541         m_keyEventQueue.removeFirst();
2542
2543         m_pageClient->doneWithKeyEvent(event, handled);
2544
2545         if (handled)
2546             break;
2547
2548         m_uiClient.didNotHandleKeyEvent(this, event);
2549         break;
2550     }
2551     }
2552 }
2553
2554 void WebPageProxy::voidCallback(uint64_t callbackID)
2555 {
2556     RefPtr<VoidCallback> callback = m_voidCallbacks.take(callbackID);
2557     if (!callback) {
2558         // FIXME: Log error or assert.
2559         return;
2560     }
2561
2562     callback->performCallback();
2563 }
2564
2565 void WebPageProxy::dataCallback(const CoreIPC::DataReference& dataReference, uint64_t callbackID)
2566 {
2567     RefPtr<DataCallback> callback = m_dataCallbacks.take(callbackID);
2568     if (!callback) {
2569         // FIXME: Log error or assert.
2570         return;
2571     }
2572
2573     callback->performCallbackWithReturnValue(WebData::create(dataReference.data(), dataReference.size()).get());
2574 }
2575
2576 void WebPageProxy::stringCallback(const String& resultString, uint64_t callbackID)
2577 {
2578     RefPtr<StringCallback> callback = m_stringCallbacks.take(callbackID);
2579     if (!callback) {
2580         // FIXME: Log error or assert.
2581         // this can validly happen if a load invalidated the callback, though
2582         return;
2583     }
2584
2585     m_loadDependentStringCallbackIDs.remove(callbackID);
2586
2587     callback->performCallbackWithReturnValue(resultString.impl());
2588 }
2589
2590 void WebPageProxy::scriptValueCallback(const CoreIPC::DataReference& dataReference, uint64_t callbackID)
2591 {
2592     RefPtr<ScriptValueCallback> callback = m_scriptValueCallbacks.take(callbackID);
2593     if (!callback) {
2594         // FIXME: Log error or assert.
2595         return;
2596     }
2597
2598     Vector<uint8_t> data;
2599     data.reserveInitialCapacity(dataReference.size());
2600     data.append(dataReference.data(), dataReference.size());
2601
2602     callback->performCallbackWithReturnValue(data.size() ? WebSerializedScriptValue::adopt(data).get() : 0);
2603 }
2604
2605 void WebPageProxy::computedPagesCallback(const Vector<WebCore::IntRect>& pageRects, double totalScaleFactorForPrinting, uint64_t callbackID)
2606 {
2607     RefPtr<ComputedPagesCallback> callback = m_computedPagesCallbacks.take(callbackID);
2608     if (!callback) {
2609         // FIXME: Log error or assert.
2610         return;
2611     }
2612
2613     callback->performCallbackWithReturnValue(pageRects, totalScaleFactorForPrinting);
2614 }
2615
2616 void WebPageProxy::validateCommandCallback(const String& commandName, bool isEnabled, int state, uint64_t callbackID)
2617 {
2618     RefPtr<ValidateCommandCallback> callback = m_validateCommandCallbacks.take(callbackID);
2619     if (!callback) {
2620         // FIXME: Log error or assert.
2621         return;
2622     }
2623
2624     callback->performCallbackWithReturnValue(commandName.impl(), isEnabled, state);
2625 }
2626
2627 void WebPageProxy::focusedFrameChanged(uint64_t frameID)
2628 {
2629     if (!frameID) {
2630         m_focusedFrame = 0;
2631         return;
2632     }
2633
2634     WebFrameProxy* frame = process()->webFrame(frameID);
2635     MESSAGE_CHECK(frame);
2636
2637     m_focusedFrame = frame;
2638 }
2639
2640 void WebPageProxy::frameSetLargestFrameChanged(uint64_t frameID)
2641 {
2642     if (!frameID) {
2643         m_frameSetLargestFrame = 0;
2644         return;
2645     }
2646
2647     WebFrameProxy* frame = process()->webFrame(frameID);
2648     MESSAGE_CHECK(frame);
2649
2650     m_frameSetLargestFrame = frame;
2651 }
2652
2653 void WebPageProxy::processDidBecomeUnresponsive()
2654 {
2655     m_loaderClient.processDidBecomeUnresponsive(this);
2656 }
2657
2658 void WebPageProxy::processDidBecomeResponsive()
2659 {
2660     m_loaderClient.processDidBecomeResponsive(this);
2661 }
2662
2663 void WebPageProxy::processDidCrash()
2664 {
2665     ASSERT(m_pageClient);
2666
2667     m_isValid = false;
2668
2669     if (m_mainFrame)
2670         m_urlAtProcessExit = m_mainFrame->url();
2671
2672     m_mainFrame = 0;
2673
2674     m_drawingArea = nullptr;
2675
2676 #if ENABLE(INSPECTOR)
2677     if (m_inspector) {
2678         m_inspector->invalidate();
2679         m_inspector = 0;
2680     }
2681 #endif
2682
2683 #if ENABLE(FULLSCREEN_API)
2684     if (m_fullScreenManager) {
2685         m_fullScreenManager->invalidate();
2686         m_fullScreenManager = 0;
2687     }
2688 #endif
2689
2690     if (m_openPanelResultListener) {
2691         m_openPanelResultListener->invalidate();
2692         m_openPanelResultListener = 0;
2693     }
2694
2695     m_geolocationPermissionRequestManager.invalidateRequests();
2696
2697     m_toolTip = String();
2698
2699     m_mainFrameHasHorizontalScrollbar = false;
2700     m_mainFrameHasVerticalScrollbar = false;
2701
2702     m_mainFrameIsPinnedToLeftSide = false;
2703     m_mainFrameIsPinnedToRightSide = false;
2704
2705     invalidateCallbackMap(m_voidCallbacks);
2706     invalidateCallbackMap(m_dataCallbacks);
2707     invalidateCallbackMap(m_stringCallbacks);
2708     m_loadDependentStringCallbackIDs.clear();
2709     invalidateCallbackMap(m_scriptValueCallbacks);
2710     invalidateCallbackMap(m_computedPagesCallbacks);
2711     invalidateCallbackMap(m_validateCommandCallbacks);
2712
2713     Vector<WebEditCommandProxy*> editCommandVector;
2714     copyToVector(m_editCommandSet, editCommandVector);
2715     m_editCommandSet.clear();
2716     for (size_t i = 0, size = editCommandVector.size(); i < size; ++i)
2717         editCommandVector[i]->invalidate();
2718     m_pageClient->clearAllEditCommands();
2719
2720     m_activePopupMenu = 0;
2721
2722     m_estimatedProgress = 0.0;
2723
2724     m_pendingLearnOrIgnoreWordMessageCount = 0;
2725
2726     m_pageClient->processDidCrash();
2727     m_loaderClient.processDidCrash(this);
2728
2729     // Can't expect DidReceiveEvent notifications from a crashed web process.
2730     m_keyEventQueue.clear();
2731 }
2732
2733 WebPageCreationParameters WebPageProxy::creationParameters() const
2734 {
2735     WebPageCreationParameters parameters;
2736
2737     parameters.viewSize = m_pageClient->viewSize();
2738     parameters.isActive = m_pageClient->isViewWindowActive();
2739     parameters.isFocused = m_pageClient->isViewFocused();
2740     parameters.isVisible = m_pageClient->isViewVisible();
2741     parameters.isInWindow = m_pageClient->isViewInWindow();
2742     parameters.drawingAreaType = m_drawingArea->type();
2743     parameters.store = m_pageGroup->preferences()->store();
2744     parameters.pageGroupData = m_pageGroup->data();
2745     parameters.drawsBackground = m_drawsBackground;
2746     parameters.drawsTransparentBackground = m_drawsTransparentBackground;
2747     parameters.areMemoryCacheClientCallsEnabled = m_areMemoryCacheClientCallsEnabled;
2748     parameters.useFixedLayout = m_useFixedLayout;
2749     parameters.fixedLayoutSize = m_fixedLayoutSize;
2750     parameters.userAgent = userAgent();
2751     parameters.sessionState = SessionState(m_backForwardList->entries(), m_backForwardList->currentIndex());
2752     parameters.highestUsedBackForwardItemID = WebBackForwardListItem::highedUsedItemID();
2753     parameters.canRunBeforeUnloadConfirmPanel = m_uiClient.canRunBeforeUnloadConfirmPanel();
2754     parameters.canRunModal = m_uiClient.canRunModal();
2755     parameters.userSpaceScaleFactor = m_pageClient->userSpaceScaleFactor();
2756
2757 #if PLATFORM(MAC)
2758     parameters.isSmartInsertDeleteEnabled = m_isSmartInsertDeleteEnabled;
2759 #endif
2760
2761 #if PLATFORM(WIN)
2762     parameters.nativeWindow = m_pageClient->nativeWindow();
2763 #endif
2764
2765     return parameters;
2766 }
2767
2768 #if USE(ACCELERATED_COMPOSITING)
2769 void WebPageProxy::enterAcceleratedCompositingMode(const LayerTreeContext& layerTreeContext)
2770 {
2771     m_pageClient->enterAcceleratedCompositingMode(layerTreeContext);
2772 }
2773
2774 void WebPageProxy::exitAcceleratedCompositingMode()
2775 {
2776     m_pageClient->exitAcceleratedCompositingMode();
2777 }
2778 #endif // USE(ACCELERATED_COMPOSITING)
2779
2780 void WebPageProxy::backForwardClear()
2781 {
2782     m_backForwardList->clear();
2783 }
2784
2785 void WebPageProxy::canAuthenticateAgainstProtectionSpaceInFrame(uint64_t frameID, const WebCore::ProtectionSpace& coreProtectionSpace, bool& canAuthenticate)
2786 {
2787     WebFrameProxy* frame = process()->webFrame(frameID);
2788     MESSAGE_CHECK(frame);
2789
2790     RefPtr<WebProtectionSpace> protectionSpace = WebProtectionSpace::create(coreProtectionSpace);
2791     
2792     canAuthenticate = m_loaderClient.canAuthenticateAgainstProtectionSpaceInFrame(this, frame, protectionSpace.get());
2793 }
2794
2795 void WebPageProxy::didReceiveAuthenticationChallenge(uint64_t frameID, const WebCore::AuthenticationChallenge& coreChallenge, uint64_t challengeID)
2796 {
2797     WebFrameProxy* frame = process()->webFrame(frameID);
2798     MESSAGE_CHECK(frame);
2799
2800     RefPtr<AuthenticationChallengeProxy> authenticationChallenge = AuthenticationChallengeProxy::create(coreChallenge, challengeID, process());
2801     
2802     m_loaderClient.didReceiveAuthenticationChallengeInFrame(this, frame, authenticationChallenge.get());
2803 }
2804
2805 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)
2806 {
2807     WebFrameProxy* frame = process()->webFrame(frameID);
2808     MESSAGE_CHECK(frame);
2809
2810     RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::create(originIdentifier);
2811
2812     newQuota = m_uiClient.exceededDatabaseQuota(this, frame, origin.get(), databaseName, displayName, currentQuota, currentUsage, expectedUsage);
2813 }
2814
2815 void WebPageProxy::requestGeolocationPermissionForFrame(uint64_t geolocationID, uint64_t frameID, String originIdentifier)
2816 {
2817     WebFrameProxy* frame = process()->webFrame(frameID);
2818     MESSAGE_CHECK(frame);
2819
2820     RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::create(originIdentifier);
2821     RefPtr<GeolocationPermissionRequestProxy> request = m_geolocationPermissionRequestManager.createRequest(geolocationID);
2822
2823     if (!m_uiClient.decidePolicyForGeolocationPermissionRequest(this, frame, origin.get(), request.get()))
2824         request->deny();
2825 }
2826
2827 float WebPageProxy::headerHeight(WebFrameProxy* frame)
2828 {
2829     return m_uiClient.headerHeight(this, frame);
2830 }
2831
2832 float WebPageProxy::footerHeight(WebFrameProxy* frame)
2833 {
2834     return m_uiClient.footerHeight(this, frame);
2835 }
2836
2837 void WebPageProxy::drawHeader(WebFrameProxy* frame, const FloatRect& rect)
2838 {
2839     m_uiClient.drawHeader(this, frame, rect);
2840 }
2841
2842 void WebPageProxy::drawFooter(WebFrameProxy* frame, const FloatRect& rect)
2843 {
2844     m_uiClient.drawFooter(this, frame, rect);
2845 }
2846
2847 void WebPageProxy::didCompleteRubberBandForMainFrame(const IntSize& initialOverhang)
2848 {
2849     m_uiClient.didCompleteRubberBandForMainFrame(this, initialOverhang);
2850 }
2851
2852 void WebPageProxy::didChangeScrollbarsForMainFrame(bool hasHorizontalScrollbar, bool hasVerticalScrollbar)
2853 {
2854     m_mainFrameHasHorizontalScrollbar = hasHorizontalScrollbar;
2855     m_mainFrameHasVerticalScrollbar = hasVerticalScrollbar;
2856
2857     m_pageClient->didChangeScrollbarsForMainFrame();
2858 }
2859
2860 void WebPageProxy::didChangeScrollOffsetPinningForMainFrame(bool pinnedToLeftSide, bool pinnedToRightSide)
2861 {
2862     m_mainFrameIsPinnedToLeftSide = pinnedToLeftSide;
2863     m_mainFrameIsPinnedToRightSide = pinnedToRightSide;
2864 }
2865
2866 void WebPageProxy::didFinishLoadingDataForCustomRepresentation(const String& suggestedFilename, const CoreIPC::DataReference& dataReference)
2867 {
2868     m_pageClient->didFinishLoadingDataForCustomRepresentation(suggestedFilename, dataReference);
2869 }
2870
2871 void WebPageProxy::backForwardRemovedItem(uint64_t itemID)
2872 {
2873     process()->send(Messages::WebPage::DidRemoveBackForwardItem(itemID), m_pageID);
2874 }
2875
2876 void WebPageProxy::beginPrinting(WebFrameProxy* frame, const PrintInfo& printInfo)
2877 {
2878     if (m_isInPrintingMode)
2879         return;
2880
2881     m_isInPrintingMode = true;
2882     process()->send(Messages::WebPage::BeginPrinting(frame->frameID(), printInfo), m_pageID, m_isPerformingDOMPrintOperation ? CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply : 0);
2883 }
2884
2885 void WebPageProxy::endPrinting()
2886 {
2887     if (!m_isInPrintingMode)
2888         return;
2889
2890     m_isInPrintingMode = false;
2891     process()->send(Messages::WebPage::EndPrinting(), m_pageID, m_isPerformingDOMPrintOperation ? CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply : 0);
2892 }
2893
2894 void WebPageProxy::computePagesForPrinting(WebFrameProxy* frame, const PrintInfo& printInfo, PassRefPtr<ComputedPagesCallback> prpCallback)
2895 {
2896     RefPtr<ComputedPagesCallback> callback = prpCallback;
2897     if (!isValid()) {
2898         callback->invalidate();
2899         return;
2900     }
2901
2902     uint64_t callbackID = callback->callbackID();
2903     m_computedPagesCallbacks.set(callbackID, callback.get());
2904     m_isInPrintingMode = true;
2905     process()->send(Messages::WebPage::ComputePagesForPrinting(frame->frameID(), printInfo, callbackID), m_pageID, m_isPerformingDOMPrintOperation ? CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply : 0);
2906 }
2907
2908 #if PLATFORM(MAC) || PLATFORM(WIN)
2909 void WebPageProxy::drawRectToPDF(WebFrameProxy* frame, const IntRect& rect, PassRefPtr<DataCallback> prpCallback)
2910 {
2911     RefPtr<DataCallback> callback = prpCallback;
2912     if (!isValid()) {
2913         callback->invalidate();
2914         return;
2915     }
2916     
2917     uint64_t callbackID = callback->callbackID();
2918     m_dataCallbacks.set(callbackID, callback.get());
2919     process()->send(Messages::WebPage::DrawRectToPDF(frame->frameID(), rect, callbackID), m_pageID, m_isPerformingDOMPrintOperation ? CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply : 0);
2920 }
2921
2922 void WebPageProxy::drawPagesToPDF(WebFrameProxy* frame, uint32_t first, uint32_t count, PassRefPtr<DataCallback> prpCallback)
2923 {
2924     RefPtr<DataCallback> callback = prpCallback;
2925     if (!isValid()) {
2926         callback->invalidate();
2927         return;
2928     }
2929     
2930     uint64_t callbackID = callback->callbackID();
2931     m_dataCallbacks.set(callbackID, callback.get());
2932     process()->send(Messages::WebPage::DrawPagesToPDF(frame->frameID(), first, count, callbackID), m_pageID, m_isPerformingDOMPrintOperation ? CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply : 0);
2933 }
2934 #endif
2935
2936 void WebPageProxy::flashBackingStoreUpdates(const Vector<IntRect>& updateRects)
2937 {
2938     m_pageClient->flashBackingStoreUpdates(updateRects);
2939 }
2940
2941 Color WebPageProxy::viewUpdatesFlashColor()
2942 {
2943     return Color(0, 200, 255);
2944 }
2945
2946 Color WebPageProxy::backingStoreUpdatesFlashColor()
2947 {
2948     return Color(200, 0, 255);
2949 }
2950
2951 void WebPageProxy::saveDataToFileInDownloadsFolder(const String& suggestedFilename, const String& mimeType, const String& originatingURLString, WebData* data)
2952 {
2953     m_uiClient.saveDataToFileInDownloadsFolder(this, suggestedFilename, mimeType, originatingURLString, data);
2954 }
2955
2956 void WebPageProxy::linkClicked(const String& url, const WebMouseEvent& event)
2957 {
2958     process()->send(Messages::WebPage::LinkClicked(url, event), m_pageID, 0);
2959 }
2960
2961 #if PLATFORM(MAC) && !defined(BUILDING_ON_SNOW_LEOPARD)
2962 void WebPageProxy::showCorrectionPanel(int32_t panelType, const WebCore::FloatRect& boundingBoxOfReplacedString, const String& replacedString, const String& replacementString, const Vector<String>& alternativeReplacementStrings)
2963 {
2964     m_pageClient->showCorrectionPanel((WebCore::CorrectionPanelInfo::PanelType)panelType, boundingBoxOfReplacedString, replacedString, replacementString, alternativeReplacementStrings);
2965 }
2966
2967 void WebPageProxy::dismissCorrectionPanel(int32_t reason)
2968 {
2969     m_pageClient->dismissCorrectionPanel((WebCore::ReasonForDismissingCorrectionPanel)reason);
2970 }
2971
2972 void WebPageProxy::dismissCorrectionPanelSoon(int32_t reason, String& result)
2973 {
2974     result = m_pageClient->dismissCorrectionPanelSoon((WebCore::ReasonForDismissingCorrectionPanel)reason);
2975 }
2976
2977 void WebPageProxy::recordAutocorrectionResponse(int32_t responseType, const String& replacedString, const String& replacementString)
2978 {
2979     m_pageClient->recordAutocorrectionResponse((WebCore::EditorClient::AutocorrectionResponseType)responseType, replacedString, replacementString);
2980 }
2981 #endif
2982
2983 #if PLATFORM(MAC)
2984 void WebPageProxy::handleCorrectionPanelResult(const String& result)
2985 {
2986 #if !defined(BUILDING_ON_SNOW_LEOPARD)
2987     if (!isClosed())
2988         process()->send(Messages::WebPage::HandleCorrectionPanelResult(result), m_pageID, 0);
2989 #endif
2990 }
2991 #endif
2992
2993 } // namespace WebKit