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