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