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