Merge inbound to mozilla-central. a=merge
authorCiure Andrei <aciure@mozilla.com>
Thu, 08 Feb 2018 00:05:57 +0200
changeset 402821 8cc2427a322caa1e2c09ca3957335f88e573dc7a
parent 402820 fc3d9de1f56c35341db3d903dbbd0be5931ca343 (current diff)
parent 402743 3e3cfa85d219e7d166f268474c1e38780e38be85 (diff)
child 402822 5ceb1098fef34d35a79e25a495949c61dfa34e61
child 402906 d00497dcbe240a47619d8ee17c765cdb9af4d1dd
child 402911 090f99a013a26e337a717c088da9e52aaad4116c
push id99659
push useraciure@mozilla.com
push dateWed, 07 Feb 2018 22:33:57 +0000
treeherdermozilla-inbound@5ceb1098fef3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone60.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to mozilla-central. a=merge
dom/svg/crashtests/367357-1.xhtml
dom/svg/crashtests/369249-1.svg
dom/svg/crashtests/372046-1.svg
dom/svg/crashtests/372046-2.svg
dom/svg/crashtests/435209-1.svg
dom/svg/test/test_SVGPathSegList.xhtml
dom/svg/test/test_pathLength.html
dom/svg/test/test_pathSeg.xhtml
layout/reftests/svg/path-03.svg
layout/svg/crashtests/327709-1.svg
--- a/accessible/tests/mochitest/elm/test_HTMLSpec.html
+++ b/accessible/tests/mochitest/elm/test_HTMLSpec.html
@@ -1505,20 +1505,21 @@
   <embed id="embed_plugin_windowed" type="application/x-test" wmode="window"
          width="300" height="300"></embed>
 
   <fieldset id="fieldset">
     <legend id="legend">legend</legend>
     <input />
   </fieldset>
 
-  <figure id="figure">
-    <img src="../moz.png" alt="An awesome picture">
-    <figcaption id="figcaption">Caption for the awesome picture</figcaption>
-  </figure>
+  <!-- Depending on whether or not the image is cached, layout may be able to
+       optimize away spaces between the figure, img and figcaption tags. As
+       such, we should keep everything on one line to get consistent results.
+  -->
+  <figure id="figure"><img src="../moz.png" alt="An awesome picture"><figcaption id="figcaption">Caption for the awesome picture</figcaption></figure>
 
   <footer id="footer">Some copyright info</footer>
   <article>
     <footer id="footer_in_article">Some copyright info</footer>
   </article>
   <aside>
     <footer id="footer_in_aside">Some copyright info</footer>
   </aside>
--- a/accessible/tests/mochitest/name/markuprules.xml
+++ b/accessible/tests/mochitest/name/markuprules.xml
@@ -229,31 +229,43 @@
                   aria-labelledby="l1 l2"
                   value="name from value"
                   alt="no name from alt"
                   src="no name from src"
                   data="no name from data"
                   title="no name from title"/>
     </markup>
 
+    <!--
+      Disabled due to intermittent failures (bug 1436323) which became more
+      frequent due to the landing of bug 1383682. The latter bug made loading
+      of images from cache much more consistent, which appears to have impacted
+      the timing for this test case. If the image is switched to a unique
+      image (e.g. always decoding since there is no cache), the failure rate
+      increases, presumably because the test is dependent on a specific ordering
+      of events, and implicitly assumes the image is loaded immediately.
+    -->
+
+    <!--
     <markup id="HTMLInputImageTest"
             ref="html:input" ruleset="HTMLInputImage">
       <html:span id="l1" textequiv="test2">test2</html:span>
       <html:span id="l2" textequiv="test3">test3</html:span>
       <html:label for="btn-image" textequiv="test4">test4</html:label>
       <html:input id="btn-image"
                   type="image"
                   aria-label="test1"
                   aria-labelledby="l1 l2"
                   alt="name from alt"
                   value="name from value"
                   src="../moz.png"
                   data="no name from data"
                   title="name from title"/>
     </markup>
+    -->
 
     <markup id="HTMLInputImageNoValidSrcTest"
             ref="html:input" ruleset="HTMLInputImageNoValidSrc">
       <html:span id="l1" textequiv="test2">test2</html:span>
       <html:span id="l2" textequiv="test3">test3</html:span>
       <html:label for="btn-image" textequiv="test4">test4</html:label>
       <html:input id="btn-image"
                   type="image"
--- a/accessible/tests/mochitest/tree/test_txtcntr.html
+++ b/accessible/tests/mochitest/tree/test_txtcntr.html
@@ -222,12 +222,14 @@
   </div>
   <div id="c4" contentEditable="true">
     helllo <p>blabla</p> hello
   </div>
   <div id="c5"><blockquote>Hello</blockquote></div>
   <div id="c6">This <abbr title="accessibility">a11y</abbr> test</div>
   <div id="c7">This <acronym title="personal computer">PC</acronym> is broken</div>
 
-  <!-- only whitespace between images should be exposed -->
-  <div id="c8">   <img src="../moz.png">   <img src="../moz.png">   </div>
+  <!-- Whitespace between images should be exposed. Whitespace between the
+       div and img tags will be inconsistent depending on the image cache
+       state and what optimizations layout was able to apply. -->
+  <div id="c8"><img src="../moz.png">   <img src="../moz.png"></div>
 </body>
 </html>
--- a/accessible/tests/mochitest/treeupdate/test_whitespace.html
+++ b/accessible/tests/mochitest/treeupdate/test_whitespace.html
@@ -165,14 +165,17 @@
     Mozilla Bug 625652
   </a>
 
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
-  <div id="container1">  <img src="../moz.png">  <img id="img1" src="../moz.png">  <img src="../moz.png">  </div>
-  <div> <a id="container2"></a> <a><img src="../moz.png"></a> </div>
+  <!-- Whitespace between the div and img tags will be inconsistent depending
+       on the image cache state and what optimizations layout was able to
+       apply. -->
+  <div id="container1"><img src="../moz.png">  <img id="img1" src="../moz.png">  <img src="../moz.png"></div>
+  <div><a id="container2"></a> <a><img src="../moz.png"></a></div>
 
   <div id="eventdump"></div>
 </body>
 </html>
--- a/devtools/client/debugger/new/README.mozilla
+++ b/devtools/client/debugger/new/README.mozilla
@@ -1,13 +1,13 @@
 This is the debugger.html project output.
 See https://github.com/devtools-html/debugger.html
 
-Version 13.0
-Comparison: https://github.com/devtools-html/debugger.html/compare/release-12...release-13
-Commit: https://github.com/devtools-html/debugger.html/commit/3c10bd43b5
+Version 14.0
+Comparison: https://github.com/devtools-html/debugger.html/compare/release-13...release-14
+Commit: https://github.com/devtools-html/debugger.html/commit/5805cf467
 
 Packages:
 - babel-plugin-transform-es2015-modules-commonjs @6.26.0
 - babel-preset-react @6.24.1
 - react @15.6.2
 - react-dom @15.6.2
 - webpack @3.10.0
--- a/devtools/client/debugger/new/debugger.css
+++ b/devtools/client/debugger/new/debugger.css
@@ -951,17 +951,17 @@ menuseparator {
 .shortcut,
 .add-button {
   fill: var(--theme-splitter-color);
 }
 
 .file,
 .folder,
 .domain {
-  background-color: var(--theme-splitter-color);
+  background-color: var(--theme-comment);
 }
 
 .worker,
 .file,
 .folder {
   position: relative;
   top: 2px;
 }
@@ -1017,17 +1017,17 @@ img.file {
 
 img.arrow {
   mask: url("chrome://devtools/skin/images/debugger/arrow.svg");
   margin-inline-end: 5px;
   margin-top: 3px;
   width: 9px;
   height: 9px;
   padding-top: 9px;
-  background: var(--theme-splitter-color);
+  background: var(--disclosure-arrow);
   mask-size: 100%;
   display: inline-block;
   margin-bottom: 1px;
   transform: rotate(-90deg);
   transition: transform 0.18s ease;
 }
 
 html[dir="ltr"] img.arrow {
@@ -1062,17 +1062,18 @@ html .arrow.expanded svg {
   height: 10px;
   width: 15px;
 }
 
 .function path {
   fill: var(--theme-body-color);
 }
 
-.angular svg, .source-icon svg {
+.angular svg,
+.source-icon svg {
   width: 15px;
   height: 15px;
   margin-right: 5px;
   vertical-align: sub;
 }
 
 .source-icon svg {
   fill: var(--theme-body-color);
@@ -1090,16 +1091,21 @@ html .arrow.expanded svg {
   -moz-user-select: none;
   -ms-user-select: none;
   -o-user-select: none;
   user-select: none;
 
   white-space: nowrap;
   overflow: auto;
   min-width: 100%;
+
+  display: grid;
+  grid-template-columns: 1fr;
+  align-content: start;
+
 }
 
 .managed-tree .tree button {
   display: block;
 }
 
 .managed-tree .tree .node {
   padding: 2px 3px 2px 3px;
@@ -1228,17 +1234,17 @@ html[dir="rtl"] .arrow svg,
   flex-direction: row;
   justify-content: center;
   align-items: center;
 }
 
 .close-btn .close {
   mask: url("chrome://devtools/skin/images/debugger/close.svg") no-repeat;
   mask-size: 100%;
-  background-color: var(--theme-comment-alt);
+  background-color: var(--theme-comment);
   width: 8px;
   height: 8px;
   transition: all 0.15s ease-in-out;
   padding: 0;
   margin-top: 0;
 }
 
 .close-btn:hover img.close {
@@ -1312,21 +1318,21 @@ html[dir="rtl"] .arrow svg,
 .search-field.big i.magnifying-glass,
 .search-field.big i.sad-face {
   padding: 14px;
   width: 40px;
 }
 
 .search-field .magnifying-glass path,
 .search-field .magnifying-glass ellipse {
-  stroke: var(--theme-splitter-color);
+  stroke: var(--theme-comment);
 }
 
 .search-field input::placeholder {
-  color: var(--theme-body-color-inactive);
+  color: var(--theme-toolbar-color);
 }
 
 .search-field input:focus {
   outline-width: 0;
 }
 
 .search-field input.empty {
   color: var(--theme-highlight-orange);
@@ -1394,16 +1400,17 @@ html[dir="rtl"] .arrow svg,
 }
 
 .project-text-search .result {
   display: flex;
   cursor: default;
   padding: 4px 0 4px 30px;
   line-height: 16px;
   font-size: 10px;
+  width: 100%;
 }
 
 .project-text-search .matches-summary {
   margin-left: 5px;
 }
 
 .project-text-search .result {
   font-family: Menlo, monospace;
@@ -1509,37 +1516,32 @@ html[dir="rtl"] .arrow svg,
 .sources-list .managed-tree {
   flex: 1;
   display: flex;
   overflow-x: hidden;
   overflow-y: auto;
 }
 
 .sources-list .managed-tree .tree .node {
-  padding: 0px 0px 0px 3px;
-  height: 21px;
+  padding: 0 10px 0 3px;
   width: 100%;
 }
 
 .sources-list .tree img.arrow {
   margin-right: 5px;
 }
 
 .sources-list .tree .focused img.arrow {
   background-color: white;
 }
 
 .sources-list .tree img.arrow.expanded {
   transform: rotate(0deg);
 }
 
-.theme-dark .sources-list .tree .node:not(.focused) img.arrow {
-  background: var(--theme-content-color3);
-}
-
 .theme-dark .source-list .tree .node.focused {
   background-color: var(--theme-tab-toolbar-background);
 }
 
 .sources-list .tree .focused .label {
   background-color: var(--theme-selection-background);
 }
 
@@ -1664,17 +1666,17 @@ html[dir="rtl"] .arrow svg,
   text-align: center;
   padding: 0.5em;
   user-select: none;
   font-size: 12px;
 }
 
 .outline-list {
   list-style-type: none;
-  width: 100%;
+  flex: 1 0 100%;
   padding: 10px 0px;
   margin: 0;
 }
 
 .outline-list__class-list {
   list-style: none;
   margin: 0;
   padding: 0;
@@ -1683,30 +1685,29 @@ html[dir="rtl"] .arrow svg,
 .outline-list h2 {
   font-weight: normal;
   font-size: 1em;
   margin: 10px 0 10px 10px;
   color: var(--theme-body-color);
 }
 
 .outline-list__element {
-  padding-bottom: 0.5rem;
-  padding-right: 0.5rem;
-  padding-top: 0.2rem;
+  padding: 3px 10px 3px 10px;
   cursor: default;
   white-space: nowrap;
 }
 
+.outline-list__element-icon {
+  padding-right: 0.4rem;
+  padding-left: 1rem;
+}
+
 .outline-list__element:hover {
   background: var(--theme-toolbar-background-hover);
 }
-
-.outline-list__element .function {
-  padding-left: 10px;
-}
 /* 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/>. */
 
 .function-signature {
   align-self: center;
 }
 
@@ -1960,17 +1961,17 @@ html .toggle-button.end.vertical svg {
   display: flex;
   justify-content: center;
   align-items: center;
   padding: 0;
   width: 16px;
 }
 
 .search-bottom-bar .search-modifiers button svg {
-  fill: var(--theme-comment-alt);
+  fill: var(--theme-comment);
   height: 16px;
   width: 16px;
 }
 
 .search-bottom-bar .search-modifiers button:hover {
   background: var(--theme-toolbar-background-hover);
 }
 
@@ -1992,17 +1993,17 @@ html .toggle-button.end.vertical svg {
   max-width: 68%;
 }
 
 .search-bottom-bar .search-type-name {
   padding: 1px 0 0 0;
   margin: 0 0 0 6px;
   border: none;
   background: transparent;
-  color: var(--theme-comment-alt);
+  color: var(--theme-comment);
 }
 
 .search-bottom-bar .search-type-toggles .search-type-btn:active {
   outline: none;
 }
 
 .search-bottom-bar .search-type-toggles .search-type-btn.active {
   color: var(--theme-selection-background);
@@ -2984,18 +2985,17 @@ html .breakpoints-list .breakpoint.pause
 .input-expression.error {
   border: 1px solid red;
   animation: 150ms cubic-bezier(0.07, 0.95, 0, 1) shake;
 }
 
 .input-expression::placeholder {
   text-align: center;
   font-style: italic;
-  color: var(--theme-comment-alt);
-  opacity: 1;
+  color: var(--theme-comment);
 }
 
 .input-expression:focus {
   outline: none;
   cursor: text;
 }
 
 .expressions-list {
@@ -3304,20 +3304,22 @@ html .breakpoints-list .breakpoint.pause
   background-color: var(--search-overlays-semitransparent);
 }
 /* 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/>. */
 
 :root {
   --accordion-header-background: var(--theme-toolbar-background);
+  --disclosure-arrow: #b2b2b2;
 }
 
 :root.theme-dark {
   --accordion-header-background: #222225;
+  --disclosure-arrow: #7f7f81;
 }
 
 .accordion {
   background-color: var(--theme-sidebar-background);
   width: 100%;
 }
 
 .accordion ._header {
@@ -3378,16 +3380,20 @@ html .breakpoints-list .breakpoint.pause
   padding: 0;
   width: 16px;
   height: 16px;
 }
 
 .accordion .header-buttons button::-moz-focus-inner {
   border: none;
 }
+
+.accordion .arrow svg {
+  fill: var(--disclosure-arrow);
+}
 /* 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/>. */
 
 .command-bar {
   flex: 0 0 30px;
   border-bottom: 1px solid var(--theme-splitter-color);
   display: flex;
@@ -3403,17 +3409,21 @@ html[dir="rtl"] .command-bar {
 .theme-dark .command-bar {
   background-color: var(--theme-toolbar-background);
 }
 
 img.pause,
 img.stepOver,
 img.stepIn,
 img.stepOut,
-img.resume {
+img.resume,
+img.rewind,
+img.reverseStepOver,
+img.reverseStepIn,
+img.reverseStepOut {
   background-color: var(--theme-body-color);
 }
 
 .command-bar img.pause {
   mask: url("chrome://devtools/skin/images/debugger/pause.svg") no-repeat;
 }
 
 .command-bar img.stepOver {
@@ -3427,16 +3437,36 @@ img.resume {
 .command-bar img.stepOut {
   mask: url("chrome://devtools/skin/images/debugger/stepOut.svg") no-repeat;
 }
 
 .command-bar img.resume {
   mask: url("chrome://devtools/skin/images/debugger/resume.svg") no-repeat;
 }
 
+.command-bar img.rewind {
+  mask: url("chrome://devtools/skin/images/debugger/resume.svg") no-repeat;
+  transform: scaleX(-1);
+}
+
+.command-bar img.reverseStepOver {
+  mask: url("chrome://devtools/skin/images/debugger/stepOver.svg") no-repeat;
+  transform: scaleX(-1);
+}
+
+.command-bar img.reverseStepIn {
+  mask: url("chrome://devtools/skin/images/debugger/stepIn.svg") no-repeat;
+  transform: scaleX(-1);
+}
+
+.command-bar img.reverseStepOut {
+  mask: url("chrome://devtools/skin/images/debugger/stepOut.svg") no-repeat;
+  transform: scaleX(-1);
+}
+
 .command-bar > .pause-exceptions.uncaught.enabled > img.pause-exceptions {
   background-color: var(--theme-highlight-purple);
 }
 
 .command-bar > .pause-exceptions.all.enabled > img.pause-exceptions {
   background-color: var(--theme-highlight-blue);
 }
 
@@ -3692,20 +3722,16 @@ img.ignore-exceptions {
   font-style: italic;
   text-align: center;
   padding: 0.5em;
   -moz-user-select: none;
   user-select: none;
   cursor: default;
 }
 
-.theme-dark .secondary-panes .accordion .arrow svg {
-  fill: var(--theme-content-color3);
-}
-
 .secondary-panes .breakpoints-buttons {
   display: flex;
 }
 
 .secondary-panes .accordion .plus svg {
   width: 12px;
   margin-top: 3px;
   fill: var(--theme-comment-alt);
@@ -3729,17 +3755,16 @@ img.ignore-exceptions {
   /* Offsetting it by 30px for the sources-header area */
   height: calc(100% - 30px);
   position: absolute;
   top: 30px;
   left: 0;
   padding: 50px 0 0 0;
   text-align: center;
   font-size: 1.25em;
-  color: var(--theme-comment-alt);
   background-color: var(--theme-toolbar-background);
   font-weight: lighter;
   z-index: 10;
   user-select: none;
 }
 
 .theme-dark .welcomebox {
   background-color: var(--theme-body-background);
@@ -3772,16 +3797,17 @@ img.ignore-exceptions {
   margin-right: 10px;
   font-family: Courier;
 }
 
 .shortcutFunction {
   text-align: left;
   float: left;
   margin-left: 25px;
+  color: var(--theme-comment);
 }
 
 html .welcomebox .toggle-button-end.collapsed {
   bottom: 1px;
 }
 
 @media (max-width: 430px) {
   .welcomebox .small-size-layout {
@@ -4028,20 +4054,21 @@ html .welcomebox .toggle-button-end.coll
 
 .search-bar .result-list {
   border-bottom: 1px solid var(--theme-splitter-color);
 }
 
 .theme-dark .result-list {
   background-color: var(--theme-body-background);
 }
-.result-item .title .fuzzy-match {
+.result-item .title .highlight {
   font-weight: bold;
 }
 
-.result-item .subtitle .fuzzy-match {
+.result-item .subtitle .highlight {
   color: var(--grey-90);
-}
-
-.theme-dark .result-item .title .fuzzy-match,
-.theme-dark .result-item .subtitle .fuzzy-match {
+  font-weight: 500;
+}
+
+.theme-dark .result-item .title .highlight,
+.theme-dark .result-item .subtitle .highlight {
   color: white;
 }
--- a/devtools/client/debugger/new/debugger.js
+++ b/devtools/client/debugger/new/debugger.js
@@ -10133,17 +10133,17 @@ if (isDevelopment()) {
   pref("devtools.debugger.prefs-schema-version", "1.0.1");
   pref("devtools.debugger.features.workers", true);
   pref("devtools.debugger.features.async-stepping", true);
   pref("devtools.debugger.features.wasm", true);
   pref("devtools.debugger.features.shortcuts", true);
   pref("devtools.debugger.features.root", true);
   pref("devtools.debugger.features.column-breakpoints", false);
   pref("devtools.debugger.features.chrome-scopes", false);
-  pref("devtools.debugger.features.map-scopes", false);
+  pref("devtools.debugger.features.map-scopes", true);
   pref("devtools.debugger.features.breakpoints-dropdown", true);
   pref("devtools.debugger.features.remove-command-bar-options", true);
   pref("devtools.debugger.features.code-coverage", false);
   pref("devtools.debugger.features.event-listeners", false);
   pref("devtools.debugger.features.code-folding", false);
   pref("devtools.debugger.features.outline", true);
   pref("devtools.debugger.features.column-breakpoints", true);
 }
@@ -13920,17 +13920,17 @@ module.exports = "<!-- This Source Code 
 /* 955 */,
 /* 956 */,
 /* 957 */,
 /* 958 */,
 /* 959 */,
 /* 960 */
 /***/ (function(module, exports) {
 
-module.exports = "# This Source Code Form is subject to the terms of the Mozilla Public\n# License, v. 2.0. If a copy of the MPL was not distributed with this\n# file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\n# LOCALIZATION NOTE These strings are used inside the Debugger\n# which is available from the Web Developer sub-menu -> 'Debugger'.\n# The correct localization of this file might be to keep it in\n# English, or another language commonly spoken among web developers.\n# You want to make that choice consistent across the developer tools.\n# A good criteria is the language in which you'd find the best\n# documentation on web development on the web.\n\n# LOCALIZATION NOTE (collapsePanes): This is the tooltip for the button\n# that collapses the left and right panes in the debugger UI.\ncollapsePanes=Collapse panes\n\n# LOCALIZATION NOTE (copySource): This is the text that appears in the\n# context menu to copy the selected source of file open.\ncopySource=Copy\ncopySource.accesskey=y\n\n# LOCALIZATION NOTE (copySourceUri2): This is the text that appears in the\n# context menu to copy the source URI of file open.\ncopySourceUri2=Copy source URI\ncopySourceUri2.accesskey=u\n\n# LOCALIZATION NOTE (setDirectoryRoot.label): This is the text that appears in the\n# context menu to set a directory as root directory\nsetDirectoryRoot.label=Set directory root\nsetDirectoryRoot.accesskey=r\n\n# LOCALIZATION NOTE (removeDirectoryRoot.label): This is the text that appears in the\n# context menu to remove a directory as root directory\nremoveDirectoryRoot.label=Remove directory root\nremoveDirectoryRoot.accesskey=d\n\n# LOCALIZATION NOTE (copyFunction.label): This is the text that appears in the\n# context menu to copy the function the user selected\ncopyFunction.label=Copy function\ncopyFunction.accesskey=F\n\n# LOCALIZATION NOTE (copyStackTrace): This is the text that appears in the\n# context menu to copy the stack trace methods, file names and row number.\ncopyStackTrace=Copy stack trace\ncopyStackTrace.accesskey=c\n\n# LOCALIZATION NOTE (expandPanes): This is the tooltip for the button\n# that expands the left and right panes in the debugger UI.\nexpandPanes=Expand panes\n\n# LOCALIZATION NOTE (pauseButtonTooltip): The tooltip that is displayed for the pause\n# button when the debugger is in a running state.\npauseButtonTooltip=Pause %S\n\n# LOCALIZATION NOTE (pausePendingButtonTooltip): The tooltip that is displayed for\n# the pause button after it's been clicked but before the next JavaScript to run.\npausePendingButtonTooltip=Waiting for next execution\n\n# LOCALIZATION NOTE (resumeButtonTooltip): The label that is displayed on the pause\n# button when the debugger is in a paused state.\nresumeButtonTooltip=Resume %S\n\n# LOCALIZATION NOTE (stepOverTooltip): The label that is displayed on the\n# button that steps over a function call.\nstepOverTooltip=Step over %S\n\n# LOCALIZATION NOTE (stepInTooltip): The label that is displayed on the\n# button that steps into a function call.\nstepInTooltip=Step in %S\n\n# LOCALIZATION NOTE (stepOutTooltip): The label that is displayed on the\n# button that steps out of a function call.\nstepOutTooltip=Step out %S\n\n# LOCALIZATION NOTE (pauseButtonItem): The label that is displayed for the dropdown pause\n# list item when the debugger is in a running state.\npauseButtonItem=Pause on Next Statement\n\n# LOCALIZATION NOTE (ignoreExceptionsItem): The pause on exceptions button description\n# when the debugger will not pause on exceptions.\nignoreExceptionsItem=Ignore exceptions\n\n# LOCALIZATION NOTE (pauseOnUncaughtExceptionsItem): The pause on exceptions dropdown\n# item shown when a user is adding a new breakpoint.\npauseOnUncaughtExceptionsItem=Pause on uncaught exceptions\n\n# LOCALIZATION NOTE (pauseOnExceptionsItem): The pause on exceptions button description\n# when the debugger will pause on all exceptions.\npauseOnExceptionsItem=Pause on all exceptions\n\n# LOCALIZATION NOTE (workersHeader): The text to display in the events\n# header.\nworkersHeader=Workers\n\n# LOCALIZATION NOTE (noWorkersText): The text to display in the workers list\n# when there are no workers.\nnoWorkersText=This page has no workers.\n\n# LOCALIZATION NOTE (noSourcesText): The text to display in the sources list\n# when there are no sources.\nnoSourcesText=This page has no sources.\n\n# LOCALIZATION NOTE (noEventListenersText): The text to display in the events tab\n# when there are no events.\nnoEventListenersText=No event listeners to display.\n\n# LOCALIZATION NOTE (eventListenersHeader): The text to display in the events\n# header.\neventListenersHeader=Event listeners\n\n# LOCALIZATION NOTE (noStackFramesText): The text to display in the call stack tab\n# when there are no stack frames.\nnoStackFramesText=No stack frames to display\n\n# LOCALIZATION NOTE (eventCheckboxTooltip): The tooltip text to display when\n# the user hovers over the checkbox used to toggle an event breakpoint.\neventCheckboxTooltip=Toggle breaking on this event\n\n# LOCALIZATION NOTE (eventOnSelector): The text to display in the events tab\n# for every event item, between the event type and event selector.\neventOnSelector=on\n\n# LOCALIZATION NOTE (eventInSource): The text to display in the events tab\n# for every event item, between the event selector and listener's owner source.\neventInSource=in\n\n# LOCALIZATION NOTE (eventNodes): The text to display in the events tab when\n# an event is listened on more than one target node.\neventNodes=%S nodes\n\n# LOCALIZATION NOTE (eventNative): The text to display in the events tab when\n# a listener is added from plugins, thus getting translated to native code.\neventNative=[native code]\n\n# LOCALIZATION NOTE (*Events): The text to display in the events tab for\n# each group of sub-level event entries.\nanimationEvents=Animation\naudioEvents=Audio\nbatteryEvents=Battery\nclipboardEvents=Clipboard\ncompositionEvents=Composition\ndeviceEvents=Device\ndisplayEvents=Display\ndragAndDropEvents=Drag and Drop\ngamepadEvents=Gamepad\nindexedDBEvents=IndexedDB\ninteractionEvents=Interaction\nkeyboardEvents=Keyboard\nmediaEvents=HTML5 Media\nmouseEvents=Mouse\nmutationEvents=Mutation\nnavigationEvents=Navigation\npointerLockEvents=Pointer Lock\nsensorEvents=Sensor\nstorageEvents=Storage\ntimeEvents=Time\ntouchEvents=Touch\notherEvents=Other\n\n# LOCALIZATION NOTE (blackboxCheckboxTooltip2): The tooltip text to display when\n# the user hovers over the checkbox used to toggle blackboxing its associated\n# source.\nblackboxCheckboxTooltip2=Toggle blackboxing\n\n# LOCALIZATION NOTE (sources.search.key2): Key shortcut to open the search for\n# searching all the source files the debugger has seen.\nsources.search.key2=CmdOrCtrl+P\n\n# LOCALIZATION NOTE (sources.search.alt.key): A second key shortcut to open the\n# search for searching all the source files the debugger has seen.\nsources.search.alt.key=CmdOrCtrl+O\n\n# LOCALIZATION NOTE (projectTextSearch.key): A key shortcut to open the\n# full project text search for searching all the files the debugger has seen.\nprojectTextSearch.key=CmdOrCtrl+Shift+F\n\n# LOCALIZATION NOTE (functionSearch.key): A key shortcut to open the\n# modal for searching functions in a file.\nfunctionSearch.key=CmdOrCtrl+Shift+O\n\n# LOCALIZATION NOTE (toggleBreakpoint.key): A key shortcut to toggle\n# breakpoints.\ntoggleBreakpoint.key=CmdOrCtrl+B\n\n# LOCALIZATION NOTE (toggleCondPanel.key): A key shortcut to toggle\n# the conditional breakpoint panel.\ntoggleCondPanel.key=CmdOrCtrl+Shift+B\n\n# LOCALIZATION NOTE (stepOut.key): A key shortcut to\n# step out.\nstepOut.key=Shift+F11\n\n# LOCALIZATION NOTE (shortcuts.header.editor): Sections header in\n# the shortcuts modal for keyboard shortcuts related to editing.\nshortcuts.header.editor=Editor\n\n# LOCALIZATION NOTE (shortcuts.header.stepping): Sections header in\n# the shortcuts modal for keyboard shortcuts related to stepping.\nshortcuts.header.stepping=Stepping\n\n# LOCALIZATION NOTE (shortcuts.header.search): Sections header in\n# the shortcuts modal for keyboard shortcuts related to search.\nshortcuts.header.search=Search\n\n# LOCALIZATION NOTE (projectTextSearch.placeholder): A placeholder shown\n# when searching across all of the files in a project.\nprojectTextSearch.placeholder=Find in files…\n\n# LOCALIZATION NOTE (projectTextSearch.noResults): The center pane Text Search\n# message when the query did not match any text of all files in a project.\nprojectTextSearch.noResults=No results found\n\n# LOCALIZATION NOTE (sources.noSourcesAvailable): Text shown when the debugger\n# does not have any sources.\nsources.noSourcesAvailable=This page has no sources\n\n# LOCALIZATION NOTE (sourceSearch.search.key2): Key shortcut to open the search\n# for searching within a the currently opened files in the editor\nsourceSearch.search.key2=CmdOrCtrl+F\n\n# LOCALIZATION NOTE (sourceSearch.search.placeholder): placeholder text in\n# the source search input bar\nsourceSearch.search.placeholder=Search in file…\n\n# LOCALIZATION NOTE (sourceSearch.search.again.key2): Key shortcut to highlight\n# the next occurrence of the last search triggered from a source search\nsourceSearch.search.again.key2=CmdOrCtrl+G\n\n# LOCALIZATION NOTE (sourceSearch.search.againPrev.key2): Key shortcut to highlight\n# the previous occurrence of the last search triggered from a source search\nsourceSearch.search.againPrev.key2=CmdOrCtrl+Shift+G\n\n# LOCALIZATION NOTE (sourceSearch.resultsSummary1): Shows a summary of\n# the number of matches for autocomplete\nsourceSearch.resultsSummary1=%d results\n\n# LOCALIZATION NOTE (noMatchingStringsText): The text to display in the\n# global search results when there are no matching strings after filtering.\nnoMatchingStringsText=No matches found\n\n# LOCALIZATION NOTE (emptySearchText): This is the text that appears in the\n# filter text box when it is empty and the scripts container is selected.\nemptySearchText=Search scripts (%S)\n\n# LOCALIZATION NOTE (emptyVariablesFilterText): This is the text that\n# appears in the filter text box for the variables view container.\nemptyVariablesFilterText=Filter variables\n\n# LOCALIZATION NOTE (emptyPropertiesFilterText): This is the text that\n# appears in the filter text box for the editor's variables view bubble.\nemptyPropertiesFilterText=Filter properties\n\n# LOCALIZATION NOTE (searchPanelFilter): This is the text that appears in the\n# filter panel popup for the filter scripts operation.\nsearchPanelFilter=Filter scripts (%S)\n\n# LOCALIZATION NOTE (searchPanelGlobal): This is the text that appears in the\n# filter panel popup for the global search operation.\nsearchPanelGlobal=Search in all files (%S)\n\n# LOCALIZATION NOTE (searchPanelFunction): This is the text that appears in the\n# filter panel popup for the function search operation.\nsearchPanelFunction=Search for function definition (%S)\n\n# LOCALIZATION NOTE (searchPanelToken): This is the text that appears in the\n# filter panel popup for the token search operation.\nsearchPanelToken=Find in this file (%S)\n\n# LOCALIZATION NOTE (searchPanelGoToLine): This is the text that appears in the\n# filter panel popup for the line search operation.\nsearchPanelGoToLine=Go to line (%S)\n\n# LOCALIZATION NOTE (searchPanelVariable): This is the text that appears in the\n# filter panel popup for the variables search operation.\nsearchPanelVariable=Filter variables (%S)\n\n# LOCALIZATION NOTE (breakpointMenuItem): The text for all the elements that\n# are displayed in the breakpoints menu item popup.\nbreakpointMenuItem.setConditional=Configure conditional breakpoint\nbreakpointMenuItem.enableSelf2.label=Enable\nbreakpointMenuItem.enableSelf2.accesskey=E\nbreakpointMenuItem.disableSelf2.label=Disable\nbreakpointMenuItem.disableSelf2.accesskey=D\nbreakpointMenuItem.deleteSelf2.label=Remove\nbreakpointMenuItem.deleteSelf2.accesskey=R\nbreakpointMenuItem.enableOthers2.label=Enable others\nbreakpointMenuItem.enableOthers2.accesskey=o\nbreakpointMenuItem.disableOthers2.label=Disable others\nbreakpointMenuItem.disableOthers2.accesskey=s\nbreakpointMenuItem.deleteOthers2.label=Remove others\nbreakpointMenuItem.deleteOthers2.accesskey=h\nbreakpointMenuItem.enableAll2.label=Enable all\nbreakpointMenuItem.enableAll2.accesskey=b\nbreakpointMenuItem.disableAll2.label=Disable all\nbreakpointMenuItem.disableAll2.accesskey=k\nbreakpointMenuItem.deleteAll2.label=Remove all\nbreakpointMenuItem.deleteAll2.accesskey=a\nbreakpointMenuItem.removeCondition2.label=Remove condition\nbreakpointMenuItem.removeCondition2.accesskey=c\nbreakpointMenuItem.addCondition2.label=Add condition\nbreakpointMenuItem.addCondition2.accesskey=A\nbreakpointMenuItem.editCondition2.label=Edit condition\nbreakpointMenuItem.editCondition2.accesskey=n\nbreakpointMenuItem.enableSelf=Enable breakpoint\nbreakpointMenuItem.enableSelf.accesskey=E\nbreakpointMenuItem.disableSelf=Disable breakpoint\nbreakpointMenuItem.disableSelf.accesskey=D\nbreakpointMenuItem.deleteSelf=Remove breakpoint\nbreakpointMenuItem.deleteSelf.accesskey=R\nbreakpointMenuItem.enableOthers=Enable others\nbreakpointMenuItem.enableOthers.accesskey=o\nbreakpointMenuItem.disableOthers=Disable others\nbreakpointMenuItem.disableOthers.accesskey=s\nbreakpointMenuItem.deleteOthers=Remove others\nbreakpointMenuItem.deleteOthers.accesskey=h\nbreakpointMenuItem.enableAll=Enable all breakpoints\nbreakpointMenuItem.enableAll.accesskey=b\nbreakpointMenuItem.disableAll=Disable all breakpoints\nbreakpointMenuItem.disableAll.accesskey=k\nbreakpointMenuItem.deleteAll=Remove all breakpoints\nbreakpointMenuItem.deleteAll.accesskey=a\nbreakpointMenuItem.removeCondition.label=Remove breakpoint condition\nbreakpointMenuItem.removeCondition.accesskey=c\nbreakpointMenuItem.editCondition.label=Edit breakpoint condition\nbreakpointMenuItem.editCondition.accesskey=n\n\n# LOCALIZATION NOTE (breakpoints.header): Breakpoints right sidebar pane header.\nbreakpoints.header=Breakpoints\n\n# LOCALIZATION NOTE (breakpoints.none): The text that appears when there are\n# no breakpoints present\nbreakpoints.none=No breakpoints\n\n# LOCALIZATION NOTE (breakpoints.enable): The text that may appear as a tooltip\n# when hovering over the 'disable breakpoints' switch button in right sidebar\nbreakpoints.enable=Enable breakpoints\n\n# LOCALIZATION NOTE (breakpoints.disable): The text that may appear as a tooltip\n# when hovering over the 'disable breakpoints' switch button in right sidebar\nbreakpoints.disable=Disable breakpoints\n\n# LOCALIZATION NOTE (breakpoints.removeBreakpointTooltip): The tooltip that is displayed\n# for remove breakpoint button in right sidebar\nbreakpoints.removeBreakpointTooltip=Remove breakpoint\n\n# LOCALIZATION NOTE (callStack.header): Call Stack right sidebar pane header.\ncallStack.header=Call stack\n\n# LOCALIZATION NOTE (callStack.notPaused): Call Stack right sidebar pane\n# message when not paused.\ncallStack.notPaused=Not paused\n\n# LOCALIZATION NOTE (callStack.collapse): Call Stack right sidebar pane\n# message to hide some of the frames that are shown.\ncallStack.collapse=Collapse rows\n\n# LOCALIZATION NOTE (callStack.expand): Call Stack right sidebar pane\n# message to show more of the frames.\ncallStack.expand=Expand rows\n\n# LOCALIZATION NOTE (editor.searchResults): Editor Search bar message\n# for the summarizing the selected search result. e.g. 5 of 10 results.\neditor.searchResults=%d of %d results\n\n# LOCALIZATION NOTE (editor.singleResult): Copy shown when there is one result.\neditor.singleResult=1 result\n\n# LOCALIZATION NOTE (editor.noResults): Editor Search bar message\n# for when no results found.\neditor.noResults=No results\n\n# LOCALIZATION NOTE (editor.searchResults.nextResult): Editor Search bar\n# tooltip for traversing to the Next Result\neditor.searchResults.nextResult=Next result\n\n# LOCALIZATION NOTE (editor.searchResults.prevResult): Editor Search bar\n# tooltip for traversing to the Previous Result\neditor.searchResults.prevResult=Previous result\n\n# LOCALIZATION NOTE (editor.searchTypeToggleTitle): Search bar title for\n# toggling search type buttons(function search, variable search)\neditor.searchTypeToggleTitle=Search for:\n\n# LOCALIZATION NOTE (editor.continueToHere.label): Editor gutter context\n# menu item for jumping to a new paused location\neditor.continueToHere.label=Continue to here\neditor.continueToHere.accesskey=H\n\n# LOCALIZATION NOTE (editor.addBreakpoint): Editor gutter context menu item\n# for adding a breakpoint on a line.\neditor.addBreakpoint=Add breakpoint\n\n# LOCALIZATION NOTE (editor.disableBreakpoint): Editor gutter context menu item\n# for disabling a breakpoint on a line.\neditor.disableBreakpoint=Disable breakpoint\neditor.disableBreakpoint.accesskey=D\n\n# LOCALIZATION NOTE (editor.enableBreakpoint): Editor gutter context menu item\n# for enabling a breakpoint on a line.\neditor.enableBreakpoint=Enable breakpoint\n\n# LOCALIZATION NOTE (editor.removeBreakpoint): Editor gutter context menu item\n# for removing a breakpoint on a line.\neditor.removeBreakpoint=Remove breakpoint\n\n# LOCALIZATION NOTE (editor.editBreakpoint): Editor gutter context menu item\n# for setting a breakpoint condition on a line.\neditor.editBreakpoint=Edit breakpoint\n\n# LOCALIZATION NOTE (editor.addConditionalBreakpoint): Editor gutter context\n# menu item for adding a breakpoint condition on a line.\neditor.addConditionalBreakpoint=Add conditional breakpoint\neditor.addConditionalBreakpoint.accesskey=c\n\n# LOCALIZATION NOTE (editor.conditionalPanel.placeholder): Placeholder text for\n# input element inside ConditionalPanel component\neditor.conditionalPanel.placeholder=This breakpoint will pause when the expression is true\n\n# LOCALIZATION NOTE (editor.conditionalPanel.close): Tooltip text for\n# close button inside ConditionalPanel component\neditor.conditionalPanel.close=Cancel edit breakpoint and close\n\n# LOCALIZATION NOTE (editor.jumpToMappedLocation1): Context menu item\n# for navigating to a source mapped location\neditor.jumpToMappedLocation1=Jump to %S location\neditor.jumpToMappedLocation1.accesskey=m\n\n# LOCALIZATION NOTE (framework.disableGrouping): This is the text that appears in the\n# context menu to disable framework grouping.\nframework.disableGrouping=Disable framework grouping\nframework.disableGrouping.accesskey=u\n\n# LOCALIZATION NOTE (framework.enableGrouping): This is the text that appears in the\n# context menu to enable framework grouping.\nframework.enableGrouping=Enable framework grouping\nframework.enableGrouping.accesskey=u\n\n# LOCALIZATION NOTE (generated): Source Map term for a server source location\ngenerated=generated\n\n# LOCALIZATION NOTE (original): Source Map term for a debugger UI source location\noriginal=original\n\n# LOCALIZATION NOTE (expressions.placeholder): Placeholder text for expression\n# input element\nexpressions.placeholder=Add watch expression\n# LOCALIZATION NOTE (expressions.errorMsg): Error text for expression\n# input element\nexpressions.errorMsg=Invalid expression…\nexpressions.label=Add watch expression\nexpressions.accesskey=e\n\n# LOCALIZATION NOTE (sourceTabs.closeTab): Editor source tab context menu item\n# for closing the selected tab below the mouse.\nsourceTabs.closeTab=Close tab\nsourceTabs.closeTab.accesskey=c\n\n# LOCALIZATION NOTE (sourceTabs.closeOtherTabs): Editor source tab context menu item\n# for closing the other tabs.\nsourceTabs.closeOtherTabs=Close other tabs\nsourceTabs.closeOtherTabs.accesskey=o\n\n# LOCALIZATION NOTE (sourceTabs.closeTabsToEnd): Editor source tab context menu item\n# for closing the tabs to the end (the right for LTR languages) of the selected tab.\nsourceTabs.closeTabsToEnd=Close tabs to the right\nsourceTabs.closeTabsToEnd.accesskey=e\n\n# LOCALIZATION NOTE (sourceTabs.closeAllTabs): Editor source tab context menu item\n# for closing all tabs.\nsourceTabs.closeAllTabs=Close all tabs\nsourceTabs.closeAllTabs.accesskey=a\n\n# LOCALIZATION NOTE (sourceTabs.revealInTree): Editor source tab context menu item\n# for revealing source in tree.\nsourceTabs.revealInTree=Reveal in tree\nsourceTabs.revealInTree.accesskey=r\n\n# LOCALIZATION NOTE (sourceTabs.prettyPrint): Editor source tab context menu item\n# for pretty printing the source.\nsourceTabs.prettyPrint=Pretty print source\nsourceTabs.prettyPrint.accesskey=p\n\n# LOCALIZATION NOTE (sourceFooter.blackbox): Tooltip text associated\n# with the blackbox button\nsourceFooter.blackbox=Blackbox source\nsourceFooter.blackbox.accesskey=B\n\n# LOCALIZATION NOTE (sourceFooter.unblackbox): Tooltip text associated\n# with the blackbox button\nsourceFooter.unblackbox=Unblackbox source\nsourceFooter.unblackbox.accesskey=b\n\n# LOCALIZATION NOTE (sourceFooter.blackboxed): Text associated\n# with a blackboxed source\nsourceFooter.blackboxed=Blackboxed source\n\n# LOCALIZATION NOTE (sourceFooter.mappedSource): Text associated\n# with a mapped source. %S is replaced by the source map origin.\nsourceFooter.mappedSource=(From %S)\n\n# LOCALIZATION NOTE (sourceFooter.mappedSourceTooltip): Tooltip text associated\n# with a mapped source. %S is replaced by the source map origin.\nsourceFooter.mappedSourceTooltip=(Source mapped from %S)\n\n# LOCALIZATION NOTE (sourceFooter.codeCoverage): Text associated\n# with a code coverage button\nsourceFooter.codeCoverage=Code coverage\n\n# LOCALIZATION NOTE (sourceTabs.closeTabButtonTooltip): The tooltip that is displayed\n# for close tab button in source tabs.\nsourceTabs.closeTabButtonTooltip=Close tab\n\n# LOCALIZATION NOTE (scopes.header): Scopes right sidebar pane header.\nscopes.header=Scopes\n\n# LOCALIZATION NOTE (scopes.notAvailable): Scopes right sidebar pane message\n# for when the debugger is paused, but there isn't pause data.\nscopes.notAvailable=Scopes unavailable\n\n# LOCALIZATION NOTE (scopes.notPaused): Scopes right sidebar pane message\n# for when the debugger is not paused.\nscopes.notPaused=Not paused\n\n# LOCALIZATION NOTE (scopes.block): Refers to a block of code in\n# the scopes pane when the debugger is paused.\nscopes.block=Block\n\n# LOCALIZATION NOTE (sources.header): Sources left sidebar header\nsources.header=Sources\n\n# LOCALIZATION NOTE (outline.header): Outline left sidebar header\noutline.header=Outline\n\n# LOCALIZATION NOTE (outline.noFunctions): Outline text when there are no functions to display\noutline.noFunctions=No functions\n\n# LOCALIZATION NOTE (sources.search): Sources left sidebar prompt\n# e.g. Cmd+P to search. On a mac, we use the command unicode character.\n# On windows, it's ctrl.\nsources.search=%S to search\n\n# LOCALIZATION NOTE (watchExpressions.header): Watch Expressions right sidebar\n# pane header.\nwatchExpressions.header=Watch expressions\n\n# LOCALIZATION NOTE (watchExpressions.refreshButton): Watch Expressions header\n# button for refreshing the expressions.\nwatchExpressions.refreshButton=Refresh\n\n# LOCALIZATION NOTE (welcome.search): The center pane welcome panel's\n# search prompt. e.g. cmd+p to search for files. On windows, it's ctrl, on\n# a mac we use the unicode character.\nwelcome.search=%S to search for sources\n\n# LOCALIZATION NOTE (welcome.findInFiles): The center pane welcome panel's\n# search prompt. e.g. cmd+f to search for files. On windows, it's ctrl+shift+f, on\n# a mac we use the unicode character.\nwelcome.findInFiles=%S to find in files\n\n# LOCALIZATION NOTE (welcome.searchFunction): Label displayed in the welcome\n# panel. %S is replaced by the keyboard shortcut to search for functions.\nwelcome.searchFunction=%S to search for functions in file\n\n# LOCALIZATION NOTE (sourceSearch.search): The center pane Source Search\n# prompt for searching for files.\nsourceSearch.search=Search sources…\n\n# LOCALIZATION NOTE (sourceSearch.noResults2): The center pane Source Search\n# message when the query did not match any of the sources.\nsourceSearch.noResults2=No results found\n\n# LOCALIZATION NOTE (ignoreExceptions): The pause on exceptions button tooltip\n# when the debugger will not pause on exceptions.\nignoreExceptions=Ignore exceptions. Click to pause on uncaught exceptions\n\n# LOCALIZATION NOTE (pauseOnUncaughtExceptions): The pause on exceptions button\n# tooltip when the debugger will pause on uncaught exceptions.\npauseOnUncaughtExceptions=Pause on uncaught exceptions. Click to pause on all exceptions\n\n# LOCALIZATION NOTE (pauseOnExceptions): The pause on exceptions button tooltip\n# when the debugger will pause on all exceptions.\npauseOnExceptions=Pause on all exceptions. Click to ignore exceptions\n\n# LOCALIZATION NOTE (loadingText): The text that is displayed in the script\n# editor when the loading process has started but there is no file to display\n# yet.\nloadingText=Loading\\u2026\n\n# LOCALIZATION NOTE (wasmIsNotAvailable): The text that is displayed in the\n# script editor when the WebAssembly source is not available.\nwasmIsNotAvailable=Please refresh to debug this module\n\n# LOCALIZATION NOTE (errorLoadingText3): The text that is displayed in the debugger\n# viewer when there is an error loading a file\nerrorLoadingText3=Error loading this URI: %S\n\n# LOCALIZATION NOTE (addWatchExpressionText): The text that is displayed in the\n# watch expressions list to add a new item.\naddWatchExpressionText=Add watch expression\n\n# LOCALIZATION NOTE (addWatchExpressionButton): The button that is displayed in the\n# variables view popup.\naddWatchExpressionButton=Watch\n\n# LOCALIZATION NOTE (emptyVariablesText): The text that is displayed in the\n# variables pane when there are no variables to display.\nemptyVariablesText=No variables to display\n\n# LOCALIZATION NOTE (scopeLabel): The text that is displayed in the variables\n# pane as a header for each variable scope (e.g. \"Global scope, \"With scope\",\n# etc.).\nscopeLabel=%S scope\n\n# LOCALIZATION NOTE (watchExpressionsScopeLabel): The name of the watch\n# expressions scope. This text is displayed in the variables pane as a header for\n# the watch expressions scope.\nwatchExpressionsScopeLabel=Watch expressions\n\n# LOCALIZATION NOTE (globalScopeLabel): The name of the global scope. This text\n# is added to scopeLabel and displayed in the variables pane as a header for\n# the global scope.\nglobalScopeLabel=Global\n\n# LOCALIZATION NOTE (variablesViewErrorStacktrace): This is the text that is\n# shown before the stack trace in an error.\nvariablesViewErrorStacktrace=Stack trace:\n\n# LOCALIZATION NOTE (variablesViewMoreObjects): the text that is displayed\n# when you have an object preview that does not show all of the elements. At the end of the list\n# you see \"N more...\" in the web console output.\n# This is a semi-colon list of plural forms.\n# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals\n# #1 number of remaining items in the object\n# example: 3 more…\nvariablesViewMoreObjects=#1 more…;#1 more…\n\n# LOCALIZATION NOTE (variablesEditableNameTooltip): The text that is displayed\n# in the variables list on an item with an editable name.\nvariablesEditableNameTooltip=Double click to edit\n\n# LOCALIZATION NOTE (variablesEditableValueTooltip): The text that is displayed\n# in the variables list on an item with an editable value.\nvariablesEditableValueTooltip=Click to change value\n\n# LOCALIZATION NOTE (variablesCloseButtonTooltip): The text that is displayed\n# in the variables list on an item which can be removed.\nvariablesCloseButtonTooltip=Click to remove\n\n# LOCALIZATION NOTE (variablesEditButtonTooltip): The text that is displayed\n# in the variables list on a getter or setter which can be edited.\nvariablesEditButtonTooltip=Click to set value\n\n# LOCALIZATION NOTE (variablesDomNodeValueTooltip): The text that is displayed\n# in a tooltip on the \"open in inspector\" button in the the variables list for a\n# DOMNode item.\nvariablesDomNodeValueTooltip=Click to select the node in the inspector\n\n# LOCALIZATION NOTE (configurable|...|Tooltip): The text that is displayed\n# in the variables list on certain variables or properties as tooltips.\n# Expanations of what these represent can be found at the following links:\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed\n# It's probably best to keep these in English.\nconfigurableTooltip=configurable\nenumerableTooltip=enumerable\nwritableTooltip=writable\nfrozenTooltip=frozen\nsealedTooltip=sealed\nextensibleTooltip=extensible\noverriddenTooltip=overridden\nWebIDLTooltip=WebIDL\n\n# LOCALIZATION NOTE (variablesSeparatorLabel): The text that is displayed\n# in the variables list as a separator between the name and value.\nvariablesSeparatorLabel=:\n\n# LOCALIZATION NOTE (watchExpressionsSeparatorLabel2): The text that is displayed\n# in the watch expressions list as a separator between the code and evaluation.\nwatchExpressionsSeparatorLabel2=\\u0020→\n\n# LOCALIZATION NOTE (functionSearchSeparatorLabel): The text that is displayed\n# in the functions search panel as a separator between function's inferred name\n# and its real name (if available).\nfunctionSearchSeparatorLabel=←\n\n# LOCALIZATION NOTE(gotoLineModal.placeholder): The placeholder\n# text displayed when the user searches for specific lines in a file\ngotoLineModal.placeholder=Go to line…\ngotoLineModal.key=CmdOrCtrl+Shift+;\ngotoLineModal.title=Go to a line number in a file\n\n# LOCALIZATION NOTE(symbolSearch.search.functionsPlaceholder): The placeholder\n# text displayed when the user searches for functions in a file\nsymbolSearch.search.functionsPlaceholder=Search functions…\nsymbolSearch.search.functionsPlaceholder.title=Search for a function in a file\n\n# LOCALIZATION NOTE(symbolSearch.search.variablesPlaceholder): The placeholder\n# text displayed when the user searches for variables in a file\nsymbolSearch.search.variablesPlaceholder=Search variables…\nsymbolSearch.search.variablesPlaceholder.title=Search for a variable in a file\n\n# LOCALIZATION NOTE(symbolSearch.search.key2): The Key Shortcut for\n# searching for a function or variable\nsymbolSearch.search.key2=CmdOrCtrl+Shift+O\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.modifiersLabel): A label\n# preceding the group of modifiers\nsymbolSearch.searchModifier.modifiersLabel=Modifiers:\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.regex): A search option\n# when searching text in a file\nsymbolSearch.searchModifier.regex=Regex\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.caseSensitive): A search option\n# when searching text in a file\nsymbolSearch.searchModifier.caseSensitive=Case sensitive\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.wholeWord): A search option\n# when searching text in a file\nsymbolSearch.searchModifier.wholeWord=Whole word\n\n# LOCALIZATION NOTE (resumptionOrderPanelTitle): This is the text that appears\n# as a description in the notification panel popup, when multiple debuggers are\n# open in separate tabs and the user tries to resume them in the wrong order.\n# The substitution parameter is the URL of the last paused window that must be\n# resumed first.\nresumptionOrderPanelTitle=There are one or more paused debuggers. Please resume the most-recently paused debugger first at: %S\n\nvariablesViewOptimizedOut=(optimized away)\nvariablesViewUninitialized=(uninitialized)\nvariablesViewMissingArgs=(unavailable)\n\nanonymousSourcesLabel=Anonymous sources\n\nexperimental=This is an experimental feature\n\n# LOCALIZATION NOTE (whyPaused.debuggerStatement): The text that is displayed\n# in a info block explaining how the debugger is currently paused due to a `debugger`\n# statement in the code\nwhyPaused.debuggerStatement=Paused on debugger statement\n\n# LOCALIZATION NOTE (whyPaused.breakpoint): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a breakpoint\nwhyPaused.breakpoint=Paused on breakpoint\n\n# LOCALIZATION NOTE (whyPaused.exception): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an exception\nwhyPaused.exception=Paused on exception\n\n# LOCALIZATION NOTE (whyPaused.resumeLimit): The text that is displayed\n# in a info block explaining how the debugger is currently paused while stepping\n# in or out of the stack\nwhyPaused.resumeLimit=Paused while stepping\n\n# LOCALIZATION NOTE (whyPaused.pauseOnDOMEvents): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a\n# dom event\nwhyPaused.pauseOnDOMEvents=Paused on event listener\n\n# LOCALIZATION NOTE (whyPaused.breakpointConditionThrown): The text that is displayed\n# in an info block when evaluating a conditional breakpoint throws an error\nwhyPaused.breakpointConditionThrown=Error with conditional breakpoint\n\n# LOCALIZATION NOTE (whyPaused.xhr): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an\n# xml http request\nwhyPaused.xhr=Paused on XMLHttpRequest\n\n# LOCALIZATION NOTE (whyPaused.promiseRejection): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a\n# promise rejection\nwhyPaused.promiseRejection=Paused on promise rejection\n\n# LOCALIZATION NOTE (whyPaused.assert): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an\n# assert\nwhyPaused.assert=Paused on assertion\n\n# LOCALIZATION NOTE (whyPaused.debugCommand): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a\n# debugger statement\nwhyPaused.debugCommand=Paused on debugged function\n\n# LOCALIZATION NOTE (whyPaused.other): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an event\n# listener breakpoint set\nwhyPaused.other=Debugger paused\n\n# LOCALIZATION NOTE (ctrl): The text that is used for documenting\n# keyboard shortcuts that use the control key\nctrl=Ctrl\n\n# LOCALIZATION NOTE (anonymous): The text that is displayed when the\n# display name is null.\nanonymous=(anonymous)\n\n# LOCALIZATION NOTE (shortcuts.toggleBreakpoint): text describing\n# keyboard shortcut action for toggling breakpoint\nshortcuts.toggleBreakpoint=Toggle Breakpoint\nshortcuts.toggleBreakpoint.accesskey=B\n\n# LOCALIZATION NOTE (shortcuts.toggleCondPanel): text describing\n# keyboard shortcut action for toggling conditional panel keyboard\nshortcuts.toggleCondPanel=Toggle Conditional Panel\n\n# LOCALIZATION NOTE (shortcuts.pauseOrResume): text describing\n# keyboard shortcut action for pause of resume\nshortcuts.pauseOrResume=Pause/Resume\n\n# LOCALIZATION NOTE (shortcuts.stepOver): text describing\n# keyboard shortcut action for stepping over\nshortcuts.stepOver=Step Over\n\n# LOCALIZATION NOTE (shortcuts.stepIn): text describing\n# keyboard shortcut action for stepping in\nshortcuts.stepIn=Step In\n\n# LOCALIZATION NOTE (shortcuts.stepOut): text describing\n# keyboard shortcut action for stepping out\nshortcuts.stepOut=Step Out\n\n# LOCALIZATION NOTE (shortcuts.fileSearch): text describing\n# keyboard shortcut action for source file search\nshortcuts.fileSearch=Source File Search\n\n# LOCALIZATION NOTE (shortcuts.searchAgain): text describing\n# keyboard shortcut action for searching again\nshortcuts.searchAgain=Search Again\n\n# LOCALIZATION NOTE (shortcuts.projectSearch): text describing\n# keyboard shortcut action for full project search\nshortcuts.projectSearch=Full Project Search\n\n# LOCALIZATION NOTE (shortcuts.functionSearch): text describing\n# keyboard shortcut action for function search\nshortcuts.functionSearch=Function Search\n\n# LOCALIZATION NOTE (shortcuts.buttonName): text describing\n# keyboard shortcut button text\nshortcuts.buttonName=Keyboard shortcuts\n"
+module.exports = "# This Source Code Form is subject to the terms of the Mozilla Public\n# License, v. 2.0. If a copy of the MPL was not distributed with this\n# file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\n# LOCALIZATION NOTE These strings are used inside the Debugger\n# which is available from the Web Developer sub-menu -> 'Debugger'.\n# The correct localization of this file might be to keep it in\n# English, or another language commonly spoken among web developers.\n# You want to make that choice consistent across the developer tools.\n# A good criteria is the language in which you'd find the best\n# documentation on web development on the web.\n\n# LOCALIZATION NOTE (collapsePanes): This is the tooltip for the button\n# that collapses the left and right panes in the debugger UI.\ncollapsePanes=Collapse panes\n\n# LOCALIZATION NOTE (copySource): This is the text that appears in the\n# context menu to copy the selected source of file open.\ncopySource=Copy\ncopySource.accesskey=y\n\n# LOCALIZATION NOTE (copySourceUri2): This is the text that appears in the\n# context menu to copy the source URI of file open.\ncopySourceUri2=Copy source URI\ncopySourceUri2.accesskey=u\n\n# LOCALIZATION NOTE (setDirectoryRoot.label): This is the text that appears in the\n# context menu to set a directory as root directory\nsetDirectoryRoot.label=Set directory root\nsetDirectoryRoot.accesskey=r\n\n# LOCALIZATION NOTE (removeDirectoryRoot.label): This is the text that appears in the\n# context menu to remove a directory as root directory\nremoveDirectoryRoot.label=Remove directory root\nremoveDirectoryRoot.accesskey=d\n\n# LOCALIZATION NOTE (copyFunction.label): This is the text that appears in the\n# context menu to copy the function the user selected\ncopyFunction.label=Copy function\ncopyFunction.accesskey=F\n\n# LOCALIZATION NOTE (copyStackTrace): This is the text that appears in the\n# context menu to copy the stack trace methods, file names and row number.\ncopyStackTrace=Copy stack trace\ncopyStackTrace.accesskey=c\n\n# LOCALIZATION NOTE (expandPanes): This is the tooltip for the button\n# that expands the left and right panes in the debugger UI.\nexpandPanes=Expand panes\n\n# LOCALIZATION NOTE (pauseButtonTooltip): The tooltip that is displayed for the pause\n# button when the debugger is in a running state.\npauseButtonTooltip=Pause %S\n\n# LOCALIZATION NOTE (pausePendingButtonTooltip): The tooltip that is displayed for\n# the pause button after it's been clicked but before the next JavaScript to run.\npausePendingButtonTooltip=Waiting for next execution\n\n# LOCALIZATION NOTE (resumeButtonTooltip): The label that is displayed on the pause\n# button when the debugger is in a paused state.\nresumeButtonTooltip=Resume %S\n\n# LOCALIZATION NOTE (stepOverTooltip): The label that is displayed on the\n# button that steps over a function call.\nstepOverTooltip=Step over %S\n\n# LOCALIZATION NOTE (stepInTooltip): The label that is displayed on the\n# button that steps into a function call.\nstepInTooltip=Step in %S\n\n# LOCALIZATION NOTE (stepOutTooltip): The label that is displayed on the\n# button that steps out of a function call.\nstepOutTooltip=Step out %S\n\n# LOCALIZATION NOTE (pauseButtonItem): The label that is displayed for the dropdown pause\n# list item when the debugger is in a running state.\npauseButtonItem=Pause on Next Statement\n\n# LOCALIZATION NOTE (ignoreExceptionsItem): The pause on exceptions button description\n# when the debugger will not pause on exceptions.\nignoreExceptionsItem=Ignore exceptions\n\n# LOCALIZATION NOTE (pauseOnUncaughtExceptionsItem): The pause on exceptions dropdown\n# item shown when a user is adding a new breakpoint.\npauseOnUncaughtExceptionsItem=Pause on uncaught exceptions\n\n# LOCALIZATION NOTE (pauseOnExceptionsItem): The pause on exceptions button description\n# when the debugger will pause on all exceptions.\npauseOnExceptionsItem=Pause on all exceptions\n\n# LOCALIZATION NOTE (workersHeader): The text to display in the events\n# header.\nworkersHeader=Workers\n\n# LOCALIZATION NOTE (noWorkersText): The text to display in the workers list\n# when there are no workers.\nnoWorkersText=This page has no workers.\n\n# LOCALIZATION NOTE (noSourcesText): The text to display in the sources list\n# when there are no sources.\nnoSourcesText=This page has no sources.\n\n# LOCALIZATION NOTE (noEventListenersText): The text to display in the events tab\n# when there are no events.\nnoEventListenersText=No event listeners to display.\n\n# LOCALIZATION NOTE (eventListenersHeader): The text to display in the events\n# header.\neventListenersHeader=Event listeners\n\n# LOCALIZATION NOTE (noStackFramesText): The text to display in the call stack tab\n# when there are no stack frames.\nnoStackFramesText=No stack frames to display\n\n# LOCALIZATION NOTE (eventCheckboxTooltip): The tooltip text to display when\n# the user hovers over the checkbox used to toggle an event breakpoint.\neventCheckboxTooltip=Toggle breaking on this event\n\n# LOCALIZATION NOTE (eventOnSelector): The text to display in the events tab\n# for every event item, between the event type and event selector.\neventOnSelector=on\n\n# LOCALIZATION NOTE (eventInSource): The text to display in the events tab\n# for every event item, between the event selector and listener's owner source.\neventInSource=in\n\n# LOCALIZATION NOTE (eventNodes): The text to display in the events tab when\n# an event is listened on more than one target node.\neventNodes=%S nodes\n\n# LOCALIZATION NOTE (eventNative): The text to display in the events tab when\n# a listener is added from plugins, thus getting translated to native code.\neventNative=[native code]\n\n# LOCALIZATION NOTE (*Events): The text to display in the events tab for\n# each group of sub-level event entries.\nanimationEvents=Animation\naudioEvents=Audio\nbatteryEvents=Battery\nclipboardEvents=Clipboard\ncompositionEvents=Composition\ndeviceEvents=Device\ndisplayEvents=Display\ndragAndDropEvents=Drag and Drop\ngamepadEvents=Gamepad\nindexedDBEvents=IndexedDB\ninteractionEvents=Interaction\nkeyboardEvents=Keyboard\nmediaEvents=HTML5 Media\nmouseEvents=Mouse\nmutationEvents=Mutation\nnavigationEvents=Navigation\npointerLockEvents=Pointer Lock\nsensorEvents=Sensor\nstorageEvents=Storage\ntimeEvents=Time\ntouchEvents=Touch\notherEvents=Other\n\n# LOCALIZATION NOTE (blackboxCheckboxTooltip2): The tooltip text to display when\n# the user hovers over the checkbox used to toggle blackboxing its associated\n# source.\nblackboxCheckboxTooltip2=Toggle blackboxing\n\n# LOCALIZATION NOTE (sources.search.key2): Key shortcut to open the search for\n# searching all the source files the debugger has seen.\n# Do not localize \"CmdOrCtrl+P\", or change the format of the string. These are\n# key identifiers, not messages displayed to the user.\nsources.search.key2=CmdOrCtrl+P\n\n# LOCALIZATION NOTE (sources.search.alt.key): A second key shortcut to open the\n# search for searching all the source files the debugger has seen.\n# Do not localize \"CmdOrCtrl+O\", or change the format of the string. These are\n# key identifiers, not messages displayed to the user.\nsources.search.alt.key=CmdOrCtrl+O\n\n# LOCALIZATION NOTE (projectTextSearch.key): A key shortcut to open the\n# full project text search for searching all the files the debugger has seen.\n# Do not localize \"CmdOrCtrl+Shift+F\", or change the format of the string. These are\n# key identifiers, not messages displayed to the user.\nprojectTextSearch.key=CmdOrCtrl+Shift+F\n\n# LOCALIZATION NOTE (functionSearch.key): A key shortcut to open the\n# modal for searching functions in a file.\n# Do not localize \"CmdOrCtrl+Shift+O\", or change the format of the string. These are\n# key identifiers, not messages displayed to the user.\nfunctionSearch.key=CmdOrCtrl+Shift+O\n\n# LOCALIZATION NOTE (toggleBreakpoint.key): A key shortcut to toggle\n# breakpoints.\n# Do not localize \"CmdOrCtrl+B\", or change the format of the string. These are\n# key identifiers, not messages displayed to the user.\ntoggleBreakpoint.key=CmdOrCtrl+B\n\n# LOCALIZATION NOTE (toggleCondPanel.key): A key shortcut to toggle\n# the conditional breakpoint panel.\n# Do not localize \"CmdOrCtrl+Shift+B\", or change the format of the string. These are\n# key identifiers, not messages displayed to the user.\ntoggleCondPanel.key=CmdOrCtrl+Shift+B\n\n# LOCALIZATION NOTE (stepOut.key): A key shortcut to\n# step out.\nstepOut.key=Shift+F11\n\n# LOCALIZATION NOTE (shortcuts.header.editor): Sections header in\n# the shortcuts modal for keyboard shortcuts related to editing.\nshortcuts.header.editor=Editor\n\n# LOCALIZATION NOTE (shortcuts.header.stepping): Sections header in\n# the shortcuts modal for keyboard shortcuts related to stepping.\nshortcuts.header.stepping=Stepping\n\n# LOCALIZATION NOTE (shortcuts.header.search): Sections header in\n# the shortcuts modal for keyboard shortcuts related to search.\nshortcuts.header.search=Search\n\n# LOCALIZATION NOTE (projectTextSearch.placeholder): A placeholder shown\n# when searching across all of the files in a project.\nprojectTextSearch.placeholder=Find in files…\n\n# LOCALIZATION NOTE (projectTextSearch.noResults): The center pane Text Search\n# message when the query did not match any text of all files in a project.\nprojectTextSearch.noResults=No results found\n\n# LOCALIZATION NOTE (sources.noSourcesAvailable): Text shown when the debugger\n# does not have any sources.\nsources.noSourcesAvailable=This page has no sources\n\n# LOCALIZATION NOTE (sourceSearch.search.key2): Key shortcut to open the search\n# for searching within a the currently opened files in the editor\n# Do not localize \"CmdOrCtrl+F\", or change the format of the string. These are\n# key identifiers, not messages displayed to the user.\nsourceSearch.search.key2=CmdOrCtrl+F\n\n# LOCALIZATION NOTE (sourceSearch.search.placeholder): placeholder text in\n# the source search input bar\nsourceSearch.search.placeholder=Search in file…\n\n# LOCALIZATION NOTE (sourceSearch.search.again.key2): Key shortcut to highlight\n# the next occurrence of the last search triggered from a source search\n# Do not localize \"CmdOrCtrl+G\", or change the format of the string. These are\n# key identifiers, not messages displayed to the user.\nsourceSearch.search.again.key2=CmdOrCtrl+G\n\n# LOCALIZATION NOTE (sourceSearch.search.againPrev.key2): Key shortcut to highlight\n# the previous occurrence of the last search triggered from a source search\n# Do not localize \"CmdOrCtrl+Shift+G\", or change the format of the string. These are\n# key identifiers, not messages displayed to the user.\nsourceSearch.search.againPrev.key2=CmdOrCtrl+Shift+G\n\n# LOCALIZATION NOTE (sourceSearch.resultsSummary1): Shows a summary of\n# the number of matches for autocomplete\nsourceSearch.resultsSummary1=%d results\n\n# LOCALIZATION NOTE (noMatchingStringsText): The text to display in the\n# global search results when there are no matching strings after filtering.\nnoMatchingStringsText=No matches found\n\n# LOCALIZATION NOTE (emptySearchText): This is the text that appears in the\n# filter text box when it is empty and the scripts container is selected.\nemptySearchText=Search scripts (%S)\n\n# LOCALIZATION NOTE (emptyVariablesFilterText): This is the text that\n# appears in the filter text box for the variables view container.\nemptyVariablesFilterText=Filter variables\n\n# LOCALIZATION NOTE (emptyPropertiesFilterText): This is the text that\n# appears in the filter text box for the editor's variables view bubble.\nemptyPropertiesFilterText=Filter properties\n\n# LOCALIZATION NOTE (searchPanelFilter): This is the text that appears in the\n# filter panel popup for the filter scripts operation.\nsearchPanelFilter=Filter scripts (%S)\n\n# LOCALIZATION NOTE (searchPanelGlobal): This is the text that appears in the\n# filter panel popup for the global search operation.\nsearchPanelGlobal=Search in all files (%S)\n\n# LOCALIZATION NOTE (searchPanelFunction): This is the text that appears in the\n# filter panel popup for the function search operation.\nsearchPanelFunction=Search for function definition (%S)\n\n# LOCALIZATION NOTE (searchPanelToken): This is the text that appears in the\n# filter panel popup for the token search operation.\nsearchPanelToken=Find in this file (%S)\n\n# LOCALIZATION NOTE (searchPanelGoToLine): This is the text that appears in the\n# filter panel popup for the line search operation.\nsearchPanelGoToLine=Go to line (%S)\n\n# LOCALIZATION NOTE (searchPanelVariable): This is the text that appears in the\n# filter panel popup for the variables search operation.\nsearchPanelVariable=Filter variables (%S)\n\n# LOCALIZATION NOTE (breakpointMenuItem): The text for all the elements that\n# are displayed in the breakpoints menu item popup.\nbreakpointMenuItem.setConditional=Configure conditional breakpoint\nbreakpointMenuItem.enableSelf2.label=Enable\nbreakpointMenuItem.enableSelf2.accesskey=E\nbreakpointMenuItem.disableSelf2.label=Disable\nbreakpointMenuItem.disableSelf2.accesskey=D\nbreakpointMenuItem.deleteSelf2.label=Remove\nbreakpointMenuItem.deleteSelf2.accesskey=R\nbreakpointMenuItem.enableOthers2.label=Enable others\nbreakpointMenuItem.enableOthers2.accesskey=o\nbreakpointMenuItem.disableOthers2.label=Disable others\nbreakpointMenuItem.disableOthers2.accesskey=s\nbreakpointMenuItem.deleteOthers2.label=Remove others\nbreakpointMenuItem.deleteOthers2.accesskey=h\nbreakpointMenuItem.enableAll2.label=Enable all\nbreakpointMenuItem.enableAll2.accesskey=b\nbreakpointMenuItem.disableAll2.label=Disable all\nbreakpointMenuItem.disableAll2.accesskey=k\nbreakpointMenuItem.deleteAll2.label=Remove all\nbreakpointMenuItem.deleteAll2.accesskey=a\nbreakpointMenuItem.removeCondition2.label=Remove condition\nbreakpointMenuItem.removeCondition2.accesskey=c\nbreakpointMenuItem.addCondition2.label=Add condition\nbreakpointMenuItem.addCondition2.accesskey=A\nbreakpointMenuItem.editCondition2.label=Edit condition\nbreakpointMenuItem.editCondition2.accesskey=n\nbreakpointMenuItem.enableSelf=Enable breakpoint\nbreakpointMenuItem.enableSelf.accesskey=E\nbreakpointMenuItem.disableSelf=Disable breakpoint\nbreakpointMenuItem.disableSelf.accesskey=D\nbreakpointMenuItem.deleteSelf=Remove breakpoint\nbreakpointMenuItem.deleteSelf.accesskey=R\nbreakpointMenuItem.enableOthers=Enable others\nbreakpointMenuItem.enableOthers.accesskey=o\nbreakpointMenuItem.disableOthers=Disable others\nbreakpointMenuItem.disableOthers.accesskey=s\nbreakpointMenuItem.deleteOthers=Remove others\nbreakpointMenuItem.deleteOthers.accesskey=h\nbreakpointMenuItem.enableAll=Enable all breakpoints\nbreakpointMenuItem.enableAll.accesskey=b\nbreakpointMenuItem.disableAll=Disable all breakpoints\nbreakpointMenuItem.disableAll.accesskey=k\nbreakpointMenuItem.deleteAll=Remove all breakpoints\nbreakpointMenuItem.deleteAll.accesskey=a\nbreakpointMenuItem.removeCondition.label=Remove breakpoint condition\nbreakpointMenuItem.removeCondition.accesskey=c\nbreakpointMenuItem.editCondition.label=Edit breakpoint condition\nbreakpointMenuItem.editCondition.accesskey=n\n\n# LOCALIZATION NOTE (breakpoints.header): Breakpoints right sidebar pane header.\nbreakpoints.header=Breakpoints\n\n# LOCALIZATION NOTE (breakpoints.none): The text that appears when there are\n# no breakpoints present\nbreakpoints.none=No breakpoints\n\n# LOCALIZATION NOTE (breakpoints.enable): The text that may appear as a tooltip\n# when hovering over the 'disable breakpoints' switch button in right sidebar\nbreakpoints.enable=Enable breakpoints\n\n# LOCALIZATION NOTE (breakpoints.disable): The text that may appear as a tooltip\n# when hovering over the 'disable breakpoints' switch button in right sidebar\nbreakpoints.disable=Disable breakpoints\n\n# LOCALIZATION NOTE (breakpoints.removeBreakpointTooltip): The tooltip that is displayed\n# for remove breakpoint button in right sidebar\nbreakpoints.removeBreakpointTooltip=Remove breakpoint\n\n# LOCALIZATION NOTE (callStack.header): Call Stack right sidebar pane header.\ncallStack.header=Call stack\n\n# LOCALIZATION NOTE (callStack.notPaused): Call Stack right sidebar pane\n# message when not paused.\ncallStack.notPaused=Not paused\n\n# LOCALIZATION NOTE (callStack.collapse): Call Stack right sidebar pane\n# message to hide some of the frames that are shown.\ncallStack.collapse=Collapse rows\n\n# LOCALIZATION NOTE (callStack.expand): Call Stack right sidebar pane\n# message to show more of the frames.\ncallStack.expand=Expand rows\n\n# LOCALIZATION NOTE (editor.searchResults): Editor Search bar message\n# for the summarizing the selected search result. e.g. 5 of 10 results.\neditor.searchResults=%d of %d results\n\n# LOCALIZATION NOTE (editor.singleResult): Copy shown when there is one result.\neditor.singleResult=1 result\n\n# LOCALIZATION NOTE (editor.noResults): Editor Search bar message\n# for when no results found.\neditor.noResults=No results\n\n# LOCALIZATION NOTE (editor.searchResults.nextResult): Editor Search bar\n# tooltip for traversing to the Next Result\neditor.searchResults.nextResult=Next result\n\n# LOCALIZATION NOTE (editor.searchResults.prevResult): Editor Search bar\n# tooltip for traversing to the Previous Result\neditor.searchResults.prevResult=Previous result\n\n# LOCALIZATION NOTE (editor.searchTypeToggleTitle): Search bar title for\n# toggling search type buttons(function search, variable search)\neditor.searchTypeToggleTitle=Search for:\n\n# LOCALIZATION NOTE (editor.continueToHere.label): Editor gutter context\n# menu item for jumping to a new paused location\neditor.continueToHere.label=Continue to here\neditor.continueToHere.accesskey=H\n\n# LOCALIZATION NOTE (editor.addBreakpoint): Editor gutter context menu item\n# for adding a breakpoint on a line.\neditor.addBreakpoint=Add breakpoint\n\n# LOCALIZATION NOTE (editor.disableBreakpoint): Editor gutter context menu item\n# for disabling a breakpoint on a line.\neditor.disableBreakpoint=Disable breakpoint\neditor.disableBreakpoint.accesskey=D\n\n# LOCALIZATION NOTE (editor.enableBreakpoint): Editor gutter context menu item\n# for enabling a breakpoint on a line.\neditor.enableBreakpoint=Enable breakpoint\n\n# LOCALIZATION NOTE (editor.removeBreakpoint): Editor gutter context menu item\n# for removing a breakpoint on a line.\neditor.removeBreakpoint=Remove breakpoint\n\n# LOCALIZATION NOTE (editor.editBreakpoint): Editor gutter context menu item\n# for setting a breakpoint condition on a line.\neditor.editBreakpoint=Edit breakpoint\n\n# LOCALIZATION NOTE (editor.addConditionalBreakpoint): Editor gutter context\n# menu item for adding a breakpoint condition on a line.\neditor.addConditionalBreakpoint=Add conditional breakpoint\neditor.addConditionalBreakpoint.accesskey=c\n\n# LOCALIZATION NOTE (editor.conditionalPanel.placeholder): Placeholder text for\n# input element inside ConditionalPanel component\neditor.conditionalPanel.placeholder=This breakpoint will pause when the expression is true\n\n# LOCALIZATION NOTE (editor.conditionalPanel.close): Tooltip text for\n# close button inside ConditionalPanel component\neditor.conditionalPanel.close=Cancel edit breakpoint and close\n\n# LOCALIZATION NOTE (editor.jumpToMappedLocation1): Context menu item\n# for navigating to a source mapped location\neditor.jumpToMappedLocation1=Jump to %S location\neditor.jumpToMappedLocation1.accesskey=m\n\n# LOCALIZATION NOTE (framework.disableGrouping): This is the text that appears in the\n# context menu to disable framework grouping.\nframework.disableGrouping=Disable framework grouping\nframework.disableGrouping.accesskey=u\n\n# LOCALIZATION NOTE (framework.enableGrouping): This is the text that appears in the\n# context menu to enable framework grouping.\nframework.enableGrouping=Enable framework grouping\nframework.enableGrouping.accesskey=u\n\n# LOCALIZATION NOTE (generated): Source Map term for a server source location\ngenerated=generated\n\n# LOCALIZATION NOTE (original): Source Map term for a debugger UI source location\noriginal=original\n\n# LOCALIZATION NOTE (expressions.placeholder): Placeholder text for expression\n# input element\nexpressions.placeholder=Add watch expression\n# LOCALIZATION NOTE (expressions.errorMsg): Error text for expression\n# input element\nexpressions.errorMsg=Invalid expression…\nexpressions.label=Add watch expression\nexpressions.accesskey=e\n\n# LOCALIZATION NOTE (sourceTabs.closeTab): Editor source tab context menu item\n# for closing the selected tab below the mouse.\nsourceTabs.closeTab=Close tab\nsourceTabs.closeTab.accesskey=c\n\n# LOCALIZATION NOTE (sourceTabs.closeOtherTabs): Editor source tab context menu item\n# for closing the other tabs.\nsourceTabs.closeOtherTabs=Close other tabs\nsourceTabs.closeOtherTabs.accesskey=o\n\n# LOCALIZATION NOTE (sourceTabs.closeTabsToEnd): Editor source tab context menu item\n# for closing the tabs to the end (the right for LTR languages) of the selected tab.\nsourceTabs.closeTabsToEnd=Close tabs to the right\nsourceTabs.closeTabsToEnd.accesskey=e\n\n# LOCALIZATION NOTE (sourceTabs.closeAllTabs): Editor source tab context menu item\n# for closing all tabs.\nsourceTabs.closeAllTabs=Close all tabs\nsourceTabs.closeAllTabs.accesskey=a\n\n# LOCALIZATION NOTE (sourceTabs.revealInTree): Editor source tab context menu item\n# for revealing source in tree.\nsourceTabs.revealInTree=Reveal in tree\nsourceTabs.revealInTree.accesskey=r\n\n# LOCALIZATION NOTE (sourceTabs.prettyPrint): Editor source tab context menu item\n# for pretty printing the source.\nsourceTabs.prettyPrint=Pretty print source\nsourceTabs.prettyPrint.accesskey=p\n\n# LOCALIZATION NOTE (sourceFooter.blackbox): Tooltip text associated\n# with the blackbox button\nsourceFooter.blackbox=Blackbox source\nsourceFooter.blackbox.accesskey=B\n\n# LOCALIZATION NOTE (sourceFooter.unblackbox): Tooltip text associated\n# with the blackbox button\nsourceFooter.unblackbox=Unblackbox source\nsourceFooter.unblackbox.accesskey=b\n\n# LOCALIZATION NOTE (sourceFooter.blackboxed): Text associated\n# with a blackboxed source\nsourceFooter.blackboxed=Blackboxed source\n\n# LOCALIZATION NOTE (sourceFooter.mappedSource): Text associated\n# with a mapped source. %S is replaced by the source map origin.\nsourceFooter.mappedSource=(From %S)\n\n# LOCALIZATION NOTE (sourceFooter.mappedSourceTooltip): Tooltip text associated\n# with a mapped source. %S is replaced by the source map origin.\nsourceFooter.mappedSourceTooltip=(Source mapped from %S)\n\n# LOCALIZATION NOTE (sourceFooter.codeCoverage): Text associated\n# with a code coverage button\nsourceFooter.codeCoverage=Code coverage\n\n# LOCALIZATION NOTE (sourceTabs.closeTabButtonTooltip): The tooltip that is displayed\n# for close tab button in source tabs.\nsourceTabs.closeTabButtonTooltip=Close tab\n\n# LOCALIZATION NOTE (scopes.header): Scopes right sidebar pane header.\nscopes.header=Scopes\n\n# LOCALIZATION NOTE (scopes.notAvailable): Scopes right sidebar pane message\n# for when the debugger is paused, but there isn't pause data.\nscopes.notAvailable=Scopes unavailable\n\n# LOCALIZATION NOTE (scopes.notPaused): Scopes right sidebar pane message\n# for when the debugger is not paused.\nscopes.notPaused=Not paused\n\n# LOCALIZATION NOTE (scopes.block): Refers to a block of code in\n# the scopes pane when the debugger is paused.\nscopes.block=Block\n\n# LOCALIZATION NOTE (sources.header): Sources left sidebar header\nsources.header=Sources\n\n# LOCALIZATION NOTE (outline.header): Outline left sidebar header\noutline.header=Outline\n\n# LOCALIZATION NOTE (outline.noFunctions): Outline text when there are no functions to display\noutline.noFunctions=No functions\n\n# LOCALIZATION NOTE (sources.search): Sources left sidebar prompt\n# e.g. Cmd+P to search. On a mac, we use the command unicode character.\n# On windows, it's ctrl.\nsources.search=%S to search\n\n# LOCALIZATION NOTE (watchExpressions.header): Watch Expressions right sidebar\n# pane header.\nwatchExpressions.header=Watch expressions\n\n# LOCALIZATION NOTE (watchExpressions.refreshButton): Watch Expressions header\n# button for refreshing the expressions.\nwatchExpressions.refreshButton=Refresh\n\n# LOCALIZATION NOTE (welcome.search): The center pane welcome panel's\n# search prompt. e.g. cmd+p to search for files. On windows, it's ctrl, on\n# a mac we use the unicode character.\nwelcome.search=%S To search for sources\n\n# LOCALIZATION NOTE (welcome.findInFiles): The center pane welcome panel's\n# search prompt. e.g. cmd+f to search for files. On windows, it's ctrl+shift+f, on\n# a mac we use the unicode character.\nwelcome.findInFiles=%S To find in files\n\n# LOCALIZATION NOTE (welcome.searchFunction): Label displayed in the welcome\n# panel. %S is replaced by the keyboard shortcut to search for functions.\nwelcome.searchFunction=%S To search for functions in file\n\n# LOCALIZATION NOTE (sourceSearch.search): The center pane Source Search\n# prompt for searching for files.\nsourceSearch.search=Search sources…\n\n# LOCALIZATION NOTE (sourceSearch.noResults2): The center pane Source Search\n# message when the query did not match any of the sources.\nsourceSearch.noResults2=No results found\n\n# LOCALIZATION NOTE (ignoreExceptions): The pause on exceptions button tooltip\n# when the debugger will not pause on exceptions.\nignoreExceptions=Ignore exceptions. Click to pause on uncaught exceptions\n\n# LOCALIZATION NOTE (pauseOnUncaughtExceptions): The pause on exceptions button\n# tooltip when the debugger will pause on uncaught exceptions.\npauseOnUncaughtExceptions=Pause on uncaught exceptions. Click to pause on all exceptions\n\n# LOCALIZATION NOTE (pauseOnExceptions): The pause on exceptions button tooltip\n# when the debugger will pause on all exceptions.\npauseOnExceptions=Pause on all exceptions. Click to ignore exceptions\n\n# LOCALIZATION NOTE (loadingText): The text that is displayed in the script\n# editor when the loading process has started but there is no file to display\n# yet.\nloadingText=Loading\\u2026\n\n# LOCALIZATION NOTE (wasmIsNotAvailable): The text that is displayed in the\n# script editor when the WebAssembly source is not available.\nwasmIsNotAvailable=Please refresh to debug this module\n\n# LOCALIZATION NOTE (errorLoadingText3): The text that is displayed in the debugger\n# viewer when there is an error loading a file\nerrorLoadingText3=Error loading this URI: %S\n\n# LOCALIZATION NOTE (addWatchExpressionText): The text that is displayed in the\n# watch expressions list to add a new item.\naddWatchExpressionText=Add watch expression\n\n# LOCALIZATION NOTE (addWatchExpressionButton): The button that is displayed in the\n# variables view popup.\naddWatchExpressionButton=Watch\n\n# LOCALIZATION NOTE (emptyVariablesText): The text that is displayed in the\n# variables pane when there are no variables to display.\nemptyVariablesText=No variables to display\n\n# LOCALIZATION NOTE (scopeLabel): The text that is displayed in the variables\n# pane as a header for each variable scope (e.g. \"Global scope, \"With scope\",\n# etc.).\nscopeLabel=%S scope\n\n# LOCALIZATION NOTE (watchExpressionsScopeLabel): The name of the watch\n# expressions scope. This text is displayed in the variables pane as a header for\n# the watch expressions scope.\nwatchExpressionsScopeLabel=Watch expressions\n\n# LOCALIZATION NOTE (globalScopeLabel): The name of the global scope. This text\n# is added to scopeLabel and displayed in the variables pane as a header for\n# the global scope.\nglobalScopeLabel=Global\n\n# LOCALIZATION NOTE (variablesViewErrorStacktrace): This is the text that is\n# shown before the stack trace in an error.\nvariablesViewErrorStacktrace=Stack trace:\n\n# LOCALIZATION NOTE (variablesViewMoreObjects): the text that is displayed\n# when you have an object preview that does not show all of the elements. At the end of the list\n# you see \"N more...\" in the web console output.\n# This is a semi-colon list of plural forms.\n# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals\n# #1 number of remaining items in the object\n# example: 3 more…\nvariablesViewMoreObjects=#1 more…;#1 more…\n\n# LOCALIZATION NOTE (variablesEditableNameTooltip): The text that is displayed\n# in the variables list on an item with an editable name.\nvariablesEditableNameTooltip=Double click to edit\n\n# LOCALIZATION NOTE (variablesEditableValueTooltip): The text that is displayed\n# in the variables list on an item with an editable value.\nvariablesEditableValueTooltip=Click to change value\n\n# LOCALIZATION NOTE (variablesCloseButtonTooltip): The text that is displayed\n# in the variables list on an item which can be removed.\nvariablesCloseButtonTooltip=Click to remove\n\n# LOCALIZATION NOTE (variablesEditButtonTooltip): The text that is displayed\n# in the variables list on a getter or setter which can be edited.\nvariablesEditButtonTooltip=Click to set value\n\n# LOCALIZATION NOTE (variablesDomNodeValueTooltip): The text that is displayed\n# in a tooltip on the \"open in inspector\" button in the the variables list for a\n# DOMNode item.\nvariablesDomNodeValueTooltip=Click to select the node in the inspector\n\n# LOCALIZATION NOTE (configurable|...|Tooltip): The text that is displayed\n# in the variables list on certain variables or properties as tooltips.\n# Expanations of what these represent can be found at the following links:\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed\n# It's probably best to keep these in English.\nconfigurableTooltip=configurable\nenumerableTooltip=enumerable\nwritableTooltip=writable\nfrozenTooltip=frozen\nsealedTooltip=sealed\nextensibleTooltip=extensible\noverriddenTooltip=overridden\nWebIDLTooltip=WebIDL\n\n# LOCALIZATION NOTE (variablesSeparatorLabel): The text that is displayed\n# in the variables list as a separator between the name and value.\nvariablesSeparatorLabel=:\n\n# LOCALIZATION NOTE (watchExpressionsSeparatorLabel2): The text that is displayed\n# in the watch expressions list as a separator between the code and evaluation.\nwatchExpressionsSeparatorLabel2=\\u0020→\n\n# LOCALIZATION NOTE (functionSearchSeparatorLabel): The text that is displayed\n# in the functions search panel as a separator between function's inferred name\n# and its real name (if available).\nfunctionSearchSeparatorLabel=←\n\n# LOCALIZATION NOTE(gotoLineModal.placeholder): The placeholder\n# text displayed when the user searches for specific lines in a file\n# Do not localize \"CmdOrCtrl+;\", or change the format of the string. These are\n# key identifiers, not messages displayed to the user.\ngotoLineModal.placeholder=Go to line…\ngotoLineModal.key=CmdOrCtrl+;\ngotoLineModal.title=Go to a line number in a file\n\n# LOCALIZATION NOTE(symbolSearch.search.functionsPlaceholder): The placeholder\n# text displayed when the user searches for functions in a file\nsymbolSearch.search.functionsPlaceholder=Search functions…\nsymbolSearch.search.functionsPlaceholder.title=Search for a function in a file\n\n# LOCALIZATION NOTE(symbolSearch.search.variablesPlaceholder): The placeholder\n# text displayed when the user searches for variables in a file\nsymbolSearch.search.variablesPlaceholder=Search variables…\nsymbolSearch.search.variablesPlaceholder.title=Search for a variable in a file\n\n# LOCALIZATION NOTE(symbolSearch.search.key2): The Key Shortcut for\n# searching for a function or variable\n# Do not localize \"CmdOrCtrl+Shift+O\", or change the format of the string. These are\n# key identifiers, not messages displayed to the user.\nsymbolSearch.search.key2=CmdOrCtrl+Shift+O\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.modifiersLabel): A label\n# preceding the group of modifiers\nsymbolSearch.searchModifier.modifiersLabel=Modifiers:\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.regex): A search option\n# when searching text in a file\nsymbolSearch.searchModifier.regex=Regex\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.caseSensitive): A search option\n# when searching text in a file\nsymbolSearch.searchModifier.caseSensitive=Case sensitive\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.wholeWord): A search option\n# when searching text in a file\nsymbolSearch.searchModifier.wholeWord=Whole word\n\n# LOCALIZATION NOTE (resumptionOrderPanelTitle): This is the text that appears\n# as a description in the notification panel popup, when multiple debuggers are\n# open in separate tabs and the user tries to resume them in the wrong order.\n# The substitution parameter is the URL of the last paused window that must be\n# resumed first.\nresumptionOrderPanelTitle=There are one or more paused debuggers. Please resume the most-recently paused debugger first at: %S\n\nvariablesViewOptimizedOut=(optimized away)\nvariablesViewUninitialized=(uninitialized)\nvariablesViewMissingArgs=(unavailable)\n\nanonymousSourcesLabel=Anonymous sources\n\nexperimental=This is an experimental feature\n\n# LOCALIZATION NOTE (whyPaused.debuggerStatement): The text that is displayed\n# in a info block explaining how the debugger is currently paused due to a `debugger`\n# statement in the code\nwhyPaused.debuggerStatement=Paused on debugger statement\n\n# LOCALIZATION NOTE (whyPaused.breakpoint): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a breakpoint\nwhyPaused.breakpoint=Paused on breakpoint\n\n# LOCALIZATION NOTE (whyPaused.exception): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an exception\nwhyPaused.exception=Paused on exception\n\n# LOCALIZATION NOTE (whyPaused.resumeLimit): The text that is displayed\n# in a info block explaining how the debugger is currently paused while stepping\n# in or out of the stack\nwhyPaused.resumeLimit=Paused while stepping\n\n# LOCALIZATION NOTE (whyPaused.pauseOnDOMEvents): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a\n# dom event\nwhyPaused.pauseOnDOMEvents=Paused on event listener\n\n# LOCALIZATION NOTE (whyPaused.breakpointConditionThrown): The text that is displayed\n# in an info block when evaluating a conditional breakpoint throws an error\nwhyPaused.breakpointConditionThrown=Error with conditional breakpoint\n\n# LOCALIZATION NOTE (whyPaused.xhr): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an\n# xml http request\nwhyPaused.xhr=Paused on XMLHttpRequest\n\n# LOCALIZATION NOTE (whyPaused.promiseRejection): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a\n# promise rejection\nwhyPaused.promiseRejection=Paused on promise rejection\n\n# LOCALIZATION NOTE (whyPaused.assert): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an\n# assert\nwhyPaused.assert=Paused on assertion\n\n# LOCALIZATION NOTE (whyPaused.debugCommand): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a\n# debugger statement\nwhyPaused.debugCommand=Paused on debugged function\n\n# LOCALIZATION NOTE (whyPaused.other): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an event\n# listener breakpoint set\nwhyPaused.other=Debugger paused\n\n# LOCALIZATION NOTE (ctrl): The text that is used for documenting\n# keyboard shortcuts that use the control key\nctrl=Ctrl\n\n# LOCALIZATION NOTE (anonymous): The text that is displayed when the\n# display name is null.\nanonymous=(anonymous)\n\n# LOCALIZATION NOTE (shortcuts.toggleBreakpoint): text describing\n# keyboard shortcut action for toggling breakpoint\nshortcuts.toggleBreakpoint=Toggle Breakpoint\nshortcuts.toggleBreakpoint.accesskey=B\n\n# LOCALIZATION NOTE (shortcuts.toggleCondPanel): text describing\n# keyboard shortcut action for toggling conditional panel keyboard\nshortcuts.toggleCondPanel=Toggle Conditional Panel\n\n# LOCALIZATION NOTE (shortcuts.pauseOrResume): text describing\n# keyboard shortcut action for pause of resume\nshortcuts.pauseOrResume=Pause/Resume\n\n# LOCALIZATION NOTE (shortcuts.stepOver): text describing\n# keyboard shortcut action for stepping over\nshortcuts.stepOver=Step Over\n\n# LOCALIZATION NOTE (shortcuts.stepIn): text describing\n# keyboard shortcut action for stepping in\nshortcuts.stepIn=Step In\n\n# LOCALIZATION NOTE (shortcuts.stepOut): text describing\n# keyboard shortcut action for stepping out\nshortcuts.stepOut=Step Out\n\n# LOCALIZATION NOTE (shortcuts.fileSearch): text describing\n# keyboard shortcut action for source file search\nshortcuts.fileSearch=Source File Search\n\n# LOCALIZATION NOTE (shortcuts.gotoLine): text describing\n# keyboard shortcut for jumping to a specific line\nshortcuts.gotoLine=Go to line\n\n# LOCALIZATION NOTE (shortcuts.searchAgain): text describing\n# keyboard shortcut action for searching again\nshortcuts.searchAgain=Search Again\n\n# LOCALIZATION NOTE (shortcuts.projectSearch): text describing\n# keyboard shortcut action for full project search\nshortcuts.projectSearch=Full Project Search\n\n# LOCALIZATION NOTE (shortcuts.functionSearch): text describing\n# keyboard shortcut action for function search\nshortcuts.functionSearch=Function Search\n\n# LOCALIZATION NOTE (shortcuts.buttonName): text describing\n# keyboard shortcut button text\nshortcuts.buttonName=Keyboard shortcuts\n"
 
 /***/ }),
 /* 961 */,
 /* 962 */,
 /* 963 */,
 /* 964 */,
 /* 965 */
 /***/ (function(module, exports) {
@@ -17839,17 +17839,17 @@ function createPendingBreakpoint(bp) {
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.replaceOriginalVariableName = exports.isReactComponent = exports.hasSyntaxError = exports.clearSources = exports.setSource = exports.hasSource = exports.getEmptyLines = exports.getNextStep = exports.clearASTs = exports.clearScopes = exports.clearSymbols = exports.findOutOfScopeLocations = exports.getVariablesInScope = exports.getScopes = exports.getSymbols = exports.getClosestExpression = exports.stopParserWorker = exports.startParserWorker = undefined;
+exports.replaceOriginalVariableName = exports.getFramework = exports.hasSyntaxError = exports.clearSources = exports.setSource = exports.hasSource = exports.getEmptyLines = exports.getNextStep = exports.clearASTs = exports.clearScopes = exports.clearSymbols = exports.findOutOfScopeLocations = exports.getVariablesInScope = exports.getScopes = exports.getSymbols = exports.getClosestExpression = exports.stopParserWorker = exports.startParserWorker = undefined;
 
 var _devtoolsUtils = __webpack_require__(1363);
 
 const { WorkerDispatcher } = _devtoolsUtils.workerUtils; /* 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/>. */
 
 const dispatcher = new WorkerDispatcher();
@@ -17865,17 +17865,17 @@ const clearSymbols = exports.clearSymbol
 const clearScopes = exports.clearScopes = dispatcher.task("clearScopes");
 const clearASTs = exports.clearASTs = dispatcher.task("clearASTs");
 const getNextStep = exports.getNextStep = dispatcher.task("getNextStep");
 const getEmptyLines = exports.getEmptyLines = dispatcher.task("getEmptyLines");
 const hasSource = exports.hasSource = dispatcher.task("hasSource");
 const setSource = exports.setSource = dispatcher.task("setSource");
 const clearSources = exports.clearSources = dispatcher.task("clearSources");
 const hasSyntaxError = exports.hasSyntaxError = dispatcher.task("hasSyntaxError");
-const isReactComponent = exports.isReactComponent = dispatcher.task("isReactComponent");
+const getFramework = exports.getFramework = dispatcher.task("getFramework");
 const replaceOriginalVariableName = exports.replaceOriginalVariableName = dispatcher.task("replaceOriginalVariableName");
 
 /***/ }),
 /* 1366 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
@@ -19114,17 +19114,17 @@ class SearchInput extends _react.Compone
     }, _temp;
   }
 
   componentDidMount() {
     if (this.$input) {
       const input = this.$input;
       input.focus();
       if (input.value != "") {
-        input.setSelectionRange(input.value.length + 1, input.value.length + 1);
+        input.select();
       }
     }
   }
 
   renderSvg() {
     if (this.shouldShowErrorEmoji()) {
       return _react2.default.createElement(_Svg2.default, { name: "sad-face" });
     }
@@ -19157,53 +19157,66 @@ class SearchInput extends _react.Compone
       placeholder,
       summaryMsg,
       onChange,
       onKeyDown,
       onKeyUp,
       onFocus,
       onBlur,
       handleClose,
-      size
+      size,
+      expanded,
+      selectedItemId
     } = this.props;
 
     const inputProps = {
       className: (0, _classnames2.default)({
         empty: this.shouldShowErrorEmoji()
       }),
       onChange,
       onKeyDown,
       onKeyUp,
       onFocus,
       onBlur,
+      "aria-autocomplete": "list",
+      "aria-controls": "result-list",
+      "aria-activedescendant": expanded && selectedItemId ? `${selectedItemId}-title` : "",
       placeholder,
       value: query,
       spellCheck: false,
       ref: c => this.$input = c
     };
 
     return _react2.default.createElement(
       "div",
-      { className: (0, _classnames2.default)("search-field", size) },
+      {
+        className: (0, _classnames2.default)("search-field", size),
+        role: "combobox",
+        "aria-haspopup": "listbox",
+        "aria-owns": "result-list",
+        "aria-expanded": expanded
+      },
       this.renderSvg(),
       _react2.default.createElement("input", inputProps),
       _react2.default.createElement(
         "div",
         { className: "summary" },
         summaryMsg || ""
       ),
       this.renderNav(),
       _react2.default.createElement(_Close2.default, { handleClick: handleClose, buttonClass: size })
     );
   }
 }
 
 SearchInput.defaultProps = {
   size: "",
-  showErrorEmoji: true
+  showErrorEmoji: true,
+  expanded: false,
+  selectedItemId: ""
 };
 exports.default = SearchInput;
 
 /***/ }),
 /* 1380 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -20441,46 +20454,58 @@ var _extends = Object.assign || function
 exports.getPauseReason = getPauseReason;
 exports.isStepping = isStepping;
 exports.isPaused = isPaused;
 exports.isEvaluatingExpression = isEvaluatingExpression;
 exports.getPopupObjectProperties = getPopupObjectProperties;
 exports.getIsWaitingOnBreak = getIsWaitingOnBreak;
 exports.getShouldPauseOnExceptions = getShouldPauseOnExceptions;
 exports.getShouldIgnoreCaughtExceptions = getShouldIgnoreCaughtExceptions;
+exports.getCanRewind = getCanRewind;
 exports.getFrames = getFrames;
+exports.getGeneratedFrameScope = getGeneratedFrameScope;
 exports.getFrameScope = getFrameScope;
 exports.getSelectedScope = getSelectedScope;
-exports.getScopes = getScopes;
 exports.getSelectedFrameId = getSelectedFrameId;
 exports.getTopFrame = getTopFrame;
 exports.getDebuggeeUrl = getDebuggeeUrl;
 exports.getChromeScopes = getChromeScopes;
 
 var _reselect = __webpack_require__(993);
 
+var _devtoolsSourceMap = __webpack_require__(1360);
+
 var _prefs = __webpack_require__(226);
 
+var _sources = __webpack_require__(1369);
+
 const State = exports.State = () => ({
   why: null,
   isWaitingOnBreak: false,
   frames: undefined,
   selectedFrameId: undefined,
-  frameScopes: {},
+  frameScopes: {
+    generated: {},
+    original: {}
+  },
   loadedObjects: {},
   shouldPauseOnExceptions: _prefs.prefs.pauseOnExceptions,
   shouldIgnoreCaughtExceptions: _prefs.prefs.ignoreCaughtExceptions,
+  canRewind: false,
   debuggeeUrl: "",
   command: ""
 });
 
 const emptyPauseState = {
   pause: null,
   frames: null,
-  frameScopes: {},
+  frameScopes: {
+    generated: {},
+    original: {}
+  },
   selectedFrameId: null,
   loadedObjects: {}
 };
 
 function update(state = State(), action) {
   switch (action.type) {
     case "PAUSED":
       {
@@ -20491,34 +20516,62 @@ function update(state = State(), action)
         loadedObjects.forEach(obj => {
           objectMap[obj.value.objectId] = obj;
         });
 
         return _extends({}, state, {
           isWaitingOnBreak: false,
           selectedFrameId,
           frames,
-          frameScopes: {},
+          frameScopes: _extends({}, emptyPauseState.frameScopes),
           loadedObjects: objectMap,
           why
         });
       }
 
     case "MAP_FRAMES":
       {
         return _extends({}, state, { frames: action.frames });
       }
 
     case "ADD_SCOPES":
+      {
+        const { frame, status, value } = action;
+        const selectedFrameId = frame.id;
+
+        const generated = _extends({}, state.frameScopes.generated, {
+          [selectedFrameId]: {
+            pending: status !== "done",
+            scope: value
+          }
+        });
+        return _extends({}, state, {
+          frameScopes: _extends({}, state.frameScopes, {
+            generated
+          })
+        });
+      }
+
     case "MAP_SCOPES":
-      const { frame, scopes } = action;
-      const selectedFrameId = frame.id;
-
-      const frameScopes = _extends({}, state.frameScopes, { [selectedFrameId]: scopes });
-      return _extends({}, state, { frameScopes });
+      {
+        const { frame, status, value } = action;
+        const selectedFrameId = frame.id;
+
+        const original = _extends({}, state.frameScopes.original, {
+          [selectedFrameId]: {
+            pending: status !== "done",
+            scope: value
+          }
+        });
+        return _extends({}, state, {
+          frameScopes: _extends({}, state.frameScopes, {
+            original
+          })
+        });
+      }
 
     case "BREAK_ON_NEXT":
       return _extends({}, state, { isWaitingOnBreak: true });
 
     case "SELECT_FRAME":
       return _extends({}, state, {
         selectedFrameId: action.frame.id
       });
@@ -20530,17 +20583,20 @@ function update(state = State(), action)
 
       return _extends({}, state, {
         loadedObjects: _extends({}, state.loadedObjects, {
           [action.objectId]: action.properties
         })
       });
 
     case "CONNECT":
-      return _extends({}, State(), { debuggeeUrl: action.url });
+      return _extends({}, State(), {
+        debuggeeUrl: action.url,
+        canRewind: action.canRewind
+      });
 
     case "PAUSE_ON_EXCEPTIONS":
       const { shouldPauseOnExceptions, shouldIgnoreCaughtExceptions } = action;
 
       _prefs.prefs.pauseOnExceptions = shouldPauseOnExceptions;
       _prefs.prefs.ignoreCaughtExceptions = shouldIgnoreCaughtExceptions;
 
       return _extends({}, state, {
@@ -20610,36 +20666,52 @@ function getIsWaitingOnBreak(state) {
 function getShouldPauseOnExceptions(state) {
   return state.pause.shouldPauseOnExceptions;
 }
 
 function getShouldIgnoreCaughtExceptions(state) {
   return state.pause.shouldIgnoreCaughtExceptions;
 }
 
+function getCanRewind(state) {
+  return state.pause.canRewind;
+}
+
 function getFrames(state) {
   return state.pause.frames;
 }
 
-function getFrameScope(state, frameId) {
+function getGeneratedFrameScope(state, frameId) {
   if (!frameId) {
     return null;
   }
 
-  return state.pause.frameScopes[frameId];
+  return state.pause.frameScopes.generated[frameId];
+}
+
+function getFrameScope(state, sourceId, frameId) {
+  if (!frameId || !sourceId) {
+    return null;
+  }
+
+  const isGenerated = (0, _devtoolsSourceMap.isGeneratedId)(sourceId);
+  const original = state.pause.frameScopes.original[frameId];
+
+  if (!isGenerated && original && (original.pending || original.scope)) {
+    return original;
+  }
+
+  return state.pause.frameScopes.generated[frameId];
 }
 
 function getSelectedScope(state) {
+  const sourceRecord = (0, _sources.getSelectedSource)(state);
   const frameId = getSelectedFrameId(state);
-  return getFrameScope(state, frameId);
-}
-
-function getScopes(state) {
-  const selectedFrameId = getSelectedFrameId(state);
-  return state.pause.frameScopes[selectedFrameId];
+  const { scope } = getFrameScope(state, sourceRecord && sourceRecord.get("id"), frameId) || {};
+  return scope || null;
 }
 
 function getSelectedFrameId(state) {
   return state.pause.selectedFrameId;
 }
 
 function getTopFrame(state) {
   const frames = getFrames(state);
@@ -21290,22 +21362,22 @@ function setSourceMetaData(sourceId) {
       return;
     }
 
     const source = sourceRecord.toJS();
     if (!source.text || source.isWasm) {
       return;
     }
 
-    const isReactComp = await (0, _parser.isReactComponent)(source.id);
+    const framework = await (0, _parser.getFramework)(source.id);
     dispatch({
       type: "SET_SOURCE_METADATA",
       sourceId: source.id,
       sourceMetaData: {
-        isReactComponent: isReactComp
+        framework
       }
     });
   };
 } /* 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/>. */
 
 function setSymbols(sourceId) {
@@ -21668,17 +21740,17 @@ function buildQuery(originalQuery, modif
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.Modal = undefined;
+exports.Modal = exports.transitionTimeout = undefined;
 exports.default = Slide;
 
 var _propTypes = __webpack_require__(20);
 
 var _propTypes2 = _interopRequireDefault(_propTypes);
 
 var _react = __webpack_require__(0);
 
@@ -21691,16 +21763,20 @@ var _classnames2 = _interopRequireDefaul
 var _Transition = __webpack_require__(333);
 
 var _Transition2 = _interopRequireDefault(_Transition);
 
 __webpack_require__(1303);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
+const transitionTimeout = exports.transitionTimeout = 175; /* 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/>. */
+
 class Modal extends _react2.default.Component {
   constructor(...args) {
     var _temp;
 
     return _temp = super(...args), this.onClick = e => {
       e.stopPropagation();
     }, _temp;
   }
@@ -21718,33 +21794,30 @@ class Modal extends _react2.default.Comp
           onClick: this.onClick
         },
         this.props.children
       )
     );
   }
 }
 
-exports.Modal = Modal; /* 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/>. */
-
+exports.Modal = Modal;
 Modal.contextTypes = {
   shortcuts: _propTypes2.default.object
 };
 
 function Slide({
   in: inProp,
   children,
   additionalClass,
   handleClose
 }) {
   return _react2.default.createElement(
     _Transition2.default,
-    { "in": inProp, timeout: 175, appear: true },
+    { "in": inProp, timeout: transitionTimeout, appear: true },
     status => _react2.default.createElement(
       Modal,
       {
         status: status,
         additionalClass: additionalClass,
         handleClose: handleClose
       },
       children
@@ -22016,31 +22089,45 @@ function getURL(sourceUrl, debuggeeUrl =
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.scrollList = undefined;
 
 var _devtoolsConfig = __webpack_require__(1355);
 
-function scrollList(resultList, index) {
+var _Modal = __webpack_require__(1403);
+
+/* 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/>. */
+
+function scrollList(resultList, index, delayed = false) {
   if (!resultList.hasOwnProperty(index)) {
     return;
   }
 
   const resultEl = resultList[index];
 
-  if ((0, _devtoolsConfig.isFirefox)()) {
-    resultEl.scrollIntoView({ block: "center", behavior: "smooth" });
-  } else {
-    chromeScrollList(resultEl, index);
-  }
-} /* 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/>. */
+  const scroll = () => {
+    if ((0, _devtoolsConfig.isFirefox)()) {
+      resultEl.scrollIntoView({ block: "center", behavior: "smooth" });
+    } else {
+      chromeScrollList(resultEl, index);
+    }
+  };
+
+  if (delayed) {
+    // Wait for Modal Transition timeout before scrolling to resultEl.
+    setTimeout(scroll, _Modal.transitionTimeout + 10);
+    return;
+  }
+
+  scroll();
+}
 
 function chromeScrollList(elem, index) {
   const resultsEl = elem.parentNode;
   if (!resultsEl || resultsEl.children.length === 0) {
     return;
   }
 
   const resultsHeight = resultsEl.clientHeight;
@@ -23788,16 +23875,19 @@ exports.createPause = createPause;
 exports.createBreakpointLocation = createBreakpointLocation;
 /* 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/>. */
 
 // This module converts Firefox specific types to the generic types
 
 function createFrame(frame) {
+  if (!frame) {
+    return null;
+  }
   let title;
   if (frame.type == "call") {
     const c = frame.callee;
     title = c.name || c.userDisplayName || c.displayName || L10N.getStr("anonymous");
   } else {
     title = `(${frame.type})`;
   }
   const location = {
@@ -25040,53 +25130,62 @@ class ResultList extends _react.Componen
 
   renderListItem(item, index) {
     const { selectItem, selected } = this.props;
     const props = {
       onClick: event => selectItem(event, item, index),
       key: `${item.id}${item.value}${index}`,
       ref: String(index),
       title: item.value,
+      "aria-labelledby": `${item.id}-title`,
+      "aria-describedby": `${item.id}-subtitle`,
+      role: "option",
       className: (0, _classnames2.default)("result-item", {
         selected: index === selected
       })
     };
 
     return _react2.default.createElement(
       "li",
       props,
       _react2.default.createElement(
         "div",
-        { className: "title" },
+        { id: `${item.id}-title`, className: "title" },
         item.title
       ),
       _react2.default.createElement(
         "div",
-        { className: "subtitle" },
+        { id: `${item.id}-subtitle`, className: "subtitle" },
         item.subtitle
       )
     );
   }
 
   render() {
-    const { size, items } = this.props;
+    const { size, items, role } = this.props;
 
     return _react2.default.createElement(
       "ul",
-      { className: (0, _classnames2.default)("result-list", size) },
+      {
+        className: (0, _classnames2.default)("result-list", size),
+        id: "result-list",
+        role: role,
+        "aria-live": "polite"
+      },
       items.map(this.renderListItem)
     );
   }
 }
 exports.default = ResultList; /* 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/>. */
 
 ResultList.defaultProps = {
-  size: "small"
+  size: "small",
+  role: "listbox"
 };
 
 /***/ }),
 /* 1446 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
@@ -29240,17 +29339,18 @@ async function onConnect(connection, act
 
   // In Firefox, we need to initially request all of the sources. This
   // usually fires off individual `newSource` notifications as the
   // debugger finds them, but there may be existing sources already in
   // the debugger (if it's paused already, or if loading the page from
   // bfcache) so explicity fire `newSource` events for all returned
   // sources.
   const sources = await _commands.clientCommands.fetchSources();
-  await actions.connect(tabTarget.url);
+  const traits = tabTarget.activeTab ? tabTarget.activeTab.traits : null;
+  await actions.connect(tabTarget.url, traits && traits.canRewind);
   await actions.newSources(sources);
 
   // If the threadClient is already paused, make sure to show a
   // paused state.
   const pausedPacket = threadClient.getLastPausePacket();
   if (pausedPacket) {
     _events.clientEvents.paused("paused", pausedPacket);
   }
@@ -29317,16 +29417,40 @@ function stepOver() {
 }
 
 function stepOut() {
   return new Promise(resolve => {
     threadClient.stepOut(resolve);
   });
 }
 
+function rewind() {
+  return new Promise(resolve => {
+    threadClient.rewind(resolve);
+  });
+}
+
+function reverseStepIn() {
+  return new Promise(resolve => {
+    threadClient.reverseStepIn(resolve);
+  });
+}
+
+function reverseStepOver() {
+  return new Promise(resolve => {
+    threadClient.reverseStepOver(resolve);
+  });
+}
+
+function reverseStepOut() {
+  return new Promise(resolve => {
+    threadClient.reverseStepOut(resolve);
+  });
+}
+
 function breakOnNext() {
   return threadClient.breakOnNext();
 }
 
 function sourceContents(sourceId) {
   const sourceClient = threadClient.source({ actor: sourceId });
   return sourceClient.source();
 }
@@ -29513,16 +29637,20 @@ const clientCommands = {
   blackBox,
   interrupt,
   eventListeners,
   pauseGrip,
   resume,
   stepIn,
   stepOut,
   stepOver,
+  rewind,
+  reverseStepIn,
+  reverseStepOut,
+  reverseStepOver,
   breakOnNext,
   sourceContents,
   getBreakpointByLocation,
   setBreakpoint,
   removeBreakpoint,
   setBreakpointCondition,
   evaluate,
   evaluateInFrame,
@@ -30626,17 +30754,20 @@ class App extends _react.Component {
   }
 
   render() {
     const { quickOpenEnabled } = this.props;
     return _react2.default.createElement(
       "div",
       { className: "debugger" },
       this.isHorizontal() ? this.renderHorizontalLayout() : this.renderVerticalLayout(),
-      quickOpenEnabled === true && _react2.default.createElement(_QuickOpenModal2.default, null),
+      quickOpenEnabled === true && _react2.default.createElement(_QuickOpenModal2.default, {
+        shortcutsModalEnabled: this.state.shortcutsModalEnabled,
+        toggleShortcutsModal: () => this.toggleShortcutsModal()
+      }),
       this.renderShortcutsModal()
     );
   }
 }
 
 App.childContextTypes = { shortcuts: _propTypes2.default.object };
 
 function mapStateToProps(state) {
@@ -31387,20 +31518,20 @@ function navigate(url) {
   _sourceQueue2.default.clear();
 
   return {
     type: "NAVIGATE",
     url
   };
 }
 
-function connect(url) {
+function connect(url, canRewind) {
   return async function ({ dispatch }) {
     await dispatch((0, _debuggee.updateWorkers)());
-    dispatch({ type: "CONNECT", url });
+    dispatch({ type: "CONNECT", url, canRewind });
   };
 }
 
 /**
  * @memberof actions/navigation
  * @static
  */
 function navigated() {
@@ -31739,17 +31870,18 @@ class ShortcutsModal extends _react.Comp
 
   renderSearchShortcuts() {
     return _react2.default.createElement(
       "ul",
       { className: "shortcuts-list" },
       this.renderShorcutItem(L10N.getStr("shortcuts.fileSearch"), (0, _text.formatKeyShortcut)(L10N.getStr("sources.search.key2"))),
       this.renderShorcutItem(L10N.getStr("shortcuts.searchAgain"), (0, _text.formatKeyShortcut)(L10N.getStr("sourceSearch.search.again.key2"))),
       this.renderShorcutItem(L10N.getStr("shortcuts.projectSearch"), (0, _text.formatKeyShortcut)(L10N.getStr("projectTextSearch.key"))),
-      this.renderShorcutItem(L10N.getStr("shortcuts.functionSearch"), (0, _text.formatKeyShortcut)(L10N.getStr("functionSearch.key")))
+      this.renderShorcutItem(L10N.getStr("shortcuts.functionSearch"), (0, _text.formatKeyShortcut)(L10N.getStr("functionSearch.key"))),
+      this.renderShorcutItem(L10N.getStr("shortcuts.gotoLine"), (0, _text.formatKeyShortcut)(L10N.getStr("gotoLineModal.key")))
     );
   }
 
   renderShortcutsContent() {
     return _react2.default.createElement(
       "div",
       {
         className: (0, _classnames2.default)("shortcuts-content", this.props.additionalClass)
@@ -32154,17 +32286,16 @@ const svg = {
   "case-match": __webpack_require__(351),
   choo: __webpack_require__(1290),
   close: __webpack_require__(352),
   coffeescript: __webpack_require__(2250),
   dojo: __webpack_require__(806),
   domain: __webpack_require__(353),
   file: __webpack_require__(354),
   folder: __webpack_require__(355),
-  function: __webpack_require__(1787),
   globe: __webpack_require__(356),
   javascript: __webpack_require__(2251),
   jquery: __webpack_require__(999),
   underscore: __webpack_require__(1117),
   lodash: __webpack_require__(1118),
   ember: __webpack_require__(1119),
   vuejs: __webpack_require__(1174),
   "magnifying-glass": __webpack_require__(357),
@@ -33531,30 +33662,30 @@ var _redux = __webpack_require__(3);
 var _reactRedux = __webpack_require__(1189);
 
 var _actions = __webpack_require__(1354);
 
 var _actions2 = _interopRequireDefault(_actions);
 
 var _selectors = __webpack_require__(1352);
 
-var _Svg = __webpack_require__(1359);
-
-var _Svg2 = _interopRequireDefault(_Svg);
-
 __webpack_require__(1319);
 
 var _PreviewFunction = __webpack_require__(1446);
 
 var _PreviewFunction2 = _interopRequireDefault(_PreviewFunction);
 
 var _lodash = __webpack_require__(2);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
+/* 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/>. */
+
 class Outline extends _react.Component {
   selectItem(location) {
     const { selectedSource, selectLocation } = this.props;
     if (!selectedSource) {
       return;
     }
     const selectedSourceId = selectedSource.get("id");
     const startLine = location.start.line;
@@ -33574,77 +33705,77 @@ class Outline extends _react.Component {
 
     return _react2.default.createElement(
       "li",
       {
         key: `${name}:${location.start.line}:${location.start.column}`,
         className: "outline-list__element",
         onClick: () => this.selectItem(location)
       },
-      _react2.default.createElement(_Svg2.default, { name: "function" }),
+      _react2.default.createElement(
+        "span",
+        { className: "outline-list__element-icon" },
+        "\u03BB"
+      ),
       _react2.default.createElement(_PreviewFunction2.default, { func: { name, parameterNames } })
     );
   }
 
-  renderClassFunctions(functions) {
-    const classFunctions = functions.filter(func => func.name != "anonymous" && !!func.klass);
-
-    if (classFunctions.length == 0) {
+  renderClassFunctions(klass, functions) {
+    if (klass == null || functions.length == 0) {
       return null;
     }
 
-    const klass = classFunctions[0].klass;
-    const klassFunc = functions.find(func => func.name === klass);
-
-    return _react2.default.createElement(
-      "div",
-      { className: "outline-list__class" },
+    const classFunc = functions.find(func => func.name === klass);
+    const classFunctions = functions.filter(func => func.klass === klass);
+
+    return _react2.default.createElement(
+      "div",
+      { className: "outline-list__class", key: klass },
       _react2.default.createElement(
         "h2",
         null,
-        klassFunc ? this.renderFunction(klassFunc) : klass
+        classFunc ? this.renderFunction(classFunc) : `class ${klass}`
       ),
       _react2.default.createElement(
         "ul",
         { className: "outline-list__class-list" },
         classFunctions.map(func => this.renderFunction(func))
       )
     );
   }
 
   renderFunctions(functions) {
     const classes = (0, _lodash.uniq)(functions.map(func => func.klass));
-
     const namedFunctions = functions.filter(func => func.name != "anonymous" && !func.klass && !classes.includes(func.name));
 
+    const classFunctions = functions.filter(func => func.name != "anonymous" && !!func.klass);
+
     return _react2.default.createElement(
       "ul",
       { className: "outline-list" },
       namedFunctions.map(func => this.renderFunction(func)),
-      this.renderClassFunctions(functions)
+      classes.map(klass => this.renderClassFunctions(klass, classFunctions))
     );
   }
 
   render() {
     const { symbols } = this.props;
 
     const symbolsToDisplay = symbols.functions.filter(func => func.name != "anonymous");
 
     return _react2.default.createElement(
       "div",
       { className: "outline" },
       symbolsToDisplay.length > 0 ? this.renderFunctions(symbols.functions) : this.renderPlaceholder()
     );
   }
 }
 
-exports.Outline = Outline; /* 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/>. */
-
+exports.Outline = Outline;
 exports.default = (0, _reactRedux.connect)(state => {
   const selectedSource = (0, _selectors.getSelectedSource)(state);
   return {
     symbols: (0, _selectors.getSymbols)(state, selectedSource && selectedSource.toJS()),
     selectedSource
   };
 }, dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(Outline);
 
@@ -34144,16 +34275,17 @@ const cssVars = {
  * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
 
 class Editor extends _react.PureComponent {
   constructor(props) {
     super(props);
 
     this.onToggleBreakpoint = (key, e) => {
       e.preventDefault();
+      e.stopPropagation();
       const { selectedSource, conditionalPanelLine } = this.props;
 
       if (!selectedSource) {
         return;
       }
 
       const line = this.getCurrentLine();
 
@@ -34162,16 +34294,23 @@ class Editor extends _react.PureComponen
       } else if (!conditionalPanelLine) {
         this.props.toggleBreakpoint(line);
       } else {
         this.toggleConditionalPanel(line);
         this.props.toggleBreakpoint(line);
       }
     };
 
+    this.onToggleConditionalPanel = (key, e) => {
+      e.stopPropagation();
+      e.preventDefault();
+      const line = this.getCurrentLine();
+      this.toggleConditionalPanel(line);
+    };
+
     this.onEscape = (key, e) => {
       if (!this.state.editor) {
         return;
       }
 
       const { codeMirror } = this.state.editor;
       if (codeMirror.listSelections().length > 1) {
         codeMirror.execCommand("singleSelection");
@@ -34227,20 +34366,16 @@ class Editor extends _react.PureComponen
 
     this.toggleConditionalPanel = line => {
       const {
         conditionalPanelLine,
         closeConditionalPanel,
         openConditionalPanel
       } = this.props;
 
-      if (!line || isNaN(line)) {
-        line = this.getCurrentLine();
-      }
-
       if (conditionalPanelLine) {
         return closeConditionalPanel();
       }
 
       return openConditionalPanel(line);
     };
 
     this.closeConditionalPanel = () => {
@@ -34323,17 +34458,17 @@ class Editor extends _react.PureComponen
 
     const { selectedSource } = this.props;
     const { shortcuts } = this.context;
 
     const searchAgainKey = L10N.getStr("sourceSearch.search.again.key2");
     const searchAgainPrevKey = L10N.getStr("sourceSearch.search.againPrev.key2");
 
     shortcuts.on(L10N.getStr("toggleBreakpoint.key"), this.onToggleBreakpoint);
-    shortcuts.on(L10N.getStr("toggleCondPanel.key"), this.toggleConditionalPanel);
+    shortcuts.on(L10N.getStr("toggleCondPanel.key"), this.onToggleConditionalPanel);
     shortcuts.on("Esc", this.onEscape);
     shortcuts.on(searchAgainPrevKey, this.onSearchAgain);
     shortcuts.on(searchAgainKey, this.onSearchAgain);
 
     (0, _editor.updateDocument)(editor, selectedSource);
   }
 
   componentWillUnmount() {
@@ -40167,64 +40302,64 @@ Object.defineProperty(exports, "__esModu
 var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; /* 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/>. */
 
 var _react = __webpack_require__(0);
 
 var _react2 = _interopRequireDefault(_react);
 
+var _redux = __webpack_require__(3);
+
+var _reactRedux = __webpack_require__(1189);
+
 var _immutable = __webpack_require__(146);
 
 var I = _interopRequireWildcard(_immutable);
 
-var _reactRedux = __webpack_require__(1189);
-
-var _reselect = __webpack_require__(993);
-
-var _redux = __webpack_require__(3);
-
-var _prefs = __webpack_require__(226);
-
 var _classnames = __webpack_require__(175);
 
 var _classnames2 = _interopRequireDefault(_classnames);
 
+var _reselect = __webpack_require__(993);
+
+var _lodash = __webpack_require__(2);
+
 var _actions = __webpack_require__(1354);
 
 var _actions2 = _interopRequireDefault(_actions);
 
-var _selectors = __webpack_require__(1352);
-
-var _breakpoint = __webpack_require__(1364);
-
-var _utils = __webpack_require__(1366);
-
-var _source = __webpack_require__(1356);
-
-var _pause = __webpack_require__(1400);
-
 var _Close = __webpack_require__(1374);
 
 var _Close2 = _interopRequireDefault(_Close);
 
-__webpack_require__(1334);
-
-var _lodash = __webpack_require__(2);
+var _utils = __webpack_require__(1366);
+
+var _prefs = __webpack_require__(226);
+
+var _source = __webpack_require__(1356);
+
+var _selectors = __webpack_require__(1352);
+
+var _pause = __webpack_require__(1400);
+
+var _breakpoint = __webpack_require__(1364);
 
 var _BreakpointsContextMenu = __webpack_require__(1805);
 
 var _BreakpointsContextMenu2 = _interopRequireDefault(_BreakpointsContextMenu);
 
+__webpack_require__(1334);
+
 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 function isCurrentlyPausedAtBreakpoint(frame, why, breakpoint) {
-  if (!(0, _pause.isInterrupted)(why)) {
+  if (!frame || !(0, _pause.isInterrupted)(why)) {
     return false;
   }
 
   const bpId = (0, _breakpoint.makeLocationId)(breakpoint.location);
   const pausedId = (0, _breakpoint.makeLocationId)(frame.location);
   return bpId === pausedId;
 }
 
@@ -41351,16 +41486,17 @@ var _CommandBarButton = __webpack_requir
 var _CommandBarButton2 = _interopRequireDefault(_CommandBarButton);
 
 __webpack_require__(1295);
 
 var _devtoolsModules = __webpack_require__(1376);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
+/* -*- indent-tabs-mode: nil; js-indent-level: 2; js-indent-level: 2 -*- */
 /* 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/>. */
 
 const { appinfo } = _devtoolsModules.Services;
 
 const isMacOS = appinfo.OS === "Darwin";
 
@@ -41467,17 +41603,17 @@ class CommandBar extends _react.Componen
 
   renderPauseButton() {
     const { isPaused, breakOnNext, isWaitingOnBreak } = this.props;
 
     if (isPaused) {
       return debugBtn(this.props.resume, "resume", "active", L10N.getFormatStr("resumeButtonTooltip", formatKey("resume")));
     }
 
-    if (_prefs.features.removeCommandBarOptions) {
+    if (_prefs.features.removeCommandBarOptions && !this.props.canRewind) {
       return;
     }
 
     if (isWaitingOnBreak) {
       return debugBtn(null, "pause", "disabled", L10N.getStr("pausePendingButtonTooltip"), true);
     }
 
     return debugBtn(breakOnNext, "pause", "active", L10N.getFormatStr("pauseButtonTooltip", formatKey("pause")));
@@ -41506,41 +41642,60 @@ class CommandBar extends _react.Componen
 
     if (shouldPauseOnExceptions && shouldIgnoreCaughtExceptions) {
       return debugBtn(() => pauseOnExceptions(true, false), "pause-exceptions", "uncaught enabled", L10N.getStr("pauseOnUncaughtExceptions"), false, true);
     }
 
     return debugBtn(() => pauseOnExceptions(false, false), "pause-exceptions", "all enabled", L10N.getStr("pauseOnExceptions"), false, true);
   }
 
+  renderRewindButton() {
+    if (!this.props.canRewind || !this.props.isPaused) {
+      return;
+    }
+
+    return debugBtn(this.props.rewind, "rewind", "active", "Rewind Execution");
+  }
+
+  renderReverseStepButtons() {
+    if (!this.props.canRewind || !this.props.isPaused) {
+      return;
+    }
+
+    return [debugBtn(this.props.reverseStepOver, "reverseStepOver", "active", "Reverse step over"), debugBtn(this.props.reverseStepIn, "reverseStepIn", "active", "Reverse step in"), debugBtn(this.props.reverseStepOut, "reverseStepOut", "active", "Reverse step out")];
+  }
+
   render() {
     return _react2.default.createElement(
       "div",
       {
         className: (0, _classnames2.default)("command-bar", {
           vertical: !this.props.horizontal
         })
       },
       this.renderPauseButton(),
+      this.renderRewindButton(),
       this.renderStepButtons(),
-      this.renderPauseOnExceptions()
+      this.renderPauseOnExceptions(),
+      this.renderReverseStepButtons()
     );
   }
 }
 
 CommandBar.contextTypes = {
   shortcuts: _propTypes2.default.object
 };
 
 exports.default = (0, _reactRedux.connect)(state => {
   return {
     isPaused: (0, _selectors.isPaused)(state),
     isWaitingOnBreak: (0, _selectors.getIsWaitingOnBreak)(state),
     shouldPauseOnExceptions: (0, _selectors.getShouldPauseOnExceptions)(state),
-    shouldIgnoreCaughtExceptions: (0, _selectors.getShouldIgnoreCaughtExceptions)(state)
+    shouldIgnoreCaughtExceptions: (0, _selectors.getShouldIgnoreCaughtExceptions)(state),
+    canRewind: (0, _selectors.getCanRewind)(state)
   };
 }, dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(CommandBar);
 
 /***/ }),
 /* 1609 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -41895,17 +42050,17 @@ class Scopes extends _react.PureComponen
     if (isPausedChanged || selectedFrameChanged || frameScopesChanged) {
       this.setState({
         scopes: (0, _scopes.getScopes)(nextProps.why, nextProps.selectedFrame, nextProps.frameScopes)
       });
     }
   }
 
   render() {
-    const { isPaused } = this.props;
+    const { isPaused, isLoading } = this.props;
     const { scopes } = this.state;
 
     if (scopes) {
       return _react2.default.createElement(
         "div",
         { className: "pane scopes-list" },
         _react2.default.createElement(_devtoolsReps.ObjectInspector, {
           roots: scopes,
@@ -41913,36 +42068,50 @@ class Scopes extends _react.PureComponen
           autoExpandDepth: 1,
           disableWrap: true,
           disabledFocus: true,
           dimTopLevelWindow: true,
           createObjectClient: grip => (0, _firefox.createObjectClient)(grip)
         })
       );
     }
+
+    let stateText = L10N.getStr("scopes.notPaused");
+    if (isPaused) {
+      if (isLoading) {
+        stateText = L10N.getStr("loadingText");
+      } else {
+        stateText = L10N.getStr("scopes.notAvailable");
+      }
+    }
+
     return _react2.default.createElement(
       "div",
       { className: "pane scopes-list" },
       _react2.default.createElement(
         "div",
         { className: "pane-info" },
-        isPaused ? L10N.getStr("scopes.notAvailable") : L10N.getStr("scopes.notPaused")
+        stateText
       )
     );
   }
 } /* 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/>. */
 
 exports.default = (0, _reactRedux.connect)(state => {
   const selectedFrame = (0, _selectors.getSelectedFrame)(state);
-  const frameScopes = selectedFrame ? (0, _selectors.getFrameScope)(state, selectedFrame.id) : null;
+  const selectedSource = (0, _selectors.getSelectedSource)(state);
+
+  const { scope: frameScopes, pending } = (0, _selectors.getFrameScope)(state, selectedSource && selectedSource.get("id"), selectedFrame.id) || { pending: false };
+
   return {
     selectedFrame,
     isPaused: (0, _selectors.isPaused)(state),
+    isLoading: pending,
     why: (0, _selectors.getPauseReason)(state),
     frameScopes: frameScopes
   };
 }, dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(Scopes);
 
 /***/ }),
 /* 1612 */,
 /* 1613 */
@@ -42404,51 +42573,81 @@ var _extends = Object.assign || function
 exports.mapScopes = mapScopes;
 
 var _selectors = __webpack_require__(1352);
 
 var _loadSourceText = __webpack_require__(1435);
 
 var _parser = __webpack_require__(1365);
 
+var _promise = __webpack_require__(1653);
+
+var _prefs = __webpack_require__(226);
+
+var _devtoolsSourceMap = __webpack_require__(1360);
+
+function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
+
 function mapScopes(scopes, frame) {
   return async function ({ dispatch, getState, client, sourceMaps }) {
+    const generatedSourceRecord = (0, _selectors.getSource)(getState(), frame.generatedLocation.sourceId);
+
     const sourceRecord = (0, _selectors.getSource)(getState(), frame.location.sourceId);
-    await dispatch((0, _loadSourceText.loadSourceText)(sourceRecord));
-    const source = sourceRecord.toJS();
-
-    const originalAstScopes = await (0, _parser.getScopes)(frame.location);
-    const generatedAstScopes = await (0, _parser.getScopes)(frame.generatedLocation);
-
-    if (!originalAstScopes || !generatedAstScopes) {
-      return;
-    }
-
-    const generatedAstBindings = buildGeneratedBindingList(scopes, generatedAstScopes);
-
-    const mappedOriginalScopes = await Promise.all(Array.from(originalAstScopes, async item => {
-      const generatedBindings = {};
-
-      await Promise.all(Object.keys(item.bindings).map(async name => {
-        generatedBindings[name] = await findGeneratedBinding(sourceMaps, source, name, item.bindings[name], generatedAstBindings);
-      }));
-
-      return _extends({}, item, {
-        generatedBindings
-      });
-    }));
-
-    const mappedScopes = generateClientScope(scopes, mappedOriginalScopes);
+
+    const shouldMapScopes = _prefs.features.mapScopes && !generatedSourceRecord.get("isWasm") && !sourceRecord.get("isPrettyPrinted") && !(0, _devtoolsSourceMap.isGeneratedId)(frame.location.sourceId);
 
     dispatch({
       type: "MAP_SCOPES",
       frame,
-      scopes: mappedScopes
-    });
-  };
+      [_promise.PROMISE]: async function () {
+        if (!shouldMapScopes) {
+          return null;
+        }
+
+        await dispatch((0, _loadSourceText.loadSourceText)(sourceRecord));
+
+        try {
+          return await buildMappedScopes(sourceRecord.toJS(), frame, (await scopes), sourceMaps);
+        } catch (e) {
+          return null;
+        }
+      }()
+    });
+  };
+}
+
+async function buildMappedScopes(source, frame, scopes, sourceMaps) {
+  const originalAstScopes = await (0, _parser.getScopes)(frame.location);
+  const generatedAstScopes = await (0, _parser.getScopes)(frame.generatedLocation);
+
+  if (!originalAstScopes || !generatedAstScopes) {
+    return null;
+  }
+
+  const generatedAstBindings = buildGeneratedBindingList(scopes, generatedAstScopes, frame.this);
+
+  const mappedOriginalScopes = await Promise.all(Array.from(originalAstScopes, async item => {
+    const generatedBindings = {};
+
+    await Promise.all(Object.keys(item.bindings).map(async name => {
+      const binding = item.bindings[name];
+
+      const result = await findGeneratedBinding(sourceMaps, source, name, binding, generatedAstBindings);
+
+      if (result) {
+        generatedBindings[name] = result;
+      }
+    }));
+
+    return _extends({}, item, {
+      generatedBindings
+    });
+  }));
+
+  return generateClientScope(scopes, mappedOriginalScopes);
 }
 
 function generateClientScope(scopes, originalScopes) {
   // Pull the root object scope and root lexical scope to reuse them in
   // our mapped scopes. This assumes that file file being processed is
   // a CommonJS or ES6 module, which might not be ideal. Potentially
   let globalLexicalScope = null;
   for (let s = scopes; s.parent; s = s.parent) {
@@ -42457,82 +42656,112 @@ function generateClientScope(scopes, ori
   }
   if (!globalLexicalScope) {
     throw new Error("Assertion failure - there should always be a scope");
   }
 
   // Build a structure similar to the client's linked scope object using
   // the original AST scopes, but pulling in the generated bindings
   // linked to each scope.
-  const result = originalScopes.slice(0, -2).reverse().reduce((acc, orig, i) => _extends({
-    // Flow doesn't like casting 'parent'.
-    parent: acc,
-    actor: `originalActor${i}`,
-    type: orig.type,
-    bindings: {
-      arguments: [],
-      variables: orig.generatedBindings
-    }
-  }, orig.type === "function" ? {
-    function: {
-      displayName: orig.displayName
-    }
-  } : null, orig.type === "block" ? {
-    block: {
-      displayName: orig.displayName
-    }
-  } : null), globalLexicalScope);
+  const result = originalScopes.slice(0, -2).reverse().reduce((acc, orig, i) => {
+    const _orig$generatedBindin = orig.generatedBindings,
+          {
+      // The 'this' binding data we have is handled independently, so
+      // the binding data is not included here.
+      // eslint-disable-next-line no-unused-vars
+      this: _this
+    } = _orig$generatedBindin,
+          variables = _objectWithoutProperties(_orig$generatedBindin, ["this"]);
+
+    return _extends({
+      // Flow doesn't like casting 'parent'.
+      parent: acc,
+      actor: `originalActor${i}`,
+      type: orig.type,
+      bindings: {
+        arguments: [],
+        variables
+      }
+    }, orig.type === "function" ? {
+      function: {
+        displayName: orig.displayName
+      }
+    } : null, orig.type === "block" ? {
+      block: {
+        displayName: orig.displayName
+      }
+    } : null);
+  }, globalLexicalScope);
+
+  // The rendering logic in getScope 'this' bindings only runs on the current
+  // selected frame scope, so we pluck out the 'this' binding that was mapped,
+  // and put it in a special location
+  const thisScope = originalScopes.find(scope => scope.bindings.this);
+  if (thisScope) {
+    result.bindings.this = thisScope.generatedBindings.this || null;
+  }
 
   return result;
 }
 
 async function findGeneratedBinding(sourceMaps, source, name, originalBinding, generatedAstBindings) {
+  // If there are no references to the implicits, then we have no way to
+  // even attempt to map it back to the original since there is no location
+  // data to use. Bail out instead of just showing it as unmapped.
+  if (originalBinding.type === "implicit" && originalBinding.refs.length === 0) {
+    return null;
+  }
+
   const { declarations, refs } = originalBinding;
 
   const genContent = await declarations.concat(refs).reduce(async (acc, pos) => {
     const result = await acc;
     if (result) {
       return result;
     }
 
     const gen = await sourceMaps.getGeneratedLocation(pos.start, source);
+    const genEnd = await sourceMaps.getGeneratedLocation(pos.end, source);
+
+    // Since the map takes the closest location, sometimes mapping a
+    // binding's location can point at the start of a binding listed after
+    // it, so we need to make sure it maps to a location that actually has
+    // a size in order to avoid picking up the wrong descriptor.
+    if (gen.line === genEnd.line && gen.column === genEnd.column) {
+      return null;
+    }
 
     return generatedAstBindings.find(val => val.loc.start.line === gen.line && val.loc.start.column === gen.column);
   }, null);
 
-  if (genContent && !genContent.desc) {
+  if (genContent && genContent.desc) {
+    return genContent.desc;
+  } else if (genContent) {
+    // If there is no descriptor for 'this', then this is not the top-level
+    // 'this' that the server gave us a binding for, and we can just ignore it.
+    if (name === "this") {
+      return null;
+    }
+
     // If the location is found but the descriptor is not, then it
     // means that the server scope information didn't match the scope
     // information from the DevTools parsed scopes.
     return {
       configurable: false,
       enumerable: true,
       writable: false,
       value: {
         type: "unscoped",
         unscoped: true,
 
         // HACK: Until support for "unscoped" lands in devtools-reps,
         // this will make these show as (unavailable).
         missingArguments: true
       }
     };
-  } else if (genContent) {
-    // If `this` is just mapped back to the same `this`, then
-    // we don't need to do any mapping for it at all.
-    // if (name === "this" && !genContent.desc) return null;
-    if (name === "this" && genContent.name === "this") {
-      return null;
-    }
-
-    // If the location is found but the descriptor is not, then this
-    // there is a bug. TODO to maybe log when this happens or something?
-    // For now mark these with a special type, but we should
-    // technically flag them.
-    return genContent.desc;
   }
 
   // If no location mapping is found, then the map is bad, or
   // the map is okay but it original location is inside
   // of some scope, but the generated location is outside, leading
   // us to search for bindings that don't technically exist.
   return {
     configurable: false,
@@ -42544,28 +42773,45 @@ async function findGeneratedBinding(sour
 
       // HACK: Until support for "unmapped" lands in devtools-reps,
       // this will make these show as (unavailable).
       missingArguments: true
     }
   };
 }
 
-function buildGeneratedBindingList(scopes, generatedAstScopes) {
+function buildGeneratedBindingList(scopes, generatedAstScopes, thisBinding) {
   const clientScopes = [];
   for (let s = scopes; s; s = s.parent) {
     clientScopes.push(s);
   }
 
-  const generatedBindings = clientScopes.reverse().map((s, i) => ({
-    generated: generatedAstScopes[generatedAstScopes.length - 1 - i],
-    client: _extends({}, s, {
-      bindings: s.bindings ? Object.assign({}, ...s.bindings.arguments, s.bindings.variables) : {}
-    })
-  })).slice(2).reduce((acc, { client: { bindings }, generated }) => {
+  // The server's binding data doesn't include general 'this' binding
+  // information, so we manually inject the one 'this' binding we have into
+  // the normal binding data we are working with.
+  const frameThisOwner = generatedAstScopes.find(generated => "this" in generated.bindings);
+
+  const generatedBindings = clientScopes.reverse().map((s, i) => {
+    const generated = generatedAstScopes[generatedAstScopes.length - 1 - i];
+
+    const bindings = s.bindings ? Object.assign({}, ...s.bindings.arguments, s.bindings.variables) : {};
+
+    if (generated === frameThisOwner && thisBinding) {
+      bindings.this = {
+        value: thisBinding
+      };
+    }
+
+    return {
+      generated,
+      client: _extends({}, s, {
+        bindings
+      })
+    };
+  }).slice(2).reduce((acc, { client: { bindings }, generated }) => {
     // If the parser worker's result didn't match the client scopes,
     // there might not be a generated scope that matches.
     if (generated) {
       for (const name of Object.keys(generated.bindings)) {
         const { declarations, refs } = generated.bindings[name];
         for (const loc of declarations.concat(refs)) {
           acc.push({
             name,
@@ -42688,17 +42934,16 @@ var _extends = Object.assign || function
                                                                                                                                                                                                                                                                    * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
 
 exports.parseQuickOpenQuery = parseQuickOpenQuery;
 exports.parseLineColumn = parseLineColumn;
 exports.formatSymbol = formatSymbol;
 exports.formatSymbols = formatSymbols;
 exports.formatShortcutResults = formatShortcutResults;
 exports.formatSources = formatSources;
-exports.groupFuzzyMatches = groupFuzzyMatches;
 
 var _utils = __webpack_require__(1366);
 
 var _source = __webpack_require__(1356);
 
 const MODIFIERS = exports.MODIFIERS = {
   "@": "functions",
   "#": "variables",
@@ -42782,72 +43027,35 @@ function formatSources(sources) {
       title: sourcePath.split("/").pop(),
       subtitle: (0, _utils.endTruncateStr)(sourcePath, 100),
       id: source.get("id"),
       url: source.get("url")
     };
   }).filter(({ value }) => value != "").toJS();
 }
 
-function groupFuzzyMatches(input, query) {
-  const parts = input.toLowerCase().split("");
-  const queryChars = query.toLowerCase().split("");
-  const shared = parts.filter(char => queryChars.includes(char));
-  const output = [];
-  let matched;
-  let missed;
-  parts.forEach((char, i) => {
-    if (shared.includes(char)) {
-      if (!matched) {
-        matched = { type: "match", value: input[i] };
-        output.push(matched);
-        return;
-      }
-      matched = output[output.length - 1];
-      if (matched.type === "match") {
-        matched.value = `${matched.value}${input[i]}`;
-      } else {
-        matched = { type: "match", value: input[i] };
-        output.push(matched);
-      }
-      return;
-    }
-
-    if (!missed) {
-      missed = { type: "miss", value: input[i] };
-      output.push(missed);
-      return;
-    }
-
-    missed = output[output.length - 1];
-    if (missed.type === "miss") {
-      missed.value = `${missed.value}${input[i]}`;
-    } else {
-      missed = { type: "miss", value: input[i] };
-      output.push(missed);
-    }
-  });
-  return output;
-}
-
 /***/ }),
 /* 1637 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.command = command;
 exports.stepIn = stepIn;
 exports.stepOver = stepOver;
 exports.stepOut = stepOut;
 exports.resume = resume;
+exports.rewind = rewind;
+exports.reverseStepIn = reverseStepIn;
+exports.reverseStepOver = reverseStepOver;
+exports.reverseStepOut = reverseStepOut;
 exports.astCommand = astCommand;
 
 var _selectors = __webpack_require__(1352);
 
 var _promise = __webpack_require__(1653);
 
 var _parser = __webpack_require__(1365);
 
@@ -42873,16 +43081,17 @@ function command(type) {
 }
 
 /**
  * StepIn
  * @memberof actions/pause
  * @static
  * @returns {Function} {@link command}
  */
+/* -*- indent-tabs-mode: nil; js-indent-level: 2; js-indent-level: 2 -*- */
 /* 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/>. */
 
 function stepIn() {
   return ({ dispatch, getState }) => {
     if ((0, _selectors.isPaused)(getState())) {
       return dispatch(command("stepIn"));
@@ -42928,16 +43137,72 @@ function resume() {
   return ({ dispatch, getState }) => {
     if ((0, _selectors.isPaused)(getState())) {
       return dispatch(command("resume"));
     }
   };
 }
 
 /**
+ * rewind
+ * @memberof actions/pause
+ * @static
+ * @returns {Function} {@link command}
+ */
+function rewind() {
+  return ({ dispatch, getState }) => {
+    if ((0, _selectors.isPaused)(getState())) {
+      return dispatch(command("rewind"));
+    }
+  };
+}
+
+/**
+ * reverseStepIn
+ * @memberof actions/pause
+ * @static
+ * @returns {Function} {@link command}
+ */
+function reverseStepIn() {
+  return ({ dispatch, getState }) => {
+    if ((0, _selectors.isPaused)(getState())) {
+      return dispatch(command("reverseStepIn"));
+    }
+  };
+}
+
+/**
+ * reverseStepOver
+ * @memberof actions/pause
+ * @static
+ * @returns {Function} {@link command}
+ */
+function reverseStepOver() {
+  return ({ dispatch, getState }) => {
+    if ((0, _selectors.isPaused)(getState())) {
+      return dispatch(astCommand("reverseStepOver"));
+    }
+  };
+}
+
+/**
+ * reverseStepOut
+ * @memberof actions/pause
+ * @static
+ * @returns {Function} {@link command}
+ */
+function reverseStepOut() {
+  return ({ dispatch, getState }) => {
+    if ((0, _selectors.isPaused)(getState())) {
+      return dispatch(command("reverseStepOut"));
+    }
+  };
+}
+
+/**
  * @memberOf actions/pause
  * @static
  * @param stepType
  * @returns {function(ThunkArgs)}
  */
 function astCommand(stepType) {
   return async ({ dispatch, getState, sourceMaps }) => {
     if (!_prefs.features.asyncStepping) {
@@ -43021,16 +43286,40 @@ Object.defineProperty(exports, "stepOut"
   }
 });
 Object.defineProperty(exports, "resume", {
   enumerable: true,
   get: function () {
     return _commands.resume;
   }
 });
+Object.defineProperty(exports, "rewind", {
+  enumerable: true,
+  get: function () {
+    return _commands.rewind;
+  }
+});
+Object.defineProperty(exports, "reverseStepIn", {
+  enumerable: true,
+  get: function () {
+    return _commands.reverseStepIn;
+  }
+});
+Object.defineProperty(exports, "reverseStepOver", {
+  enumerable: true,
+  get: function () {
+    return _commands.reverseStepOver;
+  }
+});
+Object.defineProperty(exports, "reverseStepOut", {
+  enumerable: true,
+  get: function () {
+    return _commands.reverseStepOut;
+  }
+});
 
 var _fetchScopes = __webpack_require__(1655);
 
 Object.defineProperty(exports, "fetchScopes", {
   enumerable: true,
   get: function () {
     return _fetchScopes.fetchScopes;
   }
@@ -43150,36 +43439,37 @@ var _fetchScopes = __webpack_require__(1
 function paused(pauseInfo) {
   return async function ({ dispatch, getState, client, sourceMaps }) {
     const { frames, why, loadedObjects } = pauseInfo;
 
     dispatch({
       type: "PAUSED",
       why,
       frames,
-      selectedFrameId: frames[0].id,
+      selectedFrameId: frames[0] ? frames[0].id : undefined,
       loadedObjects: loadedObjects || []
     });
 
     const hiddenBreakpointLocation = (0, _selectors.getHiddenBreakpointLocation)(getState());
     if (hiddenBreakpointLocation) {
       dispatch((0, _breakpoints.removeBreakpoint)(hiddenBreakpointLocation));
     }
 
     if (!(0, _selectors.isEvaluatingExpression)(getState())) {
       dispatch((0, _expressions.evaluateExpressions)());
     }
 
     await dispatch((0, _.mapFrames)());
     const selectedFrame = (0, _selectors.getSelectedFrame)(getState());
-    const visibleFrame = (0, _selectors.getVisibleSelectedFrame)(getState());
-
-    const location = (0, _devtoolsSourceMap.isGeneratedId)(visibleFrame.location.sourceId) ? selectedFrame.generatedLocation : selectedFrame.location;
-
-    await dispatch((0, _sources.selectLocation)(location));
+
+    if (selectedFrame) {
+      const visibleFrame = (0, _selectors.getVisibleSelectedFrame)(getState());
+      const location = (0, _devtoolsSourceMap.isGeneratedId)(visibleFrame.location.sourceId) ? selectedFrame.generatedLocation : selectedFrame.location;
+      await dispatch((0, _sources.selectLocation)(location));
+    }
 
     dispatch((0, _ui.togglePaneCollapse)("end", false));
     dispatch((0, _fetchScopes.fetchScopes)());
   };
 }
 
 /***/ }),
 /* 1641 */
@@ -43439,16 +43729,18 @@ var _react = __webpack_require__(0);
 var _react2 = _interopRequireDefault(_react);
 
 var _reactRedux = __webpack_require__(1189);
 
 var _fuzzaldrinPlus = __webpack_require__(161);
 
 var _fuzzaldrinPlus2 = _interopRequireDefault(_fuzzaldrinPlus);
 
+var _path = __webpack_require__(1393);
+
 var _actions = __webpack_require__(1354);
 
 var _actions2 = _interopRequireDefault(_actions);
 
 var _selectors = __webpack_require__(1352);
 
 var _resultList = __webpack_require__(1406);
 
@@ -43690,103 +43982,119 @@ class QuickOpenModal extends _react.Comp
     this.isGotoSourceQuery = () => this.props.searchType === "gotoSource";
 
     this.isShortcutQuery = () => this.props.searchType === "shortcuts";
 
     this.isSourcesQuery = () => this.props.searchType === "sources";
 
     this.isSourceSearch = () => this.isSourcesQuery() || this.isGotoSourceQuery();
 
-    this.renderHighlight = (part, i) => {
-      if (part.type === "match") {
-        return _react2.default.createElement(
-          "span",
-          { key: `${part.value}-${i}`, className: "fuzzy-match" },
-          part.value
-        );
-      }
-      return part.value;
+    this.renderHighlight = (candidateString, query, name) => {
+      const html = _fuzzaldrinPlus2.default.wrap(candidateString, query);
+
+      return _react2.default.createElement("div", { dangerouslySetInnerHTML: { __html: html } });
     };
 
     this.highlightMatching = (query, results) => {
-      if (query === "") {
+      let newQuery = query;
+      if (newQuery === "") {
         return results;
       }
+      if (Object.keys(_quickOpen.MODIFIERS).includes(query[0])) {
+        newQuery = query.slice(1, query.length);
+      }
+
       return results.map(result => {
-        const title = (0, _quickOpen.groupFuzzyMatches)(result.title, query);
-        const subtitle = result.subtitle != null ? (0, _quickOpen.groupFuzzyMatches)(result.subtitle, query) : null;
         return _extends({}, result, {
-          title: title.map(this.renderHighlight)
-        }, subtitle != null && !this.isSymbolSearch() ? { subtitle: subtitle.map(this.renderHighlight) } : null);
+          title: this.renderHighlight(result.title, (0, _path.basename)(newQuery), "title")
+        }, result.subtitle != null && !this.isSymbolSearch() ? {
+          subtitle: this.renderHighlight(result.subtitle, newQuery, "subtitle")
+        } : null);
       });
     };
 
     this.state = { results: null, selectedIndex: 0 };
   }
 
   componentDidMount() {
-    this.updateResults(this.props.query);
+    const { query, shortcutsModalEnabled, toggleShortcutsModal } = this.props;
+
+    this.updateResults(query);
+
+    if (shortcutsModalEnabled) {
+      toggleShortcutsModal();
+    }
   }
 
   componentDidUpdate(prevProps) {
-    if (this.refs.resultList && this.refs.resultList.refs) {
-      (0, _resultList.scrollList)(this.refs.resultList.refs, this.state.selectedIndex);
-    }
-
     const nowEnabled = !prevProps.enabled && this.props.enabled;
     const queryChanged = prevProps.query !== this.props.query;
+
+    if (this.refs.resultList && this.refs.resultList.refs) {
+      (0, _resultList.scrollList)(this.refs.resultList.refs, this.state.selectedIndex, nowEnabled || !queryChanged);
+    }
+
     if (nowEnabled || queryChanged) {
       this.updateResults(this.props.query);
     }
   }
 
   // Query helpers
 
 
+  /* eslint-disable react/no-danger */
+
+
   render() {
     const { enabled, query } = this.props;
     const { selectedIndex, results } = this.state;
 
     if (!enabled) {
       return null;
     }
     const summaryMsg = L10N.getFormatStr("sourceSearch.resultsSummary1", this.getResultCount());
     const showSummary = this.isSourcesQuery() || this.isSymbolSearch() || this.isShortcutQuery();
     const newResults = results && results.slice(0, 100);
+    const items = this.highlightMatching(query, newResults || []);
+    const expanded = !!items && items.length > 0;
     return _react2.default.createElement(
       _Modal2.default,
       { "in": enabled, handleClose: this.closeModal },
       _react2.default.createElement(_SearchInput2.default, _extends({
         query: query,
         count: this.getResultCount(),
         placeholder: L10N.getStr("sourceSearch.search")
       }, showSummary === true ? { summaryMsg } : {}, {
         onChange: this.onChange,
         onKeyDown: this.onKeyDown,
-        handleClose: this.closeModal
+        handleClose: this.closeModal,
+        expanded: expanded,
+        selectedItemId: expanded ? items[selectedIndex].id : ""
       })),
       newResults && _react2.default.createElement(_ResultList2.default, _extends({
         key: "results",
-        items: this.highlightMatching(query, newResults),
+        items: items,
         selected: selectedIndex,
         selectItem: this.selectResultItem,
-        ref: "resultList"
+        ref: "resultList",
+        expanded: expanded
       }, this.isSourceSearch() ? { size: "big" } : {}))
     );
   }
 }
 
 exports.QuickOpenModal = QuickOpenModal; /* istanbul ignore next: ignoring testing of redux connection stuff */
 
 function mapStateToProps(state) {
   const selectedSource = (0, _selectors.getSelectedSource)(state);
   let symbols = null;
   if (selectedSource != null) {
     symbols = (0, _selectors.getSymbols)(state, selectedSource.toJS());
   }
+
   return {
     enabled: (0, _selectors.getQuickOpenEnabled)(state),
     sources: (0, _quickOpen.formatSources)((0, _selectors.getSources)(state)),
     selectedSource,
     symbols: (0, _quickOpen.formatSymbols)(symbols),
     query: (0, _selectors.getQuickOpenQuery)(state),
     searchType: (0, _selectors.getQuickOpenType)(state),
     tabs: (0, _selectors.getTabs)(state).toArray()
@@ -43878,60 +44186,38 @@ exports.promise = promiseMiddleware;
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.fetchScopes = fetchScopes;
 
 var _selectors = __webpack_require__(1352);
 
-var _prefs = __webpack_require__(226);
-
-var _devtoolsSourceMap = __webpack_require__(1360);
-
 var _mapScopes = __webpack_require__(1634);
 
-/* 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/>. */
+var _promise = __webpack_require__(1653);
 
 function fetchScopes() {
   return async function ({ dispatch, getState, client, sourceMaps }) {
     const frame = (0, _selectors.getSelectedFrame)(getState());
-    if (!frame || (0, _selectors.getFrameScope)(getState(), frame.id)) {
-      return;
-    }
-
-    const scopes = await client.getFrameScopes(frame);
-    dispatch({
+    if (!frame || (0, _selectors.getGeneratedFrameScope)(getState(), frame.id)) {
+      return;
+    }
+
+    const scopes = dispatch({
       type: "ADD_SCOPES",
       frame,
-      scopes
-    });
-
-    const generatedSourceRecord = (0, _selectors.getSource)(getState(), frame.generatedLocation.sourceId);
-
-    if (generatedSourceRecord.get("isWasm")) {
-      return;
-    }
-
-    const sourceRecord = (0, _selectors.getSource)(getState(), frame.location.sourceId);
-    if (sourceRecord.get("isPrettyPrinted")) {
-      return;
-    }
-
-    if ((0, _devtoolsSourceMap.isGeneratedId)(frame.location.sourceId)) {
-      return;
-    }
-
-    if (_prefs.features.mapScopes) {
-      dispatch((0, _mapScopes.mapScopes)(scopes, frame));
-    }
-  };
-}
+      [_promise.PROMISE]: client.getFrameScopes(frame)
+    });
+
+    dispatch((0, _mapScopes.mapScopes)(scopes, frame));
+  };
+} /* 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/>. */
 
 /***/ }),
 /* 1656 */,
 /* 1657 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
@@ -45559,19 +45845,17 @@ function getFramePopVariables(why, path)
         });
       }
     }
   }
 
   return vars;
 }
 
-function getThisVariable(frame, path) {
-  const this_ = frame.this;
-
+function getThisVariable(this_, path) {
   if (!this_) {
     return null;
   }
 
   return {
     name: "<this>",
     path: `${path}/<this>`,
     contents: { value: this_ }
@@ -47246,22 +47530,17 @@ function clearPreview() {
 
     return dispatch({
       type: "CLEAR_SELECTION"
     });
   };
 }
 
 /***/ }),
-/* 1787 */
-/***/ (function(module, exports) {
-
-module.exports = "<!-- 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 viewBox=\"0 0 9 15\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><title>Group 2</title><desc>Created with Sketch.</desc><g id=\"Symbols\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\"><g id=\"Group-2\" transform=\"translate(-3.000000, 0.000000)\" fill-rule=\"nonzero\" fill=\"#000000\"><g transform=\"translate(2.000000, 0.000000)\" id=\"path10\"><path d=\"M8.66478978,0.152329483 L6.24859226,7.23234215 L6.24859226,7.23234215 C6.22451137,7.30290469 6.14778771,7.34058551 6.07722517,7.31650462 C6.0437665,7.30508617 6.01612208,7.2809984 6.00023206,7.24941723 L2.49196511,0.276788279 L2.49196511,0.276788279 C2.4537519,0.200840088 2.3759926,0.152917255 2.29097274,0.152917255 L1.08420686,0.152917255 L1.08420686,0.152917255 C1.02897839,0.152917255 0.984206865,0.19768878 0.984206865,0.252917255 C0.984206865,0.268916365 0.988045664,0.284681937 0.99540091,0.2988901 L5.47310495,8.94849143 L5.47310495,8.94849143 C5.53346173,9.06508289 5.54553974,9.2007357 5.50673082,9.3261565 L4.0917648,13.8989752 L4.0917648,13.8989752 C4.06260539,13.9932111 3.97546399,14.0574648 3.87681975,14.0574648 L1.45804052,14.0574648 L1.45804052,14.0574648 C1.33377645,14.0574648 1.23304051,14.1582007 1.23304051,14.2824648 L1.23304051,14.775 L1.23304051,14.775 C1.23304051,14.8992641 1.33377645,15 1.45804052,15 L4.50020953,15 L4.50020953,15 C4.71271509,15 4.90200445,14.8656767 4.97216898,14.6650887 L10.0088745,0.266035474 L10.0088745,0.266035474 C10.0453448,0.161773071 9.99038856,0.0476866038 9.88612615,0.0112162185 C9.86490135,0.00379190571 9.84257651,2.78889645e-14 9.82009068,2.5895952e-14 L8.87773108,-4.83289971e-14 L8.87773108,-4.79061235e-14 C8.78147405,-5.47279145e-14 8.69587888,0.061231278 8.66478978,0.152329483 Z\" transform=\"translate(5.502176, 7.500000) scale(1, -1) translate(-5.502176, -7.500000) \"></path></g></g></g></svg>"
-
-/***/ }),
+/* 1787 */,
 /* 1788 */
 /***/ (function(module, exports) {
 
 // removed by extract-text-webpack-plugin
 
 /***/ }),
 /* 1789 */,
 /* 1790 */
@@ -47518,17 +47797,26 @@ function getScope(scope, selectedFrame, 
     const bindings = scope.bindings;
 
     let vars = (0, _getVariables.getBindingVariables)(bindings, key);
 
     // show exception, return, and this variables in innermost scope
     if (isLocalScope) {
       vars = vars.concat((0, _utils.getFramePopVariables)(why, key));
 
-      const this_ = (0, _utils.getThisVariable)(selectedFrame, key);
+      let thisDesc_ = selectedFrame.this;
+
+      if ("this" in bindings) {
+        // The presence of "this" means we're rendering a "this" binding
+        // generated from mapScopes and this can override the binding
+        // provided by the current frame.
+        thisDesc_ = bindings.this ? bindings.this.value : null;
+      }
+
+      const this_ = (0, _utils.getThisVariable)(thisDesc_, key);
 
       if (this_) {
         vars.push(this_);
       }
     }
 
     if (vars && vars.length) {
       const title = getScopeTitle(type, scope);
@@ -48472,138 +48760,138 @@ function showContextMenu(props) {
   const addConditionKey = L10N.getStr("breakpointMenuItem.addCondition2.accesskey");
 
   const otherBreakpoints = breakpoints.filter(b => b !== breakpoint);
   const enabledBreakpoints = breakpoints.filter(b => !b.disabled);
   const disabledBreakpoints = breakpoints.filter(b => b.disabled);
   const otherEnabledBreakpoints = breakpoints.filter(b => !b.disabled && b !== breakpoint);
   const otherDisabledBreakpoints = breakpoints.filter(b => b.disabled && b !== breakpoint);
 
-  const deleteSelf = {
+  const deleteSelfItem = {
     id: "node-menu-delete-self",
     label: deleteSelfLabel,
     accesskey: deleteSelfKey,
     disabled: false,
     click: () => removeBreakpoint(breakpoint.location)
   };
 
-  const deleteAll = {
+  const deleteAllItem = {
     id: "node-menu-delete-all",
     label: deleteAllLabel,
     accesskey: deleteAllKey,
     disabled: false,
     click: () => removeAllBreakpoints()
   };
 
-  const deleteOthers = {
+  const deleteOthersItem = {
     id: "node-menu-delete-other",
     label: deleteOthersLabel,
     accesskey: deleteOthersKey,
     disabled: false,
     click: () => removeBreakpoints(otherBreakpoints)
   };
 
-  const enableSelf = {
+  const enableSelfItem = {
     id: "node-menu-enable-self",
     label: enableSelfLabel,
     accesskey: enableSelfKey,
     disabled: false,
     click: () => toggleDisabledBreakpoint(breakpoint.location.line)
   };
 
-  const enableAll = {
+  const enableAllItem = {
     id: "node-menu-enable-all",
     label: enableAllLabel,
     accesskey: enableAllKey,
     disabled: false,
     click: () => toggleAllBreakpoints(false)
   };
 
-  const enableOthers = {
+  const enableOthersItem = {
     id: "node-menu-enable-others",
     label: enableOthersLabel,
     accesskey: enableOthersKey,
     disabled: false,
     click: () => toggleBreakpoints(false, otherDisabledBreakpoints)
   };
 
-  const disableSelf = {
+  const disableSelfItem = {
     id: "node-menu-disable-self",
     label: disableSelfLabel,
     accesskey: disableSelfKey,
     disabled: false,
     click: () => toggleDisabledBreakpoint(breakpoint.location.line)
   };
 
-  const disableAll = {
+  const disableAllItem = {
     id: "node-menu-disable-all",
     label: disableAllLabel,
     accesskey: disableAllKey,
     disabled: false,
     click: () => toggleAllBreakpoints(true)
   };
 
-  const disableOthers = {
+  const disableOthersItem = {
     id: "node-menu-disable-others",
     label: disableOthersLabel,
     accesskey: disableOthersKey,
     click: () => toggleBreakpoints(true, otherEnabledBreakpoints)
   };
 
-  const removeCondition = {
+  const removeConditionItem = {
     id: "node-menu-remove-condition",
     label: removeConditionLabel,
     accesskey: removeConditionKey,
     disabled: false,
     click: () => setBreakpointCondition(breakpoint.location)
   };
 
-  const addCondition = {
+  const addConditionItem = {
     id: "node-menu-add-condition",
     label: addConditionLabel,
     accesskey: addConditionKey,
     click: () => {
       selectLocation(breakpoint.location);
       openConditionalPanel(breakpoint.location.line);
     }
   };
 
-  const editCondition = {
+  const editConditionItem = {
     id: "node-menu-edit-condition",
     label: editConditionLabel,
     accesskey: editConditionKey,
     click: () => {
       selectLocation(breakpoint.location);
       openConditionalPanel(breakpoint.location.line);
     }
   };
 
-  const hideEnableSelf = !breakpoint.disabled;
-  const hideEnableAll = disabledBreakpoints.size === 0;
-  const hideEnableOthers = otherDisabledBreakpoints.size === 0;
-  const hideDisableAll = enabledBreakpoints.size === 0;
-  const hideDisableOthers = otherEnabledBreakpoints.size === 0;
-  const hideDisableSelf = breakpoint.disabled;
-
-  const items = [{ item: enableSelf, hidden: () => hideEnableSelf }, { item: enableAll, hidden: () => hideEnableAll }, { item: enableOthers, hidden: () => hideEnableOthers }, {
+  const hideEnableSelfItem = !breakpoint.disabled;
+  const hideEnableAllItem = disabledBreakpoints.size === 0;
+  const hideEnableOthersItem = otherDisabledBreakpoints.size === 0;
+  const hideDisableAllItem = enabledBreakpoints.size === 0;
+  const hideDisableOthersItem = otherEnabledBreakpoints.size === 0;
+  const hideDisableSelfItem = breakpoint.disabled;
+
+  const items = [{ item: enableSelfItem, hidden: () => hideEnableSelfItem }, { item: enableAllItem, hidden: () => hideEnableAllItem }, { item: enableOthersItem, hidden: () => hideEnableOthersItem }, {
     item: { type: "separator" },
-    hidden: () => hideEnableSelf && hideEnableAll && hideEnableOthers
-  }, { item: deleteSelf }, { item: deleteAll }, { item: deleteOthers, hidden: () => breakpoints.size === 1 }, {
+    hidden: () => hideEnableSelfItem && hideEnableAllItem && hideEnableOthersItem
+  }, { item: deleteSelfItem }, { item: deleteAllItem }, { item: deleteOthersItem, hidden: () => breakpoints.size === 1 }, {
     item: { type: "separator" },
-    hidden: () => hideDisableSelf && hideDisableAll && hideDisableOthers
-  }, { item: disableSelf, hidden: () => hideDisableSelf }, { item: disableAll, hidden: () => hideDisableAll }, { item: disableOthers, hidden: () => hideDisableOthers }, {
+    hidden: () => hideDisableSelfItem && hideDisableAllItem && hideDisableOthersItem
+  }, { item: disableSelfItem, hidden: () => hideDisableSelfItem }, { item: disableAllItem, hidden: () => hideDisableAllItem }, { item: disableOthersItem, hidden: () => hideDisableOthersItem }, {
     item: { type: "separator" }
   }, {
-    item: addCondition,
+    item: addConditionItem,
     hidden: () => breakpoint.condition
   }, {
-    item: editCondition,
+    item: editConditionItem,
     hidden: () => !breakpoint.condition
   }, {
-    item: removeCondition,
+    item: removeConditionItem,
     hidden: () => !breakpoint.condition
   }];
 
   (0, _devtoolsContextmenu.showMenu)(contextMenuEvent, (0, _devtoolsContextmenu.buildMenu)(items));
 }
 
 /***/ }),
 /* 1806 */
@@ -49623,19 +49911,22 @@ function getHiddenTabs(sourceTabs, sourc
     return element && hasTopOffset(element);
   });
 }
 
 function getSourceAnnotation(source, getMetaData) {
   const sourceId = source.get("id");
   const sourceMetaData = getMetaData(sourceId);
 
-  if (sourceMetaData && sourceMetaData.isReactComponent) {
-    return _react2.default.createElement("img", { className: "react" });
-  }
+  const framework = sourceMetaData && sourceMetaData.framework ? sourceMetaData.framework : false;
+
+  if (framework) {
+    return _react2.default.createElement("img", { className: framework.toLowerCase() });
+  }
+
   if ((0, _source.isPretty)(source)) {
     return _react2.default.createElement("img", { className: "prettyPrint" });
   }
   if (source.get("isBlackBoxed")) {
     return _react2.default.createElement("img", { className: "blackBox" });
   }
 }
 
--- a/devtools/client/debugger/new/parser-worker.js
+++ b/devtools/client/debugger/new/parser-worker.js
@@ -33258,17 +33258,34 @@ var _getFunctionName2 = _interopRequireD
 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 let symbolDeclarations = new Map();
 
 function getFunctionParameterNames(path) {
   if (path.node.params != null) {
-    return path.node.params.map(param => param.name);
+    return path.node.params.map(param => {
+      if (param.type !== "AssignmentPattern") {
+        return param.name;
+      }
+
+      // Parameter with default value
+      if (param.left.type === "Identifier" && param.right.type === "Identifier") {
+        return `${param.left.name} = ${param.right.name}`;
+      } else if (param.left.type === "Identifier" && param.right.type === "StringLiteral") {
+        return `${param.left.name} = ${param.right.value}`;
+      } else if (param.left.type === "Identifier" && param.right.type === "ObjectExpression") {
+        return `${param.left.name} = {}`;
+      } else if (param.left.type === "Identifier" && param.right.type === "ArrayExpression") {
+        return `${param.left.name} = []`;
+      } else if (param.left.type === "Identifier" && param.right.type === "NullLiteral") {
+        return `${param.left.name} = null`;
+      }
+    });
   }
   return [];
 }
 
 function getVariableNames(path) {
   if (t.isObjectProperty(path) && !(0, _helpers.isFunction)(path.node.value)) {
     if (path.node.key.type === "StringLiteral") {
       return [{
@@ -33856,17 +33873,17 @@ self.onmessage = workerHandler({
   clearASTs: _ast.clearASTs,
   hasSource: _sources.hasSource,
   setSource: _sources.setSource,
   clearSources: _sources.clearSources,
   getVariablesInScope: _scopes.getVariablesInScope,
   getNextStep: _steps.getNextStep,
   getEmptyLines: _getEmptyLines2.default,
   hasSyntaxError: _validate.hasSyntaxError,
-  isReactComponent: _frameworks.isReactComponent
+  getFramework: _frameworks.getFramework
 });
 
 /***/ }),
 /* 1619 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
@@ -34593,30 +34610,36 @@ module.exports = findLastIndex;
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.isReactComponent = isReactComponent;
+exports.getFramework = getFramework;
 
 var _getSymbols = __webpack_require__(1457);
 
 var _getSymbols2 = _interopRequireDefault(_getSymbols);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
+function getFramework(sourceId) {
+  if (isReactComponent(sourceId)) {
+    return "React";
+  }
+} /* 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/>. */
+
 function isReactComponent(sourceId) {
   const { imports, classes, callExpressions } = (0, _getSymbols2.default)(sourceId);
   return (importsReact(imports) || requiresReact(callExpressions)) && extendsComponent(classes);
-} /* 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/>. */
+}
 
 function importsReact(imports) {
   return imports.some(importObj => importObj.source === "react" && importObj.specifiers.some(specifier => specifier === "React"));
 }
 
 function requiresReact(callExpressions) {
   return callExpressions.some(callExpression => callExpression.name === "require" && callExpression.values.some(value => value === "react"));
 }
@@ -35261,16 +35284,30 @@ module.exports = {"builtin":{"Array":fal
 var _devtoolsSourceMap = __webpack_require__(1360);
 
 var _getFunctionName = __webpack_require__(1621);
 
 var _getFunctionName2 = _interopRequireDefault(_getFunctionName);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
+/**
+ * "implicit"
+ * Variables added automaticly like "this" and "arguments"
+ *
+ * "var"
+ * Variables declared with "var" or non-block function declarations
+ *
+ * "let"
+ * Variables declared with "let".
+ *
+ * "const"
+ * Variables declared with "const", imported bindings, or added as const
+ * bindings like inner function expressions and inner class names.
+ */
 /* 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/. */
 
 function createTempScope(type, displayName, parent, loc) {
   const result = {
     type,
     displayName,
@@ -35284,17 +35321,17 @@ function createTempScope(type, displayNa
   }
   return result;
 }
 
 function isNode(node, type) {
   return node ? node.type === type : false;
 }
 
-function getFunctionScope(scope) {
+function getVarScope(scope) {
   let s = scope;
   while (s.type !== "function" && s.type !== "module") {
     if (!s.parent) {
       return s;
     }
     s = s.parent;
   }
   return s;
@@ -35356,47 +35393,40 @@ function findIdentifierInScopes(scope, n
   return null;
 }
 
 function toParsedScopes(children, sourceId) {
   if (!children || children.length === 0) {
     return undefined;
   }
   return children.map(scope => {
-    // Removing unneed information from TempScope such as parent reference and
-    // name types. We also need to convert BabelLocation to the Location type.
+    // Removing unneed information from TempScope such as parent reference.
+    // We also need to convert BabelLocation to the Location type.
     const bindings = Object.keys(scope.names).reduce((_bindings, n) => {
       const nameRefs = scope.names[n];
-      switch (nameRefs.type) {
-        case "var":
-        case "let":
-        case "const":
-        case "param":
-        case "fn":
-        case "import":
-          _bindings[n] = {
-            declarations: nameRefs.declarations.map(({ start, end }) => ({
-              start: fromBabelLocation(start, sourceId),
-              end: fromBabelLocation(end, sourceId)
-            })),
-            refs: nameRefs.refs.map(({ start, end }) => ({
-              start: fromBabelLocation(start, sourceId),
-              end: fromBabelLocation(end, sourceId)
-            }))
-          };
-          break;
-      }
+
+      _bindings[n] = {
+        type: nameRefs.type,
+        declarations: nameRefs.declarations.map(({ start, end }) => ({
+          start: fromBabelLocation(start, sourceId),
+          end: fromBabelLocation(end, sourceId)
+        })),
+        refs: nameRefs.refs.map(({ start, end }) => ({
+          start: fromBabelLocation(start, sourceId),
+          end: fromBabelLocation(end, sourceId)
+        }))
+      };
       return _bindings;
     }, Object.create(null));
     return {
       start: fromBabelLocation(scope.loc.start, sourceId),
       end: fromBabelLocation(scope.loc.end, sourceId),
       type: scope.type === "module" ? "block" : scope.type,
       displayName: scope.displayName,
-      bindings,
+      bindings: bindings,
       children: toParsedScopes(scope.children, sourceId)
     };
   });
 }
 
 /**
  * Creates at visitor for babel-traverse that will parse/extract all bindings
  * information from the source. See also findScopes to perform lookup of the
@@ -35444,16 +35474,21 @@ function createParseJSScopeVisitor(sourc
             declarations: [],
             refs: []
           }
         });
 
         parent = createTempScope("block", "Lexical Global", parent, location);
 
         parent = createTempScope("module", "Module", parent, location);
+        parent.names.this = {
+          type: "implicit",
+          declarations: [],
+          refs: []
+        };
         return;
       }
       if (path.isFunction()) {
         savedParents.set(path, parent);
 
         if (path.isFunctionExpression() && isNode(tree.id, "Identifier")) {
           parent = createTempScope("block", "Function Expression", parent, location);
           parent.names[tree.id.name] = {
@@ -35465,28 +35500,63 @@ function createParseJSScopeVisitor(sourc
 
         const scope = createTempScope("function", (0, _getFunctionName2.default)(path), parent, {
           // Being at the start of a function doesn't count as
           // being inside of it.
           start: tree.params[0] ? tree.params[0].loc.start : location.start,
           end: location.end
         });
         if (path.isFunctionDeclaration() && isNode(tree.id, "Identifier")) {
-          const functionName = {
-            type: "fn",
+          // This ignores Annex B function declaration hoisting, which
+          // is probably a fine assumption.
+          const fnScope = getVarScope(parent);
+          scope.names[tree.id.name] = {
+            type: fnScope === scope ? "var" : "let",
             declarations: [tree.id.loc],
             refs: []
           };
-          getFunctionScope(parent).names[tree.id.name] = functionName;
-          scope.names[tree.id.name] = functionName;
-        }
-        tree.params.forEach(param => parseDeclarator(param, scope, "param"));
+        }
+        tree.params.forEach(param => parseDeclarator(param, scope, "var"));
+
+        if (!path.isArrowFunctionExpression()) {
+          scope.names.this = {
+            type: "implicit",
+            declarations: [],
+            refs: []
+          };
+          scope.names.arguments = {
+            type: "implicit",
+            declarations: [],
+            refs: []
+          };
+        }
+
         parent = scope;
         return;
       }
+      if (path.isClass()) {
+        if (path.isClassDeclaration() && path.get("id").isIdentifier()) {
+          parent.names[tree.id.name] = {
+            type: "let",
+            declarations: [tree.id.loc],
+            refs: []
+          };
+        }
+
+        if (path.get("id").isIdentifier()) {
+          savedParents.set(path, parent);
+          parent = createTempScope("block", "Class", parent, location);
+
+          parent.names[tree.id.name] = {
+            type: "const",
+            declarations: [tree.id.loc],
+            refs: []
+          };
+        }
+      }
       if (path.isForXStatement() || path.isForStatement()) {
         const init = tree.init || tree.left;
         if (isNode(init, "VariableDeclaration") && isLetOrConst(init)) {
           // Debugger will create new lexical environment for the for.
           savedParents.set(path, parent);
           parent = createTempScope("block", "For", parent, {
             // Being at the start of a for loop doesn't count as
             // being inside it.
@@ -35494,41 +35564,43 @@ function createParseJSScopeVisitor(sourc
             end: location.end
           });
         }
         return;
       }
       if (path.isCatchClause()) {
         savedParents.set(path, parent);
         parent = createTempScope("block", "Catch", parent, location);
-        parseDeclarator(tree.param, parent, "param");
+        parseDeclarator(tree.param, parent, "var");
         return;
       }
       if (path.isBlockStatement()) {
         if (hasLetOrConst(path)) {
           // Debugger will create new lexical environment for the block.
           savedParents.set(path, parent);
           parent = createTempScope("block", "Block", parent, location);
         }
         return;
       }
-      if (path.isVariableDeclaration()) {
+      if (path.isVariableDeclaration() && (path.node.kind === "var" ||
+      // Lexical declarations in for statements are handled above.
+      !path.parentPath.isForStatement({ init: tree }) || !path.parentPath.isXStatement({ left: tree }))) {
         // Finds right lexical environment
-        const hoistAt = !isLetOrConst(tree) ? getFunctionScope(parent) : parent;
+        const hoistAt = !isLetOrConst(tree) ? getVarScope(parent) : parent;
         tree.declarations.forEach(declarator => {
           parseDeclarator(declarator.id, hoistAt, tree.kind);
         });
         return;
       }
       if (path.isImportDeclaration()) {
         isUnambiguousModule = true;
 
         path.get("specifiers").forEach(spec => {
           parent.names[spec.node.local.name] = {
-            type: "import",
+            type: "const",
             declarations: [spec.node.local.loc],
             refs: []
           };
         });
         return;
       }
       if (path.isExportDeclaration()) {
         isUnambiguousModule = true;
@@ -35537,20 +35609,36 @@ function createParseJSScopeVisitor(sourc
 
       if (path.isReferencedIdentifier()) {
         const scope = findIdentifierInScopes(parent, tree.name);
         if (scope) {
           scope.names[tree.name].refs.push(tree.loc);
         }
         return;
       }
+      if (path.isThisExpression()) {
+        const scope = findIdentifierInScopes(parent, "this");
+        if (scope) {
+          scope.names.this.refs.push(tree.loc);
+        }
+      }
 
       if (path.parentPath.isClassProperty({ value: tree })) {
         savedParents.set(path, parent);
         parent = createTempScope("block", "Class Field", parent, location);
+        parent.names.this = {
+          type: "implicit",
+          declarations: [],
+          refs: []
+        };
+        parent.names.arguments = {
+          type: "implicit",
+          declarations: [],
+          refs: []
+        };
         return;
       }
 
       if (path.isSwitchStatement() && path.node.cases.some(node => node.consequent.some(child => isLexicalVariable(child)))) {
         savedParents.set(path, parent);
         parent = createTempScope("block", "Switch", parent, location);
         return;
       }
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-sourcemaps-reloading.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-sourcemaps-reloading.js
@@ -1,13 +1,16 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 async function waitForBreakpointCount(dbg, count) {
-  return waitForState(dbg, state => dbg.selectors.getBreakpoints(state).size === count)
+  return waitForState(
+    dbg,
+    state => dbg.selectors.getBreakpoints(state).size === count
+  );
 }
 
 add_task(async function() {
   // NOTE: the CORS call makes the test run times inconsistent
   requestLongerTimeout(2);
 
   const dbg = await initDebugger("doc-sourcemaps.html");
   const { selectors: { getBreakpoint, getBreakpoints }, getState } = dbg;
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-sourcemaps.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-sourcemaps.js
@@ -75,19 +75,19 @@ add_task(async function() {
 
   invokeInTab("keepMeAlive");
   await waitForPaused(dbg);
   assertPausedLocation(dbg);
 
   await stepIn(dbg);
   assertPausedLocation(dbg);
 
-  await dbg.actions.jumpToMappedSelectedLocation()
+  await dbg.actions.jumpToMappedSelectedLocation();
   await stepOver(dbg);
   assertPausedLocation(dbg);
   assertDebugLine(dbg, 71);
 
-  await dbg.actions.jumpToMappedSelectedLocation()
+  await dbg.actions.jumpToMappedSelectedLocation();
   await stepOut(dbg);
   await stepOut(dbg);
   assertPausedLocation(dbg);
   assertDebugLine(dbg, 16);
 });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-sources.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-sources.js
@@ -24,23 +24,23 @@ function getLabel(dbg, index) {
 
 add_task(async function() {
   const dbg = await initDebugger("doc-sources.html");
   const { selectors: { getSelectedSource }, getState } = dbg;
 
   await waitForSources(dbg, "simple1", "simple2", "nested-source", "long.js");
 
   // Expand nodes and make sure more sources appear.
-  assertSourceCount(dbg, 2);
+  await assertSourceCount(dbg, 2);
   await clickElement(dbg, "sourceArrow", 2);
 
-  assertSourceCount(dbg, 7);
+  await assertSourceCount(dbg, 7);
   await clickElement(dbg, "sourceArrow", 3);
 
-  assertSourceCount(dbg, 8);
+  await assertSourceCount(dbg, 8);
 
   // Select a source.
   ok(
     !findElementWithSelector(dbg, ".sources-list .focused"),
     "Source is not focused"
   );
   const selected = waitForDispatch(dbg, "SELECT_SOURCE");
   await clickElement(dbg, "sourceNode", 4);
--- a/devtools/client/debugger/new/test/mochitest/head.js
+++ b/devtools/client/debugger/new/test/mochitest/head.js
@@ -280,19 +280,25 @@ function assertNotPaused(dbg) {
  *
  * @memberof mochitest/asserts
  * @param {Object} dbg
  * @param {String} source
  * @param {Number} line
  * @static
  */
 function assertPausedLocation(dbg) {
-  const { selectors: { getSelectedSource, getVisibleSelectedFrame }, getState } = dbg;
+  const {
+    selectors: { getSelectedSource, getVisibleSelectedFrame },
+    getState
+  } = dbg;
 
-  ok(isSelectedFrameSelected(dbg, getState()), "top frame's source is selected");
+  ok(
+    isSelectedFrameSelected(dbg, getState()),
+    "top frame's source is selected"
+  );
 
   // Check the pause location
   const frame = getVisibleSelectedFrame(getState());
   const pauseLine = frame && frame.location.line;
   assertDebugLine(dbg, pauseLine);
 
   ok(isVisibleInEditor(dbg, getCM(dbg).display.gutters), "gutter is visible");
 }
@@ -442,17 +448,17 @@ function waitForTime(ms) {
  * @memberof mochitest/waits
  * @param {Object} dbg
  * @static
  */
 async function waitForMappedScopes(dbg) {
   await waitForState(
     dbg,
     state => {
-      const scopes = dbg.selectors.getScopes(state);
+      const scopes = dbg.selectors.getSelectedScope(state);
       return scopes && scopes.sourceBindings;
     },
     "mapped scopes"
   );
 }
 
 function isSelectedFrameSelected(dbg, state) {
   const frame = dbg.selectors.getVisibleSelectedFrame(state);
@@ -944,24 +950,24 @@ const selectors = {
   stepOver: ".stepOver.active",
   stepOut: ".stepOut.active",
   stepIn: ".stepIn.active",
   toggleBreakpoints: ".breakpoints-toggle",
   prettyPrintButton: ".source-footer .prettyPrint",
   sourceMapLink: ".source-footer .mapped-source",
   sourcesFooter: ".sources-panel .source-footer",
   editorFooter: ".editor-pane .source-footer",
-  sourceNode: i => `.sources-list .tree-node:nth-child(${i})`,
+  sourceNode: i => `.sources-list .tree-node:nth-child(${i}) .node`,
   sourceNodes: ".sources-list .tree-node",
   sourceArrow: i => `.sources-list .tree-node:nth-child(${i}) .arrow`,
   resultItems: ".result-list .result-item",
   fileMatch: ".managed-tree .result",
   popup: ".popover",
   tooltip: ".tooltip",
-  outlineItem: i => `.outline-list__element:nth-child(${i})`,
+  outlineItem: i => `.outline-list__element:nth-child(${i}) .function-signature`,
   outlineItems: ".outline-list__element"
 };
 
 function getSelector(elementName, ...args) {
   let selector = selectors[elementName];
   if (!selector) {
     throw new Error(`The selector ${elementName} is not defined`);
   }
@@ -1077,8 +1083,22 @@ function toggleObjectInspectorNode(node)
     () => objectInspector.querySelectorAll(".node").length !== properties
   );
 }
 
 function getCM(dbg) {
   const el = dbg.win.document.querySelector(".CodeMirror");
   return el.CodeMirror;
 }
+
+// NOTE: still experimental, the screenshots might not be exactly correct
+async function takeScreenshot(dbg) {
+  let canvas = dbg.win.document.createElementNS(
+    "http://www.w3.org/1999/xhtml",
+    "html:canvas"
+  );
+  let context = canvas.getContext("2d");
+  canvas.width = dbg.win.innerWidth;
+  canvas.height = dbg.win.innerHeight;
+  context.drawWindow(dbg.win, 0, 0, canvas.width, canvas.height, "white");
+  await waitForTime(1000);
+  dump(`[SCREENSHOT] ${canvas.toDataURL()}\n`);
+}
--- a/devtools/client/locales/en-US/debugger.properties
+++ b/devtools/client/locales/en-US/debugger.properties
@@ -159,36 +159,48 @@ otherEvents=Other
 
 # LOCALIZATION NOTE (blackboxCheckboxTooltip2): The tooltip text to display when
 # the user hovers over the checkbox used to toggle blackboxing its associated
 # source.
 blackboxCheckboxTooltip2=Toggle blackboxing
 
 # LOCALIZATION NOTE (sources.search.key2): Key shortcut to open the search for
 # searching all the source files the debugger has seen.
+# Do not localize "CmdOrCtrl+P", or change the format of the string. These are
+# key identifiers, not messages displayed to the user.
 sources.search.key2=CmdOrCtrl+P
 
 # LOCALIZATION NOTE (sources.search.alt.key): A second key shortcut to open the
 # search for searching all the source files the debugger has seen.
+# Do not localize "CmdOrCtrl+O", or change the format of the string. These are
+# key identifiers, not messages displayed to the user.
 sources.search.alt.key=CmdOrCtrl+O
 
 # LOCALIZATION NOTE (projectTextSearch.key): A key shortcut to open the
 # full project text search for searching all the files the debugger has seen.
+# Do not localize "CmdOrCtrl+Shift+F", or change the format of the string. These are
+# key identifiers, not messages displayed to the user.
 projectTextSearch.key=CmdOrCtrl+Shift+F
 
 # LOCALIZATION NOTE (functionSearch.key): A key shortcut to open the
 # modal for searching functions in a file.
+# Do not localize "CmdOrCtrl+Shift+O", or change the format of the string. These are
+# key identifiers, not messages displayed to the user.
 functionSearch.key=CmdOrCtrl+Shift+O
 
 # LOCALIZATION NOTE (toggleBreakpoint.key): A key shortcut to toggle
 # breakpoints.
+# Do not localize "CmdOrCtrl+B", or change the format of the string. These are
+# key identifiers, not messages displayed to the user.
 toggleBreakpoint.key=CmdOrCtrl+B
 
 # LOCALIZATION NOTE (toggleCondPanel.key): A key shortcut to toggle
 # the conditional breakpoint panel.
+# Do not localize "CmdOrCtrl+Shift+B", or change the format of the string. These are
+# key identifiers, not messages displayed to the user.
 toggleCondPanel.key=CmdOrCtrl+Shift+B
 
 # LOCALIZATION NOTE (stepOut.key): A key shortcut to
 # step out.
 stepOut.key=Shift+F11
 
 # LOCALIZATION NOTE (shortcuts.header.editor): Sections header in
 # the shortcuts modal for keyboard shortcuts related to editing.
@@ -211,28 +223,34 @@ projectTextSearch.placeholder=Find in files…
 projectTextSearch.noResults=No results found
 
 # LOCALIZATION NOTE (sources.noSourcesAvailable): Text shown when the debugger
 # does not have any sources.
 sources.noSourcesAvailable=This page has no sources
 
 # LOCALIZATION NOTE (sourceSearch.search.key2): Key shortcut to open the search
 # for searching within a the currently opened files in the editor
+# Do not localize "CmdOrCtrl+F", or change the format of the string. These are
+# key identifiers, not messages displayed to the user.
 sourceSearch.search.key2=CmdOrCtrl+F
 
 # LOCALIZATION NOTE (sourceSearch.search.placeholder): placeholder text in
 # the source search input bar
 sourceSearch.search.placeholder=Search in file…
 
 # LOCALIZATION NOTE (sourceSearch.search.again.key2): Key shortcut to highlight
 # the next occurrence of the last search triggered from a source search
+# Do not localize "CmdOrCtrl+G", or change the format of the string. These are
+# key identifiers, not messages displayed to the user.
 sourceSearch.search.again.key2=CmdOrCtrl+G
 
 # LOCALIZATION NOTE (sourceSearch.search.againPrev.key2): Key shortcut to highlight
 # the previous occurrence of the last search triggered from a source search
+# Do not localize "CmdOrCtrl+Shift+G", or change the format of the string. These are
+# key identifiers, not messages displayed to the user.
 sourceSearch.search.againPrev.key2=CmdOrCtrl+Shift+G
 
 # LOCALIZATION NOTE (sourceSearch.resultsSummary1): Shows a summary of
 # the number of matches for autocomplete
 sourceSearch.resultsSummary1=%d results
 
 # LOCALIZATION NOTE (noMatchingStringsText): The text to display in the
 # global search results when there are no matching strings after filtering.
@@ -545,26 +563,26 @@ watchExpressions.header=Watch expression
 
 # LOCALIZATION NOTE (watchExpressions.refreshButton): Watch Expressions header
 # button for refreshing the expressions.
 watchExpressions.refreshButton=Refresh
 
 # LOCALIZATION NOTE (welcome.search): The center pane welcome panel's
 # search prompt. e.g. cmd+p to search for files. On windows, it's ctrl, on
 # a mac we use the unicode character.
-welcome.search=%S to search for sources
+welcome.search=%S To search for sources
 
 # LOCALIZATION NOTE (welcome.findInFiles): The center pane welcome panel's
 # search prompt. e.g. cmd+f to search for files. On windows, it's ctrl+shift+f, on
 # a mac we use the unicode character.
-welcome.findInFiles=%S to find in files
+welcome.findInFiles=%S To find in files
 
 # LOCALIZATION NOTE (welcome.searchFunction): Label displayed in the welcome
 # panel. %S is replaced by the keyboard shortcut to search for functions.
-welcome.searchFunction=%S to search for functions in file
+welcome.searchFunction=%S To search for functions in file
 
 # LOCALIZATION NOTE (sourceSearch.search): The center pane Source Search
 # prompt for searching for files.
 sourceSearch.search=Search sources…
 
 # LOCALIZATION NOTE (sourceSearch.noResults2): The center pane Source Search
 # message when the query did not match any of the sources.
 sourceSearch.noResults2=No results found
@@ -682,32 +700,36 @@ watchExpressionsSeparatorLabel2=\u0020→
 
 # LOCALIZATION NOTE (functionSearchSeparatorLabel): The text that is displayed
 # in the functions search panel as a separator between function's inferred name
 # and its real name (if available).
 functionSearchSeparatorLabel=←
 
 # LOCALIZATION NOTE(gotoLineModal.placeholder): The placeholder
 # text displayed when the user searches for specific lines in a file
+# Do not localize "CmdOrCtrl+;", or change the format of the string. These are
+# key identifiers, not messages displayed to the user.
 gotoLineModal.placeholder=Go to line…
-gotoLineModal.key=CmdOrCtrl+Shift+;
+gotoLineModal.key=CmdOrCtrl+;
 gotoLineModal.title=Go to a line number in a file
 
 # LOCALIZATION NOTE(symbolSearch.search.functionsPlaceholder): The placeholder
 # text displayed when the user searches for functions in a file
 symbolSearch.search.functionsPlaceholder=Search functions…
 symbolSearch.search.functionsPlaceholder.title=Search for a function in a file
 
 # LOCALIZATION NOTE(symbolSearch.search.variablesPlaceholder): The placeholder
 # text displayed when the user searches for variables in a file
 symbolSearch.search.variablesPlaceholder=Search variables…
 symbolSearch.search.variablesPlaceholder.title=Search for a variable in a file
 
 # LOCALIZATION NOTE(symbolSearch.search.key2): The Key Shortcut for
 # searching for a function or variable
+# Do not localize "CmdOrCtrl+Shift+O", or change the format of the string. These are
+# key identifiers, not messages displayed to the user.
 symbolSearch.search.key2=CmdOrCtrl+Shift+O
 
 # LOCALIZATION NOTE(symbolSearch.searchModifier.modifiersLabel): A label
 # preceding the group of modifiers
 symbolSearch.searchModifier.modifiersLabel=Modifiers:
 
 # LOCALIZATION NOTE(symbolSearch.searchModifier.regex): A search option
 # when searching text in a file
@@ -820,16 +842,20 @@ shortcuts.stepIn=Step In
 # LOCALIZATION NOTE (shortcuts.stepOut): text describing
 # keyboard shortcut action for stepping out
 shortcuts.stepOut=Step Out
 
 # LOCALIZATION NOTE (shortcuts.fileSearch): text describing
 # keyboard shortcut action for source file search
 shortcuts.fileSearch=Source File Search
 
+# LOCALIZATION NOTE (shortcuts.gotoLine): text describing
+# keyboard shortcut for jumping to a specific line
+shortcuts.gotoLine=Go to line
+
 # LOCALIZATION NOTE (shortcuts.searchAgain): text describing
 # keyboard shortcut action for searching again
 shortcuts.searchAgain=Search Again
 
 # LOCALIZATION NOTE (shortcuts.projectSearch): text describing
 # keyboard shortcut action for full project search
 shortcuts.projectSearch=Full Project Search
 
--- a/devtools/client/preferences/debugger.js
+++ b/devtools/client/preferences/debugger.js
@@ -40,17 +40,17 @@ pref("devtools.debugger.expressions", "[
 pref("devtools.debugger.file-search-case-sensitive", false);
 pref("devtools.debugger.file-search-whole-word", false);
 pref("devtools.debugger.file-search-regex-match", false);
 pref("devtools.debugger.features.async-stepping", true);
 pref("devtools.debugger.project-directory-root", "");
 
 pref("devtools.debugger.features.wasm", true);
 pref("devtools.debugger.features.shortcuts", true);
-pref("devtools.debugger.features.root", false);
+pref("devtools.debugger.features.root", true);
 pref("devtools.debugger.features.column-breakpoints", false);
 pref("devtools.debugger.features.chrome-scopes", false);
 pref("devtools.debugger.features.map-scopes", false);
 pref("devtools.debugger.features.breakpoints-dropdown", false);
 pref("devtools.debugger.features.remove-command-bar-options", false);
 pref("devtools.debugger.features.workers", true);
 pref("devtools.debugger.features.code-coverage", false);
 pref("devtools.debugger.features.event-listeners", false);
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -13818,16 +13818,21 @@ class CGDictionary(CGThing):
             # Strings are always OK.
             return True
 
         if type.isPrimitive():
             # Primitives (numbers and booleans) are ok, as long as
             # they're not unrestricted float/double.
             return not type.isFloat() or not type.isUnrestricted()
 
+        if type.isRecord():
+            # Records are okay, as long as the value type is.
+            # Per spec, only strings are allowed as keys.
+            return CGDictionary.typeSafeToJSONify(type.inner)
+
         return False
 
     @staticmethod
     def dictionarySafeToJSONify(dictionary):
         # The dictionary itself is OK, so we're good if all our types are.
         return all(CGDictionary.typeSafeToJSONify(m.type)
                    for m in dictionary.members)
 
deleted file mode 100644
--- a/dom/svg/crashtests/367357-1.xhtml
+++ /dev/null
@@ -1,20 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-
-<script>
-function boom()
-{
-  document.getElementById("path").pathSegList.pathSegTypeAsLetter;
-}
-</script>
-
-</head>
-
-<body onload="boom()">
-
-  <svg xmlns="http://www.w3.org/2000/svg" height="400px" width="400px">
-    <path id="path" style="stroke: blue" d="M 200.50000,387.89713 L 201.19970,12.500000" />
-  </svg>
-
-</body>
-</html>
deleted file mode 100644
--- a/dom/svg/crashtests/369249-1.svg
+++ /dev/null
@@ -1,20 +0,0 @@
-<svg width='100%' height='100%' 
-  xmlns='http://www.w3.org/2000/svg' 
-  xmlns:html="http://www.w3.org/1999/xhtml"
-  onload='boom()'>
-  
-<html:script>
-  
-function boom()
-{
-  try {
-    document.getElementById("path").pathSegList.getItem(-10000000);
-  } catch(e) {
-  }
-}
-
-</html:script>
-
-<path id='path' d='M300,25 C320,250 375,150 400,150 S400,340 330,350'/>
-
-</svg>
deleted file mode 100644
--- a/dom/svg/crashtests/372046-1.svg
+++ /dev/null
@@ -1,17 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" onload="setTimeout(boom, 30);" class="reftest-wait">
-
-<script>
-function boom()
-{
-  try {
-    document.getElementById("path_1").pathSegList.insertItemBefore({}, 0);
-  } catch(e) {
-  }
-
-  document.documentElement.removeAttribute("class");
-}
-</script>
-
-<path id='path_1' d='M300,25 C500,100 575,300 330,350'/>
-
-</svg>
deleted file mode 100644
--- a/dom/svg/crashtests/372046-2.svg
+++ /dev/null
@@ -1,17 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" onload="setTimeout(boom, 30);" class="reftest-wait">
-
-<script>
-function boom()
-{
-  try {
-    document.getElementById("path_1").pathSegList.insertItemBefore({}, 0);
-  } catch(e) {
-  }
-
-  document.documentElement.removeAttribute("class");
-}
-</script>
-
-<path id='path_1' d='M300,25 C500,100 575,300 330,350'/>
-
-</svg>
deleted file mode 100644
--- a/dom/svg/crashtests/435209-1.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg">
-<path/>
-
-<script xmlns="http://www.w3.org/1999/xhtml"><![CDATA[
-var x=document.getElementsByTagName('path')[0];
-var y = x.pathSegList;
-var z = x.createSVGPathSegMovetoRel(0,0);
-y.appendItem(z,0);
-y.replaceItem(z, 0);
-]]></script>
-</svg>
\ No newline at end of file
--- a/dom/svg/crashtests/crashtests.list
+++ b/dom/svg/crashtests/crashtests.list
@@ -1,22 +1,18 @@
 asserts(0-6) load 307322-1.svg # bug 563481
 load 327705-1.svg
 load 336994-1.html
 load 344888-1.svg
 load 345445-1.svg
 load 360836-1.svg
-load 367357-1.xhtml
 load 369051-1.svg
-load 369249-1.svg
 load 369291-1.svg
 load 369291-2.svg
 load 369568-1.svg
-load 372046-1.svg
-load 372046-2.svg
 load 374882-1.svg
 load 380101-1.svg 
 load 381777-1.svg
 load 383685-1.svg
 load 385096.html
 load 385554-1.html
 load 385554-2.xul
 load 388712-1.svg
@@ -36,17 +32,16 @@ load 410659-1.svg
 load 410659-2.svg
 load 410659-3.svg
 asserts(3-4) load 412104-1.svg # bug 903785
 load 413174-1.svg
 load 414188-1.svg
 load 427325-1.svg
 load 428228-1.svg
 load 428841-1.svg
-load 435209-1.svg
 load 436418-mpathRoot-1.svg
 load 448244-1.svg
 load 466576-1.xhtml
 load 499879-1.svg
 load 535691-1.svg
 load 539167-1.svg
 load 573316-1.svg
 load 579356-1.svg
--- a/dom/svg/test/mochitest.ini
+++ b/dom/svg/test/mochitest.ini
@@ -50,18 +50,17 @@ skip-if = true # disabled-for-intermitte
 [test_length.xhtml]
 [test_lengthParsing.html]
 [test_markerOrient.xhtml]
 [test_nonAnimStrings.xhtml]
 [test_non-scaling-stroke.html]
 [test_object-delayed-intrinsic-size.html]
 [test_onerror.xhtml]
 [test_pathAnimInterpolation.xhtml]
-[test_pathLength.html]
-[test_pathSeg.xhtml]
+skip-if = true # We need to polyfill the SVG DOM for path data
 [test_pointAtLength.xhtml]
 [test_pointer-events-1a.xhtml]
 [test_pointer-events-1b.xhtml]
 [test_pointer-events-2.xhtml]
 [test_pointer-events-3.xhtml]
 skip-if = android_version == '18' # bug 1147994
 [test_pointer-events-4.xhtml]
 [test_pointer-events-5.xhtml]
@@ -72,17 +71,16 @@ skip-if = android_version == '18' # bug 
 [test_style_sheet.html]
 [test_stroke-hit-testing.xhtml]
 [test_stroke-linecap-hit-testing.xhtml]
 [test_SVGLengthList-2.xhtml]
 [test_SVGLengthList.xhtml]
 [test_SVGMatrix.xhtml]
 [test_SVG_namespace_ids.html]
 [test_SVGNumberList.xhtml]
-[test_SVGPathSegList.xhtml]
 [test_SVGPointList.xhtml]
 [test_SVGStringList.xhtml]
 [test_SVGStyleElement.xhtml]
 [test_SVGTransformListAddition.xhtml]
 [test_SVGTransformList.xhtml]
 [test_SVGxxxListIndexing.xhtml]
 [test_SVGxxxList.xhtml]
 [test_switch.xhtml]
deleted file mode 100644
--- a/dom/svg/test/test_SVGPathSegList.xhtml
+++ /dev/null
@@ -1,128 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml">
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=611138
--->
-<head>
-  <title>Generic tests for SVG animated length lists</title>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="MutationEventChecker.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=611138">Mozilla Bug 611138</a>
-<p id="display"></p>
-<div id="content" style="display:none;">
-<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="100" height="100">
-  <path id="path"/>
-</svg>
-</div>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-<![CDATA[
-
-SimpleTest.waitForExplicitFinish();
-
-/*
-This file runs a series of SVGPathSegList specific tests. Generic SVGXxxList
-tests can be found in test_SVGxxxList.xhtml. Anything that can be generalized
-to other list types belongs there.
-*/
-
-function run_tests()
-{
-  document.getElementById('svg').pauseAnimations();
-
-  var d;
-  var seg;
-  var path = document.getElementById("path");
-  var list = path.pathSegList;
-
-  // See https://bugzilla.mozilla.org/show_bug.cgi?id=611138
-  // Here we are doing a replace with a segment (arc) that has more arguments
-  // than the total number of arguments in the entire path + 2 (the +2
-  // refering to the encoding of the segment types for the two segments).
-  path.setAttribute('d', 'M0,0 L100,100');
-  var arc = path.createSVGPathSegArcAbs(400, 0, 200, 200, 0, 1, 1);
-  list.replaceItem(arc, 1);
-
-  is(list.numberOfItems, 2, 'The length of the list should be the same after a valid replaceItem() call');
-  is(list.getItem(1), arc, 'The inserted object should now be the object at the index being replaced');
-
-  // Test whether and when we normalize the 'd' attribute:
-
-  d = "  \n  M  10  ,  10  \n  L  20  10  \n  ";
-  path.setAttribute('d', d);
-  is(path.getAttribute('d'), d, "Values passed to setAttribute for the 'd' attribute should not be normalised");
-  list.getItem(1).y = 20;
-  isnot(path.getAttribute('d'), d, "The 'd' attribute should change when its underlying DOM list changes");
-
-  // Test that path manipulations still work even when the path is invalid due
-  // to it not starting with a moveto segment:
-
-  path.setAttribute('d', 'M0,0 L1,1');
-  is(list.numberOfItems, 2, 'setAttribute should result in two items')
-
-  seg = list.getItem(1);
-  list.removeItem(0);
-  ok(list.numberOfItems == 1 && list.getItem(0) == seg,
-    'If removeItem removes the initial moveto leaving an invalid path, the other items should still be left in the list')
-
-  seg = path.createSVGPathSegLinetoAbs(1, 2);
-  list.appendItem(seg);
-  ok(list.numberOfItems == 2 && list.getItem(1) == seg,
-    'appendItem should be able to append to an invalid path');
-
-  seg = path.createSVGPathSegLinetoAbs(1, 2);
-  list.replaceItem(seg, 1);
-  ok(list.numberOfItems == 2 && list.getItem(1) == seg,
-    'replaceItem should be able to replace items in an invalid path');
-
-  seg = path.createSVGPathSegLinetoAbs(1, 2);
-  list.insertItemBefore(seg, 1);
-  ok(list.numberOfItems == 3 && list.getItem(1) == seg,
-    'insertItemBefore should be able insert items into an invalid path');
-
-  seg = path.createSVGPathSegLinetoAbs(1, 2);
-  list.initialize(seg);
-  ok(list.numberOfItems == 1 && list.getItem(0) == seg,
-    'initialize should be able initialize an invalid path with a non-moveto item');
-
-  // Test mutation events
-
-  eventChecker = new MutationEventChecker;
-  d = 'M0,0 L12,34'
-  path.setAttribute('d', d);
-  eventChecker.watchAttr(path, "d");
-
-  // -- Actual changes
-  eventChecker.expect("modify modify modify");
-  list[0].x = 10;
-  list[0].y = 5;
-  path.setAttribute("d", "M20,5 L12,34");
-
-  // -- Redundant changes
-  eventChecker.expect("");
-  list[0].x = 20;
-  list[1].y = 34;
-  path.setAttribute("d", "M20,5 L12,34");
-
-  // -- Attribute removal
-  eventChecker.expect("remove");
-  path.removeAttribute("d");
-
-  // -- Non-existent attribute removal
-  eventChecker.expect("");
-  path.removeAttribute("d");
-  path.removeAttributeNS(null, "d");
-  eventChecker.finish();
-
-  SimpleTest.finish();
-}
-
-window.addEventListener("load", run_tests);
-
-]]>
-</script>
-</pre>
-</body>
-</html>
--- a/dom/svg/test/test_SVGxxxList.xhtml
+++ b/dom/svg/test/test_SVGxxxList.xhtml
@@ -218,71 +218,16 @@ var tests = [
          typeof(itemB.y) != 'undefined',
          'expecting y property');
 
       is(itemA.x, itemB.x, message);
       is(itemA.y, itemB.y, message);
     }
   },
   {
-    // SVGPathSegList test:
-    target_element_id: 'path',
-    attr_name: 'd',
-    prop_name: null, // SVGAnimatedPathData is an inherited interface!
-    bv_name: 'pathSegList',
-    av_name: 'animatedPathSegList',
-    el_type: 'SVGPathElement',
-    prop_type: null,
-    list_type: 'SVGPathSegList',
-    item_type: 'SVGPathSeg',
-    attr_val_3a: 'M 10,10 L 50,50 L 90,10',
-    attr_val_3b: 'M 10,50 L 50,10 L 90,50',
-    attr_val_4 : 'M 10,10 L 50,50 L 90,10 M 200,100',
-    attr_val_5a: 'M 10,10 L 50,50 L 90,10 L 130,50 L 170,10',
-    attr_val_5b: 'M 50,10 L 50,10 L 90,50 L 130,10 L 170,50',
-    attr_val_5b_firstItem_x3_constructor: function(constructor) {
-      var expected = constructor();
-      is(expected.pathSegTypeAsLetter, "M",
-         "test error -- expected constructor to generate a segment of type M");
-      expected.x = 150;
-      expected.y = 30;
-      return expected;
-    },
-    item_constructor: function() {
-      // XXX return different values each time
-      return document.getElementById('path').createSVGPathSegMovetoAbs(1, 1);
-    },
-    item_is: function(itemA, itemB, message) {
-      ok(typeof(itemA.pathSegTypeAsLetter) != 'undefined' &&
-         typeof(itemB.pathSegTypeAsLetter) != 'undefined',
-         'expecting pathSegTypeAsLetter property');
-
-      // First: are we dealing  with the same type of segment?
-      is(itemA.pathSegTypeAsLetter, itemB.pathSegTypeAsLetter, message);
-      if (itemA.pathSegTypeAsLetter != itemB.pathSegTypeAsLetter)
-        return;  // The rest of this function is nonsense if types don't match.
-
-      // Make sure property-counts match (so we can iterate across itemA's
-      // properties and not worry about itemB having extra properties that
-      // we might be skipping over).
-      is(keys(itemA).length, keys(itemB).length,
-        'expecting same property-count when comparing path segs of same type.');
-
-      // Compare the properties, skipping the constant properties inherited
-      // from 'SVGPathSeg', and skipping the pathSegTypeAsLetter field since we
-      // already checked that above.
-      for (var prop in itemA) {
-        if (!SVGPathSeg.hasOwnProperty(prop) &&
-            prop != 'pathSegTypeAsLetter') {
-          is(itemA[prop], itemB[prop], message);
-        }
-      }
-    }
-  },
-  {
     // SVGStringList test:
     target_element_id: 'g',
     attr_name: 'requiredFeatures', // requiredExtensions, systemLanguage, viewTarget
     prop_name: null, // SVGStringList attributes are not animatable
     bv_name: 'requiredFeatures',
     av_name: null,
     el_type: 'SVGGElement',
     prop_type: null,
@@ -1165,24 +1110,22 @@ function run_animation_timeline_tests()
        'The start of an animation should never affect the '+t.list_type+
        ' for '+t.bv_path+', or its list items.');
 
     ok(t.animVal.numberOfItems == 5 && t.animVal.getItem(4) != null,
        'The start of the animation should have changed the number of items '+
        'in the '+t.list_type+' for '+t.bv_path+' to 5.');
 
     // TODO
-    if (t.list_type != 'SVGPathSegList') {
     ok(t.animVal.getItem(3) === t.old_animVal_items[3],
        'When affected by SMIL animation, list items in the '+t.list_type+
        ' for '+t.bv_path+' that are at indexes that existed prior to the '+
        'start of the animation should be the exact same objects as the '+
        'objects that were at those indexes prior to the start of the '+
        'animation.');
-    }
 
     t.old_animVal_items = get_array_of_list_items(t.animVal);
 
     t.element.setAttribute(t.attr_name, t.attr_val_3a);
 
     ok(t.baseVal.numberOfItems == 3 &&
        t.baseVal.getItem(2) === t.old_baseVal_items[2],
        'Setting the underlying attribute should change the items in the '+
--- a/dom/svg/test/test_SVGxxxListIndexing.xhtml
+++ b/dom/svg/test/test_SVGxxxListIndexing.xhtml
@@ -43,23 +43,16 @@ var tests = [
                 { values: "1em 2em 3em 4em 5em", length: 5 } ] },
   { element: text,
     attribute: "rotate",
     listProperty: "rotate.baseVal",
     type: "SVGNumberList",
     subtests: [ { values: null, length: 3 },
                 { values: "10", length: 1 },
                 { values: "1 2 3 4 5", length: 5 } ] },
-  { element: path,
-    attribute: "d",
-    listProperty: "pathSegList",
-    type: "SVGPathSegList",
-    subtests: [ { values: null, length: 2 },
-                { values: "M50,50", length: 1 },
-                { values: "M0,0 h10 v20 h30 v40", length: 5 } ] },
   { element: poly,
     attribute: "points",
     listProperty: "animatedPoints",
     type: "SVGPointList",
     subtests: [ { values: null, length: 3 },
                 { values: "100,100", length: 1 },
                 { values: "0,0 10,10 20,0 30,10 40,0", length: 5 } ] },
   { element: g,
deleted file mode 100644
--- a/dom/svg/test/test_pathLength.html
+++ /dev/null
@@ -1,58 +0,0 @@
-<!doctype html>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=1024926
--->
-<head>
-  <meta charset="utf-8">
-  <title>Test path length changes when manipulated</title>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1024926">Mozilla Bug 1024926</a>
-<p id="display"></p>
-<div id="content" style="display: none">
-  <svg width="100%" height="1" id="svg">
-    <path id="path_lines" d="M50,100l0,0l0,-50l100,0l86.3325,122.665z"></path>
-    <path id="path_straight_curve" d="M0,0 C100,0 150,0 200,0" />
-    <path id="path_straight_arc" d="M0,0 A100,0 0 0 0 200, 0" />
-  </svg>
-</div>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-
-  SimpleTest.waitForExplicitFinish();
-
-  // Test a closed path with a series of lines.
-  var path = document.getElementById("path_lines");
-  is(path.getTotalLength(), 500, "Unexpected path length");
-
-  // Test a path that's been shortened via the DOM.
-  for (var i = 0; i < 2; i++) {
-      path.pathSegList.removeItem(path.pathSegList.numberOfItems - 1);
-  }
-  is(path.getTotalLength(), 150, "Unexpected path length");
-
-  // Test a path that's been shortened to be empty, via the DOM.
-  while (path.pathSegList.numberOfItems > 0) {
-      path.pathSegList.removeItem(0);
-  }
-  is(path.getTotalLength(), 0, "Unexpected path length");
-
-  // Test a path with a curve command ("C") that is really a straight line.
-  path = document.getElementById("path_straight_curve");
-  is(path.getTotalLength(), 200, "Unexpected path length, for straight line " +
-                                 "generated by 'C' command");
-
-  // Test a path with an arc command ("A") that is really a straight line.
-  path = document.getElementById("path_straight_arc");
-  is(path.getTotalLength(), 200, "Unexpected path length, for straight line " +
-                                 "generated by 'A' command");
-
-  SimpleTest.finish();
-
-</script>
-</pre>
-</body>
-</html>
deleted file mode 100644
--- a/dom/svg/test/test_pathSeg.xhtml
+++ /dev/null
@@ -1,142 +0,0 @@
-<!DOCTYPE html>
-<html xmlns="http://www.w3.org/1999/xhtml">
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=459953
--->
-<head>
-  <title>Test for Bug 459953</title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=459953">Mozilla Bug 459953</a>
-<p id="display"></p>
-
-<pre id="test">
-<script class="testbody" type="application/javascript">
-<![CDATA[
-SimpleTest.waitForExplicitFinish();
-
-function runTest()
-{
-  var svgns="http://www.w3.org/2000/svg";
-
-  var path1=document.createElementNS(svgns, "path");
-
-  var sseg;
-  
-  var a=10,s=20,d=30,z=9; //Arbitrary numbers for arguments
-  
-  var whatever=true; //This is often so, but here it does not matter
-  
-  sseg=path1.createSVGPathSegMovetoAbs(a, s);
-  path1.pathSegList.appendItem(sseg);
-  sseg=path1.createSVGPathSegMovetoRel(a, s);
-  path1.pathSegList.appendItem(sseg);
-  sseg=path1.createSVGPathSegLinetoAbs(a, s);
-  path1.pathSegList.appendItem(sseg);
-  sseg=path1.createSVGPathSegLinetoRel(a, s);
-  path1.pathSegList.appendItem(sseg);
-  sseg=path1.createSVGPathSegLinetoVerticalAbs(a);
-  path1.pathSegList.appendItem(sseg);
-  sseg=path1.createSVGPathSegLinetoVerticalRel(a);
-  path1.pathSegList.appendItem(sseg);
-  sseg=path1.createSVGPathSegLinetoHorizontalAbs(a);
-  path1.pathSegList.appendItem(sseg);
-  sseg=path1.createSVGPathSegLinetoHorizontalRel(a);
-  path1.pathSegList.appendItem(sseg);
-  sseg=path1.createSVGPathSegCurvetoCubicAbs(a, s, d, z, a, s);
-  path1.pathSegList.appendItem(sseg);
-  sseg=path1.createSVGPathSegCurvetoCubicRel(a, s, d, z, a, s);
-  path1.pathSegList.appendItem(sseg);
-  sseg=path1.createSVGPathSegCurvetoCubicSmoothAbs(a, s, d, z);
-  path1.pathSegList.appendItem(sseg);
-  sseg=path1.createSVGPathSegCurvetoCubicSmoothRel(a, s, d, z);
-  path1.pathSegList.appendItem(sseg);
-  sseg=path1.createSVGPathSegCurvetoQuadraticAbs(a, s, d, z);
-  path1.pathSegList.appendItem(sseg);
-  sseg=path1.createSVGPathSegCurvetoQuadraticRel(a, s, d, z);
-  path1.pathSegList.appendItem(sseg);
-  sseg=path1.createSVGPathSegCurvetoQuadraticSmoothAbs(a, s);
-  path1.pathSegList.appendItem(sseg);
-  sseg=path1.createSVGPathSegCurvetoQuadraticSmoothRel(a, s);
-  path1.pathSegList.appendItem(sseg);
-  sseg=path1.createSVGPathSegArcAbs(a, s, d, z, a, whatever, whatever);
-  path1.pathSegList.appendItem(sseg);
-  sseg=path1.createSVGPathSegArcRel(a, s, d, z, a, whatever, whatever);
-  path1.pathSegList.appendItem(sseg);
-  sseg=path1.createSVGPathSegClosePath();
-  path1.pathSegList.appendItem(sseg);
-  
-  for(var i=0;i<path1.pathSegList.numberOfItems;i++){
-    var seg=path1.pathSegList.getItem(i);
-    switch(seg.pathSegType){
-    case seg.PATHSEG_MOVETO_ABS:
-      is(seg.pathSegTypeAsLetter, "M", "wrong path segment letter");      
-      break;
-    case seg.PATHSEG_MOVETO_REL:
-      is(seg.pathSegTypeAsLetter, "m", "wrong path segment letter");      
-      break;
-    case seg.PATHSEG_CLOSEPATH:
-      is(seg.pathSegTypeAsLetter, "z", "wrong path segment letter");      
-      break;
-    case seg.PATHSEG_LINETO_ABS:
-      is(seg.pathSegTypeAsLetter, "L", "wrong path segment letter");      
-      break;
-    case seg.PATHSEG_LINETO_REL:
-      is(seg.pathSegTypeAsLetter, "l", "wrong path segment letter");      
-      break;
-    case seg.PATHSEG_LINETO_VERTICAL_ABS:
-      is(seg.pathSegTypeAsLetter, "V", "wrong path segment letter");      
-      break;
-    case seg.PATHSEG_LINETO_VERTICAL_REL:
-      is(seg.pathSegTypeAsLetter, "v", "wrong path segment letter");      
-      break;
-    case seg.PATHSEG_LINETO_HORIZONTAL_ABS:
-      is(seg.pathSegTypeAsLetter, "H", "wrong path segment letter");      
-      break;
-    case seg.PATHSEG_LINETO_HORIZONTAL_REL:
-      is(seg.pathSegTypeAsLetter, "h", "wrong path segment letter");      
-      break;
-    case seg.PATHSEG_CURVETO_CUBIC_ABS:
-      is(seg.pathSegTypeAsLetter, "C", "wrong path segment letter");      
-      break;
-    case seg.PATHSEG_CURVETO_CUBIC_REL:
-      is(seg.pathSegTypeAsLetter, "c", "wrong path segment letter");      
-      break;
-    case seg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:
-      is(seg.pathSegTypeAsLetter, "S", "wrong path segment letter");      
-      break;
-    case seg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL:
-      is(seg.pathSegTypeAsLetter, "s", "wrong path segment letter");      
-      break;
-    case seg.PATHSEG_CURVETO_QUADRATIC_ABS:
-      is(seg.pathSegTypeAsLetter, "Q", "wrong path segment letter");      
-      break;
-    case seg.PATHSEG_CURVETO_QUADRATIC_REL:
-      is(seg.pathSegTypeAsLetter, "q", "wrong path segment letter");      
-      break;
-    case seg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:
-      is(seg.pathSegTypeAsLetter, "T", "wrong path segment letter");      
-      break;
-    case seg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:
-      is(seg.pathSegTypeAsLetter, "t", "wrong path segment letter");      
-      break;
-    case seg.PATHSEG_ARC_ABS:
-      is(seg.pathSegTypeAsLetter, "A", "wrong path segment letter");      
-      break;
-    case seg.PATHSEG_ARC_REL:
-      is(seg.pathSegTypeAsLetter, "a", "wrong path segment letter");      
-      break;
-      
-    }
-  }
-  SimpleTest.finish();
-}
-
-window.addEventListener("load", runTest);
-]]>
-</script>
-</pre>
-</body>
-</html>
--- a/dom/tests/mochitest/general/test_interfaces.js
+++ b/dom/tests/mochitest/general/test_interfaces.js
@@ -1022,58 +1022,18 @@ var interfaceNamesInGlobalScope =
     {name: "SVGMPathElement", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "SVGNumber", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "SVGNumberList", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "SVGPathElement", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "SVGPathSeg", insecureContext: true},
-// IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "SVGPathSegArcAbs", insecureContext: true},
-// IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "SVGPathSegArcRel", insecureContext: true},
-// IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "SVGPathSegClosePath", insecureContext: true},
-// IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "SVGPathSegCurvetoCubicAbs", insecureContext: true},
-// IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "SVGPathSegCurvetoCubicRel", insecureContext: true},
-// IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "SVGPathSegCurvetoCubicSmoothAbs", insecureContext: true},
-// IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "SVGPathSegCurvetoCubicSmoothRel", insecureContext: true},
-// IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "SVGPathSegCurvetoQuadraticAbs", insecureContext: true},
-// IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "SVGPathSegCurvetoQuadraticRel", insecureContext: true},
-// IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "SVGPathSegCurvetoQuadraticSmoothAbs", insecureContext: true},
-// IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "SVGPathSegCurvetoQuadraticSmoothRel", insecureContext: true},
-// IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "SVGPathSegLinetoAbs", insecureContext: true},
-// IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "SVGPathSegLinetoHorizontalAbs", insecureContext: true},
-// IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "SVGPathSegLinetoHorizontalRel", insecureContext: true},
-// IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "SVGPathSegLinetoRel", insecureContext: true},
-// IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "SVGPathSegLinetoVerticalAbs", insecureContext: true},
-// IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "SVGPathSegLinetoVerticalRel", insecureContext: true},
-// IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "SVGPathSegList", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "SVGPathSegMovetoAbs", insecureContext: true},
-// IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "SVGPathSegMovetoRel", insecureContext: true},
-// IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "SVGPatternElement", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "SVGPoint", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "SVGPointList", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "SVGPolygonElement", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
--- a/dom/webbrowserpersist/nsWebBrowserPersist.cpp
+++ b/dom/webbrowserpersist/nsWebBrowserPersist.cpp
@@ -2108,20 +2108,20 @@ nsWebBrowserPersist::CalculateUniqueFile
 
         if (localFile)
         {
             nsAutoString filenameAsUnichar;
             CopyASCIItoUTF16(filename, filenameAsUnichar);
             localFile->SetLeafName(filenameAsUnichar);
 
             // Resync the URI with the file after the extension has been appended
-            return NS_MutateURI(aURI)
-                     .Apply<nsIFileURLMutator>(&nsIFileURLMutator::SetFile,
-                                               localFile)
-                     .Finalize(aOutURI);
+            nsresult rv;
+            nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(aURI, &rv);
+            NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
+            fileURL->SetFile(localFile);  // this should recalculate uri
         }
         else
         {
             return NS_MutateURI(url)
                      .Apply<nsIURLMutator>(&nsIURLMutator::SetFileName,
                                            filename,
                                            nullptr)
                      .Finalize(aOutURI);
@@ -2287,20 +2287,19 @@ nsWebBrowserPersist::CalculateAndAppendF
                     newFileName.Append(fileExt);
                 }
 
                 if (localFile)
                 {
                     localFile->SetLeafName(NS_ConvertUTF8toUTF16(newFileName));
 
                     // Resync the URI with the file after the extension has been appended
-                    return NS_MutateURI(aURI)
-                             .Apply<nsIFileURLMutator>(&nsIFileURLMutator::SetFile,
-                                                   localFile)
-                             .Finalize(aOutURI);
+                    nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(aURI, &rv);
+                    NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
+                    fileURL->SetFile(localFile);  // this should recalculate uri
                 }
                 else
                 {
                     return NS_MutateURI(url)
                              .Apply<nsIURLMutator>(&nsIURLMutator::SetFileName,
                                                    newFileName,
                                                    nullptr)
                              .Finalize(aOutURI);
--- a/dom/webidl/SVGPathElement.webidl
+++ b/dom/webidl/SVGPathElement.webidl
@@ -7,50 +7,12 @@
  * http://www.w3.org/TR/SVG2/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 interface SVGPathElement : SVGGeometryElement {
 
   unsigned long getPathSegAtLength(float distance);
-  [NewObject]
-  SVGPathSegClosePath createSVGPathSegClosePath();
-  [NewObject]
-  SVGPathSegMovetoAbs createSVGPathSegMovetoAbs(float x, float y);
-  [NewObject]
-  SVGPathSegMovetoRel createSVGPathSegMovetoRel(float x, float y);
-  [NewObject]
-  SVGPathSegLinetoAbs createSVGPathSegLinetoAbs(float x, float y);
-  [NewObject]
-  SVGPathSegLinetoRel createSVGPathSegLinetoRel(float x, float y);
-  [NewObject]
-  SVGPathSegCurvetoCubicAbs createSVGPathSegCurvetoCubicAbs(float x, float y, float x1, float y1, float x2, float y2);
-  [NewObject]
-  SVGPathSegCurvetoCubicRel createSVGPathSegCurvetoCubicRel(float x, float y, float x1, float y1, float x2, float y2);
-  [NewObject]
-  SVGPathSegCurvetoQuadraticAbs createSVGPathSegCurvetoQuadraticAbs(float x, float y, float x1, float y1);
-  [NewObject]
-  SVGPathSegCurvetoQuadraticRel createSVGPathSegCurvetoQuadraticRel(float x, float y, float x1, float y1);
-  [NewObject]
-  SVGPathSegArcAbs createSVGPathSegArcAbs(float x, float y, float r1, float r2, float angle, boolean largeArcFlag, boolean sweepFlag);
-  [NewObject]
-  SVGPathSegArcRel createSVGPathSegArcRel(float x, float y, float r1, float r2, float angle, boolean largeArcFlag, boolean sweepFlag);
-  [NewObject]
-  SVGPathSegLinetoHorizontalAbs createSVGPathSegLinetoHorizontalAbs(float x);
-  [NewObject]
-  SVGPathSegLinetoHorizontalRel createSVGPathSegLinetoHorizontalRel(float x);
-  [NewObject]
-  SVGPathSegLinetoVerticalAbs createSVGPathSegLinetoVerticalAbs(float y);
-  [NewObject]
-  SVGPathSegLinetoVerticalRel createSVGPathSegLinetoVerticalRel(float y);
-  [NewObject]
-  SVGPathSegCurvetoCubicSmoothAbs createSVGPathSegCurvetoCubicSmoothAbs(float x, float y, float x2, float y2);
-  [NewObject]
-  SVGPathSegCurvetoCubicSmoothRel createSVGPathSegCurvetoCubicSmoothRel(float x, float y, float x2, float y2);
-  [NewObject]
-  SVGPathSegCurvetoQuadraticSmoothAbs createSVGPathSegCurvetoQuadraticSmoothAbs(float x, float y);
-  [NewObject]
-  SVGPathSegCurvetoQuadraticSmoothRel createSVGPathSegCurvetoQuadraticSmoothRel(float x, float y);
 };
 
 SVGPathElement implements SVGAnimatedPathData;
 
--- a/dom/webidl/SVGPathSeg.webidl
+++ b/dom/webidl/SVGPathSeg.webidl
@@ -5,16 +5,17 @@
  *
  * The origin of this IDL file is
  * http://www.w3.org/TR/SVG2/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
+[NoInterfaceObject]
 interface SVGPathSeg {
 
   // Path Segment Types
   const unsigned short PATHSEG_UNKNOWN = 0;
   const unsigned short PATHSEG_CLOSEPATH = 1;
   const unsigned short PATHSEG_MOVETO_ABS = 2;
   const unsigned short PATHSEG_MOVETO_REL = 3;
   const unsigned short PATHSEG_LINETO_ABS = 4;
@@ -35,99 +36,109 @@ interface SVGPathSeg {
   const unsigned short PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL = 19;
 
   [Pure]
   readonly attribute unsigned short pathSegType;
   [Pure]
   readonly attribute DOMString pathSegTypeAsLetter;
 };
 
+[NoInterfaceObject]
 interface SVGPathSegClosePath : SVGPathSeg {
 };
 
+[NoInterfaceObject]
 interface SVGPathSegMovetoAbs : SVGPathSeg {
   [SetterThrows]
   attribute float x;
   [SetterThrows]
   attribute float y;
 };
 
+[NoInterfaceObject]
 interface SVGPathSegMovetoRel : SVGPathSeg {
   [SetterThrows]
   attribute float x;
   [SetterThrows]
   attribute float y;
 };
 
+[NoInterfaceObject]
 interface SVGPathSegLinetoAbs : SVGPathSeg {
   [SetterThrows]
   attribute float x;
   [SetterThrows]
   attribute float y;
 };
 
+[NoInterfaceObject]
 interface SVGPathSegLinetoRel : SVGPathSeg {
   [SetterThrows]
   attribute float x;
   [SetterThrows]
   attribute float y;
 };
 
+[NoInterfaceObject]
 interface SVGPathSegCurvetoCubicAbs : SVGPathSeg {
   [SetterThrows]
   attribute float x;
   [SetterThrows]
   attribute float y;
   [SetterThrows]
   attribute float x1;
   [SetterThrows]
   attribute float y1;
   [SetterThrows]
   attribute float x2;
   [SetterThrows]
   attribute float y2;
 };
 
+[NoInterfaceObject]
 interface SVGPathSegCurvetoCubicRel : SVGPathSeg {
   [SetterThrows]
   attribute float x;
   [SetterThrows]
   attribute float y;
   [SetterThrows]
   attribute float x1;
   [SetterThrows]
   attribute float y1;
   [SetterThrows]
   attribute float x2;
   [SetterThrows]
   attribute float y2;
 };
 
+[NoInterfaceObject]
 interface SVGPathSegCurvetoQuadraticAbs : SVGPathSeg {
   [SetterThrows]
   attribute float x;
   [SetterThrows]
   attribute float y;
   [SetterThrows]
   attribute float x1;
   [SetterThrows]
   attribute float y1;
 };
 
+[NoInterfaceObject]
 interface SVGPathSegCurvetoQuadraticRel : SVGPathSeg {
   [SetterThrows]
   attribute float x;
   [SetterThrows]
   attribute float y;
   [SetterThrows]
   attribute float x1;
   [SetterThrows]
   attribute float y1;
 };
 
+[NoInterfaceObject]
 interface SVGPathSegArcAbs : SVGPathSeg {
   [SetterThrows]
   attribute float x;
   [SetterThrows]
   attribute float y;
   [SetterThrows]
   attribute float r1;
   [SetterThrows]
@@ -135,16 +146,17 @@ interface SVGPathSegArcAbs : SVGPathSeg 
   [SetterThrows]
   attribute float angle;
   [SetterThrows]
   attribute boolean largeArcFlag;
   [SetterThrows]
   attribute boolean sweepFlag;
 };
 
+[NoInterfaceObject]
 interface SVGPathSegArcRel : SVGPathSeg {
   [SetterThrows]
   attribute float x;
   [SetterThrows]
   attribute float y;
   [SetterThrows]
   attribute float r1;
   [SetterThrows]
@@ -152,64 +164,72 @@ interface SVGPathSegArcRel : SVGPathSeg 
   [SetterThrows]
   attribute float angle;
   [SetterThrows]
   attribute boolean largeArcFlag;
   [SetterThrows]
   attribute boolean sweepFlag;
 };
 
+[NoInterfaceObject]
 interface SVGPathSegLinetoHorizontalAbs : SVGPathSeg {
   [SetterThrows]
   attribute float x;
 };
 
+[NoInterfaceObject]
 interface SVGPathSegLinetoHorizontalRel : SVGPathSeg {
   [SetterThrows]
   attribute float x;
 };
 
+[NoInterfaceObject]
 interface SVGPathSegLinetoVerticalAbs : SVGPathSeg {
   [SetterThrows]
   attribute float y;
 };
 
+[NoInterfaceObject]
 interface SVGPathSegLinetoVerticalRel : SVGPathSeg {
   [SetterThrows]
   attribute float y;
 };
 
+[NoInterfaceObject]
 interface SVGPathSegCurvetoCubicSmoothAbs : SVGPathSeg {
   [SetterThrows]
   attribute float x;
   [SetterThrows]
   attribute float y;
   [SetterThrows]
   attribute float x2;
   [SetterThrows]
   attribute float y2;
 };
 
+[NoInterfaceObject]
 interface SVGPathSegCurvetoCubicSmoothRel : SVGPathSeg {
   [SetterThrows]
   attribute float x;
   [SetterThrows]
   attribute float y;
   [SetterThrows]
   attribute float x2;
   [SetterThrows]
   attribute float y2;
 };
 
+[NoInterfaceObject]
 interface SVGPathSegCurvetoQuadraticSmoothAbs : SVGPathSeg {
   [SetterThrows]
   attribute float x;
   [SetterThrows]
   attribute float y;
 };
 
+[NoInterfaceObject]
 interface SVGPathSegCurvetoQuadraticSmoothRel : SVGPathSeg {
   [SetterThrows]
   attribute float x;
   [SetterThrows]
   attribute float y;
 };
 
--- a/dom/webidl/SVGPathSegList.webidl
+++ b/dom/webidl/SVGPathSegList.webidl
@@ -8,25 +8,13 @@
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 interface SVGPathSegList {
   readonly attribute unsigned long numberOfItems;
   [Throws]
-  void clear();
-  [Throws]
-  SVGPathSeg initialize(SVGPathSeg newItem);
-  [Throws]
   getter SVGPathSeg getItem(unsigned long index);
-  [Throws]
-  SVGPathSeg insertItemBefore(SVGPathSeg newItem, unsigned long index);
-  [Throws]
-  SVGPathSeg replaceItem(SVGPathSeg newItem, unsigned long index);
-  [Throws]
-  SVGPathSeg removeItem(unsigned long index);
-  [Throws]
-  SVGPathSeg appendItem(SVGPathSeg newItem);
 
   // Mozilla-specific stuff
   readonly attribute unsigned long length; // synonym for numberOfItems
 };
--- a/dom/webidl/WebAuthentication.webidl
+++ b/dom/webidl/WebAuthentication.webidl
@@ -50,18 +50,17 @@ dictionary MakePublicKeyCredentialOption
 
     required BufferSource                            challenge;
     required sequence<PublicKeyCredentialParameters> pubKeyCredParams;
 
     unsigned long                                timeout;
     sequence<PublicKeyCredentialDescriptor>      excludeCredentials = [];
     AuthenticatorSelectionCriteria               authenticatorSelection;
     AttestationConveyancePreference              attestation = "none";
-    // Extensions are not supported yet.
-    // AuthenticationExtensions                  extensions; // Add in Bug 1406458
+    AuthenticationExtensionsClientInputs         extensions;
 };
 
 dictionary PublicKeyCredentialEntity {
     required DOMString    name;
     USVString             icon;
 };
 
 dictionary PublicKeyCredentialRpEntity : PublicKeyCredentialEntity {
@@ -97,31 +96,35 @@ enum UserVerificationRequirement {
 };
 
 dictionary PublicKeyCredentialRequestOptions {
     required BufferSource                challenge;
     unsigned long                        timeout;
     USVString                            rpId;
     sequence<PublicKeyCredentialDescriptor> allowCredentials = [];
     UserVerificationRequirement          userVerification = "preferred";
-    // Extensions are not supported yet.
-    // AuthenticationExtensions             extensions; // Add in Bug 1406458
+    AuthenticationExtensionsClientInputs extensions;
 };
 
-typedef record<DOMString, any>       AuthenticationExtensions;
+dictionary AuthenticationExtensionsClientInputs {
+};
+
+dictionary AuthenticationExtensionsClientOutputs {
+};
+
+typedef record<DOMString, DOMString> AuthenticationExtensionsAuthenticatorInputs;
 
 dictionary CollectedClientData {
     required DOMString           type;
     required DOMString           challenge;
     required DOMString           origin;
     required DOMString           hashAlgorithm;
     DOMString                    tokenBindingId;
-    // Extensions are not supported yet.
-    // AuthenticationExtensions     clientExtensions; // Add in Bug 1406458
-    // AuthenticationExtensions     authenticatorExtensions; // Add in Bug 1406458
+    AuthenticationExtensionsClientInputs clientExtensions;
+    AuthenticationExtensionsAuthenticatorInputs authenticatorExtensions;
 };
 
 enum PublicKeyCredentialType {
     "public-key"
 };
 
 dictionary PublicKeyCredentialDescriptor {
     required PublicKeyCredentialType      type;
--- a/gfx/layers/client/TextureClient.h
+++ b/gfx/layers/client/TextureClient.h
@@ -756,17 +756,17 @@ protected:
 
   // Used to assign serial ids of TextureClient.
   static mozilla::Atomic<uint64_t> sSerialCounter;
 
   friend class TextureChild;
   friend void TestTextureClientSurface(TextureClient*, gfxImageSurface*);
   friend void TestTextureClientYCbCr(TextureClient*, PlanarYCbCrData&);
   friend already_AddRefed<TextureHost> CreateTextureHostWithBackend(
-    TextureClient*, LayersBackend&);
+    TextureClient*, ISurfaceAllocator*, LayersBackend&);
 
 #ifdef GFX_DEBUG_TRACK_CLIENTS_IN_POOL
 public:
   // Pointer to the pool this tile came from.
   TextureClientPool* mPoolTracker;
 #endif
 };
 
--- a/gfx/layers/composite/TextureHost.cpp
+++ b/gfx/layers/composite/TextureHost.cpp
@@ -111,25 +111,19 @@ WrapWithWebRenderTextureHost(ISurfaceAll
 PTextureParent*
 TextureHost::CreateIPDLActor(HostIPCAllocator* aAllocator,
                              const SurfaceDescriptor& aSharedData,
                              LayersBackend aLayersBackend,
                              TextureFlags aFlags,
                              uint64_t aSerial,
                              const wr::MaybeExternalImageId& aExternalImageId)
 {
-  if (aSharedData.type() == SurfaceDescriptor::TSurfaceDescriptorBuffer &&
-      aSharedData.get_SurfaceDescriptorBuffer().data().type() == MemoryOrShmem::Tuintptr_t &&
-      !aAllocator->IsSameProcess())
-  {
-    NS_ERROR("A client process is trying to peek at our address space using a MemoryTexture!");
-    return nullptr;
-  }
   TextureParent* actor = new TextureParent(aAllocator, aSerial, aExternalImageId);
   if (!actor->Init(aSharedData, aLayersBackend, aFlags)) {
+    actor->ActorDestroy(ipc::IProtocol::ActorDestroyReason::FailedConstructor);
     delete actor;
     return nullptr;
   }
   return actor;
 }
 
 // static
 bool
@@ -227,33 +221,38 @@ TextureHost::Create(const SurfaceDescrip
         break;
       } else {
         result = CreateTextureHostBasic(aDesc, aDeallocator, aBackend, aFlags);
         break;
       }
 
 #ifdef MOZ_X11
     case SurfaceDescriptor::TSurfaceDescriptorX11: {
+      if (!aDeallocator->IsSameProcess()) {
+        NS_ERROR("A client process is trying to peek at our address space using a X11Texture!");
+        return nullptr;
+      }
+
       const SurfaceDescriptorX11& desc = aDesc.get_SurfaceDescriptorX11();
       result = MakeAndAddRef<X11TextureHost>(aFlags, desc);
       break;
     }
 #endif
 
 #ifdef XP_WIN
     case SurfaceDescriptor::TSurfaceDescriptorD3D10:
     case SurfaceDescriptor::TSurfaceDescriptorDXGIYCbCr:
       result = CreateTextureHostD3D11(aDesc, aDeallocator, aBackend, aFlags);
       break;
 #endif
     default:
       MOZ_CRASH("GFX: Unsupported Surface type host");
   }
 
-  if (WrapWithWebRenderTextureHost(aDeallocator, aBackend, aFlags)) {
+  if (result && WrapWithWebRenderTextureHost(aDeallocator, aBackend, aFlags)) {
     MOZ_ASSERT(aExternalImageId.isSome());
     result = new WebRenderTextureHost(aDesc, aFlags, result, aExternalImageId.ref());
   }
 
   return result.forget();
 }
 
 already_AddRefed<TextureHost>
@@ -264,23 +263,60 @@ CreateBackendIndependentTextureHost(cons
 {
   RefPtr<TextureHost> result;
   switch (aDesc.type()) {
     case SurfaceDescriptor::TSurfaceDescriptorBuffer: {
       const SurfaceDescriptorBuffer& bufferDesc = aDesc.get_SurfaceDescriptorBuffer();
       const MemoryOrShmem& data = bufferDesc.data();
       switch (data.type()) {
         case MemoryOrShmem::TShmem: {
-          result = new ShmemTextureHost(data.get_Shmem(),
-                                        bufferDesc.desc(),
-                                        aDeallocator,
-                                        aFlags);
+          const ipc::Shmem& shmem = data.get_Shmem();
+          const BufferDescriptor& desc = bufferDesc.desc();
+          if (!shmem.IsReadable()) {
+            // We failed to map the shmem so we can't verify its size. This
+            // should not be a fatal error, so just create the texture with
+            // nothing backing it.
+            result = new ShmemTextureHost(shmem, desc, aDeallocator, aFlags);
+            break;
+          }
+
+          size_t bufSize = shmem.Size<char>();
+          size_t reqSize = SIZE_MAX;
+          switch (desc.type()) {
+            case BufferDescriptor::TYCbCrDescriptor: {
+              const YCbCrDescriptor& ycbcr = desc.get_YCbCrDescriptor();
+              reqSize =
+                ImageDataSerializer::ComputeYCbCrBufferSize(ycbcr.ySize(), ycbcr.yStride(),
+                                                            ycbcr.cbCrSize(), ycbcr.cbCrStride());
+              break;
+            }
+            case BufferDescriptor::TRGBDescriptor: {
+              const RGBDescriptor& rgb = desc.get_RGBDescriptor();
+              reqSize = ImageDataSerializer::ComputeRGBBufferSize(rgb.size(), rgb.format());
+              break;
+            }
+            default:
+              gfxCriticalError() << "Bad buffer host descriptor " << (int)desc.type();
+              MOZ_CRASH("GFX: Bad descriptor");
+          }
+
+          if (bufSize < reqSize) {
+            NS_ERROR("A client process gave a shmem too small to fit for its descriptor!");
+            return nullptr;
+          }
+
+          result = new ShmemTextureHost(shmem, desc, aDeallocator, aFlags);
           break;
         }
         case MemoryOrShmem::Tuintptr_t: {
+          if (!aDeallocator->IsSameProcess()) {
+            NS_ERROR("A client process is trying to peek at our address space using a MemoryTexture!");
+            return nullptr;
+          }
+
           result = new MemoryTextureHost(reinterpret_cast<uint8_t*>(data.get_uintptr_t()),
                                          bufferDesc.desc(),
                                          aFlags);
           break;
         }
         default:
           gfxCriticalError() << "Failed texture host for backend " << (int)data.type();
           MOZ_CRASH("GFX: No texture host for backend");
@@ -288,16 +324,21 @@ CreateBackendIndependentTextureHost(cons
       break;
     }
     case SurfaceDescriptor::TSurfaceDescriptorGPUVideo: {
       result = new GPUVideoTextureHost(aFlags, aDesc.get_SurfaceDescriptorGPUVideo());
       break;
     }
 #ifdef XP_WIN
     case SurfaceDescriptor::TSurfaceDescriptorDIB: {
+      if (!aDeallocator->IsSameProcess()) {
+        NS_ERROR("A client process is trying to peek at our address space using a DIBTexture!");
+        return nullptr;
+      }
+
       result = new DIBTextureHost(aFlags, aDesc);
       break;
     }
     case SurfaceDescriptor::TSurfaceDescriptorFileMapping: {
       result = new TextureHostFileMapping(aFlags, aDesc);
       break;
     }
 #endif
--- a/gfx/layers/composite/X11TextureHost.cpp
+++ b/gfx/layers/composite/X11TextureHost.cpp
@@ -18,28 +18,27 @@ namespace mozilla {
 namespace layers {
 
 using namespace mozilla::gfx;
 
 X11TextureHost::X11TextureHost(TextureFlags aFlags,
                                const SurfaceDescriptorX11& aDescriptor)
  : TextureHost(aFlags)
 {
-  RefPtr<gfxXlibSurface> surface = aDescriptor.OpenForeign();
-  mSurface = surface.get();
+  mSurface = aDescriptor.OpenForeign();
 
-  if (!(aFlags & TextureFlags::DEALLOCATE_CLIENT)) {
+  if (mSurface && !(aFlags & TextureFlags::DEALLOCATE_CLIENT)) {
     mSurface->TakePixmap();
   }
 }
 
 bool
 X11TextureHost::Lock()
 {
-  if (!mCompositor) {
+  if (!mCompositor || !mSurface) {
     return false;
   }
 
   if (!mTextureSource) {
     switch (mCompositor->GetBackendType()) {
       case LayersBackend::LAYERS_BASIC:
         mTextureSource =
           new X11TextureSourceBasic(mCompositor->AsBasicCompositor(), mSurface);
@@ -70,28 +69,34 @@ X11TextureHost::SetTextureSourceProvider
   if (mTextureSource) {
     mTextureSource->SetTextureSourceProvider(aProvider);
   }
 }
 
 SurfaceFormat
 X11TextureHost::GetFormat() const
 {
+  if (!mSurface) {
+    return SurfaceFormat::UNKNOWN;
+  }
   gfxContentType type = mSurface->GetContentType();
 #ifdef GL_PROVIDER_GLX
   if (mCompositor->GetBackendType() == LayersBackend::LAYERS_OPENGL) {
     return X11TextureSourceOGL::ContentTypeToSurfaceFormat(type);
   }
 #endif
   return X11TextureSourceBasic::ContentTypeToSurfaceFormat(type);
 }
 
 IntSize
 X11TextureHost::GetSize() const
 {
+  if (!mSurface) {
+    return IntSize();
+  }
   return mSurface->GetSize();
 }
 
 already_AddRefed<gfx::DataSourceSurface>
 X11TextureHost::GetAsSurface()
 {
   if (!mTextureSource || !mTextureSource->AsSourceBasic()) {
     return nullptr;
--- a/gfx/layers/d3d11/TextureD3D11.cpp
+++ b/gfx/layers/d3d11/TextureD3D11.cpp
@@ -758,32 +758,28 @@ DXGIYCbCrTextureData::Deallocate(LayersI
 already_AddRefed<TextureHost>
 CreateTextureHostD3D11(const SurfaceDescriptor& aDesc,
                        ISurfaceAllocator* aDeallocator,
                        LayersBackend aBackend,
                        TextureFlags aFlags)
 {
   RefPtr<TextureHost> result;
   switch (aDesc.type()) {
-    case SurfaceDescriptor::TSurfaceDescriptorBuffer: {
-      result = CreateBackendIndependentTextureHost(aDesc, aDeallocator, aBackend, aFlags);
-      break;
-    }
     case SurfaceDescriptor::TSurfaceDescriptorD3D10: {
       result = new DXGITextureHostD3D11(aFlags,
                                         aDesc.get_SurfaceDescriptorD3D10());
       break;
     }
     case SurfaceDescriptor::TSurfaceDescriptorDXGIYCbCr: {
       result = new DXGIYCbCrTextureHostD3D11(aFlags,
                                              aDesc.get_SurfaceDescriptorDXGIYCbCr());
       break;
     }
     default: {
-      NS_WARNING("Unsupported SurfaceDescriptor type");
+      MOZ_ASSERT_UNREACHABLE("Unsupported SurfaceDescriptor type");
     }
   }
   return result.forget();
 }
 
 
 already_AddRefed<DrawTarget>
 D3D11TextureData::BorrowDrawTarget()
--- a/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp
+++ b/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp
@@ -27,16 +27,18 @@ MacIOSurfaceTextureHostOGL::MacIOSurface
 MacIOSurfaceTextureHostOGL::~MacIOSurfaceTextureHostOGL()
 {
   MOZ_COUNT_DTOR(MacIOSurfaceTextureHostOGL);
 }
 
 GLTextureSource*
 MacIOSurfaceTextureHostOGL::CreateTextureSourceForPlane(size_t aPlane)
 {
+  MOZ_ASSERT(mSurface);
+
   GLuint textureHandle;
   gl::GLContext* gl = mProvider->GetGLContext();
   gl->fGenTextures(1, &textureHandle);
   gl->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, textureHandle);
   gl->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
   gl->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
 
   gfx::SurfaceFormat readFormat = gfx::SurfaceFormat::UNKNOWN;
@@ -89,21 +91,27 @@ MacIOSurfaceTextureHostOGL::SetTextureSo
     mTextureSource = nullptr;
   }
 
   mProvider = aProvider;
 }
 
 gfx::SurfaceFormat
 MacIOSurfaceTextureHostOGL::GetFormat() const {
+  if (!mSurface) {
+    return gfx::SurfaceFormat::UNKNOWN;
+  }
   return mSurface->GetFormat();
 }
 
 gfx::SurfaceFormat
 MacIOSurfaceTextureHostOGL::GetReadFormat() const {
+  if (!mSurface) {
+    return gfx::SurfaceFormat::UNKNOWN;
+  }
   return mSurface->GetReadFormat();
 }
 
 gfx::IntSize
 MacIOSurfaceTextureHostOGL::GetSize() const {
   if (!mSurface) {
     return gfx::IntSize();
   }
--- a/gfx/layers/opengl/TextureHostOGL.cpp
+++ b/gfx/layers/opengl/TextureHostOGL.cpp
@@ -21,44 +21,32 @@
 #include "GfxTexturesReporter.h"        // for GfxTexturesReporter
 #include "GLBlitTextureImageHelper.h"
 #include "GeckoProfiler.h"
 
 #ifdef XP_MACOSX
 #include "mozilla/layers/MacIOSurfaceTextureHostOGL.h"
 #endif
 
-#ifdef GL_PROVIDER_GLX
-#include "mozilla/layers/X11TextureHost.h"
-#endif
-
 using namespace mozilla::gl;
 using namespace mozilla::gfx;
 
 namespace mozilla {
 namespace layers {
 
 class Compositor;
 
 already_AddRefed<TextureHost>
 CreateTextureHostOGL(const SurfaceDescriptor& aDesc,
                      ISurfaceAllocator* aDeallocator,
                      LayersBackend aBackend,
                      TextureFlags aFlags)
 {
   RefPtr<TextureHost> result;
   switch (aDesc.type()) {
-    case SurfaceDescriptor::TSurfaceDescriptorBuffer: {
-      result = CreateBackendIndependentTextureHost(aDesc,
-                                                   aDeallocator,
-                                                   aBackend,
-                                                   aFlags);
-      break;
-    }
-
 #ifdef MOZ_WIDGET_ANDROID
     case SurfaceDescriptor::TSurfaceTextureDescriptor: {
       const SurfaceTextureDescriptor& desc = aDesc.get_SurfaceTextureDescriptor();
       java::GeckoSurfaceTexture::LocalRef surfaceTexture = java::GeckoSurfaceTexture::Lookup(desc.handle());
 
       result = new SurfaceTextureHost(aFlags,
                                       surfaceTexture,
                                       desc.size(),
@@ -83,34 +71,29 @@ CreateTextureHostOGL(const SurfaceDescri
     case SurfaceDescriptor::TSurfaceDescriptorMacIOSurface: {
       const SurfaceDescriptorMacIOSurface& desc =
         aDesc.get_SurfaceDescriptorMacIOSurface();
       result = new MacIOSurfaceTextureHostOGL(aFlags, desc);
       break;
     }
 #endif
 
-#ifdef GL_PROVIDER_GLX
-    case SurfaceDescriptor::TSurfaceDescriptorX11: {
-      const auto& desc = aDesc.get_SurfaceDescriptorX11();
-      result = new X11TextureHost(aFlags, desc);
-      break;
-    }
-#endif
-
     case SurfaceDescriptor::TSurfaceDescriptorSharedGLTexture: {
       const auto& desc = aDesc.get_SurfaceDescriptorSharedGLTexture();
       result = new GLTextureHost(aFlags, desc.texture(),
                                  desc.target(),
                                  (GLsync)desc.fence(),
                                  desc.size(),
                                  desc.hasAlpha());
       break;
     }
-    default: return nullptr;
+    default: {
+      MOZ_ASSERT_UNREACHABLE("Unsupported SurfaceDescriptor type");
+      break;
+    }
   }
   return result.forget();
 }
 
 static gl::TextureImage::Flags
 FlagsToGLFlags(TextureFlags aFlags)
 {
   uint32_t result = TextureImage::NoFlags;
--- a/gfx/tests/gtest/TestLayers.h
+++ b/gfx/tests/gtest/TestLayers.h
@@ -3,16 +3,32 @@
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 #ifndef GFX_TEST_LAYERS_H
 #define GFX_TEST_LAYERS_H
 
 #include "Layers.h"
 #include "nsTArray.h"
+#include "mozilla/layers/ISurfaceAllocator.h"
+
+namespace mozilla {
+namespace layers {
+
+class TestSurfaceAllocator final : public ISurfaceAllocator
+{
+public:
+  TestSurfaceAllocator() {}
+  ~TestSurfaceAllocator() override {}
+
+  bool IsSameProcess() const override { return true; }
+};
+
+} // layers
+} // mozilla
 
 /* Create layer tree from a simple layer tree description syntax.
  * Each index is either the first letter of the layer type or
  * a '(',')' to indicate the start/end of the child layers.
  * The aim of this function is to remove hard to read
  * layer tree creation code.
  *
  * Example "c(c(c(tt)t))" would yield:
--- a/gfx/tests/gtest/TestTextureCompatibility.cpp
+++ b/gfx/tests/gtest/TestTextureCompatibility.cpp
@@ -9,46 +9,50 @@
 #include "gtest/gtest.h"
 #include "MockWidget.h"
 #include "mozilla/layers/BasicCompositor.h"
 #include "mozilla/layers/Compositor.h"
 #include "mozilla/layers/LayersTypes.h"
 #include "mozilla/layers/TextureClient.h"
 #include "mozilla/layers/TextureHost.h"
 #include "mozilla/RefPtr.h"
+#include "TestLayers.h"
 #include "TextureHelper.h"
 
 using mozilla::gfx::Feature;
 using mozilla::gfx::gfxConfig;
 using mozilla::layers::BasicCompositor;
 using mozilla::layers::Compositor;
 using mozilla::layers::CompositorOptions;
 using mozilla::layers::LayersBackend;
+using mozilla::layers::TestSurfaceAllocator;
 using mozilla::layers::TextureClient;
 using mozilla::layers::TextureHost;
 using mozilla::widget::CompositorWidget;
 using mozilla::widget::InProcessCompositorWidget;
 
 /**
  * This function will create the possible TextureClient and TextureHost pairs
  * according to the given backend.
  */
-void
+static void
 CreateTextureWithBackend(LayersBackend& aLayersBackend,
+                         ISurfaceAllocator* aDeallocator,
                          nsTArray<RefPtr<TextureClient>>& aTextureClients,
                          nsTArray<RefPtr<TextureHost>>& aTextureHosts)
 {
   aTextureClients.AppendElement(CreateTextureClientWithBackend(aLayersBackend));
 
   aTextureClients.AppendElement(
     CreateYCbCrTextureClientWithBackend(aLayersBackend));
 
   for (uint32_t i = 0; i < aTextureClients.Length(); i++) {
     aTextureHosts.AppendElement(
-      CreateTextureHostWithBackend(aTextureClients[i], aLayersBackend));
+      CreateTextureHostWithBackend(aTextureClients[i], aDeallocator,
+                                   aLayersBackend));
   }
 }
 
 /**
  * This will return the default list of backends that units test should run
  * against.
  */
 static void
@@ -110,18 +114,20 @@ CheckCompatibilityWithBasicCompositor(La
       aTextures[i]->Unlock();
     }
   }
 }
 
 TEST(Gfx, TestTextureCompatibility)
 {
   nsTArray<LayersBackend> backendHints;
+  RefPtr<TestSurfaceAllocator> deallocator = new TestSurfaceAllocator();
 
   GetPlatformBackends(backendHints);
   for (uint32_t i = 0; i < backendHints.Length(); i++) {
     nsTArray<RefPtr<TextureClient>> textureClients;
     nsTArray<RefPtr<TextureHost>> textureHosts;
 
-    CreateTextureWithBackend(backendHints[i], textureClients, textureHosts);
+    CreateTextureWithBackend(backendHints[i], deallocator,
+                             textureClients, textureHosts);
     CheckCompatibilityWithBasicCompositor(backendHints[i], textureHosts);
   }
 }
--- a/gfx/tests/gtest/TestTextures.cpp
+++ b/gfx/tests/gtest/TestTextures.cpp
@@ -1,15 +1,16 @@
 /* vim:set ts=2 sw=2 sts=2 et: */
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 #include "gtest/gtest.h"
 #include "gmock/gmock.h"
+#include "TestLayers.h"
 
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/Tools.h"
 #include "mozilla/layers/BufferTexture.h"
 #include "mozilla/layers/ImageBridgeChild.h"  // for ImageBridgeChild
 #include "mozilla/layers/TextureClient.h"
 #include "mozilla/layers/TextureHost.h"
 #include "mozilla/RefPtr.h"
@@ -142,17 +143,18 @@ void TestTextureClientSurface(TextureCli
 
   // client serialization
   SurfaceDescriptor descriptor;
   ASSERT_TRUE(texture->ToSurfaceDescriptor(descriptor));
 
   ASSERT_NE(descriptor.type(), SurfaceDescriptor::Tnull_t);
 
   // host deserialization
-  RefPtr<TextureHost> host = CreateBackendIndependentTextureHost(descriptor, nullptr,
+  RefPtr<TestSurfaceAllocator> deallocator = new TestSurfaceAllocator();
+  RefPtr<TextureHost> host = CreateBackendIndependentTextureHost(descriptor, deallocator,
                                                                  LayersBackend::LAYERS_NONE,
                                                                  texture->GetFlags());
 
   ASSERT_TRUE(host.get() != nullptr);
   ASSERT_EQ(host->GetFlags(), texture->GetFlags());
 
   // host read
 
@@ -188,17 +190,18 @@ void TestTextureClientYCbCr(TextureClien
   auto bufferDesc = descriptor.get_SurfaceDescriptorBuffer();
   ASSERT_EQ(bufferDesc.desc().type(), BufferDescriptor::TYCbCrDescriptor);
   auto ycbcrDesc = bufferDesc.desc().get_YCbCrDescriptor();
   ASSERT_EQ(ycbcrDesc.ySize(), ycbcrData.mYSize);
   ASSERT_EQ(ycbcrDesc.cbCrSize(), ycbcrData.mCbCrSize);
   ASSERT_EQ(ycbcrDesc.stereoMode(), ycbcrData.mStereoMode);
 
   // host deserialization
-  RefPtr<TextureHost> textureHost = CreateBackendIndependentTextureHost(descriptor, nullptr,
+  RefPtr<TestSurfaceAllocator> deallocator = new TestSurfaceAllocator();
+  RefPtr<TextureHost> textureHost = CreateBackendIndependentTextureHost(descriptor, deallocator,
                                                                         LayersBackend::LAYERS_NONE,
                                                                         client->GetFlags());
 
   RefPtr<BufferTextureHost> host = static_cast<BufferTextureHost*>(textureHost.get());
 
   ASSERT_TRUE(host.get() != nullptr);
   ASSERT_EQ(host->GetFlags(), client->GetFlags());
 
--- a/gfx/tests/gtest/TextureHelper.h
+++ b/gfx/tests/gtest/TextureHelper.h
@@ -135,27 +135,28 @@ CreateTextureClientWithBackend(LayersBac
   return nullptr;
 }
 
 /**
  * Create a TextureHost according to the given TextureClient.
  */
 already_AddRefed<TextureHost>
 CreateTextureHostWithBackend(TextureClient* aClient,
+                             ISurfaceAllocator* aDeallocator,
                              LayersBackend& aLayersBackend)
 {
   if (!aClient) {
     return nullptr;
   }
 
   // client serialization
   SurfaceDescriptor descriptor;
   RefPtr<TextureHost> textureHost;
 
   aClient->ToSurfaceDescriptor(descriptor);
 
   wr::MaybeExternalImageId id = Nothing();
-  return TextureHost::Create(descriptor, nullptr, aLayersBackend,
+  return TextureHost::Create(descriptor, aDeallocator, aLayersBackend,
                              aClient->GetFlags(), id);
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/webrender_bindings/RenderCompositorANGLE.cpp
+++ b/gfx/webrender_bindings/RenderCompositorANGLE.cpp
@@ -80,18 +80,21 @@ RenderCompositorANGLE::Initialize()
 
     DXGI_SWAP_CHAIN_DESC1 desc{};
     desc.Width = 0;
     desc.Height = 0;
     desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
     desc.SampleDesc.Count = 1;
     desc.SampleDesc.Quality = 0;
     desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
-    desc.BufferCount = 2;
-    desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
+    // Do not use DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, since it makes HWND unreusable.
+    //desc.BufferCount = 2;
+    //desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
+    desc.BufferCount = 1;
+    desc.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL;
     desc.Scaling = DXGI_SCALING_NONE;
     desc.Flags = 0;
 
     HRESULT hr = dxgiFactory2->CreateSwapChainForHwnd(mDevice, hwnd, &desc,
                                                       nullptr, nullptr,
                                                       getter_AddRefs(swapChain1));
     if (SUCCEEDED(hr) && swapChain1) {
       DXGI_RGBA color = { 1.0f, 1.0f, 1.0f, 1.0f };
--- a/image/IProgressObserver.h
+++ b/image/IProgressObserver.h
@@ -38,17 +38,18 @@ public:
 
   // imgINotificationObserver methods:
   virtual void Notify(int32_t aType, const nsIntRect* aRect = nullptr) = 0;
   virtual void OnLoadComplete(bool aLastPart) = 0;
 
   // Other, internal-only methods:
   virtual void SetHasImage() = 0;
   virtual bool NotificationsDeferred() const = 0;
-  virtual void SetNotificationsDeferred(bool aDeferNotifications) = 0;
+  virtual void MarkPendingNotify() = 0;
+  virtual void ClearPendingNotify() = 0;
 
   virtual already_AddRefed<nsIEventTarget> GetEventTarget() const
   {
     return nullptr;
   }
 
 protected:
   virtual ~IProgressObserver() { }
--- a/image/MultipartImage.cpp
+++ b/image/MultipartImage.cpp
@@ -90,17 +90,18 @@ public:
     if (tracker->GetProgress() & FLAG_HAS_ERROR) {
       FinishObserving();
     }
   }
 
   // Other notifications are ignored.
   virtual void SetHasImage() override { }
   virtual bool NotificationsDeferred() const override { return false; }
-  virtual void SetNotificationsDeferred(bool) override { }
+  virtual void MarkPendingNotify() override { }
+  virtual void ClearPendingNotify() override { }
 
 private:
   virtual ~NextPartObserver() { }
 
   void FinishObserving()
   {
     MOZ_ASSERT(mImage);
 
@@ -117,17 +118,17 @@ private:
 
 
 ///////////////////////////////////////////////////////////////////////////////
 // Implementation
 ///////////////////////////////////////////////////////////////////////////////
 
 MultipartImage::MultipartImage(Image* aFirstPart)
   : ImageWrapper(aFirstPart)
-  , mDeferNotifications(false)
+  , mPendingNotify(false)
 {
   mNextPartObserver = new NextPartObserver(this);
 }
 
 void
 MultipartImage::Init()
 {
   MOZ_ASSERT(NS_IsMainThread());
@@ -328,19 +329,25 @@ void
 MultipartImage::SetHasImage()
 {
   mTracker->OnImageAvailable();
 }
 
 bool
 MultipartImage::NotificationsDeferred() const
 {
-  return mDeferNotifications;
+  return mPendingNotify;
 }
 
 void
-MultipartImage::SetNotificationsDeferred(bool aDeferNotifications)
+MultipartImage::MarkPendingNotify()
 {
-  mDeferNotifications = aDeferNotifications;
+  mPendingNotify = true;
+}
+
+void
+MultipartImage::ClearPendingNotify()
+{
+  mPendingNotify = false;
 }
 
 } // namespace image
 } // namespace mozilla
--- a/image/MultipartImage.h
+++ b/image/MultipartImage.h
@@ -54,32 +54,33 @@ public:
 #endif
 
   // Overridden IProgressObserver methods:
   virtual void Notify(int32_t aType,
                       const nsIntRect* aRect = nullptr) override;
   virtual void OnLoadComplete(bool aLastPart) override;
   virtual void SetHasImage() override;
   virtual bool NotificationsDeferred() const override;
-  virtual void SetNotificationsDeferred(bool aDeferNotifications) override;
+  virtual void MarkPendingNotify() override;
+  virtual void ClearPendingNotify() override;
 
 protected:
   virtual ~MultipartImage();
 
 private:
   friend class ImageFactory;
   friend class NextPartObserver;
 
   explicit MultipartImage(Image* aFirstPart);
   void Init();
 
   void FinishTransition();
 
   RefPtr<ProgressTracker> mTracker;
   RefPtr<NextPartObserver> mNextPartObserver;
   RefPtr<Image> mNextPart;
-  bool mDeferNotifications : 1;
+  bool mPendingNotify : 1;
 };
 
 } // namespace image
 } // namespace mozilla
 
 #endif // mozilla_image_MultipartImage_h
--- a/image/ProgressTracker.cpp
+++ b/image/ProgressTracker.cpp
@@ -136,17 +136,17 @@ class AsyncNotifyRunnable : public Runna
       mObservers.AppendElement(aObserver);
     }
 
     NS_IMETHOD Run() override
     {
       MOZ_ASSERT(NS_IsMainThread(), "Should be running on the main thread");
       MOZ_ASSERT(mTracker, "mTracker should not be null");
       for (uint32_t i = 0; i < mObservers.Length(); ++i) {
-        mObservers[i]->SetNotificationsDeferred(false);
+        mObservers[i]->ClearPendingNotify();
         mTracker->SyncNotify(mObservers[i]);
       }
 
       mTracker->mRunnable = nullptr;
       return NS_OK;
     }
 
     void AddObserver(IProgressObserver* aObserver)
@@ -166,31 +166,36 @@ class AsyncNotifyRunnable : public Runna
     nsTArray<RefPtr<IProgressObserver>> mObservers;
 };
 
 void
 ProgressTracker::Notify(IProgressObserver* aObserver)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
+  if (aObserver->NotificationsDeferred()) {
+    // There is a pending notification, or the observer isn't ready yet.
+    return;
+  }
+
   if (MOZ_LOG_TEST(gImgLog, LogLevel::Debug)) {
     RefPtr<Image> image = GetImage();
     if (image && image->GetURI()) {
       RefPtr<ImageURL> uri(image->GetURI());
       nsAutoCString spec;
       uri->GetSpec(spec);
       LOG_FUNC_WITH_PARAM(gImgLog,
                           "ProgressTracker::Notify async", "uri", spec.get());
     } else {
       LOG_FUNC_WITH_PARAM(gImgLog,
                           "ProgressTracker::Notify async", "uri", "<unknown>");
     }
   }
 
-  aObserver->SetNotificationsDeferred(true);
+  aObserver->MarkPendingNotify();
 
   // If we have an existing runnable that we can use, we just append this
   // observer to its list of observers to be notified. This ensures we don't
   // unnecessarily delay onload.
   AsyncNotifyRunnable* runnable =
     static_cast<AsyncNotifyRunnable*>(mRunnable.get());
 
   if (runnable) {
@@ -216,17 +221,17 @@ class AsyncNotifyCurrentStateRunnable : 
       MOZ_ASSERT(mProgressTracker, "mProgressTracker should not be null");
       MOZ_ASSERT(mObserver, "mObserver should not be null");
       mImage = mProgressTracker->GetImage();
     }
 
     NS_IMETHOD Run() override
     {
       MOZ_ASSERT(NS_IsMainThread(), "Should be running on the main thread");
-      mObserver->SetNotificationsDeferred(false);
+      mObserver->ClearPendingNotify();
 
       mProgressTracker->SyncNotify(mObserver);
       return NS_OK;
     }
 
   private:
     RefPtr<ProgressTracker> mProgressTracker;
     RefPtr<IProgressObserver> mObserver;
@@ -236,27 +241,32 @@ class AsyncNotifyCurrentStateRunnable : 
     RefPtr<Image> mImage;
 };
 
 void
 ProgressTracker::NotifyCurrentState(IProgressObserver* aObserver)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
+  if (aObserver->NotificationsDeferred()) {
+    // There is a pending notification, or the observer isn't ready yet.
+    return;
+  }
+
   if (MOZ_LOG_TEST(gImgLog, LogLevel::Debug)) {
     RefPtr<Image> image = GetImage();
     nsAutoCString spec;
     if (image && image->GetURI()) {
       image->GetURI()->GetSpec(spec);
     }
     LOG_FUNC_WITH_PARAM(gImgLog,
                         "ProgressTracker::NotifyCurrentState", "uri", spec.get());
   }
 
-  aObserver->SetNotificationsDeferred(true);
+  aObserver->MarkPendingNotify();
 
   nsCOMPtr<nsIRunnable> ev = new AsyncNotifyCurrentStateRunnable(this,
                                                                  aObserver);
   mEventTarget->Dispatch(ev.forget(), NS_DISPATCH_NORMAL);
 }
 
 /**
  * ImageObserverNotifier is a helper type that abstracts over the difference
@@ -511,17 +521,17 @@ ProgressTracker::RemoveObserver(IProgres
 
   // Make sure we don't give callbacks to an observer that isn't interested in
   // them any more.
   AsyncNotifyRunnable* runnable =
     static_cast<AsyncNotifyRunnable*>(mRunnable.get());
 
   if (aObserver->NotificationsDeferred() && runnable) {
     runnable->RemoveObserver(aObserver);
-    aObserver->SetNotificationsDeferred(false);
+    aObserver->ClearPendingNotify();
   }
 
   return removed;
 }
 
 uint32_t
 ProgressTracker::ObserverCount() const
 {
--- a/image/imgLoader.cpp
+++ b/image/imgLoader.cpp
@@ -1763,17 +1763,17 @@ imgLoader::ValidateRequestWithNewChannel
 
     if (*aProxyRequest) {
       imgRequestProxy* proxy = static_cast<imgRequestProxy*>(*aProxyRequest);
 
       // We will send notifications from imgCacheValidator::OnStartRequest().
       // In the mean time, we must defer notifications because we are added to
       // the imgRequest's proxy list, and we can get extra notifications
       // resulting from methods such as StartDecoding(). See bug 579122.
-      proxy->SetNotificationsDeferred(true);
+      proxy->MarkValidating();
 
       // Attach the proxy without notifying
       request->GetValidator()->AddProxy(proxy);
     }
 
     return NS_SUCCEEDED(rv);
 
   }
@@ -1829,17 +1829,17 @@ imgLoader::ValidateRequestWithNewChannel
   newChannel->SetNotificationCallbacks(hvc);
 
   request->SetValidator(hvc);
 
   // We will send notifications from imgCacheValidator::OnStartRequest().
   // In the mean time, we must defer notifications because we are added to
   // the imgRequest's proxy list, and we can get extra notifications
   // resulting from methods such as StartDecoding(). See bug 579122.
-  req->SetNotificationsDeferred(true);
+  req->MarkValidating();
 
   // Add the proxy without notifying
   hvc->AddProxy(req);
 
   mozilla::net::PredictorLearn(aURI, aInitialDocumentURI,
                                nsINetworkPredictor::LEARN_LOAD_SUBRESOURCE, aLoadGroup);
   rv = newChannel->AsyncOpen2(listener);
   if (NS_WARN_IF(NS_FAILED(rv))) {
@@ -2931,23 +2931,55 @@ imgCacheValidator::~imgCacheValidator()
 
 void
 imgCacheValidator::AddProxy(imgRequestProxy* aProxy)
 {
   // aProxy needs to be in the loadgroup since we're validating from
   // the network.
   aProxy->AddToLoadGroup();
 
-  mProxies.AppendObject(aProxy);
+  mProxies.AppendElement(aProxy);
 }
 
 void
 imgCacheValidator::RemoveProxy(imgRequestProxy* aProxy)
 {
-  mProxies.RemoveObject(aProxy);
+  mProxies.RemoveElement(aProxy);
+}
+
+void
+imgCacheValidator::UpdateProxies()
+{
+  // We have finished validating the request, so we can safely take ownership
+  // of the proxy list. imgRequestProxy::SyncNotifyListener can mutate the list
+  // if imgRequestProxy::CancelAndForgetObserver is called by its owner. Note
+  // that any potential notifications should still be suppressed in
+  // imgRequestProxy::ChangeOwner because we haven't cleared the validating
+  // flag yet, and thus they will remain deferred.
+  AutoTArray<RefPtr<imgRequestProxy>, 4> proxies(Move(mProxies));
+
+  for (auto& proxy : proxies) {
+    // First update the state of all proxies before notifying any of them
+    // to ensure a consistent state (e.g. in case the notification causes
+    // other proxies to be touched indirectly.)
+    MOZ_ASSERT(proxy->IsValidating());
+    MOZ_ASSERT(proxy->NotificationsDeferred(),
+               "Proxies waiting on cache validation should be "
+               "deferring notifications!");
+    if (mNewRequest) {
+      proxy->ChangeOwner(mNewRequest);
+    }
+    proxy->ClearValidating();
+  }
+
+  for (auto& proxy : proxies) {
+    // Notify synchronously, because we're already in OnStartRequest, an
+    // asynchronously-called function.
+    proxy->SyncNotifyListener();
+  }
 }
 
 /** nsIRequestObserver methods **/
 
 NS_IMETHODIMP
 imgCacheValidator::OnStartRequest(nsIRequest* aRequest, nsISupports* ctxt)
 {
   // We may be holding on to a document, so ensure that it's released.
@@ -2977,43 +3009,30 @@ imgCacheValidator::OnStartRequest(nsIReq
     mRequest->GetFinalURI(getter_AddRefs(finalURI));
 
     bool sameURI = false;
     if (channelURI && finalURI) {
       channelURI->Equals(finalURI, &sameURI);
     }
 
     if (isFromCache && sameURI) {
-      uint32_t count = mProxies.Count();
-      for (int32_t i = count-1; i>=0; i--) {
-        imgRequestProxy* proxy = static_cast<imgRequestProxy*>(mProxies[i]);
-
-        // Proxies waiting on cache validation should be deferring
-        // notifications. Undefer them.
-        MOZ_ASSERT(proxy->NotificationsDeferred(),
-                   "Proxies waiting on cache validation should be "
-                   "deferring notifications!");
-        proxy->SetNotificationsDeferred(false);
-
-        // Notify synchronously, because we're already in OnStartRequest, an
-        // asynchronously-called function.
-        proxy->SyncNotifyListener();
-      }
-
       // We don't need to load this any more.
       aRequest->Cancel(NS_BINDING_ABORTED);
 
+      // Clear the validator before updating the proxies. The notifications may
+      // clone an existing request, and its state could be inconsistent.
       mRequest->SetLoadId(context);
       mRequest->SetValidator(nullptr);
 
       mRequest = nullptr;
 
       mNewRequest = nullptr;
       mNewEntry = nullptr;
 
+      UpdateProxies();
       return NS_OK;
     }
   }
 
   // We can't load out of cache. We have to create a whole new request for the
   // data that's coming in off the channel.
   nsCOMPtr<nsIURI> uri;
   {
@@ -3030,16 +3049,18 @@ imgCacheValidator::OnStartRequest(nsIReq
 
   int32_t corsmode = mRequest->GetCORSMode();
   ReferrerPolicy refpol = mRequest->GetReferrerPolicy();
   nsCOMPtr<nsIPrincipal> triggeringPrincipal = mRequest->GetTriggeringPrincipal();
 
   // Doom the old request's cache entry
   mRequest->RemoveFromCache();
 
+  // Clear the validator before updating the proxies. The notifications may
+  // clone an existing request, and its state could be inconsistent.
   mRequest->SetValidator(nullptr);
   mRequest = nullptr;
 
   // We use originalURI here to fulfil the imgIRequest contract on GetURI.
   nsCOMPtr<nsIURI> originalURI;
   channel->GetOriginalURI(getter_AddRefs(originalURI));
   nsresult rv =
     mNewRequest->Init(originalURI, uri, mHadInsecureRedirect, aRequest, channel,
@@ -3050,27 +3071,17 @@ imgCacheValidator::OnStartRequest(nsIReq
 
   mDestListener = new ProxyListener(mNewRequest);
 
   // Try to add the new request into the cache. Note that the entry must be in
   // the cache before the proxies' ownership changes, because adding a proxy
   // changes the caching behaviour for imgRequests.
   mImgLoader->PutIntoCache(mNewRequest->CacheKey(), mNewEntry);
 
-  uint32_t count = mProxies.Count();
-  for (int32_t i = count-1; i>=0; i--) {
-    imgRequestProxy* proxy = static_cast<imgRequestProxy*>(mProxies[i]);
-    proxy->ChangeOwner(mNewRequest);
-
-    // Notify synchronously, because we're already in OnStartRequest, an
-    // asynchronously-called function.
-    proxy->SetNotificationsDeferred(false);
-    proxy->SyncNotifyListener();
-  }
-
+  UpdateProxies();
   mNewRequest = nullptr;
   mNewEntry = nullptr;
 
   return mDestListener->OnStartRequest(aRequest, ctxt);
 }
 
 NS_IMETHODIMP
 imgCacheValidator::OnStopRequest(nsIRequest* aRequest,
--- a/image/imgLoader.h
+++ b/image/imgLoader.h
@@ -563,25 +563,26 @@ public:
   NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
   NS_DECL_NSISTREAMLISTENER
   NS_DECL_NSIREQUESTOBSERVER
   NS_DECL_NSICHANNELEVENTSINK
   NS_DECL_NSIINTERFACEREQUESTOR
   NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK
 
 private:
+  void UpdateProxies();
   virtual ~imgCacheValidator();
 
   nsCOMPtr<nsIStreamListener> mDestListener;
   RefPtr<nsProgressNotificationProxy> mProgressProxy;
   nsCOMPtr<nsIAsyncVerifyRedirectCallback> mRedirectCallback;
   nsCOMPtr<nsIChannel> mRedirectChannel;
 
   RefPtr<imgRequest> mRequest;
-  nsCOMArray<imgIRequest> mProxies;
+  AutoTArray<RefPtr<imgRequestProxy>, 4> mProxies;
 
   RefPtr<imgRequest> mNewRequest;
   RefPtr<imgCacheEntry> mNewEntry;
 
   nsCOMPtr<nsISupports> mContext;
 
   imgLoader* mImgLoader;
 
--- a/image/imgRequestProxy.cpp
+++ b/image/imgRequestProxy.cpp
@@ -115,17 +115,18 @@ imgRequestProxy::imgRequestProxy() :
   mLoadFlags(nsIRequest::LOAD_NORMAL),
   mLockCount(0),
   mAnimationConsumers(0),
   mCanceled(false),
   mIsInLoadGroup(false),
   mForceDispatchLoadGroup(false),
   mListenerIsStrongRef(false),
   mDecodeRequested(false),
-  mDeferNotifications(false),
+  mPendingNotify(false),
+  mValidating(false),
   mHadListener(false),
   mHadDispatch(false)
 {
   /* member initializers and constructor code */
   LOG_FUNC(gImgLog, "imgRequestProxy::imgRequestProxy");
 }
 
 imgRequestProxy::~imgRequestProxy()
@@ -158,25 +159,23 @@ imgRequestProxy::~imgRequestProxy()
   ClearAnimationConsumers();
 
   // Explicitly set mListener to null to ensure that the RemoveProxy
   // call below can't send |this| to an arbitrary listener while |this|
   // is being destroyed.  This is all belt-and-suspenders in view of the
   // above assert.
   NullOutListener();
 
-  if (GetOwner()) {
-    /* Call RemoveProxy with a successful status.  This will keep the
-       channel, if still downloading data, from being canceled if 'this' is
-       the last observer.  This allows the image to continue to download and
-       be cached even if no one is using it currently.
-    */
-    mCanceled = true;
-    GetOwner()->RemoveProxy(this, NS_OK);
-  }
+  /* Call RemoveProxy with a successful status.  This will keep the
+     channel, if still downloading data, from being canceled if 'this' is
+     the last observer.  This allows the image to continue to download and
+     be cached even if no one is using it currently.
+  */
+  mCanceled = true;
+  RemoveFromOwner(NS_OK);
 
   RemoveFromLoadGroup();
   LOG_FUNC(gImgLog, "imgRequestProxy::~imgRequestProxy");
 }
 
 nsresult
 imgRequestProxy::Init(imgRequest* aOwner,
                       nsILoadGroup* aLoadGroup,
@@ -232,38 +231,54 @@ imgRequestProxy::ChangeOwner(imgRequest*
 
   // If we're holding animation requests, undo them.
   uint32_t oldAnimationConsumers = mAnimationConsumers;
   ClearAnimationConsumers();
 
   GetOwner()->RemoveProxy(this, NS_OK);
 
   mBehaviour->SetOwner(aNewOwner);
+  MOZ_ASSERT(!GetValidator(), "New owner cannot be validating!");
 
   // If we were locked, apply the locks here
   for (uint32_t i = 0; i < oldLockCount; i++) {
     LockImage();
   }
 
   // If we had animation requests, restore them here. Note that we
   // do this *after* RemoveProxy, which clears out animation consumers
   // (see bug 601723).
   for (uint32_t i = 0; i < oldAnimationConsumers; i++) {
     IncrementAnimationConsumers();
   }
 
   AddToOwner(nullptr);
+  return NS_OK;
+}
+
+void
+imgRequestProxy::MarkValidating()
+{
+  MOZ_ASSERT(GetValidator());
+  mValidating = true;
+}
+
+void
+imgRequestProxy::ClearValidating()
+{
+  MOZ_ASSERT(mValidating);
+  MOZ_ASSERT(!GetValidator());
+  mValidating = false;
 
   // If we'd previously requested a synchronous decode, request a decode on the
   // new image.
   if (mDecodeRequested) {
+    mDecodeRequested = false;
     StartDecoding(imgIContainer::FLAG_NONE);
   }
-
-  return NS_OK;
 }
 
 bool
 imgRequestProxy::IsOnEventTarget() const
 {
   // Ensure we are in some main thread context because the scheduler group
   // methods are only safe to call on the main thread.
   MOZ_ASSERT(NS_IsMainThread());
@@ -346,21 +361,38 @@ imgRequestProxy::AddToOwner(nsIDocument*
       MOZ_ASSERT(mEventTarget);
     }
   }
 
   if (mListener && !mEventTarget) {
     mEventTarget = do_GetMainThread();
   }
 
-  if (!GetOwner()) {
+  imgRequest* owner = GetOwner();
+  if (!owner) {
     return;
   }
 
-  GetOwner()->AddProxy(this);
+  owner->AddProxy(this);
+}
+
+void
+imgRequestProxy::RemoveFromOwner(nsresult aStatus)
+{
+  imgRequest* owner = GetOwner();
+  if (owner) {
+    if (mValidating) {
+      imgCacheValidator* validator = owner->GetValidator();
+      MOZ_ASSERT(validator);
+      validator->RemoveProxy(this);
+      mValidating = false;
+    }
+
+    owner->RemoveProxy(this, aStatus);
+  }
 }
 
 void
 imgRequestProxy::AddToLoadGroup()
 {
   NS_ASSERTION(!mIsInLoadGroup, "Whaa, we're already in the loadgroup!");
   MOZ_ASSERT(!mForceDispatchLoadGroup);
 
@@ -489,20 +521,17 @@ imgRequestProxy::Cancel(nsresult status)
 
   nsCOMPtr<nsIRunnable> ev = new imgCancelRunnable(this, status);
   return DispatchWithTargetIfAvailable(ev.forget());
 }
 
 void
 imgRequestProxy::DoCancel(nsresult status)
 {
-  if (GetOwner()) {
-    GetOwner()->RemoveProxy(this, status);
-  }
-
+  RemoveFromOwner(status);
   RemoveFromLoadGroup();
   NullOutListener();
 }
 
 NS_IMETHODIMP
 imgRequestProxy::CancelAndForgetObserver(nsresult aStatus)
 {
   // If mCanceled is true but mListener is non-null, that means
@@ -514,58 +543,54 @@ imgRequestProxy::CancelAndForgetObserver
   if (mCanceled && !mListener) {
     return NS_ERROR_FAILURE;
   }
 
   LOG_SCOPE(gImgLog, "imgRequestProxy::CancelAndForgetObserver");
 
   mCanceled = true;
   mForceDispatchLoadGroup = true;
-
-  imgRequest* owner = GetOwner();
-  if (owner) {
-    imgCacheValidator* validator = owner->GetValidator();
-    if (validator) {
-      validator->RemoveProxy(this);
-    }
-
-    owner->RemoveProxy(this, aStatus);
-  }
-
+  RemoveFromOwner(aStatus);
   RemoveFromLoadGroup();
   mForceDispatchLoadGroup = false;
 
   NullOutListener();
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 imgRequestProxy::StartDecoding(uint32_t aFlags)
 {
-  // Flag this, so we know to transfer the request if our owner changes
-  mDecodeRequested = true;
+  // Flag this, so we know to request after validation if pending.
+  if (IsValidating()) {
+    mDecodeRequested = true;
+    return NS_OK;
+  }
 
   RefPtr<Image> image = GetImage();
   if (image) {
     return image->StartDecoding(aFlags);
   }
 
   if (GetOwner()) {
     GetOwner()->StartDecoding();
   }
 
   return NS_OK;
 }
 
 bool
 imgRequestProxy::StartDecodingWithResult(uint32_t aFlags)
 {
-  // Flag this, so we know to transfer the request if our owner changes
-  mDecodeRequested = true;
+  // Flag this, so we know to request after validation if pending.
+  if (IsValidating()) {
+    mDecodeRequested = true;
+    return false;
+  }
 
   RefPtr<Image> image = GetImage();
   if (image) {
     return image->StartDecodingWithResult(aFlags);
   }
 
   if (GetOwner()) {
     GetOwner()->StartDecoding();
@@ -712,18 +737,26 @@ imgRequestProxy::GetImage(imgIContainer*
   imageToReturn.swap(*aImage);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 imgRequestProxy::GetImageStatus(uint32_t* aStatus)
 {
-  RefPtr<ProgressTracker> progressTracker = GetProgressTracker();
-  *aStatus = progressTracker->GetImageStatus();
+  if (IsValidating()) {
+    // We are currently validating the image, and so our status could revert if
+    // we discard the cache. We should also be deferring notifications, such
+    // that the caller will be notified when validation completes. Rather than
+    // risk misleading the caller, return nothing.
+    *aStatus = imgIRequest::STATUS_NONE;
+  } else {
+    RefPtr<ProgressTracker> progressTracker = GetProgressTracker();
+    *aStatus = progressTracker->GetImageStatus();
+  }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 imgRequestProxy::GetImageErrorCode(nsresult* aStatus)
 {
   if (!GetOwner()) {
@@ -854,25 +887,26 @@ imgRequestProxy::PerformClone(imgINotifi
     return rv;
   }
 
   // Assign to *aClone before calling Notify so that if the caller expects to
   // only be notified for requests it's already holding pointers to it won't be
   // surprised.
   NS_ADDREF(*aClone = clone);
 
-  if (GetOwner() && GetOwner()->GetValidator()) {
+  imgCacheValidator* validator = GetValidator();
+  if (validator) {
     // Note that if we have a validator, we don't want to issue notifications at
     // here because we want to defer until that completes. AddProxy will add us
     // to the load group; we cannot avoid that in this case, because we don't
     // know when the validation will complete, and if it will cause us to
     // discard our cached state anyways. We are probably already blocked by the
     // original LoadImage(WithChannel) request in any event.
-    clone->SetNotificationsDeferred(true);
-    GetOwner()->GetValidator()->AddProxy(clone);
+    clone->MarkValidating();
+    validator->AddProxy(clone);
   } else {
     // We only want to add the request to the load group of the owning document
     // if it is still in progress. Some callers cannot handle a supurious load
     // group removal (e.g. print preview) so we must be careful. On the other
     // hand, if after cloning, the original request proxy is cancelled /
     // destroyed, we need to ensure that any clones still block the load group
     // if it is incomplete.
     bool addToLoadGroup = mIsInLoadGroup;
@@ -1265,16 +1299,26 @@ imgRequestProxy::HasImage() const
 }
 
 imgRequest*
 imgRequestProxy::GetOwner() const
 {
   return mBehaviour->GetOwner();
 }
 
+imgCacheValidator*
+imgRequestProxy::GetValidator() const
+{
+  imgRequest* owner = GetOwner();
+  if (!owner) {
+    return nullptr;
+  }
+  return owner->GetValidator();
+}
+
 ////////////////// imgRequestProxyStatic methods
 
 class StaticBehaviour : public ProxyBehaviour
 {
 public:
   explicit StaticBehaviour(mozilla::image::Image* aImage) : mImage(aImage) {}
 
   already_AddRefed<mozilla::image::Image>
--- a/image/imgRequestProxy.h
+++ b/image/imgRequestProxy.h
@@ -25,16 +25,17 @@
 #define NS_IMGREQUESTPROXY_CID \
 { /* 20557898-1dd2-11b2-8f65-9c462ee2bc95 */         \
      0x20557898,                                     \
      0x1dd2,                                         \
      0x11b2,                                         \
     {0x8f, 0x65, 0x9c, 0x46, 0x2e, 0xe2, 0xbc, 0x95} \
 }
 
+class imgCacheValidator;
 class imgINotificationObserver;
 class imgStatusNotifyRunnable;
 class ProxyBehaviour;
 
 namespace mozilla {
 namespace dom {
 class TabGroup;
 }
@@ -106,25 +107,35 @@ public:
   virtual void Notify(int32_t aType,
                       const mozilla::gfx::IntRect* aRect = nullptr) override;
   virtual void OnLoadComplete(bool aLastPart) override;
 
   // Other, internal-only methods:
   virtual void SetHasImage() override;
 
   // Whether we want notifications from ProgressTracker to be deferred until
-  // an event it has scheduled has been fired.
+  // an event it has scheduled has been fired and/or validation is complete.
   virtual bool NotificationsDeferred() const override
   {
-    return mDeferNotifications;
+    return IsValidating() || mPendingNotify;
+  }
+  virtual void MarkPendingNotify() override
+  {
+    mPendingNotify = true;
   }
-  virtual void SetNotificationsDeferred(bool aDeferNotifications) override
+  virtual void ClearPendingNotify() override
   {
-    mDeferNotifications = aDeferNotifications;
+    mPendingNotify = false;
   }
+  bool IsValidating() const
+  {
+    return mValidating;
+  }
+  void MarkValidating();
+  void ClearValidating();
 
   bool IsOnEventTarget() const;
   already_AddRefed<nsIEventTarget> GetEventTarget() const override;
 
   // Removes all animation consumers that were created with
   // IncrementAnimationConsumers. This is necessary since we need
   // to do it before the proxy itself is destroyed. See
   // imgRequest::RemoveProxy
@@ -189,16 +200,17 @@ protected:
       return nullptr;
     }
     return GetOwner()->GetTimedChannel();
   }
 
   already_AddRefed<Image> GetImage() const;
   bool HasImage() const;
   imgRequest* GetOwner() const;
+  imgCacheValidator* GetValidator() const;
 
   nsresult PerformClone(imgINotificationObserver* aObserver,
                         nsIDocument* aLoadingDocument,
                         bool aSyncNotify,
                         imgRequestProxy** aClone);
 
   virtual imgRequestProxy* NewClonedProxy();
 
@@ -207,16 +219,17 @@ public:
 
 protected:
   mozilla::UniquePtr<ProxyBehaviour> mBehaviour;
 
 private:
   friend class imgCacheValidator;
 
   void AddToOwner(nsIDocument* aLoadingDocument);
+  void RemoveFromOwner(nsresult aStatus);
 
   nsresult DispatchWithTargetIfAvailable(already_AddRefed<nsIRunnable> aEvent);
   void DispatchWithTarget(already_AddRefed<nsIRunnable> aEvent);
 
   // The URI of our request.
   RefPtr<ImageURL> mURI;
 
   // mListener is only promised to be a weak ref (see imgILoader.idl),
@@ -236,17 +249,18 @@ private:
   bool mCanceled : 1;
   bool mIsInLoadGroup : 1;
   bool mForceDispatchLoadGroup : 1;
   bool mListenerIsStrongRef : 1;
   bool mDecodeRequested : 1;
 
   // Whether we want to defer our notifications by the non-virtual Observer
   // interfaces as image loads proceed.
-  bool mDeferNotifications : 1;
+  bool mPendingNotify : 1;
+  bool mValidating : 1;
   bool mHadListener : 1;
   bool mHadDispatch : 1;
 };
 
 // Used for static image proxies for which no requests are available, so
 // certain behaviours must be overridden to compensate.
 class imgRequestProxyStatic : public imgRequestProxy
 {
--- a/js/src/jit-test/tests/basic/dumpStringRepresentation.js
+++ b/js/src/jit-test/tests/basic/dumpStringRepresentation.js
@@ -5,16 +5,19 @@ if (typeof dumpStringRepresentation !== 
   quit(0);
 
 print("Empty string:");
 dumpStringRepresentation("");
 
 print("\nResult of coercion to string:");
 dumpStringRepresentation();
 
+print("\nString with an index value:");
+dumpStringRepresentation((12345).toString());
+
 print("\ns = Simple short atom:");
 var s = "xxxxxxxx";
 dumpStringRepresentation(s);
 
 // Simple non-atom flat.
 print("\ns + s: Non-atom flat:");
 var s2 = s + s;
 dumpStringRepresentation(s2);
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -5500,17 +5500,18 @@ CodeGenerator::generateBody()
         if (counts) {
             blockCounts.emplace(&counts->block(i), &masm);
             if (!blockCounts->init())
                 return false;
         }
         TrackedOptimizations* last = nullptr;
 
 #if defined(JS_ION_PERF)
-        perfSpewer->startBasicBlock(current->mir(), masm);
+        if (!perfSpewer->startBasicBlock(current->mir(), masm))
+            return false;
 #endif
 
         for (LInstructionIterator iter = current->begin(); iter != current->end(); iter++) {
             if (!alloc().ensureBallast())
                 return false;
 
 #ifdef JS_JITSPEW
             JitSpewStart(JitSpew_Codegen, "instruction %s", iter->opName());
@@ -8648,34 +8649,24 @@ CodeGenerator::visitBoundsCheckLower(LBo
                  lir->snapshot());
 }
 
 void
 CodeGenerator::visitSpectreMaskIndex(LSpectreMaskIndex* lir)
 {
     MOZ_ASSERT(JitOptions.spectreIndexMasking);
 
-    const LAllocation* index = lir->index();
     const LAllocation* length = lir->length();
+    Register index = ToRegister(lir->index());
     Register output = ToRegister(lir->output());
 
-    if (index->isConstant()) {
-        int32_t idx = ToInt32(index);
-        if (length->isRegister())
-            masm.spectreMaskIndex(idx, ToRegister(length), output);
-        else
-            masm.spectreMaskIndex(idx, ToAddress(length), output);
-        return;
-    }
-
-    Register indexReg = ToRegister(index);
     if (length->isRegister())
-        masm.spectreMaskIndex(indexReg, ToRegister(length), output);
+        masm.spectreMaskIndex(index, ToRegister(length), output);
     else
-        masm.spectreMaskIndex(indexReg, ToAddress(length), output);
+        masm.spectreMaskIndex(index, ToAddress(length), output);
 }
 
 class OutOfLineStoreElementHole : public OutOfLineCodeBase<CodeGenerator>
 {
     LInstruction* ins_;
     Label rejoinStore_;
     bool strict_;
 
--- a/js/src/jit/JitOptions.cpp
+++ b/js/src/jit/JitOptions.cpp
@@ -227,17 +227,17 @@ DefaultJitOptions::DefaultJitOptions()
     // pass decide.
     const char* forcedRegisterAllocatorEnv = "JIT_OPTION_forcedRegisterAllocator";
     if (const char* env = getenv(forcedRegisterAllocatorEnv)) {
         forcedRegisterAllocator = LookupRegisterAllocator(env);
         if (!forcedRegisterAllocator.isSome())
             Warn(forcedRegisterAllocatorEnv, env);
     }
 
-    SET_DEFAULT(spectreIndexMasking, false);
+    SET_DEFAULT(spectreIndexMasking, true);
 
     // Toggles whether unboxed plain objects can be created by the VM.
     SET_DEFAULT(disableUnboxedObjects, false);
 
     // Test whether Atomics are allowed in asm.js code.
     SET_DEFAULT(asmJSAtomicsEnable, false);
 
     // Toggles the optimization whereby offsets are folded into loads and not
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -3158,26 +3158,18 @@ LIRGenerator::visitBoundsCheck(MBoundsCh
 
 void
 LIRGenerator::visitSpectreMaskIndex(MSpectreMaskIndex* ins)
 {
     MOZ_ASSERT(ins->index()->type() == MIRType::Int32);
     MOZ_ASSERT(ins->length()->type() == MIRType::Int32);
     MOZ_ASSERT(ins->type() == MIRType::Int32);
 
-    // On 64-bit platforms, the length must be in a register, so
-    // MacroAssembler::maskIndex can emit more efficient code.
-#if JS_BITS_PER_WORD == 64
-    LAllocation lengthUse = useRegister(ins->length());
-#else
-    LAllocation lengthUse = useAny(ins->length());
-#endif
-
     LSpectreMaskIndex* lir =
-        new(alloc()) LSpectreMaskIndex(useRegisterOrConstant(ins->index()), lengthUse);
+        new(alloc()) LSpectreMaskIndex(useRegister(ins->index()), useAny(ins->length()));
     define(lir, ins);
 }
 
 void
 LIRGenerator::visitBoundsCheckLower(MBoundsCheckLower* ins)
 {
     MOZ_ASSERT(ins->index()->type() == MIRType::Int32);
 
--- a/js/src/jit/MacroAssembler.cpp
+++ b/js/src/jit/MacroAssembler.cpp
@@ -3317,155 +3317,51 @@ MacroAssembler::debugAssertIsObject(cons
 #ifdef DEBUG
     Label ok;
     branchTestObject(Assembler::Equal, val, &ok);
     assumeUnreachable("Expected an object!");
     bind(&ok);
 #endif
 }
 
-template <typename T>
 void
-MacroAssembler::computeSpectreIndexMaskGeneric(Register index, const T& length, Register output)
-{
-    MOZ_ASSERT(JitOptions.spectreIndexMasking);
-    MOZ_ASSERT(index != output);
-
-    // mask := ((index - length) & ~index) >> 31
-    mov(index, output);
-    sub32(length, output);
-    not32(index);
-    and32(index, output);
-    not32(index); // Restore index register to its original value.
-    rshift32Arithmetic(Imm32(31), output);
-}
-
-template <typename T>
-void
-MacroAssembler::computeSpectreIndexMask(int32_t index, const T& length, Register output)
-{
-    MOZ_ASSERT(JitOptions.spectreIndexMasking);
-
-    // mask := ((index - length) & ~index) >> 31
-    move32(Imm32(index), output);
-    sub32(length, output);
-    and32(Imm32(~index), output);
-    rshift32Arithmetic(Imm32(31), output);
-}
-
-void
-MacroAssembler::computeSpectreIndexMask(Register index, Register length, Register output)
+MacroAssembler::spectreMaskIndex(Register index, Register length, Register output)
 {
     MOZ_ASSERT(JitOptions.spectreIndexMasking);
     MOZ_ASSERT(length != output);
     MOZ_ASSERT(index != output);
 
-#if JS_BITS_PER_WORD == 64
-    // On 64-bit platforms, we can use a faster algorithm:
-    //
-    //   mask := (uint64_t(index) - uint64_t(length)) >> 32
-    //
-    // mask is 0x11…11 if index < length, 0 otherwise.
-    move32(index, output);
-    subPtr(length, output);
-    rshiftPtr(Imm32(32), output);
-#else
-    computeSpectreIndexMaskGeneric(index, length, output);
-#endif
-}
-
-void
-MacroAssembler::spectreMaskIndex(int32_t index, Register length, Register output)
-{
-    MOZ_ASSERT(length != output);
-    if (index == 0) {
-        move32(Imm32(index), output);
-    } else {
-        computeSpectreIndexMask(index, length, output);
-        and32(Imm32(index), output);
-    }
-}
-
-void
-MacroAssembler::spectreMaskIndex(int32_t index, const Address& length, Register output)
-{
-    MOZ_ASSERT(length.base != output);
-    if (index == 0) {
-        move32(Imm32(index), output);
-    } else {
-        computeSpectreIndexMask(index, length, output);
-        and32(Imm32(index), output);
-    }
-}
-
-void
-MacroAssembler::spectreMaskIndex(Register index, Register length, Register output)
-{
-    MOZ_ASSERT(length != output);
-    MOZ_ASSERT(index != output);
-
-    computeSpectreIndexMask(index, length, output);
-    and32(index, output);
+    move32(Imm32(0), output);
+    cmp32Move32(Assembler::Below, index, length, index, output);
 }
 
 void
 MacroAssembler::spectreMaskIndex(Register index, const Address& length, Register output)
 {
+    MOZ_ASSERT(JitOptions.spectreIndexMasking);
     MOZ_ASSERT(index != length.base);
     MOZ_ASSERT(length.base != output);
     MOZ_ASSERT(index != output);
 
-    computeSpectreIndexMaskGeneric(index, length, output);
-    and32(index, output);
+    move32(Imm32(0), output);
+    cmp32Move32(Assembler::Below, index, length, index, output);
 }
 
 void
 MacroAssembler::boundsCheck32PowerOfTwo(Register index, uint32_t length, Label* failure)
 {
     MOZ_ASSERT(mozilla::IsPowerOfTwo(length));
     branch32(Assembler::AboveOrEqual, index, Imm32(length), failure);
 
     // Note: it's fine to clobber the input register, as this is a no-op: it
     // only affects speculative execution.
     if (JitOptions.spectreIndexMasking)
         and32(Imm32(length - 1), index);
 }
 
-void
-MacroAssembler::boundsCheck32ForLoad(Register index, Register length, Register scratch,
-                                     Label* failure)
-{
-    MOZ_ASSERT(index != length);
-    MOZ_ASSERT(length != scratch);
-    MOZ_ASSERT(index != scratch);
-
-    branch32(Assembler::AboveOrEqual, index, length, failure);
-
-    if (JitOptions.spectreIndexMasking) {
-        computeSpectreIndexMask(index, length, scratch);
-        and32(scratch, index);
-    }
-}
-
-void
-MacroAssembler::boundsCheck32ForLoad(Register index, const Address& length, Register scratch,
-                                     Label* failure)
-{
-    MOZ_ASSERT(index != length.base);
-    MOZ_ASSERT(length.base != scratch);
-    MOZ_ASSERT(index != scratch);
-
-    branch32(Assembler::BelowOrEqual, length, index, failure);
-
-    if (JitOptions.spectreIndexMasking) {
-        computeSpectreIndexMaskGeneric(index, length, scratch);
-        and32(scratch, index);
-    }
-}
-
 namespace js {
 namespace jit {
 
 #ifdef DEBUG
 template <class RegisterType>
 AutoGenericRegisterScope<RegisterType>::AutoGenericRegisterScope(MacroAssembler& masm, RegisterType reg)
   : RegisterType(reg), masm_(masm)
 {
--- a/js/src/jit/MacroAssembler.h
+++ b/js/src/jit/MacroAssembler.h
@@ -1354,16 +1354,34 @@ class MacroAssembler : public MacroAssem
     template <typename T>
     inline void branchTestPrimitiveImpl(Condition cond, const T& t, Label* label)
         DEFINED_ON(arm, arm64, x86_shared);
     template <typename T, class L>
     inline void branchTestMagicImpl(Condition cond, const T& t, L label)
         DEFINED_ON(arm, arm64, x86_shared);
 
   public:
+
+    inline void cmp32Move32(Condition cond, Register lhs, Register rhs, Register src,
+                            Register dest)
+        DEFINED_ON(arm, arm64, x86_shared);
+
+    inline void cmp32Move32(Condition cond, Register lhs, const Address& rhs, Register src,
+                            Register dest)
+        DEFINED_ON(arm, arm64, x86_shared);
+
+    // Performs a bounds check and zeroes the index register if out-of-bounds
+    // (to mitigate Spectre).
+    inline void boundsCheck32ForLoad(Register index, Register length, Register scratch,
+                                     Label* failure)
+        DEFINED_ON(arm, arm64, x86_shared);
+    inline void boundsCheck32ForLoad(Register index, const Address& length, Register scratch,
+                                     Label* failure)
+        DEFINED_ON(arm, arm64, x86_shared);
+
     // ========================================================================
     // Canonicalization primitives.
     inline void canonicalizeDouble(FloatRegister reg);
     inline void canonicalizeDoubleIfDeterministic(FloatRegister reg);
 
     inline void canonicalizeFloat(FloatRegister reg);
     inline void canonicalizeFloatIfDeterministic(FloatRegister reg);
 
@@ -2050,39 +2068,23 @@ class MacroAssembler : public MacroAssem
     using MacroAssemblerSpecific::store32;
     void store32(const RegisterOrInt32Constant& key, const Address& dest) {
         if (key.isRegister())
             store32(key.reg(), dest);
         else
             store32(Imm32(key.constant()), dest);
     }
 
-  private:
-    template <typename T>
-    void computeSpectreIndexMaskGeneric(Register index, const T& length, Register output);
-
-    void computeSpectreIndexMask(Register index, Register length, Register output);
-
-    template <typename T>
-    void computeSpectreIndexMask(int32_t index, const T& length, Register output);
-
-  public:
-    void spectreMaskIndex(int32_t index, Register length, Register output);
-    void spectreMaskIndex(int32_t index, const Address& length, Register output);
     void spectreMaskIndex(Register index, Register length, Register output);
     void spectreMaskIndex(Register index, const Address& length, Register output);
 
     // The length must be a power of two. Performs a bounds check and Spectre index
     // masking.
     void boundsCheck32PowerOfTwo(Register index, uint32_t length, Label* failure);
 
-    // Performs a bounds check and Spectre index masking.
-    void boundsCheck32ForLoad(Register index, Register length, Register scratch, Label* failure);
-    void boundsCheck32ForLoad(Register index, const Address& length, Register scratch, Label* failure);
-
     template <typename T>
     void guardedCallPreBarrier(const T& address, MIRType type) {
         Label done;
 
         branchTestNeedsIncrementalBarrier(Assembler::Zero, &done);
 
         if (type == MIRType::Value)
             branchTestGCThing(Assembler::NotEqual, address, &done);
--- a/js/src/jit/PerfSpewer.cpp
+++ b/js/src/jit/PerfSpewer.cpp
@@ -124,34 +124,31 @@ js::jit::PerfBlockEnabled() {
 }
 
 bool
 js::jit::PerfFuncEnabled() {
     MOZ_ASSERT(PerfMode);
     return PerfMode == PERF_MODE_FUNC;
 }
 
-static bool
-lockPerfMap(void)
-{
-    if (!PerfEnabled())
-        return false;
-
-    PerfMutex->lock();
-
-    MOZ_ASSERT(PerfFilePtr);
-    return true;
-}
-
-static void
-unlockPerfMap()
-{
-    MOZ_ASSERT(PerfFilePtr);
-    fflush(PerfFilePtr);
-    PerfMutex->unlock();
+namespace {
+    struct MOZ_RAII AutoLockPerfMap
+    {
+        AutoLockPerfMap() {
+            if (!PerfEnabled())
+                return;
+            PerfMutex->lock();
+            MOZ_ASSERT(PerfFilePtr);
+        }
+        ~AutoLockPerfMap() {
+            MOZ_ASSERT(PerfFilePtr);
+            fflush(PerfFilePtr);
+            PerfMutex->unlock();
+        }
+    };
 }
 
 uint32_t PerfSpewer::nextFunctionIndex = 0;
 
 bool
 PerfSpewer::startBasicBlock(MBasicBlock* blk,
                             MacroAssembler& masm)
 {
@@ -168,172 +165,160 @@ PerfSpewer::startBasicBlock(MBasicBlock*
         lineNumber = 0;
         columnNumber = 0;
     }
     Record r(filename, lineNumber, columnNumber, blk->id());
     masm.bind(&r.start);
     return basicBlocks_.append(r);
 }
 
-bool
+void
 PerfSpewer::endBasicBlock(MacroAssembler& masm)
 {
     if (!PerfBlockEnabled())
-        return true;
-
+        return;
     masm.bind(&basicBlocks_.back().end);
-    return true;
 }
 
-bool
+void
 PerfSpewer::noteEndInlineCode(MacroAssembler& masm)
 {
     if (!PerfBlockEnabled())
-        return true;
+        return;
+    masm.bind(&endInlineCode);
+}
 
-    masm.bind(&endInlineCode);
-    return true;
+void
+PerfSpewer::WriteEntry(const AutoLockPerfMap&, uintptr_t address, size_t size,
+                       const char* fmt, ...)
+{
+    va_list ap;
+    va_start(ap, fmt);
+
+    auto result = mozilla::Vsmprintf<js::SystemAllocPolicy>(fmt, ap);
+    va_end(ap);
+
+    fprintf(PerfFilePtr, "%" PRIxPTR " %zx %s\n",
+            address,
+            size,
+            result.get());
 }
 
 void
 PerfSpewer::writeProfile(JSScript* script,
                          JitCode* code,
                          MacroAssembler& masm)
 {
+    AutoLockPerfMap lock;
+
     if (PerfFuncEnabled()) {
-        if (!lockPerfMap())
-            return;
-
         uint32_t thisFunctionIndex = nextFunctionIndex++;
-
         size_t size = code->instructionsSize();
         if (size > 0) {
-            fprintf(PerfFilePtr, "%p %zx %s:%zu: Func%02d\n",
-                    code->raw(),
-                    size,
-                    script->filename(),
-                    script->lineno(),
-                    thisFunctionIndex);
+            WriteEntry(lock, reinterpret_cast<uintptr_t>(code->raw()), size, "%s:%zu: Func%02" PRIu32,
+                       script->filename(), script->lineno(), thisFunctionIndex);
         }
-        unlockPerfMap();
         return;
     }
 
     if (PerfBlockEnabled() && basicBlocks_.length() > 0) {
-        if (!lockPerfMap())
-            return;
-
         uint32_t thisFunctionIndex = nextFunctionIndex++;
         uintptr_t funcStart = uintptr_t(code->raw());
         uintptr_t funcEndInlineCode = funcStart + endInlineCode.offset();
         uintptr_t funcEnd = funcStart + code->instructionsSize();
 
         // function begins with the prologue, which is located before the first basic block
         size_t prologueSize = basicBlocks_[0].start.offset();
 
         if (prologueSize > 0) {
-            fprintf(PerfFilePtr, "%zx %zx %s:%zu: Func%02d-Prologue\n",
-                    funcStart, prologueSize, script->filename(), script->lineno(), thisFunctionIndex);
+            WriteEntry(lock, funcStart, prologueSize, "%s:%zu: Func%02" PRIu32 "-Prologue",
+                       script->filename(), script->lineno(), thisFunctionIndex);
         }
 
         uintptr_t cur = funcStart + prologueSize;
         for (uint32_t i = 0; i < basicBlocks_.length(); i++) {
             Record& r = basicBlocks_[i];
 
             uintptr_t blockStart = funcStart + r.start.offset();
             uintptr_t blockEnd = funcStart + r.end.offset();
 
             MOZ_ASSERT(cur <= blockStart);
             if (cur < blockStart) {
-                fprintf(PerfFilePtr, "%" PRIxPTR " %" PRIxPTR " %s:%zu: Func%02d-Block?\n",
-                        cur, blockStart - cur,
-                        script->filename(), script->lineno(),
-                        thisFunctionIndex);
+                WriteEntry(lock, cur, blockStart - cur, "%s:%zu: Func%02" PRIu32 "-Block?",
+                           script->filename(), script->lineno(), thisFunctionIndex);
             }
             cur = blockEnd;
 
             size_t size = blockEnd - blockStart;
 
             if (size > 0) {
-                fprintf(PerfFilePtr, "%" PRIxPTR " %zx %s:%d:%d: Func%02d-Block%d\n",
-                        blockStart, size,
-                        r.filename, r.lineNumber, r.columnNumber,
-                        thisFunctionIndex, r.id);
+                WriteEntry(lock, blockStart, size, "%s:%u:%u: Func%02" PRIu32 "d-Block%" PRIu32,
+                           r.filename, r.lineNumber, r.columnNumber, thisFunctionIndex, r.id);
             }
         }
 
         MOZ_ASSERT(cur <= funcEndInlineCode);
         if (cur < funcEndInlineCode) {
-            fprintf(PerfFilePtr, "%" PRIxPTR " %" PRIxPTR " %s:%zu: Func%02d-Epilogue\n",
-                    cur, funcEndInlineCode - cur,
-                    script->filename(), script->lineno(),
-                    thisFunctionIndex);
+            WriteEntry(lock, cur, funcEndInlineCode - cur, "%s:%zu: Func%02" PRIu32 "-Epilogue",
+                       script->filename(), script->lineno(), thisFunctionIndex);
         }
 
         MOZ_ASSERT(funcEndInlineCode <= funcEnd);
         if (funcEndInlineCode < funcEnd) {
-            fprintf(PerfFilePtr, "%" PRIxPTR " %" PRIxPTR " %s:%zu: Func%02d-OOL\n",
-                    funcEndInlineCode, funcEnd - funcEndInlineCode,
-                    script->filename(), script->lineno(),
-                    thisFunctionIndex);
+            WriteEntry(lock, funcEndInlineCode, funcEnd - funcEndInlineCode,
+                       "%s:%zu: Func%02" PRIu32 "-OOL",
+                       script->filename(), script->lineno(), thisFunctionIndex);
         }
-
-        unlockPerfMap();
-        return;
     }
 }
 
 void
 js::jit::writePerfSpewerBaselineProfile(JSScript* script, JitCode* code)
 {
     if (!PerfEnabled())
         return;
 
-    if (!lockPerfMap())
-        return;
-
     size_t size = code->instructionsSize();
     if (size > 0) {
-        fprintf(PerfFilePtr, "%" PRIxPTR " %zx %s:%zu: Baseline\n",
-                reinterpret_cast<uintptr_t>(code->raw()),
-                size, script->filename(), script->lineno());
+        AutoLockPerfMap lock;
+        PerfSpewer::WriteEntry(lock, reinterpret_cast<uintptr_t>(code->raw()), size,
+                               "%s:%zu: Baseline", script->filename(), script->lineno());
     }
-
-    unlockPerfMap();
 }
 
 void
 js::jit::writePerfSpewerJitCodeProfile(JitCode* code, const char* msg)
 {
     if (!code || !PerfEnabled())
         return;
 
-    if (!lockPerfMap())
-        return;
-
     size_t size = code->instructionsSize();
     if (size > 0) {
-        fprintf(PerfFilePtr, "%" PRIxPTR " %zx %s (%p 0x%zx)\n",
-                reinterpret_cast<uintptr_t>(code->raw()),
-                size, msg, code->raw(), size);
+        AutoLockPerfMap lock;
+        PerfSpewer::WriteEntry(lock, reinterpret_cast<uintptr_t>(code->raw()), size,
+                               "%s (%p 0x%zx)", msg, code->raw(), size);
     }
+}
 
-    unlockPerfMap();
+void
+js::jit::writePerfSpewerWasmMap(uintptr_t base, uintptr_t size, const char* filename,
+                                const char* annotation)
+{
+    if (!PerfFuncEnabled() || size == 0U)
+        return;
+
+    AutoLockPerfMap lock;
+    PerfSpewer::WriteEntry(lock, base, size, "%s: Function %s", filename, annotation);
 }
 
 void
 js::jit::writePerfSpewerWasmFunctionMap(uintptr_t base, uintptr_t size,
-                                         const char* filename, unsigned lineno, unsigned colIndex,
+                                         const char* filename, unsigned lineno,
                                          const char* funcName)
 {
     if (!PerfFuncEnabled() || size == 0U)
         return;
 
-    if (!lockPerfMap())
-        return;
-
-    fprintf(PerfFilePtr, "%" PRIxPTR " %" PRIxPTR " %s:%u:%u: Function %s\n",
-            base, size, filename, lineno, colIndex, funcName);
-
-    unlockPerfMap();
+    AutoLockPerfMap lock;
+    PerfSpewer::WriteEntry(lock, base, size, "%s:%u: Function %s", filename, lineno, funcName);
 }
 
 #endif // defined (JS_ION_PERF)
--- a/js/src/jit/PerfSpewer.h
+++ b/js/src/jit/PerfSpewer.h
@@ -7,16 +7,20 @@
 #ifndef jit_PerfSpewer_h
 #define jit_PerfSpewer_h
 
 #ifdef JS_ION_PERF
 # include <stdio.h>
 # include "jit/MacroAssembler.h"
 #endif
 
+namespace {
+    struct AutoLockPerfMap;
+}
+
 namespace js {
 namespace jit {
 
 class MBasicBlock;
 class MacroAssembler;
 
 #ifdef JS_ION_PERF
 void CheckPerf();
@@ -62,34 +66,40 @@ class PerfSpewer
   public:
     Label endInlineCode;
 
   protected:
     BasicBlocksVector basicBlocks_;
 
   public:
     virtual MOZ_MUST_USE bool startBasicBlock(MBasicBlock* blk, MacroAssembler& masm);
-    virtual MOZ_MUST_USE bool endBasicBlock(MacroAssembler& masm);
-    MOZ_MUST_USE bool noteEndInlineCode(MacroAssembler& masm);
+    virtual void endBasicBlock(MacroAssembler& masm);
+    void noteEndInlineCode(MacroAssembler& masm);
 
     void writeProfile(JSScript* script, JitCode* code, MacroAssembler& masm);
+
+    static void WriteEntry(const AutoLockPerfMap&, uintptr_t address, size_t size,
+                           const char* fmt, ...)
+        MOZ_FORMAT_PRINTF(4, 5);
 };
 
 void writePerfSpewerBaselineProfile(JSScript* script, JitCode* code);
 void writePerfSpewerJitCodeProfile(JitCode* code, const char* msg);
 
 // wasm doesn't support block annotations.
 class WasmPerfSpewer : public PerfSpewer
 {
   public:
     MOZ_MUST_USE bool startBasicBlock(MBasicBlock* blk, MacroAssembler& masm) { return true; }
-    MOZ_MUST_USE bool endBasicBlock(MacroAssembler& masm) { return true; }
+    void endBasicBlock(MacroAssembler& masm) { }
 };
 
+void writePerfSpewerWasmMap(uintptr_t base, uintptr_t size, const char* filename,
+                            const char* annotation);
 void writePerfSpewerWasmFunctionMap(uintptr_t base, uintptr_t size, const char* filename,
-                                    unsigned lineno, unsigned colIndex, const char* funcName);
+                                    unsigned lineno, const char* funcName);
 
 #endif // JS_ION_PERF
 
 } // namespace jit
 } // namespace js
 
 #endif /* jit_PerfSpewer_h */
--- a/js/src/jit/arm/MacroAssembler-arm-inl.h
+++ b/js/src/jit/arm/MacroAssembler-arm-inl.h
@@ -2131,16 +2131,68 @@ MacroAssembler::branchToComputedAddress(
     uint32_t scale = Imm32::ShiftOf(addr.scale).value;
 
     ma_ldr(DTRAddr(base, DtrRegImmShift(addr.index, LSL, scale)), pc);
     // When loading from pc, the pc is shifted to the next instruction, we
     // add one extra instruction to accomodate for this shifted offset.
     breakpoint();
 }
 
+void
+MacroAssembler::cmp32Move32(Condition cond, Register lhs, Register rhs, Register src,
+                            Register dest)
+{
+    cmp32(lhs, rhs);
+    ma_mov(src, dest, LeaveCC, cond);
+}
+
+void
+MacroAssembler::cmp32Move32(Condition cond, Register lhs, const Address& rhs, Register src,
+                            Register dest)
+{
+    ScratchRegisterScope scratch(*this);
+    SecondScratchRegisterScope scratch2(*this);
+    ma_ldr(rhs, scratch, scratch2);
+    cmp32Move32(cond, lhs, scratch, src, dest);
+}
+
+void
+MacroAssembler::boundsCheck32ForLoad(Register index, Register length, Register scratch,
+                                     Label* failure)
+{
+    MOZ_ASSERT(index != length);
+    MOZ_ASSERT(length != scratch);
+    MOZ_ASSERT(index != scratch);
+
+    if (JitOptions.spectreIndexMasking)
+        move32(Imm32(0), scratch);
+
+    branch32(Assembler::BelowOrEqual, length, index, failure);
+
+    if (JitOptions.spectreIndexMasking)
+        ma_mov(scratch, index, LeaveCC, Assembler::BelowOrEqual);
+}
+
+void
+MacroAssembler::boundsCheck32ForLoad(Register index, const Address& length, Register scratch,
+                                     Label* failure)
+{
+    MOZ_ASSERT(index != length.base);
+    MOZ_ASSERT(length.base != scratch);
+    MOZ_ASSERT(index != scratch);
+
+    if (JitOptions.spectreIndexMasking)
+        move32(Imm32(0), scratch);
+
+    branch32(Assembler::BelowOrEqual, length, index, failure);
+
+    if (JitOptions.spectreIndexMasking)
+        ma_mov(scratch, index, LeaveCC, Assembler::BelowOrEqual);
+}
+
 // ========================================================================
 // Memory access primitives.
 void
 MacroAssembler::storeUncanonicalizedDouble(FloatRegister src, const Address& addr)
 {
     ScratchRegisterScope scratch(*this);
     ma_vstr(src, addr, scratch);
 }
--- a/js/src/jit/arm64/MacroAssembler-arm64-inl.h
+++ b/js/src/jit/arm64/MacroAssembler-arm64-inl.h
@@ -1705,16 +1705,60 @@ MacroAssembler::branchTestMagic(Conditio
 }
 
 void
 MacroAssembler::branchToComputedAddress(const BaseIndex& addr)
 {
     MOZ_CRASH("branchToComputedAddress");
 }
 
+void
+MacroAssembler::cmp32Move32(Condition cond, Register lhs, Register rhs, Register src,
+                            Register dest)
+{
+    cmp32(lhs, rhs);
+    Csel(ARMRegister(dest, 32), ARMRegister(src, 32), ARMRegister(dest, 32), cond);
+}
+
+void
+MacroAssembler::cmp32Move32(Condition cond, Register lhs, const Address& rhs, Register src,
+                            Register dest)
+{
+    cmp32(lhs, rhs);
+    Csel(ARMRegister(dest, 32), ARMRegister(src, 32), ARMRegister(dest, 32), cond);
+}
+
+void
+MacroAssembler::boundsCheck32ForLoad(Register index, Register length, Register scratch,
+                                     Label* failure)
+{
+    MOZ_ASSERT(index != length);
+    MOZ_ASSERT(length != scratch);
+    MOZ_ASSERT(index != scratch);
+
+    branch32(Assembler::BelowOrEqual, length, index, failure);
+
+    if (JitOptions.spectreIndexMasking)
+        Csel(ARMRegister(index, 32), ARMRegister(index, 32), vixl::wzr, Assembler::Above);
+}
+
+void
+MacroAssembler::boundsCheck32ForLoad(Register index, const Address& length, Register scratch,
+                                     Label* failure)
+{
+    MOZ_ASSERT(index != length.base);
+    MOZ_ASSERT(length.base != scratch);
+    MOZ_ASSERT(index != scratch);
+
+    branch32(Assembler::BelowOrEqual, length, index, failure);
+
+    if (JitOptions.spectreIndexMasking)
+        Csel(ARMRegister(index, 32), ARMRegister(index, 32), vixl::wzr, Assembler::Above);
+}
+
 // ========================================================================
 // Memory access primitives.
 void
 MacroAssembler::storeUncanonicalizedDouble(FloatRegister src, const Address& dest)
 {
     Str(ARMFPRegister(src, 64), toMemOperand(dest));
 }
 void
--- a/js/src/jit/arm64/MacroAssembler-arm64.h
+++ b/js/src/jit/arm64/MacroAssembler-arm64.h
@@ -1017,28 +1017,37 @@ class MacroAssemblerCompat : public vixl
         Cmp(ARMRegister(a, 32), Operand(ARMRegister(b, 32)));
     }
     void cmp32(const Address& lhs, Imm32 rhs) {
         cmp32(Operand(lhs.base, lhs.offset), rhs);
     }
     void cmp32(const Address& lhs, Register rhs) {
         cmp32(Operand(lhs.base, lhs.offset), rhs);
     }
+    void cmp32(Register lhs, const Address& rhs) {
+        cmp32(lhs, Operand(rhs.base, rhs.offset));
+    }
     void cmp32(const Operand& lhs, Imm32 rhs) {
         vixl::UseScratchRegisterScope temps(this);
         const ARMRegister scratch32 = temps.AcquireW();
         Mov(scratch32, lhs);
         Cmp(scratch32, Operand(rhs.value));
     }
     void cmp32(const Operand& lhs, Register rhs) {
         vixl::UseScratchRegisterScope temps(this);
         const ARMRegister scratch32 = temps.AcquireW();
         Mov(scratch32, lhs);
         Cmp(scratch32, Operand(ARMRegister(rhs, 32)));
     }
+    void cmp32(Register lhs, const Operand& rhs) {
+        vixl::UseScratchRegisterScope temps(this);
+        const ARMRegister scratch32 = temps.AcquireW();
+        Mov(scratch32, rhs);
+        Cmp(scratch32, Operand(ARMRegister(lhs, 32)));
+    }
 
     void cmpPtr(Register lhs, Imm32 rhs) {
         Cmp(ARMRegister(lhs, 64), Operand(rhs.value));
     }
     void cmpPtr(Register lhs, ImmWord rhs) {
         Cmp(ARMRegister(lhs, 64), Operand(rhs.value));
     }
     void cmpPtr(Register lhs, ImmPtr rhs) {
--- a/js/src/jit/x86-shared/Assembler-x86-shared.h
+++ b/js/src/jit/x86-shared/Assembler-x86-shared.h
@@ -464,16 +464,20 @@ class AssemblerX86Shared : public Assemb
             break;
           case Operand::MEM_SCALE:
             masm.cmovCCl_mr(cc, src.disp(), src.base(), src.index(), src.scale(), dest.encoding());
             break;
           default:
             MOZ_CRASH("unexpected operand kind");
         }
     }
+    void cmovCCl(Condition cond, Register src, Register dest) {
+        X86Encoding::Condition cc = static_cast<X86Encoding::Condition>(cond);
+        masm.cmovCCl_rr(cc, src.encoding(), dest.encoding());
+    }
     void cmovzl(const Operand& src, Register dest) {
         cmovCCl(Condition::Zero, src, dest);
     }
     void cmovnzl(const Operand& src, Register dest) {
         cmovCCl(Condition::NonZero, src, dest);
     }
     void movl(Imm32 imm32, Register dest) {
         masm.movl_i32r(imm32.value, dest.encoding());
--- a/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h
+++ b/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h
@@ -1089,16 +1089,68 @@ MacroAssembler::branchTestMagic(Conditio
 template <typename T, class L>
 void
 MacroAssembler::branchTestMagicImpl(Condition cond, const T& t, L label)
 {
     cond = testMagic(cond, t);
     j(cond, label);
 }
 
+void
+MacroAssembler::cmp32Move32(Condition cond, Register lhs, Register rhs, Register src,
+                            Register dest)
+{
+    cmp32(lhs, rhs);
+    cmovCCl(cond, src, dest);
+}
+
+void
+MacroAssembler::cmp32Move32(Condition cond, Register lhs, const Address& rhs, Register src,
+                            Register dest)
+{
+    cmp32(lhs, Operand(rhs));
+    cmovCCl(cond, src, dest);
+}
+
+void
+MacroAssembler::boundsCheck32ForLoad(Register index, Register length, Register scratch,
+                                     Label* failure)
+{
+    MOZ_ASSERT(index != length);
+    MOZ_ASSERT(length != scratch);
+    MOZ_ASSERT(index != scratch);
+
+    if (JitOptions.spectreIndexMasking)
+        move32(Imm32(0), scratch);
+
+    cmp32(index, length);
+    j(Assembler::AboveOrEqual, failure);
+
+    if (JitOptions.spectreIndexMasking)
+        cmovCCl(Assembler::AboveOrEqual, scratch, index);
+}
+
+void
+MacroAssembler::boundsCheck32ForLoad(Register index, const Address& length, Register scratch,
+                                     Label* failure)
+{
+    MOZ_ASSERT(index != length.base);
+    MOZ_ASSERT(length.base != scratch);
+    MOZ_ASSERT(index != scratch);
+
+    if (JitOptions.spectreIndexMasking)
+        move32(Imm32(0), scratch);
+
+    cmp32(index, Operand(length));
+    j(Assembler::AboveOrEqual, failure);
+
+    if (JitOptions.spectreIndexMasking)
+        cmovCCl(Assembler::AboveOrEqual, scratch, index);
+}
+
 // ========================================================================
 // Canonicalization primitives.
 void
 MacroAssembler::canonicalizeFloat32x4(FloatRegister reg, FloatRegister scratch)
 {
     ScratchSimd128Scope scratch2(*this);
 
     MOZ_ASSERT(scratch.asSimd128() != scratch2.asSimd128());
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -5839,16 +5839,24 @@ JS_AtomizeAndPinStringN(JSContext* cx, c
     AssertHeapIsIdle();
     CHECK_REQUEST(cx);
     JSAtom* atom = Atomize(cx, s, length, PinAtom);
     MOZ_ASSERT_IF(atom, JS_StringHasBeenPinned(cx, atom));
     return atom;
 }
 
 JS_PUBLIC_API(JSString*)
+JS_NewLatin1String(JSContext* cx, JS::Latin1Char* chars, size_t length)
+{
+    AssertHeapIsIdle();
+    CHECK_REQUEST(cx);
+    return NewString<CanGC>(cx, chars, length);
+}
+
+JS_PUBLIC_API(JSString*)
 JS_NewUCString(JSContext* cx, char16_t* chars, size_t length)
 {
     AssertHeapIsIdle();
     CHECK_REQUEST(cx);
     return NewString<CanGC>(cx, chars, length);
 }
 
 JS_PUBLIC_API(JSString*)
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -4718,16 +4718,19 @@ JS_AtomizeString(JSContext* cx, const ch
 
 extern JS_PUBLIC_API(JSString*)
 JS_AtomizeAndPinStringN(JSContext* cx, const char* s, size_t length);
 
 extern JS_PUBLIC_API(JSString*)
 JS_AtomizeAndPinString(JSContext* cx, const char* s);
 
 extern JS_PUBLIC_API(JSString*)
+JS_NewLatin1String(JSContext* cx, JS::Latin1Char* chars, size_t length);
+
+extern JS_PUBLIC_API(JSString*)
 JS_NewUCString(JSContext* cx, char16_t* chars, size_t length);
 
 extern JS_PUBLIC_API(JSString*)
 JS_NewUCStringCopyN(JSContext* cx, const char16_t* s, size_t n);
 
 extern JS_PUBLIC_API(JSString*)
 JS_NewUCStringCopyZ(JSContext* cx, const char16_t* s);
 
--- a/js/src/vm/String.cpp
+++ b/js/src/vm/String.cpp
@@ -206,17 +206,17 @@ JSString::dumpRepresentationHeader(js::G
     // copy-and-paste into a debugger.
     out.printf("((%s*) %p) length: %zu  flags: 0x%x", subclass, this, length(), flags);
     if (flags & LINEAR_BIT)             out.put(" LINEAR");
     if (flags & HAS_BASE_BIT)           out.put(" HAS_BASE");
     if (flags & INLINE_CHARS_BIT)       out.put(" INLINE_CHARS");
     if (flags & ATOM_BIT)               out.put(" ATOM");
     if (isPermanentAtom())              out.put(" PERMANENT");
     if (flags & LATIN1_CHARS_BIT)       out.put(" LATIN1");
-    if (flags & INDEX_VALUE_BIT)        out.put(" INDEX_VALUE(%u)", getIndexValue());
+    if (flags & INDEX_VALUE_BIT)        out.printf(" INDEX_VALUE(%u)", getIndexValue());
     out.putChar('\n');
 }
 
 void
 JSLinearString::dumpRepresentationChars(js::GenericPrinter& out, int indent) const
 {
     if (hasLatin1Chars()) {
         out.printf("%*schars: ((Latin1Char*) %p) ", indent, "", rawLatin1Chars());
--- a/js/src/wasm/WasmBinaryConstants.h
+++ b/js/src/wasm/WasmBinaryConstants.h
@@ -582,17 +582,18 @@ static const unsigned MaxDataSegments   
 static const unsigned MaxElemSegments        = 10000000;
 static const unsigned MaxTableInitialLength  = 10000000;
 static const unsigned MaxStringBytes         =   100000;
 static const unsigned MaxLocals              =    50000;
 static const unsigned MaxParams              =     1000;
 static const unsigned MaxBrTableElems        =  1000000;
 static const unsigned MaxMemoryInitialPages  = 16384;
 static const unsigned MaxMemoryMaximumPages  = 65536;
-static const unsigned MaxModuleBytes         = 1024 * 1024 * 1024;
+static const unsigned MaxCodeSectionBytes    = 1024 * 1024 * 1024;
+static const unsigned MaxModuleBytes         = MaxCodeSectionBytes;
 static const unsigned MaxFunctionBytes       =  7654321;
 
 // A magic value of the FramePointer to indicate after a return to the entry
 // stub that an exception has been caught and that we should throw.
 
 static const unsigned FailFP = 0xbad;
 
 // Asserted by Decoder::readVarU32.
--- a/js/src/wasm/WasmCode.cpp
+++ b/js/src/wasm/WasmCode.cpp
@@ -134,58 +134,85 @@ StaticallyUnlink(uint8_t* base, const Li
             uint8_t* patchAt = base + offset;
             Assembler::PatchDataWithValueCheck(CodeLocationLabel(patchAt),
                                                PatchedImmPtr((void*)-1),
                                                PatchedImmPtr(target));
         }
     }
 }
 
+#ifdef JS_ION_PERF
+static bool
+AppendToString(const char* str, UTF8Bytes* bytes)
+{
+    return bytes->append(str, strlen(str)) && bytes->append('\0');
+}
+#endif
+
 static void
 SendCodeRangesToProfiler(const CodeSegment& cs, const Bytes& bytecode, const Metadata& metadata)
 {
     bool enabled = false;
 #ifdef JS_ION_PERF
     enabled |= PerfFuncEnabled();
 #endif
 #ifdef MOZ_VTUNE
     enabled |= vtune::IsProfilingActive();
 #endif
     if (!enabled)
         return;
 
     for (const CodeRange& codeRange : metadata.metadata(cs.tier()).codeRanges) {
-        if (!codeRange.isFunction())
+        if (!codeRange.hasFuncIndex())
             continue;
 
         uintptr_t start = uintptr_t(cs.base() + codeRange.begin());
-        uintptr_t end = uintptr_t(cs.base() + codeRange.end());
-        uintptr_t size = end - start;
+        uintptr_t size = codeRange.end() - codeRange.begin();
 
         UTF8Bytes name;
         if (!metadata.getFuncName(&bytecode, codeRange.funcIndex(), &name))
             return;
-        if (!name.append('\0'))
-            return;
 
         // Avoid "unused" warnings
         (void)start;
         (void)size;
 
 #ifdef JS_ION_PERF
         if (PerfFuncEnabled()) {
             const char* file = metadata.filename.get();
-            unsigned line = codeRange.funcLineOrBytecode();
-            unsigned column = 0;
-            writePerfSpewerWasmFunctionMap(start, size, file, line, column, name.begin());
+            if (codeRange.isFunction()) {
+                if (!name.append('\0'))
+                    return;
+                unsigned line = codeRange.funcLineOrBytecode();
+                writePerfSpewerWasmFunctionMap(start, size, file, line, name.begin());
+            } else if (codeRange.isInterpEntry()) {
+                if (!AppendToString(" slow entry", &name))
+                    return;
+                writePerfSpewerWasmMap(start, size, file, name.begin());
+            } else if (codeRange.isImportInterpExit()) {
+                if (!AppendToString(" slow exit", &name))
+                    return;
+                writePerfSpewerWasmMap(start, size, file, name.begin());
+            } else if (codeRange.isImportJitExit()) {
+                if (!AppendToString(" fast exit", &name))
+                    return;
+                writePerfSpewerWasmMap(start, size, file, name.begin());
+            } else {
+                MOZ_CRASH("unhandled perf hasFuncIndex type");
+            }
         }
 #endif
 #ifdef MOZ_VTUNE
-        if (vtune::IsProfilingActive())
-            vtune::MarkWasm(vtune::GenerateUniqueMethodID(), name.begin(), (void*)start, size);
+        if (!vtune::IsProfilingActive())
+            continue;
+        if (!codeRange.isFunction())
+            continue;
+        if (!name.append('\0'))
+            return;
+        vtune::MarkWasm(vtune::GenerateUniqueMethodID(), name.begin(), (void*)start, size);
 #endif
     }
 }
 
 /* static */ UniqueCodeSegment
 CodeSegment::create(Tier tier,
                     MacroAssembler& masm,
                     const ShareableBytes& bytecode,
--- a/js/src/wasm/WasmGenerator.cpp
+++ b/js/src/wasm/WasmGenerator.cpp
@@ -206,19 +206,19 @@ ModuleGenerator::init(Metadata* maybeAsm
     if (!funcToCodeRange_.appendN(BAD_CODE_RANGE, env_->funcSigs.length()))
         return false;
 
     // Pre-reserve space for large Vectors to avoid the significant cost of the
     // final reallocs. In particular, the MacroAssembler can be enormous, so be
     // extra conservative. Note, podResizeToFit calls at the end will trim off
     // unneeded capacity.
 
-    uint32_t codeSectionSize = env_->codeSection ? env_->codeSection->size : 0;
-
-    if (!masm_.reserve(size_t(1.2 * EstimateCompiledCodeSize(tier(), codeSectionSize))))
+    size_t codeSectionSize = env_->codeSection ? env_->codeSection->size : 0;
+    size_t estimatedCodeSize = 1.2 * EstimateCompiledCodeSize(tier(), codeSectionSize);
+    if (!masm_.reserve(Min(estimatedCodeSize, MaxCodeBytesPerProcess)))
         return false;
 
     if (!metadataTier_->codeRanges.reserve(2 * env_->numFuncDefs()))
         return false;
 
     const size_t ByteCodesPerCallSite = 10;
     if (!metadataTier_->callSites.reserve(codeSectionSize / ByteCodesPerCallSite))
         return false;
@@ -777,17 +777,17 @@ ModuleGenerator::compileFuncDef(uint32_t
     uint32_t threshold;
     switch (tier()) {
       case Tier::Baseline: threshold = JitOptions.wasmBatchBaselineThreshold; break;
       case Tier::Ion:      threshold = JitOptions.wasmBatchIonThreshold;      break;
       default:             MOZ_CRASH("Invalid tier value");                   break;
     }
 
     batchedBytecode_ += funcBytecodeLength;
-    MOZ_ASSERT(batchedBytecode_ <= MaxModuleBytes);
+    MOZ_ASSERT(batchedBytecode_ <= MaxCodeSectionBytes);
     return batchedBytecode_ <= threshold || launchBatchCompile();
 }
 
 bool
 ModuleGenerator::finishFuncDefs()
 {
     MOZ_ASSERT(!finishedFuncDefs_);
 
--- a/js/src/wasm/WasmJS.cpp
+++ b/js/src/wasm/WasmJS.cpp
@@ -2513,17 +2513,17 @@ class CompileStreamTask : public Promise
 
             if (!StartsCodeSection(envBytes_.begin(), envBytes_.end(), &codeSection_))
                 return true;
 
             uint32_t extraBytes = envBytes_.length() - codeSection_.start;
             if (extraBytes)
                 envBytes_.shrinkTo(codeSection_.start);
 
-            if (codeSection_.size > MaxModuleBytes)
+            if (codeSection_.size > MaxCodeSectionBytes)
                 return rejectAndDestroyBeforeHelperThreadStarted(JSMSG_OUT_OF_MEMORY);
 
             if (!codeBytes_.resize(codeSection_.size))
                 return rejectAndDestroyBeforeHelperThreadStarted(JSMSG_OUT_OF_MEMORY);
 
             codeStreamEnd_ = codeBytes_.begin();
             exclusiveCodeStreamEnd_.lock().get() = codeStreamEnd_;
 
--- a/js/src/wasm/WasmTypes.h
+++ b/js/src/wasm/WasmTypes.h
@@ -1121,19 +1121,25 @@ class CodeRange
 
     Kind kind() const {
         return kind_;
     }
 
     bool isFunction() const {
         return kind() == Function;
     }
+    bool isInterpEntry() const {
+        return kind() == InterpEntry;
+    }
     bool isImportExit() const {
         return kind() == ImportJitExit || kind() == ImportInterpExit || kind() == BuiltinThunk;
     }
+    bool isImportInterpExit() const {
+        return kind() == ImportInterpExit;
+    }
     bool isImportJitExit() const {
         return kind() == ImportJitExit;
     }
     bool isTrapExit() const {
         return kind() == OldTrapExit || kind() == TrapExit;
     }
     bool isDebugTrap() const {
         return kind() == DebugTrap;
--- a/js/src/wasm/WasmValidate.cpp
+++ b/js/src/wasm/WasmValidate.cpp
@@ -1717,16 +1717,19 @@ wasm::DecodeModuleEnvironment(Decoder& d
         return false;
 
     if (!DecodeElemSection(d, env))
         return false;
 
     if (!d.startSection(SectionId::Code, env, &env->codeSection, "code"))
         return false;
 
+    if (env->codeSection && env->codeSection->size > MaxCodeSectionBytes)
+        return d.fail("code section too big");
+
     return true;
 }
 
 static bool
 DecodeFunctionBody(Decoder& d, const ModuleEnvironment& env, uint32_t funcIndex)
 {
     uint32_t bodySize;
     if (!d.readVarU32(&bodySize))
deleted file mode 100644
--- a/layout/reftests/svg/path-03.svg
+++ /dev/null
@@ -1,29 +0,0 @@
-<!--
-     Any copyright is dedicated to the Public Domain.
-     http://creativecommons.org/publicdomain/zero/1.0/
--->
-<svg xmlns="http://www.w3.org/2000/svg">
-
-  <title>Testcase for invalid path</title>
-
-  <!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=601699 -->
-
-  <marker id="marker" markerWidth="10" markerHeight="10">
-    <circle cx="5" cy="5" r="5"/>
-  </marker>
-
-  <rect width="100%" height="100%" fill="lime"/>
-
-  <path id="path" fill="red" marker-mid="url(#marker)"/>
-
-  <script><![CDATA[
-
-// Parser will throw out path without an initial moveto command, so we use
-// script to inject one and see what happens.
-
-var path = document.getElementById("path");
-var curve = path.createSVGPathSegCurvetoCubicAbs(0, 400, 400, 400, 400, 0);
-path.pathSegList.appendItem(curve);
-
-  ]]></script>
-</svg>
--- a/layout/reftests/svg/reftest.list
+++ b/layout/reftests/svg/reftest.list
@@ -335,17 +335,16 @@ fuzzy-if(skiaContent,7,175) == outline.h
 == paint-on-maskLayer-1b.html paint-on-maskLayer-1-ref.html
 == paint-on-maskLayer-1c.html paint-on-maskLayer-1-ref.html
 pref(svg.paint-order.enabled,true) == paint-order-01.svg paint-order-01-ref.svg
 pref(svg.paint-order.enabled,true) == paint-order-02.svg paint-order-02-ref.svg
 pref(svg.paint-order.enabled,true) == paint-order-03.svg paint-order-03-ref.svg
 
 #fuzzy(23,60) fails-if(d2d) == path-01.svg path-01-ref.svg
 == path-02.svg pass.svg
-== path-03.svg pass.svg
 == path-04.svg pass.svg
 == path-05.svg pass.svg
 fuzzy-if(skiaContent,1,400) == path-06.svg path-06-ref.svg
 == path-07.svg path-07-ref.svg
 == path-08.svg pass.svg
 
 == pathLength-01.svg pass.svg
 == pathLength-02.svg pass.svg
deleted file mode 100644
--- a/layout/svg/crashtests/327709-1.svg
+++ /dev/null
@@ -1,17 +0,0 @@
-<!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=327709 -->
-<!-- Just checking for absence of assertion, nothing more -->
-<svg xmlns="http://www.w3.org/2000/svg">
-
-<script>
-function init()
-{
-  var apsl = document.getElementById("n126").animatedPathSegList;
-  apsl.appendItem(apsl.__proto__);
-}
-window.addEventListener("load", init, false);
-</script>
-
-<path id="n126" d="M 270 60 L 320 60 L 320 110 Z"/>
-
-</svg>
-
--- a/layout/svg/crashtests/crashtests.list
+++ b/layout/svg/crashtests/crashtests.list
@@ -10,17 +10,16 @@ load 313737-1.xml
 load 314244-1.xul
 load 322185-1.svg
 load 322215-1.svg
 load 323704-1.svg
 load 325427-1.svg
 load 326495-1.svg
 load 326974-1.svg
 load 327706-1.svg
-load 327709-1.svg
 load 327711-1.svg
 load 328137-1.svg
 load 329848-1.svg
 load 337408-1.xul
 load 338301-1.xhtml
 load 338312-1.xhtml
 load 340083-1.svg
 load 340945-1.svg
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -1544,17 +1544,17 @@ pref("javascript.options.mem.gc_max_empt
 pref("javascript.options.showInConsole", false);
 
 pref("javascript.options.shared_memory", false);
 
 pref("javascript.options.throw_on_debuggee_would_run", false);
 pref("javascript.options.dump_stack_on_debuggee_would_run", false);
 
 // Spectre security vulnerability mitigations.
-pref("javascript.options.spectre.index_masking", false);
+pref("javascript.options.spectre.index_masking", true);
 
 // Streams API
 pref("javascript.options.streams", false);
 
 // advanced prefs
 pref("advanced.mailftp",                    false);
 pref("image.animation_mode",                "normal");
 
--- a/testing/web-platform/meta/svg/historical.html.ini
+++ b/testing/web-platform/meta/svg/historical.html.ini
@@ -1,12 +1,9 @@
 [historical.html]
-  [SVGPathSeg interface must be removed]
-    expected: FAIL
-
   [SVGUnitTypes mixin interface must not be exposed]
     expected: FAIL
 
   [SVGZoomAndPan mixin interface must not be exposed]
     expected: FAIL
 
   [SVGGraphicsElement.prototype.getTransformToElement must be removed]
     expected: FAIL