diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-05 14:34:32 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-05 14:34:32 -0800 |
commit | 635860845790a19bf50bbc51ba8fb66a96dde068 (patch) | |
tree | ef6ad9ff73a5b57f65249d4232a202fa77e6a140 /WebCore/history | |
parent | 8e35f3cfc7fba1d1c829dc557ebad6409cbe16a2 (diff) | |
download | external_webkit-635860845790a19bf50bbc51ba8fb66a96dde068.zip external_webkit-635860845790a19bf50bbc51ba8fb66a96dde068.tar.gz external_webkit-635860845790a19bf50bbc51ba8fb66a96dde068.tar.bz2 |
auto import from //depot/cupcake/@136594
Diffstat (limited to 'WebCore/history')
-rw-r--r-- | WebCore/history/BackForwardList.cpp | 15 | ||||
-rw-r--r-- | WebCore/history/BackForwardList.h | 37 | ||||
-rw-r--r-- | WebCore/history/BackForwardListChromium.cpp | 141 | ||||
-rw-r--r-- | WebCore/history/CachedFrame.cpp | 133 | ||||
-rw-r--r-- | WebCore/history/CachedFrame.h | 73 | ||||
-rw-r--r-- | WebCore/history/CachedFramePlatformData.h (renamed from WebCore/history/CachedPagePlatformData.h) | 10 | ||||
-rw-r--r-- | WebCore/history/CachedPage.cpp | 144 | ||||
-rw-r--r-- | WebCore/history/CachedPage.h | 49 | ||||
-rw-r--r-- | WebCore/history/HistoryItem.cpp | 184 | ||||
-rw-r--r-- | WebCore/history/HistoryItem.h | 63 | ||||
-rw-r--r-- | WebCore/history/PageCache.cpp | 1 | ||||
-rw-r--r-- | WebCore/history/mac/HistoryItemMac.mm | 24 |
12 files changed, 626 insertions, 248 deletions
diff --git a/WebCore/history/BackForwardList.cpp b/WebCore/history/BackForwardList.cpp index 3bd7a06..e747a33 100644 --- a/WebCore/history/BackForwardList.cpp +++ b/WebCore/history/BackForwardList.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2005, 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -304,4 +305,18 @@ bool BackForwardList::containsItem(HistoryItem* entry) return m_entryHash.contains(entry); } +#if ENABLE(WML) +void BackForwardList::clearWmlPageHistory() +{ + PassRefPtr<HistoryItem> cur = currentItem(); + + for (unsigned i = 0; i < m_entries.size(); ++i) + pageCache()->remove(m_entries[i].get()); + + m_entries.clear(); + m_entryHash.clear(); + m_current = NoCurrentItemIndex; +} +#endif + }; // namespace WebCore diff --git a/WebCore/history/BackForwardList.h b/WebCore/history/BackForwardList.h index 048778b..a99d387 100644 --- a/WebCore/history/BackForwardList.h +++ b/WebCore/history/BackForwardList.h @@ -1,5 +1,7 @@ /* * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) + * Copyright (C) 2009 Google, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -39,10 +41,31 @@ class Page; typedef Vector<RefPtr<HistoryItem> > HistoryItemVector; typedef HashSet<RefPtr<HistoryItem> > HistoryItemHashSet; +#if PLATFORM(CHROMIUM) +// In the Chromium port, the back/forward list is managed externally. +// See BackForwardListChromium.cpp +class BackForwardListClient { +public: + virtual ~BackForwardListClient() {} + virtual void addItem(PassRefPtr<HistoryItem>) = 0; + virtual void goToItem(HistoryItem*) = 0; + virtual HistoryItem* currentItem() = 0; + virtual HistoryItem* itemAtIndex(int) = 0; + virtual int backListCount() = 0; + virtual int forwardListCount() = 0; + virtual void close() = 0; +}; +#endif + class BackForwardList : public RefCounted<BackForwardList> { public: static PassRefPtr<BackForwardList> create(Page* page) { return adoptRef(new BackForwardList(page)); } ~BackForwardList(); + +#if PLATFORM(CHROMIUM) + // Must be called before any other methods. + void setClient(BackForwardListClient* client) { m_client = client; } +#endif Page* page() { return m_page; } @@ -73,18 +96,26 @@ public: void removeItem(HistoryItem*); HistoryItemVector& entries(); +#if ENABLE(WML) + void clearWmlPageHistory(); +#endif + private: BackForwardList(Page*); Page* m_page; +#if PLATFORM(CHROMIUM) + BackForwardListClient* m_client; +#else HistoryItemVector m_entries; HistoryItemHashSet m_entryHash; unsigned m_current; +#endif unsigned m_capacity; bool m_closed; bool m_enabled; -}; //class BackForwardList +}; -}; //namespace WebCore +} //namespace WebCore -#endif //BACKFORWARDLIST_H +#endif diff --git a/WebCore/history/BackForwardListChromium.cpp b/WebCore/history/BackForwardListChromium.cpp new file mode 100644 index 0000000..011f987 --- /dev/null +++ b/WebCore/history/BackForwardListChromium.cpp @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2005, 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) + * Copyright (c) 2009, Google 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" + +namespace WebCore { + +static const unsigned DefaultCapacity = 100; +static const unsigned NoCurrentItemIndex = UINT_MAX; + +BackForwardList::BackForwardList(Page* page) + : m_page(page) + , 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; + + m_client->addItem(prpItem); +} + +void BackForwardList::goToItem(HistoryItem* item) +{ + m_client->goToItem(item); +} + +HistoryItem* BackForwardList::backItem() +{ + ASSERT_NOT_REACHED(); + return 0; +} + +HistoryItem* BackForwardList::forwardItem() +{ + ASSERT_NOT_REACHED(); + return 0; +} + +HistoryItem* BackForwardList::currentItem() +{ + return m_client->currentItem(); +} + +int BackForwardList::capacity() +{ + return m_capacity; +} + +void BackForwardList::setCapacity(int size) +{ + 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_client->backListCount(); +} + +int BackForwardList::forwardListCount() +{ + return m_client->forwardListCount(); +} + +HistoryItem* BackForwardList::itemAtIndex(int index) +{ + return m_client->itemAtIndex(index); +} + +HistoryItemVector& BackForwardList::entries() +{ + static HistoryItemVector noEntries; + return noEntries; +} + +void BackForwardList::close() +{ + m_client->close(); + m_page = 0; + m_closed = true; +} + +bool BackForwardList::closed() +{ + return m_closed; +} + +} // namespace WebCore diff --git a/WebCore/history/CachedFrame.cpp b/WebCore/history/CachedFrame.cpp new file mode 100644 index 0000000..ed7e9eb --- /dev/null +++ b/WebCore/history/CachedFrame.cpp @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2009 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 "CachedFramePlatformData.h" +#include "DocumentLoader.h" +#include "Frame.h" +#include "FrameView.h" +#include <wtf/RefCountedLeakCounter.h> + +#if ENABLE(SVG) +#include "SVGDocumentExtensions.h" +#endif + +namespace WebCore { + +#ifndef NDEBUG +static WTF::RefCountedLeakCounter& cachedFrameCounter() +{ + DEFINE_STATIC_LOCAL(WTF::RefCountedLeakCounter, counter, ("CachedFrame")); + return counter; +} +#endif + +CachedFrame::CachedFrame(Frame* frame) + : m_document(frame->document()) + , m_documentLoader(frame->loader()->documentLoader()) + , m_view(frame->view()) + , m_mousePressNode(frame->eventHandler()->mousePressNode()) + , m_URL(frame->loader()->url()) + , m_cachedFrameScriptData(frame) +{ +#ifndef NDEBUG + cachedFrameCounter().increment(); +#endif + m_document->documentWillBecomeInactive(); + frame->clearTimers(); + m_document->setInPageCache(true); +} + +CachedFrame::~CachedFrame() +{ +#ifndef NDEBUG + cachedFrameCounter().decrement(); +#endif + + clear(); +} + +void CachedFrame::restore(Frame* frame) +{ + ASSERT(m_document->view() == m_view); + + m_cachedFrameScriptData.restore(frame); + +#if ENABLE(SVG) + if (m_document && m_document->svgExtensions()) + m_document->accessSVGExtensions()->unpauseAnimations(); +#endif + + frame->animation()->resumeAnimations(m_document.get()); + frame->eventHandler()->setMousePressNode(mousePressNode()); +} + +void CachedFrame::clear() +{ + if (!m_document) + return; + + if (m_cachedFramePlatformData) + m_cachedFramePlatformData->clear(); + + ASSERT(m_view); + ASSERT(m_document->frame() == m_view->frame()); + + if (m_document->inPageCache()) { + Frame::clearTimers(m_view.get(), m_document.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(); + + m_cachedFramePlatformData.clear(); + + m_cachedFrameScriptData.clear(); +} + +void CachedFrame::setCachedFramePlatformData(CachedFramePlatformData* data) +{ + m_cachedFramePlatformData.set(data); +} + +CachedFramePlatformData* CachedFrame::cachedFramePlatformData() +{ + return m_cachedFramePlatformData.get(); +} + +} // namespace WebCore diff --git a/WebCore/history/CachedFrame.h b/WebCore/history/CachedFrame.h new file mode 100644 index 0000000..c7beb15 --- /dev/null +++ b/WebCore/history/CachedFrame.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2009 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 CachedFrame_h +#define CachedFrame_h + +#include "KURL.h" +#include "ScriptCachedFrameData.h" +#include <wtf/Noncopyable.h> + +namespace WebCore { + + class CachedFramePlatformData; + class DOMWindow; + class Document; + class DocumentLoader; + class Frame; + class FrameView; + class Node; + +class CachedFrame : public Noncopyable { +public: + CachedFrame(Frame*); + ~CachedFrame(); + + void restore(Frame*); + void clear(); + + Document* document() const { return m_document.get(); } + DocumentLoader* documentLoader() const { return m_documentLoader.get(); } + FrameView* view() const { return m_view.get(); } + Node* mousePressNode() const { return m_mousePressNode.get(); } + const KURL& url() const { return m_URL; } + DOMWindow* domWindow() const { return m_cachedFrameScriptData.domWindow(); } + + void setCachedFramePlatformData(CachedFramePlatformData*); + CachedFramePlatformData* cachedFramePlatformData(); + +private: + RefPtr<Document> m_document; + RefPtr<DocumentLoader> m_documentLoader; + RefPtr<FrameView> m_view; + RefPtr<Node> m_mousePressNode; + KURL m_URL; + ScriptCachedFrameData m_cachedFrameScriptData; + OwnPtr<CachedFramePlatformData> m_cachedFramePlatformData; +}; + +} // namespace WebCore + +#endif // CachedFrame_h diff --git a/WebCore/history/CachedPagePlatformData.h b/WebCore/history/CachedFramePlatformData.h index c623f2f..01da8e5 100644 --- a/WebCore/history/CachedPagePlatformData.h +++ b/WebCore/history/CachedFramePlatformData.h @@ -25,8 +25,8 @@ * (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 +#ifndef CachedFramePlatformData_h +#define CachedFramePlatformData_h namespace WebCore { @@ -34,12 +34,12 @@ namespace WebCore { // 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 { +class CachedFramePlatformData { public: - virtual ~CachedPagePlatformData() { } + virtual ~CachedFramePlatformData() { } virtual void clear() { } }; } // namespace WebCore -#endif // CachedPagePlatformData_h +#endif // CachedFramePlatformData_h diff --git a/WebCore/history/CachedPage.cpp b/WebCore/history/CachedPage.cpp index 2381f52..7167275 100644 --- a/WebCore/history/CachedPage.cpp +++ b/WebCore/history/CachedPage.cpp @@ -26,32 +26,13 @@ #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 "CachedFrame.h" #include "FocusController.h" #include "Frame.h" -#include "FrameLoader.h" -#include "FrameView.h" -#include "GCController.h" -#include "JSDOMWindow.h" -#include "JSDOMWindowShell.h" -#include "Logging.h" #include "Page.h" -#include "PageGroup.h" -#include "PausedTimeouts.h" -#include "SystemTime.h" -#include "ScriptController.h" -#include <runtime/JSLock.h> +#include <wtf/CurrentTime.h> #include <wtf/RefCountedLeakCounter.h> -#if ENABLE(SVG) -#include "SVGDocumentExtensions.h" -#endif - using namespace JSC; namespace WebCore { @@ -66,30 +47,12 @@ PassRefPtr<CachedPage> CachedPage::create(Page* page) } CachedPage::CachedPage(Page* page) - : 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_timeStamp(currentTime()) + , m_cachedMainFrame(page->mainFrame()) { #ifndef NDEBUG cachedPageCounter.increment(); #endif - - m_document->documentWillBecomeInactive(); - - Frame* mainFrame = page->mainFrame(); - mainFrame->clearTimers(); - - JSLock lock(false); - - ScriptController* proxy = mainFrame->script(); - if (proxy->haveWindowShell()) { - m_window = proxy->windowShell()->window(); - m_window->pauseTimeouts(m_pausedTimeouts); - } - - m_document->setInPageCache(true); } CachedPage::~CachedPage() @@ -103,34 +66,9 @@ CachedPage::~CachedPage() void CachedPage::restore(Page* page) { - ASSERT(m_document->view() == m_view); - - Frame* mainFrame = page->mainFrame(); - - JSLock lock(false); - - ScriptController* proxy = mainFrame->script(); - if (proxy->haveWindowShell()) { - JSDOMWindowShell* windowShell = proxy->windowShell(); - if (m_window) { - windowShell->setWindow(m_window.get()); - windowShell->window()->resumeTimeouts(m_pausedTimeouts); - } else { - windowShell->setWindow(mainFrame->domWindow()); - proxy->attachDebugger(page->debugger()); - windowShell->window()->setProfileGroup(page->group().identifier()); - } - } - -#if ENABLE(SVG) - if (m_document && m_document->svgExtensions()) - m_document->accessSVGExtensions()->unpauseAnimations(); -#endif - - mainFrame->animation()->resumeAnimations(m_document.get()); + ASSERT(page && page->mainFrame()); + m_cachedMainFrame.restore(page->mainFrame()); - 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(); @@ -142,75 +80,7 @@ void CachedPage::restore(Page* page) 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.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(false); - m_pausedTimeouts.clear(); - m_window = 0; - - m_cachedPagePlatformData.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(); + m_cachedMainFrame.clear(); } } // namespace WebCore diff --git a/WebCore/history/CachedPage.h b/WebCore/history/CachedPage.h index 842cb03..a9cf71c 100644 --- a/WebCore/history/CachedPage.h +++ b/WebCore/history/CachedPage.h @@ -26,55 +26,44 @@ #ifndef CachedPage_h #define CachedPage_h -#include "KURL.h" -#include <wtf/OwnPtr.h> -#include "PausedTimeouts.h" -#include <kjs/protect.h> +#include "CachedFrame.h" namespace WebCore { - class CachedPagePlatformData; + class CachedFrame; + class CachedFramePlatformData; + class DOMWindow; class Document; class DocumentLoader; class FrameView; - class JSDOMWindow; + class KURL; 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 clear(); - void setCachedPagePlatformData(CachedPagePlatformData*); - CachedPagePlatformData* cachedPagePlatformData(); + Document* document() const { return m_cachedMainFrame.document(); } + DocumentLoader* documentLoader() const { return m_cachedMainFrame.documentLoader(); } + FrameView* view() const { return m_cachedMainFrame.view(); } + Node* mousePressNode() const { return m_cachedMainFrame.mousePressNode(); } + const KURL& url() const { return m_cachedMainFrame.url(); } + DOMWindow* domWindow() const { return m_cachedMainFrame.domWindow(); } + + double timeStamp() const { return m_timeStamp; } + + CachedFrame* cachedMainFrame() { return &m_cachedMainFrame; } 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; - JSC::ProtectedPtr<JSDOMWindow> m_window; - OwnPtr<PausedTimeouts> m_pausedTimeouts; - OwnPtr<CachedPagePlatformData> m_cachedPagePlatformData; + double m_timeStamp; + CachedFrame m_cachedMainFrame; }; } // namespace WebCore diff --git a/WebCore/history/HistoryItem.cpp b/WebCore/history/HistoryItem.cpp index d4e58e4..5a059b2 100644 --- a/WebCore/history/HistoryItem.cpp +++ b/WebCore/history/HistoryItem.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005, 2006 Apple Inc. All rights reserved. + * Copyright (C) 2005, 2006, 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 @@ -26,12 +26,10 @@ #include "config.h" #include "HistoryItem.h" +#include "CString.h" +#include "CachedPage.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> @@ -50,6 +48,8 @@ void (*notifyHistoryItemChanged)() = defaultNotifyHistoryItemChanged; HistoryItem::HistoryItem() : m_lastVisitedTime(0) + , m_lastVisitWasHTTPNonGet(false) + , m_lastVisitWasFailure(false) , m_isInPageCache(false) , m_isTargetItem(false) , m_visitCount(0) @@ -61,6 +61,8 @@ HistoryItem::HistoryItem(const String& urlString, const String& title, double ti , m_originalURLString(urlString) , m_title(title) , m_lastVisitedTime(time) + , m_lastVisitWasHTTPNonGet(false) + , m_lastVisitWasFailure(false) , m_isInPageCache(false) , m_isTargetItem(false) , m_visitCount(0) @@ -74,10 +76,12 @@ HistoryItem::HistoryItem(const String& urlString, const String& title, const Str , m_title(title) , m_displayTitle(alternateTitle) , m_lastVisitedTime(time) + , m_lastVisitWasHTTPNonGet(false) + , m_lastVisitWasFailure(false) , m_isInPageCache(false) , m_isTargetItem(false) , m_visitCount(0) -{ +{ iconDatabase()->retainIconForPageURL(m_urlString); } @@ -88,6 +92,8 @@ HistoryItem::HistoryItem(const KURL& url, const String& target, const String& pa , m_parent(parent) , m_title(title) , m_lastVisitedTime(0) + , m_lastVisitWasHTTPNonGet(false) + , m_lastVisitWasFailure(false) , m_isInPageCache(false) , m_isTargetItem(false) , m_visitCount(0) @@ -105,18 +111,21 @@ inline HistoryItem::HistoryItem(const HistoryItem& item) : RefCounted<HistoryItem>() , m_urlString(item.m_urlString) , m_originalURLString(item.m_originalURLString) + , m_referrer(item.m_referrer) , 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_lastVisitWasHTTPNonGet(item.m_lastVisitWasHTTPNonGet) , m_scrollPoint(item.m_scrollPoint) + , m_lastVisitWasFailure(item.m_lastVisitWasFailure) , m_isInPageCache(item.m_isInPageCache) , m_isTargetItem(item.m_isTargetItem) , m_visitCount(item.m_visitCount) + , m_dailyVisitCounts(item.m_dailyVisitCounts) + , m_weeklyVisitCounts(item.m_weeklyVisitCounts) , 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(); @@ -125,6 +134,9 @@ inline HistoryItem::HistoryItem(const HistoryItem& item) m_subItems.reserveCapacity(size); for (unsigned i = 0; i < size; ++i) m_subItems.append(item.m_subItems[i]->copy()); + + if (item.m_redirectURLs) + m_redirectURLs.set(new Vector<String>(*item.m_redirectURLs)); } PassRefPtr<HistoryItem> HistoryItem::copy() const @@ -175,6 +187,11 @@ KURL HistoryItem::originalURL() const return KURL(m_originalURLString); } +const String& HistoryItem::referrer() const +{ + return m_referrer; +} + const String& HistoryItem::target() const { return m_target; @@ -225,6 +242,16 @@ void HistoryItem::setOriginalURLString(const String& urlString) #endif } +void HistoryItem::setReferrer(const String& referrer) +{ + m_referrer = referrer; +#ifdef ANDROID_HISTORY_CLIENT + notifyHistoryItemChanged(this); +#else + notifyHistoryItemChanged(); +#endif +} + void HistoryItem::setTitle(const String& title) { m_title = title; @@ -250,12 +277,67 @@ void HistoryItem::setParent(const String& parent) m_parent = parent; } -void HistoryItem::setLastVisitedTime(double time) +static inline int timeToDay(double time) { - if (m_lastVisitedTime != time) { - m_lastVisitedTime = time; - m_visitCount++; + static const double secondsPerDay = 60 * 60 * 24; + return static_cast<int>(ceil(time / secondsPerDay)); +} + +void HistoryItem::padDailyCountsForNewVisit(double time) +{ + if (m_dailyVisitCounts.isEmpty()) + m_dailyVisitCounts.prepend(m_visitCount); + + int daysElapsed = timeToDay(time) - timeToDay(m_lastVisitedTime); + + if (daysElapsed < 0) + daysElapsed = 0; + + Vector<int> padding; + padding.fill(0, daysElapsed); + m_dailyVisitCounts.prepend(padding); +} + +static const size_t daysPerWeek = 7; +static const size_t maxDailyCounts = 2 * daysPerWeek - 1; +static const size_t maxWeeklyCounts = 5; + +void HistoryItem::collapseDailyVisitsToWeekly() +{ + while (m_dailyVisitCounts.size() > maxDailyCounts) { + int oldestWeekTotal = 0; + for (size_t i = 0; i < daysPerWeek; i++) + oldestWeekTotal += m_dailyVisitCounts[m_dailyVisitCounts.size() - daysPerWeek + i]; + m_dailyVisitCounts.shrink(m_dailyVisitCounts.size() - daysPerWeek); + m_weeklyVisitCounts.prepend(oldestWeekTotal); } + + if (m_weeklyVisitCounts.size() > maxWeeklyCounts) + m_weeklyVisitCounts.shrink(maxWeeklyCounts); +} + +void HistoryItem::recordVisitAtTime(double time) +{ + padDailyCountsForNewVisit(time); + + m_lastVisitedTime = time; + m_visitCount++; + + m_dailyVisitCounts[0]++; + + collapseDailyVisitsToWeekly(); +} + +void HistoryItem::setLastVisitedTime(double time) +{ + if (m_lastVisitedTime != time) + recordVisitAtTime(time); +} + +void HistoryItem::visited(const String& title, double time) +{ + m_title = title; + recordVisitAtTime(time); } int HistoryItem::visitCount() const @@ -263,11 +345,25 @@ int HistoryItem::visitCount() const return m_visitCount; } +void HistoryItem::recordInitialVisit() +{ + ASSERT(!m_visitCount); + recordVisitAtTime(m_lastVisitedTime); +} + void HistoryItem::setVisitCount(int count) { m_visitCount = count; } +void HistoryItem::adoptVisitCounts(Vector<int>& dailyCounts, Vector<int>& weeklyCounts) +{ + m_dailyVisitCounts.clear(); + m_dailyVisitCounts.swap(dailyCounts); + m_weeklyVisitCounts.clear(); + m_weeklyVisitCounts.swap(weeklyCounts); +} + const IntPoint& HistoryItem::scrollPoint() const { return m_scrollPoint; @@ -376,33 +472,18 @@ 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) { + m_referrer = request.httpReferrer(); + 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(); } #ifdef ANDROID_HISTORY_CLIENT notifyHistoryItemChanged(this); @@ -422,12 +503,37 @@ bool HistoryItem::isCurrentDocument(Document* doc) const void HistoryItem::mergeAutoCompleteHints(HistoryItem* otherItem) { + // FIXME: this is broken - we should be merging the daily counts + // somehow. but this is to support API that's not really used in + // practice so leave it broken for now. ASSERT(otherItem); if (otherItem != this) m_visitCount += otherItem->m_visitCount; } +void HistoryItem::addRedirectURL(const String& url) +{ + if (!m_redirectURLs) + m_redirectURLs.set(new Vector<String>); + + // Our API allows us to store all the URLs in the redirect chain, but for + // now we only have a use for the final URL. + (*m_redirectURLs).resize(1); + (*m_redirectURLs)[0] = url; +} + +Vector<String>* HistoryItem::redirectURLs() const +{ + return m_redirectURLs.get(); +} + +void HistoryItem::setRedirectURLs(std::auto_ptr<Vector<String> > redirectURLs) +{ + m_redirectURLs.adopt(redirectURLs); +} + #ifndef NDEBUG + int HistoryItem::showTree() const { return showTreeWithIndent(0); @@ -435,26 +541,28 @@ int HistoryItem::showTree() const int HistoryItem::showTreeWithIndent(unsigned indentLevel) const { - String prefix(""); - int totalSubItems = 0; - unsigned i; - for (i = 0; i < indentLevel; ++i) - prefix.append(" "); + Vector<char> prefix; + for (unsigned i = 0; i < indentLevel; ++i) + prefix.append(" ", 2); + prefix.append("\0", 1); - fprintf(stderr, "%s+-%s (%p)\n", prefix.ascii().data(), m_urlString.ascii().data(), this); + fprintf(stderr, "%s+-%s (%p)\n", prefix.data(), m_urlString.utf8().data(), this); - for (unsigned int i = 0; i < m_subItems.size(); ++i) { + int totalSubItems = 0; + for (unsigned i = 0; i < m_subItems.size(); ++i) totalSubItems += m_subItems[i]->showTreeWithIndent(indentLevel + 1); - } return totalSubItems + 1; } + #endif -}; //namespace WebCore +} // 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 index 839f47d..cd23c9e 100644 --- a/WebCore/history/HistoryItem.h +++ b/WebCore/history/HistoryItem.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2006, 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 @@ -26,20 +26,8 @@ #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(QT) -#include <QVariant> -#endif #if PLATFORM(MAC) #import <wtf/RetainPtr.h> @@ -50,14 +38,20 @@ typedef struct objc_object* id; #include "WebHistory.h" #endif +#if PLATFORM(QT) +#include <QVariant> +#endif + namespace WebCore { +class CachedPage; class Document; +class FormData; +class HistoryItem; class Image; class KURL; class ResourceRequest; -class HistoryItem; typedef Vector<RefPtr<HistoryItem> > HistoryItemVector; #ifdef ANDROID_HISTORY_CLIENT @@ -105,15 +99,16 @@ public: const String& parent() const; KURL url() const; KURL originalURL() const; + const String& referrer() const; const String& target() const; bool isTargetItem() const; FormData* formData(); String formContentType() const; - String formReferrer() const; - String rssFeedReferrer() const; int visitCount() const; + bool lastVisitWasFailure() const { return m_lastVisitWasFailure; } + bool lastVisitWasHTTPNonGet() const { return m_lastVisitWasHTTPNonGet; } void mergeAutoCompleteHints(HistoryItem* otherItem); @@ -127,6 +122,7 @@ public: void setURL(const KURL&); void setURLString(const String&); void setOriginalURLString(const String&); + void setReferrer(const String&); void setTarget(const String&); void setParent(const String&); void setTitle(const String&); @@ -134,8 +130,11 @@ public: void setFormInfoFromRequest(const ResourceRequest&); - void setRSSFeedReferrer(const String&); + void recordInitialVisit(); + void setVisitCount(int); + void setLastVisitWasFailure(bool wasFailure) { m_lastVisitWasFailure = wasFailure; } + void setLastVisitWasHTTPNonGet(bool wasNotGet) { m_lastVisitWasHTTPNonGet = wasNotGet; } void addChildItem(PassRefPtr<HistoryItem>); HistoryItem* childItemWithName(const String&) const; @@ -147,7 +146,12 @@ public: // 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); - + void visited(const String& title, double time); + + void addRedirectURL(const String&); + Vector<String>* redirectURLs() const; + void setRedirectURLs(std::auto_ptr<Vector<String> >); + bool isCurrentDocument(Document*) const; #if PLATFORM(MAC) @@ -175,6 +179,10 @@ public: android::WebHistoryItem* bridge() const { return m_bridge.get(); } #endif + void adoptVisitCounts(Vector<int>& dailyCounts, Vector<int>& weeklyCounts); + const Vector<int>& dailyVisitCounts() { return m_dailyVisitCounts; } + const Vector<int>& weeklyVisitCounts() { return m_weeklyVisitCounts; } + private: HistoryItem(); HistoryItem(const String& urlString, const String& title, double lastVisited); @@ -182,32 +190,39 @@ private: HistoryItem(const KURL& url, const String& target, const String& parent, const String& title); HistoryItem(const HistoryItem&); - + + void padDailyCountsForNewVisit(double time); + void collapseDailyVisitsToWeekly(); + void recordVisitAtTime(double); + String m_urlString; String m_originalURLString; + String m_referrer; String m_target; String m_parent; String m_title; String m_displayTitle; double m_lastVisitedTime; + bool m_lastVisitWasHTTPNonGet; IntPoint m_scrollPoint; Vector<String> m_documentState; HistoryItemVector m_subItems; + bool m_lastVisitWasFailure; bool m_isInPageCache; bool m_isTargetItem; int m_visitCount; - + Vector<int> m_dailyVisitCounts; + Vector<int> m_weeklyVisitCounts; + + OwnPtr<Vector<String> > m_redirectURLs; + // 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; diff --git a/WebCore/history/PageCache.cpp b/WebCore/history/PageCache.cpp index dc24fd2..7c25701 100644 --- a/WebCore/history/PageCache.cpp +++ b/WebCore/history/PageCache.cpp @@ -32,6 +32,7 @@ #include "HistoryItem.h" #include "Logging.h" #include "SystemTime.h" +#include <wtf/CurrentTime.h> using namespace std; diff --git a/WebCore/history/mac/HistoryItemMac.mm b/WebCore/history/mac/HistoryItemMac.mm index cac9b1b..52ae7be 100644 --- a/WebCore/history/mac/HistoryItemMac.mm +++ b/WebCore/history/mac/HistoryItemMac.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2006, 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 @@ -26,10 +26,9 @@ #include "config.h" #include "HistoryItem.h" -namespace WebCore { +#include "StringHash.h" -// Notification strings. -NSString *WebHistoryItemChangedNotification = @"WebHistoryItemChangedNotification"; +namespace WebCore { id HistoryItem::viewState() const { @@ -52,14 +51,17 @@ id HistoryItem::getTransientProperty(const String& key) const 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 + if (!value) { + if (m_transientProperties) { + m_transientProperties->remove(key); + if (m_transientProperties->isEmpty()) + m_transientProperties.clear(); + } + } else { + if (!m_transientProperties) + m_transientProperties.set(new HashMap<String, RetainPtr<id> >); m_transientProperties->set(key, value); + } } } // namespace WebCore - - |