Bug 504837: Hashchange event should not be restricted to firing only when the document's readystate is 'complete'. r/sr=smaug
authorJustin Lebar <jlebar@mozilla.com>
Tue, 21 Jul 2009 14:17:15 -0700
changeset 30621 f82a5ce4c3ce84a2f17c9973ff2ae6b921d3e612
parent 30620 55955ee71c10022333105c2c5e9ec2a4199899c8
child 30622 b2d3327fb4ccfd51bf9aa90d3630aebc86144a9a
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
bugs504837
milestone1.9.2a1pre
Bug 504837: Hashchange event should not be restricted to firing only when the document's readystate is 'complete'. r/sr=smaug
docshell/test/Makefile.in
docshell/test/file_bug385434_3.html
docshell/test/file_bug385434_4.html
docshell/test/test_bug385434.html
dom/base/nsGlobalWindow.cpp
--- 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()