2007-10-20 Rodney Dawes <dobey@wayofthemonkey.com>
[WebKit-https.git] / WebCore / history / CachedPage.cpp
1 /*
2  * Copyright (C) 2006, 2007 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 COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27 #include "CachedPage.h"
28
29 #include "Document.h"
30 #include "Element.h"
31 #include "EventHandler.h"
32 #include "FocusController.h"
33 #include "Frame.h"
34 #include "FrameLoader.h"
35 #include "FrameView.h"
36 #include "GCController.h"
37 #include "Logging.h"
38 #include "Page.h"
39 #include "SystemTime.h"
40 #if ENABLE(SVG)
41 #include "SVGDocumentExtensions.h"
42 #endif
43
44 #include "kjs_proxy.h"
45 #include "kjs_window.h"
46 #include "kjs_window.h"
47 #include <kjs/JSLock.h>
48 #include <kjs/SavedBuiltins.h>
49 #include <kjs/property_map.h>
50
51 using namespace KJS;
52
53 namespace WebCore {
54
55 #ifndef NDEBUG
56 WTFLogChannel LogWebCoreCachedPageLeaks =  { 0x00000000, "", WTFLogChannelOn };
57
58 struct CachedPageCounter { 
59     static int count; 
60     ~CachedPageCounter() 
61     { 
62         if (count)
63             LOG(WebCoreCachedPageLeaks, "LEAK: %d CachedPage\n", count);
64     }
65 };
66 int CachedPageCounter::count = 0;
67 static CachedPageCounter cachedPageCounter;
68 #endif
69
70 PassRefPtr<CachedPage> CachedPage::create(Page* page)
71 {
72     return new CachedPage(page);
73 }
74
75 CachedPage::CachedPage(Page* page)
76     : m_timeStamp(0)
77     , m_document(page->mainFrame()->document())
78     , m_view(page->mainFrame()->view())
79     , m_mousePressNode(page->mainFrame()->eventHandler()->mousePressNode())
80     , m_URL(page->mainFrame()->loader()->url())
81     , m_windowProperties(new SavedProperties)
82     , m_locationProperties(new SavedProperties)
83     , m_interpreterBuiltins(new SavedBuiltins)
84 {
85 #ifndef NDEBUG
86     ++CachedPageCounter::count;
87 #endif
88     
89     Frame* mainFrame = page->mainFrame();
90     KJSProxy* proxy = mainFrame->scriptProxy();
91     KJS::Window* window = KJS::Window::retrieveWindow(mainFrame);
92
93     mainFrame->clearTimers();
94
95     JSLock lock;
96
97     if (proxy && window) {
98         proxy->interpreter()->saveBuiltins(*m_interpreterBuiltins.get());
99         window->saveProperties(*m_windowProperties.get());
100         window->location()->saveProperties(*m_locationProperties.get());
101         m_pausedTimeouts.set(window->pauseTimeouts());
102     }
103
104     m_document->setInPageCache(true);
105
106 #if ENABLE(SVG)
107     if (m_document && m_document->svgExtensions())
108         m_document->accessSVGExtensions()->pauseAnimations();
109 #endif
110 }
111
112 CachedPage::~CachedPage()
113 {
114 #ifndef NDEBUG
115     --CachedPageCounter::count;
116 #endif
117
118     close();
119 }
120
121 void CachedPage::restore(Page* page)
122 {
123     ASSERT(m_document->view() == m_view);
124
125     Frame* mainFrame = page->mainFrame();
126     KJSProxy* proxy = mainFrame->scriptProxy();
127     KJS::Window* window = KJS::Window::retrieveWindow(mainFrame);
128
129     JSLock lock;
130
131     if (proxy && window) {
132         proxy->interpreter()->restoreBuiltins(*m_interpreterBuiltins.get());
133         window->restoreProperties(*m_windowProperties.get());
134         window->location()->restoreProperties(*m_locationProperties.get());
135         window->resumeTimeouts(m_pausedTimeouts.get());
136     }
137
138 #if ENABLE(SVG)
139     if (m_document && m_document->svgExtensions())
140         m_document->accessSVGExtensions()->unpauseAnimations();
141 #endif
142
143     mainFrame->eventHandler()->setMousePressNode(mousePressNode());
144         
145     // Restore the focus appearance for the focused element.
146     // FIXME: Right now we don't support pages w/ frames in the b/f cache.  This may need to be tweaked when we add support for that.
147     Document* focusedDocument = page->focusController()->focusedOrMainFrame()->document();
148     if (Node* node = focusedDocument->focusedNode()) {
149         if (node->isElementNode())
150             static_cast<Element*>(node)->updateFocusAppearance(true);
151     }
152 }
153
154 void CachedPage::clear()
155 {
156     if (!m_document)
157         return;
158
159     ASSERT(m_view);
160     ASSERT(m_document->frame() == m_view->frame());
161
162     if (m_document->inPageCache()) {
163         Frame::clearTimers(m_view.get());
164
165         m_document->setInPageCache(false);
166         // FIXME: We don't call willRemove here. Why is that OK?
167         m_document->detach();
168         m_document->removeAllEventListenersFromAllNodes();
169
170         m_view->clearFrame();
171     }
172
173     ASSERT(!m_document->inPageCache());
174
175     m_document = 0;
176     m_view = 0;
177     m_mousePressNode = 0;
178     m_URL = KURL();
179
180     JSLock lock;
181
182     m_windowProperties.clear();
183     m_locationProperties.clear();
184     m_interpreterBuiltins.clear();
185     m_pausedTimeouts.clear();
186
187     gcController().garbageCollectSoon();
188 }
189
190 void CachedPage::setDocumentLoader(PassRefPtr<DocumentLoader> loader)
191 {
192     m_documentLoader = loader;
193 }
194
195 DocumentLoader* CachedPage::documentLoader()
196 {
197     return m_documentLoader.get();
198 }
199
200 void CachedPage::setTimeStamp(double timeStamp)
201 {
202     m_timeStamp = timeStamp;
203 }
204
205 void CachedPage::setTimeStampToNow()
206 {
207     m_timeStamp = currentTime();
208 }
209
210 double CachedPage::timeStamp() const
211 {
212     return m_timeStamp;
213 }
214
215 } // namespace WebCore