diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/history/CachedFrame.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebCore/history/CachedFrame.cpp')
-rw-r--r-- | Source/WebCore/history/CachedFrame.cpp | 144 |
1 files changed, 60 insertions, 84 deletions
diff --git a/Source/WebCore/history/CachedFrame.cpp b/Source/WebCore/history/CachedFrame.cpp index 1f61671d7..210285243 100644 --- a/Source/WebCore/history/CachedFrame.cpp +++ b/Source/WebCore/history/CachedFrame.cpp @@ -10,10 +10,10 @@ * 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 + * THIS SOFTWARE IS PROVIDED BY APPLE 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 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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 @@ -24,44 +24,32 @@ */ #include "config.h" -#include "CachedPage.h" +#include "CachedFrame.h" -#include "AnimationController.h" +#include "CSSAnimationController.h" #include "CachedFramePlatformData.h" +#include "CachedPage.h" #include "DOMWindow.h" #include "Document.h" #include "DocumentLoader.h" -#include "EventHandler.h" -#include "EventNames.h" -#include "ExceptionCode.h" -#include "FocusController.h" #include "FrameLoader.h" #include "FrameLoaderClient.h" #include "FrameView.h" -#include "HistoryController.h" -#include "HistoryItem.h" #include "Logging.h" #include "MainFrame.h" #include "Page.h" -#include "PageTransitionEvent.h" +#include "PageCache.h" +#include "SVGDocumentExtensions.h" #include "ScriptController.h" #include "SerializedScriptValue.h" #include <wtf/RefCountedLeakCounter.h> #include <wtf/text/CString.h> -#if ENABLE(SVG) -#include "SVGDocumentExtensions.h" -#endif - -#if ENABLE(TOUCH_EVENTS) +#if PLATFORM(IOS) || ENABLE(TOUCH_EVENTS) #include "Chrome.h" #include "ChromeClient.h" #endif -#if USE(ACCELERATED_COMPOSITING) -#include "PageCache.h" -#endif - namespace WebCore { DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, cachedFrameCounter, ("CachedFrame")); @@ -70,12 +58,8 @@ 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.document()->url()) , m_isMainFrame(!frame.tree().parent()) -#if USE(ACCELERATED_COMPOSITING) - , m_isComposited(frame.view()->hasCompositedContent()) -#endif { } @@ -88,6 +72,17 @@ CachedFrameBase::~CachedFrameBase() ASSERT(!m_document); } +void CachedFrameBase::pruneDetachedChildFrames() +{ + for (size_t i = m_childFrames.size(); i;) { + --i; + if (m_childFrames[i]->view()->frame().page()) + continue; + m_childFrames[i]->destroy(); + m_childFrames.remove(i); + } +} + void CachedFrameBase::restore() { ASSERT(m_document->view() == m_view); @@ -98,31 +93,27 @@ void CachedFrameBase::restore() Frame& frame = m_view->frame(); m_cachedFrameScriptData->restore(frame); -#if ENABLE(SVG) if (m_document->svgExtensions()) - m_document->accessSVGExtensions()->unpauseAnimations(); -#endif + m_document->accessSVGExtensions().unpauseAnimations(); frame.animation().resumeAnimationsForDocument(m_document.get()); - frame.eventHandler().setMousePressNode(m_mousePressNode.get()); - m_document->resumeActiveDOMObjects(ActiveDOMObject::DocumentWillBecomeInactive); - m_document->resumeScriptedAnimationControllerCallbacks(); + + m_document->resume(ActiveDOMObject::PageCache); // It is necessary to update any platform script objects after restoring the // cached page. frame.script().updatePlatformScriptObjects(); -#if USE(ACCELERATED_COMPOSITING) - if (m_isComposited) - frame.view()->restoreBackingStores(); -#endif - frame.loader().client().didRestoreFromPageCache(); + pruneDetachedChildFrames(); + // Reconstruct the FrameTree. And open the child CachedFrames in their respective FrameLoaders. - for (unsigned i = 0; i < m_childFrames.size(); ++i) { - frame.tree().appendChild(&m_childFrames[i]->view()->frame()); - m_childFrames[i]->open(); + for (auto& childFrame : m_childFrames) { + ASSERT(childFrame->view()->frame().page()); + frame.tree().appendChild(childFrame->view()->frame()); + childFrame->open(); + ASSERT_WITH_SECURITY_IMPLICATION(m_document == frame.document()); } #if PLATFORM(IOS) @@ -131,25 +122,14 @@ void CachedFrameBase::restore() if (DOMWindow* domWindow = m_document->domWindow()) { // FIXME: Add SCROLL_LISTENER to the list of event types on Document, and use m_document->hasListenerType(). See <rdar://problem/9615482>. + // FIXME: Can use Document::hasListenerType() now. if (domWindow->scrollEventListenerCount() && frame.page()) - frame.page()->chrome().client().setNeedsScrollNotifications(&frame, true); + frame.page()->chrome().client().setNeedsScrollNotifications(frame, true); } } #endif - // FIXME: update Page Visibility state here. - // https://bugs.webkit.org/show_bug.cgi?id=116770 - m_document->enqueuePageshowEvent(PageshowEventPersisted); - - HistoryItem* historyItem = frame.loader().history().currentItem(); - m_document->enqueuePopstateEvent(historyItem && historyItem->stateObject() ? historyItem->stateObject() : SerializedScriptValue::nullValue()); - -#if ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS) - if (m_document->hasTouchEventHandlers()) - m_document->page()->chrome().client().needTouchEvents(true); -#endif - - m_document->documentDidResumeFromPageCache(); + frame.view()->didRestoreFromPageCache(); } CachedFrame::CachedFrame(Frame& frame) @@ -161,38 +141,21 @@ CachedFrame::CachedFrame(Frame& frame) ASSERT(m_document); ASSERT(m_documentLoader); ASSERT(m_view); - - if (frame.page()->focusController().focusedFrame() == &frame) - frame.page()->focusController().setFocusedFrame(&frame.mainFrame()); - - // Custom scrollbar renderers will get reattached when the document comes out of the page cache - m_view->detachCustomScrollbars(); - - m_document->setInPageCache(true); - frame.loader().stopLoading(UnloadEventPolicyUnloadAndPageHide); + ASSERT(m_document->pageCacheState() == Document::InPageCache); // Create the CachedFrames for all Frames in the FrameTree. for (Frame* child = frame.tree().firstChild(); child; child = child->tree().nextSibling()) m_childFrames.append(std::make_unique<CachedFrame>(*child)); - // Active DOM objects must be suspended before we cache the frame script data, - // but after we've fired the pagehide event, in case that creates more objects. - // Suspending must also happen after we've recursed over child frames, in case - // those create more objects. - m_document->documentWillSuspendForPageCache(); - m_document->suspendScriptedAnimationControllerCallbacks(); - m_document->suspendActiveDOMObjects(ActiveDOMObject::DocumentWillBecomeInactive); + // Active DOM objects must be suspended before we cache the frame script data. + m_document->suspend(ActiveDOMObject::PageCache); + m_cachedFrameScriptData = std::make_unique<ScriptCachedFrameData>(frame); - m_document->domWindow()->suspendForPageCache(); + m_document->domWindow()->suspendForDocumentSuspension(); frame.loader().client().savePlatformDataToCachedFrame(this); -#if USE(ACCELERATED_COMPOSITING) - if (m_isComposited && pageCache()->shouldClearBackingStores()) - frame.view()->clearBackingStores(); -#endif - // documentWillSuspendForPageCache() can set up a layout timer on the FrameView, so clear timers after that. frame.clearTimers(); @@ -201,7 +164,7 @@ CachedFrame::CachedFrame(Frame& frame) // 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()); + frame.tree().removeChild(m_childFrames[i]->view()->frame()); if (!m_isMainFrame) frame.page()->decrementSubframeCount(); @@ -219,18 +182,25 @@ CachedFrame::CachedFrame(Frame& frame) if (m_isMainFrame) { if (DOMWindow* domWindow = m_document->domWindow()) { if (domWindow->scrollEventListenerCount() && frame.page()) - frame.page()->chrome().client().setNeedsScrollNotifications(&frame, false); + frame.page()->chrome().client().setNeedsScrollNotifications(frame, false); } } #endif + + m_document->detachFromCachedFrame(*this); + + ASSERT_WITH_SECURITY_IMPLICATION(!m_documentLoader->isLoading()); } void CachedFrame::open() { ASSERT(m_view); + ASSERT(m_document); if (!m_isMainFrame) m_view->frame().page()->incrementSubframeCount(); + m_document->attachToCachedFrame(*this); + m_view->frame().loader().open(*this); } @@ -243,7 +213,7 @@ void CachedFrame::clear() // 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_document->pageCacheState() == Document::NotInPageCache); ASSERT(m_view); ASSERT(!m_document->frame() || m_document->frame() == &m_view->frame()); @@ -252,7 +222,6 @@ void CachedFrame::clear() m_document = nullptr; m_view = nullptr; - m_mousePressNode = nullptr; m_url = URL(); m_cachedFramePlatformData = nullptr; @@ -265,15 +234,15 @@ void CachedFrame::destroy() return; // Only CachedFrames that are still in the PageCache should be destroyed in this manner - ASSERT(m_document->inPageCache()); + ASSERT(m_document->pageCacheState() == Document::InPageCache); ASSERT(m_view); - ASSERT(m_document->frame() == &m_view->frame()); + ASSERT(!m_document->frame()); m_document->domWindow()->willDestroyCachedFrame(); - if (!m_isMainFrame) { - m_view->frame().detachFromPage(); + if (!m_isMainFrame && m_view->frame().page()) { m_view->frame().loader().detachViewsAndDocumentLoader(); + m_view->frame().detachFromPage(); } for (int i = m_childFrames.size() - 1; i >= 0; --i) @@ -284,11 +253,13 @@ void CachedFrame::destroy() Frame::clearTimers(m_view.get(), m_document.get()); + m_view->frame().animation().detachFromDocument(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); + m_document->setPageCacheState(Document::NotInPageCache); m_document->prepareForDestruction(); clear(); @@ -296,7 +267,7 @@ void CachedFrame::destroy() void CachedFrame::setCachedFramePlatformData(std::unique_ptr<CachedFramePlatformData> data) { - m_cachedFramePlatformData = std::move(data); + m_cachedFramePlatformData = WTFMove(data); } CachedFramePlatformData* CachedFrame::cachedFramePlatformData() @@ -304,6 +275,11 @@ CachedFramePlatformData* CachedFrame::cachedFramePlatformData() return m_cachedFramePlatformData.get(); } +void CachedFrame::setHasInsecureContent(HasInsecureContent hasInsecureContent) +{ + m_hasInsecureContent = hasInsecureContent; +} + int CachedFrame::descendantFrameCount() const { int count = m_childFrames.size(); |