diff options
author | Steve Block <steveblock@google.com> | 2009-10-08 17:19:54 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2009-10-20 00:41:58 +0100 |
commit | 231d4e3152a9c27a73b6ac7badbe6be673aa3ddf (patch) | |
tree | a6c7e2d6cd7bfa7011cc39abbb436142d7a4a7c8 /WebCore/history | |
parent | e196732677050bd463301566a68a643b6d14b907 (diff) | |
download | external_webkit-231d4e3152a9c27a73b6ac7badbe6be673aa3ddf.zip external_webkit-231d4e3152a9c27a73b6ac7badbe6be673aa3ddf.tar.gz external_webkit-231d4e3152a9c27a73b6ac7badbe6be673aa3ddf.tar.bz2 |
Merge webkit.org at R49305 : Automatic merge by git.
Change-Id: I8968561bc1bfd72b8923b7118d3728579c6dbcc7
Diffstat (limited to 'WebCore/history')
-rw-r--r-- | WebCore/history/CachedFrame.cpp | 153 | ||||
-rw-r--r-- | WebCore/history/CachedFrame.h | 42 | ||||
-rw-r--r-- | WebCore/history/CachedPage.cpp | 21 | ||||
-rw-r--r-- | WebCore/history/CachedPage.h | 4 | ||||
-rw-r--r-- | WebCore/history/HistoryItem.cpp | 4 | ||||
-rw-r--r-- | WebCore/history/PageCache.cpp | 2 | ||||
-rw-r--r-- | WebCore/history/qt/HistoryItemQt.cpp | 2 |
7 files changed, 160 insertions, 68 deletions
diff --git a/WebCore/history/CachedFrame.cpp b/WebCore/history/CachedFrame.cpp index 5f4e746..16c7087 100644 --- a/WebCore/history/CachedFrame.cpp +++ b/WebCore/history/CachedFrame.cpp @@ -29,10 +29,13 @@ #include "CachedFramePlatformData.h" #include "CString.h" #include "DocumentLoader.h" +#include "ExceptionCode.h" +#include "EventNames.h" #include "Frame.h" #include "FrameLoaderClient.h" #include "FrameView.h" #include "Logging.h" +#include "PageTransitionEvent.h" #include <wtf/RefCountedLeakCounter.h> #if ENABLE(SVG) @@ -49,12 +52,58 @@ static WTF::RefCountedLeakCounter& cachedFrameCounter() } #endif -CachedFrame::CachedFrame(Frame* frame) +CachedFrameBase::CachedFrameBase(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_isMainFrame(!frame->tree()->parent()) +{ +} + +CachedFrameBase::~CachedFrameBase() +{ +#ifndef NDEBUG + cachedFrameCounter().decrement(); +#endif + // CachedFrames should always have had destroy() called by their parent CachedPage + ASSERT(!m_document); +} + +void CachedFrameBase::restore() +{ + ASSERT(m_document->view() == m_view); + + Frame* frame = m_view->frame(); + m_cachedFrameScriptData->restore(frame); + +#if ENABLE(SVG) + if (m_document->svgExtensions()) + m_document->accessSVGExtensions()->unpauseAnimations(); +#endif + + frame->animation()->resumeAnimations(m_document.get()); + frame->eventHandler()->setMousePressNode(m_mousePressNode.get()); + m_document->resumeActiveDOMObjects(); + + // It is necessary to update any platform script objects after restoring the + // cached page. + frame->script()->updatePlatformScriptObjects(); + + // Reconstruct the FrameTree + for (unsigned i = 0; i < m_childFrames.size(); ++i) + frame->tree()->appendChild(m_childFrames[i]->view()->frame()); + + // Open the child CachedFrames in their respective FrameLoaders. + for (unsigned i = 0; i < m_childFrames.size(); ++i) + m_childFrames[i]->open(); + + m_document->dispatchWindowEvent(PageTransitionEvent::create(EventNames().pageshowEvent, true), m_document); +} + +CachedFrame::CachedFrame(Frame* frame) + : CachedFrameBase(frame) { #ifndef NDEBUG cachedFrameCounter().increment(); @@ -67,46 +116,38 @@ CachedFrame::CachedFrame(Frame* frame) m_document->suspendActiveDOMObjects(); m_cachedFrameScriptData.set(new ScriptCachedFrameData(frame)); + // Custom scrollbar renderers will get reattached when the document comes out of the page cache + m_view->detachCustomScrollbars(); + m_document->documentWillBecomeInactive(); frame->clearTimers(); m_document->setInPageCache(true); frame->loader()->client()->savePlatformDataToCachedFrame(this); + // Create the CachedFrames for all Frames in the FrameTree. for (Frame* child = frame->tree()->firstChild(); child; child = child->tree()->nextSibling()) m_childFrames.append(CachedFrame::create(child)); - LOG(PageCache, "Finished creating CachedFrame with url %s and documentloader %p\n", m_url.string().utf8().data(), m_documentLoader.get()); -} + // Deconstruct the FrameTree, to restore it later. + // We do this for two reasons: + // 1 - We reuse the main frame, so when it navigates to a new page load it needs to start with a blank FrameTree. + // 2 - It's much easier to destroy a CachedFrame while it resides in the PageCache if it is disconnected from its parent. + for (unsigned i = 0; i < m_childFrames.size(); ++i) + frame->tree()->removeChild(m_childFrames[i]->view()->frame()); -CachedFrame::~CachedFrame() -{ #ifndef NDEBUG - cachedFrameCounter().decrement(); + if (m_isMainFrame) + LOG(PageCache, "Finished creating CachedFrame for main frame url '%s' and DocumentLoader %p\n", m_url.string().utf8().data(), m_documentLoader.get()); + else + LOG(PageCache, "Finished creating CachedFrame for child frame with url '%s' and DocumentLoader %p\n", m_url.string().utf8().data(), m_documentLoader.get()); #endif - - clear(); } -void CachedFrame::restore() +void CachedFrame::open() { - ASSERT(m_document->view() == m_view); - - Frame* frame = m_view->frame(); - m_cachedFrameScriptData->restore(frame); - -#if ENABLE(SVG) - if (m_document->svgExtensions()) - m_document->accessSVGExtensions()->unpauseAnimations(); -#endif - - frame->animation()->resumeAnimations(m_document.get()); - frame->eventHandler()->setMousePressNode(mousePressNode()); - m_document->resumeActiveDOMObjects(); - - // It is necessary to update any platform script objects after restoring the - // cached page. - frame->script()->updatePlatformScriptObjects(); + ASSERT(m_view); + m_view->frame()->loader()->open(*this); } void CachedFrame::clear() @@ -114,26 +155,16 @@ void CachedFrame::clear() if (!m_document) return; - if (m_cachedFramePlatformData) - m_cachedFramePlatformData->clear(); - + // clear() should only be called for Frames representing documents that are no longer in the page cache. + // This means the CachedFrame has been: + // 1 - Successfully restore()'d by going back/forward. + // 2 - destroy()'ed because the PageCache is pruning or the WebView was closed. + ASSERT(!m_document->inPageCache()); ASSERT(m_view); ASSERT(m_document->frame() == m_view->frame()); - if (m_document->inPageCache()) { - Frame::clearTimers(m_view.get(), m_document.get()); - - // FIXME: Why do we need to call removeAllEventListeners here? When the document is in page cache, this method won't work - // fully anyway, because the document won't be able to access its DOMWindow object (due to being frameless). - m_document->removeAllEventListeners(); - - m_document->setInPageCache(false); - // FIXME: We don't call willRemove here. Why is that OK? - m_document->detach(); - m_view->clearFrame(); - } - - ASSERT(!m_document->inPageCache()); + for (int i = m_childFrames.size() - 1; i >= 0; --i) + m_childFrames[i]->clear(); m_document = 0; m_view = 0; @@ -141,10 +172,44 @@ void CachedFrame::clear() m_url = KURL(); m_cachedFramePlatformData.clear(); - m_cachedFrameScriptData.clear(); } +void CachedFrame::destroy() +{ + if (!m_document) + return; + + // Only CachedFrames that are still in the PageCache should be destroyed in this manner + ASSERT(m_document->inPageCache()); + ASSERT(m_view); + ASSERT(m_document->frame() == m_view->frame()); + + if (!m_isMainFrame) { + m_view->frame()->detachFromPage(); + m_view->frame()->loader()->detachViewsAndDocumentLoader(); + } + + for (int i = m_childFrames.size() - 1; i >= 0; --i) + m_childFrames[i]->destroy(); + + if (m_cachedFramePlatformData) + m_cachedFramePlatformData->clear(); + + Frame::clearTimers(m_view.get(), m_document.get()); + + // FIXME: Why do we need to call removeAllEventListeners here? When the document is in page cache, this method won't work + // fully anyway, because the document won't be able to access its DOMWindow object (due to being frameless). + m_document->removeAllEventListeners(); + + m_document->setInPageCache(false); + // FIXME: We don't call willRemove here. Why is that OK? + m_document->detach(); + m_view->clearFrame(); + + clear(); +} + void CachedFrame::setCachedFramePlatformData(CachedFramePlatformData* data) { m_cachedFramePlatformData.set(data); diff --git a/WebCore/history/CachedFrame.h b/WebCore/history/CachedFrame.h index 0302444..883c12a 100644 --- a/WebCore/history/CachedFrame.h +++ b/WebCore/history/CachedFrame.h @@ -43,29 +43,20 @@ namespace WebCore { typedef Vector<RefPtr<CachedFrame> > CachedFrameVector; -class CachedFrame : public RefCounted<CachedFrame> { +class CachedFrameBase { public: - static PassRefPtr<CachedFrame> create(Frame* frame) { return adoptRef(new CachedFrame(frame)); } - ~CachedFrame(); - void restore(); - 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(); } + bool isMainFrame() { return m_isMainFrame; } - void setCachedFramePlatformData(CachedFramePlatformData*); - CachedFramePlatformData* cachedFramePlatformData(); +protected: + CachedFrameBase(Frame*); + ~CachedFrameBase(); - int descendantFrameCount() const; - -private: - CachedFrame(Frame*); - RefPtr<Document> m_document; RefPtr<DocumentLoader> m_documentLoader; RefPtr<FrameView> m_view; @@ -73,10 +64,33 @@ private: KURL m_url; OwnPtr<ScriptCachedFrameData> m_cachedFrameScriptData; OwnPtr<CachedFramePlatformData> m_cachedFramePlatformData; + bool m_isMainFrame; CachedFrameVector m_childFrames; }; +class CachedFrame : public RefCounted<CachedFrame>, private CachedFrameBase { +public: + static PassRefPtr<CachedFrame> create(Frame* frame) { return adoptRef(new CachedFrame(frame)); } + + void open(); + void clear(); + void destroy(); + + void setCachedFramePlatformData(CachedFramePlatformData* data); + CachedFramePlatformData* cachedFramePlatformData(); + + using CachedFrameBase::document; + using CachedFrameBase::view; + DocumentLoader* documentLoader() const { return m_documentLoader.get(); } + Node* mousePressNode() const { return m_mousePressNode.get(); } + + int descendantFrameCount() const; + +private: + CachedFrame(Frame*); +}; + } // namespace WebCore #endif // CachedFrame_h diff --git a/WebCore/history/CachedPage.cpp b/WebCore/history/CachedPage.cpp index 8898ce2..20c5fd7 100644 --- a/WebCore/history/CachedPage.cpp +++ b/WebCore/history/CachedPage.cpp @@ -61,14 +61,17 @@ CachedPage::~CachedPage() cachedPageCounter.decrement(); #endif - clear(); + destroy(); + ASSERT(!m_cachedMainFrame); } void CachedPage::restore(Page* page) { + ASSERT(m_cachedMainFrame); ASSERT(page && page->mainFrame() && page->mainFrame() == m_cachedMainFrame->view()->frame()); - m_cachedMainFrame->restore(); + m_cachedMainFrame->open(); + // 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(); @@ -76,11 +79,23 @@ void CachedPage::restore(Page* page) if (node->isElementNode()) static_cast<Element*>(node)->updateFocusAppearance(true); } + + clear(); } void CachedPage::clear() { - m_cachedMainFrame.clear(); + ASSERT(m_cachedMainFrame); + m_cachedMainFrame->clear(); + m_cachedMainFrame = 0; +} + +void CachedPage::destroy() +{ + if (m_cachedMainFrame) + m_cachedMainFrame->destroy(); + + m_cachedMainFrame = 0; } } // namespace WebCore diff --git a/WebCore/history/CachedPage.h b/WebCore/history/CachedPage.h index 430cf3a..c68c753 100644 --- a/WebCore/history/CachedPage.h +++ b/WebCore/history/CachedPage.h @@ -46,12 +46,10 @@ public: void restore(Page*); void clear(); + void destroy(); Document* document() const { return m_cachedMainFrame->document(); } DocumentLoader* documentLoader() const { return m_cachedMainFrame->documentLoader(); } - FrameView* mainFrameView() const { return m_cachedMainFrame->view(); } - const KURL& url() const { return m_cachedMainFrame->url(); } - DOMWindow* domWindow() const { return m_cachedMainFrame->domWindow(); } double timeStamp() const { return m_timeStamp; } diff --git a/WebCore/history/HistoryItem.cpp b/WebCore/history/HistoryItem.cpp index 08143e8..efd7078 100644 --- a/WebCore/history/HistoryItem.cpp +++ b/WebCore/history/HistoryItem.cpp @@ -176,12 +176,12 @@ double HistoryItem::lastVisitedTime() const KURL HistoryItem::url() const { - return KURL(m_urlString); + return KURL(ParsedURLString, m_urlString); } KURL HistoryItem::originalURL() const { - return KURL(m_originalURLString); + return KURL(ParsedURLString, m_originalURLString); } const String& HistoryItem::referrer() const diff --git a/WebCore/history/PageCache.cpp b/WebCore/history/PageCache.cpp index 8d04f6f..9a3ecd7 100644 --- a/WebCore/history/PageCache.cpp +++ b/WebCore/history/PageCache.cpp @@ -182,7 +182,7 @@ void PageCache::releaseAutoreleasedPagesNow() CachedPageSet::iterator end = tmp.end(); for (CachedPageSet::iterator it = tmp.begin(); it != end; ++it) - (*it)->clear(); + (*it)->destroy(); // Now do the prune. cache()->setPruneEnabled(true); diff --git a/WebCore/history/qt/HistoryItemQt.cpp b/WebCore/history/qt/HistoryItemQt.cpp index 68fee87..098a786 100644 --- a/WebCore/history/qt/HistoryItemQt.cpp +++ b/WebCore/history/qt/HistoryItemQt.cpp @@ -45,7 +45,7 @@ bool WebCore::HistoryItem::restoreState(QDataStream& in, int /*version*/) WebCore::IntPoint scrollPoint; WTF::Vector<int> weeklyVisitCounts; WTF::Vector<int> dailyVisitCounts; - bool loadFormdata; + // bool loadFormdata; // WebCore::String formContentType; // WTF::Vector<char> formData; |