Changeset 214014 in webkit


Ignore:
Timestamp:
Mar 15, 2017 3:44:59 PM (7 years ago)
Author:
dbates@webkit.org
Message:

Iteratively dispatch DOM events after restoring a cached page
https://bugs.webkit.org/show_bug.cgi?id=169703
<rdar://problem/31075903>

Reviewed by Brady Eidson.

Make dispatching of DOM events when restoring a page from the page cache symmetric with
dispatching of events when saving a page to the page cache.

  • history/CachedFrame.cpp:

(WebCore::CachedFrameBase::restore): Move code to dispatch events from here to FrameLoader::didRestoreFromCachedPage().

  • loader/FrameLoader.cpp:

(WebCore::FrameLoader::commitProvisionalLoad): Ensure that no DOM events are dispatched during
restoration of a cached page. Call didRestoreFromCachedPage() after restoring the page to
dispatch DOM events on the restored frames.
(WebCore::FrameLoader::willRestoreFromCachedPage): Renamed; formerly named prepareForCachedPageRestore().
(WebCore::FrameLoader::didRestoreFromCachedPage): Added.
(WebCore::FrameLoader::prepareForCachedPageRestore): Renamed to willRestoreFromCachedPage().

  • loader/FrameLoader.h:
  • page/FrameTree.cpp:

(WebCore::FrameTree::traverseNextInPostOrderWithWrap): Returns the next Frame* in a post-order
traversal of the frame tree optionally wrapping around to the deepest first child in the tree.
(WebCore::FrameTree::deepFirstChild): Added.

  • page/FrameTree.h:
