[iOS] Upstream WebCore/history changes
[WebKit-https.git] / Source / WebCore / history / CachedPage.cpp
1 /*
2  * Copyright (C) 2006, 2007, 2008 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 "FocusController.h"
32 #include "FrameView.h"
33 #include "MainFrame.h"
34 #include "Node.h"
35 #include "Page.h"
36 #include "Settings.h"
37 #include "VisitedLinkState.h"
38 #include <wtf/CurrentTime.h>
39 #include <wtf/RefCountedLeakCounter.h>
40 #include <wtf/StdLibExtras.h>
41
42 #if PLATFORM(IOS)
43 #include "FrameSelection.h"
44 #endif
45
46 using namespace JSC;
47
48 namespace WebCore {
49
50 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, cachedPageCounter, ("CachedPage"));
51
52 PassOwnPtr<CachedPage> CachedPage::create(Page& page)
53 {
54     return adoptPtr(new CachedPage(page));
55 }
56
57 CachedPage::CachedPage(Page& page)
58     : m_timeStamp(monotonicallyIncreasingTime())
59     , m_expirationTime(m_timeStamp + page.settings().backForwardCacheExpirationInterval())
60     , m_cachedMainFrame(CachedFrame::create(page.mainFrame()))
61     , m_needStyleRecalcForVisitedLinks(false)
62     , m_needsFullStyleRecalc(false)
63     , m_needsCaptionPreferencesChanged(false)
64     , m_needsDeviceScaleChanged(false)
65 {
66 #ifndef NDEBUG
67     cachedPageCounter.increment();
68 #endif
69 }
70
71 CachedPage::~CachedPage()
72 {
73 #ifndef NDEBUG
74     cachedPageCounter.decrement();
75 #endif
76
77     destroy();
78     ASSERT(!m_cachedMainFrame);
79 }
80
81 void CachedPage::restore(Page& page)
82 {
83     ASSERT(m_cachedMainFrame);
84     ASSERT(m_cachedMainFrame->view()->frame().isMainFrame());
85     ASSERT(!page.subframeCount());
86
87     m_cachedMainFrame->open();
88     
89     // Restore the focus appearance for the focused element.
90     // 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.
91     Document* focusedDocument = page.focusController().focusedOrMainFrame().document();
92     if (Element* element = focusedDocument->focusedElement()) {
93 #if PLATFORM(IOS)
94         // We don't want focused nodes changing scroll position when restoring from the cache
95         // as it can cause ugly jumps before we manage to restore the cached position.
96         page.mainFrame().selection().suppressScrolling();
97 #endif
98         element->updateFocusAppearance(true);
99 #if PLATFORM(IOS)
100         page.mainFrame().selection().restoreScrolling();
101 #endif
102     }
103
104     if (m_needStyleRecalcForVisitedLinks) {
105         for (Frame* frame = &page.mainFrame(); frame; frame = frame->tree().traverseNext())
106             frame->document()->visitedLinkState().invalidateStyleForAllLinks();
107     }
108
109 #if USE(ACCELERATED_COMPOSITING)
110     if (m_needsDeviceScaleChanged) {
111         page.mainFrame().deviceOrPageScaleFactorChanged();
112     }
113 #endif
114
115     if (m_needsFullStyleRecalc)
116         page.setNeedsRecalcStyleInAllFrames();
117
118 #if ENABLE(VIDEO_TRACK)
119     if (m_needsCaptionPreferencesChanged)
120         page.captionPreferencesChanged();
121 #endif
122
123     clear();
124 }
125
126 void CachedPage::clear()
127 {
128     ASSERT(m_cachedMainFrame);
129     m_cachedMainFrame->clear();
130     m_cachedMainFrame = 0;
131     m_needStyleRecalcForVisitedLinks = false;
132     m_needsFullStyleRecalc = false;
133 }
134
135 void CachedPage::destroy()
136 {
137     if (m_cachedMainFrame)
138         m_cachedMainFrame->destroy();
139
140     m_cachedMainFrame = 0;
141 }
142
143 bool CachedPage::hasExpired() const
144 {
145     return monotonicallyIncreasingTime() > m_expirationTime;
146 }
147
148 } // namespace WebCore