Title: [214236] branches/safari-603-branch/Source/WebCore

Diff

Modified: branches/safari-603-branch/Source/WebCore/ChangeLog (214235 => 214236)


--- branches/safari-603-branch/Source/WebCore/ChangeLog	2017-03-21 23:40:26 UTC (rev 214235)
+++ branches/safari-603-branch/Source/WebCore/ChangeLog	2017-03-22 00:06:26 UTC (rev 214236)
@@ -1,3 +1,34 @@
+2017-03-21  Jason Marcell  <jmarc...@apple.com>
+
+        Merge r214014. rdar://problem/30921815
+
+    2017-03-15  Daniel Bates  <daba...@apple.com>
+
+            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:
+
 2017-03-20  Matthew Hanson  <matthew_han...@apple.com>
 
         Merge r213949. rdar://problem/31049771

Modified: branches/safari-603-branch/Source/WebCore/history/CachedFrame.cpp (214235 => 214236)


--- branches/safari-603-branch/Source/WebCore/history/CachedFrame.cpp	2017-03-21 23:40:26 UTC (rev 214235)
+++ branches/safari-603-branch/Source/WebCore/history/CachedFrame.cpp	2017-03-22 00:06:26 UTC (rev 214236)
@@ -35,13 +35,10 @@
 #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 "PageCache.h"
-#include "PageTransitionEvent.h"
 #include "SVGDocumentExtensions.h"
 #include "ScriptController.h"
 #include "SerializedScriptValue.h"
@@ -102,6 +99,7 @@
     for (unsigned i = 0; i < m_childFrames.size(); ++i) {
         frame.tree().appendChild(&m_childFrames[i]->view()->frame());
         m_childFrames[i]->open();
+        ASSERT_WITH_SECURITY_IMPLICATION(m_document == frame.document());
     }
 
 #if PLATFORM(IOS)
@@ -117,14 +115,6 @@
     }
 #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();
-    if (historyItem && historyItem->stateObject())
-        m_document->enqueuePopstateEvent(historyItem->stateObject());
-
 #if ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS)
     if (m_document->hasTouchEventHandlers())
         m_document->page()->chrome().client().needTouchEvents(true);

Modified: branches/safari-603-branch/Source/WebCore/loader/FrameLoader.cpp (214235 => 214236)


--- branches/safari-603-branch/Source/WebCore/loader/FrameLoader.cpp	2017-03-21 23:40:26 UTC (rev 214235)
+++ branches/safari-603-branch/Source/WebCore/loader/FrameLoader.cpp	2017-03-22 00:06:26 UTC (rev 214236)
@@ -86,6 +86,7 @@
 #include "MainFrame.h"
 #include "MemoryCache.h"
 #include "MemoryRelease.h"
+#include "NoEventDispatchAssertion.h"
 #include "Page.h"
 #include "PageCache.h"
 #include "PageTransitionEvent.h"
@@ -1817,7 +1818,7 @@
         // commit to happen before any changes to viewport arguments and dealing with this there is difficult.
         m_frame.page()->chrome().setDispatchViewportDataDidChangeSuppressed(true);
 #endif
-        prepareForCachedPageRestore();
+        willRestoreFromCachedPage();
 
         // Start request for the main resource and dispatch didReceiveResponse before the load is committed for
         // consistency with all other loads. See https://bugs.webkit.org/show_bug.cgi?id=150927.
@@ -1829,10 +1830,19 @@
 
         std::optional<HasInsecureContent> hasInsecureContent = cachedPage->cachedMainFrame()->hasInsecureContent();
 
-        // FIXME: This API should be turned around so that we ground CachedPage into the Page.
-        cachedPage->restore(*m_frame.page());
+        {
+            // Do not dispatch DOM events as their _javascript_ listeners could cause the page to be put
+            // into the page cache before we have finished restoring it from the page cache.
+            NoEventDispatchAssertion assertNoEventDispatch;
 
+            // FIXME: This API should be turned around so that we ground CachedPage into the Page.
+            cachedPage->restore(*m_frame.page());
+        }
+
         dispatchDidCommitLoad(hasInsecureContent);
+
+        didRestoreFromCachedPage();
+
 #if PLATFORM(IOS)
         m_frame.page()->chrome().setDispatchViewportDataDidChangeSuppressed(false);
         m_frame.page()->chrome().dispatchViewportPropertiesDidChange(m_frame.page()->viewportArguments());
