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