Changeset 214392 in webkit
- Timestamp:
- Mar 24, 2017 6:13:23 PM (7 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r214388 r214392 1 2017-03-24 Daniel Bates <dabates@apple.com> 2 3 media/restore-from-page-cache.html causes NoEventDispatchAssertion::isEventAllowedInMainThread() assertion failure 4 https://bugs.webkit.org/show_bug.cgi?id=170087 5 <rdar://problem/31254822> 6 7 Reviewed by Simon Fraser. 8 9 Reduce the scope of code that should never dispatch DOM events so as to allow updating contents size 10 after restoring a page from the page cache. 11 12 In r214014 we instantiate a NoEventDispatchAssertion in FrameLoader::commitProvisionalLoad() 13 around the call to CachedPage::restore() to assert when a DOM event is dispatched during 14 page restoration as such events can cause re-entrancy into the page cache. As it turns out 15 it is sufficient to ensure that no DOM events are dispatched after restoring all cached frames 16 as opposed to after CachedPage::restore() returns. 17 18 Also rename Document::enqueue{Pageshow, Popstate}Event() to dispatch{Pageshow, Popstate}Event(), 19 respectively, since they synchronously dispatch events :(. We hope in the future to make them 20 asynchronously dispatch events. 21 22 * dom/Document.cpp: 23 (WebCore::Document::implicitClose): Update for renaming. 24 (WebCore::Document::statePopped): Ditto. 25 (WebCore::Document::dispatchPageshowEvent): Renamed; formerly named enqueuePageshowEvent(). 26 (WebCore::Document::dispatchPopstateEvent): Renamed; formerly named enqueuePopstateEvent(). 27 (WebCore::Document::enqueuePageshowEvent): Deleted. 28 (WebCore::Document::enqueuePopstateEvent): Deleted. 29 * dom/Document.h: 30 * history/CachedPage.cpp: 31 (WebCore::firePageShowAndPopStateEvents): Moved logic from FrameLoader::didRestoreFromCachedPage() to here. 32 (WebCore::CachedPage::restore): Modified to call firePageShowAndPopStateEvents(). 33 * loader/FrameLoader.cpp: 34 (WebCore::FrameLoader::commitProvisionalLoad): Removed use of NoEventDispatchAssertion RAII object. We 35 will instantiate it in CachedPage::restore() with a smaller scope. 36 (WebCore::FrameLoader::didRestoreFromCachedPage): Deleted; moved logic from here to WebCore::firePageShowAndPopStateEvents(). 37 * loader/FrameLoader.h: 38 1 39 2017-03-24 Ryan Haddad <ryanhaddad@apple.com> 2 40 -
trunk/Source/WebCore/dom/Document.cpp
r214388 r214392 2645 2645 2646 2646 dispatchWindowLoadEvent(); 2647 enqueuePageshowEvent(PageshowEventNotPersisted);2647 dispatchPageshowEvent(PageshowEventNotPersisted); 2648 2648 if (m_pendingStateObject) 2649 enqueuePopstateEvent(WTFMove(m_pendingStateObject));2649 dispatchPopstateEvent(WTFMove(m_pendingStateObject)); 2650 2650 2651 2651 if (f) … … 5236 5236 // defer firing of popstate until we're in the complete state. 5237 5237 if (m_readyState == Complete) 5238 enqueuePopstateEvent(WTFMove(stateObject));5238 dispatchPopstateEvent(WTFMove(stateObject)); 5239 5239 else 5240 5240 m_pendingStateObject = WTFMove(stateObject); … … 5461 5461 } 5462 5462 5463 void Document:: enqueuePageshowEvent(PageshowEventPersistence persisted)5463 void Document::dispatchPageshowEvent(PageshowEventPersistence persisted) 5464 5464 { 5465 5465 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=36334 Pageshow event needs to fire asynchronously. … … 5472 5472 } 5473 5473 5474 void Document:: enqueuePopstateEvent(RefPtr<SerializedScriptValue>&& stateObject)5474 void Document::dispatchPopstateEvent(RefPtr<SerializedScriptValue>&& stateObject) 5475 5475 { 5476 5476 dispatchWindowEvent(PopStateEvent::create(WTFMove(stateObject), m_domWindow ? m_domWindow->history() : nullptr)); -
trunk/Source/WebCore/dom/Document.h
r214333 r214392 1059 1059 void enqueueDocumentEvent(Ref<Event>&&); 1060 1060 void enqueueOverflowEvent(Ref<Event>&&); 1061 void enqueuePageshowEvent(PageshowEventPersistence);1061 void dispatchPageshowEvent(PageshowEventPersistence); 1062 1062 void enqueueHashchangeEvent(const String& oldURL, const String& newURL); 1063 void enqueuePopstateEvent(RefPtr<SerializedScriptValue>&& stateObject);1063 void dispatchPopstateEvent(RefPtr<SerializedScriptValue>&& stateObject); 1064 1064 DocumentEventQueue& eventQueue() const final { return m_eventQueue; } 1065 1065 -
trunk/Source/WebCore/history/CachedPage.cpp
r211569 r214392 31 31 #include "FocusController.h" 32 32 #include "FrameView.h" 33 #include "HistoryController.h" 34 #include "HistoryItem.h" 33 35 #include "MainFrame.h" 36 #include "NoEventDispatchAssertion.h" 34 37 #include "Node.h" 35 38 #include "Page.h" 39 #include "PageTransitionEvent.h" 36 40 #include "Settings.h" 37 41 #include "VisitedLinkState.h" … … 70 74 } 71 75 76 static void firePageShowAndPopStateEvents(Page& page) 77 { 78 // Dispatching JavaScript events can cause frame destruction. 79 auto& mainFrame = page.mainFrame(); 80 Vector<Ref<Frame>> childFrames; 81 for (auto* child = mainFrame.tree().traverseNextInPostOrderWithWrap(true); child; child = child->tree().traverseNextInPostOrderWithWrap(false)) 82 childFrames.append(*child); 83 84 for (auto& child : childFrames) { 85 if (!child->tree().isDescendantOf(&mainFrame)) 86 continue; 87 auto* document = child->document(); 88 if (!document) 89 continue; 90 91 // FIXME: Update Page Visibility state here. 92 // https://bugs.webkit.org/show_bug.cgi?id=116770 93 document->dispatchPageshowEvent(PageshowEventPersisted); 94 95 auto* historyItem = child->loader().history().currentItem(); 96 if (historyItem && historyItem->stateObject()) 97 document->dispatchPopstateEvent(historyItem->stateObject()); 98 } 99 } 100 72 101 void CachedPage::restore(Page& page) 73 102 { … … 76 105 ASSERT(!page.subframeCount()); 77 106 78 m_cachedMainFrame->open(); 107 { 108 // Do not dispatch DOM events as their JavaScript listeners could cause the page to be put 109 // into the page cache before we have finished restoring it from the page cache. 110 NoEventDispatchAssertion noEventDispatchAssertion; 111 112 m_cachedMainFrame->open(); 113 } 79 114 80 115 // Restore the focus appearance for the focused element. … … 117 152 } 118 153 154 firePageShowAndPopStateEvents(page); 155 119 156 clear(); 120 157 } -
trunk/Source/WebCore/loader/FrameLoader.cpp
r214365 r214392 87 87 #include "MemoryCache.h" 88 88 #include "MemoryRelease.h" 89 #include "NoEventDispatchAssertion.h"90 89 #include "Page.h" 91 90 #include "PageCache.h" … … 1867 1866 std::optional<HasInsecureContent> hasInsecureContent = cachedPage->cachedMainFrame()->hasInsecureContent(); 1868 1867 1869 { 1870 // Do not dispatch DOM events as their JavaScript listeners could cause the page to be put 1871 // into the page cache before we have finished restoring it from the page cache. 1872 NoEventDispatchAssertion assertNoEventDispatch; 1873 1874 // FIXME: This API should be turned around so that we ground CachedPage into the Page. 1875 cachedPage->restore(*m_frame.page()); 1876 } 1868 // FIXME: This API should be turned around so that we ground CachedPage into the Page. 1869 cachedPage->restore(*m_frame.page()); 1877 1870 1878 1871 dispatchDidCommitLoad(hasInsecureContent); 1879 1880 didRestoreFromCachedPage();1881 1872 1882 1873 #if PLATFORM(IOS) … … 2110 2101 window->setStatus(String()); 2111 2102 window->setDefaultStatus(String()); 2112 }2113 }2114 2115 void FrameLoader::didRestoreFromCachedPage()2116 {2117 // Dispatching JavaScript events can cause frame destruction.2118 auto& mainFrame = m_frame.page()->mainFrame();2119 Vector<Ref<Frame>> childFrames;2120 for (auto* child = mainFrame.tree().traverseNextInPostOrderWithWrap(true); child; child = child->tree().traverseNextInPostOrderWithWrap(false))2121 childFrames.append(*child);2122 2123 for (auto& child : childFrames) {2124 if (!child->tree().isDescendantOf(&mainFrame))2125 continue;2126 auto* document = child->document();2127 if (!document)2128 continue;2129 2130 // FIXME: Update Page Visibility state here.2131 // https://bugs.webkit.org/show_bug.cgi?id=1167702132 document->enqueuePageshowEvent(PageshowEventPersisted);2133 2134 auto* historyItem = child->loader().history().currentItem();2135 if (historyItem && historyItem->stateObject())2136 document->enqueuePopstateEvent(historyItem->stateObject());2137 2103 } 2138 2104 } -
trunk/Source/WebCore/loader/FrameLoader.h
r214194 r214392 348 348 void closeOldDataSources(); 349 349 void willRestoreFromCachedPage(); 350 void didRestoreFromCachedPage();351 350 352 351 bool shouldReloadToHandleUnreachableURL(DocumentLoader*);
Note: See TracChangeset
for help on using the changeset viewer.