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