Merge autoland to mozilla-central. a=merge
authorBogdan Tara <btara@mozilla.com>
Fri, 25 Oct 2019 00:39:45 +0300
changeset 499178 dd7a79a0e83d6d24f672ce3f619f613ca7ab5f1d
parent 499122 724c75f9d98fa441703a4e36f294672859e138d7 (current diff)
parent 499111 c8f662192222035fe449c21a6cd1d24f2fe09b4a (diff)
child 499225 11b08c1b006151252402f683152cb7f39d95cc61
push id114161
push userncsoregi@mozilla.com
push dateTue, 29 Oct 2019 21:34:24 +0000
treeherdermozilla-inbound@25bf8e097e60 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone72.0a1
first release with
nightly linux32
dd7a79a0e83d / 72.0a1 / 20191024214023 / files
nightly linux64
dd7a79a0e83d / 72.0a1 / 20191024214023 / files
nightly mac
dd7a79a0e83d / 72.0a1 / 20191024214023 / files
nightly win32
dd7a79a0e83d / 72.0a1 / 20191024214023 / files
nightly win64
dd7a79a0e83d / 72.0a1 / 20191024214023 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge autoland to mozilla-central. a=merge
--- a/.eslintignore
+++ b/.eslintignore
@@ -6,20 +6,16 @@
 **/crashtests/
 # Also ignore reftest - specially crafted to produce expected output.
 **/reftest/
 **/reftests/
 
 # Exclude expected objdirs.
 obj*/
 
-# dom/ exclusions which should be removed (aka ESLint enabled)
-dom/media/test/
-!dom/media/test/marionette/yttest/*.js
-
 # build/ third-party code
 build/pgo/js-input/
 
 # browser/ exclusions
 browser/app/
 browser/branding/**/firefox-branding.js
 # Gzipped test file.
 browser/base/content/test/general/gZipOfflineChild.html
@@ -154,16 +150,18 @@ dom/svg/test/test_SVG_namespace_ids.html
 
 # Strange encodings
 dom/base/test/file_bug687859-16.js
 dom/encoding/test/test_utf16_files.html
 dom/encoding/test/file_utf16_be_bom.js
 dom/encoding/test/file_utf16_le_bom.js
 
 # Not parsable
+dom/media/test/marionette/yttest/duration_test.js
+dom/media/test/marionette/yttest/until_end_test.js
 dom/tests/mochitest/general/test_focusrings.xul
 dom/html/test/test_bug677658.html
 
 # Service workers fixtures which require specific resource caching.
 dom/base/test/file_js_cache.js
 dom/serviceworkers/test/file_js_cache.js
 
 # Intentional broken files
--- a/browser/components/aboutconfig/content/aboutconfig.css
+++ b/browser/components/aboutconfig/content/aboutconfig.css
@@ -12,21 +12,21 @@
 }
 
 .table-shown > #show-all,
 .table-shown > .config-background-wrapper {
   display: none;
 }
 
 .config-background {
-  background-image: url("chrome://browser/content/aboutconfig/background.svg");
-  background-repeat: no-repeat;
-  background-position: center center;
-  background-size: 400px;
-  height: 350px;
+  background: url("chrome://browser/content/aboutconfig/background.svg") no-repeat;
+  height: 182px;
+  margin-block: 32px;
+  margin-inline: auto;
+  width: 235px;
 }
 
 .config-help-text {
   text-align: center;
 }
 
 .title {
   background-image: url("chrome://global/skin/icons/warning.svg");
@@ -49,25 +49,40 @@
   fill: currentColor;
   fill-opacity: 0.8;
   box-sizing: border-box;
   width: 100%;
   background-image: url("chrome://global/skin/icons/search-textbox.svg");
   background-repeat: no-repeat;
   background-position: 9px center;
   background-size: 12px 12px;
-  padding-inline-start: 30px;
   z-index: 1;
   /* Set horizontal margin to 0 to ensure alignment with table. */
-  margin-right: 0;
-  margin-left: 0;
+  margin-inline: 0;
+  text-align: match-parent;
+  /* All prefs must be left-to-right. */
+  direction: ltr;
 }
 
-#about-config-search:dir(rtl) {
+#about-config-search:placeholder-shown {
+  /* Display the placeholder in its natural directionality,
+   * even if the user changes the text direction manually
+   * (e.g. via RightCtrl+Shift). */
+  direction: inherit;
+}
+
+:root:dir(ltr) #about-config-search {
+  /* Be explicit about padding direction since
+   * `about-config-search` is forced to be LTR. */
+  padding-left: 30px;
+}
+
+:root:dir(rtl) #about-config-search {
   background-position-x: right 9px;
+  padding-right: 30px;
 }
 
 #show-all {
   display: block;
   margin: 10px auto;
 }
 
 #prefs {
@@ -111,18 +126,27 @@
 
 #prefs > tr > td,
 #prefs > tr > th {
   padding: 4px;
   font-weight: inherit;
 }
 
 #prefs > tr > th {
-  text-align: unset;
-  padding-inline-start: 30px;
+  direction: ltr;
+  text-align: match-parent;
+}
+
+#prefs > tr:dir(ltr) > th {
+  /* Be explicit about padding direction since `th` is forced to be LTR. */
+  padding-left: 30px;
+}
+
+#prefs > tr:dir(rtl) > th {
+  padding-right: 30px;
 }
 
 #prefs > tr.deleted > th {
   font-weight: bold;
   color: var(--in-content-deemphasized-text);
 }
 
 #prefs > tr > td.cell-edit,
@@ -140,16 +164,20 @@
 tr:not(.deleted) > .cell-value {
   /* Always display the text in the value cell using left-to-right rules, but
      align it according to the page direction. This doesn't apply to the radio
      buttons shown for deleted preferences. */
   direction: ltr;
   text-align: match-parent;
 }
 
+#form-edit > label {
+  padding-inline-end: 10px;
+}
+
 td.cell-value > form > input[type="text"],
 td.cell-value > form > input[type="number"] {
   -moz-appearance: textfield;
   margin: 0;
   width: 100%;
   box-sizing: border-box;
   /* Align the text inside the input field in the same way as the table cell,
      for both the left-to-right and right-to-left directions. */
--- a/browser/components/aboutconfig/content/background.svg
+++ b/browser/components/aboutconfig/content/background.svg
@@ -1,4 +1,4 @@
 <!-- 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/. -->
-<svg xmlns="http://www.w3.org/2000/svg"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="-507.873" y1="-715.302" x2="996.096" y2="1216.054"><stop offset="0" stop-color="#CCFBFF"/><stop offset="1" stop-color="#C9E4FF"/></linearGradient><linearGradient id="b" gradientUnits="userSpaceOnUse" x1="-866.014" y1="-1067.102" x2="1061.399" y2="1209.328"><stop offset="0" stop-color="#00C8D7"/><stop offset="1" stop-color="#0A84FF"/></linearGradient><path fill="#fff" d="M231.96 50.07h-45.22c-4.04-7.41-14.06-23.35-26.58-25.74-16.64-3.17-19.96 13.41-19.96 13.41s-11.06-28.74-39.03-24.93c-30.84 4.2-17.08 36.19-16.61 37.26h-47.22c-1.21 0-2.19.98-2.19 2.19s.98 2.19 2.19 2.19h194.61c1.21 0 2.19-.98 2.19-2.19s-.98-2.19-2.18-2.19zM388.94 106.16h-25.71c-2.24-4.12-7.84-13.06-14.85-14.39-9.28-1.77-11.14 7.48-11.14 7.48s-6.17-16.04-21.78-13.92c-17.5 2.38-9.26 20.81-9.26 20.81h-26.35l.85.02h-.37c-1.21 0-2.19.98-2.19 2.19s.98 2.19 2.19 2.19h108.6c1.21 0 2.19-.98 2.19-2.19s-.97-2.19-2.18-2.19z"/><path fill="#EAEAEE" d="M290.26 270.21c27.38-5.11 44.63-12.57 44.63-20.87 0-15.42-59.51-27.92-132.92-27.92s-132.92 12.5-132.92 27.92c0 12.94 41.95 23.83 98.84 26.99-2.48 1.99-3.84 4.12-3.84 6.34 0 10.82 31.9 19.58 71.25 19.58s71.25-8.77 71.25-19.58c.01-4.73-6.1-9.07-16.29-12.46z"/><ellipse fill="#EAEAEE" cx="338.65" cy="275.6" rx="20.42" ry="6.67"/><ellipse fill="#EAEAEE" cx="131.56" cy="285.18" rx="15.83" ry="5.42"/><ellipse fill="#EAEAEE" cx="346.56" cy="261.43" rx="7.92" ry="3.33"/><path fill="#EAEAEE" d="M89.35 155.33h205.58c1.03 0 1.86-.83 1.86-1.86 0-1.03-.83-1.86-1.86-1.86h-205.58c-1.03 0-1.86.83-1.86 1.86.01 1.03.84 1.86 1.86 1.86zM117.13 146.05h51.57c.51 0 .93-.42.93-.93s-.42-.93-.93-.93h-51.57c-.51 0-.93.42-.93.93s.41.93.93.93zM52.33 163.45h22.29c.51 0 .93-.42.93-.93s-.42-.93-.93-.93h-22.29c-.51 0-.93.42-.93.93s.41.93.93.93zM89.48 161.59c-.51 0-.93.42-.93.93s.42.93.93.93h5.57c.51 0 .93-.42.93-.93s-.42-.93-.93-.93h-5.57zM294.73 162.52c0 .51.42.93.93.93h5.57c.51 0 .93-.42.93-.93s-.42-.93-.93-.93h-5.57c-.51 0-.93.42-.93.93zM308.66 163.45h1.86c.51 0 .93-.42.93-.93s-.42-.93-.93-.93h-1.86c-.51 0-.93.42-.93.93s.42.93.93.93zM104.34 161.59h-1.86c-.51 0-.93.42-.93.93s.42.93.93.93h1.86c.51 0 .93-.42.93-.93s-.42-.93-.93-.93zM327.24 163.45h22.29c.51 0 .93-.42.93-.93s-.42-.93-.93-.93h-22.29c-.51 0-.93.42-.93.93s.41.93.93.93zM281.73 162.52c0-.51-.42-.93-.93-.93h-22.29c-.51 0-.93.42-.93.93s.42.93.93.93h22.29c.51 0 .93-.42.93-.93zM369.21 211.12h-94.45c-1.03 0-1.86.83-1.86 1.86s.83 1.86 1.86 1.86h94.45c1.03 0 1.86-.83 1.86-1.86s-.83-1.86-1.86-1.86zM99.21 211.12h-84.45c-1.03 0-1.86.83-1.86 1.86s.83 1.86 1.86 1.86h84.45c1.03 0 1.86-.83 1.86-1.86s-.83-1.86-1.86-1.86zM230.6 46.06h-12.16c-.6 0-1.09-.49-1.09-1.09 0-.6.49-1.09 1.09-1.09h12.16c.6 0 1.09.49 1.09 1.09 0 .6-.49 1.09-1.09 1.09zm-31.83 0h-2.19c-.6 0-1.09-.49-1.09-1.09 0-.6.49-1.09 1.09-1.09h2.19c.6 0 1.09.49 1.09 1.09.01.6-.48 1.09-1.09 1.09zm-113.39-1.32h-3.52c-.6 0-1.09-.49-1.09-1.09 0-.6.49-1.09 1.09-1.09h1.9c-.15-.4-.32-.87-.5-1.4-.19-.57.11-1.19.69-1.39.57-.19 1.19.11 1.39.69.58 1.7 1.03 2.73 1.04 2.75.15.34.12.73-.08 1.04-.2.3-.55.49-.92.49zm-21 0h-26.22c-.6 0-1.09-.49-1.09-1.09 0-.6.49-1.09 1.09-1.09h26.22c.6 0 1.09.49 1.09 1.09.01.6-.48 1.09-1.09 1.09zm124.32-.12c-.38 0-.75-.2-.96-.56-.7-1.25-1.85-3.22-3.4-5.52-.34-.5-.2-1.18.3-1.52.5-.34 1.18-.2 1.52.3 1.58 2.37 2.77 4.39 3.49 5.67.29.53.11 1.19-.42 1.49-.17.09-.35.14-.53.14zm-106.44-11.23c-.54 0-1-.39-1.08-.94-.1-.73-.19-1.48-.25-2.24-.05-.6.4-1.13 1-1.18.63-.03 1.13.4 1.18 1 .06.72.14 1.42.23 2.11.08.6-.33 1.15-.93 1.23l-.15.02zm56.93-4.82c-.39 0-.77-.21-.96-.57-.31-.58-.66-1.2-1.06-1.86-.31-.52-.14-1.19.38-1.5.52-.32 1.19-.14 1.5.38.41.69.78 1.34 1.11 1.95.29.53.09 1.19-.44 1.48-.18.08-.36.12-.53.12zm34.69-2.79c-.25 0-.51-.09-.71-.26-4.17-3.58-8.35-5.79-12.41-6.57-3.99-.76-7.53-.38-10.45 1.13-.54.28-1.2.06-1.47-.47-.28-.54-.07-1.2.47-1.47 3.37-1.74 7.39-2.19 11.87-1.34 4.44.85 8.96 3.22 13.42 7.06.46.39.51 1.08.12 1.54-.23.25-.54.38-.84.38zm-40.9-6.19c-.3 0-.61-.13-.82-.37-1.43-1.65-2.97-3.15-4.55-4.48-.46-.39-.52-1.08-.14-1.54.39-.46 1.07-.52 1.54-.14 1.67 1.4 3.29 2.99 4.8 4.72.4.46.35 1.15-.11 1.54-.21.18-.47.27-.72.27zm-45.06-6.37c-.3 0-.59-.12-.81-.36-.41-.45-.37-1.14.08-1.54 3.49-3.16 8.42-5.19 14.64-6.05 3.81-.52 7.53-.47 11.07.15.59.1.99.67.89 1.26-.1.59-.68 1-1.26.89-3.31-.58-6.81-.62-10.4-.13-5.78.79-10.31 2.64-13.47 5.5-.22.18-.48.28-.74.28zM306.98 103.19h-26.31c-.61 0-1.1-.49-1.1-1.1 0-.61.49-1.1 1.1-1.1h26.31c.61 0 1.1.49 1.1 1.1 0 .61-.49 1.1-1.1 1.1zm81.08-.35h-1.01c-.61 0-1.1-.49-1.1-1.1s.49-1.1 1.1-1.1h1.01c.61 0 1.1.49 1.1 1.1s-.5 1.1-1.1 1.1zm-9.79 0h-6.58c-.61 0-1.1-.49-1.1-1.1s.49-1.1 1.1-1.1h6.58c.61 0 1.1.49 1.1 1.1s-.49 1.1-1.1 1.1zm-40.21-6.55c-.45 0-.91-.3-1.03-.71s-.16-.62.26-1.76c1.01-3.07 3.9-7.43 9.63-7.43.79 0 1.62.08 2.47.24 3.26.62 6.55 2.52 9.78 5.66.43.42.45 1.12.02 1.55-.42.44-1.12.45-1.55.03-2.92-2.83-5.83-4.54-8.67-5.08-.72-.14-1.41-.21-2.06-.21-6.32 0-7.74 6.55-7.8 6.83-.08.51-.53.88-1.05.88zm-30.5-9.79c-.25 0-.5-.09-.71-.26-.46-.39-.52-1.08-.13-1.55 1.45-1.71 3.47-2.97 6.01-3.76.58-.18 1.19.14 1.37.72.18.58-.14 1.19-.72 1.37-2.13.66-3.81 1.7-4.99 3.09-.22.26-.52.39-.83.39zm16.31-3.69c-.1 0-.19-.01-.29-.04-.65-.18-1.32-.31-2.01-.42-.6-.09-1.02-.64-.93-1.24.09-.6.64-.99 1.24-.93.79.11 1.55.27 2.27.47.58.16.93.76.77 1.34-.12.5-.57.82-1.05.82z"/><path fill="#fff" d="M272.33 258.76l-20.54-172c-.42-3.52-3.41-6.17-6.95-6.17h-103.41c-2 0-3.91.86-5.23 2.35-1.06 1.2-1.67 2.71-1.76 4.28-.56.78-.96 1.68-1.16 2.63l-31.55 151.25c-.43 2.07.09 4.2 1.42 5.84 1.33 1.64 3.31 2.58 5.43 2.58h45.13l1.3 10.9c.42 3.52 3.41 6.17 6.95 6.17h103.41c2 0 3.91-.86 5.24-2.35s1.95-3.49 1.72-5.48z"/><path fill="#F9F9FA" d="M151.59 96.15h86.53l18.78 154.22h-86.53z"/><path fill="url(#a)" d="M112.33 240.19h45.45l-16.55-138.58-28.9 138.58zm130.95-149.93h-98.37l19.94 167h98.37l-19.94-167zm-91.69 5.89h86.53l18.77 154.23h-86.53l-18.77-154.23zm63.14 7.45h-35c-2.75 0-5 2.25-5 5s2.25 5 5 5h35c2.75 0 5-2.25 5-5s-2.25-5-5-5z"/><path fill="url(#b)" d="M268.52 259.46l-20.54-172c-.15-1.26-1.22-2.2-2.48-2.2h-103.41c-.71 0-1.4.31-1.87.84-.47.53-.7 1.25-.61 1.96l.14 1.14c-.69.32-1.23.95-1.4 1.75l-31.55 151.23c-.15.74.03 1.5.51 2.09.47.58 1.19.92 1.94.92h49.12l1.77 14.86c.15 1.26 1.22 2.2 2.48 2.2h103.41c.71 0 1.4-.31 1.87-.84.49-.53.71-1.24.62-1.95zm-156.19-19.27l23.94-114.76 13.36 114.76h-37.3zm52.52 17.07l-19.94-167h98.37l19.94 167h-98.37zm15.59-105.41c-3.59-.25-6.69 2.62-6.93 6.4-.24 3.79 2.48 7.06 6.07 7.31 1.25.09 2.43-.21 3.46-.78.71-2.52 1.69-5.98 2.66-9.39-1.03-1.98-2.97-3.38-5.26-3.54zm57.96 23.94l-19.85-8.73c-.9-.39-1.92-.25-2.69.39l-9.68 8.04-.14-.14-11.31-10.35 17.37-17.12c1.08-1.06 1.14-2.85.13-3.99-1.01-1.14-2.7-1.2-3.78-.13l-16.83 16.59c1.95-6.89 5.02-17.35 7.21-24.7.44-1.49-.34-3.07-1.75-3.54-1.41-.47-2.91.36-3.36 1.85-.02.06-1.22 4.12-2.75 9.31-.6 2.03-1.24 4.23-1.88 6.44-4.78 16.44-4.74 16.82-4.63 17.65.07.54.28 1.02.58 1.41l.12.24c.26.52.61.99 1.06 1.4l13.65 12.47c.12.11.24.21.37.3l.2.14 8.6 8.07-9.19 16.56-2.4 4.33c-.75 1.35-.32 3.08.96 3.86.49.3 1.03.42 1.55.38.85-.07 1.65-.56 2.11-1.39l12.7-22.89c.64-1.16.42-2.64-.53-3.54l-7.2-6.75.14-.1 2.89-2.39 7.89-6.55 13.04 5.74 5.36 2.36c.4.18.82.24 1.23.21.97-.08 1.87-.71 2.27-1.73.55-1.45-.1-3.1-1.46-3.7zm-58.67-61.19h35c3.31 0 6-2.69 6-6s-2.69-6-6-6h-35c-3.31 0-6 2.69-6 6s2.69 6 6 6zm0-10h35c2.21 0 4 1.79 4 4s-1.79 4-4 4h-35c-2.21 0-4-1.79-4-4s1.8-4 4-4z"/></svg>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a"><stop offset="0" stop-color="#ccfbff"/><stop offset="1" stop-color="#c9e4ff"/></linearGradient><linearGradient id="b" gradientTransform="matrix(1 0 0 -1 0 320)" gradientUnits="userSpaceOnUse" x1="6.5576" x2="120.5576" xlink:href="#a" y1="318.3719" y2="152.8721"/><linearGradient id="c" gradientTransform="matrix(1 0 0 -1 0 320)" gradientUnits="userSpaceOnUse" x1="37.205" x2="151.205" xlink:href="#a" y1="339.4831" y2="173.9827"/><linearGradient id="d"><stop offset="0" stop-color="#00c8d7"/><stop offset="1" stop-color="#0a84ff"/></linearGradient><linearGradient id="e" gradientTransform="matrix(1 0 0 -1 0 320)" gradientUnits="userSpaceOnUse" x1="-51.3427" x2="242.3216" xlink:href="#d" y1="411.209" y2="56.9062"/><linearGradient id="f" gradientTransform="matrix(1 0 0 -1 0 320)" gradientUnits="userSpaceOnUse" x1="98.7014" x2="116.0054" xlink:href="#d" y1="238.5525" y2="212.9205"/><linearGradient id="g" gradientTransform="matrix(1 0 0 -1 0 320)" gradientUnits="userSpaceOnUse" x1="70.9844" x2="164.4848" xlink:href="#d" y1="291.4737" y2="152.9739"/><linearGradient id="h" gradientTransform="matrix(1 0 0 -1 0 320)" gradientUnits="userSpaceOnUse" x1="53.6667" x2="192.6669" xlink:href="#a" y1="337.889" y2="159.389"/><linearGradient id="i" gradientTransform="matrix(1 0 0 -1 0 320)" gradientUnits="userSpaceOnUse" x1="16.7153" x2="201.7151" xlink:href="#d" y1="374.8648" y2="156.3646"/><g fill="#eaeaee"><path d="m174.2 162.1c16.4-3.1 26.8-7.5 26.8-12.5 0-9.3-35.7-16.8-79.8-16.8s-79.8 7.5-79.8 16.8c0 7.8 25.2 14.3 59.3 16.2-1.5 1.2-2.3 2.5-2.3 3.8 0 6.5 19.1 11.7 42.8 11.7s42.8-5.3 42.8-11.7c-.1-2.8-3.7-5.4-9.8-7.5z"/><ellipse cx="203.2" cy="165.4" rx="12.3" ry="4"/><ellipse cx="78.9" cy="171.1" rx="9.5" ry="3.3"/><ellipse cx="207.9" cy="156.9" rx="4.8" ry="2"/><path d="m53.6 93.2h123.4c.6 0 1.1-.5 1.1-1.1s-.5-1.1-1.1-1.1h-123.4c-.6 0-1.1.5-1.1 1.1s.5 1.1 1.1 1.1zm16.7-5.6h30.9c.3 0 .6-.3.6-.6s-.3-.6-.6-.6h-30.9c-.3 0-.6.3-.6.6s.3.6.6.6zm-38.9 10.5h13.4c.3 0 .6-.3.6-.6s-.3-.6-.6-.6h-13.4c-.3 0-.6.3-.6.6s.3.6.6.6zm22.3-1.1c-.3 0-.6.3-.6.6s.3.6.6.6h3.3c.3 0 .6-.3.6-.6s-.3-.6-.6-.6zm123.1.5c0 .3.3.6.6.6h3.3c.3 0 .6-.3.6-.6s-.3-.5-.6-.5h-3.3c-.3 0-.6.2-.6.5zm8.4.6h1.1c.3 0 .6-.3.6-.6s-.3-.6-.6-.6h-1.1c-.3 0-.6.3-.6.6s.3.6.6.6zm-122.6-1.1h-1.1c-.3 0-.6.3-.6.6s.3.6.6.6h1.1c.3 0 .6-.3.6-.6 0-.4-.3-.6-.6-.6zm133.7 1.1h13.4c.3 0 .6-.3.6-.6s-.3-.5-.6-.5h-13.4c-.3 0-.6.3-.6.6s.3.5.6.5zm-27.3-.6c0-.3-.3-.6-.6-.6h-13.4c-.3 0-.6.3-.6.6s.3.6.6.6h13.4c.4 0 .6-.3.6-.6zm52.5 29.2h-56.7c-.6 0-1.1.5-1.1 1.1s.5 1.1 1.1 1.1h56.7c.6 0 1.1-.5 1.1-1.1s-.5-1.1-1.1-1.1zm-162 0h-50.6c-.6 0-1.1.5-1.1 1.1s.5 1.1 1.1 1.1h50.7c.6 0 1.1-.5 1.1-1.1s-.6-1.1-1.2-1.1z"/></g><path d="m163.4 155.3-12.3-103.2c-.3-2.1-2-3.7-4.2-3.7h-62c-2.4 0-4.1 1.8-4.6 4l-19.3 92.3c-.3 1.2.1 2.5.9 3.5s2 1.5 3.3 1.5h27.1l.8 6.5c.3 2.1 2 3.7 4.2 3.7h62c1.2 0 2.3-.5 3.1-1.4s1.1-2 1-3.2z" fill="#fff"/><path d="m94.7 144.1-10-83.1-17.3 83.1z" fill="url(#b)"/><path d="m86.9 54.2 12 100.2h59l-11.9-100.2z" fill="url(#c)"/><path d="m161.1 155.7-12.3-103.2c-.1-.8-.7-1.3-1.5-1.3h-62c-.9 0-1.6.5-1.8 1.3l-19.4 92.9c-.1.4 0 .9.3 1.3.3.3.7.6 1.2.6h29.4l1.1 8.9c.1.8.7 1.3 1.5 1.3h62c.4 0 .8-.2 1.1-.5.3-.5.5-.9.4-1.3zm-79.3-80.4 8 68.9h-22.4c0-.1 14.4-68.9 14.4-68.9zm17.1 79.1-12-100.2h59l12 100.2z" fill="url(#e)"/><path d="m91 57.7 11.3 92.5h51.9l-11.3-92.5z" fill="#f9f9fa"/><path d="m108.3 91.1c-2.2-.1-4 1.6-4.2 3.8-.1 2.3 1.5 4.2 3.6 4.4.8.1 1.5-.1 2.1-.5.4-1.5 1-3.6 1.6-5.6-.6-1.2-1.8-2-3.1-2.1z" fill="url(#f)"/><path d="m143 105.5-11.9-5.2c-.5-.2-1.2-.2-1.6.2l-5.8 4.8-.1-.1-6.8-6.2 10.4-10.3c.6-.6.7-1.7.1-2.4s-1.6-.7-2.3-.1l-10.1 10c1.2-4.1 3-10.4 4.3-14.8.3-.9-.2-1.8-1.1-2.1-.8-.3-1.7.2-2 1.1 0 0-.7 2.5-1.7 5.6-.4 1.2-.7 2.5-1.1 3.9-2.9 9.9-2.8 10.1-2.8 10.6 0 .3.2.6.3.8l.1.1c.2.3.4.6.6.8l8.2 7.5.2.2.1.1 5.2 4.8-5.5 9.9-1.4 2.6c-.4.8-.2 1.8.6 2.3.3.2.6.3.9.2.5 0 1-.3 1.3-.8l7.6-13.7c.4-.7.3-1.6-.3-2.1l-4.3-4.1.1-.1 1.7-1.4 4.7-3.9 7.8 3.4 3.2 1.4c.2.1.5.1.7.1.6 0 1.1-.4 1.4-1 .5-.8.2-1.8-.7-2.1z" fill="url(#g)"/><path d="m139.2 30h-27.2c-2.4-4.4-8.4-14-15.9-15.4-10-1.9-12 8-12 8s-6.6-17.2-23.4-15c-18.5 2.5-10.2 21.7-10 22.4h-28.3c-.7 0-1.3.6-1.3 1.3s.6 1.3 1.3 1.3h116.8c.7 0 1.3-.6 1.3-1.3s-.6-1.3-1.3-1.3z" fill="#fff"/><path d="m138.4 27.6h-7.3c-.4 0-.7-.3-.7-.7s.3-.7.7-.7h7.3c.4 0 .7.3.7.7s-.4.7-.7.7zm-19.1 0h-1.3c-.4 0-.7-.3-.7-.7s.3-.7.7-.7h1.3c.4 0 .7.3.7.7-.1.4-.4.7-.7.7zm-68.1-.8h-2.1c-.4 0-.7-.3-.7-.7s.3-.7.7-.7h1.1c-.1-.2-.2-.5-.3-.8s.1-.7.4-.8.7.1.8.4c.3 1 .6 1.6.6 1.6.1.2.1.4 0 .6 0 .3-.2.4-.5.4zm-12.6 0h-15.7c-.4 0-.7-.3-.7-.7s.3-.7.7-.7h15.7c.4 0 .7.3.7.7s-.3.7-.7.7zm74.6 0c-.2 0-.5-.1-.6-.3-.4-.8-1.1-1.9-2-3.3-.2-.3-.1-.7.2-.9s.7-.1.9.2c.9 1.4 1.7 2.6 2.1 3.4.2.3.1.7-.3.9-.1-.1-.2 0-.3 0zm-63.8-6.8c-.3 0-.6-.2-.6-.6-.1-.4-.1-.9-.1-1.3s.2-.7.6-.7.7.2.7.6.1.9.1 1.3c0 .3-.3.7-.7.7zm34.1-2.9c-.2 0-.5-.1-.6-.3-.2-.3-.4-.7-.6-1.1-.2-.3-.1-.7.2-.9s.7-.1.9.2c.2.4.5.8.7 1.2.2.3.1.7-.3.9-.1 0-.2 0-.3 0zm20.8-1.6c-.2 0-.3-.1-.4-.2-2.5-2.1-5-3.5-7.4-3.9-2.4-.5-4.5-.2-6.3.7-.3.2-.7 0-.9-.3s0-.7.3-.9c2-1 4.4-1.3 7.1-.8s5.4 1.9 8.1 4.2c.3.2.3.6.1.9-.2.2-.4.3-.6.3zm-24.5-3.7c-.2 0-.4-.1-.5-.2-.9-1-1.8-1.9-2.7-2.7-.3-.2-.3-.6-.1-.9s.6-.3.9-.1c1 .8 2 1.8 2.9 2.8.2.3.2.7-.1.9-.1.1-.3.2-.4.2zm-27-3.9c-.2 0-.4-.1-.5-.2-.3-.3-.3-.7 0-.9 2.1-1.9 5.1-3.1 8.8-3.6 2.3-.3 4.5-.3 6.6.1.4.1.6.4.5.8s-.4.6-.8.5c-2-.3-4.1-.4-6.2-.1-3.5.5-6.2 1.6-8.1 3.3 0 .1-.2.1-.3.1z" fill="#eaeaee"/><path d="m233.4 63.7h-15.4c-1.3-2.5-4.7-7.8-8.9-8.6-5.6-1.1-6.7 4.5-6.7 4.5s-3.7-9.6-13.1-8.4c-10.5 1.4-5.6 12.5-5.6 12.5h-15.8.5-.2c-.7 0-1.3.6-1.3 1.3s.6 1.3 1.3 1.3h65.2c.7 0 1.3-.6 1.3-1.3s-.6-1.3-1.3-1.3z" fill="#fff"/><path d="m184.2 61.9h-15.8c-.4 0-.7-.3-.7-.7s.3-.7.7-.7h15.8c.4 0 .7.3.7.7s-.3.7-.7.7zm48.6-.2h-.6c-.4 0-.7-.3-.7-.7s.3-.7.7-.7h.6c.4 0 .7.3.7.7s-.3.7-.7.7zm-5.8 0h-4c-.4 0-.7-.3-.7-.7s.3-.7.7-.7h3.9c.4 0 .7.3.7.7s-.3.7-.6.7zm-24.2-3.9c-.3 0-.5-.2-.6-.4s-.1-.4.2-1.1c.6-1.8 2.3-4.5 5.8-4.5.5 0 1 0 1.5.1 2 .4 3.9 1.5 5.9 3.4.3.3.3.7 0 .9-.3.3-.7.3-.9 0-1.8-1.7-3.5-2.7-5.2-3-.4-.1-.8-.1-1.2-.1-3.8 0-4.6 3.9-4.7 4.1-.2.4-.5.6-.8.6zm-18.3-5.9c-.1 0-.3-.1-.4-.2-.3-.2-.3-.6-.1-.9.9-1 2.1-1.8 3.6-2.3.3-.1.7.1.8.4s-.1.7-.4.8c-1.3.4-2.3 1-3 1.9-.1.2-.3.3-.5.3zm9.8-2.2c-.1 0-.1 0-.2 0-.4-.1-.8-.2-1.2-.3s-.6-.4-.6-.7.4-.6.7-.6c.5.1.9.2 1.4.3.3.1.6.5.5.8 0 .3-.3.5-.6.5z" fill="#eaeaee"/><path d="m128.8 68.2h-21c-1.7 0-3-1.3-3-3 0-1.6 1.3-3 3-3h21c1.6 0 3 1.3 3 3 0 1.6-1.3 3-3 3z" fill="url(#h)"/><path d="m128.8 68.8h-21c-2 0-3.6-1.6-3.6-3.6s1.6-3.6 3.6-3.6h21c2 0 3.6 1.6 3.6 3.6 0 1.9-1.6 3.6-3.6 3.6zm-21-6c-1.3 0-2.4 1.1-2.4 2.4s1.1 2.4 2.4 2.4h21c1.3 0 2.4-1.1 2.4-2.4s-1.1-2.4-2.4-2.4z" fill="url(#i)"/></svg>
--- a/browser/components/extensions/test/browser/browser.ini
+++ b/browser/components/extensions/test/browser/browser.ini
@@ -58,24 +58,21 @@ skip-if = os == 'linux' && debug # Bug 1
 [browser_ext_browserAction_contextMenu.js]
 # bug 1369197
 skip-if = os == 'linux'
 [browser_ext_browserAction_disabled.js]
 [browser_ext_browserAction_incognito.js]
 [browser_ext_browserAction_pageAction_icon.js]
 [browser_ext_browserAction_pageAction_icon_permissions.js]
 [browser_ext_browserAction_popup.js]
-skip-if =
-  (debug && os == 'linux' && bits == 32) || # Bug 1313372
-  fission && debug # Causes shutdown crashes under Fission.
+skip-if = debug && os == 'linux' && bits == 32# Bug 1313372
 [browser_ext_browserAction_popup_port.js]
 [browser_ext_browserAction_popup_preload.js]
 skip-if = (os == 'win' && !debug) || (verify && debug && (os == 'mac')) # bug 1352668
 [browser_ext_browserAction_popup_resize.js]
-skip-if = fission && debug # Causes shutdown crashes under Fission.
 [browser_ext_browserAction_popup_resize_bottom.js]
 skip-if = debug # Bug 1522164
 [browser_ext_browserAction_simple.js]
 [browser_ext_browserAction_telemetry.js]
 [browser_ext_browserAction_theme_icons.js]
 skip-if = (os == 'mac') # macosx1014 due to 1479256
 [browser_ext_browsingData_formData.js]
 [browser_ext_browsingData_history.js]
--- a/browser/themes/shared/urlbar-searchbar.inc.css
+++ b/browser/themes/shared/urlbar-searchbar.inc.css
@@ -130,17 +130,17 @@
 
 #urlbar.megabar > #urlbar-input-container > #urlbar-search-icon {
   width: calc(16px + 2 * @identityBoxPaddingInline@);
   margin-inline-end: @identityBoxMarginInlineEnd@;
   background-image: url(chrome://browser/skin/search-glass.svg);
   background-repeat: no-repeat;
   background-position: center;
   -moz-context-properties: fill, fill-opacity;
-  fill: var(--lwt-toolbarbutton-icon-fill, currentColor);
+  fill: var(--lwt-toolbarbutton-icon-fill, var(--toolbar-color));
   fill-opacity: var(--toolbarbutton-icon-fill-opacity);
 }
 
 /**
  * The urlbar background is a separate element so we can animate it
  * independently from the content. It's positioned absolutely and stretched to
  * the bounds of the urlbar.
  */
@@ -202,16 +202,20 @@
 }
 
 #urlbar[breakout][breakout-extend] > #urlbar-input-container {
   height: var(--urlbar-toolbar-height);
   padding-block: calc((var(--urlbar-toolbar-height) - var(--urlbar-height)) / 2);
   padding-inline: @urlbarMarginInline@;
 }
 
+#urlbar[breakout][breakout-extend] > #urlbar-input-container > #urlbar-search-icon {
+  fill: currentColor;
+}
+
 @keyframes urlbar-grow {
   0% {
     transform: scaleX(.98) scaleY(.9);
   }
   100% {
     transform: scale(1.0);
   }
 }
--- a/caps/OriginAttributes.cpp
+++ b/caps/OriginAttributes.cpp
@@ -99,24 +99,29 @@ void OriginAttributes::SetFirstPartyDoma
       mFirstPartyDomain = NS_ConvertUTF8toUTF16(publicSuffix);
     }
     return;
   }
 }
 
 void OriginAttributes::SetFirstPartyDomain(const bool aIsTopLevelDocument,
                                            const nsACString& aDomain) {
+  SetFirstPartyDomain(aIsTopLevelDocument, NS_ConvertUTF8toUTF16(aDomain));
+}
+
+void OriginAttributes::SetFirstPartyDomain(const bool aIsTopLevelDocument,
+                                           const nsAString& aDomain) {
   bool isFirstPartyEnabled = IsFirstPartyEnabled();
 
   // If the pref is off or this is not a top level load, bail out.
   if (!isFirstPartyEnabled || !aIsTopLevelDocument) {
     return;
   }
 
-  mFirstPartyDomain = NS_ConvertUTF8toUTF16(aDomain);
+  mFirstPartyDomain = aDomain;
 }
 
 void OriginAttributes::CreateSuffix(nsACString& aStr) const {
   URLParams params;
   nsAutoString value;
 
   //
   // Important: While serializing any string-valued attributes, perform a
--- a/caps/OriginAttributes.h
+++ b/caps/OriginAttributes.h
@@ -24,16 +24,18 @@ class OriginAttributes : public dom::Ori
 
   explicit OriginAttributes(const OriginAttributesDictionary& aOther)
       : OriginAttributesDictionary(aOther) {}
 
   void SetFirstPartyDomain(const bool aIsTopLevelDocument, nsIURI* aURI,
                            bool aForced = false);
   void SetFirstPartyDomain(const bool aIsTopLevelDocument,
                            const nsACString& aDomain);
+  void SetFirstPartyDomain(const bool aIsTopLevelDocument,
+                           const nsAString& aDomain);
 
   enum {
     STRIP_FIRST_PARTY_DOMAIN = 0x01,
     STRIP_USER_CONTEXT_ID = 0x02,
   };
 
   inline void StripAttributes(uint32_t aFlags) {
     if (aFlags & STRIP_FIRST_PARTY_DOMAIN) {
--- a/devtools/client/framework/test/browser_target_parents.js
+++ b/devtools/client/framework/test/browser_target_parents.js
@@ -37,25 +37,51 @@ add_task(async function() {
   const transport = DebuggerServer.connectPipe();
   const client = new DebuggerClient(transport);
   await client.connect();
 
   const mainRoot = client.mainRoot;
 
   const { processes } = await mainRoot.listProcesses();
 
+  // Assert that concurrent calls to getTarget resolves the same target and that it is already attached
+  // We that, we were chasing a precise race, where a second call to ProcessDescriptor.getTarget()
+  // happens between the instantiation of ContentProcessTarget and its call to attach() from getTarget
+  // function.
   await Promise.all(
     processes.map(async processDescriptor => {
-      const process = await processDescriptor.getTarget();
-
-      is(
-        process.descriptorFront,
-        processDescriptor,
-        "Got the correct descriptorFront from the process target."
-      );
+      const promises = [];
+      const concurrentCalls = 10;
+      for (let i = 0; i < concurrentCalls; i++) {
+        const targetPromise = processDescriptor.getTarget();
+        // Every odd runs, wait for a tick to introduce some more randomness
+        if (i % 2 == 0) {
+          await wait(0);
+        }
+        promises.push(
+          targetPromise.then(target => {
+            is(
+              target.descriptorFront,
+              processDescriptor,
+              "Got the correct descriptorFront from the process target."
+            );
+            // activeConsole is one of the only attribute to assess that a Content Process Target is attached
+            ok(target.activeConsole, "The target is attached");
+            return target;
+          })
+        );
+      }
+      const targets = await Promise.all(promises);
+      for (let i = 1; i < concurrentCalls; i++) {
+        is(
+          targets[0],
+          targets[i],
+          "All the targets returned by concurrent calls to getTarget are the same"
+        );
+      }
     })
   );
 
   await client.close();
 });
 
 // Test against Frame targets
 add_task(async function() {
@@ -68,25 +94,49 @@ add_task(async function() {
   const transport = DebuggerServer.connectPipe();
   const client = new DebuggerClient(transport);
   await client.connect();
 
   const mainRoot = client.mainRoot;
 
   const mainProcess = await mainRoot.getMainProcess();
   const { frames } = await mainProcess.listRemoteFrames();
+
+  // Assert that concurrent calls to getTarget resolves the same target and that it is already attached
   await Promise.all(
-    frames.map(async frameDescriptorFront => {
-      const frameTargetFront = await frameDescriptorFront.getTarget();
-
-      is(
-        frameTargetFront.descriptorFront,
-        frameDescriptorFront,
-        "Got the correct descriptorFront from the frame target."
-      );
+    frames.map(async frameDescriptor => {
+      const promises = [];
+      const concurrentCalls = 10;
+      for (let i = 0; i < concurrentCalls; i++) {
+        const targetPromise = frameDescriptor.getTarget();
+        // Every odd runs, wait for a tick to introduce some more randomness
+        if (i % 2 == 0) {
+          await wait(0);
+        }
+        promises.push(
+          targetPromise.then(target => {
+            is(
+              target.descriptorFront,
+              frameDescriptor,
+              "Got the correct descriptorFront from the frame target."
+            );
+            // traits is one attribute to assert that a Frame Target is attached
+            ok(target.traits, "The target is attached");
+            return target;
+          })
+        );
+      }
+      const targets = await Promise.all(promises);
+      for (let i = 1; i < concurrentCalls; i++) {
+        is(
+          targets[0],
+          targets[i],
+          "All the targets returned by concurrent calls to getTarget are the same"
+        );
+      }
     })
   );
 
   await client.close();
 });
 
 // Test against Webextension targets
 add_task(async function() {
--- a/devtools/server/tests/unit/test_protocol_onFront.js
+++ b/devtools/server/tests/unit/test_protocol_onFront.js
@@ -7,24 +7,32 @@
  * Test Front.onFront method.
  */
 
 const protocol = require("devtools/shared/protocol");
 const { RetVal } = protocol;
 
 const childSpec = protocol.generateActorSpec({
   typeName: "childActor",
+
+  methods: {
+    release: {
+      release: true,
+    },
+  },
 });
 
 const ChildActor = protocol.ActorClassWithSpec(childSpec, {
   initialize(conn, id) {
     protocol.Actor.prototype.initialize.call(this, conn);
     this.childID = id;
   },
 
+  release() {},
+
   form: function() {
     return {
       actor: this.actorID,
       childID: this.childID,
       foo: "bar",
     };
   },
 });
@@ -90,24 +98,25 @@ add_task(async function run_test() {
 
   const trace = connectPipeTracing();
   const client = new DebuggerClient(trace);
   await client.connect();
 
   const rootFront = new RootFront(client);
 
   const fronts = [];
-  rootFront.onFront("childActor", front => {
+  const listener = front => {
     equal(
       front.foo,
       "bar",
       "Front's form is set before onFront listeners are called"
     );
     fronts.push(front);
-  });
+  };
+  rootFront.onFront("childActor", listener);
 
   const firstChild = await rootFront.createChild();
   ok(
     firstChild instanceof ChildFront,
     "createChild returns a ChildFront instance"
   );
   equal(firstChild.childID, 0, "First child has ID=0");
 
@@ -142,11 +151,34 @@ add_task(async function run_test() {
 
   equal(
     fronts.length,
     2,
     "After a second call to createChild, two fronts are reported"
   );
   equal(fronts[1], secondChild, "And the new front is the right instance");
 
+  // Test unregistering a front listener
+  rootFront.offFront("childActor", listener);
+
+  const thirdChild = await rootFront.createChild();
+  equal(
+    fronts.length,
+    2,
+    "After calling offFront, the listener is no longer called"
+  );
+
+  // Test front destruction
+  const destroyed = [];
+  rootFront.onFrontDestroyed("childActor", front => {
+    destroyed.push(front);
+  });
+  await thirdChild.release();
+  equal(
+    destroyed.length,
+    1,
+    "After the destruction of the front, one destruction is reported"
+  );
+  equal(destroyed[0], thirdChild, "And the destroyed front is the right one");
+
   trace.close();
   await client.close();
 });
--- a/devtools/shared/fronts/descriptors/frame.js
+++ b/devtools/shared/fronts/descriptors/frame.js
@@ -38,43 +38,52 @@ class FrameDescriptorFront extends Front
     front = new BrowsingContextTargetFront(this._client, null, this);
     front.actorID = form.actor;
     front.form(form);
     this.manage(front);
     return front;
   }
 
   async getTarget() {
+    // Only return the cached Target if it is still alive.
+    // It may have been destroyed in case of navigation trigerring a load in another
+    // process.
     if (this._frameTargetFront && this._frameTargetFront.actorID) {
       return this._frameTargetFront;
     }
+    // Otherwise, ensure that we don't try to spawn more than one Target by
+    // returning the pending promise
     if (this._targetFrontPromise) {
       return this._targetFrontPromise;
     }
     this._targetFrontPromise = (async () => {
+      let target = null;
       try {
         const targetForm = await super.getTarget();
+        // getTarget uses 'json' in the specification type and this prevents converting
+        // actor exception into front exceptions
         if (targetForm.error) {
-          this._targetFrontPromise = null;
-          return null;
+          throw new Error(targetForm.error);
         }
-        this._frameTargetFront = await this._createFrameTarget(targetForm);
-        await this._frameTargetFront.attach();
-        // clear the promise if we are finished so that we can re-connect if
-        // necessary
-        this._targetFrontPromise = null;
-        return this._frameTargetFront;
+        target = await this._createFrameTarget(targetForm);
+        await target.attach();
       } catch (e) {
         // This is likely to happen if we get a lot of events which drop previous
         // frames.
         console.log(
           `Request to connect to frameDescriptor "${this.id}" failed: ${e}`
         );
-        return null;
       }
+      // Save the reference to the target only after the call to attach
+      // so that getTarget always returns the attached target in case of concurrent calls
+      this._frameTargetFront = target;
+      // clear the promise if we are finished so that we can re-connect if
+      // necessary
+      this._targetFrontPromise = null;
+      return target;
     })();
     return this._targetFrontPromise;
   }
 
   async getParentTarget() {
     if (!this.parentID) {
       return null;
     }
--- a/devtools/shared/fronts/descriptors/process.js
+++ b/devtools/shared/fronts/descriptors/process.js
@@ -50,41 +50,45 @@ class ProcessDescriptorFront extends Fro
     front.actorID = form.actor;
     front.form(form);
     front.processID = this.id;
     this.manage(front);
     return front;
   }
 
   async getTarget() {
+    // Only return the cached Target if it is still alive.
     if (this._processTargetFront && this._processTargetFront.actorID) {
       return this._processTargetFront;
     }
+    // Otherwise, ensure that we don't try to spawn more than one Target by
+    // returning the pending promise
     if (this._targetFrontPromise) {
       return this._targetFrontPromise;
     }
     this._targetFrontPromise = (async () => {
+      let targetFront = null;
       try {
         const targetForm = await super.getTarget();
-        this._processTargetFront = await this._createProcessTargetFront(
-          targetForm
-        );
-        await this._processTargetFront.attach();
-        // clear the promise if we are finished so that we can re-connect if
-        // necessary
-        this._targetFrontPromise = null;
-        return this._processTargetFront;
+        targetFront = await this._createProcessTargetFront(targetForm);
+        await targetFront.attach();
       } catch (e) {
         // This is likely to happen if we get a lot of events which drop previous
         // processes.
         console.log(
           `Request to connect to ProcessDescriptor "${this.id}" failed: ${e}`
         );
-        return null;
       }
+      // Save the reference to the target only after the call to attach
+      // so that getTarget always returns the attached target in case of concurrent calls
+      this._processTargetFront = targetFront;
+      // clear the promise if we are finished so that we can re-connect if
+      // necessary
+      this._targetFrontPromise = null;
+      return targetFront;
     })();
     return this._targetFrontPromise;
   }
 
   destroy() {
     this._processTargetFront = null;
     this._targetFrontPromise = null;
     super.destroy();
--- a/devtools/shared/protocol/Front.js
+++ b/devtools/shared/protocol/Front.js
@@ -99,30 +99,86 @@ class Front extends Pool {
     if (form) {
       front.form(form, ctx);
     }
 
     // Call listeners registered via `onFront` method
     this._frontListeners.emit(front.typeName, front);
   }
 
-  // Run callback on every front of this type that currently exists, and on every
-  // instantiation of front type in the future.
+  async unmanage(front) {
+    super.unmanage(front);
+
+    // Call listeners registered via `onFrontDestroyed` method
+    // TODO: to be implemented differently in bug 1590401.
+    this._frontListeners.emit(front.typeName + ":destroyed", front);
+  }
+
+  /**
+   * Register an event listener that will be called on every front of this type
+   * that currently exists, and on every instantiation of front type in the future.
+   *
+   * TODO: A special typeName is use to implement onFrontDestroyed:
+   * `${typeName}:destroyed`. This should be cleaned up by bug 1590401.
+   *
+   * @param String typeName
+   *   Actor type to watch.
+   * @param Function callback
+   *   Function that will process the event.
+   */
   onFront(typeName, callback) {
     // First fire the callback on already instantiated fronts
     for (const front of this.poolChildren()) {
       if (front.typeName == typeName) {
         callback(front);
       }
     }
     // Then register the callback for fronts instantiated in the future
     this._frontListeners.on(typeName, callback);
   }
 
   /**
+   * Unregister an event listener which was set via `Front.onFront`.
+   *
+   * @param String typeName
+   *   Actor type to stop watching.
+   * @param Function callback
+   *   Function that was processing the event.
+   */
+  offFront(typeName, callback) {
+    this._frontListeners.off(typeName, callback);
+  }
+
+  /**
+   * Register an event listener that will be called evertype a front of this type
+   * is destroyed.
+   *
+   * @param String typeName
+   *   Actor type to watch.
+   * @param Function callback
+   *   Function that will process the event.
+   */
+  onFrontDestroyed(typeName, callback) {
+    // TODO: to be implemented differently in bug 1590401.
+    this.onFront(typeName + ":destroyed", callback);
+  }
+
+  /**
+   * Unregister an event listener which was set via `Front.onFrontDestroyed`.
+   *
+   * @param String typeName
+   *   Actor type to stop watching.
+   * @param Function callback
+   *   Function that was processing the event.
+   */
+  offFrontDestroyed(typeName, callback) {
+    this.offFront(typeName + ":destroyed", callback);
+  }
+
+  /**
    * Register an event listener that will be called immediately on packer receival.
    * The given callback is going to be called before emitting the event via EventEmitter
    * API on the Front. Event emitting will be delayed if the callback is async.
    * Only one such listener can be registered per type of event.
    *
    * @param String type
    *   Event emitted by the actor to intercept.
    * @param Function callback
--- a/docshell/base/CanonicalBrowsingContext.cpp
+++ b/docshell/base/CanonicalBrowsingContext.cpp
@@ -304,20 +304,26 @@ void CanonicalBrowsingContext::PendingRe
       [wasRemote, resetInFlightId](mozilla::ipc::ResponseRejectReason aReason) {
         if (!wasRemote) {
           resetInFlightId();
         }
       });
 
   // FIXME: We should get the correct principal for the to-be-created window so
   // we can avoid creating unnecessary extra windows in the new process.
+  OriginAttributes attrs = embedderBrowser->OriginAttributesRef();
+  RefPtr<nsIPrincipal> principal = embedderBrowser->GetContentPrincipal();
+  if (principal) {
+    attrs.SetFirstPartyDomain(
+        true, principal->OriginAttributesRef().mFirstPartyDomain);
+  }
+
   nsCOMPtr<nsIPrincipal> initialPrincipal =
-      NullPrincipal::CreateWithInheritedAttributes(
-          embedderBrowser->OriginAttributesRef(),
-          /* isFirstParty */ false);
+      NullPrincipal::CreateWithInheritedAttributes(attrs,
+                                                   /* isFirstParty */ false);
   WindowGlobalInit windowInit =
       WindowGlobalActor::AboutBlankInitializer(target, initialPrincipal);
 
   // Actually create the new BrowserParent actor and finish initialization of
   // our new BrowserBridgeParent.
   nsresult rv = bridge->InitWithProcess(aContentParent, EmptyString(),
                                         windowInit, chromeFlags, tabId);
   if (NS_WARN_IF(NS_FAILED(rv))) {
--- a/dom/base/AutocompleteFieldList.h
+++ b/dom/base/AutocompleteFieldList.h
@@ -56,19 +56,16 @@
 //-----------------------------------------------------
 // Unsupported list
 
 // Unsupported field names
 AUTOCOMPLETE_UNSUPPORTED_FIELD_NAME(HONORIFIX_PREFIX, "honorifix-prefix")
 AUTOCOMPLETE_UNSUPPORTED_FIELD_NAME(HONORIFIX_SUFFIX, "honorifix-suffix")
 AUTOCOMPLETE_UNSUPPORTED_FIELD_NAME(NICKNAME, "nickname")
 AUTOCOMPLETE_UNSUPPORTED_FIELD_NAME(ORGANIZATION_TITLE, "organization-title")
-AUTOCOMPLETE_UNSUPPORTED_FIELD_NAME(USERNAME, "username")
-AUTOCOMPLETE_UNSUPPORTED_FIELD_NAME(NEW_PASSWORD, "new-password")
-AUTOCOMPLETE_UNSUPPORTED_FIELD_NAME(CURRENT_PASSWORD, "current-password")
 AUTOCOMPLETE_UNSUPPORTED_FIELD_NAME(ADDRESS_LEVEL4, "address-level4")
 AUTOCOMPLETE_UNSUPPORTED_FIELD_NAME(CC_GIVEN_NAME, "cc-given-name")
 AUTOCOMPLETE_UNSUPPORTED_FIELD_NAME(CC_ADDITIONAL_NAME, "cc-additional-name")
 AUTOCOMPLETE_UNSUPPORTED_FIELD_NAME(CC_FAMILY_NAME, "cc-family-name")
 AUTOCOMPLETE_UNSUPPORTED_FIELD_NAME(CC_CSC, "cc-csc")
 AUTOCOMPLETE_UNSUPPORTED_FIELD_NAME(CC_TYPE, "cc-type")
 AUTOCOMPLETE_UNSUPPORTED_FIELD_NAME(TRANSACTION_CURRENCY,
                                     "transaction-currency")
--- a/dom/base/ThirdPartyUtil.cpp
+++ b/dom/base/ThirdPartyUtil.cpp
@@ -209,17 +209,19 @@ ThirdPartyUtil::IsThirdPartyWindow(mozID
   // Ignore about:blank URIs here since they have no domain and attempting to
   // compare against them will fail.
   if (aURI && !NS_IsAboutBlank(aURI)) {
     nsCOMPtr<nsIPrincipal> prin;
     nsresult rv = GetPrincipalFromWindow(aWindow, getter_AddRefs(prin));
     NS_ENSURE_SUCCESS(rv, rv);
     // Determine whether aURI is foreign with respect to the current principal.
     rv = prin->IsThirdPartyURI(aURI, &result);
-    NS_ENSURE_SUCCESS(rv, rv);
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
 
     if (result) {
       *aResult = true;
       return NS_OK;
     }
   }
 
   nsPIDOMWindowOuter* current = nsPIDOMWindowOuter::From(aWindow);
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -2519,19 +2519,21 @@ bool nsFrameLoader::TryRemoteBrowserInte
   }
 
   nsCOMPtr<nsIDocShell> parentDocShell = parentWin->GetDocShell();
   if (!parentDocShell) {
     return false;
   }
 
   RefPtr<ContentParent> openerContentParent;
+  RefPtr<nsIPrincipal> openerContentPrincipal;
   RefPtr<BrowserParent> sameTabGroupAs;
   if (auto* host = BrowserHost::GetFrom(parentDocShell->GetOpener())) {
     openerContentParent = host->GetContentParent();
+    openerContentPrincipal = host->GetActor()->GetContentPrincipal();
   }
 
   // <iframe mozbrowser> gets to skip these checks.
   // iframes for JS plugins also get to skip these checks. We control the URL
   // that gets loaded, but the load is triggered from the document containing
   // the plugin.
   // out of process iframes also get to skip this check.
   if (!OwnerIsMozBrowserFrame() && !XRE_IsContentProcess()) {
@@ -2599,16 +2601,22 @@ bool nsFrameLoader::TryRemoteBrowserInte
   }
 
   AUTO_PROFILER_LABEL("nsFrameLoader::TryRemoteBrowser:Create", OTHER);
 
   MutableTabContext context;
   nsresult rv = GetNewTabContext(&context);
   NS_ENSURE_SUCCESS(rv, false);
 
+  // We need to propagate the first party domain if the opener is presented.
+  if (openerContentPrincipal) {
+    context.SetFirstPartyDomainAttributes(
+        openerContentPrincipal->OriginAttributesRef().mFirstPartyDomain);
+  }
+
   uint64_t nextRemoteTabId = 0;
   if (mOwnerContent) {
     nsAutoString nextBrowserParentIdAttr;
     mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::nextRemoteTabId,
                            nextBrowserParentIdAttr);
     nextRemoteTabId = strtoull(
         NS_ConvertUTF16toUTF8(nextBrowserParentIdAttr).get(), nullptr, 10);
 
--- a/dom/base/test/mochitest.ini
+++ b/dom/base/test/mochitest.ini
@@ -593,17 +593,16 @@ skip-if = fission # Times out in weird w
 support-files = test_bug1037687_subframe.html
 [test_bug1043106.html]
 [test_bug1057176.html]
 [test_bug1060938.html]
 [test_bug1064481.html]
 [test_bug1070015.html]
 [test_bug1075702.html]
 [test_bug1091883.html]
-skip-if = fission
 [test_bug1100912.html]
 support-files = file_bug1100912.html
 [test_bug1101364.html]
 [test_bug1118689.html]
 [test_bug1126851.html]
 [test_bug1163743.html]
 [test_bug1165501.html]
 [test_bug1187157.html]
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -6821,36 +6821,16 @@ void HTMLMediaElement::DispatchEncrypted
   asyncDispatcher->PostDOMEvent();
 }
 
 bool HTMLMediaElement::IsEventAttributeNameInternal(nsAtom* aName) {
   return aName == nsGkAtoms::onencrypted ||
          nsGenericHTMLElement::IsEventAttributeNameInternal(aName);
 }
 
-already_AddRefed<nsIPrincipal> HTMLMediaElement::GetTopLevelPrincipal() {
-  RefPtr<nsIPrincipal> principal;
-  nsCOMPtr<nsPIDOMWindowInner> window = OwnerDoc()->GetInnerWindow();
-  if (!window) {
-    return nullptr;
-  }
-  // XXXkhuey better hope we always have an outer ...
-  nsCOMPtr<nsPIDOMWindowOuter> top =
-      window->GetOuterWindow()->GetInProcessTop();
-  if (!top) {
-    return nullptr;
-  }
-  Document* doc = top->GetExtantDoc();
-  if (!doc) {
-    return nullptr;
-  }
-  principal = doc->NodePrincipal();
-  return principal.forget();
-}
-
 void HTMLMediaElement::NotifyWaitingForKey() {
   LOG(LogLevel::Debug, ("%p, NotifyWaitingForKey()", this));
 
   // http://w3c.github.io/encrypted-media/#wait-for-key
   // 7.3.4 Queue a "waitingforkey" Event
   // 1. Let the media element be the specified HTMLMediaElement object.
   // 2. If the media element's waiting for key value is true, abort these steps.
   if (mWaitingForKey == NOT_WAITING_FOR_KEY) {
--- a/dom/html/HTMLMediaElement.h
+++ b/dom/html/HTMLMediaElement.h
@@ -598,20 +598,16 @@ class HTMLMediaElement : public nsGeneri
   mozilla::dom::EventHandlerNonNull* GetOnwaitingforkey();
   void SetOnwaitingforkey(mozilla::dom::EventHandlerNonNull* aCallback);
 
   void DispatchEncrypted(const nsTArray<uint8_t>& aInitData,
                          const nsAString& aInitDataType) override;
 
   bool IsEventAttributeNameInternal(nsAtom* aName) override;
 
-  // Returns the principal of the "top level" document; the origin displayed
-  // in the URL bar of the browser window.
-  already_AddRefed<nsIPrincipal> GetTopLevelPrincipal();
-
   bool ContainsRestrictedContent();
 
   void NotifyWaitingForKey() override;
 
   already_AddRefed<DOMMediaStream> CaptureAudio(ErrorResult& aRv,
                                                 MediaTrackGraph* aGraph);
 
   already_AddRefed<DOMMediaStream> MozCaptureStream(ErrorResult& aRv);
--- a/dom/html/test/forms/test_autocomplete.html
+++ b/dom/html/test/forms/test_autocomplete.html
@@ -19,20 +19,21 @@ var values = [
 
   // One token
   ["on", "on"],
   ["On", "on"],
   ["off", "off"],
   ["OFF", "off"],
   ["name", "name"],
   [" name ", "name"],
-  ["username", ""],
-  [" username ", ""],
+  ["username", "username"],
+  [" username ", "username"],
   ["cc-csc", ""],
   ["language", ""],
+  [" language ", ""],
   ["tel-extension", ""],
   ["foobar", ""],
   ["section-blue", ""],
 
   // Two tokens
   ["on off", ""],
   ["off on", ""],
   ["username tel", ""],
--- a/dom/html/test/forms/test_autocompleteinfo.html
+++ b/dom/html/test/forms/test_autocompleteinfo.html
@@ -27,23 +27,24 @@ var values = [
   ["", {}, ""],
 
   // One token
   ["on", {fieldName: "on" }, "on"],
   ["On", {fieldName: "on" }, "on"],
   ["off", {fieldName: "off", canAutomaticallyPersist: false}, "off" ],
   ["name", {fieldName: "name" }, "name"],
   [" name ", {fieldName: "name" }, "name"],
-  ["username", {fieldName: "username"}, ""],
-  [" username ", {fieldName: "username"}, ""],
-  ["current-password", {fieldName: "current-password", canAutomaticallyPersist: false}, ""],
-  ["new-password", {fieldName: "new-password", canAutomaticallyPersist: false}, ""],
+  ["username", {fieldName: "username"}, "username"],
+  [" username ", {fieldName: "username"}, "username"],
+  ["current-password", {fieldName: "current-password", canAutomaticallyPersist: false}, "current-password"],
+  ["new-password", {fieldName: "new-password", canAutomaticallyPersist: false}, "new-password"],
   ["cc-number", {fieldName: "cc-number", canAutomaticallyPersist: false}, "cc-number"],
   ["cc-csc", {fieldName: "cc-csc", canAutomaticallyPersist: false}, ""],
   ["language", {fieldName: "language"}, ""],
+  [" language ", {fieldName: "language"}, ""],
   ["tel-extension", {fieldName: "tel-extension"}, ""],
   ["foobar", {}, ""],
   ["section-blue", {}, ""],
 
   // Two tokens
   ["on off", {}, ""],
   ["off on", {}, ""],
   ["username tel", {}, ""],
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0256dcfcf9916e817829489e6e5314ce903091a5
GIT binary patch
literal 4799
zc$}@52{@E%8^^~oiH?0gwz5QxB_hj&CbDHLS;juLnXycE%9scTsgu$~St6kj8B2>b
zQI;%Y7mYaflb9%z`D~v~Dw39Sdgpqsd7pRY{oViPzV7Q@jE>UKG63FR6bG0gVBNJH
zzz^{C^Yn2*A!N)<=>arm5_nryBfPEu$sGVH+Bqr!fR<zRe@0sp*wzue5I)BpJP;m!
z|B}V~RhE;BkLU3pmB-+?5h?I3q^q;z2dv-LSdM?Z^j>L>M9t;DX;-&Z0D#8#uyP9f
z_9^UB-mfU{=ZkRjmG<+6BRtVQu3ktNxP!BYw68bX)erIMOp%70j87384TrV(>AaE-
zCcn1GG93wk>4dZFjXfqfWVFjFJ5-59VG<qAiZ|m-aJDFK4zF!tAa^?VYFr4Ks92)G
zOu$<!-nKdsRLv_+WWK;$cdDZg1{Rhb;dr|wVJS)QtbIsnJ{g{QCXe8o2x)*+7@IK`
zHbK2KG>EtU@Z#roB(Y8td4i&*oZcKH*bSTrCUXvr!Qcr3b%$}pYwFXvG0SSR9k2W6
zxvLu|QrkR5)FVT-FI6W3mes9<V(8z+i#tv2Nl#P7X!6lnMQ|l)Bf731smq=VyL?Ra
z21g+u-?30y%~(?{2dU@G?MQpOdyYE0;X9AHox*X<f}K$&m!c)7niMA>*)MW=N7xH>
zx--t_>bD;=a9om$SX?qN<g&SV#vCb2vBB7Z^4W9^?vu45g0d4Vf(Vu9Q!BDkyhq}r
ztt2}bR1NFfh8ikEgo4-t<j`y}t*1+_Mq6gKK2>S(U{%g%2?Sp$8ZUklX$d=Hduuvl
zJh|eMIkq~{8m#8nJk_gLMI=5EM0;>c8%4gA3waY*sN<_TP`WKfmW`~!{0@%FyV(&r
zgSqSVuE0Gu?tVs?4`p!x9fQ<tB?{I8y?riuMn{&y(~wCN!M}H>S~cokv$l_!TF%YY
z8M6`OD12uUp*ovTd_}Zk;nwp$s6<=edHNwT^?+TQ8v;Yjb%iVTW;PES2&80j2HZF%
zlg+tME`xm5A_}^dX)9OHf&`xOmOM3S0TPccI@*3$8s5fUrtB~<+hTz#NUadxK2%M;
zQtr~#d_r{~`oZlRm1D~7%><YhSfnt%F<;rBFK|+;0uo*ph#V8BQcx(8`r8Huf5fKi
zE2G!T*xR4H6S${FPb~kabxKCl8Rh-e9bLFmnU3qb@`NcWR*%qmg-?;e*0Q8nbm^S8
zDU0Gw3i)zeRYcHex$IaU>WT**M6@Jn(RyPNL+)6ECl?QoYlpeZEYT%p4RDoUFI0@}
zo|Tz{_L@yGSBEL>uSqqqY8;v%Dg9Z>RU3GoN{`nlgmj=2Oy#-<*Vp17j!6ZcExs)p
zeOFv{_(8m=S1ET-A<4~Raxky+$}WhF)sSI!(Xp5(Z&IUayP8Xg83R#-QAA$0nOj_~
z?aQH9H+~EOykgD7lhc>W^LrledE9BO1;Gi)u$$anH;qaCJQS>fUPH{p{j31@038+-
zibB4cU)eJ3HIPWozZq9#4pMN5+lIaV?!b#700LS}nhjG@c#_Iso-$TRgw4GmTm(Iw
z?p3a<nvOs|1i31ZI8$3A?{v9yBdv`6!~4}TkwsSW@(1QKAGtyEk`HFmXg$}M?CUre
zrm7e{_gZa2eJx#ii7*x^sxR}^*?oLq(zF9as!K1p2=Pz1@Z=ZBQLvIu9B6JE7n;nh
z(W=lZsXrkTe*w-iojI2o9K7fmQ?d5uAQ$hLh>iY8_ujcv{n+L4-FLtuYd<~E8+*6X
zJiamm&j+)wJ>z+-O*|PmH2yH2t7ccscujuG{Dj0xbFU><xYpZy`5KhVDVe_w7%s>c
zkUIV5qh6xj$z{4V=+f&&<~7j^e^G?iRFEf^msVy%?tC)z;P=>P{-}@n8AgI{T@U_q
zmPNXv5xzfBjCLV>|D;*Hf4?+;jd9se)^j8_Sx0($Zhd<FUn9WH)8EI#0sS*>Sg!*5
zi&cE~$BE7U*jR9F@<t$BtGm6cOYB=Rq>m%~9Go5e9Hau|KH(!amsBVFYbtFIZah94
zOT~#7Lvf6b-xMzR!sz4^myw;+t6LTTfa$Z*FAH|qR|+=lkw?cNmTPx$DyAc6a<`l5
zGi4Q=F=Bm5ziT_f<j5Z!Hn1CX&c|`b@m{a&^Ff&3*g~p8L8&#|uc@#Q!e~{WL84Nj
zFy_$V$AlLN{RwR?EiD*rHEh2>ZJmiak8CJ2gzE6%9^uoks7>u-+KZbHWkfLCPODnd
z<{o`^)uwh>?<vC~Uu);y$0ZcttP~z;bjC-dc}0w4V6+b+=9Xy%RZ%}}b20T2=e#;T
zJIgDm%FuG;Y?5XKIP5}ga8=lwoZQ|yS?0sy97J~SWt<+|UaEi>C%oc*Ze%%%bf_{`
zprNuJB{m(W_*PtjI!19&sD}B@Vj$j9bkP~T5W3&*-~!~SqW%A99+^S&dm2XK?Zu^;
zm+dXfdYGIW=!6#1L>33JFF;cX#R%hKD?%y9`0O?nnpbZnOAVn|M1bABCMPW9LefM5
ztM<9d0{n@c&yDZ9&!4?HsgiKefcVyO#a6GgX(T!;6xC#V6?1@2?bcMcaZmNN-6@(e
zV0@-=ZDZUM^1YdOm;ZHhC77~D(d_2kk^kV5HyC%I9rz42qd*D*ncF|6zy?*Tdaf>-
z*-TDghs2=yUG?K-y2Nbx%u)TO?A(HjhF}yS$)xO+nxZ$)eA_d-c(Sc_ycU?D_hMAz
zQ_aNTDnuII@*$z7m8(U9AlfxsKH9w3C&lA0eMb@YaY@Pa=qVap069omYg=M56x#PZ
zJ?dPYS~t%_s?Tv26$~@fy^df{Uk#m})m-!2YMeRwARPP<aA!wpH{XAvjL8~r`+j{9
zW!G>JL*hP`2oi-eJ-OUv^zx*+>LJ+6yz4hoau}4!=x+HL+8}B)>q-R<9nT2a*=a2w
zOd35koT1bJXsKqByjwPLTPoaeur<(~M_?b7C#!T>A(^YYlSio7;$G8Kjs#k>W|>J!
zfiWUukNFX>OaD%(Wyg#m(~!M|IN?V9KH!cdX$vyPY1tW0r=(75L9tFfT8({-)!g+9
z9qwnRx@rA-_~1_MihEX)RYBS15D-1b%z}$bel|934+4JxJ@T4$dC&uRtI^>>7(>aG
z+gOduGJ~#O6#T9@crgz)t17xkp8m}fFAEWk$IlHCbyJv`gj(|m3eh%m6-Tz&PoGCs
zMVUX<ttZ?&TbuU#`8rXUUcFKms|oB)Ms<(F-FAn=%Gt6BdS^j%UYsYr`EU1PxNxuc
zk29Tg8q>@@@B0$3*sm^`+LMKd2&(yWHm8Wo1fyFL(yKV4cxa48j=Gf}s)L-@?9AtV
zOcEQRemR|v((UD&aB7VbWPdq~FrbXq80{aVA-V9l7zg8e?)UKxl=TQbYweG6Q@VU`
z@xpGyUUj3RRMdhrTMb-1Yj-SwDaiZp&*K;HLu%QS6St<ZZJ-@qM_WIN{XCa<12^WY
z+)rcK_wk#Dvi11CzJ>oVq5(gQXkRt4)quwH$y`RL64iH1{OGv$^RCp`aMqM<|53=t
zj^@XNZ0u(~2%-ANBYbqfM2PIaaf$v0mn8ohCF|OppH~Fk5G}&nf32eLIBBbfXT7BC
zZ%NwN{`{D!jcv|)Q-bt>O-;}DnVU=6=V&_}8o2}TMS%l;C~%vIz-{l}`fc^20t5g&
I8Q<^z4|g}nivR!s
--- a/dom/indexedDB/test/unit/test_marker_file.js
+++ b/dom/indexedDB/test/unit/test_marker_file.js
@@ -53,18 +53,18 @@ async function testSteps() {
   SpecialPowers.setBoolPref("dom.quotaManager.testing", true);
 
   const name = this.window ? window.location.pathname : "Splendid Test";
 
   info("Verifying initialization");
 
   createTestingEnvironment();
 
-  let request = await initChromeOrigin("persistent");
-  ok(request.resultCode == Cr.NS_OK, "Initialization succeed");
+  let request = initChromeOrigin("persistent");
+  await requestFinished(request);
 
   let testingFiles = getTestingFiles();
   ok(!testingFiles.dbFile.exists(), "The obsolete database file doesn't exist");
   ok(!testingFiles.dir.exists(), "The obsolete directory doesn't exist");
   ok(!testingFiles.markerFile.exists(), "The marker file doesn't exist");
 
   info("Verifying open shouldn't be blocked by unexpected files");
 
new file mode 100644
--- /dev/null
+++ b/dom/indexedDB/test/unit/test_orphaned_files.js
@@ -0,0 +1,58 @@
+/**
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+/**
+ * The goal of this test is to prove that orphaned files are cleaned up during
+ * origin initialization. A file is orphaned when there's a file with zero size
+ * in the $dbName.files/journals directory and the file table in the database
+ * contains no records for given id. A file can become orphaned when we didn't
+ * have a chance to remove the file from disk during shutdown or the app just
+ * crashed.
+ */
+
+async function testSteps() {
+  const name = "test_orphaned_files.js";
+
+  const objectStoreName = "Blobs";
+
+  const blobData = { key: 1 };
+
+  info("Installing profile");
+
+  let request = clearAllDatabases();
+  await requestFinished(request);
+
+  // The profile contains one initialized origin directory (with an IndexedDB
+  // database and an orphaned file), a script for origin initialization and the
+  // storage database:
+  // - storage/permanent/chrome
+  // - create_db.js
+  // - storage.sqlite
+  // The file create_db.js in the package was run locally, specifically it was
+  // temporarily added to xpcshell.ini and then executed:
+  //   mach xpcshell-test --interactive dom/indexedDB/test/unit/create_db.js
+  // Note: to make it become the profile in the test, additional manual steps
+  // are needed.
+  // 1. Remove the file "storage/ls-archive.sqlite".
+
+  installPackagedProfile("orphaned_files_profile");
+
+  info("Opening database");
+
+  request = indexedDB.open(name);
+  await expectingSuccess(request);
+
+  info("Getting data");
+
+  request = request.result
+    .transaction([objectStoreName])
+    .objectStore(objectStoreName)
+    .get(blobData.key);
+  await requestSucceeded(request);
+
+  info("Verifying data");
+
+  ok(request.result === undefined, "Correct result");
+}
--- a/dom/indexedDB/test/unit/xpcshell-head-parent-process.js
+++ b/dom/indexedDB/test/unit/xpcshell-head-parent-process.js
@@ -247,16 +247,23 @@ function setTimeout(fun, timeout) {
     notify(timer) {
       fun();
     },
   };
   timer.initWithCallback(event, timeout, Ci.nsITimer.TYPE_ONE_SHOT);
   return timer;
 }
 
+function initChromeOrigin(persistence) {
+  let principal = Cc["@mozilla.org/systemprincipal;1"].createInstance(
+    Ci.nsIPrincipal
+  );
+  return Services.qms.initStoragesForPrincipal(principal, persistence);
+}
+
 function resetOrClearAllDatabases(callback, clear) {
   if (!SpecialPowers.isMainProcess()) {
     throw new Error("clearAllDatabases not implemented for child processes!");
   }
 
   const quotaPref = "dom.quotaManager.testing";
 
   let oldPrefValue;
@@ -279,24 +286,26 @@ function resetOrClearAllDatabases(callba
       SpecialPowers.setBoolPref(quotaPref, oldPrefValue);
     } else {
       SpecialPowers.clearUserPref(quotaPref);
     }
     throw e;
   }
 
   request.callback = callback;
+
+  return request;
 }
 
 function resetAllDatabases(callback) {
-  resetOrClearAllDatabases(callback, false);
+  return resetOrClearAllDatabases(callback, false);
 }
 
 function clearAllDatabases(callback) {
-  resetOrClearAllDatabases(callback, true);
+  return resetOrClearAllDatabases(callback, true);
 }
 
 function installPackagedProfile(packageName) {
   let profileDir = Services.dirsvc.get("ProfD", Ci.nsIFile);
 
   let currentDir = Services.dirsvc.get("CurWorkD", Ci.nsIFile);
 
   let packageFile = currentDir.clone();
@@ -541,56 +550,70 @@ function resetPreprocessing() {
   SpecialPowers.clearUserPref("dom.indexedDB.preprocessing");
 }
 
 function getPrincipal(url) {
   let uri = Services.io.newURI(url);
   return Services.scriptSecurityManager.createContentPrincipal(uri, {});
 }
 
+function requestFinished(request) {
+  return new Promise(function(resolve, reject) {
+    request.callback = function(req) {
+      if (req.resultCode == Cr.NS_OK) {
+        resolve(req.result);
+      } else {
+        reject(req.resultCode);
+      }
+    };
+  });
+}
+
+// TODO: Rename to openDBRequestSucceeded ?
 function expectingSuccess(request) {
   return new Promise(function(resolve, reject) {
     request.onerror = function(event) {
       ok(false, "indexedDB error, '" + event.target.error.name + "'");
       reject(event);
     };
     request.onsuccess = function(event) {
       resolve(event);
     };
     request.onupgradeneeded = function(event) {
       ok(false, "Got upgrade, but did not expect it!");
       reject(event);
     };
   });
 }
 
+// TODO: Rename to openDBRequestUpgradeNeeded ?
 function expectingUpgrade(request) {
   return new Promise(function(resolve, reject) {
     request.onerror = function(event) {
       ok(false, "indexedDB error, '" + event.target.error.name + "'");
       reject(event);
     };
     request.onupgradeneeded = function(event) {
       resolve(event);
     };
     request.onsuccess = function(event) {
       ok(false, "Got success, but did not expect it!");
       reject(event);
     };
   });
 }
 
-function initChromeOrigin(persistence) {
-  let principal = Cc["@mozilla.org/systemprincipal;1"].createInstance(
-    Ci.nsIPrincipal
-  );
-  return new Promise(function(resolve) {
-    let request = Services.qms.initStoragesForPrincipal(principal, persistence);
-    request.callback = function() {
-      return resolve(request);
+function requestSucceeded(request) {
+  return new Promise(function(resolve, reject) {
+    request.onerror = function(event) {
+      ok(false, "indexedDB error, '" + event.target.error.name + "'");
+      reject(event);
+    };
+    request.onsuccess = function(event) {
+      resolve(event);
     };
   });
 }
 
 // Given a "/"-delimited path relative to the profile directory,
 // return an nsIFile representing the path.  This does not test
 // for the existence of the file or parent directories.
 // It is safe even on Windows where the directory separator is not "/",
--- a/dom/indexedDB/test/unit/xpcshell-parent-process.ini
+++ b/dom/indexedDB/test/unit/xpcshell-parent-process.ini
@@ -8,16 +8,17 @@ head = xpcshell-head-parent-process.js
 tail =
 support-files =
   bug1056939_profile.zip
   defaultStorageUpgrade_profile.zip
   idbSubdirUpgrade1_profile.zip
   idbSubdirUpgrade2_profile.zip
   mutableFileUpgrade_profile.zip
   obsoleteOriginAttributes_profile.zip
+  orphaned_files_profile.zip
   oldDirectories_profile.zip
   GlobalObjectsChild.js
   GlobalObjectsComponent.js
   GlobalObjectsComponent.manifest
   GlobalObjectsModule.jsm
   GlobalObjectsSandbox.js
   metadata2Restore_profile.zip
   metadataRestore_profile.zip
@@ -28,16 +29,17 @@ support-files =
   storagePersistentUpgrade_profile.zip
   wasm_get_values_profile.zip
   xpcshell-shared.ini
 
 [include:xpcshell-shared.ini]
 
 [test_bad_origin_directory.js]
 [test_obsoleteOriginAttributesUpgrade.js]
+[test_orphaned_files.js]
 [test_blob_file_backed.js]
 [test_bug1056939.js]
 [test_cleanup_transaction.js]
 [test_database_close_without_onclose.js]
 [test_database_onclose.js]
 [test_defaultStorageUpgrade.js]
 [test_file_copy_failure.js]
 [test_idbSubdirUpgrade.js]
--- a/dom/ipc/BrowserBridgeParent.cpp
+++ b/dom/ipc/BrowserBridgeParent.cpp
@@ -29,21 +29,29 @@ BrowserBridgeParent::~BrowserBridgeParen
 
 nsresult BrowserBridgeParent::InitWithProcess(
     ContentParent* aContentParent, const nsString& aPresentationURL,
     const WindowGlobalInit& aWindowInit, uint32_t aChromeFlags, TabId aTabId) {
   RefPtr<CanonicalBrowsingContext> browsingContext =
       aWindowInit.browsingContext()->Canonical();
 
   // We can inherit most TabContext fields for the new BrowserParent actor from
-  // our Manager BrowserParent.
+  // our Manager BrowserParent. We also need to sync the first party domain if
+  // the content principal exists.
   MutableTabContext tabContext;
+  OriginAttributes attrs;
+  attrs = Manager()->OriginAttributesRef();
+  RefPtr<nsIPrincipal> principal = Manager()->GetContentPrincipal();
+  if (principal) {
+    attrs.SetFirstPartyDomain(
+        true, principal->OriginAttributesRef().mFirstPartyDomain);
+  }
+
   tabContext.SetTabContext(false, Manager()->ChromeOuterWindowID(),
-                           Manager()->ShowFocusRings(),
-                           Manager()->OriginAttributesRef(), aPresentationURL,
+                           Manager()->ShowFocusRings(), attrs, aPresentationURL,
                            Manager()->GetMaxTouchPoints());
 
   // Ensure that our content process is subscribed to our newly created
   // BrowsingContextGroup.
   browsingContext->Group()->EnsureSubscribed(aContentParent);
   browsingContext->SetOwnerProcessId(aContentParent->ChildID());
 
   // Construct the BrowserParent object for our subframe.
--- a/dom/ipc/BrowserParent.cpp
+++ b/dom/ipc/BrowserParent.cpp
@@ -487,16 +487,30 @@ ShowInfo BrowserParent::GetShowInfo() {
     return ShowInfo(name, allowFullscreen, isPrivate, false, isTransparent,
                     mDPI, mRounding, mDefaultScale.scale);
   }
 
   return ShowInfo(EmptyString(), false, false, false, false, mDPI, mRounding,
                   mDefaultScale.scale);
 }
 
+already_AddRefed<nsIPrincipal> BrowserParent::GetContentPrincipal() const {
+  nsCOMPtr<nsIBrowser> browser =
+      mFrameElement ? mFrameElement->AsBrowser() : nullptr;
+  NS_ENSURE_TRUE(browser, nullptr);
+
+  RefPtr<nsIPrincipal> principal;
+
+  nsresult rv;
+  rv = browser->GetContentPrincipal(getter_AddRefs(principal));
+  NS_ENSURE_SUCCESS(rv, nullptr);
+
+  return principal.forget();
+}
+
 void BrowserParent::SetOwnerElement(Element* aElement) {
   // If we held previous content then unregister for its events.
   RemoveWindowListeners();
 
   // If we change top-level documents then we need to change our
   // registration with them.
   RefPtr<nsPIWindowRoot> curTopLevelWin, newTopLevelWin;
   if (mFrameElement) {
--- a/dom/ipc/BrowserParent.h
+++ b/dom/ipc/BrowserParent.h
@@ -187,16 +187,19 @@ class BrowserParent final : public PBrow
   BrowserBridgeParent* GetBrowserBridgeParent() const;
 
   // Returns the BrowserHost if this BrowserParent is for a top-level browser
   // and nullptr otherwise.
   BrowserHost* GetBrowserHost() const;
 
   ShowInfo GetShowInfo();
 
+  // Get the content principal from the owner element.
+  already_AddRefed<nsIPrincipal> GetContentPrincipal() const;
+
   /**
    * Let managees query if Destroy() is already called so they don't send out
    * messages when the PBrowser actor is being destroyed.
    */
   bool IsDestroyed() const { return mIsDestroyed; }
 
   /**
    * Returns whether we're in the process of creating a new window (from
--- a/dom/ipc/TabContext.cpp
+++ b/dom/ipc/TabContext.cpp
@@ -46,16 +46,21 @@ bool TabContext::SetTabContext(const Tab
 
   return true;
 }
 
 void TabContext::SetPrivateBrowsingAttributes(bool aIsPrivateBrowsing) {
   mOriginAttributes.SyncAttributesWithPrivateBrowsing(aIsPrivateBrowsing);
 }
 
+void TabContext::SetFirstPartyDomainAttributes(
+    const nsAString& aFirstPartyDomain) {
+  mOriginAttributes.SetFirstPartyDomain(true, aFirstPartyDomain);
+}
+
 bool TabContext::UpdateTabContextAfterSwap(const TabContext& aContext) {
   // This is only used after already initialized.
   MOZ_ASSERT(mInitialized);
 
   // The only permissable changes are to `mIsMozBrowserElement` and
   // mChromeOuterWindowID.  All other fields must match for the change
   // to be accepted.
   if (aContext.mOriginAttributes != mOriginAttributes) {
--- a/dom/ipc/TabContext.h
+++ b/dom/ipc/TabContext.h
@@ -92,16 +92,21 @@ class TabContext {
    */
   bool SetTabContext(const TabContext& aContext);
 
   /**
    * Set the tab context's origin attributes to a private browsing value.
    */
   void SetPrivateBrowsingAttributes(bool aIsPrivateBrowsing);
 
+  /**
+   * Set the first party domain of the tab context's origin attributes.
+   */
+  void SetFirstPartyDomainAttributes(const nsAString& aFirstPartyDomain);
+
   bool SetTabContext(bool aIsMozBrowserElement, uint64_t aChromeOuterWindowID,
                      UIStateChangeType aShowFocusRings,
                      const OriginAttributes& aOriginAttributes,
                      const nsAString& aPresentationURL,
                      uint32_t aMaxTouchPoints);
 
   /**
    * Modify this TabContext to match the given TabContext.  This is a special
@@ -189,16 +194,20 @@ class MutableTabContext : public TabCont
     return TabContext::SetTabContext(aIsMozBrowserElement, aChromeOuterWindowID,
                                      aShowFocusRings, aOriginAttributes,
                                      aPresentationURL, aMaxTouchPoints);
   }
 
   bool SetTabContextForJSPluginFrame(uint32_t aJSPluginID) {
     return TabContext::SetTabContextForJSPluginFrame(aJSPluginID);
   }
+
+  void SetFirstPartyDomainAttributes(const nsAString& aFirstPartyDomain) {
+    TabContext::SetFirstPartyDomainAttributes(aFirstPartyDomain);
+  }
 };
 
 /**
  * MaybeInvalidTabContext is a simple class that lets you transform an
  * IPCTabContext into a TabContext.
  *
  * The issue is that an IPCTabContext is not necessarily valid.  So to convert
  * an IPCTabContext into a TabContext, you construct a MaybeInvalidTabContext,
--- a/dom/media/test/AutoplayTestUtils.js
+++ b/dom/media/test/AutoplayTestUtils.js
@@ -1,39 +1,46 @@
+/* import-globals-from manifest.js */
+
 function playAndPostResult(muted, parent_window) {
   let element = document.createElement("video");
   element.preload = "auto";
   element.muted = muted;
   element.src = "short.mp4";
   element.id = "video";
   document.body.appendChild(element);
   let allowedToPlay = element.allowedToPlay;
   element.play().then(
-      () => {
-        parent_window.postMessage({played: true, allowedToPlay}, "*");
-      },
-      () => {
-        parent_window.postMessage({played: false, allowedToPlay}, "*");
-      }
-    );
+    () => {
+      parent_window.postMessage({ played: true, allowedToPlay }, "*");
+    },
+    () => {
+      parent_window.postMessage({ played: false, allowedToPlay }, "*");
+    }
+  );
 }
 
 function nextWindowMessage() {
   return nextEvent(window, "message");
 }
 
 function log(msg) {
   var log_pane = document.body;
   log_pane.appendChild(document.createTextNode(msg));
   log_pane.appendChild(document.createElement("br"));
 }
 
 const autoplayPermission = "autoplay-media";
 
 async function pushAutoplayAllowedPermission() {
   return new Promise((resolve, reject) => {
-    SpecialPowers.pushPermissions([{
-      'type': autoplayPermission,
-      'allow': true,
-      'context': document
-    }], resolve);
+    SpecialPowers.pushPermissions(
+      [
+        {
+          type: autoplayPermission,
+          allow: true,
+          context: document,
+        },
+      ],
+      resolve
+    );
   });
 }
--- a/dom/media/test/background_video.js
+++ b/dom/media/test/background_video.js
@@ -1,75 +1,91 @@
 /* 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/. */
-/* jshint esversion: 6, -W097 */
-/* globals SimpleTest, SpecialPowers, document, info, is, manager, ok */
+
+// This file expects manager to be defined in the global scope.
+/* global manager */
+/* import-globals-from manifest.js */
 
 "use strict";
 
 function startTest(test) {
   info(test.desc);
   SimpleTest.waitForExplicitFinish();
-  SpecialPowers.pushPrefEnv({ 'set': test.prefs }, () => {
+  SpecialPowers.pushPrefEnv({ set: test.prefs }, () => {
     manager.runTests(test.tests, test.runTest);
   });
 }
 
 function nextVideoEnded(video) {
-  return nextEvent(video, 'ended');
+  return nextEvent(video, "ended");
 }
 
 function nextVideoPlaying(video) {
-  return nextEvent(video, 'playing');
+  return nextEvent(video, "playing");
 }
 
 function nextVideoResumes(video) {
-  return nextEvent(video, 'mozexitvideosuspend');
+  return nextEvent(video, "mozexitvideosuspend");
 }
 
 function nextVideoSuspends(video) {
-  return nextEvent(video, 'mozentervideosuspend');
+  return nextEvent(video, "mozentervideosuspend");
 }
 
 /**
  * @param {string} url video src.
  * @returns {HTMLMediaElement} The created video element.
  */
 function appendVideoToDoc(url, token, width, height) {
   // Default size of (160, 120) is used by other media tests.
-  if (width === undefined) { width = 160; }
-  if (height === undefined) { height = 3 * width / 4; }
+  if (width === undefined) {
+    width = 160;
+  }
+  if (height === undefined) {
+    height = (3 * width) / 4;
+  }
 
-  let v = document.createElement('video');
+  let v = document.createElement("video");
   v.token = token;
   v.width = width;
   v.height = height;
   v.src = url;
   document.body.appendChild(v);
   return v;
 }
 
 function appendVideoToDocWithoutLoad(token, width, height) {
   // Default size of (160, 120) is used by other media tests.
-  if (width === undefined) { width = 160; }
-  if (height === undefined) { height = 3*width/4; }
+  if (width === undefined) {
+    width = 160;
+  }
+  if (height === undefined) {
+    height = (3 * width) / 4;
+  }
 
-  let v = document.createElement('video');
+  let v = document.createElement("video");
   v.token = token;
   document.body.appendChild(v);
   v.width = width;
   v.height = height;
   return v;
 }
 
 function loadAndWaitUntilLoadedmetadata(video, url, preloadType = "metadata") {
   return new Promise((resolve, reject) => {
     video.preload = preloadType;
-    video.addEventListener("loadedmetadata", () => { resolve(); }, true);
+    video.addEventListener(
+      "loadedmetadata",
+      () => {
+        resolve();
+      },
+      true
+    );
     video.src = url;
   });
 }
 
 /**
  * @param {HTMLMediaElement} video Video element with under test.
  * @returns {Promise} Promise that is resolved when video 'visibilitychanged' event fires.
  */
@@ -90,111 +106,119 @@ function waitUntilVisible(video) {
   });
 }
 
 /**
  * @param {HTMLMediaElement} video Video element under test.
  * @returns {Promise} Promise that is resolved when video 'playing' event fires.
  */
 function waitUntilPlaying(video) {
-  var p = once(video, 'playing', () => { ok(true, `${video.token} played.`); });
+  var p = once(video, "playing", () => {
+    ok(true, `${video.token} played.`);
+  });
   Log(video.token, "Start playing");
   video.play();
   return p;
 }
 
 /**
  * @param {HTMLMediaElement} video Video element under test.
  * @returns {Promise} Promise which is resolved when video 'ended' event fires.
  */
 function waitUntilEnded(video) {
   Log(video.token, "Waiting for ended");
   if (video.ended) {
     ok(true, video.token + " already ended");
     return Promise.resolve();
   }
 
-  return once(video, 'ended', () => { ok(true, `${video.token} ended`); });
+  return once(video, "ended", () => {
+    ok(true, `${video.token} ended`);
+  });
 }
 
 /**
  * @param {HTMLMediaElement} video Video element under test.
  * @returns {Promise} Promise that is resolved when video decode starts
  *                    suspend timer.
  */
 function testSuspendTimerStartedWhenHidden(video) {
-  var p = once(video, 'mozstartvideosuspendtimer').then(() => {
-    ok(true, `${video.token} suspend begins`)
+  var p = once(video, "mozstartvideosuspendtimer").then(() => {
+    ok(true, `${video.token} suspend begins`);
   });
-  Log(video.token, 'Set Hidden');
+  Log(video.token, "Set Hidden");
   video.setVisible(false);
   return p;
 }
 
 /**
  * @param {HTMLMediaElement} video Video element under test.
  * @returns {Promise} Promise that is resolved when video decode suspends.
  */
 function testVideoSuspendsWhenHidden(video) {
-  let p = once(video, 'mozentervideosuspend').then(() => {
+  let p = once(video, "mozentervideosuspend").then(() => {
     ok(true, `${video.token} suspends`);
   });
   Log(video.token, "Set hidden");
   video.setVisible(false);
   return p;
 }
 
 /**
  * @param {HTMLMediaElement} video Video element under test.
  * @returns {Promise} Promise that is resolved when video decode resumes.
  */
 function testVideoResumesWhenShown(video) {
-  var p = once(video, 'mozexitvideosuspend').then(() => {
+  var p = once(video, "mozexitvideosuspend").then(() => {
     ok(true, `${video.token} resumes`);
   });
   Log(video.token, "Set visible");
   video.setVisible(true);
   return p;
 }
 
 /**
  * @param {HTMLMediaElement} video Video element under test.
  * @returns {Promise} Promise that is resolved when video decode resumes.
  */
 function testVideoOnlySeekCompletedWhenShown(video) {
-  var p = once(video, 'mozvideoonlyseekcompleted').then(() => {
+  var p = once(video, "mozvideoonlyseekcompleted").then(() => {
     ok(true, `${video.token} resumes`);
   });
   Log(video.token, "Set visible");
   video.setVisible(true);
   return p;
 }
 
 /**
  * @param {HTMLVideoElement} video Video element under test.
  * @returns {Promise} Promise that is resolved if video ends and rejects if video suspends.
  */
 function checkVideoDoesntSuspend(video) {
   let p = Promise.race([
-    waitUntilEnded(video).then(() => { ok(true, `${video.token} ended before decode was suspended`) }),
-    once(video, 'mozentervideosuspend', () => { Promise.reject(new Error(`${video.token} suspended`)) })
+    waitUntilEnded(video).then(() => {
+      ok(true, `${video.token} ended before decode was suspended`);
+    }),
+    once(video, "mozentervideosuspend", () => {
+      Promise.reject(new Error(`${video.token} suspended`));
+    }),
   ]);
   Log(video.token, "Set hidden.");
   video.setVisible(false);
   return p;
 }
 
 /**
  * @param {HTMLMediaElement} video Video element under test.
  * @param {number} time video current time to wait til.
  * @returns {Promise} Promise that is resolved once currentTime passes time.
  */
 function waitTil(video, time) {
   Log(video.token, `Waiting for time to reach ${time}s`);
   return new Promise(resolve => {
-    video.addEventListener('timeupdate', function timeUpdateEvent() {
+    video.addEventListener("timeupdate", function timeUpdateEvent() {
       if (video.currentTime > time) {
         video.removeEventListener(name, timeUpdateEvent);
         resolve();
       }
     });
   });
 }
--- a/dom/media/test/can_play_type_dash.js
+++ b/dom/media/test/can_play_type_dash.js
@@ -6,20 +6,20 @@ function check_dash(v, enabled) {
   // DASH types
   check("application/dash+xml", "probably");
 
   // Supported Webm codecs
   check("application/dash+xml; codecs=vorbis", "probably");
   check("application/dash+xml; codecs=vorbis", "probably");
   check("application/dash+xml; codecs=vorbis,vp8", "probably");
   check("application/dash+xml; codecs=vorbis,vp8.0", "probably");
-  check("application/dash+xml; codecs=\"vorbis,vp8\"", "probably");
-  check("application/dash+xml; codecs=\"vorbis,vp8.0\"", "probably");
-  check("application/dash+xml; codecs=\"vp8, vorbis\"", "probably");
-  check("application/dash+xml; codecs=\"vp8.0, vorbis\"", "probably");
+  check('application/dash+xml; codecs="vorbis,vp8"', "probably");
+  check('application/dash+xml; codecs="vorbis,vp8.0"', "probably");
+  check('application/dash+xml; codecs="vp8, vorbis"', "probably");
+  check('application/dash+xml; codecs="vp8.0, vorbis"', "probably");
   check("application/dash+xml; codecs=vp8", "probably");
   check("application/dash+xml; codecs=vp8.0", "probably");
 
   // Unsupported codecs
   check("application/dash+xml; codecs=xyz", "");
   check("application/dash+xml; codecs=xyz,vorbis", "");
   check("application/dash+xml; codecs=vorbis,xyz", "");
   check("application/dash+xml; codecs=xyz,vp8.0", "");
--- a/dom/media/test/can_play_type_ogg.js
+++ b/dom/media/test/can_play_type_ogg.js
@@ -1,72 +1,72 @@
-
 function check_ogg(v, enabled, finish) {
   function check(type, expected) {
     is(v.canPlayType(type), enabled ? expected : "", type);
   }
 
   function basic_test() {
     return new Promise(function(resolve, reject) {
       // Ogg types
       check("video/ogg", "maybe");
       check("audio/ogg", "maybe");
       check("application/ogg", "maybe");
 
       // Supported Ogg codecs
       check("audio/ogg; codecs=vorbis", "probably");
       check("video/ogg; codecs=vorbis", "probably");
       check("video/ogg; codecs=vorbis,theora", "probably");
-      check("video/ogg; codecs=\"vorbis, theora\"", "probably");
+      check('video/ogg; codecs="vorbis, theora"', "probably");
       check("video/ogg; codecs=theora", "probably");
 
       resolve();
     });
   }
 
   // Verify Opus support
   function verify_opus_support() {
     return new Promise(function(resolve, reject) {
-      var OpusEnabled = undefined;
-      try {
-        OpusEnabled = SpecialPowers.getBoolPref("media.opus.enabled");
-      } catch (ex) {
-        // SpecialPowers failed, perhaps because Opus isn't compiled in
-        console.log("media.opus.enabled pref not found; skipping Opus validation");
-      }
+      var OpusEnabled = SpecialPowers.getBoolPref(
+        "media.opus.enabled",
+        undefined
+      );
       if (OpusEnabled != undefined) {
         resolve();
       } else {
+        console.log(
+          "media.opus.enabled pref not found; skipping Opus validation"
+        );
         reject();
       }
     });
   }
 
   function opus_enable() {
-    return SpecialPowers.pushPrefEnv({"set": [['media.opus.enabled', true]]})
-           .then(function() {
-             check("audio/ogg; codecs=opus", "probably");
-           });
+    return SpecialPowers.pushPrefEnv({
+      set: [["media.opus.enabled", true]],
+    }).then(function() {
+      check("audio/ogg; codecs=opus", "probably");
+    });
   }
 
   function opus_disable() {
-    return SpecialPowers.pushPrefEnv({"set": [['media.opus.enabled', false]]})
-           .then(function() {
-             check("audio/ogg; codecs=opus", "");
-           });
+    return SpecialPowers.pushPrefEnv({
+      set: [["media.opus.enabled", false]],
+    }).then(function() {
+      check("audio/ogg; codecs=opus", "");
+    });
   }
 
   function unspported_ogg() {
     // Unsupported Ogg codecs
     check("video/ogg; codecs=xyz", "");
     check("video/ogg; codecs=xyz,vorbis", "");
     check("video/ogg; codecs=vorbis,xyz", "");
 
     finish.call();
   }
 
   basic_test()
-  .then(verify_opus_support)
-  .then(opus_enable)
-  .then(opus_disable)
-  .then(unspported_ogg, unspported_ogg);
-
+    .then(verify_opus_support)
+    .then(opus_enable)
+    .then(opus_disable)
+    .then(unspported_ogg, unspported_ogg);
 }
--- a/dom/media/test/can_play_type_wave.js
+++ b/dom/media/test/can_play_type_wave.js
@@ -10,20 +10,20 @@ function check_wave(v, enabled) {
   check("audio/x-pn-wav", "maybe");
 
   // Supported Wave codecs
   check("audio/wave; codecs=1", "probably");
   check("audio/wave; codecs=6", "probably");
   check("audio/wave; codecs=7", "probably");
   // "no codecs" should be supported, I guess
   check("audio/wave; codecs=", "maybe");
-  check("audio/wave; codecs=\"\"", "maybe");
+  check('audio/wave; codecs=""', "maybe");
 
   // Unsupported Wave codecs
   check("audio/wave; codecs=0", "");
   check("audio/wave; codecs=2", "");
   check("audio/wave; codecs=xyz,1", "");
   check("audio/wave; codecs=1,xyz", "");
-  check("audio/wave; codecs=\"xyz, 1\"", "");
+  check('audio/wave; codecs="xyz, 1"', "");
   // empty codec names
   check("audio/wave; codecs=,", "");
-  check("audio/wave; codecs=\"0, 1,\"", "");
+  check('audio/wave; codecs="0, 1,"', "");
 }
--- a/dom/media/test/can_play_type_webm.js
+++ b/dom/media/test/can_play_type_webm.js
@@ -1,43 +1,39 @@
 async function check_webm(v, enabled) {
   function check(type, expected) {
-    is(v.canPlayType(type), enabled ? expected : "", type + "='" + expected + "'");
+    is(
+      v.canPlayType(type),
+      enabled ? expected : "",
+      type + "='" + expected + "'"
+    );
   }
 
   // WebM types
   check("video/webm", "maybe");
   check("audio/webm", "maybe");
 
-  var video = ['vp8', 'vp8.0', 'vp9', 'vp9.0'];
-  var audio = ['vorbis', 'opus'];
+  var video = ["vp8", "vp8.0", "vp9", "vp9.0"];
+  var audio = ["vorbis", "opus"];
 
   audio.forEach(function(acodec) {
     check("audio/webm; codecs=" + acodec, "probably");
     check("video/webm; codecs=" + acodec, "probably");
   });
   video.forEach(function(vcodec) {
     check("video/webm; codecs=" + vcodec, "probably");
     audio.forEach(function(acodec) {
-        check("video/webm; codecs=\"" + vcodec + ", " + acodec + "\"", "probably");
-        check("video/webm; codecs=\"" + acodec + ", " + vcodec + "\"", "probably");
+      check('video/webm; codecs="' + vcodec + ", " + acodec + '"', "probably");
+      check('video/webm; codecs="' + acodec + ", " + vcodec + '"', "probably");
     });
   });
 
   // Unsupported WebM codecs
   check("video/webm; codecs=xyz", "");
   check("video/webm; codecs=xyz,vorbis", "");
   check("video/webm; codecs=vorbis,xyz", "");
 
-  function getPref(name) {
-    var pref = false;
-    try {
-      pref = SpecialPowers.getBoolPref(name);
-    } catch(ex) { }
-    return pref;
-  }
+  await SpecialPowers.pushPrefEnv({ set: [["media.av1.enabled", true]] });
+  check('video/webm; codecs="av1"', "probably");
 
-  await SpecialPowers.pushPrefEnv({"set": [["media.av1.enabled", true]]});
-  check("video/webm; codecs=\"av1\"", "probably");
-
-  await SpecialPowers.pushPrefEnv({"set": [["media.av1.enabled", false]]});
-  check("video/webm; codecs=\"av1\"", "");
+  await SpecialPowers.pushPrefEnv({ set: [["media.av1.enabled", false]] });
+  check('video/webm; codecs="av1"', "");
 }
--- a/dom/media/test/chromeHelper.js
+++ b/dom/media/test/chromeHelper.js
@@ -1,19 +1,23 @@
 /* -*- Mode: javascript; indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* 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/. */
 
+/* eslint-env mozilla/frame-script */
+
 "use strict";
 
-const dirSvc = Cc["@mozilla.org/file/directory_service;1"].
-               getService(Ci.nsIProperties);
+// eslint-disable-next-line mozilla/use-services
+const dirSvc = Cc["@mozilla.org/file/directory_service;1"].getService(
+  Ci.nsIProperties
+);
 
-addMessageListener('media-test:getcwd', () => {
+addMessageListener("media-test:getcwd", () => {
   let cwd;
   try {
     cwd = dirSvc.get("CurWorkD", Ci.nsIFile).path;
   } finally {
-    sendAsyncMessage('media-test:cwd', cwd);
+    sendAsyncMessage("media-test:cwd", cwd);
   }
 });
--- a/dom/media/test/cloneElementVisually_helpers.js
+++ b/dom/media/test/cloneElementVisually_helpers.js
@@ -1,24 +1,26 @@
-const TEST_VIDEO_1 = "http://mochi.test:8888/tests/dom/media/test/bipbop_225w_175kbps.mp4";
-const TEST_VIDEO_2 = "http://mochi.test:8888/tests/dom/media/test/pixel_aspect_ratio.mp4";
+const TEST_VIDEO_1 =
+  "http://mochi.test:8888/tests/dom/media/test/bipbop_225w_175kbps.mp4";
+const TEST_VIDEO_2 =
+  "http://mochi.test:8888/tests/dom/media/test/pixel_aspect_ratio.mp4";
 const LONG_VIDEO = "http://mochi.test:8888/tests/dom/media/test/gizmo.mp4";
 
 /**
  * Ensure that the original <video> is prepped and ready to play
  * before starting any other tests.
  */
 async function setup() {
   await SpecialPowers.pushPrefEnv({
     set: [
-      [ "media.test.video-suspend", true ],
-      [ "media.suspend-bkgnd-video.enabled", true ],
-      [ "media.suspend-bkgnd-video.delay-ms", 500 ],
-      [ "media.dormant-on-pause-timeout-ms", 0 ],
-      [ "media.cloneElementVisually.testing", true ],
+      ["media.test.video-suspend", true],
+      ["media.suspend-bkgnd-video.enabled", true],
+      ["media.suspend-bkgnd-video.delay-ms", 500],
+      ["media.dormant-on-pause-timeout-ms", 0],
+      ["media.cloneElementVisually.testing", true],
     ],
   });
 
   let originalVideo = document.getElementById("original");
   await setVideoSrc(originalVideo, TEST_VIDEO_1);
 }
 
 /**
@@ -84,21 +86,29 @@ function captureFrameImageData(video) {
  * @resolves
  *        Resolves as true if the two videos match.
  */
 async function assertVideosMatch(video1, video2) {
   let video1Frame = captureFrameImageData(video1);
   let video2Frame = captureFrameImageData(video2);
 
   let left = document.getElementById("left");
-  let leftCtx = getWrappedScaledCanvasContext(left, video1Frame.width, video1Frame.height);
+  let leftCtx = getWrappedScaledCanvasContext(
+    left,
+    video1Frame.width,
+    video1Frame.height
+  );
   leftCtx.putImageData(video1Frame, 0, 0);
 
   let right = document.getElementById("right");
-  let rightCtx = getWrappedScaledCanvasContext(right, video2Frame.width, video2Frame.height);
+  let rightCtx = getWrappedScaledCanvasContext(
+    right,
+    video2Frame.width,
+    video2Frame.height
+  );
   rightCtx.putImageData(video2Frame, 0, 0);
 
   if (video1Frame.data.length != video2Frame.data.length) {
     return false;
   }
 
   let leftDataURL = left.toDataURL();
   let rightDataURL = right.toDataURL();
@@ -205,20 +215,18 @@ async function ensureVideoSuspendable(vi
   ok(!video.hasSuspendTaint(), "Should be suspendable");
 
   // First, we'll simulate putting the video in the background by
   // making it invisible.
   let suspendPromise = waitForEventOnce(video, "mozentervideosuspend");
   video.setVisible(false);
   await suspendPromise;
   ok(true, "Suspended after the video was made invisible.");
-  video.setVisible(true)
+  video.setVisible(true);
 
   ok(!video.hasSuspendTaint(), "Should still be suspendable.");
 
   // Next, we'll pause the video.
   await video.pause();
   await waitForShutdownDecoder(video);
   ok(true, "Shutdown decoder after the video was paused.");
   await video.play();
 }
-
-
--- a/dom/media/test/eme.js
+++ b/dom/media/test/eme.js
@@ -1,241 +1,276 @@
+/* import-globals-from manifest.js */
+
 const CLEARKEY_KEYSYSTEM = "org.w3.clearkey";
 
-const gCencMediaKeySystemConfig = [{
-  initDataTypes: ['cenc'],
-  videoCapabilities: [{ contentType: 'video/mp4' }],
-  audioCapabilities: [{ contentType: 'audio/mp4' }],
-}];
+const gCencMediaKeySystemConfig = [
+  {
+    initDataTypes: ["cenc"],
+    videoCapabilities: [{ contentType: "video/mp4" }],
+    audioCapabilities: [{ contentType: "audio/mp4" }],
+  },
+];
 
 function IsMacOSSnowLeopardOrEarlier() {
   var re = /Mac OS X (\d+)\.(\d+)/;
   var ver = navigator.userAgent.match(re);
   if (!ver || ver.length != 3) {
     return false;
   }
   var major = ver[1] | 0;
   var minor = ver[2] | 0;
   return major == 10 && minor <= 6;
 }
 
-function bail(message)
-{
+function bail(message) {
   return function(err) {
     if (err) {
-      message +=  "; " + String(err)
+      message += "; " + String(err);
     }
     ok(false, message);
     if (err) {
       info(String(err));
     }
     SimpleTest.finish();
-  }
+  };
 }
 
-function ArrayBufferToString(arr)
-{
-  var str = '';
+function ArrayBufferToString(arr) {
+  var str = "";
   var view = new Uint8Array(arr);
   for (var i = 0; i < view.length; i++) {
     str += String.fromCharCode(view[i]);
   }
   return str;
 }
 
-function StringToArrayBuffer(str)
-{
+function StringToArrayBuffer(str) {
   var arr = new ArrayBuffer(str.length);
   var view = new Uint8Array(arr);
   for (var i = 0; i < str.length; i++) {
     view[i] = str.charCodeAt(i);
   }
   return arr;
 }
 
-function StringToHex(str){
+function StringToHex(str) {
   var res = "";
   for (var i = 0; i < str.length; ++i) {
-      res += ("0" + str.charCodeAt(i).toString(16)).slice(-2);
+    res += ("0" + str.charCodeAt(i).toString(16)).slice(-2);
   }
   return res;
 }
 
-function Base64ToHex(str)
-{
+function Base64ToHex(str) {
   var bin = window.atob(str.replace(/-/g, "+").replace(/_/g, "/"));
   var res = "";
   for (var i = 0; i < bin.length; i++) {
     res += ("0" + bin.charCodeAt(i).toString(16)).substr(-2);
   }
   return res;
 }
 
-function HexToBase64(hex)
-{
+function HexToBase64(hex) {
   var bin = "";
   for (var i = 0; i < hex.length; i += 2) {
     bin += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
   }
-  return window.btoa(bin).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
+  return window
+    .btoa(bin)
+    .replace(/=/g, "")
+    .replace(/\+/g, "-")
+    .replace(/\//g, "_");
 }
 
-function TimeRangesToString(trs)
-{
+function TimeRangesToString(trs) {
   var l = trs.length;
-  if (l === 0) { return "-"; }
+  if (l === 0) {
+    return "-";
+  }
   var s = "";
   var i = 0;
   for (;;) {
     s += trs.start(i) + "-" + trs.end(i);
-    if (++i === l) { return s; }
+    if (++i === l) {
+      return s;
+    }
     s += ",";
   }
 }
 
-function SourceBufferToString(sb)
-{
-  return ("SourceBuffer{"
-    + "AppendMode=" + (sb.AppendMode || "-")
-    + ", updating=" + (sb.updating ? "true" : "false")
-    + ", buffered=" + TimeRangesToString(sb.buffered)
-    + ", audioTracks=" + (sb.audioTracks ? sb.audioTracks.length : "-")
-    + ", videoTracks=" + (sb.videoTracks ? sb.videoTracks.length : "-")
-    + "}");
+function SourceBufferToString(sb) {
+  return (
+    "SourceBuffer{" +
+    "AppendMode=" +
+    (sb.AppendMode || "-") +
+    ", updating=" +
+    (sb.updating ? "true" : "false") +
+    ", buffered=" +
+    TimeRangesToString(sb.buffered) +
+    ", audioTracks=" +
+    (sb.audioTracks ? sb.audioTracks.length : "-") +
+    ", videoTracks=" +
+    (sb.videoTracks ? sb.videoTracks.length : "-") +
+    "}"
+  );
 }
 
-function SourceBufferListToString(sbl)
-{
+function SourceBufferListToString(sbl) {
   return "SourceBufferList[" + sbl.map(SourceBufferToString).join(", ") + "]";
 }
 
-function GenerateClearKeyLicense(licenseRequest, keyStore)
-{
+function GenerateClearKeyLicense(licenseRequest, keyStore) {
   var msgStr = ArrayBufferToString(licenseRequest);
   var msg = JSON.parse(msgStr);
 
   var keys = [];
   for (var i = 0; i < msg.kids.length; i++) {
     var id64 = msg.kids[i];
     var idHex = Base64ToHex(msg.kids[i]).toLowerCase();
     var key = keyStore[idHex];
 
     if (key) {
       keys.push({
-        "kty": "oct",
-        "kid": id64,
-        "k": HexToBase64(key)
+        kty: "oct",
+        kid: id64,
+        k: HexToBase64(key),
       });
     }
   }
 
-  return new TextEncoder().encode(JSON.stringify({
-    "keys" : keys,
-    "type" : msg.type || "temporary"
-  }));
+  return new TextEncoder().encode(
+    JSON.stringify({
+      keys,
+      type: msg.type || "temporary",
+    })
+  );
 }
 
 function UpdateSessionFunc(test, token, sessionType, resolve, reject) {
   return function(ev) {
     var license = GenerateClearKeyLicense(ev.message, test.keys);
-    Log(token, "sending update message to CDM: " + (new TextDecoder().decode(license)));
-    ev.target.update(license).then(function() {
-      Log(token, "MediaKeySession update ok!");
-      resolve(ev.target);
-    }).catch(function(reason) {
-      reject(`${token} MediaKeySession update failed: ${reason}`);
-    });
-  }
+    Log(
+      token,
+      "sending update message to CDM: " + new TextDecoder().decode(license)
+    );
+    ev.target
+      .update(license)
+      .then(function() {
+        Log(token, "MediaKeySession update ok!");
+        resolve(ev.target);
+      })
+      .catch(function(reason) {
+        reject(`${token} MediaKeySession update failed: ${reason}`);
+      });
+  };
 }
 
-function MaybeCrossOriginURI(test, uri)
-{
+function MaybeCrossOriginURI(test, uri) {
   if (test.crossOrigin) {
     return "https://example.com:443/tests/dom/media/test/allowed.sjs?" + uri;
-  } else {
-    return uri;
   }
+  return uri;
 }
 
-function AppendTrack(test, ms, track, token)
-{
+function AppendTrack(test, ms, track, token) {
   return new Promise(function(resolve, reject) {
     var sb;
     var curFragment = 0;
-    var resolved = false;
     var fragments = track.fragments;
     var fragmentFile;
 
     function addNextFragment() {
       if (curFragment >= fragments.length) {
         Log(token, track.name + ": end of track");
         resolve();
-        resolved = true;
         return;
       }
 
       fragmentFile = MaybeCrossOriginURI(test, fragments[curFragment++]);
 
       var req = new XMLHttpRequest();
       req.open("GET", fragmentFile);
       req.responseType = "arraybuffer";
 
       req.addEventListener("load", function() {
-        Log(token, track.name + ": fetch of " + fragmentFile + " complete, appending");
+        Log(
+          token,
+          track.name + ": fetch of " + fragmentFile + " complete, appending"
+        );
         sb.appendBuffer(new Uint8Array(req.response));
       });
 
       req.addEventListener("error", function() {
         reject(`${token} - ${track.name}: error fetching ${fragmentFile}`);
       });
       req.addEventListener("abort", function() {
         reject(`${token} - ${track.name}: aborted fetching ${fragmentFile}`);
       });
 
-      Log(token, track.name + ": addNextFragment() fetching next fragment " + fragmentFile);
+      Log(
+        token,
+        track.name +
+          ": addNextFragment() fetching next fragment " +
+          fragmentFile
+      );
       req.send(null);
     }
 
     Log(token, track.name + ": addSourceBuffer(" + track.type + ")");
     sb = ms.addSourceBuffer(track.type);
     sb.addEventListener("updateend", function() {
-      Log(token, track.name + ": updateend for " + fragmentFile + ", " + SourceBufferToString(sb));
+      Log(
+        token,
+        track.name +
+          ": updateend for " +
+          fragmentFile +
+          ", " +
+          SourceBufferToString(sb)
+      );
       addNextFragment();
     });
 
     addNextFragment();
   });
 }
 
 //Returns a promise that is resolved when the media element is ready to have
 //its play() function called; when it's loaded MSE fragments.
-function LoadTest(test, elem, token, endOfStream = true)
-{
+function LoadTest(test, elem, token, endOfStream = true) {
   if (!test.tracks) {
     ok(false, token + " test does not have a tracks list");
     return Promise.reject();
   }
 
   var ms = new MediaSource();
   elem.src = URL.createObjectURL(ms);
   elem.crossOrigin = test.crossOrigin || false;
 
-  return new Promise(function (resolve, reject) {
-    ms.addEventListener("sourceopen", function () {
-      Log(token, "sourceopen");
-      Promise.all(test.tracks.map(function(track) {
-        return AppendTrack(test, ms, track, token);
-      })).then(function() {
-        Log(token, "Tracks loaded, calling MediaSource.endOfStream()");
-        if (endOfStream) {
-          ms.endOfStream();
-        }
-        resolve();
-      }).catch(reject);
-    }, {once: true});
+  return new Promise(function(resolve, reject) {
+    ms.addEventListener(
+      "sourceopen",
+      function() {
+        Log(token, "sourceopen");
+        Promise.all(
+          test.tracks.map(function(track) {
+            return AppendTrack(test, ms, track, token);
+          })
+        )
+          .then(function() {
+            Log(token, "Tracks loaded, calling MediaSource.endOfStream()");
+            if (endOfStream) {
+              ms.endOfStream();
+            }
+            resolve();
+          })
+          .catch(reject);
+      },
+      { once: true }
+    );
   });
 }
 
 function EMEPromise() {
   var self = this;
   self.promise = new Promise(function(resolve, reject) {
     self.resolve = resolve;
     self.reject = reject;
@@ -243,80 +278,89 @@ function EMEPromise() {
 }
 
 /*
  * Create a new MediaKeys object.
  * Return a promise which will be resolved with a new MediaKeys object,
  * or will be rejected with a string that describes the failure.
  */
 function CreateMediaKeys(v, test, token) {
-  let p = new EMEPromise;
+  let p = new EMEPromise();
 
   function streamType(type) {
     var x = test.tracks.find(o => o.name == type);
     return x ? x.type : undefined;
   }
 
   function onencrypted(ev) {
     var options = { initDataTypes: [ev.initDataType] };
     if (streamType("video")) {
-      options.videoCapabilities = [{contentType: streamType("video")}];
+      options.videoCapabilities = [{ contentType: streamType("video") }];
     }
     if (streamType("audio")) {
-      options.audioCapabilities = [{contentType: streamType("audio")}];
+      options.audioCapabilities = [{ contentType: streamType("audio") }];
     }
-    navigator.requestMediaKeySystemAccess(CLEARKEY_KEYSYSTEM, [options])
-    .then(keySystemAccess => {
-      keySystemAccess.createMediaKeys().then(
-        p.resolve,
-        () => p.reject(`${token} Failed to create MediaKeys object.`)
-      );
-    }, () => p.reject(`${token} Failed to request key system access.`));
+    navigator.requestMediaKeySystemAccess(CLEARKEY_KEYSYSTEM, [options]).then(
+      keySystemAccess => {
+        keySystemAccess
+          .createMediaKeys()
+          .then(p.resolve, () =>
+            p.reject(`${token} Failed to create MediaKeys object.`)
+          );
+      },
+      () => p.reject(`${token} Failed to request key system access.`)
+    );
   }
 
-  v.addEventListener("encrypted", onencrypted, {once: true});
+  v.addEventListener("encrypted", onencrypted, { once: true });
   return p.promise;
 }
 
 /*
  * Create a new MediaKeys object and provide it to the media element.
  * Return a promise which will be resolved if succeeded, or will be rejected
  * with a string that describes the failure.
  */
 function CreateAndSetMediaKeys(v, test, token) {
-  let p = new EMEPromise;
+  let p = new EMEPromise();
 
   CreateMediaKeys(v, test, token).then(mediaKeys => {
-    v.setMediaKeys(mediaKeys).then(
-      p.resolve,
-      () => p.reject(`${token} Failed to set MediaKeys on <video> element.`)
+    v.setMediaKeys(mediaKeys).then(p.resolve, () =>
+      p.reject(`${token} Failed to set MediaKeys on <video> element.`)
     );
-  }, p.reject)
+  }, p.reject);
 
   return p.promise;
 }
 
 /*
  * Collect the init data from 'encrypted' events.
  * Return a promise which will be resolved with the init data when collection
  * is completed (specified by test.sessionCount).
  */
 function LoadInitData(v, test, token) {
-  let p = new EMEPromise;
+  let p = new EMEPromise();
   let initDataQueue = [];
 
   // Call SimpleTest._originalSetTimeout() to bypass the flaky timeout checker.
-  let timer = SimpleTest._originalSetTimeout.call(window, () => {
-    p.reject(`${token} Timed out in waiting for the init data.`);
-  }, 60000);
+  let timer = SimpleTest._originalSetTimeout.call(
+    window,
+    () => {
+      p.reject(`${token} Timed out in waiting for the init data.`);
+    },
+    60000
+  );
 
   function onencrypted(ev) {
     initDataQueue.push(ev);
-    Log(token, `got encrypted(${ev.initDataType}, ` +
-        `${StringToHex(ArrayBufferToString(ev.initData))}) event.`);
+    Log(
+      token,
+      `got encrypted(${ev.initDataType}, ` +
+        `${StringToHex(ArrayBufferToString(ev.initData))}) event.`
+    );
     if (test.sessionCount == initDataQueue.length) {
       p.resolve(initDataQueue);
       clearTimeout(timer);
     }
   }
 
   v.addEventListener("encrypted", onencrypted);
   return p.promise;
@@ -324,26 +368,28 @@ function LoadInitData(v, test, token) {
 
 /*
  * Generate a license request and update the session.
  * Return a promsise which will be resolved with the updated session
  * or rejected with a string that describes the failure.
  */
 function MakeRequest(test, token, ev, session, sessionType) {
   sessionType = sessionType || "temporary";
-  let p = new EMEPromise;
-  let str = `session[${session.sessionId}].generateRequest(` +
+  let p = new EMEPromise();
+  let str =
+    `session[${session.sessionId}].generateRequest(` +
     `${ev.initDataType}, ${StringToHex(ArrayBufferToString(ev.initData))})`;
 
-  session.addEventListener("message",
-    UpdateSessionFunc(test, token, sessionType, p.resolve, p.reject));
+  session.addEventListener(
+    "message",
+    UpdateSessionFunc(test, token, sessionType, p.resolve, p.reject)
+  );
 
   Log(token, str);
-  session.generateRequest(ev.initDataType, ev.initData)
-  .catch(reason => {
+  session.generateRequest(ev.initDataType, ev.initData).catch(reason => {
     // Reject the promise if generateRequest() failed.
     // Otherwise it will be resolved in UpdateSessionFunc().
     p.reject(`${token}: ${str} failed; ${reason}`);
   });
 
   return p.promise;
 }
 
@@ -370,82 +416,92 @@ function CleanUpMedia(v) {
   v.removeAttribute("src");
   v.load();
 }
 
 /*
  * Close all sessions and clean up the |v| element.
  */
 function CloseSessions(v, sessions) {
-  return Promise.all(sessions.map(s => s.close()))
-  .then(CleanUpMedia(v));
+  return Promise.all(sessions.map(s => s.close())).then(CleanUpMedia(v));
 }
 
 /*
  * Set up media keys and source buffers for the media element.
  * Return a promise resolved when all key sessions are updated or rejected
  * if any failure.
  */
 function SetupEME(v, test, token) {
-  let p = new EMEPromise;
+  let p = new EMEPromise();
 
   v.onerror = function() {
     p.reject(`${token} got an error event.`);
-  }
+  };
 
   Promise.all([
     LoadInitData(v, test, token),
     CreateAndSetMediaKeys(v, test, token),
-    LoadTest(test, v, token)])
-  .then(values => {
-    let initData = values[0];
-    return ProcessInitData(v, test, token, initData);
-  })
-  .then(p.resolve, p.reject);
+    LoadTest(test, v, token),
+  ])
+    .then(values => {
+      let initData = values[0];
+      return ProcessInitData(v, test, token, initData);
+    })
+    .then(p.resolve, p.reject);
 
   return p.promise;
 }
 
 function SetupEMEPref(callback) {
   var prefs = [
-    [ "media.mediasource.enabled", true ],
-    [ "media.mediasource.webm.enabled", true ],
+    ["media.mediasource.enabled", true],
+    ["media.mediasource.webm.enabled", true],
   ];
 
-  if (SpecialPowers.Services.appinfo.name == "B2G" ||
-      !manifestVideo().canPlayType("video/mp4")) {
+  if (
+    SpecialPowers.Services.appinfo.name == "B2G" ||
+    !manifestVideo().canPlayType("video/mp4")
+  ) {
     // XXX remove once we have mp4 PlatformDecoderModules on all platforms.
-    prefs.push([ "media.use-blank-decoder", true ]);
+    prefs.push(["media.use-blank-decoder", true]);
   }
 
-  SpecialPowers.pushPrefEnv({ "set" : prefs }, callback);
+  SpecialPowers.pushPrefEnv({ set: prefs }, callback);
 }
 
 function fetchWithXHR(uri, onLoadFunction) {
   var p = new Promise(function(resolve, reject) {
     var xhr = new XMLHttpRequest();
     xhr.open("GET", uri, true);
     xhr.responseType = "arraybuffer";
-    xhr.addEventListener("load", function () {
-      is(xhr.status, 200, "fetchWithXHR load uri='" + uri + "' status=" + xhr.status);
+    xhr.addEventListener("load", function() {
+      is(
+        xhr.status,
+        200,
+        "fetchWithXHR load uri='" + uri + "' status=" + xhr.status
+      );
       resolve(xhr.response);
     });
     xhr.send();
   });
 
   if (onLoadFunction) {
     p.then(onLoadFunction);
   }
 
   return p;
-};
+}
 
 function once(target, name, cb) {
   var p = new Promise(function(resolve, reject) {
-    target.addEventListener(name, function(arg) {
-      resolve(arg);
-    }, {once: true});
+    target.addEventListener(
+      name,
+      function(arg) {
+        resolve(arg);
+      },
+      { once: true }
+    );
   });
   if (cb) {
     p.then(cb);
   }
   return p;
 }
--- a/dom/media/test/file_autoplay_policy_activation_frame.html
+++ b/dom/media/test/file_autoplay_policy_activation_frame.html
@@ -18,14 +18,14 @@
         (event) => {
           if (event.data == "click") {
             synthesizeMouseAtCenter(document.body, {});
           } else if (event.data == "play-audible") {
             playAndPostResult(false, event.source);
           } else if (event.data == "play-muted") {
             playAndPostResult(true, event.source);
           }
-        }, false);
+        });
       let w = window.opener || window.parent;
       w.postMessage("ready", "*");
     </script>
   </body>
 </html>
--- a/dom/media/test/file_autoplay_policy_eventdown_activation.html
+++ b/dom/media/test/file_autoplay_policy_eventdown_activation.html
@@ -31,22 +31,22 @@
 
           await once(element, "loadedmetadata");
 
           let played = await element.play().then(() => true, () => false);
           ok(!played, "Document should start out not activated, with playback blocked.");
 
           let x = eventNames.map(
             (eventName) => {
-              return new Promise(async function (resolve, reject) {
+              return new Promise(function (resolve, reject) {
                 window.addEventListener(eventName, async function (event) {
-                  let played = await element.play().then(() => true, () => false);
-                  ok(played, "Expect to be activated already in " + eventName);
+                  let p = await element.play().then(() => true, () => false);
+                  ok(p, "Expect to be activated already in " + eventName);
                   resolve();
-                }, false);
+                });
               });
             });
 
           activator();
 
           await Promise.all(x);
 
           removeNodeAndSource(element);
--- a/dom/media/test/fragment_noplay.js
+++ b/dom/media/test/fragment_noplay.js
@@ -1,14 +1,19 @@
 function test_fragment_noplay(v, start, end, is, ok, finish) {
+  function onLoadedMetadata() {
+    var s = start == null ? 0 : start;
+    var e = end == null ? v.duration : end;
+    var a = s - 0.15;
+    var b = s + 0.15;
+    ok(
+      v.currentTime >= a && v.currentTime <= b,
+      "loadedmetadata currentTime is " + a + " < " + v.currentTime + " < " + b
+    );
+    ok(
+      v.mozFragmentEnd == e,
+      "mozFragmentEnd (" + v.mozFragmentEnd + ") == end Time (" + e + ")"
+    );
+    finish();
+  }
 
-function onLoadedMetadata() {
-  var s = start == null ? 0 : start;
-  var e = end == null ? v.duration : end;
-  var a = s - 0.15;
-  var b = s + 0.15;
-  ok(v.currentTime >= a && v.currentTime <= b, "loadedmetadata currentTime is " + a + " < " + v.currentTime + " < " + b);
-  ok(v.mozFragmentEnd == e, "mozFragmentEnd (" + v.mozFragmentEnd + ") == end Time (" + e + ")");
-  finish();
+  v.addEventListener("loadedmetadata", onLoadedMetadata);
 }
-
-v.addEventListener("loadedmetadata", onLoadedMetadata);
-}
--- a/dom/media/test/fragment_play.js
+++ b/dom/media/test/fragment_play.js
@@ -1,67 +1,92 @@
 function test_fragment_play(v, start, end, is, ok, finish) {
-
-var completed = false;
-var loadedMetadataRaised = false;
-var seekedRaised = false;
-var pausedRaised = false;
+  var completed = false;
+  var loadedMetadataRaised = false;
+  var seekedRaised = false;
+  var pausedRaised = false;
 
-function onLoadedMetadata() {
-  var s = start == null ? 0 : start;
-  var e = end == null ? v.duration : end;
-  ok(v.currentTime == s, "loadedmetadata currentTime is " + v.currentTime + " != " + s);
-  ok(v.mozFragmentEnd == e, "mozFragmentEnd (" + v.mozFragmentEnd + ") == end Time (" + e + ")");
-  loadedMetadataRaised = true; 
-  v.play();
-}
+  function onLoadedMetadata() {
+    var s = start == null ? 0 : start;
+    var e = end == null ? v.duration : end;
+    ok(
+      v.currentTime == s,
+      "loadedmetadata currentTime is " + v.currentTime + " != " + s
+    );
+    ok(
+      v.mozFragmentEnd == e,
+      "mozFragmentEnd (" + v.mozFragmentEnd + ") == end Time (" + e + ")"
+    );
+    loadedMetadataRaised = true;
+    v.play();
+  }
 
-function onSeeked() {
-  if (completed)
-    return;
-
-  var s = start == null ? 0 : start;
-  ok(v.currentTime - s < 0.1, "seeked currentTime is " + v.currentTime + " != " + s + " (fuzzy compare +-0.1)");
+  function onSeeked() {
+    if (completed) {
+      return;
+    }
 
-  seekedRaised = true;
-}
+    var s = start == null ? 0 : start;
+    ok(
+      v.currentTime - s < 0.1,
+      "seeked currentTime is " +
+        v.currentTime +
+        " != " +
+        s +
+        " (fuzzy compare +-0.1)"
+    );
 
-function onTimeUpdate() {
-  if (completed)
-    return;
+    seekedRaised = true;
+  }
 
-  v._lastTimeUpdate = v.currentTime;
-}
+  function onTimeUpdate() {
+    if (completed) {
+      return;
+    }
 
-function onPause() {
-  if (completed)
-    return;
+    v._lastTimeUpdate = v.currentTime;
+  }
 
-  var e = end == null ? v.duration : end;
-  var a = e - 0.05;
-  var b = e + 0.05;
-  ok(v.currentTime >= a && v.currentTime <= b, "paused currentTime is " + a + " < " + v.currentTime + " < " + b + " ? " + v._lastTimeUpdate);
-  pausedRaised = true;
-  v.play();
-}
-
-
-function onEnded() {
-  if (completed)
-    return;
+  function onPause() {
+    if (completed) {
+      return;
+    }
 
-  completed = true;
-  ok(loadedMetadataRaised, "loadedmetadata event");
-  if (start) {
-    ok(seekedRaised, "seeked event");
-  }
-  if (end) {
-    ok(pausedRaised, "paused event: " + end + " " + v.duration);
+    var e = end == null ? v.duration : end;
+    var a = e - 0.05;
+    var b = e + 0.05;
+    ok(
+      v.currentTime >= a && v.currentTime <= b,
+      "paused currentTime is " +
+        a +
+        " < " +
+        v.currentTime +
+        " < " +
+        b +
+        " ? " +
+        v._lastTimeUpdate
+    );
+    pausedRaised = true;
+    v.play();
   }
-  finish();
-}
+
+  function onEnded() {
+    if (completed) {
+      return;
+    }
 
-v.addEventListener("ended", onEnded);
-v.addEventListener("loadedmetadata", onLoadedMetadata);
-v.addEventListener("seeked", onSeeked);
-v.addEventListener("pause", onPause);
-v.addEventListener("timeupdate", onTimeUpdate);
+    completed = true;
+    ok(loadedMetadataRaised, "loadedmetadata event");
+    if (start) {
+      ok(seekedRaised, "seeked event");
+    }
+    if (end) {
+      ok(pausedRaised, "paused event: " + end + " " + v.duration);
+    }
+    finish();
+  }
+
+  v.addEventListener("ended", onEnded);
+  v.addEventListener("loadedmetadata", onLoadedMetadata);
+  v.addEventListener("seeked", onSeeked);
+  v.addEventListener("pause", onPause);
+  v.addEventListener("timeupdate", onTimeUpdate);
 }
--- a/dom/media/test/gUM_support.js
+++ b/dom/media/test/gUM_support.js
@@ -4,74 +4,93 @@
 
 // Setup preconditions for tests using getUserMedia. This functions helps
 // manage different prefs that affect gUM calls in tests and makes explicit
 // the expected state before test runs.
 async function pushGetUserMediaTestPrefs({
   fakeAudio = false,
   fakeVideo = false,
   loopbackAudio = false,
-  loopbackVideo = false}) {
+  loopbackVideo = false,
+}) {
   // Make sure we have sensical arguments
   if (!fakeAudio && !loopbackAudio) {
-    throw new Error("pushGetUserMediaTestPrefs: Should have fake or loopback audio!");
+    throw new Error(
+      "pushGetUserMediaTestPrefs: Should have fake or loopback audio!"
+    );
   } else if (fakeAudio && loopbackAudio) {
-    throw new Error("pushGetUserMediaTestPrefs: Should not have both fake and loopback audio!");
+    throw new Error(
+      "pushGetUserMediaTestPrefs: Should not have both fake and loopback audio!"
+    );
   }
   if (!fakeVideo && !loopbackVideo) {
-    throw new Error("pushGetUserMediaTestPrefs: Should have fake or loopback video!");
+    throw new Error(
+      "pushGetUserMediaTestPrefs: Should have fake or loopback video!"
+    );
   } else if (fakeVideo && loopbackVideo) {
-    throw new Error("pushGetUserMediaTestPrefs: Should not have both fake and loopback video!");
+    throw new Error(
+      "pushGetUserMediaTestPrefs: Should not have both fake and loopback video!"
+    );
   }
 
   let testPrefs = [];
   if (fakeAudio) {
     // Unset the loopback device so it doesn't take precedence
     testPrefs.push(["media.audio_loopback_dev", ""]);
     // Setup fake streams pref
     testPrefs.push(["media.navigator.streams.fake", true]);
   }
   if (loopbackAudio) {
     // If audio loopback is requested we expect the test harness to have set
     // the loopback device pref, make sure it's set
-    let audioLoopDev = SpecialPowers.getCharPref("media.audio_loopback_dev", "");
+    let audioLoopDev = SpecialPowers.getCharPref(
+      "media.audio_loopback_dev",
+      ""
+    );
     if (!audioLoopDev) {
-      throw new Error("pushGetUserMediaTestPrefs: Loopback audio requested but " +
-        "media.audio_loopback_dev does not appear to be set!");
+      throw new Error(
+        "pushGetUserMediaTestPrefs: Loopback audio requested but " +
+          "media.audio_loopback_dev does not appear to be set!"
+      );
     }
   }
   if (fakeVideo) {
     // Unset the loopback device so it doesn't take precedence
     testPrefs.push(["media.video_loopback_dev", ""]);
     // Setup fake streams pref
     testPrefs.push(["media.navigator.streams.fake", true]);
   }
   if (loopbackVideo) {
     // If video loopback is requested we expect the test harness to have set
     // the loopback device pref, make sure it's set
-    let videoLoopDev = SpecialPowers.getCharPref("media.video_loopback_dev", "");
+    let videoLoopDev = SpecialPowers.getCharPref(
+      "media.video_loopback_dev",
+      ""
+    );
     if (!videoLoopDev) {
-      throw new Error("pushGetUserMediaTestPrefs: Loopback video requested but " +
-        "media.video_loopback_dev does not appear to be set!");
+      throw new Error(
+        "pushGetUserMediaTestPrefs: Loopback video requested but " +
+          "media.video_loopback_dev does not appear to be set!"
+      );
     }
   }
   if (loopbackAudio || loopbackVideo) {
     // Prevent gUM permission prompt. Since loopback devices are considered
     // real devices we need to set prefs so the gUM prompt isn't presented.
-    testPrefs.push(['media.navigator.permission.disabled', true]);
+    testPrefs.push(["media.navigator.permission.disabled", true]);
   }
-  return SpecialPowers.pushPrefEnv({set: testPrefs});
+  return SpecialPowers.pushPrefEnv({ set: testPrefs });
 }
 
 // Setup preconditions for tests using getUserMedia. This function will
 // configure prefs to select loopback device(s) if it can find loopback device
 // names already set in the prefs. If no loopback device name can be found then
 // prefs are setup such that a fake device is used.
 async function setupGetUserMediaTestPrefs() {
-  prefRequests = {};
+  let prefRequests = {};
   let audioLoopDev = SpecialPowers.getCharPref("media.audio_loopback_dev", "");
   if (audioLoopDev) {
     prefRequests.fakeAudio = false;
     prefRequests.loopbackAudio = true;
   } else {
     prefRequests.fakeAudio = true;
     prefRequests.loopbackAudio = false;
   }
--- a/dom/media/test/manifest.js
+++ b/dom/media/test/manifest.js
@@ -3,509 +3,736 @@
 // "bogus/duh" in each list.
 
 // Make sure to not touch navigator in here, since we want to push prefs that
 // will affect the APIs it exposes, but the set of exposed APIs is determined
 // when Navigator.prototype is created.  So if we touch navigator before pushing
 // the prefs, the APIs it exposes will not take those prefs into account.  We
 // work around this by using a navigator object from a different global for our
 // UA string testing.
-var gManifestNavigatorSource = document.documentElement.appendChild(document.createElement("iframe"));
+var gManifestNavigatorSource = document.documentElement.appendChild(
+  document.createElement("iframe")
+);
 gManifestNavigatorSource.style.display = "none";
 function manifestNavigator() {
   return gManifestNavigatorSource.contentWindow.navigator;
 }
 
 // Similarly, use a <video> element from a different global for canPlayType or
 // other feature testing.  If we used one from our global and did so before our
 // prefs are pushed, then we'd instantiate HTMLMediaElement.prototype before the
 // prefs are pushed and APIs we expect to be on that object would not be there.
 function manifestVideo() {
-  return gManifestNavigatorSource.contentDocument.createElement('video');
+  return gManifestNavigatorSource.contentDocument.createElement("video");
 }
 
 // Need to get the server url composed with ip:port instead of mochi.test.
 // Since we will provide the url to Exoplayer which cannot recognize the domain
 // name "mochi.test".
-let serverUrl = SpecialPowers.Services.prefs.getCharPref("media.hls.server.url");
+let serverUrl = SpecialPowers.Services.prefs.getCharPref(
+  "media.hls.server.url"
+);
 var gHLSTests = [
-  { name: serverUrl + "/bipbop_4x3_variant.m3u8", type:"audio/x-mpegurl", duration:20.000 }
+  {
+    name: serverUrl + "/bipbop_4x3_variant.m3u8",
+    type: "audio/x-mpegurl",
+    duration: 20.0,
+  },
 ];
 
 // These are small test files, good for just seeing if something loads. We
 // really only need one test file per backend here.
 var gSmallTests = [
-  { name:"small-shot.ogg", type:"audio/ogg", duration:0.276 },
-  { name:"small-shot.m4a", type:"audio/mp4", duration:0.29 },
-  { name:"small-shot.mp3", type:"audio/mpeg", duration:0.27 },
-  { name:"small-shot-mp3.mp4", type:"audio/mp4; codecs=mp3", duration:0.34 },
-  { name:"small-shot.flac", type:"audio/flac", duration:0.197 },
-  { name:"r11025_s16_c1-short.wav", type:"audio/x-wav", duration:0.37 },
-  { name:"320x240.ogv", type:"video/ogg", width:320, height:240, duration:0.266 },
-  { name:"seek-short.webm", type:"video/webm", width:320, height:240, duration:0.23 },
-  { name:"vp9-short.webm", type:"video/webm", width:320, height:240, duration:0.20 },
-  { name:"detodos-short.opus", type:"audio/ogg; codecs=opus", duration:0.22 },
-  { name:"gizmo-short.mp4", type:"video/mp4", width:560, height:320, duration:0.27 },
-  { name:"flac-s24.flac", type:"audio/flac", duration:4.04 },
-  { name:"bogus.duh", type:"bogus/duh" }
+  { name: "small-shot.ogg", type: "audio/ogg", duration: 0.276 },
+  { name: "small-shot.m4a", type: "audio/mp4", duration: 0.29 },
+  { name: "small-shot.mp3", type: "audio/mpeg", duration: 0.27 },
+  { name: "small-shot-mp3.mp4", type: "audio/mp4; codecs=mp3", duration: 0.34 },
+  { name: "small-shot.flac", type: "audio/flac", duration: 0.197 },
+  { name: "r11025_s16_c1-short.wav", type: "audio/x-wav", duration: 0.37 },
+  {
+    name: "320x240.ogv",
+    type: "video/ogg",
+    width: 320,
+    height: 240,
+    duration: 0.266,
+  },
+  {
+    name: "seek-short.webm",
+    type: "video/webm",
+    width: 320,
+    height: 240,
+    duration: 0.23,
+  },
+  {
+    name: "vp9-short.webm",
+    type: "video/webm",
+    width: 320,
+    height: 240,
+    duration: 0.2,
+  },
+  {
+    name: "detodos-short.opus",
+    type: "audio/ogg; codecs=opus",
+    duration: 0.22,
+  },
+  {
+    name: "gizmo-short.mp4",
+    type: "video/mp4",
+    width: 560,
+    height: 320,
+    duration: 0.27,
+  },
+  { name: "flac-s24.flac", type: "audio/flac", duration: 4.04 },
+  { name: "bogus.duh", type: "bogus/duh" },
 ];
 
 var gFrameCountTests = [
-  { name:"bipbop.mp4", type:"video/mp4", totalFrameCount:297},
-  { name:"gizmo.mp4", type:"video/mp4", totalFrameCount:166},
-  { name:"seek-short.webm", type:"video/webm", totalFrameCount:8},
-  { name:"seek.webm", type:"video/webm", totalFrameCount:120},
-  { name:"320x240.ogv", type:"video/ogg", totalFrameCount:8},
-  { name:"av1.mp4", type:"video/mp4", totalFrameCount:24},
+  { name: "bipbop.mp4", type: "video/mp4", totalFrameCount: 297 },
+  { name: "gizmo.mp4", type: "video/mp4", totalFrameCount: 166 },
+  { name: "seek-short.webm", type: "video/webm", totalFrameCount: 8 },
+  { name: "seek.webm", type: "video/webm", totalFrameCount: 120 },
+  { name: "320x240.ogv", type: "video/ogg", totalFrameCount: 8 },
+  { name: "av1.mp4", type: "video/mp4", totalFrameCount: 24 },
 ];
 
 gSmallTests = gSmallTests.concat([
-  { name:"sample.3gp", type:"video/3gpp", duration:4.933 },
-  { name:"sample.3g2", type:"video/3gpp2", duration:4.933 }
+  { name: "sample.3gp", type: "video/3gpp", duration: 4.933 },
+  { name: "sample.3g2", type: "video/3gpp2", duration: 4.933 },
 ]);
 
 // Used by test_bug654550.html, for videoStats preference
 var gVideoTests = [
-  { name:"320x240.ogv", type:"video/ogg", width:320, height:240, duration:0.266 },
-  { name:"seek-short.webm", type:"video/webm", width:320, height:240, duration:0.23 },
-  { name:"bogus.duh", type:"bogus/duh" }
+  {
+    name: "320x240.ogv",
+    type: "video/ogg",
+    width: 320,
+    height: 240,
+    duration: 0.266,
+  },
+  {
+    name: "seek-short.webm",
+    type: "video/webm",
+    width: 320,
+    height: 240,
+    duration: 0.23,
+  },
+  { name: "bogus.duh", type: "bogus/duh" },
 ];
 
 // Temp hack for trackIDs and captureStream() -- bug 1215769
 var gLongerTests = [
-  { name:"seek.webm", type:"video/webm", width:320, height:240, duration:3.966 },
-  { name:"gizmo.mp4", type:"video/mp4", width:560, height:320, duration:5.56 },
+  {
+    name: "seek.webm",
+    type: "video/webm",
+    width: 320,
+    height: 240,
+    duration: 3.966,
+  },
+  {
+    name: "gizmo.mp4",
+    type: "video/mp4",
+    width: 560,
+    height: 320,
+    duration: 5.56,
+  },
 ];
 
 // Used by test_progress to ensure we get the correct progress information
 // during resource download.
 var gProgressTests = [
-  { name:"r11025_u8_c1.wav", type:"audio/x-wav", duration:1.0, size:11069 },
-  { name:"big-short.wav", type:"audio/x-wav", duration:1.11, size:12366 },
-  { name:"seek-short.ogv", type:"video/ogg", duration:1.03, size:79921 },
-  { name:"320x240.ogv", type:"video/ogg", width:320, height:240, duration:0.266, size:28942 },
-  { name:"seek-short.webm", type:"video/webm", duration:0.23, size:19267 },
-  { name:"gizmo-short.mp4", type:"video/mp4", duration:0.27, size:29905 },
-  { name:"bogus.duh", type:"bogus/duh" }
+  { name: "r11025_u8_c1.wav", type: "audio/x-wav", duration: 1.0, size: 11069 },
+  { name: "big-short.wav", type: "audio/x-wav", duration: 1.11, size: 12366 },
+  { name: "seek-short.ogv", type: "video/ogg", duration: 1.03, size: 79921 },
+  {
+    name: "320x240.ogv",
+    type: "video/ogg",
+    width: 320,
+    height: 240,
+    duration: 0.266,
+    size: 28942,
+  },
+  { name: "seek-short.webm", type: "video/webm", duration: 0.23, size: 19267 },
+  { name: "gizmo-short.mp4", type: "video/mp4", duration: 0.27, size: 29905 },
+  { name: "bogus.duh", type: "bogus/duh" },
 ];
 
 // Used by test_played.html
 var gPlayedTests = [
-  { name:"big-short.wav", type:"audio/x-wav", duration:1.11 },
-  { name:"seek-short.ogv", type:"video/ogg", duration:1.03 },
-  { name:"seek-short.webm", type:"video/webm", duration:0.23 },
-  { name:"gizmo-short.mp4", type:"video/mp4", duration:0.27 },
-  { name:"owl-short.mp3", type:"audio/mpeg", duration:0.52 },
-  { name:"very-short.mp3", type:"audio/mpeg", duration:0.07 },
+  { name: "big-short.wav", type: "audio/x-wav", duration: 1.11 },
+  { name: "seek-short.ogv", type: "video/ogg", duration: 1.03 },
+  { name: "seek-short.webm", type: "video/webm", duration: 0.23 },
+  { name: "gizmo-short.mp4", type: "video/mp4", duration: 0.27 },
+  { name: "owl-short.mp3", type: "audio/mpeg", duration: 0.52 },
+  { name: "very-short.mp3", type: "audio/mpeg", duration: 0.07 },
   // Disable vbr.mp3 to see if it reduces the error of AUDCLNT_E_CPUUSAGE_EXCEEDED.
   // See bug 1110922 comment 26.
   //{ name:"vbr.mp3", type:"audio/mpeg", duration:10.0 },
-  { name:"bug495794.ogg", type:"audio/ogg", duration:0.3 },
+  { name: "bug495794.ogg", type: "audio/ogg", duration: 0.3 },
 ];
 
-if (manifestNavigator().userAgent.includes("Windows") &&
-    manifestVideo().canPlayType('video/mp4; codecs="avc1.42E01E"')) {
-  gPlayedTests = gPlayedTests.concat({name: "red-46x48.mp4", type:"video/mp4", duration:1.00},
-                                     {name: "red-48x46.mp4", type:"video/mp4", duration:1.00});
+if (
+  manifestNavigator().userAgent.includes("Windows") &&
+  manifestVideo().canPlayType('video/mp4; codecs="avc1.42E01E"')
+) {
+  gPlayedTests = gPlayedTests.concat(
+    { name: "red-46x48.mp4", type: "video/mp4", duration: 1.0 },
+    { name: "red-48x46.mp4", type: "video/mp4", duration: 1.0 }
+  );
 }
 
 // Used by test_mozLoadFrom.  Need one test file per decoder backend, plus
 // anything for testing clone-specific bugs.
-var cloneKey = Math.floor(Math.random()*100000000);
+var cloneKey = Math.floor(Math.random() * 100000000);
 var gCloneTests = [
   // short-video is more like 1s, so if you load this twice you'll get an unexpected duration
-  { name:"dynamic_resource.sjs?key=" + cloneKey + "&res1=320x240.ogv&res2=short-video.ogv",
-    type:"video/ogg", duration:0.266 },
+  {
+    name:
+      "dynamic_resource.sjs?key=" +
+      cloneKey +
+      "&res1=320x240.ogv&res2=short-video.ogv",
+    type: "video/ogg",
+    duration: 0.266,
+  },
 ];
 
 // Used by test_play_twice.  Need one test file per decoder backend, plus
 // anything for testing bugs that occur when replying a played file.
 var gReplayTests = gSmallTests.concat([
-  { name:"bug533822.ogg", type:"audio/ogg" },
+  { name: "bug533822.ogg", type: "audio/ogg" },
 ]);
 
 // Used by test_paused_after_ended. Need one test file per decoder backend, plus
 // anything for testing bugs that occur when replying a played file.
 var gPausedAfterEndedTests = gSmallTests.concat([
-  { name:"r11025_u8_c1.wav", type:"audio/x-wav", duration:1.0 },
-  { name:"small-shot.ogg", type:"video/ogg", duration:0.276 }
+  { name: "r11025_u8_c1.wav", type: "audio/x-wav", duration: 1.0 },
+  { name: "small-shot.ogg", type: "video/ogg", duration: 0.276 },
 ]);
 
 // Test the mozHasAudio property, and APIs that detect different kinds of
 // tracks
 var gTrackTests = [
-  { name:"big-short.wav", type:"audio/x-wav", duration:1.11, size:12366, hasAudio:true, hasVideo:false },
-  { name:"320x240.ogv", type:"video/ogg", width:320, height:240, duration:0.266, size:28942, hasAudio:false, hasVideo:true },
-  { name:"short-video.ogv", type:"video/ogg", duration:1.081, hasAudio:true, hasVideo:true },
-  { name:"seek-short.webm", type:"video/webm", duration:0.23, size:19267, hasAudio:false, hasVideo:true },
-  { name:"flac-s24.flac", type:"audio/flac", duration:4.04, hasAudio:true, hasVideo:false },
-  { name:"bogus.duh", type:"bogus/duh" }
+  {
+    name: "big-short.wav",
+    type: "audio/x-wav",
+    duration: 1.11,
+    size: 12366,
+    hasAudio: true,
+    hasVideo: false,
+  },
+  {
+    name: "320x240.ogv",
+    type: "video/ogg",
+    width: 320,
+    height: 240,
+    duration: 0.266,
+    size: 28942,
+    hasAudio: false,
+    hasVideo: true,
+  },
+  {
+    name: "short-video.ogv",
+    type: "video/ogg",
+    duration: 1.081,
+    hasAudio: true,
+    hasVideo: true,
+  },
+  {
+    name: "seek-short.webm",
+    type: "video/webm",
+    duration: 0.23,
+    size: 19267,
+    hasAudio: false,
+    hasVideo: true,
+  },
+  {
+    name: "flac-s24.flac",
+    type: "audio/flac",
+    duration: 4.04,
+    hasAudio: true,
+    hasVideo: false,
+  },
+  { name: "bogus.duh", type: "bogus/duh" },
 ];
 
 var gClosingConnectionsTest = [
-  { name:"seek-short.ogv", type:"video/ogg", duration:1.03 },
+  { name: "seek-short.ogv", type: "video/ogg", duration: 1.03 },
 ];
 
 // Used by any media recorder test. Need one test file per decoder backend
 // currently supported by the media encoder.
 var gMediaRecorderTests = [
   // Duration should be greater than 500ms because we will record 2
   // time slices (250ms per slice)
-  { name:"detodos-recorder-test.opus", type:"audio/ogg; codecs=opus", duration:0.62 }
+  {
+    name: "detodos-recorder-test.opus",
+    type: "audio/ogg; codecs=opus",
+    duration: 0.62,
+  },
 ];
 
 // Used by video media recorder tests
 var gMediaRecorderVideoTests = [
-  { name:"seek-short.webm", type:"video/webm", width:320, height:240, duration:0.23 },
+  {
+    name: "seek-short.webm",
+    type: "video/webm",
+    width: 320,
+    height: 240,
+    duration: 0.23,
+  },
 ];
 
 // These are files that we want to make sure we can play through.  We can
 // also check metadata.  Put files of the same type together in this list so if
 // something crashes we have some idea of which backend is responsible.
 // Used by test_playback, which expects no error event and one ended event.
 var gPlayTests = [
   // Test playback of a WebM file with vp9 video
-  { name:"vp9cake-short.webm", type:"video/webm", duration:1.00 },
+  { name: "vp9cake-short.webm", type: "video/webm", duration: 1.0 },
   // 8-bit samples
-  { name:"r11025_u8_c1.wav", type:"audio/x-wav", duration:1.0 },
+  { name: "r11025_u8_c1.wav", type: "audio/x-wav", duration: 1.0 },
   // 8-bit samples, file is truncated
-  { name:"r11025_u8_c1_trunc.wav", type:"audio/x-wav", duration:1.8 },
+  { name: "r11025_u8_c1_trunc.wav", type: "audio/x-wav", duration: 1.8 },
   // file has trailing non-PCM data
-  { name:"r11025_s16_c1_trailing.wav", type:"audio/x-wav", duration:1.0 },
+  { name: "r11025_s16_c1_trailing.wav", type: "audio/x-wav", duration: 1.0 },
   // file with list chunk
-  { name:"r16000_u8_c1_list.wav", type:"audio/x-wav", duration:4.2 },
+  { name: "r16000_u8_c1_list.wav", type: "audio/x-wav", duration: 4.2 },
   // file with 2 extra bytes of metadata
-  { name:"16bit_wave_extrametadata.wav", type:"audio/x-wav", duration:1.108 },
+  {
+    name: "16bit_wave_extrametadata.wav",
+    type: "audio/x-wav",
+    duration: 1.108,
+  },
   // 24-bit samples
-  { name:"wavedata_s24.wav", type:"audio/x-wav", duration:1.0 },
+  { name: "wavedata_s24.wav", type: "audio/x-wav", duration: 1.0 },
   // aLaw compressed wave file
-  { name:"wavedata_alaw.wav", type:"audio/x-wav", duration:1.0 },
+  { name: "wavedata_alaw.wav", type: "audio/x-wav", duration: 1.0 },
   // uLaw compressed wave file
-  { name:"wavedata_ulaw.wav", type:"audio/x-wav", duration:1.0 },
+  { name: "wavedata_ulaw.wav", type: "audio/x-wav", duration: 1.0 },
   // Data length 0xFFFFFFFF
-  { name:"bug1301226.wav", type:"audio/x-wav", duration:0.003673 },
+  { name: "bug1301226.wav", type: "audio/x-wav", duration: 0.003673 },
   // Data length 0xFFFFFFFF and odd chunk lengths.
-  { name:"bug1301226-odd.wav", type:"audio/x-wav", duration:0.003673 },
+  { name: "bug1301226-odd.wav", type: "audio/x-wav", duration: 0.003673 },
 
   // Ogg stream without eof marker
-  { name:"bug461281.ogg", type:"application/ogg", duration:2.208 },
+  { name: "bug461281.ogg", type: "application/ogg", duration: 2.208 },
 
   // oggz-chop stream
-  { name:"bug482461.ogv", type:"video/ogg", duration:4.34 },
+  { name: "bug482461.ogv", type: "video/ogg", duration: 4.34 },
   // Theora only oggz-chop stream
-  { name:"bug482461-theora.ogv", type:"video/ogg", duration:4.138 },
+  { name: "bug482461-theora.ogv", type: "video/ogg", duration: 4.138 },
   // With first frame a "duplicate" (empty) frame.
-  { name:"bug500311.ogv", type:"video/ogg", duration:1.96, contentDuration:1.958 },
+  {
+    name: "bug500311.ogv",
+    type: "video/ogg",
+    duration: 1.96,
+    contentDuration: 1.958,
+  },
   // Small audio file
-  { name:"small-shot.ogg", type:"audio/ogg", duration:0.276 },
+  { name: "small-shot.ogg", type: "audio/ogg", duration: 0.276 },
   // More audio in file than video.
-  { name:"short-video.ogv", type:"video/ogg", duration:1.081 },
+  { name: "short-video.ogv", type: "video/ogg", duration: 1.081 },
   // First Theora data packet is zero bytes.
-  { name:"bug504613.ogv", type:"video/ogg", duration:Number.NaN },
+  { name: "bug504613.ogv", type: "video/ogg", duration: Number.NaN },
   // Multiple audio streams.
-  { name:"bug516323.ogv", type:"video/ogg", duration:4.208 },
+  { name: "bug516323.ogv", type: "video/ogg", duration: 4.208 },
   // oggz-chop with non-keyframe as first frame
-  { name:"bug556821.ogv", type:"video/ogg", duration:2.936, contentDuration:2.903 },
+  {
+    name: "bug556821.ogv",
+    type: "video/ogg",
+    duration: 2.936,
+    contentDuration: 2.903,
+  },
 
   // Encoded with vorbis beta1, includes unusually sized codebooks
-  { name:"beta-phrasebook.ogg", type:"audio/ogg", duration:4.01 },
+  { name: "beta-phrasebook.ogg", type: "audio/ogg", duration: 4.01 },
   // Small file, only 1 frame with audio only.
-  { name:"bug520493.ogg", type:"audio/ogg", duration:0.458 },
+  { name: "bug520493.ogg", type: "audio/ogg", duration: 0.458 },
   // Small file with vorbis comments with 0 length values and names.
-  { name:"bug520500.ogg", type:"audio/ogg", duration:0.123 },
+  { name: "bug520500.ogg", type: "audio/ogg", duration: 0.123 },
 
   // Various weirdly formed Ogg files
-  { name:"bug499519.ogv", type:"video/ogg", duration:0.24, contentDuration:0.22 },
-  { name:"bug506094.ogv", type:"video/ogg", duration:0 },
-  { name:"bug498855-1.ogv", type:"video/ogg", duration:0.24 },
-  { name:"bug498855-2.ogv", type:"video/ogg", duration:0.24 },
-  { name:"bug498855-3.ogv", type:"video/ogg", duration:0.24 },
-  { name:"bug504644.ogv", type:"video/ogg", duration:1.6, contentDuration:1.52 },
-  { name:"chain.ogv", type:"video/ogg", duration:Number.NaN, contentDuration:0.266 },
-  { name:"bug523816.ogv", type:"video/ogg", duration:0.766, contentDuration:0 },
-  { name:"bug495129.ogv", type:"video/ogg", duration:2.41 },
-  { name:"bug498380.ogv", type:"video/ogg", duration:0.7663, contentDuration:0 },
-  { name:"bug495794.ogg", type:"audio/ogg", duration:0.3 },
-  { name:"bug557094.ogv", type:"video/ogg", duration:0.24 },
-  { name:"multiple-bos.ogg", type:"video/ogg", duration:0.431 },
-  { name:"audio-overhang.ogg", type:"video/ogg", duration:2.3 },
-  { name:"video-overhang.ogg", type:"video/ogg", duration:3.966 },
+  {
+    name: "bug499519.ogv",
+    type: "video/ogg",
+    duration: 0.24,
+    contentDuration: 0.22,
+  },
+  { name: "bug506094.ogv", type: "video/ogg", duration: 0 },
+  { name: "bug498855-1.ogv", type: "video/ogg", duration: 0.24 },
+  { name: "bug498855-2.ogv", type: "video/ogg", duration: 0.24 },
+  { name: "bug498855-3.ogv", type: "video/ogg", duration: 0.24 },
+  {
+    name: "bug504644.ogv",
+    type: "video/ogg",
+    duration: 1.6,
+    contentDuration: 1.52,
+  },
+  {
+    name: "chain.ogv",
+    type: "video/ogg",
+    duration: Number.NaN,
+    contentDuration: 0.266,
+  },
+  {
+    name: "bug523816.ogv",
+    type: "video/ogg",
+    duration: 0.766,
+    contentDuration: 0,
+  },
+  { name: "bug495129.ogv", type: "video/ogg", duration: 2.41 },
+  {
+    name: "bug498380.ogv",
+    type: "video/ogg",
+    duration: 0.7663,
+    contentDuration: 0,
+  },
+  { name: "bug495794.ogg", type: "audio/ogg", duration: 0.3 },
+  { name: "bug557094.ogv", type: "video/ogg", duration: 0.24 },
+  { name: "multiple-bos.ogg", type: "video/ogg", duration: 0.431 },
+  { name: "audio-overhang.ogg", type: "video/ogg", duration: 2.3 },
+  { name: "video-overhang.ogg", type: "video/ogg", duration: 3.966 },
 
   // bug461281.ogg with the middle second chopped out.
-  { name:"audio-gaps.ogg", type:"audio/ogg", duration:2.208 },
+  { name: "audio-gaps.ogg", type: "audio/ogg", duration: 2.208 },
 
   // Test playback/metadata work after a redirect
-  { name:"redirect.sjs?domain=mochi.test:8888&file=320x240.ogv",
-    type:"video/ogg", duration:0.266 },
+  {
+    name: "redirect.sjs?domain=mochi.test:8888&file=320x240.ogv",
+    type: "video/ogg",
+    duration: 0.266,
+  },
 
   // Test playback of a webm file
-  { name:"seek-short.webm", type:"video/webm", duration:0.23 },
+  { name: "seek-short.webm", type: "video/webm", duration: 0.23 },
 
   // Test playback of a webm file with 'matroska' doctype
-  { name:"bug1377278.webm", type:"video/webm", duration:4.0 },
+  { name: "bug1377278.webm", type: "video/webm", duration: 4.0 },
 
   // Test playback of a WebM file with non-zero start time.
-  { name:"split.webm", type:"video/webm", duration:1.967 },
+  { name: "split.webm", type: "video/webm", duration: 1.967 },
 
   // Test playback of a WebM file with resolution changes.
-  { name:"resolution-change.webm", type:"video/webm", duration:6.533 },
+  { name: "resolution-change.webm", type: "video/webm", duration: 6.533 },
 
   // A really short, low sample rate, single channel file. This tests whether
   // we can handle playing files when only push very little audio data to the
   // hardware.
-  { name:"spacestorm-1000Hz-100ms.ogg", type:"audio/ogg", duration:0.099 },
+  { name: "spacestorm-1000Hz-100ms.ogg", type: "audio/ogg", duration: 0.099 },
 
   // Opus data in an ogg container
-  { name:"detodos-short.opus", type:"audio/ogg; codecs=opus", duration:0.22, contentDuration:0.2135 },
+  {
+    name: "detodos-short.opus",
+    type: "audio/ogg; codecs=opus",
+    duration: 0.22,
+    contentDuration: 0.2135,
+  },
   // Opus data in a webm container
-  { name:"detodos-short.webm", type:"audio/webm; codecs=opus", duration:0.26, contentDuration:0.2535 },
+  {
+    name: "detodos-short.webm",
+    type: "audio/webm; codecs=opus",
+    duration: 0.26,
+    contentDuration: 0.2535,
+  },
   // Opus in webm channel mapping=2 sample file
-  { name:"opus-mapping2.webm", type:"audio/webm; codecs=opus", duration:10.01, contentDuration:9.99 },
-  { name:"bug1066943.webm", type:"audio/webm; codecs=opus", duration:1.383 },
+  {
+    name: "opus-mapping2.webm",
+    type: "audio/webm; codecs=opus",
+    duration: 10.01,
+    contentDuration: 9.99,
+  },
+  { name: "bug1066943.webm", type: "audio/webm; codecs=opus", duration: 1.383 },
 
   // Multichannel Opus in an ogg container
-  { name:"test-1-mono.opus", type:"audio/ogg; codecs=opus", duration:1.044 },
-  { name:"test-2-stereo.opus", type:"audio/ogg; codecs=opus", duration:2.925 },
-  { name:"test-3-LCR.opus", type:"audio/ogg; codecs=opus", duration:4.214 },
-  { name:"test-4-quad.opus", type:"audio/ogg; codecs=opus", duration:6.234 },
-  { name:"test-5-5.0.opus", type:"audio/ogg; codecs=opus", duration:7.558 },
-  { name:"test-6-5.1.opus", type:"audio/ogg; codecs=opus", duration:10.333 },
-  { name:"test-7-6.1.opus", type:"audio/ogg; codecs=opus", duration:11.690 },
-  { name:"test-8-7.1.opus", type:"audio/ogg; codecs=opus", duration:13.478 },
+  { name: "test-1-mono.opus", type: "audio/ogg; codecs=opus", duration: 1.044 },
+  {
+    name: "test-2-stereo.opus",
+    type: "audio/ogg; codecs=opus",
+    duration: 2.925,
+  },
+  { name: "test-3-LCR.opus", type: "audio/ogg; codecs=opus", duration: 4.214 },
+  { name: "test-4-quad.opus", type: "audio/ogg; codecs=opus", duration: 6.234 },
+  { name: "test-5-5.0.opus", type: "audio/ogg; codecs=opus", duration: 7.558 },
+  { name: "test-6-5.1.opus", type: "audio/ogg; codecs=opus", duration: 10.333 },
+  { name: "test-7-6.1.opus", type: "audio/ogg; codecs=opus", duration: 11.69 },
+  { name: "test-8-7.1.opus", type: "audio/ogg; codecs=opus", duration: 13.478 },
 
-  { name:"gizmo-short.mp4", type:"video/mp4", duration:0.27, contentDuration:0.267 },
+  {
+    name: "gizmo-short.mp4",
+    type: "video/mp4",
+    duration: 0.27,
+    contentDuration: 0.267,
+  },
   // Test playback of a MP4 file with a non-zero start time (and audio starting
   // a second later).
-  { name:"bipbop-lateaudio.mp4", type:"video/mp4" },
+  { name: "bipbop-lateaudio.mp4", type: "video/mp4" },
   // Ambisonics AAC, requires AAC extradata to be set when creating decoder (see bug 1431169)
   // Also test 4.0 decoding.
-  { name:"ambisonics.mp4", type:"audio/mp4", duration:16.48 },
+  { name: "ambisonics.mp4", type: "audio/mp4", duration: 16.48 },
   // Opus in MP4 channel mapping=0 sample file (content shorter due to preskip)
-  { name:"opus-sample.mp4", type:"audio/mp4; codecs=opus", duration:10.92, contentDuration:10.09 },
+  {
+    name: "opus-sample.mp4",
+    type: "audio/mp4; codecs=opus",
+    duration: 10.92,
+    contentDuration: 10.09,
+  },
   // Opus in MP4 channel mapping=2 sample file
-  { name:"opus-mapping2.mp4", type:"audio/mp4; codecs=opus", duration:10.0 },
+  { name: "opus-mapping2.mp4", type: "audio/mp4; codecs=opus", duration: 10.0 },
 
-  { name:"small-shot.m4a", type:"audio/mp4", duration:0.29 },
-  { name:"small-shot.mp3", type:"audio/mpeg", duration:0.27 },
-  { name:"owl.mp3", type:"audio/mpeg", duration:3.343 },
+  { name: "small-shot.m4a", type: "audio/mp4", duration: 0.29 },
+  { name: "small-shot.mp3", type: "audio/mpeg", duration: 0.27 },
+  { name: "owl.mp3", type: "audio/mpeg", duration: 3.343 },
   // owl.mp3 as above, but with something funny going on in the ID3v2 tag
   // that caused DirectShow to fail.
-  { name:"owl-funny-id3.mp3", type:"audio/mpeg", duration:3.343 },
+  { name: "owl-funny-id3.mp3", type: "audio/mpeg", duration: 3.343 },
   // owl.mp3 as above, but with something even funnier going on in the ID3v2 tag
   // that caused DirectShow to fail.
-  { name:"owl-funnier-id3.mp3", type:"audio/mpeg", duration:3.343 },
+  { name: "owl-funnier-id3.mp3", type: "audio/mpeg", duration: 3.343 },
   // One second of silence with ~140KB of ID3 tags. Usually when the first MP3
   // frame is at such a high offset into the file, MP3FrameParser will give up
   // and report that the stream is not MP3. However, it does not count ID3 tags
   // in that offset. This test case makes sure that ID3 exclusion holds.
-  { name:"huge-id3.mp3", type:"audio/mpeg", duration:1.00 },
+  { name: "huge-id3.mp3", type: "audio/mpeg", duration: 1.0 },
   // A truncated VBR MP3 with just enough frames to keep most decoders happy.
   // The Xing header reports the length of the file to be around 10 seconds, but
   // there is really only one second worth of data. We want MP3FrameParser to
   // trust the header, so this should be reported as 10 seconds.
-  { name:"vbr-head.mp3", type:"audio/mpeg", duration:10.00, contentDuration:1.019 },
+  {
+    name: "vbr-head.mp3",
+    type: "audio/mpeg",
+    duration: 10.0,
+    contentDuration: 1.019,
+  },
 
   // A flac file where the STREAMINFO block was removed.
   // It is necessary to parse the file to find an audio frame instead.
-  { name:"flac-noheader-s16.flac", type:"audio/flac", duration:4.0 },
-  { name:"flac-s24.flac", type:"audio/flac", duration:4.04 },
-  { name:"flac-sample.mp4", type:"audio/mp4; codecs=flac", duration:4.95, contentDuration:5.03 },
+  { name: "flac-noheader-s16.flac", type: "audio/flac", duration: 4.0 },
+  { name: "flac-s24.flac", type: "audio/flac", duration: 4.04 },
+  {
+    name: "flac-sample.mp4",
+    type: "audio/mp4; codecs=flac",
+    duration: 4.95,
+    contentDuration: 5.03,
+  },
   // Ogg with theora video and flac audio.
-  { name:"A4.ogv", type:"video/ogg", width:320, height:240, duration:3.13 },
+  {
+    name: "A4.ogv",
+    type: "video/ogg",
+    width: 320,
+    height: 240,
+    duration: 3.13,
+  },
 
   // Invalid file
-  { name:"bogus.duh", type:"bogus/duh", duration:Number.NaN },
+  { name: "bogus.duh", type: "bogus/duh", duration: Number.NaN },
 ];
 
-const win32 = SpecialPowers.Services.appinfo.OS == "WINNT" &&
-              !SpecialPowers.Services.appinfo.is64Bit;
+const win32 =
+  SpecialPowers.Services.appinfo.OS == "WINNT" &&
+  !SpecialPowers.Services.appinfo.is64Bit;
 if (!win32) {
-  gPlayTests.push({ name: "av1.mp4", type:"video/mp4", duration:1.00 });
+  gPlayTests.push({ name: "av1.mp4", type: "video/mp4", duration: 1.0 });
 }
 
 var gSeekToNextFrameTests = [
   // Test playback of a WebM file with vp9 video
-  { name:"vp9-short.webm", type:"video/webm", duration:0.20 },
-  { name:"vp9cake-short.webm", type:"video/webm", duration:1.00 },
+  { name: "vp9-short.webm", type: "video/webm", duration: 0.2 },
+  { name: "vp9cake-short.webm", type: "video/webm", duration: 1.0 },
   // oggz-chop stream
-  { name:"bug482461.ogv", type:"video/ogg", duration:4.34 },
+  { name: "bug482461.ogv", type: "video/ogg", duration: 4.34 },
   // Theora only oggz-chop stream
-  { name:"bug482461-theora.ogv", type:"video/ogg", duration:4.138 },
+  { name: "bug482461-theora.ogv", type: "video/ogg", duration: 4.138 },
   // With first frame a "duplicate" (empty) frame.
-  { name:"bug500311.ogv", type:"video/ogg", duration:1.96 },
+  { name: "bug500311.ogv", type: "video/ogg", duration: 1.96 },
 
   // More audio in file than video.
-  { name:"short-video.ogv", type:"video/ogg", duration:1.081 },
+  { name: "short-video.ogv", type: "video/ogg", duration: 1.081 },
   // First Theora data packet is zero bytes.
-  { name:"bug504613.ogv", type:"video/ogg", duration:Number.NaN },
+  { name: "bug504613.ogv", type: "video/ogg", duration: Number.NaN },
   // Multiple audio streams.
-  { name:"bug516323.ogv", type:"video/ogg", duration:4.208 },
+  { name: "bug516323.ogv", type: "video/ogg", duration: 4.208 },
   // oggz-chop with non-keyframe as first frame
-  { name:"bug556821.ogv", type:"video/ogg", duration:2.936 },
+  { name: "bug556821.ogv", type: "video/ogg", duration: 2.936 },
   // Various weirdly formed Ogg files
-  { name:"bug498855-1.ogv", type:"video/ogg", duration:0.24 },
-  { name:"bug498855-2.ogv", type:"video/ogg", duration:0.24 },
-  { name:"bug498855-3.ogv", type:"video/ogg", duration:0.24 },
-  { name:"bug504644.ogv", type:"video/ogg", duration:1.6 },
+  { name: "bug498855-1.ogv", type: "video/ogg", duration: 0.24 },
+  { name: "bug498855-2.ogv", type: "video/ogg", duration: 0.24 },
+  { name: "bug498855-3.ogv", type: "video/ogg", duration: 0.24 },
+  { name: "bug504644.ogv", type: "video/ogg", duration: 1.6 },
+
+  { name: "bug523816.ogv", type: "video/ogg", duration: 0.766 },
 
-  { name:"bug523816.ogv", type:"video/ogg", duration:0.766 },
-
-  { name:"bug498380.ogv", type:"video/ogg", duration:0.2 },
-  { name:"bug557094.ogv", type:"video/ogg", duration:0.24 },
-  { name:"multiple-bos.ogg", type:"video/ogg", duration:0.431 },
+  { name: "bug498380.ogv", type: "video/ogg", duration: 0.2 },
+  { name: "bug557094.ogv", type: "video/ogg", duration: 0.24 },
+  { name: "multiple-bos.ogg", type: "video/ogg", duration: 0.431 },
   // Test playback/metadata work after a redirect
-  { name:"redirect.sjs?domain=mochi.test:8888&file=320x240.ogv",
-    type:"video/ogg", duration:0.266 },
+  {
+    name: "redirect.sjs?domain=mochi.test:8888&file=320x240.ogv",
+    type: "video/ogg",
+    duration: 0.266,
+  },
   // Test playback of a webm file
-  { name:"seek-short.webm", type:"video/webm", duration:0.23 },
+  { name: "seek-short.webm", type: "video/webm", duration: 0.23 },
   // Test playback of a WebM file with non-zero start time.
-  { name:"split.webm", type:"video/webm", duration:1.967 },
+  { name: "split.webm", type: "video/webm", duration: 1.967 },
 
-  { name:"gizmo-short.mp4", type:"video/mp4", duration:0.27 },
+  { name: "gizmo-short.mp4", type: "video/mp4", duration: 0.27 },
 
   // Test playback of a MP4 file with a non-zero start time (and audio starting
   // a second later).
-  { name:"bipbop-lateaudio.mp4", type:"video/mp4" },
+  { name: "bipbop-lateaudio.mp4", type: "video/mp4" },
 ];
 
 // A file for each type we can support.
 var gSnifferTests = [
-  { name:"big.wav", type:"audio/x-wav", duration:9.278982, size:102444 },
-  { name:"320x240.ogv", type:"video/ogg", width:320, height:240, duration:0.233, size:28942 },
-  { name:"seek.webm", type:"video/webm", duration:3.966, size:215529 },
-  { name:"gizmo.mp4", type:"video/mp4", duration:5.56, size:383631 },
+  { name: "big.wav", type: "audio/x-wav", duration: 9.278982, size: 102444 },
+  {
+    name: "320x240.ogv",
+    type: "video/ogg",
+    width: 320,
+    height: 240,
+    duration: 0.233,
+    size: 28942,
+  },
+  { name: "seek.webm", type: "video/webm", duration: 3.966, size: 215529 },
+  { name: "gizmo.mp4", type: "video/mp4", duration: 5.56, size: 383631 },
   // A mp3 file with id3 tags.
-  { name:"id3tags.mp3", type:"audio/mpeg", duration:0.28, size:3530},
-  { name:"bogus.duh", type:"bogus/duh" }
+  { name: "id3tags.mp3", type: "audio/mpeg", duration: 0.28, size: 3530 },
+  { name: "bogus.duh", type: "bogus/duh" },
 ];
 
 // Files that contain resolution changes
 var gResolutionChangeTests = [
-  { name:"resolution-change.webm", type:"video/webm", duration:6.533 },
+  { name: "resolution-change.webm", type: "video/webm", duration: 6.533 },
 ];
 
 // Files we must reject as invalid.
 var gInvalidTests = [
-  { name:"invalid-m0c0.opus", type:"audio/ogg; codecs=opus"},
-  { name:"invalid-m0c3.opus", type:"audio/ogg; codecs=opus"},
-  { name:"invalid-m1c0.opus", type:"audio/ogg; codecs=opus"},
-  { name:"invalid-m1c9.opus", type:"audio/ogg; codecs=opus"},
-  { name:"invalid-m2c0.opus", type:"audio/ogg; codecs=opus"},
-  { name:"invalid-m2c1.opus", type:"audio/ogg; codecs=opus"},
-  { name:"invalid-cmap-short.opus", type:"audio/ogg; codecs=opus"},
-  { name:"invalid-cmap-s0c0.opus", type:"audio/ogg; codecs=opus"},
-  { name:"invalid-cmap-s0c2.opus", type:"audio/ogg; codecs=opus"},
-  { name:"invalid-cmap-s1c2.opus", type:"audio/ogg; codecs=opus"},
-  { name:"invalid-preskip.webm", type:"audio/webm; codecs=opus"},
+  { name: "invalid-m0c0.opus", type: "audio/ogg; codecs=opus" },
+  { name: "invalid-m0c3.opus", type: "audio/ogg; codecs=opus" },
+  { name: "invalid-m1c0.opus", type: "audio/ogg; codecs=opus" },
+  { name: "invalid-m1c9.opus", type: "audio/ogg; codecs=opus" },
+  { name: "invalid-m2c0.opus", type: "audio/ogg; codecs=opus" },
+  { name: "invalid-m2c1.opus", type: "audio/ogg; codecs=opus" },
+  { name: "invalid-cmap-short.opus", type: "audio/ogg; codecs=opus" },
+  { name: "invalid-cmap-s0c0.opus", type: "audio/ogg; codecs=opus" },
+  { name: "invalid-cmap-s0c2.opus", type: "audio/ogg; codecs=opus" },
+  { name: "invalid-cmap-s1c2.opus", type: "audio/ogg; codecs=opus" },
+  { name: "invalid-preskip.webm", type: "audio/webm; codecs=opus" },
 ];
 
 var gInvalidPlayTests = [
-  { name:"invalid-excess_discard.webm", type:"audio/webm; codecs=opus"},
-  { name:"invalid-excess_neg_discard.webm", type:"audio/webm; codecs=opus"},
-  { name:"invalid-neg_discard.webm", type:"audio/webm; codecs=opus"},
-  { name:"invalid-discard_on_multi_blocks.webm", type:"audio/webm; codecs=opus"},
+  { name: "invalid-excess_discard.webm", type: "audio/webm; codecs=opus" },
+  { name: "invalid-excess_neg_discard.webm", type: "audio/webm; codecs=opus" },
+  { name: "invalid-neg_discard.webm", type: "audio/webm; codecs=opus" },
+  {
+    name: "invalid-discard_on_multi_blocks.webm",
+    type: "audio/webm; codecs=opus",
+  },
 ];
 
 // Files to check different cases of ogg skeleton information.
 // sample-fisbone-skeleton4.ogv
 // - Skeleton v4, w/ Content-Type,Role,Name,Language,Title for both theora/vorbis
 // sample-fisbone-wrong-header.ogv
 // - Skeleton v4, wrong message field sequence for vorbis
 // multiple-bos-more-header-fields.ogg
 // - Skeleton v3, w/ Content-Type,Role,Name,Language,Title for both theora/vorbis
 // seek-short.ogv
 // - No skeleton, but theora
 // audio-gaps-short.ogg
 // - No skeleton, but vorbis
 var gMultitrackInfoOggPlayList = [
-  { name:"sample-fisbone-skeleton4.ogv", type:"video/ogg", duration:1.00 },
-  { name:"sample-fisbone-wrong-header.ogv", type:"video/ogg", duration:1.00 },
-  { name:"multiple-bos-more-header-fileds.ogg", type:"video/ogg", duration:0.431 },
-  { name:"seek-short.ogv", type:"video/ogg", duration:1.03 },
-  { name:"audio-gaps-short.ogg", type:"audio/ogg", duration:0.50 }
+  { name: "sample-fisbone-skeleton4.ogv", type: "video/ogg", duration: 1.0 },
+  { name: "sample-fisbone-wrong-header.ogv", type: "video/ogg", duration: 1.0 },
+  {
+    name: "multiple-bos-more-header-fileds.ogg",
+    type: "video/ogg",
+    duration: 0.431,
+  },
+  { name: "seek-short.ogv", type: "video/ogg", duration: 1.03 },
+  { name: "audio-gaps-short.ogg", type: "audio/ogg", duration: 0.5 },
 ];
 // Pre-parsed results of gMultitrackInfoOggPlayList.
 var gOggTrackInfoResults = {
-  "sample-fisbone-skeleton4.ogv" : {
-    "audio_id":" audio_1",
-    "audio_kind":"main",
-    "audio_language":" en-US",
-    "audio_label":" Audio track for test",
-    "video_id":" video_1",
-    "video_kind":"main",
-    "video_language":" fr",
-    "video_label":" Video track for test"
+  "sample-fisbone-skeleton4.ogv": {
+    audio_id: " audio_1",
+    audio_kind: "main",
+    audio_language: " en-US",
+    audio_label: " Audio track for test",
+    video_id: " video_1",
+    video_kind: "main",
+    video_language: " fr",
+    video_label: " Video track for test",
   },
-  "sample-fisbone-wrong-header.ogv" : {
-    "audio_id":"1",
-    "audio_kind":"main",
-    "audio_language":"",
-    "audio_label":"",
-    "video_id":" video_1",
-    "video_kind":"main",
-    "video_language":" fr",
-    "video_label":" Video track for test"
+  "sample-fisbone-wrong-header.ogv": {
+    audio_id: "1",
+    audio_kind: "main",
+    audio_language: "",
+    audio_label: "",
+    video_id: " video_1",
+    video_kind: "main",
+    video_language: " fr",
+    video_label: " Video track for test",
   },
-  "multiple-bos-more-header-fileds.ogg" : {
-    "audio_id":"1",
-    "audio_kind":"main",
-    "audio_language":"",
-    "audio_label":"",
-    "video_id":"2",
-    "video_kind":"main",
-    "video_language":"",
-    "video_label":""
+  "multiple-bos-more-header-fileds.ogg": {
+    audio_id: "1",
+    audio_kind: "main",
+    audio_language: "",
+    audio_label: "",
+    video_id: "2",
+    video_kind: "main",
+    video_language: "",
+    video_label: "",
   },
-  "seek-short.ogv" : {
-    "video_id":"2",
-    "video_kind":"main",
-    "video_language":"",
-    "video_label":""
+  "seek-short.ogv": {
+    video_id: "2",
+    video_kind: "main",
+    video_language: "",
+    video_label: "",
   },
-  "audio-gaps-short.ogg" : {
-    "audio_id":"1",
-    "audio_kind":"main",
-    "audio_language":"",
-    "audio_label":""
-  }
+  "audio-gaps-short.ogg": {
+    audio_id: "1",
+    audio_kind: "main",
+    audio_language: "",
+    audio_label: "",
+  },
 };
 
 // Returns a promise that resolves to a function that converts
 // relative paths to absolute, to test loading files from file: URIs.
 // Optionally checks whether the file actually exists on disk at the location
 // we've specified.
 function makeAbsolutePathConverter() {
-  const url = SimpleTest.getTestFileURL('chromeHelper.js');
+  const url = SimpleTest.getTestFileURL("chromeHelper.js");
   const script = SpecialPowers.loadChromeScript(url);
   return new Promise((resolve, reject) => {
-    script.addMessageListener('media-test:cwd', cwd => {
+    script.addMessageListener("media-test:cwd", cwd => {
       if (!cwd) {
-	ok(false, "Failed to find path to test files");
+        ok(false, "Failed to find path to test files");
       }
 
       resolve((path, mustExist) => {
-	// android mochitest doesn't support file://
-	if (manifestNavigator().appVersion.includes("Android"))
-	  return path;
+        // android mochitest doesn't support file://
+        if (manifestNavigator().appVersion.includes("Android")) {
+          return path;
+        }
 
-	const { Ci, Cc } = SpecialPowers;
-	var f = Cc["@mozilla.org/file/local;1"]
-            .createInstance(Ci.nsIFile);
-	f.initWithPath(cwd);
-	var split = path.split("/");
-	for(var i = 0; i < split.length; ++i) {
-	  f.append(split[i]);
-	}
-	if (mustExist && !f.exists()) {
-	  ok(false, "We expected '" + path + "' to exist, but it doesn't!");
-	}
-	return f.path;
+        const { Ci, Cc } = SpecialPowers;
+        var f = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
+        f.initWithPath(cwd);
+        var split = path.split("/");
+        for (var i = 0; i < split.length; ++i) {
+          f.append(split[i]);
+        }
+        if (mustExist && !f.exists()) {
+          ok(false, "We expected '" + path + "' to exist, but it doesn't!");
+        }
+        return f.path;
       });
     });
-    script.sendAsyncMessage('media-test:getcwd');
+    script.sendAsyncMessage("media-test:getcwd");
   });
 }
 
 // Returns true if two TimeRanges are equal, false otherwise
 function range_equals(r1, r2) {
   if (r1.length != r2.length) {
     return false;
   }
@@ -518,1171 +745,1265 @@ function range_equals(r1, r2) {
 }
 
 // These are URIs to files that we use to check that we don't leak any state
 // or other information such that script can determine stuff about a user's
 // environment. Used by test_info_leak.
 function makeInfoLeakTests() {
   return makeAbsolutePathConverter().then(fileUriToSrc => [
     {
-      type: 'video/ogg',
+      type: "video/ogg",
       src: fileUriToSrc("tests/dom/media/test/320x240.ogv", true),
-    },{
-      type: 'video/ogg',
+    },
+    {
+      type: "video/ogg",
       src: fileUriToSrc("tests/dom/media/test/404.ogv", false),
-    }, {
-      type: 'audio/x-wav',
+    },
+    {
+      type: "audio/x-wav",
       src: fileUriToSrc("tests/dom/media/test/r11025_s16_c1.wav", true),
-    }, {
-      type: 'audio/x-wav',
+    },
+    {
+      type: "audio/x-wav",
       src: fileUriToSrc("tests/dom/media/test/404.wav", false),
-    }, {
-      type: 'audio/ogg',
+    },
+    {
+      type: "audio/ogg",
       src: fileUriToSrc("tests/dom/media/test/bug461281.ogg", true),
-    }, {
-      type: 'audio/ogg',
+    },
+    {
+      type: "audio/ogg",
       src: fileUriToSrc("tests/dom/media/test/404.ogg", false),
-    }, {
-      type: 'video/webm',
+    },
+    {
+      type: "video/webm",
       src: fileUriToSrc("tests/dom/media/test/seek.webm", true),
-    }, {
-      type: 'video/webm',
+    },
+    {
+      type: "video/webm",
       src: fileUriToSrc("tests/dom/media/test/404.webm", false),
-    }, {
-      type: 'video/ogg',
-      src: 'http://localhost/404.ogv',
-    }, {
-      type: 'audio/x-wav',
-      src: 'http://localhost/404.wav',
-    }, {
-      type: 'video/webm',
-      src: 'http://localhost/404.webm',
-    }, {
-      type: 'video/ogg',
-      src: 'http://example.com/tests/dom/media/test/test_info_leak.html'
-    }, {
-      type: 'audio/ogg',
-      src: 'http://example.com/tests/dom/media/test/test_info_leak.html'
-    }
+    },
+    {
+      type: "video/ogg",
+      src: "http://localhost/404.ogv",
+    },
+    {
+      type: "audio/x-wav",
+      src: "http://localhost/404.wav",
+    },
+    {
+      type: "video/webm",
+      src: "http://localhost/404.webm",
+    },
+    {
+      type: "video/ogg",
+      src: "http://example.com/tests/dom/media/test/test_info_leak.html",
+    },
+    {
+      type: "audio/ogg",
+      src: "http://example.com/tests/dom/media/test/test_info_leak.html",
+    },
   ]);
 }
 
 // These are files that must fire an error during load or playback, and do not
 // cause a crash. Used by test_playback_errors, which expects one error event
 // and no ended event. Put files of the same type together in this list so if
 // something crashes we have some idea of which backend is responsible.
 var gErrorTests = [
-  { name:"bogus.wav", type:"audio/x-wav" },
-  { name:"bogus.ogv", type:"video/ogg" },
-  { name:"448636.ogv", type:"video/ogg" },
-  { name:"bug504843.ogv", type:"video/ogg" },
-  { name:"bug501279.ogg", type:"audio/ogg" },
-  { name:"bug603918.webm", type:"video/webm" },
-  { name:"bug604067.webm", type:"video/webm" },
-  { name:"bogus.duh", type:"bogus/duh" }
+  { name: "bogus.wav", type: "audio/x-wav" },
+  { name: "bogus.ogv", type: "video/ogg" },
+  { name: "448636.ogv", type: "video/ogg" },
+  { name: "bug504843.ogv", type: "video/ogg" },
+  { name: "bug501279.ogg", type: "audio/ogg" },
+  { name: "bug603918.webm", type: "video/webm" },
+  { name: "bug604067.webm", type: "video/webm" },
+  { name: "bogus.duh", type: "bogus/duh" },
 ];
 
 // These files would get error after receiving "loadedmetadata", we would like
 // to check duration in "onerror" and make sure the duration is still available.
 var gDurationTests = [
-  { name:"bug603918.webm", duration:6.076 },
-  { name:"bug604067.webm", duration:6.076 }
-]
+  { name: "bug603918.webm", duration: 6.076 },
+  { name: "bug604067.webm", duration: 6.076 },
+];
 
 // These are files that have nontrivial duration and are useful for seeking within.
 var gSeekTests = [
-  { name:"r11025_s16_c1.wav", type:"audio/x-wav", duration:1.0 },
-  { name:"audio.wav", type:"audio/x-wav", duration:0.031247 },
-  { name:"seek.ogv", type:"video/ogg", duration:3.966 },
-  { name:"320x240.ogv", type:"video/ogg", duration:0.266 },
-  { name:"seek.webm", type:"video/webm", duration:3.966 },
-  { name:"sine.webm", type:"audio/webm", duration:4.001 },
-  { name:"bug516323.indexed.ogv", type:"video/ogg", duration:4.208333 },
-  { name:"split.webm", type:"video/webm", duration:1.967 },
-  { name:"detodos.opus", type:"audio/ogg; codecs=opus", duration:2.9135 },
-  { name:"gizmo.mp4", type:"video/mp4", duration:5.56 },
-  { name:"owl.mp3", type:"audio/mpeg", duration:3.343 },
-  { name:"bogus.duh", type:"bogus/duh", duration:123 },
+  { name: "r11025_s16_c1.wav", type: "audio/x-wav", duration: 1.0 },
+  { name: "audio.wav", type: "audio/x-wav", duration: 0.031247 },
+  { name: "seek.ogv", type: "video/ogg", duration: 3.966 },
+  { name: "320x240.ogv", type: "video/ogg", duration: 0.266 },
+  { name: "seek.webm", type: "video/webm", duration: 3.966 },
+  { name: "sine.webm", type: "audio/webm", duration: 4.001 },
+  { name: "bug516323.indexed.ogv", type: "video/ogg", duration: 4.208333 },
+  { name: "split.webm", type: "video/webm", duration: 1.967 },
+  { name: "detodos.opus", type: "audio/ogg; codecs=opus", duration: 2.9135 },
+  { name: "gizmo.mp4", type: "video/mp4", duration: 5.56 },
+  { name: "owl.mp3", type: "audio/mpeg", duration: 3.343 },
+  { name: "bogus.duh", type: "bogus/duh", duration: 123 },
 
   // Bug 1242338: hit a numerical problem while seeking to the duration.
-  { name:"bug482461-theora.ogv", type:"video/ogg", duration:4.138 },
+  { name: "bug482461-theora.ogv", type: "video/ogg", duration: 4.138 },
 ];
 
 var gFastSeekTests = [
-  { name:"gizmo.mp4", type:"video/mp4", keyframes:[0, 1.0, 2.0, 3.0, 4.0, 5.0 ] },
+  {
+    name: "gizmo.mp4",
+    type: "video/mp4",
+    keyframes: [0, 1.0, 2.0, 3.0, 4.0, 5.0],
+  },
   // Note: Not all keyframes in the file are actually referenced in the Cues in this file.
-  { name:"seek.webm", type:"video/webm", keyframes:[0, 0.8, 1.6, 2.4, 3.2]},
+  { name: "seek.webm", type: "video/webm", keyframes: [0, 0.8, 1.6, 2.4, 3.2] },
   // Note: the sync points are the points on both the audio and video streams
   // before the keyframes. You can't just assume that the keyframes are the sync
   // points, as the audio required for that sync point may be before the keyframe.
-  { name:"bug516323.indexed.ogv", type:"video/ogg", keyframes:[0, 0.46, 3.06] },
+  {
+    name: "bug516323.indexed.ogv",
+    type: "video/ogg",
+    keyframes: [0, 0.46, 3.06],
+  },
 ];
 
 // These files are WebMs without cues. They're seekable within their buffered
 // ranges. If work renders WebMs fully seekable these files should be moved
 // into gSeekTests
 var gCuelessWebMTests = [
-  { name:"no-cues.webm", type:"video/webm", duration:3.967 },
+  { name: "no-cues.webm", type: "video/webm", duration: 3.967 },
 ];
 
 // These are files that are non seekable, due to problems with the media,
 // for example broken or missing indexes.
-var gUnseekableTests = [
-  { name:"bogus.duh", type:"bogus/duh"}
-];
+var gUnseekableTests = [{ name: "bogus.duh", type: "bogus/duh" }];
 
 var androidVersion = -1; // non-Android platforms
-if (manifestNavigator().userAgent.includes("Mobile") ||
-    manifestNavigator().userAgent.includes("Tablet")) {
-  androidVersion = SpecialPowers.Cc['@mozilla.org/system-info;1']
-                                .getService(SpecialPowers.Ci.nsIPropertyBag2)
-                                .getProperty('version');
+if (
+  manifestNavigator().userAgent.includes("Mobile") ||
+  manifestNavigator().userAgent.includes("Tablet")
+) {
+  androidVersion = SpecialPowers.Cc["@mozilla.org/system-info;1"]
+    .getService(SpecialPowers.Ci.nsIPropertyBag2)
+    .getProperty("version");
 }
 
 function getAndroidVersion() {
   return androidVersion;
 }
 
 // These are files suitable for using with a "new Audio" constructor.
 var gAudioTests = [
-  { name:"r11025_s16_c1.wav", type:"audio/x-wav", duration:1.0 },
-  { name:"sound.ogg", type:"audio/ogg" },
-  { name:"owl.mp3", type:"audio/mpeg", duration:3.343 },
-  { name:"small-shot.m4a", type:"audio/mp4", duration:0.29 },
-  { name:"bogus.duh", type:"bogus/duh", duration:123 },
-  { name:"empty_size.mp3", type:"audio/mpeg", duration: 2.235 }
+  { name: "r11025_s16_c1.wav", type: "audio/x-wav", duration: 1.0 },
+  { name: "sound.ogg", type: "audio/ogg" },
+  { name: "owl.mp3", type: "audio/mpeg", duration: 3.343 },
+  { name: "small-shot.m4a", type: "audio/mp4", duration: 0.29 },
+  { name: "bogus.duh", type: "bogus/duh", duration: 123 },
+  { name: "empty_size.mp3", type: "audio/mpeg", duration: 2.235 },
 ];
 
 // These files ensure our handling of 404 errors is consistent across the
 // various backends.
 var g404Tests = [
-  { name:"404.wav", type:"audio/x-wav" },
-  { name:"404.ogv", type:"video/ogg" },
-  { name:"404.oga", type:"audio/ogg" },
-  { name:"404.webm", type:"video/webm" },
-  { name:"bogus.duh", type:"bogus/duh" }
+  { name: "404.wav", type: "audio/x-wav" },
+  { name: "404.ogv", type: "video/ogg" },
+  { name: "404.oga", type: "audio/ogg" },
+  { name: "404.webm", type: "video/webm" },
+  { name: "bogus.duh", type: "bogus/duh" },
 ];
 
 // These are files suitable for testing various decoder failures that are
 // expected to fire MEDIA_ERR_DECODE.  Used by test_decode_error, which expects
 // an error and emptied event, and no loadedmetadata or ended event.
 var gDecodeErrorTests = [
   // Valid files with unsupported codecs
-  { name:"r11025_msadpcm_c1.wav", type:"audio/x-wav" },
-  { name:"dirac.ogg", type:"video/ogg" },
+  { name: "r11025_msadpcm_c1.wav", type: "audio/x-wav" },
+  { name: "dirac.ogg", type: "video/ogg" },
   // Invalid files
-  { name:"bogus.wav", type:"audio/x-wav" },
-  { name:"bogus.ogv", type:"video/ogg" },
+  { name: "bogus.wav", type: "audio/x-wav" },
+  { name: "bogus.ogv", type: "video/ogg" },
 
-  { name:"bogus.duh", type:"bogus/duh" }
+  { name: "bogus.duh", type: "bogus/duh" },
 ];
 
 // These are files that are used for media fragments tests
 var gFragmentTests = [
-  { name:"big.wav", type:"audio/x-wav", duration:9.278982, size:102444 }
+  { name: "big.wav", type: "audio/x-wav", duration: 9.278982, size: 102444 },
 ];
 
 // Used by test_chaining.html. The |links| attributes is the number of links in
 // this file that we should be able to play.
 var gChainingTests = [
   // Vorbis and Opus chained file. They have user comments |index=n| where `n`
   // is the index of this segment in the file, 0 indexed.
-  { name:"chain.ogg", type:"audio/ogg", links: 4},
-  { name:"chain.opus", type:"audio/ogg; codec=opus", links: 4},
+  { name: "chain.ogg", type: "audio/ogg", links: 4 },
+  { name: "chain.opus", type: "audio/ogg; codec=opus", links: 4 },
   // Those files are chained files with a different number of channels in each
   // part. This is not supported and should stop playing after the first part.
-  { name:"variable-channel.ogg", type:"audio/ogg", links: 1 },
-  { name:"variable-channel.opus", type:"audio/ogg; codec=opus", links: 1 },
+  { name: "variable-channel.ogg", type: "audio/ogg", links: 1 },
+  { name: "variable-channel.opus", type: "audio/ogg; codec=opus", links: 1 },
   // Those files are chained files with a different sample rate in each
   // part. This is not supported and should stop playing after the first part.
-  { name:"variable-samplerate.ogg", type:"audio/ogg", links: 1 },
+  { name: "variable-samplerate.ogg", type: "audio/ogg", links: 1 },
   // Opus decoding in Firefox outputs 48 kHz PCM despite having a different
   // original sample rate, so we can safely play Opus chained media that have
   // different samplerate accross links.
-  { name:"variable-samplerate.opus", type:"audio/ogg; codec=opus", links: 2 },
+  { name: "variable-samplerate.opus", type: "audio/ogg; codec=opus", links: 2 },
   // A chained video file. We don't support those, so only one link should be
   // reported.
-  { name:"chained-video.ogv", type:"video/ogg", links: 1 },
+  { name: "chained-video.ogv", type: "video/ogg", links: 1 },
   // A file that consist in 4 links of audio, then another link that has video.
   // We should stop right after the 4 audio links.
-  { name:"chained-audio-video.ogg", type:"video/ogg", links: 4 },
+  { name: "chained-audio-video.ogg", type: "video/ogg", links: 4 },
   // An opus file that has two links, with a different preskip value for each
   // link. We should be able to play both links.
-  { name:"variable-preskip.opus", type:"audio/ogg; codec=opus", links: 2 },
-  { name:"bogus.duh", type:"bogus/duh" }
+  { name: "variable-preskip.opus", type: "audio/ogg; codec=opus", links: 2 },
+  { name: "bogus.duh", type: "bogus/duh" },
 ];
 
 // Videos with an aspect ratio. Used for testing that displaying frames
 // on a canvas works correctly in the case of non-standard aspect ratios.
 // See bug 874897 for an example.
 var gAspectRatioTests = [
-  { name:"VID_0001.ogg", type:"video/ogg", duration:19.966 }
+  { name: "VID_0001.ogg", type: "video/ogg", duration: 19.966 },
 ];
 
 // These are files with non-trivial tag sets.
 // Used by test_metadata.html.
 var gMetadataTests = [
   // Ogg Vorbis files
-  { name:"short-video.ogv", tags: {
-      TITLE:"Lepidoptera",
-      ARTIST:"Epoq",
-      ALBUM:"Kahvi Collective",
-      DATE:"2002",
-      COMMENT:"http://www.kahvi.org",
-    }
+  {
+    name: "short-video.ogv",
+    tags: {
+      TITLE: "Lepidoptera",
+      ARTIST: "Epoq",
+      ALBUM: "Kahvi Collective",
+      DATE: "2002",
+      COMMENT: "http://www.kahvi.org",
+    },
   },
-  { name:"bug516323.ogv", tags: {
-      GENRE:"Open Movie",
-      ENCODER:"Audacity",
-      TITLE:"Elephants Dream",
-      ARTIST:"Silvia Pfeiffer",
-      COMMENTS:"Audio Description"
-    }
+  {
+    name: "bug516323.ogv",
+    tags: {
+      GENRE: "Open Movie",
+      ENCODER: "Audacity",
+      TITLE: "Elephants Dream",
+      ARTIST: "Silvia Pfeiffer",
+      COMMENTS: "Audio Description",
+    },
   },
-  { name:"bug516323.indexed.ogv", tags: {
-      GENRE:"Open Movie",
-      ENCODER:"Audacity",
-      TITLE:"Elephants Dream",
-      ARTIST:"Silvia Pfeiffer",
-      COMMENTS:"Audio Description"
-    }
+  {
+    name: "bug516323.indexed.ogv",
+    tags: {
+      GENRE: "Open Movie",
+      ENCODER: "Audacity",
+      TITLE: "Elephants Dream",
+      ARTIST: "Silvia Pfeiffer",
+      COMMENTS: "Audio Description",
+    },
   },
-  { name:"detodos.opus", tags: {
-      title:"De todos. Para todos.",
-      artist:"Mozilla.org"
-    }
+  {
+    name: "detodos.opus",
+    tags: {
+      title: "De todos. Para todos.",
+      artist: "Mozilla.org",
+    },
   },
-  { name:"sound.ogg", tags: { } },
-  { name:"small-shot.ogg", tags: {
-      title:"Pew SFX"
-    }
+  { name: "sound.ogg", tags: {} },
+  {
+    name: "small-shot.ogg",
+    tags: {
+      title: "Pew SFX",
+    },
   },
-  { name:"badtags.ogg", tags: {
+  {
+    name: "badtags.ogg",
+    tags: {
       // We list only the valid tags here, and verify
       // the invalid ones are filtered out.
-      title:"Invalid comments test file",
-      empty:"",
-      "":"empty",
-      "{- [(`!@\"#$%^&')] -}":"valid tag name, surprisingly"
+      title: "Invalid comments test file",
+      empty: "",
+      "": "empty",
+      "{- [(`!@\"#$%^&')] -}": "valid tag name, surprisingly",
       // The file also includes the following invalid tags.
       // "A description with no separator is a common problem.",
       // "雨":"Likely, but an invalid key (non-ascii).",
       // "not\nval\x1fid":"invalid tag name",
       // "not~valid":"this isn't a valid name either",
       // "not-utf-8":"invalid sequences: \xff\xfe\xfa\xfb\0eol"
-    }
+    },
   },
-  { name:"wave_metadata.wav", tags: {
-      name:"Track Title",
-      artist:"Artist Name",
-      comments:"Comments",
-    }
+  {
+    name: "wave_metadata.wav",
+    tags: {
+      name: "Track Title",
+      artist: "Artist Name",
+      comments: "Comments",
+    },
   },
-  { name:"wave_metadata_utf8.wav", tags: {
-      name:"歌曲名稱",
-      artist:"作曲者",
-      comments:"註解",
-    }
+  {
+    name: "wave_metadata_utf8.wav",
+    tags: {
+      name: "歌曲名稱",
+      artist: "作曲者",
+      comments: "註解",
+    },
   },
-  { name:"wave_metadata_unknown_tag.wav", tags: {
-      name:"Track Title",
-      comments:"Comments",
-    }
+  {
+    name: "wave_metadata_unknown_tag.wav",
+    tags: {
+      name: "Track Title",
+      comments: "Comments",
+    },
   },
-  { name:"wave_metadata_bad_len.wav", tags: {
-      name:"Track Title",
-      artist:"Artist Name",
-      comments:"Comments",
-    }
+  {
+    name: "wave_metadata_bad_len.wav",
+    tags: {
+      name: "Track Title",
+      artist: "Artist Name",
+      comments: "Comments",
+    },
   },
-  { name:"wave_metadata_bad_no_null.wav", tags: {
-      name:"Track Title",
-      artist:"Artist Name",
-      comments:"Comments!!",
-    }
+  {
+    name: "wave_metadata_bad_no_null.wav",
+    tags: {
+      name: "Track Title",
+      artist: "Artist Name",
+      comments: "Comments!!",
+    },
   },
-  { name:"wave_metadata_bad_utf8.wav", tags: {
-      name:"歌曲名稱",
-      comments:"註解",
-    }
+  {
+    name: "wave_metadata_bad_utf8.wav",
+    tags: {
+      name: "歌曲名稱",
+      comments: "註解",
+    },
   },
-  { name:"wavedata_u8.wav", tags: { }
-  },
+  { name: "wavedata_u8.wav", tags: {} },
 ];
 
 // Now Fennec doesn't support flac, so only test it on non-android platforms.
 if (getAndroidVersion() < 0) {
   gMetadataTests = gMetadataTests.concat([
-    { name:"flac-s24.flac", tags: {
-        ALBUM:"Seascapes",
-        TITLE:"(La Mer) - II. Jeux de vagues. Allegro",
-        COMPOSER:"Debussy, Claude",
-        TRACKNUMBER:"2/9",
-        DISCNUMBER:"1/1",
-        encoder:"Lavf57.41.100",
-      }
-    }]);
+    {
+      name: "flac-s24.flac",
+      tags: {
+        ALBUM: "Seascapes",
+        TITLE: "(La Mer) - II. Jeux de vagues. Allegro",
+        COMPOSER: "Debussy, Claude",
+        TRACKNUMBER: "2/9",
+        DISCNUMBER: "1/1",
+        encoder: "Lavf57.41.100",
+      },
+    },
+  ]);
 }
 
 // Test files for Encrypted Media Extensions
 var gEMETests = [
   {
-    name:"vp9 in mp4",
+    name: "vp9 in mp4",
     tracks: [
       {
-          name:"video",
-          type:"video/mp4; codecs=\"vp9.0\"",
-          fragments:[ "short-vp9-encrypted-video.mp4",
-                    ]
+        name: "video",
+        type: 'video/mp4; codecs="vp9.0"',
+        fragments: ["short-vp9-encrypted-video.mp4"],
       },
       {
-          name:"audio",
-          type:"audio/mp4; codecs=\"mp4a.40.2\"",
-          fragments:[ "short-aac-encrypted-audio.mp4",
-                    ]
-      }
+        name: "audio",
+        type: 'audio/mp4; codecs="mp4a.40.2"',
+        fragments: ["short-aac-encrypted-audio.mp4"],
+      },
     ],
     keys: {
-      "2cdb0ed6119853e7850671c3e9906c3c":"808B9ADAC384DE1E4F56140F4AD76194"
+      "2cdb0ed6119853e7850671c3e9906c3c": "808B9ADAC384DE1E4F56140F4AD76194",
     },
-    sessionType:"temporary",
-    sessionCount:2,
-    duration:0.47
+    sessionType: "temporary",
+    sessionCount: 2,
+    duration: 0.47,
   },
   {
-    name:"video-only with 2 keys",
+    name: "video-only with 2 keys",
     tracks: [
       {
-        name:"video",
-        type:"video/mp4; codecs=\"avc1.64000d\"",
-        fragments:[ "bipbop-cenc-videoinit.mp4",
-                    "bipbop-cenc-video1.m4s",
-                    "bipbop-cenc-video2.m4s",
-                  ]
-      }
+        name: "video",
+        type: 'video/mp4; codecs="avc1.64000d"',
+        fragments: [
+          "bipbop-cenc-videoinit.mp4",
+          "bipbop-cenc-video1.m4s",
+          "bipbop-cenc-video2.m4s",
+        ],
+      },
     ],
     keys: {
       // "keyid" : "key"
-      "7e571d037e571d037e571d037e571d03" : "7e5733337e5733337e5733337e573333",
-      "7e571d047e571d047e571d047e571d04" : "7e5744447e5744447e5744447e574444",
+      "7e571d037e571d037e571d037e571d03": "7e5733337e5733337e5733337e573333",
+      "7e571d047e571d047e571d047e571d04": "7e5744447e5744447e5744447e574444",
     },
-    sessionType:"temporary",
-    sessionCount:1,
-    duration:1.60,
+    sessionType: "temporary",
+    sessionCount: 1,
+    duration: 1.6,
   },
   {
-    name:"video-only with 2 keys, CORS",
+    name: "video-only with 2 keys, CORS",
     tracks: [
       {
-        name:"video",
-        type:"video/mp4; codecs=\"avc1.64000d\"",
-        fragments:[ "bipbop-cenc-videoinit.mp4",
-                    "bipbop-cenc-video1.m4s",
-                    "bipbop-cenc-video2.m4s",
-                  ]
-      }
-    ],
-    keys: {
-      // "keyid" : "key"
-      "7e571d037e571d037e571d037e571d03" : "7e5733337e5733337e5733337e573333",
-      "7e571d047e571d047e571d047e571d04" : "7e5744447e5744447e5744447e574444",
-    },
-    sessionType:"temporary",
-    sessionCount:1,
-    crossOrigin:true,
-    duration:1.60,
-  },
-  {
-    name:"audio&video tracks, both with all keys",
-    tracks: [
-      {
-        name:"audio",
-        type:"audio/mp4; codecs=\"mp4a.40.2\"",
-        fragments:[ "bipbop-cenc-audioinit.mp4",
-                    "bipbop-cenc-audio1.m4s",
-                    "bipbop-cenc-audio2.m4s",
-                    "bipbop-cenc-audio3.m4s",
-                  ],
-      },
-      {
-        name:"video",
-        type:"video/mp4; codecs=\"avc1.64000d\"",
-        fragments:[ "bipbop-cenc-videoinit.mp4",
-                    "bipbop-cenc-video1.m4s",
-                    "bipbop-cenc-video2.m4s",
-                  ],
+        name: "video",
+        type: 'video/mp4; codecs="avc1.64000d"',
+        fragments: [
+          "bipbop-cenc-videoinit.mp4",
+          "bipbop-cenc-video1.m4s",
+          "bipbop-cenc-video2.m4s",
+        ],
       },
     ],
     keys: {
       // "keyid" : "key"
-      "7e571d037e571d037e571d037e571d03" : "7e5733337e5733337e5733337e573333",
-      "7e571d047e571d047e571d047e571d04" : "7e5744447e5744447e5744447e574444",
+      "7e571d037e571d037e571d037e571d03": "7e5733337e5733337e5733337e573333",
+      "7e571d047e571d047e571d047e571d04": "7e5744447e5744447e5744447e574444",
     },
-    sessionType:"temporary",
-    sessionCount:2,
-    duration:1.60,
+    sessionType: "temporary",
+    sessionCount: 1,
+    crossOrigin: true,
+    duration: 1.6,
   },
   {
-    name:"audio&video tracks, both with all keys, CORS",
+    name: "audio&video tracks, both with all keys",
     tracks: [
       {
-        name:"audio",
-        type:"audio/mp4; codecs=\"mp4a.40.2\"",
-        fragments:[ "bipbop-cenc-audioinit.mp4",
-                    "bipbop-cenc-audio1.m4s",
-                    "bipbop-cenc-audio2.m4s",
-                    "bipbop-cenc-audio3.m4s",
-                  ],
+        name: "audio",
+        type: 'audio/mp4; codecs="mp4a.40.2"',
+        fragments: [
+          "bipbop-cenc-audioinit.mp4",
+          "bipbop-cenc-audio1.m4s",
+          "bipbop-cenc-audio2.m4s",
+          "bipbop-cenc-audio3.m4s",
+        ],
       },
       {
-        name:"video",
-        type:"video/mp4; codecs=\"avc1.64000d\"",
-        fragments:[ "bipbop-cenc-videoinit.mp4",
-                    "bipbop-cenc-video1.m4s",
-                    "bipbop-cenc-video2.m4s",
-                  ],
+        name: "video",
+        type: 'video/mp4; codecs="avc1.64000d"',
+        fragments: [
+          "bipbop-cenc-videoinit.mp4",
+          "bipbop-cenc-video1.m4s",
+          "bipbop-cenc-video2.m4s",
+        ],
+      },
+    ],
+    keys: {
+      // "keyid" : "key"
+      "7e571d037e571d037e571d037e571d03": "7e5733337e5733337e5733337e573333",
+      "7e571d047e571d047e571d047e571d04": "7e5744447e5744447e5744447e574444",
+    },
+    sessionType: "temporary",
+    sessionCount: 2,
+    duration: 1.6,
+  },
+  {
+    name: "audio&video tracks, both with all keys, CORS",
+    tracks: [
+      {
+        name: "audio",
+        type: 'audio/mp4; codecs="mp4a.40.2"',
+        fragments: [
+          "bipbop-cenc-audioinit.mp4",
+          "bipbop-cenc-audio1.m4s",
+          "bipbop-cenc-audio2.m4s",
+          "bipbop-cenc-audio3.m4s",
+        ],
+      },
+      {
+        name: "video",
+        type: 'video/mp4; codecs="avc1.64000d"',
+        fragments: [
+          "bipbop-cenc-videoinit.mp4",
+          "bipbop-cenc-video1.m4s",
+          "bipbop-cenc-video2.m4s",
+        ],
       },
     ],
     keys: {
       // "keyid" : "key"
-      "7e571d037e571d037e571d037e571d03" : "7e5733337e5733337e5733337e573333",
-      "7e571d047e571d047e571d047e571d04" : "7e5744447e5744447e5744447e574444",
+      "7e571d037e571d037e571d037e571d03": "7e5733337e5733337e5733337e573333",
+      "7e571d047e571d047e571d047e571d04": "7e5744447e5744447e5744447e574444",
     },
-    sessionType:"temporary",
-    sessionCount:2,
-    crossOrigin:true,
-    duration:1.60,
+    sessionType: "temporary",
+    sessionCount: 2,
+    crossOrigin: true,
+    duration: 1.6,
   },
   {
-    name:"400x300 audio&video tracks, each with its key",
+    name: "400x300 audio&video tracks, each with its key",
     tracks: [
       {
-        name:"audio",
-        type:"audio/mp4; codecs=\"mp4a.40.2\"",
-        fragments:[ "bipbop_300_215kbps-cenc-audio-key1-init.mp4",
-                    "bipbop_300_215kbps-cenc-audio-key1-1.m4s",
-                    "bipbop_300_215kbps-cenc-audio-key1-2.m4s",
-                    "bipbop_300_215kbps-cenc-audio-key1-3.m4s",
-                    "bipbop_300_215kbps-cenc-audio-key1-4.m4s",
-                  ],
+        name: "audio",
+        type: 'audio/mp4; codecs="mp4a.40.2"',
+        fragments: [
+          "bipbop_300_215kbps-cenc-audio-key1-init.mp4",
+          "bipbop_300_215kbps-cenc-audio-key1-1.m4s",
+          "bipbop_300_215kbps-cenc-audio-key1-2.m4s",
+          "bipbop_300_215kbps-cenc-audio-key1-3.m4s",
+          "bipbop_300_215kbps-cenc-audio-key1-4.m4s",
+        ],
       },
       {
-        name:"video",
-        type:"video/mp4; codecs=\"avc1.64000d\"",
-        fragments:[ "bipbop_300_215kbps-cenc-video-key1-init.mp4",
-                    "bipbop_300_215kbps-cenc-video-key1-1.m4s",
-                    "bipbop_300_215kbps-cenc-video-key1-2.m4s",
-                  ],
+        name: "video",
+        type: 'video/mp4; codecs="avc1.64000d"',
+        fragments: [
+          "bipbop_300_215kbps-cenc-video-key1-init.mp4",
+          "bipbop_300_215kbps-cenc-video-key1-1.m4s",
+          "bipbop_300_215kbps-cenc-video-key1-2.m4s",
+        ],
       },
     ],
     keys: {
       // "keyid" : "key"
-      "7e571d037e571d037e571d037e571d11" : "7e5733337e5733337e5733337e573311",
-      "7e571d047e571d047e571d047e571d21" : "7e5744447e5744447e5744447e574421",
+      "7e571d037e571d037e571d037e571d11": "7e5733337e5733337e5733337e573311",
+      "7e571d047e571d047e571d047e571d21": "7e5744447e5744447e5744447e574421",
     },
-    sessionType:"temporary",
-    sessionCount:2,
-    duration:1.60,
+    sessionType: "temporary",
+    sessionCount: 2,
+    duration: 1.6,
   },
   {
-    name:"640x480@624kbps audio&video tracks, each with its key",
+    name: "640x480@624kbps audio&video tracks, each with its key",
     tracks: [
       {
-        name:"audio",
-        type:"audio/mp4; codecs=\"mp4a.40.2\"",
-        fragments:[ "bipbop_480_624kbps-cenc-audio-key1-init.mp4",
-                    "bipbop_480_624kbps-cenc-audio-key1-1.m4s",
-                    "bipbop_480_624kbps-cenc-audio-key1-2.m4s",
-                    "bipbop_480_624kbps-cenc-audio-key1-3.m4s",
-                    "bipbop_480_624kbps-cenc-audio-key1-4.m4s",
-                  ],
+        name: "audio",
+        type: 'audio/mp4; codecs="mp4a.40.2"',
+        fragments: [
+          "bipbop_480_624kbps-cenc-audio-key1-init.mp4",
+          "bipbop_480_624kbps-cenc-audio-key1-1.m4s",
+          "bipbop_480_624kbps-cenc-audio-key1-2.m4s",
+          "bipbop_480_624kbps-cenc-audio-key1-3.m4s",
+          "bipbop_480_624kbps-cenc-audio-key1-4.m4s",
+        ],
       },
       {
-        name:"video",
-        type:"video/mp4; codecs=\"avc1.64000d\"",
-        fragments:[ "bipbop_480_624kbps-cenc-video-key1-init.mp4",
-                    "bipbop_480_624kbps-cenc-video-key1-1.m4s",
-                    "bipbop_480_624kbps-cenc-video-key1-2.m4s",
-                  ],
+        name: "video",
+        type: 'video/mp4; codecs="avc1.64000d"',
+        fragments: [
+          "bipbop_480_624kbps-cenc-video-key1-init.mp4",
+          "bipbop_480_624kbps-cenc-video-key1-1.m4s",
+          "bipbop_480_624kbps-cenc-video-key1-2.m4s",
+        ],
       },
     ],
     keys: {
       // "keyid" : "key"
-      "7e571d037e571d037e571d037e571d11" : "7e5733337e5733337e5733337e573311",
-      "7e571d047e571d047e571d047e571d21" : "7e5744447e5744447e5744447e574421",
+      "7e571d037e571d037e571d037e571d11": "7e5733337e5733337e5733337e573311",
+      "7e571d047e571d047e571d047e571d21": "7e5744447e5744447e5744447e574421",
     },
-    sessionType:"temporary",
-    sessionCount:2,
-    duration:1.60,
+    sessionType: "temporary",
+    sessionCount: 2,
+    duration: 1.6,
   },
   {
-    name:"640x480@959kbps audio&video tracks, each with its key",
+    name: "640x480@959kbps audio&video tracks, each with its key",
     tracks: [
       {
-        name:"audio",
-        type:"audio/mp4; codecs=\"mp4a.40.2\"",
-        fragments:[ "bipbop_480_959kbps-cenc-audio-key1-init.mp4",
-                    "bipbop_480_959kbps-cenc-audio-key1-1.m4s",
-                    "bipbop_480_959kbps-cenc-audio-key1-2.m4s",
-                    "bipbop_480_959kbps-cenc-audio-key1-3.m4s",
-                    "bipbop_480_959kbps-cenc-audio-key1-4.m4s",
-                  ],
+        name: "audio",
+        type: 'audio/mp4; codecs="mp4a.40.2"',
+        fragments: [
+          "bipbop_480_959kbps-cenc-audio-key1-init.mp4",
+          "bipbop_480_959kbps-cenc-audio-key1-1.m4s",
+          "bipbop_480_959kbps-cenc-audio-key1-2.m4s",
+          "bipbop_480_959kbps-cenc-audio-key1-3.m4s",
+          "bipbop_480_959kbps-cenc-audio-key1-4.m4s",
+        ],
       },
       {
-        name:"video",
-        type:"video/mp4; codecs=\"avc1.64000d\"",
-        fragments:[ "bipbop_480_959kbps-cenc-video-key1-init.mp4",
-                    "bipbop_480_959kbps-cenc-video-key1-1.m4s",
-                    "bipbop_480_959kbps-cenc-video-key1-2.m4s",
-                  ],
+        name: "video",
+        type: 'video/mp4; codecs="avc1.64000d"',
+        fragments: [
+          "bipbop_480_959kbps-cenc-video-key1-init.mp4",
+          "bipbop_480_959kbps-cenc-video-key1-1.m4s",
+          "bipbop_480_959kbps-cenc-video-key1-2.m4s",
+        ],
       },
     ],
     keys: {
       // "keyid" : "key"
-      "7e571d037e571d037e571d037e571d11" : "7e5733337e5733337e5733337e573311",
-      "7e571d047e571d047e571d047e571d21" : "7e5744447e5744447e5744447e574421",
+      "7e571d037e571d037e571d037e571d11": "7e5733337e5733337e5733337e573311",
+      "7e571d047e571d047e571d047e571d21": "7e5744447e5744447e5744447e574421",
     },
-    sessionType:"temporary",
-    sessionCount:2,
-    duration:1.60,
+    sessionType: "temporary",
+    sessionCount: 2,
+    duration: 1.6,
   },
   {
-    name:"640x480 then 400x300, same key (1st) per track",
+    name: "640x480 then 400x300, same key (1st) per track",
     tracks: [
       {
-        name:"audio",
-        type:"audio/mp4; codecs=\"mp4a.40.2\"",
-        fragments:[ "bipbop_480_624kbps-cenc-audio-key1-init.mp4",
-                    "bipbop_480_624kbps-cenc-audio-key1-1.m4s",
-                    "bipbop_480_624kbps-cenc-audio-key1-2.m4s",
-                    "bipbop_480_624kbps-cenc-audio-key1-3.m4s",
-                    "bipbop_480_624kbps-cenc-audio-key1-4.m4s",
-                  ],
+        name: "audio",
+        type: 'audio/mp4; codecs="mp4a.40.2"',
+        fragments: [
+          "bipbop_480_624kbps-cenc-audio-key1-init.mp4",
+          "bipbop_480_624kbps-cenc-audio-key1-1.m4s",
+          "bipbop_480_624kbps-cenc-audio-key1-2.m4s",
+          "bipbop_480_624kbps-cenc-audio-key1-3.m4s",
+          "bipbop_480_624kbps-cenc-audio-key1-4.m4s",
+        ],
       },
       {
-        name:"video",
-        type:"video/mp4; codecs=\"avc1.64000d\"",
-        fragments:[ "bipbop_480_624kbps-cenc-video-key1-init.mp4",
-                    "bipbop_480_624kbps-cenc-video-key1-1.m4s",
-                    "bipbop_300_215kbps-cenc-video-key1-init.mp4",
-                    "bipbop_300_215kbps-cenc-video-key1-2.m4s",
-                  ],
+        name: "video",
+        type: 'video/mp4; codecs="avc1.64000d"',
+        fragments: [
+          "bipbop_480_624kbps-cenc-video-key1-init.mp4",
+          "bipbop_480_624kbps-cenc-video-key1-1.m4s",
+          "bipbop_300_215kbps-cenc-video-key1-init.mp4",
+          "bipbop_300_215kbps-cenc-video-key1-2.m4s",
+        ],
       },
     ],
     keys: {
       // "keyid" : "key"
-      "7e571d037e571d037e571d037e571d11" : "7e5733337e5733337e5733337e573311",
-      "7e571d047e571d047e571d047e571d21" : "7e5744447e5744447e5744447e574421",
+      "7e571d037e571d037e571d037e571d11": "7e5733337e5733337e5733337e573311",
+      "7e571d047e571d047e571d047e571d21": "7e5744447e5744447e5744447e574421",
     },
-    sessionType:"temporary",
-    sessionCount:3,
-    duration:1.60,
+    sessionType: "temporary",
+    sessionCount: 3,
+    duration: 1.6,
   },
   {
-    name:"640x480 then 400x300, same key (2nd) per track",
+    name: "640x480 then 400x300, same key (2nd) per track",
     tracks: [
       {
-        name:"audio",
-        type:"audio/mp4; codecs=\"mp4a.40.2\"",
-        fragments:[ "bipbop_480_624kbps-cenc-audio-key2-init.mp4",
-                    "bipbop_480_624kbps-cenc-audio-key2-1.m4s",
-                    "bipbop_480_624kbps-cenc-audio-key2-2.m4s",
-                    "bipbop_480_624kbps-cenc-audio-key2-3.m4s",
-                    "bipbop_480_624kbps-cenc-audio-key2-4.m4s",
-                  ],
+        name: "audio",
+        type: 'audio/mp4; codecs="mp4a.40.2"',
+        fragments: [
+          "bipbop_480_624kbps-cenc-audio-key2-init.mp4",
+          "bipbop_480_624kbps-cenc-audio-key2-1.m4s",
+          "bipbop_480_624kbps-cenc-audio-key2-2.m4s",
+          "bipbop_480_624kbps-cenc-audio-key2-3.m4s",
+          "bipbop_480_624kbps-cenc-audio-key2-4.m4s",
+        ],
       },
       {
-        name:"video",
-        type:"video/mp4; codecs=\"avc1.64000d\"",
-        fragments:[ "bipbop_480_624kbps-cenc-video-key2-init.mp4",
-                    "bipbop_480_624kbps-cenc-video-key2-1.m4s",
-                    "bipbop_300_215kbps-cenc-video-key2-init.mp4",
-                    "bipbop_300_215kbps-cenc-video-key2-2.m4s",
-                  ],
+        name: "video",
+        type: 'video/mp4; codecs="avc1.64000d"',
+        fragments: [
+          "bipbop_480_624kbps-cenc-video-key2-init.mp4",
+          "bipbop_480_624kbps-cenc-video-key2-1.m4s",
+          "bipbop_300_215kbps-cenc-video-key2-init.mp4",
+          "bipbop_300_215kbps-cenc-video-key2-2.m4s",
+        ],
       },
     ],
     keys: {
       // "keyid" : "key"
-      "7e571d037e571d037e571d037e571d12" : "7e5733337e5733337e5733337e573312",
-      "7e571d047e571d047e571d047e571d22" : "7e5744447e5744447e5744447e574422",
+      "7e571d037e571d037e571d037e571d12": "7e5733337e5733337e5733337e573312",
+      "7e571d047e571d047e571d047e571d22": "7e5744447e5744447e5744447e574422",
     },
-    sessionType:"temporary",
-    sessionCount:3,
-    duration:1.60,
+    sessionType: "temporary",
+    sessionCount: 3,
+    duration: 1.6,
   },
   {
-    name:"640x480 with 1st keys then 400x300 with 2nd keys",
+    name: "640x480 with 1st keys then 400x300 with 2nd keys",
     tracks: [
       {
-        name:"audio",
-        type:"audio/mp4; codecs=\"mp4a.40.2\"",
-        fragments:[ "bipbop_480_624kbps-cenc-audio-key1-init.mp4",
-                    "bipbop_480_624kbps-cenc-audio-key1-1.m4s",
-                    "bipbop_480_624kbps-cenc-audio-key1-2.m4s",
-                    "bipbop_480_624kbps-cenc-audio-key1-3.m4s",
-                    "bipbop_480_624kbps-cenc-audio-key1-4.m4s",
-                  ],
+        name: "audio",
+        type: 'audio/mp4; codecs="mp4a.40.2"',
+        fragments: [
+          "bipbop_480_624kbps-cenc-audio-key1-init.mp4",
+          "bipbop_480_624kbps-cenc-audio-key1-1.m4s",
+          "bipbop_480_624kbps-cenc-audio-key1-2.m4s",
+          "bipbop_480_624kbps-cenc-audio-key1-3.m4s",
+          "bipbop_480_624kbps-cenc-audio-key1-4.m4s",
+        ],
       },
       {
-        name:"video",
-        type:"video/mp4; codecs=\"avc1.64000d\"",
-        fragments:[ "bipbop_480_624kbps-cenc-video-key1-init.mp4",
-                    "bipbop_480_624kbps-cenc-video-key1-1.m4s",
-                    "bipbop_300_215kbps-cenc-video-key2-init.mp4",
-                    "bipbop_300_215kbps-cenc-video-key2-2.m4s",
-                  ],
+        name: "video",
+        type: 'video/mp4; codecs="avc1.64000d"',
+        fragments: [
+          "bipbop_480_624kbps-cenc-video-key1-init.mp4",
+          "bipbop_480_624kbps-cenc-video-key1-1.m4s",
+          "bipbop_300_215kbps-cenc-video-key2-init.mp4",
+          "bipbop_300_215kbps-cenc-video-key2-2.m4s",
+        ],
       },
     ],
     keys: {
       // "keyid" : "key"
-      "7e571d037e571d037e571d037e571d11" : "7e5733337e5733337e5733337e573311",
-      "7e571d037e571d037e571d037e571d12" : "7e5733337e5733337e5733337e573312",
-      "7e571d047e571d047e571d047e571d21" : "7e5744447e5744447e5744447e574421",
+      "7e571d037e571d037e571d037e571d11": "7e5733337e5733337e5733337e573311",
+      "7e571d037e571d037e571d037e571d12": "7e5733337e5733337e5733337e573312",
+      "7e571d047e571d047e571d047e571d21": "7e5744447e5744447e5744447e574421",
     },
-    sessionType:"temporary",
-    sessionCount:3,
-    duration:1.60,
+    sessionType: "temporary",
+    sessionCount: 3,
+    duration: 1.6,
   },
   {
-    name:"400x300 with 1st keys then 640x480 with 2nd keys",
+    name: "400x300 with 1st keys then 640x480 with 2nd keys",
     tracks: [
       {
-        name:"audio",
-        type:"audio/mp4; codecs=\"mp4a.40.2\"",
-        fragments:[ "bipbop_300_215kbps-cenc-audio-key1-init.mp4",
-                    "bipbop_300_215kbps-cenc-audio-key1-1.m4s",
-                    "bipbop_300_215kbps-cenc-audio-key1-2.m4s",
-                    "bipbop_300_215kbps-cenc-audio-key1-3.m4s",
-                    "bipbop_300_215kbps-cenc-audio-key1-4.m4s",
-                  ],
+        name: "audio",
+        type: 'audio/mp4; codecs="mp4a.40.2"',
+        fragments: [
+          "bipbop_300_215kbps-cenc-audio-key1-init.mp4",
+          "bipbop_300_215kbps-cenc-audio-key1-1.m4s",
+          "bipbop_300_215kbps-cenc-audio-key1-2.m4s",
+          "bipbop_300_215kbps-cenc-audio-key1-3.m4s",
+          "bipbop_300_215kbps-cenc-audio-key1-4.m4s",
+        ],
       },
       {
-        name:"video",
-        type:"video/mp4; codecs=\"avc1.64000d\"",
-        fragments:[ "bipbop_300_215kbps-cenc-video-key1-init.mp4",
-                    "bipbop_300_215kbps-cenc-video-key1-1.m4s",
-                    "bipbop_480_624kbps-cenc-video-key2-init.mp4",
-                    "bipbop_480_624kbps-cenc-video-key2-2.m4s",
-                  ],
+        name: "video",
+        type: 'video/mp4; codecs="avc1.64000d"',
+        fragments: [
+          "bipbop_300_215kbps-cenc-video-key1-init.mp4",
+          "bipbop_300_215kbps-cenc-video-key1-1.m4s",
+          "bipbop_480_624kbps-cenc-video-key2-init.mp4",
+          "bipbop_480_624kbps-cenc-video-key2-2.m4s",
+        ],
       },
     ],
     keys: {
       // "keyid" : "key"
-      "7e571d037e571d037e571d037e571d11" : "7e5733337e5733337e5733337e573311",
-      "7e571d037e571d037e571d037e571d12" : "7e5733337e5733337e5733337e573312",
-      "7e571d047e571d047e571d047e571d21" : "7e5744447e5744447e5744447e574421",
+      "7e571d037e571d037e571d037e571d11": "7e5733337e5733337e5733337e573311",
+      "7e571d037e571d037e571d037e571d12": "7e5733337e5733337e5733337e573312",
+      "7e571d047e571d047e571d047e571d21": "7e5744447e5744447e5744447e574421",
     },
-    sessionType:"temporary",
-    sessionCount:3,
-    duration:1.60,
+    sessionType: "temporary",
+    sessionCount: 3,
+    duration: 1.6,
   },
   {
-    name:"640x480@959kbps with 1st keys then 640x480@624kbps with 2nd keys",
+    name: "640x480@959kbps with 1st keys then 640x480@624kbps with 2nd keys",
     tracks: [
       {
-        name:"audio",
-        type:"audio/mp4; codecs=\"mp4a.40.2\"",
-        fragments:[ "bipbop_480_959kbps-cenc-audio-key1-init.mp4",
-                    "bipbop_480_959kbps-cenc-audio-key1-1.m4s",
-                    "bipbop_480_959kbps-cenc-audio-key1-2.m4s",
-                    "bipbop_480_959kbps-cenc-audio-key1-3.m4s",
-                    "bipbop_480_959kbps-cenc-audio-key1-4.m4s",
-                  ],
+        name: "audio",
+        type: 'audio/mp4; codecs="mp4a.40.2"',
+        fragments: [
+          "bipbop_480_959kbps-cenc-audio-key1-init.mp4",
+          "bipbop_480_959kbps-cenc-audio-key1-1.m4s",
+          "bipbop_480_959kbps-cenc-audio-key1-2.m4s",
+          "bipbop_480_959kbps-cenc-audio-key1-3.m4s",
+          "bipbop_480_959kbps-cenc-audio-key1-4.m4s",
+        ],
       },
       {
-        name:"video",
-        type:"video/mp4; codecs=\"avc1.64000d\"",
-        fragments:[ "bipbop_480_959kbps-cenc-video-key1-init.mp4",
-                    "bipbop_480_959kbps-cenc-video-key1-1.m4s",
-                    "bipbop_480_624kbps-cenc-video-key2-init.mp4",
-                    "bipbop_480_624kbps-cenc-video-key2-2.m4s",
-                  ],
+        name: "video",
+        type: 'video/mp4; codecs="avc1.64000d"',
+        fragments: [
+          "bipbop_480_959kbps-cenc-video-key1-init.mp4",
+          "bipbop_480_959kbps-cenc-video-key1-1.m4s",
+          "bipbop_480_624kbps-cenc-video-key2-init.mp4",
+          "bipbop_480_624kbps-cenc-video-key2-2.m4s",
+        ],
       },
     ],
     keys: {
       // "keyid" : "key"
-      "7e571d037e571d037e571d037e571d11" : "7e5733337e5733337e5733337e573311",
-      "7e571d037e571d037e571d037e571d12" : "7e5733337e5733337e5733337e573312",
-      "7e571d047e571d047e571d047e571d21" : "7e5744447e5744447e5744447e574421",
+      "7e571d037e571d037e571d037e571d11": "7e5733337e5733337e5733337e573311",
+      "7e571d037e571d037e571d037e571d12": "7e5733337e5733337e5733337e573312",
+      "7e571d047e571d047e571d047e571d21": "7e5744447e5744447e5744447e574421",
     },
-    sessionType:"temporary",
-    sessionCount:3,
-    duration:1.60,
+    sessionType: "temporary",
+    sessionCount: 3,
+    duration: 1.6,
   },
   {
-    name:"640x480@624kbps with 1st keys then 640x480@959kbps with 2nd keys",
+    name: "640x480@624kbps with 1st keys then 640x480@959kbps with 2nd keys",
     tracks: [
       {
-        name:"audio",
-        type:"audio/mp4; codecs=\"mp4a.40.2\"",
-        fragments:[ "bipbop_480_624kbps-cenc-audio-key1-init.mp4",
-                    "bipbop_480_624kbps-cenc-audio-key1-1.m4s",
-                    "bipbop_480_624kbps-cenc-audio-key1-2.m4s",
-                    "bipbop_480_624kbps-cenc-audio-key1-3.m4s",
-                    "bipbop_480_624kbps-cenc-audio-key1-4.m4s",
-                  ],
+        name: "audio",
+        type: 'audio/mp4; codecs="mp4a.40.2"',
+        fragments: [
+          "bipbop_480_624kbps-cenc-audio-key1-init.mp4",
+          "bipbop_480_624kbps-cenc-audio-key1-1.m4s",
+          "bipbop_480_624kbps-cenc-audio-key1-2.m4s",
+          "bipbop_480_624kbps-cenc-audio-key1-3.m4s",
+          "bipbop_480_624kbps-cenc-audio-key1-4.m4s",
+        ],
       },
       {
-        name:"video",
-        type:"video/mp4; codecs=\"avc1.64000d\"",
-        fragments:[ "bipbop_480_624kbps-cenc-video-key1-init.mp4",
-                    "bipbop_480_624kbps-cenc-video-key1-1.m4s",
-                    "bipbop_480_959kbps-cenc-video-key2-init.mp4",
-                    "bipbop_480_959kbps-cenc-video-key2-2.m4s",
-                  ],
+        name: "video",
+        type: 'video/mp4; codecs="avc1.64000d"',
+        fragments: [
+          "bipbop_480_624kbps-cenc-video-key1-init.mp4",
+          "bipbop_480_624kbps-cenc-video-key1-1.m4s",
+          "bipbop_480_959kbps-cenc-video-key2-init.mp4",
+          "bipbop_480_959kbps-cenc-video-key2-2.m4s",
+        ],
       },
     ],
     keys: {
       // "keyid" : "key"
-      "7e571d037e571d037e571d037e571d11" : "7e5733337e5733337e5733337e573311",
-      "7e571d037e571d037e571d037e571d12" : "7e5733337e5733337e5733337e573312",
-      "7e571d047e571d047e571d047e571d21" : "7e5744447e5744447e5744447e574421",
+      "7e571d037e571d037e571d037e571d11": "7e5733337e5733337e5733337e573311",
+      "7e571d037e571d037e571d037e571d12": "7e5733337e5733337e5733337e573312",
+      "7e571d047e571d047e571d047e571d21": "7e5744447e5744447e5744447e574421",
     },
-    sessionType:"temporary",
-    sessionCount:3,
-    duration:1.60,
+    sessionType: "temporary",
+    sessionCount: 3,
+    duration: 1.6,
   },
   {
-    name:"400x300 with presentation size 533x300",
+    name: "400x300 with presentation size 533x300",
     tracks: [
       {
-        name:"audio",
-        type:"audio/mp4; codecs=\"mp4a.40.2\"",
-        fragments:[ "bipbop_300wp_227kbps-cenc-audio-key1-init.mp4",
-                    "bipbop_300wp_227kbps-cenc-audio-key1-1.m4s",
-                    "bipbop_300wp_227kbps-cenc-audio-key1-2.m4s",
-                    "bipbop_300wp_227kbps-cenc-audio-key1-3.m4s",
-                    "bipbop_300wp_227kbps-cenc-audio-key1-4.m4s",
-                  ],
+        name: "audio",
+        type: 'audio/mp4; codecs="mp4a.40.2"',
+        fragments: [
+          "bipbop_300wp_227kbps-cenc-audio-key1-init.mp4",
+          "bipbop_300wp_227kbps-cenc-audio-key1-1.m4s",
+          "bipbop_300wp_227kbps-cenc-audio-key1-2.m4s",
+          "bipbop_300wp_227kbps-cenc-audio-key1-3.m4s",
+          "bipbop_300wp_227kbps-cenc-audio-key1-4.m4s",
+        ],
       },
       {
-        name:"video",
-        type:"video/mp4; codecs=\"avc1.64000d\"",
-        fragments:[ "bipbop_300wp_227kbps-cenc-video-key1-init.mp4",
-                    "bipbop_300wp_227kbps-cenc-video-key1-1.m4s",
-                    "bipbop_300wp_227kbps-cenc-video-key1-2.m4s",
-                  ],
+        name: "video",
+        type: 'video/mp4; codecs="avc1.64000d"',
+        fragments: [
+          "bipbop_300wp_227kbps-cenc-video-key1-init.mp4",
+          "bipbop_300wp_227kbps-cenc-video-key1-1.m4s",
+          "bipbop_300wp_227kbps-cenc-video-key1-2.m4s",
+        ],
       },
     ],
     keys: {
       // "keyid" : "key"
-      "7e571d037e571d037e571d037e571d11" : "7e5733337e5733337e5733337e573311",
-      "7e571d047e571d047e571d047e571d21" : "7e5744447e5744447e5744447e574421",
+      "7e571d037e571d037e571d037e571d11": "7e5733337e5733337e5733337e573311",
+      "7e571d047e571d047e571d047e571d21": "7e5744447e5744447e5744447e574421",
     },
-    sessionType:"temporary",
-    sessionCount:2,
-    duration:1.60,
+    sessionType: "temporary",
+    sessionCount: 2,
+    duration: 1.6,
   },
   {
-    name:"400x300 as-is then 400x300 presented as 533x300",
+    name: "400x300 as-is then 400x300 presented as 533x300",
     tracks: [
       {
-        name:"audio",
-        type:"audio/mp4; codecs=\"mp4a.40.2\"",
-        fragments:[
-                    "bipbop_300_215kbps-cenc-audio-key1-init.mp4",
-                    "bipbop_300_215kbps-cenc-audio-key1-1.m4s",
-                    "bipbop_300_215kbps-cenc-audio-key1-2.m4s",
-                    "bipbop_300_215kbps-cenc-audio-key1-3.m4s",
-                    "bipbop_300_215kbps-cenc-audio-key1-4.m4s",
-                  ],
+        name: "audio",
+        type: 'audio/mp4; codecs="mp4a.40.2"',
+        fragments: [
+          "bipbop_300_215kbps-cenc-audio-key1-init.mp4",
+          "bipbop_300_215kbps-cenc-audio-key1-1.m4s",
+          "bipbop_300_215kbps-cenc-audio-key1-2.m4s",
+          "bipbop_300_215kbps-cenc-audio-key1-3.m4s",
+          "bipbop_300_215kbps-cenc-audio-key1-4.m4s",
+        ],
       },
       {
-        name:"video",
-        type:"video/mp4; codecs=\"avc1.64000d\"",
-        fragments:[ "bipbop_300_215kbps-cenc-video-key1-init.mp4",
-                    "bipbop_300_215kbps-cenc-video-key1-1.m4s",
-                    "bipbop_300wp_227kbps-cenc-video-key1-init.mp4",
-                    "bipbop_300wp_227kbps-cenc-video-key1-2.m4s",
-                  ],
+        name: "video",
+        type: 'video/mp4; codecs="avc1.64000d"',
+        fragments: [
+          "bipbop_300_215kbps-cenc-video-key1-init.mp4",
+          "bipbop_300_215kbps-cenc-video-key1-1.m4s",
+          "bipbop_300wp_227kbps-cenc-video-key1-init.mp4",
+          "bipbop_300wp_227kbps-cenc-video-key1-2.m4s",
+        ],
       },
     ],
     keys: {
       // "keyid" : "key"
-      "7e571d037e571d037e571d037e571d11" : "7e5733337e5733337e5733337e573311",
-      "7e571d047e571d047e571d047e571d21" : "7e5744447e5744447e5744447e574421",
+      "7e571d037e571d037e571d037e571d11": "7e5733337e5733337e5733337e573311",
+      "7e571d047e571d047e571d047e571d21": "7e5744447e5744447e5744447e574421",
     },
-    sessionType:"temporary",
-    sessionCount:3,
-    duration:1.60,
+    sessionType: "temporary",
+    sessionCount: 3,
+    duration: 1.6,
   },
   {
-    name:"400x225",
+    name: "400x225",
     tracks: [
       {
-        name:"audio",
-        type:"audio/mp4; codecs=\"mp4a.40.2\"",
-        fragments:[ "bipbop_225w_175kbps-cenc-audio-key1-init.mp4",
-                    "bipbop_225w_175kbps-cenc-audio-key1-1.m4s",
-                    "bipbop_225w_175kbps-cenc-audio-key1-2.m4s",
-                    "bipbop_225w_175kbps-cenc-audio-key1-3.m4s",
-                    "bipbop_225w_175kbps-cenc-audio-key1-4.m4s",
-                  ],
+        name: "audio",
+        type: 'audio/mp4; codecs="mp4a.40.2"',
+        fragments: [
+          "bipbop_225w_175kbps-cenc-audio-key1-init.mp4",
+          "bipbop_225w_175kbps-cenc-audio-key1-1.m4s",
+          "bipbop_225w_175kbps-cenc-audio-key1-2.m4s",
+          "bipbop_225w_175kbps-cenc-audio-key1-3.m4s",
+          "bipbop_225w_175kbps-cenc-audio-key1-4.m4s",
+        ],
       },
       {
-        name:"video",
-        type:"video/mp4; codecs=\"avc1.64000d\"",
-        fragments:[ "bipbop_225w_175kbps-cenc-video-key1-init.mp4",
-                    "bipbop_225w_175kbps-cenc-video-key1-1.m4s",
-                  ],
+        name: "video",
+        type: 'video/mp4; codecs="avc1.64000d"',
+        fragments: [
+          "bipbop_225w_175kbps-cenc-video-key1-init.mp4",
+          "bipbop_225w_175kbps-cenc-video-key1-1.m4s",
+        ],
       },
     ],
     keys: {
       // "keyid" : "key"
-      "7e571d037e571d037e571d037e571d11" : "7e5733337e5733337e5733337e573311",
-      "7e571d047e571d047e571d047e571d21" : "7e5744447e5744447e5744447e574421",
+      "7e571d037e571d037e571d037e571d11": "7e5733337e5733337e5733337e573311",
+      "7e571d047e571d047e571d047e571d21": "7e5744447e5744447e5744447e574421",
     },
-    sessionType:"temporary",
-    sessionCount:2,
-    duration:1.60,
+    sessionType: "temporary",
+    sessionCount: 2,
+    duration: 1.6,
   },
   {
-    name:"640x360",
+    name: "640x360",
     tracks: [
       {
-        name:"audio",
-        type:"audio/mp4; codecs=\"mp4a.40.2\"",
-        fragments:[ "bipbop_360w_253kbps-cenc-audio-key1-init.mp4",
-                    "bipbop_360w_253kbps-cenc-audio-key1-1.m4s",
-                    "bipbop_360w_253kbps-cenc-audio-key1-2.m4s",
-                    "bipbop_360w_253kbps-cenc-audio-key1-3.m4s",
-                    "bipbop_360w_253kbps-cenc-audio-key1-4.m4s",
-                  ],
+        name: "audio",
+        type: 'audio/mp4; codecs="mp4a.40.2"',
+        fragments: [
+          "bipbop_360w_253kbps-cenc-audio-key1-init.mp4",
+          "bipbop_360w_253kbps-cenc-audio-key1-1.m4s",
+          "bipbop_360w_253kbps-cenc-audio-key1-2.m4s",
+          "bipbop_360w_253kbps-cenc-audio-key1-3.m4s",
+          "bipbop_360w_253kbps-cenc-audio-key1-4.m4s",
+        ],
       },
       {
-        name:"video",
-        type:"video/mp4; codecs=\"avc1.64000d\"",
-        fragments:[ "bipbop_360w_253kbps-cenc-video-key1-init.mp4",
-                    "bipbop_360w_253kbps-cenc-video-key1-1.m4s",
-                  ],
+        name: "video",
+        type: 'video/mp4; codecs="avc1.64000d"',
+        fragments: [
+          "bipbop_360w_253kbps-cenc-video-key1-init.mp4",
+          "bipbop_360w_253kbps-cenc-video-key1-1.m4s",
+        ],
       },
     ],
     keys: {
       // "keyid" : "key"
-      "7e571d037e571d037e571d037e571d11" : "7e5733337e5733337e5733337e573311",
-      "7e571d047e571d047e571d047e571d21" : "7e5744447e5744447e5744447e574421",
+      "7e571d037e571d037e571d037e571d11": "7e5733337e5733337e5733337e573311",
+      "7e571d047e571d047e571d047e571d21": "7e5744447e5744447e5744447e574421",
     },
-    sessionType:"temporary",
-    sessionCount:2,
-    duration:1.60,
+    sessionType: "temporary",
+    sessionCount: 2,
+    duration: 1.6,
   },
   {
-    name:"400x225 then 640x360",
+    name: "400x225 then 640x360",
     tracks: [
       {
-        name:"audio",
-        type:"audio/mp4; codecs=\"mp4a.40.2\"",
-        fragments:[ "bipbop_225w_175kbps-cenc-audio-key1-init.mp4",
-                    "bipbop_225w_175kbps-cenc-audio-key1-1.m4s",
-                    "bipbop_225w_175kbps-cenc-audio-key1-2.m4s",
-                    "bipbop_225w_175kbps-cenc-audio-key1-3.m4s",
-                    "bipbop_225w_175kbps-cenc-audio-key1-4.m4s",
-                  ],
+        name: "audio",
+        type: 'audio/mp4; codecs="mp4a.40.2"',
+        fragments: [
+          "bipbop_225w_175kbps-cenc-audio-key1-init.mp4",
+          "bipbop_225w_175kbps-cenc-audio-key1-1.m4s",
+          "bipbop_225w_175kbps-cenc-audio-key1-2.m4s",
+          "bipbop_225w_175kbps-cenc-audio-key1-3.m4s",
+          "bipbop_225w_175kbps-cenc-audio-key1-4.m4s",
+        ],
       },
       {
-        name:"video",
-        type:"video/mp4; codecs=\"avc1.64000d\"",
-        fragments:[ "bipbop_225w_175kbps-cenc-video-key1-init.mp4",
-                    "bipbop_225w_175kbps-cenc-video-key1-1.m4s",
-                    "bipbop_360w_253kbps-cenc-video-key2-init.mp4",
-                    "bipbop_360w_253kbps-cenc-video-key2-1.m4s",
-                  ],
+        name: "video",
+        type: 'video/mp4; codecs="avc1.64000d"',
+        fragments: [
+          "bipbop_225w_175kbps-cenc-video-key1-init.mp4",
+          "bipbop_225w_175kbps-cenc-video-key1-1.m4s",
+          "bipbop_360w_253kbps-cenc-video-key2-init.mp4",
+          "bipbop_360w_253kbps-cenc-video-key2-1.m4s",
+        ],
       },
     ],
     keys: {
       // "keyid" : "key"
-      "7e571d037e571d037e571d037e571d11" : "7e5733337e5733337e5733337e573311",
-      "7e571d047e571d047e571d047e571d21" : "7e5744447e5744447e5744447e574421",
-      "7e571d037e571d037e571d037e571d12" : "7e5733337e5733337e5733337e573312",
+      "7e571d037e571d037e571d037e571d11": "7e5733337e5733337e5733337e573311",
+      "7e571d047e571d047e571d047e571d21": "7e5744447e5744447e5744447e574421",
+      "7e571d037e571d037e571d037e571d12": "7e5733337e5733337e5733337e573312",
     },
-    sessionType:"temporary",
-    sessionCount:3,
-    duration:1.60,
+    sessionType: "temporary",
+    sessionCount: 3,
+    duration: 1.6,
   },
   {
-    name:"640x360 then 640x480",
+    name: "640x360 then 640x480",
     tracks: [
       {
-        name:"audio",
-        type:"audio/mp4; codecs=\"mp4a.40.2\"",
-        fragments:[ "bipbop_360w_253kbps-cenc-audio-key1-init.mp4",
-                    "bipbop_360w_253kbps-cenc-audio-key1-1.m4s",
-                    "bipbop_360w_253kbps-cenc-audio-key1-2.m4s",
-                    "bipbop_360w_253kbps-cenc-audio-key1-3.m4s",
-                    "bipbop_360w_253kbps-cenc-audio-key1-4.m4s",
-                  ],
+        name: "audio",
+        type: 'audio/mp4; codecs="mp4a.40.2"',
+        fragments: [
+          "bipbop_360w_253kbps-cenc-audio-key1-init.mp4",
+          "bipbop_360w_253kbps-cenc-audio-key1-1.m4s",
+          "bipbop_360w_253kbps-cenc-audio-key1-2.m4s",
+          "bipbop_360w_253kbps-cenc-audio-key1-3.m4s",
+          "bipbop_360w_253kbps-cenc-audio-key1-4.m4s",
+        ],
       },
       {
-        name:"video",
-        type:"video/mp4; codecs=\"avc1.64000d\"",
-        fragments:[ "bipbop_360w_253kbps-cenc-video-key1-init.mp4",
-                    "bipbop_360w_253kbps-cenc-video-key1-1.m4s",
-                    "bipbop_480_624kbps-cenc-video-key2-init.mp4",
-                    "bipbop_480_624kbps-cenc-video-key2-2.m4s",
-                  ],
+        name: "video",
+        type: 'video/mp4; codecs="avc1.64000d"',
+        fragments: [
+          "bipbop_360w_253kbps-cenc-video-key1-init.mp4",
+          "bipbop_360w_253kbps-cenc-video-key1-1.m4s",
+          "bipbop_480_624kbps-cenc-video-key2-init.mp4",
+          "bipbop_480_624kbps-cenc-video-key2-2.m4s",
+        ],
       },
     ],
     keys: {
       // "keyid" : "key"
-      "7e571d037e571d037e571d037e571d11" : "7e5733337e5733337e5733337e573311",
-      "7e571d047e571d047e571d047e571d21" : "7e5744447e5744447e5744447e574421",
-      "7e571d037e571d037e571d037e571d12" : "7e5733337e5733337e5733337e573312",
+      "7e571d037e571d037e571d037e571d11": "7e5733337e5733337e5733337e573311",
+      "7e571d047e571d047e571d047e571d21": "7e5744447e5744447e5744447e574421",
+      "7e571d037e571d037e571d037e571d12": "7e5733337e5733337e5733337e573312",
     },
-    sessionType:"temporary",
-    sessionCount:3,
-    duration:1.60,
+    sessionType: "temporary",
+    sessionCount: 3,
+    duration: 1.6,
   },
   {
     // File generated with shaka packager:
     // packager-osx --enable_raw_key_encryption --keys label=:key_id=7e571d047e571d047e571d047e571d21:key=7e5744447e5744447e5744447e574421 --segment_duration 1 --clear_lead 0 in=test-flac.mp4,stream=audio,output=flac-sample-cenc.mp4
     name: "flac in mp4 clearkey",
     tracks: [
       {
-        name:"audio",
-        type:"audio/mp4; codecs=\"flac\"",
-        fragments:[ "flac-sample-cenc.mp4",
-                  ],
+        name: "audio",
+        type: 'audio/mp4; codecs="flac"',
+        fragments: ["flac-sample-cenc.mp4"],
       },
     ],
     keys: {
       // "keyid" : "key"
-      "7e571d047e571d047e571d047e571d21" : "7e5744447e5744447e5744447e574421",
+      "7e571d047e571d047e571d047e571d21": "7e5744447e5744447e5744447e574421",
     },
-    sessionType:"temporary",
-    sessionCount:1,
-    duration:2.05,
+    sessionType: "temporary",
+    sessionCount: 1,
+    duration: 2.05,
   },
   {
     // File generated with shaka packager:
     // packager-osx --enable_raw_key_encryption --keys label=:key_id=7e571d047e571d047e571d047e571d21:key=7e5744447e5744447e5744447e574421 --segment_duration 1 --clear_lead 0 in=test-opus.mp4,stream=audio,output=opus-sample-cenc.mp4
     name: "opus in mp4 clearkey",
     tracks: [
       {
-        name:"audio",
-        type:"audio/mp4; codecs=\"opus\"",
-        fragments:[ "opus-sample-cenc.mp4",
-                  ],
+        name: "audio",
+        type: 'audio/mp4; codecs="opus"',
+        fragments: ["opus-sample-cenc.mp4"],
       },
     ],
     keys: {
       // "keyid" : "key"
-      "7e571d047e571d047e571d047e571d21" : "7e5744447e5744447e5744447e574421",
+      "7e571d047e571d047e571d047e571d21": "7e5744447e5744447e5744447e574421",
     },
-    sessionType:"temporary",
-    sessionCount:1,
-    duration:1.98,
+    sessionType: "temporary",
+    sessionCount: 1,
+    duration: 1.98,
   },
   {
     name: "WebM vorbis audio & vp8 video clearkey",
     tracks: [
       {
-        name:"audio",
-        type:"audio/webm; codecs=\"vorbis\"",
-        fragments:[ "bipbop_360w_253kbps-clearkey-audio.webm",
-                  ],
+        name: "audio",
+        type: 'audio/webm; codecs="vorbis"',
+        fragments: ["bipbop_360w_253kbps-clearkey-audio.webm"],
       },
       {
-        name:"video",
-        type:"video/webm; codecs=\"vp8\"",
-        fragments:[ "bipbop_360w_253kbps-clearkey-video-vp8.webm",
-                  ],
+        name: "video",
+        type: 'video/webm; codecs="vp8"',
+        fragments: ["bipbop_360w_253kbps-clearkey-video-vp8.webm"],
       },
     ],
     keys: {
       // "keyid" : "key"
-      "f1f3ee1790527e9de47217d43835f76a" : "97b9ddc459c8d5ff23c1f2754c95abe8",
-      "8b5df745ad84145b5617c33116e35a67" : "bddfd35dd9be033ee73bc18bc1885056",
+      f1f3ee1790527e9de47217d43835f76a: "97b9ddc459c8d5ff23c1f2754c95abe8",
+      "8b5df745ad84145b5617c33116e35a67": "bddfd35dd9be033ee73bc18bc1885056",
     },
-    sessionType:"temporary",
-    sessionCount:2,
-    duration:1.60,
+    sessionType: "temporary",
+    sessionCount: 2,
+    duration: 1.6,
   },
   {
     name: "WebM vorbis audio & vp9 video clearkey",
     tracks: [
       {
-        name:"audio",
-        type:"audio/webm; codecs=\"vorbis\"",
-        fragments:[ "bipbop_360w_253kbps-clearkey-audio.webm",
-                  ],
+        name: "audio",
+        type: 'audio/webm; codecs="vorbis"',
+        fragments: ["bipbop_360w_253kbps-clearkey-audio.webm"],
       },
       {
-        name:"video",
-        type:"video/webm; codecs=\"vp9\"",
-        fragments:[ "bipbop_360w_253kbps-clearkey-video-vp9.webm",
-                  ],
+        name: "video",
+        type: 'video/webm; codecs="vp9"',
+        fragments: ["bipbop_360w_253kbps-clearkey-video-vp9.webm"],
       },
     ],
     keys: {
       // "keyid" : "key"
-      "f1f3ee1790527e9de47217d43835f76a" : "97b9ddc459c8d5ff23c1f2754c95abe8",
-      "eedf63a94fa7c398ee094f123a4ee709" : "973b679a746c82f3acdb856b30e9378e",
+      f1f3ee1790527e9de47217d43835f76a: "97b9ddc459c8d5ff23c1f2754c95abe8",
+      eedf63a94fa7c398ee094f123a4ee709: "973b679a746c82f3acdb856b30e9378e",
     },
-    sessionType:"temporary",
-    sessionCount:2,
-    duration:1.60,
+    sessionType: "temporary",
+    sessionCount: 2,
+    duration: 1.6,
   },
   {
     name: "WebM vorbis audio & vp9 video clearkey with subsample encryption",
     tracks: [
       {
-        name:"audio",
-        type:"audio/webm; codecs=\"vorbis\"",
-        fragments:[ "sintel-short-clearkey-subsample-encrypted-audio.webm",
-                  ],
+        name: "audio",
+        type: 'audio/webm; codecs="vorbis"',
+        fragments: ["sintel-short-clearkey-subsample-encrypted-audio.webm"],
       },
       {
-        name:"video",
-        type:"video/webm; codecs=\"vp9\"",
-        fragments:[ "sintel-short-clearkey-subsample-encrypted-video.webm",
-                  ],
+        name: "video",
+        type: 'video/webm; codecs="vp9"',
+        fragments: ["sintel-short-clearkey-subsample-encrypted-video.webm"],
       },
     ],
     keys: {
       // "keyid" : "key"
-      "2cdb0ed6119853e7850671c3e9906c3c" : "808B9ADAC384DE1E4F56140F4AD76194",
+      "2cdb0ed6119853e7850671c3e9906c3c": "808B9ADAC384DE1E4F56140F4AD76194",
     },
-    sessionType:"temporary",
-    sessionCount:2,
-    duration:2.0,
+    sessionType: "temporary",
+    sessionCount: 2,
+    duration: 2.0,
   },
 ];
 
 var gEMENonMSEFailTests = [
   {
-    name:"short-cenc.mp4",
-    audioType:"audio/mp4; codecs=\"mp4a.40.2\"",
-    videoType:"video/mp4; codecs=\"avc1.64000d\"",
-    duration:0.47,
+    name: "short-cenc.mp4",
+    audioType: 'audio/mp4; codecs="mp4a.40.2"',
+    videoType: 'video/mp4; codecs="avc1.64000d"',
+    duration: 0.47,
   },
 ];
 
 // These are files that are used for video decode suspend in
 // background tabs tests.
 var gDecodeSuspendTests = [
-  { name:"gizmo.mp4", type:"video/mp4", duration:5.56 },
-  { name:"gizmo-noaudio.mp4", type:"video/mp4", duration:5.56 },
-  { name:"gizmo.webm", type:'video/webm; codecs="vp9,opus"', duration:5.56 },
-  { name:"gizmo-noaudio.webm", type:'video/webm; codecs="vp9"', duration:5.56 }
+  { name: "gizmo.mp4", type: "video/mp4", duration: 5.56 },
+  { name: "gizmo-noaudio.mp4", type: "video/mp4", duration: 5.56 },
+  { name: "gizmo.webm", type: 'video/webm; codecs="vp9,opus"', duration: 5.56 },
+  {
+    name: "gizmo-noaudio.webm",
+    type: 'video/webm; codecs="vp9"',
+    duration: 5.56,
+  },
 ];
 
 function checkMetadata(msg, e, test) {
   if (test.width) {
     is(e.videoWidth, test.width, msg + " video width");
   }
   if (test.height) {
     is(e.videoHeight, test.height, msg + " video height");
   }
   if (test.duration) {
-    ok(Math.abs(e.duration - test.duration) < 0.1,
-       msg + " duration (" + e.duration + ") should be around " + test.duration);
+    ok(
+      Math.abs(e.duration - test.duration) < 0.1,
+      msg + " duration (" + e.duration + ") should be around " + test.duration
+    );
   }
-  is(!!test.keys, SpecialPowers.do_lookupGetter(e, "isEncrypted").apply(e),
-     msg + " isEncrypted should be true if we have decryption keys");
+  is(
+    !!test.keys,
+    SpecialPowers.do_lookupGetter(e, "isEncrypted").apply(e),
+    msg + " isEncrypted should be true if we have decryption keys"
+  );
 }
 
 // Returns the first test from candidates array which we can play with the
 // installed video backends.
 function getPlayableVideo(candidates) {
   var resources = getPlayableVideos(candidates);
-  if (resources.length > 0)
+  if (resources.length > 0) {
     return resources[0];
+  }
   return null;
 }
 
 function getPlayableVideos(candidates) {
   var v = manifestVideo();
-  return candidates.filter(function(x){return /^video/.test(x.type) && v.canPlayType(x.type);});
+  return candidates.filter(function(x) {
+    return /^video/.test(x.type) && v.canPlayType(x.type);
+  });
 }
 
 function getPlayableAudio(candidates) {
   var v = manifestVideo();
-  var resources = candidates.filter(function(x){return /^audio/.test(x.type) && v.canPlayType(x.type);});
-  if (resources.length > 0)
+  var resources = candidates.filter(function(x) {
+    return /^audio/.test(x.type) && v.canPlayType(x.type);
+  });
+  if (resources.length > 0) {
     return resources[0];
+  }
   return null;
 }
 
 // Returns the type of element that should be created for the given mimetype.
 function getMajorMimeType(mimetype) {
   if (/^video/.test(mimetype)) {
     return "video";
-  } else {
-    return "audio";
   }
+  return "audio";
 }
 
 // Force releasing decoder to avoid timeout in waiting for decoding resource.
 function removeNodeAndSource(n) {
   n.remove();
   // reset |srcObject| first since it takes precedence over |src|.
   n.srcObject = null;
   n.removeAttribute("src");
   n.load();
   while (n.firstChild) {
     n.firstChild.remove();
   }
 }
 
 function once(target, name, cb) {
   var p = new Promise(function(resolve, reject) {
-    target.addEventListener(name, function() {
-      resolve();
-    }, {once: true});
+    target.addEventListener(
+      name,
+      function() {
+        resolve();
+      },
+      { once: true }
+    );
   });
   if (cb) {
     p.then(cb);
   }
   return p;
 }
 
 /**
  * @param {HTMLMediaElement} video target of interest.
  * @param {string} eventName the event to wait on.
  * @returns {Promise} A promise that is resolved when event happens.
  */
 function nextEvent(video, eventName) {
-  return new Promise(function (resolve, reject) {
-    let f = function (event) {
-      video.removeEventListener(eventName, f, false);
+  return new Promise(function(resolve, reject) {
+    let f = function(event) {
+      video.removeEventListener(eventName, f);
       resolve(event);
     };
-    video.addEventListener(eventName, f, false);
+    video.addEventListener(eventName, f);
   });
 }
 
 function TimeStamp(token) {
   function pad(x) {
-    return (x < 10) ? "0" + x : x;
+    return x < 10 ? "0" + x : x;
   }
   var now = new Date();
   var ms = now.getMilliseconds();
-  var time = "[" +
-             pad(now.getHours()) + ":" +
-             pad(now.getMinutes()) + ":" +
-             pad(now.getSeconds()) + "." +
-             ms +
-             "]" +
-             (ms < 10 ? "  " : (ms < 100 ? " " : ""));
-  return token ? (time + " " + token) : time;
+  var time =
+    "[" +
+    pad(now.getHours()) +
+    ":" +
+    pad(now.getMinutes()) +
+    ":" +
+    pad(now.getSeconds()) +
+    "." +
+    ms +
+    "]" +
+    // eslint-disable-next-line no-nested-ternary
+    (ms < 10 ? "  " : ms < 100 ? " " : "");
+  return token ? time + " " + token : time;
 }
 
 function Log(token, msg) {
   info(TimeStamp(token) + " " + msg);
 }
 
 // Number of tests to run in parallel.
 var PARALLEL_TESTS = 2;
 
 // Prefs to set before running tests.  Use this to improve coverage of
 // conditions that might not otherwise be encountered on the test data.
 var gTestPrefs = [
-  ['media.recorder.max_memory', 1024],
-  ['media.audio-max-decode-error', 0],
-  ['media.video-max-decode-error', 0],
+  ["media.recorder.max_memory", 1024],
+  ["media.audio-max-decode-error", 0],
+  ["media.video-max-decode-error", 0],
 ];
 
 // When true, we'll loop forever on whatever test we run. Use this to debug
 // intermittent test failures.
 const DEBUG_TEST_LOOP_FOREVER = false;
 
 // Manages a run of media tests. Runs them in chunks in order to limit
 // the number of media elements/threads running in parallel. This limits peak
@@ -1695,17 +2016,16 @@ const DEBUG_TEST_LOOP_FOREVER = false;
 //      element in one of the g*Tests above. Your startTest function must call
 //      MediaTestManager.start(token) if it starts a test. The test object is
 //      guaranteed to be playable by our supported decoders; you don't need to
 //      check canPlayType.
 //   3. When your tests finishes, call MediaTestManager.finished(), passing
 //      the token back to the manager. The manager may either start the next run
 //      or end the mochitest if all the tests are done.
 function MediaTestManager() {
-
   // Set a very large timeout to prevent Mochitest timeout.
   // Instead MediaTestManager will manage timeout of each test.
   SimpleTest.requestLongerTimeout(1000);
 
   // Return how many seconds elapsed since |begin|.
   function elapsedTime(begin) {
     var end = new Date();
     return (end.getTime() - begin.getTime()) / 1000;
@@ -1715,65 +2035,82 @@ function MediaTestManager() {
   // the user supplied 'startTest' function to initialize the test. This
   // function must accept two arguments, the test entry from the 'tests' array,
   // and a token. Call MediaTestManager.started(token) if you start the test,
   // and MediaTestManager.finished(token) when the test finishes. You don't have
   // to start every test, but if you call started() you *must* call finish()
   // else you'll timeout.
   this.runTests = function(tests, startTest) {
     this.startTime = new Date();
-    SimpleTest.info("Started " + this.startTime + " (" + this.startTime.getTime()/1000 + "s)");
+    SimpleTest.info(
+      "Started " +
+        this.startTime +
+        " (" +
+        this.startTime.getTime() / 1000 +
+        "s)"
+    );
     this.testNum = 0;
     this.tests = tests;
     this.startTest = startTest;
     this.tokens = [];
     this.isShutdown = false;
     this.numTestsRunning = 0;
     this.handlers = {};
     this.timers = {};
 
     // Always wait for explicit finish.
     SimpleTest.waitForExplicitFinish();
-    SpecialPowers.pushPrefEnv({'set': gTestPrefs}, () => {
+    SpecialPowers.pushPrefEnv({ set: gTestPrefs }, () => {
       this.nextTest();
     });
 
     SimpleTest.registerCleanupFunction(() => {
       if (this.tokens.length > 0) {
         info("Test timed out. Remaining tests=" + this.tokens);
       }
       for (var token of this.tokens) {
         var handler = this.handlers[token];
         if (handler && handler.ontimeout) {
           handler.ontimeout();
         }
       }
     });
-  }
+  };
 
   // Registers that the test corresponding to 'token' has been started.
   // Don't call more than once per token.
   this.started = function(token, handler) {
     this.tokens.push(token);
     this.numTestsRunning++;
     this.handlers[token] = handler;
 
     var onTimeout = async () => {
       ok(false, "Test timed out!");
       info(`${token} timed out!`);
       await dumpDebugInfoForToken(token);
       this.finished(token);
     };
     // Default timeout to 180s for each test.
     // Call SimpleTest._originalSetTimeout() to bypass the flaky timeout checker.
-    this.timers[token] = SimpleTest._originalSetTimeout.call(window, onTimeout, 180000);
+    this.timers[token] = SimpleTest._originalSetTimeout.call(
+      window,
+      onTimeout,
+      180000
+    );
 
-    is(this.numTestsRunning, this.tokens.length,
-       "[started " + token + " t=" + elapsedTime(this.startTime) + "] Length of array should match number of running tests");
-  }
+    is(
+      this.numTestsRunning,
+      this.tokens.length,
+      "[started " +
+        token +
+        " t=" +
+        elapsedTime(this.startTime) +
+        "] Length of array should match number of running tests"
+    );
+  };
 
   // Registers that the test corresponding to 'token' has finished. Call when
   // you've finished your test. If all tests are complete this will finish the
   // run, otherwise it may start up the next run. It's ok to call multiple times
   // per token.
   this.finished = function(token) {
     var i = this.tokens.indexOf(token);
     if (i != -1) {
@@ -1784,79 +2121,95 @@ function MediaTestManager() {
     if (this.timers[token]) {
       // Cancel the timer when the test finishes.
       clearTimeout(this.timers[token]);
       this.timers[token] = null;
     }
 
     info("[finished " + token + "] remaining= " + this.tokens);
     this.numTestsRunning--;
-    is(this.numTestsRunning, this.tokens.length,
-       "[finished " + token + " t=" + elapsedTime(this.startTime) + "] Length of array should match number of running tests");
+    is(
+      this.numTestsRunning,
+      this.tokens.length,
+      "[finished " +
+        token +
+        " t=" +
+        elapsedTime(this.startTime) +
+        "] Length of array should match number of running tests"
+    );
     if (this.tokens.length < PARALLEL_TESTS) {
       this.nextTest();
     }
-  }
+  };
 
   // Starts the next batch of tests, or finishes if they're all done.
   // Don't call this directly, call finished(token) when you're done.
   this.nextTest = function() {
-    while (this.testNum < this.tests.length && this.tokens.length < PARALLEL_TESTS) {
+    while (
+      this.testNum < this.tests.length &&
+      this.tokens.length < PARALLEL_TESTS
+    ) {
       var test = this.tests[this.testNum];
-      var token = (test.name ? (test.name + "-"): "") + this.testNum;
+      var token = (test.name ? test.name + "-" : "") + this.testNum;
       this.testNum++;
 
       if (DEBUG_TEST_LOOP_FOREVER && this.testNum == this.tests.length) {
         this.testNum = 0;
       }
 
       // Ensure we can play the resource type.
-      if (test.type && !document.createElement('video').canPlayType(test.type))
+      if (
+        test.type &&
+        !document.createElement("video").canPlayType(test.type)
+      ) {
         continue;
+      }
 
       // Do the init. This should start the test.
       this.startTest(test, token);
     }
 
-    if (this.testNum == this.tests.length &&
-        !DEBUG_TEST_LOOP_FOREVER &&
-        this.tokens.length == 0 &&
-        !this.isShutdown)
-    {
+    if (
+      this.testNum == this.tests.length &&
+      !DEBUG_TEST_LOOP_FOREVER &&
+      this.tokens.length == 0 &&
+      !this.isShutdown
+    ) {
       this.isShutdown = true;
       if (this.onFinished) {
         this.onFinished();
       }
       var onCleanup = () => {
         var end = new Date();
-        SimpleTest.info("Finished at " + end + " (" + (end.getTime() / 1000) + "s)");
+        SimpleTest.info(
+          "Finished at " + end + " (" + end.getTime() / 1000 + "s)"
+        );
         SimpleTest.info("Running time: " + elapsedTime(this.startTime) + "s");
         SimpleTest.finish();
       };
       mediaTestCleanup(onCleanup);
-      return;
     }
-  }
+  };
 }
 
 // Ensures we've got no active video or audio elements in the document, and
 // forces a GC to release the address space reserved by the decoders' threads'
 // stacks.
 function mediaTestCleanup(callback) {
-    var V = document.getElementsByTagName("video");
-    for (i=0; i<V.length; i++) {
-      removeNodeAndSource(V[i]);
-      V[i] = null;
-    }
-    var A = document.getElementsByTagName("audio");
-    for (i=0; i<A.length; i++) {
-      removeNodeAndSource(A[i]);
-      A[i] = null;
-    }
-    SpecialPowers.exactGC(callback);
+  var V = document.getElementsByTagName("video");
+  for (let i = 0; i < V.length; i++) {
+    removeNodeAndSource(V[i]);
+    V[i] = null;
+  }
+  var A = document.getElementsByTagName("audio");
+  for (let i = 0; i < A.length; i++) {
+    removeNodeAndSource(A[i]);
+    A[i] = null;
+  }
+  SpecialPowers.exactGC(callback);
 }
 
 async function dumpDebugInfoForToken(token) {
   for (let v of document.getElementsByTagName("video")) {
     if (token === v.token) {
       info(JSON.stringify(await SpecialPowers.wrap(v).mozRequestDebugInfo()));
       return;
     }
@@ -1872,15 +2225,19 @@ async function dumpDebugInfoForToken(tok
 // Could be undefined in a page opened by the parent test page
 // like file_access_controls.html.
 if ("SimpleTest" in window) {
   SimpleTest.requestFlakyTimeout("untriaged");
 
   // Register timeout function to dump debugging logs.
   SimpleTest.registerTimeoutFunction(async function() {
     for (const v of document.getElementsByTagName("video")) {
-      SimpleTest.info(JSON.stringify(await SpecialPowers.wrap(v).mozRequestDebugInfo()));
+      SimpleTest.info(
+        JSON.stringify(await SpecialPowers.wrap(v).mozRequestDebugInfo())
+      );
     }
     for (const a of document.getElementsByTagName("audio")) {
-      SimpleTest.info(JSON.stringify(await SpecialPowers.wrap(a).mozRequestDebugInfo()));
+      SimpleTest.info(
+        JSON.stringify(await SpecialPowers.wrap(a).mozRequestDebugInfo())
+      );
     }
   });
 }
--- a/dom/media/test/marionette/yttest/debug_info.js
+++ b/dom/media/test/marionette/yttest/debug_info.js
@@ -1,18 +1,20 @@
+/* global video, result, resolve */
+
 video.mozRequestDebugInfo().then(debugInfo => {
   // The parsing won't be necessary once we have bug 1542674
   try {
-    debugInfo = debugInfo.replace(/\t/g, '').split(/\n/g);
+    debugInfo = debugInfo.replace(/\t/g, "").split(/\n/g);
     var JSONDebugInfo = "{";
-      for(let g =0; g<debugInfo.length-1; g++){
-          var pair = debugInfo[g].split(": ");
-          JSONDebugInfo += '"' + pair[0] + '":"' + pair[1] + '",';
-      }
-      JSONDebugInfo = JSONDebugInfo.slice(0,JSONDebugInfo.length-1);
-      JSONDebugInfo += "}";
-      result["mozRequestDebugInfo"] = JSON.parse(JSONDebugInfo);
+    for (let g = 0; g < debugInfo.length - 1; g++) {
+      var pair = debugInfo[g].split(": ");
+      JSONDebugInfo += '"' + pair[0] + '":"' + pair[1] + '",';
+    }
+    JSONDebugInfo = JSONDebugInfo.slice(0, JSONDebugInfo.length - 1);
+    JSONDebugInfo += "}";
+    result.mozRequestDebugInfo = JSON.parse(JSONDebugInfo);
   } catch (err) {
     console.log(`Error '${err.toString()} in JSON.parse(${debugInfo})`);
-    result["mozRequestDebugInfo"] = debugInfo;
+    result.mozRequestDebugInfo = debugInfo;
   }
   resolve(result);
 });
--- a/dom/media/test/marionette/yttest/force_hd.js
+++ b/dom/media/test/marionette/yttest/force_hd.js
@@ -1,73 +1,91 @@
 // This parts forces the highest definition
 // https://addons.mozilla.org/en-US/firefox/addon/youtube-auto-hd-lq/
 // licence: MPL 2.0
 var config = {
-  "HD": true,
-  "LQ": false,
-  "ID": "auto-hd-lq-for-ytb",
-  "type": function (t) {
-    config.HD = t === 'hd';
-    config.LQ = t === 'lq';
+  HD: true,
+  LQ: false,
+  ID: "auto-hd-lq-for-ytb",
+  type(t) {
+    config.HD = t === "hd";
+    config.LQ = t === "lq";
   },
-  "quality": function () {
+  quality() {
     if (config.HD || config.LQ) {
-      var youtubePlayerListener = function (LQ, HD) {
-        return function youtubePlayerListener (e) {
+      var youtubePlayerListener = function(LQ, HD) {
+        return function(e) {
           if (e === 1) {
-            var player = document.getElementById('movie_player');
+            var player = document.getElementById("movie_player");
             if (player) {
               var levels = player.getAvailableQualityLevels();
               if (levels.length) {
-                var q = (HD && levels[0]) ? levels[0] : ((LQ && levels[levels.length - 2]) ? levels[levels.length - 2] : null);
+                var q =
+                  // eslint-disable-next-line no-nested-ternary
+                  HD && levels[0]
+                    ? levels[0]
+                    : LQ && levels[levels.length - 2]
+                    ? levels[levels.length - 2]
+                    : null;
                 if (q) {
                   player.setPlaybackQuality(q);
                   player.setPlaybackQualityRange(q, q);
                 }
               }
             }
           }
-        }
-      }
+        };
+      };
       /*  */
-      var inject = function () {
-        var action = function () {
-          var player = document.getElementById('movie_player');
+      var inject = function() {
+        var action = function() {
+          var player = document.getElementById("movie_player");
           if (player && player.addEventListener && player.getPlayerState) {
             player.addEventListener("onStateChange", "youtubePlayerListener");
-          } else window.setTimeout(action, 1000);
+          } else {
+            window.setTimeout(action, 1000);
+          }
         };
         /*  */
         action();
       };
       var script = document.getElementById(config.ID);
       if (!script) {
         script = document.createElement("script");
         script.setAttribute("type", "text/javascript");
         script.setAttribute("id", config.ID);
         document.documentElement.appendChild(script);
       }
       /*  */
-      script.textContent = "var youtubePlayerListener = (" + youtubePlayerListener + ')(' + config.LQ + ',' + config.HD  + ');(' + inject + ')();';
+      script.textContent =
+        "var youtubePlayerListener = (" +
+        youtubePlayerListener +
+        ")(" +
+        config.LQ +
+        "," +
+        config.HD +
+        ");(" +
+        inject +
+        ")();";
     }
-  }
+  },
 };
 
-  if (/^https?:\/\/www\.youtube.com\/watch\?/.test(document.location.href)) config.quality();
-  var content = document.getElementById('content');
-  if (content) {
-    var observer = new window.MutationObserver(function (e) {
-      e.forEach(function (m) {
-        if (m.addedNodes !== null) {
-          for (var i = 0; i < m.addedNodes.length; i++) {
-            if (m.addedNodes[i].id === 'movie_player') {
-              config.quality();
-              return;
-            }
+if (/^https?:\/\/www\.youtube.com\/watch\?/.test(document.location.href)) {
+  config.quality();
+}
+var content = document.getElementById("content");
+if (content) {
+  var observer = new window.MutationObserver(function(e) {
+    e.forEach(function(m) {
+      if (m.addedNodes !== null) {
+        for (var i = 0; i < m.addedNodes.length; i++) {
+          if (m.addedNodes[i].id === "movie_player") {
+            config.quality();
+            return;
           }
         }
-      });
+      }
     });
-    /*  */
-    observer.observe(content, {"childList": true, "subtree": true});
-  }
-
+  });
+  /*  */
+  observer.observe(content, { childList: true, subtree: true });
+}
--- a/dom/media/test/marionette/yttest/video_playback_quality.js
+++ b/dom/media/test/marionette/yttest/video_playback_quality.js
@@ -1,1 +1,2 @@
-var result = {"getVideoPlaybackQuality": video.getVideoPlaybackQuality()};
+/* global video */
+var result = { getVideoPlaybackQuality: video.getVideoPlaybackQuality() };
--- a/dom/media/test/play_promise.js
+++ b/dom/media/test/play_promise.js
@@ -1,3 +1,3 @@
 function getNotSupportedFile(name) {
   return name + ".bad";
-}
\ No newline at end of file
+}
--- a/dom/media/test/seek_support.js
+++ b/dom/media/test/seek_support.js
@@ -1,45 +1,61 @@
-var manager = new MediaTestManager;
+// This file expects manifest.js to be included in the same scope.
+/* import-globals-from manifest.js */
+// This file expects SEEK_TEST_NUMBER to be defined by the test.
+/* global SEEK_TEST_NUMBER */
+var manager = new MediaTestManager();
 
 function createTestArray() {
   var tests = [];
   var tmpVid = document.createElement("video");
 
-  for (var testNum=0; testNum<gSeekTests.length; testNum++) {
+  for (var testNum = 0; testNum < gSeekTests.length; testNum++) {
     var test = gSeekTests[testNum];
     if (!tmpVid.canPlayType(test.type)) {
       continue;
     }
 
-    var t = new Object;
+    var t = {};
     t.name = test.name;
     t.type = test.type;
     t.duration = test.duration;
     t.number = SEEK_TEST_NUMBER;
     tests.push(t);
   }
   return tests;
 }
 
 function startTest(test, token) {
-  var v = document.createElement('video');
-  v.token = token += "-seek" + test.number + ".js";
-  manager.started(v.token);
-  v.src = test.name;
-  v.preload = "metadata";
-  document.body.appendChild(v);
+  var video = document.createElement("video");
+  video.token = token += "-seek" + test.number + ".js";
+  manager.started(video.token);
+  video.src = test.name;
+  video.preload = "metadata";
+  document.body.appendChild(video);
   var name = test.name + " seek test " + test.number;
-  var localIs = function(name) { return function(a, b, msg) {
-    is(a, b, name + ": " + msg);
-  }}(name);
-  var localOk = function(name) { return function(a, msg) {
-    ok(a, name + ": " + msg);
-  }}(name);
-  var localFinish = function(v, manager) { return function() {
-    v.onerror = null;
-    removeNodeAndSource(v);
-    dump("SEEK-TEST: Finished " + name + " token: " + v.token + "\n");
-    manager.finished(v.token);
-  }}(v, manager);
+  var localIs = (function(n) {
+    return function(a, b, msg) {
+      is(a, b, n + ": " + msg);
+    };
+  })(name);
+  var localOk = (function(n) {
+    return function(a, msg) {
+      ok(a, n + ": " + msg);
+    };
+  })(name);
+  var localFinish = (function(v, m) {
+    return function() {
+      v.onerror = null;
+      removeNodeAndSource(v);
+      dump("SEEK-TEST: Finished " + name + " token: " + v.token + "\n");
+      m.finished(v.token);
+    };
+  })(video, manager);
   dump("SEEK-TEST: Started " + name + "\n");
-  window['test_seek' + test.number](v, test.duration/2, localIs, localOk, localFinish);
+  window["test_seek" + test.number](
+    video,
+    test.duration / 2,
+    localIs,
+    localOk,
+    localFinish
+  );
 }
--- a/dom/media/test/test_access_control.html
+++ b/dom/media/test/test_access_control.html
@@ -36,17 +36,19 @@ window.addEventListener("message", recei
 
 function receiveMessage(event)
 {
   if (event.origin !== "http://example.org") {
     ok(false, "Received message from wrong domain");
     return;
   }
 
-  if (event.data.done == "true")
-    return done();
+  if (event.data.done == "true") {
+    done();
+    return;
+  }
 
   ok(event.data.result, event.data.message);
 }
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/test/test_autoplay_policy_activation.html
+++ b/dom/media/test/test_autoplay_policy_activation.html
@@ -131,17 +131,17 @@
             should_play: true,
           },
 
         ];
 
         let child_url = "file_autoplay_policy_activation_window.html";
 
         async function runTest() {
-          for (test_case of test_cases) {
+          for (const test_case of test_cases) {
             // Run each test in a new window, to ensure its user gesture
             // activation state isn't tainted by preceeding tests.
             let child = window.open(child_url, "", "width=500,height=500");
             await once(child, "load");
             child.postMessage(test_case, window.origin);
             let result = await nextWindowMessage();
             SimpleTest.is(result.data.allowedToPlay, test_case.should_play, "allowed - " + test_case.name);
             SimpleTest.is(result.data.played, test_case.should_play, "played - " + test_case.name);
--- a/dom/media/test/test_autoplay_policy_eventdown_activation.html
+++ b/dom/media/test/test_autoplay_policy_eventdown_activation.html
@@ -26,25 +26,25 @@
 
         async function runTest() {
           // Run test in a new window, to ensure its user gesture
           // activation state isn't tainted by preceeding tests.
           {
             let child = window.open(child_url, "", "width=500,height=500");
             await once(child, "load");
             child.postMessage("run keydown test", window.origin);
-            let result = await nextWindowMessage();
+            await nextWindowMessage();
             child.close();
           }
 
           {
             let child = window.open(child_url, "", "width=500,height=500");
             await once(child, "load");
             child.postMessage("run mousedown test", window.origin);
-            let result = await nextWindowMessage();
+            await nextWindowMessage();
             child.close();
           }
 
           SimpleTest.finish();
         }
 
         SimpleTest.waitForExplicitFinish();
 
--- a/dom/media/test/test_autoplay_policy_key_blacklist.html
+++ b/dom/media/test/test_autoplay_policy_key_blacklist.html
@@ -28,17 +28,17 @@
         let child_url = "file_autoplay_policy_key_blacklist.html";
 
         async function runTest() {
           // Run test in a new window, to ensure its user gesture
           // activation state isn't tainted by preceeding tests.
           let child = window.open(child_url, "", "width=500,height=500");
           await once(child, "load");
           child.postMessage("run test", window.origin);
-          let result = await nextWindowMessage();
+          await nextWindowMessage();
           child.close();
           SimpleTest.finish();
         }
 
         SimpleTest.waitForExplicitFinish();
 
       </script>
     </pre>
--- a/dom/media/test/test_autoplay_policy_play_before_loadedmetadata.html
+++ b/dom/media/test/test_autoplay_policy_play_before_loadedmetadata.html
@@ -47,23 +47,23 @@
             shouldPlay: true,
             muted: true,
           },
         ];
 
         let child_url = "file_autoplay_policy_play_before_loadedmetadata.html";
 
         async function runTest() {
-          for (testCase of testCases) {
+          for (const testCase of testCases) {
             // Run each test in a new window, to ensure its user gesture
             // activation state isn't tainted by preceeding tests.
             let child = window.open(child_url, "", "width=500,height=500");
             await once(child, "load");
             child.postMessage(testCase, window.origin);
-            let result = await nextWindowMessage();
+            await nextWindowMessage();
             child.close();
           }
           SimpleTest.finish();
         }
 
         SimpleTest.waitForExplicitFinish();
 
       </script>
--- a/dom/media/test/test_autoplay_policy_unmute_pauses.html
+++ b/dom/media/test/test_autoplay_policy_unmute_pauses.html
@@ -38,23 +38,23 @@
             inaudible: 0.0,
             audible: 1.0,
           },
         ];
 
         let child_url = "file_autoplay_policy_unmute_pauses.html";
 
         async function runTest() {
-          for (testCase of testCases) {
+          for (const testCase of testCases) {
             // Run each test in a new window, to ensure its user gesture
             // activation state isn't tainted by preceeding tests.
             let child = window.open(child_url, "", "width=500,height=500");
             await once(child, "load");
             child.postMessage(testCase, window.origin);
-            let result = await nextWindowMessage();
+            await nextWindowMessage();
             child.close();
           }
           SimpleTest.finish();
         }
 
         SimpleTest.waitForExplicitFinish();
 
       </script>
--- a/dom/media/test/test_autoplay_policy_web_audio_AudioParamStream.html
+++ b/dom/media/test/test_autoplay_policy_web_audio_AudioParamStream.html
@@ -46,16 +46,17 @@ function setupTestPreferences() {
     ["media.autoplay.default", SpecialPowers.Ci.nsIAutoplay.BLOCKED],
     ["media.autoplay.enabled.user-gestures-needed", true],
     ["media.autoplay.block-webaudio", true],
     ["media.autoplay.block-event.enabled", true],
   ]});
 }
 
 function createAudioContext() {
+  /* global ac */
   window.ac = new AudioContext();
 
   ac.allowedToStart = new Promise(resolve => {
     ac.addEventListener("statechange", function() {
       if (ac.state === "running") {
         resolve();
       }
     }, {once: true});
@@ -96,17 +97,17 @@ function createAudioParams(nodeType) {
     case "panner":
       let panner = ac.createPanner();
       return [panner.positionX, panner.positionY, panner.positionZ,
               panner.orientationX, panner.orientationY, panner.orientationZ];
     case "stereoPanner":
       return [ac.createStereoPanner().pan];
     default:
       ok(false, `non-defined node type ${nodeType}.`);
-      return;
+      return [];
   }
 }
 
 function createAudioParamArrWithName(nodeType) {
   let audioParamsArr = createAudioParams(nodeType);
   for (let audioParam of audioParamsArr) {
     audioParam.name = nodeType;
   }
--- a/dom/media/test/test_autoplay_policy_web_audio_createMediaStreamSource.html
+++ b/dom/media/test/test_autoplay_policy_web_audio_createMediaStreamSource.html
@@ -41,16 +41,17 @@ function setupTestPreferences() {
     ["media.autoplay.default", SpecialPowers.Ci.nsIAutoplay.BLOCKED],
     ["media.autoplay.enabled.user-gestures-needed", true],
     ["media.autoplay.block-webaudio", true],
     ["media.autoplay.block-event.enabled", true],
   ]});
 }
 
 function createAudioContexts() {
+  /* global ac1, ac2 */
   window.ac1 = new AudioContext();
   window.ac2 = new AudioContext();
 
   ac1.allowedToStart = new Promise(resolve => {
     ac1.addEventListener("statechange", function() {
       if (ac1.state === "running") {
         resolve();
       }
--- a/dom/media/test/test_autoplay_policy_web_audio_mediaElementAudioSourceNode.html
+++ b/dom/media/test/test_autoplay_policy_web_audio_mediaElementAudioSourceNode.html
@@ -44,16 +44,17 @@ function setupTestPreferences() {
     ["media.autoplay.default", SpecialPowers.Ci.nsIAutoplay.BLOCKED],
     ["media.autoplay.enabled.user-gestures-needed", true],
     ["media.autoplay.block-webaudio", true],
     ["media.autoplay.block-event.enabled", true],
   ]});
 }
 
 function createAudioContext() {
+  /* global ac */
   window.ac = new AudioContext();
 
   ac.allowedToStart = new Promise(resolve => {
     ac.addEventListener("statechange", function() {
       if (ac.state === "running") {
         resolve();
       }
     }, {once: true});
--- a/dom/media/test/test_autoplay_policy_web_audio_notResumePageInvokedSuspendedAudioContext.html
+++ b/dom/media/test/test_autoplay_policy_web_audio_notResumePageInvokedSuspendedAudioContext.html
@@ -44,16 +44,17 @@ function setupTestPreferences() {
     ["media.autoplay.default", SpecialPowers.Ci.nsIAutoplay.BLOCKED],
     ["media.autoplay.enabled.user-gestures-needed", true],
     ["media.autoplay.block-webaudio", true],
     ["media.autoplay.block-event.enabled", true],
   ]});
 }
 
 async function createAudioContext() {
+  /* global ac */
   window.ac = new AudioContext();
   await once(ac, "blocked");
   is(ac.state, "suspended", `AudioContext is blocked.`);
 }
 
 function suspendAudioContext() {
   try {
     ac.suspend();
--- a/dom/media/test/test_background_video_drawimage_with_suspended_video.html
+++ b/dom/media/test/test_background_video_drawimage_with_suspended_video.html
@@ -12,19 +12,17 @@ video, canvas {
 </style>
 <script type="text/javascript">
 "use strict";
 
 var manager = new MediaTestManager;
 
 function drawVideoToCanvas(v) {
   console.log('drawVideoToCanvas');
-  let w = v.width,
-      h = v.height,
-      c = document.createElement('canvas');
+  let c = document.createElement('canvas');
   c.width = 4;
   c.height = 4;
   c.style.width = 64;
   c.style.height = 64;
   document.body.appendChild(c);
 
   let gfx = c.getContext('2d');
   if (!gfx) {
@@ -70,9 +68,9 @@ startTest({
     waitUntilPlaying(v)
       .then(() => testVideoSuspendsWhenHidden(v))
       .then(() => {
         drawVideoToCanvas(v);
         manager.finished(token);
       });
   }
 });
-</script>
\ No newline at end of file
+</script>
--- a/dom/media/test/test_background_video_suspend.html
+++ b/dom/media/test/test_background_video_suspend.html
@@ -71,11 +71,11 @@
       ["media.test.video-suspend", true],
       ["media.suspend-bkgnd-video.enabled", true],
       // Use a short delay to ensure video decode suspend happens before end
       // of video.
       ["media.suspend-bkgnd-video.delay-ms", MIN_DELAY],
       ["privacy.reduceTimerPrecision", false]
     ],
     tests: gDecodeSuspendTests,
-    runTest: runTest
+    runTest
   });
 </script>
\ No newline at end of file
--- a/dom/media/test/test_background_video_suspend_ends.html
+++ b/dom/media/test/test_background_video_suspend_ends.html
@@ -45,11 +45,11 @@
     prefs: [
       ["media.test.video-suspend", true],
       ["media.suspend-bkgnd-video.enabled", true],
       // User a short delay to ensure video decode suspend happens before end
       // of video.
       ["media.suspend-bkgnd-video.delay-ms", 1000]
     ],
     tests: gDecodeSuspendTests,
-    runTest: runTest
+    runTest
   });
 </script>
\ No newline at end of file
--- a/dom/media/test/test_background_video_tainted_by_capturestream.html
+++ b/dom/media/test/test_background_video_tainted_by_capturestream.html
@@ -6,17 +6,17 @@
 <script src="background_video.js"></script>
 <link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
 <script type="text/javascript">
 "use strict";
 
 var manager = new MediaTestManager;
 
 function captureVideoAsStream(v) {
-  let stream = v.mozCaptureStream();
+  v.mozCaptureStream();
 }
 
 startTest({
   desc: 'Test Background Video Is Tainted By captureStream',
   prefs: [
     [ "media.test.video-suspend", true ],
     [ "media.suspend-bkgnd-video.enabled", true ],
     [ "media.suspend-bkgnd-video.delay-ms", 1000 ]
@@ -38,9 +38,9 @@ startTest({
         manager.finished(token);
       })
       .catch((e) => {
         ok(false, 'Test failed: ' + e.toString());
         manager.finished(token);
       });
   }
 });
-</script>
\ No newline at end of file
+</script>
--- a/dom/media/test/test_buffered.html
+++ b/dom/media/test/test_buffered.html
@@ -31,42 +31,42 @@ function testBuffered(e) {
   is(b.length, 1, v._name + ": Should be buffered in one range");
   is(b.start(0), 0, v._name + ": First range start should be media start");
   ok(Math.abs(b.end(0) - v.duration) < 0.1, v._name + ": First range end should be media end");
 
   // Ensure INDEX_SIZE_ERR is thrown when we access outside the range
   var caught = false;
   try {
     b.start(-1);
-  } catch (e) {
-    caught = e.name == "IndexSizeError" && e.code == DOMException.INDEX_SIZE_ERR;
+  } catch (ex) {
+    caught = ex.name == "IndexSizeError" && ex.code == DOMException.INDEX_SIZE_ERR;
   }
   is(caught, true, v._name + ": Should throw INDEX_SIZE_ERR on under start bounds range");
 
   caught = false;
   try {
     b.end(-1);
-  } catch (e) {
-    caught = e.name == "IndexSizeError" && e.code == DOMException.INDEX_SIZE_ERR;
+  } catch (ex) {
+    caught = ex.name == "IndexSizeError" && ex.code == DOMException.INDEX_SIZE_ERR;
   }
   is(caught, true, v._name + ": Should throw INDEX_SIZE_ERR on under end bounds range");
 
   caught = false;
   try {
     b.start(b.length);
-  } catch (e) {
-    caught = e.name == "IndexSizeError" && e.code == DOMException.INDEX_SIZE_ERR;
+  } catch (ex) {
+    caught = ex.name == "IndexSizeError" && ex.code == DOMException.INDEX_SIZE_ERR;
   }
   is(caught, true, v._name + ": Should throw INDEX_SIZE_ERR on over start bounds range");
 
   caught = false;
   try {
     b.end(b.length);
-  } catch (e) {
-    caught = e.name == "IndexSizeError" && e.code == DOMException.INDEX_SIZE_ERR;
+  } catch (ex) {
+    caught = ex.name == "IndexSizeError" && ex.code == DOMException.INDEX_SIZE_ERR;
   }
   is(caught, true, v._name + ": Should throw INDEX_SIZE_ERR on over end bounds range");
 
   removeNodeAndSource(v);
   manager.finished(v._token);
 }
 
 function fetch(url, fetched_callback) {
--- a/dom/media/test/test_bug1248229.html
+++ b/dom/media/test/test_bug1248229.html
@@ -8,16 +8,17 @@
 </head>
 <body onload="doTest()">
 <video id="v" src="black100x100-aspect3to2.ogv"></video>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 SimpleTest.waitForExplicitFinish();
 
 function doTest() {
+  /* global v */
   window.oak = v.mozCaptureStreamUntilEnded();
   v.mozCaptureStreamUntilEnded();
   v.play();
 
   v.onended = function() {
     info("Got ended.");
     v.onended = null;
     SpecialPowers.exactGC(function() {
--- a/dom/media/test/test_bug1431810_opus_downmix_to_mono.html
+++ b/dom/media/test/test_bug1431810_opus_downmix_to_mono.html
@@ -11,16 +11,18 @@
 <script class="testbody" type="text/javascript">
 /*
   This test makes use of an (stereo) opus file with phase inversion of 180 degrees (right = -left => right + left = 0).
   Firstly, the phase inversion is verified on a normal stereo playback.
   Secondly, mono playback is forced which results in the phase inversion being disabled (Bug 1431810).
 */
 SimpleTest.waitForExplicitFinish();
 
+/* global a, b */
+
 function areChannelsInverted(b1, b2) {
   for (var i = 0; i < b1.length; i++) {
     if (Math.abs(b1[i] + b2[i]) > 9e-2) {
       return false;
     }
   }
   return true;
 }
--- a/dom/media/test/test_bug1512958.html
+++ b/dom/media/test/test_bug1512958.html
@@ -22,32 +22,32 @@ function wait(ms) {
 
 const a = document.getElementById('a');
 
 const events = ["timeupdate", "seeking", "seeked", "ended", "playing", "pause"];
 for (let ev of events) {
   a.addEventListener(ev, dumpEvent);
 }
 
-(async _ => {
+(async () => {
   try {
     SimpleTest.waitForExplicitFinish();
     SimpleTest.requestFlakyTimeout("Timeouts for shortcutting test-timeout");
 
     const test = getPlayableAudio(gTrackTests.filter(t => t.duration > 2));
     if (!test) {
       todo(false, "No playable audio");
       return;
     }
 
     // Start playing and capture
     a.src = test.name;
     a.name = test.name;
     const ac = new AudioContext();
-    const src = ac.createMediaElementSource(a);
+    ac.createMediaElementSource(a);
     a.play();
     do {
       await new Promise(r => a.ontimeupdate = r);
     } while(a.currentTime == 0)
 
     // Pause to trigger recreating tracks in DecodedStream
     a.pause();
     await new Promise(r => a.onpause = r);
@@ -55,17 +55,17 @@ for (let ev of events) {
     // Resuming should now work. Bug 1512958 would cause a stall because the
     // original track wasn't ended and we'd block on it.
     // See https://bugzilla.mozilla.org/show_bug.cgi?id=1512958#c5
     a.play();
     await new Promise(r => a.onplaying = r);
     a.currentTime = test.duration - 1;
     await Promise.race([
       new Promise(res => a.onended = res),
-      wait(30000).then(_ => Promise.reject(new Error("Timeout"))),
+      wait(30000).then(() => Promise.reject(new Error("Timeout"))),
     ]);
   } catch(e) {
     ok(false, e);
   } finally {
     SimpleTest.finish();
   }
 })();
 </script>
--- a/dom/media/test/test_bug463162.xhtml
+++ b/dom/media/test/test_bug463162.xhtml
@@ -1,18 +1,18 @@
 <html xmlns="http://www.w3.org/1999/xhtml"
       xmlns:html="http://www.w3.org/1999/xhtml"
       xmlns:svg="http://www.w3.org/2000/svg">
 <!--
 https://bugzilla.mozilla.org/show_bug.cgi?id=463162
 -->
 <head>
   <title>Test for Bug 463162</title>
-  <script src="/tests/SimpleTest/SimpleTest.js"></script>        
-  <script src="/tests/SimpleTest/EventUtils.js"/>
+  <script src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script src="/tests/SimpleTest/EventUtils.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
   <script type="text/javascript" src="manifest.js"></script>
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=463162">Mozilla Bug 463162</a>
 
 <script class="testbody" type="text/javascript">
 <![CDATA[
--- a/dom/media/test/test_bug686942.html
+++ b/dom/media/test/test_bug686942.html
@@ -16,17 +16,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 <script class="testbody" type="text/javascript">
 
 var manager = new MediaTestManager;
 
 function onloaded(event) {
   var v = event.target;
   v.removeEventListener("loadedmetadata", onloaded);
   v.currentTime = v.duration;
-  return;
+  
 }
 
 function checkNotPlaying(v) {
   ok(v.currentTime == 0, "Should not be playing after seek to end and back to beginning");
   v._finished = true;
   manager.finished(v.token);
   removeNodeAndSource(v);
 }
--- a/dom/media/test/test_bug895305.html
+++ b/dom/media/test/test_bug895305.html
@@ -17,16 +17,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 SimpleTest.waitForExplicitFinish();
 
 var audio = document.createElement("audio");
 
 // Check leaking on TextTrackList objects.
+/* global ttl, ttc */
 window.ttl = audio.textTracks;
 ttl.addEventListener("click", function(){});
 
 // Check leaking on VTTCue objects.
 window.ttc = new VTTCue(3, 4, "Test.");
 ttc.addEventListener("click", function() {});
 
 // Check leaking on TextTrack objects.
--- a/dom/media/test/test_can_play_type_mpeg.html
+++ b/dom/media/test/test_can_play_type_mpeg.html
@@ -126,21 +126,17 @@ function IsMacOSSnowLeopardOrLater() {
   return major == 10 && minor >= 6;
 }
 
 function IsLinux() {
   return navigator.userAgent.includes("Linux");
 }
 
 function getPref(name) {
-  var pref = false;
-  try {
-    pref = SpecialPowers.getBoolPref(name);
-  } catch(ex) { }
-  return pref;
+  return SpecialPowers.getBoolPref(name, false);
 }
 
 function IsSupportedAndroid() {
   return getAndroidVersion() >= 14;
 }
 
 function IsJellyBeanOrLater() {
   return getAndroidVersion() >= 16;
--- a/dom/media/test/test_cloneElementVisually_ended_video.html
+++ b/dom/media/test/test_cloneElementVisually_ended_video.html
@@ -16,16 +16,18 @@
 <div id="results">
   <h1>Results</h1>
   <canvas id="left"></canvas>
   <canvas id="right"></canvas>
 </div>
 
 <script type="application/javascript">
 
+/* import-globals-from cloneElementVisually_helpers.js */
+
 /**
  * Test that when we start cloning a video that has already ended, the
  * clone displays the last frame from the video.
  */
 add_task(async () => {
   await setup();
 
   let originalVideo = document.getElementById("original");
--- a/dom/media/test/test_cloneElementVisually_mediastream.html
+++ b/dom/media/test/test_cloneElementVisually_mediastream.html
@@ -18,16 +18,18 @@
 <div id="results">
   <h1>Results</h1>
   <canvas id="left"></canvas>
   <canvas id="right"></canvas>
 </div>
 
 <script type="application/javascript">
 
+/* import-globals-from cloneElementVisually_helpers.js */
+
 /**
  * Test that we can clone a video that is playing a MediaStream.
  */
 add_task(async () => {
   await setup();
 
   let originalVideo = document.getElementById("original");
   let stream = originalVideo.mozCaptureStream();
--- a/dom/media/test/test_cloneElementVisually_no_suspend.html
+++ b/dom/media/test/test_cloneElementVisually_no_suspend.html
@@ -18,16 +18,18 @@
 <div id="results">
   <h1>Results</h1>
   <canvas id="left"></canvas>
   <canvas id="right"></canvas>
 </div>
 
 <script type="application/javascript">
 
+/* import-globals-from cloneElementVisually_helpers.js */
+
 /**
  * Tests that cloning a video prevents the decoder from being suspended
  * if the original video stops being visible.
  */
 add_task(async () => {
   await setup();
 
   let originalVideo = document.getElementById("original");
--- a/dom/media/test/test_cloneElementVisually_paused.html
+++ b/dom/media/test/test_cloneElementVisually_paused.html
@@ -16,16 +16,18 @@
 <div id="results">
   <h1>Results</h1>
   <canvas id="left"></canvas>
   <canvas id="right"></canvas>
 </div>
 
 <script type="application/javascript">
 
+/* import-globals-from cloneElementVisually_helpers.js */
+
 /**
  * Test that when we start cloning a paused video, the clone displays
  * the first paused frame.
  */
 add_task(async () => {
   await setup();
 
   let originalVideo = document.getElementById("original");
--- a/dom/media/test/test_cloneElementVisually_poster.html
+++ b/dom/media/test/test_cloneElementVisually_poster.html
@@ -16,16 +16,18 @@
 <div id="results">
   <h1>Results</h1>
   <canvas id="left"></canvas>
   <canvas id="right"></canvas>
 </div>
 
 <script type="application/javascript">
 
+/* import-globals-from cloneElementVisually_helpers.js */
+
 /**
  * Test that when we start cloning a paused video, the clone displays
  * the first paused frame.
  */
 add_task(async () => {
   await setup();
 
   let originalVideo = document.getElementById("original");
--- a/dom/media/test/test_cloneElementVisually_resource_change.html
+++ b/dom/media/test/test_cloneElementVisually_resource_change.html
@@ -18,16 +18,18 @@
 <div id="results">
   <h1>Results</h1>
   <canvas id="left"></canvas>
   <canvas id="right"></canvas>
 </div>
 
 <script type="application/javascript">
 
+/* import-globals-from cloneElementVisually_helpers.js */
+
 /**
  * Tests that cloning survives changes to the underlying video resource.
  */
 add_task(async () => {
   await setup();
 
   let originalVideo = document.getElementById("original");
   originalVideo.setAttribute("loop", true);
--- a/dom/media/test/test_clone_media_element.html
+++ b/dom/media/test/test_clone_media_element.html
@@ -25,27 +25,27 @@ function startTest(test, token) {
 
   v.onloadedmetadata = function(evt) {
     info(evt.target.token + " metadata loaded.");
     evt.target.onloadedmetadata = null;
     var clone = evt.target.cloneNode(false);
     clone.token = evt.target.token;
     clone.play();
 
-    clone.onloadstart = function(evt) {
-      info("cloned " + evt.target.token + " start loading.");
-      evt.target.onloadstart = null;
+    clone.onloadstart = function(event) {
+      info("cloned " + event.target.token + " start loading.");
+      event.target.onloadstart = null;
       removeNodeAndSource(v);
     }
 
-    clone.onended = function(evt) {
-      ok(true, "cloned " + evt.target.token + " ended.");
-      evt.target.onended = null;
-      removeNodeAndSource(evt.target);
-      manager.finished(evt.target.token);
+    clone.onended = function(event) {
+      ok(true, "cloned " + event.target.token + " ended.");
+      event.target.onended = null;
+      removeNodeAndSource(event.target);
+      manager.finished(event.target.token);
     }
   }
 }
 
 var manager = new MediaTestManager;
 manager.runTests(gSmallTests.concat(gPlayedTests), startTest);
 
 </script>
--- a/dom/media/test/test_cueless_webm_seek-1.html
+++ b/dom/media/test/test_cueless_webm_seek-1.html
@@ -37,27 +37,27 @@ function testWebM1(e) {
   var seekFlagStart = false;
   var seekFlagEnd = false;
   var readonly = true;
   var completed = false;
 
   ok(v.buffered.length >= 1, "Should have a buffered range");
   var halfBuffered = v.buffered.end(0) / 2;
 
-  function startTest() {
+  function start() {
     is(v.seekable.start(0), v.buffered.start(0), "Seekable start should be buffered start");
     is(v.seekable.end(0), v.buffered.end(0), "Seekable end should be buffered end");
     ok(!completed, "Should not be completed yet");
     ok(!v.seeking, "seeking should default to false");
     try {
       v.seeking = true;
       readonly = v.seeking === false;
     }
-    catch(e) {
-      readonly = "threw exception: " + e;
+    catch(ex) {
+      readonly = "threw exception: " + ex;
     }
     is(readonly, true, "seeking should be readonly");
 
     v.currentTime = halfBuffered;
     seekFlagStart = v.seeking;
   }
 
   function seekStarted() {
@@ -85,17 +85,17 @@ function testWebM1(e) {
     removeNodeAndSource(v);
     manager.finished(v._token);
   }
 
   once(v, "ended", playbackEnded);
   once(v, "seeking", seekStarted);
   once(v, "seeked", seekEnded);
 
-  startTest();
+  start();
 }
 
 // Fetch the media resource using XHR so we can be sure the entire
 // resource is loaded before we test buffered ranges. This ensures
 // we have deterministic behaviour.
 function fetch(url, fetched_callback) {
   var xhr = new XMLHttpRequest();
   xhr.open("GET", url, true);
@@ -128,9 +128,9 @@ function startTest(test, token) {
 }
 
 SimpleTest.waitForExplicitFinish();
 manager.runTests(gCuelessWebMTests, startTest);
 
 </script>
 </pre>
 </body>
-</html>
\ No newline at end of file
+</html>
--- a/dom/media/test/test_cueless_webm_seek-2.html
+++ b/dom/media/test/test_cueless_webm_seek-2.html
@@ -34,17 +34,17 @@ function testWebM2(e) {
 
   var startPassed = false;
   var endPassed = false;
   var completed = false;
 
   ok(v.buffered.length >= 1, "Should have a buffered range");
   var halfBuffered = v.buffered.end(0) / 2;
 
-  function startTest() {
+  function start() {
     if (completed)
       return;
 
     is(v.seekable.start(0), v.buffered.start(0), "Seekable start should be buffered start");
     is(v.seekable.end(0), v.buffered.end(0), "Seekable end should be buffered end");
     v.currentTime=halfBuffered;
     v.play();
   }
@@ -75,17 +75,17 @@ function testWebM2(e) {
     removeNodeAndSource(v);
     manager.finished(v._token);
   }
 
   v.addEventListener("ended", playbackEnded);
   v.addEventListener("seeking", seekStarted);
   v.addEventListener("seeked", seekEnded);
 
-  startTest();
+  start();
 }
 
 // Fetch the media resource using XHR so we can be sure the entire
 // resource is loaded before we test buffered ranges. This ensures
 // we have deterministic behaviour.
 function fetch(url, fetched_callback) {
   var xhr = new XMLHttpRequest();
   xhr.open("GET", url, true);
@@ -118,9 +118,9 @@ function startTest(test, token) {
 }
 
 SimpleTest.waitForExplicitFinish();
 manager.runTests(gCuelessWebMTests, startTest);
 
 </script>
 </pre>
 </body>
-</html>
\ No newline at end of file
+</html>
--- a/dom/media/test/test_cueless_webm_seek-3.html
+++ b/dom/media/test/test_cueless_webm_seek-3.html
@@ -27,24 +27,23 @@ https://bugzilla.mozilla.org/show_bug.cg
 
 var manager = new MediaTestManager;
 
 // Exercise functionality as in test_seek-3
 function testWebM3(e) {
   var v = e.target;
   v.removeEventListener('loadeddata', testWebM3);
 
-  var startPassed = false;
   var completed = false;
   var gotTimeupdate = false;
 
   ok(v.buffered.length >= 1, "Should have a buffered range");
   var halfBuffered = v.buffered.end(0) / 2;
 
-  function startTest() {
+  function start() {
     if (completed)
       return;
 
     is(v.seekable.start(0), v.buffered.start(0), "Seekable start should be buffered start");
     is(v.seekable.end(0), v.buffered.end(0), "Seekable end should be buffered end");
     v.currentTime=halfBuffered;
   }
 
@@ -53,17 +52,16 @@ function testWebM3(e) {
     v.removeEventListener("timeupdate", timeupdate);
   }
 
   function seekStarted() {
     if (completed)
       return;
 
     v.addEventListener("timeupdate", timeupdate);
-    startPassed = true;
   }
 
   function seekEnded() {
     if (completed)
       return;
 
     var t = v.currentTime;
     ok(Math.abs(t - halfBuffered) <= 0.1, "Video currentTime should be around " + halfBuffered + ": " + t);
@@ -71,17 +69,17 @@ function testWebM3(e) {
     completed = true;
     removeNodeAndSource(v);
     manager.finished(v._token);
   }
 
   v.addEventListener("seeking", seekStarted);
   v.addEventListener("seeked", seekEnded);
 
-  startTest()
+  start()
 }
 
 // Fetch the media resource using XHR so we can be sure the entire
 // resource is loaded before we test buffered ranges. This ensures
 // we have deterministic behaviour.
 function fetch(url, fetched_callback) {
   var xhr = new XMLHttpRequest();
   xhr.open("GET", url, true);
@@ -114,9 +112,9 @@ function startTest(test, token) {
 }
 
 SimpleTest.waitForExplicitFinish();
 manager.runTests(gCuelessWebMTests, startTest);
 
 </script>
 </pre>
 </body>
-</html>
\ No newline at end of file
+</html>
--- a/dom/media/test/test_decoder_disable.html
+++ b/dom/media/test/test_decoder_disable.html
@@ -19,40 +19,40 @@ https://bugzilla.mozilla.org/show_bug.cg
 function filename(uri) {
   return uri.substr(uri.lastIndexOf("/")+1);
 }
 
 function e(id) {
   return document.getElementById(id);
 }
 
-var gLoadError = new Object();
+var gLoadError = {};
 
-gLoadError['video1'] = 0; 
-gLoadError['video2'] = 0;
-gLoadError['video3'] = 0;
+gLoadError.video1 = 0;
+gLoadError.video2 = 0;
+gLoadError.video3 = 0;
 
 var gErrorCount = 0;
 
 SimpleTest.waitForExplicitFinish();
 
 function finishTest() {
   is(e('video1').currentSrc,
      "",
      'video1 currentSrc should be empty when there\'s no playable typed source children');
   is(filename(e('video2').currentSrc),
      filename(e('video2').src),
      'video2 currentSrc should match src');
   is(filename(e('video3').currentSrc),
      filename(e('video3').src),
      'video3 currentSrc should match src');
 
-  is(gLoadError['video1'], 2, "Expect one error per invalid source child on video1");
-  is(gLoadError['video2'], 1, "Expect one error on video2");
-  is(gLoadError['video3'], 1, "Expect one error on video3");
+  is(gLoadError.video1, 2, "Expect one error per invalid source child on video1");
+  is(gLoadError.video2, 1, "Expect one error on video2");
+  is(gLoadError.video3, 1, "Expect one error on video3");
 
   SimpleTest.finish();
 }
 
 function videoError(event, id) {
   gLoadError[id]++;
   gErrorCount++;
   if (gErrorCount >= 4) {
--- a/dom/media/test/test_eme_autoplay.html
+++ b/dom/media/test/test_eme_autoplay.html
@@ -5,16 +5,17 @@
   <script src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
   <script type="text/javascript" src="manifest.js"></script>
   <script type="text/javascript" src="https://example.com:443/tests/dom/media/test/eme.js"></script>
 </head>
 <body>
 <pre id="test">
 <script class="testbody" type="text/javascript">
+/* import-globals-from eme.js */
 var manager = new MediaTestManager;
 
 var EMEmanifest = [
   {
     name:"bipbop 10s",
     tracks: [
       {
           name:"video",
@@ -39,18 +40,18 @@ function startTest(test, token)
   let v = document.createElement("video");
   v.controls = true;
   v.autoplay = true;
 
   document.body.appendChild(v);
 
   var eventCounts = { play: 0, playing: 0};
   function ForbiddenEvents(e) {
-    var v = e.target;
-    ok(v.readyState >= v.HAVE_FUTURE_DATA, "Must not have received event too early");
+    var video = e.target;
+    ok(video.readyState >= video.HAVE_FUTURE_DATA, "Must not have received event too early");
     is(eventCounts[e.type], 0, "event should have only be fired once");
     eventCounts[e.type]++;
   }
   // Log events for debugging.
   var events = ["suspend", "play", "canplay", "canplaythrough", "loadstart", "loadedmetadata",
                 "loadeddata", "playing", "ended", "error", "stalled", "emptied", "abort",
                 "waiting", "pause", "durationchange", "seeking", "seeked"];
   function logEvent(e) {
--- a/dom/media/test/test_eme_detach_reattach_same_mediakeys_during_playback.html
+++ b/dom/media/test/test_eme_detach_reattach_same_mediakeys_during_playback.html
@@ -6,16 +6,17 @@
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
   <script type="text/javascript" src="manifest.js"></script>
   <script type="text/javascript" src="https://example.com:443/tests/dom/media/test/eme.js"></script>
 </head>
 <body>
 <pre id="test">
 <video id="v" controls></video>
 <script class="testbody" type="text/javascript">
+/* import-globals-from eme.js */
 var manager = new MediaTestManager;
 
 var EMEmanifest = [
   {
     name:"bipbop 10s",
     tracks: [
       {
           name:"video",
--- a/dom/media/test/test_eme_non_mse_fails.html
+++ b/dom/media/test/test_eme_non_mse_fails.html
@@ -5,19 +5,20 @@
   <script src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
   <script type="text/javascript" src="manifest.js"></script>
   <script type="text/javascript" src="eme.js"></script>
 </head>
 <body>
 <pre id="test">
 <script class="testbody" type="text/javascript">
+/* import-globals-from eme.js */
 var manager = new MediaTestManager;
 
-function DoSetMediaKeys(v, test)
+function DoSetMediaKeys(v, test, token)
 {
   var options = [{
     initDataTypes: ["cenc"],
     audioCapabilities: [{contentType: test.audioType}],
     videoCapabilities: [{contentType: test.videoType}],
   }];
 
   return navigator.requestMediaKeySystemAccess(CLEARKEY_KEYSYSTEM, options)
@@ -64,17 +65,17 @@ function TestSetSrc(test, token)
   manager.started(token);
 
   var v = document.createElement("video");
   v.addEventListener("error", function(err) {
     ok(true, token + " got error setting src on video element, as expected");
     manager.finished(token);
   });
 
-  DoSetMediaKeys(v, test)
+  DoSetMediaKeys(v, test, token)
 
   .then(function() {
     v.src = test.name;
   })
 
   .catch(function() {
     ok(false, token + " got error setting media keys");
   });
@@ -95,9 +96,8 @@ if (!IsMacOSSnowLeopardOrEarlier()) {
   SetupEMEPref(beginTest);
 } else {
   todo(false, "Test disabled on this platform.");
 }
 </script>
 </pre>
 </body>
 </html>
-
--- a/dom/media/test/test_eme_playback.html
+++ b/dom/media/test/test_eme_playback.html
@@ -5,16 +5,17 @@
   <script src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
   <script type="text/javascript" src="manifest.js"></script>
   <script type="text/javascript" src="https://example.com:443/tests/dom/media/test/eme.js"></script>
 </head>
 <body>
 <pre id="test">
 <script class="testbody" type="text/javascript">
+/* import-globals-from eme.js */
 var manager = new MediaTestManager;
 
 function ArrayBuffersEqual(a, b) {
   if (a.byteLength != b.byteLength) {
     return false;
   }
   var ua = new Uint8Array(a);
   var ub = new Uint8Array(b);
@@ -28,49 +29,49 @@ function ArrayBuffersEqual(a, b) {
 
 function KeysChangeFunc(session, keys, token) {
   session.keyIdsReceived = [];
   for (var keyid in keys) {
     Log(token, "Set " + keyid + " to false in session[" + session.sessionId + "].keyIdsReceived");
     session.keyIdsReceived[keyid] = false;
   }
   return function(ev) {
-    var session = ev.target;
-    session.gotKeysChanged = true;
+    var s = ev.target;
+    s.gotKeysChanged = true;
 
     var keyList = [];
     var valueList = [];
-    var map = session.keyStatuses;
+    var map = s.keyStatuses;
 
     // Test that accessing keys not known to the CDM has expected behaviour.
     var absentKey = new Uint8Array([0xeb, 0xdd, 0x62, 0xf1, 0x68, 0x14, 0xd2, 0x7b,
                                     0x68, 0xef, 0x12, 0x2a, 0xfc, 0xe4, 0xae, 0x3c]);
     is(map.has(absentKey), false, "Shouldn't have a key that's not in the media");
     is(map.get(absentKey), undefined, "Unknown keys should undefined status");
 
     // Verify known keys have expected status.
-    for (var [key, val] of map.entries()) {
+    for (let [key, val] of map.entries()) {
       is(key.constructor, ArrayBuffer, "keyId should be ArrayBuffer");
       ok(map.has(key), "MediaKeyStatusMap.has() should work.");
       is(map.get(key), val, "MediaKeyStatusMap.get() should work.");
       keyList.push(key);
       valueList.push(val);
       is(val, "usable", token + ": key status should be usable");
       var kid = Base64ToHex(window.btoa(ArrayBufferToString(key)));
-      ok(kid in session.keyIdsReceived, TimeStamp(token) + " session[" + session.sessionId + "].keyIdsReceived contained " + kid + " as expected.");
-      session.keyIdsReceived[kid] = true;
+      ok(kid in s.keyIdsReceived, TimeStamp(token) + " session[" + s.sessionId + "].keyIdsReceived contained " + kid + " as expected.");
+      s.keyIdsReceived[kid] = true;
     }
 
     var index = 0;
     for (var keyId of map.keys()) {
       ok(ArrayBuffersEqual(keyId, keyList[index]), "MediaKeyStatusMap.keys() should correspond to entries");
       index++;
     }
     index = 0;
-    for (var val of map.values()) {
+    for (let val of map.values()) {
       is(val, valueList[index], "MediaKeyStatusMap.values() should correspond to entries");
       index++;
     }
   }
 }
 
 function startTest(test, token)
 {
@@ -137,29 +138,29 @@ function startTest(test, token)
                         + " session" + (test.sessionCount === 1 ? "" : "s"));
     var keyIdsReceived = [];
     for (var keyid in test.keys) { keyIdsReceived[keyid] = false; }
     for (var i = 0; i < sessions.length; i++) {
       var session = sessions[i];
       ok(session.gotKeysChanged,
          TimeStamp(token) + " session[" + session.sessionId
          + "] should have received at least one keychange event");
-      for (var kid in session.keyIdsReceived) {
+      for (let kid in session.keyIdsReceived) {
         Log(token, "session[" + session.sessionId + "] key " + kid + " = " + (session.keyIdsReceived[kid] ? "true" : "false"));
         if (session.keyIdsReceived[kid]) { keyIdsReceived[kid] = true; }
       }
       ok(session.numKeystatuseschangeEvents > 0, TimeStamp(token) + " should get key status changes");
       is(session.numKeystatuseschangeEvents, session.numOnkeystatuseschangeEvents,
          TimeStamp(token) + " should have as many keystatuseschange event listener calls as event handler calls.");
 
       ok(session.numMessageEvents > 0, TimeStamp(token) + " should get message events");
       is(session.numMessageEvents, session.numOnMessageEvents,
          TimeStamp(token) + " should have as many message event listener calls as event handler calls.");
     }
-    for (var kid in keyIdsReceived) {
+    for (let kid in keyIdsReceived) {
       ok(keyIdsReceived[kid], TimeStamp(token) + " key with id " + kid + " was usable as expected");
     }
 
     CloseSessions(v, sessions).then(finish.resolve, finish.reject);
   });
 
   Promise.all([
     LoadInitData(v, test, token),
--- a/dom/media/test/test_eme_pssh_in_moof.html
+++ b/dom/media/test/test_eme_pssh_in_moof.html
@@ -104,25 +104,25 @@
         }
 
         let initData = new Uint8Array(event.initData);
         is(event.initDataType, "cenc", "'encrypted' event should have 'cenc' " +
            "initDataType");
         Log(token, "encrypted event => len=" + initData.length + " " + hexStr);
         let session = event.target.mediaKeys.createSession();
         initDatas.set(hexStr, session);
-        session.addEventListener("message", event => {
-          event.target.update(
-            GenerateClearKeyLicense(event.message, test.keys));
+        session.addEventListener("message", e => {
+          e.target.update(
+            GenerateClearKeyLicense(e.message, test.keys));
         });
 
         session.generateRequest(event.initDataType, event.initData);
       }
 
-      video.addEventListener("encrypted", handleEncrypted, false);
+      video.addEventListener("encrypted", handleEncrypted);
 
       video.addEventListener("ended", () => {
         let expectedEncryptedEvents =
           test.tracks.reduce((sum, track) => sum += track.initDatas, 0);
         is(encryptedEventCount, expectedEncryptedEvents,
            "Should get one 'encrypted' event per run of contiguous PSSH " +
            "boxes in media.");
         manager.finished(token);
@@ -133,9 +133,9 @@
       createAndSetMediaKeys(video, test, token)
         .then(() => LoadTest(test, video, token))
     }
 
     manager.runTests(psshTests, startTest);
 
     </script>
   </body>
-</html>
\ No newline at end of file
+</html>
--- a/dom/media/test/test_eme_request_notifications.html
+++ b/dom/media/test/test_eme_request_notifications.html
@@ -23,17 +23,16 @@ function observe() {
       resolve(JSON.parse(data).status);
     };
     SpecialPowers.Services.obs.addObserver(observer, "mediakeys-request");
   });
 }
 
 function Test(test) {
   var p = test.prefs ? SetPrefs(test.prefs) : Promise.resolve();
-  observedStatus = "nothing";
   var name = "'" + test.keySystem + "'";
 
   var res = observe().then((status) => {
     is(status, test.expectedStatus, name + " expected status");
   });
 
   p.then(() => navigator.requestMediaKeySystemAccess(test.keySystem, gCencMediaKeySystemConfig))
    .then((keySystemAccess) => keySystemAccess.createMediaKeys());
--- a/dom/media/test/test_eme_stream_capture_blocked_case1.html
+++ b/dom/media/test/test_eme_stream_capture_blocked_case1.html
@@ -10,17 +10,16 @@
 <body>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 var manager = new MediaTestManager;
 
 function startTest(test, token)
 {
   // Case 1. setting MediaKeys on an element captured by MediaElementSource should fail.
-  var p1 = new EMEPromise;
   var case1token = token + "_case1";
   let v1 = document.createElement("video");
 
   function setMediaKeys() {
     let p = new EMEPromise;
     CreateMediaKeys(v1, test, case1token)
     .then(mediaKeys => {
       v1.setMediaKeys(mediaKeys)
@@ -30,17 +29,17 @@ function startTest(test, token)
         ok(true, TimeStamp(case1token) + " setMediaKeys failed as expected.");
         p.resolve();
       })
     }, p.reject);
     return p.promise;
   }
 
   var context = new AudioContext();
-  var node = context.createMediaElementSource(v1);
+  context.createMediaElementSource(v1);
   v1.addEventListener("loadeddata", function(ev) {
     ok(false, TimeStamp(case1token) + " should never reach loadeddata, as setMediaKeys should fail");
   });
 
   manager.started(case1token);
 
   Promise.all([
     LoadTest(test, v1, case1token),
--- a/dom/media/test/test_eme_stream_capture_blocked_case2.html
+++ b/dom/media/test/test_eme_stream_capture_blocked_case2.html
@@ -20,17 +20,17 @@ function startTest(test, token)
   var case2token = token + "_case2";
   let v2 = document.createElement("video");
 
   v2.addEventListener("loadeddata", function(ev) {
     ok(true, case2token + " should reach loadeddata");
     var threw = false;
     try {
       var context = new AudioContext();
-      var node = context.createMediaElementSource(v2);
+      context.createMediaElementSource(v2);
     } catch (e) {
       threw = true;
     }
     ok(!threw, "Should always work when creating a MediaElementSource.");
     p1.resolve();
   });
 
   manager.started(case2token);
--- a/dom/media/test/test_eme_stream_capture_blocked_case3.html
+++ b/dom/media/test/test_eme_stream_capture_blocked_case3.html
@@ -18,17 +18,17 @@ function startTest(test, token)
   var p1 = new EMEPromise;
   var case3token = token + "_case3";
   let v3 = document.createElement("video");
 
   v3.addEventListener("loadeddata", function(ev) {
     ok(true, TimeStamp(case3token) + " should reach loadeddata");
     var threw = false;
     try {
-      var stream = v3.mozCaptureStreamUntilEnded();
+      v3.mozCaptureStreamUntilEnded();
     } catch (e) {
       threw = true;
     }
     ok(threw, TimeStamp(case3token) + " Should throw an error calling mozCaptureStreamUntilEnded an EME video.");
     p1.resolve();
   });
 
   manager.started(case3token);
--- a/dom/media/test/test_eme_unsetMediaKeys_then_capture.html
+++ b/dom/media/test/test_eme_unsetMediaKeys_then_capture.html
@@ -5,16 +5,17 @@
   <script src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
   <script type="text/javascript" src="manifest.js"></script>
   <script type="text/javascript" src="https://example.com:443/tests/dom/media/test/eme.js"></script>
 </head>
 <body>
 <pre id="test">
 <script class="testbody" type="text/javascript">
+/* import-globals-from eme.js */
 var manager = new MediaTestManager;
 
 // Test that if we can capture a video frame while playing clear content after
 // removing the MediaKeys object which was used for a previous encrypted content
 // playback on the same video element
 function startTest(test, token)
 {
   manager.started(token);
@@ -36,25 +37,25 @@ function startTest(test, token)
   let finish = new EMEPromise;
 
   function onVideoEnded(ev) {
     ok(true, TimeStamp(token) + " (ENCRYPTED) content playback ended.");
 
     function playClearVideo() {
       var p1 = once(v, 'loadeddata', (e) => {
         ok(true, TimeStamp(token) + " Receiving event 'loadeddata' for (CLEAR) content.");
-        canvasElem = document.createElement('canvas');
+        let canvasElem = document.createElement('canvas');
         document.body.appendChild(canvasElem);
-        ctx2d = canvasElem.getContext('2d');
+        let ctx2d = canvasElem.getContext('2d');
 
         var gotTypeError = false;
         try {
           ctx2d.drawImage(v, 0, 0);
-        } catch (e) {
-          if (e instanceof TypeError) {
+        } catch (ex) {
+          if (ex instanceof TypeError) {
             gotTypeError = true;
           }
         }
         ok(!gotTypeError, TimeStamp(token) + " Canvas2D context drawImage succeed.")
       });
       v.src = 'bipbop_225w_175kbps.mp4';
       v.play();
       Promise.all([p1]).then(() => {
--- a/dom/media/test/test_eme_waitingforkey.html
+++ b/dom/media/test/test_eme_waitingforkey.html
@@ -5,16 +5,17 @@
   <script src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
   <script type="text/javascript" src="manifest.js"></script>
   <script type="text/javascript" src="https://example.com:443/tests/dom/media/test/eme.js"></script>
 </head>
 <body>
 <pre id="test">
 <script class="testbody" type="text/javascript">
+/* import-globals-from eme.js */
 var manager = new MediaTestManager;
 
 function startTest(test, token)
 {
   manager.started(token);
 
   let v = document.createElement("video");
   document.body.appendChild(v);
--- a/dom/media/test/test_fastSeek-forwards.html
+++ b/dom/media/test/test_fastSeek-forwards.html
@@ -52,17 +52,17 @@ https://bugzilla.mozilla.org/show_bug.cg
       v.removeEventListener("loadedmetadata", onLoadedMetadata);
       v.addEventListener("seeked", onFirstSeekComplete);
       v.firstSeekTarget = v.keyframes[1] * 0.5;
       v.currentTime = v.firstSeekTarget;
     }
 
     function startTest(test, token) {
       manager.started(token);
-      v = document.createElement("video");
+      let v = document.createElement("video");
       v.src = test.name;
       v.name = test.name;
       v.preload = "metadata";
       v.token = token;
       v.target = 0;
       v.keyframes = test.keyframes;
       v.keyframeIndex = 0;
       ok(v.keyframes.length >= 2, v.name + " - video should have at least two sync points");
--- a/dom/media/test/test_fastSeek.html
+++ b/dom/media/test/test_fastSeek.html
@@ -62,17 +62,17 @@ https://bugzilla.mozilla.org/show_bug.cg
         manager.finished(v.token);
       } else {
         doSeek(v);
       }
     }
 
     function startTest(test, token) {
       manager.started(token);
-      v = document.createElement("video");
+      let v = document.createElement("video");
       v.src = test.name;
       v.name = test.name;
       v.preload = "metadata";
       v.token = token;
       v.target = 0;
       v.keyframes = test.keyframes;
       v.keyframeIndex = 0;
       ok(v.keyframes.length > 0, v.name + " - video should have at least one sync point");
--- a/dom/media/test/test_fragment_noplay.html
+++ b/dom/media/test/test_fragment_noplay.html
@@ -80,48 +80,48 @@ function createTestArray() {
   for (var testNum=0; testNum<gFragmentTests.length; testNum++) {
     var test = gFragmentTests[testNum];
     if (!tmpVid.canPlayType(test.type)) {
       continue;
     }
 
     for (var fragNum=0; fragNum<gFragmentParams.length; fragNum++) {
       var p = gFragmentParams[fragNum];
-      var t = new Object;
+      var t = {};
       t.name = test.name + p.fragment;
       t.type = test.type;
       t.duration = test.duration;
       t.start = p.start;
       t.end = p.end;
       tests.push(t);
     }
   }
   return tests;
 }
 
 function startTest(test, token) {
-  var v = document.createElement('video');
+  var video = document.createElement('video');
   manager.started(token);
-  v.preload = "metadata";
-  v.src = test.name;
-  v.token = token;
-  v.controls = true;
-  document.body.appendChild(v);
+  video.preload = "metadata";
+  video.src = test.name;
+  video.token = token;
+  video.controls = true;
+  document.body.appendChild(video);
   var name = test.name + " fragment test";
-  var localIs = function(name) { return function(a, b, msg) {
-    is(a, b, name + ": " + msg);
+  var localIs = function(n) { return function(a, b, msg) {
+    is(a, b, n + ": " + msg);
   }}(name);
-  var localOk = function(name) { return function(a, msg) {
-    ok(a, name + ": " + msg);
+  var localOk = function(n) { return function(a, msg) {
+    ok(a, n + ": " + msg);
   }}(name);
-  var localFinish = function(v, manager) { return function() {
+  var localFinish = function(v, m) { return function() {
     removeNodeAndSource(v);
-    manager.finished(v.token);
-  }}(v, manager);
-  window['test_fragment_noplay'](v, test.start, test.end, localIs, localOk, localFinish);
+    m.finished(v.token);
+  }}(video, manager);
+  window.test_fragment_noplay(video, test.start, test.end, localIs, localOk, localFinish);
 }
 
 manager.runTests(createTestArray(), startTest);
 
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/test/test_fragment_play.html
+++ b/dom/media/test/test_fragment_play.html
@@ -39,17 +39,17 @@ function createTestArray() {
   for (var testNum=0; testNum<gFragmentTests.length; testNum++) {
     var test = gFragmentTests[testNum];
     if (!tmpVid.canPlayType(test.type)) {
       continue;
     }
 
     for (var fragNum=0; fragNum<gFragmentParams.length; fragNum++) {
       var p = gFragmentParams[fragNum];
-      var t = new Object;
+      var t = {};
       t.name = test.name + p.fragment;
       t.type = test.type;
       t.duration = test.duration;
       t.start = p.start;
       t.end = p.end;
       t.todo = p.todo;
       tests.push(t);
     }
@@ -57,35 +57,35 @@ function createTestArray() {
   return tests;
 }
 
 function startTest(test, token) {
   if (test.todo) {
     todo(false, test.todo);
     return;
   }
-  var v = document.createElement('video');
+  var video = document.createElement('video');
   manager.started(token);
-  v.preload = "metadata";
-  v.src = test.name;
-  v.token = token;
-  v.controls = true;
-  document.body.appendChild(v);
+  video.preload = "metadata";
+  video.src = test.name;
+  video.token = token;
+  video.controls = true;
+  document.body.appendChild(video);
   var name = test.name + " fragment test";
-  var localIs = function(name) { return function(a, b, msg) {
-    is(a, b, name + ": " + msg);
+  var localIs = function(n) { return function(a, b, msg) {
+    is(a, b, n + ": " + msg);
   }}(name);
-  var localOk = function(name) { return function(a, msg) {
-    ok(a, name + ": " + msg);
+  var localOk = function(n) { return function(a, msg) {
+    ok(a, n + ": " + msg);
   }}(name);
-  var localFinish = function(v, manager) { return function() {
+  var localFinish = function(v, m) { return function() {
     removeNodeAndSource(v);
-    manager.finished(v.token);
-  }}(v, manager);
-  window['test_fragment_play'](v, test.start, test.end, localIs, localOk, localFinish);
+    m.finished(v.token);
+  }}(video, manager);
+  window.test_fragment_play(video, test.start, test.end, localIs, localOk, localFinish);
 }
 
 manager.runTests(createTestArray(), startTest);
 
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/test/test_info_leak.html
+++ b/dom/media/test/test_info_leak.html
@@ -8,17 +8,17 @@ https://bugzilla.mozilla.org/show_bug.cg
   <script src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
   <script type="text/javascript" src="manifest.js"></script>
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=478957">Mozilla Bug 478957</a>
 <p id="display"></p>
 <div id="content" style="display: none">
-  
+
 </div>
 
 <div id="log" style="font-size: small;"></div>
 
 <pre id="test">
 <script type="application/javascript">
 
 /** Test for Bug 478957 **/
@@ -37,29 +37,30 @@ function createTestArray() {
 
   return makeInfoLeakTests().then(infoLeakTests => {
     for (var testNum=0; testNum < infoLeakTests.length; testNum++) {
       var test = infoLeakTests[testNum];
       if (!tmpVid.canPlayType(test.type)) {
         continue;
       }
 
-      var t = new Object;
+      var t = {};
       t.name = test.src;
       t.type = test.type;
 
       tests.push(t);
     }
     return tests;
   })
 }
 
 function log(msg) {
   info(msg);
   var l = document.getElementById('log');
+  // eslint-disable-next-line no-unsanitized/property
   l.innerHTML += msg + "<br>";
 }
 
 function finish(v) {
   log("finish: " + v.name);
   clearInterval(v.checkStateInterval);
 
   for (var i=0; i<gEventTypes.length; i++) {
@@ -86,17 +87,17 @@ function listener(evt) {
   var expected = (v.eventNum < gExpectedEvents.length) ? gExpectedEvents[v.eventNum] : "NoEvent";
   is(evt.type, expected, filename(v.name) + " Events received in wrong order");
   v.eventNum++;
   if (v.eventNum == gExpectedEvents.length) {
     // In one second, move onto the next test. This give a chance for any
     // other events to come in. Note: we don't expect any events to come
     // in, unless we've leaked some info, and 1 second should be enough time
     // for the leak to show up.
-    setTimeout(function() {finish(v);}, 1000); 
+    setTimeout(function() {finish(v);}, 1000);
   }
 }
 
 function createMedia(type, src, token) {
   var tag = getMajorMimeType(type);
   var v = document.createElement(tag);
   for (var i=0; i<gEventTypes.length; i++) {
     v.addEventListener(gEventTypes[i], listener);
@@ -129,17 +130,17 @@ function test_is(a, b, msg) {
   }
 }
 
 function filename(uri) {
   return uri.substr(uri.lastIndexOf("/")+1);
 }
 
 function checkState(v) {
-  test_ok(v.networkState <= HTMLMediaElement.NETWORK_LOADING || 
+  test_ok(v.networkState <= HTMLMediaElement.NETWORK_LOADING ||
           v.networkState == HTMLMediaElement.NETWORK_NO_SOURCE,
           "NetworkState of " + v.networkState + " was leaked.");
   test_ok(v.readyState == HTMLMediaElement.HAVE_NOTHING,
           "Ready state of " + v.readyState + " was leaked");
   test_is(v.seeking, false, "Seeking leaked");
   test_is(v.currentTime, 0, "Leaked currentTime");
   test_ok(isNaN(v.duration), "Leaked duration");
   test_is(v.paused, true, "Paused leaked");
@@ -154,17 +155,17 @@ function checkState(v) {
           v.networkState == HTMLMediaElement.NETWORK_NO_SOURCE,
           "currentSrc should match candidate uri, if we've got a valid source");
 }
 
 
 function startTest(test, token) {
   manager.started(token);
   log("Testing: " + test.type + " @ " + test.name);
-  createMedia(test.type, test.name, token);  
+  createMedia(test.type, test.name, token);
 }
 
 SimpleTest.waitForExplicitFinish();
 createTestArray().then(testArray => {
   manager.runTests(testArray, startTest);
 });
 
 </script>
--- a/dom/media/test/test_load.html
+++ b/dom/media/test/test_load.html
@@ -84,72 +84,66 @@ function prependSource(src, type) {
   s.type = type;
   gMedia.insertBefore(s, gMedia.firstChild);
   return s;
 }
 
 var gTests = [
   {
     // Test 0: adding video to doc, then setting src should load implicitly.
-    create:
-      function(src, type) {
+    create(src, type) {
         document.body.appendChild(gMedia);
         gMedia.src = src;
       },
     expectedEvents: ['loadstart', 'durationchange', 'loadedmetadata', 'loadeddata']
   }, {
     // Test 1: adding video to doc, then adding source.
-    create:
-      function(src, type) {
+    create(src, type) {
         document.body.appendChild(gMedia);
         addSource(src, type);
       },
     expectedEvents: ['loadstart', 'durationchange', 'loadedmetadata', 'loadeddata']
   },{
     // Test 2: video with multiple source, the first of which are bad, we should load the last,
     // and receive error events for failed loads on the source children.
-    create:
-      function(src, type) {
+    create(src, type) {
         document.body.appendChild(gMedia);
         addSource("404a", type);
         addSource("404b", type);
         addSource(src, type);
       },
     expectedEvents: ['loadstart', 'source_error', 'source_error', 'durationchange', 'loadedmetadata', 'loadeddata']
   }, {
     // Test 3:  video with bad src, good <source>, ensure that <source> aren't used.
-    create:
-      function(src, type) {
+    create(src, type) {
         gMedia.src = "404a";
         addSource(src, type);
         document.body.appendChild(gMedia);
       },
     expectedEvents: ['loadstart', 'error']
   }, {
     // Test 4:  video with only bad source, loading, then adding a good source
     // -  should resume load.
-    create:
-      function(src, type) {
+    create(src, type) {
         addSource("404a", type);
         var s2 = addSource("404b", type);
         s2.addEventListener("error",
           function(e) {
             // Should awaken waiting load, causing successful load.
             addSource(src, type);
           });
         document.body.appendChild(gMedia);
       },
     expectedEvents: ['loadstart', 'source_error', 'source_error', 'durationchange', 'loadedmetadata', 'loadeddata']
   }, {
     // Test 5: video with only 1 bad source, let it fail to load, then prepend
     // a good <source> to the video, it shouldn't be selected, because the
     // "pointer" should be after the last child - the bad source.
     prepended: false,
-    create:
-      function(src, type) {
+    create(src, type) {
         var prepended = false;
         addSource("404a", type);
         var s2 = addSource("404b", type);
         s2.addEventListener("error",
           function(e) {
             // Should awaken waiting load, causing successful load.
             if (!prepended) {
               prependSource(src, type);
@@ -157,18 +151,17 @@ var gTests = [
             }
           });
         document.body.appendChild(gMedia);
       },
     expectedEvents: ['loadstart', 'source_error', 'source_error']
   }, {
     // Test 6: (Bug 1165203) preload="none" then followed by an explicit
     // call to load() should load metadata
-    create:
-      function(src, type) {
+    create(src, type) {
         gMedia.preload = "none";
         gMedia.src = src;
         document.body.appendChild(gMedia);
         addSource(src, type);
         gMedia.load();
       },
     expectedEvents: ['emptied',  'loadstart', 'durationchange', 'loadedmetadata', 'loadeddata']
   }
--- a/dom/media/test/test_load_same_resource.html
+++ b/dom/media/test/test_load_same_resource.html
@@ -33,21 +33,21 @@ function tryClone(e) {
   manager.started(clone.token);
   manager.finished(e.token);
 
   // Log events for debugging.
   var events = ["suspend", "play", "canplay", "canplaythrough", "loadstart", "loadedmetadata",
                 "loadeddata", "playing", "ended", "error", "stalled", "emptied", "abort",
                 "waiting", "pause"];
   function logEvent(evt) {
-    var e = evt.target;
-    info(`${e.token} got ${evt.type}`);
+    var event = evt.target;
+    info(`${event.token} got ${evt.type}`);
   }
-  events.forEach(function(e) {
-    clone.addEventListener(e, logEvent);
+  events.forEach(function(event) {
+    clone.addEventListener(event, logEvent);
   });
 
 
   checkDuration(e.duration, e._expectedDuration, e.token);
   clone._expectedDuration = e._expectedDuration;
 
   clone.addEventListener("loadeddata", cloneLoaded, {once: true});
   clone.addEventListener("loadstart", function(evt) {
--- a/dom/media/test/test_media_selection.html
+++ b/dom/media/test/test_media_selection.html
@@ -102,18 +102,18 @@ for (var i = 0; i < gSmallTests.length; 
   var type = test.type;
 
   if (!tmpVid.canPlayType(type))
     continue;
 
   // The following nested function hack is to ensure that 'test' is correctly
   // captured in the closure and we don't end up getting the value 'test'
   // had in the last iteration of the loop. I blame Brendan.
-  var check = function(test) { return function (e) {
-    checkMetadata(test.name, e, test);
+  var check = function(t) { return function (e) {
+    checkMetadata(t.name, e, t);
   }}(test);
 
   var otherType = type.match(/^video\//) ? "audio/x-wav" : "video/ogg";
   subtests.push(maketest(set_src, src, null, check),
                 maketest(add_source, src, null, check),
                 maketest(add_source, src, type, check),
                 maketest(add_sources_last, src, null, check),
                 maketest(add_sources_first, src, type, check),
@@ -125,18 +125,18 @@ for (var i = 0; i < gSmallTests.length; 
                 // should not start loading, type excludes it from media candiate list
                 maketest(add_source, src, 'bogus/type', null),
 
                 // element doesn't notice source children attached later, needs bug 462455 fixed
                 maketest(late_add_sources_last, src, type, check),
                 maketest(late_add_sources_first, src, type, check));
 }
 
-function startTest(test, token) {
-  test(token);
+function startTest(t, token) {
+  t(token);
 }
 
 manager.runTests(subtests, startTest);
 
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/test/test_mediarecorder_bitrate.html
+++ b/dom/media/test/test_mediarecorder_bitrate.html
@@ -19,17 +19,16 @@ var results = [];
 function startTest(test, token) {
   manager.started(token);
   runTest(test, token, 1000000);
   runTest(test, token, 100000);
 }
 
 function runTest(test, token, bitrate) {
   var element = document.createElement('video');
-  var expectedMimeType = test.type.substring(0, test.type.indexOf(';'));
 
   element.token = token;
 
   element.src = test.name;
   element.preload = "metadata";
   element.onloadedmetadata = function () {
     info("loadedmetadata");
     const stream = element.mozCaptureStreamUntilEnded();
--- a/dom/media/test/test_mediarecorder_pause_resume_video.html
+++ b/dom/media/test/test_mediarecorder_pause_resume_video.html
@@ -8,16 +8,17 @@
 </head>
 <body>
 <pre id="test">
 <div id="content">
   <canvas id="video-src-canvas"></canvas>
   <video id="recorded-video"></video>
 </div>
 <script class="testbody" type="text/javascript">
+/* import-globals-from ../../canvas/test/captureStream_common.js */
 
 function startTest() {
   // Setup canvas and take a stream from it
   let canvas = document.getElementById("video-src-canvas");
 
   let canvas_size = 100;
   let new_canvas_size = 50;
 
@@ -29,17 +30,17 @@ function startTest() {
   let canvasStream = canvas.captureStream();
   // Canvas set up
 
    // Check values for events
   let numDataAvailabledRaised = 0;
   // Recorded data that will be playback.
   let blob;
 
-  mediaRecorder = new MediaRecorder(canvasStream);
+  let mediaRecorder = new MediaRecorder(canvasStream);
   is(mediaRecorder.stream, canvasStream,
      "Media recorder stream = canvas stream at the start of recording");
 
   mediaRecorder.onwarning = () => ok(false, "warning unexpectedly fired");
 
   mediaRecorder.onerror = () => ok(false, "Recording failed");
 
   mediaRecorder.ondataavailable = ev => {
--- a/dom/media/test/test_mediarecorder_playback_can_repeat.html
+++ b/dom/media/test/test_mediarecorder_playback_can_repeat.html
@@ -8,16 +8,17 @@
 </head>
 <body>
 <pre id="test">
 <div id="content">
   <canvas id="video-src-canvas"></canvas>
   <video id="recorded-video" loop></video>
 </div>
 <script class="testbody" type="text/javascript">
+/* import-globals-from ../../canvas/test/captureStream_common.js */
 
 function startTest() {
   let canvas = document.getElementById("video-src-canvas");
 
   let canvas_size = 100;
   canvas.width = canvas.height = canvas_size;
   let helper = new CaptureStreamTestHelper2D(canvas_size, canvas_size);
   helper.drawColor(canvas, helper.red);
--- a/dom/media/test/test_mediarecorder_record_4ch_audiocontext.html
+++ b/dom/media/test/test_mediarecorder_record_4ch_audiocontext.html
@@ -22,42 +22,39 @@ function startTest() {
   var source = context.createBufferSource();
   source.buffer = buffer;
   source.loop = true;
   var dest = context.createMediaStreamDestination();
   var stopTriggered = false;
   var onstopTriggered = false;
   dest.channelCount = 4;
   var expectedMimeType = 'audio/ogg; codecs=opus';
-  var totalBlobSize = 0;
   source.channelCountMode = 'explicit';
   source.connect(dest);
   var elem = document.createElement('audio');
   elem.srcObject = dest.stream;
-  mMediaStream = dest.stream;
   source.start(0);
   elem.play();
-  mMediaRecorder = new MediaRecorder(dest.stream);
+  let mMediaRecorder = new MediaRecorder(dest.stream);
   mMediaRecorder.onwarning = function() {
     ok(false, 'onwarning unexpectedly fired');
   };
 
   mMediaRecorder.onerror = function() {
     ok(false, 'onerror unexpectedly fired');
   };
 
   mMediaRecorder.onstop = function() {
     ok(true, 'onstop fired successfully');
     is(mMediaRecorder.state, 'inactive', 'check recording status is inactive');
     onstopTriggered = true;
     SimpleTest.finish();
   };
   mMediaRecorder.ondataavailable = function (e) {
     ok(e.data.size > 0, 'check blob has data');
-    totalBlobSize += e.data.size;
     is(e.data.type, expectedMimeType, 'blob should have expected mimetype');
     if (!stopTriggered) {
       is(mMediaRecorder.mimeType, expectedMimeType, 'recorder should have expected mimetype');
       mMediaRecorder.stop();
       is(mMediaRecorder.mimeType, '', 'recorder should have reset its mimetype');
       stopTriggered = true;
     } else if (onstopTriggered) {
       ok(false, 'ondataavailable should come before onstop event');
--- a/dom/media/test/test_mediarecorder_record_addtracked_stream.html
+++ b/dom/media/test/test_mediarecorder_record_addtracked_stream.html
@@ -7,16 +7,18 @@
   <script src="/tests/dom/media/tests/mochitest/head.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 <pre id="test">
 <div id="content">
 </div>
 <script>
+/* import-globals-from ../../canvas/test/captureStream_common.js */
+/* import-globals-from ../tests/mochitest/head.js */
 SimpleTest.waitForExplicitFinish();
 runTestWhenReady(async () => {
   const canvas = document.createElement("canvas");
   canvas.width = canvas.height = 100;
   document.getElementById("content").appendChild(canvas);
 
   const helper = new CaptureStreamTestHelper2D(100, 100);
   helper.drawColor(canvas, helper.red);
@@ -28,17 +30,17 @@ runTestWhenReady(async () => {
   const dest = audioCtx.createMediaStreamDestination();
   osc.connect(dest);
 
   const stream = dest.stream;
   canvas.captureStream(0).getVideoTracks().forEach(t => stream.addTrack(t));
 
   const blobs = [];
 
-  mediaRecorder = new MediaRecorder(stream);
+  let mediaRecorder = new MediaRecorder(stream);
   is(mediaRecorder.stream, stream,
      "Media recorder stream = constructed stream at the start of recording");
 
 
   mediaRecorder.ondataavailable = evt => {
     info("ondataavailable fired");
 
     is(mediaRecorder.state, "inactive", "Blob received after stopping");
--- a/dom/media/test/test_mediarecorder_record_audiocontext.html
+++ b/dom/media/test/test_mediarecorder_record_audiocontext.html
@@ -7,34 +7,32 @@
   <script type="text/javascript" src="manifest.js"></script>
 </head>
 <body>
 
 <script class="testbody" type="text/javascript">
 
 function startTest() {
   var context = new AudioContext();
-  var hasonstop = false;
   var buffer = context.createBuffer(1, 80920, context.sampleRate);
   for (var i = 0; i < 80920; ++i) {
     buffer.getChannelData(0)[i] = Math.sin(1000 * 2 * Math.PI * i / context.sampleRate);
   }
 
   var source = context.createBufferSource();
   source.buffer = buffer;
   source.loop = true;
 
   var dest = context.createMediaStreamDestination();
   source.connect(dest);
   var elem = document.createElement('audio');
   elem.srcObject = dest.stream;
-  mMediaStream = dest.stream;
   source.start(0);
   elem.play();
-  mMediaRecorder = new MediaRecorder(dest.stream);
+  let mMediaRecorder = new MediaRecorder(dest.stream);
   mMediaRecorder.onwarning = function() {
     ok(false, 'onwarning unexpectedly fired');
   };
 
   mMediaRecorder.onerror = function() {
     ok(false, 'onerror unexpectedly fired');
   };
 
--- a/dom/media/test/test_mediarecorder_record_canvas_captureStream.html
+++ b/dom/media/test/test_mediarecorder_record_canvas_captureStream.html
@@ -6,30 +6,31 @@
   <script src="/tests/dom/canvas/test/captureStream_common.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 <pre id="test">
 <div id="content">
 </div>
 <script class="testbody" type="text/javascript">
+/* import-globals-from ../../canvas/test/captureStream_common.js */
 
 function startTest() {
   var canvas = document.createElement("canvas");
   canvas.width = canvas.height = 100;
   document.getElementById("content").appendChild(canvas);
 
   var helper = new CaptureStreamTestHelper2D(100, 100);
   helper.drawColor(canvas, helper.red);
 
   var stream = canvas.captureStream(0);
 
   var blob;
 
-  mediaRecorder = new MediaRecorder(stream);
+  let mediaRecorder = new MediaRecorder(stream);
   is(mediaRecorder.stream, stream,
      "Media recorder stream = canvas stream at the start of recording");
 
   mediaRecorder.onwarning = () => ok(false, "warning unexpectedly fired");
 
   mediaRecorder.onerror = () => ok(false, "Recording failed");
 
   mediaRecorder.ondataavailable = ev => {
--- a/dom/media/test/test_mediarecorder_record_downsize_resolution.html
+++ b/dom/media/test/test_mediarecorder_record_downsize_resolution.html
@@ -6,16 +6,17 @@
   <script src="/tests/dom/canvas/test/captureStream_common.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 <pre id="test">
 <div id="content">
 </div>
 <script class="testbody" type="text/javascript">
+/* import-globals-from ../../canvas/test/captureStream_common.js */
 
 function startTest() {
   var canvas = document.createElement("canvas");
   var canvas_size = 100;
   var new_canvas_size = 50;
   canvas.width = canvas.height = canvas_size;
 
   var helper = new CaptureStreamTestHelper2D(canvas_size, canvas_size);
--- a/dom/media/test/test_mediarecorder_record_gum_video_timeslice.html
+++ b/dom/media/test/test_mediarecorder_record_gum_video_timeslice.html
@@ -15,17 +15,17 @@
 async function startTest() {
   try {
     await setupGetUserMediaTestPrefs();
     let stream = await navigator.mediaDevices.getUserMedia({audio: true, video: true});
     let dataAvailableCount = 0;
     let onDataAvailableFirst = false;
     const expectedMimeType = 'video/webm; codecs="vp8, opus"';
 
-    mediaRecorder = new MediaRecorder(stream);
+    let mediaRecorder = new MediaRecorder(stream);
     is(mediaRecorder.stream, stream,
        'Media recorder stream = element stream at the start of recording');
     mediaRecorder.onwarning = function() {
       ok(false, 'onwarning unexpectedly fired');
     };
 
     mediaRecorder.onerror = function() {
       ok(false, 'onerror unexpectedly fired');
@@ -44,17 +44,17 @@ async function startTest() {
       is(evt.type, 'dataavailable',
          'Event type should dataavailable');
       ok(evt.data.size >= 0,
          'Blob data size ' + evt.data.size + ' received is greater than or equal to zero');
       is(evt.data.type, expectedMimeType, 'Expected blob mime type');
 
       // We'll stop recording upon the 1st blob being received
       if (dataAvailableCount === 1) {
-        mediaRecorder.onstop = function (evt) {
+        mediaRecorder.onstop = function (event) {
           info('onstop fired');
 
           if (!onDataAvailableFirst) {
             ok(false, 'onstop unexpectedly fired before ondataavailable');
           }
 
           ok(true, 'onstop fired successfully');
           is(mediaRecorder.state, 'inactive',
--- a/dom/media/test/test_mediarecorder_record_gum_video_timeslice_mixed.html
+++ b/dom/media/test/test_mediarecorder_record_gum_video_timeslice_mixed.html
@@ -8,17 +8,17 @@
 </head>
 <body>
 <pre id="test">
 <script type="text/javascript">
 function unexpected({type}) {
   ok(false, `${type} unexpectedly fired`);
 }
 
-(async _ => {
+(async () => {
   SimpleTest.waitForExplicitFinish();
   let blobUrl = null;
   let stream = null;
   try {
     // This is the memory limit per blob. If a blob is larger than this,
     // MediaRecorder will put it in a file. For this test we need to get at
     // least one blob under, and one blob over the limit.
     const memoryLimit = 3000;
@@ -27,17 +27,17 @@ function unexpected({type}) {
     ]});
     // We always use fake devices since the loopback ones don't make enough
     // pixels change per frame to make the encoded frames large enough.
     await pushGetUserMediaTestPrefs({fakeAudio: true, fakeVideo: true});
     stream = await navigator.mediaDevices.getUserMedia(
       {audio: true, video: true});
     const blobs = [];
 
-    mediaRecorder = new MediaRecorder(stream);
+    let mediaRecorder = new MediaRecorder(stream);
     is(mediaRecorder.stream, stream,
        "Media recorder stream = element stream at the start of recording");
     mediaRecorder.start();
     mediaRecorder.addEventListener("warning", unexpected);
     mediaRecorder.addEventListener("error", unexpected);
     mediaRecorder.addEventListener("stop", unexpected);
     await new Promise(r => mediaRecorder.onstart = r);
 
@@ -73,17 +73,17 @@ function unexpected({type}) {
     const blob = new Blob(blobs);
     blobUrl = URL.createObjectURL(blob);
     video.src = blobUrl;
     info(`Starting playback. Blob-size=${blob.size}`);
     video.play();
 
     await Promise.race([
       new Promise(res => video.onended = res),
-      new Promise((_, rej) => video.onerror = _ => rej(video.error.message)),
+      new Promise((res, rej) => video.onerror = () => rej(video.error.message)),
     ]);
   } catch (e) {
     ok(false, e);
   } finally {
     if (stream) {
       for (const t of stream.getTracks()) {
         t.stop();
       }
--- a/dom/media/test/test_mediarecorder_record_timeslice.html
+++ b/dom/media/test/test_mediarecorder_record_timeslice.html
@@ -63,17 +63,17 @@ function startTest(test, token) {
 
       is(evt.data.type, expectedMimeType,
          'Blob data received should have type = ' + expectedMimeType);
       is(mediaRecorder.mimeType, expectedMimeType,
          'Mime type in ondataavailable = ' + mediaRecorder.mimeType);
 
       // We'll stop recording upon the 1st blob being received
       if (dataAvailableCount === 1) {
-        mediaRecorder.onstop = function (evt) {
+        mediaRecorder.onstop = function (event) {
           info('onstop fired');
 
           if (!onDataAvailableFirst) {
             ok(false, 'onstop unexpectedly fired before ondataavailable');
           }
           element.pause();
           manager.finished(token);
         };
--- a/dom/media/test/test_mediarecorder_record_upsize_resolution.html
+++ b/dom/media/test/test_mediarecorder_record_upsize_resolution.html
@@ -6,16 +6,17 @@
   <script src="/tests/dom/canvas/test/captureStream_common.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 <pre id="test">
 <div id="content">
 </div>
 <script class="testbody" type="text/javascript">
+/* import-globals-from ../../canvas/test/captureStream_common.js */
 
 function startTest() {
   var canvas = document.createElement("canvas");
   var canvas_size = 100;
   var new_canvas_size = 150;
   canvas.width = canvas.height = canvas_size;
 
   var helper = new CaptureStreamTestHelper2D(canvas_size, canvas_size);
--- a/dom/media/test/test_mediarecorder_reload_crash.html
+++ b/dom/media/test/test_mediarecorder_reload_crash.html
@@ -6,22 +6,24 @@
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
   <script type="text/javascript" src="manifest.js"></script>
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=894348">Mozill
 a Bug 894348</a>
 <pre id="test">
 <script class="testbody" type="text/javascript">
-  for (i = 0; i< 5; i++) {
+  for (let i = 0; i< 5; i++) {
+    /* eslint-disable no-undef */
     try { o0 = document.createElement('audio') } catch(e) { }
     try { o0.src = "sound.ogg" } catch(e) { }
     try { (document.body || document.documentElement).appendChild(o0) } catch(e) { }
     try { o1 = o0.mozCaptureStreamUntilEnded(); } catch(e) { }
     try { o2 = new MediaRecorder(o1) } catch(e) { }
     try { o2.start(0) } catch(e) { }
+    /* eslint-enable no-undef */
     SpecialPowers.gc();
   }
   ok(true, "pass the crash test");
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/test/test_mediarecorder_state_transition.html
+++ b/dom/media/test/test_mediarecorder_state_transition.html
@@ -218,22 +218,22 @@ var operationTests = [
  * Runs through each available state transition test by running all
  * available operations on a media recorder object. Then, we report
  * back if the test was expected through an exception or not.
  *
  * @param {MediaStream} testStream the media stream used for media recorder
  *                                 operation tests
  */
 function runStateTransitionTests(testStream) {
-  for (operationTest of operationTests) {
+  for (const operationTest of operationTests) {
     var mediaRecorder = new MediaRecorder(testStream);
     var operationsString = operationTest.operations.toString();
 
     try {
-      for (operation of operationTest.operations) {
+      for (const operation of operationTest.operations) {
         if (operationTest.timeSlice && operation === 'start') {
           operationsString += ' with timeslice ' + operationTest.timeSlice;
           mediaRecorder[operation](operationTest.timeSlice);
         } else {
           mediaRecorder[operation]();
         }
       }
 
@@ -251,17 +251,16 @@ function runStateTransitionTests(testStr
 
 /**
  * Starts a test on every media recorder file included to check that various
  * state transition flows that can happen in the media recorder object throw
  * exceptions when they are expected to and vice versa.
  */
 function startTest(test, token) {
   var element = document.createElement('audio');
-  var expectedMimeType = test.type.substring(0, test.type.indexOf(';'));
 
   element.token = token;
   manager.started(token);
 
   element.src = test.name;
   element.test = test;
   element.stream = element.mozCaptureStream();
 
--- a/dom/media/test/test_mediatrack_consuming_mediastream.html
+++ b/dom/media/test/test_mediatrack_consuming_mediastream.html
@@ -9,52 +9,42 @@
 </head>
 <body>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 async function startTest() {
   let steps = 0;
   let audioOnchange = 0;
   let audioOnaddtrack = 0;
-  let audioOnremovetrack = 0;
   let videoOnchange = 0;
   let videoOnaddtrack = 0;
-  let videoOnremovetrack = 0;
   let isPlaying = false;
   let element = document.createElement("video");
   let stream;
   try {
     await setupGetUserMediaTestPrefs();
     stream = await navigator.mediaDevices.getUserMedia({audio: true, video: true});
   } catch (err) {
     ok(false, 'Unexpected error fired with: ' + err);
     SimpleTest.finish();
     return;
   }
 
   element.audioTracks.onaddtrack = function(e) {
     audioOnaddtrack++;
   };
 
-  element.audioTracks.onremovetrack = function(e) {
-    audioOnremovetrack++;
-  };
-
   element.audioTracks.onchange = function(e) {
     audioOnchange++;
   };
 
   element.videoTracks.onaddtrack = function(e) {
     videoOnaddtrack++;
   };
 
-  element.videoTracks.onremovetrack = function(e) {
-    videoOnremovetrack++;
-  };
-
   element.videoTracks.onchange = function(e) {
     videoOnchange++;
   };
 
   function checkTrackRemoved() {
     if (isPlaying) {
       is(element.audioTracks.length, 0, 'The length of audioTracks should be 0.');
       is(element.videoTracks.length, 0, 'The length of videoTracks should be 0.');
--- a/dom/media/test/test_mediatrack_replay_from_end.html
+++ b/dom/media/test/test_mediatrack_replay_from_end.html
@@ -21,20 +21,18 @@ function startTest(test, token) {
   //    and all tracks should be removed from the list after we seek to the end.
   // 3. After seek to the middle from end of playback, all tracks should be
   //    added back to the list if we play from here, and all tracks should be
   //    removed from the list after we seek to the end.
 
   var elemType = getMajorMimeType(test.type);
   var element = document.createElement(elemType);
 
-  var audioOnchange = 0;
   var audioOnaddtrack = 0;
   var audioOnremovetrack = 0;
-  var videoOnchange = 0;
   var videoOnaddtrack = 0;
   var videoOnremovetrack = 0;
   var isPlaying = false;
   var steps = 0;
 
   element.audioTracks.onaddtrack = function(e) {
     audioOnaddtrack++;
   }
--- a/dom/media/test/test_metadata.html
+++ b/dom/media/test/test_metadata.html
@@ -21,56 +21,57 @@ function startTest(test, token) {
   manager.started(token);
 
   a.src = test.name;
   a.name = test.name;
 
   // Tags should not be available immediately.
   var exception_fired = false;
   try {
-    var m = a.mozGetMetadata();
+    a.mozGetMetadata();
   } catch (e) {
     is(e.name, 'InvalidStateError',
        "early mozGetMetadata() should throw InvalidStateError");
     exception_fired = true;
   }
   ok(exception_fired,
      "mozGetMetadata() should throw an exception before HAVE_METADATA");
 
   // Wait until metadata has loaded.
   a.addEventListener('loadedmetadata', function() {
     // read decoded tags
-    tags = a.mozGetMetadata();
+    let tags = a.mozGetMetadata();
     ok(tags, "mozGetMetadata() should return a truthy value");
     // Dump them out.
     var d = document.getElementById('output');
     var html = '<table>\n';
     html += '<caption><p>Called getMozMetadata()'
     html += ' on '+test.name+'</p></caption>\n';
     html += '<tr><th>tag</th>';
     html += '<th>decoded value</th><th>expected value</th></tr>\n';
-    for (tag in tags) {
+    for (let tag in tags) {
       html += '<tr><td>'+tag+'</td>';
       html += '<td>'+tags[tag]+'</td>';
       html += '<td>'+test.tags[tag]+'</td>';
       html += '</tr>\n';
     }
     if (!Object.keys(tags).length) {
       html += '<tr><td colspan=3 align=center><em>no tags</em></td></tr>\n';
     }
     html += '</table>\n';
     var div = document.createElement('div');
+    // eslint-disable-next-line no-unsanitized/property
     div.innerHTML = html;
     d.appendChild(div);
     // Verify decoded tag values.
-    for (tag in tags) {
+    for (let tag in tags) {
       is(tags[tag], test.tags[tag], "Tag '"+tag+"' should match");
     }
     // Verify expected tag values
-    for (tag in test.tags) {
+    for (let tag in test.tags) {
       is(tags[tag], test.tags[tag], "Tag '"+tag+"' should match");
     }
     removeNodeAndSource(a);
     manager.finished(token);
   });
 }
 
 manager.runTests(gMetadataTests, startTest);
--- a/dom/media/test/test_midflight_redirect_blocked.html
+++ b/dom/media/test/test_midflight_redirect_blocked.html
@@ -29,47 +29,43 @@
             element.addEventListener(eventName, (event)=> {
               info(test.name + " " + event.type);
             });
           });
 
           element.addEventListener("loadedmetadata", ()=>{
             resolve(true);
             removeNodeAndSource(element);
-          }, false);
+          });
 
           element.addEventListener("error", ()=>{
             resolve(false);
             removeNodeAndSource(element);
-          }, false);
+          });
 
-          var noise = Math.floor(Math.random() * 100000000);
           // Note: request redirect before the end of metadata, otherwise we won't
           // error before metadata has loaded if mixed origins are allowed.
           element.src = "midflight-redirect.sjs?resource=" + test.name
                       + (useCors ? "&cors" : "")
                       + "&type=" + test.type
                       + "&redirectAt=200";
           element.preload = "metadata";
           document.body.appendChild(element);
           element.load()
         });
       }
 
       let v = document.createElement("video");
       const testCases = gSmallTests.filter(t => v.canPlayType(t.type));
 
-      function testMediaLoad(expectedToLoad, message, useCors) {
-        return new Promise(async function(resolve, reject) {
-          for (let test of testCases) {
-            let loaded = await testIfLoadsToMetadata(test, useCors);
-            is(loaded, expectedToLoad, test.name + " " + message);
-          }
-          resolve();
-        });
+      async function testMediaLoad(expectedToLoad, message, useCors) {
+        for (let test of testCases) {
+          let loaded = await testIfLoadsToMetadata(test, useCors);
+          is(loaded, expectedToLoad, test.name + " " + message);
+        }
       }
 
       async function runTest() {
         try {
           SimpleTest.info("Allowing midflight redirects...");
           await SpecialPowers.pushPrefEnv({'set': [["media.block-midflight-redirects", false]]});
 
           SimpleTest.info("Test that all media plays...");
--- a/dom/media/test/test_play_twice.html
+++ b/dom/media/test/test_play_twice.html
@@ -8,88 +8,88 @@
 </head>
 <body>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 var manager = new MediaTestManager;
 
 function startTest(test, token) {
-  var v = document.createElement('video');
-  v.token = token;
+  var video = document.createElement('video');
+  video.token = token;
   manager.started(token);
-  v.src = test.name;
-  v.name = test.name;
-  v.playingCount = 0;
-  v._playedOnce = false;
+  video.src = test.name;
+  video.name = test.name;
+  video.playingCount = 0;
+  video._playedOnce = false;
 
-  var check = function(test, v) { return function() {
-    checkMetadata(test.name, v, test);
-  }}(test, v);
+  var check = function(t, v) { return function() {
+    checkMetadata(t.name, v, test);
+  }}(test, video);
 
-  var noLoad = function(test, v) { return function() {
-    ok(false, test.name + " should not fire 'load' event");
-  }}(test, v);
+  var noLoad = function(t, v) { return function() {
+    ok(false, t.name + " should not fire 'load' event");
+  }}(test, video);
 
   function finish(v) {
     removeNodeAndSource(v);
     manager.finished(v.token);
   }
 
   function mayFinish(v) {
     if (v.seenEnded && v.seenSuspend) {
       finish(v);
     }
   }
 
-  var checkEnded = function(test, v) { return function() {
-    if (test.duration) {
-      ok(Math.abs(v.currentTime - test.duration) < 0.1,
-         test.name + " current time at end: " + v.currentTime);
+  var checkEnded = function(t, v) { return function() {
+    if (t.duration) {
+      ok(Math.abs(v.currentTime - t.duration) < 0.1,
+         t.name + " current time at end: " + v.currentTime);
     }
 
-    is(v.readyState, v.HAVE_CURRENT_DATA, test.name + " checking readyState");
-    ok(v.ended, test.name + " checking playback has ended");
+    is(v.readyState, v.HAVE_CURRENT_DATA, t.name + " checking readyState");
+    ok(v.ended, t.name + " checking playback has ended");
     ok(v.playingCount > 0, "Expect at least one playing event");
     v.playingCount = 0;
 
     if (v._playedOnce) {
       v.seenEnded = true;
       mayFinish(v);
     } else {
       v._playedOnce = true;
       v.play();
     }
-  }}(test, v);
+  }}(test, video);
 
-  var checkSuspended = function(test, v) { return function() {
+  var checkSuspended = function(t, v) { return function() {
     if (v.seenSuspend) {
       return;
     }
 
     v.seenSuspend = true;
-    ok(true, test.name + " got suspend");
+    ok(true, t.name + " got suspend");
     mayFinish(v);
-  }}(test, v);
+  }}(test, video);
 
-  var checkPlaying = function(test, v) { return function() {
-    is(test.name, v.name, "Should be testing file we think we're testing...");
+  var checkPlaying = function(t, v) { return function() {
+    is(t.name, v.name, "Should be testing file we think we're testing...");
     v.playingCount++;
-  }}(test, v);
+  }}(test, video);
 
-  v.addEventListener("load", noLoad);
-  v.addEventListener("loadedmetadata", check);
-  v.addEventListener("playing", checkPlaying);
+  video.addEventListener("load", noLoad);
+  video.addEventListener("loadedmetadata", check);
+  video.addEventListener("playing", checkPlaying);
 
   // We should get "ended" and "suspend" events for every resource
-  v.addEventListener("ended", checkEnded);
-  v.addEventListener("suspend", checkSuspended);
+  video.addEventListener("ended", checkEnded);
+  video.addEventListener("suspend", checkSuspended);
 
-  document.body.appendChild(v);
-  v.play();
+  document.body.appendChild(video);
+  video.play();
 }
 
 manager.runTests(gReplayTests, startTest);
 
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/test/test_playback.html
+++ b/dom/media/test/test_playback.html
@@ -8,101 +8,101 @@
 </head>
 <body>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 var manager = new MediaTestManager;
 
 function startTest(test, token) {
-  var v = document.createElement('video');
-  v.preload = "metadata";
-  v.token = token;
-  v.prevTime = 0;
-  v.seenEnded = false;
-  v.seenSuspend = false;
+  var video = document.createElement('video');
+  video.preload = "metadata";
+  video.token = token;
+  video.prevTime = 0;
+  video.seenEnded = false;
+  video.seenSuspend = false;
 
   var handler = {
     "ontimeout": function() {
-      Log(token, "timed out: ended=" + v.seenEnded + ", suspend=" + v.seenSuspend);
+      Log(token, "timed out: ended=" + video.seenEnded + ", suspend=" + video.seenSuspend);
     }
   };
   manager.started(token, handler);
 
-  v.src = test.name;
-  v.name = test.name;
+  video.src = test.name;
+  video.name = test.name;
 
-  var check = function(test, v) { return function() {
-    is(test.name, v.name, test.name + ": Name should match #1");
-    checkMetadata(test.name, v, test);
-  }}(test, v);
+  var check = function(t, v) { return function() {
+    is(t.name, v.name, t.name + ": Name should match #1");
+    checkMetadata(t.name, v, t);
+  }}(test, video);
 
-  var noLoad = function(test, v) { return function() {
-    ok(false, test.name + " should not fire 'load' event");
-  }}(test, v);
+  var noLoad = function(t, v) { return function() {
+    ok(false, t.name + " should not fire 'load' event");
+  }}(test, video);
 
-  var noError = function(test, v) { return function() {
-    ok(false, test.name + " should not fire 'error' event " + v.error.message);
-  }}(test, v);
+  var noError = function(t, v) { return function() {
+    ok(false, t.name + " should not fire 'error' event " + v.error.message);
+  }}(test, video);
 
   var finish = function() {
-    v.finished = true;
-    v.removeEventListener("timeupdate", timeUpdate);
-    removeNodeAndSource(v);
-    manager.finished(v.token);
+    video.finished = true;
+    video.removeEventListener("timeupdate", timeUpdate);
+    removeNodeAndSource(video);
+    manager.finished(video.token);
   }
 
   // We should get "ended" and "suspend" events to finish the test.
   var mayFinish = function() {
-    if (v.seenEnded && v.seenSuspend) {
+    if (video.seenEnded && video.seenSuspend) {
       finish();
     }
   }
 
-  var checkEnded = function(test, v) { return function() {
-    is(test.name, v.name, test.name + ": Name should match #2");
-    checkMetadata(test.name, v, test);
-    is(v.readyState, v.HAVE_CURRENT_DATA, test.name + " checking readyState");
-    ok(v.ended, test.name + " checking playback has ended");
-    ok(!v.finished, test.name + " shouldn't be finished");
-    ok(!v.seenEnded, test.name + " shouldn't be ended");
+  var checkEnded = function(t, v) { return function() {
+    is(t.name, v.name, t.name + ": Name should match #2");
+    checkMetadata(t.name, v, test);
+    is(v.readyState, v.HAVE_CURRENT_DATA, t.name + " checking readyState");
+    ok(v.ended, t.name + " checking playback has ended");
+    ok(!v.finished, t.name + " shouldn't be finished");
+    ok(!v.seenEnded, t.name + " shouldn't be ended");
 
     v.seenEnded = true;
     mayFinish();
-  }}(test, v);
+  }}(test, video);
 
-  var checkSuspended = function(test, v) { return function() {
+  var checkSuspended = function(t, v) { return function() {
     if (v.seenSuspend) {
       return;
     }
-    is(test.name, v.name, test.name + ": Name should match #3");
+    is(t.name, v.name, t.name + ": Name should match #3");
 
     v.seenSuspend = true;
     mayFinish();
-  }}(test, v);
+  }}(test, video);
 
-  var timeUpdate = function(test, v) { return function() {
+  var timeUpdate = function(t, v) { return function() {
     if (v.prevTime > v.currentTime) {
-      ok(false, test.name + " time should run forwards: p=" +
+      ok(false, t.name + " time should run forwards: p=" +
                 v.prevTime + " c=" + v.currentTime);
     }
     v.prevTime = v.currentTime;
-  }}(test, v);
+  }}(test, video);
 
-  v.addEventListener("load", noLoad);
-  v.addEventListener("error", noError);
-  v.addEventListener("loadedmetadata", check);
-  v.addEventListener("timeupdate", timeUpdate);
+  video.addEventListener("load", noLoad);
+  video.addEventListener("error", noError);
+  video.addEventListener("loadedmetadata", check);
+  video.addEventListener("timeupdate", timeUpdate);
 
   // We should get "ended" and "suspend" events for every resource
-  v.addEventListener("ended", checkEnded);
-  v.addEventListener("suspend", checkSuspended);
+  video.addEventListener("ended", checkEnded);
+  video.addEventListener("suspend", checkSuspended);
 
-  document.body.appendChild(v);
-  v.play();
+  document.body.appendChild(video);
+  video.play();
 }
 
 manager.runTests(gPlayTests, startTest);
 
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/test/test_playback_errors.html
+++ b/dom/media/test/test_playback_errors.html
@@ -8,41 +8,41 @@
 </head>
 <body>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 var manager = new MediaTestManager;
 
 function startTest(test, token) {
-  var v = document.createElement('video');
+  var video = document.createElement('video');
   manager.started(token);
-  v._errorCount = 0;
-  v._ignore = false;
+  video._errorCount = 0;
+  video._ignore = false;
   function endedTest(v) {
     if (v._ignore)
       return;
     v._ignore = true;
     v.remove();
     manager.finished(token);
   }
-  var checkError = function(test, v) { return function(evt) {
+  var checkError = function(t, v) { return function(evt) {
     v._errorCount++;
-    is(v._errorCount, 1, test.name + " only one error fired");
+    is(v._errorCount, 1, t.name + " only one error fired");
     endedTest(v);
-  }}(test, v);
-  var checkEnded = function(test, v) { return function() {
-    ok(false, test.name + " successfully played");
+  }}(test, video);
+  var checkEnded = function(t, v) { return function() {
+    ok(false, t.name + " successfully played");
     endedTest(v);
-  }}(test, v);
-  v.addEventListener("error", checkError);
-  v.addEventListener("ended", checkEnded);
-  v.src = test.name;
-  document.body.appendChild(v);
-  v.play();
+  }}(test, video);
+  video.addEventListener("error", checkError);
+  video.addEventListener("ended", checkEnded);
+  video.src = test.name;
+  document.body.appendChild(video);
+  video.play();
 }
 
 manager.runTests(gErrorTests, startTest);
 
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/test/test_playback_hls.html
+++ b/dom/media/test/test_playback_hls.html
@@ -8,84 +8,84 @@
 </head>
 <body>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 var manager = new MediaTestManager;
 
 function startTest(test, token) {
-  var v = document.createElement('video');
-  v.preload = "metadata";
-  v.token = token;
-  v.prevTime = 0;
-  v.seenEnded = false;
+  var video = document.createElement('video');
+  video.preload = "metadata";
+  video.token = token;
+  video.prevTime = 0;
+  video.seenEnded = false;
 
   var handler = {
     "ontimeout": function() {
-      Log(token, "timed out: ended=" + v.seenEnded);
+      Log(token, "timed out: ended=" + video.seenEnded);
     }
   };
   manager.started(token, handler);
 
-  v.src = test.name;
-  v.name = test.name;
+  video.src = test.name;
+  video.name = test.name;
 
-  var check = function(test, v) { return function() {
-    is(test.name, v.name, test.name + ": Name should match #1");
-    checkMetadata(test.name, v, test);
-  }}(test, v);
+  var check = function(t, v) { return function() {
+    is(t.name, v.name, t.name + ": Name should match #1");
+    checkMetadata(t.name, v, t);
+  }}(test, video);
 
-  var noLoad = function(test, v) { return function() {
-    ok(false, test.name + " should not fire 'load' event");
-  }}(test, v);
+  var noLoad = function(t, v) { return function() {
+    ok(false, t.name + " should not fire 'load' event");
+  }}(test, video);
 
   var finish = function() {
-    v.finished = true;
-    v.removeEventListener("timeupdate", timeUpdate);
-    removeNodeAndSource(v);
-    manager.finished(v.token);
+    video.finished = true;
+    video.removeEventListener("timeupdate", timeUpdate);
+    removeNodeAndSource(video);
+    manager.finished(video.token);
   }
 
   // We should get "ended" events to finish the test.
   var mayFinish = function() {
-    if (v.seenEnded) {
+    if (video.seenEnded) {
       finish();
     }
   }
 
-  var checkEnded = function(test, v) { return function() {
-    is(test.name, v.name, test.name + ": Name should match #2");
-    checkMetadata(test.name, v, test);
-    is(v.readyState, v.HAVE_CURRENT_DATA, test.name + " checking readyState");
-    ok(v.ended, test.name + " checking playback has ended");
-    ok(!v.finished, test.name + " shouldn't be finished");
-    ok(!v.seenEnded, test.name + " shouldn't be ended");
+  var checkEnded = function(t, v) { return function() {
+    is(t.name, v.name, t.name + ": Name should match #2");
+    checkMetadata(t.name, v, test);
+    is(v.readyState, v.HAVE_CURRENT_DATA, t.name + " checking readyState");
+    ok(v.ended, t.name + " checking playback has ended");
+    ok(!v.finished, t.name + " shouldn't be finished");
+    ok(!v.seenEnded, t.name + " shouldn't be ended");
 
     v.seenEnded = true;
     mayFinish();
-  }}(test, v);
+  }}(test, video);
 
-  var timeUpdate = function(test, v) { return function() {
+  var timeUpdate = function(t, v) { return function() {
     if (v.prevTime > v.currentTime) {
-      ok(false, test.name + " time should run forwards: p=" +
+      ok(false, t.name + " time should run forwards: p=" +
                 v.prevTime + " c=" + v.currentTime);
     }
     v.prevTime = v.currentTime;
-  }}(test, v);
+  }}(test, video);
 
-  v.addEventListener("load", noLoad);
-  v.addEventListener("loadedmetadata", check);
-  v.addEventListener("timeupdate", timeUpdate);
+  video.addEventListener("load", noLoad);
+  video.addEventListener("loadedmetadata", check);
+  video.addEventListener("timeupdate", timeUpdate);
 
   // We should get "ended" events for the hls resource
-  v.addEventListener("ended", checkEnded);
+  video.addEventListener("ended", checkEnded);
 
-  document.body.appendChild(v);
-  v.play();
+  document.body.appendChild(video);
+  video.play();
 }
 
 manager.runTests(gHLSTests, startTest);
 
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/test/test_playback_reactivate.html
+++ b/dom/media/test/test_playback_reactivate.html
@@ -15,63 +15,63 @@
    When the metadata is loaded, we remove the video element to trigger dormant.
    Then set a timer to append the video element back and play it.
    Test pass if the video plays to the end.
 */
 
 var manager = new MediaTestManager;
 
 function startTest(test, token) {
-  var v = document.createElement('video');
-  v.preload = "metadata";
-  v.token = token;
+  var video = document.createElement('video');
+  video.preload = "metadata";
+  video.token = token;
 
   var handler = {
     "ontimeout": function() {
-      Log(token, "timed out: ended=" + v.seenEnded + ", suspend=" + v.seenSuspend);
+      Log(token, "timed out: ended=" + video.seenEnded + ", suspend=" + video.seenSuspend);
     }
   };
   manager.started(token, handler);
 
-  v.src = test.name;
-  v.name = test.name;
+  video.src = test.name;
+  video.name = test.name;
 
-  var check = function(test, v) { return function() {
-    is(test.name, v.name, test.name + ": Name should match #1");
+  var check = function(t, v) { return function() {
+    is(t.name, v.name, t.name + ": Name should match #1");
     Log(v.token, "removeChild: " + v.name);
     document.body.removeChild(v);
     var appendAndPlayElement = function() {
       Log(v.token, "appendChild: " + v.name);
       document.body.appendChild(v);
       Log(v.token, "Element play: " + v.name);
       v.play();
     }
     setTimeout(appendAndPlayElement, 2000);
-  }}(test, v);
+  }}(test, video);
 
   var finish = function() {
-    v.finished = true;
-    removeNodeAndSource(v);
-    manager.finished(v.token);
+    video.finished = true;
+    removeNodeAndSource(video);
+    manager.finished(video.token);
   }
 
-  var checkEnded = function(test, v) { return function() {
-    is(test.name, v.name, test.name + ": Name should match #2");
-    checkMetadata(test.name, v, test);
-    is(v.readyState, v.HAVE_CURRENT_DATA, test.name + " checking readyState");
-    ok(v.ended, test.name + " checking playback has ended");
+  var checkEnded = function(t, v) { return function() {
+    is(t.name, v.name, t.name + ": Name should match #2");
+    checkMetadata(t.name, v, t);
+    is(v.readyState, v.HAVE_CURRENT_DATA, t.name + " checking readyState");
+    ok(v.ended, t.name + " checking playback has ended");
 
     finish();
-  }}(test, v);
+  }}(test, video);
 
 
-  v.addEventListener("loadedmetadata", check);
-  v.addEventListener("ended", checkEnded);
+  video.addEventListener("loadedmetadata", check);
+  video.addEventListener("ended", checkEnded);
 
-  document.body.appendChild(v);
+  document.body.appendChild(video);
 }
 
 manager.runTests(gSmallTests, startTest);
 
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/test/test_played.html
+++ b/dom/media/test/test_played.html
@@ -27,37 +27,37 @@ function check_full_file_played(element)
     is(element.played.end(0), e.target.duration, element.token + ": end time shall be duration");
     finish_test(e.target);
   }));
 }
 
 var tests = [
 // Without playing, check that player.played.length == 0.
 {
-  setup : function(element) {
+  setup(element) {
     element.addEventListener("loadedmetadata", function() {
       is(element.played.length, 0, element.token + ": initial played.length equals zero");
       finish_test(element);
     });
   },
   name: "test1"
 },
 // Play the file, test the range we have.
 {
-  setup : function(element) {
+  setup(element) {
     check_full_file_played(element);
     element.play();
   },
   name: "test2"
 },
 
 // Play the second half of the file, pause, play
 // an check we have only one range.
 {
-  setup : function (element) {
+  setup (element) {
     element.onended = function (e) {
       var t = e.target;
       t.onended = null;
       check_full_file_played(t);
       t.pause();
       t.currentTime = 0;
       t.play();
     };
@@ -67,17 +67,17 @@ var tests = [
     });
   },
   name: "test3"
 },
 
 // Play the first half of the file, seek back, while
 // continuing to play. We shall have only one range.
 {
-  setup : function (element) {
+  setup (element) {
     let onTimeUpdate = function() {
       if (element.currentTime > element.duration / 2) {
         info(element.token + ": currentTime=" + element.currentTime + ", duration=" + element.duration);
         element.removeEventListener("timeupdate", onTimeUpdate);
         element.pause();
         var oldEndRange = element.played.end(0);
         element.currentTime = element.duration / 4;
         is(element.played.end(0), oldEndRange,
@@ -90,17 +90,17 @@ var tests = [
     element.play();
   },
   name: "test4"
 },
 
 // Play and seek to have two ranges, and check that, as well a
 // boundaries.
 {
-  setup : function (element) {
+  setup (element) {
     let seekTarget = 0;
     let onTimeUpdate = function() {
       if (element.currentTime > element.duration / 2) {
         info(element.token + ": currentTime=" + element.currentTime + ", duration=" + element.duration);
         element.removeEventListener("timeupdate", onTimeUpdate);
         element.pause();
         // Remember seek target for later comparison since duration may change
         // during playback.
@@ -127,17 +127,17 @@ var tests = [
 
     element.play();
   },
   name: "test5"
 },
 
 // Play to create two ranges, in the reverse order. check that they are sorted.
 {
-  setup : function (element) {
+  setup (element) {
     function end() {
       element.pause();
       let p = element.played;
       ok(p.length >= 1, element.token + ": There should be at least one range=" + p.length);
       is(p.start(0), seekTarget, element.token + ": Start of first range should be the sixth of the duration");
       ok(p.end(p.length - 1) > 5 * element.duration / 6, element.token + ": End of last range should be greater that five times the sixth of the duration");
       finish_test(element);
     }
@@ -173,17 +173,17 @@ var tests = [
       element.currentTime = 4 * element.duration / 6;
       element.play();
     });
   },
   name: "test6"
 },
 // Seek repeatedly without playing. No range should appear.
 {
-  setup : function(element) {
+  setup(element) {
     let index = 1;
 
     element.addEventListener('seeked', function() {
       index++;
       element.currentTime = index * element.duration / 5;
       is(element.played.length, 0, element.token + ": played.length should be 0");
       if (index == 5) {
         finish_test(element);
@@ -197,17 +197,17 @@ var tests = [
   name: "test7"
 }
 ];
 
 function createTestArray() {
   var A = [];
   for (var i=0; i<tests.length; i++) {
     for (var k=0; k<gPlayedTests.length; k++) {
-      var t = new Object();
+      var t = {};
       t.setup = tests[i].setup;
       t.name = tests[i].name + "-" + gPlayedTests[k].name;
       t.type = gPlayedTests[k].type;
       t.src = gPlayedTests[k].name;
       A.push(t);
     }
   }
   return A;
--- a/dom/media/test/test_preload_actions.html
+++ b/dom/media/test/test_preload_actions.html
@@ -8,17 +8,17 @@ https://bugzilla.mozilla.org/show_bug.cg
   <script src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
   <script type="text/javascript" src="manifest.js"></script>
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=548523">Mozilla Bug 548523</a>
 <p id="display"></p>
 <div id="content" style="display: none">
-  
+
 </div>
 <!-- <button onClick="SimpleTest.finish();">Finish</button> -->
 <div>Tests complete: <span id="log" style="font-size: small;"></span></div>
 <pre id="test">
 <script type="application/javascript">
 
 /** Test for Bug 548523 **/
 
@@ -36,16 +36,17 @@ var bogusSrc = "bogus.duh";
 var bogusType = "video/bogus";
 var gotLoadEvent = false;
 var finished = false;
 
 addLoadEvent(function() {gotLoadEvent=true;});
 
 function log(m) {
   var l = document.getElementById("log");
+  // eslint-disable-next-line no-unsanitized/property
   l.innerHTML += m;
 }
 
 function maybeFinish(v, n) {
   if (v._finished) {
     return;
   }
   v._finished = true;
@@ -60,119 +61,110 @@ function filename(uri) {
 
 // Every test must have a setup(v) function, and must call maybeFinish() when test is complete.
 var tests = [
   {
     // 1. Add preload:none video with src to document. Load should halt at NETWORK_IDLE and HAVE_NOTHING,
     // after receiving a suspend event. Should not receive loaded events until after we call load().
     // Note the suspend event is explictly sent by our "stop the load" code, but other tests can't rely
     // on it for the preload:metadata case, as there can be multiple suspend events when loading metadata.
-    suspend:
-    function(e) {
+    suspend(e) {
       var v = e.target;
       is(v._gotLoadStart, true, "(1) Must get loadstart.");
       is(v._gotLoadedMetaData, false, "(1) Must not get loadedmetadata.");
       is(v.readyState, v.HAVE_NOTHING, "(1) ReadyState must be HAVE_NOTHING");
       // bug 962949
       // is(v.networkState, v.NETWORK_IDLE, "(1) NetworkState must be NETWORK_IDLE");
       maybeFinish(v, 1);
     },
 
-    setup:
-    function(v) {
+    setup(v) {
       v._gotLoadStart = false;
       v._gotLoadedMetaData = false;
       v.preload = "none";
       v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;});
       v.addEventListener("loadstart", function(e){v._gotLoadStart = true;});
       v.addEventListener("suspend", this.suspend);
       v.src = test.name;
       document.body.appendChild(v); // Causes implicit load, which will be halted due to preload:none.
     },
 
     name: "test1",
   },
   {
     // 2. Add preload:metadata video with src to document. Should halt with NETWORK_IDLE, HAVE_CURRENT_DATA
     // after suspend event and after loadedmetadata.
-    loadeddata:
-    function(e) {
+    loadeddata(e) {
       var v = e.target;
       is(v._gotLoadStart, true, "(2) Must get loadstart.");
       is(v._gotLoadedMetaData, true, "(2) Must get loadedmetadata.");
       ok(v.readyState >= v.HAVE_CURRENT_DATA, "(2) ReadyState must be >= HAVE_CURRENT_DATA");
       // bug 962949
       // is(v.networkState, v.NETWORK_IDLE, "(2) NetworkState must be NETWORK_IDLE");
       maybeFinish(v, 2);
     },
 
-    setup:
-    function(v) {
+    setup(v) {
       v._gotLoadStart = false;
       v._gotLoadedMetaData = false;
       v.preload = "metadata";
       v.addEventListener("loadstart", function(e){v._gotLoadStart = true;});
       v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;});
       v.addEventListener("loadeddata", this.loadeddata);
       v.src = test.name;
       document.body.appendChild(v); // Causes implicit load, which will be halted after
                                      // metadata due to preload:metadata.
     },
 
     name: "test2",
   },
   {
     // 3. Add preload:auto to document. Should receive canplaythrough eventually.
-    canplaythrough:
-    function(e) {
+    canplaythrough(e) {
       var v = e.target;
       is(v._gotLoadStart, true, "(3) Must get loadstart.");
       is(v._gotLoadedMetaData, true, "(3) Must get loadedmetadata.");
       maybeFinish(v, 3);
     },
 
-    setup:
-    function(v) {
+    setup(v) {
       v._gotLoadStart = false;
       v._gotLoadedMetaData = false;
       v.preload = "auto";
       v.addEventListener("loadstart", function(e){v._gotLoadStart = true;});
       v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;});
       v.addEventListener("canplaythrough", this.canplaythrough);
       v.src = test.name; // Causes implicit load.
       document.body.appendChild(v);
     },
 
     name: "test3",
   },
   {
     // 4. Add preload:none video to document. Call play(), should load then play through.
-    suspend:
-    function(e) {
+    suspend(e) {
       var v = e.target;
       if (v._gotSuspend) {
         return; // We can receive multiple suspend events, like the one after download completes.
       }
       v._gotSuspend = true;
       is(v._gotLoadStart, true, "(4) Must get loadstart.");
       is(v._gotLoadedMetaData, false, "(4) Must not get loadedmetadata.");
       is(v.readyState, v.HAVE_NOTHING, "(4) ReadyState must be HAVE_NOTHING");
       // bug 962949
       // is(v.networkState, v.NETWORK_IDLE, "(4) NetworkState must be NETWORK_IDLE");
       v.play(); // Should load and play through.
     },
 
-    ended:
-    function(e) {
+    ended(e) {
       ok(true, "(4) Got playback ended");
       maybeFinish(e.target, 4);
     },
 
-    setup:
-    function(v) {
+    setup(v) {
       v._gotLoadStart = false;
       v._gotLoadedMetaData = false;
       v._gotSuspend = false;
       v.preload = "none";
       v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;});
       v.addEventListener("loadstart", function(e){v._gotLoadStart = true;});
       v.addEventListener("suspend", this.suspend);
       v.addEventListener("ended", this.ended);
@@ -180,57 +172,53 @@ var tests = [
       document.body.appendChild(v);
     },
 
     name: "test4",
   },
   {
     // 5. preload:none video without resource, add to document, will implicitly start a
     // preload:none load. Add a src, it shouldn't load.
-    suspend:
-    function(e) {
+    suspend(e) {
       var v = e.target;
       is(v._gotLoadStart, true, "(5) Must get loadstart.");
       is(v._gotLoadedMetaData, false, "(5) Must not get loadedmetadata.");
       is(v.readyState, v.HAVE_NOTHING, "(5) ReadyState must be HAVE_NOTHING");
       // bug 962949
       // is(v.networkState, v.NETWORK_IDLE, "(5) NetworkState must be NETWORK_IDLE");
       maybeFinish(v, 5);
     },
 
-    setup:
-    function(v) {
+    setup(v) {
       v._gotLoadStart = false;
       v._gotLoadedMetaData = false;
       v.preload = "none";
       v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;});
       v.addEventListener("loadstart", function(e){v._gotLoadStart = true;});
       v.addEventListener("suspend", this.suspend);
       document.body.appendChild(v); // Causes implicit load, which will be halted due to no resource.
       v.src = test.name; // Load should start, and halt at preload:none.
     },
 
     name: "test5",
   },
   {
     // 6. preload:none video without resource, add to document, will implicitly start a
     // preload:none load. Add a source, it shouldn't load.
-    suspend:
-    function(e) {
+    suspend(e) {
       var v = e.target;
       is(v._gotLoadStart, true, "(6) Must get loadstart.");
       is(v._gotLoadedMetaData, false, "(6) Must not get loadedmetadata.");
       is(v.readyState, v.HAVE_NOTHING, "(6) ReadyState must be HAVE_NOTHING");
       // bug 962949
       // is(v.networkState, v.NETWORK_IDLE, "(6) NetworkState must be NETWORK_IDLE");
       maybeFinish(v, 6);
     },
 
-    setup:
-    function(v) {
+    setup(v) {
       v._gotLoadStart = false;
       v._gotLoadedMetaData = false;
       v.preload = "none";
       v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;});
       v.addEventListener("loadstart", function(e){v._gotLoadStart = true;});
       v.addEventListener("suspend", this.suspend);
       document.body.appendChild(v); // Causes implicit load, which will be halted due to no resource.
       var s = document.createElement("source");
@@ -239,40 +227,37 @@ var tests = [
       v.appendChild(s); // Load should start, and halt at preload:none.
     },
 
     name: "test6",
   },
   {
     // 7. create a preload:none document with multiple sources, the first of which is invalid.
     // Add to document, then play. It should load and play through the second source.
-    suspend:
-    function(e) {
+    suspend(e) {
       var v = e.target;
-      if (v._gotSuspend) 
+      if (v._gotSuspend)
         return; // We can receive multiple suspend events, like the one after download completes.
       v._gotSuspend = true;
       is(v._gotLoadStart, true, "(7) Must get loadstart.");
       is(v._gotLoadedMetaData, false, "(7) Must not get loadedmetadata.");
       is(v.readyState, v.HAVE_NOTHING, "(7) ReadyState must be HAVE_NOTHING");
       // bug 962949
       // is(v.networkState, v.NETWORK_IDLE, "(7) NetworkState must be NETWORK_IDLE");
       v.play(); // Should load and play through.
     },
 
-    ended:
-    function(e) {
+    ended(e) {
       ok(true, "(7) Got playback ended");
       var v = e.target;
-      is(v._gotErrorEvent, true, "(7) Should get error event from first source load failure");      
+      is(v._gotErrorEvent, true, "(7) Should get error event from first source load failure");
       maybeFinish(v, 7);
     },
 
-    setup:
-    function(v) {
+    setup(v) {
       v._gotLoadStart = false;
       v._gotLoadedMetaData = false;
       v.preload = "none";
       v._gotErrorEvent = false;
       v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;});
       v.addEventListener("loadstart", function(e){v._gotLoadStart = true;});
       v.addEventListener("suspend", this.suspend);
       v.addEventListener("ended", this.ended);
@@ -287,28 +272,26 @@ var tests = [
       v.appendChild(s2);
       document.body.appendChild(v); // Causes implicit load, which will be halt at preload:none on the second resource.
     },
 
     name: "test7",
   },
   {
     // 8. Change preload value from none to metadata should cause metadata to be loaded.
-    loadeddata:
-    function(e) {
+    loadeddata(e) {
       var v = e.target;
       is(v._gotLoadedMetaData, true, "(8) Must get loadedmetadata.");
       ok(v.readyState >= v.HAVE_CURRENT_DATA, "(8) ReadyState must be >= HAVE_CURRENT_DATA on suspend.");
       // bug 962949
       // is(v.networkState, v.NETWORK_IDLE, "(8) NetworkState must be NETWORK_IDLE when load is halted");
       maybeFinish(v, 8);
     },
 
-    setup:
-    function(v) {
+    setup(v) {
       v._gotLoadedMetaData = false;
       v.preload = "none";
       v.addEventListener("loadstart", function(e){v.preload = "metadata";});
       v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;});
       v.addEventListener("loadeddata", this.loadeddata);
       v.src = test.name; // Causes implicit load.
       document.body.appendChild(v);
     },
@@ -337,229 +320,210 @@ var tests = [
       v.addEventListener("loadeddata", function(){v.preload = "auto"}, false);
       v.addEventListener("canplaythrough", this.canplaythrough, false);
       v.src = test.name; // Causes implicit load.
       document.body.appendChild(v);
     },
   },*/
   {
     // 10. Change preload value from none to auto should cause entire media to be loaded.
-    canplaythrough:
-    function(e) {
+    canplaythrough(e) {
       var v = e.target;
       is(v._gotLoadedMetaData, true, "(10) Must get loadedmetadata.");
       maybeFinish(v, 10);
     },
 
-    setup:
-    function(v) {
+    setup(v) {
       v._gotLoadedMetaData = false;
       v.preload = "none";
       v.addEventListener("loadstart", function(e){v.preload = "auto";});
       v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;});
       v.addEventListener("canplaythrough", this.canplaythrough);
       v.src = test.name; // Causes implicit load.
       document.body.appendChild(v);
     },
 
     name: "test10",
   },
   {
     // 11. Change preload value from none to metadata should cause metadata to load.
-    loadeddata:
-    function(e) {
+    loadeddata(e) {
       var v = e.target;
       is(v._gotLoadedMetaData, true, "(11) Must get loadedmetadata.");
       ok(v.readyState >= v.HAVE_CURRENT_DATA, "(11) ReadyState must be >= HAVE_CURRENT_DATA.");
       // bug 962949
       // is(v.networkState, v.NETWORK_IDLE, "(11) NetworkState must be NETWORK_IDLE.");
       maybeFinish(v, 11);
     },
 
-    setup:
-    function(v) {
+    setup(v) {
       v._gotLoadedMetaData = false;
       v.preload = "none";
       v.addEventListener("loadstart", function(e){v.preload = "metadata";});
       v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;});
       v.addEventListener("loadeddata", this.loadeddata);
       v.src = test.name; // Causes implicit load.
       document.body.appendChild(v);
     },
 
     name: "test11",
   },
   {
     // 13. Change preload value from auto to none after specifying a src
     // should load according to preload none, no buffering should have taken place
-    suspend:
-    function(e) {
+    suspend(e) {
       var v = e.target;
       is(v._gotLoadStart, true, "(13) Must get loadstart.");
       is(v._gotLoadedMetaData, false, "(13) Must not get loadedmetadata.");
       is(v.readyState, v.HAVE_NOTHING, "(13) ReadyState must be HAVE_NOTHING");
       // bug 962949
       // is(v.networkState, v.NETWORK_IDLE, "(13) NetworkState must be NETWORK_IDLE");
       maybeFinish(v, 13);
     },
 
-    setup:
-    function(v) {
+    setup(v) {
       v._gotLoadStart = false;
       v._gotLoadedMetaData = false;
       v.preload = "auto";
       v.src = test.name;
       v.preload = "none";
       v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;});
       v.addEventListener("loadstart", function(e){v._gotLoadStart = true;});
       v.addEventListener("suspend", this.suspend);
       document.body.appendChild(v); // Causes implicit load, should load according to preload none
-      var s = document.createElement("source");
+      document.createElement("source");
     },
 
     name: "test13",
   },
   {
     // 14. Add preload:metadata video with src to document. Play(), should play through.
-    loadeddata:
-    function(e) {
+    loadeddata(e) {
       var v = e.target;
       is(v._gotLoadStart, true, "(14) Must get loadstart.");
       is(v._gotLoadedMetaData, true, "(14) Must get loadedmetadata.");
       ok(v.readyState >= v.HAVE_CURRENT_DATA, "(14) ReadyState must be >= HAVE_CURRENT_DATA");
       // bug 962949
       // is(v.networkState, v.NETWORK_IDLE, "(14) NetworkState must be NETWORK_IDLE");
       v.play();
     },
 
-    ended:
-    function(e) {
+    ended(e) {
       ok(true, "(14) Got playback ended");
       var v = e.target;
       maybeFinish(v, 14);
     },
 
-    setup:
-    function(v) {
+    setup(v) {
       v._gotLoadStart = false;
       v._gotLoadedMetaData = false;
       v.preload = "metadata";
       v.addEventListener("loadstart", function(e){v._gotLoadStart = true;});
       v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;});
       v.addEventListener("ended", this.ended);
       v.addEventListener("loadeddata", this.loadeddata);
       v.src = test.name;
       document.body.appendChild(v); // Causes implicit load, which will be halted after
                                      // metadata due to preload:metadata.
     },
 
     name: "test14",
   },
   {
     // 15. Autoplay should override preload:none.
-    ended:
-    function(e) {
+    ended(e) {
       ok(true, "(15) Got playback ended.");
       var v = e.target;
       maybeFinish(v, 15);
     },
 
-    setup:
-    function(v) {
+    setup(v) {
       v._gotLoadStart = false;
       v._gotLoadedMetaData = false;
       v.preload = "none";
       v.autoplay = true;
       v.addEventListener("loadstart", function(e){v._gotLoadStart = true;});
       v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;});
       v.addEventListener("ended", this.ended);
       v.src = test.name; // Causes implicit load.
       document.body.appendChild(v);
 
       // Log events for debugging.
       var events = ["suspend", "play", "canplay", "canplaythrough", "loadstart", "loadedmetadata",
                     "loadeddata", "playing", "ended", "error", "stalled", "emptied", "abort",
                     "waiting", "pause"];
       function logEvent(e) {
-        var v = e.target;
         info(e.target.token + ": got " + e.type);
       }
       events.forEach(function(e) {
         v.addEventListener(e, logEvent);
       });
     },
 
     name: "test15",
   },
   {
     // 16. Autoplay should override preload:metadata.
-    ended:
-    function(e) {
+    ended(e) {
       ok(true, "(16) Got playback ended.");
       var v = e.target;
       maybeFinish(v, 16);
     },
 
-    setup:
-    function(v) {
+    setup(v) {
       v.preload = "metadata";
       v.autoplay = true;
       v.addEventListener("ended", this.ended);
       v.src = test.name; // Causes implicit load.
       document.body.appendChild(v);
     },
 
     name: "test16",
   },
   {
     // 17. On a preload:none video, adding autoplay should disable preload none, i.e. don't break autoplay!
-    ended:
-    function(e) {
+    ended(e) {
       ok(true, "(17) Got playback ended.");
       var v = e.target;
       maybeFinish(v, 17);
     },
 
-    setup:
-    function(v) {
+    setup(v) {
       v.addEventListener("ended", this.ended);
       v.preload = "none";
       document.body.appendChild(v); // Causes implicit load, which will be halted due to preload:none.
       v.autoplay = true;
       v.src = test.name;
     },
 
     name: "test17",
   },
   {
     // 18. On a preload='none' video, call play() before load algorithms's sync
     // has run, the play() call should override preload='none'.
-    ended:
-    function(e) {
+    ended(e) {
       ok(true, "(18) Got playback ended.");
       var v = e.target;
       maybeFinish(v, 18);
     },
 
-    setup:
-    function(v) {
+    setup(v) {
       v.addEventListener("ended", this.ended);
       v.preload = "none";
       v.src = test.name; // Schedules async section to continue load algorithm.
       document.body.appendChild(v);
       v.play(); // Should cause preload:none to be overridden.
     },
 
     name: "test18",
   },
   {
     // 19. Set preload='auto' on first video source then switching preload='none' and swapping the video source to another.
     // The second video should not start playing as it's preload state has been changed to 'none' from 'auto'
-    setup:
-    function(v) {
+    setup(v) {
       v.preload = "auto";
       v.src = test.name;
       // add a listener for when the video has loaded, so we know preload auto has worked
       v.onloadedmetadata = function() {
         is(v.preload, "auto", "(19) preload is initially auto");
         // set preload state to none and switch video sources
         v.preload="none";
         v.src = test.name + "?asdf";
@@ -586,28 +550,28 @@ var tests = [
       document.body.appendChild(v);
     },
 
     name: "test19",
   }
 ];
 
 var iterationCount = 0;
-function startTest(test, token) {
-  if (test == tests[0]) {
+function startTest(t, token) {
+  if (t == tests[0]) {
     ++iterationCount;
     info("iterationCount=" + iterationCount);
   }
   if (iterationCount == 2) {
     // Do this series of tests on logically different resources
-    test.name = baseName + "?" + Math.floor(Math.random()*100000);
+    t.name = baseName + "?" + Math.floor(Math.random()*100000);
   }
   var v = document.createElement("video");
   v.token = token;
-  test.setup(v);
+  t.setup(v);
   manager.started(token);
 }
 
 var twiceTests = tests.concat(tests);
 SimpleTest.waitForExplicitFinish();
 SpecialPowers.pushPrefEnv({"set": [["media.cache_size", 40000]]}, beginTest);
 function beginTest() {
   manager.runTests(twiceTests, startTest);
--- a/dom/media/test/test_preload_suspend.html
+++ b/dom/media/test/test_preload_suspend.html
@@ -24,17 +24,17 @@ function checkSuspendCount(evt) {
   }
 }
 
 var tests = [
   {
     name: 'v1',
     preload: 'none',
     expectedSuspendCount: 2,
-    onsuspend: function(evt) {
+    onsuspend(evt) {
       checkSuspendCount(evt);
       if (evt.target.suspendCount == 1) {
         evt.target.preload = 'auto';
       }
     }
   },
   {
     name: 'v2',
@@ -48,17 +48,17 @@ var tests = [
     autoplay: true,
     expectedSuspendCount: 1,
     onsuspend: checkSuspendCount
   },
   {
     name: 'v4',
     preload: 'none',
     expectedSuspendCount: 2,
-    onsuspend: function(evt) {
+    onsuspend(evt) {
       checkSuspendCount(evt);
       if (evt.target.suspendCount == 1) {
         evt.target.play();
       }
     }
   },
   // disable v5 since media element doesn't support 'load' event anymore.
   /*{
@@ -71,17 +71,17 @@ var tests = [
         evt.target.currentTime = 0.1;
       }
     }
   },*/
   {
     name: 'v6',
     preload: 'none',
     expectedSuspendCount: 2,
-    onsuspend: function(evt) {
+    onsuspend(evt) {
       checkSuspendCount(evt);
       if (evt.target.suspendCount == 1) {
         evt.target.autoplay = true;
       }
     }
   }
 ];
 
--- a/dom/media/test/test_reset_events_async.html
+++ b/dom/media/test/test_reset_events_async.html
@@ -15,40 +15,40 @@ https://bugzilla.mozilla.org/show_bug.cg
   // Test that 'emptied' and 'abort' events are fired asynchronously when re-starting