Backed out changeset f52c26d677b0 (bug 918703)
authorSebastian Hengst <archaeopteryx@coole-files.de>
Sun, 17 Jul 2016 12:55:38 +0200
changeset 330380 33e438fbb442212265493d533b3794a29308b981
parent 330379 1d657d984bed365b1c2bdc499532cf34c60b1edd
child 330381 d8201a97184f2f6cdcd70f19d8d6fc90e5589f33
push id9858
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 14:37:10 +0000
treeherdermozilla-aurora@203106ef6cb6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs918703
milestone50.0a1
backs outf52c26d677b09dd07a3967d1b294776e2c4559e3
Backed out changeset f52c26d677b0 (bug 918703)
dom/base/test/fileutils.js
dom/base/test/test_bug435425.html
dom/workers/test/bug1063538_worker.js
dom/workers/test/test_bug1063538.html
dom/xhr/XMLHttpRequestMainThread.cpp
dom/xhr/XMLHttpRequestMainThread.h
dom/xhr/tests/test_xhr_progressevents.html
testing/web-platform/meta/MANIFEST.json
testing/web-platform/meta/XMLHttpRequest/abort-after-send.htm.ini
testing/web-platform/meta/XMLHttpRequest/abort-during-upload.htm.ini
testing/web-platform/meta/XMLHttpRequest/abort-event-order.htm.ini
testing/web-platform/meta/XMLHttpRequest/event-progress.htm.ini
testing/web-platform/meta/XMLHttpRequest/response-data-progress.htm.ini
testing/web-platform/meta/XMLHttpRequest/send-network-error-async-events.sub.htm.ini
testing/web-platform/meta/XMLHttpRequest/send-timeout-events.htm.ini
testing/web-platform/tests/XMLHttpRequest/abort-during-done.htm
testing/web-platform/tests/XMLHttpRequest/abort-during-upload.htm
testing/web-platform/tests/XMLHttpRequest/abort-event-order.htm
testing/web-platform/tests/XMLHttpRequest/event-error-order.sub.html
testing/web-platform/tests/XMLHttpRequest/event-error.html
testing/web-platform/tests/XMLHttpRequest/event-error.sub.html
testing/web-platform/tests/XMLHttpRequest/event-progress.htm
testing/web-platform/tests/XMLHttpRequest/event-timeout-order.htm
testing/web-platform/tests/XMLHttpRequest/resources/trickle.py
testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-event-order.js
testing/web-platform/tests/XMLHttpRequest/response-data-progress.htm
testing/web-platform/tests/XMLHttpRequest/security-consideration.sub.html
testing/web-platform/tests/XMLHttpRequest/send-no-response-event-order.htm
testing/web-platform/tests/XMLHttpRequest/send-sync-response-event-order.htm
--- a/dom/base/test/fileutils.js
+++ b/dom/base/test/fileutils.js
@@ -95,17 +95,17 @@ function getXHRLoadHandler(expectedResul
     is(event.target.status, 200,
        "[XHR] no error in test " + testName);
     // Do not use |is(convertXHRBinary(event.target.responseText), expectedResult, "...");| that may output raw binary data.
     var convertedData = convertXHRBinary(event.target.responseText);
     is(convertedData.length, expectedResult.length,
        "[XHR] Length of result in test " + testName);
     ok(convertedData == expectedResult,
        "[XHR] Content of result in test " + testName);
-    is(event.lengthComputable, event.total != 0,
+    is(event.lengthComputable, true,
        "[XHR] lengthComputable in test " + testName);
     is(event.loaded, expectedLength,
        "[XHR] Loaded length in test " + testName);
     is(event.total, expectedLength,
        "[XHR] Total length in test " + testName);
 
     testHasRun();
   }
--- a/dom/base/test/test_bug435425.html
+++ b/dom/base/test/test_bug435425.html
@@ -19,60 +19,39 @@ https://bugzilla.mozilla.org/show_bug.cg
 
 /** Test for Bug 435425 **/
 
 var xhr = null;
 var upload = null;
 var currentEvents = null;
 var expectedResponseText = null;
 var uploadTotal = 0;
-var currentProgress = -1;
 
 function logEvent(evt) {
   var i = 0;
   while ((currentEvents.length != i) &&
          currentEvents[i].optional &&
          ((currentEvents[i].type != evt.type) ||
           !(evt.target instanceof currentEvents[i].target))) {
     ++i;
   }
-
   if (evt.target instanceof XMLHttpRequestUpload) {
     if (evt.type == "loadstart") {
       uploadTotal = evt.total
     } else {
       if (evt.type == "progress") {
-        is(evt.lengthComputable, evt.total != 0, "event(" + evt.type +  ").lengthComputable should be " + (evt.total != 0 ? true : false) + ".");
+        ok(evt.lengthComputable, "event(" + evt.type +  ").lengthComputable should be true.");
       }
-      if (evt.total != uploadTotal && evt.total != 0) {
-        ok(false, "event(" + evt.type +  ").total should not change during upload except to become 0 on error/abort/timeout.");
-      }
+      is(evt.total, uploadTotal, "event(" + evt.type +  ").total should not change during upload.");
     }
   }
   ok(i != currentEvents.length, "Extra or wrong event?");
   is(evt.type, currentEvents[i].type, "Wrong event!")
   ok(evt.target instanceof currentEvents[i].target,
      "Wrong event target [" + evt.target + "," + evt.type + "]!");
-
-  // There can be any number of repeated progress events, so special-case this.
-  if (evt.type == "progress") {
-    // Progress events can repeat, but their "loaded" value must increase.
-    if (currentProgress >= 0) {
-      ok(currentProgress < evt.loaded, "Progress should increase, got " +
-                                       evt.loaded + " after " + currentProgress);
-      currentProgress = evt.loaded;
-      return; // stay at the currentEvent, since we got progress instead of it.
-    }
-    // Starting a new progress event group.
-    currentProgress = evt.loaded;
-  } else {
-    // Reset the progress indicator on any other event type.
-    currentProgress = -1;
-  }
-
   // If we handled non-optional event, remove all optional events before the 
   // handled event and then the non-optional event from the list.
   if (!currentEvents[i].optional) {
     for (;i != -1; --i) {
       currentEvents.shift();
     }
   }
 }
@@ -100,17 +79,16 @@ function openXHR(xhr, method, url, privi
     xhr.open(method, url);
 }
 
 function start(obj) {
   xhr = new XMLHttpRequest();
   upload = xhr.upload;
   currentEvents = obj.expectedEvents;
   expectedResponseText = obj.withUpload;
-  currentProgress = -1;
   xhr.onload =
     function(evt) {
       if (expectedResponseText) {
         is(evt.target.responseText, expectedResponseText, "Wrong responseText");
       }
       logEvent(evt);
     }
   xhr.onerror =
@@ -206,210 +184,202 @@ for (var largeLength = 0; largeLength < 
 
 const XHR = XMLHttpRequest;
 const UPLOAD = XMLHttpRequestUpload;
 
 var tests = 
   [
     { method: "GET", withUpload: none, testAbort: false, testRedirectError: false, testNetworkError: false,
       expectedEvents: [{target: XHR, type: "loadstart", optional: false},
-                       {target: XHR, type: "progress", optional: false},
+                       {target: XHR, type: "progress", optional: true},
                        {target: XHR, type: "load", optional: false},
                        {target: XHR, type: "loadend", optional: false}]},
     { method: "GET", withUpload: none, testAbort: true, testRedirectError: false, testNetworkError: false,
       expectedEvents: [{target: XHR, type: "loadstart", optional: false},
-                       {target: XHR, type: "progress", optional: false},
                        {target: XHR, type: "abort", optional: false},
                        {target: XHR, type: "loadend", optional: false}]},
     { method: "GET", withUpload: none, testAbort: false, testRedirectError: true, testNetworkError: false,
       expectedEvents: [{target: XHR, type: "loadstart", optional: false},
                        {target: XHR, type: "error", optional: false},
                        {target: XHR, type: "loadend", optional: false}]},
     { method: "GET", withUpload: none, testAbort: false, testRedirectError: false, testNetworkError: true,
       expectedEvents: [{target: XHR, type: "loadstart", optional: false},
                        {target: XHR, type: "error", optional: false},
                        {target: XHR, type: "loadend", optional: false}]},
 
     { method: "GET", withUpload: small, testAbort: false, testRedirectError: false, testNetworkError: false,
       expectedEvents: [{target: XHR, type: "loadstart", optional: false},
-                       {target: XHR, type: "progress", optional: false},
+                       {target: XHR, type: "progress", optional: true},
                        {target: XHR, type: "load", optional: false},
                        {target: XHR, type: "loadend", optional: false}]},
     { method: "GET", withUpload: small, testAbort: true, testRedirectError: false, testNetworkError: false,
       expectedEvents: [{target: XHR, type: "loadstart", optional: false},
-                       {target: XHR, type: "progress", optional: false},
                        {target: XHR, type: "abort", optional: false},
                        {target: XHR, type: "loadend", optional: false}]},
     { method: "GET", withUpload: small, testAbort: false, testRedirectError: true, testNetworkError: false,
       expectedEvents: [{target: XHR, type: "loadstart", optional: false},
                        {target: XHR, type: "error", optional: false},
                        {target: XHR, type: "loadend", optional: false}]},
     { method: "GET", withUpload: small, testAbort: false, testRedirectError: false, testNetworkError: true,
       expectedEvents: [{target: XHR, type: "loadstart", optional: false},
                        {target: XHR, type: "error", optional: false},
                        {target: XHR, type: "loadend", optional: false}]},
 
     { method: "GET", withUpload: mid, testAbort: false, testRedirectError: false, testNetworkError: false,
       expectedEvents: [{target: XHR, type: "loadstart", optional: false},
-                       {target: XHR, type: "progress", optional: false},
+                       {target: XHR, type: "progress", optional: true},
                        {target: XHR, type: "load", optional: false},
                        {target: XHR, type: "loadend", optional: false}]},
     { method: "GET", withUpload: mid, testAbort: true, testRedirectError: false, testNetworkError: false,
       expectedEvents: [{target: XHR, type: "loadstart", optional: false},
-                       {target: XHR, type: "progress", optional: false},
                        {target: XHR, type: "abort", optional: false},
                        {target: XHR, type: "loadend", optional: false}]},
     { method: "GET", withUpload: mid, testAbort: false, testRedirectError: true, testNetworkError: false,
       expectedEvents: [{target: XHR, type: "loadstart", optional: false},
                        {target: XHR, type: "error", optional: false},
                        {target: XHR, type: "loadend", optional: false}]},
     { method: "GET", withUpload: mid, testAbort: false, testRedirectError: false, testNetworkError: true,
       expectedEvents: [{target: XHR, type: "loadstart", optional: false},
                        {target: XHR, type: "error", optional: false},
                        {target: XHR, type: "loadend", optional: false}]},
 
     { method: "GET", withUpload: large, testAbort: false, testRedirectError: false, testNetworkError: false,
       expectedEvents: [{target: XHR, type: "loadstart", optional: false},
-                       {target: XHR, type: "progress", optional: false},
+                       {target: XHR, type: "progress", optional: true},
                        {target: XHR, type: "load", optional: false},
                        {target: XHR, type: "loadend", optional: false}]},
     { method: "GET", withUpload: large, testAbort: true, testRedirectError: false, testNetworkError: false,
       expectedEvents: [{target: XHR, type: "loadstart", optional: false},
-                       {target: XHR, type: "progress", optional: false},
                        {target: XHR, type: "abort", optional: false},
                        {target: XHR, type: "loadend", optional: false}]},
     { method: "GET", withUpload: large, testAbort: false, testRedirectError: true, testNetworkError: false,
       expectedEvents: [{target: XHR, type: "loadstart", optional: false},
                        {target: XHR, type: "error", optional: false},
                        {target: XHR, type: "loadend", optional: false}]},
     { method: "GET", withUpload: large, testAbort: false, testRedirectError: false, testNetworkError: true,
       expectedEvents: [{target: XHR, type: "loadstart", optional: false},
                        {target: XHR, type: "error", optional: false},
                        {target: XHR, type: "loadend", optional: false}]},
 
     { method: "POST", withUpload: none, testAbort: false, testRedirectError: false, testNetworkError: false,
       expectedEvents: [{target: XHR, type: "loadstart", optional: false},
-                       {target: XHR, type: "progress", optional: false},
+                       {target: XHR, type: "progress", optional: true},
                        {target: XHR, type: "load", optional: false},
                        {target: XHR, type: "loadend", optional: false}]},
     { method: "POST", withUpload: none, testAbort: true, testRedirectError: false, testNetworkError: false,
       expectedEvents: [{target: XHR, type: "loadstart", optional: false},
-                       {target: XHR, type: "progress", optional: false},
                        {target: XHR, type: "abort", optional: false},
                        {target: XHR, type: "loadend", optional: false}]},
     { method: "POST", withUpload: none, testAbort: false, testRedirectError: true, testNetworkError: false,
       expectedEvents: [{target: XHR, type: "loadstart", optional: false},
                        {target: XHR, type: "error", optional: false},
                        {target: XHR, type: "loadend", optional: false}]},
     { method: "POST", withUpload: none, testAbort: false, testRedirectError: false, testNetworkError: true,
       expectedEvents: [{target: XHR, type: "loadstart", optional: false},
                        {target: XHR, type: "error", optional: false},
                        {target: XHR, type: "loadend", optional: false}]},
 
     { method: "POST", withUpload: small, testAbort: false, testRedirectError: false, testNetworkError: false,
       expectedEvents: [{target: XHR, type: "loadstart", optional: false},
                        {target: UPLOAD, type: "loadstart", optional: false},
-                       {target: UPLOAD, type: "progress", optional: false},
+                       {target: UPLOAD, type: "progress", optional: true},
                        {target: UPLOAD, type: "load", optional: false},
                        {target: UPLOAD, type: "loadend", optional: false},
-                       {target: XHR, type: "progress", optional: false},
+                       {target: XHR, type: "progress", optional: true},
                        {target: XHR, type: "load", optional: false},
                        {target: XHR, type: "loadend", optional: false}]},
     { method: "POST", withUpload: small, testAbort: true, testRedirectError: false, testNetworkError: false,
       expectedEvents: [{target: XHR, type: "loadstart", optional: false},
                        {target: UPLOAD, type: "loadstart", optional: false},
-                       {target: UPLOAD, type: "progress", optional: false},
+                       {target: XHR, type: "abort", optional: false},
+                       {target: XHR, type: "loadend", optional: false},
                        {target: UPLOAD, type: "abort", optional: false},
-                       {target: UPLOAD, type: "loadend", optional: false},
-                       {target: XHR, type: "progress", optional: false},
-                       {target: XHR, type: "abort", optional: false},
-                       {target: XHR, type: "loadend", optional: false}]},
+                       {target: UPLOAD, type: "loadend", optional: false}]},
     { method: "POST", withUpload: small, testAbort: false, testRedirectError: true, testNetworkError: false,
       expectedEvents: [{target: XHR, type: "loadstart", optional: false},
                        {target: UPLOAD, type: "loadstart", optional: false},
                        {target: UPLOAD, type: "progress", optional: true},
+                       {target: XHR, type: "error", optional: false},
+                       {target: XHR, type: "loadend", optional: false},
                        {target: UPLOAD, type: "error", optional: false},
-                       {target: UPLOAD, type: "loadend", optional: false},
-                       {target: XHR, type: "error", optional: false},
-                       {target: XHR, type: "loadend", optional: false}]},
+                       {target: UPLOAD, type: "loadend", optional: false}]},
     { method: "POST", withUpload: small, testAbort: false, testRedirectError: false, testNetworkError: true,
       expectedEvents: [{target: XHR, type: "loadstart", optional: false},
                        {target: UPLOAD, type: "loadstart", optional: false},
+                       {target: UPLOAD, type: "progress", optional: true},
+                       {target: XHR, type: "error", optional: false},
+                       {target: XHR, type: "loadend", optional: false},
                        {target: UPLOAD, type: "error", optional: false},
-                       {target: UPLOAD, type: "loadend", optional: false},
-                       {target: XHR, type: "error", optional: false},
-                       {target: XHR, type: "loadend", optional: false}]},
+                       {target: UPLOAD, type: "loadend", optional: false}]},
 
     { method: "POST", withUpload: mid, testAbort: false, testRedirectError: false, testNetworkError: false,
       expectedEvents: [{target: XHR, type: "loadstart", optional: false},
                        {target: UPLOAD, type: "loadstart", optional: false},
-                       {target: UPLOAD, type: "progress", optional: false},
+                       {target: UPLOAD, type: "progress", optional: true},
                        {target: UPLOAD, type: "load", optional: false},
                        {target: UPLOAD, type: "loadend", optional: false},
-                       {target: XHR, type: "progress", optional: false},
+                       {target: XHR, type: "progress", optional: true},
                        {target: XHR, type: "load", optional: false},
                        {target: XHR, type: "loadend", optional: false}]},
     { method: "POST", withUpload: mid, testAbort: true, testRedirectError: false, testNetworkError: false,
       expectedEvents: [{target: XHR, type: "loadstart", optional: false},
                        {target: UPLOAD, type: "loadstart", optional: false},
-                       {target: UPLOAD, type: "progress", optional: false},
+                       {target: XHR, type: "abort", optional: false},
+                       {target: XHR, type: "loadend", optional: false},
                        {target: UPLOAD, type: "abort", optional: false},
-                       {target: UPLOAD, type: "loadend", optional: false},
-                       {target: XHR, type: "progress", optional: false},
-                       {target: XHR, type: "abort", optional: false},
-                       {target: XHR, type: "loadend", optional: false}]},
+                       {target: UPLOAD, type: "loadend", optional: false}]},
     { method: "POST", withUpload: mid, testAbort: false, testRedirectError: true, testNetworkError: false,
       expectedEvents: [{target: XHR, type: "loadstart", optional: false},
                        {target: UPLOAD, type: "loadstart", optional: false},
                        {target: UPLOAD, type: "progress", optional: true},
+                       {target: XHR, type: "error", optional: false},
+                       {target: XHR, type: "loadend", optional: false},
                        {target: UPLOAD, type: "error", optional: false},
-                       {target: UPLOAD, type: "loadend", optional: false},
-                       {target: XHR, type: "error", optional: false},
-                       {target: XHR, type: "loadend", optional: false}]},
+                       {target: UPLOAD, type: "loadend", optional: false}]},
     { method: "POST", withUpload: mid, testAbort: false, testRedirectError: false, testNetworkError: true,
       expectedEvents: [{target: XHR, type: "loadstart", optional: false},
                        {target: UPLOAD, type: "loadstart", optional: false},
+                       {target: UPLOAD, type: "progress", optional: true},
+                       {target: XHR, type: "error", optional: false},
+                       {target: XHR, type: "loadend", optional: false},
                        {target: UPLOAD, type: "error", optional: false},
-                       {target: UPLOAD, type: "loadend", optional: false},
-                       {target: XHR, type: "error", optional: false},
-                       {target: XHR, type: "loadend", optional: false}]},
+                       {target: UPLOAD, type: "loadend", optional: false}]},
 
     { method: "POST", withUpload: large, testAbort: false, testRedirectError: false, testNetworkError: false,
       expectedEvents: [{target: XHR, type: "loadstart", optional: false},
                        {target: UPLOAD, type: "loadstart", optional: false},
-                       {target: UPLOAD, type: "progress", optional: false},
+                       {target: UPLOAD, type: "progress", optional: true},
                        {target: UPLOAD, type: "load", optional: false},
                        {target: UPLOAD, type: "loadend", optional: false},
-                       {target: XHR, type: "progress", optional: false},
+                       {target: XHR, type: "progress", optional: true},
                        {target: XHR, type: "load", optional: false},
                        {target: XHR, type: "loadend", optional: false}]},
     { method: "POST", withUpload: large, testAbort: true, testRedirectError: false, testNetworkError: false,
       expectedEvents: [{target: XHR, type: "loadstart", optional: false},
                        {target: UPLOAD, type: "loadstart", optional: false},
-                       {target: UPLOAD, type: "progress", optional: false},
+                       {target: XHR, type: "abort", optional: false},
+                       {target: XHR, type: "loadend", optional: false},
                        {target: UPLOAD, type: "abort", optional: false},
-                       {target: UPLOAD, type: "loadend", optional: false},
-                       {target: XHR, type: "progress", optional: false},
-                       {target: XHR, type: "abort", optional: false},
-                       {target: XHR, type: "loadend", optional: false}]},
+                       {target: UPLOAD, type: "loadend", optional: false}]},
     { method: "POST", withUpload: large, testAbort: false, testRedirectError: true, testNetworkError: false,
       expectedEvents: [{target: XHR, type: "loadstart", optional: false},
                        {target: UPLOAD, type: "loadstart", optional: false},
                        {target: UPLOAD, type: "progress", optional: true},
+                       {target: XHR, type: "error", optional: false},
+                       {target: XHR, type: "loadend", optional: false},
                        {target: UPLOAD, type: "error", optional: false},
-                       {target: UPLOAD, type: "loadend", optional: false},
-                       {target: XHR, type: "error", optional: false},
-                       {target: XHR, type: "loadend", optional: false}]},
+                       {target: UPLOAD, type: "loadend", optional: false}]},
     { method: "POST", withUpload: large, testAbort: false, testRedirectError: false, testNetworkError: true,
       expectedEvents: [{target: XHR, type: "loadstart", optional: false},
                        {target: UPLOAD, type: "loadstart", optional: false},
+                       {target: UPLOAD, type: "progress", optional: true},
+                       {target: XHR, type: "error", optional: false},
+                       {target: XHR, type: "loadend", optional: false},
                        {target: UPLOAD, type: "error", optional: false},
-                       {target: UPLOAD, type: "loadend", optional: false},
-                       {target: XHR, type: "error", optional: false},
-                       {target: XHR, type: "loadend", optional: false}]},
+                       {target: UPLOAD, type: "loadend", optional: false}]},
 ];
 
 function runTest() {
   var test = tests.shift();
   start(test);
 }
 
 function nextTest() {
--- a/dom/workers/test/bug1063538_worker.js
+++ b/dom/workers/test/bug1063538_worker.js
@@ -1,25 +1,18 @@
 /**
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 var gJar = "jar:http://example.org/tests/dom/base/test/file_bug945152.jar!/data_big.txt";
 var xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true});
-var progressFired = false;
-
-xhr.onloadend = function(e) {
-  postMessage({type: 'finish', progressFired: progressFired });
-  self.close();
-};
 
 xhr.onprogress = function(e) {
-  if (e.loaded > 0) {
-    progressFired = true;
-  }
   xhr.abort();
+  postMessage({type: 'finish' });
+  self.close();
 };
 
 onmessage = function(e) {
   xhr.open("GET", gJar, true);
   xhr.send();
 }
--- a/dom/workers/test/test_bug1063538.html
+++ b/dom/workers/test/test_bug1063538.html
@@ -22,17 +22,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 <pre id="test">
 <script type="application/javascript">
 
 function runTest() {
   var worker = new Worker("bug1063538_worker.js");
 
   worker.onmessage = function(e) {
     if (e.data.type == 'finish') {
-      ok(e.data.progressFired, "Progress was fired.");
+      ok(true, "Testing done.\n");
       SimpleTest.finish();
     }
   };
 
   worker.postMessage(true);
 }
 
 SimpleTest.waitForExplicitFinish();
--- a/dom/xhr/XMLHttpRequestMainThread.cpp
+++ b/dom/xhr/XMLHttpRequestMainThread.cpp
@@ -168,17 +168,17 @@ XMLHttpRequestMainThread::XMLHttpRequest
     mFlagTimedOut(false), mFlagDeleted(false), mFlagSend(false),
     mUploadTransferred(0), mUploadTotal(0), mUploadComplete(true),
     mProgressSinceLastProgressEvent(false),
     mRequestSentTime(0), mTimeoutMilliseconds(0),
     mErrorLoad(false), mWaitingForOnStopRequest(false),
     mProgressTimerIsActive(false),
     mIsHtml(false),
     mWarnAboutSyncHtml(false),
-    mLoadTotal(0),
+    mLoadLengthComputable(false), mLoadTotal(0),
     mIsSystem(false),
     mIsAnon(false),
     mFirstStartRequestSeen(false),
     mInLoadProgressEvent(false),
     mResultJSON(JS::UndefinedValue()),
     mResultArrayBuffer(nullptr),
     mIsMappedArrayBuffer(false),
     mXPCOMifier(nullptr)
@@ -1007,37 +1007,38 @@ void
 XMLHttpRequestMainThread::CloseRequestWithError(const ProgressEventType aType)
 {
   if (mChannel) {
     mChannel->Cancel(NS_BINDING_ABORTED);
   }
   if (mTimeoutTimer) {
     mTimeoutTimer->Cancel();
   }
+  uint32_t responseLength = mResponseBody.Length();
   ResetResponse();
 
   // If we're in the destructor, don't risk dispatching an event.
   if (mFlagDeleted) {
     mFlagSyncLooping = false;
     return;
   }
 
   if (mState != State::unsent &&
       !(mState == State::opened && !mFlagSend) &&
       mState != State::done) {
     ChangeState(State::done, true);
 
     if (!mFlagSyncLooping) {
+      DispatchProgressEvent(this, aType, mLoadLengthComputable, responseLength,
+                            mLoadTotal);
       if (mUpload && !mUploadComplete) {
         mUploadComplete = true;
-        DispatchProgressEvent(mUpload, ProgressEventType::progress, 0, 0);
-        DispatchProgressEvent(mUpload, aType, 0, 0);
+        DispatchProgressEvent(mUpload, aType, true, mUploadTransferred,
+                              mUploadTotal);
       }
-      DispatchProgressEvent(this, ProgressEventType::progress, 0, 0);
-      DispatchProgressEvent(this, aType, 0, 0);
     }
   }
 
   // The ChangeState call above calls onreadystatechange handlers which
   // if they load a new url will cause XMLHttpRequestMainThread::Open to clear
   // the abort state bit. If this occurs we're not uninitialized (bug 361773).
   if (mFlagAborted) {
     ChangeState(State::unsent, false);  // IE seems to do it
@@ -1284,44 +1285,34 @@ XMLHttpRequestMainThread::FireReadystate
   event->SetTrusted(true);
   DispatchDOMEvent(nullptr, event, nullptr, nullptr);
   return NS_OK;
 }
 
 void
 XMLHttpRequestMainThread::DispatchProgressEvent(DOMEventTargetHelper* aTarget,
                                                 const ProgressEventType aType,
+                                                bool aLengthComputable,
                                                 int64_t aLoaded, int64_t aTotal)
 {
   NS_ASSERTION(aTarget, "null target");
 
   if (NS_FAILED(CheckInnerWindowCorrectness()) ||
       (!AllowUploadProgress() && aTarget == mUpload)) {
     return;
   }
 
-  // If blocked by CORS, zero-out the stats on progress events
-  // and never fire "progress" or "load" events at all.
-  if (IsDeniedCrossSiteCORSRequest()) {
-    if (aType == ProgressEventType::progress ||
-        aType == ProgressEventType::load) {
-      return;
-    }
-    aLoaded = 0;
-    aTotal = 0;
-  }
-
   if (aType == ProgressEventType::progress) {
     mInLoadProgressEvent = true;
   }
 
   ProgressEventInit init;
   init.mBubbles = false;
   init.mCancelable = false;
-  init.mLengthComputable = aTotal != 0; // XHR spec step 6.1
+  init.mLengthComputable = aLengthComputable;
   init.mLoaded = aLoaded;
   init.mTotal = (aTotal == -1) ? 0 : aTotal;
 
   const nsAString& typeString = ProgressEventTypeStrings[(uint8_t)aType];
   RefPtr<ProgressEvent> event =
     ProgressEvent::Constructor(aTarget, typeString, init);
   event->SetTrusted(true);
 
@@ -1339,17 +1330,18 @@ XMLHttpRequestMainThread::DispatchProgre
       mArrayBufferBuilder.reset();
     }
   }
 
   // If we're sending a load, error, timeout or abort event, then
   // also dispatch the subsequent loadend event.
   if (aType == ProgressEventType::load || aType == ProgressEventType::error ||
       aType == ProgressEventType::timeout || aType == ProgressEventType::abort) {
-    DispatchProgressEvent(aTarget, ProgressEventType::loadend, aLoaded, aTotal);
+    DispatchProgressEvent(aTarget, ProgressEventType::loadend,
+                          aLengthComputable, aLoaded, aTotal);
   }
 }
 
 already_AddRefed<nsIHttpChannel>
 XMLHttpRequestMainThread::GetCurrentHttpChannel()
 {
   nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(mChannel);
   return httpChannel.forget();
@@ -1798,23 +1790,24 @@ XMLHttpRequestMainThread::OnStartRequest
   // stop the timer and fire any final progress events.
   if (mUpload && !mUploadComplete && !mErrorLoad && !mFlagSynchronous) {
     StopProgressEventTimer();
 
     mUploadTransferred = mUploadTotal;
 
     if (mProgressSinceLastProgressEvent) {
       DispatchProgressEvent(mUpload, ProgressEventType::progress,
-                            mUploadTransferred, mUploadTotal);
+                            mUploadLengthComputable, mUploadTransferred,
+                            mUploadTotal);
       mProgressSinceLastProgressEvent = false;
     }
 
     mUploadComplete = true;
     DispatchProgressEvent(mUpload, ProgressEventType::load,
-                          mUploadTotal, mUploadTotal);
+                          true, mUploadTotal, mUploadTotal);
   }
 
   mContext = ctxt;
   mFlagParseBody = true;
   ChangeState(State::headers_received);
 
   ResetResponse();
 
@@ -2032,23 +2025,18 @@ XMLHttpRequestMainThread::OnStopRequest(
   if (mXMLParserStreamListener && mFlagParseBody) {
     mXMLParserStreamListener->OnStopRequest(request, ctxt, status);
   }
 
   mXMLParserStreamListener = nullptr;
   mContext = nullptr;
 
   if (NS_SUCCEEDED(status) &&
-      (mResponseType == XMLHttpRequestResponseType::_empty ||
-       mResponseType == XMLHttpRequestResponseType::Text)) {
-    mLoadTotal = mResponseBody.Length();
-  } else if (NS_SUCCEEDED(status) &&
       (mResponseType == XMLHttpRequestResponseType::Blob ||
        mResponseType == XMLHttpRequestResponseType::Moz_blob)) {
-    ErrorResult rv;
     if (!mDOMBlob) {
       CreateDOMBlob(request);
     }
     if (mDOMBlob) {
       mResponseBlob = mDOMBlob;
       mDOMBlob = nullptr;
     } else {
       // mBlobSet can be null if the channel is non-file non-cacheable
@@ -2056,39 +2044,33 @@ XMLHttpRequestMainThread::OnStopRequest(
       if (!mBlobSet) {
         mBlobSet = new BlobSet();
       }
       // Smaller files may be written in cache map instead of separate files.
       // Also, no-store response cannot be written in persistent cache.
       nsAutoCString contentType;
       mChannel->GetContentType(contentType);
 
+      ErrorResult rv;
       mResponseBlob = mBlobSet->GetBlobInternal(GetOwner(), contentType, rv);
       mBlobSet = nullptr;
 
       if (NS_WARN_IF(rv.Failed())) {
         return rv.StealNSResult();
       }
     }
-
-    mLoadTotal = mResponseBlob->GetSize(rv);
-    if (NS_WARN_IF(rv.Failed())) {
-      status = rv.StealNSResult();
-    }
-
     NS_ASSERTION(mResponseBody.IsEmpty(), "mResponseBody should be empty");
     NS_ASSERTION(mResponseText.IsEmpty(), "mResponseText should be empty");
   } else if (NS_SUCCEEDED(status) &&
              ((mResponseType == XMLHttpRequestResponseType::Arraybuffer &&
                !mIsMappedArrayBuffer) ||
               mResponseType == XMLHttpRequestResponseType::Moz_chunked_arraybuffer)) {
     // set the capacity down to the actual length, to realloc back
     // down to the actual size
-    mLoadTotal = mArrayBufferBuilder.length();
-    if (!mArrayBufferBuilder.setCapacity(mLoadTotal)) {
+    if (!mArrayBufferBuilder.setCapacity(mArrayBufferBuilder.length())) {
       // this should never happen!
       status = NS_ERROR_UNEXPECTED;
     }
   }
 
   nsCOMPtr<nsIChannel> channel(do_QueryInterface(request));
   NS_ENSURE_TRUE(channel, NS_ERROR_UNEXPECTED);
 
@@ -2110,97 +2092,76 @@ XMLHttpRequestMainThread::OnStopRequest(
   // If we're uninitialized at this point, we encountered an error
   // earlier and listeners have already been notified. Also we do
   // not want to do this if we already completed.
   if (mState == State::unsent || mState == State::done) {
     return NS_OK;
   }
 
   if (!mResponseXML) {
-    mFlagParseBody = false;
     ChangeStateToDone();
     return NS_OK;
   }
-
   if (mIsHtml) {
     NS_ASSERTION(!mFlagSyncLooping,
       "We weren't supposed to support HTML parsing with XHR!");
     nsCOMPtr<EventTarget> eventTarget = do_QueryInterface(mResponseXML);
     EventListenerManager* manager =
       eventTarget->GetOrCreateListenerManager();
     manager->AddEventListenerByType(new nsXHRParseEndListener(this),
                                     kLiteralString_DOMContentLoaded,
                                     TrustedEventsAtSystemGroupBubble());
     return NS_OK;
-  } else {
-    mFlagParseBody = false;
   }
-
   // We might have been sent non-XML data. If that was the case,
   // we should null out the document member. The idea in this
   // check here is that if there is no document element it is not
   // an XML document. We might need a fancier check...
   if (!mResponseXML->GetRootElement()) {
     mResponseXML = nullptr;
   }
   ChangeStateToDone();
   return NS_OK;
 }
 
 void
-XMLHttpRequestMainThread::OnBodyParseEnd()
-{
-  mFlagParseBody = false;
-  ChangeStateToDone();
-}
-
-void
 XMLHttpRequestMainThread::ChangeStateToDone()
 {
   StopProgressEventTimer();
 
   MOZ_ASSERT(!mFlagParseBody,
              "ChangeStateToDone() called before async HTML parsing is done.");
 
+  // Fire the final progress event required by spec, if we haven't already.
+  if (mProgressSinceLastProgressEvent && !mErrorLoad && !mFlagSynchronous) {
+    mLoadTotal = mLoadTransferred;
+    DispatchProgressEvent(this, ProgressEventType::progress,
+                          mLoadLengthComputable, mLoadTransferred,
+                          mLoadTotal);
+    mProgressSinceLastProgressEvent = false;
+  }
+
+  ChangeState(State::done, true);
+
   mFlagSend = false;
 
   if (mTimeoutTimer) {
     mTimeoutTimer->Cancel();
   }
 
-  mLoadTotal = mLoadTransferred;
-
-  // Per spec, fire the last download progress event, if any,
-  // before readystatechange=4/done. (Note that 0-sized responses
-  // will have not sent a progress event yet, so one must be sent here).
-  if (!mFlagSynchronous &&
-      (!mLoadTransferred || mProgressSinceLastProgressEvent)) {
-    DispatchProgressEvent(this, ProgressEventType::progress,
-                          mLoadTransferred, mLoadTotal);
-    mProgressSinceLastProgressEvent = false;
+  DispatchProgressEvent(this,
+                        mErrorLoad ? ProgressEventType::error : ProgressEventType::load,
+                        !mErrorLoad,
+                        mLoadTransferred,
+                        mErrorLoad ? 0 : mLoadTransferred);
+  if (mErrorLoad && mUpload && !mUploadComplete) {
+    DispatchProgressEvent(mUpload, ProgressEventType::error, true,
+                          mUploadTransferred, mUploadTotal);
   }
 
-  // Per spec, fire readystatechange=4/done before final error events.
-  ChangeState(State::done, true);
-
-  // Per spec, if we failed in the upload phase, fire a final progress, error,
-  // and loadend event for the upload after readystatechange=4/done.
-  if (!mFlagSynchronous && mUpload && !mUploadComplete) {
-    DispatchProgressEvent(mUpload, ProgressEventType::progress, 0, 0);
-    DispatchProgressEvent(mUpload, ProgressEventType::error, 0, 0);
-  }
-
-  // Per spec, fire download's load/error and loadend events after
-  // readystatechange=4/done (and of course all upload events).
-  DispatchProgressEvent(this,
-                        mErrorLoad ? ProgressEventType::error :
-                                     ProgressEventType::load,
-                        mErrorLoad ? 0 : mLoadTransferred,
-                        mErrorLoad ? 0 : mLoadTotal);
-
   if (mErrorLoad) {
     // By nulling out channel here we make it so that Send() can test
     // for that and throw. Also calling the various status
     // methods/members will not throw.
     // This matches what IE does.
     mChannel = nullptr;
   }
 }
@@ -2573,16 +2534,17 @@ XMLHttpRequestMainThread::Send(nsIVarian
     }
   }
 
   mUploadTransferred = 0;
   mUploadTotal = 0;
   // By default we don't have any upload, so mark upload complete.
   mUploadComplete = true;
   mErrorLoad = false;
+  mLoadLengthComputable = false;
   mLoadTotal = 0;
   if ((aVariant || !aBody.IsNull()) && httpChannel &&
       !method.LowerCaseEqualsLiteral("get") &&
       !method.LowerCaseEqualsLiteral("head")) {
 
     nsAutoCString charset;
     nsAutoCString defaultContentType;
     nsCOMPtr<nsIInputStream> postDataStream;
@@ -2883,21 +2845,20 @@ XMLHttpRequestMainThread::Send(nsIVarian
     // can run script that would try to restart this request, and that could end
     // up doing our AsyncOpen on a null channel if the reentered AsyncOpen fails.
     StopProgressEventTimer();
 
     // Upload phase beginning; start the progress event timer if necessary.
     if (mUpload && mUpload->HasListenersFor(nsGkAtoms::onprogress)) {
       StartProgressEventTimer();
     }
-
-    // Dispatch loadstart events
-    DispatchProgressEvent(this, ProgressEventType::loadstart, 0, 0);
+    DispatchProgressEvent(this, ProgressEventType::loadstart, false,
+                          0, 0);
     if (mUpload && !mUploadComplete) {
-      DispatchProgressEvent(mUpload, ProgressEventType::loadstart,
+      DispatchProgressEvent(mUpload, ProgressEventType::loadstart, true,
                             0, mUploadTotal);
     }
   }
 
   if (!mChannel) {
     return NS_ERROR_FAILURE;
   }
 
@@ -3281,23 +3242,25 @@ XMLHttpRequestMainThread::OnProgress(nsI
   // So, try to remove the headers, if possible.
   bool lengthComputable = (aProgressMax != -1);
   if (InUploadPhase()) {
     int64_t loaded = aProgress;
     if (lengthComputable) {
       int64_t headerSize = aProgressMax - mUploadTotal;
       loaded -= headerSize;
     }
+    mUploadLengthComputable = lengthComputable;
     mUploadTransferred = loaded;
     mProgressSinceLastProgressEvent = true;
 
     if (!mFlagSynchronous && !mProgressTimerIsActive) {
       StartProgressEventTimer();
     }
   } else {
+    mLoadLengthComputable = lengthComputable;
     mLoadTotal = lengthComputable ? aProgressMax : 0;
     mLoadTransferred = aProgress;
     // OnDataAvailable() handles mProgressSinceLastProgressEvent
     // for the download phase.
   }
 
   if (mProgressEventSink) {
     mProgressEventSink->OnProgress(aRequest, aContext, aProgress,
@@ -3493,21 +3456,23 @@ XMLHttpRequestMainThread::HandleProgress
 
   if (!mProgressSinceLastProgressEvent || mErrorLoad) {
     return;
   }
 
   if (InUploadPhase()) {
     if (mUpload && !mUploadComplete) {
       DispatchProgressEvent(mUpload, ProgressEventType::progress,
-                            mUploadTransferred, mUploadTotal);
+                            mUploadLengthComputable, mUploadTransferred,
+                            mUploadTotal);
     }
   } else {
     DispatchProgressEvent(this, ProgressEventType::progress,
-                          mLoadTransferred, mLoadTotal);
+                          mLoadLengthComputable, mLoadTransferred,
+                          mLoadTotal);
   }
 
   mProgressSinceLastProgressEvent = false;
 
   StartProgressEventTimer();
 }
 
 void
--- a/dom/xhr/XMLHttpRequestMainThread.h
+++ b/dom/xhr/XMLHttpRequestMainThread.h
@@ -534,16 +534,17 @@ public:
                JS::MutableHandle<JS::Value> aRetval,
                ErrorResult& aRv) override;
 
   // This fires a trusted readystatechange event, which is not cancelable and
   // doesn't bubble.
   nsresult FireReadystatechangeEvent();
   void DispatchProgressEvent(DOMEventTargetHelper* aTarget,
                              const ProgressEventType aType,
+                             bool aLengthComputable,
                              int64_t aLoaded, int64_t aTotal);
 
   // This is called by the factory constructor.
   nsresult Init();
 
   nsresult init(nsIPrincipal* principal,
                 nsIScriptContext* scriptContext,
                 nsPIDOMWindowInner* globalObject,
@@ -595,17 +596,16 @@ protected:
   nsIURI *GetBaseURI();
 
   already_AddRefed<nsIHttpChannel> GetCurrentHttpChannel();
   already_AddRefed<nsIJARChannel> GetCurrentJARChannel();
 
   bool IsSystemXHR() const;
   bool InUploadPhase() const;
 
-  void OnBodyParseEnd();
   void ChangeStateToDone();
 
   void StartProgressEventTimer();
   void StopProgressEventTimer();
 
   nsresult OnRedirectVerifyCallback(nsresult result);
 
   nsresult Open(const nsACString& method, const nsACString& url, bool async,
@@ -713,32 +713,34 @@ protected:
   // finishes downloading (or an error/abort has occurred during either phase).
   // Used to guard against the user trying to alter headers/etc when it's too
   // late, and ensure the XHR only handles one in-flight request at once.
   bool mFlagSend;
 
   RefPtr<XMLHttpRequestUpload> mUpload;
   int64_t mUploadTransferred;
   int64_t mUploadTotal;
+  bool mUploadLengthComputable;
   bool mUploadComplete;
   bool mProgressSinceLastProgressEvent;
 
   // Timeout support
   PRTime mRequestSentTime;
   uint32_t mTimeoutMilliseconds;
   nsCOMPtr<nsITimer> mTimeoutTimer;
   void StartTimeoutTimer();
   void HandleTimeoutCallback();
 
   bool mErrorLoad;
   bool mWaitingForOnStopRequest;
   bool mProgressTimerIsActive;
   bool mIsHtml;
   bool mWarnAboutMultipartHtml;
   bool mWarnAboutSyncHtml;
+  bool mLoadLengthComputable;
   int64_t mLoadTotal; // 0 if not known.
   // Amount of script-exposed (i.e. after undoing gzip compresion) data
   // received.
   uint64_t mDataAvailable;
   // Number of HTTP message body bytes received so far. This quantity is
   // in the same units as Content-Length and mLoadTotal, and hence counts
   // compressed bytes when the channel has gzip Content-Encoding. If the
   // channel does not have Content-Encoding, this will be the same as
@@ -854,17 +856,17 @@ private:
 class nsXHRParseEndListener : public nsIDOMEventListener
 {
 public:
   NS_DECL_ISUPPORTS
   NS_IMETHOD HandleEvent(nsIDOMEvent *event) override
   {
     nsCOMPtr<nsIXMLHttpRequest> xhr = do_QueryReferent(mXHR);
     if (xhr) {
-      static_cast<XMLHttpRequestMainThread*>(xhr.get())->OnBodyParseEnd();
+      static_cast<XMLHttpRequestMainThread*>(xhr.get())->ChangeStateToDone();
     }
     mXHR = nullptr;
     return NS_OK;
   }
   explicit nsXHRParseEndListener(nsIXMLHttpRequest* aXHR)
     : mXHR(do_GetWeakReference(aXHR)) {}
 private:
   virtual ~nsXHRParseEndListener() {}
--- a/dom/xhr/tests/test_xhr_progressevents.html
+++ b/dom/xhr/tests/test_xhr_progressevents.html
@@ -1,14 +1,14 @@
 <!DOCTYPE HTML>
 <html>
 <head>
   <title>Test for XMLHttpRequest Progress Events</title>
   <script type="text/javascript" src="/MochiKit/packed.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>        
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body onload="gen.next();">
 <pre id=l></pre>
 <script type="application/javascript;version=1.7">
 SimpleTest.waitForExplicitFinish();
 
 var gen = runTests();
@@ -28,17 +28,17 @@ function getEvent(e) {
 
 function startsWith(a, b) {
   return a.substr(0, b.length) === b;
 }
 
 function updateProgress(e, data, testName) {
   var test = " while running " + testName;
   is(e.type, "progress", "event type" + test);
-
+  
   let response;
   if (data.nodata) {
     is(e.target.response, null, "response should be null" + test);
     response = null;
   }
   else if (data.text) {
     is(typeof e.target.response, "string", "response should be a string" + test);
     response = e.target.response;
@@ -69,17 +69,17 @@ function updateProgress(e, data, testNam
   ok(e.loaded - data.receivedBytes <= data.pendingBytes,
      "event.loaded didn't increase too much" + test);
 
   if (!data.nodata && !data.blob) {
     var newData;
     ok(startsWith(response, data.receivedResult),
        "response strictly grew" + test);
     newData = response.substr(data.receivedResult.length);
-
+  
     if (!data.encoded) {
       ok(newData.length > 0, "sanity check for progress" + test);
     }
     ok(startsWith(data.pendingResult, newData), "new data matches expected" + test);
   }
 
   is(e.lengthComputable, "total" in data, "lengthComputable" + test);
   if ("total" in data) {
@@ -194,30 +194,30 @@ function runTests() {
                       receivedBytes: 0,
                       total: test.total,
                       encoded: test.encoded,
                       nodata: responseType.nodata,
                       chunked: responseType.chunked,
                       text: responseType.text,
                       blob: responseType.blob,
                       file: test.file };
-
+  
         xhr.onreadystatechange = null;
         if (testState.file)
           xhr.open("GET", test.file);
         else
           xhr.open("POST", "progressserver.sjs?open&" + test.open);
         xhr.responseType = responseType.type;
         xhr.send("ready");
         xhr.onreadystatechange = getEvent;
 
         let e = yield undefined;
         is(e.type, "readystatechange", "should readystate to headers-received starting " + testState.name);
         is(xhr.readyState, xhr.HEADERS_RECEIVED, "should be in state HEADERS_RECEIVED starting " + testState.name);
-
+  
         e = yield undefined;
         is(e.type, "readystatechange", "should readystate to loading starting " + testState.name);
         is(xhr.readyState, xhr.LOADING, "should be in state LOADING starting " + testState.name);
         if (typeof testState.total == "undefined")
           delete testState.total;
       }
       if ("file" in test) {
         testState.pendingBytes = testState.total;
@@ -233,29 +233,29 @@ function runTests() {
         is(e.type, "readystatechange", "should readystate to done closing " + testState.name);
         is(xhr.readyState, xhr.DONE, "should be in state DONE closing " + testState.name);
         log("readystate to 4");
 
         if (responseType.chunked) {
           xhr.responseType;
           is(xhr.response, null, "chunked data has null response for " + testState.name);
         }
-
+      
         e = yield undefined;
         is(e.type, "load", "should fire load closing " + testState.name);
-        is(e.lengthComputable, e.total != 0, "length should " + (e.total == 0 ? "not " : "") + "be computable during load closing " + testState.name);
+        is(e.lengthComputable, true, "length should be computable during load closing " + testState.name);
         log("got load");
 
         if (responseType.chunked) {
           is(xhr.response, null, "chunked data has null response for " + testState.name);
         }
-
+      
         e = yield undefined;
         is(e.type, "loadend", "should fire loadend closing " + testState.name);
-        is(e.lengthComputable, e.total != 0, "length should " + (e.total == 0 ? "not " : "") + "be computable during loadend closing " + testState.name);
+        is(e.lengthComputable, true, "length should be computable during loadend closing " + testState.name);
         log("got loadend");
 
         // if we closed the connection using an explicit request, make sure that goes through before
         // running the next test in order to avoid reordered requests from closing the wrong
         // connection.
         if (xhrClose && xhrClose.readyState != xhrClose.DONE) {
           log("wait for closeConn to finish");
           xhrClose.onloadend = getEvent;
@@ -293,38 +293,38 @@ function runTests() {
           testState.pendingResult += "utf16" in test ? test.utf16 : test.data;
         }
         else {
           testState.pendingResult += test.data;
         }
         testState.pendingBytes = test.data.length;
         sendData(test.data);
       }
-
+  
       while(testState.pendingBytes) {
         log("waiting for more bytes: " + testState.pendingBytes);
         e = yield undefined;
         // Readystate can fire several times between each progress event.
         if (e.type === "readystatechange")
           continue;
-
+  
         updateProgress(e, testState, "data for " + testState.name + "[" + testState.index + "]");
         if (responseType.chunked) {
           testState.receivedResult = "";
         }
       }
 
       if (!testState.nodata && !testState.blob) {
         is(testState.pendingResult, "",
            "should have consumed the expected result");
       }
 
       log("done with this test");
     }
-
+  
     is(testState.name, "", "forgot to close last test");
   }
 
   SimpleTest.finish();
   yield undefined;
 }
 
 </script>
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -12427,22 +12427,18 @@
         "path": "XMLHttpRequest/data-uri.htm",
         "url": "/XMLHttpRequest/data-uri.htm"
       },
       {
         "path": "XMLHttpRequest/event-abort.htm",
         "url": "/XMLHttpRequest/event-abort.htm"
       },
       {
-        "path": "XMLHttpRequest/event-error.sub.html",
-        "url": "/XMLHttpRequest/event-error.sub.html"
-      },
-      {
-        "path": "XMLHttpRequest/event-error-order.sub.html",
-        "url": "/XMLHttpRequest/event-error-order.sub.html"
+        "path": "XMLHttpRequest/event-error.html",
+        "url": "/XMLHttpRequest/event-error.html"
       },
       {
         "path": "XMLHttpRequest/event-load.htm",
         "url": "/XMLHttpRequest/event-load.htm"
       },
       {
         "path": "XMLHttpRequest/event-loadend.htm",
         "url": "/XMLHttpRequest/event-loadend.htm"
@@ -12463,20 +12459,16 @@
         "path": "XMLHttpRequest/event-readystatechange-loaded.htm",
         "url": "/XMLHttpRequest/event-readystatechange-loaded.htm"
       },
       {
         "path": "XMLHttpRequest/event-timeout.htm",
         "url": "/XMLHttpRequest/event-timeout.htm"
       },
       {
-        "path": "XMLHttpRequest/event-timeout-order.htm",
-        "url": "/XMLHttpRequest/event-timeout-order.htm"
-      },
-      {
         "path": "XMLHttpRequest/event-upload-progress-crossorigin.sub.htm",
         "url": "/XMLHttpRequest/event-upload-progress-crossorigin.sub.htm"
       },
       {
         "path": "XMLHttpRequest/event-upload-progress.htm",
         "url": "/XMLHttpRequest/event-upload-progress.htm"
       },
       {
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/XMLHttpRequest/abort-after-send.htm.ini
@@ -0,0 +1,5 @@
+[abort-after-send.htm]
+  type: testharness
+  [XMLHttpRequest: abort() after send()]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/XMLHttpRequest/abort-during-upload.htm.ini
@@ -0,0 +1,5 @@
+[abort-during-upload.htm]
+  type: testharness
+  [XMLHttpRequest: abort() while sending data]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/XMLHttpRequest/abort-event-order.htm.ini
@@ -0,0 +1,5 @@
+[abort-event-order.htm]
+  type: testharness
+  [XMLHttpRequest: The abort() method: abort and loadend events]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/XMLHttpRequest/event-progress.htm.ini
@@ -0,0 +1,7 @@
+[event-progress.htm]
+  type: testharness
+  expected:
+    if asan or (debug and (os == "linux")): OK
+    if debug and (os == "mac"): OK
+    if debug and (os == "win"): OK
+    TIMEOUT
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/XMLHttpRequest/response-data-progress.htm.ini
@@ -0,0 +1,3 @@
+[response-data-progress.htm]
+  type: testharness
+  expected: TIMEOUT
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/XMLHttpRequest/send-network-error-async-events.sub.htm.ini
@@ -0,0 +1,5 @@
+[send-network-error-async-events.sub.htm]
+  type: testharness
+  [XmlHttpRequest: The send() method: Fire a progress event named error when Network error happens (synchronous flag is unset)]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/XMLHttpRequest/send-timeout-events.htm.ini
@@ -0,0 +1,5 @@
+[send-timeout-events.htm]
+  type: testharness
+  [XMLHttpRequest: The send() method: timeout is not 0 ]
+    expected: FAIL
+
--- a/testing/web-platform/tests/XMLHttpRequest/abort-during-done.htm
+++ b/testing/web-platform/tests/XMLHttpRequest/abort-during-done.htm
@@ -19,16 +19,14 @@
             result.push(client.readyState)
           })
         }
         client.open("GET", "resources/well-formed.xml", false)
         client.send(null)
         assert_equals(client.readyState, 4)
         client.abort()
         assert_equals(client.readyState, 0)
-console.log(result)
-console.log(expected)
         assert_array_equals(result, expected)
         test.done()
       })
     </script>
   </body>
 </html>
--- a/testing/web-platform/tests/XMLHttpRequest/abort-during-upload.htm
+++ b/testing/web-platform/tests/XMLHttpRequest/abort-during-upload.htm
@@ -1,30 +1,42 @@
 <!doctype html>
 <html>
   <head>
     <title>XMLHttpRequest: abort() while sending data</title>
     <script src="/resources/testharness.js"></script>
     <script src="/resources/testharnessreport.js"></script>
-    <script src="resources/xmlhttprequest-event-order.js"></script>
     <link rel="help" href="https://xhr.spec.whatwg.org/#the-abort()-method" data-tested-assertations="following-sibling::ol/li[4]/ol/li[7] following-sibling::ol/li[4]/ol/li[7]/ol/li[2] following-sibling::ol/li[4]/ol/li[7]/ol/li[3] following-sibling::ol/li[4]/ol/li[7]/ol/li[4]" />
     <link rel="help" href="https://xhr.spec.whatwg.org/#make-upload-progress-notifications" data-tested-assertations="following::ul[1]/li[1] following::ul[1]/li[2]/ol[1]/li[2] following::ul[1]/li[2]/ol[1]/li[3] following::ul[1]/li[2]/ol[1]/li[4]" />
   </head>
   <body>
     <div id="log"></div>
     <script>
       var test = async_test(document.title, {timeout:1100})
+      var result = []
+      var expected = ['progress on XHR Upload', 'abort on XHR Upload', 'loadend on XHR Upload', 'progress on XHR', 'abort on XHR', 'loadend on XHR']
+      function logEvt (e) {
+        var str = e.type+' on '
+        str += e.target instanceof XMLHttpRequest ? 'XHR' : 'XHR Upload'
+        result.push(str)
+      }
       test.step(function() {
         var client = new XMLHttpRequest()
-        prepare_xhr_for_event_order_test(client);
         client.open("POST", "resources/delay.py?ms=1000")
-        client.addEventListener("loadend", function(e) {
+        client.addEventListener('progress', logEvt)
+        client.addEventListener('abort', logEvt)
+        client.addEventListener('loadend', function (e) {
+          logEvt(e)
           test.step(function() {
-            assert_xhr_event_order_matches([1, "loadstart(0,0,false)", "upload.loadstart(0,9999,true)", 4, "upload.progress(0,0,false)", "upload.abort(0,0,false)", "upload.loadend(0,0,false)", "progress(0,0,false)", "abort(0,0,false)", "loadend(0,0,false)"]);
+            assert_equals(client.readyState, 4)
+            assert_array_equals(result, expected)
             test.done()
           })
-        });
+        })
+        client.upload.addEventListener('loadend', logEvt)
+        client.upload.addEventListener('progress', logEvt)
+        client.upload.addEventListener('abort', logEvt)
         client.send((new Array(10000)).join('a'))
         client.abort()
       })
     </script>
   </body>
 </html>
--- a/testing/web-platform/tests/XMLHttpRequest/abort-event-order.htm
+++ b/testing/web-platform/tests/XMLHttpRequest/abort-event-order.htm
@@ -1,49 +1,62 @@
 <!DOCTYPE html>
 <html>
 <head>
     <link rel="help" href="https://xhr.spec.whatwg.org/#the-abort()-method" data-tested-assertations="following-sibling::ol/li[4]/ol/li[3] following-sibling::ol/li[4]/ol/li[5] following-sibling::ol/li[4]/ol/li[6] following-sibling::ol/li[4]/ol/li[7]/ol/li[3] following-sibling::ol/li[4]/ol/li[7]/ol/li[4] following-sibling::ol/li[5]" />
     <script src="/resources/testharness.js"></script>
     <script src="/resources/testharnessreport.js"></script>
-    <script src="resources/xmlhttprequest-event-order.js"></script>
     <title>XMLHttpRequest: The abort() method: abort and loadend events</title>
 </head>
 
 <body>
     <div id="log"></div>
 
     <script type="text/javascript">
         var test = async_test();
 
         test.step(function()
         {
             var xhr = new XMLHttpRequest();
-            prepare_xhr_for_event_order_test(xhr);
+            var expect = [1, 4, "upload.abort", "upload.loadend", "abort", "loadend"];
+            var actual = [];
 
-            xhr.addEventListener("loadstart", function() {
+            xhr.onreadystatechange = function()
+            {
+                test.step(function()
+                {
+                     actual.push(xhr.readyState);
+                });
+            };
+            xhr.onloadstart = function()
+            {
                 test.step(function()
                 {
                     var readyState = xhr.readyState;
                     if (readyState == 1)
                     {
                         xhr.abort();
                         VerifyResult();
-                    } else {
+                    }else{
                         assert_unreached('Loadstart event should not fire in readyState '+readyState);
                     }
                 });
-            });
+            };
+
+            xhr.onloadend          = function(e){ actual.push(e.type); };
+            xhr.onabort            = function(e){ actual.push(e.type); };
+
+            xhr.upload.onloadend   = function(e){ actual.push("upload." + e.type); };
+            xhr.upload.onabort     = function(e){ actual.push("upload." + e.type); };
 
             function VerifyResult()
             {
                 test.step(function()
                 {
-                    assert_xhr_event_order_matches([1, "loadstart(0,0,false)", 4, "upload.progress(0,0,false)", "upload.abort(0,0,false)", "upload.loadend(0,0,false)", "progress(0,0,false)", "abort(0,0,false)", "loadend(0,0,false)"]);
-
+                    assert_array_equals(actual, expect);
                     assert_equals(xhr.readyState, 0, 'state should be UNSENT');
                     test.done();
                 });
             };
 
             xhr.open("POST", "./resources/content.py", true);
             xhr.send("Test Message");
         });
deleted file mode 100644
--- a/testing/web-platform/tests/XMLHttpRequest/event-error-order.sub.html
+++ /dev/null
@@ -1,35 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-    <meta name="assert" content="Check the order of events fired when the request has failed.">
-    <script src="/resources/testharness.js"></script>
-    <script src="/resources/testharnessreport.js"></script>
-    <script src="resources/xmlhttprequest-event-order.js"></script>
-    <title>XMLHttpRequest: event - error (order of events)</title>
-</head>
-
-<body>
-    <div id="log"></div>
-
-    <script type="text/javascript">
-        var test = async_test();
-
-        test.step(function()
-        {
-            var xhr = new XMLHttpRequest();
-            prepare_xhr_for_event_order_test(xhr);
-
-            xhr.addEventListener("loadend", function() {
-                test.step(function() {
-                    // no progress events due to CORS failure
-                    assert_xhr_event_order_matches([1, "loadstart(0,0,false)", "upload.loadstart(0,12,true)", 2, 4, "upload.error(0,0,false)", "upload.loadend(0,0,false)", "error(0,0,false)", "loadend(0,0,false)"]);
-                    test.done();
-                });
-            });
-
-            xhr.open("POST", "http://nonexistent-origin.{{host}}:{{ports[http][0]}}", true);
-            xhr.send("Test Message");
-        });
-    </script>
-</body>
-</html>
--- a/testing/web-platform/tests/XMLHttpRequest/event-error.html
+++ b/testing/web-platform/tests/XMLHttpRequest/event-error.html
@@ -13,13 +13,13 @@
 async_test(function (t) {
   var client = new XMLHttpRequest();
   client.onerror = t.step_func(function(e) {
     assert_true(e instanceof ProgressEvent);
     assert_equals(e.type, "error");
     t.done();
   });
 
-  client.open("GET", "http://nonexistent-origin.{{host}}:{{ports[http][0]}}");
+  client.open("GET", "http://example.nonexist");
   client.send("null");
 }, document.title);
 
 </script>
deleted file mode 100644
--- a/testing/web-platform/tests/XMLHttpRequest/event-error.sub.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<!DOCTYPE html>
-<meta charset="utf-8">
-<title>XMLHttpRequest Test: event - error</title>
-<link rel="author" title="Intel" href="http://www.intel.com">
-<meta name="assert" content="Check if event onerror is fired When the request has failed.">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-
-<div id="log"></div>
-
-<script>
-
-async_test(function (t) {
-  var client = new XMLHttpRequest();
-  client.onerror = t.step_func(function(e) {
-    assert_true(e instanceof ProgressEvent);
-    assert_equals(e.type, "error");
-    t.done();
-  });
-
-  client.open("GET", "http://nonexistent-origin.{{host}}:{{ports[http][0]}}");
-  client.send("null");
-}, document.title);
-
-</script>
--- a/testing/web-platform/tests/XMLHttpRequest/event-progress.htm
+++ b/testing/web-platform/tests/XMLHttpRequest/event-progress.htm
@@ -18,12 +18,12 @@
       assert_true(e instanceof ProgressEvent);
       assert_equals(e.type, "progress");
       test.done();
     });
     client.onreadystatechange = test.step_func(function() {
       if (client.readyState === 4)
         assert_unreached("onprogress not called.");
     });
-    client.open("GET", "resources/trickle.py?count=4&delay=150");
+    client.open("GET", "resources/trickle.py");
     client.send(null);
   });
 </script>
deleted file mode 100644
--- a/testing/web-platform/tests/XMLHttpRequest/event-timeout-order.htm
+++ /dev/null
@@ -1,37 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-    <meta name="assert" content="Check the order of events fired when the request has failed.">
-    <script src="/resources/testharness.js"></script>
-    <script src="/resources/testharnessreport.js"></script>
-    <script src="resources/xmlhttprequest-event-order.js"></script>
-    <title>XMLHttpRequest: event - timeout (order of events)</title>
-</head>
-
-<body>
-    <div id="log"></div>
-
-    <script type="text/javascript">
-        var test = async_test();
-
-        test.step(function()
-        {
-            var xhr = new XMLHttpRequest();
-            prepare_xhr_for_event_order_test(xhr);
-            xhr.addEventListener("loadend", function() {
-                test.step(function() {
-                    assert_xhr_event_order_matches([1, "loadstart(0,0,false)", "upload.loadstart(0,12,true)", 4, "upload.progress(0,0,false)", "upload.timeout(0,0,false)", "upload.loadend(0,0,false)", "progress(0,0,false)", "timeout(0,0,false)", "loadend(0,0,false)"]);
-                    test.done();
-                });
-            });
-
-            xhr.timeout = 5;
-            xhr.open("POST", "resources/delay.py?ms=20000");
-            xhr.send("Test Message");
-            setTimeout(test.step_func(function () {
-              assert_unreached("ontimeout not called.");
-            }), 10);
-        });
-    </script>
-</body>
-</html>
--- a/testing/web-platform/tests/XMLHttpRequest/resources/trickle.py
+++ b/testing/web-platform/tests/XMLHttpRequest/resources/trickle.py
@@ -1,15 +1,12 @@
 import time
 
 def main(request, response):
-    chunk = "TEST_TRICKLE\n"
     delay = float(request.GET.first("ms", 500)) / 1E3
     count = int(request.GET.first("count", 50))
-    if "specifylength" in request.GET:
-        response.headers.set("Content-Length", count * len(chunk))
     time.sleep(delay)
     response.headers.set("Content-type", "text/plain")
     response.write_status_headers()
     time.sleep(delay);
     for i in xrange(count):
-        response.writer.write_content(chunk)
+        response.writer.write_content("TEST_TRICKLE\n")
         time.sleep(delay)
deleted file mode 100644
--- a/testing/web-platform/tests/XMLHttpRequest/resources/xmlhttprequest-event-order.js
+++ /dev/null
@@ -1,33 +0,0 @@
-(function(global) {
-  var recorded_xhr_events = [];
-
-  function record_xhr_event(e) {
-    var prefix = e.target instanceof XMLHttpRequestUpload ? "upload." : "";
-    recorded_xhr_events.push((prefix || "") + e.type + "(" + e.loaded + "," + e.total + "," + e.lengthComputable + ")");
-  }
-
-  global.prepare_xhr_for_event_order_test = function(xhr) {
-    xhr.addEventListener("readystatechange", function(e) {
-      recorded_xhr_events.push(xhr.readyState);
-    });
-    var events = ["loadstart", "progress", "abort", "timeout", "error", "load", "loadend"];
-    for(var i=0; i<events.length; ++i) {
-      xhr.addEventListener(events[i], record_xhr_event);
-    }
-    if ("upload" in xhr) {
-      for(var i=0; i<events.length; ++i) {
-        xhr.upload.addEventListener(events[i], record_xhr_event);
-      }
-    }
-  }
-
-  global.assert_xhr_event_order_matches = function(expected) {
-    try {
-      assert_array_equals(recorded_xhr_events, expected);
-    } catch(e) {
-      console.log("Recorded events were:", recorded_xhr_events);
-      console.log("Expected events are: ", expected);
-      throw e;
-    }
-  }
-}(this));
--- a/testing/web-platform/tests/XMLHttpRequest/response-data-progress.htm
+++ b/testing/web-platform/tests/XMLHttpRequest/response-data-progress.htm
@@ -10,42 +10,36 @@
     <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-onprogress" data-tested-assertations="/../.." />
     <link rel="help" href="https://xhr.spec.whatwg.org/#event-xhr-progress" data-tested-assertations="/../.." />
 </head>
 
 <div id="log"></div>
 
 <script>
 
-function doTest(test, expectedLengthComputable, expectedTotal, url) {
+var test = async_test();
+
+test.step(function() {
     var client = new XMLHttpRequest();
     var lastSize = 0;
 
-    client.onprogress = test.step_func(function(e) {
-        assert_equals(e.total, expectedTotal);
-        assert_equals(e.lengthComputable, expectedLengthComputable);
-
+    client.onprogress = test.step_func(function() {
         var currentSize = client.responseText.length;
 
         if (lastSize > 0 && currentSize > lastSize) {
             // growth from a positive size to bigger!
+
             test.done();
         }
 
         lastSize = currentSize;
     });
 
     client.onreadystatechange = test.step_func(function() {
         if (client.readyState === 4) {
             assert_unreached("onprogress not called multiple times, or response body did not grow.");
         }
     });
 
-    client.open("GET", url);
+    client.open("GET", "resources/trickle.py?count=1000");
     client.send(null);
-    return client;
-}
-
-async_test(function () { doTest(this, false, 0, "resources/trickle.py?count=6&delay=150"); },
-           document.title + ', unknown content-length');
-async_test(function () { doTest(this, true, 78, "resources/trickle.py?count=6&delay=150&specifylength=1"); },
-           document.title + ', known content-length');
+});
 </script>
--- a/testing/web-platform/tests/XMLHttpRequest/security-consideration.sub.html
+++ b/testing/web-platform/tests/XMLHttpRequest/security-consideration.sub.html
@@ -16,21 +16,15 @@
         xhr.onprogress = this.unreached_func("MUST NOT dispatch progress event.");
         xhr.onload = this.unreached_func("MUST NOT dispatch load event.");
         xhr.onerror = this.step_func(function(pe) {
           assert_equals(pe.type, "error");
           assert_equals(pe.loaded, 0, "loaded is zero.");
           assert_false(pe.lengthComputable, "lengthComputable is false.");
           assert_equals(pe.total, 0, "total is zero.");
         });
-        xhr.onloadend = this.step_func(function(pe) {
-          assert_equals(pe.type, "loadend");
-          assert_equals(pe.loaded, 0, "loaded is zero.");
-          assert_false(pe.lengthComputable, "lengthComputable is false.");
-          assert_equals(pe.total, 0, "total is zero.");
-          this.done();
-        });
+        xhr.onloadend = this.step_func_done();
         xhr.open("GET", "http://{{host}}:{{ports[http][1]}}/XMLHttpRequest/resources/img.jpg", true);
         xhr.send(null);
       })
     </script>
   </body>
 </html>
--- a/testing/web-platform/tests/XMLHttpRequest/send-no-response-event-order.htm
+++ b/testing/web-platform/tests/XMLHttpRequest/send-no-response-event-order.htm
@@ -6,40 +6,56 @@
     <link rel="help" href="https://xhr.spec.whatwg.org/#event-xhr-loadstart" data-tested-assertations="../.." />
     <link rel="help" href="https://xhr.spec.whatwg.org/#event-xhr-loadend" data-tested-assertations="../.." />
     <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following-sibling::ol/li[9]/ol/li[2]" />
     <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following::dt[10] following::a[contains(@href,'#switch-done')]/.." />
     <link rel="help" href="https://xhr.spec.whatwg.org/#switch-done" data-tested-assertations="following::ol[1]/li[3] following::ol[1]/li[4] following::ol[1]/li[6] following::ol[1]/li[7]" />
     <link rel="help" href="https://xhr.spec.whatwg.org/#the-response-attribute" data-tested-assertations="following-sibling::ol/li[1]" />
     <script src="/resources/testharness.js"></script>
     <script src="/resources/testharnessreport.js"></script>
-    <script src="resources/xmlhttprequest-event-order.js"></script>
     <title>XMLHttpRequest: The send() method: event order when there is no response entity body</title>
 </head>
 
 <body>
     <div id="log"></div>
 
     <script type="text/javascript">
         var test = async_test();
 
         test.step(function()
         {
             var xhr = new XMLHttpRequest();
-            prepare_xhr_for_event_order_test(xhr);
+            var expect = ["loadstart", 4, "load", "loadend"];
+            var actual = [];
 
-            xhr.addEventListener("readystatechange", test.step_func(function() {
-                if (xhr.readyState == 3) {
-                    assert_equals(xhr.response, "");
-                }
-            }));
+            xhr.onreadystatechange = test.step_func(function()
+            {
+                test.step(function()
+                {
+                    if (xhr.readyState == 3)
+                    {
+                        assert_equals(xhr.response, "");
+                    }
+                    else if (xhr.readyState == 4)
+                    {
+                        actual.push(xhr.readyState);
+                    }
+                });
+            });
 
-            xhr.addEventListener("loadend", test.step_func(function(e) {
-                assert_xhr_event_order_matches([1, "loadstart(0,0,false)", 2, "progress(0,0,false)", 4,"load(0,0,false)", "loadend(0,0,false)"]);
+            xhr.onloadstart        = test.step_func(function(e){ actual.push(e.type); });
+            xhr.onload             = test.step_func(function(e){ actual.push(e.type); });
+            xhr.onloadend          = test.step_func(function(e){
+                actual.push(e.type);
+                assert_array_equals(actual, expect);
                 test.done();
-            }));
+            });
+
+            xhr.upload.onloadstart = test.step_func(function(e){ assert_unreached('upload.'+e.type); });
+            xhr.upload.onload      = test.step_func(function(e){ assert_unreached('upload.'+e.type); });
+            xhr.upload.onloadend   = test.step_func(function(e){ assert_unreached('upload.'+e.type); });
 
             xhr.open("POST", "./resources/content.py", true);
             xhr.send();
         });
     </script>
 </body>
 </html>
--- a/testing/web-platform/tests/XMLHttpRequest/send-sync-response-event-order.htm
+++ b/testing/web-platform/tests/XMLHttpRequest/send-sync-response-event-order.htm
@@ -1,14 +1,13 @@
 <!DOCTYPE html>
 <html>
 <head>
     <script src="/resources/testharness.js"></script>
     <script src="/resources/testharnessreport.js"></script>
-    <script src="resources/xmlhttprequest-event-order.js"></script>
     <title>XMLHttpRequest: The send() method: event order when synchronous flag is set</title>
     <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-onloadstart" data-tested-assertations="../.." />
     <link rel="help" href="https://xhr.spec.whatwg.org/#handler-xhr-onloadend" data-tested-assertations="../.." />
     <link rel="help" href="https://xhr.spec.whatwg.org/#event-xhr-loadstart" data-tested-assertations="../.." />
     <link rel="help" href="https://xhr.spec.whatwg.org/#event-xhr-loadend" data-tested-assertations="../.." />
     <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following-sibling::ol/li[9]" />
     <link rel="help" href="https://xhr.spec.whatwg.org/#same-origin-request-steps" data-tested-assertations="following::DL[1]/DT[1]"/>
     <link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following::dt[11] following::a[contains(@href,'#switch-done')]/.." />
@@ -17,19 +16,36 @@
 </head>
 
 <body>
     <div id="log"></div>
 
     <script type="text/javascript">
         test(function () {
             var xhr = new XMLHttpRequest();
-            prepare_xhr_for_event_order_test(xhr);
+            var expect = [4, "load", "loadend"];
+            var actual = [];
+
+            xhr.onreadystatechange = function()
+            {
+                if (xhr.readyState == 4)
+                {
+                    actual.push(xhr.readyState);
+                }
+            };
+
+            xhr.onloadstart        = function(e){ actual.push(e.type); };
+            xhr.onload             = function(e){ actual.push(e.type); };
+            xhr.onloadend          = function(e){ actual.push(e.type); };
+
+            xhr.upload.onload      = function(e){ actual.push("upload." + e.type); };
+            xhr.upload.onloadstart = function(e){ actual.push("upload." + e.type); };
+            xhr.upload.onloadend   = function(e){ actual.push("upload." + e.type);};
 
             xhr.open("POST", "./resources/content.py", false);
             xhr.send("Test Message");
 
             assert_equals(xhr.response, "Test Message");
-            assert_xhr_event_order_matches([1, 4, "load(12,12,true)", "loadend(12,12,true)"]);
+            assert_array_equals(actual, expect);
         });
     </script>
 </body>
 </html>