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