Bug 504837: Hashchange event should not be restricted to firing only when the document's readystate is 'complete'. r/sr=smaug
--- a/docshell/test/Makefile.in
+++ b/docshell/test/Makefile.in
@@ -71,13 +71,12 @@ include $(topsrcdir)/config/rules.mk
bug413310-post.sjs \
test_bug402210.html \
test_bug475636.html \
file_bug475636.sjs \
test_bug385434.html \
file_bug385434_1.html \
file_bug385434_2.html \
file_bug385434_3.html \
- file_bug385434_4.html \
$(NULL)
libs:: $(_TEST_FILES)
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
--- a/docshell/test/file_bug385434_3.html
+++ b/docshell/test/file_bug385434_3.html
@@ -2,24 +2,19 @@
Inner frame for test of bug 385434.
https://bugzilla.mozilla.org/show_bug.cgi?id=385434
-->
<html>
<head>
<script type="application/javascript">
// Notify our parent if we have a hashchange and once we're done loading.
window.addEventListener("hashchange", parent.onIframeHashchange, false);
- window.addEventListener("load", parent.onIframeLoad, false);
- // This shouldn't trigger a hashchange, because we haven't finished loading
- // the document.
- window.location.hash = "1";
-
window.addEventListener("DOMContentLoaded", function() {
- // This also shouldn't trigger a hashchange, becuase the readystate is
+ // This also should trigger a hashchange, becuase the readystate is
// "interactive", not "complete" during DOMContentLoaded.
window.location.hash = "2";
}, false);
</script>
</head>
<body>
deleted file mode 100644
--- a/docshell/test/file_bug385434_4.html
+++ /dev/null
@@ -1,36 +0,0 @@
-<!--
-Inner frame for test of bug 385434.
-https://bugzilla.mozilla.org/show_bug.cgi?id=385434
--->
-<html>
-<head>
- <script type="application/javascript">
- window.addEventListener("hashchange", function() {
- parent.statusMsg("Hashchange in 4a.");
- parent.onIframeHashchange();
- }, false);
-
- window.addEventListener("load", function() {
- parent.statusMsg("Load listener.");
- document.location.hash = "foo";
-
- // synchronously wipe out the whole document. The new document shouldn't
- // have a hashchange event dispatched to it.
- document.open();
-
- window.addEventListener("hashchange", function() {
- parent.statusMsg("Hashchange in 4a after document.open()");
- parent.onIframeHashchange();
- }, false);
-
- }, false);
-
- </script>
-</head>
-<body>
-<!-- This page is loaded in an iframe 100px high, so the div below forces #foo
- off the screen, and we can count that focusing it will trigger a scroll.-->
-<div style="height:200px"></div>
-<a name="foo">Foo</a>
-</body>
-</html>
--- a/docshell/test/test_bug385434.html
+++ b/docshell/test/test_bug385434.html
@@ -164,90 +164,46 @@ function run_test() {
longWait();
yield;
noEventExpected("Moving between different Documents shouldn't " +
"trigger a hashchange.");
/*
* TEST 2 tests that:
* <frameset onhashchange = ... > works,
+ * the event is targeted at the window object
* the event's cancelable, bubbles settings are correct
*/
enableIframeLoadCallback();
frameCw.document.location = "file_bug385434_2.html";
yield;
frameCw.document.location = "file_bug385434_2.html#foo";
yield;
eventExpected("frame onhashchange should fire events.");
// iframe should set gSampleEvent
+ is(gSampleEvent.target, frameCw,
+ "The hashchange event should be targeted to the window.");
is(gSampleEvent.type, "hashchange",
"Event type should be 'hashchange'.");
is(gSampleEvent.cancelable, false,
"The hashchange event shouldn't be cancelable.");
is(gSampleEvent.bubbles, false,
"The hashchange event shouldn't bubble.");
/*
* TEST 3 tests that:
- * hashchange is not dispatched if the current document readyState is
- * not "complete".
+ * hashchange is dispatched if the current document readyState is
+ * not "complete" (bug 504837).
*/
- enableIframeLoadCallback();
frameCw.document.location = "file_bug385434_3.html";
yield;
- noEventExpected("Hashchange shouldn't fire if the document " +
- "hasn't finished loading.");
-
- longWait();
- yield;
- noEventExpected("Hashchange shouldn't fire after longWait() if " +
- "the document hasn't finished loading.");
-
- /*
- * TEST 4 tests that if we
- *
- * * Load a page A
- * * Register a hashchange callback on A
- * * Navigate to A#foo
- * * Redirect to a different page, B, before the hashchange event triggered
- * by redirecting to A#foo fires,
- *
- * a hashchange event is not fired on B.
- */
- statusMsg("Starting test 4.");
- frameCw.document.location = "file_bug385434_4.html";
- longWait();
- yield;
- noEventExpected("Test 4 sequence shouldn't trigger a hashchange.");
-
- /*
- * TEST 5 tests that:
- * document.window.addEventListener() works for hashchange,
- * hashchange is dispatched to window, not to body
- */
-
- // Make sure the current window doesn't have a hash, as would happen if we
- // were running this test interactively and it hung right after we assigned a
- // value to window.location.hash
- window.location.hash = "";
-
- window.addEventListener("hashchange", onIframeHashchange, false);
- window.location.hash = "#foo";
- yield;
- eventExpected("addEventListener() should work for hashchange.");
- window.removeEventListener("hashchange", onIframeHashchange, false);
-
- document.body.addEventListener("hashchange", onIframeHashchange, false);
- enableIframeLoadCallback();
- window.location.hash = "#baz";
- longWait();
- yield;
- noEventExpected("hashchange shouldn't be dispatched to <body>.");
+ eventExpected("Hashchange should fire even if the document " +
+ "hasn't finished loading.");
SimpleTest.finish();
yield;
}
var gGen = run_test();
gGen.next();
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -6730,22 +6730,16 @@ nsGlobalWindow::PageHidden()
mNeedsFocus = PR_TRUE;
}
nsresult
nsGlobalWindow::DispatchAsyncHashchange()
{
FORWARD_TO_INNER(DispatchAsyncHashchange, (), NS_OK);
- nsIDocument::ReadyState readyState = mDoc->GetReadyStateEnum();
-
- // We only queue up the event if the ready state is currently "complete"
- if (readyState != nsIDocument::READYSTATE_COMPLETE)
- return NS_OK;
-
nsCOMPtr<nsIRunnable> event =
NS_NEW_RUNNABLE_METHOD(nsGlobalWindow, this, FireHashchange);
return NS_DispatchToCurrentThread(event);
}
nsresult
nsGlobalWindow::FireHashchange()