@@ -2058,7 +2068,7 @@
     m_client.setMainFrameDocumentReady(false); // stop giving out the actual DOMDocument to observers
 }
 
-void FrameLoader::prepareForCachedPageRestore()
+void FrameLoader::willRestoreFromCachedPage()
 {
     ASSERT(!m_frame.tree().parent());
     ASSERT(m_frame.page());
@@ -2077,6 +2087,31 @@
     }
 }
 
+void FrameLoader::didRestoreFromCachedPage()
+{
+    // Dispatching _javascript_ events can cause frame destruction.
+    auto& mainFrame = m_frame.page()->mainFrame();
+    Vector<Ref<Frame>> childFrames;
+    for (auto* child = mainFrame.tree().traverseNextInPostOrderWithWrap(true); child; child = child->tree().traverseNextInPostOrderWithWrap(false))
+        childFrames.append(*child);
+
+    for (auto& child : childFrames) {
+        if (!child->tree().isDescendantOf(&mainFrame))
+            continue;
+        auto* document = child->document();
+        if (!document)
+            continue;
+
+        // FIXME: Update Page Visibility state here.
+        // https://bugs.webkit.org/show_bug.cgi?id=116770
+        document->enqueuePageshowEvent(PageshowEventPersisted);
+
+        auto* historyItem = child->loader().history().currentItem();
+        if (historyItem && historyItem->stateObject())
+            document->enqueuePopstateEvent(historyItem->stateObject());
+    }
+}
+
 void FrameLoader::open(CachedFrameBase& cachedFrame)
 {
     m_isComplete = false;

Modified: branches/safari-603-branch/Source/WebCore/loader/FrameLoader.h (214235 => 214236)


--- branches/safari-603-branch/Source/WebCore/loader/FrameLoader.h	2017-03-21 23:40:26 UTC (rev 214235)
+++ branches/safari-603-branch/Source/WebCore/loader/FrameLoader.h	2017-03-22 00:06:26 UTC (rev 214236)
@@ -347,7 +347,8 @@
     void setState(FrameState);
 
     void closeOldDataSources();
-    void prepareForCachedPageRestore();
+    void willRestoreFromCachedPage();
+    void didRestoreFromCachedPage();
 
     bool shouldReloadToHandleUnreachableURL(DocumentLoader*);
 

Modified: branches/safari-603-branch/Source/WebCore/page/FrameTree.cpp (214235 => 214236)


--- branches/safari-603-branch/Source/WebCore/page/FrameTree.cpp	2017-03-21 23:40:26 UTC (rev 214235)
+++ branches/safari-603-branch/Source/WebCore/page/FrameTree.cpp	2017-03-22 00:06:26 UTC (rev 214236)
@@ -464,6 +464,25 @@
     return nullptr;
 }
 
+Frame* FrameTree::traverseNextInPostOrderWithWrap(bool wrap) const
+{
+    if (m_nextSibling)
+        return m_nextSibling->tree().deepFirstChild();
+    if (m_parent)
+        return m_parent;
+    if (wrap)
+        return deepFirstChild();
+    return nullptr;
+}
+
+Frame* FrameTree::deepFirstChild() const
+{
+    Frame* result = &m_thisFrame;
+    while (auto* next = result->tree().firstChild())
+        result = next;
+    return result;
+}
+
 Frame* FrameTree::deepLastChild() const
 {
     Frame* result = &m_thisFrame;

Modified: branches/safari-603-branch/Source/WebCore/page/FrameTree.h (214235 => 214236)


--- branches/safari-603-branch/Source/WebCore/page/FrameTree.h	2017-03-21 23:40:26 UTC (rev 214235)
+++ branches/safari-603-branch/Source/WebCore/page/FrameTree.h	2017-03-22 00:06:26 UTC (rev 214236)
@@ -67,6 +67,9 @@
     
     WEBCORE_EXPORT void appendChild(PassRefPtr<Frame>);
     bool transferChild(PassRefPtr<Frame>);
+
+    Frame* traverseNextInPostOrderWithWrap(bool) const;
+
     void detachFromParent() { m_parent = nullptr; }
     void removeChild(Frame*);
 
@@ -86,6 +89,7 @@
     unsigned indexInParent() const;
 
 private:
+    Frame* deepFirstChild() const;
     Frame* deepLastChild() const;
     void actuallyAppendChild(PassRefPtr<Frame>);
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to