Implement WebKit2 callback equivalent to - [WebUIDelegate webView:setStatusText:]
[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 "DrawingAreaProxy.h"
29 #include "MessageID.h"
30 #include "PageClient.h"
31 #include "WebBackForwardList.h"
32 #include "WebBackForwardListItem.h"
33 #include "WebContext.h"
34 #include "WebContextUserMessageCoders.h"
35 #include "WebCoreArgumentCoders.h"
36 #include "WebData.h"
37 #include "WebEditCommandProxy.h"
38 #include "WebEvent.h"
39 #include "WebFormSubmissionListenerProxy.h"
40 #include "WebFramePolicyListenerProxy.h"
41 #include "WebPageMessageKinds.h"
42 #include "WebPageNamespace.h"
43 #include "WebPageProxyMessageKinds.h"
44 #include "WebPreferences.h"
45 #include "WebProcessManager.h"
46 #include "WebProcessMessageKinds.h"
47 #include "WebProcessProxy.h"
48 #include "WebURLRequest.h"
49
50 #include "WKContextPrivate.h"
51 #include <stdio.h>
52
53 #ifndef NDEBUG
54 #include <wtf/RefCountedLeakCounter.h>
55 #endif
56
57 using namespace WebCore;
58
59 namespace WebKit {
60
61 #ifndef NDEBUG
62 static WTF::RefCountedLeakCounter webPageProxyCounter("WebPageProxy");
63 #endif
64
65 PassRefPtr<WebPageProxy> WebPageProxy::create(WebPageNamespace* pageNamespace, uint64_t pageID)
66 {
67     return adoptRef(new WebPageProxy(pageNamespace, pageID));
68 }
69
70 WebPageProxy::WebPageProxy(WebPageNamespace* pageNamespace, uint64_t pageID)
71     : m_pageClient(0)
72     , m_pageNamespace(pageNamespace)
73     , m_mainFrame(0)
74     , m_estimatedProgress(0.0)
75     , m_isInWindow(false)
76     , m_backForwardList(WebBackForwardList::create(this))
77     , m_textZoomFactor(1)
78     , m_pageZoomFactor(1)
79     , m_valid(true)
80     , m_closed(false)
81     , m_pageID(pageID)
82 {
83 #ifndef NDEBUG
84     webPageProxyCounter.increment();
85 #endif
86 }
87
88 WebPageProxy::~WebPageProxy()
89 {
90 #ifndef NDEBUG
91     webPageProxyCounter.decrement();
92 #endif
93 }
94
95 WebProcessProxy* WebPageProxy::process() const
96 {
97     return m_pageNamespace->process();
98 }
99
100 bool WebPageProxy::isValid()
101 {
102     return m_valid;
103 }
104
105 void WebPageProxy::setPageClient(PageClient* pageClient)
106 {
107     m_pageClient = pageClient;
108 }
109
110 void WebPageProxy::setDrawingArea(PassOwnPtr<DrawingAreaProxy> drawingArea)
111 {
112     if (drawingArea == m_drawingArea)
113         return;
114
115     m_drawingArea = drawingArea;
116 }
117
118 void WebPageProxy::initializeLoaderClient(const WKPageLoaderClient* loadClient)
119 {
120     m_loaderClient.initialize(loadClient);
121 }
122
123 void WebPageProxy::initializePolicyClient(const WKPagePolicyClient* policyClient)
124 {
125     m_policyClient.initialize(policyClient);
126 }
127
128 void WebPageProxy::initializeFormClient(const WKPageFormClient* formClient)
129 {
130     m_formClient.initialize(formClient);
131 }
132
133 void WebPageProxy::initializeUIClient(const WKPageUIClient* client)
134 {
135     m_uiClient.initialize(client);
136 }
137
138 void WebPageProxy::revive()
139 {
140     m_valid = true;
141     m_pageNamespace->reviveIfNecessary();
142     m_pageNamespace->process()->addExistingWebPage(this, m_pageID);
143
144     processDidRevive();
145 }
146
147 void WebPageProxy::initializeWebPage(const IntSize& size, PassOwnPtr<DrawingAreaProxy> drawingArea)
148 {
149     if (!isValid()) {
150         puts("initializeWebPage called with a dead WebProcess");
151         revive();
152         return;
153     }
154
155     m_drawingArea = drawingArea;
156     process()->send(WebProcessMessage::Create, m_pageID, CoreIPC::In(size, pageNamespace()->context()->preferences()->store(), *(m_drawingArea.get())));
157 }
158
159 void WebPageProxy::reinitializeWebPage(const WebCore::IntSize& size)
160 {
161     if (!isValid())
162         return;
163
164     ASSERT(m_drawingArea);
165     process()->send(WebProcessMessage::Create, m_pageID, CoreIPC::In(size, pageNamespace()->context()->preferences()->store(), *(m_drawingArea.get())));
166 }
167
168 void WebPageProxy::close()
169 {
170     if (!isValid())
171         return;
172
173     m_closed = true;
174
175     process()->disconnectFramesFromPage(this);
176     m_mainFrame = 0;
177
178     m_pageTitle = String();
179     m_toolTip = String();
180
181     Vector<RefPtr<ScriptReturnValueCallback> > scriptReturnValueCallbacks;
182     copyValuesToVector(m_scriptReturnValueCallbacks, scriptReturnValueCallbacks);
183     for (size_t i = 0, size = scriptReturnValueCallbacks.size(); i < size; ++i)
184         scriptReturnValueCallbacks[i]->invalidate();
185     m_scriptReturnValueCallbacks.clear();
186
187     Vector<RefPtr<RenderTreeExternalRepresentationCallback> > renderTreeExternalRepresentationCallbacks;
188     copyValuesToVector(m_renderTreeExternalRepresentationCallbacks, renderTreeExternalRepresentationCallbacks);
189     for (size_t i = 0, size = renderTreeExternalRepresentationCallbacks.size(); i < size; ++i)
190         renderTreeExternalRepresentationCallbacks[i]->invalidate();
191     m_renderTreeExternalRepresentationCallbacks.clear();
192
193     Vector<RefPtr<FrameSourceCallback> > frameSourceCallbacks;
194     copyValuesToVector(m_frameSourceCallbacks, frameSourceCallbacks);
195     m_frameSourceCallbacks.clear();
196     for (size_t i = 0, size = frameSourceCallbacks.size(); i < size; ++i)
197         frameSourceCallbacks[i]->invalidate();
198
199     Vector<WebEditCommandProxy*> editCommandVector;
200     copyToVector(m_editCommandSet, editCommandVector);
201     m_editCommandSet.clear();
202     for (size_t i = 0, size = editCommandVector.size(); i < size; ++i)
203         editCommandVector[i]->invalidate();
204
205     m_estimatedProgress = 0.0;
206     
207     m_loaderClient.initialize(0);
208     m_policyClient.initialize(0);
209     m_uiClient.initialize(0);
210
211     m_drawingArea.clear();
212
213     process()->send(WebPageMessage::Close, m_pageID, CoreIPC::In());
214     process()->removeWebPage(m_pageID);
215 }
216
217 bool WebPageProxy::tryClose()
218 {
219     if (!isValid())
220         return true;
221
222     process()->send(WebPageMessage::TryClose, m_pageID, CoreIPC::In());
223     return false;
224 }
225
226 void WebPageProxy::loadURL(const String& url)
227 {
228     if (!isValid()) {
229         puts("loadURL called with a dead WebProcess");
230         revive();
231     }
232
233     process()->send(WebPageMessage::LoadURL, m_pageID, CoreIPC::In(url));
234 }
235
236 void WebPageProxy::loadURLRequest(WebURLRequest* urlRequest)
237 {
238     if (!isValid()) {
239         puts("loadURLRequest called with a dead WebProcess");
240         revive();
241     }
242
243     process()->send(WebPageMessage::LoadURLRequest, m_pageID, CoreIPC::In(urlRequest->resourceRequest()));
244 }
245
246 void WebPageProxy::stopLoading()
247 {
248     if (!isValid())
249         return;
250     process()->send(WebPageMessage::StopLoading, m_pageID, CoreIPC::In());
251 }
252
253 void WebPageProxy::reload(bool reloadFromOrigin)
254 {
255     if (!isValid())
256         return;
257     process()->send(WebPageMessage::Reload, m_pageID, CoreIPC::In(reloadFromOrigin));
258 }
259
260 void WebPageProxy::goForward()
261 {
262     if (!isValid())
263         return;
264
265     if (!canGoForward())
266         return;
267
268     process()->send(WebPageMessage::GoForward, m_pageID, CoreIPC::In(m_backForwardList->forwardItem()->itemID()));
269 }
270
271 bool WebPageProxy::canGoForward() const
272 {
273     return m_backForwardList->forwardItem();
274 }
275
276 void WebPageProxy::goBack()
277 {
278     if (!isValid())
279         return;
280
281     if (!canGoBack())
282         return;
283
284     process()->send(WebPageMessage::GoBack, m_pageID, CoreIPC::In(m_backForwardList->backItem()->itemID()));
285 }
286
287 bool WebPageProxy::canGoBack() const
288 {
289     return m_backForwardList->backItem();
290 }
291
292 void WebPageProxy::goToBackForwardItem(WebBackForwardListItem* item)
293 {
294     if (!isValid())
295         return;
296
297     process()->send(WebPageMessage::GoToBackForwardItem, m_pageID, CoreIPC::In(item->itemID()));
298 }
299
300 void WebPageProxy::didChangeBackForwardList()
301 {
302     m_loaderClient.didChangeBackForwardList(this);
303 }
304
305 void WebPageProxy::setFocused(bool isFocused)
306 {
307     if (!isValid())
308         return;
309     process()->send(WebPageMessage::SetFocused, m_pageID, CoreIPC::In(isFocused));
310 }
311
312 void WebPageProxy::setActive(bool active)
313 {
314     if (!isValid())
315         return;
316     process()->send(WebPageMessage::SetActive, m_pageID, CoreIPC::In(active));
317 }
318
319 void WebPageProxy::setIsInWindow(bool isInWindow)
320 {
321     if (m_isInWindow == isInWindow)
322         return;
323     
324     m_isInWindow = isInWindow;
325     if (!isValid())
326         return;
327     process()->send(WebPageMessage::SetIsInWindow, m_pageID, CoreIPC::In(isInWindow));
328 }
329     
330 void WebPageProxy::mouseEvent(const WebMouseEvent& event)
331 {
332     if (!isValid())
333         return;
334
335     // NOTE: This does not start the responsiveness timer because mouse move should not indicate interaction.
336     if (event.type() != WebEvent::MouseMove)
337         process()->responsivenessTimer()->start();
338     process()->send(WebPageMessage::MouseEvent, m_pageID, CoreIPC::In(event));
339 }
340
341 void WebPageProxy::wheelEvent(const WebWheelEvent& event)
342 {
343     if (!isValid())
344         return;
345
346     process()->responsivenessTimer()->start();
347     process()->send(WebPageMessage::WheelEvent, m_pageID, CoreIPC::In(event));
348 }
349
350 void WebPageProxy::keyEvent(const WebKeyboardEvent& event)
351 {
352     if (!isValid())
353         return;
354
355     process()->responsivenessTimer()->start();
356     process()->send(WebPageMessage::KeyEvent, m_pageID, CoreIPC::In(event));
357 }
358
359 #if ENABLE(TOUCH_EVENTS)
360 void WebPageProxy::touchEvent(const WebTouchEvent& event)
361 {
362     if (!isValid())
363         return;
364     process()->send(WebPageMessage::TouchEvent, m_pageID, CoreIPC::In(event)); 
365 }
366 #endif
367
368 void WebPageProxy::receivedPolicyDecision(WebCore::PolicyAction action, WebFrameProxy* frame, uint64_t listenerID)
369 {
370     if (!isValid())
371         return;
372
373     process()->send(WebPageMessage::DidReceivePolicyDecision, m_pageID, CoreIPC::In(frame->frameID(), listenerID, (uint32_t)action));
374 }
375
376 void WebPageProxy::setCustomUserAgent(const String& userAgent)
377 {
378     if (!isValid())
379         return;
380
381     process()->send(WebPageMessage::SetCustomUserAgent, m_pageID, CoreIPC::In(userAgent));
382 }
383
384 void WebPageProxy::terminateProcess()
385 {
386     if (!isValid())
387         return;
388
389     process()->terminate();
390 }
391
392 PassRefPtr<WebData> WebPageProxy::sessionState() const
393 {
394     // FIXME: Return session state data for saving Page state.
395     return 0;
396 }
397
398 void WebPageProxy::restoreFromSessionState(WebData*)
399 {
400     // FIXME: Restore the Page from the passed in session state data.
401 }
402
403 void WebPageProxy::setTextZoomFactor(double zoomFactor)
404 {
405     if (!isValid())
406         return;
407
408     if (m_textZoomFactor == zoomFactor)
409         return;
410
411     m_textZoomFactor = zoomFactor;
412     process()->send(WebPageMessage::SetTextZoomFactor, m_pageID, CoreIPC::In(m_textZoomFactor)); 
413 }
414
415 void WebPageProxy::setPageZoomFactor(double zoomFactor)
416 {
417     if (!isValid())
418         return;
419
420     if (m_pageZoomFactor == zoomFactor)
421         return;
422
423     m_pageZoomFactor = zoomFactor;
424     process()->send(WebPageMessage::SetPageZoomFactor, m_pageID, CoreIPC::In(m_pageZoomFactor)); 
425 }
426
427 void WebPageProxy::setPageAndTextZoomFactors(double pageZoomFactor, double textZoomFactor)
428 {
429     if (!isValid())
430         return;
431
432     if (m_pageZoomFactor == pageZoomFactor && m_textZoomFactor == textZoomFactor)
433         return;
434
435     m_pageZoomFactor = pageZoomFactor;
436     m_textZoomFactor = textZoomFactor;
437     process()->send(WebPageMessage::SetPageAndTextZoomFactors, m_pageID, CoreIPC::In(m_pageZoomFactor, m_textZoomFactor)); 
438 }
439
440 void WebPageProxy::runJavaScriptInMainFrame(const String& script, PassRefPtr<ScriptReturnValueCallback> prpCallback)
441 {
442     RefPtr<ScriptReturnValueCallback> callback = prpCallback;
443     uint64_t callbackID = callback->callbackID();
444     m_scriptReturnValueCallbacks.set(callbackID, callback.get());
445     process()->send(WebPageMessage::RunJavaScriptInMainFrame, m_pageID, CoreIPC::In(script, callbackID));
446 }
447
448 void WebPageProxy::getRenderTreeExternalRepresentation(PassRefPtr<RenderTreeExternalRepresentationCallback> prpCallback)
449 {
450     RefPtr<RenderTreeExternalRepresentationCallback> callback = prpCallback;
451     uint64_t callbackID = callback->callbackID();
452     m_renderTreeExternalRepresentationCallbacks.set(callbackID, callback.get());
453     process()->send(WebPageMessage::GetRenderTreeExternalRepresentation, m_pageID, callbackID);
454 }
455
456 void WebPageProxy::getSourceForFrame(WebFrameProxy* frame, PassRefPtr<FrameSourceCallback> prpCallback)
457 {
458     RefPtr<FrameSourceCallback> callback = prpCallback;
459     uint64_t callbackID = callback->callbackID();
460     m_frameSourceCallbacks.set(callbackID, callback.get());
461     process()->send(WebPageMessage::GetSourceForFrame, m_pageID, CoreIPC::In(frame->frameID(), callbackID));
462 }
463
464 void WebPageProxy::preferencesDidChange()
465 {
466     if (!isValid())
467         return;
468
469     // FIXME: It probably makes more sense to send individual preference changes.
470     // However, WebKitTestRunner depends on getting a preference change notification even if nothing changed in UI process, so that overrides get removed.
471     process()->send(WebPageMessage::PreferencesDidChange, m_pageID, CoreIPC::In(pageNamespace()->context()->preferences()->store()));
472 }
473
474 void WebPageProxy::getStatistics(WKContextStatistics* statistics)
475 {
476     statistics->numberOfWKFrames += process()->frameCountInPage(this);
477 }
478
479 void WebPageProxy::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments)
480 {
481     if (messageID.is<CoreIPC::MessageClassDrawingAreaProxy>()) {
482         m_drawingArea->didReceiveMessage(connection, messageID, arguments);
483         return;
484     }
485
486     switch (messageID.get<WebPageProxyMessage::Kind>()) {
487         case WebPageProxyMessage::DidCreateMainFrame: {
488             uint64_t frameID;
489             if (!arguments->decode(frameID))
490                 return;
491             didCreateMainFrame(frameID);
492             break;
493         }
494         case WebPageProxyMessage::DidCreateSubFrame: {
495             uint64_t frameID;
496             if (!arguments->decode(frameID))
497                 return;
498             didCreateSubFrame(frameID);
499             break;
500         }
501         case WebPageProxyMessage::DidStartProvisionalLoadForFrame: {
502             uint64_t frameID;
503             String url;
504             if (!arguments->decode(CoreIPC::Out(frameID, url)))
505                 return;
506             didStartProvisionalLoadForFrame(process()->webFrame(frameID), url);
507             break;
508         }
509         case WebPageProxyMessage::DidReceiveServerRedirectForProvisionalLoadForFrame: {
510             uint64_t frameID;
511             if (!arguments->decode(frameID))
512                 return;
513             didReceiveServerRedirectForProvisionalLoadForFrame(process()->webFrame(frameID));
514             break;
515         }
516         case WebPageProxyMessage::DidFailProvisionalLoadForFrame: {
517             uint64_t frameID;
518             if (!arguments->decode(frameID))
519                 return;
520             didFailProvisionalLoadForFrame(process()->webFrame(frameID));
521             break;
522         }
523         case WebPageProxyMessage::DidCommitLoadForFrame: {
524             uint64_t frameID;
525             if (!arguments->decode(frameID))
526                 return;
527             didCommitLoadForFrame(process()->webFrame(frameID));
528             break;
529         }
530         case WebPageProxyMessage::DidFinishDocumentLoadForFrame: {
531             uint64_t frameID;
532             if (!arguments->decode(frameID))
533                 return;
534             didFinishDocumentLoadForFrame(process()->webFrame(frameID));
535             break;
536         }
537         case WebPageProxyMessage::DidFinishLoadForFrame: {
538             uint64_t frameID;
539             if (!arguments->decode(frameID))
540                 return;
541             didFinishLoadForFrame(process()->webFrame(frameID));
542             break;
543         }
544         case WebPageProxyMessage::DidFailLoadForFrame: {
545             uint64_t frameID;
546             if (!arguments->decode(frameID))
547                 return;
548             didFailLoadForFrame(process()->webFrame(frameID));
549             break;
550         }
551         case WebPageProxyMessage::DidReceiveTitleForFrame: {
552             uint64_t frameID;
553             String title;
554             if (!arguments->decode(CoreIPC::Out(frameID, title)))
555                 return;
556             didReceiveTitleForFrame(process()->webFrame(frameID), title);
557             break;
558         }
559         case WebPageProxyMessage::DidFirstLayoutForFrame: {
560             uint64_t frameID;
561             if (!arguments->decode(frameID))
562                 return;
563             didFirstLayoutForFrame(process()->webFrame(frameID));
564             break;
565         }
566         case WebPageProxyMessage::DidFirstVisuallyNonEmptyLayoutForFrame: {
567             uint64_t frameID;
568             if (!arguments->decode(frameID))
569                 return;
570             didFirstVisuallyNonEmptyLayoutForFrame(process()->webFrame(frameID));
571             break;
572         }
573         case WebPageProxyMessage::DidStartProgress:
574             didStartProgress();
575             break;
576         case WebPageProxyMessage::DidChangeProgress: {
577             double value;
578             if (!arguments->decode(value))
579                 return;
580             didChangeProgress(value);
581             break;
582         }
583         case WebPageProxyMessage::DidFinishProgress:
584             didFinishProgress();
585             break;
586         case WebPageProxyMessage::DidReceiveEvent: {
587             uint32_t type;
588             if (!arguments->decode(type))
589                 return;
590             didReceiveEvent((WebEvent::Type)type);
591             break;
592         }
593         case WebPageProxyMessage::TakeFocus: {
594             // FIXME: Use enum here.
595             bool direction;
596             if (!arguments->decode(direction))
597                 return;
598             takeFocus(direction);
599             break;
600         }
601         case WebPageProxyMessage::DecidePolicyForNavigationAction: {
602             uint64_t frameID;
603             uint32_t navigationType;
604             uint32_t modifiers;
605             String url;
606             uint64_t listenerID;
607             if (!arguments->decode(CoreIPC::Out(frameID, navigationType, modifiers, url, listenerID)))
608                 return;
609             decidePolicyForNavigationAction(process()->webFrame(frameID), static_cast<NavigationType>(navigationType), static_cast<WebEvent::Modifiers>(modifiers), url, listenerID);
610             break;
611         }
612         case WebPageProxyMessage::DecidePolicyForNewWindowAction: {
613             uint64_t frameID;
614             uint32_t navigationType;
615             uint32_t modifiers;
616             String url;
617             uint64_t listenerID;
618             if (!arguments->decode(CoreIPC::Out(frameID, navigationType, modifiers, url, listenerID)))
619                 return;
620             decidePolicyForNewWindowAction(process()->webFrame(frameID), static_cast<NavigationType>(navigationType), static_cast<WebEvent::Modifiers>(modifiers), url, listenerID);
621             break;
622         }
623         case WebPageProxyMessage::DecidePolicyForMIMEType: {
624             uint64_t frameID;
625             String MIMEType;
626             String url;
627             uint64_t listenerID;
628             if (!arguments->decode(CoreIPC::Out(frameID, MIMEType, url, listenerID)))
629                 return;
630             decidePolicyForMIMEType(process()->webFrame(frameID), MIMEType, url, listenerID);
631             break;
632         }
633         case WebPageProxyMessage::WillSubmitForm: {
634             uint64_t frameID;
635             uint64_t sourceFrameID;
636             Vector<std::pair<String, String> > textFieldValues;
637             uint64_t listenerID;
638
639             RefPtr<APIObject> userData;
640             WebContextUserMessageDecoder messageDecoder(userData, pageNamespace()->context());
641
642             if (!arguments->decode(CoreIPC::Out(frameID, sourceFrameID, textFieldValues, listenerID, messageDecoder)))
643                 return;
644
645             willSubmitForm(process()->webFrame(frameID), process()->webFrame(sourceFrameID), textFieldValues, userData.get(), listenerID);
646             break;
647         }
648         case WebPageProxyMessage::DidRunJavaScriptInMainFrame: {
649             String resultString;
650             uint64_t callbackID;
651             if (!arguments->decode(CoreIPC::Out(resultString, callbackID)))
652                 return;
653             didRunJavaScriptInMainFrame(resultString, callbackID);
654             break;
655         }
656         case WebPageProxyMessage::DidGetRenderTreeExternalRepresentation: {
657             String resultString;
658             uint64_t callbackID;
659             if (!arguments->decode(CoreIPC::Out(resultString, callbackID)))
660                 return;
661             didGetRenderTreeExternalRepresentation(resultString, callbackID);
662             break;
663         }
664         case WebPageProxyMessage::DidGetSourceForFrame: {
665             String resultString;
666             uint64_t callbackID;
667             if (!arguments->decode(CoreIPC::Out(resultString, callbackID)))
668                 return;
669             didGetSourceForFrame(resultString, callbackID);
670             break;
671         }
672         case WebPageProxyMessage::SetToolTip: {
673             String toolTip;
674             if (!arguments->decode(toolTip))
675                 return;
676             setToolTip(toolTip);
677             break;
678         }
679         case WebPageProxyMessage::SetCursor: {
680 #if USE(LAZY_NATIVE_CURSOR)
681             Cursor cursor;
682             if (!arguments->decode(cursor))
683                 return;
684             setCursor(cursor);
685 #endif
686             break;
687         }
688         case WebPageProxyMessage::ShowPage: {
689             showPage();
690             break;
691         }
692         case WebPageProxyMessage::ClosePage: {
693             closePage();
694             break;
695         }
696         case WebPageProxyMessage::BackForwardAddItem: {
697             uint64_t itemID;
698             if (!arguments->decode(CoreIPC::Out(itemID)))
699                 return;
700             addItemToBackForwardList(process()->webBackForwardItem(itemID));
701             break;
702         }
703         case WebPageProxyMessage::BackForwardGoToItem: {
704             uint64_t itemID;
705             if (!arguments->decode(CoreIPC::Out(itemID)))
706                 return;
707             goToItemInBackForwardList(process()->webBackForwardItem(itemID));
708             break;
709         }
710         case WebPageProxyMessage::ContentsSizeChanged: {
711             IntSize size;
712             uint64_t frameID;
713             if (!arguments->decode(CoreIPC::Out(frameID, size)))
714                 return;
715             contentsSizeChanged(process()->webFrame(frameID), size);
716             break;
717         }
718         case WebPageProxyMessage::SetStatusText: {
719             String text;
720             if (!arguments->decode(CoreIPC::Out(text)))
721                 return;
722             setStatusText(text);
723             break;
724         }
725         case WebPageProxyMessage::RegisterEditCommandForUndo: {
726             uint64_t commandID;
727             uint32_t editAction;
728             if (!arguments->decode(CoreIPC::Out(commandID, editAction)))
729                 return;
730                 
731             registerEditCommandForUndo(commandID, static_cast<EditAction>(editAction));
732             break;
733         }
734         case WebPageProxyMessage::ClearAllEditCommands:
735             clearAllEditCommands();
736             break;
737         default:
738             ASSERT_NOT_REACHED();
739             break;
740     }
741 }
742
743 void WebPageProxy::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments, CoreIPC::ArgumentEncoder* reply)
744 {
745     if (messageID.is<CoreIPC::MessageClassDrawingAreaProxy>()) {
746         m_drawingArea->didReceiveSyncMessage(connection, messageID, arguments, reply);
747         return;
748     }
749
750     switch (messageID.get<WebPageProxyMessage::Kind>()) {
751         case WebPageProxyMessage::CreateNewPage: {
752             RefPtr<WebPageProxy> newPage = createNewPage();
753             if (newPage) {
754                 // FIXME: Pass the real size.
755                 reply->encode(CoreIPC::In(newPage->pageID(), IntSize(100, 100), 
756                                           newPage->pageNamespace()->context()->preferences()->store(),
757                                           *(newPage->drawingArea())));
758             } else {
759                 reply->encode(CoreIPC::In(static_cast<uint64_t>(0), IntSize(), WebPreferencesStore(), DrawingAreaBase::DrawingAreaInfo()));
760             }
761             break;
762         }
763         case WebPageProxyMessage::RunJavaScriptAlert: {
764             uint64_t frameID;
765             String message;
766             if (!arguments->decode(CoreIPC::Out(frameID, message)))
767                 return;
768             runJavaScriptAlert(process()->webFrame(frameID), message);
769             break;
770         }
771         case WebPageProxyMessage::RunJavaScriptConfirm: {
772             // FIXME: We should probably encode something in the case that the arguments do not decode correctly.
773             uint64_t frameID;
774             String message;
775             if (!arguments->decode(CoreIPC::Out(frameID, message)))
776                 return;
777
778             bool result = runJavaScriptConfirm(process()->webFrame(frameID), message);
779             reply->encode(CoreIPC::In(result));
780             break;
781         }
782         case WebPageProxyMessage::RunJavaScriptPrompt: {
783             // FIXME: We should probably encode something in the case that the arguments do not decode correctly.
784             uint64_t frameID;
785             String message;
786             String defaultValue;
787             if (!arguments->decode(CoreIPC::Out(frameID, message, defaultValue)))
788                 return;
789
790             String result = runJavaScriptPrompt(process()->webFrame(frameID), message, defaultValue);
791             reply->encode(CoreIPC::In(result));
792             break;
793         }
794
795         case WebPageProxyMessage::BackForwardBackItem: {
796             WebBackForwardListItem* backItem = m_backForwardList->backItem();
797             uint64_t backItemID = backItem ? backItem->itemID() : 0;
798             reply->encode(CoreIPC::In(backItemID));
799             break;
800         }
801         case WebPageProxyMessage::BackForwardCurrentItem: {
802             WebBackForwardListItem* currentItem = m_backForwardList->currentItem();
803             uint64_t currentItemID = currentItem ? currentItem->itemID() : 0;
804             reply->encode(CoreIPC::In(currentItemID));
805             break;
806         }
807         case WebPageProxyMessage::BackForwardForwardItem: {
808             WebBackForwardListItem* forwardItem = m_backForwardList->forwardItem();
809             uint64_t forwardItemID = forwardItem ? forwardItem->itemID() : 0;
810             reply->encode(CoreIPC::In(forwardItemID));
811             break;
812         }
813         case WebPageProxyMessage::BackForwardItemAtIndex: {
814             int itemIndex;
815             if (!arguments->decode(CoreIPC::Out(itemIndex)))
816                 return;
817
818             WebBackForwardListItem* item = m_backForwardList->itemAtIndex(itemIndex);
819             uint64_t itemID = item ? item->itemID() : 0;
820             reply->encode(CoreIPC::In(itemID));
821             break;
822         }
823         case WebPageProxyMessage::BackForwardBackListCount: {
824             int backListCount = m_backForwardList->backListCount();
825             reply->encode(CoreIPC::In(backListCount));
826             break;
827         }
828         case WebPageProxyMessage::BackForwardForwardListCount: {
829             int forwardListCount = m_backForwardList->forwardListCount();
830             reply->encode(CoreIPC::In(forwardListCount));
831             break;
832         }
833 #if USE(ACCELERATED_COMPOSITING)
834         case WebPageProxyMessage::DidChangeAcceleratedCompositing: {
835             bool compositing;
836             if (!arguments->decode(CoreIPC::Out(compositing)))
837                 return;
838
839             didChangeAcceleratedCompositing(compositing);
840             reply->encode(*(drawingArea()));
841             break;
842         }
843 #endif // USE(ACCELERATED_COMPOSITING)
844
845         default:
846             ASSERT_NOT_REACHED();
847             break;
848     }
849 }
850
851 void WebPageProxy::didCreateMainFrame(uint64_t frameID)
852 {
853     ASSERT(!m_mainFrame);
854
855     m_mainFrame = WebFrameProxy::create(this, frameID);
856     process()->frameCreated(frameID, m_mainFrame.get());
857 }
858
859 void WebPageProxy::didCreateSubFrame(uint64_t frameID)
860 {
861     ASSERT(m_mainFrame);
862     process()->frameCreated(frameID, WebFrameProxy::create(this, frameID).get());
863 }
864
865 void WebPageProxy::didStartProgress()
866 {
867     m_estimatedProgress = 0.0;
868     
869     m_loaderClient.didStartProgress(this);
870 }
871
872 void WebPageProxy::didChangeProgress(double value)
873 {
874     m_estimatedProgress = value;
875     
876     m_loaderClient.didChangeProgress(this);
877 }
878
879 void WebPageProxy::didFinishProgress()
880 {
881     m_estimatedProgress = 1.0;
882
883     m_loaderClient.didFinishProgress(this);
884 }
885
886 void WebPageProxy::didStartProvisionalLoadForFrame(WebFrameProxy* frame, const String& url)
887 {
888     frame->didStartProvisionalLoad(url);
889     m_loaderClient.didStartProvisionalLoadForFrame(this, frame);
890 }
891
892 void WebPageProxy::didReceiveServerRedirectForProvisionalLoadForFrame(WebFrameProxy* frame)
893 {
894     m_loaderClient.didReceiveServerRedirectForProvisionalLoadForFrame(this, frame);
895 }
896
897 void WebPageProxy::didFailProvisionalLoadForFrame(WebFrameProxy* frame)
898 {
899     m_loaderClient.didFailProvisionalLoadWithErrorForFrame(this, frame);
900 }
901
902 void WebPageProxy::didCommitLoadForFrame(WebFrameProxy* frame)
903 {
904     frame->didCommitLoad();
905     m_loaderClient.didCommitLoadForFrame(this, frame);
906 }
907
908 void WebPageProxy::didFinishDocumentLoadForFrame(WebFrameProxy* frame)
909 {
910     m_loaderClient.didFinishDocumentLoadForFrame(this, frame);
911 }
912
913 void WebPageProxy::didFinishLoadForFrame(WebFrameProxy* frame)
914 {
915     frame->didFinishLoad();
916     m_loaderClient.didFinishLoadForFrame(this, frame);
917 }
918
919 void WebPageProxy::didFailLoadForFrame(WebFrameProxy* frame)
920 {
921     m_loaderClient.didFailLoadWithErrorForFrame(this, frame);
922 }
923
924 void WebPageProxy::didReceiveTitleForFrame(WebFrameProxy* frame, const String& title)
925 {
926     frame->didReceiveTitle(title);
927
928     // Cache the title for the main frame in the page.
929     if (frame == m_mainFrame)
930         m_pageTitle = title;
931
932     m_loaderClient.didReceiveTitleForFrame(this, title.impl(), frame);
933 }
934
935 void WebPageProxy::didFirstLayoutForFrame(WebFrameProxy* frame)
936 {
937     m_loaderClient.didFirstLayoutForFrame(this, frame);
938 }
939
940 void WebPageProxy::didFirstVisuallyNonEmptyLayoutForFrame(WebFrameProxy* frame)
941 {
942     m_loaderClient.didFirstVisuallyNonEmptyLayoutForFrame(this, frame);
943 }
944
945 // PolicyClient
946
947 void WebPageProxy::decidePolicyForNavigationAction(WebFrameProxy* frame, NavigationType navigationType, WebEvent::Modifiers modifiers, const String& url, uint64_t listenerID)
948 {
949     RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
950     if (!m_policyClient.decidePolicyForNavigationAction(this, navigationType, modifiers, url, frame, listener.get()))
951         listener->use();
952 }
953
954 void WebPageProxy::decidePolicyForNewWindowAction(WebFrameProxy* frame, NavigationType navigationType, WebEvent::Modifiers modifiers, const String& url, uint64_t listenerID)
955 {
956     RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
957     if (!m_policyClient.decidePolicyForNewWindowAction(this, navigationType, modifiers, url, frame, listener.get()))
958         listener->use();
959 }
960
961 void WebPageProxy::decidePolicyForMIMEType(WebFrameProxy* frame, const String& MIMEType, const String& url, uint64_t listenerID)
962 {
963     RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
964     if (!m_policyClient.decidePolicyForMIMEType(this, MIMEType, url, frame, listener.get()))
965         listener->use();
966 }
967
968 // FormClient
969
970 void WebPageProxy::willSubmitForm(WebFrameProxy* frame, WebFrameProxy* sourceFrame, Vector<std::pair<String, String> >& textFieldValues, APIObject* userData, uint64_t listenerID)
971 {
972     RefPtr<WebFormSubmissionListenerProxy> listener = frame->setUpFormSubmissionListenerProxy(listenerID);
973     if (!m_formClient.willSubmitForm(this, frame, sourceFrame, textFieldValues, userData, listener.get()))
974         listener->continueSubmission();
975 }
976
977 // UIClient
978
979 PassRefPtr<WebPageProxy> WebPageProxy::createNewPage()
980 {
981     return m_uiClient.createNewPage(this);
982 }
983     
984 void WebPageProxy::showPage()
985 {
986     m_uiClient.showPage(this);
987 }
988
989 void WebPageProxy::closePage()
990 {
991     m_uiClient.close(this);
992 }
993
994 void WebPageProxy::runJavaScriptAlert(WebFrameProxy* frame, const String& message)
995 {
996     m_uiClient.runJavaScriptAlert(this, message, frame);
997 }
998
999 bool WebPageProxy::runJavaScriptConfirm(WebFrameProxy* frame, const String& message)
1000 {
1001     return m_uiClient.runJavaScriptConfirm(this, message, frame);
1002 }
1003
1004 String WebPageProxy::runJavaScriptPrompt(WebFrameProxy* frame, const String& message, const String& defaultValue)
1005 {
1006     return m_uiClient.runJavaScriptPrompt(this, message, defaultValue, frame);
1007 }
1008
1009 void WebPageProxy::setStatusText(const String& text)
1010 {
1011     m_uiClient.setStatusText(this, text);
1012 }
1013
1014 void WebPageProxy::contentsSizeChanged(WebFrameProxy* frame, const WebCore::IntSize& size)
1015 {
1016     m_uiClient.contentsSizeChanged(this, size, frame);
1017 }
1018
1019 // BackForwardList
1020
1021 void WebPageProxy::addItemToBackForwardList(WebBackForwardListItem* item)
1022 {
1023     m_backForwardList->addItem(item);
1024 }
1025
1026 void WebPageProxy::goToItemInBackForwardList(WebBackForwardListItem* item)
1027 {
1028     m_backForwardList->goToItem(item);
1029 }
1030
1031 // Undo management
1032
1033 void WebPageProxy::registerEditCommandForUndo(uint64_t commandID, EditAction editAction)
1034 {
1035     registerEditCommandForUndo(WebEditCommandProxy::create(commandID, editAction, this));
1036 }
1037
1038 void WebPageProxy::clearAllEditCommands()
1039 {
1040     m_pageClient->clearAllEditCommands();
1041 }
1042
1043 void WebPageProxy::registerEditCommandForUndo(PassRefPtr<WebEditCommandProxy> commandProxy)
1044 {
1045     m_pageClient->registerEditCommand(commandProxy, PageClient::Undo);
1046 }
1047
1048 void WebPageProxy::registerEditCommandForRedo(PassRefPtr<WebEditCommandProxy> commandProxy)
1049 {
1050     m_pageClient->registerEditCommand(commandProxy, PageClient::Redo);
1051 }
1052
1053 void WebPageProxy::addEditCommand(WebEditCommandProxy* command)
1054 {
1055     m_editCommandSet.add(command);
1056 }
1057
1058 void WebPageProxy::removeEditCommand(WebEditCommandProxy* command)
1059 {
1060     m_editCommandSet.remove(command);
1061
1062     if (!isValid())
1063         return;
1064     process()->send(WebPageMessage::DidRemoveEditCommand, m_pageID, command->commandID());
1065 }
1066
1067 // Other
1068
1069 void WebPageProxy::takeFocus(bool direction)
1070 {
1071     m_pageClient->takeFocus(direction);
1072 }
1073
1074 void WebPageProxy::setToolTip(const String& toolTip)
1075 {
1076     String oldToolTip = m_toolTip;
1077     m_toolTip = toolTip;
1078     m_pageClient->toolTipChanged(oldToolTip, m_toolTip);
1079 }
1080
1081 void WebPageProxy::setCursor(const WebCore::Cursor& cursor)
1082 {
1083     m_pageClient->setCursor(cursor);
1084 }
1085
1086 void WebPageProxy::didReceiveEvent(WebEvent::Type type)
1087 {
1088     switch (type) {
1089         case WebEvent::MouseMove:
1090             break;
1091
1092         case WebEvent::MouseDown:
1093         case WebEvent::MouseUp:
1094         case WebEvent::Wheel:
1095         case WebEvent::KeyDown:
1096         case WebEvent::KeyUp:
1097         case WebEvent::RawKeyDown:
1098         case WebEvent::Char:
1099             process()->responsivenessTimer()->stop();
1100             break;
1101     }
1102 }
1103
1104 void WebPageProxy::didRunJavaScriptInMainFrame(const String& resultString, uint64_t callbackID)
1105 {
1106     RefPtr<ScriptReturnValueCallback> callback = m_scriptReturnValueCallbacks.take(callbackID);
1107     if (!callback) {
1108         // FIXME: Log error or assert.
1109         return;
1110     }
1111
1112     callback->performCallbackWithReturnValue(resultString.impl());
1113 }
1114
1115 void WebPageProxy::didGetRenderTreeExternalRepresentation(const String& resultString, uint64_t callbackID)
1116 {
1117     RefPtr<RenderTreeExternalRepresentationCallback> callback = m_renderTreeExternalRepresentationCallbacks.take(callbackID);
1118     if (!callback) {
1119         // FIXME: Log error or assert.
1120         return;
1121     }
1122
1123     callback->performCallbackWithReturnValue(resultString.impl());
1124 }
1125
1126 void WebPageProxy::didGetSourceForFrame(const String& resultString, uint64_t callbackID)
1127 {
1128     RefPtr<FrameSourceCallback> callback = m_frameSourceCallbacks.take(callbackID);
1129     if (!callback) {
1130         // FIXME: Log error or assert.
1131         return;
1132     }
1133
1134     callback->performCallbackWithReturnValue(resultString.impl());
1135 }
1136
1137 #if USE(ACCELERATED_COMPOSITING)
1138 void WebPageProxy::didChangeAcceleratedCompositing(bool compositing)
1139 {
1140     if (compositing)
1141         didEnterAcceleratedCompositing();
1142     else
1143         didLeaveAcceleratedCompositing();
1144 }
1145 #endif
1146
1147 void WebPageProxy::processDidBecomeUnresponsive()
1148 {
1149     m_loaderClient.didBecomeUnresponsive(this);
1150 }
1151
1152 void WebPageProxy::processDidBecomeResponsive()
1153 {
1154     m_loaderClient.didBecomeResponsive(this);
1155 }
1156
1157 void WebPageProxy::processDidExit()
1158 {
1159     ASSERT(m_pageClient);
1160
1161     m_valid = false;
1162
1163     if (m_mainFrame)
1164         m_urlAtProcessExit = m_mainFrame->url();
1165
1166     m_mainFrame = 0;
1167
1168     m_pageTitle = String();
1169     m_toolTip = String();
1170
1171     Vector<RefPtr<ScriptReturnValueCallback> > scriptReturnValueCallbacks;
1172     copyValuesToVector(m_scriptReturnValueCallbacks, scriptReturnValueCallbacks);
1173     for (size_t i = 0, size = scriptReturnValueCallbacks.size(); i < size; ++i)
1174         scriptReturnValueCallbacks[i]->invalidate();
1175     m_scriptReturnValueCallbacks.clear();
1176
1177     Vector<RefPtr<RenderTreeExternalRepresentationCallback> > renderTreeExternalRepresentationCallbacks;
1178     copyValuesToVector(m_renderTreeExternalRepresentationCallbacks, renderTreeExternalRepresentationCallbacks);
1179     for (size_t i = 0, size = renderTreeExternalRepresentationCallbacks.size(); i < size; ++i)
1180         renderTreeExternalRepresentationCallbacks[i]->invalidate();
1181     m_renderTreeExternalRepresentationCallbacks.clear();
1182
1183     Vector<RefPtr<FrameSourceCallback> > frameSourceCallbacks;
1184     copyValuesToVector(m_frameSourceCallbacks, frameSourceCallbacks);
1185     m_frameSourceCallbacks.clear();
1186     for (size_t i = 0, size = frameSourceCallbacks.size(); i < size; ++i)
1187         frameSourceCallbacks[i]->invalidate();
1188
1189     Vector<WebEditCommandProxy*> editCommandVector;
1190     copyToVector(m_editCommandSet, editCommandVector);
1191     m_editCommandSet.clear();
1192     for (size_t i = 0, size = editCommandVector.size(); i < size; ++i)
1193         editCommandVector[i]->invalidate();
1194     m_pageClient->clearAllEditCommands();
1195
1196     m_estimatedProgress = 0.0;
1197
1198     m_pageClient->processDidExit();
1199     m_loaderClient.processDidExit(this);
1200 }
1201
1202 void WebPageProxy::processDidRevive()
1203 {
1204     ASSERT(m_pageClient);
1205     m_pageClient->processDidRevive();
1206 }
1207
1208 #if USE(ACCELERATED_COMPOSITING)
1209 void WebPageProxy::didEnterAcceleratedCompositing()
1210 {
1211     m_pageClient->pageDidEnterAcceleratedCompositing();
1212 }
1213
1214 void WebPageProxy::didLeaveAcceleratedCompositing()
1215 {
1216     m_pageClient->pageDidLeaveAcceleratedCompositing();
1217 }
1218 #endif // USE(ACCELERATED_COMPOSITING)
1219
1220 } // namespace WebKit