Location:
trunk/Source/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r214010 r214014  
     12017-03-15  Daniel Bates  <dabates@apple.com>
     2
     3        Iteratively dispatch DOM events after restoring a cached page
     4        https://bugs.webkit.org/show_bug.cgi?id=169703
     5        <rdar://problem/31075903>
     6
     7        Reviewed by Brady Eidson.
     8
     9        Make dispatching of DOM events when restoring a page from the page cache symmetric with
     10        dispatching of events when saving a page to the page cache.
     11
     12        * history/CachedFrame.cpp:
     13        (WebCore::CachedFrameBase::restore): Move code to dispatch events from here to FrameLoader::didRestoreFromCachedPage().
     14        * loader/FrameLoader.cpp:
     15        (WebCore::FrameLoader::commitProvisionalLoad): Ensure that no DOM events are dispatched during
     16        restoration of a cached page. Call didRestoreFromCachedPage() after restoring the page to
     17        dispatch DOM events on the restored frames.
     18        (WebCore::FrameLoader::willRestoreFromCachedPage): Renamed; formerly named prepareForCachedPageRestore().
     19        (WebCore::FrameLoader::didRestoreFromCachedPage): Added.
     20        (WebCore::FrameLoader::prepareForCachedPageRestore): Renamed to willRestoreFromCachedPage().
     21        * loader/FrameLoader.h:
     22        * page/FrameTree.cpp:
     23        (WebCore::FrameTree::traverseNextInPostOrderWithWrap): Returns the next Frame* in a post-order
     24        traversal of the frame tree optionally wrapping around to the deepest first child in the tree.
     25        (WebCore::FrameTree::deepFirstChild): Added.
     26        * page/FrameTree.h:
     27
    1282017-03-15  Dave Hyatt  <hyatt@apple.com>
    229
  • trunk/Source/WebCore/history/CachedFrame.cpp

    r212173 r214014  
    3636#include "FrameLoaderClient.h"
    3737#include "FrameView.h"
    38 #include "HistoryController.h"
    39 #include "HistoryItem.h"
    4038#include "Logging.h"
    4139#include "MainFrame.h"
    4240#include "Page.h"
    4341#include "PageCache.h"
    44 #include "PageTransitionEvent.h"
    4542#include "SVGDocumentExtensions.h"
    4643#include "ScriptController.h"
     
    117114        frame.tree().appendChild(childFrame->view()->frame());
    118115        childFrame->open();
     116        ASSERT_WITH_SECURITY_IMPLICATION(m_document == frame.document());
    119117    }
    120118
     
    132130#endif
    133131
    134     // FIXME: update Page Visibility state here.
    135     // https://bugs.webkit.org/show_bug.cgi?id=116770
    136     m_document->enqueuePageshowEvent(PageshowEventPersisted);
    137 
    138     HistoryItem* historyItem = frame.loader().history().currentItem();
    139     if (historyItem && historyItem->stateObject())
    140         m_document->enqueuePopstateEvent(historyItem->stateObject());
    141 
    142132    frame.view()->didRestoreFromPageCache();
    143133}
  • trunk/Source/WebCore/loader/FrameLoader.cpp

    r213621 r214014  
    8787#include "MemoryCache.h"
    8888#include "MemoryRelease.h"
     89#include "NoEventDispatchAssertion.h"
    8990#include "Page.h"
    9091#include "PageCache.h"
     
    18141815        m_frame.page()->chrome().setDispatchViewportDataDidChangeSuppressed(true);
    18151816#endif
    1816         prepareForCachedPageRestore();
     1817        willRestoreFromCachedPage();
    18171818
    18181819        // Start request for the main resource and dispatch didReceiveResponse before the load is committed for
     
    18261827        std::optional<HasInsecureContent> hasInsecureContent = cachedPage->cachedMainFrame()->hasInsecureContent();
    18271828
    1828         // FIXME: This API should be turned around so that we ground CachedPage into the Page.
    1829         cachedPage->restore(*m_frame.page());
     1829        {
     1830            // Do not dispatch DOM events as their JavaScript listeners could cause the page to be put
     1831            // into the page cache before we have finished restoring it from the page cache.
     1832            NoEventDispatchAssertion assertNoEventDispatch;
     1833
     1834            // FIXME: This API should be turned around so that we ground CachedPage into the Page.
     1835            cachedPage->restore(*m_frame.page());
     1836        }
    18301837
    18311838        dispatchDidCommitLoad(hasInsecureContent);
     1839
     1840        didRestoreFromCachedPage();
     1841
    18321842#if PLATFORM(IOS)
    18331843        m_frame.page()->chrome().setDispatchViewportDataDidChangeSuppressed(false);
     
    20482058}
    20492059
    2050 void FrameLoader::prepareForCachedPageRestore()
     2060void FrameLoader::willRestoreFromCachedPage()
    20512061{
    20522062    ASSERT(!m_frame.tree().parent());
     
    20642074        window->setStatus(String());
    20652075        window->setDefaultStatus(String());
     2076    }
     2077}
     2078
     2079void FrameLoader::didRestoreFromCachedPage()
     2080{
     2081    // Dispatching JavaScript events can cause frame destruction.
     2082    auto& mainFrame = m_frame.page()->mainFrame();
     2083    Vector<Ref<Frame>> childFrames;
     2084    for (auto* child = mainFrame.tree().traverseNextInPostOrderWithWrap(true); child; child = child->tree().traverseNextInPostOrderWithWrap(false))
     2085        childFrames.append(*child);
     2086
     2087    for (auto& child : childFrames) {
     2088        if (!child->tree().isDescendantOf(&mainFrame))
     2089            continue;
     2090        auto* document = child->document();
     2091        if (!document)
     2092            continue;
     2093
     2094        // FIXME: Update Page Visibility state here.
     2095        // https://bugs.webkit.org/show_bug.cgi?id=116770
     2096        document->enqueuePageshowEvent(PageshowEventPersisted);
     2097
     2098        auto* historyItem = child->loader().history().currentItem();
     2099        if (historyItem && historyItem->stateObject())
     2100            document->enqueuePopstateEvent(historyItem->stateObject());
    20662101    }
    20672102}
  • trunk/Source/WebCore/loader/FrameLoader.h

    r213590 r214014  
    346346
    347347    void closeOldDataSources();
    348     void prepareForCachedPageRestore();
     348    void willRestoreFromCachedPage();
     349    void didRestoreFromCachedPage();
    349350
    350351    bool shouldReloadToHandleUnreachableURL(DocumentLoader*);
  • trunk/Source/WebCore/page/FrameTree.cpp

    r211033 r214014  
    432432}
    433433
     434Frame* FrameTree::traverseNextInPostOrderWithWrap(bool wrap) const
     435{
     436    if (m_nextSibling)
     437        return m_nextSibling->tree().deepFirstChild();
     438    if (m_parent)
     439        return m_parent;
     440    if (wrap)
     441        return deepFirstChild();
     442    return nullptr;
     443}
     444
     445Frame* FrameTree::deepFirstChild() const
     446{
     447    Frame* result = &m_thisFrame;
     448    while (auto* next = result->tree().firstChild())
     449        result = next;
     450    return result;
     451}
     452
    434453Frame* FrameTree::deepLastChild() const
    435454{
  • trunk/Source/WebCore/page/FrameTree.h

    r211033 r214014  
    6565    WEBCORE_EXPORT Frame* traverseNextWithWrap(bool) const;
    6666    WEBCORE_EXPORT Frame* traversePreviousWithWrap(bool) const;
    67    
     67
     68    Frame* traverseNextInPostOrderWithWrap(bool) const;
     69
    6870    WEBCORE_EXPORT void appendChild(Frame&);
    6971    void detachFromParent() { m_parent = nullptr; }
     
    8688
    8789private:
     90    Frame* deepFirstChild() const;
    8891    Frame* deepLastChild() const;
    8992
Note: See TracChangeset for help on using the changeset viewer.