Merge mozilla-central to autoland
authorarthur.iakab <aiakab@mozilla.com>
Thu, 27 Dec 2018 23:57:57 +0200
changeset 509118 5f2cdabc126a00b893bc871184440ae58248556c
parent 509117 1a2a77d23796084a781ffa1d8d281e2b4f22f8f2 (current diff)
parent 509116 a77e8f3efc4cb45b7caa0c87879910b9991b4219 (diff)
child 509119 3c54ad1e420e75dd4b2c5e6671ad9d04cd0e8717
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone66.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge mozilla-central to autoland
dom/smil/nsSMILCSSValueType.cpp
dom/smil/nsSMILCSSValueType.h
dom/smil/nsSMILNullType.cpp
dom/smil/nsSMILNullType.h
--- a/browser/components/extensions/test/browser/browser-common.ini
+++ b/browser/components/extensions/test/browser/browser-common.ini
@@ -111,16 +111,17 @@ skip-if = (verify && (os == 'linux' || o
 [browser_ext_management.js]
 [browser_ext_menus.js]
 [browser_ext_menus_accesskey.js]
 [browser_ext_menus_activeTab.js]
 [browser_ext_menus_capture_secondary_click.js]
 [browser_ext_menus_errors.js]
 [browser_ext_menus_event_order.js]
 [browser_ext_menus_events.js]
+skip-if = os == 'linux' #Bug 1433892
 [browser_ext_menus_refresh.js]
 [browser_ext_menus_replace_menu.js]
 [browser_ext_menus_replace_menu_context.js]
 [browser_ext_menus_replace_menu_permissions.js]
 [browser_ext_menus_targetElement.js]
 [browser_ext_menus_targetElement_extension.js]
 [browser_ext_menus_targetElement_shadow.js]
 [browser_ext_menus_visible.js]
--- a/browser/components/preferences/in-content/main.xul
+++ b/browser/components/preferences/in-content/main.xul
@@ -388,27 +388,26 @@
 <groupbox id="applicationsGroup" data-category="paneGeneral" hidden="true">
   <label><html:h2 data-l10n-id="applications-header"/></label>
   <description data-l10n-id="applications-description"/>
   <textbox id="filter" flex="1"
            type="search"
            data-l10n-id="applications-filter"
            aria-controls="handlersView"/>
 
+  <listheader equalsize="always">
+    <treecol id="typeColumn" data-l10n-id="applications-type-column" value="type"
+             persist="sortDirection"
+             flex="1" sortDirection="ascending"/>
+    <treecol id="actionColumn" data-l10n-id="applications-action-column" value="action"
+             persist="sortDirection"
+             flex="1"/>
+  </listheader>
   <richlistbox id="handlersView"
-               preference="pref.downloads.disable_button.edit_actions">
-    <listheader equalsize="always">
-        <treecol id="typeColumn" data-l10n-id="applications-type-column" value="type"
-                 persist="sortDirection"
-                 flex="1" sortDirection="ascending"/>
-        <treecol id="actionColumn" data-l10n-id="applications-action-column" value="action"
-                 persist="sortDirection"
-                 flex="1"/>
-    </listheader>
-  </richlistbox>
+               preference="pref.downloads.disable_button.edit_actions"/>
 </groupbox>
 
 
 <!-- DRM Content -->
 <groupbox id="drmGroup" data-category="paneGeneral" data-subcategory="drm" hidden="true">
   <label><html:h2 data-l10n-id="drm-content-header"/></label>
   <grid id="contentGrid2">
     <columns>
--- a/browser/components/preferences/permissions.js
+++ b/browser/components/preferences/permissions.js
@@ -425,17 +425,17 @@ var gPermissionManager = {
       items.sort((a, b) => sortFunc(b, a));
     } else {
       items.sort(sortFunc);
     }
 
     // Re-append items in the correct order:
     items.forEach(item => frag.appendChild(item));
 
-    let cols = list.querySelectorAll("treecol");
+    let cols = list.previousElementSibling.querySelectorAll("treecol");
     cols.forEach(c => {
       c.removeAttribute("data-isCurrentSortCol");
       c.removeAttribute("sortDirection");
     });
     column.setAttribute("data-isCurrentSortCol", "true");
     column.setAttribute("sortDirection", sortDirection);
     column.setAttribute("data-last-sortDirection", sortDirection);
   },
--- a/browser/components/preferences/permissions.xul
+++ b/browser/components/preferences/permissions.xul
@@ -43,27 +43,26 @@
       <button id="btnBlock" disabled="true" data-l10n-id="permissions-block"
               oncommand="gPermissionManager.addPermission(Ci.nsIPermissionManager.DENY_ACTION);"/>
       <button id="btnSession" disabled="true" data-l10n-id="permissions-session"
               oncommand="gPermissionManager.addPermission(Ci.nsICookiePermission.ACCESS_SESSION);"/>
       <button id="btnAllow" disabled="true" data-l10n-id="permissions-allow" default="true"
               oncommand="gPermissionManager.addPermission(Ci.nsIPermissionManager.ALLOW_ACTION);"/>
     </hbox>
     <separator class="thin"/>
+    <listheader>
+      <treecol id="siteCol" data-l10n-id="permissions-site-name" flex="3" width="0"
+               onclick="gPermissionManager.buildPermissionsList(event.target)"/>
+      <treecol id="statusCol" data-l10n-id="permissions-status" flex="1" width="0"
+               data-isCurrentSortCol="true"
+               onclick="gPermissionManager.buildPermissionsList(event.target);"/>
+    </listheader>
     <richlistbox id="permissionsBox" flex="1" selected="false"
                  onkeypress="gPermissionManager.onPermissionKeyPress(event);"
-                 onselect="gPermissionManager.onPermissionSelect();">
-      <listheader>
-        <treecol id="siteCol" data-l10n-id="permissions-site-name" flex="3" width="0"
-                 onclick="gPermissionManager.buildPermissionsList(event.target)"/>
-        <treecol id="statusCol" data-l10n-id="permissions-status" flex="1" width="0"
-                 data-isCurrentSortCol="true"
-                 onclick="gPermissionManager.buildPermissionsList(event.target);"/>
-      </listheader>
-    </richlistbox>
+                 onselect="gPermissionManager.onPermissionSelect();"/>
   </vbox>
 
   <hbox class="actionButtons" align="left" flex="1">
     <button id="removePermission" disabled="true"
             data-l10n-id="permissions-remove"
             icon="remove"
             oncommand="gPermissionManager.onPermissionDelete();"/>
     <button id="removeAllPermissions"
--- a/browser/components/preferences/siteDataSettings.js
+++ b/browser/components/preferences/siteDataSettings.js
@@ -164,17 +164,17 @@ let gSiteDataSettings = {
         break;
     }
     if (sortDirection === "descending") {
       sites.sort((a, b) => sortFunc(b, a));
     } else {
       sites.sort(sortFunc);
     }
 
-    let cols = this._list.querySelectorAll("treecol");
+    let cols = this._list.previousElementSibling.querySelectorAll("treecol");
     cols.forEach(c => {
       c.removeAttribute("sortDirection");
       c.removeAttribute("data-isCurrentSortCol");
     });
     col.setAttribute("data-isCurrentSortCol", true);
     col.setAttribute("sortDirection", sortDirection);
     col.setAttribute("data-last-sortDirection", sortDirection);
   },
--- a/browser/components/preferences/siteDataSettings.xul
+++ b/browser/components/preferences/siteDataSettings.xul
@@ -30,25 +30,24 @@
     <separator class="thin"/>
 
     <hbox id="searchBoxContainer">
       <textbox id="searchBox" type="search" flex="1"
         data-l10n-id="site-data-search-textbox"/>
     </hbox>
     <separator class="thin"/>
 
-    <richlistbox seltype="multiple" id="sitesList" orient="vertical" flex="1">
-      <listheader>
-        <treecol flex="4" width="50" data-l10n-id="site-data-column-host" id="hostCol"/>
-        <treecol flex="1" width="50" data-l10n-id="site-data-column-cookies" id="cookiesCol"/>
-        <!-- Sorted by usage so the user can quickly see which sites use the most data. -->
-        <treecol flex="2" width="50" data-l10n-id="site-data-column-storage" id="usageCol" data-isCurrentSortCol="true"/>
-        <treecol flex="2" width="50" data-l10n-id="site-data-column-last-used" id="lastAccessedCol" />
-      </listheader>
-    </richlistbox>
+    <listheader>
+      <treecol flex="4" width="50" data-l10n-id="site-data-column-host" id="hostCol"/>
+      <treecol flex="1" width="50" data-l10n-id="site-data-column-cookies" id="cookiesCol"/>
+      <!-- Sorted by usage so the user can quickly see which sites use the most data. -->
+      <treecol flex="2" width="50" data-l10n-id="site-data-column-storage" id="usageCol" data-isCurrentSortCol="true"/>
+      <treecol flex="2" width="50" data-l10n-id="site-data-column-last-used" id="lastAccessedCol" />
+    </listheader>
+    <richlistbox seltype="multiple" id="sitesList" orient="vertical" flex="1"/>
   </vbox>
 
   <hbox align="start">
     <button id="removeSelected" data-l10n-id="site-data-remove-selected"/>
     <button id="removeAll"/>
   </hbox>
 
   <vbox align="end">
--- a/browser/components/preferences/sitePermissions.js
+++ b/browser/components/preferences/sitePermissions.js
@@ -461,17 +461,17 @@ var gSitePermissionsManager = {
       items.sort((a, b) => sortFunc(b, a));
     } else {
       items.sort(sortFunc);
     }
 
     // Re-append items in the correct order:
     items.forEach(item => frag.appendChild(item));
 
-    let cols = list.querySelectorAll("treecol");
+    let cols = list.previousElementSibling.querySelectorAll("treecol");
     cols.forEach(c => {
       c.removeAttribute("data-isCurrentSortCol");
       c.removeAttribute("sortDirection");
     });
     column.setAttribute("data-isCurrentSortCol", "true");
     column.setAttribute("sortDirection", sortDirection);
     column.setAttribute("data-last-sortDirection", sortDirection);
   },
--- a/browser/components/preferences/sitePermissions.xul
+++ b/browser/components/preferences/sitePermissions.xul
@@ -33,27 +33,26 @@
   <vbox class="contentPane">
     <description id="permissionsText" control="url"/>
     <separator class="thin"/>
     <hbox align="start">
       <textbox id="searchBox" flex="1" data-l10n-id="permissions-searchbox"
                type="search" oncommand="gSitePermissionsManager.buildPermissionsList();"/>
     </hbox>
     <separator class="thin"/>
+    <listheader>
+      <treecol id="siteCol" data-l10n-id="permissions-site-name" flex="3" width="50"
+               onclick="gSitePermissionsManager.buildPermissionsList(event.target)"/>
+      <treecol id="statusCol" data-l10n-id="permissions-status" flex="1" width="50"
+               data-isCurrentSortCol="true"
+               onclick="gSitePermissionsManager.buildPermissionsList(event.target);"/>
+    </listheader>
     <richlistbox id="permissionsBox" flex="1" selected="false"
                  onkeypress="gSitePermissionsManager.onPermissionKeyPress(event);"
-                 onselect="gSitePermissionsManager.onPermissionSelect();">
-      <listheader>
-        <treecol id="siteCol" data-l10n-id="permissions-site-name" flex="3" width="50"
-                 onclick="gSitePermissionsManager.buildPermissionsList(event.target)"/>
-        <treecol id="statusCol" data-l10n-id="permissions-status" flex="1" width="50"
-                 data-isCurrentSortCol="true"
-                 onclick="gSitePermissionsManager.buildPermissionsList(event.target);"/>
-      </listheader>
-    </richlistbox>
+                 onselect="gSitePermissionsManager.onPermissionSelect();"/>
   </vbox>
 
   <hbox class="actionButtons" align="left" flex="1">
     <button id="removePermission" disabled="true"
             data-l10n-id="permissions-remove"
             icon="remove"
             oncommand="gSitePermissionsManager.onPermissionDelete();"/>
     <button id="removeAllPermissions"
--- 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 111
+Version 112
 
-Comparison: https://github.com/devtools-html/debugger.html/compare/release-110...release-111
+Comparison: https://github.com/devtools-html/debugger.html/compare/release-111...release-112
 
 Packages:
 - babel-plugin-transform-es2015-modules-commonjs @6.26.2
 - babel-preset-react @6.24.1
 - react @16.4.1
 - react-dom @16.4.1
 - webpack @3.12.0
