summaryrefslogtreecommitdiffstats
path: root/WebCore/history
diff options
context:
space:
mode:
authorUpstream <upstream-import@none>1970-01-12 13:46:40 +0000
committerUpstream <upstream-import@none>1970-01-12 13:46:40 +0000
commitd8543bb6618c17b12da906afa77d216f58cf4058 (patch)
treec58dc05ed86825bd0ef8d305d58c8205106b540f /WebCore/history
downloadexternal_webkit-d8543bb6618c17b12da906afa77d216f58cf4058.zip
external_webkit-d8543bb6618c17b12da906afa77d216f58cf4058.tar.gz
external_webkit-d8543bb6618c17b12da906afa77d216f58cf4058.tar.bz2
external/webkit r30707
Diffstat (limited to 'WebCore/history')
-rw-r--r--WebCore/history/BackForwardList.cpp267
-rw-r--r--WebCore/history/BackForwardList.h90
-rw-r--r--WebCore/history/CachedPage.cpp240
-rw-r--r--WebCore/history/CachedPage.h88
-rw-r--r--WebCore/history/CachedPagePlatformData.h45
-rw-r--r--WebCore/history/HistoryItem.cpp437
-rw-r--r--WebCore/history/HistoryItem.h195
-rw-r--r--WebCore/history/PageCache.cpp183
-rw-r--r--WebCore/history/PageCache.h83
-rw-r--r--WebCore/history/mac/HistoryItemMac.mm65
10 files changed, 1693 insertions, 0 deletions
diff --git a/WebCore/history/BackForwardList.cpp b/WebCore/history/BackForwardList.cpp
new file mode 100644
index 0000000..f912239
--- /dev/null
+++ b/WebCore/history/BackForwardList.cpp
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 2005, 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "BackForwardList.h"
+
+#include "HistoryItem.h"
+#include "Logging.h"
+#include "PageCache.h"
+
+using namespace std;
+
+namespace WebCore {
+
+static const unsigned DefaultCapacity = 100;
+static const unsigned NoCurrentItemIndex = UINT_MAX;
+
+BackForwardList::BackForwardList(Page* page)
+ : m_page(page)
+ , m_current(NoCurrentItemIndex)
+ , m_capacity(DefaultCapacity)
+ , m_closed(true)
+ , m_enabled(true)
+{
+}
+
+BackForwardList::~BackForwardList()
+{
+ ASSERT(m_closed);
+}
+
+void BackForwardList::addItem(PassRefPtr<HistoryItem> prpItem)
+{
+ ASSERT(prpItem);
+ if (m_capacity == 0 || !m_enabled)
+ return;
+
+ // Toss anything in the forward list
+ if (m_current != NoCurrentItemIndex) {
+ unsigned targetSize = m_current + 1;
+ while (m_entries.size() > targetSize) {
+ RefPtr<HistoryItem> item = m_entries.last();
+ m_entries.removeLast();
+ m_entryHash.remove(item);
+ pageCache()->remove(item.get());
+ }
+ }
+
+ // Toss the first item if the list is getting too big, as long as we're not using it
+ // (or even if we are, if we only want 1 entry).
+ if (m_entries.size() == m_capacity && (m_current != 0 || m_capacity == 1)) {
+ RefPtr<HistoryItem> item = m_entries[0];
+ m_entries.remove(0);
+ m_entryHash.remove(item);
+ pageCache()->remove(item.get());
+ m_current--;
+ }
+
+ m_entries.append(prpItem);
+ m_entryHash.add(m_entries.last());
+ m_current++;
+}
+
+void BackForwardList::goBack()
+{
+ ASSERT(m_current > 0);
+ if (m_current > 0)
+ m_current--;
+}
+
+void BackForwardList::goForward()
+{
+ ASSERT(m_current < m_entries.size() - 1);
+ if (m_current < m_entries.size() - 1)
+ m_current++;
+}
+
+void BackForwardList::goToItem(HistoryItem* item)
+{
+ if (!m_entries.size() || !item)
+ return;
+
+ unsigned int index = 0;
+ for (; index < m_entries.size(); ++index)
+ if (m_entries[index] == item)
+ break;
+ if (index < m_entries.size())
+ m_current = index;
+}
+
+HistoryItem* BackForwardList::backItem()
+{
+ if (m_current && m_current != NoCurrentItemIndex)
+ return m_entries[m_current - 1].get();
+ return 0;
+}
+
+HistoryItem* BackForwardList::currentItem()
+{
+ if (m_current != NoCurrentItemIndex)
+ return m_entries[m_current].get();
+ return 0;
+}
+
+HistoryItem* BackForwardList::forwardItem()
+{
+ if (m_entries.size() && m_current < m_entries.size() - 1)
+ return m_entries[m_current + 1].get();
+ return 0;
+}
+
+void BackForwardList::backListWithLimit(int limit, HistoryItemVector& list)
+{
+ list.clear();
+ if (m_current != NoCurrentItemIndex) {
+ unsigned first = max((int)m_current - limit, 0);
+ for (; first < m_current; ++first)
+ list.append(m_entries[first]);
+ }
+}
+
+void BackForwardList::forwardListWithLimit(int limit, HistoryItemVector& list)
+{
+ ASSERT(limit > -1);
+ list.clear();
+ if (!m_entries.size())
+ return;
+
+ unsigned lastEntry = m_entries.size() - 1;
+ if (m_current < lastEntry) {
+ int last = min(m_current + limit, lastEntry);
+ limit = m_current + 1;
+ for (; limit <= last; ++limit)
+ list.append(m_entries[limit]);
+ }
+}
+
+int BackForwardList::capacity()
+{
+ return m_capacity;
+}
+
+void BackForwardList::setCapacity(int size)
+{
+ while (size < (int)m_entries.size()) {
+ RefPtr<HistoryItem> item = m_entries.last();
+ m_entries.removeLast();
+ m_entryHash.remove(item);
+ pageCache()->remove(item.get());
+ }
+
+ if (!size)
+ m_current = NoCurrentItemIndex;
+ else if (m_current > m_entries.size() - 1)
+ m_current = m_entries.size() - 1;
+
+ m_capacity = size;
+}
+
+bool BackForwardList::enabled()
+{
+ return m_enabled;
+}
+
+void BackForwardList::setEnabled(bool enabled)
+{
+ m_enabled = enabled;
+ if (!enabled) {
+ int capacity = m_capacity;
+ setCapacity(0);
+ setCapacity(capacity);
+ }
+}
+
+int BackForwardList::backListCount()
+{
+ return m_current == NoCurrentItemIndex ? 0 : m_current;
+}
+
+int BackForwardList::forwardListCount()
+{
+ return m_current == NoCurrentItemIndex ? 0 : (int)m_entries.size() - (m_current + 1);
+}
+
+HistoryItem* BackForwardList::itemAtIndex(int index)
+{
+ // Do range checks without doing math on index to avoid overflow.
+ if (index < -(int)m_current)
+ return 0;
+
+ if (index > forwardListCount())
+ return 0;
+
+ return m_entries[index + m_current].get();
+}
+
+HistoryItemVector& BackForwardList::entries()
+{
+ return m_entries;
+}
+
+void BackForwardList::close()
+{
+ int size = m_entries.size();
+ for (int i = 0; i < size; ++i)
+ pageCache()->remove(m_entries[i].get());
+ m_entries.clear();
+ m_entryHash.clear();
+ m_page = 0;
+ m_closed = true;
+}
+
+bool BackForwardList::closed()
+{
+ return m_closed;
+}
+
+void BackForwardList::removeItem(HistoryItem* item)
+{
+ if (!item)
+ return;
+
+ for (unsigned i = 0; i < m_entries.size(); ++i)
+ if (m_entries[i] == item) {
+ m_entries.remove(i);
+ m_entryHash.remove(item);
+ if (m_current == NoCurrentItemIndex || m_current < i)
+ break;
+ if (m_current > i)
+ m_current--;
+ else {
+ size_t count = m_entries.size();
+ if (m_current >= count)
+ m_current = count ? count-1 : NoCurrentItemIndex;
+ }
+ break;
+ }
+}
+
+bool BackForwardList::containsItem(HistoryItem* entry)
+{
+ return m_entryHash.contains(entry);
+}
+
+}; // namespace WebCore
diff --git a/WebCore/history/BackForwardList.h b/WebCore/history/BackForwardList.h
new file mode 100644
index 0000000..048778b
--- /dev/null
+++ b/WebCore/history/BackForwardList.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef BackForwardList_h
+#define BackForwardList_h
+
+#include <wtf/RefCounted.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/HashSet.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class HistoryItem;
+class Page;
+
+typedef Vector<RefPtr<HistoryItem> > HistoryItemVector;
+typedef HashSet<RefPtr<HistoryItem> > HistoryItemHashSet;
+
+class BackForwardList : public RefCounted<BackForwardList> {
+public:
+ static PassRefPtr<BackForwardList> create(Page* page) { return adoptRef(new BackForwardList(page)); }
+ ~BackForwardList();
+
+ Page* page() { return m_page; }
+
+ void addItem(PassRefPtr<HistoryItem>);
+ void goBack();
+ void goForward();
+ void goToItem(HistoryItem*);
+
+ HistoryItem* backItem();
+ HistoryItem* currentItem();
+ HistoryItem* forwardItem();
+ HistoryItem* itemAtIndex(int);
+
+ void backListWithLimit(int, HistoryItemVector&);
+ void forwardListWithLimit(int, HistoryItemVector&);
+
+ int capacity();
+ void setCapacity(int);
+ bool enabled();
+ void setEnabled(bool);
+ int backListCount();
+ int forwardListCount();
+ bool containsItem(HistoryItem*);
+
+ void close();
+ bool closed();
+
+ void removeItem(HistoryItem*);
+ HistoryItemVector& entries();
+
+private:
+ BackForwardList(Page*);
+
+ Page* m_page;
+ HistoryItemVector m_entries;
+ HistoryItemHashSet m_entryHash;
+ unsigned m_current;
+ unsigned m_capacity;
+ bool m_closed;
+ bool m_enabled;
+}; //class BackForwardList
+
+}; //namespace WebCore
+
+#endif //BACKFORWARDLIST_H
diff --git a/WebCore/history/CachedPage.cpp b/WebCore/history/CachedPage.cpp
new file mode 100644
index 0000000..e28ab50
--- /dev/null
+++ b/WebCore/history/CachedPage.cpp
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CachedPage.h"
+
+#include "AnimationController.h"
+#include "CachedPagePlatformData.h"
+#include "Document.h"
+#include "DocumentLoader.h"
+#include "Element.h"
+#include "EventHandler.h"
+#include "FocusController.h"
+#include "Frame.h"
+#include "FrameLoader.h"
+#include "FrameView.h"
+#include "GCController.h"
+#include "JSLocation.h"
+#include "Logging.h"
+#include "Page.h"
+#include "PausedTimeouts.h"
+#include "SystemTime.h"
+#if ENABLE(SVG)
+#include "SVGDocumentExtensions.h"
+#endif
+
+#include "kjs_proxy.h"
+#include "kjs_window.h"
+#include <kjs/JSLock.h>
+#include <kjs/SavedBuiltins.h>
+#include <kjs/property_map.h>
+
+using namespace KJS;
+
+namespace WebCore {
+
+#ifndef NDEBUG
+WTFLogChannel LogWebCoreCachedPageLeaks = { 0x00000000, "", WTFLogChannelOn };
+
+struct CachedPageCounter {
+ static int count;
+ ~CachedPageCounter()
+ {
+ if (count)
+ LOG(WebCoreCachedPageLeaks, "LEAK: %d CachedPage\n", count);
+ }
+};
+int CachedPageCounter::count = 0;
+static CachedPageCounter cachedPageCounter;
+#endif
+
+PassRefPtr<CachedPage> CachedPage::create(Page* page)
+{
+ return new CachedPage(page);
+}
+
+CachedPage::CachedPage(Page* page)
+ : RefCounted<CachedPage>(0)
+ , m_timeStamp(0)
+ , m_document(page->mainFrame()->document())
+ , m_view(page->mainFrame()->view())
+ , m_mousePressNode(page->mainFrame()->eventHandler()->mousePressNode())
+ , m_URL(page->mainFrame()->loader()->url())
+ , m_windowProperties(new SavedProperties)
+ , m_locationProperties(new SavedProperties)
+ , m_windowLocalStorage(new SavedProperties)
+ , m_windowBuiltins(new SavedBuiltins)
+{
+#ifndef NDEBUG
+ ++CachedPageCounter::count;
+#endif
+
+ m_document->willSaveToCache();
+
+ Frame* mainFrame = page->mainFrame();
+ Window* window = Window::retrieveWindow(mainFrame);
+
+ mainFrame->clearTimers();
+
+ JSLock lock;
+
+ if (window) {
+ window->saveBuiltins(*m_windowBuiltins.get());
+ window->saveProperties(*m_windowProperties.get());
+ window->saveLocalStorage(*m_windowLocalStorage.get());
+ window->location()->saveProperties(*m_locationProperties.get());
+ m_pausedTimeouts.set(window->pauseTimeouts());
+ }
+
+ m_document->setInPageCache(true);
+
+#if ENABLE(SVG)
+ if (m_document && m_document->svgExtensions())
+ m_document->accessSVGExtensions()->pauseAnimations();
+#endif
+}
+
+CachedPage::~CachedPage()
+{
+#ifndef NDEBUG
+ --CachedPageCounter::count;
+#endif
+
+ clear();
+}
+
+void CachedPage::restore(Page* page)
+{
+ ASSERT(m_document->view() == m_view);
+
+ Frame* mainFrame = page->mainFrame();
+ Window* window = Window::retrieveWindow(mainFrame);
+
+ JSLock lock;
+
+ if (window) {
+ window->restoreBuiltins(*m_windowBuiltins.get());
+ window->restoreProperties(*m_windowProperties.get());
+ window->restoreLocalStorage(*m_windowLocalStorage.get());
+ window->location()->restoreProperties(*m_locationProperties.get());
+ window->resumeTimeouts(m_pausedTimeouts.get());
+ }
+
+#if ENABLE(SVG)
+ if (m_document && m_document->svgExtensions())
+ m_document->accessSVGExtensions()->unpauseAnimations();
+#endif
+
+ mainFrame->animationController()->resumeAnimations();
+
+ mainFrame->eventHandler()->setMousePressNode(mousePressNode());
+
+ // Restore the focus appearance for the focused element.
+ // 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.
+ Document* focusedDocument = page->focusController()->focusedOrMainFrame()->document();
+ if (Node* node = focusedDocument->focusedNode()) {
+ if (node->isElementNode())
+ static_cast<Element*>(node)->updateFocusAppearance(true);
+ }
+}
+
+void CachedPage::clear()
+{
+ if (!m_document)
+ return;
+
+ if (m_cachedPagePlatformData)
+ m_cachedPagePlatformData->clear();
+
+ ASSERT(m_view);
+ ASSERT(m_document->frame() == m_view->frame());
+
+ if (m_document->inPageCache()) {
+ Frame::clearTimers(m_view.get());
+
+ m_document->setInPageCache(false);
+ // FIXME: We don't call willRemove here. Why is that OK?
+ m_document->detach();
+ m_document->removeAllEventListenersFromAllNodes();
+
+ m_view->clearFrame();
+ }
+
+ ASSERT(!m_document->inPageCache());
+
+ m_document = 0;
+ m_view = 0;
+ m_mousePressNode = 0;
+ m_URL = KURL();
+
+ JSLock lock;
+
+ m_windowProperties.clear();
+ m_locationProperties.clear();
+ m_windowBuiltins.clear();
+ m_pausedTimeouts.clear();
+ m_cachedPagePlatformData.clear();
+ m_windowLocalStorage.clear();
+
+ gcController().garbageCollectSoon();
+}
+
+void CachedPage::setDocumentLoader(PassRefPtr<DocumentLoader> loader)
+{
+ m_documentLoader = loader;
+}
+
+DocumentLoader* CachedPage::documentLoader()
+{
+ return m_documentLoader.get();
+}
+
+void CachedPage::setTimeStamp(double timeStamp)
+{
+ m_timeStamp = timeStamp;
+}
+
+void CachedPage::setTimeStampToNow()
+{
+ m_timeStamp = currentTime();
+}
+
+double CachedPage::timeStamp() const
+{
+ return m_timeStamp;
+}
+
+void CachedPage::setCachedPagePlatformData(CachedPagePlatformData* data)
+{
+ m_cachedPagePlatformData.set(data);
+}
+
+CachedPagePlatformData* CachedPage::cachedPagePlatformData()
+{
+ return m_cachedPagePlatformData.get();
+}
+
+} // namespace WebCore
diff --git a/WebCore/history/CachedPage.h b/WebCore/history/CachedPage.h
new file mode 100644
index 0000000..9157b0b
--- /dev/null
+++ b/WebCore/history/CachedPage.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CachedPage_h
+#define CachedPage_h
+
+#include "KURL.h"
+#include <wtf/OwnPtr.h>
+
+namespace KJS {
+ class SavedBuiltins;
+ struct SavedProperties;
+}
+
+namespace WebCore {
+
+ class CachedPagePlatformData;
+ class Document;
+ class DocumentLoader;
+ class FrameView;
+ class Node;
+ class Page;
+ class PausedTimeouts;
+
+class CachedPage : public RefCounted<CachedPage> {
+public:
+ static PassRefPtr<CachedPage> create(Page*);
+ ~CachedPage();
+
+ void clear();
+ Document* document() const { return m_document.get(); }
+ FrameView* view() const { return m_view.get(); }
+ Node* mousePressNode() const { return m_mousePressNode.get(); }
+ const KURL& url() const { return m_URL; }
+ void restore(Page*);
+
+ void setTimeStamp(double);
+ void setTimeStampToNow();
+ double timeStamp() const;
+ void setDocumentLoader(PassRefPtr<DocumentLoader>);
+ DocumentLoader* documentLoader();
+
+ void setCachedPagePlatformData(CachedPagePlatformData*);
+ CachedPagePlatformData* cachedPagePlatformData();
+
+private:
+ CachedPage(Page*);
+ RefPtr<DocumentLoader> m_documentLoader;
+ double m_timeStamp;
+
+ RefPtr<Document> m_document;
+ RefPtr<FrameView> m_view;
+ RefPtr<Node> m_mousePressNode;
+ KURL m_URL;
+ OwnPtr<KJS::SavedProperties> m_windowProperties;
+ OwnPtr<KJS::SavedProperties> m_locationProperties;
+ OwnPtr<KJS::SavedProperties> m_windowLocalStorage;
+ OwnPtr<KJS::SavedBuiltins> m_windowBuiltins;
+ OwnPtr<PausedTimeouts> m_pausedTimeouts;
+ OwnPtr<CachedPagePlatformData> m_cachedPagePlatformData;
+};
+
+} // namespace WebCore
+
+#endif // CachedPage_h
+
diff --git a/WebCore/history/CachedPagePlatformData.h b/WebCore/history/CachedPagePlatformData.h
new file mode 100644
index 0000000..c623f2f
--- /dev/null
+++ b/WebCore/history/CachedPagePlatformData.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef CachedPagePlatformData_h
+#define CachedPagePlatformData_h
+
+namespace WebCore {
+
+// The purpose of this class is to give each platform a vessel to store platform data when a page
+// goes into the Back/Forward page cache, and perform some action with that data when the page comes out.
+// Each platform should subclass this class as neccessary
+
+class CachedPagePlatformData {
+public:
+ virtual ~CachedPagePlatformData() { }
+ virtual void clear() { }
+};
+
+} // namespace WebCore
+
+#endif // CachedPagePlatformData_h
diff --git a/WebCore/history/HistoryItem.cpp b/WebCore/history/HistoryItem.cpp
new file mode 100644
index 0000000..05ee6ec
--- /dev/null
+++ b/WebCore/history/HistoryItem.cpp
@@ -0,0 +1,437 @@
+/*
+ * Copyright (C) 2005, 2006 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "HistoryItem.h"
+
+#include "Document.h"
+#include "FrameLoader.h"
+#include "IconDatabase.h"
+#include "IntSize.h"
+#include "KURL.h"
+#include "Logging.h"
+#include "PageCache.h"
+#include "ResourceRequest.h"
+#include <stdio.h>
+
+namespace WebCore {
+
+static void defaultNotifyHistoryItemChanged() {}
+void (*notifyHistoryItemChanged)() = defaultNotifyHistoryItemChanged;
+
+HistoryItem::HistoryItem()
+ : RefCounted<HistoryItem>(0)
+ , m_lastVisitedTime(0)
+ , m_isInPageCache(false)
+ , m_isTargetItem(false)
+ , m_visitCount(0)
+{
+}
+
+HistoryItem::HistoryItem(const String& urlString, const String& title, double time)
+ : RefCounted<HistoryItem>(0)
+ , m_urlString(urlString)
+ , m_originalURLString(urlString)
+ , m_title(title)
+ , m_lastVisitedTime(time)
+ , m_isInPageCache(false)
+ , m_isTargetItem(false)
+ , m_visitCount(0)
+{
+ iconDatabase()->retainIconForPageURL(m_urlString);
+}
+
+HistoryItem::HistoryItem(const String& urlString, const String& title, const String& alternateTitle, double time)
+ : RefCounted<HistoryItem>(0)
+ , m_urlString(urlString)
+ , m_originalURLString(urlString)
+ , m_title(title)
+ , m_displayTitle(alternateTitle)
+ , m_lastVisitedTime(time)
+ , m_isInPageCache(false)
+ , m_isTargetItem(false)
+ , m_visitCount(0)
+{
+ iconDatabase()->retainIconForPageURL(m_urlString);
+}
+
+HistoryItem::HistoryItem(const KURL& url, const String& title)
+ : RefCounted<HistoryItem>(0)
+ , m_urlString(url.string())
+ , m_originalURLString(url.string())
+ , m_title(title)
+ , m_lastVisitedTime(0)
+ , m_isInPageCache(false)
+ , m_isTargetItem(false)
+ , m_visitCount(0)
+{
+ iconDatabase()->retainIconForPageURL(m_urlString);
+}
+
+HistoryItem::HistoryItem(const KURL& url, const String& target, const String& parent, const String& title)
+ : RefCounted<HistoryItem>(0)
+ , m_urlString(url.string())
+ , m_originalURLString(url.string())
+ , m_target(target)
+ , m_parent(parent)
+ , m_title(title)
+ , m_lastVisitedTime(0)
+ , m_isInPageCache(false)
+ , m_isTargetItem(false)
+ , m_visitCount(0)
+{
+ iconDatabase()->retainIconForPageURL(m_urlString);
+}
+
+HistoryItem::~HistoryItem()
+{
+ ASSERT(!m_isInPageCache);
+ iconDatabase()->releaseIconForPageURL(m_urlString);
+}
+
+HistoryItem::HistoryItem(const HistoryItem& item)
+ : RefCounted<HistoryItem>(0)
+ , m_urlString(item.m_urlString)
+ , m_originalURLString(item.m_originalURLString)
+ , m_target(item.m_target)
+ , m_parent(item.m_parent)
+ , m_title(item.m_title)
+ , m_displayTitle(item.m_displayTitle)
+ , m_lastVisitedTime(item.m_lastVisitedTime)
+ , m_scrollPoint(item.m_scrollPoint)
+ , m_isInPageCache(item.m_isInPageCache)
+ , m_isTargetItem(item.m_isTargetItem)
+ , m_visitCount(item.m_visitCount)
+ , m_formContentType(item.m_formContentType)
+ , m_formReferrer(item.m_formReferrer)
+ , m_rssFeedReferrer(item.m_rssFeedReferrer)
+{
+ if (item.m_formData)
+ m_formData = item.m_formData->copy();
+
+ unsigned size = item.m_subItems.size();
+ m_subItems.reserveCapacity(size);
+ for (unsigned i = 0; i < size; ++i)
+ m_subItems.append(item.m_subItems[i]->copy());
+}
+
+PassRefPtr<HistoryItem> HistoryItem::copy() const
+{
+ return new HistoryItem(*this);
+}
+
+const String& HistoryItem::urlString() const
+{
+ return m_urlString;
+}
+
+// The first URL we loaded to get to where this history item points. Includes both client
+// and server redirects.
+const String& HistoryItem::originalURLString() const
+{
+ return m_originalURLString;
+}
+
+const String& HistoryItem::title() const
+{
+ return m_title;
+}
+
+const String& HistoryItem::alternateTitle() const
+{
+ return m_displayTitle;
+}
+
+Image* HistoryItem::icon() const
+{
+ Image* result = iconDatabase()->iconForPageURL(m_urlString, IntSize(16,16));
+ return result ? result : iconDatabase()->defaultIcon(IntSize(16,16));
+}
+
+double HistoryItem::lastVisitedTime() const
+{
+ return m_lastVisitedTime;
+}
+
+KURL HistoryItem::url() const
+{
+ return KURL(m_urlString);
+}
+
+KURL HistoryItem::originalURL() const
+{
+ return KURL(m_originalURLString);
+}
+
+const String& HistoryItem::target() const
+{
+ return m_target;
+}
+
+const String& HistoryItem::parent() const
+{
+ return m_parent;
+}
+
+void HistoryItem::setAlternateTitle(const String& alternateTitle)
+{
+ m_displayTitle = alternateTitle;
+ notifyHistoryItemChanged();
+}
+
+void HistoryItem::setURLString(const String& urlString)
+{
+ if (m_urlString != urlString) {
+ iconDatabase()->releaseIconForPageURL(m_urlString);
+ m_urlString = urlString;
+ iconDatabase()->retainIconForPageURL(m_urlString);
+ }
+
+ notifyHistoryItemChanged();
+}
+
+void HistoryItem::setURL(const KURL& url)
+{
+ pageCache()->remove(this);
+ setURLString(url.string());
+ clearDocumentState();
+}
+
+void HistoryItem::setOriginalURLString(const String& urlString)
+{
+ m_originalURLString = urlString;
+ notifyHistoryItemChanged();
+}
+
+void HistoryItem::setTitle(const String& title)
+{
+ m_title = title;
+ notifyHistoryItemChanged();
+}
+
+void HistoryItem::setTarget(const String& target)
+{
+ m_target = target;
+ notifyHistoryItemChanged();
+}
+
+void HistoryItem::setParent(const String& parent)
+{
+ m_parent = parent;
+}
+
+void HistoryItem::setLastVisitedTime(double time)
+{
+ if (m_lastVisitedTime != time) {
+ m_lastVisitedTime = time;
+ m_visitCount++;
+ }
+}
+
+int HistoryItem::visitCount() const
+{
+ return m_visitCount;
+}
+
+void HistoryItem::setVisitCount(int count)
+{
+ m_visitCount = count;
+}
+
+const IntPoint& HistoryItem::scrollPoint() const
+{
+ return m_scrollPoint;
+}
+
+void HistoryItem::setScrollPoint(const IntPoint& point)
+{
+ m_scrollPoint = point;
+}
+
+void HistoryItem::clearScrollPoint()
+{
+ m_scrollPoint.setX(0);
+ m_scrollPoint.setY(0);
+}
+
+void HistoryItem::setDocumentState(const Vector<String>& state)
+{
+ m_documentState = state;
+}
+
+const Vector<String>& HistoryItem::documentState() const
+{
+ return m_documentState;
+}
+
+void HistoryItem::clearDocumentState()
+{
+ m_documentState.clear();
+}
+
+bool HistoryItem::isTargetItem() const
+{
+ return m_isTargetItem;
+}
+
+void HistoryItem::setIsTargetItem(bool flag)
+{
+ m_isTargetItem = flag;
+}
+
+void HistoryItem::addChildItem(PassRefPtr<HistoryItem> child)
+{
+ m_subItems.append(child);
+}
+
+HistoryItem* HistoryItem::childItemWithName(const String& name) const
+{
+ unsigned size = m_subItems.size();
+ for (unsigned i = 0; i < size; ++i)
+ if (m_subItems[i]->target() == name)
+ return m_subItems[i].get();
+ return 0;
+}
+
+// <rdar://problem/4895849> HistoryItem::recurseToFindTargetItem() should be replace with a non-recursive method
+HistoryItem* HistoryItem::recurseToFindTargetItem()
+{
+ if (m_isTargetItem)
+ return this;
+ if (!m_subItems.size())
+ return 0;
+
+ HistoryItem* match;
+ unsigned size = m_subItems.size();
+ for (unsigned i = 0; i < size; ++i) {
+ match = m_subItems[i]->recurseToFindTargetItem();
+ if (match)
+ return match;
+ }
+
+ return 0;
+}
+
+HistoryItem* HistoryItem::targetItem()
+{
+ if (!m_subItems.size())
+ return this;
+ return recurseToFindTargetItem();
+}
+
+const HistoryItemVector& HistoryItem::children() const
+{
+ return m_subItems;
+}
+
+bool HistoryItem::hasChildren() const
+{
+ return m_subItems.size();
+}
+
+String HistoryItem::formContentType() const
+{
+ return m_formContentType;
+}
+
+String HistoryItem::formReferrer() const
+{
+ return m_formReferrer;
+}
+
+String HistoryItem::rssFeedReferrer() const
+{
+ return m_rssFeedReferrer;
+}
+
+void HistoryItem::setRSSFeedReferrer(const String& referrer)
+{
+ m_rssFeedReferrer = referrer;
+}
+
+void HistoryItem::setFormInfoFromRequest(const ResourceRequest& request)
+{
+ if (equalIgnoringCase(request.httpMethod(), "POST")) {
+ // FIXME: Eventually we have to make this smart enough to handle the case where
+ // we have a stream for the body to handle the "data interspersed with files" feature.
+ m_formData = request.httpBody();
+ m_formContentType = request.httpContentType();
+ m_formReferrer = request.httpReferrer();
+ } else {
+ m_formData = 0;
+ m_formContentType = String();
+ m_formReferrer = String();
+ }
+}
+
+FormData* HistoryItem::formData()
+{
+ return m_formData.get();
+}
+
+bool HistoryItem::isCurrentDocument(Document* doc) const
+{
+ // FIXME: We should find a better way to check if this is the current document.
+ return urlString() == doc->url();
+}
+
+void HistoryItem::mergeAutoCompleteHints(HistoryItem* otherItem)
+{
+ ASSERT(otherItem);
+ if (otherItem != this)
+ m_visitCount += otherItem->m_visitCount;
+}
+
+#ifndef NDEBUG
+int HistoryItem::showTree() const
+{
+ return showTreeWithIndent(0);
+}
+
+int HistoryItem::showTreeWithIndent(unsigned indentLevel) const
+{
+ String prefix("");
+ int totalSubItems = 0;
+ unsigned i;
+ for (i = 0; i < indentLevel; ++i)
+ prefix.append(" ");
+
+ fprintf(stderr, "%s+-%s (%p)\n", prefix.ascii().data(), m_urlString.ascii().data(), this);
+
+ for (unsigned int i = 0; i < m_subItems.size(); ++i) {
+ totalSubItems += m_subItems[i]->showTreeWithIndent(indentLevel + 1);
+ }
+ return totalSubItems + 1;
+}
+#endif
+
+}; //namespace WebCore
+
+#ifndef NDEBUG
+int showTree(const WebCore::HistoryItem* item)
+{
+ return item->showTree();
+}
+#endif
diff --git a/WebCore/history/HistoryItem.h b/WebCore/history/HistoryItem.h
new file mode 100644
index 0000000..c0650a4
--- /dev/null
+++ b/WebCore/history/HistoryItem.h
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HistoryItem_h
+#define HistoryItem_h
+
+#include "CachedPage.h"
+#include "FormData.h"
+#include "IntPoint.h"
+#include "PlatformString.h"
+#include <wtf/RefCounted.h>
+#include "StringHash.h"
+#include <wtf/HashMap.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/RefPtr.h>
+#include <wtf/Vector.h>
+
+#if PLATFORM(MAC)
+#import <wtf/RetainPtr.h>
+typedef struct objc_object* id;
+#endif
+
+namespace WebCore {
+
+class Document;
+class Image;
+class KURL;
+class ResourceRequest;
+
+class HistoryItem;
+typedef Vector<RefPtr<HistoryItem> > HistoryItemVector;
+
+extern void (*notifyHistoryItemChanged)();
+
+class HistoryItem : public RefCounted<HistoryItem> {
+ friend class PageCache;
+
+public:
+ HistoryItem();
+ HistoryItem(const String& urlString, const String& title, double lastVisited);
+ HistoryItem(const String& urlString, const String& title, const String& alternateTitle, double lastVisited);
+ HistoryItem(const KURL& url, const String& title);
+ HistoryItem(const KURL& url, const String& target, const String& parent, const String& title);
+
+ ~HistoryItem();
+
+ PassRefPtr<HistoryItem> copy() const;
+
+ const String& originalURLString() const;
+ const String& urlString() const;
+ const String& title() const;
+
+ void setInPageCache(bool inPageCache) { m_isInPageCache = inPageCache; }
+ bool isInPageCache() const { return m_isInPageCache; }
+
+ double lastVisitedTime() const;
+
+ void setAlternateTitle(const String& alternateTitle);
+ const String& alternateTitle() const;
+
+ Image* icon() const;
+
+ const String& parent() const;
+ KURL url() const;
+ KURL originalURL() const;
+ const String& target() const;
+ bool isTargetItem() const;
+
+ FormData* formData();
+ String formContentType() const;
+ String formReferrer() const;
+ String rssFeedReferrer() const;
+
+ int visitCount() const;
+
+ void mergeAutoCompleteHints(HistoryItem* otherItem);
+
+ const IntPoint& scrollPoint() const;
+ void setScrollPoint(const IntPoint&);
+ void clearScrollPoint();
+ const Vector<String>& documentState() const;
+ void setDocumentState(const Vector<String>&);
+ void clearDocumentState();
+
+ void setURL(const KURL&);
+ void setURLString(const String&);
+ void setOriginalURLString(const String&);
+ void setTarget(const String&);
+ void setParent(const String&);
+ void setTitle(const String&);
+ void setIsTargetItem(bool);
+
+ void setFormInfoFromRequest(const ResourceRequest&);
+
+ void setRSSFeedReferrer(const String&);
+ void setVisitCount(int);
+
+ void addChildItem(PassRefPtr<HistoryItem>);
+ HistoryItem* childItemWithName(const String&) const;
+ HistoryItem* targetItem();
+ HistoryItem* recurseToFindTargetItem();
+ const HistoryItemVector& children() const;
+ bool hasChildren() const;
+
+ // This should not be called directly for HistoryItems that are already included
+ // in GlobalHistory. The WebKit api for this is to use -[WebHistory setLastVisitedTimeInterval:forItem:] instead.
+ void setLastVisitedTime(double);
+
+ bool isCurrentDocument(Document*) const;
+
+#if PLATFORM(MAC)
+ id viewState() const;
+ void setViewState(id);
+
+ // Transient properties may be of any ObjC type. They are intended to be used to store state per back/forward list entry.
+ // The properties will not be persisted; when the history item is removed, the properties will be lost.
+ id getTransientProperty(const String&) const;
+ void setTransientProperty(const String&, id);
+#endif
+
+#ifndef NDEBUG
+ int showTree() const;
+ int showTreeWithIndent(unsigned indentLevel) const;
+#endif
+
+private:
+ HistoryItem(const HistoryItem&);
+
+ String m_urlString;
+ String m_originalURLString;
+ String m_target;
+ String m_parent;
+ String m_title;
+ String m_displayTitle;
+
+ double m_lastVisitedTime;
+
+ IntPoint m_scrollPoint;
+ Vector<String> m_documentState;
+
+ HistoryItemVector m_subItems;
+
+ bool m_isInPageCache;
+ bool m_isTargetItem;
+ int m_visitCount;
+
+ // info used to repost form data
+ RefPtr<FormData> m_formData;
+ String m_formContentType;
+ String m_formReferrer;
+
+ // info used to support RSS feeds
+ String m_rssFeedReferrer;
+
+ // PageCache controls these fields.
+ HistoryItem* m_next;
+ HistoryItem* m_prev;
+ RefPtr<CachedPage> m_cachedPage;
+
+#if PLATFORM(MAC)
+ RetainPtr<id> m_viewState;
+ OwnPtr<HashMap<String, RetainPtr<id> > > m_transientProperties;
+#endif
+}; //class HistoryItem
+
+} //namespace WebCore
+
+#ifndef NDEBUG
+// Outside the WebCore namespace for ease of invocation from gdb.
+extern "C" int showTree(const WebCore::HistoryItem*);
+#endif
+
+#endif // HISTORYITEM_H
diff --git a/WebCore/history/PageCache.cpp b/WebCore/history/PageCache.cpp
new file mode 100644
index 0000000..dc24fd2
--- /dev/null
+++ b/WebCore/history/PageCache.cpp
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PageCache.h"
+
+#include "Cache.h"
+#include "CachedPage.h"
+#include "FrameLoader.h"
+#include "HistoryItem.h"
+#include "Logging.h"
+#include "SystemTime.h"
+
+using namespace std;
+
+namespace WebCore {
+
+static const double autoreleaseInterval = 3;
+
+PageCache* pageCache()
+{
+ static PageCache* staticPageCache = new PageCache;
+ return staticPageCache;
+}
+
+PageCache::PageCache()
+ : m_capacity(0)
+ , m_size(0)
+ , m_head(0)
+ , m_tail(0)
+ , m_autoreleaseTimer(this, &PageCache::releaseAutoreleasedPagesNowOrReschedule)
+{
+}
+
+void PageCache::setCapacity(int capacity)
+{
+ ASSERT(capacity >= 0);
+ m_capacity = max(capacity, 0);
+
+ prune();
+}
+
+void PageCache::add(PassRefPtr<HistoryItem> prpItem, PassRefPtr<CachedPage> cachedPage)
+{
+ ASSERT(prpItem);
+ ASSERT(cachedPage);
+
+ HistoryItem* item = prpItem.releaseRef(); // Balanced in remove().
+
+ // Remove stale cache entry if necessary.
+ if (item->m_cachedPage)
+ remove(item);
+
+ item->m_cachedPage = cachedPage;
+ addToLRUList(item);
+ ++m_size;
+
+ prune();
+}
+
+void PageCache::remove(HistoryItem* item)
+{
+ // Safely ignore attempts to remove items not in the cache.
+ if (!item || !item->m_cachedPage)
+ return;
+
+ autorelease(item->m_cachedPage.release());
+ removeFromLRUList(item);
+ --m_size;
+
+ item->deref(); // Balanced in add().
+}
+
+void PageCache::prune()
+{
+ while (m_size > m_capacity) {
+ ASSERT(m_tail && m_tail->m_cachedPage);
+ remove(m_tail);
+ }
+}
+
+void PageCache::addToLRUList(HistoryItem* item)
+{
+ item->m_next = m_head;
+ item->m_prev = 0;
+
+ if (m_head) {
+ ASSERT(m_tail);
+ m_head->m_prev = item;
+ } else {
+ ASSERT(!m_tail);
+ m_tail = item;
+ }
+
+ m_head = item;
+}
+
+void PageCache::removeFromLRUList(HistoryItem* item)
+{
+ if (!item->m_next) {
+ ASSERT(item == m_tail);
+ m_tail = item->m_prev;
+ } else {
+ ASSERT(item != m_tail);
+ item->m_next->m_prev = item->m_prev;
+ }
+
+ if (!item->m_prev) {
+ ASSERT(item == m_head);
+ m_head = item->m_next;
+ } else {
+ ASSERT(item != m_head);
+ item->m_prev->m_next = item->m_next;
+ }
+}
+
+void PageCache::releaseAutoreleasedPagesNowOrReschedule(Timer<PageCache>* timer)
+{
+ double loadDelta = currentTime() - FrameLoader::timeOfLastCompletedLoad();
+ float userDelta = userIdleTime();
+
+ // FIXME: <rdar://problem/5211190> This limit of 42 risks growing the page cache far beyond its nominal capacity.
+ if ((userDelta < 0.5 || loadDelta < 1.25) && m_autoreleaseSet.size() < 42) {
+ LOG(PageCache, "WebCorePageCache: Postponing releaseAutoreleasedPagesNowOrReschedule() - %f since last load, %f since last input, %i objects pending release", loadDelta, userDelta, m_autoreleaseSet.size());
+ timer->startOneShot(autoreleaseInterval);
+ return;
+ }
+
+ LOG(PageCache, "WebCorePageCache: Releasing page caches - %f seconds since last load, %f since last input, %i objects pending release", loadDelta, userDelta, m_autoreleaseSet.size());
+ releaseAutoreleasedPagesNow();
+}
+
+void PageCache::releaseAutoreleasedPagesNow()
+{
+ m_autoreleaseTimer.stop();
+
+ // Postpone dead pruning until all our resources have gone dead.
+ cache()->setPruneEnabled(false);
+
+ CachedPageSet tmp;
+ tmp.swap(m_autoreleaseSet);
+
+ CachedPageSet::iterator end = tmp.end();
+ for (CachedPageSet::iterator it = tmp.begin(); it != end; ++it)
+ (*it)->clear();
+
+ // Now do the prune.
+ cache()->setPruneEnabled(true);
+ cache()->prune();
+}
+
+void PageCache::autorelease(PassRefPtr<CachedPage> page)
+{
+ ASSERT(page);
+ ASSERT(!m_autoreleaseSet.contains(page.get()));
+ m_autoreleaseSet.add(page);
+ if (!m_autoreleaseTimer.isActive())
+ m_autoreleaseTimer.startOneShot(autoreleaseInterval);
+}
+
+} // namespace WebCore
diff --git a/WebCore/history/PageCache.h b/WebCore/history/PageCache.h
new file mode 100644
index 0000000..ad15ab6
--- /dev/null
+++ b/WebCore/history/PageCache.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PageCache_h
+#define PageCache_h
+
+#include "HistoryItem.h"
+#include "Timer.h"
+#include <wtf/Forward.h>
+#include <wtf/HashSet.h>
+#include <wtf/Noncopyable.h>
+
+namespace WebCore {
+
+ class CachedPage;
+ class HistoryItem;
+
+ class PageCache : Noncopyable {
+ public:
+ friend PageCache* pageCache();
+
+ void setCapacity(int); // number of pages to cache
+ int capacity() { return m_capacity; }
+
+ void add(PassRefPtr<HistoryItem>, PassRefPtr<CachedPage>); // Prunes if capacity() is exceeded.
+ void remove(HistoryItem*);
+ CachedPage* get(HistoryItem* item) { return item ? item->m_cachedPage.get() : 0; }
+
+ void releaseAutoreleasedPagesNow();
+
+ private:
+ typedef HashSet<RefPtr<CachedPage> > CachedPageSet;
+
+ PageCache(); // Use pageCache() instead.
+ ~PageCache(); // Not implemented to make sure nobody accidentally calls delete -- WebCore does not delete singletons.
+
+ void addToLRUList(HistoryItem*); // Adds to the head of the list.
+ void removeFromLRUList(HistoryItem*);
+
+ void prune();
+
+ void autorelease(PassRefPtr<CachedPage>);
+ void releaseAutoreleasedPagesNowOrReschedule(Timer<PageCache>*);
+
+ int m_capacity;
+ int m_size;
+
+ // LRU List
+ HistoryItem* m_head;
+ HistoryItem* m_tail;
+
+ Timer<PageCache> m_autoreleaseTimer;
+ CachedPageSet m_autoreleaseSet;
+ };
+
+ // Function to obtain the global page cache.
+ PageCache* pageCache();
+
+} // namespace WebCore
+
+#endif // PageCache_h
diff --git a/WebCore/history/mac/HistoryItemMac.mm b/WebCore/history/mac/HistoryItemMac.mm
new file mode 100644
index 0000000..cac9b1b
--- /dev/null
+++ b/WebCore/history/mac/HistoryItemMac.mm
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "HistoryItem.h"
+
+namespace WebCore {
+
+// Notification strings.
+NSString *WebHistoryItemChangedNotification = @"WebHistoryItemChangedNotification";
+
+id HistoryItem::viewState() const
+{
+ return m_viewState.get();
+}
+
+void HistoryItem::setViewState(id statePList)
+{
+ id newState = [statePList copy];
+ m_viewState = newState;
+ [newState release];
+}
+
+id HistoryItem::getTransientProperty(const String& key) const
+{
+ if (!m_transientProperties)
+ return nil;
+ return m_transientProperties->get(key).get();
+}
+
+void HistoryItem::setTransientProperty(const String& key, id value)
+{
+ if (!m_transientProperties)
+ m_transientProperties.set(new HashMap<String, RetainPtr<id> >);
+ if (value == nil)
+ m_transientProperties->remove(key);
+ else
+ m_transientProperties->set(key, value);
+}
+
+} // namespace WebCore
+
+