Merge inbound to mozilla-central. a=merge
authorNarcis Beleuzu <nbeleuzu@mozilla.com>
Tue, 06 Feb 2018 11:54:42 +0200
changeset 402508 f1a4b64f19b0e93c49492735db30a5023e624ae7
parent 402433 25ceb97b57731fb14c0de1bfea1446466501e56f (current diff)
parent 402507 151fa667962275b294c5859177189893b9707ca6 (diff)
child 402509 b4f43f69ed0aa287e5f881e166f8f4689f20184d
child 402526 969b4102cfbf02081903e7957fe738d9110e557b
child 402582 021162c1d64e404463b75f7aae0499a15446fd22
push id33390
push usernbeleuzu@mozilla.com
push dateTue, 06 Feb 2018 09:55:26 +0000
treeherdermozilla-central@f1a4b64f19b0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone60.0a1
first release with
nightly linux32
f1a4b64f19b0 / 60.0a1 / 20180206100151 / files
nightly linux64
f1a4b64f19b0 / 60.0a1 / 20180206100151 / files
nightly mac
f1a4b64f19b0 / 60.0a1 / 20180206100151 / files
nightly win32
f1a4b64f19b0 / 60.0a1 / 20180206100151 / files
nightly win64
f1a4b64f19b0 / 60.0a1 / 20180206100151 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to mozilla-central. a=merge
dom/xslt/nsIXSLTProcessor.idl
dom/xslt/nsIXSLTProcessorPrivate.idl
gfx/2d/CaptureCommandList.h
js/xpconnect/idl/xpcexception.idl
python/mozbuild/mozbuild/configure/libstdcxx.py
testing/web-platform/meta/MANIFEST.json
testing/web-platform/meta/css/css-flexbox/anonymous-flex-item-004.html.ini
testing/web-platform/meta/css/css-flexbox/anonymous-flex-item-005.html.ini
testing/web-platform/meta/css/css-flexbox/anonymous-flex-item-006.html.ini
testing/web-platform/meta/css/css-typed-om/stylevalue-subclasses/cssPositionValue.tentative.html.ini
testing/web-platform/meta/css/css-typed-om/stylevalue-subclasses/cssUnparsedValue.tentative.html.ini
testing/web-platform/meta/css/css-typed-om/stylevalue-subclasses/cssUrlImageValue.tentative.html.ini
testing/web-platform/meta/css/css-typed-om/stylevalue-subclasses/cssVariableReferenceValue.tentative.html.ini
testing/web-platform/meta/css/css-typed-om/the-stylepropertymap/declared/test.tentative.html.ini
testing/web-platform/meta/service-workers/service-worker/request-end-to-end.https.html.ini
testing/web-platform/meta/webvr/idlharness.html.ini
testing/web-platform/tests/css/css-typed-om/stylevalue-subclasses/cssPositionValue.tentative.html
testing/web-platform/tests/css/css-typed-om/stylevalue-subclasses/cssUnparsedValue.tentative.html
testing/web-platform/tests/css/css-typed-om/stylevalue-subclasses/cssUrlImageValue.tentative.html
testing/web-platform/tests/css/css-typed-om/stylevalue-subclasses/cssVariableReferenceValue.tentative.html
testing/web-platform/tests/css/css-typed-om/the-stylepropertymap/declared/test.tentative.html
testing/web-platform/tests/webvr/idlharness.html
--- a/browser/base/content/browser-sets.inc
+++ b/browser/base/content/browser-sets.inc
@@ -382,17 +382,17 @@
 #expand    <key id="key_selectTab6" oncommand="gBrowser.selectTabAtIndex(5, event);" key="6" modifiers="__NUM_SELECT_TAB_MODIFIER__"/>
 #expand    <key id="key_selectTab7" oncommand="gBrowser.selectTabAtIndex(6, event);" key="7" modifiers="__NUM_SELECT_TAB_MODIFIER__"/>
 #expand    <key id="key_selectTab8" oncommand="gBrowser.selectTabAtIndex(7, event);" key="8" modifiers="__NUM_SELECT_TAB_MODIFIER__"/>
 #expand    <key id="key_selectLastTab" oncommand="gBrowser.selectTabAtIndex(-1, event);" key="9" modifiers="__NUM_SELECT_TAB_MODIFIER__"/>
 
 #ifdef NIGHTLY_BUILD
     <key id="key_wrCaptureCmd"
 #ifdef XP_MACOSX
-    keycode="3" modifiers="control,shift"
+    key="3" modifiers="control,shift"
 #else
     key="#" modifiers="control"
 #endif
     command="wrCaptureCmd"/>
 #endif
   </keyset>
 
 # Used by baseMenuOverlay
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/metaTags/bad_meta_tags.html
@@ -0,0 +1,14 @@
+<html>
+  <head>
+    <meta charset="UTF-8" />
+    <title>BadMetaTags</title>
+    <meta property="twitter:image" content="http://test.com/twitter-image.jpg" />
+    <meta property="og:image:url" content="ftp://test.com/og-image-url" />
+    <meta property="og:image" content="file:///Users/invalid/img.jpg" />
+    <meta property="twitter:description" />
+    <meta property="og:description" content="" />
+    <meta name="description" content="description" />
+  </head>
+  <body>
+  </body>
+</html>
--- a/browser/base/content/test/metaTags/browser.ini
+++ b/browser/base/content/test/metaTags/browser.ini
@@ -1,5 +1,8 @@
 [DEFAULT]
 support-files =
   head.js
-  meta_tags.html
+
+[browser_bad_meta_tags.js]
+support-files = bad_meta_tags.html
 [browser_meta_tags.js]
+support-files = meta_tags.html
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/metaTags/browser_bad_meta_tags.js
@@ -0,0 +1,25 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+const TEST_PATH = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "https://example.com") + "bad_meta_tags.html";
+
+/**
+ * This tests that with the page bad_meta_tags.html, ContentMetaHandler.jsm parses
+ * out the meta tags available and does not store content provided by a malformed
+ * meta tag. In this case the best defined meta tags are malformed, so here we
+ * test that we store the next best ones - "description" and "twitter:image". The
+ * list of meta tags and order of preference is found in ContentMetaHandler.jsm.
+ */
+add_task(async function test_bad_meta_tags() {
+  const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PATH);
+
+  // Wait until places has stored the page info
+  const pageInfo = await waitForPageInfo(TEST_PATH);
+  is(pageInfo.description, "description", "did not collect a og:description because meta tag was malformed");
+  is(pageInfo.previewImageURL.href, "http://test.com/twitter-image.jpg", "did not collect og:image because of invalid loading principal");
+
+  await BrowserTestUtils.removeTab(tab);
+  await PlacesTestUtils.clearHistory();
+});
+
--- a/browser/base/content/test/metaTags/browser_meta_tags.js
+++ b/browser/base/content/test/metaTags/browser_meta_tags.js
@@ -1,48 +1,45 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
-const URL = "https://example.com/browser/browser/base/content/test/metaTags/meta_tags.html";
-
+const TEST_PATH = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "https://example.com") + "meta_tags.html";
 /**
  * This tests that with the page meta_tags.html, ContentMetaHandler.jsm parses
  * out the meta tags avilable and only stores the best one for description and
  * one for preview image url. In the case of this test, the best defined meta
  * tags are "og:description" and "og:image:secure_url". The list of meta tags
- * and order of preference is found in ContentMetaHandler.jsm. Because there is
- * debounce logic in ContentLinkHandler.jsm to only make one single SQL update,
- * we have to wait for some time before checking that the page info was stored.
+ * and order of preference is found in ContentMetaHandler.jsm.
  */
 add_task(async function test_metadata() {
-  const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, URL);
+  const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PATH);
 
   // Wait until places has stored the page info
-  const pageInfo = await waitForPageInfo(URL);
+  const pageInfo = await waitForPageInfo(TEST_PATH);
   is(pageInfo.description, "og:description", "got the correct description");
   is(pageInfo.previewImageURL.href, "https://test.com/og-image-secure-url.jpg", "got the correct preview image");
 
   await BrowserTestUtils.removeTab(tab);
   await PlacesTestUtils.clearHistory();
 });
 
 /**
  * This test is almost like the previous one except it opens a second tab to
  * make sure the extra tab does not cause the debounce logic to be skipped. If
  * incorrectly skipped, the updated metadata would not include the delayed meta.
  */
 add_task(async function multiple_tabs() {
-  const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, URL);
+  const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PATH);
 
   // Add a background tab to cause another page to load *without* putting the
   // desired URL in a background tab, which results in its timers being throttled.
   gBrowser.addTab();
 
   // Wait until places has stored the page info
-  const pageInfo = await waitForPageInfo(URL);
+  const pageInfo = await waitForPageInfo(TEST_PATH);
   is(pageInfo.description, "og:description", "got the correct description");
   is(pageInfo.previewImageURL.href, "https://test.com/og-image-secure-url.jpg", "got the correct preview image");
 
   await BrowserTestUtils.removeTab(tab);
   await BrowserTestUtils.removeTab(gBrowser.selectedTab);
   await PlacesTestUtils.clearHistory();
 });
--- a/browser/base/content/test/metaTags/head.js
+++ b/browser/base/content/test/metaTags/head.js
@@ -2,16 +2,19 @@ ChromeUtils.import("resource://gre/modul
 
 ChromeUtils.defineModuleGetter(this, "PlacesUtils",
   "resource://gre/modules/PlacesUtils.jsm");
 ChromeUtils.defineModuleGetter(this, "PlacesTestUtils",
   "resource://testing-common/PlacesTestUtils.jsm");
 
 /**
  * Wait for url's page info (non-null description and preview url) to be set.
+ * Because there is debounce logic in ContentLinkHandler.jsm to only make one
+ * single SQL update, we have to wait for some time before checking that the page
+ * info was stored.
  */
 async function waitForPageInfo(url) {
   let pageInfo;
   await BrowserTestUtils.waitForCondition(async () => {
     pageInfo = await PlacesUtils.history.fetch(url, {"includeMeta": true});
     return pageInfo && pageInfo.description && pageInfo.previewImageURL;
   });
   return pageInfo;
--- a/browser/extensions/pdfjs/README.mozilla
+++ b/browser/extensions/pdfjs/README.mozilla
@@ -1,5 +1,5 @@
 This is the PDF.js project output, https://github.com/mozilla/pdf.js
 
-Current extension version is: 2.0.303
+Current extension version is: 2.0.332
 
-Taken from upstream commit: 55e3f97a
+Taken from upstream commit: 6b7e2cbc
--- a/browser/extensions/pdfjs/content/PdfJsNetwork.jsm
+++ b/browser/extensions/pdfjs/content/PdfJsNetwork.jsm
@@ -14,17 +14,17 @@
  */
 
 "use strict";
 
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 var EXPORTED_SYMBOLS = ["NetworkManager"];
 
-function log(aMsg) {
+function log(aMsg) { // eslint-disable-line no-unused-vars
   var msg = "PdfJsNetwork.jsm: " + (aMsg.join ? aMsg.join("") : aMsg);
   Services.console.logStringMessage(msg);
 }
 
 var NetworkManager = (function NetworkManagerClosure() {
 
   const OK_RESPONSE = 200;
   const PARTIAL_CONTENT_RESPONSE = 206;
--- a/browser/extensions/pdfjs/content/PdfStreamConverter.jsm
+++ b/browser/extensions/pdfjs/content/PdfStreamConverter.jsm
@@ -18,17 +18,16 @@
 var EXPORTED_SYMBOLS = ["PdfStreamConverter"];
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cr = Components.results;
 const Cu = Components.utils;
 
 const PDFJS_EVENT_ID = "pdf.js.message";
-const PDF_CONTENT_TYPE = "application/pdf";
 const PREF_PREFIX = "pdfjs";
 const PDF_VIEWER_WEB_PAGE = "resource://pdf.js/web/viewer.html";
 const MAX_NUMBER_OF_PREFS = 50;
 const MAX_STRING_PREF_LENGTH = 128;
 
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 
--- a/browser/extensions/pdfjs/content/build/pdf.js
+++ b/browser/extensions/pdfjs/content/build/pdf.js
@@ -1667,18 +1667,16 @@ function getDefaultSetting(id) {
     case 'cMapPacked':
       return globalSettings ? globalSettings.cMapPacked : false;
     case 'postMessageTransfers':
       return globalSettings ? globalSettings.postMessageTransfers : true;
     case 'workerPort':
       return globalSettings ? globalSettings.workerPort : null;
     case 'workerSrc':
       return globalSettings ? globalSettings.workerSrc : null;
-    case 'disableWorker':
-      return globalSettings ? globalSettings.disableWorker : false;
     case 'maxImageSize':
       return globalSettings ? globalSettings.maxImageSize : -1;
     case 'imageResourcesPath':
       return globalSettings ? globalSettings.imageResourcesPath : '';
     case 'isEvalSupported':
       return globalSettings ? globalSettings.isEvalSupported : true;
     case 'externalLinkTarget':
       if (!globalSettings) {
@@ -1923,17 +1921,17 @@ function getDocument(src) {
     });
   }).catch(task._capability.reject);
   return task;
 }
 function _fetchDocument(worker, source, pdfDataRangeTransport, docId) {
   if (worker.destroyed) {
     return Promise.reject(new Error('Worker was destroyed'));
   }
-  let apiVersion = '2.0.303';
+  let apiVersion = '2.0.332';
   source.disableRange = (0, _dom_utils.getDefaultSetting)('disableRange');
   source.disableAutoFetch = (0, _dom_utils.getDefaultSetting)('disableAutoFetch');
   source.disableStream = (0, _dom_utils.getDefaultSetting)('disableStream');
   if (pdfDataRangeTransport) {
     source.length = pdfDataRangeTransport.length;
     source.initialData = pdfDataRangeTransport.initialData;
   }
   return worker.messageHandler.sendWithPromise('GetDocRequest', {
@@ -2422,24 +2420,34 @@ var PDFWorker = function PDFWorkerClosur
     if (typeof workerSrc !== 'undefined') {
       return workerSrc;
     }
     if ((0, _dom_utils.getDefaultSetting)('workerSrc')) {
       return (0, _dom_utils.getDefaultSetting)('workerSrc');
     }
     throw new Error('No PDFJS.workerSrc specified');
   }
+  function getMainThreadWorkerMessageHandler() {
+    if (typeof window === 'undefined') {
+      return null;
+    }
+    return window.pdfjsDistBuildPdfWorker && window.pdfjsDistBuildPdfWorker.WorkerMessageHandler;
+  }
   let fakeWorkerFilesLoadedCapability;
   function setupFakeWorkerGlobal() {
-    var WorkerMessageHandler;
     if (fakeWorkerFilesLoadedCapability) {
       return fakeWorkerFilesLoadedCapability.promise;
     }
     fakeWorkerFilesLoadedCapability = (0, _util.createPromiseCapability)();
-    var loader = fakeWorkerFilesLoader || function (callback) {
+    let mainWorkerMessageHandler = getMainThreadWorkerMessageHandler();
+    if (mainWorkerMessageHandler) {
+      fakeWorkerFilesLoadedCapability.resolve(mainWorkerMessageHandler);
+      return fakeWorkerFilesLoadedCapability.promise;
+    }
+    let loader = fakeWorkerFilesLoader || function (callback) {
       _util.Util.loadScript(getWorkerSrc(), function () {
         callback(window.pdfjsDistBuildPdfWorker.WorkerMessageHandler);
       });
     };
     loader(fakeWorkerFilesLoadedCapability.resolve);
     return fakeWorkerFilesLoadedCapability.promise;
   }
   function createCDNWrapper(url) {
@@ -2477,17 +2485,17 @@ var PDFWorker = function PDFWorkerClosur
     },
     _initializeFromPort: function PDFWorker_initializeFromPort(port) {
       this._port = port;
       this._messageHandler = new _util.MessageHandler('main', 'worker', port);
       this._messageHandler.on('ready', function () {});
       this._readyCapability.resolve();
     },
     _initialize: function PDFWorker_initialize() {
-      if (!isWorkerDisabled && !(0, _dom_utils.getDefaultSetting)('disableWorker') && typeof Worker !== 'undefined') {
+      if (typeof Worker !== 'undefined' && !isWorkerDisabled && !getMainThreadWorkerMessageHandler()) {
         var workerSrc = getWorkerSrc();
         try {
           var worker = new Worker(workerSrc);
           var messageHandler = new _util.MessageHandler('main', 'worker', worker);
           var terminateEarly = () => {
             worker.removeEventListener('error', onWorkerError);
             messageHandler.destroy();
             worker.terminate();
@@ -2553,17 +2561,17 @@ var PDFWorker = function PDFWorkerClosur
           return;
         } catch (e) {
           (0, _util.info)('The worker has been disabled.');
         }
       }
       this._setupFakeWorker();
     },
     _setupFakeWorker: function PDFWorker_setupFakeWorker() {
-      if (!isWorkerDisabled && !(0, _dom_utils.getDefaultSetting)('disableWorker')) {
+      if (!isWorkerDisabled) {
         (0, _util.warn)('Setting up fake worker.');
         isWorkerDisabled = true;
       }
       setupFakeWorkerGlobal().then(WorkerMessageHandler => {
         if (this.destroyed) {
           this._readyCapability.reject(new Error('Worker was destroyed'));
           return;
         }
@@ -2593,16 +2601,19 @@ var PDFWorker = function PDFWorkerClosur
     }
   };
   PDFWorker.fromPort = function (port) {
     if (pdfWorkerPorts.has(port)) {
       return pdfWorkerPorts.get(port);
     }
     return new PDFWorker(null, port);
   };
+  PDFWorker.getWorkerSrc = function () {
+    return getWorkerSrc();
+  };
   return PDFWorker;
 }();
 var WorkerTransport = function WorkerTransportClosure() {
   function WorkerTransport(messageHandler, loadingTask, networkStream, CMapReaderFactory) {
     this.messageHandler = messageHandler;
     this.loadingTask = loadingTask;
     this.commonObjs = new PDFObjects();
     this.fontLoader = new _font_loader.FontLoader(loadingTask.docId);
@@ -3218,18 +3229,18 @@ var InternalRenderTask = function Intern
         }
       }
     }
   };
   return InternalRenderTask;
 }();
 var version, build;
 {
-  exports.version = version = '2.0.303';
-  exports.build = build = '55e3f97a';
+  exports.version = version = '2.0.332';
+  exports.build = build = '6b7e2cbc';
 }
 exports.getDocument = getDocument;
 exports.LoopbackPort = LoopbackPort;
 exports.PDFDataRangeTransport = PDFDataRangeTransport;
 exports.PDFWorker = PDFWorker;
 exports.PDFDocumentProxy = PDFDocumentProxy;
 exports.PDFPageProxy = PDFPageProxy;
 exports.setPDFNetworkStreamFactory = setPDFNetworkStreamFactory;
@@ -4612,18 +4623,18 @@ exports.SVGGraphics = SVGGraphics;
 
 /***/ }),
 /* 8 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
 
 "use strict";
 
 
-var pdfjsVersion = '2.0.303';
-var pdfjsBuild = '55e3f97a';
+var pdfjsVersion = '2.0.332';
+var pdfjsBuild = '6b7e2cbc';
 var pdfjsSharedUtil = __w_pdfjs_require__(0);
 var pdfjsDisplayGlobal = __w_pdfjs_require__(12);
 var pdfjsDisplayAPI = __w_pdfjs_require__(3);
 var pdfjsDisplayTextLayer = __w_pdfjs_require__(6);
 var pdfjsDisplayAnnotationLayer = __w_pdfjs_require__(5);
 var pdfjsDisplayDOMUtils = __w_pdfjs_require__(1);
 var pdfjsDisplaySVG = __w_pdfjs_require__(7);
 ;
@@ -7735,18 +7746,18 @@ var _svg = __w_pdfjs_require__(7);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 if (!_global_scope2.default.PDFJS) {
   _global_scope2.default.PDFJS = {};
 }
 var PDFJS = _global_scope2.default.PDFJS;
 {
-  PDFJS.version = '2.0.303';
-  PDFJS.build = '55e3f97a';
+  PDFJS.version = '2.0.332';
+  PDFJS.build = '6b7e2cbc';
 }
 PDFJS.pdfBug = false;
 if (PDFJS.verbosity !== undefined) {
   (0, _util.setVerbosityLevel)(PDFJS.verbosity);
 }
 delete PDFJS.verbosity;
 Object.defineProperty(PDFJS, 'verbosity', {
   get() {
@@ -7783,17 +7794,16 @@ PDFJS.UnexpectedResponseException = _uti
 PDFJS.Util = _util.Util;
 PDFJS.PageViewport = _util.PageViewport;
 PDFJS.createPromiseCapability = _util.createPromiseCapability;
 PDFJS.maxImageSize = PDFJS.maxImageSize === undefined ? -1 : PDFJS.maxImageSize;
 PDFJS.cMapUrl = PDFJS.cMapUrl === undefined ? null : PDFJS.cMapUrl;
 PDFJS.cMapPacked = PDFJS.cMapPacked === undefined ? false : PDFJS.cMapPacked;
 PDFJS.disableFontFace = PDFJS.disableFontFace === undefined ? false : PDFJS.disableFontFace;
 PDFJS.imageResourcesPath = PDFJS.imageResourcesPath === undefined ? '' : PDFJS.imageResourcesPath;
-PDFJS.disableWorker = PDFJS.disableWorker === undefined ? false : PDFJS.disableWorker;
 PDFJS.workerSrc = PDFJS.workerSrc === undefined ? null : PDFJS.workerSrc;
 PDFJS.workerPort = PDFJS.workerPort === undefined ? null : PDFJS.workerPort;
 PDFJS.disableRange = PDFJS.disableRange === undefined ? false : PDFJS.disableRange;
 PDFJS.disableStream = PDFJS.disableStream === undefined ? false : PDFJS.disableStream;
 PDFJS.disableAutoFetch = PDFJS.disableAutoFetch === undefined ? false : PDFJS.disableAutoFetch;
 PDFJS.pdfBug = PDFJS.pdfBug === undefined ? false : PDFJS.pdfBug;
 PDFJS.postMessageTransfers = PDFJS.postMessageTransfers === undefined ? true : PDFJS.postMessageTransfers;
 PDFJS.disableCreateObjectURL = PDFJS.disableCreateObjectURL === undefined ? false : PDFJS.disableCreateObjectURL;
--- a/browser/extensions/pdfjs/content/build/pdf.worker.js
+++ b/browser/extensions/pdfjs/content/build/pdf.worker.js
@@ -15045,65 +15045,46 @@ var NullCipher = function NullCipherClos
   function NullCipher() {}
   NullCipher.prototype = {
     decryptBlock: function NullCipher_decryptBlock(data) {
       return data;
     }
   };
   return NullCipher;
 }();
-var AES128Cipher = function AES128CipherClosure() {
-  var rcon = new Uint8Array([0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d]);
-  var s = new Uint8Array([0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16]);
-  var inv_s = new Uint8Array([0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d]);
-  var mixCol = new Uint8Array(256);
-  for (var i = 0; i < 256; i++) {
-    if (i < 128) {
-      mixCol[i] = i << 1;
-    } else {
-      mixCol[i] = i << 1 ^ 0x1b;
-    }
-  }
-  var mix = new Uint32Array([0x00000000, 0x0e090d0b, 0x1c121a16, 0x121b171d, 0x3824342c, 0x362d3927, 0x24362e3a, 0x2a3f2331, 0x70486858, 0x7e416553, 0x6c5a724e, 0x62537f45, 0x486c5c74, 0x4665517f, 0x547e4662, 0x5a774b69, 0xe090d0b0, 0xee99ddbb, 0xfc82caa6, 0xf28bc7ad, 0xd8b4e49c, 0xd6bde997, 0xc4a6fe8a, 0xcaaff381, 0x90d8b8e8, 0x9ed1b5e3, 0x8ccaa2fe, 0x82c3aff5, 0xa8fc8cc4, 0xa6f581cf, 0xb4ee96d2, 0xbae79bd9, 0xdb3bbb7b, 0xd532b670, 0xc729a16d, 0xc920ac66, 0xe31f8f57, 0xed16825c, 0xff0d9541, 0xf104984a, 0xab73d323, 0xa57ade28, 0xb761c935, 0xb968c43e, 0x9357e70f, 0x9d5eea04, 0x8f45fd19, 0x814cf012, 0x3bab6bcb, 0x35a266c0, 0x27b971dd, 0x29b07cd6, 0x038f5fe7, 0x0d8652ec, 0x1f9d45f1, 0x119448fa, 0x4be30393, 0x45ea0e98, 0x57f11985, 0x59f8148e, 0x73c737bf, 0x7dce3ab4, 0x6fd52da9, 0x61dc20a2, 0xad766df6, 0xa37f60fd, 0xb16477e0, 0xbf6d7aeb, 0x955259da, 0x9b5b54d1, 0x894043cc, 0x87494ec7, 0xdd3e05ae, 0xd33708a5, 0xc12c1fb8, 0xcf2512b3, 0xe51a3182, 0xeb133c89, 0xf9082b94, 0xf701269f, 0x4de6bd46, 0x43efb04d, 0x51f4a750, 0x5ffdaa5b, 0x75c2896a, 0x7bcb8461, 0x69d0937c, 0x67d99e77, 0x3daed51e, 0x33a7d815, 0x21bccf08, 0x2fb5c203, 0x058ae132, 0x0b83ec39, 0x1998fb24, 0x1791f62f, 0x764dd68d, 0x7844db86, 0x6a5fcc9b, 0x6456c190, 0x4e69e2a1, 0x4060efaa, 0x527bf8b7, 0x5c72f5bc, 0x0605bed5, 0x080cb3de, 0x1a17a4c3, 0x141ea9c8, 0x3e218af9, 0x302887f2, 0x223390ef, 0x2c3a9de4, 0x96dd063d, 0x98d40b36, 0x8acf1c2b, 0x84c61120, 0xaef93211, 0xa0f03f1a, 0xb2eb2807, 0xbce2250c, 0xe6956e65, 0xe89c636e, 0xfa877473, 0xf48e7978, 0xdeb15a49, 0xd0b85742, 0xc2a3405f, 0xccaa4d54, 0x41ecdaf7, 0x4fe5d7fc, 0x5dfec0e1, 0x53f7cdea, 0x79c8eedb, 0x77c1e3d0, 0x65daf4cd, 0x6bd3f9c6, 0x31a4b2af, 0x3fadbfa4, 0x2db6a8b9, 0x23bfa5b2, 0x09808683, 0x07898b88, 0x15929c95, 0x1b9b919e, 0xa17c0a47, 0xaf75074c, 0xbd6e1051, 0xb3671d5a, 0x99583e6b, 0x97513360, 0x854a247d, 0x8b432976, 0xd134621f, 0xdf3d6f14, 0xcd267809, 0xc32f7502, 0xe9105633, 0xe7195b38, 0xf5024c25, 0xfb0b412e, 0x9ad7618c, 0x94de6c87, 0x86c57b9a, 0x88cc7691, 0xa2f355a0, 0xacfa58ab, 0xbee14fb6, 0xb0e842bd, 0xea9f09d4, 0xe49604df, 0xf68d13c2, 0xf8841ec9, 0xd2bb3df8, 0xdcb230f3, 0xcea927ee, 0xc0a02ae5, 0x7a47b13c, 0x744ebc37, 0x6655ab2a, 0x685ca621, 0x42638510, 0x4c6a881b, 0x5e719f06, 0x5078920d, 0x0a0fd964, 0x0406d46f, 0x161dc372, 0x1814ce79, 0x322bed48, 0x3c22e043, 0x2e39f75e, 0x2030fa55, 0xec9ab701, 0xe293ba0a, 0xf088ad17, 0xfe81a01c, 0xd4be832d, 0xdab78e26, 0xc8ac993b, 0xc6a59430, 0x9cd2df59, 0x92dbd252, 0x80c0c54f, 0x8ec9c844, 0xa4f6eb75, 0xaaffe67e, 0xb8e4f163, 0xb6edfc68, 0x0c0a67b1, 0x02036aba, 0x10187da7, 0x1e1170ac, 0x342e539d, 0x3a275e96, 0x283c498b, 0x26354480, 0x7c420fe9, 0x724b02e2, 0x605015ff, 0x6e5918f4, 0x44663bc5, 0x4a6f36ce, 0x587421d3, 0x567d2cd8, 0x37a10c7a, 0x39a80171, 0x2bb3166c, 0x25ba1b67, 0x0f853856, 0x018c355d, 0x13972240, 0x1d9e2f4b, 0x47e96422, 0x49e06929, 0x5bfb7e34, 0x55f2733f, 0x7fcd500e, 0x71c45d05, 0x63df4a18, 0x6dd64713, 0xd731dcca, 0xd938d1c1, 0xcb23c6dc, 0xc52acbd7, 0xef15e8e6, 0xe11ce5ed, 0xf307f2f0, 0xfd0efffb, 0xa779b492, 0xa970b999, 0xbb6bae84, 0xb562a38f, 0x9f5d80be, 0x91548db5, 0x834f9aa8, 0x8d4697a3]);
-  function expandKey128(cipherKey) {
-    var b = 176,
-        result = new Uint8Array(b);
-    result.set(cipherKey);
-    for (var j = 16, i = 1; j < b; ++i) {
-      var t1 = result[j - 3],
-          t2 = result[j - 2],
-          t3 = result[j - 1],
-          t4 = result[j - 4];
-      t1 = s[t1];
-      t2 = s[t2];
-      t3 = s[t3];
-      t4 = s[t4];
-      t1 = t1 ^ rcon[i];
-      for (var n = 0; n < 4; ++n) {
-        result[j] = t1 ^= result[j - 16];
-        j++;
-        result[j] = t2 ^= result[j - 16];
-        j++;
-        result[j] = t3 ^= result[j - 16];
-        j++;
-        result[j] = t4 ^= result[j - 16];
-        j++;
-      }
-    }
-    return result;
-  }
-  function decrypt128(input, key) {
-    var state = new Uint8Array(16);
+class AESBaseCipher {
+  constructor() {
+    if (this.constructor === AESBaseCipher) {
+      (0, _util.unreachable)('Cannot initialize AESBaseCipher.');
+    }
+    this._s = new Uint8Array([0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16]);
+    this._inv_s = new Uint8Array([0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d]);
+    this._mix = new Uint32Array([0x00000000, 0x0e090d0b, 0x1c121a16, 0x121b171d, 0x3824342c, 0x362d3927, 0x24362e3a, 0x2a3f2331, 0x70486858, 0x7e416553, 0x6c5a724e, 0x62537f45, 0x486c5c74, 0x4665517f, 0x547e4662, 0x5a774b69, 0xe090d0b0, 0xee99ddbb, 0xfc82caa6, 0xf28bc7ad, 0xd8b4e49c, 0xd6bde997, 0xc4a6fe8a, 0xcaaff381, 0x90d8b8e8, 0x9ed1b5e3, 0x8ccaa2fe, 0x82c3aff5, 0xa8fc8cc4, 0xa6f581cf, 0xb4ee96d2, 0xbae79bd9, 0xdb3bbb7b, 0xd532b670, 0xc729a16d, 0xc920ac66, 0xe31f8f57, 0xed16825c, 0xff0d9541, 0xf104984a, 0xab73d323, 0xa57ade28, 0xb761c935, 0xb968c43e, 0x9357e70f, 0x9d5eea04, 0x8f45fd19, 0x814cf012, 0x3bab6bcb, 0x35a266c0, 0x27b971dd, 0x29b07cd6, 0x038f5fe7, 0x0d8652ec, 0x1f9d45f1, 0x119448fa, 0x4be30393, 0x45ea0e98, 0x57f11985, 0x59f8148e, 0x73c737bf, 0x7dce3ab4, 0x6fd52da9, 0x61dc20a2, 0xad766df6, 0xa37f60fd, 0xb16477e0, 0xbf6d7aeb, 0x955259da, 0x9b5b54d1, 0x894043cc, 0x87494ec7, 0xdd3e05ae, 0xd33708a5, 0xc12c1fb8, 0xcf2512b3, 0xe51a3182, 0xeb133c89, 0xf9082b94, 0xf701269f, 0x4de6bd46, 0x43efb04d, 0x51f4a750, 0x5ffdaa5b, 0x75c2896a, 0x7bcb8461, 0x69d0937c, 0x67d99e77, 0x3daed51e, 0x33a7d815, 0x21bccf08, 0x2fb5c203, 0x058ae132, 0x0b83ec39, 0x1998fb24, 0x1791f62f, 0x764dd68d, 0x7844db86, 0x6a5fcc9b, 0x6456c190, 0x4e69e2a1, 0x4060efaa, 0x527bf8b7, 0x5c72f5bc, 0x0605bed5, 0x080cb3de, 0x1a17a4c3, 0x141ea9c8, 0x3e218af9, 0x302887f2, 0x223390ef, 0x2c3a9de4, 0x96dd063d, 0x98d40b36, 0x8acf1c2b, 0x84c61120, 0xaef93211, 0xa0f03f1a, 0xb2eb2807, 0xbce2250c, 0xe6956e65, 0xe89c636e, 0xfa877473, 0xf48e7978, 0xdeb15a49, 0xd0b85742, 0xc2a3405f, 0xccaa4d54, 0x41ecdaf7, 0x4fe5d7fc, 0x5dfec0e1, 0x53f7cdea, 0x79c8eedb, 0x77c1e3d0, 0x65daf4cd, 0x6bd3f9c6, 0x31a4b2af, 0x3fadbfa4, 0x2db6a8b9, 0x23bfa5b2, 0x09808683, 0x07898b88, 0x15929c95, 0x1b9b919e, 0xa17c0a47, 0xaf75074c, 0xbd6e1051, 0xb3671d5a, 0x99583e6b, 0x97513360, 0x854a247d, 0x8b432976, 0xd134621f, 0xdf3d6f14, 0xcd267809, 0xc32f7502, 0xe9105633, 0xe7195b38, 0xf5024c25, 0xfb0b412e, 0x9ad7618c, 0x94de6c87, 0x86c57b9a, 0x88cc7691, 0xa2f355a0, 0xacfa58ab, 0xbee14fb6, 0xb0e842bd, 0xea9f09d4, 0xe49604df, 0xf68d13c2, 0xf8841ec9, 0xd2bb3df8, 0xdcb230f3, 0xcea927ee, 0xc0a02ae5, 0x7a47b13c, 0x744ebc37, 0x6655ab2a, 0x685ca621, 0x42638510, 0x4c6a881b, 0x5e719f06, 0x5078920d, 0x0a0fd964, 0x0406d46f, 0x161dc372, 0x1814ce79, 0x322bed48, 0x3c22e043, 0x2e39f75e, 0x2030fa55, 0xec9ab701, 0xe293ba0a, 0xf088ad17, 0xfe81a01c, 0xd4be832d, 0xdab78e26, 0xc8ac993b, 0xc6a59430, 0x9cd2df59, 0x92dbd252, 0x80c0c54f, 0x8ec9c844, 0xa4f6eb75, 0xaaffe67e, 0xb8e4f163, 0xb6edfc68, 0x0c0a67b1, 0x02036aba, 0x10187da7, 0x1e1170ac, 0x342e539d, 0x3a275e96, 0x283c498b, 0x26354480, 0x7c420fe9, 0x724b02e2, 0x605015ff, 0x6e5918f4, 0x44663bc5, 0x4a6f36ce, 0x587421d3, 0x567d2cd8, 0x37a10c7a, 0x39a80171, 0x2bb3166c, 0x25ba1b67, 0x0f853856, 0x018c355d, 0x13972240, 0x1d9e2f4b, 0x47e96422, 0x49e06929, 0x5bfb7e34, 0x55f2733f, 0x7fcd500e, 0x71c45d05, 0x63df4a18, 0x6dd64713, 0xd731dcca, 0xd938d1c1, 0xcb23c6dc, 0xc52acbd7, 0xef15e8e6, 0xe11ce5ed, 0xf307f2f0, 0xfd0efffb, 0xa779b492, 0xa970b999, 0xbb6bae84, 0xb562a38f, 0x9f5d80be, 0x91548db5, 0x834f9aa8, 0x8d4697a3]);
+    this._mixCol = new Uint8Array(256);
+    for (let i = 0; i < 256; i++) {
+      if (i < 128) {
+        this._mixCol[i] = i << 1;
+      } else {
+        this._mixCol[i] = i << 1 ^ 0x1b;
+      }
+    }
+    this.buffer = new Uint8Array(16);
+    this.bufferPosition = 0;
+  }
+  _expandKey(cipherKey) {
+    (0, _util.unreachable)('Cannot call `_expandKey` on the base class');
+  }
+  _decrypt(input, key) {
+    let t, u, v;
+    let state = new Uint8Array(16);
     state.set(input);
-    var i, j, k;
-    var t, u, v;
-    for (j = 0, k = 160; j < 16; ++j, ++k) {
+    for (let j = 0, k = this._keySize; j < 16; ++j, ++k) {
       state[j] ^= key[k];
     }
-    for (i = 9; i >= 1; --i) {
+    for (let i = this._cyclesOfRepetition - 1; i >= 1; --i) {
       t = state[13];
       state[13] = state[9];
       state[9] = state[5];
       state[5] = state[1];
       state[1] = t;
       t = state[14];
       u = state[10];
       state[14] = state[6];
@@ -15112,27 +15093,27 @@ var AES128Cipher = function AES128Cipher
       state[2] = u;
       t = state[15];
       u = state[11];
       v = state[7];
       state[15] = state[3];
       state[11] = t;
       state[7] = u;
       state[3] = v;
-      for (j = 0; j < 16; ++j) {
-        state[j] = inv_s[state[j]];
-      }
-      for (j = 0, k = i * 16; j < 16; ++j, ++k) {
+      for (let j = 0; j < 16; ++j) {
+        state[j] = this._inv_s[state[j]];
+      }
+      for (let j = 0, k = i * 16; j < 16; ++j, ++k) {
         state[j] ^= key[k];
       }
-      for (j = 0; j < 16; j += 4) {
-        var s0 = mix[state[j]],
-            s1 = mix[state[j + 1]],
-            s2 = mix[state[j + 2]],
-            s3 = mix[state[j + 3]];
+      for (let j = 0; j < 16; j += 4) {
+        let s0 = this._mix[state[j]];
+        let s1 = this._mix[state[j + 1]];
+        let s2 = this._mix[state[j + 2]];
+        let s3 = this._mix[state[j + 3]];
         t = s0 ^ s1 >>> 8 ^ s1 << 24 ^ s2 >>> 16 ^ s2 << 16 ^ s3 >>> 24 ^ s3 << 8;
         state[j] = t >>> 24 & 0xFF;
         state[j + 1] = t >> 16 & 0xFF;
         state[j + 2] = t >> 8 & 0xFF;
         state[j + 3] = t & 0xFF;
       }
     }
     t = state[13];
@@ -15148,31 +15129,32 @@ var AES128Cipher = function AES128Cipher
     state[2] = u;
     t = state[15];
     u = state[11];
     v = state[7];
     state[15] = state[3];
     state[11] = t;
     state[7] = u;
     state[3] = v;
-    for (j = 0; j < 16; ++j) {
-      state[j] = inv_s[state[j]];
+    for (let j = 0; j < 16; ++j) {
+      state[j] = this._inv_s[state[j]];
       state[j] ^= key[j];
     }
     return state;
   }
-  function encrypt128(input, key) {
-    var t, u, v, j, k;
-    var state = new Uint8Array(16);
+  _encrypt(input, key) {
+    const s = this._s;
+    let t, u, v;
+    let state = new Uint8Array(16);
     state.set(input);
-    for (j = 0; j < 16; ++j) {
+    for (let j = 0; j < 16; ++j) {
       state[j] ^= key[j];
     }
-    for (i = 1; i < 10; i++) {
-      for (j = 0; j < 16; ++j) {
+    for (let i = 1; i < this._cyclesOfRepetition; i++) {
+      for (let j = 0; j < 16; ++j) {
         state[j] = s[state[j]];
       }
       v = state[1];
       state[1] = state[5];
       state[5] = state[9];
       state[9] = state[13];
       state[13] = v;
       v = state[2];
@@ -15183,32 +15165,32 @@ var AES128Cipher = function AES128Cipher
       state[14] = u;
       v = state[3];
       u = state[7];
       t = state[11];
       state[3] = state[15];
       state[7] = v;
       state[11] = u;
       state[15] = t;
-      for (j = 0; j < 16; j += 4) {
-        var s0 = state[j + 0],
-            s1 = state[j + 1];
-        var s2 = state[j + 2],
-            s3 = state[j + 3];
+      for (let j = 0; j < 16; j += 4) {
+        let s0 = state[j + 0];
+        let s1 = state[j + 1];
+        let s2 = state[j + 2];
+        let s3 = state[j + 3];
         t = s0 ^ s1 ^ s2 ^ s3;
-        state[j + 0] ^= t ^ mixCol[s0 ^ s1];
-        state[j + 1] ^= t ^ mixCol[s1 ^ s2];
-        state[j + 2] ^= t ^ mixCol[s2 ^ s3];
-        state[j + 3] ^= t ^ mixCol[s3 ^ s0];
-      }
-      for (j = 0, k = i * 16; j < 16; ++j, ++k) {
+        state[j + 0] ^= t ^ this._mixCol[s0 ^ s1];
+        state[j + 1] ^= t ^ this._mixCol[s1 ^ s2];
+        state[j + 2] ^= t ^ this._mixCol[s2 ^ s3];
+        state[j + 3] ^= t ^ this._mixCol[s3 ^ s0];
+      }
+      for (let j = 0, k = i * 16; j < 16; ++j, ++k) {
         state[j] ^= key[k];
       }
     }
-    for (j = 0; j < 16; ++j) {
+    for (let j = 0; j < 16; ++j) {
       state[j] = s[state[j]];
     }
     v = state[1];
     state[1] = state[5];
     state[5] = state[9];
     state[9] = state[13];
     state[13] = v;
     v = state[2];
@@ -15219,157 +15201,181 @@ var AES128Cipher = function AES128Cipher
     state[14] = u;
     v = state[3];
     u = state[7];
     t = state[11];
     state[3] = state[15];
     state[7] = v;
     state[11] = u;
     state[15] = t;
-    for (j = 0, k = 160; j < 16; ++j, ++k) {
+    for (let j = 0, k = this._keySize; j < 16; ++j, ++k) {
       state[j] ^= key[k];
     }
     return state;
   }
-  function AES128Cipher(key) {
-    this.key = expandKey128(key);
-    this.buffer = new Uint8Array(16);
-    this.bufferPosition = 0;
-  }
-  function decryptBlock2(data, finalize) {
-    var i,
-        j,
-        ii,
-        sourceLength = data.length,
-        buffer = this.buffer,
-        bufferLength = this.bufferPosition,
-        result = [],
+  _decryptBlock2(data, finalize) {
+    let sourceLength = data.length;
+    let buffer = this.buffer,
+        bufferLength = this.bufferPosition;
+    let result = [],
         iv = this.iv;
-    for (i = 0; i < sourceLength; ++i) {
+    for (let i = 0; i < sourceLength; ++i) {
       buffer[bufferLength] = data[i];
       ++bufferLength;
       if (bufferLength < 16) {
         continue;
       }
-      var plain = decrypt128(buffer, this.key);
-      for (j = 0; j < 16; ++j) {
+      let plain = this._decrypt(buffer, this._key);
+      for (let j = 0; j < 16; ++j) {
         plain[j] ^= iv[j];
       }
       iv = buffer;
       result.push(plain);
       buffer = new Uint8Array(16);
       bufferLength = 0;
     }
     this.buffer = buffer;
     this.bufferLength = bufferLength;
     this.iv = iv;
     if (result.length === 0) {
-      return new Uint8Array([]);
-    }
-    var outputLength = 16 * result.length;
+      return new Uint8Array(0);
+    }
+    let outputLength = 16 * result.length;
     if (finalize) {
-      var lastBlock = result[result.length - 1];
-      var psLen = lastBlock[15];
+      let lastBlock = result[result.length - 1];
+      let psLen = lastBlock[15];
       if (psLen <= 16) {
-        for (i = 15, ii = 16 - psLen; i >= ii; --i) {
+        for (let i = 15, ii = 16 - psLen; i >= ii; --i) {
           if (lastBlock[i] !== psLen) {
             psLen = 0;
             break;
           }
         }
         outputLength -= psLen;
         result[result.length - 1] = lastBlock.subarray(0, 16 - psLen);
       }
     }
-    var output = new Uint8Array(outputLength);
-    for (i = 0, j = 0, ii = result.length; i < ii; ++i, j += 16) {
+    let output = new Uint8Array(outputLength);
+    for (let i = 0, j = 0, ii = result.length; i < ii; ++i, j += 16) {
       output.set(result[i], j);
     }
     return output;
   }
-  AES128Cipher.prototype = {
-    decryptBlock: function AES128Cipher_decryptBlock(data, finalize) {
-      var i,
-          sourceLength = data.length;
-      var buffer = this.buffer,
-          bufferLength = this.bufferPosition;
-      for (i = 0; bufferLength < 16 && i < sourceLength; ++i, ++bufferLength) {
+  decryptBlock(data, finalize, iv = null) {
+    let sourceLength = data.length;
+    let buffer = this.buffer,
+        bufferLength = this.bufferPosition;
+    if (iv) {
+      this.iv = iv;
+    } else {
+      for (let i = 0; bufferLength < 16 && i < sourceLength; ++i, ++bufferLength) {
         buffer[bufferLength] = data[i];
       }
       if (bufferLength < 16) {
         this.bufferLength = bufferLength;
-        return new Uint8Array([]);
+        return new Uint8Array(0);
       }
       this.iv = buffer;
-      this.buffer = new Uint8Array(16);
-      this.bufferLength = 0;
-      this.decryptBlock = decryptBlock2;
-      return this.decryptBlock(data.subarray(16), finalize);
-    },
-    encrypt: function AES128Cipher_encrypt(data, iv) {
-      var i,
-          j,
-          ii,
-          sourceLength = data.length,
-          buffer = this.buffer,
-          bufferLength = this.bufferPosition,
-          result = [];
-      if (!iv) {
-        iv = new Uint8Array(16);
-      }
-      for (i = 0; i < sourceLength; ++i) {
-        buffer[bufferLength] = data[i];
-        ++bufferLength;
-        if (bufferLength < 16) {
-          continue;
-        }
-        for (j = 0; j < 16; ++j) {
-          buffer[j] ^= iv[j];
-        }
-        var cipher = encrypt128(buffer, this.key);
-        iv = cipher;
-        result.push(cipher);
-        buffer = new Uint8Array(16);
-        bufferLength = 0;
-      }
-      this.buffer = buffer;
-      this.bufferLength = bufferLength;
-      this.iv = iv;
-      if (result.length === 0) {
-        return new Uint8Array([]);
-      }
-      var outputLength = 16 * result.length;
-      var output = new Uint8Array(outputLength);
-      for (i = 0, j = 0, ii = result.length; i < ii; ++i, j += 16) {
-        output.set(result[i], j);
-      }
-      return output;
-    }
-  };
-  return AES128Cipher;
-}();
-var AES256Cipher = function AES256CipherClosure() {
-  var s = new Uint8Array([0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16]);
-  var inv_s = new Uint8Array([0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d]);
-  var mixCol = new Uint8Array(256);
-  for (var i = 0; i < 256; i++) {
-    if (i < 128) {
-      mixCol[i] = i << 1;
-    } else {
-      mixCol[i] = i << 1 ^ 0x1b;
-    }
-  }
-  var mix = new Uint32Array([0x00000000, 0x0e090d0b, 0x1c121a16, 0x121b171d, 0x3824342c, 0x362d3927, 0x24362e3a, 0x2a3f2331, 0x70486858, 0x7e416553, 0x6c5a724e, 0x62537f45, 0x486c5c74, 0x4665517f, 0x547e4662, 0x5a774b69, 0xe090d0b0, 0xee99ddbb, 0xfc82caa6, 0xf28bc7ad, 0xd8b4e49c, 0xd6bde997, 0xc4a6fe8a, 0xcaaff381, 0x90d8b8e8, 0x9ed1b5e3, 0x8ccaa2fe, 0x82c3aff5, 0xa8fc8cc4, 0xa6f581cf, 0xb4ee96d2, 0xbae79bd9, 0xdb3bbb7b, 0xd532b670, 0xc729a16d, 0xc920ac66, 0xe31f8f57, 0xed16825c, 0xff0d9541, 0xf104984a, 0xab73d323, 0xa57ade28, 0xb761c935, 0xb968c43e, 0x9357e70f, 0x9d5eea04, 0x8f45fd19, 0x814cf012, 0x3bab6bcb, 0x35a266c0, 0x27b971dd, 0x29b07cd6, 0x038f5fe7, 0x0d8652ec, 0x1f9d45f1, 0x119448fa, 0x4be30393, 0x45ea0e98, 0x57f11985, 0x59f8148e, 0x73c737bf, 0x7dce3ab4, 0x6fd52da9, 0x61dc20a2, 0xad766df6, 0xa37f60fd, 0xb16477e0, 0xbf6d7aeb, 0x955259da, 0x9b5b54d1, 0x894043cc, 0x87494ec7, 0xdd3e05ae, 0xd33708a5, 0xc12c1fb8, 0xcf2512b3, 0xe51a3182, 0xeb133c89, 0xf9082b94, 0xf701269f, 0x4de6bd46, 0x43efb04d, 0x51f4a750, 0x5ffdaa5b, 0x75c2896a, 0x7bcb8461, 0x69d0937c, 0x67d99e77, 0x3daed51e, 0x33a7d815, 0x21bccf08, 0x2fb5c203, 0x058ae132, 0x0b83ec39, 0x1998fb24, 0x1791f62f, 0x764dd68d, 0x7844db86, 0x6a5fcc9b, 0x6456c190, 0x4e69e2a1, 0x4060efaa, 0x527bf8b7, 0x5c72f5bc, 0x0605bed5, 0x080cb3de, 0x1a17a4c3, 0x141ea9c8, 0x3e218af9, 0x302887f2, 0x223390ef, 0x2c3a9de4, 0x96dd063d, 0x98d40b36, 0x8acf1c2b, 0x84c61120, 0xaef93211, 0xa0f03f1a, 0xb2eb2807, 0xbce2250c, 0xe6956e65, 0xe89c636e, 0xfa877473, 0xf48e7978, 0xdeb15a49, 0xd0b85742, 0xc2a3405f, 0xccaa4d54, 0x41ecdaf7, 0x4fe5d7fc, 0x5dfec0e1, 0x53f7cdea, 0x79c8eedb, 0x77c1e3d0, 0x65daf4cd, 0x6bd3f9c6, 0x31a4b2af, 0x3fadbfa4, 0x2db6a8b9, 0x23bfa5b2, 0x09808683, 0x07898b88, 0x15929c95, 0x1b9b919e, 0xa17c0a47, 0xaf75074c, 0xbd6e1051, 0xb3671d5a, 0x99583e6b, 0x97513360, 0x854a247d, 0x8b432976, 0xd134621f, 0xdf3d6f14, 0xcd267809, 0xc32f7502, 0xe9105633, 0xe7195b38, 0xf5024c25, 0xfb0b412e, 0x9ad7618c, 0x94de6c87, 0x86c57b9a, 0x88cc7691, 0xa2f355a0, 0xacfa58ab, 0xbee14fb6, 0xb0e842bd, 0xea9f09d4, 0xe49604df, 0xf68d13c2, 0xf8841ec9, 0xd2bb3df8, 0xdcb230f3, 0xcea927ee, 0xc0a02ae5, 0x7a47b13c, 0x744ebc37, 0x6655ab2a, 0x685ca621, 0x42638510, 0x4c6a881b, 0x5e719f06, 0x5078920d, 0x0a0fd964, 0x0406d46f, 0x161dc372, 0x1814ce79, 0x322bed48, 0x3c22e043, 0x2e39f75e, 0x2030fa55, 0xec9ab701, 0xe293ba0a, 0xf088ad17, 0xfe81a01c, 0xd4be832d, 0xdab78e26, 0xc8ac993b, 0xc6a59430, 0x9cd2df59, 0x92dbd252, 0x80c0c54f, 0x8ec9c844, 0xa4f6eb75, 0xaaffe67e, 0xb8e4f163, 0xb6edfc68, 0x0c0a67b1, 0x02036aba, 0x10187da7, 0x1e1170ac, 0x342e539d, 0x3a275e96, 0x283c498b, 0x26354480, 0x7c420fe9, 0x724b02e2, 0x605015ff, 0x6e5918f4, 0x44663bc5, 0x4a6f36ce, 0x587421d3, 0x567d2cd8, 0x37a10c7a, 0x39a80171, 0x2bb3166c, 0x25ba1b67, 0x0f853856, 0x018c355d, 0x13972240, 0x1d9e2f4b, 0x47e96422, 0x49e06929, 0x5bfb7e34, 0x55f2733f, 0x7fcd500e, 0x71c45d05, 0x63df4a18, 0x6dd64713, 0xd731dcca, 0xd938d1c1, 0xcb23c6dc, 0xc52acbd7, 0xef15e8e6, 0xe11ce5ed, 0xf307f2f0, 0xfd0efffb, 0xa779b492, 0xa970b999, 0xbb6bae84, 0xb562a38f, 0x9f5d80be, 0x91548db5, 0x834f9aa8, 0x8d4697a3]);
-  function expandKey256(cipherKey) {
-    var b = 240,
-        result = new Uint8Array(b);
-    var r = 1;
+      data = data.subarray(16);
+    }
+    this.buffer = new Uint8Array(16);
+    this.bufferLength = 0;
+    this.decryptBlock = this._decryptBlock2;
+    return this.decryptBlock(data, finalize);
+  }
+  encrypt(data, iv) {
+    let sourceLength = data.length;
+    let buffer = this.buffer,
+        bufferLength = this.bufferPosition;
+    let result = [];
+    if (!iv) {
+      iv = new Uint8Array(16);
+    }
+    for (let i = 0; i < sourceLength; ++i) {
+      buffer[bufferLength] = data[i];
+      ++bufferLength;
+      if (bufferLength < 16) {
+        continue;
+      }
+      for (let j = 0; j < 16; ++j) {
+        buffer[j] ^= iv[j];
+      }
+      let cipher = this._encrypt(buffer, this._key);
+      iv = cipher;
+      result.push(cipher);
+      buffer = new Uint8Array(16);
+      bufferLength = 0;
+    }
+    this.buffer = buffer;
+    this.bufferLength = bufferLength;
+    this.iv = iv;
+    if (result.length === 0) {
+      return new Uint8Array(0);
+    }
+    let outputLength = 16 * result.length;
+    let output = new Uint8Array(outputLength);
+    for (let i = 0, j = 0, ii = result.length; i < ii; ++i, j += 16) {
+      output.set(result[i], j);
+    }
+    return output;
+  }
+}
+class AES128Cipher extends AESBaseCipher {
+  constructor(key) {
+    super();
+    this._cyclesOfRepetition = 10;
+    this._keySize = 160;
+    this._rcon = new Uint8Array([0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d]);
+    this._key = this._expandKey(key);
+  }
+  _expandKey(cipherKey) {
+    const b = 176;
+    const s = this._s;
+    const rcon = this._rcon;
+    let result = new Uint8Array(b);
     result.set(cipherKey);
-    for (var j = 32, i = 1; j < b; ++i) {
-      var t1, t2, t3, t4;
+    for (let j = 16, i = 1; j < b; ++i) {
+      let t1 = result[j - 3];
+      let t2 = result[j - 2];
+      let t3 = result[j - 1];
+      let t4 = result[j - 4];
+      t1 = s[t1];
+      t2 = s[t2];
+      t3 = s[t3];
+      t4 = s[t4];
+      t1 = t1 ^ rcon[i];
+      for (let n = 0; n < 4; ++n) {
+        result[j] = t1 ^= result[j - 16];
+        j++;
+        result[j] = t2 ^= result[j - 16];
+        j++;
+        result[j] = t3 ^= result[j - 16];
+        j++;
+        result[j] = t4 ^= result[j - 16];
+        j++;
+      }
+    }
+    return result;
+  }
+}
+class AES256Cipher extends AESBaseCipher {
+  constructor(key) {
+    super();
+    this._cyclesOfRepetition = 14;
+    this._keySize = 224;
+    this._key = this._expandKey(key);
+  }
+  _expandKey(cipherKey) {
+    const b = 240;
+    const s = this._s;
+    let result = new Uint8Array(b);
+    result.set(cipherKey);
+    let r = 1;
+    let t1, t2, t3, t4;
+    for (let j = 32, i = 1; j < b; ++i) {
       if (j % 32 === 16) {
         t1 = s[t1];
         t2 = s[t2];
         t3 = s[t3];
         t4 = s[t4];
       } else if (j % 32 === 0) {
         t1 = result[j - 3];
         t2 = result[j - 2];
@@ -15379,290 +15385,30 @@ var AES256Cipher = function AES256Cipher
         t2 = s[t2];
         t3 = s[t3];
         t4 = s[t4];
         t1 = t1 ^ r;
         if ((r <<= 1) >= 256) {
           r = (r ^ 0x1b) & 0xFF;
         }
       }
-      for (var n = 0; n < 4; ++n) {
+      for (let n = 0; n < 4; ++n) {
         result[j] = t1 ^= result[j - 32];
         j++;
         result[j] = t2 ^= result[j - 32];
         j++;
         result[j] = t3 ^= result[j - 32];
         j++;
         result[j] = t4 ^= result[j - 32];
         j++;
       }
     }
     return result;
   }
-  function decrypt256(input, key) {
-    var state = new Uint8Array(16);
-    state.set(input);
-    var i, j, k;
-    var t, u, v;
-    for (j = 0, k = 224; j < 16; ++j, ++k) {
-      state[j] ^= key[k];
-    }
-    for (i = 13; i >= 1; --i) {
-      t = state[13];
-      state[13] = state[9];
-      state[9] = state[5];
-      state[5] = state[1];
-      state[1] = t;
-      t = state[14];
-      u = state[10];
-      state[14] = state[6];
-      state[10] = state[2];
-      state[6] = t;
-      state[2] = u;
-      t = state[15];
-      u = state[11];
-      v = state[7];
-      state[15] = state[3];
-      state[11] = t;
-      state[7] = u;
-      state[3] = v;
-      for (j = 0; j < 16; ++j) {
-        state[j] = inv_s[state[j]];
-      }
-      for (j = 0, k = i * 16; j < 16; ++j, ++k) {
-        state[j] ^= key[k];
-      }
-      for (j = 0; j < 16; j += 4) {
-        var s0 = mix[state[j]],
-            s1 = mix[state[j + 1]],
-            s2 = mix[state[j + 2]],
-            s3 = mix[state[j + 3]];
-        t = s0 ^ s1 >>> 8 ^ s1 << 24 ^ s2 >>> 16 ^ s2 << 16 ^ s3 >>> 24 ^ s3 << 8;
-        state[j] = t >>> 24 & 0xFF;
-        state[j + 1] = t >> 16 & 0xFF;
-        state[j + 2] = t >> 8 & 0xFF;
-        state[j + 3] = t & 0xFF;
-      }
-    }
-    t = state[13];
-    state[13] = state[9];
-    state[9] = state[5];
-    state[5] = state[1];
-    state[1] = t;
-    t = state[14];
-    u = state[10];
-    state[14] = state[6];
-    state[10] = state[2];
-    state[6] = t;
-    state[2] = u;
-    t = state[15];
-    u = state[11];
-    v = state[7];
-    state[15] = state[3];
-    state[11] = t;
-    state[7] = u;
-    state[3] = v;
-    for (j = 0; j < 16; ++j) {
-      state[j] = inv_s[state[j]];
-      state[j] ^= key[j];
-    }
-    return state;
-  }
-  function encrypt256(input, key) {
-    var t, u, v, i, j, k;
-    var state = new Uint8Array(16);
-    state.set(input);
-    for (j = 0; j < 16; ++j) {
-      state[j] ^= key[j];
-    }
-    for (i = 1; i < 14; i++) {
-      for (j = 0; j < 16; ++j) {
-        state[j] = s[state[j]];
-      }
-      v = state[1];
-      state[1] = state[5];
-      state[5] = state[9];
-      state[9] = state[13];
-      state[13] = v;
-      v = state[2];
-      u = state[6];
-      state[2] = state[10];
-      state[6] = state[14];
-      state[10] = v;
-      state[14] = u;
-      v = state[3];
-      u = state[7];
-      t = state[11];
-      state[3] = state[15];
-      state[7] = v;
-      state[11] = u;
-      state[15] = t;
-      for (j = 0; j < 16; j += 4) {
-        var s0 = state[j + 0],
-            s1 = state[j + 1];
-        var s2 = state[j + 2],
-            s3 = state[j + 3];
-        t = s0 ^ s1 ^ s2 ^ s3;
-        state[j + 0] ^= t ^ mixCol[s0 ^ s1];
-        state[j + 1] ^= t ^ mixCol[s1 ^ s2];
-        state[j + 2] ^= t ^ mixCol[s2 ^ s3];
-        state[j + 3] ^= t ^ mixCol[s3 ^ s0];
-      }
-      for (j = 0, k = i * 16; j < 16; ++j, ++k) {
-        state[j] ^= key[k];
-      }
-    }
-    for (j = 0; j < 16; ++j) {
-      state[j] = s[state[j]];
-    }
-    v = state[1];
-    state[1] = state[5];
-    state[5] = state[9];
-    state[9] = state[13];
-    state[13] = v;
-    v = state[2];
-    u = state[6];
-    state[2] = state[10];
-    state[6] = state[14];
-    state[10] = v;
-    state[14] = u;
-    v = state[3];
-    u = state[7];
-    t = state[11];
-    state[3] = state[15];
-    state[7] = v;
-    state[11] = u;
-    state[15] = t;
-    for (j = 0, k = 224; j < 16; ++j, ++k) {
-      state[j] ^= key[k];
-    }
-    return state;
-  }
-  function AES256Cipher(key) {
-    this.key = expandKey256(key);
-    this.buffer = new Uint8Array(16);
-    this.bufferPosition = 0;
-  }
-  function decryptBlock2(data, finalize) {
-    var i,
-        j,
-        ii,
-        sourceLength = data.length,
-        buffer = this.buffer,
-        bufferLength = this.bufferPosition,
-        result = [],
-        iv = this.iv;
-    for (i = 0; i < sourceLength; ++i) {
-      buffer[bufferLength] = data[i];
-      ++bufferLength;
-      if (bufferLength < 16) {
-        continue;
-      }
-      var plain = decrypt256(buffer, this.key);
-      for (j = 0; j < 16; ++j) {
-        plain[j] ^= iv[j];
-      }
-      iv = buffer;
-      result.push(plain);
-      buffer = new Uint8Array(16);
-      bufferLength = 0;
-    }
-    this.buffer = buffer;
-    this.bufferLength = bufferLength;
-    this.iv = iv;
-    if (result.length === 0) {
-      return new Uint8Array([]);
-    }
-    var outputLength = 16 * result.length;
-    if (finalize) {
-      var lastBlock = result[result.length - 1];
-      var psLen = lastBlock[15];
-      if (psLen <= 16) {
-        for (i = 15, ii = 16 - psLen; i >= ii; --i) {
-          if (lastBlock[i] !== psLen) {
-            psLen = 0;
-            break;
-          }
-        }
-        outputLength -= psLen;
-        result[result.length - 1] = lastBlock.subarray(0, 16 - psLen);
-      }
-    }
-    var output = new Uint8Array(outputLength);
-    for (i = 0, j = 0, ii = result.length; i < ii; ++i, j += 16) {
-      output.set(result[i], j);
-    }
-    return output;
-  }
-  AES256Cipher.prototype = {
-    decryptBlock: function AES256Cipher_decryptBlock(data, finalize, iv) {
-      var i,
-          sourceLength = data.length;
-      var buffer = this.buffer,
-          bufferLength = this.bufferPosition;
-      if (iv) {
-        this.iv = iv;
-      } else {
-        for (i = 0; bufferLength < 16 && i < sourceLength; ++i, ++bufferLength) {
-          buffer[bufferLength] = data[i];
-        }
-        if (bufferLength < 16) {
-          this.bufferLength = bufferLength;
-          return new Uint8Array([]);
-        }
-        this.iv = buffer;
-        data = data.subarray(16);
-      }
-      this.buffer = new Uint8Array(16);
-      this.bufferLength = 0;
-      this.decryptBlock = decryptBlock2;
-      return this.decryptBlock(data, finalize);
-    },
-    encrypt: function AES256Cipher_encrypt(data, iv) {
-      var i,
-          j,
-          ii,
-          sourceLength = data.length,
-          buffer = this.buffer,
-          bufferLength = this.bufferPosition,
-          result = [];
-      if (!iv) {
-        iv = new Uint8Array(16);
-      }
-      for (i = 0; i < sourceLength; ++i) {
-        buffer[bufferLength] = data[i];
-        ++bufferLength;
-        if (bufferLength < 16) {
-          continue;
-        }
-        for (j = 0; j < 16; ++j) {
-          buffer[j] ^= iv[j];
-        }
-        var cipher = encrypt256(buffer, this.key);
-        this.iv = cipher;
-        result.push(cipher);
-        buffer = new Uint8Array(16);
-        bufferLength = 0;
-      }
-      this.buffer = buffer;
-      this.bufferLength = bufferLength;
-      this.iv = iv;
-      if (result.length === 0) {
-        return new Uint8Array([]);
-      }
-      var outputLength = 16 * result.length;
-      var output = new Uint8Array(outputLength);
-      for (i = 0, j = 0, ii = result.length; i < ii; ++i, j += 16) {
-        output.set(result[i], j);
-      }
-      return output;
-    }
-  };
-  return AES256Cipher;
-}();
+}
 var PDF17 = function PDF17Closure() {
   function compareByteArrays(array1, array2) {
     if (array1.length !== array2.length) {
       return false;
     }
     for (var i = 0; i < array1.length; i++) {
       if (array1[i] !== array2[i]) {
         return false;
@@ -21314,18 +21060,18 @@ exports.PostScriptCompiler = PostScriptC
 
 /***/ }),
 /* 19 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
 
 "use strict";
 
 
-var pdfjsVersion = '2.0.303';
-var pdfjsBuild = '55e3f97a';
+var pdfjsVersion = '2.0.332';
+var pdfjsBuild = '6b7e2cbc';
 var pdfjsCoreWorker = __w_pdfjs_require__(20);
 exports.WorkerMessageHandler = pdfjsCoreWorker.WorkerMessageHandler;
 
 /***/ }),
 /* 20 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
 
 "use strict";
@@ -21516,17 +21262,17 @@ var WorkerMessageHandler = {
     });
   },
   createDocumentHandler(docParams, port) {
     var pdfManager;
     var terminated = false;
     var cancelXHRs = null;
     var WorkerTasks = [];
     let apiVersion = docParams.apiVersion;
-    let workerVersion = '2.0.303';
+    let workerVersion = '2.0.332';
     if (apiVersion !== null && apiVersion !== workerVersion) {
       throw new Error(`The API version "${apiVersion}" does not match ` + `the Worker version "${workerVersion}".`);
     }
     var docId = docParams.docId;
     var docBaseUrl = docParams.docBaseUrl;
     var workerHandlerName = docParams.docId + '_worker';
     var handler = new _util.MessageHandler(workerHandlerName, docId, port);
     handler.postMessageTransfers = docParams.postMessageTransfers;
@@ -27875,32 +27621,32 @@ var JpegImage = function JpegImageClosur
             }
           }
           mcu++;
         }
       }
       bitsCount = 0;
       fileMarker = findNextFileMarker(data, offset);
       if (fileMarker && fileMarker.invalid) {
-        (0, _util.warn)('decodeScan - unexpected MCU data, next marker is: ' + fileMarker.invalid);
+        (0, _util.warn)('decodeScan - unexpected MCU data, current marker is: ' + fileMarker.invalid);
         offset = fileMarker.offset;
       }
       var marker = fileMarker && fileMarker.marker;
       if (!marker || marker <= 0xFF00) {
         throw new JpegError('marker was not found');
       }
       if (marker >= 0xFFD0 && marker <= 0xFFD7) {
         offset += 2;
       } else {
         break;
       }
     }
     fileMarker = findNextFileMarker(data, offset);
     if (fileMarker && fileMarker.invalid) {
-      (0, _util.warn)('decodeScan - unexpected Scan data, next marker is: ' + fileMarker.invalid);
+      (0, _util.warn)('decodeScan - unexpected Scan data, current marker is: ' + fileMarker.invalid);
       offset = fileMarker.offset;
     }
     return offset - startOffset;
   }
   function quantizeAndInverse(component, blockBufferOffset, p) {
     var qt = component.quantizationTable,
         blockData = component.blockData;
     var v0, v1, v2, v3, v4, v5, v6, v7;
@@ -28056,21 +27802,21 @@ var JpegImage = function JpegImageClosur
     for (var blockRow = 0; blockRow < blocksPerColumn; blockRow++) {
       for (var blockCol = 0; blockCol < blocksPerLine; blockCol++) {
         var offset = getBlockBufferOffset(component, blockRow, blockCol);
         quantizeAndInverse(component, offset, computationBuffer);
       }
     }
     return component.blockData;
   }
-  function findNextFileMarker(data, currentPos, startPos) {
+  function findNextFileMarker(data, currentPos, startPos = currentPos) {
     function peekUint16(pos) {
       return data[pos] << 8 | data[pos + 1];
     }
-    var maxPos = data.length - 1;
+    const maxPos = data.length - 1;
     var newPos = startPos < currentPos ? startPos : currentPos;
     if (currentPos >= maxPos) {
       return null;
     }
     var currentMarker = peekUint16(currentPos);
     if (currentMarker >= 0xFFC0 && currentMarker <= 0xFFFE) {
       return {
         invalid: null,
@@ -28098,17 +27844,17 @@ var JpegImage = function JpegImageClosur
         offset += 2;
         return value;
       }
       function readDataBlock() {
         var length = readUint16();
         var endOffset = offset + length - 2;
         var fileMarker = findNextFileMarker(data, endOffset, offset);
         if (fileMarker && fileMarker.invalid) {
-          (0, _util.warn)('readDataBlock - incorrect length, next marker is: ' + fileMarker.invalid);
+          (0, _util.warn)('readDataBlock - incorrect length, current marker is: ' + fileMarker.invalid);
           endOffset = fileMarker.offset;
         }
         var array = data.subarray(offset, endOffset);
         offset += array.length;
         return array;
       }
       function prepareComponents(frame) {
         var mcusPerLine = Math.ceil(frame.samplesPerLine / 8 / frame.maxH);
@@ -28298,16 +28044,22 @@ var JpegImage = function JpegImageClosur
               offset--;
             }
             break;
           default:
             if (data[offset - 3] === 0xFF && data[offset - 2] >= 0xC0 && data[offset - 2] <= 0xFE) {
               offset -= 3;
               break;
             }
+            let nextFileMarker = findNextFileMarker(data, offset - 2);
+            if (nextFileMarker && nextFileMarker.invalid) {
+              (0, _util.warn)('JpegImage.parse - unexpected data, current marker is: ' + nextFileMarker.invalid);
+              offset = nextFileMarker.offset;
+              break;
+            }
             throw new JpegError('unknown marker ' + fileMarker.toString(16));
         }
         fileMarker = readUint16();
       }
       this.width = frame.samplesPerLine;
       this.height = frame.scanLines;
       this.jfif = jfif;
       this.adobe = adobe;
--- a/browser/extensions/pdfjs/content/web/viewer.js
+++ b/browser/extensions/pdfjs/content/web/viewer.js
@@ -1023,18 +1023,18 @@ let PDFViewerApplication = {
     })]).catch(function (reason) {});
   },
   _parseHashParameters() {
     let { appConfig, viewerPrefs } = this;
     let waitOn = [];
     if (viewerPrefs['pdfBugEnabled']) {
       let hash = document.location.hash.substring(1);
       let hashParams = (0, _ui_utils.parseQueryString)(hash);
-      if ('disableworker' in hashParams) {
-        _pdfjsLib.PDFJS.disableWorker = hashParams['disableworker'] === 'true';
+      if ('disableworker' in hashParams && hashParams['disableworker'] === 'true') {
+        waitOn.push(loadFakeWorker());
       }
       if ('disablerange' in hashParams) {
         _pdfjsLib.PDFJS.disableRange = hashParams['disablerange'] === 'true';
       }
       if ('disablestream' in hashParams) {
         _pdfjsLib.PDFJS.disableStream = hashParams['disablestream'] === 'true';
       }
       if ('disableautofetch' in hashParams) {
@@ -1855,16 +1855,29 @@ let PDFViewerApplication = {
     _boundEvents.windowResize = null;
     _boundEvents.windowHashChange = null;
     _boundEvents.windowBeforePrint = null;
     _boundEvents.windowAfterPrint = null;
   }
 };
 let validateFileURL;
 ;
+function loadFakeWorker() {
+  return new Promise(function (resolve, reject) {
+    let script = document.createElement('script');
+    script.src = _pdfjsLib.PDFWorker.getWorkerSrc();
+    script.onload = function () {
+      resolve();
+    };
+    script.onerror = function () {
+      reject(new Error(`Cannot load fake worker at: ${script.src}`));
+    };
+    (document.head || document.documentElement).appendChild(script);
+  });
+}
 function loadAndEnablePDFBug(enabledTabs) {
   return new Promise(function (resolve, reject) {
     let appConfig = PDFViewerApplication.appConfig;
     let script = document.createElement('script');
     script.src = appConfig.debuggerScriptPath;
     script.onload = function () {
       PDFBug.enable(enabledTabs);
       PDFBug.init({
--- a/build/build-clang/build-clang.py
+++ b/build/build-clang/build-clang.py
@@ -184,17 +184,17 @@ def build_one_stage(cc, cxx, asm, ld, ar
                   "-DCMAKE_LINKER=%s" % slashify_path(ld[0]),
                   "-DCMAKE_AR=%s" % slashify_path(ar),
                   "-DCMAKE_C_FLAGS=%s" % ' '.join(cc[1:]),
                   "-DCMAKE_CXX_FLAGS=%s" % ' '.join(cxx[1:]),
                   "-DCMAKE_ASM_FLAGS=%s" % ' '.join(asm[1:]),
                   "-DCMAKE_EXE_LINKER_FLAGS=%s" % ' '.join(ld[1:]),
                   "-DCMAKE_SHARED_LINKER_FLAGS=%s" % ' '.join(ld[1:]),
                   "-DCMAKE_BUILD_TYPE=%s" % build_type,
-                  "-DLLVM_TARGETS_TO_BUILD=X86;ARM",
+                  "-DLLVM_TARGETS_TO_BUILD=X86;ARM;AArch64",
                   "-DLLVM_ENABLE_ASSERTIONS=%s" % ("ON" if assertions else "OFF"),
                   "-DPYTHON_EXECUTABLE=%s" % slashify_path(python_path),
                   "-DCMAKE_INSTALL_PREFIX=%s" % inst_dir,
                   "-DLLVM_TOOL_LIBCXX_BUILD=%s" % ("ON" if build_libcxx else "OFF"),
                   "-DLIBCXX_LIBCPPABI_VERSION=\"\"",
                   src_dir]
     if is_windows():
         cmake_args.insert(-1, "-DLLVM_EXPORT_SYMBOLS_FOR_PLUGINS=ON")
--- a/caps/nsJSPrincipals.cpp
+++ b/caps/nsJSPrincipals.cpp
@@ -10,17 +10,17 @@
 #include "nsJSPrincipals.h"
 #include "plstr.h"
 #include "nsCOMPtr.h"
 #include "nsIServiceManager.h"
 #include "nsMemory.h"
 #include "nsStringBuffer.h"
 
 #include "mozilla/dom/StructuredCloneTags.h"
-// for mozilla::dom::workers::kJSPrincipalsDebugToken
+// for mozilla::dom::workerinternals::kJSPrincipalsDebugToken
 #include "mozilla/dom/workerinternals/JSSettings.h"
 #include "mozilla/ipc/BackgroundUtils.h"
 
 using namespace mozilla;
 using namespace mozilla::ipc;
 
 NS_IMETHODIMP_(MozExternalRefCountType)
 nsJSPrincipals::AddRef()
--- a/caps/nsScriptSecurityManager.cpp
+++ b/caps/nsScriptSecurityManager.cpp
@@ -1204,17 +1204,17 @@ nsScriptSecurityManager::doGetObjectPrin
 }
 
 NS_IMETHODIMP
 nsScriptSecurityManager::CanCreateWrapper(JSContext *cx,
                                           const nsIID &aIID,
                                           nsISupports *aObj,
                                           nsIClassInfo *aClassInfo)
 {
-// XXX Special case for nsIXPCException ?
+// XXX Special case for Exception ?
 
     uint32_t flags;
     if (aClassInfo && NS_SUCCEEDED(aClassInfo->GetFlags(&flags)) &&
         (flags & nsIClassInfo::DOM_OBJECT)) {
         return NS_OK;
     }
 
     // We give remote-XUL whitelisted domains a free pass here. See bug 932906.
--- a/devtools/client/inspector/animation/components/AnimationTarget.js
+++ b/devtools/client/inspector/animation/components/AnimationTarget.js
@@ -2,16 +2,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/. */
 
 "use strict";
 
 const { PureComponent } = require("devtools/client/shared/vendor/react");
 const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
 const dom = require("devtools/client/shared/vendor/react-dom-factories");
+const { translateNodeFrontToGrip } = require("devtools/client/inspector/shared/utils");
 
 const { REPS, MODE } = require("devtools/client/shared/components/reps/reps");
 const { Rep } = REPS;
 const ElementNode = REPS.ElementNode;
 
 class AnimationTarget extends PureComponent {
   static get propTypes() {
     return {
@@ -41,46 +42,16 @@ class AnimationTarget extends PureCompon
       this.updateNodeFront(nextProps.animation);
     }
   }
 
   shouldComponentUpdate(nextProps, nextState) {
     return this.state.nodeFront !== nextState.nodeFront;
   }
 
-  /**
-   * While waiting for a reps fix in https://github.com/devtools-html/reps/issues/92,
-   * translate nodeFront to a grip-like object that can be used with an ElementNode rep.
-   *
-   * @params  {NodeFront} nodeFront
-   *          The NodeFront for which we want to create a grip-like object.
-   * @returns {Object} a grip-like object that can be used with Reps.
-   */
-  translateNodeFrontToGrip(nodeFront) {
-    let { attributes } = nodeFront;
-
-    // The main difference between NodeFront and grips is that attributes are treated as
-    // a map in grips and as an array in NodeFronts.
-    let attributesMap = {};
-    for (let {name, value} of attributes) {
-      attributesMap[name] = value;
-    }
-
-    return {
-      actor: nodeFront.actorID,
-      preview: {
-        attributes: attributesMap,
-        attributesLength: attributes.length,
-        isConnected: true,
-        nodeName: nodeFront.nodeName.toLowerCase(),
-        nodeType: nodeFront.nodeType,
-      }
-    };
-  }
-
   async updateNodeFront(animation) {
     const { emitEventForTest, getNodeFromActor } = this.props;
 
     // Try and get it from the playerFront directly.
     let nodeFront = animation.animationTargetNodeFront;
 
     // Next, get it from the walkerActor if it wasn't found.
     if (!nodeFront) {
@@ -119,17 +90,17 @@ class AnimationTarget extends PureCompon
     return dom.div(
       {
         className: "animation-target"
       },
       Rep(
         {
           defaultRep: ElementNode,
           mode: MODE.TINY,
-          object: this.translateNodeFrontToGrip(nodeFront),
+          object: translateNodeFrontToGrip(nodeFront),
           onDOMNodeMouseOut: () => onHideBoxModelHighlighter(),
           onDOMNodeMouseOver: () => onShowBoxModelHighlighterForNode(nodeFront),
           onInspectIconClick: () => setSelectedNode(nodeFront, "animation-panel"),
         }
       )
     );
   }
 }
--- a/devtools/client/inspector/boxmodel/components/ComputedProperty.js
+++ b/devtools/client/inspector/boxmodel/components/ComputedProperty.js
@@ -2,16 +2,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/. */
 
 "use strict";
 
 const { PureComponent } = require("devtools/client/shared/vendor/react");
 const dom = require("devtools/client/shared/vendor/react-dom-factories");
 const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
+const { translateNodeFrontToGrip } = require("devtools/client/inspector/shared/utils");
 
 const { REPS, MODE } = require("devtools/client/shared/components/reps/reps");
 const { Rep } = REPS;
 
 class ComputedProperty extends PureComponent {
   static get propTypes() {
     return {
       name: PropTypes.string.isRequired,
@@ -22,17 +23,16 @@ class ComputedProperty extends PureCompo
       onHideBoxModelHighlighter: PropTypes.func.isRequired,
       onShowBoxModelHighlighterForNode: PropTypes.func.isRequired,
     };
   }
 
   constructor(props) {
     super(props);
     this.renderReferenceElementPreview = this.renderReferenceElementPreview.bind(this);
-    this.translateNodeFrontToGrip = this.translateNodeFrontToGrip.bind(this);
     this.onFocus = this.onFocus.bind(this);
   }
 
   renderReferenceElementPreview() {
     let {
       referenceElement,
       referenceElementType,
       setSelectedNode,
@@ -47,57 +47,24 @@ class ComputedProperty extends PureCompo
     return dom.div(
       {
         className: "reference-element"
       },
       dom.span({ className: "reference-element-type" }, referenceElementType),
       Rep({
         defaultRep: referenceElement,
         mode: MODE.TINY,
-        object: this.translateNodeFrontToGrip(referenceElement),
+        object: translateNodeFrontToGrip(referenceElement),
         onInspectIconClick: () => setSelectedNode(referenceElement, "box-model"),
         onDOMNodeMouseOver: () => onShowBoxModelHighlighterForNode(referenceElement),
         onDOMNodeMouseOut: () => onHideBoxModelHighlighter(),
       })
     );
   }
 
-  /**
-   * While waiting for a reps fix in https://github.com/devtools-html/reps/issues/92,
-   * translate nodeFront to a grip-like object that can be used with an ElementNode rep.
-   *
-   * @param  {NodeFront} nodeFront
-   *         The NodeFront for which we want to create a grip-like object.
-   * @return {Object} a grip-like object that can be used with Reps.
-   */
-  translateNodeFrontToGrip(nodeFront) {
-    let {
-      attributes
-    } = nodeFront;
-
-    // The main difference between NodeFront and grips is that attributes are treated as
-    // a map in grips and as an array in NodeFronts.
-    let attributesMap = {};
-    for (let { name, value } of attributes) {
-      attributesMap[name] = value;
-    }
-
-    return {
-      actor: nodeFront.actorID,
-      preview: {
-        attributes: attributesMap,
-        attributesLength: attributes.length,
-        // nodeName is already lowerCased in Node grips
-        nodeName: nodeFront.nodeName.toLowerCase(),
-        nodeType: nodeFront.nodeType,
-        isConnected: true,
-      }
-    };
-  }
-
   onFocus() {
     this.container.focus();
   }
 
   render() {
     const { name, value } = this.props;
 
     return dom.div(
--- a/devtools/client/inspector/grids/components/GridItem.js
+++ b/devtools/client/inspector/grids/components/GridItem.js
@@ -3,16 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const { PureComponent } = require("devtools/client/shared/vendor/react");
 const dom = require("devtools/client/shared/vendor/react-dom-factories");
 const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
 const { findDOMNode } = require("devtools/client/shared/vendor/react-dom");
+const { translateNodeFrontToGrip } = require("devtools/client/inspector/shared/utils");
 
 // Reps
 const { REPS, MODE } = require("devtools/client/shared/components/reps/reps");
 const { Rep } = REPS;
 const ElementNode = REPS.ElementNode;
 
 const Types = require("../types");
 
@@ -27,17 +28,16 @@ class GridItem extends PureComponent {
       onShowBoxModelHighlighterForNode: PropTypes.func.isRequired,
       onToggleGridHighlighter: PropTypes.func.isRequired,
     };
   }
 
   constructor(props) {
     super(props);
     this.setGridColor = this.setGridColor.bind(this);
-    this.translateNodeFrontToGrip = this.translateNodeFrontToGrip.bind(this);
     this.onGridCheckboxClick = this.onGridCheckboxClick.bind(this);
     this.onGridInspectIconClick = this.onGridInspectIconClick.bind(this);
   }
 
   componentDidMount() {
     let swatchEl = findDOMNode(this).querySelector(".grid-color-swatch");
     let tooltip = this.props.getSwatchColorPickerTooltip();
 
@@ -60,48 +60,16 @@ class GridItem extends PureComponent {
     tooltip.removeSwatch(swatchEl);
   }
 
   setGridColor() {
     let color = findDOMNode(this).querySelector(".grid-color-value").textContent;
     this.props.onSetGridOverlayColor(this.props.grid.nodeFront, color);
   }
 
-  /**
-   * While waiting for a reps fix in https://github.com/devtools-html/reps/issues/92,
-   * translate nodeFront to a grip-like object that can be used with an ElementNode rep.
-   *
-   * @params  {NodeFront} nodeFront
-   *          The NodeFront for which we want to create a grip-like object.
-   * @returns {Object} a grip-like object that can be used with Reps.
-   */
-  translateNodeFrontToGrip(nodeFront) {
-    let { attributes } = nodeFront;
-
-    // The main difference between NodeFront and grips is that attributes are treated as
-    // a map in grips and as an array in NodeFronts.
-    let attributesMap = {};
-    for (let {name, value} of attributes) {
-      attributesMap[name] = value;
-    }
-
-    return {
-      actor: nodeFront.actorID,
-      preview: {
-        attributes: attributesMap,
-        attributesLength: attributes.length,
-        // All the grid containers are assumed to be in the DOM tree.
-        isConnected: true,
-        // nodeName is already lowerCased in Node grips
-        nodeName: nodeFront.nodeName.toLowerCase(),
-        nodeType: nodeFront.nodeType,
-      }
-    };
-  }
-
   onGridCheckboxClick(e) {
     // If the click was on the svg icon to select the node in the inspector, bail out.
     let originalTarget = e.nativeEvent && e.nativeEvent.explicitOriginalTarget;
     if (originalTarget && originalTarget.namespaceURI === "http://www.w3.org/2000/svg") {
       // We should be able to cancel the click event propagation after the following reps
       // issue is implemented : https://github.com/devtools-html/reps/issues/95 .
       e.preventDefault();
       return;
@@ -140,17 +108,17 @@ class GridItem extends PureComponent {
             value: grid.id,
             onChange: this.onGridCheckboxClick,
           }
         ),
         Rep(
           {
             defaultRep: ElementNode,
             mode: MODE.TINY,
-            object: this.translateNodeFrontToGrip(nodeFront),
+            object: translateNodeFrontToGrip(nodeFront),
             onDOMNodeMouseOut: () => onHideBoxModelHighlighter(),
             onDOMNodeMouseOver: () => onShowBoxModelHighlighterForNode(nodeFront),
             onInspectIconClick: () => this.onGridInspectIconClick(nodeFront),
           }
         )
       ),
       dom.div(
         {
--- a/devtools/client/inspector/shared/utils.js
+++ b/devtools/client/inspector/shared/utils.js
@@ -10,59 +10,16 @@ const {parseDeclarations} = require("dev
 const promise = require("promise");
 const {getCSSLexer} = require("devtools/shared/css/lexer");
 const {KeyCodes} = require("devtools/client/shared/keycodes");
 const {throttle} = require("devtools/shared/throttle");
 
 const HTML_NS = "http://www.w3.org/1999/xhtml";
 
 /**
- * Create a child element with a set of attributes.
- *
- * @param {Element} parent
- *        The parent node.
- * @param {string} tagName
- *        The tag name.
- * @param {object} attributes
- *        A set of attributes to set on the node.
- */
-function createChild(parent, tagName, attributes = {}) {
-  let elt = parent.ownerDocument.createElementNS(HTML_NS, tagName);
-  for (let attr in attributes) {
-    if (attributes.hasOwnProperty(attr)) {
-      if (attr === "textContent") {
-        elt.textContent = attributes[attr];
-      } else if (attr === "child") {
-        elt.appendChild(attributes[attr]);
-      } else {
-        elt.setAttribute(attr, attributes[attr]);
-      }
-    }
-  }
-  parent.appendChild(elt);
-  return elt;
-}
-
-exports.createChild = createChild;
-
-/**
- * Append a text node to an element.
- *
- * @param {Element} parent
- *        The parent node.
- * @param {string} text
- *        The text content for the text node.
- */
-function appendText(parent, text) {
-  parent.appendChild(parent.ownerDocument.createTextNode(text));
-}
-
-exports.appendText = appendText;
-
-/**
  * Called when a character is typed in a value editor.  This decides
  * whether to advance or not, first by checking to see if ";" was
  * typed, and then by lexing the input and seeing whether the ";"
  * would be a terminator at this point.
  *
  * @param {number} keyCode
  *        Key code to be checked.
  * @param {string} aValue
@@ -93,42 +50,114 @@ function advanceValidate(keyCode, value,
       }
       // The ";" is not a terminator in this context.
       break;
     }
   }
   return false;
 }
 
-exports.advanceValidate = advanceValidate;
+/**
+ * Append a text node to an element.
+ *
+ * @param {Element} parent
+ *        The parent node.
+ * @param {string} text
+ *        The text content for the text node.
+ */
+function appendText(parent, text) {
+  parent.appendChild(parent.ownerDocument.createTextNode(text));
+}
 
 /**
  * Event handler that causes a blur on the target if the input has
  * multiple CSS properties as the value.
  */
 function blurOnMultipleProperties(cssProperties) {
   return (e) => {
     setTimeout(() => {
       let props = parseDeclarations(cssProperties.isKnown, e.target.value);
       if (props.length > 1) {
         e.target.blur();
       }
     }, 0);
   };
 }
 
-exports.blurOnMultipleProperties = blurOnMultipleProperties;
+/**
+ * Create a child element with a set of attributes.
+ *
+ * @param {Element} parent
+ *        The parent node.
+ * @param {string} tagName
+ *        The tag name.
+ * @param {object} attributes
+ *        A set of attributes to set on the node.
+ */
+function createChild(parent, tagName, attributes = {}) {
+  let elt = parent.ownerDocument.createElementNS(HTML_NS, tagName);
+  for (let attr in attributes) {
+    if (attributes.hasOwnProperty(attr)) {
+      if (attr === "textContent") {
+        elt.textContent = attributes[attr];
+      } else if (attr === "child") {
+        elt.appendChild(attributes[attr]);
+      } else {
+        elt.setAttribute(attr, attributes[attr]);
+      }
+    }
+  }
+  parent.appendChild(elt);
+  return elt;
+}
 
 /**
  * Log the provided error to the console and return a rejected Promise for
  * this error.
  *
  * @param {Error} error
  *         The error to log
  * @return {Promise} A rejected promise
  */
 function promiseWarn(error) {
   console.error(error);
   return promise.reject(error);
 }
 
+/**
+ * While waiting for a reps fix in https://github.com/devtools-html/reps/issues/92,
+ * translate nodeFront to a grip-like object that can be used with an ElementNode rep.
+ *
+ * @params  {NodeFront} nodeFront
+ *          The NodeFront for which we want to create a grip-like object.
+ * @returns {Object} a grip-like object that can be used with Reps.
+ */
+function translateNodeFrontToGrip(nodeFront) {
+  const { attributes } = nodeFront;
+
+  // The main difference between NodeFront and grips is that attributes are treated as
+  // a map in grips and as an array in NodeFronts.
+  let attributesMap = {};
+  for (let {name, value} of attributes) {
+    attributesMap[name] = value;
+  }
+
+  return {
+    actor: nodeFront.actorID,
+    preview: {
+      attributes: attributesMap,
+      attributesLength: attributes.length,
+      // All the grid containers are assumed to be in the DOM tree.
+      isConnected: true,
+      // nodeName is already lowerCased in Node grips
+      nodeName: nodeFront.nodeName.toLowerCase(),
+      nodeType: nodeFront.nodeType,
+    }
+  };
+}
+
+exports.advanceValidate = advanceValidate;
+exports.appendText = appendText;
+exports.blurOnMultipleProperties = blurOnMultipleProperties;
+exports.createChild = createChild;
 exports.promiseWarn = promiseWarn;
 exports.throttle = throttle;
+exports.translateNodeFrontToGrip = translateNodeFrontToGrip;
--- a/devtools/shared/apps/app-actor-front.js
+++ b/devtools/shared/apps/app-actor-front.js
@@ -50,31 +50,22 @@ function addDirToZip(writer, dir, basePa
       writer.addEntryFile(basePath + file.leafName,
                           Ci.nsIZipWriter.COMPRESSION_DEFAULT,
                           file,
                           true);
     }
   }
 }
 
-/**
- * Convert an XPConnect result code to its name and message.
- * We have to extract them from an exception per bug 637307 comment 5.
- */
 function getResultText(code) {
-  let regexp =
-    /^\[Exception... "(.*)"  nsresult: "0x[0-9a-fA-F]* \((.*)\)"  location: ".*"  data: .*\]$/; // eslint-disable-line
-  let ex = Cc["@mozilla.org/js/xpc/Exception;1"]
-           .createInstance(Ci.nsIXPCException);
-  ex.initialize(null, code, null, null, null, null);
-  let [, message, name] = regexp.exec(ex.toString());
-  return {
-    name,
-    message
-  };
+  /*
+   * If it ever becomes necessary to convert the nsresult to a useful
+   * string here, we'll need an API for that.
+   */
+  return { name: "Error code", message: code + "" };
 }
 
 function zipDirectory(zipFile, dirToArchive) {
   let deferred = defer();
   let writer = Cc["@mozilla.org/zipwriter;1"].createInstance(Ci.nsIZipWriter);
   writer.open(zipFile, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE);
 
   addDirToZip(writer, dirToArchive, "");
--- a/dom/base/DOMException.cpp
+++ b/dom/base/DOMException.cpp
@@ -138,18 +138,17 @@ NS_GetNameAndMessageForDOMNSResult(nsres
 
 namespace mozilla {
 namespace dom {
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Exception)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(Exception)
   NS_INTERFACE_MAP_ENTRY(nsIException)
-  NS_INTERFACE_MAP_ENTRY(nsIXPCException)
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIException)
+  NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(Exception)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(Exception)
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(Exception)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Exception)
@@ -164,35 +163,36 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Exception)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mLocation)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mData)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
   tmp->mThrownJSVal.setNull();
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
-NS_IMPL_CI_INTERFACE_GETTER(Exception, nsIXPCException)
-
 Exception::Exception(const nsACString& aMessage,
                      nsresult aResult,
                      const nsACString& aName,
                      nsIStackFrame *aLocation,
                      nsISupports *aData)
-: mResult(NS_OK),
-  mInitialized(false),
-  mHoldingJSVal(false)
+  : mMessage(aMessage)
+  , mResult(aResult)
+  , mName(aName)
+  , mData(aData)
+  , mHoldingJSVal(false)
 {
-  Initialize(aMessage, aResult, aName, aLocation, aData);
-}
-
-Exception::Exception()
-  : mResult(NS_OK),
-    mInitialized(false),
-    mHoldingJSVal(false)
-{
+  if (aLocation) {
+    mLocation = aLocation;
+  } else {
+    mLocation = GetCurrentJSStack();
+    // it is legal for there to be no active JS stack, if C++ code
+    // is operating on a JS-implemented interface pointer without
+    // having been called in turn by JS.  This happens in the JS
+    // component loader.
+  }
 }
 
 Exception::~Exception()
 {
   if (mHoldingJSVal) {
     MOZ_ASSERT(NS_IsMainThread());
 
     mozilla::DropJSObjects(this);
@@ -223,134 +223,57 @@ Exception::StowJSVal(JS::Value& aVp)
 
   mThrownJSVal = aVp;
   if (!mHoldingJSVal) {
     mozilla::HoldJSObjects(this);
     mHoldingJSVal = true;
   }
 }
 
-NS_IMETHODIMP
-Exception::GetMessageMoz(nsACString& aMessage)
-{
-  NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
-
-  aMessage.Assign(mMessage);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-Exception::GetResult(nsresult* aResult)
+void
+Exception::GetName(nsAString& aName)
 {
-  NS_ENSURE_ARG_POINTER(aResult);
-  NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
-
-  *aResult = mResult;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-Exception::GetName(nsACString& aName)
-{
-  NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
-
   if (!mName.IsEmpty()) {
-    aName.Assign(mName);
+    CopyUTF8toUTF16(mName, aName);
   } else {
     aName.Truncate();
 
     const char* name = nullptr;
     nsXPCException::NameAndFormatForNSResult(mResult, &name, nullptr);
 
     if (name) {
-      aName.Assign(name);
+      CopyUTF8toUTF16(name, aName);
     }
   }
-
-  return NS_OK;
 }
 
-NS_IMETHODIMP
+void
 Exception::GetFilename(JSContext* aCx, nsAString& aFilename)
 {
-  NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
-
   if (mLocation) {
-    return mLocation->GetFilename(aCx, aFilename);
+    mLocation->GetFilename(aCx, aFilename);
+    return;
   }
 
   aFilename.Truncate();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-Exception::GetLineNumber(JSContext* aCx, uint32_t *aLineNumber)
-{
-  NS_ENSURE_ARG_POINTER(aLineNumber);
-  NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
-
-  if (mLocation) {
-    int32_t lineno;
-    nsresult rv = mLocation->GetLineNumber(aCx, &lineno);
-    *aLineNumber = lineno;
-    return rv;
-  }
-
-  *aLineNumber = 0;
-  return NS_OK;
 }
 
-NS_IMETHODIMP
-Exception::GetColumnNumber(uint32_t* aColumnNumber)
-{
-  NS_ENSURE_ARG_POINTER(aColumnNumber);
-  NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
-
-  *aColumnNumber = 0;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-Exception::GetLocation(nsIStackFrame** aLocation)
-{
-  NS_ENSURE_ARG_POINTER(aLocation);
-  NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
-
-  nsCOMPtr<nsIStackFrame> location = mLocation;
-  location.forget(aLocation);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-Exception::GetData(nsISupports** aData)
-{
-  NS_ENSURE_ARG_POINTER(aData);
-  NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
-
-  nsCOMPtr<nsISupports> data = mData;
-  data.forget(aData);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
+void
 Exception::ToString(JSContext* aCx, nsACString& _retval)
 {
-  NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
-
   static const char defaultMsg[] = "<no message>";
   static const char defaultLocation[] = "<unknown>";
   static const char format[] =
 "[Exception... \"%s\"  nsresult: \"0x%" PRIx32 " (%s)\"  location: \"%s\"  data: %s]";
 
   nsCString location;
 
   if (mLocation) {
     // we need to free this if it does not fail
-    nsresult rv = mLocation->ToString(aCx, location);
-    NS_ENSURE_SUCCESS(rv, rv);
+    mLocation->ToString(aCx, location);
   }
 
   if (location.IsEmpty()) {
     location.Assign(defaultLocation);
   }
 
   const char* msg = mMessage.IsEmpty() ? nullptr : mMessage.get();
 
@@ -363,91 +286,41 @@ Exception::ToString(JSContext* aCx, nsAC
     }
     resultName = "<unknown>";
   }
   const char* data = mData ? "yes" : "no";
 
   _retval.Truncate();
   _retval.AppendPrintf(format, msg, static_cast<uint32_t>(mResult), resultName,
                        location.get(), data);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-Exception::Initialize(const nsACString& aMessage, nsresult aResult,
-                      const nsACString& aName, nsIStackFrame *aLocation,
-                      nsISupports *aData)
-{
-  NS_ENSURE_FALSE(mInitialized, NS_ERROR_ALREADY_INITIALIZED);
-
-  mMessage = aMessage;
-  mName = aName;
-  mResult = aResult;
-
-  if (aLocation) {
-    mLocation = aLocation;
-  } else {
-    mLocation = GetCurrentJSStack();
-    // it is legal for there to be no active JS stack, if C++ code
-    // is operating on a JS-implemented interface pointer without
-    // having been called in turn by JS.  This happens in the JS
-    // component loader.
-  }
-
-  mData = aData;
-
-  mInitialized = true;
-  return NS_OK;
 }
 
 JSObject*
 Exception::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
 {
   return ExceptionBinding::Wrap(cx, this, aGivenProto);
 }
 
 void
 Exception::GetMessageMoz(nsString& retval)
 {
-  nsCString str;
-#ifdef DEBUG
-  DebugOnly<nsresult> rv =
-#endif
-  GetMessageMoz(str);
-  MOZ_ASSERT(NS_SUCCEEDED(rv));
-  CopyUTF8toUTF16(str, retval);
+  CopyUTF8toUTF16(mMessage, retval);
 }
 
 uint32_t
 Exception::Result() const
 {
   return (uint32_t)mResult;
 }
 
-void
-Exception::GetName(nsString& retval)
-{
-  nsCString str;
-#ifdef DEBUG
-  DebugOnly<nsresult> rv =
-#endif
-  GetName(str);
-  MOZ_ASSERT(NS_SUCCEEDED(rv));
-  CopyUTF8toUTF16(str, retval);
-}
-
 uint32_t
 Exception::LineNumber(JSContext* aCx) const
 {
   if (mLocation) {
-    int32_t lineno;
-    if (NS_SUCCEEDED(mLocation->GetLineNumber(aCx, &lineno))) {
-      return lineno;
-    }
-    return 0;
+    return mLocation->GetLineNumber(aCx);
   }
 
   return 0;
 }
 
 uint32_t
 Exception::ColumnNumber() const
 {
@@ -456,54 +329,47 @@ Exception::ColumnNumber() const
 
 already_AddRefed<nsIStackFrame>
 Exception::GetLocation() const
 {
   nsCOMPtr<nsIStackFrame> location = mLocation;
   return location.forget();
 }
 
-already_AddRefed<nsISupports>
+nsISupports*
 Exception::GetData() const
 {
-  nsCOMPtr<nsISupports> data = mData;
-  return data.forget();
+  return mData;
 }
 
 void
-Exception::GetStack(JSContext* aCx, nsAString& aStack, ErrorResult& aRv) const
+Exception::GetStack(JSContext* aCx, nsAString& aStack) const
 {
   if (mLocation) {
-    aRv = mLocation->GetFormattedStack(aCx, aStack);
+    mLocation->GetFormattedStack(aCx, aStack);
   }
 }
 
 void
 Exception::Stringify(JSContext* aCx, nsString& retval)
 {
   nsCString str;
-#ifdef DEBUG
-  DebugOnly<nsresult> rv =
-#endif
   ToString(aCx, str);
-  MOZ_ASSERT(NS_SUCCEEDED(rv));
   CopyUTF8toUTF16(str, retval);
 }
 
 NS_IMPL_ADDREF_INHERITED(DOMException, Exception)
 NS_IMPL_RELEASE_INHERITED(DOMException, Exception)
 NS_INTERFACE_MAP_BEGIN(DOMException)
   NS_INTERFACE_MAP_ENTRY(nsIDOMDOMException)
 NS_INTERFACE_MAP_END_INHERITING(Exception)
 
 DOMException::DOMException(nsresult aRv, const nsACString& aMessage,
                            const nsACString& aName, uint16_t aCode)
-  : Exception(EmptyCString(), aRv, EmptyCString(), nullptr, nullptr),
-    mName(aName),
-    mMessage(aMessage),
+  : Exception(aMessage, aRv, aName, nullptr, nullptr),
     mCode(aCode)
 {
 }
 
 NS_IMETHODIMP
 DOMException::GetCode(uint16_t* aCode)
 {
   NS_ENSURE_ARG_POINTER(aCode);
@@ -516,17 +382,17 @@ DOMException::GetCode(uint16_t* aCode)
     if (doc) {
       doc->WarnOnceAbout(nsIDocument::eDOMExceptionCode);
     }
   }
 
   return NS_OK;
 }
 
-NS_IMETHODIMP
+void
 DOMException::ToString(JSContext* aCx, nsACString& aReturn)
 {
   aReturn.Truncate();
 
   static const char defaultMsg[] = "<no message>";
   static const char defaultLocation[] = "<unknown>";
   static const char defaultName[] = "<unknown>";
   static const char format[] =
@@ -538,32 +404,24 @@ DOMException::ToString(JSContext* aCx, n
     location = defaultLocation;
   }
 
   const char* msg = !mMessage.IsEmpty() ? mMessage.get() : defaultMsg;
   const char* resultName = !mName.IsEmpty() ? mName.get() : defaultName;
 
   aReturn.AppendPrintf(format, msg, mCode, static_cast<uint32_t>(mResult), resultName,
                        location.get());
-
-  return NS_OK;
 }
 
 void
 DOMException::GetName(nsString& retval)
 {
   CopyUTF8toUTF16(mName, retval);
 }
 
-void
-DOMException::GetMessageMoz(nsString& retval)
-{
-  CopyUTF8toUTF16(mMessage, retval);
-}
-
 already_AddRefed<DOMException>
 DOMException::Constructor(GlobalObject& /* unused */,
                           const nsAString& aMessage,
                           const Optional<nsAString>& aName,
                           ErrorResult& aError)
 {
   nsresult exceptionResult = NS_OK;
   uint16_t exceptionCode = 0;
--- a/dom/base/DOMException.h
+++ b/dom/base/DOMException.h
@@ -15,17 +15,17 @@
 
 #include <stdint.h>
 #include "jspubtd.h"
 #include "nsCOMPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsID.h"
 #include "nsIDOMDOMException.h"
 #include "nsWrapperCache.h"
-#include "xpcexception.h"
+#include "nsIException.h"
 #include "nsString.h"
 #include "mozilla/dom/BindingDeclarations.h"
 
 class nsIStackFrame;
 
 nsresult
 NS_GetNameAndMessageForDOMNSResult(nsresult aNSResult, nsACString& aName,
                                    nsACString& aMessage,
@@ -37,98 +37,100 @@ class ErrorResult;
 namespace dom {
 
 class GlobalObject;
 
 #define MOZILLA_EXCEPTION_IID \
 { 0x55eda557, 0xeba0, 0x4fe3, \
   { 0xae, 0x2e, 0xf3, 0x94, 0x49, 0x23, 0x62, 0xd6 } }
 
-class Exception : public nsIXPCException,
+class Exception : public nsIException,
                   public nsWrapperCache
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_EXCEPTION_IID)
 
-  NS_DEFINE_STATIC_CID_ACCESSOR(NS_XPCEXCEPTION_CID)
-
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Exception)
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_NSIEXCEPTION
-  NS_DECL_NSIXPCEXCEPTION
+
+  const nsCString& GetMessageMoz() const
+  {
+    return mMessage;
+  }
+  nsresult GetResult() const
+  {
+    return mResult;
+  }
+  // DOMException wants different ToString behavior, so allow it to override.
+  virtual void ToString(JSContext* aCx, nsACString& aReturn);
+
 
   // Cruft used by XPConnect for exceptions originating in JS implemented
   // components.
   bool StealJSVal(JS::Value* aVp);
   void StowJSVal(JS::Value& aVp);
 
   // WebIDL API
   virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
     override;
 
   nsISupports* GetParentObject() const { return nullptr; }
 
   void GetMessageMoz(nsString& retval);
 
   uint32_t Result() const;
 
-  void GetName(nsString& retval);
+  void GetName(nsAString& retval);
 
   virtual void GetErrorMessage(nsAString& aRetVal)
   {
-    // Since GetName and GetMessageMoz are non-virtual and they deal with
-    // different member variables in Exception vs. DOMException, have a
-    // virtual method to ensure the right error message creation.
+    // Since GetName is non non-virtual and deals with different
+    // member variables in Exception vs. DOMException, have a virtual
+    // method to ensure the right error message creation.
     nsAutoString name;
-    nsAutoString message;
     GetName(name);
-    GetMessageMoz(message);
-    CreateErrorMessage(name, message, aRetVal);
+    CreateErrorMessage(name, aRetVal);
   }
 
-  // The XPCOM GetFilename does the right thing.  It might throw, but we want to
-  // return an empty filename in that case anyway, instead of throwing.
+  void GetFilename(JSContext* aCx, nsAString& aFilename);
 
   uint32_t LineNumber(JSContext* aCx) const;
 
   uint32_t ColumnNumber() const;
 
   already_AddRefed<nsIStackFrame> GetLocation() const;
 
-  already_AddRefed<nsISupports> GetData() const;
+  nsISupports* GetData() const;
 
-  void GetStack(JSContext* aCx, nsAString& aStack, ErrorResult& aRv) const;
+  void GetStack(JSContext* aCx, nsAString& aStack) const;
 
   void Stringify(JSContext* aCx, nsString& retval);
 
-  // XPCOM factory ctor.
-  Exception();
-
   Exception(const nsACString& aMessage,
             nsresult aResult,
             const nsACString& aName,
             nsIStackFrame *aLocation,
             nsISupports *aData);
 
 protected:
   virtual ~Exception();
 
-  void CreateErrorMessage(const nsAString& aName, const nsAString& aMessage,
-                          nsAString& aRetVal)
+  void CreateErrorMessage(const nsAString& aName, nsAString& aRetVal)
   {
     // Create similar error message as what ErrorReport::init does in jsexn.cpp.
-    if (!aName.IsEmpty() && !aMessage.IsEmpty()) {
+    if (!aName.IsEmpty() && !mMessage.IsEmpty()) {
       aRetVal.Assign(aName);
       aRetVal.AppendLiteral(": ");
-      aRetVal.Append(aMessage);
+      AppendUTF8toUTF16(mMessage, aRetVal);
     } else if (!aName.IsEmpty()) {
       aRetVal.Assign(aName);
-    } else if (!aMessage.IsEmpty()) {
-      aRetVal.Assign(aMessage);
+    } else if (!mMessage.IsEmpty()) {
+      CopyUTF8toUTF16(mMessage, aRetVal);
     } else {
       aRetVal.Truncate();
     }
   }
 
   nsCString       mMessage;
   nsresult        mResult;
   nsCString       mName;
@@ -147,60 +149,54 @@ class DOMException : public Exception,
 {
 public:
   DOMException(nsresult aRv, const nsACString& aMessage,
                const nsACString& aName, uint16_t aCode);
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMDOMEXCEPTION
 
-  // nsIException overrides
-  NS_IMETHOD ToString(JSContext* aCx, nsACString& aReturn) override;
-
   // nsWrapperCache overrides
   virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
     override;
 
   static already_AddRefed<DOMException>
   Constructor(GlobalObject& /* unused */,
               const nsAString& aMessage,
               const Optional<nsAString>& aName,
               ErrorResult& aError);
 
   uint16_t Code() const {
     return mCode;
   }
 
-  // Intentionally shadow the nsXPCException version.
-  void GetMessageMoz(nsString& retval);
+  // Intentionally shadow the Exception version.
   void GetName(nsString& retval);
 
+  // Exception overrides
+  void ToString(JSContext* aCx, nsACString& aReturn) override;
+
   virtual void GetErrorMessage(nsAString& aRetVal) override
   {
     // See the comment in Exception::GetErrorMessage.
     nsAutoString name;
-    nsAutoString message;
     GetName(name);
-    GetMessageMoz(message);
-    CreateErrorMessage(name, message, aRetVal);
+    CreateErrorMessage(name, aRetVal);
   }
 
   static already_AddRefed<DOMException>
   Create(nsresult aRv);
 
   static already_AddRefed<DOMException>
   Create(nsresult aRv, const nsACString& aMessage);
 
 protected:
 
   virtual ~DOMException() {}
 
-  nsCString mName;
-  nsCString mMessage;
-
   uint16_t mCode;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #ifdef __GNUC__
 #pragma GCC diagnostic pop
--- a/dom/base/DOMRequest.cpp
+++ b/dom/base/DOMRequest.cpp
@@ -164,25 +164,24 @@ DOMRequest::FireError(nsresult aError)
   FireEvent(NS_LITERAL_STRING("error"), true, true);
 
   if (mPromise) {
     mPromise->MaybeRejectBrokenly(mError);
   }
 }
 
 void
-DOMRequest::FireDetailedError(DOMException* aError)
+DOMRequest::FireDetailedError(DOMException& aError)
 {
   NS_ASSERTION(!mDone, "mDone shouldn't have been set to true already!");
   NS_ASSERTION(!mError, "mError shouldn't have been set!");
   NS_ASSERTION(mResult.isUndefined(), "mResult shouldn't have been set!");
-  NS_ASSERTION(aError, "No detailed error provided");
 
   mDone = true;
-  mError = aError;
+  mError = &aError;
 
   FireEvent(NS_LITERAL_STRING("error"), true, true);
 
   if (mPromise) {
     mPromise->MaybeRejectBrokenly(mError);
   }
 }
 
@@ -278,28 +277,16 @@ DOMRequestService::FireError(nsIDOMDOMRe
                              const nsAString& aError)
 {
   NS_ENSURE_STATE(aRequest);
   static_cast<DOMRequest*>(aRequest)->FireError(aError);
 
   return NS_OK;
 }
 
-NS_IMETHODIMP
-DOMRequestService::FireDetailedError(nsIDOMDOMRequest* aRequest,
-                                     nsISupports* aError)
-{
-  NS_ENSURE_STATE(aRequest);
-  nsCOMPtr<nsIException> err = do_QueryInterface(aError);
-  NS_ENSURE_STATE(err);
-  static_cast<DOMRequest*>(aRequest)->FireDetailedError(static_cast<DOMException*>(err.get()));
-
-  return NS_OK;
-}
-
 class FireSuccessAsyncTask : public mozilla::Runnable
 {
 
   FireSuccessAsyncTask(DOMRequest* aRequest, const JS::Value& aResult)
     : mozilla::Runnable("FireSuccessAsyncTask")
     , mReq(aRequest)
     , mResult(RootingCx(), aResult)
   {
--- a/dom/base/DOMRequest.h
+++ b/dom/base/DOMRequest.h
@@ -77,17 +77,17 @@ public:
   Then(JSContext* aCx, AnyCallback* aResolveCallback,
        AnyCallback* aRejectCallback,
        JS::MutableHandle<JS::Value> aRetval,
        mozilla::ErrorResult& aRv);
 
   void FireSuccess(JS::Handle<JS::Value> aResult);
   void FireError(const nsAString& aError);
   void FireError(nsresult aError);
-  void FireDetailedError(DOMException* aError);
+  void FireDetailedError(DOMException& aError);
 
   explicit DOMRequest(nsPIDOMWindowInner* aWindow);
   explicit DOMRequest(nsIGlobalObject* aGlobal);
 
 protected:
   virtual ~DOMRequest();
 
   void FireEvent(const nsAString& aType, bool aBubble, bool aCancelable);
--- a/dom/base/EventSource.cpp
+++ b/dom/base/EventSource.cpp
@@ -45,18 +45,16 @@
 #include "nsWrapperCacheInlines.h"
 #include "mozilla/Attributes.h"
 #include "nsError.h"
 #include "mozilla/Encoding.h"
 
 namespace mozilla {
 namespace dom {
 
-using namespace workers;
-
 static LazyLogModule gEventSourceLog("EventSource");
 
 #define SPACE_CHAR           (char16_t)0x0020
 #define CR_CHAR              (char16_t)0x000D
 #define LF_CHAR              (char16_t)0x000A
 #define COLON_CHAR           (char16_t)0x003A
 
 // Reconnection time related values in milliseconds. The default one is equal
--- a/dom/base/ImageEncoder.cpp
+++ b/dom/base/ImageEncoder.cpp
@@ -84,17 +84,17 @@ public:
   explicit EncodingCompleteEvent(EncodeCompleteCallback* aEncodeCompleteCallback)
     : CancelableRunnable("EncodingCompleteEvent")
     , mImgSize(0)
     , mType()
     , mImgData(nullptr)
     , mEncodeCompleteCallback(aEncodeCompleteCallback)
     , mFailed(false)
   {
-    if (!NS_IsMainThread() && workers::GetCurrentThreadWorkerPrivate()) {
+    if (!NS_IsMainThread() && GetCurrentThreadWorkerPrivate()) {
       mCreationEventTarget = GetCurrentThreadEventTarget();
     } else {
       mCreationEventTarget = GetMainThreadEventTarget();
     }
   }
 
   NS_IMETHOD Run() override
   {
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -2439,19 +2439,19 @@ nsContentUtils::CalcRoundedWindowSizeFor
 
   *aOutputWidth = resultWidth;
   *aOutputHeight = resultHeight;
 }
 
 bool
 nsContentUtils::ThreadsafeIsCallerChrome()
 {
-  return NS_IsMainThread() ?
-    IsCallerChrome() :
-    workers::IsCurrentThreadRunningChromeWorker();
+  return NS_IsMainThread()
+           ? IsCallerChrome()
+           : IsCurrentThreadRunningChromeWorker();
 }
 
 bool
 nsContentUtils::IsCallerContentXBL()
 {
   JSContext *cx = GetCurrentJSContext();
   if (!cx)
     return false;
@@ -2480,17 +2480,17 @@ nsContentUtils::IsSystemCaller(JSContext
 
 bool
 nsContentUtils::ThreadsafeIsSystemCaller(JSContext* aCx)
 {
   if (NS_IsMainThread()) {
     return IsSystemCaller(aCx);
   }
 
-  return workers::GetWorkerPrivateFromContext(aCx)->UsesSystemPrincipal();
+  return GetWorkerPrivateFromContext(aCx)->UsesSystemPrincipal();
 }
 
 // static
 bool
 nsContentUtils::LookupBindingMember(JSContext* aCx, nsIContent *aContent,
                                     JS::Handle<jsid> aId,
                                     JS::MutableHandle<JS::PropertyDescriptor> aDesc)
 {
@@ -6139,17 +6139,17 @@ nsContentUtils::GetCurrentJSContext()
 /* static */
 JSContext *
 nsContentUtils::GetCurrentJSContextForThread()
 {
   MOZ_ASSERT(IsInitialized());
   if (MOZ_LIKELY(NS_IsMainThread())) {
     return GetCurrentJSContext();
   }
-  return workers::GetCurrentThreadJSContext();
+  return GetCurrentWorkerThreadJSContext();
 }
 
 template<typename StringType, typename CharType>
 void
 _ASCIIToLowerInSitu(StringType& aStr)
 {
   CharType* iter = aStr.BeginWriting();
   CharType* end = aStr.EndWriting();
--- a/dom/base/nsGlobalWindowInner.cpp
+++ b/dom/base/nsGlobalWindowInner.cpp
@@ -1263,17 +1263,17 @@ nsGlobalWindowInner::FreeInnerObjects()
   NotifyDOMWindowDestroyed(this);
   if (auto* reporter = nsWindowMemoryReporter::Get()) {
     reporter->ObserveDOMWindowDetached(this);
   }
 
   mInnerObjectsFreed = true;
 
   // Kill all of the workers for this window.
-  mozilla::dom::workers::CancelWorkersForWindow(this);
+  CancelWorkersForWindow(this);
 
   if (mTimeoutManager) {
     mTimeoutManager->ClearAllTimeouts();
   }
 
   if (mIdleTimer) {
     mIdleTimer->Cancel();
     mIdleTimer = nullptr;
@@ -6095,17 +6095,17 @@ nsGlobalWindowInner::Suspend()
   nsCOMPtr<nsIDeviceSensors> ac = do_GetService(NS_DEVICE_SENSORS_CONTRACTID);
   if (ac) {
     for (uint32_t i = 0; i < mEnabledSensors.Length(); i++)
       ac->RemoveWindowListener(mEnabledSensors[i], this);
   }
   DisableGamepadUpdates();
   DisableVRUpdates();
 
-  mozilla::dom::workers::SuspendWorkersForWindow(this);
+  SuspendWorkersForWindow(this);
 
   SuspendIdleRequests();
 
   mTimeoutManager->Suspend();
 
   // Suspend all of the AudioContexts for this window
   for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) {
     ErrorResult dummy;
@@ -6157,17 +6157,17 @@ nsGlobalWindowInner::Resume()
 
   mTimeoutManager->Resume();
 
   ResumeIdleRequests();
 
   // Resume all of the workers for this window.  We must do this
   // after timeouts since workers may have queued events that can trigger
   // a setTimeout().
-  mozilla::dom::workers::ResumeWorkersForWindow(this);
+  ResumeWorkersForWindow(this);
 }
 
 bool
 nsGlobalWindowInner::IsSuspended() const
 {
   MOZ_ASSERT(NS_IsMainThread());
   return mSuspendDepth != 0;
 }
@@ -6190,17 +6190,17 @@ nsGlobalWindowInner::FreezeInternal()
   CallOnChildren(&nsGlobalWindowInner::FreezeInternal);
 
   mFreezeDepth += 1;
   MOZ_ASSERT(mSuspendDepth >= mFreezeDepth);
   if (mFreezeDepth != 1) {
     return;
   }
 
-  mozilla::dom::workers::FreezeWorkersForWindow(this);
+  FreezeWorkersForWindow(this);
 
   mTimeoutManager->Freeze();
   if (mClientSource) {
     mClientSource->Freeze();
   }
 
   NotifyDOMWindowFrozen(this);
 }
@@ -6229,17 +6229,17 @@ nsGlobalWindowInner::ThawInternal()
     return;
   }
 
   if (mClientSource) {
     mClientSource->Thaw();
   }
   mTimeoutManager->Thaw();
 
-  mozilla::dom::workers::ThawWorkersForWindow(this);
+  ThawWorkersForWindow(this);
 
   NotifyDOMWindowThawed(this);
 }
 
 bool
 nsGlobalWindowInner::IsFrozen() const
 {
   MOZ_ASSERT(NS_IsMainThread());
--- a/dom/base/nsIDOMDOMRequest.idl
+++ b/dom/base/nsIDOMDOMRequest.idl
@@ -30,13 +30,12 @@ interface nsIDOMRequestService : nsISupp
    *        Called when `continue()' is called in the cursor, should be used to
    *        notify the data provider that content wants the next result.
    */
   nsIDOMDOMCursor createCursor(in mozIDOMWindow window,
                                in nsICursorContinueCallback aCallback);
 
   void fireSuccess(in nsIDOMDOMRequest request, in jsval result);
   void fireError(in nsIDOMDOMRequest request, in DOMString error);
-  void fireDetailedError(in nsIDOMDOMRequest request, in nsISupports error);
   void fireSuccessAsync(in nsIDOMDOMRequest request, in jsval result);
   void fireErrorAsync(in nsIDOMDOMRequest request, in DOMString error);
   void fireDone(in nsIDOMDOMCursor cursor);
 };
--- a/dom/base/nsJSTimeoutHandler.cpp
+++ b/dom/base/nsJSTimeoutHandler.cpp
@@ -18,17 +18,16 @@
 #include "nsIContentSecurityPolicy.h"
 #include "nsIDocument.h"
 #include "nsIScriptTimeoutHandler.h"
 #include "nsIXPConnect.h"
 #include "nsJSUtils.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
-using namespace mozilla::dom::workers;
 
 // Our JS nsIScriptTimeoutHandler implementation.
 class nsJSScriptTimeoutHandler final : public nsIScriptTimeoutHandler
 {
 public:
   // nsISupports
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsJSScriptTimeoutHandler)
--- a/dom/base/test/test_domrequest.html
+++ b/dom/base/test/test_domrequest.html
@@ -104,17 +104,17 @@ function testDetailedError() {
     runTest();
   }, function(e) {
     ok(e instanceof DOMException, "got error rejection");
     ok(e === req.error, "got correct error when rejecting the promise");
     error = e;
     runTest();
   });
   ok(promise instanceof Promise, "then() should return a Promise");
-  reqserv.fireDetailedError(req, new DOMException("detailedError"));
+  SpecialPowers.wrwp(req).fireDetailedError(new DOMException("detailedError"));
   ok(ev, "got error event");
   is(ev.type, "error", "correct type during error");
   is(ev.target, req, "correct target during error");
   is(req.readyState, "done", "correct readyState after error");
   is(req.error.name, "UnknownError", "correct error type after error");
   is(req.error.message, "detailedError", "correct error message after error");
   is(req.result, undefined, "correct result after error");
   is(error, null, "Promise should not be rejected synchronously");
@@ -189,17 +189,17 @@ function testDetailedError() {
     runTest();
   }, function(e) {
     ok(e instanceof DOMException, "got error rejection");
     ok(e === req.error, "got correct error when rejecting the promise");
     error = e;
     runTest();
   });
   ok(promise instanceof Promise, "then() should return a Promise");
-  reqserv.fireDetailedError(req, new DOMException("detailedError"));
+  SpecialPowers.wrap(req).fireDetailedError(new DOMException("detailedError"));
   ok(ev, "got error event");
   is(ev.type, "error", "correct type during error");
   is(ev.target, req, "correct target during error");
   is(req.readyState, "done", "correct readyState after error");
   is(req.error.name, "Error", "correct error type after error");
   is(req.error.message, "detailedError", "correct error message after error");
   is(req.result, undefined, "correct result after error");
   is(error, null, "Promise should not be rejected synchronously");
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -59,18 +59,16 @@
 #include "ipc/ErrorIPCUtils.h"
 #include "mozilla/UseCounter.h"
 #include "mozilla/dom/DocGroup.h"
 #include "nsXULElement.h"
 
 namespace mozilla {
 namespace dom {
 
-using namespace workers;
-
 // Forward declare GetConstructorObject methods.
 #define HTML_TAG(_tag, _classname, _interfacename)                             \
 namespace HTML##_interfacename##ElementBinding {                               \
   JSObject* GetConstructorObject(JSContext*);                                  \
 }
 #define HTML_OTHER(_tag)
 #include "nsHTMLTagList.h"
 #undef HTML_TAG
--- a/dom/bindings/Exceptions.cpp
+++ b/dom/bindings/Exceptions.cpp
@@ -25,17 +25,17 @@ namespace mozilla {
 namespace dom {
 
 // Throw the given exception value if it's safe.  If it's not safe, then
 // synthesize and throw a new exception value for NS_ERROR_UNEXPECTED.  The
 // incoming value must be in the compartment of aCx.  This function guarantees
 // that an exception is pending on aCx when it returns.
 static void
 ThrowExceptionValueIfSafe(JSContext* aCx, JS::Handle<JS::Value> exnVal,
-                          nsIException* aOriginalException)
+                          Exception* aOriginalException)
 {
   MOZ_ASSERT(aOriginalException);
 
   if (!exnVal.isObject()) {
     JS_SetPendingException(aCx, exnVal);
     return;
   }
 
@@ -64,38 +64,16 @@ ThrowExceptionValueIfSafe(JSContext* aCx
   }
   MOZ_ASSERT(syntheticVal.isObject() &&
              !js::IsWrapper(&syntheticVal.toObject()),
              "Must have a reflector here, not a wrapper");
   JS_SetPendingException(aCx, syntheticVal);
 }
 
 void
-ThrowExceptionObject(JSContext* aCx, nsIException* aException)
-{
-  // See if we really have an Exception.
-  nsCOMPtr<Exception> exception = do_QueryInterface(aException);
-  if (exception) {
-    ThrowExceptionObject(aCx, exception);
-    return;
-  }
-
-  // We only have an nsIException (probably an XPCWrappedJS).  Fall back on old
-  // wrapping.
-  MOZ_ASSERT(NS_IsMainThread());
-
-  JS::Rooted<JS::Value> val(aCx);
-  if (!WrapObject(aCx, aException, &NS_GET_IID(nsIException), &val)) {
-    return;
-  }
-
-  ThrowExceptionValueIfSafe(aCx, val, aException);
-}
-
-void
 ThrowExceptionObject(JSContext* aCx, Exception* aException)
 {
   JS::Rooted<JS::Value> thrown(aCx);
 
   // If we stored the original thrown JS value in the exception
   // (see XPCConvert::ConstructException) and we are in a web context
   // (i.e., not chrome), rethrow the original value. This only applies to JS
   // implemented components so we only need to check for this on the main
@@ -104,19 +82,18 @@ ThrowExceptionObject(JSContext* aCx, Exc
       aException->StealJSVal(thrown.address())) {
     // Now check for the case when thrown is a number which matches
     // aException->GetResult().  This would indicate that what actually got
     // thrown was an nsresult value.  In that situation, we should go back
     // through dom::Throw with that nsresult value, because it will make sure to
     // create the right sort of Exception or DOMException, with the right
     // global.
     if (thrown.isNumber()) {
-      nsresult exceptionResult;
-      if (NS_SUCCEEDED(aException->GetResult(&exceptionResult)) &&
-          double(exceptionResult) == thrown.toNumber()) {
+      nsresult exceptionResult = aException->GetResult();
+      if (double(exceptionResult) == thrown.toNumber()) {
         Throw(aCx, exceptionResult);
         return;
       }
     }
     if (!JS_WrapValue(aCx, &thrown)) {
       return;
     }
     ThrowExceptionValueIfSafe(aCx, thrown, aException);
@@ -140,27 +117,25 @@ Throw(JSContext* aCx, nsresult aRv, cons
   }
 
   if (JS_IsExceptionPending(aCx)) {
     // Don't clobber the existing exception.
     return false;
   }
 
   CycleCollectedJSContext* context = CycleCollectedJSContext::Get();
-  nsCOMPtr<nsIException> existingException = context->GetPendingException();
+  RefPtr<Exception> existingException = context->GetPendingException();
   // Make sure to clear the pending exception now.  Either we're going to reuse
   // it (and we already grabbed it), or we plan to throw something else and this
   // pending exception is no longer relevant.
   context->SetPendingException(nullptr);
 
   // Ignore the pending exception if we have a non-default message passed in.
   if (aMessage.IsEmpty() && existingException) {
-    nsresult nr;
-    if (NS_SUCCEEDED(existingException->GetResult(&nr)) &&
-        aRv == nr) {
+    if (aRv == existingException->GetResult()) {
       // Reuse the existing exception.
       ThrowExceptionObject(aCx, existingException);
       return false;
     }
   }
 
   RefPtr<Exception> finalException = CreateException(aRv, aMessage);
   MOZ_ASSERT(finalException);
@@ -238,21 +213,16 @@ class JSStackFrame : public nsIStackFram
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(JSStackFrame)
   NS_DECL_NSISTACKFRAME
 
   // aStack must not be null.
   explicit JSStackFrame(JS::Handle<JSObject*> aStack);
 
-protected:
-  int32_t GetLineno(JSContext* aCx);
-
-  int32_t GetColNo(JSContext* aCx);
-
 private:
   virtual ~JSStackFrame();
 
   JS::Heap<JSObject*> mStack;
   nsString mFormattedStack;
 
   nsCOMPtr<nsIStackFrame> mCaller;
   nsCOMPtr<nsIStackFrame> mAsyncCaller;
@@ -349,89 +319,100 @@ GetValueIfNotCached(JSContext* aCx, cons
     return;
   }
 
   *aUseCachedValue = false;
 
   aPropGetter(aCx, stack, aValue, JS::SavedFrameSelfHosted::Exclude);
 }
 
-NS_IMETHODIMP JSStackFrame::GetFilename(JSContext* aCx, nsAString& aFilename)
+NS_IMETHODIMP JSStackFrame::GetFilenameXPCOM(JSContext* aCx, nsAString& aFilename)
+{
+  GetFilename(aCx, aFilename);
+  return NS_OK;
+}
+
+void
+JSStackFrame::GetFilename(JSContext* aCx, nsAString& aFilename)
 {
   if (!mStack) {
     aFilename.Truncate();
-    return NS_OK;
+    return;
   }
 
   JS::Rooted<JSString*> filename(aCx);
   bool canCache = false, useCachedValue = false;
   GetValueIfNotCached(aCx, mStack, JS::GetSavedFrameSource,
                       mFilenameInitialized,
                       &canCache, &useCachedValue, &filename);
   if (useCachedValue) {
     aFilename = mFilename;
-    return NS_OK;
+    return;
   }
 
   nsAutoJSString str;
   if (!str.init(aCx, filename)) {
     JS_ClearPendingException(aCx);
     aFilename.Truncate();
-    return NS_OK;
+    return;
   }
   aFilename = str;
 
   if (canCache) {
     mFilename = str;
     mFilenameInitialized = true;
   }
+}
 
+NS_IMETHODIMP
+JSStackFrame::GetNameXPCOM(JSContext* aCx, nsAString& aFunction)
+{
+  GetName(aCx, aFunction);
   return NS_OK;
 }
 
-NS_IMETHODIMP JSStackFrame::GetName(JSContext* aCx, nsAString& aFunction)
+void
+JSStackFrame::GetName(JSContext* aCx, nsAString& aFunction)
 {
   if (!mStack) {
     aFunction.Truncate();
-    return NS_OK;
+    return;
   }
 
   JS::Rooted<JSString*> name(aCx);
   bool canCache = false, useCachedValue = false;
   GetValueIfNotCached(aCx, mStack, JS::GetSavedFrameFunctionDisplayName,
                       mFunnameInitialized, &canCache, &useCachedValue,
                       &name);
 
   if (useCachedValue) {
     aFunction = mFunname;
-    return NS_OK;
+    return;
   }
 
   if (name) {
     nsAutoJSString str;
     if (!str.init(aCx, name)) {
       JS_ClearPendingException(aCx);
       aFunction.Truncate();
-      return NS_OK;
+      return;
     }
     aFunction = str;
   } else {
     aFunction.SetIsVoid(true);
   }
 
   if (canCache) {
     mFunname = aFunction;
     mFunnameInitialized = true;
   }
-
-  return NS_OK;
 }
 
 int32_t
-JSStackFrame::GetLineno(JSContext* aCx)
+JSStackFrame::GetLineNumber(JSContext* aCx)
 {
   if (!mStack) {
     return 0;
   }
 
   uint32_t line;
   bool canCache = false, useCachedValue = false;
   GetValueIfNotCached(aCx, mStack, JS::GetSavedFrameLine, mLinenoInitialized,
@@ -444,24 +425,25 @@ JSStackFrame::GetLineno(JSContext* aCx)
   if (canCache) {
     mLineno = line;
     mLinenoInitialized = true;
   }
 
   return line;
 }
 
-NS_IMETHODIMP JSStackFrame::GetLineNumber(JSContext* aCx, int32_t* aLineNumber)
+NS_IMETHODIMP
+JSStackFrame::GetLineNumberXPCOM(JSContext* aCx, int32_t* aLineNumber)
 {
-  *aLineNumber = GetLineno(aCx);
+  *aLineNumber = GetLineNumber(aCx);
   return NS_OK;
 }
 
 int32_t
-JSStackFrame::GetColNo(JSContext* aCx)
+JSStackFrame::GetColumnNumber(JSContext* aCx)
 {
   if (!mStack) {
     return 0;
   }
 
   uint32_t col;
   bool canCache = false, useCachedValue = false;
   GetValueIfNotCached(aCx, mStack, JS::GetSavedFrameColumn, mColNoInitialized,
@@ -474,209 +456,240 @@ JSStackFrame::GetColNo(JSContext* aCx)
   if (canCache) {
     mColNo = col;
     mColNoInitialized = true;
   }
 
   return col;
 }
 
-NS_IMETHODIMP JSStackFrame::GetColumnNumber(JSContext* aCx,
-                                            int32_t* aColumnNumber)
+NS_IMETHODIMP
+JSStackFrame::GetColumnNumberXPCOM(JSContext* aCx,
+                                   int32_t* aColumnNumber)
 {
-  *aColumnNumber = GetColNo(aCx);
+  *aColumnNumber = GetColumnNumber(aCx);
   return NS_OK;
 }
 
 NS_IMETHODIMP JSStackFrame::GetSourceLine(nsACString& aSourceLine)
 {
   aSourceLine.Truncate();
   return NS_OK;
 }
 
-NS_IMETHODIMP JSStackFrame::GetAsyncCause(JSContext* aCx,
-                                          nsAString& aAsyncCause)
+NS_IMETHODIMP
+JSStackFrame::GetAsyncCauseXPCOM(JSContext* aCx,
+                                 nsAString& aAsyncCause)
+{
+  GetAsyncCause(aCx, aAsyncCause);
+  return NS_OK;
+}
+
+void
+JSStackFrame::GetAsyncCause(JSContext* aCx,
+                            nsAString& aAsyncCause)
 {
   if (!mStack) {
     aAsyncCause.Truncate();
-    return NS_OK;
+    return;
   }
 
   JS::Rooted<JSString*> asyncCause(aCx);
   bool canCache = false, useCachedValue = false;
   GetValueIfNotCached(aCx, mStack, JS::GetSavedFrameAsyncCause,
                       mAsyncCauseInitialized, &canCache, &useCachedValue,
                       &asyncCause);
 
   if (useCachedValue) {
     aAsyncCause = mAsyncCause;
-    return NS_OK;
+    return;
   }
 
   if (asyncCause) {
     nsAutoJSString str;
     if (!str.init(aCx, asyncCause)) {
       JS_ClearPendingException(aCx);
       aAsyncCause.Truncate();
-      return NS_OK;
+      return;
     }
     aAsyncCause = str;
   } else {
     aAsyncCause.SetIsVoid(true);
   }
 
   if (canCache) {
     mAsyncCause = aAsyncCause;
     mAsyncCauseInitialized = true;
   }
+}
 
+NS_IMETHODIMP
+JSStackFrame::GetAsyncCallerXPCOM(JSContext* aCx,
+                                  nsIStackFrame** aAsyncCaller)
+{
+  *aAsyncCaller = GetAsyncCaller(aCx).take();
   return NS_OK;
 }
 
-NS_IMETHODIMP JSStackFrame::GetAsyncCaller(JSContext* aCx,
-                                           nsIStackFrame** aAsyncCaller)
+already_AddRefed<nsIStackFrame>
+JSStackFrame::GetAsyncCaller(JSContext* aCx)
 {
   if (!mStack) {
-    *aAsyncCaller = nullptr;
-    return NS_OK;
+    return nullptr;
   }
 
   JS::Rooted<JSObject*> asyncCallerObj(aCx);
   bool canCache = false, useCachedValue = false;
   GetValueIfNotCached(aCx, mStack, JS::GetSavedFrameAsyncParent,
                       mAsyncCallerInitialized, &canCache, &useCachedValue,
                       &asyncCallerObj);
 
   if (useCachedValue) {
-    NS_IF_ADDREF(*aAsyncCaller = mAsyncCaller);
-    return NS_OK;
+    nsCOMPtr<nsIStackFrame> asyncCaller = mAsyncCaller;
+    return asyncCaller.forget();
   }
 
   nsCOMPtr<nsIStackFrame> asyncCaller =
     asyncCallerObj ? new JSStackFrame(asyncCallerObj) : nullptr;
-  asyncCaller.forget(aAsyncCaller);
 
   if (canCache) {
-    mAsyncCaller = *aAsyncCaller;
+    mAsyncCaller = asyncCaller;
     mAsyncCallerInitialized = true;
   }
 
+  return asyncCaller.forget();
+}
+
+NS_IMETHODIMP
+JSStackFrame::GetCallerXPCOM(JSContext* aCx, nsIStackFrame** aCaller)
+{
+  *aCaller = GetCaller(aCx).take();
   return NS_OK;
 }
 
-NS_IMETHODIMP JSStackFrame::GetCaller(JSContext* aCx, nsIStackFrame** aCaller)
+already_AddRefed<nsIStackFrame>
+JSStackFrame::GetCaller(JSContext* aCx)
 {
   if (!mStack) {
-    *aCaller = nullptr;
-    return NS_OK;
+    return nullptr;
   }
 
   JS::Rooted<JSObject*> callerObj(aCx);
   bool canCache = false, useCachedValue = false;
   GetValueIfNotCached(aCx, mStack, JS::GetSavedFrameParent, mCallerInitialized,
                       &canCache, &useCachedValue, &callerObj);
 
   if (useCachedValue) {
-    NS_IF_ADDREF(*aCaller = mCaller);
-    return NS_OK;
+    nsCOMPtr<nsIStackFrame> caller = mCaller;
+    return caller.forget();
   }
 
   nsCOMPtr<nsIStackFrame> caller =
     callerObj ? new JSStackFrame(callerObj) : nullptr;
-  caller.forget(aCaller);
 
   if (canCache) {
-    mCaller = *aCaller;
+    mCaller = caller;
     mCallerInitialized = true;
   }
 
+  return caller.forget();
+}
+
+NS_IMETHODIMP
+JSStackFrame::GetFormattedStackXPCOM(JSContext* aCx, nsAString& aStack)
+{
+  GetFormattedStack(aCx, aStack);
   return NS_OK;
 }
 
-NS_IMETHODIMP JSStackFrame::GetFormattedStack(JSContext* aCx, nsAString& aStack)
+void
+JSStackFrame::GetFormattedStack(JSContext* aCx, nsAString& aStack)
 {
   if (!mStack) {
     aStack.Truncate();
-    return NS_OK;
+    return;
   }
 
   // Sadly we can't use GetValueIfNotCached here, because our getter
   // returns bool, not JS::SavedFrameResult.  Maybe it's possible to
   // make the templates more complicated to deal, but in the meantime
   // let's just inline GetValueIfNotCached here.
 
   // Allow caching if aCx and stack are same-compartment.  Otherwise take the
   // slow path.
   bool canCache =
     js::GetContextCompartment(aCx) == js::GetObjectCompartment(mStack);
   if (canCache && mFormattedStackInitialized) {
     aStack = mFormattedStack;
-    return NS_OK;
+    return;
   }
 
   JS::Rooted<JSObject*> stack(aCx, mStack);
 
   JS::Rooted<JSString*> formattedStack(aCx);
   if (!JS::BuildStackString(aCx, stack, &formattedStack)) {
     JS_ClearPendingException(aCx);
     aStack.Truncate();
-    return NS_OK;
+    return;
   }
 
   nsAutoJSString str;
   if (!str.init(aCx, formattedStack)) {
     JS_ClearPendingException(aCx);
     aStack.Truncate();
-    return NS_OK;
+    return;
   }
 
   aStack = str;
 
   if (canCache) {
     mFormattedStack = str;
     mFormattedStackInitialized = true;
   }
-
-  return NS_OK;
 }
 
 NS_IMETHODIMP JSStackFrame::GetNativeSavedFrame(JS::MutableHandle<JS::Value> aSavedFrame)
 {
   aSavedFrame.setObjectOrNull(mStack);
   return NS_OK;
 }
 
-NS_IMETHODIMP JSStackFrame::ToString(JSContext* aCx, nsACString& _retval)
+NS_IMETHODIMP
+JSStackFrame::ToStringXPCOM(JSContext* aCx, nsACString& _retval)
+{
+  ToString(aCx, _retval);
+  return NS_OK;
+}
+
+void
+JSStackFrame::ToString(JSContext* aCx, nsACString& _retval)
 {
   _retval.Truncate();
 
   nsString filename;
-  nsresult rv = GetFilename(aCx, filename);
-  NS_ENSURE_SUCCESS(rv, rv);
+  GetFilename(aCx, filename);
 
   if (filename.IsEmpty()) {
     filename.AssignLiteral("<unknown filename>");
   }
 
   nsString funname;
-  rv = GetName(aCx, funname);
-  NS_ENSURE_SUCCESS(rv, rv);
+  GetName(aCx, funname);
 
   if (funname.IsEmpty()) {
     funname.AssignLiteral("<TOP_LEVEL>");
   }
 
-  int32_t lineno = GetLineno(aCx);
+  int32_t lineno = GetLineNumber(aCx);
 
   static const char format[] = "JS frame :: %s :: %s :: line %d";
   _retval.AppendPrintf(format,
                        NS_ConvertUTF16toUTF8(filename).get(),
                        NS_ConvertUTF16toUTF8(funname).get(),
                        lineno);
-  return NS_OK;
 }
 
 already_AddRefed<nsIStackFrame>
 CreateStack(JSContext* aCx, JS::StackCapture&& aCaptureMode)
 {
   JS::Rooted<JSObject*> stack(aCx);
   if (!JS::CaptureCurrentStack(aCx, &stack, mozilla::Move(aCaptureMode))) {
     return nullptr;
--- a/dom/bindings/Exceptions.h
+++ b/dom/bindings/Exceptions.h
@@ -6,17 +6,16 @@
 
 #ifndef mozilla_dom_Exceptions_h__
 #define mozilla_dom_Exceptions_h__
 
 // DOM exception throwing machinery (for both main thread and workers).
 
 #include <stdint.h>
 #include "jspubtd.h"
-#include "nsIException.h"
 #include "nsString.h"
 #include "jsapi.h"
 
 class nsIStackFrame;
 class nsPIDOMWindowInner;
 template <class T>
 struct already_AddRefed;
 
@@ -33,18 +32,16 @@ Throw(JSContext* cx, nsresult rv, const 
 // Create, throw and report an exception to a given window.
 void
 ThrowAndReport(nsPIDOMWindowInner* aWindow, nsresult aRv);
 
 // Both signatures of ThrowExceptionObject guarantee that an exception is set on
 // aCx before they return.
 void
 ThrowExceptionObject(JSContext* aCx, Exception* aException);
-void
-ThrowExceptionObject(JSContext* aCx, nsIException* aException);
 
 // Create an exception object for the given nsresult and message. If we're
 // throwing a DOMException and aMessage is empty, the default message for the
 // nsresult in question will be used.
 //
 // This never returns null.
 already_AddRefed<Exception>
 CreateException(nsresult aRv, const nsACString& aMessage = EmptyCString());
--- a/dom/broadcastchannel/BroadcastChannel.cpp
+++ b/dom/broadcastchannel/BroadcastChannel.cpp
@@ -27,17 +27,16 @@
 #endif
 
 namespace mozilla {
 
 using namespace ipc;
 
 namespace dom {
 
-using namespace workers;
 using namespace ipc;
 
 class BroadcastChannelMessage final : public StructuredCloneDataNoTransfers
 {
 public:
   NS_INLINE_DECL_REFCOUNTING(BroadcastChannelMessage)
 
   BroadcastChannelMessage()
--- a/dom/broadcastchannel/BroadcastChannelChild.cpp
+++ b/dom/broadcastchannel/BroadcastChannelChild.cpp
@@ -18,18 +18,16 @@
 #include "mozilla/dom/WorkerPrivate.h"
 
 namespace mozilla {
 
 using namespace ipc;
 
 namespace dom {
 
-using namespace workers;
-
 BroadcastChannelChild::BroadcastChannelChild(const nsACString& aOrigin)
   : mBC(nullptr)
   , mActorDestroyed(false)
 {
   CopyUTF8toUTF16(aOrigin, mOrigin);
 }
 
 BroadcastChannelChild::~BroadcastChannelChild()
--- a/dom/canvas/ImageBitmap.cpp
+++ b/dom/canvas/ImageBitmap.cpp
@@ -21,18 +21,16 @@
 #include "imgTools.h"
 
 using namespace mozilla::gfx;
 using namespace mozilla::layers;
 
 namespace mozilla {
 namespace dom {
 
-using namespace workers;
-
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ImageBitmap, mParent)
 NS_IMPL_CYCLE_COLLECTING_ADDREF(ImageBitmap)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(ImageBitmap)
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ImageBitmap)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
--- a/dom/canvas/ImageBitmap.h
+++ b/dom/canvas/ImageBitmap.h
@@ -34,20 +34,16 @@ class SourceSurface;
 
 namespace layers {
 class Image;
 }
 
 namespace dom {
 class OffscreenCanvas;
 
-namespace workers {
-class WorkerStructuredCloneClosure;
-}
-
 class ArrayBufferViewOrArrayBuffer;
 class CanvasRenderingContext2D;
 struct ChannelPixelLayout;
 class CreateImageBitmapFromBlob;
 class CreateImageBitmapFromBlobTask;
 class CreateImageBitmapFromBlobWorkerTask;
 class File;
 class HTMLCanvasElement;
--- a/dom/clients/api/Client.cpp
+++ b/dom/clients/api/Client.cpp
@@ -14,17 +14,16 @@
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/WorkerPrivate.h"
 #include "mozilla/dom/WorkerScope.h"
 #include "nsIGlobalObject.h"
 
 namespace mozilla {
 namespace dom {
 
-using namespace workers;
 using mozilla::dom::ipc::StructuredCloneData;
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(mozilla::dom::Client);
 NS_IMPL_CYCLE_COLLECTING_RELEASE(mozilla::dom::Client);
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(mozilla::dom::Client, mGlobal);
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(mozilla::dom::Client)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
--- a/dom/clients/api/ClientDOMUtil.h
+++ b/dom/clients/api/ClientDOMUtil.h
@@ -21,18 +21,18 @@ namespace dom {
 // if the thread is shutting down.
 template<typename Func, typename Arg, typename Resolve, typename Reject>
 void
 StartClientManagerOp(Func aFunc, const Arg& aArg, nsISerialEventTarget* aTarget,
                      Resolve aResolve, Reject aReject)
 {
   RefPtr<WorkerHolderToken> token;
   if (!NS_IsMainThread()) {
-    token = WorkerHolderToken::Create(workers::GetCurrentThreadWorkerPrivate(),
-                                      mozilla::dom::WorkerStatus::Closing);
+    token = WorkerHolderToken::Create(GetCurrentThreadWorkerPrivate(),
+                                      WorkerStatus::Closing);
   }
 
   RefPtr<ClientOpPromise> promise = aFunc(aArg, aTarget);
   promise->Then(aTarget, __func__,
     [aResolve, token](const ClientOpResult& aResult) {
       if (token && token->IsShuttingDown()) {
         return;
       }
--- a/dom/clients/api/Clients.cpp
+++ b/dom/clients/api/Clients.cpp
@@ -16,17 +16,16 @@
 #include "mozilla/dom/WorkerPrivate.h"
 #include "mozilla/SystemGroup.h"
 #include "nsIGlobalObject.h"
 #include "nsString.h"
 
 namespace mozilla {
 namespace dom {
 
-using namespace workers;
 using mozilla::ipc::PrincipalInfo;
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(Clients);
 NS_IMPL_CYCLE_COLLECTING_RELEASE(Clients);
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Clients, mGlobal);
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Clients)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
--- a/dom/clients/manager/ClientManager.cpp
+++ b/dom/clients/manager/ClientManager.cpp
@@ -37,17 +37,17 @@ ClientManager::ClientManager()
   PBackgroundChild* parentActor = BackgroundChild::GetOrCreateForCurrentThread();
   if (NS_WARN_IF(!parentActor)) {
     Shutdown();
     return;
   }
 
   RefPtr<WorkerHolderToken> workerHolderToken;
   if (!NS_IsMainThread()) {
-    WorkerPrivate* workerPrivate = workers::GetCurrentThreadWorkerPrivate();
+    WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
     MOZ_DIAGNOSTIC_ASSERT(workerPrivate);
 
     workerHolderToken =
       WorkerHolderToken::Create(workerPrivate, Closing,
                                 WorkerHolderToken::AllowIdleShutdownStart);
     if (NS_WARN_IF(!workerHolderToken)) {
       Shutdown();
       return;
--- a/dom/console/Console.cpp
+++ b/dom/console/Console.cpp
@@ -32,16 +32,17 @@
 #include "nsContentUtils.h"
 #include "nsDocShell.h"
 #include "nsProxyRelease.h"
 #include "mozilla/ConsoleTimelineMarker.h"
 #include "mozilla/TimestampTimelineMarker.h"
 
 #include "nsIConsoleAPIStorage.h"
 #include "nsIDOMWindowUtils.h"
+#include "nsIException.h" // for nsIStackFrame
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsILoadContext.h"
 #include "nsISensitiveInfoHiddenURI.h"
 #include "nsIServiceManager.h"
 #include "nsISupportsPrimitives.h"
 #include "nsIWebNavigation.h"
 #include "nsIXPConnect.h"
 
@@ -58,17 +59,16 @@
 // This tags are used in the Structured Clone Algorithm to move js values from
 // worker thread to main thread
 #define CONSOLE_TAG_BLOB   JS_SCTAG_USER_MIN
 
 // This value is taken from ConsoleAPIStorage.js
 #define STORAGE_MAX_EVENTS 1000
 
 using namespace mozilla::dom::exceptions;
-using namespace mozilla::dom::workers;
 
 namespace mozilla {
 namespace dom {
 
 struct
 ConsoleStructuredCloneData
 {
   nsCOMPtr<nsISupports> mParent;
@@ -1149,73 +1149,54 @@ Console::Assert(const GlobalObject& aGlo
 /* static */ void
 Console::Count(const GlobalObject& aGlobal, const nsAString& aLabel)
 {
   StringMethod(aGlobal, aLabel, MethodCount, NS_LITERAL_STRING("count"));
 }
 
 namespace {
 
-nsresult
+void
 StackFrameToStackEntry(JSContext* aCx, nsIStackFrame* aStackFrame,
                        ConsoleStackEntry& aStackEntry)
 {
   MOZ_ASSERT(aStackFrame);
 
-  nsresult rv = aStackFrame->GetFilename(aCx, aStackEntry.mFilename);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  int32_t lineNumber;
-  rv = aStackFrame->GetLineNumber(aCx, &lineNumber);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  aStackEntry.mLineNumber = lineNumber;
-
-  int32_t columnNumber;
-  rv = aStackFrame->GetColumnNumber(aCx, &columnNumber);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  aStackEntry.mColumnNumber = columnNumber;
-
-  rv = aStackFrame->GetName(aCx, aStackEntry.mFunctionName);
-  NS_ENSURE_SUCCESS(rv, rv);
+  aStackFrame->GetFilename(aCx, aStackEntry.mFilename);
+
+  aStackEntry.mLineNumber = aStackFrame->GetLineNumber(aCx);
+
+  aStackEntry.mColumnNumber = aStackFrame->GetColumnNumber(aCx);
+
+  aStackFrame->GetName(aCx, aStackEntry.mFunctionName);
 
   nsString cause;
-  rv = aStackFrame->GetAsyncCause(aCx, cause);
-  NS_ENSURE_SUCCESS(rv, rv);
+  aStackFrame->GetAsyncCause(aCx, cause);
   if (!cause.IsEmpty()) {
     aStackEntry.mAsyncCause.Construct(cause);
   }
-
-  return NS_OK;
 }
 
-nsresult
+void
 ReifyStack(JSContext* aCx, nsIStackFrame* aStack,
            nsTArray<ConsoleStackEntry>& aRefiedStack)
 {
   nsCOMPtr<nsIStackFrame> stack(aStack);
 
   while (stack) {
     ConsoleStackEntry& data = *aRefiedStack.AppendElement();
-    nsresult rv = StackFrameToStackEntry(aCx, stack, data);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    nsCOMPtr<nsIStackFrame> caller;
-    rv = stack->GetCaller(aCx, getter_AddRefs(caller));
-    NS_ENSURE_SUCCESS(rv, rv);
+    StackFrameToStackEntry(aCx, stack, data);
+
+    nsCOMPtr<nsIStackFrame> caller = stack->GetCaller(aCx);
 
     if (!caller) {
-      rv = stack->GetAsyncCaller(aCx, getter_AddRefs(caller));
-      NS_ENSURE_SUCCESS(rv, rv);
+      caller = stack->GetAsyncCaller(aCx);
     }
     stack.swap(caller);
   }
-
-  return NS_OK;
 }
 
 } // anonymous namespace
 
 // Queue a call to a console method. See the CALL_DELAY constant.
 /* static */ void
 Console::Method(const GlobalObject& aGlobal, MethodName aMethodName,
                 const nsAString& aMethodString,
@@ -1298,33 +1279,26 @@ Console::MethodInternal(JSContext* aCx, 
 
   JS::StackCapture captureMode = ShouldIncludeStackTrace(aMethodName) ?
     JS::StackCapture(JS::MaxFrames(DEFAULT_MAX_STACKTRACE_DEPTH)) :
     JS::StackCapture(JS::FirstSubsumedFrame(aCx));
   nsCOMPtr<nsIStackFrame> stack = CreateStack(aCx, mozilla::Move(captureMode));
 
   if (stack) {
     callData->mTopStackFrame.emplace();
-    nsresult rv = StackFrameToStackEntry(aCx, stack,
-                                         *callData->mTopStackFrame);
-    if (NS_FAILED(rv)) {
-      return;
-    }
+    StackFrameToStackEntry(aCx, stack, *callData->mTopStackFrame);
   }
 
   if (NS_IsMainThread()) {
     callData->mStack = stack;
   } else {
     // nsIStackFrame is not threadsafe, so we need to snapshot it now,
     // before we post our runnable to the main thread.
     callData->mReifiedStack.emplace();
-    nsresult rv = ReifyStack(aCx, stack, *callData->mReifiedStack);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return;
-    }
+    ReifyStack(aCx, stack, *callData->mReifiedStack);
   }
 
   DOMHighResTimeStamp monotonicTimer;
 
   // Monotonic timer for 'time' and 'timeEnd'
   if ((aMethodName == MethodTime ||
        aMethodName == MethodTimeEnd ||
        aMethodName == MethodTimeStamp) &&
@@ -1417,21 +1391,17 @@ LazyStackGetter(JSContext* aCx, unsigned
   if (v.isUndefined()) {
     // Already reified.
     args.rval().set(js::GetFunctionNativeReserved(callee, SLOT_STACKOBJ));
     return true;
   }
 
   nsIStackFrame* stack = reinterpret_cast<nsIStackFrame*>(v.toPrivate());
   nsTArray<ConsoleStackEntry> reifiedStack;
-  nsresult rv = ReifyStack(aCx, stack, reifiedStack);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    Throw(aCx, rv);
-    return false;
-  }
+  ReifyStack(aCx, stack, reifiedStack);
 
   JS::Rooted<JS::Value> stackVal(aCx);
   if (NS_WARN_IF(!ToJSValue(aCx, reifiedStack, &stackVal))) {
     return false;
   }
 
   MOZ_ASSERT(stackVal.isObject());
 
@@ -2690,43 +2660,34 @@ Console::MaybeExecuteDumpFunctionForTrac
     message.Append(mPrefix);
     message.AppendLiteral(": ");
   }
 
   nsCOMPtr<nsIStackFrame> stack(aStack);
 
   while (stack) {
     nsAutoString filename;
-    nsresult rv = stack->GetFilename(aCx, filename);
-    NS_ENSURE_SUCCESS_VOID(rv);
+    stack->GetFilename(aCx, filename);
 
     message.Append(filename);
     message.AppendLiteral(" ");
 
-    int32_t lineNumber;
-    rv = stack->GetLineNumber(aCx, &lineNumber);
-    NS_ENSURE_SUCCESS_VOID(rv);
-
-    message.AppendInt(lineNumber);
+    message.AppendInt(stack->GetLineNumber(aCx));
     message.AppendLiteral(" ");
 
     nsAutoString functionName;
-    rv = stack->GetName(aCx, functionName);
-    NS_ENSURE_SUCCESS_VOID(rv);
+    stack->GetName(aCx, functionName);
 
     message.Append(filename);
     message.AppendLiteral("\n");
 
-    nsCOMPtr<nsIStackFrame> caller;
-    rv = stack->GetCaller(aCx, getter_AddRefs(caller));
-    NS_ENSURE_SUCCESS_VOID(rv);
+    nsCOMPtr<nsIStackFrame> caller = stack->GetCaller(aCx);
 
     if (!caller) {
-      rv = stack->GetAsyncCaller(aCx, getter_AddRefs(caller));
-      NS_ENSURE_SUCCESS_VOID(rv);
+      caller = stack->GetAsyncCaller(aCx);
     }
 
     stack.swap(caller);
   }
 
   message.AppendLiteral("\n");
   ExecuteDumpFunction(message);
 }
--- a/dom/crypto/WebCryptoTask.cpp
+++ b/dom/crypto/WebCryptoTask.cpp
@@ -148,17 +148,17 @@ class WebCryptoTask::InternalWorkerHolde
     // worker automatically.
   }
 
 public:
   static already_AddRefed<InternalWorkerHolder>
   Create()
   {
     MOZ_ASSERT(!NS_IsMainThread());
-    WorkerPrivate* workerPrivate = workers::GetCurrentThreadWorkerPrivate();
+    WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
     MOZ_ASSERT(workerPrivate);
     RefPtr<InternalWorkerHolder> ref = new InternalWorkerHolder();
     if (NS_WARN_IF(!ref->HoldWorker(workerPrivate, Canceling))) {
       return nullptr;
     }
     return ref.forget();
   }
 
--- a/dom/events/Event.cpp
+++ b/dom/events/Event.cpp
@@ -329,17 +329,17 @@ Event::SetTrusted(bool aTrusted)
 {
   mEvent->mFlags.mIsTrusted = aTrusted;
 }
 
 bool
 Event::Init(mozilla::dom::EventTarget* aGlobal)
 {
   if (!mIsMainThreadEvent) {
-    return workers::IsCurrentThreadRunningChromeWorker();
+    return IsCurrentThreadRunningChromeWorker();
   }
   bool trusted = false;
   nsCOMPtr<nsPIDOMWindowInner> w = do_QueryInterface(aGlobal);
   if (w) {
     nsCOMPtr<nsIDocument> d = w->GetExtantDoc();
     if (d) {
       trusted = nsContentUtils::IsChromeDoc(d);
       nsIPresShell* s = d->GetShell();
@@ -1113,17 +1113,17 @@ Event::TimeStampImpl() const
     Performance* perf = win->GetPerformance();
     if (NS_WARN_IF(!perf)) {
       return 0.0;
     }
 
     return perf->GetDOMTiming()->TimeStampToDOMHighRes(mEvent->mTimeStamp);
   }
 
-  WorkerPrivate* workerPrivate = workers::GetCurrentThreadWorkerPrivate();
+  WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
   MOZ_ASSERT(workerPrivate);
 
   return workerPrivate->TimeStampToDOMHighRes(mEvent->mTimeStamp);
 }
 
 double
 Event::TimeStamp() const
 {
--- a/dom/events/EventDispatcher.cpp
+++ b/dom/events/EventDispatcher.cpp
@@ -914,17 +914,17 @@ EventDispatcher::DispatchDOMEvent(nsISup
       innerEvent->mOriginalTarget = nullptr;
     } else {
       aDOMEvent->GetIsTrusted(&dontResetTrusted);
     }
 
     if (!dontResetTrusted) {
       //Check security state to determine if dispatcher is trusted
       bool trusted = NS_IsMainThread() ? nsContentUtils::LegacyIsCallerChromeOrNativeCode()
-                                       : mozilla::dom::workers::IsCurrentThreadRunningChromeWorker();
+                                       : IsCurrentThreadRunningChromeWorker();
       aDOMEvent->SetTrusted(trusted);
     }
 
     return EventDispatcher::Dispatch(aTarget, aPresContext, innerEvent,
                                      aDOMEvent, aEventStatus);
   } else if (aEvent) {
     return EventDispatcher::Dispatch(aTarget, aPresContext, aEvent,
                                      aDOMEvent, aEventStatus);
--- a/dom/events/JSEventHandler.cpp
+++ b/dom/events/JSEventHandler.cpp
@@ -121,17 +121,17 @@ JSEventHandler::HandleEvent(nsIDOMEvent*
 
   Event* event = aEvent->InternalDOMEvent();
   bool isMainThread = event->IsMainThreadEvent();
   bool isChromeHandler =
     isMainThread ?
       nsContentUtils::ObjectPrincipal(
         GetTypedEventHandler().Ptr()->CallbackPreserveColor()) ==
         nsContentUtils::GetSystemPrincipal() :
-      mozilla::dom::workers::IsCurrentThreadRunningChromeWorker();
+      mozilla::dom::IsCurrentThreadRunningChromeWorker();
 
   if (mTypedHandler.Type() == TypedEventHandler::eOnError) {
     MOZ_ASSERT_IF(mEventName, mEventName == nsGkAtoms::onerror);
 
     nsString errorMsg, file;
     EventOrString msgOrEvent;
     Optional<nsAString> fileName;
     Optional<uint32_t> lineNumber;
--- a/dom/fetch/Fetch.cpp
+++ b/dom/fetch/Fetch.cpp
@@ -48,18 +48,16 @@
 #include "mozilla/dom/WorkerCommon.h"
 #include "mozilla/dom/WorkerPrivate.h"
 #include "mozilla/dom/WorkerRunnable.h"
 #include "mozilla/dom/WorkerScope.h"
 
 namespace mozilla {
 namespace dom {
 
-using namespace workers;
-
 namespace {
 
 void
 AbortStream(JSContext* aCx, JS::Handle<JSObject*> aStream)
 {
   if (!JS::ReadableStreamIsReadable(aStream)) {
     return;
   }
--- a/dom/fetch/FetchConsumer.cpp
+++ b/dom/fetch/FetchConsumer.cpp
@@ -13,18 +13,16 @@
 #include "mozilla/dom/WorkerScope.h"
 #include "mozilla/ipc/PBackgroundSharedTypes.h"
 #include "nsIInputStreamPump.h"
 #include "nsProxyRelease.h"
 
 namespace mozilla {
 namespace dom {
 
-using namespace workers;
-
 namespace {
 
 template <class Derived>
 class FetchBodyWorkerHolder final : public WorkerHolder
 {
   RefPtr<FetchBodyConsumer<Derived>> mConsumer;
   bool mWasNotified;
 
@@ -97,16 +95,42 @@ public:
   bool
   WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
   {
     mFetchBodyConsumer->ContinueConsumeBody(mStatus, mLength, mResult);
     return true;
   }
 };
 
+// ControlRunnable used to complete the releasing of resources on the worker
+// thread when already shutting down.
+template <class Derived>
+class ContinueConsumeBodyControlRunnable final : public MainThreadWorkerControlRunnable
+{
+  RefPtr<FetchBodyConsumer<Derived>> mFetchBodyConsumer;
+
+public:
+  ContinueConsumeBodyControlRunnable(FetchBodyConsumer<Derived>* aFetchBodyConsumer,
+                                     uint8_t* aResult)
+    : MainThreadWorkerControlRunnable(aFetchBodyConsumer->GetWorkerPrivate())
+    , mFetchBodyConsumer(aFetchBodyConsumer)
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+    free(aResult);
+  }
+
+  bool
+  WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
+  {
+    mFetchBodyConsumer->ContinueConsumeBody(NS_BINDING_ABORTED, 0, nullptr,
+                                            true /* shutting down */);
+    return true;
+  }
+};
+
 template <class Derived>
 class FailConsumeBodyWorkerRunnable : public MainThreadWorkerControlRunnable
 {
   RefPtr<FetchBodyConsumer<Derived>> mBodyConsumer;
 
 public:
   explicit FailConsumeBodyWorkerRunnable(FetchBodyConsumer<Derived>* aBodyConsumer)
     : MainThreadWorkerControlRunnable(aBodyConsumer->GetWorkerPrivate())
@@ -184,16 +208,41 @@ public:
   bool
   WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
   {
     mFetchBodyConsumer->ContinueConsumeBlobBody(mBlobImpl);
     return true;
   }
 };
 
+// ControlRunnable used to complete the releasing of resources on the worker
+// thread when already shutting down.
+template <class Derived>
+class ContinueConsumeBlobBodyControlRunnable final
+  : public MainThreadWorkerControlRunnable
+{
+  RefPtr<FetchBodyConsumer<Derived>> mFetchBodyConsumer;
+
+public:
+  explicit ContinueConsumeBlobBodyControlRunnable(FetchBodyConsumer<Derived>* aFetchBodyConsumer)
+    : MainThreadWorkerControlRunnable(aFetchBodyConsumer->GetWorkerPrivate())
+    , mFetchBodyConsumer(aFetchBodyConsumer)
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+  }
+
+  bool
+  WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
+  {
+    mFetchBodyConsumer->ContinueConsumeBlobBody(nullptr,
+                                                true /* shutting down */);
+    return true;
+  }
+};
+
 template <class Derived>
 class ConsumeBodyDoneObserver : public nsIStreamLoaderObserver
                               , public MutableBlobStorageCallback
 {
   RefPtr<FetchBodyConsumer<Derived>> mFetchBodyConsumer;
 
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
@@ -211,30 +260,43 @@ public:
   {
     MOZ_ASSERT(NS_IsMainThread());
 
     // The loading is completed. Let's nullify the pump before continuing the
     // consuming of the body.
     mFetchBodyConsumer->NullifyConsumeBodyPump();
 
     uint8_t* nonconstResult = const_cast<uint8_t*>(aResult);
-    if (mFetchBodyConsumer->GetWorkerPrivate()) {
+    if (!mFetchBodyConsumer->GetWorkerPrivate()) {
+      mFetchBodyConsumer->ContinueConsumeBody(aStatus, aResultLength,
+                                              nonconstResult);
+      // FetchBody is responsible for data.
+      return NS_SUCCESS_ADOPTED_DATA;
+    }
+
+    {
       RefPtr<ContinueConsumeBodyRunnable<Derived>> r =
         new ContinueConsumeBodyRunnable<Derived>(mFetchBodyConsumer,
                                                  aStatus,
                                                  aResultLength,
                                                  nonconstResult);
-      if (!r->Dispatch()) {
-        NS_WARNING("Could not dispatch ConsumeBodyRunnable");
-        // Return failure so that aResult is freed.
-        return NS_ERROR_FAILURE;
+      if (r->Dispatch()) {
+        // FetchBody is responsible for data.
+        return NS_SUCCESS_ADOPTED_DATA;
       }
-    } else {
-      mFetchBodyConsumer->ContinueConsumeBody(aStatus, aResultLength,
-                                              nonconstResult);
+    }
+
+    // The worker is shutting down. Let's use a control runnable to complete the
+    // shutting down procedure.
+
+    RefPtr<ContinueConsumeBodyControlRunnable<Derived>> r =
+      new ContinueConsumeBodyControlRunnable<Derived>(mFetchBodyConsumer,
+                                                      nonconstResult);
+    if (NS_WARN_IF(!r->Dispatch())) {
+      return NS_ERROR_FAILURE;
     }
 
     // FetchBody is responsible for data.
     return NS_SUCCESS_ADOPTED_DATA;
   }
 
   virtual void BlobStoreCompleted(MutableBlobStorage* aBlobStorage,
                                   Blob* aBlob,
@@ -247,28 +309,38 @@ public:
     }
 
     // The loading is completed. Let's nullify the pump before continuing the
     // consuming of the body.
     mFetchBodyConsumer->NullifyConsumeBodyPump();
 
     MOZ_ASSERT(aBlob);
 
-    if (mFetchBodyConsumer->GetWorkerPrivate()) {
+    if (!mFetchBodyConsumer->GetWorkerPrivate()) {
+      mFetchBodyConsumer->ContinueConsumeBlobBody(aBlob->Impl());
+      return;
+    }
+
+    {
       RefPtr<ContinueConsumeBlobBodyRunnable<Derived>> r =
         new ContinueConsumeBlobBodyRunnable<Derived>(mFetchBodyConsumer,
                                                      aBlob->Impl());
 
-      if (!r->Dispatch()) {
-        NS_WARNING("Could not dispatch ConsumeBlobBodyRunnable");
+      if (r->Dispatch()) {
         return;
       }
-    } else {
-      mFetchBodyConsumer->ContinueConsumeBlobBody(aBlob->Impl());
     }
+
+    // The worker is shutting down. Let's use a control runnable to complete the
+    // shutting down procedure.
+
+    RefPtr<ContinueConsumeBlobBodyControlRunnable<Derived>> r =
+      new ContinueConsumeBlobBodyControlRunnable<Derived>(mFetchBodyConsumer);
+
+    Unused << NS_WARN_IF(!r->Dispatch());
   }
 
 private:
   virtual ~ConsumeBodyDoneObserver()
   { }
 };
 
 template <class Derived>
@@ -520,17 +592,18 @@ FetchBodyConsumer<Derived>::BeginConsume
     }
   }
 }
 
 template <class Derived>
 void
 FetchBodyConsumer<Derived>::ContinueConsumeBody(nsresult aStatus,
                                                 uint32_t aResultLength,
-                                                uint8_t* aResult)
+                                                uint8_t* aResult,
+                                                bool aShuttingDown)
 {
   AssertIsOnTargetThread();
 
   if (mBodyConsumed) {
     return;
   }
   mBodyConsumed = true;
 
@@ -545,16 +618,21 @@ FetchBodyConsumer<Derived>::ContinueCons
   MOZ_ASSERT(mConsumePromise);
   RefPtr<Promise> localPromise = mConsumePromise.forget();
 
   RefPtr<FetchBodyConsumer<Derived>> self = this;
   auto autoReleaseObject = mozilla::MakeScopeExit([&] {
     self->ReleaseObject();
   });
 
+  if (aShuttingDown) {
+    // If shutting down, we don't want to resolve any promise.
+    return;
+  }
+
   if (NS_WARN_IF(NS_FAILED(aStatus))) {
     localPromise->MaybeReject(NS_ERROR_DOM_ABORT_ERR);
   }
 
   // Don't warn here since we warned above.
   if (NS_FAILED(aStatus)) {
     return;
   }
@@ -627,37 +705,40 @@ FetchBodyConsumer<Derived>::ContinueCons
   error.WouldReportJSException();
   if (error.Failed()) {
     localPromise->MaybeReject(error);
   }
 }
 
 template <class Derived>
 void
-FetchBodyConsumer<Derived>::ContinueConsumeBlobBody(BlobImpl* aBlobImpl)
+FetchBodyConsumer<Derived>::ContinueConsumeBlobBody(BlobImpl* aBlobImpl,
+                                                    bool aShuttingDown)
 {
   AssertIsOnTargetThread();
   MOZ_ASSERT(mConsumeType == CONSUME_BLOB);
 
   if (mBodyConsumed) {
     return;
   }
   mBodyConsumed = true;
 
   // Just a precaution to ensure ContinueConsumeBody is not called out of
   // sync with a body read.
   MOZ_ASSERT(mBody->BodyUsed());
 
-  MOZ_ASSERT(mConsumePromise);
-  RefPtr<Promise> localPromise = mConsumePromise.forget();
+  if (!aShuttingDown) {
+    MOZ_ASSERT(mConsumePromise);
+    RefPtr<Promise> localPromise = mConsumePromise.forget();
 
-  RefPtr<dom::Blob> blob = dom::Blob::Create(mGlobal, aBlobImpl);
-  MOZ_ASSERT(blob);
+    RefPtr<dom::Blob> blob = dom::Blob::Create(mGlobal, aBlobImpl);
+    MOZ_ASSERT(blob);
 
-  localPromise->MaybeResolve(blob);
+    localPromise->MaybeResolve(blob);
+  }
 
   ReleaseObject();
 }
 
 template <class Derived>
 void
 FetchBodyConsumer<Derived>::ShutDownMainThreadConsuming()
 {
--- a/dom/fetch/FetchConsumer.h
+++ b/dom/fetch/FetchConsumer.h
@@ -46,20 +46,21 @@ public:
 
   void
   ReleaseObject();
 
   void
   BeginConsumeBodyMainThread();
 
   void
-  ContinueConsumeBody(nsresult aStatus, uint32_t aLength, uint8_t* aResult);
+  ContinueConsumeBody(nsresult aStatus, uint32_t aLength, uint8_t* aResult,
+                      bool aShuttingDown = false);
 
   void
-  ContinueConsumeBlobBody(BlobImpl* aBlobImpl);
+  ContinueConsumeBlobBody(BlobImpl* aBlobImpl, bool aShuttingDown = false);
 
   void
   ShutDownMainThreadConsuming();
 
   WorkerPrivate*
   GetWorkerPrivate() const
   {
     return mWorkerPrivate;
--- a/dom/fetch/FetchDriver.cpp
+++ b/dom/fetch/FetchDriver.cpp
@@ -193,17 +193,17 @@ AlternativeDataStreamListener::GetCacheI
   nsCOMPtr<nsICacheInfoChannel> channel = mCacheInfoChannel;
   return channel.forget();
 }
 
 NS_IMETHODIMP
 AlternativeDataStreamListener::OnStartRequest(nsIRequest* aRequest,
                                               nsISupports* aContext)
 {
-  workers::AssertIsOnMainThread();
+  AssertIsOnMainThread();
   MOZ_ASSERT(!mAlternativeDataType.IsEmpty());
   // Checking the alternative data type is the same between we asked and the
   // saved in the channel.
   nsAutoCString alternativeDataType;
   nsCOMPtr<nsICacheInfoChannel> cic = do_QueryInterface(aRequest);
   mStatus = AlternativeDataStreamListener::LOADING;
   if (cic &&
       NS_SUCCEEDED(cic->GetAlternativeDataType(alternativeDataType)) &&
@@ -269,17 +269,17 @@ AlternativeDataStreamListener::OnDataAva
   return NS_OK;
 }
 
 NS_IMETHODIMP
 AlternativeDataStreamListener::OnStopRequest(nsIRequest* aRequest,
                                              nsISupports* aContext,
                                              nsresult aStatusCode)
 {
-  workers::AssertIsOnMainThread();
+  AssertIsOnMainThread();
 
   // Alternative data loading is going to finish, breaking the reference cycle
   // here by taking the ownership to a loacl variable.
   RefPtr<FetchDriver> fetchDriver = mFetchDriver.forget();
 
   if (mStatus == AlternativeDataStreamListener::CANCELED) {
     // do nothing
     return NS_OK;
@@ -358,17 +358,17 @@ FetchDriver::~FetchDriver()
   // We assert this since even on failures, we should call
   // FailWithNetworkError().
   MOZ_ASSERT(mResponseAvailableCalled);
 }
 
 nsresult
 FetchDriver::Fetch(AbortSignal* aSignal, FetchDriverObserver* aObserver)
 {
-  workers::AssertIsOnMainThread();
+  AssertIsOnMainThread();
 #ifdef DEBUG
   MOZ_ASSERT(!mFetchCalled);
   mFetchCalled = true;
 #endif
 
   mObserver = aObserver;
 
   Telemetry::Accumulate(Telemetry::SERVICE_WORKER_REQUEST_PASSTHROUGH,
@@ -766,17 +766,17 @@ FetchDriver::BeginAndGetFilteredResponse
   }
 
   return filteredResponse.forget();
 }
 
 void
 FetchDriver::FailWithNetworkError(nsresult rv)
 {
-  workers::AssertIsOnMainThread();
+  AssertIsOnMainThread();
   RefPtr<InternalResponse> error = InternalResponse::NetworkError(rv);
   if (mObserver) {
     mObserver->OnResponseAvailable(error);
 #ifdef DEBUG
     mResponseAvailableCalled = true;
 #endif
     mObserver->OnResponseEnd(FetchDriverObserver::eByNetworking);
     mObserver = nullptr;
@@ -784,17 +784,17 @@ FetchDriver::FailWithNetworkError(nsresu
 
   mChannel = nullptr;
 }
 
 NS_IMETHODIMP
 FetchDriver::OnStartRequest(nsIRequest* aRequest,
                             nsISupports* aContext)
 {
-  workers::AssertIsOnMainThread();
+  AssertIsOnMainThread();
 
   // Note, this can be called multiple times if we are doing an opaqueredirect.
   // In that case we will get a simulated OnStartRequest() and then the real
   // channel will call in with an errored OnStartRequest().
 
   nsresult rv;
   aRequest->GetStatus(&rv);
   if (NS_FAILED(rv)) {
@@ -1146,17 +1146,17 @@ FetchDriver::OnDataAvailable(nsIRequest*
   return rv;
 }
 
 NS_IMETHODIMP
 FetchDriver::OnStopRequest(nsIRequest* aRequest,
                            nsISupports* aContext,
                            nsresult aStatusCode)
 {
-  workers::AssertIsOnMainThread();
+  AssertIsOnMainThread();
 
   MOZ_DIAGNOSTIC_ASSERT(!mOnStopRequestCalled);
   mOnStopRequestCalled = true;
 
   // main data loading is going to finish, breaking the reference cycle.
   RefPtr<AlternativeDataStreamListener> altDataListener = mAltDataListener.forget();
 
   // We need to check mObserver, which is nulled by FailWithNetworkError(),
@@ -1212,17 +1212,17 @@ FetchDriver::OnStopRequest(nsIRequest* a
   }
 
   return FinishOnStopRequest(altDataListener);
 }
 
 nsresult
 FetchDriver::FinishOnStopRequest(AlternativeDataStreamListener* aAltDataListener)
 {
-  workers::AssertIsOnMainThread();
+  AssertIsOnMainThread();
   // OnStopRequest is not called from channel, that means the main data loading
   // does not finish yet. Reaching here since alternative data loading finishes.
   if (!mOnStopRequestCalled) {
     return NS_OK;
   }
 
   MOZ_DIAGNOSTIC_ASSERT(!mAltDataListener);
   // Wait for alternative data loading finish if we needed it.
--- a/dom/fetch/FetchStream.cpp
+++ b/dom/fetch/FetchStream.cpp
@@ -15,18 +15,16 @@
 #define FETCH_STREAM_FLAG 0
 
 static NS_DEFINE_CID(kStreamTransportServiceCID,
                      NS_STREAMTRANSPORTSERVICE_CID);
 
 namespace mozilla {
 namespace dom {
 
-using namespace workers;
-
 namespace {
 
 class FetchStreamWorkerHolder final : public WorkerHolder
 {
 public:
   explicit FetchStreamWorkerHolder(FetchStream* aStream)
     : WorkerHolder("FetchStreamWorkerHolder",
                    WorkerHolder::Behavior::AllowIdleShutdownStart)
--- a/dom/fetch/FetchStreamReader.cpp
+++ b/dom/fetch/FetchStreamReader.cpp
@@ -11,18 +11,16 @@
 #include "mozilla/TaskCategory.h"
 #include "nsContentUtils.h"
 #include "nsIScriptError.h"
 #include "nsPIDOMWindow.h"
 
 namespace mozilla {
 namespace dom {
 
-using namespace workers;
-
 namespace {
 
 class FetchStreamReaderWorkerHolder final : public WorkerHolder
 {
 public:
   explicit FetchStreamReaderWorkerHolder(FetchStreamReader* aReader)
     : WorkerHolder("FetchStreamReaderWorkerHolder",
                    WorkerHolder::Behavior::AllowIdleShutdownStart)
--- a/dom/file/FileBlobImpl.cpp
+++ b/dom/file/FileBlobImpl.cpp
@@ -164,17 +164,17 @@ FileBlobImpl::GetType(nsAString& aType)
 {
   aType.Truncate();
 
   if (mContentType.IsVoid()) {
     MOZ_ASSERT(mWholeFile,
                "Should only use lazy ContentType when using the whole file");
 
     if (!NS_IsMainThread()) {
-      WorkerPrivate* workerPrivate = workers::GetCurrentThreadWorkerPrivate();
+      WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
       if (!workerPrivate) {
         // I have no idea in which thread this method is called. We cannot
         // return any valid value.
         return;
       }
 
       RefPtr<GetTypeRunnable> runnable =
         new GetTypeRunnable(workerPrivate, this);
--- a/dom/file/FileReader.cpp
+++ b/dom/file/FileReader.cpp
@@ -134,17 +134,17 @@ FileReader::~FileReader()
 /* static */ already_AddRefed<FileReader>
 FileReader::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
 {
   nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
   WorkerPrivate* workerPrivate = nullptr;
 
   if (!NS_IsMainThread()) {
     JSContext* cx = aGlobal.Context();
-    workerPrivate = workers::GetWorkerPrivateFromContext(cx);
+    workerPrivate = GetWorkerPrivateFromContext(cx);
     MOZ_ASSERT(workerPrivate);
   }
 
   RefPtr<FileReader> fileReader = new FileReader(global, workerPrivate);
 
   return fileReader.forget();
 }
 
--- a/dom/file/FileReaderSync.cpp
+++ b/dom/file/FileReaderSync.cpp
@@ -436,17 +436,17 @@ FileReaderSync::SyncRead(nsIInputStream*
   }
 
   // We need to proceed async.
   nsCOMPtr<nsIAsyncInputStream> asyncStream = do_QueryInterface(aStream);
   if (!asyncStream) {
     return rv;
   }
 
-  WorkerPrivate* workerPrivate = workers::GetCurrentThreadWorkerPrivate();
+  WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
   MOZ_ASSERT(workerPrivate);
 
   AutoSyncLoopHolder syncLoop(workerPrivate, Closing);
 
   nsCOMPtr<nsIEventTarget> syncLoopTarget = syncLoop.GetEventTarget();
   if (!syncLoopTarget) {
     // SyncLoop creation can fail if the worker is shutting down.
     return NS_ERROR_DOM_INVALID_STATE_ERR;
--- a/dom/file/ipc/IPCBlobInputStreamChild.cpp
+++ b/dom/file/ipc/IPCBlobInputStreamChild.cpp
@@ -10,18 +10,16 @@
 #include "mozilla/ipc/IPCStreamUtils.h"
 #include "mozilla/dom/WorkerHolder.h"
 #include "mozilla/dom/WorkerPrivate.h"
 #include "mozilla/dom/WorkerRunnable.h"
 
 namespace mozilla {
 namespace dom {
 
-using namespace workers;
-
 namespace {
 
 // This runnable is used in case the last stream is forgotten on the 'wrong'
 // thread.
 class ShutdownRunnable final : public CancelableRunnable
 {
 public:
   explicit ShutdownRunnable(IPCBlobInputStreamChild* aActor)
--- a/dom/file/nsHostObjectProtocolHandler.cpp
+++ b/dom/file/nsHostObjectProtocolHandler.cpp
@@ -19,16 +19,17 @@
 #include "mozilla/ModuleUtils.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/SystemGroup.h"
 #include "nsClassHashtable.h"
 #include "nsContentUtils.h"
 #include "nsError.h"
 #include "nsHostObjectURI.h"
 #include "nsIAsyncShutdown.h"
+#include "nsIException.h" // for nsIStackFrame
 #include "nsIMemoryReporter.h"
 #include "nsIPrincipal.h"
 #include "nsIUUIDGenerator.h"
 #include "nsNetUtil.h"
 
 #define RELEASING_TIMER 5000
 
 using namespace mozilla;
@@ -351,20 +352,19 @@ class BlobURLsReporter final : public ns
 
     // If we got a frame, we better have a current JSContext.  This is cheating
     // a bit; ideally we'd have our caller pass in a JSContext, or have
     // GetCurrentJSStack() hand out the JSContext it found.
     JSContext* cx = frame ? nsContentUtils::GetCurrentJSContext() : nullptr;
 
     for (uint32_t i = 0; frame; ++i) {
       nsString fileNameUTF16;
-      int32_t lineNumber = 0;
+      frame->GetFilename(cx, fileNameUTF16);
 
-      frame->GetFilename(cx, fileNameUTF16);
-      frame->GetLineNumber(cx, &lineNumber);
+      int32_t lineNumber = frame->GetLineNumber(cx);
 
       if (!fileNameUTF16.IsEmpty()) {
         NS_ConvertUTF16toUTF8 fileName(fileNameUTF16);
         stack += "js(";
         if (!origin.IsEmpty()) {
           // Make the file name root-relative for conciseness if possible.
           const char* originData;
           uint32_t originLen;
@@ -381,20 +381,17 @@ class BlobURLsReporter final : public ns
         stack += fileName;
         if (lineNumber > 0) {
           stack += ", line=";
           stack.AppendInt(lineNumber);
         }
         stack += ")/";
       }
 
-      nsCOMPtr<nsIStackFrame> caller;
-      nsresult rv = frame->GetCaller(cx, getter_AddRefs(caller));
-      NS_ENSURE_SUCCESS_VOID(rv);
-      caller.swap(frame);
+      frame = frame->GetCaller(cx);
     }
   }
 
  private:
   ~BlobURLsReporter() {}
 
   static void BuildPath(nsAutoCString& path,
                         nsCStringHashKey::KeyType aKey,
--- a/dom/indexedDB/ActorsChild.cpp
+++ b/dom/indexedDB/ActorsChild.cpp
@@ -67,18 +67,16 @@
 #endif // DEBUG || GC_ON_IPC_MESSAGES
 
 namespace mozilla {
 
 using ipc::PrincipalInfo;
 
 namespace dom {
 
-using namespace workers;
-
 namespace indexedDB {
 
 /*******************************************************************************
  * ThreadLocal
  ******************************************************************************/
 
 ThreadLocal::ThreadLocal(const nsID& aBackgroundChildLoggingId)
   : mLoggingInfo(aBackgroundChildLoggingId, 1, -1, 1)
--- a/dom/indexedDB/IDBObjectStore.cpp
+++ b/dom/indexedDB/IDBObjectStore.cpp
@@ -58,17 +58,16 @@
 // Include this last to avoid path problems on Windows.
 #include "ActorsChild.h"
 
 namespace mozilla {
 namespace dom {
 
 using namespace mozilla::dom::indexedDB;
 using namespace mozilla::dom::quota;
-using namespace mozilla::dom::workers;
 using namespace mozilla::ipc;
 
 struct IDBObjectStore::StructuredCloneWriteInfo
 {
   JSAutoStructuredCloneBuffer mCloneBuffer;
   nsTArray<StructuredCloneFile> mFiles;
   IDBDatabase* mDatabase;
   uint64_t mOffsetToKeyProp;
--- a/dom/indexedDB/IDBRequest.cpp
+++ b/dom/indexedDB/IDBRequest.cpp
@@ -35,17 +35,16 @@
 
 // Include this last to avoid path problems on Windows.
 #include "ActorsChild.h"
 
 namespace mozilla {
 namespace dom {
 
 using namespace mozilla::dom::indexedDB;
-using namespace mozilla::dom::workers;
 using namespace mozilla::ipc;
 
 namespace {
 
 NS_DEFINE_IID(kIDBRequestIID, PRIVATE_IDBREQUEST_IID);
 
 } // namespace
 
--- a/dom/indexedDB/IDBTransaction.cpp
+++ b/dom/indexedDB/IDBTransaction.cpp
@@ -28,17 +28,16 @@
 
 // Include this last to avoid path problems on Windows.
 #include "ActorsChild.h"
 
 namespace mozilla {
 namespace dom {
 
 using namespace mozilla::dom::indexedDB;
-using namespace mozilla::dom::workers;
 using namespace mozilla::ipc;
 
 class IDBTransaction::WorkerHolder final : public mozilla::dom::WorkerHolder
 {
   WorkerPrivate* mWorkerPrivate;
 
   // The IDBTransaction owns this object so we only need a weak reference back
   // to it.
--- a/dom/indexedDB/IndexedDatabaseManager.cpp
+++ b/dom/indexedDB/IndexedDatabaseManager.cpp
@@ -68,17 +68,16 @@
 #define LOW_DISK_SPACE_DATA_FULL "full"
 #define LOW_DISK_SPACE_DATA_FREE "free"
 
 namespace mozilla {
 namespace dom {
 namespace indexedDB {
 
 using namespace mozilla::dom::quota;
-using namespace mozilla::dom::workers;
 using namespace mozilla::ipc;
 
 class FileManagerInfo
 {
 public:
   already_AddRefed<FileManager>
   GetFileManager(PersistenceType aPersistenceType,
                  const nsAString& aName) const;
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -229,17 +229,16 @@
 
 #ifdef MOZ_CODE_COVERAGE
 #include "mozilla/CodeCoverageHandler.h"
 #endif
 
 using namespace mozilla;
 using namespace mozilla::docshell;
 using namespace mozilla::dom::ipc;
-using namespace mozilla::dom::workers;
 using namespace mozilla::media;
 using namespace mozilla::embedding;
 using namespace mozilla::gmp;
 using namespace mozilla::hal_sandbox;
 using namespace mozilla::ipc;
 using namespace mozilla::intl;
 using namespace mozilla::layers;
 using namespace mozilla::layout;
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -142,17 +142,16 @@
     NS_LITERAL_STRING("chrome://global/content/BrowserElementChild.js")
 
 #define TABC_LOG(...)
 // #define TABC_LOG(...) printf_stderr("TABC: " __VA_ARGS__)
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::dom::ipc;
-using namespace mozilla::dom::workers;
 using namespace mozilla::ipc;
 using namespace mozilla::layers;
 using namespace mozilla::layout;
 using namespace mozilla::docshell;
 using namespace mozilla::widget;
 using namespace mozilla::jsipc;
 using mozilla::layers::GeckoContentController;
 
--- a/dom/messagechannel/MessagePort.cpp
+++ b/dom/messagechannel/MessagePort.cpp
@@ -37,18 +37,16 @@
 #include "nsIPresShell.h"
 #include "nsISupportsPrimitives.h"
 #include "nsServiceManagerUtils.h"
 
 #ifdef XP_WIN
 #undef PostMessage
 #endif
 
-using namespace mozilla::dom::workers;
-
 namespace mozilla {
 namespace dom {
 
 class PostMessageRunnable final : public CancelableRunnable
 {
   friend class MessagePort;
 
 public:
--- a/dom/notification/Notification.cpp
+++ b/dom/notification/Notification.cpp
@@ -56,18 +56,16 @@
 #include "nsStructuredCloneContainer.h"
 #include "nsThreadUtils.h"
 #include "nsToolkitCompsCID.h"
 #include "nsXULAppAPI.h"
 
 namespace mozilla {
 namespace dom {
 
-using namespace workers;
-
 struct NotificationStrings
 {
   const nsString mID;
   const nsString mTitle;
   const nsString mDir;
   const nsString mLang;
   const nsString mBody;
   const nsString mTag;
--- a/dom/notification/Notification.h
+++ b/dom/notification/Notification.h
@@ -365,17 +365,17 @@ protected:
     }
     return NotificationDirection::Auto;
   }
 
   static nsresult GetOrigin(nsIPrincipal* aPrincipal, nsString& aOrigin);
 
   void GetAlertName(nsAString& aRetval)
   {
-    workers::AssertIsOnMainThread();
+    AssertIsOnMainThread();
     if (mAlertName.IsEmpty()) {
       SetAlertName();
     }
     aRetval = mAlertName;
   }
 
   void GetScope(nsAString& aScope)
   {
--- a/dom/performance/Performance.cpp
+++ b/dom/performance/Performance.cpp
@@ -536,17 +536,17 @@ Performance::QueueEntry(PerformanceEntry
 
 /* static */ bool
 Performance::IsObserverEnabled(JSContext* aCx, JSObject* aGlobal)
 {
   if (NS_IsMainThread()) {
     return Preferences::GetBool("dom.enable_performance_observer", false);
   }
 
-  WorkerPrivate* workerPrivate = workers::GetCurrentThreadWorkerPrivate();
+  WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
   MOZ_ASSERT(workerPrivate);
   workerPrivate->AssertIsOnWorkerThread();
 
   RefPtr<PrefEnabledRunnable> runnable =
     new PrefEnabledRunnable(workerPrivate,
                             NS_LITERAL_CSTRING("dom.enable_performance_observer"));
 
   return runnable->Dispatch() && runnable->IsEnabled();
--- a/dom/performance/PerformanceObserver.cpp
+++ b/dom/performance/PerformanceObserver.cpp
@@ -83,17 +83,17 @@ PerformanceObserver::Constructor(const G
     }
 
     RefPtr<PerformanceObserver> observer =
       new PerformanceObserver(ownerWindow, aCb);
     return observer.forget();
   }
 
   JSContext* cx = aGlobal.Context();
-  WorkerPrivate* workerPrivate = workers::GetWorkerPrivateFromContext(cx);
+  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
   MOZ_ASSERT(workerPrivate);
 
   RefPtr<PerformanceObserver> observer =
     new PerformanceObserver(workerPrivate, aCb);
   return observer.forget();
 }
 
 JSObject*
--- a/dom/promise/Promise.cpp
+++ b/dom/promise/Promise.cpp
@@ -489,17 +489,17 @@ Promise::ReportRejectedPromise(JSContext
   if (!report.init(aCx, result, js::ErrorReport::NoSideEffects)) {
     JS_ClearPendingException(aCx);
     return;
   }
 
   RefPtr<xpc::ErrorReport> xpcReport = new xpc::ErrorReport();
   bool isMainThread = MOZ_LIKELY(NS_IsMainThread());
   bool isChrome = isMainThread ? nsContentUtils::IsSystemPrincipal(nsContentUtils::ObjectPrincipal(aPromise))
-                               : workers::GetCurrentThreadWorkerPrivate()->IsChromeWorker();
+                               : GetCurrentThreadWorkerPrivate()->IsChromeWorker();
   nsGlobalWindowInner* win = isMainThread
     ? xpc::WindowGlobalOrNull(aPromise)
     : nullptr;
   xpcReport->Init(report.report(), report.toStringResult().c_str(), isChrome,
                   win ? win->AsInner()->WindowID() : 0);
 
   // Now post an event to do the real reporting async
   NS_DispatchToMainThread(new AsyncErrorReporter(xpcReport));
@@ -757,17 +757,17 @@ PromiseWorkerProxy::~PromiseWorkerProxy(
   MOZ_ASSERT(!mWorkerPromise);
   MOZ_ASSERT(!mWorkerPrivate);
 }
 
 void
 PromiseWorkerProxy::CleanProperties()
 {
 #ifdef DEBUG
-  WorkerPrivate* worker = workers::GetCurrentThreadWorkerPrivate();
+  WorkerPrivate* worker = GetCurrentThreadWorkerPrivate();
   MOZ_ASSERT(worker);
   worker->AssertIsOnWorkerThread();
 #endif
   // Ok to do this unprotected from Create().
   // CleanUp() holds the lock before calling this.
   mCleanedUp = true;
   mWorkerPromise = nullptr;
   mWorkerPrivate = nullptr;
@@ -810,17 +810,17 @@ PromiseWorkerProxy::GetWorkerPrivate() c
 
   return mWorkerPrivate;
 }
 
 Promise*
 PromiseWorkerProxy::WorkerPromise() const
 {
 #ifdef DEBUG
-  WorkerPrivate* worker = workers::GetCurrentThreadWorkerPrivate();
+  WorkerPrivate* worker = GetCurrentThreadWorkerPrivate();
   MOZ_ASSERT(worker);
   worker->AssertIsOnWorkerThread();
 #endif
   MOZ_ASSERT(mWorkerPromise);
   return mWorkerPromise;
 }
 
 void
--- a/dom/push/PushManager.cpp
+++ b/dom/push/PushManager.cpp
@@ -27,19 +27,16 @@
 #include "nsIPushService.h"
 
 #include "nsComponentManagerUtils.h"
 #include "nsContentUtils.h"
 
 namespace mozilla {
 namespace dom {
 
-using namespace workers;
-using workers::AssertIsOnMainThread;
-
 namespace {
 
 nsresult
 GetPermissionState(nsIPrincipal* aPrincipal,
                    PushPermissionState& aState)
 {
   nsCOMPtr<nsIPermissionManager> permManager =
     mozilla::services::GetPermissionManager();
--- a/dom/push/PushNotifier.cpp
+++ b/dom/push/PushNotifier.cpp
@@ -19,18 +19,16 @@
 
 #include "mozilla/dom/BodyUtil.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/ContentParent.h"
 
 namespace mozilla {
 namespace dom {
 
-using workers::AssertIsOnMainThread;
-
 PushNotifier::PushNotifier()
 {}
 
 PushNotifier::~PushNotifier()
 {}
 
 NS_IMPL_CYCLE_COLLECTION_0(PushNotifier)
 
--- a/dom/push/PushSubscription.cpp
+++ b/dom/push/PushSubscription.cpp
@@ -18,18 +18,16 @@
 #include "mozilla/dom/PushUtil.h"
 #include "mozilla/dom/WorkerCommon.h"
 #include "mozilla/dom/WorkerPrivate.h"
 #include "mozilla/dom/WorkerScope.h"
 
 namespace mozilla {
 namespace dom {
 
-using namespace workers;
-
 namespace {
 
 class UnsubscribeResultCallback final : public nsIUnsubscribeResultCallback
 {
 public:
   NS_DECL_ISUPPORTS
 
   explicit UnsubscribeResultCallback(Promise* aPromise)
--- a/dom/quota/StorageManager.cpp
+++ b/dom/quota/StorageManager.cpp
@@ -14,18 +14,16 @@
 #include "mozilla/ErrorResult.h"
 #include "mozilla/EventStateManager.h"
 #include "mozilla/Telemetry.h"
 #include "nsContentPermissionHelper.h"
 #include "nsIQuotaCallbacks.h"
 #include "nsIQuotaRequests.h"
 #include "nsPIDOMWindow.h"
 
-using namespace mozilla::dom::workers;
-
 namespace mozilla {
 namespace dom {
 
 namespace {
 
 // This class is used to get quota usage, request persist and check persisted
 // status callbacks.
 class RequestResolver final
--- a/dom/script/ScriptSettings.cpp
+++ b/dom/script/ScriptSettings.cpp
@@ -539,17 +539,17 @@ WarningOnlyErrorReporter(JSContext* aCx,
   if (!NS_IsMainThread()) {
     // Reporting a warning on workers is a bit complicated because we have to
     // climb our parent chain until we get to the main thread.  So go ahead and
     // just go through the worker ReportError codepath here.
     //
     // That said, it feels like we should be able to short-circuit things a bit
     // here by posting an appropriate runnable to the main thread directly...
     // Worth looking into sometime.
-    WorkerPrivate* worker = workers::GetWorkerPrivateFromContext(aCx);
+    WorkerPrivate* worker = GetWorkerPrivateFromContext(aCx);
     MOZ_ASSERT(worker);
 
     worker->ReportError(aCx, JS::ConstUTF8CharsZ(), aRep);
     return;
   }
 
   RefPtr<xpc::ErrorReport> xpcReport = new xpc::ErrorReport();
   nsGlobalWindowInner* win = xpc::CurrentWindowOrNull(aCx);
@@ -576,17 +576,17 @@ AutoJSAPI::ReportException()
   // requires us to be in a compartment when we fetch the pending exception.
   // In this case, we enter the privileged junk scope and don't dispatch any
   // error events.
   JS::Rooted<JSObject*> errorGlobal(cx(), JS::CurrentGlobalOrNull(cx()));
   if (!errorGlobal) {
     if (mIsMainThread) {
       errorGlobal = xpc::PrivilegedJunkScope();
     } else {
-      errorGlobal = workers::GetCurrentThreadWorkerGlobal();
+      errorGlobal = GetCurrentThreadWorkerGlobal();
     }
   }
   JSAutoCompartment ac(cx(), errorGlobal);
   JS::Rooted<JS::Value> exn(cx());
   js::ErrorReport jsReport(cx());
   if (StealException(&exn) &&
       jsReport.init(cx(), exn, js::ErrorReport::WithSideEffects)) {
     if (mIsMainThread) {
@@ -612,17 +612,17 @@ AutoJSAPI::ReportException()
           xpc::FindExceptionStackForConsoleReport(inner, exn));
         xpcReport->LogToConsoleWithStack(stack);
       }
     } else {
       // On a worker, we just use the worker error reporting mechanism and don't
       // bother with xpc::ErrorReport.  This will ensure that all the right
       // events (which are a lot more complicated than in the window case) get
       // fired.
-      WorkerPrivate* worker = workers::GetCurrentThreadWorkerPrivate();
+      WorkerPrivate* worker = GetCurrentThreadWorkerPrivate();
       MOZ_ASSERT(worker);
       MOZ_ASSERT(worker->GetJSContext() == cx());
       // Before invoking ReportError, put the exception back on the context,
       // because it may want to put it in its error events and has no other way
       // to get hold of it.  After we invoke ReportError, clear the exception on
       // cx(), just in case ReportError didn't.
       JS_SetPendingException(cx(), exn);
       worker->ReportError(cx(), jsReport.toStringResult(), jsReport.report());
--- a/dom/serviceworkers/ServiceWorkerEvents.cpp
+++ b/dom/serviceworkers/ServiceWorkerEvents.cpp
@@ -46,17 +46,16 @@
 #include "mozilla/dom/WorkerPrivate.h"
 
 #include "js/Conversions.h"
 #include "js/TypeDecls.h"
 #include "xpcpublic.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
-using namespace mozilla::dom::workers;
 
 namespace {
 
 void
 AsyncLog(nsIInterceptedChannel *aInterceptedChannel,
          const nsACString& aRespondWithScriptSpec,
          uint32_t aRespondWithLineNumber, uint32_t aRespondWithColumnNumber,
          const nsACString& aMessageName, const nsTArray<nsString>& aParams)
--- a/dom/serviceworkers/ServiceWorkerRegistrar.cpp
+++ b/dom/serviceworkers/ServiceWorkerRegistrar.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ServiceWorkerRegistrar.h"
 #include "mozilla/dom/ServiceWorkerRegistrarTypes.h"
+#include "mozilla/dom/DOMException.h"
 #include "mozilla/net/MozURL.h"
 
 #include "nsIEventTarget.h"
 #include "nsIInputStream.h"
 #include "nsILineInputStream.h"
 #include "nsIObserverService.h"
 #include "nsIOutputStream.h"
 #include "nsISafeOutputStream.h"
@@ -1130,21 +1131,19 @@ ServiceWorkerRegistrar::GetState(nsIProp
 {
   return NS_OK;
 }
 
 #define RELEASE_ASSERT_SUCCEEDED(rv, name) do { \
     if (NS_FAILED(rv)) {                                                       \
       if (rv == NS_ERROR_XPC_JAVASCRIPT_ERROR_WITH_DETAILS) {                  \
         if (auto* context = CycleCollectedJSContext::Get()) {                  \
-          if (nsCOMPtr<nsIException> exn = context->GetPendingException()) {   \
-            nsAutoCString msg;                                                 \
-            if (NS_SUCCEEDED(exn->GetMessageMoz(msg))) {                       \
-              MOZ_CRASH_UNSAFE_PRINTF("Failed to get " name ": %s", msg.get());\
-            }                                                                  \
+          if (RefPtr<Exception> exn = context->GetPendingException()) {        \
+            MOZ_CRASH_UNSAFE_PRINTF("Failed to get " name ": %s",              \
+                                    exn->GetMessageMoz().get());               \
           }                                                                    \
         }                                                                      \
       }                                                                        \
                                                                                \
       nsAutoCString errorName;                                                 \
       GetErrorName(rv, errorName);                                             \
       MOZ_CRASH_UNSAFE_PRINTF("Failed to get " name ": %s",                    \
                               errorName.get());                                \
--- a/dom/serviceworkers/ServiceWorkerRegistration.cpp
+++ b/dom/serviceworkers/ServiceWorkerRegistration.cpp
@@ -27,18 +27,16 @@
 #include "ServiceWorkerManager.h"
 
 #include "nsIDocument.h"
 #include "nsIServiceWorkerManager.h"
 #include "nsISupportsPrimitives.h"
 #include "nsPIDOMWindow.h"
 #include "nsContentUtils.h"
 
-using namespace mozilla::dom::workers;
-
 namespace mozilla {
 namespace dom {
 
 ////////////////////////////////////////////////////
 // Main Thread implementation
 
 class ServiceWorkerRegistrationMainThread final : public ServiceWorkerRegistration,
                                                   public ServiceWorkerRegistrationListener
--- a/dom/svg/SVGTransformableElement.cpp
+++ b/dom/svg/SVGTransformableElement.cpp
@@ -119,17 +119,17 @@ SVGTransformableElement::GetAnimateMotio
 {
   return mAnimateMotionTransform.get();
 }
 
 void
 SVGTransformableElement::SetAnimateMotionTransform(const gfx::Matrix* aMatrix)
 {
   if ((!aMatrix && !mAnimateMotionTransform) ||
-      (aMatrix && mAnimateMotionTransform && *aMatrix == *mAnimateMotionTransform)) {
+      (aMatrix && mAnimateMotionTransform && aMatrix->FuzzyEquals(*mAnimateMotionTransform))) {
     return;
   }
   bool transformSet = mTransforms && mTransforms->IsExplicitlySet();
   bool prevSet = mAnimateMotionTransform || transformSet;
   mAnimateMotionTransform = aMatrix ? new gfx::Matrix(*aMatrix) : nullptr;
   bool nowSet = mAnimateMotionTransform || transformSet;
   int32_t modType;
   if (prevSet && !nowSet) {
--- a/dom/url/URLWorker.cpp
+++ b/dom/url/URLWorker.cpp
@@ -15,19 +15,16 @@
 #include "nsURLHelper.h"
 
 namespace mozilla {
 
 using net::nsStandardURL;
 
 namespace dom {
 
-using namespace workers;
-using workers::AssertIsOnMainThread;
-
 // Proxy class to forward all the requests to a URLMainThread object.
 class URLWorker::URLProxy final
 {
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(URLProxy)
 
   explicit URLProxy(already_AddRefed<URLMainThread> aURL)
     : mURL(aURL)
--- a/dom/webidl/DOMException.webidl
+++ b/dom/webidl/DOMException.webidl
@@ -42,17 +42,17 @@ interface ExceptionMembers
   [ChromeOnly, Exposed=Window]
   readonly attribute StackFrame?             location;
 
   // Arbitary data for the implementation.
   [Exposed=Window]
   readonly attribute nsISupports?            data;
 
   // Formatted exception stack
-  [Throws, Replaceable]
+  [Replaceable]
   readonly attribute DOMString               stack;
 };
 
 [NoInterfaceObject, Exposed=(Window,Worker)]
 interface Exception {
   // The name of the error code (ie, a string repr of |result|).
   readonly attribute DOMString               name;
   // A custom message set by the thrower.
--- a/dom/webidl/DOMRequest.webidl
+++ b/dom/webidl/DOMRequest.webidl
@@ -19,11 +19,14 @@ interface DOMRequestShared {
 [Exposed=(Window,Worker,System)]
 interface DOMRequest : EventTarget {
   // The [TreatNonCallableAsNull] annotation is required since then() should do
   // nothing instead of throwing errors when non-callable arguments are passed.
   // See documentation for Promise.then to see why we return "any".
   [NewObject, Throws]
   any then([TreatNonCallableAsNull] optional AnyCallback? fulfillCallback = null,
            [TreatNonCallableAsNull] optional AnyCallback? rejectCallback = null);
+
+  [ChromeOnly]
+  void fireDetailedError(DOMException aError);
 };
 
 DOMRequest implements DOMRequestShared;
--- a/dom/webidl/InspectorUtils.webidl
+++ b/dom/webidl/InspectorUtils.webidl
@@ -53,18 +53,18 @@ namespace InspectorUtils {
   const unsigned long TYPE_NUMBER = 10;
   [Throws] boolean cssPropertySupportsType(DOMString property, unsigned long type);
 
   boolean isIgnorableWhitespace(CharacterData dataNode);
   Node? getParentForNode(Node node, boolean showingAnonymousContent);
   [NewObject] NodeList getChildrenForNode(Node node,
                                           boolean showingAnonymousContent);
   sequence<DOMString> getBindingURLs(Element element);
-  [Throws] void setContentState(Element element, unsigned long long state);
-  [Throws] void removeContentState(
+  [Throws] boolean setContentState(Element element, unsigned long long state);
+  [Throws] boolean removeContentState(
       Element element,
       unsigned long long state,
       optional boolean clearActiveDocument = false);
   unsigned long long getContentState(Element element);
   [NewObject, Throws] sequence<InspectorFontFace> getUsedFontFaces(Range range);
   sequence<DOMString> getCSSPseudoElementNames();
   void addPseudoClassLock(Element element,
                           DOMString pseudoClass,
--- a/dom/webidl/XSLTProcessor.webidl
+++ b/dom/webidl/XSLTProcessor.webidl
@@ -41,17 +41,17 @@ interface XSLTProcessor {
      * @param source The node to be transformed
      * @return Document The result of the transformation
      */
     [CEReactions, Throws]
     Document transformToDocument(Node source);
 
     /**
      * Sets a parameter to be used in subsequent transformations with this
-     * nsIXSLTProcessor. If the parameter doesn't exist in the stylesheet the
+     * XSLTProcessor. If the parameter doesn't exist in the stylesheet the
      * parameter will be ignored.
      *
      * @param namespaceURI The namespaceURI of the XSLT parameter
      * @param localName    The local name of the XSLT parameter
      * @param value        The new value of the XSLT parameter
      */
     [Throws]
     void setParameter([TreatNullAs=EmptyString] DOMString namespaceURI,
@@ -76,24 +76,24 @@ interface XSLTProcessor {
      * @param namespaceURI The namespaceURI of the XSLT parameter
      * @param localName    The local name of the XSLT parameter
      */
     [Throws]
     void removeParameter([TreatNullAs=EmptyString] DOMString namespaceURI,
                          DOMString localName);
 
     /**
-     * Removes all set parameters from this nsIXSLTProcessor. This will make
+     * Removes all set parameters from this XSLTProcessor. This will make
      * the processor use the default-value for all parameters as specified in
      * the stylesheet.
      */
     void clearParameters();
 
     /**
-     * Remove all parameters and stylesheets from this nsIXSLTProcessor.
+     * Remove all parameters and stylesheets from this XSLTProcessor.
      */
     void reset();
 
     /**
     * Disables all loading of external documents, such as from
     * <xsl:import> and document()
     * Defaults to off and is *not* reset by calls to reset()
     */
--- a/dom/websocket/WebSocket.cpp
+++ b/dom/websocket/WebSocket.cpp
@@ -63,17 +63,16 @@
 #include "nsWeakReference.h"
 
 #define OPEN_EVENT_STRING NS_LITERAL_STRING("open")
 #define MESSAGE_EVENT_STRING NS_LITERAL_STRING("message")
 #define ERROR_EVENT_STRING NS_LITERAL_STRING("error")
 #define CLOSE_EVENT_STRING NS_LITERAL_STRING("close")
 
 using namespace mozilla::net;
-using namespace mozilla::dom::workers;
 
 namespace mozilla {
 namespace dom {
 
 class WebSocketImpl final : public nsIInterfaceRequestor
                           , public nsIWebSocketListener
                           , public nsIObserver
                           , public nsSupportsWeakReference
--- a/dom/workers/MessageEventRunnable.cpp
+++ b/dom/workers/MessageEventRunnable.cpp
@@ -125,17 +125,17 @@ MessageEventRunnable::WorkerRun(JSContex
     }
 
     aWorkerPrivate->AssertInnerWindowIsCorrect();
 
     return DispatchDOMEvent(aCx, aWorkerPrivate, aWorkerPrivate,
                             !aWorkerPrivate->GetParent());
   }
 
-  MOZ_ASSERT(aWorkerPrivate == workers::GetWorkerPrivateFromContext(aCx));
+  MOZ_ASSERT(aWorkerPrivate == GetWorkerPrivateFromContext(aCx));
 
   return DispatchDOMEvent(aCx, aWorkerPrivate, aWorkerPrivate->GlobalScope(),
                           false);
 }
 
 void
 MessageEventRunnable::DispatchError(JSContext* aCx,
                                     DOMEventTargetHelper* aTarget)
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -79,17 +79,16 @@
 #define WORKERS_SHUTDOWN_TOPIC "web-workers-shutdown"
 
 namespace mozilla {
 
 using namespace ipc;
 
 namespace dom {
 
-using namespace workers;
 using namespace workerinternals;
 
 namespace workerinternals {
 
 // The size of the worker runtime heaps in bytes. May be changed via pref.
 #define WORKER_DEFAULT_RUNTIME_HEAPSIZE 32 * 1024 * 1024
 
 // The size of the generational GC nursery for workers, in bytes.
@@ -130,17 +129,17 @@ static_assert(MAX_WORKERS_PER_DOMAIN >= 
 #define GC_REQUEST_OBSERVER_TOPIC "child-gc-request"
 #define CC_REQUEST_OBSERVER_TOPIC "child-cc-request"
 #define MEMORY_PRESSURE_OBSERVER_TOPIC "memory-pressure"
 
 #define BROADCAST_ALL_WORKERS(_func, ...)                                      \
   PR_BEGIN_MACRO                                                               \
     AssertIsOnMainThread();                                                    \
                                                                                \
-    AutoTArray<WorkerPrivate*, 100> workers;                                 \
+    AutoTArray<WorkerPrivate*, 100> workers;                                   \
     {                                                                          \
       MutexAutoLock lock(mMutex);                                              \
                                                                                \
       AddAllTopLevelWorkersToArray(workers);                                   \
     }                                                                          \
                                                                                \
     if (!workers.IsEmpty()) {                                                  \
       for (uint32_t index = 0; index < workers.Length(); index++) {            \
@@ -930,24 +929,26 @@ PreserveWrapper(JSContext *cx, JSObject 
 
     return mozilla::dom::TryPreserveWrapper(obj);
 }
 
 JSObject*
 Wrap(JSContext *cx, JS::HandleObject existing, JS::HandleObject obj)
 {
   JSObject* targetGlobal = JS::CurrentGlobalOrNull(cx);
-  if (!IsDebuggerGlobal(targetGlobal) && !IsDebuggerSandbox(targetGlobal)) {
+  if (!IsWorkerDebuggerGlobal(targetGlobal) &&
+      !IsWorkerDebuggerSandbox(targetGlobal)) {
     MOZ_CRASH("There should be no edges from the debuggee to the debugger.");
   }
 
   JSObject* originGlobal = js::GetGlobalForObjectCrossCompartment(obj);
 
   const js::Wrapper* wrapper = nullptr;
-  if (IsDebuggerGlobal(originGlobal) || IsDebuggerSandbox(originGlobal)) {
+  if (IsWorkerDebuggerGlobal(originGlobal) ||
+      IsWorkerDebuggerSandbox(originGlobal)) {
     wrapper = &js::CrossCompartmentWrapper::singleton;
   } else {
     wrapper = &js::OpaqueCrossCompartmentWrapper::singleton;
   }
 
   if (existing) {
     js::Wrapper::Renew(existing, obj, wrapper);
   }
@@ -1118,30 +1119,31 @@ public:
   {
     RefPtr<nsIRunnable> runnable(aRunnable);
 
     MOZ_ASSERT(!NS_IsMainThread());
     MOZ_ASSERT(runnable);
 
     std::queue<nsCOMPtr<nsIRunnable>>* microTaskQueue = nullptr;
 
-    JSContext* cx = GetCurrentThreadJSContext();
+    JSContext* cx = GetCurrentWorkerThreadJSContext();
     NS_ASSERTION(cx, "This should never be null!");
 
     JS::Rooted<JSObject*> global(cx, JS::CurrentGlobalOrNull(cx));
     NS_ASSERTION(global, "This should never be null!");
 
     // On worker threads, if the current global is the worker global, we use the
     // main promise micro task queue. Otherwise, the current global must be
     // either the debugger global or a debugger sandbox, and we use the debugger
     // promise micro task queue instead.
     if (IsWorkerGlobal(global)) {
       microTaskQueue = &mPromiseMicroTaskQueue;
     } else {
-      MOZ_ASSERT(IsDebuggerGlobal(global) || IsDebuggerSandbox(global));
+      MOZ_ASSERT(IsWorkerDebuggerGlobal(global) ||
+                 IsWorkerDebuggerSandbox(global));
 
       microTaskQueue = &mDebuggerPromiseMicroTaskQueue;
     }
 
     microTaskQueue->push(runnable.forget());
   }
 
 private:
@@ -2807,18 +2809,16 @@ WorkerThreadPrimaryRunnable::FinishedRun
     MOZ_ALWAYS_SUCCEEDS(thread->Shutdown());
   }
 
   return NS_OK;
 }
 
 } // workerinternals namespace
 
-namespace workers {
-
 void
 CancelWorkersForWindow(nsPIDOMWindowInner* aWindow)
 {
   AssertIsOnMainThread();
   RuntimeService* runtime = RuntimeService::GetService();
   if (runtime) {
     runtime->CancelWorkersForWindow(aWindow);
   }
@@ -2901,17 +2901,17 @@ GetCurrentThreadWorkerPrivate()
 
 bool
 IsCurrentThreadRunningChromeWorker()
 {
   return GetCurrentThreadWorkerPrivate()->UsesSystemPrincipal();
 }
 
 JSContext*
-GetCurrentThreadJSContext()
+GetCurrentWorkerThreadJSContext()
 {
   WorkerPrivate* wp = GetCurrentThreadWorkerPrivate();
   if (!wp) {
     return nullptr;
   }
   return wp->GetJSContext();
 }
 
@@ -2924,22 +2924,10 @@ GetCurrentThreadWorkerGlobal()
   }
   WorkerGlobalScope* scope = wp->GlobalScope();
   if (!scope) {
     return nullptr;
   }
   return scope->GetGlobalJSObject();
 }
 
-#ifdef DEBUG
-
-void
-AssertIsOnMainThread()
-{
-  MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
-}
-
-#endif
-
-} // workers namespace
-
 } // dom namespace
 } // mozilla namespace
--- a/dom/workers/RuntimeService.h
+++ b/dom/workers/RuntimeService.h
@@ -168,24 +168,24 @@ public:
   }
 
   void
   NoteIdleThread(WorkerThread* aThread);
 
   static void
   GetDefaultJSSettings(workerinternals::JSSettings& aSettings)
   {
-    workers::AssertIsOnMainThread();
+    AssertIsOnMainThread();
     aSettings = sDefaultJSSettings;
   }
 
   static void
   SetDefaultContextOptions(const JS::ContextOptions& aContextOptions)
   {
-    workers::AssertIsOnMainThread();
+    AssertIsOnMainThread();
     sDefaultJSSettings.contextOptions = aContextOptions;
   }
 
   void
   UpdateAppNameOverridePreference(const nsAString& aValue);
 
   void
   UpdateAppVersionOverridePreference(const nsAString& aValue);
@@ -197,28 +197,28 @@ public:
   UpdateAllWorkerContextOptions();
 
   void
   UpdateAllWorkerLanguages(const nsTArray<nsString>& aLanguages);
 
   static void
   SetDefaultJSGCSettings(JSGCParamKey aKey, uint32_t aValue)
   {
-    workers::AssertIsOnMainThread();
+    AssertIsOnMainThread();
     sDefaultJSSettings.ApplyGCSetting(aKey, aValue);
   }
 
   void
   UpdateAllWorkerMemoryParameter(JSGCParamKey aKey, uint32_t aValue);
 
 #ifdef JS_GC_ZEAL
   static void
   SetDefaultGCZeal(uint8_t aGCZeal, uint32_t aFrequency)
   {
-    workers::AssertIsOnMainThread();
+    AssertIsOnMainThread();
     sDefaultJSSettings.gcZeal = aGCZeal;
     sDefaultJSSettings.gcZealFrequency = aFrequency;
   }
 
   void
   UpdateAllWorkerGCZeal();
 #endif
 
--- a/dom/workers/ScriptLoader.cpp
+++ b/dom/workers/ScriptLoader.cpp
@@ -75,18 +75,16 @@
 
 using mozilla::dom::cache::Cache;
 using mozilla::dom::cache::CacheStorage;
 using mozilla::ipc::PrincipalInfo;
 
 namespace mozilla {
 namespace dom {
 
-using namespace workers;
-
 namespace {
 
 nsIURI*
 GetBaseURI(bool aIsMainScript, WorkerPrivate* aWorkerPrivate)
 {
   MOZ_ASSERT(aWorkerPrivate);
   nsIURI* baseURI;
   WorkerPrivate* parentWorker = aWorkerPrivate->GetParent();
--- a/dom/workers/WorkerCommon.h
+++ b/dom/workers/WorkerCommon.h
@@ -13,40 +13,29 @@
 
 class nsPIDOMWindowInner;
 
 namespace mozilla {
 namespace dom {
 
 class WorkerPrivate;
 
-namespace workers {
-
 // All of these are implemented in RuntimeService.cpp
 
-#ifdef DEBUG
-void
-AssertIsOnMainThread();
-#else
-inline void
-AssertIsOnMainThread()
-{ }
-#endif
-
 WorkerPrivate*
 GetWorkerPrivateFromContext(JSContext* aCx);
 
 WorkerPrivate*
 GetCurrentThreadWorkerPrivate();
 
 bool
 IsCurrentThreadRunningChromeWorker();
 
 JSContext*
-GetCurrentThreadJSContext();
+GetCurrentWorkerThreadJSContext();
 
 JSObject*
 GetCurrentThreadWorkerGlobal();
 
 void
 CancelWorkersForWindow(nsPIDOMWindowInner* aWindow);
 
 void
@@ -62,18 +51,17 @@ void
 ResumeWorkersForWindow(nsPIDOMWindowInner* aWindow);
 
 // All of these are implemented in WorkerScope.cpp
 
 bool
 IsWorkerGlobal(JSObject* global);
 
 bool
-IsDebuggerGlobal(JSObject* global);
+IsWorkerDebuggerGlobal(JSObject* global);
 
 bool
-IsDebuggerSandbox(JSObject* object);
+IsWorkerDebuggerSandbox(JSObject* object);
 
-} // workers namespace
 } // dom namespace
 } // mozilla namespace
 
 #endif // mozilla_dom_workers_WorkerCommon_h
--- a/dom/workers/WorkerError.cpp
+++ b/dom/workers/WorkerError.cpp
@@ -95,17 +95,17 @@ public:
           WorkerGlobalScope* globalScope = nullptr;
           UNWRAP_OBJECT(WorkerGlobalScope, &global, globalScope);
 
           if (!globalScope) {
             WorkerDebuggerGlobalScope* globalScope = nullptr;
             UNWRAP_OBJECT(WorkerDebuggerGlobalScope, &global, globalScope);
 
             MOZ_ASSERT_IF(globalScope, globalScope->GetWrapperPreserveColor() == global);
-            if (globalScope || IsDebuggerSandbox(global)) {
+            if (globalScope || IsWorkerDebuggerSandbox(global)) {
               aWorkerPrivate->ReportErrorToDebugger(aReport.mFilename, aReport.mLineNumber,
                                                     aReport.mMessage);
               return;
             }
 
             MOZ_ASSERT(SimpleGlobalObject::SimpleGlobalType(global) ==
                          SimpleGlobalObject::GlobalType::BindingDetail);
             // XXXbz We should really log this to console, but unwinding out of
@@ -351,17 +351,17 @@ WorkerErrorReport::ReportError(JSContext
         WorkerGlobalScope* globalScope = nullptr;
         UNWRAP_OBJECT(WorkerGlobalScope, &global, globalScope);
 
         if (!globalScope) {
           WorkerDebuggerGlobalScope* globalScope = nullptr;
           UNWRAP_OBJECT(WorkerDebuggerGlobalScope, &global, globalScope);
 
           MOZ_ASSERT_IF(globalScope, globalScope->GetWrapperPreserveColor() == global);
-          if (globalScope || IsDebuggerSandbox(global)) {
+          if (globalScope || IsWorkerDebuggerSandbox(global)) {
             aWorkerPrivate->ReportErrorToDebugger(aReport.mFilename, aReport.mLineNumber,
                                                   aReport.mMessage);
             return;
           }
 
           MOZ_ASSERT(SimpleGlobalObject::SimpleGlobalType(global) ==
                        SimpleGlobalObject::GlobalType::BindingDetail);
           // XXXbz We should really log this to console, but unwinding out of
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -91,17 +91,16 @@ TimeoutsLog()
 #define LOG(log, _args) MOZ_LOG(log, LogLevel::Debug, _args);
 
 namespace mozilla {
 
 using namespace ipc;
 
 namespace dom {
 
-using namespace workers;
 using namespace workerinternals;
 
 MOZ_DEFINE_MALLOC_SIZE_OF(JsWorkerMallocSizeOf)
 
 namespace {
 
 #ifdef DEBUG
 
--- a/dom/workers/WorkerPrivate.h
+++ b/dom/workers/WorkerPrivate.h
@@ -401,17 +401,17 @@ public:
   {
     mMutex.AssertCurrentThreadOwns();
     return mParentStatus;
   }
 
   nsIScriptContext*
   GetScriptContext() const
   {
-    workers::AssertIsOnMainThread();
+    AssertIsOnMainThread();
     return mLoadInfo.mScriptContext;
   }
 
   const nsString&
   ScriptURL() const
   {
     return mScriptURL;
   }
@@ -450,35 +450,35 @@ public:
   ServiceWorkerScope() const
   {
     return GetServiceWorkerDescriptor().Scope();
   }
 
   nsIURI*
   GetBaseURI() const
   {
-    workers::AssertIsOnMainThread();
+    AssertIsOnMainThread();
     return mLoadInfo.mBaseURI;
   }
 
   void
   SetBaseURI(nsIURI* aBaseURI);
 
   nsIURI*
   GetResolvedScriptURI() const
   {
-    workers::AssertIsOnMainThread();
+    AssertIsOnMainThread();
     return mLoadInfo.mResolvedScriptURI;
   }
 
   const nsString&
   ServiceWorkerCacheName() const
   {
     MOZ_DIAGNOSTIC_ASSERT(IsServiceWorker());
-    workers::AssertIsOnMainThread();
+    AssertIsOnMainThread();
     return mLoadInfo.mServiceWorkerCacheName;
   }
 
   const ServiceWorkerDescriptor&
   GetServiceWorkerDescriptor() const
   {
     MOZ_DIAGNOSTIC_ASSERT(IsServiceWorker());
     MOZ_DIAGNOSTIC_ASSERT(mLoadInfo.mServiceWorkerDescriptor.isSome());
@@ -503,17 +503,17 @@ public:
   GetChannelInfo() const
   {
     return mLoadInfo.mChannelInfo;
   }
 
   void
   SetChannelInfo(const ChannelInfo& aChannelInfo)
   {
-    workers::AssertIsOnMainThread();
+    AssertIsOnMainThread();
     MOZ_ASSERT(!mLoadInfo.mChannelInfo.IsInitialized());
     MOZ_ASSERT(aChannelInfo.IsInitialized());
     mLoadInfo.mChannelInfo = aChannelInfo;
   }
 
   void
   InitChannelInfo(nsIChannel* aChannel)
   {
@@ -564,36 +564,36 @@ public:
     MOZ_ASSERT(!aTimeStamp.IsNull());
     TimeDuration duration = aTimeStamp - mCreationTimeStamp;
     return duration.ToMilliseconds();
   }
 
   nsIPrincipal*
   GetPrincipal() const
   {
-    workers::AssertIsOnMainThread();
+    AssertIsOnMainThread();
     return mLoadInfo.mPrincipal;
   }
 
   nsIPrincipal*
   GetLoadingPrincipal() const
   {
-    workers::AssertIsOnMainThread();
+    AssertIsOnMainThread();
     return mLoadInfo.mLoadingPrincipal;
   }
 
   const nsAString& Origin() const
   {
     return mLoadInfo.mOrigin;
   }
 
   nsILoadGroup*
   GetLoadGroup() const
   {
-    workers::AssertIsOnMainThread();
+    AssertIsOnMainThread();
     return mLoadInfo.mLoadGroup;
   }
 
   // This method allows the principal to be retrieved off the main thread.
   // Principals are main-thread objects so the caller must ensure that all
   // access occurs on the main thread.
   nsIPrincipal*
   GetPrincipalDontAssertMainThread() const
@@ -625,33 +625,33 @@ public:
   GetPrincipalInfo() const
   {
     return *mLoadInfo.mPrincipalInfo;
   }
 
   already_AddRefed<nsIChannel>
   ForgetWorkerChannel()
   {
-    workers::AssertIsOnMainThread();
+    AssertIsOnMainThread();
     return mLoadInfo.mChannel.forget();
   }
 
   nsIDocument* GetDocument() const;
 
   nsPIDOMWindowInner*
   GetWindow()
   {
-    workers::AssertIsOnMainThread();
+    AssertIsOnMainThread();
     return mLoadInfo.mWindow;
   }
 
   nsIContentSecurityPolicy*
   GetCSP() const
   {
-    workers::AssertIsOnMainThread();
+    AssertIsOnMainThread();
     return mLoadInfo.mCSP;
   }
 
   void
   SetCSP(nsIContentSecurityPolicy* aCSP);
 
   nsresult
   SetCSPFromHeaderValues(const nsACString& aCSPHeaderValue,
@@ -1002,26 +1002,26 @@ public:
   // ServiceWorker and the loading principal for any other type.
   static void
   OverrideLoadInfoLoadGroup(WorkerLoadInfo& aLoadInfo,
                             nsIPrincipal* aPrincipal);
 
   bool
   IsDebuggerRegistered()
   {
-    workers::AssertIsOnMainThread();
+    AssertIsOnMainThread();
 
     // No need to lock here since this is only ever modified by the same thread.
     return mDebuggerRegistered;
   }
 
   void
   SetIsDebuggerRegistered(bool aDebuggerRegistered)
   {
-    workers::AssertIsOnMainThread();
+    AssertIsOnMainThread();
 
     MutexAutoLock lock(mMutex);
 
     MOZ_ASSERT(mDebuggerRegistered != aDebuggerRegistered);
     mDebuggerRegistered = aDebuggerRegistered;
 
     mCondVar.Notify();
   }
@@ -1038,26 +1038,26 @@ public:
     while (mDebuggerRegistered != aDebuggerRegistered) {
       mCondVar.Wait();
     }
   }
 
   WorkerDebugger*
   Debugger() const
   {
-    workers::AssertIsOnMainThread();
+    AssertIsOnMainThread();
 
     MOZ_ASSERT(mDebugger);
     return mDebugger;
   }
 
   void
   SetDebugger(WorkerDebugger* aDebugger)
   {
-    workers::AssertIsOnMainThread();
+    AssertIsOnMainThread();
 
     MOZ_ASSERT(mDebugger != aDebugger);
     mDebugger = aDebugger;
   }
 
   JS::UniqueChars
   AdoptDefaultLocale()
   {
--- a/dom/workers/WorkerRunnable.cpp
+++ b/dom/workers/WorkerRunnable.cpp
@@ -279,17 +279,17 @@ WorkerRunnable::Run()
   }
 
   // Track down the appropriate global, if any, to use for the AutoEntryScript.
   nsCOMPtr<nsIGlobalObject> globalObject;
   bool isMainThread = !targetIsWorkerThread && !mWorkerPrivate->GetParent();
   MOZ_ASSERT(isMainThread == NS_IsMainThread());
   RefPtr<WorkerPrivate> kungFuDeathGrip;
   if (targetIsWorkerThread) {
-    JSContext* cx = GetCurrentThreadJSContext();
+    JSContext* cx = GetCurrentWorkerThreadJSContext();
     if (NS_WARN_IF(!cx)) {
       return NS_ERROR_FAILURE;
     }
 
     JSObject* global = JS::CurrentGlobalOrNull(cx);
     if (global) {
       globalObject = xpc::NativeGlobal(global);
     } else {
@@ -468,17 +468,17 @@ MainThreadWorkerSyncRunnable::PostDispat
 }
 
 MainThreadStopSyncLoopRunnable::MainThreadStopSyncLoopRunnable(
                                WorkerPrivate* aWorkerPrivate,
                                already_AddRefed<nsIEventTarget>&& aSyncLoopTarget,
                                bool aResult)
 : WorkerSyncRunnable(aWorkerPrivate, Move(aSyncLoopTarget)), mResult(aResult)
 {
-  workers::AssertIsOnMainThread();
+  AssertIsOnMainThread();
 #ifdef DEBUG
   mWorkerPrivate->AssertValidSyncLoop(mSyncLoopTarget);
 #endif
 }
 
 nsresult
 MainThreadStopSyncLoopRunnable::Cancel()
 {
@@ -602,17 +602,17 @@ WorkerMainThreadRunnable::Dispatch(Worke
   if (!success) {
     aRv.ThrowUncatchableException();
   }
 }
 
 NS_IMETHODIMP
 WorkerMainThreadRunnable::Run()
 {
-  workers::AssertIsOnMainThread();
+  AssertIsOnMainThread();
 
   bool runResult = MainThreadRun();
 
   RefPtr<MainThreadStopSyncLoopRunnable> response =
     new MainThreadStopSyncLoopRunnable(mWorkerPrivate,
                                        mSyncLoopTarget.forget(),
                                        runResult);
 
@@ -694,17 +694,17 @@ WorkerProxyToMainThreadRunnable::Dispatc
   }
 
   return true;
 }
 
 NS_IMETHODIMP
 WorkerProxyToMainThreadRunnable::Run()
 {
-  workers::AssertIsOnMainThread();
+  AssertIsOnMainThread();
   RunOnMainThread();
   PostDispatchOnMainThread();
   return NS_OK;
 }
 
 void
 WorkerProxyToMainThreadRunnable::PostDispatchOnMainThread()
 {
--- a/dom/workers/WorkerRunnable.h
+++ b/dom/workers/WorkerRunnable.h
@@ -140,23 +140,24 @@ protected:
   // value will be passed to PostRun().  The JSContext passed in here comes from
   // an AutoJSAPI (or AutoEntryScript) that we set up on the stack.  If
   // mBehavior is ParentThreadUnchangedBusyCount, it is in the compartment of
   // mWorkerPrivate's reflector (i.e. the worker object in the parent thread),
   // unless that reflector is null, in which case it's in the compartment of the
   // parent global (which is the compartment reflector would have been in), or
   // in the null compartment if there is no parent global.  For other mBehavior
   // values, we're running on the worker thread and aCx is in whatever
-  // compartment GetCurrentThreadJSContext() was in when nsIRunnable::Run() got
-  // called.  This is actually important for cases when a runnable spins a
-  // syncloop and wants everything that happens during the syncloop to happen in
-  // the compartment that runnable set up (which may, for example, be a debugger
-  // sandbox compartment!).  If aCx wasn't in a compartment to start with, aCx
-  // will be in either the debugger global's compartment or the worker's
-  // global's compartment depending on whether IsDebuggerRunnable() is true.
+  // compartment GetCurrentWorkerThreadJSContext() was in when
+  // nsIRunnable::Run() got called.  This is actually important for cases when a
+  // runnable spins a syncloop and wants everything that happens during the
+  // syncloop to happen in the compartment that runnable set up (which may, for
+  // example, be a debugger sandbox compartment!).  If aCx wasn't in a
+  // compartment to start with, aCx will be in either the debugger global's
+  // compartment or the worker's global's compartment depending on whether
+  // IsDebuggerRunnable() is true.
   //
   // Immediately after WorkerRun returns, the caller will assert that either it
   // returns false or there is no exception pending on aCx.  Then it will report
   // any pending exceptions on aCx.
   virtual bool
   WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) = 0;
 
   // By default asserts that Run() (and WorkerRun()) were called on the correct
@@ -196,17 +197,17 @@ private:
   IsDebuggerRunnable() const override
   {
     return true;
   }
 
   virtual bool
   PreDispatch(WorkerPrivate* aWorkerPrivate) override final
   {
-    workers::AssertIsOnMainThread();
+    AssertIsOnMainThread();
 
     return true;
   }
 
   virtual void
   PostDispatch(WorkerPrivate* aWorkerPrivate,
                bool aDispatchResult) override;
 };
@@ -238,34 +239,34 @@ class MainThreadWorkerSyncRunnable : pub
 {
 protected:
   // Passing null for aSyncLoopTarget is allowed and will result in the behavior
   // of a normal WorkerRunnable.
   MainThreadWorkerSyncRunnable(WorkerPrivate* aWorkerPrivate,
                                nsIEventTarget* aSyncLoopTarget)
   : WorkerSyncRunnable(aWorkerPrivate, aSyncLoopTarget)
   {
-    workers::AssertIsOnMainThread();
+    AssertIsOnMainThread();
   }
 
   MainThreadWorkerSyncRunnable(WorkerPrivate* aWorkerPrivate,
                                already_AddRefed<nsIEventTarget>&& aSyncLoopTarget)
   : WorkerSyncRunnable(aWorkerPrivate, Move(aSyncLoopTarget))
   {
-    workers::AssertIsOnMainThread();
+    AssertIsOnMainThread();
   }
 
   virtual ~MainThreadWorkerSyncRunnable()
   { }
 
 private:
   virtual bool
   PreDispatch(WorkerPrivate* aWorkerPrivate) override
   {
-    workers::AssertIsOnMainThread();
+    AssertIsOnMainThread();
     return true;
   }
 
   virtual void
   PostDispatch(WorkerPrivate* aWorkerPrivate,
                bool aDispatchResult) override;
 };
 
@@ -308,34 +309,34 @@ private:
 // A convenience class for WorkerRunnables that are originated on the main
 // thread.
 class MainThreadWorkerRunnable : public WorkerRunnable
 {
 protected:
   explicit MainThreadWorkerRunnable(WorkerPrivate* aWorkerPrivate)
   : WorkerRunnable(aWorkerPrivate, WorkerThreadUnchangedBusyCount)
   {
-    workers::AssertIsOnMainThread();
+    AssertIsOnMainThread();
   }
 
   virtual ~MainThreadWorkerRunnable()
   {}
 
   virtual bool
   PreDispatch(WorkerPrivate* aWorkerPrivate) override
   {
-    workers::AssertIsOnMainThread();
+    AssertIsOnMainThread();
     return true;
   }
 
   virtual void
   PostDispatch(WorkerPrivate* aWorkerPrivate,
                bool aDispatchResult) override
   {
-    workers::AssertIsOnMainThread();
+    AssertIsOnMainThread();
   }
 };
 
 // A convenience class for WorkerControlRunnables that originate on the main
 // thread.
 class MainThreadWorkerControlRunnable : public WorkerControlRunnable
 {
 protected:
@@ -344,25 +345,25 @@ protected:
   { }
 
   virtual ~MainThreadWorkerControlRunnable()
   { }
 
   virtual bool
   PreDispatch(WorkerPrivate* aWorkerPrivate) override
   {
-    workers::AssertIsOnMainThread();
+    AssertIsOnMainThread();
     return true;
   }
 
   virtual void
   PostDispatch(WorkerPrivate* aWorkerPrivate,
                bool aDispatchResult) override
   {
-    workers::AssertIsOnMainThread();
+    AssertIsOnMainThread();
   }
 };
 
 // A WorkerRunnable that should be dispatched from the worker to itself for
 // async tasks. This will increment the busy count PostDispatch() (only if
 // dispatch was successful) and decrement it in PostRun().
 //
 // Async tasks will almost always want to use this since
@@ -500,17 +501,17 @@ public:
 protected:
   virtual ~MainThreadStopSyncLoopRunnable()
   { }
 
 private:
   virtual bool
   PreDispatch(WorkerPrivate* aWorkerPrivate) override final
   {
-    workers::AssertIsOnMainThread();
+    AssertIsOnMainThread();
     return true;
   }
 
   virtual void
   PostDispatch(WorkerPrivate* aWorkerPrivate,
                bool aDispatchResult) override;
 
   virtual bool
--- a/dom/workers/WorkerScope.cpp
+++ b/dom/workers/WorkerScope.cpp
@@ -979,17 +979,17 @@ WorkerDebuggerGlobalScope::LoadSubScript
                                          const Optional<JS::Handle<JSObject*>>& aSandbox,
                                          ErrorResult& aRv)
 {
   mWorkerPrivate->AssertIsOnWorkerThread();
 
   Maybe<JSAutoCompartment> ac;
   if (aSandbox.WasPassed()) {
     JS::Rooted<JSObject*> sandbox(aCx, js::CheckedUnwrap(aSandbox.Value()));
-    if (!IsDebuggerSandbox(sandbox)) {
+    if (!IsWorkerDebuggerSandbox(sandbox)) {
       aRv.Throw(NS_ERROR_INVALID_ARG);
       return;
     }
 
     ac.emplace(aCx, sandbox);
   }
 
   nsTArray<nsString> urls;
@@ -1112,32 +1112,29 @@ WorkerDebuggerGlobalScope::EventTargetFo
 }
 
 AbstractThread*
 WorkerDebuggerGlobalScope::AbstractMainThreadFor(TaskCategory aCategory)
 {
   MOZ_CRASH("AbstractMainThreadFor not supported for workers.");
 }
 
-namespace workers {
-
 bool
 IsWorkerGlobal(JSObject* object)
 {
   return IS_INSTANCE_OF(WorkerGlobalScope, object);
 }
 
 bool
-IsDebuggerGlobal(JSObject* object)
+IsWorkerDebuggerGlobal(JSObject* object)
 {
   return IS_INSTANCE_OF(WorkerDebuggerGlobalScope, object);
 }
 
 bool
-IsDebuggerSandbox(JSObject* object)
+IsWorkerDebuggerSandbox(JSObject* object)
 {
   return SimpleGlobalObject::SimpleGlobalType(object) ==
     SimpleGlobalObject::GlobalType::WorkerDebuggerSandbox;
 }
 
-} // workers namespace
 } // dom namespace
 } // mozilla namespace
--- a/dom/xhr/XMLHttpRequestWorker.cpp
+++ b/dom/xhr/XMLHttpRequestWorker.cpp
@@ -156,27 +156,27 @@ public:
   Teardown(bool aSendUnpin);
 
   bool
   AddRemoveEventListeners(bool aUpload, bool aAdd);
 
   void
   Reset()
   {
-    workers::AssertIsOnMainThread();
+    AssertIsOnMainThread();
 
     if (mUploadEventListenersAttached) {
       AddRemoveEventListeners(true, false);
     }
   }
 
   already_AddRefed<nsIEventTarget>
   GetEventTarget()
   {
-    workers::AssertIsOnMainThread();
+    AssertIsOnMainThread();
 
     nsCOMPtr<nsIEventTarget> target = mSyncEventResponseTarget ?
                                       mSyncEventResponseTarget :
                                       mSyncLoopTarget;
     return target.forget();
   }
 
 private:
@@ -367,17 +367,17 @@ public:
 
 private:
   ~AsyncTeardownRunnable()
   { }
 
   NS_IMETHOD
   Run() override
   {
-    workers::AssertIsOnMainThread();
+    AssertIsOnMainThread();
 
     // This means the XHR was GC'd, so we can't be pinned, and we don't need to
     // try to unpin.
     mProxy->Teardown(/* aSendUnpin */ false);
     mProxy = nullptr;
 
     return NS_OK;
   }
@@ -444,41 +444,41 @@ public:
     : Runnable("dom::LoadStartDetectionRunnable")
     , mWorkerPrivate(aProxy->mWorkerPrivate)
     , mProxy(aProxy)
     , mXHR(aProxy->mXHR)
     , mXMLHttpRequestPrivate(aXHRPrivate)
     , mChannelId(mProxy->mInnerChannelId)
     , mReceivedLoadStart(false)
   {
-    workers::AssertIsOnMainThread();
+    AssertIsOnMainThread();
     CopyASCIItoUTF16(sEventStrings[STRING_loadstart], mEventType);
   }
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIRUNNABLE
   NS_DECL_NSIDOMEVENTLISTENER
 
   bool
   RegisterAndDispatch()
   {
-    workers::AssertIsOnMainThread();
+    AssertIsOnMainThread();
 
     if (NS_FAILED(mXHR->AddEventListener(mEventType, this, false, false, 2))) {
       NS_WARNING("Failed to add event listener!");
       return false;
     }
 
     return NS_SUCCEEDED(mWorkerPrivate->DispatchToMainThread(this));
   }
 
 private:
   ~LoadStartDetectionRunnable()
   {
-    workers::AssertIsOnMainThread();
+    AssertIsOnMainThread();
   }
 };
 
 class EventRunnable final : public MainThreadProxyRunnable
                           , public StructuredCloneHolder
 {
   nsString mType;
   nsString mResponseType;
@@ -847,17 +847,17 @@ public:
   }
 };
 
 } // namespace
 
 bool
 Proxy::Init()
 {
-  workers::AssertIsOnMainThread();
+  AssertIsOnMainThread();
   MOZ_ASSERT(mWorkerPrivate);
 
   if (mXHR) {
     return true;
   }
 
   nsPIDOMWindowInner* ownerWindow = mWorkerPrivate->GetWindow();
   if (ownerWindow && !ownerWindow->IsCurrentInnerWindow()) {
@@ -890,17 +890,17 @@ Proxy::Init()
   }
 
   return true;
 }
 
 void
 Proxy::Teardown(bool aSendUnpin)
 {
-  workers::AssertIsOnMainThread();
+  AssertIsOnMainThread();
 
   if (mXHR) {
     Reset();
 
     // NB: We are intentionally dropping events coming from xhr.abort on the
     // floor.
     AddRemoveEventListeners(false, false);
 
@@ -940,17 +940,17 @@ Proxy::Teardown(bool aSendUnpin)
 
   MOZ_ASSERT(!mWorkerPrivate);
   MOZ_ASSERT(!mSyncLoopTarget);
 }
 
 bool
 Proxy::AddRemoveEventListeners(bool aUpload, bool aAdd)
 {
-  workers::AssertIsOnMainThread();
+  AssertIsOnMainThread();
 
   NS_ASSERTION(!aUpload ||
                (mUploadEventListenersAttached && !aAdd) ||
                (!mUploadEventListenersAttached && aAdd),
                "Messed up logic for upload listeners!");
 
   nsCOMPtr<nsIDOMEventTarget> target =
     aUpload ?
@@ -980,17 +980,17 @@ Proxy::AddRemoveEventListeners(bool aUpl
   return true;
 }
 
 NS_IMPL_ISUPPORTS(Proxy, nsIDOMEventListener)
 
 NS_IMETHODIMP
 Proxy::HandleEvent(nsIDOMEvent* aEvent)
 {
-  workers::AssertIsOnMainThread();
+  AssertIsOnMainThread();
 
   if (!mWorkerPrivate || !mXMLHttpRequestPrivate) {
     NS_ERROR("Shouldn't get here!");
     return NS_OK;
   }
 
   nsString type;
   if (NS_FAILED(aEvent->GetType(type))) {
@@ -1061,17 +1061,17 @@ Proxy::HandleEvent(nsIDOMEvent* aEvent)
 }
 
 NS_IMPL_ISUPPORTS_INHERITED(LoadStartDetectionRunnable, Runnable,
                                                         nsIDOMEventListener)
 
 NS_IMETHODIMP
 LoadStartDetectionRunnable::Run()
 {
-  workers::AssertIsOnMainThread();
+  AssertIsOnMainThread();
 
   if (NS_FAILED(mXHR->RemoveEventListener(mEventType, this, false))) {
     NS_WARNING("Failed to remove event listener!");
   }
 
   if (!mReceivedLoadStart) {
     if (mProxy->mOutstandingSendCount > 1) {
       mProxy->mOutstandingSendCount--;
@@ -1093,17 +1093,17 @@ LoadStartDetectionRunnable::Run()
   mXHR = nullptr;
   mXMLHttpRequestPrivate = nullptr;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 LoadStartDetectionRunnable::HandleEvent(nsIDOMEvent* aEvent)
 {
-  workers::AssertIsOnMainThread();
+  AssertIsOnMainThread();
 
 #ifdef DEBUG
   {
     nsString type;
     if (NS_SUCCEEDED(aEvent->GetType(type))) {
       MOZ_ASSERT(type == mEventType);
     }
     else {
@@ -1114,17 +1114,17 @@ LoadStartDetectionRunnable::HandleEvent(
 
   mReceivedLoadStart = true;
   return NS_OK;
 }
 
 bool
 EventRunnable::PreDispatch(WorkerPrivate* /* unused */)
 {
-  workers::AssertIsOnMainThread();
+  AssertIsOnMainThread();
 
   AutoJSAPI jsapi;
   DebugOnly<bool> ok = jsapi.Init(xpc::NativeGlobal(mScopeObj));
   MOZ_ASSERT(ok);
   JSContext* cx = jsapi.cx();
   // Now keep the mScopeObj alive for the duration
   JS::Rooted<JSObject*> scopeObj(cx, mScopeObj);
   // And reset mScopeObj now, before we have a chance to run its destructor on
@@ -1369,17 +1369,17 @@ EventRunnable::WorkerRun(JSContext* aCx,
   }
 
   return true;
 }
 
 bool
 WorkerThreadProxySyncRunnable::MainThreadRun()
 {
-  workers::AssertIsOnMainThread();
+  AssertIsOnMainThread();
 
   nsCOMPtr<nsIEventTarget> tempTarget = mSyncLoopTarget;
 
   mProxy->mSyncEventResponseTarget.swap(tempTarget);
 
   ErrorResult rv;
   RunOnMainThread(rv);
   mErrorCode = rv.StealNSResult();
@@ -1584,17 +1584,17 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INH
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 /* static */ already_AddRefed<XMLHttpRequest>
 XMLHttpRequestWorker::Construct(const GlobalObject& aGlobal,
                                 const MozXMLHttpRequestParameters& aParams,
                                 ErrorResult& aRv)
 {
   JSContext* cx = aGlobal.Context();
-  WorkerPrivate* workerPrivate = workers::GetWorkerPrivateFromContext(cx);
+  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
   MOZ_ASSERT(workerPrivate);
 
   RefPtr<XMLHttpRequestWorker> xhr = new XMLHttpRequestWorker(workerPrivate);
 
   if (workerPrivate->XHRParamsAllowed()) {
     if (aParams.mMozSystem)
       xhr->mMozAnon = true;
     else
--- a/dom/xml/moz.build
+++ b/dom/xml/moz.build
@@ -35,15 +35,16 @@ UNIFIED_SOURCES += [
 ]
 
 FINAL_LIBRARY = 'xul'
 
 LOCAL_INCLUDES += [
     '/caps',
     '/dom/base',
     '/dom/html',
+    '/dom/xslt/base',
     '/dom/xul',
     '/layout/style',
 ]
 
 RESOURCE_FILES.dtd += [
     'htmlmathml-f.ent',
 ]
--- a/dom/xml/nsXMLContentSink.cpp
+++ b/dom/xml/nsXMLContentSink.cpp
@@ -54,16 +54,17 @@
 #include "nsHtml5SVGLoadDispatcher.h"
 #include "nsTextNode.h"
 #include "mozilla/dom/CDATASection.h"
 #include "mozilla/dom/Comment.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/HTMLTemplateElement.h"
 #include "mozilla/dom/ProcessingInstruction.h"
 #include "mozilla/dom/ScriptLoader.h"
+#include "mozilla/dom/txMozillaXSLTProcessor.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 // XXX Open Issues:
 // 1) what's not allowed - We need to figure out which HTML tags
 //    (prefixed with a HTML namespace qualifier) are explicitly not
 //    allowed (if any).
@@ -621,22 +622,17 @@ nsXMLContentSink::AddContentAsLeaf(nsICo
   return result;
 }
 
 // Create an XML parser and an XSL content sink and start parsing
 // the XSL stylesheet located at the given URI.
 nsresult
 nsXMLContentSink::LoadXSLStyleSheet(nsIURI* aUrl)
 {
-  nsCOMPtr<nsIDocumentTransformer> processor =
-    do_CreateInstance("@mozilla.org/document-transformer;1?type=xslt");
-  if (!processor) {
-    // No XSLT processor available, continue normal document loading
-    return NS_OK;
-  }
+  nsCOMPtr<nsIDocumentTransformer> processor = new txMozillaXSLTProcessor();
 
   processor->SetTransformObserver(this);
 
   if (NS_SUCCEEDED(processor->LoadStyleSheet(aUrl, mDocument))) {
     mXSLTProcessor.swap(processor);
   }
 
   // Intentionally ignore errors here, we should continue loading the
--- a/dom/xml/nsXMLPrettyPrinter.cpp
+++ b/dom/xml/nsXMLPrettyPrinter.cpp
@@ -3,31 +3,31 @@
  * 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 "nsXMLPrettyPrinter.h"
 #include "nsContentUtils.h"
 #include "nsICSSDeclaration.h"
 #include "nsIDOMDocumentXBL.h"
 #include "nsIObserver.h"
-#include "nsIXSLTProcessor.h"
 #include "nsSyncLoadService.h"
 #include "nsPIDOMWindow.h"
 #include "nsIDOMElement.h"
 #include "nsIServiceManager.h"
 #include "nsNetUtil.h"
 #include "mozilla/dom/Element.h"
-#include "nsIDOMDocumentFragment.h"
 #include "nsBindingManager.h"
 #include "nsXBLService.h"
 #include "nsIScriptSecurityManager.h"
 #include "mozilla/Preferences.h"
 #include "nsIDocument.h"
 #include "nsVariant.h"
 #include "mozilla/dom/CustomEvent.h"
+#include "mozilla/dom/DocumentFragment.h"
+#include "mozilla/dom/txMozillaXSLTProcessor.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 NS_IMPL_ISUPPORTS(nsXMLPrettyPrinter,
                   nsIDocumentObserver,
                   nsIMutationObserver)
 
@@ -106,28 +106,29 @@ nsXMLPrettyPrinter::PrettyPrint(nsIDocum
     rv = nsSyncLoadService::LoadDocument(xslUri, nsIContentPolicy::TYPE_XSLT,
                                          nsContentUtils::GetSystemPrincipal(),
                                          nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
                                          nullptr, true, mozilla::net::RP_Unset,
                                          getter_AddRefs(xslDocument));
     NS_ENSURE_SUCCESS(rv, rv);
 
     // Transform the document
-    nsCOMPtr<nsIXSLTProcessor> transformer =
-        do_CreateInstance("@mozilla.org/document-transformer;1?type=xslt", &rv);
-    NS_ENSURE_SUCCESS(rv, rv);
+    RefPtr<txMozillaXSLTProcessor> transformer = new txMozillaXSLTProcessor();
+    ErrorResult err;
+    nsCOMPtr<nsIDocument> xslDoc = do_QueryInterface(xslDocument);
+    transformer->ImportStylesheet(*xslDoc, err);
+    if (NS_WARN_IF(err.Failed())) {
+        return err.StealNSResult();
+    }
 
-    rv = transformer->ImportStylesheet(xslDocument);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    nsCOMPtr<nsIDOMDocumentFragment> resultFragment;
-    nsCOMPtr<nsIDOMDocument> sourceDocument = do_QueryInterface(aDocument);
-    rv = transformer->TransformToFragment(sourceDocument, sourceDocument,
-                                          getter_AddRefs(resultFragment));
-    NS_ENSURE_SUCCESS(rv, rv);
+    RefPtr<DocumentFragment> resultFragment =
+        transformer->TransformToFragment(*aDocument, *aDocument, err);
+    if (NS_WARN_IF(err.Failed())) {
+        return err.StealNSResult();
+    }
 
     //
     // Apply the prettprint XBL binding.
     //
     // We take some shortcuts here. In particular, we don't bother invoking the
     // contstructor (since the binding has no constructor), and we don't bother
     // calling LoadBindingDocument because it's a chrome:// URI and thus will get
     // sync loaded no matter what.
@@ -165,17 +166,17 @@ nsXMLPrettyPrinter::PrettyPrint(nsIDocum
                                   getter_AddRefs(unused), &ignored);
     NS_ENSURE_SUCCESS(rv, rv);
 
     // Fire an event at the bound element to pass it |resultFragment|.
     RefPtr<CustomEvent> event =
       NS_NewDOMCustomEvent(rootElement, nullptr, nullptr);
     MOZ_ASSERT(event);
     nsCOMPtr<nsIWritableVariant> resultFragmentVariant = new nsVariant();
-    rv = resultFragmentVariant->SetAsISupports(resultFragment);
+    rv = resultFragmentVariant->SetAsISupports(ToSupports(resultFragment.get()));
     MOZ_ASSERT(NS_SUCCEEDED(rv));
     rv = event->InitCustomEvent(NS_LITERAL_STRING("prettyprint-dom-created"),
                                 /* bubbles = */ false, /* cancelable = */ false,
                                 /* detail = */ resultFragmentVariant);
     NS_ENSURE_SUCCESS(rv, rv);
     event->SetTrusted(true);
     bool dummy;
     rv = rootElement->DispatchEvent(event, &dummy);
--- a/dom/xslt/moz.build
+++ b/dom/xslt/moz.build
@@ -3,18 +3,16 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 with Files("**"):
     BUG_COMPONENT = ("Core", "XSLT")
 
 XPIDL_SOURCES += [
-    'nsIXSLTProcessor.idl',
-    'nsIXSLTProcessorPrivate.idl',
     'txIEXSLTRegExFunctions.idl',
     'txIFunctionEvaluationContext.idl',
     'txINodeSet.idl',
     'txIXPathObject.idl',
 ]
 
 XPIDL_MODULE = 'content_xslt'
 
deleted file mode 100644
--- a/dom/xslt/nsIXSLTProcessor.idl
+++ /dev/null
@@ -1,94 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "domstubs.idl"
-
-interface nsIVariant;
-
-[scriptable, uuid(4a91aeb3-4100-43ee-a21e-9866268757c5)]
-interface nsIXSLTProcessor : nsISupports
-{
-    /**
-     * Import the stylesheet into this XSLTProcessor for transformations.
-     *
-     * @param style The root-node of a XSLT stylesheet. This can be either
-     *              a document node or an element node. If a document node
-     *              then the document can contain either a XSLT stylesheet
-     *              or a LRE stylesheet.
-     *              If the argument is an element node it must be the
-     *              xsl:stylesheet (or xsl:transform) element of an XSLT
-     *              stylesheet.
-     */
-    void importStylesheet(in nsIDOMNode style);
-
-    /**
-     * Transforms the node source applying the stylesheet given by
-     * the importStylesheet() function. The owner document of the output node
-     * owns the returned document fragment.
-     *
-     * @param source The node to be transformed
-     * @param output This document is used to generate the output
-     * @return DocumentFragment The result of the transformation
-     */
-    nsIDOMDocumentFragment transformToFragment(in nsIDOMNode source,
-                                               in nsIDOMDocument output);
-
-    /**
-     * Transforms the node source applying the stylesheet given by the
-     * importStylesheet() function.
-     *
-     * @param source The node to be transformed
-     * @return Document The result of the transformation
-     */
-    nsIDOMDocument transformToDocument(in nsIDOMNode source);
-
-    /**
-     * Sets a parameter to be used in subsequent transformations with this
-     * nsIXSLTProcessor. If the parameter doesn't exist in the stylesheet the
-     * parameter will be ignored.
-     *
-     * @param namespaceURI The namespaceURI of the XSLT parameter
-     * @param localName    The local name of the XSLT parameter
-     * @param value        The new value of the XSLT parameter
-     *
-     * @exception NS_ERROR_ILLEGAL_VALUE The datatype of value is
-     *                                   not supported
-     */
-    void setParameter(in DOMString namespaceURI,
-                      in DOMString localName,
-                      in nsIVariant value);
-
-    /**
-     * Gets a parameter if previously set by setParameter. Returns null
-     * otherwise.
-     *
-     * @param namespaceURI The namespaceURI of the XSLT parameter
-     * @param localName    The local name of the XSLT parameter
-     * @return nsIVariant  The value of the XSLT parameter
-     */
-    nsIVariant getParameter(in DOMString namespaceURI,
-                            in DOMString localName);
-    /**
-     * Removes a parameter, if set. This will make the processor use the
-     * default-value for the parameter as specified in the stylesheet.
-     *
-     * @param namespaceURI The namespaceURI of the XSLT parameter
-     * @param localName    The local name of the XSLT parameter
-     */
-    void removeParameter(in DOMString namespaceURI,
-                         in DOMString localName);
-
-    /**
-     * Removes all set parameters from this nsIXSLTProcessor. This will make
-     * the processor use the default-value for all parameters as specified in
-     * the stylesheet.
-     */
-    void clearParameters();
-
-    /**
-     * Remove all parameters and stylesheets from this nsIXSLTProcessor.
-     */
-    void reset();
-};
deleted file mode 100644
--- a/dom/xslt/nsIXSLTProcessorPrivate.idl
+++ /dev/null
@@ -1,17 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsISupports.idl"
-
-[scriptable, uuid(b8d727f7-67f4-4dc1-a318-ec0c87280816)]
-interface nsIXSLTProcessorPrivate : nsISupports
-{
-  /**
-   * Disables all loading of external documents, such as from
-   * <xsl:import> and document()
-   * Defaults to off and is *not* reset by calls to reset()
-   */
-  const unsigned long DISABLE_ALL_LOADS = 1;
-};
--- a/dom/xslt/xslt/txMozillaXSLTProcessor.cpp
+++ b/dom/xslt/xslt/txMozillaXSLTProcessor.cpp
@@ -35,16 +35,17 @@
 #include "nsIScriptSecurityManager.h"
 #include "nsJSUtils.h"
 #include "nsIXPConnect.h"
 #include "nsVariant.h"
 #include "nsTextNode.h"
 #include "mozilla/dom/DocumentFragment.h"
 #include "mozilla/dom/XSLTProcessorBinding.h"
 
+using namespace mozilla;
 using namespace mozilla::dom;
 
 static NS_DEFINE_CID(kXMLDocumentCID, NS_XMLDOCUMENT_CID);
 
 /**
  * Output Handler Factories
  */
 class txToDocHandlerFactory : public txAOutputHandlerFactory
@@ -331,21 +332,19 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(tx
                                       mOwner, mEmbeddedStylesheetRoot,
                                       mSource, mVariables)
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(txMozillaXSLTProcessor)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(txMozillaXSLTProcessor)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(txMozillaXSLTProcessor)
     NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
-    NS_INTERFACE_MAP_ENTRY(nsIXSLTProcessor)
-    NS_INTERFACE_MAP_ENTRY(nsIXSLTProcessorPrivate)
     NS_INTERFACE_MAP_ENTRY(nsIDocumentTransformer)
     NS_INTERFACE_MAP_ENTRY(nsIMutationObserver)
-    NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXSLTProcessor)
+    NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDocumentTransformer)
 NS_INTERFACE_MAP_END
 
 txMozillaXSLTProcessor::txMozillaXSLTProcessor()
   : mOwner(nullptr),
     mStylesheetDocument(nullptr),
     mTransformResult(NS_OK),
     mCompileResult(NS_OK),
     mFlags(0)
@@ -589,78 +588,86 @@ txMozillaXSLTProcessor::DoTransform()
         // XXX Maybe we should just display the source document in this case?
         //     Also, set up context information, see bug 204655.
         reportError(rv, nullptr, nullptr);
     }
 
     return rv;
 }
 
-NS_IMETHODIMP
-txMozillaXSLTProcessor::ImportStylesheet(nsIDOMNode *aStyle)
+void
+txMozillaXSLTProcessor::ImportStylesheet(nsINode& aStyle,
+                                         mozilla::ErrorResult& aRv)
 {
-    NS_ENSURE_TRUE(aStyle, NS_ERROR_NULL_POINTER);
-
     // We don't support importing multiple stylesheets yet.
-    NS_ENSURE_TRUE(!mStylesheetDocument && !mStylesheet,
-                   NS_ERROR_NOT_IMPLEMENTED);
+    if (NS_WARN_IF(mStylesheetDocument || mStylesheet)) {
+        aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
+        return;
+    }
 
-    nsCOMPtr<nsINode> node = do_QueryInterface(aStyle);
-    if (!node || !nsContentUtils::SubjectPrincipalOrSystemIfNativeCaller()->Subsumes(node->NodePrincipal())) {
-        return NS_ERROR_DOM_SECURITY_ERR;
+    if (!nsContentUtils::SubjectPrincipalOrSystemIfNativeCaller()->Subsumes(aStyle.NodePrincipal())) {
+        aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
+        return;
     }
 
-    nsCOMPtr<nsINode> styleNode = do_QueryInterface(aStyle);
-    NS_ENSURE_TRUE(styleNode &&
-                   (styleNode->IsElement() ||
-                    styleNode->IsNodeOfType(nsINode::eDOCUMENT)),
-                   NS_ERROR_INVALID_ARG);
+    if (NS_WARN_IF(!aStyle.IsElement() &&
+                   !aStyle.IsNodeOfType(nsINode::eDOCUMENT))) {
+        aRv.Throw(NS_ERROR_INVALID_ARG);
+        return;
+    }
 
-    nsresult rv = TX_CompileStylesheet(styleNode, this,
+    nsresult rv = TX_CompileStylesheet(&aStyle, this,
                                        getter_AddRefs(mStylesheet));
     // XXX set up exception context, bug 204658
-    NS_ENSURE_SUCCESS(rv, rv);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+        aRv.Throw(rv);
+        return;
+    }
 
-    if (styleNode->IsElement()) {
-        mStylesheetDocument = styleNode->OwnerDoc();
-        NS_ENSURE_TRUE(mStylesheetDocument, NS_ERROR_UNEXPECTED);
-
-        mEmbeddedStylesheetRoot = static_cast<nsIContent*>(styleNode.get());
-    }
-    else {
-        mStylesheetDocument = static_cast<nsIDocument*>(styleNode.get());
+    mStylesheetDocument = aStyle.OwnerDoc();
+    if (aStyle.IsElement()) {
+        mEmbeddedStylesheetRoot = aStyle.AsElement();
     }
 
     mStylesheetDocument->AddMutationObserver(this);
-
-    return NS_OK;
 }
 
-NS_IMETHODIMP
-txMozillaXSLTProcessor::TransformToDocument(nsIDOMNode *aSource,
-                                            nsIDOMDocument **aResult)
+already_AddRefed<nsIDocument>
+txMozillaXSLTProcessor::TransformToDocument(nsINode& aSource,
+                                            ErrorResult& aRv)
 {
-    NS_ENSURE_ARG(aSource);
-    NS_ENSURE_ARG_POINTER(aResult);
-    NS_ENSURE_SUCCESS(mCompileResult, mCompileResult);
+    if (NS_WARN_IF(NS_FAILED(mCompileResult))) {
+        aRv.Throw(mCompileResult);
+        return nullptr;
+    }
 
-    if (!nsContentUtils::CanCallerAccess(aSource)) {
-        return NS_ERROR_DOM_SECURITY_ERR;
+    if (!nsContentUtils::CanCallerAccess(&aSource)) {
+        aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
+        return nullptr;
     }
 
     nsresult rv = ensureStylesheet();
-    NS_ENSURE_SUCCESS(rv, rv);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+        aRv.Throw(rv);
+        return nullptr;
+    }
+
+    mSource = &aSource;
 
-    mSource = do_QueryInterface(aSource);
-
-    return TransformToDoc(aResult, true);
+    nsCOMPtr<nsIDocument> doc;
+    rv = TransformToDoc(getter_AddRefs(doc), true);
+    if (NS_FAILED(rv)) {
+        aRv.Throw(rv);
+        return nullptr;
+    }
+    return doc.forget();
 }
 
 nsresult
-txMozillaXSLTProcessor::TransformToDoc(nsIDOMDocument **aResult,
+txMozillaXSLTProcessor::TransformToDoc(nsIDocument **aResult,
                                        bool aCreateDataDocument)
 {
     nsAutoPtr<txXPathNode> sourceNode(txXPathNativeNode::createXPathNode(mSource));
     if (!sourceNode) {
         return NS_ERROR_OUT_OF_MEMORY;
     }
 
     txExecutionState es(mStylesheet, IsLoadDisabled());
@@ -683,86 +690,95 @@ txMozillaXSLTProcessor::TransformToDoc(n
     if (NS_SUCCEEDED(rv)) {
       rv = endRv;
     }
 
     if (NS_SUCCEEDED(rv)) {
         if (aResult) {
             txAOutputXMLEventHandler* handler =
                 static_cast<txAOutputXMLEventHandler*>(es.mOutputHandler);
-            handler->getOutputDocument(aResult);
-            nsCOMPtr<nsIDocument> doc = do_QueryInterface(*aResult);
+            nsCOMPtr<nsIDOMDocument> result;
+            handler->getOutputDocument(getter_AddRefs(result));
+            nsCOMPtr<nsIDocument> doc = do_QueryInterface(result);
             MOZ_ASSERT(doc->GetReadyStateEnum() ==
                        nsIDocument::READYSTATE_INTERACTIVE, "Bad readyState");
             doc->SetReadyStateInternal(nsIDocument::READYSTATE_COMPLETE);
+            doc.forget(aResult);
         }
     }
     else if (mObserver) {
         // XXX set up context information, bug 204655
         reportError(rv, nullptr, nullptr);
     }
 
     return rv;
 }
 
-NS_IMETHODIMP
-txMozillaXSLTProcessor::TransformToFragment(nsIDOMNode *aSource,
-                                            nsIDOMDocument *aOutput,
-                                            nsIDOMDocumentFragment **aResult)
+already_AddRefed<DocumentFragment>
+txMozillaXSLTProcessor::TransformToFragment(nsINode& aSource,
+                                            nsIDocument& aOutput,
+                                            ErrorResult& aRv)
 {
-    NS_ENSURE_ARG(aSource);
-    NS_ENSURE_ARG(aOutput);
-    NS_ENSURE_ARG_POINTER(aResult);
-    NS_ENSURE_SUCCESS(mCompileResult, mCompileResult);
+    if (NS_WARN_IF(NS_FAILED(mCompileResult))) {
+        aRv.Throw(mCompileResult);
+        return nullptr;
+    }
 
-    nsCOMPtr<nsINode> node = do_QueryInterface(aSource);
-    nsCOMPtr<nsIDocument> doc = do_QueryInterface(aOutput);
-    NS_ENSURE_TRUE(node && doc, NS_ERROR_DOM_SECURITY_ERR);
     nsIPrincipal* subject = nsContentUtils::SubjectPrincipalOrSystemIfNativeCaller();
-    if (!subject->Subsumes(node->NodePrincipal()) ||
-        !subject->Subsumes(doc->NodePrincipal()))
+    if (!subject->Subsumes(aSource.NodePrincipal()) ||
+        !subject->Subsumes(aOutput.NodePrincipal()))
     {
-        return NS_ERROR_DOM_SECURITY_ERR;
+        aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
+        return nullptr;
     }
 
     nsresult rv = ensureStylesheet();
-    NS_ENSURE_SUCCESS(rv, rv);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+        aRv.Throw(rv);
+        return nullptr;
+    }
 
-    nsAutoPtr<txXPathNode> sourceNode(txXPathNativeNode::createXPathNode(aSource));
+    nsAutoPtr<txXPathNode> sourceNode(txXPathNativeNode::createXPathNode(&aSource));
     if (!sourceNode) {
-        return NS_ERROR_OUT_OF_MEMORY;
+        aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
+        return nullptr;
     }
 
     txExecutionState es(mStylesheet, IsLoadDisabled());
 
     // XXX Need to add error observers
 
-    *aResult = doc->CreateDocumentFragment().take();
-    txToFragmentHandlerFactory handlerFactory(*aResult);
+    RefPtr<DocumentFragment> frag = aOutput.CreateDocumentFragment();
+    txToFragmentHandlerFactory handlerFactory(frag);
     es.mOutputHandlerFactory = &handlerFactory;
 
     rv = es.init(*sourceNode, &mVariables);
 
     // Process root of XML source document
     if (NS_SUCCEEDED(rv)) {
         rv = txXSLTProcessor::execute(es);
     }
     // XXX setup exception context, bug 204658
     nsresult endRv = es.end(rv);
     if (NS_SUCCEEDED(rv)) {
       rv = endRv;
     }
 
-    return rv;
+    if (NS_FAILED(rv)) {
+        aRv.Throw(rv);
+        return nullptr;
+    }
+
+    return frag.forget();
 }
 
-NS_IMETHODIMP
-txMozillaXSLTProcessor::SetParameter(const nsAString & aNamespaceURI,
-                                     const nsAString & aLocalName,
-                                     nsIVariant *aValue)
+nsresult
+txMozillaXSLTProcessor::SetParameter(const nsAString& aNamespaceURI,
+                                     const nsAString& aLocalName,
+                                     nsIVariant* aValue)
 {
     NS_ENSURE_ARG(aValue);
 
     nsCOMPtr<nsIVariant> value = aValue;
 
     uint16_t dataType;
     value->GetDataType(&dataType);
     switch (dataType) {
@@ -951,71 +967,80 @@ txMozillaXSLTProcessor::SetParameter(con
         var->setValue(value);
         return NS_OK;
     }
 
     var = new txVariable(value);
     return mVariables.add(varName, var);
 }
 
-NS_IMETHODIMP
+already_AddRefed<nsIVariant>
 txMozillaXSLTProcessor::GetParameter(const nsAString& aNamespaceURI,
                                      const nsAString& aLocalName,
-                                     nsIVariant **aResult)
+                                     ErrorResult& aRv)
 {
     int32_t nsId = kNameSpaceID_Unknown;
     nsresult rv = nsContentUtils::NameSpaceManager()->
         RegisterNameSpace(aNamespaceURI, nsId);
-    NS_ENSURE_SUCCESS(rv, rv);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+        aRv.Throw(rv);
+        return nullptr;
+    }
     RefPtr<nsAtom> localName = NS_Atomize(aLocalName);
     txExpandedName varName(nsId, localName);
 
     txVariable* var = static_cast<txVariable*>(mVariables.get(varName));
-    if (var) {
-        return var->getValue(aResult);
+    if (!var) {
+        return nullptr;
     }
-    return NS_OK;
+
+    nsCOMPtr<nsIVariant> result;
+    rv = var->getValue(getter_AddRefs(result));
+    if (NS_FAILED(rv)) {
+        aRv.Throw(rv);
+        return nullptr;
+    }
+    return result.forget();
 }
 
-NS_IMETHODIMP
+void
 txMozillaXSLTProcessor::RemoveParameter(const nsAString& aNamespaceURI,
-                                        const nsAString& aLocalName)
+                                        const nsAString& aLocalName,
+                                        ErrorResult& aRv)
 {
     int32_t nsId = kNameSpaceID_Unknown;
     nsresult rv = nsContentUtils::NameSpaceManager()->
         RegisterNameSpace(aNamespaceURI, nsId);
-    NS_ENSURE_SUCCESS(rv, rv);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+        aRv.Throw(rv);
+        return;
+    }
     RefPtr<nsAtom> localName = NS_Atomize(aLocalName);
     txExpandedName varName(nsId, localName);
 
     mVariables.remove(varName);
-    return NS_OK;
 }
 
-NS_IMETHODIMP
+void
 txMozillaXSLTProcessor::ClearParameters()
 {
     mVariables.clear();
-
-    return NS_OK;
 }
 
-NS_IMETHODIMP
+void
 txMozillaXSLTProcessor::Reset()
 {
     if (mStylesheetDocument) {
         mStylesheetDocument->RemoveMutationObserver(this);
     }
     mStylesheet = nullptr;
     mStylesheetDocument = nullptr;
     mEmbeddedStylesheetRoot = nullptr;
     mCompileResult = NS_OK;
     mVariables.clear();
-
-    return NS_OK;
 }
 
 void
 txMozillaXSLTProcessor::SetFlags(uint32_t aFlags, SystemCallerGuarantee)
 {
     mFlags = aFlags;
 }
 
@@ -1270,73 +1295,31 @@ txMozillaXSLTProcessor::Constructor(cons
                                     mozilla::ErrorResult& aRv)
 {
     RefPtr<txMozillaXSLTProcessor> processor =
         new txMozillaXSLTProcessor(aGlobal.GetAsSupports());
     return processor.forget();
 }
 
 void
-txMozillaXSLTProcessor::ImportStylesheet(nsINode& stylesheet,
-                                         mozilla::ErrorResult& aRv)
-{
-    aRv = ImportStylesheet(stylesheet.AsDOMNode());
-}
-
-already_AddRefed<DocumentFragment>
-txMozillaXSLTProcessor::TransformToFragment(nsINode& source,
-                                            nsIDocument& docVal,
-                                            mozilla::ErrorResult& aRv)
-{
-    nsCOMPtr<nsIDOMDocumentFragment> fragment;
-    nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(&docVal);
-    if (!domDoc) {
-        aRv.Throw(NS_ERROR_FAILURE);
-        return nullptr;
-    }
-    aRv = TransformToFragment(source.AsDOMNode(), domDoc, getter_AddRefs(fragment));
-    return fragment.forget().downcast<DocumentFragment>();
-}
-
-already_AddRefed<nsIDocument>
-txMozillaXSLTProcessor::TransformToDocument(nsINode& source,
-                                            mozilla::ErrorResult& aRv)
-{
-    nsCOMPtr<nsIDOMDocument> document;
-    aRv = TransformToDocument(source.AsDOMNode(), getter_AddRefs(document));
-    nsCOMPtr<nsIDocument> domDoc = do_QueryInterface(document);
-    return domDoc.forget();
-}
-
-void
 txMozillaXSLTProcessor::SetParameter(JSContext* aCx,
                                      const nsAString& aNamespaceURI,
                                      const nsAString& aLocalName,
                                      JS::Handle<JS::Value> aValue,
                                      mozilla::ErrorResult& aRv)
 {
     nsCOMPtr<nsIVariant> val;
     aRv = nsContentUtils::XPConnect()->JSToVariant(aCx, aValue,
                                                    getter_AddRefs(val));
     if (aRv.Failed()) {
         return;
     }
     aRv = SetParameter(aNamespaceURI, aLocalName, val);
 }
 
-nsIVariant*
-txMozillaXSLTProcessor::GetParameter(const nsAString& aNamespaceURI,
-                                     const nsAString& aLocalName,
-                                     mozilla::ErrorResult& aRv)
-{
-    nsCOMPtr<nsIVariant> val;
-    aRv = GetParameter(aNamespaceURI, aLocalName, getter_AddRefs(val));
-    return val;
-}
-
 /* static*/
 nsresult
 txMozillaXSLTProcessor::Startup()
 {
     if (!txXSLTProcessor::init()) {
         return NS_ERROR_OUT_OF_MEMORY;
     }
 
--- a/dom/xslt/xslt/txMozillaXSLTProcessor.h
+++ b/dom/xslt/xslt/txMozillaXSLTProcessor.h
@@ -4,25 +4,24 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef TRANSFRMX_TXMOZILLAXSLTPROCESSOR_H
 #define TRANSFRMX_TXMOZILLAXSLTPROCESSOR_H
 
 #include "nsAutoPtr.h"
 #include "nsStubMutationObserver.h"
 #include "nsIDocumentTransformer.h"
-#include "nsIXSLTProcessor.h"
-#include "nsIXSLTProcessorPrivate.h"
 #include "txExpandedNameMap.h"
 #include "txNamespaceMap.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsWrapperCache.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/dom/BindingDeclarations.h"
+#include "mozilla/dom/XSLTProcessorBinding.h"
 #include "mozilla/net/ReferrerPolicy.h"
 
 class nsINode;
 class nsIDOMNode;
 class nsIURI;
 class txStylesheet;
 class txResultRecycler;
 class txIGlobalParameter;
@@ -33,50 +32,35 @@ namespace dom {
 class DocGroup;
 class Document;
 class DocumentFragment;
 class GlobalObject;
 
 } // namespace dom
 } // namespace mozilla
 
-/* bacd8ad0-552f-11d3-a9f7-000064657374 */
-#define TRANSFORMIIX_XSLT_PROCESSOR_CID   \
-{ 0x618ee71d, 0xd7a7, 0x41a1, {0xa3, 0xfb, 0xc2, 0xbe, 0xdc, 0x6a, 0x21, 0x7e} }
-
-#define TRANSFORMIIX_XSLT_PROCESSOR_CONTRACTID \
-"@mozilla.org/document-transformer;1?type=xslt"
-
 #define XSLT_MSGS_URL  "chrome://global/locale/xslt/xslt.properties"
 
 /**
  * txMozillaXSLTProcessor is a front-end to the XSLT Processor.
  */
-class txMozillaXSLTProcessor final : public nsIXSLTProcessor,
-                                     public nsIXSLTProcessorPrivate,
-                                     public nsIDocumentTransformer,
+class txMozillaXSLTProcessor final : public nsIDocumentTransformer,
                                      public nsStubMutationObserver,
                                      public nsWrapperCache
 {
 public:
     /**
      * Creates a new txMozillaXSLTProcessor
      */
     txMozillaXSLTProcessor();
 
     // nsISupports interface
     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(txMozillaXSLTProcessor,
-                                                           nsIXSLTProcessor)
-
-    // nsIXSLTProcessor interface
-    NS_DECL_NSIXSLTPROCESSOR
-
-    // nsIXSLTProcessorPrivate interface
-    NS_DECL_NSIXSLTPROCESSORPRIVATE
+                                                           nsIDocumentTransformer)
 
     // nsIDocumentTransformer interface
     NS_IMETHOD SetTransformObserver(nsITransformObserver* aObserver) override;
     NS_IMETHOD LoadStyleSheet(nsIURI* aUri, nsIDocument* aLoaderDocument) override;
     NS_IMETHOD SetSourceContentModel(nsIDocument* aDocument,
                                      const nsTArray<nsCOMPtr<nsIContent>>& aSource) override;
     NS_IMETHOD CancelLoads() override {return NS_OK;}
     NS_IMETHOD AddXSLTParamNamespace(const nsString& aPrefix,
@@ -118,60 +102,64 @@ public:
     already_AddRefed<nsIDocument>
     TransformToDocument(nsINode& source, mozilla::ErrorResult& aRv);
 
     void SetParameter(JSContext* aCx,
                       const nsAString& aNamespaceURI,
                       const nsAString& aLocalName,
                       JS::Handle<JS::Value> aValue,
                       mozilla::ErrorResult& aRv);
-    nsIVariant* GetParameter(const nsAString& aNamespaceURI,
-                             const nsAString& aLocalName,
-                             mozilla::ErrorResult& aRv);
+    already_AddRefed<nsIVariant> GetParameter(const nsAString& aNamespaceURI,
+                                              const nsAString& aLocalName,
+                                              mozilla::ErrorResult& aRv);
     void RemoveParameter(const nsAString& aNamespaceURI,
                          const nsAString& aLocalName,
-                         mozilla::ErrorResult& aRv)
-    {
-        aRv = RemoveParameter(aNamespaceURI, aLocalName);
-    }
+                         mozilla::ErrorResult& aRv);
+    void ClearParameters();
+    void Reset();
 
     uint32_t Flags(mozilla::dom::SystemCallerGuarantee);
     void SetFlags(uint32_t aFlags, mozilla::dom::SystemCallerGuarantee);
 
     nsresult setStylesheet(txStylesheet* aStylesheet);
     void reportError(nsresult aResult, const char16_t *aErrorText,
                      const char16_t *aSourceText);
 
     nsINode *GetSourceContentModel()
     {
         return mSource;
     }
 
-    nsresult TransformToDoc(nsIDOMDocument **aResult,
+    nsresult TransformToDoc(nsIDocument **aResult,
                             bool aCreateDataDocument);
 
     bool IsLoadDisabled()
     {
-        return (mFlags & DISABLE_ALL_LOADS) != 0;
+        return (mFlags & mozilla::dom::XSLTProcessorBinding::DISABLE_ALL_LOADS) != 0;
     }
 
     static nsresult Startup();
     static void Shutdown();
 
 private:
     explicit txMozillaXSLTProcessor(nsISupports* aOwner);
     /**
      * Default destructor for txMozillaXSLTProcessor
      */
     ~txMozillaXSLTProcessor();
 
     nsresult DoTransform();
     void notifyError();
     nsresult ensureStylesheet();
 
+    // Helper method for the WebIDL SetParameter.
+    nsresult SetParameter(const nsAString& aNamespaceURI,
+                          const nsAString& aLocalName,
+                          nsIVariant* aValue);
+
     nsCOMPtr<nsISupports> mOwner;
 
     RefPtr<txStylesheet> mStylesheet;
     nsIDocument* mStylesheetDocument; // weak
     nsCOMPtr<nsIContent> mEmbeddedStylesheetRoot;
 
     nsCOMPtr<nsINode> mSource;
     nsresult mTransformResult;
--- a/editor/libeditor/CSSEditUtils.cpp
+++ b/editor/libeditor/CSSEditUtils.cpp
@@ -310,16 +310,18 @@ CSSEditUtils::CSSEditUtils(HTMLEditor* a
 }
 
 CSSEditUtils::~CSSEditUtils()
 {
 }
 
 // Answers true if we have some CSS equivalence for the HTML style defined
 // by aProperty and/or aAttribute for the node aNode
+
+// static
 bool
 CSSEditUtils::IsCSSEditableProperty(nsINode* aNode,
                                     nsAtom* aProperty,
                                     nsAtom* aAttribute)
 {
   MOZ_ASSERT(aNode);
 
   nsINode* node = aNode;
@@ -484,32 +486,35 @@ CSSEditUtils::RemoveCSSProperty(Element&
   }
   if (NS_WARN_IF(!mHTMLEditor)) {
     return NS_ERROR_NOT_AVAILABLE;
   }
   RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
   return htmlEditor->DoTransaction(transaction);
 }
 
+// static
 nsresult
 CSSEditUtils::GetSpecifiedProperty(nsINode& aNode,
                                    nsAtom& aProperty,
                                    nsAString& aValue)
 {
   return GetCSSInlinePropertyBase(&aNode, &aProperty, aValue, eSpecified);
 }
 
+// static
 nsresult
 CSSEditUtils::GetComputedProperty(nsINode& aNode,
                                   nsAtom& aProperty,
                                   nsAString& aValue)
 {
   return GetCSSInlinePropertyBase(&aNode, &aProperty, aValue, eComputed);
 }
 
+// static
 nsresult
 CSSEditUtils::GetCSSInlinePropertyBase(nsINode* aNode,
                                        nsAtom* aProperty,
                                        nsAString& aValue,
                                        StyleType aStyleType)
 {
   MOZ_ASSERT(aNode && aProperty);
   aValue.Truncate();
@@ -540,16 +545,17 @@ CSSEditUtils::GetCSSInlinePropertyBase(n
                                CSSEnabledState::eForAllContent);
   MOZ_ASSERT(prop != eCSSProperty_UNKNOWN);
 
   decl->GetPropertyValueByID(prop, aValue);
 
   return NS_OK;
 }
 
+// static
 already_AddRefed<nsComputedDOMStyle>
 CSSEditUtils::GetComputedStyle(Element* aElement)
 {
   MOZ_ASSERT(aElement);
 
   nsIDocument* doc = aElement->GetUncomposedDoc();
   NS_ENSURE_TRUE(doc, nullptr);
 
@@ -581,24 +587,28 @@ CSSEditUtils::RemoveCSSInlineStyle(nsINo
     return NS_OK;
   }
 
   return mHTMLEditor->RemoveContainer(element);
 }
 
 // Answers true if the property can be removed by setting a "none" CSS value
 // on a node
+
+// static
 bool
 CSSEditUtils::IsCSSInvertible(nsAtom& aProperty,
                               nsAtom* aAttribute)
 {
   return nsGkAtoms::b == &aProperty;
 }
 
 // Get the default browser background color if we need it for GetCSSBackgroundColorState
+
+// static
 void
 CSSEditUtils::GetDefaultBackgroundColor(nsAString& aColor)
 {
   if (Preferences::GetBool("editor.use_custom_colors", false)) {
     nsresult rv = Preferences::GetString("editor.background_color", aColor);
     // XXX Why don't you validate the pref value?
     if (NS_FAILED(rv)) {
       NS_WARNING("failed to get editor.background_color");
@@ -616,30 +626,34 @@ CSSEditUtils::GetDefaultBackgroundColor(
   // XXX Why don't you validate the pref value?
   if (NS_FAILED(rv)) {
     NS_WARNING("failed to get browser.display.background_color");
     aColor.AssignLiteral("#ffffff");  // Default to white
   }
 }
 
 // Get the default length unit used for CSS Indent/Outdent
+
+// static
 void
 CSSEditUtils::GetDefaultLengthUnit(nsAString& aLengthUnit)
 {
   nsresult rv =
     Preferences::GetString("editor.css.default_length_unit", aLengthUnit);
   // XXX Why don't you validate the pref value?
   if (NS_FAILED(rv)) {
     aLengthUnit.AssignLiteral("px");
   }
 }
 
 // Unfortunately, CSSStyleDeclaration::GetPropertyCSSValue is not yet
 // implemented... We need then a way to determine the number part and the unit
 // from aString, aString being the result of a GetPropertyValue query...
+
+// static
 void
 CSSEditUtils::ParseLength(const nsAString& aString,
                           float* aValue,
                           nsAtom** aUnit)
 {
   if (aString.IsEmpty()) {
     *aValue = 0;
     *aUnit = NS_Atomize(aString).take();
@@ -679,16 +693,17 @@ CSSEditUtils::ParseLength(const nsAStrin
     else break;
     iter++;
     i++;
   }
   *aValue = value * sign;
   *aUnit = NS_Atomize(StringTail(aString, j-i)).take();
 }
 
+// static
 void
 CSSEditUtils::GetCSSPropertyAtom(nsCSSEditableProperty aProperty,
                                  nsAtom** aAtom)
 {
   *aAtom = nullptr;
   switch (aProperty) {
     case eCSSEditableProperty_background_color:
       *aAtom = nsGkAtoms::backgroundColor;
@@ -750,16 +765,18 @@ CSSEditUtils::GetCSSPropertyAtom(nsCSSEd
     case eCSSEditableProperty_NONE:
       // intentionally empty
       break;
   }
 }
 
 // Populate aProperty and aValueArray with the CSS declarations equivalent to the
 // value aValue according to the equivalence table aEquivTable
+
+// static
 void
 CSSEditUtils::BuildCSSDeclarations(nsTArray<nsAtom*>& aPropertyArray,
                                    nsTArray<nsString>& aValueArray,
                                    const CSSEquivTable* aEquivTable,
                                    const nsAString* aValue,
                                    bool aGetOrRemoveRequest)
 {
   // clear arrays
@@ -793,16 +810,18 @@ CSSEditUtils::BuildCSSDeclarations(nsTAr
     }
     index++;
     cssProperty = aEquivTable[index].cssProperty;
   }
 }
 
 // Populate cssPropertyArray and cssValueArray with the declarations equivalent
 // to aHTMLProperty/aAttribute/aValue for the node aNode
+
+// static
 void
 CSSEditUtils::GenerateCSSDeclarationsFromHTMLStyle(
                 Element* aElement,
                 nsAtom* aHTMLProperty,
                 nsAtom* aAttribute,
                 const nsAString* aValue,
                 nsTArray<nsAtom*>& cssPropertyArray,
                 nsTArray<nsString>& cssValueArray,
@@ -945,16 +964,18 @@ CSSEditUtils::RemoveCSSEquivalentToHTMLS
   }
   return NS_OK;
 }
 
 // returns in aValueString the list of values for the CSS equivalences to
 // the HTML style aHTMLProperty/aAttribute/aValueString for the node aNode;
 // the value of aStyleType controls the styles we retrieve : specified or
 // computed.
+
+// static
 nsresult
 CSSEditUtils::GetCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode,
                                                    nsAtom* aHTMLProperty,
                                                    nsAtom* aAttribute,
                                                    nsAString& aValueString,
                                                    StyleType aStyleType)
 {
   aValueString.Truncate();
@@ -991,43 +1012,47 @@ CSSEditUtils::GetCSSEquivalentToHTMLInli
 
 // Does the node aNode (or its parent, if it's not an element node) have a CSS
 // style equivalent to the HTML style aHTMLProperty/aHTMLAttribute/valueString?
 // The value of aStyleType controls the styles we retrieve: specified or
 // computed. The return value aIsSet is true if the CSS styles are set.
 //
 // The nsIContent variant returns aIsSet instead of using an out parameter, and
 // does not modify aValue.
+
+// static
 bool
 CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode,
                                                   nsAtom* aProperty,
                                                   nsAtom* aAttribute,
                                                   const nsAString& aValue,
                                                   StyleType aStyleType)
 {
   // Use aValue as only an in param, not in-out
   nsAutoString value(aValue);
   return IsCSSEquivalentToHTMLInlineStyleSet(aNode, aProperty, aAttribute,
                                              value, aStyleType);
 }
 
+// static
 bool
 CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode,
                                                   nsAtom* aProperty,
                                                   const nsAString* aAttribute,
                                                   nsAString& aValue,
                                                   StyleType aStyleType)
 {
   MOZ_ASSERT(aNode && aProperty);
   RefPtr<nsAtom> attribute = aAttribute ? NS_Atomize(*aAttribute) : nullptr;
   return IsCSSEquivalentToHTMLInlineStyleSet(aNode,
                                              aProperty, attribute,
                                              aValue, aStyleType);
 }
 
+// static
 bool
 CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(
                 nsINode* aNode,
                 nsAtom* aHTMLProperty,
                 nsAtom* aHTMLAttribute,
                 nsAString& valueString,
                 StyleType aStyleType)
 {
@@ -1209,38 +1234,26 @@ CSSEditUtils::HaveCSSEquivalentStyles(
 
 void
 CSSEditUtils::SetCSSEnabled(bool aIsCSSPrefChecked)
 {
   mIsCSSPrefChecked = aIsCSSPrefChecked;
 }
 
 bool
-CSSEditUtils::IsCSSPrefChecked()
+CSSEditUtils::IsCSSPrefChecked() const
 {
   return mIsCSSPrefChecked ;
 }
 
 // ElementsSameStyle compares two elements and checks if they have the same
 // specified CSS declarations in the STYLE attribute
 // The answer is always negative if at least one of them carries an ID or a class
-bool
-CSSEditUtils::ElementsSameStyle(nsIDOMNode* aFirstNode,
-                                nsIDOMNode* aSecondNode)
-{
-  nsCOMPtr<Element> firstElement  = do_QueryInterface(aFirstNode);
-  nsCOMPtr<Element> secondElement = do_QueryInterface(aSecondNode);
 
-  NS_ASSERTION((firstElement && secondElement), "Non element nodes passed to ElementsSameStyle.");
-  NS_ENSURE_TRUE(firstElement, false);
-  NS_ENSURE_TRUE(secondElement, false);
-
-  return ElementsSameStyle(firstElement, secondElement);
-}
-
+// static
 bool
 CSSEditUtils::ElementsSameStyle(Element* aFirstElement,
                                 Element* aSecondElement)
 {
   MOZ_ASSERT(aFirstElement);
   MOZ_ASSERT(aSecondElement);
 
   if (aFirstElement->HasAttr(kNameSpaceID_None, nsGkAtoms::id) ||
@@ -1307,16 +1320,17 @@ CSSEditUtils::ElementsSameStyle(Element*
     if (!firstValue.Equals(secondValue)) {
       return false;
     }
   }
 
   return true;
 }
 
+// static
 nsresult
 CSSEditUtils::GetInlineStyles(Element* aElement,
                               nsICSSDeclaration** aCssDecl,
                               uint32_t* aLength)
 {
   NS_ENSURE_TRUE(aElement && aLength, NS_ERROR_NULL_POINTER);
   *aLength = 0;
   nsCOMPtr<nsStyledElement> inlineStyles = do_QueryInterface(aElement);
@@ -1325,16 +1339,17 @@ CSSEditUtils::GetInlineStyles(Element* a
   nsCOMPtr<nsICSSDeclaration> cssDecl = inlineStyles->Style();
   MOZ_ASSERT(cssDecl);
 
   cssDecl.forget(aCssDecl);
   *aLength = (*aCssDecl)->Length();
   return NS_OK;
 }
 
+// static
 Element*
 CSSEditUtils::GetElementContainerOrSelf(nsINode* aNode)
 {
   MOZ_ASSERT(aNode);
   if (nsINode::DOCUMENT_NODE == aNode->NodeType()) {
     return nullptr;
   }
 
--- a/editor/libeditor/CSSEditUtils.h
+++ b/editor/libeditor/CSSEditUtils.h
@@ -82,18 +82,18 @@ public:
    *
    * @param aNode          [IN] A DOM node.
    * @param aProperty      [IN] An atom containing a HTML tag name.
    * @param aAttribute     [IN] An atom containing a HTML
    *                            attribute carried by the element above.
    * @return               A boolean saying if the tag/attribute has a CSS
    *                       equiv.
    */
-  bool IsCSSEditableProperty(nsINode* aNode, nsAtom* aProperty,
-                             nsAtom* aAttribute);
+  static bool IsCSSEditableProperty(nsINode* aNode, nsAtom* aProperty,
+                                    nsAtom* aAttribute);
 
   /**
    * Adds/remove a CSS declaration to the STYLE atrribute carried by a given
    * element.
    *
    * @param aElement       [IN] A DOM element.
    * @param aProperty      [IN] An atom containing the CSS property to set.
    * @param aValue         [IN] A string containing the value of the CSS
@@ -113,20 +113,20 @@ public:
   /**
    * Gets the specified/computed style value of a CSS property for a given
    * node (or its element ancestor if it is not an element).
    *
    * @param aNode          [IN] A DOM node.
    * @param aProperty      [IN] An atom containing the CSS property to get.
    * @param aPropertyValue [OUT] The retrieved value of the property.
    */
-  nsresult GetSpecifiedProperty(nsINode& aNode, nsAtom& aProperty,
-                                nsAString& aValue);
-  nsresult GetComputedProperty(nsINode& aNode, nsAtom& aProperty,
-                               nsAString& aValue);
+  static nsresult GetSpecifiedProperty(nsINode& aNode, nsAtom& aProperty,
+                                       nsAString& aValue);
+  static nsresult GetComputedProperty(nsINode& aNode, nsAtom& aProperty,
+                                      nsAString& aValue);
 
   /**
    * Removes a CSS property from the specified declarations in STYLE attribute
    * and removes the node if it is an useless span.
    *
    * @param aNode           [IN] The specific node we want to remove a style
    *                             from.
    * @param aProperty       [IN] The CSS property atom to remove.
@@ -141,82 +141,82 @@ public:
    * on a node.
    *
    * @param aProperty     [IN] An atom containing a CSS property.
    * @param aAttribute    [IN] Pointer to an attribute name or null if this
    *                           information is irrelevant.
    * @return              A boolean saying if the property can be remove by
    *                      setting a "none" value.
    */
-  bool IsCSSInvertible(nsAtom& aProperty, nsAtom* aAttribute);
+  static bool IsCSSInvertible(nsAtom& aProperty, nsAtom* aAttribute);
 
   /**
    * Get the default browser background color if we need it for
    * GetCSSBackgroundColorState().
    *
    * @param aColor         [OUT] The default color as it is defined in prefs.
    */
-  void GetDefaultBackgroundColor(nsAString& aColor);
+  static void GetDefaultBackgroundColor(nsAString& aColor);
 
   /**
    * Get the default length unit used for CSS Indent/Outdent.
    *
    * @param aLengthUnit    [OUT] The default length unit as it is defined in
    *                             prefs.
    */
-  void GetDefaultLengthUnit(nsAString & aLengthUnit);
+  static void GetDefaultLengthUnit(nsAString & aLengthUnit);
 
   /**
    * Returns the list of values for the CSS equivalences to
    * the passed HTML style for the passed node.
    *
    * @param aNode          [IN] A DOM node.
    * @param aHTMLProperty  [IN] An atom containing an HTML property.
    * @param aAttribute     [IN] An atom of attribute name or nullptr if
    *                            irrelevant.
    * @param aValueString   [OUT] The list of CSS values.
    * @param aStyleType     [IN] eSpecified or eComputed.
    */
-  nsresult GetCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode,
-                                                nsAtom* aHTMLProperty,
-                                                nsAtom* aAttribute,
-                                                nsAString& aValueString,
-                                                StyleType aStyleType);
+  static nsresult GetCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode,
+                                                       nsAtom* aHTMLProperty,
+                                                       nsAtom* aAttribute,
+                                                       nsAString& aValueString,
+                                                       StyleType aStyleType);
 
   /**
    * Does the node aNode (or his parent if it is not an element node) carries
    * the CSS equivalent styles to the HTML style for this node ?
    *
    * @param aNode          [IN] A DOM node.
    * @param aHTMLProperty  [IN] An atom containing an HTML property.
    * @param aAttribute     [IN] A pointer/atom to an attribute name or nullptr
    *                            if irrelevant.
    * @param aValueString   [IN/OUT] The attribute value (in) the list of CSS
    *                                values (out).
    * @param aStyleType     [IN] eSpecified or eComputed.
    * @return               A boolean being true if the css properties are
    *                       not same as initial value.
    */
-  bool IsCSSEquivalentToHTMLInlineStyleSet(nsINode* aContent,
-                                           nsAtom* aProperty,
-                                           nsAtom* aAttribute,
-                                           nsAString& aValue,
-                                           StyleType aStyleType);
+  static bool IsCSSEquivalentToHTMLInlineStyleSet(nsINode* aContent,
+                                                  nsAtom* aProperty,
+                                                  nsAtom* aAttribute,
+                                                  nsAString& aValue,
+                                                  StyleType aStyleType);
 
-  bool IsCSSEquivalentToHTMLInlineStyleSet(nsINode* aContent,
-                                           nsAtom* aProperty,
-                                           nsAtom* aAttribute,
-                                           const nsAString& aValue,
-                                           StyleType aStyleType);
+  static bool IsCSSEquivalentToHTMLInlineStyleSet(nsINode* aContent,
+                                                  nsAtom* aProperty,
+                                                  nsAtom* aAttribute,
+                                                  const nsAString& aValue,
+                                                  StyleType aStyleType);
 
-  bool IsCSSEquivalentToHTMLInlineStyleSet(nsINode* aContent,
-                                           nsAtom* aProperty,
-                                           const nsAString* aAttribute,
-                                           nsAString& aValue,
-                                           StyleType aStyleType);
+  static bool IsCSSEquivalentToHTMLInlineStyleSet(nsINode* aContent,
+                                                  nsAtom* aProperty,
+                                                  const nsAString* aAttribute,
+                                                  nsAString& aValue,
+                                                  StyleType aStyleType);
 
   /**
    * This is a kind of IsCSSEquivalentToHTMLInlineStyleSet.
    * IsCSSEquivalentToHTMLInlineStyleSet returns whether the properties
    * aren't same as initial value.  But this method returns whether the
    * properties aren't set.
    * If node is <span style="font-weight: normal"/>,
    *  - IsCSSEquivalentToHTMLInlineStyleSet returns false.
@@ -226,20 +226,20 @@ public:
    * @param aHTMLProperty  [IN] An atom containing an HTML property.
    * @param aAttribute     [IN] An atom to an attribute name or nullptr
    *                            if irrelevant.
    * @param aStyleType     [IN] eSpecified or eComputed.
    * @return               A boolean being true if the css properties are
    *                       not set.
    */
 
-  bool HaveCSSEquivalentStyles(nsINode& aNode,
-                               nsAtom* aProperty,
-                               nsAtom* aAttribute,
-                               StyleType aStyleType);
+  static bool HaveCSSEquivalentStyles(nsINode& aNode,
+                                      nsAtom* aProperty,
+                                      nsAtom* aAttribute,
+                                      StyleType aStyleType);
 
   /**
    * Adds to the node the CSS inline styles equivalent to the HTML style
    * and return the number of CSS properties set by the call.
    *
    * @param aNode          [IN] A DOM node.
    * @param aHTMLProperty  [IN] An atom containing an HTML property.
    * @param aAttribute     [IN] An atom to an attribute name or nullptr
@@ -277,105 +277,107 @@ public:
    * Parses a "xxxx.xxxxxuuu" string where x is a digit and u an alpha char
    * we need such a parser because
    * nsIDOMCSSStyleDeclaration::GetPropertyCSSValue() is not implemented.
    *
    * @param aString        [IN] Input string to parse.
    * @param aValue         [OUT] Numeric part.
    * @param aUnit          [OUT] Unit part.
    */
-  void ParseLength(const nsAString& aString, float* aValue, nsAtom** aUnit);
+  static void ParseLength(const nsAString& aString, float* aValue,
+                          nsAtom** aUnit);
 
   /**
    * Sets the mIsCSSPrefChecked private member; used as callback from observer
    *  when the CSS pref state is changed.
    *
    * @param aIsCSSPrefChecked [IN] The new boolean state for the pref.
    */
   void SetCSSEnabled(bool aIsCSSPrefChecked);
 
   /**
    * Retrieves the mIsCSSPrefChecked private member, true if the CSS pref is
    * checked, false if it is not.
    *
    * @return                 the boolean value of the CSS pref.
    */
-  bool IsCSSPrefChecked();
+  bool IsCSSPrefChecked() const;
 
   /**
    * ElementsSameStyle compares two elements and checks if they have the same
    * specified CSS declarations in the STYLE attribute.
    * The answer is always false if at least one of them carries an ID or a
    * class.
    *
    * @param aFirstNode           [IN] A DOM node.
    * @param aSecondNode          [IN] A DOM node.
    * @return                     true if the two elements are considered to
    *                             have same styles.
    */
-  bool ElementsSameStyle(dom::Element* aFirstNode,
-                         dom::Element* aSecondNode);
-  bool ElementsSameStyle(nsIDOMNode* aFirstNode, nsIDOMNode* aSecondNode);
+  static bool ElementsSameStyle(dom::Element* aFirstNode,
+                                dom::Element* aSecondNode);
 
   /**
    * Get the specified inline styles (style attribute) for an element.
    *
    * @param aElement        [IN] The element node.
    * @param aCssDecl        [OUT] The CSS declaration corresponding to the
    *                              style attribute.
    * @param aLength         [OUT] The number of declarations in aCssDecl.
    */
-  nsresult GetInlineStyles(dom::Element* aElement,
-                           nsICSSDeclaration** aCssDecl,
-                           uint32_t* aLength);
+  static nsresult GetInlineStyles(dom::Element* aElement,
+                                  nsICSSDeclaration** aCssDecl,
+                                  uint32_t* aLength);
 
 public:
   /**
    * Returns aNode itself if it is an element node, or the first ancestors
    * being an element node if aNode is not one itself.
    *
    * @param aNode           [IN] A node
    * @param aElement        [OUT] The deepest element node containing aNode
    *                              (possibly aNode itself)
    */
-  dom::Element* GetElementContainerOrSelf(nsINode* aNode);
+  static dom::Element* GetElementContainerOrSelf(nsINode* aNode);
 
   /**
    * Gets the computed style for a given element.  Can return null.
    */
-  already_AddRefed<nsComputedDOMStyle> GetComputedStyle(dom::Element* aElement);
+  static already_AddRefed<nsComputedDOMStyle>
+           GetComputedStyle(dom::Element* aElement);
 
 private:
   /**
    * Retrieves the CSS property atom from an enum.
    *
    * @param aProperty          [IN] The enum value for the property.
    * @param aAtom              [OUT] The corresponding atom.
    */
-  void GetCSSPropertyAtom(nsCSSEditableProperty aProperty, nsAtom** aAtom);
+  static void GetCSSPropertyAtom(nsCSSEditableProperty aProperty,
+                                 nsAtom** aAtom);
 
   /**
    * Retrieves the CSS declarations equivalent to a HTML style value for
    * a given equivalence table.
    *
    * @param aPropertyArray     [OUT] The array of css properties.
    * @param aValueArray        [OUT] The array of values for the CSS properties
    *                                 above.
    * @param aEquivTable        [IN] The equivalence table.
    * @param aValue             [IN] The HTML style value.
    * @param aGetOrRemoveRequest [IN] A boolean value being true if the call to
    *                                 the current method is made for
    *                                 GetCSSEquivalentToHTMLInlineStyleSet() or
    *                                 RemoveCSSEquivalentToHTMLInlineStyleSet().
    */
-  void BuildCSSDeclarations(nsTArray<nsAtom*>& aPropertyArray,
-                            nsTArray<nsString>& cssValueArray,
-                            const CSSEquivTable* aEquivTable,
-                            const nsAString* aValue,
-                            bool aGetOrRemoveRequest);
+  static void BuildCSSDeclarations(nsTArray<nsAtom*>& aPropertyArray,
+                                   nsTArray<nsString>& cssValueArray,
+                                   const CSSEquivTable* aEquivTable,
+                                   const nsAString* aValue,
+                                   bool aGetOrRemoveRequest);
 
   /**
    * Retrieves the CSS declarations equivalent to the given HTML
    * property/attribute/value for a given node.
    *
    * @param aNode              [IN] The DOM node.
    * @param aHTMLProperty      [IN] An atom containing an HTML property.
    * @param aAttribute         [IN] An atom to an attribute name or nullptr
@@ -384,34 +386,36 @@ private:
    * @param aPropertyArray     [OUT] The array of CSS properties.
    * @param aValueArray        [OUT] The array of values for the CSS properties
    *                                 above.
    * @param aGetOrRemoveRequest [IN] A boolean value being true if the call to
    *                                 the current method is made for
    *                                 GetCSSEquivalentToHTMLInlineStyleSet() or
    *                                 RemoveCSSEquivalentToHTMLInlineStyleSet().
    */
-  void GenerateCSSDeclarationsFromHTMLStyle(dom::Element* aNode,
-                                            nsAtom* aHTMLProperty,
-                                            nsAtom* aAttribute,
-                                            const nsAString* aValue,
-                                            nsTArray<nsAtom*>& aPropertyArray,
-                                            nsTArray<nsString>& aValueArray,
-                                            bool aGetOrRemoveRequest);
+  static void GenerateCSSDeclarationsFromHTMLStyle(
+                dom::Element* aNode,
+                nsAtom* aHTMLProperty,
+                nsAtom* aAttribute,
+                const nsAString* aValue,
+                nsTArray<nsAtom*>& aPropertyArray,
+                nsTArray<nsString>& aValueArray,
+                bool aGetOrRemoveRequest);
 
   /**
    * Back-end for GetSpecifiedProperty and GetComputedProperty.
    *
    * @param aNode               [IN] A DOM node.
    * @param aProperty           [IN] A CSS property.
    * @param aValue              [OUT] The retrieved value for this property.
    * @param aStyleType          [IN] eSpecified or eComputed.
    */
-  nsresult GetCSSInlinePropertyBase(nsINode* aNode, nsAtom* aProperty,
-                                    nsAString& aValue, StyleType aStyleType);
+  static nsresult GetCSSInlinePropertyBase(nsINode* aNode, nsAtom* aProperty,
+                                           nsAString& aValue,
+                                           StyleType aStyleType);
 
 private:
   HTMLEditor* mHTMLEditor;
   bool mIsCSSPrefChecked;
 };
 
 #define NS_EDITOR_INDENT_INCREMENT_IN        0.4134f
 #define NS_EDITOR_INDENT_INCREMENT_CM        1.05f
--- a/editor/libeditor/HTMLAbsPositionEditor.cpp
+++ b/editor/libeditor/HTMLAbsPositionEditor.cpp
@@ -81,18 +81,18 @@ HTMLEditor::SetSelectionToAbsoluteOrStat
 already_AddRefed<Element>
 HTMLEditor::GetAbsolutelyPositionedSelectionContainer()
 {
   nsAutoString positionStr;
   RefPtr<Element> element = GetSelectionContainer();
 
   while (element && !element->IsHTMLElement(nsGkAtoms::html)) {
     nsresult rv =
-      mCSSEditUtils->GetComputedProperty(*element, *nsGkAtoms::position,
-                                         positionStr);
+      CSSEditUtils::GetComputedProperty(*element, *nsGkAtoms::position,
+                                        positionStr);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return nullptr;
     }
     if (positionStr.EqualsLiteral("absolute")) {
       return element.forget();
     }
     element = element->GetParentElement();
   }
@@ -167,38 +167,38 @@ HTMLEditor::AddZIndex(int32_t aChange)
 }
 
 int32_t
 HTMLEditor::GetZIndex(Element& aElement)
 {
   nsAutoString zIndexStr;
 
   nsresult rv =
-    mCSSEditUtils->GetSpecifiedProperty(aElement, *nsGkAtoms::z_index,
-                                        zIndexStr);
+    CSSEditUtils::GetSpecifiedProperty(aElement, *nsGkAtoms::z_index,
+                                       zIndexStr);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return 0;
   }
   if (zIndexStr.EqualsLiteral("auto")) {
     // we have to look at the positioned ancestors
     // cf. CSS 2 spec section 9.9.1
     nsCOMPtr<nsINode> node = aElement.GetParentNode();
     nsAutoString positionStr;
     while (node && zIndexStr.EqualsLiteral("auto") &&
            !node->IsHTMLElement(nsGkAtoms::body)) {
-      rv = mCSSEditUtils->GetComputedProperty(*node, *nsGkAtoms::position,
-                                              positionStr);
+      rv = CSSEditUtils::GetComputedProperty(*node, *nsGkAtoms::position,
+                                             positionStr);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return 0;
       }
       if (positionStr.EqualsLiteral("absolute")) {
         // ah, we found one, what's its z-index ? If its z-index is auto,
         // we have to continue climbing the document's tree
-        rv = mCSSEditUtils->GetComputedProperty(*node, *nsGkAtoms::z_index,
-                                                zIndexStr);
+        rv = CSSEditUtils::GetComputedProperty(*node, *nsGkAtoms::z_index,
+                                               zIndexStr);
         if (NS_WARN_IF(NS_FAILED(rv))) {
           return 0;
         }
       }
       node = node->GetParentNode();
     }
   }
 
@@ -453,18 +453,18 @@ HTMLEditor::AddPositioningOffset(int32_t
   aY += positioningOffset;
 }
 
 nsresult
 HTMLEditor::SetPositionToAbsoluteOrStatic(Element& aElement,
                                           bool aEnabled)
 {
   nsAutoString positionStr;
-  mCSSEditUtils->GetComputedProperty(aElement, *nsGkAtoms::position,
-                                     positionStr);
+  CSSEditUtils::GetComputedProperty(aElement, *nsGkAtoms::position,
+                                    positionStr);
   bool isPositioned = (positionStr.EqualsLiteral("absolute"));
 
   // nothing to do if the element is already in the state we want
   if (isPositioned == aEnabled) {
     return NS_OK;
   }
 
   if (aEnabled) {
@@ -602,34 +602,34 @@ HTMLEditor::GetTemporaryStyleForFocusedP
   //       each above #d0, use a black background
   //   If the background color is 'auto' and at least one of R G B values of
   //       the foreground is below #d0, use a white background
   // Otherwise don't change background/foreground
   aReturn.Truncate();
 
   nsAutoString bgImageStr;
   nsresult rv =
-    mCSSEditUtils->GetComputedProperty(aElement, *nsGkAtoms::background_image,
-                                       bgImageStr);
+    CSSEditUtils::GetComputedProperty(aElement, *nsGkAtoms::background_image,
+                                      bgImageStr);
   NS_ENSURE_SUCCESS(rv, rv);
   if (!bgImageStr.EqualsLiteral("none")) {
     return NS_OK;
   }
 
   nsAutoString bgColorStr;
   rv =
-    mCSSEditUtils->GetComputedProperty(aElement, *nsGkAtoms::backgroundColor,
-                                       bgColorStr);
+    CSSEditUtils::GetComputedProperty(aElement, *nsGkAtoms::backgroundColor,
+                                      bgColorStr);
   NS_ENSURE_SUCCESS(rv, rv);
   if (!bgColorStr.EqualsLiteral("transparent")) {
     return NS_OK;
   }
 
   RefPtr<nsComputedDOMStyle> cssDecl =
-    mCSSEditUtils->GetComputedStyle(&aElement);
+    CSSEditUtils::GetComputedStyle(&aElement);
   NS_ENSURE_STATE(cssDecl);
 
   // from these declarations, get the one we want and that one only
   ErrorResult error;
   RefPtr<dom::CSSValue> cssVal =
     cssDecl->GetPropertyCSSValue(NS_LITERAL_STRING("color"), error);
   NS_ENSURE_TRUE(!error.Failed(), error.StealNSResult());
 
--- a/editor/libeditor/HTMLAnonymousNodeEditor.cpp
+++ b/editor/libeditor/HTMLAnonymousNodeEditor.cpp
@@ -482,28 +482,28 @@ HTMLEditor::GetPositionAndDimensions(Ele
                                      int32_t& aMarginTop)
 {
   // Is the element positioned ? let's check the cheap way first...
   bool isPositioned =
     aElement.HasAttr(kNameSpaceID_None, nsGkAtoms::_moz_abspos);
   if (!isPositioned) {
     // hmmm... the expensive way now...
     nsAutoString positionStr;
-    mCSSEditUtils->GetComputedProperty(aElement, *nsGkAtoms::position,
+    CSSEditUtils::GetComputedProperty(aElement, *nsGkAtoms::position,
                                        positionStr);
     isPositioned = positionStr.EqualsLiteral("absolute");
   }
 
   if (isPositioned) {
     // Yes, it is absolutely positioned
     mResizedObjectIsAbsolutelyPositioned = true;
 
     // Get the all the computed css styles attached to the element node
     RefPtr<nsComputedDOMStyle> cssDecl =
-      mCSSEditUtils->GetComputedStyle(&aElement);
+      CSSEditUtils::GetComputedStyle(&aElement);
     NS_ENSURE_STATE(cssDecl);
 
     aBorderLeft = GetCSSFloatValue(cssDecl, NS_LITERAL_STRING("border-left-width"));
     aBorderTop  = GetCSSFloatValue(cssDecl, NS_LITERAL_STRING("border-top-width"));
     aMarginLeft = GetCSSFloatValue(cssDecl, NS_LITERAL_STRING("margin-left"));
     aMarginTop  = GetCSSFloatValue(cssDecl, NS_LITERAL_STRING("margin-top"));
 
     aX = GetCSSFloatValue(cssDecl, NS_LITERAL_STRING("left")) +
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -873,23 +873,23 @@ HTMLEditRules::GetAlignment(bool* aMixed
 
   NS_ENSURE_TRUE(nodeToExamine, NS_ERROR_NULL_POINTER);
 
   nsCOMPtr<Element> blockParent = htmlEditor->GetBlock(*nodeToExamine);
 
   NS_ENSURE_TRUE(blockParent, NS_ERROR_FAILURE);
 
   if (htmlEditor->IsCSSEnabled() &&
-      htmlEditor->mCSSEditUtils->IsCSSEditableProperty(blockParent, nullptr,
-                                                       nsGkAtoms::align)) {
+      CSSEditUtils::IsCSSEditableProperty(blockParent, nullptr,
+                                          nsGkAtoms::align)) {
     // We are in CSS mode and we know how to align this element with CSS
     nsAutoString value;
     // Let's get the value(s) of text-align or margin-left/margin-right
-    htmlEditor->mCSSEditUtils->GetCSSEquivalentToHTMLInlineStyleSet(
-        blockParent, nullptr, nsGkAtoms::align, value, CSSEditUtils::eComputed);
+    CSSEditUtils::GetCSSEquivalentToHTMLInlineStyleSet(
+      blockParent, nullptr, nsGkAtoms::align, value, CSSEditUtils::eComputed);
     if (value.EqualsLiteral("center") ||
         value.EqualsLiteral("-moz-center") ||
         value.EqualsLiteral("auto auto")) {
       *aAlign = nsIHTMLEditor::eCenter;
       return NS_OK;
     }
     if (value.EqualsLiteral("right") ||
         value.EqualsLiteral("-moz-right") ||
@@ -911,22 +911,22 @@ HTMLEditRules::GetAlignment(bool* aMixed
     if (!isFirstNodeToExamine &&
         nodeToExamine->IsHTMLElement(nsGkAtoms::table)) {
       // The node to examine is a table and this is not the first node we
       // examine; let's break here to materialize the 'inline-block' behaviour
       // of html tables regarding to text alignment
       return NS_OK;
     }
 
-    if (htmlEditor->mCSSEditUtils->IsCSSEditableProperty(nodeToExamine, nullptr,
-                                                         nsGkAtoms::align)) {
+    if (CSSEditUtils::IsCSSEditableProperty(nodeToExamine, nullptr,
+                                            nsGkAtoms::align)) {
       nsAutoString value;
-      htmlEditor->mCSSEditUtils->GetSpecifiedProperty(*nodeToExamine,
-                                                      *nsGkAtoms::textAlign,
-                                                      value);
+      CSSEditUtils::GetSpecifiedProperty(*nodeToExamine,
+                                         *nsGkAtoms::textAlign,
+                                         value);
       if (!value.IsEmpty()) {
         if (value.EqualsLiteral("center")) {
           *aAlign = nsIHTMLEditor::eCenter;
           return NS_OK;
         }
         if (value.EqualsLiteral("right")) {
           *aAlign = nsIHTMLEditor::eRight;
           return NS_OK;
@@ -963,21 +963,21 @@ HTMLEditRules::GetAlignment(bool* aMixed
         return NS_OK;
       }
     }
     isFirstNodeToExamine = false;
   }
   return NS_OK;
 }
 
-static nsAtom& MarginPropertyAtomForIndent(CSSEditUtils& aHTMLCSSUtils,
-                                            nsINode& aNode)
+static nsAtom&
+MarginPropertyAtomForIndent(nsINode& aNode)
 {
   nsAutoString direction;
-  aHTMLCSSUtils.GetComputedProperty(aNode, *nsGkAtoms::direction, direction);
+  CSSEditUtils::GetComputedProperty(aNode, *nsGkAtoms::direction, direction);
   return direction.EqualsLiteral("rtl") ?
     *nsGkAtoms::marginRight : *nsGkAtoms::marginLeft;
 }
 
 nsresult
 HTMLEditRules::GetIndentState(bool* aCanIndent,
                               bool* aCanOutdent)
 {
@@ -1004,29 +1004,24 @@ HTMLEditRules::GetIndentState(bool* aCan
   NS_ENSURE_STATE(mHTMLEditor);
   bool useCSS = mHTMLEditor->IsCSSEnabled();
   for (auto& curNode : Reversed(arrayOfNodes)) {
     if (HTMLEditUtils::IsNodeThatCanOutdent(curNode)) {
       *aCanOutdent = true;
       break;
     } else if (useCSS) {
       // we are in CSS mode, indentation is done using the margin-left (or margin-right) property
-      NS_ENSURE_STATE(mHTMLEditor);
-      nsAtom& marginProperty =
-        MarginPropertyAtomForIndent(*mHTMLEditor->mCSSEditUtils, curNode);
+      nsAtom& marginProperty = MarginPropertyAtomForIndent(curNode);
       nsAutoString value;
       // retrieve its specified value
-      NS_ENSURE_STATE(mHTMLEditor);
-      mHTMLEditor->mCSSEditUtils->GetSpecifiedProperty(*curNode,
-                                                       marginProperty, value);
+      CSSEditUtils::GetSpecifiedProperty(*curNode, marginProperty, value);
       float f;
       RefPtr<nsAtom> unit;
       // get its number part and its unit
-      NS_ENSURE_STATE(mHTMLEditor);
-      mHTMLEditor->mCSSEditUtils->ParseLength(value, &f, getter_AddRefs(unit));
+      CSSEditUtils::ParseLength(value, &f, getter_AddRefs(unit));
       // if the number part is strictly positive, outdent is possible
       if (0 < f) {
         *aCanOutdent = true;
         break;
       }
     }
   }
 
@@ -4543,27 +4538,22 @@ HTMLEditRules::WillOutdent(Selection& aS
           curBlockQuoteIsIndentedWithCSS = false;
         }
         rv = htmlEditor->RemoveBlockContainer(curNode);
         NS_ENSURE_SUCCESS(rv, rv);
         continue;
       }
       // Is it a block with a 'margin' property?
       if (useCSS && IsBlockNode(curNode)) {
-        nsAtom& marginProperty =
-          MarginPropertyAtomForIndent(*htmlEditor->mCSSEditUtils, curNode);
+        nsAtom& marginProperty = MarginPropertyAtomForIndent(curNode);
         nsAutoString value;
-        htmlEditor->mCSSEditUtils->GetSpecifiedProperty(curNode,
-                                                         marginProperty,
-                                                         value);
+        CSSEditUtils::GetSpecifiedProperty(curNode, marginProperty, value);
         float f;
         RefPtr<nsAtom> unit;
-        NS_ENSURE_STATE(htmlEditor);
-        htmlEditor->mCSSEditUtils->ParseLength(value, &f,
-                                               getter_AddRefs(unit));
+        CSSEditUtils::ParseLength(value, &f, getter_AddRefs(unit));
         if (f > 0) {
           ChangeIndentation(*curNode->AsElement(), Change::minus);
           continue;
         }
       }
       // Is it a list item?
       if (HTMLEditUtils::IsListItem(curNode)) {
         // If it is a list item, that means we are not outdenting whole list.
@@ -4622,24 +4612,22 @@ HTMLEditRules::WillOutdent(Selection& aS
         n = *n->GetParentNode();
         if (n->IsHTMLElement(nsGkAtoms::blockquote)) {
           // If so, remember it and the first node we are taking out of it.
           curBlockQuote = n->AsElement();
           firstBQChild = curNode;
           lastBQChild = curNode;
           break;
         } else if (useCSS) {
-          nsAtom& marginProperty =
-            MarginPropertyAtomForIndent(*htmlEditor->mCSSEditUtils, curNode);
+          nsAtom& marginProperty = MarginPropertyAtomForIndent(curNode);
           nsAutoString value;
-          htmlEditor->mCSSEditUtils->GetSpecifiedProperty(*n, marginProperty,
-                                                           value);
+          CSSEditUtils::GetSpecifiedProperty(*n, marginProperty, value);
           float f;
           RefPtr<nsAtom> unit;
-          htmlEditor->mCSSEditUtils->ParseLength(value, &f, getter_AddRefs(unit));
+          CSSEditUtils::ParseLength(value, &f, getter_AddRefs(unit));
           if (f > 0 && !(HTMLEditUtils::IsList(curParent) &&
                          HTMLEditUtils::IsList(curNode))) {
             curBlockQuote = n->AsElement();
             firstBQChild = curNode;
             lastBQChild = curNode;
             curBlockQuoteIsIndentedWithCSS = true;
             break;
           }
@@ -7762,18 +7750,18 @@ HTMLEditRules::JoinNodesSmart(nsIContent
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return EditorDOMPoint();
   }
 
   if (lastLeft && firstRight && mHTMLEditor &&
       mHTMLEditor->AreNodesSameType(lastLeft, firstRight) &&
       (lastLeft->GetAsText() || !mHTMLEditor ||
        (lastLeft->IsElement() && firstRight->IsElement() &&
-        mHTMLEditor->mCSSEditUtils->ElementsSameStyle(lastLeft->AsElement(),
-                                                  firstRight->AsElement())))) {
+        CSSEditUtils::ElementsSameStyle(lastLeft->AsElement(),
+                                        firstRight->AsElement())))) {
     if (NS_WARN_IF(!mHTMLEditor)) {
       return EditorDOMPoint();
     }
     return JoinNodesSmart(*lastLeft, *firstRight);
   }
   return ret;
 }
 
@@ -7836,18 +7824,17 @@ HTMLEditRules::GetInlineStyles(nsINode* 
     if (!useCSS || (aStyleCache[j].tag == nsGkAtoms::font &&
                     aStyleCache[j].attr == nsGkAtoms::size)) {
       NS_ENSURE_STATE(mHTMLEditor);
       isSet = mHTMLEditor->IsTextPropertySetByContent(aNode, aStyleCache[j].tag,
                                                       aStyleCache[j].attr,
                                                       nullptr,
                                                       &outValue);
     } else {
-      NS_ENSURE_STATE(mHTMLEditor);
-      isSet = mHTMLEditor->mCSSEditUtils->IsCSSEquivalentToHTMLInlineStyleSet(
+      isSet = CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(
                 aNode, aStyleCache[j].tag, aStyleCache[j].attr, outValue,
                 CSSEditUtils::eComputed);
     }
     if (isSet) {
       aStyleCache[j].mPresent = true;
       aStyleCache[j].value.Assign(outValue);
     }
   }
@@ -7895,20 +7882,19 @@ HTMLEditRules::ReapplyCachedStyles()
   for (size_t i = 0; i < SIZE_STYLE_TABLE; ++i) {
     if (mCachedStyles[i].mPresent) {
       bool bFirst, bAny, bAll;
       bFirst = bAny = bAll = false;
 
       nsAutoString curValue;
       if (useCSS) {
         // check computed style first in css case
-        NS_ENSURE_STATE(mHTMLEditor);
-        bAny = mHTMLEditor->mCSSEditUtils->IsCSSEquivalentToHTMLInlineStyleSet(
-          selNode, mCachedStyles[i].tag, mCachedStyles[i].attr, curValue,
-          CSSEditUtils::eComputed);
+        bAny = CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(
+                 selNode, mCachedStyles[i].tag, mCachedStyles[i].attr, curValue,
+                 CSSEditUtils::eComputed);
       }
       if (!bAny) {
         // then check typeinstate and html style
         NS_ENSURE_STATE(mHTMLEditor);
         nsresult rv =
           mHTMLEditor->GetInlinePropertyBase(*mCachedStyles[i].tag,
                                              mCachedStyles[i].attr,
                                              &(mCachedStyles[i].value),
@@ -9176,27 +9162,25 @@ HTMLEditRules::AlignBlock(Element& aElem
 
 nsresult
 HTMLEditRules::ChangeIndentation(Element& aElement,
                                  Change aChange)
 {
   NS_ENSURE_STATE(mHTMLEditor);
   RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
 
-  nsAtom& marginProperty =
-    MarginPropertyAtomForIndent(*htmlEditor->mCSSEditUtils, aElement);
+  nsAtom& marginProperty = MarginPropertyAtomForIndent(aElement);
   nsAutoString value;
-  htmlEditor->mCSSEditUtils->GetSpecifiedProperty(aElement, marginProperty,
-                                                  value);
+  CSSEditUtils::GetSpecifiedProperty(aElement, marginProperty, value);
   float f;
   RefPtr<nsAtom> unit;
-  htmlEditor->mCSSEditUtils->ParseLength(value, &f, getter_AddRefs(unit));
+  CSSEditUtils::ParseLength(value, &f, getter_AddRefs(unit));
   if (!f) {
     nsAutoString defaultLengthUnit;
-    htmlEditor->mCSSEditUtils->GetDefaultLengthUnit(defaultLengthUnit);
+    CSSEditUtils::GetDefaultLengthUnit(defaultLengthUnit);
     unit = NS_Atomize(defaultLengthUnit);
   }
   int8_t multiplier = aChange == Change::plus ? +1 : -1;
   if (nsGkAtoms::in == unit) {
     f += NS_EDITOR_INDENT_INCREMENT_IN * multiplier;
   } else if (nsGkAtoms::cm == unit) {
     f += NS_EDITOR_INDENT_INCREMENT_CM * multiplier;
   } else if (nsGkAtoms::mm == unit) {
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -1719,28 +1719,28 @@ HTMLEditor::GetCSSBackgroundColorState(b
     // we are querying the block background (and not the text background), let's
     // climb to the block container
     nsCOMPtr<Element> blockParent = GetBlock(*nodeToExamine);
     NS_ENSURE_TRUE(blockParent, NS_OK);
 
     // Make sure to not walk off onto the Document node
     do {
       // retrieve the computed style of background-color for blockParent
-      mCSSEditUtils->GetComputedProperty(*blockParent,
-                                         *nsGkAtoms::backgroundColor,
-                                         aOutColor);
+      CSSEditUtils::GetComputedProperty(*blockParent,
+                                        *nsGkAtoms::backgroundColor,
+                                        aOutColor);
       blockParent = blockParent->GetParentElement();
       // look at parent if the queried color is transparent and if the node to
       // examine is not the root of the document
     } while (aOutColor.EqualsLiteral("transparent") && blockParent);
     if (aOutColor.EqualsLiteral("transparent")) {
       // we have hit the root of the document and the color is still transparent !
       // Grumble... Let's look at the default background color because that's the
       // color we are looking for
-      mCSSEditUtils->GetDefaultBackgroundColor(aOutColor);
+      CSSEditUtils::GetDefaultBackgroundColor(aOutColor);
     }
   }
   else {
     // no, we are querying the text background for the Text Highlight button
     if (IsTextNode(nodeToExamine)) {
       // if the node of interest is a text node, let's climb a level
       nodeToExamine = nodeToExamine->GetParentNode();
     }
@@ -1752,19 +1752,19 @@ HTMLEditor::GetCSSBackgroundColorState(b
       // is the node to examine a block ?
       if (NodeIsBlockStatic(nodeToExamine)) {
         // yes it is a block; in that case, the text background color is transparent
         aOutColor.AssignLiteral("transparent");
         break;
       } else {
         // no, it's not; let's retrieve the computed style of background-color for the
         // node to examine
-        mCSSEditUtils->GetComputedProperty(*nodeToExamine,
-                                           *nsGkAtoms::backgroundColor,
-                                           aOutColor);
+        CSSEditUtils::GetComputedProperty(*nodeToExamine,
+                                          *nsGkAtoms::backgroundColor,
+                                          aOutColor);
         if (!aOutColor.EqualsLiteral("transparent")) {
           break;
         }
       }
       nodeToExamine = nodeToExamine->GetParentNode();
     } while ( aOutColor.EqualsLiteral("transparent") && nodeToExamine );
   }
   return NS_OK;
@@ -4308,19 +4308,23 @@ HTMLEditor::AreNodesSameType(nsIContent*
   if (aNode1->NodeInfo()->NameAtom() != aNode2->NodeInfo()->NameAtom()) {
     return false;
   }
 
   if (!IsCSSEnabled() || !aNode1->IsHTMLElement(nsGkAtoms::span)) {
     return true;
   }
 
+  if (!aNode1->IsElement() || !aNode2->IsElement()) {
+    return false;
+  }
+
   // If CSS is enabled, we are stricter about span nodes.
-  return mCSSEditUtils->ElementsSameStyle(aNode1->AsDOMNode(),
-                                          aNode2->AsDOMNode());
+  return CSSEditUtils::ElementsSameStyle(aNode1->AsElement(),
+                                         aNode2->AsElement());
 }
 
 nsresult
 HTMLEditor::CopyLastEditableChildStyles(nsINode* aPreviousBlock,
                                         nsINode* aNewBlock,
                                         Element** aOutBrNode)
 {
   nsCOMPtr<nsINode> newBlock = do_QueryInterface(aNewBlock);
--- a/editor/libeditor/HTMLEditor.h
+++ b/editor/libeditor/HTMLEditor.h
@@ -482,17 +482,17 @@ public:
 
   /**
    * Add a url + known style sheet to the internal lists.
    */
   nsresult AddNewStyleSheetToList(const nsAString &aURL,
                                   StyleSheet* aStyleSheet);
   nsresult RemoveStyleSheetFromList(const nsAString &aURL);
 
-  bool IsCSSEnabled()
+  bool IsCSSEnabled() const
   {
     // TODO: removal of mCSSAware and use only the presence of mCSSEditUtils
     return mCSSAware && mCSSEditUtils && mCSSEditUtils->IsCSSPrefChecked();
   }
 
   static bool HasAttributes(Element* aElement)
   {
     MOZ_ASSERT(aElement);
--- a/editor/libeditor/HTMLEditorObjectResizer.cpp
+++ b/editor/libeditor/HTMLEditorObjectResizer.cpp
@@ -189,22 +189,22 @@ HTMLEditor::SetAllResizersPosition()
   int32_t h = mResizedObjectHeight;
 
   // now let's place all the resizers around the image
 
   // get the size of resizers
   nsAutoString value;
   float resizerWidth, resizerHeight;
   RefPtr<nsAtom> dummyUnit;
-  mCSSEditUtils->GetComputedProperty(*mTopLeftHandle, *nsGkAtoms::width,
-                                     value);
-  mCSSEditUtils->ParseLength(value, &resizerWidth, getter_AddRefs(dummyUnit));
-  mCSSEditUtils->GetComputedProperty(*mTopLeftHandle, *nsGkAtoms::height,
-                                     value);
-  mCSSEditUtils->ParseLength(value, &resizerHeight, getter_AddRefs(dummyUnit));
+  CSSEditUtils::GetComputedProperty(*mTopLeftHandle, *nsGkAtoms::width,
+                                    value);
+  CSSEditUtils::ParseLength(value, &resizerWidth, getter_AddRefs(dummyUnit));
+  CSSEditUtils::GetComputedProperty(*mTopLeftHandle, *nsGkAtoms::height,
+                                    value);
+  CSSEditUtils::ParseLength(value, &resizerHeight, getter_AddRefs(dummyUnit));
 
   int32_t rw  = (int32_t)((resizerWidth + 1) / 2);
   int32_t rh =  (int32_t)((resizerHeight+ 1) / 2);
 
   SetAnonymousElementPosition(x-rw,     y-rh, mTopLeftHandle);
   SetAnonymousElementPosition(x+w/2-rw, y-rh, mTopHandle);
   SetAnonymousElementPosition(x+w-rw-1, y-rh, mTopRightHandle);
 
--- a/editor/libeditor/HTMLStyleEditor.cpp
+++ b/editor/libeditor/HTMLStyleEditor.cpp
@@ -227,17 +227,17 @@ HTMLEditor::IsSimpleModifiableNode(nsICo
       // Property-specific handling is needed (bug 760211).
       return true;
     }
   }
 
   // No luck so far.  Now we check for a <span> with a single style=""
   // attribute that sets only the style we're looking for, if this type of
   // style supports it
-  if (!mCSSEditUtils->IsCSSEditableProperty(element, aProperty, aAttribute) ||
+  if (!CSSEditUtils::IsCSSEditableProperty(element, aProperty, aAttribute) ||
       !element->IsHTMLElement(nsGkAtoms::span) ||
       element->GetAttrCount() != 1 ||
       !element->HasAttr(kNameSpaceID_None, nsGkAtoms::style)) {
     return false;
   }
 
   // Some CSS styles are not so simple.  For instance, underline is
   // "text-decoration: underline", which decomposes into four different text-*
@@ -245,17 +245,17 @@ HTMLEditor::IsSimpleModifiableNode(nsICo
   // see if it matches.
   nsCOMPtr<Element> newSpan = CreateHTMLContent(nsGkAtoms::span);
   NS_ASSERTION(newSpan, "CreateHTMLContent failed");
   NS_ENSURE_TRUE(newSpan, false);
   mCSSEditUtils->SetCSSEquivalentToHTMLStyle(newSpan, aProperty,
                                              aAttribute, aValue,
                                              /*suppress transaction*/ true);
 
-  return mCSSEditUtils->ElementsSameStyle(newSpan, element);
+  return CSSEditUtils::ElementsSameStyle(newSpan, element);
 }
 
 nsresult
 HTMLEditor::SetInlinePropertyOnTextNode(Text& aText,
                                         int32_t aStartOffset,
                                         int32_t aEndOffset,
                                         nsAtom& aProperty,
                                         nsAtom* aAttribute,
@@ -267,20 +267,20 @@ HTMLEditor::SetInlinePropertyOnTextNode(
   }
 
   // Don't need to do anything if no characters actually selected
   if (aStartOffset == aEndOffset) {
     return NS_OK;
   }
 
   // Don't need to do anything if property already set on node
-  if (mCSSEditUtils->IsCSSEditableProperty(&aText, &aProperty, aAttribute)) {
+  if (CSSEditUtils::IsCSSEditableProperty(&aText, &aProperty, aAttribute)) {
     // The HTML styles defined by aProperty/aAttribute have a CSS equivalence
     // for node; let's check if it carries those CSS styles
-    if (mCSSEditUtils->IsCSSEquivalentToHTMLInlineStyleSet(&aText, &aProperty,
+    if (CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(&aText, &aProperty,
           aAttribute, aValue, CSSEditUtils::eComputed)) {
       return NS_OK;
     }
   } else if (IsTextPropertySetByContent(&aText, &aProperty, aAttribute,
                                         &aValue)) {
     return NS_OK;
   }
 
@@ -374,29 +374,29 @@ HTMLEditor::SetInlinePropertyOnNodeImpl(
   }
   if (IsSimpleModifiableNode(nextSibling, &aProperty, aAttribute, &aValue)) {
     nsresult rv = MoveNode(&aNode, nextSibling, 0);
     NS_ENSURE_SUCCESS(rv, rv);
     return NS_OK;
   }
 
   // Don't need to do anything if property already set on node
-  if (mCSSEditUtils->IsCSSEditableProperty(&aNode, &aProperty, aAttribute)) {
-    if (mCSSEditUtils->IsCSSEquivalentToHTMLInlineStyleSet(
+  if (CSSEditUtils::IsCSSEditableProperty(&aNode, &aProperty, aAttribute)) {
+    if (CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(
           &aNode, &aProperty, aAttribute, aValue, CSSEditUtils::eComputed)) {
       return NS_OK;
     }
   } else if (IsTextPropertySetByContent(&aNode, &aProperty,
                                         aAttribute, &aValue)) {
     return NS_OK;
   }
 
   bool useCSS = (IsCSSEnabled() &&
-                 mCSSEditUtils->IsCSSEditableProperty(&aNode, &aProperty,
-                                                      aAttribute)) ||
+                 CSSEditUtils::IsCSSEditableProperty(&aNode, &aProperty,
+                                                     aAttribute)) ||
                 // bgcolor is always done using CSS
                 aAttribute == nsGkAtoms::bgcolor;
 
   if (useCSS) {
     nsCOMPtr<dom::Element> tmp;
     // We only add style="" to <span>s with no attributes (bug 746515).  If we
     // don't have one, we need to make one.
     if (aNode.IsHTMLElement(nsGkAtoms::span) &&
@@ -532,23 +532,23 @@ HTMLEditor::SplitStyleAbovePoint(nsCOMPt
   OwningNonNull<nsIContent> node = *(*aNode)->AsContent();
 
   bool useCSS = IsCSSEnabled();
 
   bool isSet;
   while (!IsBlockNode(node) && node->GetParent() &&
          IsEditable(node->GetParent())) {
     isSet = false;
-    if (useCSS && mCSSEditUtils->IsCSSEditableProperty(node, aProperty,
-                                                       aAttribute)) {
+    if (useCSS && CSSEditUtils::IsCSSEditableProperty(node, aProperty,
+                                                      aAttribute)) {
       // The HTML style defined by aProperty/aAttribute has a CSS equivalence
       // in this implementation for the node; let's check if it carries those
       // CSS styles
       nsAutoString firstValue;
-      isSet = mCSSEditUtils->IsCSSEquivalentToHTMLInlineStyleSet(
+      isSet = CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(
                 node, aProperty, aAttribute, firstValue,
                 CSSEditUtils::eSpecified);
     }
     if (// node is the correct inline prop
         (aProperty && node->IsHTMLElement(aProperty)) ||
         // node is href - test if really <a href=...
         (aProperty == nsGkAtoms::href && HTMLEditUtils::IsLink(node)) ||
         // or node is any prop, and we asked to split them all
@@ -747,25 +747,25 @@ HTMLEditor::RemoveStyleInside(nsIContent
             return rv;
           }
         }
       }
     }
   }
 
   if (!aChildrenOnly &&
-      mCSSEditUtils->IsCSSEditableProperty(&aNode, aProperty, aAttribute)) {
+      CSSEditUtils::IsCSSEditableProperty(&aNode, aProperty, aAttribute)) {
     // the HTML style defined by aProperty/aAttribute has a CSS equivalence in
     // this implementation for the node aNode; let's check if it carries those
     // css styles
     if (aNode.IsElement()) {
       bool hasAttribute =
-        mCSSEditUtils->HaveCSSEquivalentStyles(
-                         aNode, aProperty, aAttribute,
-                         CSSEditUtils::eSpecified);
+        CSSEditUtils::HaveCSSEquivalentStyles(
+                        aNode, aProperty, aAttribute,
+                        CSSEditUtils::eSpecified);
       if (hasAttribute) {
         // yes, tmp has the corresponding css declarations in its style
         // attribute
         // let's remove them
         mCSSEditUtils->RemoveCSSEquivalentToHTMLStyle(aNode.AsElement(),
                                                       aProperty,
                                                       aAttribute,
                                                       nullptr,
@@ -976,24 +976,25 @@ HTMLEditor::GetInlinePropertyBase(nsAtom
       } else {
         mTypeInState->GetTypingState(isSet, theSetting, &aProperty);
       }
       if (isSet) {
         *aFirst = *aAny = *aAll = theSetting;
         return NS_OK;
       }
 
-      if (mCSSEditUtils->IsCSSEditableProperty(collapsedNode, &aProperty,
-                                               aAttribute)) {
+      if (CSSEditUtils::IsCSSEditableProperty(collapsedNode, &aProperty,
+                                              aAttribute)) {
         if (aValue) {
           tOutString.Assign(*aValue);
         }
         *aFirst = *aAny = *aAll =
-          mCSSEditUtils->IsCSSEquivalentToHTMLInlineStyleSet(collapsedNode,
-              &aProperty, aAttribute, tOutString, CSSEditUtils::eComputed);
+          CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(
+                          collapsedNode, &aProperty, aAttribute, tOutString,
+                          CSSEditUtils::eComputed);
         if (outValue) {
           outValue->Assign(tOutString);
         }
         return NS_OK;
       }
 
       isSet = IsTextPropertySetByContent(collapsedNode, &aProperty,
                                          aAttribute, aValue, outValue);
@@ -1035,46 +1036,47 @@ HTMLEditor::GetInlinePropertyBase(nsAtom
         }
       } else if (content->IsElement()) {
         // handle non-text leaf nodes here
         continue;
       }
 
       bool isSet = false;
       if (first) {
-        if (mCSSEditUtils->IsCSSEditableProperty(content, &aProperty,
-                                                 aAttribute)) {
+        if (CSSEditUtils::IsCSSEditableProperty(content, &aProperty,
+                                                aAttribute)) {
           // The HTML styles defined by aProperty/aAttribute have a CSS
           // equivalence in this implementation for node; let's check if it
           // carries those CSS styles
           if (aValue) {
             firstValue.Assign(*aValue);
           }
-          isSet = mCSSEditUtils->IsCSSEquivalentToHTMLInlineStyleSet(content,
-              &aProperty, aAttribute, firstValue, CSSEditUtils::eComputed);
+          isSet = CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(
+                    content, &aProperty, aAttribute, firstValue,
+                    CSSEditUtils::eComputed);
         } else {
           isSet = IsTextPropertySetByContent(content, &aProperty, aAttribute,
                                              aValue, &firstValue);
         }
         *aFirst = isSet;
         first = false;
         if (outValue) {
           *outValue = firstValue;
         }
       } else {
-        if (mCSSEditUtils->IsCSSEditableProperty(content, &aProperty,
-                                                 aAttribute)) {
+        if (CSSEditUtils::IsCSSEditableProperty(content, &aProperty,
+                                                aAttribute)) {
           // The HTML styles defined by aProperty/aAttribute have a CSS
           // equivalence in this implementation for node; let's check if it
           // carries those CSS styles
           if (aValue) {
             theValue.Assign(*aValue);
           }
-          isSet = mCSSEditUtils->IsCSSEquivalentToHTMLInlineStyleSet(content,
-              &aProperty, aAttribute, theValue, CSSEditUtils::eComputed);
+          isSet = CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(
+              content, &aProperty, aAttribute, theValue, CSSEditUtils::eComputed);
         } else {
           isSet = IsTextPropertySetByContent(content, &aProperty, aAttribute,
                                              aValue, &theValue);
         }
         if (firstValue != theValue) {
           *aAll = false;
         }
       }
@@ -1242,28 +1244,28 @@ HTMLEditor::RemoveInlineProperty(nsAtom*
       NS_ENSURE_SUCCESS(rv, rv);
 
       // Check for easy case: both range endpoints in same text node
       nsCOMPtr<nsINode> startNode = range->GetStartContainer();
       nsCOMPtr<nsINode> endNode = range->GetEndContainer();
       if (startNode && startNode == endNode && startNode->GetAsText()) {
         // We're done with this range!
         if (IsCSSEnabled() &&
-            mCSSEditUtils->IsCSSEditableProperty(startNode, aProperty,
-                                                 aAttribute)) {
+            CSSEditUtils::IsCSSEditableProperty(startNode, aProperty,
+                                                aAttribute)) {
           // The HTML style defined by aProperty/aAttribute has a CSS
           // equivalence in this implementation for startNode
-          if (mCSSEditUtils->IsCSSEquivalentToHTMLInlineStyleSet(startNode,
-                aProperty, aAttribute, EmptyString(),
-                CSSEditUtils::eComputed)) {
+          if (CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(
+                              startNode, aProperty, aAttribute, EmptyString(),
+                              CSSEditUtils::eComputed)) {
             // startNode's computed style indicates the CSS equivalence to the
             // HTML style to remove is applied; but we found no element in the
             // ancestors of startNode carrying specified styles; assume it
             // comes from a rule and try to insert a span "inverting" the style
-            if (mCSSEditUtils->IsCSSInvertible(*aProperty, aAttribute)) {
+            if (CSSEditUtils::IsCSSInvertible(*aProperty, aAttribute)) {
               NS_NAMED_LITERAL_STRING(value, "-moz-editor-invert-value");
               SetInlinePropertyOnTextNode(*startNode->GetAsText(),
                                           range->StartOffset(),
                                           range->EndOffset(), *aProperty,
                                           aAttribute, value);
             }
           }
         }
@@ -1283,27 +1285,27 @@ HTMLEditor::RemoveInlineProperty(nsAtom*
           }
         }
 
         // Loop through the list, remove the property on each node
         for (auto& node : arrayOfNodes) {
           rv = RemoveStyleInside(node, aProperty, aAttribute);
           NS_ENSURE_SUCCESS(rv, rv);
           if (IsCSSEnabled() &&
-              mCSSEditUtils->IsCSSEditableProperty(node, aProperty,
-                                                   aAttribute) &&
-              mCSSEditUtils->IsCSSEquivalentToHTMLInlineStyleSet(node,
-                  aProperty, aAttribute, EmptyString(),
-                  CSSEditUtils::eComputed) &&
+              CSSEditUtils::IsCSSEditableProperty(node, aProperty,
+                                                  aAttribute) &&
+              CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(
+                              node, aProperty, aAttribute, EmptyString(),
+                              CSSEditUtils::eComputed) &&
               // startNode's computed style indicates the CSS equivalence to
               // the HTML style to remove is applied; but we found no element
               // in the ancestors of startNode carrying specified styles;
               // assume it comes from a rule and let's try to insert a span
               // "inverting" the style
-              mCSSEditUtils->IsCSSInvertible(*aProperty, aAttribute)) {
+              CSSEditUtils::IsCSSInvertible(*aProperty, aAttribute)) {
             NS_NAMED_LITERAL_STRING(value, "-moz-editor-invert-value");
             SetInlinePropertyOnNode(node, *aProperty, aAttribute, value);
           }
         }
       }
     }
   }
   if (!cancel) {
--- a/gfx/2d/CaptureCommandList.h
+++ b/gfx/2d/CaptureCommandList.h
@@ -6,43 +6,59 @@
 
 #ifndef mozilla_gfx_2d_CaptureCommandList_h
 #define mozilla_gfx_2d_CaptureCommandList_h
 
 #include "mozilla/Move.h"
 #include "mozilla/PodOperations.h"
 #include <vector>
 
+#include "DrawCommand.h"
+
 namespace mozilla {
 namespace gfx {
 
-class DrawingCommand;
-
 class CaptureCommandList
 {
 public:
   CaptureCommandList()
+    : mLastCommand(nullptr)
   {}
   CaptureCommandList(CaptureCommandList&& aOther)
-   : mStorage(Move(aOther.mStorage))
-  {}
+   : mStorage(Move(aOther.mStorage)), mLastCommand(aOther.mLastCommand)
+  {
+    aOther.mLastCommand = nullptr;
+  }
   ~CaptureCommandList();
 
   CaptureCommandList& operator =(CaptureCommandList&& aOther) {
     mStorage = Move(aOther.mStorage);
+    mLastCommand = aOther.mLastCommand;
+    aOther.mLastCommand = nullptr;
     return *this;
   }
 
   template <typename T>
   T* Append() {
     size_t oldSize = mStorage.size();
     mStorage.resize(mStorage.size() + sizeof(T) + sizeof(uint32_t));
     uint8_t* nextDrawLocation = &mStorage.front() + oldSize;
     *(uint32_t*)(nextDrawLocation) = sizeof(T) + sizeof(uint32_t);
-    return reinterpret_cast<T*>(nextDrawLocation + sizeof(uint32_t));
+    T* newCommand = reinterpret_cast<T*>(nextDrawLocation + sizeof(uint32_t));
+    mLastCommand = newCommand;
+    return newCommand;
+  }
+
+  template <typename T>
+  T* ReuseOrAppend() {
+    if (mLastCommand != nullptr &&
+      mLastCommand->GetType() == T::Type) {
+      return reinterpret_cast<T*>(mLastCommand);
+    }
+    return Append<T>();
   }
 
   class iterator
   {
   public:
     explicit iterator(CaptureCommandList& aParent)
      : mParent(aParent),
        mCurrent(nullptr),
@@ -72,14 +88,15 @@ public:
   };
 
 private:
   CaptureCommandList(const CaptureCommandList& aOther) = delete;
   void operator =(const CaptureCommandList& aOther) = delete;
 
 private:
   std::vector<uint8_t> mStorage;
+  DrawingCommand* mLastCommand;
 };
 
 } // namespace gfx
 } // namespace mozilla
 
 #endif // mozilla_gfx_2d_CaptureCommandList_h
--- a/gfx/2d/DrawCommand.h
+++ b/gfx/2d/DrawCommand.h
@@ -8,22 +8,23 @@
 #define MOZILLA_GFX_DRAWCOMMAND_H_
 
 #include <math.h>
 
 #include "2D.h"
 #include "Blur.h"
 #include "Filters.h"
 #include <vector>
-#include "CaptureCommandList.h"
 #include "FilterNodeCapture.h"
 
 namespace mozilla {
 namespace gfx {
 
+class CaptureCommandList;
+
 enum class CommandType : int8_t {
   DRAWSURFACE = 0,
   DRAWFILTER,
   DRAWSURFACEWITHSHADOW,
   CLEARRECT,
   COPYSURFACE,
   COPYRECT,
   FILLRECT,
@@ -62,880 +63,12 @@ protected:
     : mType(aType)
   {
   }
 
 private:
   CommandType mType;
 };
 
-#define CLONE_INTO(Type) new (aList->Append<Type>()) Type
-
-class StrokeOptionsCommand : public DrawingCommand
-{
-public:
-  StrokeOptionsCommand(CommandType aType,
-                       const StrokeOptions& aStrokeOptions)
-    : DrawingCommand(aType)
-    , mStrokeOptions(aStrokeOptions)
-  {
-    // Stroke Options dashes are owned by the caller.
-    // Have to copy them here so they don't get freed
-    // between now and replay.
-    if (aStrokeOptions.mDashLength) {
-      mDashes.resize(aStrokeOptions.mDashLength);
-      mStrokeOptions.mDashPattern = &mDashes.front();
-      PodCopy(&mDashes.front(), aStrokeOptions.mDashPattern, mStrokeOptions.mDashLength);
-    }
-  }
-
-  virtual ~StrokeOptionsCommand() {}
-
-protected:
-  StrokeOptions mStrokeOptions;
-  std::vector<Float> mDashes;
-};
-
-class StoredPattern
-{
-public:
-  explicit StoredPattern(const Pattern& aPattern)
-  {
-    Assign(aPattern);
-  }
-
-  void Assign(const Pattern& aPattern)
-  {
-    switch (aPattern.GetType()) {
-    case PatternType::COLOR:
-      new (mColor)ColorPattern(*static_cast<const ColorPattern*>(&aPattern));
-      return;
-    case PatternType::SURFACE:
-    {
-      SurfacePattern* surfPat = new (mSurface)SurfacePattern(*static_cast<const SurfacePattern*>(&aPattern));
-      surfPat->mSurface->GuaranteePersistance();
-      return;
-    }
-    case PatternType::LINEAR_GRADIENT:
-      new (mLinear)LinearGradientPattern(*static_cast<const LinearGradientPattern*>(&aPattern));
-      return;
-    case PatternType::RADIAL_GRADIENT:
-      new (mRadial)RadialGradientPattern(*static_cast<const RadialGradientPattern*>(&aPattern));
-      return;
-    }
-  }
-
-  ~StoredPattern()
-  {
-    reinterpret_cast<Pattern*>(mPattern)->~Pattern();
-  }
-
-  operator Pattern&()
-  {
-    return *reinterpret_cast<Pattern*>(mPattern);
-  }
-
-  operator const Pattern&() const
-  {
-    return *reinterpret_cast<const Pattern*>(mPattern);
-  }
-
-  StoredPattern(const StoredPattern& aPattern)
-  {
-    Assign(aPattern);
-  }
-
-private:
-  StoredPattern operator=(const StoredPattern& aOther)
-  {
-    // Block this so that we notice if someone's doing excessive assigning.
-    return *this;
-  }
-
-  union {
-    char mPattern[sizeof(Pattern)];
-    char mColor[sizeof(ColorPattern)];
-    char mLinear[sizeof(LinearGradientPattern)];
-    char mRadial[sizeof(RadialGradientPattern)];
-    char mSurface[sizeof(SurfacePattern)];
-  };
-};
-
-class DrawSurfaceCommand : public DrawingCommand
-{
-public:
-  DrawSurfaceCommand(SourceSurface *aSurface, const Rect& aDest,
-                     const Rect& aSource, const DrawSurfaceOptions& aSurfOptions,
-                     const DrawOptions& aOptions)
-    : DrawingCommand(CommandType::DRAWSURFACE)
-    , mSurface(aSurface), mDest(aDest)
-    , mSource(aSource), mSurfOptions(aSurfOptions)
-    , mOptions(aOptions)
-  {
-  }
-
-  void CloneInto(CaptureCommandList* aList) override
-  {
-    CLONE_INTO(DrawSurfaceCommand)(mSurface, mDest, mSource, mSurfOptions, mOptions);
-  }
-
-  virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override
-  {
-    aDT->DrawSurface(mSurface, mDest, mSource, mSurfOptions, mOptions);
-  }
-
-  static const bool AffectsSnapshot = true;
-
-private:
-  RefPtr<SourceSurface> mSurface;
-  Rect mDest;
-  Rect mSource;
-  DrawSurfaceOptions mSurfOptions;
-  DrawOptions mOptions;
-};
-
-class DrawSurfaceWithShadowCommand : public DrawingCommand
-{
-public:
-  DrawSurfaceWithShadowCommand(SourceSurface *aSurface,
-                               const Point &aDest,
-                               const Color &aColor,
-                               const Point &aOffset,
-                               Float aSigma,
-                               CompositionOp aOperator)
-    : DrawingCommand(CommandType::DRAWSURFACEWITHSHADOW),
-      mSurface(aSurface),
-      mDest(aDest),
-      mColor(aColor),
-      mOffset(aOffset),
-      mSigma(aSigma),
-      mOperator(aOperator)
-  {
-  }
-
-  void CloneInto(CaptureCommandList* aList) override
-  {
-    CLONE_INTO(DrawSurfaceWithShadowCommand)(mSurface, mDest, mColor, mOffset, mSigma, mOperator);
-  }
-
-  virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override
-  {
-    aDT->DrawSurfaceWithShadow(mSurface, mDest, mColor, mOffset, mSigma, mOperator);
-  }
-
-  static const bool AffectsSnapshot = true;
-
-private:
-  RefPtr<SourceSurface> mSurface;
-  Point mDest;
-  Color mColor;
-  Point mOffset;
-  Float mSigma;
-  CompositionOp mOperator;
-};
-
-class DrawFilterCommand : public DrawingCommand
-{
-public:
-  DrawFilterCommand(FilterNode* aFilter, const Rect& aSourceRect,
-                    const Point& aDestPoint, const DrawOptions& aOptions)
-    : DrawingCommand(CommandType::DRAWSURFACE)
-    , mFilter(aFilter), mSourceRect(aSourceRect)
-    , mDestPoint(aDestPoint), mOptions(aOptions)
-  {
-  }
-
-  void CloneInto(CaptureCommandList* aList) override
-  {
-    CLONE_INTO(DrawFilterCommand)(mFilter, mSourceRect, mDestPoint, mOptions);
-  }
-
-  virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override
-  {
-    RefPtr<FilterNode> filter = mFilter;
-    if (mFilter->GetBackendType() == FilterBackend::FILTER_BACKEND_CAPTURE) {
-      filter = static_cast<FilterNodeCapture*>(filter.get())->Validate(aDT);
-    }
-    aDT->DrawFilter(filter, mSourceRect, mDestPoint, mOptions);
-  }
-
-  static const bool AffectsSnapshot = true;
-
-private:
-  RefPtr<FilterNode> mFilter;
-  Rect mSourceRect;
-  Point mDestPoint;
-  DrawOptions mOptions;
-};
-
-class ClearRectCommand : public DrawingCommand
-{
-public:
-  explicit ClearRectCommand(const Rect& aRect)
-    : DrawingCommand(CommandType::CLEARRECT)
-    , mRect(aRect)
-  {
-  }
-
-  void CloneInto(CaptureCommandList* aList) override
-  {
-    CLONE_INTO(ClearRectCommand)(mRect);
-  }
-
-  virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override
-  {
-    aDT->ClearRect(mRect);
-  }
-
-  static const bool AffectsSnapshot = true;
-
-private:
-  Rect mRect;
-};
-
-class CopySurfaceCommand : public DrawingCommand
-{
-public:
-  CopySurfaceCommand(SourceSurface* aSurface,
-                     const IntRect& aSourceRect,
-                     const IntPoint& aDestination)
-    : DrawingCommand(CommandType::COPYSURFACE)
-    , mSurface(aSurface)
-    , mSourceRect(aSourceRect)
-    , mDestination(aDestination)
-  {
-  }
-
-  void CloneInto(CaptureCommandList* aList) override
-  {
-    CLONE_INTO(CopySurfaceCommand)(mSurface, mSourceRect, mDestination);
-  }
-
-  virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix* aTransform) const override
-  {
-    MOZ_ASSERT(!aTransform || !aTransform->HasNonIntegerTranslation());
-    Point dest(Float(mDestination.x), Float(mDestination.y));
-    if (aTransform) {
-      dest = aTransform->TransformPoint(dest);
-    }
-    aDT->CopySurface(mSurface, mSourceRect, IntPoint(uint32_t(dest.x), uint32_t(dest.y)));
-  }
-
-  static const bool AffectsSnapshot = true;
-
-private:
-  RefPtr<SourceSurface> mSurface;
-  IntRect mSourceRect;
-  IntPoint mDestination;
-};
-
-class FillRectCommand : public DrawingCommand
-{
-public:
-  FillRectCommand(const Rect& aRect,
-                  const Pattern& aPattern,
-                  const DrawOptions& aOptions)
-    : DrawingCommand(CommandType::FILLRECT)
-    , mRect(aRect)
-    , mPattern(aPattern)
-    , mOptions(aOptions)
-  {
-  }
-
-  void CloneInto(CaptureCommandList* aList) override
-  {
-    CLONE_INTO(FillRectCommand)(mRect, mPattern, mOptions);
-  }
-
-  virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override
-  {
-    aDT->FillRect(mRect, mPattern, mOptions);
-  }
-
-  bool GetAffectedRect(Rect& aDeviceRect, const Matrix& aTransform) const override
-  {
-    aDeviceRect = aTransform.TransformBounds(mRect);
-    return true;
-  }
-
-  static const bool AffectsSnapshot = true;
-
-private:
-  Rect mRect;
-  StoredPattern mPattern;
-  DrawOptions mOptions;
-};
-
-class StrokeRectCommand : public StrokeOptionsCommand
-{
-public:
-  StrokeRectCommand(const Rect& aRect,
-                    const Pattern& aPattern,
-                    const StrokeOptions& aStrokeOptions,
-                    const DrawOptions& aOptions)
-    : StrokeOptionsCommand(CommandType::STROKERECT, aStrokeOptions)
-    , mRect(aRect)
-    , mPattern(aPattern)
-    , mOptions(aOptions)
-  {
-  }
-
-  void CloneInto(CaptureCommandList* aList) override
-  {
-    CLONE_INTO(StrokeRectCommand)(mRect, mPattern, mStrokeOptions, mOptions);
-  }
-
-  virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override
-  {
-    aDT->StrokeRect(mRect, mPattern, mStrokeOptions, mOptions);
-  }
-
-  static const bool AffectsSnapshot = true;
-
-private:
-  Rect mRect;
-  StoredPattern mPattern;
-  DrawOptions mOptions;
-};
-
-class StrokeLineCommand : public StrokeOptionsCommand
-{
-public:
-  StrokeLineCommand(const Point& aStart,
-                    const Point& aEnd,
-                    const Pattern& aPattern,
-                    const StrokeOptions& aStrokeOptions,
-                    const DrawOptions& aOptions)
-    : StrokeOptionsCommand(CommandType::STROKELINE, aStrokeOptions)
-    , mStart(aStart)
-    , mEnd(aEnd)
-    , mPattern(aPattern)
-    , mOptions(aOptions)
-  {
-  }
-
-  void CloneInto(CaptureCommandList* aList) override
-  {
-    CLONE_INTO(StrokeLineCommand)(mStart, mEnd, mPattern, mStrokeOptions, mOptions);
-  }
-
-  virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override
-  {
-    aDT->StrokeLine(mStart, mEnd, mPattern, mStrokeOptions, mOptions);
-  }
-
-  static const bool AffectsSnapshot = true;
-
-private:
-  Point mStart;
-  Point mEnd;
-  StoredPattern mPattern;
-  DrawOptions mOptions;
-};
-
-class FillCommand : public DrawingCommand
-{
-public:
-  FillCommand(const Path* aPath,
-              const Pattern& aPattern,
-              const DrawOptions& aOptions)
-    : DrawingCommand(CommandType::FILL)
-    , mPath(const_cast<Path*>(aPath))
-    , mPattern(aPattern)
-    , mOptions(aOptions)
-  {
-  }
-
-  void CloneInto(CaptureCommandList* aList) override
-  {
-    CLONE_INTO(FillCommand)(mPath, mPattern, mOptions);
-  }
-
-  virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override
-  {
-    aDT->Fill(mPath, mPattern, mOptions);
-  }
-
-  bool GetAffectedRect(Rect& aDeviceRect, const Matrix& aTransform) const override
-  {
-    aDeviceRect = mPath->GetBounds(aTransform);
-    return true;
-  }
-
-  static const bool AffectsSnapshot = true;
-
-private:
-  RefPtr<Path> mPath;
-  StoredPattern mPattern;
-  DrawOptions mOptions;
-};
-
-#ifndef M_SQRT2
-#define M_SQRT2 1.41421356237309504880
-#endif
-
-#ifndef M_SQRT1_2
-#define M_SQRT1_2 0.707106781186547524400844362104849039
-#endif
-
-// The logic for this comes from _cairo_stroke_style_max_distance_from_path
-static Rect
-PathExtentsToMaxStrokeExtents(const StrokeOptions &aStrokeOptions,
-                              const Rect &aRect,
-                              const Matrix &aTransform)
-{
-  double styleExpansionFactor = 0.5f;
-
-  if (aStrokeOptions.mLineCap == CapStyle::SQUARE) {
-    styleExpansionFactor = M_SQRT1_2;
-  }
-
-  if (aStrokeOptions.mLineJoin == JoinStyle::MITER &&
-      styleExpansionFactor < M_SQRT2 * aStrokeOptions.mMiterLimit) {
-    styleExpansionFactor = M_SQRT2 * aStrokeOptions.mMiterLimit;
-  }
-
-  styleExpansionFactor *= aStrokeOptions.mLineWidth;
-
-  double dx = styleExpansionFactor * hypot(aTransform._11, aTransform._21);
-  double dy = styleExpansionFactor * hypot(aTransform._22, aTransform._12);
-
-  // Even if the stroke only partially covers a pixel, it must still render to
-  // full pixels. Round up to compensate for this.
-  dx = ceil(dx);
-  dy = ceil(dy);
-
-  Rect result = aRect;
-  result.Inflate(dx, dy);
-  return result;
-}
-
-
-class StrokeCommand : public StrokeOptionsCommand
-{
-public:
-  StrokeCommand(const Path* aPath,
-                const Pattern& aPattern,
-                const StrokeOptions& aStrokeOptions,
-                const DrawOptions& aOptions)
-    : StrokeOptionsCommand(CommandType::STROKE, aStrokeOptions)
-    , mPath(const_cast<Path*>(aPath))
-    , mPattern(aPattern)
-    , mOptions(aOptions)
-  {
-  }
-
-  void CloneInto(CaptureCommandList* aList) override
-  {
-    CLONE_INTO(StrokeCommand)(mPath, mPattern, mStrokeOptions, mOptions);
-  }
-
-  virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override
-  {
-    aDT->Stroke(mPath, mPattern, mStrokeOptions, mOptions);
-  }
-
-  bool GetAffectedRect(Rect& aDeviceRect, const Matrix& aTransform) const override
-  {
-    aDeviceRect = PathExtentsToMaxStrokeExtents(mStrokeOptions, mPath->GetBounds(aTransform), aTransform);
-    return true;
-  }
-
-  static const bool AffectsSnapshot = true;
-
-private:
-  RefPtr<Path> mPath;
-  StoredPattern mPattern;
-  DrawOptions mOptions;
-};
-
-class FillGlyphsCommand : public DrawingCommand
-{
-  friend class DrawTargetCaptureImpl;
-public:
-  FillGlyphsCommand(ScaledFont* aFont,
-                    const GlyphBuffer& aBuffer,
-                    const Pattern& aPattern,
-                    const DrawOptions& aOptions)
-    : DrawingCommand(CommandType::FILLGLYPHS)
-    , mFont(aFont)
-    , mPattern(aPattern)
-    , mOptions(aOptions)
-  {
-    mGlyphs.resize(aBuffer.mNumGlyphs);
-    memcpy(&mGlyphs.front(), aBuffer.mGlyphs, sizeof(Glyph) * aBuffer.mNumGlyphs);
-  }
-
-  void CloneInto(CaptureCommandList* aList) override
-  {
-    GlyphBuffer glyphs = {
-      mGlyphs.data(),
-      (uint32_t)mGlyphs.size(),
-    };
-    CLONE_INTO(FillGlyphsCommand)(mFont, glyphs, mPattern, mOptions);
-  }
-
-  virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override
-  {
-    GlyphBuffer buf;
-    buf.mNumGlyphs = mGlyphs.size();
-    buf.mGlyphs = &mGlyphs.front();
-    aDT->FillGlyphs(mFont, buf, mPattern, mOptions);
-  }
-
-  static const bool AffectsSnapshot = true;
-
-private:
-  RefPtr<ScaledFont> mFont;
-  std::vector<Glyph> mGlyphs;
-  StoredPattern mPattern;
-  DrawOptions mOptions;
-};
-
-class StrokeGlyphsCommand : public StrokeOptionsCommand
-{
-  friend class DrawTargetCaptureImpl;
-public:
-  StrokeGlyphsCommand(ScaledFont* aFont,
-                      const GlyphBuffer& aBuffer,
-                      const Pattern& aPattern,
-                      const StrokeOptions& aStrokeOptions,
-                      const DrawOptions& aOptions)
-    : StrokeOptionsCommand(CommandType::STROKEGLYPHS, aStrokeOptions)
-    , mFont(aFont)
-    , mPattern(aPattern)
-    , mOptions(aOptions)
-  {
-    mGlyphs.resize(aBuffer.mNumGlyphs);
-    memcpy(&mGlyphs.front(), aBuffer.mGlyphs, sizeof(Glyph) * aBuffer.mNumGlyphs);
-  }
-
-  void CloneInto(CaptureCommandList* aList) override
-  {
-    GlyphBuffer glyphs = {
-      mGlyphs.data(),
-      (uint32_t)mGlyphs.size(),
-    };
-    CLONE_INTO(StrokeGlyphsCommand)(mFont, glyphs, mPattern, mStrokeOptions, mOptions);
-  }
-
-  virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override
-  {
-    GlyphBuffer buf;
-    buf.mNumGlyphs = mGlyphs.size();
-    buf.mGlyphs = &mGlyphs.front();
-    aDT->StrokeGlyphs(mFont, buf, mPattern, mStrokeOptions, mOptions);
-  }
-
-  static const bool AffectsSnapshot = true;
-
-private:
-  RefPtr<ScaledFont> mFont;
-  std::vector<Glyph> mGlyphs;
-  StoredPattern mPattern;
-  DrawOptions mOptions;
-};
-
-class MaskCommand : public DrawingCommand
-{
-public:
-  MaskCommand(const Pattern& aSource,
-              const Pattern& aMask,
-              const DrawOptions& aOptions)
-    : DrawingCommand(CommandType::MASK)
-    , mSource(aSource)
-    , mMask(aMask)
-    , mOptions(aOptions)
-  {
-  }
-
-  void CloneInto(CaptureCommandList* aList) override
-  {
-    CLONE_INTO(MaskCommand)(mSource, mMask, mOptions);
-  }
-
-  virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override
-  {
-    aDT->Mask(mSource, mMask, mOptions);
-  }
-
-  static const bool AffectsSnapshot = true;
-
-private:
-  StoredPattern mSource;
-  StoredPattern mMask;
-  DrawOptions mOptions;
-};
-
-class MaskSurfaceCommand : public DrawingCommand
-{
-public:
-  MaskSurfaceCommand(const Pattern& aSource,
-                     const SourceSurface* aMask,
-                     const Point& aOffset,
-                     const DrawOptions& aOptions)
-    : DrawingCommand(CommandType::MASKSURFACE)
-    , mSource(aSource)
-    , mMask(const_cast<SourceSurface*>(aMask))
-    , mOffset(aOffset)
-    , mOptions(aOptions)
-  {
-  }
-
-  void CloneInto(CaptureCommandList* aList) override
-  {
-    CLONE_INTO(MaskSurfaceCommand)(mSource, mMask, mOffset, mOptions);
-  }
-
-  virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override
-  {
-    aDT->MaskSurface(mSource, mMask, mOffset, mOptions);
-  }
-
-  static const bool AffectsSnapshot = true;
-
-private:
-  StoredPattern mSource;
-  RefPtr<SourceSurface> mMask;
-  Point mOffset;
-  DrawOptions mOptions;
-};
-
-class PushClipCommand : public DrawingCommand
-{
-public:
-  explicit PushClipCommand(const Path* aPath)
-    : DrawingCommand(CommandType::PUSHCLIP)
-    , mPath(const_cast<Path*>(aPath))
-  {
-  }
-
-  void CloneInto(CaptureCommandList* aList) override
-  {
-    CLONE_INTO(PushClipCommand)(mPath);
-  }
-
-  virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override
-  {
-    aDT->PushClip(mPath);
-  }
-
-  static const bool AffectsSnapshot = false;
-
-private:
-  RefPtr<Path> mPath;
-};
-
-class PushClipRectCommand : public DrawingCommand
-{
-public:
-  explicit PushClipRectCommand(const Rect& aRect)
-    : DrawingCommand(CommandType::PUSHCLIPRECT)
-    , mRect(aRect)
-  {
-  }
-
-  void CloneInto(CaptureCommandList* aList) override
-  {
-    CLONE_INTO(PushClipRectCommand)(mRect);
-  }
-
-  virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override
-  {
-    aDT->PushClipRect(mRect);
-  }
-
-  static const bool AffectsSnapshot = false;
-
-private:
-  Rect mRect;
-};
-
-class PushLayerCommand : public DrawingCommand
-{
-public:
-  PushLayerCommand(const bool aOpaque,
-                   const Float aOpacity,
-                   SourceSurface* aMask,
-                   const Matrix& aMaskTransform,
-                   const IntRect& aBounds,
-                   bool aCopyBackground)
-    : DrawingCommand(CommandType::PUSHLAYER)
-    , mOpaque(aOpaque)
-    , mOpacity(aOpacity)
-    , mMask(aMask)
-    , mMaskTransform(aMaskTransform)
-    , mBounds(aBounds)
-    , mCopyBackground(aCopyBackground)
-  {
-  }
-
-  void CloneInto(CaptureCommandList* aList) override
-  {
-    CLONE_INTO(PushLayerCommand)(mOpaque, mOpacity, mMask, mMaskTransform, mBounds, mCopyBackground);
-  }
-
-  virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override
-  {
-    aDT->PushLayer(mOpaque, mOpacity, mMask,
-                   mMaskTransform, mBounds, mCopyBackground);
-  }
-
-  static const bool AffectsSnapshot = false;
-
-private:
-  bool mOpaque;
-  float mOpacity;
-  RefPtr<SourceSurface> mMask;
-  Matrix mMaskTransform;
-  IntRect mBounds;
-  bool mCopyBackground;
-};
-
-class PopClipCommand : public DrawingCommand
-{
-public:
-  PopClipCommand()
-    : DrawingCommand(CommandType::POPCLIP)
-  {
-  }
-
-  void CloneInto(CaptureCommandList* aList) override
-  {
-    CLONE_INTO(PopClipCommand)();
-  }
-
-  virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override
-  {
-    aDT->PopClip();
-  }
-
-  static const bool AffectsSnapshot = false;
-};
-
-class PopLayerCommand : public DrawingCommand
-{
-public:
-  PopLayerCommand()
-    : DrawingCommand(CommandType::POPLAYER)
-  {
-  }
-
-  void CloneInto(CaptureCommandList* aList) override
-  {
-    CLONE_INTO(PopLayerCommand)();
-  }
-
-  virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override
-  {
-    aDT->PopLayer();
-  }
-
-  static const bool AffectsSnapshot = true;
-};
-
-class SetTransformCommand : public DrawingCommand
-{
-  friend class DrawTargetCaptureImpl;
-public:
-  explicit SetTransformCommand(const Matrix& aTransform)
-    : DrawingCommand(CommandType::SETTRANSFORM)
-    , mTransform(aTransform)
-  {
-  }
-
-  void CloneInto(CaptureCommandList* aList) override
-  {
-    CLONE_INTO(SetTransformCommand)(mTransform);
-  }
-
-  virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix* aMatrix) const override
-  {
-    if (aMatrix) {
-      aDT->SetTransform(mTransform * (*aMatrix));
-    } else {
-      aDT->SetTransform(mTransform);
-    }
-  }
-
-  static const bool AffectsSnapshot = false;
-
-private:
-  Matrix mTransform;
-};
-
-class SetPermitSubpixelAACommand : public DrawingCommand
-{
-  friend class DrawTargetCaptureImpl;
-public:
-  explicit SetPermitSubpixelAACommand(bool aPermitSubpixelAA)
-    : DrawingCommand(CommandType::SETPERMITSUBPIXELAA)
-    , mPermitSubpixelAA(aPermitSubpixelAA)
-  {
-  }
-
-  void CloneInto(CaptureCommandList* aList) override
-  {
-    CLONE_INTO(SetPermitSubpixelAACommand)(mPermitSubpixelAA);
-  }
-
-  virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix* aMatrix) const override
-  {
-    aDT->SetPermitSubpixelAA(mPermitSubpixelAA);
-  }
-
-  static const bool AffectsSnapshot = false;
-
-private:
-  bool mPermitSubpixelAA;
-};
-
-class FlushCommand : public DrawingCommand
-{
-public:
-  explicit FlushCommand()
-    : DrawingCommand(CommandType::FLUSH)
-  {
-  }
-
-  void CloneInto(CaptureCommandList* aList) override
-  {
-    CLONE_INTO(FlushCommand)();
-  }
-
-  virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override
-  {
-    aDT->Flush();
-  }
-
-  static const bool AffectsSnapshot = false;
-};
-
-class BlurCommand : public DrawingCommand
-{
-public:
-  explicit BlurCommand(const AlphaBoxBlur& aBlur)
-   : DrawingCommand(CommandType::BLUR)
-   , mBlur(aBlur)
-  {}
-
-  void CloneInto(CaptureCommandList* aList) override
-  {
-    CLONE_INTO(BlurCommand)(mBlur);
-  }
-
-  virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override
-  {
-    aDT->Blur(mBlur);
-  }
-
-  static const bool AffectsSnapshot = true;
-
-private:
-  AlphaBoxBlur mBlur;
-};
-
-#undef CLONE_INTO
-
 } // namespace gfx
 } // namespace mozilla
 
 #endif /* MOZILLA_GFX_DRAWCOMMAND_H_ */
copy from gfx/2d/DrawCommand.h
copy to gfx/2d/DrawCommands.h
--- a/gfx/2d/DrawCommand.h
+++ b/gfx/2d/DrawCommands.h
@@ -1,77 +1,30 @@
 /* -*- 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/. */
 
-#ifndef MOZILLA_GFX_DRAWCOMMAND_H_
-#define MOZILLA_GFX_DRAWCOMMAND_H_
+#ifndef MOZILLA_GFX_DRAWCOMMANDS_H_
+#define MOZILLA_GFX_DRAWCOMMANDS_H_
 
 #include <math.h>
 
 #include "2D.h"
 #include "Blur.h"
 #include "Filters.h"
 #include <vector>
 #include "CaptureCommandList.h"
+#include "DrawCommand.h"
 #include "FilterNodeCapture.h"
 
 namespace mozilla {
 namespace gfx {
 
-enum class CommandType : int8_t {
-  DRAWSURFACE = 0,
-  DRAWFILTER,
-  DRAWSURFACEWITHSHADOW,
-  CLEARRECT,
-  COPYSURFACE,
-  COPYRECT,
-  FILLRECT,
-  STROKERECT,
-  STROKELINE,
-  STROKE,
-  FILL,
-  FILLGLYPHS,
-  STROKEGLYPHS,
-  MASK,
-  MASKSURFACE,
-  PUSHCLIP,
-  PUSHCLIPRECT,
-  PUSHLAYER,
-  POPCLIP,
-  POPLAYER,
-  SETTRANSFORM,
-  SETPERMITSUBPIXELAA,
-  FLUSH,
-  BLUR
-};
-
-class DrawingCommand
-{
-public:
-  virtual ~DrawingCommand() {}
-
-  virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix* aTransform = nullptr) const = 0;
-  virtual bool GetAffectedRect(Rect& aDeviceRect, const Matrix& aTransform) const { return false; }
-  virtual void CloneInto(CaptureCommandList* aList) = 0;
-
-  CommandType GetType() { return mType; }
-
-protected:
-  explicit DrawingCommand(CommandType aType)
-    : mType(aType)
-  {
-  }
-
-private:
-  CommandType mType;
-};
-
 #define CLONE_INTO(Type) new (aList->Append<Type>()) Type
 
 class StrokeOptionsCommand : public DrawingCommand
 {
 public:
   StrokeOptionsCommand(CommandType aType,
                        const StrokeOptions& aStrokeOptions)
     : DrawingCommand(aType)
@@ -160,17 +113,17 @@ private:
 };
 
 class DrawSurfaceCommand : public DrawingCommand
 {
 public:
   DrawSurfaceCommand(SourceSurface *aSurface, const Rect& aDest,
                      const Rect& aSource, const DrawSurfaceOptions& aSurfOptions,
                      const DrawOptions& aOptions)
-    : DrawingCommand(CommandType::DRAWSURFACE)
+    : DrawingCommand(DrawSurfaceCommand::Type)
     , mSurface(aSurface), mDest(aDest)
     , mSource(aSource), mSurfOptions(aSurfOptions)
     , mOptions(aOptions)
   {
   }
 
   void CloneInto(CaptureCommandList* aList) override
   {
@@ -178,16 +131,17 @@ public:
   }
 
   virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override
   {
     aDT->DrawSurface(mSurface, mDest, mSource, mSurfOptions, mOptions);
   }
 
   static const bool AffectsSnapshot = true;
+  static const CommandType Type = CommandType::DRAWSURFACE;
 
 private:
   RefPtr<SourceSurface> mSurface;
   Rect mDest;
   Rect mSource;
   DrawSurfaceOptions mSurfOptions;
   DrawOptions mOptions;
 };
@@ -196,17 +150,17 @@ class DrawSurfaceWithShadowCommand : pub
 {
 public:
   DrawSurfaceWithShadowCommand(SourceSurface *aSurface,
                                const Point &aDest,
                                const Color &aColor,
                                const Point &aOffset,
                                Float aSigma,
                                CompositionOp aOperator)
-    : DrawingCommand(CommandType::DRAWSURFACEWITHSHADOW),
+    : DrawingCommand(DrawSurfaceWithShadowCommand::Type),
       mSurface(aSurface),
       mDest(aDest),
       mColor(aColor),
       mOffset(aOffset),
       mSigma(aSigma),
       mOperator(aOperator)
   {
   }
@@ -217,32 +171,33 @@ public:
   }
 
   virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override
   {
     aDT->DrawSurfaceWithShadow(mSurface, mDest, mColor, mOffset, mSigma, mOperator);
   }
 
   static const bool AffectsSnapshot = true;
+  static const CommandType Type = CommandType::DRAWSURFACEWITHSHADOW;
 
 private:
   RefPtr<SourceSurface> mSurface;
   Point mDest;
   Color mColor;
   Point mOffset;
   Float mSigma;
   CompositionOp mOperator;
 };
 
 class DrawFilterCommand : public DrawingCommand
 {
 public:
   DrawFilterCommand(FilterNode* aFilter, const Rect& aSourceRect,
                     const Point& aDestPoint, const DrawOptions& aOptions)
-    : DrawingCommand(CommandType::DRAWSURFACE)
+    : DrawingCommand(DrawFilterCommand::Type)
     , mFilter(aFilter), mSourceRect(aSourceRect)
     , mDestPoint(aDestPoint), mOptions(aOptions)
   {
   }
 
   void CloneInto(CaptureCommandList* aList) override
   {
     CLONE_INTO(DrawFilterCommand)(mFilter, mSourceRect, mDestPoint, mOptions);
@@ -253,56 +208,58 @@ public:
     RefPtr<FilterNode> filter = mFilter;
     if (mFilter->GetBackendType() == FilterBackend::FILTER_BACKEND_CAPTURE) {
       filter = static_cast<FilterNodeCapture*>(filter.get())->Validate(aDT);
     }
     aDT->DrawFilter(filter, mSourceRect, mDestPoint, mOptions);
   }
 
   static const bool AffectsSnapshot = true;
+  static const CommandType Type = CommandType::DRAWFILTER;
 
 private:
   RefPtr<FilterNode> mFilter;
   Rect mSourceRect;
   Point mDestPoint;
   DrawOptions mOptions;
 };
 
 class ClearRectCommand : public DrawingCommand
 {
 public:
   explicit ClearRectCommand(const Rect& aRect)
-    : DrawingCommand(CommandType::CLEARRECT)
+    : DrawingCommand(ClearRectCommand::Type)
     , mRect(aRect)
   {
   }
 
   void CloneInto(CaptureCommandList* aList) override
   {
     CLONE_INTO(ClearRectCommand)(mRect);
   }
 
   virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override
   {
     aDT->ClearRect(mRect);
   }
 
   static const bool AffectsSnapshot = true;
+  static const CommandType Type = CommandType::CLEARRECT;
 
 private:
   Rect mRect;
 };
 
 class CopySurfaceCommand : public DrawingCommand
 {
 public:
   CopySurfaceCommand(SourceSurface* aSurface,
                      const IntRect& aSourceRect,
                      const IntPoint& aDestination)
-    : DrawingCommand(CommandType::COPYSURFACE)
+    : DrawingCommand(CopySurfaceCommand::Type)
     , mSurface(aSurface)
     , mSourceRect(aSourceRect)
     , mDestination(aDestination)
   {
   }
 
   void CloneInto(CaptureCommandList* aList) override
   {
@@ -315,30 +272,31 @@ public:
     Point dest(Float(mDestination.x), Float(mDestination.y));
     if (aTransform) {
       dest = aTransform->TransformPoint(dest);
     }
     aDT->CopySurface(mSurface, mSourceRect, IntPoint(uint32_t(dest.x), uint32_t(dest.y)));
   }
 
   static const bool AffectsSnapshot = true;
+  static const CommandType Type = CommandType::COPYSURFACE;
 
 private:
   RefPtr<SourceSurface> mSurface;
   IntRect mSourceRect;
   IntPoint mDestination;
 };
 
 class FillRectCommand : public DrawingCommand
 {
 public:
   FillRectCommand(const Rect& aRect,
                   const Pattern& aPattern,
                   const DrawOptions& aOptions)
-    : DrawingCommand(CommandType::FILLRECT)
+    : DrawingCommand(FillRectCommand::Type)
     , mRect(aRect)
     , mPattern(aPattern)
     , mOptions(aOptions)
   {
   }
 
   void CloneInto(CaptureCommandList* aList) override
   {
@@ -352,31 +310,32 @@ public:
 
   bool GetAffectedRect(Rect& aDeviceRect, const Matrix& aTransform) const override
   {
     aDeviceRect = aTransform.TransformBounds(mRect);
     return true;
   }
 
   static const bool AffectsSnapshot = true;
+  static const CommandType Type = CommandType::FILLRECT;
 
 private:
   Rect mRect;
   StoredPattern mPattern;
   DrawOptions mOptions;
 };
 
 class StrokeRectCommand : public StrokeOptionsCommand
 {
 public:
   StrokeRectCommand(const Rect& aRect,
                     const Pattern& aPattern,
                     const StrokeOptions& aStrokeOptions,
                     const DrawOptions& aOptions)
-    : StrokeOptionsCommand(CommandType::STROKERECT, aStrokeOptions)
+    : StrokeOptionsCommand(StrokeRectCommand::Type, aStrokeOptions)
     , mRect(aRect)
     , mPattern(aPattern)
     , mOptions(aOptions)
   {
   }
 
   void CloneInto(CaptureCommandList* aList) override
   {
@@ -384,32 +343,33 @@ public:
   }
 
   virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override
   {
     aDT->StrokeRect(mRect, mPattern, mStrokeOptions, mOptions);
   }
 
   static const bool AffectsSnapshot = true;
+  static const CommandType Type = CommandType::STROKERECT;
 
 private:
   Rect mRect;
   StoredPattern mPattern;
   DrawOptions mOptions;
 };
 
 class StrokeLineCommand : public StrokeOptionsCommand
 {
 public:
   StrokeLineCommand(const Point& aStart,
                     const Point& aEnd,
                     const Pattern& aPattern,
                     const StrokeOptions& aStrokeOptions,
                     const DrawOptions& aOptions)
-    : StrokeOptionsCommand(CommandType::STROKELINE, aStrokeOptions)
+    : StrokeOptionsCommand(StrokeLineCommand::Type, aStrokeOptions)
     , mStart(aStart)
     , mEnd(aEnd)
     , mPattern(aPattern)
     , mOptions(aOptions)
   {
   }
 
   void CloneInto(CaptureCommandList* aList) override
@@ -418,31 +378,32 @@ public:
   }
 
   virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override
   {
     aDT->StrokeLine(mStart, mEnd, mPattern, mStrokeOptions, mOptions);
   }
 
   static const bool AffectsSnapshot = true;
+  static const CommandType Type = CommandType::STROKELINE;
 
 private:
   Point mStart;
   Point mEnd;
   StoredPattern mPattern;
   DrawOptions mOptions;
 };
 
 class FillCommand : public DrawingCommand
 {
 public:
   FillCommand(const Path* aPath,
               const Pattern& aPattern,
               const DrawOptions& aOptions)
-    : DrawingCommand(CommandType::FILL)
+    : DrawingCommand(FillCommand::Type)
     , mPath(const_cast<Path*>(aPath))
     , mPattern(aPattern)
     , mOptions(aOptions)
   {
   }
 
   void CloneInto(CaptureCommandList* aList) override
   {
@@ -456,16 +417,17 @@ public:
 
   bool GetAffectedRect(Rect& aDeviceRect, const Matrix& aTransform) const override
   {
     aDeviceRect = mPath->GetBounds(aTransform);
     return true;
   }
 
   static const bool AffectsSnapshot = true;
+  static const CommandType Type = CommandType::FILL;
 
 private:
   RefPtr<Path> mPath;
   StoredPattern mPattern;
   DrawOptions mOptions;
 };
 
 #ifndef M_SQRT2
@@ -511,17 +473,17 @@ PathExtentsToMaxStrokeExtents(const Stro
 
 class StrokeCommand : public StrokeOptionsCommand
 {
 public:
   StrokeCommand(const Path* aPath,
                 const Pattern& aPattern,
                 const StrokeOptions& aStrokeOptions,
                 const DrawOptions& aOptions)
-    : StrokeOptionsCommand(CommandType::STROKE, aStrokeOptions)
+    : StrokeOptionsCommand(StrokeCommand::Type, aStrokeOptions)
     , mPath(const_cast<Path*>(aPath))
     , mPattern(aPattern)
     , mOptions(aOptions)
   {
   }
 
   void CloneInto(CaptureCommandList* aList) override
   {
@@ -535,32 +497,33 @@ public:
 
   bool GetAffectedRect(Rect& aDeviceRect, const Matrix& aTransform) const override
   {
     aDeviceRect = PathExtentsToMaxStrokeExtents(mStrokeOptions, mPath->GetBounds(aTransform), aTransform);
     return true;
   }
 
   static const bool AffectsSnapshot = true;
+  static const CommandType Type = CommandType::STROKE;
 
 private:
   RefPtr<Path> mPath;
   StoredPattern mPattern;
   DrawOptions mOptions;
 };
 
 class FillGlyphsCommand : public DrawingCommand
 {
   friend class DrawTargetCaptureImpl;
 public:
   FillGlyphsCommand(ScaledFont* aFont,
                     const GlyphBuffer& aBuffer,
                     const Pattern& aPattern,
                     const DrawOptions& aOptions)
-    : DrawingCommand(CommandType::FILLGLYPHS)
+    : DrawingCommand(FillGlyphsCommand::Type)
     , mFont(aFont)
     , mPattern(aPattern)
     , mOptions(aOptions)
   {
     mGlyphs.resize(aBuffer.mNumGlyphs);
     memcpy(&mGlyphs.front(), aBuffer.mGlyphs, sizeof(Glyph) * aBuffer.mNumGlyphs);
   }
 
@@ -577,16 +540,17 @@ public:
   {
     GlyphBuffer buf;
     buf.mNumGlyphs = mGlyphs.size();
     buf.mGlyphs = &mGlyphs.front();
     aDT->FillGlyphs(mFont, buf, mPattern, mOptions);
   }
 
   static const bool AffectsSnapshot = true;
+  static const CommandType Type = CommandType::FILLGLYPHS;
 
 private:
   RefPtr<ScaledFont> mFont;
   std::vector<Glyph> mGlyphs;
   StoredPattern mPattern;
   DrawOptions mOptions;
 };
 
@@ -594,17 +558,17 @@ class StrokeGlyphsCommand : public Strok
 {
   friend class DrawTargetCaptureImpl;
 public:
   StrokeGlyphsCommand(ScaledFont* aFont,
                       const GlyphBuffer& aBuffer,
                       const Pattern& aPattern,
                       const StrokeOptions& aStrokeOptions,
                       const DrawOptions& aOptions)
-    : StrokeOptionsCommand(CommandType::STROKEGLYPHS, aStrokeOptions)
+    : StrokeOptionsCommand(StrokeGlyphsCommand::Type, aStrokeOptions)
     , mFont(aFont)
     , mPattern(aPattern)
     , mOptions(aOptions)
   {
     mGlyphs.resize(aBuffer.mNumGlyphs);
     memcpy(&mGlyphs.front(), aBuffer.mGlyphs, sizeof(Glyph) * aBuffer.mNumGlyphs);
   }
 
@@ -621,31 +585,32 @@ public:
   {
     GlyphBuffer buf;
     buf.mNumGlyphs = mGlyphs.size();
     buf.mGlyphs = &mGlyphs.front();
     aDT->StrokeGlyphs(mFont, buf, mPattern, mStrokeOptions, mOptions);
   }
 
   static const bool AffectsSnapshot = true;
+  static const CommandType Type = CommandType::STROKEGLYPHS;
 
 private:
   RefPtr<ScaledFont> mFont;
   std::vector<Glyph> mGlyphs;
   StoredPattern mPattern;
   DrawOptions mOptions;
 };
 
 class MaskCommand : public DrawingCommand
 {
 public:
   MaskCommand(const Pattern& aSource,
               const Pattern& aMask,
               const DrawOptions& aOptions)
-    : DrawingCommand(CommandType::MASK)
+    : DrawingCommand(MaskCommand::Type)
     , mSource(aSource)
     , mMask(aMask)
     , mOptions(aOptions)
   {
   }
 
   void CloneInto(CaptureCommandList* aList) override
   {
@@ -653,31 +618,32 @@ public:
   }
 
   virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override
   {
     aDT->Mask(mSource, mMask, mOptions);
   }
 
   static const bool AffectsSnapshot = true;
+  static const CommandType Type = CommandType::MASK;
 
 private:
   StoredPattern mSource;
   StoredPattern mMask;
   DrawOptions mOptions;
 };
 
 class MaskSurfaceCommand : public DrawingCommand
 {
 public:
   MaskSurfaceCommand(const Pattern& aSource,
                      const SourceSurface* aMask,
                      const Point& aOffset,
                      const DrawOptions& aOptions)
-    : DrawingCommand(CommandType::MASKSURFACE)
+    : DrawingCommand(MaskSurfaceCommand::Type)
     , mSource(aSource)
     , mMask(const_cast<SourceSurface*>(aMask))
     , mOffset(aOffset)
     , mOptions(aOptions)
   {
   }
 
   void CloneInto(CaptureCommandList* aList) override
@@ -686,84 +652,87 @@ public:
   }
 
   virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override
   {
     aDT->MaskSurface(mSource, mMask, mOffset, mOptions);
   }
 
   static const bool AffectsSnapshot = true;
+  static const CommandType Type = CommandType::MASKSURFACE;
 
 private:
   StoredPattern mSource;
   RefPtr<SourceSurface> mMask;
   Point mOffset;
   DrawOptions mOptions;
 };
 
 class PushClipCommand : public DrawingCommand
 {
 public:
   explicit PushClipCommand(const Path* aPath)
-    : DrawingCommand(CommandType::PUSHCLIP)
+    : DrawingCommand(PushClipCommand::Type)
     , mPath(const_cast<Path*>(aPath))
   {
   }
 
   void CloneInto(CaptureCommandList* aList) override
   {
     CLONE_INTO(PushClipCommand)(mPath);
   }
 
   virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override
   {
     aDT->PushClip(mPath);
   }
 
   static const bool AffectsSnapshot = false;
+  static const CommandType Type = CommandType::PUSHCLIP;
 
 private:
   RefPtr<Path> mPath;
 };
 
 class PushClipRectCommand : public DrawingCommand
 {
 public:
   explicit PushClipRectCommand(const Rect& aRect)
-    : DrawingCommand(CommandType::PUSHCLIPRECT)
+    : DrawingCommand(PushClipRectCommand::Type)
     , mRect(aRect)
   {
   }
 
   void CloneInto(CaptureCommandList* aList) override
   {
     CLONE_INTO(PushClipRectCommand)(mRect);
   }
 
   virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override
   {
     aDT->PushClipRect(mRect);
   }
 
   static const bool AffectsSnapshot = false;
+  static const CommandType Type = CommandType::PUSHCLIPRECT;
 
 private:
   Rect mRect;
 };
 
 class PushLayerCommand : public DrawingCommand
 {
 public:
   PushLayerCommand(const bool aOpaque,
                    const Float aOpacity,
                    SourceSurface* aMask,
                    const Matrix& aMaskTransform,
                    const IntRect& aBounds,
                    bool aCopyBackground)
-    : DrawingCommand(CommandType::PUSHLAYER)
+    : DrawingCommand(PushLayerCommand::Type)
     , mOpaque(aOpaque)
     , mOpacity(aOpacity)
     , mMask(aMask)
     , mMaskTransform(aMaskTransform)
     , mBounds(aBounds)
     , mCopyBackground(aCopyBackground)
   {
   }
@@ -775,74 +744,77 @@ public:
 
   virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override
   {
     aDT->PushLayer(mOpaque, mOpacity, mMask,
                    mMaskTransform, mBounds, mCopyBackground);
   }
 
   static const bool AffectsSnapshot = false;
+  static const CommandType Type = CommandType::PUSHLAYER;
 
 private:
   bool mOpaque;
   float mOpacity;
   RefPtr<SourceSurface> mMask;
   Matrix mMaskTransform;
   IntRect mBounds;
   bool mCopyBackground;
 };
 
 class PopClipCommand : public DrawingCommand
 {
 public:
   PopClipCommand()
-    : DrawingCommand(CommandType::POPCLIP)
+    : DrawingCommand(PopClipCommand::Type)
   {
   }
 
   void CloneInto(CaptureCommandList* aList) override
   {
     CLONE_INTO(PopClipCommand)();
   }
 
   virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override
   {
     aDT->PopClip();
   }
 
   static const bool AffectsSnapshot = false;
+  static const CommandType Type = CommandType::POPCLIP;
 };
 
 class PopLayerCommand : public DrawingCommand
 {
 public:
   PopLayerCommand()
-    : DrawingCommand(CommandType::POPLAYER)
+    : DrawingCommand(PopLayerCommand::Type)
   {
   }
 
   void CloneInto(CaptureCommandList* aList) override
   {
     CLONE_INTO(PopLayerCommand)();
   }
 
   virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override
   {
     aDT->PopLayer();
   }
 
   static const bool AffectsSnapshot = true;
+  static const CommandType Type = CommandType::POPLAYER;
 };
 
 class SetTransformCommand : public DrawingCommand
 {
   friend class DrawTargetCaptureImpl;
 public:
   explicit SetTransformCommand(const Matrix& aTransform)
-    : DrawingCommand(CommandType::SETTRANSFORM)
+    : DrawingCommand(SetTransformCommand::Type)
     , mTransform(aTransform)
   {
   }
 
   void CloneInto(CaptureCommandList* aList) override
   {
     CLONE_INTO(SetTransformCommand)(mTransform);
   }
@@ -852,90 +824,94 @@ public:
     if (aMatrix) {
       aDT->SetTransform(mTransform * (*aMatrix));
     } else {
       aDT->SetTransform(mTransform);
     }
   }
 
   static const bool AffectsSnapshot = false;
+  static const CommandType Type = CommandType::SETTRANSFORM;
 
 private:
   Matrix mTransform;
 };
 
 class SetPermitSubpixelAACommand : public DrawingCommand
 {
   friend class DrawTargetCaptureImpl;
 public:
   explicit SetPermitSubpixelAACommand(bool aPermitSubpixelAA)
-    : DrawingCommand(CommandType::SETPERMITSUBPIXELAA)
+    : DrawingCommand(SetPermitSubpixelAACommand::Type)
     , mPermitSubpixelAA(aPermitSubpixelAA)
   {
   }
 
   void CloneInto(CaptureCommandList* aList) override
   {
     CLONE_INTO(SetPermitSubpixelAACommand)(mPermitSubpixelAA);
   }
 
   virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix* aMatrix) const override
   {
     aDT->SetPermitSubpixelAA(mPermitSubpixelAA);
   }
 
   static const bool AffectsSnapshot = false;
+  static const CommandType Type = CommandType::SETPERMITSUBPIXELAA;
 
 private:
   bool mPermitSubpixelAA;
 };
 
 class FlushCommand : public DrawingCommand
 {
 public:
   explicit FlushCommand()
-    : DrawingCommand(CommandType::FLUSH)
+    : DrawingCommand(FlushCommand::Type)
   {
   }
 
   void CloneInto(CaptureCommandList* aList) override
   {
     CLONE_INTO(FlushCommand)();
   }
 
   virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override
   {
     aDT->Flush();
   }
 
   static const bool AffectsSnapshot = false;
+  static const CommandType Type = CommandType::FLUSH;
 };
 
 class BlurCommand : public DrawingCommand
 {
 public:
   explicit BlurCommand(const AlphaBoxBlur& aBlur)
-   : DrawingCommand(CommandType::BLUR)
+   : DrawingCommand(BlurCommand::Type)
    , mBlur(aBlur)
   {}
 
   void CloneInto(CaptureCommandList* aList) override
   {
     CLONE_INTO(BlurCommand)(mBlur);
   }
 
   virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override
   {
     aDT->Blur(mBlur);
   }
 
   static const bool AffectsSnapshot = true;
+  static const CommandType Type = CommandType::BLUR;