--- a/devtools/client/debugger/new/dist/debugger.css
+++ b/devtools/client/debugger/new/dist/debugger.css
@@ -1535,16 +1535,29 @@ html .toggle-button.end.vertical svg {
 
 .search-field .search-nav-buttons .nav-btn:active path {
   fill: var(--theme-comment-alt);
 }
 
 .search-field .search-nav-buttons .nav-btn path {
   fill: var(--theme-comment);
 }
+
+.search-field i.loader svg {
+  animation: rotate 0.5s linear infinite;
+}
+
+@keyframes rotate {
+  from {
+    transform: rotate(0deg);
+  }
+  to {
+    transform: rotate(360deg);
+  }
+}
 /* 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/>. */
 
 .search-container {
   position: absolute;
   top: 30px;
   left: 0;
@@ -1658,16 +1671,20 @@ html .toggle-button.end.vertical svg {
 }
 
 .project-text-search .managed-tree .tree .tree-node {
   display: contents;
 }
 
 /* Focus values */
 
+.project-text-search .file-result.focused .img.file {
+  background-color: white;
+}
+
 .project-text-search .file-result.focused,
 .project-text-search .result.focused .line-value {
   background-color: var(--theme-selection-background);
 }
 
 .project-text-search .result.focused .line-number {
   font-weight: bolder;
   background-color: var(--theme-selection-background);
@@ -3066,16 +3083,20 @@ debug-expression-error {
 
 .CodeMirror-guttermarker-subtle {
   visibility: hidden;
 }
 
 .visible {
   visibility: visible;
 }
+
+.download-anchor {
+  display: none;
+}
 /* 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/>. */
 
 .cm-highlight {
   position: relative;
 }
 
--- a/devtools/client/debugger/new/dist/parser-worker.js
+++ b/devtools/client/debugger/new/dist/parser-worker.js
@@ -23137,16 +23137,17 @@ const getGeneratedRanges = dispatcher.ta
 });
 const getGeneratedLocation = dispatcher.task("getGeneratedLocation", {
   queue: true
 });
 const getAllGeneratedLocations = dispatcher.task("getAllGeneratedLocations", {
   queue: true
 });
 const getOriginalLocation = dispatcher.task("getOriginalLocation");
+const getFileGeneratedRange = dispatcher.task("getFileGeneratedRange");
 const getLocationScopes = dispatcher.task("getLocationScopes");
 const getOriginalSourceText = dispatcher.task("getOriginalSourceText");
 const applySourceMap = dispatcher.task("applySourceMap");
 const clearSourceMaps = dispatcher.task("clearSourceMaps");
 const hasMappedSource = dispatcher.task("hasMappedSource");
 const getOriginalStackFrames = dispatcher.task("getOriginalStackFrames");
 
 module.exports = {
@@ -23156,16 +23157,17 @@ module.exports = {
   isOriginalId,
   hasMappedSource,
   getOriginalURLs,
   getOriginalRanges,
   getGeneratedRanges,
   getGeneratedLocation,
   getAllGeneratedLocations,
   getOriginalLocation,
+  getFileGeneratedRange,
   getLocationScopes,
   getOriginalSourceText,
   applySourceMap,
   clearSourceMaps,
   getOriginalStackFrames,
   startSourceMapWorker(url, assetRoot) {
     dispatcher.start(url);
     setAssetRootURL(assetRoot);
@@ -23240,17 +23242,18 @@ const contentMap = {
   jsm: "text/javascript",
   mjs: "text/javascript",
   ts: "text/typescript",
   tsx: "text/typescript-jsx",
   jsx: "text/jsx",
   vue: "text/vue",
   coffee: "text/coffeescript",
   elm: "text/elm",
-  cljs: "text/x-clojure"
+  cljc: "text/x-clojure",
+  cljs: "text/x-clojurescript"
 };
 
 /**
  * Returns the content type for the specified URL.  If no specific
  * content type can be determined, "text/plain" is returned.
  *
  * @return String
  *         The content type.
--- a/devtools/client/debugger/new/dist/vendors.js
+++ b/devtools/client/debugger/new/dist/vendors.js
@@ -3865,17 +3865,17 @@ module.exports = "<!-- This Source Code 
 
 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 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><g fill-rule=\"evenodd\"><circle cx=\"8\" cy=\"8.5\" r=\"1.5\"></circle><path d=\"M15.498 8.28l-.001-.03v-.002-.004l-.002-.018-.004-.031c0-.002 0-.002 0 0l-.004-.035.006.082c-.037-.296-.133-.501-.28-.661-.4-.522-.915-1.042-1.562-1.604-1.36-1.182-2.74-1.975-4.178-2.309a6.544 6.544 0 0 0-2.755-.042c-.78.153-1.565.462-2.369.91C3.252 5.147 2.207 6 1.252 7.035c-.216.233-.36.398-.499.577-.338.437-.338 1 0 1.437.428.552.941 1.072 1.59 1.635 1.359 1.181 2.739 1.975 4.177 2.308.907.21 1.829.223 2.756.043.78-.153 1.564-.462 2.369-.91 1.097-.612 2.141-1.464 3.097-2.499.217-.235.36-.398.498-.578.12-.128.216-.334.248-.554 0 .01 0 .01-.008.04l.013-.079-.001.011.003-.031.001-.017v.005l.001-.02v.008l.002-.03.001-.05-.001-.044v-.004-.004zm-.954.045v.007l.001.004V8.33v.012l-.001.01v-.005-.005l.002-.015-.001.008c-.002.014-.002.014 0 0l-.007.084c.003-.057-.004-.041-.014-.031-.143.182-.27.327-.468.543-.89.963-1.856 1.752-2.86 2.311-.724.404-1.419.677-2.095.81a5.63 5.63 0 0 1-2.374-.036c-1.273-.295-2.523-1.014-3.774-2.101-.604-.525-1.075-1.001-1.457-1.496-.054-.07-.054-.107 0-.177.117-.152.244-.298.442-.512.89-.963 1.856-1.752 2.86-2.311.724-.404 1.419-.678 2.095-.81a5.631 5.631 0 0 1 2.374.036c1.272.295 2.523 1.014 3.774 2.101.603.524 1.074 1 1.457 1.496.035.041.043.057.046.076 0 .01 0 .01.008.043l-.009-.047.003.02-.002-.013v-.008.016c0-.004 0-.004 0 0v-.004z\"></path></g></svg>"
 
 /***/ }),
 
 /***/ 350:
 /***/ (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 xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 60 12\"><path id=\"base-path\" d=\"M53.9,0H1C0.4,0,0,0.4,0,1v10c0,0.6,0.4,1,1,1h52.9c0.6,0,1.2-0.3,1.5-0.7L60,6l-4.4-5.3C55,0.3,54.5,0,53.9,0z\"></path></svg>"
+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 xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 60 14\"><path id=\"base-path\" d=\"M53.07.5H1.5a1 1 0 0 0-1 1v11a1 1 0 0 0 1 1h51.57a2 2 0 0 0 1.53-.7L59.3 7l-4.7-5.8a2 2 0 0 0-1.53-.7z&gt;&lt;/path&gt;&lt;/svg&gt;\">"
 
 /***/ }),
 
 /***/ 351:
 /***/ (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 xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 20 16\" stroke=\"none\" fillrule=\"evenodd\"><path d=\"M10.919,13 L9.463,13 C9.29966585,13 9.16550052,12.9591671 9.0605,12.8775 C8.95549947,12.7958329 8.8796669,12.6943339 8.833,12.573 L8.077,10.508 L3.884,10.508 L3.128,12.573 C3.09066648,12.6803339 3.01716722,12.7783329 2.9075,12.867 C2.79783279,12.9556671 2.66366746,13 2.505,13 L1.042,13 L5.018,2.878 L6.943,2.878 L10.919,13 Z M4.367,9.178 L7.594,9.178 L6.362,5.811 C6.30599972,5.66166592 6.24416701,5.48550102 6.1765,5.2825 C6.108833,5.07949898 6.04233366,4.85900119 5.977,4.621 C5.91166634,4.85900119 5.84750032,5.08066564 5.7845,5.286 C5.72149969,5.49133436 5.65966697,5.67099923 5.599,5.825 L4.367,9.178 Z M18.892,13 L18.115,13 C17.9516658,13 17.8233338,12.9755002 17.73,12.9265 C17.6366662,12.8774998 17.5666669,12.7783341 17.52,12.629 L17.366,12.118 C17.1839991,12.2813341 17.0055009,12.4248327 16.8305,12.5485 C16.6554991,12.6721673 16.4746676,12.7759996 16.288,12.86 C16.1013324,12.9440004 15.903001,13.0069998 15.693,13.049 C15.4829989,13.0910002 15.2496679,13.112 14.993,13.112 C14.6896651,13.112 14.4096679,13.0711671 14.153,12.9895 C13.896332,12.9078329 13.6758342,12.7853342 13.4915,12.622 C13.3071657,12.4586658 13.1636672,12.2556679 13.061,12.013 C12.9583328,11.7703321 12.907,11.4880016 12.907,11.166 C12.907,10.895332 12.9781659,10.628168 13.1205,10.3645 C13.262834,10.100832 13.499665,9.8628344 13.831,9.6505 C14.162335,9.43816561 14.6033306,9.2620007 15.154,9.122 C15.7046694,8.9819993 16.3883292,8.90266676 17.205,8.884 L17.205,8.464 C17.205,7.98333093 17.103501,7.62750116 16.9005,7.3965 C16.697499,7.16549885 16.4023352,7.05 16.015,7.05 C15.7349986,7.05 15.5016676,7.08266634 15.315,7.148 C15.1283324,7.21333366 14.9661673,7.28683292 14.8285,7.3685 C14.6908326,7.45016707 14.5636672,7.52366634 14.447,7.589 C14.3303327,7.65433366 14.2020007,7.687 14.062,7.687 C13.9453327,7.687 13.8450004,7.65666697 13.761,7.596 C13.6769996,7.53533303 13.6093336,7.46066711 13.558,7.372 L13.243,6.819 C14.0690041,6.06299622 15.0653275,5.685 16.232,5.685 C16.6520021,5.685 17.0264983,5.75383264 17.3555,5.8915 C17.6845016,6.02916736 17.9633322,6.22049877 18.192,6.4655 C18.4206678,6.71050122 18.5944994,7.00333163 18.7135,7.344 C18.8325006,7.68466837 18.892,8.05799797 18.892,8.464 L18.892,13 Z M15.532,11.922 C15.7093342,11.922 15.8726659,11.9056668 16.022,11.873 C16.1713341,11.8403332 16.3124993,11.7913337 16.4455,11.726 C16.5785006,11.6606663 16.7068327,11.5801671 16.8305,11.4845 C16.9541673,11.3888329 17.0789993,11.2756673 17.205,11.145 L17.205,9.934 C16.7009975,9.95733345 16.279835,10.0004997 15.9415,10.0635 C15.603165,10.1265003 15.3313343,10.2069995 15.126,10.305 C14.9206656,10.4030005 14.7748337,10.5173327 14.6885,10.648 C14.6021662,10.7786673 14.559,10.9209992 14.559,11.075 C14.559,11.3783349 14.6488324,11.5953327 14.8285,11.726 C15.0081675,11.8566673 15.2426652,11.922 15.532,11.922 L15.532,11.922 Z\"></path></svg>"
 
@@ -5038,16 +5038,20 @@ class Tree extends Component {
       onFocus: _propTypes2.default.func,
 
       // The depth to which we should automatically expand new items.
       autoExpandDepth: _propTypes2.default.number,
       // Should auto expand all new items or just the new items under the first
       // root item.
       autoExpandAll: _propTypes2.default.bool,
 
+      // Auto expand a node only if number of its children
+      // are less than autoExpandNodeChildrenLimit
+      autoExpandNodeChildrenLimit: _propTypes2.default.number,
+
       // Note: the two properties below are mutually exclusive. Only one of the
       // label properties is necessary.
       // ID of an element whose textual content serves as an accessible label
       // for a tree.
       labelledby: _propTypes2.default.string,
       // Accessibility label for a tree widget.
       label: _propTypes2.default.string,
 
@@ -5129,32 +5133,37 @@ class Tree extends Component {
     if (this.props.focused && prevProps.focused !== this.props.focused) {
       this._scrollNodeIntoView(this.props.focused);
       // Always keep the focus on the tree itself.
       this.treeRef.focus();
     }
   }
 
   _autoExpand() {
-    if (!this.props.autoExpandDepth) {
+    const { autoExpandDepth, autoExpandNodeChildrenLimit } = this.props;
+    if (!autoExpandDepth) {
       return;
     }
 
     // Automatically expand the first autoExpandDepth levels for new items. Do
     // not use the usual DFS infrastructure because we don't want to ignore
     // collapsed nodes.
     const autoExpand = (item, currentDepth) => {
-      if (currentDepth >= this.props.autoExpandDepth || this.state.seen.has(item)) {
+      if (currentDepth >= autoExpandDepth || this.state.seen.has(item)) {
+        return;
+      }
+
+      const children = this.props.getChildren(item);
+      if (autoExpandNodeChildrenLimit && children.length > autoExpandNodeChildrenLimit) {
         return;
       }
 
       this.props.onExpand(item);
       this.state.seen.add(item);
 
-      const children = this.props.getChildren(item);
       const length = children.length;
       for (let i = 0; i < length; i++) {
         autoExpand(children[i], currentDepth + 1);
       }
     };
 
     const roots = this.props.getRoots();
     const length = roots.length;
@@ -7053,17 +7062,17 @@ function formatKeyShortcut(shortcut) {
   return shortcut.replace(/CommandOrControl\+|CmdOrCtrl\+/g, "Ctrl").replace(/Shift\+/g, "Shift");
 }
 
 /***/ }),
 
 /***/ 3789:
 /***/ (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 version=\"1.1\" id=\"loader-1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\" viewBox=\"0 0 40 40\" enable-background=\"new 0 0 40 40\" xml:space=\"preserve\"><path opacity=\"0.2\" fill=\"#000\" d=\"M20.201,5.169c-8.254,0-14.946,6.692-14.946,14.946c0,8.255,6.692,14.946,14.946,14.946 s14.946-6.691,14.946-14.946C35.146,11.861,28.455,5.169,20.201,5.169z M20.201,31.749c-6.425,0-11.634-5.208-11.634-11.634 c0-6.425,5.209-11.634,11.634-11.634c6.425,0,11.633,5.209,11.633,11.634C31.834,26.541,26.626,31.749,20.201,31.749z\"></path><path fill=\"#000\" d=\"M26.013,10.047l1.654-2.866c-2.198-1.272-4.743-2.012-7.466-2.012h0v3.312h0 C22.32,8.481,24.301,9.057,26.013,10.047z\"><animateTransform attributeType=\"xml\" attributeName=\"transform\" type=\"rotate\" from=\"0 20 20\" to=\"360 20 20\" dur=\"0.5s\" repeatCount=\"indefinite\"></animateTransform></path></svg>"
+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 version=\"1.1\" id=\"loader-1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\" viewBox=\"0 0 40 40\" enable-background=\"new 0 0 40 40\" xml:space=\"preserve\"><path opacity=\"0.2\" fill=\"#000\" d=\"M20.201,5.169c-8.254,0-14.946,6.692-14.946,14.946c0,8.255,6.692,14.946,14.946,14.946 s14.946-6.691,14.946-14.946C35.146,11.861,28.455,5.169,20.201,5.169z M20.201,31.749c-6.425,0-11.634-5.208-11.634-11.634 c0-6.425,5.209-11.634,11.634-11.634c6.425,0,11.633,5.209,11.633,11.634C31.834,26.541,26.626,31.749,20.201,31.749z\"></path><path fill=\"#000\" d=\"M26.013,10.047l1.654-2.866c-2.198-1.272-4.743-2.012-7.466-2.012h0v3.312h0 C22.32,8.481,24.301,9.057,26.013,10.047z\"></path></svg>"
 
 /***/ }),
 
 /***/ 3791:
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
--- a/devtools/client/debugger/new/images/breakpoint.svg
+++ b/devtools/client/debugger/new/images/breakpoint.svg
@@ -1,6 +1,6 @@
 <!-- This Source Code Form is subject to the terms of the Mozilla Public
    - License, v. 2.0. If a copy of the MPL was not distributed with this
    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 60 12">
-  <path id="base-path" d="M53.9,0H1C0.4,0,0,0.4,0,1v10c0,0.6,0.4,1,1,1h52.9c0.6,0,1.2-0.3,1.5-0.7L60,6l-4.4-5.3C55,0.3,54.5,0,53.9,0z"/>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 60 14">
+  <path id="base-path" d="M53.07.5H1.5a1 1 0 0 0-1 1v11a1 1 0 0 0 1 1h51.57a2 2 0 0 0 1.53-.7L59.3 7l-4.7-5.8a2 2 0 0 0-1.53-.7z/>
 </svg>
--- a/devtools/client/debugger/new/src/actions/pause/mapFrames.js
+++ b/devtools/client/debugger/new/src/actions/pause/mapFrames.js
@@ -17,27 +17,28 @@ import { findClosestFunction } from "../
 
 import type { Frame } from "../../types";
 import type { State } from "../../reducers/types";
 import type { ThunkArgs } from "../types";
 import { features } from "../../utils/prefs";
 
 import { isGeneratedId } from "devtools-source-map";
 
+function isFrameBlackboxed(state, frame) {
+  const source = getSource(state, frame.location.sourceId);
+  return source && source.isBlackBoxed;
+}
+
 function getSelectedFrameId(state, frames) {
-  if (!features.originalBlackbox) {
-    const selectedFrame = getSelectedFrame(state);
-    return selectedFrame && selectedFrame.id;
+  let selectedFrame = getSelectedFrame(state);
+  if (selectedFrame && !isFrameBlackboxed(state, selectedFrame)) {
+    return selectedFrame.id;
   }
 
-  const selectedFrame = frames.find(frame => {
-    const source = getSource(state, frame.location.sourceId);
-    return source && !source.isBlackBoxed;
-  });
-
+  selectedFrame = frames.find(frame => !isFrameBlackboxed(state, frame));
   return selectedFrame && selectedFrame.id;
 }
 
 export function updateFrameLocation(frame: Frame, sourceMaps: any) {
   if (frame.isOriginal) {
     return Promise.resolve(frame);
   }
   return sourceMaps.getOriginalLocation(frame.location).then(loc => ({
--- a/devtools/client/debugger/new/src/actions/sources/blackbox.js
+++ b/devtools/client/debugger/new/src/actions/sources/blackbox.js
@@ -4,37 +4,41 @@
 
 // @flow
 
 /**
  * Redux actions for the sources state
  * @module actions/sources
  */
 
-import { isOriginalId } from "devtools-source-map";
+import { isOriginalId, originalToGeneratedId } from "devtools-source-map";
 import { recordEvent } from "../../utils/telemetry";
 import { features } from "../../utils/prefs";
 
 import { PROMISE } from "../utils/middleware/promise";
+
 import type { Source } from "../../types";
 import type { ThunkArgs } from "../types";
 
 export function toggleBlackBox(source: Source) {
   return async ({ dispatch, getState, client, sourceMaps }: ThunkArgs) => {
-    const { isBlackBoxed, id } = source;
+    const { isBlackBoxed } = source;
 
     if (!isBlackBoxed) {
       recordEvent("blackbox");
     }
 
     let promise;
-    if (features.originalBlackbox && isOriginalId(id)) {
-      promise = Promise.resolve({ isBlackBoxed: !isBlackBoxed });
+
+    if (features.originalBlackbox && isOriginalId(source.id)) {
+      const range = await sourceMaps.getFileGeneratedRange(source);
+      const generatedId = originalToGeneratedId(source.id);
+      promise = client.blackBox(generatedId, isBlackBoxed, range);
     } else {
-      promise = client.blackBox(id, isBlackBoxed);
+      promise = client.blackBox(source.id, isBlackBoxed);
     }
 
     return dispatch({
       type: "BLACKBOX",
       source,
       [PROMISE]: promise
     });
   };
--- a/devtools/client/debugger/new/src/client/chrome/create.js
+++ b/devtools/client/debugger/new/src/client/chrome/create.js
@@ -1,15 +1,15 @@
 /* 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/>. */
 
 // @flow
 
-import type { SourceLocation, LoadedObject } from "../../types";
+import type { ChromeFrame, SourceLocation, LoadedObject } from "../../types";
 import type { ServerLocation } from "./types";
 
 export function fromServerLocation(
   serverLocation?: ServerLocation
 ): ?SourceLocation {
   if (serverLocation) {
     return {
       sourceId: serverLocation.scriptId,
@@ -22,17 +22,17 @@ export function fromServerLocation(
 
 export function toServerLocation(location: SourceLocation): ServerLocation {
   return {
     scriptId: location.sourceId,
     lineNumber: location.line - 1
   };
 }
 
-export function createFrame(frame: any) {
+export function createFrame(frame: any): ChromeFrame {
   return {
     id: frame.callFrameId,
     displayName: frame.functionName,
     scopeChain: frame.scopeChain,
     generatedLocation: frame.location,
     location: fromServerLocation(frame.location)
   };
 }
--- a/devtools/client/debugger/new/src/client/firefox/commands.js
+++ b/devtools/client/debugger/new/src/client/firefox/commands.js
@@ -340,22 +340,26 @@ function pauseOnExceptions(
   );
 }
 
 function prettyPrint(sourceId: SourceId, indentSize: number): Promise<*> {
   const sourceClient = threadClient.source({ actor: sourceId });
   return sourceClient.prettyPrint(indentSize);
 }
 
-async function blackBox(sourceId: SourceId, isBlackBoxed: boolean): Promise<*> {
+async function blackBox(
+  sourceId: SourceId,
+  isBlackBoxed: boolean,
+  range?: Range
+): Promise<*> {
   const sourceClient = threadClient.source({ actor: sourceId });
   if (isBlackBoxed) {
-    await sourceClient.unblackBox(null);
+    await sourceClient.unblackBox(range);
   } else {
-    await sourceClient.blackBox(null);
+    await sourceClient.blackBox(range);
   }
 
   return { isBlackBoxed: !isBlackBoxed };
 }
 
 function disablePrettyPrint(sourceId: SourceId): Promise<*> {
   const sourceClient = threadClient.source({ actor: sourceId });
   return sourceClient.disablePrettyPrint();
--- a/devtools/client/debugger/new/src/components/Editor/EditorMenu.js
+++ b/devtools/client/debugger/new/src/components/Editor/EditorMenu.js
@@ -9,17 +9,23 @@ import { isOriginalId } from "devtools-s
 
 import { copyToTheClipboard } from "../../utils/clipboard";
 import { findFunctionText } from "../../utils/function";
 import { findClosestFunction } from "../../utils/ast";
 import {
   getSourceLocationFromMouseEvent,
   toSourceLine
 } from "../../utils/editor";
-import { isPretty, getRawSourceURL, shouldBlackbox } from "../../utils/source";
+import {
+  isPretty,
+  getRawSourceURL,
+  getFilename,
+  shouldBlackbox
+} from "../../utils/source";
+import { downloadFile } from "../../utils/utils";
 import {
   getContextMenu,
   getPrettySource,
   getSelectedLocation,
   getSelectedSource,
   getSymbols
 } from "../../selectors";
 
@@ -88,16 +94,18 @@ function getMenuItems(
   const jumpToMappedLocLabel = L10N.getFormatStr(
     "editor.jumpToMappedLocation1",
     isOriginal ? L10N.getStr("generated") : L10N.getStr("original")
   );
   const revealInTreeKey = L10N.getStr("sourceTabs.revealInTree.accesskey");
   const revealInTreeLabel = L10N.getStr("sourceTabs.revealInTree");
   const watchExpressionKey = L10N.getStr("expressions.accesskey");
   const watchExpressionLabel = L10N.getStr("expressions.label");
+  const downloadKey = L10N.getStr("downloadFile.accesskey");
+  const downloadLabel = L10N.getStr("downloadFile.label");
 
   // menu items
 
   const copyToClipboardItem = {
     id: "node-menu-copy-to-clipboard",
     label: copyToClipboardLabel,
     accesskey: copyToClipboardKey,
     disabled: false,
@@ -174,16 +182,23 @@ function getMenuItems(
   };
 
   const evaluateInConsoleItem = {
     id: "node-menu-evaluate-in-console",
     label: evaluateInConsoleLabel,
     click: () => evaluateInConsole(selectionText)
   };
 
+  const downloadFileItem = {
+    id: "node-menu-download-file",
+    label: downloadLabel,
+    accesskey: downloadKey,
+    click: () => downloadFile(selectedSource.text, getFilename(selectedSource))
+  };
+
   // construct menu
   const menuItems = [
     copyToClipboardItem,
     copySourceItem,
     copySourceUri2Item,
     copyFunctionItem,
     { type: "separator" },
     jumpToMappedLocationItem,
@@ -192,16 +207,18 @@ function getMenuItems(
   ];
 
   // conditionally added items
   // TODO: Find a new way to only add this for mapped sources?
   if (isTextSelected) {
     menuItems.push(watchExpressionItem, evaluateInConsoleItem);
   }
 
+  menuItems.push(downloadFileItem);
+
   return menuItems;
 }
 
 class EditorMenu extends Component {
   props: Props;
 
   shouldComponentUpdate(nextProps) {
     return nextProps.contextMenu.type === "Editor";
--- a/devtools/client/debugger/new/src/components/Editor/Footer.js
+++ b/devtools/client/debugger/new/src/components/Editor/Footer.js
@@ -243,22 +243,24 @@ class SourceFooter extends PureComponent
         {this.renderCursorPosition()}
       </div>
     );
   }
 }
 
 const mapStateToProps = state => {
   const selectedSource = getSelectedSource(state);
-  const selectedId = selectedSource.id;
 
   return {
     selectedSource,
     mappedSource: getGeneratedSource(state, selectedSource),
-    prettySource: getPrettySource(state, selectedId),
+    prettySource: getPrettySource(
+      state,
+      selectedSource ? selectedSource.id : null
+    ),
     endPanelCollapsed: getPaneCollapse(state, "end")
   };
 };
 
 export default connect(
   mapStateToProps,
   {
     togglePrettyPrint: actions.togglePrettyPrint,
--- a/devtools/client/debugger/new/src/components/PrimaryPanes/Outline.js
+++ b/devtools/client/debugger/new/src/components/PrimaryPanes/Outline.js
@@ -256,22 +256,29 @@ export class Outline extends Component<P
         </div>
       </div>
     );
   }
 }
 
 const mapStateToProps = state => {
   const selectedSource = getSelectedSource(state);
-  const symbols = getSymbols(state, selectedSource);
+  const symbols = selectedSource ? getSymbols(state, selectedSource) : null;
+
   return {
     symbols,
     selectedSource,
     selectedLocation: getSelectedLocation(state),
-    getFunctionText: line => findFunctionText(line, selectedSource, symbols)
+    getFunctionText: line => {
+      if (selectedSource) {
+        return findFunctionText(line, selectedSource, symbols);
+      }
+
+      return null;
+    }
   };
 };
 
 export default connect(
   mapStateToProps,
   {
     selectLocation: actions.selectLocation,
     flashLineRange: actions.flashLineRange
--- a/devtools/client/debugger/new/src/components/SecondaryPanes/Breakpoints/Breakpoint.js
+++ b/devtools/client/debugger/new/src/components/SecondaryPanes/Breakpoints/Breakpoint.js
@@ -170,17 +170,17 @@ class Breakpoint extends PureComponent<P
       </div>
     );
   }
 }
 
 const getFormattedFrame = createSelector(
   getSelectedSource,
   getSelectedFrame,
-  (selectedSource: Source, frame: Frame): ?FormattedFrame => {
+  (selectedSource: ?Source, frame: ?Frame): ?FormattedFrame => {
     if (!frame) {
       return null;
     }
 
     return {
       ...frame,
       selectedLocation: getSelectedLocation(frame, selectedSource)
     };
--- a/devtools/client/debugger/new/src/components/SecondaryPanes/CommandBar.js
+++ b/devtools/client/debugger/new/src/components/SecondaryPanes/CommandBar.js
@@ -266,17 +266,17 @@ class CommandBar extends Component<Props
       <button
         className={classnames(
           "command-bar-button",
           "command-bar-skip-pausing",
           {
             active: skipPausing
           }
         )}
-        title={L10N.getStr("skipPausingTooltip")}
+        title={L10N.getStr("skipPausingTooltip.label")}
         onClick={toggleSkipPausing}
       >
         <AccessibleImage className="skipPausing" />
       </button>
     );
   }
 
   render() {
--- a/devtools/client/debugger/new/src/reducers/ast.js
+++ b/devtools/client/debugger/new/src/reducers/ast.js
@@ -154,17 +154,17 @@ function update(
     }
   }
 }
 
 // NOTE: we'd like to have the app state fully typed
 // https://github.com/devtools-html/debugger.html/blob/master/src/reducers/sources.js#L179-L185
 type OuterState = { ast: Record<ASTState> };
 
-export function getSymbols(state: OuterState, source?: Source): ?Symbols {
+export function getSymbols(state: OuterState, source: ?Source): ?Symbols {
   if (!source) {
     return null;
   }
 
   return state.ast.symbols.get(source.id) || null;
 }
 
 export function hasSymbols(state: OuterState, source: Source): boolean {
@@ -172,17 +172,17 @@ export function hasSymbols(state: OuterS
 
   if (!symbols) {
     return false;
   }
 
   return !symbols.loading;
 }
 
-export function isSymbolsLoading(state: OuterState, source: Source): boolean {
+export function isSymbolsLoading(state: OuterState, source: ?Source): boolean {
   const symbols = getSymbols(state, source);
   if (!symbols) {
     return false;
   }
 
   return symbols.loading;
 }
 
--- a/devtools/client/debugger/new/src/reducers/expressions.js
+++ b/devtools/client/debugger/new/src/reducers/expressions.js
@@ -8,20 +8,21 @@
  * Expressions reducer
  * @module reducers/expressions
  */
 
 import makeRecord from "../utils/makeRecord";
 import { List, Map } from "immutable";
 import { omit, zip } from "lodash";
 
-import { createSelector } from "../utils/createSelector";
+import { createSelector } from "reselect";
 import { prefs } from "../utils/prefs";
 
 import type { Expression } from "../types";
+import type { Selector, State } from "../reducers/types";
 import type { Action } from "../actions/types";
 import type { Record } from "../utils/makeRecord";
 
 export type ExpressionState = {
   expressions: List<Expression>,
   expressionError: boolean,
   autocompleteMatches: Map<string, List<string>>,
   currentAutocompleteInput: string | null
@@ -153,45 +154,43 @@ function updateExpressionInList(
     return list.update(index, () => value);
   });
 
   storeExpressions(newState);
   return newState;
 }
 
 function deleteExpression(state: Record<ExpressionState>, input: string) {
-  const index = getExpressions({ expressions: state }).findIndex(
-    e => e.input == input
-  );
+  const index = state.expressions.findIndex(e => e.input == input);
   const newState = state.deleteIn(["expressions", index]);
   storeExpressions(newState);
   return newState;
 }
 
-type OuterState = { expressions: Record<ExpressionState> };
-
 const getExpressionsWrapper = state => state.expressions;
 
-export const getExpressions = createSelector(
+export const getExpressions: Selector<List<Expression>> = createSelector(
   getExpressionsWrapper,
   expressions => expressions.expressions
 );
 
-export const getAutocompleteMatches = createSelector(
+export const getAutocompleteMatches: Selector<
+  Map<string, List<string>>
+> = createSelector(
   getExpressionsWrapper,
   expressions => expressions.autocompleteMatches
 );
 
-export function getExpression(state: OuterState, input: string) {
+export function getExpression(state: State, input: string) {
   return getExpressions(state).find(exp => exp.input == input);
 }
 
-export function getAutocompleteMatchset(state: OuterState) {
+export function getAutocompleteMatchset(state: State) {
   const input = state.expressions.get("currentAutocompleteInput");
   return getAutocompleteMatches(state).get(input);
 }
 
-export const getExpressionError = createSelector(
+export const getExpressionError: Selector<boolean> = createSelector(
   getExpressionsWrapper,
   expressions => expressions.expressionError
 );
 
 export default update;
--- a/devtools/client/debugger/new/src/reducers/pause.js
+++ b/devtools/client/debugger/new/src/reducers/pause.js
@@ -5,25 +5,33 @@
 // @flow
 /* eslint complexity: ["error", 30]*/
 
 /**
  * Pause reducer
  * @module reducers/pause
  */
 
-import { createSelector } from "../utils/createSelector";
+import { createSelector } from "reselect";
 import { isGeneratedId } from "devtools-source-map";
 import { prefs } from "../utils/prefs";
 import { getSelectedSource } from "./sources";
 
 import type { OriginalScope } from "../utils/pause/mapScopes";
 import type { Action } from "../actions/types";
-import type { State } from "./types";
-import type { Why, Scope, SourceId, FrameId, MappedLocation } from "../types";
+import type { Selector, State } from "./types";
+import type {
+  Why,
+  Scope,
+  SourceId,
+  ChromeFrame,
+  Frame,
+  FrameId,
+  MappedLocation
+} from "../types";
 
 export type Command =
   | null
   | "stepOver"
   | "stepIn"
   | "stepOut"
   | "resume"
   | "rewind"
@@ -335,17 +343,17 @@ function getPauseLocation(state, action)
 // pick off the piece of state we're interested in. It's impossible
 // (right now) to type those wrapped functions.
 type OuterState = State;
 
 function getCurrentPauseState(state: OuterState): ThreadPauseState {
   return getThreadPauseState(state.pause, state.pause.currentThread);
 }
 
-export const getAllPopupObjectProperties = createSelector(
+export const getAllPopupObjectProperties: Selector<{}> = createSelector(
   getCurrentPauseState,
   pauseWrapper => pauseWrapper.loadedObjects
 );
 
 export function getPauseReason(state: OuterState): ?Why {
   return getCurrentPauseState(state).why;
 }
 
@@ -529,17 +537,17 @@ export function getSelectedFrameId(state
   return getCurrentPauseState(state).selectedFrameId;
 }
 
 export function getTopFrame(state: OuterState) {
   const frames = getFrames(state);
   return frames && frames[0];
 }
 
-export const getSelectedFrame = createSelector(
+export const getSelectedFrame: Selector<?Frame> = createSelector(
   getSelectedFrameId,
   getFrames,
   (selectedFrameId, frames) => {
     if (!frames) {
       return null;
     }
 
     return frames.find(frame => frame.id == selectedFrameId);
@@ -551,13 +559,13 @@ export function getDebuggeeUrl(state: Ou
 }
 
 export function getSkipPausing(state: OuterState) {
   return getCurrentPauseState(state).skipPausing;
 }
 
 // NOTE: currently only used for chrome
 export function getChromeScopes(state: OuterState) {
-  const frame = getSelectedFrame(state);
+  const frame: ?ChromeFrame = (getSelectedFrame(state): any);
   return frame ? frame.scopeChain : undefined;
 }
 
 export default update;
--- a/devtools/client/debugger/new/src/reducers/sources.js
+++ b/devtools/client/debugger/new/src/reducers/sources.js
@@ -4,29 +4,29 @@
 
 // @flow
 
 /**
  * Sources reducer
  * @module reducers/sources
  */
 
-import { createSelector } from "../utils/createSelector";
+import { createSelector } from "reselect";
 import {
   getPrettySourceURL,
   underRoot,
   getRelativeUrl,
   isGenerated,
   isOriginal as isOriginalSource
 } from "../utils/source";
 import { originalToGeneratedId } from "devtools-source-map";
 import { prefs } from "../utils/prefs";
 
 import type { Source, SourceId, SourceLocation } from "../types";
-import type { PendingSelectedLocation } from "./types";
+import type { PendingSelectedLocation, Selector } from "./types";
 import type { Action, DonePromiseAction } from "../actions/types";
 import type { LoadSourceAction } from "../actions/types/SourceAction";
 
 export type SourcesMap = { [string]: Source };
 
 type UrlsMap = { [string]: SourceId[] };
 
 export type SourcesState = {
@@ -340,29 +340,40 @@ export function getSourceByURL(state: Ou
 export function getSourcesByURLs(state: OuterState, urls: string[]) {
   return urls.map(url => getSourceByURL(state, url)).filter(Boolean);
 }
 
 export function getSourcesByURL(state: OuterState, url: string): Source[] {
   return getSourcesByUrlInSources(getSources(state), getUrls(state), url);
 }
 
-export function getGeneratedSource(state: OuterState, source: Source): Source {
+export function getGeneratedSource(
+  state: OuterState,
+  source: ?Source
+): ?Source {
+  if (!source) {
+    return null;
+  }
+
   if (isGenerated(source)) {
     return source;
   }
 
   return getSourceFromId(state, originalToGeneratedId(source.id));
 }
 
 export function getPendingSelectedLocation(state: OuterState) {
   return state.sources.pendingSelectedLocation;
 }
 
-export function getPrettySource(state: OuterState, id: string) {
+export function getPrettySource(state: OuterState, id: ?string) {
+  if (!id) {
+    return;
+  }
+
   const source = getSource(state, id);
   if (!source) {
     return;
   }
 
   return getSpecificSourceByURL(state, getPrettySourceURL(source.url), true);
 }
 
@@ -465,27 +476,27 @@ export function getSources(state: OuterS
 export function getUrls(state: OuterState) {
   return state.sources.urls;
 }
 
 export function getSourceList(state: OuterState): Source[] {
   return (Object.values(getSources(state)): any);
 }
 
-export const getSourceCount = createSelector(
+export const getSourceCount: Selector<number> = createSelector(
   getSources,
   sources => Object.keys(sources).length
 );
 
-export const getSelectedLocation = createSelector(
+export const getSelectedLocation: Selector<?SourceLocation> = createSelector(
   getSourcesState,
   sources => sources.selectedLocation
 );
 
-export const getSelectedSource = createSelector(
+export const getSelectedSource: Selector<?Source> = createSelector(
   getSelectedLocation,
   getSources,
   (selectedLocation: ?SourceLocation, sources: SourcesMap): ?Source => {
     if (!selectedLocation) {
       return;
     }
 
     return sources[selectedLocation.sourceId];
--- a/devtools/client/debugger/new/src/reducers/tabs.js
+++ b/devtools/client/debugger/new/src/reducers/tabs.js
@@ -4,32 +4,33 @@
 
 // @flow
 
 /**
  * Tabs reducer
  * @module reducers/tabs
  */
 
-import { createSelector } from "../utils/createSelector";
+import { createSelector } from "reselect";
 import { isOriginalId } from "devtools-source-map";
 import move from "lodash-move";
 
 import { asyncStore } from "../utils/prefs";
 import {
   getSource,
   getSources,
   getUrls,
   getSpecificSourceByURL,
   getSpecificSourceByUrlInSources
 } from "./sources";
 
 import type { Action } from "../actions/types";
 import type { SourcesState } from "./sources";
 import type { Source } from "../types";
+import type { Selector } from "./types";
 
 export type Tab = {
   url: string,
   framework?: string | null,
   isOriginal: boolean,
   sourceId?: string
 };
 export type TabList = Tab[];
@@ -189,25 +190,25 @@ export function getNewSelectedSourceId(
 // module for the UI, and all of those selectors should take the
 // top-level app state, so we'd have to "wrap" them to automatically
 // pick off the piece of state we're interested in. It's impossible
 // (right now) to type those wrapped functions.
 type OuterState = { tabs: TabList, sources: SourcesState };
 
 export const getTabs = (state: OuterState): TabList => state.tabs;
 
-export const getSourceTabs = createSelector(
+export const getSourceTabs: Selector<Tab[]> = createSelector(
   getTabs,
   getSources,
   getUrls,
   (tabs, sources, urls) =>
     tabs.filter(tab => getTabWithOrWithoutUrl(tab, sources, urls))
 );
 
-export const getSourcesForTabs = createSelector(
+export const getSourcesForTabs: Selector<Source[]> = createSelector(
   getSourceTabs,
   getSources,
   getUrls,
   (tabs, sources, urls) =>
     tabs.map(tab => getTabWithOrWithoutUrl(tab, sources, urls)).filter(Boolean)
 );
 
 function getTabWithOrWithoutUrl(tab, sources, urls) {
--- a/devtools/client/debugger/new/src/selectors/breakpointSources.js
+++ b/devtools/client/debugger/new/src/selectors/breakpointSources.js
@@ -1,48 +1,48 @@
 /* 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/>. */
 
 // @flow
 
 import { sortBy, uniq } from "lodash";
-import { createSelector } from "../utils/createSelector";
+import { createSelector } from "reselect";
 import {
   getSources,
   getBreakpointsList,
   getSelectedSource
 } from "../selectors";
 import { isGenerated, getFilename } from "../utils/source";
 import { getSelectedLocation } from "../utils/source-maps";
 
 import type {
   Source,
   Breakpoint,
   BreakpointId,
   SourceLocation
 } from "../types";
-import type { SourcesMap } from "../reducers/types";
+import type { Selector, SourcesMap } from "../reducers/types";
 
 export type BreakpointSources = Array<{
   source: Source,
   breakpoints: FormattedBreakpoint[]
 }>;
 
 export type FormattedBreakpoint = {|
   id: BreakpointId,
   condition: ?string,
   disabled: boolean,
   text: string,
   selectedLocation: SourceLocation
 |};
 
 function formatBreakpoint(
   breakpoint: Breakpoint,
-  selectedSource: Source
+  selectedSource: ?Source
 ): FormattedBreakpoint {
   const { id, condition, disabled } = breakpoint;
 
   return {
     id,
     condition,
     disabled,
     text:
@@ -50,51 +50,50 @@ function formatBreakpoint(
         ? breakpoint.text
         : breakpoint.originalText,
     selectedLocation: getSelectedLocation(breakpoint, selectedSource)
   };
 }
 
 function getBreakpointsForSource(
   source: Source,
-  selectedSource: Source,
+  selectedSource: ?Source,
   breakpoints: Breakpoint[]
 ) {
   return breakpoints
     .sort((a, b) => a.location.line - b.location.line)
     .filter(
       bp =>
         !bp.hidden &&
         !bp.loading &&
         (bp.text || bp.originalText || bp.condition || bp.disabled)
     )
     .map(bp => formatBreakpoint(bp, selectedSource))
     .filter(bp => bp.selectedLocation.sourceId == source.id);
 }
 
 function findBreakpointSources(
   sources: SourcesMap,
-  selectedSource: Source,
   breakpoints: Breakpoint[]
 ): Source[] {
   const sourceIds: string[] = uniq(breakpoints.map(bp => bp.location.sourceId));
 
   const breakpointSources = sourceIds
     .map(id => sources[id])
     .filter(source => source && !source.isBlackBoxed);
 
   return sortBy(breakpointSources, (source: Source) => getFilename(source));
 }
 
-export const getBreakpointSources = createSelector(
+export const getBreakpointSources: Selector<BreakpointSources> = createSelector(
   getBreakpointsList,
   getSources,
   getSelectedSource,
-  (breakpoints: Breakpoint[], sources: SourcesMap, selectedSource: Source) =>
-    findBreakpointSources(sources, selectedSource, breakpoints)
+  (breakpoints: Breakpoint[], sources: SourcesMap, selectedSource: ?Source) =>
+    findBreakpointSources(sources, breakpoints)
       .map(source => ({
         source,
         breakpoints: getBreakpointsForSource(
           source,
           selectedSource,
           breakpoints
         )
       }))
--- a/devtools/client/debugger/new/src/selectors/breakpoints.js
+++ b/devtools/client/debugger/new/src/selectors/breakpoints.js
@@ -1,28 +1,29 @@
 /* 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/>. */
 
 // @flow
 
-import { createSelector } from "../utils/createSelector";
+import { createSelector } from "reselect";
 
 import type {
   BreakpointsState,
   XHRBreakpointsList
 } from "../reducers/breakpoints";
+import type { Selector } from "../reducers/types";
 
 type OuterState = { breakpoints: BreakpointsState };
 
 export function getXHRBreakpoints(state: OuterState): XHRBreakpointsList {
   return state.breakpoints.xhrBreakpoints;
 }
 
-export const shouldPauseOnAnyXHR = createSelector(
+export const shouldPauseOnAnyXHR: Selector<boolean> = createSelector(
   getXHRBreakpoints,
   xhrBreakpoints => {
     const emptyBp = xhrBreakpoints.find(({ path }) => path.length === 0);
     if (!emptyBp) {
       return false;
     }
 
     return !emptyBp.disabled;
--- a/devtools/client/debugger/new/src/selectors/getCallStackFrames.js
+++ b/devtools/client/debugger/new/src/selectors/getCallStackFrames.js
@@ -8,17 +8,17 @@ import {
   getSourceInSources
 } from "../reducers/sources";
 import { getFrames } from "../reducers/pause";
 import { annotateFrames } from "../utils/pause/frames";
 import { isOriginal } from "../utils/source";
 import { get } from "lodash";
 import type { Frame, Source } from "../types";
 import type { SourcesMap } from "../reducers/sources";
-import { createSelector } from "../utils/createSelector";
+import { createSelector } from "reselect";
 
 function getLocation(frame, isGeneratedSource) {
   return isGeneratedSource
     ? frame.generatedLocation || frame.location
     : frame.location;
 }
 
 function getSourceForFrame(sources, frame, isGeneratedSource) {
--- a/devtools/client/debugger/new/src/selectors/visibleBreakpoints.js
+++ b/devtools/client/debugger/new/src/selectors/visibleBreakpoints.js
@@ -1,25 +1,26 @@
 /* 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/>. */
 
 // @flow
 
 import { isGeneratedId } from "devtools-source-map";
-import { createSelector } from "../utils/createSelector";
+import { createSelector } from "reselect";
 import { uniqBy } from "lodash";
 
 import { getBreakpointsList } from "../reducers/breakpoints";
 import { getSelectedSource } from "../reducers/sources";
 
 import memoize from "../utils/memoize";
 import { sortBreakpoints } from "../utils/breakpoint";
 
 import type { Breakpoint, Source } from "../types";
+import type { Selector } from "../reducers/types";
 
 function getLocation(breakpoint, isGeneratedSource) {
   return isGeneratedSource
     ? breakpoint.generatedLocation || breakpoint.location
     : breakpoint.location;
 }
 
 const formatBreakpoint = memoize(function(breakpoint, selectedSource) {
@@ -31,46 +32,49 @@ const formatBreakpoint = memoize(functio
     location: getLocation(breakpoint, isGeneratedSource),
     condition,
     loading,
     disabled,
     hidden
   };
 });
 
-function isVisible(breakpoint, selectedSource) {
+function isVisible(breakpoint: Breakpoint, selectedSource: Source) {
   const sourceId = selectedSource.id;
   const isGeneratedSource = isGeneratedId(sourceId);
 
   const location = getLocation(breakpoint, isGeneratedSource);
   return location.sourceId === sourceId;
 }
 
 /*
  * Finds the breakpoints, which appear in the selected source.
  */
-export const getVisibleBreakpoints = createSelector(
+export const getVisibleBreakpoints: Selector<?(Breakpoint[])> = createSelector(
   getSelectedSource,
   getBreakpointsList,
-  (selectedSource: Source, breakpoints: Breakpoint[]) => {
-    if (!selectedSource) {
+  (selectedSource: ?Source, breakpoints: Breakpoint[]) => {
+    if (selectedSource == null) {
       return null;
     }
 
+    // FIXME: Even though selectedSource is checked above, it fails type
+    // checking for isVisible
+    const source: Source = selectedSource;
+
     return breakpoints
-      .filter(bp => isVisible(bp, selectedSource))
+      .filter(bp => isVisible(bp, source))
       .map(bp => formatBreakpoint(bp, selectedSource));
   }
 );
 
 /*
  * Finds the first breakpoint per line, which appear in the selected source.
  */
-export const getFirstVisibleBreakpoints = createSelector(
-  getVisibleBreakpoints,
-  breakpoints => {
-    if (!breakpoints) {
-      return null;
-    }
+export const getFirstVisibleBreakpoints: Selector<
+  Breakpoint[]
+> = createSelector(getVisibleBreakpoints, breakpoints => {
+  if (!breakpoints) {
+    return [];
+  }
 
-    return uniqBy(sortBreakpoints(breakpoints), bp => bp.location.line);
-  }
-);
+  return (uniqBy(sortBreakpoints(breakpoints), bp => bp.location.line): any);
+});
--- a/devtools/client/debugger/new/src/selectors/visibleColumnBreakpoints.js
+++ b/devtools/client/debugger/new/src/selectors/visibleColumnBreakpoints.js
@@ -1,14 +1,14 @@
 /* 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/>. */
 
 import { groupBy, get, sortedUniqBy } from "lodash";
-import { createSelector } from "../utils/createSelector";
+import { createSelector } from "reselect";
 
 import { getViewport } from "../selectors";
 import { getVisibleBreakpoints } from "./visibleBreakpoints";
 import { getVisiblePausePoints } from "./visiblePausePoints";
 import { makeLocationId } from "../utils/breakpoint";
 
 import type { SourceLocation } from "../types";
 
--- a/devtools/client/debugger/new/src/selectors/visibleSelectedFrame.js
+++ b/devtools/client/debugger/new/src/selectors/visibleSelectedFrame.js
@@ -2,31 +2,35 @@
  * 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/>. */
 
 // @flow
 
 import { getSelectedLocation } from "../reducers/sources";
 import { getSelectedFrame } from "../reducers/pause";
 import { isOriginalId } from "devtools-source-map";
-import { createSelector } from "../utils/createSelector";
+import { createSelector } from "reselect";
 
 import type { Frame, SourceLocation } from "../types";
+import type { Selector } from "../reducers/types";
 
-function getLocation(frame: Frame, location?: SourceLocation) {
+function getLocation(frame: Frame, location: ?SourceLocation) {
   if (!location) {
     return frame.location;
   }
 
   return !isOriginalId(location.sourceId)
     ? frame.generatedLocation || frame.location
     : frame.location;
 }
 
-export const getVisibleSelectedFrame = createSelector(
+export const getVisibleSelectedFrame: Selector<?{
+  id: string,
+  location: SourceLocation
+}> = createSelector(
   getSelectedLocation,
   getSelectedFrame,
   (selectedLocation, selectedFrame) => {
     if (!selectedFrame) {
       return null;
     }
 
     const { id } = selectedFrame;
--- a/devtools/client/debugger/new/src/utils/moz.build
+++ b/devtools/client/debugger/new/src/utils/moz.build
@@ -13,17 +13,16 @@ DIRS += [
 DebuggerModules(
     'assert.js',
     'ast.js',
     'asyncStoreHelper.js',
     'bootstrap.js',
     'build-query.js',
     'clipboard.js',
     'connect.js',
-    'createSelector.js',
     'dbg.js',
     'defer.js',
     'DevToolsUtils.js',
     'expressions.js',
     'fromJS.js',
     'function.js',
     'indentation.js',
     'isMinified.js',
--- a/devtools/client/debugger/new/src/utils/prefs.js
+++ b/devtools/client/debugger/new/src/utils/prefs.js
@@ -56,17 +56,17 @@ if (isDevelopment()) {
   pref("devtools.debugger.features.column-breakpoints", false);
   pref("devtools.debugger.features.pause-points", true);
   pref("devtools.debugger.features.skip-pausing", true);
   pref("devtools.debugger.features.component-pane", false);
   pref("devtools.debugger.features.autocomplete-expressions", false);
   pref("devtools.debugger.features.map-expression-bindings", true);
   pref("devtools.debugger.features.map-await-expression", true);
   pref("devtools.debugger.features.xhr-breakpoints", true);
-  pref("devtools.debugger.features.origial-blackbox", false);
+  pref("devtools.debugger.features.origial-blackbox", true);
   pref("devtools.debugger.features.windowless-workers", false);
 }
 
 export const prefs = new PrefsHelper("devtools", {
   logging: ["Bool", "debugger.alphabetize-outline"],
   alphabetizeOutline: ["Bool", "debugger.alphabetize-outline"],
   autoPrettyPrint: ["Bool", "debugger.auto-pretty-print"],
   clientSourceMapsEnabled: ["Bool", "source-map.client-service.enabled"],
--- a/devtools/client/debugger/new/src/utils/source.js
+++ b/devtools/client/debugger/new/src/utils/source.js
@@ -260,16 +260,17 @@ const contentTypeModeMap = {
   "text/coffeescript": { name: "coffeescript" },
   "text/typescript-jsx": {
     name: "jsx",
     base: { name: "javascript", typescript: true }
   },
   "text/jsx": { name: "jsx" },
   "text/x-elm": { name: "elm" },
   "text/x-clojure": { name: "clojure" },
+  "text/x-clojurescript": { name: "clojure" },
   "text/wasm": { name: "text" },
   "text/html": { name: "htmlmixed" }
 };
 
 export function getSourcePath(url: string) {
   if (!url) {
     return "";
   }
--- a/devtools/client/debugger/new/src/utils/utils.js
+++ b/devtools/client/debugger/new/src/utils/utils.js
@@ -47,8 +47,25 @@ export function endTruncateStr(str: any,
     return `…${str.slice(str.length - size)}`;
   }
   return str;
 }
 
 export function waitForMs(ms: number): Promise<void> {
   return new Promise(resolve => setTimeout(resolve, ms));
 }
+
+export function downloadFile(data: string, fileName: string) {
+  const { body } = document;
+  if (!body) {
+    return;
+  }
+
+  const a = document.createElement("a");
+  body.appendChild(a);
+  a.className = "download-anchor";
+  a.href = window.URL.createObjectURL(
+    new Blob([data], { type: "text/javascript" })
+  );
+  a.setAttribute("download", fileName);
+  a.click();
+  body.removeChild(a);
+}
--- a/devtools/client/debugger/new/test/mochitest/browser.ini
+++ b/devtools/client/debugger/new/test/mochitest/browser.ini
@@ -735,16 +735,17 @@ skip-if = os == "win"
 skip-if = true
 [browser_dbg-pause-points.js]
 [browser_dbg-scopes-mutations.js]
 [browser_dbg-search-file.js]
 skip-if = os == "win" # Bug 1393121
 [browser_dbg-quick-open.js]
 skip-if = os == "win"
 [browser_dbg-search-project.js]
+[browser_dbg-blackbox-original.js]
 [browser_dbg-sourcemaps.js]
 [browser_dbg-sourcemaps-disabled.js]
 [browser_dbg-sourcemaps-reload.js]
 skip-if = os == "win" || (verify) # Bug 1434792
 [browser_dbg-sourcemaps-reloading.js]
 [browser_dbg-sourcemaps2.js]
 [browser_dbg-sourcemaps3.js]
 [browser_dbg-sourcemaps-bogus.js]
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-blackbox-original.js
@@ -0,0 +1,42 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// This source map does not have source contents, so it's fetched separately
+add_task(async function() {
+  // NOTE: the CORS call makes the test run times inconsistent
+  await pushPref("devtools.debugger.features.map-scopes", true);
+
+  const dbg = await initDebugger("doc-sourcemaps3.html");
+  const {
+    selectors: { getBreakpoint, getBreakpointCount },
+    getState
+  } = dbg;
+
+  await waitForSources(dbg, "bundle.js", "sorted.js", "test.js");
+
+  const sortedSrc = findSource(dbg, "sorted.js");
+
+  await selectSource(dbg, sortedSrc);
+
+  await clickElement(dbg, "blackbox");
+  await waitForDispatch(dbg, "BLACKBOX");
+
+  // breakpoint at line 38 in sorted
+  await addBreakpoint(dbg, sortedSrc, 38);
+  // invoke test
+  invokeInTab("test");
+  // should not pause
+  is(isPaused(dbg), false);
+
+
+  // unblackbox
+  await clickElement(dbg, "blackbox");
+  await waitForDispatch(dbg, "BLACKBOX");
+
+  // click on test
+  invokeInTab("test");
+  // should pause
+  await waitForPaused(dbg);
+
+  ok(true, "blackbox works")
+});
--- a/devtools/client/debugger/new/test/mochitest/helpers.js
+++ b/devtools/client/debugger/new/test/mochitest/helpers.js
@@ -1131,17 +1131,18 @@ const selectors = {
   fileMatch: ".project-text-search .line-value",
   popup: ".popover",
   tooltip: ".tooltip",
   previewPopup: ".preview-popup",
   outlineItem: i =>
     `.outline-list__element:nth-child(${i}) .function-signature`,
   outlineItems: ".outline-list__element",
   conditionalPanelInput: ".conditional-breakpoint-panel input",
-  searchField: ".search-field"
+  searchField: ".search-field",
+  blackbox: ".action.black-box"
 };
 
 function getSelector(elementName, ...args) {
   let selector = selectors[elementName];
   if (!selector) {
     throw new Error(`The selector ${elementName} is not defined`);
   }
 
--- a/devtools/client/locales/en-US/debugger.properties
+++ b/devtools/client/locales/en-US/debugger.properties
@@ -77,19 +77,19 @@ stepOverTooltip=Step over %S
 # LOCALIZATION NOTE (stepInTooltip): The label that is displayed on the
 # button that steps into a function call.
 stepInTooltip=Step in %S
 
 # LOCALIZATION NOTE (stepOutTooltip): The label that is displayed on the
 # button that steps out of a function call.
 stepOutTooltip=Step out %S
 
-# LOCALIZATION NOTE (skipPausingTooltip): The tooltip text for disabling all
+# LOCALIZATION NOTE (skipPausingTooltip.label): The tooltip text for disabling all
 # breakpoints and pausing triggers
-skipPausingTooltip=Skip all pausing
+skipPausingTooltip.label=Deactivate breakpoints
 
 # LOCALIZATION NOTE (pauseButtonItem): The label that is displayed for the dropdown pause
 # list item when the debugger is in a running state.
 pauseButtonItem=Pause on Next Statement
 
 # LOCALIZATION NOTE (ignoreExceptionsItem): The pause on exceptions button description
 # when the debugger will not pause on exceptions.
 ignoreExceptionsItem=Ignore exceptions
@@ -505,16 +505,21 @@ editor.conditionalPanel.placeholder=This
 # close button inside ConditionalPanel component
 editor.conditionalPanel.close=Cancel edit breakpoint and close
 
 # LOCALIZATION NOTE (editor.jumpToMappedLocation1): Context menu item
 # for navigating to a source mapped location
 editor.jumpToMappedLocation1=Jump to %S location
 editor.jumpToMappedLocation1.accesskey=m
 
+# LOCALIZATION NOTE (downloadFile.label): Context menu item
+# for downloading a source's content
+downloadFile.label=Download file
+downloadFile.accesskey=d
+
 # LOCALIZATION NOTE (framework.disableGrouping): This is the text that appears in the
 # context menu to disable framework grouping.
 framework.disableGrouping=Disable framework grouping
 framework.disableGrouping.accesskey=u
 
 # LOCALIZATION NOTE (framework.enableGrouping): This is the text that appears in the
 # context menu to enable framework grouping.
 framework.enableGrouping=Enable framework grouping
--- a/devtools/client/preferences/debugger.js
+++ b/devtools/client/preferences/debugger.js
@@ -62,10 +62,10 @@ pref("devtools.debugger.features.code-fo
 pref("devtools.debugger.features.outline", true);
 pref("devtools.debugger.features.pause-points", true);
 pref("devtools.debugger.features.component-pane", false);
 pref("devtools.debugger.features.async-stepping", true);
 pref("devtools.debugger.features.skip-pausing", true);
 pref("devtools.debugger.features.autocomplete-expressions", false);
 pref("devtools.debugger.features.map-expression-bindings", true);
 pref("devtools.debugger.features.xhr-breakpoints", true);
-pref("devtools.debugger.features.origial-blackbox", false);
+pref("devtools.debugger.features.origial-blackbox", true);
 pref("devtools.debugger.features.windowless-workers", false);
--- a/devtools/client/shared/components/reps/reps.js
+++ b/devtools/client/shared/components/reps/reps.js
@@ -4098,16 +4098,20 @@ class Tree extends Component {
       onFocus: _propTypes2.default.func,
 
       // The depth to which we should automatically expand new items.
       autoExpandDepth: _propTypes2.default.number,
       // Should auto expand all new items or just the new items under the first
       // root item.
       autoExpandAll: _propTypes2.default.bool,
 
+      // Auto expand a node only if number of its children
+      // are less than autoExpandNodeChildrenLimit
+      autoExpandNodeChildrenLimit: _propTypes2.default.number,
+
       // Note: the two properties below are mutually exclusive. Only one of the
       // label properties is necessary.
       // ID of an element whose textual content serves as an accessible label
       // for a tree.
       labelledby: _propTypes2.default.string,
       // Accessibility label for a tree widget.
       label: _propTypes2.default.string,
 
@@ -4189,32 +4193,37 @@ class Tree extends Component {
     if (this.props.focused && prevProps.focused !== this.props.focused) {
       this._scrollNodeIntoView(this.props.focused);
       // Always keep the focus on the tree itself.
       this.treeRef.focus();
     }
   }
 
   _autoExpand() {
-    if (!this.props.autoExpandDepth) {
+    const { autoExpandDepth, autoExpandNodeChildrenLimit } = this.props;
+    if (!autoExpandDepth) {
       return;
     }
 
     // Automatically expand the first autoExpandDepth levels for new items. Do
     // not use the usual DFS infrastructure because we don't want to ignore
     // collapsed nodes.
     const autoExpand = (item, currentDepth) => {
-      if (currentDepth >= this.props.autoExpandDepth || this.state.seen.has(item)) {
+      if (currentDepth >= autoExpandDepth || this.state.seen.has(item)) {
+        return;
+      }
+
+      const children = this.props.getChildren(item);
+      if (autoExpandNodeChildrenLimit && children.length > autoExpandNodeChildrenLimit) {
         return;
       }
 
       this.props.onExpand(item);
       this.state.seen.add(item);
 
-      const children = this.props.getChildren(item);
       const length = children.length;
       for (let i = 0; i < length; i++) {
         autoExpand(children[i], currentDepth + 1);
       }
     };
 
     const roots = this.props.getRoots();
     const length = roots.length;
--- a/devtools/client/shared/source-map/index.js
+++ b/devtools/client/shared/source-map/index.js
@@ -444,16 +444,17 @@ const getGeneratedRanges = dispatcher.ta
 });
 const getGeneratedLocation = dispatcher.task("getGeneratedLocation", {
   queue: true
 });
 const getAllGeneratedLocations = dispatcher.task("getAllGeneratedLocations", {
   queue: true
 });
 const getOriginalLocation = dispatcher.task("getOriginalLocation");
+const getFileGeneratedRange = dispatcher.task("getFileGeneratedRange");
 const getLocationScopes = dispatcher.task("getLocationScopes");
 const getOriginalSourceText = dispatcher.task("getOriginalSourceText");
 const applySourceMap = dispatcher.task("applySourceMap");
 const clearSourceMaps = dispatcher.task("clearSourceMaps");
 const hasMappedSource = dispatcher.task("hasMappedSource");
 const getOriginalStackFrames = dispatcher.task("getOriginalStackFrames");
 
 module.exports = {
@@ -463,16 +464,17 @@ module.exports = {
   isOriginalId,
   hasMappedSource,
   getOriginalURLs,
   getOriginalRanges,
   getGeneratedRanges,
   getGeneratedLocation,
   getAllGeneratedLocations,
   getOriginalLocation,
+  getFileGeneratedRange,
   getLocationScopes,
   getOriginalSourceText,
   applySourceMap,
   clearSourceMaps,
   getOriginalStackFrames,
   startSourceMapWorker(url, assetRoot) {
     dispatcher.start(url);
     setAssetRootURL(assetRoot);
@@ -547,17 +549,18 @@ const contentMap = {
   jsm: "text/javascript",
   mjs: "text/javascript",
   ts: "text/typescript",
   tsx: "text/typescript-jsx",
   jsx: "text/jsx",
   vue: "text/vue",
   coffee: "text/coffeescript",
   elm: "text/elm",
-  cljs: "text/x-clojure"
+  cljc: "text/x-clojure",
+  cljs: "text/x-clojurescript"
 };
 
 /**
  * Returns the content type for the specified URL.  If no specific
  * content type can be determined, "text/plain" is returned.
  *
  * @return String
  *         The content type.
--- a/devtools/client/shared/source-map/worker.js
+++ b/devtools/client/shared/source-map/worker.js
@@ -478,17 +478,18 @@ const contentMap = {
   jsm: "text/javascript",
   mjs: "text/javascript",
   ts: "text/typescript",
   tsx: "text/typescript-jsx",
   jsx: "text/jsx",
   vue: "text/vue",
   coffee: "text/coffeescript",
   elm: "text/elm",
-  cljs: "text/x-clojure"
+  cljc: "text/x-clojure",
+  cljs: "text/x-clojurescript"
 };
 
 /**
  * Returns the content type for the specified URL.  If no specific
  * content type can be determined, "text/plain" is returned.
  *
  * @return String
  *         The content type.
@@ -1871,16 +1872,17 @@ exports.ArraySet = ArraySet;
 const {
   getOriginalURLs,
   getOriginalRanges,
   getGeneratedRanges,
   getGeneratedLocation,
   getAllGeneratedLocations,
   getOriginalLocation,
   getOriginalSourceText,
+  getFileGeneratedRange,
   hasMappedSource,
   clearSourceMaps,
   applySourceMap
 } = __webpack_require__(3710);
 
 const { getOriginalStackFrames } = __webpack_require__(3783);
 const { setAssetRootURL } = __webpack_require__(3794);
 
@@ -1895,16 +1897,17 @@ self.onmessage = workerHandler({
   getOriginalURLs,
   getOriginalRanges,
   getGeneratedRanges,
   getGeneratedLocation,
   getAllGeneratedLocations,
   getOriginalLocation,
   getOriginalSourceText,
   getOriginalStackFrames,
+  getFileGeneratedRange,
   hasMappedSource,
   applySourceMap,
   clearSourceMaps
 });
 
 /***/ }),
 
 /***/ 3710:
@@ -2182,16 +2185,44 @@ async function getOriginalSourceText(ori
   }
 
   return {
     text,
     contentType: getContentType(originalSource.url || "")
   };
 }
 
+async function getFileGeneratedRange(originalSource) {
+  assert(isOriginalId(originalSource.id), "Source is not an original source");
+
+  const map = await getSourceMap(originalToGeneratedId(originalSource.id));
+  if (!map) {
+    return;
+  }
+
+  const start = map.generatedPositionFor({
+    source: originalSource.url,
+    line: 1,
+    column: 0,
+    bias: SourceMapConsumer.LEAST_UPPER_BOUND
+  });
+
+  const end = map.generatedPositionFor({
+    source: originalSource.url,
+    line: Number.MAX_SAFE_INTEGER,
+    column: Number.MAX_SAFE_INTEGER,
+    bias: SourceMapConsumer.GREATEST_LOWER_BOUND
+  });
+
+  return {
+    start,
+    end
+  };
+}
+
 async function hasMappedSource(location) {
   if (isOriginalId(location.sourceId)) {
     return true;
   }
 
   const loc = await getOriginalLocation(location);
   return loc.sourceId !== location.sourceId;
 }
@@ -2213,16 +2244,17 @@ function clearSourceMaps() {
 module.exports = {
   getOriginalURLs,
   getOriginalRanges,
   getGeneratedRanges,
   getGeneratedLocation,
   getAllGeneratedLocations,
   getOriginalLocation,
   getOriginalSourceText,
+  getFileGeneratedRange,
   applySourceMap,
   clearSourceMaps,
   hasMappedSource
 };
 
 /***/ }),
 
 /***/ 3711:
--- a/devtools/server/actors/thread.js
+++ b/devtools/server/actors/thread.js
@@ -1230,20 +1230,20 @@ const ThreadActor = ActorClassWithSpec(t
         actor.onRelease();
       } else if (actor.destroy) {
         actor.destroy();
       }
     }
     return res ? res : {};
   },
 
-  onSources: function(request) {
-    for (const source of this.dbg.findSources()) {
+  onSources: async function(request) {
+    await Promise.all(this.dbg.findSources().map(source => {
       this.sources.createSourceActor(source);
-    }
+    }));
 
     // No need to flush the new source packets here, as we are sending the
     // list of sources out immediately and we don't need to invoke the
     // overhead of an RDP packet for every source right now. Let the default
     // timeout flush the buffered packets.
 
     return {
       sources: this.sources.iter().map(s => s.form()),
--- a/dom/smil/SMILBoolType.cpp
+++ b/dom/smil/SMILBoolType.cpp
@@ -15,17 +15,17 @@ void SMILBoolType::Init(nsSMILValue& aVa
   MOZ_ASSERT(aValue.IsNull(), "Unexpected value type");
   aValue.mU.mBool = false;
   aValue.mType = this;
 }
 
 void SMILBoolType::Destroy(nsSMILValue& aValue) const {
   MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value");
   aValue.mU.mBool = false;
-  aValue.mType = nsSMILNullType::Singleton();
+  aValue.mType = SMILNullType::Singleton();
 }
 
 nsresult SMILBoolType::Assign(nsSMILValue& aDest,
                               const nsSMILValue& aSrc) const {
   MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types");
   MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value");
   aDest.mU.mBool = aSrc.mU.mBool;
   return NS_OK;
rename from dom/smil/nsSMILCSSValueType.cpp
rename to dom/smil/SMILCSSValueType.cpp
--- a/dom/smil/nsSMILCSSValueType.cpp
+++ b/dom/smil/SMILCSSValueType.cpp
@@ -1,17 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* representation of a value for a SMIL-animated CSS property */
 
-#include "nsSMILCSSValueType.h"
+#include "SMILCSSValueType.h"
 
 #include "nsComputedDOMStyle.h"
 #include "nsString.h"
 #include "nsSMILParserUtils.h"
 #include "nsSMILValue.h"
 #include "nsCSSProps.h"
 #include "nsCSSValue.h"
 #include "nsColor.h"
@@ -22,22 +22,23 @@
 #include "mozilla/ServoCSSParser.h"
 #include "mozilla/ServoStyleSet.h"
 #include "mozilla/dom/BaseKeyframeTypesBinding.h"  // For CompositeOperation
 #include "mozilla/dom/Element.h"
 #include "nsDebug.h"
 #include "nsStyleUtil.h"
 #include "nsIDocument.h"
 
-using namespace mozilla;
 using namespace mozilla::dom;
 
+namespace mozilla {
+
 typedef AutoTArray<RefPtr<RawServoAnimationValue>, 1> ServoAnimationValues;
 
-/*static*/ nsSMILCSSValueType nsSMILCSSValueType::sSingleton;
+/*static*/ SMILCSSValueType SMILCSSValueType::sSingleton;
 
 struct ValueWrapper {
   ValueWrapper(nsCSSPropertyID aPropID, const AnimationValue& aValue)
       : mPropID(aPropID) {
     MOZ_ASSERT(!aValue.IsNull());
     mServoValues.AppendElement(aValue.mServo);
   }
   ValueWrapper(nsCSSPropertyID aPropID,
@@ -113,31 +114,31 @@ static ValueWrapper* ExtractValueWrapper
 }
 
 static const ValueWrapper* ExtractValueWrapper(const nsSMILValue& aValue) {
   return static_cast<const ValueWrapper*>(aValue.mU.mPtr);
 }
 
 // Class methods
 // -------------
-void nsSMILCSSValueType::Init(nsSMILValue& aValue) const {
+void SMILCSSValueType::Init(nsSMILValue& aValue) const {
   MOZ_ASSERT(aValue.IsNull(), "Unexpected SMIL value type");
 
   aValue.mU.mPtr = nullptr;
   aValue.mType = this;
 }
 
-void nsSMILCSSValueType::Destroy(nsSMILValue& aValue) const {
+void SMILCSSValueType::Destroy(nsSMILValue& aValue) const {
   MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value type");
   delete static_cast<ValueWrapper*>(aValue.mU.mPtr);
-  aValue.mType = nsSMILNullType::Singleton();
+  aValue.mType = SMILNullType::Singleton();
 }
 
-nsresult nsSMILCSSValueType::Assign(nsSMILValue& aDest,
-                                    const nsSMILValue& aSrc) const {
+nsresult SMILCSSValueType::Assign(nsSMILValue& aDest,
+                                  const nsSMILValue& aSrc) const {
   MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types");
   MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value type");
   const ValueWrapper* srcWrapper = ExtractValueWrapper(aSrc);
   ValueWrapper* destWrapper = ExtractValueWrapper(aDest);
 
   if (srcWrapper) {
     if (!destWrapper) {
       // barely-initialized dest -- need to alloc & copy
@@ -150,18 +151,18 @@ nsresult nsSMILCSSValueType::Assign(nsSM
     // fully-initialized dest, barely-initialized src -- clear dest
     delete destWrapper;
     aDest.mU.mPtr = destWrapper = nullptr;
   }  // else, both are barely-initialized -- nothing to do.
 
   return NS_OK;
 }
 
-bool nsSMILCSSValueType::IsEqual(const nsSMILValue& aLeft,
-                                 const nsSMILValue& aRight) const {
+bool SMILCSSValueType::IsEqual(const nsSMILValue& aLeft,
+                               const nsSMILValue& aRight) const {
   MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types");
   MOZ_ASSERT(aLeft.mType == this, "Unexpected SMIL value");
   const ValueWrapper* leftWrapper = ExtractValueWrapper(aLeft);
   const ValueWrapper* rightWrapper = ExtractValueWrapper(aRight);
 
   if (leftWrapper) {
     if (rightWrapper) {
       // Both non-null
@@ -233,17 +234,17 @@ static bool AddOrAccumulateForServo(nsSM
 
   return true;
 }
 
 static bool AddOrAccumulate(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
                             CompositeOperation aCompositeOp, uint64_t aCount) {
   MOZ_ASSERT(aValueToAdd.mType == aDest.mType,
              "Trying to add mismatching types");
-  MOZ_ASSERT(aValueToAdd.mType == &nsSMILCSSValueType::sSingleton,
+  MOZ_ASSERT(aValueToAdd.mType == &SMILCSSValueType::sSingleton,
              "Unexpected SMIL value type");
   MOZ_ASSERT(aCompositeOp == CompositeOperation::Add ||
                  aCompositeOp == CompositeOperation::Accumulate,
              "Composite operation should be add or accumulate");
   MOZ_ASSERT(aCompositeOp != CompositeOperation::Add || aCount == 1,
              "Count should be 1 if composite operation is add");
 
   ValueWrapper* destWrapper = ExtractValueWrapper(aDest);
@@ -270,26 +271,26 @@ static bool AddOrAccumulate(nsSMILValue&
   if (property == eCSSProperty_font) {
     return false;
   }
 
   return AddOrAccumulateForServo(aDest, valueToAddWrapper, destWrapper,
                                  aCompositeOp, aCount);
 }
 
-nsresult nsSMILCSSValueType::SandwichAdd(nsSMILValue& aDest,
-                                         const nsSMILValue& aValueToAdd) const {
+nsresult SMILCSSValueType::SandwichAdd(nsSMILValue& aDest,
+                                       const nsSMILValue& aValueToAdd) const {
   return AddOrAccumulate(aDest, aValueToAdd, CompositeOperation::Add, 1)
              ? NS_OK
              : NS_ERROR_FAILURE;
 }
 
-nsresult nsSMILCSSValueType::Add(nsSMILValue& aDest,
-                                 const nsSMILValue& aValueToAdd,
-                                 uint32_t aCount) const {
+nsresult SMILCSSValueType::Add(nsSMILValue& aDest,
+                               const nsSMILValue& aValueToAdd,
+                               uint32_t aCount) const {
   return AddOrAccumulate(aDest, aValueToAdd, CompositeOperation::Accumulate,
                          aCount)
              ? NS_OK
              : NS_ERROR_FAILURE;
 }
 
 static nsresult ComputeDistanceForServo(const ValueWrapper* aFromWrapper,
                                         const ValueWrapper& aToWrapper,
@@ -323,19 +324,19 @@ static nsresult ComputeDistanceForServo(
     squareDistance += distance * distance;
   }
 
   aDistance = sqrt(squareDistance);
 
   return NS_OK;
 }
 
-nsresult nsSMILCSSValueType::ComputeDistance(const nsSMILValue& aFrom,
-                                             const nsSMILValue& aTo,
-                                             double& aDistance) const {
+nsresult SMILCSSValueType::ComputeDistance(const nsSMILValue& aFrom,
+                                           const nsSMILValue& aTo,
+                                           double& aDistance) const {
   MOZ_ASSERT(aFrom.mType == aTo.mType, "Trying to compare different types");
   MOZ_ASSERT(aFrom.mType == this, "Unexpected source type");
 
   const ValueWrapper* fromWrapper = ExtractValueWrapper(aFrom);
   const ValueWrapper* toWrapper = ExtractValueWrapper(aTo);
   MOZ_ASSERT(toWrapper, "expecting non-null endpoint");
   return ComputeDistanceForServo(fromWrapper, *toWrapper, aDistance);
 }
@@ -383,20 +384,20 @@ static nsresult InterpolateForServo(cons
     }
     results.AppendElement(result);
   }
   aResult.mU.mPtr = new ValueWrapper(aEndWrapper.mPropID, std::move(results));
 
   return NS_OK;
 }
 
-nsresult nsSMILCSSValueType::Interpolate(const nsSMILValue& aStartVal,
-                                         const nsSMILValue& aEndVal,
-                                         double aUnitDistance,
-                                         nsSMILValue& aResult) const {
+nsresult SMILCSSValueType::Interpolate(const nsSMILValue& aStartVal,
+                                       const nsSMILValue& aEndVal,
+                                       double aUnitDistance,
+                                       nsSMILValue& aResult) const {
   MOZ_ASSERT(aStartVal.mType == aEndVal.mType,
              "Trying to interpolate different types");
   MOZ_ASSERT(aStartVal.mType == this, "Unexpected types for interpolation");
   MOZ_ASSERT(aResult.mType == this, "Unexpected result type");
   MOZ_ASSERT(aUnitDistance >= 0.0 && aUnitDistance <= 1.0,
              "unit distance value out of bounds");
   MOZ_ASSERT(!aResult.mU.mPtr, "expecting barely-initialized outparam");
 
@@ -432,21 +433,21 @@ static ServoAnimationValues ValueFromStr
   // Compute value
   aPresContext->StyleSet()->GetAnimationValues(
       servoDeclarationBlock, aTargetElement, aComputedStyle, result);
 
   return result;
 }
 
 // static
-void nsSMILCSSValueType::ValueFromString(nsCSSPropertyID aPropID,
-                                         Element* aTargetElement,
-                                         const nsAString& aString,
-                                         nsSMILValue& aValue,
-                                         bool* aIsContextSensitive) {
+void SMILCSSValueType::ValueFromString(nsCSSPropertyID aPropID,
+                                       Element* aTargetElement,
+                                       const nsAString& aString,
+                                       nsSMILValue& aValue,
+                                       bool* aIsContextSensitive) {
   MOZ_ASSERT(aValue.IsNull(), "Outparam should be null-typed");
   nsPresContext* presContext =
       nsContentUtils::GetContextForContent(aTargetElement);
   if (!presContext) {
     NS_WARNING("Not parsing animation value; unable to get PresContext");
     return;
   }
 
@@ -473,17 +474,17 @@ void nsSMILCSSValueType::ValueFromString
 
   if (!parsedValues.IsEmpty()) {
     sSingleton.Init(aValue);
     aValue.mU.mPtr = new ValueWrapper(aPropID, std::move(parsedValues));
   }
 }
 
 // static
-nsSMILValue nsSMILCSSValueType::ValueFromAnimationValue(
+nsSMILValue SMILCSSValueType::ValueFromAnimationValue(
     nsCSSPropertyID aPropID, Element* aTargetElement,
     const AnimationValue& aValue) {
   nsSMILValue result;
 
   nsIDocument* doc = aTargetElement->GetComposedDoc();
   // We'd like to avoid serializing |aValue| if possible, and since the
   // string passed to CSPAllowsInlineStyle is only used for reporting violations
   // and an intermediate CSS value is not likely to be particularly useful
@@ -498,54 +499,53 @@ nsSMILValue nsSMILCSSValueType::ValueFro
 
   sSingleton.Init(result);
   result.mU.mPtr = new ValueWrapper(aPropID, aValue);
 
   return result;
 }
 
 // static
-bool nsSMILCSSValueType::SetPropertyValues(const nsSMILValue& aValue,
-                                           DeclarationBlock& aDecl) {
-  MOZ_ASSERT(aValue.mType == &nsSMILCSSValueType::sSingleton,
+bool SMILCSSValueType::SetPropertyValues(const nsSMILValue& aValue,
+                                         DeclarationBlock& aDecl) {
+  MOZ_ASSERT(aValue.mType == &SMILCSSValueType::sSingleton,
              "Unexpected SMIL value type");
   const ValueWrapper* wrapper = ExtractValueWrapper(aValue);
   if (!wrapper) {
     return false;
   }
 
   bool changed = false;
   for (const auto& value : wrapper->mServoValues) {
     changed |=
         Servo_DeclarationBlock_SetPropertyToAnimationValue(aDecl.Raw(), value);
   }
 
   return changed;
 }
 
 // static
-nsCSSPropertyID nsSMILCSSValueType::PropertyFromValue(
-    const nsSMILValue& aValue) {
-  if (aValue.mType != &nsSMILCSSValueType::sSingleton) {
+nsCSSPropertyID SMILCSSValueType::PropertyFromValue(const nsSMILValue& aValue) {
+  if (aValue.mType != &SMILCSSValueType::sSingleton) {
     return eCSSProperty_UNKNOWN;
   }
 
   const ValueWrapper* wrapper = ExtractValueWrapper(aValue);
   if (!wrapper) {
     return eCSSProperty_UNKNOWN;
   }
 
   return wrapper->mPropID;
 }
 
 // static
-void nsSMILCSSValueType::FinalizeValue(nsSMILValue& aValue,
-                                       const nsSMILValue& aValueToMatch) {
+void SMILCSSValueType::FinalizeValue(nsSMILValue& aValue,
+                                     const nsSMILValue& aValueToMatch) {
   MOZ_ASSERT(aValue.mType == aValueToMatch.mType, "Incompatible SMIL types");
-  MOZ_ASSERT(aValue.mType == &nsSMILCSSValueType::sSingleton,
+  MOZ_ASSERT(aValue.mType == &SMILCSSValueType::sSingleton,
              "Unexpected SMIL value type");
 
   ValueWrapper* valueWrapper = ExtractValueWrapper(aValue);
   // If |aValue| already has a value, there's nothing to do here.
   if (valueWrapper) {
     return;
   }
 
@@ -564,8 +564,10 @@ void nsSMILCSSValueType::FinalizeValue(n
     if (!zeroValue) {
       return;
     }
     zeroValues.AppendElement(std::move(zeroValue));
   }
   aValue.mU.mPtr =
       new ValueWrapper(valueToMatchWrapper->mPropID, std::move(zeroValues));
 }
+
+}  // namespace mozilla
rename from dom/smil/nsSMILCSSValueType.h
rename to dom/smil/SMILCSSValueType.h
--- a/dom/smil/nsSMILCSSValueType.h
+++ b/dom/smil/SMILCSSValueType.h
@@ -15,28 +15,27 @@
 #include "mozilla/Attributes.h"
 
 namespace mozilla {
 struct AnimationValue;
 class DeclarationBlock;
 namespace dom {
 class Element;
 }  // namespace dom
-}  // namespace mozilla
 
 /*
- * nsSMILCSSValueType: Represents a SMIL-animated CSS value.
+ * SMILCSSValueType: Represents a SMIL-animated CSS value.
  */
-class nsSMILCSSValueType : public nsISMILType {
+class SMILCSSValueType : public nsISMILType {
  public:
   typedef mozilla::dom::Element Element;
   typedef mozilla::AnimationValue AnimationValue;
 
   // Singleton for nsSMILValue objects to hold onto.
-  static nsSMILCSSValueType sSingleton;
+  static SMILCSSValueType sSingleton;
 
  protected:
   // nsISMILType Methods
   // -------------------
   void Init(nsSMILValue& aValue) const override;
   void Destroy(nsSMILValue&) const override;
   nsresult Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const override;
   bool IsEqual(const nsSMILValue& aLeft,
@@ -54,33 +53,33 @@ class nsSMILCSSValueType : public nsISMI
  public:
   // Helper Methods
   // --------------
   /**
    * Sets up the given nsSMILValue to represent the given string value.  The
    * string is interpreted as a value for the given property on the given
    * element.
    *
-   * On failure, this method leaves aValue.mType == nsSMILNullType::sSingleton.
+   * On failure, this method leaves aValue.mType == SMILNullType::sSingleton.
    * Otherwise, this method leaves aValue.mType == this class's singleton.
    *
    * @param       aPropID         The property for which we're parsing a value.
    * @param       aTargetElement  The target element to whom the property/value
    *                              setting applies.
    * @param       aString         The string to be parsed as a CSS value.
    * @param [out] aValue          The nsSMILValue to be populated. Should
    *                              initially be null-typed.
    * @param [out] aIsContextSensitive Set to true if |aString| may produce
    *                                  a different |aValue| depending on other
    *                                  CSS properties on |aTargetElement|
    *                                  or its ancestors (e.g. 'inherit).
    *                                  false otherwise. May be nullptr.
    *                                  Not set if the method fails.
    * @pre  aValue.IsNull()
-   * @post aValue.IsNull() || aValue.mType == nsSMILCSSValueType::sSingleton
+   * @post aValue.IsNull() || aValue.mType == SMILCSSValueType::sSingleton
    */
   static void ValueFromString(nsCSSPropertyID aPropID, Element* aTargetElement,
                               const nsAString& aString, nsSMILValue& aValue,
                               bool* aIsContextSensitive);
 
   /**
    * Creates an nsSMILValue to wrap the given animation value.
    *
@@ -104,34 +103,36 @@ class nsSMILCSSValueType : public nsISMI
   static bool SetPropertyValues(const nsSMILValue&, mozilla::DeclarationBlock&);
 
   /**
    * Return the CSS property animated by the specified value.
    *
    * @param   aValue   The nsSMILValue to examine.
    * @return           The nsCSSPropertyID enum value of the property animated
    *                   by |aValue|, or eCSSProperty_UNKNOWN if the type of
-   *                   |aValue| is not nsSMILCSSValueType.
+   *                   |aValue| is not SMILCSSValueType.
    */
   static nsCSSPropertyID PropertyFromValue(const nsSMILValue& aValue);
 
   /**
    * If |aValue| is an empty value, converts it to a suitable zero value by
    * matching the type of value stored in |aValueToMatch|.
    *
    * There is no indication if this method fails. If a suitable zero value could
    * not be created, |aValue| is simply unmodified.
    *
-   * @param aValue        The nsSMILValue (of type nsSMILCSSValueType) to
+   * @param aValue        The nsSMILValue (of type SMILCSSValueType) to
    *                      possibly update.
-   * @param aValueToMatch A nsSMILValue (of type nsSMILCSSValueType) for which
+   * @param aValueToMatch A nsSMILValue (of type SMILCSSValueType) for which
    *                      a corresponding zero value will be created if |aValue|
    *                      is empty.
    */
   static void FinalizeValue(nsSMILValue& aValue,
                             const nsSMILValue& aValueToMatch);
 
  private:
   // Private constructor: prevent instances beyond my singleton.
-  constexpr nsSMILCSSValueType() {}
+  constexpr SMILCSSValueType() {}
 };
 
+}  // namespace mozilla
+
 #endif  // NS_SMILCSSVALUETYPE_H_
--- a/dom/smil/SMILEnumType.cpp
+++ b/dom/smil/SMILEnumType.cpp
@@ -15,17 +15,17 @@ void SMILEnumType::Init(nsSMILValue& aVa
   MOZ_ASSERT(aValue.IsNull(), "Unexpected value type");
   aValue.mU.mUint = 0;
   aValue.mType = this;
 }
 
 void SMILEnumType::Destroy(nsSMILValue& aValue) const {
   MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value");
   aValue.mU.mUint = 0;
-  aValue.mType = nsSMILNullType::Singleton();
+  aValue.mType = SMILNullType::Singleton();
 }
 
 nsresult SMILEnumType::Assign(nsSMILValue& aDest,
                               const nsSMILValue& aSrc) const {
   MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types");
   MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value");
   aDest.mU.mUint = aSrc.mU.mUint;
   return NS_OK;
--- a/dom/smil/SMILFloatType.cpp
+++ b/dom/smil/SMILFloatType.cpp
@@ -15,17 +15,17 @@ void SMILFloatType::Init(nsSMILValue& aV
   MOZ_ASSERT(aValue.IsNull(), "Unexpected value type");
   aValue.mU.mDouble = 0.0;
   aValue.mType = this;
 }
 
 void SMILFloatType::Destroy(nsSMILValue& aValue) const {
   MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value");
   aValue.mU.mDouble = 0.0;
-  aValue.mType = nsSMILNullType::Singleton();
+  aValue.mType = SMILNullType::Singleton();
 }
 
 nsresult SMILFloatType::Assign(nsSMILValue& aDest,
                                const nsSMILValue& aSrc) const {
   MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types");
   MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value");
   aDest.mU.mDouble = aSrc.mU.mDouble;
   return NS_OK;
--- a/dom/smil/SMILIntegerType.cpp
+++ b/dom/smil/SMILIntegerType.cpp
@@ -15,17 +15,17 @@ void SMILIntegerType::Init(nsSMILValue& 
   MOZ_ASSERT(aValue.IsNull(), "Unexpected value type");
   aValue.mU.mInt = 0;
   aValue.mType = this;
 }
 
 void SMILIntegerType::Destroy(nsSMILValue& aValue) const {
   MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value");
   aValue.mU.mInt = 0;
-  aValue.mType = nsSMILNullType::Singleton();
+  aValue.mType = SMILNullType::Singleton();
 }
 
 nsresult SMILIntegerType::Assign(nsSMILValue& aDest,
                                  const nsSMILValue& aSrc) const {
   MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types");
   MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value");
   aDest.mU.mInt = aSrc.mU.mInt;
   return NS_OK;
rename from dom/smil/nsSMILNullType.cpp
rename to dom/smil/SMILNullType.cpp
--- a/dom/smil/nsSMILNullType.cpp
+++ b/dom/smil/SMILNullType.cpp
@@ -1,52 +1,56 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "nsSMILNullType.h"
+#include "SMILNullType.h"
 #include "nsSMILValue.h"
 #include "nsDebug.h"
 
-/*static*/ nsSMILNullType* nsSMILNullType::Singleton() {
-  static nsSMILNullType sSingleton;
+namespace mozilla {
+
+/*static*/ SMILNullType* SMILNullType::Singleton() {
+  static SMILNullType sSingleton;
   return &sSingleton;
 }
 
-nsresult nsSMILNullType::Assign(nsSMILValue& aDest,
-                                const nsSMILValue& aSrc) const {
+nsresult SMILNullType::Assign(nsSMILValue& aDest,
+                              const nsSMILValue& aSrc) const {
   MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types");
   MOZ_ASSERT(aSrc.mType == this, "Unexpected source type");
   aDest.mU = aSrc.mU;
   aDest.mType = Singleton();
   return NS_OK;
 }
 
-bool nsSMILNullType::IsEqual(const nsSMILValue& aLeft,
-                             const nsSMILValue& aRight) const {
+bool SMILNullType::IsEqual(const nsSMILValue& aLeft,
+                           const nsSMILValue& aRight) const {
   MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types");
   MOZ_ASSERT(aLeft.mType == this, "Unexpected type for SMIL value");
 
   return true;  // All null-typed values are equivalent.
 }
 
-nsresult nsSMILNullType::Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
-                             uint32_t aCount) const {
+nsresult SMILNullType::Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
+                           uint32_t aCount) const {
   MOZ_ASSERT_UNREACHABLE("Adding NULL type");
   return NS_ERROR_FAILURE;
 }
 
-nsresult nsSMILNullType::ComputeDistance(const nsSMILValue& aFrom,
-                                         const nsSMILValue& aTo,
-                                         double& aDistance) const {
+nsresult SMILNullType::ComputeDistance(const nsSMILValue& aFrom,
+                                       const nsSMILValue& aTo,
+                                       double& aDistance) const {
   MOZ_ASSERT_UNREACHABLE("Computing distance for NULL type");
   return NS_ERROR_FAILURE;
 }
 
-nsresult nsSMILNullType::Interpolate(const nsSMILValue& aStartVal,
-                                     const nsSMILValue& aEndVal,
-                                     double aUnitDistance,
-                                     nsSMILValue& aResult) const {
+nsresult SMILNullType::Interpolate(const nsSMILValue& aStartVal,
+                                   const nsSMILValue& aEndVal,
+                                   double aUnitDistance,
+                                   nsSMILValue& aResult) const {
   MOZ_ASSERT_UNREACHABLE("Interpolating NULL type");
   return NS_ERROR_FAILURE;
 }
+
+}  // namespace mozilla
rename from dom/smil/nsSMILNullType.h
rename to dom/smil/SMILNullType.h
--- a/dom/smil/nsSMILNullType.h
+++ b/dom/smil/SMILNullType.h
@@ -5,20 +5,22 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef NS_SMILNULLTYPE_H_
 #define NS_SMILNULLTYPE_H_
 
 #include "mozilla/Attributes.h"
 #include "nsISMILType.h"
 
-class nsSMILNullType : public nsISMILType {
+namespace mozilla {
+
+class SMILNullType : public nsISMILType {
  public:
   // Singleton for nsSMILValue objects to hold onto.
-  static nsSMILNullType* Singleton();
+  static SMILNullType* Singleton();
 
  protected:
   // nsISMILType Methods
   // -------------------
   virtual void Init(nsSMILValue& aValue) const override {}
   virtual void Destroy(nsSMILValue& aValue) const override {}
   virtual nsresult Assign(nsSMILValue& aDest,
                           const nsSMILValue& aSrc) const override;
@@ -33,12 +35,14 @@ class nsSMILNullType : public nsISMILTyp
                                    const nsSMILValue& aTo,
                                    double& aDistance) const override;
   virtual nsresult Interpolate(const nsSMILValue& aStartVal,
                                const nsSMILValue& aEndVal, double aUnitDistance,
                                nsSMILValue& aResult) const override;
 
  private:
   // Private constructor: prevent instances beyond my singleton.
-  constexpr nsSMILNullType() {}
+  constexpr SMILNullType() {}
 };
 
+}  // namespace mozilla
+
 #endif  // NS_SMILNULLTYPE_H_
--- a/dom/smil/SMILStringType.cpp
+++ b/dom/smil/SMILStringType.cpp
@@ -16,17 +16,17 @@ void SMILStringType::Init(nsSMILValue& a
   aValue.mU.mPtr = new nsString();
   aValue.mType = this;
 }
 
 void SMILStringType::Destroy(nsSMILValue& aValue) const {
   MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value");
   delete static_cast<nsAString*>(aValue.mU.mPtr);
   aValue.mU.mPtr = nullptr;
-  aValue.mType = nsSMILNullType::Singleton();
+  aValue.mType = SMILNullType::Singleton();
 }
 
 nsresult SMILStringType::Assign(nsSMILValue& aDest,
                                 const nsSMILValue& aSrc) const {
   MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types");
   MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value");
 
   const nsAString* src = static_cast<const nsAString*>(aSrc.mU.mPtr);
--- a/dom/smil/moz.build
+++ b/dom/smil/moz.build
@@ -11,60 +11,60 @@ MOCHITEST_MANIFESTS += ['test/mochitest.
 
 EXPORTS += [
     'nsISMILAttr.h',
     'nsISMILType.h',
     'nsSMILAnimationController.h',
     'nsSMILAnimationFunction.h',
     'nsSMILCompositorTable.h',
     'nsSMILCSSProperty.h',
-    'nsSMILCSSValueType.h',
     'nsSMILInstanceTime.h',
     'nsSMILInterval.h',
     'nsSMILKeySpline.h',
     'nsSMILMilestone.h',
-    'nsSMILNullType.h',
     'nsSMILRepeatCount.h',
     'nsSMILSetAnimationFunction.h',
     'nsSMILTargetIdentifier.h',
     'nsSMILTimeContainer.h',
     'nsSMILTimedElement.h',
     'nsSMILTimeValue.h',
     'nsSMILTimeValueSpec.h',
     'nsSMILTimeValueSpecParams.h',
     'nsSMILTypes.h',
     'nsSMILValue.h',
+    'SMILCSSValueType.h',
+    'SMILNullType.h',
 ]
 
 EXPORTS.mozilla.dom += [
     'TimeEvent.h',
 ]
 
 UNIFIED_SOURCES += [
     'nsSMILAnimationController.cpp',
     'nsSMILAnimationFunction.cpp',
     'nsSMILCompositor.cpp',
     'nsSMILCSSProperty.cpp',
-    'nsSMILCSSValueType.cpp',
     'nsSMILInstanceTime.cpp',
     'nsSMILInterval.cpp',
     'nsSMILKeySpline.cpp',
-    'nsSMILNullType.cpp',
     'nsSMILParserUtils.cpp',
     'nsSMILRepeatCount.cpp',
     'nsSMILSetAnimationFunction.cpp',
     'nsSMILTimeContainer.cpp',
     'nsSMILTimedElement.cpp',
     'nsSMILTimeValue.cpp',
     'nsSMILTimeValueSpec.cpp',
     'nsSMILValue.cpp',
     'SMILBoolType.cpp',
+    'SMILCSSValueType.cpp',
     'SMILEnumType.cpp',
     'SMILFloatType.cpp',
     'SMILIntegerType.cpp',
+    'SMILNullType.cpp',
     'SMILStringType.cpp',
     'TimeEvent.cpp',
 ]
 
 LOCAL_INCLUDES += [
     '/dom/base',
     '/dom/svg',
     '/layout/base',
--- a/dom/smil/nsSMILAnimationFunction.cpp
+++ b/dom/smil/nsSMILAnimationFunction.cpp
@@ -4,19 +4,19 @@
  * 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/. */
 
 #include "nsSMILAnimationFunction.h"
 
 #include "mozilla/dom/SVGAnimationElement.h"
 #include "mozilla/Move.h"
 #include "nsISMILAttr.h"
-#include "nsSMILCSSValueType.h"
+#include "SMILCSSValueType.h"
 #include "nsSMILParserUtils.h"
-#include "nsSMILNullType.h"
+#include "SMILNullType.h"
 #include "nsSMILTimedElement.h"
 #include "nsAttrValueInlines.h"
 #include "nsGkAtoms.h"
 #include "nsCOMPtr.h"
 #include "nsCOMArray.h"
 #include "nsIContent.h"
 #include "nsContentUtils.h"
 #include "nsReadableUtils.h"
@@ -336,17 +336,17 @@ nsresult nsSMILAnimationFunction::Interp
   }
 
   nsresult rv = NS_OK;
   nsSMILCalcMode calcMode = GetCalcMode();
 
   // Force discrete calcMode for visibility since StyleAnimationValue will
   // try to interpolate it using the special clamping behavior defined for
   // CSS.
-  if (nsSMILCSSValueType::PropertyFromValue(aValues[0]) ==
+  if (SMILCSSValueType::PropertyFromValue(aValues[0]) ==
       eCSSProperty_visibility) {
     calcMode = CALC_DISCRETE;
   }
 
   if (calcMode != CALC_DISCRETE) {
     // Get the normalised progress between adjacent values
     const nsSMILValue* from = nullptr;
     const nsSMILValue* to = nullptr;
@@ -420,35 +420,35 @@ nsresult nsSMILAnimationFunction::Interp
       uint32_t index = (uint32_t)floor(scaledSimpleProgress * 2);
       aResult = index == 0 ? aBaseValue : aValues[0];
     } else {
       uint32_t index = (uint32_t)floor(scaledSimpleProgress * aValues.Length());
       aResult = aValues[index];
 
       // For animation of CSS properties, normally when interpolating we perform
       // a zero-value fixup which means that empty values (values with type
-      // nsSMILCSSValueType but a null pointer value) are converted into
+      // SMILCSSValueType but a null pointer value) are converted into
       // a suitable zero value based on whatever they're being interpolated
       // with. For discrete animation, however, since we don't interpolate,
       // that never happens. In some rare cases, such as discrete non-additive
       // by-animation, we can arrive here with |aResult| being such an empty
       // value so we need to manually perform the fixup.
       //
       // We could define a generic method for this on nsSMILValue but its faster
-      // and simpler to just special case nsSMILCSSValueType.
-      if (aResult.mType == &nsSMILCSSValueType::sSingleton) {
+      // and simpler to just special case SMILCSSValueType.
+      if (aResult.mType == &SMILCSSValueType::sSingleton) {
         // We have currently only ever encountered this case for the first
         // value of a by-animation (which has two values) and since we have no
         // way of testing other cases we just skip them (but assert if we
         // ever do encounter them so that we can add code to handle them).
         if (index + 1 >= aValues.Length()) {
           MOZ_ASSERT(aResult.mU.mPtr, "The last value should not be empty");
         } else {
           // Base the type of the zero value on the next element in the series.
-          nsSMILCSSValueType::FinalizeValue(aResult, aValues[index + 1]);
+          SMILCSSValueType::FinalizeValue(aResult, aValues[index + 1]);
         }
       }
     }
     rv = NS_OK;
   }
   return rv;
 }
 
--- a/dom/smil/nsSMILCSSProperty.cpp
+++ b/dom/smil/nsSMILCSSProperty.cpp
@@ -8,17 +8,17 @@
 
 #include "nsSMILCSSProperty.h"
 
 #include "mozilla/dom/Element.h"
 #include "mozilla/Move.h"
 #include "mozilla/ServoBindings.h"
 #include "mozilla/StyleAnimationValue.h"
 #include "nsDOMCSSAttrDeclaration.h"
-#include "nsSMILCSSValueType.h"
+#include "SMILCSSValueType.h"
 #include "nsSMILValue.h"
 #include "nsCSSProps.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 // Class Methods
 nsSMILCSSProperty::nsSMILCSSProperty(nsCSSPropertyID aPropID, Element* aElement,
@@ -50,41 +50,41 @@ nsSMILValue nsSMILCSSProperty::GetBaseVa
     // doing so involves clearing and resetting the property which can cause
     // frames to be recreated which we'd like to avoid.
     //
     // Furthermore, if we don't (yet) have a base ComputedStyle we obviously
     // can't resolve a base value.
     //
     // In any case, just return a dummy value (initialized with the right
     // type, so as not to indicate failure).
-    nsSMILValue tmpVal(&nsSMILCSSValueType::sSingleton);
+    nsSMILValue tmpVal(&SMILCSSValueType::sSingleton);
     Swap(baseValue, tmpVal);
     return baseValue;
   }
 
   AnimationValue computedValue;
   computedValue.mServo =
       Servo_ComputedValues_ExtractAnimationValue(mBaseComputedStyle, mPropID)
           .Consume();
   if (!computedValue.mServo) {
     return baseValue;
   }
 
-  baseValue = nsSMILCSSValueType::ValueFromAnimationValue(mPropID, mElement,
-                                                          computedValue);
+  baseValue = SMILCSSValueType::ValueFromAnimationValue(mPropID, mElement,
+                                                        computedValue);
   return baseValue;
 }
 
 nsresult nsSMILCSSProperty::ValueFromString(
     const nsAString& aStr, const SVGAnimationElement* aSrcElement,
     nsSMILValue& aValue, bool& aPreventCachingOfSandwich) const {
   NS_ENSURE_TRUE(IsPropertyAnimatable(mPropID), NS_ERROR_FAILURE);
 
-  nsSMILCSSValueType::ValueFromString(mPropID, mElement, aStr, aValue,
-                                      &aPreventCachingOfSandwich);
+  SMILCSSValueType::ValueFromString(mPropID, mElement, aStr, aValue,
+                                    &aPreventCachingOfSandwich);
 
   if (aValue.IsNull()) {
     return NS_ERROR_FAILURE;
   }
 
   // XXX Due to bug 536660 (or at least that seems to be the most likely
   // culprit), when we have animation setting display:none on a <use> element,
   // if we DON'T set the property every sample, chaos ensues.
--- a/dom/smil/nsSMILCSSProperty.h
+++ b/dom/smil/nsSMILCSSProperty.h
@@ -31,17 +31,17 @@ class nsSMILCSSProperty : public nsISMIL
  public:
   /**
    * Constructs a new nsSMILCSSProperty.
    * @param  aPropID   The CSS property we're interested in animating.
    * @param  aElement  The element whose CSS property is being animated.
    * @param  aBaseComputedStyle  The ComputedStyle to use when getting the base
    *                             value. If this is nullptr and GetBaseValue is
    *                             called, an empty nsSMILValue initialized with
-   *                             the nsSMILCSSValueType will be returned.
+   *                             the SMILCSSValueType will be returned.
    */
   nsSMILCSSProperty(nsCSSPropertyID aPropID, mozilla::dom::Element* aElement,
                     mozilla::ComputedStyle* aBaseComputedStyle);
 
   // nsISMILAttr methods
   virtual nsresult ValueFromString(
       const nsAString& aStr,
       const mozilla::dom::SVGAnimationElement* aSrcElement, nsSMILValue& aValue,
--- a/dom/smil/nsSMILValue.cpp
+++ b/dom/smil/nsSMILValue.cpp
@@ -7,28 +7,28 @@
 #include "nsSMILValue.h"
 #include "nsDebug.h"
 #include <string.h>
 
 //----------------------------------------------------------------------
 // Public methods
 
 nsSMILValue::nsSMILValue(const nsISMILType* aType)
-    : mType(nsSMILNullType::Singleton()) {
+    : mType(SMILNullType::Singleton()) {
   mU.mBool = false;
   if (!aType) {
     NS_ERROR("Trying to construct nsSMILValue with null mType pointer");
     return;
   }
 
   InitAndCheckPostcondition(aType);
 }
 
 nsSMILValue::nsSMILValue(const nsSMILValue& aVal)
-    : mType(nsSMILNullType::Singleton()) {
+    : mType(SMILNullType::Singleton()) {
   InitAndCheckPostcondition(aVal.mType);
   mType->Assign(*this, aVal);
 }
 
 const nsSMILValue& nsSMILValue::operator=(const nsSMILValue& aVal) {
   if (&aVal == this) return *this;
 
   if (mType != aVal.mType) {
@@ -42,32 +42,32 @@ const nsSMILValue& nsSMILValue::operator
 
 // Move constructor / reassignment operator:
 nsSMILValue::nsSMILValue(nsSMILValue&& aVal)
     : mU(aVal.mU),  // Copying union is only OK because we clear aVal.mType
                     // below.
       mType(aVal.mType) {
   // Leave aVal with a null type, so that it's safely destructible (and won't
   // mess with anything referenced by its union, which we've copied).
-  aVal.mType = nsSMILNullType::Singleton();
+  aVal.mType = SMILNullType::Singleton();
 }
 
 nsSMILValue& nsSMILValue::operator=(nsSMILValue&& aVal) {
   if (!IsNull()) {
     // Clean up any data we're currently tracking.
     DestroyAndCheckPostcondition();
   }
 
   // Copy the union (which could include a pointer to external memory) & mType:
   mU = aVal.mU;
   mType = aVal.mType;
 
   // Leave aVal with a null type, so that it's safely destructible (and won't
   // mess with anything referenced by its union, which we've now copied).
-  aVal.mType = nsSMILNullType::Singleton();
+  aVal.mType = SMILNullType::Singleton();
 
   return *this;
 }
 
 bool nsSMILValue::operator==(const nsSMILValue& aVal) const {
   if (&aVal == this) return true;
 
   return mType == aVal.mType && mType->IsEqual(*this, aVal);
--- a/dom/smil/nsSMILValue.h
+++ b/dom/smil/nsSMILValue.h
@@ -3,47 +3,49 @@
 /* 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/. */
 
 #ifndef NS_SMILVALUE_H_
 #define NS_SMILVALUE_H_
 
 #include "nsISMILType.h"
-#include "nsSMILNullType.h"
+#include "SMILNullType.h"
 
 /**
  * Although objects of this type are generally only created on the stack and
  * only exist during the taking of a new time sample, that's not always the
  * case. The nsSMILValue objects obtained from attributes' base values are
  * cached so that the SMIL engine can make certain optimizations during a
  * sample if the base value has not changed since the last sample (potentially
  * avoiding recomposing). These nsSMILValue objects typically live much longer
  * than a single sample.
  */
 class nsSMILValue {
  public:
-  nsSMILValue() : mU(), mType(nsSMILNullType::Singleton()) {}
+  typedef mozilla::SMILNullType SMILNullType;
+
+  nsSMILValue() : mU(), mType(SMILNullType::Singleton()) {}
   explicit nsSMILValue(const nsISMILType* aType);
   nsSMILValue(const nsSMILValue& aVal);
 
   ~nsSMILValue() { mType->Destroy(*this); }
 
   const nsSMILValue& operator=(const nsSMILValue& aVal);
 
   // Move constructor / reassignment operator:
   nsSMILValue(nsSMILValue&& aVal);
   nsSMILValue& operator=(nsSMILValue&& aVal);
 
   // Equality operators. These are allowed to be conservative (return false
   // more than you'd expect) - see comment above nsISMILType::IsEqual.
   bool operator==(const nsSMILValue& aVal) const;
   bool operator!=(const nsSMILValue& aVal) const { return !(*this == aVal); }
 
-  bool IsNull() const { return (mType == nsSMILNullType::Singleton()); }
+  bool IsNull() const { return (mType == SMILNullType::Singleton()); }
 
   nsresult Add(const nsSMILValue& aValueToAdd, uint32_t aCount = 1);
   nsresult SandwichAdd(const nsSMILValue& aValueToAdd);
   nsresult ComputeDistance(const nsSMILValue& aTo, double& aDistance) const;
   nsresult Interpolate(const nsSMILValue& aEndVal, double aUnitDistance,
                        nsSMILValue& aResult) const;
 
   union {
--- a/dom/svg/DOMSVGTransformList.cpp
+++ b/dom/svg/DOMSVGTransformList.cpp
@@ -1,20 +1,21 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "DOMSVGTransformList.h"
+
+#include "mozilla/dom/SVGElement.h"
 #include "mozilla/dom/SVGTransform.h"
 #include "mozilla/dom/SVGMatrix.h"
+#include "mozilla/dom/SVGTransformListBinding.h"
 #include "SVGAnimatedTransformList.h"
-#include "SVGElement.h"
-#include "mozilla/dom/SVGTransformListBinding.h"
 #include "nsError.h"
 #include <algorithm>
 
 // local helper functions
 namespace {
 
 void UpdateListIndicesFromIndex(
     FallibleTArray<mozilla::dom::SVGTransform*>& aItemsArray,
--- a/dom/svg/DOMSVGTransformList.h
+++ b/dom/svg/DOMSVGTransformList.h
@@ -5,18 +5,18 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MOZILLA_DOMSVGTRANSFORMLIST_H__
 #define MOZILLA_DOMSVGTRANSFORMLIST_H__
 
 #include "DOMSVGAnimatedTransformList.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsDebug.h"
+#include "SVGTransformList.h"
 #include "nsTArray.h"
-#include "SVGTransformList.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/ErrorResult.h"
 
 namespace mozilla {
 
 namespace dom {
 class SVGElement;
 class SVGMatrix;
--- a/dom/svg/SVGAnimatedTransformList.cpp
+++ b/dom/svg/SVGAnimatedTransformList.cpp
@@ -2,23 +2,23 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "SVGAnimatedTransformList.h"
 
 #include "mozilla/dom/MutationEventBinding.h"
-#include "DOMSVGAnimatedTransformList.h"
 #include "mozilla/dom/SVGAnimationElement.h"
 #include "mozilla/Move.h"
 #include "nsCharSeparatedTokenizer.h"
-#include "nsSVGTransform.h"
+#include "DOMSVGAnimatedTransformList.h"
+#include "SVGContentUtils.h"
 #include "nsSMILValue.h"
-#include "SVGContentUtils.h"
+#include "nsSVGTransform.h"
 #include "SVGTransformListSMILType.h"
 
 using namespace mozilla::dom;
 using namespace mozilla::dom::SVGTransform_Binding;
 
 namespace mozilla {
 
 nsresult SVGAnimatedTransformList::SetBaseValueString(const nsAString& aValue,
--- a/dom/svg/SVGElement.cpp
+++ b/dom/svg/SVGElement.cpp
@@ -5,61 +5,61 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/Unused.h"
 
 #include "SVGElement.h"
 
+#include "mozilla/dom/MutationEventBinding.h"
+#include "mozilla/dom/SVGAnimatedEnumeration.h"
+#include "mozilla/dom/SVGElementBinding.h"
 #include "mozilla/dom/SVGLengthBinding.h"
 #include "mozilla/dom/SVGSVGElement.h"
 #include "mozilla/dom/SVGTests.h"
 #include "mozilla/dom/SVGUnitTypesBinding.h"
+#include "mozilla/DeclarationBlock.h"
+#include "mozilla/EventListenerManager.h"
+#include "mozilla/InternalMutationEvent.h"
+#include "mozilla/RestyleManager.h"
+#include "mozilla/Unused.h"
+#include "mozAutoDocUpdate.h"
+#include "nsAttrValueOrString.h"
+#include "nsCSSProps.h"
 #include "nsContentUtils.h"
 #include "nsICSSDeclaration.h"
 #include "nsIContentInlines.h"
 #include "nsIDocument.h"
-#include "mozilla/InternalMutationEvent.h"
-#include "mozAutoDocUpdate.h"
 #include "nsError.h"
-#include "nsIPresShell.h"
 #include "nsGkAtoms.h"
-#include "nsCSSProps.h"
-#include "mozilla/EventListenerManager.h"
+#include "nsIPresShell.h"
+#include "nsIFrame.h"
 #include "nsLayoutUtils.h"
-#include "SVGAnimatedTransformList.h"
+#include "nsSMILAnimationController.h"
+#include "nsSVGAngle.h"
+#include "nsSVGBoolean.h"
+#include "nsSVGEnum.h"
+#include "nsSVGInteger.h"
+#include "nsSVGIntegerPair.h"
 #include "nsSVGLength2.h"
 #include "nsSVGNumber2.h"
 #include "nsSVGNumberPair.h"
-#include "nsSVGInteger.h"
-#include "nsSVGIntegerPair.h"
-#include "nsSVGAngle.h"
-#include "nsSVGBoolean.h"
-#include "nsSVGEnum.h"
+#include "nsSVGString.h"
 #include "nsSVGViewBox.h"
-#include "nsSVGString.h"
-#include "mozilla/dom/SVGAnimatedEnumeration.h"
 #include "SVGAnimatedNumberList.h"
 #include "SVGAnimatedLengthList.h"
 #include "SVGAnimatedPointList.h"
 #include "SVGAnimatedPathSegList.h"
+#include "SVGAnimatedTransformList.h"
 #include "SVGContentUtils.h"
 #include "SVGGeometryElement.h"
-#include "nsIFrame.h"
+#include "SVGMotionSMILAttr.h"
 #include "nsQueryObject.h"
 #include <stdarg.h>
-#include "SVGMotionSMILAttr.h"
-#include "nsAttrValueOrString.h"
-#include "nsSMILAnimationController.h"
-#include "mozilla/dom/MutationEventBinding.h"
-#include "mozilla/dom/SVGElementBinding.h"
-#include "mozilla/DeclarationBlock.h"
-#include "mozilla/Unused.h"
-#include "mozilla/RestyleManager.h"
 
 // This is needed to ensure correct handling of calls to the
 // vararg-list methods in this file:
 //   SVGElement::GetAnimated{Length,Number,Integer}Values
 // See bug 547964 for details:
 static_assert(sizeof(void*) == sizeof(nullptr),
               "nullptr should be the correct size");
 
--- a/dom/svg/SVGElement.h
+++ b/dom/svg/SVGElement.h
@@ -8,28 +8,28 @@
 #define __NS_SVGELEMENT_H__
 
 /*
   SVGElement is the base class for all SVG content elements.
   It implements all the common DOM interfaces and handles attributes.
 */
 
 #include "mozilla/Attributes.h"
+#include "mozilla/dom/DOMRect.h"
+#include "mozilla/dom/Element.h"
+#include "mozilla/gfx/MatrixFwd.h"
 #include "nsAutoPtr.h"
 #include "nsChangeHint.h"
 #include "nsCOMPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsError.h"
-#include "mozilla/dom/DOMRect.h"
-#include "mozilla/dom/Element.h"
-#include "mozilla/gfx/MatrixFwd.h"
 #include "nsISupportsImpl.h"
 #include "nsStyledElement.h"
+#include "SVGContentUtils.h"
 #include "nsSVGClass.h"
-#include "SVGContentUtils.h"
 #include "gfxMatrix.h"
 
 class nsSVGAngle;
 class nsSVGBoolean;
 class nsSVGEnum;
 class nsSVGInteger;
 class nsSVGIntegerPair;
 class nsSVGLength2;
--- a/dom/svg/SVGFragmentIdentifier.cpp
+++ b/dom/svg/SVGFragmentIdentifier.cpp
@@ -3,19 +3,19 @@
 /* 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/. */
 
 #include "SVGFragmentIdentifier.h"
 
 #include "mozilla/dom/SVGSVGElement.h"
 #include "mozilla/dom/SVGViewElement.h"
+#include "nsCharSeparatedTokenizer.h"
 #include "nsContentUtils.h"  // for nsCharSeparatedTokenizerTemplate
 #include "SVGAnimatedTransformList.h"
-#include "nsCharSeparatedTokenizer.h"
 
 namespace mozilla {
 
 using namespace dom;
 
 static bool IsMatchingParameter(const nsAString& aString,
                                 const nsAString& aParameterName) {
   // The first two tests ensure aString.Length() > aParameterName.Length()
--- a/dom/svg/SVGGradientElement.cpp
+++ b/dom/svg/SVGGradientElement.cpp
@@ -2,25 +2,25 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/SVGGradientElement.h"
 
 #include "mozilla/ArrayUtils.h"
-#include "DOMSVGAnimatedTransformList.h"
+#include "mozilla/dom/SVGElement.h"
 #include "mozilla/dom/SVGGradientElementBinding.h"
-#include "mozilla/dom/SVGRadialGradientElementBinding.h"
 #include "mozilla/dom/SVGLengthBinding.h"
 #include "mozilla/dom/SVGLinearGradientElementBinding.h"
+#include "mozilla/dom/SVGRadialGradientElementBinding.h"
 #include "mozilla/dom/SVGUnitTypesBinding.h"
+#include "DOMSVGAnimatedTransformList.h"
 #include "nsCOMPtr.h"
 #include "nsGkAtoms.h"
-#include "SVGElement.h"
 
 NS_IMPL_NS_NEW_SVG_ELEMENT(LinearGradient)
 NS_IMPL_NS_NEW_SVG_ELEMENT(RadialGradient)
 
 namespace mozilla {
 namespace dom {
 
 using namespace SVGGradientElement_Binding;
--- a/dom/svg/SVGGradientElement.h
+++ b/dom/svg/SVGGradientElement.h
@@ -5,18 +5,18 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef __NS_SVGGRADIENTELEMENT_H__
 #define __NS_SVGGRADIENTELEMENT_H__
 
 #include "nsAutoPtr.h"
 #include "SVGAnimatedTransformList.h"
 #include "SVGElement.h"
+#include "nsSVGEnum.h"
 #include "nsSVGLength2.h"
-#include "nsSVGEnum.h"
 #include "nsSVGString.h"
 
 class nsSVGGradientFrame;
 class nsSVGLinearGradientFrame;
 class nsSVGRadialGradientFrame;
 
 nsresult NS_NewSVGLinearGradientElement(
     nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
--- a/dom/svg/SVGIntegerPairSMILType.cpp
+++ b/dom/svg/SVGIntegerPairSMILType.cpp
@@ -18,17 +18,17 @@ void SVGIntegerPairSMILType::Init(nsSMIL
   aValue.mU.mIntPair[1] = 0;
   aValue.mType = this;
 }
 
 void SVGIntegerPairSMILType::Destroy(nsSMILValue& aValue) const {
   MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value");
   aValue.mU.mIntPair[0] = 0;
   aValue.mU.mIntPair[1] = 0;
-  aValue.mType = nsSMILNullType::Singleton();
+  aValue.mType = SMILNullType::Singleton();
 }
 
 nsresult SVGIntegerPairSMILType::Assign(nsSMILValue& aDest,
                                         const nsSMILValue& aSrc) const {
   MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types");
   MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value");
 
   aDest.mU.mIntPair[0] = aSrc.mU.mIntPair[0];
--- a/dom/svg/SVGLengthListSMILType.cpp
+++ b/dom/svg/SVGLengthListSMILType.cpp
@@ -30,17 +30,17 @@ void SVGLengthListSMILType::Init(nsSMILV
   aValue.mU.mPtr = lengthList;
   aValue.mType = this;
 }
 
 void SVGLengthListSMILType::Destroy(nsSMILValue& aValue) const {
   MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value type");
   delete static_cast<SVGLengthListAndInfo*>(aValue.mU.mPtr);
   aValue.mU.mPtr = nullptr;
-  aValue.mType = nsSMILNullType::Singleton();
+  aValue.mType = SMILNullType::Singleton();
 }
 
 nsresult SVGLengthListSMILType::Assign(nsSMILValue& aDest,
                                        const nsSMILValue& aSrc) const {
   MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types");
   MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value");
 
   const SVGLengthListAndInfo* src =
--- a/dom/svg/SVGMotionSMILType.cpp
+++ b/dom/svg/SVGMotionSMILType.cpp
@@ -168,17 +168,17 @@ void SVGMotionSMILType::Init(nsSMILValue
 
 void SVGMotionSMILType::Destroy(nsSMILValue& aValue) const {
   MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL type");
 
   MotionSegmentArray* arr = static_cast<MotionSegmentArray*>(aValue.mU.mPtr);
   delete arr;
 
   aValue.mU.mPtr = nullptr;
-  aValue.mType = nsSMILNullType::Singleton();
+  aValue.mType = SMILNullType::Singleton();
 }
 
 nsresult SVGMotionSMILType::Assign(nsSMILValue& aDest,
                                    const nsSMILValue& aSrc) const {
   MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types");
   MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL type");
 
   const MotionSegmentArray& srcArr = ExtractMotionSegmentArray(aSrc);
--- a/dom/svg/SVGNumberListSMILType.cpp
+++ b/dom/svg/SVGNumberListSMILType.cpp
@@ -45,17 +45,17 @@ void SVGNumberListSMILType::Init(nsSMILV
   aValue.mU.mPtr = numberList;
   aValue.mType = this;
 }
 
 void SVGNumberListSMILType::Destroy(nsSMILValue& aValue) const {
   MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value type");
   delete static_cast<SVGNumberListAndInfo*>(aValue.mU.mPtr);
   aValue.mU.mPtr = nullptr;
-  aValue.mType = nsSMILNullType::Singleton();
+  aValue.mType = SMILNullType::Singleton();
 }
 
 nsresult SVGNumberListSMILType::Assign(nsSMILValue& aDest,
                                        const nsSMILValue& aSrc) const {
   MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types");
   MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value");
 
   const SVGNumberListAndInfo* src =
--- a/dom/svg/SVGNumberPairSMILType.cpp
+++ b/dom/svg/SVGNumberPairSMILType.cpp
@@ -20,17 +20,17 @@ void SVGNumberPairSMILType::Init(nsSMILV
   aValue.mU.mNumberPair[1] = 0;
   aValue.mType = this;
 }
 
 void SVGNumberPairSMILType::Destroy(nsSMILValue& aValue) const {
   MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value");
   aValue.mU.mNumberPair[0] = 0;
   aValue.mU.mNumberPair[1] = 0;
-  aValue.mType = nsSMILNullType::Singleton();
+  aValue.mType = SMILNullType::Singleton();
 }
 
 nsresult SVGNumberPairSMILType::Assign(nsSMILValue& aDest,
                                        const nsSMILValue& aSrc) const {
   MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types");
   MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value");
 
   aDest.mU.mNumberPair[0] = aSrc.mU.mNumberPair[0];
--- a/dom/svg/SVGOrientSMILType.cpp
+++ b/dom/svg/SVGOrientSMILType.cpp
@@ -25,17 +25,17 @@ void SVGOrientSMILType::Init(nsSMILValue
   aValue.mU.mOrient.mUnit = SVG_ANGLETYPE_UNSPECIFIED;
   aValue.mU.mOrient.mOrientType = SVG_MARKER_ORIENT_ANGLE;
   aValue.mType = this;
 }
 
 void SVGOrientSMILType::Destroy(nsSMILValue& aValue) const {
   MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value.");
   aValue.mU.mPtr = nullptr;
-  aValue.mType = nsSMILNullType::Singleton();
+  aValue.mType = SMILNullType::Singleton();
 }
 
 nsresult SVGOrientSMILType::Assign(nsSMILValue& aDest,
                                    const nsSMILValue& aSrc) const {
   MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types.");
   MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value.");
 
   aDest.mU.mOrient.mAngle = aSrc.mU.mOrient.mAngle;
--- a/dom/svg/SVGPathSegListSMILType.cpp
+++ b/dom/svg/SVGPathSegListSMILType.cpp
@@ -28,17 +28,17 @@ void SVGPathSegListSMILType::Init(nsSMIL
   aValue.mU.mPtr = new SVGPathDataAndInfo();
   aValue.mType = this;
 }
 
 void SVGPathSegListSMILType::Destroy(nsSMILValue& aValue) const {
   MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value type");
   delete static_cast<SVGPathDataAndInfo*>(aValue.mU.mPtr);
   aValue.mU.mPtr = nullptr;
-  aValue.mType = nsSMILNullType::Singleton();
+  aValue.mType = SMILNullType::Singleton();
 }
 
 nsresult SVGPathSegListSMILType::Assign(nsSMILValue& aDest,
                                         const nsSMILValue& aSrc) const {
   MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types");
   MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value");
 
   const SVGPathDataAndInfo* src =
--- a/dom/svg/SVGPatternElement.cpp
+++ b/dom/svg/SVGPatternElement.cpp
@@ -1,23 +1,23 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+#include "mozilla/dom/SVGPatternElement.h"
+
 #include "mozilla/ArrayUtils.h"
-
+#include "mozilla/dom/SVGLengthBinding.h"
+#include "mozilla/dom/SVGPatternElementBinding.h"
+#include "mozilla/dom/SVGUnitTypesBinding.h"
+#include "DOMSVGAnimatedTransformList.h"
 #include "nsCOMPtr.h"
 #include "nsGkAtoms.h"
-#include "DOMSVGAnimatedTransformList.h"
-#include "mozilla/dom/SVGLengthBinding.h"
-#include "mozilla/dom/SVGPatternElement.h"
-#include "mozilla/dom/SVGPatternElementBinding.h"
-#include "mozilla/dom/SVGUnitTypesBinding.h"
 
 NS_IMPL_NS_NEW_SVG_ELEMENT(Pattern)
 
 namespace mozilla {
 namespace dom {
 
 using namespace SVGUnitTypes_Binding;
 
--- a/dom/svg/SVGPatternElement.h
+++ b/dom/svg/SVGPatternElement.h
@@ -3,23 +3,23 @@
 /* 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/. */
 
 #ifndef mozilla_dom_SVGPatternElement_h
 #define mozilla_dom_SVGPatternElement_h
 
 #include "nsAutoPtr.h"
+#include "mozilla/dom/SVGElement.h"
+#include "SVGAnimatedPreserveAspectRatio.h"
+#include "SVGAnimatedTransformList.h"
 #include "nsSVGEnum.h"
 #include "nsSVGLength2.h"
 #include "nsSVGString.h"
-#include "SVGElement.h"
 #include "nsSVGViewBox.h"
-#include "SVGAnimatedPreserveAspectRatio.h"
-#include "SVGAnimatedTransformList.h"
 
 class nsSVGPatternFrame;
 
 nsresult NS_NewSVGPatternElement(
     nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
 namespace mozilla {
 namespace dom {
--- a/dom/svg/SVGPointListSMILType.cpp
+++ b/dom/svg/SVGPointListSMILType.cpp
@@ -26,17 +26,17 @@ void SVGPointListSMILType::Init(nsSMILVa
   aValue.mU.mPtr = pointList;
   aValue.mType = this;
 }
 
 void SVGPointListSMILType::Destroy(nsSMILValue& aValue) const {
   MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value type");
   delete static_cast<SVGPointListAndInfo*>(aValue.mU.mPtr);
   aValue.mU.mPtr = nullptr;
-  aValue.mType = nsSMILNullType::Singleton();
+  aValue.mType = SMILNullType::Singleton();
 }
 
 nsresult SVGPointListSMILType::Assign(nsSMILValue& aDest,
                                       const nsSMILValue& aSrc) const {
   MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types");
   MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value");
 
   const SVGPointListAndInfo* src =
--- a/dom/svg/SVGSVGElement.cpp
+++ b/dom/svg/SVGSVGElement.cpp
@@ -10,26 +10,26 @@
 #include "mozilla/dom/SVGMatrix.h"
 #include "mozilla/dom/SVGRect.h"
 #include "mozilla/dom/SVGViewElement.h"
 #include "mozilla/EventDispatcher.h"
 
 #include "DOMSVGLength.h"
 #include "DOMSVGNumber.h"
 #include "DOMSVGPoint.h"
+#include "nsFrameSelection.h"
 #include "nsLayoutStylesheetCache.h"
-#include "nsSVGAngle.h"
-#include "nsFrameSelection.h"
 #include "nsIFrame.h"
 #include "nsISVGSVGFrame.h"
 #include "nsSMILAnimationController.h"
 #include "nsSMILTimeContainer.h"
+#include "nsSVGAngle.h"
+#include "SVGAngle.h"
 #include "nsSVGDisplayableFrame.h"
 #include "nsSVGUtils.h"
-#include "SVGAngle.h"
 
 NS_IMPL_NS_NEW_SVG_ELEMENT_CHECK_PARSER(SVG)
 
 using namespace mozilla::gfx;
 
 namespace mozilla {
 namespace dom {
 
--- a/dom/svg/SVGTransform.cpp
+++ b/dom/svg/SVGTransform.cpp
@@ -4,21 +4,21 @@
  * 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/. */
 
 #include "SVGTransform.h"
 
 #include "mozilla/dom/SVGTransform.h"
 #include "mozilla/dom/SVGMatrix.h"
 #include "mozilla/dom/SVGTransformBinding.h"
+#include "mozilla/DebugOnly.h"
+#include "mozilla/FloatingPoint.h"
 #include "nsError.h"
 #include "SVGAnimatedTransformList.h"
 #include "nsSVGAttrTearoffTable.h"
-#include "mozilla/DebugOnly.h"
-#include "mozilla/FloatingPoint.h"
 
 namespace {
 const double kRadPerDegree = 2.0 * M_PI / 360.0;
 }  // namespace
 
 namespace mozilla {
 namespace dom {
 
--- a/dom/svg/SVGTransformList.h
+++ b/dom/svg/SVGTransformList.h
@@ -3,19 +3,18 @@
 /* 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/. */
 
 #ifndef MOZILLA_SVGTRANSFORMLIST_H__
 #define MOZILLA_SVGTRANSFORMLIST_H__
 
 #include "gfxMatrix.h"
-#include "nsDebug.h"
+#include "nsSVGTransform.h"
 #include "nsTArray.h"
-#include "nsSVGTransform.h"
 
 namespace mozilla {
 
 namespace dom {
 class SVGTransform;
 }  // namespace dom
 
 /**
--- a/dom/svg/SVGTransformListSMILType.cpp
+++ b/dom/svg/SVGTransformListSMILType.cpp
@@ -27,17 +27,17 @@ void SVGTransformListSMILType::Init(nsSM
   aValue.mType = this;
 }
 
 void SVGTransformListSMILType::Destroy(nsSMILValue& aValue) const {
   MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value type");
   TransformArray* params = static_cast<TransformArray*>(aValue.mU.mPtr);
   delete params;
   aValue.mU.mPtr = nullptr;
-  aValue.mType = nsSMILNullType::Singleton();
+  aValue.mType = SMILNullType::Singleton();
 }
 
 nsresult SVGTransformListSMILType::Assign(nsSMILValue& aDest,
                                           const nsSMILValue& aSrc) const {
   MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types");
   MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value");
 
   const TransformArray* srcTransforms =
--- a/dom/svg/SVGTransformableElement.cpp
+++ b/dom/svg/SVGTransformableElement.cpp
@@ -1,27 +1,28 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+#include "SVGTransformableElement.h"
+
+#include "DOMSVGAnimatedTransformList.h"
 #include "gfx2DGlue.h"
 #include "mozilla/dom/MutationEventBinding.h"
-#include "DOMSVGAnimatedTransformList.h"
 #include "mozilla/dom/SVGGraphicsElementBinding.h"
-#include "mozilla/dom/SVGTransformableElement.h"
 #include "mozilla/dom/SVGMatrix.h"
+#include "mozilla/dom/SVGRect.h"
 #include "mozilla/dom/SVGSVGElement.h"
 #include "nsContentUtils.h"
 #include "nsIFrame.h"
+#include "SVGContentUtils.h"
 #include "nsSVGDisplayableFrame.h"
-#include "mozilla/dom/SVGRect.h"
 #include "nsSVGUtils.h"
-#include "SVGContentUtils.h"
 
 using namespace mozilla::gfx;
 
 namespace mozilla {
 namespace dom {
 
 already_AddRefed<DOMSVGAnimatedTransformList>
 SVGTransformableElement::Transform() {
--- a/dom/svg/SVGTransformableElement.h
+++ b/dom/svg/SVGTransformableElement.h
@@ -2,21 +2,21 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef SVGTransformableElement_h
 #define SVGTransformableElement_h
 
-#include "mozilla/Attributes.h"
 #include "nsAutoPtr.h"
 #include "SVGAnimatedTransformList.h"
-#include "SVGElement.h"
 #include "gfxMatrix.h"
+#include "mozilla/Attributes.h"
+#include "mozilla/dom/SVGElement.h"
 #include "mozilla/gfx/Matrix.h"
 
 namespace mozilla {
 namespace dom {
 
 class DOMSVGAnimatedTransformList;
 class SVGGraphicsElement;
 class SVGMatrix;
--- a/dom/svg/SVGViewBoxSMILType.cpp
+++ b/dom/svg/SVGViewBoxSMILType.cpp
@@ -20,17 +20,17 @@ void SVGViewBoxSMILType::Init(nsSMILValu
   aValue.mU.mPtr = new nsSVGViewBoxRect();
   aValue.mType = this;
 }
 
 void SVGViewBoxSMILType::Destroy(nsSMILValue& aValue) const {
   MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value");
   delete static_cast<nsSVGViewBoxRect*>(aValue.mU.mPtr);
   aValue.mU.mPtr = nullptr;
-  aValue.mType = nsSMILNullType::Singleton();
+  aValue.mType = SMILNullType::Singleton();
 }
 
 nsresult SVGViewBoxSMILType::Assign(nsSMILValue& aDest,
                                     const nsSMILValue& aSrc) const {
   MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types");
   MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value");
 
   const nsSVGViewBoxRect* src =
--- a/dom/svg/SVGViewportElement.h
+++ b/dom/svg/SVGViewportElement.h
@@ -2,28 +2,28 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_SVGViewportElement_h
 #define mozilla_dom_SVGViewportElement_h
 
+#include "mozilla/Attributes.h"
 #include "mozilla/dom/FromParser.h"
 #include "nsAutoPtr.h"
 #include "nsIContentInlines.h"
 #include "nsISVGPoint.h"
+#include "SVGAnimatedPreserveAspectRatio.h"
 #include "nsSVGEnum.h"
-#include "nsSVGLength2.h"
 #include "SVGGraphicsElement.h"
 #include "SVGImageContext.h"
+#include "SVGPreserveAspectRatio.h"
+#include "nsSVGLength2.h"
 #include "nsSVGViewBox.h"
-#include "SVGPreserveAspectRatio.h"
-#include "SVGAnimatedPreserveAspectRatio.h"
-#include "mozilla/Attributes.h"
 
 class nsSVGOuterSVGFrame;
 class nsSVGViewportFrame;
 
 namespace mozilla {
 class AutoPreserveAspectRatioOverride;
 class DOMSVGAnimatedPreserveAspectRatio;
 
--- a/gfx/gl/SharedSurfaceANGLE.cpp
+++ b/gfx/gl/SharedSurfaceANGLE.cpp
@@ -93,16 +93,19 @@ SharedSurface_ANGLEShareHandle::SharedSu
     : SharedSurface(SharedSurfaceType::EGLSurfaceANGLE, AttachmentType::Screen,
                     gl, size, hasAlpha, true),
       mEGL(egl),
       mPBuffer(pbuffer),
       mShareHandle(shareHandle),
       mKeyedMutex(keyedMutex) {}
 
 SharedSurface_ANGLEShareHandle::~SharedSurface_ANGLEShareHandle() {
+  if (GLContextEGL::Cast(mGL)->GetEGLSurfaceOverride() == mPBuffer) {
+    GLContextEGL::Cast(mGL)->SetEGLSurfaceOverride(EGL_NO_SURFACE);
+  }
   mEGL->fDestroySurface(Display(), mPBuffer);
 }
 
 void SharedSurface_ANGLEShareHandle::LockProdImpl() {
   GLContextEGL::Cast(mGL)->SetEGLSurfaceOverride(mPBuffer);
 }
 
 void SharedSurface_ANGLEShareHandle::UnlockProdImpl() {}
--- a/gfx/skia/skia/src/core/SkGlyphRunPainter.cpp
+++ b/gfx/skia/skia/src/core/SkGlyphRunPainter.cpp
@@ -64,16 +64,21 @@ bool SkGlyphRunListPainter::ShouldDrawAs
         return true;
     }
 
     // we don't cache perspective
     if (matrix.hasPerspective()) {
         return true;
     }
 
+    // Glyphs like Emojis can't be rendered as a path.
+    if (paint.getTypeface() && paint.getTypeface()->hasColorGlyphs()) {
+      return false;
+    }
+
     SkMatrix textM;
     SkPaintPriv::MakeTextMatrix(&textM, paint);
     return SkPaint::TooBigToUseCache(matrix, textM, 1024);
 }
 
 bool SkGlyphRunListPainter::ensureBitmapBuffers(size_t runSize) {
     if (runSize > fMaxRunSize) {
         fPositions.reset(runSize);
--- a/js/src/jit/arm64/Assembler-arm64.h
+++ b/js/src/jit/arm64/Assembler-arm64.h
@@ -32,25 +32,33 @@ static const Scale ScalePointer = TimesE
 // For safety, scratch registers should always be acquired using
 // vixl::UseScratchRegisterScope.
 static constexpr Register ScratchReg{Registers::ip0};
 static constexpr ARMRegister ScratchReg64 = {ScratchReg, 64};
 
 static constexpr Register ScratchReg2{Registers::ip1};
 static constexpr ARMRegister ScratchReg2_64 = {ScratchReg2, 64};
 
+static constexpr FloatRegister ReturnDoubleReg = {FloatRegisters::d0,
+                                                  FloatRegisters::Double};
 static constexpr FloatRegister ScratchDoubleReg = {FloatRegisters::d31,
                                                    FloatRegisters::Double};
-static constexpr FloatRegister ReturnDoubleReg = {FloatRegisters::d0,
-                                                  FloatRegisters::Double};
+struct ScratchDoubleScope : public AutoFloatRegisterScope {
+  explicit ScratchDoubleScope(MacroAssembler& masm)
+    : AutoFloatRegisterScope(masm, ScratchDoubleReg) {}
+};
 
 static constexpr FloatRegister ReturnFloat32Reg = {FloatRegisters::s0,
                                                    FloatRegisters::Single};
 static constexpr FloatRegister ScratchFloat32Reg = {FloatRegisters::s31,
                                                     FloatRegisters::Single};
+struct ScratchFloat32Scope : public AutoFloatRegisterScope {
+  explicit ScratchFloat32Scope(MacroAssembler& masm)
+    : AutoFloatRegisterScope(masm, ScratchFloat32Reg) {}
+};
 
 static constexpr Register InvalidReg{Registers::invalid_reg};
 static constexpr FloatRegister InvalidFloatReg = {FloatRegisters::invalid_fpreg,
                                                   FloatRegisters::Single};
 
 static constexpr Register OsrFrameReg{Registers::x3};
 static constexpr Register CallTempReg0{Registers::x9};
 static constexpr Register CallTempReg1{Registers::x10};
--- a/js/src/jit/arm64/CodeGenerator-arm64.cpp
+++ b/js/src/jit/arm64/CodeGenerator-arm64.cpp
@@ -739,17 +739,52 @@ void CodeGenerator::visitUrshD(LUrshD* i
   } else {
     masm.And(temp32, toWRegister(rhs), Operand(0x1F));
     masm.Lsr(temp32, lhs, temp32);
     masm.convertUInt32ToDouble(temp, out);
   }
 }
 
 void CodeGenerator::visitPowHalfD(LPowHalfD* ins) {
-  MOZ_CRASH("visitPowHalfD");
+  FloatRegister input = ToFloatRegister(ins->input());
+  FloatRegister output = ToFloatRegister(ins->output());
+
+  ScratchDoubleScope scratch(masm);
+
+  Label done, sqrt;
+
+  if (!ins->mir()->operandIsNeverNegativeInfinity()) {
+    // Branch if not -Infinity.
+    masm.loadConstantDouble(NegativeInfinity<double>(), scratch);
+
+    Assembler::DoubleCondition cond = Assembler::DoubleNotEqualOrUnordered;
+    if (ins->mir()->operandIsNeverNaN()) {
+      cond = Assembler::DoubleNotEqual;
+    }
+    masm.branchDouble(cond, input, scratch, &sqrt);
+
+    // Math.pow(-Infinity, 0.5) == Infinity.
+    masm.zeroDouble(output);
+    masm.subDouble(scratch, output);
+    masm.jump(&done);
+
+    masm.bind(&sqrt);
+  }
+
+  if (!ins->mir()->operandIsNeverNegativeZero()) {
+    // Math.pow(-0, 0.5) == 0 == Math.pow(0, 0.5).
+    // Adding 0 converts any -0 to 0.
+    masm.zeroDouble(scratch);
+    masm.addDouble(input, scratch);
+    masm.sqrtDouble(scratch, output);
+  } else {
+    masm.sqrtDouble(input, output);
+  }
+
+  masm.bind(&done);
 }
 
 MoveOperand CodeGeneratorARM64::toMoveOperand(const LAllocation a) const {
   if (a.isGeneralReg()) {
     return MoveOperand(ToRegister(a));
   }
   if (a.isFloatReg()) {
     return MoveOperand(ToFloatRegister(a));
--- a/js/src/jit/arm64/vixl/Disasm-vixl.cpp
+++ b/js/src/jit/arm64/vixl/Disasm-vixl.cpp
@@ -3498,9 +3498,16 @@ void DisassembleInstruction(char* buffer
 {
     vixl::Disassembler disasm(buffer, bufsize-1);
     vixl::Decoder decoder;
     decoder.AppendVisitor(&disasm);
     decoder.Decode(instr);
     buffer[bufsize-1] = 0;      // Just to be safe
 }
 
+char* GdbDisassembleInstruction(const Instruction* instr)
+{
+    static char buffer[1024];
+    DisassembleInstruction(buffer, sizeof(buffer), instr);
+    return buffer;
+}
+
 }  // namespace vixl
--- a/js/src/jit/arm64/vixl/Disasm-vixl.h
+++ b/js/src/jit/arm64/vixl/Disasm-vixl.h
@@ -169,12 +169,13 @@ class PrintDisassembler: public Disassem
  protected:
   virtual void ProcessOutput(const Instruction* instr) override;
 
  private:
   FILE *stream_;
 };
 
 void DisassembleInstruction(char* buffer, size_t bufsize, const Instruction* instr);
+char* GdbDisassembleInstruction(const Instruction* instr);
 
 }  // namespace vixl
 
 #endif  // VIXL_A64_DISASM_A64_H
--- a/js/src/jit/x86-shared/CodeGenerator-x86-shared.cpp
+++ b/js/src/jit/x86-shared/CodeGenerator-x86-shared.cpp
@@ -750,18 +750,18 @@ void CodeGenerator::visitPowHalfD(LPowHa
     masm.zeroDouble(output);
     masm.subDouble(scratch, output);
     masm.jump(&done);
 
     masm.bind(&sqrt);
   }
 
   if (!ins->mir()->operandIsNeverNegativeZero()) {
-    // Math.pow(-0, 0.5) == 0 == Math.pow(0, 0.5). Adding 0 converts any -0 to
-    // 0.
+    // Math.pow(-0, 0.5) == 0 == Math.pow(0, 0.5).
+    // Adding 0 converts any -0 to 0.
     masm.zeroDouble(scratch);
     masm.addDouble(input, scratch);
     masm.vsqrtsd(scratch, output, output);
   } else {
     masm.vsqrtsd(input, output, output);
   }
 
   masm.bind(&done);
--- a/layout/style/nsDOMCSSAttrDeclaration.cpp
+++ b/layout/style/nsDOMCSSAttrDeclaration.cpp
@@ -11,17 +11,17 @@
 #include "mozilla/DeclarationBlock.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/MutationEventBinding.h"
 #include "mozilla/InternalMutationEvent.h"
 #include "mozAutoDocUpdate.h"
 #include "nsIDocument.h"
 #include "nsIURI.h"
 #include "nsNodeUtils.h"
-#include "nsSMILCSSValueType.h"
+#include "SMILCSSValueType.h"
 #include "nsWrapperCacheInlines.h"
 #include "nsIFrame.h"
 #include "ActiveLayerTracker.h"
 
 using namespace mozilla;
 
 nsDOMCSSAttributeDeclaration::nsDOMCSSAttributeDeclaration(
     dom::Element* aElement, bool aIsSMILOverride)
@@ -141,17 +141,17 @@ nsresult nsDOMCSSAttributeDeclaration::S
   RefPtr<DeclarationBlock> created;
   DeclarationBlock* olddecl =
       GetOrCreateCSSDeclaration(eOperation_Modify, getter_AddRefs(created));
   if (!olddecl) {
     return NS_ERROR_NOT_AVAILABLE;
   }
   mozAutoDocUpdate autoUpdate(DocToUpdate(), true);
   RefPtr<DeclarationBlock> decl = olddecl->EnsureMutable();
-  bool changed = nsSMILCSSValueType::SetPropertyValues(aValue, *decl);
+  bool changed = SMILCSSValueType::SetPropertyValues(aValue, *decl);
   if (changed) {
     // We can pass nullptr as the latter param, since this is
     // mIsSMILOverride == true case.
     SetCSSDeclaration(decl, nullptr);
   }
   return NS_OK;
 }
 
--- a/toolkit/content/widgets/richlistbox.xml
+++ b/toolkit/content/widgets/richlistbox.xml
@@ -10,17 +10,16 @@
 <bindings id="richlistboxBindings"
           xmlns="http://www.mozilla.org/xbl"
           xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
           xmlns:xbl="http://www.mozilla.org/xbl">
 
   <binding id="richlistbox"
            extends="chrome://global/content/bindings/general.xml#basecontrol">
     <content>
-      <children includes="listheader"/>
       <xul:scrollbox allowevents="true" orient="vertical" anonid="main-box"
                      flex="1" style="overflow: auto;" xbl:inherits="dir,pack">
         <children/>
       </xul:scrollbox>
     </content>
 
     <implementation implements="nsIDOMXULMultiSelectControlElement">
       <field name="_scrollbox">
--- a/toolkit/themes/shared/in-content/common.inc.css
+++ b/toolkit/themes/shared/in-content/common.inc.css
@@ -709,25 +709,42 @@ xul|*.radio-label-box {
   line-height: 1.3em;
   margin: 0;
   -moz-user-select: none;
 }
 
 /* List boxes */
 
 html|select[size][multiple],
+xul|listheader,
 xul|richlistbox {
   -moz-appearance: none;
-  margin-inline-start: 0;
+  margin-left: 0;
+  margin-right: 0;
   background-color: var(--in-content-box-background);
   border: 1px solid var(--in-content-box-border-color);
   border-radius: 2px;
   color: var(--in-content-text-color);
 }
 
+xul|listheader {
+  border-bottom: none;
+  border-bottom-left-radius: 0;
+  border-bottom-right-radius: 0;
+  padding-bottom: 1px;
+  box-shadow: inset 0 -1px var(--in-content-border-color);
+}
+
+xul|listheader + xul|richlistbox {
+  margin-top: 0;
+  border-top: none;
+  border-top-left-radius: 0;
+  border-top-right-radius: 0;
+}
+
 html|select[size][multiple] > html|option,
 xul|treechildren::-moz-tree-row {
   padding: 0.3em;
   margin: 0;
   border: none;
   border-radius: 0;
   background-image: none;
 }
@@ -756,17 +773,16 @@ xul|tree {
   margin: 0;
 }
 
 xul|tree:-moz-focusring,
 xul|richlistbox:-moz-focusring {
   border: 1px dotted var(--in-content-border-focus);
 }
 
-xul|listheader,
 xul|treecols {
   -moz-appearance: none;
   border: none;
   border-bottom: 1px solid var(--in-content-border-color);
   padding: 0;
 }
 
 xul|treecol:not([hideheader="true"]),