- Revision
- 197935
- Author
- [email protected]
- Date
- 2016-03-10 08:10:24 -0800 (Thu, 10 Mar 2016)
Log Message
Merge r196807 - Revert to dispatching the popstate event synchronously
https://bugs.webkit.org/show_bug.cgi?id=153297
rdar://problem/24092294
Reviewed by Brent Fulgham.
Source/WebCore:
r192369 made the popstate event dispatch asynchronously, which matches what the HTML5 spec says to do. However,
due to compatibility regressions we need to revert back to dispatching synchronously. This change reverts
r192369's changes to Document.cpp, but retains the new tests.
Firing popstate synchronously makes both fast/loader/remove-iframe-during-history-navigation-different.html and
fast/loader/remove-iframe-during-history-navigation-same.html crash, because their onpopstate handlers remove
frames from the document that will later be accessed by HistoryController::recursiveGoToItem().
To prevent the crashes, this change does two things:
1. Keep a reference to the current frame inside FrameLoader::loadSameDocumentItem(), since calling
loadInSameDocument() might otherwise delete it.
2. Handle a null frame when iterating a HistoryItem's child frames in HistoryController::recursiveGoToItem(),
since calling goToItem() on one frame might cause another frame to be deleted.
Covered by existing tests. fast/loader/stateobjects/popstate-is-asynchronous.html was renamed to
fast/loader/stateobjects/popstate-is-synchronous.html and modified to expect synchronous dispatch.
* dom/Document.cpp:
(WebCore::Document::enqueuePopstateEvent):
* loader/FrameLoader.cpp:
(WebCore::FrameLoader::loadSameDocumentItem):
* loader/HistoryController.cpp:
(WebCore::HistoryController::recursiveGoToItem):
LayoutTests:
Renamed and modified this test to expect synchronous dispatch.
* fast/loader/stateobjects/popstate-is-synchronous-expected.txt: Renamed from LayoutTests/fast/loader/stateobjects/popstate-is-asynchronous-expected.txt.
* fast/loader/stateobjects/popstate-is-synchronous.html: Renamed from LayoutTests/fast/loader/stateobjects/popstate-is-asynchronous.html.
Modified Paths
Added Paths
Removed Paths
Diff
Modified: releases/WebKitGTK/webkit-2.10/LayoutTests/ChangeLog (197934 => 197935)
--- releases/WebKitGTK/webkit-2.10/LayoutTests/ChangeLog 2016-03-10 16:09:46 UTC (rev 197934)
+++ releases/WebKitGTK/webkit-2.10/LayoutTests/ChangeLog 2016-03-10 16:10:24 UTC (rev 197935)
@@ -1,3 +1,16 @@
+2016-02-18 Andy Estes <[email protected]>
+
+ Revert to dispatching the popstate event synchronously
+ https://bugs.webkit.org/show_bug.cgi?id=153297
+ rdar://problem/24092294
+
+ Reviewed by Brent Fulgham.
+
+ Renamed and modified this test to expect synchronous dispatch.
+
+ * fast/loader/stateobjects/popstate-is-synchronous-expected.txt: Renamed from LayoutTests/fast/loader/stateobjects/popstate-is-asynchronous-expected.txt.
+ * fast/loader/stateobjects/popstate-is-synchronous.html: Renamed from LayoutTests/fast/loader/stateobjects/popstate-is-asynchronous.html.
+
2015-11-11 Jon Honeycutt <[email protected]>
popstate event should be dispatched asynchronously
Deleted: releases/WebKitGTK/webkit-2.10/LayoutTests/fast/loader/stateobjects/popstate-is-asynchronous-expected.txt (197934 => 197935)
--- releases/WebKitGTK/webkit-2.10/LayoutTests/fast/loader/stateobjects/popstate-is-asynchronous-expected.txt 2016-03-10 16:09:46 UTC (rev 197934)
+++ releases/WebKitGTK/webkit-2.10/LayoutTests/fast/loader/stateobjects/popstate-is-asynchronous-expected.txt 2016-03-10 16:10:24 UTC (rev 197935)
@@ -1,13 +0,0 @@
-Tests that popstate events fire asynchronously.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-onload fired
-popstate fired
-Setting hash to #foo
-Set hash to #foo
-popstate fired
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
Deleted: releases/WebKitGTK/webkit-2.10/LayoutTests/fast/loader/stateobjects/popstate-is-asynchronous.html (197934 => 197935)
--- releases/WebKitGTK/webkit-2.10/LayoutTests/fast/loader/stateobjects/popstate-is-asynchronous.html 2016-03-10 16:09:46 UTC (rev 197934)
+++ releases/WebKitGTK/webkit-2.10/LayoutTests/fast/loader/stateobjects/popstate-is-asynchronous.html 2016-03-10 16:10:24 UTC (rev 197935)
@@ -1,40 +0,0 @@
-<!DOCTYPE html>
-<html>
-<body>
-<link rel="stylesheet" href="" type="text/css">
-<script src=""
-<div id="description"></div>
-<pre id="console"></pre>
-<script>
-description('Tests that popstate events fire asynchronously.');
-
-window._onload_ = function()
-{
- debug('onload fired');
- history.pushState("test", "test");
- history.back();
-}
-
-var initialPopState = true;
-
-window._onpopstate_ = function()
-{
- debug('popstate fired');
-
- if (initialPopState) {
- initialPopState = false;
-
- // This should not be re-entrant; there should be no other log lines
- // between the "Setting..." and "Set..." lines.
- debug('Setting hash to #foo');
- location.hash = '#foo';
- debug('Set hash to #foo');
- } else
- finishJSTest();
-}
-
-var successfullyParsed = true;
-var jsTestIsAsync = true;
-</script>
-<script src=""
-</html>
Copied: releases/WebKitGTK/webkit-2.10/LayoutTests/fast/loader/stateobjects/popstate-is-synchronous-expected.txt (from rev 197934, releases/WebKitGTK/webkit-2.10/LayoutTests/fast/loader/stateobjects/popstate-is-asynchronous-expected.txt) (0 => 197935)
--- releases/WebKitGTK/webkit-2.10/LayoutTests/fast/loader/stateobjects/popstate-is-synchronous-expected.txt (rev 0)
+++ releases/WebKitGTK/webkit-2.10/LayoutTests/fast/loader/stateobjects/popstate-is-synchronous-expected.txt 2016-03-10 16:10:24 UTC (rev 197935)
@@ -0,0 +1,13 @@
+Tests that popstate events fire synchronously during fragment navigation.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+onload fired
+popstate fired
+Setting hash to #foo
+popstate fired
+Set hash to #foo
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Copied: releases/WebKitGTK/webkit-2.10/LayoutTests/fast/loader/stateobjects/popstate-is-synchronous.html (from rev 197934, releases/WebKitGTK/webkit-2.10/LayoutTests/fast/loader/stateobjects/popstate-is-asynchronous.html) (0 => 197935)
--- releases/WebKitGTK/webkit-2.10/LayoutTests/fast/loader/stateobjects/popstate-is-synchronous.html (rev 0)
+++ releases/WebKitGTK/webkit-2.10/LayoutTests/fast/loader/stateobjects/popstate-is-synchronous.html 2016-03-10 16:10:24 UTC (rev 197935)
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+<body>
+<link rel="stylesheet" href="" type="text/css">
+<script src=""
+<div id="description"></div>
+<pre id="console"></pre>
+<script>
+description('Tests that popstate events fire synchronously during fragment navigation.');
+
+window._onload_ = function()
+{
+ debug('onload fired');
+ history.pushState("test", "test");
+ history.back();
+}
+
+var initialPopState = true;
+
+window._onpopstate_ = function()
+{
+ debug('popstate fired');
+
+ if (!initialPopState) {
+ window.setTimeout(finishJSTest, 0);
+ return;
+ }
+
+ initialPopState = false;
+
+ debug('Setting hash to #foo');
+ location.hash = '#foo';
+ debug('Set hash to #foo');
+}
+
+var successfullyParsed = true;
+var jsTestIsAsync = true;
+</script>
+<script src=""
+</html>
Modified: releases/WebKitGTK/webkit-2.10/Source/WebCore/ChangeLog (197934 => 197935)
--- releases/WebKitGTK/webkit-2.10/Source/WebCore/ChangeLog 2016-03-10 16:09:46 UTC (rev 197934)
+++ releases/WebKitGTK/webkit-2.10/Source/WebCore/ChangeLog 2016-03-10 16:10:24 UTC (rev 197935)
@@ -1,3 +1,35 @@
+2016-02-18 Andy Estes <[email protected]>
+
+ Revert to dispatching the popstate event synchronously
+ https://bugs.webkit.org/show_bug.cgi?id=153297
+ rdar://problem/24092294
+
+ Reviewed by Brent Fulgham.
+
+ r192369 made the popstate event dispatch asynchronously, which matches what the HTML5 spec says to do. However,
+ due to compatibility regressions we need to revert back to dispatching synchronously. This change reverts
+ r192369's changes to Document.cpp, but retains the new tests.
+
+ Firing popstate synchronously makes both fast/loader/remove-iframe-during-history-navigation-different.html and
+ fast/loader/remove-iframe-during-history-navigation-same.html crash, because their onpopstate handlers remove
+ frames from the document that will later be accessed by HistoryController::recursiveGoToItem().
+
+ To prevent the crashes, this change does two things:
+ 1. Keep a reference to the current frame inside FrameLoader::loadSameDocumentItem(), since calling
+ loadInSameDocument() might otherwise delete it.
+ 2. Handle a null frame when iterating a HistoryItem's child frames in HistoryController::recursiveGoToItem(),
+ since calling goToItem() on one frame might cause another frame to be deleted.
+
+ Covered by existing tests. fast/loader/stateobjects/popstate-is-asynchronous.html was renamed to
+ fast/loader/stateobjects/popstate-is-synchronous.html and modified to expect synchronous dispatch.
+
+ * dom/Document.cpp:
+ (WebCore::Document::enqueuePopstateEvent):
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::loadSameDocumentItem):
+ * loader/HistoryController.cpp:
+ (WebCore::HistoryController::recursiveGoToItem):
+
2015-11-11 Jon Honeycutt <[email protected]>
popstate event should be dispatched asynchronously
Modified: releases/WebKitGTK/webkit-2.10/Source/WebCore/dom/Document.cpp (197934 => 197935)
--- releases/WebKitGTK/webkit-2.10/Source/WebCore/dom/Document.cpp 2016-03-10 16:09:46 UTC (rev 197934)
+++ releases/WebKitGTK/webkit-2.10/Source/WebCore/dom/Document.cpp 2016-03-10 16:10:24 UTC (rev 197935)
@@ -5363,7 +5363,7 @@
void Document::enqueuePopstateEvent(PassRefPtr<SerializedScriptValue> stateObject)
{
- enqueueWindowEvent(PopStateEvent::create(stateObject, m_domWindow ? m_domWindow->history() : nullptr));
+ dispatchWindowEvent(PopStateEvent::create(stateObject, m_domWindow ? m_domWindow->history() : nullptr));
}
void Document::addMediaCanStartListener(MediaCanStartListener* listener)
Modified: releases/WebKitGTK/webkit-2.10/Source/WebCore/loader/FrameLoader.cpp (197934 => 197935)
--- releases/WebKitGTK/webkit-2.10/Source/WebCore/loader/FrameLoader.cpp 2016-03-10 16:09:46 UTC (rev 197934)
+++ releases/WebKitGTK/webkit-2.10/Source/WebCore/loader/FrameLoader.cpp 2016-03-10 16:10:24 UTC (rev 197935)
@@ -3236,6 +3236,8 @@
{
ASSERT(item.documentSequenceNumber() == history().currentItem()->documentSequenceNumber());
+ Ref<Frame> protect(m_frame);
+
// Save user view state to the current history item here since we don't do a normal load.
// FIXME: Does form state need to be saved here too?
history().saveScrollPositionAndViewStateToItem(history().currentItem());
Modified: releases/WebKitGTK/webkit-2.10/Source/WebCore/loader/HistoryController.cpp (197934 => 197935)
--- releases/WebKitGTK/webkit-2.10/Source/WebCore/loader/HistoryController.cpp 2016-03-10 16:09:46 UTC (rev 197934)
+++ releases/WebKitGTK/webkit-2.10/Source/WebCore/loader/HistoryController.cpp 2016-03-10 16:10:24 UTC (rev 197935)
@@ -747,9 +747,8 @@
HistoryItem* fromChildItem = fromItem->childItemWithTarget(childFrameName);
ASSERT(fromChildItem);
- Frame* childFrame = m_frame.tree().child(childFrameName);
- ASSERT(childFrame);
- childFrame->loader().history().recursiveGoToItem(const_cast<HistoryItem&>(childItem.get()), fromChildItem, type);
+ if (Frame* childFrame = m_frame.tree().child(childFrameName))
+ childFrame->loader().history().recursiveGoToItem(const_cast<HistoryItem&>(childItem.get()), fromChildItem, type);
}
}