b245b2bea8bab1ae4177b54b7d55c7d0c417d703
[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 "AnimationController.h"
30 #include "CachedPagePlatformData.h"
31 #include "Document.h"
32 #include "Element.h"
33 #include "EventHandler.h"
34 #include "FocusController.h"
35 #include "Frame.h"
36 #include "FrameLoader.h"
37 #include "FrameView.h"
38 #include "GCController.h"
39 #include "JSLocation.h"
40 #include "Logging.h"
41 #include "Page.h"
42 #include "PausedTimeouts.h"
43 #include "SystemTime.h"
44 #if ENABLE(SVG)
45 #include "SVGDocumentExtensions.h"
46 #endif
47
48 #include "kjs_proxy.h"
49 #include "kjs_window.h"
50 #include <kjs/JSLock.h>
51 #include <kjs/SavedBuiltins.h>
52 #include <kjs/property_map.h>
53
54 using namespace KJS;
55
56 namespace WebCore {
57
58 #ifndef NDEBUG
59 WTFLogChannel LogWebCoreCachedPageLeaks =  { 0x00000000, "", WTFLogChannelOn };
60
61 struct CachedPageCounter { 
62     static int count; 
63     ~CachedPageCounter() 
64     { 
65         if (count)
66             LOG(WebCoreCachedPageLeaks, "LEAK: %d CachedPage\n", count);
67     }
68 };
69 int CachedPageCounter::count = 0;
70 static CachedPageCounter cachedPageCounter;
71 #endif
72
73 PassRefPtr<CachedPage> CachedPage::create(Page* page)
74 {
75     return new CachedPage(page);
76 }
77
78 CachedPage::CachedPage(Page* page)
79     : m_timeStamp(0)
80     , m_document(page->mainFrame()->document())
81     , m_view(page->mainFrame()->view())
82     , m_mousePressNode(page->mainFrame()->eventHandler()->mousePressNode())
83     , m_URL(page->mainFrame()->loader()->url())
84     , m_windowProperties(new SavedProperties)
85     , m_locationProperties(new SavedProperties)
86     , m_windowLocalStorage(new SavedProperties)
87     , m_windowBuiltins(new SavedBuiltins)
88 {
89 #ifndef NDEBUG
90     ++CachedPageCounter::count;
91 #endif
92     
93     m_document->willSaveToCache(); 
94     
95     Frame* mainFrame = page->mainFrame();
96     Window* window = Window::retrieveWindow(mainFrame);
97
98     mainFrame->clearTimers();
99
100     JSLock lock;
101
102     if (window) {
103         window->saveBuiltins(*m_windowBuiltins.get());
104         window->saveProperties(*m_windowProperties.get());
105         window->saveSymbolTable(m_windowSymbolTable);
106         window->saveLocalStorage(*m_windowLocalStorage.get());
107         window->location()->saveProperties(*m_locationProperties.get());
108         m_pausedTimeouts.set(window->pauseTimeouts());
109     }
110
111     m_document->setInPageCache(true);
112
113 #if ENABLE(SVG)
114     if (m_document && m_document->svgExtensions())
115         m_document->accessSVGExtensions()->pauseAnimations();
116 #endif
117 }
118
119 CachedPage::~CachedPage()
120 {
121 #ifndef NDEBUG
122     --CachedPageCounter::count;
123 #endif
124
125     clear();
126 }
127
128 void CachedPage::restore(Page* page)
129 {
130     ASSERT(m_document->view() == m_view);
131
132     Frame* mainFrame = page->mainFrame();
133     Window* window = Window::retrieveWindow(mainFrame);
134
135     JSLock lock;
136
137     if (window) {
138         window->restoreBuiltins(*m_windowBuiltins.get());
139         window->restoreProperties(*m_windowProperties.get());
140         window->restoreSymbolTable(m_windowSymbolTable);
141         window->restoreLocalStorage(*m_windowLocalStorage.get());
142         window->location()->restoreProperties(*m_locationProperties.get());
143         window->resumeTimeouts(m_pausedTimeouts.get());
144     }
145
146 #if ENABLE(SVG)
147     if (m_document && m_document->svgExtensions())
148         m_document->accessSVGExtensions()->unpauseAnimations();
149 #endif
150
151     mainFrame->animationController()->resumeAnimations();
152
153     mainFrame->eventHandler()->setMousePressNode(mousePressNode());
154         
155     // Restore the focus appearance for the focused element.
156     // 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.
157     Document* focusedDocument = page->focusController()->focusedOrMainFrame()->document();
158     if (Node* node = focusedDocument->focusedNode()) {
159         if (node->isElementNode())
160             static_cast<Element*>(node)->updateFocusAppearance(true);
161     }
162 }
163
164 void CachedPage::clear()
165 {
166     if (!m_document)
167         return;
168
169     if (m_cachedPagePlatformData)
170         m_cachedPagePlatformData->clear();
171         
172     ASSERT(m_view);
173     ASSERT(m_document->frame() == m_view->frame());
174
175     if (m_document->inPageCache()) {
176         Frame::clearTimers(m_view.get());
177
178         m_document->setInPageCache(false);
179         // FIXME: We don't call willRemove here. Why is that OK?
180         m_document->detach();
181         m_document->removeAllEventListenersFromAllNodes();
182
183         m_view->clearFrame();
184     }
185
186     ASSERT(!m_document->inPageCache());
187
188     m_document = 0;
189     m_view = 0;
190     m_mousePressNode = 0;
191     m_URL = KURL();
192
193     JSLock lock;
194
195     m_windowProperties.clear();
196     m_locationProperties.clear();
197     m_windowBuiltins.clear();
198     m_pausedTimeouts.clear();
199     m_cachedPagePlatformData.clear();
200     m_windowLocalStorage.clear();
201     m_windowSymbolTable.clear();
202
203     gcController().garbageCollectSoon();
204 }
205
206 void CachedPage::setDocumentLoader(PassRefPtr<DocumentLoader> loader)
207 {
208     m_documentLoader = loader;
209 }
210
211 DocumentLoader* CachedPage::documentLoader()
212 {
213     return m_documentLoader.get();
214 }
215
216 void CachedPage::setTimeStamp(double timeStamp)
217 {
218     m_timeStamp = timeStamp;
219 }
220
221 void CachedPage::setTimeStampToNow()
222 {
223     m_timeStamp = currentTime();
224 }
225
226 double CachedPage::timeStamp() const
227 {
228     return m_timeStamp;
229 }
230
231 void CachedPage::setCachedPagePlatformData(CachedPagePlatformData* data)
232 {
233     m_cachedPagePlatformData.set(data);
234 }
235
236 CachedPagePlatformData* CachedPage::cachedPagePlatformData()
237 {
238     return m_cachedPagePlatformData.get();
239 }
240
241 } // namespace WebCore