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