• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 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 "CachedFramePlatformData.h"
30 #include "CString.h"
31 #include "DocumentLoader.h"
32 #include "Frame.h"
33 #include "FrameLoaderClient.h"
34 #include "FrameView.h"
35 #include "Logging.h"
36 #include <wtf/RefCountedLeakCounter.h>
37 
38 #if ENABLE(SVG)
39 #include "SVGDocumentExtensions.h"
40 #endif
41 
42 namespace WebCore {
43 
44 #ifndef NDEBUG
cachedFrameCounter()45 static WTF::RefCountedLeakCounter& cachedFrameCounter()
46 {
47     DEFINE_STATIC_LOCAL(WTF::RefCountedLeakCounter, counter, ("CachedFrame"));
48     return counter;
49 }
50 #endif
51 
CachedFrame(Frame * frame)52 CachedFrame::CachedFrame(Frame* frame)
53     : m_document(frame->document())
54     , m_documentLoader(frame->loader()->documentLoader())
55     , m_view(frame->view())
56     , m_mousePressNode(frame->eventHandler()->mousePressNode())
57     , m_url(frame->loader()->url())
58 {
59 #ifndef NDEBUG
60     cachedFrameCounter().increment();
61 #endif
62     ASSERT(m_document);
63     ASSERT(m_documentLoader);
64     ASSERT(m_view);
65 
66     // Active DOM objects must be suspended before we cached the frame script data
67     m_document->suspendActiveDOMObjects();
68     m_cachedFrameScriptData.set(new ScriptCachedFrameData(frame));
69 
70     m_document->documentWillBecomeInactive();
71     frame->clearTimers();
72     m_document->setInPageCache(true);
73 
74     frame->loader()->client()->savePlatformDataToCachedFrame(this);
75 
76     for (Frame* child = frame->tree()->firstChild(); child; child = child->tree()->nextSibling())
77         m_childFrames.append(CachedFrame::create(child));
78 
79     LOG(PageCache, "Finished creating CachedFrame with url %s and documentloader %p\n", m_url.string().utf8().data(), m_documentLoader.get());
80 }
81 
~CachedFrame()82 CachedFrame::~CachedFrame()
83 {
84 #ifndef NDEBUG
85     cachedFrameCounter().decrement();
86 #endif
87 
88     clear();
89 }
90 
restore()91 void CachedFrame::restore()
92 {
93     ASSERT(m_document->view() == m_view);
94 
95     Frame* frame = m_view->frame();
96     m_cachedFrameScriptData->restore(frame);
97 
98 #if ENABLE(SVG)
99     if (m_document->svgExtensions())
100         m_document->accessSVGExtensions()->unpauseAnimations();
101 #endif
102 
103     frame->animation()->resumeAnimations(m_document.get());
104     frame->eventHandler()->setMousePressNode(mousePressNode());
105     m_document->resumeActiveDOMObjects();
106 
107     // It is necessary to update any platform script objects after restoring the
108     // cached page.
109     frame->script()->updatePlatformScriptObjects();
110 }
111 
clear()112 void CachedFrame::clear()
113 {
114     if (!m_document)
115         return;
116 
117     if (m_cachedFramePlatformData)
118         m_cachedFramePlatformData->clear();
119 
120     ASSERT(m_view);
121     ASSERT(m_document->frame() == m_view->frame());
122 
123     if (m_document->inPageCache()) {
124         Frame::clearTimers(m_view.get(), m_document.get());
125 
126         // FIXME: Why do we need to call removeAllEventListeners here? When the document is in page cache, this method won't work
127         // fully anyway, because the document won't be able to access its DOMWindow object (due to being frameless).
128         m_document->removeAllEventListeners();
129 
130         m_document->setInPageCache(false);
131         // FIXME: We don't call willRemove here. Why is that OK?
132         m_document->detach();
133         m_view->clearFrame();
134     }
135 
136     ASSERT(!m_document->inPageCache());
137 
138     m_document = 0;
139     m_view = 0;
140     m_mousePressNode = 0;
141     m_url = KURL();
142 
143     m_cachedFramePlatformData.clear();
144 
145     m_cachedFrameScriptData.clear();
146 }
147 
setCachedFramePlatformData(CachedFramePlatformData * data)148 void CachedFrame::setCachedFramePlatformData(CachedFramePlatformData* data)
149 {
150     m_cachedFramePlatformData.set(data);
151 }
152 
cachedFramePlatformData()153 CachedFramePlatformData* CachedFrame::cachedFramePlatformData()
154 {
155     return m_cachedFramePlatformData.get();
156 }
157 
descendantFrameCount() const158 int CachedFrame::descendantFrameCount() const
159 {
160     int count = m_childFrames.size();
161     for (size_t i = 0; i < m_childFrames.size(); ++i)
162         count += m_childFrames[i]->descendantFrameCount();
163 
164     return count;
165 }
166 
167 } // namespace WebCore
168