diff --git a/Cargo.lock b/Cargo.lock
index 3f52d85966ffdda7528bc60ceba421c4a26c3172..2c09d3bee7899bde2ca80bb26c2c69958a148f25 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1662,7 +1662,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "plane-split"
-version = "0.13.0"
+version = "0.13.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "binary-space-partition 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2651,7 +2651,7 @@ dependencies = [
  "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "plane-split 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "plane-split 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "ron 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2974,7 +2974,7 @@ dependencies = [
 "checksum phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6b07ffcc532ccc85e3afc45865469bf5d9e4ef5bfcf9622e3cfe80c2d275ec03"
 "checksum phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "07e24b0ca9643bdecd0632f2b3da6b1b89bbb0030e0b992afc1113b23a7bc2f2"
 "checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"
-"checksum plane-split 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "64d766f38b15fe1337bdddfc869ef5c50437323f857aaaadc6490197db80a1b8"
+"checksum plane-split 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cd1ab9bf7197c31ac8004a487cd1ddc5cf420029fb53023fdcab0540b5fa1410"
 "checksum podio 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e5422a1ee1bc57cc47ae717b0137314258138f38fd5f3cea083f43a9725383a0"
 "checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
 "checksum proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "77997c53ae6edd6d187fec07ec41b207063b5ee6f33680e9fa86d405cdd313d4"
diff --git a/accessible/android/SessionAccessibility.cpp b/accessible/android/SessionAccessibility.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8bdcdbfad6047d49472923b960604b0fca9ee131
--- /dev/null
+++ b/accessible/android/SessionAccessibility.cpp
@@ -0,0 +1,36 @@
+/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
+ * 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 "SessionAccessibility.h"
+#include "AndroidUiThread.h"
+#include "nsThreadUtils.h"
+
+#ifdef DEBUG
+#include <android/log.h>
+#define AALOG(args...)                                                         \
+  __android_log_print(ANDROID_LOG_INFO, "GeckoAccessibilityNative", ##args)
+#else
+#define AALOG(args...)                                                         \
+  do {                                                                         \
+  } while (0)
+#endif
+
+template<>
+const char nsWindow::NativePtr<mozilla::a11y::SessionAccessibility>::sName[] =
+  "SessionAccessibility";
+
+using namespace mozilla::a11y;
+
+void
+SessionAccessibility::SetAttached(bool aAttached)
+{
+  if (RefPtr<nsThread> uiThread = GetAndroidUiThread()) {
+    uiThread->Dispatch(NS_NewRunnableFunction(
+      "SessionAccessibility::Attach",
+      [aAttached,
+       sa = java::SessionAccessibility::NativeProvider::GlobalRef(
+         mSessionAccessibility)] { sa->SetAttached(aAttached); }));
+  }
+}
diff --git a/accessible/android/SessionAccessibility.h b/accessible/android/SessionAccessibility.h
new file mode 100644
index 0000000000000000000000000000000000000000..47b5da6296031a2749a7563b4907fa8562acaa6c
--- /dev/null
+++ b/accessible/android/SessionAccessibility.h
@@ -0,0 +1,51 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_a11y_SessionAccessibility_h_
+#define mozilla_a11y_SessionAccessibility_h_
+
+#include "GeneratedJNINatives.h"
+#include "nsWindow.h"
+
+namespace mozilla {
+namespace a11y {
+
+class SessionAccessibility final
+  : public java::SessionAccessibility::NativeProvider::Natives<SessionAccessibility>
+{
+public:
+  typedef java::SessionAccessibility::NativeProvider::Natives<SessionAccessibility> Base;
+
+  SessionAccessibility(
+    nsWindow::NativePtr<SessionAccessibility>* aPtr,
+    nsWindow* aWindow,
+    java::SessionAccessibility::NativeProvider::Param aSessionAccessibility)
+    : mWindow(aPtr, aWindow)
+    , mSessionAccessibility(aSessionAccessibility)
+  {
+    SetAttached(true);
+  }
+
+  void OnDetach() { SetAttached(false); }
+
+  // Native implementations
+  using Base::AttachNative;
+  using Base::DisposeNative;
+
+  NS_INLINE_DECL_REFCOUNTING(SessionAccessibility)
+
+private:
+  ~SessionAccessibility() {}
+
+  void SetAttached(bool aAttached);
+
+  nsWindow::WindowPtr<SessionAccessibility> mWindow; // Parent only
+  java::SessionAccessibility::NativeProvider::GlobalRef mSessionAccessibility;
+};
+
+} // namespace a11y
+} // namespace mozilla
+
+#endif
diff --git a/accessible/android/moz.build b/accessible/android/moz.build
index 6eae6a18ea56c12621bb8469a43a47ac2cbaae73..a76b3e4ed2c7d82b9203c704c01d5c5567e0be3f 100644
--- a/accessible/android/moz.build
+++ b/accessible/android/moz.build
@@ -6,11 +6,13 @@
 
 EXPORTS.mozilla.a11y += ['AccessibleWrap.h',
     'HyperTextAccessibleWrap.h',
+    'SessionAccessibility.h',
 ]
 
 SOURCES += [
     'AccessibleWrap.cpp',
     'Platform.cpp',
+    'SessionAccessibility.cpp',
 ]
 
 LOCAL_INCLUDES += [
diff --git a/accessible/base/AccGroupInfo.cpp b/accessible/base/AccGroupInfo.cpp
index 7548cf1648c7b9b0ef8bbd2078897ada444e3abf..74dbb4e38ca4fd4e50a296feb4f84425fa7d521a 100644
--- a/accessible/base/AccGroupInfo.cpp
+++ b/accessible/base/AccGroupInfo.cpp
@@ -4,6 +4,7 @@
 
 #include "AccGroupInfo.h"
 #include "nsAccUtils.h"
+#include "TableAccessible.h"
 
 #include "Role.h"
 #include "States.h"
@@ -185,6 +186,75 @@ AccGroupInfo::FirstItemOf(const Accessible* aContainer)
   return nullptr;
 }
 
+uint32_t
+AccGroupInfo::TotalItemCount(Accessible* aContainer, bool* aIsHierarchical)
+{
+  uint32_t itemCount = 0;
+  switch (aContainer->Role()) {
+    case roles::TABLE:
+      if (nsCoreUtils::GetUIntAttr(aContainer->GetContent(),
+                                   nsGkAtoms::aria_rowcount,
+                                   (int32_t*)&itemCount)) {
+        break;
+      }
+
+      if (TableAccessible* tableAcc = aContainer->AsTable()) {
+        return tableAcc->RowCount();
+      }
+
+      break;
+    case roles::ROW:
+      if (Accessible* table = nsAccUtils::TableFor(aContainer)) {
+        if (nsCoreUtils::GetUIntAttr(table->GetContent(),
+                                     nsGkAtoms::aria_colcount,
+                                     (int32_t*)&itemCount)) {
+          break;
+        }
+
+        if (TableAccessible* tableAcc = table->AsTable()) {
+          return tableAcc->ColCount();
+        }
+      }
+
+      break;
+    case roles::OUTLINE:
+    case roles::LIST:
+    case roles::MENUBAR:
+    case roles::MENUPOPUP:
+    case roles::COMBOBOX:
+    case roles::GROUPING:
+    case roles::TREE_TABLE:
+    case roles::COMBOBOX_LIST:
+    case roles::LISTBOX:
+    case roles::DEFINITION_LIST:
+    case roles::EDITCOMBOBOX:
+    case roles::RADIO_GROUP:
+    case roles::PAGETABLIST: {
+      Accessible* childItem = AccGroupInfo::FirstItemOf(aContainer);
+      if (!childItem) {
+        childItem = aContainer->FirstChild();
+        if (childItem->IsTextLeaf()) {
+          // First child can be a text leaf, check its sibling for an item.
+          childItem = childItem->NextSibling();
+        }
+      }
+
+      if (childItem) {
+        GroupPos groupPos = childItem->GroupPosition();
+        itemCount = groupPos.setSize;
+        if (groupPos.level && aIsHierarchical) {
+          *aIsHierarchical = true;
+        }
+      }
+      break;
+    }
+    default:
+      break;
+  }
+
+  return itemCount;
+}
+
 Accessible*
 AccGroupInfo::NextItemTo(Accessible* aItem)
 {
diff --git a/accessible/base/AccGroupInfo.h b/accessible/base/AccGroupInfo.h
index c3879860eac9b3aad2270a069b9c329524e568e6..b4fb874d5faa7701560c96ebda848049a45a6eca 100644
--- a/accessible/base/AccGroupInfo.h
+++ b/accessible/base/AccGroupInfo.h
@@ -69,6 +69,11 @@ public:
    */
   static Accessible* FirstItemOf(const Accessible* aContainer);
 
+  /**
+   * Return total number of items in container, and if it is has nested collections.
+   */
+  static uint32_t TotalItemCount(Accessible* aContainer, bool* aIsHierarchical);
+
   /**
    * Return next item of the same group to the given item.
    */
diff --git a/accessible/generic/Accessible.cpp b/accessible/generic/Accessible.cpp
index 1e9f4c59681d2854c8631df50c32f6e8735a9150..0b3c4d0ff9e472795424f04fdb22a9c4d927f8a6 100644
--- a/accessible/generic/Accessible.cpp
+++ b/accessible/generic/Accessible.cpp
@@ -1048,6 +1048,20 @@ Accessible::NativeAttributes()
   nsAccUtils::SetAccGroupAttrs(attributes, groupPos.level,
                                groupPos.setSize, groupPos.posInSet);
 
+  bool hierarchical = false;
+  uint32_t itemCount = AccGroupInfo::TotalItemCount(this, &hierarchical);
+  if (itemCount) {
+    nsAutoString itemCountStr;
+    itemCountStr.AppendInt(itemCount);
+    attributes->SetStringProperty(NS_LITERAL_CSTRING("child-item-count"),
+      itemCountStr, unused);
+  }
+
+  if (hierarchical) {
+    attributes->SetStringProperty(NS_LITERAL_CSTRING("hierarchical"),
+      NS_LITERAL_STRING("true"), unused);
+  }
+
   // If the accessible doesn't have own content (such as list item bullet or
   // xul tree item) then don't calculate content based attributes.
   if (!HasOwnContent())
diff --git a/accessible/tests/mochitest/attributes.js b/accessible/tests/mochitest/attributes.js
index 711f2623d3ff2a1d5e9bb8da379127648185b66c..f38897993aa2012898fec6663ef7eafc6b070203 100644
--- a/accessible/tests/mochitest/attributes.js
+++ b/accessible/tests/mochitest/attributes.js
@@ -25,6 +25,26 @@ function testAbsentAttrs(aAccOrElmOrID, aAbsentAttrs) {
   testAttrsInternal(aAccOrElmOrID, {}, true, aAbsentAttrs);
 }
 
+/**
+ * Test object attributes that aren't right, but should be (todo)
+ *
+ * @param aAccOrElmOrID         [in] the accessible identifier
+ * @param aKey                  [in] attribute name
+ * @param aExpectedValue        [in] expected attribute value
+ */
+function todoAttr(aAccOrElmOrID, aKey, aExpectedValue) {
+  var accessible = getAccessible(aAccOrElmOrID);
+  if (!accessible)
+    return;
+
+  var attrs = null;
+  try {
+    attrs = accessible.attributes;
+  } catch (e) { }
+
+  todo_is(attrs.getStringProperty(aKey), aExpectedValue, "attributes match");
+}
+
 /**
  * Test CSS based object attributes.
  */
@@ -96,6 +116,16 @@ function testGroupAttrs(aAccOrElmOrID, aPosInSet, aSetSize, aLevel) {
   }
 }
 
+function testGroupParentAttrs(aAccOrElmOrID, aChildItemCount, aIsHierarchical) {
+  testAttrs(aAccOrElmOrID, { "child-item-count": String(aChildItemCount) }, true);
+
+  if (aIsHierarchical) {
+    testAttrs(aAccOrElmOrID, { "hierarchical": "true" }, true);
+  } else {
+    testAbsentAttrs(aAccOrElmOrID, { "hierarchical": "true" });
+  }
+}
+
 // //////////////////////////////////////////////////////////////////////////////
 // Text attributes.
 
diff --git a/accessible/tests/mochitest/attributes/test_obj_group.html b/accessible/tests/mochitest/attributes/test_obj_group.html
index 4e0c140f388fb126d5d0e9df466c1779f4ecb11f..d2b42cb6e697e73e502a822b36fdcb04bb8ab926 100644
--- a/accessible/tests/mochitest/attributes/test_obj_group.html
+++ b/accessible/tests/mochitest/attributes/test_obj_group.html
@@ -24,6 +24,9 @@
       testGroupAttrs("opt3-nosize", 3, 4);
       testGroupAttrs("opt4-nosize", 4, 4);
 
+      // Container should have item count and not hierarchical
+      testGroupParentAttrs(getAccessible("opt1-nosize").parent, 4, false);
+
       // ////////////////////////////////////////////////////////////////////////
       // HTML select
       testGroupAttrs("opt1", 1, 2);
@@ -58,32 +61,45 @@
       testGroupAttrs("li2", 2, 3);
       testGroupAttrs("li3", 3, 3);
 
+      // ul should have item count and not hierarchical
+      testGroupParentAttrs("ul", 3, false);
+
       // ////////////////////////////////////////////////////////////////////////
       // HTML ul/ol (nested lists)
 
       testGroupAttrs("li4", 1, 3, 1);
       testGroupAttrs("li5", 2, 3, 1);
       testGroupAttrs("li6", 3, 3, 1);
+      // ol with nested list should have 1st level item count and be hierarchical
+      testGroupParentAttrs("ol", 3, true);
 
       testGroupAttrs("n_li4", 1, 3, 2);
       testGroupAttrs("n_li5", 2, 3, 2);
       testGroupAttrs("n_li6", 3, 3, 2);
+      // nested ol should have item count and be hierarchical
+      testGroupParentAttrs("ol_nested", 3, true);
 
       // ////////////////////////////////////////////////////////////////////////
       // ARIA list
       testGroupAttrs("li7", 1, 3);
       testGroupAttrs("li8", 2, 3);
       testGroupAttrs("li9", 3, 3);
+      // simple flat aria list
+      testGroupParentAttrs("aria-list_1", 3, false);
 
       // ////////////////////////////////////////////////////////////////////////
       // ARIA list (nested lists: list -> listitem -> list -> listitem)
       testGroupAttrs("li10", 1, 3, 1);
       testGroupAttrs("li11", 2, 3, 1);
       testGroupAttrs("li12", 3, 3, 1);
+      // aria list with nested list
+      testGroupParentAttrs("aria-list_2", 3, true);
 
       testGroupAttrs("n_li10", 1, 3, 2);
       testGroupAttrs("n_li11", 2, 3, 2);
       testGroupAttrs("n_li12", 3, 3, 2);
+      // nested aria list.
+      testGroupParentAttrs("aria-list_2_1", 3, true);
 
       // ////////////////////////////////////////////////////////////////////////
       // ARIA list (nested lists: list -> listitem -> group -> listitem)
@@ -93,6 +109,8 @@
       testGroupAttrs("lgt_li2", 2, 2, 1);
       testGroupAttrs("lgt_li2_nli1", 1, 2, 2);
       testGroupAttrs("lgt_li2_nli2", 2, 2, 2);
+      // aria list with nested list
+      testGroupParentAttrs("aria-list_3", 2, true);
 
       // ////////////////////////////////////////////////////////////////////////
       // ARIA menu (menuitem, separator, menuitemradio and menuitemcheckbox)
@@ -103,18 +121,27 @@
       testGroupAttrs("menu_item1.3", 1, 3);
       testGroupAttrs("menu_item1.4", 2, 3);
       testGroupAttrs("menu_item1.5", 3, 3);
+      // menu bar item count
+      testGroupParentAttrs("menubar", 2, false);
+      // Bug 1492529. Menu should have total number of items 5 from both sets,
+      // but only has the first 2 item set.
+      todoAttr("menu", "child-item-count", "5");
 
       // ////////////////////////////////////////////////////////////////////////
       // ARIA tab
       testGroupAttrs("tab_1", 1, 3);
       testGroupAttrs("tab_2", 2, 3);
       testGroupAttrs("tab_3", 3, 3);
+      // tab list tab count
+      testGroupParentAttrs("tablist_1", 3, false);
 
       // ////////////////////////////////////////////////////////////////////////
       // ARIA radio
       testGroupAttrs("r1", 1, 3);
       testGroupAttrs("r2", 2, 3);
       testGroupAttrs("r3", 3, 3);
+      // explicit aria radio group
+      testGroupParentAttrs("rg1", 3, false);
 
       // ////////////////////////////////////////////////////////////////////////
       // ARIA tree
@@ -126,6 +153,7 @@
       testGroupAttrs("ti6", 2, 3, 2);
       testGroupAttrs("ti7", 3, 3, 2);
       testGroupAttrs("ti8", 3, 3, 1);
+      testGroupParentAttrs("tree_1", 3, true);
 
       // ////////////////////////////////////////////////////////////////////////
       // ARIA tree (tree -> treeitem -> group -> treeitem)
@@ -135,6 +163,7 @@
       testGroupAttrs("tree2_ti2", 2, 2, 1);
       testGroupAttrs("tree2_ti2a", 1, 2, 2);
       testGroupAttrs("tree2_ti2b", 2, 2, 2);
+      testGroupParentAttrs("tree_2", 2, true);
 
       // ////////////////////////////////////////////////////////////////////////
       // ARIA tree (tree -> treeitem, group -> treeitem)
@@ -144,6 +173,7 @@
       testGroupAttrs("tree3_ti2", 2, 2, 1);
       testGroupAttrs("tree3_ti2a", 1, 2, 2);
       testGroupAttrs("tree3_ti2b", 2, 2, 2);
+      testGroupParentAttrs("tree_3", 2, true);
 
       // ////////////////////////////////////////////////////////////////////////
       // ARIA grid
@@ -154,6 +184,7 @@
       testGroupAttrs("grid_row2", 2, 2);
       testAbsentAttrs("grid_cell3", {"posinset": "", "setsize": ""});
       testAbsentAttrs("grid_cell4", {"posinset": "", "setsize": ""});
+      testGroupParentAttrs("grid", 2, false);
 
       // ////////////////////////////////////////////////////////////////////////
       // ARIA treegrid
@@ -169,6 +200,10 @@
       testAbsentAttrs("treegrid_cell5", {"posinset": "", "setsize": ""});
       testAbsentAttrs("treegrid_cell6", {"posinset": "", "setsize": ""});
 
+      testGroupParentAttrs("treegrid", 2, true);
+      // row child item count provided by parent grid's aria-colcount
+      testGroupParentAttrs("treegrid_row1", 4, false);
+
       // ////////////////////////////////////////////////////////////////////////
       // HTML headings
       testGroupAttrs("h1", 0, 0, 1);
@@ -177,6 +212,8 @@
       testGroupAttrs("h4", 0, 0, 4);
       testGroupAttrs("h5", 0, 0, 5);
       testGroupAttrs("h6", 0, 0, 6);
+      // No child item counts or "hierarchical" flag for parent of headings
+      testAbsentAttrs("headings", {"child-item-count": "", "hierarchical": ""});
 
       // ////////////////////////////////////////////////////////////////////////
       // ARIA combobox
@@ -184,26 +221,36 @@
       testGroupAttrs("combo1_opt2", 2, 4);
       testGroupAttrs("combo1_opt3", 3, 4);
       testGroupAttrs("combo1_opt4", 4, 4);
+      testGroupParentAttrs("combo1", 4, false);
 
       // ////////////////////////////////////////////////////////////////////////
       // ARIA table
       testGroupAttrs("table_cell", 3, 4);
       testGroupAttrs("table_row", 2, 2);
 
+      // grid child item count provided by aria-rowcount
+      testGroupParentAttrs("table", 2, false);
+      // row child item count provided by parent grid's aria-colcount
+      testGroupParentAttrs("table_row", 4, false);
+
       // ////////////////////////////////////////////////////////////////////////
       // ARIA list constructed by ARIA owns
       testGroupAttrs("t1_li1", 1, 3);
       testGroupAttrs("t1_li2", 2, 3);
       testGroupAttrs("t1_li3", 3, 3);
+      testGroupParentAttrs("aria-list_4", 3, false);
 
       // Test that group position information updates after deleting node.
       testGroupAttrs("tree4_ti1", 1, 2, 1);
       testGroupAttrs("tree4_ti2", 2, 2, 1);
+      testGroupParentAttrs("tree4", 2, true);
+
       var tree4element = document.getElementById("tree4_ti1");
       var tree4acc = getAccessible("tree4");
       tree4element.remove();
       waitForEvent(EVENT_REORDER, tree4acc, function() {
         testGroupAttrs("tree4_ti2", 1, 1, 1);
+        testGroupParentAttrs("tree4", 1, true);
         SimpleTest.finish();
       });
     }
@@ -269,17 +316,17 @@
   <input type="radio" id="radio3" name="group2"/>
   <input type="radio" id="radio4" name="group2"/>
 
-  <ul>
+  <ul id="ul">
     <li id="li1">Oranges</li>
     <li id="li2">Apples</li>
     <li id="li3">Bananas</li>
   </ul>
 
-  <ol>
+  <ol id="ol">
     <li id="li4">Oranges</li>
     <li id="li5">Apples</li>
     <li id="li6">Bananas
-      <ul>
+      <ul id="ol_nested">
         <li id="n_li4">Oranges</li>
         <li id="n_li5">Apples</li>
         <li id="n_li6">Bananas</li>
@@ -287,17 +334,17 @@
     </li>
   </ol>
 
-  <span role="list">
+  <span role="list" id="aria-list_1">
     <span role="listitem" id="li7">Oranges</span>
     <span role="listitem" id="li8">Apples</span>
     <span role="listitem" id="li9">Bananas</span>
   </span>
 
-  <span role="list">
+  <span role="list" id="aria-list_2">
     <span role="listitem" id="li10">Oranges</span>
     <span role="listitem" id="li11">Apples</span>
     <span role="listitem" id="li12">Bananas
-      <span role="list">
+      <span role="list" id="aria-list_2_1">
         <span role="listitem" id="n_li10">Oranges</span>
         <span role="listitem" id="n_li11">Apples</span>
         <span role="listitem" id="n_li12">Bananas</span>
@@ -305,7 +352,7 @@
     </span>
   </span>
 
-  <div role="list">
+  <div role="list" id="aria-list_3">
     <div role="listitem" id="lgt_li1">Item 1
       <div role="group">
         <div role="listitem" id="lgt_li1_nli1">Item 1A</div>
@@ -320,9 +367,9 @@
     </div>
   </div>
 
-  <ul role="menubar">
+  <ul role="menubar" id="menubar">
     <li role="menuitem" aria-haspopup="true" id="menu_item1">File
-      <ul role="menu">
+      <ul role="menu" id="menu">
         <li role="menuitem" id="menu_item1.1">New</li>
         <li role="menuitem" id="menu_item1.2">Open…</li>
         <li role="separator">-----</li>
@@ -346,7 +393,7 @@
     <li id="r3" role="radio" aria-checked="false">Jimmy Johns</li>
   </ul>
 
-  <table role="tree">
+  <table role="tree" id="tree_1">
     <tr role="presentation">
       <td role="treeitem" aria-expanded="true" aria-level="1"
           id="ti1">vegetables</td>
@@ -375,7 +422,7 @@
     </tr>
   </table>
 
-  <ul role="tree">
+  <ul role="tree" id="tree_2">
     <li role="treeitem" id="tree2_ti1">Item 1
       <ul role="group">
         <li role="treeitem" id="tree2_ti1a">Item 1A</li>
@@ -390,7 +437,7 @@
     </li>
   </div>
 
-  <div role="tree">
+  <div role="tree" id="tree_3">
     <div role="treeitem" id="tree3_ti1">Item 1</div>
     <div role="group">
       <li role="treeitem" id="tree3_ti1a">Item 1A</li>
@@ -408,7 +455,7 @@
     id="tree4_ti1">Item 1</div><div role="treeitem"
     id="tree4_ti2">Item 2</div></div>
 
-  <table role="grid">
+  <table role="grid" id="grid">
     <tr role="row" id="grid_row1">
       <td role="gridcell" id="grid_cell1">cell1</td>
       <td role="gridcell" id="grid_cell2">cell2</td>
@@ -419,7 +466,7 @@
     </tr>
   </table>
 
-  <div role="treegrid">
+  <div role="treegrid" id="treegrid" aria-colcount="4">
     <div role="row" aria-level="1" id="treegrid_row1">
       <div role="gridcell" id="treegrid_cell1">cell1</div>
       <div role="gridcell" id="treegrid_cell2">cell2</div>
@@ -434,12 +481,14 @@
     </div>
   </div>
 
-  <h1 id="h1">heading1</h1>
-  <h2 id="h2">heading2</h2>
-  <h3 id="h3">heading3</h3>
-  <h4 id="h4">heading4</h4>
-  <h5 id="h5">heading5</h5>
-  <h6 id="h6">heading6</h6>
+  <div id="headings">
+    <h1 id="h1">heading1</h1>
+    <h2 id="h2">heading2</h2>
+    <h3 id="h3">heading3</h3>
+    <h4 id="h4">heading4</h4>
+    <h5 id="h5">heading5</h5>
+    <h6 id="h6">heading6</h6>
+  </div>
 
   <ul id="combo1" role="combobox">Password
     <li id="combo1_opt1" role="option">Xyzzy</li>
@@ -453,13 +502,13 @@
     <input type="radio" id="radio5" name="group3">
   </form>
 
-  <div role="table" aria-colcount="4" aria-rowcount="2">
+  <div role="table" aria-colcount="4" aria-rowcount="2" id="table">
     <div role="row" id="table_row" aria-rowindex="2">
       <div role="cell" id="table_cell" aria-colindex="3">cell</div>
     </div>
   </div>
 
-  <div role="list" aria-owns="t1_li1 t1_li2 t1_li3">
+  <div role="list" aria-owns="t1_li1 t1_li2 t1_li3" id="aria-list_4">
     <div role="listitem" id="t1_li2">Apples</div>
     <div role="listitem" id="t1_li1">Oranges</div>
   </span>
diff --git a/dom/base/Attr.cpp b/dom/base/Attr.cpp
index cc12c49e9fff6d941e557134500ccb58e9c4fa37..c2b764af7f93bca1fd3e3616092c039e3b223b0d 100644
--- a/dom/base/Attr.cpp
+++ b/dom/base/Attr.cpp
@@ -37,7 +37,7 @@ bool Attr::sInitialized;
 Attr::Attr(nsDOMAttributeMap *aAttrMap,
            already_AddRefed<dom::NodeInfo>&& aNodeInfo,
            const nsAString& aValue)
-  : nsINode(aNodeInfo), mAttrMap(aAttrMap), mValue(aValue)
+  : nsINode(std::move(aNodeInfo)), mAttrMap(aAttrMap), mValue(aValue)
 {
   MOZ_ASSERT(mNodeInfo, "We must get a nodeinfo here!");
   MOZ_ASSERT(mNodeInfo->NodeType() == ATTRIBUTE_NODE,
diff --git a/dom/base/CharacterData.cpp b/dom/base/CharacterData.cpp
index ea47bf4a2d74ae33b677ad264deb9b1ddbef22db..86bf9a56d60f87929e4ef1d612306526c98d87f8 100644
--- a/dom/base/CharacterData.cpp
+++ b/dom/base/CharacterData.cpp
@@ -41,19 +41,8 @@
 namespace mozilla {
 namespace dom {
 
-CharacterData::CharacterData(already_AddRefed<dom::NodeInfo>& aNodeInfo)
-  : nsIContent(aNodeInfo)
-{
-  MOZ_ASSERT(mNodeInfo->NodeType() == TEXT_NODE ||
-             mNodeInfo->NodeType() == CDATA_SECTION_NODE ||
-             mNodeInfo->NodeType() == COMMENT_NODE ||
-             mNodeInfo->NodeType() == PROCESSING_INSTRUCTION_NODE ||
-             mNodeInfo->NodeType() == DOCUMENT_TYPE_NODE,
-             "Bad NodeType in aNodeInfo");
-}
-
 CharacterData::CharacterData(already_AddRefed<dom::NodeInfo>&& aNodeInfo)
-  : nsIContent(aNodeInfo)
+  : nsIContent(std::move(aNodeInfo))
 {
   MOZ_ASSERT(mNodeInfo->NodeType() == TEXT_NODE ||
              mNodeInfo->NodeType() == CDATA_SECTION_NODE ||
diff --git a/dom/base/CharacterData.h b/dom/base/CharacterData.h
index c7c8ca82b4f66cca6dfe3f9e1bd601c460bd8669..f07936ee038f3da66adbd1812c1c664ee5fd180e 100644
--- a/dom/base/CharacterData.h
+++ b/dom/base/CharacterData.h
@@ -85,7 +85,6 @@ public:
 
   NS_DECL_ADDSIZEOFEXCLUDINGTHIS
 
-  explicit CharacterData(already_AddRefed<dom::NodeInfo>& aNodeInfo);
   explicit CharacterData(already_AddRefed<dom::NodeInfo>&& aNodeInfo);
 
   void MarkAsMaybeModifiedFrequently()
diff --git a/dom/base/Comment.h b/dom/base/Comment.h
index 80dd21e178be2579733243eb87e236dc4a01036d..345f3ed35b0bc06eb7748c388834f43a1758d870 100644
--- a/dom/base/Comment.h
+++ b/dom/base/Comment.h
@@ -26,7 +26,7 @@ private:
 
 public:
   explicit Comment(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
-    : CharacterData(aNodeInfo)
+    : CharacterData(std::move(aNodeInfo))
   {
     Init();
   }
diff --git a/dom/base/DocumentFragment.h b/dom/base/DocumentFragment.h
index 94a244a171ca15813932ec2e67cf004ec1c5c46d..136ba9a4d0b68bb69d637ffddc10b917c3dad18b 100644
--- a/dom/base/DocumentFragment.h
+++ b/dom/base/DocumentFragment.h
@@ -43,8 +43,8 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DocumentFragment, FragmentOrElement)
 
-  explicit DocumentFragment(already_AddRefed<dom::NodeInfo>& aNodeInfo)
-    : FragmentOrElement(aNodeInfo), mHost(nullptr)
+  explicit DocumentFragment(already_AddRefed<dom::NodeInfo>&& aNodeInfo)
+    : FragmentOrElement(std::move(aNodeInfo)), mHost(nullptr)
   {
     Init();
   }
diff --git a/dom/base/DocumentType.cpp b/dom/base/DocumentType.cpp
index dd7f5fc47f6b11370d7c4da1722b93d442dc5c33..fae958e6fe01583e40cbd2d455c7a5450c74166e 100644
--- a/dom/base/DocumentType.cpp
+++ b/dom/base/DocumentType.cpp
@@ -27,13 +27,14 @@ NS_NewDOMDocumentType(nsNodeInfoManager* aNodeInfoManager,
 {
   MOZ_ASSERT(aName, "Must have a name");
 
-  already_AddRefed<mozilla::dom::NodeInfo> ni =
+  RefPtr<mozilla::dom::NodeInfo> ni =
     aNodeInfoManager->GetNodeInfo(nsGkAtoms::documentTypeNodeName, nullptr,
                                   kNameSpaceID_None,
                                   nsINode::DOCUMENT_TYPE_NODE, aName);
 
   RefPtr<mozilla::dom::DocumentType> docType =
-    new mozilla::dom::DocumentType(ni, aPublicId, aSystemId, aInternalSubset);
+    new mozilla::dom::DocumentType(ni.forget(), aPublicId, aSystemId,
+                                   aInternalSubset);
   return docType.forget();
 }
 
@@ -46,11 +47,11 @@ DocumentType::WrapNode(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
   return DocumentType_Binding::Wrap(cx, this, aGivenProto);
 }
 
-DocumentType::DocumentType(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
+DocumentType::DocumentType(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                            const nsAString& aPublicId,
                            const nsAString& aSystemId,
                            const nsAString& aInternalSubset) :
-  CharacterData(aNodeInfo),
+  CharacterData(std::move(aNodeInfo)),
   mPublicId(aPublicId),
   mSystemId(aSystemId),
   mInternalSubset(aInternalSubset)
@@ -101,8 +102,8 @@ DocumentType::GetInternalSubset(nsAString& aInternalSubset) const
 already_AddRefed<CharacterData>
 DocumentType::CloneDataNode(mozilla::dom::NodeInfo *aNodeInfo, bool aCloneText) const
 {
-  already_AddRefed<mozilla::dom::NodeInfo> ni = RefPtr<mozilla::dom::NodeInfo>(aNodeInfo).forget();
-  return do_AddRef(new DocumentType(ni, mPublicId, mSystemId, mInternalSubset));
+  return do_AddRef(new DocumentType(do_AddRef(aNodeInfo), mPublicId, mSystemId,
+                                    mInternalSubset));
 }
 
 } // namespace dom
diff --git a/dom/base/DocumentType.h b/dom/base/DocumentType.h
index 44cca0f94c7b66da9f86bd277db8266d800ba306..803caced764baf7b230f7db71fad8862cd336107 100644
--- a/dom/base/DocumentType.h
+++ b/dom/base/DocumentType.h
@@ -28,7 +28,7 @@ namespace dom {
 class DocumentType final : public CharacterData
 {
 public:
-  DocumentType(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
+  DocumentType(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                const nsAString& aPublicId,
                const nsAString& aSystemId,
                const nsAString& aInternalSubset);
diff --git a/dom/base/Element.h b/dom/base/Element.h
index b872f36474a15c957447513ef98e29c9bda56483..fc4ed5ead837ec034703d1d43aa627694482eab2 100644
--- a/dom/base/Element.h
+++ b/dom/base/Element.h
@@ -148,8 +148,8 @@ class Element : public FragmentOrElement
 {
 public:
 #ifdef MOZILLA_INTERNAL_API
-  explicit Element(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo) :
-    FragmentOrElement(aNodeInfo),
+  explicit Element(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo) :
+    FragmentOrElement(std::move(aNodeInfo)),
     mState(NS_EVENT_STATE_MOZ_READONLY | NS_EVENT_STATE_DEFINED)
   {
     MOZ_ASSERT(mNodeInfo->NodeType() == ELEMENT_NODE,
@@ -2101,9 +2101,8 @@ nsresult                                                                    \
 _elementName::Clone(mozilla::dom::NodeInfo* aNodeInfo, nsINode** aResult) const \
 {                                                                           \
   *aResult = nullptr;                                                       \
-  already_AddRefed<mozilla::dom::NodeInfo> ni =                             \
-    RefPtr<mozilla::dom::NodeInfo>(aNodeInfo).forget();                     \
-  _elementName *it = new _elementName(ni);                                  \
+  RefPtr<mozilla::dom::NodeInfo> ni(aNodeInfo);                             \
+  _elementName *it = new _elementName(ni.forget());                         \
   if (!it) {                                                                \
     return NS_ERROR_OUT_OF_MEMORY;                                          \
   }                                                                         \
@@ -2124,9 +2123,8 @@ _elementName::Clone(mozilla::dom::NodeInfo* aNodeInfo,                      \
                     nsINode** aResult) const                                \
 {                                                                           \
   *aResult = nullptr;                                                       \
-  already_AddRefed<mozilla::dom::NodeInfo> ni =                             \
-    RefPtr<mozilla::dom::NodeInfo>(aNodeInfo).forget();                     \
-  _elementName *it = new _elementName(ni EXPAND extra_args_);               \
+  RefPtr<mozilla::dom::NodeInfo> ni(aNodeInfo);                             \
+  _elementName *it = new _elementName(ni.forget() EXPAND extra_args_);      \
   if (!it) {                                                                \
     return NS_ERROR_OUT_OF_MEMORY;                                          \
   }                                                                         \
diff --git a/dom/base/FragmentOrElement.cpp b/dom/base/FragmentOrElement.cpp
index d60f8529936beaf9a5ac77fb2afa3889e8e39cfe..dbcdce2da53eb2fe2b77f632cc440aa4eb372190 100644
--- a/dom/base/FragmentOrElement.cpp
+++ b/dom/base/FragmentOrElement.cpp
@@ -857,13 +857,8 @@ FragmentOrElement::nsExtendedDOMSlots::SizeOfExcludingThis(MallocSizeOf aMallocS
   return n;
 }
 
-FragmentOrElement::FragmentOrElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : nsIContent(aNodeInfo)
-{
-}
-
 FragmentOrElement::FragmentOrElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
-  : nsIContent(aNodeInfo)
+  : nsIContent(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/base/GeneratedImageContent.cpp b/dom/base/GeneratedImageContent.cpp
index 28316263f8bb3f87200850110b5aebc4ae235f1d..c07789805f0680fdacc2cbf73fe6cb5cae3fdfbd 100644
--- a/dom/base/GeneratedImageContent.cpp
+++ b/dom/base/GeneratedImageContent.cpp
@@ -28,14 +28,7 @@ GeneratedImageContent::Create(nsIDocument& aDocument, uint32_t aContentIndex)
                   kNameSpaceID_XHTML,
                   nsINode::ELEMENT_NODE);
 
-  // Work around not being able to bind a non-const lvalue reference
-  // to an rvalue of non-reference type by just creating an rvalue
-  // reference.  And we can't change the constructor signature,
-  // because then the macro-generated Clone() method fails to compile.
-  already_AddRefed<dom::NodeInfo>&& rvalue = nodeInfo.forget();
-
-  auto image =
-    MakeRefPtr<GeneratedImageContent>(rvalue);
+  auto image = MakeRefPtr<GeneratedImageContent>(nodeInfo.forget());
   image->mIndex = aContentIndex;
   return image.forget();
 }
diff --git a/dom/base/GeneratedImageContent.h b/dom/base/GeneratedImageContent.h
index 2faee97413e5743168e8dc4e75fe98779beba4e3..5f157ed014c142eece8888fe2844bfc95e82f95e 100644
--- a/dom/base/GeneratedImageContent.h
+++ b/dom/base/GeneratedImageContent.h
@@ -26,8 +26,8 @@ public:
   static already_AddRefed<GeneratedImageContent>
     Create(nsIDocument&, uint32_t aContentIndex);
 
-  explicit GeneratedImageContent(already_AddRefed<dom::NodeInfo>& aNodeInfo)
-    : nsGenericHTMLElement(aNodeInfo)
+  explicit GeneratedImageContent(already_AddRefed<dom::NodeInfo>&& aNodeInfo)
+    : nsGenericHTMLElement(std::move(aNodeInfo))
   {
     MOZ_ASSERT(IsInNamespace(kNameSpaceID_XHTML), "Someone messed up our nodeinfo");
   }
diff --git a/dom/base/ShadowRoot.cpp b/dom/base/ShadowRoot.cpp
index 9b401e002d33110b7a122cc7cc8885552e93edba..34079b1f2ccb68178159904339797e82ee22393c 100644
--- a/dom/base/ShadowRoot.cpp
+++ b/dom/base/ShadowRoot.cpp
@@ -64,7 +64,7 @@ NS_IMPL_RELEASE_INHERITED(ShadowRoot, DocumentFragment)
 
 ShadowRoot::ShadowRoot(Element* aElement, ShadowRootMode aMode,
                        already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
-  : DocumentFragment(aNodeInfo)
+  : DocumentFragment(std::move(aNodeInfo))
   , DocumentOrShadowRoot(*this)
   , mMode(aMode)
   , mIsUAWidget(false)
diff --git a/dom/base/Text.h b/dom/base/Text.h
index c7c0c1d1b126261675866452d986488005a56ca3..9cd5a2b88ec63cb3c6a3320459f13efedf98ddec 100644
--- a/dom/base/Text.h
+++ b/dom/base/Text.h
@@ -18,12 +18,8 @@ class Text : public CharacterData
 public:
   NS_IMPL_FROMNODE_HELPER(Text, IsText())
 
-  explicit Text(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : CharacterData(aNodeInfo)
-  {}
-
   explicit Text(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
-    : CharacterData(aNodeInfo)
+  : CharacterData(std::move(aNodeInfo))
   {}
 
   // WebIDL API
diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp
index 3ce48b80a74c6318fdbcdfe89d23ab6fb6d4af49..d2dc6a0c641c17e79060cdacd5bd9b353cda3832 100644
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -1349,13 +1349,11 @@ struct nsIDocument::FrameRequest
   int32_t mHandle;
 };
 
-static already_AddRefed<mozilla::dom::NodeInfo> nullNodeInfo;
-
 // ==================================================================
 // =
 // ==================================================================
 nsIDocument::nsIDocument()
-  : nsINode(nullNodeInfo),
+  : nsINode(nullptr),
     DocumentOrShadowRoot(*this),
     mReferrerPolicySet(false),
     mReferrerPolicy(mozilla::net::RP_Unset),
diff --git a/dom/base/nsIContent.h b/dom/base/nsIContent.h
index c1cb0156f9bf3d09833c856a82013ac6c09e2d8e..d8818ce80c55a36bd00933b21ff04cd0c85b5a6a 100644
--- a/dom/base/nsIContent.h
+++ b/dom/base/nsIContent.h
@@ -61,8 +61,8 @@ public:
   // If you're using the external API, the only thing you can know about
   // nsIContent is that it exists with an IID
 
-  explicit nsIContent(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : nsINode(aNodeInfo)
+  explicit nsIContent(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : nsINode(std::move(aNodeInfo))
   {
     MOZ_ASSERT(mNodeInfo);
     SetNodeIsContent();
diff --git a/dom/base/nsINode.cpp b/dom/base/nsINode.cpp
index 5030839ac4e2ecfa96a36b9bc43465fc14b10073..0d29bce254c52e7efb25431b79e998ff870d5443 100644
--- a/dom/base/nsINode.cpp
+++ b/dom/base/nsINode.cpp
@@ -152,8 +152,8 @@ nsINode::nsSlots::Unlink()
 //----------------------------------------------------------------------
 
 #ifdef MOZILLA_INTERNAL_API
-nsINode::nsINode(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : mNodeInfo(aNodeInfo)
+nsINode::nsINode(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : mNodeInfo(std::move(aNodeInfo))
   , mParent(nullptr)
 #ifndef BOOL_FLAGS_ON_WRAPPER_CACHE
   , mBoolFlags(0)
diff --git a/dom/base/nsINode.h b/dom/base/nsINode.h
index fdbd9fea61f5e221d15514a34ac7c29b513e3db3..52f57b29b4f752dafa60c3444c1568471c52cb60 100644
--- a/dom/base/nsINode.h
+++ b/dom/base/nsINode.h
@@ -370,7 +370,7 @@ public:
   friend class AttrArray;
 
 #ifdef MOZILLA_INTERNAL_API
-  explicit nsINode(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit nsINode(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 #endif
 
   virtual ~nsINode();
diff --git a/dom/base/nsMappedAttributeElement.h b/dom/base/nsMappedAttributeElement.h
index 7e2eeb3a0a59d3273f483983248127d79313fae2..6168a3d2d5f3289ac69eff6787843e5d36aa552c 100644
--- a/dom/base/nsMappedAttributeElement.h
+++ b/dom/base/nsMappedAttributeElement.h
@@ -32,8 +32,8 @@ class nsMappedAttributeElement : public nsMappedAttributeElementBase
 
 protected:
 
-  explicit nsMappedAttributeElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : nsMappedAttributeElementBase(aNodeInfo)
+  explicit nsMappedAttributeElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : nsMappedAttributeElementBase(std::move(aNodeInfo))
   {}
 
 public:
diff --git a/dom/base/nsStyledElement.h b/dom/base/nsStyledElement.h
index 5ef9282d2e58f3042f7fdec8d9a9572822492707..8c2c52cc8d1b4575bf99eaaff41f1acc4a1b21b8 100644
--- a/dom/base/nsStyledElement.h
+++ b/dom/base/nsStyledElement.h
@@ -33,8 +33,8 @@ class nsStyledElement : public nsStyledElementBase
 
 protected:
 
-  inline explicit nsStyledElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : nsStyledElementBase(aNodeInfo)
+  inline explicit nsStyledElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : nsStyledElementBase(std::move(aNodeInfo))
   {}
 
 public:
diff --git a/dom/base/nsTextNode.cpp b/dom/base/nsTextNode.cpp
index cb748337a8b036f59a9abf30729f89c9789c3af9..50726dddaa2f4f78ee289b067419741de1a3d7b9 100644
--- a/dom/base/nsTextNode.cpp
+++ b/dom/base/nsTextNode.cpp
@@ -34,10 +34,10 @@ class nsAttributeTextNode final : public nsTextNode,
 public:
   NS_DECL_ISUPPORTS_INHERITED
 
-  nsAttributeTextNode(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
+  nsAttributeTextNode(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                       int32_t aNameSpaceID,
                       nsAtom* aAttrName) :
-    nsTextNode(aNodeInfo),
+    nsTextNode(std::move(aNodeInfo)),
     mGrandparent(nullptr),
     mNameSpaceID(aNameSpaceID),
     mAttrName(aAttrName)
@@ -58,10 +58,8 @@ public:
     CloneDataNode(mozilla::dom::NodeInfo *aNodeInfo,
                   bool aCloneText) const override
   {
-    already_AddRefed<mozilla::dom::NodeInfo> ni =
-      RefPtr<mozilla::dom::NodeInfo>(aNodeInfo).forget();
     RefPtr<nsAttributeTextNode> it =
-      new nsAttributeTextNode(ni, mNameSpaceID, mAttrName);
+      new nsAttributeTextNode(do_AddRef(aNodeInfo), mNameSpaceID, mAttrName);
     if (aCloneText) {
       it->mText = mText;
     }
@@ -115,8 +113,7 @@ nsTextNode::IsNodeOfType(uint32_t aFlags) const
 already_AddRefed<CharacterData>
 nsTextNode::CloneDataNode(mozilla::dom::NodeInfo *aNodeInfo, bool aCloneText) const
 {
-  already_AddRefed<mozilla::dom::NodeInfo> ni = RefPtr<mozilla::dom::NodeInfo>(aNodeInfo).forget();
-  RefPtr<nsTextNode> it = new nsTextNode(ni);
+  RefPtr<nsTextNode> it = new nsTextNode(do_AddRef(aNodeInfo));
   if (aCloneText) {
     it->mText = mText;
   }
@@ -219,12 +216,12 @@ NS_NewAttributeContent(nsNodeInfoManager *aNodeInfoManager,
 
   *aResult = nullptr;
 
-  already_AddRefed<mozilla::dom::NodeInfo> ni = aNodeInfoManager->GetTextNodeInfo();
+  RefPtr<mozilla::dom::NodeInfo> ni = aNodeInfoManager->GetTextNodeInfo();
 
-  nsAttributeTextNode* textNode = new nsAttributeTextNode(ni,
-                                                          aNameSpaceID,
-                                                          aAttrName);
-  NS_ADDREF(*aResult = textNode);
+  RefPtr<nsAttributeTextNode> textNode = new nsAttributeTextNode(ni.forget(),
+                                                                 aNameSpaceID,
+                                                                 aAttrName);
+  textNode.forget(aResult);
 
   return NS_OK;
 }
diff --git a/dom/base/nsTextNode.h b/dom/base/nsTextNode.h
index cd6dd02efad0d3fa9f85457391ba6d8db6d2cbb6..0f7dd40039f67888c0b121a92847ddf88df0e35e 100644
--- a/dom/base/nsTextNode.h
+++ b/dom/base/nsTextNode.h
@@ -30,8 +30,8 @@ private:
   }
 
 public:
-  explicit nsTextNode(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : mozilla::dom::Text(aNodeInfo)
+  explicit nsTextNode(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : mozilla::dom::Text(std::move(aNodeInfo))
   {
     Init();
   }
diff --git a/dom/canvas/OffscreenCanvas.cpp b/dom/canvas/OffscreenCanvas.cpp
index f950c0e1d6a847ff2c1391c747fb93def285fc17..80fa39b0e1605888c6d66efcc56a7f6bd2f634a7 100644
--- a/dom/canvas/OffscreenCanvas.cpp
+++ b/dom/canvas/OffscreenCanvas.cpp
@@ -128,7 +128,7 @@ OffscreenCanvas::GetContext(JSContext* aCx,
     return nullptr;
   }
 
-  already_AddRefed<nsISupports> result =
+  RefPtr<nsISupports> result =
     CanvasRenderingContextHelper::GetContext(aCx,
                                              aContextId,
                                              aContextOptions,
@@ -166,7 +166,7 @@ OffscreenCanvas::GetContext(JSContext* aCx,
     }
   }
 
-  return result;
+  return result.forget();
 }
 
 already_AddRefed<nsICanvasRenderingContextInternal>
diff --git a/dom/html/HTMLAnchorElement.h b/dom/html/HTMLAnchorElement.h
index f61ad17f6e870b6f60d471fd6805e3ec6ce02274..c0b00f568dc45e43bfb93501edef05d519eaac43 100644
--- a/dom/html/HTMLAnchorElement.h
+++ b/dom/html/HTMLAnchorElement.h
@@ -23,8 +23,8 @@ class HTMLAnchorElement final : public nsGenericHTMLElement,
 public:
   using Element::GetText;
 
-  explicit HTMLAnchorElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : nsGenericHTMLElement(aNodeInfo)
+  explicit HTMLAnchorElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : nsGenericHTMLElement(std::move(aNodeInfo))
     , Link(this)
   {
   }
diff --git a/dom/html/HTMLAreaElement.cpp b/dom/html/HTMLAreaElement.cpp
index 99fa131dca3a4fa6c61227c9b24738fa216ca8d8..295d20721e85978e905324fad2d4b6a7d5d8e8ff 100644
--- a/dom/html/HTMLAreaElement.cpp
+++ b/dom/html/HTMLAreaElement.cpp
@@ -19,8 +19,8 @@ NS_IMPL_NS_NEW_HTML_ELEMENT(Area)
 namespace mozilla {
 namespace dom {
 
-HTMLAreaElement::HTMLAreaElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : nsGenericHTMLElement(aNodeInfo)
+HTMLAreaElement::HTMLAreaElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : nsGenericHTMLElement(std::move(aNodeInfo))
   , Link(this)
 {
 }
diff --git a/dom/html/HTMLAreaElement.h b/dom/html/HTMLAreaElement.h
index 8f7df21b8438c06382abd1dde2465e73e50ff111..028e4f59ee94d2311b4b15cc37880e8f461aab57 100644
--- a/dom/html/HTMLAreaElement.h
+++ b/dom/html/HTMLAreaElement.h
@@ -24,7 +24,7 @@ class HTMLAreaElement final : public nsGenericHTMLElement,
                               public Link
 {
 public:
-  explicit HTMLAreaElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit HTMLAreaElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
diff --git a/dom/html/HTMLAudioElement.cpp b/dom/html/HTMLAudioElement.cpp
index a607eb02e615385a402e768eb034b0840c28660c..9beb4a85bcc2140334c9f6db600b13c6ae30361b 100644
--- a/dom/html/HTMLAudioElement.cpp
+++ b/dom/html/HTMLAudioElement.cpp
@@ -27,8 +27,8 @@ namespace dom {
 
 NS_IMPL_ELEMENT_CLONE(HTMLAudioElement)
 
-HTMLAudioElement::HTMLAudioElement(already_AddRefed<NodeInfo>& aNodeInfo)
-  : HTMLMediaElement(aNodeInfo)
+HTMLAudioElement::HTMLAudioElement(already_AddRefed<NodeInfo>&& aNodeInfo)
+: HTMLMediaElement(std::move(aNodeInfo))
 {
   DecoderDoctorLogger::LogConstruction(this);
 }
@@ -57,12 +57,12 @@ HTMLAudioElement::Audio(const GlobalObject& aGlobal,
     return nullptr;
   }
 
-  already_AddRefed<mozilla::dom::NodeInfo> nodeInfo =
+  RefPtr<mozilla::dom::NodeInfo> nodeInfo =
     doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::audio, nullptr,
                                         kNameSpaceID_XHTML,
                                         ELEMENT_NODE);
 
-  RefPtr<HTMLAudioElement> audio = new HTMLAudioElement(nodeInfo);
+  RefPtr<HTMLAudioElement> audio = new HTMLAudioElement(nodeInfo.forget());
   audio->SetHTMLAttr(nsGkAtoms::preload, NS_LITERAL_STRING("auto"), aRv);
   if (aRv.Failed()) {
     return nullptr;
diff --git a/dom/html/HTMLAudioElement.h b/dom/html/HTMLAudioElement.h
index 94b42cd64a426adf7fe3d89ad198a7985e2243f2..08e4031de7af20c3a7c7b59f9069a68c9016d641 100644
--- a/dom/html/HTMLAudioElement.h
+++ b/dom/html/HTMLAudioElement.h
@@ -23,7 +23,7 @@ public:
 
   NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLAudioElement, audio)
 
-  explicit HTMLAudioElement(already_AddRefed<NodeInfo>& aNodeInfo);
+  explicit HTMLAudioElement(already_AddRefed<NodeInfo>&& aNodeInfo);
 
   // Element
   virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const override;
diff --git a/dom/html/HTMLBRElement.cpp b/dom/html/HTMLBRElement.cpp
index 68bd34798f43eae5da3678b135c1dbf6cd5c41e2..6654eaa3cf567fd2d0177cc8a8df08cd1e33522c 100644
--- a/dom/html/HTMLBRElement.cpp
+++ b/dom/html/HTMLBRElement.cpp
@@ -17,8 +17,8 @@ NS_IMPL_NS_NEW_HTML_ELEMENT(BR)
 namespace mozilla {
 namespace dom {
 
-HTMLBRElement::HTMLBRElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : nsGenericHTMLElement(aNodeInfo)
+HTMLBRElement::HTMLBRElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : nsGenericHTMLElement(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/html/HTMLBRElement.h b/dom/html/HTMLBRElement.h
index ac9aa9f95442ac9c936073bc6504b7ddd167ce41..d42759f2ee597e1e6846e11a0658cde273ebdf75 100644
--- a/dom/html/HTMLBRElement.h
+++ b/dom/html/HTMLBRElement.h
@@ -17,7 +17,7 @@ namespace dom {
 class HTMLBRElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLBRElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit HTMLBRElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
   virtual bool ParseAttribute(int32_t aNamespaceID,
                                 nsAtom* aAttribute,
diff --git a/dom/html/HTMLBodyElement.h b/dom/html/HTMLBodyElement.h
index 95d00d1f3b78e7348ef5ffc0267f03e8b9311c1c..3cd3db4c46f315008c4684dc7c6aaa226bfc221e 100644
--- a/dom/html/HTMLBodyElement.h
+++ b/dom/html/HTMLBodyElement.h
@@ -22,8 +22,8 @@ class HTMLBodyElement final : public nsGenericHTMLElement
 public:
   using Element::GetText;
 
-  explicit HTMLBodyElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : nsGenericHTMLElement(aNodeInfo)
+  explicit HTMLBodyElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : nsGenericHTMLElement(std::move(aNodeInfo))
   {
   }
 
diff --git a/dom/html/HTMLButtonElement.cpp b/dom/html/HTMLButtonElement.cpp
index 74cde1d3183782117bd23963198c8538044b59c3..dec9cd3aac33ed363db363719ca709c0ff9aa6e9 100644
--- a/dom/html/HTMLButtonElement.cpp
+++ b/dom/html/HTMLButtonElement.cpp
@@ -53,9 +53,9 @@ static const nsAttrValue::EnumTable* kButtonDefaultType = &kButtonTypeTable[2];
 
 
 // Construction, destruction
-HTMLButtonElement::HTMLButtonElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
+HTMLButtonElement::HTMLButtonElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                                      FromParser aFromParser)
-  : nsGenericHTMLFormElementWithState(aNodeInfo, kButtonDefaultType->value),
+  : nsGenericHTMLFormElementWithState(std::move(aNodeInfo), kButtonDefaultType->value),
     mDisabledChanged(false),
     mInInternalActivate(false),
     mInhibitStateRestoration(!!(aFromParser & FROM_PARSER_FRAGMENT))
diff --git a/dom/html/HTMLButtonElement.h b/dom/html/HTMLButtonElement.h
index 2aee8b5e1ed15cc28d85caa8af4b6e8c8313e30d..7a8846f75d82c9623cfc1520e697506dfa80a0bb 100644
--- a/dom/html/HTMLButtonElement.h
+++ b/dom/html/HTMLButtonElement.h
@@ -22,7 +22,7 @@ class HTMLButtonElement final : public nsGenericHTMLFormElementWithState,
 public:
   using nsIConstraintValidation::GetValidationMessage;
 
-  explicit HTMLButtonElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
+  explicit HTMLButtonElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                              FromParser aFromParser = NOT_FROM_PARSER);
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLButtonElement,
diff --git a/dom/html/HTMLCanvasElement.cpp b/dom/html/HTMLCanvasElement.cpp
index 800a6f2803c82cf65f506b96295908ae70f5bc7e..077e59e38790e68a79f0139ebc38d64d95a4a8b3 100644
--- a/dom/html/HTMLCanvasElement.cpp
+++ b/dom/html/HTMLCanvasElement.cpp
@@ -393,8 +393,8 @@ NS_IMPL_ISUPPORTS(HTMLCanvasElementObserver, nsIObserver)
 
 // ---------------------------------------------------------------------------
 
-HTMLCanvasElement::HTMLCanvasElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : nsGenericHTMLElement(aNodeInfo),
+HTMLCanvasElement::HTMLCanvasElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : nsGenericHTMLElement(std::move(aNodeInfo)),
     mResetLayer(true) ,
     mWriteOnly(false)
 {}
diff --git a/dom/html/HTMLCanvasElement.h b/dom/html/HTMLCanvasElement.h
index db54c874fffe13798f424a0054703b929f66c7ec..6cf307e1403ebf9657502437301379b247910b0b 100644
--- a/dom/html/HTMLCanvasElement.h
+++ b/dom/html/HTMLCanvasElement.h
@@ -131,7 +131,7 @@ class HTMLCanvasElement final : public nsGenericHTMLElement,
   typedef layers::WebRenderCanvasData WebRenderCanvasData;
 
 public:
-  explicit HTMLCanvasElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit HTMLCanvasElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
   NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLCanvasElement, canvas)
 
diff --git a/dom/html/HTMLDataElement.cpp b/dom/html/HTMLDataElement.cpp
index e891b02330f2da200c27ef0f53c763e582761eb2..e87ef96c591cc5dff20239c2e8067f824643b54e 100644
--- a/dom/html/HTMLDataElement.cpp
+++ b/dom/html/HTMLDataElement.cpp
@@ -13,8 +13,8 @@ NS_IMPL_NS_NEW_HTML_ELEMENT(Data)
 namespace mozilla {
 namespace dom {
 
-HTMLDataElement::HTMLDataElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : nsGenericHTMLElement(aNodeInfo)
+HTMLDataElement::HTMLDataElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : nsGenericHTMLElement(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/html/HTMLDataElement.h b/dom/html/HTMLDataElement.h
index 1c424a24739c324e8dee84b99b2120d16ecf13b1..6c38e57b9d3f1018262d3378d6411e326903adb2 100644
--- a/dom/html/HTMLDataElement.h
+++ b/dom/html/HTMLDataElement.h
@@ -17,7 +17,7 @@ namespace dom {
 class HTMLDataElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLDataElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit HTMLDataElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
   // HTMLDataElement WebIDL
   void GetValue(DOMString& aValue)
diff --git a/dom/html/HTMLDataListElement.h b/dom/html/HTMLDataListElement.h
index f337484b9a5cd7cea5bbc84509c355aa84b2d1c5..dd1f4e17f85228eb1bc3fe588a645b2d21e43ad9 100644
--- a/dom/html/HTMLDataListElement.h
+++ b/dom/html/HTMLDataListElement.h
@@ -16,8 +16,8 @@ namespace dom {
 class HTMLDataListElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLDataListElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : nsGenericHTMLElement(aNodeInfo)
+  explicit HTMLDataListElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : nsGenericHTMLElement(std::move(aNodeInfo))
   {
   }
 
diff --git a/dom/html/HTMLDetailsElement.h b/dom/html/HTMLDetailsElement.h
index 2a4c7f06b5230afd7e887355ff5fb2619315dc48..2d6d5dd7ae579e92f904e63f32ccb0c475cebccb 100644
--- a/dom/html/HTMLDetailsElement.h
+++ b/dom/html/HTMLDetailsElement.h
@@ -24,8 +24,8 @@ class HTMLDetailsElement final : public nsGenericHTMLElement
 public:
   using NodeInfo = mozilla::dom::NodeInfo;
 
-  explicit HTMLDetailsElement(already_AddRefed<NodeInfo>& aNodeInfo)
-    : nsGenericHTMLElement(aNodeInfo)
+  explicit HTMLDetailsElement(already_AddRefed<NodeInfo>&& aNodeInfo)
+    : nsGenericHTMLElement(std::move(aNodeInfo))
   {
   }
 
diff --git a/dom/html/HTMLDialogElement.cpp b/dom/html/HTMLDialogElement.cpp
index b4f33b5bd48d5f13ea96fe5d29435faa81221c71..60d27fb3d32b6888d851da86304d3384e76352db 100644
--- a/dom/html/HTMLDialogElement.cpp
+++ b/dom/html/HTMLDialogElement.cpp
@@ -15,10 +15,10 @@ NS_NewHTMLDialogElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                          mozilla::dom::FromParser aFromParser)
 {
   if (!mozilla::dom::HTMLDialogElement::IsDialogEnabled()) {
-    return new mozilla::dom::HTMLUnknownElement(aNodeInfo);
+    return new mozilla::dom::HTMLUnknownElement(std::move(aNodeInfo));
   }
 
-  return new mozilla::dom::HTMLDialogElement(aNodeInfo);
+  return new mozilla::dom::HTMLDialogElement(std::move(aNodeInfo));
 }
 
 namespace mozilla {
diff --git a/dom/html/HTMLDialogElement.h b/dom/html/HTMLDialogElement.h
index 890829fb3f9d920f3164e6e66554f62c45d8177e..1d5a82fbd40c2da11e683f0923f7cbb309235f35 100644
--- a/dom/html/HTMLDialogElement.h
+++ b/dom/html/HTMLDialogElement.h
@@ -18,7 +18,8 @@ namespace dom {
 class HTMLDialogElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLDialogElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo) : nsGenericHTMLElement(aNodeInfo)
+  explicit HTMLDialogElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : nsGenericHTMLElement(std::move(aNodeInfo))
   {
   }
 
diff --git a/dom/html/HTMLDivElement.h b/dom/html/HTMLDivElement.h
index c0352d9702a2ef6f83e5f6e3648f6e0f7a8f9589..349a31fc3e09ce1ba6bcdbd0b1dacbc3593480e9 100644
--- a/dom/html/HTMLDivElement.h
+++ b/dom/html/HTMLDivElement.h
@@ -15,8 +15,8 @@ namespace dom {
 class HTMLDivElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLDivElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : nsGenericHTMLElement(aNodeInfo)
+  explicit HTMLDivElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : nsGenericHTMLElement(std::move(aNodeInfo))
   {
   }
 
diff --git a/dom/html/HTMLElement.cpp b/dom/html/HTMLElement.cpp
index 57a1397f785904858fd7b9fe7df174679cd29d1e..76caa73cf8c7d455620e1c5e5740a3a05d574abd 100644
--- a/dom/html/HTMLElement.cpp
+++ b/dom/html/HTMLElement.cpp
@@ -14,7 +14,7 @@ namespace dom {
 class HTMLElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit HTMLElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   virtual ~HTMLElement();
 
   nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
@@ -23,8 +23,8 @@ protected:
   JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
 };
 
-HTMLElement::HTMLElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : nsGenericHTMLElement(aNodeInfo)
+HTMLElement::HTMLElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : nsGenericHTMLElement(std::move(aNodeInfo))
 {
   if (NodeInfo()->Equals(nsGkAtoms::bdi)) {
     AddStatesSilently(NS_EVENT_STATE_DIR_ATTR_LIKE_AUTO);
@@ -52,7 +52,7 @@ nsGenericHTMLElement*
 NS_NewHTMLElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                   mozilla::dom::FromParser aFromParser)
 {
-  return new mozilla::dom::HTMLElement(aNodeInfo);
+  return new mozilla::dom::HTMLElement(std::move(aNodeInfo));
 }
 
 // Distinct from the above in order to have function pointer that compared unequal
@@ -61,5 +61,5 @@ nsGenericHTMLElement*
 NS_NewCustomElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                     mozilla::dom::FromParser aFromParser)
 {
-  return new mozilla::dom::HTMLElement(aNodeInfo);
+  return new mozilla::dom::HTMLElement(std::move(aNodeInfo));
 }
diff --git a/dom/html/HTMLEmbedElement.cpp b/dom/html/HTMLEmbedElement.cpp
index 822a39bbfdf896e9d80c58608c94b2513695e443..d1c8855f908fc1d652a39f8bc7b6852108ba6ce0 100644
--- a/dom/html/HTMLEmbedElement.cpp
+++ b/dom/html/HTMLEmbedElement.cpp
@@ -27,9 +27,9 @@ NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Embed)
 namespace mozilla {
 namespace dom {
 
-HTMLEmbedElement::HTMLEmbedElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
+HTMLEmbedElement::HTMLEmbedElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                                    FromParser aFromParser)
-  : nsGenericHTMLElement(aNodeInfo)
+  : nsGenericHTMLElement(std::move(aNodeInfo))
 {
   RegisterActivityObserver();
   SetIsNetworkCreated(aFromParser == FROM_PARSER_NETWORK);
diff --git a/dom/html/HTMLEmbedElement.h b/dom/html/HTMLEmbedElement.h
index 3f16dedad085970f739e2f197a343312229088af..8588488ef983c5d55e52afb61558faf97dce6336 100644
--- a/dom/html/HTMLEmbedElement.h
+++ b/dom/html/HTMLEmbedElement.h
@@ -20,7 +20,7 @@ class HTMLEmbedElement final : public nsGenericHTMLElement
                              , public nsObjectLoadingContent
 {
 public:
-  explicit HTMLEmbedElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
+  explicit HTMLEmbedElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                             mozilla::dom::FromParser aFromParser = mozilla::dom::NOT_FROM_PARSER);
 
   // nsISupports
diff --git a/dom/html/HTMLFieldSetElement.cpp b/dom/html/HTMLFieldSetElement.cpp
index de5c082da34a9fec94b2623862e792666b059363..3e1c65acc7dcd31a4db6b243bc0dc908e458feac 100644
--- a/dom/html/HTMLFieldSetElement.cpp
+++ b/dom/html/HTMLFieldSetElement.cpp
@@ -17,8 +17,8 @@ NS_IMPL_NS_NEW_HTML_ELEMENT(FieldSet)
 namespace mozilla {
 namespace dom {
 
-HTMLFieldSetElement::HTMLFieldSetElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : nsGenericHTMLFormElement(aNodeInfo, NS_FORM_FIELDSET)
+HTMLFieldSetElement::HTMLFieldSetElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : nsGenericHTMLFormElement(std::move(aNodeInfo), NS_FORM_FIELDSET)
   , mElements(nullptr)
   , mFirstLegend(nullptr)
   , mInvalidElementsCount(0)
diff --git a/dom/html/HTMLFieldSetElement.h b/dom/html/HTMLFieldSetElement.h
index b3baa6d6314099a4e60bf3fc7634f12227ebb018..cb3c5d607891053490f2d2e86a1a91adc988a033 100644
--- a/dom/html/HTMLFieldSetElement.h
+++ b/dom/html/HTMLFieldSetElement.h
@@ -25,7 +25,7 @@ public:
   using nsIConstraintValidation::GetValidationMessage;
   using nsIConstraintValidation::SetCustomValidity;
 
-  explicit HTMLFieldSetElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit HTMLFieldSetElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
   NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLFieldSetElement, fieldset)
 
diff --git a/dom/html/HTMLFontElement.h b/dom/html/HTMLFontElement.h
index b411493719650ec809a8254e7dfa2ce379db0d65..bdb0f4d457a5e5f7c8b18c6f11f54f17d018e46d 100644
--- a/dom/html/HTMLFontElement.h
+++ b/dom/html/HTMLFontElement.h
@@ -15,8 +15,8 @@ namespace dom {
 class HTMLFontElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLFontElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : nsGenericHTMLElement(aNodeInfo)
+  explicit HTMLFontElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : nsGenericHTMLElement(std::move(aNodeInfo))
   {
   }
 
diff --git a/dom/html/HTMLFormElement.cpp b/dom/html/HTMLFormElement.cpp
index 971b054344e9b89d8920adef2c0b17ca41eda45c..7c9fe66ce6f657c8ad0c66574d68dcf936ff084d 100644
--- a/dom/html/HTMLFormElement.cpp
+++ b/dom/html/HTMLFormElement.cpp
@@ -95,8 +95,8 @@ static const nsAttrValue::EnumTable* kFormDefaultAutocomplete = &kFormAutocomple
 bool HTMLFormElement::gFirstFormSubmitted = false;
 bool HTMLFormElement::gPasswordManagerInitialized = false;
 
-HTMLFormElement::HTMLFormElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : nsGenericHTMLElement(aNodeInfo),
+HTMLFormElement::HTMLFormElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : nsGenericHTMLElement(std::move(aNodeInfo)),
     mControls(new HTMLFormControlsCollection(this)),
     mSelectedRadioButtons(2),
     mRequiredRadioButtonCounts(2),
diff --git a/dom/html/HTMLFormElement.h b/dom/html/HTMLFormElement.h
index 9d9b1b2300747e9645f5012367afe7db07a7262a..db1bd7bafac319577e1e1ebfeab6fa9533a15957 100644
--- a/dom/html/HTMLFormElement.h
+++ b/dom/html/HTMLFormElement.h
@@ -44,7 +44,7 @@ class HTMLFormElement final : public nsGenericHTMLElement,
 public:
   NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLFormElement, form)
 
-  explicit HTMLFormElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit HTMLFormElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
   enum {
     FORM_CONTROL_LIST_HASHTABLE_LENGTH = 8
diff --git a/dom/html/HTMLFrameElement.cpp b/dom/html/HTMLFrameElement.cpp
index 872739ea39deff6d13565939602fdef3957fdf6a..48703ef615078daf801b314b638f843e4f0f6add 100644
--- a/dom/html/HTMLFrameElement.cpp
+++ b/dom/html/HTMLFrameElement.cpp
@@ -12,9 +12,9 @@ NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Frame)
 namespace mozilla {
 namespace dom {
 
-HTMLFrameElement::HTMLFrameElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
+HTMLFrameElement::HTMLFrameElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                                    FromParser aFromParser)
-  : nsGenericHTMLFrameElement(aNodeInfo, aFromParser)
+  : nsGenericHTMLFrameElement(std::move(aNodeInfo), aFromParser)
 {
 }
 
diff --git a/dom/html/HTMLFrameElement.h b/dom/html/HTMLFrameElement.h
index 3a3c5d9d34e9a9acdf6ea6d3016abe096e50ff33..f507aae660970a7fdba685b8c70246b7f00d29fd 100644
--- a/dom/html/HTMLFrameElement.h
+++ b/dom/html/HTMLFrameElement.h
@@ -19,7 +19,7 @@ class HTMLFrameElement final : public nsGenericHTMLFrameElement
 public:
   using nsGenericHTMLFrameElement::SwapFrameLoaders;
 
-  explicit HTMLFrameElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
+  explicit HTMLFrameElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                             FromParser aFromParser = NOT_FROM_PARSER);
 
   // nsISupports
diff --git a/dom/html/HTMLFrameSetElement.h b/dom/html/HTMLFrameSetElement.h
index bca67b8305df876a4d4bfc9309e6ed460de07b4f..fa930984a64133031f3f248d695dced78084308f 100644
--- a/dom/html/HTMLFrameSetElement.h
+++ b/dom/html/HTMLFrameSetElement.h
@@ -46,8 +46,8 @@ class OnBeforeUnloadEventHandlerNonNull;
 class HTMLFrameSetElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLFrameSetElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : nsGenericHTMLElement(aNodeInfo),
+  explicit HTMLFrameSetElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : nsGenericHTMLElement(std::move(aNodeInfo)),
       mNumRows(0),
       mNumCols(0),
       mCurrentRowColHint(NS_STYLE_HINT_REFLOW)
diff --git a/dom/html/HTMLHRElement.cpp b/dom/html/HTMLHRElement.cpp
index 36bd3d6d6db7400ae546e81a9386679548aa2490..a92b1e1e3bc3ce962efb65f66507ee80b8e676d7 100644
--- a/dom/html/HTMLHRElement.cpp
+++ b/dom/html/HTMLHRElement.cpp
@@ -14,8 +14,8 @@ NS_IMPL_NS_NEW_HTML_ELEMENT(HR)
 namespace mozilla {
 namespace dom {
 
-HTMLHRElement::HTMLHRElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : nsGenericHTMLElement(aNodeInfo)
+HTMLHRElement::HTMLHRElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : nsGenericHTMLElement(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/html/HTMLHRElement.h b/dom/html/HTMLHRElement.h
index 732aa844344d0164f9bef7b05b05717aa1f2f9ed..b892ff7678af025dac97b333bc7e8fe3bab0906a 100644
--- a/dom/html/HTMLHRElement.h
+++ b/dom/html/HTMLHRElement.h
@@ -18,7 +18,7 @@ namespace dom {
 class HTMLHRElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLHRElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit HTMLHRElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
   // nsISupports
   NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLHRElement, nsGenericHTMLElement)
diff --git a/dom/html/HTMLHeadingElement.h b/dom/html/HTMLHeadingElement.h
index 2b8acc00d42a010f19e4d259b5976751af586943..98b6d8ec30527fa233cca63c980d5fa6079623fc 100644
--- a/dom/html/HTMLHeadingElement.h
+++ b/dom/html/HTMLHeadingElement.h
@@ -16,8 +16,8 @@ namespace dom {
 class HTMLHeadingElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLHeadingElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : nsGenericHTMLElement(aNodeInfo)
+  explicit HTMLHeadingElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : nsGenericHTMLElement(std::move(aNodeInfo))
   {
   }
 
diff --git a/dom/html/HTMLIFrameElement.cpp b/dom/html/HTMLIFrameElement.cpp
index c5905882197d461ee5532750bebd4c1e5f8e67d9..b1c52bddd763d3f091bec63744e8dde2953df4c5 100644
--- a/dom/html/HTMLIFrameElement.cpp
+++ b/dom/html/HTMLIFrameElement.cpp
@@ -27,9 +27,9 @@ const DOMTokenListSupportedToken HTMLIFrameElement::sSupportedSandboxTokens[] =
   nullptr
 };
 
-HTMLIFrameElement::HTMLIFrameElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
+HTMLIFrameElement::HTMLIFrameElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                                      FromParser aFromParser)
-  : nsGenericHTMLFrameElement(aNodeInfo, aFromParser)
+  : nsGenericHTMLFrameElement(std::move(aNodeInfo), aFromParser)
 {
 }
 
diff --git a/dom/html/HTMLIFrameElement.h b/dom/html/HTMLIFrameElement.h
index d07ae6367fa6a56814634fcdcd70e79d1360958d..c73624ff19f912cd8f330114e0bd848fa5f88678 100644
--- a/dom/html/HTMLIFrameElement.h
+++ b/dom/html/HTMLIFrameElement.h
@@ -17,7 +17,7 @@ namespace dom {
 class HTMLIFrameElement final : public nsGenericHTMLFrameElement
 {
 public:
-  explicit HTMLIFrameElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
+  explicit HTMLIFrameElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                              FromParser aFromParser = NOT_FROM_PARSER);
 
   NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLIFrameElement, iframe)
diff --git a/dom/html/HTMLImageElement.cpp b/dom/html/HTMLImageElement.cpp
index 5dd41297c8bb2afee8cac1da330aaff5a8eccd01..2d683f78e66f0859364a4ee416f7e66bfde08d29 100644
--- a/dom/html/HTMLImageElement.cpp
+++ b/dom/html/HTMLImageElement.cpp
@@ -117,8 +117,8 @@ private:
   bool mUseUrgentStartForChannel;
 };
 
-HTMLImageElement::HTMLImageElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : nsGenericHTMLElement(aNodeInfo)
+HTMLImageElement::HTMLImageElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : nsGenericHTMLElement(std::move(aNodeInfo))
   , mForm(nullptr)
   , mInDocResponsiveContent(false)
   , mCurrentDensity(1.0)
@@ -734,12 +734,12 @@ HTMLImageElement::Image(const GlobalObject& aGlobal,
     return nullptr;
   }
 
-  already_AddRefed<mozilla::dom::NodeInfo> nodeInfo =
+  RefPtr<mozilla::dom::NodeInfo> nodeInfo =
     doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::img, nullptr,
                                         kNameSpaceID_XHTML,
                                         ELEMENT_NODE);
 
-  RefPtr<HTMLImageElement> img = new HTMLImageElement(nodeInfo);
+  RefPtr<HTMLImageElement> img = new HTMLImageElement(nodeInfo.forget());
 
   if (aWidth.WasPassed()) {
     img->SetWidth(aWidth.Value(), aError);
diff --git a/dom/html/HTMLImageElement.h b/dom/html/HTMLImageElement.h
index 5bca5eeb70de33e993195d26f765732680c12410..55ec0858e3ae7f72b60a2b77d83ca2f4b4cfc640 100644
--- a/dom/html/HTMLImageElement.h
+++ b/dom/html/HTMLImageElement.h
@@ -27,7 +27,7 @@ class HTMLImageElement final : public nsGenericHTMLElement,
   friend class HTMLPictureElement;
   friend class ImageLoadTask;
 public:
-  explicit HTMLImageElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit HTMLImageElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
   static already_AddRefed<HTMLImageElement>
     Image(const GlobalObject& aGlobal,
diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp
index 48229708bcea39e95f17ce0c83a2ee9d5830c45f..585e07b34f51874a13d87fdd4032b105d41f4f44 100644
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -989,9 +989,9 @@ HTMLInputElement::Shutdown()
 // construction, destruction
 //
 
-HTMLInputElement::HTMLInputElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
+HTMLInputElement::HTMLInputElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                                    FromParser aFromParser, FromClone aFromClone)
-  : nsGenericHTMLFormElementWithState(aNodeInfo, kInputDefaultType->value)
+  : nsGenericHTMLFormElementWithState(std::move(aNodeInfo), kInputDefaultType->value)
   , mAutocompleteAttrState(nsContentUtils::eAutocompleteAttrState_Unknown)
   , mAutocompleteInfoState(nsContentUtils::eAutocompleteAttrState_Unknown)
   , mDisabledChanged(false)
@@ -1131,8 +1131,8 @@ HTMLInputElement::Clone(dom::NodeInfo* aNodeInfo, nsINode** aResult) const
 {
   *aResult = nullptr;
 
-  already_AddRefed<mozilla::dom::NodeInfo> ni = RefPtr<mozilla::dom::NodeInfo>(aNodeInfo).forget();
-  RefPtr<HTMLInputElement> it = new HTMLInputElement(ni, NOT_FROM_PARSER,
+  RefPtr<HTMLInputElement> it = new HTMLInputElement(do_AddRef(aNodeInfo),
+                                                     NOT_FROM_PARSER,
                                                      FromClone::yes);
 
   nsresult rv = const_cast<HTMLInputElement*>(this)->CopyInnerTo(it);
diff --git a/dom/html/HTMLInputElement.h b/dom/html/HTMLInputElement.h
index 68bcce85e74c5bba463687837d527e5efb4056be..fefd796158ea9ca4a06e354b29be49dd64ab6b7e 100644
--- a/dom/html/HTMLInputElement.h
+++ b/dom/html/HTMLInputElement.h
@@ -137,7 +137,7 @@ public:
 
   enum class FromClone { no, yes };
 
-  HTMLInputElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
+  HTMLInputElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                    mozilla::dom::FromParser aFromParser,
                    FromClone aFromClone = FromClone::no);
 
diff --git a/dom/html/HTMLLIElement.h b/dom/html/HTMLLIElement.h
index d976d13c41abb7440878d413679b54d7840a0058..c5fe56a66750cf7660ce9fff4e9168ef421c96f6 100644
--- a/dom/html/HTMLLIElement.h
+++ b/dom/html/HTMLLIElement.h
@@ -17,8 +17,8 @@ namespace dom {
 class HTMLLIElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLLIElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : nsGenericHTMLElement(aNodeInfo)
+  explicit HTMLLIElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : nsGenericHTMLElement(std::move(aNodeInfo))
   {
   }
 
diff --git a/dom/html/HTMLLabelElement.h b/dom/html/HTMLLabelElement.h
index 01b1e9ba7370e5757cd6eb9fb752f505d6bcb218..18d44bba0214178265113fcd2a481607ecdb9bab 100644
--- a/dom/html/HTMLLabelElement.h
+++ b/dom/html/HTMLLabelElement.h
@@ -20,8 +20,8 @@ namespace dom {
 class HTMLLabelElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLLabelElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : nsGenericHTMLElement(aNodeInfo),
+  explicit HTMLLabelElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : nsGenericHTMLElement(std::move(aNodeInfo)),
       mHandlingEvent(false)
   {
   }
diff --git a/dom/html/HTMLLegendElement.h b/dom/html/HTMLLegendElement.h
index 0a70c1879205b116be6589c870b202bdeb385ef5..3c734899429f216f2203eb26fdba340462bb7545 100644
--- a/dom/html/HTMLLegendElement.h
+++ b/dom/html/HTMLLegendElement.h
@@ -17,8 +17,8 @@ namespace dom {
 class HTMLLegendElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLLegendElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : nsGenericHTMLElement(aNodeInfo)
+  explicit HTMLLegendElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : nsGenericHTMLElement(std::move(aNodeInfo))
   {
   }
 
diff --git a/dom/html/HTMLLinkElement.cpp b/dom/html/HTMLLinkElement.cpp
index 5f02d9a4f4d08096e218b1e8384a09611892bda0..496ae5c748d3401df5ca6dfaeeefe1a7389bc759 100644
--- a/dom/html/HTMLLinkElement.cpp
+++ b/dom/html/HTMLLinkElement.cpp
@@ -58,8 +58,8 @@ NS_IMPL_NS_NEW_HTML_ELEMENT(Link)
 namespace mozilla {
 namespace dom {
 
-HTMLLinkElement::HTMLLinkElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : nsGenericHTMLElement(aNodeInfo)
+HTMLLinkElement::HTMLLinkElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : nsGenericHTMLElement(std::move(aNodeInfo))
   , Link(this)
 {
 }
diff --git a/dom/html/HTMLLinkElement.h b/dom/html/HTMLLinkElement.h
index b33ed39b09dea2501070186138b03545d301e6f6..bba7cb6b2526c5bef8b3e15f8bb23a5279d19e79 100644
--- a/dom/html/HTMLLinkElement.h
+++ b/dom/html/HTMLLinkElement.h
@@ -22,7 +22,7 @@ class HTMLLinkElement final : public nsGenericHTMLElement,
                               public Link
 {
 public:
-  explicit HTMLLinkElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit HTMLLinkElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
diff --git a/dom/html/HTMLMapElement.cpp b/dom/html/HTMLMapElement.cpp
index e19901bf15b6977271750a0748b275a4ba0da9ed..850dc9be18d4c20d0921dce2948da9dc6a02c680 100644
--- a/dom/html/HTMLMapElement.cpp
+++ b/dom/html/HTMLMapElement.cpp
@@ -16,8 +16,8 @@ NS_IMPL_NS_NEW_HTML_ELEMENT(Map)
 namespace mozilla {
 namespace dom {
 
-HTMLMapElement::HTMLMapElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : nsGenericHTMLElement(aNodeInfo)
+HTMLMapElement::HTMLMapElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : nsGenericHTMLElement(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/html/HTMLMapElement.h b/dom/html/HTMLMapElement.h
index 95445bc0729e040d261b272967973ba2dd2d4939..2713dd012c230dabcaedcbe55814041c16472ff0 100644
--- a/dom/html/HTMLMapElement.h
+++ b/dom/html/HTMLMapElement.h
@@ -19,7 +19,7 @@ namespace dom {
 class HTMLMapElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLMapElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit HTMLMapElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp
index 4c784f051e7659b79d343f08d35f27be6357f6d1..83aaead799e8ae132f89cbc1ad614210789fc051 100644
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -3870,8 +3870,8 @@ private:
 NS_IMPL_ISUPPORTS(HTMLMediaElement::ShutdownObserver, nsIObserver)
 
 HTMLMediaElement::HTMLMediaElement(
-  already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : nsGenericHTMLElement(aNodeInfo)
+  already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : nsGenericHTMLElement(std::move(aNodeInfo))
   , mWatchManager(this, OwnerDoc()->AbstractMainThreadFor(TaskCategory::Other))
   , mMainThreadEventTarget(OwnerDoc()->EventTargetFor(TaskCategory::Other))
   , mAbstractMainThread(OwnerDoc()->AbstractMainThreadFor(TaskCategory::Other))
diff --git a/dom/html/HTMLMediaElement.h b/dom/html/HTMLMediaElement.h
index 0923d972b54bc0f8913acc72e7e1fba79d89847c..dbfc61fc5bfaca428f64cdf4249c5e4d44c7346d 100644
--- a/dom/html/HTMLMediaElement.h
+++ b/dom/html/HTMLMediaElement.h
@@ -122,7 +122,7 @@ public:
     return mCORSMode;
   }
 
-  explicit HTMLMediaElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit HTMLMediaElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
   void ReportCanPlayTelemetry();
 
diff --git a/dom/html/HTMLMenuElement.cpp b/dom/html/HTMLMenuElement.cpp
index 6f7e367d32561b8c88d9731c7c7cc0ce536179aa..1344d4f00a48d596bda58429091f0655021683c0 100644
--- a/dom/html/HTMLMenuElement.cpp
+++ b/dom/html/HTMLMenuElement.cpp
@@ -46,8 +46,8 @@ enum SeparatorType
 
 
 
-HTMLMenuElement::HTMLMenuElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : nsGenericHTMLElement(aNodeInfo), mType(MENU_TYPE_TOOLBAR)
+HTMLMenuElement::HTMLMenuElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : nsGenericHTMLElement(std::move(aNodeInfo)), mType(MENU_TYPE_TOOLBAR)
 {
 }
 
diff --git a/dom/html/HTMLMenuElement.h b/dom/html/HTMLMenuElement.h
index f5fb98ee0a8d84c3abac219e7c113f4f107ffd66..35f534e2da13c881685be6aaac771e04069a3a23 100644
--- a/dom/html/HTMLMenuElement.h
+++ b/dom/html/HTMLMenuElement.h
@@ -18,7 +18,7 @@ namespace dom {
 class HTMLMenuElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLMenuElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit HTMLMenuElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
   NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLMenuElement, menu)
 
diff --git a/dom/html/HTMLMenuItemElement.cpp b/dom/html/HTMLMenuItemElement.cpp
index a9ee5470ab5f2e624958da82f693e4acf8f73474..96a7868b1cbd69c2c4f94b5957cac24da3edcb0b 100644
--- a/dom/html/HTMLMenuItemElement.cpp
+++ b/dom/html/HTMLMenuItemElement.cpp
@@ -157,8 +157,8 @@ protected:
 
 
 HTMLMenuItemElement::HTMLMenuItemElement(
-  already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo, FromParser aFromParser)
-  : nsGenericHTMLElement(aNodeInfo),
+  already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo, FromParser aFromParser)
+  : nsGenericHTMLElement(std::move(aNodeInfo)),
     mType(kMenuItemDefaultType->value),
     mParserCreating(false),
     mShouldInitChecked(false),
@@ -179,9 +179,8 @@ nsresult
 HTMLMenuItemElement::Clone(dom::NodeInfo* aNodeInfo, nsINode** aResult) const
 {
   *aResult = nullptr;
-  already_AddRefed<mozilla::dom::NodeInfo> ni = RefPtr<mozilla::dom::NodeInfo>(aNodeInfo).forget();
   RefPtr<HTMLMenuItemElement> it =
-    new HTMLMenuItemElement(ni, NOT_FROM_PARSER);
+    new HTMLMenuItemElement(do_AddRef(aNodeInfo), NOT_FROM_PARSER);
   nsresult rv = const_cast<HTMLMenuItemElement*>(this)->CopyInnerTo(it);
   if (NS_SUCCEEDED(rv)) {
     switch (mType) {
diff --git a/dom/html/HTMLMenuItemElement.h b/dom/html/HTMLMenuItemElement.h
index fa5e6462821045d83e5a53d339b09ccea5e6cf72..462593c8f97a02bbc76a80711c1a347b34b0f1a2 100644
--- a/dom/html/HTMLMenuItemElement.h
+++ b/dom/html/HTMLMenuItemElement.h
@@ -23,7 +23,7 @@ class HTMLMenuItemElement final : public nsGenericHTMLElement
 public:
   using mozilla::dom::Element::GetText;
 
-  HTMLMenuItemElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
+  HTMLMenuItemElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                       mozilla::dom::FromParser aFromParser);
 
   NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLMenuItemElement, menuitem)
diff --git a/dom/html/HTMLMetaElement.cpp b/dom/html/HTMLMetaElement.cpp
index e28fd8ac2ea0ecf55452b74080a73196052ae661..57751ad77e07f95b589b03c09485ed0630af4c6b 100644
--- a/dom/html/HTMLMetaElement.cpp
+++ b/dom/html/HTMLMetaElement.cpp
@@ -22,8 +22,8 @@ NS_IMPL_NS_NEW_HTML_ELEMENT(Meta)
 namespace mozilla {
 namespace dom {
 
-HTMLMetaElement::HTMLMetaElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : nsGenericHTMLElement(aNodeInfo)
+HTMLMetaElement::HTMLMetaElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : nsGenericHTMLElement(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/html/HTMLMetaElement.h b/dom/html/HTMLMetaElement.h
index 02b3819595b796f1f21cd351049bb81b01766129..9079822bd37598e30dc2219a35e129d5c7546b46 100644
--- a/dom/html/HTMLMetaElement.h
+++ b/dom/html/HTMLMetaElement.h
@@ -16,7 +16,7 @@ namespace dom {
 class HTMLMetaElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLMetaElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit HTMLMetaElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
   // nsISupports
   NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLMetaElement, nsGenericHTMLElement)
diff --git a/dom/html/HTMLMeterElement.cpp b/dom/html/HTMLMeterElement.cpp
index a62c9b844b1b924b07392dc95ed8b13d64ab7fea..5e4ad16f4a36c37e51942cf4095c30a11f7a5c00 100644
--- a/dom/html/HTMLMeterElement.cpp
+++ b/dom/html/HTMLMeterElement.cpp
@@ -18,8 +18,8 @@ const double HTMLMeterElement::kDefaultMin   =  0.0;
 const double HTMLMeterElement::kDefaultMax   =  1.0;
 
 
-HTMLMeterElement::HTMLMeterElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : nsGenericHTMLElement(aNodeInfo)
+HTMLMeterElement::HTMLMeterElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : nsGenericHTMLElement(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/html/HTMLMeterElement.h b/dom/html/HTMLMeterElement.h
index 99e29edaa211a698e02b7a0aa759848042e68814..ef333204d0415b5f628dafe68901698662c852a2 100644
--- a/dom/html/HTMLMeterElement.h
+++ b/dom/html/HTMLMeterElement.h
@@ -20,7 +20,7 @@ namespace dom {
 class HTMLMeterElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLMeterElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit HTMLMeterElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
   virtual EventStates IntrinsicState() const override;
 
diff --git a/dom/html/HTMLModElement.cpp b/dom/html/HTMLModElement.cpp
index 18a3d54640f409edb099f6586596971a73a61939..1c4599892afe679e502d33869adba9411430535f 100644
--- a/dom/html/HTMLModElement.cpp
+++ b/dom/html/HTMLModElement.cpp
@@ -13,8 +13,8 @@ NS_IMPL_NS_NEW_HTML_ELEMENT(Mod)
 namespace mozilla {
 namespace dom {
 
-HTMLModElement::HTMLModElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : nsGenericHTMLElement(aNodeInfo)
+HTMLModElement::HTMLModElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : nsGenericHTMLElement(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/html/HTMLModElement.h b/dom/html/HTMLModElement.h
index 08fdd48bd2f0188d8f63f5268fbb947f891bb9bf..131c63694074d470e4821a93571c44f9060a2e4a 100644
--- a/dom/html/HTMLModElement.h
+++ b/dom/html/HTMLModElement.h
@@ -17,7 +17,7 @@ namespace dom {
 class HTMLModElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLModElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit HTMLModElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
   virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
 
diff --git a/dom/html/HTMLObjectElement.cpp b/dom/html/HTMLObjectElement.cpp
index 1d45f60751489cac12bac8e5d46d72d85af412ec..80525e6fb0e20739aa736de22d99434db459c625 100644
--- a/dom/html/HTMLObjectElement.cpp
+++ b/dom/html/HTMLObjectElement.cpp
@@ -27,9 +27,9 @@
 namespace mozilla {
 namespace dom {
 
-HTMLObjectElement::HTMLObjectElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
+HTMLObjectElement::HTMLObjectElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                                      FromParser aFromParser)
-  : nsGenericHTMLFormElement(aNodeInfo, NS_FORM_OBJECT),
+  : nsGenericHTMLFormElement(std::move(aNodeInfo), NS_FORM_OBJECT),
     mIsDoneAddingChildren(!aFromParser)
 {
   RegisterActivityObserver();
diff --git a/dom/html/HTMLObjectElement.h b/dom/html/HTMLObjectElement.h
index d66539a9002930d5404730ccfc0e037c7d50adef..ff3a03bc7cdd1a38c3492cca32af50885d599211 100644
--- a/dom/html/HTMLObjectElement.h
+++ b/dom/html/HTMLObjectElement.h
@@ -22,7 +22,7 @@ class HTMLObjectElement final : public nsGenericHTMLFormElement
                               , public nsIConstraintValidation
 {
 public:
-  explicit HTMLObjectElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
+  explicit HTMLObjectElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                              FromParser aFromParser = NOT_FROM_PARSER);
 
   // nsISupports
diff --git a/dom/html/HTMLOptGroupElement.cpp b/dom/html/HTMLOptGroupElement.cpp
index da0ecf8fdd249e78d8c16f4e9fde236b0985231d..47dac9b6dca8db5c75984e9e7ea2337930934c5c 100644
--- a/dom/html/HTMLOptGroupElement.cpp
+++ b/dom/html/HTMLOptGroupElement.cpp
@@ -25,8 +25,8 @@ namespace dom {
 
 
 
-HTMLOptGroupElement::HTMLOptGroupElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : nsGenericHTMLElement(aNodeInfo)
+HTMLOptGroupElement::HTMLOptGroupElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : nsGenericHTMLElement(std::move(aNodeInfo))
 {
   // We start off enabled
   AddStatesSilently(NS_EVENT_STATE_ENABLED);
diff --git a/dom/html/HTMLOptGroupElement.h b/dom/html/HTMLOptGroupElement.h
index 81765b7f54402a758f81f0fdf4017525960b4843..9516f802529e3d24c8762793580270dda031c86f 100644
--- a/dom/html/HTMLOptGroupElement.h
+++ b/dom/html/HTMLOptGroupElement.h
@@ -17,7 +17,7 @@ namespace dom {
 class HTMLOptGroupElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLOptGroupElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit HTMLOptGroupElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
   NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLOptGroupElement, optgroup)
 
diff --git a/dom/html/HTMLOptionElement.cpp b/dom/html/HTMLOptionElement.cpp
index d811765be512659c06163b93af1311a3e4034571..c7a966da70d0243cd4b3760e40fda9c48db39cf5 100644
--- a/dom/html/HTMLOptionElement.cpp
+++ b/dom/html/HTMLOptionElement.cpp
@@ -32,8 +32,8 @@ NS_IMPL_NS_NEW_HTML_ELEMENT(Option)
 namespace mozilla {
 namespace dom {
 
-HTMLOptionElement::HTMLOptionElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : nsGenericHTMLElement(aNodeInfo),
+HTMLOptionElement::HTMLOptionElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : nsGenericHTMLElement(std::move(aNodeInfo)),
     mSelectedChanged(false),
     mIsSelected(false),
     mIsInSetDefaultSelected(false)
@@ -341,12 +341,12 @@ HTMLOptionElement::Option(const GlobalObject& aGlobal,
     return nullptr;
   }
 
-  already_AddRefed<mozilla::dom::NodeInfo> nodeInfo =
+  RefPtr<mozilla::dom::NodeInfo> nodeInfo =
     doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::option, nullptr,
                                         kNameSpaceID_XHTML,
                                         ELEMENT_NODE);
 
-  RefPtr<HTMLOptionElement> option = new HTMLOptionElement(nodeInfo);
+  RefPtr<HTMLOptionElement> option = new HTMLOptionElement(nodeInfo.forget());
 
   if (!aText.IsEmpty()) {
     // Create a new text node and append it to the option
diff --git a/dom/html/HTMLOptionElement.h b/dom/html/HTMLOptionElement.h
index a1946d31522fa573e13eba6a06a27eae06b4d448..cf40178ab21c43034ed4e30577d05f1f8450f97c 100644
--- a/dom/html/HTMLOptionElement.h
+++ b/dom/html/HTMLOptionElement.h
@@ -19,7 +19,7 @@ class HTMLSelectElement;
 class HTMLOptionElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLOptionElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit HTMLOptionElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
   static already_AddRefed<HTMLOptionElement>
     Option(const GlobalObject& aGlobal,
diff --git a/dom/html/HTMLOutputElement.cpp b/dom/html/HTMLOutputElement.cpp
index e38394fb6e42496c2c42589124e5f600bdf280fa..75a69230da132f53618fd188943407ea1a4f081f 100644
--- a/dom/html/HTMLOutputElement.cpp
+++ b/dom/html/HTMLOutputElement.cpp
@@ -19,9 +19,9 @@ NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Output)
 namespace mozilla {
 namespace dom {
 
-HTMLOutputElement::HTMLOutputElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
+HTMLOutputElement::HTMLOutputElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                                      FromParser aFromParser)
-  : nsGenericHTMLFormElement(aNodeInfo, NS_FORM_OUTPUT)
+  : nsGenericHTMLFormElement(std::move(aNodeInfo), NS_FORM_OUTPUT)
   , mValueModeFlag(eModeDefault)
   , mIsDoneAddingChildren(!aFromParser)
 {
diff --git a/dom/html/HTMLOutputElement.h b/dom/html/HTMLOutputElement.h
index 3483b69850fa66fb268f7c6679ee7113c794dafd..ef377c43548bc15d39a27ca0b1489b4bdd88f5f7 100644
--- a/dom/html/HTMLOutputElement.h
+++ b/dom/html/HTMLOutputElement.h
@@ -24,7 +24,7 @@ class HTMLOutputElement final : public nsGenericHTMLFormElement,
 public:
   using nsIConstraintValidation::GetValidationMessage;
 
-  explicit HTMLOutputElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
+  explicit HTMLOutputElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                              FromParser aFromParser = NOT_FROM_PARSER);
 
   // nsISupports
diff --git a/dom/html/HTMLParagraphElement.h b/dom/html/HTMLParagraphElement.h
index 7f9cc9d4f78d733fe62796ab599c1a8514e8b575..590cde264772ff8a8f97fd7b899400ff70f296a7 100644
--- a/dom/html/HTMLParagraphElement.h
+++ b/dom/html/HTMLParagraphElement.h
@@ -17,8 +17,8 @@ namespace dom {
 class HTMLParagraphElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLParagraphElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : nsGenericHTMLElement(aNodeInfo)
+  explicit HTMLParagraphElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : nsGenericHTMLElement(std::move(aNodeInfo))
   {
   }
 
diff --git a/dom/html/HTMLPictureElement.cpp b/dom/html/HTMLPictureElement.cpp
index e702ddf227fe394e3c3a3d115261a05b7be32113..410a6602d6505a4bd4ab44a4bd6d2273f151b579 100644
--- a/dom/html/HTMLPictureElement.cpp
+++ b/dom/html/HTMLPictureElement.cpp
@@ -13,14 +13,14 @@ nsGenericHTMLElement*
 NS_NewHTMLPictureElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                          mozilla::dom::FromParser aFromParser)
 {
-  return new mozilla::dom::HTMLPictureElement(aNodeInfo);
+  return new mozilla::dom::HTMLPictureElement(std::move(aNodeInfo));
 }
 
 namespace mozilla {
 namespace dom {
 
-HTMLPictureElement::HTMLPictureElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : nsGenericHTMLElement(aNodeInfo)
+HTMLPictureElement::HTMLPictureElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : nsGenericHTMLElement(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/html/HTMLPictureElement.h b/dom/html/HTMLPictureElement.h
index 140b525f06c733a02e360aa898418199b9075a5e..a0eaea554fd08aba7d3bfbe57b88ec5f980d43d3 100644
--- a/dom/html/HTMLPictureElement.h
+++ b/dom/html/HTMLPictureElement.h
@@ -16,7 +16,7 @@ namespace dom {
 class HTMLPictureElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLPictureElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit HTMLPictureElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
   // nsISupports
   NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLPictureElement, nsGenericHTMLElement)
diff --git a/dom/html/HTMLPreElement.h b/dom/html/HTMLPreElement.h
index 21b9ba34a2b0abf7d5cf21621434caf9945f4e01..c3b808e6d35da668a7759a08357248d5c5d6a4b9 100644
--- a/dom/html/HTMLPreElement.h
+++ b/dom/html/HTMLPreElement.h
@@ -17,8 +17,8 @@ namespace dom {
 class HTMLPreElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLPreElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : nsGenericHTMLElement(aNodeInfo)
+  explicit HTMLPreElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : nsGenericHTMLElement(std::move(aNodeInfo))
   {
   }
 
diff --git a/dom/html/HTMLProgressElement.cpp b/dom/html/HTMLProgressElement.cpp
index d76672c4de1ceaf296a382a164e0935090d6abf4..2e30be5953caf2b6dc0a416fc7160d065359dc06 100644
--- a/dom/html/HTMLProgressElement.cpp
+++ b/dom/html/HTMLProgressElement.cpp
@@ -18,8 +18,8 @@ const double HTMLProgressElement::kDefaultValue          =  0.0;
 const double HTMLProgressElement::kDefaultMax            =  1.0;
 
 
-HTMLProgressElement::HTMLProgressElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : nsGenericHTMLElement(aNodeInfo)
+HTMLProgressElement::HTMLProgressElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : nsGenericHTMLElement(std::move(aNodeInfo))
 {
   // We start out indeterminate
   AddStatesSilently(NS_EVENT_STATE_INDETERMINATE);
diff --git a/dom/html/HTMLProgressElement.h b/dom/html/HTMLProgressElement.h
index a761b7ef8ea842b97024e54a8984429b6af6165d..bd74ac87c94ff5c96e05b9c2574996826f8d3723 100644
--- a/dom/html/HTMLProgressElement.h
+++ b/dom/html/HTMLProgressElement.h
@@ -19,7 +19,7 @@ namespace dom {
 class HTMLProgressElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLProgressElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit HTMLProgressElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
   EventStates IntrinsicState() const override;
 
diff --git a/dom/html/HTMLScriptElement.cpp b/dom/html/HTMLScriptElement.cpp
index 607dc97e43acf986925a5f1a8c53d731f99a56e5..f9dfd5358a17cd645deca574e2902a08decfcafa 100644
--- a/dom/html/HTMLScriptElement.cpp
+++ b/dom/html/HTMLScriptElement.cpp
@@ -35,9 +35,9 @@ HTMLScriptElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
   return HTMLScriptElement_Binding::Wrap(aCx, this, aGivenProto);
 }
 
-HTMLScriptElement::HTMLScriptElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
+HTMLScriptElement::HTMLScriptElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                                      FromParser aFromParser)
-  : nsGenericHTMLElement(aNodeInfo)
+  : nsGenericHTMLElement(std::move(aNodeInfo))
   , ScriptElement(aFromParser)
 {
   AddMutationObserver(this);
@@ -95,8 +95,8 @@ HTMLScriptElement::Clone(dom::NodeInfo* aNodeInfo, nsINode** aResult) const
 {
   *aResult = nullptr;
 
-  already_AddRefed<mozilla::dom::NodeInfo> ni = RefPtr<mozilla::dom::NodeInfo>(aNodeInfo).forget();
-  HTMLScriptElement* it = new HTMLScriptElement(ni, NOT_FROM_PARSER);
+  HTMLScriptElement* it = new HTMLScriptElement(do_AddRef(aNodeInfo),
+                                                NOT_FROM_PARSER);
 
   nsCOMPtr<nsINode> kungFuDeathGrip = it;
   nsresult rv = const_cast<HTMLScriptElement*>(this)->CopyInnerTo(it);
diff --git a/dom/html/HTMLScriptElement.h b/dom/html/HTMLScriptElement.h
index 88142276dddd3bc9eeb6e9727f72782c4c3dad98..4196d5b40b0fdc45a43ea297895f1eff4300ecb1 100644
--- a/dom/html/HTMLScriptElement.h
+++ b/dom/html/HTMLScriptElement.h
@@ -20,7 +20,7 @@ class HTMLScriptElement final : public nsGenericHTMLElement,
 public:
   using Element::GetText;
 
-  HTMLScriptElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
+  HTMLScriptElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                     FromParser aFromParser);
 
   // nsISupports
diff --git a/dom/html/HTMLSelectElement.cpp b/dom/html/HTMLSelectElement.cpp
index 809dda414b58a9ad135a2b5a5dbb86b9f0e88af7..fcb6bc0677037120abb31ebd5f896f67e057cf1d 100644
--- a/dom/html/HTMLSelectElement.cpp
+++ b/dom/html/HTMLSelectElement.cpp
@@ -113,9 +113,9 @@ SafeOptionListMutation::~SafeOptionListMutation()
 // construction, destruction
 
 
-HTMLSelectElement::HTMLSelectElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
+HTMLSelectElement::HTMLSelectElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                                      FromParser aFromParser)
-  : nsGenericHTMLFormElementWithState(aNodeInfo, NS_FORM_SELECT),
+  : nsGenericHTMLFormElementWithState(std::move(aNodeInfo), NS_FORM_SELECT),
     mOptions(new HTMLOptionsCollection(this)),
     mAutocompleteAttrState(nsContentUtils::eAutocompleteAttrState_Unknown),
     mAutocompleteInfoState(nsContentUtils::eAutocompleteAttrState_Unknown),
diff --git a/dom/html/HTMLSelectElement.h b/dom/html/HTMLSelectElement.h
index 9d5d84309a3e8cb9786aa601af0f030a56f31d8e..f3c656816eb9b936b36abf60e97c72ab0984742f 100644
--- a/dom/html/HTMLSelectElement.h
+++ b/dom/html/HTMLSelectElement.h
@@ -102,7 +102,7 @@ public:
 
   using nsIConstraintValidation::GetValidationMessage;
 
-  explicit HTMLSelectElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
+  explicit HTMLSelectElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                              FromParser aFromParser = NOT_FROM_PARSER);
 
   NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLSelectElement, select)
diff --git a/dom/html/HTMLSharedElement.h b/dom/html/HTMLSharedElement.h
index 2728a0e8af78ba7359c40325273bc6f5979d7024..8bf93c4a3c00283c2736e560b3600829fa71c963 100644
--- a/dom/html/HTMLSharedElement.h
+++ b/dom/html/HTMLSharedElement.h
@@ -20,8 +20,8 @@ namespace dom {
 class HTMLSharedElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLSharedElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : nsGenericHTMLElement(aNodeInfo)
+  explicit HTMLSharedElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : nsGenericHTMLElement(std::move(aNodeInfo))
   {
     if (mNodeInfo->Equals(nsGkAtoms::head) ||
         mNodeInfo->Equals(nsGkAtoms::html)) {
diff --git a/dom/html/HTMLSharedListElement.h b/dom/html/HTMLSharedListElement.h
index 1838b4e46b889fb2e326e77ec5ff88060b3a8bcd..1a5075b64cdef59304cddf23fd1c2ef4fc36076a 100644
--- a/dom/html/HTMLSharedListElement.h
+++ b/dom/html/HTMLSharedListElement.h
@@ -17,8 +17,8 @@ namespace dom {
 class HTMLSharedListElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLSharedListElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : nsGenericHTMLElement(aNodeInfo)
+  explicit HTMLSharedListElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : nsGenericHTMLElement(std::move(aNodeInfo))
   {
   }
 
diff --git a/dom/html/HTMLSlotElement.cpp b/dom/html/HTMLSlotElement.cpp
index 92265bb9d305e6a9d243ef01f7bb7c57f852239c..a973030650c6c8bbe4a0a5dd7e2d66ac65c054d7 100644
--- a/dom/html/HTMLSlotElement.cpp
+++ b/dom/html/HTMLSlotElement.cpp
@@ -16,21 +16,19 @@ nsGenericHTMLElement*
 NS_NewHTMLSlotElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                       mozilla::dom::FromParser aFromParser)
 {
-  RefPtr<mozilla::dom::NodeInfo> nodeInfo(aNodeInfo);
+  RefPtr<mozilla::dom::NodeInfo> nodeInfo(std::move(aNodeInfo));
   if (nsDocument::IsShadowDOMEnabled(nodeInfo->GetDocument())) {
-    already_AddRefed<mozilla::dom::NodeInfo> nodeInfoArg(nodeInfo.forget());
-    return new mozilla::dom::HTMLSlotElement(nodeInfoArg);
+    return new mozilla::dom::HTMLSlotElement(nodeInfo.forget());
   }
 
-  already_AddRefed<mozilla::dom::NodeInfo> nodeInfoArg(nodeInfo.forget());
-  return new mozilla::dom::HTMLUnknownElement(nodeInfoArg);
+  return new mozilla::dom::HTMLUnknownElement(nodeInfo.forget());
 }
 
 namespace mozilla {
 namespace dom {
 
-HTMLSlotElement::HTMLSlotElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : nsGenericHTMLElement(aNodeInfo)
+HTMLSlotElement::HTMLSlotElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : nsGenericHTMLElement(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/html/HTMLSlotElement.h b/dom/html/HTMLSlotElement.h
index c068e116a3ce930ce632954bebc600c063783d09..b373b0ceae099893a88415f457c1375ca689f68a 100644
--- a/dom/html/HTMLSlotElement.h
+++ b/dom/html/HTMLSlotElement.h
@@ -18,7 +18,7 @@ struct AssignedNodesOptions;
 class HTMLSlotElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLSlotElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit HTMLSlotElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLSlotElement, slot)
 
   NS_DECL_ISUPPORTS_INHERITED
diff --git a/dom/html/HTMLSourceElement.cpp b/dom/html/HTMLSourceElement.cpp
index 9700ad10293cc1cee17c12737d949e08420147db..c814dc04fe21e13f45ff0bbd1ed5d03111300674 100644
--- a/dom/html/HTMLSourceElement.cpp
+++ b/dom/html/HTMLSourceElement.cpp
@@ -23,8 +23,8 @@ NS_IMPL_NS_NEW_HTML_ELEMENT(Source)
 namespace mozilla {
 namespace dom {
 
-HTMLSourceElement::HTMLSourceElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : nsGenericHTMLElement(aNodeInfo)
+HTMLSourceElement::HTMLSourceElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : nsGenericHTMLElement(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/html/HTMLSourceElement.h b/dom/html/HTMLSourceElement.h
index 39ff38b0a374d832320ed13911c9fb0b1c76d682..e48318cb2bd8570c394f68c313519479244a228c 100644
--- a/dom/html/HTMLSourceElement.h
+++ b/dom/html/HTMLSourceElement.h
@@ -21,7 +21,7 @@ class MediaList;
 class HTMLSourceElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLSourceElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit HTMLSourceElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
diff --git a/dom/html/HTMLSpanElement.h b/dom/html/HTMLSpanElement.h
index 25758bb51e11f9dae2c268840b2b174fe6ae77e6..6ca81bebed07f3aea05e201e44dd4e3595a59dd3 100644
--- a/dom/html/HTMLSpanElement.h
+++ b/dom/html/HTMLSpanElement.h
@@ -19,8 +19,8 @@ namespace dom {
 class HTMLSpanElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLSpanElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : nsGenericHTMLElement(aNodeInfo)
+  explicit HTMLSpanElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : nsGenericHTMLElement(std::move(aNodeInfo))
   {
   }
 
diff --git a/dom/html/HTMLStyleElement.cpp b/dom/html/HTMLStyleElement.cpp
index 8380441fa554f187a6be3c55f986cec93f4b4915..3253ab0a9d20dd62b29d9e60bb67125086f04d72 100644
--- a/dom/html/HTMLStyleElement.cpp
+++ b/dom/html/HTMLStyleElement.cpp
@@ -18,8 +18,8 @@ NS_IMPL_NS_NEW_HTML_ELEMENT(Style)
 namespace mozilla {
 namespace dom {
 
-HTMLStyleElement::HTMLStyleElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : nsGenericHTMLElement(aNodeInfo)
+HTMLStyleElement::HTMLStyleElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : nsGenericHTMLElement(std::move(aNodeInfo))
 {
   AddMutationObserver(this);
 }
diff --git a/dom/html/HTMLStyleElement.h b/dom/html/HTMLStyleElement.h
index fa3263890c3067f84554a6831dd890b782c058c0..3f298e763618ed29c79896c4b628d35094986dac 100644
--- a/dom/html/HTMLStyleElement.h
+++ b/dom/html/HTMLStyleElement.h
@@ -22,7 +22,7 @@ class HTMLStyleElement final : public nsGenericHTMLElement,
                                public nsStubMutationObserver
 {
 public:
-  explicit HTMLStyleElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit HTMLStyleElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
diff --git a/dom/html/HTMLSummaryElement.h b/dom/html/HTMLSummaryElement.h
index c29b5c4fb80a8e5a324f93c8862c48e9c5b4c50b..1c8f52fb8e170dda233cb442dea30264bb8ec97f 100644
--- a/dom/html/HTMLSummaryElement.h
+++ b/dom/html/HTMLSummaryElement.h
@@ -23,8 +23,8 @@ class HTMLSummaryElement final : public nsGenericHTMLElement
 public:
   using NodeInfo = mozilla::dom::NodeInfo;
 
-  explicit HTMLSummaryElement(already_AddRefed<NodeInfo>& aNodeInfo)
-    : nsGenericHTMLElement(aNodeInfo)
+  explicit HTMLSummaryElement(already_AddRefed<NodeInfo>&& aNodeInfo)
+    : nsGenericHTMLElement(std::move(aNodeInfo))
   {
   }
 
diff --git a/dom/html/HTMLTableCaptionElement.h b/dom/html/HTMLTableCaptionElement.h
index cc3e6b28179360d4a5f7b3ce96531563c385e8bc..9660e1eaa6c74ee2ccccce6d1dac79c20bc33f2c 100644
--- a/dom/html/HTMLTableCaptionElement.h
+++ b/dom/html/HTMLTableCaptionElement.h
@@ -15,8 +15,8 @@ namespace dom {
 class HTMLTableCaptionElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLTableCaptionElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : nsGenericHTMLElement(aNodeInfo)
+  explicit HTMLTableCaptionElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : nsGenericHTMLElement(std::move(aNodeInfo))
   {
     SetHasWeirdParserInsertionMode();
   }
diff --git a/dom/html/HTMLTableCellElement.h b/dom/html/HTMLTableCellElement.h
index 718db82f97b7cebd3b574bc21114655a458d2da1..45c344261ed7059b9d9b1f519a3620ca8b4ee02e 100644
--- a/dom/html/HTMLTableCellElement.h
+++ b/dom/html/HTMLTableCellElement.h
@@ -17,8 +17,8 @@ class HTMLTableElement;
 class HTMLTableCellElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLTableCellElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : nsGenericHTMLElement(aNodeInfo)
+  explicit HTMLTableCellElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : nsGenericHTMLElement(std::move(aNodeInfo))
   {
     SetHasWeirdParserInsertionMode();
   }
diff --git a/dom/html/HTMLTableColElement.h b/dom/html/HTMLTableColElement.h
index c93ffe01e63c23a49240856342ab29f0df03bee6..08a9c31b7d2aa7943c198afae0207d1371834be3 100644
--- a/dom/html/HTMLTableColElement.h
+++ b/dom/html/HTMLTableColElement.h
@@ -15,8 +15,8 @@ namespace dom {
 class HTMLTableColElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLTableColElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : nsGenericHTMLElement(aNodeInfo)
+  explicit HTMLTableColElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : nsGenericHTMLElement(std::move(aNodeInfo))
   {
     SetHasWeirdParserInsertionMode();
   }
diff --git a/dom/html/HTMLTableElement.cpp b/dom/html/HTMLTableElement.cpp
index b3fce80a10e07fb6389dd231fcfffb10b474b403..5950291b898712d99f7a548ed783dfc497de1f80 100644
--- a/dom/html/HTMLTableElement.cpp
+++ b/dom/html/HTMLTableElement.cpp
@@ -539,8 +539,8 @@ TableRowsCollection::NodeWillBeDestroyed(const nsINode* aNode)
 
 /* --------------------------- HTMLTableElement ---------------------------- */
 
-HTMLTableElement::HTMLTableElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : nsGenericHTMLElement(aNodeInfo),
+HTMLTableElement::HTMLTableElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : nsGenericHTMLElement(std::move(aNodeInfo)),
     mTableInheritedAttributes(nullptr)
 {
   SetHasWeirdParserInsertionMode();
diff --git a/dom/html/HTMLTableElement.h b/dom/html/HTMLTableElement.h
index 5f569140f630a275a840437da056292874179090..26cd8180a5dfe098bbe8b2ff6ccdffcc807d7931 100644
--- a/dom/html/HTMLTableElement.h
+++ b/dom/html/HTMLTableElement.h
@@ -19,7 +19,7 @@ class TableRowsCollection;
 class HTMLTableElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLTableElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit HTMLTableElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
   NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLTableElement, table)
 
diff --git a/dom/html/HTMLTableRowElement.h b/dom/html/HTMLTableRowElement.h
index 722e4fcc21e4f6ef61742b95f888755299d1e8aa..ac8068fe5e2aa3309fd686ee57df21d9bf3e2aa9 100644
--- a/dom/html/HTMLTableRowElement.h
+++ b/dom/html/HTMLTableRowElement.h
@@ -19,8 +19,8 @@ class HTMLTableSectionElement;
 class HTMLTableRowElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLTableRowElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : nsGenericHTMLElement(aNodeInfo)
+  explicit HTMLTableRowElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : nsGenericHTMLElement(std::move(aNodeInfo))
   {
     SetHasWeirdParserInsertionMode();
   }
diff --git a/dom/html/HTMLTableSectionElement.h b/dom/html/HTMLTableSectionElement.h
index 46b642efd74882ac81a54b23f63054bdd44b5bd6..e0d1e12d080dd605938f4e88cd335cf21942031b 100644
--- a/dom/html/HTMLTableSectionElement.h
+++ b/dom/html/HTMLTableSectionElement.h
@@ -16,8 +16,8 @@ namespace dom {
 class HTMLTableSectionElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLTableSectionElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : nsGenericHTMLElement(aNodeInfo)
+  explicit HTMLTableSectionElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : nsGenericHTMLElement(std::move(aNodeInfo))
   {
     SetHasWeirdParserInsertionMode();
   }
diff --git a/dom/html/HTMLTemplateElement.cpp b/dom/html/HTMLTemplateElement.cpp
index fc91b0968bf235854051ad2ffc1b11bf209ddd5f..dfc191618ece1afc0c617c876281e2611d72b417 100644
--- a/dom/html/HTMLTemplateElement.cpp
+++ b/dom/html/HTMLTemplateElement.cpp
@@ -17,8 +17,8 @@ NS_IMPL_NS_NEW_HTML_ELEMENT(Template)
 namespace mozilla {
 namespace dom {
 
-HTMLTemplateElement::HTMLTemplateElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : nsGenericHTMLElement(aNodeInfo)
+HTMLTemplateElement::HTMLTemplateElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : nsGenericHTMLElement(std::move(aNodeInfo))
 {
   SetHasWeirdParserInsertionMode();
 
diff --git a/dom/html/HTMLTemplateElement.h b/dom/html/HTMLTemplateElement.h
index 4b427d49315159ced99fc188b6875cb4385bf175..2a2b3c3fb924cf9b9d1866b11e883f954476b76a 100644
--- a/dom/html/HTMLTemplateElement.h
+++ b/dom/html/HTMLTemplateElement.h
@@ -17,7 +17,7 @@ namespace dom {
 class HTMLTemplateElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLTemplateElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit HTMLTemplateElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
diff --git a/dom/html/HTMLTextAreaElement.cpp b/dom/html/HTMLTextAreaElement.cpp
index 76d07cbb33e8e0bba664c43b9ff41afcce04c39f..0f4f8d503f5021a0083899c036fcc4d3e6f7adbf 100644
--- a/dom/html/HTMLTextAreaElement.cpp
+++ b/dom/html/HTMLTextAreaElement.cpp
@@ -50,9 +50,9 @@ NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(TextArea)
 namespace mozilla {
 namespace dom {
 
-HTMLTextAreaElement::HTMLTextAreaElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
+HTMLTextAreaElement::HTMLTextAreaElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                                          FromParser aFromParser)
-  : nsGenericHTMLFormElementWithState(aNodeInfo, NS_FORM_TEXTAREA),
+  : nsGenericHTMLFormElementWithState(std::move(aNodeInfo), NS_FORM_TEXTAREA),
     mValueChanged(false),
     mLastValueChangeWasInteractive(false),
     mHandlingSelect(false),
@@ -96,9 +96,8 @@ nsresult
 HTMLTextAreaElement::Clone(dom::NodeInfo* aNodeInfo, nsINode** aResult) const
 {
   *aResult = nullptr;
-  already_AddRefed<mozilla::dom::NodeInfo> ni =
-    RefPtr<mozilla::dom::NodeInfo>(aNodeInfo).forget();
-  RefPtr<HTMLTextAreaElement> it = new HTMLTextAreaElement(ni);
+  RefPtr<HTMLTextAreaElement> it =
+    new HTMLTextAreaElement(do_AddRef(aNodeInfo));
 
   nsresult rv = const_cast<HTMLTextAreaElement*>(this)->CopyInnerTo(it);
   NS_ENSURE_SUCCESS(rv, rv);
diff --git a/dom/html/HTMLTextAreaElement.h b/dom/html/HTMLTextAreaElement.h
index 6df0df373b89079a882148a396957d8359355e9a..008d9b57f1b08fa9fd11fdedd0b859218475befe 100644
--- a/dom/html/HTMLTextAreaElement.h
+++ b/dom/html/HTMLTextAreaElement.h
@@ -44,7 +44,7 @@ class HTMLTextAreaElement final : public nsGenericHTMLFormElementWithState,
 public:
   using nsIConstraintValidation::GetValidationMessage;
 
-  explicit HTMLTextAreaElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
+  explicit HTMLTextAreaElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                                FromParser aFromParser = NOT_FROM_PARSER);
 
   // nsISupports
diff --git a/dom/html/HTMLTimeElement.cpp b/dom/html/HTMLTimeElement.cpp
index faeb02b5410ee6f6e1231f564ad59464d7d0dd35..7b3ba5eeb6f366c3c32a93c4dcb32e695db91626 100644
--- a/dom/html/HTMLTimeElement.cpp
+++ b/dom/html/HTMLTimeElement.cpp
@@ -15,8 +15,8 @@ NS_IMPL_NS_NEW_HTML_ELEMENT(Time)
 namespace mozilla {
 namespace dom {
 
-HTMLTimeElement::HTMLTimeElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : nsGenericHTMLElement(aNodeInfo)
+HTMLTimeElement::HTMLTimeElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : nsGenericHTMLElement(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/html/HTMLTimeElement.h b/dom/html/HTMLTimeElement.h
index 00e2e3c01e1545bafa2a27e75b3505b74f62352a..ed175cb3e1a0db66893d9dcaf1c92c0c3ac18b6b 100644
--- a/dom/html/HTMLTimeElement.h
+++ b/dom/html/HTMLTimeElement.h
@@ -17,7 +17,7 @@ namespace dom {
 class HTMLTimeElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLTimeElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit HTMLTimeElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   virtual ~HTMLTimeElement();
 
   // HTMLTimeElement WebIDL
diff --git a/dom/html/HTMLTitleElement.cpp b/dom/html/HTMLTitleElement.cpp
index db7695517968361c79ac11fb9eeb4380da53ff98..55631d1bfe665c369cb7929505b7bbc9ed88f7f5 100644
--- a/dom/html/HTMLTitleElement.cpp
+++ b/dom/html/HTMLTitleElement.cpp
@@ -18,8 +18,8 @@ NS_IMPL_NS_NEW_HTML_ELEMENT(Title)
 namespace mozilla {
 namespace dom {
 
-HTMLTitleElement::HTMLTitleElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : nsGenericHTMLElement(aNodeInfo)
+HTMLTitleElement::HTMLTitleElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : nsGenericHTMLElement(std::move(aNodeInfo))
 {
   AddMutationObserver(this);
 }
diff --git a/dom/html/HTMLTitleElement.h b/dom/html/HTMLTitleElement.h
index f8f4dc63298795c1d9af27fca96ded473c3e34f7..239461c992e205eb9199a2900067562ca30b4be8 100644
--- a/dom/html/HTMLTitleElement.h
+++ b/dom/html/HTMLTitleElement.h
@@ -22,7 +22,7 @@ class HTMLTitleElement final : public nsGenericHTMLElement,
 public:
   using Element::GetText;
 
-  explicit HTMLTitleElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit HTMLTitleElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
diff --git a/dom/html/HTMLTrackElement.cpp b/dom/html/HTMLTrackElement.cpp
index 9da8ceeaeb92ae5ac7b4f4732236ce529c342ce1..7609636820d457c4188d2252bd6370293a3db7a8 100644
--- a/dom/html/HTMLTrackElement.cpp
+++ b/dom/html/HTMLTrackElement.cpp
@@ -47,7 +47,7 @@ nsGenericHTMLElement*
 NS_NewHTMLTrackElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                        mozilla::dom::FromParser aFromParser)
 {
-  return new mozilla::dom::HTMLTrackElement(aNodeInfo);
+  return new mozilla::dom::HTMLTrackElement(std::move(aNodeInfo));
 }
 
 namespace mozilla {
@@ -120,8 +120,8 @@ private:
 NS_IMPL_ISUPPORTS(WindowDestroyObserver, nsIObserver);
 
 /** HTMLTrackElement */
-HTMLTrackElement::HTMLTrackElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : nsGenericHTMLElement(aNodeInfo)
+HTMLTrackElement::HTMLTrackElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : nsGenericHTMLElement(std::move(aNodeInfo))
   , mLoadResourceDispatched(false)
   , mWindowDestroyObserver(nullptr)
 {
diff --git a/dom/html/HTMLTrackElement.h b/dom/html/HTMLTrackElement.h
index 42dd6b0c447281c77892e1b548505fd85f00d136..30547bad214a1c68c902098154611bf1459b04cb 100644
--- a/dom/html/HTMLTrackElement.h
+++ b/dom/html/HTMLTrackElement.h
@@ -27,7 +27,7 @@ class WindowDestroyObserver;
 class HTMLTrackElement final : public nsGenericHTMLElement
 {
 public:
-  explicit HTMLTrackElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit HTMLTrackElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
diff --git a/dom/html/HTMLUnknownElement.h b/dom/html/HTMLUnknownElement.h
index 9923127a5e879a4790290bc3ccbcfe3c78d52672..e3dd3d7d1a9666d54feb589f8391b345f3c285aa 100644
--- a/dom/html/HTMLUnknownElement.h
+++ b/dom/html/HTMLUnknownElement.h
@@ -24,8 +24,8 @@ public:
 
   NS_DECL_ISUPPORTS_INHERITED
 
-  explicit HTMLUnknownElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : nsGenericHTMLElement(aNodeInfo)
+  explicit HTMLUnknownElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : nsGenericHTMLElement(std::move(aNodeInfo))
   {
   }
 
diff --git a/dom/html/HTMLVideoElement.cpp b/dom/html/HTMLVideoElement.cpp
index b8ee27c67f9a5780a4c2a867a3aab1b0d0ef9139..121624881c1798aef8501bf12dc461202b15a492 100644
--- a/dom/html/HTMLVideoElement.cpp
+++ b/dom/html/HTMLVideoElement.cpp
@@ -44,8 +44,8 @@ static bool sVideoStatsEnabled;
 
 NS_IMPL_ELEMENT_CLONE(HTMLVideoElement)
 
-HTMLVideoElement::HTMLVideoElement(already_AddRefed<NodeInfo>& aNodeInfo)
-  : HTMLMediaElement(aNodeInfo)
+HTMLVideoElement::HTMLVideoElement(already_AddRefed<NodeInfo>&& aNodeInfo)
+  : HTMLMediaElement(std::move(aNodeInfo))
   , mIsOrientationLocked(false)
 {
   DecoderDoctorLogger::LogConstruction(this);
diff --git a/dom/html/HTMLVideoElement.h b/dom/html/HTMLVideoElement.h
index 7ae0d6b725e39034e7dd36e0ed51c26ce25aa016..43ec245007b968fee802ab779b7fd4d9bc06dda0 100644
--- a/dom/html/HTMLVideoElement.h
+++ b/dom/html/HTMLVideoElement.h
@@ -25,7 +25,7 @@ class HTMLVideoElement final : public HTMLMediaElement
 public:
   typedef mozilla::dom::NodeInfo NodeInfo;
 
-  explicit HTMLVideoElement(already_AddRefed<NodeInfo>& aNodeInfo);
+  explicit HTMLVideoElement(already_AddRefed<NodeInfo>&& aNodeInfo);
 
   NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLVideoElement, video)
 
diff --git a/dom/html/nsGenericHTMLElement.cpp b/dom/html/nsGenericHTMLElement.cpp
index 3506ec23fa389a30c645cea87762204613231343..c1adb2a223b70c99b35d8ee132f72deeeb9f36ac 100644
--- a/dom/html/nsGenericHTMLElement.cpp
+++ b/dom/html/nsGenericHTMLElement.cpp
@@ -1620,9 +1620,9 @@ nsGenericHTMLElement::TouchEventsEnabled(JSContext* aCx, JSObject* aGlobal)
 
 //----------------------------------------------------------------------
 
-nsGenericHTMLFormElement::nsGenericHTMLFormElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
+nsGenericHTMLFormElement::nsGenericHTMLFormElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                                                    uint8_t aType)
-  : nsGenericHTMLElement(aNodeInfo)
+  : nsGenericHTMLElement(std::move(aNodeInfo))
   , nsIFormControl(aType)
   , mForm(nullptr)
   , mFieldSet(nullptr)
@@ -2700,9 +2700,9 @@ nsGenericHTMLElement::ChangeEditableState(int32_t aChange)
 //----------------------------------------------------------------------
 
 nsGenericHTMLFormElementWithState::nsGenericHTMLFormElementWithState(
-    already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo, uint8_t aType
+    already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo, uint8_t aType
   )
-  : nsGenericHTMLFormElement(aNodeInfo, aType)
+  : nsGenericHTMLFormElement(std::move(aNodeInfo), aType)
 {
   mStateKey.SetIsVoid(true);
 }
@@ -3007,10 +3007,10 @@ nsGenericHTMLElement::SetInnerText(const nsAString& aValue)
         break;
       }
       str.Truncate();
-      already_AddRefed<mozilla::dom::NodeInfo> ni =
+      RefPtr<mozilla::dom::NodeInfo> ni =
         NodeInfo()->NodeInfoManager()->GetNodeInfo(nsGkAtoms::br,
           nullptr, kNameSpaceID_XHTML, ELEMENT_NODE);
-      RefPtr<HTMLBRElement> br = new HTMLBRElement(ni);
+      RefPtr<HTMLBRElement> br = new HTMLBRElement(ni.forget());
       AppendChildTo(br, true);
     } else {
       str.Append(*s);
diff --git a/dom/html/nsGenericHTMLElement.h b/dom/html/nsGenericHTMLElement.h
index aeaf56644da95a1ac5ec88ad9b8af2e23e95a5a4..95a834f9ec640a0a9073bb4886fb2c5d73cf3091 100644
--- a/dom/html/nsGenericHTMLElement.h
+++ b/dom/html/nsGenericHTMLElement.h
@@ -50,8 +50,8 @@ class nsGenericHTMLElement : public nsGenericHTMLElementBase
 public:
   using Element::SetTabIndex;
   using Element::Focus;
-  explicit nsGenericHTMLElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : nsGenericHTMLElementBase(aNodeInfo)
+  explicit nsGenericHTMLElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : nsGenericHTMLElementBase(std::move(aNodeInfo))
   {
     NS_ASSERTION(mNodeInfo->NamespaceID() == kNameSpaceID_XHTML,
                  "Unexpected namespace");
@@ -976,7 +976,7 @@ class nsGenericHTMLFormElement : public nsGenericHTMLElement,
                                  public nsIFormControl
 {
 public:
-  nsGenericHTMLFormElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
+  nsGenericHTMLFormElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                            uint8_t aType);
 
   NS_DECL_ISUPPORTS_INHERITED
@@ -1159,7 +1159,7 @@ protected:
 class nsGenericHTMLFormElementWithState : public nsGenericHTMLFormElement
 {
 public:
-  nsGenericHTMLFormElementWithState(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
+  nsGenericHTMLFormElementWithState(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                                     uint8_t aType);
 
   /**
@@ -1246,7 +1246,7 @@ nsGenericHTMLElement*                                                        \
 NS_NewHTML##_elementName##Element(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo, \
                                   mozilla::dom::FromParser aFromParser)      \
 {                                                                            \
-  return new mozilla::dom::HTML##_elementName##Element(aNodeInfo);           \
+  return new mozilla::dom::HTML##_elementName##Element(std::move(aNodeInfo)); \
 }
 
 #define NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(_elementName)               \
@@ -1254,7 +1254,7 @@ nsGenericHTMLElement*                                                        \
 NS_NewHTML##_elementName##Element(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo, \
                                   mozilla::dom::FromParser aFromParser)      \
 {                                                                            \
-  return new mozilla::dom::HTML##_elementName##Element(aNodeInfo,            \
+  return new mozilla::dom::HTML##_elementName##Element(std::move(aNodeInfo), \
                                                        aFromParser);         \
 }
 
diff --git a/dom/html/nsGenericHTMLFrameElement.h b/dom/html/nsGenericHTMLFrameElement.h
index 241e3983f4205a567b38ca1d8051169132a629e4..5fabc7856c0d04f6686bac78b5a5f155f52ad1d1 100644
--- a/dom/html/nsGenericHTMLFrameElement.h
+++ b/dom/html/nsGenericHTMLFrameElement.h
@@ -36,9 +36,9 @@ class nsGenericHTMLFrameElement : public nsGenericHTMLElement,
                                   public nsIMozBrowserFrame
 {
 public:
-  nsGenericHTMLFrameElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
+  nsGenericHTMLFrameElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                             mozilla::dom::FromParser aFromParser)
-    : nsGenericHTMLElement(aNodeInfo)
+    : nsGenericHTMLElement(std::move(aNodeInfo))
     , nsBrowserElement()
     , mSrcLoadHappened(false)
     , mNetworkCreated(aFromParser == mozilla::dom::FROM_PARSER_NETWORK)
diff --git a/dom/indexedDB/test/test_third_party.html b/dom/indexedDB/test/test_third_party.html
index 22e78baa075033a8f5650e247b3e4aa4689ccb38..047e67c9faf85a8281c5c8b4f25b113458fb7488 100644
--- a/dom/indexedDB/test/test_third_party.html
+++ b/dom/indexedDB/test/test_third_party.html
@@ -62,12 +62,7 @@
         iframe.addEventListener("load", iframeLoaded);
       }
       SpecialPowers.pushPrefEnv({
-        "set": [
-          ["browser.contentblocking.enabled", true],
-          ["browser.contentblocking.ui.enabled", true],
-          ["browser.contentblocking.rejecttrackers.ui.enabled", true],
-          ["network.cookie.cookieBehavior", testData[testIndex].cookieBehavior],
-        ]
+        "set": [["network.cookie.cookieBehavior", testData[testIndex].cookieBehavior]]
       }, () => {
         iframe.src = testData[testIndex].host + iframe1Path;
       });
diff --git a/dom/mathml/nsMathMLElement.cpp b/dom/mathml/nsMathMLElement.cpp
index 5c5afe4a1e2de3815ec36c7765c400941ec8a002..43f71d525293a27b41bf1bc86e99f0b262174281 100644
--- a/dom/mathml/nsMathMLElement.cpp
+++ b/dom/mathml/nsMathMLElement.cpp
@@ -77,14 +77,14 @@ ReportParseErrorNoTag(const nsString& aValue,
 }
 
 nsMathMLElement::nsMathMLElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-: nsMathMLElementBase(aNodeInfo),
+: nsMathMLElementBase(std::move(aNodeInfo)),
   ALLOW_THIS_IN_INITIALIZER_LIST(Link(this)),
   mIncrementScriptLevel(false)
 {
 }
 
 nsMathMLElement::nsMathMLElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
-: nsMathMLElementBase(aNodeInfo),
+ : nsMathMLElementBase(std::move(aNodeInfo)),
   ALLOW_THIS_IN_INITIALIZER_LIST(Link(this)),
   mIncrementScriptLevel(false)
 {
diff --git a/dom/media/webaudio/PannerNode.cpp b/dom/media/webaudio/PannerNode.cpp
index aeac3a0a3465ca00d4a8472cf0b34bd9b9fac0c7..a95b5779ac300e5715fbe6dae144ab16e0229567 100644
--- a/dom/media/webaudio/PannerNode.cpp
+++ b/dom/media/webaudio/PannerNode.cpp
@@ -104,9 +104,9 @@ public:
       return;
     }
     // HRTFDatabaseLoader needs to be fetched on the main thread.
-    already_AddRefed<HRTFDatabaseLoader> loader =
+    RefPtr<HRTFDatabaseLoader> loader =
       HRTFDatabaseLoader::createAndLoadAsynchronouslyIfNecessary(NodeMainThread()->Context()->SampleRate());
-    mHRTFPanner = new HRTFPanner(NodeMainThread()->Context()->SampleRate(), std::move(loader));
+    mHRTFPanner = new HRTFPanner(NodeMainThread()->Context()->SampleRate(), loader.forget());
   }
 
   void SetInt32Parameter(uint32_t aIndex, int32_t aParam) override
diff --git a/dom/serviceworkers/test/test_third_party_iframes.html b/dom/serviceworkers/test/test_third_party_iframes.html
index 828a2719c8aaa305c7a2e8703b9b87400735e5ba..e0ead59a48df85fae7e6398aaa83d57e4ef2ff32 100644
--- a/dom/serviceworkers/test/test_third_party_iframes.html
+++ b/dom/serviceworkers/test/test_third_party_iframes.html
@@ -84,9 +84,6 @@ function runTest(aExpectedResponses) {
 // the given cookie policy.
 function testShouldIntercept(behavior, lifetime, done) {
   SpecialPowers.pushPrefEnv({"set": [
-      ["browser.contentblocking.enabled", true],
-      ["browser.contentblocking.ui.enabled", true],
-      ["browser.contentblocking.rejecttrackers.ui.enabled", true],
       ["network.cookie.cookieBehavior", behavior],
       ["network.cookie.lifetimePolicy", lifetime],
   ]}, function() {
diff --git a/dom/svg/SVGAElement.cpp b/dom/svg/SVGAElement.cpp
index 8e59afa680e21159238564aa8d601d3841603b5a..bf7a47de59a5493a5157fad4b56c4ad90010a9a6 100644
--- a/dom/svg/SVGAElement.cpp
+++ b/dom/svg/SVGAElement.cpp
@@ -59,8 +59,8 @@ NS_IMPL_RELEASE_INHERITED(SVGAElement, SVGAElementBase)
 //----------------------------------------------------------------------
 // Implementation
 
-SVGAElement::SVGAElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGAElementBase(aNodeInfo)
+SVGAElement::SVGAElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGAElementBase(std::move(aNodeInfo))
   , Link(this)
 {
 }
diff --git a/dom/svg/SVGAElement.h b/dom/svg/SVGAElement.h
index 9b9e328e1b7e8c8a0c7ac7ef5cc8f0ac0c421620..f343e8273097b2039130617c6f0cb4ec62f44035 100644
--- a/dom/svg/SVGAElement.h
+++ b/dom/svg/SVGAElement.h
@@ -30,7 +30,7 @@ class SVGAElement final : public SVGAElementBase,
 protected:
   using Element::GetText;
 
-  explicit SVGAElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGAElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   friend nsresult (::NS_NewSVGAElement(nsIContent **aResult,
                                        already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
   virtual JSObject* WrapNode(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
diff --git a/dom/svg/SVGAnimateElement.cpp b/dom/svg/SVGAnimateElement.cpp
index 546bd8b893c74059335dfc9f6dead73451f344de..dd2f0bb295659ff3822003efa85c0573edf816da 100644
--- a/dom/svg/SVGAnimateElement.cpp
+++ b/dom/svg/SVGAnimateElement.cpp
@@ -21,8 +21,8 @@ SVGAnimateElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 //----------------------------------------------------------------------
 // Implementation
 
-SVGAnimateElement::SVGAnimateElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGAnimationElement(aNodeInfo)
+SVGAnimateElement::SVGAnimateElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGAnimationElement(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/svg/SVGAnimateElement.h b/dom/svg/SVGAnimateElement.h
index 7ad042a380a09f09d5777350d5534ca52651c94d..cb864f5a2fee8aaed583e9f69e3fe81ebbb79037 100644
--- a/dom/svg/SVGAnimateElement.h
+++ b/dom/svg/SVGAnimateElement.h
@@ -20,7 +20,7 @@ namespace dom {
 class SVGAnimateElement final : public SVGAnimationElement
 {
 protected:
-  explicit SVGAnimateElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGAnimateElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
   nsSMILAnimationFunction mAnimationFunction;
   friend nsresult
diff --git a/dom/svg/SVGAnimateMotionElement.cpp b/dom/svg/SVGAnimateMotionElement.cpp
index 5f8e43d1e9af954e4f0ebfc2af5f82e6944e10b0..0171c732cfc9c2bd06b11c3b5d3a413cee021af3 100644
--- a/dom/svg/SVGAnimateMotionElement.cpp
+++ b/dom/svg/SVGAnimateMotionElement.cpp
@@ -21,8 +21,8 @@ SVGAnimateMotionElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenPr
 //----------------------------------------------------------------------
 // Implementation
 
-SVGAnimateMotionElement::SVGAnimateMotionElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGAnimationElement(aNodeInfo)
+SVGAnimateMotionElement::SVGAnimateMotionElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGAnimationElement(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/svg/SVGAnimateMotionElement.h b/dom/svg/SVGAnimateMotionElement.h
index ea6485506382694cd9627650f07c104c1e7c95e9..68570374e261c542563bfb074b535041599d50bc 100644
--- a/dom/svg/SVGAnimateMotionElement.h
+++ b/dom/svg/SVGAnimateMotionElement.h
@@ -20,7 +20,7 @@ namespace dom {
 class SVGAnimateMotionElement final : public SVGAnimationElement
 {
 protected:
-  explicit SVGAnimateMotionElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGAnimateMotionElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
   SVGMotionSMILAnimationFunction mAnimationFunction;
   friend nsresult
diff --git a/dom/svg/SVGAnimateTransformElement.cpp b/dom/svg/SVGAnimateTransformElement.cpp
index 580f6735279c8a269be0808386224048211f5c89..33d98e8f1f08d1b4430f6044f1e5574a9fdbc1f8 100644
--- a/dom/svg/SVGAnimateTransformElement.cpp
+++ b/dom/svg/SVGAnimateTransformElement.cpp
@@ -21,8 +21,8 @@ SVGAnimateTransformElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGive
 //----------------------------------------------------------------------
 // Implementation
 
-SVGAnimateTransformElement::SVGAnimateTransformElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGAnimationElement(aNodeInfo)
+SVGAnimateTransformElement::SVGAnimateTransformElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGAnimationElement(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/svg/SVGAnimateTransformElement.h b/dom/svg/SVGAnimateTransformElement.h
index 2a855f64b0fc4fd915600468a890bc3f9ca5233f..024677e60578658e38783c12b86d14ed0812aee4 100644
--- a/dom/svg/SVGAnimateTransformElement.h
+++ b/dom/svg/SVGAnimateTransformElement.h
@@ -20,7 +20,7 @@ namespace dom {
 class SVGAnimateTransformElement final : public SVGAnimationElement
 {
 protected:
-  explicit SVGAnimateTransformElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGAnimateTransformElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
   nsSMILAnimationFunction mAnimationFunction;
   friend nsresult
diff --git a/dom/svg/SVGAnimationElement.cpp b/dom/svg/SVGAnimationElement.cpp
index 69a31e4d24b35c7e0ab26c7eb0800064f25467d6..05ab64c6ec684ed26b370caf7451688f8d201647 100644
--- a/dom/svg/SVGAnimationElement.cpp
+++ b/dom/svg/SVGAnimationElement.cpp
@@ -35,8 +35,8 @@ NS_IMPL_CYCLE_COLLECTION_INHERITED(SVGAnimationElement,
 //----------------------------------------------------------------------
 // Implementation
 
-SVGAnimationElement::SVGAnimationElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGAnimationElementBase(aNodeInfo),
+SVGAnimationElement::SVGAnimationElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGAnimationElementBase(std::move(aNodeInfo)),
     mHrefTarget(this)
 {
 }
diff --git a/dom/svg/SVGAnimationElement.h b/dom/svg/SVGAnimationElement.h
index ba142f1b77e64cfc2a5ed3a6006d51e153d6d96c..2e40da02b782a15e05668aff9d9742d13d4cab46 100644
--- a/dom/svg/SVGAnimationElement.h
+++ b/dom/svg/SVGAnimationElement.h
@@ -28,7 +28,7 @@ class SVGAnimationElement : public SVGAnimationElementBase,
                             public SVGTests
 {
 protected:
-  explicit SVGAnimationElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGAnimationElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   nsresult Init();
   virtual ~SVGAnimationElement();
 
diff --git a/dom/svg/SVGCircleElement.cpp b/dom/svg/SVGCircleElement.cpp
index 8d5761081d5d45a5a71f955e34667c2beddf6333..494d8ab46707a4683cbe457daab864491576be72 100644
--- a/dom/svg/SVGCircleElement.cpp
+++ b/dom/svg/SVGCircleElement.cpp
@@ -33,8 +33,8 @@ nsSVGElement::LengthInfo SVGCircleElement::sLengthInfo[3] =
 //----------------------------------------------------------------------
 // Implementation
 
-SVGCircleElement::SVGCircleElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGCircleElementBase(aNodeInfo)
+SVGCircleElement::SVGCircleElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGCircleElementBase(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/svg/SVGCircleElement.h b/dom/svg/SVGCircleElement.h
index 71849e49f14232439f9e30a6cecbe21303ba0c19..7ff8a68311a2877fafe648b5dbf6579e79caeb9d 100644
--- a/dom/svg/SVGCircleElement.h
+++ b/dom/svg/SVGCircleElement.h
@@ -21,7 +21,7 @@ typedef SVGGeometryElement SVGCircleElementBase;
 class SVGCircleElement final : public SVGCircleElementBase
 {
 protected:
-  explicit SVGCircleElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGCircleElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   virtual JSObject* WrapNode(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
   friend nsresult (::NS_NewSVGCircleElement(nsIContent **aResult,
                                             already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
diff --git a/dom/svg/SVGClipPathElement.cpp b/dom/svg/SVGClipPathElement.cpp
index 83adce65077d28c7871c081f1973a498fc9c83fa..7d0d3c05ce0ae2bda268ba8c9aea1d784cdd5846 100644
--- a/dom/svg/SVGClipPathElement.cpp
+++ b/dom/svg/SVGClipPathElement.cpp
@@ -35,8 +35,8 @@ nsSVGElement::EnumInfo SVGClipPathElement::sEnumInfo[1] =
 //----------------------------------------------------------------------
 // Implementation
 
-SVGClipPathElement::SVGClipPathElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGClipPathElementBase(aNodeInfo)
+SVGClipPathElement::SVGClipPathElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGClipPathElementBase(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/svg/SVGClipPathElement.h b/dom/svg/SVGClipPathElement.h
index 5ff6b75a3eca1b888b419fe32b99e6828116a994..175544f0f738a3ddb38adade6be0bdbb34019623 100644
--- a/dom/svg/SVGClipPathElement.h
+++ b/dom/svg/SVGClipPathElement.h
@@ -27,7 +27,7 @@ class SVGClipPathElement final : public SVGClipPathElementBase
 protected:
   friend nsresult (::NS_NewSVGClipPathElement(nsIContent **aResult,
                                               already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
-  explicit SVGClipPathElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGClipPathElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   virtual JSObject* WrapNode(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
 
 public:
diff --git a/dom/svg/SVGComponentTransferFunctionElement.h b/dom/svg/SVGComponentTransferFunctionElement.h
index 7a74d62fa4b0c5c8228d18674020448823201471..e978d3322b1467ce99bb07e90a4aab3a02eb0c2e 100644
--- a/dom/svg/SVGComponentTransferFunctionElement.h
+++ b/dom/svg/SVGComponentTransferFunctionElement.h
@@ -28,8 +28,8 @@ typedef SVGFEUnstyledElement SVGComponentTransferFunctionElementBase;
 class SVGComponentTransferFunctionElement : public SVGComponentTransferFunctionElementBase
 {
 protected:
-  explicit SVGComponentTransferFunctionElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : SVGComponentTransferFunctionElementBase(aNodeInfo)
+  explicit SVGComponentTransferFunctionElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : SVGComponentTransferFunctionElementBase(std::move(aNodeInfo))
   {
   }
 
@@ -95,8 +95,8 @@ class SVGFEFuncRElement : public SVGComponentTransferFunctionElement
   friend nsresult (::NS_NewSVGFEFuncRElement(
     nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
 protected:
-  explicit SVGFEFuncRElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : SVGComponentTransferFunctionElement(aNodeInfo) {}
+  explicit SVGFEFuncRElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : SVGComponentTransferFunctionElement(std::move(aNodeInfo)) {}
 
 public:
   virtual int32_t GetChannel() override { return 0; }
@@ -120,8 +120,8 @@ class SVGFEFuncGElement : public SVGComponentTransferFunctionElement
   friend nsresult (::NS_NewSVGFEFuncGElement(
     nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
 protected:
-  explicit SVGFEFuncGElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : SVGComponentTransferFunctionElement(aNodeInfo) {}
+  explicit SVGFEFuncGElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : SVGComponentTransferFunctionElement(std::move(aNodeInfo)) {}
 
 public:
   virtual int32_t GetChannel() override { return 1; }
@@ -145,8 +145,8 @@ class SVGFEFuncBElement : public SVGComponentTransferFunctionElement
   friend nsresult (::NS_NewSVGFEFuncBElement(
     nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
 protected:
-  explicit SVGFEFuncBElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : SVGComponentTransferFunctionElement(aNodeInfo) {}
+  explicit SVGFEFuncBElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : SVGComponentTransferFunctionElement(std::move(aNodeInfo)) {}
 
 public:
   virtual int32_t GetChannel() override { return 2; }
@@ -170,8 +170,8 @@ class SVGFEFuncAElement : public SVGComponentTransferFunctionElement
   friend nsresult (::NS_NewSVGFEFuncAElement(
     nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
 protected:
-  explicit SVGFEFuncAElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : SVGComponentTransferFunctionElement(aNodeInfo) {}
+  explicit SVGFEFuncAElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : SVGComponentTransferFunctionElement(std::move(aNodeInfo)) {}
 
 public:
   virtual int32_t GetChannel() override { return 3; }
diff --git a/dom/svg/SVGDefsElement.cpp b/dom/svg/SVGDefsElement.cpp
index 76745f00ff7f350501204b895032bd8b04dfbf67..d0445c09dc25d01d51a3f5dce050fa5c81cf36ad 100644
--- a/dom/svg/SVGDefsElement.cpp
+++ b/dom/svg/SVGDefsElement.cpp
@@ -21,8 +21,8 @@ SVGDefsElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 //----------------------------------------------------------------------
 // Implementation
 
-SVGDefsElement::SVGDefsElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGGraphicsElement(aNodeInfo)
+SVGDefsElement::SVGDefsElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGGraphicsElement(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/svg/SVGDefsElement.h b/dom/svg/SVGDefsElement.h
index 382619f4402aff4ea12ea4db42f19391b8db77fc..d44b1be6103f010f5f5d3673e5477ad2e4da826d 100644
--- a/dom/svg/SVGDefsElement.h
+++ b/dom/svg/SVGDefsElement.h
@@ -20,7 +20,7 @@ class SVGDefsElement final : public SVGGraphicsElement
 protected:
   friend nsresult (::NS_NewSVGDefsElement(nsIContent **aResult,
                                           already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
-  explicit SVGDefsElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGDefsElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
 public:
diff --git a/dom/svg/SVGDescElement.cpp b/dom/svg/SVGDescElement.cpp
index 2981482f5d0995c86241e671a4321c862babb119..f2f1391e7b550c7bee73a85285091dfbadd1723a 100644
--- a/dom/svg/SVGDescElement.cpp
+++ b/dom/svg/SVGDescElement.cpp
@@ -21,8 +21,8 @@ SVGDescElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 //----------------------------------------------------------------------
 // Implementation
 
-SVGDescElement::SVGDescElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGDescElementBase(aNodeInfo)
+SVGDescElement::SVGDescElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGDescElementBase(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/svg/SVGDescElement.h b/dom/svg/SVGDescElement.h
index e30c39e691044292cfae0cde9bee2231580d94d1..943063d576725bf96cce4d66f12e2c91055864e5 100644
--- a/dom/svg/SVGDescElement.h
+++ b/dom/svg/SVGDescElement.h
@@ -23,7 +23,7 @@ class SVGDescElement final : public SVGDescElementBase
 protected:
   friend nsresult (::NS_NewSVGDescElement(nsIContent **aResult,
                                           already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
-  explicit SVGDescElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGDescElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
   JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
diff --git a/dom/svg/SVGEllipseElement.cpp b/dom/svg/SVGEllipseElement.cpp
index d64c40704ecc90aba341bce2a051d8cce4183b54..ca3a094af20fc0b36b6557419c2ce528dcaaa019 100644
--- a/dom/svg/SVGEllipseElement.cpp
+++ b/dom/svg/SVGEllipseElement.cpp
@@ -35,8 +35,8 @@ nsSVGElement::LengthInfo SVGEllipseElement::sLengthInfo[4] =
 //----------------------------------------------------------------------
 // Implementation
 
-SVGEllipseElement::SVGEllipseElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGEllipseElementBase(aNodeInfo)
+SVGEllipseElement::SVGEllipseElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGEllipseElementBase(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/svg/SVGEllipseElement.h b/dom/svg/SVGEllipseElement.h
index 15d198c0e263aa42a04e57249788034575065b45..602e7e6748b19baf579c65dc1589c67b4fa80890 100644
--- a/dom/svg/SVGEllipseElement.h
+++ b/dom/svg/SVGEllipseElement.h
@@ -21,7 +21,7 @@ typedef SVGGeometryElement SVGEllipseElementBase;
 class SVGEllipseElement final : public SVGEllipseElementBase
 {
 protected:
-  explicit SVGEllipseElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGEllipseElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   virtual JSObject* WrapNode(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
   friend nsresult (::NS_NewSVGEllipseElement(nsIContent **aResult,
                                              already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
diff --git a/dom/svg/SVGFEBlendElement.h b/dom/svg/SVGFEBlendElement.h
index 801e86a538b90fe5d2a62f0ba9fb274562c3c862..6965852c655523ea3bf0e54ddc92da6307c2b550 100644
--- a/dom/svg/SVGFEBlendElement.h
+++ b/dom/svg/SVGFEBlendElement.h
@@ -22,8 +22,8 @@ class SVGFEBlendElement : public SVGFEBlendElementBase
   friend nsresult (::NS_NewSVGFEBlendElement(nsIContent **aResult,
                                              already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
 protected:
-  explicit SVGFEBlendElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : SVGFEBlendElementBase(aNodeInfo)
+  explicit SVGFEBlendElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : SVGFEBlendElementBase(std::move(aNodeInfo))
   {
   }
   virtual JSObject* WrapNode(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
diff --git a/dom/svg/SVGFEColorMatrixElement.h b/dom/svg/SVGFEColorMatrixElement.h
index ebd42eea002f009801090f77f47782c6c157636b..3ee9448a33dbe536e6cdb0dea3871b9e82237247 100644
--- a/dom/svg/SVGFEColorMatrixElement.h
+++ b/dom/svg/SVGFEColorMatrixElement.h
@@ -24,8 +24,8 @@ class SVGFEColorMatrixElement : public SVGFEColorMatrixElementBase
   friend nsresult (::NS_NewSVGFEColorMatrixElement(nsIContent **aResult,
                                                    already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
 protected:
-  explicit SVGFEColorMatrixElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : SVGFEColorMatrixElementBase(aNodeInfo)
+  explicit SVGFEColorMatrixElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : SVGFEColorMatrixElementBase(std::move(aNodeInfo))
   {
   }
   virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
diff --git a/dom/svg/SVGFEComponentTransferElement.h b/dom/svg/SVGFEComponentTransferElement.h
index 221f0c63fa3820de112bab1994b6ed34fe75cb5a..0a3e7889e3b9c25efcdfe79006ab962bb5629f39 100644
--- a/dom/svg/SVGFEComponentTransferElement.h
+++ b/dom/svg/SVGFEComponentTransferElement.h
@@ -22,8 +22,8 @@ class SVGFEComponentTransferElement : public SVGFEComponentTransferElementBase
   friend nsresult (::NS_NewSVGFEComponentTransferElement(nsIContent **aResult,
                                                          already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
 protected:
-  explicit SVGFEComponentTransferElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : SVGFEComponentTransferElementBase(aNodeInfo)
+  explicit SVGFEComponentTransferElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : SVGFEComponentTransferElementBase(std::move(aNodeInfo))
   {
   }
   virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
diff --git a/dom/svg/SVGFECompositeElement.h b/dom/svg/SVGFECompositeElement.h
index d0419548d0d331fda5af7472addf2c53bfaa0665..343026822b69b116922db9a9b553cf8bc2d43342 100644
--- a/dom/svg/SVGFECompositeElement.h
+++ b/dom/svg/SVGFECompositeElement.h
@@ -24,8 +24,8 @@ class SVGFECompositeElement : public SVGFECompositeElementBase
   friend nsresult (::NS_NewSVGFECompositeElement(nsIContent **aResult,
                                                  already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
 protected:
-  explicit SVGFECompositeElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : SVGFECompositeElementBase(aNodeInfo)
+  explicit SVGFECompositeElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : SVGFECompositeElementBase(std::move(aNodeInfo))
   {
   }
   virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
diff --git a/dom/svg/SVGFEConvolveMatrixElement.h b/dom/svg/SVGFEConvolveMatrixElement.h
index 8ef1f59ee71061c97a1bac100d21aa9810e4ddf1..27da33c96b3bc0b19592d3205b9e7c894d347a65 100644
--- a/dom/svg/SVGFEConvolveMatrixElement.h
+++ b/dom/svg/SVGFEConvolveMatrixElement.h
@@ -32,8 +32,8 @@ class SVGFEConvolveMatrixElement : public SVGFEConvolveMatrixElementBase
   friend nsresult (::NS_NewSVGFEConvolveMatrixElement(nsIContent **aResult,
                                                       already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
 protected:
-  explicit SVGFEConvolveMatrixElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : SVGFEConvolveMatrixElementBase(aNodeInfo)
+  explicit SVGFEConvolveMatrixElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : SVGFEConvolveMatrixElementBase(std::move(aNodeInfo))
   {
   }
   virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
diff --git a/dom/svg/SVGFEDiffuseLightingElement.h b/dom/svg/SVGFEDiffuseLightingElement.h
index b6917eb54fd70db3fe35eeb0a97592cde0ebf7ad..9a6d18887e2611d2aec9e080f5979a0d432bc4cb 100644
--- a/dom/svg/SVGFEDiffuseLightingElement.h
+++ b/dom/svg/SVGFEDiffuseLightingElement.h
@@ -22,8 +22,8 @@ class SVGFEDiffuseLightingElement : public SVGFEDiffuseLightingElementBase
   friend nsresult (::NS_NewSVGFEDiffuseLightingElement(nsIContent **aResult,
                                                        already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
 protected:
-  explicit SVGFEDiffuseLightingElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : SVGFEDiffuseLightingElementBase(aNodeInfo)
+  explicit SVGFEDiffuseLightingElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : SVGFEDiffuseLightingElementBase(std::move(aNodeInfo))
   {
   }
   virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
diff --git a/dom/svg/SVGFEDisplacementMapElement.h b/dom/svg/SVGFEDisplacementMapElement.h
index 86373d1ea89a8459e2b8909d9db8a1530a5e06cd..ac6267475687ebd432fa1a92bfb2addb78a703bd 100644
--- a/dom/svg/SVGFEDisplacementMapElement.h
+++ b/dom/svg/SVGFEDisplacementMapElement.h
@@ -23,8 +23,8 @@ class SVGFEDisplacementMapElement : public SVGFEDisplacementMapElementBase
 protected:
   friend nsresult (::NS_NewSVGFEDisplacementMapElement(nsIContent **aResult,
                                                        already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
-  explicit SVGFEDisplacementMapElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : SVGFEDisplacementMapElementBase(aNodeInfo)
+  explicit SVGFEDisplacementMapElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : SVGFEDisplacementMapElementBase(std::move(aNodeInfo))
   {
   }
   virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
diff --git a/dom/svg/SVGFEDistantLightElement.h b/dom/svg/SVGFEDistantLightElement.h
index 605970b3a024e20313f7fa515cfb813380066935..d8c23c146b2a78e604e28b57fe1369a199941a35 100644
--- a/dom/svg/SVGFEDistantLightElement.h
+++ b/dom/svg/SVGFEDistantLightElement.h
@@ -23,8 +23,8 @@ class SVGFEDistantLightElement : public SVGFEDistantLightElementBase
   friend nsresult (::NS_NewSVGFEDistantLightElement(nsIContent **aResult,
                                                     already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
 protected:
-  explicit SVGFEDistantLightElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : SVGFEDistantLightElementBase(aNodeInfo)
+  explicit SVGFEDistantLightElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : SVGFEDistantLightElementBase(std::move(aNodeInfo))
   {
   }
   virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
diff --git a/dom/svg/SVGFEDropShadowElement.h b/dom/svg/SVGFEDropShadowElement.h
index 5169abf278d18443f0da3c432b089cf99193d988..9d33602f6601a765dd09c9b63ae6730f797eb683 100644
--- a/dom/svg/SVGFEDropShadowElement.h
+++ b/dom/svg/SVGFEDropShadowElement.h
@@ -25,8 +25,8 @@ class SVGFEDropShadowElement : public SVGFEDropShadowElementBase
   friend nsresult (::NS_NewSVGFEDropShadowElement(nsIContent **aResult,
                                                   already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
 protected:
-  explicit SVGFEDropShadowElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : SVGFEDropShadowElementBase(aNodeInfo)
+  explicit SVGFEDropShadowElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : SVGFEDropShadowElementBase(std::move(aNodeInfo))
   {
   }
   virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
diff --git a/dom/svg/SVGFEFloodElement.h b/dom/svg/SVGFEFloodElement.h
index d814d5b1c4b2dfb024763c92bce257f22752d85f..433da378350a9488be595892ddfdf1ed6045134a 100644
--- a/dom/svg/SVGFEFloodElement.h
+++ b/dom/svg/SVGFEFloodElement.h
@@ -22,8 +22,8 @@ class SVGFEFloodElement : public SVGFEFloodElementBase
   friend nsresult (::NS_NewSVGFEFloodElement(nsIContent **aResult,
                                              already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
 protected:
-  explicit SVGFEFloodElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : SVGFEFloodElementBase(aNodeInfo)
+  explicit SVGFEFloodElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : SVGFEFloodElementBase(std::move(aNodeInfo))
   {
   }
   virtual JSObject* WrapNode(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
diff --git a/dom/svg/SVGFEGaussianBlurElement.h b/dom/svg/SVGFEGaussianBlurElement.h
index 40de3faea03cff6d922755250bd25172502ff5e7..057b433a237d1e153ab53c0e0eaa5ed460dcb46a 100644
--- a/dom/svg/SVGFEGaussianBlurElement.h
+++ b/dom/svg/SVGFEGaussianBlurElement.h
@@ -24,8 +24,8 @@ class SVGFEGaussianBlurElement : public SVGFEGaussianBlurElementBase
   friend nsresult (::NS_NewSVGFEGaussianBlurElement(nsIContent **aResult,
                                                     already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
 protected:
-  explicit SVGFEGaussianBlurElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : SVGFEGaussianBlurElementBase(aNodeInfo)
+  explicit SVGFEGaussianBlurElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : SVGFEGaussianBlurElementBase(std::move(aNodeInfo))
   {
   }
   virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
diff --git a/dom/svg/SVGFEImageElement.cpp b/dom/svg/SVGFEImageElement.cpp
index 0609079a5be961d77a41ae6fedbab322feaecc79..30c9a447d9053e7e6d93596da334f98f746f4d09 100644
--- a/dom/svg/SVGFEImageElement.cpp
+++ b/dom/svg/SVGFEImageElement.cpp
@@ -48,8 +48,8 @@ NS_IMPL_ISUPPORTS_INHERITED(SVGFEImageElement, SVGFEImageElementBase,
 //----------------------------------------------------------------------
 // Implementation
 
-SVGFEImageElement::SVGFEImageElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGFEImageElementBase(aNodeInfo)
+SVGFEImageElement::SVGFEImageElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGFEImageElementBase(std::move(aNodeInfo))
 {
   // We start out broken
   AddStatesSilently(NS_EVENT_STATE_BROKEN);
diff --git a/dom/svg/SVGFEImageElement.h b/dom/svg/SVGFEImageElement.h
index f40097e1eb70f174653068d1eec38b6dc8f446ec..fef7cf4efaa9786c47c80d24fca5996331873c36 100644
--- a/dom/svg/SVGFEImageElement.h
+++ b/dom/svg/SVGFEImageElement.h
@@ -28,7 +28,7 @@ class SVGFEImageElement final : public SVGFEImageElementBase,
 protected:
   friend nsresult (::NS_NewSVGFEImageElement(nsIContent **aResult,
                                              already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
-  explicit SVGFEImageElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGFEImageElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   virtual ~SVGFEImageElement();
   virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
 
diff --git a/dom/svg/SVGFEMergeElement.h b/dom/svg/SVGFEMergeElement.h
index 76b1d6a0ece1c1ffeb9066d59d0a7c0f146fc36c..dcb88a672f4a4bc9f7277a5bcd2148cc94647f18 100644
--- a/dom/svg/SVGFEMergeElement.h
+++ b/dom/svg/SVGFEMergeElement.h
@@ -22,8 +22,8 @@ class SVGFEMergeElement : public SVGFEMergeElementBase
   friend nsresult (::NS_NewSVGFEMergeElement(nsIContent **aResult,
                                              already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
 protected:
-  explicit SVGFEMergeElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : SVGFEMergeElementBase(aNodeInfo)
+  explicit SVGFEMergeElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : SVGFEMergeElementBase(std::move(aNodeInfo))
   {
   }
   virtual JSObject* WrapNode(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
diff --git a/dom/svg/SVGFEMergeNodeElement.h b/dom/svg/SVGFEMergeNodeElement.h
index 02606de55ae9317c89ad697f9051d75c722c44f5..e0da6034b7a12d98b35dcd434ffbad53923b43d9 100644
--- a/dom/svg/SVGFEMergeNodeElement.h
+++ b/dom/svg/SVGFEMergeNodeElement.h
@@ -22,8 +22,8 @@ class SVGFEMergeNodeElement : public SVGFEMergeNodeElementBase
   friend nsresult (::NS_NewSVGFEMergeNodeElement(nsIContent **aResult,
                                                  already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
 protected:
-  explicit SVGFEMergeNodeElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : SVGFEMergeNodeElementBase(aNodeInfo)
+  explicit SVGFEMergeNodeElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : SVGFEMergeNodeElementBase(std::move(aNodeInfo))
   {
   }
   virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
diff --git a/dom/svg/SVGFEMorphologyElement.h b/dom/svg/SVGFEMorphologyElement.h
index e2bfacef9a08f05b1c7d391237bd76670987dd80..0bd1e0bd0d816780af3d7277af5b880636e93af3 100644
--- a/dom/svg/SVGFEMorphologyElement.h
+++ b/dom/svg/SVGFEMorphologyElement.h
@@ -25,8 +25,8 @@ class SVGFEMorphologyElement : public SVGFEMorphologyElementBase
   friend nsresult (::NS_NewSVGFEMorphologyElement(nsIContent **aResult,
                                                   already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
 protected:
-  explicit SVGFEMorphologyElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : SVGFEMorphologyElementBase(aNodeInfo)
+  explicit SVGFEMorphologyElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : SVGFEMorphologyElementBase(std::move(aNodeInfo))
   {
   }
   virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
diff --git a/dom/svg/SVGFEOffsetElement.h b/dom/svg/SVGFEOffsetElement.h
index 4193d0fbb9ab516daec1455508ae55a7f4580a16..1bc8ace8c1766dcdc1f1bad08f71089352400bc6 100644
--- a/dom/svg/SVGFEOffsetElement.h
+++ b/dom/svg/SVGFEOffsetElement.h
@@ -24,8 +24,8 @@ class SVGFEOffsetElement : public SVGFEOffsetElementBase
   friend nsresult (::NS_NewSVGFEOffsetElement(nsIContent **aResult,
                                               already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
 protected:
-  explicit SVGFEOffsetElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : SVGFEOffsetElementBase(aNodeInfo)
+  explicit SVGFEOffsetElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : SVGFEOffsetElementBase(std::move(aNodeInfo))
   {
   }
   virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
diff --git a/dom/svg/SVGFEPointLightElement.h b/dom/svg/SVGFEPointLightElement.h
index 9a657e1e674deba824fb81e6583bc50a15d71dd6..aba4f517f568ddef2bb1872bae6e2734b9dd20a3 100644
--- a/dom/svg/SVGFEPointLightElement.h
+++ b/dom/svg/SVGFEPointLightElement.h
@@ -23,8 +23,8 @@ class SVGFEPointLightElement : public SVGFEPointLightElementBase
   friend nsresult (::NS_NewSVGFEPointLightElement(nsIContent **aResult,
                                                   already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
 protected:
-  explicit SVGFEPointLightElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : SVGFEPointLightElementBase(aNodeInfo)
+  explicit SVGFEPointLightElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : SVGFEPointLightElementBase(std::move(aNodeInfo))
   {
   }
   virtual JSObject* WrapNode(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
diff --git a/dom/svg/SVGFESpecularLightingElement.h b/dom/svg/SVGFESpecularLightingElement.h
index 6edcbac58aa8563b85837e77e87079f2347985f6..30d57dad4e552d826fec117272539fb8647a1097 100644
--- a/dom/svg/SVGFESpecularLightingElement.h
+++ b/dom/svg/SVGFESpecularLightingElement.h
@@ -24,8 +24,8 @@ class SVGFESpecularLightingElement : public SVGFESpecularLightingElementBase
   friend nsresult (::NS_NewSVGFESpecularLightingElement(nsIContent **aResult,
                                                         already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
 protected:
-  explicit SVGFESpecularLightingElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : SVGFESpecularLightingElementBase(aNodeInfo)
+  explicit SVGFESpecularLightingElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : SVGFESpecularLightingElementBase(std::move(aNodeInfo))
   {
   }
   virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
diff --git a/dom/svg/SVGFESpotLightElement.h b/dom/svg/SVGFESpotLightElement.h
index 66882f76644c67b760ba8a7932d8f1ecb536ab45..08650c8e6212c6ae667df2a0373375ee40a108d4 100644
--- a/dom/svg/SVGFESpotLightElement.h
+++ b/dom/svg/SVGFESpotLightElement.h
@@ -24,8 +24,8 @@ class SVGFESpotLightElement : public SVGFESpotLightElementBase
                                                  already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
   friend class ::nsSVGFELightingElement;
 protected:
-  explicit SVGFESpotLightElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : SVGFESpotLightElementBase(aNodeInfo)
+  explicit SVGFESpotLightElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : SVGFESpotLightElementBase(std::move(aNodeInfo))
   {
   }
   virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
diff --git a/dom/svg/SVGFETileElement.h b/dom/svg/SVGFETileElement.h
index af83c7422dc00d7dd48ddca1cf5fbbd2074b543f..0a6243214ac785945c20aa34dfcf6c1df22902f7 100644
--- a/dom/svg/SVGFETileElement.h
+++ b/dom/svg/SVGFETileElement.h
@@ -22,8 +22,8 @@ class SVGFETileElement : public SVGFETileElementBase
   friend nsresult (::NS_NewSVGFETileElement(nsIContent **aResult,
                                             already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
 protected:
-  explicit SVGFETileElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : SVGFETileElementBase(aNodeInfo)
+  explicit SVGFETileElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : SVGFETileElementBase(std::move(aNodeInfo))
   {
   }
   virtual JSObject* WrapNode(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
diff --git a/dom/svg/SVGFETurbulenceElement.h b/dom/svg/SVGFETurbulenceElement.h
index f2af0237a6d2a643057eb5fa62f21eb496add6e6..a2966a3727348394d82e815b5783e4573f243143 100644
--- a/dom/svg/SVGFETurbulenceElement.h
+++ b/dom/svg/SVGFETurbulenceElement.h
@@ -26,8 +26,8 @@ class SVGFETurbulenceElement : public SVGFETurbulenceElementBase
   friend nsresult (::NS_NewSVGFETurbulenceElement(nsIContent **aResult,
                                                   already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
 protected:
-  explicit SVGFETurbulenceElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : SVGFETurbulenceElementBase(aNodeInfo)
+  explicit SVGFETurbulenceElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : SVGFETurbulenceElementBase(std::move(aNodeInfo))
   {
   }
   virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
diff --git a/dom/svg/SVGFilterElement.cpp b/dom/svg/SVGFilterElement.cpp
index fce7b663846caf7025ae132e0cd9dd620431fa46..138227f11fd81dbaa2d8aba5067ac28482583c5a 100644
--- a/dom/svg/SVGFilterElement.cpp
+++ b/dom/svg/SVGFilterElement.cpp
@@ -58,8 +58,8 @@ nsSVGElement::StringInfo SVGFilterElement::sStringInfo[2] =
 //----------------------------------------------------------------------
 // Implementation
 
-SVGFilterElement::SVGFilterElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGFilterElementBase(aNodeInfo)
+SVGFilterElement::SVGFilterElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGFilterElementBase(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/svg/SVGFilterElement.h b/dom/svg/SVGFilterElement.h
index 3e3edadb4bb989e34b27454a261e75085fdaee63..f7da97cf9b2424b6a53742c8c6a9e2c7fe42e306 100644
--- a/dom/svg/SVGFilterElement.h
+++ b/dom/svg/SVGFilterElement.h
@@ -33,7 +33,7 @@ class SVGFilterElement : public SVGFilterElementBase
 protected:
   friend nsresult (::NS_NewSVGFilterElement(nsIContent **aResult,
                                             already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
-  explicit SVGFilterElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGFilterElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   virtual JSObject* WrapNode(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
 
 public:
diff --git a/dom/svg/SVGForeignObjectElement.cpp b/dom/svg/SVGForeignObjectElement.cpp
index 6247852f86028856fbe5c0365b0338ceedcc78de..25e6098ebff33dd280e866d9c9d6082c9bca9d62 100644
--- a/dom/svg/SVGForeignObjectElement.cpp
+++ b/dom/svg/SVGForeignObjectElement.cpp
@@ -34,8 +34,8 @@ nsSVGElement::LengthInfo SVGForeignObjectElement::sLengthInfo[4] =
 //----------------------------------------------------------------------
 // Implementation
 
-SVGForeignObjectElement::SVGForeignObjectElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGGraphicsElement(aNodeInfo)
+SVGForeignObjectElement::SVGForeignObjectElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGGraphicsElement(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/svg/SVGForeignObjectElement.h b/dom/svg/SVGForeignObjectElement.h
index 2da1e213916f095b43d05a108ee7e18a093cff43..e98b2d73e94f9dbdad1bb63f37991c1cc70df1b5 100644
--- a/dom/svg/SVGForeignObjectElement.h
+++ b/dom/svg/SVGForeignObjectElement.h
@@ -25,7 +25,7 @@ class SVGForeignObjectElement final : public SVGGraphicsElement
 protected:
   friend nsresult (::NS_NewSVGForeignObjectElement(nsIContent **aResult,
                                                    already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
-  explicit SVGForeignObjectElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGForeignObjectElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   virtual JSObject* WrapNode(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
 
 public:
diff --git a/dom/svg/SVGGElement.cpp b/dom/svg/SVGGElement.cpp
index 1dfb2b3eaa63f1de79a1384e93825163508743cf..fb85d5cb24719ef14f9ff0239c365c5300f3d75b 100644
--- a/dom/svg/SVGGElement.cpp
+++ b/dom/svg/SVGGElement.cpp
@@ -21,8 +21,8 @@ SVGGElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 //----------------------------------------------------------------------
 // Implementation
 
-SVGGElement::SVGGElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGGraphicsElement(aNodeInfo)
+SVGGElement::SVGGElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGGraphicsElement(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/svg/SVGGElement.h b/dom/svg/SVGGElement.h
index 7332475a3c6b25937e7e051a43245e3f61647178..d026c439204a965ab0fa6013f277fa9f135d213a 100644
--- a/dom/svg/SVGGElement.h
+++ b/dom/svg/SVGGElement.h
@@ -18,7 +18,7 @@ namespace dom {
 class SVGGElement final : public SVGGraphicsElement
 {
 protected:
-  explicit SVGGElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGGElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   JSObject* WrapNode(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
   friend nsresult (::NS_NewSVGGElement(nsIContent **aResult,
                                        already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
diff --git a/dom/svg/SVGGeometryElement.cpp b/dom/svg/SVGGeometryElement.cpp
index 4071002ef100f905da6096a271c5d3a94690f782..a01b50bff204a4035866f92e7dbc9719a00b259e 100644
--- a/dom/svg/SVGGeometryElement.cpp
+++ b/dom/svg/SVGGeometryElement.cpp
@@ -25,8 +25,8 @@ nsSVGElement::NumberInfo SVGGeometryElement::sNumberInfo =
 //----------------------------------------------------------------------
 // Implementation
 
-SVGGeometryElement::SVGGeometryElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGGeometryElementBase(aNodeInfo)
+SVGGeometryElement::SVGGeometryElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGGeometryElementBase(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/svg/SVGGeometryElement.h b/dom/svg/SVGGeometryElement.h
index 54a7ea61412e62c3449a7d30594f4a297f8c8756..7b74af51f0868f09a607b0967e352970bd3c99c6 100644
--- a/dom/svg/SVGGeometryElement.h
+++ b/dom/svg/SVGGeometryElement.h
@@ -49,7 +49,7 @@ protected:
   typedef mozilla::gfx::StrokeOptions StrokeOptions;
 
 public:
-  explicit SVGGeometryElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGGeometryElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
   virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsAtom* aName,
                                 const nsAttrValue* aValue,
diff --git a/dom/svg/SVGGradientElement.cpp b/dom/svg/SVGGradientElement.cpp
index eb961583a6dbdb97b6c829c791795ee4794243e4..eb647e0867abd5da78b2a806887ad236a06c1f64 100644
--- a/dom/svg/SVGGradientElement.cpp
+++ b/dom/svg/SVGGradientElement.cpp
@@ -56,8 +56,8 @@ nsSVGElement::StringInfo SVGGradientElement::sStringInfo[2] =
 //----------------------------------------------------------------------
 // Implementation
 
-SVGGradientElement::SVGGradientElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGGradientElementBase(aNodeInfo)
+SVGGradientElement::SVGGradientElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGGradientElementBase(std::move(aNodeInfo))
 {
 }
 
@@ -141,8 +141,8 @@ nsSVGElement::LengthInfo SVGLinearGradientElement::sLengthInfo[4] =
 //----------------------------------------------------------------------
 // Implementation
 
-SVGLinearGradientElement::SVGLinearGradientElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGLinearGradientElementBase(aNodeInfo)
+SVGLinearGradientElement::SVGLinearGradientElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGLinearGradientElementBase(std::move(aNodeInfo))
 {
 }
 
@@ -217,8 +217,8 @@ nsSVGElement::LengthInfo SVGRadialGradientElement::sLengthInfo[6] =
 //----------------------------------------------------------------------
 // Implementation
 
-SVGRadialGradientElement::SVGRadialGradientElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGRadialGradientElementBase(aNodeInfo)
+SVGRadialGradientElement::SVGRadialGradientElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGRadialGradientElementBase(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/svg/SVGGradientElement.h b/dom/svg/SVGGradientElement.h
index ce7c5b91bfd58e4855b3164805490f1b9f605e36..bed00f43e069281434a1f27eee76883ca5b258d5 100644
--- a/dom/svg/SVGGradientElement.h
+++ b/dom/svg/SVGGradientElement.h
@@ -39,7 +39,7 @@ class SVGGradientElement : public SVGGradientElementBase
   friend class ::nsSVGGradientFrame;
 
 protected:
-  explicit SVGGradientElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGGradientElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override = 0;
 
 public:
@@ -89,7 +89,7 @@ class SVGLinearGradientElement : public SVGLinearGradientElementBase
                                       already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
 
 protected:
-  explicit SVGLinearGradientElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGLinearGradientElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
 public:
@@ -122,7 +122,7 @@ class SVGRadialGradientElement : public SVGRadialGradientElementBase
                                       already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
 
 protected:
-  explicit SVGRadialGradientElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGRadialGradientElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
 public:
diff --git a/dom/svg/SVGGraphicsElement.cpp b/dom/svg/SVGGraphicsElement.cpp
index d4e0fe50b37ca4df3c6b5d53dcdaf995dce87d02..51925cd5351aeaf0030404edcb19374380889a65 100644
--- a/dom/svg/SVGGraphicsElement.cpp
+++ b/dom/svg/SVGGraphicsElement.cpp
@@ -22,8 +22,8 @@ NS_INTERFACE_MAP_END_INHERITING(SVGGraphicsElementBase)
 //----------------------------------------------------------------------
 // Implementation
 
-SVGGraphicsElement::SVGGraphicsElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGGraphicsElementBase(aNodeInfo)
+SVGGraphicsElement::SVGGraphicsElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+: SVGGraphicsElementBase(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/svg/SVGGraphicsElement.h b/dom/svg/SVGGraphicsElement.h
index af06919fbb4633bb80692831b1804fc2ac3328ed..848e22b3d5945851097b035f30bea4c25c78aaeb 100644
--- a/dom/svg/SVGGraphicsElement.h
+++ b/dom/svg/SVGGraphicsElement.h
@@ -19,7 +19,7 @@ class SVGGraphicsElement : public SVGGraphicsElementBase,
                            public SVGTests
 {
 protected:
-  explicit SVGGraphicsElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGGraphicsElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   ~SVGGraphicsElement();
 
 public:
diff --git a/dom/svg/SVGImageElement.cpp b/dom/svg/SVGImageElement.cpp
index 1da6f36ea90c40e4ba23555572db67fc9998ec00..a911c3e096a02bdae09bcfb56dad36aba8cc7e7b 100644
--- a/dom/svg/SVGImageElement.cpp
+++ b/dom/svg/SVGImageElement.cpp
@@ -55,8 +55,8 @@ NS_IMPL_ISUPPORTS_INHERITED(SVGImageElement, SVGImageElementBase,
 //----------------------------------------------------------------------
 // Implementation
 
-SVGImageElement::SVGImageElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGImageElementBase(aNodeInfo)
+SVGImageElement::SVGImageElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGImageElementBase(std::move(aNodeInfo))
 {
   // We start out broken
   AddStatesSilently(NS_EVENT_STATE_BROKEN);
diff --git a/dom/svg/SVGImageElement.h b/dom/svg/SVGImageElement.h
index c2ee0532e314878fa9c2f40e5c2d91395f64bf3c..988327fcafd9cf5b0e08511e6159251e7ffbb6c1 100644
--- a/dom/svg/SVGImageElement.h
+++ b/dom/svg/SVGImageElement.h
@@ -30,7 +30,7 @@ class SVGImageElement : public SVGImageElementBase,
   friend class ::nsSVGImageFrame;
 
 protected:
-  explicit SVGImageElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGImageElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   virtual ~SVGImageElement();
   virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
   friend nsresult (::NS_NewSVGImageElement(nsIContent **aResult,
diff --git a/dom/svg/SVGLineElement.cpp b/dom/svg/SVGLineElement.cpp
index a164cda3c1425acff04e21764f58cab98c1b1244..0b873af759297fda190caab30dd2bb7d6085de6f 100644
--- a/dom/svg/SVGLineElement.cpp
+++ b/dom/svg/SVGLineElement.cpp
@@ -33,8 +33,8 @@ nsSVGElement::LengthInfo SVGLineElement::sLengthInfo[4] =
 //----------------------------------------------------------------------
 // Implementation
 
-SVGLineElement::SVGLineElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGLineElementBase(aNodeInfo)
+SVGLineElement::SVGLineElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGLineElementBase(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/svg/SVGLineElement.h b/dom/svg/SVGLineElement.h
index c1e453443a059a9dcacc126482300ba7476bf748..bc11b4c763fce28b58fa8829f6bf69270ced1446 100644
--- a/dom/svg/SVGLineElement.h
+++ b/dom/svg/SVGLineElement.h
@@ -21,7 +21,7 @@ typedef SVGGeometryElement SVGLineElementBase;
 class SVGLineElement final : public SVGLineElementBase
 {
 protected:
-  explicit SVGLineElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGLineElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   virtual JSObject* WrapNode(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
   friend nsresult (::NS_NewSVGLineElement(nsIContent **aResult,
                                           already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
diff --git a/dom/svg/SVGMPathElement.cpp b/dom/svg/SVGMPathElement.cpp
index 58fe49a5857e3184fb2aea95f18c89331f9a5c8a..79754e4f91d4422ea50d80f9a14d5569e078e751 100644
--- a/dom/svg/SVGMPathElement.cpp
+++ b/dom/svg/SVGMPathElement.cpp
@@ -52,8 +52,8 @@ NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED(SVGMPathElement,
                                              nsIMutationObserver)
 
 // Constructor
-SVGMPathElement::SVGMPathElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGMPathElementBase(aNodeInfo)
+SVGMPathElement::SVGMPathElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGMPathElementBase(std::move(aNodeInfo))
   , mPathTracker(this)
 {
 }
diff --git a/dom/svg/SVGMPathElement.h b/dom/svg/SVGMPathElement.h
index e764fab65a6980fdbc775a6eb2c9e00446128118..bd5daf3bda2def63bd7c02abfb413b01d628e8db 100644
--- a/dom/svg/SVGMPathElement.h
+++ b/dom/svg/SVGMPathElement.h
@@ -27,7 +27,7 @@ class SVGMPathElement final : public SVGMPathElementBase,
 protected:
   friend nsresult (::NS_NewSVGMPathElement(nsIContent **aResult,
                                            already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
-  explicit SVGMPathElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGMPathElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   ~SVGMPathElement();
 
   virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
diff --git a/dom/svg/SVGMarkerElement.cpp b/dom/svg/SVGMarkerElement.cpp
index e1a0bb832477ec0fdd0bc5b8356d242300c4821d..3baf6c8f2e22f65dd5a558574ae52f5209d6bb9a 100644
--- a/dom/svg/SVGMarkerElement.cpp
+++ b/dom/svg/SVGMarkerElement.cpp
@@ -93,8 +93,8 @@ nsSVGOrientType::ToDOMAnimatedEnum(nsSVGElement *aSVGElement)
   return toReturn.forget();
 }
 
-SVGMarkerElement::SVGMarkerElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGMarkerElementBase(aNodeInfo), mCoordCtx(nullptr)
+SVGMarkerElement::SVGMarkerElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGMarkerElementBase(std::move(aNodeInfo)), mCoordCtx(nullptr)
 {
 }
 
diff --git a/dom/svg/SVGMarkerElement.h b/dom/svg/SVGMarkerElement.h
index 4ad3fe5c9831decdd12879425519b94fd1a72af5..5c36702301b36710dad2998d0356140f037f9809 100644
--- a/dom/svg/SVGMarkerElement.h
+++ b/dom/svg/SVGMarkerElement.h
@@ -101,7 +101,7 @@ class SVGMarkerElement : public SVGMarkerElementBase
 protected:
   friend nsresult (::NS_NewSVGMarkerElement(nsIContent **aResult,
                                             already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
-  explicit SVGMarkerElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGMarkerElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   virtual JSObject* WrapNode(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
 
 public:
diff --git a/dom/svg/SVGMaskElement.cpp b/dom/svg/SVGMaskElement.cpp
index 3249cff080cefbb4fb89bc734e82916b80ed26f7..5b4745ff471f746deb0e1e5aa61cd5fb3ee1e359 100644
--- a/dom/svg/SVGMaskElement.cpp
+++ b/dom/svg/SVGMaskElement.cpp
@@ -51,8 +51,8 @@ nsSVGElement::EnumInfo SVGMaskElement::sEnumInfo[2] =
 //----------------------------------------------------------------------
 // Implementation
 
-SVGMaskElement::SVGMaskElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGMaskElementBase(aNodeInfo)
+SVGMaskElement::SVGMaskElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGMaskElementBase(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/svg/SVGMaskElement.h b/dom/svg/SVGMaskElement.h
index 37273dec69de4c30bbe3b76b9142f2ff0b40b3fd..2cd5c99523ef715c1588ae50d5da33359d5a89ba 100644
--- a/dom/svg/SVGMaskElement.h
+++ b/dom/svg/SVGMaskElement.h
@@ -30,7 +30,7 @@ class SVGMaskElement final : public SVGMaskElementBase
 protected:
   friend nsresult (::NS_NewSVGMaskElement(nsIContent **aResult,
                                           already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
-  explicit SVGMaskElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGMaskElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   virtual JSObject* WrapNode(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
 
 public:
diff --git a/dom/svg/SVGMetadataElement.cpp b/dom/svg/SVGMetadataElement.cpp
index c10300ed69540db08c18c64e318fd60cbec4ee0d..86efa4928b06d20b56c65b364dad0bd5b1654380 100644
--- a/dom/svg/SVGMetadataElement.cpp
+++ b/dom/svg/SVGMetadataElement.cpp
@@ -21,8 +21,8 @@ SVGMetadataElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 //----------------------------------------------------------------------
 // Implementation
 
-SVGMetadataElement::SVGMetadataElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGMetadataElementBase(aNodeInfo)
+SVGMetadataElement::SVGMetadataElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGMetadataElementBase(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/svg/SVGMetadataElement.h b/dom/svg/SVGMetadataElement.h
index e059dbb1e9d7a5986d51a3b42c6f43e12d6715e9..3aa62fbd1c7fbb0fec14dfdad622dd27e093ccf4 100644
--- a/dom/svg/SVGMetadataElement.h
+++ b/dom/svg/SVGMetadataElement.h
@@ -23,7 +23,7 @@ class SVGMetadataElement final : public SVGMetadataElementBase
 protected:
   friend nsresult (::NS_NewSVGMetadataElement(nsIContent **aResult,
                                               already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
-  explicit SVGMetadataElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGMetadataElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
   virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
   nsresult Init();
diff --git a/dom/svg/SVGPathElement.cpp b/dom/svg/SVGPathElement.cpp
index 6532090b53e1828711c26d715dbe98d3b216d9f4..9a4ff55b3dd7b394ee2e08bbfda373959a9190b6 100644
--- a/dom/svg/SVGPathElement.cpp
+++ b/dom/svg/SVGPathElement.cpp
@@ -39,8 +39,8 @@ SVGPathElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 //----------------------------------------------------------------------
 // Implementation
 
-SVGPathElement::SVGPathElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGPathElementBase(aNodeInfo)
+SVGPathElement::SVGPathElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGPathElementBase(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/svg/SVGPathElement.h b/dom/svg/SVGPathElement.h
index 9dd09a6aa73ca54a702bc0fe9f2102780b2e109e..7d98fb02a30a46e4f11b01440f625294c9e8fd24 100644
--- a/dom/svg/SVGPathElement.h
+++ b/dom/svg/SVGPathElement.h
@@ -32,7 +32,7 @@ protected:
   friend nsresult (::NS_NewSVGPathElement(nsIContent **aResult,
                                           already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
   virtual JSObject* WrapNode(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
-  explicit SVGPathElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGPathElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
 public:
   NS_DECL_ADDSIZEOFEXCLUDINGTHIS
diff --git a/dom/svg/SVGPatternElement.cpp b/dom/svg/SVGPatternElement.cpp
index 77e07d39ba61b946d43d656754fdf5c3885e9fd5..ee355a2daef81abdc643d8219a2973dc58443f3c 100644
--- a/dom/svg/SVGPatternElement.cpp
+++ b/dom/svg/SVGPatternElement.cpp
@@ -58,8 +58,8 @@ nsSVGElement::StringInfo SVGPatternElement::sStringInfo[2] =
 //----------------------------------------------------------------------
 // Implementation
 
-SVGPatternElement::SVGPatternElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGPatternElementBase(aNodeInfo)
+SVGPatternElement::SVGPatternElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGPatternElementBase(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/svg/SVGPatternElement.h b/dom/svg/SVGPatternElement.h
index af26b8c8e617eb3ad123f6fa338a9f6e62f6cb8c..46a508327497b7f5e58768d53d33f294ff191838 100644
--- a/dom/svg/SVGPatternElement.h
+++ b/dom/svg/SVGPatternElement.h
@@ -34,7 +34,7 @@ class SVGPatternElement final : public SVGPatternElementBase
 protected:
   friend nsresult (::NS_NewSVGPatternElement(nsIContent **aResult,
                                              already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
-  explicit SVGPatternElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGPatternElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   virtual JSObject* WrapNode(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
 
 public:
diff --git a/dom/svg/SVGPolyElement.cpp b/dom/svg/SVGPolyElement.cpp
index 4f90a4cfc859c0f496281aecc9e144a02abaed7e..2f7a109bc603cce4bf8ba39354fc081800ce64b9 100644
--- a/dom/svg/SVGPolyElement.cpp
+++ b/dom/svg/SVGPolyElement.cpp
@@ -15,8 +15,8 @@ using namespace mozilla::gfx;
 //----------------------------------------------------------------------
 // Implementation
 
-SVGPolyElement::SVGPolyElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGPolyElementBase(aNodeInfo)
+SVGPolyElement::SVGPolyElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGPolyElementBase(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/svg/SVGPolyElement.h b/dom/svg/SVGPolyElement.h
index 4b707f4aebbc38526cd810cfdfd9e9156e590220..0cac91e22de1bbf8c7f47ea034a156ae26bcb006 100644
--- a/dom/svg/SVGPolyElement.h
+++ b/dom/svg/SVGPolyElement.h
@@ -21,7 +21,7 @@ typedef SVGGeometryElement SVGPolyElementBase;
 class SVGPolyElement : public SVGPolyElementBase
 {
 protected:
-  explicit SVGPolyElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGPolyElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
   virtual ~SVGPolyElement();
 
diff --git a/dom/svg/SVGPolygonElement.cpp b/dom/svg/SVGPolygonElement.cpp
index 8cc24fcc4f7cc7a8cb8b042e23fc2790972c326c..c1e872d1a99929076ec74a1c38c26129a4fb2e47 100644
--- a/dom/svg/SVGPolygonElement.cpp
+++ b/dom/svg/SVGPolygonElement.cpp
@@ -26,8 +26,8 @@ SVGPolygonElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 //----------------------------------------------------------------------
 // Implementation
 
-SVGPolygonElement::SVGPolygonElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGPolygonElementBase(aNodeInfo)
+SVGPolygonElement::SVGPolygonElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGPolygonElementBase(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/svg/SVGPolygonElement.h b/dom/svg/SVGPolygonElement.h
index 892163cf4acd63bd13493012848936fdb142e611..d433cb6967e8f4ac688709d995134bc46bc45d86 100644
--- a/dom/svg/SVGPolygonElement.h
+++ b/dom/svg/SVGPolygonElement.h
@@ -21,7 +21,7 @@ typedef SVGPolyElement SVGPolygonElementBase;
 class SVGPolygonElement final : public SVGPolygonElementBase
 {
 protected:
-  explicit SVGPolygonElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGPolygonElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   virtual JSObject* WrapNode(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
   friend nsresult (::NS_NewSVGPolygonElement(nsIContent **aResult,
                                              already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
diff --git a/dom/svg/SVGPolylineElement.cpp b/dom/svg/SVGPolylineElement.cpp
index 2e92d9cdb5009abd5800cac94808b301fdfd6fb1..97f8d3d38458d5a613b7974b86eea4423e1f52ad 100644
--- a/dom/svg/SVGPolylineElement.cpp
+++ b/dom/svg/SVGPolylineElement.cpp
@@ -25,8 +25,8 @@ SVGPolylineElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 //----------------------------------------------------------------------
 // Implementation
 
-SVGPolylineElement::SVGPolylineElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGPolylineElementBase(aNodeInfo)
+SVGPolylineElement::SVGPolylineElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGPolylineElementBase(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/svg/SVGPolylineElement.h b/dom/svg/SVGPolylineElement.h
index c32a1aa172075df0b1b190743d8d483bf9e78196..93d882f71694bf9eaa63fbddca3ce8abc5286330 100644
--- a/dom/svg/SVGPolylineElement.h
+++ b/dom/svg/SVGPolylineElement.h
@@ -20,7 +20,7 @@ typedef SVGPolyElement SVGPolylineElementBase;
 class SVGPolylineElement final : public SVGPolylineElementBase
 {
 protected:
-  explicit SVGPolylineElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGPolylineElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   virtual JSObject* WrapNode(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
   friend nsresult (::NS_NewSVGPolylineElement(nsIContent **aResult,
                                               already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
diff --git a/dom/svg/SVGRectElement.cpp b/dom/svg/SVGRectElement.cpp
index acf4ab8d2ea60dddce30abfc6866ae758f25a53b..62f0cd7bedb920a14a5ac35d3ded3d44cab61772 100644
--- a/dom/svg/SVGRectElement.cpp
+++ b/dom/svg/SVGRectElement.cpp
@@ -42,8 +42,8 @@ nsSVGElement::LengthInfo SVGRectElement::sLengthInfo[6] =
 //----------------------------------------------------------------------
 // Implementation
 
-SVGRectElement::SVGRectElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGRectElementBase(aNodeInfo)
+SVGRectElement::SVGRectElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGRectElementBase(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/svg/SVGRectElement.h b/dom/svg/SVGRectElement.h
index 9129f47dd6b362a6c5b0a6daade52fe967fe6306..48162cba9a20fc2129f78fede2dc16de9560d6c4 100644
--- a/dom/svg/SVGRectElement.h
+++ b/dom/svg/SVGRectElement.h
@@ -21,7 +21,7 @@ typedef SVGGeometryElement SVGRectElementBase;
 class SVGRectElement final : public SVGRectElementBase
 {
 protected:
-  explicit SVGRectElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGRectElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   virtual JSObject* WrapNode(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
   friend nsresult (::NS_NewSVGRectElement(nsIContent **aResult,
                                           already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
diff --git a/dom/svg/SVGSVGElement.cpp b/dom/svg/SVGSVGElement.cpp
index 4ffd66331428dc116a504ba29985633f03be78e0..8aa92afba22900167eecf77bee08c3ecea6f0f3e 100644
--- a/dom/svg/SVGSVGElement.cpp
+++ b/dom/svg/SVGSVGElement.cpp
@@ -137,9 +137,9 @@ SVGView::SVGView()
 //----------------------------------------------------------------------
 // Implementation
 
-SVGSVGElement::SVGSVGElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
+SVGSVGElement::SVGSVGElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                              FromParser aFromParser)
-  : SVGSVGElementBase(aNodeInfo),
+  : SVGSVGElementBase(std::move(aNodeInfo)),
     mCurrentTranslate(0.0f, 0.0f),
     mCurrentScale(1.0f),
     mPreviousTranslate(0.0f, 0.0f),
diff --git a/dom/svg/SVGSVGElement.h b/dom/svg/SVGSVGElement.h
index dc8e87de7b6734addfd190fa4922e989a6404f25..0e594ce1c9cb4a2acbe3e65d34e45363b6b458c5 100644
--- a/dom/svg/SVGSVGElement.h
+++ b/dom/svg/SVGSVGElement.h
@@ -78,7 +78,7 @@ class SVGSVGElement final : public SVGSVGElementBase
   friend class mozilla::dom::SVGView;
 
 protected:
-  SVGSVGElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
+  SVGSVGElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                 FromParser aFromParser);
   virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
 
diff --git a/dom/svg/SVGScriptElement.cpp b/dom/svg/SVGScriptElement.cpp
index 3c80d5262be881cd991a14db70fd9747268abab2..f07d7ea43936d678b83e43322c156d119fcfeba5 100644
--- a/dom/svg/SVGScriptElement.cpp
+++ b/dom/svg/SVGScriptElement.cpp
@@ -38,9 +38,9 @@ NS_IMPL_ISUPPORTS_INHERITED(SVGScriptElement, SVGScriptElementBase,
 //----------------------------------------------------------------------
 // Implementation
 
-SVGScriptElement::SVGScriptElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
+SVGScriptElement::SVGScriptElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                                    FromParser aFromParser)
-  : SVGScriptElementBase(aNodeInfo)
+  : SVGScriptElementBase(std::move(aNodeInfo))
   , ScriptElement(aFromParser)
 {
   AddMutationObserver(this);
@@ -58,8 +58,8 @@ SVGScriptElement::Clone(dom::NodeInfo* aNodeInfo, nsINode** aResult) const
 {
   *aResult = nullptr;
 
-  already_AddRefed<mozilla::dom::NodeInfo> ni = RefPtr<mozilla::dom::NodeInfo>(aNodeInfo).forget();
-  SVGScriptElement* it = new SVGScriptElement(ni, NOT_FROM_PARSER);
+  SVGScriptElement* it =
+    new SVGScriptElement(do_AddRef(aNodeInfo), NOT_FROM_PARSER);
 
   nsCOMPtr<nsINode> kungFuDeathGrip = it;
   nsresult rv1 = it->Init();
diff --git a/dom/svg/SVGScriptElement.h b/dom/svg/SVGScriptElement.h
index 1bf154804ec8af7ad6585ee8cbfb06cd7f3eecc6..7a73c3b9b1edfa480fb464410ec1960b760488b3 100644
--- a/dom/svg/SVGScriptElement.h
+++ b/dom/svg/SVGScriptElement.h
@@ -30,7 +30,7 @@ protected:
   friend nsresult (::NS_NewSVGScriptElement(nsIContent **aResult,
                                             already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                                             mozilla::dom::FromParser aFromParser));
-  SVGScriptElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
+  SVGScriptElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                    FromParser aFromParser);
 
   virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
diff --git a/dom/svg/SVGSetElement.cpp b/dom/svg/SVGSetElement.cpp
index 81c6b0e9a8b49ebe34dadb0e39d0c1c1048a9404..c84d83fe656b2e6adf96e0a082af52f3cdb85019 100644
--- a/dom/svg/SVGSetElement.cpp
+++ b/dom/svg/SVGSetElement.cpp
@@ -21,8 +21,8 @@ SVGSetElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 //----------------------------------------------------------------------
 // Implementation
 
-SVGSetElement::SVGSetElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGAnimationElement(aNodeInfo)
+SVGSetElement::SVGSetElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGAnimationElement(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/svg/SVGSetElement.h b/dom/svg/SVGSetElement.h
index 8bf89896b9402bca4656027159d64e5707d579bd..3d07154d8110f310b62cfc9a417f6c19940e83fb 100644
--- a/dom/svg/SVGSetElement.h
+++ b/dom/svg/SVGSetElement.h
@@ -20,7 +20,7 @@ namespace dom {
 class SVGSetElement final : public SVGAnimationElement
 {
 protected:
-  explicit SVGSetElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGSetElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
   nsSMILSetAnimationFunction mAnimationFunction;
 
diff --git a/dom/svg/SVGStopElement.cpp b/dom/svg/SVGStopElement.cpp
index 230b313a35522d58992ee1359507c6ec5a075ed5..23d2523bfebd791d115a11c8385813897b183d27 100644
--- a/dom/svg/SVGStopElement.cpp
+++ b/dom/svg/SVGStopElement.cpp
@@ -24,8 +24,8 @@ nsSVGElement::NumberInfo SVGStopElement::sNumberInfo =
 //----------------------------------------------------------------------
 // Implementation
 
-SVGStopElement::SVGStopElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGStopElementBase(aNodeInfo)
+SVGStopElement::SVGStopElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGStopElementBase(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/svg/SVGStopElement.h b/dom/svg/SVGStopElement.h
index 6f653623f6e3ca484cfb8c05af339452e78b0bcc..595c181bd1bcebb2eb8ec781eac4d6d4685a02b3 100644
--- a/dom/svg/SVGStopElement.h
+++ b/dom/svg/SVGStopElement.h
@@ -23,7 +23,7 @@ class SVGStopElement final : public SVGStopElementBase
 protected:
   friend nsresult (::NS_NewSVGStopElement(nsIContent **aResult,
                                           already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
-  explicit SVGStopElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGStopElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
 
 public:
diff --git a/dom/svg/SVGStyleElement.cpp b/dom/svg/SVGStyleElement.cpp
index d9969ae8871ce7034a260dacac1dd8ee672bb8be..1f451ce481d4eb7b3c7dbf8027cba88b4ca48540 100644
--- a/dom/svg/SVGStyleElement.cpp
+++ b/dom/svg/SVGStyleElement.cpp
@@ -43,8 +43,8 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 //----------------------------------------------------------------------
 // Implementation
 
-SVGStyleElement::SVGStyleElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGStyleElementBase(aNodeInfo)
+SVGStyleElement::SVGStyleElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGStyleElementBase(std::move(aNodeInfo))
 {
   AddMutationObserver(this);
 }
diff --git a/dom/svg/SVGStyleElement.h b/dom/svg/SVGStyleElement.h
index ba1df1e4e32c22dfa6d1f25f492c6fcaf4168430..75616391d3ae8d8eca10b97ce37ddb954e4d119d 100644
--- a/dom/svg/SVGStyleElement.h
+++ b/dom/svg/SVGStyleElement.h
@@ -27,7 +27,7 @@ class SVGStyleElement final : public SVGStyleElementBase,
 protected:
   friend nsresult (::NS_NewSVGStyleElement(nsIContent **aResult,
                                            already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
-  explicit SVGStyleElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGStyleElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   ~SVGStyleElement();
 
   virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
diff --git a/dom/svg/SVGSwitchElement.cpp b/dom/svg/SVGSwitchElement.cpp
index 02e44935651af035c74ac077ad32ac18b42f3f0b..77622e20329259ce508e5850eeea3c38d07f3e77 100644
--- a/dom/svg/SVGSwitchElement.cpp
+++ b/dom/svg/SVGSwitchElement.cpp
@@ -39,8 +39,8 @@ NS_INTERFACE_MAP_END_INHERITING(SVGSwitchElementBase)
 //----------------------------------------------------------------------
 // Implementation
 
-SVGSwitchElement::SVGSwitchElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGSwitchElementBase(aNodeInfo)
+SVGSwitchElement::SVGSwitchElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+: SVGSwitchElementBase(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/svg/SVGSwitchElement.h b/dom/svg/SVGSwitchElement.h
index ced552d011138511c5e7271ea1e23d681453cf6c..ad44e618d8f1af55c14153dae37a86312cec9587 100644
--- a/dom/svg/SVGSwitchElement.h
+++ b/dom/svg/SVGSwitchElement.h
@@ -25,7 +25,7 @@ class SVGSwitchElement final : public SVGSwitchElementBase
 protected:
   friend nsresult (::NS_NewSVGSwitchElement(nsIContent **aResult,
                                             already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
-  explicit SVGSwitchElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGSwitchElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   ~SVGSwitchElement();
   virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
 
diff --git a/dom/svg/SVGSymbolElement.cpp b/dom/svg/SVGSymbolElement.cpp
index c8b316b7b0df96e073bf3318d35f9a14f52c3d88..11951d29985847291b2084eee505bb8f19310802 100644
--- a/dom/svg/SVGSymbolElement.cpp
+++ b/dom/svg/SVGSymbolElement.cpp
@@ -27,8 +27,8 @@ NS_IMPL_ISUPPORTS_INHERITED(SVGSymbolElement, SVGSymbolElementBase,
 //----------------------------------------------------------------------
 // Implementation
 
-SVGSymbolElement::SVGSymbolElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGSymbolElementBase(aNodeInfo)
+SVGSymbolElement::SVGSymbolElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGSymbolElementBase(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/svg/SVGSymbolElement.h b/dom/svg/SVGSymbolElement.h
index 600ab3ec1dbc81495e65e0830269a96a5e3208ec..6ee52ba51050b1b5870766b7643726bceedbb133 100644
--- a/dom/svg/SVGSymbolElement.h
+++ b/dom/svg/SVGSymbolElement.h
@@ -22,7 +22,7 @@ class SVGSymbolElement final : public SVGSymbolElementBase
 protected:
   friend nsresult (::NS_NewSVGSymbolElement(nsIContent **aResult,
                                             already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
-  explicit SVGSymbolElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGSymbolElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   ~SVGSymbolElement();
   virtual JSObject* WrapNode(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
 
diff --git a/dom/svg/SVGTSpanElement.cpp b/dom/svg/SVGTSpanElement.cpp
index d0dbd0ad19a4b67382dc189e707610067e872d25..888d41b4372ca0353860753cc8523668020647fa 100644
--- a/dom/svg/SVGTSpanElement.cpp
+++ b/dom/svg/SVGTSpanElement.cpp
@@ -22,8 +22,8 @@ SVGTSpanElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 //----------------------------------------------------------------------
 // Implementation
 
-SVGTSpanElement::SVGTSpanElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGTSpanElementBase(aNodeInfo)
+SVGTSpanElement::SVGTSpanElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGTSpanElementBase(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/svg/SVGTSpanElement.h b/dom/svg/SVGTSpanElement.h
index e7daf2774946af3fbd9ccbadb460d19bca38f002..a9cbaebd880e03e861a5b615693473958e9cb6c2 100644
--- a/dom/svg/SVGTSpanElement.h
+++ b/dom/svg/SVGTSpanElement.h
@@ -22,7 +22,7 @@ class SVGTSpanElement final : public SVGTSpanElementBase
 protected:
   friend nsresult (::NS_NewSVGTSpanElement(nsIContent **aResult,
                                            already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
-  explicit SVGTSpanElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGTSpanElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   virtual JSObject* WrapNode(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
 
 public:
diff --git a/dom/svg/SVGTextContentElement.h b/dom/svg/SVGTextContentElement.h
index 9eb464ab159a2eed821bf7948a1e5648a2ae3fc1..54619a9908ea214a4d410eeba41f71776bf72e53 100644
--- a/dom/svg/SVGTextContentElement.h
+++ b/dom/svg/SVGTextContentElement.h
@@ -49,8 +49,8 @@ public:
 
 protected:
 
-  explicit SVGTextContentElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : SVGTextContentElementBase(aNodeInfo)
+  explicit SVGTextContentElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : SVGTextContentElementBase(std::move(aNodeInfo))
   {}
 
   MOZ_CAN_RUN_SCRIPT SVGTextFrame* GetSVGTextFrame();
diff --git a/dom/svg/SVGTextElement.cpp b/dom/svg/SVGTextElement.cpp
index c1f1163a809c658e1d1c6dadd31bee38ec6c5eaa..51735bc697c86b0d3b6d0d788ea6d0db5080382e 100644
--- a/dom/svg/SVGTextElement.cpp
+++ b/dom/svg/SVGTextElement.cpp
@@ -21,8 +21,8 @@ SVGTextElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 //----------------------------------------------------------------------
 // Implementation
 
-SVGTextElement::SVGTextElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGTextElementBase(aNodeInfo)
+SVGTextElement::SVGTextElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGTextElementBase(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/svg/SVGTextElement.h b/dom/svg/SVGTextElement.h
index 1d447accd204516891606b80987a00927ac75d98..5cf9fb3ce5676cc768f2bc2c4383543497f2dbe9 100644
--- a/dom/svg/SVGTextElement.h
+++ b/dom/svg/SVGTextElement.h
@@ -20,7 +20,7 @@ typedef SVGTextPositioningElement SVGTextElementBase;
 class SVGTextElement final : public SVGTextElementBase
 {
 protected:
-  explicit SVGTextElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGTextElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   virtual JSObject* WrapNode(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
 
   friend nsresult (::NS_NewSVGTextElement(nsIContent **aResult,
diff --git a/dom/svg/SVGTextPathElement.cpp b/dom/svg/SVGTextPathElement.cpp
index b9147435126779e92272ab1a7787f29aba966874..f734d748ee3c17fbe498b56f5901b4d7ebdcb5bf 100644
--- a/dom/svg/SVGTextPathElement.cpp
+++ b/dom/svg/SVGTextPathElement.cpp
@@ -85,8 +85,8 @@ nsSVGElement::StringInfo SVGTextPathElement::sStringInfo[2] =
 //----------------------------------------------------------------------
 // Implementation
 
-SVGTextPathElement::SVGTextPathElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGTextPathElementBase(aNodeInfo)
+SVGTextPathElement::SVGTextPathElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGTextPathElementBase(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/svg/SVGTextPathElement.h b/dom/svg/SVGTextPathElement.h
index a2ef40678b26758217aee4731575581e7adf49fb..94f305f89b22c46a23fb80cfce45964dac29ceb9 100644
--- a/dom/svg/SVGTextPathElement.h
+++ b/dom/svg/SVGTextPathElement.h
@@ -35,7 +35,7 @@ friend class ::SVGTextFrame;
 protected:
   friend nsresult (::NS_NewSVGTextPathElement(nsIContent **aResult,
                                               already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
-  explicit SVGTextPathElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGTextPathElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   virtual JSObject* WrapNode(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
 
 public:
diff --git a/dom/svg/SVGTextPositioningElement.h b/dom/svg/SVGTextPositioningElement.h
index b58bba84a6fe436e9f7acc19e30c0ffb4754a05a..e2456bba291d41a48cb31a39f343472afbf6e99f 100644
--- a/dom/svg/SVGTextPositioningElement.h
+++ b/dom/svg/SVGTextPositioningElement.h
@@ -31,8 +31,8 @@ public:
 
 protected:
 
-  explicit SVGTextPositioningElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : SVGTextPositioningElementBase(aNodeInfo)
+  explicit SVGTextPositioningElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : SVGTextPositioningElementBase(std::move(aNodeInfo))
   {}
 
   virtual LengthListAttributesInfo GetLengthListInfo() override;
diff --git a/dom/svg/SVGTitleElement.cpp b/dom/svg/SVGTitleElement.cpp
index 5731a811e1650cbc536327f0c288a72eb750f2fc..daba02a0910e0cf8cf2f30c43b4164b45aa3dc7c 100644
--- a/dom/svg/SVGTitleElement.cpp
+++ b/dom/svg/SVGTitleElement.cpp
@@ -27,8 +27,8 @@ NS_IMPL_ISUPPORTS_INHERITED(SVGTitleElement, SVGTitleElementBase,
 //----------------------------------------------------------------------
 // Implementation
 
-SVGTitleElement::SVGTitleElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGTitleElementBase(aNodeInfo)
+SVGTitleElement::SVGTitleElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGTitleElementBase(std::move(aNodeInfo))
 {
   AddMutationObserver(this);
 }
diff --git a/dom/svg/SVGTitleElement.h b/dom/svg/SVGTitleElement.h
index d4df7a177d6f775b3b352f488bba2a5284488576..9b13b4aeab8e903ef49c1385c1e6402e60f54914 100644
--- a/dom/svg/SVGTitleElement.h
+++ b/dom/svg/SVGTitleElement.h
@@ -24,7 +24,7 @@ class SVGTitleElement final : public SVGTitleElementBase,
 protected:
   friend nsresult (::NS_NewSVGTitleElement(nsIContent **aResult,
                                            already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
-  explicit SVGTitleElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGTitleElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   ~SVGTitleElement();
 
   virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
diff --git a/dom/svg/SVGTransformableElement.h b/dom/svg/SVGTransformableElement.h
index 6d71f7eae22ac10562575f4fbc6e8c523e455e82..b82a7df915fb0382bc4d8b8c590018c96f39d92a 100644
--- a/dom/svg/SVGTransformableElement.h
+++ b/dom/svg/SVGTransformableElement.h
@@ -26,8 +26,8 @@ struct SVGBoundingBoxOptions;
 class SVGTransformableElement : public nsSVGElement
 {
 public:
-  explicit SVGTransformableElement(already_AddRefed<dom::NodeInfo>& aNodeInfo)
-    : nsSVGElement(aNodeInfo) {}
+  explicit SVGTransformableElement(already_AddRefed<dom::NodeInfo>&& aNodeInfo)
+    : nsSVGElement(std::move(aNodeInfo)) {}
   virtual ~SVGTransformableElement() {}
 
   virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override = 0;
diff --git a/dom/svg/SVGUseElement.cpp b/dom/svg/SVGUseElement.cpp
index c1d9b2ad6208c11175f1654dbe3325ba676c8e1b..dfcba3e17618011191661c96d9a435c4acdc26a7 100644
--- a/dom/svg/SVGUseElement.cpp
+++ b/dom/svg/SVGUseElement.cpp
@@ -74,8 +74,8 @@ NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED(SVGUseElement,
 //----------------------------------------------------------------------
 // Implementation
 
-SVGUseElement::SVGUseElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGUseElementBase(aNodeInfo)
+SVGUseElement::SVGUseElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGUseElementBase(std::move(aNodeInfo))
   , mReferencedElementTracker(this)
 {
 }
@@ -96,8 +96,7 @@ nsresult
 SVGUseElement::Clone(dom::NodeInfo* aNodeInfo, nsINode** aResult) const
 {
   *aResult = nullptr;
-  already_AddRefed<mozilla::dom::NodeInfo> ni = RefPtr<mozilla::dom::NodeInfo>(aNodeInfo).forget();
-  SVGUseElement *it = new SVGUseElement(ni);
+  SVGUseElement *it = new SVGUseElement(do_AddRef(aNodeInfo));
 
   nsCOMPtr<nsINode> kungFuDeathGrip(it);
   nsresult rv1 = it->Init();
diff --git a/dom/svg/SVGUseElement.h b/dom/svg/SVGUseElement.h
index 6df0fd4cea5712d1673fb598a0044c11cfcb9158..b088b50822566906df48aee05a3c17273d21f9e6 100644
--- a/dom/svg/SVGUseElement.h
+++ b/dom/svg/SVGUseElement.h
@@ -39,7 +39,7 @@ class SVGUseElement final : public SVGUseElementBase,
 protected:
   friend nsresult (::NS_NewSVGUseElement(nsIContent **aResult,
                                          already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
-  explicit SVGUseElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGUseElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   virtual ~SVGUseElement();
   virtual JSObject* WrapNode(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
 
diff --git a/dom/svg/SVGViewElement.cpp b/dom/svg/SVGViewElement.cpp
index 7f1eeda0f928e82833ae5bf85ca229a18a32d07a..03546520ea5e36c2ad664fdf9d9f65b893cdf314 100644
--- a/dom/svg/SVGViewElement.cpp
+++ b/dom/svg/SVGViewElement.cpp
@@ -37,8 +37,8 @@ nsSVGElement::EnumInfo SVGViewElement::sEnumInfo[1] =
 //----------------------------------------------------------------------
 // Implementation
 
-SVGViewElement::SVGViewElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGViewElementBase(aNodeInfo)
+SVGViewElement::SVGViewElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGViewElementBase(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/svg/SVGViewElement.h b/dom/svg/SVGViewElement.h
index 928a70a0ad629364e41374e23ff17e246b32123b..88d2de30284104b84f32a40d2cd9958d03336d9d 100644
--- a/dom/svg/SVGViewElement.h
+++ b/dom/svg/SVGViewElement.h
@@ -33,7 +33,7 @@ protected:
   friend class SVGSVGElement;
   friend class SVGViewportElement;
   friend class ::nsSVGOuterSVGFrame;
-  explicit SVGViewElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit SVGViewElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   friend nsresult (::NS_NewSVGViewElement(nsIContent **aResult,
                                           already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
   virtual JSObject* WrapNode(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
diff --git a/dom/svg/SVGViewportElement.cpp b/dom/svg/SVGViewportElement.cpp
index 8d121f0658ffe4d0ba768bb5492dda6f262fa208..be40d1fc4acb1d3a7cfdcd517c2e85225ecda79d 100644
--- a/dom/svg/SVGViewportElement.cpp
+++ b/dom/svg/SVGViewportElement.cpp
@@ -49,8 +49,8 @@ nsSVGElement::LengthInfo SVGViewportElement::sLengthInfo[4] =
 //----------------------------------------------------------------------
 // Implementation
 
-SVGViewportElement::SVGViewportElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : SVGGraphicsElement(aNodeInfo),
+SVGViewportElement::SVGViewportElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : SVGGraphicsElement(std::move(aNodeInfo)),
     mViewportWidth(0),
     mViewportHeight(0),
     mHasChildrenOnlyTransform(false)
diff --git a/dom/svg/SVGViewportElement.h b/dom/svg/SVGViewportElement.h
index a0cb8ec8ca61fd1a4cfa235b79e5d8046570400c..babe1a0695e1b1d86e6ba713b9f64afcaef53b2d 100644
--- a/dom/svg/SVGViewportElement.h
+++ b/dom/svg/SVGViewportElement.h
@@ -53,7 +53,7 @@ class SVGViewportElement : public SVGGraphicsElement
 
 protected:
 
-  SVGViewportElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  SVGViewportElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   ~SVGViewportElement();
 
 public:
diff --git a/dom/svg/nsSVGElement.cpp b/dom/svg/nsSVGElement.cpp
index de20e7fcaef2dfb6beaa651f1743c18ca09a926b..a443be645639ed773a08568062844324d3fd4e39 100644
--- a/dom/svg/nsSVGElement.cpp
+++ b/dom/svg/nsSVGElement.cpp
@@ -70,7 +70,7 @@ static_assert(sizeof(void*) == sizeof(nullptr),
 nsresult
 NS_NewSVGElement(Element **aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
 {
-  RefPtr<nsSVGElement> it = new nsSVGElement(aNodeInfo);
+  RefPtr<nsSVGElement> it = new nsSVGElement(std::move(aNodeInfo));
   nsresult rv = it->Init();
 
   if (NS_FAILED(rv)) {
@@ -89,8 +89,8 @@ nsSVGEnumMapping nsSVGElement::sSVGUnitTypesMap[] = {
   {nullptr, 0}
 };
 
-nsSVGElement::nsSVGElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : nsSVGElementBase(aNodeInfo)
+nsSVGElement::nsSVGElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+  : nsSVGElementBase(std::move(aNodeInfo))
 {
 }
 
diff --git a/dom/svg/nsSVGElement.h b/dom/svg/nsSVGElement.h
index 93c3785efdfc74cb4521243fca460b3735cf4957..ffdb2f6f01d6d7d2b2bd63c2d325c424600bac30 100644
--- a/dom/svg/nsSVGElement.h
+++ b/dom/svg/nsSVGElement.h
@@ -67,7 +67,7 @@ typedef nsStyledElement nsSVGElementBase;
 class nsSVGElement : public nsSVGElementBase    // nsIContent
 {
 protected:
-  explicit nsSVGElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit nsSVGElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   friend nsresult NS_NewSVGElement(mozilla::dom::Element **aResult,
                                    already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   nsresult Init();
@@ -641,8 +641,8 @@ nsresult                                                                     \
 NS_NewSVG##_elementName##Element(nsIContent **aResult,                       \
                                  already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)  \
 {                                                                            \
-  RefPtr<nsSVG##_elementName##Element> it =                                \
-    new nsSVG##_elementName##Element(aNodeInfo);                             \
+  RefPtr<nsSVG##_elementName##Element> it =                                  \
+    new nsSVG##_elementName##Element(std::move(aNodeInfo));                  \
                                                                              \
   nsresult rv = it->Init();                                                  \
                                                                              \
@@ -660,8 +660,8 @@ nsresult                                                                     \
 NS_NewSVG##_elementName##Element(nsIContent **aResult,                       \
                                  already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)  \
 {                                                                            \
-  RefPtr<mozilla::dom::SVG##_elementName##Element> it =                    \
-    new mozilla::dom::SVG##_elementName##Element(aNodeInfo);                 \
+  RefPtr<mozilla::dom::SVG##_elementName##Element> it =                      \
+    new mozilla::dom::SVG##_elementName##Element(std::move(aNodeInfo));      \
                                                                              \
   nsresult rv = it->Init();                                                  \
                                                                              \
@@ -680,8 +680,9 @@ NS_NewSVG##_elementName##Element(nsIContent **aResult,                       \
                                  already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,  \
                                  mozilla::dom::FromParser aFromParser)       \
 {                                                                            \
-  RefPtr<mozilla::dom::SVG##_elementName##Element> it =                    \
-    new mozilla::dom::SVG##_elementName##Element(aNodeInfo, aFromParser);    \
+  RefPtr<mozilla::dom::SVG##_elementName##Element> it =                      \
+    new mozilla::dom::SVG##_elementName##Element(std::move(aNodeInfo),       \
+                                                 aFromParser);               \
                                                                              \
   nsresult rv = it->Init();                                                  \
                                                                              \
diff --git a/dom/svg/nsSVGFilters.h b/dom/svg/nsSVGFilters.h
index 97ed79b09a540db7cd68bd54b76454490ca53007..df2ce4acb50e7752473e01a8246432f18016bda2 100644
--- a/dom/svg/nsSVGFilters.h
+++ b/dom/svg/nsSVGFilters.h
@@ -50,8 +50,8 @@ protected:
   typedef mozilla::gfx::ColorSpace ColorSpace;
   typedef mozilla::gfx::FilterPrimitiveDescription FilterPrimitiveDescription;
 
-  explicit nsSVGFE(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : nsSVGFEBase(aNodeInfo) {}
+  explicit nsSVGFE(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : nsSVGFEBase(std::move(aNodeInfo)) {}
   virtual ~nsSVGFE() {}
 
 public:
@@ -155,8 +155,8 @@ typedef nsSVGElement SVGFEUnstyledElementBase;
 class SVGFEUnstyledElement : public SVGFEUnstyledElementBase
 {
 protected:
-  explicit SVGFEUnstyledElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : SVGFEUnstyledElementBase(aNodeInfo) {}
+  explicit SVGFEUnstyledElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : SVGFEUnstyledElementBase(std::move(aNodeInfo)) {}
 
 public:
   virtual nsresult Clone(mozilla::dom::NodeInfo*, nsINode** aResult) const override = 0;
@@ -174,8 +174,8 @@ typedef nsSVGFE nsSVGFELightingElementBase;
 class nsSVGFELightingElement : public nsSVGFELightingElementBase
 {
 protected:
-  explicit nsSVGFELightingElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : nsSVGFELightingElementBase(aNodeInfo) {}
+  explicit nsSVGFELightingElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : nsSVGFELightingElementBase(std::move(aNodeInfo)) {}
 
   virtual ~nsSVGFELightingElement() {}
 
@@ -225,8 +225,8 @@ typedef SVGFEUnstyledElement SVGFELightElementBase;
 class SVGFELightElement : public SVGFELightElementBase
 {
 protected:
-  explicit SVGFELightElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : SVGFELightElementBase(aNodeInfo) {}
+  explicit SVGFELightElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : SVGFELightElementBase(std::move(aNodeInfo)) {}
 
 public:
   typedef gfx::PrimitiveAttributes PrimitiveAttributes;
diff --git a/dom/tests/mochitest/bugs/test_bug1171215.html b/dom/tests/mochitest/bugs/test_bug1171215.html
index cab03c43d228aa072ac15986a0f5c54e75ce6bdf..6f8585ae337527adc471bf93d175e5a88928f2b2 100644
--- a/dom/tests/mochitest/bugs/test_bug1171215.html
+++ b/dom/tests/mochitest/bugs/test_bug1171215.html
@@ -27,12 +27,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1022869
         "http://example.org/tests/dom/tests/mochitest/bugs/file_prime_cookie.html";
     waitForLoad().then(function() {
         // Cookies are set up, disallow third-party cookies and start the test.
-        SpecialPowers.pushPrefEnv({ set: [
-            ["browser.contentblocking.enabled", true],
-            ["browser.contentblocking.ui.enabled", true],
-            ["browser.contentblocking.rejecttrackers.ui.enabled", true],
-            ["network.cookie.cookieBehavior", 1],
-          ]}, () => { continueTest(); });
+        SpecialPowers.pushPrefEnv({ set: [[ 'network.cookie.cookieBehavior', 1 ]] },
+                                  () => { continueTest(); });
     }).catch((e) => { ok(false, `Got exception: ${e}`) });
   }
 
diff --git a/dom/tests/mochitest/general/storagePermissionsUtils.js b/dom/tests/mochitest/general/storagePermissionsUtils.js
index 8edcec675fd484536fb667d6b7500a03176d5663..193245192632c3f43930eb24b0bfdb04837130de 100644
--- a/dom/tests/mochitest/general/storagePermissionsUtils.js
+++ b/dom/tests/mochitest/general/storagePermissionsUtils.js
@@ -26,12 +26,7 @@ if (inFrame) {
 }
 
 function setCookieBehavior(behavior) {
-  return SpecialPowers.pushPrefEnv({"set": [
-    ["browser.contentblocking.enabled", true],
-    ["browser.contentblocking.ui.enabled", true],
-    ["browser.contentblocking.rejecttrackers.ui.enabled", true],
-    [kPrefName, behavior],
-  ]});
+  return SpecialPowers.pushPrefEnv({"set": [[kPrefName, behavior]]});
 }
 
 function runIFrame(url) {
diff --git a/dom/tests/mochitest/localstorage/test_localStorageCookieSettings.html b/dom/tests/mochitest/localstorage/test_localStorageCookieSettings.html
index fd8ce9591f33c809eb7ce6e87564e04b0a37ee37..99f3b1acef8c67b96734ed1443e7565e82379d53 100644
--- a/dom/tests/mochitest/localstorage/test_localStorageCookieSettings.html
+++ b/dom/tests/mochitest/localstorage/test_localStorageCookieSettings.html
@@ -15,12 +15,8 @@
 SimpleTest.waitForExplicitFinish();
 
 // Set cookies behavior to "always reject".
-SpecialPowers.pushPrefEnv({"set": [
-  ["browser.contentblocking.enabled", true],
-  ["browser.contentblocking.ui.enabled", true],
-  ["browser.contentblocking.rejecttrackers.ui.enabled", true],
-  ["network.cookie.cookieBehavior", 2],
-]}, test1);
+SpecialPowers.pushPrefEnv({"set": [["network.cookie.cookieBehavior", 2]]},
+                          test1);
 
 function test1() {
   try {
diff --git a/dom/workers/test/test_sharedWorker_thirdparty.html b/dom/workers/test/test_sharedWorker_thirdparty.html
index 1a7ee410efa9ee763a5250d4f7178d11eeda8458..fce9128a747293b3197ecb99473ce0ec413e5bf3 100644
--- a/dom/workers/test/test_sharedWorker_thirdparty.html
+++ b/dom/workers/test/test_sharedWorker_thirdparty.html
@@ -47,9 +47,6 @@
 
   add_task(async function blocked() {
     await SpecialPowers.pushPrefEnv({ set: [
-      ["browser.contentblocking.enabled", true],
-      ["browser.contentblocking.ui.enabled", true],
-      ["browser.contentblocking.rejecttrackers.ui.enabled", true],
       ["network.cookie.cookieBehavior", COOKIE_BEHAVIOR_REJECTFOREIGN]
     ]});
     let result = await testThirdPartyFrame('blocked');
diff --git a/dom/xbl/XBLChildrenElement.h b/dom/xbl/XBLChildrenElement.h
index e7d0081e38865550df9e73c0c1bee99340709d0e..48e70c9e05aabe3861639ce30bc2ce5a132d8f79 100644
--- a/dom/xbl/XBLChildrenElement.h
+++ b/dom/xbl/XBLChildrenElement.h
@@ -19,12 +19,8 @@ namespace dom {
 class XBLChildrenElement : public nsXMLElement
 {
 public:
-  explicit XBLChildrenElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : nsXMLElement(aNodeInfo)
-  {
-  }
   explicit XBLChildrenElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
-    : nsXMLElement(aNodeInfo)
+    : nsXMLElement(std::move(aNodeInfo))
   {
   }
 
diff --git a/dom/xml/CDATASection.h b/dom/xml/CDATASection.h
index 563175aac55fb18b6234c500c2f1fa849c6d9343..e895d694b2cbfc05d9ed3a43f6147a9111317293 100644
--- a/dom/xml/CDATASection.h
+++ b/dom/xml/CDATASection.h
@@ -25,8 +25,8 @@ private:
   virtual ~CDATASection();
 
 public:
-  explicit CDATASection(already_AddRefed<mozilla::dom::NodeInfo> aNodeInfo)
-    : Text(aNodeInfo)
+  explicit CDATASection(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : Text(std::move(aNodeInfo))
   {
     Init();
   }
diff --git a/dom/xml/nsXMLElement.cpp b/dom/xml/nsXMLElement.cpp
index 43d9864ff6d1808848e4c3adc8a67e3a3f4e4cf0..91af164ea43a88aa8f14375eef0c871ac04d5e92 100644
--- a/dom/xml/nsXMLElement.cpp
+++ b/dom/xml/nsXMLElement.cpp
@@ -16,8 +16,8 @@ nsresult
 NS_NewXMLElement(Element** aInstancePtrResult,
                  already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
 {
-  nsXMLElement* it = new nsXMLElement(aNodeInfo);
-  NS_ADDREF(*aInstancePtrResult = it);
+  RefPtr<nsXMLElement> it = new nsXMLElement(std::move(aNodeInfo));
+  it.forget(aInstancePtrResult);
   return NS_OK;
 }
 
diff --git a/dom/xml/nsXMLElement.h b/dom/xml/nsXMLElement.h
index e0888a238dbd597de8ae39f798b3a305c4ba5079..256dfee112e35ccdd6abff9404f954039667d2be 100644
--- a/dom/xml/nsXMLElement.h
+++ b/dom/xml/nsXMLElement.h
@@ -14,8 +14,8 @@
 class nsXMLElement : public mozilla::dom::Element
 {
 public:
-  explicit nsXMLElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : mozilla::dom::Element(aNodeInfo)
+  explicit nsXMLElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : mozilla::dom::Element(std::move(aNodeInfo))
   {
   }
 
diff --git a/dom/xul/XULFrameElement.h b/dom/xul/XULFrameElement.h
index d9be437a13ce75a5b577e8266ec793debac62570..12d0c61b45cfa23722aa5446a2e4c233a3aba3f0 100644
--- a/dom/xul/XULFrameElement.h
+++ b/dom/xul/XULFrameElement.h
@@ -25,8 +25,8 @@ class XULFrameElement final : public nsXULElement,
                               public nsIFrameLoaderOwner
 {
 public:
-  explicit XULFrameElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : nsXULElement(aNodeInfo)
+  explicit XULFrameElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : nsXULElement(std::move(aNodeInfo))
   {
   }
 
diff --git a/dom/xul/XULMenuElement.h b/dom/xul/XULMenuElement.h
index 8b2f062f106299e07e83ab04063c8ffa348bc757..2aa50590b96d2879a967478f64018b39b9ab7104 100644
--- a/dom/xul/XULMenuElement.h
+++ b/dom/xul/XULMenuElement.h
@@ -18,8 +18,8 @@ class XULMenuElement final : public nsXULElement
 {
 public:
 
-  explicit XULMenuElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : nsXULElement(aNodeInfo)
+  explicit XULMenuElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : nsXULElement(std::move(aNodeInfo))
   {
   }
 
diff --git a/dom/xul/XULPopupElement.cpp b/dom/xul/XULPopupElement.cpp
index 2544c6b05950b060fbd2e71e4963acef74827bb6..4efe6f74c023fe28541a12694eb10855bbb18b96 100644
--- a/dom/xul/XULPopupElement.cpp
+++ b/dom/xul/XULPopupElement.cpp
@@ -24,7 +24,7 @@ namespace dom {
 nsXULElement*
 NS_NewXULPopupElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
 {
-  return new XULPopupElement(aNodeInfo);
+  return new XULPopupElement(std::move(aNodeInfo));
 }
 
 JSObject*
diff --git a/dom/xul/XULPopupElement.h b/dom/xul/XULPopupElement.h
index 5cc0ca618f5415fb72f28d5f88242ecbdf648069..6230ddfa712aa907a034336d5b7799b3288c9f9e 100644
--- a/dom/xul/XULPopupElement.h
+++ b/dom/xul/XULPopupElement.h
@@ -33,8 +33,8 @@ private:
   nsIFrame* GetFrame(bool aFlushLayout);
 
 public:
-  explicit XULPopupElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : nsXULElement(aNodeInfo)
+  explicit XULPopupElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : nsXULElement(std::move(aNodeInfo))
   {
   }
 
diff --git a/dom/xul/XULScrollElement.h b/dom/xul/XULScrollElement.h
index fdefb1294cd3773616c0b21ed2ac912375b49545..0e636857fda1d248ad592294a8ce96e890672793 100644
--- a/dom/xul/XULScrollElement.h
+++ b/dom/xul/XULScrollElement.h
@@ -17,7 +17,8 @@ namespace dom {
 class XULScrollElement final : public nsXULElement
 {
 public:
-  explicit XULScrollElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo): nsXULElement(aNodeInfo)
+  explicit XULScrollElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : nsXULElement(std::move(aNodeInfo))
   {
   }
 
diff --git a/dom/xul/nsXULElement.cpp b/dom/xul/nsXULElement.cpp
index 4b492af236d6b9b98c41bce99294d29d40a18778..43794d7ff0b572b01ebc08b98fd4532ece079ba5 100644
--- a/dom/xul/nsXULElement.cpp
+++ b/dom/xul/nsXULElement.cpp
@@ -103,8 +103,8 @@ uint32_t             nsXULPrototypeAttribute::gNumCacheFills;
 // nsXULElement
 //
 
-nsXULElement::nsXULElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : nsStyledElement(aNodeInfo),
+nsXULElement::nsXULElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
+    : nsStyledElement(std::move(aNodeInfo)),
       mBindingParent(nullptr)
 {
     XUL_PROTOTYPE_ATTRIBUTE_METER(gNumElements);
@@ -139,7 +139,7 @@ nsXULElement::MaybeUpdatePrivateLifetime()
 /* static */
 nsXULElement* NS_NewBasicXULElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
 {
-  return new nsXULElement(aNodeInfo);
+    return new nsXULElement(std::move(aNodeInfo));
 }
 
  /* static */
@@ -156,19 +156,16 @@ nsXULElement* nsXULElement::Construct(already_AddRefed<mozilla::dom::NodeInfo>&&
   if (nodeInfo->Equals(nsGkAtoms::iframe) ||
       nodeInfo->Equals(nsGkAtoms::browser) ||
       nodeInfo->Equals(nsGkAtoms::editor)) {
-    already_AddRefed<mozilla::dom::NodeInfo> frameni = nodeInfo.forget();
-    return new XULFrameElement(frameni);
+    return new XULFrameElement(nodeInfo.forget());
   }
 
   if (nodeInfo->Equals(nsGkAtoms::menu) ||
       nodeInfo->Equals(nsGkAtoms::menulist)) {
-    already_AddRefed<mozilla::dom::NodeInfo> menuni = nodeInfo.forget();
-    return new XULMenuElement(menuni);
+    return new XULMenuElement(nodeInfo.forget());
   }
 
   if (nodeInfo->Equals(nsGkAtoms::scrollbox)) {
-    already_AddRefed<mozilla::dom::NodeInfo> scrollni = nodeInfo.forget();
-    return new XULScrollElement(scrollni);
+    return new XULScrollElement(nodeInfo.forget());
   }
 
   return NS_NewBasicXULElement(nodeInfo.forget());
diff --git a/dom/xul/nsXULElement.h b/dom/xul/nsXULElement.h
index 3bfbacca4237b7f8c272f6c927cd850ed8f2f94b..98f07ecbdc5d62d8f810dcecda61b012a6b1311d 100644
--- a/dom/xul/nsXULElement.h
+++ b/dom/xul/nsXULElement.h
@@ -335,7 +335,7 @@ class nsXULElement : public nsStyledElement
 {
 protected:
     // Use Construct to construct elements instead of this constructor.
-    explicit nsXULElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+    explicit nsXULElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
 public:
     using Element::Blur;
diff --git a/extensions/cookie/test/file_testcommon.js b/extensions/cookie/test/file_testcommon.js
index 217efec85d781683159f6e349d89b669fd0e7ed5..7ce4ac4449c86653492fc9d2431f60fbfd009439 100644
--- a/extensions/cookie/test/file_testcommon.js
+++ b/extensions/cookie/test/file_testcommon.js
@@ -13,12 +13,7 @@ function setupTest(uri, cookies, loads) {
   SimpleTest.waitForExplicitFinish();
 
   var prefSet = new Promise(resolve => {
-    SpecialPowers.pushPrefEnv({ set: [
-      ["browser.contentblocking.enabled", true],
-      ["browser.contentblocking.ui.enabled", true],
-      ["browser.contentblocking.rejecttrackers.ui.enabled", true],
-      ["network.cookie.cookieBehavior", 1],
-    ]}, resolve);
+    SpecialPowers.pushPrefEnv({ set: [["network.cookie.cookieBehavior", 1]] }, resolve);
   });
 
   gScript = SpecialPowers.loadChromeScript(SCRIPT_URL);
diff --git a/extensions/cookie/test/unit/test_cookies_thirdparty.js b/extensions/cookie/test/unit/test_cookies_thirdparty.js
index 7f08691655d1aa9da8e9d91538299ddb9ec09fe7..a39f807f2256a676ee5019dc32aa9abf0caeb9ec 100644
--- a/extensions/cookie/test/unit/test_cookies_thirdparty.js
+++ b/extensions/cookie/test/unit/test_cookies_thirdparty.js
@@ -6,11 +6,6 @@
 // 2) with channel, but with no docshell parent
 
 function run_test() {
-  // Set the needed content blocking prefs
-  Services.prefs.setBoolPref("browser.contentblocking.enabled", true);
-  Services.prefs.setBoolPref("browser.contentblocking.ui.enabled", true);
-  Services.prefs.setBoolPref("browser.contentblocking.rejecttrackers.ui.enabled", true);
-
   // Create URIs and channels pointing to foo.com and bar.com.
   // We will use these to put foo.com into first and third party contexts.
   var spec1 = "http://foo.com/foo.html";
diff --git a/gfx/layers/wr/StackingContextHelper.cpp b/gfx/layers/wr/StackingContextHelper.cpp
index 35653335bd42d0e9b94d1e530ba41891dedd5bbe..4e314965d83b63c16acb9e1252197d383f06ea00 100644
--- a/gfx/layers/wr/StackingContextHelper.cpp
+++ b/gfx/layers/wr/StackingContextHelper.cpp
@@ -36,12 +36,12 @@ StackingContextHelper::StackingContextHelper(const StackingContextHelper& aParen
                                              bool aIsPreserve3D,
                                              const Maybe<nsDisplayTransform*>& aDeferredTransformItem,
                                              const wr::WrClipId* aClipNodeId,
-                                             bool aRasterizeLocally)
+                                             bool aAnimated)
   : mBuilder(&aBuilder)
   , mScale(1.0f, 1.0f)
   , mDeferredTransformItem(aDeferredTransformItem)
   , mIsPreserve3D(aIsPreserve3D)
-  , mRasterizeLocally(aRasterizeLocally || aParentSC.mRasterizeLocally)
+  , mRasterizeLocally(aAnimated || aParentSC.mRasterizeLocally)
 {
   // Compute scale for fallback rendering. We don't try to guess a scale for 3d
   // transformed items
@@ -51,7 +51,7 @@ StackingContextHelper::StackingContextHelper(const StackingContextHelper& aParen
       && !aParentSC.mIsPreserve3D) {
     mInheritedTransform = transform2d * aParentSC.mInheritedTransform;
     mScale = mInheritedTransform.ScaleFactors(true);
-    if (aAnimation) {
+    if (aAnimated) {
       mSnappingSurfaceTransform = gfx::Matrix::Scaling(mScale.width, mScale.height);
     } else {
       mSnappingSurfaceTransform = transform2d * aParentSC.mSnappingSurfaceTransform;
diff --git a/gfx/layers/wr/StackingContextHelper.h b/gfx/layers/wr/StackingContextHelper.h
index e9b509ca38bb81663ee0b2aa2a436a644e0b093b..ff391918757ca57a68ab91840b903310e2900e50 100644
--- a/gfx/layers/wr/StackingContextHelper.h
+++ b/gfx/layers/wr/StackingContextHelper.h
@@ -39,7 +39,7 @@ public:
                         bool aIsPreserve3D = false,
                         const Maybe<nsDisplayTransform*>& aDeferredTransformItem = Nothing(),
                         const wr::WrClipId* aClipNodeId = nullptr,
-                        bool aRasterizeLocally = false);
+                        bool aAnimated = false);
   // This version of the constructor should only be used at the root level
   // of the tree, so that we have a StackingContextHelper to pass down into
   // the RenderLayer traversal, but don't actually want it to push a stacking
diff --git a/gfx/layers/wr/WebRenderCommandBuilder.cpp b/gfx/layers/wr/WebRenderCommandBuilder.cpp
index 32cc0c1e88b0c27b3049f46905cc572f0941f6cf..73a6dc6a19f4683b08ec047095a4ad483e86907b 100644
--- a/gfx/layers/wr/WebRenderCommandBuilder.cpp
+++ b/gfx/layers/wr/WebRenderCommandBuilder.cpp
@@ -855,15 +855,25 @@ Grouper::PaintContainerItem(DIGroup* aGroup, nsDisplayItem* aItem, const IntRect
       auto transformItem = static_cast<nsDisplayTransform*>(aItem);
       Matrix4x4Flagged trans = transformItem->GetTransform();
       Matrix trans2d;
-      MOZ_RELEASE_ASSERT(trans.Is2D(&trans2d));
-      aContext->Multiply(ThebesMatrix(trans2d));
-      aGroup->PaintItemRange(this, aChildren->GetBottom(), nullptr, aContext, aRecorder);
-
-      if (currentClip.HasClip()) {
-        aContext->Restore();
-        aContext->GetDrawTarget()->FlushItem(aItemBounds);
+      if (!trans.Is2D(&trans2d)) {
+        // We don't currently support doing invalidation inside 3d transforms.
+        // For now just paint it as a single item.
+        BlobItemData* data = GetBlobItemDataForGroup(aItem, aGroup);
+        if (data->mLayerManager->GetRoot()) {
+          data->mLayerManager->BeginTransaction();
+          data->mLayerManager->EndTransaction(FrameLayerBuilder::DrawPaintedLayer, mDisplayListBuilder);
+          aContext->GetDrawTarget()->FlushItem(aItemBounds);
+        }
       } else {
-        aContext->SetMatrix(matrix);
+        aContext->Multiply(ThebesMatrix(trans2d));
+        aGroup->PaintItemRange(this, aChildren->GetBottom(), nullptr, aContext, aRecorder);
+
+        if (currentClip.HasClip()) {
+          aContext->Restore();
+          aContext->GetDrawTarget()->FlushItem(aItemBounds);
+        } else {
+          aContext->SetMatrix(matrix);
+        }
       }
       break;
     }
@@ -897,16 +907,15 @@ Grouper::PaintContainerItem(DIGroup* aGroup, nsDisplayItem* aItem, const IntRect
     }
     case DisplayItemType::TYPE_MASK: {
       GP("Paint Mask\n");
-      // We don't currently support doing invalidation inside nsDisplayMask
-      // for now just paint it as a single item
-      BlobItemData* data = GetBlobItemDataForGroup(aItem, aGroup);
-      if (data->mLayerManager->GetRoot()) {
-        data->mLayerManager->BeginTransaction();
-        static_cast<nsDisplayMask*>(aItem)->PaintAsLayer(mDisplayListBuilder,
-                                                       aContext, data->mLayerManager);
-        if (data->mLayerManager->InTransaction()) {
-          data->mLayerManager->AbortTransaction();
-        }
+      auto maskItem = static_cast<nsDisplayMask*>(aItem);
+      maskItem->SetPaintRect(maskItem->GetClippedBounds(mDisplayListBuilder));
+      if (maskItem->IsValidMask()) {
+        maskItem->PaintWithContentsPaintCallback(mDisplayListBuilder, aContext, [&] {
+          GP("beginGroup %s %p-%d\n", aItem->Name(), aItem->Frame(), aItem->GetPerFrameKey());
+          aContext->GetDrawTarget()->FlushItem(aItemBounds);
+          aGroup->PaintItemRange(this, aChildren->GetBottom(), nullptr, aContext, aRecorder);
+          GP("endGroup %s %p-%d\n", aItem->Name(), aItem->Frame(), aItem->GetPerFrameKey());
+          });
         aContext->GetDrawTarget()->FlushItem(aItemBounds);
       }
       break;
@@ -1100,8 +1109,7 @@ Grouper::ConstructItemInsideInactive(WebRenderCommandBuilder* aCommandBuilder,
   nsDisplayList* children = aItem->GetChildren();
   BlobItemData* data = GetBlobItemDataForGroup(aItem, aGroup);
 
-  if (aItem->GetType() == DisplayItemType::TYPE_FILTER ||
-      aItem->GetType() == DisplayItemType::TYPE_MASK) {
+  if (aItem->GetType() == DisplayItemType::TYPE_FILTER) {
     gfx::Size scale(1, 1);
     // If ComputeDifferences finds any change, we invalidate the entire container item.
     // This is needed because blob merging requires the entire item to be within the invalid region.
@@ -1111,16 +1119,22 @@ Grouper::ConstructItemInsideInactive(WebRenderCommandBuilder* aCommandBuilder,
     const Matrix4x4Flagged& t = transformItem->GetTransform();
     Matrix t2d;
     bool is2D = t.Is2D(&t2d);
-    MOZ_RELEASE_ASSERT(is2D, "Non-2D transforms should be treated as active");
-
-    Matrix m = mTransform;
+    if (!is2D) {
+      // We'll use BasicLayerManager to handle 3d transforms.
+      gfx::Size scale(1, 1);
+      // If ComputeDifferences finds any change, we invalidate the entire container item.
+      // This is needed because blob merging requires the entire item to be within the invalid region.
+      data->mInvalid = BuildLayer(aItem, data, mDisplayListBuilder, scale);
+    } else {
+      Matrix m = mTransform;
 
-    GP("t2d: %f %f\n", t2d._31, t2d._32);
-    mTransform.PreMultiply(t2d);
-    GP("mTransform: %f %f\n", mTransform._31, mTransform._32);
-    ConstructGroupInsideInactive(aCommandBuilder, aBuilder, aResources, aGroup, children, aSc);
+      GP("t2d: %f %f\n", t2d._31, t2d._32);
+      mTransform.PreMultiply(t2d);
+      GP("mTransform: %f %f\n", mTransform._31, mTransform._32);
+      ConstructGroupInsideInactive(aCommandBuilder, aBuilder, aResources, aGroup, children, aSc);
 
-    mTransform = m;
+      mTransform = m;
+    }
   } else if (children) {
     sIndent++;
     ConstructGroupInsideInactive(aCommandBuilder, aBuilder, aResources, aGroup, children, aSc);
diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp
index 9db41e0fb4a79f880042623b0d2088387ddc8462..a2646101994e614c848e06dc646693847ce2cf73 100644
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -713,6 +713,9 @@ WebRenderMemoryReporter::CollectReports(nsIHandleReportCallback* aHandleReport,
       helper.Report(aReport.gpu_cache_cpu_mirror, "gpu-cache/cpu-mirror");
       helper.Report(aReport.render_tasks, "render-tasks");
       helper.Report(aReport.hit_testers, "hit-testers");
+      helper.Report(aReport.fonts, "resource-cache/font");
+      helper.Report(aReport.images, "resource-cache/images");
+      helper.Report(aReport.rasterized_blobs, "resource-cache/rasterized-blobs");
       FinishAsyncMemoryReport();
     },
     [](mozilla::ipc::ResponseRejectReason aReason) {
diff --git a/gfx/webrender/Cargo.toml b/gfx/webrender/Cargo.toml
index d2144118f1a21ee18e0c920016b5bb259912a67a..3bc583be1e4c9deb38eb7f293e17665bd399489a 100644
--- a/gfx/webrender/Cargo.toml
+++ b/gfx/webrender/Cargo.toml
@@ -32,7 +32,7 @@ image = { optional = true, version = "0.19" }
 lazy_static = "1"
 log = "0.4"
 num-traits = "0.2"
-plane-split = "0.13"
+plane-split = "0.13.1"
 png = { optional = true, version = "0.12" }
 rayon = "1"
 ron = { optional = true, version = "0.1.7" }
diff --git a/gfx/webrender/src/batch.rs b/gfx/webrender/src/batch.rs
index 0dbcb4b42155f45f4bdfad2303f6980235c9b0da..a2b22e15b036a399e1a2fd1b948f6d865b539e16 100644
--- a/gfx/webrender/src/batch.rs
+++ b/gfx/webrender/src/batch.rs
@@ -703,9 +703,11 @@ impl AlphaBatchBuilder {
                             if let Some(local_rect) = local_rect {
                                 match transform.transform_kind() {
                                     TransformedRectKind::AxisAligned => {
-                                        let polygon = Polygon::from_transformed_rect(
+                                        let inv_transform = transforms.get_world_inv_transform(prim_metadata.spatial_node_index);
+                                        let polygon = Polygon::from_transformed_rect_with_inverse(
                                             local_rect.cast(),
-                                            transform.cast(),
+                                            &transform.cast(),
+                                            &inv_transform.cast(),
                                             prim_index.0,
                                         ).unwrap();
                                         splitter.add(polygon);
diff --git a/gfx/webrender/src/border.rs b/gfx/webrender/src/border.rs
index 90eed86a4756ba9328b3898fd156f0c56d04e871..96507691d7d93f40c2ce5abeba7f818964d6f6b6 100644
--- a/gfx/webrender/src/border.rs
+++ b/gfx/webrender/src/border.rs
@@ -8,6 +8,7 @@ use api::{DeviceVector2D, DevicePoint, DeviceIntSize, LayoutRect, LayoutSize, No
 use api::{AuHelpers};
 use app_units::Au;
 use ellipse::Ellipse;
+use euclid::SideOffsets2D;
 use display_list_flattener::DisplayListFlattener;
 use gpu_types::{BorderInstance, BorderSegment, BrushFlags};
 use prim_store::{BrushKind, BrushPrimitive, BrushSegment};
@@ -75,27 +76,6 @@ impl From<BorderRadiusAu> for BorderRadius {
     }
 }
 
-#[derive(Clone, Debug, Hash, PartialEq, Eq)]
-#[cfg_attr(feature = "capture", derive(Serialize))]
-#[cfg_attr(feature = "replay", derive(Deserialize))]
-pub struct BorderWidthsAu {
-    pub left: Au,
-    pub top: Au,
-    pub right: Au,
-    pub bottom: Au,
-}
-
-impl From<LayoutSideOffsets> for BorderWidthsAu {
-    fn from(widths: LayoutSideOffsets) -> Self {
-        BorderWidthsAu {
-            left: Au::from_f32_px(widths.left),
-            top: Au::from_f32_px(widths.top),
-            right: Au::from_f32_px(widths.right),
-            bottom: Au::from_f32_px(widths.bottom),
-        }
-    }
-}
-
 #[derive(Clone, Debug, Hash, PartialEq, Eq)]
 #[cfg_attr(feature = "capture", derive(Serialize))]
 #[cfg_attr(feature = "replay", derive(Deserialize))]
@@ -122,7 +102,7 @@ pub struct BorderCacheKey {
     pub top: BorderSideAu,
     pub bottom: BorderSideAu,
     pub radius: BorderRadiusAu,
-    pub widths: BorderWidthsAu,
+    pub widths: SideOffsets2D<Au>,
     pub scale: Au,
 }
 
@@ -133,7 +113,12 @@ impl BorderCacheKey {
             top: border.top.into(),
             right: border.right.into(),
             bottom: border.bottom.into(),
-            widths: (*widths).into(),
+            widths: SideOffsets2D::new(
+                Au::from_f32_px(widths.top),
+                Au::from_f32_px(widths.right),
+                Au::from_f32_px(widths.bottom),
+                Au::from_f32_px(widths.left),
+            ),
             radius: border.radius.into(),
             scale: Au(0),
         }
diff --git a/gfx/webrender/src/gpu_types.rs b/gfx/webrender/src/gpu_types.rs
index c2c0d8ffd9fca4a58f47c77fdb8dccfb19f56f76..50beff47f4c6f5d696c53556d01c97c4b49a4c2a 100644
--- a/gfx/webrender/src/gpu_types.rs
+++ b/gfx/webrender/src/gpu_types.rs
@@ -2,8 +2,11 @@
  * 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 api::{DevicePoint, DeviceSize, DeviceRect, LayoutRect, LayoutToWorldTransform, LayoutTransform};
-use api::{PremultipliedColorF, LayoutToPictureTransform, PictureToLayoutTransform, PicturePixel, WorldPixel};
+use api::{
+    DevicePoint, DeviceSize, DeviceRect, LayoutRect, LayoutToWorldTransform, LayoutTransform,
+    PremultipliedColorF, LayoutToPictureTransform, PictureToLayoutTransform, PicturePixel,
+    WorldPixel, WorldToLayoutTransform,
+};
 use clip_scroll_tree::{ClipScrollTree, ROOT_SPATIAL_NODE_INDEX, SpatialNodeIndex};
 use gpu_cache::{GpuCacheAddress, GpuDataRequest};
 use internal_types::FastHashMap;
@@ -487,6 +490,15 @@ impl TransformPalette {
             .with_destination::<WorldPixel>()
     }
 
+    pub fn get_world_inv_transform(
+        &self,
+        index: SpatialNodeIndex,
+    ) -> WorldToLayoutTransform {
+        self.transforms[index.0]
+            .inv_transform
+            .with_source::<WorldPixel>()
+    }
+
     // Get a transform palette id for the given spatial node.
     // TODO(gw): In the future, it will be possible to specify
     //           a coordinate system id here, to allow retrieving
diff --git a/gfx/webrender/src/render_backend.rs b/gfx/webrender/src/render_backend.rs
index 8f31903b78cad709ade514745de7dbf05bc2efd3..53bb4a5f36a2d49ba8bca545e260b1d5f63f3817 100644
--- a/gfx/webrender/src/render_backend.rs
+++ b/gfx/webrender/src/render_backend.rs
@@ -1190,17 +1190,19 @@ impl RenderBackend {
 
     fn report_memory(&self) -> MemoryReport {
         let mut report = MemoryReport::default();
-        let op = self.size_of_op.as_ref().unwrap();
-        report.gpu_cache_metadata = self.gpu_cache.malloc_size_of(*op);
+        let op = self.size_of_op.unwrap();
+        report.gpu_cache_metadata = self.gpu_cache.malloc_size_of(op);
         for (_id, doc) in &self.documents {
             if let Some(ref fb) = doc.frame_builder {
                 report.primitive_stores += self.size_of(fb.prim_store.primitives.as_ptr());
-                report.clip_stores += fb.clip_store.malloc_size_of(*op);
+                report.clip_stores += fb.clip_store.malloc_size_of(op);
             }
             report.hit_testers +=
-                doc.hit_tester.as_ref().map_or(0, |ht| ht.malloc_size_of(*op));
+                doc.hit_tester.as_ref().map_or(0, |ht| ht.malloc_size_of(op));
         }
 
+        report += self.resource_cache.report_memory(op);
+
         report
     }
 }
diff --git a/gfx/webrender/src/resource_cache.rs b/gfx/webrender/src/resource_cache.rs
index a0615a4f0df6210a5ddd3608ae3317ce7bc373b0..9094e1aa6a1c7a788b0de5a5c8f9f5afb13a7c8e 100644
--- a/gfx/webrender/src/resource_cache.rs
+++ b/gfx/webrender/src/resource_cache.rs
@@ -10,6 +10,7 @@ use api::{ExternalImageData, ExternalImageType, BlobImageResult, BlobImageParams
 use api::{FontInstanceData, FontInstanceOptions, FontInstancePlatformOptions, FontVariation};
 use api::{GlyphDimensions, IdNamespace};
 use api::{ImageData, ImageDescriptor, ImageKey, ImageRendering};
+use api::{MemoryReport, VoidPtrToSizeFn};
 use api::{TileOffset, TileSize, TileRange, NormalizedRect, BlobImageData};
 use app_units::Au;
 #[cfg(feature = "capture")]
@@ -34,10 +35,11 @@ use render_task::{RenderTaskCache, RenderTaskCacheKey, RenderTaskId};
 use render_task::{RenderTaskCacheEntry, RenderTaskCacheEntryHandle, RenderTaskTree};
 use smallvec::SmallVec;
 use std::collections::hash_map::Entry::{self, Occupied, Vacant};
-use std::collections::hash_map::ValuesMut;
+use std::collections::hash_map::IterMut;
 use std::{cmp, mem};
 use std::fmt::Debug;
 use std::hash::Hash;
+use std::os::raw::c_void;
 #[cfg(any(feature = "capture", feature = "replay"))]
 use std::path::PathBuf;
 use std::sync::{Arc, RwLock};
@@ -245,8 +247,8 @@ where
         self.resources.entry(key)
     }
 
-    pub fn values_mut(&mut self) -> ValuesMut<K, V> {
-        self.resources.values_mut()
+    pub fn iter_mut(&mut self) -> IterMut<K, V> {
+        self.resources.iter_mut()
     }
 
     pub fn clear(&mut self) {
@@ -379,6 +381,11 @@ impl BlobImageResources for Resources {
 
 pub type GlyphDimensionsCache = FastHashMap<(FontInstance, GlyphIndex), Option<GlyphDimensions>>;
 
+/// High-level container for resources managed by the `RenderBackend`.
+///
+/// This includes a variety of things, including images, fonts, and glyphs,
+/// which may be stored as memory buffers, GPU textures, or handles to resources
+/// managed by the OS or other parts of WebRender.
 pub struct ResourceCache {
     cached_glyphs: GlyphCache,
     cached_images: ImageCache,
@@ -753,8 +760,21 @@ impl ResourceCache {
                 entry.dirty_rect = merge_dirty_rect(&entry.dirty_rect, &dirty_rect, &descriptor);
             }
             Some(&mut ImageResult::Multi(ref mut entries)) => {
-                for entry in entries.values_mut() {
-                    entry.dirty_rect = merge_dirty_rect(&entry.dirty_rect, &dirty_rect, &descriptor);
+                for (key, entry) in entries.iter_mut() {
+                    let merged_rect = merge_dirty_rect(&entry.dirty_rect, &dirty_rect, &descriptor);
+
+                    entry.dirty_rect = match (key.tile, merged_rect) {
+                        (Some(tile), Some(rect)) => {
+                            let tile_size = image.tiling.unwrap();
+                            let clipped_tile_size = compute_tile_size(&descriptor, tile_size, tile);
+
+                            rect.intersection(&DeviceUintRect::new(
+                                DeviceUintPoint::new(tile.x as u32, tile.y as u32) * tile_size as u32,
+                                clipped_tile_size,
+                            ))
+                        }
+                        _ => merged_rect,
+                    };
                 }
             }
             _ => {}
@@ -1628,6 +1648,41 @@ impl ResourceCache {
             r.clear_namespace(namespace);
         }
     }
+
+    /// Reports the CPU heap usage of this ResourceCache.
+    pub fn report_memory(&self, op: VoidPtrToSizeFn) -> MemoryReport {
+        let mut report = MemoryReport::default();
+
+        // Measure fonts. We only need the templates here, because the instances
+        // don't have big buffers.
+        for (_, font) in self.resources.font_templates.iter() {
+            if let FontTemplate::Raw(ref raw, _) = font {
+                report.fonts += unsafe { op(raw.as_ptr() as *const c_void) };
+            }
+        }
+
+        // Measure images.
+        for (_, image) in self.resources.image_templates.images.iter() {
+            report.images += match image.data {
+                ImageData::Raw(ref v) => unsafe { op(v.as_ptr() as *const c_void) },
+                ImageData::Blob(ref v) => unsafe { op(v.as_ptr() as *const c_void) },
+                ImageData::External(..) => 0,
+            }
+        }
+
+        // Mesure rasterized blobs.
+        for (_, image) in self.rasterized_blob_images.iter() {
+            let mut accumulate = |b: &RasterizedBlobImage| {
+                report.rasterized_blobs += unsafe { op(b.data.as_ptr() as *const c_void) };
+            };
+            match image {
+                RasterizedBlob::Tiled(map) => map.values().for_each(&mut accumulate),
+                RasterizedBlob::NonTiled(vec) => vec.iter().for_each(&mut accumulate),
+            };
+        }
+
+        report
+    }
 }
 
 pub fn get_blob_tiling(
diff --git a/gfx/webrender_api/src/api.rs b/gfx/webrender_api/src/api.rs
index 5ec7f406b5ff5fe745ec8ae37dff7647d2801968..3287f9f7c3e3e1f63572fb666df22646cd21a3fc 100644
--- a/gfx/webrender_api/src/api.rs
+++ b/gfx/webrender_api/src/api.rs
@@ -757,6 +757,9 @@ pub struct MemoryReport {
     pub gpu_cache_cpu_mirror: usize,
     pub render_tasks: usize,
     pub hit_testers: usize,
+    pub fonts: usize,
+    pub images: usize,
+    pub rasterized_blobs: usize,
 }
 
 impl ::std::ops::AddAssign for MemoryReport {
@@ -767,6 +770,9 @@ impl ::std::ops::AddAssign for MemoryReport {
         self.gpu_cache_cpu_mirror += other.gpu_cache_cpu_mirror;
         self.render_tasks += other.render_tasks;
         self.hit_testers += other.hit_testers;
+        self.fonts += other.fonts;
+        self.images += other.images;
+        self.rasterized_blobs += other.rasterized_blobs;
     }
 }
 
diff --git a/gfx/webrender_api/src/font.rs b/gfx/webrender_api/src/font.rs
index 7988161b2d70c99b7b86f0f52f746599d801a2df..717023dcfc0d1d1b83b7ac0198e908fd2339db6d 100644
--- a/gfx/webrender_api/src/font.rs
+++ b/gfx/webrender_api/src/font.rs
@@ -80,7 +80,13 @@ impl FontKey {
     }
 }
 
-
+/// Container for the raw data describing a font. This might be a stream of
+/// bytes corresponding to a downloaded font, or a handle to a native font from
+/// the operating system.
+///
+/// Note that fonts need to be instantiated before being used, which involves
+/// assigning size and various other options. The word 'template' here is
+/// intended to distinguish this data from instance-specific data.
 #[derive(Clone)]
 pub enum FontTemplate {
     Raw(Arc<Vec<u8>>, u32),
@@ -348,6 +354,10 @@ impl FontInstanceKey {
     }
 }
 
+/// Data corresponding to an instantiation of a font, with size and
+/// other options specified.
+///
+/// Note that the actual font is stored out-of-band in `FontTemplate`.
 #[derive(Clone)]
 pub struct FontInstanceData {
     pub font_key: FontKey,
diff --git a/gfx/webrender_bindings/revision.txt b/gfx/webrender_bindings/revision.txt
index e0940ea6b9893a01bc7a1958b44a95dfe525ee4a..25019b93ddd7a650860dc8527c63de5ff575ece0 100644
--- a/gfx/webrender_bindings/revision.txt
+++ b/gfx/webrender_bindings/revision.txt
@@ -1 +1 @@
-a601f9c291cee83257241ef61aaf62353c613438
+97a3807ea8266c324feb3ecada2ac5fd78c80e9b
diff --git a/gfx/webrender_bindings/webrender_ffi_generated.h b/gfx/webrender_bindings/webrender_ffi_generated.h
index 3e4c4ba6ef50562bc61f5418d348250e56979f19..04db0006eb9271d4b12a30b2cdcc7cc9ee21ed1f 100644
--- a/gfx/webrender_bindings/webrender_ffi_generated.h
+++ b/gfx/webrender_bindings/webrender_ffi_generated.h
@@ -488,6 +488,9 @@ struct MemoryReport {
   uintptr_t gpu_cache_cpu_mirror;
   uintptr_t render_tasks;
   uintptr_t hit_testers;
+  uintptr_t fonts;
+  uintptr_t images;
+  uintptr_t rasterized_blobs;
 
   bool operator==(const MemoryReport& aOther) const {
     return primitive_stores == aOther.primitive_stores &&
@@ -495,7 +498,10 @@ struct MemoryReport {
            gpu_cache_metadata == aOther.gpu_cache_metadata &&
            gpu_cache_cpu_mirror == aOther.gpu_cache_cpu_mirror &&
            render_tasks == aOther.render_tasks &&
-           hit_testers == aOther.hit_testers;
+           hit_testers == aOther.hit_testers &&
+           fonts == aOther.fonts &&
+           images == aOther.images &&
+           rasterized_blobs == aOther.rasterized_blobs;
   }
 };
 
diff --git a/ipc/ipdl/sync-messages.ini b/ipc/ipdl/sync-messages.ini
index 5c4ed8712f27347d34a5fd977ac9d1ed1d5caade..acd1a73d563ad6798caf9b2271bc71a824329fac 100644
--- a/ipc/ipdl/sync-messages.ini
+++ b/ipc/ipdl/sync-messages.ini
@@ -1049,8 +1049,6 @@ description =
 description =
 [PHal::LockScreenOrientation]
 description =
-[PCookieService::GetCookieString]
-description =
 [PPrinting::SavePrintSettings]
 description =
 [PHandlerService::FillHandlerInfo]
diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp
index e246fa20fec8f87d9e29a999447112079fb94c53..ec5d22bc0c821faacd5e626dff9f5013679cec07 100644
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -2505,10 +2505,8 @@ nsCSSFrameConstructor::ConstructDocElementFrame(Element*                 aDocEle
     // function in general.
     // Use a null PendingBinding, since our binding is not in fact pending.
     static const FrameConstructionData rootSVGData = FCDATA_DECL(0, nullptr);
-    already_AddRefed<ComputedStyle> extraRef =
-      RefPtr<ComputedStyle>(computedStyle).forget();
     AutoFrameConstructionItem item(this, &rootSVGData, aDocElement,
-                                   nullptr, extraRef, true);
+                                   nullptr, do_AddRef(computedStyle), true);
 
     nsFrameItems frameItems;
     contentFrame = static_cast<nsContainerFrame*>(
@@ -2555,10 +2553,8 @@ nsCSSFrameConstructor::ConstructDocElementFrame(Element*                 aDocEle
     // function in general.
     // Use a null PendingBinding, since our binding is not in fact pending.
     static const FrameConstructionData rootTableData = FCDATA_DECL(0, nullptr);
-    already_AddRefed<ComputedStyle> extraRef =
-      RefPtr<ComputedStyle>(computedStyle).forget();
     AutoFrameConstructionItem item(this, &rootTableData, aDocElement,
-                                   nullptr, extraRef, true);
+                                   nullptr, do_AddRef(computedStyle), true);
 
     nsFrameItems frameItems;
     // if the document is a table then just populate it.
@@ -5527,10 +5523,10 @@ nsCSSFrameConstructor::FindElementTagData(const Element& aElement,
 }
 
 nsCSSFrameConstructor::XBLBindingLoadInfo::XBLBindingLoadInfo(
-  already_AddRefed<ComputedStyle> aStyle,
+  already_AddRefed<ComputedStyle>&& aStyle,
   mozilla::UniquePtr<PendingBinding> aPendingBinding,
   nsAtom* aTag)
-  : mStyle(aStyle)
+  : mStyle(std::move(aStyle))
   , mPendingBinding(std::move(aPendingBinding))
   , mTag(aTag)
 {
@@ -9284,7 +9280,7 @@ nsCSSFrameConstructor::CreateNeededAnonFlexOrGridItems(
                             : nsCSSAnonBoxes::anonymousGridItem();
     ComputedStyle* parentStyle = aParentFrame->Style();
     nsIContent* parentContent = aParentFrame->GetContent();
-    already_AddRefed<ComputedStyle> wrapperStyle =
+    RefPtr<ComputedStyle> wrapperStyle =
       mPresShell->StyleSet()->ResolveInheritingAnonymousBoxStyle(pseudoType,
                                                                  parentStyle);
 
@@ -9300,7 +9296,7 @@ nsCSSFrameConstructor::CreateNeededAnonFlexOrGridItems(
                                 parentContent,
                                 // no pending binding
                                 nullptr,
-                                wrapperStyle,
+                                wrapperStyle.forget(),
                                 true);
 
     newItem->mIsAllInline =
@@ -9786,7 +9782,7 @@ nsCSSFrameConstructor::WrapItemsInPseudoParent(nsIContent* aParentContent,
     pseudoType = nsCSSAnonBoxes::inlineTable();
   }
 
-  already_AddRefed<ComputedStyle> wrapperStyle;
+  RefPtr<ComputedStyle> wrapperStyle;
   if (pseudoData.mFCData.mBits & FCDATA_IS_WRAPPER_ANON_BOX) {
     wrapperStyle =
       mPresShell->StyleSet()->ResolveInheritingAnonymousBoxStyle(pseudoType,
@@ -9802,7 +9798,7 @@ nsCSSFrameConstructor::WrapItemsInPseudoParent(nsIContent* aParentContent,
                               aParentContent,
                               // no pending binding
                               nullptr,
-                              wrapperStyle,
+                              wrapperStyle.forget(),
                               true);
 
   const nsStyleDisplay* disp = newItem->mComputedStyle->StyleDisplay();
@@ -9857,7 +9853,7 @@ nsCSSFrameConstructor::CreateNeededPseudoSiblings(
 
   const PseudoParentData& pseudoData =
     sPseudoParentData[eTypeRubyBaseContainer];
-  already_AddRefed<ComputedStyle> pseudoStyle = mPresShell->StyleSet()->
+  RefPtr<ComputedStyle> pseudoStyle = mPresShell->StyleSet()->
     ResolveInheritingAnonymousBoxStyle(*pseudoData.mPseudoType,
                                        aParentFrame->Style());
   FrameConstructionItem* newItem =
@@ -9866,7 +9862,7 @@ nsCSSFrameConstructor::CreateNeededPseudoSiblings(
                                      aParentFrame->GetContent(),
                                      // no pending binding
                                      nullptr,
-                                     pseudoStyle,
+                                     pseudoStyle.forget(),
                                      true);
   newItem->mIsAllInline = true;
   newItem->mChildItems.SetParentHasNoXBLChildren(true);
diff --git a/layout/base/nsCSSFrameConstructor.h b/layout/base/nsCSSFrameConstructor.h
index 7a204043882dcb063e81a4c52fa4bca33df80f9d..77c0fa316d2bfa1500973cdda1cbaa8794f29cf1 100644
--- a/layout/base/nsCSSFrameConstructor.h
+++ b/layout/base/nsCSSFrameConstructor.h
@@ -798,7 +798,7 @@ private:
     XBLBindingLoadInfo(nsIContent&, ComputedStyle&);
 
     // For the case we actually load an XBL binding.
-    XBLBindingLoadInfo(already_AddRefed<ComputedStyle> aStyle,
+    XBLBindingLoadInfo(already_AddRefed<ComputedStyle>&& aStyle,
                        mozilla::UniquePtr<PendingBinding> aPendingBinding,
                        nsAtom* aTag);
 
@@ -901,7 +901,7 @@ private:
     {
       FrameConstructionItem* item =
         new (aFCtor) FrameConstructionItem(aFCData, aContent,
-                                           aPendingBinding, aComputedStyle,
+                                           aPendingBinding, std::move(aComputedStyle),
                                            aSuppressWhiteSpaceOptimizations);
       mItems.insertBack(item);
       ++mItemCount;
@@ -919,7 +919,7 @@ private:
     {
       FrameConstructionItem* item =
         new (aFCtor) FrameConstructionItem(aFCData, aContent,
-                                           aPendingBinding, aComputedStyle,
+                                           aPendingBinding, std::move(aComputedStyle),
                                            aSuppressWhiteSpaceOptimizations);
       mItems.insertFront(item);
       ++mItemCount;
@@ -1147,10 +1147,10 @@ private:
     FrameConstructionItem(const FrameConstructionData* aFCData,
                           nsIContent* aContent,
                           PendingBinding* aPendingBinding,
-                          already_AddRefed<ComputedStyle>& aComputedStyle,
+                          already_AddRefed<ComputedStyle>&& aComputedStyle,
                           bool aSuppressWhiteSpaceOptimizations)
     : mFCData(aFCData), mContent(aContent),
-      mPendingBinding(aPendingBinding), mComputedStyle(aComputedStyle),
+      mPendingBinding(aPendingBinding), mComputedStyle(std::move(aComputedStyle)),
       mSuppressWhiteSpaceOptimizations(aSuppressWhiteSpaceOptimizations),
       mIsText(false), mIsGeneratedContent(false),
       mIsAnonymousContentCreatorContent(false),
diff --git a/layout/generic/DetailsFrame.cpp b/layout/generic/DetailsFrame.cpp
index 789a63aa308ec274762b1dba4526b37c18f38546..17dde53b2edd4d599781581e5ab7e1464162e06d 100644
--- a/layout/generic/DetailsFrame.cpp
+++ b/layout/generic/DetailsFrame.cpp
@@ -101,10 +101,10 @@ DetailsFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
   nsNodeInfoManager* nodeInfoManager =
     GetContent()->NodeInfo()->NodeInfoManager();
 
-  already_AddRefed<NodeInfo> nodeInfo =
+  RefPtr<NodeInfo> nodeInfo =
     nodeInfoManager->GetNodeInfo(nsGkAtoms::summary, nullptr, kNameSpaceID_XHTML,
                                  nsINode::ELEMENT_NODE);
-  mDefaultSummary = new HTMLSummaryElement(nodeInfo);
+  mDefaultSummary = new HTMLSummaryElement(nodeInfo.forget());
 
   nsAutoString defaultSummaryText;
   nsContentUtils::GetLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
diff --git a/layout/painting/nsDisplayList.cpp b/layout/painting/nsDisplayList.cpp
index e56d5c4360e6b35fc80c29b6a96e227701f7792d..08b717a391335ac636d3f53d8f56739850dd2f0d 100644
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -8752,7 +8752,7 @@ nsDisplayTransform::CreateWebRenderCommands(
 
   // If it looks like we're animated, we should rasterize in local space
   // (disabling subpixel-aa and global pixel snapping)
-  bool rasterizeLocally =
+  bool animated =
     ActiveLayerTracker::IsStyleMaybeAnimated(Frame(), eCSSProperty_transform);
 
   StackingContextHelper sc(aSc,
@@ -8769,7 +8769,7 @@ nsDisplayTransform::CreateWebRenderCommands(
                            mFrame->Extend3DContext() && !mNoExtendContext,
                            deferredTransformItem,
                            nullptr,
-                           rasterizeLocally);
+                           animated);
 
   return mStoredList.CreateWebRenderCommands(
     aBuilder, aResources, sc, aManager, aDisplayListBuilder);
@@ -9703,17 +9703,14 @@ nsDisplayMask::CanMerge(const nsDisplayItem* aItem) const
          CanMergeDisplayMaskFrame(aItem->Frame());
 }
 
-already_AddRefed<Layer>
-nsDisplayMask::BuildLayer(nsDisplayListBuilder* aBuilder,
-                          LayerManager* aManager,
-                          const ContainerLayerParameters& aContainerParameters)
-{
+bool
+nsDisplayMask::IsValidMask() {
   if (!ValidateSVGFrame()) {
-    return nullptr;
+    return false;
   }
 
   if (mFrame->StyleEffects()->mOpacity == 0.0f && mHandleOpacity) {
-    return nullptr;
+    return false;
   }
 
   nsIFrame* firstFrame =
@@ -9723,6 +9720,20 @@ nsDisplayMask::BuildLayer(nsDisplayListBuilder* aBuilder,
 
   if (effectProperties.HasInvalidClipPath() ||
       effectProperties.HasInvalidMask()) {
+    return false;
+  }
+
+  return true;
+}
+
+
+
+already_AddRefed<Layer>
+nsDisplayMask::BuildLayer(nsDisplayListBuilder* aBuilder,
+                          LayerManager* aManager,
+                          const ContainerLayerParameters& aContainerParameters)
+{
+  if (!IsValidMask()) {
     return nullptr;
   }
 
@@ -9893,6 +9904,43 @@ nsDisplayMask::PaintAsLayer(nsDisplayListBuilder* aBuilder,
   nsDisplayMaskGeometry::UpdateDrawResult(this, imgParams.result);
 }
 
+void
+nsDisplayMask::PaintWithContentsPaintCallback(nsDisplayListBuilder* aBuilder,
+                                              gfxContext* aCtx,
+                                              const std::function<void()>& aPaintChildren)
+{
+  // Clip the drawing target by mVisibleRect, which contains the visible
+  // region of the target frame and its out-of-flow and inflow descendants.
+  gfxContext* context = aCtx;
+
+  Rect bounds =
+    NSRectToRect(GetPaintRect(), mFrame->PresContext()->AppUnitsPerDevPixel());
+  bounds.RoundOut();
+  context->Clip(bounds);
+
+  imgDrawingParams imgParams(aBuilder->ShouldSyncDecodeImages()
+                               ? imgIContainer::FLAG_SYNC_DECODE
+                               : imgIContainer::FLAG_SYNC_DECODE_IF_FAST);
+  nsRect borderArea = nsRect(ToReferenceFrame(), mFrame->GetSize());
+  nsSVGIntegrationUtils::PaintFramesParams params(*aCtx,
+                                                  mFrame,
+                                                  GetPaintRect(),
+                                                  borderArea,
+                                                  aBuilder,
+                                                  nullptr,
+                                                  mHandleOpacity,
+                                                  imgParams);
+
+  ComputeMaskGeometry(params);
+
+  nsSVGIntegrationUtils::PaintMaskAndClipPath(params, aPaintChildren);
+
+  context->PopClip();
+
+  nsDisplayMaskGeometry::UpdateDrawResult(this, imgParams.result);
+}
+
+
 bool
 nsDisplayMask::CreateWebRenderCommands(
   mozilla::wr::DisplayListBuilder& aBuilder,
diff --git a/layout/painting/nsDisplayList.h b/layout/painting/nsDisplayList.h
index 8a19c3b2b1d4f64c2b7d45ba8088963a24d096f9..d99f96f882d46c42f91038074b06a9d3fc29c00a 100644
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -6784,10 +6784,17 @@ public:
   void PrintEffects(nsACString& aTo);
 #endif
 
+  bool IsValidMask();
+
   void PaintAsLayer(nsDisplayListBuilder* aBuilder,
                     gfxContext* aCtx,
                     LayerManager* aManager);
 
+  void PaintWithContentsPaintCallback(nsDisplayListBuilder* aBuilder,
+                                      gfxContext* aCtx,
+                                      const std::function<void()>& aPaintChildren);
+
+
   /*
    * Paint mask onto aMaskContext in mFrame's coordinate space and
    * return whether the mask layer was painted successfully.
diff --git a/layout/style/ServoBindings.cpp b/layout/style/ServoBindings.cpp
index a3c994fe60e473739496d5ddff2bb6827682eb5e..e1547eff8fb69353498b030c17027d24b00f5075 100644
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -2384,8 +2384,7 @@ Gecko_CSSValue_SetFontWeight(nsCSSValueBorrowedMut aCSSValue,
 void
 Gecko_nsStyleFont_SetLang(nsStyleFont* aFont, nsAtom* aAtom)
 {
-  already_AddRefed<nsAtom> atom = already_AddRefed<nsAtom>(aAtom);
-  aFont->mLanguage = atom;
+  aFont->mLanguage = dont_AddRef(aAtom);
   aFont->mExplicitLanguage = true;
 }
 
diff --git a/layout/style/test/mochitest.ini b/layout/style/test/mochitest.ini
index b23deb4521488725ca526edf7596fa3bfe512219..99e05dbfca6708a2f2b73e7436df9d272c63f0a7 100644
--- a/layout/style/test/mochitest.ini
+++ b/layout/style/test/mochitest.ini
@@ -252,6 +252,9 @@ skip-if = toolkit == 'android'
 [test_load_events_on_stylesheets.html]
 support-files = slow_broken_sheet.sjs slow_ok_sheet.sjs
 [test_logical_properties.html]
+[test_mask_image_CORS.html]
+support-files =
+  support/blue-100x100.png
 [test_media_queries.html]
 skip-if = android_version == '18' #debug-only failure; timed out #Android 4.3 aws only; bug 1030419
 [test_media_queries_dynamic.html]
diff --git a/layout/style/test/support/blue-100x100.png b/layout/style/test/support/blue-100x100.png
new file mode 100644
index 0000000000000000000000000000000000000000..3b72d5ce53c07b68fe508bb57aa61a933dbda768
Binary files /dev/null and b/layout/style/test/support/blue-100x100.png differ
diff --git a/layout/style/test/test_mask_image_CORS.html b/layout/style/test/test_mask_image_CORS.html
new file mode 100644
index 0000000000000000000000000000000000000000..8edd8af48e0395894a4b6992005d372622966059
--- /dev/null
+++ b/layout/style/test/test_mask_image_CORS.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Test mask-image CORS anonymous retrieval</title>
+<link rel="stylesheet" href="/tests/SimpleTest/test.css">
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<script src="/tests/SimpleTest/WindowSnapshot.js"></script>
+<style>
+.block100 {
+  width: 100px;
+  height: 100px;
+}
+#allow {
+  /*
+   * shape-outside is unnecessary for the mask, but using it ensures that the first frame
+   * of the image is decoded and reflow is called before onload is fired. Since the
+   * shape-outside uses the same url as the mask, this ensures that the css image resource
+   * is decoded and available for the repaint triggered by the call to snapshotRect.
+   */
+  shape-outside: url("support/blue-100x100.png");
+  mask-image: url("support/blue-100x100.png");
+  background-color: #00FF00
+}
+#refuse {
+  shape-outside: url("http://example.com/tests/layout/style/test/support/blue-100x100.png");
+  mask-image: url("http://example.com/tests/layout/style/test/support/blue-100x100.png");
+  background-color: #FF0000
+}
+</style>
+
+<script>
+SimpleTest.waitForExplicitFinish();
+
+function checkBothSquares() {
+  checkIsColor("allow", "0,255,0,255");
+  checkIsColor("refuse", "255,255,255,255");
+
+  SimpleTest.finish();
+}
+
+function checkIsColor(elementId, color) {
+  let e = document.getElementById(elementId);
+  let r = e.getBoundingClientRect();
+  info("Element " + elementId + " has rect " + r.top + ", " + r.left + ", " + r.width + ", " + r.height + ".");
+
+  let canvas = snapshotRect(window, r);
+  let context = canvas.getContext('2d');
+
+  // Only check the top left pixel.
+  let image = context.getImageData(0, 0, 1, 1);
+  let pixel = image.data.toString();
+  is(pixel, color, "Element " + elementId + " has expected color.");
+}
+</script>
+
+</head>
+<body onload="checkBothSquares()">
+  <p>There should be a green square, but no red square.</p>
+  <div id="allow" class="block100"></div>
+  <div id="refuse" class="block100"></div>
+</body>
+</html>
diff --git a/layout/svg/nsSVGIntegrationUtils.cpp b/layout/svg/nsSVGIntegrationUtils.cpp
index 6beb06f045e86342f9c8fc632b24dfeec48d3b11..f1819751bdb159b5a2125554e561322a113c3de4 100644
--- a/layout/svg/nsSVGIntegrationUtils.cpp
+++ b/layout/svg/nsSVGIntegrationUtils.cpp
@@ -862,10 +862,10 @@ nsSVGIntegrationUtils::PaintMask(const PaintFramesParams& aParams)
   return true;
 }
 
-void
-nsSVGIntegrationUtils::PaintMaskAndClipPath(const PaintFramesParams& aParams)
+template<class T>
+void PaintMaskAndClipPathInternal(const PaintFramesParams& aParams, const T& aPaintChild)
 {
-  MOZ_ASSERT(UsingMaskOrClipPathForFrame(aParams.frame),
+  MOZ_ASSERT(nsSVGIntegrationUtils::UsingMaskOrClipPathForFrame(aParams.frame),
              "Should not use this method when no mask or clipPath effect"
              "on this frame");
 
@@ -982,7 +982,7 @@ nsSVGIntegrationUtils::PaintMaskAndClipPath(const PaintFramesParams& aParams)
     }
 
     if (shouldPushMask) {
-      if (aParams.layerManager->GetRoot()->GetContentFlags() &
+      if (aParams.layerManager && aParams.layerManager->GetRoot()->GetContentFlags() &
           Layer::CONTENT_COMPONENT_ALPHA) {
         context.PushGroupAndCopyBackground(gfxContentType::COLOR_ALPHA,
                                            opacityApplied
@@ -1016,12 +1016,7 @@ nsSVGIntegrationUtils::PaintMaskAndClipPath(const PaintFramesParams& aParams)
 
   /* Paint the child */
   context.SetMatrix(matrixAutoSaveRestore.Matrix());
-  BasicLayerManager* basic = aParams.layerManager->AsBasicLayerManager();
-  RefPtr<gfxContext> oldCtx = basic->GetTarget();
-  basic->SetTarget(&context);
-  aParams.layerManager->EndTransaction(FrameLayerBuilder::DrawPaintedLayer,
-                                       aParams.builder);
-  basic->SetTarget(oldCtx);
+  aPaintChild();
 
   if (gfxPrefs::DrawMaskLayer()) {
     gfxContextAutoSaveRestore saver(&context);
@@ -1058,6 +1053,27 @@ nsSVGIntegrationUtils::PaintMaskAndClipPath(const PaintFramesParams& aParams)
 
 }
 
+
+void
+nsSVGIntegrationUtils::PaintMaskAndClipPath(const PaintFramesParams& aParams)
+{
+  PaintMaskAndClipPathInternal(aParams, [&] {
+    gfxContext& context = aParams.ctx;
+    BasicLayerManager* basic = aParams.layerManager->AsBasicLayerManager();
+    RefPtr<gfxContext> oldCtx = basic->GetTarget();
+    basic->SetTarget(&context);
+    aParams.layerManager->EndTransaction(FrameLayerBuilder::DrawPaintedLayer,
+                                         aParams.builder);
+    basic->SetTarget(oldCtx);
+  });
+}
+
+void
+nsSVGIntegrationUtils::PaintMaskAndClipPath(const PaintFramesParams& aParams, const std::function<void()>& aPaintChild)
+{
+  PaintMaskAndClipPathInternal(aParams, aPaintChild);
+}
+
 void
 nsSVGIntegrationUtils::PaintFilter(const PaintFramesParams& aParams)
 {
diff --git a/layout/svg/nsSVGIntegrationUtils.h b/layout/svg/nsSVGIntegrationUtils.h
index 1a74cece2414da27e9354a6f151ed582f4082702..d04e515c232e5b2400908086091e919f62f1d6e2 100644
--- a/layout/svg/nsSVGIntegrationUtils.h
+++ b/layout/svg/nsSVGIntegrationUtils.h
@@ -166,6 +166,11 @@ public:
   static void
   PaintMaskAndClipPath(const PaintFramesParams& aParams);
 
+  // This should use FunctionRef instead of std::function because we don't need
+  // to take ownership of the function. See bug 1490781.
+  static void
+  PaintMaskAndClipPath(const PaintFramesParams& aParams, const std::function<void()>& aPaintChild);
+
   /**
    * Paint mask of non-SVG frame onto a given context, aParams.ctx.
    * aParams.ctx must contain an A8 surface. Returns false if the mask
diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java
index 3439cf3e7164a9ee707c9458c7a329e3032184f8..1b68152a7bcc5112254d6f950523dff676b76ad7 100644
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java
@@ -708,6 +708,7 @@ public final class GeckoSession extends LayerSession
         @WrapForJNI(dispatchTo = "proxy")
         public static native void open(Window instance, NativeQueue queue,
                                        Compositor compositor, EventDispatcher dispatcher,
+                                       SessionAccessibility.NativeProvider sessionAccessibility,
                                        GeckoBundle initData, String id, String chromeUri,
                                        int screenId, boolean privateMode);
 
@@ -756,6 +757,7 @@ public final class GeckoSession extends LayerSession
         public synchronized void transfer(final NativeQueue queue,
                                           final Compositor compositor,
                                           final EventDispatcher dispatcher,
+                                          final SessionAccessibility.NativeProvider sessionAccessibility,
                                           final GeckoBundle initData) {
             if (mNativeQueue == null) {
                 // Already closed.
@@ -763,13 +765,14 @@ public final class GeckoSession extends LayerSession
             }
 
             if (GeckoThread.isStateAtLeast(GeckoThread.State.PROFILE_READY)) {
-                nativeTransfer(queue, compositor, dispatcher, initData);
+                nativeTransfer(queue, compositor, dispatcher, sessionAccessibility, initData);
             } else {
                 GeckoThread.queueNativeCallUntil(GeckoThread.State.PROFILE_READY,
                         this, "nativeTransfer",
                         NativeQueue.class, queue,
                         Compositor.class, compositor,
                         EventDispatcher.class, dispatcher,
+                        SessionAccessibility.NativeProvider.class, sessionAccessibility,
                         GeckoBundle.class, initData);
             }
 
@@ -783,12 +786,17 @@ public final class GeckoSession extends LayerSession
 
         @WrapForJNI(dispatchTo = "proxy", stubName = "Transfer")
         private native void nativeTransfer(NativeQueue queue, Compositor compositor,
-                                           EventDispatcher dispatcher, GeckoBundle initData);
+                                           EventDispatcher dispatcher,
+                                           SessionAccessibility.NativeProvider sessionAccessibility,
+                                           GeckoBundle initData);
 
         @WrapForJNI(dispatchTo = "proxy")
         public native void attachEditable(IGeckoEditableParent parent,
                                           GeckoEditableChild child);
 
+        @WrapForJNI(dispatchTo = "proxy")
+        public native void attachAccessibility(SessionAccessibility.NativeProvider sessionAccessibility);
+
         @WrapForJNI(calledFrom = "gecko")
         private synchronized void onReady(final @Nullable NativeQueue queue) {
             // onReady is called the first time the Gecko window is ready, with a null queue
@@ -876,7 +884,8 @@ public final class GeckoSession extends LayerSession
 
         if (mWindow != null) {
             mWindow.transfer(mNativeQueue, mCompositor,
-                             mEventDispatcher, createInitData());
+                             mEventDispatcher, mAccessibility != null ? mAccessibility.nativeProvider : null,
+                             createInitData());
 
             onWindowChanged(WINDOW_TRANSFER_IN, /* inProgress */ false);
         }
@@ -1003,6 +1012,7 @@ public final class GeckoSession extends LayerSession
 
         if (GeckoThread.isStateAtLeast(GeckoThread.State.PROFILE_READY)) {
             Window.open(mWindow, mNativeQueue, mCompositor, mEventDispatcher,
+                        mAccessibility != null ? mAccessibility.nativeProvider : null,
                         createInitData(), mId, chromeUri, screenId, isPrivate);
         } else {
             GeckoThread.queueNativeCallUntil(
@@ -1012,6 +1022,8 @@ public final class GeckoSession extends LayerSession
                 NativeQueue.class, mNativeQueue,
                 Compositor.class, mCompositor,
                 EventDispatcher.class, mEventDispatcher,
+                SessionAccessibility.NativeProvider.class,
+                mAccessibility != null ? mAccessibility.nativeProvider : null,
                 GeckoBundle.class, createInitData(),
                 String.class, mId,
                 String.class, chromeUri,
@@ -1076,8 +1088,18 @@ public final class GeckoSession extends LayerSession
       * @return SessionAccessibility instance.
       */
     public @NonNull SessionAccessibility getAccessibility() {
-        if (mAccessibility == null) {
-            mAccessibility = new SessionAccessibility(this);
+        ThreadUtils.assertOnUiThread();
+        if (mAccessibility != null) { return mAccessibility; }
+
+        mAccessibility = new SessionAccessibility(this);
+        if (mWindow != null) {
+            if (GeckoThread.isStateAtLeast(GeckoThread.State.PROFILE_READY)) {
+                mWindow.attachAccessibility(mAccessibility.nativeProvider);
+            } else {
+                GeckoThread.queueNativeCallUntil(GeckoThread.State.PROFILE_READY,
+                        mWindow, "attachAccessibility",
+                        SessionAccessibility.NativeProvider.class, mAccessibility.nativeProvider);
+            }
         }
         return mAccessibility;
     }
diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/SessionAccessibility.java b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/SessionAccessibility.java
index b6624a7d038da2d8b35a985c32da5679ebcbcff5..e302c4417c31013a543432c25dcbdfa50a845107 100644
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/SessionAccessibility.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/SessionAccessibility.java
@@ -5,12 +5,14 @@
 
 package org.mozilla.geckoview;
 
+import org.mozilla.gecko.annotation.WrapForJNI;
 import org.mozilla.gecko.EventDispatcher;
 import org.mozilla.gecko.GeckoAppShell;
 import org.mozilla.gecko.PrefsHelper;
 import org.mozilla.gecko.util.BundleEventListener;
 import org.mozilla.gecko.util.EventCallback;
 import org.mozilla.gecko.util.GeckoBundle;
+import org.mozilla.gecko.mozglue.JNIObject;
 
 import android.content.Context;
 import android.graphics.Matrix;
@@ -232,6 +234,8 @@ public class SessionAccessibility {
     /* package */  final GeckoSession mSession;
     // This is the view that delegates accessibility to us. We also sends event through it.
     private View mView;
+    // The native portion of the node provider.
+    /* package */ final NativeProvider nativeProvider = new NativeProvider();
     // Have we reached the last item in content?
     private boolean mLastItem;
     // Used to store the JSON message and populate the event later in the code path.
@@ -241,6 +245,8 @@ public class SessionAccessibility {
     private SparseArray<EventCallback> mAutoFillRoots;
     private int mAutoFillFocusedId = View.NO_ID;
 
+    private boolean mAttached = false;
+
     /* package */ SessionAccessibility(final GeckoSession session) {
         mSession = session;
 
@@ -803,4 +809,20 @@ public class SessionAccessibility {
             ((ViewParent) mView).requestSendAccessibilityEvent(mView, event);
         }
     }
+
+    /* package */ final class NativeProvider extends JNIObject {
+        @WrapForJNI(calledFrom = "ui")
+        private void setAttached(final boolean attached) {
+            if (attached) {
+                mAttached = true;
+            } else if (mAttached) {
+                mAttached = false;
+                disposeNative();
+            }
+        }
+
+        @WrapForJNI(calledFrom = "ui", dispatchTo = "gecko")
+        @Override
+        protected native void disposeNative();
+    }
 }
diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js
index deb866013f6d4a841b8c57d314ce813aefc82601..70748c986c1ee49ddc5eb1453a95b7a54131c774 100644
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -2266,7 +2266,6 @@ pref("network.cookie.thirdparty.sessionOnly", false);
 pref("network.cookie.thirdparty.nonsecureSessionOnly", false);
 pref("network.cookie.leave-secure-alone",   true);
 pref("network.cookie.same-site.enabled",    true); // Honor the SameSite cookie attribute
-pref("network.cookie.ipc.sync",             false);
 
 // Cookie lifetime policy. Possible values:
 // 0 - accept all cookies
diff --git a/netwerk/base/AutoClose.h b/netwerk/base/AutoClose.h
index 43ab27133fdd80ef37738b739f185643dcf67ab5..57979921b46162252f81700876442bb3907b0cca 100644
--- a/netwerk/base/AutoClose.h
+++ b/netwerk/base/AutoClose.h
@@ -38,8 +38,7 @@ public:
 
   void takeOver(nsCOMPtr<T> & rhs)
   {
-    already_AddRefed<T> other = rhs.forget();
-    TakeOverInternal(&other);
+    TakeOverInternal(rhs.forget());
   }
 
   void CloseAndRelease()
@@ -48,15 +47,12 @@ public:
   }
 
 private:
-  void TakeOverInternal(already_AddRefed<T> *aOther)
+  void TakeOverInternal(already_AddRefed<T>&& aOther)
   {
-    nsCOMPtr<T> ptr;
+    nsCOMPtr<T> ptr(std::move(aOther));
     {
       MutexAutoLock lock(mMutex);
       ptr.swap(mPtr);
-      if (aOther) {
-        mPtr = *aOther;
-      }
     }
 
     if (ptr) {
diff --git a/netwerk/cookie/CookieServiceChild.cpp b/netwerk/cookie/CookieServiceChild.cpp
index 1cb7e96c0a90ff98c644034d84a09832de995f94..a31a8f1c78fad492a6ec3f495fe60aa5bb742c9b 100644
--- a/netwerk/cookie/CookieServiceChild.cpp
+++ b/netwerk/cookie/CookieServiceChild.cpp
@@ -40,7 +40,6 @@ static const char kPrefThirdPartySession[] =
   "network.cookie.thirdparty.sessionOnly";
 static const char kPrefThirdPartyNonsecureSession[] =
   "network.cookie.thirdparty.nonsecureSessionOnly";
-static const char kPrefCookieIPCSync[] = "network.cookie.ipc.sync";
 static const char kCookieLeaveSecurityAlone[] = "network.cookie.leave-secure-alone";
 static const char kCookieMoveIntervalSecs[] = "network.cookie.move.interval_sec";
 
@@ -69,7 +68,6 @@ CookieServiceChild::CookieServiceChild()
   , mThirdPartySession(false)
   , mThirdPartyNonsecureSession(false)
   , mLeaveSecureAlone(true)
-  , mIPCSync(false)
   , mIPCOpen(false)
 {
   NS_ASSERTION(IsNeckoChild(), "not a child process");
@@ -101,7 +99,6 @@ CookieServiceChild::CookieServiceChild()
     prefBranch->AddObserver(kPrefCookieBehavior, this, true);
     prefBranch->AddObserver(kPrefThirdPartySession, this, true);
     prefBranch->AddObserver(kPrefThirdPartyNonsecureSession, this, true);
-    prefBranch->AddObserver(kPrefCookieIPCSync, this, true);
     prefBranch->AddObserver(kCookieLeaveSecurityAlone, this, true);
     prefBranch->AddObserver(kCookieMoveIntervalSecs, this, true);
     PrefChanged(prefBranch);
@@ -314,9 +311,6 @@ CookieServiceChild::PrefChanged(nsIPrefBranch *aPrefBranch)
                                             &boolval)))
     mThirdPartyNonsecureSession = boolval;
 
-  if (NS_SUCCEEDED(aPrefBranch->GetBoolPref(kPrefCookieIPCSync, &boolval)))
-    mIPCSync = !!boolval;
-
   if (NS_SUCCEEDED(aPrefBranch->GetBoolPref(kCookieLeaveSecurityAlone, &boolval)))
     mLeaveSecureAlone = !!boolval;
 
@@ -440,24 +434,6 @@ CookieServiceChild::GetCookieStringFromCookieHashTable(nsIURI                 *a
   }
 }
 
-void
-CookieServiceChild::GetCookieStringSyncIPC(nsIURI                 *aHostURI,
-                                           bool                   aIsForeign,
-                                           bool                   aIsTrackingResource,
-                                           bool                   aFirstPartyStorageAccessGranted,
-                                           bool                   aIsSafeTopLevelNav,
-                                           bool                   aIsSameSiteForeign,
-                                           const OriginAttributes &aAttrs,
-                                           nsAutoCString          &aCookieString)
-{
-  URIParams uriParams;
-  SerializeURI(aHostURI, uriParams);
-
-  SendGetCookieString(uriParams, aIsForeign, aIsTrackingResource,
-                      aFirstPartyStorageAccessGranted, aIsSafeTopLevelNav,
-                      aIsSameSiteForeign, aAttrs, &aCookieString);
-}
-
 uint32_t
 CookieServiceChild::CountCookiesFromHashTable(const nsCString &aBaseDomain,
                                               const OriginAttributes &aOriginAttrs)
@@ -601,18 +577,9 @@ CookieServiceChild::GetCookieStringInternal(nsIURI *aHostURI,
   bool isSameSiteForeign = NS_IsSameSiteForeign(aChannel, aHostURI);
 
   nsAutoCString result;
-  if (!mIPCSync) {
-    GetCookieStringFromCookieHashTable(aHostURI, isForeign, isTrackingResource,
-                                       firstPartyStorageAccessGranted, isSafeTopLevelNav,
-                                       isSameSiteForeign, attrs, result);
-  } else {
-    if (!mIPCOpen) {
-      return NS_ERROR_NOT_AVAILABLE;
-    }
-    GetCookieStringSyncIPC(aHostURI, isForeign, isTrackingResource,
-                           firstPartyStorageAccessGranted, isSafeTopLevelNav,
-                           isSameSiteForeign, attrs, result);
-  }
+  GetCookieStringFromCookieHashTable(aHostURI, isForeign, isTrackingResource,
+                                     firstPartyStorageAccessGranted, isSafeTopLevelNav,
+                                     isSameSiteForeign, attrs, result);
 
   if (!result.IsEmpty())
     *aCookieString = ToNewCString(result);
@@ -689,10 +656,6 @@ CookieServiceChild::SetCookieStringInternal(nsIURI *aHostURI,
                         stringServerTime, attrs, aFromHttp);
   }
 
-  if (mIPCSync) {
-    return NS_OK;
-  }
-
   bool requireHostMatch;
   nsCString baseDomain;
   nsCookieService::
diff --git a/netwerk/cookie/CookieServiceChild.h b/netwerk/cookie/CookieServiceChild.h
index 2d6152b57eb4643876a0ae75997f58665b920c44..5008df4f6a7eafad4cbdddb9edbacf7b3e10e520 100644
--- a/netwerk/cookie/CookieServiceChild.h
+++ b/netwerk/cookie/CookieServiceChild.h
@@ -72,16 +72,6 @@ protected:
                                           const OriginAttributes &aAttrs,
                                           nsCString &aCookieString);
 
-  void
-  GetCookieStringSyncIPC(nsIURI                 *aHostURI,
-                         bool                    aIsForeign,
-                         bool                    aIsTrackingResource,
-                         bool                    aFirstPartyStorageAccessGranted,
-                         bool                    aIsSafeTopLevelNav,
-                         bool                    aIsSameSiteForeign,
-                         const OriginAttributes &aAttrs,
-                         nsAutoCString          &aCookieString);
-
   nsresult SetCookieStringInternal(nsIURI *aHostURI,
                                    nsIChannel *aChannel,
                                    const char *aCookieString,
@@ -136,7 +126,6 @@ protected:
   bool mThirdPartySession;
   bool mThirdPartyNonsecureSession;
   bool mLeaveSecureAlone;
-  bool mIPCSync;
   bool mIPCOpen;
 };
 
diff --git a/netwerk/cookie/CookieServiceParent.cpp b/netwerk/cookie/CookieServiceParent.cpp
index 68d726cb35ef400afd1bdd7ec4b44484229ad82e..cc7291f006b021e1c1aac1ef08cbb9a5002a1f8c 100644
--- a/netwerk/cookie/CookieServiceParent.cpp
+++ b/netwerk/cookie/CookieServiceParent.cpp
@@ -233,30 +233,6 @@ CookieServiceParent::ActorDestroy(ActorDestroyReason aWhy)
   // non-refcounted class.
 }
 
-mozilla::ipc::IPCResult
-CookieServiceParent::RecvGetCookieString(const URIParams& aHost,
-                                         const bool& aIsForeign,
-                                         const bool& aIsTrackingResource,
-                                         const bool& aFirstPartyStorageAccessGranted,
-                                         const bool& aIsSafeTopLevelNav,
-                                         const bool& aIsSameSiteForeign,
-                                         const OriginAttributes& aAttrs,
-                                         nsCString* aResult)
-{
-  if (!mCookieService)
-    return IPC_OK();
-
-  // Deserialize URI. Having a host URI is mandatory and should always be
-  // provided by the child; thus we consider failure fatal.
-  nsCOMPtr<nsIURI> hostURI = DeserializeURI(aHost);
-  if (!hostURI)
-    return IPC_FAIL_NO_REASON(this);
-  mCookieService->GetCookieStringInternal(hostURI, aIsForeign, aIsTrackingResource,
-                                          aFirstPartyStorageAccessGranted, aIsSafeTopLevelNav,
-                                          aIsSameSiteForeign, false, aAttrs, *aResult);
-  return IPC_OK();
-}
-
 mozilla::ipc::IPCResult
 CookieServiceParent::RecvSetCookieString(const URIParams& aHost,
                                          const OptionalURIParams& aChannelURI,
diff --git a/netwerk/cookie/CookieServiceParent.h b/netwerk/cookie/CookieServiceParent.h
index 84b81eb419b4676c452032f48b640b666c6e1a46..68f3285c8f074a8c4f2a31f55477e3a8abdd56ad 100644
--- a/netwerk/cookie/CookieServiceParent.h
+++ b/netwerk/cookie/CookieServiceParent.h
@@ -40,15 +40,6 @@ public:
 protected:
   virtual void ActorDestroy(ActorDestroyReason aWhy) override;
 
-  virtual mozilla::ipc::IPCResult RecvGetCookieString(const URIParams& aHost,
-                                                      const bool& aIsForeign,
-                                                      const bool& aIsTrackingResource,
-                                                      const bool& aFirstPartyStorageAccessGranted,
-                                                      const bool& aIsSafeTopLevelNav,
-                                                      const bool& aIsSameSiteForeign,
-                                                      const OriginAttributes& aAttrs,
-                                                      nsCString* aResult) override;
-
   virtual mozilla::ipc::IPCResult RecvSetCookieString(const URIParams& aHost,
                                                       const OptionalURIParams& aChannelURI,
                                                       const bool& aIsForeign,
diff --git a/netwerk/cookie/PCookieService.ipdl b/netwerk/cookie/PCookieService.ipdl
index ae9ba9c093fe48cef6b77bca55345c2a30403d90..344bbe08ffb904ba2eec47beda68ffad9b2e7721 100644
--- a/netwerk/cookie/PCookieService.ipdl
+++ b/netwerk/cookie/PCookieService.ipdl
@@ -33,52 +33,6 @@ nested(upto inside_cpow) sync protocol PCookieService
 
 parent:
 
-  /*
-   * Get the complete cookie string associated with the URI. This is a sync
-   * call in order to avoid race conditions -- for instance, an HTTP response
-   * on the parent and script access on the child.
-   *
-   * @param host
-   *        Same as the 'aURI' argument to nsICookieService.getCookieString.
-   * @param isForeign
-   *        True if the the request is third party, for purposes of allowing
-   *        access to cookies. This should be obtained from
-   *        mozIThirdPartyUtil.isThirdPartyChannel. Third party requests may be
-   *        rejected depending on user preferences; if those checks are
-   *        disabled, this parameter is ignored.
-   * @param isTrackingResource
-   *        True if the request has been marked as tracking.
-   * @param firstPartyStorageAccessGranted
-   *        True if host has storage access granted. Note that the storage
-   *        access is automatically granted also if the channel is not marked as
-   *        tracking resource, or if it's not a 3rd party context.
-   * @param isSafeTopLevelNav
-   *        True for safe methods like e.g. GET.
-   * @param isSameSiteForeign
-   *        True if the same-site cookie originates from a cross-site context.
-   * @param fromHttp
-   *        Whether the result is for an HTTP request header. This should be
-   *        true for nsICookieService.getCookieStringFromHttp calls, false
-   *        otherwise.
-   * @param attrs
-   *        The origin attributes from the HTTP channel or document that the
-   *        cookie is being set on.
-   *
-   * @see nsICookieService.getCookieString
-   * @see nsICookieService.getCookieStringFromHttp
-   * @see mozIThirdPartyUtil.isThirdPartyChannel
-   *
-   * @return the resulting cookie string.
-   */
-  nested(inside_cpow) sync GetCookieString(URIParams host,
-                                           bool isForeign,
-                                           bool isTrackingResource,
-                                           bool firstPartyStorageAccessGranted,
-                                           bool isSafeTopLevelNav,
-                                           bool isSameSiteForeign,
-                                           OriginAttributes attrs)
-       returns (nsCString result);
-
   /*
    * Set a cookie string.
    *
diff --git a/netwerk/protocol/http/HttpChannelParent.cpp b/netwerk/protocol/http/HttpChannelParent.cpp
index 030c1d4087671dfb4c31fe066a8bdb28cb055acf..f918b271604301d832c3be31f9fe2596e46166a6 100644
--- a/netwerk/protocol/http/HttpChannelParent.cpp
+++ b/netwerk/protocol/http/HttpChannelParent.cpp
@@ -734,10 +734,10 @@ HttpChannelParent::WaitForBgParent()
   registrar->LinkHttpChannel(mChannel->ChannelId(), this);
 
   if (mBgParent) {
-    already_AddRefed<GenericPromise> promise = mPromise.Ensure(__func__);
+    RefPtr<GenericPromise> promise = mPromise.Ensure(__func__);
     // resolve promise immediatedly if bg channel is ready.
     mPromise.Resolve(true, __func__);
-    return promise;
+    return promise.forget();
   }
 
   return mPromise.Ensure(__func__);;
diff --git a/netwerk/test/unit_ipc/test_bug528292_wrap.js b/netwerk/test/unit_ipc/test_bug528292_wrap.js
index 61e925839b8a95ad26583e525f2503076a5bc044..e91343da5f2800e988635d717b4c993f1b9ae2ed 100644
--- a/netwerk/test/unit_ipc/test_bug528292_wrap.js
+++ b/netwerk/test/unit_ipc/test_bug528292_wrap.js
@@ -1,7 +1,6 @@
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 function run_test() {
-  Services.prefs.setBoolPref("network.cookie.ipc.sync", true);
   Services.prefs.setIntPref("network.cookie.cookieBehavior", 1);
   run_test_in_child("../unit/test_bug528292.js");
 }
diff --git a/netwerk/test/unit_ipc/test_multipart_streamconv_wrap.js b/netwerk/test/unit_ipc/test_multipart_streamconv_wrap.js
index 2d16d50266526d75c56fdbbc075370500b5c545d..2d2c4fee3e0e00643a3b8b3f2488fa9f98a1eb8b 100644
--- a/netwerk/test/unit_ipc/test_multipart_streamconv_wrap.js
+++ b/netwerk/test/unit_ipc/test_multipart_streamconv_wrap.js
@@ -1,5 +1,4 @@
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 function run_test() {
-  Services.prefs.setBoolPref("network.cookie.ipc.sync", true);
   run_test_in_child("../unit/test_multipart_streamconv.js");
 }
diff --git a/servo/components/style/properties/longhands/svg.mako.rs b/servo/components/style/properties/longhands/svg.mako.rs
index 36105247676e24eb9f1cffc7ef9a0da3cb52239c..acdb809135f103180beac6aa7f8d101be837a2f4 100644
--- a/servo/components/style/properties/longhands/svg.mako.rs
+++ b/servo/components/style/properties/longhands/svg.mako.rs
@@ -183,6 +183,7 @@ ${helpers.predefined_type(
     "ImageLayer",
     "Either::First(None_)",
     initial_specified_value="Either::First(None_)",
+    parse_method="parse_with_cors_anonymous",
     spec="https://drafts.fxtf.org/css-masking/#propdef-mask-image",
     vector=True,
     products="gecko",
diff --git a/servo/components/style/values/specified/image.rs b/servo/components/style/values/specified/image.rs
index 1b080816e83ad484f9dfdd2cf75014b1adbb720a..b1a611846a8a6f12684004aacef8865c0c1d9635 100644
--- a/servo/components/style/values/specified/image.rs
+++ b/servo/components/style/values/specified/image.rs
@@ -33,6 +33,20 @@ use values::specified::url::SpecifiedImageUrl;
 /// A specified image layer.
 pub type ImageLayer = Either<None_, Image>;
 
+impl ImageLayer {
+    /// This is a specialization of Either with an alternative parse
+    /// method to provide anonymous CORS headers for the Image url fetch.
+    pub fn parse_with_cors_anonymous<'i, 't>(
+        context: &ParserContext,
+        input: &mut Parser<'i, 't>,
+    ) -> Result<Self, ParseError<'i>> {
+        if let Ok(v) = input.try(|i| None_::parse(context, i)) {
+            return Ok(Either::First(v));
+        }
+        Image::parse_with_cors_anonymous(context, input).map(Either::Second)
+    }
+}
+
 /// Specified values for an image according to CSS-IMAGES.
 /// <https://drafts.csswg.org/css-images/#image-values>
 pub type Image = generic::Image<Gradient, MozImageRect, SpecifiedImageUrl>;
diff --git a/testing/marionette/action.js b/testing/marionette/action.js
index a6cbd33a02d3fdb48b899cefa81505cd8fb40735..87e7754f0ad2551834bda65701fabf67734d3d59 100644
--- a/testing/marionette/action.js
+++ b/testing/marionette/action.js
@@ -973,7 +973,7 @@ action.Mouse = class {
  * @param {action.Chain} chain
  *     Actions grouped by tick; each element in |chain| is a sequence of
  *     actions for one tick.
- * @param {WindowProxy} window
+ * @param {WindowProxy} win
  *     Current window global.
  * @param {boolean=} [specCompatPointerOrigin=true] specCompatPointerOrigin
  *     Flag to turn off the WebDriver spec conforming pointer origin
@@ -984,7 +984,7 @@ action.Mouse = class {
  * @return {Promise}
  *     Promise for dispatching all actions in |chain|.
  */
-action.dispatch = function(chain, window, specCompatPointerOrigin = true) {
+action.dispatch = function(chain, win, specCompatPointerOrigin = true) {
   action.specCompatPointerOrigin = specCompatPointerOrigin;
 
   let chainEvents = (async () => {
@@ -992,7 +992,7 @@ action.dispatch = function(chain, window, specCompatPointerOrigin = true) {
       await action.dispatchTickActions(
           tickActions,
           action.computeTickDuration(tickActions),
-          window);
+          win);
     }
   })();
   return chainEvents;
@@ -1013,14 +1013,14 @@ action.dispatch = function(chain, window, specCompatPointerOrigin = true) {
  *     List of actions for one tick.
  * @param {number} tickDuration
  *     Duration in milliseconds of this tick.
- * @param {WindowProxy} window
+ * @param {WindowProxy} win
  *     Current window global.
  *
  * @return {Promise}
  *     Promise for dispatching all tick-actions and pending DOM events.
  */
-action.dispatchTickActions = function(tickActions, tickDuration, window) {
-  let pendingEvents = tickActions.map(toEvents(tickDuration, window));
+action.dispatchTickActions = function(tickActions, tickDuration, win) {
+  let pendingEvents = tickActions.map(toEvents(tickDuration, win));
   return Promise.all(pendingEvents);
 };
 
@@ -1085,33 +1085,33 @@ action.computePointerDestination = function(
  *
  * @param {number} tickDuration
  *     Duration in milliseconds of this tick.
- * @param {WindowProxy} window
+ * @param {WindowProxy} win
  *     Current window global.
  *
  * @return {function(action.Action): Promise}
  *     Function that takes an action and returns a Promise for dispatching
  *     the event that corresponds to that action.
  */
-function toEvents(tickDuration, window) {
+function toEvents(tickDuration, win) {
   return a => {
     let inputState = action.inputStateMap.get(a.id);
 
     switch (a.subtype) {
       case action.KeyUp:
-        return dispatchKeyUp(a, inputState, window);
+        return dispatchKeyUp(a, inputState, win);
 
       case action.KeyDown:
-        return dispatchKeyDown(a, inputState, window);
+        return dispatchKeyDown(a, inputState, win);
 
       case action.PointerDown:
-        return dispatchPointerDown(a, inputState, window);
+        return dispatchPointerDown(a, inputState, win);
 
       case action.PointerUp:
-        return dispatchPointerUp(a, inputState, window);
+        return dispatchPointerUp(a, inputState, win);
 
       case action.PointerMove:
         return dispatchPointerMove(
-            a, inputState, tickDuration, window);
+            a, inputState, tickDuration, win);
 
       case action.PointerCancel:
         throw new UnsupportedOperationError();
@@ -1131,14 +1131,14 @@ function toEvents(tickDuration, window) {
  *     Action to dispatch.
  * @param {action.InputState} inputState
  *     Input state for this action's input source.
- * @param {WindowProxy} window
+ * @param {WindowProxy} win
  *     Current window global.
  *
  * @return {Promise}
  *     Promise to dispatch at least a keydown event, and keypress if
  *     appropriate.
  */
-function dispatchKeyDown(a, inputState, window) {
+function dispatchKeyDown(a, inputState, win) {
   return new Promise(resolve => {
     let keyEvent = new action.Key(a.value);
     keyEvent.repeat = inputState.isPressed(keyEvent.key);
@@ -1150,7 +1150,7 @@ function dispatchKeyDown(a, inputState, window) {
     // Append a copy of |a| with keyUp subtype
     action.inputsToCancel.push(Object.assign({}, a, {subtype: action.KeyUp}));
     keyEvent.update(inputState);
-    event.sendKeyDown(a.value, keyEvent, window);
+    event.sendKeyDown(a.value, keyEvent, win);
 
     resolve();
   });
@@ -1163,13 +1163,13 @@ function dispatchKeyDown(a, inputState, window) {
  *     Action to dispatch.
  * @param {action.InputState} inputState
  *     Input state for this action's input source.
- * @param {WindowProxy} window
+ * @param {WindowProxy} win
  *     Current window global.
  *
  * @return {Promise}
  *     Promise to dispatch a keyup event.
  */
-function dispatchKeyUp(a, inputState, window) {
+function dispatchKeyUp(a, inputState, win) {
   return new Promise(resolve => {
     let keyEvent = new action.Key(a.value);
 
@@ -1184,7 +1184,7 @@ function dispatchKeyUp(a, inputState, window) {
     inputState.release(keyEvent.key);
     keyEvent.update(inputState);
 
-    event.sendKeyUp(a.value, keyEvent, window);
+    event.sendKeyUp(a.value, keyEvent, win);
     resolve();
   });
 }
@@ -1197,13 +1197,13 @@ function dispatchKeyUp(a, inputState, window) {
  *     Action to dispatch.
  * @param {action.InputState} inputState
  *     Input state for this action's input source.
- * @param {WindowProxy} window
+ * @param {WindowProxy} win
  *     Current window global.
  *
  * @return {Promise}
  *     Promise to dispatch at least a pointerdown event.
  */
-function dispatchPointerDown(a, inputState, window) {
+function dispatchPointerDown(a, inputState, win) {
   return new Promise(resolve => {
     if (inputState.isPressed(a.button)) {
       resolve();
@@ -1232,7 +1232,7 @@ function dispatchPointerDown(a, inputState, window) {
             inputState.x,
             inputState.y,
             mouseEvent,
-            window);
+            win);
         if (event.MouseButton.isSecondary(a.button) ||
             mouseEvent.ctrlKey && Services.appinfo.OS !== "WINNT") {
           let contextMenuEvent = Object.assign({},
@@ -1241,7 +1241,7 @@ function dispatchPointerDown(a, inputState, window) {
               inputState.x,
               inputState.y,
               contextMenuEvent,
-              window);
+              win);
         }
         break;
 
@@ -1265,13 +1265,13 @@ function dispatchPointerDown(a, inputState, window) {
  *     Action to dispatch.
  * @param {action.InputState} inputState
  *     Input state for this action's input source.
- * @param {WindowProxy} window
+ * @param {WindowProxy} win
  *     Current window global.
  *
  * @return {Promise}
  *     Promise to dispatch at least a pointerup event.
  */
-function dispatchPointerUp(a, inputState, window) {
+function dispatchPointerUp(a, inputState, win) {
   return new Promise(resolve => {
     if (!inputState.isPressed(a.button)) {
       resolve();
@@ -1289,7 +1289,7 @@ function dispatchPointerUp(a, inputState, window) {
               mouseEvent, {clickCount: 2});
         }
         event.synthesizeMouseAtPoint(
-            inputState.x, inputState.y, mouseEvent, window);
+            inputState.x, inputState.y, mouseEvent, win);
         break;
 
       case action.PointerType.Pen:
@@ -1317,14 +1317,14 @@ function dispatchPointerUp(a, inputState, window) {
  *     Action to dispatch.
  * @param {action.InputState} inputState
  *     Input state for this action's input source.
- * @param {WindowProxy} window
+ * @param {WindowProxy} win
  *     Current window global.
  *
  * @return {Promise}
  *     Promise to dispatch at least one pointermove event, as well as
  *     mousemove events as appropriate.
  */
-function dispatchPointerMove(a, inputState, tickDuration, window) {
+function dispatchPointerMove(a, inputState, tickDuration, win) {
   const timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
   // interval between pointermove increments in ms, based on common vsync
   const fps60 = 17;
@@ -1333,21 +1333,21 @@ function dispatchPointerMove(a, inputState, tickDuration, window) {
     const start = Date.now();
     const [startX, startY] = [inputState.x, inputState.y];
 
-    let coords = getElementCenter(a.origin, window);
+    let coords = getElementCenter(a.origin, win);
     let target = action.computePointerDestination(a, inputState, coords);
     const [targetX, targetY] = [target.x, target.y];
 
-    if (!inViewPort(targetX, targetY, window)) {
+    if (!inViewPort(targetX, targetY, win)) {
       throw new MoveTargetOutOfBoundsError(
           `(${targetX}, ${targetY}) is out of bounds of viewport ` +
-          `width (${window.innerWidth}) ` +
-          `and height (${window.innerHeight})`);
+          `width (${win.innerWidth}) ` +
+          `and height (${win.innerHeight})`);
     }
 
     const duration = typeof a.duration == "undefined" ? tickDuration : a.duration;
     if (duration === 0) {
       // move pointer to destination in one step
-      performOnePointerMove(inputState, targetX, targetY, window);
+      performOnePointerMove(inputState, targetX, targetY, win);
       resolve();
       return;
     }
@@ -1365,7 +1365,7 @@ function dispatchPointerMove(a, inputState, tickDuration, window) {
       while ((1 - durationRatio) > epsilon) {
         let x = Math.floor(durationRatio * distanceX + startX);
         let y = Math.floor(durationRatio * distanceY + startY);
-        performOnePointerMove(inputState, x, y, window);
+        performOnePointerMove(inputState, x, y, win);
         // wait |fps60| ms before performing next pointer move
         await new Promise(resolveTimer =>
             timer.initWithCallback(resolveTimer, fps60, ONE_SHOT));
@@ -1377,7 +1377,7 @@ function dispatchPointerMove(a, inputState, tickDuration, window) {
     // perform last pointer move after all incremental moves are resolved and
     // durationRatio is close enough to 1
     intermediatePointerEvents.then(() => {
-      performOnePointerMove(inputState, targetX, targetY, window);
+      performOnePointerMove(inputState, targetX, targetY, win);
       resolve();
     }).catch(err => {
       reject(err);
@@ -1441,10 +1441,10 @@ function inViewPort(x, y, win) {
   return !(x < 0 || y < 0 || x > win.innerWidth || y > win.innerHeight);
 }
 
-function getElementCenter(el, window) {
+function getElementCenter(el, win) {
   if (element.isDOMElement(el)) {
     if (action.specCompatPointerOrigin) {
-      return element.getInViewCentrePoint(el.getClientRects()[0], window);
+      return element.getInViewCentrePoint(el.getClientRects()[0], win);
     }
     return element.coordinates(el);
   }
diff --git a/testing/marionette/element.js b/testing/marionette/element.js
index 746d6ae209231b06cfe745b04ddf7fc802b8cf51..d2d94480f543563a9c2222b02737651981bae133 100644
--- a/testing/marionette/element.js
+++ b/testing/marionette/element.js
@@ -201,7 +201,7 @@ element.Store = class {
    * @param {WebElement} webEl
    *     Web element reference to find the associated {@link Element}
    *     of.
-   * @param {WindowProxy} window
+   * @param {WindowProxy} win
    *     Current browsing context, which may differ from the associate
    *     browsing context of <var>el</var>.
    *
@@ -218,7 +218,7 @@ element.Store = class {
    *     attached to the DOM, or its node document is no longer the
    *     active document.
    */
-  get(webEl, window) {
+  get(webEl, win) {
     if (!(webEl instanceof WebElement)) {
       throw new TypeError(
           pprint`Expected web element, got: ${webEl}`);
@@ -236,7 +236,7 @@ element.Store = class {
       delete this.els[webEl.uuid];
     }
 
-    if (element.isStale(el, window)) {
+    if (element.isStale(el, win)) {
       throw new StaleElementReferenceError(
           pprint`The element reference of ${el || webEl.uuid} is stale; ` +
               "either the element is no longer attached to the DOM, " +
@@ -720,7 +720,7 @@ element.isCollection = function(seq) {
  *     DOM element to check for staleness.  If null, which may be
  *     the case if the element has been unwrapped from a weak
  *     reference, it is always considered stale.
- * @param {WindowProxy=} window
+ * @param {WindowProxy=} win
  *     Current browsing context, which may differ from the associate
  *     browsing context of <var>el</var>.  When retrieving XUL
  *     elements, this is optional.
@@ -728,14 +728,14 @@ element.isCollection = function(seq) {
  * @return {boolean}
  *     True if <var>el</var> is stale, false otherwise.
  */
-element.isStale = function(el, window = undefined) {
-  if (typeof window == "undefined") {
-    window = el.ownerGlobal;
+element.isStale = function(el, win = undefined) {
+  if (typeof win == "undefined") {
+    win = el.ownerGlobal;
   }
 
   if (el === null ||
       !el.ownerGlobal ||
-      el.ownerDocument !== window.document) {
+      el.ownerDocument !== win.document) {
     return true;
   }
 
@@ -1146,23 +1146,23 @@ element.isObscured = function(el) {
  * @param {DOMRect} rect
  *     Element off a DOMRect sequence produced by calling
  *     <code>getClientRects</code> on an {@link Element}.
- * @param {WindowProxy} window
+ * @param {WindowProxy} win
  *     Current window global.
  *
  * @return {Map.<string, number>}
  *     X and Y coordinates that denotes the in-view centre point of
  *     <var>rect</var>.
  */
-element.getInViewCentrePoint = function(rect, window) {
+element.getInViewCentrePoint = function(rect, win) {
   const {max, min} = Math;
 
   let x = {
     left: max(0, min(rect.x, rect.x + rect.width)),
-    right: min(window.innerWidth, max(rect.x, rect.x + rect.width)),
+    right: min(win.innerWidth, max(rect.x, rect.x + rect.width)),
   };
   let y = {
     top: max(0, min(rect.y, rect.y + rect.height)),
-    bottom: min(window.innerHeight, max(rect.y, rect.y + rect.height)),
+    bottom: min(win.innerHeight, max(rect.y, rect.y + rect.height)),
   };
 
   return {
diff --git a/testing/marionette/evaluate.js b/testing/marionette/evaluate.js
index fbc0d65f3512bdb71469e22ff57ed0e7f2e43b99..fd64d592de9e58d137948f5923e0a10df089d17a 100644
--- a/testing/marionette/evaluate.js
+++ b/testing/marionette/evaluate.js
@@ -151,7 +151,7 @@ evaluate.sandbox = function(sb, script, args = [],
  * @param {element.Store=} seenEls
  *     Known element store to look up web elements from.  If undefined,
  *     the web element references are returned instead.
- * @param {WindowProxy=} window
+ * @param {WindowProxy=} win
  *     Current browsing context, if `seenEls` is provided.
  *
  * @return {Object}
@@ -166,7 +166,7 @@ evaluate.sandbox = function(sb, script, args = [],
  *     it is no longer attached to the DOM, or its node document
  *     is no longer the active document.
  */
-evaluate.fromJSON = function(obj, seenEls = undefined, window = undefined) {
+evaluate.fromJSON = function(obj, seenEls = undefined, win = undefined) {
   switch (typeof obj) {
     case "boolean":
     case "number":
@@ -180,13 +180,13 @@ evaluate.fromJSON = function(obj, seenEls = undefined, window = undefined) {
 
       // arrays
       } else if (Array.isArray(obj)) {
-        return obj.map(e => evaluate.fromJSON(e, seenEls, window));
+        return obj.map(e => evaluate.fromJSON(e, seenEls, win));
 
       // web elements
       } else if (WebElement.isReference(obj)) {
         let webEl = WebElement.fromJSON(obj);
         if (seenEls) {
-          return seenEls.get(webEl, window);
+          return seenEls.get(webEl, win);
         }
         return webEl;
       }
@@ -194,7 +194,7 @@ evaluate.fromJSON = function(obj, seenEls = undefined, window = undefined) {
       // arbitrary objects
       let rv = {};
       for (let prop in obj) {
-        rv[prop] = evaluate.fromJSON(obj[prop], seenEls, window);
+        rv[prop] = evaluate.fromJSON(obj[prop], seenEls, win);
       }
       return rv;
   }
@@ -418,7 +418,7 @@ sandbox.augment = function(sb, adapter) {
 /**
  * Creates a sandbox.
  *
- * @param {Window} window
+ * @param {Window} win
  *     The DOM Window object.
  * @param {nsIPrincipal=} principal
  *     An optional, custom principal to prefer over the Window.  Useful if
@@ -427,11 +427,11 @@ sandbox.augment = function(sb, adapter) {
  * @return {Sandbox}
  *     The created sandbox.
  */
-sandbox.create = function(window, principal = null, opts = {}) {
-  let p = principal || window;
+sandbox.create = function(win, principal = null, opts = {}) {
+  let p = principal || win;
   opts = Object.assign({
-    sameZoneAs: window,
-    sandboxPrototype: window,
+    sameZoneAs: win,
+    sandboxPrototype: win,
     wantComponents: true,
     wantXrays: true,
   }, opts);
@@ -442,29 +442,29 @@ sandbox.create = function(window, principal = null, opts = {}) {
  * Creates a mutable sandbox, where changes to the global scope
  * will have lasting side-effects.
  *
- * @param {Window} window
+ * @param {Window} win
  *     The DOM Window object.
  *
  * @return {Sandbox}
  *     The created sandbox.
  */
-sandbox.createMutable = function(window) {
+sandbox.createMutable = function(win) {
   let opts = {
     wantComponents: false,
     wantXrays: false,
   };
   // Note: We waive Xrays here to match potentially-accidental old behavior.
-  return Cu.waiveXrays(sandbox.create(window, null, opts));
+  return Cu.waiveXrays(sandbox.create(win, null, opts));
 };
 
-sandbox.createSystemPrincipal = function(window) {
+sandbox.createSystemPrincipal = function(win) {
   let principal = Cc["@mozilla.org/systemprincipal;1"]
       .createInstance(Ci.nsIPrincipal);
-  return sandbox.create(window, principal);
+  return sandbox.create(win, principal);
 };
 
-sandbox.createSimpleTest = function(window, harness) {
-  let sb = sandbox.create(window);
+sandbox.createSimpleTest = function(win, harness) {
+  let sb = sandbox.create(win);
   sb = sandbox.augment(sb, harness);
   sb[FINISH] = () => sb[COMPLETE](harness.generate_results());
   return sb;
diff --git a/testing/marionette/event.js b/testing/marionette/event.js
index 1500a7147fa282a08add739325fe73973988500d..519a7b3cf7c7045cbc45b1d7caaf0c4883806272 100644
--- a/testing/marionette/event.js
+++ b/testing/marionette/event.js
@@ -22,15 +22,6 @@ this.EXPORTED_SYMBOLS = ["event"];
 // TODO(ato): Document!
 let seenEvent = false;
 
-function getDOMWindowUtils(win) {
-  if (!win) {
-    win = window;
-  }
-
-  // this assumes we are operating in chrome space
-  return win.windowUtils;
-}
-
 event.MouseEvents = {
   click: 0,
   dblclick: 1,
@@ -83,119 +74,6 @@ event.DoubleClickTracker = {
   },
 };
 
-/**
- * Sends a mouse event to given target.
- *
- * @param {MouseEvent} mouseEvent
- *     Event to send.
- * @param {(DOMElement|string)} target
- *     Target of event.  Can either be an element or the ID of an element.
- * @param {Window=} window
- *     Window object.  Defaults to the current window.
- *
- * @throws {TypeError}
- *     If the event is unsupported.
- */
-event.sendMouseEvent = function(mouseEvent, target, window = undefined) {
-  if (!event.MouseEvents.hasOwnProperty(mouseEvent.type)) {
-    throw new TypeError("Unsupported event type: " + mouseEvent.type);
-  }
-
-  if (!target.nodeType && typeof target != "string") {
-    throw new TypeError(
-        "Target can only be a DOM element or a string: " + target);
-  }
-
-  if (!target.nodeType) {
-    target = window.document.getElementById(target);
-  } else {
-    window = window || target.ownerGlobal;
-  }
-
-  let ev = window.document.createEvent("MouseEvent");
-
-  let view = window;
-
-  let detail = mouseEvent.detail;
-  if (!detail) {
-    if (mouseEvent.type in ["click", "mousedown", "mouseup"]) {
-      detail = 1;
-    } else if (mouseEvent.type == "dblclick") {
-      detail = 2;
-    } else {
-      detail = 0;
-    }
-  }
-
-  let screenX = mouseEvent.screenX || 0;
-  let screenY = mouseEvent.screenY || 0;
-  let clientX = mouseEvent.clientX || 0;
-  let clientY = mouseEvent.clientY || 0;
-  let ctrlKey = mouseEvent.ctrlKey || false;
-  let altKey = mouseEvent.altKey || false;
-  let shiftKey = mouseEvent.shiftKey || false;
-  let metaKey = mouseEvent.metaKey || false;
-  let button = mouseEvent.button || 0;
-  let relatedTarget = mouseEvent.relatedTarget || null;
-
-  ev.initMouseEvent(
-      mouseEvent.type,
-      /* canBubble */ true,
-      /* cancelable */ true,
-      view,
-      detail,
-      screenX,
-      screenY,
-      clientX,
-      clientY,
-      ctrlKey,
-      altKey,
-      shiftKey,
-      metaKey,
-      button,
-      relatedTarget);
-};
-
-/**
- * Send character to the currently focused element.
- *
- * This function handles casing of characters (sends the right charcode,
- * and sends a shift key for uppercase chars).  No other modifiers are
- * handled at this point.
- *
- * For now this method only works for English letters (lower and upper
- * case) and the digits 0-9.
- */
-event.sendChar = function(char, window = undefined) {
-  // DOM event charcodes match ASCII (JS charcodes) for a-zA-Z0-9
-  let hasShift = (char == char.toUpperCase());
-  event.synthesizeKey(char, {shiftKey: hasShift}, window);
-};
-
-/**
- * Send string to the focused element.
- *
- * For now this method only works for English letters (lower and upper
- * case) and the digits 0-9.
- */
-event.sendString = function(string, window = undefined) {
-  for (let i = 0; i < string.length; ++i) {
-    event.sendChar(string.charAt(i), window);
-  }
-};
-
-/**
- * Send the non-character key to the focused element.
- *
- * The name of the key should be the part that comes after "DOM_VK_"
- * in the KeyboardEvent constant name for this key.  No modifiers are
- * handled at this point.
- */
-event.sendKey = function(key, window = undefined) {
-  let keyName = "VK_" + key.toUpperCase();
-  event.synthesizeKey(keyName, {shiftKey: false}, window);
-};
-
 // TODO(ato): Unexpose this when action.Chain#emitMouseEvent
 // no longer emits its own events
 event.parseModifiers_ = function(modifiers) {
@@ -242,14 +120,13 @@ event.parseModifiers_ = function(modifiers) {
  *     Object which may contain the properties "shiftKey", "ctrlKey",
  *     "altKey", "metaKey", "accessKey", "clickCount", "button", and
  *     "type".
- * @param {Window=} window
- *     Window object.  Defaults to the current window.
+ * @param {Window} win
+ *     Window object.
  */
-event.synthesizeMouse = function(
-    element, offsetX, offsetY, opts, window = undefined) {
+event.synthesizeMouse = function(element, offsetX, offsetY, opts, win) {
   let rect = element.getBoundingClientRect();
   event.synthesizeMouseAtPoint(
-      rect.left + offsetX, rect.top + offsetY, opts, window);
+      rect.left + offsetX, rect.top + offsetY, opts, win);
 };
 
 /*
@@ -266,13 +143,11 @@ event.synthesizeMouse = function(
  *     Object which may contain the properties "shiftKey", "ctrlKey",
  *     "altKey", "metaKey", "accessKey", "clickCount", "button", and
  *     "type".
- * @param {Window=} win
- *     Window object.  Defaults to the current window.
+ * @param {Window} win
+ *     Window object.
  */
-event.synthesizeMouseAtPoint = function(
-    left, top, opts, win = window) {
-
-  let domutils = getDOMWindowUtils(win);
+event.synthesizeMouseAtPoint = function(left, top, opts, win) {
+  let domutils = win.windowUtils;
 
   let button = opts.button || 0;
   let clickCount = opts.clickCount || 1;
@@ -339,22 +214,8 @@ event.synthesizeMouseAtPoint = function(
   }
 };
 
-/**
- * Call event.synthesizeMouse with coordinates at the centre of the
- * target.
- */
-event.synthesizeMouseAtCenter = function(element, event, window) {
-  let rect = element.getBoundingClientRect();
-  event.synthesizeMouse(
-      element,
-      rect.width / 2,
-      rect.height / 2,
-      event,
-      window);
-};
-
 /* eslint-disable */
-function computeKeyCodeFromChar_(char, win = window) {
+function computeKeyCodeFromChar_(char, win) {
   if (char.length != 1) {
     return 0;
   }
@@ -467,8 +328,8 @@ function computeKeyCodeFromChar_(char, win = window) {
  * The key code should be one of consts of KeyboardEvent.DOM_VK_*,
  * or a key name begins with "VK_", or a character.
  */
-event.isKeypressFiredKey = function(key) {
-  let KeyboardEvent = getKeyboardEvent_();
+event.isKeypressFiredKey = function(key, win) {
+  let KeyboardEvent = getKeyboardEvent_(win);
 
   if (typeof key == "string") {
     if (key.indexOf("VK_") === 0) {
@@ -512,13 +373,13 @@ event.isKeypressFiredKey = function(key) {
  *     metaKey, accessKey, type.  If the type is specified (keydown or keyup),
  *     a key event of that type is fired.  Otherwise, a keydown, a keypress,
  *     and then a keyup event are fired in sequence.
- * @param {Window=} window
- *     Window object.  Defaults to the current window.
+ * @param {Window} win
+ *     Window object.
  *
  * @throws {TypeError}
  *     If unknown key.
  */
-event.synthesizeKey = function(key, event, win = undefined) {
+event.synthesizeKey = function(key, event, win) {
   let TIP = getTIP_(win);
   if (!TIP) {
     return;
@@ -554,10 +415,8 @@ event.synthesizeKey = function(key, event, win = undefined) {
 const TIPMap = new WeakMap();
 
 function getTIP_(win, callback) {
-  if (!win) {
-    win = window;
-  }
   let tip;
+
   if (TIPMap.has(win)) {
     tip = TIPMap.get(win);
   } else {
@@ -572,7 +431,7 @@ function getTIP_(win, callback) {
   return tip;
 }
 
-function getKeyboardEvent_(win = window) {
+function getKeyboardEvent_(win) {
   if (typeof KeyboardEvent != "undefined") {
     try {
       // See if the object can be instantiated; sometimes this yields
@@ -588,7 +447,7 @@ function getKeyboardEvent_(win = window) {
   return win.KeyboardEvent;
 }
 
-function createKeyboardEventDictionary_(key, keyEvent, win = window) {
+function createKeyboardEventDictionary_(key, keyEvent, win) {
   let result = {dictionary: null, flags: 0};
   let keyCodeIsDefined = "keyCode" in keyEvent &&
       keyEvent.keyCode != undefined;
@@ -596,6 +455,7 @@ function createKeyboardEventDictionary_(key, keyEvent, win = window) {
     (keyCodeIsDefined && keyEvent.keyCode >= 0 && keyEvent.keyCode <= 255) ?
       keyEvent.keyCode : 0;
   let keyName = "Unidentified";
+
   if (key.indexOf("KEY_") == 0) {
     keyName = key.substr("KEY_".length);
     result.flags |= Ci.nsITextInputProcessor.KEY_NON_PRINTABLE_KEY;
@@ -621,21 +481,29 @@ function createKeyboardEventDictionary_(key, keyEvent, win = window) {
       result.flags |= Ci.nsITextInputProcessor.KEY_FORCE_PRINTABLE_KEY;
     }
   }
+
   let locationIsDefined = "location" in keyEvent;
   if (locationIsDefined && keyEvent.location === 0) {
     result.flags |= Ci.nsITextInputProcessor.KEY_KEEP_KEY_LOCATION_STANDARD;
   }
+
+  let resultKey = "key" in keyEvent ? keyEvent.key : keyName;
+  if (!MODIFIER_KEYCODES_LOOKUP[key] && keyEvent.shiftKey) {
+    resultKey = resultKey.toUpperCase();
+  }
+
   result.dictionary = {
-    key: "key" in keyEvent ? keyEvent.key : keyName,
+    key: resultKey,
     code: "code" in keyEvent ? keyEvent.code : "",
     location: locationIsDefined ? keyEvent.location : 0,
     repeat: "repeat" in keyEvent ? keyEvent.repeat === true : false,
     keyCode,
   };
+
   return result;
 }
 
-function emulateToActivateModifiers_(TIP, keyEvent, win = window) {
+function emulateToActivateModifiers_(TIP, keyEvent, win) {
   if (!keyEvent) {
     return null;
   }
@@ -693,7 +561,7 @@ function emulateToActivateModifiers_(TIP, keyEvent, win = window) {
   return modifiers;
 }
 
-function emulateToInactivateModifiers_(TIP, modifiers, win = window) {
+function emulateToInactivateModifiers_(TIP, modifiers, win) {
   if (!modifiers) {
     return;
   }
@@ -722,7 +590,7 @@ function emulateToInactivateModifiers_(TIP, modifiers, win = window) {
 }
 
 /* eslint-disable */
-function guessKeyNameFromKeyCode_(aKeyCode, win = window) {
+function guessKeyNameFromKeyCode_(aKeyCode, win) {
   let KeyboardEvent = getKeyboardEvent_(win);
   switch (aKeyCode) {
     case KeyboardEvent.DOM_VK_CANCEL:
@@ -947,57 +815,18 @@ function checkExpectedEvent_(
  *     Expected type of the event, such as "select".
  * @param {string} testName
  *     Test name when outputing results.
- * @param {Window=} window
- *     Window object.  Defaults to the current window.
+ * @param {Window} win
+ *     Window object.
  */
 event.synthesizeMouseExpectEvent = function(
     target, offsetX, offsetY, ev, expectedTarget, expectedEvent,
-    testName, window = undefined) {
-
-  let eventHandler = expectEvent_(
-      expectedTarget,
-      expectedEvent,
-      testName);
-  event.synthesizeMouse(target, offsetX, offsetY, ev, window);
-  checkExpectedEvent_(
-      expectedTarget,
-      expectedEvent,
-      eventHandler,
-      testName);
-};
-
-/**
- * Similar to synthesizeKey except that a test is performed to see if
- * an event is fired at the right target as a result.
- *
- * @param {string} key
- *     Key to synthesise.
- * @param {Object.<string, ?>} ev
- *     Object which may contain the properties shiftKey, ctrlKey, altKey,
- *     metaKey, accessKey, type.
- * @param {Element} expectedTarget
- *     Expected originalTarget of the event.
- * @param {DOMEvent} expectedEvent
- *     Expected type of the event, such as "select".
- * @param {string} testName
- *     Test name when outputing results
- * @param {Window=} window
- *     Window object.  Defaults to the current window.
- *
- * To test that an event is not fired, use an expected type preceded by an
- * exclamation mark, such as "!select".
- *
- * aWindow is optional, and defaults to the current window object.
- */
-event.synthesizeKeyExpectEvent = function(
-    key, ev, expectedTarget, expectedEvent, testName,
-    window = undefined) {
+    testName, win) {
 
   let eventHandler = expectEvent_(
       expectedTarget,
       expectedEvent,
       testName);
-  event.synthesizeKey(key, ev, window);
+  event.synthesizeMouse(target, offsetX, offsetY, ev, win);
   checkExpectedEvent_(
       expectedTarget,
       expectedEvent,
@@ -1005,45 +834,7 @@ event.synthesizeKeyExpectEvent = function(
       testName);
 };
 
-/**
- * Synthesize a query selected text event.
- *
- * @param {Window=}
- *     Window object.  Defaults to the current window.
- *
- * @return {(nsIQueryContentEventResult|null)}
- *     Event's result, or null if it failed.
- */
-event.synthesizeQuerySelectedText = function(window = undefined) {
-  let domutils = getDOMWindowUtils(window);
-  return domutils.sendQueryContentEvent(
-      domutils.QUERY_SELECTED_TEXT, 0, 0, 0, 0);
-};
-
-/**
- * Synthesize a selection set event.
- *
- * @param {number} offset
- *     Character offset.  0 means the first character in the selection
- *     root.
- * @param {number} length
- *     Length of the text.  If the length is too long, the extra length
- *     is ignored.
- * @param {boolean} reverse
- *     If true, the selection is from |aOffset + aLength| to |aOffset|.
- *     Otherwise, from |aOffset| to |aOffset + aLength|.
- * @param {Window=} window
- *     Window object.  Defaults to the current window.
- *
- * @return         True, if succeeded.  Otherwise false.
- */
-event.synthesizeSelectionSet = function(
-    offset, length, reverse, window = undefined) {
-  let domutils = getDOMWindowUtils(window);
-  return domutils.sendSelectionSetEvent(offset, length, reverse);
-};
-
-const KEYCODES_LOOKUP = {
+const MODIFIER_KEYCODES_LOOKUP = {
   "VK_SHIFT": "shiftKey",
   "VK_CONTROL": "ctrlKey",
   "VK_ALT": "altKey",
@@ -1061,7 +852,6 @@ const VIRTUAL_KEYCODE_LOOKUP = {
   "\uE008": "VK_SHIFT",
   "\uE009": "VK_CONTROL",
   "\uE00A": "VK_ALT",
-  "\uE03D": "VK_META",
   "\uE00B": "VK_PAUSE",
   "\uE00C": "VK_ESCAPE",
   "\uE00D": "VK_SPACE",  // printable
@@ -1105,6 +895,21 @@ const VIRTUAL_KEYCODE_LOOKUP = {
   "\uE03A": "VK_F10",
   "\uE03B": "VK_F11",
   "\uE03C": "VK_F12",
+  "\uE03D": "VK_META",
+  "\uE050": "VK_SHIFT",
+  "\uE051": "VK_CONTROL",
+  "\uE052": "VK_ALT",
+  "\uE053": "VK_META",
+  "\uE054": "VK_PAGE_UP",
+  "\uE055": "VK_PAGE_DOWN",
+  "\uE056": "VK_END",
+  "\uE057": "VK_HOME",
+  "\uE058": "VK_LEFT",
+  "\uE059": "VK_UP",
+  "\uE05A": "VK_RIGHT",
+  "\uE05B": "VK_DOWN",
+  "\uE05C": "VK_INSERT",
+  "\uE05D": "VK_DELETE",
 };
 
 function getKeyCode(c) {
@@ -1114,7 +919,7 @@ function getKeyCode(c) {
   return c;
 }
 
-function isPrintable(c, win = window) {
+function isPrintable(c, win) {
   let KeyboardEvent = getKeyboardEvent_(win);
   let NON_PRINT_KEYS = [
     KeyboardEvent.DOM_VK_CANCEL,
@@ -1190,23 +995,15 @@ function isPrintable(c, win = window) {
   return !(NON_PRINT_KEYS.includes(c));
 }
 
-event.sendKeyDown = function(keyToSend, modifiers, document) {
+event.sendKeyDown = function(keyToSend, modifiers, win) {
   modifiers.type = "keydown";
-  event.sendSingleKey(keyToSend, modifiers, document);
-  // TODO: This doesn't do anything since |synthesizeKeyEvent| ignores
-  // explicit keypress request, and instead figures out itself when to
-  // send keypress.
-  if (!["VK_SHIFT", "VK_CONTROL", "VK_ALT", "VK_META"]
-      .includes(getKeyCode(keyToSend))) {
-    modifiers.type = "keypress";
-    event.sendSingleKey(keyToSend, modifiers, document);
-  }
+  event.sendSingleKey(keyToSend, modifiers, win);
   delete modifiers.type;
 };
 
-event.sendKeyUp = function(keyToSend, modifiers, window = undefined) {
+event.sendKeyUp = function(keyToSend, modifiers, win) {
   modifiers.type = "keyup";
-  event.sendSingleKey(keyToSend, modifiers, window);
+  event.sendSingleKey(keyToSend, modifiers, win);
   delete modifiers.type;
 };
 
@@ -1219,30 +1016,28 @@ event.sendKeyUp = function(keyToSend, modifiers, window = undefined) {
  *     Object with properties used in KeyboardEvent (shiftkey, repeat, ...)
  *     as well as, the event |type| such as keydown. All properties
  *     are optional.
- * @param {Window=} window
- *     Window object.  If |window| is undefined, the event is synthesized
- *     in current window.
+ * @param {Window} win
+ *     Window object.
  */
-event.sendSingleKey = function(keyToSend, modifiers, window = undefined) {
-  let keyName = getKeyCode(keyToSend);
-  if (keyName in KEYCODES_LOOKUP) {
-    // We assume that if |keyToSend| is a raw code point (like "\uE009")
-    // then |modifiers| does not already have correct value for corresponding
-    // |modName| attribute (like ctrlKey), so that value needs to be flipped.
-    let modName = KEYCODES_LOOKUP[keyName];
+event.sendSingleKey = function(keyToSend, modifiers, win) {
+  let keyCode = getKeyCode(keyToSend);
+  if (keyCode in MODIFIER_KEYCODES_LOOKUP) {
+    // For |sendKeysToElement| and legacy actions we assume that if
+    // |keyToSend| is a raw code point (like "\uE009") then |modifiers| does
+    // not already have correct value for corresponding |modName| attribute
+    // (like ctrlKey), so that value needs to be flipped.
+    let modName = MODIFIER_KEYCODES_LOOKUP[keyCode];
     modifiers[modName] = !modifiers[modName];
-  } else if (modifiers.shiftKey && keyName != "Shift") {
-    keyName = keyName.toUpperCase();
   }
-  event.synthesizeKey(keyName, modifiers, window);
+  event.synthesizeKey(keyCode, modifiers, win);
 };
 
 /**
  * @param {string} keyString
  * @param {Element} element
- * @param {Window=} window
+ * @param {Window} win
  */
-event.sendKeysToElement = function(keyString, el, window = undefined) {
+event.sendKeysToElement = function(keyString, el, win) {
   // make Object.<modifier, false> map
   let modifiers = Object.create(event.Modifiers);
   for (let modifier in event.Modifiers) {
@@ -1251,7 +1046,7 @@ event.sendKeysToElement = function(keyString, el, window = undefined) {
 
   for (let i = 0; i < keyString.length; i++) {
     let c = keyString.charAt(i);
-    event.sendSingleKey(c, modifiers, window);
+    event.sendSingleKey(c, modifiers, win);
   }
 };
 
diff --git a/testing/marionette/sync.js b/testing/marionette/sync.js
index d708269c0628d46b87ea1873978b2a4f613e3c2d..c6e784e847c78b9889b001b1c2bcfc37aec750b4 100644
--- a/testing/marionette/sync.js
+++ b/testing/marionette/sync.js
@@ -271,15 +271,15 @@ function MessageManagerDestroyedPromise(messageManager) {
  * Throttle until the main thread is idle and `window` has performed
  * an animation frame (in that order).
  *
- * @param {ChromeWindow} window
+ * @param {ChromeWindow} win
  *     Window to request the animation frame from.
  *
  * @return Promise
  */
-function IdlePromise(window) {
+function IdlePromise(win) {
   return new Promise(resolve => {
     Services.tm.idleDispatchToMainThread(() => {
-      window.requestAnimationFrame(resolve);
+      win.requestAnimationFrame(resolve);
     });
   });
 }
diff --git a/testing/marionette/test/unit/test_sync.js b/testing/marionette/test/unit/test_sync.js
index f84c704f9a9478d927becaedc2064e22b9320f76..109a99e595d3795b3f0e5823480ddca746a07e2a 100644
--- a/testing/marionette/test/unit/test_sync.js
+++ b/testing/marionette/test/unit/test_sync.js
@@ -145,12 +145,12 @@ add_task(async function test_Sleep() {
 
 add_task(async function test_IdlePromise() {
   let called = false;
-  let window = {
+  let win = {
     requestAnimationFrame(callback) {
       called = true;
       callback();
     },
   };
-  await IdlePromise(window);
+  await IdlePromise(win);
   ok(called);
 });
diff --git a/testing/web-platform/meta/MANIFEST.json b/testing/web-platform/meta/MANIFEST.json
index d0717a52d9a87f4a4d47f6fea4279c0c4bfaf2c3..eb73a16fb5b4416c682fe2745c7e3e4a6d6d8aa5 100644
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -432133,6 +432133,20 @@
      {}
     ]
    ],
+   "webdriver/tests/perform_actions/key_events.py": [
+    [
+     "/webdriver/tests/perform_actions/key_events.py",
+     {
+      "timeout": "long"
+     }
+    ]
+   ],
+   "webdriver/tests/perform_actions/key_modifiers.py": [
+    [
+     "/webdriver/tests/perform_actions/key_modifiers.py",
+     {}
+    ]
+   ],
    "webdriver/tests/perform_actions/key_shortcuts.py": [
     [
      "/webdriver/tests/perform_actions/key_shortcuts.py",
@@ -432142,9 +432156,7 @@
    "webdriver/tests/perform_actions/key_special_keys.py": [
     [
      "/webdriver/tests/perform_actions/key_special_keys.py",
-     {
-      "timeout": "long"
-     }
+     {}
     ]
    ],
    "webdriver/tests/perform_actions/none.py": [
@@ -662219,7 +662231,15 @@
    "support"
   ],
   "webdriver/tests/perform_actions/key.py": [
-   "2e6cbdfbb32f9ada42c2b8a49f7702b14ffdc550",
+   "2b3414c5ebfd62955860de540b4614471efbe8ad",
+   "wdspec"
+  ],
+  "webdriver/tests/perform_actions/key_events.py": [
+   "462688a55e527ffd5d075e4bd981489e5e029f8c",
+   "wdspec"
+  ],
+  "webdriver/tests/perform_actions/key_modifiers.py": [
+   "b6fd4bb22e6ef850c6bd78def4a0550ed7495bcc",
    "wdspec"
   ],
   "webdriver/tests/perform_actions/key_shortcuts.py": [
@@ -662227,7 +662247,7 @@
    "wdspec"
   ],
   "webdriver/tests/perform_actions/key_special_keys.py": [
-   "4a55ccfa1d97b714a9145e148d73827b8b882642",
+   "003bba4294105eb2757bfbe9e4f808b4ea13047c",
    "wdspec"
   ],
   "webdriver/tests/perform_actions/none.py": [
diff --git a/testing/web-platform/tests/webdriver/tests/perform_actions/key.py b/testing/web-platform/tests/webdriver/tests/perform_actions/key.py
index 2e6cbdfbb32f9ada42c2b8a49f7702b14ffdc550..2b3414c5ebfd62955860de540b4614471efbe8ad 100644
--- a/testing/web-platform/tests/webdriver/tests/perform_actions/key.py
+++ b/testing/web-platform/tests/webdriver/tests/perform_actions/key.py
@@ -3,7 +3,7 @@ import pytest
 from webdriver.error import NoSuchWindowException
 
 from tests.perform_actions.support.keys import Keys
-from tests.perform_actions.support.refine import filter_dict, get_events, get_keys
+from tests.perform_actions.support.refine import get_keys
 
 
 def test_null_response_value(session, key_chain):
@@ -16,175 +16,10 @@ def test_no_browsing_context(session, closed_window, key_chain):
         key_chain.key_up("a").perform()
 
 
-def test_lone_keyup_sends_no_events(session, key_reporter, key_chain):
-    key_chain.key_up("a").perform()
-    assert len(get_keys(key_reporter)) == 0
-    assert len(get_events(session)) == 0
-    session.actions.release()
-    assert len(get_keys(key_reporter)) == 0
-    assert len(get_events(session)) == 0
-
-
-@pytest.mark.parametrize("value,code", [
-    (u"a", "KeyA",),
-    ("a", "KeyA",),
-    (u"\"", "Quote"),
-    (u",", "Comma"),
-    (u"\u00E0", ""),
-    (u"\u0416", ""),
-    (u"@", "Digit2"),
-    (u"\u2603", ""),
-    (u"\uF6C2", ""),  # PUA
-])
-def test_single_printable_key_sends_correct_events(session,
-                                                   key_reporter,
-                                                   key_chain,
-                                                   value,
-                                                   code):
-    key_chain \
-        .key_down(value) \
-        .key_up(value) \
-        .perform()
-    expected = [
-        {"code": code, "key": value, "type": "keydown"},
-        {"code": code, "key": value, "type": "keypress"},
-        {"code": code, "key": value, "type": "keyup"},
-    ]
-    all_events = get_events(session)
-    events = [filter_dict(e, expected[0]) for e in all_events]
-    if len(events) > 0 and events[0]["code"] == None:
-        # Remove 'code' entry if browser doesn't support it
-        expected = [filter_dict(e, {"key": "", "type": ""}) for e in expected]
-        events = [filter_dict(e, expected[0]) for e in events]
-    assert events == expected
-    assert get_keys(key_reporter) == value
-
-
-@pytest.mark.parametrize("value", [
-    (u"\U0001F604"),
-    (u"\U0001F60D"),
-])
-def test_single_emoji_records_correct_key(session, key_reporter, key_chain, value):
-    # Not using key_chain.send_keys() because we always want to treat value as
-    # one character here. `len(value)` varies by platform for non-BMP characters,
-    # so we don't want to iterate over value.
-    key_chain \
-        .key_down(value) \
-        .key_up(value) \
-        .perform()
-    # events sent by major browsers are inconsistent so only check key value
-    assert get_keys(key_reporter) == value
-
-
-@pytest.mark.parametrize("value,code,key", [
-    (u"\uE050", "ShiftRight", "Shift"),
-    (u"\uE053", "OSRight", "Meta"),
-    (Keys.CONTROL, "ControlLeft", "Control"),
-])
-def test_single_modifier_key_sends_correct_events(session,
-                                                  key_reporter,
-                                                  key_chain,
-                                                  value,
-                                                  code,
-                                                  key):
-    key_chain \
-        .key_down(value) \
-        .key_up(value) \
-        .perform()
-    all_events = get_events(session)
-    expected = [
-        {"code": code, "key": key, "type": "keydown"},
-        {"code": code, "key": key, "type": "keyup"},
-    ]
-    events = [filter_dict(e, expected[0]) for e in all_events]
-    if len(events) > 0 and events[0]["code"] == None:
-        # Remove 'code' entry if browser doesn't support it
-        expected = [filter_dict(e, {"key": "", "type": ""}) for e in expected]
-        events = [filter_dict(e, expected[0]) for e in events]
-    assert events == expected
-    assert len(get_keys(key_reporter)) == 0
-
-
-@pytest.mark.parametrize("value,code,key", [
-    (Keys.ESCAPE, "Escape", "Escape"),
-    (Keys.RIGHT, "ArrowRight", "ArrowRight"),
-])
-def test_single_nonprintable_key_sends_events(session,
-                                              key_reporter,
-                                              key_chain,
-                                              value,
-                                              code,
-                                              key):
-    key_chain \
-        .key_down(value) \
-        .key_up(value) \
-        .perform()
-    expected = [
-        {"code": code, "key": key, "type": "keydown"},
-        {"code": code, "key": key, "type": "keypress"},
-        {"code": code, "key": key, "type": "keyup"},
-    ]
-    all_events = get_events(session)
-    events = [filter_dict(e, expected[0]) for e in all_events]
-    if len(events) > 0 and events[0]["code"] == None:
-        # Remove 'code' entry if browser doesn't support it
-        expected = [filter_dict(e, {"key": "", "type": ""}) for e in expected]
-        events = [filter_dict(e, expected[0]) for e in events]
-    if len(events) == 2:
-        # most browsers don't send a keypress for non-printable keys
-        assert events == [expected[0], expected[2]]
-    else:
-        assert events == expected
-    assert len(get_keys(key_reporter)) == 0
-
-
-def test_sequence_of_keydown_printable_keys_sends_events(session,
-                                                         key_reporter,
-                                                         key_chain):
-    key_chain \
-        .key_down("a") \
-        .key_down("b") \
-        .perform()
-    expected = [
-        {"code": "KeyA", "key": "a", "type": "keydown"},
-        {"code": "KeyA", "key": "a", "type": "keypress"},
-        {"code": "KeyB", "key": "b", "type": "keydown"},
-        {"code": "KeyB", "key": "b", "type": "keypress"},
-    ]
-    all_events = get_events(session)
-    events = [filter_dict(e, expected[0]) for e in all_events]
-    if len(events) > 0 and events[0]["code"] == None:
-        # Remove 'code' entry if browser doesn't support it
-        expected = [filter_dict(e, {"key": "", "type": ""}) for e in expected]
-        events = [filter_dict(e, expected[0]) for e in events]
-    assert events == expected
-    assert get_keys(key_reporter) == "ab"
-
-
-def test_sequence_of_keydown_character_keys(session, key_reporter, key_chain):
-    key_chain.send_keys("ef").perform()
-    expected = [
-        {"code": "KeyE", "key": "e", "type": "keydown"},
-        {"code": "KeyE", "key": "e", "type": "keypress"},
-        {"code": "KeyE", "key": "e", "type": "keyup"},
-        {"code": "KeyF", "key": "f", "type": "keydown"},
-        {"code": "KeyF", "key": "f", "type": "keypress"},
-        {"code": "KeyF", "key": "f", "type": "keyup"},
-    ]
-    all_events = get_events(session)
-    events = [filter_dict(e, expected[0]) for e in all_events]
-    if len(events) > 0 and events[0]["code"] == None:
-        # Remove 'code' entry if browser doesn't support it
-        expected = [filter_dict(e, {"key": "", "type": ""}) for e in expected]
-        events = [filter_dict(e, expected[0]) for e in events]
-    assert events == expected
-    assert get_keys(key_reporter) == "ef"
-
-
 def test_backspace_erases_keys(session, key_reporter, key_chain):
     key_chain \
         .send_keys("efcd") \
         .send_keys([Keys.BACKSPACE, Keys.BACKSPACE]) \
         .perform()
-    assert get_keys(key_reporter) == "ef"
 
+    assert get_keys(key_reporter) == "ef"
diff --git a/testing/web-platform/tests/webdriver/tests/perform_actions/key_events.py b/testing/web-platform/tests/webdriver/tests/perform_actions/key_events.py
new file mode 100644
index 0000000000000000000000000000000000000000..462688a55e527ffd5d075e4bd981489e5e029f8c
--- /dev/null
+++ b/testing/web-platform/tests/webdriver/tests/perform_actions/key_events.py
@@ -0,0 +1,205 @@
+# META: timeout=long
+
+import pytest
+
+from tests.perform_actions.support.keys import ALL_EVENTS, Keys
+from tests.perform_actions.support.refine import filter_dict, get_events, get_keys
+
+
+def test_keyup_only_sends_no_events(session, key_reporter, key_chain):
+    key_chain.key_up("a").perform()
+
+    assert len(get_keys(key_reporter)) == 0
+    assert len(get_events(session)) == 0
+
+    session.actions.release()
+    assert len(get_keys(key_reporter)) == 0
+    assert len(get_events(session)) == 0
+
+
+@pytest.mark.parametrize("key, event", [
+    (Keys.ALT, "ALT"),
+    (Keys.CONTROL, "CONTROL"),
+    (Keys.META, "META"),
+    (Keys.SHIFT, "SHIFT"),
+    (Keys.R_ALT, "R_ALT"),
+    (Keys.R_CONTROL, "R_CONTROL"),
+    (Keys.R_META, "R_META"),
+    (Keys.R_SHIFT, "R_SHIFT"),
+])
+def test_modifier_key_sends_correct_events(session, key_reporter, key_chain, key, event):
+    code = ALL_EVENTS[event]["code"]
+    value = ALL_EVENTS[event]["key"]
+
+    key_chain \
+        .key_down(key) \
+        .key_up(key) \
+        .perform()
+    all_events = get_events(session)
+
+    expected = [
+        {"code": code, "key": value, "type": "keydown"},
+        {"code": code, "key": value, "type": "keyup"},
+    ]
+
+    events = [filter_dict(e, expected[0]) for e in all_events]
+    if len(events) > 0 and events[0]["code"] is None:
+        # Remove 'code' entry if browser doesn't support it
+        expected = [filter_dict(e, {"key": "", "type": ""}) for e in expected]
+        events = [filter_dict(e, expected[0]) for e in events]
+    assert events == expected
+
+    assert len(get_keys(key_reporter)) == 0
+
+
+@pytest.mark.parametrize("key,event", [
+    (Keys.ESCAPE, "ESCAPE"),
+    (Keys.RIGHT, "RIGHT"),
+])
+def test_non_printable_key_sends_events(session, key_reporter, key_chain, key, event):
+    code = ALL_EVENTS[event]["code"]
+    value = ALL_EVENTS[event]["key"]
+
+    key_chain \
+        .key_down(key) \
+        .key_up(key) \
+        .perform()
+    all_events = get_events(session)
+
+    expected = [
+        {"code": code, "key": value, "type": "keydown"},
+        {"code": code, "key": value, "type": "keypress"},
+        {"code": code, "key": value, "type": "keyup"},
+    ]
+
+    events = [filter_dict(e, expected[0]) for e in all_events]
+    if len(events) > 0 and events[0]["code"] is None:
+        # Remove 'code' entry if browser doesn't support it
+        expected = [filter_dict(e, {"key": "", "type": ""}) for e in expected]
+        events = [filter_dict(e, expected[0]) for e in events]
+    if len(events) == 2:
+        # most browsers don't send a keypress for non-printable keys
+        assert events == [expected[0], expected[2]]
+    else:
+        assert events == expected
+
+    assert len(get_keys(key_reporter)) == 0
+
+
+@pytest.mark.parametrize("value,code", [
+    (u"a", "KeyA",),
+    ("a", "KeyA",),
+    (u"\"", "Quote"),
+    (u",", "Comma"),
+    (u"\u00E0", ""),
+    (u"\u0416", ""),
+    (u"@", "Digit2"),
+    (u"\u2603", ""),
+    (u"\uF6C2", ""),  # PUA
+])
+def test_printable_key_sends_correct_events(session, key_reporter, key_chain, value, code):
+    key_chain \
+        .key_down(value) \
+        .key_up(value) \
+        .perform()
+    all_events = get_events(session)
+
+    expected = [
+        {"code": code, "key": value, "type": "keydown"},
+        {"code": code, "key": value, "type": "keypress"},
+        {"code": code, "key": value, "type": "keyup"},
+    ]
+
+    events = [filter_dict(e, expected[0]) for e in all_events]
+    if len(events) > 0 and events[0]["code"] is None:
+        # Remove 'code' entry if browser doesn't support it
+        expected = [filter_dict(e, {"key": "", "type": ""}) for e in expected]
+        events = [filter_dict(e, expected[0]) for e in events]
+    assert events == expected
+
+    assert get_keys(key_reporter) == value
+
+
+def test_sequence_of_keydown_printable_keys_sends_events(session, key_reporter, key_chain):
+    key_chain \
+        .key_down("a") \
+        .key_down("b") \
+        .perform()
+    all_events = get_events(session)
+
+    expected = [
+        {"code": "KeyA", "key": "a", "type": "keydown"},
+        {"code": "KeyA", "key": "a", "type": "keypress"},
+        {"code": "KeyB", "key": "b", "type": "keydown"},
+        {"code": "KeyB", "key": "b", "type": "keypress"},
+    ]
+
+    events = [filter_dict(e, expected[0]) for e in all_events]
+    if len(events) > 0 and events[0]["code"] is None:
+        # Remove 'code' entry if browser doesn't support it
+        expected = [filter_dict(e, {"key": "", "type": ""}) for e in expected]
+        events = [filter_dict(e, expected[0]) for e in events]
+    assert events == expected
+
+    assert get_keys(key_reporter) == "ab"
+
+
+def test_sequence_of_keydown_printable_characters_sends_events(session, key_reporter, key_chain):
+    key_chain.send_keys("ef").perform()
+    all_events = get_events(session)
+
+    expected = [
+        {"code": "KeyE", "key": "e", "type": "keydown"},
+        {"code": "KeyE", "key": "e", "type": "keypress"},
+        {"code": "KeyE", "key": "e", "type": "keyup"},
+        {"code": "KeyF", "key": "f", "type": "keydown"},
+        {"code": "KeyF", "key": "f", "type": "keypress"},
+        {"code": "KeyF", "key": "f", "type": "keyup"},
+    ]
+
+    events = [filter_dict(e, expected[0]) for e in all_events]
+    if len(events) > 0 and events[0]["code"] is None:
+        # Remove 'code' entry if browser doesn't support it
+        expected = [filter_dict(e, {"key": "", "type": ""}) for e in expected]
+        events = [filter_dict(e, expected[0]) for e in events]
+    assert events == expected
+
+    assert get_keys(key_reporter) == "ef"
+
+
+@pytest.mark.parametrize("name,expected", ALL_EVENTS.items())
+def test_special_key_sends_keydown(session, key_reporter, key_chain, name, expected):
+    if name.startswith("F"):
+        # Prevent default behavior for F1, etc., but only after keydown
+        # bubbles up to body. (Otherwise activated browser menus/functions
+        # may interfere with subsequent tests.)
+        session.execute_script("""
+            document.body.addEventListener("keydown",
+                    function(e) { e.preventDefault() });
+        """)
+    if (session.capabilities["browserName"] == 'internet explorer'):
+        key_reporter.click()
+        session.execute_script("resetEvents();")
+    key_chain.key_down(getattr(Keys, name)).perform()
+
+    # only interested in keydown
+    first_event = get_events(session)[0]
+    # make a copy so we can throw out irrelevant keys and compare to events
+    expected = dict(expected)
+
+    del expected["value"]
+
+    # check and remove keys that aren't in expected
+    assert first_event["type"] == "keydown"
+    assert first_event["repeat"] is False
+    first_event = filter_dict(first_event, expected)
+    if first_event["code"] is None:
+        del first_event["code"]
+        del expected["code"]
+    assert first_event == expected
+    # only printable characters should be recorded in input field
+    entered_keys = get_keys(key_reporter)
+    if len(expected["key"]) == 1:
+        assert entered_keys == expected["key"]
+    else:
+        assert len(entered_keys) == 0
diff --git a/testing/web-platform/tests/webdriver/tests/perform_actions/key_modifiers.py b/testing/web-platform/tests/webdriver/tests/perform_actions/key_modifiers.py
new file mode 100644
index 0000000000000000000000000000000000000000..55dc9280c6267172a96a4f3c02f2503aa0c22500
--- /dev/null
+++ b/testing/web-platform/tests/webdriver/tests/perform_actions/key_modifiers.py
@@ -0,0 +1,24 @@
+import pytest
+
+from tests.perform_actions.support.keys import Keys
+
+
+@pytest.mark.parametrize("modifier", [Keys.SHIFT, Keys.R_SHIFT])
+def test_shift_modifier_generates_capital_letters(session, key_reporter, key_chain, modifier):
+    key_chain \
+        .send_keys("b") \
+        .key_down(modifier) \
+        .key_down("c") \
+        .key_up(modifier) \
+        .key_up("c") \
+        .key_down("d") \
+        .key_up("d") \
+        .key_down(modifier) \
+        .key_down("e") \
+        .key_up("e") \
+        .key_down("f") \
+        .key_up(modifier) \
+        .key_up("f") \
+        .perform()
+
+    assert key_reporter.property("value") == "bCdEF"
diff --git a/testing/web-platform/tests/webdriver/tests/perform_actions/key_special_keys.py b/testing/web-platform/tests/webdriver/tests/perform_actions/key_special_keys.py
index 4a55ccfa1d97b714a9145e148d73827b8b882642..003bba4294105eb2757bfbe9e4f808b4ea13047c 100644
--- a/testing/web-platform/tests/webdriver/tests/perform_actions/key_special_keys.py
+++ b/testing/web-platform/tests/webdriver/tests/perform_actions/key_special_keys.py
@@ -1,69 +1,26 @@
-# META: timeout=long
-
 import pytest
 
 from webdriver import error
 
-from tests.perform_actions.support.keys import ALL_EVENTS, Keys
-from tests.perform_actions.support.refine import filter_dict, get_events, get_keys
-
-
-@pytest.mark.parametrize("name,expected", ALL_EVENTS.items())
-def test_webdriver_special_key_sends_keydown(session,
-                                             key_reporter,
-                                             key_chain,
-                                             name,
-                                             expected):
-    if name.startswith("F"):
-        # Prevent default behavior for F1, etc., but only after keydown
-        # bubbles up to body. (Otherwise activated browser menus/functions
-        # may interfere with subsequent tests.)
-        session.execute_script("""
-            document.body.addEventListener("keydown",
-                    function(e) { e.preventDefault() });
-        """)
-    if (session.capabilities["browserName"] == 'internet explorer'):
-        key_reporter.click()
-        session.execute_script("resetEvents();")
-    key_chain.key_down(getattr(Keys, name)).perform()
-
-    # only interested in keydown
-    first_event = get_events(session)[0]
-    # make a copy so we can throw out irrelevant keys and compare to events
-    expected = dict(expected)
-
-    del expected["value"]
-
-    # check and remove keys that aren't in expected
-    assert first_event["type"] == "keydown"
-    assert first_event["repeat"] == False
-    first_event = filter_dict(first_event, expected)
-    if first_event["code"] == None:
-        del first_event["code"]
-        del expected["code"]
-    assert first_event == expected
-    # only printable characters should be recorded in input field
-    entered_keys = get_keys(key_reporter)
-    if len(expected["key"]) == 1:
-        assert entered_keys == expected["key"]
-    else:
-        assert len(entered_keys) == 0
+from tests.perform_actions.support.refine import get_keys
 
 
 @pytest.mark.parametrize("value", [
-    (u"f"),
+    (u"\U0001F604"),
+    (u"\U0001F60D"),
     (u"\u0BA8\u0BBF"),
     (u"\u1100\u1161\u11A8"),
 ])
-def test_multiple_codepoint_keys_behave_correctly(session,
-                                                  key_reporter,
-                                                  key_chain,
-                                                  value):
+def test_codepoint_keys_behave_correctly(session, key_reporter, key_chain, value):
+    # Not using key_chain.send_keys() because we always want to treat value as
+    # one character here. `len(value)` varies by platform for non-BMP characters,
+    # so we don't want to iterate over value.
     key_chain \
         .key_down(value) \
         .key_up(value) \
         .perform()
 
+    # events sent by major browsers are inconsistent so only check key value
     assert get_keys(key_reporter) == value
 
 
@@ -73,12 +30,9 @@ def test_multiple_codepoint_keys_behave_correctly(session,
     (u"\u0BA8\u0BBF\u0BA8"),
     (u"\u1100\u1161\u11A8c")
 ])
-def test_invalid_multiple_codepoint_keys_fail(session,
-                                              key_reporter,
-                                              key_chain,
-                                              value):
+def test_invalid_multiple_codepoint_keys_fail(session, key_reporter, key_chain, value):
     with pytest.raises(error.InvalidArgumentException):
         key_chain \
             .key_down(value) \
             .key_up(value) \
-            .perform()
\ No newline at end of file
+            .perform()
diff --git a/third_party/rust/plane-split/.cargo-checksum.json b/third_party/rust/plane-split/.cargo-checksum.json
index 519db83eaa5d2dd4f743cf26241333ac025b8a50..c3b5f2c426f455ddde9737f7af74b901bbc06e96 100644
--- a/third_party/rust/plane-split/.cargo-checksum.json
+++ b/third_party/rust/plane-split/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{".travis.yml":"b76d49f66f842c652d40825c67791352364a6b6bbb7d8d1009f2ac79eb413e66","Cargo.toml":"91ca8efc8aeb123545f2dace7bebe3cd2d14bfba3d7f09a242cf88fdd04ee951","LICENSE":"b946744aeda89b467929585fe8eeb5461847695220c1b168fb375d8abd4ea3d0","README.md":"a65ed5c817c867fe23bc2029f34baea4a645a07dd5d101a0027e796d2923be58","benches/split.rs":"632a011dfc6d8235dea853785061b7bbfe0362eb85b91b3b01fbf77a7f1c7f26","src/bsp.rs":"60a306ecb7032a57bc5a7b7f094cb9669f7cd112894f85e6e2fc501a608a9404","src/clip.rs":"838cee6106d240581d1cfcba5d47b67f99a1360748ce7c56531dc4582121fc34","src/lib.rs":"a9ce93011a0b0702a1df2a342aeeb9982a3c8a819b20fefa284686ee0fa04d08","src/polygon.rs":"8c2509698441582d66ca86c35ca6fa924aeaf891a2bb1fc6b08bb311d11ae738","tests/clip.rs":"3335364fd6849697d3919084be5dce6c49acb31d8c53adc93a4cd05ee2ea93a9","tests/main.rs":"ed807b036c475ab99973124c31a9932da51e77e7e580cdc182e98a96af6be941","tests/split.rs":"0eb1afb1f26cdecd5fffbf32d57e889f8f69254c0a57eecb8ccbbdf38efcdf27"},"package":"64d766f38b15fe1337bdddfc869ef5c50437323f857aaaadc6490197db80a1b8"}
\ No newline at end of file
+{"files":{".travis.yml":"b76d49f66f842c652d40825c67791352364a6b6bbb7d8d1009f2ac79eb413e66","Cargo.toml":"5eab4dba3f19782995f02da90370806ad27d8bdd76d81332a62794baff7434a4","LICENSE":"b946744aeda89b467929585fe8eeb5461847695220c1b168fb375d8abd4ea3d0","README.md":"a65ed5c817c867fe23bc2029f34baea4a645a07dd5d101a0027e796d2923be58","benches/split.rs":"632a011dfc6d8235dea853785061b7bbfe0362eb85b91b3b01fbf77a7f1c7f26","src/bsp.rs":"25358cd319195ed1f23068be70aab86f057b12a6117d88be3fdf111cc8c6353c","src/clip.rs":"838cee6106d240581d1cfcba5d47b67f99a1360748ce7c56531dc4582121fc34","src/lib.rs":"a9ce93011a0b0702a1df2a342aeeb9982a3c8a819b20fefa284686ee0fa04d08","src/polygon.rs":"3fa806dd1529a23caf86d81a64b812698ee76ab28ebef442b79e7f90f3d99e3e","tests/clip.rs":"3335364fd6849697d3919084be5dce6c49acb31d8c53adc93a4cd05ee2ea93a9","tests/main.rs":"1ac76121187062b5469cfaad385d957e0678edb8b1ab80bbfaa8dc1c6af25e8d","tests/split.rs":"0eb1afb1f26cdecd5fffbf32d57e889f8f69254c0a57eecb8ccbbdf38efcdf27"},"package":"cd1ab9bf7197c31ac8004a487cd1ddc5cf420029fb53023fdcab0540b5fa1410"}
\ No newline at end of file
diff --git a/third_party/rust/plane-split/Cargo.toml b/third_party/rust/plane-split/Cargo.toml
index d2b3d552ab03bb23a184c02b6ddae0e97f5caf3c..81aeda50c1e1a5e07f64fc25ce3c4771b10e0d59 100644
--- a/third_party/rust/plane-split/Cargo.toml
+++ b/third_party/rust/plane-split/Cargo.toml
@@ -12,7 +12,7 @@
 
 [package]
 name = "plane-split"
-version = "0.13.0"
+version = "0.13.1"
 authors = ["Dzmitry Malyshau <kvark@mozilla.com>"]
 description = "Plane splitting"
 documentation = "https://docs.rs/plane-split"
diff --git a/third_party/rust/plane-split/src/bsp.rs b/third_party/rust/plane-split/src/bsp.rs
index 49c915e02dd6c1d65a81f8d2be0e315fcb622599..80d4afcae4f3ecf577a88ddc836a80af8538b604 100644
--- a/third_party/rust/plane-split/src/bsp.rs
+++ b/third_party/rust/plane-split/src/bsp.rs
@@ -1,4 +1,5 @@
 use {Intersection, Plane, Polygon, Splitter};
+use is_zero;
 
 use binary_space_partition::{BspNode, Plane as BspPlane, PlaneCut};
 use euclid::{TypedPoint3D, TypedVector3D};
@@ -15,47 +16,63 @@ impl<T, U> BspPlane for Polygon<T, U> where
         Zero + One + Float,
     U: fmt::Debug,
 {
-    fn cut(&self, mut plane: Self) -> PlaneCut<Self> {
-        debug!("\tCutting anchor {}", plane.anchor);
-        let dist = self.plane.signed_distance_sum_to(&plane);
+    fn cut(&self, mut poly: Self) -> PlaneCut<Self> {
+        debug!("\tCutting anchor {} by {}", poly.anchor, self.anchor);
+        trace!("\t\tbase {:?}", self.plane);
 
-        match self.intersect(&plane) {
-            Intersection::Coplanar if dist.approx_eq(&T::zero()) => {
-                debug!("\t\tCoplanar and matching");
-                PlaneCut::Sibling(plane)
+        let (intersection, dist) = if self.plane.normal
+            .dot(poly.plane.normal)
+            .approx_eq(&T::one())
+        {
+            debug!("\t\tNormals roughly match");
+            (Intersection::Coplanar, self.plane.offset - poly.plane.offset)
+        } else {
+            let is = self.intersect(&poly);
+            let dist = self.plane.signed_distance_sum_to(&poly);
+            (is, dist)
+        };
+
+        match intersection {
+            //Note: we deliberately make the comparison wider than just with T::epsilon().
+            // This is done to avoid mistakenly ordering items that should be on the same
+            // plane but end up slightly different due to the floating point precision.
+            Intersection::Coplanar if is_zero(dist) => {
+                debug!("\t\tCoplanar at {:?}", dist);
+                PlaneCut::Sibling(poly)
             }
             Intersection::Coplanar | Intersection::Outside => {
-                debug!("\t\tCoplanar at {:?}", dist);
+                debug!("\t\tOutside at {:?}", dist);
                 if dist > T::zero() {
                     PlaneCut::Cut {
-                        front: vec![plane],
+                        front: vec![poly],
                         back: vec![],
                     }
                 } else {
                     PlaneCut::Cut {
                         front: vec![],
-                        back: vec![plane],
+                        back: vec![poly],
                     }
                 }
             }
             Intersection::Inside(line) => {
-                let (res_add1, res_add2) = plane.split(&line);
+                debug!("\t\tCut across {:?}", line);
+                let (res_add1, res_add2) = poly.split(&line);
                 let mut front = Vec::new();
                 let mut back = Vec::new();
 
-                for sub in iter::once(plane)
+                for sub in iter::once(poly)
                     .chain(res_add1)
                     .chain(res_add2)
                     .filter(|p| !p.is_empty())
                 {
                     if self.plane.signed_distance_sum_to(&sub) > T::zero() {
+                        trace!("\t\t\tfront: {:?}", sub);
                         front.push(sub)
                     } else {
+                        trace!("\t\t\tback: {:?}", sub);
                         back.push(sub)
                     }
                 }
-                debug!("\t\tCut across {:?} by {} in front and {} in back",
-                    line, front.len(), back.len());
 
                 PlaneCut::Cut {
                     front,
diff --git a/third_party/rust/plane-split/src/polygon.rs b/third_party/rust/plane-split/src/polygon.rs
index ba903d62dfce87963af3ccda890b94351684d77f..8bc2a1cb2130dca73e88523e78de3ec733594ba4 100644
--- a/third_party/rust/plane-split/src/polygon.rs
+++ b/third_party/rust/plane-split/src/polygon.rs
@@ -161,15 +161,19 @@ impl<T, U> Polygon<T, U> where
 
     /// Construct a polygon from a non-transformed rectangle.
     pub fn from_rect(rect: TypedRect<T, U>, anchor: usize) -> Self {
-        Self::from_points(
-            [
+        Polygon {
+            points: [
                 rect.origin.to_3d(),
                 rect.top_right().to_3d(),
                 rect.bottom_right().to_3d(),
                 rect.bottom_left().to_3d(),
             ],
+            plane: Plane {
+                normal: TypedVector3D::new(T::zero(), T::zero(), T::one()),
+                offset: T::zero(),
+            },
             anchor,
-        ).unwrap()
+        }
     }
 
     /// Construct a polygon from a rectangle with 3D transform.
@@ -187,13 +191,48 @@ impl<T, U> Polygon<T, U> where
             transform.transform_point3d(&rect.bottom_right().to_3d())?,
             transform.transform_point3d(&rect.bottom_left().to_3d())?,
         ];
-
-        //Note: this code path could be more efficient if we had inverse-transpose
-        //let n4 = transform.transform_point4d(&TypedPoint4D::new(T::zero(), T::zero(), T::one(), T::zero()));
-        //let normal = TypedPoint3D::new(n4.x, n4.y, n4.z);
         Self::from_points(points, anchor)
     }
 
+    /// Construct a polygon from a rectangle with an invertible 3D transform.
+    pub fn from_transformed_rect_with_inverse<V>(
+        rect: TypedRect<T, V>,
+        transform: &TypedTransform3D<T, V, U>,
+        inv_transform: &TypedTransform3D<T, U, V>,
+        anchor: usize,
+    ) -> Option<Self>
+    where
+        T: Trig + ops::Neg<Output=T>,
+    {
+        let points = [
+            transform.transform_point3d(&rect.origin.to_3d())?,
+            transform.transform_point3d(&rect.top_right().to_3d())?,
+            transform.transform_point3d(&rect.bottom_right().to_3d())?,
+            transform.transform_point3d(&rect.bottom_left().to_3d())?,
+        ];
+
+        // Compute the normal directly from the transformation. This guarantees consistent polygons
+        // generated from various local rectanges on the same geometry plane.
+        let normal_raw = TypedVector3D::new(inv_transform.m13, inv_transform.m23, inv_transform.m33);
+        let normal_sql = normal_raw.square_length();
+        if normal_sql.approx_eq(&T::zero()) {
+            None
+        } else {
+            let normal = normal_raw / normal_sql.sqrt();
+            let offset = -TypedVector3D::new(transform.m41, transform.m42, transform.m43)
+                .dot(normal) * transform.m44;
+
+            Some(Polygon {
+                points,
+                plane: Plane {
+                    normal,
+                    offset,
+                },
+                anchor,
+            })
+        }
+    }
+
     /// Bring a point into the local coordinate space, returning
     /// the 2D normalized coordinates.
     pub fn untransform_point(&self, point: TypedPoint3D<T, U>) -> Point2D<T> {
diff --git a/third_party/rust/plane-split/tests/main.rs b/third_party/rust/plane-split/tests/main.rs
index fe112bd4d4f2e134bf8cb720fb5acf9e903abe01..06a709af430f19e2e27aa56ba2a5d55e019288c4 100644
--- a/third_party/rust/plane-split/tests/main.rs
+++ b/third_party/rust/plane-split/tests/main.rs
@@ -78,8 +78,14 @@ fn from_transformed_rect() {
     let transform: TypedTransform3D<f32, (), ()> =
         TypedTransform3D::create_rotation(0.5f32.sqrt(), 0.0, 0.5f32.sqrt(), Angle::radians(5.0))
         .pre_translate(vec3(0.0, 0.0, 10.0));
-    let poly = Polygon::from_transformed_rect(rect, transform, 0);
-    assert!(poly.is_some() && poly.unwrap().is_valid());
+    let poly = Polygon::from_transformed_rect(rect, transform, 0).unwrap();
+    assert!(poly.is_valid());
+
+    let inv_transform = transform.inverse().unwrap();
+    let poly2 = Polygon::from_transformed_rect_with_inverse(rect, &transform, &inv_transform, 0).unwrap();
+    assert_eq!(poly.points, poly2.points);
+    assert!(poly.plane.offset.approx_eq(&poly2.plane.offset));
+    assert!(poly.plane.normal.dot(poly2.plane.normal).approx_eq(&1.0));
 }
 
 #[test]
diff --git a/toolkit/components/antitracking/test/browser/browser_blockingWorkers.js b/toolkit/components/antitracking/test/browser/browser_blockingWorkers.js
index 3d41fd93198ccf7878430cf8c25eb483b192529e..e9049b37e45d85fab98942c03d49aa1d2965164e 100644
--- a/toolkit/components/antitracking/test/browser/browser_blockingWorkers.js
+++ b/toolkit/components/antitracking/test/browser/browser_blockingWorkers.js
@@ -128,7 +128,8 @@ AntiTracking.runTest("ServiceWorkers and Storage Access API",
 
     await navigator.serviceWorker.register("empty.js").then(
       _ => { ok(false, "ServiceWorker cannot be used!"); },
-      _ => { ok(true, "ServiceWorker cannot be used!"); });
+      _ => { ok(true, "ServiceWorker cannot be used!"); }).
+      catch(e => ok(false, "Promise rejected: " + e));
 
     let dwu = SpecialPowers.getDOMWindowUtils(window);
     let helper = dwu.setHandlingUserInput(true);
@@ -148,7 +149,8 @@ AntiTracking.runTest("ServiceWorkers and Storage Access API",
       reg => { ok(true, "ServiceWorker can be used!"); return reg; },
       _ => { ok(false, "ServiceWorker cannot be used! " + _); }).then(
       reg => reg.unregister(),
-      _ => { ok(false, "unregister failed"); });
+      _ => { ok(false, "unregister failed"); }).
+      catch(e => ok(false, "Promise rejected: " + e));
   },
   async _ => {
     await SpecialPowers.pushPrefEnv({"set": [
@@ -164,7 +166,8 @@ AntiTracking.runTest("ServiceWorkers and Storage Access API",
       reg => { ok(true, "ServiceWorker can be used!"); return reg; },
       _ => { ok(false, "ServiceWorker cannot be used!"); }).then(
       reg => reg.unregister(),
-      _ => { ok(false, "unregister failed"); });
+      _ => { ok(false, "unregister failed"); }).
+      catch(e => ok(false, "Promise rejected: " + e));
 
     let dwu = SpecialPowers.getDOMWindowUtils(window);
     let helper = dwu.setHandlingUserInput(true);
@@ -185,7 +188,8 @@ AntiTracking.runTest("ServiceWorkers and Storage Access API",
       reg => { ok(true, "ServiceWorker can be used!"); return reg; },
       _ => { ok(false, "ServiceWorker cannot be used!"); }).then(
       reg => reg.unregister(),
-      _ => { ok(false, "unregister failed"); });
+      _ => { ok(false, "unregister failed"); }).
+      catch(e => ok(false, "Promise rejected: " + e));
   },
   async _ => {
     await new Promise(resolve => {
diff --git a/tools/fuzzing/faulty/Faulty.cpp b/tools/fuzzing/faulty/Faulty.cpp
index 3e4a24501c58493b6fea6d6a634b467360093204..dde4e33e3df84325d4c1f5fd4d29dec54bb5b63d 100644
--- a/tools/fuzzing/faulty/Faulty.cpp
+++ b/tools/fuzzing/faulty/Faulty.cpp
@@ -752,8 +752,6 @@ Faulty::ReadFile(const char* aPathname, nsTArray<nsCString> &aArray)
     aArray.AppendElement(line);
   } while (more);
 
-  file.forget();
-
   return NS_OK;
 }
 
diff --git a/widget/android/nsWindow.cpp b/widget/android/nsWindow.cpp
index a0ddbca2e5e67d90613c8c73ba80fbcc95644855..3d6edd1f8ba0ce4e55759b1fdc05972f99571b4d 100644
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -17,6 +17,7 @@
 #include "mozilla/WeakPtr.h"
 #include "mozilla/WheelHandlingHelper.h"    // for WheelDeltaAdjustmentStrategy
 
+#include "mozilla/a11y/SessionAccessibility.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/MouseEventBinding.h"
@@ -285,6 +286,7 @@ public:
                      jni::Object::Param aQueue,
                      jni::Object::Param aCompositor,
                      jni::Object::Param aDispatcher,
+                     jni::Object::Param aSessionAccessibility,
                      jni::Object::Param aInitData,
                      jni::String::Param aId,
                      jni::String::Param aChromeURI,
@@ -299,12 +301,16 @@ public:
                   jni::Object::Param aQueue,
                   jni::Object::Param aCompositor,
                   jni::Object::Param aDispatcher,
+                  jni::Object::Param aSessionAccessibility,
                   jni::Object::Param aInitData);
 
     void AttachEditable(const GeckoSession::Window::LocalRef& inst,
                         jni::Object::Param aEditableParent,
                         jni::Object::Param aEditableChild);
 
+    void AttachAccessibility(const GeckoSession::Window::LocalRef& inst,
+                             jni::Object::Param aSessionAccessibility);
+
     void OnReady(jni::Object::Param aQueue = nullptr);
 };
 
@@ -1135,6 +1141,10 @@ nsWindow::GeckoViewSupport::~GeckoViewSupport()
     if (window.mLayerViewSupport) {
         window.mLayerViewSupport.Detach();
     }
+
+    if (window.mSessionAccessibility) {
+        window.mSessionAccessibility.Detach();
+    }
 }
 
 /* static */ void
@@ -1143,6 +1153,7 @@ nsWindow::GeckoViewSupport::Open(const jni::Class::LocalRef& aCls,
                                  jni::Object::Param aQueue,
                                  jni::Object::Param aCompositor,
                                  jni::Object::Param aDispatcher,
+                                 jni::Object::Param aSessionAccessibility,
                                  jni::Object::Param aInitData,
                                  jni::String::Param aId,
                                  jni::String::Param aChromeURI,
@@ -1198,7 +1209,7 @@ nsWindow::GeckoViewSupport::Open(const jni::Class::LocalRef& aCls,
 
     // Attach other session support objects.
     window->mGeckoViewSupport->Transfer(
-            sessionWindow, aQueue, aCompositor, aDispatcher, aInitData);
+            sessionWindow, aQueue, aCompositor, aDispatcher, aSessionAccessibility, aInitData);
 
     if (window->mWidgetListener) {
         nsCOMPtr<nsIXULWindow> xulWindow(
@@ -1232,6 +1243,7 @@ nsWindow::GeckoViewSupport::Transfer(const GeckoSession::Window::LocalRef& inst,
                                      jni::Object::Param aQueue,
                                      jni::Object::Param aCompositor,
                                      jni::Object::Param aDispatcher,
+                                     jni::Object::Param aSessionAccessibility,
                                      jni::Object::Param aInitData)
 {
     if (window.mNPZCSupport) {
@@ -1253,6 +1265,13 @@ nsWindow::GeckoViewSupport::Transfer(const GeckoSession::Window::LocalRef& inst,
     window.mAndroidView->mEventDispatcher->Attach(
             java::EventDispatcher::Ref::From(aDispatcher), mDOMWindow);
 
+    if (window.mSessionAccessibility) {
+        window.mSessionAccessibility.Detach();
+    }
+    if (aSessionAccessibility) {
+        AttachAccessibility(inst, aSessionAccessibility);
+    }
+
     if (mIsReady) {
         // We're in a transfer; update init-data and notify JS code.
         window.mAndroidView->mInitData =
@@ -1285,6 +1304,24 @@ nsWindow::GeckoViewSupport::AttachEditable(const GeckoSession::Window::LocalRef&
     window.mEditableParent = aEditableParent;
 }
 
+void
+nsWindow::GeckoViewSupport::AttachAccessibility(const GeckoSession::Window::LocalRef& inst,
+                                                jni::Object::Param aSessionAccessibility)
+{
+    MOZ_ASSERT(!window.mSessionAccessibility);
+    java::SessionAccessibility::NativeProvider::LocalRef sessionAccessibility(
+      inst.Env());
+    sessionAccessibility = java::SessionAccessibility::NativeProvider::Ref::From(
+      aSessionAccessibility);
+
+    if (window.mSessionAccessibility) {
+        window.mSessionAccessibility.Detach();
+    }
+
+    window.mSessionAccessibility.Attach(
+      sessionAccessibility, &window, sessionAccessibility);
+}
+
 void
 nsWindow::InitNatives()
 {
@@ -1293,6 +1330,7 @@ nsWindow::InitNatives()
     nsWindow::NPZCSupport::Init();
 
     GeckoEditableSupport::Init();
+    a11y::SessionAccessibility::Init();
 }
 
 nsWindow*
@@ -2342,4 +2380,3 @@ nsIWidget::CreateChildWindow()
   nsCOMPtr<nsIWidget> window = new nsWindow();
   return window.forget();
 }
-
diff --git a/widget/android/nsWindow.h b/widget/android/nsWindow.h
index a9e3f8bff55c519b9e0d5939dba5182beb4346a3..6d6bf3050bb6e77beedba13641a33a98ffabc385 100644
--- a/widget/android/nsWindow.h
+++ b/widget/android/nsWindow.h
@@ -38,6 +38,10 @@ namespace mozilla {
     namespace ipc {
         class Shmem;
     } // namespace ipc
+
+    namespace a11y {
+      class SessionAccessibility;
+    }
 }
 
 class nsWindow final : public nsBaseWidget
@@ -186,6 +190,10 @@ private:
     NativePtr<mozilla::widget::GeckoEditableSupport> mEditableSupport;
     mozilla::jni::Object::GlobalRef mEditableParent;
 
+    // Object that implements native SessionAccessibility calls.
+    // Strong referenced by the Java instance.
+    NativePtr<mozilla::a11y::SessionAccessibility> mSessionAccessibility;
+
     class GeckoViewSupport;
     // Object that implements native GeckoView calls and associated states.
     // nullptr for nsWindows that were not opened from GeckoView.
@@ -306,6 +314,8 @@ public:
 
     mozilla::jni::Object::Ref& GetEditableParent() { return mEditableParent; }
 
+    mozilla::a11y::SessionAccessibility* GetSessionAccessibility() { return mSessionAccessibility; }
+
     void RecvToolbarAnimatorMessageFromCompositor(int32_t aMessage) override;
     void UpdateRootFrameMetrics(const ScreenPoint& aScrollOffset, const CSSToScreenScale& aZoom) override;
     void RecvScreenPixels(mozilla::ipc::Shmem&& aMem, const ScreenIntSize& aSize) override;
@@ -353,6 +363,7 @@ private:
 // Explicit template declarations to make clang be quiet.
 template<> const char nsWindow::NativePtr<nsWindow::LayerViewSupport>::sName[];
 template<> const char nsWindow::NativePtr<mozilla::widget::GeckoEditableSupport>::sName[];
+template<> const char nsWindow::NativePtr<mozilla::a11y::SessionAccessibility>::sName[];
 template<> const char nsWindow::NativePtr<nsWindow::NPZCSupport>::sName[];
 
 template<class Impl>