Fix for https://bugs.webkit.org/show_bug.cgi?id=38471
[WebKit-https.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 "WebContext.h"
32 #include "WebCoreTypeArgumentMarshalling.h"
33 #include "WebEvent.h"
34 #include "WebNavigationDataStore.h"
35 #include "WebPageMessageKinds.h"
36 #include "WebPageNamespace.h"
37 #include "WebPageProxyMessageKinds.h"
38 #include "WebPreferences.h"
39 #include "WebProcessManager.h"
40 #include "WebProcessMessageKinds.h"
41 #include "WebProcessProxy.h"
42
43 #include "WKContextPrivate.h"
44
45 #ifndef NDEBUG
46 #include <wtf/RefCountedLeakCounter.h>
47 #endif
48
49 using namespace WebCore;
50
51 namespace WebKit {
52
53 #ifndef NDEBUG
54 static WTF::RefCountedLeakCounter webPageProxyCounter("WebPageProxy");
55 #endif
56
57 PassRefPtr<WebPageProxy> WebPageProxy::create(WebPageNamespace* pageNamespace, uint64_t pageID)
58 {
59     return adoptRef(new WebPageProxy(pageNamespace, pageID));
60 }
61
62 WebPageProxy::WebPageProxy(WebPageNamespace* pageNamespace, uint64_t pageID)
63     : m_pageNamespace(pageNamespace)
64     , m_mainFrame(0)
65     , m_canGoBack(false)
66     , m_canGoForward(false)
67     , m_valid(true)
68     , m_closed(false)
69     , m_pageID(pageID)
70 {
71 #ifndef NDEBUG
72     webPageProxyCounter.increment();
73 #endif
74 }
75
76 WebPageProxy::~WebPageProxy()
77 {
78 #ifndef NDEBUG
79     webPageProxyCounter.decrement();
80 #endif
81 }
82
83 WebProcessProxy* WebPageProxy::process() const
84 {
85     return m_pageNamespace->process();
86 }
87
88 bool WebPageProxy::isValid()
89 {
90     return m_valid;
91 }
92
93 void WebPageProxy::setPageClient(PageClient* pageClient)
94 {
95     m_pageClient.set(pageClient);
96 }
97
98 void WebPageProxy::initializeLoaderClient(WKPageLoaderClient* loadClient)
99 {
100     m_loaderClient.initialize(loadClient);
101 }
102
103 void WebPageProxy::initializePolicyClient(WKPagePolicyClient* policyClient)
104 {
105     m_policyClient.initialize(policyClient);
106 }
107
108 void WebPageProxy::initializeUIClient(WKPageUIClient* client)
109 {
110     m_uiClient.initialize(client);
111 }
112
113 void WebPageProxy::initializeHistoryClient(WKPageHistoryClient* client)
114 {
115     m_historyClient.initialize(client);
116 }
117
118 void WebPageProxy::revive()
119 {
120     m_valid = true;
121     m_pageNamespace->reviveIfNecessary();
122     m_pageNamespace->process()->addExistingWebPage(this, m_pageID);
123
124     processDidRevive();
125 }
126
127 void WebPageProxy::initializeWebPage(const IntSize& size, PassOwnPtr<DrawingAreaProxy> drawingArea)
128 {
129     if (!isValid()) {
130         puts("initializeWebPage called with a dead WebProcess");
131         revive();
132         return;
133     }
134
135     m_drawingArea = drawingArea;
136     process()->connection()->send(WebProcessMessage::Create, m_pageID, CoreIPC::In(size, pageNamespace()->context()->preferences()->store(), *(m_drawingArea.get())));
137 }
138
139 void WebPageProxy::reinitializeWebPage(const WebCore::IntSize& size)
140 {
141     if (!isValid())
142         return;
143
144     ASSERT(m_drawingArea);
145     process()->connection()->send(WebProcessMessage::Create, m_pageID, CoreIPC::In(size, pageNamespace()->context()->preferences()->store(), *(m_drawingArea.get())));
146 }
147
148 void WebPageProxy::close()
149 {
150     if (!isValid())
151         return;
152
153     m_closed = true;
154
155     Vector<RefPtr<WebFrameProxy> > frames;
156     copyValuesToVector(m_frameMap, frames);
157     for (size_t i = 0, size = frames.size(); i < size; ++i)
158         frames[i]->disconnect();
159     m_frameMap.clear();
160     m_mainFrame = 0;
161
162     m_pageTitle = String();
163     m_toolTip = String();
164
165     Vector<RefPtr<ScriptReturnValueCallback> > scriptReturnValueCallbacks;
166     copyValuesToVector(m_scriptReturnValueCallbacks, scriptReturnValueCallbacks);
167     for (size_t i = 0, size = scriptReturnValueCallbacks.size(); i < size; ++i)
168         scriptReturnValueCallbacks[i]->invalidate();
169     m_scriptReturnValueCallbacks.clear();
170
171     Vector<RefPtr<RenderTreeExternalRepresentationCallback> > renderTreeExternalRepresentationCallbacks;
172     copyValuesToVector(m_renderTreeExternalRepresentationCallbacks, renderTreeExternalRepresentationCallbacks);
173     for (size_t i = 0, size = renderTreeExternalRepresentationCallbacks.size(); i < size; ++i)
174         renderTreeExternalRepresentationCallbacks[i]->invalidate();
175     m_renderTreeExternalRepresentationCallbacks.clear();
176
177     m_canGoForward = false;
178     m_canGoBack = false;
179
180     m_loaderClient.initialize(0);
181     m_policyClient.initialize(0);
182     m_uiClient.initialize(0);
183
184     m_drawingArea.clear();
185
186     process()->connection()->send(WebPageMessage::Close, m_pageID, CoreIPC::In());
187     process()->removeWebPage(m_pageID);
188 }
189
190 bool WebPageProxy::tryClose()
191 {
192     if (!isValid())
193         return true;
194
195     process()->connection()->send(WebPageMessage::TryClose, m_pageID, CoreIPC::In());
196     return false;
197 }
198
199 void WebPageProxy::loadURL(const String& url)
200 {
201     if (!isValid()) {
202         puts("loadURL called with a dead WebProcess");
203         revive();
204     }
205     process()->connection()->send(WebPageMessage::LoadURL, m_pageID, CoreIPC::In(url));
206 }
207
208 void WebPageProxy::stopLoading()
209 {
210     if (!isValid())
211         return;
212     process()->connection()->send(WebPageMessage::StopLoading, m_pageID, CoreIPC::In());
213 }
214
215 void WebPageProxy::reload()
216 {
217     if (!isValid())
218         return;
219     process()->connection()->send(WebPageMessage::Reload, m_pageID, CoreIPC::In());
220 }
221
222 void WebPageProxy::goForward()
223 {
224     if (!isValid())
225         return;
226     process()->connection()->send(WebPageMessage::GoForward, m_pageID, CoreIPC::In());
227 }
228
229 void WebPageProxy::goBack()
230 {
231     if (!isValid())
232         return;
233     process()->connection()->send(WebPageMessage::GoBack, m_pageID, CoreIPC::In());
234 }
235
236 void WebPageProxy::setFocused(bool isFocused)
237 {
238     if (!isValid())
239         return;
240     process()->connection()->send(WebPageMessage::SetFocused, m_pageID, CoreIPC::In(isFocused));
241 }
242
243 void WebPageProxy::setActive(bool active)
244 {
245     if (!isValid())
246         return;
247     process()->connection()->send(WebPageMessage::SetActive, m_pageID, CoreIPC::In(active));
248 }
249
250 void WebPageProxy::mouseEvent(const WebMouseEvent& event)
251 {
252     if (!isValid())
253         return;
254
255     // NOTE: This does not start the responsiveness timer because mouse move should not indicate interaction.
256     if (event.type() != WebEvent::MouseMove)
257         process()->responsivenessTimer()->start();
258     process()->connection()->send(WebPageMessage::MouseEvent, m_pageID, CoreIPC::In(event));
259 }
260
261 void WebPageProxy::wheelEvent(const WebWheelEvent& event)
262 {
263     if (!isValid())
264         return;
265
266     process()->responsivenessTimer()->start();
267     process()->connection()->send(WebPageMessage::WheelEvent, m_pageID, CoreIPC::In(event));
268 }
269
270 void WebPageProxy::keyEvent(const WebKeyboardEvent& event)
271 {
272     if (!isValid())
273         return;
274
275     process()->responsivenessTimer()->start();
276     process()->connection()->send(WebPageMessage::KeyEvent, m_pageID, CoreIPC::In(event));
277 }
278
279 void WebPageProxy::receivedPolicyDecision(WebCore::PolicyAction action, WebFrameProxy* frame, uint64_t listenerID)
280 {
281     if (!isValid())
282         return;
283
284     process()->connection()->send(WebPageMessage::DidReceivePolicyDecision, m_pageID, CoreIPC::In(frame->frameID(), listenerID, (uint32_t)action));
285 }
286
287 void WebPageProxy::terminateProcess()
288 {
289     if (!isValid())
290         return;
291
292     process()->terminate();
293 }
294
295 void WebPageProxy::runJavaScriptInMainFrame(const String& script, PassRefPtr<ScriptReturnValueCallback> prpCallback)
296 {
297     RefPtr<ScriptReturnValueCallback> callback = prpCallback;
298     uint64_t callbackID = callback->callbackID();
299     m_scriptReturnValueCallbacks.set(callbackID, callback.get());
300     process()->connection()->send(WebPageMessage::RunJavaScriptInMainFrame, m_pageID, CoreIPC::In(script, callbackID));
301 }
302
303 void WebPageProxy::getRenderTreeExternalRepresentation(PassRefPtr<RenderTreeExternalRepresentationCallback> prpCallback)
304 {
305     RefPtr<RenderTreeExternalRepresentationCallback> callback = prpCallback;
306     uint64_t callbackID = callback->callbackID();
307     m_renderTreeExternalRepresentationCallbacks.set(callbackID, callback.get());
308     process()->connection()->send(WebPageMessage::GetRenderTreeExternalRepresentation, m_pageID, callbackID);
309 }
310
311 void WebPageProxy::preferencesDidChange()
312 {
313     if (!isValid())
314         return;
315
316     // FIXME: It probably makes more sense to send individual preference changes.
317     process()->connection()->send(WebPageMessage::PreferencesDidChange, m_pageID, CoreIPC::In(pageNamespace()->context()->preferences()->store()));
318 }
319
320 void WebPageProxy::getStatistics(WKContextStatistics* statistics)
321 {
322     statistics->numberOfWKFrames += m_frameMap.size();
323 }
324
325 WebFrameProxy* WebPageProxy::webFrame(uint64_t frameID) const
326 {
327     return m_frameMap.get(frameID).get();
328 }
329
330 void WebPageProxy::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder& arguments)
331 {
332     if (messageID.is<CoreIPC::MessageClassDrawingAreaProxy>()) {
333         m_drawingArea->didReceiveMessage(connection, messageID, arguments);
334         return;
335     }
336
337     switch (messageID.get<WebPageProxyMessage::Kind>()) {
338         case WebPageProxyMessage::DidCreateMainFrame: {
339             uint64_t frameID;
340             if (!arguments.decode(frameID))
341                 return;
342             didCreateMainFrame(frameID);
343             break;
344         }
345         case WebPageProxyMessage::DidCreateSubFrame: {
346             uint64_t frameID;
347             if (!arguments.decode(frameID))
348                 return;
349             didCreateSubFrame(frameID);
350             break;
351         }
352         case WebPageProxyMessage::DidStartProvisionalLoadForFrame: {
353             uint64_t frameID;
354             String url;
355             if (!arguments.decode(CoreIPC::Out(frameID, url)))
356                 return;
357             didStartProvisionalLoadForFrame(webFrame(frameID), url);
358             break;
359         }
360         case WebPageProxyMessage::DidReceiveServerRedirectForProvisionalLoadForFrame: {
361             uint64_t frameID;
362             if (!arguments.decode(frameID))
363                 return;
364             didReceiveServerRedirectForProvisionalLoadForFrame(webFrame(frameID));
365             break;
366         }
367         case WebPageProxyMessage::DidFailProvisionalLoadForFrame: {
368             uint64_t frameID;
369             if (!arguments.decode(frameID))
370                 return;
371             didFailProvisionalLoadForFrame(webFrame(frameID));
372             break;
373         }
374         case WebPageProxyMessage::DidCommitLoadForFrame: {
375             uint64_t frameID;
376             if (!arguments.decode(frameID))
377                 return;
378             didCommitLoadForFrame(webFrame(frameID));
379             break;
380         }
381         case WebPageProxyMessage::DidFinishLoadForFrame: {
382             uint64_t frameID;
383             if (!arguments.decode(frameID))
384                 return;
385             didFinishLoadForFrame(webFrame(frameID));
386             break;
387         }
388         case WebPageProxyMessage::DidFailLoadForFrame: {
389             uint64_t frameID;
390             if (!arguments.decode(frameID))
391                 return;
392             didFailLoadForFrame(webFrame(frameID));
393             break;
394         }
395         case WebPageProxyMessage::DidReceiveTitleForFrame: {
396             uint64_t frameID;
397             String title;
398             if (!arguments.decode(CoreIPC::Out(frameID, title)))
399                 return;
400             didReceiveTitleForFrame(webFrame(frameID), title);
401             break;
402         }
403         case WebPageProxyMessage::DidFirstLayoutForFrame: {
404             uint64_t frameID;
405             if (!arguments.decode(frameID))
406                 return;
407             didFirstLayoutForFrame(webFrame(frameID));
408             break;
409         }
410         case WebPageProxyMessage::DidFirstVisuallyNonEmptyLayoutForFrame: {
411             uint64_t frameID;
412             if (!arguments.decode(frameID))
413                 return;
414             didFirstVisuallyNonEmptyLayoutForFrame(webFrame(frameID));
415             break;
416         }
417         case WebPageProxyMessage::DidStartProgress:
418             didStartProgress();
419             break;
420         case WebPageProxyMessage::DidChangeProgress: {
421             double value;
422             if (!arguments.decode(value))
423                 return;
424             didChangeProgress(value);
425             break;
426         }
427         case WebPageProxyMessage::DidFinishProgress:
428             didFinishProgress();
429             break;
430         case WebPageProxyMessage::DidReceiveEvent: {
431             uint32_t type;
432             if (!arguments.decode(type))
433                 return;
434             didReceiveEvent((WebEvent::Type)type);
435             break;
436         }
437         case WebPageProxyMessage::TakeFocus: {
438             // FIXME: Use enum here.
439             bool direction;
440             if (!arguments.decode(direction))
441                 return;
442             takeFocus(direction);
443             break;
444         }
445         case WebPageProxyMessage::DidChangeCanGoBack: {
446             bool canGoBack;
447             if (!arguments.decode(canGoBack))
448                 return;
449             m_canGoBack = canGoBack;
450             break;
451         }
452         case WebPageProxyMessage::DidChangeCanGoForward: {
453             bool canGoForward;
454             if (!arguments.decode(canGoForward))
455                 return;
456             m_canGoForward = canGoForward;
457             break;
458         }
459         case WebPageProxyMessage::DecidePolicyForNavigationAction: {
460             uint64_t frameID;
461             uint32_t navigationType;
462             String url;
463             uint64_t listenerID;
464             if (!arguments.decode(CoreIPC::Out(frameID, navigationType, url, listenerID)))
465                 return;
466             decidePolicyForNavigationAction(webFrame(frameID), navigationType, url, listenerID);
467             break;
468         }
469         case WebPageProxyMessage::DecidePolicyForNewWindowAction: {
470             uint64_t frameID;
471             uint32_t navigationType;
472             String url;
473             uint64_t listenerID;
474             if (!arguments.decode(CoreIPC::Out(frameID, navigationType, url, listenerID)))
475                 return;
476             decidePolicyForNewWindowAction(webFrame(frameID), navigationType, url, listenerID);
477             break;
478         }
479         case WebPageProxyMessage::DecidePolicyForMIMEType: {
480             uint64_t frameID;
481             String MIMEType;
482             String url;
483             uint64_t listenerID;
484             if (!arguments.decode(CoreIPC::Out(frameID, MIMEType, url, listenerID)))
485                 return;
486             decidePolicyForMIMEType(webFrame(frameID), MIMEType, url, listenerID);
487             break;
488         }
489         case WebPageProxyMessage::DidRunJavaScriptInMainFrame: {
490             String resultString;
491             uint64_t callbackID;
492             if (!arguments.decode(CoreIPC::Out(resultString, callbackID)))
493                 return;
494             didRunJavaScriptInMainFrame(resultString, callbackID);
495             break;
496         }
497         case WebPageProxyMessage::DidGetRenderTreeExternalRepresentation: {
498             String resultString;
499             uint64_t callbackID;
500             if (!arguments.decode(CoreIPC::Out(resultString, callbackID)))
501                 return;
502             didGetRenderTreeExternalRepresentation(resultString, callbackID);
503             break;
504         }
505         case WebPageProxyMessage::SetToolTip: {
506             String toolTip;
507             if (!arguments.decode(toolTip))
508                 return;
509             setToolTip(toolTip);
510             break;
511         }
512         case WebPageProxyMessage::ShowPage: {
513             showPage();
514             break;
515         }
516         case WebPageProxyMessage::ClosePage: {
517             closePage();
518             break;
519         }
520         case WebPageProxyMessage::DidNavigateWithNavigationData: {
521             WebNavigationDataStore store;
522             uint64_t frameID;
523             if (!arguments.decode(CoreIPC::Out(store, frameID)))
524                 return;
525             didNavigateWithNavigationData(webFrame(frameID), store);
526             break;
527         }
528         case WebPageProxyMessage::DidPerformClientRedirect: {
529             String sourceURLString;
530             String destinationURLString;
531             uint64_t frameID;
532             if (!arguments.decode(CoreIPC::Out(sourceURLString, destinationURLString, frameID)))
533                 return;
534             didPerformClientRedirect(webFrame(frameID), sourceURLString, destinationURLString);
535             break;
536         }
537         case WebPageProxyMessage::DidPerformServerRedirect: {
538             String sourceURLString;
539             String destinationURLString;
540             uint64_t frameID;
541             if (!arguments.decode(CoreIPC::Out(sourceURLString, destinationURLString, frameID)))
542                 return;
543             didPerformServerRedirect(webFrame(frameID), sourceURLString, destinationURLString);
544             break;
545         }
546         case WebPageProxyMessage::DidUpdateHistoryTitle: {
547             String title;
548             String url;
549             uint64_t frameID;
550             if (!arguments.decode(CoreIPC::Out(title, url, frameID)))
551                 return;
552             didUpdateHistoryTitle(webFrame(frameID), title, url);
553             break;
554         }
555         default:
556             ASSERT_NOT_REACHED();
557             break;
558     }
559 }
560
561 void WebPageProxy::didReceiveSyncMessage(CoreIPC::Connection*, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder& arguments, CoreIPC::ArgumentEncoder& reply)
562 {
563     switch (messageID.get<WebPageProxyMessage::Kind>()) {
564         case WebPageProxyMessage::CreateNewPage: {
565             WebPageProxy* newPage = createNewPage();
566             if (newPage) {
567                 // FIXME: Pass the real size.
568                 reply.encode(CoreIPC::In(newPage->pageID(), IntSize(100, 100), 
569                                          newPage->pageNamespace()->context()->preferences()->store(),
570                                          *(newPage->m_drawingArea.get())));
571             } else {
572                 // FIXME: We should encode a drawing area type here instead.
573                 reply.encode(CoreIPC::In(static_cast<uint64_t>(0), IntSize(), WebPreferencesStore(), 0));
574             }
575             break;
576         }
577         case WebPageProxyMessage::RunJavaScriptAlert: {
578             uint64_t frameID;
579             String alertText;
580             if (!arguments.decode(CoreIPC::Out(frameID, alertText)))
581                 return;
582             runJavaScriptAlert(webFrame(frameID), alertText);
583             break;
584         }
585         default:
586             ASSERT_NOT_REACHED();
587             break;
588     }
589 }
590
591 void WebPageProxy::didCreateMainFrame(uint64_t frameID)
592 {
593     ASSERT(!m_mainFrame);
594     ASSERT(m_frameMap.isEmpty());
595
596     m_mainFrame = WebFrameProxy::create(this, frameID);
597     m_frameMap.set(frameID, m_mainFrame);
598 }
599
600 void WebPageProxy::didCreateSubFrame(uint64_t frameID)
601 {
602     ASSERT(m_mainFrame);
603     ASSERT(!m_frameMap.isEmpty());
604     ASSERT(!m_frameMap.contains(frameID));
605
606     m_frameMap.set(frameID, WebFrameProxy::create(this, frameID));
607 }
608
609 void WebPageProxy::didStartProgress()
610 {
611     m_loaderClient.didStartProgress(this);
612 }
613
614 void WebPageProxy::didChangeProgress(double value)
615 {
616     m_loaderClient.didChangeProgress(this, value);
617 }
618
619 void WebPageProxy::didFinishProgress()
620 {
621     m_loaderClient.didFinishProgress(this);
622 }
623
624 void WebPageProxy::didStartProvisionalLoadForFrame(WebFrameProxy* frame, const String& url)
625 {
626     frame->didStartProvisionalLoad(url);
627     m_loaderClient.didStartProvisionalLoadForFrame(this, frame);
628 }
629
630 void WebPageProxy::didReceiveServerRedirectForProvisionalLoadForFrame(WebFrameProxy* frame)
631 {
632     m_loaderClient.didReceiveServerRedirectForProvisionalLoadForFrame(this, frame);
633 }
634
635 void WebPageProxy::didFailProvisionalLoadForFrame(WebFrameProxy* frame)
636 {
637     m_loaderClient.didFailProvisionalLoadWithErrorForFrame(this, frame);
638 }
639
640 void WebPageProxy::didCommitLoadForFrame(WebFrameProxy* frame)
641 {
642     frame->didCommitLoad();
643     m_loaderClient.didCommitLoadForFrame(this, frame);
644 }
645
646 void WebPageProxy::didFinishLoadForFrame(WebFrameProxy* frame)
647 {
648     frame->didFinishLoad();
649     m_loaderClient.didFinishLoadForFrame(this, frame);
650 }
651
652 void WebPageProxy::didFailLoadForFrame(WebFrameProxy* frame)
653 {
654     m_loaderClient.didFailLoadWithErrorForFrame(this, frame);
655 }
656
657 void WebPageProxy::didReceiveTitleForFrame(WebFrameProxy* frame, const String& title)
658 {
659     frame->didReceiveTitle(title);
660
661     // Cache the title for the main frame in the page.
662     if (frame == m_mainFrame)
663         m_pageTitle = title;
664
665     m_loaderClient.didReceiveTitleForFrame(this, title.impl(), frame);
666 }
667
668 void WebPageProxy::didFirstLayoutForFrame(WebFrameProxy* frame)
669 {
670     m_loaderClient.didFirstLayoutForFrame(this, frame);
671 }
672
673 void WebPageProxy::didFirstVisuallyNonEmptyLayoutForFrame(WebFrameProxy* frame)
674 {
675     m_loaderClient.didFirstVisuallyNonEmptyLayoutForFrame(this, frame);
676 }
677
678 // PolicyClient
679
680 void WebPageProxy::decidePolicyForNavigationAction(WebFrameProxy* frame, uint32_t navigationType, const String& url, uint64_t listenerID)
681 {
682     RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
683     if (!m_policyClient.decidePolicyForNavigationAction(this, navigationType, url, frame, listener.get()))
684         listener->use();
685 }
686
687 void WebPageProxy::decidePolicyForNewWindowAction(WebFrameProxy* frame, uint32_t navigationType, const String& url, uint64_t listenerID)
688 {
689     RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
690     if (!m_policyClient.decidePolicyForNewWindowAction(this, navigationType, url, frame, listener.get()))
691         listener->use();
692 }
693
694 void WebPageProxy::decidePolicyForMIMEType(WebFrameProxy* frame, const String& MIMEType, const String& url, uint64_t listenerID)
695 {
696     RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
697     if (!m_policyClient.decidePolicyForMIMEType(this, MIMEType, url, frame, listener.get()))
698         listener->use();
699 }
700
701 // UIClient
702 WebPageProxy* WebPageProxy::createNewPage()
703 {
704     return m_uiClient.createNewPage(this);
705 }
706     
707 void WebPageProxy::showPage()
708 {
709     m_uiClient.showPage(this);
710 }
711
712 void WebPageProxy::closePage()
713 {
714     m_uiClient.close(this);
715 }
716
717 void WebPageProxy::runJavaScriptAlert(WebFrameProxy* frame, const WebCore::String& alertText)
718 {
719     m_uiClient.runJavaScriptAlert(this, alertText.impl(), frame);
720 }
721
722
723 // HistoryClient
724
725 void WebPageProxy::didNavigateWithNavigationData(WebFrameProxy* frame, const WebNavigationDataStore& store) 
726 {
727     m_historyClient.didNavigateWithNavigationData(this, store, frame);
728 }
729
730 void WebPageProxy::didPerformClientRedirect(WebFrameProxy* frame, const String& sourceURLString, const String& destinationURLString)
731 {
732     m_historyClient.didPerformClientRedirect(this, sourceURLString, destinationURLString, frame);
733 }
734
735 void WebPageProxy::didPerformServerRedirect(WebFrameProxy* frame, const String& sourceURLString, const String& destinationURLString)
736 {
737     m_historyClient.didPerformServerRedirect(this, sourceURLString, destinationURLString, frame);
738 }
739
740 void WebPageProxy::didUpdateHistoryTitle(WebFrameProxy* frame, const String& title, const String& url)
741 {
742     m_historyClient.didUpdateHistoryTitle(this, title, url, frame);
743 }
744
745 // Other
746
747 void WebPageProxy::takeFocus(bool direction)
748 {
749     m_pageClient->takeFocus(direction);
750 }
751
752 void WebPageProxy::setToolTip(const String& toolTip)
753 {
754     String oldToolTip = m_toolTip;
755     m_toolTip = toolTip;
756     m_pageClient->toolTipChanged(oldToolTip, m_toolTip);
757 }
758
759 void WebPageProxy::didReceiveEvent(WebEvent::Type type)
760 {
761     switch (type) {
762         case WebEvent::MouseMove:
763             break;
764
765         case WebEvent::MouseDown:
766         case WebEvent::MouseUp:
767         case WebEvent::Wheel:
768         case WebEvent::KeyDown:
769         case WebEvent::KeyUp:
770         case WebEvent::RawKeyDown:
771         case WebEvent::Char:
772             process()->responsivenessTimer()->stop();
773             break;
774     }
775 }
776
777 void WebPageProxy::didRunJavaScriptInMainFrame(const String& resultString, uint64_t callbackID)
778 {
779     RefPtr<ScriptReturnValueCallback> callback = m_scriptReturnValueCallbacks.take(callbackID);
780     if (!callback) {
781         // FIXME: Log error or assert.
782         return;
783     }
784
785     callback->performCallbackWithReturnValue(resultString.impl());
786 }
787
788 void WebPageProxy::didGetRenderTreeExternalRepresentation(const String& resultString, uint64_t callbackID)
789 {
790     RefPtr<RenderTreeExternalRepresentationCallback> callback = m_renderTreeExternalRepresentationCallbacks.take(callbackID);
791     if (!callback) {
792         // FIXME: Log error or assert.
793         return;
794     }
795
796     callback->performCallbackWithReturnValue(resultString.impl());
797 }
798
799 void WebPageProxy::processDidBecomeUnresponsive()
800 {
801     m_loaderClient.didBecomeUnresponsive(this);
802 }
803
804 void WebPageProxy::processDidBecomeResponsive()
805 {
806     m_loaderClient.didBecomeResponsive(this);
807 }
808
809 void WebPageProxy::processDidExit()
810 {
811     ASSERT(m_pageClient);
812
813     m_valid = false;
814
815     if (m_mainFrame)
816         m_urlAtProcessExit = m_mainFrame->url();
817
818     Vector<RefPtr<WebFrameProxy> > frames;
819     copyValuesToVector(m_frameMap, frames);
820     for (size_t i = 0, size = frames.size(); i < size; ++i)
821         frames[i]->disconnect();
822     m_frameMap.clear();
823     m_mainFrame = 0;
824
825     m_pageTitle = String();
826     m_toolTip = String();
827
828     Vector<RefPtr<ScriptReturnValueCallback> > scriptReturnValueCallbacks;
829     copyValuesToVector(m_scriptReturnValueCallbacks, scriptReturnValueCallbacks);
830     for (size_t i = 0, size = scriptReturnValueCallbacks.size(); i < size; ++i)
831         scriptReturnValueCallbacks[i]->invalidate();
832     m_scriptReturnValueCallbacks.clear();
833
834     Vector<RefPtr<RenderTreeExternalRepresentationCallback> > renderTreeExternalRepresentationCallbacks;
835     copyValuesToVector(m_renderTreeExternalRepresentationCallbacks, renderTreeExternalRepresentationCallbacks);
836     for (size_t i = 0, size = renderTreeExternalRepresentationCallbacks.size(); i < size; ++i)
837         renderTreeExternalRepresentationCallbacks[i]->invalidate();
838     m_renderTreeExternalRepresentationCallbacks.clear();
839
840     m_canGoForward = false;
841     m_canGoBack = false;
842
843     m_pageClient->processDidExit();
844 }
845
846 void WebPageProxy::processDidRevive()
847 {
848     ASSERT(m_pageClient);
849     m_pageClient->processDidRevive();
850 }
851
852 } // namespace WebKit