Merge inbound to mozilla-central a=merge
authorCoroiu Cristina <ccoroiu@mozilla.com>
Sat, 22 Dec 2018 06:12:53 +0200
changeset 508905 42d4ad944a37049139e65a175a9b9c0961a3e3b9
parent 508895 d30b4fd63e1723d205e31251af32ba8930aa9abd (current diff)
parent 508904 079be36cc55e311d0dc040ead0aa1ec2041d7cb6 (diff)
child 508906 66865fdea5afa8c7613300502f6f1a33d704754a
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone66.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to mozilla-central a=merge
dom/base/nsDocument.cpp
dom/svg/nsSVGDataParser.cpp
dom/svg/nsSVGDataParser.h
dom/svg/nsSVGPathDataParser.cpp
dom/svg/nsSVGPathDataParser.h
gfx/layers/wr/WebRenderCommandBuilder.cpp
old-configure.in
--- a/db/sqlite3/src/moz.build
+++ b/db/sqlite3/src/moz.build
@@ -31,17 +31,17 @@ SOURCES += [
 # increases the page size from 1k, see bug 416330.  It must be kept in sync with
 # the value of PREF_TS_PAGESIZE_DEFAULT in mozStorageService.cpp.  The value can
 # be overridden on a per-platform basis through the use of the PREF_TS_PAGESIZE
 # hidden preference.  If that preference is missing or invalid then this value
 # will be used.
 # Note: Be sure to update the configure.in checks when these change!
 for var in ('SQLITE_SECURE_DELETE', 'SQLITE_THREADSAFE', 'SQLITE_CORE',
             'SQLITE_ENABLE_FTS3', 'SQLITE_ENABLE_UNLOCK_NOTIFY',
-            'SQLITE_ENABLE_DBSTAT_VTAB', 'SQLITE_DBCONFIG_DEFENSIVE'):
+            'SQLITE_ENABLE_DBSTAT_VTAB'):
     DEFINES[var] = 1
 
 DEFINES['SQLITE_DEFAULT_PAGE_SIZE'] = 32768
 DEFINES['SQLITE_MAX_DEFAULT_PAGE_SIZE'] = 32768
 
 # -DSQLITE_WIN32_GETVERSIONEX=0 avoids using deprecated functions.
 # SQLite will just assume we are running on NT kinds of Windows. That's fine
 # because we don't support Win9x.
--- a/devtools/client/inspector/inspector.js
+++ b/devtools/client/inspector/inspector.js
@@ -876,16 +876,21 @@ Inspector.prototype = {
           this.browserRequire("devtools/client/inspector/fonts/fonts");
         panel = new FontInspector(this, this.panelWin);
         break;
       case "layoutview":
         const LayoutView =
           this.browserRequire("devtools/client/inspector/layout/layout");
         panel = new LayoutView(this, this.panelWin);
         break;
+      case "newruleview":
+        const RulesView =
+          this.browserRequire("devtools/client/inspector/rules/new-rules");
+        panel = new RulesView(this, this.panelWin);
+        break;
       case "ruleview":
         const {RuleViewTool} = require("devtools/client/inspector/rules/rules");
         panel = new RuleViewTool(this, this.panelWin);
         break;
       default:
         // This is a custom panel or a non lazy-loaded one.
         return null;
     }
@@ -956,16 +961,23 @@ Inspector.prototype = {
       // Insert Changes as third tab, right after Computed.
       // TODO: move this inline to `sidebarPanels` above when addressing Bug 1491887.
       sidebarPanels.splice(2, 0, {
         id: "changesview",
         title: INSPECTOR_L10N.getStr("inspector.sidebar.changesViewTitle"),
       });
     }
 
