2011-01-18 Maciej Stachowiak <mjs@apple.com>
[WebKit.git] / Source / WebKit2 / UIProcess / WebPageProxy.cpp
1 /*
2  * Copyright (C) 2010 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->setPageIsVisible(isVisible);
501         }
502     }
503
504     if (flags & ViewIsInWindow) {
505         bool isInWindow = m_pageClient->isViewInWindow();
506         if (m_isInWindow != isInWindow) {
507             m_isInWindow = isInWindow;
508             process()->send(Messages::WebPage::SetIsInWindow(isInWindow), m_pageID);
509         }
510     }
511 }
512
513 IntSize WebPageProxy::viewSize() const
514 {
515     return m_pageClient->viewSize();
516 }
517
518 void WebPageProxy::setInitialFocus(bool forward)
519 {
520     if (!isValid())
521         return;
522     process()->send(Messages::WebPage::SetInitialFocus(forward), m_pageID);
523 }
524
525 void WebPageProxy::setWindowResizerSize(const IntSize& windowResizerSize)
526 {
527     if (!isValid())
528         return;
529     process()->send(Messages::WebPage::SetWindowResizerSize(windowResizerSize), m_pageID);
530 }
531
532 void WebPageProxy::validateMenuItem(const String& commandName)
533 {
534     if (!isValid())
535         return;
536     process()->send(Messages::WebPage::ValidateMenuItem(commandName), m_pageID);
537 }
538     
539 void WebPageProxy::executeEditCommand(const String& commandName)
540 {
541     if (!isValid())
542         return;
543
544     process()->send(Messages::WebPage::ExecuteEditCommand(commandName), m_pageID);
545 }
546     
547 #if PLATFORM(MAC)
548 void WebPageProxy::updateWindowIsVisible(bool windowIsVisible)
549 {
550     if (!isValid())
551         return;
552     process()->send(Messages::WebPage::SetWindowIsVisible(windowIsVisible), m_pageID);
553 }
554
555 void WebPageProxy::windowAndViewFramesChanged(const IntRect& windowFrameInScreenCoordinates, const IntRect& viewFrameInWindowCoordinates, const IntPoint& accessibilityViewCoordinates)
556 {
557     if (!isValid())
558         return;
559
560     process()->send(Messages::WebPage::WindowAndViewFramesChanged(windowFrameInScreenCoordinates, viewFrameInWindowCoordinates, accessibilityViewCoordinates), m_pageID);
561 }
562
563 void WebPageProxy::getMarkedRange(uint64_t& location, uint64_t& length)
564 {
565     process()->sendSync(Messages::WebPage::GetMarkedRange(), Messages::WebPage::GetMarkedRange::Reply(location, length), m_pageID);
566 }
567     
568 uint64_t WebPageProxy::characterIndexForPoint(const IntPoint point)
569 {
570     uint64_t result;
571     process()->sendSync(Messages::WebPage::CharacterIndexForPoint(point), Messages::WebPage::CharacterIndexForPoint::Reply(result), m_pageID);
572     return result;
573 }
574
575 WebCore::IntRect WebPageProxy::firstRectForCharacterRange(uint64_t location, uint64_t length)
576 {
577     IntRect resultRect;
578     process()->sendSync(Messages::WebPage::FirstRectForCharacterRange(location, length), Messages::WebPage::FirstRectForCharacterRange::Reply(resultRect), m_pageID);
579     return resultRect;
580 }
581 #elif PLATFORM(WIN)
582 WebCore::IntRect WebPageProxy::firstRectForCharacterInSelectedRange(int characterPosition)
583 {
584     IntRect resultRect;
585     process()->sendSync(Messages::WebPage::FirstRectForCharacterInSelectedRange(characterPosition), Messages::WebPage::FirstRectForCharacterInSelectedRange::Reply(resultRect), m_pageID);
586     return resultRect;
587 }
588
589 String WebPageProxy::getSelectedText()
590 {
591     String text;
592     process()->sendSync(Messages::WebPage::GetSelectedText(), Messages::WebPage::GetSelectedText::Reply(text), m_pageID);
593     return text;
594 }
595 #endif
596
597 #if ENABLE(TILED_BACKING_STORE)
598 void WebPageProxy::setActualVisibleContentRect(const IntRect& rect)
599 {
600     if (!isValid())
601         return;
602
603     process()->send(Messages::WebPage::SetActualVisibleContentRect(rect), m_pageID);
604 }
605 #endif
606
607 void WebPageProxy::performDragControllerAction(DragControllerAction action, WebCore::DragData* dragData, const String& dragStorageName)
608 {
609     if (!isValid())
610         return;
611     process()->send(Messages::WebPage::PerformDragControllerAction(action, dragData->clientPosition(), dragData->globalPosition(), dragData->draggingSourceOperationMask(), dragStorageName, dragData->flags()), m_pageID);
612 }
613
614 void WebPageProxy::didPerformDragControllerAction(uint64_t resultOperation)
615 {
616     m_currentDragOperation = static_cast<DragOperation>(resultOperation);
617 }
618
619 void WebPageProxy::handleMouseEvent(const WebMouseEvent& event)
620 {
621     if (!isValid())
622         return;
623
624     // NOTE: This does not start the responsiveness timer because mouse move should not indicate interaction.
625     if (event.type() != WebEvent::MouseMove)
626         process()->responsivenessTimer()->start();
627     else {
628         if (m_processingMouseMoveEvent) {
629             m_nextMouseMoveEvent = adoptPtr(new WebMouseEvent(event));
630             return;
631         }
632
633         m_processingMouseMoveEvent = true;
634     }
635
636     process()->send(Messages::WebPage::MouseEvent(event), m_pageID);
637 }
638
639 static PassOwnPtr<WebWheelEvent> coalesceWheelEvents(WebWheelEvent* oldNextWheelEvent, const WebWheelEvent& newWheelEvent)
640 {
641 #if MERGE_WHEEL_EVENTS
642     // Merge model: Combine wheel event deltas (and wheel ticks) into a single wheel event.
643     if (!oldNextWheelEvent)
644         return adoptPtr(new WebWheelEvent(newWheelEvent));
645
646     if (oldNextWheelEvent->position() != newWheelEvent.position() || oldNextWheelEvent->modifiers() != newWheelEvent.modifiers() || oldNextWheelEvent->granularity() != newWheelEvent.granularity())
647         return adoptPtr(new WebWheelEvent(newWheelEvent));
648
649     FloatSize mergedDelta = oldNextWheelEvent->delta() + newWheelEvent.delta();
650     FloatSize mergedWheelTicks = oldNextWheelEvent->wheelTicks() + newWheelEvent.wheelTicks();
651
652     return adoptPtr(new WebWheelEvent(WebEvent::Wheel, newWheelEvent.position(), newWheelEvent.globalPosition(), mergedDelta, mergedWheelTicks, newWheelEvent.granularity(), newWheelEvent.modifiers(), newWheelEvent.timestamp()));
653 #else
654     // Simple model: Just keep the last event, dropping all interim events.
655     return adoptPtr(new WebWheelEvent(newWheelEvent));
656 #endif
657 }
658
659 void WebPageProxy::handleWheelEvent(const WebWheelEvent& event)
660 {
661     if (!isValid())
662         return;
663
664     if (m_processingWheelEvent) {
665         m_nextWheelEvent = coalesceWheelEvents(m_nextWheelEvent.get(), event);
666         return;
667     }
668
669     process()->responsivenessTimer()->start();
670     process()->send(Messages::WebPage::WheelEvent(event), m_pageID);
671     m_processingWheelEvent = true;
672 }
673
674 void WebPageProxy::handleKeyboardEvent(const NativeWebKeyboardEvent& event)
675 {
676     if (!isValid())
677         return;
678
679     m_keyEventQueue.append(event);
680
681     process()->responsivenessTimer()->start();
682     process()->send(Messages::WebPage::KeyEvent(event), m_pageID);
683 }
684
685 #if ENABLE(TOUCH_EVENTS)
686 void WebPageProxy::handleTouchEvent(const WebTouchEvent& event)
687 {
688     if (!isValid())
689         return;
690     process()->send(Messages::WebPage::TouchEvent(event), m_pageID); 
691 }
692 #endif
693
694 void WebPageProxy::receivedPolicyDecision(PolicyAction action, WebFrameProxy* frame, uint64_t listenerID)
695 {
696     if (!isValid())
697         return;
698
699     uint64_t downloadID = 0;
700     if (action == PolicyDownload) {
701         // Create a download proxy.
702         downloadID = context()->createDownloadProxy();
703     }
704
705     // If we received a policy decision while in decidePolicyForMIMEType the decision will 
706     // be sent back to the web process by decidePolicyForMIMEType. 
707     if (m_inDecidePolicyForMIMEType) {
708         m_syncMimeTypePolicyActionIsValid = true;
709         m_syncMimeTypePolicyAction = action;
710         m_syncMimeTypePolicyDownloadID = downloadID;
711         return;
712     }
713
714     process()->send(Messages::WebPage::DidReceivePolicyDecision(frame->frameID(), listenerID, action, downloadID), m_pageID);
715 }
716
717 String WebPageProxy::pageTitle() const
718 {
719     // Return the null string if there is no main frame (e.g. nothing has been loaded in the page yet, WebProcess has
720     // crashed, page has been closed).
721     if (!m_mainFrame)
722         return String();
723
724     return m_mainFrame->title();
725 }
726
727 void WebPageProxy::setUserAgent(const String& userAgent)
728 {
729     if (m_userAgent == userAgent)
730         return;
731     m_userAgent = userAgent;
732
733     if (!isValid())
734         return;
735     process()->send(Messages::WebPage::SetUserAgent(m_userAgent), m_pageID);
736 }
737
738 void WebPageProxy::setApplicationNameForUserAgent(const String& applicationName)
739 {
740     if (m_applicationNameForUserAgent == applicationName)
741         return;
742
743     m_applicationNameForUserAgent = applicationName;
744     if (!m_customUserAgent.isEmpty())
745         return;
746
747     setUserAgent(standardUserAgent(m_applicationNameForUserAgent));
748 }
749
750 void WebPageProxy::setCustomUserAgent(const String& customUserAgent)
751 {
752     if (m_customUserAgent == customUserAgent)
753         return;
754
755     m_customUserAgent = customUserAgent;
756
757     if (m_customUserAgent.isEmpty()) {
758         setUserAgent(standardUserAgent(m_applicationNameForUserAgent));
759         return;
760     }
761
762     setUserAgent(m_customUserAgent);
763 }
764
765 bool WebPageProxy::supportsTextEncoding() const
766 {
767     return !m_mainFrameHasCustomRepresentation && m_mainFrame && !m_mainFrame->isDisplayingStandaloneImageDocument();
768 }
769
770 void WebPageProxy::setCustomTextEncodingName(const String& encodingName)
771 {
772     if (m_customTextEncodingName == encodingName)
773         return;
774     m_customTextEncodingName = encodingName;
775
776     if (!isValid())
777         return;
778     process()->send(Messages::WebPage::SetCustomTextEncodingName(encodingName), m_pageID);
779 }
780
781 void WebPageProxy::terminateProcess()
782 {
783     if (!isValid())
784         return;
785
786     process()->terminate();
787 }
788
789 #if !PLATFORM(CF) || defined(BUILDING_QT__)
790 PassRefPtr<WebData> WebPageProxy::sessionStateData(WebPageProxySessionStateFilterCallback, void* context) const
791 {
792     // FIXME: Return session state data for saving Page state.
793     return 0;
794 }
795
796 void WebPageProxy::restoreFromSessionStateData(WebData*)
797 {
798     // FIXME: Restore the Page from the passed in session state data.
799 }
800 #endif
801
802 bool WebPageProxy::supportsTextZoom() const
803 {
804     if (m_mainFrameHasCustomRepresentation)
805         return false;
806
807     // FIXME: This should also return false for standalone media and plug-in documents.
808     if (!m_mainFrame || m_mainFrame->isDisplayingStandaloneImageDocument())
809         return false;
810
811     return true;
812 }
813  
814 void WebPageProxy::setTextZoomFactor(double zoomFactor)
815 {
816     if (!isValid())
817         return;
818
819     if (m_mainFrameHasCustomRepresentation)
820         return;
821
822     if (m_textZoomFactor == zoomFactor)
823         return;
824
825     m_textZoomFactor = zoomFactor;
826     process()->send(Messages::WebPage::SetTextZoomFactor(m_textZoomFactor), m_pageID); 
827 }
828
829 double WebPageProxy::pageZoomFactor() const
830 {
831     return m_mainFrameHasCustomRepresentation ? m_pageClient->customRepresentationZoomFactor() : m_pageZoomFactor;
832 }
833
834 void WebPageProxy::setPageZoomFactor(double zoomFactor)
835 {
836     if (!isValid())
837         return;
838
839     if (m_mainFrameHasCustomRepresentation) {
840         m_pageClient->setCustomRepresentationZoomFactor(zoomFactor);
841         return;
842     }
843
844     if (m_pageZoomFactor == zoomFactor)
845         return;
846
847     m_pageZoomFactor = zoomFactor;
848     process()->send(Messages::WebPage::SetPageZoomFactor(m_pageZoomFactor), m_pageID); 
849 }
850
851 void WebPageProxy::setPageAndTextZoomFactors(double pageZoomFactor, double textZoomFactor)
852 {
853     if (!isValid())
854         return;
855
856     if (m_mainFrameHasCustomRepresentation) {
857         m_pageClient->setCustomRepresentationZoomFactor(pageZoomFactor);
858         return;
859     }
860
861     if (m_pageZoomFactor == pageZoomFactor && m_textZoomFactor == textZoomFactor)
862         return;
863
864     m_pageZoomFactor = pageZoomFactor;
865     m_textZoomFactor = textZoomFactor;
866     process()->send(Messages::WebPage::SetPageAndTextZoomFactors(m_pageZoomFactor, m_textZoomFactor), m_pageID); 
867 }
868
869 void WebPageProxy::scaleWebView(double scale, const IntPoint& origin)
870 {
871     if (!isValid())
872         return;
873
874     if (m_viewScaleFactor == scale)
875         return;
876
877     m_viewScaleFactor = scale;
878     process()->send(Messages::WebPage::ScaleWebView(scale, origin), m_pageID);
879 }
880
881 void WebPageProxy::setUseFixedLayout(bool fixed)
882 {
883     if (!isValid())
884         return;
885
886     if (fixed == m_useFixedLayout)
887         return;
888
889     m_useFixedLayout = fixed;
890     if (!fixed)
891         m_fixedLayoutSize = IntSize();
892     process()->send(Messages::WebPage::SetUseFixedLayout(fixed), m_pageID);
893 }
894
895 void WebPageProxy::setFixedLayoutSize(const IntSize& size)
896 {
897     if (!isValid())
898         return;
899
900     if (size == m_fixedLayoutSize)
901         return;
902
903     m_fixedLayoutSize = size;
904     process()->send(Messages::WebPage::SetFixedLayoutSize(size), m_pageID);
905 }
906
907 void WebPageProxy::findString(const String& string, FindOptions options, unsigned maxMatchCount)
908 {
909     process()->send(Messages::WebPage::FindString(string, options, maxMatchCount), m_pageID);
910 }
911
912 void WebPageProxy::hideFindUI()
913 {
914     process()->send(Messages::WebPage::HideFindUI(), m_pageID);
915 }
916
917 void WebPageProxy::countStringMatches(const String& string, FindOptions options, unsigned maxMatchCount)
918 {
919     process()->send(Messages::WebPage::CountStringMatches(string, options, maxMatchCount), m_pageID);
920 }
921     
922 void WebPageProxy::runJavaScriptInMainFrame(const String& script, PassRefPtr<StringCallback> prpCallback)
923 {
924     RefPtr<StringCallback> callback = prpCallback;
925     uint64_t callbackID = callback->callbackID();
926     m_stringCallbacks.set(callbackID, callback.get());
927     process()->send(Messages::WebPage::RunJavaScriptInMainFrame(script, callbackID), m_pageID);
928 }
929
930 void WebPageProxy::getRenderTreeExternalRepresentation(PassRefPtr<StringCallback> prpCallback)
931 {
932     RefPtr<StringCallback> callback = prpCallback;
933     uint64_t callbackID = callback->callbackID();
934     m_stringCallbacks.set(callbackID, callback.get());
935     process()->send(Messages::WebPage::GetRenderTreeExternalRepresentation(callbackID), m_pageID);
936 }
937
938 void WebPageProxy::getSourceForFrame(WebFrameProxy* frame, PassRefPtr<StringCallback> prpCallback)
939 {
940     RefPtr<StringCallback> callback = prpCallback;
941     uint64_t callbackID = callback->callbackID();
942     m_stringCallbacks.set(callbackID, callback.get());
943     process()->send(Messages::WebPage::GetSourceForFrame(frame->frameID(), callbackID), m_pageID);
944 }
945
946 void WebPageProxy::getContentsAsString(PassRefPtr<StringCallback> prpCallback)
947 {
948     RefPtr<StringCallback> callback = prpCallback;
949     uint64_t callbackID = callback->callbackID();
950     m_stringCallbacks.set(callbackID, callback.get());
951     process()->send(Messages::WebPage::GetContentsAsString(callbackID), m_pageID);
952 }
953
954 void WebPageProxy::getSelectionOrContentsAsString(PassRefPtr<StringCallback> prpCallback)
955 {
956     RefPtr<StringCallback> callback = prpCallback;
957     uint64_t callbackID = callback->callbackID();
958     m_stringCallbacks.set(callbackID, callback.get());
959     process()->send(Messages::WebPage::GetSelectionOrContentsAsString(callbackID), m_pageID);
960 }
961
962 void WebPageProxy::getMainResourceDataOfFrame(WebFrameProxy* frame, PassRefPtr<DataCallback> prpCallback)
963 {
964     RefPtr<DataCallback> callback = prpCallback;
965     uint64_t callbackID = callback->callbackID();
966     m_dataCallbacks.set(callbackID, callback.get());
967     process()->send(Messages::WebPage::GetMainResourceDataOfFrame(frame->frameID(), callbackID), m_pageID);
968 }
969
970 void WebPageProxy::getResourceDataFromFrame(WebFrameProxy* frame, WebURL* resourceURL, PassRefPtr<DataCallback> prpCallback)
971 {
972     RefPtr<DataCallback> callback = prpCallback;
973     uint64_t callbackID = callback->callbackID();
974     m_dataCallbacks.set(callbackID, callback.get());
975     process()->send(Messages::WebPage::GetResourceDataFromFrame(frame->frameID(), resourceURL->string(), callbackID), m_pageID);
976 }
977
978 void WebPageProxy::getWebArchiveOfFrame(WebFrameProxy* frame, PassRefPtr<DataCallback> prpCallback)
979 {
980     RefPtr<DataCallback> callback = prpCallback;
981     uint64_t callbackID = callback->callbackID();
982     m_dataCallbacks.set(callbackID, callback.get());
983     process()->send(Messages::WebPage::GetWebArchiveOfFrame(frame->frameID(), callbackID), m_pageID);
984 }
985
986 void WebPageProxy::preferencesDidChange()
987 {
988     if (!isValid())
989         return;
990
991     // FIXME: It probably makes more sense to send individual preference changes.
992     // However, WebKitTestRunner depends on getting a preference change notification
993     // even if nothing changed in UI process, so that overrides get removed.
994     process()->send(Messages::WebPage::PreferencesDidChange(pageGroup()->preferences()->store()), m_pageID);
995 }
996
997 #if ENABLE(TILED_BACKING_STORE)
998 void WebPageProxy::setResizesToContentsUsingLayoutSize(const WebCore::IntSize& targetLayoutSize)
999 {
1000     process()->send(Messages::WebPage::SetResizesToContentsUsingLayoutSize(targetLayoutSize), m_pageID);
1001 }
1002 #endif
1003
1004 void WebPageProxy::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments)
1005 {
1006 #ifdef __APPLE__
1007     if (messageID.is<CoreIPC::MessageClassDrawingAreaProxy>()) {
1008         m_drawingArea->didReceiveDrawingAreaProxyMessage(connection, messageID, arguments);
1009         return;
1010     }
1011 #endif
1012
1013     if (messageID.is<CoreIPC::MessageClassDrawingAreaProxyLegacy>()) {
1014         m_drawingArea->didReceiveMessage(connection, messageID, arguments);
1015         return;
1016     }
1017
1018 #if ENABLE(INSPECTOR)
1019     if (messageID.is<CoreIPC::MessageClassWebInspectorProxy>()) {
1020         if (WebInspectorProxy* inspector = this->inspector())
1021             inspector->didReceiveWebInspectorProxyMessage(connection, messageID, arguments);
1022         return;
1023     }
1024 #endif
1025
1026     didReceiveWebPageProxyMessage(connection, messageID, arguments);
1027 }
1028
1029 void WebPageProxy::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments, CoreIPC::ArgumentEncoder* reply)
1030 {
1031     if (messageID.is<CoreIPC::MessageClassDrawingAreaProxyLegacy>()) {
1032         m_drawingArea->didReceiveSyncMessage(connection, messageID, arguments, reply);
1033         return;
1034     }
1035
1036 #if ENABLE(INSPECTOR)
1037     if (messageID.is<CoreIPC::MessageClassWebInspectorProxy>()) {
1038         if (WebInspectorProxy* inspector = this->inspector())
1039             inspector->didReceiveSyncWebInspectorProxyMessage(connection, messageID, arguments, reply);
1040         return;
1041     }
1042 #endif
1043
1044     // FIXME: Do something with reply.
1045     didReceiveSyncWebPageProxyMessage(connection, messageID, arguments, reply);
1046 }
1047
1048 #if PLATFORM(MAC)
1049 void WebPageProxy::interpretKeyEvent(uint32_t type, Vector<KeypressCommand>& commandsList, uint32_t selectionStart, uint32_t selectionEnd, Vector<CompositionUnderline>& underlines)
1050 {
1051     m_pageClient->interceptKeyEvent(m_keyEventQueue.first(), commandsList, selectionStart, selectionEnd, underlines);
1052 }
1053 #endif
1054
1055 void WebPageProxy::didCreateMainFrame(uint64_t frameID)
1056 {
1057     MESSAGE_CHECK(!m_mainFrame);
1058     MESSAGE_CHECK(process()->canCreateFrame(frameID));
1059
1060     m_mainFrame = WebFrameProxy::create(this, frameID);
1061
1062     // Add the frame to the process wide map.
1063     process()->frameCreated(frameID, m_mainFrame.get());
1064 }
1065
1066 void WebPageProxy::didCreateSubframe(uint64_t frameID, uint64_t parentFrameID)
1067 {
1068     MESSAGE_CHECK(m_mainFrame);
1069
1070     WebFrameProxy* parentFrame = process()->webFrame(parentFrameID);
1071     MESSAGE_CHECK(parentFrame);
1072     MESSAGE_CHECK(parentFrame->isDescendantOf(m_mainFrame.get()));
1073
1074     MESSAGE_CHECK(process()->canCreateFrame(frameID));
1075     
1076     RefPtr<WebFrameProxy> subFrame = WebFrameProxy::create(this, frameID);
1077
1078     // Add the frame to the process wide map.
1079     process()->frameCreated(frameID, subFrame.get());
1080
1081     // Insert the frame into the frame hierarchy.
1082     parentFrame->appendChild(subFrame.get());
1083 }
1084
1085 static bool isDisconnectedFrame(WebFrameProxy* frame)
1086 {
1087     return !frame->page() || !frame->page()->mainFrame() || !frame->isDescendantOf(frame->page()->mainFrame());
1088 }
1089
1090 void WebPageProxy::didSaveFrameToPageCache(uint64_t frameID)
1091 {
1092     MESSAGE_CHECK(m_mainFrame);
1093
1094     WebFrameProxy* subframe = process()->webFrame(frameID);
1095     MESSAGE_CHECK(subframe);
1096
1097     if (isDisconnectedFrame(subframe))
1098         return;
1099
1100     MESSAGE_CHECK(subframe->isDescendantOf(m_mainFrame.get()));
1101
1102     subframe->didRemoveFromHierarchy();
1103 }
1104
1105 void WebPageProxy::didRestoreFrameFromPageCache(uint64_t frameID, uint64_t parentFrameID)
1106 {
1107     MESSAGE_CHECK(m_mainFrame);
1108
1109     WebFrameProxy* subframe = process()->webFrame(frameID);
1110     MESSAGE_CHECK(subframe);
1111     MESSAGE_CHECK(!subframe->parentFrame());
1112     MESSAGE_CHECK(subframe->page() == m_mainFrame->page());
1113
1114     WebFrameProxy* parentFrame = process()->webFrame(parentFrameID);
1115     MESSAGE_CHECK(parentFrame);
1116     MESSAGE_CHECK(parentFrame->isDescendantOf(m_mainFrame.get()));
1117
1118     // Insert the frame into the frame hierarchy.
1119     parentFrame->appendChild(subframe);
1120 }
1121
1122 void WebPageProxy::didStartProgress()
1123 {
1124     m_estimatedProgress = 0.0;
1125     
1126     m_loaderClient.didStartProgress(this);
1127 }
1128
1129 void WebPageProxy::didChangeProgress(double value)
1130 {
1131     m_estimatedProgress = value;
1132     
1133     m_loaderClient.didChangeProgress(this);
1134 }
1135
1136 void WebPageProxy::didFinishProgress()
1137 {
1138     m_estimatedProgress = 1.0;
1139
1140     m_loaderClient.didFinishProgress(this);
1141 }
1142
1143 void WebPageProxy::didStartProvisionalLoadForFrame(uint64_t frameID, const String& url, bool loadingSubstituteDataForUnreachableURL, CoreIPC::ArgumentDecoder* arguments)
1144 {
1145     RefPtr<APIObject> userData;
1146     WebContextUserMessageDecoder messageDecoder(userData, context());
1147     if (!arguments->decode(messageDecoder))
1148         return;
1149
1150     WebFrameProxy* frame = process()->webFrame(frameID);
1151     MESSAGE_CHECK(frame);
1152
1153     if (!loadingSubstituteDataForUnreachableURL)
1154         frame->setUnreachableURL(String());
1155
1156     frame->didStartProvisionalLoad(url);
1157     m_loaderClient.didStartProvisionalLoadForFrame(this, frame, userData.get());
1158 }
1159
1160 void WebPageProxy::didReceiveServerRedirectForProvisionalLoadForFrame(uint64_t frameID, const String& url, CoreIPC::ArgumentDecoder* arguments)
1161 {
1162     RefPtr<APIObject> userData;
1163     WebContextUserMessageDecoder messageDecoder(userData, context());
1164     if (!arguments->decode(messageDecoder))
1165         return;
1166
1167     WebFrameProxy* frame = process()->webFrame(frameID);
1168     MESSAGE_CHECK(frame);
1169
1170     frame->didReceiveServerRedirectForProvisionalLoad(url);
1171
1172     m_loaderClient.didReceiveServerRedirectForProvisionalLoadForFrame(this, frame, userData.get());
1173 }
1174
1175 void WebPageProxy::didFailProvisionalLoadForFrame(uint64_t frameID, const ResourceError& error, CoreIPC::ArgumentDecoder* arguments)
1176 {
1177     RefPtr<APIObject> userData;
1178     WebContextUserMessageDecoder messageDecoder(userData, context());
1179     if (!arguments->decode(messageDecoder))
1180         return;
1181
1182     WebFrameProxy* frame = process()->webFrame(frameID);
1183     MESSAGE_CHECK(frame);
1184
1185     frame->didFailProvisionalLoad();
1186
1187     m_loaderClient.didFailProvisionalLoadWithErrorForFrame(this, frame, error, userData.get());
1188 }
1189
1190 void WebPageProxy::didCommitLoadForFrame(uint64_t frameID, const String& mimeType, bool frameHasCustomRepresentation, const PlatformCertificateInfo& certificateInfo, CoreIPC::ArgumentDecoder* arguments)
1191 {
1192     RefPtr<APIObject> userData;
1193     WebContextUserMessageDecoder messageDecoder(userData, context());
1194     if (!arguments->decode(messageDecoder))
1195         return;
1196
1197     WebFrameProxy* frame = process()->webFrame(frameID);
1198     MESSAGE_CHECK(frame);
1199
1200     frame->didCommitLoad(mimeType, certificateInfo);
1201
1202     if (frame->isMainFrame()) {
1203         m_mainFrameHasCustomRepresentation = frameHasCustomRepresentation;
1204         m_pageClient->didCommitLoadForMainFrame(frameHasCustomRepresentation);
1205     }
1206
1207     m_loaderClient.didCommitLoadForFrame(this, frame, userData.get());
1208 }
1209
1210 void WebPageProxy::didFinishDocumentLoadForFrame(uint64_t frameID, CoreIPC::ArgumentDecoder* arguments)
1211 {
1212     RefPtr<APIObject> userData;
1213     WebContextUserMessageDecoder messageDecoder(userData, context());
1214     if (!arguments->decode(messageDecoder))
1215         return;
1216
1217     WebFrameProxy* frame = process()->webFrame(frameID);
1218     MESSAGE_CHECK(frame);
1219
1220     m_loaderClient.didFinishDocumentLoadForFrame(this, frame, userData.get());
1221 }
1222
1223 void WebPageProxy::didFinishLoadForFrame(uint64_t frameID, CoreIPC::ArgumentDecoder* arguments)
1224 {
1225     RefPtr<APIObject> userData;
1226     WebContextUserMessageDecoder messageDecoder(userData, context());
1227     if (!arguments->decode(messageDecoder))
1228         return;
1229
1230     WebFrameProxy* frame = process()->webFrame(frameID);
1231     MESSAGE_CHECK(frame);
1232
1233     frame->didFinishLoad();
1234
1235     m_loaderClient.didFinishLoadForFrame(this, frame, userData.get());
1236 }
1237
1238 void WebPageProxy::didFailLoadForFrame(uint64_t frameID, const ResourceError& error, CoreIPC::ArgumentDecoder* arguments)
1239 {
1240     RefPtr<APIObject> userData;
1241     WebContextUserMessageDecoder messageDecoder(userData, context());
1242     if (!arguments->decode(messageDecoder))
1243         return;
1244
1245     WebFrameProxy* frame = process()->webFrame(frameID);
1246     MESSAGE_CHECK(frame);
1247
1248     frame->didFailLoad();
1249
1250     m_loaderClient.didFailLoadWithErrorForFrame(this, frame, error, userData.get());
1251 }
1252
1253 void WebPageProxy::didSameDocumentNavigationForFrame(uint64_t frameID, uint32_t opaqueSameDocumentNavigationType, const String& url, CoreIPC::ArgumentDecoder* arguments)
1254 {
1255     RefPtr<APIObject> userData;
1256     WebContextUserMessageDecoder messageDecoder(userData, context());
1257     if (!arguments->decode(messageDecoder))
1258         return;
1259
1260     WebFrameProxy* frame = process()->webFrame(frameID);
1261     MESSAGE_CHECK(frame);
1262
1263     frame->didSameDocumentNavigation(url);
1264
1265     m_loaderClient.didSameDocumentNavigationForFrame(this, frame, static_cast<SameDocumentNavigationType>(opaqueSameDocumentNavigationType), userData.get());
1266 }
1267
1268 void WebPageProxy::didReceiveTitleForFrame(uint64_t frameID, const String& title, CoreIPC::ArgumentDecoder* arguments)
1269 {
1270     RefPtr<APIObject> userData;
1271     WebContextUserMessageDecoder messageDecoder(userData, context());
1272     if (!arguments->decode(messageDecoder))
1273         return;
1274
1275     WebFrameProxy* frame = process()->webFrame(frameID);
1276     MESSAGE_CHECK(frame);
1277
1278     frame->didChangeTitle(title);
1279     
1280     m_loaderClient.didReceiveTitleForFrame(this, title, frame, userData.get());
1281 }
1282
1283 void WebPageProxy::didFirstLayoutForFrame(uint64_t frameID, CoreIPC::ArgumentDecoder* arguments)
1284 {
1285     RefPtr<APIObject> userData;
1286     WebContextUserMessageDecoder messageDecoder(userData, context());
1287     if (!arguments->decode(messageDecoder))
1288         return;
1289
1290     WebFrameProxy* frame = process()->webFrame(frameID);
1291     MESSAGE_CHECK(frame);
1292
1293     m_loaderClient.didFirstLayoutForFrame(this, frame, userData.get());
1294 }
1295
1296 void WebPageProxy::didFirstVisuallyNonEmptyLayoutForFrame(uint64_t frameID, CoreIPC::ArgumentDecoder* arguments)
1297 {
1298     RefPtr<APIObject> userData;
1299     WebContextUserMessageDecoder messageDecoder(userData, context());
1300     if (!arguments->decode(messageDecoder))
1301         return;
1302
1303     WebFrameProxy* frame = process()->webFrame(frameID);
1304     MESSAGE_CHECK(frame);
1305
1306     m_loaderClient.didFirstVisuallyNonEmptyLayoutForFrame(this, frame, userData.get());
1307 }
1308
1309 void WebPageProxy::didRemoveFrameFromHierarchy(uint64_t frameID, CoreIPC::ArgumentDecoder* arguments)
1310 {
1311     RefPtr<APIObject> userData;
1312     WebContextUserMessageDecoder messageDecoder(userData, context());
1313     if (!arguments->decode(messageDecoder))
1314         return;
1315
1316     WebFrameProxy* frame = process()->webFrame(frameID);
1317     MESSAGE_CHECK(frame);
1318
1319     frame->didRemoveFromHierarchy();
1320
1321     m_loaderClient.didRemoveFrameFromHierarchy(this, frame, userData.get());
1322 }
1323
1324 void WebPageProxy::didDisplayInsecureContentForFrame(uint64_t frameID, CoreIPC::ArgumentDecoder* arguments)
1325 {
1326     RefPtr<APIObject> userData;
1327     WebContextUserMessageDecoder messageDecoder(userData, context());
1328     if (!arguments->decode(messageDecoder))
1329         return;
1330
1331     WebFrameProxy* frame = process()->webFrame(frameID);
1332     MESSAGE_CHECK(frame);
1333
1334     m_loaderClient.didDisplayInsecureContentForFrame(this, frame, userData.get());
1335 }
1336
1337 void WebPageProxy::didRunInsecureContentForFrame(uint64_t frameID, CoreIPC::ArgumentDecoder* arguments)
1338 {
1339     RefPtr<APIObject> userData;
1340     WebContextUserMessageDecoder messageDecoder(userData, context());
1341     if (!arguments->decode(messageDecoder))
1342         return;
1343
1344     WebFrameProxy* frame = process()->webFrame(frameID);
1345     MESSAGE_CHECK(frame);
1346
1347     m_loaderClient.didRunInsecureContentForFrame(this, frame, userData.get());
1348 }
1349
1350 void WebPageProxy::didReceiveAccessibilityPageToken(const CoreIPC::DataReference& data)
1351 {
1352 #if PLATFORM(MAC)
1353     m_pageClient->accessibilityChildTokenReceived(data);
1354 #endif
1355 }
1356     
1357 void WebPageProxy::frameDidBecomeFrameSet(uint64_t frameID, bool value)
1358 {
1359     WebFrameProxy* frame = process()->webFrame(frameID);
1360     MESSAGE_CHECK(frame);
1361
1362     frame->setIsFrameSet(value);
1363     if (frame->isMainFrame())
1364         m_frameSetLargestFrame = value ? m_mainFrame : 0;
1365 }
1366
1367 // PolicyClient
1368
1369 void WebPageProxy::decidePolicyForNavigationAction(uint64_t frameID, uint32_t opaqueNavigationType, uint32_t opaqueModifiers, int32_t opaqueMouseButton, const String& url, uint64_t listenerID)
1370 {
1371     WebFrameProxy* frame = process()->webFrame(frameID);
1372     MESSAGE_CHECK(frame);
1373
1374     NavigationType navigationType = static_cast<NavigationType>(opaqueNavigationType);
1375     WebEvent::Modifiers modifiers = static_cast<WebEvent::Modifiers>(opaqueModifiers);
1376     WebMouseEvent::Button mouseButton = static_cast<WebMouseEvent::Button>(opaqueMouseButton);
1377     
1378     RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
1379     if (!m_policyClient.decidePolicyForNavigationAction(this, navigationType, modifiers, mouseButton, url, frame, listener.get()))
1380         listener->use();
1381 }
1382
1383 void WebPageProxy::decidePolicyForNewWindowAction(uint64_t frameID, uint32_t opaqueNavigationType, uint32_t opaqueModifiers, int32_t opaqueMouseButton, const String& url, uint64_t listenerID)
1384 {
1385     WebFrameProxy* frame = process()->webFrame(frameID);
1386     MESSAGE_CHECK(frame);
1387
1388     NavigationType navigationType = static_cast<NavigationType>(opaqueNavigationType);
1389     WebEvent::Modifiers modifiers = static_cast<WebEvent::Modifiers>(opaqueModifiers);
1390     WebMouseEvent::Button mouseButton = static_cast<WebMouseEvent::Button>(opaqueMouseButton);
1391
1392     RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
1393     if (!m_policyClient.decidePolicyForNewWindowAction(this, navigationType, modifiers, mouseButton, url, frame, listener.get()))
1394         listener->use();
1395 }
1396
1397 void WebPageProxy::decidePolicyForMIMEType(uint64_t frameID, const String& MIMEType, const String& url, uint64_t listenerID, bool& receivedPolicyAction, uint64_t& policyAction, uint64_t& downloadID)
1398 {
1399     WebFrameProxy* frame = process()->webFrame(frameID);
1400     MESSAGE_CHECK(frame);
1401
1402     RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
1403
1404     ASSERT(!m_inDecidePolicyForMIMEType);
1405
1406     m_inDecidePolicyForMIMEType = true;
1407     m_syncMimeTypePolicyActionIsValid = false;
1408
1409     if (!m_policyClient.decidePolicyForMIMEType(this, MIMEType, url, frame, listener.get()))
1410         listener->use();
1411
1412     m_inDecidePolicyForMIMEType = false;
1413
1414     // Check if we received a policy decision already. If we did, we can just pass it back.
1415     if (m_syncMimeTypePolicyActionIsValid) {
1416         receivedPolicyAction = true;
1417         policyAction = m_syncMimeTypePolicyAction;
1418         downloadID = m_syncMimeTypePolicyDownloadID;
1419     }
1420 }
1421
1422 // FormClient
1423
1424 void WebPageProxy::willSubmitForm(uint64_t frameID, uint64_t sourceFrameID, const StringPairVector& textFieldValues, uint64_t listenerID, CoreIPC::ArgumentDecoder* arguments)
1425 {
1426     RefPtr<APIObject> userData;
1427     WebContextUserMessageDecoder messageDecoder(userData, context());
1428     if (!arguments->decode(messageDecoder))
1429         return;
1430
1431     WebFrameProxy* frame = process()->webFrame(frameID);
1432     MESSAGE_CHECK(frame);
1433
1434     WebFrameProxy* sourceFrame = process()->webFrame(sourceFrameID);
1435     MESSAGE_CHECK(sourceFrame);
1436
1437     RefPtr<WebFormSubmissionListenerProxy> listener = frame->setUpFormSubmissionListenerProxy(listenerID);
1438     if (!m_formClient.willSubmitForm(this, frame, sourceFrame, textFieldValues.stringPairVector(), userData.get(), listener.get()))
1439         listener->continueSubmission();
1440 }
1441
1442 // ResourceLoad Client
1443
1444 void WebPageProxy::didInitiateLoadForResource(uint64_t frameID, uint64_t resourceIdentifier, const ResourceRequest& request)
1445 {
1446     WebFrameProxy* frame = process()->webFrame(frameID);
1447     MESSAGE_CHECK(frame);
1448
1449     m_resourceLoadClient.didInitiateLoadForResource(this, frame, resourceIdentifier, request);
1450 }
1451
1452 void WebPageProxy::didSendRequestForResource(uint64_t frameID, uint64_t resourceIdentifier, const ResourceRequest& request, const ResourceResponse& redirectResponse)
1453 {
1454     WebFrameProxy* frame = process()->webFrame(frameID);
1455     MESSAGE_CHECK(frame);
1456
1457     m_resourceLoadClient.didSendRequestForResource(this, frame, resourceIdentifier, request, redirectResponse);
1458 }
1459
1460 void WebPageProxy::didReceiveResponseForResource(uint64_t frameID, uint64_t resourceIdentifier, const ResourceResponse& response)
1461 {
1462     WebFrameProxy* frame = process()->webFrame(frameID);
1463     MESSAGE_CHECK(frame);
1464
1465     m_resourceLoadClient.didReceiveResponseForResource(this, frame, resourceIdentifier, response);
1466 }
1467
1468 void WebPageProxy::didReceiveContentLengthForResource(uint64_t frameID, uint64_t resourceIdentifier, uint64_t contentLength)
1469 {
1470     WebFrameProxy* frame = process()->webFrame(frameID);
1471     MESSAGE_CHECK(frame);
1472
1473     m_resourceLoadClient.didReceiveContentLengthForResource(this, frame, resourceIdentifier, contentLength);
1474 }
1475
1476 void WebPageProxy::didFinishLoadForResource(uint64_t frameID, uint64_t resourceIdentifier)
1477 {
1478     WebFrameProxy* frame = process()->webFrame(frameID);
1479     MESSAGE_CHECK(frame);
1480
1481     m_resourceLoadClient.didFinishLoadForResource(this, frame, resourceIdentifier);
1482 }
1483
1484 void WebPageProxy::didFailLoadForResource(uint64_t frameID, uint64_t resourceIdentifier, const ResourceError& error)
1485 {
1486     WebFrameProxy* frame = process()->webFrame(frameID);
1487     MESSAGE_CHECK(frame);
1488
1489     m_resourceLoadClient.didFailLoadForResource(this, frame, resourceIdentifier, error);
1490 }
1491
1492 // UIClient
1493
1494 void WebPageProxy::createNewPage(const WindowFeatures& windowFeatures, uint32_t opaqueModifiers, int32_t opaqueMouseButton, uint64_t& newPageID, WebPageCreationParameters& newPageParameters)
1495 {
1496     RefPtr<WebPageProxy> newPage = m_uiClient.createNewPage(this, windowFeatures, static_cast<WebEvent::Modifiers>(opaqueModifiers), static_cast<WebMouseEvent::Button>(opaqueMouseButton));
1497     if (newPage) {
1498         newPageID = newPage->pageID();
1499         newPageParameters = newPage->creationParameters();
1500     } else
1501         newPageID = 0;
1502 }
1503     
1504 void WebPageProxy::showPage()
1505 {
1506     m_uiClient.showPage(this);
1507 }
1508
1509 void WebPageProxy::closePage()
1510 {
1511     m_uiClient.close(this);
1512 }
1513
1514 void WebPageProxy::runJavaScriptAlert(uint64_t frameID, const String& message)
1515 {
1516     WebFrameProxy* frame = process()->webFrame(frameID);
1517     MESSAGE_CHECK(frame);
1518
1519     m_uiClient.runJavaScriptAlert(this, message, frame);
1520 }
1521
1522 void WebPageProxy::runJavaScriptConfirm(uint64_t frameID, const String& message, bool& result)
1523 {
1524     WebFrameProxy* frame = process()->webFrame(frameID);
1525     MESSAGE_CHECK(frame);
1526
1527     result = m_uiClient.runJavaScriptConfirm(this, message, frame);
1528 }
1529
1530 void WebPageProxy::runJavaScriptPrompt(uint64_t frameID, const String& message, const String& defaultValue, String& result)
1531 {
1532     WebFrameProxy* frame = process()->webFrame(frameID);
1533     MESSAGE_CHECK(frame);
1534
1535     result = m_uiClient.runJavaScriptPrompt(this, message, defaultValue, frame);
1536 }
1537
1538 void WebPageProxy::setStatusText(const String& text)
1539 {
1540     m_uiClient.setStatusText(this, text);
1541 }
1542
1543 void WebPageProxy::mouseDidMoveOverElement(uint32_t opaqueModifiers, CoreIPC::ArgumentDecoder* arguments)
1544 {
1545     RefPtr<APIObject> userData;
1546     WebContextUserMessageDecoder messageDecoder(userData, context());
1547     if (!arguments->decode(messageDecoder))
1548         return;
1549
1550     WebEvent::Modifiers modifiers = static_cast<WebEvent::Modifiers>(opaqueModifiers);
1551
1552     m_uiClient.mouseDidMoveOverElement(this, modifiers, userData.get());
1553 }
1554
1555 void WebPageProxy::missingPluginButtonClicked(const String& mimeType, const String& url)
1556 {
1557     m_uiClient.missingPluginButtonClicked(this, mimeType, url);
1558 }
1559
1560 void WebPageProxy::setToolbarsAreVisible(bool toolbarsAreVisible)
1561 {
1562     m_uiClient.setToolbarsAreVisible(this, toolbarsAreVisible);
1563 }
1564
1565 void WebPageProxy::getToolbarsAreVisible(bool& toolbarsAreVisible)
1566 {
1567     toolbarsAreVisible = m_uiClient.toolbarsAreVisible(this);
1568 }
1569
1570 void WebPageProxy::setMenuBarIsVisible(bool menuBarIsVisible)
1571 {
1572     m_uiClient.setMenuBarIsVisible(this, menuBarIsVisible);
1573 }
1574
1575 void WebPageProxy::getMenuBarIsVisible(bool& menuBarIsVisible)
1576 {
1577     menuBarIsVisible = m_uiClient.menuBarIsVisible(this);
1578 }
1579
1580 void WebPageProxy::setStatusBarIsVisible(bool statusBarIsVisible)
1581 {
1582     m_uiClient.setStatusBarIsVisible(this, statusBarIsVisible);
1583 }
1584
1585 void WebPageProxy::getStatusBarIsVisible(bool& statusBarIsVisible)
1586 {
1587     statusBarIsVisible = m_uiClient.statusBarIsVisible(this);
1588 }
1589
1590 void WebPageProxy::setIsResizable(bool isResizable)
1591 {
1592     m_uiClient.setIsResizable(this, isResizable);
1593 }
1594
1595 void WebPageProxy::getIsResizable(bool& isResizable)
1596 {
1597     isResizable = m_uiClient.isResizable(this);
1598 }
1599
1600 void WebPageProxy::setWindowFrame(const FloatRect& newWindowFrame)
1601 {
1602     m_uiClient.setWindowFrame(this, m_pageClient->convertToDeviceSpace(newWindowFrame));
1603 }
1604
1605 void WebPageProxy::getWindowFrame(FloatRect& newWindowFrame)
1606 {
1607     newWindowFrame = m_pageClient->convertToUserSpace(m_uiClient.windowFrame(this));
1608 }
1609
1610 void WebPageProxy::canRunBeforeUnloadConfirmPanel(bool& canRun)
1611 {
1612     canRun = m_uiClient.canRunBeforeUnloadConfirmPanel();
1613 }
1614
1615 void WebPageProxy::runBeforeUnloadConfirmPanel(const String& message, uint64_t frameID, bool& shouldClose)
1616 {
1617     WebFrameProxy* frame = process()->webFrame(frameID);
1618     MESSAGE_CHECK(frame);
1619
1620     shouldClose = m_uiClient.runBeforeUnloadConfirmPanel(this, message, frame);
1621 }
1622
1623 #if ENABLE(TILED_BACKING_STORE)
1624 void WebPageProxy::pageDidRequestScroll(const IntSize& delta)
1625 {
1626     m_pageClient->pageDidRequestScroll(delta);
1627 }
1628 #endif
1629
1630 void WebPageProxy::didChangeViewportData(const ViewportArguments& args)
1631 {
1632     m_pageClient->setViewportArguments(args);
1633 }
1634
1635 void WebPageProxy::pageDidScroll()
1636 {
1637     m_uiClient.pageDidScroll(this);
1638 }
1639
1640 void WebPageProxy::runOpenPanel(uint64_t frameID, const WebOpenPanelParameters::Data& data)
1641 {
1642     if (m_openPanelResultListener) {
1643         m_openPanelResultListener->invalidate();
1644         m_openPanelResultListener = 0;
1645     }
1646
1647     WebFrameProxy* frame = process()->webFrame(frameID);
1648     MESSAGE_CHECK(frame);
1649
1650     m_openPanelResultListener = WebOpenPanelResultListenerProxy::create(this);
1651
1652     if (!m_uiClient.runOpenPanel(this, frame, data, m_openPanelResultListener.get()))
1653         didCancelForOpenPanel();
1654 }
1655
1656 #if PLATFORM(QT)
1657 void WebPageProxy::didChangeContentsSize(const WebCore::IntSize& size)
1658 {
1659     m_pageClient->didChangeContentsSize(size);
1660 }
1661
1662 void WebPageProxy::didFindZoomableArea(const WebCore::IntRect& area)
1663 {
1664     m_pageClient->didFindZoomableArea(area);
1665 }
1666
1667 void WebPageProxy::findZoomableAreaForPoint(const WebCore::IntPoint& point)
1668 {
1669     if (!isValid())
1670         return;
1671
1672     process()->send(Messages::WebPage::FindZoomableAreaForPoint(point), m_pageID);
1673 }
1674 #endif
1675
1676 void WebPageProxy::didDraw()
1677 {
1678     m_uiClient.didDraw(this);
1679 }
1680
1681 // Inspector
1682
1683 #if ENABLE(INSPECTOR)
1684
1685 WebInspectorProxy* WebPageProxy::inspector()
1686 {
1687     if (isClosed() || !isValid())
1688         return 0;
1689     if (!m_inspector)
1690         m_inspector = WebInspectorProxy::create(this);
1691     return m_inspector.get();
1692 }
1693
1694 #endif
1695
1696 // BackForwardList
1697
1698 void WebPageProxy::backForwardAddItem(uint64_t itemID)
1699 {
1700     m_backForwardList->addItem(process()->webBackForwardItem(itemID));
1701 }
1702
1703 void WebPageProxy::backForwardGoToItem(uint64_t itemID)
1704 {
1705     m_backForwardList->goToItem(process()->webBackForwardItem(itemID));
1706 }
1707
1708 void WebPageProxy::backForwardItemAtIndex(int32_t index, uint64_t& itemID)
1709 {
1710     WebBackForwardListItem* item = m_backForwardList->itemAtIndex(index);
1711     itemID = item ? item->itemID() : 0;
1712 }
1713
1714 void WebPageProxy::backForwardBackListCount(int32_t& count)
1715 {
1716     count = m_backForwardList->backListCount();
1717 }
1718
1719 void WebPageProxy::backForwardForwardListCount(int32_t& count)
1720 {
1721     count = m_backForwardList->forwardListCount();
1722 }
1723
1724 void WebPageProxy::selectionStateChanged(const SelectionState& selectionState)
1725 {
1726     m_selectionState = selectionState;
1727 }
1728
1729 #if PLATFORM(MAC)
1730 // Complex text input support for plug-ins.
1731 void WebPageProxy::sendComplexTextInputToPlugin(uint64_t pluginComplexTextInputIdentifier, const String& textInput)
1732 {
1733     if (!isValid())
1734         return;
1735     
1736     process()->send(Messages::WebPage::SendComplexTextInputToPlugin(pluginComplexTextInputIdentifier, textInput), m_pageID);
1737 }
1738 #endif
1739
1740 #if PLATFORM(WIN)
1741 void WebPageProxy::didChangeCompositionSelection(bool hasComposition)
1742 {
1743     m_pageClient->compositionSelectionChanged(hasComposition);
1744 }
1745
1746 void WebPageProxy::confirmComposition(const String& compositionString)
1747 {
1748     process()->send(Messages::WebPage::ConfirmComposition(compositionString), m_pageID);
1749 }
1750
1751 void WebPageProxy::setComposition(const String& compositionString, Vector<WebCore::CompositionUnderline>& underlines, int cursorPosition)
1752 {
1753     process()->send(Messages::WebPage::SetComposition(compositionString, underlines, cursorPosition), m_pageID);
1754 }
1755 #endif
1756     
1757 // Undo management
1758
1759 void WebPageProxy::registerEditCommandForUndo(uint64_t commandID, uint32_t editAction)
1760 {
1761     registerEditCommand(WebEditCommandProxy::create(commandID, static_cast<EditAction>(editAction), this), Undo);
1762 }
1763
1764 void WebPageProxy::clearAllEditCommands()
1765 {
1766     m_pageClient->clearAllEditCommands();
1767 }
1768
1769 void WebPageProxy::didCountStringMatches(const String& string, uint32_t matchCount)
1770 {
1771     m_findClient.didCountStringMatches(this, string, matchCount);
1772 }
1773
1774 void WebPageProxy::setFindIndicator(const FloatRect& selectionRect, const Vector<FloatRect>& textRects, const SharedMemory::Handle& contentImageHandle, bool fadeOut)
1775 {
1776     RefPtr<FindIndicator> findIndicator = FindIndicator::create(selectionRect, textRects, contentImageHandle);
1777     m_pageClient->setFindIndicator(findIndicator.release(), fadeOut);
1778 }
1779
1780 void WebPageProxy::didFindString(const String& string, uint32_t matchCount)
1781 {
1782     m_findClient.didFindString(this, string, matchCount);
1783 }
1784
1785 void WebPageProxy::didFailToFindString(const String& string)
1786 {
1787     m_findClient.didFailToFindString(this, string);
1788 }
1789
1790 void WebPageProxy::valueChangedForPopupMenu(WebPopupMenuProxy*, int32_t newSelectedIndex)
1791 {
1792     process()->send(Messages::WebPage::DidChangeSelectedIndexForActivePopupMenu(newSelectedIndex), m_pageID);
1793 }
1794
1795 void WebPageProxy::setTextFromItemForPopupMenu(WebPopupMenuProxy*, int32_t index)
1796 {
1797     process()->send(Messages::WebPage::SetTextForActivePopupMenu(index), m_pageID);
1798 }
1799
1800 void WebPageProxy::showPopupMenu(const IntRect& rect, const Vector<WebPopupItem>& items, int32_t selectedIndex, const PlatformPopupMenuData& data)
1801 {
1802     if (m_activePopupMenu)
1803         m_activePopupMenu->hidePopupMenu();
1804     else
1805         m_activePopupMenu = m_pageClient->createPopupMenuProxy(this);
1806
1807 #if PLATFORM(WIN)
1808     // On Windows, we're about to run our own message pump in showPopupMenu(), so turn off the responsiveness timer.
1809     process()->responsivenessTimer()->stop();
1810 #endif
1811
1812     m_activePopupMenu->showPopupMenu(rect, items, data, selectedIndex);
1813     m_activePopupMenu = 0;
1814 }
1815
1816 void WebPageProxy::hidePopupMenu()
1817 {
1818     if (!m_activePopupMenu)
1819         return;
1820
1821     m_activePopupMenu->hidePopupMenu();
1822     m_activePopupMenu = 0;
1823 }
1824
1825 void WebPageProxy::showContextMenu(const IntPoint& menuLocation, const ContextMenuState& contextMenuState, const Vector<WebContextMenuItemData>& proposedItems, CoreIPC::ArgumentDecoder* arguments)
1826 {
1827     RefPtr<APIObject> userData;
1828     WebContextUserMessageDecoder messageDecoder(userData, context());
1829     if (!arguments->decode(messageDecoder))
1830         return;
1831
1832     m_activeContextMenuState = contextMenuState;
1833
1834     if (m_activeContextMenu)
1835         m_activeContextMenu->hideContextMenu();
1836     else
1837         m_activeContextMenu = m_pageClient->createContextMenuProxy(this);
1838
1839     // Give the PageContextMenuClient one last swipe at changing the menu.
1840     Vector<WebContextMenuItemData> items;
1841         
1842     if (!m_contextMenuClient.getContextMenuFromProposedMenu(this, proposedItems, items, userData.get())) {
1843         m_activeContextMenu->showContextMenu(menuLocation, proposedItems);
1844         return;
1845     }
1846     
1847     if (items.size())
1848         m_activeContextMenu->showContextMenu(menuLocation, items);
1849 }
1850
1851 void WebPageProxy::contextMenuItemSelected(const WebContextMenuItemData& item)
1852 {
1853     // Application custom items don't need to round-trip through to WebCore in the WebProcess.
1854     if (item.action() >= ContextMenuItemBaseApplicationTag) {
1855         m_contextMenuClient.customContextMenuItemSelected(this, item);
1856         return;
1857     }
1858
1859 #if PLATFORM(MAC)
1860     if (item.action() == ContextMenuItemTagSmartCopyPaste) {
1861         setSmartInsertDeleteEnabled(!isSmartInsertDeleteEnabled());
1862         return;
1863     }
1864     if (item.action() == ContextMenuItemTagSmartQuotes) {
1865         TextChecker::setAutomaticQuoteSubstitutionEnabled(!TextChecker::state().isAutomaticQuoteSubstitutionEnabled);
1866         process()->updateTextCheckerState();
1867         return;
1868     }
1869     if (item.action() == ContextMenuItemTagSmartDashes) {
1870         TextChecker::setAutomaticDashSubstitutionEnabled(!TextChecker::state().isAutomaticDashSubstitutionEnabled);
1871         process()->updateTextCheckerState();
1872         return;
1873     }
1874     if (item.action() == ContextMenuItemTagSmartLinks) {
1875         TextChecker::setAutomaticLinkDetectionEnabled(!TextChecker::state().isAutomaticLinkDetectionEnabled);
1876         process()->updateTextCheckerState();
1877         return;
1878     }
1879     if (item.action() == ContextMenuItemTagTextReplacement) {
1880         TextChecker::setAutomaticTextReplacementEnabled(!TextChecker::state().isAutomaticTextReplacementEnabled);
1881         process()->updateTextCheckerState();
1882         return;
1883     }
1884 #endif
1885     if (item.action() == ContextMenuItemTagDownloadImageToDisk) {
1886         m_context->download(this, KURL(KURL(), m_activeContextMenuState.absoluteImageURLString));
1887         return;    
1888     }
1889     if (item.action() == ContextMenuItemTagDownloadLinkToDisk) {
1890         m_context->download(this, KURL(KURL(), m_activeContextMenuState.absoluteLinkURLString));
1891         return;
1892     }
1893     
1894     if (item.action() == ContextMenuItemTagLearnSpelling || item.action() == ContextMenuItemTagIgnoreSpelling)
1895         ++m_pendingLearnOrIgnoreWordMessageCount;
1896
1897     process()->send(Messages::WebPage::DidSelectItemFromActiveContextMenu(item), m_pageID);
1898 }
1899
1900 void WebPageProxy::didChooseFilesForOpenPanel(const Vector<String>& fileURLs)
1901 {
1902     if (!isValid())
1903         return;
1904
1905     // FIXME: This also needs to send a sandbox extension for these paths.
1906     process()->send(Messages::WebPage::DidChooseFilesForOpenPanel(fileURLs), m_pageID);
1907
1908     m_openPanelResultListener->invalidate();
1909     m_openPanelResultListener = 0;
1910 }
1911
1912 void WebPageProxy::didCancelForOpenPanel()
1913 {
1914     if (!isValid())
1915         return;
1916
1917     process()->send(Messages::WebPage::DidCancelForOpenPanel(), m_pageID);
1918     
1919     m_openPanelResultListener->invalidate();
1920     m_openPanelResultListener = 0;
1921 }
1922
1923 void WebPageProxy::advanceToNextMisspelling(bool startBeforeSelection)
1924 {
1925     process()->send(Messages::WebPage::AdvanceToNextMisspelling(startBeforeSelection), m_pageID);
1926 }
1927
1928 void WebPageProxy::changeSpellingToWord(const String& word)
1929 {
1930     if (word.isEmpty())
1931         return;
1932
1933     process()->send(Messages::WebPage::ChangeSpellingToWord(word), m_pageID);
1934 }
1935
1936 void WebPageProxy::unmarkAllMisspellings()
1937 {
1938     process()->send(Messages::WebPage::UnmarkAllMisspellings(), m_pageID);
1939 }
1940
1941 void WebPageProxy::unmarkAllBadGrammar()
1942 {
1943     process()->send(Messages::WebPage::UnmarkAllBadGrammar(), m_pageID);
1944 }
1945
1946 #if PLATFORM(MAC)
1947 void WebPageProxy::uppercaseWord()
1948 {
1949     process()->send(Messages::WebPage::UppercaseWord(), m_pageID);
1950 }
1951
1952 void WebPageProxy::lowercaseWord()
1953 {
1954     process()->send(Messages::WebPage::LowercaseWord(), m_pageID);
1955 }
1956
1957 void WebPageProxy::capitalizeWord()
1958 {
1959     process()->send(Messages::WebPage::CapitalizeWord(), m_pageID);
1960 }
1961
1962 void WebPageProxy::setSmartInsertDeleteEnabled(bool isSmartInsertDeleteEnabled)
1963
1964     if (m_isSmartInsertDeleteEnabled == isSmartInsertDeleteEnabled)
1965         return;
1966
1967     TextChecker::setSmartInsertDeleteEnabled(isSmartInsertDeleteEnabled);
1968     m_isSmartInsertDeleteEnabled = isSmartInsertDeleteEnabled;
1969     process()->send(Messages::WebPage::SetSmartInsertDeleteEnabled(isSmartInsertDeleteEnabled), m_pageID);
1970 }
1971 #endif
1972
1973 void WebPageProxy::registerEditCommand(PassRefPtr<WebEditCommandProxy> commandProxy, UndoOrRedo undoOrRedo)
1974 {
1975     m_pageClient->registerEditCommand(commandProxy, undoOrRedo);
1976 }
1977
1978 void WebPageProxy::addEditCommand(WebEditCommandProxy* command)
1979 {
1980     m_editCommandSet.add(command);
1981 }
1982
1983 void WebPageProxy::removeEditCommand(WebEditCommandProxy* command)
1984 {
1985     m_editCommandSet.remove(command);
1986
1987     if (!isValid())
1988         return;
1989     process()->send(Messages::WebPage::DidRemoveEditCommand(command->commandID()), m_pageID);
1990 }
1991
1992 int64_t WebPageProxy::spellDocumentTag()
1993 {
1994     if (!m_hasSpellDocumentTag) {
1995         m_spellDocumentTag = TextChecker::uniqueSpellDocumentTag();
1996         m_hasSpellDocumentTag = true;
1997     }
1998
1999     return m_spellDocumentTag;
2000 }
2001
2002 void WebPageProxy::checkTextOfParagraph(const String& text, uint64_t checkingTypes, Vector<TextCheckingResult>& results)
2003 {
2004     results = TextChecker::checkTextOfParagraph(spellDocumentTag(), text.characters(), text.length(), checkingTypes);
2005 }
2006
2007 void WebPageProxy::updateSpellingUIWithMisspelledWord(const String& misspelledWord)
2008 {
2009     TextChecker::updateSpellingUIWithMisspelledWord(misspelledWord);
2010 }
2011
2012 void WebPageProxy::getGuessesForWord(const String& word, const String& context, Vector<String>& guesses)
2013 {
2014     TextChecker::getGuessesForWord(spellDocumentTag(), word, context, guesses);
2015 }
2016
2017 void WebPageProxy::learnWord(const String& word)
2018 {
2019     MESSAGE_CHECK(m_pendingLearnOrIgnoreWordMessageCount);
2020     --m_pendingLearnOrIgnoreWordMessageCount;
2021
2022     TextChecker::learnWord(word);
2023 }
2024
2025 void WebPageProxy::ignoreWord(const String& word)
2026 {
2027     MESSAGE_CHECK(m_pendingLearnOrIgnoreWordMessageCount);
2028     --m_pendingLearnOrIgnoreWordMessageCount;
2029
2030     TextChecker::ignoreWord(spellDocumentTag(), word);
2031 }
2032
2033 // Other
2034
2035 void WebPageProxy::takeFocus(bool direction)
2036 {
2037     m_pageClient->takeFocus(direction);
2038 }
2039
2040 void WebPageProxy::setToolTip(const String& toolTip)
2041 {
2042     String oldToolTip = m_toolTip;
2043     m_toolTip = toolTip;
2044     m_pageClient->toolTipChanged(oldToolTip, m_toolTip);
2045 }
2046
2047 void WebPageProxy::setCursor(const WebCore::Cursor& cursor)
2048 {
2049     m_pageClient->setCursor(cursor);
2050 }
2051
2052 void WebPageProxy::didValidateMenuItem(const String& commandName, bool isEnabled, int32_t state)
2053 {
2054     m_pageClient->setEditCommandState(commandName, isEnabled, state);
2055 }
2056
2057 void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled)
2058 {
2059     WebEvent::Type type = static_cast<WebEvent::Type>(opaqueType);
2060
2061     switch (type) {
2062     case WebEvent::MouseMove:
2063         break;
2064
2065     case WebEvent::MouseDown:
2066     case WebEvent::MouseUp:
2067     case WebEvent::Wheel:
2068     case WebEvent::KeyDown:
2069     case WebEvent::KeyUp:
2070     case WebEvent::RawKeyDown:
2071     case WebEvent::Char:
2072         process()->responsivenessTimer()->stop();
2073         break;
2074     }
2075
2076     switch (type) {
2077     case WebEvent::MouseMove:
2078         m_processingMouseMoveEvent = false;
2079         if (m_nextMouseMoveEvent) {
2080             handleMouseEvent(*m_nextMouseMoveEvent);
2081             m_nextMouseMoveEvent = nullptr;
2082         }
2083         break;
2084     case WebEvent::MouseDown:
2085     case WebEvent::MouseUp:
2086         break;
2087
2088     case WebEvent::Wheel: {
2089         m_processingWheelEvent = false;
2090         if (m_nextWheelEvent) {
2091             handleWheelEvent(*m_nextWheelEvent);
2092             m_nextWheelEvent = nullptr;
2093         }
2094         break;
2095     }
2096
2097     case WebEvent::KeyDown:
2098     case WebEvent::KeyUp:
2099     case WebEvent::RawKeyDown:
2100     case WebEvent::Char: {
2101         NativeWebKeyboardEvent event = m_keyEventQueue.first();
2102         MESSAGE_CHECK(type == event.type());
2103
2104         m_keyEventQueue.removeFirst();
2105
2106         if (handled)
2107             break;
2108
2109         m_pageClient->didNotHandleKeyEvent(event);
2110         m_uiClient.didNotHandleKeyEvent(this, event);
2111         break;
2112     }
2113     }
2114 }
2115
2116 void WebPageProxy::dataCallback(const CoreIPC::DataReference& dataReference, uint64_t callbackID)
2117 {
2118     RefPtr<DataCallback> callback = m_dataCallbacks.take(callbackID);
2119     if (!callback) {
2120         // FIXME: Log error or assert.
2121         return;
2122     }
2123
2124     callback->performCallbackWithReturnValue(WebData::create(dataReference.data(), dataReference.size()).get());
2125 }
2126
2127 void WebPageProxy::stringCallback(const String& resultString, uint64_t callbackID)
2128 {
2129     RefPtr<StringCallback> callback = m_stringCallbacks.take(callbackID);
2130     if (!callback) {
2131         // FIXME: Log error or assert.
2132         return;
2133     }
2134
2135     callback->performCallbackWithReturnValue(resultString.impl());
2136 }
2137
2138 #if PLATFORM(MAC)
2139 void WebPageProxy::sendAccessibilityPresenterToken(const CoreIPC::DataReference& token)
2140 {
2141     if (!isValid())
2142         return;
2143
2144     process()->send(Messages::WebPage::SendAccessibilityPresenterToken(token), m_pageID);
2145 }
2146 #endif
2147
2148 void WebPageProxy::focusedFrameChanged(uint64_t frameID)
2149 {
2150     if (!frameID) {
2151         m_focusedFrame = 0;
2152         return;
2153     }
2154
2155     WebFrameProxy* frame = process()->webFrame(frameID);
2156     MESSAGE_CHECK(frame);
2157
2158     m_focusedFrame = frame;
2159 }
2160
2161 void WebPageProxy::frameSetLargestFrameChanged(uint64_t frameID)
2162 {
2163     if (!frameID) {
2164         m_frameSetLargestFrame = 0;
2165         return;
2166     }
2167
2168     WebFrameProxy* frame = process()->webFrame(frameID);
2169     MESSAGE_CHECK(frame);
2170
2171     m_frameSetLargestFrame = frame;
2172 }
2173
2174 #if USE(ACCELERATED_COMPOSITING)
2175 void WebPageProxy::didChangeAcceleratedCompositing(bool compositing, DrawingAreaInfo& drawingAreaInfo)
2176 {
2177     if (compositing)
2178         didEnterAcceleratedCompositing();
2179     else
2180         didLeaveAcceleratedCompositing();
2181
2182     drawingAreaInfo = drawingArea()->info();
2183 }
2184 #endif
2185
2186 void WebPageProxy::processDidBecomeUnresponsive()
2187 {
2188     m_loaderClient.processDidBecomeUnresponsive(this);
2189 }
2190
2191 void WebPageProxy::processDidBecomeResponsive()
2192 {
2193     m_loaderClient.processDidBecomeResponsive(this);
2194 }
2195
2196 void WebPageProxy::processDidCrash()
2197 {
2198     ASSERT(m_pageClient);
2199
2200     m_isValid = false;
2201
2202     if (m_mainFrame)
2203         m_urlAtProcessExit = m_mainFrame->url();
2204
2205     m_mainFrame = 0;
2206
2207     m_drawingArea = nullptr;
2208
2209 #if ENABLE(INSPECTOR)
2210     if (m_inspector) {
2211         m_inspector->invalidate();
2212         m_inspector = 0;
2213     }
2214 #endif
2215
2216     if (m_openPanelResultListener) {
2217         m_openPanelResultListener->invalidate();
2218         m_openPanelResultListener = 0;
2219     }
2220
2221     m_geolocationPermissionRequestManager.invalidateRequests();
2222
2223     m_toolTip = String();
2224
2225     invalidateCallbackMap(m_dataCallbacks);
2226     invalidateCallbackMap(m_stringCallbacks);
2227
2228     Vector<WebEditCommandProxy*> editCommandVector;
2229     copyToVector(m_editCommandSet, editCommandVector);
2230     m_editCommandSet.clear();
2231     for (size_t i = 0, size = editCommandVector.size(); i < size; ++i)
2232         editCommandVector[i]->invalidate();
2233     m_pageClient->clearAllEditCommands();
2234
2235     m_activePopupMenu = 0;
2236
2237     m_estimatedProgress = 0.0;
2238
2239     m_pendingLearnOrIgnoreWordMessageCount = 0;
2240
2241     m_pageClient->processDidCrash();
2242     m_loaderClient.processDidCrash(this);
2243 }
2244
2245 WebPageCreationParameters WebPageProxy::creationParameters() const
2246 {
2247     WebPageCreationParameters parameters;
2248
2249     parameters.viewSize = m_pageClient->viewSize();
2250     parameters.isActive = m_pageClient->isViewWindowActive();
2251     parameters.isFocused = m_pageClient->isViewFocused();
2252     parameters.isVisible = m_pageClient->isViewVisible();
2253     parameters.isInWindow = m_pageClient->isViewInWindow();
2254
2255     parameters.drawingAreaInfo = m_drawingArea->info();
2256     parameters.store = m_pageGroup->preferences()->store();
2257     parameters.pageGroupData = m_pageGroup->data();
2258     parameters.drawsBackground = m_drawsBackground;
2259     parameters.drawsTransparentBackground = m_drawsTransparentBackground;
2260     parameters.useFixedLayout = m_useFixedLayout;
2261     parameters.fixedLayoutSize = m_fixedLayoutSize;
2262     parameters.userAgent = userAgent();
2263     parameters.sessionState = SessionState(m_backForwardList->entries(), m_backForwardList->currentIndex());
2264     parameters.highestUsedBackForwardItemID = WebBackForwardListItem::highedUsedItemID();
2265
2266 #if PLATFORM(MAC)
2267     parameters.isSmartInsertDeleteEnabled = m_isSmartInsertDeleteEnabled;
2268 #endif
2269
2270 #if PLATFORM(WIN)
2271     parameters.nativeWindow = m_pageClient->nativeWindow();
2272 #endif
2273
2274     return parameters;
2275 }
2276
2277 #if USE(ACCELERATED_COMPOSITING)
2278
2279 void WebPageProxy::didEnterAcceleratedCompositing()
2280 {
2281     m_pageClient->pageDidEnterAcceleratedCompositing();
2282 }
2283
2284 void WebPageProxy::didLeaveAcceleratedCompositing()
2285 {
2286     m_pageClient->pageDidLeaveAcceleratedCompositing();
2287 }
2288
2289 #endif // USE(ACCELERATED_COMPOSITING)
2290
2291 void WebPageProxy::backForwardClear()
2292 {
2293     m_backForwardList->clear();
2294 }
2295
2296 void WebPageProxy::canAuthenticateAgainstProtectionSpaceInFrame(uint64_t frameID, const WebCore::ProtectionSpace& coreProtectionSpace, bool& canAuthenticate)
2297 {
2298     WebFrameProxy* frame = process()->webFrame(frameID);
2299     MESSAGE_CHECK(frame);
2300
2301     RefPtr<WebProtectionSpace> protectionSpace = WebProtectionSpace::create(coreProtectionSpace);
2302     
2303     canAuthenticate = m_loaderClient.canAuthenticateAgainstProtectionSpaceInFrame(this, frame, protectionSpace.get());
2304 }
2305
2306 void WebPageProxy::didReceiveAuthenticationChallenge(uint64_t frameID, const WebCore::AuthenticationChallenge& coreChallenge, uint64_t challengeID)
2307 {
2308     WebFrameProxy* frame = process()->webFrame(frameID);
2309     MESSAGE_CHECK(frame);
2310
2311     RefPtr<AuthenticationChallengeProxy> authenticationChallenge = AuthenticationChallengeProxy::create(coreChallenge, challengeID, this);
2312     
2313     m_loaderClient.didReceiveAuthenticationChallengeInFrame(this, frame, authenticationChallenge.get());
2314 }
2315
2316 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)
2317 {
2318     WebFrameProxy* frame = process()->webFrame(frameID);
2319     MESSAGE_CHECK(frame);
2320
2321     RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::create(originIdentifier);
2322
2323     newQuota = m_uiClient.exceededDatabaseQuota(this, frame, origin.get(), databaseName, displayName, currentQuota, currentUsage, expectedUsage);
2324 }
2325
2326 void WebPageProxy::requestGeolocationPermissionForFrame(uint64_t geolocationID, uint64_t frameID, String originIdentifier)
2327 {
2328     WebFrameProxy* frame = process()->webFrame(frameID);
2329     MESSAGE_CHECK(frame);
2330
2331     RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::create(originIdentifier);
2332     RefPtr<GeolocationPermissionRequestProxy> request = m_geolocationPermissionRequestManager.createRequest(geolocationID);
2333
2334     if (!m_uiClient.decidePolicyForGeolocationPermissionRequest(this, frame, origin.get(), request.get()))
2335         request->deny();
2336 }
2337
2338 void WebPageProxy::didFinishLoadingDataForCustomRepresentation(const CoreIPC::DataReference& dataReference)
2339 {
2340     m_pageClient->didFinishLoadingDataForCustomRepresentation(dataReference);
2341 }
2342
2343 #if PLATFORM(MAC)
2344 void WebPageProxy::setComplexTextInputEnabled(uint64_t pluginComplexTextInputIdentifier, bool complexTextInputEnabled)
2345 {
2346     m_pageClient->setComplexTextInputEnabled(pluginComplexTextInputIdentifier, complexTextInputEnabled);
2347 }
2348 #endif
2349
2350 void WebPageProxy::backForwardRemovedItem(uint64_t itemID)
2351 {
2352     process()->send(Messages::WebPage::DidRemoveBackForwardItem(itemID), m_pageID);
2353 }
2354
2355 void WebPageProxy::beginPrinting(WebFrameProxy* frame, const PrintInfo& printInfo)
2356 {
2357     if (m_isInPrintingMode)
2358         return;
2359
2360     m_isInPrintingMode = true;
2361     process()->send(Messages::WebPage::BeginPrinting(frame->frameID(), printInfo), m_pageID);
2362 }
2363
2364 void WebPageProxy::endPrinting()
2365 {
2366     if (!m_isInPrintingMode)
2367         return;
2368
2369     m_isInPrintingMode = false;
2370     process()->send(Messages::WebPage::EndPrinting(), m_pageID);
2371 }
2372
2373 void WebPageProxy::computePagesForPrinting(WebFrameProxy* frame, const PrintInfo& printInfo, Vector<WebCore::IntRect>& resultPageRects, double& resultTotalScaleFactorForPrinting)
2374 {
2375     // Layout for printing can take a long time, but we need to have the answer.
2376     process()->sendSync(Messages::WebPage::ComputePagesForPrinting(frame->frameID(), printInfo), Messages::WebPage::ComputePagesForPrinting::Reply(resultPageRects, resultTotalScaleFactorForPrinting), m_pageID);
2377 }
2378
2379 #if PLATFORM(MAC)
2380 void WebPageProxy::drawRectToPDF(WebFrameProxy* frame, const IntRect& rect, Vector<uint8_t>& pdfData)
2381 {
2382     // Printing can take a long time, but we need to have the answer.
2383     process()->sendSync(Messages::WebPage::DrawRectToPDF(frame->frameID(), rect), Messages::WebPage::DrawRectToPDF::Reply(pdfData), m_pageID);
2384 }
2385 #endif
2386
2387 } // namespace WebKit