Merge mozilla-central to autoland. a=merge CLOSED TREE
authorBogdan Tara <btara@mozilla.com>
Thu, 03 Jan 2019 06:26:47 +0200
changeset 509476 6432c3a5e531482df9559b504238b1d5ed99e058
parent 509475 11a443603ee556a64fc9cbb5a2e85dbc783654ee (current diff)
parent 509447 bf8d42d3382e874fcf2d34e9932346280ac4b7eb (diff)
child 509477 ef22d23a09a8f1b18669fd48389a9fb20e999e98
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)
reviewersmerge
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. a=merge CLOSED TREE
dom/svg/nsSVGEnum.cpp
dom/svg/nsSVGEnum.h
--- 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 112
+Version 115
 
-Comparison: https://github.com/devtools-html/debugger.html/compare/release-111...release-112
+Comparison: https://github.com/devtools-html/debugger.html/compare/release-114...release-115
 
 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
@@ -240,20 +240,23 @@
 
 /******************************************************************************/
 /* Open DOMNode in inspector or Accessible in accessibility inspector button */
 
 button.open-accessibility-inspector,
 button.open-inspector {
   mask: url("resource://devtools/client/shared/components/reps/images/open-inspector.svg") no-repeat;
   display: inline-block;
+  vertical-align: top;
+  height: 15px;
+  width: 15px;
+  margin: 0 4px;
+  padding: 0;
+  border: none;
   background-color: var(--comment-node-color);
-  height: 16px;
-  margin-left: 0.25em;
-  vertical-align: middle;
   cursor: pointer;
 }
 
 .objectBox-accessible:hover .open-accessibility-inspector,
 .objectBox-node:hover .open-inspector,
 .objectBox-textNode:hover .open-inspector,
 .open-accessibility-inspector:hover,
 .open-inspector:hover {
@@ -1494,28 +1497,29 @@ html .toggle-button.end.vertical svg {
   stroke: var(--theme-comment);
 }
 
 .search-field input::placeholder {
   color: var(--theme-toolbar-color);
 }
 
 .search-field input.empty {
-  color: var(--theme-highlight-orange);
+  color: var(--theme-body-color-inactive);
 }
 
 .search-field .summary {
   line-height: 27px;
   text-align: center;
   padding-inline-start: 5px;
   padding-inline-end: 5px;
   color: var(--theme-body-color-inactive);
   align-self: center;
   padding-top: 1px;
   white-space: nowrap;
+  user-select: none;
 }
 
 .search-field .search-nav-buttons {
   display: flex;
   user-select: none;
 }
 
 .search-field .search-nav-buttons .nav-btn {
@@ -1609,16 +1613,18 @@ html .toggle-button.end.vertical svg {
   width: 100%;
   text-align: right;
   grid-column: 1/2;
 }
 
 .project-text-search .result .line-value {
   grid-column: 2/3;
   padding-left: 5px;
+  text-overflow: ellipsis;
+  overflow-x: hidden;
 }
 
 .project-text-search .tree-indent {
   display: none;
 }
 
 .project-text-search .no-result-msg {
   color: var(--theme-body-color-inactive);
@@ -1663,16 +1669,17 @@ html .toggle-button.end.vertical svg {
   overflow-y: auto;
   height: 100%;
 }
 
 .project-text-search .managed-tree .tree {
   height: 100%;
   display: grid;
   grid-template-columns: auto 1fr;
+  overflow-x: hidden;
 }
 
 .project-text-search .managed-tree .tree .tree-node {
   display: contents;
 }
 
 /* Focus values */
 
@@ -1768,32 +1775,27 @@ html .toggle-button.end.vertical svg {
 
 .sources-clear-root-label {
   margin-left: 5px;
 }
 
 .sources-pane {
   display: flex;
   flex: 1;
-  overflow-x: auto;
-  overflow-y: auto;
   height: 100%;
 }
 
 .sources-list {
   flex: 1;
   display: flex;
-  overflow: hidden;
 }
 
 .sources-list .managed-tree {
   flex: 1;
   display: flex;
-  overflow-x: hidden;
-  overflow-y: auto;
 }
 
 .sources-list .managed-tree .tree-node:first-child {
   margin-top: 4px;
 }
 
 .sources-list .managed-tree .tree .node {
   padding: 0 10px 0 3px;
@@ -2752,16 +2754,21 @@ menuseparator {
   fill-opacity: 0.5;
 }
 
 .column-breakpoint.has-condition svg {
   fill: var(--theme-graphs-yellow);
   stroke: var(--theme-graphs-orange);
 }
 
+.column-breakpoint.has-condition.log svg {
+  fill: var(--theme-graphs-orange);
+  stroke: var(--theme-graphs-yellow);
+}
+
 .theme-dark .column-breakpoint.active svg {
   fill: var(--blue-55);
   stroke: var(--blue-40);
 }
 
 .theme-dark .column-breakpoint.disabled svg {
   fill: var(--blue-50);
   stroke: var(--blue-60);
@@ -2961,16 +2968,21 @@ html[dir="rtl"] .editor-mount {
   right: -16px;
 }
 
 .new-breakpoint.has-condition .CodeMirror-gutter-wrapper svg {
   fill: var(--theme-graphs-yellow);
   stroke: var(--theme-graphs-orange);
 }
 
+.new-breakpoint.has-condition.log .CodeMirror-gutter-wrapper svg {
+  fill: var(--theme-graphs-orange);
+  stroke: var(--theme-graphs-yellow);
+}
+
 .editor.new-breakpoint.breakpoint-disabled svg {
   fill: var(--breakpoint-fill-disabled);
   stroke: var(--breakpoint-stroke-disabled);
   fill-opacity: 0.5;
 }
 
 .editor.column-breakpoint svg {
   fill: var(--theme-selection-background);
@@ -3049,32 +3061,31 @@ debug-expression-error {
   outline: var(--debug-line-error-border) solid 1px;
 }
 
 /* Don't display the highlight color since the debug line
   is already highlighted */
 .new-debug-line-error .CodeMirror-activeline-background {
   display: none;
 }
-
-.debugger:not(.can-rewind) .highlight-line .CodeMirror-line {
+.highlight-line .CodeMirror-line {
   animation: fade-highlight-out 1.5s normal forwards;
 }
 
 @keyframes fade-highlight-out {
   0% {
     background-color: var(--theme-highlight-gray);
   }
   100% {
     background-color: transparent;
   }
 }
 
 .theme-dark .highlight-line .CodeMirror-line {
-  animation: fade-highlight-out-dark 1.5s normal forwards;
+  animation: fade-highlight-out-dark 1s normal forwards;
 }
 
 @keyframes fade-highlight-out-dark {
   0% {
     background-color: var(--theme-comment);
   }
   100% {
     background-color: transparent;
@@ -3236,16 +3247,24 @@ html:not([dir="rtl"]) .breakpoints-excep
 html:not([dir="rtl"]) .breakpoints-list .breakpoint.is-conditional {
   border-left-color: var(--theme-graphs-yellow);
 }
 
 html[dir="rtl"] .breakpoints-list .breakpoint.is-conditional {
   border-right-color: var(--theme-graphs-yellow);
 }
 
+html:not([dir="rtl"]) .breakpoints-list .breakpoint.is-conditional.log {
+  border-left-color: var(--theme-graphs-orange);
+}
+
+html[dir="rtl"] .breakpoints-list .breakpoint.is-conditional.log {
+  border-right-color: var(--theme-graphs-orange);
+}
+
 html .breakpoints-list .breakpoint.paused {
   background-color: var(--theme-toolbar-background-alt);
   border-color: var(--breakpoint-active-color);
 }
 
 .breakpoints-list .breakpoint.disabled .breakpoint-label {
   color: var(--theme-comment);
   transition: color 0.15s linear;
@@ -3267,17 +3286,17 @@ html .breakpoints-list .breakpoint.pause
   text-align: right;
 }
 
 html[dir="rtl"] .breakpoints-list .breakpoint .breakpoint-line {
   text-align: left;
 }
 
 .breakpoints-list .breakpoint:hover .breakpoint-line {
-  display: none;
+  color: transparent;
 }
 
 .breakpoints-list .breakpoint.paused:hover {
   border-color: var(--breakpoint-active-color-hover);
 }
 
 .breakpoints-list .breakpoint-label {
   max-width: calc(100% - var(--breakpoint-expression-right-clear-space));
@@ -4081,19 +4100,26 @@ html[dir="rtl"] .object-node {
 }
 
 .scopes-list .scope-type-toggle {
   text-align: center;
   padding-top: 10px;
   padding-bottom: 10px;
 }
 
-.scopes-list .scope-type-toggle a {
+.scopes-list .scope-type-toggle button {
   /* Override color so that the link doesn't turn purple */
   color: var(--theme-body-color);
+  font-size: inherit;
+  text-decoration: underline;
+  cursor: pointer;
+}
+
+.scopes-list .scope-type-toggle button:hover {
+  background: transparent;
 }
 /* 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/>. */
 
 .secondary-panes {
   overflow: auto;
   display: flex;
@@ -4219,22 +4245,27 @@ html[dir="rtl"] .object-node {
 .welcomebox__searchProject:hover,
 .welcomebox__allShortcuts:hover {
   color: var(--theme-body-color);
 }
 
 .shortcutKey {
   text-align: right;
   padding-right: 10px;
-  font-family: Courier;
+  font-family: var(--monospace-font-family);
+  font-size: 14px;
+  line-height: 18px;
+  color: var(--theme-body-color);
 }
 
 .shortcutLabel {
   text-align: left;
   padding-left: 10px;
+  font-size: 14px;
+  line-height: 18px;
 }
 
 .shortcutFunction {
   margin: 0 auto;
   color: var(--theme-comment);
   display: table;
 }
 
--- a/devtools/client/debugger/new/dist/search-worker.js
+++ b/devtools/client/debugger/new/dist/search-worker.js
@@ -605,48 +605,90 @@ function getMatches(query, text, modifie
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.findSourceMatches = findSourceMatches;
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
+
+var _getMatches = __webpack_require__(1632);
 
-// Maybe reuse file search's functions?
+var _getMatches2 = _interopRequireDefault(_getMatches);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 function findSourceMatches(source, queryText) {
   const { id, loadedState, text } = source;
   if (loadedState != "loaded" || !text || queryText == "") {
     return [];
   }
 
+  const modifiers = {
+    caseSensitive: false,
+    regexMatch: false,
+    wholeWord: false
+  };
+
   const lines = text.split("\n");
-  let result = undefined;
-  const query = new RegExp(queryText, "g");
 
-  const matches = lines.map((_text, line) => {
-    const indices = [];
+  return (0, _getMatches2.default)(queryText, text, modifiers).map(({ line, ch }) => {
+    const { value, matchIndex } = truncateLine(lines[line], ch);
+    return {
+      sourceId: id,
+      line: line + 1,
+      column: ch,
+      matchIndex,
+      match: queryText,
+      value
+    };
+  });
+}
+
+// This is used to find start of a word, so that cropped string look nice
+/* 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/>. */
+
+// Maybe reuse file search's functions?
 
-    while (result = query.exec(_text)) {
-      indices.push({
-        sourceId: id,
-        line: line + 1,
-        column: result.index,
-        match: result[0],
-        value: _text
-      });
-    }
-    return indices;
-  }).filter(_matches => _matches.length > 0);
+const startRegex = /([ !@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?])/g;
+// Similarly, find
+const endRegex = new RegExp(["([ !@#$%^&*()_+-=[]{};':\"\\|,.<>/?])", '[^ !@#$%^&*()_+-=[]{};\':"\\|,.<>/?]*$"/'].join(""));
+
+function truncateLine(text, column) {
+  if (text.length < 100) {
+    return {
+      matchIndex: column,
+      value: text
+    };
+  }
 
-  return [].concat(...matches);
+  // Initially take 40 chars left to the match
+  const offset = Math.max(column - 40, 0);
+  // 400 characters should be enough to figure out the context of the match
+  const truncStr = text.slice(offset, column + 400);
+  let start = truncStr.search(startRegex);
+  let end = truncStr.search(endRegex);
+
+  if (start > column) {
+    // No word separator found before the match, so we take all characters
+    // before the match
+    start = -1;
+  }
+  if (end < column) {
+    end = truncStr.length;
+  }
+  const value = truncStr.slice(start + 1, end);
+
+  return {
+    matchIndex: column - start - offset - 1,
+    value
+  };
 }
 
 /***/ }),
 
 /***/ 259:
 /***/ (function(module, exports, __webpack_require__) {
 
 var toString = __webpack_require__(108);
--- a/devtools/client/debugger/new/src/actions/breakpoints/addBreakpoint.js
+++ b/devtools/client/debugger/new/src/actions/breakpoints/addBreakpoint.js
@@ -73,16 +73,17 @@ async function addBreakpointPromise(getS
   const text = getTextAtPosition(generatedSource, actualLocation);
 
   const newBreakpoint = {
     id,
     disabled: false,
     hidden: breakpoint.hidden,
     loading: false,
     condition: breakpoint.condition,
+    log: breakpoint.log,
     location: newLocation,
     astLocation,
     generatedLocation: newGeneratedLocation,
     text,
     originalText
   };
 
   assertBreakpoint(newBreakpoint);
@@ -145,21 +146,22 @@ export function enableBreakpoint(locatio
  * @memberof actions/breakpoints
  * @static
  * @param {String} $1.condition Conditional breakpoint condition value
  * @param {Boolean} $1.disabled Disable value for breakpoint value
  */
 
 export function addBreakpoint(
   location: SourceLocation,
-  { condition, hidden }: addBreakpointOptions = {}
+  { condition, hidden, log = false }: addBreakpointOptions = {}
 ) {
-  const breakpoint = createBreakpoint(location, { condition, hidden });
   return ({ dispatch, getState, sourceMaps, client }: ThunkArgs) => {
     recordEvent("add_breakpoint");
 
+    const breakpoint = createBreakpoint(location, { condition, hidden, log });
+
     return dispatch({
       type: "ADD_BREAKPOINT",
       breakpoint,
       [PROMISE]: addBreakpointPromise(getState, client, sourceMaps, breakpoint)
     });
   };
 }
--- a/devtools/client/debugger/new/src/actions/breakpoints/index.js
+++ b/devtools/client/debugger/new/src/actions/breakpoints/index.js
@@ -39,17 +39,18 @@ import type {
   SourceLocation,
   XHRBreakpoint
 } from "../../types";
 
 import { recordEvent } from "../../utils/telemetry";
 
 export type addBreakpointOptions = {
   condition?: string,
-  hidden?: boolean
+  hidden?: boolean,
+  log?: boolean
 };
 
 /**
  * Remove a single breakpoint
  *
  * @memberof actions/breakpoints
  * @static
  */
@@ -278,22 +279,22 @@ export function remapBreakpoints(sourceI
  * @param {SourceLocation} location
  *        @see DebuggerController.Breakpoints.addBreakpoint
  * @param {string} condition
  *        The condition to set on the breakpoint
  * @param {Boolean} $1.disabled Disable value for breakpoint value
  */
 export function setBreakpointCondition(
   location: SourceLocation,
-  { condition }: addBreakpointOptions = {}
+  { condition, log = false }: addBreakpointOptions = {}
 ) {
   return async ({ dispatch, getState, client, sourceMaps }: ThunkArgs) => {
     const bp = getBreakpoint(getState(), location);
     if (!bp) {
-      return dispatch(addBreakpoint(location, { condition }));
+      return dispatch(addBreakpoint(location, { condition, log }));
     }
 
     if (bp.loading) {
       return;
     }
 
     if (bp.disabled) {
       await dispatch(enableBreakpoint(location));
@@ -301,17 +302,17 @@ export function setBreakpointCondition(
 
     await client.setBreakpointCondition(
       bp.id,
       location,
       condition,
       isOriginalId(bp.location.sourceId)
     );
 
-    const newBreakpoint = { ...bp, disabled: false, condition };
+    const newBreakpoint = { ...bp, disabled: false, condition, log };
 
     assertBreakpoint(newBreakpoint);
 
     return dispatch(
       ({
         type: "SET_BREAKPOINT_CONDITION",
         breakpoint: newBreakpoint
       }: Action)
--- a/devtools/client/debugger/new/src/actions/debuggee.js
+++ b/devtools/client/debugger/new/src/actions/debuggee.js
@@ -1,14 +1,17 @@
 /* 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 { Action, ThunkArgs } from "./types";
+import { closeTabsForMissingThreads } from "./tabs";
 
 export function updateWorkers() {
-  return async function({ dispatch, client }: ThunkArgs) {
+  return async function({ dispatch, getState, client }: ThunkArgs) {
     const { workers } = await client.fetchWorkers();
     dispatch(({ type: "SET_WORKERS", workers }: Action));
+
+    dispatch(closeTabsForMissingThreads(workers));
   };
 }
--- a/devtools/client/debugger/new/src/actions/sources/newSources.js
+++ b/devtools/client/debugger/new/src/actions/sources/newSources.js
@@ -58,19 +58,19 @@ function loadSourceMaps(sources: Source[
     }
 
     const sourceList = await Promise.all(
       sources.map(async ({ id }) => {
         const originalSources = await dispatch(loadSourceMap(id));
         sourceQueue.queueSources(originalSources);
         return originalSources;
       })
-    )
+    );
 
-    await sourceQueue.flush()
+    await sourceQueue.flush();
     return flatten(sourceList);
   };
 }
 
 /**
  * @memberof actions/sources
  * @static
  */
--- a/devtools/client/debugger/new/src/actions/tabs.js
+++ b/devtools/client/debugger/new/src/actions/tabs.js
@@ -12,23 +12,26 @@
 import { isOriginalId } from "devtools-source-map";
 
 import { removeDocument } from "../utils/editor";
 import { selectSource } from "./sources";
 
 import {
   getSourcesByURLs,
   getSourceTabs,
+  getSourceFromId,
   getNewSelectedSourceId,
   removeSourceFromTabList,
   removeSourcesFromTabList
 } from "../selectors";
 
+import { getMainThread } from "../reducers/pause";
+
 import type { Action, ThunkArgs } from "./types";
-import type { Source } from "../types";
+import type { Source, Worker } from "../types";
 
 export function updateTab(source: Source, framework: string): Action {
   const { url, id: sourceId, thread } = source;
   const isOriginal = isOriginalId(source.id);
 
   return {
     type: "UPDATE_TAB",
     url,
@@ -88,8 +91,32 @@ export function closeTabs(urls: string[]
 
     const tabs = removeSourcesFromTabList(getSourceTabs(getState()), sources);
     dispatch(({ type: "CLOSE_TABS", sources, tabs }: Action));
 
     const sourceId = getNewSelectedSourceId(getState(), tabs);
     dispatch(selectSource(sourceId));
   };
 }
+
+export function closeTabsForMissingThreads(workers: Worker[]) {
+  return ({ dispatch, getState }: ThunkArgs) => {
+    const oldTabs = getSourceTabs(getState());
+    const mainThread = getMainThread(getState());
+    const removed = [];
+    for (const { sourceId } of oldTabs) {
+      if (sourceId) {
+        const source = getSourceFromId(getState(), sourceId);
+        if (
+          source.thread != mainThread &&
+          !workers.some(({ actor }) => actor == source.thread)
+        ) {
+          removed.push(source);
+        }
+      }
+    }
+    const tabs = removeSourcesFromTabList(oldTabs, removed);
+    dispatch({ type: "CLOSE_TABS", removed, tabs });
+
+    const sourceId = getNewSelectedSourceId(getState(), tabs);
+    dispatch(selectSource(sourceId));
+  };
+}
--- a/devtools/client/debugger/new/src/actions/ui.js
+++ b/devtools/client/debugger/new/src/actions/ui.js
@@ -151,24 +151,28 @@ export function flashLineRange(location:
  * @static
  */
 export function clearHighlightLineRange() {
   return {
     type: "CLEAR_HIGHLIGHT_LINES"
   };
 }
 
-export function openConditionalPanel(location: ?SourceLocation) {
+export function openConditionalPanel(
+  location: ?SourceLocation,
+  log: boolean = false
+) {
   if (!location) {
     return;
   }
 
   return {
     type: "OPEN_CONDITIONAL_PANEL",
-    location
+    location,
+    log
   };
 }
 
 export function closeConditionalPanel() {
   return {
     type: "CLOSE_CONDITIONAL_PANEL"
   };
 }
--- a/devtools/client/debugger/new/src/client/chrome/create.js
+++ b/devtools/client/debugger/new/src/client/chrome/create.js
@@ -22,23 +22,28 @@ export function fromServerLocation(
 
 export function toServerLocation(location: SourceLocation): ServerLocation {
   return {
     scriptId: location.sourceId,
     lineNumber: location.line - 1
   };
 }
 
-export function createFrame(frame: any): ChromeFrame {
+export function createFrame(frame: any): ?ChromeFrame {
+  const location = fromServerLocation(frame.location);
+  if (!location) {
+    return null;
+  }
+
   return {
     id: frame.callFrameId,
     displayName: frame.functionName,
     scopeChain: frame.scopeChain,
-    generatedLocation: frame.location,
-    location: fromServerLocation(frame.location)
+    generatedLocation: location,
+    location
   };
 }
 
 export function createLoadedObject(
   serverObject: any,
   parentId: string
 ): LoadedObject {
   const { value, name } = serverObject;
--- a/devtools/client/debugger/new/src/client/chrome/events.js
+++ b/devtools/client/debugger/new/src/client/chrome/events.js
@@ -1,26 +1,28 @@
 /* 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 { createFrame, createLoadedObject } from "./create";
+import sourceQueue from "../../utils/source-queue";
 
 let actions;
 let pageAgent;
 let clientType;
 let runtimeAgent;
 
 function setupEvents(dependencies: any) {
   actions = dependencies.actions;
   pageAgent = dependencies.Page;
   clientType = dependencies.clientType;
   runtimeAgent = dependencies.Runtime;
+  sourceQueue.initialize(actions);
 }
 
 // Debugger Events
 function scriptParsed({
   scriptId,
   url,
   startLine,
   startColumn,
@@ -69,18 +71,17 @@ async function paused({
     objectId
   });
 
   const loadedObjects = result.map(createLoadedObject);
 
   if (clientType == "chrome") {
     pageAgent.configureOverlay({ message: "Paused in debugger.html" });
   }
-
-  await actions.paused({ frame, why, frames, loadedObjects });
+  await actions.paused({ thread: "root", frame, why, frames, loadedObjects });
 }
 
 function resumed() {
   if (clientType == "chrome") {
     pageAgent.configureOverlay({ suspended: false });
   }
 
   actions.resumed();
--- a/devtools/client/debugger/new/src/client/firefox/commands.js
+++ b/devtools/client/debugger/new/src/client/firefox/commands.js
@@ -401,54 +401,41 @@ async function createSources(client: Thr
   const { sources } = await client.getSources();
   return (
     sources &&
     sources.map(packet => createSource(client.actor, packet, { supportsWasm }))
   );
 }
 
 async function fetchSources(): Promise<any[]> {
-  let sources = await createSources(threadClient);
+  const sources = await createSources(threadClient);
 
   // NOTE: this happens when we fetch sources and then immediately navigate
   if (!sources) {
     return [];
   }
 
-  if (features.windowlessWorkers) {
-    // Also fetch sources from any workers.
-    workerClients = await updateWorkerClients({
-      threadClient,
-      debuggerClient,
-      tabTarget,
-      workerClients
-    });
-
-    const workerNames = Object.getOwnPropertyNames(workerClients);
-    workerNames.forEach(actor => {
-      const workerSources = createSources(workerClients[actor].thread);
-      if (workerSources) {
-        sources = sources.concat(workerSources);
-      }
-    });
-  }
-
   return sources;
 }
 
 async function fetchWorkers(): Promise<{ workers: Worker[] }> {
   if (features.windowlessWorkers) {
     workerClients = await updateWorkerClients({
       tabTarget,
       debuggerClient,
       threadClient,
       workerClients
     });
 
     const workerNames = Object.getOwnPropertyNames(workerClients);
+
+    workerNames.forEach(actor => {
+      createSources(workerClients[actor].thread);
+    });
+
     return {
       workers: workerNames.map(actor =>
         createWorker(actor, workerClients[actor].url)
       )
     };
   }
 
   if (!supportsWorkers(tabTarget)) {
--- a/devtools/client/debugger/new/src/components/Editor/Breakpoint.js
+++ b/devtools/client/debugger/new/src/components/Editor/Breakpoint.js
@@ -56,17 +56,21 @@ class Breakpoint extends PureComponent<P
     editor.codeMirror.setGutterMarker(
       line,
       "breakpoints",
       makeMarker(breakpoint.disabled)
     );
 
     editor.codeMirror.addLineClass(line, "line", "new-breakpoint");
     if (breakpoint.condition) {
-      editor.codeMirror.addLineClass(line, "line", "has-condition");
+      if (breakpoint.log) {
+        editor.codeMirror.addLineClass(line, "line", "has-condition log");
+      } else {
+        editor.codeMirror.addLineClass(line, "line", "has-condition");
+      }
     } else {
       editor.codeMirror.removeLineClass(line, "line", "has-condition");
     }
   };
 
   componentDidMount() {
     this.addBreakpoint();
   }
--- a/devtools/client/debugger/new/src/components/Editor/ConditionalPanel.js
+++ b/devtools/client/debugger/new/src/components/Editor/ConditionalPanel.js
@@ -1,31 +1,34 @@
 /* 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 React, { PureComponent } from "react";
 import ReactDOM from "react-dom";
 import { connect } from "../../utils/connect";
+import classNames from "classnames";
 import "./ConditionalPanel.css";
 import { toEditorLine } from "../../utils/editor";
 import actions from "../../actions";
 
 import {
   getBreakpointForLocation,
-  getConditionalPanelLocation
+  getConditionalPanelLocation,
+  getLogPointStatus
 } from "../../selectors";
 
 import type { SourceLocation } from "../../types";
 
 type Props = {
   breakpoint: ?Object,
   setBreakpointCondition: Function,
   location: SourceLocation,
+  log: boolean,
   editor: Object,
   openConditionalPanel: typeof actions.openConditionalPanel,
   closeConditionalPanel: typeof actions.closeConditionalPanel
 };
 
 export class ConditionalPanel extends PureComponent<Props> {
   cbPanel: null | Object;
   input: ?HTMLInputElement;
@@ -55,18 +58,21 @@ export class ConditionalPanel extends Pu
     if (e.key === "Enter") {
       this.saveAndClose();
     } else if (e.key === "Escape") {
       this.props.closeConditionalPanel();
     }
   };
 
   setBreakpoint(condition: string) {
-    const { location } = this.props;
-    return this.props.setBreakpointCondition(location, { condition });
+    const { location, log } = this.props;
+    if (log) {
+      condition = `console.log(${condition})`;
+    }
+    return this.props.setBreakpointCondition(location, { condition, log });
   }
 
   clearConditionalPanel() {
     if (this.cbPanel) {
       this.cbPanel.clear();
       this.cbPanel = null;
     }
     if (this.scrollParent) {
@@ -132,30 +138,43 @@ export class ConditionalPanel extends Pu
       if (this.scrollParent) {
         this.scrollParent.addEventListener("scroll", this.repositionOnScroll);
         this.repositionOnScroll();
       }
     }
   }
 
   renderConditionalPanel(props: Props) {
-    const { breakpoint } = props;
-    const condition = breakpoint ? breakpoint.condition : "";
+    const { breakpoint, log } = props;
+    let condition = breakpoint ? breakpoint.condition : "";
+
+    if (log) {
+      if (condition && condition.match(/^console.log\(.*\)$/)) {
+        condition = condition.match(/^console.log\((.*)\)/)[1];
+      }
+    }
+
     const panel = document.createElement("div");
     ReactDOM.render(
       <div
-        className="conditional-breakpoint-panel"
+        className={classNames("conditional-breakpoint-panel", {
+          "log-point": log
+        })}
         onClick={() => this.keepFocusOnInput()}
         onBlur={this.props.closeConditionalPanel}
         ref={node => (this.panelNode = node)}
       >
         <div className="prompt">ยป</div>
         <input
           defaultValue={condition}
-          placeholder={L10N.getStr("editor.conditionalPanel.placeholder")}
+          placeholder={L10N.getStr(
+            log
+              ? "editor.conditionalPanel.logPoint.placeholder"
+              : "editor.conditionalPanel.placeholder"
+          )}
           onKeyDown={this.onKey}
           ref={input => {
             this.input = input;
             this.keepFocusOnInput();
           }}
         />
       </div>,
       panel
@@ -165,20 +184,21 @@ export class ConditionalPanel extends Pu
 
   render() {
     return null;
   }
 }
 
 const mapStateToProps = state => {
   const location = getConditionalPanelLocation(state);
-
+  const log = getLogPointStatus(state);
   return {
     breakpoint: getBreakpointForLocation(state, location),
-    location
+    location,
+    log
   };
 };
 
 const {
   setBreakpointCondition,
   openConditionalPanel,
   closeConditionalPanel
 } = actions;
--- a/devtools/client/debugger/new/src/components/Editor/GutterMenu.js
+++ b/devtools/client/debugger/new/src/components/Editor/GutterMenu.js
@@ -1,16 +1,17 @@
 /* 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 { Component } from "react";
 import { showMenu } from "devtools-contextmenu";
 import { connect } from "../../utils/connect";
 import { lineAtHeight } from "../../utils/editor";
+import { features } from "../../utils/prefs";
 import {
   getContextMenu,
   getEmptyLines,
   getSelectedLocation,
   getSelectedSource,
   getVisibleBreakpoints,
   isPaused as getIsPaused
 } from "../../selectors";
@@ -39,27 +40,35 @@ export function gutterMenu({
   event.stopPropagation();
   event.preventDefault();
 
   const gutterItems = {
     addBreakpoint: {
       id: "node-menu-add-breakpoint",
       label: L10N.getStr("editor.addBreakpoint")
     },
+    addLogPoint: {
+      id: "node-menu-add-log-point",
+      label: L10N.getStr("editor.addLogPoint")
+    },
     addConditional: {
       id: "node-menu-add-conditional-breakpoint",
       label: L10N.getStr("editor.addConditionalBreakpoint")
     },
     removeBreakpoint: {
       id: "node-menu-remove-breakpoint",
       label: L10N.getStr("editor.removeBreakpoint")
     },
+    editLogPoint: {
+      id: "node-menu-edit-log-point",
+      label: L10N.getStr("editor.editLogPoint")
+    },
     editConditional: {
       id: "node-menu-edit-conditional-breakpoint",
-      label: L10N.getStr("editor.editBreakpoint")
+      label: L10N.getStr("editor.editConditionalBreakpoint")
     },
     enableBreakpoint: {
       id: "node-menu-enable-breakpoint",
       label: L10N.getStr("editor.enableBreakpoint")
     },
     disableBreakpoint: {
       id: "node-menu-disable-breakpoint",
       label: L10N.getStr("editor.disableBreakpoint")
@@ -78,31 +87,50 @@ export function gutterMenu({
       if (isCbPanelOpen) {
         closeConditionalPanel();
       }
     },
     accelerator: L10N.getStr("toggleBreakpoint.key"),
     ...(breakpoint ? gutterItems.removeBreakpoint : gutterItems.addBreakpoint)
   };
 
+  const logPoint = {
+    accesskey: L10N.getStr("editor.addLogPoint.accesskey"),
+    disabled: false,
+    click: () =>
+      openConditionalPanel(
+        breakpoint ? breakpoint.location : { line, column, sourceId },
+        true
+      ),
+    accelerator: L10N.getStr("toggleCondPanel.key"),
+    ...(breakpoint && breakpoint.condition
+      ? gutterItems.editLogPoint
+      : gutterItems.addLogPoint)
+  };
+
   const conditionalBreakpoint = {
     accesskey: L10N.getStr("editor.addConditionalBreakpoint.accesskey"),
     disabled: false,
     // Leaving column undefined so pause points can be detected
     click: () =>
       openConditionalPanel(
         breakpoint ? breakpoint.location : { line, column, sourceId }
       ),
     accelerator: L10N.getStr("toggleCondPanel.key"),
     ...(breakpoint && breakpoint.condition
       ? gutterItems.editConditional
       : gutterItems.addConditional)
   };
 
-  const items = [toggleBreakpointItem, conditionalBreakpoint];
+  let items = [toggleBreakpointItem, conditionalBreakpoint, logPoint];
+
+  if (breakpoint && breakpoint.condition) {
+    const remove = breakpoint.log ? conditionalBreakpoint : logPoint;
+    items = items.filter(item => item !== remove);
+  }
 
   if (isPaused) {
     const continueToHereItem = {
       accesskey: L10N.getStr("editor.continueToHere.accesskey"),
       disabled: false,
       click: () => continueToHere(line, column),
       ...gutterItems.continueToHere
     };
@@ -146,18 +174,20 @@ class GutterContextMenuComponent extends
     const column = props.editor.codeMirror.coordsChar({
       left: event.x,
       top: event.y
     }).ch;
     const breakpoint = nextProps.breakpoints.find(
       bp => bp.location.line === line && bp.location.column === column
     );
 
-    if (props.emptyLines && props.emptyLines.includes(line)) {
-      return;
+    // Allow getFirstVisiblePausePoint to find the best first breakpoint
+    // position by not providing an explicit column number
+    if (features.columnBreakpoints && !breakpoint && column === 0) {
+      column = undefined;
     }
 
     gutterMenu({ event, sourceId, line, column, breakpoint, ...props });
   }
 
   render() {
     return null;
   }
--- a/devtools/client/debugger/new/src/components/Editor/SearchBar.js
+++ b/devtools/client/debugger/new/src/components/Editor/SearchBar.js
@@ -226,17 +226,17 @@ class SearchBar extends Component<Props,
       query
     } = this.props;
 
     if (query.trim() == "") {
       return "";
     }
 
     if (count == 0) {
-      return L10N.getStr("editor.noResults");
+      return L10N.getStr("editor.noResultsFound");
     }
 
     if (index == -1) {
       return L10N.getFormatStr("sourceSearch.resultsSummary1", count);
     }
 
     return L10N.getFormatStr("editor.searchResults", matchIndex + 1, count);
   }
--- a/devtools/client/debugger/new/src/components/Editor/index.js
+++ b/devtools/client/debugger/new/src/components/Editor/index.js
@@ -428,24 +428,33 @@ class Editor extends PureComponent<Props
       jumpToMappedLocation(sourceLocation);
     }
   }
 
   toggleConditionalPanel = line => {
     const {
       conditionalPanelLocation,
       closeConditionalPanel,
-      openConditionalPanel
+      openConditionalPanel,
+      selectedSource
     } = this.props;
 
     if (conditionalPanelLocation) {
       return closeConditionalPanel();
     }
 
-    return openConditionalPanel(conditionalPanelLocation);
+    if (!selectedSource) {
+      return;
+    }
+
+    return openConditionalPanel({
+      line: line,
+      sourceId: selectedSource.id,
+      sourceUrl: selectedSource.url
+    });
   };
 
   closeConditionalPanel = () => {
     return this.props.closeConditionalPanel();
   };
 
   shouldScrollToLocation(nextProps) {
     const { selectedLocation, selectedSource } = this.props;
--- a/devtools/client/debugger/new/src/components/PrimaryPanes/SourcesTree.js
+++ b/devtools/client/debugger/new/src/components/PrimaryPanes/SourcesTree.js
@@ -189,17 +189,16 @@ class SourcesTree extends Component<Prop
   };
 
   onCollapse = (item: Item, expandedState: Set<string>) => {
     this.props.setExpandedState(this.props.thread, expandedState);
   };
 
   onKeyDown = (e: KeyboardEvent) => {
     const { focused } = this.props;
-
     if (e.keyCode === 13 && focused) {
       this.selectItem(focused);
     }
   };
 
   isEmpty() {
     const { sourceTree } = this.state;
     return sourceTree.contents.length === 0;
--- a/devtools/client/debugger/new/src/components/PrimaryPanes/index.js
+++ b/devtools/client/debugger/new/src/components/PrimaryPanes/index.js
@@ -1,24 +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 React, { Component } from "react";
+import { sortBy } from "lodash";
 import { connect } from "../../utils/connect";
 import { Tab, Tabs, TabList, TabPanels } from "react-aria-components/src/tabs";
 import { formatKeyShortcut } from "../../utils/text";
 import actions from "../../actions";
 import {
   getRelativeSources,
   getActiveSearch,
   getSelectedPrimaryPaneTab,
-  getWorkerDisplayName
+  getWorkerDisplayName,
+  isValidThread
 } from "../../selectors";
 import { features, prefs } from "../../utils/prefs";
 import "./Sources.css";
 import classnames from "classnames";
 
 import Outline from "./Outline";
 import SourcesTree from "./SourcesTree";
 
@@ -32,17 +34,18 @@ type State = {
 type Props = {
   selectedTab: SelectedPrimaryPaneTabType,
   sources: SourcesMapByThread,
   horizontal: boolean,
   sourceSearchOn: boolean,
   setPrimaryPaneTab: typeof actions.setPrimaryPaneTab,
   setActiveSearch: typeof actions.setActiveSearch,
   closeActiveSearch: typeof actions.closeActiveSearch,
-  getWorkerDisplayName: string => string
+  getWorkerDisplayName: string => string,
+  isValidThread: string => boolean
 };
 
 class PrimaryPanes extends Component<Props, State> {
   constructor(props: Props) {
     super(props);
 
     this.state = {
       alphabetizeOutline: prefs.alphabetizeOutline
@@ -89,23 +92,23 @@ class PrimaryPanes extends Component<Pro
         key="outline-tab"
       >
         {outline}
       </Tab>
     ];
   }
 
   renderThreadSources() {
-    const threads = Object.getOwnPropertyNames(this.props.sources);
-    threads.sort(
-      (a, b) =>
-        this.props.getWorkerDisplayName(a) > this.props.getWorkerDisplayName(b)
-          ? 1
-          : -1
+    const threads = sortBy(
+      Object.getOwnPropertyNames(this.props.sources).filter(
+        this.props.isValidThread
+      ),
+      this.props.getWorkerDisplayName
     );
+
     return threads.map(thread => <SourcesTree thread={thread} key={thread} />);
   }
 
   render() {
     const { selectedTab } = this.props;
     const activeIndex = selectedTab === "sources" ? 0 : 1;
 
     return (
@@ -128,17 +131,18 @@ class PrimaryPanes extends Component<Pro
     );
   }
 }
 
 const mapStateToProps = state => ({
   selectedTab: getSelectedPrimaryPaneTab(state),
   sources: getRelativeSources(state),
   sourceSearchOn: getActiveSearch(state) === "source",
-  getWorkerDisplayName: thread => getWorkerDisplayName(state, thread)
+  getWorkerDisplayName: thread => getWorkerDisplayName(state, thread),
+  isValidThread: thread => isValidThread(state, thread)
 });
 
 const connector = connect(
   mapStateToProps,
   {
     setPrimaryPaneTab: actions.setPrimaryPaneTab,
     setActiveSearch: actions.setActiveSearch,
     closeActiveSearch: actions.closeActiveSearch
--- a/devtools/client/debugger/new/src/components/ProjectSearch.js
+++ b/devtools/client/debugger/new/src/components/ProjectSearch.js
@@ -34,16 +34,17 @@ import type { StatusType } from "../redu
 
 import "./ProjectSearch.css";
 
 export type Match = {
   type: "MATCH",
   sourceId: string,
   line: number,
   column: number,
+  matchIndex: number,
   match: string,
   value: string,
   text: string
 };
 
 type Result = {
   type: "RESULT",
   filepath: string,
@@ -258,24 +259,25 @@ export class ProjectSearch extends Compo
     return this.renderMatch(item, focused);
   };
 
   renderResults = () => {
     const { status, results } = this.props;
     if (!this.props.query) {
       return;
     }
-    if (results.length && status === statusType.done) {
+    if (results.length) {
       return (
         <ManagedTree
           getRoots={() => results}
           getChildren={file => file.matches || []}
           itemHeight={24}
           autoExpandAll={true}
           autoExpandDepth={1}
+          autoExpandNodeChildrenLimit={100}
           getParent={item => null}
           getPath={getFilePath}
           renderItem={this.renderItem}
         />
       );
     }
     const msg =
       status === statusType.fetching
--- a/devtools/client/debugger/new/src/components/SecondaryPanes/Breakpoints/Breakpoint.js
+++ b/devtools/client/debugger/new/src/components/SecondaryPanes/Breakpoints/Breakpoint.js
@@ -130,41 +130,44 @@ class Breakpoint extends PureComponent<P
     const node = document.createElement("div");
     editor.CodeMirror.runMode(text, "application/javascript", node);
     return { __html: node.innerHTML };
   }
 
   /* eslint-disable react/no-danger */
   render() {
     const { breakpoint } = this.props;
-
     return (
       <div
         className={classnames({
           breakpoint,
           paused: this.isCurrentlyPausedAtBreakpoint(),
           disabled: breakpoint.disabled,
-          "is-conditional": !!breakpoint.condition
+          "is-conditional": !!breakpoint.condition,
+          log: breakpoint.log
         })}
         onClick={this.selectBreakpoint}
         onDoubleClick={this.onDoubleClick}
         onContextMenu={this.onContextMenu}
       >
         <input
+          id={breakpoint.id}
           type="checkbox"
           className="breakpoint-checkbox"
           checked={!breakpoint.disabled}
           onChange={this.handleBreakpointCheckbox}
           onClick={ev => ev.stopPropagation()}
         />
         <label
+          htmlFor={breakpoint.id}
           className="breakpoint-label cm-s-mozilla"
           title={this.getBreakpointText()}
-          dangerouslySetInnerHTML={this.highlightText()}
-        />
+        >
+          <span dangerouslySetInnerHTML={this.highlightText()} />
+        </label>
         <div className="breakpoint-line-close">
           <div className="breakpoint-line">{this.getBreakpointLocation()}</div>
           <CloseButton
             handleClick={e => this.removeBreakpoint(e)}
             tooltip={L10N.getStr("breakpoints.removeBreakpointTooltip")}
           />
         </div>
       </div>
--- a/devtools/client/debugger/new/src/components/SecondaryPanes/Expressions.js
+++ b/devtools/client/debugger/new/src/components/SecondaryPanes/Expressions.js
@@ -272,17 +272,17 @@ class Expressions extends Component<Prop
           })}
         </datalist>
       );
     }
     return <datalist id="autocomplete-matches" />;
   }
 
   renderNewExpressionInput() {
-    const { expressionError, showInput } = this.props;
+    const { expressionError } = this.props;
     const { editing, inputValue, focused } = this.state;
     const error = editing === false && expressionError === true;
     const placeholder: string = error
       ? L10N.getStr("expressions.errorMsg")
       : L10N.getStr("expressions.placeholder");
 
     return (
       <li
@@ -292,17 +292,16 @@ class Expressions extends Component<Prop
           <input
             className="input-expression"
             type="text"
             placeholder={placeholder}
             onChange={this.handleChange}
             onBlur={this.hideInput}
             onKeyDown={this.handleKeyDown}
             onFocus={this.onFocus}
-            autoFocus={showInput}
             value={!editing ? inputValue : ""}
             ref={c => (this._input = c)}
             {...features.autocompleteExpression && {
               list: "autocomplete-matches"
             }}
           />
           {this.renderAutoCompleteMatches()}
           <input type="submit" style={{ display: "none" }} />
--- a/devtools/client/debugger/new/src/components/SecondaryPanes/Scopes.js
+++ b/devtools/client/debugger/new/src/components/SecondaryPanes/Scopes.js
@@ -120,27 +120,26 @@ class Scopes extends PureComponent<Props
             dimTopLevelWindow={true}
             openLink={openLink}
             createObjectClient={grip => createObjectClient(grip)}
             onDOMNodeClick={grip => openElementInInspector(grip)}
             onInspectIconClick={grip => openElementInInspector(grip)}
           />
           {originalScopes ? (
             <div className="scope-type-toggle">
-              <a
-                href=""
+              <button
                 onClick={e => {
                   e.preventDefault();
                   this.setState({ showOriginal: !showOriginal });
                 }}
               >
                 {showOriginal
                   ? L10N.getStr("scopes.toggleToGenerated")
                   : L10N.getStr("scopes.toggleToOriginal")}
-              </a>
+              </button>
             </div>
           ) : null}
         </div>
       );
     }
 
     let stateText = L10N.getStr("scopes.notPaused");
     if (isPaused) {
--- a/devtools/client/debugger/new/src/components/SecondaryPanes/XHRBreakpoints.js
+++ b/devtools/client/debugger/new/src/components/SecondaryPanes/XHRBreakpoints.js
@@ -126,33 +126,31 @@ class XHRBreakpoints extends Component<P
       inputMethod: method,
       editing: true,
       editIndex: index
     });
   };
 
   renderXHRInput(onSubmit) {
     const { focused, inputValue } = this.state;
-    const { showInput } = this.props;
     const placeholder = L10N.getStr("xhrBreakpoints.placeholder");
 
     return (
       <li
         className={classnames("xhr-input-container", { focused })}
         key="xhr-input"
       >
         <form className="xhr-input-form" onSubmit={onSubmit}>
           <input
             className="xhr-input"
             type="text"
             placeholder={placeholder}
             onChange={this.handleChange}
             onBlur={this.hideInput}
             onFocus={this.onFocus}
-            autoFocus={showInput}
             value={inputValue}
             ref={c => (this._input = c)}
           />
           <input type="submit" style={{ display: "none" }} />
         </form>
       </li>
     );
   }
--- a/devtools/client/debugger/new/src/components/SecondaryPanes/index.js
+++ b/devtools/client/debugger/new/src/components/SecondaryPanes/index.js
@@ -189,17 +189,17 @@ class SecondaryPanes extends Component<P
         evt => {
           if (prefs.expressionsVisible) {
             evt.stopPropagation();
           }
           this.setState({ showXHRInput: true });
         },
         "plus",
         "plus",
-        L10N.getStr("xhrBreakpoints.placeholder")
+        L10N.getStr("xhrBreakpoints.label")
       )
     );
 
     return buttons;
   }
 
   getScopeItem(): AccordionPaneItem {
     return {
--- a/devtools/client/debugger/new/src/components/shared/Accordion.js
+++ b/devtools/client/debugger/new/src/components/shared/Accordion.js
@@ -57,17 +57,17 @@ class Accordion extends Component<Props,
       this.handleHeaderClick(i);
     }
   }
 
   renderContainer = (item: AccordionItem, i: number) => {
     const { opened } = item;
 
     return (
-      <li role="listitem" className={item.className} key={i}>
+      <li className={item.className} key={i}>
         <h2
           className="_header"
           tabIndex="0"
           onKeyDown={e => this.onHandleHeaderKeyDown(e, i)}
           onClick={() => this.handleHeaderClick(i)}
         >
           <Svg name="arrow" className={opened ? "expanded" : ""} />
           {item.header}
@@ -82,16 +82,16 @@ class Accordion extends Component<Props,
             {cloneElement(item.component, item.componentProps || {})}
           </div>
         )}
       </li>
     );
   };
   render() {
     return (
-      <ul role="list" className="accordion">
+      <ul className="accordion">
         {this.props.items.map(this.renderContainer)}
       </ul>
     );
   }
 }
 
 export default Accordion;
--- a/devtools/client/debugger/new/src/components/shared/SearchInput.js
+++ b/devtools/client/debugger/new/src/components/shared/SearchInput.js
@@ -99,17 +99,17 @@ class SearchInput extends Component<Prop
 
       // omit prefix @:# from being selected
       const selectStartPos = this.props.hasPrefix ? 1 : 0;
       input.setSelectionRange(selectStartPos, input.value.length + 1);
     }
   }
 
   renderSvg() {
-    const svgName = this.props.showErrorEmoji ? "sad-face" : "magnifying-glass";
+    const svgName = "magnifying-glass";
     return <Svg name={svgName} />;
   }
 
   renderArrowButtons() {
     const { handleNext, handlePrev } = this.props;
 
     return [
       arrowBtn(
--- a/devtools/client/debugger/new/src/reducers/debuggee.js
+++ b/devtools/client/debugger/new/src/reducers/debuggee.js
@@ -9,16 +9,17 @@
  * @module reducers/debuggee
  */
 
 import { List } from "immutable";
 import type { Record } from "../utils/makeRecord";
 import type { Worker } from "../types";
 import type { Action } from "../actions/types";
 import makeRecord from "../utils/makeRecord";
+import { getMainThread } from "./pause";
 
 export type WorkersList = List<Worker>;
 
 type DebuggeeState = {
   workers: WorkersList
 };
 
 export const createDebuggeeState: () => Record<DebuggeeState> = makeRecord({
@@ -45,9 +46,21 @@ export const getWorkerDisplayName = (sta
     if (actor == thread) {
       return `Worker #${index}`;
     }
     index++;
   }
   return "";
 };
 
+export const isValidThread = (state: OuterState, thread: string) => {
+  if (thread == getMainThread((state: any))) {
+    return true;
+  }
+  for (const { actor } of state.debuggee.workers) {
+    if (actor == thread) {
+      return true;
+    }
+  }
+  return false;
+};
+
 type OuterState = { debuggee: DebuggeeState };
--- a/devtools/client/debugger/new/src/reducers/ui.js
+++ b/devtools/client/debugger/new/src/reducers/ui.js
@@ -35,29 +35,31 @@ export type UIState = {
   frameworkGroupingOn: boolean,
   orientation: OrientationType,
   viewport: ?Viewport,
   highlightedLineRange?: {
     start?: number,
     end?: number,
     sourceId?: number
   },
-  conditionalPanelLocation: null | SourceLocation
+  conditionalPanelLocation: null | SourceLocation,
+  isLogPoint: boolean
 };
 
 export const createUIState: () => Record<UIState> = makeRecord({
   selectedPrimaryPaneTab: "sources",
   activeSearch: null,
   contextMenu: {},
   shownSource: null,
   startPanelCollapsed: prefs.startPanelCollapsed,
   endPanelCollapsed: prefs.endPanelCollapsed,
   frameworkGroupingOn: prefs.frameworkGroupingOn,
   highlightedLineRange: undefined,
   conditionalPanelLocation: null,
+  isLogPoint: false,
   orientation: "horizontal",
   viewport: null
 });
 
 function update(
   state: Record<UIState> = createUIState(),
   action: Action
 ): Record<UIState> {
@@ -103,17 +105,19 @@ function update(
 
       return state.set("highlightedLineRange", lineRange);
 
     case "CLOSE_QUICK_OPEN":
     case "CLEAR_HIGHLIGHT_LINES":
       return state.set("highlightedLineRange", {});
 
     case "OPEN_CONDITIONAL_PANEL":
-      return state.set("conditionalPanelLocation", action.location);
+      return state
+        .set("conditionalPanelLocation", action.location)
+        .set("isLogPoint", action.log);
 
     case "CLOSE_CONDITIONAL_PANEL":
       return state.set("conditionalPanelLocation", null);
 
     case "SET_PRIMARY_PANE_TAB":
       return state.set("selectedPrimaryPaneTab", action.tabName);
 
     case "CLOSE_PROJECT_SEARCH": {
@@ -179,16 +183,20 @@ export function getHighlightedLineRange(
 }
 
 export function getConditionalPanelLocation(
   state: OuterState
 ): null | SourceLocation {
   return state.ui.get("conditionalPanelLocation");
 }
 
+export function getLogPointStatus(state: OuterState): boolean {
+  return state.ui.get("isLogPoint");
+}
+
 export function getOrientation(state: OuterState): OrientationType {
   return state.ui.get("orientation");
 }
 
 export function getViewport(state: OuterState) {
   return state.ui.get("viewport");
 }
 
--- a/devtools/client/debugger/new/src/selectors/breakpointSources.js
+++ b/devtools/client/debugger/new/src/selectors/breakpointSources.js
@@ -25,31 +25,33 @@ import type { Selector, SourcesMap } fro
 export type BreakpointSources = Array<{
   source: Source,
   breakpoints: FormattedBreakpoint[]
 }>;
 
 export type FormattedBreakpoint = {|
   id: BreakpointId,
   condition: ?string,
+  log: boolean,
   disabled: boolean,
   text: string,
   selectedLocation: SourceLocation
 |};
 
 function formatBreakpoint(
   breakpoint: Breakpoint,
   selectedSource: ?Source
 ): FormattedBreakpoint {
-  const { id, condition, disabled } = breakpoint;
+  const { id, condition, disabled, log } = breakpoint;
 
   return {
     id,
     condition,
     disabled,
+    log,
     text:
       selectedSource && isGenerated(selectedSource)
         ? breakpoint.text
         : breakpoint.originalText,
     selectedLocation: getSelectedLocation(breakpoint, selectedSource)
   };
 }
 
--- a/devtools/client/debugger/new/src/selectors/visibleBreakpoints.js
+++ b/devtools/client/debugger/new/src/selectors/visibleBreakpoints.js
@@ -19,26 +19,27 @@ import type { Selector } from "../reduce
 
 function getLocation(breakpoint, isGeneratedSource) {
   return isGeneratedSource
     ? breakpoint.generatedLocation || breakpoint.location
     : breakpoint.location;
 }
 
 const formatBreakpoint = memoize(function(breakpoint, selectedSource) {
-  const { condition, loading, disabled, hidden } = breakpoint;
+  const { condition, loading, disabled, hidden, log } = breakpoint;
   const sourceId = selectedSource.id;
   const isGeneratedSource = isGeneratedId(sourceId);
 
   return {
     location: getLocation(breakpoint, isGeneratedSource),
     condition,
     loading,
     disabled,
-    hidden
+    hidden,
+    log
   };
 });
 
 function isVisible(breakpoint: Breakpoint, selectedSource: Source) {
   const sourceId = selectedSource.id;
   const isGeneratedSource = isGeneratedId(sourceId);
 
   const location = getLocation(breakpoint, isGeneratedSource);
--- a/devtools/client/debugger/new/src/utils/breakpoint/index.js
+++ b/devtools/client/debugger/new/src/utils/breakpoint/index.js
@@ -125,27 +125,29 @@ export function createBreakpoint(
   const {
     condition,
     disabled,
     hidden,
     generatedLocation,
     astLocation,
     id,
     text,
-    originalText
+    originalText,
+    log
   } = overrides;
 
   const defaultASTLocation = {
     name: undefined,
     offset: location,
     index: 0
   };
   const properties = {
     id,
     condition: condition || null,
+    log: log || false,
     disabled: disabled || false,
     hidden: hidden || false,
     loading: false,
     astLocation: astLocation || defaultASTLocation,
     generatedLocation: generatedLocation || location,
     location,
     text,
     originalText
@@ -178,16 +180,17 @@ function createPendingLocation(location:
 export function createPendingBreakpoint(bp: Breakpoint) {
   const pendingLocation = createPendingLocation(bp.location);
   const pendingGeneratedLocation = createPendingLocation(bp.generatedLocation);
 
   assertPendingLocation(pendingLocation);
 
   return {
     condition: bp.condition,
+    log: bp.log,
     disabled: bp.disabled,
     location: pendingLocation,
     astLocation: bp.astLocation,
     generatedLocation: pendingGeneratedLocation
   };
 }
 
 export function sortFormattedBreakpoints(breakpoints: FormattedBreakpoint[]) {
--- a/devtools/client/debugger/new/src/utils/location.js
+++ b/devtools/client/debugger/new/src/utils/location.js
@@ -10,19 +10,19 @@ type IncompleteLocation = {
   sourceId: SourceId,
   line?: number,
   column?: number,
   sourceUrl?: string
 };
 
 export function createLocation({
   sourceId,
-  line,
+  line = 1,
   column,
-  sourceUrl
+  sourceUrl = ""
 }: IncompleteLocation): SourceLocation {
   return {
     sourceId,
-    line: line || 0,
+    line,
     column,
-    sourceUrl: sourceUrl || ""
+    sourceUrl
   };
 }
--- 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", true);
+  pref("devtools.debugger.features.original-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"],
@@ -112,17 +112,17 @@ export const features = new PrefsHelper(
   codeFolding: ["Bool", "code-folding"],
   pausePoints: ["Bool", "pause-points"],
   skipPausing: ["Bool", "skip-pausing"],
   autocompleteExpression: ["Bool", "autocomplete-expressions"],
   mapExpressionBindings: ["Bool", "map-expression-bindings"],
   mapAwaitExpression: ["Bool", "map-await-expression"],
   componentPane: ["Bool", "component-pane"],
   xhrBreakpoints: ["Bool", "xhr-breakpoints"],
-  originalBlackbox: ["Bool", "origial-blackbox"]
+  originalBlackbox: ["Bool", "original-blackbox"]
 });
 
 export const asyncStore = asyncStoreHelper("debugger", {
   pendingBreakpoints: ["pending-breakpoints", {}],
   tabs: ["tabs", []],
   xhrBreakpoints: ["xhr-breakpoints", []]
 });
 
--- a/devtools/client/debugger/new/src/utils/project-search.js
+++ b/devtools/client/debugger/new/src/utils/project-search.js
@@ -5,25 +5,25 @@
 // @flow
 
 // Maybe reuse file search's functions?
 
 import React from "react";
 import type { Match } from "../components/ProjectSearch";
 
 export function highlightMatches(lineMatch: Match) {
-  const { value, column, match } = lineMatch;
+  const { value, matchIndex, match } = lineMatch;
   const len = match.length;
 
   return (
     <span className="line-value">
       <span className="line-match" key={0}>
-        {value.slice(0, column)}
+        {value.slice(0, matchIndex)}
       </span>
       <span className="query-match" key={1}>
-        {value.substr(column, len)}
+        {value.substr(matchIndex, len)}
       </span>
       <span className="line-match" key={2}>
-        {value.slice(column + len, value.length)}
+        {value.slice(matchIndex + len, value.length)}
       </span>
     </span>
   );
 }
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-breakpoints-columns.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-breakpoints-columns.js
@@ -17,20 +17,20 @@ function waitForElementFocus(dbg, el) {
 
 function hasCondition(marker) {
   return marker.classList.contains("has-condition");
 }
 
 async function setConditionalBreakpoint(dbg, index, condition) {
   const {
       addConditionalBreakpoint,
-      editBreakpoint
+      editConditionalBreakpoint
   } = selectors.gutterContextMenu;
   // Make this work with either add or edit menu items
-  const selector = `${addConditionalBreakpoint},${editBreakpoint}`;
+  const selector = `${addConditionalBreakpoint},${editConditionalBreakpoint}`;
 
   rightClickElement(dbg, "breakpointItem", index);
   selectContextMenuItem(dbg, selector);
   await waitForElement(dbg, "conditionalPanelInput");
   await assertConditionalBreakpointIsFocused(dbg);
 
   // Position cursor reliably at the end of the text.
   pressKey(dbg, "End");
@@ -41,17 +41,17 @@ async function setConditionalBreakpoint(
 function removeBreakpointViaContext(dbg, index) {
   rightClickElement(dbg, "breakpointItem", index);
   selectContextMenuItem(dbg, "#node-menu-delete-self");
 }
 
 // Test enabling and disabling a breakpoint using the check boxes
 add_task(async function() {
   const dbg = await initDebugger("doc-scripts.html", "simple1");
-  await pushPref("devtools.debugger.features.column-breakpoints", true);
+  await pushPref("devtools.debugger.features.column-breakpoints", false);
 
   if(!Services.prefs.getBoolPref("devtools.debugger.features.column-breakpoints")) {
     ok(true, "This test only applies when column breakpoints are on");
     return;
   }
 
   await selectSource(dbg, "simple1");
 
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-breakpoints-cond.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-breakpoints-cond.js
@@ -36,44 +36,47 @@ function waitForElementFocus(dbg, el) {
 async function assertConditionalBreakpointIsFocused(dbg) {
   const input = findElement(dbg, "conditionalPanelInput");
   await waitForElementFocus(dbg, input);
 }
 
 async function setConditionalBreakpoint(dbg, index, condition) {
   const {
     addConditionalBreakpoint,
-    editBreakpoint
+    editConditionalBreakpoint
   } = selectors.gutterContextMenu;
   // Make this work with either add or edit menu items
-  const selector = `${addConditionalBreakpoint},${editBreakpoint}`;
+  const selector = `${addConditionalBreakpoint},${editConditionalBreakpoint}`;
 
   rightClickElement(dbg, "gutter", index);
   selectContextMenuItem(dbg, selector);
   await waitForElement(dbg, "conditionalPanelInput");
   await assertConditionalBreakpointIsFocused(dbg);
 
   // Position cursor reliably at the end of the text.
   pressKey(dbg, "End");
   type(dbg, condition);
   pressKey(dbg, "Enter");
 }
 
 add_task(async function() {
   const dbg = await initDebugger("doc-scripts.html", "simple2");
+  await pushPref("devtools.debugger.features.column-breakpoints", false);
+
   await selectSource(dbg, "simple2");
   await waitForSelectedSource(dbg, "simple2");
 
   await setConditionalBreakpoint(dbg, 5, "1");
   await waitForDispatch(dbg, "ADD_BREAKPOINT");
-  
+
   let bp = findBreakpoint(dbg, "simple2", 5);
   is(bp.condition, "1", "breakpoint is created with the condition");
   assertEditorBreakpoint(dbg, 5, true);
 
+  // Edit the conditional breakpoint set above
   await setConditionalBreakpoint(dbg, 5, "2");
   await waitForDispatch(dbg, "SET_BREAKPOINT_CONDITION");
   bp = findBreakpoint(dbg, "simple2", 5);
   is(bp.condition, "12", "breakpoint is created with the condition");
   assertEditorBreakpoint(dbg, 5, true);
 
   clickElement(dbg, "gutter", 5);
   await waitForDispatch(dbg, "REMOVE_BREAKPOINT");
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-search-project.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-search-project.js
@@ -1,10 +1,11 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
 
 function openProjectSearch(dbg) {
   synthesizeKeyShortcut("CmdOrCtrl+Shift+F");
   return waitForState(
     dbg,
     state => dbg.selectors.getActiveSearch(state) === "project"
   );
 }
@@ -18,41 +19,60 @@ async function selectResult(dbg) {
   const select = waitForState(
     dbg,
     () => !dbg.selectors.getActiveSearch(dbg.getState())
   );
   await clickElement(dbg, "fileMatch");
   return select;
 }
 
-function getResultsCount(dbg) {
+function getExpandedResultsCount(dbg) {
+  return findAllElements(dbg, "projectSerchExpandedResults").length;
+}
+
+function getResultsFiles(dbg) {
   const matches = dbg.selectors
     .getTextSearchResults(dbg.getState())
     .map(file => file.matches);
 
   return [...matches].length;
 }
 
 // Testing project search
 add_task(async function() {
-  await pushPref("devtools.debugger.project-text-search-enabled", true);
-
   const dbg = await initDebugger("doc-script-switching.html", "switching-01");
 
   await selectSource(dbg, "switching-01");
 
   // test opening and closing
   await openProjectSearch(dbg);
   await closeProjectSearch(dbg);
 
   await openProjectSearch(dbg);
   type(dbg, "first");
   pressKey(dbg, "Enter");
 
-  await waitForState(dbg, () => getResultsCount(dbg) === 1);
+  await waitForState(dbg, () => getResultsFiles(dbg) === 1);
 
   await selectResult(dbg);
 
   is(dbg.selectors.getActiveSearch(dbg.getState()), null);
 
   const selectedSource = dbg.selectors.getSelectedSource(dbg.getState());
   ok(selectedSource.url.includes("switching-01"));
 });
+
+add_task(async function() {
+  const dbg = await initDebugger("doc-react.html", "App.js");
+  await openProjectSearch(dbg);
+  type(dbg, "we");
+  pressKey(dbg, "Enter");
+  await waitForState(dbg, state => state.projectTextSearch.status === "DONE");
+
+  is(getExpandedResultsCount(dbg), 18);
+
+  const collapsedNodes = findAllElements(dbg, "projectSearchCollapsed");
+  is(collapsedNodes.length, 1);
+
+  collapsedNodes[0].click();
+
+  is(getExpandedResultsCount(dbg), 226);
+});
--- a/devtools/client/debugger/new/test/mochitest/helpers.js
+++ b/devtools/client/debugger/new/test/mochitest/helpers.js
@@ -1096,17 +1096,17 @@ const selectors = {
   scopeValue: i =>
     `.scopes-list .tree-node:nth-child(${i}) .object-delimiter + *`,
   frame: i => `.frames ul li:nth-child(${i})`,
   frames: ".frames ul li",
   gutter: i => `.CodeMirror-code *:nth-child(${i}) .CodeMirror-linenumber`,
   // These work for bobth the breakpoint listing and gutter marker
   gutterContextMenu: {
     addConditionalBreakpoint: "#node-menu-add-condition, #node-menu-add-conditional-breakpoint",
-    editBreakpoint: "#node-menu-edit-condition, #node-menu-edit-conditional-breakpoint"
+    editConditionalBreakpoint: "#node-menu-edit-condition, #node-menu-edit-conditional-breakpoint"
   },
   menuitem: i => `menupopup menuitem:nth-child(${i})`,
   pauseOnExceptions: ".pause-exceptions",
   breakpoint: ".CodeMirror-code > .new-breakpoint",
   highlightLine: ".CodeMirror-code > .highlight-line",
   debugLine: ".new-debug-line",
   debugErrorLine: ".new-debug-line-error",
   codeMirror: ".CodeMirror",
@@ -1132,17 +1132,19 @@ const selectors = {
   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",
-  blackbox: ".action.black-box"
+  blackbox: ".action.black-box",
+  projectSearchCollapsed: ".project-text-search .arrow:not(.expanded)",
+  projectSerchExpandedResults: ".project-text-search .result",
 };
 
 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
@@ -445,19 +445,19 @@ components.header=Components
 
 # LOCALIZATION NOTE (editor.searchResults): Editor Search bar message
 # for the summarizing the selected search result. e.g. 5 of 10 results.
 editor.searchResults=%d of %d results
 
 # LOCALIZATION NOTE (editor.singleResult): Copy shown when there is one result.
 editor.singleResult=1 result
 
-# LOCALIZATION NOTE (editor.noResults): Editor Search bar message
+# LOCALIZATION NOTE (editor.noResultsFound): Editor Search bar message
 # for when no results found.
-editor.noResults=No results
+editor.noResultsFound=No results found
 
 # LOCALIZATION NOTE (editor.searchResults.nextResult): Editor Search bar
 # tooltip for traversing to the Next Result
 editor.searchResults.nextResult=Next result
 
 # LOCALIZATION NOTE (editor.searchResults.prevResult): Editor Search bar
 # tooltip for traversing to the Previous Result
 editor.searchResults.prevResult=Previous result
@@ -489,23 +489,40 @@ editor.enableBreakpoint=Enable breakpoin
 editor.removeBreakpoint=Remove breakpoint
 
 # LOCALIZATION NOTE (editor.editBreakpoint): Editor gutter context menu item
 # for setting a breakpoint condition on a line.
 editor.editBreakpoint=Edit breakpoint
 
 # LOCALIZATION NOTE (editor.addConditionalBreakpoint): Editor gutter context
 # menu item for adding a breakpoint condition on a line.
-editor.addConditionalBreakpoint=Add conditional breakpoint
+editor.addConditionalBreakpoint=Add condition
 editor.addConditionalBreakpoint.accesskey=c
 
+# LOCALIZATION NOTE (editor.editBreakpoint): Editor gutter context menu item
+# for setting a breakpoint condition on a line.
+editor.editConditionalBreakpoint=Edit condition
+
+# LOCALIZATION NOTE (editor.addLogPoint): Editor gutter context
+# menu item for adding a log point on a line.
+editor.addLogPoint=Add log
+editor.addLogPoint.accesskey=l
+
+# LOCALIZATION NOTE (editor.editLogpoint): Editor gutter context menu item
+# for setting a log point on a line.
+editor.editLogPoint=Edit log
+
 # LOCALIZATION NOTE (editor.conditionalPanel.placeholder): Placeholder text for
 # input element inside ConditionalPanel component
 editor.conditionalPanel.placeholder=This breakpoint will pause when the expression is true
 
+# LOCALIZATION NOTE (editor.conditionalPanel.logPoint.placeholder): Placeholder text for
+# input element inside ConditionalPanel component when a log point is set
+editor.conditionalPanel.logPoint.placeholder=This breakpoint will log the result of the expression
+
 # LOCALIZATION NOTE (editor.conditionalPanel.close): Tooltip text for
 # 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
--- 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", true);
+pref("devtools.debugger.features.original-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
@@ -6486,18 +6486,18 @@ function reducer(state = initialState(),
     return cloneState({
       actors: data.actor ? new Set(state.actors || []).add(data.result.from) : state.actors,
       evaluations: new Map(state.evaluations).set(data.node.path, {
         getterValue: data.result && data.result.value && (data.result.value.return || data.result.value.throw)
       })
     });
   }
 
-  // NOTE: we clear the state on resume because otherwise the scopes pane 
-  // would be out of date. Bug 1514760 
+  // NOTE: we clear the state on resume because otherwise the scopes pane
+  // would be out of date. Bug 1514760
   if (type === "RESUME" || type == "NAVIGATE") {
     return initialState();
   }
 
   return state;
 }
 
 function getObjectInspectorState(state) {
--- a/dom/base/nsDOMMutationObserver.cpp
+++ b/dom/base/nsDOMMutationObserver.cpp
@@ -51,20 +51,17 @@ nsINodeList* nsDOMMutationRecord::Remove
 }
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMMutationRecord)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMMutationRecord)
-// Break down the linked list so that cycle collector can delete the
-// objects sooner.
-NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_LAST_RELEASE(nsDOMMutationRecord,
-                                                   mNext = nullptr)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMMutationRecord)
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsDOMMutationRecord, mTarget,
                                       mPreviousSibling, mNextSibling,
                                       mAddedNodes, mRemovedNodes,
                                       mAddedAnimations, mRemovedAnimations,
                                       mChangedAnimations, mNext, mOwner)
 
 // Observer
--- a/dom/base/nsDOMMutationObserver.h
+++ b/dom/base/nsDOMMutationObserver.h
@@ -497,19 +497,24 @@ class nsDOMMutationObserver final : publ
       MOZ_ASSERT(mFirstPendingMutation);
       mLastPendingMutation->mNext = record.forget();
       mLastPendingMutation = mLastPendingMutation->mNext;
     }
     ++mPendingMutationCount;
   }
 
   void ClearPendingRecords() {
-    mFirstPendingMutation = nullptr;
+    // Break down the pending mutation record list so that cycle collector
+    // can delete the objects sooner.
+    RefPtr<nsDOMMutationRecord> current = mFirstPendingMutation.forget();
     mLastPendingMutation = nullptr;
     mPendingMutationCount = 0;
+    while (current) {
+      current = current->mNext.forget();
+    }
   }
 
   // static methods
   static void QueueMutationObserverMicroTask();
 
   static void HandleMutations(mozilla::AutoSlowOperation& aAso);
 
   static bool AllScheduledMutationObserversAreSuppressed() {
--- a/dom/events/EventTarget.h
+++ b/dom/events/EventTarget.h
@@ -4,16 +4,17 @@
  * 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_EventTarget_h_
 #define mozilla_dom_EventTarget_h_
 
 #include "mozilla/dom/BindingDeclarations.h"
 #include "mozilla/dom/Nullable.h"
+#include "mozilla/dom/WindowProxyHolder.h"
 #include "nsISupports.h"
 #include "nsWrapperCache.h"
 #include "nsAtom.h"
 
 class nsPIDOMWindowOuter;
 class nsIGlobalObject;
 class nsIDOMEventListener;
 
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -1233,17 +1233,23 @@ void ContentChild::InitXPCOM(
 mozilla::ipc::IPCResult ContentChild::RecvRequestMemoryReport(
     const uint32_t& aGeneration, const bool& aAnonymize,
     const bool& aMinimizeMemoryUsage, const MaybeFileDesc& aDMDFile) {
   nsCString process;
   GetProcessName(process);
   AppendProcessId(process);
 
   MemoryReportRequestClient::Start(aGeneration, aAnonymize,
-                                   aMinimizeMemoryUsage, aDMDFile, process);
+                                   aMinimizeMemoryUsage, aDMDFile, process,
+                                   [&](const MemoryReport& aReport) {
+                                     Unused << GetSingleton()->SendAddMemoryReport(aReport);
+                                   },
+                                   [&](const uint32_t& aGeneration) {
+                                     return GetSingleton()->SendFinishMemoryReport(aGeneration);
+                                   });
   return IPC_OK();
 }
 
 PCycleCollectWithLogsChild* ContentChild::AllocPCycleCollectWithLogsChild(
     const bool& aDumpAllTraces, const FileDescriptor& aGCLog,
     const FileDescriptor& aCCLog) {
   return do_AddRef(new CycleCollectWithLogsChild()).take();
 }
--- a/dom/ipc/MemoryReportRequest.cpp
+++ b/dom/ipc/MemoryReportRequest.cpp
@@ -1,19 +1,15 @@
 /* -*- 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 "MemoryReportRequest.h"
-#include "mozilla/RDDParent.h"
-#include "mozilla/Unused.h"
-#include "mozilla/dom/ContentChild.h"
-#include "mozilla/gfx/GPUParent.h"
 
 namespace mozilla {
 namespace dom {
 
 MemoryReportRequestHost::MemoryReportRequestHost(uint32_t aGeneration)
     : mGeneration(aGeneration), mSuccess(false) {
   MOZ_COUNT_CTOR(MemoryReportRequestHost);
   mReporterManager = nsMemoryReporterManager::GetOrCreate();
@@ -49,131 +45,119 @@ MemoryReportRequestHost::~MemoryReportRe
     mReporterManager = nullptr;
   }
 }
 
 NS_IMPL_ISUPPORTS(MemoryReportRequestClient, nsIRunnable)
 
 /* static */ void MemoryReportRequestClient::Start(
     uint32_t aGeneration, bool aAnonymize, bool aMinimizeMemoryUsage,
-    const MaybeFileDesc& aDMDFile, const nsACString& aProcessString) {
+    const MaybeFileDesc& aDMDFile, const nsACString& aProcessString,
+    const ReportCallback& aReportCallback,
+    const FinishCallback& aFinishCallback) {
   RefPtr<MemoryReportRequestClient> request = new MemoryReportRequestClient(
-      aGeneration, aAnonymize, aDMDFile, aProcessString);
+      aGeneration, aAnonymize, aDMDFile, aProcessString,
+      aReportCallback, aFinishCallback);
 
   DebugOnly<nsresult> rv;
   if (aMinimizeMemoryUsage) {
     nsCOMPtr<nsIMemoryReporterManager> mgr =
         do_GetService("@mozilla.org/memory-reporter-manager;1");
     rv = mgr->MinimizeMemoryUsage(request);
     // mgr will eventually call actor->Run()
   } else {
     rv = request->Run();
   }
 
   NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "actor operation failed");
 }
 
 MemoryReportRequestClient::MemoryReportRequestClient(
     uint32_t aGeneration, bool aAnonymize, const MaybeFileDesc& aDMDFile,
-    const nsACString& aProcessString)
+    const nsACString& aProcessString, const ReportCallback& aReportCallback,
+    const FinishCallback& aFinishCallback)
     : mGeneration(aGeneration),
       mAnonymize(aAnonymize),
-      mProcessString(aProcessString) {
+      mProcessString(aProcessString),
+      mReportCallback(aReportCallback),
+      mFinishCallback(aFinishCallback) {
   if (aDMDFile.type() == MaybeFileDesc::TFileDescriptor) {
     mDMDFile = aDMDFile.get_FileDescriptor();
   }
 }
 
 MemoryReportRequestClient::~MemoryReportRequestClient() {}
 
 class HandleReportCallback final : public nsIHandleReportCallback {
  public:
+  using ReportCallback = typename MemoryReportRequestClient::ReportCallback;
+
   NS_DECL_ISUPPORTS
 
   explicit HandleReportCallback(uint32_t aGeneration,
-                                const nsACString& aProcess)
-      : mGeneration(aGeneration), mProcess(aProcess) {}
+                                const nsACString& aProcess,
+                                const ReportCallback& aReportCallback)
+      : mGeneration(aGeneration),
+        mProcess(aProcess),
+        mReportCallback(aReportCallback) {}
 
   NS_IMETHOD Callback(const nsACString& aProcess, const nsACString& aPath,
                       int32_t aKind, int32_t aUnits, int64_t aAmount,
                       const nsACString& aDescription,
                       nsISupports* aUnused) override {
     MemoryReport memreport(mProcess, nsCString(aPath), aKind, aUnits, aAmount,
                            mGeneration, nsCString(aDescription));
-    switch (XRE_GetProcessType()) {
-      case GeckoProcessType_Content:
-        ContentChild::GetSingleton()->SendAddMemoryReport(memreport);
-        break;
-      case GeckoProcessType_GPU:
-        Unused << gfx::GPUParent::GetSingleton()->SendAddMemoryReport(
-            memreport);
-        break;
-      case GeckoProcessType_RDD:
-        Unused << RDDParent::GetSingleton()->SendAddMemoryReport(memreport);
-        break;
-      default:
-        MOZ_ASSERT_UNREACHABLE("Unhandled process type");
-    }
+    mReportCallback(memreport);
     return NS_OK;
   }
 
  private:
   ~HandleReportCallback() = default;
 
   uint32_t mGeneration;
   const nsCString mProcess;
+  ReportCallback mReportCallback;
 };
 
 NS_IMPL_ISUPPORTS(HandleReportCallback, nsIHandleReportCallback)
 
 class FinishReportingCallback final : public nsIFinishReportingCallback {
  public:
+  using FinishCallback = typename MemoryReportRequestClient::FinishCallback;
+
   NS_DECL_ISUPPORTS
 
-  explicit FinishReportingCallback(uint32_t aGeneration)
-      : mGeneration(aGeneration) {}
+  explicit FinishReportingCallback(uint32_t aGeneration,
+                                   const FinishCallback& aFinishCallback)
+      : mGeneration(aGeneration),
+        mFinishCallback(aFinishCallback) {}
 
   NS_IMETHOD Callback(nsISupports* aUnused) override {
-    bool sent = false;
-    switch (XRE_GetProcessType()) {
-      case GeckoProcessType_Content:
-        sent =
-            ContentChild::GetSingleton()->SendFinishMemoryReport(mGeneration);
-        break;
-      case GeckoProcessType_GPU:
-        sent =
-            gfx::GPUParent::GetSingleton()->SendFinishMemoryReport(mGeneration);
-        break;
-      case GeckoProcessType_RDD:
-        sent = RDDParent::GetSingleton()->SendFinishMemoryReport(mGeneration);
-        break;
-      default:
-        MOZ_ASSERT_UNREACHABLE("Unhandled process type");
-    }
-    return sent ? NS_OK : NS_ERROR_FAILURE;
+    return mFinishCallback(mGeneration) ? NS_OK : NS_ERROR_FAILURE;
   }
 
  private:
   ~FinishReportingCallback() = default;
 
   uint32_t mGeneration;
+  FinishCallback mFinishCallback;
 };
 
 NS_IMPL_ISUPPORTS(FinishReportingCallback, nsIFinishReportingCallback)
 
 NS_IMETHODIMP MemoryReportRequestClient::Run() {
   nsCOMPtr<nsIMemoryReporterManager> mgr =
       do_GetService("@mozilla.org/memory-reporter-manager;1");
 
   // Run the reporters.  The callback will turn each measurement into a
   // MemoryReport.
   RefPtr<HandleReportCallback> handleReport =
-      new HandleReportCallback(mGeneration, mProcessString);
+      new HandleReportCallback(mGeneration, mProcessString, mReportCallback);
   RefPtr<FinishReportingCallback> finishReporting =
-      new FinishReportingCallback(mGeneration);
+      new FinishReportingCallback(mGeneration, mFinishCallback);
 
   nsresult rv = mgr->GetReportsForThisProcessExtended(
       handleReport, nullptr, mAnonymize, FileDescriptorToFILE(mDMDFile, "wb"),
       finishReporting, nullptr);
   NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
                        "GetReportsForThisProcessExtended failed");
   return rv;
 }
--- a/dom/ipc/MemoryReportRequest.h
+++ b/dom/ipc/MemoryReportRequest.h
@@ -6,22 +6,25 @@
 
 #ifndef mozilla_dom_MemoryReportRequest_h_
 #define mozilla_dom_MemoryReportRequest_h_
 
 #include "mozilla/dom/MemoryReportTypes.h"
 #include "mozilla/ipc/FileDescriptor.h"
 #include "nsISupports.h"
 
+#include <functional>
+
 class nsMemoryReporterManager;
 
 namespace mozilla {
 namespace dom {
 
 class MaybeFileDesc;
+class MemoryReport;
 
 class MemoryReportRequestHost final {
  public:
   explicit MemoryReportRequestHost(uint32_t aGeneration);
   ~MemoryReportRequestHost();
 
   void RecvReport(const MemoryReport& aReport);
   void Finish(uint32_t aGeneration);
@@ -30,34 +33,43 @@ class MemoryReportRequestHost final {
   const uint32_t mGeneration;
   // Non-null if we haven't yet called EndProcessReport() on it.
   RefPtr<nsMemoryReporterManager> mReporterManager;
   bool mSuccess;
 };
 
 class MemoryReportRequestClient final : public nsIRunnable {
  public:
+  using ReportCallback = std::function<void(const MemoryReport&)>;
+  using FinishCallback = std::function<bool(const uint32_t&)>;
+
   NS_DECL_ISUPPORTS
 
   static void Start(uint32_t aGeneration, bool aAnonymize,
                     bool aMinimizeMemoryUsage, const MaybeFileDesc& aDMDFile,
-                    const nsACString& aProcessString);
+                    const nsACString& aProcessString,
+                    const ReportCallback& aReportCallback,
+                    const FinishCallback& aFinishCallback);
 
   NS_IMETHOD Run() override;
 
  private:
   MemoryReportRequestClient(uint32_t aGeneration, bool aAnonymize,
                             const MaybeFileDesc& aDMDFile,
-                            const nsACString& aProcessString);
+                            const nsACString& aProcessString,
+                            const ReportCallback& aReportCallback,
+                            const FinishCallback& aFinishCallback);
 
  private:
   ~MemoryReportRequestClient();
 
   uint32_t mGeneration;
   bool mAnonymize;
   mozilla::ipc::FileDescriptor mDMDFile;
   nsCString mProcessString;
+  ReportCallback mReportCallback;
+  FinishCallback mFinishCallback;
 };
 
 }  // namespace dom
 }  // namespace mozilla
 
 #endif  // mozilla_dom_MemoryReportRequest_h_
--- a/dom/media/ipc/RDDParent.cpp
+++ b/dom/media/ipc/RDDParent.cpp
@@ -150,17 +150,23 @@ mozilla::ipc::IPCResult RDDParent::RecvN
 }
 
 mozilla::ipc::IPCResult RDDParent::RecvRequestMemoryReport(
     const uint32_t& aGeneration, const bool& aAnonymize,
     const bool& aMinimizeMemoryUsage, const MaybeFileDesc& aDMDFile) {
   nsPrintfCString processName("RDD (pid %u)", (unsigned)getpid());
 
   mozilla::dom::MemoryReportRequestClient::Start(
-      aGeneration, aAnonymize, aMinimizeMemoryUsage, aDMDFile, processName);
+      aGeneration, aAnonymize, aMinimizeMemoryUsage, aDMDFile, processName,
+      [&](const MemoryReport& aReport) {
+        Unused << GetSingleton()->SendAddMemoryReport(aReport);
+      },
+      [&](const uint32_t& aGeneration) {
+        return GetSingleton()->SendFinishMemoryReport(aGeneration);
+      });
   return IPC_OK();
 }
 
 void RDDParent::ActorDestroy(ActorDestroyReason aWhy) {
   if (AbnormalShutdown == aWhy) {
     NS_WARNING("Shutting down RDD process early due to a crash!");
     ProcessChild::QuickExit();
   }
--- a/dom/svg/SVGClipPathElement.h
+++ b/dom/svg/SVGClipPathElement.h
@@ -2,17 +2,17 @@
 /* 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_SVGClipPathElement_h
 #define mozilla_dom_SVGClipPathElement_h
 
-#include "nsSVGEnum.h"
+#include "SVGEnum.h"
 #include "mozilla/dom/SVGTransformableElement.h"
 
 class nsSVGClipPathFrame;
 
 nsresult NS_NewSVGClipPathElement(
     nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
 namespace mozilla {
@@ -39,17 +39,17 @@ class SVGClipPathElement final : public 
   already_AddRefed<SVGAnimatedEnumeration> ClipPathUnits();
 
   // This is an internal method that does not flush style, and thus
   // the answer may be out of date if there's a pending style flush.
   bool IsUnitsObjectBoundingBox() const;
 
  protected:
   enum { CLIPPATHUNITS };
-  nsSVGEnum mEnumAttributes[1];
+  SVGEnum mEnumAttributes[1];
   static EnumInfo sEnumInfo[1];
 
   virtual EnumAttributesInfo GetEnumInfo() override;
 };
 
 }  // namespace dom
 }  // namespace mozilla
 
--- a/dom/svg/SVGComponentTransferFunctionElement.h
+++ b/dom/svg/SVGComponentTransferFunctionElement.h
@@ -2,20 +2,20 @@
 /* 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_SVGComponentTransferFunctionElement_h
 #define mozilla_dom_SVGComponentTransferFunctionElement_h
 
-#include "nsSVGEnum.h"
+#include "SVGAnimatedNumberList.h"
+#include "SVGEnum.h"
 #include "SVGFilters.h"
 #include "nsSVGNumber2.h"
-#include "SVGAnimatedNumberList.h"
 
 #define NS_SVG_FE_COMPONENT_TRANSFER_FUNCTION_ELEMENT_CID \
   {                                                       \
     0xafab106d, 0xbc18, 0x4f7f, {                         \
       0x9e, 0x29, 0xfe, 0xb4, 0xb0, 0x16, 0x5f, 0xf4      \
     }                                                     \
   }
 
@@ -73,18 +73,18 @@ class SVGComponentTransferFunctionElemen
   SVGAnimatedNumberList mNumberListAttributes[1];
   static NumberListInfo sNumberListInfo[1];
 
   enum { SLOPE, INTERCEPT, AMPLITUDE, EXPONENT, OFFSET };
   nsSVGNumber2 mNumberAttributes[5];
   static NumberInfo sNumberInfo[5];
 
   enum { TYPE };
-  nsSVGEnum mEnumAttributes[1];
-  static nsSVGEnumMapping sTypeMap[];
+  SVGEnum mEnumAttributes[1];
+  static SVGEnumMapping sTypeMap[];
   static EnumInfo sEnumInfo[1];
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(SVGComponentTransferFunctionElement,
                               NS_SVG_FE_COMPONENT_TRANSFER_FUNCTION_ELEMENT_CID)
 
 }  // namespace dom
 }  // namespace mozilla
--- a/dom/svg/SVGElement.cpp
+++ b/dom/svg/SVGElement.cpp
@@ -1,64 +1,64 @@
 /* -*- 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/SVGElement.h"
 
-#include "mozilla/ArrayUtils.h"
-#include "mozilla/DebugOnly.h"
-#include "mozilla/Unused.h"
-
 #include "mozilla/dom/MutationEventBinding.h"
 #include "mozilla/dom/SVGAnimatedEnumeration.h"
 #include "mozilla/dom/SVGElementBinding.h"
+#include "mozilla/dom/SVGGeometryElement.h"
 #include "mozilla/dom/SVGLengthBinding.h"
 #include "mozilla/dom/SVGSVGElement.h"
 #include "mozilla/dom/SVGTests.h"
 #include "mozilla/dom/SVGUnitTypesBinding.h"
+
+#include "mozilla/ArrayUtils.h"
+#include "mozilla/DebugOnly.h"
 #include "mozilla/DeclarationBlock.h"
 #include "mozilla/EventListenerManager.h"
 #include "mozilla/InternalMutationEvent.h"
 #include "mozilla/RestyleManager.h"
 #include "mozilla/SMILAnimationController.h"
+#include "mozilla/SVGContentUtils.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 "nsError.h"
 #include "nsGkAtoms.h"
 #include "nsIPresShell.h"
 #include "nsIFrame.h"
+#include "nsQueryObject.h"
 #include "nsLayoutUtils.h"
 #include "SVGAngle.h"
-#include "nsSVGBoolean.h"
-#include "nsSVGEnum.h"
-#include "nsSVGInteger.h"
-#include "nsSVGIntegerPair.h"
-#include "nsSVGLength2.h"
-#include "nsSVGNumber2.h"
-#include "nsSVGNumberPair.h"
-#include "nsSVGString.h"
-#include "nsSVGViewBox.h"
 #include "SVGAnimatedNumberList.h"
 #include "SVGAnimatedLengthList.h"
 #include "SVGAnimatedPointList.h"
 #include "SVGAnimatedPathSegList.h"
 #include "SVGAnimatedTransformList.h"
-#include "SVGContentUtils.h"
-#include "SVGGeometryElement.h"
+#include "nsSVGBoolean.h"
+#include "SVGEnum.h"
+#include "nsSVGInteger.h"
+#include "nsSVGIntegerPair.h"
+#include "nsSVGLength2.h"
 #include "SVGMotionSMILAttr.h"
-#include "nsQueryObject.h"
+#include "nsSVGNumber2.h"
+#include "nsSVGNumberPair.h"
+#include "nsSVGString.h"
+#include "nsSVGViewBox.h"
 #include <stdarg.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");
@@ -78,17 +78,17 @@ nsresult NS_NewSVGElement(
 }
 
 namespace mozilla {
 namespace dom {
 using namespace SVGUnitTypes_Binding;
 
 NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGElement)
 
-nsSVGEnumMapping SVGElement::sSVGUnitTypesMap[] = {
+SVGEnumMapping SVGElement::sSVGUnitTypesMap[] = {
     {nsGkAtoms::userSpaceOnUse, SVG_UNIT_TYPE_USERSPACEONUSE},
     {nsGkAtoms::objectBoundingBox, SVG_UNIT_TYPE_OBJECTBOUNDINGBOX},
     {nullptr, 0}};
 
 SVGElement::SVGElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
     : SVGElementBase(std::move(aNodeInfo)) {}
 
 SVGElement::~SVGElement() {
@@ -496,17 +496,17 @@ bool SVGElement::ParseAttribute(int32_t 
           }
           foundMatch = true;
           break;
         }
       }
     }
 
     if (!foundMatch) {
-      // Check for nsSVGEnum attribute
+      // Check for SVGEnum attribute
       EnumAttributesInfo enumInfo = GetEnumInfo();
       for (i = 0; i < enumInfo.mEnumCount; i++) {
         if (aAttribute == enumInfo.mEnumInfo[i].mName) {
           RefPtr<nsAtom> valAtom = NS_Atomize(aValue);
           rv = enumInfo.mEnums[i].SetBaseValueAtom(valAtom, this);
           if (NS_FAILED(rv)) {
             enumInfo.SetUnknownValue(i);
           } else {
--- a/dom/svg/SVGElement.h
+++ b/dom/svg/SVGElement.h
@@ -23,45 +23,45 @@
 #include "nsCOMPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsError.h"
 #include "nsISupportsImpl.h"
 #include "nsStyledElement.h"
 #include "gfxMatrix.h"
 
 class nsSVGBoolean;
-class nsSVGEnum;
 class nsSVGInteger;
 class nsSVGIntegerPair;
 class nsSVGLength2;
 class nsSVGNumber2;
 class nsSVGNumberPair;
 class nsSVGString;
 class nsSVGViewBox;
 
-struct nsSVGEnumMapping;
-
 nsresult NS_NewSVGElement(mozilla::dom::Element** aResult,
                           already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
 namespace mozilla {
 class DeclarationBlock;
 
 class SVGAngle;
 class SVGAnimatedNumberList;
 class SVGNumberList;
 class SVGAnimatedLengthList;
+class SVGEnum;
 class SVGUserUnitList;
 class SVGAnimatedPointList;
 class SVGAnimatedPathSegList;
 class SVGAnimatedPreserveAspectRatio;
 class SVGAnimatedTransformList;
 class SVGStringList;
 class DOMSVGStringList;
 
+struct SVGEnumMapping;
+
 namespace dom {
 class SVGSVGElement;
 class SVGViewportElement;
 
 typedef nsStyledElement SVGElementBase;
 
 class SVGElement : public SVGElementBase  // nsIContent
 {
@@ -72,16 +72,18 @@ class SVGElement : public SVGElementBase
                          already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
   nsresult Init();
   virtual ~SVGElement();
 
  public:
   virtual nsresult Clone(mozilla::dom::NodeInfo*,
                          nsINode** aResult) const MOZ_MUST_OVERRIDE override;
 
+  typedef mozilla::SVGEnum SVGEnum;
+  typedef mozilla::SVGEnumMapping SVGEnumMapping;
   typedef mozilla::SVGNumberList SVGNumberList;
   typedef mozilla::SVGAnimatedNumberList SVGAnimatedNumberList;
   typedef mozilla::SVGUserUnitList SVGUserUnitList;
   typedef mozilla::SVGAnimatedLengthList SVGAnimatedLengthList;
   typedef mozilla::SVGAnimatedPointList SVGAnimatedPointList;
   typedef mozilla::SVGAnimatedPathSegList SVGAnimatedPathSegList;
   typedef mozilla::SVGAnimatedPreserveAspectRatio
       SVGAnimatedPreserveAspectRatio;
@@ -473,30 +475,30 @@ class SVGElement : public SVGElementBase
                           uint32_t aBooleanCount)
         : mBooleans(aBooleans),
           mBooleanInfo(aBooleanInfo),
           mBooleanCount(aBooleanCount) {}
 
     void Reset(uint8_t aAttrEnum);
   };
 
-  friend class ::nsSVGEnum;
+  friend class mozilla::SVGEnum;
 
   struct EnumInfo {
     nsStaticAtom* const mName;
-    const nsSVGEnumMapping* const mMapping;
+    const SVGEnumMapping* const mMapping;
     const uint16_t mDefaultValue;
   };
 
   struct EnumAttributesInfo {
-    nsSVGEnum* const mEnums;
+    SVGEnum* const mEnums;
     const EnumInfo* const mEnumInfo;
     const uint32_t mEnumCount;
 
-    EnumAttributesInfo(nsSVGEnum* aEnums, EnumInfo* aEnumInfo,
+    EnumAttributesInfo(SVGEnum* aEnums, EnumInfo* aEnumInfo,
                        uint32_t aEnumCount)
         : mEnums(aEnums), mEnumInfo(aEnumInfo), mEnumCount(aEnumCount) {}
 
     void Reset(uint8_t aAttrEnum);
     void SetUnknownValue(uint8_t aAttrEnum);
   };
 
   struct NumberListInfo {
@@ -600,17 +602,17 @@ class SVGElement : public SVGElementBase
   // so we don't need to wrap the class
   virtual nsSVGViewBox* GetViewBox();
   virtual SVGAnimatedPreserveAspectRatio* GetPreserveAspectRatio();
   virtual NumberListAttributesInfo GetNumberListInfo();
   virtual LengthListAttributesInfo GetLengthListInfo();
   virtual StringAttributesInfo GetStringInfo();
   virtual StringListAttributesInfo GetStringListInfo();
 
-  static nsSVGEnumMapping sSVGUnitTypesMap[];
+  static SVGEnumMapping sSVGUnitTypesMap[];
 
  private:
   void UnsetAttrInternal(int32_t aNameSpaceID, nsAtom* aAttribute,
                          bool aNotify);
 
   SVGClass mClassAttribute;
   nsAutoPtr<nsAttrValue> mClassAnimAttr;
   RefPtr<mozilla::DeclarationBlock> mContentDeclarationBlock;
rename from dom/svg/nsSVGEnum.cpp
rename to dom/svg/SVGEnum.cpp
--- a/dom/svg/nsSVGEnum.cpp
+++ b/dom/svg/SVGEnum.cpp
@@ -1,41 +1,42 @@
 /* -*- 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 "nsSVGEnum.h"
+#include "SVGEnum.h"
 
+#include "mozilla/dom/SVGElement.h"
+#include "nsAtom.h"
 #include "nsError.h"
 #include "nsSVGAttrTearoffTable.h"
-#include "nsAtom.h"
-#include "SVGElement.h"
+#include "SMILEnumType.h"
 #include "nsSMILValue.h"
-#include "SMILEnumType.h"
 
-using namespace mozilla;
 using namespace mozilla::dom;
 
-static nsSVGAttrTearoffTable<nsSVGEnum, nsSVGEnum::DOMAnimatedEnum>
+namespace mozilla {
+
+static nsSVGAttrTearoffTable<SVGEnum, SVGEnum::DOMAnimatedEnum>
     sSVGAnimatedEnumTearoffTable;
 
-const nsSVGEnumMapping* nsSVGEnum::GetMapping(SVGElement* aSVGElement) {
+const SVGEnumMapping* SVGEnum::GetMapping(SVGElement* aSVGElement) {
   SVGElement::EnumAttributesInfo info = aSVGElement->GetEnumInfo();
 
   NS_ASSERTION(info.mEnumCount > 0 && mAttrEnum < info.mEnumCount,
                "mapping request for a non-attrib enum");
 
   return info.mEnumInfo[mAttrEnum].mMapping;
 }
 
-nsresult nsSVGEnum::SetBaseValueAtom(const nsAtom* aValue,
-                                     SVGElement* aSVGElement) {
-  const nsSVGEnumMapping* mapping = GetMapping(aSVGElement);
+nsresult SVGEnum::SetBaseValueAtom(const nsAtom* aValue,
+                                   SVGElement* aSVGElement) {
+  const SVGEnumMapping* mapping = GetMapping(aSVGElement);
 
   while (mapping && mapping->mKey) {
     if (aValue == mapping->mKey) {
       mIsBaseSet = true;
       if (mBaseVal != mapping->mVal) {
         mBaseVal = mapping->mVal;
         if (!mIsAnimated) {
           mAnimVal = mBaseVal;
@@ -49,31 +50,31 @@ nsresult nsSVGEnum::SetBaseValueAtom(con
       return NS_OK;
     }
     mapping++;
   }
 
   return NS_ERROR_DOM_TYPE_ERR;
 }
 
-nsAtom* nsSVGEnum::GetBaseValueAtom(SVGElement* aSVGElement) {
-  const nsSVGEnumMapping* mapping = GetMapping(aSVGElement);
+nsAtom* SVGEnum::GetBaseValueAtom(SVGElement* aSVGElement) {
+  const SVGEnumMapping* mapping = GetMapping(aSVGElement);
 
   while (mapping && mapping->mKey) {
     if (mBaseVal == mapping->mVal) {
       return mapping->mKey;
     }
     mapping++;
   }
   NS_ERROR("unknown enumeration value");
   return nsGkAtoms::_empty;
 }
 
-nsresult nsSVGEnum::SetBaseValue(uint16_t aValue, SVGElement* aSVGElement) {
-  const nsSVGEnumMapping* mapping = GetMapping(aSVGElement);
+nsresult SVGEnum::SetBaseValue(uint16_t aValue, SVGElement* aSVGElement) {
+  const SVGEnumMapping* mapping = GetMapping(aSVGElement);
 
   while (mapping && mapping->mKey) {
     if (mapping->mVal == aValue) {
       mIsBaseSet = true;
       if (mBaseVal != uint8_t(aValue)) {
         mBaseVal = uint8_t(aValue);
         if (!mIsAnimated) {
           mAnimVal = mBaseVal;
@@ -84,51 +85,51 @@ nsresult nsSVGEnum::SetBaseValue(uint16_
       }
       return NS_OK;
     }
     mapping++;
   }
   return NS_ERROR_DOM_TYPE_ERR;
 }
 
-void nsSVGEnum::SetAnimValue(uint16_t aValue, SVGElement* aSVGElement) {
+void SVGEnum::SetAnimValue(uint16_t aValue, SVGElement* aSVGElement) {
   if (mIsAnimated && aValue == mAnimVal) {
     return;
   }
   mAnimVal = aValue;
   mIsAnimated = true;
   aSVGElement->DidAnimateEnum(mAttrEnum);
 }
 
-already_AddRefed<SVGAnimatedEnumeration> nsSVGEnum::ToDOMAnimatedEnum(
+already_AddRefed<SVGAnimatedEnumeration> SVGEnum::ToDOMAnimatedEnum(
     SVGElement* aSVGElement) {
   RefPtr<DOMAnimatedEnum> domAnimatedEnum =
       sSVGAnimatedEnumTearoffTable.GetTearoff(this);
   if (!domAnimatedEnum) {
     domAnimatedEnum = new DOMAnimatedEnum(this, aSVGElement);
     sSVGAnimatedEnumTearoffTable.AddTearoff(this, domAnimatedEnum);
   }
 
   return domAnimatedEnum.forget();
 }
 
-nsSVGEnum::DOMAnimatedEnum::~DOMAnimatedEnum() {
+SVGEnum::DOMAnimatedEnum::~DOMAnimatedEnum() {
   sSVGAnimatedEnumTearoffTable.RemoveTearoff(mVal);
 }
 
-UniquePtr<nsISMILAttr> nsSVGEnum::ToSMILAttr(SVGElement* aSVGElement) {
+UniquePtr<nsISMILAttr> SVGEnum::ToSMILAttr(SVGElement* aSVGElement) {
   return MakeUnique<SMILEnum>(this, aSVGElement);
 }
 
-nsresult nsSVGEnum::SMILEnum::ValueFromString(
-    const nsAString& aStr, const dom::SVGAnimationElement* /*aSrcElement*/,
+nsresult SVGEnum::SMILEnum::ValueFromString(
+    const nsAString& aStr, const SVGAnimationElement* /*aSrcElement*/,
     nsSMILValue& aValue, bool& aPreventCachingOfSandwich) const {
   nsAtom* valAtom = NS_GetStaticAtom(aStr);
   if (valAtom) {
-    const nsSVGEnumMapping* mapping = mVal->GetMapping(mSVGElement);
+    const SVGEnumMapping* mapping = mVal->GetMapping(mSVGElement);
 
     while (mapping && mapping->mKey) {
       if (valAtom == mapping->mKey) {
         nsSMILValue val(SMILEnumType::Singleton());
         val.mU.mUint = mapping->mVal;
         aValue = val;
         aPreventCachingOfSandwich = false;
         return NS_OK;
@@ -137,32 +138,34 @@ nsresult nsSVGEnum::SMILEnum::ValueFromS
     }
   }
 
   // only a warning since authors may mistype attribute values
   NS_WARNING("unknown enumeration key");
   return NS_ERROR_FAILURE;
 }
 
-nsSMILValue nsSVGEnum::SMILEnum::GetBaseValue() const {
+nsSMILValue SVGEnum::SMILEnum::GetBaseValue() const {
   nsSMILValue val(SMILEnumType::Singleton());
   val.mU.mUint = mVal->mBaseVal;
   return val;
 }
 
-void nsSVGEnum::SMILEnum::ClearAnimValue() {
+void SVGEnum::SMILEnum::ClearAnimValue() {
   if (mVal->mIsAnimated) {
     mVal->mIsAnimated = false;
     mVal->mAnimVal = mVal->mBaseVal;
     mSVGElement->DidAnimateEnum(mVal->mAttrEnum);
   }
 }
 
-nsresult nsSVGEnum::SMILEnum::SetAnimValue(const nsSMILValue& aValue) {
+nsresult SVGEnum::SMILEnum::SetAnimValue(const nsSMILValue& aValue) {
   NS_ASSERTION(aValue.mType == SMILEnumType::Singleton(),
                "Unexpected type to assign animated value");
   if (aValue.mType == SMILEnumType::Singleton()) {
     MOZ_ASSERT(aValue.mU.mUint <= USHRT_MAX,
                "Very large enumerated value - too big for uint16_t");
     mVal->SetAnimValue(uint16_t(aValue.mU.mUint), mSVGElement);
   }
   return NS_OK;
 }
+
+}  // namespace mozilla
rename from dom/svg/nsSVGEnum.h
rename to dom/svg/SVGEnum.h
--- a/dom/svg/nsSVGEnum.h
+++ b/dom/svg/SVGEnum.h
@@ -5,38 +5,37 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef __NS_SVGENUM_H__
 #define __NS_SVGENUM_H__
 
 #include "nsCycleCollectionParticipant.h"
 #include "nsError.h"
 #include "nsISMILAttr.h"
-#include "SVGElement.h"
 #include "mozilla/Attributes.h"
+#include "mozilla/UniquePtr.h"
 #include "mozilla/dom/SVGAnimatedEnumeration.h"
-#include "mozilla/UniquePtr.h"
+#include "mozilla/dom/SVGElement.h"
 
 class nsAtom;
 class nsSMILValue;
 
 namespace mozilla {
 namespace dom {
 class SVGAnimationElement;
 }  // namespace dom
-}  // namespace mozilla
 
-typedef uint8_t nsSVGEnumValue;
+typedef uint8_t SVGEnumValue;
 
-struct nsSVGEnumMapping {
+struct SVGEnumMapping {
   nsStaticAtom* const mKey;
-  const nsSVGEnumValue mVal;
+  const SVGEnumValue mVal;
 };
 
-class nsSVGEnum {
+class SVGEnum {
  public:
   typedef mozilla::dom::SVGElement SVGElement;
 
   void Init(uint8_t aAttrEnum, uint16_t aValue) {
     mAnimVal = mBaseVal = uint8_t(aValue);
     mAttrEnum = aAttrEnum;
     mIsAnimated = false;
     mIsBaseSet = false;
@@ -52,31 +51,31 @@ class nsSVGEnum {
   bool IsExplicitlySet() const { return mIsAnimated || mIsBaseSet; }
 
   already_AddRefed<mozilla::dom::SVGAnimatedEnumeration> ToDOMAnimatedEnum(
       SVGElement* aSVGElement);
 
   mozilla::UniquePtr<nsISMILAttr> ToSMILAttr(SVGElement* aSVGElement);
 
  private:
-  nsSVGEnumValue mAnimVal;
-  nsSVGEnumValue mBaseVal;
+  SVGEnumValue mAnimVal;
+  SVGEnumValue mBaseVal;
   uint8_t mAttrEnum;  // element specified tracking for attribute
   bool mIsAnimated;
   bool mIsBaseSet;
 
-  const nsSVGEnumMapping* GetMapping(SVGElement* aSVGElement);
+  const SVGEnumMapping* GetMapping(SVGElement* aSVGElement);
 
  public:
   struct DOMAnimatedEnum final : public mozilla::dom::SVGAnimatedEnumeration {
-    DOMAnimatedEnum(nsSVGEnum* aVal, SVGElement* aSVGElement)
+    DOMAnimatedEnum(SVGEnum* aVal, SVGElement* aSVGElement)
         : mozilla::dom::SVGAnimatedEnumeration(aSVGElement), mVal(aVal) {}
     virtual ~DOMAnimatedEnum();
 
-    nsSVGEnum* mVal;  // kept alive because it belongs to content
+    SVGEnum* mVal;  // kept alive because it belongs to content
 
     using mozilla::dom::SVGAnimatedEnumeration::SetBaseVal;
     virtual uint16_t BaseVal() override { return mVal->GetBaseValue(); }
     virtual void SetBaseVal(uint16_t aBaseVal,
                             mozilla::ErrorResult& aRv) override {
       aRv = mVal->SetBaseValue(aBaseVal, mSVGElement);
     }
     virtual uint16_t AnimVal() override {
@@ -85,29 +84,31 @@ class nsSVGEnum {
       // modifications.
       mSVGElement->FlushAnimations();
       return mVal->GetAnimValue();
     }
   };
 
   struct SMILEnum : public nsISMILAttr {
    public:
-    SMILEnum(nsSVGEnum* aVal, SVGElement* aSVGElement)
+    SMILEnum(SVGEnum* aVal, SVGElement* aSVGElement)
         : mVal(aVal), mSVGElement(aSVGElement) {}
 
     // These will stay alive because a nsISMILAttr only lives as long
     // as the Compositing step, and DOM elements don't get a chance to
     // die during that.
-    nsSVGEnum* mVal;
+    SVGEnum* mVal;
     SVGElement* mSVGElement;
 
     // nsISMILAttr methods
     virtual nsresult ValueFromString(
         const nsAString& aStr,
         const mozilla::dom::SVGAnimationElement* aSrcElement,
         nsSMILValue& aValue, bool& aPreventCachingOfSandwich) const override;
     virtual nsSMILValue GetBaseValue() const override;
     virtual void ClearAnimValue() override;
     virtual nsresult SetAnimValue(const nsSMILValue& aValue) override;
   };
 };
 
+}  // namespace mozilla
+
 #endif  //__NS_SVGENUM_H__
--- a/dom/svg/SVGFEBlendElement.cpp
+++ b/dom/svg/SVGFEBlendElement.cpp
@@ -15,17 +15,17 @@ using namespace mozilla::gfx;
 namespace mozilla {
 namespace dom {
 
 JSObject* SVGFEBlendElement::WrapNode(JSContext* aCx,
                                       JS::Handle<JSObject*> aGivenProto) {
   return SVGFEBlendElement_Binding::Wrap(aCx, this, aGivenProto);
 }
 
-nsSVGEnumMapping SVGFEBlendElement::sModeMap[] = {
+SVGEnumMapping SVGFEBlendElement::sModeMap[] = {
     {nsGkAtoms::normal, SVG_FEBLEND_MODE_NORMAL},
     {nsGkAtoms::multiply, SVG_FEBLEND_MODE_MULTIPLY},
     {nsGkAtoms::screen, SVG_FEBLEND_MODE_SCREEN},
     {nsGkAtoms::darken, SVG_FEBLEND_MODE_DARKEN},
     {nsGkAtoms::lighten, SVG_FEBLEND_MODE_LIGHTEN},
     {nsGkAtoms::overlay, SVG_FEBLEND_MODE_OVERLAY},
     {nsGkAtoms::colorDodge, SVG_FEBLEND_MODE_COLOR_DODGE},
     {nsGkAtoms::colorBurn, SVG_FEBLEND_MODE_COLOR_BURN},
--- a/dom/svg/SVGFEBlendElement.h
+++ b/dom/svg/SVGFEBlendElement.h
@@ -2,18 +2,18 @@
 /* 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_SVGFEBlendElement_h
 #define mozilla_dom_SVGFEBlendElement_h
 
+#include "SVGEnum.h"
 #include "SVGFilters.h"
-#include "nsSVGEnum.h"
 
 nsresult NS_NewSVGFEBlendElement(
     nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 namespace mozilla {
 namespace dom {
 
 typedef SVGFE SVGFEBlendElementBase;
 
@@ -48,18 +48,18 @@ class SVGFEBlendElement : public SVGFEBl
   already_AddRefed<SVGAnimatedString> In2();
   already_AddRefed<SVGAnimatedEnumeration> Mode();
 
  protected:
   virtual EnumAttributesInfo GetEnumInfo() override;
   virtual StringAttributesInfo GetStringInfo() override;
 
   enum { MODE };
-  nsSVGEnum mEnumAttributes[1];
-  static nsSVGEnumMapping sModeMap[];
+  SVGEnum mEnumAttributes[1];
+  static SVGEnumMapping sModeMap[];
   static EnumInfo sEnumInfo[1];
 
   enum { RESULT, IN1, IN2 };
   nsSVGString mStringAttributes[3];
   static StringInfo sStringInfo[3];
 };
 
 }  // namespace dom
--- a/dom/svg/SVGFEColorMatrixElement.cpp
+++ b/dom/svg/SVGFEColorMatrixElement.cpp
@@ -19,17 +19,17 @@ using namespace mozilla::gfx;
 namespace mozilla {
 namespace dom {
 
 JSObject* SVGFEColorMatrixElement::WrapNode(JSContext* aCx,
                                             JS::Handle<JSObject*> aGivenProto) {
   return SVGFEColorMatrixElement_Binding::Wrap(aCx, this, aGivenProto);
 }
 
-nsSVGEnumMapping SVGFEColorMatrixElement::sTypeMap[] = {
+SVGEnumMapping SVGFEColorMatrixElement::sTypeMap[] = {
     {nsGkAtoms::matrix, SVG_FECOLORMATRIX_TYPE_MATRIX},
     {nsGkAtoms::saturate, SVG_FECOLORMATRIX_TYPE_SATURATE},
     {nsGkAtoms::hueRotate, SVG_FECOLORMATRIX_TYPE_HUE_ROTATE},
     {nsGkAtoms::luminanceToAlpha, SVG_FECOLORMATRIX_TYPE_LUMINANCE_TO_ALPHA},
     {nullptr, 0}};
 
 SVGElement::EnumInfo SVGFEColorMatrixElement::sEnumInfo[1] = {
     {nsGkAtoms::type, sTypeMap, SVG_FECOLORMATRIX_TYPE_MATRIX}};
--- a/dom/svg/SVGFEColorMatrixElement.h
+++ b/dom/svg/SVGFEColorMatrixElement.h
@@ -2,19 +2,19 @@
 /* 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_SVGFEColorMatrixElement_h
 #define mozilla_dom_SVGFEColorMatrixElement_h
 
-#include "nsSVGEnum.h"
+#include "SVGAnimatedNumberList.h"
+#include "SVGEnum.h"
 #include "SVGFilters.h"
-#include "SVGAnimatedNumberList.h"
 
 nsresult NS_NewSVGFEColorMatrixElement(
     nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
 namespace mozilla {
 namespace dom {
 
 class DOMSVGAnimatedNumberList;
@@ -53,18 +53,18 @@ class SVGFEColorMatrixElement : public S
   already_AddRefed<DOMSVGAnimatedNumberList> Values();
 
  protected:
   virtual EnumAttributesInfo GetEnumInfo() override;
   virtual StringAttributesInfo GetStringInfo() override;
   virtual NumberListAttributesInfo GetNumberListInfo() override;
 
   enum { TYPE };
-  nsSVGEnum mEnumAttributes[1];
-  static nsSVGEnumMapping sTypeMap[];
+  SVGEnum mEnumAttributes[1];
+  static SVGEnumMapping sTypeMap[];
   static EnumInfo sEnumInfo[1];
 
   enum { RESULT, IN1 };
   nsSVGString mStringAttributes[2];
   static StringInfo sStringInfo[2];
 
   enum { VALUES };
   SVGAnimatedNumberList mNumberListAttributes[1];
--- a/dom/svg/SVGFECompositeElement.cpp
+++ b/dom/svg/SVGFECompositeElement.cpp
@@ -20,17 +20,17 @@ JSObject* SVGFECompositeElement::WrapNod
 }
 
 SVGElement::NumberInfo SVGFECompositeElement::sNumberInfo[4] = {
     {nsGkAtoms::k1, 0, false},
     {nsGkAtoms::k2, 0, false},
     {nsGkAtoms::k3, 0, false},
     {nsGkAtoms::k4, 0, false}};
 
-nsSVGEnumMapping SVGFECompositeElement::sOperatorMap[] = {
+SVGEnumMapping SVGFECompositeElement::sOperatorMap[] = {
     {nsGkAtoms::over, SVG_FECOMPOSITE_OPERATOR_OVER},
     {nsGkAtoms::in, SVG_FECOMPOSITE_OPERATOR_IN},
     {nsGkAtoms::out, SVG_FECOMPOSITE_OPERATOR_OUT},
     {nsGkAtoms::atop, SVG_FECOMPOSITE_OPERATOR_ATOP},
     {nsGkAtoms::xor_, SVG_FECOMPOSITE_OPERATOR_XOR},
     {nsGkAtoms::arithmetic, SVG_FECOMPOSITE_OPERATOR_ARITHMETIC},
     {nullptr, 0}};
 
--- a/dom/svg/SVGFECompositeElement.h
+++ b/dom/svg/SVGFECompositeElement.h
@@ -2,17 +2,17 @@
 /* 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_SVGFECompositeElement_h
 #define mozilla_dom_SVGFECompositeElement_h
 
-#include "nsSVGEnum.h"
+#include "SVGEnum.h"
 #include "SVGFilters.h"
 #include "nsSVGNumber2.h"
 
 nsresult NS_NewSVGFECompositeElement(
     nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
 namespace mozilla {
 namespace dom {
@@ -60,18 +60,18 @@ class SVGFECompositeElement : public SVG
   virtual EnumAttributesInfo GetEnumInfo() override;
   virtual StringAttributesInfo GetStringInfo() override;
 
   enum { ATTR_K1, ATTR_K2, ATTR_K3, ATTR_K4 };
   nsSVGNumber2 mNumberAttributes[4];
   static NumberInfo sNumberInfo[4];
 
   enum { OPERATOR };
-  nsSVGEnum mEnumAttributes[1];
-  static nsSVGEnumMapping sOperatorMap[];
+  SVGEnum mEnumAttributes[1];
+  static SVGEnumMapping sOperatorMap[];
   static EnumInfo sEnumInfo[1];
 
   enum { RESULT, IN1, IN2 };
   nsSVGString mStringAttributes[3];
   static StringInfo sStringInfo[3];
 };
 
 }  // namespace dom
--- a/dom/svg/SVGFEConvolveMatrixElement.cpp
+++ b/dom/svg/SVGFEConvolveMatrixElement.cpp
@@ -34,17 +34,17 @@ SVGElement::IntegerInfo SVGFEConvolveMat
     {nsGkAtoms::targetX, 0}, {nsGkAtoms::targetY, 0}};
 
 SVGElement::IntegerPairInfo SVGFEConvolveMatrixElement::sIntegerPairInfo[1] = {
     {nsGkAtoms::order, 3, 3}};
 
 SVGElement::BooleanInfo SVGFEConvolveMatrixElement::sBooleanInfo[1] = {
     {nsGkAtoms::preserveAlpha, false}};
 
-nsSVGEnumMapping SVGFEConvolveMatrixElement::sEdgeModeMap[] = {
+SVGEnumMapping SVGFEConvolveMatrixElement::sEdgeModeMap[] = {
     {nsGkAtoms::duplicate, SVG_EDGEMODE_DUPLICATE},
     {nsGkAtoms::wrap, SVG_EDGEMODE_WRAP},
     {nsGkAtoms::none, SVG_EDGEMODE_NONE},
     {nullptr, 0}};
 
 SVGElement::EnumInfo SVGFEConvolveMatrixElement::sEnumInfo[1] = {
     {nsGkAtoms::edgeMode, sEdgeModeMap, SVG_EDGEMODE_DUPLICATE}};
 
--- a/dom/svg/SVGFEConvolveMatrixElement.h
+++ b/dom/svg/SVGFEConvolveMatrixElement.h
@@ -2,24 +2,24 @@
 /* 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_SVGFEConvolveMatrixElement_h
 #define mozilla_dom_SVGFEConvolveMatrixElement_h
 
+#include "SVGAnimatedNumberList.h"
 #include "nsSVGBoolean.h"
-#include "nsSVGEnum.h"
+#include "SVGEnum.h"
 #include "SVGFilters.h"
 #include "nsSVGInteger.h"
 #include "nsSVGIntegerPair.h"
 #include "nsSVGNumber2.h"
 #include "nsSVGString.h"
-#include "SVGAnimatedNumberList.h"
 
 nsresult NS_NewSVGFEConvolveMatrixElement(
     nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
 namespace mozilla {
 
 namespace dom {
 class DOMSVGAnimatedNumberList;
@@ -93,18 +93,18 @@ class SVGFEConvolveMatrixElement : publi
   nsSVGIntegerPair mIntegerPairAttributes[1];
   static IntegerPairInfo sIntegerPairInfo[1];
 
   enum { PRESERVEALPHA };
   nsSVGBoolean mBooleanAttributes[1];
   static BooleanInfo sBooleanInfo[1];
 
   enum { EDGEMODE };
-  nsSVGEnum mEnumAttributes[1];
-  static nsSVGEnumMapping sEdgeModeMap[];
+  SVGEnum mEnumAttributes[1];
+  static SVGEnumMapping sEdgeModeMap[];
   static EnumInfo sEnumInfo[1];
 
   enum { RESULT, IN1 };
   nsSVGString mStringAttributes[2];
   static StringInfo sStringInfo[2];
 
   enum { KERNELMATRIX };
   SVGAnimatedNumberList mNumberListAttributes[1];
--- a/dom/svg/SVGFEDisplacementMapElement.cpp
+++ b/dom/svg/SVGFEDisplacementMapElement.cpp
@@ -20,17 +20,17 @@ JSObject* SVGFEDisplacementMapElement::W
     JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
   return SVGFEDisplacementMapElement_Binding::Wrap(aCx, this, aGivenProto);
 }
 
 SVGElement::NumberInfo SVGFEDisplacementMapElement::sNumberInfo[1] = {
     {nsGkAtoms::scale, 0, false},
 };
 
-nsSVGEnumMapping SVGFEDisplacementMapElement::sChannelMap[] = {
+SVGEnumMapping SVGFEDisplacementMapElement::sChannelMap[] = {
     {nsGkAtoms::R, SVG_CHANNEL_R},
     {nsGkAtoms::G, SVG_CHANNEL_G},
     {nsGkAtoms::B, SVG_CHANNEL_B},
     {nsGkAtoms::A, SVG_CHANNEL_A},
     {nullptr, 0}};
 
 SVGElement::EnumInfo SVGFEDisplacementMapElement::sEnumInfo[2] = {
     {nsGkAtoms::xChannelSelector, sChannelMap, SVG_CHANNEL_A},
--- a/dom/svg/SVGFEDisplacementMapElement.h
+++ b/dom/svg/SVGFEDisplacementMapElement.h
@@ -2,17 +2,17 @@
 /* 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_SVGFEDisplacementMapElement_h
 #define mozilla_dom_SVGFEDisplacementMapElement_h
 
-#include "nsSVGEnum.h"
+#include "SVGEnum.h"
 #include "SVGFilters.h"
 
 nsresult NS_NewSVGFEDisplacementMapElement(
     nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
 namespace mozilla {
 namespace dom {
 
@@ -69,18 +69,18 @@ class SVGFEDisplacementMapElement : publ
   virtual EnumAttributesInfo GetEnumInfo() override;
   virtual StringAttributesInfo GetStringInfo() override;
 
   enum { SCALE };
   nsSVGNumber2 mNumberAttributes[1];
   static NumberInfo sNumberInfo[1];
 
   enum { CHANNEL_X, CHANNEL_Y };
-  nsSVGEnum mEnumAttributes[2];
-  static nsSVGEnumMapping sChannelMap[];
+  SVGEnum mEnumAttributes[2];
+  static SVGEnumMapping sChannelMap[];
   static EnumInfo sEnumInfo[2];
 
   enum { RESULT, IN1, IN2 };
   nsSVGString mStringAttributes[3];
   static StringInfo sStringInfo[3];
 };
 
 }  // namespace dom
--- a/dom/svg/SVGFEMorphologyElement.cpp
+++ b/dom/svg/SVGFEMorphologyElement.cpp
@@ -18,17 +18,17 @@ namespace dom {
 JSObject* SVGFEMorphologyElement::WrapNode(JSContext* aCx,
                                            JS::Handle<JSObject*> aGivenProto) {
   return SVGFEMorphologyElement_Binding::Wrap(aCx, this, aGivenProto);
 }
 
 SVGElement::NumberPairInfo SVGFEMorphologyElement::sNumberPairInfo[1] = {
     {nsGkAtoms::radius, 0, 0}};
 
-nsSVGEnumMapping SVGFEMorphologyElement::sOperatorMap[] = {
+SVGEnumMapping SVGFEMorphologyElement::sOperatorMap[] = {
     {nsGkAtoms::erode, SVG_OPERATOR_ERODE},
     {nsGkAtoms::dilate, SVG_OPERATOR_DILATE},
     {nullptr, 0}};
 
 SVGElement::EnumInfo SVGFEMorphologyElement::sEnumInfo[1] = {
     {nsGkAtoms::_operator, sOperatorMap, SVG_OPERATOR_ERODE}};
 
 SVGElement::StringInfo SVGFEMorphologyElement::sStringInfo[2] = {
--- a/dom/svg/SVGFEMorphologyElement.h
+++ b/dom/svg/SVGFEMorphologyElement.h
@@ -2,17 +2,17 @@
 /* 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_SVGFEMorphologyElement_h
 #define mozilla_dom_SVGFEMorphologyElement_h
 
-#include "nsSVGEnum.h"
+#include "SVGEnum.h"
 #include "SVGFilters.h"
 #include "nsSVGNumberPair.h"
 #include "nsSVGString.h"
 
 nsresult NS_NewSVGFEMorphologyElement(
     nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
 namespace mozilla {
@@ -60,18 +60,18 @@ class SVGFEMorphologyElement : public SV
   virtual EnumAttributesInfo GetEnumInfo() override;
   virtual StringAttributesInfo GetStringInfo() override;
 
   enum { RADIUS };
   nsSVGNumberPair mNumberPairAttributes[1];
   static NumberPairInfo sNumberPairInfo[1];
 
   enum { OPERATOR };
-  nsSVGEnum mEnumAttributes[1];
-  static nsSVGEnumMapping sOperatorMap[];
+  SVGEnum mEnumAttributes[1];
+  static SVGEnumMapping sOperatorMap[];
   static EnumInfo sEnumInfo[1];
 
   enum { RESULT, IN1 };
   nsSVGString mStringAttributes[2];
   static StringInfo sStringInfo[2];
 };
 
 }  // namespace dom
--- a/dom/svg/SVGFETurbulenceElement.cpp
+++ b/dom/svg/SVGFETurbulenceElement.cpp
@@ -31,22 +31,22 @@ SVGElement::NumberInfo SVGFETurbulenceEl
     {nsGkAtoms::seed, 0, false}};
 
 SVGElement::NumberPairInfo SVGFETurbulenceElement::sNumberPairInfo[1] = {
     {nsGkAtoms::baseFrequency, 0, 0}};
 
 SVGElement::IntegerInfo SVGFETurbulenceElement::sIntegerInfo[1] = {
     {nsGkAtoms::numOctaves, 1}};
 
-nsSVGEnumMapping SVGFETurbulenceElement::sTypeMap[] = {
+SVGEnumMapping SVGFETurbulenceElement::sTypeMap[] = {
     {nsGkAtoms::fractalNoise, SVG_TURBULENCE_TYPE_FRACTALNOISE},
     {nsGkAtoms::turbulence, SVG_TURBULENCE_TYPE_TURBULENCE},
     {nullptr, 0}};
 
-nsSVGEnumMapping SVGFETurbulenceElement::sStitchTilesMap[] = {
+SVGEnumMapping SVGFETurbulenceElement::sStitchTilesMap[] = {
     {nsGkAtoms::stitch, SVG_STITCHTYPE_STITCH},
     {nsGkAtoms::noStitch, SVG_STITCHTYPE_NOSTITCH},
     {nullptr, 0}};
 
 SVGElement::EnumInfo SVGFETurbulenceElement::sEnumInfo[2] = {
     {nsGkAtoms::type, sTypeMap, SVG_TURBULENCE_TYPE_TURBULENCE},
     {nsGkAtoms::stitchTiles, sStitchTilesMap, SVG_STITCHTYPE_NOSTITCH}};
 
--- a/dom/svg/SVGFETurbulenceElement.h
+++ b/dom/svg/SVGFETurbulenceElement.h
@@ -2,17 +2,17 @@
 /* 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_SVGFETurbulenceElement_h
 #define mozilla_dom_SVGFETurbulenceElement_h
 
-#include "nsSVGEnum.h"
+#include "SVGEnum.h"
 #include "SVGFilters.h"
 #include "nsSVGNumber2.h"
 #include "nsSVGInteger.h"
 #include "nsSVGString.h"
 
 nsresult NS_NewSVGFETurbulenceElement(
     nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
@@ -71,19 +71,19 @@ class SVGFETurbulenceElement : public SV
   nsSVGNumberPair mNumberPairAttributes[1];
   static NumberPairInfo sNumberPairInfo[1];
 
   enum { OCTAVES };
   nsSVGInteger mIntegerAttributes[1];
   static IntegerInfo sIntegerInfo[1];
 
   enum { TYPE, STITCHTILES };
-  nsSVGEnum mEnumAttributes[2];
-  static nsSVGEnumMapping sTypeMap[];
-  static nsSVGEnumMapping sStitchTilesMap[];
+  SVGEnum mEnumAttributes[2];
+  static SVGEnumMapping sTypeMap[];
+  static SVGEnumMapping sStitchTilesMap[];
   static EnumInfo sEnumInfo[2];
 
   enum { RESULT };
   nsSVGString mStringAttributes[1];
   static StringInfo sStringInfo[1];
 };
 
 }  // namespace dom
--- a/dom/svg/SVGFilterElement.h
+++ b/dom/svg/SVGFilterElement.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 mozilla_dom_SVGFilterElement_h
 #define mozilla_dom_SVGFilterElement_h
 
-#include "nsSVGEnum.h"
-#include "SVGElement.h"
+#include "SVGEnum.h"
 #include "nsSVGIntegerPair.h"
 #include "nsSVGLength2.h"
 #include "nsSVGString.h"
+#include "mozilla/dom/SVGElement.h"
 
 class nsSVGFilterFrame;
 class nsSVGFilterInstance;
 
 nsresult NS_NewSVGFilterElement(
     nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
 namespace mozilla {
@@ -60,17 +60,17 @@ class SVGFilterElement : public SVGFilte
   virtual EnumAttributesInfo GetEnumInfo() override;
   virtual StringAttributesInfo GetStringInfo() override;
 
   enum { ATTR_X, ATTR_Y, ATTR_WIDTH, ATTR_HEIGHT };
   nsSVGLength2 mLengthAttributes[4];
   static LengthInfo sLengthInfo[4];
 
   enum { FILTERUNITS, PRIMITIVEUNITS };
-  nsSVGEnum mEnumAttributes[2];
+  SVGEnum mEnumAttributes[2];
   static EnumInfo sEnumInfo[2];
 
   enum { HREF, XLINK_HREF };
   nsSVGString mStringAttributes[2];
   static StringInfo sStringInfo[2];
 };
 
 }  // namespace dom
--- a/dom/svg/SVGFilters.cpp
+++ b/dom/svg/SVGFilters.cpp
@@ -1,48 +1,48 @@
 /* -*- 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 "SVGFilters.h"
 
-#include "SVGElement.h"
+#include <algorithm>
+#include "DOMSVGAnimatedNumberList.h"
+#include "imgIContainer.h"
 #include "nsGkAtoms.h"
-#include "nsSVGNumber2.h"
-#include "nsSVGNumberPair.h"
+#include "nsCOMPtr.h"
+#include "nsIFrame.h"
+#include "nsLayoutUtils.h"
+#include "SVGAnimatedNumberList.h"
+#include "nsSVGBoolean.h"
+#include "SVGEnum.h"
+#include "nsSVGFilterInstance.h"
 #include "nsSVGInteger.h"
 #include "nsSVGIntegerPair.h"
-#include "nsSVGBoolean.h"
-#include "nsCOMPtr.h"
-#include "nsSVGFilterInstance.h"
-#include "nsSVGEnum.h"
+#include "nsSVGNumber2.h"
+#include "nsSVGNumberPair.h"
 #include "SVGNumberList.h"
-#include "SVGAnimatedNumberList.h"
-#include "DOMSVGAnimatedNumberList.h"
-#include "nsLayoutUtils.h"
+#include "nsSVGString.h"
+#include "mozilla/ArrayUtils.h"
+#include "mozilla/ComputedStyle.h"
+#include "mozilla/SVGContentUtils.h"
 #include "nsSVGUtils.h"
-#include "mozilla/ComputedStyle.h"
-#include "nsIFrame.h"
-#include "imgIContainer.h"
-#include "mozilla/dom/SVGFilterElement.h"
-#include "nsSVGString.h"
-#include "SVGContentUtils.h"
-#include <algorithm>
-#include "mozilla/ArrayUtils.h"
 #include "mozilla/dom/SVGAnimatedLength.h"
 #include "mozilla/dom/SVGComponentTransferFunctionElement.h"
+#include "mozilla/dom/SVGElement.h"
 #include "mozilla/dom/SVGFEDistantLightElement.h"
 #include "mozilla/dom/SVGFEFuncAElementBinding.h"
 #include "mozilla/dom/SVGFEFuncBElementBinding.h"
 #include "mozilla/dom/SVGFEFuncGElementBinding.h"
 #include "mozilla/dom/SVGFEFuncRElementBinding.h"
 #include "mozilla/dom/SVGFEPointLightElement.h"
 #include "mozilla/dom/SVGFESpotLightElement.h"
+#include "mozilla/dom/SVGFilterElement.h"
 #include "mozilla/dom/SVGLengthBinding.h"
 
 #if defined(XP_WIN)
 // Prevent Windows redefining LoadImage
 #undef LoadImage
 #endif
 
 using namespace mozilla::gfx;
@@ -171,17 +171,17 @@ SVGElement::NumberListInfo
 
 SVGElement::NumberInfo SVGComponentTransferFunctionElement::sNumberInfo[5] = {
     {nsGkAtoms::slope, 1, false},
     {nsGkAtoms::intercept, 0, false},
     {nsGkAtoms::amplitude, 1, false},
     {nsGkAtoms::exponent, 1, false},
     {nsGkAtoms::offset, 0, false}};
 
-nsSVGEnumMapping SVGComponentTransferFunctionElement::sTypeMap[] = {
+SVGEnumMapping SVGComponentTransferFunctionElement::sTypeMap[] = {
     {nsGkAtoms::identity, SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY},
     {nsGkAtoms::table, SVG_FECOMPONENTTRANSFER_TYPE_TABLE},
     {nsGkAtoms::discrete, SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE},
     {nsGkAtoms::linear, SVG_FECOMPONENTTRANSFER_TYPE_LINEAR},
     {nsGkAtoms::gamma, SVG_FECOMPONENTTRANSFER_TYPE_GAMMA},
     {nullptr, 0}};
 
 SVGElement::EnumInfo SVGComponentTransferFunctionElement::sEnumInfo[1] = {
--- a/dom/svg/SVGGradientElement.cpp
+++ b/dom/svg/SVGGradientElement.cpp
@@ -23,17 +23,17 @@ NS_IMPL_NS_NEW_SVG_ELEMENT(RadialGradien
 namespace mozilla {
 namespace dom {
 
 using namespace SVGGradientElement_Binding;
 using namespace SVGUnitTypes_Binding;
 
 //--------------------- Gradients------------------------
 
-nsSVGEnumMapping SVGGradientElement::sSpreadMethodMap[] = {
+SVGEnumMapping SVGGradientElement::sSpreadMethodMap[] = {
     {nsGkAtoms::pad, SVG_SPREADMETHOD_PAD},
     {nsGkAtoms::reflect, SVG_SPREADMETHOD_REFLECT},
     {nsGkAtoms::repeat, SVG_SPREADMETHOD_REPEAT},
     {nullptr, 0}};
 
 SVGElement::EnumInfo SVGGradientElement::sEnumInfo[2] = {
     {nsGkAtoms::gradientUnits, sSVGUnitTypesMap,
      SVG_UNIT_TYPE_OBJECTBOUNDINGBOX},
--- a/dom/svg/SVGGradientElement.h
+++ b/dom/svg/SVGGradientElement.h
@@ -3,21 +3,21 @@
 /* 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_SVGGRADIENTELEMENT_H__
 #define __NS_SVGGRADIENTELEMENT_H__
 
 #include "nsAutoPtr.h"
-#include "SVGAnimatedTransformList.h"
-#include "SVGElement.h"
-#include "nsSVGEnum.h"
+#include "SVGEnum.h"
 #include "nsSVGLength2.h"
 #include "nsSVGString.h"
+#include "SVGAnimatedTransformList.h"
+#include "mozilla/dom/SVGElement.h"
 
 class nsSVGGradientFrame;
 class nsSVGLinearGradientFrame;
 class nsSVGRadialGradientFrame;
 
 nsresult NS_NewSVGLinearGradientElement(
     nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 nsresult NS_NewSVGRadialGradientElement(
@@ -59,18 +59,18 @@ class SVGGradientElement : public SVGGra
   already_AddRefed<SVGAnimatedEnumeration> SpreadMethod();
   already_AddRefed<SVGAnimatedString> Href();
 
  protected:
   virtual EnumAttributesInfo GetEnumInfo() override;
   virtual StringAttributesInfo GetStringInfo() override;
 
   enum { GRADIENTUNITS, SPREADMETHOD };
-  nsSVGEnum mEnumAttributes[2];
-  static nsSVGEnumMapping sSpreadMethodMap[];
+  SVGEnum mEnumAttributes[2];
+  static SVGEnumMapping sSpreadMethodMap[];
   static EnumInfo sEnumInfo[2];
 
   enum { HREF, XLINK_HREF };
   nsSVGString mStringAttributes[2];
   static StringInfo sStringInfo[2];
 
   // SVGGradientElement values
   nsAutoPtr<SVGAnimatedTransformList> mGradientTransform;
--- a/dom/svg/SVGMarkerElement.cpp
+++ b/dom/svg/SVGMarkerElement.cpp
@@ -40,17 +40,17 @@ SVGElement::LengthInfo SVGMarkerElement:
     {nsGkAtoms::refY, 0, SVGLength_Binding::SVG_LENGTHTYPE_NUMBER,
      SVGContentUtils::Y},
     {nsGkAtoms::markerWidth, 3, SVGLength_Binding::SVG_LENGTHTYPE_NUMBER,
      SVGContentUtils::X},
     {nsGkAtoms::markerHeight, 3, SVGLength_Binding::SVG_LENGTHTYPE_NUMBER,
      SVGContentUtils::Y},
 };
 
-nsSVGEnumMapping SVGMarkerElement::sUnitsMap[] = {
+SVGEnumMapping SVGMarkerElement::sUnitsMap[] = {
     {nsGkAtoms::strokeWidth, SVG_MARKERUNITS_STROKEWIDTH},
     {nsGkAtoms::userSpaceOnUse, SVG_MARKERUNITS_USERSPACEONUSE},
     {nullptr, 0}};
 
 SVGElement::EnumInfo SVGMarkerElement::sEnumInfo[1] = {
     {nsGkAtoms::markerUnits, sUnitsMap, SVG_MARKERUNITS_STROKEWIDTH}};
 
 SVGElement::AngleInfo SVGMarkerElement::sAngleInfo[1] = {
--- a/dom/svg/SVGMarkerElement.h
+++ b/dom/svg/SVGMarkerElement.h
@@ -4,23 +4,23 @@
  * 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_SVGMarkerElement_h
 #define mozilla_dom_SVGMarkerElement_h
 
 #include "nsAutoPtr.h"
 #include "SVGAngle.h"
-#include "nsSVGEnum.h"
+#include "SVGAnimatedPreserveAspectRatio.h"
+#include "SVGEnum.h"
 #include "nsSVGLength2.h"
 #include "nsSVGViewBox.h"
-#include "SVGAnimatedPreserveAspectRatio.h"
-#include "SVGElement.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/dom/SVGAnimatedEnumeration.h"
+#include "mozilla/dom/SVGElement.h"
 #include "mozilla/dom/SVGMarkerElementBinding.h"
 
 class nsSVGMarkerFrame;
 struct nsSVGMark;
 
 nsresult NS_NewSVGMarkerElement(
     nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
@@ -57,18 +57,18 @@ class nsSVGOrientType {
                : mAnimVal;
   }
   uint16_t GetAnimValueInternal() const { return mAnimVal; }
 
   already_AddRefed<SVGAnimatedEnumeration> ToDOMAnimatedEnum(
       SVGElement* aSVGElement);
 
  private:
-  nsSVGEnumValue mAnimVal;
-  nsSVGEnumValue mBaseVal;
+  SVGEnumValue mAnimVal;
+  SVGEnumValue mBaseVal;
 
   struct DOMAnimatedEnum final : public SVGAnimatedEnumeration {
     DOMAnimatedEnum(nsSVGOrientType* aVal, SVGElement* aSVGElement)
         : SVGAnimatedEnumeration(aSVGElement), mVal(aVal) {}
 
     nsSVGOrientType* mVal;  // kept alive because it belongs to content
 
     using mozilla::dom::SVGAnimatedEnumeration::SetBaseVal;
@@ -143,18 +143,18 @@ class SVGMarkerElement : public SVGMarke
   virtual nsSVGViewBox* GetViewBox() override;
   virtual SVGAnimatedPreserveAspectRatio* GetPreserveAspectRatio() override;
 
   enum { REFX, REFY, MARKERWIDTH, MARKERHEIGHT };
   nsSVGLength2 mLengthAttributes[4];
   static LengthInfo sLengthInfo[4];
 
   enum { MARKERUNITS };
-  nsSVGEnum mEnumAttributes[1];
-  static nsSVGEnumMapping sUnitsMap[];
+  SVGEnum mEnumAttributes[1];
+  static SVGEnumMapping sUnitsMap[];
   static EnumInfo sEnumInfo[1];
 
   enum { ORIENT };
   SVGAngle mAngleAttributes[1];
   static AngleInfo sAngleInfo[1];
 
   nsSVGViewBox mViewBox;
   SVGAnimatedPreserveAspectRatio mPreserveAspectRatio;
--- a/dom/svg/SVGMaskElement.h
+++ b/dom/svg/SVGMaskElement.h
@@ -2,19 +2,19 @@
 /* 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_SVGMaskElement_h
 #define mozilla_dom_SVGMaskElement_h
 
-#include "nsSVGEnum.h"
+#include "SVGEnum.h"
 #include "nsSVGLength2.h"
-#include "SVGElement.h"
+#include "mozilla/dom/SVGElement.h"
 
 class nsSVGMaskFrame;
 
 nsresult NS_NewSVGMaskElement(
     nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
 namespace mozilla {
 namespace dom {
@@ -54,16 +54,16 @@ class SVGMaskElement final : public SVGM
   virtual LengthAttributesInfo GetLengthInfo() override;
   virtual EnumAttributesInfo GetEnumInfo() override;
 
   enum { ATTR_X, ATTR_Y, ATTR_WIDTH, ATTR_HEIGHT };
   nsSVGLength2 mLengthAttributes[4];
   static LengthInfo sLengthInfo[4];
 
   enum { MASKUNITS, MASKCONTENTUNITS };
-  nsSVGEnum mEnumAttributes[2];
+  SVGEnum mEnumAttributes[2];
   static EnumInfo sEnumInfo[2];
 };
 
 }  // namespace dom
 }  // namespace mozilla
 
 #endif  // mozilla_dom_SVGMaskElement_h
--- 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 "SVGEnum.h"
 #include "nsSVGLength2.h"
 #include "nsSVGString.h"
 #include "nsSVGViewBox.h"
+#include "mozilla/dom/SVGElement.h"
 
 class nsSVGPatternFrame;
 
 nsresult NS_NewSVGPatternElement(
     nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
 namespace mozilla {
 namespace dom {
@@ -76,17 +76,17 @@ class SVGPatternElement final : public S
   virtual SVGAnimatedPreserveAspectRatio* GetPreserveAspectRatio() override;
   virtual StringAttributesInfo GetStringInfo() override;
 
   enum { ATTR_X, ATTR_Y, ATTR_WIDTH, ATTR_HEIGHT };
   nsSVGLength2 mLengthAttributes[4];
   static LengthInfo sLengthInfo[4];
 
   enum { PATTERNUNITS, PATTERNCONTENTUNITS };
-  nsSVGEnum mEnumAttributes[2];
+  SVGEnum mEnumAttributes[2];
   static EnumInfo sEnumInfo[2];
 
   nsAutoPtr<mozilla::SVGAnimatedTransformList> mPatternTransform;
 
   enum { HREF, XLINK_HREF };
   nsSVGString mStringAttributes[2];
   static StringInfo sStringInfo[2];
 
--- a/dom/svg/SVGSVGElement.cpp
+++ b/dom/svg/SVGSVGElement.cpp
@@ -31,17 +31,17 @@ NS_IMPL_NS_NEW_SVG_ELEMENT_CHECK_PARSER(
 using namespace mozilla::gfx;
 
 namespace mozilla {
 namespace dom {
 
 using namespace SVGPreserveAspectRatio_Binding;
 using namespace SVGSVGElement_Binding;
 
-nsSVGEnumMapping SVGSVGElement::sZoomAndPanMap[] = {
+SVGEnumMapping SVGSVGElement::sZoomAndPanMap[] = {
     {nsGkAtoms::disable, SVG_ZOOMANDPAN_DISABLE},
     {nsGkAtoms::magnify, SVG_ZOOMANDPAN_MAGNIFY},
     {nullptr, 0}};
 
 SVGElement::EnumInfo SVGSVGElement::sEnumInfo[1] = {
     {nsGkAtoms::zoomAndPan, sZoomAndPanMap, SVG_ZOOMANDPAN_MAGNIFY}};
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED(DOMSVGTranslatePoint, nsISVGPoint, mElement)
--- a/dom/svg/SVGSVGElement.h
+++ b/dom/svg/SVGSVGElement.h
@@ -2,16 +2,17 @@
 /* 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_SVGSVGElement_h
 #define mozilla_dom_SVGSVGElement_h
 
+#include "SVGEnum.h"
 #include "SVGViewportElement.h"
 
 nsresult NS_NewSVGSVGElement(
     nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
     mozilla::dom::FromParser aFromParser);
 
 namespace mozilla {
 class AutoSVGViewHandler;
@@ -27,17 +28,17 @@ class SVGMatrix;
 class SVGIRect;
 class SVGSVGElement;
 
 // Stores svgView arguments of SVG fragment identifiers.
 class SVGView {
  public:
   SVGView();
 
-  nsSVGEnum mZoomAndPan;
+  mozilla::SVGEnum mZoomAndPan;
   nsSVGViewBox mViewBox;
   SVGAnimatedPreserveAspectRatio mPreserveAspectRatio;
   nsAutoPtr<SVGAnimatedTransformList> mTransforms;
 };
 
 class DOMSVGTranslatePoint final : public nsISVGPoint {
  public:
   DOMSVGTranslatePoint(SVGPoint* aPt, SVGSVGElement* aElement)
@@ -219,18 +220,18 @@ class SVGSVGElement final : public SVGSV
   virtual float GetCurrentScale() const override { return mCurrentScale; }
 
   virtual const nsSVGViewBox& GetViewBoxInternal() const override;
   virtual SVGAnimatedTransformList* GetTransformInternal() const override;
 
   virtual EnumAttributesInfo GetEnumInfo() override;
 
   enum { ZOOMANDPAN };
-  nsSVGEnum mEnumAttributes[1];
-  static nsSVGEnumMapping sZoomAndPanMap[];
+  mozilla::SVGEnum mEnumAttributes[1];
+  static mozilla::SVGEnumMapping sZoomAndPanMap[];
   static EnumInfo sEnumInfo[1];
 
   // The time container for animations within this SVG document fragment. Set
   // for all outermost <svg> elements (not nested <svg> elements).
   nsAutoPtr<SMILTimeContainer> mTimedDocumentRoot;
 
   // zoom and pan
   // IMPORTANT: see the comment in RecordCurrentScaleTranslate before writing
--- a/dom/svg/SVGTSpanElement.h
+++ b/dom/svg/SVGTSpanElement.h
@@ -32,18 +32,18 @@ class SVGTSpanElement final : public SVG
   NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
 
   virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
 
  protected:
   virtual EnumAttributesInfo GetEnumInfo() override;
   virtual LengthAttributesInfo GetLengthInfo() override;
 
-  nsSVGEnum mEnumAttributes[1];
-  virtual nsSVGEnum* EnumAttributes() override { return mEnumAttributes; }
+  SVGEnum mEnumAttributes[1];
+  virtual SVGEnum* EnumAttributes() override { return mEnumAttributes; }
 
   nsSVGLength2 mLengthAttributes[1];
   virtual nsSVGLength2* LengthAttributes() override {
     return mLengthAttributes;
   }
 };
 
 }  // namespace dom
--- a/dom/svg/SVGTextContentElement.cpp
+++ b/dom/svg/SVGTextContentElement.cpp
@@ -16,17 +16,17 @@
 #include "nsTextNode.h"
 #include "SVGTextFrame.h"
 
 namespace mozilla {
 namespace dom {
 
 using namespace SVGTextContentElement_Binding;
 
-nsSVGEnumMapping SVGTextContentElement::sLengthAdjustMap[] = {
+SVGEnumMapping SVGTextContentElement::sLengthAdjustMap[] = {
     {nsGkAtoms::spacing, LENGTHADJUST_SPACING},
     {nsGkAtoms::spacingAndGlyphs, LENGTHADJUST_SPACINGANDGLYPHS},
     {nullptr, 0}};
 
 SVGElement::EnumInfo SVGTextContentElement::sEnumInfo[1] = {
     {nsGkAtoms::lengthAdjust, sLengthAdjustMap, LENGTHADJUST_SPACING}};
 
 SVGElement::LengthInfo SVGTextContentElement::sLengthInfo[1] = {
--- a/dom/svg/SVGTextContentElement.h
+++ b/dom/svg/SVGTextContentElement.h
@@ -4,17 +4,17 @@
  * 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_SVGTextContentElement_h
 #define mozilla_dom_SVGTextContentElement_h
 
 #include "mozilla/dom/SVGGraphicsElement.h"
 #include "mozilla/dom/SVGAnimatedEnumeration.h"
-#include "nsSVGEnum.h"
+#include "SVGEnum.h"
 #include "nsSVGLength2.h"
 
 class SVGTextFrame;
 
 namespace mozilla {
 class nsISVGPoint;
 
 namespace dom {
@@ -55,18 +55,18 @@ class SVGTextContentElement : public SVG
       : SVGTextContentElementBase(std::move(aNodeInfo)) {}
 
   MOZ_CAN_RUN_SCRIPT SVGTextFrame* GetSVGTextFrame();
   MOZ_CAN_RUN_SCRIPT SVGTextFrame* GetSVGTextFrameForNonLayoutDependentQuery();
   MOZ_CAN_RUN_SCRIPT mozilla::Maybe<int32_t>
   GetNonLayoutDependentNumberOfChars();
 
   enum { LENGTHADJUST };
-  virtual nsSVGEnum* EnumAttributes() = 0;
-  static nsSVGEnumMapping sLengthAdjustMap[];
+  virtual SVGEnum* EnumAttributes() = 0;
+  static SVGEnumMapping sLengthAdjustMap[];
   static EnumInfo sEnumInfo[1];
 
   enum { TEXTLENGTH };
   virtual nsSVGLength2* LengthAttributes() = 0;
   static LengthInfo sLengthInfo[1];
 };
 
 }  // namespace dom
--- a/dom/svg/SVGTextElement.h
+++ b/dom/svg/SVGTextElement.h
@@ -32,18 +32,18 @@ class SVGTextElement final : public SVGT
   NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
 
   virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
 
  protected:
   virtual EnumAttributesInfo GetEnumInfo() override;
   virtual LengthAttributesInfo GetLengthInfo() override;
 
-  nsSVGEnum mEnumAttributes[1];
-  virtual nsSVGEnum* EnumAttributes() override { return mEnumAttributes; }
+  SVGEnum mEnumAttributes[1];
+  virtual SVGEnum* EnumAttributes() override { return mEnumAttributes; }
 
   nsSVGLength2 mLengthAttributes[1];
   virtual nsSVGLength2* LengthAttributes() override {
     return mLengthAttributes;
   }
 };
 
 }  // namespace dom
--- a/dom/svg/SVGTextPathElement.cpp
+++ b/dom/svg/SVGTextPathElement.cpp
@@ -30,27 +30,27 @@ JSObject* SVGTextPathElement::WrapNode(J
 SVGElement::LengthInfo SVGTextPathElement::sLengthInfo[2] = {
     // from SVGTextContentElement:
     {nsGkAtoms::textLength, 0, SVGLength_Binding::SVG_LENGTHTYPE_NUMBER,
      SVGContentUtils::XY},
     // from SVGTextPathElement:
     {nsGkAtoms::startOffset, 0, SVGLength_Binding::SVG_LENGTHTYPE_NUMBER,
      SVGContentUtils::X}};
 
-nsSVGEnumMapping SVGTextPathElement::sMethodMap[] = {
+SVGEnumMapping SVGTextPathElement::sMethodMap[] = {
     {nsGkAtoms::align, TEXTPATH_METHODTYPE_ALIGN},
     {nsGkAtoms::stretch, TEXTPATH_METHODTYPE_STRETCH},
     {nullptr, 0}};
 
-nsSVGEnumMapping SVGTextPathElement::sSpacingMap[] = {
+SVGEnumMapping SVGTextPathElement::sSpacingMap[] = {
     {nsGkAtoms::_auto, TEXTPATH_SPACINGTYPE_AUTO},
     {nsGkAtoms::exact, TEXTPATH_SPACINGTYPE_EXACT},
     {nullptr, 0}};
 
-nsSVGEnumMapping SVGTextPathElement::sSideMap[] = {
+SVGEnumMapping SVGTextPathElement::sSideMap[] = {
     {nsGkAtoms::left, TEXTPATH_SIDETYPE_LEFT},
     {nsGkAtoms::right, TEXTPATH_SIDETYPE_RIGHT},
     {nullptr, 0}};
 
 SVGElement::EnumInfo SVGTextPathElement::sEnumInfo[4] = {
     // from SVGTextContentElement:
     {nsGkAtoms::lengthAdjust, sLengthAdjustMap, LENGTHADJUST_SPACING},
     // from SVGTextPathElement:
--- a/dom/svg/SVGTextPathElement.h
+++ b/dom/svg/SVGTextPathElement.h
@@ -2,17 +2,17 @@
 /* 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_SVGTextPathElement_h
 #define mozilla_dom_SVGTextPathElement_h
 
-#include "nsSVGEnum.h"
+#include "SVGEnum.h"
 #include "nsSVGLength2.h"
 #include "nsSVGString.h"
 #include "mozilla/dom/SVGAnimatedPathSegList.h"
 #include "mozilla/dom/SVGTextContentElement.h"
 
 class nsAtom;
 class nsIContent;
 
@@ -67,21 +67,21 @@ class SVGTextPathElement final : public 
   enum { /* TEXTLENGTH, */ STARTOFFSET = 1 };
   nsSVGLength2 mLengthAttributes[2];
   virtual nsSVGLength2* LengthAttributes() override {
     return mLengthAttributes;
   }
   static LengthInfo sLengthInfo[2];
 
   enum { /* LENGTHADJUST, */ METHOD = 1, SPACING, SIDE };
-  nsSVGEnum mEnumAttributes[4];
-  virtual nsSVGEnum* EnumAttributes() override { return mEnumAttributes; }
-  static nsSVGEnumMapping sMethodMap[];
-  static nsSVGEnumMapping sSpacingMap[];
-  static nsSVGEnumMapping sSideMap[];
+  SVGEnum mEnumAttributes[4];
+  virtual SVGEnum* EnumAttributes() override { return mEnumAttributes; }
+  static SVGEnumMapping sMethodMap[];
+  static SVGEnumMapping sSpacingMap[];
+  static SVGEnumMapping sSideMap[];
   static EnumInfo sEnumInfo[4];
 
   enum { HREF, XLINK_HREF };
   nsSVGString mStringAttributes[2];
   static StringInfo sStringInfo[2];
 
   SVGAnimatedPathSegList mPath;
 };
--- a/dom/svg/SVGViewElement.cpp
+++ b/dom/svg/SVGViewElement.cpp
@@ -14,17 +14,17 @@ namespace dom {
 
 using namespace SVGViewElement_Binding;
 
 JSObject* SVGViewElement::WrapNode(JSContext* aCx,
                                    JS::Handle<JSObject*> aGivenProto) {
   return SVGViewElement_Binding::Wrap(aCx, this, aGivenProto);
 }
 
-nsSVGEnumMapping SVGViewElement::sZoomAndPanMap[] = {
+SVGEnumMapping SVGViewElement::sZoomAndPanMap[] = {
     {nsGkAtoms::disable, SVG_ZOOMANDPAN_DISABLE},
     {nsGkAtoms::magnify, SVG_ZOOMANDPAN_MAGNIFY},
     {nullptr, 0}};
 
 SVGElement::EnumInfo SVGViewElement::sEnumInfo[1] = {
     {nsGkAtoms::zoomAndPan, sZoomAndPanMap, SVG_ZOOMANDPAN_MAGNIFY}};
 
 //----------------------------------------------------------------------
--- a/dom/svg/SVGViewElement.h
+++ b/dom/svg/SVGViewElement.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 mozilla_dom_SVGViewElement_h
 #define mozilla_dom_SVGViewElement_h
 
-#include "SVGElement.h"
-#include "nsSVGEnum.h"
+#include "SVGAnimatedPreserveAspectRatio.h"
+#include "SVGEnum.h"
+#include "SVGStringList.h"
 #include "nsSVGViewBox.h"
-#include "SVGAnimatedPreserveAspectRatio.h"
-#include "SVGStringList.h"
+#include "mozilla/dom/SVGElement.h"
 
 class nsSVGOuterSVGFrame;
 
 nsresult NS_NewSVGViewElement(
     nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
 namespace mozilla {
 class SVGFragmentIdentifier;
@@ -49,18 +49,18 @@ class SVGViewElement : public SVGViewEle
   already_AddRefed<DOMSVGAnimatedPreserveAspectRatio> PreserveAspectRatio();
 
  private:
   // SVGElement overrides
 
   virtual EnumAttributesInfo GetEnumInfo() override;
 
   enum { ZOOMANDPAN };
-  nsSVGEnum mEnumAttributes[1];
-  static nsSVGEnumMapping sZoomAndPanMap[];
+  SVGEnum mEnumAttributes[1];
+  static SVGEnumMapping sZoomAndPanMap[];
   static EnumInfo sEnumInfo[1];
 
   virtual nsSVGViewBox* GetViewBox() override;
   virtual SVGAnimatedPreserveAspectRatio* GetPreserveAspectRatio() override;
 
   nsSVGViewBox mViewBox;
   SVGAnimatedPreserveAspectRatio mPreserveAspectRatio;
 };
--- a/dom/svg/SVGViewportElement.h
+++ b/dom/svg/SVGViewportElement.h
@@ -6,23 +6,23 @@
 
 #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 "SVGEnum.h"
 #include "SVGGraphicsElement.h"
 #include "SVGImageContext.h"
+#include "nsSVGLength2.h"
+#include "nsISVGPoint.h"
 #include "SVGPreserveAspectRatio.h"
-#include "nsSVGLength2.h"
 #include "nsSVGViewBox.h"
 
 class nsSVGOuterSVGFrame;
 class nsSVGViewportFrame;
 
 namespace mozilla {
 class AutoPreserveAspectRatioOverride;
 class DOMSVGAnimatedPreserveAspectRatio;
--- a/dom/svg/moz.build
+++ b/dom/svg/moz.build
@@ -119,17 +119,16 @@ UNIFIED_SOURCES += [
     'DOMSVGPathSegList.cpp',
     'DOMSVGPoint.cpp',
     'DOMSVGPointList.cpp',
     'DOMSVGStringList.cpp',
     'DOMSVGTransform.cpp',
     'DOMSVGTransformList.cpp',
     'nsISVGPoint.cpp',
     'nsSVGBoolean.cpp',
-    'nsSVGEnum.cpp',
     'nsSVGInteger.cpp',
     'nsSVGIntegerPair.cpp',
     'nsSVGLength2.cpp',
     'nsSVGNumber2.cpp',
     'nsSVGNumberPair.cpp',
     'nsSVGString.cpp',
     'nsSVGViewBox.cpp',
     'SVGAElement.cpp',
@@ -159,16 +158,17 @@ UNIFIED_SOURCES += [
     'SVGContentUtils.cpp',
     'SVGDataParser.cpp',
     'SVGDefsElement.cpp',
     'SVGDescElement.cpp',
     'SVGDocument.cpp',
     'SVGElement.cpp',
     'SVGElementFactory.cpp',
     'SVGEllipseElement.cpp',
+    'SVGEnum.cpp',
     'SVGFEBlendElement.cpp',
     'SVGFEColorMatrixElement.cpp',
     'SVGFEComponentTransferElement.cpp',
     'SVGFECompositeElement.cpp',
     'SVGFEConvolveMatrixElement.cpp',
     'SVGFEDiffuseLightingElement.cpp',
     'SVGFEDisplacementMapElement.cpp',
     'SVGFEDistantLightElement.cpp',
--- a/gfx/ipc/GPUParent.cpp
+++ b/gfx/ipc/GPUParent.cpp
@@ -442,17 +442,23 @@ mozilla::ipc::IPCResult GPUParent::RecvN
 
 mozilla::ipc::IPCResult GPUParent::RecvRequestMemoryReport(
     const uint32_t& aGeneration, const bool& aAnonymize,
     const bool& aMinimizeMemoryUsage, const MaybeFileDesc& aDMDFile) {
   nsAutoCString processName;
   GetGPUProcessName(processName);
 
   mozilla::dom::MemoryReportRequestClient::Start(
-      aGeneration, aAnonymize, aMinimizeMemoryUsage, aDMDFile, processName);
+      aGeneration, aAnonymize, aMinimizeMemoryUsage, aDMDFile, processName,
+      [&](const MemoryReport& aReport) {
+        Unused << GetSingleton()->SendAddMemoryReport(aReport);
+      },
+      [&](const uint32_t& aGeneration) {
+        return GetSingleton()->SendFinishMemoryReport(aGeneration);
+      });
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult GPUParent::RecvShutdownVR() {
   if (gfxPrefs::VRProcessEnabled()) {
     VRGPUChild::ShutDown();
   }
   return IPC_OK();
--- a/js/src/gc/GC.cpp
+++ b/js/src/gc/GC.cpp
@@ -1203,17 +1203,18 @@ bool GCRuntime::parseAndSetZeal(const ch
   CharRangeVector modes;
   if (!SplitStringBy(parts[0], ';', &modes)) {
     return false;
   }
 
   for (const auto& descr : modes) {
     uint32_t mode;
     if (!ParseZealModeName(descr, &mode) &&
-        !ParseZealModeNumericParam(descr, &mode)) {
+        !(ParseZealModeNumericParam(descr, &mode) &&
+          mode <= unsigned(ZealMode::Limit))) {
       return PrintZealHelpAndFail();
     }
 
     setZeal(mode, frequency);
   }
 
   return true;
 }
@@ -8969,27 +8970,30 @@ JS_PUBLIC_API void js::gc::detail::Asser
 
   // TODO: I'd like to AssertHeapIsIdle() here, but this ends up getting
   // called during GC and while iterating the heap for memory reporting.
   MOZ_ASSERT(!JS::RuntimeHeapIsCycleCollecting());
 
   auto tc = &cell->asTenured();
   if (tc->zone()->isGCMarkingBlackAndGray()) {
     // We are doing gray marking in the cell's zone. Even if the cell is
-    // currently marked gray it may eventually be marked black. Delay the check
-    // until we finish gray marking.
-    JSRuntime* rt = tc->zone()->runtimeFromMainThread();
-    AutoEnterOOMUnsafeRegion oomUnsafe;
-    if (!rt->gc.cellsToAssertNotGray.ref().append(cell)) {
-      oomUnsafe.crash("Can't append to delayed gray checks list");
+    // currently marked gray it may eventually be marked black. Delay checking
+    // non-black cells until we finish gray marking.
+
+    if (!tc->isMarkedBlack()) {
+      JSRuntime* rt = tc->zone()->runtimeFromMainThread();
+      AutoEnterOOMUnsafeRegion oomUnsafe;
+      if (!rt->gc.cellsToAssertNotGray.ref().append(cell)) {
+        oomUnsafe.crash("Can't append to delayed gray checks list");
+      }
     }
     return;
   }
 
-  MOZ_ASSERT(!detail::CellIsMarkedGray(tc));
+  MOZ_ASSERT(!tc->isMarkedGray());
 }
 
 extern JS_PUBLIC_API bool js::gc::detail::ObjectIsMarkedBlack(
     const JSObject* obj) {
   return obj->isMarkedBlack();
 }
 
 #endif
--- a/js/src/gc/GCMarker.h
+++ b/js/src/gc/GCMarker.h
@@ -288,23 +288,17 @@ class GCMarker : public JSTracer {
 
   void enterWeakMarkingMode();
   void leaveWeakMarkingMode();
   void abortLinearWeakMarking() {
     leaveWeakMarkingMode();
     linearWeakMarkingDisabled_ = true;
   }
 
-  void delayMarkingArena(gc::Arena* arena);
   void delayMarkingChildren(gc::Cell* cell);
-  void markDelayedChildren(gc::Arena* arena, gc::MarkColor color);
-  MOZ_MUST_USE bool markAllDelayedChildren(SliceBudget& budget);
-  bool processDelayedMarkingList(gc::MarkColor color, bool shouldYield,
-                                 SliceBudget& budget);
-  bool hasDelayedChildren() const { return !!delayedMarkingList; }
 
   bool isDrained() { return isMarkStackEmpty() && !delayedMarkingList; }
 
   MOZ_MUST_USE bool markUntilBudgetExhausted(SliceBudget& budget);
 
   void setGCMode(JSGCMode mode) { stack.setGCMode(mode); }
 
   size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
@@ -379,16 +373,21 @@ class GCMarker : public JSTracer {
       const gc::MarkStack::SavedValueArray& savedArray);
 
   void saveValueRanges();
   gc::MarkStack::SavedValueArray saveValueRange(
       const gc::MarkStack::ValueArray& array);
 
   inline void processMarkStackTop(SliceBudget& budget);
 
+  void markDelayedChildren(gc::Arena* arena, gc::MarkColor color);
+  MOZ_MUST_USE bool markAllDelayedChildren(SliceBudget& budget);
+  bool processDelayedMarkingList(gc::MarkColor color, SliceBudget& budget);
+  bool hasDelayedChildren() const { return !!delayedMarkingList; }
+  void rebuildDelayedMarkingList();
   void appendToDelayedMarkingList(gc::Arena** listTail, gc::Arena* arena);
 
   template <typename F>
   void forEachDelayedMarkingArena(F&& f);
 
   /* The mark stack. Pointers in this stack are "gray" in the GC sense. */
   gc::MarkStack stack;
 
--- a/js/src/gc/Heap-inl.h
+++ b/js/src/gc/Heap-inl.h
@@ -13,25 +13,27 @@
 #include "gc/Zone.h"
 
 inline void js::gc::Arena::init(JS::Zone* zoneArg, AllocKind kind,
                                 const AutoLockGC& lock) {
   MOZ_ASSERT(firstFreeSpan.isEmpty());
   MOZ_ASSERT(!zone);
   MOZ_ASSERT(!allocated());
   MOZ_ASSERT(!onDelayedMarkingList_);
-  MOZ_ASSERT(!hasDelayedMarking_);
+  MOZ_ASSERT(!hasDelayedBlackMarking_);
+  MOZ_ASSERT(!hasDelayedGrayMarking_);
   MOZ_ASSERT(!nextDelayedMarkingArena_);
 
   MOZ_MAKE_MEM_UNDEFINED(this, ArenaSize);
 
   zone = zoneArg;
   allocKind = size_t(kind);
   onDelayedMarkingList_ = 0;
-  hasDelayedMarking_ = 0;
+  hasDelayedBlackMarking_ = 0;
+  hasDelayedGrayMarking_ = 0;
   nextDelayedMarkingArena_ = 0;
   if (zone->isAtomsZone()) {
     zone->runtimeFromAnyThread()->gc.atomMarking.registerArena(this, lock);
   } else {
     bufferedCells() = &ArenaCellSet::Empty;
   }
 
   setAsFullyUnused();
--- a/js/src/gc/Heap.h
+++ b/js/src/gc/Heap.h
@@ -231,21 +231,25 @@ class Arena {
   size_t allocKind : 8;
 
  private:
   /*
    * When recursive marking uses too much stack we delay marking of
    * arenas and link them into a list for later processing. This
    * uses the following fields.
    */
+  static const size_t DELAYED_MARKING_FLAG_BITS = 3;
+  static const size_t DELAYED_MARKING_ARENA_BITS =
+    JS_BITS_PER_WORD - 8 - DELAYED_MARKING_FLAG_BITS;
   size_t onDelayedMarkingList_ : 1;
-  size_t hasDelayedMarking_ : 1;
-  size_t nextDelayedMarkingArena_ : JS_BITS_PER_WORD - 8 - 1 - 1;
+  size_t hasDelayedBlackMarking_ : 1;
+  size_t hasDelayedGrayMarking_ : 1;
+  size_t nextDelayedMarkingArena_ : DELAYED_MARKING_ARENA_BITS;
   static_assert(
-      ArenaShift >= 8 + 1 + 1,
+      DELAYED_MARKING_ARENA_BITS >= JS_BITS_PER_WORD - ArenaShift,
       "Arena::nextDelayedMarkingArena_ packing assumes that ArenaShift has "
       "enough bits to cover allocKind and delayed marking state.");
 
   union {
     /*
      * For arenas in zones other than the atoms zone, if non-null, points
      * to an ArenaCellSet that represents the set of cells in this arena
      * that are in the nursery's store buffer.
@@ -284,17 +288,18 @@ class Arena {
 
   // Initialize an arena to its unallocated state. For arenas that were
   // previously allocated for some zone, use release() instead.
   void setAsNotAllocated() {
     firstFreeSpan.initAsEmpty();
     zone = nullptr;
     allocKind = size_t(AllocKind::LIMIT);
     onDelayedMarkingList_ = 0;
-    hasDelayedMarking_ = 0;
+    hasDelayedBlackMarking_ = 0;
+    hasDelayedGrayMarking_ = 0;
     nextDelayedMarkingArena_ = 0;
     bufferedCells_ = nullptr;
   }
 
   // Return an allocated arena to its unallocated state.
   inline void release(const AutoLockGC& lock);
 
   uintptr_t address() const {
@@ -394,45 +399,56 @@ class Arena {
   Arena* getNextDelayedMarking() const {
     MOZ_ASSERT(onDelayedMarkingList_);
     return reinterpret_cast<Arena*>(nextDelayedMarkingArena_ << ArenaShift);
   }
 
   void setNextDelayedMarkingArena(Arena* arena) {
     MOZ_ASSERT(!(uintptr_t(arena) & ArenaMask));
     MOZ_ASSERT(!onDelayedMarkingList_);
-    MOZ_ASSERT(!hasDelayedMarking_);
+    MOZ_ASSERT(!hasDelayedBlackMarking_);
+    MOZ_ASSERT(!hasDelayedGrayMarking_);
     MOZ_ASSERT(!nextDelayedMarkingArena_);
     onDelayedMarkingList_ = 1;
-    hasDelayedMarking_ = 1;
     if (arena) {
       nextDelayedMarkingArena_ = arena->address() >> ArenaShift;
     }
   }
 
   void updateNextDelayedMarkingArena(Arena* arena) {
     MOZ_ASSERT(!(uintptr_t(arena) & ArenaMask));
     MOZ_ASSERT(onDelayedMarkingList_);
     nextDelayedMarkingArena_ = arena ? arena->address() >> ArenaShift : 0;
   }
 
-  bool hasDelayedMarking() const {
+  bool hasDelayedMarking(MarkColor color) const {
     MOZ_ASSERT(onDelayedMarkingList_);
-    return hasDelayedMarking_;
+    return color == MarkColor::Black ? hasDelayedBlackMarking_
+                                     : hasDelayedGrayMarking_;
   }
 
-  void setHasDelayedMarking(bool value) {
+  bool hasAnyDelayedMarking() const {
     MOZ_ASSERT(onDelayedMarkingList_);
-    hasDelayedMarking_ = value;
+    return hasDelayedBlackMarking_ || hasDelayedGrayMarking_;
+  }
+
+  void setHasDelayedMarking(MarkColor color, bool value) {
+    MOZ_ASSERT(onDelayedMarkingList_);
+    if (color == MarkColor::Black) {
+      hasDelayedBlackMarking_ = value;
+    } else {
+      hasDelayedGrayMarking_ = value;
+    }
   }
 
   void clearDelayedMarkingState() {
     MOZ_ASSERT(onDelayedMarkingList_);
     onDelayedMarkingList_ = 0;
-    hasDelayedMarking_ = 0;
+    hasDelayedBlackMarking_ = 0;
+    hasDelayedGrayMarking_ = 0;
     nextDelayedMarkingArena_ = 0;
   }
 
   inline ArenaCellSet*& bufferedCells();
   inline size_t& atomBitmapStart();
 
   template <typename T>
   size_t finalize(FreeOp* fop, AllocKind thingKind, size_t thingSize);
--- a/js/src/gc/Marking.cpp
+++ b/js/src/gc/Marking.cpp
@@ -945,29 +945,33 @@ struct TypeParticipatesInCC {};
 #define EXPAND_PARTICIPATES_IN_CC(_, type, addToCCKind) \
   template <>                                           \
   struct TypeParticipatesInCC<type> {                   \
     static const bool value = addToCCKind;              \
   };
 JS_FOR_EACH_TRACEKIND(EXPAND_PARTICIPATES_IN_CC)
 #undef EXPAND_PARTICIPATES_IN_CC
 
+}  // namespace
+
+#ifdef DEBUG
+
 struct ParticipatesInCCFunctor {
   template <typename T>
   bool operator()() {
     return TypeParticipatesInCC<T>::value;
   }
 };
 
-}  // namespace
-
 static bool TraceKindParticipatesInCC(JS::TraceKind kind) {
   return DispatchTraceKindTyped(ParticipatesInCCFunctor(), kind);
 }
 
+#endif // DEBUG
+
 template <typename T>
 bool js::GCMarker::mark(T* thing) {
   if (IsInsideNursery(thing)) {
     return false;
   }
   AssertShouldMarkInZone(thing);
   TenuredCell* cell = TenuredCell::fromPointer(thing);
 
@@ -2538,82 +2542,69 @@ void GCMarker::leaveWeakMarkingMode() {
   for (GCZonesIter zone(runtime()); !zone.done(); zone.next()) {
     if (!zone->gcWeakKeys().clear()) {
       oomUnsafe.crash("clearing weak keys in GCMarker::leaveWeakMarkingMode()");
     }
   }
 }
 
 void GCMarker::delayMarkingChildren(Cell* cell) {
-  delayMarkingArena(cell->asTenured().arena());
-}
-
-void GCMarker::delayMarkingArena(Arena* arena) {
-  if (arena->onDelayedMarkingList()) {
-    // The arena is already on the delayed marking list, so just set a flag to
-    // ensure it gets processed again.
-    if (!arena->hasDelayedMarking()) {
-      arena->setHasDelayedMarking(true);
-      delayedMarkingWorkAdded = true;
-    }
-    return;
+  Arena* arena = cell->asTenured().arena();
+  if (!arena->onDelayedMarkingList()) {
+    arena->setNextDelayedMarkingArena(delayedMarkingList);
+    delayedMarkingList = arena;
+#ifdef DEBUG
+    markLaterArenas++;
+#endif
   }
-  arena->setNextDelayedMarkingArena(delayedMarkingList);
-  delayedMarkingList = arena;
-  delayedMarkingWorkAdded = true;
-#ifdef DEBUG
-  markLaterArenas++;
-#endif
+  if (!arena->hasDelayedMarking(color)) {
+    arena->setHasDelayedMarking(color, true);
+    delayedMarkingWorkAdded = true;
+  }
 }
 
 void GCMarker::markDelayedChildren(Arena* arena, MarkColor color) {
   JS::TraceKind kind = MapAllocToTraceKind(arena->getAllocKind());
   MOZ_ASSERT_IF(color == MarkColor::Gray, TraceKindParticipatesInCC(kind));
 
+  AutoSetMarkColor setColor(*this, color);
   for (ArenaCellIterUnderGC i(arena); !i.done(); i.next()) {
     TenuredCell* t = i.getCell();
     if ((color == MarkColor::Gray && t->isMarkedGray()) ||
         (color == MarkColor::Black && t->isMarkedBlack())) {
       js::TraceChildren(this, t, kind);
     }
   }
 }
 
-static inline bool ArenaCanHaveGrayThings(Arena* arena) {
-  JS::TraceKind kind = MapAllocToTraceKind(arena->getAllocKind());
-  return TraceKindParticipatesInCC(kind);
-}
-
 /*
  * Process arenas from |delayedMarkingList| by marking the unmarked children of
- * marked cells of color |color|. If |shouldYield|, return early if the |budget|
- * is exceeded.
+ * marked cells of color |color|. Return early if the |budget| is exceeded.
  *
  * This is called twice, first to mark gray children and then to mark black
  * children.
  */
-bool GCMarker::processDelayedMarkingList(MarkColor color, bool shouldYield,
-                                         SliceBudget& budget) {
+bool GCMarker::processDelayedMarkingList(MarkColor color, SliceBudget& budget) {
   // Marking delayed children may add more arenas to the list, including arenas
-  // we are currently or have previously processed. Handle this by setting a
-  // flag on arenas we think we've processed which is cleared if they are
-  // re-added. Iterate the list until the flag is set on all arenas.
+  // we are currently processing or have previously processed. Handle this by
+  // clearing a flag on each arena before marking its children. This flag will
+  // be set again if the arena is re-added. Iterate the list until no new arenas
+  // were added.
 
   do {
     delayedMarkingWorkAdded = false;
     for (Arena* arena = delayedMarkingList; arena;
          arena = arena->getNextDelayedMarking()) {
-      if (!arena->hasDelayedMarking() ||
-          (color == MarkColor::Gray && !ArenaCanHaveGrayThings(arena))) {
+      if (!arena->hasDelayedMarking(color)) {
         continue;
       }
-      arena->setHasDelayedMarking(false);
+      arena->setHasDelayedMarking(color, false);
       markDelayedChildren(arena, color);
       budget.step(150);
-      if (shouldYield && budget.isOverBudget()) {
+      if (budget.isOverBudget()) {
         return false;
       }
     }
   } while (delayedMarkingWorkAdded);
 
   return true;
 }
 
@@ -2626,64 +2617,53 @@ bool GCMarker::markAllDelayedChildren(Sl
                         gcstats::PhaseKind::MARK_DELAYED);
 
   // We have a list of arenas containing marked cells with unmarked children
   // where we ran out of stack space during marking.
   //
   // Both black and gray cells in these arenas may have unmarked children, and
   // we must mark gray children first as gray entries always sit before black
   // entries on the mark stack. Therefore the list is processed in two stages.
-  //
-  // In order to guarantee progress here, the fist pass (gray marking) is done
-  // non-incrementally. We can't remove anything from the list until the second
-  // pass so if we yield during the first pass we will have to restart and
-  // process all the arenas over again. If there are enough arenas we may never
-  // finish during our timeslice. Disallowing yield during the first pass
-  // ensures that the list will at least shrink by one arena every time.
 
   MOZ_ASSERT(delayedMarkingList);
 
   bool finished;
-  finished = processDelayedMarkingList(MarkColor::Gray, false, /* don't yield */
-                                       budget);
-  MOZ_ASSERT(finished);
-
-  forEachDelayedMarkingArena([&](Arena* arena) {
-    MOZ_ASSERT(!arena->hasDelayedMarking());
-    arena->setHasDelayedMarking(true);
-  });
-
-  finished = processDelayedMarkingList(MarkColor::Black,
-                                       true, /* yield if over budget */
-                                       budget);
-
-  // Rebuild the list, removing processed arenas.
+  finished = processDelayedMarkingList(MarkColor::Gray, budget);
+  rebuildDelayedMarkingList();
+  if (!finished) {
+    return false;
+  }
+
+  finished = processDelayedMarkingList(MarkColor::Black, budget);
+  rebuildDelayedMarkingList();
+
+  MOZ_ASSERT_IF(finished, !delayedMarkingList);
+  MOZ_ASSERT_IF(finished, !markLaterArenas);
+
+  return finished;
+}
+
+void GCMarker::rebuildDelayedMarkingList() {
+  // Rebuild the delayed marking list, removing arenas which do not need further
+  // marking.
+
   Arena* listTail = nullptr;
   forEachDelayedMarkingArena([&](Arena* arena) {
-    if (!arena->hasDelayedMarking()) {
+    if (!arena->hasAnyDelayedMarking()) {
       arena->clearDelayedMarkingState();
 #ifdef DEBUG
       MOZ_ASSERT(markLaterArenas);
       markLaterArenas--;
 #endif
       return;
     }
 
     appendToDelayedMarkingList(&listTail, arena);
   });
   appendToDelayedMarkingList(&listTail, nullptr);
-
-  if (!finished) {
-    return false;
-  }
-
-  MOZ_ASSERT(!delayedMarkingList);
-  MOZ_ASSERT(!markLaterArenas);
-
-  return true;
 }
 
 inline void GCMarker::appendToDelayedMarkingList(Arena** listTail,
                                                  Arena* arena) {
   if (*listTail) {
     (*listTail)->updateNextDelayedMarkingArena(arena);
   } else {
     delayedMarkingList = arena;
--- a/js/src/gc/Statistics.cpp
+++ b/js/src/gc/Statistics.cpp
@@ -175,18 +175,20 @@ Phase Statistics::lookupChildPhase(Phase
   Phase phase;
   for (phase = phaseKinds[phaseKind].firstPhase; phase != Phase::NONE;
        phase = phases[phase].nextWithPhaseKind) {
     if (phases[phase].parent == currentPhase()) {
       break;
     }
   }
 
-  MOZ_RELEASE_ASSERT(phase != Phase::NONE,
-                     "Requested child phase not found under current phase");
+  if (phase == Phase::NONE) {
+      MOZ_CRASH_UNSAFE_PRINTF("Child phase kind %u not found under current phase kind %u",
+                              unsigned(phaseKind), unsigned(currentPhaseKind()));
+  }
 
   return phase;
 }
 
 inline decltype(mozilla::MakeEnumeratedRange(Phase::FIRST, Phase::LIMIT))
 AllPhases() {
   return mozilla::MakeEnumeratedRange(Phase::FIRST, Phase::LIMIT);
 }
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -11643,17 +11643,17 @@ class OutOfLineSwitch : public OutOfLine
     Register base;
     if (tableType == SwitchTableType::Inline) {
 #if defined(JS_CODEGEN_ARM)
       base = ::js::jit::pc;
 #else
       MOZ_CRASH("NYI: SwitchTableType::Inline");
 #endif
     } else {
-#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64)
+#if defined(JS_CODEGEN_ARM)
       MOZ_CRASH("NYI: SwitchTableType::OutOfLine");
 #else
       masm.mov(start(), temp);
       base = temp;
 #endif
     }
     BaseIndex jumpTarget(base, index, ScalePointer);
     masm.branchToComputedAddress(jumpTarget);
@@ -11678,17 +11678,17 @@ class OutOfLineSwitch : public OutOfLine
   void setOutOfLine() { isOutOfLine_ = true; }
 };
 
 template <SwitchTableType tableType>
 void CodeGenerator::visitOutOfLineSwitch(
     OutOfLineSwitch<tableType>* jumpTable) {
   jumpTable->setOutOfLine();
   if (tableType == SwitchTableType::OutOfLine) {
-#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64)
+#if defined(JS_CODEGEN_ARM)
     MOZ_CRASH("NYI: SwitchTableType::OutOfLine");
 #elif defined(JS_CODEGEN_NONE)
     MOZ_CRASH();
 #else
     masm.haltingAlign(sizeof(void*));
     masm.bind(jumpTable->start());
     masm.addCodeLabel(*jumpTable->start());
 #endif
@@ -11724,26 +11724,26 @@ void CodeGenerator::visitLoadElementFrom
   FloatRegister tempD = ToFloatRegister(lir->tempD());
   ValueOperand out = ToOutValue(lir);
 
   // For each element, load it and box it.
   MArgumentState* array = lir->array()->toArgumentState();
   Label join;
 
   // Jump to the code which is loading the element, based on its index.
-#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64)
+#if defined(JS_CODEGEN_ARM)
   auto* jumpTable =
       new (alloc()) OutOfLineSwitch<SwitchTableType::Inline>(alloc());
 #else
   auto* jumpTable =
       new (alloc()) OutOfLineSwitch<SwitchTableType::OutOfLine>(alloc());
 #endif
 
   {
-#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64)
+#if defined(JS_CODEGEN_ARM)
     // Inhibit pools within the following sequence because we are indexing into
     // a pc relative table. The region will have one instruction for ma_ldr, one
     // for breakpoint, and each table case takes one word.
     AutoForbidPools afp(&masm, 1 + 1 + array->numElements());
 #endif
     jumpTable->jumpToCodeEntries(masm, index, temp0);
 
     // Add table entries if the table is inlined.
--- a/js/src/jit/arm/MacroAssembler-arm.cpp
+++ b/js/src/jit/arm/MacroAssembler-arm.cpp
@@ -1625,17 +1625,16 @@ BufferOffset MacroAssemblerARM::ma_vstr(
                                         Register index,
                                         AutoRegisterScope& scratch,
                                         int32_t shift, Condition cc) {
   as_add(scratch, base, lsl(index, shift), LeaveCC, cc);
   return as_vdtr(IsStore, src, Operand(Address(scratch, 0)).toVFPAddr(), cc);
 }
 
 bool MacroAssemblerARMCompat::buildOOLFakeExitFrame(void* fakeReturnAddr) {
-  DebugOnly<uint32_t> initialDepth = asMasm().framePushed();
   uint32_t descriptor = MakeFrameDescriptor(
       asMasm().framePushed(), FrameType::IonJS, ExitFrameLayout::Size());
 
   asMasm().Push(Imm32(descriptor));  // descriptor_
   asMasm().Push(ImmPtr(fakeReturnAddr));
 
   return true;
 }
--- a/js/src/jit/arm64/MacroAssembler-arm64.cpp
+++ b/js/src/jit/arm64/MacroAssembler-arm64.cpp
@@ -448,17 +448,48 @@ void MacroAssembler::PushRegsInMask(Live
       adjustFrame(8);
     }
     vixl::MacroAssembler::Push(src[0], src[1], src[2], src[3]);
   }
 }
 
 void MacroAssembler::storeRegsInMask(LiveRegisterSet set, Address dest,
                                      Register scratch) {
-  MOZ_CRASH("NYI: storeRegsInMask");
+  FloatRegisterSet fpuSet(set.fpus().reduceSetForPush());
+  unsigned numFpu = fpuSet.size();
+  int32_t diffF = fpuSet.getPushSizeInBytes();
+  int32_t diffG = set.gprs().size() * sizeof(intptr_t);
+
+  MOZ_ASSERT(dest.offset >= diffG + diffF);
+
+  for (GeneralRegisterBackwardIterator iter(set.gprs()); iter.more(); ++iter) {
+    diffG -= sizeof(intptr_t);
+    dest.offset -= sizeof(intptr_t);
+    storePtr(*iter, dest);
+  }
+  MOZ_ASSERT(diffG == 0);
+
+  for (FloatRegisterBackwardIterator iter(fpuSet); iter.more(); ++iter) {
+    FloatRegister reg = *iter;
+    diffF -= reg.size();
+    numFpu -= 1;
+    dest.offset -= reg.size();
+    if (reg.isDouble()) {
+      storeDouble(reg, dest);
+    } else if (reg.isSingle()) {
+      storeFloat32(reg, dest);
+    } else {
+      MOZ_CRASH("Unknown register type.");
+    }
+
+  }
+  MOZ_ASSERT(numFpu == 0);
+  // Padding to keep the stack aligned, taken from the x64 and mips64 implementations.
+  diffF -= diffF % sizeof(uintptr_t);
+  MOZ_ASSERT(diffF == 0);
 }
 
 void MacroAssembler::PopRegsInMaskIgnore(LiveRegisterSet set,
                                          LiveRegisterSet ignore) {
   // The offset of the data from the stack pointer.
   uint32_t offset = 0;
 
   for (FloatRegisterIterator iter(set.fpus().reduceSetForPush());
@@ -818,16 +849,24 @@ uint32_t MacroAssembler::pushFakeReturnA
   Push(scratch);
   bind(&fakeCallsite);
   uint32_t pseudoReturnOffset = currentOffset();
 
   leaveNoPool();
   return pseudoReturnOffset;
 }
 
+bool MacroAssemblerCompat::buildOOLFakeExitFrame(void* fakeReturnAddr) {
+  uint32_t descriptor = MakeFrameDescriptor(
+      asMasm().framePushed(), FrameType::IonJS, ExitFrameLayout::Size());
+  asMasm().Push(Imm32(descriptor));
+  asMasm().Push(ImmPtr(fakeReturnAddr));
+  return true;
+}
+
 // ===============================================================
 // Move instructions
 
 void MacroAssembler::moveValue(const TypedOrValueRegister& src,
                                const ValueOperand& dest) {
   if (src.hasValue()) {
     moveValue(src.valueReg(), dest);
     return;
--- a/js/src/jit/arm64/MacroAssembler-arm64.h
+++ b/js/src/jit/arm64/MacroAssembler-arm64.h
@@ -2013,23 +2013,17 @@ class MacroAssemblerCompat : public vixl
       And(ARMRegister(dest, 64), ARMRegister(dest, 64),
           Operand(JSVAL_TAG_MASK));
     } else {
       Bfxil(ARMRegister(dest, 64), ARMRegister(src, 64), 0, JSVAL_TAG_SHIFT);
     }
   }
 
  protected:
-  bool buildOOLFakeExitFrame(void* fakeReturnAddr) {
-    uint32_t descriptor = MakeFrameDescriptor(framePushed(), FrameType::IonJS,
-                                              ExitFrameLayout::Size());
-    Push(Imm32(descriptor));
-    Push(ImmPtr(fakeReturnAddr));
-    return true;
-  }
+  bool buildOOLFakeExitFrame(void* fakeReturnAddr);
 };
 
 // See documentation for ScratchTagScope and ScratchTagScopeRelease in
 // MacroAssembler-x64.h.
 
 class ScratchTagScope {
   vixl::UseScratchRegisterScope temps_;
   ARMRegister scratch64_;
--- a/layout/svg/nsSVGClipPathFrame.cpp
+++ b/layout/svg/nsSVGClipPathFrame.cpp
@@ -422,17 +422,17 @@ void nsSVGClipPathFrame::Init(nsIContent
 
 gfxMatrix nsSVGClipPathFrame::GetCanvasTM() { return mMatrixForChildren; }
 
 gfxMatrix nsSVGClipPathFrame::GetClipPathTransform(nsIFrame* aClippedFrame) {
   SVGClipPathElement* content = static_cast<SVGClipPathElement*>(GetContent());
 
   gfxMatrix tm = content->PrependLocalTransformsTo(gfxMatrix());
 
-  nsSVGEnum* clipPathUnits =
+  SVGEnum* clipPathUnits =
       &content->mEnumAttributes[SVGClipPathElement::CLIPPATHUNITS];
 
   uint32_t flags = nsSVGUtils::eBBoxIncludeFillGeometry |
                    (aClippedFrame->StyleBorder()->mBoxDecorationBreak ==
                             StyleBoxDecorationBreak::Clone
                         ? nsSVGUtils::eIncludeOnlyCurrentFrameForNonSVGElement
                         : 0);
 
--- a/layout/svg/nsSVGFilterFrame.cpp
+++ b/layout/svg/nsSVGFilterFrame.cpp
@@ -25,17 +25,17 @@ using namespace mozilla::dom;
 nsIFrame* NS_NewSVGFilterFrame(nsIPresShell* aPresShell,
                                ComputedStyle* aStyle) {
   return new (aPresShell) nsSVGFilterFrame(aStyle);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsSVGFilterFrame)
 
 uint16_t nsSVGFilterFrame::GetEnumValue(uint32_t aIndex, nsIContent* aDefault) {
-  nsSVGEnum& thisEnum =
+  SVGEnum& thisEnum =
       static_cast<SVGFilterElement*>(GetContent())->mEnumAttributes[aIndex];
 
   if (thisEnum.IsExplicitlySet()) {
     return thisEnum.GetAnimValue();
   }
 
   // Before we recurse, make sure we'll break reference loops and over long
   // reference chains:
--- a/layout/svg/nsSVGGradientFrame.cpp
+++ b/layout/svg/nsSVGGradientFrame.cpp
@@ -60,19 +60,18 @@ nsresult nsSVGGradientFrame::AttributeCh
   return nsSVGPaintServerFrame::AttributeChanged(aNameSpaceID, aAttribute,
                                                  aModType);
 }
 
 //----------------------------------------------------------------------
 
 uint16_t nsSVGGradientFrame::GetEnumValue(uint32_t aIndex,
                                           nsIContent* aDefault) {
-  const nsSVGEnum& thisEnum =
-      static_cast<dom::SVGGradientElement*>(GetContent())
-          ->mEnumAttributes[aIndex];
+  const SVGEnum& thisEnum = static_cast<dom::SVGGradientElement*>(GetContent())
+                                ->mEnumAttributes[aIndex];
 
   if (thisEnum.IsExplicitlySet()) {
     return thisEnum.GetAnimValue();
   }
 
   // Before we recurse, make sure we'll break reference loops and over long
   // reference chains:
   static int16_t sRefChainLengthCounter = AutoReferenceChainGuard::noChain;
--- a/layout/svg/nsSVGMaskFrame.cpp
+++ b/layout/svg/nsSVGMaskFrame.cpp
@@ -199,17 +199,17 @@ void nsSVGMaskFrame::Init(nsIContent* aC
 }
 #endif /* DEBUG */
 
 gfxMatrix nsSVGMaskFrame::GetCanvasTM() { return mMatrixForChildren; }
 
 gfxMatrix nsSVGMaskFrame::GetMaskTransform(nsIFrame* aMaskedFrame) {
   SVGMaskElement* content = static_cast<SVGMaskElement*>(GetContent());
 
-  nsSVGEnum* maskContentUnits =
+  SVGEnum* maskContentUnits =
       &content->mEnumAttributes[SVGMaskElement::MASKCONTENTUNITS];
 
   uint32_t flags = nsSVGUtils::eBBoxIncludeFillGeometry |
                    (aMaskedFrame->StyleBorder()->mBoxDecorationBreak ==
                             StyleBoxDecorationBreak::Clone
                         ? nsSVGUtils::eIncludeOnlyCurrentFrameForNonSVGElement
                         : 0);
 
--- a/layout/svg/nsSVGPatternFrame.cpp
+++ b/layout/svg/nsSVGPatternFrame.cpp
@@ -405,17 +405,17 @@ nsSVGPatternFrame *nsSVGPatternFrame::Ge
     return nullptr;
   }
 
   return next->GetPatternWithChildren();
 }
 
 uint16_t nsSVGPatternFrame::GetEnumValue(uint32_t aIndex,
                                          nsIContent *aDefault) {
-  nsSVGEnum &thisEnum =
+  SVGEnum &thisEnum =
       static_cast<SVGPatternElement *>(GetContent())->mEnumAttributes[aIndex];
 
   if (thisEnum.IsExplicitlySet()) {
     return thisEnum.GetAnimValue();
   }
 
   // Before we recurse, make sure we'll break reference loops and over long
   // reference chains:
--- a/layout/svg/nsSVGUtils.cpp
+++ b/layout/svg/nsSVGUtils.cpp
@@ -1199,17 +1199,17 @@ bool nsSVGUtils::CanOptimizeOpacity(nsIF
 
   if (!style->HasFill() || !HasStroke(aFrame)) {
     return true;
   }
   return false;
 }
 
 gfxMatrix nsSVGUtils::AdjustMatrixForUnits(const gfxMatrix& aMatrix,
-                                           nsSVGEnum* aUnits, nsIFrame* aFrame,
+                                           SVGEnum* aUnits, nsIFrame* aFrame,
                                            uint32_t aFlags) {
   if (aFrame && aUnits->GetAnimValue() == SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
     gfxRect bbox = GetBBox(aFrame, aFlags);
     gfxMatrix tm = aMatrix;
     tm.PreTranslate(gfxPoint(bbox.X(), bbox.Y()));
     tm.PreScale(bbox.Width(), bbox.Height());
     return tm;
   }
--- a/layout/svg/nsSVGUtils.h
+++ b/layout/svg/nsSVGUtils.h
@@ -31,27 +31,27 @@
 class gfxContext;
 class nsFrameList;
 class nsIContent;
 class nsIDocument;
 class nsIFrame;
 class nsPresContext;
 class nsStyleSVGPaint;
 class nsSVGDisplayContainerFrame;
-class nsSVGEnum;
 class nsSVGLength2;
 class nsSVGOuterSVGFrame;
 class nsTextFrame;
 
 struct nsStyleSVG;
 struct nsRect;
 
 namespace mozilla {
 class SVGContextPaint;
 struct SVGContextPaintImpl;
+class SVGEnum;
 class SVGGeometryFrame;
 namespace dom {
 class Element;
 class SVGElement;
 class UserSpaceMetrics;
 }  // namespace dom
 namespace gfx {
 class DrawTarget;
@@ -339,18 +339,18 @@ class nsSVGUtils {
    * (I.e. so that [0,0] is at the top left of its bbox, and [1,1] is at the
    * bottom right of its bbox).
    *
    * If the bbox is empty, this will return a singular matrix.
    *
    * @param aFlags One or more of the BBoxFlags values defined below.
    */
   static gfxMatrix AdjustMatrixForUnits(const gfxMatrix& aMatrix,
-                                        nsSVGEnum* aUnits, nsIFrame* aFrame,
-                                        uint32_t aFlags);
+                                        mozilla::SVGEnum* aUnits,
+                                        nsIFrame* aFrame, uint32_t aFlags);
 
   enum BBoxFlags {
     eBBoxIncludeFill = 1 << 0,
     // Include the geometry of the fill even when the fill does not
     // actually render (e.g. when fill="none" or fill-opacity="0")
     eBBoxIncludeFillGeometry = 1 << 1,
     eBBoxIncludeStroke = 1 << 2,
     // Include the geometry of the stroke even when the stroke does not
--- a/mfbt/RefPtr.h
+++ b/mfbt/RefPtr.h
@@ -196,18 +196,17 @@ class MOZ_IS_REFPTR RefPtr {
 
   RefPtr<T>& operator=(const nsQueryReferent& aQueryReferent);
   RefPtr<T>& operator=(const nsCOMPtr_helper& aHelper);
 #if defined(XP_WIN)
   RefPtr<T>& operator=(const mozilla::mscom::AgileReference& aAgileRef);
 #endif  // defined(XP_WIN)
 
   RefPtr<T>& operator=(RefPtr<T>&& aRefPtr) {
-    assign_assuming_AddRef(aRefPtr.mRawPtr);
-    aRefPtr.mRawPtr = nullptr;
+    assign_assuming_AddRef(aRefPtr.forget().take());
     return *this;
   }
 
   // Defined in OwningNonNull.h
   template <class U>
   RefPtr<T>& operator=(const mozilla::OwningNonNull<U>& aOther);
 
   // Defined in StaticPtr.h