+    if (Services.prefs.getBoolPref("devtools.inspector.new-rulesview.enabled")) {
+      sidebarPanels.push({
+        id: "newruleview",
+        title: INSPECTOR_L10N.getStr("inspector.sidebar.ruleViewTitle"),
+      });
+    }
+
     for (const { id, title } of sidebarPanels) {
       // The Computed panel is not a React-based panel. We pick its element container from
       // the DOM and wrap it in a React component (InspectorTabPanel) so it behaves like
       // other panels when using the Inspector's tool sidebar.
       if (id === "computedview") {
         this.sidebar.queueExistingTab(id, title, defaultTab === id);
       } else {
         // When `panel` is a function, it is called when the tab should render. It is
--- a/devtools/client/inspector/reducers.js
+++ b/devtools/client/inspector/reducers.js
@@ -12,8 +12,9 @@ exports.boxModel = require("devtools/cli
 exports.changes = require("devtools/client/inspector/changes/reducers/changes");
 exports.extensionsSidebar = require("devtools/client/inspector/extensions/reducers/sidebar");
 exports.flexbox = require("devtools/client/inspector/flexbox/reducers/flexbox");
 exports.fontOptions = require("devtools/client/inspector/fonts/reducers/font-options");
 exports.fontData = require("devtools/client/inspector/fonts/reducers/fonts");
 exports.fontEditor = require("devtools/client/inspector/fonts/reducers/font-editor");
 exports.grids = require("devtools/client/inspector/grids/reducers/grids");
 exports.highlighterSettings = require("devtools/client/inspector/grids/reducers/highlighter-settings");
+exports.rules = require("devtools/client/inspector/rules/reducers/rules");
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/rules/actions/index.js
@@ -0,0 +1,14 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const { createEnum } = require("devtools/client/shared/enum");
+
+createEnum([
+
+  // Update the entire rules state with the new list of rules.
+  "UPDATE_RULES",
+
+], module.exports);
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/rules/actions/moz.build
@@ -0,0 +1,7 @@
+# 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/.
+
+DevToolsModules(
+    'index.js',
+)
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/rules/components/RulesApp.js
@@ -0,0 +1,35 @@
+/* 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/. */
+
+"use strict";
+
+const { PureComponent } = require("devtools/client/shared/vendor/react");
+const dom = require("devtools/client/shared/vendor/react-dom-factories");
+const { connect } = require("devtools/client/shared/vendor/react-redux");
+
+const { getStr } = require("../utils/l10n");
+
+class RulesApp extends PureComponent {
+  static get propTypes() {
+    return {};
+  }
+
+  render() {
+    return dom.div(
+      {
+        id: "sidebar-panel-ruleview",
+        className: "theme-sidebar inspector-tabpanel",
+      },
+      dom.div(
+        {
+          id: "ruleview-no-results",
+          className: "devtools-sidepanel-no-result",
+        },
+        getStr("rule.empty")
+      )
+    );
+  }
+}
+
+module.exports = connect(state => state)(RulesApp);
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/rules/components/moz.build
@@ -0,0 +1,7 @@
+# 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/.
+
+DevToolsModules(
+    'RulesApp.js',
+)
--- a/devtools/client/inspector/rules/moz.build
+++ b/devtools/client/inspector/rules/moz.build
@@ -1,19 +1,24 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 DIRS += [
+    'actions',
+    'components',
     'models',
+    'reducers',
+    'utils',
     'views',
 ]
 
 DevToolsModules(
+    'new-rules.js',
     'rules.js',
 )
 
 BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
 
 with Files('**'):
     BUG_COMPONENT = ('DevTools', 'CSS Rules Inspector')
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/rules/new-rules.js
@@ -0,0 +1,50 @@
+/* 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/. */
+
+"use strict";
+
+const { createFactory, createElement } = require("devtools/client/shared/vendor/react");
+const { Provider } = require("devtools/client/shared/vendor/react-redux");
+
+const RulesApp = createFactory(require("./components/RulesApp"));
+
+const { LocalizationHelper } = require("devtools/shared/l10n");
+const INSPECTOR_L10N =
+  new LocalizationHelper("devtools/client/locales/inspector.properties");
+
+class RulesView {
+  constructor(inspector, window) {
+    this.document = window.document;
+    this.inspector = inspector;
+    this.store = inspector.store;
+
+    this.init();
+  }
+
+  init() {
+    if (!this.inspector) {
+      return;
+    }
+
+    const rulesApp = RulesApp({});
+
+    const provider = createElement(Provider, {
+      id: "ruleview",
+      key: "ruleview",
+      store: this.store,
+      title: INSPECTOR_L10N.getStr("inspector.sidebar.ruleViewTitle"),
+    }, rulesApp);
+
+    // Expose the provider to let inspector.js use it in setupSidebar.
+    this.provider = provider;
+  }
+
+  destroy() {
+    this.document = null;
+    this.inspector = null;
+    this.store = null;
+  }
+}
+
+module.exports = RulesView;
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/rules/reducers/moz.build
@@ -0,0 +1,7 @@
+# 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/.
+
+DevToolsModules(
+    'rules.js',
+)
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/rules/reducers/rules.js
@@ -0,0 +1,19 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const INITIAL_RULES = {};
+
+const reducers = {
+
+};
+
+module.exports = function(rules = INITIAL_RULES, action) {
+  const reducer = reducers[action.type];
+  if (!reducer) {
+    return rules;
+  }
+  return reducer(rules, action);
+};
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/rules/utils/l10n.js
@@ -0,0 +1,13 @@
+/* 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/. */
+
+"use strict";
+
+const { LocalizationHelper } = require("devtools/shared/l10n");
+const L10N = new LocalizationHelper("devtools/shared/locales/styleinspector.properties");
+
+module.exports = {
+  getStr: (...args) => L10N.getStr(...args),
+  getFormatStr: (...args) => L10N.getFormatStr(...args),
+};
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/rules/utils/moz.build
@@ -0,0 +1,9 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+DevToolsModules(
+    'l10n.js',
+)
--- a/devtools/client/preferences/devtools-client.js
+++ b/devtools/client/preferences/devtools-client.js
@@ -51,16 +51,18 @@ pref("devtools.inspector.showAllAnonymou
 // Show user agent shadow roots
 pref("devtools.inspector.showUserAgentShadowRoots", false);
 // Enable the CSS shapes highlighter
 pref("devtools.inspector.shapesHighlighter.enabled", true);
 // Enable the font highlight-on-hover feature
 pref("devtools.inspector.fonthighlighter.enabled", true);
 // Enable tracking of style changes and the Changes panel in the Inspector
 pref("devtools.inspector.changes.enabled", true);
+// Enable the new Rules View
+pref("devtools.inspector.new-rulesview.enabled", false);
 
 // Flexbox preferences
 pref("devtools.inspector.flexboxHighlighter.enabled", true);
 pref("devtools.flexboxinspector.enabled", true);
 
 // Grid highlighter preferences
 pref("devtools.gridinspector.gridOutlineMaxColumns", 50);
 pref("devtools.gridinspector.gridOutlineMaxRows", 50);
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -12676,17 +12676,17 @@ already_AddRefed<mozilla::dom::Promise> 
       promise->MaybeResolveWithUndefined();
       return promise.forget();
     }
   }
 
   // Step 5. If the sub frame is not sandboxed, skip to step 7.
   // Step 6. If the sub frame doesn't have the token
   //         "allow-storage-access-by-user-activation", reject.
-  if (mSandboxFlags & SANDBOXED_STORAGE_ACCESS) {
+  if (StorageAccessSandboxed()) {
     promise->MaybeRejectWithUndefined();
     return promise.forget();
   }
 
   // Step 7. If the sub frame's parent frame is not the top frame, reject.
   nsIDocument* parent = GetParentDocument();
   if (parent && !parent->IsTopLevelContentDocument()) {
     promise->MaybeRejectWithUndefined();
@@ -12883,8 +12883,13 @@ void nsIDocument::ReportShadowDOMUsage()
                          NS_LITERAL_STRING("] or in some of its subdocuments.");
       nsContentUtils::ReportToConsoleNonLocalized(
           msg, nsIScriptError::infoFlag, NS_LITERAL_CSTRING("DOM"), topLevel);
     }
   }
 
   mHasReportedShadowDOMUsage = true;
 }
+
+bool nsIDocument::StorageAccessSandboxed() const {
+  return StaticPrefs::dom_storage_access_enabled() &&
+         (GetSandboxFlags() & SANDBOXED_STORAGE_ACCESS) != 0;
+}
--- a/dom/base/nsGlobalWindowInner.cpp
+++ b/dom/base/nsGlobalWindowInner.cpp
@@ -5798,17 +5798,17 @@ nsIPrincipal* nsGlobalWindowInner::GetTo
   if (NS_WARN_IF(!topLevelPrincipal)) {
     return nullptr;
   }
 
   return topLevelPrincipal;
 }
 
 nsIPrincipal* nsGlobalWindowInner::GetTopLevelStorageAreaPrincipal() {
-  if (mDoc && ((mDoc->GetSandboxFlags() & SANDBOXED_STORAGE_ACCESS) != 0 ||
+  if (mDoc && (mDoc->StorageAccessSandboxed() ||
                nsContentUtils::IsInPrivateBrowsing(mDoc))) {
     // Storage access is disabled
     return nullptr;
   }
 
   nsPIDOMWindowOuter* outerWindow = GetParentInternal();
   if (!outerWindow) {
     // No outer window available!
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -1294,16 +1294,20 @@ class nsIDocument : public nsINode,
   // Returns strong references to mBlockedTrackingNodes. (nsIDocument.h)
   //
   // This array contains nodes that have been blocked to prevent
   // user tracking. They most likely have had their nsIChannel
   // canceled by the URL classifier (Safebrowsing).
   //
   already_AddRefed<nsSimpleContentList> BlockedTrackingNodes() const;
 
+  // Helper method that returns true if the document has storage-access sandbox
+  // flag.
+  bool StorageAccessSandboxed() const;
+
  protected:
   friend class nsUnblockOnloadEvent;
 
   nsresult InitCSP(nsIChannel* aChannel);
 
   nsresult InitFeaturePolicy(nsIChannel* aChannel);
 
   void PostUnblockOnloadEvent();
--- a/dom/svg/SVGContentUtils.cpp
+++ b/dom/svg/SVGContentUtils.cpp
@@ -25,17 +25,17 @@
 #include "nsMathUtils.h"
 #include "SVGAnimationElement.h"
 #include "SVGAnimatedPreserveAspectRatio.h"
 #include "nsContentUtils.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/Types.h"
 #include "mozilla/FloatingPoint.h"
 #include "mozilla/ComputedStyle.h"
-#include "nsSVGPathDataParser.h"
+#include "SVGPathDataParser.h"
 #include "SVGPathData.h"
 #include "SVGPathElement.h"
 
 using namespace mozilla::dom;
 using namespace mozilla::dom::SVGPreserveAspectRatio_Binding;
 using namespace mozilla::gfx;
 
 namespace mozilla {
@@ -782,17 +782,17 @@ float SVGContentUtils::CoordToFloat(SVGE
     default:
       return 0.0f;
   }
 }
 
 already_AddRefed<gfx::Path> SVGContentUtils::GetPath(
     const nsAString& aPathString) {
   SVGPathData pathData;
-  nsSVGPathDataParser parser(aPathString, &pathData);
+  SVGPathDataParser parser(aPathString, &pathData);
   if (!parser.Parse()) {
     return NULL;
   }
 
   RefPtr<DrawTarget> drawTarget =
       gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget();
   RefPtr<PathBuilder> builder =
       drawTarget->CreatePathBuilder(FillRule::FILL_WINDING);
rename from dom/svg/nsSVGDataParser.cpp
rename to dom/svg/SVGDataParser.cpp
--- a/dom/svg/nsSVGDataParser.cpp
+++ b/dom/svg/SVGDataParser.cpp
@@ -1,35 +1,39 @@
 /* -*- 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 "nsSVGDataParser.h"
+#include "SVGDataParser.h"
 #include "nsContentUtils.h"
 #include "SVGContentUtils.h"
 
-nsSVGDataParser::nsSVGDataParser(const nsAString& aValue)
+namespace mozilla {
+
+SVGDataParser::SVGDataParser(const nsAString& aValue)
     : mIter(SVGContentUtils::GetStartRangedPtr(aValue)),
       mEnd(SVGContentUtils::GetEndRangedPtr(aValue)) {}
 
-bool nsSVGDataParser::SkipCommaWsp() {
+bool SVGDataParser::SkipCommaWsp() {
   if (!SkipWsp()) {
     // end of string
     return false;
   }
   if (*mIter != ',') {
     return true;
   }
   ++mIter;
   return SkipWsp();
 }
 
-bool nsSVGDataParser::SkipWsp() {
+bool SVGDataParser::SkipWsp() {
   while (mIter != mEnd) {
     if (!nsContentUtils::IsHTMLWhitespace(*mIter)) {
       return true;
     }
     ++mIter;
   }
   return false;
 }
+
+}  // namespace mozilla
rename from dom/svg/nsSVGDataParser.h
rename to dom/svg/SVGDataParser.h
--- a/dom/svg/nsSVGDataParser.h
+++ b/dom/svg/SVGDataParser.h
@@ -5,23 +5,25 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef __NS_SVGDATAPARSER_H__
 #define __NS_SVGDATAPARSER_H__
 
 #include "mozilla/RangedPtr.h"
 #include "nsString.h"
 
+namespace mozilla {
+
 ////////////////////////////////////////////////////////////////////////
-// nsSVGDataParser: a simple base class for parsing values
+// SVGDataParser: a simple base class for parsing values
 // for path and transform values.
 //
-class nsSVGDataParser {
+class SVGDataParser {
  public:
-  explicit nsSVGDataParser(const nsAString& aValue);
+  explicit SVGDataParser(const nsAString& aValue);
 
  protected:
   static bool IsAlpha(char16_t aCh) {
     // Exclude non-ascii characters before calling isalpha
     return (aCh & 0x7f) == aCh && isalpha(aCh);
   }
 
   // Returns true if there are more characters to read, false otherwise.
@@ -29,9 +31,11 @@ class nsSVGDataParser {
 
   // Returns true if there are more characters to read, false otherwise.
   bool SkipWsp();
 
   mozilla::RangedPtr<const char16_t> mIter;
   const mozilla::RangedPtr<const char16_t> mEnd;
 };
 
+}  // namespace mozilla
+
 #endif  // __NS_SVGDATAPARSER_H__
--- a/dom/svg/SVGMotionSMILAnimationFunction.cpp
+++ b/dom/svg/SVGMotionSMILAnimationFunction.cpp
@@ -8,17 +8,17 @@
 #include "mozilla/dom/SVGAnimationElement.h"
 #include "mozilla/dom/SVGPathElement.h"  // for nsSVGPathList
 #include "mozilla/dom/SVGMPathElement.h"
 #include "mozilla/gfx/2D.h"
 #include "nsAttrValue.h"
 #include "nsAttrValueInlines.h"
 #include "nsSMILParserUtils.h"
 #include "nsSVGAngle.h"
-#include "nsSVGPathDataParser.h"
+#include "SVGPathDataParser.h"
 #include "SVGMotionSMILType.h"
 #include "SVGMotionSMILPathUtils.h"
 
 using namespace mozilla::dom;
 using namespace mozilla::dom::SVGAngle_Binding;
 using namespace mozilla::gfx;
 
 namespace mozilla {
@@ -219,17 +219,17 @@ void SVGMotionSMILAnimationFunction::Reb
 }
 
 void SVGMotionSMILAnimationFunction::RebuildPathAndVerticesFromPathAttr() {
   const nsAString& pathSpec = GetAttr(nsGkAtoms::path)->GetStringValue();
   mPathSourceType = ePathSourceType_PathAttr;
 
   // Generate Path from |path| attr
   SVGPathData path;
-  nsSVGPathDataParser pathParser(pathSpec, &path);
+  SVGPathDataParser pathParser(pathSpec, &path);
 
   // We ignore any failure returned from Parse() since the SVG spec says to
   // accept all segments up to the first invalid token. Instead we must
   // explicitly check that the parse produces at least one path segment (if
   // the path data doesn't begin with a valid "M", then it's invalid).
   pathParser.Parse();
   if (!path.Length()) {
     return;
--- a/dom/svg/SVGPathData.cpp
+++ b/dom/svg/SVGPathData.cpp
@@ -9,17 +9,17 @@
 #include "gfx2DGlue.h"
 #include "gfxPlatform.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/Types.h"
 #include "mozilla/gfx/Point.h"
 #include "mozilla/RefPtr.h"
 #include "nsError.h"
 #include "nsString.h"
-#include "nsSVGPathDataParser.h"
+#include "SVGPathDataParser.h"
 #include <stdarg.h>
 #include "nsStyleConsts.h"
 #include "SVGContentUtils.h"
 #include "SVGGeometryElement.h"  // for nsSVGMark
 #include "SVGPathSegUtils.h"
 #include <algorithm>
 
 using namespace mozilla;
@@ -78,17 +78,17 @@ void SVGPathData::GetValueAsString(nsASt
   }
 }
 
 nsresult SVGPathData::SetValueFromString(const nsAString& aValue) {
   // We don't use a temp variable since the spec says to parse everything up to
   // the first error. We still return any error though so that callers know if
   // there's a problem.
 
-  nsSVGPathDataParser pathParser(aValue, this);
+  SVGPathDataParser pathParser(aValue, this);
   return pathParser.Parse() ? NS_OK : NS_ERROR_DOM_SYNTAX_ERR;
 }
 
 nsresult SVGPathData::AppendSeg(uint32_t aType, ...) {
   uint32_t oldLength = mData.Length();
   uint32_t newLength = oldLength + 1 + SVGPathSegUtils::ArgCountForType(aType);
   if (!mData.SetLength(newLength, fallible)) {
     return NS_ERROR_OUT_OF_MEMORY;
@@ -391,18 +391,18 @@ already_AddRefed<Path> SVGPathData::Buil
         if (segType == PATHSEG_ARC_REL) {
           segEnd += segStart;
         }
         if (segEnd != segStart) {
           subpathHasLength = true;
           if (radii.x == 0.0f || radii.y == 0.0f) {
             aBuilder->LineTo(segEnd);
           } else {
-            nsSVGArcConverter converter(segStart, segEnd, radii, mData[i + 2],
-                                        mData[i + 3] != 0, mData[i + 4] != 0);
+            SVGArcConverter converter(segStart, segEnd, radii, mData[i + 2],
+                                      mData[i + 3] != 0, mData[i + 4] != 0);
             while (converter.GetNextSegment(&cp1, &cp2, &segEnd)) {
               aBuilder->BezierTo(cp1, cp2, segEnd);
             }
           }
         }
         break;
       }
 
@@ -641,19 +641,18 @@ already_AddRefed<Path> SVGPathData::Buil
         if (arc.absolute == StyleIsAbsolute::No) {
           segEnd += segStart;
         }
         if (segEnd != segStart) {
           subpathHasLength = true;
           if (radii.x == 0.0f || radii.y == 0.0f) {
             aBuilder->LineTo(scale(segEnd));
           } else {
-            nsSVGArcConverter converter(segStart, segEnd, radii, arc.angle,
-                                        arc.large_arc_flag._0,
-                                        arc.sweep_flag._0);
+            SVGArcConverter converter(segStart, segEnd, radii, arc.angle,
+                                      arc.large_arc_flag._0, arc.sweep_flag._0);
             while (converter.GetNextSegment(&cp1, &cp2, &segEnd)) {
               aBuilder->BezierTo(scale(cp1), scale(cp2), scale(segEnd));
             }
           }
         }
         break;
       }
       case StylePathCommand::Tag::HorizontalLineTo:
--- a/dom/svg/SVGPathData.h
+++ b/dom/svg/SVGPathData.h
@@ -16,22 +16,22 @@
 #include "mozilla/gfx/Types.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/RefPtr.h"
 #include "SVGElement.h"
 #include "nsTArray.h"
 
 #include <string.h>
 
-class nsSVGPathDataParser;  // IWYU pragma: keep
-
 struct nsSVGMark;
 
 namespace mozilla {
 
+class SVGPathDataParser;  // IWYU pragma: keep
+
 /**
  * ATTENTION! WARNING! WATCH OUT!!
  *
  * Consumers that modify objects of this type absolutely MUST keep the DOM
  * wrappers for those lists (if any) in sync!! That's why this class is so
  * locked down.
  *
  * The DOM wrapper class for this class is DOMSVGPathSegList.
@@ -72,18 +72,18 @@ namespace mozilla {
  * SVGPathSegUtils::ArgCountForType(type) to determine how many arguments
  * there are (if any), and thus where the current encoded segment ends, and
  * where the next segment (if any) begins.
  */
 class SVGPathData {
   friend class SVGAnimatedPathSegList;
   friend class DOMSVGPathSegList;
   friend class DOMSVGPathSeg;
-  friend class ::nsSVGPathDataParser;
-  // nsSVGPathDataParser will not keep wrappers in sync, so consumers
+  friend class SVGPathDataParser;
+  // SVGPathDataParser will not keep wrappers in sync, so consumers
   // are responsible for that!
 
   typedef gfx::DrawTarget DrawTarget;
   typedef gfx::Path Path;
   typedef gfx::PathBuilder PathBuilder;
   typedef gfx::FillRule FillRule;
   typedef gfx::Float Float;
   typedef gfx::CapStyle CapStyle;
rename from dom/svg/nsSVGPathDataParser.cpp
rename to dom/svg/SVGPathDataParser.cpp
--- a/dom/svg/nsSVGPathDataParser.cpp
+++ b/dom/svg/SVGPathDataParser.cpp
@@ -1,71 +1,72 @@
 /* -*- 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 "nsSVGPathDataParser.h"
+#include "SVGPathDataParser.h"
 
 #include "mozilla/gfx/Point.h"
-#include "nsSVGDataParser.h"
+#include "SVGDataParser.h"
 #include "SVGContentUtils.h"
 #include "SVGPathData.h"
 #include "SVGPathSegUtils.h"
 
-using namespace mozilla;
 using namespace mozilla::dom::SVGPathSeg_Binding;
 using namespace mozilla::gfx;
 
+namespace mozilla {
+
 static inline char16_t ToUpper(char16_t aCh) {
   return aCh >= 'a' && aCh <= 'z' ? aCh - 'a' + 'A' : aCh;
 }
 
-bool nsSVGPathDataParser::Parse() {
+bool SVGPathDataParser::Parse() {
   mPathSegList->Clear();
   return ParsePath();
 }
 
 //----------------------------------------------------------------------
 
-bool nsSVGPathDataParser::ParseCoordPair(float& aX, float& aY) {
+bool SVGPathDataParser::ParseCoordPair(float& aX, float& aY) {
   return SVGContentUtils::ParseNumber(mIter, mEnd, aX) && SkipCommaWsp() &&
          SVGContentUtils::ParseNumber(mIter, mEnd, aY);
 }
 
-bool nsSVGPathDataParser::ParseFlag(bool& aFlag) {
+bool SVGPathDataParser::ParseFlag(bool& aFlag) {
   if (mIter == mEnd || (*mIter != '0' && *mIter != '1')) {
     return false;
   }
   aFlag = (*mIter == '1');
 
   ++mIter;
   return true;
 }
 
 //----------------------------------------------------------------------
 
-bool nsSVGPathDataParser::ParsePath() {
+bool SVGPathDataParser::ParsePath() {
   while (SkipWsp()) {
     if (!ParseSubPath()) {
       return false;
     }
   }
 
   return true;
 }
 
 //----------------------------------------------------------------------
 
-bool nsSVGPathDataParser::ParseSubPath() {
+bool SVGPathDataParser::ParseSubPath() {
   return ParseMoveto() && ParseSubPathElements();
 }
 
-bool nsSVGPathDataParser::ParseSubPathElements() {
+bool SVGPathDataParser::ParseSubPathElements() {
   while (SkipWsp() && !IsStartOfSubPath()) {
     char16_t commandType = ToUpper(*mIter);
 
     // Upper case commands have absolute co-ordinates,
     // lower case commands have relative co-ordinates.
     bool absCoords = commandType == *mIter;
 
     ++mIter;
@@ -73,18 +74,18 @@ bool nsSVGPathDataParser::ParseSubPathEl
 
     if (!ParseSubPathElement(commandType, absCoords)) {
       return false;
     }
   }
   return true;
 }
 
-bool nsSVGPathDataParser::ParseSubPathElement(char16_t aCommandType,
-                                              bool aAbsCoords) {
+bool SVGPathDataParser::ParseSubPathElement(char16_t aCommandType,
+                                            bool aAbsCoords) {
   switch (aCommandType) {
     case 'Z':
       return ParseClosePath();
     case 'L':
       return ParseLineto(aAbsCoords);
     case 'H':
       return ParseHorizontalLineto(aAbsCoords);
     case 'V':
@@ -98,23 +99,23 @@ bool nsSVGPathDataParser::ParseSubPathEl
     case 'T':
       return ParseSmoothQuadBezierCurveto(aAbsCoords);
     case 'A':
       return ParseEllipticalArc(aAbsCoords);
   }
   return false;
 }
 
-bool nsSVGPathDataParser::IsStartOfSubPath() const {
+bool SVGPathDataParser::IsStartOfSubPath() const {
   return *mIter == 'm' || *mIter == 'M';
 }
 
 //----------------------------------------------------------------------
 
-bool nsSVGPathDataParser::ParseMoveto() {
+bool SVGPathDataParser::ParseMoveto() {
   if (!IsStartOfSubPath()) {
     return false;
   }
 
   bool absCoords = (*mIter == 'M');
 
   ++mIter;
   SkipWsp();
@@ -139,23 +140,23 @@ bool nsSVGPathDataParser::ParseMoveto() 
   // Per SVG 1.1 Section 8.3.2
   // If a moveto is followed by multiple pairs of coordinates,
   // the subsequent pairs are treated as implicit lineto commands
   return ParseLineto(absCoords);
 }
 
 //----------------------------------------------------------------------
 
-bool nsSVGPathDataParser::ParseClosePath() {
+bool SVGPathDataParser::ParseClosePath() {
   return NS_SUCCEEDED(mPathSegList->AppendSeg(PATHSEG_CLOSEPATH));
 }
 
 //----------------------------------------------------------------------
 
-bool nsSVGPathDataParser::ParseLineto(bool aAbsCoords) {
+bool SVGPathDataParser::ParseLineto(bool aAbsCoords) {
   while (true) {
     float x, y;
     if (!ParseCoordPair(x, y)) {
       return false;
     }
 
     if (NS_FAILED(mPathSegList->AppendSeg(
             aAbsCoords ? PATHSEG_LINETO_ABS : PATHSEG_LINETO_REL, x, y))) {
@@ -167,17 +168,17 @@ bool nsSVGPathDataParser::ParseLineto(bo
       return true;
     }
     SkipCommaWsp();
   }
 }
 
 //----------------------------------------------------------------------
 
-bool nsSVGPathDataParser::ParseHorizontalLineto(bool aAbsCoords) {
+bool SVGPathDataParser::ParseHorizontalLineto(bool aAbsCoords) {
   while (true) {
     float x;
     if (!SVGContentUtils::ParseNumber(mIter, mEnd, x)) {
       return false;
     }
 
     if (NS_FAILED(mPathSegList->AppendSeg(aAbsCoords
                                               ? PATHSEG_LINETO_HORIZONTAL_ABS
@@ -191,17 +192,17 @@ bool nsSVGPathDataParser::ParseHorizonta
       return true;
     }
     SkipCommaWsp();
   }
 }
 
 //----------------------------------------------------------------------
 
-bool nsSVGPathDataParser::ParseVerticalLineto(bool aAbsCoords) {
+bool SVGPathDataParser::ParseVerticalLineto(bool aAbsCoords) {
   while (true) {
     float y;
     if (!SVGContentUtils::ParseNumber(mIter, mEnd, y)) {
       return false;
     }
 
     if (NS_FAILED(mPathSegList->AppendSeg(aAbsCoords
                                               ? PATHSEG_LINETO_VERTICAL_ABS
@@ -215,17 +216,17 @@ bool nsSVGPathDataParser::ParseVerticalL
       return true;
     }
     SkipCommaWsp();
   }
 }
 
 //----------------------------------------------------------------------
 
-bool nsSVGPathDataParser::ParseCurveto(bool aAbsCoords) {
+bool SVGPathDataParser::ParseCurveto(bool aAbsCoords) {
   while (true) {
     float x1, y1, x2, y2, x, y;
 
     if (!(ParseCoordPair(x1, y1) && SkipCommaWsp() && ParseCoordPair(x2, y2) &&
           SkipCommaWsp() && ParseCoordPair(x, y))) {
       return false;
     }
 
@@ -240,17 +241,17 @@ bool nsSVGPathDataParser::ParseCurveto(b
       return true;
     }
     SkipCommaWsp();
   }
 }
 
 //----------------------------------------------------------------------
 
-bool nsSVGPathDataParser::ParseSmoothCurveto(bool aAbsCoords) {
+bool SVGPathDataParser::ParseSmoothCurveto(bool aAbsCoords) {
   while (true) {
     float x2, y2, x, y;
     if (!(ParseCoordPair(x2, y2) && SkipCommaWsp() && ParseCoordPair(x, y))) {
       return false;
     }
 
     if (NS_FAILED(mPathSegList->AppendSeg(
             aAbsCoords ? PATHSEG_CURVETO_CUBIC_SMOOTH_ABS
@@ -264,17 +265,17 @@ bool nsSVGPathDataParser::ParseSmoothCur
       return true;
     }
     SkipCommaWsp();
   }
 }
 
 //----------------------------------------------------------------------
 
-bool nsSVGPathDataParser::ParseQuadBezierCurveto(bool aAbsCoords) {
+bool SVGPathDataParser::ParseQuadBezierCurveto(bool aAbsCoords) {
   while (true) {
     float x1, y1, x, y;
     if (!(ParseCoordPair(x1, y1) && SkipCommaWsp() && ParseCoordPair(x, y))) {
       return false;
     }
 
     if (NS_FAILED(mPathSegList->AppendSeg(aAbsCoords
                                               ? PATHSEG_CURVETO_QUADRATIC_ABS
@@ -288,17 +289,17 @@ bool nsSVGPathDataParser::ParseQuadBezie
       return true;
     }
     SkipCommaWsp();
   }
 }
 
 //----------------------------------------------------------------------
 
-bool nsSVGPathDataParser::ParseSmoothQuadBezierCurveto(bool aAbsCoords) {
+bool SVGPathDataParser::ParseSmoothQuadBezierCurveto(bool aAbsCoords) {
   while (true) {
     float x, y;
     if (!ParseCoordPair(x, y)) {
       return false;
     }
 
     if (NS_FAILED(mPathSegList->AppendSeg(
             aAbsCoords ? PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS
@@ -312,17 +313,17 @@ bool nsSVGPathDataParser::ParseSmoothQua
       return true;
     }
     SkipCommaWsp();
   }
 }
 
 //----------------------------------------------------------------------
 
-bool nsSVGPathDataParser::ParseEllipticalArc(bool aAbsCoords) {
+bool SVGPathDataParser::ParseEllipticalArc(bool aAbsCoords) {
   while (true) {
     float r1, r2, angle, x, y;
     bool largeArcFlag, sweepFlag;
 
     if (!(SVGContentUtils::ParseNumber(mIter, mEnd, r1) && SkipCommaWsp() &&
           SVGContentUtils::ParseNumber(mIter, mEnd, r2) && SkipCommaWsp() &&
           SVGContentUtils::ParseNumber(mIter, mEnd, angle) && SkipCommaWsp() &&
           ParseFlag(largeArcFlag) && SkipCommaWsp() && ParseFlag(sweepFlag) &&
@@ -350,19 +351,19 @@ bool nsSVGPathDataParser::ParseElliptica
 
 static double CalcVectorAngle(double ux, double uy, double vx, double vy) {
   double ta = atan2(uy, ux);
   double tb = atan2(vy, vx);
   if (tb >= ta) return tb - ta;
   return 2 * M_PI - (ta - tb);
 }
 
-nsSVGArcConverter::nsSVGArcConverter(const Point& from, const Point& to,
-                                     const Point& radii, double angle,
-                                     bool largeArcFlag, bool sweepFlag) {
+SVGArcConverter::SVGArcConverter(const Point& from, const Point& to,
+                                 const Point& radii, double angle,
+                                 bool largeArcFlag, bool sweepFlag) {
   MOZ_ASSERT(radii.x != 0.0f && radii.y != 0.0f, "Bad radii");
 
   const double radPerDeg = M_PI / 180.0;
   mSegIndex = 0;
 
   if (from == to) {
     mNumSegs = 0;
     return;
@@ -423,17 +424,17 @@ nsSVGArcConverter::nsSVGArcConverter(con
   // Convert into cubic bezier segments <= 90deg
   mNumSegs = static_cast<int>(ceil(fabs(dtheta / (M_PI / 2.0))));
   mDelta = dtheta / mNumSegs;
   mT = 8.0 / 3.0 * sin(mDelta / 4.0) * sin(mDelta / 4.0) / sin(mDelta / 2.0);
 
   mFrom = from;
 }
 
-bool nsSVGArcConverter::GetNextSegment(Point* cp1, Point* cp2, Point* to) {
+bool SVGArcConverter::GetNextSegment(Point* cp1, Point* cp2, Point* to) {
   if (mSegIndex == mNumSegs) {
     return false;
   }
 
   double cosTheta1 = cos(mTheta);
   double sinTheta1 = sin(mTheta);
   double theta2 = mTheta + mDelta;
   double cosTheta2 = cos(theta2);
@@ -454,8 +455,10 @@ bool nsSVGArcConverter::GetNextSegment(P
 
   // do next segment
   mTheta = theta2;
   mFrom = *to;
   ++mSegIndex;
 
   return true;
 }
+
+}  // namespace mozilla
rename from dom/svg/nsSVGPathDataParser.h
rename to dom/svg/SVGPathDataParser.h
--- a/dom/svg/nsSVGPathDataParser.h
+++ b/dom/svg/SVGPathDataParser.h
@@ -4,31 +4,30 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef __NS_SVGPATHDATAPARSER_H__
 #define __NS_SVGPATHDATAPARSER_H__
 
 #include "mozilla/Attributes.h"
 #include "mozilla/gfx/Point.h"
-#include "nsSVGDataParser.h"
+#include "SVGDataParser.h"
 
 namespace mozilla {
 class SVGPathData;
-}  // namespace mozilla
 
 ////////////////////////////////////////////////////////////////////////
-// nsSVGPathDataParser: a simple recursive descent parser that builds
+// SVGPathDataParser: a simple recursive descent parser that builds
 // DOMSVGPathSegs from path data strings. The grammar for path data
 // can be found in SVG CR 20001102, chapter 8.
 
-class nsSVGPathDataParser : public nsSVGDataParser {
+class SVGPathDataParser : public SVGDataParser {
  public:
-  nsSVGPathDataParser(const nsAString& aValue, mozilla::SVGPathData* aList)
-      : nsSVGDataParser(aValue), mPathSegList(aList) {
+  SVGPathDataParser(const nsAString& aValue, mozilla::SVGPathData* aList)
+      : SVGDataParser(aValue), mPathSegList(aList) {
     MOZ_ASSERT(aList, "null path data");
   }
 
   bool Parse();
 
  private:
   bool ParseCoordPair(float& aX, float& aY);
   bool ParseFlag(bool& aFlag);
@@ -49,25 +48,27 @@ class nsSVGPathDataParser : public nsSVG
   bool ParseSmoothCurveto(bool aAbsCoords);
   bool ParseQuadBezierCurveto(bool aAbsCoords);
   bool ParseSmoothQuadBezierCurveto(bool aAbsCoords);
   bool ParseEllipticalArc(bool aAbsCoords);
 
   mozilla::SVGPathData* const mPathSegList;
 };
 
-class nsSVGArcConverter {
+class SVGArcConverter {
   typedef mozilla::gfx::Point Point;
 
  public:
-  nsSVGArcConverter(const Point& from, const Point& to, const Point& radii,
-                    double angle, bool largeArcFlag, bool sweepFlag);
+  SVGArcConverter(const Point& from, const Point& to, const Point& radii,
+                  double angle, bool largeArcFlag, bool sweepFlag);
   bool GetNextSegment(Point* cp1, Point* cp2, Point* to);
 
  protected:
   int32_t mNumSegs, mSegIndex;
   double mTheta, mDelta, mT;
   double mSinPhi, mCosPhi;
   double mRx, mRy;
   Point mFrom, mC;
 };
 
+}  // namespace mozilla
+
 #endif  // __NS_SVGPATHDATAPARSER_H__
--- a/dom/svg/SVGPathSegUtils.cpp
+++ b/dom/svg/SVGPathSegUtils.cpp
@@ -4,17 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/ArrayUtils.h"  // MOZ_ARRAY_LENGTH
 
 #include "SVGPathSegUtils.h"
 
 #include "gfx2DGlue.h"
-#include "nsSVGPathDataParser.h"
+#include "SVGPathDataParser.h"
 #include "nsTextFormatter.h"
 
 using namespace mozilla;
 using namespace mozilla::gfx;
 
 static const float PATH_SEG_LENGTH_TOLERANCE = 0.0000001f;
 static const uint32_t MAX_RECURSION = 10;
 
@@ -333,18 +333,18 @@ static void TraverseArcAbs(const float* 
   Point to(aArgs[5], aArgs[6]);
   if (aState.ShouldUpdateLengthAndControlPoints()) {
     float dist = 0;
     Point radii(aArgs[0], aArgs[1]);
     if (radii.x == 0.0f || radii.y == 0.0f) {
       dist = CalcDistanceBetweenPoints(aState.pos, to);
     } else {
       Point bez[4] = {aState.pos, Point(0, 0), Point(0, 0), Point(0, 0)};
-      nsSVGArcConverter converter(aState.pos, to, radii, aArgs[2],
-                                  aArgs[3] != 0, aArgs[4] != 0);
+      SVGArcConverter converter(aState.pos, to, radii, aArgs[2], aArgs[3] != 0,
+                                aArgs[4] != 0);
       while (converter.GetNextSegment(&bez[1], &bez[2], &bez[3])) {
         dist += CalcBezLengthHelper(bez, 4, 0, SplitCubicBezier);
         bez[0] = bez[3];
       }
     }
     aState.length += dist;
     aState.cp1 = aState.cp2 = to;
   }
@@ -355,18 +355,18 @@ static void TraverseArcRel(const float* 
   Point to = aState.pos + Point(aArgs[5], aArgs[6]);
   if (aState.ShouldUpdateLengthAndControlPoints()) {
     float dist = 0;
     Point radii(aArgs[0], aArgs[1]);
     if (radii.x == 0.0f || radii.y == 0.0f) {
       dist = CalcDistanceBetweenPoints(aState.pos, to);
     } else {
       Point bez[4] = {aState.pos, Point(0, 0), Point(0, 0), Point(0, 0)};
-      nsSVGArcConverter converter(aState.pos, to, radii, aArgs[2],
-                                  aArgs[3] != 0, aArgs[4] != 0);
+      SVGArcConverter converter(aState.pos, to, radii, aArgs[2], aArgs[3] != 0,
+                                aArgs[4] != 0);
       while (converter.GetNextSegment(&bez[1], &bez[2], &bez[3])) {
         dist += CalcBezLengthHelper(bez, 4, 0, SplitCubicBezier);
         bez[0] = bez[3];
       }
     }
     aState.length += dist;
     aState.cp1 = aState.cp2 = to;
   }
--- a/dom/svg/SVGTransformListParser.h
+++ b/dom/svg/SVGTransformListParser.h
@@ -3,33 +3,33 @@
 /* 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_SVGTRANSFORMLISTPARSER_H__
 #define MOZILLA_SVGTRANSFORMLISTPARSER_H__
 
 #include "mozilla/Attributes.h"
-#include "nsSVGDataParser.h"
+#include "SVGDataParser.h"
 #include "nsTArray.h"
 
 ////////////////////////////////////////////////////////////////////////
 // SVGTransformListParser: A simple recursive descent parser that builds
 // transform lists from transform attributes. The grammar for path data
 // can be found in SVG 1.1,  chapter 7.
 // http://www.w3.org/TR/SVG11/coords.html#TransformAttribute
 
 namespace mozilla {
 
 class nsSVGTransform;
 
-class SVGTransformListParser : public nsSVGDataParser {
+class SVGTransformListParser : public SVGDataParser {
  public:
   explicit SVGTransformListParser(const nsAString& aValue)
-      : nsSVGDataParser(aValue) {}
+      : SVGDataParser(aValue) {}
 
   bool Parse();
 
   const nsTArray<nsSVGTransform>& GetTransformList() const {
     return mTransforms;
   }
 
  private:
--- a/dom/svg/moz.build
+++ b/dom/svg/moz.build
@@ -122,25 +122,23 @@ UNIFIED_SOURCES += [
     'DOMSVGPointList.cpp',
     'DOMSVGStringList.cpp',
     'DOMSVGTransformList.cpp',
     'nsISVGPoint.cpp',
     'nsSVGAngle.cpp',
     'nsSVGAnimatedTransformList.cpp',
     'nsSVGBoolean.cpp',
     'nsSVGClass.cpp',
-    'nsSVGDataParser.cpp',
     'nsSVGEnum.cpp',
     'nsSVGFeatures.cpp',
     'nsSVGInteger.cpp',
     'nsSVGIntegerPair.cpp',
     'nsSVGLength2.cpp',
     'nsSVGNumber2.cpp',
     'nsSVGNumberPair.cpp',
-    'nsSVGPathDataParser.cpp',
     'nsSVGString.cpp',
     'nsSVGTransform.cpp',
     'nsSVGViewBox.cpp',
     'SVGAElement.cpp',
     'SVGAngle.cpp',
     'SVGAnimatedAngle.cpp',
     'SVGAnimatedBoolean.cpp',
     'SVGAnimatedEnumeration.cpp',
@@ -158,16 +156,17 @@ UNIFIED_SOURCES += [
     'SVGAnimateElement.cpp',
     'SVGAnimateMotionElement.cpp',
     'SVGAnimateTransformElement.cpp',
     'SVGAnimationElement.cpp',
     'SVGAttrValueWrapper.cpp',
     'SVGCircleElement.cpp',
     'SVGClipPathElement.cpp',
     'SVGContentUtils.cpp',
+    'SVGDataParser.cpp',
     'SVGDefsElement.cpp',
     'SVGDescElement.cpp',
     'SVGDocument.cpp',
     'SVGElement.cpp',
     'SVGElementFactory.cpp',
     'SVGEllipseElement.cpp',
     'SVGFEBlendElement.cpp',
     'SVGFEColorMatrixElement.cpp',
@@ -213,16 +212,17 @@ UNIFIED_SOURCES += [
     'SVGMotionSMILPathUtils.cpp',
     'SVGMotionSMILType.cpp',
     'SVGMPathElement.cpp',
     'SVGNumberList.cpp',
     'SVGNumberListSMILType.cpp',
     'SVGNumberPairSMILType.cpp',
     'SVGOrientSMILType.cpp',
     'SVGPathData.cpp',
+    'SVGPathDataParser.cpp',
     'SVGPathElement.cpp',
     'SVGPathSegListSMILType.cpp',
     'SVGPathSegUtils.cpp',
     'SVGPatternElement.cpp',
     'SVGPointList.cpp',
     'SVGPointListSMILType.cpp',
     'SVGPolyElement.cpp',
     'SVGPolygonElement.cpp',
--- a/gfx/layers/wr/StackingContextHelper.cpp
+++ b/gfx/layers/wr/StackingContextHelper.cpp
@@ -18,16 +18,17 @@ StackingContextHelper::StackingContextHe
       mAffectsClipPositioning(false),
       mIsPreserve3D(false),
       mRasterizeLocally(false) {
   // mOrigin remains at 0,0
 }
 
 StackingContextHelper::StackingContextHelper(
     const StackingContextHelper& aParentSC, const ActiveScrolledRoot* aAsr,
+    nsIFrame* aContainerFrame, nsDisplayItem* aContainerItem,
     wr::DisplayListBuilder& aBuilder, const nsTArray<wr::WrFilterOp>& aFilters,
     const LayoutDeviceRect& aBounds, const gfx::Matrix4x4* aBoundTransform,
     const wr::WrAnimationProperty* aAnimation, const float* aOpacityPtr,
     const gfx::Matrix4x4* aTransformPtr, const gfx::Matrix4x4* aPerspectivePtr,
     const gfx::CompositionOp& aMixBlendMode, bool aBackfaceVisible,
     bool aIsPreserve3D,
     const Maybe<nsDisplayTransform*>& aDeferredTransformItem,
     const wr::WrClipId* aClipNodeId, bool aAnimated)
@@ -37,17 +38,23 @@ StackingContextHelper::StackingContextHe
       mIsPreserve3D(aIsPreserve3D),
       mRasterizeLocally(aAnimated || aParentSC.mRasterizeLocally) {
   // Compute scale for fallback rendering. We don't try to guess a scale for 3d
   // transformed items
   gfx::Matrix transform2d;
   if (aBoundTransform && aBoundTransform->CanDraw2D(&transform2d) &&
       !aPerspectivePtr && !aParentSC.mIsPreserve3D) {
     mInheritedTransform = transform2d * aParentSC.mInheritedTransform;
-    mScale = mInheritedTransform.ScaleFactors(true);
+
+    int32_t apd = aContainerFrame->PresContext()->AppUnitsPerDevPixel();
+    nsRect r = LayoutDevicePixel::ToAppUnits(aBounds, apd);
+    mScale = FrameLayerBuilder::ChooseScale(aContainerFrame, aContainerItem, r,
+                                            1.f, 1.f, mInheritedTransform,
+                                            /* aCanDraw2D = */ true);
+
     if (aAnimated) {
       mSnappingSurfaceTransform =
           gfx::Matrix::Scaling(mScale.width, mScale.height);
     } else {
       mSnappingSurfaceTransform =
           transform2d * aParentSC.mSnappingSurfaceTransform;
     }
   } else {
--- a/gfx/layers/wr/StackingContextHelper.h
+++ b/gfx/layers/wr/StackingContextHelper.h
@@ -24,16 +24,17 @@ namespace layers {
 /**
  * This is a helper class that pushes/pops a stacking context, and manages
  * some of the coordinate space transformations needed.
  */
 class MOZ_RAII StackingContextHelper {
  public:
   StackingContextHelper(
       const StackingContextHelper& aParentSC, const ActiveScrolledRoot* aAsr,
+      nsIFrame* aContainerFrame, nsDisplayItem* aContainerItem,
       wr::DisplayListBuilder& aBuilder,
       const nsTArray<wr::WrFilterOp>& aFilters = nsTArray<wr::WrFilterOp>(),
       const LayoutDeviceRect& aBounds = LayoutDeviceRect(),
       const gfx::Matrix4x4* aBoundTransform = nullptr,
       const wr::WrAnimationProperty* aAnimation = nullptr,
       const float* aOpacityPtr = nullptr,
       const gfx::Matrix4x4* aTransformPtr = nullptr,
       const gfx::Matrix4x4* aPerspectivePtr = nullptr,
--- a/gfx/layers/wr/WebRenderCommandBuilder.cpp
+++ b/gfx/layers/wr/WebRenderCommandBuilder.cpp
@@ -1433,18 +1433,18 @@ void WebRenderCommandBuilder::BuildWebRe
 
   {
     if (!mZoomProp && gfxPrefs::APZAllowZooming() && XRE_IsContentProcess()) {
       mZoomProp.emplace();
       mZoomProp->effect_type = wr::WrAnimationType::Transform;
       mZoomProp->id = AnimationHelper::GetNextCompositorAnimationsId();
     }
 
-    StackingContextHelper pageRootSc(sc, nullptr, aBuilder, aFilters,
-                                     LayoutDeviceRect(), nullptr,
+    StackingContextHelper pageRootSc(sc, nullptr, nullptr, nullptr, aBuilder,
+                                     aFilters, LayoutDeviceRect(), nullptr,
                                      mZoomProp.ptrOr(nullptr));
     if (ShouldDumpDisplayList(aDisplayListBuilder)) {
       mBuilderDumpIndex =
           aBuilder.Dump(mDumpIndent + 1, Some(mBuilderDumpIndex), Nothing());
     }
     CreateWebRenderCommandsFromDisplayList(aDisplayList, nullptr,
                                            aDisplayListBuilder, pageRootSc,
                                            aBuilder, aResourceUpdates);
@@ -2004,18 +2004,16 @@ WebRenderCommandBuilder::GenerateFallbac
   auto bounds =
       LayoutDeviceRect::FromAppUnits(paintBounds, appUnitsPerDevPixel);
   if (bounds.IsEmpty()) {
     return nullptr;
   }
 
   gfx::Size scale = aSc.GetInheritedScale();
   gfx::Size oldScale = fallbackData->GetScale();
-  // This scale determination should probably be done using
-  // ChooseScaleAndSetTransform but for now we just fake it.
   // We tolerate slight changes in scale so that we don't, for example,
   // rerasterize on MotionMark
   bool differentScale = gfx::FuzzyEqual(scale.width, oldScale.width, 1e-6f) &&
                         gfx::FuzzyEqual(scale.height, oldScale.height, 1e-6f);
 
   LayoutDeviceToLayerScale2D layerScale(scale.width, scale.height);
   auto scaledBounds = bounds * layerScale;
   auto dtRect = RoundedOut(scaledBounds);
--- a/layout/painting/FrameLayerBuilder.cpp
+++ b/layout/painting/FrameLayerBuilder.cpp
@@ -5997,16 +5997,90 @@ static nsSize ComputeDesiredDisplaySizeF
   if (widget) {
     return LayoutDevicePixel::ToAppUnits(widget->GetClientSize(),
                                          presContext->AppUnitsPerDevPixel());
   }
 
   return presContext->GetVisibleArea().Size();
 }
 
+/* static */ Size FrameLayerBuilder::ChooseScale(nsIFrame* aContainerFrame,
+                                                 nsDisplayItem* aContainerItem,
+                                                 const nsRect& aVisibleRect,
+                                                 float aXScale, float aYScale,
+                                                 const Matrix& aTransform2d,
+                                                 bool aCanDraw2D) {
+  Size scale;
+  // XXX Should we do something for 3D transforms?
+  if (aCanDraw2D && !aContainerFrame->Combines3DTransformWithAncestors() &&
+      !aContainerFrame->HasPerspective()) {
+    // If the container's transform is animated off main thread, fix a suitable
+    // scale size for animation
+    if (aContainerItem &&
+        aContainerItem->GetType() == DisplayItemType::TYPE_TRANSFORM &&
+        EffectCompositor::HasAnimationsForCompositor(aContainerFrame,
+                                                     eCSSProperty_transform)) {
+      nsSize displaySize =
+          ComputeDesiredDisplaySizeForAnimation(aContainerFrame);
+      // compute scale using the animation on the container, taking ancestors in
+      // to account
+      nsSize scaledVisibleSize = nsSize(aVisibleRect.Width() * aXScale,
+                                        aVisibleRect.Height() * aYScale);
+      scale = nsLayoutUtils::ComputeSuitableScaleForAnimation(
+          aContainerFrame, scaledVisibleSize, displaySize);
+      // multiply by the scale inherited from ancestors--we use a uniform
+      // scale factor to prevent blurring when the layer is rotated.
+      float incomingScale = std::max(aXScale, aYScale);
+      scale.width *= incomingScale;
+      scale.height *= incomingScale;
+    } else {
+      // Scale factors are normalized to a power of 2 to reduce the number of
+      // resolution changes
+      scale = aTransform2d.ScaleFactors(true);
+      // For frames with a changing scale transform round scale factors up to
+      // nearest power-of-2 boundary so that we don't keep having to redraw
+      // the content as it scales up and down. Rounding up to nearest
+      // power-of-2 boundary ensures we never scale up, only down --- avoiding
+      // jaggies. It also ensures we never scale down by more than a factor of
+      // 2, avoiding bad downscaling quality.
+      Matrix frameTransform;
+      if (ActiveLayerTracker::IsScaleSubjectToAnimation(aContainerFrame)) {
+        scale.width = gfxUtils::ClampToScaleFactor(scale.width);
+        scale.height = gfxUtils::ClampToScaleFactor(scale.height);
+
+        // Limit animated scale factors to not grow excessively beyond the
+        // display size.
+        nsSize maxScale(4, 4);
+        if (!aVisibleRect.IsEmpty()) {
+          nsSize displaySize =
+              ComputeDesiredDisplaySizeForAnimation(aContainerFrame);
+          maxScale = Max(maxScale, displaySize / aVisibleRect.Size());
+        }
+        if (scale.width > maxScale.width) {
+          scale.width = gfxUtils::ClampToScaleFactor(maxScale.width, true);
+        }
+        if (scale.height > maxScale.height) {
+          scale.height = gfxUtils::ClampToScaleFactor(maxScale.height, true);
+        }
+      } else {
+        // XXX Do we need to move nearly-integer values to integers here?
+      }
+    }
+    // If the scale factors are too small, just use 1.0. The content is being
+    // scaled out of sight anyway.
+    if (fabs(scale.width) < 1e-8 || fabs(scale.height) < 1e-8) {
+      scale = Size(1.0, 1.0);
+    }
+  } else {
+    scale = Size(1.0, 1.0);
+  }
+
+  return scale;
+}
+
 static bool ChooseScaleAndSetTransform(
     FrameLayerBuilder* aLayerBuilder, nsDisplayListBuilder* aDisplayListBuilder,
     nsIFrame* aContainerFrame, nsDisplayItem* aContainerItem,
     const nsRect& aVisibleRect, const Matrix4x4* aTransform,
     const ContainerLayerParameters& aIncomingScale, ContainerLayer* aLayer,
     ContainerLayerParameters& aOutgoingScale) {
   nsIntPoint offset;
 
@@ -6048,89 +6122,27 @@ static bool ChooseScaleAndSetTransform(
   transform.PostTranslate(offset.x + aIncomingScale.mOffset.x,
                           offset.y + aIncomingScale.mOffset.y, 0);
 
   if (transform.IsSingular()) {
     return false;
   }
 
   bool canDraw2D = transform.CanDraw2D(&transform2d);
-  Size scale;
-  // XXX Should we do something for 3D transforms?
-  if (canDraw2D && !aContainerFrame->Combines3DTransformWithAncestors() &&
-      !aContainerFrame->HasPerspective()) {
-    // If the container's transform is animated off main thread, fix a suitable
-    // scale size for animation
-    if (aContainerItem &&
-        aContainerItem->GetType() == DisplayItemType::TYPE_TRANSFORM &&
-        EffectCompositor::HasAnimationsForCompositor(aContainerFrame,
-                                                     eCSSProperty_transform)) {
-      nsSize displaySize =
-          ComputeDesiredDisplaySizeForAnimation(aContainerFrame);
-      // compute scale using the animation on the container, taking ancestors in
-      // to account
-      nsSize scaledVisibleSize =
-          nsSize(aVisibleRect.Width() * aIncomingScale.mXScale,
-                 aVisibleRect.Height() * aIncomingScale.mYScale);
-      scale = nsLayoutUtils::ComputeSuitableScaleForAnimation(
-          aContainerFrame, scaledVisibleSize, displaySize);
-      // multiply by the scale inherited from ancestors--we use a uniform
-      // scale factor to prevent blurring when the layer is rotated.
-      float incomingScale =
-          std::max(aIncomingScale.mXScale, aIncomingScale.mYScale);
-      scale.width *= incomingScale;
-      scale.height *= incomingScale;
-    } else {
-      // Scale factors are normalized to a power of 2 to reduce the number of
-      // resolution changes
-      scale = transform2d.ScaleFactors(true);
-      // For frames with a changing scale transform round scale factors up to
-      // nearest power-of-2 boundary so that we don't keep having to redraw
-      // the content as it scales up and down. Rounding up to nearest
-      // power-of-2 boundary ensures we never scale up, only down --- avoiding
-      // jaggies. It also ensures we never scale down by more than a factor of
-      // 2, avoiding bad downscaling quality.
-      Matrix frameTransform;
-      if (ActiveLayerTracker::IsScaleSubjectToAnimation(aContainerFrame)) {
-        scale.width = gfxUtils::ClampToScaleFactor(scale.width);
-        scale.height = gfxUtils::ClampToScaleFactor(scale.height);
-
-        // Limit animated scale factors to not grow excessively beyond the
-        // display size.
-        nsSize maxScale(4, 4);
-        if (!aVisibleRect.IsEmpty()) {
-          nsSize displaySize =
-              ComputeDesiredDisplaySizeForAnimation(aContainerFrame);
-          maxScale = Max(maxScale, displaySize / aVisibleRect.Size());
-        }
-        if (scale.width > maxScale.width) {
-          scale.width = gfxUtils::ClampToScaleFactor(maxScale.width, true);
-        }
-        if (scale.height > maxScale.height) {
-          scale.height = gfxUtils::ClampToScaleFactor(maxScale.height, true);
-        }
-      } else {
-        // XXX Do we need to move nearly-integer values to integers here?
-      }
-    }
-    // If the scale factors are too small, just use 1.0. The content is being
-    // scaled out of sight anyway.
-    if (fabs(scale.width) < 1e-8 || fabs(scale.height) < 1e-8) {
-      scale = Size(1.0, 1.0);
-    }
-    // If this is a transform container layer, then pre-rendering might
-    // mean we try render a layer bigger than the max texture size. If we have
-    // tiling, that's not a problem, since we'll automatically choose a tiled
-    // layer for layers of that size. If not, we need to apply clamping to
-    // prevent this.
-    if (aTransform && !gfxPrefs::LayersTilesEnabled()) {
-      RestrictScaleToMaxLayerSize(scale, aVisibleRect, aContainerFrame, aLayer);
-    }
-  } else {
-    scale = Size(1.0, 1.0);
+  Size scale = FrameLayerBuilder::ChooseScale(
+      aContainerFrame, aContainerItem, aVisibleRect, aIncomingScale.mXScale,
+      aIncomingScale.mYScale, transform2d, canDraw2D);
+
+  // If this is a transform container layer, then pre-rendering might
+  // mean we try render a layer bigger than the max texture size. If we have
+  // tiling, that's not a problem, since we'll automatically choose a tiled
+  // layer for layers of that size. If not, we need to apply clamping to
+  // prevent this.
+  if (aTransform && !gfxPrefs::LayersTilesEnabled()) {
+    RestrictScaleToMaxLayerSize(scale, aVisibleRect, aContainerFrame, aLayer);
   }
 
   // Store the inverse of our resolution-scale on the layer
   aLayer->SetBaseTransform(transform);
   aLayer->SetPreScale(1.0f / scale.width, 1.0f / scale.height);
   aLayer->SetInheritedScale(aIncomingScale.mXScale, aIncomingScale.mYScale);
 
   aOutgoingScale = ContainerLayerParameters(scale.width, scale.height, -offset,
--- a/layout/painting/FrameLayerBuilder.h
+++ b/layout/painting/FrameLayerBuilder.h
@@ -380,16 +380,22 @@ class FrameLayerBuilder : public layers:
   typedef layers::ImageLayer ImageLayer;
   typedef layers::LayerManager LayerManager;
   typedef layers::BasicLayerManager BasicLayerManager;
   typedef layers::EventRegions EventRegions;
 
   FrameLayerBuilder();
   ~FrameLayerBuilder() override;
 
+  static gfx::Size ChooseScale(nsIFrame* aContainerFrame,
+                               nsDisplayItem* aContainerItem,
+                               const nsRect& aVisibleRect, float aXScale,
+                               float aYScale, const gfx::Matrix& aTransform2d,
+                               bool aCanDraw2D);
+
   static void Shutdown();
 
   void Init(nsDisplayListBuilder* aBuilder, LayerManager* aManager,
             PaintedLayerData* aLayerData = nullptr,
             bool aIsInactiveLayerManager = false,
             const DisplayItemClip* aInactiveLayerClip = nullptr);
 
   /**
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -6056,18 +6056,18 @@ bool nsDisplayOpacity::CreateWebRenderCo
   uint64_t animationsId = AddAnimationsForWebRender(
       this, eCSSProperty_opacity, aManager, aDisplayListBuilder);
   wr::WrAnimationProperty prop{
       wr::WrAnimationType::Opacity,
       animationsId,
   };
 
   nsTArray<mozilla::wr::WrFilterOp> filters;
-  StackingContextHelper sc(aSc, GetActiveScrolledRoot(), aBuilder, filters,
-                           LayoutDeviceRect(), nullptr,
+  StackingContextHelper sc(aSc, GetActiveScrolledRoot(), mFrame, this, aBuilder,
+                           filters, LayoutDeviceRect(), nullptr,
                            animationsId ? &prop : nullptr, opacityForSC);
 
   aManager->CommandBuilder().CreateWebRenderCommandsFromDisplayList(
       &mList, this, aDisplayListBuilder, sc, aBuilder, aResources);
   return true;
 }
 
 nsDisplayBlendMode::nsDisplayBlendMode(
@@ -6095,19 +6095,19 @@ LayerState nsDisplayBlendMode::GetLayerS
 
 bool nsDisplayBlendMode::CreateWebRenderCommands(
     mozilla::wr::DisplayListBuilder& aBuilder,
     mozilla::wr::IpcResourceUpdateQueue& aResources,
     const StackingContextHelper& aSc,
     mozilla::layers::WebRenderLayerManager* aManager,
     nsDisplayListBuilder* aDisplayListBuilder) {
   nsTArray<mozilla::wr::WrFilterOp> filters;
-  StackingContextHelper sc(aSc, GetActiveScrolledRoot(), aBuilder, filters,
-                           LayoutDeviceRect(), nullptr, nullptr, nullptr,
-                           nullptr, nullptr,
+  StackingContextHelper sc(aSc, GetActiveScrolledRoot(), mFrame, this, aBuilder,
+                           filters, LayoutDeviceRect(), nullptr, nullptr,
+                           nullptr, nullptr, nullptr,
                            nsCSSRendering::GetGFXBlendMode(mBlendMode));
 
   return nsDisplayWrapList::CreateWebRenderCommands(
       aBuilder, aResources, sc, aManager, aDisplayListBuilder);
 }
 
 // nsDisplayBlendMode uses layers for rendering
 already_AddRefed<Layer> nsDisplayBlendMode::BuildLayer(
@@ -6216,17 +6216,18 @@ LayerState nsDisplayBlendContainer::GetL
 }
 
 bool nsDisplayBlendContainer::CreateWebRenderCommands(
     mozilla::wr::DisplayListBuilder& aBuilder,
     mozilla::wr::IpcResourceUpdateQueue& aResources,
     const StackingContextHelper& aSc,
     mozilla::layers::WebRenderLayerManager* aManager,
     nsDisplayListBuilder* aDisplayListBuilder) {
-  StackingContextHelper sc(aSc, GetActiveScrolledRoot(), aBuilder);
+  StackingContextHelper sc(aSc, GetActiveScrolledRoot(), mFrame, this,
+                           aBuilder);
 
   return nsDisplayWrapList::CreateWebRenderCommands(
       aBuilder, aResources, sc, aManager, aDisplayListBuilder);
 }
 
 /* static */ nsDisplayTableBlendContainer*
 nsDisplayTableBlendContainer::CreateForBackgroundBlendMode(
     nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsDisplayList* aList,
@@ -6323,17 +6324,17 @@ bool nsDisplayOwnLayer::CreateWebRenderC
   AnimationInfo& animationInfo = animationData->GetAnimationInfo();
   animationInfo.EnsureAnimationsId();
   mWrAnimationId = animationInfo.GetCompositorAnimationsId();
 
   wr::WrAnimationProperty prop;
   prop.id = mWrAnimationId;
   prop.effect_type = wr::WrAnimationType::Transform;
 
-  StackingContextHelper sc(aSc, GetActiveScrolledRoot(), aBuilder,
+  StackingContextHelper sc(aSc, GetActiveScrolledRoot(), mFrame, this, aBuilder,
                            nsTArray<wr::WrFilterOp>(), LayoutDeviceRect(),
                            nullptr, &prop);
 
   nsDisplayWrapList::CreateWebRenderCommands(aBuilder, aResources, sc, aManager,
                                              aDisplayListBuilder);
   return true;
 }
 
@@ -6990,17 +6991,18 @@ bool nsDisplayStickyPosition::CreateWebR
         rightMargin.ptrOr(nullptr), bottomMargin.ptrOr(nullptr),
         leftMargin.ptrOr(nullptr), vBounds, hBounds, applied);
 
     aBuilder.PushClip(id);
     aManager->CommandBuilder().PushOverrideForASR(mContainerASR, id);
   }
 
   {
-    StackingContextHelper sc(aSc, GetActiveScrolledRoot(), aBuilder);
+    StackingContextHelper sc(aSc, GetActiveScrolledRoot(), mFrame, this,
+                             aBuilder);
     nsDisplayWrapList::CreateWebRenderCommands(aBuilder, aResources, sc,
                                                aManager, aDisplayListBuilder);
   }
 
   if (stickyScrollContainer) {
     aManager->CommandBuilder().PopOverrideForASR(mContainerASR);
     aBuilder.PopClip();
   }
@@ -7855,23 +7857,23 @@ bool nsDisplayTransform::CreateWebRender
     deferredTransformItem = Some(this);
   }
 
   // If it looks like we're animated, we should rasterize in local space
   // (disabling subpixel-aa and global pixel snapping)
   bool animated =
       ActiveLayerTracker::IsStyleMaybeAnimated(Frame(), eCSSProperty_transform);
 
-  StackingContextHelper sc(aSc, GetActiveScrolledRoot(), aBuilder, filters,
-                           LayoutDeviceRect(position, LayoutDeviceSize()),
-                           &newTransformMatrix, animationsId ? &prop : nullptr,
-                           nullptr, transformForSC, nullptr,
-                           gfx::CompositionOp::OP_OVER, !BackfaceIsHidden(),
-                           mFrame->Extend3DContext() && !mNoExtendContext,
-                           deferredTransformItem, nullptr, animated);
+  StackingContextHelper sc(
+      aSc, GetActiveScrolledRoot(), mFrame, this, aBuilder, filters,
+      LayoutDeviceRect(position, LayoutDeviceSize()), &newTransformMatrix,
+      animationsId ? &prop : nullptr, nullptr, transformForSC, nullptr,
+      gfx::CompositionOp::OP_OVER, !BackfaceIsHidden(),
+      mFrame->Extend3DContext() && !mNoExtendContext, deferredTransformItem,
+      nullptr, animated);
 
   return mStoredList.CreateWebRenderCommands(aBuilder, aResources, sc, aManager,
                                              aDisplayListBuilder);
 }
 
 bool nsDisplayTransform::UpdateScrollData(
     mozilla::layers::WebRenderScrollData* aData,
     mozilla::layers::WebRenderLayerScrollData* aLayerData) {
@@ -8447,19 +8449,19 @@ bool nsDisplayPerspective::CreateWebRend
   Point3D roundedOrigin(NS_round(newOrigin.x), NS_round(newOrigin.y), 0);
 
   gfx::Matrix4x4 transformForSC = gfx::Matrix4x4::Translation(roundedOrigin);
 
   nsIFrame* perspectiveFrame =
       mFrame->GetContainingBlock(nsIFrame::SKIP_SCROLLED_FRAME);
 
   nsTArray<mozilla::wr::WrFilterOp> filters;
-  StackingContextHelper sc(aSc, GetActiveScrolledRoot(), aBuilder, filters,
-                           LayoutDeviceRect(), nullptr, nullptr, nullptr,
-                           &transformForSC, &perspectiveMatrix,
+  StackingContextHelper sc(aSc, GetActiveScrolledRoot(), mFrame, this, aBuilder,
+                           filters, LayoutDeviceRect(), nullptr, nullptr,
+                           nullptr, &transformForSC, &perspectiveMatrix,
                            gfx::CompositionOp::OP_OVER, !BackfaceIsHidden(),
                            perspectiveFrame->Extend3DContext());
 
   return mList.CreateWebRenderCommands(aBuilder, aResources, sc, aManager,
                                        aDisplayListBuilder);
 }
 
 nsDisplayItemGeometry* nsCharClipDisplayItem::AllocateGeometry(
@@ -9042,17 +9044,17 @@ bool nsDisplayMasksAndClipPaths::CreateW
     bounds.MoveTo(0, 0);
 
     wr::WrClipId clipId = clip->first();
 
     Maybe<float> opacity = clip->second() == HandleOpacity::Yes
                                ? Some(mFrame->StyleEffects()->mOpacity)
                                : Nothing();
 
-    layer.emplace(aSc, GetActiveScrolledRoot(), aBuilder,
+    layer.emplace(aSc, GetActiveScrolledRoot(), mFrame, this, aBuilder,
                   /*aFilters: */ nsTArray<wr::WrFilterOp>(),
                   /*aBounds: */ bounds,
                   /*aBoundTransform: */ nullptr,
                   /*aAnimation: */ nullptr,
                   /*aOpacity: */ opacity.ptrOr(nullptr),
                   /*aTransform: */ nullptr,
                   /*aPerspective: */ nullptr,
                   /*aMixBlendMode: */ gfx::CompositionOp::OP_OVER,
@@ -9327,20 +9329,20 @@ bool nsDisplayFilters::CreateWebRenderCo
     return false;
   }
 
   wr::WrClipId clipId =
       aBuilder.DefineClip(Nothing(), wr::ToLayoutRect(postFilterBounds));
 
   float opacity = mFrame->StyleEffects()->mOpacity;
   StackingContextHelper sc(
-      aSc, GetActiveScrolledRoot(), aBuilder, wrFilters, LayoutDeviceRect(),
-      nullptr, nullptr, opacity != 1.0f && mHandleOpacity ? &opacity : nullptr,
-      nullptr, nullptr, gfx::CompositionOp::OP_OVER, true, false, Nothing(),
-      &clipId);
+      aSc, GetActiveScrolledRoot(), mFrame, this, aBuilder, wrFilters,
+      LayoutDeviceRect(), nullptr, nullptr,
+      opacity != 1.0f && mHandleOpacity ? &opacity : nullptr, nullptr, nullptr,
+      gfx::CompositionOp::OP_OVER, true, false, Nothing(), &clipId);
 
   nsDisplayEffectsBase::CreateWebRenderCommands(aBuilder, aResources, sc,
                                                 aManager, aDisplayListBuilder);
 
   return true;
 }
 
 #ifdef MOZ_DUMP_PAINTING
--- a/layout/svg/tests/file_black_yellow.svg
+++ b/layout/svg/tests/file_black_yellow.svg
@@ -1,9 +1,9 @@
 <!--
      Any copyright is dedicated to the Public Domain.
      http://creativecommons.org/publicdomain/zero/1.0/
 -->
 <svg xmlns="http://www.w3.org/2000/svg" version="1.1"
      xmlns:xlink="http://www.w3.org/1999/xlink">
   <rect height="100%" width="100%" fill="yellow" />
-  <rect height="50%" width="100%" fill="black" />
+  <rect height="50px" width="100px" fill="black" />
 </svg>
--- a/layout/svg/tests/file_filter_crossorigin.svg
+++ b/layout/svg/tests/file_filter_crossorigin.svg
@@ -12,14 +12,14 @@
 
   <!-- giant yellow rect in the background, just so you can visually tell
        that this SVG file has loaded/rendered. -->
   <rect height="100%" width="100%" fill="yellow" />
 
   <!-- For both rects below: if it's black, its filter resolved successfully.
        If it's transparent, it means we failed to load the resource
        (e.g. because it was blocked as a cross-origin resource). -->
-  <rect height="50%" width="100%" fill="red"
+  <rect height="50px" width="100px" fill="red"
         filter="url(http://mochi.test:8888/tests/layout/svg/tests/filters.svg#NonWhiteToBlack)"/>
-  <rect y="50%"
-        height="50%" width="100%" fill="red"
+  <rect y="50px"
+        height="50px" width="100px" fill="red"
         filter="url(http://example.org/tests/layout/svg/tests/filters.svg#NonWhiteToBlack)"/>
 </svg>
--- a/layout/svg/tests/file_yellow_black.svg
+++ b/layout/svg/tests/file_yellow_black.svg
@@ -1,9 +1,9 @@
 <!--
      Any copyright is dedicated to the Public Domain.
      http://creativecommons.org/publicdomain/zero/1.0/
 -->
 <svg xmlns="http://www.w3.org/2000/svg" version="1.1"
      xmlns:xlink="http://www.w3.org/1999/xlink">
   <rect height="100%" width="100%" fill="yellow" />
-  <rect y="50%" height="50%" width="100%" fill="black" />
+  <rect y="50px" height="50px" width="100px" fill="black" />
 </svg>
--- a/modules/libpref/init/StaticPrefList.h
+++ b/modules/libpref/init/StaticPrefList.h
@@ -463,16 +463,23 @@ VARCACHE_PREF(
 #undef PREF_VALUE
 
 VARCACHE_PREF(
   "dom.disable_open_during_load",
    dom_disable_open_during_load,
   bool, false
 )
 
+// Storage-access API.
+VARCACHE_PREF(
+  "dom.storage_access.enabled",
+   dom_storage_access_enabled,
+  bool, false
+)
+
 //---------------------------------------------------------------------------
 // Clear-Site-Data prefs
 //---------------------------------------------------------------------------
 
 VARCACHE_PREF(
   "dom.clearSiteData.enabled",
    dom_clearSiteData_enabled,
   bool, true
--- a/netwerk/base/LoadInfo.cpp
+++ b/netwerk/base/LoadInfo.cpp
@@ -171,19 +171,18 @@ LoadInfo::LoadInfo(
         // sub-iframes). If we are loading a sub-document resource, we must
         // calculate what the top-level-storage-area-principal will be for the
         // new context.
         if (externalType != nsIContentPolicy::TYPE_SUBDOCUMENT) {
           mTopLevelStorageAreaPrincipal =
               innerWindow->GetTopLevelStorageAreaPrincipal();
         } else if (contextOuter->IsTopLevelWindow()) {
           nsIDocument* doc = innerWindow->GetExtantDoc();
-          if (!doc ||
-              ((doc->GetSandboxFlags() & SANDBOXED_STORAGE_ACCESS) == 0 &&
-               !nsContentUtils::IsInPrivateBrowsing(doc))) {
+          if (!doc || (!doc->StorageAccessSandboxed() &&
+                       !nsContentUtils::IsInPrivateBrowsing(doc))) {
             mTopLevelStorageAreaPrincipal = innerWindow->GetPrincipal();
           }
         }
 
         mDocumentHasLoaded = innerWindow->IsDocumentLoaded();
 
         if (innerWindow->IsFrame()) {
           // For resources within iframes, we actually want the
--- a/old-configure.in
+++ b/old-configure.in
@@ -2808,45 +2808,16 @@ then
         )
     ])
     AC_MSG_RESULT($ac_cv_sqlite_dbstat_vtab)
     CFLAGS="$_SAVE_CFLAGS"
     LIBS="$_SAVE_LIBS"
     if test "x$ac_cv_sqlite_dbstat_vtab" = "xno"; then
         AC_MSG_ERROR([System SQLite library is not compiled with SQLITE_ENABLE_DBSTAT_VTAB.])
     fi
-
-    dnl =========================================
-    dnl === SQLITE_DBCONFIG_DEFENSIVE check ===
-    dnl =========================================
-    dnl check to see if the system SQLite package is compiled with
-    dnl SQLITE_DBCONFIG_DEFENSIVE.
-    AC_MSG_CHECKING(for SQLITE_DBCONFIG_DEFENSIVE support in system SQLite)
-    _SAVE_CFLAGS="$CFLAGS"
-    CFLAGS="$CFLAGS $SQLITE_CFLAGS"
-    _SAVE_LIBS="$LIBS"
-    LIBS="$LIBS $SQLITE_LIBS"
-    AC_CACHE_VAL(ac_cv_sqlite_dbconfig_defensive,[
-        AC_TRY_RUN([
-            #include "sqlite3.h"
-
-            int main(int argc, char **argv){
-              return !sqlite3_compileoption_used("SQLITE_DBCONFIG_DEFENSIVE");
-            }],
-            ac_cv_sqlite_dbconfig_defensive=yes,
-            ac_cv_sqlite_dbconfig_defensive=no,
-            ac_cv_sqlite_dbconfig_defensive=no
-        )
-    ])
-    AC_MSG_RESULT($ac_cv_sqlite_dbconfig_defensive)
-    CFLAGS="$_SAVE_CFLAGS"
-    LIBS="$_SAVE_LIBS"
-    if test "x$ac_cv_sqlite_dbconfig_defensive" = "xno"; then
-        AC_MSG_ERROR([System SQLite library is not compiled with SQLITE_DBCONFIG_DEFENSIVE.])
-    fi
 else
     dnl ==============================
     dnl === SQLite fdatasync check ===
     dnl ==============================
     dnl Check to see if fdatasync is available
     AC_CHECK_FUNC(fdatasync)
 fi
 
--- a/testing/mach_commands.py
+++ b/testing/mach_commands.py
@@ -716,17 +716,17 @@ class TestInfoCommand(MachCommandBase):
             worst_rate = 0.0
             worst_platform = None
             total_runs = 0
             total_failures = 0
             for record in data:
                 platform = self.get_platform(record)
                 runs = record['count']
                 total_runs = total_runs + runs
-                failures = record['failures']
+                failures = record.get('failures', 0)
                 total_failures = total_failures + failures
                 rate = (float)(failures) / runs
                 if rate >= worst_rate:
                     worst_rate = rate
                     worst_platform = platform
                     worst_failures = failures
                     worst_runs = runs
                 print("%-40s %6d failures in %6d runs" % (
--- a/toolkit/components/antitracking/AntiTrackingCommon.cpp
+++ b/toolkit/components/antitracking/AntiTrackingCommon.cpp
@@ -68,17 +68,17 @@ bool GetParentPrincipalAndTrackingOrigin
     nsIURI** aTrackingURI, nsIPrincipal** aTrackingPrincipal) {
   if (!nsContentUtils::IsThirdPartyTrackingResourceWindow(
           a3rdPartyTrackingWindow)) {
     return false;
   }
 
   nsIDocument* doc = a3rdPartyTrackingWindow->GetDocument();
   // Make sure storage access isn't disabled
-  if (doc && ((doc->GetSandboxFlags() & SANDBOXED_STORAGE_ACCESS) != 0 ||
+  if (doc && (doc->StorageAccessSandboxed() ||
               nsContentUtils::IsInPrivateBrowsing(doc))) {
     return false;
   }
 
   // Now we need the principal and the origin of the parent window.
   nsCOMPtr<nsIPrincipal> topLevelStoragePrincipal =
       a3rdPartyTrackingWindow->GetTopLevelStorageAreaPrincipal();
   if (!topLevelStoragePrincipal) {