Bug 1104732 - having deferred scripts shouldn't cause async scripts to delay domcontentloaded, r?smaug
authorGijs Kruitbosch <gijskruitbosch@gmail.com>
Thu, 28 May 2015 13:40:07 +0100
changeset 246145 991331d28d8e481f8875386fed0824f42d283f2d
parent 246144 9ef73cc7ef3da0fd8b6640c2986f6efa27f41492
child 246146 14a44154018ad9b5c51de4def9f0a0bc9180b9f4
push id60383
push usergijskruitbosch@gmail.com
push dateFri, 29 May 2015 10:50:48 +0000
treeherdermozilla-inbound@991331d28d8e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1104732
milestone41.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1104732 - having deferred scripts shouldn't cause async scripts to delay domcontentloaded, r?smaug
dom/base/nsScriptLoader.cpp
parser/htmlparser/tests/mochitest/file_async_bug1104732.sjs
parser/htmlparser/tests/mochitest/file_defer_bug1104732.js
parser/htmlparser/tests/mochitest/mochitest.ini
parser/htmlparser/tests/mochitest/test_bug1104732.html
--- a/dom/base/nsScriptLoader.cpp
+++ b/dom/base/nsScriptLoader.cpp
@@ -1205,24 +1205,28 @@ nsScriptLoader::ProcessPendingRequests()
   }
 
   while (!mPendingChildLoaders.IsEmpty() && ReadyToExecuteScripts()) {
     nsRefPtr<nsScriptLoader> child = mPendingChildLoaders[0];
     mPendingChildLoaders.RemoveElementAt(0);
     child->RemoveExecuteBlocker();
   }
 
+  if (mDocumentParsingDone && mDocument && !mParserBlockingRequest &&
+      mNonAsyncExternalScriptInsertedRequests.isEmpty() &&
+      mXSLTRequests.isEmpty() && mDeferRequests.isEmpty() &&
+      MaybeRemovedDeferRequests()) {
+    return ProcessPendingRequests();
+  }
+
   if (mDocumentParsingDone && mDocument &&
       !mParserBlockingRequest && mLoadingAsyncRequests.isEmpty() &&
       mLoadedAsyncRequests.isEmpty() &&
       mNonAsyncExternalScriptInsertedRequests.isEmpty() &&
       mXSLTRequests.isEmpty() && mDeferRequests.isEmpty()) {
-    if (MaybeRemovedDeferRequests()) {
-      return ProcessPendingRequests();
-    }
     // No more pending scripts; time to unblock onload.
     // OK to unblock onload synchronously here, since callers must be
     // prepared for the world changing anyway.
     mDocumentParsingDone = false;
     mDocument->UnblockOnload(true);
   }
 }
 
new file mode 100644
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_async_bug1104732.sjs
@@ -0,0 +1,14 @@
+var timer = null;
+
+function handleRequest(request, response)
+{
+  response.processAsync();
+  response.setHeader("Content-Type", "application/javascript", false);
+  response.write("state = 'mid-async';\n");
+
+  timer = Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer);
+  timer.initWithCallback(function() {
+    response.write("state = 'async loaded';\n");
+    response.finish();
+  }, 5 * 1000 /* milliseconds */, timer.TYPE_ONE_SHOT);
+}
new file mode 100644
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_defer_bug1104732.js
@@ -0,0 +1,3 @@
+is(document.readyState, "interactive", "readyState should be interactive during defer.");
+state = "defer";
+
--- a/parser/htmlparser/tests/mochitest/mochitest.ini
+++ b/parser/htmlparser/tests/mochitest/mochitest.ini
@@ -124,16 +124,21 @@ support-files =
 [test_bug672453.html]
 [test_bug688580.html]
 [test_bug688580.xhtml]
 [test_bug709083.html]
 [test_bug715112.html]
 [test_bug715739.html]
 [test_bug716579.html]
 [test_bug717180.html]
+[test_bug1104732.html]
+support-files =
+  file_defer_bug1104732.js
+  file_async_bug1104732.sjs
+
 [test_compatmode.html]
 [test_html5_tree_construction.html]
 skip-if = toolkit == 'android' #TIMED_OUT
 [test_html5_tree_construction_part2.html]
 skip-if = toolkit == 'android' || e10s #TIMED_OUT
 [test_img_picture_preload.html]
 [test_viewsource.html]
 [test_xml_mislabeled.html]
new file mode 100644
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_bug1104732.html
@@ -0,0 +1,50 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1104732
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 1104732</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="application/javascript">
+
+  /** Test for Bug 1104732 **/
+
+  // Expected order of the values of the "state" variable:
+  // Test starting
+  // defer
+  // DOMContentLoaded
+  // async loaded
+  // load
+
+  var state = "Test starting";
+  SimpleTest.waitForExplicitFinish();
+  is(document.readyState, "loading", "Document should have been loading.");
+  document.addEventListener("DOMContentLoaded", function () {
+    is(document.readyState, "interactive", "readyState should be interactive during DOMContentLoaded.");
+    is(state, "defer", "Bad state upon DOMContentLoaded");
+    state = "DOMContentLoaded";
+  });
+  window.addEventListener("load", function () {
+    is(document.readyState, "complete", "readyState should be complete during load.");
+    is(state, "async loaded", "Bad state upon load")
+    state = "load";
+    SimpleTest.finish();
+  });
+  </script>
+  <script defer src="file_defer_bug1104732.js"></script>
+  <script async src="file_async_bug1104732.sjs"></script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1104732">Mozilla Bug 1104732</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
+