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