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