Merge mozilla-central to inbound
authorarthur.iakab <aiakab@mozilla.com>
Thu, 27 Dec 2018 23:59:04 +0200
changeset 509130 8427d4e2753703f2bf32ad34d670c82bb5492294
parent 509129 4fac48f96e20a106f379c3aec96c11cf047c68cd (current diff)
parent 509116 a77e8f3efc4cb45b7caa0c87879910b9991b4219 (diff)
child 509131 75ddf9a6a2bb75a76e4fe1f683d52ca8987250bf
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone66.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
Merge mozilla-central to inbound
--- a/.cron.yml
+++ b/.cron.yml
@@ -99,16 +99,17 @@ jobs:
               mozilla-central: [{hour: 10, minute: 0}]
               # No default
 
     - name: customv8-update
       job:
           type: decision-task
           treeherder-symbol: customv8
           target-tasks-method: customv8_update
+          optimize-target-tasks: false
       run-on-projects:
           - mozilla-central
       when:
           by-project:
               mozilla-central: [{hour: 10, minute: 30}]
 
     - name: bouncer-check
       job:
--- a/.eslintignore
+++ b/.eslintignore
@@ -15,20 +15,16 @@ obj*/**
 # If you are enabling a directory, please add directory specific exclusions
 # below.
 docshell/test/browser/**
 docshell/test/iframesandbox/**
 docshell/test/mochitest/**
 extensions/cookie/**
 extensions/spellcheck/**
 extensions/universalchardet/**
-gfx/layers/**
-gfx/tests/browser/**
-gfx/tests/chrome/**
-gfx/tests/mochitest/**
 image/**
 layout/**
 modules/**
 netwerk/cookie/test/browser/**
 netwerk/test/browser/**
 netwerk/test/mochitests/**
 netwerk/test/unit*/**
 tools/update-packaging/**
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -41,10 +41,16 @@ module.exports = {
     }
   }, {
     // TODO: Bug 1513639. Temporarily turn off reject-importGlobalProperties
     // due to other ESLint enabling happening in DOM.
     "files": "dom/**",
     "rules": {
       "mozilla/reject-importGlobalProperties": "off",
     }
+  }, {
+    // TODO: Bug 1515949. Enable no-undef for gfx/
+    "files": "gfx/layers/apz/test/mochitest/**",
+    "rules": {
+      "no-undef": "off",
+    }
   }]
 };
--- a/browser/components/enterprisepolicies/content/aboutPolicies.css
+++ b/browser/components/enterprisepolicies/content/aboutPolicies.css
@@ -50,49 +50,58 @@ body {
 .tab {
   padding: 0.5em 0;
 }
 
 .tab table {
   width: 100%;
 }
 
-tr:hover td {
+tbody tr {
+  transition: background cubic-bezier(.07, .95, 0, 1) 250ms;
+}
+
+tbody tr:hover {
   background-color: #d7d7db;
 }
 
 th, td, table {
   border-collapse: collapse;
   border: none;
   text-align: start;
 }
 
 th {
   padding: 1rem;
   font-size: larger;
 }
 
 td {
   padding: 1rem;
-  transition: background cubic-bezier(.07, .95, 0, 1) 250ms;
 }
 
 /*
  * In Documentation Tab, this property sets the policies row in an
  * alternate color scheme of white and grey as each policy comprises
  * of two tbody tags, one for the description and the other for the
  * collapsible information block.
  */
 
 .active-policies tr.odd,
 .errors tr:nth-child(odd),
 tbody:nth-child(4n + 1) {
   background-color: #ededf0;
 }
 
+.active-policies tr.odd:hover,
+.errors tr:nth-child(odd):hover,
+tbody:nth-child(4n + 1):hover {
+  background-color: #d7d7db;
+}
+
 .arr_sep.odd:not(:last-child) td:not(:first-child) {
   border-bottom: 2px solid #f9f9fa;
 }
 
 .arr_sep.even:not(:last-child) td:not(:first-child) {
   border-bottom: 2px solid #ededf0;
 }
 
--- a/build/moz.configure/rust.configure
+++ b/build/moz.configure/rust.configure
@@ -67,17 +67,17 @@ def rust_compiler(rustc_info, cargo_info
         die(dedent('''\
         Rust compiler not found.
         To compile rust language sources, you must have 'rustc' in your path.
         See https://www.rust-lang.org/ for more information.
 
         You can install rust by running './mach bootstrap'
         or by directly running the installer from https://rustup.rs/
         '''))
-    rustc_min_version = Version('1.30.0')
+    rustc_min_version = Version('1.31.0')
     cargo_min_version = rustc_min_version
 
     version = rustc_info.version
     if version < rustc_min_version:
         die(dedent('''\
         Rust compiler {} is too old.
 
         To compile Rust language sources please install at least
--- a/dom/canvas/test/webgl-conf/generated-mochitest.ini
+++ b/dom/canvas/test/webgl-conf/generated-mochitest.ini
@@ -1,14 +1,14 @@
 # This is a GENERATED FILE. Do not edit it directly.
 # Regenerated it by using `python generate-wrappers-and-manifest.py`.
 # Mark failing (fail-if) and crashing (skip-if) tests in mochitest-errata.ini.
 
 [DEFAULT]
-
+skip-if = toolkit == 'android' && e10s && isEmulator
 
 support-files = always-fail.html
                 checkout/00_test_list.txt
                 checkout/CONFORMANCE_RULES.txt
                 checkout/README.md
                 checkout/closure-library/AUTHORS
                 checkout/closure-library/CONTRIBUTING
                 checkout/closure-library/LICENSE
--- a/dom/canvas/test/webgl-conf/mochitest-errata.ini
+++ b/dom/canvas/test/webgl-conf/mochitest-errata.ini
@@ -16,16 +16,18 @@
 # os_version strings
 #   https://msdn.microsoft.com/en-us/library/windows/desktop/ms724832%28v=vs.85%29.aspx
 #   * Windows 7: 6.1
 #   * Windows 8: 6.2
 #   * Windows 8.1: 6.3
 #   * Windows 10: 10.0
 
 [DEFAULT]
+# Cross-process WebGL doesn't seem to work under an emulator
+skip-if = toolkit == 'android' && e10s && is_emulator
 
 [generated/test_..__always-fail.html]
 fail-if = 1
 
 ####################
 # Tests requesting non-local network connections.
 
 [generated/test_conformance__more__functions__readPixelsBadArgs.html]
--- a/dom/locales/en-US/chrome/security/security.properties
+++ b/dom/locales/en-US/chrome/security/security.properties
@@ -75,21 +75,21 @@ UnsupportedHashAlg=Unsupported hash algorithm in the integrity attribute: “%1$S”
 # LOCALIZATION NOTE: Do not translate "integrity"
 NoValidMetadata=The integrity attribute does not contain any valid metadata.
 
 # LOCALIZATION NOTE: Do not translate "RC4".
 WeakCipherSuiteWarning=This site uses the cipher RC4 for encryption, which is deprecated and insecure.
 
 #XCTO: nosniff
 # LOCALIZATION NOTE: Do not translate "X-Content-Type-Options: nosniff".
-MimeTypeMismatch=The resource from “%1$S” was blocked due to MIME type mismatch (X-Content-Type-Options: nosniff).
+MimeTypeMismatch2=The resource from “%1$S” was blocked due to MIME type (“%2$S”) mismatch (X-Content-Type-Options: nosniff).
 # LOCALIZATION NOTE: Do not translate "X-Content-Type-Options" and also do not trasnlate "nosniff".
 XCTOHeaderValueMissing=X-Content-Type-Options header warning: value was “%1$S”; did you mean to send “nosniff”?
 
-BlockScriptWithWrongMimeType=Script from “%1$S” was blocked because of a disallowed MIME type.
+BlockScriptWithWrongMimeType2=Script from “%1$S” was blocked because of a disallowed MIME type (“%2$S”).
 
 # LOCALIZATION NOTE: Do not translate "data: URI".
 BlockTopLevelDataURINavigation=Navigation to toplevel data: URI not allowed (Blocked loading of: “%1$S”)
 BlockSubresourceRedirectToData=Redirecting to insecure data: URI not allowed (Blocked loading of: “%1$S”)
 
 BlockSubresourceFTP=Loading FTP subresource within http(s) page not allowed (Blocked loading of: “%1$S”)
 
 # LOCALIZATION NOTE (BrowserUpgradeInsecureDisplayRequest):
--- a/dom/media/tests/mochitest/mochitest.ini
+++ b/dom/media/tests/mochitest/mochitest.ini
@@ -185,17 +185,18 @@ tags=capturestream
 skip-if = toolkit == 'android' # android(Bug 1189784, timeouts on 4.3 emulator), Bug 1264340
 [test_peerConnection_captureStream_canvas_2d.html]
 skip-if = android_version == '18' # android(Bug 1319019, timeouts on 4.3 emulator)
 [test_peerConnection_captureStream_canvas_2d_noSSRC.html]
 skip-if = android_version == '18' # android(Bug 1319019, timeouts on 4.3 emulator)
 [test_peerConnection_multiple_captureStream_canvas_2d.html]
 skip-if = (android_version == '18' && debug) # android(Bug 1189784, timeouts on 4.3 emulator)
 [test_peerConnection_captureStream_canvas_webgl.html]
-skip-if = (android_version <= '17' || android_version == '18') # (<17: bug 1346630, 18: bug 1385950)
+# Cross process WebGL doesn't seem to work in the emulator
+skip-if = (toolkit == 'android' && e10s && is_emulator) || (android_version <= '17' || android_version == '18') # (<17: bug 1346630, 18: bug 1385950)
 [test_peerConnection_certificates.html]
 disabled=bug 1180968
 [test_peerConnection_close.html]
 [test_peerConnection_closeDuringIce.html]
 [test_peerConnection_constructedStream.html]
 skip-if = android_version == '18' # android(Bug 1189784, timeouts on 4.3 emulator)
 [test_peerConnection_errorCallbacks.html]
 [test_peerConnection_iceFailure.html]
--- a/gfx/layers/apz/test/mochitest/apz_test_native_event_utils.js
+++ b/gfx/layers/apz/test/mochitest/apz_test_native_event_utils.js
@@ -1,8 +1,11 @@
+// ownerGlobal isn't defined in content privileged windows.
+/* eslint-disable mozilla/use-ownerGlobal */
+
 // Utilities for synthesizing of native events.
 
 function getResolution() {
   let resolution = { value: -1 }; // bogus value in case DWU fails us
   SpecialPowers.getDOMWindowUtils(window).getResolution(resolution);
   return resolution.value;
 }
 
@@ -10,17 +13,17 @@ function getPlatform() {
   if (navigator.platform.indexOf("Win") == 0) {
     return "windows";
   }
   if (navigator.platform.indexOf("Mac") == 0) {
     return "mac";
   }
   // Check for Android before Linux
   if (navigator.appVersion.includes("Android")) {
-    return "android"
+    return "android";
   }
   if (navigator.platform.indexOf("Linux") == 0) {
     return "linux";
   }
   return "unknown";
 }
 
 function nativeVerticalWheelEventMsg() {
@@ -106,17 +109,17 @@ function getBoundingClientRectRelativeTo
   var rect = aElement.getBoundingClientRect();
   var offsetX = {}, offsetY = {};
   utils.getVisualViewportOffsetRelativeToLayoutViewport(offsetX, offsetY);
   rect.x -= offsetX.value;
   rect.y -= offsetY.value;
   return rect;
 }
 
-// Several event sythesization functions below (and their helpers) take a "target" 
+// Several event sythesization functions below (and their helpers) take a "target"
 // parameter which may be either an element or a window. For such functions,
 // the target's "bounding rect" refers to the bounding client rect for an element,
 // and the window's origin for a window.
 // Not all functions have been "upgraded" to allow a window argument yet; feel
 // free to upgrade others as necessary.
 
 // Convert (aX, aY), in CSS pixels relative to aTarget's bounding rect
 // to device pixels relative to the screen.
@@ -126,31 +129,31 @@ function coordinatesRelativeToScreen(aX,
   var resolution = getResolution();
   var rect = (aTarget instanceof Window)
     ? {left: 0, top: 0} /* we don't use the width or height */
     : getBoundingClientRectRelativeToVisualViewport(aTarget);
   // moxInnerScreen{X,Y} are in CSS coordinates of the browser chrome.
   // The device scale applies to them, but the resolution only zooms the content.
   return {
     x: (targetWindow.mozInnerScreenX + ((rect.left + aX) * resolution)) * deviceScale,
-    y: (targetWindow.mozInnerScreenY + ((rect.top + aY) * resolution)) * deviceScale
+    y: (targetWindow.mozInnerScreenY + ((rect.top + aY) * resolution)) * deviceScale,
   };
 }
 
 // Get the bounding box of aElement, and return it in device pixels
 // relative to the screen.
 function rectRelativeToScreen(aElement) {
   var targetWindow = aElement.ownerDocument.defaultView;
   var scale = targetWindow.devicePixelRatio;
   var rect = aElement.getBoundingClientRect();
   return {
     x: (targetWindow.mozInnerScreenX + rect.left) * scale,
     y: (targetWindow.mozInnerScreenY + rect.top) * scale,
     w: (rect.width * scale),
-    h: (rect.height * scale)
+    h: (rect.height * scale),
   };
 }
 
 // Synthesizes a native mousewheel event and returns immediately. This does not
 // guarantee anything; you probably want to use one of the other functions below
 // which actually wait for results.
 // aX and aY are relative to the top-left of |aTarget|'s bounding rect.
 // aDeltaX and aDeltaY are pixel deltas, and aObserver can be left undefined
@@ -170,42 +173,42 @@ function synthesizeNativeWheel(aTarget, 
 }
 
 // Synthesizes a native mousewheel event and invokes the callback once the
 // request has been successfully made to the OS. This does not necessarily
 // guarantee that the OS generates the event we requested. See
 // synthesizeNativeWheel for details on the parameters.
 function synthesizeNativeWheelAndWaitForObserver(aElement, aX, aY, aDeltaX, aDeltaY, aCallback) {
   var observer = {
-    observe: function(aSubject, aTopic, aData) {
+    observe(aSubject, aTopic, aData) {
       if (aCallback && aTopic == "mousescrollevent") {
         setTimeout(aCallback, 0);
       }
-    }
+    },
   };
   return synthesizeNativeWheel(aElement, aX, aY, aDeltaX, aDeltaY, observer);
 }
 
 // Synthesizes a native mousewheel event and invokes the callback once the
 // wheel event is dispatched to |aTarget|'s containing window. If the event
 // targets content in a subdocument, |aTarget| should be inside the
-// subdocument (or the subdocument's window). See synthesizeNativeWheel for 
+// subdocument (or the subdocument's window). See synthesizeNativeWheel for
 // details on the other parameters.
 function synthesizeNativeWheelAndWaitForWheelEvent(aTarget, aX, aY, aDeltaX, aDeltaY, aCallback) {
   var targetWindow = windowForTarget(aTarget);
   targetWindow.addEventListener("wheel", function(e) {
     setTimeout(aCallback, 0);
   }, {once: true});
   return synthesizeNativeWheel(aTarget, aX, aY, aDeltaX, aDeltaY);
 }
 
 // Synthesizes a native mousewheel event and invokes the callback once the
 // first resulting scroll event is dispatched to |aTarget|'s containing window.
 // If the event targets content in a subdocument, |aTarget| should be inside
-// the subdocument (or the subdocument's window).  See synthesizeNativeWheel 
+// the subdocument (or the subdocument's window).  See synthesizeNativeWheel
 // for details on the other parameters.
 function synthesizeNativeWheelAndWaitForScrollEvent(aTarget, aX, aY, aDeltaX, aDeltaY, aCallback) {
   var targetWindow = windowForTarget(aTarget);
   targetWindow.addEventListener("scroll", function() {
     setTimeout(aCallback, 0);
   }, {capture: true, once: true}); // scroll events don't always bubble
   return synthesizeNativeWheel(aTarget, aX, aY, aDeltaX, aDeltaY);
 }
@@ -218,17 +221,17 @@ function synthesizeNativeMouseMove(aTarg
   var element = elementForTarget(aTarget);
   utils.sendNativeMouseEvent(pt.x, pt.y, nativeMouseMoveEventMsg(), 0, element);
   return true;
 }
 
 // Synthesizes a native mouse move event and invokes the callback once the
 // mouse move event is dispatched to |aTarget|'s containing window. If the event
 // targets content in a subdocument, |aTarget| should be inside the
-// subdocument (or the subdocument window). See synthesizeNativeMouseMove for 
+// subdocument (or the subdocument window). See synthesizeNativeMouseMove for
 // details on the other parameters.
 function synthesizeNativeMouseMoveAndWaitForMoveEvent(aTarget, aX, aY, aCallback) {
   var targetWindow = windowForTarget(aTarget);
   targetWindow.addEventListener("mousemove", function(e) {
     setTimeout(aCallback, 0);
   }, {once: true});
   return synthesizeNativeMouseMove(aTarget, aX, aY);
 }
@@ -260,25 +263,25 @@ function synthesizeNativeTouch(aTarget, 
 // aObserver is the observer that will get registered on the very last
 //   synthesizeNativeTouch call this function makes.
 // aTouchIds is an array holding the touch ID values of each "finger".
 function* synthesizeNativeTouchSequences(aTarget, aPositions, aObserver = null, aTouchIds = [0]) {
   // We use lastNonNullValue to figure out which synthesizeNativeTouch call
   // will be the last one we make, so that we can register aObserver on it.
   var lastNonNullValue = -1;
   var yields = 0;
-  for (var i = 0; i < aPositions.length; i++) {
+  for (let i = 0; i < aPositions.length; i++) {
     if (aPositions[i] == null) {
       yields++;
       continue;
     }
     if (aPositions[i].length != aTouchIds.length) {
       throw "aPositions[" + i + "] did not have the expected number of positions; expected " + aTouchIds.length + " touch points but found " + aPositions[i].length;
     }
-    for (var j = 0; j < aTouchIds.length; j++) {
+    for (let j = 0; j < aTouchIds.length; j++) {
       if (aPositions[i][j] != null) {
         lastNonNullValue = ((i - yields) * aTouchIds.length) + j;
       }
     }
   }
   if (lastNonNullValue < 0) {
     throw "All values in positions array were null!";
   }
@@ -295,23 +298,23 @@ function* synthesizeNativeTouchSequences
   var lastSynthesizeCall = lastNonNullValue + aTouchIds.length;
 
   // track which touches are down and which are up. start with all up
   var currentPositions = new Array(aTouchIds.length);
   currentPositions.fill(null);
 
   // Iterate over the position data now, and generate the touches requested
   yields = 0;
-  for (var i = 0; i < aPositions.length; i++) {
+  for (let i = 0; i < aPositions.length; i++) {
     if (aPositions[i] == null) {
       yields++;
       yield i;
       continue;
     }
-    for (var j = 0; j < aTouchIds.length; j++) {
+    for (let j = 0; j < aTouchIds.length; j++) {
       if (aPositions[i][j] == null) {
         // null means lift the finger
         if (currentPositions[j] == null) {
           // it's already lifted, do nothing
         } else {
           // synthesize the touch-up. If this is the last call we're going to
           // make, pass the observer as well
           var thisIndex = ((i - yields) * aTouchIds.length) + j;
@@ -328,18 +331,17 @@ function* synthesizeNativeTouchSequences
   return true;
 }
 
 // Note that when calling this function you'll want to make sure that the pref
 // "apz.touch_start_tolerance" is set to 0, or some of the touchmove will get
 // consumed to overcome the panning threshold.
 function synthesizeNativeTouchDrag(aTarget, aX, aY, aDeltaX, aDeltaY, aObserver = null, aTouchId = 0) {
   var steps = Math.max(Math.abs(aDeltaX), Math.abs(aDeltaY));
-  var positions = new Array();
-  positions.push([{ x: aX, y: aY }]);
+  var positions = [[{ x: aX, y: aY }]];
   for (var i = 1; i < steps; i++) {
     var dx = i * (aDeltaX / steps);
     var dy = i * (aDeltaY / steps);
     var pos = { x: aX + dx, y: aY + dy };
     positions.push([pos]);
   }
   positions.push([{ x: aX + aDeltaX, y: aY + aDeltaY }]);
   var continuation = synthesizeNativeTouchSequences(aTarget, positions, aObserver, [aTouchId]);
@@ -420,13 +422,13 @@ function* dragVerticalScrollbar(element,
   yield synthesizeNativeMouseEvent(element, mouseX, mouseY, nativeMouseDownEventMsg(), testDriver);
   // drag vertically by |increment| until we reach the specified distance
   for (var y = increment; y < distance; y += increment) {
     yield synthesizeNativeMouseEvent(element, mouseX, mouseY + y, nativeMouseMoveEventMsg(), testDriver);
   }
   yield synthesizeNativeMouseEvent(element, mouseX, mouseY + distance, nativeMouseMoveEventMsg(), testDriver);
 
   // and return a generator to call afterwards to finish up the drag
-  return function*() {
+  return function* () {
     dump("Finishing drag of #" + element.id + "\n");
     yield synthesizeNativeMouseEvent(element, mouseX, mouseY + distance, nativeMouseUpEventMsg(), testDriver);
   };
 }
--- a/gfx/layers/apz/test/mochitest/apz_test_utils.js
+++ b/gfx/layers/apz/test/mochitest/apz_test_utils.js
@@ -3,32 +3,35 @@
 // ----------------------------------------------------------------------
 // Functions that convert the APZ test data into a more usable form.
 // Every place we have a WebIDL sequence whose elements are dictionaries
 // with two elements, a key, and a value, we convert this into a JS
 // object with a property for each key/value pair. (This is the structure
 // we really want, but we can't express in directly in WebIDL.)
 // ----------------------------------------------------------------------
 
+// getHitTestConfig() expects apz_test_native_event_utils.js to be loaded as well.
+/* import-globals-from apz_test_native_event_utils.js */
+
 function convertEntries(entries) {
   var result = {};
   for (var i = 0; i < entries.length; ++i) {
     result[entries[i].key] = entries[i].value;
   }
   return result;
 }
 
 function getPropertyAsRect(scrollFrames, scrollId, prop) {
   SimpleTest.ok(scrollId in scrollFrames,
-                'expected scroll frame data for scroll id ' + scrollId);
+                "expected scroll frame data for scroll id " + scrollId);
   var scrollFrameData = scrollFrames[scrollId];
-  SimpleTest.ok('displayport' in scrollFrameData,
-                'expected a ' + prop + ' for scroll id ' + scrollId);
+  SimpleTest.ok("displayport" in scrollFrameData,
+                "expected a " + prop + " for scroll id " + scrollId);
   var value = scrollFrameData[prop];
-  var pieces = value.replace(/[()\s]+/g, '').split(',');
+  var pieces = value.replace(/[()\s]+/g, "").split(",");
   SimpleTest.is(pieces.length, 4, "expected string of form (x,y,w,h)");
   return { x: parseInt(pieces[0]),
            y: parseInt(pieces[1]),
            w: parseInt(pieces[2]),
            h: parseInt(pieces[3]) };
 }
 
 function convertScrollFrameData(scrollFrames) {
@@ -82,36 +85,36 @@ function isTransformClose(a, b, name) {
 // APZC tree structure corresponding to the layer subtree for the
 // content process that triggered the paint, is reconstructed (as
 // the APZ test data only contains information abot this subtree).
 function buildApzcTree(paint) {
   // The APZC tree can potentially have multiple root nodes,
   // so we invent a node that is the parent of all roots.
   // This 'root' does not correspond to an APZC.
   var root = {scrollId: -1, children: []};
-  for (var scrollId in paint) {
+  for (let scrollId in paint) {
     paint[scrollId].children = [];
     paint[scrollId].scrollId = scrollId;
   }
-  for (var scrollId in paint) {
+  for (let scrollId in paint) {
     var parentNode = null;
     if ("hasNoParentWithSameLayersId" in paint[scrollId]) {
       parentNode = root;
     } else if ("parentScrollId" in paint[scrollId]) {
       parentNode = paint[paint[scrollId].parentScrollId];
     }
     parentNode.children.push(paint[scrollId]);
   }
   return root;
 }
 
 // Given an APZC tree produced by buildApzcTree, return the RCD node in
 // the tree, or null if there was none.
 function findRcdNode(apzcTree) {
-  if (!!apzcTree.isRootContent) { // isRootContent will be undefined or "1"
+  if (apzcTree.isRootContent) { // isRootContent will be undefined or "1"
     return apzcTree;
   }
   for (var i = 0; i < apzcTree.children.length; i++) {
     var rcd = findRcdNode(apzcTree.children[i]);
     if (rcd != null) {
       return rcd;
     }
   }
@@ -124,26 +127,26 @@ function findRcdNode(apzcTree) {
 function isLayerized(elementId) {
   var contentTestData = SpecialPowers.getDOMWindowUtils(window).getContentAPZTestData();
   ok(contentTestData.paints.length > 0, "expected at least one paint");
   var seqno = contentTestData.paints[contentTestData.paints.length - 1].sequenceNumber;
   contentTestData = convertTestData(contentTestData);
   var paint = contentTestData.paints[seqno];
   for (var scrollId in paint) {
     if ("contentDescription" in paint[scrollId]) {
-      if (paint[scrollId]["contentDescription"].includes(elementId)) {
+      if (paint[scrollId].contentDescription.includes(elementId)) {
         return true;
       }
     }
   }
   return false;
 }
 
 function promiseApzRepaintsFlushed(aWindow = window) {
-  return new Promise(function (resolve, reject) {
+  return new Promise(function(resolve, reject) {
     var repaintDone = function() {
       SpecialPowers.Services.obs.removeObserver(repaintDone, "apz-repaints-flushed");
       setTimeout(resolve, 0);
     };
     SpecialPowers.Services.obs.addObserver(repaintDone, "apz-repaints-flushed");
     if (SpecialPowers.getDOMWindowUtils(aWindow).flushApzRepaints()) {
       dump("Flushed APZ repaints, waiting for callback...\n");
     } else {
@@ -222,17 +225,17 @@ function runSubtestsSeriallyInFreshWindo
 
     function advanceSubtestExecution() {
       var test = aSubtests[testIndex];
       if (w) {
         // Run any cleanup functions registered in the subtest
         if (w.ApzCleanup) { // guard against the subtest not loading apz_test_utils.js
           w.ApzCleanup.execute();
         }
-        if (typeof test.dp_suppression != 'undefined') {
+        if (typeof test.dp_suppression != "undefined") {
           // We modified the suppression when starting the test, so now undo that.
           SpecialPowers.getDOMWindowUtils(window).respectDisplayPortSuppression(!test.dp_suppression);
         }
         if (test.prefs) {
           // We pushed some prefs for this test, pop them, and re-invoke
           // advanceSubtestExecution() after that's been processed
           SpecialPowers.popPrefEnv(function() {
             w.close();
@@ -256,54 +259,54 @@ function runSubtestsSeriallyInFreshWindo
       if (onlyOneSubtest && onlyOneSubtest != test.file) {
         SimpleTest.ok(true, "Skipping " + test.file + " because only " + onlyOneSubtest + " is being run");
         setTimeout(function() { advanceSubtestExecution(); }, 0);
         return;
       }
 
       SimpleTest.ok(true, "Starting subtest " + test.file);
 
-      if (typeof test.dp_suppression != 'undefined') {
+      if (typeof test.dp_suppression != "undefined") {
         // Normally during a test, the displayport will get suppressed during page
         // load, and unsuppressed at a non-deterministic time during the test. The
         // unsuppression can trigger a repaint which interferes with the test, so
         // to avoid that we can force the displayport to be unsuppressed for the
         // entire test which is more deterministic.
         SpecialPowers.getDOMWindowUtils(window).respectDisplayPortSuppression(test.dp_suppression);
       }
 
       function spawnTest(aFile) {
-        w = window.open('', "_blank");
+        w = window.open("", "_blank");
         w.subtestDone = advanceSubtestExecution;
         w.isApzSubtest = true;
         w.SimpleTest = SimpleTest;
         w.is = function(a, b, msg) { return is(a, b, aFile + " | " + msg); };
         w.ok = function(cond, msg) {
           arguments[1] = aFile + " | " + msg;
           // Forward all arguments to SimpleTest.ok where we will check that ok() was
           // called with at most 2 arguments.
           return SimpleTest.ok.apply(SimpleTest, arguments);
         };
-        w.todo_is = function(a, b, msg)  { return todo_is(a, b, aFile + " | " + msg); };
+        w.todo_is = function(a, b, msg) { return todo_is(a, b, aFile + " | " + msg); };
         w.todo = function(cond, msg) { return todo(cond, aFile + " | " + msg); };
         if (test.onload) {
-          w.addEventListener('load', function(e) { test.onload(w); }, { once: true });
+          w.addEventListener("load", function(e) { test.onload(w); }, { once: true });
         }
-        var subtestUrl = location.href.substring(0, location.href.lastIndexOf('/') + 1) + aFile;
+        var subtestUrl = location.href.substring(0, location.href.lastIndexOf("/") + 1) + aFile;
         function urlResolves(url) {
           var request = new XMLHttpRequest();
-          request.open('GET', url, false);
+          request.open("GET", url, false);
           request.send();
           return request.status !== 404;
         }
         if (!urlResolves(subtestUrl)) {
           SimpleTest.ok(false, "Subtest URL " + subtestUrl + " does not resolve. " +
               "Be sure it's present in the support-files section of mochitest.ini.");
           reject();
-          return;
+          return undefined;
         }
         w.location = subtestUrl;
         return w;
       }
 
       if (test.prefs) {
         // Got some prefs for this subtest, push them
         SpecialPowers.pushPrefEnv({"set": test.prefs}, function() {
@@ -316,36 +319,37 @@ function runSubtestsSeriallyInFreshWindo
 
     advanceSubtestExecution();
   }).catch(function(e) {
     SimpleTest.ok(false, "Error occurred while running subtests: " + e);
   });
 }
 
 function pushPrefs(prefs) {
-  return SpecialPowers.pushPrefEnv({'set': prefs});
+  return SpecialPowers.pushPrefEnv({"set": prefs});
 }
 
 async function waitUntilApzStable() {
   if (!SpecialPowers.isMainProcess()) {
     // We use this waitUntilApzStable function during test initialization
     // and for those scenarios we want to flush the parent-process layer
     // tree to the compositor and wait for that as well. That way we know
     // that not only is the content-process layer tree ready in the compositor,
     // the parent-process layer tree in the compositor has the appropriate
     // RefLayer pointing to the content-process layer tree.
 
     // Sadly this helper function cannot reuse any code from other places because
     // it must be totally self-contained to be shipped over to the parent process.
+    /* eslint-env mozilla/frame-script */
     function parentProcessFlush() {
       addMessageListener("apz-flush", function() {
         ChromeUtils.import("resource://gre/modules/Services.jsm");
-        var topWin = Services.wm.getMostRecentWindow('navigator:browser');
+        var topWin = Services.wm.getMostRecentWindow("navigator:browser");
         if (!topWin) {
-          topWin = Services.wm.getMostRecentWindow('navigator:geckoview');
+          topWin = Services.wm.getMostRecentWindow("navigator:geckoview");
         }
         var topUtils = topWin.windowUtils;
 
         var repaintDone = function() {
           Services.obs.removeObserver(repaintDone, "apz-repaints-flushed");
           // send message back to content process
           sendAsyncMessage("apz-flush-done", null);
         };
@@ -357,17 +361,17 @@ async function waitUntilApzStable() {
 
           Services.obs.addObserver(repaintDone, "apz-repaints-flushed");
           if (topUtils.flushApzRepaints()) {
             dump("Parent process: flushed APZ repaints, waiting for callback...\n");
           } else {
             dump("Parent process: flushing APZ repaints was a no-op, triggering callback directly...\n");
             repaintDone();
           }
-        }
+        };
 
         // Flush APZ repaints, but wait until all the pending paints have been
         // sent.
         flushRepaint();
       });
     }
 
     // This is the first time waitUntilApzStable is being called, do initialization
@@ -476,62 +480,64 @@ function runContinuation(testFunction) {
 // element is obscured by other things on top, the snapshot will include those
 // things. If it is clipped by a scroll container, the snapshot will include
 // that area anyway, so you will probably get parts of the scroll container in
 // the snapshot. If the rect extends outside the browser window then the
 // results are undefined.
 // The snapshot is returned in the form of a data URL.
 function getSnapshot(rect) {
   function parentProcessSnapshot() {
-    addMessageListener('snapshot', function(rect) {
-      ChromeUtils.import('resource://gre/modules/Services.jsm');
-      var topWin = Services.wm.getMostRecentWindow('navigator:browser');
+    addMessageListener("snapshot", function(parentRect) {
+      ChromeUtils.import("resource://gre/modules/Services.jsm");
+      var topWin = Services.wm.getMostRecentWindow("navigator:browser");
       if (!topWin) {
-        topWin = Services.wm.getMostRecentWindow('navigator:geckoview');
+        topWin = Services.wm.getMostRecentWindow("navigator:geckoview");
       }
 
       // reposition the rect relative to the top-level browser window
-      rect = JSON.parse(rect);
-      rect.x -= topWin.mozInnerScreenX;
-      rect.y -= topWin.mozInnerScreenY;
+      parentRect = JSON.parse(parentRect);
+      parentRect.x -= topWin.mozInnerScreenX;
+      parentRect.y -= topWin.mozInnerScreenY;
 
       // take the snapshot
       var canvas = topWin.document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
-      canvas.width = rect.w;
-      canvas.height = rect.h;
+      canvas.width = parentRect.w;
+      canvas.height = parentRect.h;
       var ctx = canvas.getContext("2d");
-      ctx.drawWindow(topWin, rect.x, rect.y, rect.w, rect.h, 'rgb(255,255,255)', ctx.DRAWWINDOW_DRAW_VIEW | ctx.DRAWWINDOW_USE_WIDGET_LAYERS | ctx.DRAWWINDOW_DRAW_CARET);
+      ctx.drawWindow(topWin, parentRect.x, parentRect.y, parentRect.w, parentRect.h,
+        "rgb(255,255,255)",
+        ctx.DRAWWINDOW_DRAW_VIEW | ctx.DRAWWINDOW_USE_WIDGET_LAYERS | ctx.DRAWWINDOW_DRAW_CARET);
       return canvas.toDataURL();
     });
   }
 
-  if (typeof getSnapshot.chromeHelper == 'undefined') {
+  if (typeof getSnapshot.chromeHelper == "undefined") {
     // This is the first time getSnapshot is being called; do initialization
     getSnapshot.chromeHelper = SpecialPowers.loadChromeScript(parentProcessSnapshot);
-    ApzCleanup.register(function() { getSnapshot.chromeHelper.destroy() });
+    ApzCleanup.register(function() { getSnapshot.chromeHelper.destroy(); });
   }
 
-  return getSnapshot.chromeHelper.sendSyncMessage('snapshot', JSON.stringify(rect)).toString();
+  return getSnapshot.chromeHelper.sendSyncMessage("snapshot", JSON.stringify(rect)).toString();
 }
 
 // Takes the document's query string and parses it, assuming the query string
 // is composed of key-value pairs where the value is in JSON format. The object
 // returned contains the various values indexed by their respective keys. In
 // case of duplicate keys, the last value be used.
 // Examples:
 //   ?key="value"&key2=false&key3=500
 //     produces { "key": "value", "key2": false, "key3": 500 }
 //   ?key={"x":0,"y":50}&key2=[1,2,true]
 //     produces { "key": { "x": 0, "y": 0 }, "key2": [1, 2, true] }
 function getQueryArgs() {
   var args = {};
   if (location.search.length > 0) {
-    var params = location.search.substr(1).split('&');
+    var params = location.search.substr(1).split("&");
     for (var p of params) {
-      var [k, v] = p.split('=');
+      var [k, v] = p.split("=");
       args[k] = JSON.parse(v);
     }
   }
   return args;
 }
 
 // Return a function that returns a promise to create a script element with the
 // given URI and append it to the head of the document in the given window.
@@ -540,43 +546,43 @@ function getQueryArgs() {
 //   waitUntilApzStable().then(injectScript('foo'))
 //                       .then(injectScript('bar'));
 // If you want to do the injection right away, run the function returned by
 // this function:
 //   injectScript('foo')();
 function injectScript(aScript, aWindow = window) {
   return function() {
     return new Promise(function(resolve, reject) {
-      var e = aWindow.document.createElement('script');
-      e.type = 'text/javascript';
+      var e = aWindow.document.createElement("script");
+      e.type = "text/javascript";
       e.onload = function() {
         resolve();
       };
       e.onerror = function() {
-        dump('Script [' + aScript + '] errored out\n');
+        dump("Script [" + aScript + "] errored out\n");
         reject();
       };
       e.src = aScript;
-      aWindow.document.getElementsByTagName('head')[0].appendChild(e);
+      aWindow.document.getElementsByTagName("head")[0].appendChild(e);
     });
   };
 }
 
 // Compute some configuration information used for hit testing.
 // The computed information is cached to avoid recomputing it
 // each time this function is called.
 // The computed information is an object with three fields:
 //   utils: the nsIDOMWindowUtils instance for this window
 //   isWebRender: true if WebRender is enabled
 //   isWindow: true if the platform is Windows
 function getHitTestConfig() {
   if (!("hitTestConfig" in window)) {
     var utils = SpecialPowers.getDOMWindowUtils(window);
-    var isWebRender = (utils.layerManagerType == 'WebRender');
-    var isWindows = (getPlatform() == 'windows');
+    var isWebRender = (utils.layerManagerType == "WebRender");
+    var isWindows = (getPlatform() == "windows");
     window.hitTestConfig = { utils, isWebRender, isWindows };
   }
   return window.hitTestConfig;
 }
 
 // Compute the coordinates of the center of the given element. The argument
 // can either be a string (the id of the element desired) or the element
 // itself.
@@ -625,21 +631,21 @@ function hitInfoToString(hitInfo) {
 function checkHitResult(hitResult, expectedHitInfo, expectedScrollId, desc) {
   is(hitInfoToString(hitResult.hitInfo), hitInfoToString(expectedHitInfo), desc + " hit info");
   is(hitResult.scrollId, expectedScrollId, desc + " scrollid");
 }
 
 // Symbolic constants used by hitTestScrollbar().
 var ScrollbarTrackLocation = {
     START: 1,
-    END: 2
+    END: 2,
 };
 var LayerState = {
     ACTIVE: 1,
-    INACTIVE: 2
+    INACTIVE: 2,
 };
 
 // Perform a hit test on the scrollbar(s) of a scroll frame.
 // This function takes a single argument which is expected to be
 // an object with the following fields:
 //   element: The scroll frame to perform the hit test on.
 //   directions: The direction(s) of scrollbars to test.
 //     If directions.vertical is true, the vertical scrollbar will be tested.
@@ -694,17 +700,17 @@ function hitTestScrollbar(params) {
 
   // Hit-test the targeted areas, assuming we don't have overlay scrollbars
   // with zero dimensions.
   if (params.directions.vertical && verticalScrollbarWidth > 0) {
     var verticalScrollbarPoint = {
         x: boundingClientRect.right - (verticalScrollbarWidth / 2),
         y: (params.trackLocation == ScrollbarTrackLocation.START)
              ? (boundingClientRect.y + scrollbarArrowButtonHeight + 5)
-             : (boundingClientRect.bottom - horizontalScrollbarHeight - scrollbarArrowButtonHeight - 5)
+             : (boundingClientRect.bottom - horizontalScrollbarHeight - scrollbarArrowButtonHeight - 5),
     };
     checkHitResult(hitTest(verticalScrollbarPoint),
                    expectedHitInfo | APZHitResultFlags.SCROLLBAR_VERTICAL,
                    params.expectedScrollId,
                    scrollframeMsg + " - vertical scrollbar");
   }
 
   if (params.directions.horizontal && horizontalScrollbarHeight > 0) {
@@ -749,28 +755,28 @@ function getPrefs(ident) {
     default:
       return [];
   }
 }
 
 var ApzCleanup = {
   _cleanups: [],
 
-  register: function(func) {
+  register(func) {
     if (this._cleanups.length == 0) {
       if (!window.isApzSubtest) {
         SimpleTest.registerCleanupFunction(this.execute.bind(this));
       } // else ApzCleanup.execute is called from runSubtestsSeriallyInFreshWindows
     }
     this._cleanups.push(func);
   },
 
-  execute: function() {
+  execute() {
     while (this._cleanups.length > 0) {
       var func = this._cleanups.pop();
       try {
         func();
       } catch (ex) {
         SimpleTest.ok(false, "Subtest cleanup function [" + func.toString() + "] threw exception [" + ex + "] on page [" + location.href + "]");
       }
     }
-  }
+  },
 };
--- a/gfx/layers/apz/test/mochitest/helper_basic_doubletap_zoom.html
+++ b/gfx/layers/apz/test/mochitest/helper_basic_doubletap_zoom.html
@@ -17,38 +17,38 @@ function* doubleTapOn(element, x, y, tes
   synthesizeNativeTap(element, x, y);
   synthesizeNativeTap(element, x, y);
 
   // Wait for the APZ:TransformEnd to fire
   yield true;
 
   // We get here once the APZ:TransformEnd has fired, so we don't need that
   // observer any more.
-  SpecialPowers.Services.obs.removeObserver(testDriver, "APZ:TransformEnd", false);
+  SpecialPowers.Services.obs.removeObserver(testDriver, "APZ:TransformEnd");
 
   // Flush state so we can query an accurate resolution
   yield flushApzRepaints(testDriver);
 }
 
 function* test(testDriver) {
   var resolution = getResolution();
   ok(resolution > 0,
-     'The initial_resolution is ' + resolution + ', which is some sane value');
+     "The initial_resolution is " + resolution + ", which is some sane value");
 
   // Check that double-tapping once zooms in
-  yield* doubleTapOn(document.getElementById('target'), 10, 10, testDriver);
+  yield* doubleTapOn(document.getElementById("target"), 10, 10, testDriver);
   var prev_resolution = resolution;
   resolution = getResolution();
-  ok(resolution > prev_resolution, 'The first double-tap has increased the resolution to ' + resolution);
+  ok(resolution > prev_resolution, "The first double-tap has increased the resolution to " + resolution);
 
   // Check that double-tapping again on the same spot zooms out
-  yield* doubleTapOn(document.getElementById('target'), 10, 10, testDriver);
+  yield* doubleTapOn(document.getElementById("target"), 10, 10, testDriver);
   prev_resolution = resolution;
   resolution = getResolution();
-  ok(resolution < prev_resolution, 'The second double-tap has decreased the resolution to ' + resolution);
+  ok(resolution < prev_resolution, "The second double-tap has decreased the resolution to " + resolution);
 }
 
 waitUntilApzStable()
 .then(runContinuation(test))
 .then(subtestDone);
 
   </script>
   <style type="text/css">
--- a/gfx/layers/apz/test/mochitest/helper_basic_pan.html
+++ b/gfx/layers/apz/test/mochitest/helper_basic_pan.html
@@ -26,17 +26,17 @@ function* test(testDriver) {
   synthesizeNativeTouchDrag(document.body, 10, 100, 0, -50);
   dump("Finished native drag, waiting for transform-end observer...\n");
 
   // Wait for the APZ:TransformEnd to be fired after touch events are processed.
   yield true;
 
   // We get here once the APZ:TransformEnd has fired, so we don't need that
   // observer any more.
-  SpecialPowers.Services.obs.removeObserver(testDriver, "APZ:TransformEnd", false);
+  SpecialPowers.Services.obs.removeObserver(testDriver, "APZ:TransformEnd");
 
   // Flush state.
   yield waitForApzFlushedRepaints(testDriver);
 
   is(window.scrollY, 50, "check that the window scrolled");
 
   // Check we've got the expected events.
   // This page is using "width=device-width; initial-scale=1.0" and we haven't
--- a/gfx/layers/apz/test/mochitest/helper_basic_zoom.html
+++ b/gfx/layers/apz/test/mochitest/helper_basic_zoom.html
@@ -20,17 +20,17 @@ function* test(testDriver) {
                                            { mozSystemGroup: true });
   let visScrEvtInternal = new EventCounter(window, "mozvisualscroll",
                                            { mozSystemGroup: true });
   let visResEvtContent = new EventCounter(window, "mozvisualresize");
   let visScrEvtContent = new EventCounter(window, "mozvisualscroll");
 
   var initial_resolution = getResolution();
   ok(initial_resolution > 0,
-      'The initial_resolution is ' + initial_resolution + ', which is some sane value');
+      "The initial_resolution is " + initial_resolution + ", which is some sane value");
 
   // This listener will trigger the test to continue once APZ is done with
   // processing the scroll.
   SpecialPowers.Services.obs.addObserver(testDriver, "APZ:TransformEnd");
 
   var zoom_in = [
       [ { x: 125, y: 250 }, { x: 175, y: 350 } ],
       [ { x: 120, y: 220 }, { x: 180, y: 380 } ],
@@ -43,22 +43,22 @@ function* test(testDriver) {
   var touchIds = [0, 1];
   yield* synthesizeNativeTouchSequences(document.body, zoom_in, null, touchIds);
 
   // Wait for the APZ:TransformEnd to be fired after touch events are processed.
   yield true;
 
   // We get here once the APZ:TransformEnd has fired, so we don't need that
   // observer any more.
-  SpecialPowers.Services.obs.removeObserver(testDriver, "APZ:TransformEnd", false);
+  SpecialPowers.Services.obs.removeObserver(testDriver, "APZ:TransformEnd");
 
   // Flush state and get the resolution we're at now
   yield waitForApzFlushedRepaints(testDriver);
   let final_resolution = getResolution();
-  ok(final_resolution > initial_resolution, 'The final resolution (' + final_resolution + ') is greater after zooming in');
+  ok(final_resolution > initial_resolution, "The final resolution (" + final_resolution + ") is greater after zooming in");
 
   // Check we've got the expected events.
   // Pinch-zooming the page should fire visual viewport resize events:
   visResEvt.unregister();
   ok(visResEvt.count > 0, "Got some visual viewport resize events");
   visResEvtInternal.unregister();
   ok(visResEvtInternal.count > 0, "Got some mozvisualresize events");
 
--- a/gfx/layers/apz/test/mochitest/helper_bug1151663.html
+++ b/gfx/layers/apz/test/mochitest/helper_bug1151663.html
@@ -14,17 +14,17 @@ https://bugzilla.mozilla.org/show_bug.cg
     // Infrastructure to get the test assertions to run at the right time.
     // -------------------------------------------------------------------
     var SimpleTest = window.opener.SimpleTest;
     var utils = SpecialPowers.getDOMWindowUtils(window);
 
     // --------------------------------------------------------------------
     // The actual logic for testing bug 1151663.
     //
-    // In this test we have a simple page which is scrollable, with a 
+    // In this test we have a simple page which is scrollable, with a
     // scrollable <div> which is also scrollable. We test that the
     // <div> does not get an initial APZC, since primary scrollable
     // frame is the page's root scroll frame.
     // --------------------------------------------------------------------
 
     function testBug1151663() {
       // Get the compositor-side test data from nsIDOMWindowUtils.
       var compositorTestData = utils.getCompositorAPZTestData();
--- a/gfx/layers/apz/test/mochitest/helper_bug1162771.html
+++ b/gfx/layers/apz/test/mochitest/helper_bug1162771.html
@@ -5,54 +5,54 @@
   <meta name="viewport" content="width=device-width; initial-scale=1.0">
   <title>Test for touchend on media elements</title>
   <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
   <script type="application/javascript" src="apz_test_utils.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
   <script type="application/javascript">
 
 function* test(testDriver) {
-  var v = document.getElementById('video');
-  var a = document.getElementById('audio');
-  var d = document.getElementById('div');
+  var v = document.getElementById("video");
+  var a = document.getElementById("audio");
+  var d = document.getElementById("div");
 
   document.body.ontouchstart = function(e) {
     if (e.target === v || e.target === a || e.target === d) {
-      e.target.style.display = 'none';
-      ok(true, 'Set display to none on #' + e.target.id);
+      e.target.style.display = "none";
+      ok(true, "Set display to none on #" + e.target.id);
     } else {
-      ok(false, 'Got unexpected touchstart on ' + e.target);
+      ok(false, "Got unexpected touchstart on " + e.target);
     }
     waitForAllPaints(testDriver);
   };
 
   document.body.ontouchend = function(e) {
     if (e.target === v || e.target === a || e.target === d) {
       e.target._gotTouchend = true;
-      ok(true, 'Got touchend event on #' + e.target.id);
+      ok(true, "Got touchend event on #" + e.target.id);
     }
     testDriver();
   };
 
   var utils = SpecialPowers.getDOMWindowUtils(window);
 
   var pt = coordinatesRelativeToScreen(25, 5, v);
   yield utils.sendNativeTouchPoint(0, SpecialPowers.DOMWindowUtils.TOUCH_CONTACT, pt.x, pt.y, 1, 90, null);
   yield utils.sendNativeTouchPoint(0, SpecialPowers.DOMWindowUtils.TOUCH_REMOVE, pt.x, pt.y, 1, 90, null);
-  ok(v._gotTouchend, 'Touchend was received on video element');
+  ok(v._gotTouchend, "Touchend was received on video element");
 
   pt = coordinatesRelativeToScreen(25, 5, a);
   yield utils.sendNativeTouchPoint(0, SpecialPowers.DOMWindowUtils.TOUCH_CONTACT, pt.x, pt.y, 1, 90, null);
   yield utils.sendNativeTouchPoint(0, SpecialPowers.DOMWindowUtils.TOUCH_REMOVE, pt.x, pt.y, 1, 90, null);
-  ok(a._gotTouchend, 'Touchend was received on audio element');
+  ok(a._gotTouchend, "Touchend was received on audio element");
 
   pt = coordinatesRelativeToScreen(25, 5, d);
   yield utils.sendNativeTouchPoint(0, SpecialPowers.DOMWindowUtils.TOUCH_CONTACT, pt.x, pt.y, 1, 90, null);
   yield utils.sendNativeTouchPoint(0, SpecialPowers.DOMWindowUtils.TOUCH_REMOVE, pt.x, pt.y, 1, 90, null);
-  ok(d._gotTouchend, 'Touchend was received on div element');
+  ok(d._gotTouchend, "Touchend was received on div element");
 }
 
 waitUntilApzStable()
 .then(runContinuation(test))
 .then(subtestDone);
 
   </script>
   <style>
--- a/gfx/layers/apz/test/mochitest/helper_bug1271432.html
+++ b/gfx/layers/apz/test/mochitest/helper_bug1271432.html
@@ -1,16 +1,16 @@
 <head>
   <title>Ensure that the hit region doesn't get unexpectedly expanded</title>
   <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
   <script type="application/javascript" src="apz_test_utils.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
 <script type="application/javascript">
 function* test(testDriver) {
-  var scroller = document.getElementById('scroller');
+  var scroller = document.getElementById("scroller");
   var scrollerPos = scroller.scrollTop;
   var dx = 100, dy = 50;
 
   is(window.scrollY, 0, "Initial page scroll position should be 0");
   is(scrollerPos, 0, "Initial scroller position should be 0");
 
   yield moveMouseAndScrollWheelOver(scroller, dx, dy, testDriver);
 
--- a/gfx/layers/apz/test/mochitest/helper_bug1280013.html
+++ b/gfx/layers/apz/test/mochitest/helper_bug1280013.html
@@ -33,36 +33,36 @@ function* test(testDriver) {
   // However, because of the overflow:hidden on the root elements, all this
   // scrolling is happening in APZ and is not reflected in the main-thread
   // scroll position (it is stored in the callback transform instead). We check
   // this by checking the scroll offset.
   yield flushApzRepaints(testDriver);
   is(window.scrollY, 0, "Main-thread scroll position is still at 0");
 
   // Scroll the iframe by 300px.
-  var subframe = document.getElementById('subframe');
+  var subframe = document.getElementById("subframe");
   yield synthesizeNativeTouchDrag(subframe, 10, 200, 0, -300);
 
   // Remove the observer, we don't need it any more.
-  SpecialPowers.Services.obs.removeObserver(testDriver, "APZ:TransformEnd", false);
+  SpecialPowers.Services.obs.removeObserver(testDriver, "APZ:TransformEnd");
 
   // Flush any pending paints
   yield flushApzRepaints(testDriver);
 
   // get the displayport for the subframe
   var utils = SpecialPowers.getDOMWindowUtils(window);
   var contentPaints = utils.getContentAPZTestData().paints;
   var lastPaint = convertScrollFrameData(getLastNonemptyBucket(contentPaints).scrollFrames);
   var foundIt = 0;
   for (var scrollId in lastPaint) {
-    if (('contentDescription' in lastPaint[scrollId]) &&
-        (lastPaint[scrollId]['contentDescription'].includes('tall_html'))) {
-      var dp = getPropertyAsRect(lastPaint, scrollId, 'displayport');
-      ok(dp.y <= 0, 'The displayport top should be less than or equal to zero to cover the visible part of the subframe; it is ' + dp.y);
-      ok(dp.y + dp.h >= subframe.clientHeight, 'The displayport bottom should be greater than the clientHeight; it is ' + (dp.y + dp.h));
+    if (("contentDescription" in lastPaint[scrollId]) &&
+        (lastPaint[scrollId].contentDescription.includes("tall_html"))) {
+      var dp = getPropertyAsRect(lastPaint, scrollId, "displayport");
+      ok(dp.y <= 0, "The displayport top should be less than or equal to zero to cover the visible part of the subframe; it is " + dp.y);
+      ok(dp.y + dp.h >= subframe.clientHeight, "The displayport bottom should be greater than the clientHeight; it is " + (dp.y + dp.h));
       foundIt++;
     }
   }
   is(foundIt, 1, "Found exactly one displayport for the subframe we were interested in.");
 }
 
 waitUntilApzStable()
 .then(runContinuation(test))
--- a/gfx/layers/apz/test/mochitest/helper_bug1285070.html
+++ b/gfx/layers/apz/test/mochitest/helper_bug1285070.html
@@ -12,31 +12,31 @@
       let eventsList = ["pointerover", "pointerenter", "pointerdown",
                         "pointerup", "pointerleave", "pointerout",
                         "mousedown", "mouseup",
                         "touchstart", "touchend", "click"];
       let eventsCount = {};
 
       eventsList.forEach((eventName) => {
         eventsCount[eventName] = 0;
-        document.getElementById('div1').addEventListener(eventName, (event) => {
+        document.getElementById("div1").addEventListener(eventName, (event) => {
           ++eventsCount[event.type];
           ok(true, "Received event " + event.type);
         });
       });
 
       document.addEventListener("click", (event) => {
-        is(event.target, document.getElementById('div1'), "Clicked on div (at " + event.clientX + "," + event.clientY + ")");
+        is(event.target, document.getElementById("div1"), "Clicked on div (at " + event.clientX + "," + event.clientY + ")");
         for (var key in eventsCount) {
           is(eventsCount[key], 1, "Event " + key + " should be generated once");
         }
         subtestDone();
       });
 
-      synthesizeNativeTap(document.getElementById('div1'), 100, 100);
+      synthesizeNativeTap(document.getElementById("div1"), 100, 100);
     }
 
     waitUntilApzStable().then(test);
 
   </script>
 </head>
 <body>
   <div id="div1" style="width: 200px; height: 200px; background: black"></div>
--- a/gfx/layers/apz/test/mochitest/helper_bug1299195.html
+++ b/gfx/layers/apz/test/mochitest/helper_bug1299195.html
@@ -30,18 +30,18 @@
         ++mousedown_count;
       });
       target0.addEventListener("pointerup", () => {
         ++pointerup_count;
       });
       target0.addEventListener("pointerdown", () => {
         ++pointerdown_count;
       });
-      synthesizeNativeTap(document.getElementById('target0'), 100, 100);
-      synthesizeNativeTap(document.getElementById('target0'), 100, 100);
+      synthesizeNativeTap(document.getElementById("target0"), 100, 100);
+      synthesizeNativeTap(document.getElementById("target0"), 100, 100);
     }
     waitUntilApzStable().then(runTests);
     </script>
 </head>
 <body>
   <div id="target0" style="width: 200px; height: 200px; background: green"></div>
 </body>
 </html>
--- a/gfx/layers/apz/test/mochitest/helper_bug1326290.html
+++ b/gfx/layers/apz/test/mochitest/helper_bug1326290.html
@@ -16,18 +16,18 @@
     .content {
       width: 1000px;
       height: 2000px;
     }
   </style>
   <script type="text/javascript">
 
 function* test(testDriver) {
-  var scrollableDiv = document.getElementById('scrollable');
-  scrollableDiv.addEventListener('scroll', () => setTimeout(testDriver, 0), {once: true});
+  var scrollableDiv = document.getElementById("scrollable");
+  scrollableDiv.addEventListener("scroll", () => setTimeout(testDriver, 0), {once: true});
 
   var dragFinisher = yield* dragVerticalScrollbar(scrollableDiv, testDriver);
   if (!dragFinisher) {
     ok(true, "No scrollbar, can't do this test");
     return;
   }
 
   // the events above might be stuck in APZ input queue for a bit until the
--- a/gfx/layers/apz/test/mochitest/helper_bug1331693.html
+++ b/gfx/layers/apz/test/mochitest/helper_bug1331693.html
@@ -5,18 +5,18 @@
   <meta name="viewport" content="width=device-width; initial-scale=1.0">
   <title>Dragging the mouse on a scrollframe inside an SVGEffects</title>
   <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
   <script type="application/javascript" src="apz_test_utils.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
   <script type="text/javascript">
 
 function* test(testDriver) {
-  var scrollableDiv = document.getElementById('scrollable');
-  scrollableDiv.addEventListener('scroll', () => setTimeout(testDriver, 0), {once: true});
+  var scrollableDiv = document.getElementById("scrollable");
+  scrollableDiv.addEventListener("scroll", () => setTimeout(testDriver, 0), {once: true});
 
   var dragFinisher = yield* dragVerticalScrollbar(scrollableDiv, testDriver);
   if (!dragFinisher) {
     ok(true, "No scrollbar, can't do this test");
     return;
   }
 
   // the events above might be stuck in APZ input queue for a bit until the
--- a/gfx/layers/apz/test/mochitest/helper_bug1346632.html
+++ b/gfx/layers/apz/test/mochitest/helper_bug1346632.html
@@ -23,17 +23,17 @@
     #fixed-content {
       height: 2000px;
     }
   </style>
   <script type="text/javascript">
 function* test(testDriver) {
   var root = document.scrollingElement;
   var scrollPos = root.scrollTop;
-  document.addEventListener('scroll', () => {
+  document.addEventListener("scroll", () => {
     ok(root.scrollTop > scrollPos, "document scrolled after dragging scrollbar");
     setTimeout(testDriver, 0);
   }, {once: true});
 
   var scrollbarX = (window.innerWidth + root.clientWidth) / 2;
   // Move the mouse to the scrollbar
   yield synthesizeNativeMouseEvent(root, scrollbarX, 100, nativeMouseMoveEventMsg(), testDriver);
   // mouse down
--- a/gfx/layers/apz/test/mochitest/helper_bug1462961.html
+++ b/gfx/layers/apz/test/mochitest/helper_bug1462961.html
@@ -5,18 +5,18 @@
   <meta name="viewport" content="width=device-width; initial-scale=1.0">
   <title>Dragging the mouse on a transformed scrollframe inside a fixed-pos element</title>
   <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
   <script type="application/javascript" src="apz_test_utils.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
   <script type="text/javascript">
 
 function* test(testDriver) {
-  var scrollableDiv = document.getElementById('scrollable');
-  scrollableDiv.addEventListener('scroll', () => setTimeout(testDriver, 0), {once: true});
+  var scrollableDiv = document.getElementById("scrollable");
+  scrollableDiv.addEventListener("scroll", () => setTimeout(testDriver, 0), {once: true});
 
   // Scroll down a small amount (10px). The bug in this case is that the
   // scrollthumb remains a little "above" where it's supposed to be, so if the
   // bug manifests here, then the thumb will remain at the top of the track
   // and the scroll position will remain at 0.
   var dragFinisher = yield* dragVerticalScrollbar(scrollableDiv, testDriver, 10, 10);
   if (!dragFinisher) {
     ok(true, "No scrollbar, can't do this test");
--- a/gfx/layers/apz/test/mochitest/helper_bug1464568_opacity.html
+++ b/gfx/layers/apz/test/mochitest/helper_bug1464568_opacity.html
@@ -23,17 +23,17 @@
   This height should be smaller than window height, otherwise the animation
   followed by this element will be out of view, thus the animation doesn't run
   on the compositor.
   -->
  <div style="height: 500px"></div>
  <div id="anim"></div>
 </body>
 <script>
-'use strict';
+"use strict";
 
 const utils = SpecialPowers.getDOMWindowUtils(window);
 
 async function test_opacity() {
   utils.setDisplayPortForElement(0, 0, 300, 1000, document.documentElement, 1);
   await promiseAllPaintsDone();
   let dpr = window.devicePixelRatio;
 
@@ -45,17 +45,17 @@ async function test_opacity() {
 
   await new Promise(resolve => waitForApzFlushedRepaints(resolve));
 
   transform = parseTransform(utils.getOMTCTransform(anim));
   isTransformClose(transform, [1, 0, 0, 1, 0, -300 * dpr],
      "Element should have been moved by the offset");
 }
 
-if (utils.layerManagerType == 'WebRender') {
+if (utils.layerManagerType == "WebRender") {
   ok(true, "This test doesn't need to run on WebRender");
   subtestDone();
 } else {
   waitUntilApzStable().then(test_opacity).then(subtestDone);
 }
 
 </script>
 </html>
--- a/gfx/layers/apz/test/mochitest/helper_bug1464568_transform.html
+++ b/gfx/layers/apz/test/mochitest/helper_bug1464568_transform.html
@@ -23,17 +23,17 @@
   This height should be smaller than window height, otherwise the animation
   followed by this element will be out of view, thus the animation doesn't run
   on the compositor.
   -->
  <div style="height: 500px"></div>
  <div id="anim"></div>
 </body>
 <script>
-'use strict';
+"use strict";
 
 const utils = SpecialPowers.getDOMWindowUtils(window);
 
 async function test_transform() {
   utils.setDisplayPortForElement(0, 0, 300, 1000, document.documentElement, 1);
   await promiseAllPaintsDone();
 
   let dpr = window.devicePixelRatio;
@@ -45,17 +45,17 @@ async function test_transform() {
 
   await new Promise(resolve => waitForApzFlushedRepaints(resolve));
 
   transform = parseTransform(utils.getOMTCTransform(anim));
   isTransformClose(transform, [1, 0, 0, 1, 200 * dpr, -300 * dpr],
      "Element should have been moved by the offset");
 }
 
-if (utils.layerManagerType == 'WebRender') {
+if (utils.layerManagerType == "WebRender") {
   ok(true, "This test doesn't need to run on WebRender");
   subtestDone();
 } else {
   waitUntilApzStable().then(test_transform).then(subtestDone);
 }
 
 </script>
 </html>
--- a/gfx/layers/apz/test/mochitest/helper_bug1473108.html
+++ b/gfx/layers/apz/test/mochitest/helper_bug1473108.html
@@ -33,17 +33,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 <body>
   <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1473108">Mozilla Bug 1473108</a>
   <a class="a" id="event"><span id="target"></span></a>
 
   <script type="application/javascript">
 
   waitUntilApzStable().then(() => {
     let target = document.getElementById("target");
-    target.addEventListener('click', function(e) {
+    target.addEventListener("click", function(e) {
       is(e.target, target, `Clicked on at (${e.clientX}, ${e.clientY})`);
       subtestDone();
     });
     synthesizeNativeTap(target, 5, 5);
   });
 
 </script>
 </body>
--- a/gfx/layers/apz/test/mochitest/helper_bug1490393-2.html
+++ b/gfx/layers/apz/test/mochitest/helper_bug1490393-2.html
@@ -5,18 +5,18 @@
   <meta name="viewport" content="width=device-width; initial-scale=1.0">
   <title>Dragging the mouse on a scrollbar for a scrollframe inside nested transforms</title>
   <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
   <script type="application/javascript" src="apz_test_utils.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
   <script type="text/javascript">
 
 function* test(testDriver) {
-  var scrollableDiv = document.getElementById('scrollable');
-  scrollableDiv.addEventListener('scroll', () => setTimeout(testDriver, 0), {once: true});
+  var scrollableDiv = document.getElementById("scrollable");
+  scrollableDiv.addEventListener("scroll", () => setTimeout(testDriver, 0), {once: true});
 
   // Scroll down a small amount (10px). The bug in this case is that the
   // scrollthumb "jumps" by an additional 40 pixels (height of the "gap" div)
   // and the scrollframe scrolls by a corresponding amount. So after doing this
   // drag we check the scroll position to make sure it hasn't scrolled by
   // too much.
   // Given the scrollable height of 2000px and scrollframe height of 400px,
   // the scrollthumb should be approximately 80px tall, and dragging it 10px
--- a/gfx/layers/apz/test/mochitest/helper_bug1490393.html
+++ b/gfx/layers/apz/test/mochitest/helper_bug1490393.html
@@ -5,18 +5,18 @@
   <meta name="viewport" content="width=device-width; initial-scale=1.0">
   <title>Dragging the mouse on a scrollbar for a scrollframe inside nested transforms</title>
   <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
   <script type="application/javascript" src="apz_test_utils.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
   <script type="text/javascript">
 
 function* test(testDriver) {
-  var scrollableDiv = document.getElementById('scrollable');
-  scrollableDiv.addEventListener('scroll', () => setTimeout(testDriver, 0), {once: true});
+  var scrollableDiv = document.getElementById("scrollable");
+  scrollableDiv.addEventListener("scroll", () => setTimeout(testDriver, 0), {once: true});
 
   // Scroll down a small amount (10px). The bug in this case is that the
   // scrollthumb "jumps" by an additional 40 pixels (height of the "gap" div)
   // and the scrollframe scrolls by a corresponding amount. So after doing this
   // drag we check the scroll position to make sure it hasn't scrolled by
   // too much.
   // Given the scrollable height of 2000px and scrollframe height of 400px,
   // the scrollthumb should be approximately 80px tall, and dragging it 10px
--- a/gfx/layers/apz/test/mochitest/helper_bug1502010_unconsumed_pan.html
+++ b/gfx/layers/apz/test/mochitest/helper_bug1502010_unconsumed_pan.html
@@ -10,47 +10,47 @@
   <script type="application/javascript">
     var pointerMoveCount = 0;
     var lastPointerCoord = -1;
     var apzFlushed = false;
     var endEventReceived = false;
 
     function checkForTestEnd() {
         if (apzFlushed && endEventReceived) {
-            var target = document.getElementById('carousel');
-            target.removeEventListener('pointermove', moveListener);
+            var target = document.getElementById("carousel");
+            target.removeEventListener("pointermove", moveListener);
 
             ok(pointerMoveCount > 0, "Got " + pointerMoveCount + " pointermove events");
             is(document.scrollingElement.scrollTop, 0, "Document didn't y-scroll");
             is(document.scrollingElement.scrollLeft, 0, "Document didn't x-scroll");
 
             subtestDone();
         }
     }
 
     function moveListener(event) {
         ok(event.clientX >= lastPointerCoord, "Got nondecreasing pointermove to " + event.clientX + "," + event.clientY);
         lastPointerCoord = event.clientX;
         pointerMoveCount++;
     }
 
     function* test(testDriver) {
-        var target = document.getElementById('carousel');
-        target.addEventListener('pointercancel', (event) => {
+        var target = document.getElementById("carousel");
+        target.addEventListener("pointercancel", (event) => {
             ok(false, "Received pointercancel, uh-oh!");
             endEventReceived = true;
             setTimeout(checkForTestEnd, 0);
         }, {once: true});
-        target.addEventListener('pointerup', () => {
+        target.addEventListener("pointerup", () => {
             ok(true, "Received pointerup");
             endEventReceived = true;
             setTimeout(checkForTestEnd, 0);
         }, {once: true});
 
-        target.addEventListener('pointermove', moveListener);
+        target.addEventListener("pointermove", moveListener);
 
         // Drag mostly horizontally but also slightly vertically. If the
         // touch-action were not respected due to a bug this might result
         // in vertical scrolling instead of pointermove events.
         yield synthesizeNativeTouchDrag(target, 10, 10, 200, -10, testDriver);
         yield flushApzRepaints(testDriver);
         apzFlushed = true;
 
--- a/gfx/layers/apz/test/mochitest/helper_bug982141.html
+++ b/gfx/layers/apz/test/mochitest/helper_bug982141.html
@@ -55,18 +55,18 @@ https://bugzilla.mozilla.org/show_bug.cg
       SimpleTest.is(rcd.children.length, 1, "expected a single child APZC");
       var childScrollId = rcd.children[0].scrollId;
 
       // We should have content-side data for the same paint.
       SimpleTest.ok(lastCompositorPaintSeqNo in contentTestData.paints,
                     "expected a content paint with sequence number" + lastCompositorPaintSeqNo);
       var correspondingContentPaint = contentTestData.paints[lastCompositorPaintSeqNo];
 
-      var dp = getPropertyAsRect(correspondingContentPaint, childScrollId, 'displayport');
-      var subframe = document.getElementById('subframe');
+      var dp = getPropertyAsRect(correspondingContentPaint, childScrollId, "displayport");
+      var subframe = document.getElementById("subframe");
       // The clientWidth and clientHeight may be less than 50 if there are scrollbars showing.
       // In general they will be (50 - <scrollbarwidth>, 50 - <scrollbarheight>).
       SimpleTest.ok(subframe.clientWidth > 0, "Expected a non-zero clientWidth, got: " + subframe.clientWidth);
       SimpleTest.ok(subframe.clientHeight > 0, "Expected a non-zero clientHeight, got: " + subframe.clientHeight);
       SimpleTest.ok(dp.w >= subframe.clientWidth && dp.h >= subframe.clientHeight,
                     "expected a displayport at least as large as the scrollable element, got " + JSON.stringify(dp));
 
       window.opener.finishTest();
--- a/gfx/layers/apz/test/mochitest/helper_click.html
+++ b/gfx/layers/apz/test/mochitest/helper_click.html
@@ -5,33 +5,33 @@
   <meta name="viewport" content="width=device-width; initial-scale=1.0">
   <title>Sanity mouse-clicking test</title>
   <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
   <script type="application/javascript" src="apz_test_utils.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
   <script type="application/javascript">
 
 function* clickButton(testDriver) {
-  document.addEventListener('click', clicked);
+  document.addEventListener("click", clicked);
 
-  if (getQueryArgs()['dtc']) {
+  if (getQueryArgs().dtc) {
     // force a dispatch-to-content region on the document
-    document.addEventListener('wheel', function() { /* no-op */ }, { passive: false });
+    document.addEventListener("wheel", function() { /* no-op */ }, { passive: false });
     yield waitForAllPaints(function() {
       flushApzRepaints(testDriver);
     });
   }
 
-  synthesizeNativeClick(document.getElementById('b'), 5, 5, function() {
+  synthesizeNativeClick(document.getElementById("b"), 5, 5, function() {
     dump("Finished synthesizing click, waiting for button to be clicked...\n");
   });
 }
 
 function clicked(e) {
-  is(e.target, document.getElementById('b'), "Clicked on button, yay! (at " + e.clientX + "," + e.clientY + ")");
+  is(e.target, document.getElementById("b"), "Clicked on button, yay! (at " + e.clientX + "," + e.clientY + ")");
   subtestDone();
 }
 
 waitUntilApzStable()
 .then(runContinuation(clickButton));
 
   </script>
 </head>
--- a/gfx/layers/apz/test/mochitest/helper_div_pan.html
+++ b/gfx/layers/apz/test/mochitest/helper_div_pan.html
@@ -6,28 +6,28 @@
   <title>Sanity panning test for scrollable div</title>
   <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
   <script type="application/javascript" src="apz_test_utils.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
   <script type="application/javascript">
 
 function scrollOuter() {
   var transformEnd = function() {
-    SpecialPowers.Services.obs.removeObserver(transformEnd, "APZ:TransformEnd", false);
+    SpecialPowers.Services.obs.removeObserver(transformEnd, "APZ:TransformEnd");
     dump("Transform complete; flushing repaints...\n");
     flushApzRepaints(checkScroll);
   };
   SpecialPowers.Services.obs.addObserver(transformEnd, "APZ:TransformEnd");
 
-  synthesizeNativeTouchDrag(document.getElementById('outer'), 10, 100, 0, -50);
+  synthesizeNativeTouchDrag(document.getElementById("outer"), 10, 100, 0, -50);
   dump("Finished native drag, waiting for transform-end observer...\n");
 }
 
 function checkScroll() {
-  var outerScroll = document.getElementById('outer').scrollTop;
+  var outerScroll = document.getElementById("outer").scrollTop;
   is(outerScroll, 50, "check that the div scrolled");
   subtestDone();
 }
 
 waitUntilApzStable().then(scrollOuter);
 
   </script>
 </head>
--- a/gfx/layers/apz/test/mochitest/helper_drag_click.html
+++ b/gfx/layers/apz/test/mochitest/helper_drag_click.html
@@ -5,35 +5,35 @@
   <meta name="viewport" content="width=device-width; initial-scale=1.0">
   <title>Sanity mouse-drag click test</title>
   <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
   <script type="application/javascript" src="apz_test_utils.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
   <script type="application/javascript">
 
 function* test(testDriver) {
-  document.addEventListener('click', clicked);
+  document.addEventListener("click", clicked);
 
   // Ensure the pointer is inside the window
-  yield synthesizeNativeMouseEvent(document.getElementById('b'), 5, 5, nativeMouseMoveEventMsg(), testDriver);
+  yield synthesizeNativeMouseEvent(document.getElementById("b"), 5, 5, nativeMouseMoveEventMsg(), testDriver);
   // mouse down, move it around, and release it near where it went down. this
   // should generate a click at the release point
-  yield synthesizeNativeMouseEvent(document.getElementById('b'), 5, 5, nativeMouseDownEventMsg(), testDriver);
-  yield synthesizeNativeMouseEvent(document.getElementById('b'), 100, 100, nativeMouseMoveEventMsg(), testDriver);
-  yield synthesizeNativeMouseEvent(document.getElementById('b'), 10, 10, nativeMouseMoveEventMsg(), testDriver);
-  yield synthesizeNativeMouseEvent(document.getElementById('b'), 8, 8, nativeMouseUpEventMsg(), testDriver);
+  yield synthesizeNativeMouseEvent(document.getElementById("b"), 5, 5, nativeMouseDownEventMsg(), testDriver);
+  yield synthesizeNativeMouseEvent(document.getElementById("b"), 100, 100, nativeMouseMoveEventMsg(), testDriver);
+  yield synthesizeNativeMouseEvent(document.getElementById("b"), 10, 10, nativeMouseMoveEventMsg(), testDriver);
+  yield synthesizeNativeMouseEvent(document.getElementById("b"), 8, 8, nativeMouseUpEventMsg(), testDriver);
   dump("Finished synthesizing click with a drag in the middle\n");
 }
 
 function clicked(e) {
   // The mouse down at (5, 5) should not have generated a click, but the up
   // at (8, 8) should have.
-  is(e.target, document.getElementById('b'), "Clicked on button, yay! (at " + e.clientX + "," + e.clientY + ")");
-  is(e.clientX, 8 + Math.floor(document.getElementById('b').getBoundingClientRect().left), 'x-coord of click event looks sane');
-  is(e.clientY, 8 + Math.floor(document.getElementById('b').getBoundingClientRect().top), 'y-coord of click event looks sane');
+  is(e.target, document.getElementById("b"), "Clicked on button, yay! (at " + e.clientX + "," + e.clientY + ")");
+  is(e.clientX, 8 + Math.floor(document.getElementById("b").getBoundingClientRect().left), "x-coord of click event looks sane");
+  is(e.clientY, 8 + Math.floor(document.getElementById("b").getBoundingClientRect().top), "y-coord of click event looks sane");
   subtestDone();
 }
 
 waitUntilApzStable()
 .then(runContinuation(test));
 
   </script>
 </head>
--- a/gfx/layers/apz/test/mochitest/helper_drag_scroll.html
+++ b/gfx/layers/apz/test/mochitest/helper_drag_scroll.html
@@ -36,37 +36,37 @@ function moveTo(mouseY, testDriver) {
   document.scrollingElement.scrollTop = (oldScrollPos + newScrollPos) / 2;
   waitForAllPaints(function() {
     document.scrollingElement.scrollTop = newScrollPos;
     testDriver();
   });
 }
 
 function setupDragging(testDriver) {
-  bar = document.getElementById('scrollbar');
+  bar = document.getElementById("scrollbar");
   mouseDown = false;
 
-  bar.addEventListener('mousedown', function(e) {
+  bar.addEventListener("mousedown", function(e) {
     mouseDown = true;
     moveTo(e.clientY, testDriver);
   }, true);
 
-  bar.addEventListener('mousemove', function(e) {
+  bar.addEventListener("mousemove", function(e) {
     if (mouseDown) {
       dump("Got mousemove clientY " + e.clientY + "\n");
       moveTo(e.clientY, testDriver);
       e.stopPropagation();
     }
   }, true);
 
-  bar.addEventListener('mouseup', function(e) {
+  bar.addEventListener("mouseup", function(e) {
     mouseDown = false;
   }, true);
 
-  window.addEventListener('mousemove', function(e) {
+  window.addEventListener("mousemove", function(e) {
     if (mouseDown) {
       ok(false, "The mousemove at " + e.clientY + " was not stopped by the bar listener, and is a glitchy event!");
       setTimeout(testDriver, 0);
     }
   });
 }
 
 function* test(testDriver) {
--- a/gfx/layers/apz/test/mochitest/helper_fixed_position_scroll_hittest.html
+++ b/gfx/layers/apz/test/mochitest/helper_fixed_position_scroll_hittest.html
@@ -27,26 +27,26 @@
 </head>
 <body>
   <div id="fixed"><input type="button" value="Button" /></div>
   <script>
     const input = document.querySelector("input");
     function* test(testDriver) {
       SpecialPowers.Services.obs.addObserver(testDriver, "APZ:TransformEnd");
       yield synthesizeNativeTouchDrag(document.body, 10, 10, -2000, 0);
-      SpecialPowers.Services.obs.removeObserver(testDriver, "APZ:TransformEnd", false);
+      SpecialPowers.Services.obs.removeObserver(testDriver, "APZ:TransformEnd");
 
       yield waitForApzFlushedRepaints(testDriver);
 
       // TODO: We're unsure why, but adding this observer substantially
       // decreases the rate of intermittents that we see. We should figure out
       // why and/or rewrite this test entirely.
       SpecialPowers.Services.obs.addObserver(testDriver, "mouseevent");
       yield synthesizeNativeClick(input, 10, 10, testDriver);
-      SpecialPowers.Services.obs.removeObserver(testDriver, "mouseevent", false);
+      SpecialPowers.Services.obs.removeObserver(testDriver, "mouseevent");
     }
     window.addEventListener("click", (e) => {
       is(e.target, input, "got click");
       subtestDone();
     });
     waitUntilApzStable().then(runContinuation(test));
   </script>
 </body>
--- a/gfx/layers/apz/test/mochitest/helper_hittest_backface_hidden.html
+++ b/gfx/layers/apz/test/mochitest/helper_hittest_backface_hidden.html
@@ -38,27 +38,27 @@
     <div id="content"></div>
   </div>
   <div id="back"></div></body>
 <script type="application/javascript">
 
 function* test(testDriver) {
   var config = getHitTestConfig();
 
-  var subframe = document.getElementById('front');
+  var subframe = document.getElementById("front");
 
   // Set a displayport to ensure the subframe is layerized.
   // This is not required for exercising the behavior we want to test,
   // but it's needed to be able to assert the results reliably.
   config.utils.setDisplayPortForElement(0, 0, 1000, 1000, subframe, 1);
   yield waitForApzFlushedRepaints(testDriver);
 
   var subframeViewId = config.utils.getViewId(subframe);
 
-  var {hitInfo, scrollId} = hitTest(centerOf(subframe));
+  var {scrollId} = hitTest(centerOf(subframe));
 
   is(scrollId, subframeViewId,
      "hit the scroll frame behind the backface-visibility:hidden element");
 
   subtestDone();
 }
 
 waitUntilApzStable().then(runContinuation(test));
--- a/gfx/layers/apz/test/mochitest/helper_hittest_basic.html
+++ b/gfx/layers/apz/test/mochitest/helper_hittest_basic.html
@@ -16,18 +16,18 @@
  <div id="make_root_scrollable" style="height: 5000px"></div>
 </body>
 <script type="application/javascript">
 
 function* test(testDriver) {
   var config = getHitTestConfig();
   var utils = config.utils;
 
-  var scroller = document.getElementById('scroller');
-  var apzaware = document.getElementById('apzaware');
+  var scroller = document.getElementById("scroller");
+  var apzaware = document.getElementById("apzaware");
 
   checkHitResult(hitTest(centerOf(scroller)),
                  APZHitResultFlags.VISIBLE | APZHitResultFlags.DISPATCH_TO_CONTENT,
                  utils.getViewId(document.scrollingElement),
                  "inactive scrollframe");
 
   // The apz-aware div (which has a non-passive wheel listener) is not visible
   // and so the hit-test should just return the root scrollframe area that's
@@ -39,17 +39,17 @@ function* test(testDriver) {
 
   // Hit test where the scroll thumbs should be.
   hitTestScrollbar({
     element: scroller,
     directions: { vertical: true, horizontal: true },
     expectedScrollId: utils.getViewId(document.scrollingElement),
     trackLocation: ScrollbarTrackLocation.START,
     expectThumb: true,
-    layerState: LayerState.INACTIVE
+    layerState: LayerState.INACTIVE,
   });
 
   // activate the scrollframe but keep the main-thread scroll position at 0.
   // also apply a async scroll offset in the y-direction such that the
   // scrollframe scrolls to the bottom of its range.
   utils.setDisplayPortForElement(0, 0, 500, 500, scroller, 1);
   yield waitForApzFlushedRepaints(testDriver);
   var scrollY = scroller.scrollTopMax;
@@ -84,44 +84,44 @@ function* test(testDriver) {
 
   // top of scrollbar track
   hitTestScrollbar({
     element: scroller,
     directions: { vertical: true },
     expectedScrollId: scrollerViewId,
     trackLocation: ScrollbarTrackLocation.START,
     expectThumb: false,
-    layerState: LayerState.ACTIVE
+    layerState: LayerState.ACTIVE,
   });
   // bottom of scrollbar track (scrollthumb)
   hitTestScrollbar({
     element: scroller,
     directions: { vertical: true },
     expectedScrollId: scrollerViewId,
     trackLocation: ScrollbarTrackLocation.END,
     expectThumb: true,
-    layerState: LayerState.ACTIVE
+    layerState: LayerState.ACTIVE,
   });
   // left part of scrollbar track (has scrollthumb)
   hitTestScrollbar({
     element: scroller,
     directions: { horizontal: true },
     expectedScrollId: scrollerViewId,
     trackLocation: ScrollbarTrackLocation.START,
     expectThumb: true,
-    layerState: LayerState.ACTIVE
+    layerState: LayerState.ACTIVE,
   });
   // right part of scrollbar track
   hitTestScrollbar({
     element: scroller,
     directions: { horizontal: true },
     expectedScrollId: scrollerViewId,
     trackLocation: ScrollbarTrackLocation.END,
     expectThumb: false,
-    layerState: LayerState.ACTIVE
+    layerState: LayerState.ACTIVE,
   });
 
   subtestDone();
 }
 
 waitUntilApzStable().then(runContinuation(test));
 
 </script>
--- a/gfx/layers/apz/test/mochitest/helper_hittest_checkerboard.html
+++ b/gfx/layers/apz/test/mochitest/helper_hittest_checkerboard.html
@@ -16,17 +16,17 @@
  <div id="make_root_scrollable" style="height: 5000px"></div>
 </body>
 <script type="application/javascript">
 
 function* test(testDriver) {
   var config = getHitTestConfig();
   var utils = config.utils;
 
-  var scroller = document.getElementById('scroller');
+  var scroller = document.getElementById("scroller");
 
   // Activate the scrollframe but keep the main-thread scroll position at 0.
   // Also apply an async scroll offset in the y-direction such that the
   // scrollframe scrolls all the way to the bottom of its range, where it's
   // sure to checkerboard.
   utils.setDisplayPortForElement(0, 0, 300, 1000, scroller, 1);
   yield waitForApzFlushedRepaints(testDriver);
   var scrollY = scroller.scrollTopMax;
--- a/gfx/layers/apz/test/mochitest/helper_hittest_fixed_in_scrolled_transform.html
+++ b/gfx/layers/apz/test/mochitest/helper_hittest_fixed_in_scrolled_transform.html
@@ -63,21 +63,21 @@ body {
 </body>
 <script type="application/javascript">
 
 function* test(testDriver) {
   var config = getHitTestConfig();
   var utils = config.utils;
 
   // layerize the scrollable frame
-  var subframe = document.querySelector('.subframe');
+  var subframe = document.querySelector(".subframe");
   utils.setDisplayPortForElement(0, 0, 800, 2000, subframe, 1);
   yield waitForApzFlushedRepaints(testDriver);
 
-  var target = document.querySelector('.absoluteClip');
+  var target = document.querySelector(".absoluteClip");
   checkHitResult(hitTest(centerOf(target)),
                  APZHitResultFlags.VISIBLE,
                  utils.getViewId(subframe),
                  "fixed item inside a scrolling transform");
 
   subtestDone();
 }
 
--- a/gfx/layers/apz/test/mochitest/helper_hittest_float_bug1434846.html
+++ b/gfx/layers/apz/test/mochitest/helper_hittest_float_bug1434846.html
@@ -33,22 +33,22 @@
   <div id="make-root-scrollable"></div>
 </body>
 <script type="application/javascript">
 
 function* test(testDriver) {
   var utils = getHitTestConfig().utils;
 
   hitTestScrollbar({
-    element: document.getElementById('subframe'),
+    element: document.getElementById("subframe"),
     directions: { vertical: true },
     expectedScrollId: utils.getViewId(document.scrollingElement),
     trackLocation: ScrollbarTrackLocation.START,
     expectThumb: true,
-    layerState: LayerState.INACTIVE
+    layerState: LayerState.INACTIVE,
   });
 
   subtestDone();
 }
 
 waitUntilApzStable().then(runContinuation(test));
 
 </script>
--- a/gfx/layers/apz/test/mochitest/helper_hittest_float_bug1443518.html
+++ b/gfx/layers/apz/test/mochitest/helper_hittest_float_bug1443518.html
@@ -33,22 +33,22 @@
   <div id="make-root-scrollable"></div>
 </body>
 <script type="application/javascript">
 
 function* test(testDriver) {
   var utils = getHitTestConfig().utils;
 
   hitTestScrollbar({
-    element: document.getElementById('subframe'),
+    element: document.getElementById("subframe"),
     directions: { horizontal: true },
     expectedScrollId: utils.getViewId(document.scrollingElement),
     trackLocation: ScrollbarTrackLocation.START,
     expectThumb: true,
-    layerState: LayerState.INACTIVE
+    layerState: LayerState.INACTIVE,
   });
 
   subtestDone();
 }
 
 waitUntilApzStable().then(runContinuation(test));
 
 </script>
--- a/gfx/layers/apz/test/mochitest/helper_hittest_touchaction.html
+++ b/gfx/layers/apz/test/mochitest/helper_hittest_touchaction.html
@@ -101,205 +101,205 @@
   </div>
  </div>
 </body>
 <script type="application/javascript">
 
 var config = getHitTestConfig();
 
 function* test(testDriver) {
-  for (var scroller of document.querySelectorAll('.taBigBox > div')) {
+  for (var scroller of document.querySelectorAll(".taBigBox > div")) {
     // layerize all the scrollable divs
     config.utils.setDisplayPortForElement(0, 0, 100, 100, scroller, 1);
   }
   yield waitForApzFlushedRepaints(testDriver);
 
   var scrollId = config.utils.getViewId(document.scrollingElement);
 
   checkHitResult(
-      hitTest(centerOf('taNone')),
+      hitTest(centerOf("taNone")),
       APZHitResultFlags.VISIBLE |
       APZHitResultFlags.PAN_X_DISABLED |
       APZHitResultFlags.PAN_Y_DISABLED |
       APZHitResultFlags.PINCH_ZOOM_DISABLED |
       APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
       scrollId,
       "touch-action: none");
   checkHitResult(
-      hitTest(centerOf('taInnerNonePanX')),
+      hitTest(centerOf("taInnerNonePanX")),
       APZHitResultFlags.VISIBLE |
       APZHitResultFlags.PAN_X_DISABLED |
       APZHitResultFlags.PAN_Y_DISABLED |
       APZHitResultFlags.PINCH_ZOOM_DISABLED |
       APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
       scrollId,
       "touch-action: pan-x inside touch-action: none");
   checkHitResult(
-      hitTest(centerOf('taInnerNoneManip')),
+      hitTest(centerOf("taInnerNoneManip")),
       APZHitResultFlags.VISIBLE |
       APZHitResultFlags.PAN_X_DISABLED |
       APZHitResultFlags.PAN_Y_DISABLED |
       APZHitResultFlags.PINCH_ZOOM_DISABLED |
       APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
       scrollId,
       "touch-action: manipulation inside touch-action: none");
 
   checkHitResult(
-      hitTest(centerOf('taPanX')),
+      hitTest(centerOf("taPanX")),
       APZHitResultFlags.VISIBLE |
       APZHitResultFlags.PAN_Y_DISABLED |
       APZHitResultFlags.PINCH_ZOOM_DISABLED |
       APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
       scrollId,
       "touch-action: pan-x");
   checkHitResult(
-      hitTest(centerOf('taInnerPanXY')),
+      hitTest(centerOf("taInnerPanXY")),
       APZHitResultFlags.VISIBLE |
       APZHitResultFlags.PAN_X_DISABLED |
       APZHitResultFlags.PAN_Y_DISABLED |
       APZHitResultFlags.PINCH_ZOOM_DISABLED |
       APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
       scrollId,
       "touch-action: pan-y inside touch-action: pan-x");
   checkHitResult(
-      hitTest(centerOf('taInnerPanXManip')),
+      hitTest(centerOf("taInnerPanXManip")),
       APZHitResultFlags.VISIBLE |
       APZHitResultFlags.PAN_Y_DISABLED |
       APZHitResultFlags.PINCH_ZOOM_DISABLED |
       APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
       scrollId,
       "touch-action: manipulation inside touch-action: pan-x");
 
   checkHitResult(
-      hitTest(centerOf('taPanY')),
+      hitTest(centerOf("taPanY")),
       APZHitResultFlags.VISIBLE |
       APZHitResultFlags.PAN_X_DISABLED |
       APZHitResultFlags.PINCH_ZOOM_DISABLED |
       APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
       scrollId,
       "touch-action: pan-y");
   checkHitResult(
-      hitTest(centerOf('taInnerPanYX')),
+      hitTest(centerOf("taInnerPanYX")),
       APZHitResultFlags.VISIBLE |
       APZHitResultFlags.PAN_X_DISABLED |
       APZHitResultFlags.PAN_Y_DISABLED |
       APZHitResultFlags.PINCH_ZOOM_DISABLED |
       APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
       scrollId,
       "touch-action: pan-x inside touch-action: pan-y");
   checkHitResult(
-      hitTest(centerOf('taInnerPanYY')),
+      hitTest(centerOf("taInnerPanYY")),
       APZHitResultFlags.VISIBLE |
       APZHitResultFlags.PAN_X_DISABLED |
       APZHitResultFlags.PINCH_ZOOM_DISABLED |
       APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
       scrollId,
       "touch-action: pan-y inside touch-action: pan-y");
 
   checkHitResult(
-      hitTest(centerOf('taPanXY')),
+      hitTest(centerOf("taPanXY")),
       APZHitResultFlags.VISIBLE |
       APZHitResultFlags.PINCH_ZOOM_DISABLED |
       APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
       scrollId,
       "touch-action: pan-x pan-y");
   checkHitResult(
-      hitTest(centerOf('taInnerPanXYNone')),
+      hitTest(centerOf("taInnerPanXYNone")),
       APZHitResultFlags.VISIBLE |
       APZHitResultFlags.PAN_X_DISABLED |
       APZHitResultFlags.PAN_Y_DISABLED |
       APZHitResultFlags.PINCH_ZOOM_DISABLED |
       APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
       scrollId,
       "touch-action: none inside touch-action: pan-x pan-y");
 
   checkHitResult(
-      hitTest(centerOf('taManip')),
+      hitTest(centerOf("taManip")),
       APZHitResultFlags.VISIBLE |
       APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
       scrollId,
       "touch-action: manipulation");
   checkHitResult(
-      hitTest(centerOf('taInnerManipPanX')),
+      hitTest(centerOf("taInnerManipPanX")),
       APZHitResultFlags.VISIBLE |
       APZHitResultFlags.PAN_Y_DISABLED |
       APZHitResultFlags.PINCH_ZOOM_DISABLED |
       APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
       scrollId,
       "touch-action: pan-x inside touch-action: manipulation");
   checkHitResult(
-      hitTest(centerOf('taInnerManipNone')),
+      hitTest(centerOf("taInnerManipNone")),
       APZHitResultFlags.VISIBLE |
       APZHitResultFlags.PAN_X_DISABLED |
       APZHitResultFlags.PAN_Y_DISABLED |
       APZHitResultFlags.PINCH_ZOOM_DISABLED |
       APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
       scrollId,
       "touch-action: none inside touch-action: manipulation");
   checkHitResult(
-      hitTest(centerOf('taInnerManipListener')),
+      hitTest(centerOf("taInnerManipListener")),
       APZHitResultFlags.VISIBLE |
       APZHitResultFlags.DISPATCH_TO_CONTENT |
       APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
       scrollId,
       "div with touch listener inside touch-action: manipulation");
 
   checkHitResult(
-      hitTest(centerOf('taListener')),
+      hitTest(centerOf("taListener")),
       APZHitResultFlags.VISIBLE |
       APZHitResultFlags.DISPATCH_TO_CONTENT,
       scrollId,
       "div with touch listener");
   checkHitResult(
-      hitTest(centerOf('taInnerListenerPanX')),
+      hitTest(centerOf("taInnerListenerPanX")),
       APZHitResultFlags.VISIBLE |
       APZHitResultFlags.DISPATCH_TO_CONTENT |
       APZHitResultFlags.PAN_Y_DISABLED |
       APZHitResultFlags.PINCH_ZOOM_DISABLED |
       APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
       scrollId,
       "touch-action: pan-x inside div with touch listener");
 
   checkHitResult(
-      hitTest(centerOf('taScrollerPanY')),
+      hitTest(centerOf("taScrollerPanY")),
       APZHitResultFlags.VISIBLE |
       APZHitResultFlags.PAN_X_DISABLED |
       APZHitResultFlags.PINCH_ZOOM_DISABLED |
       APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
-      config.utils.getViewId(document.getElementById('taScrollerPanY')),
+      config.utils.getViewId(document.getElementById("taScrollerPanY")),
       "touch-action: pan-y on scroller");
   checkHitResult(
-      hitTest(centerOf('taScroller')),
+      hitTest(centerOf("taScroller")),
       APZHitResultFlags.VISIBLE |
       APZHitResultFlags.PAN_X_DISABLED |
       APZHitResultFlags.PINCH_ZOOM_DISABLED |
       APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
-      config.utils.getViewId(document.getElementById('taScroller')),
+      config.utils.getViewId(document.getElementById("taScroller")),
       "touch-action: pan-y on div inside scroller");
   checkHitResult(
-      hitTest(centerOf('taScroller2')),
+      hitTest(centerOf("taScroller2")),
       APZHitResultFlags.VISIBLE |
       APZHitResultFlags.PINCH_ZOOM_DISABLED |
       APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
-      config.utils.getViewId(document.getElementById('taScroller2')),
+      config.utils.getViewId(document.getElementById("taScroller2")),
       "zooming restrictions from pan-x outside scroller get inherited in");
 
   checkHitResult(
-      hitTest(centerOf('taScrollerPanX')),
+      hitTest(centerOf("taScrollerPanX")),
       APZHitResultFlags.VISIBLE |
       APZHitResultFlags.PAN_Y_DISABLED |
       APZHitResultFlags.PINCH_ZOOM_DISABLED |
       APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
-      config.utils.getViewId(document.getElementById('taScrollerPanX')),
+      config.utils.getViewId(document.getElementById("taScrollerPanX")),
       "touch-action: pan-x on scroller inside manipulation");
   checkHitResult(
-      hitTest(centerOf('taScroller3')),
+      hitTest(centerOf("taScroller3")),
       APZHitResultFlags.VISIBLE |
       APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
-      config.utils.getViewId(document.getElementById('taScroller3')),
+      config.utils.getViewId(document.getElementById("taScroller3")),
       "touch-action: manipulation outside scroller gets inherited in");
 }
 
 if (!config.isWebRender) {
   ok(true, "This test is WebRender-only because we get a bunch of dispatch-to-content regions without it and the test isn't very interesting.");
   subtestDone();
 } else {
   waitUntilApzStable()
--- a/gfx/layers/apz/test/mochitest/helper_iframe_pan.html
+++ b/gfx/layers/apz/test/mochitest/helper_iframe_pan.html
@@ -5,30 +5,30 @@
   <meta name="viewport" content="width=device-width; initial-scale=1.0">
   <title>Sanity panning test for scrollable div</title>
   <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
   <script type="application/javascript" src="apz_test_utils.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
   <script type="application/javascript">
 
 function scrollOuter() {
-  var outer = document.getElementById('outer');
+  var outer = document.getElementById("outer");
   var transformEnd = function() {
-    SpecialPowers.Services.obs.removeObserver(transformEnd, "APZ:TransformEnd", false);
+    SpecialPowers.Services.obs.removeObserver(transformEnd, "APZ:TransformEnd");
     dump("Transform complete; flushing repaints...\n");
     flushApzRepaints(checkScroll, outer.contentWindow);
   };
   SpecialPowers.Services.obs.addObserver(transformEnd, "APZ:TransformEnd");
 
   synthesizeNativeTouchDrag(outer.contentDocument.body, 10, 100, 0, -50);
   dump("Finished native drag, waiting for transform-end observer...\n");
 }
 
 function checkScroll() {
-  var outerScroll = document.getElementById('outer').contentWindow.scrollY;
+  var outerScroll = document.getElementById("outer").contentWindow.scrollY;
   if (getPlatform() == "windows") {
     // On windows, because we run this test with native event synthesization,
     // Windows can end up eating the first touchmove which can result in the
     // scroll amount being slightly smaller than 50px. See bug 1388955.
     dump("iframe scrolled " + outerScroll + "px");
     ok(outerScroll > 45, "iframe scrolled at least 45 px");
     ok(outerScroll <= 50, "iframe scrolled at most 50 px");
   } else {
--- a/gfx/layers/apz/test/mochitest/helper_key_scroll.html
+++ b/gfx/layers/apz/test/mochitest/helper_key_scroll.html
@@ -28,17 +28,17 @@ https://bugzilla.mozilla.org/show_bug.cg
       // Sanity check
       is(checkHasAsyncKeyScrolled(false), false, "expected no async key scrolling before test");
 
       // Send a key to initiate a page scroll to take us to the bottom of the
       // page. This scroll is done synchronously because APZ doesn't have
       // current focus state at page load.
       window.addEventListener("scroll", waitForScrollBottom);
       window.synthesizeKey("KEY_End");
-    };
+    }
 
     function waitForScrollBottom() {
       if (window.scrollY < window.scrollMaxY) {
         return;
       }
       SimpleTest.info("Reached final scroll position of sync KEY_End scroll");
       window.removeEventListener("scroll", waitForScrollBottom);
 
@@ -48,38 +48,38 @@ https://bugzilla.mozilla.org/show_bug.cg
       var utils = SpecialPowers.DOMWindowUtils;
       for (var i = 0; i < 10; i++) {
         utils.advanceTimeAndRefresh(50);
       }
       utils.restoreNormalRefresh();
 
       // Wait for the APZ to reach a stable state as well, before dispatching
       // the next key input or the default action won't occur.
-      waitForApzFlushedRepaints(function () {
+      waitForApzFlushedRepaints(function() {
         is(checkHasAsyncKeyScrolled(false), false, "expected no async key scrolling before KEY_Home dispatch");
 
         // This scroll should be asynchronous now that the focus state is up to date.
         window.addEventListener("scroll", waitForScrollTop);
         window.synthesizeKey("KEY_Home");
       });
-    };
+    }
 
     function waitForScrollTop() {
       if (window.scrollY > 0) {
         return;
       }
       SimpleTest.info("Reached final scroll position of async KEY_Home scroll");
       window.removeEventListener("scroll", waitForScrollTop);
 
       // Wait for APZ to settle and then check that async scrolling happened.
-      waitForApzFlushedRepaints(function () {
+      waitForApzFlushedRepaints(function() {
         is(checkHasAsyncKeyScrolled(true), true, "expected async key scrolling after test");
         subtestDone();
       });
-    };
+    }
 
     function checkHasAsyncKeyScrolled(requirePaints) {
       // Get the compositor-side test data from nsIDOMWindowUtils.
       var utils = SpecialPowers.getDOMWindowUtils(window);
       var compositorTestData = utils.getCompositorAPZTestData();
 
       if (requirePaints) {
         ok(compositorTestData.paints.length > 0,
@@ -96,20 +96,20 @@ https://bugzilla.mozilla.org/show_bug.cg
       compositorTestData = convertTestData(compositorTestData);
 
       // Reconstruct the APZC tree structure in the last paint.
       var apzcTree = buildApzcTree(compositorTestData.paints[lastPaintSeqNo]);
       var rcd = findRcdNode(apzcTree);
 
       if (rcd) {
         return rcd.hasAsyncKeyScrolled === "1";
-      } else {
-        SimpleTest.info("Last paint rcd is null");
-        return false;
       }
+
+      SimpleTest.info("Last paint rcd is null");
+      return false;
     }
 
     waitUntilApzStable().then(forceLayerTreeToCompositor).then(runTests);
   </script>
 </head>
 <body style="height: 500px; overflow: scroll">
   <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1383365">Async key scrolling test</a>
   <!-- Put enough content into the page to make it have a nonzero scroll range -->
--- a/gfx/layers/apz/test/mochitest/helper_long_tap.html
+++ b/gfx/layers/apz/test/mochitest/helper_long_tap.html
@@ -5,75 +5,75 @@
   <meta name="viewport" content="width=device-width; initial-scale=1.0">
   <title>Ensure we get a touch-cancel after a contextmenu comes up</title>
   <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
   <script type="application/javascript" src="apz_test_utils.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
   <script type="application/javascript">
 
 function longPressLink() {
-  synthesizeNativeTouch(document.getElementById('b'), 5, 5, SpecialPowers.DOMWindowUtils.TOUCH_CONTACT, function() {
+  synthesizeNativeTouch(document.getElementById("b"), 5, 5, SpecialPowers.DOMWindowUtils.TOUCH_CONTACT, function() {
     dump("Finished synthesizing touch-start, waiting for events...\n");
   });
 }
 
 var eventsFired = 0;
 function recordEvent(e) {
   if (getPlatform() == "windows") {
     // On Windows we get a mouselongtap event once the long-tap has been detected
     // by APZ, and that's what we use as the trigger to lift the finger. That then
     // triggers the contextmenu. This matches the platform convention.
     switch (eventsFired) {
-      case 0: is(e.type, 'touchstart', 'Got a touchstart'); break;
+      case 0: is(e.type, "touchstart", "Got a touchstart"); break;
       case 1:
-        is(e.type, 'mouselongtap', 'Got a mouselongtap');
-        synthesizeNativeTouch(document.getElementById('b'), 5, 5, SpecialPowers.DOMWindowUtils.TOUCH_REMOVE);
+        is(e.type, "mouselongtap", "Got a mouselongtap");
+        synthesizeNativeTouch(document.getElementById("b"), 5, 5, SpecialPowers.DOMWindowUtils.TOUCH_REMOVE);
         break;
-      case 2: is(e.type, 'touchend', 'Got a touchend'); break;
-      case 3: is(e.type, 'contextmenu', 'Got a contextmenu'); e.preventDefault(); break;
-      default: ok(false, 'Got an unexpected event of type ' + e.type); break;
+      case 2: is(e.type, "touchend", "Got a touchend"); break;
+      case 3: is(e.type, "contextmenu", "Got a contextmenu"); e.preventDefault(); break;
+      default: ok(false, "Got an unexpected event of type " + e.type); break;
     }
     eventsFired++;
 
     if (eventsFired == 4) {
       dump("Finished waiting for events, doing an APZ flush to see if any more unexpected events come through...\n");
       flushApzRepaints(function() {
         dump("Done APZ flush, ending test...\n");
         subtestDone();
       });
     }
   } else {
     // On non-Windows platforms we get a contextmenu event once the long-tap has
     // been detected. Since we prevent-default that, we don't get a mouselongtap
     // event at all, and instead get a touchcancel.
     switch (eventsFired) {
-      case 0: is(e.type, 'touchstart', 'Got a touchstart'); break;
-      case 1: is(e.type, 'contextmenu', 'Got a contextmenu'); e.preventDefault(); break;
-      case 2: is(e.type, 'touchcancel', 'Got a touchcancel'); break;
-      default: ok(false, 'Got an unexpected event of type ' + e.type); break;
+      case 0: is(e.type, "touchstart", "Got a touchstart"); break;
+      case 1: is(e.type, "contextmenu", "Got a contextmenu"); e.preventDefault(); break;
+      case 2: is(e.type, "touchcancel", "Got a touchcancel"); break;
+      default: ok(false, "Got an unexpected event of type " + e.type); break;
     }
     eventsFired++;
 
     if (eventsFired == 3) {
-      synthesizeNativeTouch(document.getElementById('b'), 5, 5, SpecialPowers.DOMWindowUtils.TOUCH_REMOVE, function() {
+      synthesizeNativeTouch(document.getElementById("b"), 5, 5, SpecialPowers.DOMWindowUtils.TOUCH_REMOVE, function() {
         dump("Finished synthesizing touch-end, doing an APZ flush to see if any more unexpected events come through...\n");
         flushApzRepaints(function() {
           dump("Done APZ flush, ending test...\n");
           subtestDone();
         });
       });
     }
   }
 }
 
-window.addEventListener('touchstart', recordEvent, { passive: true, capture: true });
-window.addEventListener('touchend', recordEvent, { passive: true, capture: true });
-window.addEventListener('touchcancel', recordEvent, true);
-window.addEventListener('contextmenu', recordEvent, true);
-SpecialPowers.addChromeEventListener('mouselongtap', recordEvent, true);
+window.addEventListener("touchstart", recordEvent, { passive: true, capture: true });
+window.addEventListener("touchend", recordEvent, { passive: true, capture: true });
+window.addEventListener("touchcancel", recordEvent, true);
+window.addEventListener("contextmenu", recordEvent, true);
+SpecialPowers.addChromeEventListener("mouselongtap", recordEvent, true);
 
 waitUntilApzStable()
 .then(longPressLink);
 
   </script>
 </head>
 <body>
  <a id="b" href="#">Link to nowhere</a>
--- a/gfx/layers/apz/test/mochitest/helper_override_root.html
+++ b/gfx/layers/apz/test/mochitest/helper_override_root.html
@@ -7,17 +7,17 @@
   <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
   <script type="application/javascript" src="apz_test_utils.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
   <script type="application/javascript">
 
 // Add a non-passive listener on the document, so that we have a document-level
 // APZ-aware listener, and the entire document is put in the dispatch-to-content
 // region
-document.addEventListener('wheel', function(e) {
+document.addEventListener("wheel", function(e) {
     dump("Wheel listener running...\n");
 
     // spin for 2 seconds to give APZ time to scroll, if the event region override
     // is broken and it decides not to wait for the main thread. Note that it's
     // possible the APZ controller thread is busy for whatever reason so APZ
     // may not scroll. That might cause this test to only fail intermittently
     // instead of consistently if the behaviour being tested regresses.
     var now = Date.now();
@@ -25,17 +25,17 @@ document.addEventListener('wheel', funct
 
     // Cancel the scroll. If this works then we know APZ waited for this listener
     // to run.
     e.preventDefault();
 
     setTimeout(function() {
         flushApzRepaints(checkScroll);
     }, 0);
-}, false);
+});
 
 function scrollPage() {
   synthesizeNativeWheel(document.body, 100, 100, 0, -50);
   dump("Finished native wheel, waiting for listener to run...\n");
 }
 
 function checkScroll() {
   is(window.scrollY, 0, "check that the window didn't scroll");
--- a/gfx/layers/apz/test/mochitest/helper_overscroll_behavior_bug1425573.html
+++ b/gfx/layers/apz/test/mochitest/helper_overscroll_behavior_bug1425573.html
@@ -2,21 +2,21 @@
   <meta name="viewport" content="width=device-width; initial-scale=1.0">
   <title>Wheel-scrolling over inactive subframe with overscroll-behavior</title>
   <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
   <script type="application/javascript" src="apz_test_utils.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
   <script type="application/javascript">
 
 function* test(testDriver) {
-  var subframe = document.getElementById('scroll');
+  var subframe = document.getElementById("scroll");
 
   // scroll over the middle of the subframe, and make sure that the page
   // does not scroll.
-  var waitForScroll = false;  // don't wait for a scroll event, it will never come
+  var waitForScroll = false; // don't wait for a scroll event, it will never come
   yield moveMouseAndScrollWheelOver(subframe, 100, 100, testDriver, waitForScroll);
   ok(window.scrollY == 0, "overscroll-behavior was respected");
 }
 
 waitUntilApzStable()
 .then(runContinuation(test))
 .then(subtestDone);
 
--- a/gfx/layers/apz/test/mochitest/helper_overscroll_behavior_bug1425603.html
+++ b/gfx/layers/apz/test/mochitest/helper_overscroll_behavior_bug1425603.html
@@ -29,17 +29,17 @@
   <div id="make_root_scrollable" style="height: 5000px"></div>
 </body>
 <script type="application/javascript">
 
 function* test(testDriver) {
   var config = getHitTestConfig();
   var utils = config.utils;
 
-  var subframe = document.getElementById('subframe');
+  var subframe = document.getElementById("subframe");
 
   // Activate the scrollframe but keep the main-thread scroll position at 0.
   // Also apply an async scroll offset in the y-direction large enough
   // to make the scrollframe checkerboard.
   // Note: We have to be careful with the numbers here.
   //   moveMouseAndScrollWheelOver() relies on the main thread receiving
   //   the synthesized mouse-move and wheel events. However, the async
   //   transform created by setAsyncScrollOffset() will cause an untransform
@@ -60,17 +60,17 @@ function* test(testDriver) {
     // async scroll offset (for APZ hit-testing this doesn't matter, but for
     // WebRender hit-testing we need to make sure WR has the latest info).
     utils.advanceTimeAndRefresh(16);
     utils.restoreNormalRefresh();
   }
 
   // Scroll over the subframe, and make sure that the page does not scroll,
   // i.e. overscroll-behavior is respected.
-  var waitForScroll = false;  // don't wait for a scroll event, it will never come
+  var waitForScroll = false; // don't wait for a scroll event, it will never come
   yield moveMouseAndScrollWheelOver(subframe, 50, 50, testDriver, waitForScroll);
   ok(window.scrollY == 0, "overscroll-behavior was respected");
 
   subtestDone();
 }
 
 waitUntilApzStable().then(runContinuation(test));
 
--- a/gfx/layers/apz/test/mochitest/helper_overscroll_behavior_bug1494440.html
+++ b/gfx/layers/apz/test/mochitest/helper_overscroll_behavior_bug1494440.html
@@ -8,19 +8,18 @@
 <body>
   <iframe id="scroll" srcdoc="<html style='overscroll-behavior:none;'><div style='width:100px;height:2000px;'>">
   </iframe>
   <div style="height: 5000px;"></div><!-- So the page is scrollable as well -->
 
   <script type="application/javascript">
 
 function* test(testDriver) {
-  var iframe = document.getElementById('scroll');
+  var iframe = document.getElementById("scroll");
   var iframeWindow = iframe.contentWindow;
-  var iframeContent = iframeWindow.document.documentElement;
 
   // scroll the iframe to the bottom, such that a subsequent scroll on it
   // _would_ hand off to the page if overscroll-behavior allowed it
   iframeWindow.scrollTo(0, iframeWindow.scrollMaxY);
   yield waitForApzFlushedRepaints(testDriver);
   is(iframeWindow.scrollY, iframeWindow.scrollMaxY, "iframe has scrolled to the bottom");
 
   // Scroll over the iframe, and make sure that the page
--- a/gfx/layers/apz/test/mochitest/helper_scroll_inactive_perspective.html
+++ b/gfx/layers/apz/test/mochitest/helper_scroll_inactive_perspective.html
@@ -2,17 +2,17 @@
   <meta name="viewport" content="width=device-width; initial-scale=1.0">
   <title>Wheel-scrolling over inactive subframe with perspective</title>
   <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
   <script type="application/javascript" src="apz_test_utils.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
   <script type="application/javascript">
 
 function* test(testDriver) {
-  var subframe = document.getElementById('scroll');
+  var subframe = document.getElementById("scroll");
 
   // scroll over the middle of the subframe, to make sure it scrolls,
   // not the page
   var scrollPos = subframe.scrollTop;
   yield moveMouseAndScrollWheelOver(subframe, 100, 100, testDriver);
   dump("after scroll, subframe.scrollTop = " + subframe.scrollTop + "\n");
   ok(subframe.scrollTop > scrollPos, "subframe scrolled after wheeling over it");
 }
--- a/gfx/layers/apz/test/mochitest/helper_scroll_inactive_zindex.html
+++ b/gfx/layers/apz/test/mochitest/helper_scroll_inactive_zindex.html
@@ -2,17 +2,17 @@
   <meta name="viewport" content="width=device-width; initial-scale=1.0">
   <title>Wheel-scrolling over inactive subframe with z-index</title>
   <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
   <script type="application/javascript" src="apz_test_utils.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
   <script type="application/javascript">
 
 function* test(testDriver) {
-  var subframe = document.getElementById('scroll');
+  var subframe = document.getElementById("scroll");
 
   // scroll over the middle of the subframe, and make sure that it scrolls,
   // not the page
   var scrollPos = subframe.scrollTop;
   yield moveMouseAndScrollWheelOver(subframe, 100, 100, testDriver);
   dump("after scroll, subframe.scrollTop = " + subframe.scrollTop + "\n");
   ok(subframe.scrollTop > scrollPos, "subframe scrolled after wheeling over it");
 }
--- a/gfx/layers/apz/test/mochitest/helper_scroll_on_position_fixed.html
+++ b/gfx/layers/apz/test/mochitest/helper_scroll_on_position_fixed.html
@@ -2,31 +2,31 @@
   <meta name="viewport" content="width=device-width; initial-scale=1.0">
   <title>Wheel-scrolling over position:fixed and position:sticky elements, in the top-level document as well as iframes</title>
   <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
   <script type="application/javascript" src="apz_test_utils.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
   <script type="application/javascript">
 
 function* test(testDriver) {
-  var iframeWin = document.getElementById('iframe').contentWindow;
+  var iframeWin = document.getElementById("iframe").contentWindow;
 
   // scroll over the middle of the iframe's position:sticky element, check
   // that it scrolls the iframe
   var scrollPos = iframeWin.scrollY;
   yield moveMouseAndScrollWheelOver(iframeWin.document.body, 50, 150, testDriver);
   ok(iframeWin.scrollY > scrollPos, "iframe scrolled after wheeling over the position:sticky element");
 
   // same, but using the iframe's position:fixed element
   scrollPos = iframeWin.scrollY;
   yield moveMouseAndScrollWheelOver(iframeWin.document.body, 250, 150, testDriver);
   ok(iframeWin.scrollY > scrollPos, "iframe scrolled after wheeling over the position:fixed element");
 
   // same, but scrolling the scrollable frame *inside* the position:fixed item
-  var fpos = document.getElementById('fpos_scrollable');
+  var fpos = document.getElementById("fpos_scrollable");
   scrollPos = fpos.scrollTop;
   yield moveMouseAndScrollWheelOver(fpos, 50, 150, testDriver);
   ok(fpos.scrollTop > scrollPos, "scrollable item inside fixed-pos element scrolled");
   // wait for it to layerize fully and then try again
   yield waitForAllPaints(function() {
     flushApzRepaints(testDriver);
   });
   scrollPos = fpos.scrollTop;
--- a/gfx/layers/apz/test/mochitest/helper_scroll_over_scrollbar.html
+++ b/gfx/layers/apz/test/mochitest/helper_scroll_over_scrollbar.html
@@ -2,17 +2,17 @@
   <meta name="viewport" content="width=device-width; initial-scale=1.0">
   <title>Wheel-scrolling over scrollbar</title>
   <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
   <script type="application/javascript" src="apz_test_utils.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
   <script type="application/javascript">
 
 function* test(testDriver) {
-  var subframe = document.getElementById('scroll');
+  var subframe = document.getElementById("scroll");
 
   // scroll over the scrollbar, and make sure the subframe scrolls
   var scrollPos = subframe.scrollTop;
   var scrollbarX = (200 + subframe.clientWidth) / 2;
   yield synthesizeNativeWheelAndWaitForScrollEvent(subframe, scrollbarX, 100,
       0, -10, testDriver);
   ok(subframe.scrollTop > scrollPos, "subframe scrolled after wheeling over scrollbar");
 }
--- a/gfx/layers/apz/test/mochitest/helper_scroll_tables_perspective.html
+++ b/gfx/layers/apz/test/mochitest/helper_scroll_tables_perspective.html
@@ -1,16 +1,16 @@
 <!DOCTYPE html>
 <head>
   <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
   <script type="application/javascript" src="apz_test_utils.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
   <script type="application/javascript">
 function* test(testDriver) {
-  var subframe = document.getElementById('content-wrapper');
+  var subframe = document.getElementById("content-wrapper");
 
   // scroll over the middle of the subframe, to make sure it scrolls,
   // not the page
   var scrollPos = subframe.scrollTop;
   yield moveMouseAndScrollWheelOver(subframe, 100, 100, testDriver);
   ok(subframe.scrollTop > scrollPos, "subframe scrolled after wheeling over it");
 }
 
--- a/gfx/layers/apz/test/mochitest/helper_scrollbar_snap_bug1501062.html
+++ b/gfx/layers/apz/test/mochitest/helper_scrollbar_snap_bug1501062.html
@@ -21,26 +21,26 @@ function* test(testDriver) {
   var snapMultiplier = SpecialPowers.getIntPref("slider.snapMultiplier");
 
   // Much of the code below is "inlined" from dragVerticalScrollbar. Reusing
   // that code was nontrivial given the modifications we needed to make, and
   // would have increased the complexity of that helper function more than I'd
   // like. However if any bugfixes are made to that function this code might
   // need to be updated as well.
 
-  var scrollableDiv = document.getElementById('scrollable');
+  var scrollableDiv = document.getElementById("scrollable");
   var boundingClientRect = scrollableDiv.getBoundingClientRect();
   var verticalScrollbarWidth = boundingClientRect.width - scrollableDiv.clientWidth;
   if (verticalScrollbarWidth == 0) {
     ok(true, "No scrollbar, can't do this test");
     return;
   }
 
   // register a scroll listener for the initial drag
-  scrollableDiv.addEventListener('scroll', () => setTimeout(testDriver, 0), {once: true});
+  scrollableDiv.addEventListener("scroll", () => setTimeout(testDriver, 0), {once: true});
 
   var upArrowHeight = verticalScrollbarWidth; // assume square scrollbar buttons
   var mouseX = scrollableDiv.clientWidth + (verticalScrollbarWidth / 2);
   var mouseY = upArrowHeight + 5; // start dragging somewhere in the thumb
 
   dump("Starting drag at " + mouseX + ", " + mouseY + " from top-left of #" + scrollableDiv.id + "\n");
 
   // Move the mouse to the scrollbar thumb and drag it down
@@ -56,32 +56,32 @@ function* test(testDriver) {
   ok(savedScrollPos > 0, "Scrolled to " + savedScrollPos);
 
   // register a new scroll event listener. The next mousemove below will either
   // trigger the snapback behaviour (if snapMultiplier > 0) or trigger a vertical
   // scroll (if snapMultiplier == 0) because of the x- and y-coordinates we move
   // the mouse to. This allows us to wait for a scroll event in either case.
   // If we only triggered the snapback case then waiting for the scroll to
   // "not happen" in the other case would be more error-prone.
-  scrollableDiv.addEventListener('scroll', () => setTimeout(testDriver, 0), {once: true});
+  scrollableDiv.addEventListener("scroll", () => setTimeout(testDriver, 0), {once: true});
   // Add 2 to snapMultipler just to make sure we get far enough away from the scrollbar
   var snapBackDistance = (snapMultiplier + 2) * verticalScrollbarWidth;
   yield synthesizeNativeMouseEvent(scrollableDiv, mouseX + snapBackDistance, mouseY + 10, nativeMouseMoveEventMsg(), testDriver);
 
   // wait here until the scroll happens
   yield;
   if (snapMultiplier > 0) {
     ok(scrollableDiv.scrollTop == 0, "Scroll position snapped back to " + scrollableDiv.scrollTop);
   } else {
     ok(scrollableDiv.scrollTop > savedScrollPos, "Scroll position increased to " + scrollableDiv.scrollTop);
   }
 
   // Now we move the mouse back to the old position to ensure the scroll position
   // gets restored properly
-  scrollableDiv.addEventListener('scroll', () => setTimeout(testDriver, 0), {once: true});
+  scrollableDiv.addEventListener("scroll", () => setTimeout(testDriver, 0), {once: true});
   yield synthesizeNativeMouseEvent(scrollableDiv, mouseX, mouseY, nativeMouseMoveEventMsg(), testDriver);
 
   // wait here until the scroll happens
   yield;
   ok(scrollableDiv.scrollTop == savedScrollPos, "Scroll position was restored to " + scrollableDiv.scrollTop);
 
   // Release mouse and ensure the scroll position stuck
   yield synthesizeNativeMouseEvent(scrollableDiv, mouseX, mouseY, nativeMouseUpEventMsg(), testDriver);
--- a/gfx/layers/apz/test/mochitest/helper_scrollto_tap.html
+++ b/gfx/layers/apz/test/mochitest/helper_scrollto_tap.html
@@ -19,39 +19,39 @@ function startTest() {
   }
 
   // This is a scroll by 20px that should use paint-skipping if possible.
   // If paint-skipping is enabled, this should not trigger a paint, but go
   // directly to the compositor using an empty transaction. We check for this
   // by ensuring the document element did not get painted.
   var utils = window.opener.SpecialPowers.getDOMWindowUtils(window);
   var elem = document.documentElement;
-  var skipping = location.search == '?true';
+  var skipping = location.search == "?true";
   utils.checkAndClearPaintedState(elem);
   window.scrollTo(0, 20);
   waitForAllPaints(function() {
     if (skipping) {
       is(utils.checkAndClearPaintedState(elem), false, "Document element didn't get painted");
     }
     // After that's done, we click on the button to make sure the
     // skipped-paint codepath still has working APZ event transformations.
     clickButton();
   });
 }
 
 function clickButton() {
-  document.addEventListener('click', clicked);
+  document.addEventListener("click", clicked);
 
-  synthesizeNativeTap(document.getElementById('b'), 5, 5, function() {
+  synthesizeNativeTap(document.getElementById("b"), 5, 5, function() {
     dump("Finished synthesizing tap, waiting for button to be clicked...\n");
   });
 }
 
 function clicked(e) {
-  is(e.target, document.getElementById('b'), "Clicked on button, yay! (at " + e.clientX + "," + e.clientY + ")");
+  is(e.target, document.getElementById("b"), "Clicked on button, yay! (at " + e.clientX + "," + e.clientY + ")");
   subtestDone();
 }
 
 waitUntilApzStable().then(startTest);
 
   </script>
 </head>
 <body style="height: 5000px">
--- a/gfx/layers/apz/test/mochitest/helper_tap.html
+++ b/gfx/layers/apz/test/mochitest/helper_tap.html
@@ -5,25 +5,25 @@
   <meta name="viewport" content="width=device-width; initial-scale=1.0">
   <title>Sanity touch-tapping test</title>
   <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
   <script type="application/javascript" src="apz_test_utils.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
   <script type="application/javascript">
 
 function clickButton() {
-  document.addEventListener('click', clicked);
+  document.addEventListener("click", clicked);
 
-  synthesizeNativeTap(document.getElementById('b'), 5, 5, function() {
+  synthesizeNativeTap(document.getElementById("b"), 5, 5, function() {
     dump("Finished synthesizing tap, waiting for button to be clicked...\n");
   });
 }
 
 function clicked(e) {
-  is(e.target, document.getElementById('b'), "Clicked on button, yay! (at " + e.clientX + "," + e.clientY + ")");
+  is(e.target, document.getElementById("b"), "Clicked on button, yay! (at " + e.clientX + "," + e.clientY + ")");
   subtestDone();
 }
 
 waitUntilApzStable().then(clickButton);
 
   </script>
 </head>
 <body>
--- a/gfx/layers/apz/test/mochitest/helper_tap_default_passive.html
+++ b/gfx/layers/apz/test/mochitest/helper_tap_default_passive.html
@@ -7,56 +7,56 @@
   <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
   <script type="application/javascript" src="apz_test_utils.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
   <script type="application/javascript">
 
 var touchdownTime;
 
 function longPressLink() {
-  synthesizeNativeTouch(document.getElementById('b'), 5, 5, SpecialPowers.DOMWindowUtils.TOUCH_CONTACT, function() {
+  synthesizeNativeTouch(document.getElementById("b"), 5, 5, SpecialPowers.DOMWindowUtils.TOUCH_CONTACT, function() {
     dump("Finished synthesizing touch-start, waiting for events...\n");
   });
 }
 
 var touchstartReceived = false;
 function recordEvent(e) {
   if (!touchstartReceived) {
     touchstartReceived = true;
-    is(e.type, 'touchstart', 'Got a touchstart');
+    is(e.type, "touchstart", "Got a touchstart");
     e.preventDefault(); // should be a no-op because it's a passive listener
     return;
   }
 
   // If APZ decides to wait for the content response on a particular input block,
   // it needs to wait until both the touchstart and touchmove event are handled
   // by the main thread. In this case there is no touchmove at all, so APZ would
   // end up waiting indefinitely and time out the test. The fact that we get this
   // contextmenu event (mouselongtap on Windows) at all means that APZ decided
   // not to wait for the content response, which is the desired behaviour, since
   // the touchstart listener was registered as a passive listener.
   if (getPlatform() == "windows") {
-    is(e.type, 'mouselongtap', 'Got a mouselongtap');
+    is(e.type, "mouselongtap", "Got a mouselongtap");
   } else {
-    is(e.type, 'contextmenu', 'Got a contextmenu');
+    is(e.type, "contextmenu", "Got a contextmenu");
   }
   e.preventDefault();
 
-  synthesizeNativeTouch(document.getElementById('b'), 5, 5, SpecialPowers.DOMWindowUtils.TOUCH_REMOVE, function() {
+  synthesizeNativeTouch(document.getElementById("b"), 5, 5, SpecialPowers.DOMWindowUtils.TOUCH_REMOVE, function() {
     dump("Finished synthesizing touch-end to clear state; finishing test...\n");
     subtestDone();
   });
 }
 
 // Note, not passing 'passive'.
-window.addEventListener('touchstart', recordEvent, { capture: true });
+window.addEventListener("touchstart", recordEvent, { capture: true });
 if (getPlatform() == "windows") {
-  SpecialPowers.addChromeEventListener('mouselongtap', recordEvent, true);
+  SpecialPowers.addChromeEventListener("mouselongtap", recordEvent, true);
 } else {
-  window.addEventListener('contextmenu', recordEvent, true);
+  window.addEventListener("contextmenu", recordEvent, true);
 }
 
 waitUntilApzStable()
 .then(longPressLink);
 
   </script>
 </head>
 <body>
--- a/gfx/layers/apz/test/mochitest/helper_tap_fullzoom.html
+++ b/gfx/layers/apz/test/mochitest/helper_tap_fullzoom.html
@@ -5,25 +5,25 @@
   <meta name="viewport" content="width=device-width; initial-scale=1.0">
   <title>Sanity touch-tapping test with fullzoom</title>
   <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
   <script type="application/javascript" src="apz_test_utils.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
   <script type="application/javascript">
 
 function clickButton() {
-  document.addEventListener('click', clicked);
+  document.addEventListener("click", clicked);
 
-  synthesizeNativeTap(document.getElementById('b'), 5, 5, function() {
+  synthesizeNativeTap(document.getElementById("b"), 5, 5, function() {
     dump("Finished synthesizing tap, waiting for button to be clicked...\n");
   });
 }
 
 function clicked(e) {
-  is(e.target, document.getElementById('b'), "Clicked on button, yay! (at " + e.clientX + "," + e.clientY + ")");
+  is(e.target, document.getElementById("b"), "Clicked on button, yay! (at " + e.clientX + "," + e.clientY + ")");
   subtestDone();
 }
 
 SpecialPowers.setFullZoom(window, 2.0);
 waitUntilApzStable().then(clickButton);
 
   </script>
 </head>
--- a/gfx/layers/apz/test/mochitest/helper_tap_passive.html
+++ b/gfx/layers/apz/test/mochitest/helper_tap_passive.html
@@ -7,55 +7,55 @@
   <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
   <script type="application/javascript" src="apz_test_utils.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
   <script type="application/javascript">
 
 var touchdownTime;
 
 function longPressLink() {
-  synthesizeNativeTouch(document.getElementById('b'), 5, 5, SpecialPowers.DOMWindowUtils.TOUCH_CONTACT, function() {
+  synthesizeNativeTouch(document.getElementById("b"), 5, 5, SpecialPowers.DOMWindowUtils.TOUCH_CONTACT, function() {
     dump("Finished synthesizing touch-start, waiting for events...\n");
   });
 }
 
 var touchstartReceived = false;
 function recordEvent(e) {
   if (!touchstartReceived) {
     touchstartReceived = true;
-    is(e.type, 'touchstart', 'Got a touchstart');
+    is(e.type, "touchstart", "Got a touchstart");
     e.preventDefault(); // should be a no-op because it's a passive listener
     return;
   }
 
   // If APZ decides to wait for the content response on a particular input block,
   // it needs to wait until both the touchstart and touchmove event are handled
   // by the main thread. In this case there is no touchmove at all, so APZ would
   // end up waiting indefinitely and time out the test. The fact that we get this
   // contextmenu event (mouselongtap on Windows) at all means that APZ decided
   // not to wait for the content response, which is the desired behaviour, since
   // the touchstart listener was registered as a passive listener.
   if (getPlatform() == "windows") {
-    is(e.type, 'mouselongtap', 'Got a mouselongtap');
+    is(e.type, "mouselongtap", "Got a mouselongtap");
   } else {
-    is(e.type, 'contextmenu', 'Got a contextmenu');
+    is(e.type, "contextmenu", "Got a contextmenu");
   }
   e.preventDefault();
 
-  synthesizeNativeTouch(document.getElementById('b'), 5, 5, SpecialPowers.DOMWindowUtils.TOUCH_REMOVE, function() {
+  synthesizeNativeTouch(document.getElementById("b"), 5, 5, SpecialPowers.DOMWindowUtils.TOUCH_REMOVE, function() {
     dump("Finished synthesizing touch-end to clear state; finishing test...\n");
     subtestDone();
   });
 }
 
-window.addEventListener('touchstart', recordEvent, { passive: true, capture: true });
+window.addEventListener("touchstart", recordEvent, { passive: true, capture: true });
 if (getPlatform() == "windows") {
-  SpecialPowers.addChromeEventListener('mouselongtap', recordEvent, true);
+  SpecialPowers.addChromeEventListener("mouselongtap", recordEvent, true);
 } else {
-  window.addEventListener('contextmenu', recordEvent, true);
+  window.addEventListener("contextmenu", recordEvent, true);
 }
 
 waitUntilApzStable()
 .then(longPressLink);
 
   </script>
 </head>
 <body>
--- a/gfx/layers/apz/test/mochitest/helper_touch_action.html
+++ b/gfx/layers/apz/test/mochitest/helper_touch_action.html
@@ -10,28 +10,28 @@
   <script type="application/javascript">
 
 function checkScroll(x, y, desc) {
   is(window.scrollX, x, desc + " - x axis");
   is(window.scrollY, y, desc + " - y axis");
 }
 
 function* test(testDriver) {
-  var target = document.getElementById('target');
+  var target = document.getElementById("target");
 
-  document.body.addEventListener('touchend', testDriver, { passive: true });
+  document.body.addEventListener("touchend", testDriver, { passive: true });
 
   // drag the page up to scroll down by 50px
   yield ok(synthesizeNativeTouchDrag(target, 10, 100, 0, -50),
       "Synthesized native vertical drag (1), waiting for touch-end event...");
   yield flushApzRepaints(testDriver);
   checkScroll(0, 50, "After first vertical drag, with pan-y" );
 
   // switch style to pan-x
-  document.body.style.touchAction = 'pan-x';
+  document.body.style.touchAction = "pan-x";
   ok(true, "Waiting for pan-x to propagate...");
   yield waitForAllPaintsFlushed(function() {
     flushApzRepaints(testDriver);
   });
 
   // drag the page up to scroll down by 50px, but it won't happen because pan-x
   yield ok(synthesizeNativeTouchDrag(target, 10, 100, 0, -50),
      "Synthesized native vertical drag (2), waiting for touch-end event...");
@@ -47,44 +47,44 @@ function* test(testDriver) {
   // drag the page diagonally right/down to scroll up/left by 40px each axis;
   // only the x-axis will actually scroll because pan-x
   yield ok(synthesizeNativeTouchDrag(target, 10, 10, 40, 40),
      "Synthesized diagonal drag (1), waiting for touch-end event...");
   yield flushApzRepaints(testDriver);
   checkScroll(10, 50, "After first diagonal drag, with pan-x");
 
   // switch style back to pan-y
-  document.body.style.touchAction = 'pan-y';
+  document.body.style.touchAction = "pan-y";
   ok(true, "Waiting for pan-y to propagate...");
   yield waitForAllPaintsFlushed(function() {
     flushApzRepaints(testDriver);
   });
 
   // drag the page diagonally right/down to scroll up/left by 40px each axis;
   // only the y-axis will actually scroll because pan-y
   yield ok(synthesizeNativeTouchDrag(target, 10, 10, 40, 40),
      "Synthesized diagonal drag (2), waiting for touch-end event...");
   yield flushApzRepaints(testDriver);
   checkScroll(10, 10, "After second diagonal drag, with pan-y");
 
   // switch style to none
-  document.body.style.touchAction = 'none';
+  document.body.style.touchAction = "none";
   ok(true, "Waiting for none to propagate...");
   yield waitForAllPaintsFlushed(function() {
     flushApzRepaints(testDriver);
   });
 
   // drag the page diagonally up/left to scroll down/right by 40px each axis;
   // neither will scroll because of touch-action
   yield ok(synthesizeNativeTouchDrag(target, 100, 100, -40, -40),
       "Synthesized diagonal drag (3), waiting for touch-end event...");
   yield flushApzRepaints(testDriver);
   checkScroll(10, 10, "After third diagonal drag, with none");
 
-  document.body.style.touchAction = 'manipulation';
+  document.body.style.touchAction = "manipulation";
   ok(true, "Waiting for manipulation to propagate...");
   yield waitForAllPaintsFlushed(function() {
     flushApzRepaints(testDriver);
   });
 
   // drag the page diagonally up/left to scroll down/right by 40px each axis;
   // both will scroll because of touch-action
   yield ok(synthesizeNativeTouchDrag(target, 100, 100, -40, -40),
--- a/gfx/layers/apz/test/mochitest/helper_touch_action_complex.html
+++ b/gfx/layers/apz/test/mochitest/helper_touch_action_complex.html
@@ -15,45 +15,45 @@ function checkScroll(target, x, y, desc)
 }
 
 function resetConfiguration(config, testDriver) {
   // Cycle through all the configuration_X elements, setting them to display:none
   // except for when X == config, in which case set it to display:block
   var i = 0;
   while (true) {
     i++;
-    var element = document.getElementById('configuration_' + i);
+    var element = document.getElementById("configuration_" + i);
     if (element == null) {
       if (i <= config) {
         ok(false, "The configuration requested was not encountered!");
       }
       break;
     }
 
     if (i == config) {
-      element.style.display = 'block';
+      element.style.display = "block";
     } else {
-      element.style.display = 'none';
+      element.style.display = "none";
     }
   }
 
   // Also reset the scroll position on the scrollframe
-  var s = document.getElementById('scrollframe');
+  var s = document.getElementById("scrollframe");
   s.scrollLeft = 0;
   s.scrollTop = 0;
 
   return waitForAllPaints(function() {
     flushApzRepaints(testDriver);
   });
 }
 
 function* test(testDriver) {
-  var scrollframe = document.getElementById('scrollframe');
+  var scrollframe = document.getElementById("scrollframe");
 
-  document.body.addEventListener('touchend', testDriver, { passive: true });
+  document.body.addEventListener("touchend", testDriver, { passive: true });
 
   // Helper function for the tests below.
   // Touch-pan configuration |configuration| towards scroll offset (dx, dy) with
   // the pan touching down at (x, y). Check that the final scroll offset is
   // (ex, ey). |desc| is some description string.
   function* scrollAndCheck(configuration, x, y, dx, dy, ex, ey, desc) {
     // Start with a clean slate
     yield resetConfiguration(configuration, testDriver);
@@ -62,52 +62,52 @@ function* test(testDriver) {
     dy = -dy;
     // Do the pan
     yield ok(synthesizeNativeTouchDrag(scrollframe, x, y, dx, dy),
         "Synthesized drag of (" + dx + ", " + dy + ") on configuration " + configuration);
     yield waitForAllPaints(function() {
       flushApzRepaints(testDriver);
     });
     // Check for expected scroll position
-    checkScroll(scrollframe, ex, ey, 'configuration ' + configuration + ' ' + desc);
+    checkScroll(scrollframe, ex, ey, "configuration " + configuration + " " + desc);
   }
 
   // Test configuration_1, which contains two sibling elements that are
   // overlapping. The touch-action from the second sibling (which is on top)
   // should be used for the overlapping area.
-  yield* scrollAndCheck(1,  25,  75, 20,  0, 20,  0, "first element horizontal scroll");
-  yield* scrollAndCheck(1,  25,  75,  0, 50,  0,  0, "first element vertical scroll");
-  yield* scrollAndCheck(1,  75,  75, 50,  0,  0,  0, "overlap horizontal scroll");
-  yield* scrollAndCheck(1,  75,  75,  0, 50,  0, 50, "overlap vertical scroll");
-  yield* scrollAndCheck(1, 125,  75, 20,  0,  0,  0, "second element horizontal scroll");
-  yield* scrollAndCheck(1, 125,  75,  0, 50,  0, 50, "second element vertical scroll");
+  yield* scrollAndCheck(1, 25, 75, 20, 0, 20, 0, "first element horizontal scroll");
+  yield* scrollAndCheck(1, 25, 75, 0, 50, 0, 0, "first element vertical scroll");
+  yield* scrollAndCheck(1, 75, 75, 50, 0, 0, 0, "overlap horizontal scroll");
+  yield* scrollAndCheck(1, 75, 75, 0, 50, 0, 50, "overlap vertical scroll");
+  yield* scrollAndCheck(1, 125, 75, 20, 0, 0, 0, "second element horizontal scroll");
+  yield* scrollAndCheck(1, 125, 75, 0, 50, 0, 50, "second element vertical scroll");
 
   // Test configuration_2, which contains two overlapping elements with a
   // parent/child relationship. The parent has pan-x and the child has pan-y,
   // which means that panning on the parent should work horizontally only, and
   // on the child no panning should occur at all.
-  yield* scrollAndCheck(2, 125, 125, 50, 50,  0,  0, "child scroll");
-  yield* scrollAndCheck(2,  75,  75, 50, 50,  0,  0, "overlap scroll");
-  yield* scrollAndCheck(2,  25,  75,  0, 50,  0,  0, "parent vertical scroll");
-  yield* scrollAndCheck(2,  75,  25, 50,  0, 50,  0, "parent horizontal scroll");
+  yield* scrollAndCheck(2, 125, 125, 50, 50, 0, 0, "child scroll");
+  yield* scrollAndCheck(2, 75, 75, 50, 50, 0, 0, "overlap scroll");
+  yield* scrollAndCheck(2, 25, 75, 0, 50, 0, 0, "parent vertical scroll");
+  yield* scrollAndCheck(2, 75, 25, 50, 0, 50, 0, "parent horizontal scroll");
 
   // Test configuration_3, which is the same as configuration_2, except the child
   // has a rotation transform applied. This forces the event regions on the two
   // elements to be built separately and then get merged.
-  yield* scrollAndCheck(3, 125, 125, 50, 50,  0,  0, "child scroll");
-  yield* scrollAndCheck(3,  75,  75, 50, 50,  0,  0, "overlap scroll");
-  yield* scrollAndCheck(3,  25,  75,  0, 50,  0,  0, "parent vertical scroll");
-  yield* scrollAndCheck(3,  75,  25, 50,  0, 50,  0, "parent horizontal scroll");
+  yield* scrollAndCheck(3, 125, 125, 50, 50, 0, 0, "child scroll");
+  yield* scrollAndCheck(3, 75, 75, 50, 50, 0, 0, "overlap scroll");
+  yield* scrollAndCheck(3, 25, 75, 0, 50, 0, 0, "parent vertical scroll");
+  yield* scrollAndCheck(3, 75, 25, 50, 0, 50, 0, "parent horizontal scroll");
 
   // Test configuration_4 has two elements, one above the other, not overlapping,
   // and the second element is a child of the first. The parent has pan-x, the
   // child has pan-y, but that means panning horizontally on the parent should
   // work and panning in any direction on the child should not do anything.
-  yield* scrollAndCheck(4,  75,  75, 50, 50,  50, 0, "parent diagonal scroll");
-  yield* scrollAndCheck(4,  75, 150, 50, 50,   0, 0, "child diagonal scroll");
+  yield* scrollAndCheck(4, 75, 75, 50, 50, 50, 0, "parent diagonal scroll");
+  yield* scrollAndCheck(4, 75, 150, 50, 50, 0, 0, "child diagonal scroll");
 }
 
 waitUntilApzStable()
 .then(runContinuation(test))
 .then(subtestDone);
 
   </script>
 </head>
--- a/gfx/layers/apz/test/mochitest/helper_touch_action_regions.html
+++ b/gfx/layers/apz/test/mochitest/helper_touch_action_regions.html
@@ -10,106 +10,107 @@
   <script type="application/javascript">
 
 function failure(e) {
   ok(false, "This event listener should not have triggered: " + e.type);
 }
 
 function listener(callback) {
   return function(e) {
-    ok(e.type == 'touchstart', "The touchstart event handler was triggered after snapshotting completed");
+    ok(e.type == "touchstart", "The touchstart event handler was triggered after snapshotting completed");
     setTimeout(callback, 0);
   };
 }
 
 // This helper function provides a way for the child process to synchronously
 // check how many touch events the chrome process main-thread has processed. This
 // function can be called with three values: 'start', 'report', and 'end'.
 // The 'start' invocation sets up the listeners, and should be invoked before
 // the touch events of interest are generated. This should only be called once.
 // This returns true on success, and false on failure.
 // The 'report' invocation can be invoked multiple times, and returns an object
 // (in JSON string format) containing the counters.
 // The 'end' invocation tears down the listeners, and should be invoked once
 // at the end to clean up. Returns true on success, false on failure.
+/* eslint-env mozilla/frame-script */
 function chromeTouchEventCounter(operation) {
   function chromeProcessCounter() {
-    addMessageListener('start', function() {
-      ChromeUtils.import('resource://gre/modules/Services.jsm');
-      var topWin = Services.wm.getMostRecentWindow('navigator:browser');
-      if (typeof topWin.eventCounts != 'undefined') {
-        dump('Found pre-existing eventCounts object on the top window!\n');
+    addMessageListener("start", function() {
+      ChromeUtils.import("resource://gre/modules/Services.jsm");
+      var topWin = Services.wm.getMostRecentWindow("navigator:browser");
+      if (typeof topWin.eventCounts != "undefined") {
+        dump("Found pre-existing eventCounts object on the top window!\n");
         return false;
       }
-      topWin.eventCounts = { 'touchstart': 0, 'touchmove': 0, 'touchend': 0 };
+      topWin.eventCounts = { "touchstart": 0, "touchmove": 0, "touchend": 0 };
       topWin.counter = function(e) {
         topWin.eventCounts[e.type]++;
-      }
+      };
 
-      topWin.addEventListener('touchstart', topWin.counter, { passive: true });
-      topWin.addEventListener('touchmove', topWin.counter, { passive: true });
-      topWin.addEventListener('touchend', topWin.counter, { passive: true });
+      topWin.addEventListener("touchstart", topWin.counter, { passive: true });
+      topWin.addEventListener("touchmove", topWin.counter, { passive: true });
+      topWin.addEventListener("touchend", topWin.counter, { passive: true });
 
       return true;
     });
 
-    addMessageListener('report', function() {
-      ChromeUtils.import('resource://gre/modules/Services.jsm');
-      var topWin = Services.wm.getMostRecentWindow('navigator:browser');
+    addMessageListener("report", function() {
+      ChromeUtils.import("resource://gre/modules/Services.jsm");
+      var topWin = Services.wm.getMostRecentWindow("navigator:browser");
       return JSON.stringify(topWin.eventCounts);
     });
 
-    addMessageListener('end', function() {
-      ChromeUtils.import('resource://gre/modules/Services.jsm');
-      var topWin = Services.wm.getMostRecentWindow('navigator:browser');
-      if (typeof topWin.eventCounts == 'undefined') {
-        dump('The eventCounts object was not found on the top window!\n');
+    addMessageListener("end", function() {
+      ChromeUtils.import("resource://gre/modules/Services.jsm");
+      var topWin = Services.wm.getMostRecentWindow("navigator:browser");
+      if (typeof topWin.eventCounts == "undefined") {
+        dump("The eventCounts object was not found on the top window!\n");
         return false;
       }
-      topWin.removeEventListener('touchstart', topWin.counter);
-      topWin.removeEventListener('touchmove', topWin.counter);
-      topWin.removeEventListener('touchend', topWin.counter);
+      topWin.removeEventListener("touchstart", topWin.counter);
+      topWin.removeEventListener("touchmove", topWin.counter);
+      topWin.removeEventListener("touchend", topWin.counter);
       delete topWin.counter;
       delete topWin.eventCounts;
       return true;
     });
   }
 
-  if (typeof chromeTouchEventCounter.chromeHelper == 'undefined') {
+  if (typeof chromeTouchEventCounter.chromeHelper == "undefined") {
     // This is the first time chromeTouchEventCounter is being called; do initialization
     chromeTouchEventCounter.chromeHelper = SpecialPowers.loadChromeScript(chromeProcessCounter);
-    ApzCleanup.register(function() { chromeTouchEventCounter.chromeHelper.destroy() });
+    ApzCleanup.register(function() { chromeTouchEventCounter.chromeHelper.destroy(); });
   }
 
   return chromeTouchEventCounter.chromeHelper.sendSyncMessage(operation, "");
 }
 
 // Simple wrapper that waits until the chrome process has seen |count| instances
 // of the |eventType| event. Returns true on success, and false if 10 seconds
 // go by without the condition being satisfied.
 function waitFor(eventType, count) {
   var start = Date.now();
-  while (JSON.parse(chromeTouchEventCounter('report'))[eventType] != count) {
+  while (JSON.parse(chromeTouchEventCounter("report"))[eventType] != count) {
     if (Date.now() - start > 10000) {
       // It's taking too long, let's abort
       return false;
     }
   }
   return true;
 }
 
 function RunAfterProcessedQueuedInputEvents(aCallback) {
   let tm = SpecialPowers.Services.tm;
   tm.dispatchToMainThread(aCallback, SpecialPowers.Ci.nsIRunnablePriority.PRIORITY_INPUT);
 }
 
 function* test(testDriver) {
   // The main part of this test should run completely before the child process'
   // main-thread deals with the touch event, so check to make sure that happens.
-  document.body.addEventListener('touchstart', failure, { passive: true });
+  document.body.addEventListener("touchstart", failure, { passive: true });
 
   // What we want here is to synthesize all of the touch events (from this code in
   // the child process), and have the chrome process generate and process them,
   // but not allow the events to be dispatched back into the child process until
   // later. This allows us to ensure that the APZ in the chrome process is not
   // waiting for the child process to send notifications upon processing the
   // events. If it were doing so, the APZ would block and this test would fail.
 
@@ -170,44 +171,44 @@ function* test(testDriver) {
   // That's what the chromeTouchEventCounter business is all about. The sync
   // polling looks bad but in practice only ends up needing to poll once or
   // twice before the condition is satisfied, and as an extra precaution we add
   // a time guard so it fails after 10s of polling.
 
   // So, here we go...
 
   // Set up the chrome process touch listener
-  ok(chromeTouchEventCounter('start'), "Chrome touch counter registered");
+  ok(chromeTouchEventCounter("start"), "Chrome touch counter registered");
 
   // Set up the child process events and callbacks
-  var scroller = document.getElementById('scroller');
+  var scroller = document.getElementById("scroller");
   synthesizeNativeTouch(scroller, 10, 110, SpecialPowers.DOMWindowUtils.TOUCH_CONTACT, null, 0);
   RunAfterProcessedQueuedInputEvents(testDriver);
-  for (var i = 1; i < 10; i++) {
+  for (let i = 1; i < 10; i++) {
     synthesizeNativeTouch(scroller, 10, 110 - (i * 10), SpecialPowers.DOMWindowUtils.TOUCH_CONTACT, null, 0);
     RunAfterProcessedQueuedInputEvents(testDriver);
   }
   synthesizeNativeTouch(scroller, 10, 10, SpecialPowers.DOMWindowUtils.TOUCH_REMOVE, null, 0);
   RunAfterProcessedQueuedInputEvents(testDriver);
   ok(true, "Finished setting up event queue");
 
   // Get our baseline snapshot
   var rect = rectRelativeToScreen(scroller);
   var lastSnapshot = getSnapshot(rect);
   ok(true, "Got baseline snapshot");
   var numDifferentSnapshotPairs = 0;
 
   yield; // this will tell the chrome process to synthesize the touchstart event
          // and then we wait to make sure it got processed:
-  ok(waitFor('touchstart', 1), "Touchstart processed in chrome process");
+  ok(waitFor("touchstart", 1), "Touchstart processed in chrome process");
 
   // Loop through the touchmove events
-  for (var i = 1; i < 10; i++) {
+  for (let i = 1; i < 10; i++) {
     yield;
-    ok(waitFor('touchmove', i), "Touchmove processed in chrome process");
+    ok(waitFor("touchmove", i), "Touchmove processed in chrome process");
 
     // Take a snapshot after each touch move event. This forces
     // a composite each time, even we don't get a vsync in this
     // interval.
     var snapshot = getSnapshot(rect);
     if (lastSnapshot != snapshot) {
       numDifferentSnapshotPairs += 1;
     }
@@ -220,30 +221,30 @@ function* test(testDriver) {
   // of delay between APZ processing a touch event and the compositor
   // applying the async scroll (bug 1375949), by the end of the gesture
   // the snapshot should have changed.
   ok(numDifferentSnapshotPairs > 0,
      "The number of different snapshot pairs was " + numDifferentSnapshotPairs);
 
   // Wait for the touchend as well, to clear all pending testDriver resumes
   yield;
-  ok(waitFor('touchend', 1), "Touchend processed in chrome process");
+  ok(waitFor("touchend", 1), "Touchend processed in chrome process");
 
   // Clean up the chrome process hooks
-  chromeTouchEventCounter('end');
+  chromeTouchEventCounter("end");
 
   // Now we are going to release our grip on the child process main thread,
   // so that all the DOM events that were queued up can be processed. We
   // register a touchstart listener to make sure this happens.
-  document.body.removeEventListener('touchstart', failure);
+  document.body.removeEventListener("touchstart", failure);
   var listenerFunc = listener(testDriver);
-  document.body.addEventListener('touchstart', listenerFunc, { passive: true });
-  dump('done registering listener, going to yield\n');
+  document.body.addEventListener("touchstart", listenerFunc, { passive: true });
+  dump("done registering listener, going to yield\n");
   yield;
-  document.body.removeEventListener('touchstart', listenerFunc);
+  document.body.removeEventListener("touchstart", listenerFunc);
 }
 
 if (SpecialPowers.isMainProcess()) {
   // This is probably android, where everything is single-process. The
   // test structure depends on e10s, so the test won't run properly on
   // this platform. Skip it
   ok(true, "Skipping test because it is designed to run from the content process");
   subtestDone();
--- a/gfx/layers/apz/test/mochitest/helper_touch_action_zero_opacity_bug1500864.html
+++ b/gfx/layers/apz/test/mochitest/helper_touch_action_zero_opacity_bug1500864.html
@@ -4,19 +4,19 @@
   <meta charset="utf-8">
   <meta name="viewport" content="width=device-width; initial-scale=1.0">
   <title>Touch-action on a zero-opacity element</title>
   <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
   <script type="application/javascript" src="apz_test_utils.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
   <script type="application/javascript">
 function* test(testDriver) {
-  var target = document.getElementById('target');
+  var target = document.getElementById("target");
 
-  document.body.addEventListener('touchend', testDriver, { passive: true });
+  document.body.addEventListener("touchend", testDriver, { passive: true });
 
   // drag the page up to scroll down by 50px
   yield ok(synthesizeNativeTouchDrag(target, 10, 100, 0, -50),
       "Synthesized native vertical drag, waiting for touch-end event...");
 
   yield flushApzRepaints(testDriver);
 
   is(window.scrollX, 0, "X scroll offset didn't change");
--- a/gfx/layers/apz/test/mochitest/test_bug1151663.html
+++ b/gfx/layers/apz/test/mochitest/test_bug1151663.html
@@ -22,16 +22,16 @@ https://bugzilla.mozilla.org/show_bug.cg
           .then(function() {
             w = window.open("helper_bug1151663.html", "_blank");
           });
     }
 
     function finishTest() {
       w.close();
       SimpleTest.finish();
-    };
+    }
 
   </script>
 </head>
 <body>
   <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1151663">Mozilla Bug 1151663</a>
 </body>
 </html>
--- a/gfx/layers/apz/test/mochitest/test_bug1151667.html
+++ b/gfx/layers/apz/test/mochitest/test_bug1151667.html
@@ -40,22 +40,22 @@ https://bugzilla.mozilla.org/show_bug.cg
 <!-- This makes sure the page is also scrollable, so it (rather than the subframe)
      is considered the primary async-scrollable frame, and so the subframe isn't
      layerized upon page load. -->
 <div id="page-content"></div>
 <pre id="test">
 <script type="application/javascript">
 
 function startTest() {
-  var subframe = document.getElementById('subframe');
+  var subframe = document.getElementById("subframe");
   synthesizeNativeWheelAndWaitForScrollEvent(subframe, 100, 150, 0, -10, continueTest);
 }
 
 function continueTest() {
-  var subframe = document.getElementById('subframe');
+  var subframe = document.getElementById("subframe");
   is(subframe.scrollTop > 0, true, "We should have scrolled the subframe down");
   is(document.documentElement.scrollTop, 0, "We should not have scrolled the page");
   SimpleTest.finish();
 }
 
 SimpleTest.waitForExplicitFinish();
 waitUntilApzStable().then(startTest);
 
--- a/gfx/layers/apz/test/mochitest/test_bug1253683.html
+++ b/gfx/layers/apz/test/mochitest/test_bug1253683.html
@@ -17,31 +17,31 @@ https://bugzilla.mozilla.org/show_bug.cg
  <div id="container" style="height: 500px; overflow:scroll">
   <pre id="no_layer" style="background-color: #f5f5f5; margin: 15px; padding: 15px; margin-top: 100px; border: 1px solid #eee; overflow:scroll">sample code here</pre>
   <div style="height: 5000px">spacer to make the 'container' div the root scrollable element</div>
  </div>
 <pre id="test">
 <script type="application/javascript">
 
 function* test(testDriver) {
-  var container = document.getElementById('container');
-  var no_layer = document.getElementById('no_layer');
+  var container = document.getElementById("container");
+  var no_layer = document.getElementById("no_layer");
 
   // Check initial state
   is(container.scrollTop, 0, "Initial scrollY should be 0");
-  ok(!isLayerized('no_layer'), "initially 'no_layer' should not be layerized");
+  ok(!isLayerized("no_layer"), "initially 'no_layer' should not be layerized");
 
   // Scrolling over outer1 should layerize outer1, but not inner1.
   yield moveMouseAndScrollWheelOver(no_layer, 10, 10, testDriver, true);
   yield waitForAllPaints(function() {
     flushApzRepaints(testDriver);
   });
 
   ok(container.scrollTop > 0, "We should have scrolled the body");
-  ok(!isLayerized('no_layer'), "no_layer should still not be layerized");
+  ok(!isLayerized("no_layer"), "no_layer should still not be layerized");
 }
 
 if (isApzEnabled()) {
   SimpleTest.waitForExplicitFinish();
 
   // Turn off displayport expiry so that we don't miss failures where the
   // displayport is set and expired before we check for layerization.
   // Also enable APZ test logging, since we use that data to determine whether
--- a/gfx/layers/apz/test/mochitest/test_bug1277814.html
+++ b/gfx/layers/apz/test/mochitest/test_bug1277814.html
@@ -9,18 +9,18 @@ https://bugzilla.mozilla.org/show_bug.cg
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
   <script type="application/javascript" src="apz_test_utils.js"></script>
   <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
   <script type="application/javascript">
     function* test(testDriver) {
       // Trigger the buggy scenario
-      var subframe = document.getElementById('bug1277814-div');
-      subframe.classList.add('a');
+      var subframe = document.getElementById("bug1277814-div");
+      subframe.classList.add("a");
 
       // The transform change is animated, so let's step through 1s of animation
       var utils = SpecialPowers.getDOMWindowUtils(window);
       for (var i = 0; i < 60; i++) {
         utils.advanceTimeAndRefresh(16);
       }
       utils.restoreNormalRefresh();
 
@@ -45,18 +45,18 @@ https://bugzilla.mozilla.org/show_bug.cg
       // calculation for this scroll frame to go wrong, causing it not to
       // become layerized.
       contentTestData = convertTestData(contentTestData);
       var foundIt = false;
       for (var seqNo in contentTestData.paints) {
         var paint = contentTestData.paints[seqNo];
         for (var scrollId in paint) {
           var scrollFrame = paint[scrollId];
-          if ('contentDescription' in scrollFrame &&
-              scrollFrame['contentDescription'].includes('bug1277814-div')) {
+          if ("contentDescription" in scrollFrame &&
+              scrollFrame.contentDescription.includes("bug1277814-div")) {
             foundIt = true;
           }
         }
       }
       SimpleTest.ok(foundIt, "expected to find APZ test data for bug1277814-div");
     }
 
     if (isApzEnabled()) {
--- a/gfx/layers/apz/test/mochitest/test_bug1304689-2.html
+++ b/gfx/layers/apz/test/mochitest/test_bug1304689-2.html
@@ -27,20 +27,20 @@ https://bugzilla.mozilla.org/show_bug.cg
         width: 100%;
         z-index: 99;
     }
   </style>
   <script type="application/javascript">
 
 function* test(testDriver) {
   var utils = SpecialPowers.DOMWindowUtils;
-  var elm = document.getElementById('outer');
+  var elm = document.getElementById("outer");
 
   // Set margins on the element, to ensure it is layerized
-  utils.setDisplayPortMarginsForElement(0, 0, 0, 0, elm, /*priority*/ 1);
+  utils.setDisplayPortMarginsForElement(0, 0, 0, 0, elm, /* priority*/ 1);
   yield waitForAllPaints(function() {
     flushApzRepaints(testDriver);
   });
 
   // Take control of the refresh driver
   utils.advanceTimeAndRefresh(0);
 
   // Start a smooth-scroll animation in the compositor and let it go a few
@@ -50,17 +50,17 @@ function* test(testDriver) {
   utils.advanceTimeAndRefresh(16);
   utils.advanceTimeAndRefresh(16);
   utils.advanceTimeAndRefresh(16);
   utils.advanceTimeAndRefresh(16);
 
   // Do another scroll update but also do a frame reconstruction within the same
   // tick of the refresh driver.
   elm.scrollTop = 100;
-  elm.classList.add('contentBefore');
+  elm.classList.add("contentBefore");
 
   // Now let everything settle and all the animations run out
   for (var i = 0; i < 60; i++) {
     utils.advanceTimeAndRefresh(16);
   }
   utils.restoreNormalRefresh();
 
   yield flushApzRepaints(testDriver);
--- a/gfx/layers/apz/test/mochitest/test_bug1304689.html
+++ b/gfx/layers/apz/test/mochitest/test_bug1304689.html
@@ -30,20 +30,20 @@ https://bugzilla.mozilla.org/show_bug.cg
         width: 100%;
         z-index: 99;
     }
   </style>
   <script type="application/javascript">
 
 function* test(testDriver) {
   var utils = SpecialPowers.DOMWindowUtils;
-  var elm = document.getElementById('outer');
+  var elm = document.getElementById("outer");
 
   // Set margins on the element, to ensure it is layerized
-  utils.setDisplayPortMarginsForElement(0, 0, 0, 0, elm, /*priority*/ 1);
+  utils.setDisplayPortMarginsForElement(0, 0, 0, 0, elm, /* priority*/ 1);
   yield waitForAllPaints(function() {
     flushApzRepaints(testDriver);
   });
 
   // Take control of the refresh driver
   utils.advanceTimeAndRefresh(0);
 
   // Start a smooth-scroll animation in the compositor and let it go a few
@@ -52,19 +52,19 @@ function* test(testDriver) {
   elm.scrollTop = 10;
   utils.advanceTimeAndRefresh(16);
   utils.advanceTimeAndRefresh(16);
   utils.advanceTimeAndRefresh(16);
   utils.advanceTimeAndRefresh(16);
 
   // Do another scroll update but also do a frame reconstruction within the same
   // tick of the refresh driver.
-  elm.classList.add('instant');
+  elm.classList.add("instant");
   elm.scrollTop = 100;
-  elm.classList.add('contentBefore');
+  elm.classList.add("contentBefore");
 
   // Now let everything settle and all the animations run out
   for (var i = 0; i < 60; i++) {
     utils.advanceTimeAndRefresh(16);
   }
   utils.restoreNormalRefresh();
 
   yield flushApzRepaints(testDriver);
--- a/gfx/layers/apz/test/mochitest/test_bug1464568.html
+++ b/gfx/layers/apz/test/mochitest/test_bug1464568.html
@@ -5,19 +5,19 @@
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript" src="apz_test_utils.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
   <script type="application/javascript">
     if (isApzEnabled()) {
       SimpleTest.waitForExplicitFinish();
 
       const subtests = [
-        { file: 'helper_bug1464568_transform.html',
+        { file: "helper_bug1464568_transform.html",
           prefs: [["apz.test.logging_enabled", true]] },
-        { file: 'helper_bug1464568_opacity.html',
+        { file: "helper_bug1464568_opacity.html",
           prefs: [["apz.test.logging_enabled", true]] },
       ];
       // Run the actual test in its own window, because it requires that the
       // root APZC be scrollable. Mochitest pages themselves often run
       // inside an iframe which means we have no control over the root APZC.
       window.onload = () => {
         runSubtestsSeriallyInFreshWindows(subtests)
         .then(SimpleTest.finish, SimpleTest.finish);
--- a/gfx/layers/apz/test/mochitest/test_bug982141.html
+++ b/gfx/layers/apz/test/mochitest/test_bug982141.html
@@ -23,16 +23,16 @@ https://bugzilla.mozilla.org/show_bug.cg
           w = window.open("helper_bug982141.html", "_blank");
         });
       };
     }
 
     function finishTest() {
       w.close();
       SimpleTest.finish();
-    };
+    }
 
   </script>
 </head>
 <body>
   <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=982141">Mozilla Bug 982141</a>
 </body>
 </html>
--- a/gfx/layers/apz/test/mochitest/test_frame_reconstruction.html
+++ b/gfx/layers/apz/test/mochitest/test_frame_reconstruction.html
@@ -150,17 +150,17 @@
    </ol>
   </div>
  </div>
 </div>
 
 <pre id="test">
 <script type="application/javascript">
 function* test(testDriver) {
-  var elm = document.getElementsByClassName('inner')[0];
+  var elm = document.getElementsByClassName("inner")[0];
   elm.scrollTop = 0;
   yield flushApzRepaints(testDriver);
 
   // Take over control of the refresh driver and compositor
   var utils = SpecialPowers.DOMWindowUtils;
   utils.advanceTimeAndRefresh(0);
 
   // Kick off an APZ smooth-scroll to 0,200
@@ -173,23 +173,23 @@ function* test(testDriver) {
   yield flushApzRepaints(testDriver);
   ok(elm.scrollTop > 0, "APZ animation in progress, scrollTop is now " + elm.scrollTop);
   ok(elm.scrollTop < 200, "APZ animation not yet completed, scrollTop is now " + elm.scrollTop);
 
   var frameReconstructionTriggered = 0;
   // Register the listener that triggers the frame reconstruction
   elm.onscroll = function() {
     // Do the reconstruction
-    elm.parentNode.classList.add('contentBefore');
+    elm.parentNode.classList.add("contentBefore");
     frameReconstructionTriggered++;
     // schedule a thing to undo the changes above
     setTimeout(function() {
-      elm.parentNode.classList.remove('contentBefore');
+      elm.parentNode.classList.remove("contentBefore");
     }, 0);
-  }
+  };
 
   // and do a few more frames of the animation, this should trigger the listener
   // and the frame reconstruction
   utils.advanceTimeAndRefresh(16);
   utils.advanceTimeAndRefresh(16);
   yield flushApzRepaints(testDriver);
   ok(elm.scrollTop < 200, "APZ animation not yet completed, scrollTop is now " + elm.scrollTop);
   ok(frameReconstructionTriggered > 0, "Frame reconstruction triggered, reconstruction triggered " + frameReconstructionTriggered + " times");
--- a/gfx/layers/apz/test/mochitest/test_group_hittest.html
+++ b/gfx/layers/apz/test/mochitest/test_group_hittest.html
@@ -18,29 +18,29 @@ var prefs = [
   // the tests more robust in terms of testing all the different cross-platform
   // variations.
   ["layout.scrollbars.always-layerize-track", true],
   // We need this pref to allow the synthetic mouse events to propagate to APZ,
   // and to allow the MozMouseHittest event in particular to be dispatched to
   // APZ as a MouseInput so the hit result is recorded.
   ["test.events.async.enabled", true],
   // Turns on APZTestData logging which we use to obtain the hit test results.
-  ["apz.test.logging_enabled", true]
+  ["apz.test.logging_enabled", true],
 ];
 
 var subtests = [
-  {'file': 'helper_hittest_basic.html', 'prefs': prefs},
-  {'file': 'helper_hittest_fixed_in_scrolled_transform.html', 'prefs': prefs},
-  {'file': 'helper_hittest_float_bug1434846.html', 'prefs': prefs},
-  {'file': 'helper_hittest_float_bug1443518.html', 'prefs': prefs},
-  {'file': 'helper_hittest_checkerboard.html', 'prefs': prefs},
-  {'file': 'helper_hittest_backface_hidden.html', 'prefs': prefs},
-  {'file': 'helper_hittest_touchaction.html', 'prefs': prefs},
-  {'file': 'helper_hittest_nested_transforms_bug1459696.html', 'prefs': prefs},
-  {'file': 'helper_hittest_sticky_bug1478304.html', 'prefs': prefs}
+  {"file": "helper_hittest_basic.html", "prefs": prefs},
+  {"file": "helper_hittest_fixed_in_scrolled_transform.html", "prefs": prefs},
+  {"file": "helper_hittest_float_bug1434846.html", "prefs": prefs},
+  {"file": "helper_hittest_float_bug1443518.html", "prefs": prefs},
+  {"file": "helper_hittest_checkerboard.html", "prefs": prefs},
+  {"file": "helper_hittest_backface_hidden.html", "prefs": prefs},
+  {"file": "helper_hittest_touchaction.html", "prefs": prefs},
+  {"file": "helper_hittest_nested_transforms_bug1459696.html", "prefs": prefs},
+  {"file": "helper_hittest_sticky_bug1478304.html", "prefs": prefs},
 ];
 
 if (isApzEnabled()) {
   SimpleTest.waitForExplicitFinish();
   window.onload = function() {
     runSubtestsSeriallyInFreshWindows(subtests)
     .then(SimpleTest.finish, SimpleTest.finish);
   };
--- a/gfx/layers/apz/test/mochitest/test_group_keyboard.html
+++ b/gfx/layers/apz/test/mochitest/test_group_keyboard.html
@@ -4,17 +4,17 @@
   <meta charset="utf-8">
   <title>Various keyboard scrolling tests</title>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript" src="apz_test_utils.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
   <script type="application/javascript">
 
 var subtests = [
-  {'file': 'helper_key_scroll.html', prefs: [["apz.test.logging_enabled", true],
+  {"file": "helper_key_scroll.html", prefs: [["apz.test.logging_enabled", true],
                                              ["test.events.async.enabled", true]]},
 ];
 
     if (isKeyApzEnabled()) {
       SimpleTest.waitForExplicitFinish();
       window.onload = function() {
         runSubtestsSeriallyInFreshWindows(subtests)
         .then(SimpleTest.finish, SimpleTest.finish);
--- a/gfx/layers/apz/test/mochitest/test_group_mouseevents.html
+++ b/gfx/layers/apz/test/mochitest/test_group_mouseevents.html
@@ -5,38 +5,38 @@
   <title>Various mouse tests that spawn in new windows</title>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript" src="apz_test_utils.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
   <script type="application/javascript">
 
 var subtests = [
   // Sanity test to synthesize a mouse click
-  {'file': 'helper_click.html?dtc=false'},
+  {"file": "helper_click.html?dtc=false"},
   // Same as above, but with a dispatch-to-content region that exercises the
   // main-thread notification codepaths for mouse events
-  {'file': 'helper_click.html?dtc=true'},
+  {"file": "helper_click.html?dtc=true"},
   // Sanity test for click but with some mouse movement between the down and up
-  {'file': 'helper_drag_click.html'},
+  {"file": "helper_drag_click.html"},
   // Test for dragging on a fake-scrollbar element that scrolls the page
-  {'file': 'helper_drag_scroll.html'},
+  {"file": "helper_drag_scroll.html"},
   // Test for dragging the scrollbar with a fixed-pos element overlaying it
-  {'file': 'helper_bug1346632.html'},
+  {"file": "helper_bug1346632.html"},
   // Test for scrollbar-dragging on a scrollframe that's inactive
-  {'file': 'helper_bug1326290.html'},
+  {"file": "helper_bug1326290.html"},
   // Test for scrollbar-dragging on a scrollframe inside an SVGEffects
-  {'file': 'helper_bug1331693.html'},
+  {"file": "helper_bug1331693.html"},
   // Test for scrollbar-dragging on a transformed scrollframe inside a fixed-pos item
-  {'file': 'helper_bug1462961.html'},
+  {"file": "helper_bug1462961.html"},
   // Scrollbar dragging where we exercise the snapback behaviour by moving the
   // mouse away from the scrollbar during drag
-  {'file': 'helper_scrollbar_snap_bug1501062.html'},
+  {"file": "helper_scrollbar_snap_bug1501062.html"},
   // Tests for scrollbar-dragging on scrollframes inside nested transforms
-  {'file': 'helper_bug1490393.html'},
-  {'file': 'helper_bug1490393-2.html'}
+  {"file": "helper_bug1490393.html"},
+  {"file": "helper_bug1490393-2.html"},
 ];
 
 if (isApzEnabled()) {
   SimpleTest.waitForExplicitFinish();
   window.onload = function() {
     runSubtestsSeriallyInFreshWindows(subtests)
     .then(SimpleTest.finish, SimpleTest.finish);
   };
--- a/gfx/layers/apz/test/mochitest/test_group_overrides.html
+++ b/gfx/layers/apz/test/mochitest/test_group_overrides.html
@@ -6,25 +6,25 @@
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript" src="apz_test_utils.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
   <script type="application/javascript">
 
 var prefs = [
   // turn off smooth scrolling so that we don't have to wait for
   // APZ animations to finish before sampling the scroll offset
-  ['general.smoothScroll', false],
+  ["general.smoothScroll", false],
   // Increase the content response timeout because these tests do preventDefault
   // and we want to make sure APZ actually waits for them.
-  ['apz.content_response_timeout', 10000],
-]
+  ["apz.content_response_timeout", 10000],
+];
 
 var subtests = [
-  {'file': 'helper_override_root.html', 'prefs': prefs},
-  {'file': 'helper_override_subdoc.html', 'prefs': prefs},
+  {"file": "helper_override_root.html", "prefs": prefs},
+  {"file": "helper_override_subdoc.html", "prefs": prefs},
 ];
 
 if (isApzEnabled()) {
   SimpleTest.waitForExplicitFinish();
   window.onload = function() {
     runSubtestsSeriallyInFreshWindows(subtests)
     .then(SimpleTest.finish, SimpleTest.finish);
   };
--- a/gfx/layers/apz/test/mochitest/test_group_pointerevents.html
+++ b/gfx/layers/apz/test/mochitest/test_group_pointerevents.html
@@ -9,22 +9,22 @@ https://bugzilla.mozilla.org/show_bug.cg
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript" src="apz_test_utils.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
   <script type="application/javascript">
 
   let isWindows = navigator.platform.indexOf("Win") == 0;
   let enablePE = ["dom.w3c_pointer_events.enabled", true];
   var subtests = [
-    {'file': 'helper_bug1285070.html', 'prefs': [enablePE]},
-    {'file': 'helper_bug1299195.html', 'prefs': [enablePE]},
-    {'file': 'helper_bug1414336.html', 'prefs': [enablePE,
-      ["apz.test.fails_with_native_injection", isWindows]
+    {"file": "helper_bug1285070.html", "prefs": [enablePE]},
+    {"file": "helper_bug1299195.html", "prefs": [enablePE]},
+    {"file": "helper_bug1414336.html", "prefs": [enablePE,
+      ["apz.test.fails_with_native_injection", isWindows],
     ]},
-    {'file': 'helper_bug1502010_unconsumed_pan.html', 'prefs': [enablePE]}
+    {"file": "helper_bug1502010_unconsumed_pan.html", "prefs": [enablePE]},
   ];
 
   if (isApzEnabled()) {
     SimpleTest.waitForExplicitFinish();
     window.onload = function() {
       runSubtestsSeriallyInFreshWindows(subtests)
       .then(SimpleTest.finish, SimpleTest.finish);
     };
--- a/gfx/layers/apz/test/mochitest/test_group_touchevents-2.html
+++ b/gfx/layers/apz/test/mochitest/test_group_touchevents-2.html
@@ -14,32 +14,32 @@ var isWindows = getPlatform() == "window
 var subtests = [
   // Taps on media elements to make sure the touchend event is delivered
   // properly. We increase the long-tap timeout to ensure it doesn't get trip
   // during the tap.
   // Also this test (on Windows) cannot satisfy the OS requirement of providing
   // an injected touch event every 100ms, because it waits for a paint between
   // the touchstart and the touchend, so we have to use the "fake injection"
   // code instead.
-  {'file': 'helper_bug1162771.html', 'prefs': [["ui.click_hold_context_menus.delay", 10000],
+  {"file": "helper_bug1162771.html", "prefs": [["ui.click_hold_context_menus.delay", 10000],
                                                ["apz.test.fails_with_native_injection", isWindows]]},
 
   // As with the previous test, this test cannot inject touch events every 100ms
   // because it waits for a long-tap, so we have to use the "fake injection" code
   // instead.
-  {'file': 'helper_long_tap.html', 'prefs': [["apz.test.fails_with_native_injection", isWindows]]},
+  {"file": "helper_long_tap.html", "prefs": [["apz.test.fails_with_native_injection", isWindows]]},
 
   // For the following tests, we want to make sure APZ doesn't wait for a content
   // response that is never going to arrive. To detect this we set the content response
   // timeout to a day, so that the entire test times out and fails if APZ does
   // end up waiting.
-  {'file': 'helper_tap_passive.html', 'prefs': [["apz.content_response_timeout", 24 * 60 * 60 * 1000],
+  {"file": "helper_tap_passive.html", "prefs": [["apz.content_response_timeout", 24 * 60 * 60 * 1000],
                                                 ["apz.test.fails_with_native_injection", isWindows]]},
 
-  {'file': 'helper_tap_default_passive.html', 'prefs': [["apz.content_response_timeout", 24 * 60 * 60 * 1000],
+  {"file": "helper_tap_default_passive.html", "prefs": [["apz.content_response_timeout", 24 * 60 * 60 * 1000],
                                                         ["apz.test.fails_with_native_injection", isWindows],
                                                         ["dom.event.default_to_passive_touch_listeners", true]]},
 
   // Add new subtests to test_group_touch_events-4.html, not this file.
 ];
 
 if (isApzEnabled()) {
   ok(window.TouchEvent, "Check if TouchEvent is supported (it should be, the test harness forces it on everywhere)");
--- a/gfx/layers/apz/test/mochitest/test_group_touchevents-3.html
+++ b/gfx/layers/apz/test/mochitest/test_group_touchevents-3.html
@@ -12,24 +12,24 @@
 var touch_action_prefs = [
   ...getPrefs("TOUCH_EVENTS:PAN"),
   ["layout.css.touch_action.enabled", true],
   ["apz.test.fails_with_native_injection", getPlatform() == "windows"],
 ];
 
 var subtests = [
   // Simple test to exercise touch-action CSS property
-  {'file': 'helper_touch_action.html', 'prefs': touch_action_prefs},
+  {"file": "helper_touch_action.html", "prefs": touch_action_prefs},
   // More complex touch-action tests, with overlapping regions and such
-  {'file': 'helper_touch_action_complex.html', 'prefs': touch_action_prefs},
+  {"file": "helper_touch_action_complex.html", "prefs": touch_action_prefs},
   // Tests that touch-action CSS properties are handled in APZ without waiting
   // on the main-thread, when possible
-  {'file': 'helper_touch_action_regions.html', 'prefs': touch_action_prefs},
+  {"file": "helper_touch_action_regions.html", "prefs": touch_action_prefs},
   // Tests that touch-action inside zero-opacity items are respected
-  {'file': 'helper_touch_action_zero_opacity_bug1500864.html', 'prefs': touch_action_prefs},
+  {"file": "helper_touch_action_zero_opacity_bug1500864.html", "prefs": touch_action_prefs},
 
   // Add new subtests to test_group_touchevents-4.html, not this file (exceptions
   // may be made for quick-running tests that need the touch-action prefs)
 ];
 
 if (isApzEnabled()) {
   ok(window.TouchEvent, "Check if TouchEvent is supported (it should be, the test harness forces it on everywhere)");
   if (getPlatform() == "android") {
--- a/gfx/layers/apz/test/mochitest/test_group_touchevents-4.html
+++ b/gfx/layers/apz/test/mochitest/test_group_touchevents-4.html
@@ -6,17 +6,17 @@
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
   <script type="application/javascript" src="apz_test_utils.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
   <script type="application/javascript">
 
 var subtests = [
   // clicking on element with :active::after CSS property
-  {'file': 'helper_bug1473108.html'},
+  {"file": "helper_bug1473108.html"},
   // Add new subtests here. If this starts timing out because it's taking too
   // long, create a test_group_touchevents-5.html file. Refer to 1423011#c57
   // for more details.
 ];
 
 if (isApzEnabled()) {
   ok(window.TouchEvent, "Check if TouchEvent is supported (it should be, the test harness forces it on everywhere)");
   if (getPlatform() == "android") {
--- a/gfx/layers/apz/test/mochitest/test_group_touchevents.html
+++ b/gfx/layers/apz/test/mochitest/test_group_touchevents.html
@@ -9,29 +9,29 @@
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
   <script type="application/javascript">
 
 var basic_pan_prefs = getPrefs("TOUCH_EVENTS:PAN");
 
 var subtests = [
   // Simple tests to exercise basic panning behaviour
   // The visual viewport isn't yet enabled by default and we want to test its events, too.
-  {'file': 'helper_basic_pan.html', 'prefs': basic_pan_prefs.concat([["dom.visualviewport.enabled", true]])},
-  {'file': 'helper_div_pan.html', 'prefs': basic_pan_prefs},
-  {'file': 'helper_iframe_pan.html', 'prefs': basic_pan_prefs},
+  {"file": "helper_basic_pan.html", "prefs": basic_pan_prefs.concat([["dom.visualviewport.enabled", true]])},
+  {"file": "helper_div_pan.html", "prefs": basic_pan_prefs},
+  {"file": "helper_iframe_pan.html", "prefs": basic_pan_prefs},
 
   // Simple test to exercise touch-tapping behaviour
-  {'file': 'helper_tap.html'},
+  {"file": "helper_tap.html"},
   // Tapping, but with a full-zoom applied
-  {'file': 'helper_tap_fullzoom.html'},
+  {"file": "helper_tap_fullzoom.html"},
 
   // For the following two tests, disable displayport suppression to make sure it
   // doesn't interfere with the test by scheduling paints non-deterministically.
-  {'file': 'helper_scrollto_tap.html?true', 'prefs': [["apz.paint_skipping.enabled", true]], 'dp_suppression': false},
-  {'file': 'helper_scrollto_tap.html?false', 'prefs': [["apz.paint_skipping.enabled", false]], 'dp_suppression': false},
+  {"file": "helper_scrollto_tap.html?true", "prefs": [["apz.paint_skipping.enabled", true]], "dp_suppression": false},
+  {"file": "helper_scrollto_tap.html?false", "prefs": [["apz.paint_skipping.enabled", false]], "dp_suppression": false},
 
   // Add new subtests to test_group_touch_events-4.html, not this file.
 ];
 
 if (isApzEnabled()) {
   ok(window.TouchEvent, "Check if TouchEvent is supported (it should be, the test harness forces it on everywhere)");
   if (getPlatform() == "android") {
     // This has a lot of subtests, and Android emulators are slow.
--- a/gfx/layers/apz/test/mochitest/test_group_wheelevents.html
+++ b/gfx/layers/apz/test/mochitest/test_group_wheelevents.html
@@ -6,46 +6,46 @@
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript" src="apz_test_utils.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
   <script type="application/javascript">
 
 var prefs = [
   // turn off smooth scrolling so that we don't have to wait for
   // APZ animations to finish before sampling the scroll offset
-  ['general.smoothScroll', false],
+  ["general.smoothScroll", false],
   // ensure that any mouse movement will trigger a new wheel transaction,
   // because in this test we move the mouse a bunch and want to recalculate
   // the target APZC after each such movement.
-  ['mousewheel.transaction.ignoremovedelay', 0],
-  ['mousewheel.transaction.timeout', 0]
-]
+  ["mousewheel.transaction.ignoremovedelay", 0],
+  ["mousewheel.transaction.timeout", 0],
+];
 
 // For helper_scroll_over_scrollbar, we need to set a pref to force
 // layerization of the scrollbar track to reproduce the bug being fixed.
 // Otherwise, the bug only manifests with overlay scrollbars on macOS,
 // or in a XUL RCD, both of which are hard to materialize in a test.
-var scrollbar_prefs = prefs.slice();  // make a copy
+var scrollbar_prefs = prefs.slice(); // make a copy
 scrollbar_prefs.push(["layout.scrollbars.always-layerize-track", true]);
 
 // For helper_overscroll_behavior_bug1425573, we need to set the APZ content
 // response timeout to 0, so we exercise the fallback codepath.
-var timeout_prefs = prefs.slice();  // make a copy
+var timeout_prefs = prefs.slice(); // make a copy
 timeout_prefs.push(["apz.content_response_timeout", 0]);
 
 var subtests = [
-  {'file': 'helper_scroll_on_position_fixed.html', 'prefs': prefs},
-  {'file': 'helper_bug1271432.html', 'prefs': prefs},
-  {'file': 'helper_overscroll_behavior_bug1425573.html', 'prefs': timeout_prefs},
-  {'file': 'helper_overscroll_behavior_bug1425603.html', 'prefs': prefs},
-  {'file': 'helper_overscroll_behavior_bug1494440.html', 'prefs': prefs},
-  {'file': 'helper_scroll_inactive_perspective.html', 'prefs': prefs},
-  {'file': 'helper_scroll_inactive_zindex.html', 'prefs': prefs},
-  {'file': 'helper_scroll_over_scrollbar.html', 'prefs': scrollbar_prefs},
-  {'file': 'helper_scroll_tables_perspective.html', 'prefs': prefs},
+  {"file": "helper_scroll_on_position_fixed.html", "prefs": prefs},
+  {"file": "helper_bug1271432.html", "prefs": prefs},
+  {"file": "helper_overscroll_behavior_bug1425573.html", "prefs": timeout_prefs},
+  {"file": "helper_overscroll_behavior_bug1425603.html", "prefs": prefs},
+  {"file": "helper_overscroll_behavior_bug1494440.html", "prefs": prefs},
+  {"file": "helper_scroll_inactive_perspective.html", "prefs": prefs},
+  {"file": "helper_scroll_inactive_zindex.html", "prefs": prefs},
+  {"file": "helper_scroll_over_scrollbar.html", "prefs": scrollbar_prefs},
+  {"file": "helper_scroll_tables_perspective.html", "prefs": prefs},
 ];
 
 if (isApzEnabled()) {
   SimpleTest.waitForExplicitFinish();
   window.onload = function() {
     runSubtestsSeriallyInFreshWindows(subtests)
     .then(SimpleTest.finish, SimpleTest.finish);
   };
--- a/gfx/layers/apz/test/mochitest/test_group_zoom.html
+++ b/gfx/layers/apz/test/mochitest/test_group_zoom.html
@@ -47,21 +47,21 @@ var prefs = [
 // random delays during testing.
 var doubletap_prefs = [
   ...prefs,
   ["ui.click_hold_context_menus.delay", 10000],
   ["apz.max_tap_time", 10000],
 ];
 
 var subtests = [
-  {'file': 'helper_bug1280013.html', 'prefs': prefs},
-  {'file': 'helper_basic_zoom.html', 'prefs': prefs},
-  {'file': 'helper_zoomed_pan.html', 'prefs': prefs},
-  {'file': 'helper_fixed_position_scroll_hittest.html', 'prefs': prefs},
-  {'file': 'helper_basic_doubletap_zoom.html', 'prefs': doubletap_prefs},
+  {"file": "helper_bug1280013.html", "prefs": prefs},
+  {"file": "helper_basic_zoom.html", "prefs": prefs},
+  {"file": "helper_zoomed_pan.html", "prefs": prefs},
+  {"file": "helper_fixed_position_scroll_hittest.html", "prefs": prefs},
+  {"file": "helper_basic_doubletap_zoom.html", "prefs": doubletap_prefs},
 ];
 
 if (isApzEnabled()) {
   // This has a lot of subtests, and Android emulators are slow.
   SimpleTest.requestLongerTimeout(2);
   SimpleTest.waitForExplicitFinish();
   window.onload = function() {
     runSubtestsSeriallyInFreshWindows(subtests)
--- a/gfx/layers/apz/test/mochitest/test_interrupted_reflow.html
+++ b/gfx/layers/apz/test/mochitest/test_interrupted_reflow.html
@@ -581,33 +581,33 @@ function getAsyncScrollOffsets(aPaintsTo
       childIsLayerized = true;
     }
     if (!childIsLayerized) {
       continue;
     }
 
     ok(rcd.children.length == 1, "Root content APZC has exactly one child");
     var scroll = rcd.children[0].asyncScrollOffset;
-    var pieces = scroll.replace(/[()\s]+/g, '').split(',');
+    var pieces = scroll.replace(/[()\s]+/g, "").split(",");
     is(pieces.length, 2, "expected string of form (x,y)");
     offsets.push({ x: parseInt(pieces[0]),
                    y: parseInt(pieces[1]) });
   }
   return offsets;
 }
 
 function* test(testDriver) {
   var utils = SpecialPowers.DOMWindowUtils;
 
   // The APZ test data accumulates whenever a test turns it on. We just want
   // the data for this test, so we check how many frames are already recorded
   // and discard those later.
   var framesToSkip = SpecialPowers.getDOMWindowUtils(window).getCompositorAPZTestData().paints.length;
 
-  var elm = document.getElementsByClassName('inner')[0];
+  var elm = document.getElementsByClassName("inner")[0];
   // Set a zero-margin displayport to ensure that the element is async-scrollable
   // otherwise on Fennec it is not
   utils.setDisplayPortMarginsForElement(0, 0, 0, 0, elm, 0);
 
   var maxScroll = elm.scrollTopMax;
   elm.scrollTop = maxScroll;
   yield waitForAllPaints(function() {
     flushApzRepaints(testDriver);
@@ -619,21 +619,21 @@ function* test(testDriver) {
   // Force the next reflow to get interrupted
   utils.forceReflowInterrupt();
 
   // Make a change that triggers frame reconstruction, and then tick the refresh
   // driver so that layout processes the pending restyles and then runs an
   // interruptible reflow. That reflow *will* be interrupted (because of the flag
   // we set above), and we should end up with a transient 0,0 scroll offset
   // being sent to the compositor.
-  elm.parentNode.classList.add('contentBefore');
+  elm.parentNode.classList.add("contentBefore");
   utils.advanceTimeAndRefresh(0);
   // On android, and maybe non-e10s platforms generally, we need to manually
   // kick the paint to send the layer transaction to the compositor.
-  yield waitForAllPaints(function() { setTimeout(testDriver, 0) });
+  yield waitForAllPaints(function() { setTimeout(testDriver, 0); });
 
   // Read the main-thread scroll offset; although this is temporarily 0,0 that
   // temporary value is never exposed to content - instead reading this value
   // will finish doing the interrupted reflow from above and then report the
   // correct scroll offset.
   is(elm.scrollTop, maxScroll, "Main-thread scroll position was restored");
 
   // .. and now flush everything to make sure the state gets pushed over to the
--- a/gfx/layers/apz/test/mochitest/test_layerization.html
+++ b/gfx/layers/apz/test/mochitest/test_layerization.html
@@ -69,130 +69,130 @@ const DISPLAYPORT_EXPIRY = 100;
 function asyncWrapper(testDriver) {
   return function() {
     setTimeout(testDriver, 0);
   };
 }
 
 function* test(testDriver) {
   // Initially, nothing should be layerized.
-  ok(!isLayerized('outer1'), "initially 'outer1' should not be layerized");
-  ok(!isLayerized('inner1'), "initially 'inner1' should not be layerized");
-  ok(!isLayerized('outer2'), "initially 'outer2' should not be layerized");
-  ok(!isLayerized('inner2'), "initially 'inner2' should not be layerized");
-  ok(!isLayerized('outer3'), "initially 'outer3' should not be layerized");
-  ok(!isLayerized('inner3'), "initially 'inner3' should not be layerized");
-  ok(!isLayerized('outer4'), "initially 'outer4' should not be layerized");
-  ok(!isLayerized('inner4'), "initially 'inner4' should not be layerized");
+  ok(!isLayerized("outer1"), "initially 'outer1' should not be layerized");
+  ok(!isLayerized("inner1"), "initially 'inner1' should not be layerized");
+  ok(!isLayerized("outer2"), "initially 'outer2' should not be layerized");
+  ok(!isLayerized("inner2"), "initially 'inner2' should not be layerized");
+  ok(!isLayerized("outer3"), "initially 'outer3' should not be layerized");
+  ok(!isLayerized("inner3"), "initially 'inner3' should not be layerized");
+  ok(!isLayerized("outer4"), "initially 'outer4' should not be layerized");
+  ok(!isLayerized("inner4"), "initially 'inner4' should not be layerized");
 
   // Scrolling over outer1 should layerize outer1, but not inner1.
-  yield scrollWheelOver(document.getElementById('outer1'), true, testDriver);
-  ok(isLayerized('outer1'), "scrolling 'outer1' should cause it to be layerized");
-  ok(!isLayerized('inner1'), "scrolling 'outer1' should not cause 'inner1' to be layerized");
+  yield scrollWheelOver(document.getElementById("outer1"), true, testDriver);
+  ok(isLayerized("outer1"), "scrolling 'outer1' should cause it to be layerized");
+  ok(!isLayerized("inner1"), "scrolling 'outer1' should not cause 'inner1' to be layerized");
 
   // Scrolling over inner2 should layerize both outer2 and inner2.
-  yield scrollWheelOver(document.getElementById('inner2'), true, testDriver);
-  ok(isLayerized('inner2'), "scrolling 'inner2' should cause it to be layerized");
-  ok(isLayerized('outer2'), "scrolling 'inner2' should also cause 'outer2' to be layerized");
+  yield scrollWheelOver(document.getElementById("inner2"), true, testDriver);
+  ok(isLayerized("inner2"), "scrolling 'inner2' should cause it to be layerized");
+  ok(isLayerized("outer2"), "scrolling 'inner2' should also cause 'outer2' to be layerized");
 
   // The second half of the test repeats the same checks as the first half,
   // but with an iframe as the outer scrollable frame.
 
   // Scrolling over outer3 should layerize outer3, but not inner3.
-  yield scrollWheelOver(document.getElementById('outer3').contentDocument.documentElement, true, testDriver);
-  ok(isLayerized('outer3'), "scrolling 'outer3' should cause it to be layerized");
-  ok(!isLayerized('inner3'), "scrolling 'outer3' should not cause 'inner3' to be layerized");
+  yield scrollWheelOver(document.getElementById("outer3").contentDocument.documentElement, true, testDriver);
+  ok(isLayerized("outer3"), "scrolling 'outer3' should cause it to be layerized");
+  ok(!isLayerized("inner3"), "scrolling 'outer3' should not cause 'inner3' to be layerized");
 
   // Scrolling over outer4 should layerize both outer4 and inner4.
-  yield scrollWheelOver(document.getElementById('outer4').contentDocument.getElementById('inner4'), true, testDriver);
-  ok(isLayerized('inner4'), "scrolling 'inner4' should cause it to be layerized");
-  ok(isLayerized('outer4'), "scrolling 'inner4' should also cause 'outer4' to be layerized");
+  yield scrollWheelOver(document.getElementById("outer4").contentDocument.getElementById("inner4"), true, testDriver);
+  ok(isLayerized("inner4"), "scrolling 'inner4' should cause it to be layerized");
+  ok(isLayerized("outer4"), "scrolling 'inner4' should also cause 'outer4' to be layerized");
 
   // Now we enable displayport expiry, and verify that things are still
   // layerized as they were before.
   yield SpecialPowers.pushPrefEnv({"set": [["apz.displayport_expiry_ms", DISPLAYPORT_EXPIRY]]}, testDriver);
-  ok(isLayerized('outer1'), "outer1 is still layerized after enabling expiry");
-  ok(!isLayerized('inner1'), "inner1 is still not layerized after enabling expiry");
-  ok(isLayerized('outer2'), "outer2 is still layerized after enabling expiry");
-  ok(isLayerized('inner2'), "inner2 is still layerized after enabling expiry");
-  ok(isLayerized('outer3'), "outer3 is still layerized after enabling expiry");
-  ok(!isLayerized('inner3'), "inner3 is still not layerized after enabling expiry");
-  ok(isLayerized('outer4'), "outer4 is still layerized after enabling expiry");
-  ok(isLayerized('inner4'), "inner4 is still layerized after enabling expiry");
+  ok(isLayerized("outer1"), "outer1 is still layerized after enabling expiry");
+  ok(!isLayerized("inner1"), "inner1 is still not layerized after enabling expiry");
+  ok(isLayerized("outer2"), "outer2 is still layerized after enabling expiry");
+  ok(isLayerized("inner2"), "inner2 is still layerized after enabling expiry");
+  ok(isLayerized("outer3"), "outer3 is still layerized after enabling expiry");
+  ok(!isLayerized("inner3"), "inner3 is still not layerized after enabling expiry");
+  ok(isLayerized("outer4"), "outer4 is still layerized after enabling expiry");
+  ok(isLayerized("inner4"), "inner4 is still layerized after enabling expiry");
 
   // Now we trigger a scroll on some of the things still layerized, so that
   // the displayport expiry gets triggered.
 
   // Expire displayport with scrolling on outer1
-  yield scrollWheelOver(document.getElementById('outer1'), true, testDriver);
+  yield scrollWheelOver(document.getElementById("outer1"), true, testDriver);
   yield waitForAllPaints(function() {
     flushApzRepaints(testDriver);
   });
   yield setTimeout(testDriver, DISPLAYPORT_EXPIRY);
   yield waitForAllPaints(asyncWrapper(testDriver));
-  ok(!isLayerized('outer1'), "outer1 is no longer layerized after displayport expiry");
-  ok(!isLayerized('inner1'), "inner1 is still not layerized after displayport expiry");
+  ok(!isLayerized("outer1"), "outer1 is no longer layerized after displayport expiry");
+  ok(!isLayerized("inner1"), "inner1 is still not layerized after displayport expiry");
 
   // Expire displayport with scrolling on inner2
-  yield scrollWheelOver(document.getElementById('inner2'), true, testDriver);
+  yield scrollWheelOver(document.getElementById("inner2"), true, testDriver);
   yield waitForAllPaints(function() {
     flushApzRepaints(testDriver);
   });
   // Once the expiry elapses, it will trigger expiry on outer2, so we check
   // both, one at a time.
   yield setTimeout(testDriver, DISPLAYPORT_EXPIRY);
   yield waitForAllPaints(asyncWrapper(testDriver));
-  ok(!isLayerized('inner2'), "inner2 is no longer layerized after displayport expiry");
+  ok(!isLayerized("inner2"), "inner2 is no longer layerized after displayport expiry");
   yield setTimeout(testDriver, DISPLAYPORT_EXPIRY);
   yield waitForAllPaints(asyncWrapper(testDriver));
-  ok(!isLayerized('outer2'), "outer2 got de-layerized with inner2");
+  ok(!isLayerized("outer2"), "outer2 got de-layerized with inner2");
 
   // Scroll on inner3. inner3 isn't layerized, and this will cause it to
   // get layerized, but it will also trigger displayport expiration for inner3
   // which will eventually trigger displayport expiration on inner3 and outer3.
   // Note that the displayport expiration might actually happen before the wheel
   // input is processed in the compositor (see bug 1246480 comment 3), and so
   // we make sure not to wait for a scroll event here, since it may never fire.
   // However, if we do get a scroll event while waiting for the expiry, we need
   // to restart the expiry timer because the displayport expiry got reset. There's
   // no good way that I can think of to deterministically avoid doing this.
-  let inner3 = document.getElementById('outer3').contentDocument.getElementById('inner3');
+  let inner3 = document.getElementById("outer3").contentDocument.getElementById("inner3");
   yield scrollWheelOver(inner3, false, testDriver);
   yield waitForAllPaints(function() {
     flushApzRepaints(testDriver);
   });
   var timerId = setTimeout(testDriver, DISPLAYPORT_EXPIRY);
   var timeoutResetter = function() {
     ok(true, "Got a scroll event; resetting timer...");
     clearTimeout(timerId);
     setTimeout(testDriver, DISPLAYPORT_EXPIRY);
     // by not updating timerId we ensure that this listener resets the timeout
     // at most once.
   };
-  inner3.addEventListener('scroll', timeoutResetter);
+  inner3.addEventListener("scroll", timeoutResetter);
   yield; // wait for the setTimeout to elapse
-  inner3.removeEventListener('scroll', timeoutResetter);
+  inner3.removeEventListener("scroll", timeoutResetter);
 
   yield waitForAllPaints(asyncWrapper(testDriver));
-  ok(!isLayerized('inner3'), "inner3 becomes unlayerized after expiry");
+  ok(!isLayerized("inner3"), "inner3 becomes unlayerized after expiry");
   yield setTimeout(testDriver, DISPLAYPORT_EXPIRY);
   yield waitForAllPaints(asyncWrapper(testDriver));
-  ok(!isLayerized('outer3'), "outer3 is no longer layerized after inner3 triggered expiry");
+  ok(!isLayerized("outer3"), "outer3 is no longer layerized after inner3 triggered expiry");
 
   // Scroll outer4 and wait for the expiry. It should NOT get expired because
   // inner4 is still layerized
-  yield scrollWheelOver(document.getElementById('outer4').contentDocument.documentElement, true, testDriver);
+  yield scrollWheelOver(document.getElementById("outer4").contentDocument.documentElement, true, testDriver);
   yield waitForAllPaints(function() {
     flushApzRepaints(testDriver);
   });
   // Wait for the expiry to elapse
   yield setTimeout(testDriver, DISPLAYPORT_EXPIRY);
   yield waitForAllPaints(asyncWrapper(testDriver));
-  ok(isLayerized('inner4'), "inner4 is still layerized because it never expired");
-  ok(isLayerized('outer4'), "outer4 is still layerized because inner4 is still layerized");
+  ok(isLayerized("inner4"), "inner4 is still layerized because it never expired");
+  ok(isLayerized("outer4"), "outer4 is still layerized because inner4 is still layerized");
 }
 
 if (isApzEnabled()) {
   SimpleTest.waitForExplicitFinish();
   SimpleTest.requestFlakyTimeout("we are testing code that measures an actual timeout");
   SimpleTest.expectAssertions(0, 8); // we get a bunch of "ASSERTION: Bounds computation mismatch" sometimes (bug 1232856)
 
   // Disable smooth scrolling, because it results in long-running scroll
--- a/gfx/layers/apz/test/mochitest/test_relative_update.html
+++ b/gfx/layers/apz/test/mochitest/test_relative_update.html
@@ -34,39 +34,39 @@ https://bugzilla.mozilla.org/show_bug.cg
     <div id="frame">
         <div id="first"></div>
         <div id="second"></div>
     </div>
 <script type="application/javascript">
 function* test(testDriver) {
   var utils = SpecialPowers.DOMWindowUtils;
 
-  var elm = document.querySelector('#frame');
+  var elm = document.querySelector("#frame");
   // Set a zero-margin displayport to ensure that the element is async-scrollable
   utils.setDisplayPortMarginsForElement(0, 0, 0, 0, elm, 0);
   elm.scrollTop = 0;
 
   // Take over control of the refresh driver and don't allow a layer
   // transaction until the main thread and APZ have processed two different
   // scrolls.
   yield waitForApzFlushedRepaints(testDriver);
   utils.advanceTimeAndRefresh(0);
 
   // Scroll instantly on the main thread by (0, 100).
   elm.scrollBy(0, 100);
 
   // We are not using `scroll-behavior`
-  is(elm.scrollTop, 100, 'the main thread scroll should be instant');
+  is(elm.scrollTop, 100, "the main thread scroll should be instant");
 
   // Dispatch a wheel event to have APZ scroll by (0, 8). Wait for the wheel
   // event to ensure that the APZ has processed the scroll.
   yield synthesizeNativeWheelAndWaitForWheelEvent(elm, 40, 40, 0, -8, testDriver);
 
   // APZ should be handling the wheel scroll
-  is(elm.scrollTop, 100, 'the wheel scroll should be handled by APZ');
+  is(elm.scrollTop, 100, "the wheel scroll should be handled by APZ");
 
   // Restore control of the refresh driver, allowing the main thread to send a
   // layer transaction containing the (0, 100) scroll.
   utils.restoreNormalRefresh();
 
   // Wait for all paints to finish and for the main thread to receive pending
   // repaint requests with the scroll offset from the wheel event.
   yield waitForApzFlushedRepaints(testDriver);
--- a/gfx/layers/apz/test/mochitest/test_scroll_inactive_bug1190112.html
+++ b/gfx/layers/apz/test/mochitest/test_scroll_inactive_bug1190112.html
@@ -482,59 +482,59 @@ 37	<br>
 38	<br>
 39	<br>
 40	<br>
 
 </p>
 </div>
 <script clss="testbody" type="text/javascript">
 function ScrollTops() {
-  this.outerScrollTop = document.getElementById('iframe-body').scrollTop;
-  this.innerScrollTop = document.getElementById('subframe').scrollTop;
+  this.outerScrollTop = document.getElementById("iframe-body").scrollTop;
+  this.innerScrollTop = document.getElementById("subframe").scrollTop;
 }
 
 var DefaultEvent = {
   deltaMode: WheelEvent.DOM_DELTA_LINE,
   deltaX: 0, deltaY: 1,
   lineOrPageDeltaX: 0, lineOrPageDeltaY: 1,
 };
 
 function test() {
-  var subframe = document.getElementById('subframe');
+  var subframe = document.getElementById("subframe");
   var oldpos = new ScrollTops();
-  sendWheelAndPaint(subframe, 10, 10, DefaultEvent, function () {
+  sendWheelAndPaint(subframe, 10, 10, DefaultEvent, function() {
     var newpos = new ScrollTops();
     ok(oldpos.outerScrollTop == newpos.outerScrollTop, "viewport should not have scrolled");
     ok(oldpos.innerScrollTop != newpos.innerScrollTop, "subframe should have scrolled");
     doOuterScroll(subframe, newpos);
   });
 }
 
 function doOuterScroll(subframe, oldpos) {
-  var outer = document.getElementById('iframe-body');
-  sendWheelAndPaint(outer, 20, 5, DefaultEvent, function () {
+  var outer = document.getElementById("iframe-body");
+  sendWheelAndPaint(outer, 20, 5, DefaultEvent, function() {
     var newpos = new ScrollTops();
     ok(oldpos.outerScrollTop != newpos.outerScrollTop, "viewport should have scrolled");
     ok(oldpos.innerScrollTop == newpos.innerScrollTop, "subframe should not have scrolled");
     doInnerScrollAgain(subframe, newpos);
   });
 }
 
 function doInnerScrollAgain(subframe, oldpos) {
-  sendWheelAndPaint(subframe, 10, 10, DefaultEvent, function () {
+  sendWheelAndPaint(subframe, 10, 10, DefaultEvent, function() {
     var newpos = new ScrollTops();
     ok(oldpos.outerScrollTop == newpos.outerScrollTop, "viewport should not have scrolled");
     ok(oldpos.innerScrollTop != newpos.innerScrollTop, "subframe should have scrolled");
     SimpleTest.finish();
   });
 }
 
 SimpleTest.waitForExplicitFinish();
 
-pushPrefs([['general.smoothScroll', false],
-           ['mousewheel.transaction.timeout', 0],
-           ['mousewheel.transaction.ignoremovedelay', 0]])
+pushPrefs([["general.smoothScroll", false],
+           ["mousewheel.transaction.timeout", 0],
+           ["mousewheel.transaction.ignoremovedelay", 0]])
 .then(waitUntilApzStable)
 .then(test);
 
 </script>
 </body>
 </html>
--- a/gfx/layers/apz/test/mochitest/test_scroll_inactive_flattened_frame.html
+++ b/gfx/layers/apz/test/mochitest/test_scroll_inactive_flattened_frame.html
@@ -12,37 +12,37 @@
 <div id="container" style="height: 300px; width: 600px; overflow: auto; background: yellow">
  <div id="outer" style="height: 400px; width: 500px; overflow: auto; background: black">
   <div id="inner" style="mix-blend-mode: screen; height: 800px; overflow: auto; background: purple">
   </div>
  </div>
 </div>
 <script class="testbody" type="text/javascript">
 function test() {
-  var container = document.getElementById('container');
-  var outer = document.getElementById('outer');
-  var inner = document.getElementById('inner');
+  var container = document.getElementById("container");
+  var outer = document.getElementById("outer");
+  var inner = document.getElementById("inner");
   var outerScrollTop = outer.scrollTop;
   var containerScrollTop = container.scrollTop;
   var event = {
     deltaMode: WheelEvent.DOM_DELTA_LINE,
     deltaX: 0,
     deltaY: 10,
     lineOrPageDeltaX: 0,
     lineOrPageDeltaY: 10,
   };
-  sendWheelAndPaint(inner, 20, 30, event, function () {
+  sendWheelAndPaint(inner, 20, 30, event, function() {
     ok(container.scrollTop == containerScrollTop, "container scrollframe should not have scrolled");
     ok(outer.scrollTop > outerScrollTop, "nested scrollframe should have scrolled");
     SimpleTest.finish();
   });
 }
 
 SimpleTest.waitForExplicitFinish();
 
-pushPrefs([['general.smoothScroll', false],
-           ['mousewheel.transaction.timeout', 1000000]])
+pushPrefs([["general.smoothScroll", false],
+           ["mousewheel.transaction.timeout", 1000000]])
 .then(waitUntilApzStable)
 .then(test);
 
 </script>
 </body>
 </html>
--- a/gfx/layers/apz/test/mochitest/test_scroll_subframe_scrollbar.html
+++ b/gfx/layers/apz/test/mochitest/test_scroll_subframe_scrollbar.html
@@ -64,23 +64,23 @@ var DefaultEvent = {
   deltaMode: WheelEvent.DOM_DELTA_LINE,
   deltaX: 0, deltaY: 1,
   lineOrPageDeltaX: 0, lineOrPageDeltaY: 1,
 };
 
 var ScrollbarWidth = 0;
 
 function test() {
-  var subframe = document.getElementById('subframe');
+  var subframe = document.getElementById("subframe");
   var oldClientWidth = subframe.clientWidth;
 
-  subframe.style.overflow = 'auto';
+  subframe.style.overflow = "auto";
   subframe.getBoundingClientRect();
 
-  waitForAllPaintsFlushed(function () {
+  waitForAllPaintsFlushed(function() {
     ScrollbarWidth = oldClientWidth - subframe.clientWidth;
     if (!ScrollbarWidth) {
       // Probably we have overlay scrollbars - abort the test.
       ok(true, "overlay scrollbars - skipping test");
       SimpleTest.finish();
       return;
     }
 
@@ -93,25 +93,25 @@ function testScrolling(subframe) {
   // Send a wheel event roughly to where we think the trackbar is. We pick a
   // point at the bottom, in the middle of the trackbar, where the slider is
   // unlikely to be (since it starts at the top).
   var posX = subframe.clientWidth + (ScrollbarWidth / 2);
   var posY = subframe.clientHeight - 20;
 
   var oldScrollTop = subframe.scrollTop;
 
-  sendWheelAndPaint(subframe, posX, posY, DefaultEvent, function () {
+  sendWheelAndPaint(subframe, posX, posY, DefaultEvent, function() {
     ok(subframe.scrollTop > oldScrollTop, "subframe should have scrolled");
     SimpleTest.finish();
   });
 }
 
 SimpleTest.waitForExplicitFinish();
 
-pushPrefs([['general.smoothScroll', false],
-           ['mousewheel.transaction.timeout', 0],
-           ['mousewheel.transaction.ignoremovedelay', 0]])
+pushPrefs([["general.smoothScroll", false],
+           ["mousewheel.transaction.timeout", 0],
+           ["mousewheel.transaction.ignoremovedelay", 0]])
 .then(waitUntilApzStable)
 .then(test);
 
 </script>
 </body>
 </html>
--- a/gfx/layers/apz/test/mochitest/test_smoothness.html
+++ b/gfx/layers/apz/test/mochitest/test_smoothness.html
@@ -57,21 +57,21 @@
     window.onload = function() {
       var apzEnabled = SpecialPowers.getBoolPref("layers.async-pan-zoom.enabled");
       if (!apzEnabled) {
         SimpleTest.ok(true, "APZ not enabled, skipping test");
         SimpleTest.finish();
       }
 
       SpecialPowers.pushPrefEnv({
-        "set" : [
-          [testPref, true]
-        ]
+        "set": [
+          [testPref, true],
+        ],
       }, startTest);
-    }
+    };
     </script>
 </head>
 
 <body>
   <div id="content">
   </div>
 </body>
 </html>
--- a/gfx/layers/apz/test/mochitest/test_touch_listeners_impacting_wheel.html
+++ b/gfx/layers/apz/test/mochitest/test_touch_listeners_impacting_wheel.html
@@ -34,22 +34,22 @@ function takeSnapshots(e) {
   // Note that we want this function to take less time than the content response
   // timeout, otherwise the scrolling will start even if we haven't returned,
   // and that would invalidate purpose of the test.
   var start = Date.now();
   var lastSnapshot = null;
   var success = false;
 
   // Get the position of the 'content' div relative to the screen
-  var rect = rectRelativeToScreen(document.getElementById('content'));
+  var rect = rectRelativeToScreen(document.getElementById("content"));
 
   for (var i = 0; i < 10; i++) {
     SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(16);
     var snapshot = getSnapshot(rect);
-    //dump("Took snapshot " + snapshot + "\n"); // this might help with debugging
+    // dump("Took snapshot " + snapshot + "\n"); // this might help with debugging
 
     if (lastSnapshot && lastSnapshot != snapshot) {
       ok(true, "Found some different pixels in snapshot " + i + " compared to previous");
       success = true;
     }
     lastSnapshot = snapshot;
   }
   ok(success, "Found some snapshots that were different");
@@ -59,25 +59,25 @@ function takeSnapshots(e) {
   // because scroll events are dispatched on the main thread, which we've been
   // hogging with the code above. At this point we restore the normal refresh
   // behaviour and let the main thread go back to C++ code, so the scroll events
   // fire and we unwind from the main test continuation.
   SpecialPowers.DOMWindowUtils.restoreNormalRefresh();
 }
 
 function* test(testDriver) {
-  var box = document.getElementById('box');
+  var box = document.getElementById("box");
 
   // Ensure the div is layerized by scrolling it
   yield moveMouseAndScrollWheelOver(box, 10, 10, testDriver);
 
-  box.addEventListener('touchstart', function(e) {
+  box.addEventListener("touchstart", function(e) {
     ok(false, "This should never be run");
   });
-  box.addEventListener('wheel', takeSnapshots, { capture: false, passive: true });
+  box.addEventListener("wheel", takeSnapshots, { capture: false, passive: true });
 
   // Let the event regions and layerization propagate to the APZ
   yield waitForAllPaints(function() {
     flushApzRepaints(testDriver);
   });
 
   yield synthesizeNativeMouseMoveAndWaitForMoveEvent(box, 10, 10, testDriver);
 
--- a/gfx/layers/apz/test/mochitest/test_wheel_scroll.html
+++ b/gfx/layers/apz/test/mochitest/test_wheel_scroll.html
@@ -56,38 +56,37 @@ https://bugzilla.mozilla.org/show_bug.cg
   </div>
 </div>
 <pre id="test">
 <script type="application/javascript">
 
 var rotation = 0;
 var rotationAdjusted = false;
 
-var incrementForMode = function (mode) {
+var incrementForMode = function(mode) {
   switch (mode) {
     case WheelEvent.DOM_DELTA_PIXEL: return 1;
     case WheelEvent.DOM_DELTA_LINE: return 15;
     case WheelEvent.DOM_DELTA_PAGE: return 400;
   }
   return 0;
 };
 
-document.getElementById("scrollbox").addEventListener("wheel", function (e) {
+document.getElementById("scrollbox").addEventListener("wheel", function(e) {
   rotation += e.deltaY * incrementForMode(e.deltaMode) * 0.2;
   document.getElementById("circle").style.transform = "rotate(" + rotation + "deg)";
   rotationAdjusted = true;
   e.preventDefault();
 });
 
 function* test(testDriver) {
-  var content = document.getElementById('content');
-  for (i = 0; i < 300; i++) { // enough iterations that we would scroll to the bottom of 'content'
+  var content = document.getElementById("content");
+  for (let i = 0; i < 300; i++) { // enough iterations that we would scroll to the bottom of 'content'
     yield synthesizeNativeWheelAndWaitForWheelEvent(content, 100, 150, 0, -5, testDriver);
   }
-  var scrollbox = document.getElementById('scrollbox');
   is(content.scrollTop > 0, true, "We should have scrolled down somewhat");
   is(content.scrollTop < content.scrollTopMax, true, "We should not have scrolled to the bottom of the scrollframe");
   is(rotationAdjusted, true, "The rotation should have been adjusted");
 }
 
 SimpleTest.waitForExplicitFinish();
 
 // If we allow smooth scrolling the "smooth" scrolling may cause the page to
--- a/gfx/layers/apz/test/mochitest/test_wheel_transactions.html
+++ b/gfx/layers/apz/test/mochitest/test_wheel_transactions.html
@@ -41,19 +41,19 @@ https://bugzilla.mozilla.org/show_bug.cg
 <pre id="test">
 <script type="application/javascript">
 
 function scrollWheelOver(element, deltaY, testDriver) {
   synthesizeNativeWheelAndWaitForScrollEvent(element, 10, 10, 0, deltaY, testDriver);
 }
 
 function* test(testDriver) {
-  var outer = document.getElementById('outer-frame');
-  var inner = document.getElementById('inner-frame');
-  var innerContent = document.getElementById('inner-content');
+  var outer = document.getElementById("outer-frame");
+  var inner = document.getElementById("inner-frame");
+  var innerContent = document.getElementById("inner-content");
 
   // Register a wheel event listener that records the target of
   // the last wheel event, so that we can make assertions about it.
   var lastWheelTarget;
   var wheelTargetRecorder = function(e) { lastWheelTarget = e.target; };
   window.addEventListener("wheel", wheelTargetRecorder);
 
   // Scroll |outer| to the bottom.
--- a/gfx/layers/layerviewer/layerTreeView.js
+++ b/gfx/layers/layerviewer/layerTreeView.js
@@ -31,19 +31,19 @@ function parseDisplayList(lines) {
   var objectAtIndentation = {
     "-1": root,
   };
 
   for (var i = 0; i < lines.length; i++) {
     var line = lines[i];
 
     var layerObject = {
-      line: line,
+      line,
       children: [],
-    }
+    };
     if (!root) {
       root = layerObject;
     }
 
     var matches = line.match("(\\s*)(\\w+)\\sp=(\\w+)\\sf=(.*?)\\((.*?)\\)\\s(z=(\\w+)\\s)?(.*?)?( layer=(\\w+))?$");
     if (!matches) {
       dump("Failed to match: " + line + "\n");
       continue;
@@ -65,56 +65,54 @@ function parseDisplayList(lines) {
     if (matches[10]) { // WrapList don't provide a layer
       layerObject.layer = matches[10];
     }
     layerObject.rest = rest;
 
     // the content node name doesn't have a prefix, this makes the parsing easier
     rest = "content" + rest;
 
-    var fields = {};
     var nesting = 0;
     var startIndex;
     var lastSpace = -1;
-    var lastFieldStart = -1;
     for (var j = 0; j < rest.length; j++) {
-      if (rest.charAt(j) == '(') {
+      if (rest.charAt(j) == "(") {
         nesting++;
         if (nesting == 1) {
           startIndex = j;
         }
-      } else if (rest.charAt(j) == ')') {
+      } else if (rest.charAt(j) == ")") {
         nesting--;
         if (nesting == 0) {
           var name = rest.substring(lastSpace + 1, startIndex);
           var value = rest.substring(startIndex + 1, j);
 
-          var rectMatches = value.match("^(.*?),(.*?),(.*?),(.*?)$")
+          var rectMatches = value.match("^(.*?),(.*?),(.*?),(.*?)$");
           if (rectMatches) {
             layerObject[name] = [
               parseFloat(rectMatches[1]),
               parseFloat(rectMatches[2]),
               parseFloat(rectMatches[3]),
               parseFloat(rectMatches[4]),
             ];
           } else {
             layerObject[name] = value;
           }
         }
-      } else if (nesting == 0 && rest.charAt(j) == ' ') {
+      } else if (nesting == 0 && rest.charAt(j) == " ") {
         lastSpace = j;
       }
     }
-    //dump("FIELDS: " + JSON.stringify(fields) + "\n");
+    // dump("FIELDS: " + JSON.stringify(fields) + "\n");
   }
   return root;
 }
 
-function trim(s){ 
-  return ( s || '' ).replace( /^\s+|\s+$/g, '' ); 
+function trim(s) {
+  return ( s || "" ).replace( /^\s+|\s+$/g, "" );
 }
 
 function getDataURI(str) {
   if (str.indexOf("data:image/png;base64,") == 0) {
     return str;
   }
 
   var matches = str.match("data:image/lz4bgra;base64,([0-9]+),([0-9]+),([0-9]+),(.*)");
@@ -136,17 +134,20 @@ function getDataURI(str) {
   var decoded = new Uint8Array(stride * h);
   for (var i = 0; i < len; i++) {
     var ascii = binary_string.charCodeAt(i);
     bytes[i] = ascii;
   }
 
   var ctxt = canvas.getContext("2d");
   var out = ctxt.createImageData(w, h);
-  buffer = LZ4_uncompressChunk(bytes, decoded);
+  // This is actually undefined throughout the tree and it isn't clear what it
+  // should be. Since this is only development code, leave it alone for now.
+  // eslint-disable-next-line no-undef
+  LZ4_uncompressChunk(bytes, decoded);
 
   for (var x = 0; x < w; x++) {
     for (var y = 0; y < h; y++) {
       out.data[4 * x + 4 * y * w + 0] = decoded[4 * x + y * stride + 2];
       out.data[4 * x + 4 * y * w + 1] = decoded[4 * x + y * stride + 1];
       out.data[4 * x + 4 * y * w + 2] = decoded[4 * x + y * stride + 0];
       out.data[4 * x + 4 * y * w + 3] = decoded[4 * x + y * stride + 3];
     }
@@ -215,17 +216,17 @@ function parseLayers(layersDumpLines) {
       parseFloat(rectMatches[3]), parseFloat(rectMatches[4]),
     ];
     return rect;
   }
   function parseRegion(str) {
     str = trim(str);
 
     // Something like '< (x=0, y=0, w=2842, h=158); (x=0, y=1718, w=2842, h=500); >'
-    if (str.charAt(0) != '<' || str.charAt(str.length - 1) != '>') {
+    if (str.charAt(0) != "<" || str.charAt(str.length - 1) != ">") {
       return null;
     }
 
     var region = [];
     str = trim(str.substring(1, str.length - 1));
     while (str != "") {
       var rectMatches = str.match("^\\(x=(.*?), y=(.*?), w=(.*?), h=(.*?)\\);(.*)$");
       if (!rectMatches) {
@@ -247,63 +248,63 @@ function parseLayers(layersDumpLines) {
   var root;
   var objectAtIndentation = [];
   for (var i = 0; i < layersDumpLines.length; i++) {
     // Something like 'ThebesLayerComposite (0x12104cc00) [shadow-visible=< (x=0, y=0, w=1920, h=158); >] [visible=< (x=0, y=0, w=1920, h=158); >] [opaqueContent] [valid=< (x=0, y=0, w=1920, h=2218); >]'
     var line = layersDumpLines[i].name || layersDumpLines[i];
 
     var tileMatches = line.match("(\\s*)Tile \\(x=(.*), y=(.*)\\): (.*)");
     if (tileMatches) {
-      var indentation = Math.floor(matches[1].length / 2);
+      let indentation = Math.floor(matches[1].length / 2);
       var x = tileMatches[2];
       var y = tileMatches[3];
       var dataUri = tileMatches[4];
-      var parent = objectAtIndentation[indentation - 1];
+      let parent = objectAtIndentation[indentation - 1];
       var tiles = parent.tiles || {};
 
       tiles[x] = tiles[x] || {};
       tiles[x][y] = dataUri;
 
       parent.tiles = tiles;
 
       continue;
     }
 
     var surfaceMatches = line.match("(\\s*)Surface: (.*)");
     if (surfaceMatches) {
-      var indentation = Math.floor(matches[1].length / 2);
-      var parent = objectAtIndentation[indentation - 1] || objectAtIndentation[indentation - 2];
+      let indentation = Math.floor(matches[1].length / 2);
+      let parent = objectAtIndentation[indentation - 1] || objectAtIndentation[indentation - 2];
 
       var surfaceURI = surfaceMatches[2];
       if (parent.surfaceURI != null) {
         console.log("error: surfaceURI already set for this layer " + parent.line);
       }
       parent.surfaceURI = surfaceURI;
 
       // Look for the buffer-rect offset
       var contentHostLine = layersDumpLines[i - 2].name || layersDumpLines[i - 2];
-      var matches = contentHostLine.match(LAYERS_LINE_REGEX);
+      let matches = contentHostLine.match(LAYERS_LINE_REGEX);
       if (matches) {
         var contentHostRest = matches[4];
         parent.contentHostProp = {};
         parseProperties(contentHostRest, parent.contentHostProp);
       }
 
       continue;
     }
 
     var layerObject = {
-      line: line,
+      line,
       children: [],
-    }
+    };
     if (!root) {
       root = layerObject;
     }
 
-    var matches = line.match(LAYERS_LINE_REGEX);
+    let matches = line.match(LAYERS_LINE_REGEX);
     if (!matches) {
       continue; // Something like a texturehost dump. Safe to ignore
     }
 
     if (matches[2].includes("TiledContentHost") ||
         matches[2].includes("ContentHost") ||
         matches[2].includes("ContentClient") ||
         matches[2].includes("MemoryTextureHost") ||
@@ -330,49 +331,49 @@ function parseLayers(layersDumpLines) {
     layerObject.address = matches[3];
 
     var rest = matches[4];
 
     function parseProperties(rest, layerObject) {
       var fields = [];
       var nesting = 0;
       var startIndex;
-      for (var j = 0; j < rest.length; j++) {
-        if (rest.charAt(j) == '[') {
+      for (let j = 0; j < rest.length; j++) {
+        if (rest.charAt(j) == "[") {
           nesting++;
           if (nesting == 1) {
             startIndex = j;
           }
-        } else if (rest.charAt(j) == ']') {
+        } else if (rest.charAt(j) == "]") {
           nesting--;
           if (nesting == 0) {
             fields.push(rest.substring(startIndex + 1, j));
           }
         }
       }
 
-      for (var j = 0; j < fields.length; j++) {
+      for (let j = 0; j < fields.length; j++) {
         // Something like 'valid=< (x=0, y=0, w=1920, h=2218); >' or 'opaqueContent'
         var field = fields[j];
-        //dump("FIELD: " + field + "\n");
+        // dump("FIELD: " + field + "\n");
         var parts = field.split("=", 2);
         var fieldName = parts[0];
-        var rest = field.substring(fieldName.length + 1);
+        rest = field.substring(fieldName.length + 1);
         if (parts.length == 1) {
           layerObject[fieldName] = "true";
           layerObject[fieldName].type = "bool";
           continue;
         }
-        var float = parseFloat_cleo(rest); 
+        var float = parseFloat_cleo(rest);
         if (float) {
           layerObject[fieldName] = float;
           layerObject[fieldName].type = "float";
           continue;
         }
-        var region = parseRegion(rest); 
+        var region = parseRegion(rest);
         if (region) {
           layerObject[fieldName] = region;
           layerObject[fieldName].type = "region";
           continue;
         }
         var rect = parseRect2D(rest);
         if (rect) {
           layerObject[fieldName] = rect;
@@ -386,171 +387,171 @@ function parseLayers(layersDumpLines) {
           continue;
         }
         var color = parseColor(rest);
         if (color) {
           layerObject[fieldName] = color;
           layerObject[fieldName].type = "color";
           continue;
         }
-        if (rest[0] == '{' && rest[rest.length - 1] == '}') {
+        if (rest[0] == "{" && rest[rest.length - 1] == "}") {
           var object = {};
           parseProperties(rest.substring(1, rest.length - 2).trim(), object);
           layerObject[fieldName] = object;
           layerObject[fieldName].type = "object";
           continue;
         }
         fieldName = fieldName.split(" ")[0];
         layerObject[fieldName] = rest[0];
         layerObject[fieldName].type = "string";
       }
     }
     parseProperties(rest, layerObject);
 
-    if (!layerObject['shadow-transform']) {
+    if (!layerObject["shadow-transform"]) {
       // No shadow transform = identify
-      layerObject['shadow-transform'] = [[1, 0], [0, 1], [0, 0]];
+      layerObject["shadow-transform"] = [[1, 0], [0, 1], [0, 0]];
     }
 
     // Compute screenTransformX/screenTransformY
     // TODO Fully support transforms
-    if (layerObject['shadow-transform'] && layerObject['transform']) {
-      layerObject['screen-transform'] = [layerObject['shadow-transform'][2][0], layerObject['shadow-transform'][2][1]];
+    if (layerObject["shadow-transform"] && layerObject.transform) {
+      layerObject["screen-transform"] = [layerObject["shadow-transform"][2][0], layerObject["shadow-transform"][2][1]];
       var currIndentation = indentation - 1;
       while (currIndentation >= 0) {
-        var transform = objectAtIndentation[currIndentation]['shadow-transform'] || objectAtIndentation[currIndentation]['transform'];
+        var transform = objectAtIndentation[currIndentation]["shadow-transform"] || objectAtIndentation[currIndentation].transform;
         if (transform) {
-          layerObject['screen-transform'][0] += transform[2][0];
-          layerObject['screen-transform'][1] += transform[2][1];
+          layerObject["screen-transform"][0] += transform[2][0];
+          layerObject["screen-transform"][1] += transform[2][1];
         }
         currIndentation--;
       }
     }
 
-    //dump("Fields: " + JSON.stringify(fields) + "\n");
+    // dump("Fields: " + JSON.stringify(fields) + "\n");
   }
   root.compositeTime = layersDumpLines.compositeTime;
-  //dump("OBJECTS: " + JSON.stringify(root) + "\n");
+  // dump("OBJECTS: " + JSON.stringify(root) + "\n");
   return root;
 }
 function populateLayers(root, displayList, pane, previewParent, hasSeenRoot, contentScale, rootPreviewParent) {
-  
+
   contentScale = contentScale || 1;
   rootPreviewParent = rootPreviewParent || previewParent;
 
   function getDisplayItemForLayer(displayList) {
     var items = [];
     if (!displayList) {
       return items;
     }
     if (displayList.layer == root.address) {
       items.push(displayList);
     }
     for (var i = 0; i < displayList.children.length; i++) {
       var subDisplayItems = getDisplayItemForLayer(displayList.children[i]);
-      for (var j = 0; j < subDisplayItems.length; j++) {
+      for (let j = 0; j < subDisplayItems.length; j++) {
         items.push(subDisplayItems[j]);
       }
     }
     return items;
   }
   var elem = createElement("div", {
     className: "layerObjectDescription",
     textContent: root.line,
     style: {
       whiteSpace: "pre",
     },
-    onmouseover: function() {
+    onmouseover() {
       if (this.layerViewport) {
         this.layerViewport.classList.add("layerHover");
       }
     },
-    onmouseout: function() {
+    onmouseout() {
       if (this.layerViewport) {
         this.layerViewport.classList.remove("layerHover");
       }
     },
   });
   var icon = createElement("img", {
     src: "show.png",
     style: {
       width: "12px",
       height: "12px",
       marginLeft: "4px",
       marginRight: "4px",
       cursor: "pointer",
     },
-    onclick: function() {
+    onclick() {
       if (this.layerViewport) {
         if (this.layerViewport.style.visibility == "hidden") {
           this.layerViewport.style.visibility = "";
-          this.src = "show.png"
+          this.src = "show.png";
         } else {
           this.layerViewport.style.visibility = "hidden";
-          this.src = "hide.png"
+          this.src = "hide.png";
         }
       }
-    }
+    },
   });
   elem.insertBefore(icon, elem.firstChild);
   pane.appendChild(elem);
 
-  if (root["shadow-visible"] || root["visible"]) {
-    var visibleRegion = root["shadow-visible"] || root["visible"];
+  if (root["shadow-visible"] || root.visible) {
+    var visibleRegion = root["shadow-visible"] || root.visible;
     var layerViewport = createElement("div", {
       id: root.address + "_viewport",
       style: {
         position: "absolute",
         pointerEvents: "none",
       },
     });
     elem.layerViewport = layerViewport;
     icon.layerViewport = layerViewport;
     var layerViewportMatrix = [1, 0, 0, 1, 0, 0];
-    if (root["shadow-clip"] || root["clip"]) {
-      var clip = root["shadow-clip"] || root["clip"]
+    if (root["shadow-clip"] || root.clip) {
+      var clip = root["shadow-clip"] || root.clip;
       var clipElem = createElement("div", {
         id: root.address + "_clip",
         style: {
-          left: clip[0]+"px",
-          top: clip[1]+"px",
-          width: clip[2]+"px",
-          height: clip[3]+"px",
+          left: clip[0] + "px",
+          top: clip[1] + "px",
+          width: clip[2] + "px",
+          height: clip[3] + "px",
           position: "absolute",
           overflow: "hidden",
           pointerEvents: "none",
         },
       });
       layerViewportMatrix[4] += -clip[0];
       layerViewportMatrix[5] += -clip[1];
-      layerViewport.style.transform = "translate(-" + clip[0] + "px, -" + clip[1] + "px" + ")";
+      layerViewport.style.transform = "translate(-" + clip[0] + "px, -" + clip[1] + "px)";
     }
-    if (root["shadow-transform"] || root["transform"]) {
-      var matrix = root["shadow-transform"] || root["transform"];
+    if (root["shadow-transform"] || root.transform) {
+      var matrix = root["shadow-transform"] || root.transform;
       layerViewportMatrix[0] = matrix[0][0];
       layerViewportMatrix[1] = matrix[0][1];
       layerViewportMatrix[2] = matrix[1][0];
       layerViewportMatrix[3] = matrix[1][1];
       layerViewportMatrix[4] += matrix[2][0];
       layerViewportMatrix[5] += matrix[2][1];
     }
     layerViewport.style.transform = "matrix(" + layerViewportMatrix[0] + "," + layerViewportMatrix[1] + "," + layerViewportMatrix[2] + "," + layerViewportMatrix[3] + "," + layerViewportMatrix[4] + "," + layerViewportMatrix[5] + ")";
     if (!hasSeenRoot) {
       hasSeenRoot = true;
-      layerViewport.style.transform = "scale(" + 1/contentScale + "," + 1/contentScale + ")";
+      layerViewport.style.transform = "scale(" + 1 / contentScale + "," + 1 / contentScale + ")";
     }
     if (clipElem) {
       previewParent.appendChild(clipElem);
       clipElem.appendChild(layerViewport);
     } else {
       previewParent.appendChild(layerViewport);
     }
     previewParent = layerViewport;
-    for (var i = 0; i < visibleRegion.length; i++) {
-      var rect2d = visibleRegion[i];
+    for (let i = 0; i < visibleRegion.length; i++) {
+      let rect2d = visibleRegion[i];
       var layerPreview = createElement("div", {
         id: root.address + "_visible_part" + i + "-" + visibleRegion.length,
         className: "layerPreview",
         style: {
           position: "absolute",
           left: rect2d[0] + "px",
           top: rect2d[1] + "px",
           width: rect2d[2] + "px",
@@ -592,59 +593,59 @@ function populateLayers(root, displayLis
             }
           }
         }
         layerPreview.style.background = "";
       } else if (root.surfaceURI) {
         hasImg = true;
         var offsetX = 0;
         var offsetY = 0;
-        if (root.contentHostProp && root.contentHostProp['buffer-rect']) {
-          offsetX = root.contentHostProp['buffer-rect'][0];
-          offsetY = root.contentHostProp['buffer-rect'][1];
+        if (root.contentHostProp && root.contentHostProp["buffer-rect"]) {
+          offsetX = root.contentHostProp["buffer-rect"][0];
+          offsetY = root.contentHostProp["buffer-rect"][1];
         }
         var surfaceImgElem = createElement("img", {
           src: getDataURI(root.surfaceURI),
           style: {
             position: "absolute",
             left: (offsetX - previewOffset[0]) + "px",
             top: (offsetY - previewOffset[1]) + "px",
             pointerEvents: "auto",
           },
         });
         layerPreview.appendChild(surfaceImgElem);
         layerPreview.style.background = "";
       } else if (root.color) {
         hasImg = true;
         layerPreview.style.background = "rgba(" + root.color.r + ", " + root.color.g + ", " + root.color.b + ", " + root.color.a + ")";
       }
-      
+
       if (hasImg || true) {
         layerPreview.mouseoverElem = elem;
         layerPreview.onmouseenter = function() {
           this.mouseoverElem.onmouseover();
-        }
+        };
         layerPreview.onmouseout = function() {
           this.mouseoverElem.onmouseout();
-        }
+        };
       }
     }
 
     var layerDisplayItems = getDisplayItemForLayer(displayList);
-    for (var i = 0; i < layerDisplayItems.length; i++) {
+    for (let i = 0; i < layerDisplayItems.length; i++) {
       var displayItem = layerDisplayItems[i];
       var displayElem = createElement("div", {
         className: "layerObjectDescription",
         textContent: "            " + trim(displayItem.line),
         style: {
           whiteSpace: "pre",
         },
-        displayItem: displayItem,
-        layerViewport: layerViewport,
-        onmouseover: function() {
+        displayItem,
+        layerViewport,
+        onmouseover() {
           if (this.diPreview) {
             this.diPreview.classList.add("displayHover");
 
             var description = "";
             if (this.displayItem.contentDescriptor) {
               description += "Content: " + this.displayItem.contentDescriptor;
             } else {
               description += "Content: Unknown";
@@ -661,69 +662,68 @@ function populateLayers(root, displayLis
               description += "<br>Z: " + this.displayItem.z;
             }
             // At the end
             if (this.displayItem.rest) {
               description += "<br>" + this.displayItem.rest;
             }
 
             var box = this.diPreview.getBoundingClientRect();
-            var pageBox = document.body.getBoundingClientRect();
             this.diPreview.tooltip = createElement("div", {
               className: "csstooltip",
               innerHTML: description,
               style: {
                 top: Math.min(box.bottom, document.documentElement.clientHeight - 150) + "px",
                 left: box.left + "px",
-              }
+              },
             });
 
             document.body.appendChild(this.diPreview.tooltip);
           }
         },
-        onmouseout: function() {
+        onmouseout() {
           if (this.diPreview) {
             this.diPreview.classList.remove("displayHover");
             document.body.removeChild(this.diPreview.tooltip);
           }
         },
       });
 
-      var icon = createElement("img", {
+      icon = createElement("img", {
         style: {
           width: "12px",
           height: "12px",
           marginLeft: "4px",
           marginRight: "4px",
-        }
+        },
       });
       displayElem.insertBefore(icon, displayElem.firstChild);
       pane.appendChild(displayElem);
       // bounds doesn't adjust for within the layer. It's not a bad fallback but
       // will have the wrong offset
-      var rect2d = displayItem.layerBounds || displayItem.bounds;
+      let rect2d = displayItem.layerBounds || displayItem.bounds;
       if (rect2d) { // This doesn't place them corectly
         var appUnitsToPixels = 60 / contentScale;
-        diPreview = createElement("div", {
+        let diPreview = createElement("div", {
           id: "displayitem_" + displayItem.content + "_" + displayItem.address,
           className: "layerPreview",
           style: {
             position: "absolute",
-            left: rect2d[0]/appUnitsToPixels + "px",
-            top: rect2d[1]/appUnitsToPixels + "px",
-            width: rect2d[2]/appUnitsToPixels + "px",
-            height: rect2d[3]/appUnitsToPixels + "px",
+            left: rect2d[0] / appUnitsToPixels + "px",
+            top: rect2d[1] / appUnitsToPixels + "px",
+            width: rect2d[2] / appUnitsToPixels + "px",
+            height: rect2d[3] / appUnitsToPixels + "px",
             border: "solid 1px gray",
             pointerEvents: "auto",
           },
-          displayElem: displayElem,
-          onmouseover: function() {
+          displayElem,
+          onmouseover() {
             this.displayElem.onmouseover();
           },
-          onmouseout: function() {
+          onmouseout() {
             this.displayElem.onmouseout();
           },
         });
 
         layerViewport.appendChild(diPreview);
         displayElem.diPreview = diPreview;
       }
     }
@@ -731,97 +731,95 @@ function populateLayers(root, displayLis
 
   for (var i = 0; i < root.children.length; i++) {
     populateLayers(root.children[i], displayList, pane, previewParent, hasSeenRoot, contentScale, rootPreviewParent);
   }
 }
 
 // This function takes a stdout snippet and finds the frames
 function parseMultiLineDump(log) {
-  var lines = log.split("\n");
-
   var container = createElement("div", {
-    style: { 
+    style: {
       height: "100%",
       position: "relative",
     },
   });
 
   var layerManagerFirstLine = "[a-zA-Z]*LayerManager \\(.*$\n";
   var nextLineStartWithSpace = "([ \\t].*$\n)*";
   var layersRegex = "(" + layerManagerFirstLine + nextLineStartWithSpace + ")";
 
   var startLine = "Painting --- after optimization:\n";
-  var endLine = "Painting --- layer tree:"
+  var endLine = "Painting --- layer tree:";
   var displayListRegex = "(" + startLine + "(.*\n)*?" + endLine + ")";
 
   var regex = new RegExp(layersRegex + "|" + displayListRegex, "gm");
   var matches = log.match(regex);
   console.log(matches);
   window.matches = matches;
 
   var matchList = createElement("span", {
-    style: { 
+    style: {
       height: "95%",
       width: "10%",
       position: "relative",
       border: "solid black 2px",
       display: "inline-block",
       float: "left",
       overflow: "auto",
     },
   });
   container.appendChild(matchList);
   var contents = createElement("span", {
-    style: { 
+    style: {
       height: "95%",
       width: "88%",
       display: "inline-block",
     },
     textContent: "Click on a frame on the left to view the layer tree",
   });
   container.appendChild(contents);
 
   var lastDisplayList = null;
   var frameID = 1;
   for (let i = 0; i < matches.length; i++) {
     var currMatch = matches[i];
 
     if (currMatch.indexOf(startLine) == 0) {
       // Display list match
-      var matchLines = matches[i].split("\n")
+      var matchLines = matches[i].split("\n");
       lastDisplayList = parseDisplayList(matchLines);
     } else {
       // Layer tree match:
       let displayList = lastDisplayList;
       lastDisplayList = null;
       var currFrameDiv = createElement("a", {
         style: {
           padding: "3px",
           display: "block",
         },
         href: "#",
         textContent: "LayerTree " + (frameID++),
-        onclick: function() {
+        onclick() {
           contents.innerHTML = "";
-          var matchLines = matches[i].split("\n")
+          var matchLines = matches[i].split("\n");
           var dumpDiv = parseDump(matchLines, displayList);
           contents.appendChild(dumpDiv);
-        }
+        },
       });
       matchList.appendChild(currFrameDiv);
     }
   }
 
   return container;
 }
 
 function parseDump(log, displayList, compositeTitle, compositeTime) {
   compositeTitle |= "";
-  compositeTime |= 0
+  compositeTime |= 0;
 
   var container = createElement("div", {
     style: {
       background: "white",
       height: "100%",
       position: "relative",
     },
   });
@@ -869,16 +867,8 @@ function parseDump(log, displayList, com
     },
   });
   mainDiv.appendChild(previewDiv);
 
   var root = parseLayers(log);
   populateLayers(root, displayList, layerListPane, previewDiv);
   return container;
 }
-
-function tab_showLayersDump(layersDumpLines, compositeTitle, compositeTime) {
-  var container = parseDump(layersDumpLines, compositeTitle, compositeTime);
-
-  gTabWidget.addTab("LayerTree", container); 
-  gTabWidget.selectTab("LayerTree");
-}
-
--- a/gfx/tests/browser/browser_windowless_troubleshoot_crash.js
+++ b/gfx/tests/browser/browser_windowless_troubleshoot_crash.js
@@ -9,18 +9,18 @@ add_task(async function test_windowlessB
       observe(contentWindow, topic, data) {
         let observedDocShell = contentWindow.docShell
                                             .sameTypeRootTreeItem
                                             .QueryInterface(Ci.nsIDocShell);
           if (docShell === observedDocShell) {
             Services.obs.removeObserver(listener, "content-document-global-created");
             resolve();
           }
-        }
-    }
+        },
+    };
     Services.obs.addObserver(listener, "content-document-global-created");
   });
   let triggeringPrincipal = Services.scriptSecurityManager.createNullPrincipal({});
   webNav.loadURI("about:blank", 0, null, null, null, triggeringPrincipal);
 
   await onLoaded;
 
   let winUtils = webNav.document.defaultView.windowUtils;
--- a/gfx/tests/chrome/test_device_reset.html
+++ b/gfx/tests/chrome/test_device_reset.html
@@ -9,21 +9,17 @@ https://bugzilla.mozilla.org/show_bug.cg
     <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
     <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
   </head>
   <body>
     <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1274663">Mozilla Bug 1274663</a>
     <script>
       var importObj = {};
 
-      var Cc = SpecialPowers.Cc;
-      var Ci = SpecialPowers.Ci;
-
       var sysInfo = Cc["@mozilla.org/system-info;1"].getService(Ci.nsIPropertyBag2);
-      var xr = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime);
 
       var windows = SpecialPowers.Services.ww.getWindowEnumerator();
       var windowutils;
       while (windows.hasMoreElements()) {
         windowutils = windows.getNext().windowUtils;
       }
 
       const PAGE_WIDTH = 200;
@@ -73,17 +69,17 @@ https://bugzilla.mozilla.org/show_bug.cg
       }
 
       // Test runner code
       windowutils.triggerDeviceReset();
 
       SimpleTest.waitForExplicitFinish();
       window.addEventListener("MozAfterPaint", function paintHandle(e) {
         runCanvasTest();
-        window.removeEventListener("MozAfterPaint", paintHandle, false);
+        window.removeEventListener("MozAfterPaint", paintHandle);
       });
 
       function runCanvasTest() {
         const canvas = createCanvas();
         const ctx = canvas.getContext("2d");
         document.body.appendChild(canvas);
 
         ok(testCompositor(ctx), "Canvas did not get rendered after device reset");
--- a/gfx/tests/mochitest/test_acceleration.html
+++ b/gfx/tests/mochitest/test_acceleration.html
@@ -7,34 +7,34 @@ https://bugzilla.mozilla.org/show_bug.cg
   <title>Test hardware acceleration</title>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=627498">Mozilla Bug 627498</a>
 <p id="display"></p>
 <div id="content" style="display: none">
-  
+
 </div>
 <pre id="test">
 <script type="application/javascript">
 
 // Make sure that acceleration is enabled/disabled the way we expect it to be
 // based on platform.
 
 SimpleTest.waitForExplicitFinish();
 
 addEventListener("pageshow", runTest, false);
 
 function runTest() {
   var Cc = SpecialPowers.Cc;
   var Ci = SpecialPowers.Ci;
 
   var sysInfo = Cc["@mozilla.org/system-info;1"].getService(Ci.nsIPropertyBag2);
-  var xr = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime);
+  var xr = SpecialPowers.Services.appinfo;
 
   var windows = SpecialPowers.Services.ww.getWindowEnumerator();
   var windowutils;
   var acceleratedWindows = 0;
   var advancedLayersWindows = 0;
   var webrenderWindows = 0;
   var layerManagerLog = [];
   while (windows.hasMoreElements()) {
@@ -54,18 +54,17 @@ function runTest() {
     } catch (e) {
       // The window may not have a layer manager, in which case we get an error.
       // Don't count it as an accelerated window.
       dump("Didn't get a layer manager! " + e);
     }
   }
 
   var osName = sysInfo.getProperty("name");
-  switch(osName)
-  {
+  switch (osName) {
     case "Darwin": // Mac OS X.
       // We only enable OpenGL layers on machines that don't support QuickDraw
       // plugins. x86-64 architecture is a good proxy for this plugin support.
       if (sysInfo.getProperty("arch") != "x86-64") {
         is(acceleratedWindows, 0, "Acceleration not supported on x86 OS X");
       } else {
         // Workaround for SeaMonkey tinderboxes which don't support acceleration.
         if (navigator.userAgent.match(/ SeaMonkey\//)) {
--- a/gfx/tests/mochitest/test_bug509244.html
+++ b/gfx/tests/mochitest/test_bug509244.html
@@ -7,17 +7,17 @@ https://bugzilla.mozilla.org/show_bug.cg
   <title>Test for Bug 509244</title>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=509244">Mozilla Bug 509244</a>
 <p id="display">A</p>
 <div id="content" style="display: none">
-  
+
 </div>
 <pre id="test">
 <script type="application/javascript">
 
 /** Test for Bug 509244 **/
 
 function flush() { document.documentElement.offsetHeight; }
 
@@ -26,22 +26,20 @@ var text = document.getElementById("disp
 // layout text, caching monospace font
 text.style.fontFamily = "monospace";
 flush();
 // relayout text so that monospace font is no longer used (but cached)
 text.style.fontFamily = "sans-serif";
 flush();
 
 // flush cache
-var os = SpecialPowers.Cc["@mozilla.org/observer-service;1"]
-         .getService(SpecialPowers.Ci.nsIObserverService);
-os.notifyObservers(null, "memory-pressure", "heap-minimize");
+SpecialPowers.Services.obs.notifyObservers(null, "memory-pressure", "heap-minimize");
 
 // reuse font that was flushed from cache
 text.style.fontFamily = "monospace";
-flush(); 
+flush();
 
 ok(true, "not crashed");
 
 </script>
 </pre>
 </body>
 </html>
--- a/gfx/tests/mochitest/test_font_whitelist.html
+++ b/gfx/tests/mochitest/test_font_whitelist.html
@@ -24,23 +24,23 @@ https://bugzilla.mozilla.org/show_bug.cg
 const InspectorUtils = SpecialPowers.InspectorUtils;
 
 // Given an element id, returns the first font face name encountered.
 let fontUsed = id => {
   let element = document.getElementById(id),
       range = document.createRange();
   range.selectNode(element);
   return InspectorUtils.getUsedFontFaces(range)[0].CSSFamilyName;
-}
+};
 
 // A map of the default mono, sans and serif fonts, obtained when
 // whitelisting is disabled.
-const fonts = { mono : fontUsed("mono"),
-                sans : fontUsed("sans"),
-                serif : fontUsed("serif") };
+const fonts = { mono: fontUsed("mono"),
+                sans: fontUsed("sans"),
+                serif: fontUsed("serif") };
 
 // Set the font whitelist to contain none, some, or all of the
 // default mono, sans, and serif fonts. Check that the rendering
 // of our three test elements uses only fonts present in the
 // whitelist.
 let testFontWhitelist = async function(useMono, useSans, useSerif) {
   let whitelist = [];
   if (useMono) {
@@ -59,17 +59,17 @@ let testFontWhitelist = async function(u
   info("font whitelist: " + JSON.stringify(whitelist));
   let whitelistEmpty = whitelist.length === 0;
   is(useMono || whitelistEmpty, fontUsed("mono") === fonts.mono,
      "Correct mono whitelisting state; got " + fontUsed("mono") + ", requested " + fonts.mono);
   is(useSans || whitelistEmpty, fontUsed("sans") === fonts.sans,
      "Correct sans whitelisting state; got " + fontUsed("sans") + ", requested " + fonts.sans);
   is(useSerif || whitelistEmpty, fontUsed("serif") === fonts.serif,
      "Correct serif whitelisting state; got " + fontUsed("serif") + ", requested " + fonts.serif);
-}
+};
 
 // Run tests to confirm that only whitelisting fonts are present in a
 // rendered page. Try turning mono, sans, and serif off and on in
 // every combination.
 add_task(async function() {
   for (let useMono of [false, true]) {
     for (let useSans of [false, true]) {
       for (let useSerif of [false, true]) {
--- a/media/webrtc/trunk/webrtc/modules/video_capture/objc/rtc_video_capture_objc.mm
+++ b/media/webrtc/trunk/webrtc/modules/video_capture/objc/rtc_video_capture_objc.mm
@@ -241,25 +241,20 @@ using namespace webrtc::videocapturemodu
   [self waitForCaptureChangeToFinish];
   [self directOutputToNil];
 
   if (!_captureSession) {
     return NO;
   }
 
   _captureChanging = YES;
-  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
-    [self stopCaptureInBackground];
-  });
-  return YES;
-}
-
-- (void)stopCaptureInBackground {
   [_captureSession stopRunning];
   [self signalCaptureChangeEnd];
+
+  return YES;
 }
 
 - (BOOL)changeCaptureInputByUniqueId:(NSString*)uniqueId {
   [self waitForCaptureChangeToFinish];
   NSArray* currentInputs = [_captureSession inputs];
   // remove current input
   if ([currentInputs count] > 0) {
     AVCaptureInput* currentInput = (AVCaptureInput*)[currentInputs objectAtIndex:0];
--- a/mobile/android/branding/beta/content/jar.mn
+++ b/mobile/android/branding/beta/content/jar.mn
@@ -1,9 +1,9 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-chrome.jar:
+geckoview.jar:
 % content branding %content/branding/ contentaccessible=yes
   content/branding/about.png                     (about.png)
   content/branding/favicon32.png                 (favicon32.png)
   content/branding/favicon64.png                 (favicon64.png)
--- a/mobile/android/branding/nightly/content/jar.mn
+++ b/mobile/android/branding/nightly/content/jar.mn
@@ -1,9 +1,9 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-chrome.jar:
+geckoview.jar:
 % content branding %content/branding/ contentaccessible=yes
   content/branding/about.png                     (about.png)
   content/branding/favicon32.png                 (favicon32.png)
   content/branding/favicon64.png                 (favicon64.png)
--- a/mobile/android/branding/official/content/jar.mn
+++ b/mobile/android/branding/official/content/jar.mn
@@ -1,9 +1,9 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-chrome.jar:
+geckoview.jar:
 % content branding %content/branding/ contentaccessible=yes
   content/branding/about.png                     (about.png)
   content/branding/favicon32.png                 (favicon32.png)
   content/branding/favicon64.png                 (favicon64.png)
--- a/mobile/android/branding/unofficial/content/jar.mn
+++ b/mobile/android/branding/unofficial/content/jar.mn
@@ -1,9 +1,9 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-chrome.jar:
+geckoview.jar:
 % content branding %content/branding/ contentaccessible=yes
   content/branding/about.png                     (about.png)
   content/branding/favicon32.png                 (favicon32.png)
   content/branding/favicon64.png                 (favicon64.png)
--- a/mobile/android/chrome/geckoview/jar.mn
+++ b/mobile/android/chrome/geckoview/jar.mn
@@ -15,8 +15,10 @@ geckoview.jar:
   content/GeckoViewContentChild.js
   content/GeckoViewMediaChild.js
   content/GeckoViewNavigationChild.js
   content/GeckoViewProgressChild.js
   content/GeckoViewPromptChild.js
   content/GeckoViewScrollChild.js
   content/GeckoViewSettingsChild.js
   content/GeckoViewSelectionActionChild.js
+
+% content branding %content/branding/
--- a/mobile/android/chrome/jar.mn
+++ b/mobile/android/chrome/jar.mn
@@ -43,18 +43,16 @@ chrome.jar:
   content/aboutAccounts.xhtml          (content/aboutAccounts.xhtml)
   content/aboutAccounts.js             (content/aboutAccounts.js)
   content/aboutExperiments.xhtml       (content/aboutExperiments.xhtml)
   content/aboutExperiments.js          (content/aboutExperiments.js)
   content/aboutLogins.xhtml            (content/aboutLogins.xhtml)
   content/aboutLogins.js               (content/aboutLogins.js)
   content/ExtensionPermissions.js      (content/ExtensionPermissions.js)
 
-% content branding %content/branding/
-
 % override chrome://global/content/netError.xhtml chrome://browser/content/netError.xhtml
 % override chrome://mozapps/content/extensions/extensions.xul chrome://browser/content/aboutAddons.xhtml
 
 # L10n resource overrides.
 % override chrome://global/locale/aboutReader.properties chrome://browser/locale/overrides/aboutReader.properties
 % override chrome://global/locale/aboutRights.dtd chrome://browser/locale/overrides/aboutRights.dtd
 % override chrome://global/locale/charsetMenu.properties chrome://browser/locale/overrides/charsetMenu.properties
 % override chrome://global/locale/commonDialogs.properties chrome://browser/locale/overrides/commonDialogs.properties
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoThread.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoThread.java
@@ -1,25 +1,22 @@
 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko;
 
-import org.mozilla.gecko.TelemetryUtils;
 import org.mozilla.gecko.annotation.RobocopTarget;
 import org.mozilla.gecko.annotation.WrapForJNI;
 import org.mozilla.gecko.mozglue.GeckoLoader;
 import org.mozilla.gecko.process.GeckoProcessManager;
 import org.mozilla.gecko.util.GeckoBundle;
-import org.mozilla.gecko.util.FileUtils;
 import org.mozilla.gecko.util.ThreadUtils;
 import org.mozilla.geckoview.BuildConfig;
-import org.mozilla.geckoview.GeckoRuntimeSettings;
 
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
@@ -129,16 +126,18 @@ public class GeckoThread extends Thread 
 
     private static TelemetryUtils.Timer sInitTimer;
 
     // Main process parameters
     public static final int FLAG_DEBUGGING = 1 << 0; // Debugging mode.
     public static final int FLAG_PRELOAD_CHILD = 1 << 1; // Preload child during main thread start.
     public static final int FLAG_ENABLE_NATIVE_CRASHREPORTER = 1 << 2; // Enable native crash reporting
 
+    public static final long DEFAULT_TIMEOUT = 5000;
+
     /* package */ static final String EXTRA_ARGS = "args";
     private static final String EXTRA_PREFS_FD = "prefsFd";
     private static final String EXTRA_PREF_MAP_FD = "prefMapFd";
     private static final String EXTRA_IPC_FD = "ipcFd";
     private static final String EXTRA_CRASH_FD = "crashFd";
     private static final String EXTRA_CRASH_ANNOTATION_FD = "crashAnnotationFd";
 
     private boolean mInitialized;
@@ -571,18 +570,31 @@ public class GeckoThread extends Thread 
         // This is almost always called before Gecko loads, so we don't
         // bother checking here if Gecko is actually loaded or not.
         // Speculative connection depends on proxy settings,
         // so the earliest it can happen is after profile is ready.
         queueNativeCallUntil(State.PROFILE_READY, GeckoThread.class,
                              "speculativeConnectNative", uri);
     }
 
-    @WrapForJNI @RobocopTarget
-    public static native void waitOnGecko();
+    @WrapForJNI(stubName = "WaitOnGecko")
+    @RobocopTarget
+    private static native boolean nativeWaitOnGecko(long timeoutMillis);
+
+    public static void waitOnGeckoForever() {
+        nativeWaitOnGecko(0);
+    }
+
+    public static boolean waitOnGecko() {
+        return waitOnGecko(DEFAULT_TIMEOUT);
+    }
+
+    public static boolean waitOnGecko(long timeoutMillis) {
+        return nativeWaitOnGecko(timeoutMillis);
+    }
 
     @WrapForJNI(stubName = "OnPause", dispatchTo = "gecko")
     private static native void nativeOnPause();
 
     public static void onPause() {
         if (isStateAtLeast(State.PROFILE_READY)) {
             nativeOnPause();
         } else {
--- a/mobile/android/tests/browser/chrome/test_get_last_visited.html
+++ b/mobile/android/tests/browser/chrome/test_get_last_visited.html
@@ -12,17 +12,16 @@ https://bugzilla.mozilla.org/show_bug.cg
   <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
   <script type="application/javascript" src="head.js"></script>
   <script type="application/javascript">
 
   "use strict";
 
   ChromeUtils.import("resource://gre/modules/Services.jsm");
   ChromeUtils.import("resource://gre/modules/Messaging.jsm");
-  ChromeUtils.import("resource://gre/modules/Task.jsm");
 
   let chromeWin = Services.wm.getMostRecentWindow("navigator:browser");
   let BrowserApp = chromeWin.BrowserApp;
 
   function get_last_visited(prePath) {
     return EventDispatcher.instance.sendRequestForResult({
       type: "History:GetPrePathLastVisitedTimeMilliseconds",
       prePath: prePath,
--- a/mobile/android/tests/browser/chrome/test_home_provider.html
+++ b/mobile/android/tests/browser/chrome/test_home_provider.html
@@ -12,17 +12,16 @@ Migrated from Robocop: https://bugzilla.
   <link rel="stylesheet" type="text/css" href="chrome://global/skin"/>
   <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
   <script type="application/javascript">
 
   ChromeUtils.import("resource://gre/modules/HomeProvider.jsm");
   ChromeUtils.import("resource://gre/modules/osfile.jsm");
   ChromeUtils.import("resource://gre/modules/Services.jsm");
   ChromeUtils.import("resource://gre/modules/Sqlite.jsm");
-  ChromeUtils.import("resource://gre/modules/Task.jsm");
 
   const TEST_DATASET_ID = "test-dataset-id";
   const TEST_URL = "http://test.com";
   const TEST_TITLE = "Test";
   const TEST_BACKGROUND_URL = "http://example.com/background";
   const TEST_BACKGROUND_COLOR = "#FF9500";
 
   const PREF_SYNC_CHECK_INTERVAL_SECS = "home.sync.checkIntervalSecs";
--- a/mobile/android/tests/browser/chrome/test_media_playback.html
+++ b/mobile/android/tests/browser/chrome/test_media_playback.html
@@ -9,17 +9,16 @@
   <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
   <script type="application/javascript" src="head.js"></script>
   <script type="application/javascript">
 
 "use strict";
 
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
-ChromeUtils.import("resource://gre/modules/Task.jsm");
 
 let gChromeWin;
 let gBrowserApp;
 
 const URL = "http://example.org/chrome/mobile/android/tests/browser/chrome/media_playback.html";
 
 // Waiting for a tab to load or restore can be slow on the emulator.
 SimpleTest.requestLongerTimeout(2);
--- a/mobile/android/tests/browser/chrome/test_mozAutoplayMediaBlocked.html
+++ b/mobile/android/tests/browser/chrome/test_mozAutoplayMediaBlocked.html
@@ -15,17 +15,16 @@
  */
 
 "use strict";
 
 /* globals InspectorUtils */
 
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
-ChromeUtils.import("resource://gre/modules/Task.jsm");
 
 let gChromeWin;
 let gBrowserApp;
 
 const URL = "http://example.org/chrome/mobile/android/tests/browser/chrome/media_playback.html";
 
 // Waiting for a tab to load or restore can be slow on the emulator.
 SimpleTest.requestLongerTimeout(2);
--- a/mobile/android/tests/browser/chrome/test_offline_page.html
+++ b/mobile/android/tests/browser/chrome/test_offline_page.html
@@ -13,17 +13,16 @@ Migrated from Robocop: https://bugzilla.
   <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
   <script type="application/javascript" src="head.js"></script>
   <script type="application/javascript">
 
   "use strict";
 
   ChromeUtils.import("resource://gre/modules/Services.jsm");
   ChromeUtils.import("resource://gre/modules/Messaging.jsm");
-  ChromeUtils.import("resource://gre/modules/Task.jsm");
 
   // Provide a helper to yield until we are sure the offline state has changed
   function promiseOffline(isOffline) {
     return new Promise((resolve, reject) => {
       function observe(subject, topic, data) {
         info("Received topic: " + topic);
         Services.obs.removeObserver(observe, "network:offline-status-changed");
         resolve();
--- a/mobile/android/tests/browser/chrome/test_selectoraddtab.html
+++ b/mobile/android/tests/browser/chrome/test_selectoraddtab.html
@@ -12,17 +12,16 @@ https://bugzilla.mozilla.org/show_bug.cg
   <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
   <script type="application/javascript" src="head.js"></script>
   <script type="application/javascript">
 
   "use strict";
 
   ChromeUtils.import("resource://gre/modules/Services.jsm");
   ChromeUtils.import("resource://gre/modules/Messaging.jsm");
-  ChromeUtils.import("resource://gre/modules/Task.jsm");
 
   // The chrome window
   let chromeWin = Services.wm.getMostRecentWindow("navigator:browser");
   let BrowserApp = chromeWin.BrowserApp;
 
   // Track the tabs where the tests are happening
   let tabBlank;
   let tabTest;
--- a/mobile/android/tests/browser/chrome/test_session_clear_history.html
+++ b/mobile/android/tests/browser/chrome/test_session_clear_history.html
@@ -15,17 +15,16 @@ https://bugzilla.mozilla.org/show_bug.cg
 
   /** Test for Bug 1343603 **/
 
   "use strict";
 
   ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
   ChromeUtils.import("resource://gre/modules/Services.jsm");
   ChromeUtils.import("resource://gre/modules/Messaging.jsm");
-  ChromeUtils.import("resource://gre/modules/Task.jsm");
 
   // The chrome window
   let chromeWin = Services.wm.getMostRecentWindow("navigator:browser");
   let BrowserApp = chromeWin.BrowserApp;
 
   // Track the tabs where the tests are happening
   let tabBlank;
   let tabTest;
--- a/mobile/android/tests/browser/chrome/test_session_parentid.html
+++ b/mobile/android/tests/browser/chrome/test_session_parentid.html
@@ -15,17 +15,16 @@ https://bugzilla.mozilla.org/show_bug.cg
 
   /** Test for Bug 1301160 **/
 
   "use strict";
 
   ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
   ChromeUtils.import("resource://gre/modules/Services.jsm");
   ChromeUtils.import("resource://gre/modules/Messaging.jsm");
-  ChromeUtils.import("resource://gre/modules/Task.jsm");
 
   // The chrome window and related services
   let chromeWin = Services.wm.getMostRecentWindow("navigator:browser");
   let BrowserApp = chromeWin.BrowserApp;
   let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
 
   // Track the tabs where the tests are happening
   let tabParent;
--- a/mobile/android/tests/browser/chrome/test_session_zombification.html
+++ b/mobile/android/tests/browser/chrome/test_session_zombification.html
@@ -15,17 +15,16 @@ https://bugzilla.mozilla.org/show_bug.cg
 
   /** Test for Bug 1044556 **/
 
   "use strict";
 
   ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
   ChromeUtils.import("resource://gre/modules/Services.jsm");
   ChromeUtils.import("resource://gre/modules/Messaging.jsm");
-  ChromeUtils.import("resource://gre/modules/Task.jsm");
 
   // The chrome window
   let chromeWin = Services.wm.getMostRecentWindow("navigator:browser");
   let BrowserApp = chromeWin.BrowserApp;
 
   // Track the tabs where the tests are happening
   let tabBlank;
   let tabTest;
--- a/mobile/android/tests/browser/chrome/test_settings_fontinflation.html
+++ b/mobile/android/tests/browser/chrome/test_settings_fontinflation.html
@@ -17,17 +17,16 @@ https://bugzilla.mozilla.org/show_bug.cg
   /** Test for Bug 1328868 **/
 
   "use strict";
 
   ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
   ChromeUtils.import("resource://gre/modules/Services.jsm");
   ChromeUtils.import("resource://gre/modules/Messaging.jsm");
   ChromeUtils.import("resource://gre/modules/Promise.jsm");
-  ChromeUtils.import("resource://gre/modules/Task.jsm");
   ChromeUtils.import("resource://gre/modules/SharedPreferences.jsm");
 
   const GECKO_PREF_FONT_INFLATION = "font.size.inflation.minTwips";
   const FONT_INFLATION_DEFAULT_VALUE = 120;
   const GECKO_PREF_FONT_SCALE = "font.size.systemFontScale";
   const ANDROID_PREF = "android.not_a_preference.font.size.use_system_font_size";
 
   // The chrome window
--- a/mobile/android/tests/browser/chrome/test_shared_preferences.html
+++ b/mobile/android/tests/browser/chrome/test_shared_preferences.html
@@ -11,17 +11,16 @@ Migrated from Robocop: https://bugzilla.
   <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/AddTask.js"></script>
   <link rel="stylesheet" type="text/css" href="chrome://global/skin"/>
   <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
   <script type="application/javascript" src="head.js"></script>
   <script type="application/javascript">
 
   ChromeUtils.import("resource://gre/modules/SharedPreferences.jsm");
   ChromeUtils.import("resource://gre/modules/Promise.jsm");
-  ChromeUtils.import("resource://gre/modules/Task.jsm");
 
   let _observerId = 0;
 
   add_task(async function test_get_set() {
     let branch = SharedPreferences.forAndroid("test");
 
     branch.setBoolPref("boolKey", true);
     branch.setCharPref("charKey", "string value");
--- a/mobile/android/tests/browser/chrome/test_web_channel.html
+++ b/mobile/android/tests/browser/chrome/test_web_channel.html
@@ -11,17 +11,16 @@ Migrated from Robocop: https://bugzilla.
   <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/AddTask.js"></script>
   <link rel="stylesheet" type="text/css" href="chrome://global/skin"/>
   <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
   <script type="application/javascript">
 
   ChromeUtils.import("resource://gre/modules/Promise.jsm");
   ChromeUtils.import("resource://gre/modules/Services.jsm");
   ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-  ChromeUtils.import("resource://gre/modules/Task.jsm");
   ChromeUtils.defineModuleGetter(this, "WebChannel",
     "resource://gre/modules/WebChannel.jsm");
 
   const HTTP_PATH = "http://mochi.test:8888";
   const HTTP_ENDPOINT = "/chrome/mobile/android/tests/browser/chrome/web_channel.html";
 
   const gChromeWin = Services.wm.getMostRecentWindow("navigator:browser");
   let BrowserApp = gChromeWin.BrowserApp;
--- a/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testJarReader.java
+++ b/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testJarReader.java
@@ -23,17 +23,17 @@ public class testJarReader extends OldBa
         mAsserter.ok(!s.toLowerCase().contains("%2f"), "Path characters aren't escaped.", null);
 
         final Context context = getInstrumentation().getTargetContext().getApplicationContext();
         String appPath = getActivity().getApplication().getPackageResourcePath();
         mAsserter.isnot(appPath, null, "getPackageResourcePath is non-null");
 
         // Test reading a file from a jar url that looks correct.
         String url = "jar:file://" + appPath + "!/" + AppConstants.OMNIJAR_NAME;
-        InputStream stream = GeckoJarReader.getStream(context, "jar:" + url + "!/chrome/chrome/content/branding/favicon32.png");
+        InputStream stream = GeckoJarReader.getStream(context, "jar:" + url + "!/chrome/geckoview/content/branding/favicon32.png");
         mAsserter.isnot(stream, null, "JarReader returned non-null for valid file in valid jar");
 
         // Test looking for an non-existent file in a jar.
         url = "jar:file://" + appPath + "!/" + AppConstants.OMNIJAR_NAME;
         stream = GeckoJarReader.getStream(context, "jar:" + url + "!/chrome/chrome/content/branding/nonexistent_file.png");
         mAsserter.is(stream, null, "JarReader returned null for non-existent file in valid jar");
 
         // Test looking for a file that doesn't exist in the APK.
--- a/mobile/android/tests/browser/robocop/testReadingListCache.js
+++ b/mobile/android/tests/browser/robocop/testReadingListCache.js
@@ -2,17 +2,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* globals ReaderMode */
 
 ChromeUtils.import("resource://gre/modules/ReaderMode.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
-ChromeUtils.import("resource://gre/modules/Task.jsm");
 
 var Reader = Services.wm.getMostRecentWindow("navigator:browser").Reader;
 
 const URL_PREFIX = "http://mochi.test:8888/tests/robocop/reader_mode_pages/";
 
 var TEST_PAGES = [
   {
     url: URL_PREFIX + "basic_article.html",
--- a/mobile/android/tests/browser/robocop/testThemeInstall.js
+++ b/mobile/android/tests/browser/robocop/testThemeInstall.js
@@ -1,17 +1,16 @@
 // -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.import("resource://gre/modules/Messaging.jsm");
-ChromeUtils.import("resource://gre/modules/Task.jsm");
 
 // The chrome window and friends.
 let chromeWin = Services.wm.getMostRecentWindow("navigator:browser");
 let BrowserApp = chromeWin.BrowserApp;
 
 const BASE = "https://example.com:443/tests/robocop/";
 const XPI = BASE + "browser_theme_image_file.xpi";
 const PAGE = BASE + "robocop_blank_04.html";
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -44,21 +44,22 @@
 #include "mozilla/ipc/BackgroundUtils.h"
 #include "mozilla/net/ChannelDiverterChild.h"
 #include "mozilla/net/DNS.h"
 #include "SerializedLoadContext.h"
 #include "nsInputStreamPump.h"
 #include "InterceptedChannel.h"
 #include "mozIThirdPartyUtil.h"
 #include "nsContentSecurityManager.h"
+#include "nsICompressConvStats.h"
 #include "nsIDeprecationWarner.h"
-#include "nsICompressConvStats.h"
 #include "nsIDocument.h"
 #include "nsIDOMWindowUtils.h"
 #include "nsIEventTarget.h"
+#include "nsIScriptError.h"
 #include "nsRedirectHistoryEntry.h"
 #include "nsSocketTransportService2.h"
 #include "nsStreamUtils.h"
 #include "nsThreadUtils.h"
 #include "nsCORSListenerProxy.h"
 #include "nsApplicationCache.h"
 #include "TrackingDummyChannel.h"
 
@@ -3780,16 +3781,43 @@ HttpChannelChild::LogBlockedCORSRequest(
     bool privateBrowsing =
         !!mLoadInfo->GetOriginAttributes().mPrivateBrowsingId;
     nsCORSListenerProxy::LogBlockedCORSRequest(innerWindowID, privateBrowsing,
                                                aMessage, aCategory);
   }
   return NS_OK;
 }
 
+mozilla::ipc::IPCResult HttpChannelChild::RecvLogMimeTypeMismatch(
+    const nsCString& aMessageName, const bool& aWarning, const nsString& aURL,
+    const nsString& aContentType) {
+  Unused << LogMimeTypeMismatch(aMessageName, aWarning, aURL, aContentType);
+  return IPC_OK();
+}
+
+NS_IMETHODIMP
+HttpChannelChild::LogMimeTypeMismatch(const nsACString& aMessageName,
+                                      bool aWarning, const nsAString& aURL,
+                                      const nsAString& aContentType) {
+  nsCOMPtr<nsIDocument> doc;
+  if (mLoadInfo) {
+    mLoadInfo->GetLoadingDocument(getter_AddRefs(doc));
+  }
+
+  nsAutoString url(aURL);
+  nsAutoString contentType(aContentType);
+  const char16_t* params[] = { url.get(), contentType.get() };
+  nsContentUtils::ReportToConsole(
+      aWarning ? nsIScriptError::warningFlag : nsIScriptError::errorFlag,
+      NS_LITERAL_CSTRING("MIMEMISMATCH"), doc,
+      nsContentUtils::eSECURITY_PROPERTIES, nsCString(aMessageName).get(),
+      params, ArrayLength(params));
+  return NS_OK;
+}
+
 void HttpChannelChild::MaybeCallSynthesizedCallback() {
   if (!mSynthesizedCallback) {
     return;
   }
 
   mSynthesizedCallback->BodyComplete(mStatus);
   mSynthesizedCallback = nullptr;
 }
--- a/netwerk/protocol/http/HttpChannelChild.h
+++ b/netwerk/protocol/http/HttpChannelChild.h
@@ -199,16 +199,23 @@ class HttpChannelChild final : public PH
   // Get event target for processing network events.
   already_AddRefed<nsIEventTarget> GetNeckoTarget() override;
 
   virtual mozilla::ipc::IPCResult RecvLogBlockedCORSRequest(
       const nsString& aMessage, const nsCString& aCategory) override;
   NS_IMETHOD LogBlockedCORSRequest(const nsAString& aMessage,
                                    const nsACString& aCategory) override;
 
+  virtual mozilla::ipc::IPCResult RecvLogMimeTypeMismatch(
+      const nsCString& aMessageName, const bool& aWarning, const nsString& aURL,
+      const nsString& aContentType) override;
+  NS_IMETHOD LogMimeTypeMismatch(const nsACString& aMessageName, bool aWarning,
+                                 const nsAString& aURL,
+                                 const nsAString& aContentType) override;
+
  private:
   nsresult AsyncCallImpl(void (HttpChannelChild::*funcPtr)(),
                          nsRunnableMethod<HttpChannelChild>** retval);
 
   class OverrideRunnable : public Runnable {
    public:
     OverrideRunnable(HttpChannelChild* aChannel, HttpChannelChild* aNewChannel,
                      InterceptStreamListener* aListener, nsIInputStream* aInput,
--- a/netwerk/protocol/http/HttpChannelParent.cpp
+++ b/netwerk/protocol/http/HttpChannelParent.cpp
@@ -2391,10 +2391,22 @@ nsresult HttpChannelParent::LogBlockedCO
                                                   const nsACString& aCategory) {
   if (mIPCClosed || NS_WARN_IF(!SendLogBlockedCORSRequest(
                         nsString(aMessage), nsCString(aCategory)))) {
     return NS_ERROR_UNEXPECTED;
   }
   return NS_OK;
 }
 
+nsresult HttpChannelParent::LogMimeTypeMismatch(const nsACString& aMessageName,
+                                                bool aWarning,
+                                                const nsAString& aURL,
+                                                const nsAString& aContentType) {
+  if (mIPCClosed || NS_WARN_IF(!SendLogMimeTypeMismatch(
+                        nsCString(aMessageName), aWarning, nsString(aURL),
+                        nsString(aContentType)))) {
+    return NS_ERROR_UNEXPECTED;
+  }
+  return NS_OK;
+}
+
 }  // namespace net
 }  // namespace mozilla
--- a/netwerk/protocol/http/HttpChannelParent.h
+++ b/netwerk/protocol/http/HttpChannelParent.h
@@ -211,16 +211,19 @@ class HttpChannelParent final : public n
 
   friend class HttpChannelParentListener;
   RefPtr<mozilla::dom::TabParent> mTabParent;
 
   MOZ_MUST_USE nsresult ReportSecurityMessage(
       const nsAString& aMessageTag, const nsAString& aMessageCategory) override;
   nsresult LogBlockedCORSRequest(const nsAString& aMessage,
                                  const nsACString& aCategory) override;
+  nsresult LogMimeTypeMismatch(const nsACString& aMessageName, bool aWarning,
+                               const nsAString& aURL,
+                               const nsAString& aContentType) override;
 
   // Calls SendDeleteSelf and sets mIPCClosed to true because we should not
   // send any more messages after that. Bug 1274886
   MOZ_MUST_USE bool DoSendDeleteSelf();
   // Called to notify the parent channel to not send any more IPC messages.
   virtual mozilla::ipc::IPCResult RecvDeletingChannel() override;
   virtual mozilla::ipc::IPCResult RecvFinishInterceptedRedirect() override;
 
--- a/netwerk/protocol/http/InterceptedHttpChannel.cpp
+++ b/netwerk/protocol/http/InterceptedHttpChannel.cpp
@@ -550,16 +550,24 @@ InterceptedHttpChannel::AsyncOpen2(nsISt
 NS_IMETHODIMP
 InterceptedHttpChannel::LogBlockedCORSRequest(const nsAString& aMessage,
                                               const nsACString& aCategory) {
   // Synthetic responses should not trigger CORS blocking.
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
+InterceptedHttpChannel::LogMimeTypeMismatch(const nsACString& aMessageName,
+                                            bool aWarning,
+                                            const nsAString& aURL,
+                                            const nsAString& aContentType) {
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
 InterceptedHttpChannel::SetupFallbackChannel(const char* aFallbackKey) {
   // AppCache should not be used with service worker intercepted channels.
   // This should never be called.
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 InterceptedHttpChannel::SetPriority(int32_t aPriority) {
--- a/netwerk/protocol/http/InterceptedHttpChannel.h
+++ b/netwerk/protocol/http/InterceptedHttpChannel.h
@@ -153,16 +153,21 @@ class InterceptedHttpChannel final
   NS_IMETHOD
   AsyncOpen2(nsIStreamListener* aListener) override;
 
   NS_IMETHOD
   LogBlockedCORSRequest(const nsAString& aMessage,
                         const nsACString& aCategory) override;
 
   NS_IMETHOD
+  LogMimeTypeMismatch(const nsACString& aMessageName, bool aWarning,
+                      const nsAString& aURL,
+                      const nsAString& aContentType) override;
+
+  NS_IMETHOD
   SetupFallbackChannel(const char* aFallbackKey) override;
 
   NS_IMETHOD
   SetPriority(int32_t aPriority) override;
 
   NS_IMETHOD
   SetClassFlags(uint32_t aClassFlags) override;
 
--- a/netwerk/protocol/http/NullHttpChannel.cpp
+++ b/netwerk/protocol/http/NullHttpChannel.cpp
@@ -785,16 +785,23 @@ NullHttpChannel::SetIsMainDocumentChanne
 
 NS_IMETHODIMP
 NullHttpChannel::LogBlockedCORSRequest(const nsAString &aMessage,
                                        const nsACString &aCategory) {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
+NullHttpChannel::LogMimeTypeMismatch(const nsACString &aMessageName,
+                                     bool aWarning, const nsAString &aURL,
+                                     const nsAString &aContentType) {
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
 NullHttpChannel::SetReportResourceTiming(bool enabled) {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 NullHttpChannel::GetReportResourceTiming(bool *_retval) {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
--- a/netwerk/protocol/http/PHttpChannel.ipdl
+++ b/netwerk/protocol/http/PHttpChannel.ipdl
@@ -164,16 +164,21 @@ child:
   // Tell the child to issue a deprecation warning.
   async IssueDeprecationWarning(uint32_t warning, bool asError);
 
   // When CORS blocks the request in the parent process, it doesn't have the
   // correct window ID, so send the message to the child for logging to the web
   // console.
   async LogBlockedCORSRequest(nsString message, nsCString category);
 
+  async LogMimeTypeMismatch(nsCString messageName,
+                            bool warning,
+                            nsString url,
+                            nsString contentType);
+
   async AttachStreamFilter(Endpoint<PStreamFilterParent> aEndpoint);
 
   // See ADivertableParentChannel::CancelDiversion
   async CancelDiversion();
 
   async OriginalCacheInputStreamAvailable(OptionalIPCStream stream);
 both:
   // After receiving this message, the parent also calls
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -399,16 +399,27 @@ NS_IMETHODIMP
 nsHttpChannel::LogBlockedCORSRequest(const nsAString &aMessage,
                                      const nsACString &aCategory) {
   if (mWarningReporter) {
     return mWarningReporter->LogBlockedCORSRequest(aMessage, aCategory);
   }
   return NS_ERROR_UNEXPECTED;
 }
 
+NS_IMETHODIMP
+nsHttpChannel::LogMimeTypeMismatch(const nsACString &aMessageName,
+                                   bool aWarning, const nsAString &aURL,
+                                   const nsAString &aContentType) {
+  if (mWarningReporter) {
+    return mWarningReporter->LogMimeTypeMismatch(aMessageName, aWarning, aURL,
+                                                 aContentType);
+  }
+  return NS_ERROR_UNEXPECTED;
+}
+
 //-----------------------------------------------------------------------------
 // nsHttpChannel <private>
 //-----------------------------------------------------------------------------
 
 nsresult nsHttpChannel::PrepareToConnect() {
   LOG(("nsHttpChannel::PrepareToConnect [this=%p]\n", this));
 
   AddCookiesToRequest();
@@ -1201,32 +1212,28 @@ nsresult nsHttpChannel::SetupTransaction
 
   rv = nsInputStreamPump::Create(getter_AddRefs(mTransactionPump),
                                  responseStream);
   return rv;
 }
 
 // Helper Function to report messages to the console when loading
 // a resource was blocked due to a MIME type mismatch.
-void ReportTypeBlocking(nsIURI *aURI, nsILoadInfo *aLoadInfo,
-                        const char *aMessageName) {
-  NS_ConvertUTF8toUTF16 specUTF16(aURI->GetSpecOrDefault());
-  const char16_t *params[] = {specUTF16.get()};
-  nsCOMPtr<nsIDocument> doc;
-  if (aLoadInfo) {
-    aLoadInfo->GetLoadingDocument(getter_AddRefs(doc));
-  }
-  nsContentUtils::ReportToConsole(nsIScriptError::errorFlag,
-                                  NS_LITERAL_CSTRING("MIMEMISMATCH"), doc,
-                                  nsContentUtils::eSECURITY_PROPERTIES,
-                                  aMessageName, params, ArrayLength(params));
+void ReportTypeBlocking(nsHttpChannel *aChannel, const char *aMessageName,
+                        nsIURI *aURI, const nsACString &aContentType) {
+  NS_ConvertUTF8toUTF16 spec(aURI->GetSpecOrDefault());
+  NS_ConvertUTF8toUTF16 contentType(aContentType);
+
+  aChannel->LogMimeTypeMismatch(nsCString(aMessageName), false, spec,
+                                contentType);
 }
 
 // Check and potentially enforce X-Content-Type-Options: nosniff
-nsresult ProcessXCTO(nsIURI *aURI, nsHttpResponseHead *aResponseHead,
+nsresult ProcessXCTO(nsHttpChannel *aChannel, nsIURI *aURI,
+                     nsHttpResponseHead *aResponseHead,
                      nsILoadInfo *aLoadInfo) {
   if (!aURI || !aResponseHead || !aLoadInfo) {
     // if there is no uri, no response head or no loadInfo, then there is
     // nothing to do
     return NS_OK;
   }
 
   // 1) Query the XCTO header and check if 'nosniff' is the first value.
@@ -1271,34 +1278,35 @@ nsresult ProcessXCTO(nsIURI *aURI, nsHtt
   aResponseHead->ContentType(contentType);
 
   // 3) Compare the expected MIME type with the actual type
   if (aLoadInfo->GetExternalContentPolicyType() ==
       nsIContentPolicy::TYPE_STYLESHEET) {
     if (contentType.EqualsLiteral(TEXT_CSS)) {
       return NS_OK;
     }
-    ReportTypeBlocking(aURI, aLoadInfo, "MimeTypeMismatch");
+    ReportTypeBlocking(aChannel, "MimeTypeMismatch2", aURI, contentType);
     return NS_ERROR_CORRUPTED_CONTENT;
   }
 
   if (aLoadInfo->GetExternalContentPolicyType() ==
       nsIContentPolicy::TYPE_SCRIPT) {
     if (nsContentUtils::IsJavascriptMIMEType(
             NS_ConvertUTF8toUTF16(contentType))) {
       return NS_OK;
     }
-    ReportTypeBlocking(aURI, aLoadInfo, "MimeTypeMismatch");
+    ReportTypeBlocking(aChannel, "MimeTypeMismatch2", aURI, contentType);
     return NS_ERROR_CORRUPTED_CONTENT;
   }
   return NS_OK;
 }
 
 // Ensure that a load of type script has correct MIME type
-nsresult EnsureMIMEOfScript(nsIURI *aURI, nsHttpResponseHead *aResponseHead,
+nsresult EnsureMIMEOfScript(nsHttpChannel *aChannel, nsIURI *aURI,
+                            nsHttpResponseHead *aResponseHead,
                             nsILoadInfo *aLoadInfo) {
   if (!aURI || !aResponseHead || !aLoadInfo) {
     // if there is no uri, no response head or no loadInfo, then there is
     // nothing to do
     return NS_OK;
   }
 
   if (aLoadInfo->GetExternalContentPolicyType() !=
@@ -1420,17 +1428,18 @@ nsresult EnsureMIMEOfScript(nsIURI *aURI
                                    "security.block_script_with_wrong_mime");
     }
 
     // Do not block the load if the feature is not enabled.
     if (!sCachedBlockScriptWithWrongMime) {
       return NS_OK;
     }
 
-    ReportTypeBlocking(aURI, aLoadInfo, "BlockScriptWithWrongMimeType");
+    ReportTypeBlocking(aChannel, "BlockScriptWithWrongMimeType2", aURI,
+                       contentType);
     return NS_ERROR_CORRUPTED_CONTENT;
   }
 
   if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("text/plain"))) {
     // script load has type text/plain
     AccumulateCategorical(
         Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_plain);
     return NS_OK;
@@ -1527,20 +1536,20 @@ nsresult nsHttpChannel::CallOnStartReque
     if (mListener) {
       nsCOMPtr<nsIStreamListener> deleteProtector(mListener);
       deleteProtector->OnStartRequest(this, mListenerContext);
     }
 
     mOnStartRequestCalled = true;
   });
 
-  nsresult rv = EnsureMIMEOfScript(mURI, mResponseHead, mLoadInfo);
+  nsresult rv = EnsureMIMEOfScript(this, mURI, mResponseHead, mLoadInfo);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  rv = ProcessXCTO(mURI, mResponseHead, mLoadInfo);
+  rv = ProcessXCTO(this, mURI, mResponseHead, mLoadInfo);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Allow consumers to override our content type
   if (mLoadFlags & LOAD_CALL_CONTENT_SNIFFERS) {
     // NOTE: We can have both a txn pump and a cache pump when the cache
     // content is partial. In that case, we need to read from the cache,
     // because that's the one that has the initial contents. If that fails
     // then give the transaction pump a shot.
--- a/netwerk/protocol/http/nsHttpChannel.h
+++ b/netwerk/protocol/http/nsHttpChannel.h
@@ -46,18 +46,21 @@ namespace net {
 
 class nsChannelClassifier;
 class Http2PushedStream;
 
 class HttpChannelSecurityWarningReporter : public nsISupports {
  public:
   virtual MOZ_MUST_USE nsresult ReportSecurityMessage(
       const nsAString &aMessageTag, const nsAString &aMessageCategory) = 0;
-  virtual nsresult LogBlockedCORSRequest(const nsAString &aMessage,
-                                         const nsACString &aCategory) = 0;
+  virtual MOZ_MUST_USE nsresult LogBlockedCORSRequest(
+      const nsAString &aMessage, const nsACString &aCategory) = 0;
+  virtual MOZ_MUST_USE nsresult
+  LogMimeTypeMismatch(const nsACString &aMessageName, bool aWarning,
+                      const nsAString &aURL, const nsAString &aContentType) = 0;
 };
 
 //-----------------------------------------------------------------------------
 // nsHttpChannel
 //-----------------------------------------------------------------------------
 
 // Use to support QI nsIChannel to nsHttpChannel
 #define NS_HTTPCHANNEL_IID                           \
@@ -194,16 +197,19 @@ class nsHttpChannel final : public HttpB
   // nsICorsPreflightCallback
   NS_IMETHOD OnPreflightSucceeded() override;
   NS_IMETHOD OnPreflightFailed(nsresult aError) override;
 
   MOZ_MUST_USE nsresult AddSecurityMessage(
       const nsAString &aMessageTag, const nsAString &aMessageCategory) override;
   NS_IMETHOD LogBlockedCORSRequest(const nsAString &aMessage,
                                    const nsACString &aCategory) override;
+  NS_IMETHOD LogMimeTypeMismatch(const nsACString &aMessageName, bool aWarning,
+                                 const nsAString &aURL,
+                                 const nsAString &aContentType) override;
 
   void SetWarningReporter(HttpChannelSecurityWarningReporter *aReporter);
   HttpChannelSecurityWarningReporter *GetWarningReporter();
 
  public: /* internal necko use only */
   uint32_t GetRequestTime() const { return mRequestTime; }
 
   nsresult AsyncOpenFinal(TimeStamp aTimeStamp);
--- a/netwerk/protocol/http/nsIHttpChannel.idl
+++ b/netwerk/protocol/http/nsIHttpChannel.idl
@@ -526,9 +526,14 @@ interface nsIHttpChannel : nsIChannel
      *
      * @param aMessage
      *        The message to print in the console.
      *
      * @param aCategory
      *        The category under which the message should be displayed.
      */
     void logBlockedCORSRequest(in AString aMessage, in ACString aCategory);
+
+    void logMimeTypeMismatch(in ACString aMessageName,
+                             in boolean aWarning,
+                             in AString aURL,
+                             in AString aContentType);
 };
--- a/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
+++ b/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
@@ -1040,16 +1040,28 @@ nsViewSourceChannel::LogBlockedCORSReque
   if (!mHttpChannel) {
     NS_WARNING(
         "nsViewSourceChannel::LogBlockedCORSRequest mHttpChannel is null");
     return NS_ERROR_UNEXPECTED;
   }
   return mHttpChannel->LogBlockedCORSRequest(aMessage, aCategory);
 }
 
+NS_IMETHODIMP
+nsViewSourceChannel::LogMimeTypeMismatch(const nsACString &aMessageName,
+                                         bool aWarning, const nsAString &aURL,
+                                         const nsAString &aContentType) {
+  if (!mHttpChannel) {
+    NS_WARNING("nsViewSourceChannel::LogMimeTypeMismatch mHttpChannel is null");
+    return NS_ERROR_UNEXPECTED;
+  }
+  return mHttpChannel->LogMimeTypeMismatch(aMessageName, aWarning, aURL,
+                                           aContentType);
+}
+
 const nsTArray<mozilla::Tuple<nsCString, nsCString>>
     &nsViewSourceChannel::PreferredAlternativeDataTypes() {
   if (mCacheInfoChannel) {
     return mCacheInfoChannel->PreferredAlternativeDataTypes();
   }
   return mEmptyArray;
 }
 
--- a/parser/expat/lib/ascii.h
+++ b/parser/expat/lib/ascii.h
@@ -78,8 +78,15 @@
 #define ASCII_COLON 0x3A
 #define ASCII_SEMI 0x3B
 #define ASCII_LT 0x3C
 #define ASCII_EQUALS 0x3D
 #define ASCII_GT 0x3E
 #define ASCII_LSQB 0x5B
 #define ASCII_RSQB 0x5D
 #define ASCII_UNDERSCORE 0x5F
+#define ASCII_LPAREN 0x28
+#define ASCII_RPAREN 0x29
+#define ASCII_FF 0x0C
+#define ASCII_SLASH 0x2F
+#define ASCII_HASH 0x23
+#define ASCII_PIPE 0x7C
+#define ASCII_COMMA 0x2C
--- a/parser/expat/lib/expat.h
+++ b/parser/expat/lib/expat.h
@@ -90,17 +90,19 @@ enum XML_Error {
   XML_ERROR_SUSPENDED,
   XML_ERROR_NOT_SUSPENDED,
   XML_ERROR_ABORTED,
   XML_ERROR_FINISHED,
   XML_ERROR_SUSPEND_PE,
   /* Added in 2.0. */
   XML_ERROR_RESERVED_PREFIX_XML,
   XML_ERROR_RESERVED_PREFIX_XMLNS,
-  XML_ERROR_RESERVED_NAMESPACE_URI
+  XML_ERROR_RESERVED_NAMESPACE_URI,
+  /* Added in 2.2.1. */
+  XML_ERROR_INVALID_ARGUMENT
 };
 
 enum XML_Content_Type {
   XML_CTYPE_EMPTY = 1,
   XML_CTYPE_ANY,
   XML_CTYPE_MIXED,
   XML_CTYPE_NAME,
   XML_CTYPE_CHOICE,
@@ -701,16 +703,17 @@ XML_UseParserAsHandlerArg(XML_Parser par
      the first call to XML_Parse or XML_ParseBuffer, since it will
      have no effect after that.  Returns
      XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING.
    Note: If the document does not have a DOCTYPE declaration at all,
      then startDoctypeDeclHandler and endDoctypeDeclHandler will not
      be called, despite an external subset being parsed.
    Note: If XML_DTD is not defined when Expat is compiled, returns
      XML_ERROR_FEATURE_REQUIRES_XML_DTD.
+   Note: If parser == NULL, returns XML_ERROR_INVALID_ARGUMENT.
 */
 XMLPARSEAPI(enum XML_Error)
 XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD);
 
 
 /* Sets the base to be used for resolving relative URIs in system
    identifiers in declarations.  Resolving relative identifiers is
    left to the application: this value will be passed through as the
@@ -724,29 +727,53 @@ XML_SetBase(XML_Parser parser, const XML
 
 XMLPARSEAPI(const XML_Char *)
 XML_GetBase(XML_Parser parser);
 
 /* Returns the number of the attribute/value pairs passed in last call
    to the XML_StartElementHandler that were specified in the start-tag
    rather than defaulted. Each attribute/value pair counts as 2; thus
    this correspondds to an index into the atts array passed to the
-   XML_StartElementHandler.
+   XML_StartElementHandler.  Returns -1 if parser == NULL.
 */
 XMLPARSEAPI(int)
 XML_GetSpecifiedAttributeCount(XML_Parser parser);
 
 /* Returns the index of the ID attribute passed in the last call to
-   XML_StartElementHandler, or -1 if there is no ID attribute.  Each
-   attribute/value pair counts as 2; thus this correspondds to an
-   index into the atts array passed to the XML_StartElementHandler.
+   XML_StartElementHandler, or -1 if there is no ID attribute or
+   parser == NULL.  Each attribute/value pair counts as 2; thus this
+   correspondds to an index into the atts array passed to the
+   XML_StartElementHandler.
 */
 XMLPARSEAPI(int)
 XML_GetIdAttributeIndex(XML_Parser parser);
 
+#ifdef XML_ATTR_INFO
+/* Source file byte offsets for the start and end of attribute names and values.
+   The value indices are exclusive of surrounding quotes; thus in a UTF-8 source
+   file an attribute value of "blah" will yield:
+   info->valueEnd - info->valueStart = 4 bytes.
+*/
+typedef struct {
+  XML_Index  nameStart;  /* Offset to beginning of the attribute name. */
+  XML_Index  nameEnd;    /* Offset after the attribute name's last byte. */
+  XML_Index  valueStart; /* Offset to beginning of the attribute value. */
+  XML_Index  valueEnd;   /* Offset after the attribute value's last byte. */
+} XML_AttrInfo;
+
+/* Returns an array of XML_AttrInfo structures for the attribute/value pairs
+   passed in last call to the XML_StartElementHandler that were specified
+   in the start-tag rather than defaulted. Each attribute/value pair counts
+   as 1; thus the number of entries in the array is
+   XML_GetSpecifiedAttributeCount(parser) / 2.
+*/
+XMLPARSEAPI(const XML_AttrInfo *)
+XML_GetAttributeInfo(XML_Parser parser);
+#endif
+
 /* Parses some input. Returns XML_STATUS_ERROR if a fatal error is
    detected.  The last call to XML_Parse must have isFinal true; len
    may be zero for this call (or any other).
 
    Though the return values for these functions has always been
    described as a Boolean value, the implementation, at least for the
    1.95.x series, has always returned exactly one of the XML_Status
    values.
@@ -873,21 +900,32 @@ enum XML_ParamEntityParsing {
    call), it is illegal to make any calls on the old parser until
    XML_ParserFree has been called on the newly created parser.
    If the library has been compiled without support for parameter
    entity parsing (ie without XML_DTD being defined), then
    XML_SetParamEntityParsing will return 0 if parsing of parameter
    entities is requested; otherwise it will return non-zero.
    Note: If XML_SetParamEntityParsing is called after XML_Parse or
       XML_ParseBuffer, then it has no effect and will always return 0.
+   Note: If parser == NULL, the function will do nothing and return 0.
 */
 XMLPARSEAPI(int)
 XML_SetParamEntityParsing(XML_Parser parser,
                           enum XML_ParamEntityParsing parsing);
 
+/* Sets the hash salt to use for internal hash calculations.
+   Helps in preventing DoS attacks based on predicting hash
+   function behavior. This must be called before parsing is started.
+   Returns 1 if successful, 0 when called after parsing has started.
+   Note: If parser == NULL, the function will do nothing and return 0.
+*/
+XMLPARSEAPI(int)
+XML_SetHashSalt(XML_Parser parser,
+                unsigned long hash_salt);
+
 /* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then
    XML_GetErrorCode returns information about the error.
 */
 XMLPARSEAPI(enum XML_Error)
 XML_GetErrorCode(XML_Parser parser);
 
 /* These functions return information about the current parse
    location.  They may be called from any callback called to report
@@ -899,16 +937,20 @@ XML_GetErrorCode(XML_Parser parser);
    functions, the position indicated will be just past the last parse
    event (regardless of whether there was an associated callback).
    
    They may also be called after returning from a call to XML_Parse
    or XML_ParseBuffer.  If the return value is XML_STATUS_ERROR then
    the location is the location of the character at which the error
    was detected; otherwise the location is the location of the last
    parse event, as described above.
+
+   Note: XML_GetCurrentLineNumber and XML_GetCurrentColumnNumber
+   return 0 to indicate an error.
+   Note: XML_GetCurrentByteIndex returns -1 to indicate an error.
 */
 XMLPARSEAPI(XML_Size) XML_GetCurrentLineNumber(XML_Parser parser);
 XMLPARSEAPI(XML_Size) XML_GetCurrentColumnNumber(XML_Parser parser);
 XMLPARSEAPI(XML_Index) XML_GetCurrentByteIndex(XML_Parser parser);
 
 /* Return the number of bytes in the current event.
    Returns 0 if the event is in an internal entity.
 */
@@ -936,19 +978,22 @@ XML_GetInputContext(XML_Parser parser,
 #define XML_GetErrorByteIndex    XML_GetCurrentByteIndex
 
 /* Frees the content model passed to the element declaration handler */
 XMLPARSEAPI(void)
 XML_FreeContentModel(XML_Parser parser, XML_Content *model);
 
 /* Exposing the memory handling functions used in Expat */
 XMLPARSEAPI(void *)
+XML_ATTR_MALLOC
+XML_ATTR_ALLOC_SIZE(2)
 XML_MemMalloc(XML_Parser parser, size_t size);
 
 XMLPARSEAPI(void *)
+XML_ATTR_ALLOC_SIZE(3)
 XML_MemRealloc(XML_Parser parser, void *ptr, size_t size);
 
 XMLPARSEAPI(void)
 XML_MemFree(XML_Parser parser, void *ptr);
 
 /* Frees memory used by the parser. */
 XMLPARSEAPI(void)
 XML_ParserFree(XML_Parser parser);
@@ -978,38 +1023,38 @@ enum XML_FeatureEnum {
   XML_FEATURE_END = 0,
   XML_FEATURE_UNICODE,
   XML_FEATURE_UNICODE_WCHAR_T,
   XML_FEATURE_DTD,
   XML_FEATURE_CONTEXT_BYTES,
   XML_FEATURE_MIN_SIZE,
   XML_FEATURE_SIZEOF_XML_CHAR,
   XML_FEATURE_SIZEOF_XML_LCHAR,
-  XML_FEATURE_NS
+  XML_FEATURE_NS,
+  XML_FEATURE_LARGE_SIZE,
+  XML_FEATURE_ATTR_INFO
   /* Additional features must be added to the end of this enum. */
 };
 
 typedef struct {
   enum XML_FeatureEnum  feature;
   const XML_LChar       *name;
   long int              value;
 } XML_Feature;
 
 XMLPARSEAPI(const XML_Feature *)
 XML_GetFeatureList(void);
 
 
-/* Expat follows the GNU/Linux convention of odd number minor version for
-   beta/development releases and even number minor version for stable
-   releases. Micro is bumped with each release, and set to 0 with each
-   change to major or minor version.
+/* Expat follows the semantic versioning convention.
+   See http://semver.org.
 */
 #define XML_MAJOR_VERSION 2
-#define XML_MINOR_VERSION 0
-#define XML_MICRO_VERSION 0
+#define XML_MINOR_VERSION 2
+#define XML_MICRO_VERSION 1
 
 /* BEGIN MOZILLA CHANGE (Report opening tag of mismatched closing tag) */
 XMLPARSEAPI(const XML_Char*)
 MOZ_XML_GetMismatchedTag(XML_Parser parser);
 /* END MOZILLA CHANGE */
 
 #ifdef __cplusplus
 }
--- a/parser/expat/lib/expat_external.h
+++ b/parser/expat/lib/expat_external.h
@@ -29,19 +29,19 @@
    The XMLCALL macro was added in Expat 1.95.7.  The only one which is
    expected to be directly useful in client code is XMLCALL.
 
    Note that on at least some Unix versions, the Expat library must be
    compiled with the cdecl calling convention as the default since
    system headers may assume the cdecl convention.
 */
 #ifndef XMLCALL
-#if defined(XML_USE_MSC_EXTENSIONS)
+#if defined(_MSC_VER)
 #define XMLCALL __cdecl
-#elif defined(__GNUC__) && defined(__i386)
+#elif defined(__GNUC__) && defined(__i386) && !defined(__INTEL_COMPILER)
 #define XMLCALL __attribute__((cdecl))
 #else
 /* For any platform which uses this definition and supports more than
    one calling convention, we need to extend this definition to
    declare the convention used on that platform, if it's possible to
    do so.
 
    If this is the case for your platform, please file a bug report
@@ -60,31 +60,48 @@
 
 #ifdef XML_USE_MSC_EXTENSIONS
 #define XMLIMPORT __declspec(dllimport)
 #endif
 
 #endif
 #endif  /* not defined XML_STATIC */
 
+#if !defined(XMLIMPORT) && defined(__GNUC__) && (__GNUC__ >= 4)
+#define XMLIMPORT __attribute__ ((visibility ("default")))
+#endif
 
 /* If we didn't define it above, define it away: */
 #ifndef XMLIMPORT
 #define XMLIMPORT
 #endif
 
+#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96))
+#define XML_ATTR_MALLOC __attribute__((__malloc__))
+#else
+#define XML_ATTR_MALLOC
+#endif
+
+#if defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
+#define XML_ATTR_ALLOC_SIZE(x)  __attribute__((__alloc_size__(x)))
+#else
+#define XML_ATTR_ALLOC_SIZE(x)
+#endif
 
 #define XMLPARSEAPI(type) XMLIMPORT type XMLCALL
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 #ifdef XML_UNICODE_WCHAR_T
-#define XML_UNICODE
+# define XML_UNICODE
+# if defined(__SIZEOF_WCHAR_T__) && (__SIZEOF_WCHAR_T__ != 2)
+#  error "sizeof(wchar_t) != 2; Need -fshort-wchar for both Expat and libc"
+# endif
 #endif
 
 /* BEGIN MOZILLA CHANGE (typedef XML_Char to char16_t) */
 #if 0
 
 #ifdef XML_UNICODE     /* Information is UTF-16 encoded. */
 #ifdef XML_UNICODE_WCHAR_T
 typedef wchar_t XML_Char;
--- a/parser/expat/lib/internal.h
+++ b/parser/expat/lib/internal.h
@@ -11,21 +11,21 @@
 
    PTRCALL     - Used for functions called though function pointers.
 
    PTRFASTCALL - Like PTRCALL, but for low number of arguments.
 
    inline      - Used for selected internal functions for which inlining
                  may improve performance on some platforms.
 
-   Note: Use of these macros is based on judgment, not hard rules,
+   Note: Use of these macros is based on judgement, not hard rules,
          and therefore subject to change.
 */
 
-#if defined(__GNUC__) && defined(__i386__)
+#if defined(__GNUC__) && defined(__i386__) && !defined(__MINGW32__)
 /* We'll use this version by default only where we know it helps.
 
    regparm() generates warnings on Solaris boxes.   See SF bug #692878.
 
    Instability reported with egcs on a RedHat Linux 7.3.
    Let's comment out:
    #define FASTCALL __attribute__((stdcall, regparm(3)))
    and let's try this:
@@ -66,8 +66,30 @@
 
 #ifdef __cplusplus
 #define inline inline
 #else
 #ifndef inline
 #define inline
 #endif
 #endif
+
+#ifndef UNUSED_P
+# ifdef __GNUC__
+#  define UNUSED_P(p) UNUSED_ ## p __attribute__((__unused__))
+# else
+#  define UNUSED_P(p) UNUSED_ ## p
+# endif
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+void
+align_limit_to_full_utf8_characters(const char * from, const char ** fromLimRef);
+
+
+#ifdef __cplusplus
+}
+#endif
new file mode 100644
--- /dev/null
+++ b/parser/expat/lib/siphash.h
@@ -0,0 +1,344 @@
+/* ==========================================================================
+ * siphash.h - SipHash-2-4 in a single header file
+ * --------------------------------------------------------------------------
+ * Derived by William Ahern from the reference implementation[1] published[2]
+ * by Jean-Philippe Aumasson and Daniel J. Berstein. Licensed in kind.
+ * by Jean-Philippe Aumasson and Daniel J. Berstein.
+ * Minimal changes by Sebastian Pipping on top, details below.
+ * Licensed under the CC0 Public Domain Dedication license.
+ *
+ * 1. https://www.131002.net/siphash/siphash24.c
+ * 2. https://www.131002.net/siphash/
+ * --------------------------------------------------------------------------
+ * HISTORY:
+ *
+ * 2017-06-10  (Sebastian Pipping)
+ *   - Clarify license note in the header
+ *   - Address C89 issues:
+ *     - Stop using inline keyword (and let compiler decide)
+ *     - Turn integer suffix ULL to UL
+ *     - Replace _Bool by int
+ *     - Turn macro siphash24 into a function
+ *     - Address invalid conversion (void pointer) by explicit cast
+ *   - Always expose sip24_valid (for self-tests)
+ *
+ * 2012-11-04 - Born.  (William Ahern)
+ * --------------------------------------------------------------------------
+ * USAGE:
+ *
+ * SipHash-2-4 takes as input two 64-bit words as the key, some number of
+ * message bytes, and outputs a 64-bit word as the message digest. This
+ * implementation employs two data structures: a struct sipkey for
+ * representing the key, and a struct siphash for representing the hash
+ * state.
+ *
+ * For converting a 16-byte unsigned char array to a key, use either the
+ * macro sip_keyof or the routine sip_tokey. The former instantiates a
+ * compound literal key, while the latter requires a key object as a
+ * parameter.
+ *
+ * 	unsigned char secret[16];
+ * 	arc4random_buf(secret, sizeof secret);
+ * 	struct sipkey *key = sip_keyof(secret);
+ *
+ * For hashing a message, use either the convenience macro siphash24 or the
+ * routines sip24_init, sip24_update, and sip24_final.
+ *
+ * 	struct siphash state;
+ * 	void *msg;
+ * 	size_t len;
+ * 	uint64_t hash;
+ *
+ * 	sip24_init(&state, key);
+ * 	sip24_update(&state, msg, len);
+ * 	hash = sip24_final(&state);
+ *
+ * or
+ *
+ * 	hash = siphash24(msg, len, key);
+ *
+ * To convert the 64-bit hash value to a canonical 8-byte little-endian
+ * binary representation, use either the macro sip_binof or the routine
+ * sip_tobin. The former instantiates and returns a compound literal array,
+ * while the latter requires an array object as a parameter.
+ * --------------------------------------------------------------------------
+ * NOTES:
+ *
+ * o Neither sip_keyof, sip_binof, nor siphash24 will work with compilers
+ *   lacking compound literal support. Instead, you must use the lower-level
+ *   interfaces which take as parameters the temporary state objects.
+ *
+ * o Uppercase macros may evaluate parameters more than once. Lowercase
+ *   macros should not exhibit any such side effects.
+ * ==========================================================================
+ */
+#ifndef SIPHASH_H
+#define SIPHASH_H
+
+#include <stddef.h> /* size_t */
+#include <stdint.h> /* uint64_t uint32_t uint8_t */
+
+
+#define SIP_ROTL(x, b) (uint64_t)(((x) << (b)) | ( (x) >> (64 - (b))))
+
+#define SIP_U32TO8_LE(p, v) \
+	(p)[0] = (uint8_t)((v) >>  0); (p)[1] = (uint8_t)((v) >>  8); \
+	(p)[2] = (uint8_t)((v) >> 16); (p)[3] = (uint8_t)((v) >> 24);
+
+#define SIP_U64TO8_LE(p, v) \
+	SIP_U32TO8_LE((p) + 0, (uint32_t)((v) >>  0)); \
+	SIP_U32TO8_LE((p) + 4, (uint32_t)((v) >> 32));
+
+#define SIP_U8TO64_LE(p) \
+	(((uint64_t)((p)[0]) <<  0) | \
+	 ((uint64_t)((p)[1]) <<  8) | \
+	 ((uint64_t)((p)[2]) << 16) | \
+	 ((uint64_t)((p)[3]) << 24) | \
+	 ((uint64_t)((p)[4]) << 32) | \
+	 ((uint64_t)((p)[5]) << 40) | \
+	 ((uint64_t)((p)[6]) << 48) | \
+	 ((uint64_t)((p)[7]) << 56))
+
+
+#define SIPHASH_INITIALIZER { 0, 0, 0, 0, { 0 }, 0, 0 }
+
+struct siphash {
+	uint64_t v0, v1, v2, v3;
+
+	unsigned char buf[8], *p;
+	uint64_t c;
+}; /* struct siphash */
+
+
+#define SIP_KEYLEN 16
+
+struct sipkey {
+	uint64_t k[2];
+}; /* struct sipkey */
+
+#define sip_keyof(k) sip_tokey(&(struct sipkey){ { 0 } }, (k))
+
+static struct sipkey *sip_tokey(struct sipkey *key, const void *src) {
+	key->k[0] = SIP_U8TO64_LE((const unsigned char *)src);
+	key->k[1] = SIP_U8TO64_LE((const unsigned char *)src + 8);
+	return key;
+} /* sip_tokey() */
+
+
+#define sip_binof(v) sip_tobin((unsigned char[8]){ 0 }, (v))
+
+static void *sip_tobin(void *dst, uint64_t u64) {
+	SIP_U64TO8_LE((unsigned char *)dst, u64);
+	return dst;
+} /* sip_tobin() */
+
+
+static void sip_round(struct siphash *H, const int rounds) {
+	int i;
+
+	for (i = 0; i < rounds; i++) {
+		H->v0 += H->v1;
+		H->v1 = SIP_ROTL(H->v1, 13);
+		H->v1 ^= H->v0;
+		H->v0 = SIP_ROTL(H->v0, 32);
+
+		H->v2 += H->v3;
+		H->v3 = SIP_ROTL(H->v3, 16);
+		H->v3 ^= H->v2;
+
+		H->v0 += H->v3;
+		H->v3 = SIP_ROTL(H->v3, 21);
+		H->v3 ^= H->v0;
+
+		H->v2 += H->v1;
+		H->v1 = SIP_ROTL(H->v1, 17);
+		H->v1 ^= H->v2;
+		H->v2 = SIP_ROTL(H->v2, 32);
+	}
+} /* sip_round() */
+
+
+static struct siphash *sip24_init(struct siphash *H, const struct sipkey *key) {
+	H->v0 = 0x736f6d6570736575UL ^ key->k[0];
+	H->v1 = 0x646f72616e646f6dUL ^ key->k[1];
+	H->v2 = 0x6c7967656e657261UL ^ key->k[0];
+	H->v3 = 0x7465646279746573UL ^ key->k[1];
+
+	H->p = H->buf;
+	H->c = 0;
+
+	return H;
+} /* sip24_init() */
+
+
+#define sip_endof(a) (&(a)[sizeof (a) / sizeof *(a)])
+
+static struct siphash *sip24_update(struct siphash *H, const void *src, size_t len) {
+	const unsigned char *p = (const unsigned char *)src, *pe = p + len;
+	uint64_t m;
+
+	do {
+		while (p < pe && H->p < sip_endof(H->buf))
+			*H->p++ = *p++;
+
+		if (H->p < sip_endof(H->buf))
+			break;
+
+		m = SIP_U8TO64_LE(H->buf);
+		H->v3 ^= m;
+		sip_round(H, 2);
+		H->v0 ^= m;
+
+		H->p = H->buf;
+		H->c += 8;
+	} while (p < pe);
+
+	return H;
+} /* sip24_update() */
+
+
+static uint64_t sip24_final(struct siphash *H) {
+	char left = H->p - H->buf;
+	uint64_t b = (H->c + left) << 56;
+
+	switch (left) {
+	case 7: b |= (uint64_t)H->buf[6] << 48;
+	case 6: b |= (uint64_t)H->buf[5] << 40;
+	case 5: b |= (uint64_t)H->buf[4] << 32;
+	case 4: b |= (uint64_t)H->buf[3] << 24;
+	case 3: b |= (uint64_t)H->buf[2] << 16;
+	case 2: b |= (uint64_t)H->buf[1] << 8;
+	case 1: b |= (uint64_t)H->buf[0] << 0;
+	case 0: break;
+	}
+
+	H->v3 ^= b;
+	sip_round(H, 2);
+	H->v0 ^= b;
+	H->v2 ^= 0xff;
+	sip_round(H, 4);
+
+	return H->v0 ^ H->v1 ^ H->v2  ^ H->v3;
+} /* sip24_final() */
+
+
+static uint64_t siphash24(const void *src, size_t len, const struct sipkey *key) {
+	struct siphash state = SIPHASH_INITIALIZER;
+	return sip24_final(sip24_update(sip24_init(&state, key), src, len));
+} /* siphash24() */
+
+
+/*
+ * SipHash-2-4 output with
+ * k = 00 01 02 ...
+ * and
+ * in = (empty string)
+ * in = 00 (1 byte)
+ * in = 00 01 (2 bytes)
+ * in = 00 01 02 (3 bytes)
+ * ...
+ * in = 00 01 02 ... 3e (63 bytes)
+ */
+static int sip24_valid(void) {
+	static const unsigned char vectors[64][8] = {
+		{ 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, },
+		{ 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, },
+		{ 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, },
+		{ 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, },
+		{ 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, },
+		{ 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, },
+		{ 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, },
+		{ 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, },
+		{ 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, },
+		{ 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, },
+		{ 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, },
+		{ 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, },
+		{ 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, },
+		{ 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, },
+		{ 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, },
+		{ 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, },
+		{ 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, },
+		{ 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, },
+		{ 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, },
+		{ 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, },
+		{ 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, },
+		{ 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, },
+		{ 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, },
+		{ 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, },
+		{ 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, },
+		{ 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, },
+		{ 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, },
+		{ 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, },
+		{ 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, },
+		{ 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, },
+		{ 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, },
+		{ 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, },
+		{ 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, },
+		{ 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, },
+		{ 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, },
+		{ 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, },
+		{ 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, },
+		{ 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, },
+		{ 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, },
+		{ 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, },
+		{ 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, },
+		{ 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, },
+		{ 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, },
+		{ 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, },
+		{ 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, },
+		{ 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, },
+		{ 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, },
+		{ 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, },
+		{ 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, },
+		{ 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, },
+		{ 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, },
+		{ 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, },
+		{ 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, },
+		{ 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, },
+		{ 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, },
+		{ 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, },
+		{ 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, },
+		{ 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, },
+		{ 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, },
+		{ 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, },
+		{ 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, },
+		{ 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, },
+		{ 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, },
+		{ 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, }
+	};
+	unsigned char in[64];
+	struct sipkey k;
+	size_t i;
+
+	sip_tokey(&k, "\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017");
+
+	for (i = 0; i < sizeof in; ++i) {
+		in[i] = i;
+
+		if (siphash24(in, i, &k) != SIP_U8TO64_LE(vectors[i]))
+			return 0;
+	}
+
+	return 1;
+} /* sip24_valid() */
+
+
+#if SIPHASH_MAIN
+
+#include <stdio.h>
+
+int main(void) {
+	int ok = sip24_valid();
+
+	if (ok)
+		puts("OK");
+	else
+		puts("FAIL");
+
+	return !ok;
+} /* main() */
+
+#endif /* SIPHASH_MAIN */
+
+
+#endif /* SIPHASH_H */
new file mode 100644
--- /dev/null
+++ b/parser/expat/lib/winconfig.h
@@ -0,0 +1,54 @@
+/*================================================================
+** Copyright 2000, Clark Cooper
+** All rights reserved.
+**
+** This is free software. You are permitted to copy, distribute, or modify
+** it under the terms of the MIT/X license (contained in the COPYING file
+** with this distribution.)
+*/
+
+#ifndef WINCONFIG_H
+#define WINCONFIG_H
+
+/* BEGIN MOZILLA CHANGE (don't define WIN32_LEAN_AND_MEAN if it was already set) */
+#ifdef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN_WAS_SET
+#undef WIN32_LEAN_AND_MEAN
+#endif
+/* END MOZILLA CHANGE */
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+
+/* BEGIN MOZILLA CHANGE (redefine WIN32_LEAN_AND_MEAN if it was already set) */
+#ifdef WIN32_LEAN_AND_MEAN_WAS_SET
+#define WIN32_LEAN_AND_MEAN
+#undef WIN32_LEAN_AND_MEAN_WAS_SET
+#endif
+/* END MOZILLA CHANGE */
+
+#include <memory.h>
+#include <string.h>
+
+
+#if defined(HAVE_EXPAT_CONFIG_H)  /* e.g. MinGW */
+# include <expat_config.h>
+#else  /* !defined(HAVE_EXPAT_CONFIG_H) */
+
+
+#define XML_NS 1
+#define XML_DTD 1
+#define XML_CONTEXT_BYTES 1024
+
+/* we will assume all Windows platforms are little endian */
+#define BYTEORDER 1234
+
+/* Windows has memmove() available. */
+#define HAVE_MEMMOVE
+
+
+#endif /* !defined(HAVE_EXPAT_CONFIG_H) */
+
+
+#endif /* ndef WINCONFIG_H */
--- a/parser/expat/lib/xmlparse.c
+++ b/parser/expat/lib/xmlparse.c
@@ -1,37 +1,49 @@
 /* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
    See the file COPYING for copying permission.
+
+   77fea421d361dca90041d0040ecf1dca651167fadf2af79e990e35168d70d933 (2.2.1+)
 */
 
+#define _GNU_SOURCE                     /* syscall prototype */
+
 #include <stddef.h>
 #include <string.h>                     /* memset(), memcpy() */
 #include <assert.h>
+#include <limits.h>                     /* UINT_MAX */
+#include <stdio.h>                      /* fprintf */
+#include <stdlib.h>                     /* getenv */
+
+#ifdef _WIN32
+#define getpid GetCurrentProcessId
+#else
+#include <sys/time.h>                   /* gettimeofday() */
+#include <sys/types.h>                  /* getpid() */
+#include <unistd.h>                     /* getpid() */
+#endif
 
 #define XML_BUILDING_EXPAT 1
 
-#ifdef COMPILED_FROM_DSP
+#ifdef _WIN32
 #include "winconfig.h"
-#elif defined(MACOS_CLASSIC)
-#include "macconfig.h"
-#elif defined(__amigaos4__)
-#include "amigaconfig.h"
 #elif defined(HAVE_EXPAT_CONFIG_H)
 #include <expat_config.h>
-#endif /* ndef COMPILED_FROM_DSP */
-
+#endif /* ndef _WIN32 */
+
+#include "ascii.h"
 #include "expat.h"
+#include "siphash.h"
 
 #ifdef XML_UNICODE
 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
 #define XmlConvert XmlUtf16Convert
 #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
 #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
 #define XmlEncode XmlUtf16Encode
-
 /* Using pointer subtraction to convert to integer type. */
 #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1))
 typedef unsigned short ICHAR;
 #else
 #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
 #define XmlConvert XmlUtf8Convert
 #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
 #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
@@ -99,27 +111,21 @@ typedef struct {
 typedef struct {
   NAMED **v;
   unsigned char power;
   size_t size;
   size_t used;
   const XML_Memory_Handling_Suite *mem;
 } HASH_TABLE;
 
-/* Basic character hash algorithm, taken from Python's string hash:
-   h = h * 1000003 ^ character, the constant being a prime number.
-
-*/
-#ifdef XML_UNICODE
-#define CHAR_HASH(h, c) \
-  (((h) * 0xF4243) ^ (unsigned short)(c))
-#else
-#define CHAR_HASH(h, c) \
-  (((h) * 0xF4243) ^ (unsigned char)(c))
-#endif
+static size_t
+keylen(KEY s);
+
+static void
+copy_salt_to_sipkey(XML_Parser parser, struct sipkey * key);
 
 /* For probing (after a collision) we need a step size relative prime
    to the hash table size, which is a power of 2. We use double-hashing,
    since we can calculate a second hash value cheaply by taking those bits
    of the first hash value that were discarded (masked out) when the table
    index was calculated: index = hash & mask, where mask = table->size - 1.
    We limit the maximum step size to table->size / 4 (mask >> 2) and make
    it odd, since odd numbers are always relative prime to a power of 2.
@@ -328,43 +334,45 @@ static Processor internalEntityProcessor
 static enum XML_Error
 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
 static enum XML_Error
 processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
                const char *s, const char *next);
 static enum XML_Error
 initializeEncoding(XML_Parser parser);
 static enum XML_Error
-doProlog(XML_Parser parser, const ENCODING *enc, const char *s, 
-         const char *end, int tok, const char *next, const char **nextPtr, 
+doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
+         const char *end, int tok, const char *next, const char **nextPtr,
          XML_Bool haveMore);
 static enum XML_Error
-processInternalEntity(XML_Parser parser, ENTITY *entity, 
+processInternalEntity(XML_Parser parser, ENTITY *entity,
                       XML_Bool betweenDecl);
 static enum XML_Error
 doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
-          const char *start, const char *end, const char **endPtr, 
+          const char *start, const char *end, const char **endPtr,
           XML_Bool haveMore);
 static enum XML_Error
 doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
                const char *end, const char **nextPtr, XML_Bool haveMore);
 #ifdef XML_DTD
 static enum XML_Error
 doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
                 const char *end, const char **nextPtr, XML_Bool haveMore);
 #endif /* XML_DTD */
 
+static void
+freeBindings(XML_Parser parser, BINDING *bindings);
 static enum XML_Error
 storeAtts(XML_Parser parser, const ENCODING *, const char *s,
           TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
 static enum XML_Error
 addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
            const XML_Char *uri, BINDING **bindingsPtr);
 static int
-defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata, 
+defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
                 XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);
 static enum XML_Error
 storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
                     const char *, const char *, STRING_POOL *);
 static enum XML_Error
 appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
                      const char *, const char *, STRING_POOL *);
 static ATTRIBUTE_ID *
@@ -394,22 +402,23 @@ static void FASTCALL normalizePublicId(X
 static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);
 /* BEGIN MOZILLA CHANGE (unused API) */
 /* do not call if parentParser != NULL */
 //static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
 /* END MOZILLA CHANGE */
 static void
 dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);
 static int
-dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
+dtdCopy(XML_Parser oldParser,
+        DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
 static int
-copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
-
+copyEntityTable(XML_Parser oldParser,
+                HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
 static NAMED *
-lookup(HASH_TABLE *table, KEY name, size_t createSize);
+lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize);
 static void FASTCALL
 hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
 /* BEGIN MOZILLA CHANGE (unused API) */
 //static void FASTCALL hashTableClear(HASH_TABLE *);
 /* END MOZILLA CHANGE */
 static void FASTCALL hashTableDestroy(HASH_TABLE *);
 static void FASTCALL
 hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
@@ -434,21 +443,25 @@ static const XML_Char * FASTCALL
 poolAppendString(STRING_POOL *pool, const XML_Char *s);
 
 static int FASTCALL nextScaffoldPart(XML_Parser parser);
 static XML_Content * build_model(XML_Parser parser);
 static ELEMENT_TYPE *
 getElementType(XML_Parser parser, const ENCODING *enc,
                const char *ptr, const char *end);
 
+static unsigned long generate_hash_secret_salt(XML_Parser parser);
+static XML_Bool startParsing(XML_Parser parser);
+
 static XML_Parser
 parserCreate(const XML_Char *encodingName,
              const XML_Memory_Handling_Suite *memsuite,
              const XML_Char *nameSep,
              DTD *dtd);
+
 static void
 parserInit(XML_Parser parser, const XML_Char *encodingName);
 
 #define poolStart(pool) ((pool)->start)
 #define poolEnd(pool) ((pool)->ptr)
 #define poolLength(pool) ((pool)->ptr - (pool)->start)
 #define poolChop(pool) ((void)--(pool->ptr))
 #define poolLastChar(pool) (((pool)->ptr)[-1])
@@ -538,29 +551,33 @@ struct XML_ParserStruct {
   BINDING *m_freeBindingList;
   int m_attsSize;
   int m_nSpecifiedAtts;
   int m_idAttIndex;
   ATTRIBUTE *m_atts;
   NS_ATT *m_nsAtts;
   unsigned long m_nsAttsVersion;
   unsigned char m_nsAttsPower;
+#ifdef XML_ATTR_INFO
+  XML_AttrInfo *m_attInfo;
+#endif
   POSITION m_position;
   STRING_POOL m_tempPool;
   STRING_POOL m_temp2Pool;
   char *m_groupConnector;
   unsigned int m_groupSize;
   XML_Char m_namespaceSeparator;
   XML_Parser m_parentParser;
   XML_ParsingStatus m_parsingStatus;
 #ifdef XML_DTD
   XML_Bool m_isParamEntity;
   XML_Bool m_useForeignDTD;
   enum XML_ParamEntityParsing m_paramEntityParsing;
 #endif
+  unsigned long m_hash_secret_salt;
 /* BEGIN MOZILLA CHANGE (Report opening tag of mismatched closing tag) */
   const XML_Char* m_mismatch;
 /* END MOZILLA CHANGE */
 };
 
 #define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
 #define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
 #define FREE(p) (parser->m_mem.free_fcn((p)))
@@ -648,68 +665,243 @@ struct XML_ParserStruct {
 #define tagStack (parser->m_tagStack)
 #define atts (parser->m_atts)
 #define attsSize (parser->m_attsSize)
 #define nSpecifiedAtts (parser->m_nSpecifiedAtts)
 #define idAttIndex (parser->m_idAttIndex)
 #define nsAtts (parser->m_nsAtts)
 #define nsAttsVersion (parser->m_nsAttsVersion)
 #define nsAttsPower (parser->m_nsAttsPower)
+#define attInfo (parser->m_attInfo)
 #define tempPool (parser->m_tempPool)
 #define temp2Pool (parser->m_temp2Pool)
 #define groupConnector (parser->m_groupConnector)
 #define groupSize (parser->m_groupSize)
 #define namespaceSeparator (parser->m_namespaceSeparator)
 #define parentParser (parser->m_parentParser)
 #define ps_parsing (parser->m_parsingStatus.parsing)
 #define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)
 #ifdef XML_DTD
 #define isParamEntity (parser->m_isParamEntity)
 #define useForeignDTD (parser->m_useForeignDTD)
 #define paramEntityParsing (parser->m_paramEntityParsing)
 #endif /* XML_DTD */
+#define hash_secret_salt (parser->m_hash_secret_salt)
 /* BEGIN MOZILLA CHANGE (Report opening tag of mismatched closing tag) */
 #define mismatch (parser->m_mismatch)
 /* END MOZILLA CHANGE */
 
 /* BEGIN MOZILLA CHANGE (unused API) */
 #if 0
 XML_Parser XMLCALL
+XML_ParserCreate(const XML_Char *encodingName)
+{
+  return XML_ParserCreate_MM(encodingName, NULL, NULL);
+}
+
+XML_Parser XMLCALL
 XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
 {
   XML_Char tmp[2];
   *tmp = nsSep;
   return XML_ParserCreate_MM(encodingName, NULL, tmp);
 }
 #endif
 /* END MOZILLA CHANGE */
 
 static const XML_Char implicitContext[] = {
-  'x', 'm', 'l', '=', 'h', 't', 't', 'p', ':', '/', '/',
-  'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
-  'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
-  'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
+  ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p,
+  ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w,
+  ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g,
+  ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9,
+  ASCII_9, ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e,
+  ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0'
 };
 
+
+#if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
+# include <errno.h>
+
+# if defined(HAVE_GETRANDOM)
+#  include <sys/random.h>    /* getrandom */
+# else
+#  include <unistd.h>        /* syscall */
+#  include <sys/syscall.h>   /* SYS_getrandom */
+# endif
+
+/* Obtain entropy on Linux 3.17+ */
+static int
+writeRandomBytes_getrandom(void * target, size_t count) {
+  int success = 0;  /* full count bytes written? */
+  size_t bytesWrittenTotal = 0;
+  const unsigned int getrandomFlags = 0;
+
+  do {
+    void * const currentTarget = (void*)((char*)target + bytesWrittenTotal);
+    const size_t bytesToWrite = count - bytesWrittenTotal;
+
+    const int bytesWrittenMore =
+#if defined(HAVE_GETRANDOM)
+        getrandom(currentTarget, bytesToWrite, getrandomFlags);
+#else
+        syscall(SYS_getrandom, currentTarget, bytesToWrite, getrandomFlags);
+#endif
+
+    if (bytesWrittenMore > 0) {
+      bytesWrittenTotal += bytesWrittenMore;
+      if (bytesWrittenTotal >= count)
+        success = 1;
+    }
+  } while (! success && (errno == EINTR || errno == EAGAIN));
+
+  return success;
+}
+
+#endif  /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */
+
+
+#ifdef _WIN32
+
+typedef BOOLEAN (APIENTRY *RTLGENRANDOM_FUNC)(PVOID, ULONG);
+
+/* Obtain entropy on Windows XP / Windows Server 2003 and later.
+ * Hint on RtlGenRandom and the following article from libsodioum.
+ *
+ * Michael Howard: Cryptographically Secure Random number on Windows without using CryptoAPI
+ * https://blogs.msdn.microsoft.com/michael_howard/2005/01/14/cryptographically-secure-random-number-on-windows-without-using-cryptoapi/
+ */
+static int
+writeRandomBytes_RtlGenRandom(void * target, size_t count) {
+  int success = 0;  /* full count bytes written? */
+  const HMODULE advapi32 = LoadLibrary("ADVAPI32.DLL");
+
+  if (advapi32) {
+    const RTLGENRANDOM_FUNC RtlGenRandom
+        = (RTLGENRANDOM_FUNC)GetProcAddress(advapi32, "SystemFunction036");
+    if (RtlGenRandom) {
+      if (RtlGenRandom((PVOID)target, (ULONG)count) == TRUE) {
+        success = 1;
+      }
+    }
+    FreeLibrary(advapi32);
+  }
+
+  return success;
+}
+
+#endif /* _WIN32 */
+
+
+static unsigned long
+gather_time_entropy(void)
+{
+#ifdef _WIN32
+  FILETIME ft;
+  GetSystemTimeAsFileTime(&ft); /* never fails */
+  return ft.dwHighDateTime ^ ft.dwLowDateTime;
+#else
+  struct timeval tv;
+  int gettimeofday_res;
+
+  gettimeofday_res = gettimeofday(&tv, NULL);
+
+#if defined(NDEBUG)
+  (void)gettimeofday_res;
+#else
+  assert (gettimeofday_res == 0);
+#endif /* defined(NDEBUG) */
+
+  /* Microseconds time is <20 bits entropy */
+  return tv.tv_usec;
+#endif
+}
+
+#if defined(HAVE_ARC4RANDOM_BUF) && defined(HAVE_LIBBSD)
+# include <bsd/stdlib.h>
+#endif
+
+static unsigned long
+ENTROPY_DEBUG(const char * label, unsigned long entropy) {
+/* BEGIN MOZILLA CHANGE (don't getenv every time we set up a hash) */
+#if 0
+  const char * const EXPAT_ENTROPY_DEBUG = getenv("EXPAT_ENTROPY_DEBUG");
+  if (EXPAT_ENTROPY_DEBUG && ! strcmp(EXPAT_ENTROPY_DEBUG, "1")) {
+    fprintf(stderr, "Entropy: %s --> 0x%0*lx (%lu bytes)\n",
+        label,
+        (int)sizeof(entropy) * 2, entropy,
+        (unsigned long)sizeof(entropy));
+  }
+#endif
+/* END MOZILLA CHANGE */
+  return entropy;
+}
+
+static unsigned long
+generate_hash_secret_salt(XML_Parser parser)
+{
+  unsigned long entropy;
+  (void)parser;
+#if defined(HAVE_ARC4RANDOM_BUF) || defined(__CloudABI__)
+  (void)gather_time_entropy;
+  arc4random_buf(&entropy, sizeof(entropy));
+  return ENTROPY_DEBUG("arc4random_buf", entropy);
+#else
+  /* Try high quality providers first .. */
+#ifdef _WIN32
+  if (writeRandomBytes_RtlGenRandom((void *)&entropy, sizeof(entropy))) {
+    return ENTROPY_DEBUG("RtlGenRandom", entropy);
+  }
+#elif defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
+  if (writeRandomBytes_getrandom((void *)&entropy, sizeof(entropy))) {
+    return ENTROPY_DEBUG("getrandom", entropy);
+  }
+#endif
+  /* .. and self-made low quality for backup: */
+
+  /* Process ID is 0 bits entropy if attacker has local access */
+  entropy = gather_time_entropy() ^ getpid();
+
+  /* Factors are 2^31-1 and 2^61-1 (Mersenne primes M31 and M61) */
+  if (sizeof(unsigned long) == 4) {
+    return ENTROPY_DEBUG("fallback(4)", entropy * 2147483647);
+  } else {
+    return ENTROPY_DEBUG("fallback(8)",
+        entropy * (unsigned long)2305843009213693951);
+  }
+#endif
+}
+
+static unsigned long
+get_hash_secret_salt(XML_Parser parser) {
+  if (parser->m_parentParser != NULL)
+    return get_hash_secret_salt(parser->m_parentParser);
+  return parser->m_hash_secret_salt;
+}
+
+static XML_Bool  /* only valid for root parser */
+startParsing(XML_Parser parser)
+{
+    /* hash functions must be initialized before setContext() is called */
+    if (hash_secret_salt == 0)
+      hash_secret_salt = generate_hash_secret_salt(parser);
+    if (ns) {
+      /* implicit context only set for root parser, since child
+         parsers (i.e. external entity parsers) will inherit it
+      */
+      return setContext(parser, implicitContext);
+    }
+    return XML_TRUE;
+}
+
 XML_Parser XMLCALL
 XML_ParserCreate_MM(const XML_Char *encodingName,
                     const XML_Memory_Handling_Suite *memsuite,
                     const XML_Char *nameSep)
 {
-  XML_Parser parser = parserCreate(encodingName, memsuite, nameSep, NULL);
-  if (parser != NULL && ns) {
-    /* implicit context only set for root parser, since child
-       parsers (i.e. external entity parsers) will inherit it
-    */
-    if (!setContext(parser, implicitContext)) {
-      XML_ParserFree(parser);
-      return NULL;
-    }
-  }
-  return parser;
+  return parserCreate(encodingName, memsuite, nameSep, NULL);
 }
 
 static XML_Parser
 parserCreate(const XML_Char *encodingName,
              const XML_Memory_Handling_Suite *memsuite,
              const XML_Char *nameSep,
              DTD *dtd)
 {
@@ -744,47 +936,61 @@ parserCreate(const XML_Char *encodingNam
   bufferLim = NULL;
 
   attsSize = INIT_ATTS_SIZE;
   atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));
   if (atts == NULL) {
     FREE(parser);
     return NULL;
   }
+#ifdef XML_ATTR_INFO
+  attInfo = (XML_AttrInfo*)MALLOC(attsSize * sizeof(XML_AttrInfo));
+  if (attInfo == NULL) {
+    FREE(atts);
+    FREE(parser);
+    return NULL;
+  }
+#endif
   dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
   if (dataBuf == NULL) {
     FREE(atts);
+#ifdef XML_ATTR_INFO
+    FREE(attInfo);
+#endif
     FREE(parser);
     return NULL;
   }
   dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
 
   if (dtd)
     _dtd = dtd;
   else {
     _dtd = dtdCreate(&parser->m_mem);
     if (_dtd == NULL) {
       FREE(dataBuf);
       FREE(atts);
+#ifdef XML_ATTR_INFO
+      FREE(attInfo);
+#endif
       FREE(parser);
       return NULL;
     }
   }
 
   freeBindingList = NULL;
   freeTagList = NULL;
   freeInternalEntities = NULL;
 
   groupSize = 0;
   groupConnector = NULL;
 
   unknownEncodingHandler = NULL;
   unknownEncodingHandlerData = NULL;
 
-  namespaceSeparator = '!';
+  namespaceSeparator = ASCII_EXCL;
   ns = XML_FALSE;
   ns_triplets = XML_FALSE;
 
   nsAtts = NULL;
   nsAttsVersion = 0;
   nsAttsPower = 0;
 
   poolInit(&tempPool, &(parser->m_mem));
@@ -877,16 +1083,17 @@ parserInit(XML_Parser parser, const XML_
   unknownEncodingData = NULL;
   parentParser = NULL;
   ps_parsing = XML_INITIALIZED;
 #ifdef XML_DTD
   isParamEntity = XML_FALSE;
   useForeignDTD = XML_FALSE;
   paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
 #endif
+  hash_secret_salt = 0;
 }
 
 /* BEGIN MOZILLA CHANGE (unused API) */
 #if 0
 /* moves list of bindings to freeBindingList */
 static void FASTCALL
 moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
 {
@@ -898,16 +1105,20 @@ moveToFreeBindingList(XML_Parser parser,
   }
 }
 
 XML_Bool XMLCALL
 XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
 {
   TAG *tStk;
   OPEN_INTERNAL_ENTITY *openEntityList;
+
+  if (parser == NULL)
+      return XML_FALSE;
+
   if (parentParser)
     return XML_FALSE;
   /* move tagStack to freeTagList */
   tStk = tagStack;
   while (tStk) {
     TAG *tag = tStk;
     tStk = tStk->parent;
     tag->parent = freeTagList;
@@ -926,22 +1137,24 @@ XML_ParserReset(XML_Parser parser, const
   moveToFreeBindingList(parser, inheritedBindings);
   FREE(unknownEncodingMem);
   if (unknownEncodingRelease)
     unknownEncodingRelease(unknownEncodingData);
   poolClear(&tempPool);
   poolClear(&temp2Pool);
   parserInit(parser, encodingName);
   dtdReset(_dtd, &parser->m_mem);
-  return setContext(parser, implicitContext);
+  return XML_TRUE;
 }
 
 enum XML_Status XMLCALL
 XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
 {
+  if (parser == NULL)
+      return XML_STATUS_ERROR;
   /* Block after XML_Parse()/XML_ParseBuffer() has been called.
      XXX There's no way for the caller to determine which of the
      XXX possible error cases caused the XML_STATUS_ERROR return.
   */
   if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
     return XML_STATUS_ERROR;
   if (encodingName == NULL)
     protocolEncodingName = NULL;
@@ -957,56 +1170,98 @@ XML_SetEncoding(XML_Parser parser, const
 
 XML_Parser XMLCALL
 XML_ExternalEntityParserCreate(XML_Parser oldParser,
                                const XML_Char *context,
                                const XML_Char *encodingName)
 {
   XML_Parser parser = oldParser;
   DTD *newDtd = NULL;
-  DTD *oldDtd = _dtd;
-  XML_StartElementHandler oldStartElementHandler = startElementHandler;
-  XML_EndElementHandler oldEndElementHandler = endElementHandler;
-  XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
-  XML_ProcessingInstructionHandler oldProcessingInstructionHandler
-      = processingInstructionHandler;
-  XML_CommentHandler oldCommentHandler = commentHandler;
-  XML_StartCdataSectionHandler oldStartCdataSectionHandler
-      = startCdataSectionHandler;
-  XML_EndCdataSectionHandler oldEndCdataSectionHandler
-      = endCdataSectionHandler;
-  XML_DefaultHandler oldDefaultHandler = defaultHandler;
-  XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
-      = unparsedEntityDeclHandler;
-  XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
-  XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
-      = startNamespaceDeclHandler;
-  XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
-      = endNamespaceDeclHandler;
-  XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
-  XML_ExternalEntityRefHandler oldExternalEntityRefHandler
-      = externalEntityRefHandler;
-  XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;
-  XML_UnknownEncodingHandler oldUnknownEncodingHandler
-      = unknownEncodingHandler;
-  XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
-  XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
-  XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
-  XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
-  ELEMENT_TYPE * oldDeclElementType = declElementType;
-
-  void *oldUserData = userData;
-  void *oldHandlerArg = handlerArg;
-  XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
-  XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
+  DTD *oldDtd;
+  XML_StartElementHandler oldStartElementHandler;
+  XML_EndElementHandler oldEndElementHandler;
+  XML_CharacterDataHandler oldCharacterDataHandler;
+  XML_ProcessingInstructionHandler oldProcessingInstructionHandler;
+  XML_CommentHandler oldCommentHandler;
+  XML_StartCdataSectionHandler oldStartCdataSectionHandler;
+  XML_EndCdataSectionHandler oldEndCdataSectionHandler;
+  XML_DefaultHandler oldDefaultHandler;
+  XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler;
+  XML_NotationDeclHandler oldNotationDeclHandler;
+  XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler;
+  XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler;
+  XML_NotStandaloneHandler oldNotStandaloneHandler;
+  XML_ExternalEntityRefHandler oldExternalEntityRefHandler;
+  XML_SkippedEntityHandler oldSkippedEntityHandler;
+  XML_UnknownEncodingHandler oldUnknownEncodingHandler;
+  XML_ElementDeclHandler oldElementDeclHandler;
+  XML_AttlistDeclHandler oldAttlistDeclHandler;
+  XML_EntityDeclHandler oldEntityDeclHandler;
+  XML_XmlDeclHandler oldXmlDeclHandler;
+  ELEMENT_TYPE * oldDeclElementType;
+
+  void *oldUserData;
+  void *oldHandlerArg;
+  XML_Bool oldDefaultExpandInternalEntities;
+  XML_Parser oldExternalEntityRefHandlerArg;
 #ifdef XML_DTD
-  enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
-  int oldInEntityValue = prologState.inEntityValue;
+  enum XML_ParamEntityParsing oldParamEntityParsing;
+  int oldInEntityValue;
 #endif
-  XML_Bool oldns_triplets = ns_triplets;
+  XML_Bool oldns_triplets;
+  /* Note that the new parser shares the same hash secret as the old
+     parser, so that dtdCopy and copyEntityTable can lookup values
+     from hash tables associated with either parser without us having
+     to worry which hash secrets each table has.
+  */
+  unsigned long oldhash_secret_salt;
+
+  /* Validate the oldParser parameter before we pull everything out of it */
+  if (oldParser == NULL)
+    return NULL;
+
+  /* Stash the original parser contents on the stack */
+  oldDtd = _dtd;
+  oldStartElementHandler = startElementHandler;
+  oldEndElementHandler = endElementHandler;
+  oldCharacterDataHandler = characterDataHandler;
+  oldProcessingInstructionHandler = processingInstructionHandler;
+  oldCommentHandler = commentHandler;
+  oldStartCdataSectionHandler = startCdataSectionHandler;
+  oldEndCdataSectionHandler = endCdataSectionHandler;
+  oldDefaultHandler = defaultHandler;
+  oldUnparsedEntityDeclHandler = unparsedEntityDeclHandler;
+  oldNotationDeclHandler = notationDeclHandler;
+  oldStartNamespaceDeclHandler = startNamespaceDeclHandler;
+  oldEndNamespaceDeclHandler = endNamespaceDeclHandler;
+  oldNotStandaloneHandler = notStandaloneHandler;
+  oldExternalEntityRefHandler = externalEntityRefHandler;
+  oldSkippedEntityHandler = skippedEntityHandler;
+  oldUnknownEncodingHandler = unknownEncodingHandler;
+  oldElementDeclHandler = elementDeclHandler;
+  oldAttlistDeclHandler = attlistDeclHandler;
+  oldEntityDeclHandler = entityDeclHandler;
+  oldXmlDeclHandler = xmlDeclHandler;
+  oldDeclElementType = declElementType;
+
+  oldUserData = userData;
+  oldHandlerArg = handlerArg;
+  oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
+  oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
+#ifdef XML_DTD
+  oldParamEntityParsing = paramEntityParsing;
+  oldInEntityValue = prologState.inEntityValue;
+#endif
+  oldns_triplets = ns_triplets;
+  /* Note that the new parser shares the same hash secret as the old
+     parser, so that dtdCopy and copyEntityTable can lookup values
+     from hash tables associated with either parser without us having
+     to worry which hash secrets each table has.
+  */
+  oldhash_secret_salt = hash_secret_salt;
 
 #ifdef XML_DTD
   if (!context)
     newDtd = oldDtd;
 #endif /* XML_DTD */
 
   /* Note that the magical uses of the pre-processor to make field
      access look more like C++ require that `parser' be overwritten
@@ -1050,23 +1305,24 @@ XML_ExternalEntityParserCreate(XML_Parse
   if (oldUserData == oldHandlerArg)
     handlerArg = userData;
   else
     handlerArg = parser;
   if (oldExternalEntityRefHandlerArg != oldParser)
     externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
   defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
   ns_triplets = oldns_triplets;
+  hash_secret_salt = oldhash_secret_salt;
   parentParser = oldParser;
 #ifdef XML_DTD
   paramEntityParsing = oldParamEntityParsing;
   prologState.inEntityValue = oldInEntityValue;
   if (context) {
 #endif /* XML_DTD */
-    if (!dtdCopy(_dtd, oldDtd, &parser->m_mem)
+    if (!dtdCopy(oldParser, _dtd, oldDtd, &parser->m_mem)
       || !setContext(parser, context)) {
       XML_ParserFree(parser);
       return NULL;
     }
     processor = externalEntityInitProcessor;
 #ifdef XML_DTD
   }
   else {
@@ -1145,347 +1401,437 @@ XML_ParserFree(XML_Parser parser)
      parser->m_dtd with the root parser, so we must not destroy it
   */
   if (!isParamEntity && _dtd)
 #else
   if (_dtd)
 #endif /* XML_DTD */
     dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);
   FREE((void *)atts);
+#ifdef XML_ATTR_INFO
+  FREE((void *)attInfo);
+#endif
   FREE(groupConnector);
   FREE(buffer);
   FREE(dataBuf);
   FREE(nsAtts);
   FREE(unknownEncodingMem);
   if (unknownEncodingRelease)
     unknownEncodingRelease(unknownEncodingData);
   FREE(parser);
 }
 
 void XMLCALL
 XML_UseParserAsHandlerArg(XML_Parser parser)
 {
-  handlerArg = parser;
+  if (parser != NULL)
+    handlerArg = parser;
 }
 
 /* BEGIN MOZILLA CHANGE (unused API) */
 #if 0
 enum XML_Error XMLCALL
 XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
 {
+  if (parser == NULL)
+    return XML_ERROR_INVALID_ARGUMENT;
 #ifdef XML_DTD
   /* block after XML_Parse()/XML_ParseBuffer() has been called */
   if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
     return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
   useForeignDTD = useDTD;
   return XML_ERROR_NONE;
 #else
   return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
 #endif
 }
 #endif
 /* END MOZILLA CHANGE */
 
 void XMLCALL
 XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
 {
+  if (parser == NULL)
+    return;
   /* block after XML_Parse()/XML_ParseBuffer() has been called */
   if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
     return;
   ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
 }
 
 void XMLCALL
 XML_SetUserData(XML_Parser parser, void *p)
 {
+  if (parser == NULL)
+    return;
   if (handlerArg == userData)
     handlerArg = userData = p;
   else
     userData = p;
 }
 
 enum XML_Status XMLCALL
 XML_SetBase(XML_Parser parser, const XML_Char *p)
 {
+  if (parser == NULL)
+    return XML_STATUS_ERROR;
   if (p) {
     p = poolCopyString(&_dtd->pool, p);
     if (!p)
       return XML_STATUS_ERROR;
     curBase = p;
   }
   else
     curBase = NULL;
   return XML_STATUS_OK;
 }
 
 const XML_Char * XMLCALL
 XML_GetBase(XML_Parser parser)
 {
+  if (parser == NULL)
+    return NULL;
   return curBase;
 }
 
 int XMLCALL
 XML_GetSpecifiedAttributeCount(XML_Parser parser)
 {
+  if (parser == NULL)
+    return -1;
   return nSpecifiedAtts;
 }
 
 int XMLCALL
 XML_GetIdAttributeIndex(XML_Parser parser)
 {
+  if (parser == NULL)
+    return -1;
   return idAttIndex;
 }
 
+#ifdef XML_ATTR_INFO
+const XML_AttrInfo * XMLCALL
+XML_GetAttributeInfo(XML_Parser parser)
+{
+  if (parser == NULL)
+    return NULL;
+  return attInfo;
+}
+#endif
+
 void XMLCALL
 XML_SetElementHandler(XML_Parser parser,
                       XML_StartElementHandler start,
                       XML_EndElementHandler end)
 {
+  if (parser == NULL)
+    return;
   startElementHandler = start;
   endElementHandler = end;
 }
 
 /* BEGIN MOZILLA CHANGE (unused API) */
 #if 0
 void XMLCALL
 XML_SetStartElementHandler(XML_Parser parser,
                            XML_StartElementHandler start) {
-  startElementHandler = start;
+  if (parser != NULL)
+    startElementHandler = start;
 }
 
 void XMLCALL
 XML_SetEndElementHandler(XML_Parser parser,
                          XML_EndElementHandler end) {
-  endElementHandler = end;
+  if (parser != NULL)
+    endElementHandler = end;
 }
 #endif
 /* END MOZILLA CHANGE */
 
 void XMLCALL
 XML_SetCharacterDataHandler(XML_Parser parser,
                             XML_CharacterDataHandler handler)
 {
-  characterDataHandler = handler;
+  if (parser != NULL)
+    characterDataHandler = handler;
 }
 
 void XMLCALL
 XML_SetProcessingInstructionHandler(XML_Parser parser,
                                     XML_ProcessingInstructionHandler handler)
 {
-  processingInstructionHandler = handler;
+  if (parser != NULL)
+    processingInstructionHandler = handler;
 }
 
 void XMLCALL
 XML_SetCommentHandler(XML_Parser parser,
                       XML_CommentHandler handler)
 {
-  commentHandler = handler;
+  if (parser != NULL)
+    commentHandler = handler;
 }
 
 void XMLCALL
 XML_SetCdataSectionHandler(XML_Parser parser,
                            XML_StartCdataSectionHandler start,
                            XML_EndCdataSectionHandler end)
 {
+  if (parser == NULL)
+    return;
   startCdataSectionHandler = start;
   endCdataSectionHandler = end;
 }
 
 /* BEGIN MOZILLA CHANGE (unused API) */
 #if 0
 void XMLCALL
 XML_SetStartCdataSectionHandler(XML_Parser parser,
                                 XML_StartCdataSectionHandler start) {
-  startCdataSectionHandler = start;
+  if (parser != NULL)
+    startCdataSectionHandler = start;
 }
 
 void XMLCALL
 XML_SetEndCdataSectionHandler(XML_Parser parser,
                               XML_EndCdataSectionHandler end) {
-  endCdataSectionHandler = end;
+  if (parser != NULL)
+    endCdataSectionHandler = end;
 }
 
 void XMLCALL
 XML_SetDefaultHandler(XML_Parser parser,
                       XML_DefaultHandler handler)
 {
+  if (parser == NULL)
+    return;
   defaultHandler = handler;
   defaultExpandInternalEntities = XML_FALSE;
 }
 #endif
 /* END MOZILLA CHANGE */
 
 void XMLCALL
 XML_SetDefaultHandlerExpand(XML_Parser parser,
                             XML_DefaultHandler handler)
 {
+  if (parser == NULL)
+    return;
   defaultHandler = handler;
   defaultExpandInternalEntities = XML_TRUE;
 }
 
 void XMLCALL
 XML_SetDoctypeDeclHandler(XML_Parser parser,
                           XML_StartDoctypeDeclHandler start,
                           XML_EndDoctypeDeclHandler end)
 {
+  if (parser == NULL)
+    return;
   startDoctypeDeclHandler = start;
   endDoctypeDeclHandler = end;
 }
 
 /* BEGIN MOZILLA CHANGE (unused API) */
 #if 0
 void XMLCALL
 XML_SetStartDoctypeDeclHandler(XML_Parser parser,
                                XML_StartDoctypeDeclHandler start) {
-  startDoctypeDeclHandler = start;
+  if (parser != NULL)
+    startDoctypeDeclHandler = start;
 }
 
 void XMLCALL
 XML_SetEndDoctypeDeclHandler(XML_Parser parser,
                              XML_EndDoctypeDeclHandler end) {
-  endDoctypeDeclHandler = end;
+  if (parser != NULL)
+    endDoctypeDeclHandler = end;
 }
 #endif
 /* END MOZILLA CHANGE */
 
 void XMLCALL
 XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
                                  XML_UnparsedEntityDeclHandler handler)
 {
-  unparsedEntityDeclHandler = handler;
+  if (parser != NULL)
+    unparsedEntityDeclHandler = handler;
 }
 
 void XMLCALL
 XML_SetNotationDeclHandler(XML_Parser parser,
                            XML_NotationDeclHandler handler)
 {
-  notationDeclHandler = handler;
+  if (parser != NULL)
+    notationDeclHandler = handler;
 }
 
 void XMLCALL
 XML_SetNamespaceDeclHandler(XML_Parser parser,
                             XML_StartNamespaceDeclHandler start,
                             XML_EndNamespaceDeclHandler end)
 {
+  if (parser == NULL)
+    return;
   startNamespaceDeclHandler = start;
   endNamespaceDeclHandler = end;
 }
 
 
 /* BEGIN MOZILLA CHANGE (unused API) */
 #if 0
 void XMLCALL
 XML_SetStartNamespaceDeclHandler(XML_Parser parser,
                                  XML_StartNamespaceDeclHandler start) {
-  startNamespaceDeclHandler = start;
+  if (parser != NULL)
+    startNamespaceDeclHandler = start;
 }
 
 void XMLCALL
 XML_SetEndNamespaceDeclHandler(XML_Parser parser,
                                XML_EndNamespaceDeclHandler end) {
-  endNamespaceDeclHandler = end;
+  if (parser != NULL)
+    endNamespaceDeclHandler = end;
 }
 
 void XMLCALL
 XML_SetNotStandaloneHandler(XML_Parser parser,
                             XML_NotStandaloneHandler handler)
 {
-  notStandaloneHandler = handler;
+  if (parser != NULL)
+    notStandaloneHandler = handler;
 }
 #endif
 /* END MOZILLA CHANGE */
 
 void XMLCALL
 XML_SetExternalEntityRefHandler(XML_Parser parser,
                                 XML_ExternalEntityRefHandler handler)
 {
-  externalEntityRefHandler = handler;
+  if (parser != NULL)
+    externalEntityRefHandler = handler;
 }
 
 void XMLCALL
 XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
 {
+  if (parser == NULL)
+    return;
   if (arg)
     externalEntityRefHandlerArg = (XML_Parser)arg;
   else
     externalEntityRefHandlerArg = parser;
 }
 
 /* BEGIN MOZILLA CHANGE (unused API) */
 #if 0
 void XMLCALL
 XML_SetSkippedEntityHandler(XML_Parser parser,
                             XML_SkippedEntityHandler handler)
 {
-  skippedEntityHandler = handler;
+  if (parser != NULL)
+    skippedEntityHandler = handler;
 }
 
 void XMLCALL
 XML_SetUnknownEncodingHandler(XML_Parser parser,
                               XML_UnknownEncodingHandler handler,
                               void *data)
 {
+  if (parser == NULL)
+    return;
   unknownEncodingHandler = handler;
   unknownEncodingHandlerData = data;
 }
 
 void XMLCALL
 XML_SetElementDeclHandler(XML_Parser parser,
                           XML_ElementDeclHandler eldecl)
 {
-  elementDeclHandler = eldecl;
+  if (parser != NULL)
+    elementDeclHandler = eldecl;
 }
 
 void XMLCALL
 XML_SetAttlistDeclHandler(XML_Parser parser,
                           XML_AttlistDeclHandler attdecl)
 {
-  attlistDeclHandler = attdecl;
+  if (parser != NULL)
+    attlistDeclHandler = attdecl;
 }
 
 void XMLCALL
 XML_SetEntityDeclHandler(XML_Parser parser,
                          XML_EntityDeclHandler handler)
 {
-  entityDeclHandler = handler;
+  if (parser != NULL)
+    entityDeclHandler = handler;
 }
 #endif
 /* END MOZILLA CHANGE */
 
 void XMLCALL
 XML_SetXmlDeclHandler(XML_Parser parser,
                       XML_XmlDeclHandler handler) {
-  xmlDeclHandler = handler;
+  if (parser != NULL)
+    xmlDeclHandler = handler;
 }
 
 int XMLCALL
 XML_SetParamEntityParsing(XML_Parser parser,
                           enum XML_ParamEntityParsing peParsing)
 {
+  if (parser == NULL)
+    return 0;
   /* block after XML_Parse()/XML_ParseBuffer() has been called */
   if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
     return 0;
 #ifdef XML_DTD
   paramEntityParsing = peParsing;
   return 1;
 #else
   return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
 #endif
 }
 
+int XMLCALL
+XML_SetHashSalt(XML_Parser parser,
+                unsigned long hash_salt)
+{
+  if (parser == NULL)
+    return 0;
+  if (parser->m_parentParser)
+    return XML_SetHashSalt(parser->m_parentParser, hash_salt);
+  /* block after XML_Parse()/XML_ParseBuffer() has been called */
+  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
+    return 0;
+  hash_secret_salt = hash_salt;
+  return 1;
+}
+
 enum XML_Status XMLCALL
 XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
 {
+  if ((parser == NULL) || (len < 0) || ((s == NULL) && (len != 0))) {
+    errorCode = XML_ERROR_INVALID_ARGUMENT;
+    return XML_STATUS_ERROR;
+  }
   switch (ps_parsing) {
   case XML_SUSPENDED:
     errorCode = XML_ERROR_SUSPENDED;
     return XML_STATUS_ERROR;
   case XML_FINISHED:
     errorCode = XML_ERROR_FINISHED;
     return XML_STATUS_ERROR;
+  case XML_INITIALIZED:
+    if (parentParser == NULL && !startParsing(parser)) {
+      errorCode = XML_ERROR_NO_MEMORY;
+      return XML_STATUS_ERROR;
+    }
   default:
     ps_parsing = XML_PARSING;
   }
 
   if (len == 0) {
     ps_finalBuffer = (XML_Bool)isFinal;
     if (!isFinal)
       return XML_STATUS_OK;
@@ -1499,35 +1845,46 @@ XML_Parse(XML_Parser parser, const char 
     errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
 
     if (errorCode == XML_ERROR_NONE) {
       switch (ps_parsing) {
       case XML_SUSPENDED:
         XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
         positionPtr = bufferPtr;
         return XML_STATUS_SUSPENDED;
-      case XML_INITIALIZED: 
+      case XML_INITIALIZED:
       case XML_PARSING:
         ps_parsing = XML_FINISHED;
         /* fall through */
       default:
         return XML_STATUS_OK;
       }
     }
     eventEndPtr = eventPtr;
     processor = errorProcessor;
     return XML_STATUS_ERROR;
   }
 #ifndef XML_CONTEXT_BYTES
   else if (bufferPtr == bufferEnd) {
     const char *end;
     int nLeftOver;
-/* BEGIN MOZILLA CHANGE (|result| has type XML_Status, not XML_Error) */
     enum XML_Status result;
+    /* Detect overflow (a+b > MAX <==> b > MAX-a) */
+/* BEGIN MOZILLA CHANGE (len is signed, trying to compare it to an unsigned value) */
+#if 0
+    if (len > ((XML_Size)-1) / 2 - parseEndByteIndex) {
+#else
+    if ((XML_Size)len > ((XML_Size)-1) / 2 - parseEndByteIndex) {
+#endif
 /* END MOZILLA CHANGE */
+       errorCode = XML_ERROR_NO_MEMORY;
+       eventPtr = eventEndPtr = NULL;
+       processor = errorProcessor;
+       return XML_STATUS_ERROR;
+    }
     parseEndByteIndex += len;
     positionPtr = s;
     ps_finalBuffer = (XML_Bool)isFinal;
 
     errorCode = processor(parser, s, parseEndPtr = s + len, &end);
 
     if (errorCode != XML_ERROR_NONE) {
       eventEndPtr = eventPtr;
@@ -1536,83 +1893,46 @@ XML_Parse(XML_Parser parser, const char 
     }
     else {
       switch (ps_parsing) {
       case XML_SUSPENDED:
         result = XML_STATUS_SUSPENDED;
         break;
       case XML_INITIALIZED:
       case XML_PARSING:
-/* BEGIN MOZILLA CHANGE (always initialize result) */
-#if 0
-        result = XML_STATUS_OK;
-        if (isFinal) {
-          ps_parsing = XML_FINISHED;
-          return result;
-        }
-#else
         if (isFinal) {
           ps_parsing = XML_FINISHED;
           return XML_STATUS_OK;
         }
       /* fall through */
       default:
         result = XML_STATUS_OK;
-#endif
-/* END MOZILLA CHANGE */
       }
     }
 
     XmlUpdatePosition(encoding, positionPtr, end, &position);
     nLeftOver = s + len - end;
     if (nLeftOver) {
       if (buffer == NULL || nLeftOver > bufferLim - buffer) {
-/* BEGIN MOZILLA CHANGE (check for overflow) */
-#if 0
-        /* FIXME avoid integer overflow */
-        char *temp;
-        temp = (buffer == NULL
-                ? (char *)MALLOC(len * 2)
-                : (char *)REALLOC(buffer, len * 2));
+        /* avoid _signed_ integer overflow */
+        char *temp = NULL;
+        const int bytesToAllocate = (int)((unsigned)len * 2U);
+        if (bytesToAllocate > 0) {
+          temp = (buffer == NULL
+                ? (char *)MALLOC(bytesToAllocate)
+                : (char *)REALLOC(buffer, bytesToAllocate));
+        }
         if (temp == NULL) {
           errorCode = XML_ERROR_NO_MEMORY;
-          return XML_STATUS_ERROR;
-        }
-        buffer = temp;
-        if (!buffer) {
-          errorCode = XML_ERROR_NO_MEMORY;
           eventPtr = eventEndPtr = NULL;
           processor = errorProcessor;
           return XML_STATUS_ERROR;
         }
-        bufferLim = buffer + len * 2;
-#else
-        char *temp;
-        int newLen = len * 2;
-        if (newLen < 0) {
-          errorCode = XML_ERROR_NO_MEMORY;
-          return XML_STATUS_ERROR;
-        }
-        temp = (buffer == NULL
-                ? (char *)MALLOC(newLen)
-                : (char *)REALLOC(buffer, newLen));
-        if (temp == NULL) {
-          errorCode = XML_ERROR_NO_MEMORY;
-          return XML_STATUS_ERROR;
-        }
         buffer = temp;
-        if (!buffer) {
-          errorCode = XML_ERROR_NO_MEMORY;
-          eventPtr = eventEndPtr = NULL;
-          processor = errorProcessor;
-          return XML_STATUS_ERROR;
-        }
-        bufferLim = buffer + newLen;
-#endif
-/* END MOZILLA CHANGE */
+        bufferLim = buffer + bytesToAllocate;
       }
       memcpy(buffer, end, nLeftOver);
     }
     bufferPtr = buffer;
     bufferEnd = buffer + nLeftOver;
     positionPtr = bufferPtr;
     parseEndPtr = bufferEnd;
     eventPtr = bufferPtr;
@@ -1632,23 +1952,30 @@ XML_Parse(XML_Parser parser, const char 
 }
 
 enum XML_Status XMLCALL
 XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
 {
   const char *start;
   enum XML_Status result = XML_STATUS_OK;
 
+  if (parser == NULL)
+    return XML_STATUS_ERROR;
   switch (ps_parsing) {
   case XML_SUSPENDED:
     errorCode = XML_ERROR_SUSPENDED;
     return XML_STATUS_ERROR;
   case XML_FINISHED:
     errorCode = XML_ERROR_FINISHED;
     return XML_STATUS_ERROR;
+  case XML_INITIALIZED:
+    if (parentParser == NULL && !startParsing(parser)) {
+      errorCode = XML_ERROR_NO_MEMORY;
+      return XML_STATUS_ERROR;
+    }
   default:
     ps_parsing = XML_PARSING;
   }
 
   start = bufferPtr;
   positionPtr = start;
   bufferEnd += len;
   parseEndPtr = bufferEnd;
@@ -1662,17 +1989,17 @@ XML_ParseBuffer(XML_Parser parser, int l
     processor = errorProcessor;
     return XML_STATUS_ERROR;
   }
   else {
     switch (ps_parsing) {
     case XML_SUSPENDED:
       result = XML_STATUS_SUSPENDED;
       break;
-    case XML_INITIALIZED: 
+    case XML_INITIALIZED:
     case XML_PARSING:
       if (isFinal) {
         ps_parsing = XML_FINISHED;
         return result;
       }
     default: ;  /* should not happen */
     }
   }
@@ -1680,43 +2007,44 @@ XML_ParseBuffer(XML_Parser parser, int l
   XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
   positionPtr = bufferPtr;
   return result;
 }
 
 void * XMLCALL
 XML_GetBuffer(XML_Parser parser, int len)
 {
-/* BEGIN MOZILLA CHANGE (sanity check len) */
+  if (parser == NULL)
+    return NULL;
   if (len < 0) {
     errorCode = XML_ERROR_NO_MEMORY;
     return NULL;
   }
-/* END MOZILLA CHANGE */
   switch (ps_parsing) {
   case XML_SUSPENDED:
     errorCode = XML_ERROR_SUSPENDED;
     return NULL;
   case XML_FINISHED:
     errorCode = XML_ERROR_FINISHED;
     return NULL;
   default: ;
   }
 
   if (len > bufferLim - bufferEnd) {
-    int neededSize = len + (int)(bufferEnd - bufferPtr);
-/* BEGIN MOZILLA CHANGE (sanity check neededSize) */
+#ifdef XML_CONTEXT_BYTES
+    int keep;
+#endif  /* defined XML_CONTEXT_BYTES */
+    /* Do not invoke signed arithmetic overflow: */
+    int neededSize = (int) ((unsigned)len + (unsigned)(bufferEnd - bufferPtr));
     if (neededSize < 0) {
       errorCode = XML_ERROR_NO_MEMORY;
       return NULL;
     }
-/* END MOZILLA CHANGE */
 #ifdef XML_CONTEXT_BYTES
-    int keep = (int)(bufferPtr - buffer);
-
+    keep = (int)(bufferPtr - buffer);
     if (keep > XML_CONTEXT_BYTES)
       keep = XML_CONTEXT_BYTES;
     neededSize += keep;
 #endif  /* defined XML_CONTEXT_BYTES */
     if (neededSize  <= bufferLim - buffer) {
 #ifdef XML_CONTEXT_BYTES
       if (keep < bufferPtr - buffer) {
         int offset = (int)(bufferPtr - buffer) - keep;
@@ -1731,26 +2059,23 @@ XML_GetBuffer(XML_Parser parser, int len
 #endif  /* not defined XML_CONTEXT_BYTES */
     }
     else {
       char *newBuf;
       int bufferSize = (int)(bufferLim - bufferPtr);
       if (bufferSize == 0)
         bufferSize = INIT_BUFFER_SIZE;
       do {
-        bufferSize *= 2;
-/* BEGIN MOZILLA CHANGE (prevent infinite loop on overflow) */
+        /* Do not invoke signed arithmetic overflow: */
+        bufferSize = (int) (2U * (unsigned) bufferSize);
       } while (bufferSize < neededSize && bufferSize > 0);
-/* END MOZILLA CHANGE */
-/* BEGIN MOZILLA CHANGE (sanity check bufferSize) */
       if (bufferSize <= 0) {
         errorCode = XML_ERROR_NO_MEMORY;
         return NULL;
       }
-/* END MOZILLA CHANGE */
       newBuf = (char *)MALLOC(bufferSize);
       if (newBuf == 0) {
         errorCode = XML_ERROR_NO_MEMORY;
         return NULL;
       }
       bufferLim = newBuf + bufferSize;
 #ifdef XML_CONTEXT_BYTES
       if (bufferPtr) {
@@ -1771,23 +2096,27 @@ XML_GetBuffer(XML_Parser parser, int len
       if (bufferPtr) {
         memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
         FREE(buffer);
       }
       bufferEnd = newBuf + (bufferEnd - bufferPtr);
       bufferPtr = buffer = newBuf;
 #endif  /* not defined XML_CONTEXT_BYTES */
     }
+    eventPtr = eventEndPtr = NULL;
+    positionPtr = NULL;
   }
   return bufferEnd;
 }
 
 enum XML_Status XMLCALL
 XML_StopParser(XML_Parser parser, XML_Bool resumable)
 {
+  if (parser == NULL)
+    return XML_STATUS_ERROR;
   switch (ps_parsing) {
   case XML_SUSPENDED:
     if (resumable) {
       errorCode = XML_ERROR_SUSPENDED;
       return XML_STATUS_ERROR;
     }
     ps_parsing = XML_FINISHED;
     break;
@@ -1810,16 +2139,18 @@ XML_StopParser(XML_Parser parser, XML_Bo
   return XML_STATUS_OK;
 }
 
 enum XML_Status XMLCALL
 XML_ResumeParser(XML_Parser parser)
 {
   enum XML_Status result = XML_STATUS_OK;
 
+  if (parser == NULL)
+    return XML_STATUS_ERROR;
   if (ps_parsing != XML_SUSPENDED) {
     errorCode = XML_ERROR_NOT_SUSPENDED;
     return XML_STATUS_ERROR;
   }
   ps_parsing = XML_PARSING;
 
   errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
 
@@ -1828,17 +2159,17 @@ XML_ResumeParser(XML_Parser parser)
     processor = errorProcessor;
     return XML_STATUS_ERROR;
   }
   else {
     switch (ps_parsing) {
     case XML_SUSPENDED:
       result = XML_STATUS_SUSPENDED;
       break;
-    case XML_INITIALIZED: 
+    case XML_INITIALIZED:
     case XML_PARSING:
       if (ps_finalBuffer) {
         ps_parsing = XML_FINISHED;
         return result;
       }
     default: ;
     }
   }
@@ -1850,126 +2181,205 @@ XML_ResumeParser(XML_Parser parser)
   eventEndPtr = bufferPtr;
 /* END MOZILLA CHANGE */
   return result;
 }
 
 void XMLCALL
 XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)
 {
+  if (parser == NULL)
+    return;
   assert(status != NULL);
   *status = parser->m_parsingStatus;
 }
 
 enum XML_Error XMLCALL
 XML_GetErrorCode(XML_Parser parser)
 {
+  if (parser == NULL)
+    return XML_ERROR_INVALID_ARGUMENT;
   return errorCode;
 }
 
 XML_Index XMLCALL
 XML_GetCurrentByteIndex(XML_Parser parser)
 {
+  if (parser == NULL)
+    return -1;
   if (eventPtr)
-    return parseEndByteIndex - (parseEndPtr - eventPtr);
+    return (XML_Index)(parseEndByteIndex - (parseEndPtr - eventPtr));
 /* BEGIN MOZILLA CHANGE (fix XML_GetCurrentByteIndex) */
 #if 0
   return -1;
 #else
   return parseEndByteIndex;
 #endif
 /* END MOZILLA CHANGE */
 }
 
 /* BEGIN MOZILLA CHANGE (unused API) */
 #if 0
 int XMLCALL
 XML_GetCurrentByteCount(XML_Parser parser)
 {
+  if (parser == NULL)
+    return 0;
   if (eventEndPtr && eventPtr)
     return (int)(eventEndPtr - eventPtr);
   return 0;
 }
 
 const char * XMLCALL
 XML_GetInputContext(XML_Parser parser, int *offset, int *size)
 {
 #ifdef XML_CONTEXT_BYTES
+  if (parser == NULL)
+    return NULL;
   if (eventPtr && buffer) {
-    *offset = (int)(eventPtr - buffer);
-    *size   = (int)(bufferEnd - buffer);
+    if (offset != NULL)
+      *offset = (int)(eventPtr - buffer);
+    if (size != NULL)
+      *size   = (int)(bufferEnd - buffer);
     return buffer;
   }
+#else
+  (void)parser;
+  (void)offset;
+  (void)size;
 #endif /* defined XML_CONTEXT_BYTES */
   return (char *) 0;
 }
 #endif
 /* END MOZILLA CHANGE */
 
 XML_Size XMLCALL
 XML_GetCurrentLineNumber(XML_Parser parser)
 {
+  if (parser == NULL)
+    return 0;
   if (eventPtr && eventPtr >= positionPtr) {
     XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
     positionPtr = eventPtr;
   }
   return position.lineNumber + 1;
 }
 
 XML_Size XMLCALL
 XML_GetCurrentColumnNumber(XML_Parser parser)
 {
+  if (parser == NULL)
+    return 0;
   if (eventPtr && eventPtr >= positionPtr) {
     XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
     positionPtr = eventPtr;
   }
   return position.columnNumber;
 }
 
 /* BEGIN MOZILLA CHANGE (unused API) */
 #if 0
 void XMLCALL
 XML_FreeContentModel(XML_Parser parser, XML_Content *model)
 {
-  FREE(model);
+  if (parser != NULL)
+    FREE(model);
 }
 
 void * XMLCALL
 XML_MemMalloc(XML_Parser parser, size_t size)
 {
+  if (parser == NULL)
+    return NULL;
   return MALLOC(size);
 }
 
 void * XMLCALL
 XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
 {
+  if (parser == NULL)
+    return NULL;
   return REALLOC(ptr, size);
 }
 
 void XMLCALL
 XML_MemFree(XML_Parser parser, void *ptr)
 {
-  FREE(ptr);
+  if (parser != NULL)
+    FREE(ptr);
 }
 
 void XMLCALL
 XML_DefaultCurrent(XML_Parser parser)
 {
+  if (parser == NULL)
+    return;
   if (defaultHandler) {
     if (openInternalEntities)
       reportDefault(parser,
                     internalEncoding,
                     openInternalEntities->internalEventPtr,
                     openInternalEntities->internalEventEndPtr);
     else
       reportDefault(parser, encoding, eventPtr, eventEndPtr);
   }
 }
 
 const XML_LChar * XMLCALL
+XML_ErrorString(enum XML_Error code)
+{
+  static const XML_LChar* const message[] = {
+    0,
+    XML_L("out of memory"),
+    XML_L("syntax error"),
+    XML_L("no element found"),
+    XML_L("not well-formed (invalid token)"),
+    XML_L("unclosed token"),
+    XML_L("partial character"),
+    XML_L("mismatched tag"),
+    XML_L("duplicate attribute"),
+    XML_L("junk after document element"),
+    XML_L("illegal parameter entity reference"),
+    XML_L("undefined entity"),
+    XML_L("recursive entity reference"),
+    XML_L("asynchronous entity"),
+    XML_L("reference to invalid character number"),
+    XML_L("reference to binary entity"),
+    XML_L("reference to external entity in attribute"),
+    XML_L("XML or text declaration not at start of entity"),
+    XML_L("unknown encoding"),
+    XML_L("encoding specified in XML declaration is incorrect"),
+    XML_L("unclosed CDATA section"),
+    XML_L("error in processing external entity reference"),
+    XML_L("document is not standalone"),
+    XML_L("unexpected parser state - please send a bug report"),
+    XML_L("entity declared in parameter entity"),
+    XML_L("requested feature requires XML_DTD support in Expat"),
+    XML_L("cannot change setting once parsing has begun"),
+    XML_L("unbound prefix"),
+    XML_L("must not undeclare prefix"),
+    XML_L("incomplete markup in parameter entity"),
+    XML_L("XML declaration not well-formed"),
+    XML_L("text declaration not well-formed"),
+    XML_L("illegal character(s) in public id"),
+    XML_L("parser suspended"),
+    XML_L("parser not suspended"),
+    XML_L("parsing aborted"),
+    XML_L("parsing finished"),
+    XML_L("cannot suspend in external parameter entity"),
+    XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),
+    XML_L("reserved prefix (xmlns) must not be declared or undeclared"),
+    XML_L("prefix must not be bound to one of the reserved namespace names")
+  };
+  if (code > 0 && code < sizeof(message)/sizeof(message[0]))
+    return message[code];
+  return NULL;
+}
+
+const XML_LChar * XMLCALL
 XML_ExpatVersion(void) {
 
   /* V1 is used to string-ize the version number. However, it would
      string-ize the actual version macro *names* unless we get them
      substituted before being passed to V1. CPP is defined to expand
      a macro, then rescan for more expansions. Thus, we use V2 to expand
      the version macros, then CPP will expand the resulting V1() macro
      with the correct numerals. */
@@ -2018,16 +2428,22 @@ XML_GetFeatureList(void)
      XML_CONTEXT_BYTES},
 #endif
 #ifdef XML_MIN_SIZE
     {XML_FEATURE_MIN_SIZE,         XML_L("XML_MIN_SIZE"), 0},
 #endif
 #ifdef XML_NS
     {XML_FEATURE_NS,               XML_L("XML_NS"), 0},
 #endif
+#ifdef XML_LARGE_SIZE
+    {XML_FEATURE_LARGE_SIZE,       XML_L("XML_LARGE_SIZE"), 0},
+#endif
+#ifdef XML_ATTR_INFO
+    {XML_FEATURE_ATTR_INFO,        XML_L("XML_ATTR_INFO"), 0},
+#endif
     {XML_FEATURE_END,              NULL, 0}
   };
 
   return features;
 }
 #endif
 /* END MOZILLA CHANGE */
 
@@ -2090,17 +2506,17 @@ storeRawNames(XML_Parser parser)
 }
 
 static enum XML_Error PTRCALL
 contentProcessor(XML_Parser parser,
                  const char *start,
                  const char *end,
                  const char **endPtr)
 {
-  enum XML_Error result = doContent(parser, 0, encoding, start, end, 
+  enum XML_Error result = doContent(parser, 0, encoding, start, end,
                                     endPtr, (XML_Bool)!ps_finalBuffer);
   if (result == XML_ERROR_NONE) {
     if (!storeRawNames(parser))
       return XML_ERROR_NO_MEMORY;
   }
   return result;
 }
 
@@ -2172,17 +2588,17 @@ externalEntityInitProcessor3(XML_Parser 
   switch (tok) {
   case XML_TOK_XML_DECL:
     {
       enum XML_Error result;
       result = processXmlDecl(parser, 1, start, next);
       if (result != XML_ERROR_NONE)
         return result;
       switch (ps_parsing) {
-      case XML_SUSPENDED: 
+      case XML_SUSPENDED:
         *endPtr = next;
         return XML_ERROR_NONE;
       case XML_FINISHED:
         return XML_ERROR_ABORTED;
       default:
         start = next;
       }
     }
@@ -2206,17 +2622,17 @@ externalEntityInitProcessor3(XML_Parser 
 }
 
 static enum XML_Error PTRCALL
 externalEntityContentProcessor(XML_Parser parser,
                                const char *start,
                                const char *end,
                                const char **endPtr)
 {
-  enum XML_Error result = doContent(parser, 1, encoding, start, end, 
+  enum XML_Error result = doContent(parser, 1, encoding, start, end,
                                     endPtr, (XML_Bool)!ps_finalBuffer);
   if (result == XML_ERROR_NONE) {
     if (!storeRawNames(parser))
       return XML_ERROR_NO_MEMORY;
   }
   return result;
 }
 
@@ -2225,17 +2641,17 @@ doContent(XML_Parser parser,
           int startTagLevel,
           const ENCODING *enc,
           const char *s,
           const char *end,
           const char **nextPtr,
           XML_Bool haveMore)
 {
   /* save one level of indirection */
-  DTD * const dtd = _dtd;  
+  DTD * const dtd = _dtd;
 
   const char **eventPP;
   const char **eventEndPP;
   if (enc == encoding) {
     eventPP = &eventPtr;
     eventEndPP = &eventEndPtr;
   }
   else {
@@ -2256,18 +2672,18 @@ doContent(XML_Parser parser,
       }
       *eventEndPP = end;
       if (characterDataHandler) {
         XML_Char c = 0xA;
         characterDataHandler(handlerArg, &c, 1);
       }
       else if (defaultHandler)
         reportDefault(parser, enc, s, end);
-      /* We are at the end of the final buffer, should we check for 
-         XML_SUSPENDED, XML_FINISHED? 
+      /* We are at the end of the final buffer, should we check for
+         XML_SUSPENDED, XML_FINISHED?
       */
       if (startTagLevel == 0)
         return XML_ERROR_NO_ELEMENTS;
       if (tagLevel != startTagLevel)
         return XML_ERROR_ASYNC_ENTITY;
       *nextPtr = end;
       return XML_ERROR_NONE;
     case XML_TOK_NONE:
@@ -2311,17 +2727,17 @@ doContent(XML_Parser parser,
             reportDefault(parser, enc, s, next);
           break;
         }
         name = poolStoreString(&dtd->pool, enc,
                                 s + enc->minBytesPerChar,
                                 next - enc->minBytesPerChar);
         if (!name)
           return XML_ERROR_NO_MEMORY;
-        entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
+        entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
         poolDiscard(&dtd->pool);
         /* First, determine if a check for an existing declaration is needed;
            if yes, check that the entity exists, and that it is internal,
            otherwise call the skipped entity or default handler.
         */
         if (!dtd->hasParamEntityRefs || dtd->standalone) {
           if (!entity)
             return XML_ERROR_UNDEFINED_ENTITY;
@@ -2409,21 +2825,21 @@ doContent(XML_Parser parser,
         ++tagLevel;
         {
           const char *rawNameEnd = tag->rawName + tag->rawNameLength;
           const char *fromPtr = tag->rawName;
           toPtr = (XML_Char *)tag->buf;
           for (;;) {
             int bufSize;
             int convLen;
-            XmlConvert(enc,
+            const enum XML_Convert_Result convert_res = XmlConvert(enc,
                        &fromPtr, rawNameEnd,
                        (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
             convLen = (int)(toPtr - (XML_Char *)tag->buf);
-            if (fromPtr == rawNameEnd) {
+            if ((fromPtr >= rawNameEnd) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) {
               tag->name.strLen = convLen;
               break;
             }
             bufSize = (int)(tag->bufEnd - tag->buf) << 1;
             {
               char *temp = (char *)REALLOC(tag->buf, bufSize);
               if (temp == NULL)
                 return XML_ERROR_NO_MEMORY;
@@ -2456,41 +2872,35 @@ doContent(XML_Parser parser,
         XML_Bool noElmHandlers = XML_TRUE;
         TAG_NAME name;
         name.str = poolStoreString(&tempPool, enc, rawName,
                                    rawName + XmlNameLength(enc, rawName));
         if (!name.str)
           return XML_ERROR_NO_MEMORY;
         poolFinish(&tempPool);
         result = storeAtts(parser, enc, s, &name, &bindings);
-        if (result)
+        if (result != XML_ERROR_NONE) {
+          freeBindings(parser, bindings);
           return result;
+        }
         poolFinish(&tempPool);
         if (startElementHandler) {
           startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
           noElmHandlers = XML_FALSE;
         }
         if (endElementHandler) {
           if (startElementHandler)
             *eventPP = *eventEndPP;
           endElementHandler(handlerArg, name.str);
           noElmHandlers = XML_FALSE;
         }
         if (noElmHandlers && defaultHandler)
           reportDefault(parser, enc, s, next);
         poolClear(&tempPool);
-        while (bindings) {
-          BINDING *b = bindings;
-          if (endNamespaceDeclHandler)
-            endNamespaceDeclHandler(handlerArg, b->prefix->name);
-          bindings = bindings->nextTagBinding;
-          b->nextTagBinding = freeBindingList;
-          freeBindingList = b;
-          b->prefix->binding = b->prevPrefixBinding;
-        }
+        freeBindings(parser, bindings);
       }
       if (tagLevel == 0)
         return epilogProcessor(parser, next, end, nextPtr);
       break;
     case XML_TOK_END_TAG:
       if (tagLevel == startTagLevel)
         return XML_ERROR_ASYNC_ENTITY;
       else {
@@ -2637,77 +3047,103 @@ doContent(XML_Parser parser,
         }
         else
           characterDataHandler(handlerArg,
                                (XML_Char *)s,
                                (int)((XML_Char *)end - (XML_Char *)s));
       }
       else if (defaultHandler)
         reportDefault(parser, enc, s, end);
-      /* We are at the end of the final buffer, should we check for 
-         XML_SUSPENDED, XML_FINISHED? 
+      /* We are at the end of the final buffer, should we check for
+         XML_SUSPENDED, XML_FINISHED?
       */
       if (startTagLevel == 0) {
         *eventPP = end;
         return XML_ERROR_NO_ELEMENTS;
       }
       if (tagLevel != startTagLevel) {
         *eventPP = end;
         return XML_ERROR_ASYNC_ENTITY;
       }
       *nextPtr = end;
       return XML_ERROR_NONE;
     case XML_TOK_DATA_CHARS:
-      if (characterDataHandler) {
-        if (MUST_CONVERT(enc, s)) {
-          for (;;) {
-            ICHAR *dataPtr = (ICHAR *)dataBuf;
-            XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
-            *eventEndPP = s;
-            characterDataHandler(handlerArg, dataBuf,
-                                 (int)(dataPtr - (ICHAR *)dataBuf));
-            if (s == next)
-              break;
-            *eventPP = s;
+      {
+        XML_CharacterDataHandler charDataHandler = characterDataHandler;
+        if (charDataHandler) {
+          if (MUST_CONVERT(enc, s)) {
+            for (;;) {
+              ICHAR *dataPtr = (ICHAR *)dataBuf;
+              const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
+              *eventEndPP = s;
+              charDataHandler(handlerArg, dataBuf,
+                              (int)(dataPtr - (ICHAR *)dataBuf));
+              if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
+                break;
+              *eventPP = s;
+            }
           }
+          else
+            charDataHandler(handlerArg,
+                            (XML_Char *)s,
+                            (int)((XML_Char *)next - (XML_Char *)s));
         }
-        else
-          characterDataHandler(handlerArg,
-                               (XML_Char *)s,
-                               (int)((XML_Char *)next - (XML_Char *)s));
+        else if (defaultHandler)
+          reportDefault(parser, enc, s, next);
       }
-      else if (defaultHandler)
-        reportDefault(parser, enc, s, next);
       break;
     case XML_TOK_PI:
       if (!reportProcessingInstruction(parser, enc, s, next))
         return XML_ERROR_NO_MEMORY;
       break;
     case XML_TOK_COMMENT:
       if (!reportComment(parser, enc, s, next))
         return XML_ERROR_NO_MEMORY;
       break;
     default:
       if (defaultHandler)
         reportDefault(parser, enc, s, next);
       break;
     }
     *eventPP = s = next;
     switch (ps_parsing) {
-    case XML_SUSPENDED: 
+    case XML_SUSPENDED:
       *nextPtr = next;
       return XML_ERROR_NONE;
     case XML_FINISHED:
       return XML_ERROR_ABORTED;
     default: ;
     }
   }
   /* not reached */
 }
 
+/* This function does not call free() on the allocated memory, merely
+ * moving it to the parser's freeBindingList where it can be freed or
+ * reused as appropriate.
+ */
+static void
+freeBindings(XML_Parser parser, BINDING *bindings)
+{
+  while (bindings) {
+    BINDING *b = bindings;
+
+    /* startNamespaceDeclHandler will have been called for this
+     * binding in addBindings(), so call the end handler now.
+     */
+    if (endNamespaceDeclHandler)
+        endNamespaceDeclHandler(handlerArg, b->prefix->name);
+
+    bindings = bindings->nextTagBinding;
+    b->nextTagBinding = freeBindingList;
+    freeBindingList = b;
+    b->prefix->binding = b->prevPrefixBinding;
+  }
+}
+
 /* Precondition: all arguments must be non-NULL;
    Purpose:
    - normalize attributes
    - check attributes for well-formedness
    - generate namespace aware attribute names (URI, prefix)
    - build list of attributes for startElementHandler
    - default attributes
    - process namespace declarations (check and report them)
@@ -2730,52 +3166,73 @@ storeAtts(XML_Parser parser, const ENCOD
   int nPrefixes = 0;
 /* BEGIN MOZILLA CHANGE (Include xmlns attributes in attributes array) */
   int nXMLNSDeclarations = 0;
 /* END MOZILLA CHANGE */
   BINDING *binding;
   const XML_Char *localPart;
 
   /* lookup the element type name */
-  elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, tagNamePtr->str,0);
+  elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str,0);
   if (!elementType) {
     const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
     if (!name)
       return XML_ERROR_NO_MEMORY;
-    elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, name,
+    elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,
                                          sizeof(ELEMENT_TYPE));
     if (!elementType)
       return XML_ERROR_NO_MEMORY;
     if (ns && !setElementTypePrefix(parser, elementType))
       return XML_ERROR_NO_MEMORY;
   }
   nDefaultAtts = elementType->nDefaultAtts;
 
   /* get the attributes from the tokenizer */
   n = XmlGetAttributes(enc, attStr, attsSize, atts);
   if (n + nDefaultAtts > attsSize) {
     int oldAttsSize = attsSize;
     ATTRIBUTE *temp;
+#ifdef XML_ATTR_INFO
+    XML_AttrInfo *temp2;
+#endif
     attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
     temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
     if (temp == NULL)
       return XML_ERROR_NO_MEMORY;
     atts = temp;
+#ifdef XML_ATTR_INFO
+    temp2 = (XML_AttrInfo *)REALLOC((void *)attInfo, attsSize * sizeof(XML_AttrInfo));
+    if (temp2 == NULL)
+      return XML_ERROR_NO_MEMORY;
+    attInfo = temp2;
+#endif
     if (n > oldAttsSize)
       XmlGetAttributes(enc, attStr, n, atts);
   }
 
   appAtts = (const XML_Char **)atts;
   for (i = 0; i < n; i++) {
+    ATTRIBUTE *currAtt = &atts[i];
+#ifdef XML_ATTR_INFO
+    XML_AttrInfo *currAttInfo = &attInfo[i];
+#endif
     /* add the name and value to the attribute list */
-    ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
-                                         atts[i].name
-                                         + XmlNameLength(enc, atts[i].name));
+    ATTRIBUTE_ID *attId = getAttributeId(parser, enc, currAtt->name,
+                                         currAtt->name
+                                         + XmlNameLength(enc, currAtt->name));
     if (!attId)
       return XML_ERROR_NO_MEMORY;
+#ifdef XML_ATTR_INFO
+    currAttInfo->nameStart = parseEndByteIndex - (parseEndPtr - currAtt->name);
+    currAttInfo->nameEnd = currAttInfo->nameStart +
+                           XmlNameLength(enc, currAtt->name);
+    currAttInfo->valueStart = parseEndByteIndex -
+                            (parseEndPtr - currAtt->valuePtr);
+    currAttInfo->valueEnd = parseEndByteIndex - (parseEndPtr - currAtt->valueEnd);
+#endif
     /* Detect duplicate attributes by their QNames. This does not work when
        namespace processing is turned on and different prefixes for the same
        namespace are used. For this case we have a check further down.
     */
     if ((attId->name)[-1]) {
       if (enc == encoding)
         eventPtr = atts[i].name;
       return XML_ERROR_DUPLICATE_ATTRIBUTE;
@@ -2930,41 +3387,53 @@ storeAtts(XML_Parser parser, const ENCOD
 /* END MOZILLA CHANGE */
 
     /* expand prefixed names and check for duplicates */
     for (; i < attIndex; i += 2) {
       const XML_Char *s = appAtts[i];
       if (s[-1] == 2) {  /* prefixed */
         ATTRIBUTE_ID *id;
         const BINDING *b;
-        unsigned long uriHash = 0;
+        unsigned long uriHash;
+        struct siphash sip_state;
+        struct sipkey sip_key;
+
+        copy_salt_to_sipkey(parser, &sip_key);
+        sip24_init(&sip_state, &sip_key);
+
         ((XML_Char *)s)[-1] = 0;  /* clear flag */
-        id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, s, 0);
+        id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0);
+        if (!id || !id->prefix)
+          return XML_ERROR_NO_MEMORY;
         b = id->prefix->binding;
         if (!b)
           return XML_ERROR_UNBOUND_PREFIX;
 
-        /* as we expand the name we also calculate its hash value */
         for (j = 0; j < b->uriLen; j++) {
           const XML_Char c = b->uri[j];
           if (!poolAppendChar(&tempPool, c))
             return XML_ERROR_NO_MEMORY;
-          uriHash = CHAR_HASH(uriHash, c);
         }
-        while (*s++ != XML_T(':'))
+
+        sip24_update(&sip_state, b->uri, b->uriLen * sizeof(XML_Char));
+
+        while (*s++ != XML_T(ASCII_COLON))
           ;
+
+        sip24_update(&sip_state, s, keylen(s) * sizeof(XML_Char));
+
         do {  /* copies null terminator */
-          const XML_Char c = *s;
           if (!poolAppendChar(&tempPool, *s))
             return XML_ERROR_NO_MEMORY;
-          uriHash = CHAR_HASH(uriHash, c);
         } while (*s++);
 
+        uriHash = (unsigned long)sip24_final(&sip_state);
+
         { /* Check hash table for duplicate of expanded name (uriName).
-             Derived from code in lookup(HASH_TABLE *table, ...).
+             Derived from code in lookup(parser, HASH_TABLE *table, ...).
           */
           unsigned char step = 0;
           unsigned long mask = nsAttsSize - 1;
           j = uriHash & mask;  /* index into hash table */
           while (nsAtts[j].version == version) {
             /* for speed we compare stored hash values first */
             if (uriHash == nsAtts[j].hash) {
               const XML_Char *s1 = poolStart(&tempPool);
@@ -2996,34 +3465,35 @@ storeAtts(XML_Parser parser, const ENCOD
 
         /* fill empty slot with new version, uriName and hash value */
         nsAtts[j].version = version;
         nsAtts[j].hash = uriHash;
         nsAtts[j].uriName = s;
 
 /* BEGIN MOZILLA CHANGE (Include xmlns attributes in attributes array) */
 #if 0
-        if (!--nPrefixes)
+        if (!--nPrefixes) {
 #else
         if (!--nPrefixes && !nXMLNSDeclarations) {
 #endif
 /* END MOZILLA CHANGE */
           i += 2;
           break;
         }
       }
 /* BEGIN MOZILLA CHANGE (Include xmlns attributes in attributes array) */
       else if (s[-1] == 3) { /* xmlns attribute */
         static const XML_Char xmlnsNamespace[] = {
-          'h', 't', 't', 'p', ':', '/', '/',
-          'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
-          '2', '0', '0', '0', '/', 'x', 'm', 'l', 'n', 's', '/', '\0'
+          ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
+          ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
+          ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_2, ASCII_0, ASCII_0, ASCII_0,
+          ASCII_SLASH, ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s, ASCII_SLASH, '\0'
         };
         static const XML_Char xmlnsPrefix[] = {
-          'x', 'm', 'l', 'n', 's', '\0'
+          ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s, '\0'
         };
 
         ((XML_Char *)s)[-1] = 0;  /* clear flag */
         if (!poolAppendString(&tempPool, xmlnsNamespace)
             || !poolAppendChar(&tempPool, namespaceSeparator))
           return XML_ERROR_NO_MEMORY;
         s += sizeof(xmlnsPrefix) / sizeof(xmlnsPrefix[0]) - 1;
         if (*s == XML_T(':')) {
@@ -3071,17 +3541,17 @@ storeAtts(XML_Parser parser, const ENCOD
     return XML_ERROR_NONE;
 
   /* expand the element type name */
   if (elementType->prefix) {
     binding = elementType->prefix->binding;
     if (!binding)
       return XML_ERROR_UNBOUND_PREFIX;
     localPart = tagNamePtr->str;
-    while (*localPart++ != XML_T(':'))
+    while (*localPart++ != XML_T(ASCII_COLON))
       ;
   }
   else if (dtd->defaultPrefix.binding) {
     binding = dtd->defaultPrefix.binding;
     localPart = tagNamePtr->str;
   }
   else
     return XML_ERROR_NONE;
@@ -3126,62 +3596,66 @@ storeAtts(XML_Parser parser, const ENCOD
 /* addBinding() overwrites the value of prefix->binding without checking.
    Therefore one must keep track of the old value outside of addBinding().
 */
 static enum XML_Error
 addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
            const XML_Char *uri, BINDING **bindingsPtr)
 {
   static const XML_Char xmlNamespace[] = {
-    'h', 't', 't', 'p', ':', '/', '/',
-    'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
-    'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
-    'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
+    ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
+    ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
+    ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L,
+    ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, ASCII_SLASH,
+    ASCII_n, ASCII_a, ASCII_m, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c,
+    ASCII_e, '\0'
   };
-  static const int xmlLen = 
+  static const int xmlLen =
     (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;
   static const XML_Char xmlnsNamespace[] = {
-    'h', 't', 't', 'p', ':', '/', '/',
-    'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
-    '2', '0', '0', '0', '/', 'x', 'm', 'l', 'n', 's', '/', '\0'
+    ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
+    ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
+    ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_2, ASCII_0, ASCII_0,
+    ASCII_0, ASCII_SLASH, ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s,
+    ASCII_SLASH, '\0'
   };
-  static const int xmlnsLen = 
+  static const int xmlnsLen =
     (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;
 
   XML_Bool mustBeXML = XML_FALSE;
   XML_Bool isXML = XML_TRUE;
   XML_Bool isXMLNS = XML_TRUE;
-  
+
   BINDING *b;
   int len;
 
   /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
   if (*uri == XML_T('\0') && prefix->name)
     return XML_ERROR_UNDECLARING_PREFIX;
 
   if (prefix->name
-      && prefix->name[0] == XML_T('x')
-      && prefix->name[1] == XML_T('m')
-      && prefix->name[2] == XML_T('l')) {
+      && prefix->name[0] == XML_T(ASCII_x)
+      && prefix->name[1] == XML_T(ASCII_m)
+      && prefix->name[2] == XML_T(ASCII_l)) {
 
     /* Not allowed to bind xmlns */
-    if (prefix->name[3] == XML_T('n')
-        && prefix->name[4] == XML_T('s')
+    if (prefix->name[3] == XML_T(ASCII_n)
+        && prefix->name[4] == XML_T(ASCII_s)
         && prefix->name[5] == XML_T('\0'))
       return XML_ERROR_RESERVED_PREFIX_XMLNS;
 
     if (prefix->name[3] == XML_T('\0'))
       mustBeXML = XML_TRUE;
   }
 
   for (len = 0; uri[len]; len++) {
     if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
       isXML = XML_FALSE;
 
-    if (!mustBeXML && isXMLNS 
+    if (!mustBeXML && isXMLNS
         && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
       isXMLNS = XML_FALSE;
   }
   isXML = isXML && len == xmlLen;
   isXMLNS = isXMLNS && len == xmlnsLen;
 
   if (mustBeXML != isXML)
     return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML
@@ -3313,36 +3787,39 @@ doCdataSection(XML_Parser parser,
       if (characterDataHandler) {
         XML_Char c = 0xA;
         characterDataHandler(handlerArg, &c, 1);
       }
       else if (defaultHandler)
         reportDefault(parser, enc, s, next);
       break;
     case XML_TOK_DATA_CHARS:
-      if (characterDataHandler) {
-        if (MUST_CONVERT(enc, s)) {
-          for (;;) {
-            ICHAR *dataPtr = (ICHAR *)dataBuf;
-            XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
-            *eventEndPP = next;
-            characterDataHandler(handlerArg, dataBuf,
-                                 (int)(dataPtr - (ICHAR *)dataBuf));
-            if (s == next)
-              break;
-            *eventPP = s;
+      {
+        XML_CharacterDataHandler charDataHandler = characterDataHandler;
+        if (charDataHandler) {
+          if (MUST_CONVERT(enc, s)) {
+            for (;;) {
+              ICHAR *dataPtr = (ICHAR *)dataBuf;
+              const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
+              *eventEndPP = next;
+              charDataHandler(handlerArg, dataBuf,
+                              (int)(dataPtr - (ICHAR *)dataBuf));
+              if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
+                break;
+              *eventPP = s;
+            }
           }
+          else
+            charDataHandler(handlerArg,
+                            (XML_Char *)s,
+                            (int)((XML_Char *)next - (XML_Char *)s));
         }
-        else
-          characterDataHandler(handlerArg,
-                               (XML_Char *)s,
-                               (int)((XML_Char *)next - (XML_Char *)s));
+        else if (defaultHandler)
+          reportDefault(parser, enc, s, next);
       }
-      else if (defaultHandler)
-        reportDefault(parser, enc, s, next);
       break;
     case XML_TOK_INVALID:
       *eventPP = next;
       return XML_ERROR_INVALID_TOKEN;
     case XML_TOK_PARTIAL_CHAR:
       if (haveMore) {
         *nextPtr = s;
         return XML_ERROR_NONE;
@@ -3379,17 +3856,17 @@ doCdataSection(XML_Parser parser,
    the whole file is parsed with one call.
 */
 static enum XML_Error PTRCALL
 ignoreSectionProcessor(XML_Parser parser,
                        const char *start,
                        const char *end,
                        const char **endPtr)
 {
-  enum XML_Error result = doIgnoreSection(parser, encoding, &start, end, 
+  enum XML_Error result = doIgnoreSection(parser, encoding, &start, end,
                                           endPtr, (XML_Bool)!ps_finalBuffer);
   if (result != XML_ERROR_NONE)
     return result;
   if (start) {
     processor = prologProcessor;
     return prologProcessor(parser, start, end, endPtr);
   }
   return result;
@@ -3661,17 +4138,17 @@ entityValueInitProcessor(XML_Parser pars
                          const char *end,
                          const char **nextPtr)
 {
   int tok;
   const char *start = s;
   const char *next = start;
   eventPtr = start;
 
-  for (;;) {  
+  for (;;) {
     tok = XmlPrologTok(encoding, start, end, &next);
     eventEndPtr = next;
     if (tok <= 0) {
       if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
         *nextPtr = s;
         return XML_ERROR_NONE;
       }
       switch (tok) {
@@ -3689,17 +4166,17 @@ entityValueInitProcessor(XML_Parser pars
       return storeEntityValue(parser, encoding, s, end);
     }
     else if (tok == XML_TOK_XML_DECL) {
       enum XML_Error result;
       result = processXmlDecl(parser, 0, start, next);
       if (result != XML_ERROR_NONE)
         return result;
       switch (ps_parsing) {
-      case XML_SUSPENDED: 
+      case XML_SUSPENDED:
         *nextPtr = next;
         return XML_ERROR_NONE;
       case XML_FINISHED:
         return XML_ERROR_ABORTED;
       default:
         *nextPtr = next;
       }
       /* stop scanning for text declaration - we found one */
@@ -3712,16 +4189,24 @@ entityValueInitProcessor(XML_Parser pars
        tokens, but not for the BOM - we would rather like to skip it;
        then, when this routine is entered the next time, XmlPrologTok will
        return XML_TOK_INVALID, since the BOM is still in the buffer
     */
     else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) {
       *nextPtr = next;
       return XML_ERROR_NONE;
     }
+    /* If we get this token, we have the start of what might be a
+       normal tag, but not a declaration (i.e. it doesn't begin with
+       "<!").  In a DTD context, that isn't legal.
+    */
+    else if (tok == XML_TOK_INSTANCE_START) {
+      *nextPtr = next;
+      return XML_ERROR_SYNTAX;
+    }
     start = next;
     eventPtr = start;
   }
 }
 
 static enum XML_Error PTRCALL
 externalParEntProcessor(XML_Parser parser,
                         const char *s,
@@ -3754,17 +4239,17 @@ externalParEntProcessor(XML_Parser parse
      as valid, and report a syntax error, so we have to skip the BOM
   */
   else if (tok == XML_TOK_BOM) {
     s = next;
     tok = XmlPrologTok(encoding, s, end, &next);
   }
 
   processor = prologProcessor;
-  return doProlog(parser, encoding, s, end, tok, next, 
+  return doProlog(parser, encoding, s, end, tok, next,
                   nextPtr, (XML_Bool)!ps_finalBuffer);
 }
 
 static enum XML_Error PTRCALL
 entityValueProcessor(XML_Parser parser,
                      const char *s,
                      const char *end,
                      const char **nextPtr)
@@ -3804,51 +4289,55 @@ entityValueProcessor(XML_Parser parser,
 static enum XML_Error PTRCALL
 prologProcessor(XML_Parser parser,
                 const char *s,
                 const char *end,
                 const char **nextPtr)
 {
   const char *next = s;
   int tok = XmlPrologTok(encoding, s, end, &next);
-  return doProlog(parser, encoding, s, end, tok, next, 
+  return doProlog(parser, encoding, s, end, tok, next,
                   nextPtr, (XML_Bool)!ps_finalBuffer);
 }
 
 static enum XML_Error
 doProlog(XML_Parser parser,
          const ENCODING *enc,
          const char *s,
          const char *end,
          int tok,
          const char *next,
          const char **nextPtr,
          XML_Bool haveMore)
 {
 #ifdef XML_DTD
-  static const XML_Char externalSubsetName[] = { '#' , '\0' };
+  static const XML_Char externalSubsetName[] = { ASCII_HASH , '\0' };
 #endif /* XML_DTD */
-  static const XML_Char atypeCDATA[] = { 'C', 'D', 'A', 'T', 'A', '\0' };
-  static const XML_Char atypeID[] = { 'I', 'D', '\0' };
-  static const XML_Char atypeIDREF[] = { 'I', 'D', 'R', 'E', 'F', '\0' };
-  static const XML_Char atypeIDREFS[] = { 'I', 'D', 'R', 'E', 'F', 'S', '\0' };
-  static const XML_Char atypeENTITY[] = { 'E', 'N', 'T', 'I', 'T', 'Y', '\0' };
-  static const XML_Char atypeENTITIES[] =
-      { 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S', '\0' };
+  static const XML_Char atypeCDATA[] =
+      { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
+  static const XML_Char atypeID[] = { ASCII_I, ASCII_D, '\0' };
+  static const XML_Char atypeIDREF[] =
+      { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' };
+  static const XML_Char atypeIDREFS[] =
+      { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' };
+  static const XML_Char atypeENTITY[] =
+      { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' };
+  static const XML_Char atypeENTITIES[] = { ASCII_E, ASCII_N,
+      ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\0' };
   static const XML_Char atypeNMTOKEN[] = {
-      'N', 'M', 'T', 'O', 'K', 'E', 'N', '\0' };
-  static const XML_Char atypeNMTOKENS[] = {
-      'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S', '\0' };
-  static const XML_Char notationPrefix[] = {
-      'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N', '(', '\0' };
-  static const XML_Char enumValueSep[] = { '|', '\0' };
-  static const XML_Char enumValueStart[] = { '(', '\0' };
+      ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' };
+  static const XML_Char atypeNMTOKENS[] = { ASCII_N, ASCII_M, ASCII_T,
+      ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0' };
+  static const XML_Char notationPrefix[] = { ASCII_N, ASCII_O, ASCII_T,
+      ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0' };
+  static const XML_Char enumValueSep[] = { ASCII_PIPE, '\0' };
+  static const XML_Char enumValueStart[] = { ASCII_LPAREN, '\0' };
 
   /* save one level of indirection */
-  DTD * const dtd = _dtd; 
+  DTD * const dtd = _dtd;
 
   const char **eventPP;
   const char **eventEndPP;
   enum XML_Content_Quant quant;
 
   if (enc == encoding) {
     eventPP = &eventPtr;
     eventEndPP = &eventEndPtr;
@@ -3942,33 +4431,36 @@ doProlog(XML_Parser parser,
         enc = encoding;
         handleDefault = XML_FALSE;
       }
       break;
 #endif /* XML_DTD */
     case XML_ROLE_DOCTYPE_PUBLIC_ID:
 #ifdef XML_DTD
       useForeignDTD = XML_FALSE;
-      declEntity = (ENTITY *)lookup(&dtd->paramEntities,
+      declEntity = (ENTITY *)lookup(parser,
+                                    &dtd->paramEntities,
                                     externalSubsetName,
                                     sizeof(ENTITY));
       if (!declEntity)
         return XML_ERROR_NO_MEMORY;
 #endif /* XML_DTD */
       dtd->hasParamEntityRefs = XML_TRUE;
       if (startDoctypeDeclHandler) {
+        XML_Char *pubId;
         if (!XmlIsPublicId(enc, s, next, eventPP))
           return XML_ERROR_PUBLICID;
-        doctypePubid = poolStoreString(&tempPool, enc,
-                                       s + enc->minBytesPerChar,
-                                       next - enc->minBytesPerChar);
-        if (!doctypePubid)
+        pubId = poolStoreString(&tempPool, enc,
+                                s + enc->minBytesPerChar,
+                                next - enc->minBytesPerChar);
+        if (!pubId)
           return XML_ERROR_NO_MEMORY;
-        normalizePublicId((XML_Char *)doctypePubid);
+        normalizePublicId(pubId);
         poolFinish(&tempPool);
+        doctypePubid = pubId;
         handleDefault = XML_FALSE;
         goto alreadyChecked;
       }
       /* fall through */
     case XML_ROLE_ENTITY_PUBLIC_ID:
       if (!XmlIsPublicId(enc, s, next, eventPP))
         return XML_ERROR_PUBLICID;
     alreadyChecked:
@@ -3997,33 +4489,34 @@ doProlog(XML_Parser parser,
          XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
          was not set, indicating an external subset
       */
 #ifdef XML_DTD
       if (doctypeSysid || useForeignDTD) {
         XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
         dtd->hasParamEntityRefs = XML_TRUE;
         if (paramEntityParsing && externalEntityRefHandler) {
-          ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
+          ENTITY *entity = (ENTITY *)lookup(parser,
+                                            &dtd->paramEntities,
                                             externalSubsetName,
                                             sizeof(ENTITY));
           if (!entity)
             return XML_ERROR_NO_MEMORY;
           if (useForeignDTD)
             entity->base = curBase;
           dtd->paramEntityRead = XML_FALSE;
           if (!externalEntityRefHandler(externalEntityRefHandlerArg,
                                         0,
                                         entity->base,
                                         entity->systemId,
                                         entity->publicId))
             return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
           if (dtd->paramEntityRead) {
-            if (!dtd->standalone && 
-                notStandaloneHandler && 
+            if (!dtd->standalone &&
+                notStandaloneHandler &&
                 !notStandaloneHandler(handlerArg))
               return XML_ERROR_NOT_STANDALONE;
           }
           /* if we didn't read the foreign DTD then this means that there
              is no external subset and we must reset dtd->hasParamEntityRefs
           */
           else if (!doctypeSysid)
             dtd->hasParamEntityRefs = hadParamEntityRefs;
@@ -4041,17 +4534,17 @@ doProlog(XML_Parser parser,
 #ifdef XML_DTD
       /* if there is no DOCTYPE declaration then now is the
          last chance to read the foreign DTD
       */
       if (useForeignDTD) {
         XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
         dtd->hasParamEntityRefs = XML_TRUE;
         if (paramEntityParsing && externalEntityRefHandler) {
-          ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
+          ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,
                                             externalSubsetName,
                                             sizeof(ENTITY));
           if (!entity)
             return XML_ERROR_NO_MEMORY;
           entity->base = curBase;
           dtd->paramEntityRead = XML_FALSE;
           if (!externalEntityRefHandler(externalEntityRefHandlerArg,
                                         0,
@@ -4141,21 +4634,21 @@ doProlog(XML_Parser parser,
     case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
     case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
       if (dtd->keepProcessing) {
         if (!defineAttribute(declElementType, declAttributeId,
                              declAttributeIsCdata, declAttributeIsId,
                              0, parser))
           return XML_ERROR_NO_MEMORY;
         if (attlistDeclHandler && declAttributeType) {
-          if (*declAttributeType == XML_T('(')
-              || (*declAttributeType == XML_T('N')
-                  && declAttributeType[1] == XML_T('O'))) {
+          if (*declAttributeType == XML_T(ASCII_LPAREN)
+              || (*declAttributeType == XML_T(ASCII_N)
+                  && declAttributeType[1] == XML_T(ASCII_O))) {
             /* Enumerated or Notation type */
-            if (!poolAppendChar(&tempPool, XML_T(')'))
+            if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
                 || !poolAppendChar(&tempPool, XML_T('\0')))
               return XML_ERROR_NO_MEMORY;
             declAttributeType = tempPool.start;
             poolFinish(&tempPool);
           }
           *eventEndPP = s;
           attlistDeclHandler(handlerArg, declElementType->name,
                              declAttributeId->name, declAttributeType,
@@ -4178,21 +4671,21 @@ doProlog(XML_Parser parser,
           return result;
         attVal = poolStart(&dtd->pool);
         poolFinish(&dtd->pool);
         /* ID attributes aren't allowed to have a default */
         if (!defineAttribute(declElementType, declAttributeId,
                              declAttributeIsCdata, XML_FALSE, attVal, parser))
           return XML_ERROR_NO_MEMORY;
         if (attlistDeclHandler && declAttributeType) {
-          if (*declAttributeType == XML_T('(')
-              || (*declAttributeType == XML_T('N')
-                  && declAttributeType[1] == XML_T('O'))) {
+          if (*declAttributeType == XML_T(ASCII_LPAREN)
+              || (*declAttributeType == XML_T(ASCII_N)
+                  && declAttributeType[1] == XML_T(ASCII_O))) {
             /* Enumerated or Notation type */
-            if (!poolAppendChar(&tempPool, XML_T(')'))
+            if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
                 || !poolAppendChar(&tempPool, XML_T('\0')))
               return XML_ERROR_NO_MEMORY;
             declAttributeType = tempPool.start;
             poolFinish(&tempPool);
           }
           *eventEndPP = s;
           attlistDeclHandler(handlerArg, declElementType->name,
                              declAttributeId->name, declAttributeType,
@@ -4255,17 +4748,18 @@ doProlog(XML_Parser parser,
 #endif /* XML_DTD */
           && notStandaloneHandler
           && !notStandaloneHandler(handlerArg))
         return XML_ERROR_NOT_STANDALONE;
 #ifndef XML_DTD
       break;
 #else /* XML_DTD */
       if (!declEntity) {
-        declEntity = (ENTITY *)lookup(&dtd->paramEntities,
+        declEntity = (ENTITY *)lookup(parser,
+                                      &dtd->paramEntities,
                                       externalSubsetName,
                                       sizeof(ENTITY));
         if (!declEntity)
           return XML_ERROR_NO_MEMORY;
         declEntity->publicId = NULL;
       }
       /* fall through */
 #endif /* XML_DTD */
@@ -4330,17 +4824,17 @@ doProlog(XML_Parser parser,
         if (XmlPredefinedEntityName(enc, s, next)) {
           declEntity = NULL;
           break;
         }
         if (dtd->keepProcessing) {
           const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
           if (!name)
             return XML_ERROR_NO_MEMORY;
-          declEntity = (ENTITY *)lookup(&dtd->generalEntities, name,
+          declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities, name,
                                         sizeof(ENTITY));
           if (!declEntity)
             return XML_ERROR_NO_MEMORY;
           if (declEntity->name != name) {
             poolDiscard(&dtd->pool);
             declEntity = NULL;
           }
           else {
@@ -4362,17 +4856,17 @@ doProlog(XML_Parser parser,
       }
       break;
     case XML_ROLE_PARAM_ENTITY_NAME:
 #ifdef XML_DTD
       if (dtd->keepProcessing) {
         const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
         if (!name)
           return XML_ERROR_NO_MEMORY;
-        declEntity = (ENTITY *)lookup(&dtd->paramEntities,
+        declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities,
                                            name, sizeof(ENTITY));
         if (!declEntity)
           return XML_ERROR_NO_MEMORY;
         if (declEntity->name != name) {
           poolDiscard(&dtd->pool);
           declEntity = NULL;
         }
         else {
@@ -4451,17 +4945,17 @@ doProlog(XML_Parser parser,
         handleDefault = XML_FALSE;
       }
       poolClear(&tempPool);
       break;
     case XML_ROLE_ERROR:
       switch (tok) {
       case XML_TOK_PARAM_ENTITY_REF:
         /* PE references in internal subset are
-           not allowed within declarations. */  
+           not allowed within declarations. */
         return XML_ERROR_PARAM_ENTITY_REF;
       case XML_TOK_XML_DECL:
         return XML_ERROR_MISPLACED_XML_PI;
       default:
         return XML_ERROR_SYNTAX;
       }
 #ifdef XML_DTD
     case XML_ROLE_IGNORE_SECT:
@@ -4509,52 +5003,52 @@ doProlog(XML_Parser parser,
         dtd->scaffIndex[dtd->scaffLevel] = myindex;
         dtd->scaffLevel++;
         dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
         if (elementDeclHandler)
           handleDefault = XML_FALSE;
       }
       break;
     case XML_ROLE_GROUP_SEQUENCE:
-      if (groupConnector[prologState.level] == '|')
+      if (groupConnector[prologState.level] == ASCII_PIPE)
         return XML_ERROR_SYNTAX;
-      groupConnector[prologState.level] = ',';
+      groupConnector[prologState.level] = ASCII_COMMA;
       if (dtd->in_eldecl && elementDeclHandler)
         handleDefault = XML_FALSE;
       break;
     case XML_ROLE_GROUP_CHOICE:
-      if (groupConnector[prologState.level] == ',')
+      if (groupConnector[prologState.level] == ASCII_COMMA)
         return XML_ERROR_SYNTAX;
       if (dtd->in_eldecl
           && !groupConnector[prologState.level]
           && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
               != XML_CTYPE_MIXED)
           ) {