Merge mozilla-inbound to mozilla-central. a=merge
authorAndreea Pavel <apavel@mozilla.com>
Thu, 22 Mar 2018 11:31:19 +0200
changeset 771093 7771df14ea181add1dc4133f0f5559bf620bf976
parent 771048 f82d56c64966a27cd87ab53025ebc774936b3657 (current diff)
parent 771092 912c50cd3b665c2048174079b817bf6381cf7803 (diff)
child 771094 cafba51b6d345d8074d0cac2777bf9a26b0056f9
child 771095 3fba4fa99153d01670b5896a1bbd5322b54e2914
child 771096 10e9f26c6b7c25f22baca91bc2834053ab0f4f3f
child 771097 ec3a3ecfa4088859e510ba4e844b88720e57bf20
child 771098 55ad88b4de53230c4a2e6a31888715d54f042edb
child 771099 d2c10a0ac9adf0c286caadb1ebf649a5b4ad97f7
child 771101 55a387ceb6b9c16fb5822cf02699f494a796e5c8
child 771105 ddb5c619009b09afee0a9e077b0498dcc17b520f
child 771112 caccdbc1e77ce78411e61798629a1bfa542c2972
child 771115 ca203874cd1a2ee7f6df8108ae6c7f48fdcfd42f
child 771116 7f8fac4f7206f477495817aeaedce259ea23ddb0
child 771117 966a8a5069990f1a9d8081dfa32916ceda525b6a
child 771132 30d6a5d1373477f0c55c9f0926f5bdc53bc6a205
child 771146 7c4b08deb2b138137312e86bbe438a6803d4b1bb
child 771154 64fb0d6f48766831bc8e4d4552a202f81d13eb06
child 771155 b39f113710fee4c57eecd7c9025c34410ff475c6
child 771158 692c5b38174de76e54f584f410e990d3b05ccd28
child 771163 de5a6240acef09e3a9404aed9b9b11121329b1f6
child 771168 c1c0aabbf3092f76dde77a351d5d9eacf687b6c8
child 771169 9dd29f87106500717371eb180fff29bf1b9d5f2a
child 771186 5cbf9fa99d1646e6d6c7278e4433c6aa4a58d1a5
child 771189 01c477613c35d62c0bd95b83fe558d7420cbbd2d
child 771193 34b6fa670d2887b1d8dc05eb2d30a1dbf5862cfe
child 771196 74bc5258dd140e89ab8ca0b3961c199dd7b55f08
child 771197 45c68037f1020ac8ad075ffed7ca7f06cb916ca8
child 771202 a7ac08b1a07f5bf343bd9c110439ac9f3dd24de8
child 771221 d287fffc0d4db8f0128f788d514c3aa4c6bad69c
child 771226 079d5028aec4d6f127da83906868faf1e62ae04b
child 771234 990e49545902f12b76636986853c1d90f2c3d9dc
child 771235 53ed6485a0b95806c1c3a84859c49db50e9e3464
child 771236 ecb81523a2dc1c447cb39eb9d6d721a60a2739c3
child 771237 9944a62024f6b342427a6b012cc7e1d89ed06fe6
child 771239 ecef80bdc1f8b30e7930be3b327c2622255bf5dc
child 771241 92ed093575d397e88f61360fef68d4ad2af34e82
child 771243 7b9591f3279b109eff902b6fae5093073f4796cf
child 771245 b718d6226f6bf7ecc9ca565c13235be6acd63505
child 771248 ea71854e7c6efbc932b7223b9be8c8d9f4894433
child 771249 03cf76a5ded25b64baada3e0e81fe084bc7afbbd
child 771257 3f93d6fee2861a041b537bf9d0ddc2a521c9595a
child 771260 8e52cfef41eb0283b40e88b051d4f0f3f84751f4
child 771263 a8559a3c2f4ac9d7b37f9aaf09545f50530b59c1
child 771264 9e32ccaacf52d87e3e4d26a0e28ca96f9a1a8a2c
child 771311 f81d96b07df8085e9d80d10cd01177ae676de1ce
child 771318 e341f681b60f4570454c5483c226b0443b3c2b3e
child 771321 4598a849cbf84c56e6bdbe6c71cfa20f0467a395
child 771343 96a4b10d1b2f5df7a82da3f78287e5d397875f1c
child 771529 b31550ef8db116ec94fa6687f7ffebae32b376c7
child 771532 9a4115cbc5e1172476ebe22c632b1753628d75a6
child 771568 c39894772f672caf82b827966e91d6a6e6c5ff25
child 771569 5ca9ad773c3f70f9819658c3b263de1dd7ad7a8f
child 771571 df585e4c7ddb3b048883413576fb29a6814bb912
child 771574 0bdd94e00c9f0d672fcc2f7c637fb7c1c0e1bf50
child 771586 46f1efc022f00ca32c9128842931592c4784b282
child 771595 6fb3d373e6bdd7cf041c23426adf29817fbbbd05
child 771650 419692d1b1ae3e9c7f7ebf10dafb82f8e35b1b4e
child 771720 588614c750f40f78a751369a507c050a608be999
child 771786 1a99a824f00a810d45ad11b261f20563ae473a53
child 771962 182ebd7dd3f8b7427164829ee82ffcb8a829306f
child 772500 d6045662afdd08e981cfaa0c7056151d63f639b5
child 772570 5d1f48fe3b58348d2568d374c1f4eed1766d4a1c
child 772607 83c484b43082f2bf9bb79ccb470cb5ab5f8a9691
child 773307 5bbde49ee899ebaf52baf82909d1b555060da737
child 773880 15bc6b16e6c8302920a2bea95d36e9420f017c25
child 774060 269f22995c5de08fac1b206b449784b133cbc311
child 774821 2fa3f6db777177ed17deb429431abf55184e36e7
child 776609 74f617894a3a76bcd8a90cea4b45f989541e4d00
child 778019 160f81a30164d4707c5dde5b6ff970ebf302e34f
child 778123 6ef4178ec560b862405547850b2dd1e27eda561a
child 778392 fdb86aeae97748ea52a175bae04989742ffcd4a3
child 778551 039f7894ebebb84750d8ed90f7e95a41c85e3efb
child 779179 978a5bc48b17e61caca85b7f397797d998c0a8c2
push id103553
push usermleplatre@mozilla.com
push dateThu, 22 Mar 2018 10:33:25 +0000
reviewersmerge
milestone61.0a1
Merge mozilla-inbound to mozilla-central. a=merge
browser/base/content/test/static/browser_parsable_css.js
dom/base/nsDOMClassInfoID.h
dom/base/nsIFrameLoader.idl
dom/base/nsIScriptNameSpaceManager.h
dom/base/nsScriptNameSpaceManager.cpp
dom/base/nsScriptNameSpaceManager.h
dom/interfaces/base/nsIDOMConstructor.idl
dom/ipc/ContentParent.cpp
dom/tests/mochitest/bugs/test_bug597809.html
dom/tests/mochitest/bugs/test_bug641552.html
layout/generic/nsImageFrame.cpp
toolkit/mozapps/extensions/test/mochitest/test_bug609794.html
--- a/accessible/atk/nsMaiInterfaceText.cpp
+++ b/accessible/atk/nsMaiInterfaceText.cpp
@@ -155,21 +155,54 @@ getTextCB(AtkText *aText, gint aStartOff
   } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
     return DOMtoATK::NewATKString(proxy, aStartOffset, aEndOffset,
          DOMtoATK::AtkStringConvertFlags::None);
   }
 
   return nullptr;
 }
 
+static gint getCharacterCountCB(AtkText* aText);
+
+// Note: this does not support magic offsets, which is fine for its callers
+// which do not implement any.
+static gchar*
+getCharTextAtOffset(AtkText* aText, gint aOffset,
+                    gint* aStartOffset, gint* aEndOffset)
+{
+  gint end = aOffset + 1;
+  gint count = getCharacterCountCB(aText);
+
+  if (aOffset > count) {
+    aOffset = count;
+  }
+  if (end > count) {
+    end = count;
+  }
+  if (aOffset < 0) {
+    aOffset = 0;
+  }
+  if (end < 0) {
+    end = 0;
+  }
+  *aStartOffset = aOffset;
+  *aEndOffset = end;
+
+  return getTextCB(aText, aOffset, end);
+}
+
 static gchar*
 getTextAfterOffsetCB(AtkText *aText, gint aOffset,
                      AtkTextBoundary aBoundaryType,
                      gint *aStartOffset, gint *aEndOffset)
 {
+  if (aBoundaryType == ATK_TEXT_BOUNDARY_CHAR) {
+    return getCharTextAtOffset(aText, aOffset + 1, aStartOffset, aEndOffset);
+  }
+
     nsAutoString autoStr;
   int32_t startOffset = 0, endOffset = 0;
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
   if (accWrap) {
     HyperTextAccessible* text = accWrap->AsHyperText();
     if (!text || !text->IsTextRole())
       return nullptr;
 
@@ -187,16 +220,20 @@ getTextAfterOffsetCB(AtkText *aText, gin
   return DOMtoATK::Convert(autoStr);
 }
 
 static gchar*
 getTextAtOffsetCB(AtkText *aText, gint aOffset,
                   AtkTextBoundary aBoundaryType,
                   gint *aStartOffset, gint *aEndOffset)
 {
+  if (aBoundaryType == ATK_TEXT_BOUNDARY_CHAR) {
+    return getCharTextAtOffset(aText, aOffset, aStartOffset, aEndOffset);
+  }
+
   nsAutoString autoStr;
   int32_t startOffset = 0, endOffset = 0;
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
   if (accWrap) {
     HyperTextAccessible* text = accWrap->AsHyperText();
     if (!text || !text->IsTextRole())
       return nullptr;
 
@@ -233,16 +270,20 @@ getCharacterAtOffsetCB(AtkText* aText, g
   return 0;
 }
 
 static gchar*
 getTextBeforeOffsetCB(AtkText *aText, gint aOffset,
                       AtkTextBoundary aBoundaryType,
                       gint *aStartOffset, gint *aEndOffset)
 {
+  if (aBoundaryType == ATK_TEXT_BOUNDARY_CHAR) {
+    return getCharTextAtOffset(aText, aOffset - 1, aStartOffset, aEndOffset);
+  }
+
   nsAutoString autoStr;
   int32_t startOffset = 0, endOffset = 0;
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
   if (accWrap) {
     HyperTextAccessible* text = accWrap->AsHyperText();
     if (!text || !text->IsTextRole())
       return nullptr;
 
--- a/accessible/base/AccIterator.cpp
+++ b/accessible/base/AccIterator.cpp
@@ -134,17 +134,17 @@ HTMLLabelIterator::
   mAcc(aAccessible), mLabelFilter(aFilter)
 {
 }
 
 bool
 HTMLLabelIterator::IsLabel(Accessible* aLabel)
 {
   dom::HTMLLabelElement* labelEl =
-    dom::HTMLLabelElement::FromContent(aLabel->GetContent());
+    dom::HTMLLabelElement::FromNode(aLabel->GetContent());
   return labelEl && labelEl->GetControl() == mAcc->GetContent();
 }
 
 Accessible*
 HTMLLabelIterator::Next()
 {
   // Get either <label for="[id]"> element which explicitly points to given
   // element, or <label> ancestor which implicitly point to it.
--- a/accessible/base/nsCoreUtils.cpp
+++ b/accessible/base/nsCoreUtils.cpp
@@ -43,17 +43,17 @@ using namespace mozilla;
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsCoreUtils
 ////////////////////////////////////////////////////////////////////////////////
 
 bool
 nsCoreUtils::IsLabelWithControl(nsIContent* aContent)
 {
-  dom::HTMLLabelElement* label = dom::HTMLLabelElement::FromContent(aContent);
+  dom::HTMLLabelElement* label = dom::HTMLLabelElement::FromNode(aContent);
   if (label && label->GetControl())
     return true;
 
   return false;
 }
 
 bool
 nsCoreUtils::HasClickListener(nsIContent *aContent)
@@ -95,17 +95,17 @@ nsCoreUtils::DispatchClickEvent(nsITreeB
   nsresult rv = aTreeBoxObj->GetCoordsForCellItem(aRowIndex, aColumn,
                                                   aPseudoElt,
                                                   &x, &y, &width, &height);
   if (NS_FAILED(rv))
     return;
 
   nsCOMPtr<nsIContent> tcXULElm(do_QueryInterface(tcElm));
   nsCOMPtr<nsIBoxObject> tcBoxObj =
-    nsXULElement::FromContent(tcXULElm)->GetBoxObject(IgnoreErrors());
+    nsXULElement::FromNode(tcXULElm)->GetBoxObject(IgnoreErrors());
 
   int32_t tcX = 0;
   tcBoxObj->GetX(&tcX);
 
   int32_t tcY = 0;
   tcBoxObj->GetY(&tcY);
 
   // Dispatch mouse events.
@@ -488,34 +488,34 @@ nsCoreUtils::GetLanguageFor(nsIContent *
 }
 
 already_AddRefed<nsIBoxObject>
 nsCoreUtils::GetTreeBodyBoxObject(nsITreeBoxObject *aTreeBoxObj)
 {
   nsCOMPtr<nsIDOMElement> tcElm;
   aTreeBoxObj->GetTreeBody(getter_AddRefs(tcElm));
   nsCOMPtr<nsIContent> tcContent(do_QueryInterface(tcElm));
-  RefPtr<nsXULElement> tcXULElm = nsXULElement::FromContentOrNull(tcContent);
+  RefPtr<nsXULElement> tcXULElm = nsXULElement::FromNodeOrNull(tcContent);
   if (!tcXULElm)
     return nullptr;
 
   return tcXULElm->GetBoxObject(IgnoreErrors());
 }
 
 already_AddRefed<nsITreeBoxObject>
 nsCoreUtils::GetTreeBoxObject(nsIContent *aContent)
 {
   // Find DOMNode's parents recursively until reach the <tree> tag
   nsIContent* currentContent = aContent;
   while (currentContent) {
     if (currentContent->NodeInfo()->Equals(nsGkAtoms::tree,
                                            kNameSpaceID_XUL)) {
       // We will get the nsITreeBoxObject from the tree node
       RefPtr<nsXULElement> xulElement =
-        nsXULElement::FromContent(currentContent);
+        nsXULElement::FromNode(currentContent);
       nsCOMPtr<nsIBoxObject> box = xulElement->GetBoxObject(IgnoreErrors());
       nsCOMPtr<nsITreeBoxObject> treeBox(do_QueryInterface(box));
       if (treeBox)
         return treeBox.forget();
     }
     currentContent = currentContent->GetFlattenedTreeParent();
   }
 
--- a/accessible/generic/Accessible.cpp
+++ b/accessible/generic/Accessible.cpp
@@ -640,17 +640,17 @@ Accessible::RelativeBounds(nsIFrame** aB
         canvasFrame = nsLayoutUtils::GetClosestFrameOfType(
           canvasFrame, LayoutFrameType::HTMLCanvas);
       }
 
       // make the canvas the bounding frame
       if (canvasFrame) {
         *aBoundingFrame = canvasFrame;
         dom::HTMLCanvasElement *canvas =
-          dom::HTMLCanvasElement::FromContent(canvasFrame->GetContent());
+          dom::HTMLCanvasElement::FromNode(canvasFrame->GetContent());
 
         // get the bounding rect of the hit region
         nsRect bounds;
         if (canvas && canvas->CountContexts() &&
           canvas->GetContextAtIndex(0)->GetHitRegionRect(mContent->AsElement(), bounds)) {
           return bounds;
         }
       }
@@ -1062,17 +1062,17 @@ Accessible::NativeAttributes()
     nsAccUtils::SetAccAttr(attributes, nsGkAtoms::_class, _class);
 
   // Expose tag.
   nsAutoString tagName;
   mContent->NodeInfo()->GetName(tagName);
   nsAccUtils::SetAccAttr(attributes, nsGkAtoms::tag, tagName);
 
   // Expose draggable object attribute.
-  if (auto htmlElement = nsGenericHTMLElement::FromContent(mContent)) {
+  if (auto htmlElement = nsGenericHTMLElement::FromNode(mContent)) {
     if (htmlElement->Draggable()) {
       nsAccUtils::SetAccAttr(attributes, nsGkAtoms::draggable,
                              NS_LITERAL_STRING("true"));
     }
   }
 
   // Don't calculate CSS-based object attributes when no frame (i.e.
   // the accessible is unattached from the tree).
--- a/accessible/generic/ImageAccessible.cpp
+++ b/accessible/generic/ImageAccessible.cpp
@@ -198,17 +198,17 @@ ImageAccessible::GetLongDescURI() const
   DocAccessible* document = Document();
   if (document) {
     IDRefsIterator iter(document, mContent, nsGkAtoms::aria_describedby);
     while (nsIContent* target = iter.NextElem()) {
       if ((target->IsHTMLElement(nsGkAtoms::a) ||
            target->IsHTMLElement(nsGkAtoms::area)) &&
           target->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::href)) {
         nsGenericHTMLElement* element =
-          nsGenericHTMLElement::FromContent(target);
+          nsGenericHTMLElement::FromNode(target);
 
         nsCOMPtr<nsIURI> uri;
         element->GetURIAttr(nsGkAtoms::href, nullptr, getter_AddRefs(uri));
         return uri.forget();
       }
     }
   }
 
--- a/accessible/html/HTMLElementAccessibles.cpp
+++ b/accessible/html/HTMLElementAccessibles.cpp
@@ -63,17 +63,17 @@ HTMLLabelAccessible::NativeName(nsString
   return aName.IsEmpty() ? eNameOK : eNameFromSubtree;
 }
 
 Relation
 HTMLLabelAccessible::RelationByType(RelationType aType)
 {
   Relation rel = AccessibleWrap::RelationByType(aType);
   if (aType == RelationType::LABEL_FOR) {
-    dom::HTMLLabelElement* label = dom::HTMLLabelElement::FromContent(mContent);
+    dom::HTMLLabelElement* label = dom::HTMLLabelElement::FromNode(mContent);
     rel.AppendTarget(mDoc, label->GetControl());
   }
 
   return rel;
 }
 
 uint8_t
 HTMLLabelAccessible::ActionCount()
@@ -134,17 +134,17 @@ HTMLSummaryAccessible::ActionCount()
 
 void
 HTMLSummaryAccessible::ActionNameAt(uint8_t aIndex, nsAString& aName)
 {
   if (aIndex != eAction_Click) {
     return;
   }
 
-  dom::HTMLSummaryElement* summary = dom::HTMLSummaryElement::FromContent(mContent);
+  dom::HTMLSummaryElement* summary = dom::HTMLSummaryElement::FromNode(mContent);
   if (!summary) {
     return;
   }
 
   dom::HTMLDetailsElement* details = summary->GetDetails();
   if (!details) {
     return;
   }
@@ -166,17 +166,17 @@ HTMLSummaryAccessible::DoAction(uint8_t 
   return true;
 }
 
 uint64_t
 HTMLSummaryAccessible::NativeState()
 {
   uint64_t state = HyperTextAccessibleWrap::NativeState();
 
-  dom::HTMLSummaryElement* summary = dom::HTMLSummaryElement::FromContent(mContent);
+  dom::HTMLSummaryElement* summary = dom::HTMLSummaryElement::FromNode(mContent);
   if (!summary) {
     return state;
   }
 
   dom::HTMLDetailsElement* details = summary->GetDetails();
   if (!details) {
     return state;
   }
--- a/accessible/html/HTMLFormControlAccessible.cpp
+++ b/accessible/html/HTMLFormControlAccessible.cpp
@@ -76,17 +76,17 @@ HTMLCheckboxAccessible::DoAction(uint8_t
 }
 
 uint64_t
 HTMLCheckboxAccessible::NativeState()
 {
   uint64_t state = LeafAccessible::NativeState();
 
   state |= states::CHECKABLE;
-  HTMLInputElement* input = HTMLInputElement::FromContent(mContent);
+  HTMLInputElement* input = HTMLInputElement::FromNode(mContent);
   if (!input)
     return state;
 
   if (input->Indeterminate())
     return state | states::MIXED;
 
   if (input->Checked())
     return state | states::CHECKED;
@@ -110,17 +110,17 @@ HTMLCheckboxAccessible::IsWidget() const
 
 uint64_t
 HTMLRadioButtonAccessible::NativeState()
 {
   uint64_t state = AccessibleWrap::NativeState();
 
   state |= states::CHECKABLE;
 
-  HTMLInputElement* input = HTMLInputElement::FromContent(mContent);
+  HTMLInputElement* input = HTMLInputElement::FromNode(mContent);
   if (input && input->Checked())
     state |= states::CHECKED;
 
   return state;
 }
 
 void
 HTMLRadioButtonAccessible::GetPositionAndSizeInternal(int32_t* aPosInSet,
@@ -340,23 +340,23 @@ HTMLTextFieldAccessible::NativeName(nsSt
 
 void
 HTMLTextFieldAccessible::Value(nsString& aValue)
 {
   aValue.Truncate();
   if (NativeState() & states::PROTECTED)    // Don't return password text!
     return;
 
-  HTMLTextAreaElement* textArea = HTMLTextAreaElement::FromContent(mContent);
+  HTMLTextAreaElement* textArea = HTMLTextAreaElement::FromNode(mContent);
   if (textArea) {
     textArea->GetValue(aValue);
     return;
   }
 
-  HTMLInputElement* input = HTMLInputElement::FromContent(mContent);
+  HTMLInputElement* input = HTMLInputElement::FromNode(mContent);
   if (input) {
     // Pass NonSystem as the caller type, to be safe.  We don't expect to have a
     // file input here.
     input->GetValue(aValue, CallerType::NonSystem);
   }
 }
 
 void
@@ -387,17 +387,17 @@ HTMLTextFieldAccessible::NativeState()
     state |= states::PROTECTED;
   }
 
   if (mContent->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::readonly)) {
     state |= states::READONLY;
   }
 
   // Is it an <input> or a <textarea> ?
-  HTMLInputElement* input = HTMLInputElement::FromContent(mContent);
+  HTMLInputElement* input = HTMLInputElement::FromNode(mContent);
   state |= input && input->IsSingleLineTextControl() ?
     states::SINGLE_LINE : states::MULTI_LINE;
 
   if (state & (states::PROTECTED | states::MULTI_LINE | states::READONLY |
                states::UNAVAILABLE))
     return state;
 
   // Expose autocomplete states if this input is part of autocomplete widget.
@@ -552,66 +552,65 @@ void
 HTMLSpinnerAccessible::Value(nsString& aValue)
 {
   AccessibleWrap::Value(aValue);
   if (!aValue.IsEmpty())
     return;
 
   // Pass NonSystem as the caller type, to be safe.  We don't expect to have a
   // file input here.
-  HTMLInputElement::FromContent(mContent)->GetValue(aValue,
-                                                    CallerType::NonSystem);
+  HTMLInputElement::FromNode(mContent)->GetValue(aValue, CallerType::NonSystem);
 }
 
 double
 HTMLSpinnerAccessible::MaxValue() const
 {
   double value = AccessibleWrap::MaxValue();
   if (!IsNaN(value))
     return value;
 
-  return HTMLInputElement::FromContent(mContent)->GetMaximum().toDouble();
+  return HTMLInputElement::FromNode(mContent)->GetMaximum().toDouble();
 }
 
 
 double
 HTMLSpinnerAccessible::MinValue() const
 {
   double value = AccessibleWrap::MinValue();
   if (!IsNaN(value))
     return value;
 
-  return HTMLInputElement::FromContent(mContent)->GetMinimum().toDouble();
+  return HTMLInputElement::FromNode(mContent)->GetMinimum().toDouble();
 }
 
 double
 HTMLSpinnerAccessible::Step() const
 {
   double value = AccessibleWrap::Step();
   if (!IsNaN(value))
     return value;
 
-  return HTMLInputElement::FromContent(mContent)->GetStep().toDouble();
+  return HTMLInputElement::FromNode(mContent)->GetStep().toDouble();
 }
 
 double
 HTMLSpinnerAccessible::CurValue() const
 {
   double value = AccessibleWrap::CurValue();
   if (!IsNaN(value))
     return value;
 
-  return HTMLInputElement::FromContent(mContent)->GetValueAsDecimal().toDouble();
+  return HTMLInputElement::FromNode(mContent)->GetValueAsDecimal().toDouble();
 }
 
 bool
 HTMLSpinnerAccessible::SetCurValue(double aValue)
 {
   ErrorResult er;
-  HTMLInputElement::FromContent(mContent)->SetValueAsNumber(aValue, er);
+  HTMLInputElement::FromNode(mContent)->SetValueAsNumber(aValue, er);
   return !er.Failed();
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLRangeAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -631,65 +630,65 @@ void
 HTMLRangeAccessible::Value(nsString& aValue)
 {
   LeafAccessible::Value(aValue);
   if (!aValue.IsEmpty())
     return;
 
   // Pass NonSystem as the caller type, to be safe.  We don't expect to have a
   // file input here.
-  HTMLInputElement::FromContent(mContent)->GetValue(aValue,
-                                                    CallerType::NonSystem);
+  HTMLInputElement::FromNode(mContent)->GetValue(aValue,
+                                                 CallerType::NonSystem);
 }
 
 double
 HTMLRangeAccessible::MaxValue() const
 {
   double value = LeafAccessible::MaxValue();
   if (!IsNaN(value))
     return value;
 
-  return HTMLInputElement::FromContent(mContent)->GetMaximum().toDouble();
+  return HTMLInputElement::FromNode(mContent)->GetMaximum().toDouble();
 }
 
 double
 HTMLRangeAccessible::MinValue() const
 {
   double value = LeafAccessible::MinValue();
   if (!IsNaN(value))
     return value;
 
-  return HTMLInputElement::FromContent(mContent)->GetMinimum().toDouble();
+  return HTMLInputElement::FromNode(mContent)->GetMinimum().toDouble();
 }
 
 double
 HTMLRangeAccessible::Step() const
 {
   double value = LeafAccessible::Step();
   if (!IsNaN(value))
     return value;
 
-  return HTMLInputElement::FromContent(mContent)->GetStep().toDouble();
+  return HTMLInputElement::FromNode(mContent)->GetStep().toDouble();
 }
 
 double
 HTMLRangeAccessible::CurValue() const
 {
   double value = LeafAccessible::CurValue();
   if (!IsNaN(value))
     return value;
 
-  return HTMLInputElement::FromContent(mContent)->GetValueAsDecimal().toDouble();
+  return HTMLInputElement::FromNode(mContent)->GetValueAsDecimal().toDouble();
 }
 
 bool
 HTMLRangeAccessible::SetCurValue(double aValue)
 {
   ErrorResult er;
-  HTMLInputElement::FromContent(mContent)->SetValueAsNumber(aValue, er);
+  HTMLInputElement::FromNode(mContent)->SetValueAsNumber(aValue, er);
   return !er.Failed();
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLGroupboxAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
--- a/accessible/html/HTMLImageMapAccessible.cpp
+++ b/accessible/html/HTMLImageMapAccessible.cpp
@@ -158,17 +158,17 @@ HTMLAreaAccessible::NativeName(nsString&
 
 void
 HTMLAreaAccessible::Description(nsString& aDescription)
 {
   aDescription.Truncate();
 
   // Still to do - follow IE's standard here
   RefPtr<dom::HTMLAreaElement> area =
-    dom::HTMLAreaElement::FromContentOrNull(mContent);
+    dom::HTMLAreaElement::FromNodeOrNull(mContent);
   if (area)
     area->GetShape(aDescription);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLAreaAccessible: Accessible public
 
 Accessible*
--- a/accessible/html/HTMLSelectAccessible.cpp
+++ b/accessible/html/HTMLSelectAccessible.cpp
@@ -181,17 +181,17 @@ HTMLSelectOptionAccessible::NativeState(
   if (!select)
     return state;
 
   uint64_t selectState = select->State();
   if (selectState & states::INVISIBLE)
     return state;
 
   // Are we selected?
-  HTMLOptionElement* option = HTMLOptionElement::FromContent(mContent);
+  HTMLOptionElement* option = HTMLOptionElement::FromNode(mContent);
   bool selected = option && option->Selected();
   if (selected)
     state |= states::SELECTED;
 
   if (selectState & states::OFFSCREEN) {
     state |= states::OFFSCREEN;
   } else if (selectState & states::COLLAPSED) {
     // <select> is COLLAPSED: add OFFSCREEN, if not the currently
@@ -275,17 +275,17 @@ HTMLSelectOptionAccessible::DoAction(uin
 
   DoCommand();
   return true;
 }
 
 void
 HTMLSelectOptionAccessible::SetSelected(bool aSelect)
 {
-  HTMLOptionElement* option = HTMLOptionElement::FromContent(mContent);
+  HTMLOptionElement* option = HTMLOptionElement::FromNode(mContent);
   if (option)
     option->SetSelected(aSelect);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLSelectOptionAccessible: Widgets
 
 Accessible*
@@ -511,17 +511,17 @@ HTMLComboboxAccessible::SetCurrentItem(A
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLComboboxAccessible: protected
 
 Accessible*
 HTMLComboboxAccessible::SelectedOption() const
 {
-  HTMLSelectElement* select = HTMLSelectElement::FromContent(mContent);
+  HTMLSelectElement* select = HTMLSelectElement::FromNode(mContent);
   int32_t selectedIndex = select->SelectedIndex();
 
   if (selectedIndex >= 0) {
     HTMLOptionElement* option = select->Item(selectedIndex);
     if (option) {
       DocAccessible* document = Document();
       if (document)
         return document->GetAccessible(option);
--- a/accessible/html/HTMLTableAccessible.cpp
+++ b/accessible/html/HTMLTableAccessible.cpp
@@ -475,17 +475,17 @@ HTMLTableAccessible::Caption() const
 {
   Accessible* child = mChildren.SafeElementAt(0, nullptr);
   return child && child->Role() == roles::CAPTION ? child : nullptr;
 }
 
 void
 HTMLTableAccessible::Summary(nsString& aSummary)
 {
-  dom::HTMLTableElement* table = dom::HTMLTableElement::FromContent(mContent);
+  dom::HTMLTableElement* table = dom::HTMLTableElement::FromNode(mContent);
 
   if (table)
     table->GetSummary(aSummary);
 }
 
 uint32_t
 HTMLTableAccessible::ColCount()
 {
--- a/accessible/jsat/AccessFu.jsm
+++ b/accessible/jsat/AccessFu.jsm
@@ -336,17 +336,17 @@ var AccessFu = {
   },
 
   observe: function observe(aSubject, aTopic, aData) {
     switch (aTopic) {
       case "remote-browser-shown":
       case "inprocess-browser-shown":
       {
         // Ignore notifications that aren't from a Browser
-        let frameLoader = aSubject.QueryInterface(Ci.nsIFrameLoader);
+        let frameLoader = aSubject;
         if (!frameLoader.ownerIsMozBrowserFrame) {
           return;
         }
         this._handleMessageManager(frameLoader.messageManager);
         break;
       }
     }
   },
--- a/accessible/xul/XULTabAccessible.cpp
+++ b/accessible/xul/XULTabAccessible.cpp
@@ -47,17 +47,17 @@ XULTabAccessible::ActionNameAt(uint8_t a
     aName.AssignLiteral("switch");
 }
 
 bool
 XULTabAccessible::DoAction(uint8_t index)
 {
   if (index == eAction_Switch) {
     // XXXbz Could this just FromContent?
-    RefPtr<nsXULElement> tab = nsXULElement::FromContentOrNull(mContent);
+    RefPtr<nsXULElement> tab = nsXULElement::FromNodeOrNull(mContent);
     if (tab) {
       tab->Click(mozilla::dom::CallerType::System);
       return true;
     }
   }
   return false;
 }
 
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -255,17 +255,22 @@ pref("browser.defaultbrowser.notificatio
 // 0 = blank, 1 = home (browser.startup.homepage), 2 = last visited page, 3 = resume previous browser session
 // The behavior of option 3 is detailed at: http://wiki.mozilla.org/Session_Restore
 pref("browser.startup.page",                1);
 pref("browser.startup.homepage",            "chrome://branding/locale/browserconfig.properties");
 // Whether we should skip the homepage when opening the first-run page
 pref("browser.startup.firstrunSkipsHomepage", true);
 
 // Show an about:blank window as early as possible for quick startup feedback.
+#ifdef XP_MACOSX
+// Disabled on Mac because the bouncing dock icon already provides feedback.
 pref("browser.startup.blankWindow", false);
+#else
+pref("browser.startup.blankWindow", true);
+#endif
 
 pref("browser.slowStartup.notificationDisabled", false);
 pref("browser.slowStartup.timeThreshold", 20000);
 pref("browser.slowStartup.maxSamples", 5);
 
 // This url, if changed, MUST continue to point to an https url. Pulling arbitrary content to inject into
 // this page over http opens us up to a man-in-the-middle attack that we'd rather not face. If you are a downstream
 // repackager of this code using an alternate snippet url, please keep your users safe
--- a/browser/base/content/test/performance/browser_startup.js
+++ b/browser/base/content/test/performance/browser_startup.js
@@ -117,16 +117,20 @@ const startupPhases = {
     modules: new Set([
       "resource://gre/modules/AsyncPrefs.jsm",
       "resource://gre/modules/LoginManagerContextMenu.jsm",
       "resource://gre/modules/Task.jsm",
     ]),
   }},
 };
 
+if (Services.prefs.getBoolPref("browser.startup.blankWindow")) {
+  startupPhases["before profile selection"].whitelist.components.add("XULStore.js");
+}
+
 if (!gBrowser.selectedBrowser.isRemoteBrowser) {
   // With e10s disabled, Places and RecentWindow.jsm (from a
   // SessionSaver.jsm timer) intermittently get loaded earlier. Likely
   // due to messages from the 'content' process arriving synchronously
   // instead of crossing a process boundary.
   info("merging the 'before handling user events' blacklist into the " +
        "'before first paint' one when e10s is disabled.");
   let from = startupPhases["before handling user events"].blacklist;
--- a/browser/base/content/test/static/browser_parsable_css.js
+++ b/browser/base/content/test/static/browser_parsable_css.js
@@ -103,19 +103,16 @@ let propNameWhitelist = [
   {propName: "--chrome-nav-buttons-hover-background",
    isFromDevTools: false},
   // Bug 1441929
   {propName: "--theme-search-overlays-semitransparent",
    isFromDevTools: true},
   // Bug 1441878
   {propName: "--theme-codemirror-gutter-background",
    isFromDevTools: true},
-  // Bug 1442300
-  {propName: "--in-content-category-background",
-   isFromDevTools: false},
   // These custom properties are retrieved directly from CSSOM
   // in videocontrols.xml to get pre-defined style instead of computed
   // dimensions, which is why they are not referenced by CSS.
   {propName: "--clickToPlay-width",
    isFromDevTools: false},
   {propName: "--playButton-width",
    isFromDevTools: false},
   {propName: "--muteButton-width",
--- a/browser/components/sessionstore/SessionStore.jsm
+++ b/browser/components/sessionstore/SessionStore.jsm
@@ -446,17 +446,17 @@ var SessionStoreInternal = {
   // For each <browser> element, records the current epoch.
   _browserEpochs: new WeakMap(),
 
   // Any browsers that fires the oop-browser-crashed event gets stored in
   // here - that way we know which browsers to ignore messages from (until
   // they get restored).
   _crashedBrowsers: new WeakSet(),
 
-  // A map (xul:browser -> nsIFrameLoader) that maps a browser to the last
+  // A map (xul:browser -> FrameLoader) that maps a browser to the last
   // associated frameLoader we heard about.
   _lastKnownFrameLoader: new WeakMap(),
 
   // A map (xul:browser -> object) that maps a browser associated with a
   // recently closed tab to all its necessary state information we need to
   // properly handle final update message.
   _closedTabs: new WeakMap(),
 
--- a/browser/extensions/formautofill/test/browser/browser.ini
+++ b/browser/extensions/formautofill/test/browser/browser.ini
@@ -7,17 +7,17 @@ support-files =
   ../fixtures/autocomplete_simple_basic.html
   ../fixtures/autocomplete_creditcard_basic.html
 
 [browser_autocomplete_footer.js]
 [browser_autocomplete_marked_back_forward.js]
 [browser_autocomplete_marked_detached_tab.js]
 [browser_check_installed.js]
 [browser_creditCard_doorhanger.js]
-skip-if (os == "linux") || (os == "mac" && debug) || (os == "win") # bug 1425884
+skip-if = (os == "linux") || (os == "mac" && debug) || (os == "win") # bug 1425884
 [browser_creditCard_fill_master_password.js]
 [browser_dropdown_layout.js]
 [browser_editAddressDialog.js]
 [browser_editCreditCardDialog.js]
 [browser_first_time_use_doorhanger.js]
 [browser_insecure_form.js]
 [browser_manageAddressesDialog.js]
 [browser_manageCreditCardsDialog.js]
--- a/browser/modules/ContentCrashHandlers.jsm
+++ b/browser/modules/ContentCrashHandlers.jsm
@@ -155,18 +155,16 @@ var TabCrashHandler = {
           dump("A content process crashed and MOZ_CRASHREPORTER_SHUTDOWN is " +
                "set, shutting down\n");
           Services.startup.quit(Ci.nsIAppStartup.eForceQuit);
         }
 
         break;
       }
       case "oop-frameloader-crashed": {
-        aSubject.QueryInterface(Ci.nsIFrameLoader);
-
         let browser = aSubject.ownerElement;
         if (!browser) {
           return;
         }
 
         this.browserMap.set(browser, aSubject.childID);
         break;
       }
--- a/browser/modules/webrtcUI.jsm
+++ b/browser/modules/webrtcUI.jsm
@@ -257,17 +257,16 @@ var webrtcUI = {
       case "webrtc:UpdatingIndicators":
         webrtcUI.forgetStreamsFromProcess(aMessage.target);
         break;
       case "webrtc:UpdateGlobalIndicators":
         updateIndicators(aMessage.data, aMessage.target);
         break;
       case "webrtc:UpdateBrowserIndicators":
         let id = aMessage.data.windowId;
-        aMessage.targetFrameLoader.QueryInterface(Ci.nsIFrameLoader);
         let processMM =
           aMessage.targetFrameLoader.messageManager.processMessageManager;
         let index;
         for (index = 0; index < webrtcUI._streams.length; ++index) {
           let stream = webrtcUI._streams[index];
           if (stream.state.windowId == id && stream.processMM == processMM)
             break;
         }
--- a/browser/themes/shared/incontentprefs/preferences.inc.css
+++ b/browser/themes/shared/incontentprefs/preferences.inc.css
@@ -4,20 +4,16 @@
    - You can obtain one at http://mozilla.org/MPL/2.0/. */
 %endif
 @namespace html "http://www.w3.org/1999/xhtml";
 
 * {
   -moz-user-select: text;
 }
 
-:root {
-  --in-content-category-background: #fafafc;
-}
-
 .main-content {
   padding-top: 0;
 }
 
 .pane-container {
   /* A workaround to keep the container always float on the `top: 0` (Bug 1377009) */
   display: block;
   width: 664px;
--- a/devtools/client/debugger/new/README.mozilla
+++ b/devtools/client/debugger/new/README.mozilla
@@ -1,13 +1,13 @@
 This is the debugger.html project output.
 See https://github.com/devtools-html/debugger.html
 
-Version 24.0
+Version 25.0
 
-Comparison: https://github.com/devtools-html/debugger.html/compare/release-23...release-24
+Comparison: https://github.com/devtools-html/debugger.html/compare/release-24...release-25
 
 Packages:
 - babel-plugin-transform-es2015-modules-commonjs @6.26.0
 - babel-preset-react @6.24.1
 - react @16.2.0
 - react-dom @16.2.0
 - webpack @3.11.0
--- a/devtools/client/debugger/new/debugger.css
+++ b/devtools/client/debugger/new/debugger.css
@@ -1370,17 +1370,17 @@ html[dir="rtl"] .arrow svg,
   overflow-y: hidden;
 }
 
 .outline > div {
   width: 100%;
   position: relative;
 }
 
-.outline .outline-pane-info {
+.outline-pane-info {
   width: 100%;
   font-style: italic;
   text-align: center;
   padding: 0.5em;
   user-select: none;
   font-size: 12px;
   overflow: hidden;
 }
--- a/devtools/client/debugger/new/debugger.js
+++ b/devtools/client/debugger/new/debugger.js
@@ -3162,17 +3162,17 @@ function createPendingBreakpoint(bp) {
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.replaceOriginalVariableName = exports.getFramework = exports.hasSyntaxError = exports.clearSources = exports.setSource = exports.hasSource = exports.getEmptyLines = exports.isInvalidPauseLocation = exports.getNextStep = exports.clearASTs = exports.clearScopes = exports.clearSymbols = exports.findOutOfScopeLocations = exports.getScopes = exports.getSymbols = exports.getClosestExpression = exports.stopParserWorker = exports.startParserWorker = undefined;
+exports.replaceOriginalVariableName = exports.getPausePoints = exports.getFramework = exports.hasSyntaxError = exports.clearSources = exports.setSource = exports.hasSource = exports.isInvalidPauseLocation = exports.getNextStep = exports.clearASTs = exports.clearScopes = exports.clearSymbols = exports.findOutOfScopeLocations = exports.getScopes = exports.getSymbols = exports.getClosestExpression = exports.stopParserWorker = exports.startParserWorker = undefined;
 
 var _devtoolsUtils = __webpack_require__(1363);
 
 const { WorkerDispatcher } = _devtoolsUtils.workerUtils; /* 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/>. */
 
 const dispatcher = new WorkerDispatcher();
@@ -3183,22 +3183,22 @@ const getClosestExpression = exports.get
 const getSymbols = exports.getSymbols = dispatcher.task("getSymbols");
 const getScopes = exports.getScopes = dispatcher.task("getScopes");
 const findOutOfScopeLocations = exports.findOutOfScopeLocations = dispatcher.task("findOutOfScopeLocations");
 const clearSymbols = exports.clearSymbols = dispatcher.task("clearSymbols");
 const clearScopes = exports.clearScopes = dispatcher.task("clearScopes");
 const clearASTs = exports.clearASTs = dispatcher.task("clearASTs");
 const getNextStep = exports.getNextStep = dispatcher.task("getNextStep");
 const isInvalidPauseLocation = exports.isInvalidPauseLocation = dispatcher.task("isInvalidPauseLocation");
-const getEmptyLines = exports.getEmptyLines = dispatcher.task("getEmptyLines");
 const hasSource = exports.hasSource = dispatcher.task("hasSource");
 const setSource = exports.setSource = dispatcher.task("setSource");
 const clearSources = exports.clearSources = dispatcher.task("clearSources");
 const hasSyntaxError = exports.hasSyntaxError = dispatcher.task("hasSyntaxError");
 const getFramework = exports.getFramework = dispatcher.task("getFramework");
+const getPausePoints = exports.getPausePoints = dispatcher.task("getPausePoints");
 const replaceOriginalVariableName = exports.replaceOriginalVariableName = dispatcher.task("replaceOriginalVariableName");
 
 /***/ }),
 
 /***/ 1366:
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -4778,59 +4778,66 @@ var _extends = Object.assign || function
  */
 
 exports.initialASTState = initialASTState;
 exports.getSymbols = getSymbols;
 exports.hasSymbols = hasSymbols;
 exports.isSymbolsLoading = isSymbolsLoading;
 exports.isEmptyLineInSource = isEmptyLineInSource;
 exports.getEmptyLines = getEmptyLines;
+exports.getPausePoints = getPausePoints;
 exports.getOutOfScopeLocations = getOutOfScopeLocations;
 exports.getPreview = getPreview;
 exports.getSourceMetaData = getSourceMetaData;
 exports.getInScopeLines = getInScopeLines;
 exports.isLineInScope = isLineInScope;
 
 var _immutable = __webpack_require__(3594);
 
 var I = _interopRequireWildcard(_immutable);
 
 var _makeRecord = __webpack_require__(1361);
 
 var _makeRecord2 = _interopRequireDefault(_makeRecord);
 
+var _ast = __webpack_require__(1638);
+
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
 
 function initialASTState() {
   return (0, _makeRecord2.default)({
     symbols: I.Map(),
     emptyLines: I.Map(),
     outOfScopeLocations: null,
     inScopeLines: null,
     preview: null,
+    pausePoints: I.Map(),
     sourceMetaData: I.Map()
   })();
 }
 
 function update(state = initialASTState(), action) {
   switch (action.type) {
     case "SET_SYMBOLS":
       {
         const { source } = action;
         if (action.status === "start") {
           return state.setIn(["symbols", source.id], { loading: true });
         }
         return state.setIn(["symbols", source.id], action.value);
       }
-    case "SET_EMPTY_LINES":
-      {
-        const { source, emptyLines } = action;
-        return state.setIn(["emptyLines", source.id], emptyLines);
+
+    case "SET_PAUSE_POINTS":
+      {
+        const { source, pausePoints } = action;
+        const emptyLines = (0, _ast.findEmptyLines)(source, pausePoints);
+
+        return state.setIn(["pausePoints", source.id], pausePoints).setIn(["emptyLines", source.id], emptyLines);
       }
 
     case "OUT_OF_SCOPE_LOCATIONS":
       {
         return state.set("outOfScopeLocations", action.locations);
       }
 
     case "IN_SCOPE_LINES":
@@ -4906,25 +4913,33 @@ function isSymbolsLoading(state, source)
     return false;
   }
 
   return !!symbols.loading;
 }
 
 function isEmptyLineInSource(state, line, selectedSource) {
   const emptyLines = getEmptyLines(state, selectedSource);
-  return emptyLines.includes(line);
+  return emptyLines && emptyLines.includes(line);
 }
 
 function getEmptyLines(state, source) {
   if (!source) {
-    return [];
-  }
-
-  return state.ast.getIn(["emptyLines", source.id]) || [];
+    return null;
+  }
+
+  return state.ast.getIn(["emptyLines", source.id]);
+}
+
+function getPausePoints(state, source) {
+  if (!source) {
+    return null;
+  }
+
+  return state.ast.getIn(["pausePoints", source.id]);
 }
 
 function getOutOfScopeLocations(state) {
   return state.ast.get("outOfScopeLocations");
 }
 
 function getPreview(state) {
   return state.ast.get("preview");
@@ -6323,18 +6338,18 @@ async function getMappedExpression({ sou
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.setSourceMetaData = setSourceMetaData;
 exports.setSymbols = setSymbols;
-exports.setEmptyLines = setEmptyLines;
 exports.setOutOfScopeLocations = setOutOfScopeLocations;
+exports.setPausePoints = setPausePoints;
 
 var _selectors = __webpack_require__(3590);
 
 var _setInScopeLines = __webpack_require__(1781);
 
 var _parser = __webpack_require__(1365);
 
 var _promise = __webpack_require__(1653);
@@ -6379,40 +6394,18 @@ function setSymbols(sourceId) {
     }
 
     await dispatch({
       type: "SET_SYMBOLS",
       source,
       [_promise.PROMISE]: (0, _parser.getSymbols)(source.id)
     });
 
-    dispatch(setEmptyLines(sourceId));
-    dispatch(setSourceMetaData(sourceId));
-  };
-}
-
-function setEmptyLines(sourceId) {
-  return async ({ dispatch, getState }) => {
-    const sourceRecord = (0, _selectors.getSource)(getState(), sourceId);
-    if (!sourceRecord) {
-      return;
-    }
-
-    const source = sourceRecord.toJS();
-    if (!source.text || source.isWasm) {
-      return;
-    }
-
-    const emptyLines = await (0, _parser.getEmptyLines)(source.id);
-
-    dispatch({
-      type: "SET_EMPTY_LINES",
-      source,
-      emptyLines
-    });
+    await dispatch(setPausePoints(sourceId));
+    await dispatch(setSourceMetaData(sourceId));
   };
 }
 
 function setOutOfScopeLocations() {
   return async ({ dispatch, getState }) => {
     const location = (0, _selectors.getSelectedLocation)(getState());
     if (!location) {
       return;
@@ -6429,16 +6422,37 @@ function setOutOfScopeLocations() {
       type: "OUT_OF_SCOPE_LOCATIONS",
       locations
     });
 
     dispatch((0, _setInScopeLines.setInScopeLines)());
   };
 }
 
+function setPausePoints(sourceId) {
+  return async ({ dispatch, getState }) => {
+    const sourceRecord = (0, _selectors.getSource)(getState(), sourceId);
+    if (!sourceRecord) {
+      return;
+    }
+
+    const source = sourceRecord.toJS();
+    if (!source.text || source.isWasm) {
+      return;
+    }
+
+    const pausePoints = await (0, _parser.getPausePoints)(source.id);
+    dispatch({
+      type: "SET_PAUSE_POINTS",
+      source,
+      pausePoints
+    });
+  };
+}
+
 /***/ }),
 
 /***/ 14:
 /***/ (function(module, exports) {
 
 /**
  * Checks if `value` is object-like. A value is object-like if it's not `null`
  * and has a `typeof` result of "object".
@@ -12204,32 +12218,28 @@ var firefox = _interopRequireWildcard(_f
 var _chrome = __webpack_require__(1507);
 
 var chrome = _interopRequireWildcard(_chrome);
 
 var _prefs = __webpack_require__(226);
 
 var _dbg = __webpack_require__(2246);
 
-var _devtoolsConfig = __webpack_require__(1355);
-
 var _bootstrap = __webpack_require__(1430);
 
 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
 
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
-
 function loadFromPrefs(actions) {
   const { pauseOnExceptions, ignoreCaughtExceptions } = _prefs.prefs;
   if (pauseOnExceptions || ignoreCaughtExceptions) {
     return actions.pauseOnExceptions(pauseOnExceptions, ignoreCaughtExceptions);
   }
-}
+} /* This Source Code Form is subject to the terms of the Mozilla Public
+   * License, v. 2.0. If a copy of the MPL was not distributed with this
+   * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
 
 function getClient(connection) {
   const { tab: { clientType } } = connection;
   return clientType == "firefox" ? firefox : chrome;
 }
 
 async function onConnect(connection, { services, toolboxActions }) {
   // NOTE: the landing page does not connect to a JS process
@@ -12243,24 +12253,22 @@ async function onConnect(connection, { s
     services,
     toolboxActions
   });
 
   (0, _bootstrap.bootstrapWorkers)();
   await client.onConnect(connection, actions);
   await loadFromPrefs(actions);
 
-  if (!(0, _devtoolsConfig.isFirefoxPanel)()) {
-    (0, _dbg.setupHelper)({
-      store,
-      actions,
-      selectors,
-      client: client.clientCommands
-    });
-  }
+  (0, _dbg.setupHelper)({
+    store,
+    actions,
+    selectors,
+    client: client.clientCommands
+  });
 
   (0, _bootstrap.bootstrapApp)(store);
   return { store, actions, selectors, client: commands };
 }
 
 exports.onConnect = onConnect;
 
 /***/ }),
@@ -13467,16 +13475,20 @@ var _redux = __webpack_require__(3593);
 var _prefs = __webpack_require__(226);
 
 var _actions = __webpack_require__(1354);
 
 var _actions2 = _interopRequireDefault(_actions);
 
 var _ShortcutsModal = __webpack_require__(1535);
 
+var _VisibilityHandler = __webpack_require__(3611);
+
+var _VisibilityHandler2 = _interopRequireDefault(_VisibilityHandler);
+
 var _selectors = __webpack_require__(3590);
 
 var _devtoolsModules = __webpack_require__(1376);
 
 __webpack_require__(1305);
 
 __webpack_require__(1306);
 
@@ -13515,19 +13527,21 @@ var _Tabs = __webpack_require__(1614);
 var _Tabs2 = _interopRequireDefault(_Tabs);
 
 var _QuickOpenModal = __webpack_require__(1652);
 
 var _QuickOpenModal2 = _interopRequireDefault(_QuickOpenModal);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
-const shortcuts = new _devtoolsModules.KeyShortcuts({ window }); /* 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/>. */
+/* 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/>. */
+
+const shortcuts = new _devtoolsModules.KeyShortcuts({ window });
 
 const { appinfo } = _devtoolsModules.Services;
 
 const isMacOS = appinfo.OS === "Darwin";
 
 const horizontalLayoutBreakpoint = window.matchMedia("(min-width: 800px)");
 const verticalLayoutBreakpoint = window.matchMedia("(min-width: 10px) and (max-width: 800px)");
 
@@ -13717,24 +13731,28 @@ class App extends _react.Component {
       enabled: this.state.shortcutsModalEnabled,
       handleClose: () => this.toggleShortcutsModal()
     });
   }
 
   render() {
     const { quickOpenEnabled } = this.props;
     return _react2.default.createElement(
-      "div",
-      { className: "debugger" },
-      this.renderLayout(),
-      quickOpenEnabled === true && _react2.default.createElement(_QuickOpenModal2.default, {
-        shortcutsModalEnabled: this.state.shortcutsModalEnabled,
-        toggleShortcutsModal: () => this.toggleShortcutsModal()
-      }),
-      this.renderShortcutsModal()
+      _VisibilityHandler2.default,
+      null,
+      _react2.default.createElement(
+        "div",
+        { className: "debugger" },
+        this.renderLayout(),
+        quickOpenEnabled === true && _react2.default.createElement(_QuickOpenModal2.default, {
+          shortcutsModalEnabled: this.state.shortcutsModalEnabled,
+          toggleShortcutsModal: () => this.toggleShortcutsModal()
+        }),
+        this.renderShortcutsModal()
+      )
     );
   }
 }
 
 App.childContextTypes = { shortcuts: _propTypes2.default.object };
 
 function mapStateToProps(state) {
   return {
@@ -16788,17 +16806,20 @@ class Outline extends _react.Component {
           },
           L10N.getStr("outline.sortLabel")
         )
       )
     );
   }
 
   render() {
-    const { symbols } = this.props;
+    const { symbols, selectedSource } = this.props;
+    if (!selectedSource) {
+      return this.renderPlaceholder();
+    }
     if (!symbols || symbols.loading) {
       return this.renderLoading();
     }
     const symbolsToDisplay = symbols.functions.filter(func => func.name != "anonymous");
     return _react2.default.createElement(
       "div",
       { className: "outline" },
       symbolsToDisplay.length > 0 ? this.renderFunctions(symbols.functions) : this.renderPlaceholder()
@@ -22504,17 +22525,17 @@ class GutterContextMenuComponent extends
   showMenu(nextProps) {
     const { contextMenu } = nextProps,
           props = _objectWithoutProperties(nextProps, ["contextMenu"]);
     const { event } = contextMenu;
     const sourceId = props.selectedSource ? props.selectedSource.get("id") : "";
     const line = (0, _editor.lineAtHeight)(props.editor, sourceId, event);
     const breakpoint = nextProps.breakpoints.find(bp => bp.location.line === line);
 
-    if (props.emptyLines.includes(line)) {
+    if (props.emptyLines && props.emptyLines.includes(line)) {
       return;
     }
 
     gutterMenu(_extends({ event, sourceId, line, breakpoint }, props));
   }
 
   render() {
     return null;
@@ -22524,17 +22545,17 @@ class GutterContextMenuComponent extends
 exports.default = (0, _reactRedux.connect)(state => {
   const selectedSource = (0, _selectors.getSelectedSource)(state);
   return {
     selectedLocation: (0, _selectors.getSelectedLocation)(state),
     selectedSource: selectedSource,
     breakpoints: (0, _selectors.getVisibleBreakpoints)(state),
     isPaused: (0, _selectors.isPaused)(state),
     contextMenu: (0, _selectors.getContextMenu)(state),
-    emptyLines: selectedSource ? (0, _selectors.getEmptyLines)(state, selectedSource.toJS()) : []
+    emptyLines: (0, _selectors.getEmptyLines)(state, selectedSource.toJS())
   };
 }, dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(GutterContextMenuComponent);
 
 /***/ }),
 
 /***/ 1596:
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -26896,32 +26917,50 @@ function astCommand(stepType) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.findBestMatchExpression = findBestMatchExpression;
-/* 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/>. */
+exports.findEmptyLines = findEmptyLines;
+
+var _lodash = __webpack_require__(2);
 
 function findBestMatchExpression(symbols, tokenPos) {
   const { memberExpressions, identifiers } = symbols;
   const { line, column } = tokenPos;
   return identifiers.concat(memberExpressions).reduce((found, expression) => {
     const overlaps = expression.location.start.line == line && expression.location.start.column <= column && expression.location.end.column >= column && !expression.computed;
 
     if (overlaps) {
       return expression;
     }
 
     return found;
-  }, {});
+  }, null);
+} /* This Source Code Form is subject to the terms of the Mozilla Public
+   * License, v. 2.0. If a copy of the MPL was not distributed with this
+   * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
+
+function findEmptyLines(selectedSource, pausePoints) {
+  if (!pausePoints || !selectedSource) {
+    return [];
+  }
+
+  const breakpoints = pausePoints.filter(point => point.types.breakpoint);
+  const breakpointLines = breakpoints.map(point => point.location.line);
+
+  if (!selectedSource.text) {
+    return [];
+  }
+  const lineCount = selectedSource.text.split("\n").length;
+  const sourceLines = (0, _lodash.range)(1, lineCount);
+  return (0, _lodash.without)(sourceLines, ...breakpointLines);
 }
 
 /***/ }),
 
 /***/ 1639:
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -27897,16 +27936,28 @@ class QuickOpenModal extends _react.Comp
         return _extends({}, result, {
           title: this.renderHighlight(result.title, (0, _path.basename)(newQuery), "title")
         }, result.subtitle != null && !this.isSymbolSearch() ? {
           subtitle: this.renderHighlight(result.subtitle, newQuery, "subtitle")
         } : null);
       });
     };
 
+    this.renderLoading = () => {
+      const { symbolsLoading } = this.props;
+
+      if ((this.isFunctionQuery() || this.isVariableQuery()) && symbolsLoading) {
+        return _react2.default.createElement(
+          "div",
+          { className: "loading-indicator" },
+          L10N.getStr("loadingText")
+        );
+      }
+    };
+
     this.state = { results: null, selectedIndex: 0 };
   }
 
   componentDidMount() {
     const { query, shortcutsModalEnabled, toggleShortcutsModal } = this.props;
 
     this.updateResults(query);
 
@@ -27938,17 +27989,17 @@ class QuickOpenModal extends _react.Comp
     const { query } = this.props;
     if (this.isGotoQuery()) {
       return !/^:\d*$/.test(query);
     }
     return !this.getResultCount() && !!query;
   }
 
   render() {
-    const { enabled, query, symbols } = this.props;
+    const { enabled, query } = this.props;
     const { selectedIndex, results } = this.state;
 
     if (!enabled) {
       return null;
     }
     const newResults = results && results.slice(0, 100);
     const items = this.highlightMatching(query, newResults || []);
     const expanded = !!items && items.length > 0;
@@ -27962,47 +28013,40 @@ class QuickOpenModal extends _react.Comp
         summaryMsg: "",
         showErrorEmoji: this.shouldShowErrorEmoji(),
         onChange: this.onChange,
         onKeyDown: this.onKeyDown,
         handleClose: this.closeModal,
         expanded: expanded,
         selectedItemId: expanded && items[selectedIndex] ? items[selectedIndex].id : ""
       }),
-      !symbols || symbols.functions.length == 0 && _react2.default.createElement(
-        "div",
-        { className: "loading-indicator" },
-        L10N.getStr("loadingText")
-      ),
+      this.renderLoading(),
       newResults && _react2.default.createElement(_ResultList2.default, _extends({
         key: "results",
         items: items,
         selected: selectedIndex,
         selectItem: this.selectResultItem,
         ref: "resultList",
         expanded: expanded
       }, this.isSourceSearch() ? { size: "big" } : {}))
     );
   }
 }
 
 exports.QuickOpenModal = QuickOpenModal; /* istanbul ignore next: ignoring testing of redux connection stuff */
 
 function mapStateToProps(state) {
   const selectedSource = (0, _selectors.getSelectedSource)(state);
-  let symbols = null;
-  if (selectedSource != null) {
-    symbols = (0, _selectors.getSymbols)(state, selectedSource.toJS());
-  }
 
   return {
     enabled: (0, _selectors.getQuickOpenEnabled)(state),
     sources: (0, _quickOpen.formatSources)((0, _selectors.getSources)(state)),
     selectedSource,
-    symbols: (0, _quickOpen.formatSymbols)(symbols),
+    symbols: (0, _quickOpen.formatSymbols)((0, _selectors.getSymbols)(state, selectedSource)),
+    symbolsLoading: (0, _selectors.isSymbolsLoading)(state, selectedSource),
     query: (0, _selectors.getQuickOpenQuery)(state),
     searchType: (0, _selectors.getQuickOpenType)(state),
     tabs: (0, _selectors.getTabs)(state).toArray()
   };
 }
 
 /* istanbul ignore next: ignoring testing of redux connection stuff */
 exports.default = (0, _reactRedux.connect)(mapStateToProps, _actions2.default)(QuickOpenModal);
@@ -28571,17 +28615,17 @@ var _extends = Object.assign || function
                                                                                                                                                                                                                                                                    * 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/. */
 /* global window */
 
 exports.log = log;
 
 var _devtoolsConfig = __webpack_require__(1355);
 
-const blacklist = ["SET_POPUP_OBJECT_PROPERTIES", "SET_SYMBOLS", "OUT_OF_SCOPE_LOCATIONS", "MAP_SCOPES", "ADD_SCOPES", "IN_SCOPE_LINES", "SET_EMPTY_LINES"];
+const blacklist = ["SET_POPUP_OBJECT_PROPERTIES", "SET_PAUSE_POINTS", "SET_SYMBOLS", "OUT_OF_SCOPE_LOCATIONS", "MAP_SCOPES", "ADD_SCOPES", "IN_SCOPE_LINES", "SET_EMPTY_LINES"];
 
 function cloneAction(action) {
   action = action || {};
   action = _extends({}, action);
 
   // ADD_TAB, ...
   if (action.source && action.source.text) {
     const source = _extends({}, action.source, { text: "" });
@@ -31488,17 +31532,17 @@ function togglePrettyPrint(sourceId) {
       const _sourceId = prettySource.get("id");
       return dispatch((0, _sources.selectLocation)(_extends({}, options.location, { sourceId: _sourceId })));
     }
 
     const newPrettySource = await dispatch(createPrettySource(sourceId));
 
     await dispatch((0, _breakpoints.remapBreakpoints)(sourceId));
     await dispatch((0, _pause.mapFrames)());
-    await dispatch((0, _ast.setEmptyLines)(newPrettySource.id));
+    await dispatch((0, _ast.setPausePoints)(newPrettySource.id));
     await dispatch((0, _ast.setSymbols)(newPrettySource.id));
 
     return dispatch((0, _sources.selectLocation)(_extends({}, options.location, { sourceId: newPrettySource.id })));
   };
 }
 
 /***/ }),
 
@@ -34207,16 +34251,18 @@ exports.setupHelper = setupHelper;
 var _redux = __webpack_require__(3593);
 
 var _timings = __webpack_require__(1657);
 
 var timings = _interopRequireWildcard(_timings);
 
 var _prefs = __webpack_require__(226);
 
+var _devtoolsConfig = __webpack_require__(1355);
+
 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
 
 function findSource(dbg, url) {
   const sources = dbg.selectors.getSources();
   const source = sources.find(s => (s.get("url") || "").includes(url));
 
   if (!source) {
     return;
@@ -34259,22 +34305,24 @@ function setupHelper(obj) {
       findSource: url => findSource(dbg, url),
       evaluate: (expression, cbk) => evaluate(dbg, expression, cbk),
       sendPacket: (packet, cbk) => sendPacket(dbg, packet, cbk)
     }
   });
 
   window.dbg = dbg;
 
-  console.group("Development Notes");
-  const baseUrl = "https://devtools-html.github.io/debugger.html";
-  const localDevelopmentUrl = `${baseUrl}/docs/dbg.html`;
-  console.log("Debugging Tips", localDevelopmentUrl);
-  console.log("dbg", window.dbg);
-  console.groupEnd();
+  if ((0, _devtoolsConfig.isDevelopment)()) {
+    console.group("Development Notes");
+    const baseUrl = "https://devtools-html.github.io/debugger.html";
+    const localDevelopmentUrl = `${baseUrl}/docs/dbg.html`;
+    console.log("Debugging Tips", localDevelopmentUrl);
+    console.log("dbg", window.dbg);
+    console.groupEnd();
+  }
 }
 
 /***/ }),
 
 /***/ 2247:
 /***/ (function(module, exports) {
 
 module.exports = "<!-- This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. --><svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M8 13.4c-.5 0-.9-.2-1.2-.6L.4 5.2C0 4.7-.1 4.3.2 3.7S1 3 1.6 3h12.8c.6 0 1.2.1 1.4.7.3.6.2 1.1-.2 1.6l-6.4 7.6c-.3.4-.7.5-1.2.5z\"></path></svg>"
@@ -37856,16 +37904,85 @@ function formatCopyName(frame) {
   const fileName = (0, _source.getFilename)(frame.source);
   const frameLocation = frame.location.line;
 
   return `${displayName} (${fileName}#${frameLocation})`;
 }
 
 /***/ }),
 
+/***/ 3611:
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+var _propTypes = __webpack_require__(20);
+
+var _propTypes2 = _interopRequireDefault(_propTypes);
+
+var _react = __webpack_require__(0);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/* 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/. */
+
+/**
+ * Helper class to disable panel rendering when it is in background.
+ *
+ * Toolbox code hides the iframes when switching to another panel
+ * and triggers `visibilitychange` events.
+ *
+ * See devtools/client/framework/toolbox.js:setIframeVisible().
+ */
+
+class VisibilityHandler extends _react.Component {
+  static get propTypes() {
+    return {
+      children: _propTypes2.default.element.isRequired
+    };
+  }
+
+  constructor(props) {
+    super(props);
+    this.isVisible = true;
+    this.onVisibilityChange = this.onVisibilityChange.bind(this);
+  }
+
+  componentDidMount() {
+    window.addEventListener("visibilitychange", this.onVisibilityChange);
+  }
+
+  shouldComponentUpdate() {
+    return document.visibilityState == "visible";
+  }
+
+  componentWillUnmount() {
+    window.removeEventListener("visibilitychange", this.onVisibilityChange);
+  }
+
+  onVisibilityChange() {
+    this.isVisible = false;
+    if (document.visibilityState == "visible") {
+      this.isVisible = true;
+    }
+    this.forceUpdate();
+  }
+
+  render() {
+    return this.isVisible ? this.props.children : null;
+  }
+}
+
+module.exports = VisibilityHandler;
+
+/***/ }),
+
 /***/ 362:
 /***/ (function(module, exports) {
 
 module.exports = "<!-- This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. --><svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 20 16\" stroke=\"none\" fillrule=\"evenodd\"><rect x=\"3\" y=\"10\" width=\"3\" height=\"3\" rx=\"1\"></rect><rect x=\"12\" y=\"3\" width=\"2\" height=\"9\" rx=\"1\"></rect><rect transform=\"translate(13.000000, 7.500000) rotate(60.000000) translate(-13.000000, -7.500000) \" x=\"12\" y=\"3\" width=\"2\" height=\"9\" rx=\"1\"></rect><rect transform=\"translate(13.000000, 7.500000) rotate(-60.000000) translate(-13.000000, -7.500000) \" x=\"12\" y=\"3\" width=\"2\" height=\"9\" rx=\"1\"></rect></svg>"
 
 /***/ }),
 
 /***/ 363:
--- a/devtools/client/debugger/new/parser-worker.js
+++ b/devtools/client/debugger/new/parser-worker.js
@@ -557,130 +557,16 @@ function toKey(value) {
   return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
 }
 
 module.exports = toKey;
 
 
 /***/ }),
 
-/***/ 1129:
-/***/ (function(module, exports, __webpack_require__) {
-
-var baseDifference = __webpack_require__(1131),
-    baseFlatten = __webpack_require__(707),
-    baseRest = __webpack_require__(411),
-    isArrayLikeObject = __webpack_require__(1155);
-
-/**
- * Creates an array of `array` values not included in the other given arrays
- * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
- * for equality comparisons. The order and references of result values are
- * determined by the first array.
- *
- * **Note:** Unlike `_.pullAll`, this method returns a new array.
- *
- * @static
- * @memberOf _
- * @since 0.1.0
- * @category Array
- * @param {Array} array The array to inspect.
- * @param {...Array} [values] The values to exclude.
- * @returns {Array} Returns the new array of filtered values.
- * @see _.without, _.xor
- * @example
- *
- * _.difference([2, 1], [2, 3]);
- * // => [1]
- */
-var difference = baseRest(function(array, values) {
-  return isArrayLikeObject(array)
-    ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
-    : [];
-});
-
-module.exports = difference;
-
-
-/***/ }),
-
-/***/ 1131:
-/***/ (function(module, exports, __webpack_require__) {
-
-var SetCache = __webpack_require__(276),
-    arrayIncludes = __webpack_require__(563),
-    arrayIncludesWith = __webpack_require__(567),
-    arrayMap = __webpack_require__(110),
-    baseUnary = __webpack_require__(215),
-    cacheHas = __webpack_require__(280);
-
-/** Used as the size to enable large array optimizations. */
-var LARGE_ARRAY_SIZE = 200;
-
-/**
- * The base implementation of methods like `_.difference` without support
- * for excluding multiple arrays or iteratee shorthands.
- *
- * @private
- * @param {Array} array The array to inspect.
- * @param {Array} values The values to exclude.
- * @param {Function} [iteratee] The iteratee invoked per element.
- * @param {Function} [comparator] The comparator invoked per element.
- * @returns {Array} Returns the new array of filtered values.
- */
-function baseDifference(array, values, iteratee, comparator) {
-  var index = -1,
-      includes = arrayIncludes,
-      isCommon = true,
-      length = array.length,
-      result = [],
-      valuesLength = values.length;
-
-  if (!length) {
-    return result;
-  }
-  if (iteratee) {
-    values = arrayMap(values, baseUnary(iteratee));
-  }
-  if (comparator) {
-    includes = arrayIncludesWith;
-    isCommon = false;
-  }
-  else if (values.length >= LARGE_ARRAY_SIZE) {
-    includes = cacheHas;
-    isCommon = false;
-    values = new SetCache(values);
-  }
-  outer:
-  while (++index < length) {
-    var value = array[index],
-        computed = iteratee == null ? value : iteratee(value);
-
-    value = (comparator || value !== 0) ? value : 0;
-    if (isCommon && computed === computed) {
-      var valuesIndex = valuesLength;
-      while (valuesIndex--) {
-        if (values[valuesIndex] === computed) {
-          continue outer;
-        }
-      }
-      result.push(value);
-    }
-    else if (!includes(values, computed, comparator)) {
-      result.push(value);
-    }
-  }
-  return result;
-}
-
-module.exports = baseDifference;
-
-
-/***/ }),
-
 /***/ 114:
 /***/ (function(module, exports, __webpack_require__) {
 
 var baseAssignValue = __webpack_require__(115),
     eq = __webpack_require__(97);
 
 /** Used for built-in method references. */
 var objectProto = Object.prototype;
@@ -738,56 +624,16 @@ function baseAssignValue(object, key, va
   }
 }
 
 module.exports = baseAssignValue;
 
 
 /***/ }),
 
-/***/ 1155:
-/***/ (function(module, exports, __webpack_require__) {
-
-var isArrayLike = __webpack_require__(220),
-    isObjectLike = __webpack_require__(14);
-
-/**
- * This method is like `_.isArrayLike` except that it also checks if `value`
- * is an object.
- *
- * @static
- * @memberOf _
- * @since 4.0.0
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is an array-like object,
- *  else `false`.
- * @example
- *
- * _.isArrayLikeObject([1, 2, 3]);
- * // => true
- *
- * _.isArrayLikeObject(document.body.children);
- * // => true
- *
- * _.isArrayLikeObject('abc');
- * // => false
- *
- * _.isArrayLikeObject(_.noop);
- * // => false
- */
-function isArrayLikeObject(value) {
-  return isObjectLike(value) && isArrayLike(value);
-}
-
-module.exports = isArrayLikeObject;
-
-
-/***/ }),
-
 /***/ 116:
 /***/ (function(module, exports, __webpack_require__) {
 
 var getNative = __webpack_require__(81);
 
 var defineProperty = (function() {
   try {
     var func = getNative(Object, 'defineProperty');
@@ -1212,17 +1058,16 @@ function clearASTs() {
 
 function traverseAst(sourceId, visitor, state) {
   const ast = getAst(sourceId);
   if ((0, _isEmpty2.default)(ast)) {
     return null;
   }
 
   t.traverse(ast, visitor, state);
-  // t.fastTraverse(ast, visitor);
   return ast;
 }
 
 /***/ }),
 
 /***/ 1389:
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -2076,26 +1921,24 @@ var _getScopes2 = _interopRequireDefault
 var _sources = __webpack_require__(1458);
 
 var _findOutOfScopeLocations = __webpack_require__(1624);
 
 var _findOutOfScopeLocations2 = _interopRequireDefault(_findOutOfScopeLocations);
 
 var _steps = __webpack_require__(1625);
 
-var _getEmptyLines = __webpack_require__(1628);
-
-var _getEmptyLines2 = _interopRequireDefault(_getEmptyLines);
-
 var _validate = __webpack_require__(1629);
 
 var _frameworks = __webpack_require__(1703);
 
 var _pauseLocation = __webpack_require__(2422);
 
+var _pausePoints = __webpack_require__(3612);
+
 var _devtoolsUtils = __webpack_require__(1363);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 /* 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/>. */
 
@@ -2109,19 +1952,19 @@ self.onmessage = workerHandler({
   clearSymbols: _getSymbols.clearSymbols,
   clearScopes: _getScopes.clearScopes,
   clearASTs: _ast.clearASTs,
   hasSource: _sources.hasSource,
   setSource: _sources.setSource,
   clearSources: _sources.clearSources,
   isInvalidPauseLocation: _pauseLocation.isInvalidPauseLocation,
   getNextStep: _steps.getNextStep,
-  getEmptyLines: _getEmptyLines2.default,
   hasSyntaxError: _validate.hasSyntaxError,
-  getFramework: _frameworks.getFramework
+  getFramework: _frameworks.getFramework,
+  getPausePoints: _pausePoints.getPausePoints
 });
 
 /***/ }),
 
 /***/ 1620:
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -2523,78 +2366,16 @@ function _getNextStep(statement, positio
 /***/ 1627:
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 /***/ }),
 
-/***/ 1628:
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-Object.defineProperty(exports, "__esModule", {
-  value: true
-});
-exports.default = getEmptyLines;
-
-var _uniq = __webpack_require__(561);
-
-var _uniq2 = _interopRequireDefault(_uniq);
-
-var _difference = __webpack_require__(1129);
-
-var _difference2 = _interopRequireDefault(_difference);
-
-var _ast = __webpack_require__(1375);
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
-const commentTokens = ["CommentBlock", "CommentLine"]; /* This Source Code Form is subject to the terms of the Mozilla Public
-                                                        * License, v. 2.0. If a copy of the MPL was not distributed with this
-                                                        * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
-
-function fillRange(start, end) {
-  return Array(end - start + 1).fill().map((item, index) => start + index);
-}
-
-// Populates a pre-filled array of every line number,
-// then removes lines which were found to be executable
-function getLines(ast) {
-  return fillRange(1, ast.tokens[ast.tokens.length - 1].loc.end.line);
-}
-
-// The following sequence stores lines which have executable code
-// (contents other than comments or EOF, regardless of line position)
-function getExecutableLines(ast) {
-  const lines = ast.tokens.filter(token => !commentTokens.includes(token.type) && (!token.type || token.type.label && token.type.label != "eof")).map(token => token.loc.start.line);
-
-  return (0, _uniq2.default)(lines);
-}
-
-function getEmptyLines(sourceId) {
-  if (!sourceId) {
-    return null;
-  }
-
-  const ast = (0, _ast.getAst)(sourceId);
-  if (!ast || !ast.comments) {
-    return [];
-  }
-
-  const executableLines = getExecutableLines(ast);
-  const lines = getLines(ast);
-  return (0, _difference2.default)(lines, executableLines);
-}
-
-/***/ }),
-
 /***/ 1629:
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
@@ -14547,21 +14328,30 @@ function parseSourceScopes(sourceId) {
   if ((0, _isEmpty2.default)(ast)) {
     return null;
   }
 
   const { global, lexical } = createGlobalScope(ast, sourceId);
 
   const state = {
     sourceId,
+    freeVariables: new Map(),
+    freeVariableStack: [],
     scope: lexical,
     scopeStack: []
   };
   t.traverse(ast, scopeCollectionVisitor, state);
 
+  for (const [key, freeVariables] of state.freeVariables) {
+    const binding = global.bindings[key];
+    if (binding) {
+      binding.refs = freeVariables.concat(binding.refs);
+    }
+  }
+
   // TODO: This should probably check for ".mjs" extension on the
   // original file, and should also be skipped if the the generated
   // code is an ES6 module rather than a script.
   if ((0, _devtoolsSourceMap.isGeneratedId)(sourceId) || ast.program.sourceType === "script" && !looksLikeCommonJS(global)) {
     stripModuleScope(global);
   }
 
   return toParsedScopes([global], sourceId) || [];
@@ -14600,16 +14390,19 @@ function createTempScope(type, displayNa
     parent.children.push(result);
   }
   return result;
 }
 function pushTempScope(state, type, displayName, loc) {
   const scope = createTempScope(type, displayName, state.scope, loc);
 
   state.scope = scope;
+
+  state.freeVariableStack.push(state.freeVariables);
+  state.freeVariables = new Map();
   return scope;
 }
 
 function isNode(node, type) {
   return node ? node.type === type : false;
 }
 
 function getVarScope(scope) {
@@ -14673,26 +14466,16 @@ function hasLexicalDeclaration(node, par
   const isFunctionBody = t.isFunction(parent, { body: node });
 
   return node.body.some(child => isLexicalVariable(child) || !isFunctionBody && child.type === "FunctionDeclaration" || child.type === "ClassDeclaration");
 }
 function isLexicalVariable(node) {
   return isNode(node, "VariableDeclaration") && isLetOrConst(node);
 }
 
-function findIdentifierInScopes(scope, name) {
-  // Find nearest outer scope with the specifed name and add reference.
-  for (let s = scope; s; s = s.parent) {
-    if (name in s.bindings) {
-      return s;
-    }
-  }
-  return null;
-}
-
 function createGlobalScope(ast, sourceId) {
   const global = createTempScope("object", "Global", null, {
     start: fromBabelLocation(ast.loc.start, sourceId),
     end: fromBabelLocation(ast.loc.end, sourceId)
   });
 
   // Include fake bindings to collect references to CommonJS
   Object.assign(global.bindings, {
@@ -14864,17 +14647,17 @@ const scopeCollectionVisitor = {
     } else if (t.isVariableDeclaration(node) && (node.kind === "var" ||
     // Lexical declarations in for statements are handled above.
     !t.isForStatement(parentNode, { init: node }) || !t.isForXStatement(parentNode, { left: node }))) {
       // Finds right lexical environment
       const hoistAt = !isLetOrConst(node) ? getVarScope(state.scope) : state.scope;
       node.declarations.forEach(declarator => {
         parseDeclarator(declarator.id, hoistAt, node.kind, node, state.sourceId);
       });
-    } else if (t.isImportDeclaration(node)) {
+    } else if (t.isImportDeclaration(node) && (!node.importKind || node.importKind === "value")) {
       node.specifiers.forEach(spec => {
         if (t.isImportNamespaceSpecifier(spec)) {
           state.scope.bindings[spec.local.name] = {
             // Imported namespaces aren't live import bindings, they are
             // just normal const bindings.
             type: "const",
             refs: [{
               type: "decl",
@@ -14894,35 +14677,41 @@ const scopeCollectionVisitor = {
                 start: fromBabelLocation(node.loc.start, state.sourceId),
                 end: fromBabelLocation(node.loc.end, state.sourceId)
               }
             }]
           };
         }
       });
     } else if (t.isIdentifier(node) && t.isReferenced(node, parentNode)) {
-      const identScope = findIdentifierInScopes(state.scope, node.name);
-      if (identScope) {
-        identScope.bindings[node.name].refs.push({
-          type: "ref",
-          start: fromBabelLocation(node.loc.start, state.sourceId),
-          end: fromBabelLocation(node.loc.end, state.sourceId),
-          meta: buildMetaBindings(state.sourceId, node, ancestors)
-        });
-      }
+      let freeVariables = state.freeVariables.get(node.name);
+      if (!freeVariables) {
+        freeVariables = [];
+        state.freeVariables.set(node.name, freeVariables);
+      }
+
+      freeVariables.push({
+        type: "ref",
+        start: fromBabelLocation(node.loc.start, state.sourceId),
+        end: fromBabelLocation(node.loc.end, state.sourceId),
+        meta: buildMetaBindings(state.sourceId, node, ancestors)
+      });
     } else if (t.isThisExpression(node)) {
-      const identScope = findIdentifierInScopes(state.scope, "this");
-      if (identScope) {
-        identScope.bindings.this.refs.push({
-          type: "ref",
-          start: fromBabelLocation(node.loc.start, state.sourceId),
-          end: fromBabelLocation(node.loc.end, state.sourceId),
-          meta: buildMetaBindings(state.sourceId, node, ancestors)
-        });
-      }
+      let freeVariables = state.freeVariables.get("this");
+      if (!freeVariables) {
+        freeVariables = [];
+        state.freeVariables.set("this", freeVariables);
+      }
+
+      freeVariables.push({
+        type: "ref",
+        start: fromBabelLocation(node.loc.start, state.sourceId),
+        end: fromBabelLocation(node.loc.end, state.sourceId),
+        meta: buildMetaBindings(state.sourceId, node, ancestors)
+      });
     } else if (t.isClassProperty(parentNode, { value: node })) {
       const scope = pushTempScope(state, "function", "Class Field", {
         start: fromBabelLocation(node.loc.start, state.sourceId),
         end: fromBabelLocation(node.loc.end, state.sourceId)
       });
       scope.bindings.this = {
         type: "implicit",
         refs: []
@@ -14934,22 +14723,55 @@ const scopeCollectionVisitor = {
     } else if (t.isSwitchStatement(node) && node.cases.some(caseNode => caseNode.consequent.some(child => isLexicalVariable(child)))) {
       pushTempScope(state, "block", "Switch", {
         start: fromBabelLocation(node.loc.start, state.sourceId),
         end: fromBabelLocation(node.loc.end, state.sourceId)
       });
     }
   },
   exit(node, ancestors, state) {
-    const scope = state.scopeStack.pop();
-    if (!scope) {
+    const currentScope = state.scope;
+    const parentScope = state.scopeStack.pop();
+    if (!parentScope) {
       throw new Error("Assertion failure - unsynchronized pop");
     }
-
-    state.scope = scope;
+    state.scope = parentScope;
+
+    // It is possible, as in the case of function expressions, that a single
+    // node has added multiple scopes, so we need to traverse upward here
+    // rather than jumping stright to 'parentScope'.
+    for (let scope = currentScope; scope && scope !== parentScope; scope = scope.parent) {
+      const freeVariables = state.freeVariables;
+      state.freeVariables = state.freeVariableStack.pop();
+      const parentFreeVariables = state.freeVariables;
+
+      // Match up any free variables that match this scope's bindings and
+      // merge then into the refs.
+      for (const key of Object.keys(scope.bindings)) {
+        const binding = scope.bindings[key];
+
+        const freeVars = freeVariables.get(key);
+        if (freeVars) {
+          binding.refs.push(...freeVars);
+          freeVariables.delete(key);
+        }
+      }
+
+      // Move any undeclared references in this scope into the parent for
+      // processing in higher scopes.
+      for (const [key, value] of freeVariables) {
+        let refs = parentFreeVariables.get(key);
+        if (!refs) {
+          refs = [];
+          parentFreeVariables.set(key, refs);
+        }
+
+        refs.push(...value);
+      }
+    }
   }
 };
 
 function buildMetaBindings(sourceId, node, ancestors, parentIndex = ancestors.length - 1) {
   if (parentIndex <= 1) {
     return null;
   }
   const parent = ancestors[parentIndex].node;
@@ -16443,16 +16265,82 @@ class SimplePath {
     }
 
     return new SimplePath(this._ancestors.slice(0, -1).concat([{ node, key, index: siblingIndex }]));
   }
 }
 
 /***/ }),
 
+/***/ 3612:
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.getPausePoints = getPausePoints;
+
+var _ast = __webpack_require__(1375);
+
+var _types = __webpack_require__(2268);
+
+var t = _interopRequireWildcard(_types);
+
+function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
+
+const isControlFlow = node => t.isForStatement(node) || t.isWhileStatement(node) || t.isIfStatement(node);
+
+const isAssignment = node => t.isVariableDeclaration(node) || t.isAssignmentExpression(node);
+
+const isImport = node => t.isImport(node) || t.isImportDeclaration(node);
+const isReturn = node => t.isReturnStatement(node);
+const inExpression = parent => t.isArrayExpression(parent.node) || t.isObjectProperty(parent.node) || t.isCallExpression(parent.node);
+
+function getPausePoints(sourceId) {
+  const state = [];
+  (0, _ast.traverseAst)(sourceId, { enter: onEnter }, state);
+  return state;
+}
+
+function formatNode(location, types) {
+  return { location, types };
+}
+
+function onEnter(node, ancestors, state) {
+  const parent = ancestors[ancestors.length - 1];
+
+  if (isAssignment(node) || isImport(node) || isControlFlow(node) || isReturn(node)) {
+    state.push(formatNode(node.loc.start, { breakpoint: true, stepOver: true }));
+  }
+
+  if (t.isCallExpression(node)) {
+    state.push(formatNode(node.loc.start, {
+      breakpoint: true,
+
+      // NOTE: we do not want to land inside an expression e.g. [], {}, call
+      stepOver: !inExpression(parent)
+    }));
+  }
+
+  if (t.isDebuggerStatement(node)) {
+    state.push(formatNode(node.loc.start, { breakpoint: true, stepOver: true }));
+  }
+
+  if (t.isFunction(node)) {
+    const { line, column } = node.loc.end;
+    state.push(formatNode(node.loc.start, { breakpoint: true }));
+    state.push(formatNode({ line, column: column - 1 }, { breakpoint: true, stepOver: true }));
+  }
+}
+
+/***/ }),
+
 /***/ 398:
 /***/ (function(module, exports, __webpack_require__) {
 
 /* WEBPACK VAR INJECTION */(function(module) {var root = __webpack_require__(8);
 
 /** Detect free variable `exports`. */
 var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
 
@@ -16774,238 +16662,16 @@ function nativeKeysIn(object) {
   return result;
 }
 
 module.exports = nativeKeysIn;
 
 
 /***/ }),
 
-/***/ 411:
-/***/ (function(module, exports, __webpack_require__) {
-
-var identity = __webpack_require__(298),
-    overRest = __webpack_require__(412),
-    setToString = __webpack_require__(414);
-
-/**
- * The base implementation of `_.rest` which doesn't validate or coerce arguments.
- *
- * @private
- * @param {Function} func The function to apply a rest parameter to.
- * @param {number} [start=func.length-1] The start position of the rest parameter.
- * @returns {Function} Returns the new function.
- */
-function baseRest(func, start) {
-  return setToString(overRest(func, start, identity), func + '');
-}
-
-module.exports = baseRest;
-
-
-/***/ }),
-
-/***/ 412:
-/***/ (function(module, exports, __webpack_require__) {
-
-var apply = __webpack_require__(413);
-
-/* Built-in method references for those with the same name as other `lodash` methods. */
-var nativeMax = Math.max;
-
-/**
- * A specialized version of `baseRest` which transforms the rest array.
- *
- * @private
- * @param {Function} func The function to apply a rest parameter to.
- * @param {number} [start=func.length-1] The start position of the rest parameter.
- * @param {Function} transform The rest array transform.
- * @returns {Function} Returns the new function.
- */
-function overRest(func, start, transform) {
-  start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
-  return function() {
-    var args = arguments,
-        index = -1,
-        length = nativeMax(args.length - start, 0),
-        array = Array(length);
-
-    while (++index < length) {
-      array[index] = args[start + index];
-    }
-    index = -1;
-    var otherArgs = Array(start + 1);
-    while (++index < start) {
-      otherArgs[index] = args[index];
-    }
-    otherArgs[start] = transform(array);
-    return apply(func, this, otherArgs);
-  };
-}
-
-module.exports = overRest;
-
-
-/***/ }),
-
-/***/ 413:
-/***/ (function(module, exports) {
-
-/**
- * A faster alternative to `Function#apply`, this function invokes `func`
- * with the `this` binding of `thisArg` and the arguments of `args`.
- *
- * @private
- * @param {Function} func The function to invoke.
- * @param {*} thisArg The `this` binding of `func`.
- * @param {Array} args The arguments to invoke `func` with.
- * @returns {*} Returns the result of `func`.
- */
-function apply(func, thisArg, args) {
-  switch (args.length) {
-    case 0: return func.call(thisArg);
-    case 1: return func.call(thisArg, args[0]);
-    case 2: return func.call(thisArg, args[0], args[1]);
-    case 3: return func.call(thisArg, args[0], args[1], args[2]);
-  }
-  return func.apply(thisArg, args);
-}
-
-module.exports = apply;
-
-
-/***/ }),
-
-/***/ 414:
-/***/ (function(module, exports, __webpack_require__) {
-
-var baseSetToString = __webpack_require__(415),
-    shortOut = __webpack_require__(417);
-
-/**
- * Sets the `toString` method of `func` to return `string`.
- *
- * @private
- * @param {Function} func The function to modify.
- * @param {Function} string The `toString` result.
- * @returns {Function} Returns `func`.
- */
-var setToString = shortOut(baseSetToString);
-
-module.exports = setToString;
-
-
-/***/ }),
-
-/***/ 415:
-/***/ (function(module, exports, __webpack_require__) {
-
-var constant = __webpack_require__(416),
-    defineProperty = __webpack_require__(116),
-    identity = __webpack_require__(298);
-
-/**
- * The base implementation of `setToString` without support for hot loop shorting.
- *
- * @private
- * @param {Function} func The function to modify.
- * @param {Function} string The `toString` result.
- * @returns {Function} Returns `func`.
- */
-var baseSetToString = !defineProperty ? identity : function(func, string) {
-  return defineProperty(func, 'toString', {
-    'configurable': true,
-    'enumerable': false,
-    'value': constant(string),
-    'writable': true
-  });
-};
-
-module.exports = baseSetToString;
-
-
-/***/ }),
-
-/***/ 416:
-/***/ (function(module, exports) {
-
-/**
- * Creates a function that returns `value`.
- *
- * @static
- * @memberOf _
- * @since 2.4.0
- * @category Util
- * @param {*} value The value to return from the new function.
- * @returns {Function} Returns the new constant function.
- * @example
- *
- * var objects = _.times(2, _.constant({ 'a': 1 }));
- *
- * console.log(objects);
- * // => [{ 'a': 1 }, { 'a': 1 }]
- *
- * console.log(objects[0] === objects[1]);
- * // => true
- */
-function constant(value) {
-  return function() {
-    return value;
-  };
-}
-
-module.exports = constant;
-
-
-/***/ }),
-
-/***/ 417:
-/***/ (function(module, exports) {
-
-/** Used to detect hot functions by number of calls within a span of milliseconds. */
-var HOT_COUNT = 800,
-    HOT_SPAN = 16;
-
-/* Built-in method references for those with the same name as other `lodash` methods. */
-var nativeNow = Date.now;
-
-/**
- * Creates a function that'll short out and invoke `identity` instead
- * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
- * milliseconds.
- *
- * @private
- * @param {Function} func The function to restrict.
- * @returns {Function} Returns the new shortable function.
- */
-function shortOut(func) {
-  var count = 0,
-      lastCalled = 0;
-
-  return function() {
-    var stamp = nativeNow(),
-        remaining = HOT_SPAN - (stamp - lastCalled);
-
-    lastCalled = stamp;
-    if (remaining > 0) {
-      if (++count >= HOT_COUNT) {
-        return arguments[0];
-      }
-    } else {
-      count = 0;
-    }
-    return func.apply(undefined, arguments);
-  };
-}
-
-module.exports = shortOut;
-
-
-/***/ }),
-
 /***/ 435:
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, '__esModule', { value: true });
 
--- a/devtools/client/debugger/new/test/mochitest/browser.ini
+++ b/devtools/client/debugger/new/test/mochitest/browser.ini
@@ -22,16 +22,20 @@ support-files =
   examples/babel/fixtures/for-loops/output.js
   examples/babel/fixtures/for-loops/output.js.map
   examples/babel/fixtures/functions/output.js
   examples/babel/fixtures/functions/output.js.map
   examples/babel/fixtures/modules/output.js
   examples/babel/fixtures/modules/output.js.map
   examples/babel/fixtures/non-modules/output.js
   examples/babel/fixtures/non-modules/output.js.map
+  examples/babel/fixtures/out-of-order-declarations/output.js
+  examples/babel/fixtures/out-of-order-declarations/output.js.map
+  examples/babel/fixtures/flowtype-bindings/output.js
+  examples/babel/fixtures/flowtype-bindings/output.js.map
   examples/babel/fixtures/step-over-for-of/output.js
   examples/babel/fixtures/step-over-for-of/output.js.map
   examples/babel/fixtures/step-over-for-of-closure/output.js
   examples/babel/fixtures/step-over-for-of-closure/output.js.map
   examples/babel/fixtures/step-over-for-of-array/output.js
   examples/babel/fixtures/step-over-for-of-array/output.js.map
   examples/babel/fixtures/step-over-for-of-array-closure/output.js
   examples/babel/fixtures/step-over-for-of-array-closure/output.js.map
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-babel-scopes.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-babel-scopes.js
@@ -246,18 +246,41 @@ add_task(async function() {
 
   await breakpointScopes(dbg, "commonjs", { line: 7, column: 2 }, [
     "Module",
     ["alsoModuleScoped", "2"],
     ["moduleScoped", "1"],
     "thirdModuleScoped()"
   ]);
 
+  await breakpointScopes(dbg, "out-of-order-declarations", { line: 8, column: 4 }, [
+    "callback",
+    "fn()",
+    ["val", "undefined"],
+    "root",
+    ["callback", "(optimized away)"],
+    ["fn", "(optimized away)"],
+    ["val", "(optimized away)"],
+    "Module",
+
+    // This value is currently unmapped because import declarations don't map
+    // very well and ones at the end of the file map especially badly.
+    ["aDefault", "(unmapped)"],
+    ["root", "(optimized away)"],
+    ["val", "(optimized away)"],
+  ]);
+
   await breakpointScopes(dbg, "non-modules", { line: 7, column: 2 }, []);
 
+  await breakpointScopes(dbg, "flowtype-bindings", { line: 8, column: 2 }, [
+    "Module",
+    ["aConst", '"a-const"'],
+    "root()"
+  ]);
+
   await breakpointScopes(dbg, "switches", { line: 7, column: 6 }, [
     "Switch",
     ["val", "2"],
     "Block",
     ["val", "1"],
     "Module",
     "root()"
   ]);
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-breakpoints-cond.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-breakpoints-cond.js
@@ -44,16 +44,17 @@ async function setConditionalBreakpoint(
   pressKey(dbg, "End");
   type(dbg, condition);
   pressKey(dbg, "Enter");
 }
 
 add_task(async function() {
   const dbg = await initDebugger("doc-scripts.html");
   await selectSource(dbg, "simple2");
+  await waitForSelectedSource(dbg, "simple2");
 
   await setConditionalBreakpoint(dbg, 5, "1");
   await waitForDispatch(dbg, "ADD_BREAKPOINT");
   let bp = findBreakpoint(dbg, "simple2", 5);
   is(bp.condition, "1", "breakpoint is created with the condition");
   assertEditorBreakpoint(dbg, 5, true);
 
   await setConditionalBreakpoint(dbg, 5, "2");
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/babel/fixtures/flowtype-bindings/input.js
@@ -0,0 +1,9 @@
+import type { One, Two, Three } from "./src/mod";
+
+type Other = {};
+
+const aConst = "a-const";
+
+export default function root() {
+  console.log("pause here", aConst, root);
+}
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/babel/fixtures/flowtype-bindings/output.js
@@ -0,0 +1,89 @@
+var flowtypeBindings =
+/******/ (function(modules) { // webpackBootstrap
+/******/ 	// The module cache
+/******/ 	var installedModules = {};
+/******/
+/******/ 	// The require function
+/******/ 	function __webpack_require__(moduleId) {
+/******/
+/******/ 		// Check if module is in cache
+/******/ 		if(installedModules[moduleId]) {
+/******/ 			return installedModules[moduleId].exports;
+/******/ 		}
+/******/ 		// Create a new module (and put it into the cache)
+/******/ 		var module = installedModules[moduleId] = {
+/******/ 			i: moduleId,
+/******/ 			l: false,
+/******/ 			exports: {}
+/******/ 		};
+/******/
+/******/ 		// Execute the module function
+/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
+/******/
+/******/ 		// Flag the module as loaded
+/******/ 		module.l = true;
+/******/
+/******/ 		// Return the exports of the module
+/******/ 		return module.exports;
+/******/ 	}
+/******/
+/******/
+/******/ 	// expose the modules object (__webpack_modules__)
+/******/ 	__webpack_require__.m = modules;
+/******/
+/******/ 	// expose the module cache
+/******/ 	__webpack_require__.c = installedModules;
+/******/
+/******/ 	// define getter function for harmony exports
+/******/ 	__webpack_require__.d = function(exports, name, getter) {
+/******/ 		if(!__webpack_require__.o(exports, name)) {
+/******/ 			Object.defineProperty(exports, name, {
+/******/ 				configurable: false,
+/******/ 				enumerable: true,
+/******/ 				get: getter
+/******/ 			});
+/******/ 		}
+/******/ 	};
+/******/
+/******/ 	// getDefaultExport function for compatibility with non-harmony modules
+/******/ 	__webpack_require__.n = function(module) {
+/******/ 		var getter = module && module.__esModule ?
+/******/ 			function getDefault() { return module['default']; } :
+/******/ 			function getModuleExports() { return module; };
+/******/ 		__webpack_require__.d(getter, 'a', getter);
+/******/ 		return getter;
+/******/ 	};
+/******/
+/******/ 	// Object.prototype.hasOwnProperty.call
+/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
+/******/
+/******/ 	// __webpack_public_path__
+/******/ 	__webpack_require__.p = "";
+/******/
+/******/ 	// Load entry module and return exports
+/******/ 	return __webpack_require__(__webpack_require__.s = 0);
+/******/ })
+/************************************************************************/
+/******/ ([
+/* 0 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.default = root;
+
+
+var aConst = "a-const";
+
+function root() {
+  console.log("pause here", aConst, root);
+}
+module.exports = exports["default"];
+
+/***/ })
+/******/ ]);
+//# sourceMappingURL=output.js.map
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/babel/fixtures/flowtype-bindings/output.js.map
@@ -0,0 +1,1 @@
+{"version":3,"sources":["webpack:///webpack/bootstrap 1fc1e80408151897b204","webpack:///./fixtures/flowtype-bindings/input.js"],"names":["root","aConst","console","log"],"mappings":";;AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAK;AACL;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;AAEA;AACA;;;;;;;;;;;;;kBCvDwBA,I;;;AAFxB,IAAMC,SAAS,SAAf;;AAEe,SAASD,IAAT,GAAgB;AAC7BE,UAAQC,GAAR,CAAY,YAAZ,EAA0BF,MAA1B,EAAkCD,IAAlC;AACD","file":"fixtures/flowtype-bindings/output.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 1fc1e80408151897b204","import type { One, Two, Three } from \"./src/mod\";\n\ntype Other = {};\n\nconst aConst = \"a-const\";\n\nexport default function root() {\n  console.log(\"pause here\", aConst, root);\n}\n\n\n\n// WEBPACK FOOTER //\n// ./fixtures/flowtype-bindings/input.js"],"sourceRoot":""}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/babel/fixtures/flowtype-bindings/src/mod.js
@@ -0,0 +1,1 @@
+export default "a-default";
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/babel/fixtures/out-of-order-declarations/input.js
@@ -0,0 +1,17 @@
+var val = "outer-value";
+
+export default function root() {
+  var val = "middle-value";
+  var fn = function outerFn(outer){};
+
+  function callback() {
+    console.log("pause here", val, aDefault, fn);
+
+    var val = "inner-value";
+    function fn(inner){};
+  }
+
+  callback();
+}
+
+import aDefault from "./src/mod";
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/babel/fixtures/out-of-order-declarations/output.js
@@ -0,0 +1,118 @@
+var outOfOrderDeclarations =
+/******/ (function(modules) { // webpackBootstrap
+/******/ 	// The module cache
+/******/ 	var installedModules = {};
+/******/
+/******/ 	// The require function
+/******/ 	function __webpack_require__(moduleId) {
+/******/
+/******/ 		// Check if module is in cache
+/******/ 		if(installedModules[moduleId]) {
+/******/ 			return installedModules[moduleId].exports;
+/******/ 		}
+/******/ 		// Create a new module (and put it into the cache)
+/******/ 		var module = installedModules[moduleId] = {
+/******/ 			i: moduleId,
+/******/ 			l: false,
+/******/ 			exports: {}
+/******/ 		};
+/******/
+/******/ 		// Execute the module function
+/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
+/******/
+/******/ 		// Flag the module as loaded
+/******/ 		module.l = true;
+/******/
+/******/ 		// Return the exports of the module
+/******/ 		return module.exports;
+/******/ 	}
+/******/
+/******/
+/******/ 	// expose the modules object (__webpack_modules__)
+/******/ 	__webpack_require__.m = modules;
+/******/
+/******/ 	// expose the module cache
+/******/ 	__webpack_require__.c = installedModules;
+/******/
+/******/ 	// define getter function for harmony exports
+/******/ 	__webpack_require__.d = function(exports, name, getter) {
+/******/ 		if(!__webpack_require__.o(exports, name)) {
+/******/ 			Object.defineProperty(exports, name, {
+/******/ 				configurable: false,
+/******/ 				enumerable: true,
+/******/ 				get: getter
+/******/ 			});
+/******/ 		}
+/******/ 	};
+/******/
+/******/ 	// getDefaultExport function for compatibility with non-harmony modules
+/******/ 	__webpack_require__.n = function(module) {
+/******/ 		var getter = module && module.__esModule ?
+/******/ 			function getDefault() { return module['default']; } :
+/******/ 			function getModuleExports() { return module; };
+/******/ 		__webpack_require__.d(getter, 'a', getter);
+/******/ 		return getter;
+/******/ 	};
+/******/
+/******/ 	// Object.prototype.hasOwnProperty.call
+/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
+/******/
+/******/ 	// __webpack_public_path__
+/******/ 	__webpack_require__.p = "";
+/******/
+/******/ 	// Load entry module and return exports
+/******/ 	return __webpack_require__(__webpack_require__.s = 0);
+/******/ })
+/************************************************************************/
+/******/ ([
+/* 0 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.default = root;
+
+var _mod = __webpack_require__(1);
+
+var _mod2 = _interopRequireDefault(_mod);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var val = "outer-value";
+
+function root() {
+  var val = "middle-value";
+  var fn = function outerFn(outer) {};
+
+  function callback() {
+    console.log("pause here", val, _mod2.default, fn);
+
+    var val = "inner-value";
+    function fn(inner) {};
+  }
+
+  callback();
+}
+
+module.exports = exports["default"];
+
+/***/ }),
+/* 1 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.default = "a-default";
+module.exports = exports["default"];
+
+/***/ })
+/******/ ]);
+//# sourceMappingURL=output.js.map
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/babel/fixtures/out-of-order-declarations/output.js.map
@@ -0,0 +1,1 @@
+{"version":3,"sources":["webpack:///webpack/bootstrap 4f5a475903003c64fcaa","webpack:///./fixtures/out-of-order-declarations/input.js","webpack:///./fixtures/out-of-order-declarations/src/mod.js"],"names":["root","val","fn","outerFn","outer","callback","console","log","inner"],"mappings":";;AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAK;AACL;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;AAEA;AACA;;;;;;;;;;;;;kBC3DwBA,I;;AAcxB;;;;;;AAhBA,IAAIC,MAAM,aAAV;;AAEe,SAASD,IAAT,GAAgB;AAC7B,MAAIC,MAAM,cAAV;AACA,MAAIC,KAAK,SAASC,OAAT,CAAiBC,KAAjB,EAAuB,CAAE,CAAlC;;AAEA,WAASC,QAAT,GAAoB;AAClBC,YAAQC,GAAR,CAAY,YAAZ,EAA0BN,GAA1B,iBAAyCC,EAAzC;;AAEA,QAAID,MAAM,aAAV;AACA,aAASC,EAAT,CAAYM,KAAZ,EAAkB,CAAE;AACrB;;AAEDH;AACD;;;;;;;;;;;;;;kBCdc,W","file":"fixtures/out-of-order-declarations/output.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 4f5a475903003c64fcaa","var val = \"outer-value\";\n\nexport default function root() {\n  var val = \"middle-value\";\n  var fn = function outerFn(outer){};\n\n  function callback() {\n    console.log(\"pause here\", val, aDefault, fn);\n\n    var val = \"inner-value\";\n    function fn(inner){};\n  }\n\n  callback();\n}\n\nimport aDefault from \"./src/mod\";\n\n\n\n// WEBPACK FOOTER //\n// ./fixtures/out-of-order-declarations/input.js","export default \"a-default\";\n\n\n\n// WEBPACK FOOTER //\n// ./fixtures/out-of-order-declarations/src/mod.js"],"sourceRoot":""}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/babel/fixtures/out-of-order-declarations/src/mod.js
@@ -0,0 +1,1 @@
+export default "a-default";
--- a/devtools/client/debugger/new/test/mochitest/examples/babel/package.json
+++ b/devtools/client/debugger/new/test/mochitest/examples/babel/package.json
@@ -8,16 +8,17 @@
   },
   "keywords": [],
   "author": "",
   "license": "MPL-2.0",
   "devDependencies": {
     "babel-core": "^6.26.0",
     "babel-loader": "^7.1.2",
     "babel-plugin-add-module-exports": "^0.2.1",
+    "babel-plugin-transform-flow-strip-types": "^6.22.0",
     "babel-preset-env": "^1.6.1",
     "webpack": "^3.7.1"
   },
   "dependencies": {
     "babel-polyfill": "^6.26.0",
     "lodash": "^4.17.5"
   }
 }
--- a/devtools/client/debugger/new/test/mochitest/examples/babel/webpack.config.js
+++ b/devtools/client/debugger/new/test/mochitest/examples/babel/webpack.config.js
@@ -71,17 +71,19 @@ module.exports = [
                 exclude: /node_modules/,
                 loader: "babel-loader",
                 options: {
                   babelrc: false,
                   presets: babelEnv
                     ? [["env", { modules: babelModules ? "commonjs" : false }]]
                     : [],
                   plugins:
-                    babelEnv && babelModules ? ["add-module-exports"] : []
+                    (babelEnv && babelModules ? ["add-module-exports"] : []).concat([
+                      "babel-plugin-transform-flow-strip-types",
+                    ])
                 }
               }
             ]
           : []
       }
     };
   })
 );
--- a/devtools/client/debugger/new/test/mochitest/examples/doc-babel.html
+++ b/devtools/client/debugger/new/test/mochitest/examples/doc-babel.html
@@ -12,28 +12,32 @@
     <!--
       Content generated by examples/babel/webpack.config.js.
       Run "yarn build" to update.
     -->
     <script src="babel/fixtures/classes/output.js"></script>
     <button onclick="classes()">Run classes</button>
     <script src="babel/fixtures/commonjs/output.js"></script>
     <button onclick="commonjs()">Run commonjs</button>
+    <script src="babel/fixtures/flowtype-bindings/output.js"></script>
+    <button onclick="flowtypeBindings()">Run flowtypeBindings</button>
     <script src="babel/fixtures/for-loops/output.js"></script>
     <button onclick="forLoops()">Run forLoops</button>
     <script src="babel/fixtures/for-of/output.js"></script>
     <button onclick="forOf()">Run forOf</button>
     <script src="babel/fixtures/functions/output.js"></script>
     <button onclick="functions()">Run functions</button>
     <script src="babel/fixtures/imported-bindings/output.js"></script>
     <button onclick="importedBindings()">Run importedBindings</button>
     <script src="babel/fixtures/modules/output.js"></script>
     <button onclick="modules()">Run modules</button>
     <script src="babel/fixtures/non-modules/output.js"></script>
     <button onclick="nonModules()">Run nonModules</button>
+    <script src="babel/fixtures/out-of-order-declarations/output.js"></script>
+    <button onclick="outOfOrderDeclarations()">Run outOfOrderDeclarations</button>
     <script src="babel/fixtures/shadowed-vars/output.js"></script>
     <button onclick="shadowedVars()">Run shadowedVars</button>
     <script src="babel/fixtures/step-over-for-of/output.js"></script>
     <button onclick="stepOverForOf()">Run stepOverForOf</button>
     <script src="babel/fixtures/step-over-for-of-array/output.js"></script>
     <button onclick="stepOverForOfArray()">Run stepOverForOfArray</button>
     <script src="babel/fixtures/step-over-for-of-array-closure/output.js"></script>
     <button onclick="stepOverForOfArrayClosure()">Run stepOverForOfArrayClosure</button>
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -13730,17 +13730,17 @@ nsDocShell::OnLinkClickSync(nsIContent* 
 
   // referer could be null here in some odd cases, but that's ok,
   // we'll just load the link w/o sending a referer in those cases.
 
   nsAutoString target(aTargetSpec);
 
   // If this is an anchor element, grab its type property to use as a hint
   nsAutoString typeHint;
-  RefPtr<HTMLAnchorElement> anchor = HTMLAnchorElement::FromContent(aContent);
+  RefPtr<HTMLAnchorElement> anchor = HTMLAnchorElement::FromNode(aContent);
   if (anchor) {
     anchor->GetType(typeHint);
     NS_ConvertUTF16toUTF8 utf8Hint(typeHint);
     nsAutoCString type, dummy;
     NS_ParseRequestContentType(utf8Hint, type, dummy);
     CopyUTF8toUTF16(type, typeHint);
   }
 
--- a/dom/base/CharacterData.h
+++ b/dom/base/CharacterData.h
@@ -84,17 +84,17 @@ public:
   explicit CharacterData(already_AddRefed<dom::NodeInfo>& aNodeInfo);
   explicit CharacterData(already_AddRefed<dom::NodeInfo>&& aNodeInfo);
 
   void MarkAsMaybeModifiedFrequently()
   {
     SetFlags(NS_MAYBE_MODIFIED_FREQUENTLY);
   }
 
-  NS_IMPL_FROMCONTENT_HELPER(CharacterData, IsCharacterData())
+  NS_IMPL_FROMNODE_HELPER(CharacterData, IsCharacterData())
 
   virtual void GetNodeValueInternal(nsAString& aNodeValue) override;
   virtual void SetNodeValueInternal(const nsAString& aNodeValue,
                                     ErrorResult& aError) override;
 
   // nsINode methods
   virtual uint32_t GetChildCount() const override;
   virtual nsIContent *GetChildAt_Deprecated(uint32_t aIndex) const override;
--- a/dom/base/ChildIterator.cpp
+++ b/dom/base/ChildIterator.cpp
@@ -21,17 +21,17 @@ ExplicitChildIterator::ExplicitChildIter
                                              bool aStartAtBeginning)
   : mParent(aParent),
     mChild(nullptr),
     mDefaultChild(nullptr),
     mIsFirst(aStartAtBeginning),
     mIndexInInserted(0)
 {
   mParentAsSlot = nsDocument::IsShadowDOMEnabled(mParent) ?
-    HTMLSlotElement::FromContent(mParent) : nullptr;
+    HTMLSlotElement::FromNode(mParent) : nullptr;
 }
 
 nsIContent*
 ExplicitChildIterator::GetNextChild()
 {
   // If we're already in the inserted-children array, look there first
   if (mIndexInInserted) {
     MOZ_ASSERT(mChild);
--- a/dom/base/DOMImplementation.cpp
+++ b/dom/base/DOMImplementation.cpp
@@ -5,17 +5,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/DOMImplementation.h"
 
 #include "mozilla/ContentEvents.h"
 #include "mozilla/dom/DOMImplementationBinding.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsContentUtils.h"
-#include "nsDOMClassInfoID.h"
 #include "nsIDOMDocument.h"
 #include "mozilla/dom/DocumentType.h"
 #include "nsTextNode.h"
 
 namespace mozilla {
 namespace dom {
 
 // QueryInterface implementation for DOMImplementation
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -1532,17 +1532,17 @@ Element::GetElementsByMatching(nsElement
 
 /**
  * Returns the count of descendants (inclusive of aContent) in
  * the uncomposed document that are explicitly set as editable.
  */
 static uint32_t
 EditableInclusiveDescendantCount(nsIContent* aContent)
 {
-  auto htmlElem = nsGenericHTMLElement::FromContent(aContent);
+  auto htmlElem = nsGenericHTMLElement::FromNode(aContent);
   if (htmlElem) {
     return htmlElem->EditableInclusiveDescendantCount();
   }
 
   return aContent->EditableDescendantCount();
 }
 
 nsresult
@@ -1572,17 +1572,17 @@ Element::BindToTree(nsIDocument* aDocume
                   "Native anonymous content must have its parent as its "
                   "own binding parent");
   NS_PRECONDITION(aBindingParent || !aParent ||
                   aBindingParent == aParent->GetBindingParent(),
                   "We should be passed the right binding parent");
 
 #ifdef MOZ_XUL
   // First set the binding parent
-  nsXULElement* xulElem = nsXULElement::FromContent(this);
+  nsXULElement* xulElem = nsXULElement::FromNode(this);
   if (xulElem) {
     xulElem->SetXULBindingParent(aBindingParent);
   }
   else
 #endif
   {
     if (aBindingParent) {
       nsExtendedDOMSlots* slots = ExtendedDOMSlots();
@@ -1974,17 +1974,17 @@ Element::UnbindFromTree(bool aDeep, bool
 
     // Begin keeping track of our subtree root.
     SetSubtreeRootPointer(aNullParent ? this : mParent->SubtreeRoot());
   }
 
   bool clearBindingParent = true;
 
 #ifdef MOZ_XUL
-  if (nsXULElement* xulElem = nsXULElement::FromContent(this)) {;
+  if (nsXULElement* xulElem = nsXULElement::FromNode(this)) {;
     xulElem->SetXULBindingParent(nullptr);
     clearBindingParent = false;
   }
 #endif
 
   if (nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots()) {
     if (clearBindingParent) {
       slots->mBindingParent = nullptr;
--- a/dom/base/FragmentOrElement.cpp
+++ b/dom/base/FragmentOrElement.cpp
@@ -59,25 +59,27 @@
 #include "nsError.h"
 #include "nsDOMString.h"
 #include "nsIScriptSecurityManager.h"
 #include "mozilla/InternalMutationEvent.h"
 #include "mozilla/MouseEvents.h"
 #include "nsNodeUtils.h"
 #include "nsDocument.h"
 #include "nsAttrValueOrString.h"
+#include "nsQueryObject.h"
 #ifdef MOZ_XUL
 #include "nsXULElement.h"
 #endif /* MOZ_XUL */
 #include "nsFrameSelection.h"
 #ifdef DEBUG
 #include "nsRange.h"
 #endif
 
 #include "nsBindingManager.h"
+#include "nsFrameLoader.h"
 #include "nsXBLBinding.h"
 #include "nsPIDOMWindow.h"
 #include "nsPIBoxObject.h"
 #include "nsSVGUtils.h"
 #include "nsLayoutUtils.h"
 #include "nsGkAtoms.h"
 #include "nsContentUtils.h"
 #include "nsTextFragment.h"
@@ -741,19 +743,19 @@ FragmentOrElement::nsDOMSlots::SizeOfInc
   // - mBindingParent / mControllers: because they're   non-owning
   return n;
 }
 
 FragmentOrElement::nsExtendedDOMSlots::nsExtendedDOMSlots() = default;
 
 FragmentOrElement::nsExtendedDOMSlots::~nsExtendedDOMSlots()
 {
-  nsCOMPtr<nsIFrameLoader> frameLoader = do_QueryInterface(mFrameLoaderOrOpener);
+  RefPtr<nsFrameLoader> frameLoader = do_QueryObject(mFrameLoaderOrOpener);
   if (frameLoader) {
-    static_cast<nsFrameLoader*>(frameLoader.get())->Destroy();
+    frameLoader->Destroy();
   }
 }
 
 void
 FragmentOrElement::nsExtendedDOMSlots::Unlink()
 {
   nsIContent::nsExtendedContentSlots::Unlink();
 
@@ -762,20 +764,19 @@ FragmentOrElement::nsExtendedDOMSlots::U
   mSMILOverrideStyle = nullptr;
   mControllers = nullptr;
   mLabelsList = nullptr;
   mShadowRoot = nullptr;
   if (mCustomElementData) {
     mCustomElementData->Unlink();
     mCustomElementData = nullptr;
   }
-  nsCOMPtr<nsIFrameLoader> frameLoader =
-    do_QueryInterface(mFrameLoaderOrOpener);
+  RefPtr<nsFrameLoader> frameLoader = do_QueryObject(mFrameLoaderOrOpener);
   if (frameLoader) {
-    static_cast<nsFrameLoader*>(frameLoader.get())->Destroy();
+    frameLoader->Destroy();
   }
   mFrameLoaderOrOpener = nullptr;
 }
 
 void
 FragmentOrElement::nsExtendedDOMSlots::Traverse(nsCycleCollectionTraversalCallback& aCb)
 {
   nsIContent::nsExtendedContentSlots::Traverse(aCb);
--- a/dom/base/Location.cpp
+++ b/dom/base/Location.cpp
@@ -19,17 +19,16 @@
 #include "nsNetUtil.h"
 #include "nsCOMPtr.h"
 #include "nsEscape.h"
 #include "nsIDOMWindow.h"
 #include "nsIDocument.h"
 #include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "nsError.h"
-#include "nsDOMClassInfoID.h"
 #include "nsReadableUtils.h"
 #include "nsITextToSubURI.h"
 #include "nsJSUtils.h"
 #include "nsContentUtils.h"
 #include "nsGlobalWindow.h"
 #include "mozilla/Likely.h"
 #include "nsCycleCollectionParticipant.h"
 #include "NullPrincipal.h"
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -70,18 +70,16 @@
 #include "nsIScriptError.h"
 
 #include "mozilla/dom/MediaDevices.h"
 #include "MediaManager.h"
 
 #include "nsIDOMGlobalPropertyInitializer.h"
 #include "nsJSUtils.h"
 
-#include "nsScriptNameSpaceManager.h"
-
 #include "mozilla/dom/NavigatorBinding.h"
 #include "mozilla/dom/Promise.h"
 
 #include "nsIUploadChannel2.h"
 #include "mozilla/dom/FormData.h"
 #include "nsIDocShell.h"
 
 #include "mozilla/dom/WorkerPrivate.h"
--- a/dom/base/ShadowRoot.cpp
+++ b/dom/base/ShadowRoot.cpp
@@ -5,17 +5,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/ShadowRoot.h"
 #include "mozilla/dom/ShadowRootBinding.h"
 #include "mozilla/dom/DocumentFragment.h"
 #include "ChildIterator.h"
 #include "nsContentUtils.h"
-#include "nsDOMClassInfoID.h"
 #include "nsIStyleSheetLinkingElement.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/HTMLSlotElement.h"
 #include "nsXBLPrototypeBinding.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/StyleSheet.h"
 #include "mozilla/StyleSheetInlines.h"
 
@@ -614,17 +613,17 @@ ShadowRoot::ContentInserted(nsIContent* 
       assignment.mSlot->AppendAssignedNode(aChild);
     }
     assignment.mSlot->EnqueueSlotChangeEvent();
     return;
   }
 
   // If parent's root is a shadow root, and parent is a slot whose assigned
   // nodes is the empty list, then run signal a slot change for parent.
-  HTMLSlotElement* slot = HTMLSlotElement::FromContentOrNull(aChild->GetParent());
+  HTMLSlotElement* slot = HTMLSlotElement::FromNodeOrNull(aChild->GetParent());
   if (slot && slot->GetContainingShadow() == this &&
       slot->AssignedNodes().IsEmpty()) {
     slot->EnqueueSlotChangeEvent();
   }
 }
 
 void
 ShadowRoot::ContentRemoved(nsIContent* aChild, nsIContent* aPreviousSibling)
@@ -650,17 +649,17 @@ ShadowRoot::ContentRemoved(nsIContent* a
       slot->RemoveAssignedNode(aChild);
       slot->EnqueueSlotChangeEvent();
     }
     return;
   }
 
   // If parent's root is a shadow root, and parent is a slot whose assigned
   // nodes is the empty list, then run signal a slot change for parent.
-  HTMLSlotElement* slot = HTMLSlotElement::FromContentOrNull(aChild->GetParent());
+  HTMLSlotElement* slot = HTMLSlotElement::FromNodeOrNull(aChild->GetParent());
   if (slot && slot->GetContainingShadow() == this &&
       slot->AssignedNodes().IsEmpty()) {
     slot->EnqueueSlotChangeEvent();
   }
 }
 
 ServoStyleRuleMap&
 ShadowRoot::ServoStyleRuleMap()
--- a/dom/base/moz.build
+++ b/dom/base/moz.build
@@ -17,17 +17,17 @@ XPIDL_SOURCES += [
     'nsIContentPolicy.idl',
     'nsIDocumentEncoder.idl',
     'nsIDOMDataChannel.idl',
     'nsIDOMDOMCursor.idl',
     'nsIDOMDOMRequest.idl',
     'nsIDOMParser.idl',
     'nsIDOMSerializer.idl',
     'nsIDroppedLinkHandler.idl',
-    'nsIFrameLoader.idl',
+    'nsIFrameLoaderOwner.idl',
     'nsIImageLoadingContent.idl',
     'nsIMessageManager.idl',
     'nsIObjectLoadingContent.idl',
     'nsIPerformanceMetrics.idl',
     'nsIRemoteWindowContext.idl',
     'nsIScriptChannel.idl',
     'nsISelection.idl',
     'nsISelectionController.idl',
@@ -61,17 +61,16 @@ EXPORTS += [
     'nsContentTypeParser.h',
     'nsContentUtils.h',
     'nsCopySupport.h',
     'nsDeprecatedOperationList.h',
     'nsDocElementCreatedNotificationRunner.h',
     'nsDocumentWarningList.h',
     'nsDOMAttributeMap.h',
     'nsDOMCID.h',
-    'nsDOMClassInfoID.h',
     'nsDOMJSUtils.h',
     'nsDOMNavigationTiming.h',
     'nsDOMString.h',
     'nsDOMTokenList.h',
     'nsFocusManager.h',
     'nsFrameMessageManager.h',
     'nsGlobalWindow.h',  # Because binding headers include it.
     'nsGlobalWindowInner.h',  # Because binding headers include it.
@@ -89,17 +88,16 @@ EXPORTS += [
     'nsIDOMClassInfo.h',
     'nsIGlobalObject.h',
     'nsImageLoadingContent.h',
     'nsIMutationObserver.h',
     'nsINode.h',
     'nsINodeList.h',
     'nsIScriptContext.h',
     'nsIScriptGlobalObject.h',
-    'nsIScriptNameSpaceManager.h',
     'nsIScriptObjectPrincipal.h',
     'nsIScriptTimeoutHandler.h',
     'nsIStyleSheetLinkingElement.h',
     'nsITimeoutHandler.h',
     'nsJSEnvironment.h',
     'nsJSUtils.h',
     'nsLineBreaker.h',
     'nsMappedAttributeElement.h',
@@ -328,17 +326,16 @@ UNIFIED_SOURCES += [
     'nsNodeUtils.cpp',
     'nsOpenURIInFrameParams.cpp',
     'nsPerformanceMetrics.cpp',
     'nsPlainTextSerializer.cpp',
     'nsPropertyTable.cpp',
     'nsQueryContentEventResult.cpp',
     'nsRange.cpp',
     'nsScreen.cpp',
-    'nsScriptNameSpaceManager.cpp',
     'nsStructuredCloneContainer.cpp',
     'nsStubAnimationObserver.cpp',
     'nsStubDocumentObserver.cpp',
     'nsStubMutationObserver.cpp',
     'nsStyledElement.cpp',
     'nsStyleLinkElement.cpp',
     'nsSyncLoadService.cpp',
     'nsTextFragment.cpp',
--- a/dom/base/nsContentAreaDragDrop.cpp
+++ b/dom/base/nsContentAreaDragDrop.cpp
@@ -504,17 +504,17 @@ DragDataProducer::Produce(DataTransfer* 
       }
       image = do_QueryInterface(draggedNode);
     }
 
     {
       // set for linked images, and links
       nsCOMPtr<nsIContent> linkNode;
 
-      RefPtr<HTMLAreaElement> areaElem = HTMLAreaElement::FromContentOrNull(draggedNode);
+      RefPtr<HTMLAreaElement> areaElem = HTMLAreaElement::FromNodeOrNull(draggedNode);
       if (areaElem) {
         // use the alt text (or, if missing, the href) as the title
         areaElem->GetAttribute(NS_LITERAL_STRING("alt"), mTitleString);
         if (mTitleString.IsEmpty()) {
           // this can be a relative link
           areaElem->GetAttribute(NS_LITERAL_STRING("href"), mTitleString);
         }
 
--- a/dom/base/nsContentList.cpp
+++ b/dom/base/nsContentList.cpp
@@ -541,17 +541,17 @@ nsContentList::GetSupportedNames(nsTArra
       nsAtom* id = content->GetID();
       MOZ_ASSERT(id != nsGkAtoms::_empty,
                  "Empty ids don't get atomized");
       if (!atoms.Contains(id)) {
         atoms.AppendElement(id);
       }
     }
 
-    nsGenericHTMLElement* el = nsGenericHTMLElement::FromContent(content);
+    nsGenericHTMLElement* el = nsGenericHTMLElement::FromNode(content);
     if (el) {
       // XXXbz should we be checking for particular tags here?  How
       // stable is this part of the spec?
       // Note: nsINode::HasName means the name is exposed on the document,
       // which is false for options, so we don't check it here.
       const nsAttrValue* val = el->GetParsedAttr(nsGkAtoms::name);
       if (val && val->Type() == nsAttrValue::eAtom) {
         nsAtom* name = val->GetAtomValue();
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -569,16 +569,23 @@ nsContentUtils::Init()
   }
 
   nsHTMLTags::AddRefTable();
 
   sNameSpaceManager = nsNameSpaceManager::GetInstance();
   NS_ENSURE_TRUE(sNameSpaceManager, NS_ERROR_OUT_OF_MEMORY);
 
   sXPConnect = nsXPConnect::XPConnect();
+  // We hold a strong ref to sXPConnect to ensure that it does not go away until
+  // nsLayoutStatics::Shutdown is happening.  Otherwise ~nsXPConnect can be
+  // triggered by xpcModuleDtor late in shutdown and cause crashes due to
+  // various stuff already being torn down by then.  Note that this means that
+  // we are effectively making sure that if we leak nsLayoutStatics then we also
+  // leak nsXPConnect.
+  NS_ADDREF(sXPConnect);
 
   sSecurityManager = nsScriptSecurityManager::GetScriptSecurityManager();
   if(!sSecurityManager)
     return NS_ERROR_FAILURE;
   NS_ADDREF(sSecurityManager);
 
   sSecurityManager->GetSystemPrincipal(&sSystemPrincipal);
   MOZ_ASSERT(sSystemPrincipal);
@@ -2087,17 +2094,17 @@ nsContentUtils::Shutdown()
   NS_IF_RELEASE(sContentPolicyService);
   sTriedToGetContentPolicy = false;
   uint32_t i;
   for (i = 0; i < PropertiesFile_COUNT; ++i)
     NS_IF_RELEASE(sStringBundles[i]);
 
   NS_IF_RELEASE(sStringBundleService);
   NS_IF_RELEASE(sConsoleService);
-  sXPConnect = nullptr;
+  NS_IF_RELEASE(sXPConnect);
   NS_IF_RELEASE(sSecurityManager);
   NS_IF_RELEASE(sSystemPrincipal);
   NS_IF_RELEASE(sNullSubjectPrincipal);
   NS_IF_RELEASE(sIOService);
   NS_IF_RELEASE(sUUIDGenerator);
   sLineBreaker = nullptr;
   sWordBreaker = nullptr;
   NS_IF_RELEASE(sBidiKeyboard);
@@ -3888,17 +3895,17 @@ nsContentUtils::GetStaticRequest(nsIDocu
 }
 
 // static
 bool
 nsContentUtils::ContentIsDraggable(nsIContent* aContent)
 {
   MOZ_ASSERT(aContent);
 
-  if (auto htmlElement = nsGenericHTMLElement::FromContent(aContent)) {
+  if (auto htmlElement = nsGenericHTMLElement::FromNode(aContent)) {
     if (htmlElement->Draggable()) {
       return true;
     }
 
     if (htmlElement->AttrValueIs(kNameSpaceID_None,
                                  nsGkAtoms::draggable,
                                  nsGkAtoms::_false,
                                  eIgnoreCase)) {
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -1,20 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/ArrayUtils.h"
 
-#ifdef XP_WIN
-#undef GetClassName
-#endif
-
 // JavaScript includes
 #include "jsapi.h"
 #include "jsfriendapi.h"
 #include "WrapperFactory.h"
 #include "AccessCheck.h"
 #include "XrayWrapper.h"
 
 #include "xpcpublic.h"
@@ -46,23 +42,19 @@
 #include "nsIDOMDocument.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMEventListener.h"
 #include "nsContentUtils.h"
 #include "nsIDOMGlobalPropertyInitializer.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/Telemetry.h"
 
-// Window scriptable helper includes
-#include "nsScriptNameSpaceManager.h"
-
 // DOM base includes
 #include "nsIDOMWindow.h"
 #include "nsPIDOMWindow.h"
-#include "nsIDOMConstructor.h"
 
 // DOM core includes
 #include "nsError.h"
 
 // Event related includes
 #include "nsIDOMEventTarget.h"
 
 // CSS related includes
@@ -85,1632 +77,45 @@
 
 #ifdef MOZ_TIME_MANAGER
 #include "TimeManager.h"
 #endif
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
-// NOTE: DEFAULT_SCRIPTABLE_FLAGS and DOM_DEFAULT_SCRIPTABLE_FLAGS
-//       are defined in nsIDOMClassInfo.h.
-
-#define DOMCLASSINFO_STANDARD_FLAGS                                           \
-  (nsIClassInfo::MAIN_THREAD_ONLY |                                           \
-   nsIClassInfo::DOM_OBJECT       |                                           \
-   nsIClassInfo::SINGLETON_CLASSINFO)
-
-
-#ifdef DEBUG
-#define NS_DEFINE_CLASSINFO_DATA_DEBUG(_class)                                \
-    eDOMClassInfo_##_class##_id,
-#else
-#define NS_DEFINE_CLASSINFO_DATA_DEBUG(_class)                                \
-  // nothing
-#endif
-
-#define NS_DEFINE_CLASSINFO_DATA_HELPER(_class, _helper, _flags,              \
-                                        _chromeOnly, _allowXBL)               \
-  { nullptr,                                                                  \
-    XPC_MAKE_CLASS_OPS(_flags),                                               \
-    XPC_MAKE_CLASS(#_class, _flags,                                           \
-                   &sClassInfoData[eDOMClassInfo_##_class##_id].mClassOps),   \
-    _helper::doCreate,                                                        \
-    nullptr,                                                                  \
-    nullptr,                                                                  \
-    nullptr,                                                                  \
-    _flags,                                                                   \
-    true,                                                                     \
-    _chromeOnly,                                                              \
-    _allowXBL,                                                                \
-    false,                                                                    \
-    NS_DEFINE_CLASSINFO_DATA_DEBUG(_class)                                    \
-  },
-
-#define NS_DEFINE_CLASSINFO_DATA(_class, _helper, _flags)                     \
-  NS_DEFINE_CLASSINFO_DATA_HELPER(_class, _helper, _flags, false, false)
-
-#define NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(_class, _helper, _flags)          \
-  NS_DEFINE_CLASSINFO_DATA_HELPER(_class, _helper, _flags, true, true)
-
-
-// This list of NS_DEFINE_CLASSINFO_DATA macros is what gives the DOM
-// classes their correct behavior when used through XPConnect. The
-// arguments that are passed to NS_DEFINE_CLASSINFO_DATA are
-//
-// 1. Class name as it should appear in JavaScript, this name is also
-//    used to find the id of the class in nsDOMClassInfo
-//    (i.e. e<classname>_id)
-// 2. Scriptable helper class
-// 3. nsIClassInfo/nsIXPCScriptable flags (i.e. for GetScriptableFlags)
-
-static nsDOMClassInfoData sClassInfoData[] = {
-  // Base classes
-
-  NS_DEFINE_CLASSINFO_DATA(DOMPrototype, nsDOMConstructorSH,
-                           DOM_BASE_SCRIPTABLE_FLAGS |
-                           XPC_SCRIPTABLE_WANT_PRECREATE |
-                           XPC_SCRIPTABLE_WANT_RESOLVE |
-                           XPC_SCRIPTABLE_WANT_HASINSTANCE |
-                           XPC_SCRIPTABLE_DONT_ENUM_QUERY_INTERFACE)
-  NS_DEFINE_CLASSINFO_DATA(DOMConstructor, nsDOMConstructorSH,
-                           DOM_BASE_SCRIPTABLE_FLAGS |
-                           XPC_SCRIPTABLE_WANT_PRECREATE |
-                           XPC_SCRIPTABLE_WANT_RESOLVE |
-                           XPC_SCRIPTABLE_WANT_HASINSTANCE |
-                           XPC_SCRIPTABLE_WANT_CALL |
-                           XPC_SCRIPTABLE_WANT_CONSTRUCT |
-                           XPC_SCRIPTABLE_DONT_ENUM_QUERY_INTERFACE)
-
-  // Misc Core related classes
-
-};
-
-nsIXPConnect *nsDOMClassInfo::sXPConnect = nullptr;
 bool nsDOMClassInfo::sIsInitialized = false;
 
-
-jsid nsDOMClassInfo::sConstructor_id     = JSID_VOID;
-jsid nsDOMClassInfo::sWrappedJSObject_id = JSID_VOID;
-
-static const JSClass *sObjectClass = nullptr;
-
-/**
- * Set our JSClass pointer for the Object class
- */
-static void
-FindObjectClass(JSContext* cx, JSObject* aGlobalObject)
-{
-  NS_ASSERTION(!sObjectClass,
-               "Double set of sObjectClass");
-  JS::Rooted<JSObject*> obj(cx), proto(cx, aGlobalObject);
-  do {
-    obj = proto;
-    js::GetObjectProto(cx, obj, &proto);
-  } while (proto);
-
-  sObjectClass = js::GetObjectJSClass(obj);
-}
-
-// Helper to handle torn-down inner windows.
-static inline nsresult
-SetParentToWindow(nsGlobalWindowInner *win, JSObject **parent)
-{
-  MOZ_ASSERT(win);
-  *parent = win->FastGetGlobalJSObject();
-
-  if (MOZ_UNLIKELY(!*parent)) {
-    // The inner window has been torn down. The scope is dying, so don't create
-    // any new wrappers.
-    return NS_ERROR_FAILURE;
-  }
-  return NS_OK;
-}
-
-nsresult
-nsDOMClassInfo::DefineStaticJSVals()
-{
-  AutoJSAPI jsapi;
-  if (!jsapi.Init(xpc::UnprivilegedJunkScope())) {
-    return NS_ERROR_UNEXPECTED;
-  }
-  JSContext* cx = jsapi.cx();
-
-#define SET_JSID_TO_STRING(_id, _cx, _str)                              \
-  if (JSString *str = ::JS_AtomizeAndPinString(_cx, _str))                             \
-      _id = INTERNED_STRING_TO_JSID(_cx, str);                                \
-  else                                                                        \
-      return NS_ERROR_OUT_OF_MEMORY;
-
-  SET_JSID_TO_STRING(sConstructor_id,     cx, "constructor");
-  SET_JSID_TO_STRING(sWrappedJSObject_id, cx, "wrappedJSObject");
-
-  return NS_OK;
-}
-
 // static
-bool
-nsDOMClassInfo::ObjectIsNativeWrapper(JSContext* cx, JSObject* obj)
-{
-  return xpc::WrapperFactory::IsXrayWrapper(obj) &&
-         xpc::AccessCheck::wrapperSubsumes(obj);
-}
-
-nsDOMClassInfo::nsDOMClassInfo(nsDOMClassInfoData* aData) : mData(aData)
-{
-}
-
-NS_IMPL_ADDREF(nsDOMClassInfo)
-NS_IMPL_RELEASE(nsDOMClassInfo)
-
-NS_INTERFACE_MAP_BEGIN(nsDOMClassInfo)
-  if (aIID.Equals(NS_GET_IID(nsXPCClassInfo)))
-    foundInterface = static_cast<nsIClassInfo*>(
-                                    static_cast<nsXPCClassInfo*>(this));
-  else
-  NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
-  NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIClassInfo)
-NS_INTERFACE_MAP_END
-
-
-static const JSClass sDOMConstructorProtoClass = {
-  "DOM Constructor.prototype", 0
-};
-
-
-static const char *
-CutPrefix(const char *aName) {
-  static const char prefix_nsIDOM[] = "nsIDOM";
-  static const char prefix_nsI[]    = "nsI";
-
-  if (strncmp(aName, prefix_nsIDOM, sizeof(prefix_nsIDOM) - 1) == 0) {
-    return aName + sizeof(prefix_nsIDOM) - 1;
-  }
-
-  if (strncmp(aName, prefix_nsI, sizeof(prefix_nsI) - 1) == 0) {
-    return aName + sizeof(prefix_nsI) - 1;
-  }
-
-  return aName;
-}
-
-// static
-nsresult
-nsDOMClassInfo::RegisterClassProtos(int32_t aClassInfoID)
-{
-  nsScriptNameSpaceManager *nameSpaceManager = GetNameSpaceManager();
-  NS_ENSURE_TRUE(nameSpaceManager, NS_ERROR_NOT_INITIALIZED);
-  bool found_old;
-
-  const nsIID *primary_iid = sClassInfoData[aClassInfoID].mProtoChainInterface;
-
-  if (!primary_iid || primary_iid == &NS_GET_IID(nsISupports)) {
-    return NS_OK;
-  }
-
-  nsCOMPtr<nsIInterfaceInfoManager>
-    iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID));
-  NS_ENSURE_TRUE(iim, NS_ERROR_NOT_AVAILABLE);
-
-  nsCOMPtr<nsIInterfaceInfo> if_info;
-  bool first = true;
-
-  iim->GetInfoForIID(primary_iid, getter_AddRefs(if_info));
-
-  while (if_info) {
-    const nsIID *iid = nullptr;
-
-    if_info->GetIIDShared(&iid);
-    NS_ENSURE_TRUE(iid, NS_ERROR_UNEXPECTED);
-
-    if (iid->Equals(NS_GET_IID(nsISupports))) {
-      break;
-    }
-
-    const char *name = nullptr;
-    if_info->GetNameShared(&name);
-    NS_ENSURE_TRUE(name, NS_ERROR_UNEXPECTED);
-
-    nameSpaceManager->RegisterClassProto(CutPrefix(name), iid, &found_old);
-
-    if (first) {
-      first = false;
-    } else if (found_old) {
-      break;
-    }
-
-    nsCOMPtr<nsIInterfaceInfo> tmp(if_info);
-    tmp->GetParent(getter_AddRefs(if_info));
-  }
-
-  return NS_OK;
-}
-
-#define _DOM_CLASSINFO_MAP_BEGIN(_class, _ifptr, _has_class_if)               \
-  {                                                                           \
-    nsDOMClassInfoData &d = sClassInfoData[eDOMClassInfo_##_class##_id];      \
-    d.mProtoChainInterface = _ifptr;                                          \
-    d.mHasClassInterface = _has_class_if;                                     \
-    static const nsIID *interface_list[] = {
-
-#define DOM_CLASSINFO_MAP_BEGIN(_class, _interface)                           \
-  _DOM_CLASSINFO_MAP_BEGIN(_class, &NS_GET_IID(_interface), true)
-
-#define DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(_class, _interface)               \
-  _DOM_CLASSINFO_MAP_BEGIN(_class, &NS_GET_IID(_interface), false)
-
-#define DOM_CLASSINFO_MAP_ENTRY(_if)                                          \
-      &NS_GET_IID(_if),
-
-#define DOM_CLASSINFO_MAP_CONDITIONAL_ENTRY(_if, _cond)                       \
-      (_cond) ? &NS_GET_IID(_if) : nullptr,
-
-#define DOM_CLASSINFO_MAP_END                                                 \
-      nullptr                                                                  \
-    };                                                                        \
-                                                                              \
-    /* Compact the interface list */                                          \
-    size_t count = ArrayLength(interface_list);                               \
-    /* count is the number of array entries, which is one greater than the */ \
-    /* number of interfaces due to the terminating null */                    \
-    for (size_t i = 0; i < count - 1; ++i) {                                  \
-      if (!interface_list[i]) {                                               \
-        /* We are moving the element at index i+1 and successors, */          \
-        /* so we must move only count - (i+1) elements total. */              \
-        memmove(&interface_list[i], &interface_list[i+1],                     \
-                sizeof(nsIID*) * (count - (i+1)));                            \
-        /* Make sure to examine the new pointer we ended up with at this */   \
-        /* slot, since it may be null too */                                  \
-        --i;                                                                  \
-        --count;                                                              \
-      }                                                                       \
-    }                                                                         \
-                                                                              \
-    d.mInterfaces = interface_list;                                           \
-  }
-
 nsresult
 nsDOMClassInfo::Init()
 {
   /* Errors that can trigger early returns are done first,
      otherwise nsDOMClassInfo is left in a half inited state. */
   static_assert(sizeof(uintptr_t) == sizeof(void*),
                 "BAD! You'll need to adjust the size of uintptr_t to the "
                 "size of a pointer on your platform.");
 
   NS_ENSURE_TRUE(!sIsInitialized, NS_ERROR_ALREADY_INITIALIZED);
 
-  nsScriptNameSpaceManager *nameSpaceManager = GetNameSpaceManager();
-  NS_ENSURE_TRUE(nameSpaceManager, NS_ERROR_NOT_INITIALIZED);
-
-  NS_ADDREF(sXPConnect = nsContentUtils::XPConnect());
-
   nsCOMPtr<nsIXPCFunctionThisTranslator> elt = new nsEventListenerThisTranslator();
-  sXPConnect->SetFunctionThisTranslator(NS_GET_IID(nsIDOMEventListener), elt);
-
-  DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(DOMPrototype, nsIDOMDOMConstructor)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMDOMConstructor)
-  DOM_CLASSINFO_MAP_END
-
-  DOM_CLASSINFO_MAP_BEGIN(DOMConstructor, nsIDOMDOMConstructor)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMDOMConstructor)
-  DOM_CLASSINFO_MAP_END
-
-  static_assert(MOZ_ARRAY_LENGTH(sClassInfoData) == eDOMClassInfoIDCount,
-                "The number of items in sClassInfoData doesn't match the "
-                "number of nsIDOMClassInfo ID's, this is bad! Fix it!");
-
-#ifdef DEBUG
-  for (size_t i = 0; i < eDOMClassInfoIDCount; i++) {
-    if (!sClassInfoData[i].mConstructorFptr ||
-        sClassInfoData[i].mDebugID != i) {
-      MOZ_CRASH("Class info data out of sync, you forgot to update "
-                "nsDOMClassInfo.h and nsDOMClassInfo.cpp! Fix this, "
-                "mozilla will not work without this fixed!");
-    }
-  }
-
-  for (size_t i = 0; i < eDOMClassInfoIDCount; i++) {
-    if (!sClassInfoData[i].mInterfaces) {
-      MOZ_CRASH("Class info data without an interface list! Fix this, "
-                "mozilla will not work without this fixed!");
-     }
-   }
-#endif
-
-  // Initialize static JSString's
-  DefineStaticJSVals();
-
-  int32_t i;
-
-  for (i = 0; i < eDOMClassInfoIDCount; ++i) {
-    if (i == eDOMClassInfo_DOMPrototype_id) {
-      continue;
-    }
-
-    nsDOMClassInfoData& data = sClassInfoData[i];
-    nameSpaceManager->RegisterClassName(data.mClass.name, i, data.mChromeOnly,
-                                        data.mAllowXBL, &data.mNameUTF16);
-  }
-
-  for (i = 0; i < eDOMClassInfoIDCount; ++i) {
-    RegisterClassProtos(i);
-  }
+  nsContentUtils::XPConnect()->SetFunctionThisTranslator(NS_GET_IID(nsIDOMEventListener), elt);
 
   sIsInitialized = true;
 
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsDOMClassInfo::GetInterfaces(uint32_t *aCount, nsIID ***aArray)
-{
-  uint32_t count = 0;
-
-  while (mData->mInterfaces[count]) {
-    count++;
-  }
-
-  *aCount = count;
-
-  if (!count) {
-    *aArray = nullptr;
-
-    return NS_OK;
-  }
-
-  *aArray = static_cast<nsIID **>(moz_xmalloc(count * sizeof(nsIID *)));
-
-  uint32_t i;
-  for (i = 0; i < count; i++) {
-    *((*aArray) + i) = mData->mInterfaces[i]->Clone();
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMClassInfo::GetScriptableHelper(nsIXPCScriptable **_retval)
-{
-  nsCOMPtr<nsIXPCScriptable> rval = this;
-  rval.forget(_retval);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMClassInfo::GetContractID(nsACString& aContractID)
-{
-  aContractID.SetIsVoid(true);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMClassInfo::GetClassDescription(nsACString& aClassDescription)
-{
-  return GetClassName(aClassDescription);
-}
-
-NS_IMETHODIMP
-nsDOMClassInfo::GetClassID(nsCID **aClassID)
-{
-  *aClassID = nullptr;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMClassInfo::GetClassIDNoAlloc(nsCID *aClassID)
-{
-  return NS_ERROR_NOT_AVAILABLE;
-}
-
-NS_IMETHODIMP
-nsDOMClassInfo::GetFlags(uint32_t *aFlags)
-{
-  *aFlags = DOMCLASSINFO_STANDARD_FLAGS;
-
-  return NS_OK;
-}
-
-// nsIXPCScriptable
-
-NS_IMETHODIMP
-nsDOMClassInfo::GetClassName(nsACString& aClassName)
-{
-  aClassName.Assign(mData->mClass.name);
-  return NS_OK;
-}
-
-// virtual
-uint32_t
-nsDOMClassInfo::GetScriptableFlags()
-{
-  return mData->mScriptableFlags;
-}
-
-// virtual
-const js::Class*
-nsDOMClassInfo::GetClass()
-{
-    return &mData->mClass;
-}
-
-// virtual
-const JSClass*
-nsDOMClassInfo::GetJSClass()
-{
-    return Jsvalify(&mData->mClass);
-}
-
-NS_IMETHODIMP
-nsDOMClassInfo::PreCreate(nsISupports *nativeObj, JSContext *cx,
-                          JSObject *globalObj, JSObject **parentObj)
-{
-  *parentObj = globalObj;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMClassInfo::Enumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                          JSObject *obj, bool *_retval)
-{
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMClassInfo::NewEnumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                             JSObject *obj, JS::AutoIdVector &properties,
-                             bool *_retval)
-{
-  NS_WARNING("nsDOMClassInfo::NewEnumerate Don't call me!");
-
-  return NS_ERROR_UNEXPECTED;
-}
-
-NS_IMETHODIMP
-nsDOMClassInfo::Resolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                        JSObject *aObj, jsid aId, bool *resolvedp, bool *_retval)
-{
-  JS::Rooted<JSObject*> obj(cx, aObj);
-  JS::Rooted<jsid> id(cx, aId);
-
-  if (id != sConstructor_id) {
-    *resolvedp = false;
-    return NS_OK;
-  }
-
-  JS::Rooted<JSObject*> global(cx, ::JS_GetGlobalForObject(cx, obj));
-
-  JS::Rooted<JS::PropertyDescriptor> desc(cx);
-  if (!JS_GetPropertyDescriptor(cx, global, mData->mClass.name, &desc)) {
-    return NS_ERROR_UNEXPECTED;
-  }
-
-  if (desc.object() && !desc.hasGetterOrSetter() && desc.value().isObject()) {
-    // If val is not an (non-null) object there either is no
-    // constructor for this class, or someone messed with
-    // window.classname, just fall through and let the JS engine
-    // return the Object constructor.
-    if (!::JS_DefinePropertyById(cx, obj, id, desc.value(),
-                                 JSPROP_ENUMERATE)) {
-      return NS_ERROR_UNEXPECTED;
-    }
-
-    *resolvedp = true;
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMClassInfo::Finalize(nsIXPConnectWrappedNative *wrapper, JSFreeOp *fop,
-                         JSObject *obj)
-{
-  NS_WARNING("nsDOMClassInfo::Finalize Don't call me!");
-
-  return NS_ERROR_UNEXPECTED;
-}
-
-NS_IMETHODIMP
-nsDOMClassInfo::Call(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                     JSObject *obj, const JS::CallArgs &args, bool *_retval)
-{
-  NS_WARNING("nsDOMClassInfo::Call Don't call me!");
-
-  return NS_ERROR_UNEXPECTED;
-}
-
-NS_IMETHODIMP
-nsDOMClassInfo::Construct(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                          JSObject *obj, const JS::CallArgs &args,
-                          bool *_retval)
-{
-  NS_WARNING("nsDOMClassInfo::Construct Don't call me!");
-
-  return NS_ERROR_UNEXPECTED;
-}
-
-NS_IMETHODIMP
-nsDOMClassInfo::HasInstance(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                            JSObject *obj, JS::Handle<JS::Value> val, bool *bp,
-                            bool *_retval)
-{
-  NS_WARNING("nsDOMClassInfo::HasInstance Don't call me!");
-
-  return NS_ERROR_UNEXPECTED;
-}
-
-static nsresult
-ResolvePrototype(nsIXPConnect *aXPConnect, nsGlobalWindowInner *aWin, JSContext *cx,
-                 JS::Handle<JSObject*> obj, const char16_t *name,
-                 const nsDOMClassInfoData *ci_data,
-                 const nsGlobalNameStruct *name_struct,
-                 nsScriptNameSpaceManager *nameSpaceManager,
-                 JSObject *dot_prototype,
-                 JS::MutableHandle<JS::PropertyDescriptor> ctorDesc);
-
-NS_IMETHODIMP
-nsDOMClassInfo::PostCreatePrototype(JSContext * cx, JSObject * aProto)
-{
-  JS::Rooted<JSObject*> proto(cx, aProto);
-
-  // This is called before any other location that requires
-  // sObjectClass, so compute it here. We assume that nobody has had a
-  // chance to monkey around with proto's prototype chain before this.
-  if (!sObjectClass) {
-    FindObjectClass(cx, proto);
-    NS_ASSERTION(sObjectClass && !strcmp(sObjectClass->name, "Object"),
-                 "Incorrect object class!");
-  }
-
-#ifdef DEBUG
-    JS::Rooted<JSObject*> proto2(cx);
-    JS_GetPrototype(cx, proto, &proto2);
-    NS_ASSERTION(proto2 && JS_GetClass(proto2) == sObjectClass,
-                 "Hmm, somebody did something evil?");
-#endif
-
-#ifdef DEBUG
-  if (mData->mHasClassInterface && mData->mProtoChainInterface &&
-      mData->mProtoChainInterface != &NS_GET_IID(nsISupports)) {
-    nsCOMPtr<nsIInterfaceInfoManager>
-      iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID));
-
-    if (iim) {
-      nsCOMPtr<nsIInterfaceInfo> if_info;
-      iim->GetInfoForIID(mData->mProtoChainInterface,
-                         getter_AddRefs(if_info));
-
-      if (if_info) {
-        nsCString name;
-        if_info->GetName(getter_Copies(name));
-        NS_ASSERTION(nsCRT::strcmp(CutPrefix(name.get()), mData->mClass.name) == 0,
-                     "Class name and proto chain interface name mismatch!");
-      }
-    }
-  }
-#endif
-
-  // Make prototype delegation work correctly. Consider if a site sets
-  // HTMLElement.prototype.foopy = function () { ... } Now, calling
-  // document.body.foopy() needs to ensure that looking up foopy on
-  // document.body's prototype will find the right function.
-  JS::Rooted<JSObject*> global(cx, ::JS_GetGlobalForObject(cx, proto));
-
-  // Only do this if the global object is a window.
-  nsGlobalWindowInner* win;
-  if (NS_FAILED(UNWRAP_OBJECT(Window, &global, win))) {
-    // Not a window.
-    return NS_OK;
-  }
-
-  if (win->IsClosedOrClosing()) {
-    return NS_OK;
-  }
-
-  // Don't overwrite a property set by content.
-  bool contentDefinedProperty;
-  if (!::JS_AlreadyHasOwnUCProperty(cx, global, reinterpret_cast<const char16_t*>(mData->mNameUTF16),
-                                    NS_strlen(mData->mNameUTF16),
-                                    &contentDefinedProperty)) {
-    return NS_ERROR_FAILURE;
-  }
-
-  nsScriptNameSpaceManager *nameSpaceManager = GetNameSpaceManager();
-  NS_ENSURE_TRUE(nameSpaceManager, NS_OK);
-
-  JS::Rooted<JS::PropertyDescriptor> desc(cx);
-  nsresult rv = ResolvePrototype(sXPConnect, win, cx, global,
-                                 mData->mNameUTF16, mData, nullptr,
-                                 nameSpaceManager, proto, &desc);
-  NS_ENSURE_SUCCESS(rv, rv);
-  if (!contentDefinedProperty && desc.object() && !desc.value().isUndefined()) {
-    desc.attributesRef() |= JSPROP_RESOLVING;
-    if (!JS_DefineUCProperty(cx, global, mData->mNameUTF16,
-                             NS_strlen(mData->mNameUTF16), desc)) {
-      return NS_ERROR_UNEXPECTED;
-    }
-  }
-
-  return NS_OK;
-}
-
-// static
-nsIClassInfo *
-NS_GetDOMClassInfoInstance(nsDOMClassInfoID aID)
-{
-  if (aID >= eDOMClassInfoIDCount) {
-    NS_ERROR("Bad ID!");
-
-    return nullptr;
-  }
-
-  nsresult rv = RegisterDOMNames();
-  NS_ENSURE_SUCCESS(rv, nullptr);
-
-  if (!sClassInfoData[aID].mCachedClassInfo) {
-    nsDOMClassInfoData& data = sClassInfoData[aID];
-
-    data.mCachedClassInfo = data.mConstructorFptr(&data);
-    NS_ENSURE_TRUE(data.mCachedClassInfo, nullptr);
-
-    NS_ADDREF(data.mCachedClassInfo);
-  }
-
-  return sClassInfoData[aID].mCachedClassInfo;
-}
-
 // static
 void
 nsDOMClassInfo::ShutDown()
 {
-  if (sClassInfoData[0].mConstructorFptr) {
-    uint32_t i;
-
-    for (i = 0; i < eDOMClassInfoIDCount; i++) {
-      NS_IF_RELEASE(sClassInfoData[i].mCachedClassInfo);
-    }
-  }
-
-  sConstructor_id     = JSID_VOID;
-  sWrappedJSObject_id = JSID_VOID;
-
-  NS_IF_RELEASE(sXPConnect);
   sIsInitialized = false;
 }
 
-static nsresult
-BaseStubConstructor(nsIWeakReference* aWeakOwner,
-                    const nsGlobalNameStruct *name_struct, JSContext *cx,
-                    JS::Handle<JSObject*> obj, const JS::CallArgs &args)
-{
-  MOZ_ASSERT(obj);
-  MOZ_ASSERT(cx == nsContentUtils::GetCurrentJSContext());
-
-  nsresult rv;
-  nsCOMPtr<nsISupports> native;
-  if (name_struct->mType == nsGlobalNameStruct::eTypeClassConstructor) {
-    rv = NS_ERROR_NOT_AVAILABLE;
-  } else {
-    MOZ_ASSERT(name_struct->mType ==
-               nsGlobalNameStruct::eTypeExternalConstructor);
-    native = do_CreateInstance(name_struct->mCID, &rv);
-  }
-  if (NS_FAILED(rv)) {
-    NS_ERROR("Failed to create the object");
-    return rv;
-  }
-
-  js::AssertSameCompartment(cx, obj);
-  return nsContentUtils::WrapNative(cx, native, args.rval(), true);
-}
-
-static nsresult
-DefineInterfaceConstants(JSContext *cx, JS::Handle<JSObject*> obj, const nsIID *aIID)
-{
-  nsCOMPtr<nsIInterfaceInfoManager>
-    iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID));
-  NS_ENSURE_TRUE(iim, NS_ERROR_UNEXPECTED);
-
-  nsCOMPtr<nsIInterfaceInfo> if_info;
-
-  nsresult rv = iim->GetInfoForIID(aIID, getter_AddRefs(if_info));
-  NS_ENSURE_TRUE(NS_SUCCEEDED(rv) && if_info, rv);
-
-  uint16_t constant_count;
-
-  if_info->GetConstantCount(&constant_count);
-
-  if (!constant_count) {
-    return NS_OK;
-  }
-
-  nsCOMPtr<nsIInterfaceInfo> parent_if_info;
-
-  rv = if_info->GetParent(getter_AddRefs(parent_if_info));
-  NS_ENSURE_TRUE(NS_SUCCEEDED(rv) && parent_if_info, rv);
-
-  uint16_t parent_constant_count, i;
-  parent_if_info->GetConstantCount(&parent_constant_count);
-
-  JS::Rooted<JS::Value> v(cx);
-  for (i = parent_constant_count; i < constant_count; i++) {
-    nsCString name;
-    rv = if_info->GetConstant(i, &v, getter_Copies(name));
-    NS_ENSURE_TRUE(NS_SUCCEEDED(rv), rv);
-
-    if (!::JS_DefineProperty(cx, obj, name.get(), v,
-                             JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT)) {
-      return NS_ERROR_UNEXPECTED;
-    }
-  }
-
-  return NS_OK;
-}
-
-class nsDOMConstructor final : public nsIDOMDOMConstructor
-{
-protected:
-  nsDOMConstructor(const char16_t* aName,
-                   bool aIsConstructable,
-                   nsPIDOMWindowInner* aOwner)
-    : mClassName(aName),
-      mConstructable(aIsConstructable),
-      mWeakOwner(do_GetWeakReference(aOwner))
-  {
-  }
-
-  ~nsDOMConstructor() {}
-
-public:
-
-  static nsresult Create(const char16_t* aName,
-                         const nsGlobalNameStruct* aNameStruct,
-                         nsPIDOMWindowInner* aOwner,
-                         nsDOMConstructor** aResult);
-
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSIDOMDOMCONSTRUCTOR
-
-  nsresult PreCreate(JSContext *cx, JSObject *globalObj, JSObject **parentObj);
-
-  nsresult Construct(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                     JS::Handle<JSObject*> obj, const JS::CallArgs &args,
-                     bool *_retval);
-
-  nsresult HasInstance(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                       JS::Handle<JSObject*> obj, const JS::Value &val, bool *bp,
-                       bool *_retval);
-
-  nsresult ResolveInterfaceConstants(JSContext *cx, JS::Handle<JSObject*> obj);
-
-private:
-  const nsGlobalNameStruct *GetNameStruct()
-  {
-    if (!mClassName) {
-      NS_ERROR("Can't get name");
-      return nullptr;
-    }
-
-    const nsGlobalNameStruct *nameStruct;
-#ifdef DEBUG
-    nsresult rv =
-#endif
-      GetNameStruct(nsDependentString(mClassName), &nameStruct);
-
-    NS_ASSERTION(NS_FAILED(rv) || nameStruct, "Name isn't in hash.");
-
-    return nameStruct;
-  }
-
-  static nsresult GetNameStruct(const nsAString& aName,
-                                const nsGlobalNameStruct **aNameStruct)
-  {
-    *aNameStruct = nullptr;
-
-    nsScriptNameSpaceManager *nameSpaceManager = GetNameSpaceManager();
-    if (!nameSpaceManager) {
-      NS_ERROR("Can't get namespace manager.");
-      return NS_ERROR_UNEXPECTED;
-    }
-
-    *aNameStruct = nameSpaceManager->LookupName(aName);
-
-    // Return NS_OK here, aName just isn't a DOM class but nothing failed.
-    return NS_OK;
-  }
-
-  static bool IsConstructable(const nsGlobalNameStruct *aNameStruct)
-  {
-    return aNameStruct->mType == nsGlobalNameStruct::eTypeExternalConstructor;
-  }
-
-  const char16_t*   mClassName;
-  const bool mConstructable;
-  nsWeakPtr          mWeakOwner;
-};
-
-//static
-nsresult
-nsDOMConstructor::Create(const char16_t* aName,
-                         const nsGlobalNameStruct* aNameStruct,
-                         nsPIDOMWindowInner* aOwner,
-                         nsDOMConstructor** aResult)
-{
-  *aResult = nullptr;
-  // Prevent creating a constructor if aOwner is inner window which doesn't have
-  // an outer window. If the outer window doesn't have an inner window or the
-  // caller can't access the outer window's current inner window then try to use
-  // the owner (so long as it is, in fact, an inner window). If that doesn't
-  // work then prevent creation also.
-  nsPIDOMWindowOuter* outerWindow = aOwner->GetOuterWindow();
-  nsPIDOMWindowInner* currentInner =
-    outerWindow ? outerWindow->GetCurrentInnerWindow() : aOwner;
-  if (!currentInner) {
-    return NS_ERROR_DOM_SECURITY_ERR;
-  }
-  if (aOwner != currentInner &&
-      !nsContentUtils::CanCallerAccess(currentInner)) {
-    currentInner = aOwner;
-  }
-
-  bool constructable = aNameStruct && IsConstructable(aNameStruct);
-
-  *aResult = new nsDOMConstructor(aName, constructable, currentInner);
-  NS_ADDREF(*aResult);
-  return NS_OK;
-}
-
-NS_IMPL_ADDREF(nsDOMConstructor)
-NS_IMPL_RELEASE(nsDOMConstructor)
-NS_INTERFACE_MAP_BEGIN(nsDOMConstructor)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMDOMConstructor)
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-  if (aIID.Equals(NS_GET_IID(nsIClassInfo))) {
-#ifdef DEBUG
-    {
-      const nsGlobalNameStruct *name_struct = GetNameStruct();
-      NS_ASSERTION(!name_struct ||
-                   mConstructable == IsConstructable(name_struct),
-                   "Can't change constructability dynamically!");
-    }
-#endif
-    foundInterface =
-      NS_GetDOMClassInfoInstance(mConstructable ?
-                                 eDOMClassInfo_DOMConstructor_id :
-                                 eDOMClassInfo_DOMPrototype_id);
-    if (!foundInterface) {
-      *aInstancePtr = nullptr;
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
-  } else
-NS_INTERFACE_MAP_END
-
-nsresult
-nsDOMConstructor::PreCreate(JSContext *cx, JSObject *globalObj, JSObject **parentObj)
-{
-  nsCOMPtr<nsPIDOMWindowInner> owner(do_QueryReferent(mWeakOwner));
-  if (!owner) {
-    // Can't do anything.
-    return NS_OK;
-  }
-
-  nsGlobalWindowInner *win = nsGlobalWindowInner::Cast(owner);
-  return SetParentToWindow(win, parentObj);
-}
-
-nsresult
-nsDOMConstructor::Construct(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
-                            JS::Handle<JSObject*> obj, const JS::CallArgs &args,
-                            bool *_retval)
-{
-  MOZ_ASSERT(obj);
-
-  const nsGlobalNameStruct *name_struct = GetNameStruct();
-  NS_ENSURE_TRUE(name_struct, NS_ERROR_FAILURE);
-
-  if (!IsConstructable(name_struct)) {
-    // ignore return value, we return false anyway
-    return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
-  }
-
-  return BaseStubConstructor(mWeakOwner, name_struct, cx, obj, args);
-}
-
-nsresult
-nsDOMConstructor::HasInstance(nsIXPConnectWrappedNative *wrapper,
-                              JSContext * cx, JS::Handle<JSObject*> obj,
-                              const JS::Value &v, bool *bp, bool *_retval)
-
-{
-  // No need to look these up in the hash.
-  *bp = false;
-  if (v.isPrimitive()) {
-    return NS_OK;
-  }
-
-  JS::Rooted<JSObject*> dom_obj(cx, v.toObjectOrNull());
-  NS_ASSERTION(dom_obj, "nsDOMConstructor::HasInstance couldn't get object");
-
-  // This might not be the right object, if there are wrappers. Unwrap if we can.
-  JSObject *wrapped_obj = js::CheckedUnwrap(dom_obj, /* stopAtWindowProxy = */ false);
-  if (wrapped_obj)
-      dom_obj = wrapped_obj;
-
-  const JSClass *dom_class = JS_GetClass(dom_obj);
-  if (!dom_class) {
-    NS_ERROR("nsDOMConstructor::HasInstance can't get class.");
-    return NS_ERROR_UNEXPECTED;
-  }
-
-  const nsGlobalNameStruct *name_struct;
-  nsresult rv = GetNameStruct(NS_ConvertASCIItoUTF16(dom_class->name), &name_struct);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  if (!name_struct) {
-    // This isn't a normal DOM object, see if this constructor lives on its
-    // prototype chain.
-    JS::Rooted<JS::PropertyDescriptor> desc(cx);
-    if (!JS_GetPropertyDescriptor(cx, obj, "prototype", &desc)) {
-      return NS_ERROR_UNEXPECTED;
-    }
-
-    if (!desc.object() || desc.hasGetterOrSetter() || !desc.value().isObject()) {
-      return NS_OK;
-    }
-
-    JS::Rooted<JSObject*> dot_prototype(cx, &desc.value().toObject());
-
-    JS::Rooted<JSObject*> proto(cx, dom_obj);
-    JSAutoCompartment ac(cx, proto);
-
-    if (!JS_WrapObject(cx, &dot_prototype)) {
-      return NS_ERROR_UNEXPECTED;
-    }
-
-    for (;;) {
-      if (!JS_GetPrototype(cx, proto, &proto)) {
-        return NS_ERROR_UNEXPECTED;
-      }
-      if (!proto) {
-        break;
-      }
-      if (proto == dot_prototype) {
-        *bp = true;
-        break;
-      }
-    }
-
-    return NS_OK;
-  }
-
-  if (name_struct->mType != nsGlobalNameStruct::eTypeClassConstructor) {
-    // Doesn't have DOM interfaces.
-    return NS_OK;
-  }
-
-  const nsGlobalNameStruct *class_name_struct = GetNameStruct();
-  NS_ENSURE_TRUE(class_name_struct, NS_ERROR_FAILURE);
-
-  if (name_struct == class_name_struct) {
-    *bp = true;
-
-    return NS_OK;
-  }
-
-  const nsIID *class_iid;
-  if (class_name_struct->mType == nsGlobalNameStruct::eTypeClassProto) {
-    class_iid = &class_name_struct->mIID;
-  } else if (class_name_struct->mType == nsGlobalNameStruct::eTypeClassConstructor) {
-    class_iid =
-      sClassInfoData[class_name_struct->mDOMClassInfoID].mProtoChainInterface;
-  } else {
-    *bp = false;
-
-    return NS_OK;
-  }
-
-  NS_ASSERTION(name_struct->mType == nsGlobalNameStruct::eTypeClassConstructor,
-               "The constructor was set up with a struct of the wrong type.");
-
-  const nsDOMClassInfoData *ci_data;
-  if (name_struct->mType == nsGlobalNameStruct::eTypeClassConstructor &&
-      name_struct->mDOMClassInfoID >= 0) {
-    ci_data = &sClassInfoData[name_struct->mDOMClassInfoID];
-  } else {
-    ci_data = nullptr;
-  }
-
-  nsCOMPtr<nsIInterfaceInfoManager>
-    iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID));
-  if (!iim) {
-    NS_ERROR("nsDOMConstructor::HasInstance can't get interface info mgr.");
-    return NS_ERROR_UNEXPECTED;
-  }
-
-  nsCOMPtr<nsIInterfaceInfo> if_info;
-  uint32_t count = 0;
-  const nsIID* class_interface;
-  while ((class_interface = ci_data->mInterfaces[count++])) {
-    if (class_iid->Equals(*class_interface)) {
-      *bp = true;
-
-      return NS_OK;
-    }
-
-    iim->GetInfoForIID(class_interface, getter_AddRefs(if_info));
-    if (!if_info) {
-      NS_ERROR("nsDOMConstructor::HasInstance can't get interface info.");
-      return NS_ERROR_UNEXPECTED;
-    }
-
-    if_info->HasAncestor(class_iid, bp);
-
-    if (*bp) {
-      return NS_OK;
-    }
-  }
-
-  return NS_OK;
-}
-
-nsresult
-nsDOMConstructor::ResolveInterfaceConstants(JSContext *cx, JS::Handle<JSObject*> obj)
-{
-  const nsGlobalNameStruct *class_name_struct = GetNameStruct();
-  if (!class_name_struct)
-    return NS_ERROR_UNEXPECTED;
-
-  const nsIID *class_iid;
-  if (class_name_struct->mType == nsGlobalNameStruct::eTypeClassProto) {
-    class_iid = &class_name_struct->mIID;
-  } else if (class_name_struct->mType == nsGlobalNameStruct::eTypeClassConstructor) {
-    class_iid =
-      sClassInfoData[class_name_struct->mDOMClassInfoID].mProtoChainInterface;
-  } else {
-    return NS_OK;
-  }
-
-  nsresult rv = DefineInterfaceConstants(cx, obj, class_iid);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMConstructor::ToString(nsAString &aResult)
-{
-  aResult.AssignLiteral("[object ");
-  aResult.Append(mClassName);
-  aResult.Append(char16_t(']'));
-
-  return NS_OK;
-}
-
-
-static nsresult
-GetXPCProto(nsIXPConnect *aXPConnect, JSContext *cx, nsGlobalWindowInner *aWin,
-            const nsGlobalNameStruct *aNameStruct,
-            JS::MutableHandle<JSObject*> aProto)
-{
-  NS_ASSERTION(aNameStruct->mType == nsGlobalNameStruct::eTypeClassConstructor,
-               "Wrong type!");
-
-  int32_t id = aNameStruct->mDOMClassInfoID;
-  MOZ_ASSERT(id >= 0, "Negative DOM classinfo?!?");
-
-  nsDOMClassInfoID ci_id = (nsDOMClassInfoID)id;
-
-  nsCOMPtr<nsIClassInfo> ci = NS_GetDOMClassInfoInstance(ci_id);
-  NS_ENSURE_TRUE(ci, NS_ERROR_UNEXPECTED);
-
-  nsresult rv =
-    aXPConnect->GetWrappedNativePrototype(cx, aWin->GetGlobalJSObject(), ci, aProto.address());
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  return JS_WrapObject(cx, aProto) ? NS_OK : NS_ERROR_FAILURE;
-}
-
-// Either ci_data must be non-null or name_struct must be non-null and of type
-// eTypeClassProto.
-static nsresult
-ResolvePrototype(nsIXPConnect *aXPConnect, nsGlobalWindowInner *aWin, JSContext *cx,
-                 JS::Handle<JSObject*> obj, const char16_t *name,
-                 const nsDOMClassInfoData *ci_data,
-                 const nsGlobalNameStruct *name_struct,
-                 nsScriptNameSpaceManager *nameSpaceManager,
-                 JSObject* aDot_prototype,
-                 JS::MutableHandle<JS::PropertyDescriptor> ctorDesc)
-{
-  JS::Rooted<JSObject*> dot_prototype(cx, aDot_prototype);
-  NS_ASSERTION(ci_data ||
-               (name_struct &&
-                name_struct->mType == nsGlobalNameStruct::eTypeClassProto),
-               "Wrong type or missing ci_data!");
-
-  RefPtr<nsDOMConstructor> constructor;
-  nsresult rv = nsDOMConstructor::Create(name, name_struct, aWin->AsInner(),
-                                         getter_AddRefs(constructor));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  JS::Rooted<JS::Value> v(cx);
-
-  js::AssertSameCompartment(cx, obj);
-  rv = nsContentUtils::WrapNative(cx, constructor,
-                                  &NS_GET_IID(nsIDOMDOMConstructor), &v,
-                                  false);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  FillPropertyDescriptor(ctorDesc, obj, 0, v);
-  // And make sure we wrap the value into the right compartment.  Note that we
-  // do this with ctorDesc.value(), not with v, because we need v to be in the
-  // right compartment (that of the reflector of |constructor|) below.
-  if (!JS_WrapValue(cx, ctorDesc.value())) {
-    return NS_ERROR_UNEXPECTED;
-  }
-
-  JS::Rooted<JSObject*> class_obj(cx, &v.toObject());
-
-  const nsIID *primary_iid = &NS_GET_IID(nsISupports);
-
-  if (!ci_data) {
-    primary_iid = &name_struct->mIID;
-  }
-  else if (ci_data->mProtoChainInterface) {
-    primary_iid = ci_data->mProtoChainInterface;
-  }
-
-  nsCOMPtr<nsIInterfaceInfo> if_info;
-  nsCOMPtr<nsIInterfaceInfo> parent;
-  const char *class_parent_name = nullptr;
-
-  if (!primary_iid->Equals(NS_GET_IID(nsISupports))) {
-    JSAutoCompartment ac(cx, class_obj);
-
-    rv = DefineInterfaceConstants(cx, class_obj, primary_iid);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    nsCOMPtr<nsIInterfaceInfoManager>
-      iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID));
-    NS_ENSURE_TRUE(iim, NS_ERROR_NOT_AVAILABLE);
-
-    iim->GetInfoForIID(primary_iid, getter_AddRefs(if_info));
-    NS_ENSURE_TRUE(if_info, NS_ERROR_UNEXPECTED);
-
-    const nsIID *iid = nullptr;
-
-    if (ci_data && !ci_data->mHasClassInterface) {
-      if_info->GetIIDShared(&iid);
-    } else {
-      if_info->GetParent(getter_AddRefs(parent));
-      NS_ENSURE_TRUE(parent, NS_ERROR_UNEXPECTED);
-
-      parent->GetIIDShared(&iid);
-    }
-
-    if (iid) {
-      if (!iid->Equals(NS_GET_IID(nsISupports))) {
-        if (ci_data && !ci_data->mHasClassInterface) {
-          // If the class doesn't have a class interface the primary
-          // interface is the interface that should be
-          // constructor.prototype.__proto__.
-
-          if_info->GetNameShared(&class_parent_name);
-        } else {
-          // If the class does have a class interface (or there's no
-          // real class for this name) then the parent of the
-          // primary interface is what we want on
-          // constructor.prototype.__proto__.
-
-          NS_ASSERTION(parent, "Whoa, this is bad, null parent here!");
-
-          parent->GetNameShared(&class_parent_name);
-        }
-      }
-    }
-  }
-
-  {
-    JS::Rooted<JSObject*> winobj(cx, aWin->FastGetGlobalJSObject());
-
-    JS::Rooted<JSObject*> proto(cx);
-
-    if (class_parent_name) {
-      JSAutoCompartment ac(cx, winobj);
-
-      JS::Rooted<JS::PropertyDescriptor> desc(cx);
-      if (!JS_GetPropertyDescriptor(cx, winobj, CutPrefix(class_parent_name), &desc)) {
-        return NS_ERROR_UNEXPECTED;
-      }
-
-      if (desc.object() && !desc.hasGetterOrSetter() && desc.value().isObject()) {
-        JS::Rooted<JSObject*> obj(cx, &desc.value().toObject());
-        if (!JS_GetPropertyDescriptor(cx, obj, "prototype", &desc)) {
-          return NS_ERROR_UNEXPECTED;
-        }
-
-        if (desc.object() && !desc.hasGetterOrSetter() && desc.value().isObject()) {
-          proto = &desc.value().toObject();
-        }
-      }
-    }
-
-    if (dot_prototype) {
-      JSAutoCompartment ac(cx, dot_prototype);
-      JS::Rooted<JSObject*> xpc_proto_proto(cx);
-      if (!::JS_GetPrototype(cx, dot_prototype, &xpc_proto_proto)) {
-        return NS_ERROR_UNEXPECTED;
-      }
-
-      if (proto &&
-          (!xpc_proto_proto ||
-           JS_GetClass(xpc_proto_proto) == sObjectClass)) {
-        if (!JS_WrapObject(cx, &proto) ||
-            !JS_SetPrototype(cx, dot_prototype, proto)) {
-          return NS_ERROR_UNEXPECTED;
-        }
-      }
-    } else {
-      JSAutoCompartment ac(cx, winobj);
-      if (!proto) {
-        proto = JS_GetObjectPrototype(cx, winobj);
-      }
-      dot_prototype = ::JS_NewObjectWithUniqueType(cx,
-                                                   &sDOMConstructorProtoClass,
-                                                   proto);
-      NS_ENSURE_TRUE(dot_prototype, NS_ERROR_OUT_OF_MEMORY);
-    }
-  }
-
-  v.setObject(*dot_prototype);
-
-  JSAutoCompartment ac(cx, class_obj);
-
-  // Per ECMA, the prototype property is {DontEnum, DontDelete, ReadOnly}
-  if (!JS_WrapValue(cx, &v) ||
-      !JS_DefineProperty(cx, class_obj, "prototype", v,
-                         JSPROP_PERMANENT | JSPROP_READONLY)) {
-    return NS_ERROR_UNEXPECTED;
-  }
-
-  return NS_OK;
-}
-
-static bool
-OldBindingConstructorEnabled(const nsGlobalNameStruct *aStruct,
-                             nsGlobalWindowInner *aWin, JSContext *cx)
-{
-  MOZ_ASSERT(aStruct->mType == nsGlobalNameStruct::eTypeProperty ||
-             aStruct->mType == nsGlobalNameStruct::eTypeClassConstructor);
-
-  // Don't expose chrome only constructors to content windows.
-  if (aStruct->mChromeOnly) {
-    bool expose;
-    if (aStruct->mAllowXBL) {
-      expose = IsChromeOrXBL(cx, nullptr);
-    } else {
-      expose = nsContentUtils::IsSystemPrincipal(aWin->GetPrincipal());
-    }
-
-    if (!expose) {
-      return false;
-    }
-  }
-
-  return true;
-}
-
-static nsresult
-LookupComponentsShim(JSContext *cx, JS::Handle<JSObject*> global,
-                     nsPIDOMWindowInner *win,
-                     JS::MutableHandle<JS::PropertyDescriptor> desc);
-
-// static
-bool
-nsWindowSH::NameStructEnabled(JSContext* aCx, nsGlobalWindowInner *aWin,
-                              const nsAString& aName,
-                              const nsGlobalNameStruct& aNameStruct)
-{
-  // DOMConstructor is special: creating its proto does not actually define it
-  // as a property on the global.  So we don't want to expose its name either.
-  if (aName.EqualsLiteral("DOMConstructor")) {
-    return false;
-  }
-  const nsGlobalNameStruct* nameStruct = &aNameStruct;
-  return (nameStruct->mType != nsGlobalNameStruct::eTypeProperty &&
-          nameStruct->mType != nsGlobalNameStruct::eTypeClassConstructor) ||
-         OldBindingConstructorEnabled(nameStruct, aWin, aCx);
-}
-
-#ifdef RELEASE_OR_BETA
-#define USE_CONTROLLERS_SHIM
-#endif
-
-#ifdef USE_CONTROLLERS_SHIM
-static const JSClass ControllersShimClass = {
-    "Controllers", 0
-};
-static const JSClass XULControllersShimClass = {
-    "XULControllers", 0
-};
-#endif
-
-// static
-nsresult
-nsWindowSH::GlobalResolve(nsGlobalWindowInner *aWin, JSContext *cx,
-                          JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
-                          JS::MutableHandle<JS::PropertyDescriptor> desc)
-{
-  if (id == XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_COMPONENTS)) {
-    return LookupComponentsShim(cx, obj, aWin->AsInner(), desc);
-  }
-
-#ifdef USE_CONTROLLERS_SHIM
-  // Note: We use |obj| rather than |aWin| to get the principal here, because
-  // this is called during Window setup when the Document isn't necessarily
-  // hooked up yet.
-  if ((id == XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_CONTROLLERS) ||
-       id == XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_CONTROLLERS_CLASS)) &&
-      !xpc::IsXrayWrapper(obj) &&
-      !nsContentUtils::IsSystemPrincipal(nsContentUtils::ObjectPrincipal(obj)))
-  {
-    if (aWin->GetDoc()) {
-      aWin->GetDoc()->WarnOnceAbout(nsIDocument::eWindow_Cc_ontrollers);
-    }
-    const JSClass* clazz;
-    if (id == XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_CONTROLLERS)) {
-      clazz = &XULControllersShimClass;
-    } else {
-      clazz = &ControllersShimClass;
-    }
-    MOZ_ASSERT(JS_IsGlobalObject(obj));
-    JS::Rooted<JSObject*> shim(cx, JS_NewObject(cx, clazz));
-    if (NS_WARN_IF(!shim)) {
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
-    FillPropertyDescriptor(desc, obj, JS::ObjectValue(*shim), /* readOnly = */ false);
-    return NS_OK;
-  }
-#endif
-
-  nsScriptNameSpaceManager *nameSpaceManager = GetNameSpaceManager();
-  NS_ENSURE_TRUE(nameSpaceManager, NS_ERROR_NOT_INITIALIZED);
-
-  // Note - Our only caller is nsGlobalWindow::DoResolve, which checks that
-  // JSID_IS_STRING(id) is true.
-  nsAutoJSString name;
-  if (!name.init(cx, JSID_TO_STRING(id))) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
-
-  const char16_t *class_name = nullptr;
-  const nsGlobalNameStruct *name_struct =
-    nameSpaceManager->LookupName(name, &class_name);
-
-  if (!name_struct) {
-    return NS_OK;
-  }
-
-  // The class_name had better match our name
-  MOZ_ASSERT(name.Equals(class_name));
-
-  NS_ENSURE_TRUE(class_name, NS_ERROR_UNEXPECTED);
-
-  nsresult rv = NS_OK;
-
-  if (name_struct->mType == nsGlobalNameStruct::eTypeClassConstructor) {
-    if (!OldBindingConstructorEnabled(name_struct, aWin, cx)) {
-      return NS_OK;
-    }
-
-    // Create the XPConnect prototype for our classinfo, PostCreateProto will
-    // set up the prototype chain.  This will go ahead and define things on the
-    // actual window's global.
-    JS::Rooted<JSObject*> dot_prototype(cx);
-    rv = GetXPCProto(nsDOMClassInfo::sXPConnect, cx, aWin, name_struct,
-                     &dot_prototype);
-    NS_ENSURE_SUCCESS(rv, rv);
-    MOZ_ASSERT(dot_prototype);
-
-    bool isXray = xpc::WrapperFactory::IsXrayWrapper(obj);
-    MOZ_ASSERT_IF(obj != aWin->GetGlobalJSObject(), isXray);
-    if (!isXray) {
-      // GetXPCProto already defined the property for us
-      FillPropertyDescriptor(desc, obj, JS::UndefinedValue(), false);
-      return NS_OK;
-    }
-
-    // This is the Xray case.  Look up the constructor object for this
-    // prototype.
-    return ResolvePrototype(nsDOMClassInfo::sXPConnect, aWin, cx, obj,
-                            class_name,
-                            &sClassInfoData[name_struct->mDOMClassInfoID],
-                            name_struct, nameSpaceManager, dot_prototype,
-                            desc);
-  }
-
-  if (name_struct->mType == nsGlobalNameStruct::eTypeClassProto) {
-    // We don't have a XPConnect prototype object, let ResolvePrototype create
-    // one.
-    return ResolvePrototype(nsDOMClassInfo::sXPConnect, aWin, cx, obj,
-                            class_name, nullptr,
-                            name_struct, nameSpaceManager, nullptr, desc);
-  }
-
-  if (name_struct->mType == nsGlobalNameStruct::eTypeExternalConstructor) {
-    RefPtr<nsDOMConstructor> constructor;
-    rv = nsDOMConstructor::Create(class_name, name_struct, aWin->AsInner(),
-                                  getter_AddRefs(constructor));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    JS::Rooted<JS::Value> val(cx);
-    js::AssertSameCompartment(cx, obj);
-    rv = nsContentUtils::WrapNative(cx, constructor,
-                                    &NS_GET_IID(nsIDOMDOMConstructor), &val,
-                                    true);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    NS_ASSERTION(val.isObject(), "Why didn't we get a JSObject?");
-
-    FillPropertyDescriptor(desc, obj, 0, val);
-
-    return NS_OK;
-  }
-
-  if (name_struct->mType == nsGlobalNameStruct::eTypeProperty) {
-    if (!OldBindingConstructorEnabled(name_struct, aWin, cx))
-      return NS_OK;
-
-    // Before defining a global property, check for a named subframe of the
-    // same name. If it exists, we don't want to shadow it.
-    if (nsCOMPtr<nsPIDOMWindowOuter> childWin = aWin->GetChildWindow(name)) {
-      return NS_OK;
-    }
-
-    nsCOMPtr<nsISupports> native(do_CreateInstance(name_struct->mCID, &rv));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    JS::Rooted<JS::Value> prop_val(cx, JS::UndefinedValue()); // Property value.
-
-    nsCOMPtr<nsIDOMGlobalPropertyInitializer> gpi(do_QueryInterface(native));
-    if (gpi) {
-      rv = gpi->Init(aWin->AsInner(), &prop_val);
-      NS_ENSURE_SUCCESS(rv, rv);
-    }
-
-    if (prop_val.isPrimitive() && !prop_val.isNull()) {
-      rv = nsContentUtils::WrapNative(cx, native, &prop_val, true);
-    }
-
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    if (!JS_WrapValue(cx, &prop_val)) {
-      return NS_ERROR_UNEXPECTED;
-    }
-
-    FillPropertyDescriptor(desc, obj, prop_val, false);
-
-    return NS_OK;
-  }
-
-  return rv;
-}
-
-struct InterfaceShimEntry {
-  const char *geckoName;
-  const char *domName;
-};
-
-// We add shims from Components.interfaces.nsIDOMFoo to window.Foo for each
-// interface that has interface constants that sites might be getting off
-// of Ci.
-const InterfaceShimEntry kInterfaceShimMap[] =
-{ { "nsIXMLHttpRequest", "XMLHttpRequest" },
-  { "nsIDOMDOMException", "DOMException" },
-  { "nsIDOMNode", "Node" },
-  { "nsIDOMCSSPrimitiveValue", "CSSPrimitiveValue" },
-  { "nsIDOMCSSRule", "CSSRule" },
-  { "nsIDOMCSSValue", "CSSValue" },
-  { "nsIDOMEvent", "Event" },
-  { "nsIDOMNSEvent", "Event" },
-  { "nsIDOMKeyEvent", "KeyEvent" },
-  { "nsIDOMMouseEvent", "MouseEvent" },
-  { "nsIDOMMouseScrollEvent", "MouseScrollEvent" },
-  { "nsIDOMMutationEvent", "MutationEvent" },
-  { "nsIDOMSimpleGestureEvent", "SimpleGestureEvent" },
-  { "nsIDOMUIEvent", "UIEvent" },
-  { "nsIDOMHTMLMediaElement", "HTMLMediaElement" },
-  { "nsIDOMOfflineResourceList", "OfflineResourceList" },
-  { "nsIDOMRange", "Range" },
-  { "nsIDOMSVGLength", "SVGLength" },
-  // Think about whether Ci.nsINodeFilter can just go away for websites!
-  { "nsIDOMNodeFilter", "NodeFilter" },
-  { "nsIDOMXPathResult", "XPathResult" } };
-
-static nsresult
-LookupComponentsShim(JSContext *cx, JS::Handle<JSObject*> global,
-                     nsPIDOMWindowInner *win,
-                     JS::MutableHandle<JS::PropertyDescriptor> desc)
-{
-  // Keep track of how often this happens.
-  Telemetry::Accumulate(Telemetry::COMPONENTS_SHIM_ACCESSED_BY_CONTENT, true);
-
-  // Warn once.
-  nsCOMPtr<nsIDocument> doc = win->GetExtantDoc();
-  if (doc) {
-    doc->WarnOnceAbout(nsIDocument::eComponents, /* asError = */ true);
-  }
-
-  // Create a fake Components object.
-  AssertSameCompartment(cx, global);
-  JS::Rooted<JSObject*> components(cx, JS_NewPlainObject(cx));
-  NS_ENSURE_TRUE(components, NS_ERROR_OUT_OF_MEMORY);
-
-  // Create a fake interfaces object.
-  JS::Rooted<JSObject*> interfaces(cx, JS_NewPlainObject(cx));
-  NS_ENSURE_TRUE(interfaces, NS_ERROR_OUT_OF_MEMORY);
-  bool ok =
-    JS_DefineProperty(cx, components, "interfaces", interfaces,
-                      JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY);
-  NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY);
-
-  // Define a bunch of shims from the Ci.nsIDOMFoo to window.Foo for DOM
-  // interfaces with constants.
-  for (uint32_t i = 0; i < ArrayLength(kInterfaceShimMap); ++i) {
-
-    // Grab the names from the table.
-    const char *geckoName = kInterfaceShimMap[i].geckoName;
-    const char *domName = kInterfaceShimMap[i].domName;
-
-    // Look up the appopriate interface object on the global.
-    JS::Rooted<JS::Value> v(cx, JS::UndefinedValue());
-    ok = JS_GetProperty(cx, global, domName, &v);
-    NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY);
-    if (!v.isObject()) {
-      NS_WARNING("Unable to find interface object on global");
-      continue;
-    }
-
-    // Define the shim on the interfaces object.
-    ok = JS_DefineProperty(cx, interfaces, geckoName, v,
-                           JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY);
-    NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY);
-  }
-
-  FillPropertyDescriptor(desc, global, JS::ObjectValue(*components), false);
-
-  return NS_OK;
-}
-
-// EventTarget helper
-
-NS_IMETHODIMP
-nsEventTargetSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
-                           JSObject *aGlobalObj, JSObject **parentObj)
-{
-  JS::Rooted<JSObject*> globalObj(cx, aGlobalObj);
-  DOMEventTargetHelper* target = DOMEventTargetHelper::FromSupports(nativeObj);
-
-  nsCOMPtr<nsIScriptGlobalObject> native_parent;
-  target->GetParentObject(getter_AddRefs(native_parent));
-
-  *parentObj = native_parent ? native_parent->GetGlobalJSObject() : globalObj;
-
-  return *parentObj ? NS_OK : NS_ERROR_FAILURE;
-}
-
-void
-nsEventTargetSH::PreserveWrapper(nsISupports *aNative)
-{
-  DOMEventTargetHelper* target = DOMEventTargetHelper::FromSupports(aNative);
-  target->PreserveWrapper(aNative);
-}
-
 // nsIDOMEventListener::HandleEvent() 'this' converter helper
 
 NS_INTERFACE_MAP_BEGIN(nsEventListenerThisTranslator)
   NS_INTERFACE_MAP_ENTRY(nsIXPCFunctionThisTranslator)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 
@@ -1724,125 +129,8 @@ nsEventListenerThisTranslator::Translate
 {
   nsCOMPtr<nsIDOMEvent> event(do_QueryInterface(aInitialThis));
   NS_ENSURE_TRUE(event, NS_ERROR_UNEXPECTED);
 
   nsCOMPtr<EventTarget> target = event->InternalDOMEvent()->GetCurrentTarget();
   target.forget(_retval);
   return NS_OK;
 }
-
-NS_IMETHODIMP
-nsDOMConstructorSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
-                              JSObject *aGlobalObj, JSObject **parentObj)
-{
-  JS::Rooted<JSObject*> globalObj(cx, aGlobalObj);
-  nsDOMConstructor *wrapped = static_cast<nsDOMConstructor *>(nativeObj);
-
-#ifdef DEBUG
-  {
-    nsCOMPtr<nsIDOMDOMConstructor> is_constructor =
-      do_QueryInterface(nativeObj);
-    NS_ASSERTION(is_constructor, "How did we not get a constructor?");
-  }
-#endif
-
-  return wrapped->PreCreate(cx, globalObj, parentObj);
-}
-
-NS_IMETHODIMP
-nsDOMConstructorSH::Resolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                            JSObject *aObj, jsid aId, bool *resolvedp,
-                            bool *_retval)
-{
-  JS::Rooted<JSObject*> obj(cx, aObj);
-  JS::Rooted<jsid> id(cx, aId);
-  // For regular DOM constructors, we have our interface constants defined on
-  // us by nsWindowSH::GlobalResolve. However, XrayWrappers can't see these
-  // interface constants (as they look like expando properties) so we have to
-  // specially resolve those constants here, but only for Xray wrappers.
-  if (!ObjectIsNativeWrapper(cx, obj)) {
-    return NS_OK;
-  }
-
-  JS::Rooted<JSObject*> nativePropsObj(cx, xpc::XrayUtils::GetNativePropertiesObject(cx, obj));
-  nsDOMConstructor *wrapped =
-    static_cast<nsDOMConstructor *>(wrapper->Native());
-  nsresult rv = wrapped->ResolveInterfaceConstants(cx, nativePropsObj);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // Now re-lookup the ID to see if we should report back that we resolved the
-  // looked-for constant. Note that we don't have to worry about infinitely
-  // recurring back here because the Xray wrapper's holder object doesn't call
-  // Resolve hooks.
-  bool found;
-  if (!JS_HasPropertyById(cx, nativePropsObj, id, &found)) {
-    *_retval = false;
-    return NS_OK;
-  }
-
-  if (found) {
-    *resolvedp = true;
-  }
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMConstructorSH::Call(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                         JSObject *aObj, const JS::CallArgs &args, bool *_retval)
-{
-  JS::Rooted<JSObject*> obj(cx, aObj);
-  MOZ_ASSERT(obj);
-
-  nsDOMConstructor *wrapped =
-    static_cast<nsDOMConstructor *>(wrapper->Native());
-
-#ifdef DEBUG
-  {
-    nsCOMPtr<nsIDOMDOMConstructor> is_constructor =
-      do_QueryWrappedNative(wrapper);
-    NS_ASSERTION(is_constructor, "How did we not get a constructor?");
-  }
-#endif
-
-  return wrapped->Construct(wrapper, cx, obj, args, _retval);
-}
-
-NS_IMETHODIMP
-nsDOMConstructorSH::Construct(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                              JSObject *aObj, const JS::CallArgs &args, bool *_retval)
-{
-  JS::Rooted<JSObject*> obj(cx, aObj);
-  MOZ_ASSERT(obj);
-
-  nsDOMConstructor *wrapped =
-    static_cast<nsDOMConstructor *>(wrapper->Native());
-
-#ifdef DEBUG
-  {
-    nsCOMPtr<nsIDOMDOMConstructor> is_constructor =
-      do_QueryWrappedNative(wrapper);
-    NS_ASSERTION(is_constructor, "How did we not get a constructor?");
-  }
-#endif
-
-  return wrapped->Construct(wrapper, cx, obj, args, _retval);
-}
-
-NS_IMETHODIMP
-nsDOMConstructorSH::HasInstance(nsIXPConnectWrappedNative *wrapper,
-                                JSContext *cx, JSObject *aObj, JS::Handle<JS::Value> val,
-                                bool *bp, bool *_retval)
-{
-  JS::Rooted<JSObject*> obj(cx, aObj);
-  nsDOMConstructor *wrapped =
-    static_cast<nsDOMConstructor *>(wrapper->Native());
-
-#ifdef DEBUG
-  {
-    nsCOMPtr<nsIDOMDOMConstructor> is_constructor =
-      do_QueryWrappedNative(wrapper);
-    NS_ASSERTION(is_constructor, "How did we not get a constructor?");
-  }
-#endif
-
-  return wrapped->HasInstance(wrapper, cx, obj, val, bp, _retval);
-}
--- a/dom/base/nsDOMClassInfo.h
+++ b/dom/base/nsDOMClassInfo.h
@@ -3,162 +3,32 @@
 /* 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 nsDOMClassInfo_h___
 #define nsDOMClassInfo_h___
 
 #include "mozilla/Attributes.h"
-#include "nsDOMClassInfoID.h"
 #include "nsIXPCScriptable.h"
 #include "nsIScriptGlobalObject.h"
 #include "js/Class.h"
 #include "js/Id.h"
 #include "nsIXPConnect.h"
 
-#ifdef XP_WIN
-#undef GetClassName
-#endif
-
-struct nsGlobalNameStruct;
-class nsGlobalWindowInner;
-class nsGlobalWindowOuter;
-
-struct nsDOMClassInfoData;
-
-typedef nsIClassInfo* (*nsDOMClassInfoConstructorFnc)
-  (nsDOMClassInfoData* aData);
-
-typedef nsresult (*nsDOMConstructorFunc)(nsISupports** aNewObject);
-
-struct nsDOMClassInfoData
+class nsDOMClassInfo
 {
-  // The ASCII name is available as mClass.name.
-  const char16_t *mNameUTF16;
-  const js::ClassOps mClassOps;
-  const js::Class mClass;
-  nsDOMClassInfoConstructorFnc mConstructorFptr;
-
-  nsIClassInfo *mCachedClassInfo;
-  const nsIID *mProtoChainInterface;
-  const nsIID **mInterfaces;
-  uint32_t mScriptableFlags : 31; // flags must not use more than 31 bits!
-  uint32_t mHasClassInterface : 1;
-  bool mChromeOnly : 1;
-  bool mAllowXBL : 1;
-  bool mDisabled : 1;
-#ifdef DEBUG
-  uint32_t mDebugID;
-#endif
-};
-
-class nsWindowSH;
-
-class nsDOMClassInfo : public nsXPCClassInfo
-{
-  friend class nsWindowSH;
-
-protected:
-  virtual ~nsDOMClassInfo() {};
-
 public:
-  explicit nsDOMClassInfo(nsDOMClassInfoData* aData);
-
-  NS_DECL_NSIXPCSCRIPTABLE
-
-  NS_DECL_ISUPPORTS
-
-  NS_DECL_NSICLASSINFO
-
   static nsresult Init();
   static void ShutDown();
 
-  static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
-  {
-    return new nsDOMClassInfo(aData);
-  }
-
-  /*
-   * The following two functions exist because of the way that Xray wrappers
-   * work. In order to allow scriptable helpers to define non-IDL defined but
-   * still "safe" properties for Xray wrappers, we call into the scriptable
-   * helper with |obj| being the wrapper.
-   *
-   * Ideally, that would be the end of the story, however due to complications
-   * dealing with document.domain, it's possible to end up in a scriptable
-   * helper with a wrapper, even though we should be treating the lookup as a
-   * transparent one.
-   *
-   * Note: So ObjectIsNativeWrapper(cx, obj) check usually means "through xray
-   * wrapper this part is not visible".
-   */
-  static bool ObjectIsNativeWrapper(JSContext* cx, JSObject* obj);
-
 protected:
-  friend nsIClassInfo* NS_GetDOMClassInfoInstance(nsDOMClassInfoID aID);
-
-  const nsDOMClassInfoData* mData;
-
-  virtual void PreserveWrapper(nsISupports *aNative) override
-  {
-  }
-
-  static nsresult RegisterClassProtos(int32_t aDOMClassInfoID);
-
-  static nsIXPConnect *sXPConnect;
-
-  // nsIXPCScriptable code
-  static nsresult DefineStaticJSVals();
-
   static bool sIsInitialized;
-
-public:
-  static jsid sConstructor_id;
-  static jsid sWrappedJSObject_id;
 };
 
-typedef nsDOMClassInfo nsDOMGenericSH;
-
-// Makes sure that the wrapper is preserved if new properties are added.
-class nsEventTargetSH : public nsDOMGenericSH
-{
-protected:
-  explicit nsEventTargetSH(nsDOMClassInfoData* aData) : nsDOMGenericSH(aData)
-  {
-  }
-
-  virtual ~nsEventTargetSH()
-  {
-  }
-public:
-  NS_IMETHOD PreCreate(nsISupports *nativeObj, JSContext *cx,
-                       JSObject *globalObj, JSObject **parentObj) override;
-
-  virtual void PreserveWrapper(nsISupports *aNative) override;
-};
-
-// A place to hang some static methods that we should really consider
-// moving to be nsGlobalWindow member methods.  See bug 1062418.
-class nsWindowSH
-{
-protected:
-  static nsresult GlobalResolve(nsGlobalWindowInner *aWin, JSContext *cx,
-                                JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
-                                JS::MutableHandle<JS::PropertyDescriptor> desc);
-
-  friend class nsGlobalWindowInner;
-  friend class nsGlobalWindowOuter;
-public:
-  static bool NameStructEnabled(JSContext* aCx, nsGlobalWindowInner *aWin,
-                                const nsAString& aName,
-                                const nsGlobalNameStruct& aNameStruct);
-};
-
-
 // Event handler 'this' translator class, this is called by XPConnect
 // when a "function interface" (nsIDOMEventListener) is called, this
 // class extracts 'this' fomr the first argument to the called
 // function (nsIDOMEventListener::HandleEvent(in nsIDOMEvent)), this
 // class will pass back nsIDOMEvent::currentTarget to be used as
 // 'this'.
 
 class nsEventListenerThisTranslator : public nsIXPCFunctionThisTranslator
@@ -174,42 +44,9 @@ public:
 
   // nsISupports
   NS_DECL_ISUPPORTS
 
   // nsIXPCFunctionThisTranslator
   NS_DECL_NSIXPCFUNCTIONTHISTRANSLATOR
 };
 
-class nsDOMConstructorSH : public nsDOMGenericSH
-{
-protected:
-  explicit nsDOMConstructorSH(nsDOMClassInfoData* aData) : nsDOMGenericSH(aData)
-  {
-  }
-
-public:
-  NS_IMETHOD PreCreate(nsISupports *nativeObj, JSContext *cx,
-                       JSObject *globalObj, JSObject **parentObj) override;
-  NS_IMETHOD PostCreatePrototype(JSContext * cx, JSObject * proto) override
-  {
-    return NS_OK;
-  }
-  NS_IMETHOD Resolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                     JSObject *obj, jsid id, bool *resolvedp,
-                     bool *_retval) override;
-  NS_IMETHOD Call(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                  JSObject *obj, const JS::CallArgs &args, bool *_retval) override;
-
-  NS_IMETHOD Construct(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                       JSObject *obj, const JS::CallArgs &args, bool *_retval) override;
-
-  NS_IMETHOD HasInstance(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                         JSObject *obj, JS::Handle<JS::Value> val, bool *bp,
-                         bool *_retval) override;
-
-  static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
-  {
-    return new nsDOMConstructorSH(aData);
-  }
-};
-
 #endif /* nsDOMClassInfo_h___ */
deleted file mode 100644
--- a/dom/base/nsDOMClassInfoID.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- * This file defines enum values for all of the DOM objects which have
- * an entry in nsDOMClassInfo.
- */
-
-#ifndef nsDOMClassInfoID_h__
-#define nsDOMClassInfoID_h__
-
-#include "nsIXPCScriptable.h"
-
-enum nsDOMClassInfoID
-{
-  eDOMClassInfo_DOMPrototype_id,
-  eDOMClassInfo_DOMConstructor_id,
-
-  // This one better be the last one in this list
-  eDOMClassInfoIDCount
-};
-
-/**
- * nsIClassInfo helper macros
- */
-
-#ifdef MOZILLA_INTERNAL_API
-
-class nsIClassInfo;
-class nsXPCClassInfo;
-
-extern nsIClassInfo*
-NS_GetDOMClassInfoInstance(nsDOMClassInfoID aID);
-
-#define NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(_class)                          \
-  if (aIID.Equals(NS_GET_IID(nsIClassInfo)) ||                                \
-      aIID.Equals(NS_GET_IID(nsXPCClassInfo))) {                              \
-    foundInterface = NS_GetDOMClassInfoInstance(eDOMClassInfo_##_class##_id); \
-    if (!foundInterface) {                                                    \
-      *aInstancePtr = nullptr;                                                 \
-      return NS_ERROR_OUT_OF_MEMORY;                                          \
-    }                                                                         \
-  } else
-
-#define NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_CONDITIONAL(_class, condition)   \
-  if ((condition) &&                                                          \
-      (aIID.Equals(NS_GET_IID(nsIClassInfo)) ||                               \
-       aIID.Equals(NS_GET_IID(nsXPCClassInfo)))) {                            \
-    foundInterface = NS_GetDOMClassInfoInstance(eDOMClassInfo_##_class##_id); \
-    if (!foundInterface) {                                                    \
-      *aInstancePtr = nullptr;                                                 \
-      return NS_ERROR_OUT_OF_MEMORY;                                          \
-    }                                                                         \
-  } else
-
-#endif // MOZILLA_INTERNAL_API
-
-#endif // nsDOMClassInfoID_h__
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -4,17 +4,16 @@
  * 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 "nsDOMWindowUtils.h"
 
 #include "mozilla/layers/CompositorBridgeChild.h"
 #include "mozilla/layers/LayerTransactionChild.h"
 #include "nsPresContext.h"
-#include "nsDOMClassInfoID.h"
 #include "nsError.h"
 #include "nsIDOMEvent.h"
 #include "nsQueryContentEventResult.h"
 #include "nsGlobalWindow.h"
 #include "nsIDocument.h"
 #include "nsFocusManager.h"
 #include "nsFrameManager.h"
 #include "nsRefreshDriver.h"
@@ -1475,18 +1474,18 @@ nsDOMWindowUtils::CompareCanvases(nsISup
 {
   if (aCanvas1 == nullptr ||
       aCanvas2 == nullptr ||
       retVal == nullptr)
     return NS_ERROR_FAILURE;
 
   nsCOMPtr<nsIContent> contentCanvas1 = do_QueryInterface(aCanvas1);
   nsCOMPtr<nsIContent> contentCanvas2 = do_QueryInterface(aCanvas2);
-  auto canvas1 = HTMLCanvasElement::FromContentOrNull(contentCanvas1);
-  auto canvas2 = HTMLCanvasElement::FromContentOrNull(contentCanvas2);
+  auto canvas1 = HTMLCanvasElement::FromNodeOrNull(contentCanvas1);
+  auto canvas2 = HTMLCanvasElement::FromNodeOrNull(contentCanvas2);
 
   if (!canvas1 || !canvas2) {
     return NS_ERROR_FAILURE;
   }
 
   RefPtr<DataSourceSurface> img1 = CanvasToDataSourceSurface(canvas1);
   RefPtr<DataSourceSurface> img2 = CanvasToDataSourceSurface(canvas2);
 
@@ -4162,17 +4161,17 @@ nsDOMWindowUtils::ForceUseCounterFlush(n
     // Flush the document and any external documents that it depends on.
     const auto reportKind
       = nsDocument::UseCounterReportKind::eIncludeExternalResources;
     static_cast<nsDocument*>(doc.get())->ReportUseCounters(reportKind);
     return NS_OK;
   }
 
   if (nsCOMPtr<nsIContent> content = do_QueryInterface(aNode)) {
-    if (HTMLImageElement* img = HTMLImageElement::FromContent(content)) {
+    if (HTMLImageElement* img = HTMLImageElement::FromNode(content)) {
       img->FlushUseCounters();
       return NS_OK;
     }
   }
 
   return NS_OK;
 }
 
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -4705,17 +4705,17 @@ nsIDocument::SetScopeObject(nsIGlobalObj
     }
   }
 }
 
 static void
 CheckIfContainsEMEContent(nsISupports* aSupports, void* aContainsEME)
 {
   nsCOMPtr<nsIContent> content(do_QueryInterface(aSupports));
-  if (auto mediaElem = HTMLMediaElement::FromContentOrNull(content)) {
+  if (auto mediaElem = HTMLMediaElement::FromNodeOrNull(content)) {
     bool* contains = static_cast<bool*>(aContainsEME);
     if (mediaElem->GetMediaKeys()) {
       *contains = true;
     }
   }
 }
 
 bool
@@ -4726,17 +4726,17 @@ nsIDocument::ContainsEMEContent()
                              static_cast<void*>(&containsEME));
   return containsEME;
 }
 
 static void
 CheckIfContainsMSEContent(nsISupports* aSupports, void* aContainsMSE)
 {
   nsCOMPtr<nsIContent> content(do_QueryInterface(aSupports));
-  if (auto mediaElem = HTMLMediaElement::FromContentOrNull(content)) {
+  if (auto mediaElem = HTMLMediaElement::FromNodeOrNull(content)) {
     bool* contains = static_cast<bool*>(aContainsMSE);
     RefPtr<MediaSource> ms = mediaElem->GetMozMediaSourceObject();
     if (ms) {
       *contains = true;
     }
   }
 }
 
@@ -4748,17 +4748,17 @@ nsIDocument::ContainsMSEContent()
                              static_cast<void*>(&containsMSE));
   return containsMSE;
 }
 
 static void
 NotifyActivityChanged(nsISupports *aSupports, void *aUnused)
 {
   nsCOMPtr<nsIContent> content(do_QueryInterface(aSupports));
-  if (auto mediaElem = HTMLMediaElement::FromContentOrNull(content)) {
+  if (auto mediaElem = HTMLMediaElement::FromNodeOrNull(content)) {
     mediaElem->NotifyOwnerDocumentActivityChanged();
   }
   nsCOMPtr<nsIObjectLoadingContent> objectLoadingContent(do_QueryInterface(aSupports));
   if (objectLoadingContent) {
     nsObjectLoadingContent* olc = static_cast<nsObjectLoadingContent*>(objectLoadingContent.get());
     olc->NotifyOwnerDocumentActivityChanged();
   }
   nsCOMPtr<nsIDocumentActivity> objectDocumentActivity(do_QueryInterface(aSupports));
@@ -8046,17 +8046,17 @@ nsIDocument::Sanitize()
   RefPtr<nsContentList> nodes = GetElementsByTagName(NS_LITERAL_STRING("input"));
 
   nsAutoString value;
 
   uint32_t length = nodes->Length(true);
   for (uint32_t i = 0; i < length; ++i) {
     NS_ASSERTION(nodes->Item(i), "null item in node list!");
 
-    RefPtr<HTMLInputElement> input = HTMLInputElement::FromContentOrNull(nodes->Item(i));
+    RefPtr<HTMLInputElement> input = HTMLInputElement::FromNodeOrNull(nodes->Item(i));
     if (!input)
       continue;
 
     bool resetValue = false;
 
     input->GetAttribute(NS_LITERAL_STRING("autocomplete"), value);
     if (value.LowerCaseEqualsLiteral("off")) {
       resetValue = true;
@@ -8073,17 +8073,17 @@ nsIDocument::Sanitize()
 
   // Now locate all _form_ elements that have autocomplete=off and reset them
   nodes = GetElementsByTagName(NS_LITERAL_STRING("form"));
 
   length = nodes->Length(true);
   for (uint32_t i = 0; i < length; ++i) {
     NS_ASSERTION(nodes->Item(i), "null item in nodelist");
 
-    HTMLFormElement* form = HTMLFormElement::FromContent(nodes->Item(i));
+    HTMLFormElement* form = HTMLFormElement::FromNode(nodes->Item(i));
     if (!form)
       continue;
 
     form->GetAttr(kNameSpaceID_None, nsGkAtoms::autocomplete, value);
     if (value.LowerCaseEqualsLiteral("off"))
       form->Reset();
   }
 }
@@ -10063,17 +10063,17 @@ nsIDocument::CaretPositionFromPoint(floa
 
   nsCOMPtr<nsIContent> node = offsets.content;
   uint32_t offset = offsets.offset;
   nsCOMPtr<nsIContent> anonNode = node;
   bool nodeIsAnonymous = node && node->IsInNativeAnonymousSubtree();
   if (nodeIsAnonymous) {
     node = ptFrame->GetContent();
     nsIContent* nonanon = node->FindFirstNonChromeOnlyAccessContent();
-    HTMLTextAreaElement* textArea = HTMLTextAreaElement::FromContent(nonanon);
+    HTMLTextAreaElement* textArea = HTMLTextAreaElement::FromNode(nonanon);
     nsITextControlFrame* textFrame = do_QueryFrame(nonanon->GetPrimaryFrame());
     nsNumberControlFrame* numberFrame = do_QueryFrame(nonanon->GetPrimaryFrame());
     if (textFrame || numberFrame) {
       // If the anonymous content node has a child, then we need to make sure
       // that we get the appropriate child, as otherwise the offset may not be
       // correct when we construct a range for it.
       nsCOMPtr<nsIContent> firstChild = anonNode->GetFirstChild();
       if (firstChild) {
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -146,31 +146,35 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ns
                                       mDocShell,
                                       mMessageManager,
                                       mChildMessageManager,
                                       mOpener)
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsFrameLoader)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsFrameLoader)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsFrameLoader)
-  NS_INTERFACE_MAP_ENTRY(nsIFrameLoader)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIFrameLoader)
+  if (aIID.Equals(NS_GET_IID(nsFrameLoader))) {
+      // We want to end up with a pointer that can then be reinterpret_cast
+      // from nsISupports* to nsFrameLoader* and end up with |this|.
+      foundInterface = reinterpret_cast<nsISupports*>(this);
+  } else
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebBrowserPersistable)
   NS_INTERFACE_MAP_ENTRY(nsIWebBrowserPersistable)
 NS_INTERFACE_MAP_END
 
 nsFrameLoader::nsFrameLoader(Element* aOwner, nsPIDOMWindowOuter* aOpener,
                              bool aNetworkCreated, int32_t aJSPluginID)
   : mOwnerContent(aOwner)
   , mDetachedSubdocFrame(nullptr)
   , mOpener(aOpener)
   , mRemoteBrowser(nullptr)
   , mChildID(0)
   , mJSPluginID(aJSPluginID)
-  , mEventMode(EVENT_MODE_NORMAL_DISPATCH)
+  , mEventMode(FrameLoaderBinding::EVENT_MODE_NORMAL_DISPATCH)
   , mBrowserChangingProcessBlockers(nullptr)
   , mDepthTooGreat(false)
   , mIsTopLevelContent(false)
   , mDestroyCalled(false)
   , mNeedsAsyncDestroy(false)
   , mInSwap(false)
   , mInShow(false)
   , mHideCalled(false)
@@ -226,28 +230,21 @@ nsFrameLoader::Create(Element* aOwner, n
                  ((!doc->IsLoadedAsData() && aOwner->IsInComposedDoc()) ||
                   doc->IsStaticDocument()),
                  nullptr);
 
   return new nsFrameLoader(aOwner, aOpener, aNetworkCreated, aJSPluginId);
 }
 
 void
-nsFrameLoader::LoadFrame(bool aOriginalSrc, ErrorResult& aRv)
-{
-  nsresult rv = LoadFrame(aOriginalSrc);
-  if (NS_FAILED(rv)) {
-    aRv.Throw(rv);
-  }
-}
-
-NS_IMETHODIMP
 nsFrameLoader::LoadFrame(bool aOriginalSrc)
 {
-  NS_ENSURE_TRUE(mOwnerContent, NS_ERROR_NOT_INITIALIZED);
+  if (NS_WARN_IF(!mOwnerContent)) {
+    return;
+  }
 
   nsAutoString src;
   nsCOMPtr<nsIPrincipal> principal;
 
   bool isSrcdoc = mOwnerContent->IsHTMLElement(nsGkAtoms::iframe) &&
                   mOwnerContent->HasAttr(kNameSpaceID_None, nsGkAtoms::srcdoc);
   if (isSrcdoc) {
     src.AssignLiteral("about:srcdoc");
@@ -259,30 +256,30 @@ nsFrameLoader::LoadFrame(bool aOriginalS
 
     if (src.IsEmpty()) {
       // If the frame is a XUL element and has the attribute 'nodefaultsrc=true'
       // then we will not use 'about:blank' as fallback but return early without
       // starting a load if no 'src' attribute is given (or it's empty).
       if (mOwnerContent->IsXULElement() &&
           mOwnerContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::nodefaultsrc,
                                      nsGkAtoms::_true, eCaseMatters)) {
-        return NS_OK;
+        return;
       }
       src.AssignLiteral("about:blank");
     }
   }
 
   nsIDocument* doc = mOwnerContent->OwnerDoc();
   if (doc->IsStaticDocument()) {
-    return NS_OK;
+    return;
   }
 
   if (doc->IsLoadedAsInteractiveData()) {
     // XBL bindings doc shouldn't load sub-documents.
-    return NS_OK;
+    return;
   }
 
   nsCOMPtr<nsIURI> base_uri = mOwnerContent->GetBaseURI();
   auto encoding = doc->GetDocumentCharacterSet();
 
   nsCOMPtr<nsIURI> uri;
   nsresult rv = NS_NewURI(getter_AddRefs(uri), src, encoding, base_uri);
 
@@ -293,46 +290,33 @@ nsFrameLoader::LoadFrame(bool aOriginalS
   }
 
   if (NS_SUCCEEDED(rv)) {
     rv = LoadURI(uri, principal, aOriginalSrc);
   }
 
   if (NS_FAILED(rv)) {
     FireErrorEvent();
-
-    return rv;
   }
-
-  return NS_OK;
 }
 
 void
 nsFrameLoader::FireErrorEvent()
 {
   if (!mOwnerContent) {
     return;
   }
   RefPtr<AsyncEventDispatcher > loadBlockingAsyncDispatcher =
     new LoadBlockingAsyncEventDispatcher(mOwnerContent,
                                          NS_LITERAL_STRING("error"),
                                          false, false);
   loadBlockingAsyncDispatcher->PostDOMEvent();
 }
 
-void
-nsFrameLoader::LoadURI(nsIURI* aURI, bool aOriginalSrc, ErrorResult& aRv)
-{
-  nsresult rv = LoadURI(aURI, aOriginalSrc);
-  if (NS_FAILED(rv)) {
-    aRv.Throw(rv);
-  }
-}
-
-NS_IMETHODIMP
+nsresult
 nsFrameLoader::LoadURI(nsIURI* aURI, bool aOriginalSrc)
 {
   return LoadURI(aURI, nullptr, aOriginalSrc);
 }
 
 nsresult
 nsFrameLoader::LoadURI(nsIURI* aURI, nsIPrincipal* aTriggeringPrincipal,
                        bool aOriginalSrc)
@@ -443,37 +427,16 @@ nsFrameLoader::AddProcessChangeBlockingP
 {
   if (NS_WARN_IF(!mBrowserChangingProcessBlockers)) {
     aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
   } else {
     mBrowserChangingProcessBlockers->AppendElement(&aPromise);
   }
 }
 
-NS_IMETHODIMP
-nsFrameLoader::AddProcessChangeBlockingPromise(js::Handle<js::Value> aPromise,
-                                               JSContext* aCx)
-{
-  nsCOMPtr<nsIGlobalObject> go = xpc::NativeGlobal(JS::CurrentGlobalOrNull(aCx));
-  if (!go) {
-    return NS_ERROR_FAILURE;
-  }
-  ErrorResult rv;
-  RefPtr<Promise> promise = Promise::Resolve(go, aCx, aPromise, rv);
-  if (NS_WARN_IF(rv.Failed())) {
-    return rv.StealNSResult();
-  }
-
-  AddProcessChangeBlockingPromise(*promise, rv);
-  if (NS_WARN_IF(rv.Failed())) {
-    return rv.StealNSResult();
-  }
-  return NS_OK;
-}
-
 nsresult
 nsFrameLoader::ReallyStartLoading()
 {
   nsresult rv = ReallyStartLoadingInternal();
   if (NS_FAILED(rv)) {
     FireErrorEvent();
   }
 
@@ -568,17 +531,17 @@ nsFrameLoader::ReallyStartLoadingInterna
     }
   }
 
   // get referrer policy for this iframe:
   // first load document wide policy, then
   // load iframe referrer attribute if enabled in preferences
   // per element referrer overrules document wide referrer if enabled
   net::ReferrerPolicy referrerPolicy = mOwnerContent->OwnerDoc()->GetReferrerPolicy();
-  HTMLIFrameElement* iframe = HTMLIFrameElement::FromContent(mOwnerContent);
+  HTMLIFrameElement* iframe = HTMLIFrameElement::FromNode(mOwnerContent);
   if (iframe) {
     net::ReferrerPolicy iframeReferrerPolicy = iframe->GetReferrerPolicyAsEnum();
     if (iframeReferrerPolicy != net::RP_Unset) {
       referrerPolicy = iframeReferrerPolicy;
     }
   }
   loadInfo->SetReferrerPolicy(referrerPolicy);
 
@@ -637,53 +600,37 @@ nsFrameLoader::CheckURILoad(nsIURI* aURI
 
   // Bail out if this is an infinite recursion scenario
   if (IsRemoteFrame()) {
     return NS_OK;
   }
   return CheckForRecursiveLoad(aURI);
 }
 
-already_AddRefed<nsIDocShell>
+nsIDocShell*
 nsFrameLoader::GetDocShell(ErrorResult& aRv)
 {
-  nsCOMPtr<nsIDocShell> docShell;
-  nsresult rv = GetDocShell(getter_AddRefs(docShell));
-  if (NS_FAILED(rv)) {
-    aRv.Throw(rv);
-  }
-  return docShell.forget();
-}
-
-NS_IMETHODIMP
-nsFrameLoader::GetDocShell(nsIDocShell **aDocShell)
-{
-  *aDocShell = nullptr;
-  nsresult rv = NS_OK;
-
   if (IsRemoteFrame()) {
-    return rv;
+    return nullptr;
   }
 
   // If we have an owner, make sure we have a docshell and return
   // that. If not, we're most likely in the middle of being torn down,
   // then we just return null.
   if (mOwnerContent) {
     nsresult rv = MaybeCreateDocShell();
     if (NS_FAILED(rv)) {
-      return rv;
+      aRv.Throw(rv);
+      return nullptr;
     }
     NS_ASSERTION(mDocShell,
                  "MaybeCreateDocShell succeeded, but null mDocShell");
   }
 
-  *aDocShell = mDocShell;
-  NS_IF_ADDREF(*aDocShell);
-
-  return rv;
+  return mDocShell;
 }
 
 static void
 SetTreeOwnerAndChromeEventHandlerOnDocshellTree(nsIDocShellTreeItem* aItem,
                                                 nsIDocShellTreeOwner* aOwner,
                                                 EventTarget* aHandler)
 {
   NS_PRECONDITION(aItem, "Must have item");
@@ -1017,17 +964,17 @@ nsFrameLoader::ShowRemoteFrame(const Scr
       return false;
     }
 
     mRemoteBrowser->Show(size, ParentWindowIsActive(mOwnerContent->OwnerDoc()));
     mRemoteBrowserShown = true;
 
     nsCOMPtr<nsIObserverService> os = services::GetObserverService();
     if (os) {
-      os->NotifyObservers(NS_ISUPPORTS_CAST(nsIFrameLoader*, this),
+      os->NotifyObservers(ToSupports(this),
                           "remote-browser-shown", nullptr);
     }
   } else {
     nsIntRect dimensions;
     NS_ENSURE_SUCCESS(GetWindowDimensions(dimensions), false);
 
     // Don't show remote iframe if we are waiting for the completion of reflow.
     if (!aFrame || !(aFrame->GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
@@ -1234,17 +1181,17 @@ nsFrameLoader::SwapWithOtherRemoteLoader
   if (otherMessageManager) {
     otherMessageManager->SetCallback(this);
   }
   mMessageManager.swap(aOther->mMessageManager);
 
   // Perform the actual swap of the internal refptrs. We keep a strong reference
   // to ourselves to make sure we don't die while we overwrite our reference to
   // ourself.
-  nsCOMPtr<nsIFrameLoader> kungFuDeathGrip(this);
+  RefPtr<nsFrameLoader> kungFuDeathGrip(this);
   aThisOwner->InternalSetFrameLoader(aOther);
   aOtherOwner->InternalSetFrameLoader(kungFuDeathGrip);
 
   ourFrameFrame->EndSwapDocShells(otherFrame);
 
   ourShell->BackingScaleFactorChanged();
   otherShell->BackingScaleFactorChanged();
 
@@ -1659,17 +1606,17 @@ nsFrameLoader::SwapWithOtherLoader(nsFra
   if (aOther->mMessageManager) {
     aOther->mMessageManager->SetCallback(this);
   }
   mMessageManager.swap(aOther->mMessageManager);
 
   // Perform the actual swap of the internal refptrs. We keep a strong reference
   // to ourselves to make sure we don't die while we overwrite our reference to
   // ourself.
-  nsCOMPtr<nsIFrameLoader> kungFuDeathGrip(this);
+  RefPtr<nsFrameLoader> kungFuDeathGrip(this);
   aThisOwner->InternalSetFrameLoader(aOther);
   aOtherOwner->InternalSetFrameLoader(kungFuDeathGrip);
 
   // Drop any cached content viewers in the two session histories.
   nsCOMPtr<nsISHistoryInternal> ourInternalHistory =
     do_QueryInterface(ourHistory);
   nsCOMPtr<nsISHistoryInternal> otherInternalHistory =
     do_QueryInterface(otherHistory);
@@ -1697,29 +1644,19 @@ nsFrameLoader::SwapWithOtherLoader(nsFra
   // Initialize browser API if needed now that owner content has changed
   InitializeBrowserAPI();
   aOther->InitializeBrowserAPI();
 
   return NS_OK;
 }
 
 void
-nsFrameLoader::Destroy(ErrorResult& aRv)
-{
-  nsresult rv = Destroy();
-  if (NS_FAILED(rv)) {
-    aRv.Throw(rv);
-  }
-}
-
-NS_IMETHODIMP
 nsFrameLoader::Destroy()
 {
   StartDestroy();
-  return NS_OK;
 }
 
 class nsFrameLoaderDestroyRunnable : public Runnable
 {
   enum DestroyPhase
   {
     // See the implementation of Run for an explanation of these phases.
     eDestroyDocShell,
@@ -1932,23 +1869,16 @@ nsFrameLoader::DestroyComplete()
   if (mChildMessageManager) {
     mChildMessageManager->Disconnect();
   }
 
   mMessageManager = nullptr;
   mChildMessageManager = nullptr;
 }
 
-NS_IMETHODIMP
-nsFrameLoader::GetDepthTooGreat(bool* aDepthTooGreat)
-{
-  *aDepthTooGreat = mDepthTooGreat;
-  return NS_OK;
-}
-
 void
 nsFrameLoader::SetOwnerContent(Element* aContent)
 {
   if (mObservingOwnerContent) {
     mObservingOwnerContent = false;
     mOwnerContent->RemoveMutationObserver(this);
   }
   mOwnerContent = aContent;
@@ -1971,24 +1901,16 @@ nsFrameLoader::SetOwnerContent(Element* 
 
 bool
 nsFrameLoader::OwnerIsMozBrowserFrame()
 {
   nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(mOwnerContent);
   return browserFrame ? browserFrame->GetReallyIsBrowser() : false;
 }
 
-// The xpcom getter version
-NS_IMETHODIMP
-nsFrameLoader::GetOwnerIsMozBrowserFrame(bool* aResult)
-{
-  *aResult = OwnerIsMozBrowserFrame();
-  return NS_OK;
-}
-
 bool
 nsFrameLoader::OwnerIsIsolatedMozBrowserFrame()
 {
   nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(mOwnerContent);
   if (!browserFrame) {
     return false;
   }
 
@@ -2084,18 +2006,18 @@ nsFrameLoader::MaybeCreateDocShell()
   }
 
   if (!doc->IsActive()) {
     // Don't allow subframe loads in non-active documents.
     // (See bug 610571 comment 5.)
     return NS_ERROR_NOT_AVAILABLE;
   }
 
-  nsCOMPtr<nsIDocShell> docShell = doc->GetDocShell();
-  nsCOMPtr<nsIWebNavigation> parentAsWebNav = do_QueryInterface(docShell);
+  nsCOMPtr<nsIDocShell> parentDocShell = doc->GetDocShell();
+  nsCOMPtr<nsIWebNavigation> parentAsWebNav = do_QueryInterface(parentDocShell);
   NS_ENSURE_STATE(parentAsWebNav);
 
   // Create the docshell...
   mDocShell = do_CreateInstance("@mozilla.org/docshell;1");
   NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
 
   if (!mNetworkCreated) {
     if (mDocShell) {
@@ -2122,25 +2044,26 @@ nsFrameLoader::MaybeCreateDocShell()
   if (!frameName.IsEmpty()) {
     mDocShell->SetName(frameName);
   }
 
   // Inform our docShell that it has a new child.
   // Note: This logic duplicates a lot of logic in
   // nsSubDocumentFrame::AttributeChanged.  We should fix that.
 
-  const int32_t parentType = docShell->ItemType();
+  const int32_t parentType = parentDocShell->ItemType();
 
   // XXXbz why is this in content code, exactly?  We should handle
   // this some other way.....  Not sure how yet.
   nsCOMPtr<nsIDocShellTreeOwner> parentTreeOwner;
-  docShell->GetTreeOwner(getter_AddRefs(parentTreeOwner));
+  parentDocShell->GetTreeOwner(getter_AddRefs(parentTreeOwner));
   NS_ENSURE_STATE(parentTreeOwner);
   mIsTopLevelContent =
-    AddTreeItemToTreeOwner(mDocShell, parentTreeOwner, parentType, docShell);
+    AddTreeItemToTreeOwner(mDocShell, parentTreeOwner, parentType,
+                           parentDocShell);
 
   if (mIsTopLevelContent) {
     mDocShell->SetCreatedDynamically(false);
   }
 
   // Make sure all shells have links back to the content element
   // in the nearest enclosing chrome shell.
   nsCOMPtr<nsIDOMEventTarget> chromeEventHandler;
@@ -2151,17 +2074,17 @@ nsFrameLoader::MaybeCreateDocShell()
 
     chromeEventHandler = do_QueryInterface(mOwnerContent);
     NS_ASSERTION(chromeEventHandler,
                  "This mContent should implement this.");
   } else {
     // Our parent shell is a content shell. Get the chrome event
     // handler from it and use that for our shell as well.
 
-    docShell->GetChromeEventHandler(getter_AddRefs(chromeEventHandler));
+    parentDocShell->GetChromeEventHandler(getter_AddRefs(chromeEventHandler));
   }
 
   mDocShell->SetChromeEventHandler(chromeEventHandler);
 
   // This is nasty, this code (the mDocShell->GetWindow() below)
   // *must* come *after* the above call to
   // mDocShell->SetChromeEventHandler() for the global window to get
   // the right chrome event handler.
@@ -2199,18 +2122,18 @@ nsFrameLoader::MaybeCreateDocShell()
       do_CreateInstance(NS_SHISTORY_CONTRACTID, &rv);
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(mDocShell));
     webNav->SetSessionHistory(sessionHistory);
   }
 
   OriginAttributes attrs;
-  if (docShell->ItemType() == mDocShell->ItemType()) {
-    attrs = nsDocShell::Cast(docShell)->GetOriginAttributes();
+  if (parentDocShell->ItemType() == mDocShell->ItemType()) {
+    attrs = nsDocShell::Cast(parentDocShell)->GetOriginAttributes();
   }
 
   // Inherit origin attributes from parent document if
   // 1. It's in a content docshell.
   // 2. its nodePrincipal is not a SystemPrincipal.
   // 3. It's not a mozbrowser frame.
   //
   // For example, firstPartyDomain is computed from top-level document, it
@@ -2243,43 +2166,43 @@ nsFrameLoader::MaybeCreateDocShell()
     mDocShell->SetFrameType(nsIDocShell::FRAME_TYPE_BROWSER);
   }
 
   // Apply sandbox flags even if our owner is not an iframe, as this copies
   // flags from our owning content's owning document.
   // Note: ApplySandboxFlags should be called after mDocShell->SetFrameType
   // because we need to get the correct presentation URL in ApplySandboxFlags.
   uint32_t sandboxFlags = 0;
-  HTMLIFrameElement* iframe = HTMLIFrameElement::FromContent(mOwnerContent);
+  HTMLIFrameElement* iframe = HTMLIFrameElement::FromNode(mOwnerContent);
   if (iframe) {
     sandboxFlags = iframe->GetSandboxFlags();
   }
   ApplySandboxFlags(sandboxFlags);
 
   // Grab the userContextId from owner if XUL
   nsresult rv = PopulateUserContextIdFromAttribute(attrs);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   bool isPrivate = false;
-  nsCOMPtr<nsILoadContext> parentContext = do_QueryInterface(docShell);
+  nsCOMPtr<nsILoadContext> parentContext = do_QueryInterface(parentDocShell);
   NS_ENSURE_STATE(parentContext);
 
   rv = parentContext->GetUsePrivateBrowsing(&isPrivate);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   attrs.SyncAttributesWithPrivateBrowsing(isPrivate);
 
   if (OwnerIsMozBrowserFrame()) {
     // For inproc frames, set the docshell properties.
     nsAutoString name;
     if (mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::name, name)) {
-      docShell->SetName(name);
+      mDocShell->SetName(name);
     }
     mDocShell->SetFullscreenAllowed(
       mOwnerContent->HasAttr(kNameSpaceID_None, nsGkAtoms::allowfullscreen) ||
       mOwnerContent->HasAttr(kNameSpaceID_None, nsGkAtoms::mozallowfullscreen));
     bool isPrivate = mOwnerContent->HasAttr(kNameSpaceID_None, nsGkAtoms::mozprivatebrowsing);
     if (isPrivate) {
       if (mDocShell->GetHasLoadedNonBlankURI()) {
         nsContentUtils::ReportToConsoleNonLocalized(
@@ -2319,17 +2242,17 @@ nsFrameLoader::MaybeCreateDocShell()
     nsDocShell::Cast(mDocShell)->SetAncestorOuterWindowIDs(Move(ancestorOuterWindowIDs));
   }
 
   ReallyLoadFrameScripts();
   InitializeBrowserAPI();
 
   nsCOMPtr<nsIObserverService> os = services::GetObserverService();
   if (os) {
-    os->NotifyObservers(NS_ISUPPORTS_CAST(nsIFrameLoader*, this),
+    os->NotifyObservers(ToSupports(this),
                         "inprocess-browser-shown", nullptr);
   }
 
   return NS_OK;
 }
 
 void
 nsFrameLoader::GetURL(nsString& aURI, nsIPrincipal** aTriggeringPrincipal)
@@ -2473,17 +2396,17 @@ nsFrameLoader::GetWindowDimensions(nsInt
   }
 
   nsCOMPtr<nsIBaseWindow> treeOwnerAsWin(do_GetInterface(parentOwner));
   treeOwnerAsWin->GetPosition(&aRect.x, &aRect.y);
   treeOwnerAsWin->GetSize(&aRect.width, &aRect.height);
   return NS_OK;
 }
 
-NS_IMETHODIMP
+nsresult
 nsFrameLoader::UpdatePositionAndSize(nsSubDocumentFrame *aIFrame)
 {
   if (IsRemoteFrame()) {
     if (mRemoteBrowser) {
       ScreenIntSize size = aIFrame->GetSubdocumentSize();
       // If we were not able to show remote frame before, we should probably
       // retry now to send correct showInfo.
       if (!mRemoteBrowserShown) {
@@ -2498,19 +2421,18 @@ nsFrameLoader::UpdatePositionAndSize(nsS
   }
   UpdateBaseWindowPositionAndSize(aIFrame);
   return NS_OK;
 }
 
 void
 nsFrameLoader::UpdateBaseWindowPositionAndSize(nsSubDocumentFrame *aIFrame)
 {
-  nsCOMPtr<nsIDocShell> docShell;
-  GetDocShell(getter_AddRefs(docShell));
-  nsCOMPtr<nsIBaseWindow> baseWindow(do_QueryInterface(docShell));
+  nsCOMPtr<nsIBaseWindow> baseWindow =
+    do_QueryInterface(GetDocShell(IgnoreErrors()));
 
   // resize the sub document
   if (baseWindow) {
     int32_t x = 0;
     int32_t y = 0;
 
     AutoWeakFrame weakFrame(aIFrame);
 
@@ -2537,65 +2459,30 @@ nsFrameLoader::LazyWidth() const
   nsIFrame* frame = GetPrimaryFrameOfOwningContent();
   if (frame) {
     lazyWidth = frame->PresContext()->DevPixelsToIntCSSPixels(lazyWidth);
   }
 
   return lazyWidth;
 }
 
-NS_IMETHODIMP
-nsFrameLoader::GetLazyWidth(uint32_t* aLazyWidth)
-{
-  *aLazyWidth = LazyWidth();
-  return NS_OK;
-}
-
 uint32_t
 nsFrameLoader::LazyHeight() const
 {
   uint32_t lazyHeight = mLazySize.height;
 
   nsIFrame* frame = GetPrimaryFrameOfOwningContent();
   if (frame) {
     lazyHeight = frame->PresContext()->DevPixelsToIntCSSPixels(lazyHeight);
   }
 
   return lazyHeight;
 }
 
-NS_IMETHODIMP
-nsFrameLoader::GetLazyHeight(uint32_t* aLazyHeight)
-{
-  *aLazyHeight = LazyHeight();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsFrameLoader::GetEventMode(uint32_t* aEventMode)
-{
-  *aEventMode = mEventMode;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsFrameLoader::SetEventMode(uint32_t aEventMode)
-{
-  mEventMode = aEventMode;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsFrameLoader::GetClipSubdocument(bool* aResult)
-{
-  *aResult = mClipSubdocument;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
+void
 nsFrameLoader::SetClipSubdocument(bool aClip)
 {
   mClipSubdocument = aClip;
   nsIFrame* frame = GetPrimaryFrameOfOwningContent();
   if (frame) {
     frame->InvalidateFrame();
     frame->PresShell()->
       FrameNeedsReflow(frame, nsIPresShell::eResize, NS_FRAME_IS_DIRTY);
@@ -2607,27 +2494,19 @@ nsFrameLoader::SetClipSubdocument(bool a
           GetRootScrollFrame();
         if (subdocRootScrollFrame) {
           frame->PresShell()->
             FrameNeedsReflow(frame, nsIPresShell::eResize, NS_FRAME_IS_DIRTY);
         }
       }
     }
   }
-  return NS_OK;
 }
 
-NS_IMETHODIMP
-nsFrameLoader::GetClampScrollPosition(bool* aResult)
-{
-  *aResult = mClampScrollPosition;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
+void
 nsFrameLoader::SetClampScrollPosition(bool aClamp)
 {
   mClampScrollPosition = aClamp;
 
   // When turning clamping on, make sure the current position is clamped.
   if (aClamp) {
     nsIFrame* frame = GetPrimaryFrameOfOwningContent();
     nsSubDocumentFrame* subdocFrame = do_QueryFrame(frame);
@@ -2637,32 +2516,32 @@ nsFrameLoader::SetClampScrollPosition(bo
         nsIScrollableFrame* subdocRootScrollFrame = subdocRootFrame->PresShell()->
           GetRootScrollFrameAsScrollable();
         if (subdocRootScrollFrame) {
           subdocRootScrollFrame->ScrollTo(subdocRootScrollFrame->GetScrollPosition(), nsIScrollableFrame::INSTANT);
         }
       }
     }
   }
-  return NS_OK;
 }
 
 static
 Tuple<ContentParent*, TabParent*>
 GetContentParent(Element* aBrowser)
 {
   using ReturnTuple = Tuple<ContentParent*, TabParent*>;
 
   nsCOMPtr<nsIBrowser> browser = do_QueryInterface(aBrowser);
   if (!browser) {
     return ReturnTuple(nullptr, nullptr);
   }
 
-  nsCOMPtr<nsIFrameLoader> otherLoader;
-  browser->GetSameProcessAsFrameLoader(getter_AddRefs(otherLoader));
+  nsCOMPtr<nsISupports> otherLoaderAsSupports;
+  browser->GetSameProcessAsFrameLoader(getter_AddRefs(otherLoaderAsSupports));
+  RefPtr<nsFrameLoader> otherLoader = do_QueryObject(otherLoaderAsSupports);
   if (!otherLoader) {
     return ReturnTuple(nullptr, nullptr);
   }
 
   TabParent* tabParent = TabParent::GetFrom(otherLoader);
   if (tabParent &&
       tabParent->Manager() &&
       tabParent->Manager()->IsContentParent()) {
@@ -2837,125 +2716,89 @@ nsFrameLoader::GetCurrentRenderFrame() c
     return mRemoteBrowser->GetRenderFrame();
   }
   return nullptr;
 }
 
 void
 nsFrameLoader::ActivateRemoteFrame(ErrorResult& aRv)
 {
-  nsresult rv = ActivateRemoteFrame();
-  if (NS_FAILED(rv)) {
-    aRv.Throw(rv);
+  if (!mRemoteBrowser) {
+    aRv.Throw(NS_ERROR_UNEXPECTED);
+    return;
   }
-}
-
-NS_IMETHODIMP
-nsFrameLoader::ActivateRemoteFrame() {
-  if (mRemoteBrowser) {
-    mRemoteBrowser->Activate();
-    return NS_OK;
-  }
-  return NS_ERROR_UNEXPECTED;
+
+  mRemoteBrowser->Activate();
 }
 
 void
 nsFrameLoader::DeactivateRemoteFrame(ErrorResult& aRv)
 {
-  nsresult rv = DeactivateRemoteFrame();
-  if (NS_FAILED(rv)) {
-    aRv.Throw(rv);
+  if (!mRemoteBrowser) {
+    aRv.Throw(NS_ERROR_UNEXPECTED);
+    return;
   }
-}
-
-NS_IMETHODIMP
-nsFrameLoader::DeactivateRemoteFrame() {
-  if (mRemoteBrowser) {
-    mRemoteBrowser->Deactivate();
-    return NS_OK;
-  }
-  return NS_ERROR_UNEXPECTED;
+
+  mRemoteBrowser->Deactivate();
 }
 
 void
 nsFrameLoader::SendCrossProcessMouseEvent(const nsAString& aType,
                                           float aX,
                                           float aY,
                                           int32_t aButton,
                                           int32_t aClickCount,
                                           int32_t aModifiers,
                                           bool aIgnoreRootScrollFrame,
                                           ErrorResult& aRv)
 {
-  nsresult rv = SendCrossProcessMouseEvent(aType, aX, aY, aButton, aClickCount, aModifiers, aIgnoreRootScrollFrame);
-  if (NS_FAILED(rv)) {
-    aRv.Throw(rv);
+  if (!mRemoteBrowser) {
+    aRv.Throw(NS_ERROR_FAILURE);
+    return;
   }
-}
-
-NS_IMETHODIMP
-nsFrameLoader::SendCrossProcessMouseEvent(const nsAString& aType,
-                                          float aX,
-                                          float aY,
-                                          int32_t aButton,
-                                          int32_t aClickCount,
-                                          int32_t aModifiers,
-                                          bool aIgnoreRootScrollFrame)
-{
-  if (mRemoteBrowser) {
-    mRemoteBrowser->SendMouseEvent(aType, aX, aY, aButton,
-                                   aClickCount, aModifiers,
-                                   aIgnoreRootScrollFrame);
-    return NS_OK;
-  }
-  return NS_ERROR_FAILURE;
+
+  mRemoteBrowser->SendMouseEvent(aType, aX, aY, aButton,
+                                 aClickCount, aModifiers,
+                                 aIgnoreRootScrollFrame);
 }
 
 void
 nsFrameLoader::ActivateFrameEvent(const nsAString& aType, bool aCapture, ErrorResult& aRv)
 {
-  nsresult rv = ActivateFrameEvent(aType, aCapture);
-  if (NS_FAILED(rv)) {
-    aRv.Throw(rv);
+  if (!mRemoteBrowser) {
+    aRv.Throw(NS_ERROR_FAILURE);
+    return;
   }
-}
-
-NS_IMETHODIMP
-nsFrameLoader::ActivateFrameEvent(const nsAString& aType,
-                                  bool aCapture)
-{
-  if (mRemoteBrowser) {
-    return mRemoteBrowser->SendActivateFrameEvent(nsString(aType), aCapture) ?
-      NS_OK : NS_ERROR_NOT_AVAILABLE;
+
+  bool ok = mRemoteBrowser->SendActivateFrameEvent(nsString(aType), aCapture);
+  if (!ok) {
+    aRv.Throw(NS_ERROR_NOT_AVAILABLE);
   }
-  return NS_ERROR_FAILURE;
 }
 
 nsresult
-nsFrameLoader::CreateStaticClone(nsIFrameLoader* aDest)
+nsFrameLoader::CreateStaticClone(nsFrameLoader* aDest)
 {
-  nsFrameLoader* dest = static_cast<nsFrameLoader*>(aDest);
-  dest->MaybeCreateDocShell();
-  NS_ENSURE_STATE(dest->mDocShell);
-
-  nsCOMPtr<nsIDocument> kungFuDeathGrip = dest->mDocShell->GetDocument();
+  aDest->MaybeCreateDocShell();
+  NS_ENSURE_STATE(aDest->mDocShell);
+
+  nsCOMPtr<nsIDocument> kungFuDeathGrip = aDest->mDocShell->GetDocument();
   Unused << kungFuDeathGrip;
 
   nsCOMPtr<nsIContentViewer> viewer;
-  dest->mDocShell->GetContentViewer(getter_AddRefs(viewer));
+  aDest->mDocShell->GetContentViewer(getter_AddRefs(viewer));
   NS_ENSURE_STATE(viewer);
 
-  nsCOMPtr<nsIDocShell> origDocShell;
-  GetDocShell(getter_AddRefs(origDocShell));
+  nsIDocShell* origDocShell = GetDocShell(IgnoreErrors());
   NS_ENSURE_STATE(origDocShell);
 
   nsCOMPtr<nsIDocument> doc = origDocShell->GetDocument();
   NS_ENSURE_STATE(doc);
 
-  nsCOMPtr<nsIDocument> clonedDoc = doc->CreateStaticClone(dest->mDocShell);
+  nsCOMPtr<nsIDocument> clonedDoc = doc->CreateStaticClone(aDest->mDocShell);
 
   viewer->SetDocument(clonedDoc);
   return NS_OK;
 }
 
 bool
 nsFrameLoader::DoLoadMessageManagerScript(const nsAString& aURL, bool aRunInGlobalScope)
 {
@@ -3043,31 +2886,18 @@ nsFrameLoader::DoSendAsyncMessage(JSCont
 
   // We don't have any targets to send our asynchronous message to.
   return NS_ERROR_UNEXPECTED;
 }
 
 already_AddRefed<nsIMessageSender>
 nsFrameLoader::GetMessageManager()
 {
-  nsCOMPtr<nsIMessageSender> messageManager;
-  MOZ_ALWAYS_SUCCEEDS(GetMessageManager(getter_AddRefs(messageManager)));
-  return messageManager.forget();
-}
-
-NS_IMETHODIMP
-nsFrameLoader::GetMessageManager(nsIMessageSender** aManager)
-{
   EnsureMessageManager();
-  if (mMessageManager) {
-    RefPtr<nsFrameMessageManager> mm(mMessageManager);
-    mm.forget(aManager);
-    return NS_OK;
-  }
-  return NS_OK;
+  return do_AddRef(mMessageManager);
 }
 
 nsresult
 nsFrameLoader::EnsureMessageManager()
 {
   NS_ENSURE_STATE(mOwnerContent);
 
   if (mMessageManager) {
@@ -3139,33 +2969,17 @@ EventTarget*
 nsFrameLoader::GetTabChildGlobalAsEventTarget()
 {
   return mChildMessageManager.get();
 }
 
 already_AddRefed<Element>
 nsFrameLoader::GetOwnerElement()
 {
-  nsCOMPtr<Element> element = do_QueryInterface(mOwnerContent);
-  return element.forget();
-}
-
-NS_IMETHODIMP
-nsFrameLoader::GetOwnerElement(nsIDOMElement **aElement)
-{
-  nsCOMPtr<nsIDOMElement> ownerElement = do_QueryInterface(mOwnerContent);
-  ownerElement.forget(aElement);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsFrameLoader::GetChildID(uint64_t* aChildID)
-{
-  *aChildID = mChildID;
-  return NS_OK;
+  return do_AddRef(mOwnerContent);
 }
 
 void
 nsFrameLoader::SetRemoteBrowser(nsITabParent* aTabParent)
 {
   MOZ_ASSERT(!mRemoteBrowser);
   mRemoteFrame = true;
   mRemoteBrowser = TabParent::GetFrom(aTabParent);
@@ -3274,56 +3088,40 @@ nsFrameLoader::AttributeChanged(mozilla:
     parentTreeOwner->ContentShellAdded(mDocShell, is_primary);
   }
 }
 
 /**
  * Send the RequestNotifyAfterRemotePaint message to the current Tab.
  */
 void
-nsFrameLoader::RequestNotifyAfterRemotePaint(ErrorResult& aRv)
-{
-  nsresult rv = RequestNotifyAfterRemotePaint();
-  if (NS_FAILED(rv)) {
-    aRv.Throw(rv);
-  }
-}
-
-NS_IMETHODIMP
 nsFrameLoader::RequestNotifyAfterRemotePaint()
 {
   // If remote browsing (e10s), handle this with the TabParent.
   if (mRemoteBrowser) {
     Unused << mRemoteBrowser->SendRequestNotifyAfterRemotePaint();
   }
-
-  return NS_OK;
 }
 
 void
 nsFrameLoader::RequestFrameLoaderClose(ErrorResult& aRv)
 {
-  nsresult rv = RequestFrameLoaderClose();
+  nsCOMPtr<nsIBrowser> browser = do_QueryInterface(mOwnerContent);
+  if (NS_WARN_IF(!browser)) {
+    // OwnerElement other than nsIBrowser is not supported yet.
+    aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
+    return;
+  }
+
+  nsresult rv = browser->CloseBrowser();
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
   }
 }
 
-NS_IMETHODIMP
-nsFrameLoader::RequestFrameLoaderClose()
-{
-  nsCOMPtr<nsIBrowser> browser = do_QueryInterface(mOwnerContent);
-  if (NS_WARN_IF(!browser)) {
-    // OwnerElement other than nsIBrowser is not supported yet.
-    return NS_ERROR_NOT_IMPLEMENTED;
-  }
-
-  return browser->CloseBrowser();
-}
-
 void
 nsFrameLoader::RequestUpdatePosition(ErrorResult& aRv)
 {
   if (auto* tabParent = TabParent::GetFrom(GetRemoteBrowser())) {
     nsresult rv = tabParent->UpdatePosition();
 
     if (NS_FAILED(rv)) {
       aRv.Throw(rv);
@@ -3332,96 +3130,75 @@ nsFrameLoader::RequestUpdatePosition(Err
 }
 
 void
 nsFrameLoader::Print(uint64_t aOuterWindowID,
                      nsIPrintSettings* aPrintSettings,
                      nsIWebProgressListener* aProgressListener,
                      ErrorResult& aRv)
 {
-  nsresult rv = Print(aOuterWindowID, aPrintSettings, aProgressListener);
-  if (NS_FAILED(rv)) {
-    aRv.Throw(rv);
-  }
-}
-
-NS_IMETHODIMP
-nsFrameLoader::Print(uint64_t aOuterWindowID,
-                     nsIPrintSettings* aPrintSettings,
-                     nsIWebProgressListener* aProgressListener)
-{
 #if defined(NS_PRINTING)
   if (mRemoteBrowser) {
     RefPtr<embedding::PrintingParent> printingParent =
       mRemoteBrowser->Manager()->AsContentParent()->GetPrintingParent();
 
     embedding::PrintData printData;
     nsresult rv = printingParent->SerializeAndEnsureRemotePrintJob(
       aPrintSettings, aProgressListener, nullptr, &printData);
     if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
+      aRv.Throw(rv);
+      return;
     }
 
     bool success = mRemoteBrowser->SendPrint(aOuterWindowID, printData);
-    return success ? NS_OK : NS_ERROR_FAILURE;
+    if (!success) {
+      aRv.Throw(NS_ERROR_FAILURE);
+    }
+    return;
   }
 
   nsGlobalWindowOuter* outerWindow =
     nsGlobalWindowOuter::GetOuterWindowWithId(aOuterWindowID);
   if (NS_WARN_IF(!outerWindow)) {
-    return NS_ERROR_FAILURE;
+    aRv.Throw(NS_ERROR_FAILURE);
+    return;
   }
 
   nsCOMPtr<nsIWebBrowserPrint> webBrowserPrint =
     do_GetInterface(outerWindow->AsOuter());
   if (NS_WARN_IF(!webBrowserPrint)) {
-    return NS_ERROR_FAILURE;
+    aRv.Throw(NS_ERROR_FAILURE);
+    return;
   }
 
-  return webBrowserPrint->Print(aPrintSettings, aProgressListener);
+  nsresult rv = webBrowserPrint->Print(aPrintSettings, aProgressListener);
+  if (NS_FAILED(rv)) {
+    aRv.Throw(rv);
+    return;
+  }
 #endif
-  return NS_OK;
 }
 
 already_AddRefed<nsITabParent>
 nsFrameLoader::GetTabParent()
 {
   return do_AddRef(mRemoteBrowser);
 }
 
-NS_IMETHODIMP
-nsFrameLoader::GetTabParent(nsITabParent** aTabParent)
-{
-  nsCOMPtr<nsITabParent> tp = mRemoteBrowser;
-  tp.forget(aTabParent);
-  return NS_OK;
-}
-
 already_AddRefed<nsILoadContext>
 nsFrameLoader::LoadContext()
 {
   nsCOMPtr<nsILoadContext> loadContext;
-  MOZ_ALWAYS_SUCCEEDS(GetLoadContext(getter_AddRefs(loadContext)));
-  return loadContext.forget();
-}
-
-NS_IMETHODIMP
-nsFrameLoader::GetLoadContext(nsILoadContext** aLoadContext)
-{
-  nsCOMPtr<nsILoadContext> loadContext;
   if (IsRemoteFrame() &&
       (mRemoteBrowser || TryRemoteBrowser())) {
     loadContext = mRemoteBrowser->GetLoadContext();
   } else {
-    nsCOMPtr<nsIDocShell> docShell;
-    GetDocShell(getter_AddRefs(docShell));
-    loadContext = do_GetInterface(docShell);
+    loadContext = do_GetInterface(GetDocShell(IgnoreErrors()));
   }
-  loadContext.forget(aLoadContext);
-  return NS_OK;
+  return loadContext.forget();
 }
 
 void
 nsFrameLoader::InitializeBrowserAPI()
 {
   if (!OwnerIsMozBrowserFrame()) {
     return;
   }
@@ -3604,23 +3381,16 @@ nsFrameLoader::PopulateUserContextIdFrom
       aAttr.mUserContextId = userContextIdStr.ToInteger(&rv);
       NS_ENSURE_SUCCESS(rv, rv);
     }
   }
 
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsFrameLoader::GetIsDead(bool* aIsDead)
-{
-  *aIsDead = mDestroyCalled;
-  return NS_OK;
-}
-
 nsIMessageSender*
 nsFrameLoader::GetProcessMessageManager() const
 {
   return mRemoteBrowser ? mRemoteBrowser->Manager()->GetMessageManager()
                         : nullptr;
 };
 
 JSObject*
--- a/dom/base/nsFrameLoader.h
+++ b/dom/base/nsFrameLoader.h
@@ -9,17 +9,17 @@
  * handling of loads in it, recursion-checking).
  */
 
 #ifndef nsFrameLoader_h_
 #define nsFrameLoader_h_
 
 #include "nsIDocShell.h"
 #include "nsStringFwd.h"
-#include "nsIFrameLoader.h"
+#include "nsIFrameLoaderOwner.h"
 #include "nsPoint.h"
 #include "nsSize.h"
 #include "nsWrapperCache.h"
 #include "nsIURI.h"
 #include "nsFrameMessageManager.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/Attributes.h"
@@ -33,16 +33,20 @@ class nsIURI;
 class nsSubDocumentFrame;
 class nsView;
 class nsInProcessTabChildGlobal;
 class AutoResetInShow;
 class AutoResetInFrameSwap;
 class nsITabParent;
 class nsIDocShellTreeItem;
 class nsIDocShellTreeOwner;
+class nsILoadContext;
+class nsIMessageSender;
+class nsIPrintSettings;
+class nsIWebProgressListener;
 
 namespace mozilla {
 
 class OriginAttributes;
 
 namespace dom {
 class ChromeMessageSender;
 class ContentParent;
@@ -61,75 +65,82 @@ namespace layout {
 class RenderFrameParent;
 } // namespace layout
 } // namespace mozilla
 
 #if defined(MOZ_WIDGET_GTK)
 typedef struct _GtkWidget GtkWidget;
 #endif
 
-class nsFrameLoader final : public nsIFrameLoader,
-                            public nsIWebBrowserPersistable,
+// IID for nsFrameLoader, because some places want to QI to it.
+#define NS_FRAMELOADER_IID                                      \
+  { 0x297fd0ea, 0x1b4a, 0x4c9a,                                 \
+      { 0xa4, 0x04, 0xe5, 0x8b, 0xe8, 0x95, 0x10, 0x50 } }
+
+class nsFrameLoader final : public nsIWebBrowserPersistable,
                             public nsStubMutationObserver,
                             public mozilla::dom::ipc::MessageManagerCallback,
                             public nsWrapperCache
 {
   friend class AutoResetInShow;
   friend class AutoResetInFrameSwap;
   typedef mozilla::dom::PBrowserParent PBrowserParent;
   typedef mozilla::dom::TabParent TabParent;
   typedef mozilla::layout::RenderFrameParent RenderFrameParent;
 
 public:
   static nsFrameLoader* Create(mozilla::dom::Element* aOwner,
                                nsPIDOMWindowOuter* aOpener,
                                bool aNetworkCreated,
                                int32_t aJSPluginID = nsFakePluginTag::NOT_JSPLUGIN);
 
+  NS_DECLARE_STATIC_IID_ACCESSOR(NS_FRAMELOADER_IID)
+
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsFrameLoader, nsIFrameLoader)
-  NS_DECL_NSIFRAMELOADER
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsFrameLoader,
+                                                         nsIWebBrowserPersistable)
   NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
   NS_DECL_NSIWEBBROWSERPERSISTABLE
   nsresult CheckForRecursiveLoad(nsIURI* aURI);
   nsresult ReallyStartLoading();
   void StartDestroy();
   void DestroyDocShell();
   void DestroyComplete();
   nsIDocShell* GetExistingDocShell() { return mDocShell; }
   mozilla::dom::EventTarget* GetTabChildGlobalAsEventTarget();
-  nsresult CreateStaticClone(nsIFrameLoader* aDest);
-
+  nsresult CreateStaticClone(nsFrameLoader* aDest);
+  nsresult UpdatePositionAndSize(nsSubDocumentFrame *aIFrame);
 
   // WebIDL methods
 
-  already_AddRefed<nsIDocShell> GetDocShell(mozilla::ErrorResult& aRv);
+  nsIDocShell* GetDocShell(mozilla::ErrorResult& aRv);
 
   already_AddRefed<nsITabParent> GetTabParent();
 
   already_AddRefed<nsILoadContext> LoadContext();
 
-  void LoadFrame(bool aOriginalSrc, mozilla::ErrorResult& aRv);
-
-  void LoadURI(nsIURI* aURI, bool aOriginalSrc, mozilla::ErrorResult& aRv);
+  /**
+   * Start loading the frame. This method figures out what to load
+   * from the owner content in the frame loader.
+   */
+  void LoadFrame(bool aOriginalSrc);
 
   /**
-   * Triggers a load of the given URI.
-   *
-   * @param aURI The URI to load.
-   * @param aTriggeringPrincipal The triggering principal for the load. May be
-   *        null, in which case the node principal of the owner content will be
-   *        used.
+   * Loads the specified URI in this frame. Behaves identically to loadFrame,
+   * except that this method allows specifying the URI to load.
    */
-  nsresult LoadURI(nsIURI* aURI, nsIPrincipal* aTriggeringPrincipal,
-                   bool aOriginalSrc);
+  nsresult LoadURI(nsIURI* aURI, bool aOriginalSrc);
 
   void AddProcessChangeBlockingPromise(mozilla::dom::Promise& aPromise, mozilla::ErrorResult& aRv);
 
-  void Destroy(mozilla::ErrorResult& aRv);
+  /**
+   * Destroy the frame loader and everything inside it. This will
+   * clear the weak owner content reference.
+   */
+  void Destroy();
 
   void ActivateRemoteFrame(mozilla::ErrorResult& aRv);
 
   void DeactivateRemoteFrame(mozilla::ErrorResult& aRv);
 
   void SendCrossProcessMouseEvent(const nsAString& aType,
                                   float aX,
                                   float aY,
@@ -138,17 +149,17 @@ public:
                                   int32_t aModifiers,
                                   bool aIgnoreRootScrollFrame,
                                   mozilla::ErrorResult& aRv);
 
   void ActivateFrameEvent(const nsAString& aType,
                           bool aCapture,
                           mozilla::ErrorResult& aRv);
 
-  void RequestNotifyAfterRemotePaint(mozilla::ErrorResult& aRv);
+  void RequestNotifyAfterRemotePaint();
 
   void RequestFrameLoaderClose(mozilla::ErrorResult& aRv);
 
   void RequestUpdatePosition(mozilla::ErrorResult& aRv);
 
   void Print(uint64_t aOuterWindowID,
              nsIPrintSettings* aPrintSettings,
              nsIWebProgressListener* aProgressListener,
@@ -158,28 +169,34 @@ public:
                         nsIWebBrowserPersistDocumentReceiver* aRecv,
                         mozilla::ErrorResult& aRv);
 
   // WebIDL getters
 
   already_AddRefed<nsIMessageSender> GetMessageManager();
 
   uint32_t EventMode() const { return mEventMode; }
+  void SetEventMode(uint32_t aEventMode)
+  {
+    mEventMode = aEventMode;
+  }
 
   already_AddRefed<Element> GetOwnerElement();
 
   uint32_t LazyWidth() const;
 
   uint32_t LazyHeight() const;
 
   uint64_t ChildID() const { return mChildID; }
 
   bool ClampScrollPosition() const { return mClampScrollPosition; }
+  void SetClampScrollPosition(bool aClamp);
 
   bool ClipSubdocument() const { return mClipSubdocument; }
+  void SetClipSubdocument(bool aClip);
 
   bool DepthTooGreat() const { return mDepthTooGreat; }
 
   bool IsDead() const { return mDestroyCalled; }
 
   /**
    * Is this a frame loader for a bona fide <iframe mozbrowser>?
    * <xul:browser> is not a mozbrowser, so this is false for that case.
@@ -217,18 +234,16 @@ public:
 
   /**
    * Called from the layout frame associated with this frame loader, when
    * the frame is being torn down; this notifies us that out widget and view
    * are going away and we should unhook from them.
    */
   void Hide();
 
-  nsresult CloneForStatic(nsIFrameLoader* aOriginal);
-
   // The guts of an nsIFrameLoaderOwner::SwapFrameLoader implementation.  A
   // frame loader owner needs to call this, and pass in the two references to
   // nsRefPtrs for frame loaders that need to be swapped.
   nsresult SwapWithOtherLoader(nsFrameLoader* aOther,
                                nsIFrameLoaderOwner* aThisOwner,
                                nsIFrameLoaderOwner* aOtherOwner);
 
   nsresult SwapWithOtherRemoteLoader(nsFrameLoader* aOther,
@@ -420,16 +435,27 @@ private:
   // Swap ourselves with the frameloader aOther, and notify chrome code with
   // a BrowserChangedProcess event.
   bool SwapBrowsersAndNotify(nsFrameLoader* aOther);
 
   // Returns a promise which will be resolved once all of the blockers have
   // resolved which were added during the BrowserWillChangeProcess event.
   already_AddRefed<mozilla::dom::Promise> FireWillChangeProcessEvent();
 
+  /**
+   * Triggers a load of the given URI.
+   *
+   * @param aURI The URI to load.
+   * @param aTriggeringPrincipal The triggering principal for the load. May be
+   *        null, in which case the node principal of the owner content will be
+   *        used.
+   */
+  nsresult LoadURI(nsIURI* aURI, nsIPrincipal* aTriggeringPrincipal,
+                   bool aOriginalSrc);
+
   nsCOMPtr<nsIDocShell> mDocShell;
   nsCOMPtr<nsIURI> mURIToLoad;
   nsCOMPtr<nsIPrincipal> mTriggeringPrincipal;
   mozilla::dom::Element* mOwnerContent; // WEAK
 
   // After the frameloader has been removed from the DOM but before all of the
   // messages from the frame have been received, we keep a strong reference to
   // our <browser> element.
@@ -448,17 +474,17 @@ private:
   // An opener window which should be used when the docshell is created.
   nsCOMPtr<nsPIDOMWindowOuter> mOpener;
 
   TabParent* mRemoteBrowser;
   uint64_t mChildID;
 
   int32_t mJSPluginID;
 
-  // See nsIFrameLoader.idl. EVENT_MODE_NORMAL_DISPATCH automatically
+  // See FrameLoader.webidl. EVENT_MODE_NORMAL_DISPATCH automatically
   // forwards some input events to out-of-process content.
   uint32_t mEventMode;
 
   // Holds the last known size of the frame.
   mozilla::ScreenIntSize mLazySize;
 
   // A stack-maintained reference to an array of promises which are blocking
   // grouped history navigation
@@ -484,9 +510,17 @@ private:
   bool mRemoteFrame : 1;
   bool mClipSubdocument : 1;
   bool mClampScrollPosition : 1;
   bool mObservingOwnerContent : 1;
 
   bool mFreshProcess : 1;
 };
 
+NS_DEFINE_STATIC_IID_ACCESSOR(nsFrameLoader, NS_FRAMELOADER_IID)
+
+inline nsISupports*
+ToSupports(nsFrameLoader* aFrameLoader)
+{
+  return static_cast<nsIWebBrowserPersistable*>(aFrameLoader);
+}
+
 #endif
--- a/dom/base/nsFrameMessageManager.cpp
+++ b/dom/base/nsFrameMessageManager.cpp
@@ -1025,31 +1025,31 @@ public:
   RefPtr<nsFrameMessageManager> mMM;
 };
 
 
 // nsIMessageListener
 
 nsresult
 nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
-                                      nsIFrameLoader* aTargetFrameLoader,
+                                      nsFrameLoader* aTargetFrameLoader,
                                       const nsAString& aMessage,
                                       bool aIsSync,
                                       StructuredCloneData* aCloneData,
                                       mozilla::jsipc::CpowHolder* aCpows,
                                       nsIPrincipal* aPrincipal,
                                       nsTArray<StructuredCloneData>* aRetVal)
 {
   return ReceiveMessage(aTarget, aTargetFrameLoader, mClosed, aMessage, aIsSync,
                         aCloneData, aCpows, aPrincipal, aRetVal);
 }
 
 nsresult
 nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
-                                      nsIFrameLoader* aTargetFrameLoader,
+                                      nsFrameLoader* aTargetFrameLoader,
                                       bool aTargetClosed,
                                       const nsAString& aMessage,
                                       bool aIsSync,
                                       StructuredCloneData* aCloneData,
                                       mozilla::jsipc::CpowHolder* aCpows,
                                       nsIPrincipal* aPrincipal,
                                       nsTArray<StructuredCloneData>* aRetVal)
 {
@@ -1152,17 +1152,17 @@ nsFrameMessageManager::ReceiveMessage(ns
         argument.mPorts.Construct(Move(ports));
       }
 
       argument.mName = aMessage;
       argument.mPrincipal = aPrincipal;
       argument.mSync = aIsSync;
       argument.mTarget = aTarget;
       if (aTargetFrameLoader) {
-        argument.mTargetFrameLoader.Construct(aTargetFrameLoader);
+        argument.mTargetFrameLoader.Construct(*aTargetFrameLoader);
       }
 
       JS::Rooted<JS::Value> thisValue(cx, JS::UndefinedValue());
 
       if (JS::IsCallable(object)) {
         // A small hack to get 'this' value right on content side where
         // messageManager is wrapped in TabChildGlobal.
         nsCOMPtr<nsISupports> defaultThisValue;
@@ -2185,17 +2185,17 @@ nsSameProcessAsyncMessageBase::Init(cons
   mCalledInit = true;
 #endif
 
   return NS_OK;
 }
 
 void
 nsSameProcessAsyncMessageBase::ReceiveMessage(nsISupports* aTarget,
-                                              nsIFrameLoader* aTargetFrameLoader,
+                                              nsFrameLoader* aTargetFrameLoader,
                                               nsFrameMessageManager* aManager)
 {
   // Make sure that we have called Init() and it has succeeded.
   MOZ_ASSERT(mCalledInit);
   if (aManager) {
     SameProcessCpowHolder cpows(RootingCx(), mCpows);
 
     RefPtr<nsFrameMessageManager> mm = aManager;
--- a/dom/base/nsFrameMessageManager.h
+++ b/dom/base/nsFrameMessageManager.h
@@ -29,17 +29,17 @@
 #include "js/RootingAPI.h"
 #include "nsTObserverArray.h"
 #include "mozilla/TypedEnumBits.h"
 #include "mozilla/dom/CallbackObject.h"
 #include "mozilla/dom/SameProcessMessageQueue.h"
 #include "mozilla/dom/ipc/StructuredCloneData.h"
 #include "mozilla/jsipc/CpowHolder.h"
 
-class nsIFrameLoader;
+class nsFrameLoader;
 
 namespace mozilla {
 namespace dom {
 
 class nsIContentParent;
 class nsIContentChild;
 class ChildProcessMessageManager;
 class ChromeMessageSender;
@@ -260,17 +260,17 @@ public:
   NS_DECL_NSICONTENTFRAMEMESSAGEMANAGER
   NS_DECL_NSIFRAMESCRIPTLOADER
   NS_DECL_NSIPROCESSSCRIPTLOADER
   NS_DECL_NSIGLOBALPROCESSSCRIPTLOADER
 
   static mozilla::dom::ChromeMessageSender*
   NewProcessMessageManager(bool aIsRemote);
 
-  nsresult ReceiveMessage(nsISupports* aTarget, nsIFrameLoader* aTargetFrameLoader,
+  nsresult ReceiveMessage(nsISupports* aTarget, nsFrameLoader* aTargetFrameLoader,
                           const nsAString& aMessage,
                           bool aIsSync, StructuredCloneData* aCloneData,
                           mozilla::jsipc::CpowHolder* aCpows, nsIPrincipal* aPrincipal,
                           nsTArray<StructuredCloneData>* aRetVal);
 
   void AddChildManager(mozilla::dom::MessageListenerManager* aManager);
   void RemoveChildManager(mozilla::dom::MessageListenerManager* aManager);
   void Disconnect(bool aRemoveFromParent = true);
@@ -346,17 +346,17 @@ protected:
                    JS::Handle<JS::Value> aObj, JS::Handle<JSObject*> aObjects,
                    nsIPrincipal* aPrincipal, bool aIsSync, nsTArray<JS::Value>& aResult,
                    mozilla::ErrorResult& aError);
   void SendMessage(JSContext* aCx, const nsAString& aMessageName,
                    StructuredCloneData& aData, JS::Handle<JSObject*> aObjects,
                    nsIPrincipal* aPrincipal, bool aIsSync,
                    nsTArray<JS::Value>& aResult, mozilla::ErrorResult& aError);
 
-  nsresult ReceiveMessage(nsISupports* aTarget, nsIFrameLoader* aTargetFrameLoader,
+  nsresult ReceiveMessage(nsISupports* aTarget, nsFrameLoader* aTargetFrameLoader,
                           bool aTargetClosed, const nsAString& aMessage,
                           bool aIsSync, StructuredCloneData* aCloneData,
                           mozilla::jsipc::CpowHolder* aCpows, nsIPrincipal* aPrincipal,
                           nsTArray<StructuredCloneData>* aRetVal);
 
   void LoadScript(const nsAString& aURL, bool aAllowDelayedLoad,
                   bool aRunInGlobalScope, mozilla::ErrorResult& aError);
   void RemoveDelayedScript(const nsAString& aURL);
@@ -433,17 +433,17 @@ public:
   typedef mozilla::dom::ipc::StructuredCloneData StructuredCloneData;
 
   nsSameProcessAsyncMessageBase(JS::RootingContext* aRootingCx,
                                 JS::Handle<JSObject*> aCpows);
   nsresult Init(const nsAString& aMessage,
                 StructuredCloneData& aData,
                 nsIPrincipal* aPrincipal);
 
-  void ReceiveMessage(nsISupports* aTarget, nsIFrameLoader* aTargetFrameLoader,
+  void ReceiveMessage(nsISupports* aTarget, nsFrameLoader* aTargetFrameLoader,
                       nsFrameMessageManager* aManager);
 private:
   nsSameProcessAsyncMessageBase(const nsSameProcessAsyncMessageBase&);
 
   nsString mMessage;
   StructuredCloneData mData;
   JS::PersistentRooted<JSObject*> mCpows;
   nsCOMPtr<nsIPrincipal> mPrincipal;
--- a/dom/base/nsGlobalWindowInner.cpp
+++ b/dom/base/nsGlobalWindowInner.cpp
@@ -12,16 +12,17 @@
 
 // Local Includes
 #include "Navigator.h"
 #include "nsContentSecurityManager.h"
 #include "nsScreen.h"
 #include "nsHistory.h"
 #include "nsDOMNavigationTiming.h"
 #include "nsIDOMStorageManager.h"
+#include "mozilla/dom/DOMJSProxyHandler.h"
 #include "mozilla/dom/DOMPrefs.h"
 #include "mozilla/dom/LocalStorage.h"
 #include "mozilla/dom/Storage.h"
 #include "mozilla/dom/IdleRequest.h"
 #include "mozilla/dom/Performance.h"
 #include "mozilla/dom/StorageEvent.h"
 #include "mozilla/dom/StorageEventBinding.h"
 #include "mozilla/dom/StorageNotifierService.h"
@@ -46,17 +47,16 @@
 #include "nsIDocShellTreeOwner.h"
 #include "nsIDocumentLoader.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIPermissionManager.h"
 #include "nsIScriptContext.h"
 #include "nsIScriptTimeoutHandler.h"
 #include "nsITimeoutHandler.h"
 #include "nsIController.h"
-#include "nsScriptNameSpaceManager.h"
 #include "nsISlowScriptDebug.h"
 #include "nsWindowMemoryReporter.h"
 #include "nsWindowSizes.h"
 #include "WindowNamedPropertiesHandler.h"
 #include "nsFrameSelection.h"
 #include "nsNetUtil.h"
 #include "nsVariant.h"
 #include "nsPrintfCString.h"
@@ -64,17 +64,16 @@
 #include "WindowDestroyedEvent.h"
 
 // Helper Classes
 #include "nsJSUtils.h"
 #include "jsapi.h"              // for JSAutoRequest
 #include "js/Wrapper.h"
 #include "nsCharSeparatedTokenizer.h"
 #include "nsReadableUtils.h"
-#include "nsDOMClassInfo.h"
 #include "nsJSEnvironment.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Likely.h"
 #include "mozilla/Sprintf.h"
 #include "mozilla/Unused.h"
 
 // Other Classes
@@ -234,16 +233,17 @@
 #include "mozilla/dom/PrimitiveConversions.h"
 #include "mozilla/dom/WindowBinding.h"
 #include "nsITabChild.h"
 #include "mozilla/dom/MediaQueryList.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/dom/NavigatorBinding.h"
 #include "mozilla/dom/ImageBitmap.h"
 #include "mozilla/dom/ImageBitmapBinding.h"
+#include "mozilla/dom/InstallTriggerBinding.h"
 #include "mozilla/dom/ServiceWorker.h"
 #include "mozilla/dom/ServiceWorkerRegistration.h"
 #include "mozilla/dom/ServiceWorkerRegistrationDescriptor.h"
 #include "mozilla/dom/U2F.h"
 #include "mozilla/dom/WebIDLGlobalNameHash.h"
 #include "mozilla/dom/Worklet.h"
 #ifdef HAVE_SIDEBAR
 #include "mozilla/dom/ExternalBinding.h"
@@ -1215,16 +1215,17 @@ nsGlobalWindowInner::CleanUp()
   mIndexedDB = nullptr;
 
   mConsole = nullptr;
 
   mAudioWorklet = nullptr;
   mPaintWorklet = nullptr;
 
   mExternal = nullptr;
+  mInstallTrigger = nullptr;
 
   mPerformance = nullptr;
 
 #ifdef MOZ_WEBSPEECH
   mSpeechSynthesis = nullptr;
 #endif
 
 #if defined(MOZ_WIDGET_ANDROID)
@@ -1518,16 +1519,17 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStatusbar)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mScrollbars)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCrypto)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mU2F)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mConsole)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAudioWorklet)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPaintWorklet)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mExternal)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mInstallTrigger)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIntlUtils)
 
   tmp->TraverseHostObjectURIs(cb);
 
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChromeFields.mMessageManager)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChromeFields.mGroupMessageManagers)
 
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPendingPromises)
@@ -1602,16 +1604,17 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mStatusbar)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mScrollbars)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mCrypto)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mU2F)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mConsole)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mAudioWorklet)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mPaintWorklet)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mExternal)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mInstallTrigger)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mIntlUtils)
 
   tmp->UnlinkHostObjectURIs();
 
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mIdleRequestExecutor)
 
   // Here the IdleRequest list would've been unlinked, but we rely on
   // that IdleRequest objects have been traced and will remove
@@ -2445,16 +2448,34 @@ nsGlobalWindowInner::ShouldReportForServ
     nsGlobalWindowInner::Cast(topOuter->GetCurrentInnerWindow());
   NS_ENSURE_TRUE(topInner, false);
 
   topInner->ShouldReportForServiceWorkerScopeInternal(NS_ConvertUTF16toUTF8(aScope),
                                                       &result);
   return result;
 }
 
+already_AddRefed<InstallTriggerImpl>
+nsGlobalWindowInner::GetInstallTrigger()
+{
+  if (!mInstallTrigger) {
+    JS::Rooted<JSObject*> jsImplObj(RootingCx());
+    ErrorResult rv;
+    ConstructJSImplementation("@mozilla.org/addons/installtrigger;1", this,
+                              &jsImplObj, rv);
+    if (rv.Failed()) {
+      rv.SuppressException();
+      return nullptr;
+    }
+    mInstallTrigger = new InstallTriggerImpl(jsImplObj, this);
+  }
+
+  return do_AddRef(mInstallTrigger);
+}
+
 nsGlobalWindowInner::CallState
 nsGlobalWindowInner::ShouldReportForServiceWorkerScopeInternal(const nsACString& aScope,
                                                                bool* aResultOut)
 {
   MOZ_DIAGNOSTIC_ASSERT(aResultOut);
 
   // First check to see if this window is controlled.  If so, then we have
   // found a match and are done.
@@ -2862,16 +2883,130 @@ nsGlobalWindowInner::GetFrames()
 }
 
 already_AddRefed<nsPIDOMWindowOuter>
 nsGlobalWindowInner::IndexedGetter(uint32_t aIndex)
 {
   FORWARD_TO_OUTER(IndexedGetterOuter, (aIndex), nullptr);
 }
 
+namespace {
+
+struct InterfaceShimEntry {
+  const char *geckoName;
+  const char *domName;
+};
+
+} // anonymous namespace
+
+// We add shims from Components.interfaces.nsIDOMFoo to window.Foo for each
+// interface that has interface constants that sites might be getting off
+// of Ci.
+const InterfaceShimEntry kInterfaceShimMap[] =
+{ { "nsIXMLHttpRequest", "XMLHttpRequest" },
+  { "nsIDOMDOMException", "DOMException" },
+  { "nsIDOMNode", "Node" },
+  { "nsIDOMCSSPrimitiveValue", "CSSPrimitiveValue" },
+  { "nsIDOMCSSRule", "CSSRule" },
+  { "nsIDOMCSSValue", "CSSValue" },
+  { "nsIDOMEvent", "Event" },
+  { "nsIDOMNSEvent", "Event" },
+  { "nsIDOMKeyEvent", "KeyEvent" },
+  { "nsIDOMMouseEvent", "MouseEvent" },
+  { "nsIDOMMouseScrollEvent", "MouseScrollEvent" },
+  { "nsIDOMMutationEvent", "MutationEvent" },
+  { "nsIDOMSimpleGestureEvent", "SimpleGestureEvent" },
+  { "nsIDOMUIEvent", "UIEvent" },
+  { "nsIDOMHTMLMediaElement", "HTMLMediaElement" },
+  { "nsIDOMOfflineResourceList", "OfflineResourceList" },
+  { "nsIDOMRange", "Range" },
+  { "nsIDOMSVGLength", "SVGLength" },
+  // Think about whether Ci.nsINodeFilter can just go away for websites!
+  { "nsIDOMNodeFilter", "NodeFilter" },
+  { "nsIDOMXPathResult", "XPathResult" } };
+
+bool
+nsGlobalWindowInner::ResolveComponentsShim(
+  JSContext *aCx,
+  JS::Handle<JSObject*> aGlobal,
+  JS::MutableHandle<JS::PropertyDescriptor> aDesc)
+{
+  // Keep track of how often this happens.
+  Telemetry::Accumulate(Telemetry::COMPONENTS_SHIM_ACCESSED_BY_CONTENT, true);
+
+  // Warn once.
+  nsCOMPtr<nsIDocument> doc = GetExtantDoc();
+  if (doc) {
+    doc->WarnOnceAbout(nsIDocument::eComponents, /* asError = */ true);
+  }
+
+  // Create a fake Components object.
+  AssertSameCompartment(aCx, aGlobal);
+  JS::Rooted<JSObject*> components(aCx, JS_NewPlainObject(aCx));
+  if (NS_WARN_IF(!components)) {
+    return false;
+  }
+
+  // Create a fake interfaces object.
+  JS::Rooted<JSObject*> interfaces(aCx, JS_NewPlainObject(aCx));
+  if (NS_WARN_IF(!interfaces)) {
+    return false;
+  }
+  bool ok =
+    JS_DefineProperty(aCx, components, "interfaces", interfaces,
+                      JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY);
+  if (NS_WARN_IF(!ok)) {
+    return false;
+  }
+
+  // Define a bunch of shims from the Ci.nsIDOMFoo to window.Foo for DOM
+  // interfaces with constants.
+  for (uint32_t i = 0; i < ArrayLength(kInterfaceShimMap); ++i) {
+
+    // Grab the names from the table.
+    const char *geckoName = kInterfaceShimMap[i].geckoName;
+    const char *domName = kInterfaceShimMap[i].domName;
+
+    // Look up the appopriate interface object on the global.
+    JS::Rooted<JS::Value> v(aCx, JS::UndefinedValue());
+    ok = JS_GetProperty(aCx, aGlobal, domName, &v);
+    if (NS_WARN_IF(!ok)) {
+      return false;
+    }
+    if (!v.isObject()) {
+      NS_WARNING("Unable to find interface object on global");
+      continue;
+    }
+
+    // Define the shim on the interfaces object.
+    ok = JS_DefineProperty(aCx, interfaces, geckoName, v,
+                           JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY);
+    if (NS_WARN_IF(!ok)) {
+      return false;
+    }
+  }
+
+  FillPropertyDescriptor(aDesc, aGlobal, JS::ObjectValue(*components), false);
+
+  return true;
+}
+
+#ifdef RELEASE_OR_BETA
+#define USE_CONTROLLERS_SHIM
+#endif
+
+#ifdef USE_CONTROLLERS_SHIM
+static const JSClass ControllersShimClass = {
+    "Controllers", 0
+};
+static const JSClass XULControllersShimClass = {
+    "XULControllers", 0
+};
+#endif
+
 bool
 nsGlobalWindowInner::DoResolve(JSContext* aCx, JS::Handle<JSObject*> aObj,
                                JS::Handle<jsid> aId,
                                JS::MutableHandle<JS::PropertyDescriptor> aDesc)
 {
   // Note: Keep this in sync with MayResolve.
 
   // Note: The infallibleInit call in GlobalResolve depends on this check.
@@ -2883,20 +3018,53 @@ nsGlobalWindowInner::DoResolve(JSContext
   if (!WebIDLGlobalNameHash::DefineIfEnabled(aCx, aObj, aId, aDesc, &found)) {
     return false;
   }
 
   if (found) {
     return true;
   }
 
-  nsresult rv = nsWindowSH::GlobalResolve(this, aCx, aObj, aId, aDesc);
-  if (NS_FAILED(rv)) {
-    return Throw(aCx, rv);
-  }
+  // We support a cut-down Components.interfaces in case websites are
+  // using Components.interfaces.nsIFoo.CONSTANT_NAME for the ones
+  // that have constants.
+  if (aId == XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_COMPONENTS)) {
+    return ResolveComponentsShim(aCx, aObj, aDesc);
+  }
+
+  // We also support a "window.controllers" thing; apparently some
+  // sites use it for browser-sniffing.  See bug 1010577.
+#ifdef USE_CONTROLLERS_SHIM
+  // Note: We use |aObj| rather than |this| to get the principal here, because
+  // this is called during Window setup when the Document isn't necessarily
+  // hooked up yet.
+  if ((aId == XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_CONTROLLERS) ||
+       aId == XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_CONTROLLERS_CLASS)) &&
+      !xpc::IsXrayWrapper(aObj) &&
+      !nsContentUtils::IsSystemPrincipal(nsContentUtils::ObjectPrincipal(aObj)))
+  {
+    if (GetExtantDoc()) {
+      GetExtantDoc()->WarnOnceAbout(nsIDocument::eWindow_Cc_ontrollers);
+    }
+    const JSClass* clazz;
+    if (aId == XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_CONTROLLERS)) {
+      clazz = &XULControllersShimClass;
+    } else {
+      clazz = &ControllersShimClass;
+    }
+    MOZ_ASSERT(JS_IsGlobalObject(aObj));
+    JS::Rooted<JSObject*> shim(cx, JS_NewObject(cx, clazz));
+    if (NS_WARN_IF(!shim)) {
+      return false;
+    }
+    FillPropertyDescriptor(aDesc, aObj, JS::ObjectValue(*shim),
+                           /* readOnly = */ false);
+    return true;
+  }
+#endif
 
   return true;
 }
 
 /* static */
 bool
 nsGlobalWindowInner::MayResolve(jsid aId)
 {
@@ -2912,90 +3080,56 @@ nsGlobalWindowInner::MayResolve(jsid aId
 
   if (aId == XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_CONTROLLERS) ||
       aId == XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_CONTROLLERS_CLASS)) {
     // We only resolve .controllers/.Controllers in release builds and on non-chrome
     // windows, but let's not worry about any of that stuff.
     return true;
   }
 
-  if (WebIDLGlobalNameHash::MayResolve(aId)) {
-    return true;
-  }
-
-  nsScriptNameSpaceManager *nameSpaceManager = PeekNameSpaceManager();
-  if (!nameSpaceManager) {
-    // Really shouldn't happen.  Fail safe.
-    return true;
-  }
-
-  nsAutoString name;
-  AssignJSFlatString(name, JSID_TO_FLAT_STRING(aId));
-
-  return nameSpaceManager->LookupName(name);
+  return WebIDLGlobalNameHash::MayResolve(aId);
 }
 
 void
 nsGlobalWindowInner::GetOwnPropertyNames(JSContext* aCx, JS::AutoIdVector& aNames,
                                          bool aEnumerableOnly, ErrorResult& aRv)
 {
   if (aEnumerableOnly) {
     // The names we would return from here get defined on the window via one of
     // two codepaths.  The ones coming from the WebIDLGlobalNameHash will end up
     // in the DefineConstructor function in BindingUtils, which always defines
     // things as non-enumerable.  The ones coming from the script namespace
-    // manager get defined by nsDOMClassInfo::PostCreatePrototype calling
-    // ResolvePrototype and using the resulting descriptot to define the
-    // property.  ResolvePrototype always passes 0 to the FillPropertyDescriptor
-    // for the property attributes, so all those are non-enumerable as well.
+    // manager get defined by our resolve hook using FillPropertyDescriptor with
+    // 0 for the property attributes, so non-enumerable as well.
     //
     // So in the aEnumerableOnly case we have nothing to do.
     return;
   }
 
   // "Components" is marked as enumerable but only resolved on demand :-/.
   //aNames.AppendElement(NS_LITERAL_STRING("Components"));
 
-  nsScriptNameSpaceManager* nameSpaceManager = GetNameSpaceManager();
-  if (nameSpaceManager) {
-    JS::Rooted<JSObject*> wrapper(aCx, GetWrapper());
-
-    // There are actually two ways we can get called here: For normal
-    // enumeration or for Xray enumeration.  In the latter case, we want to
-    // return all possible WebIDL names, because we don't really support
-    // deleting these names off our Xray; trying to resolve them will just make
-    // them come back.  In the former case, we want to avoid returning deleted
-    // names.  But the JS engine already knows about the non-deleted
-    // already-resolved names, so we can just return the so-far-unresolved ones.
-    //
-    // We can tell which case we're in by whether aCx is in our wrapper's
-    // compartment.  If not, we're in the Xray case.
-    WebIDLGlobalNameHash::NameType nameType =
-      js::IsObjectInContextCompartment(wrapper, aCx) ?
-        WebIDLGlobalNameHash::UnresolvedNamesOnly :
-        WebIDLGlobalNameHash::AllNames;
-    if (!WebIDLGlobalNameHash::GetNames(aCx, wrapper, nameType, aNames)) {
-      aRv.NoteJSContextException(aCx);
-    }
-
-    for (auto i = nameSpaceManager->GlobalNameIter(); !i.Done(); i.Next()) {
-      const GlobalNameMapEntry* entry = i.Get();
-      if (nsWindowSH::NameStructEnabled(aCx, this, entry->mKey,
-                                        entry->mGlobalName)) {
-        // Just append all of these; even if they get deleted our resolve hook
-        // just goes ahead and recreates them.
-        JSString* str = JS_AtomizeUCStringN(aCx,
-                                            entry->mKey.BeginReading(),
-                                            entry->mKey.Length());
-        if (!str || !aNames.append(NON_INTEGER_ATOM_TO_JSID(str))) {
-          aRv.NoteJSContextException(aCx);
-          return;
-        }
-      }
-    }
+  JS::Rooted<JSObject*> wrapper(aCx, GetWrapper());
+
+  // There are actually two ways we can get called here: For normal
+  // enumeration or for Xray enumeration.  In the latter case, we want to
+  // return all possible WebIDL names, because we don't really support
+  // deleting these names off our Xray; trying to resolve them will just make
+  // them come back.  In the former case, we want to avoid returning deleted
+  // names.  But the JS engine already knows about the non-deleted
+  // already-resolved names, so we can just return the so-far-unresolved ones.
+  //
+  // We can tell which case we're in by whether aCx is in our wrapper's
+  // compartment.  If not, we're in the Xray case.
+  WebIDLGlobalNameHash::NameType nameType =
+    js::IsObjectInContextCompartment(wrapper, aCx) ?
+      WebIDLGlobalNameHash::UnresolvedNamesOnly :
+      WebIDLGlobalNameHash::AllNames;
+  if (!WebIDLGlobalNameHash::GetNames(aCx, wrapper, nameType, aNames)) {
+    aRv.NoteJSContextException(aCx);
   }
 }
 
 /* static */ bool
 nsGlobalWindowInner::IsPrivilegedChromeWindow(JSContext* aCx, JSObject* aObj)
 {
   // For now, have to deal with XPConnect objects here.
   return xpc::WindowOrNull(aObj)->IsChromeWindow() &&
@@ -7702,18 +7836,17 @@ nsGlobalWindowInner::IsSecureContext() c
   return JS_GetIsSecureContext(js::GetObjectCompartment(GetWrapperPreserveColor()));
 }
 
 already_AddRefed<External>
 nsGlobalWindowInner::GetExternal(ErrorResult& aRv)
 {
 #ifdef HAVE_SIDEBAR
   if (!mExternal) {
-    AutoJSContext cx;
-    JS::Rooted<JSObject*> jsImplObj(cx);
+    JS::Rooted<JSObject*> jsImplObj(RootingCx());
     ConstructJSImplementation("@mozilla.org/sidebar;1", this, &jsImplObj, aRv);
     if (aRv.Failed()) {
       return nullptr;
     }
     mExternal = new External(jsImplObj, this);
   }
 
   RefPtr<External> external = static_cast<External*>(mExternal.get());
--- a/dom/base/nsGlobalWindowInner.h
+++ b/dom/base/nsGlobalWindowInner.h
@@ -105,16 +105,17 @@ class CustomElementRegistry;
 class DocGroup;
 class External;
 class Function;
 class Gamepad;
 enum class ImageBitmapFormat : uint8_t;
 class IdleRequest;
 class IdleRequestCallback;
 class IncrementalRunnable;
+class InstallTriggerImpl;
 class IntlUtils;
 class Location;
 class MediaQueryList;
 class OwningExternalOrWindowProxy;
 class Promise;
 class PostMessageEvent;
 struct RequestInit;
 class RequestOrUSVString;
@@ -984,16 +985,18 @@ public:
   void GetInterface(JSContext* aCx, nsIJSID* aIID,
                     JS::MutableHandle<JS::Value> aRetval,
                     mozilla::ErrorResult& aError);
 
   already_AddRefed<nsWindowRoot> GetWindowRoot(mozilla::ErrorResult& aError);
 
   bool ShouldReportForServiceWorkerScope(const nsAString& aScope);
 
+  already_AddRefed<mozilla::dom::InstallTriggerImpl> GetInstallTrigger();
+
   void UpdateTopInnerWindow();
 
   virtual bool IsInSyncOperation() override
   {
     return GetExtantDoc() && GetExtantDoc()->IsInSyncOperation();
   }
 
 protected:
@@ -1261,16 +1264,20 @@ protected:
                       JS::Handle<JS::Value> aTransfer,
                       nsIPrincipal& aSubjectPrincipal,
                       mozilla::ErrorResult& aError);
 
 private:
   // Fire the JS engine's onNewGlobalObject hook.  Only used on inner windows.
   void FireOnNewGlobalObject();
 
+  // Helper for resolving the components shim.
+  bool ResolveComponentsShim(JSContext* aCx, JS::Handle<JSObject*> aObj,
+                             JS::MutableHandle<JS::PropertyDescriptor> aDesc);
+
   // nsPIDOMWindow{Inner,Outer} should be able to see these helper methods.
   friend class nsPIDOMWindowInner;
   friend class nsPIDOMWindowOuter;
 
   mozilla::dom::TabGroup* TabGroupInner();
 
   bool IsBackgroundInternal() const;
 
@@ -1382,16 +1389,17 @@ protected:
   RefPtr<mozilla::dom::Console> mConsole;
   RefPtr<mozilla::dom::Worklet> mAudioWorklet;
   RefPtr<mozilla::dom::Worklet> mPaintWorklet;
   // We need to store an nsISupports pointer to this object because the
   // mozilla::dom::External class doesn't exist on b2g and using the type
   // forward declared here means that ~nsGlobalWindow wouldn't compile because
   // it wouldn't see the ~External function's declaration.
   nsCOMPtr<nsISupports>         mExternal;
+  RefPtr<mozilla::dom::InstallTriggerImpl> mInstallTrigger;
 
   RefPtr<mozilla::dom::Storage> mLocalStorage;
   RefPtr<mozilla::dom::Storage> mSessionStorage;
 
   RefPtr<mozilla::EventListenerManager> mListenerManager;
   RefPtr<mozilla::dom::Location> mLocation;
   RefPtr<nsHistory>           mHistory;
   RefPtr<mozilla::dom::CustomElementRegistry> mCustomElements;
--- a/dom/base/nsGlobalWindowOuter.cpp
+++ b/dom/base/nsGlobalWindowOuter.cpp
@@ -44,17 +44,16 @@
 #include "mozilla/dom/power/PowerManagerService.h"
 #include "nsIDocShellTreeOwner.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIPermissionManager.h"
 #include "nsIScriptContext.h"
 #include "nsIScriptTimeoutHandler.h"
 #include "nsITimeoutHandler.h"
 #include "nsIController.h"
-#include "nsScriptNameSpaceManager.h"
 #include "nsISlowScriptDebug.h"
 #include "nsWindowMemoryReporter.h"
 #include "nsWindowSizes.h"
 #include "WindowNamedPropertiesHandler.h"
 #include "nsFrameSelection.h"
 #include "nsNetUtil.h"
 #include "nsVariant.h"
 #include "nsPrintfCString.h"
@@ -62,17 +61,16 @@
 #include "WindowDestroyedEvent.h"
 
 // Helper Classes
 #include "nsJSUtils.h"
 #include "jsapi.h"              // for JSAutoRequest
 #include "js/Wrapper.h"
 #include "nsCharSeparatedTokenizer.h"
 #include "nsReadableUtils.h"
-#include "nsDOMClassInfo.h"
 #include "nsJSEnvironment.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Likely.h"
 #include "mozilla/Sprintf.h"
 #include "mozilla/Unused.h"
 
 // Other Classes
@@ -635,17 +633,17 @@ nsOuterWindowProxy::hasOwn(JSContext *cx
 }
 
 bool
 nsOuterWindowProxy::get(JSContext *cx, JS::Handle<JSObject*> proxy,
                         JS::Handle<JS::Value> receiver,
                         JS::Handle<jsid> id,
                         JS::MutableHandle<JS::Value> vp) const
 {
-  if (id == nsDOMClassInfo::sWrappedJSObject_id &&
+  if (id == GetJSIDByIndex(cx, XPCJSContext::IDX_WRAPPED_JSOBJECT) &&
       xpc::AccessCheck::isChrome(js::GetContextCompartment(cx))) {
     vp.set(JS::ObjectValue(*proxy));
     return true;
   }
 
   bool found;
   if (!GetSubframeWindow(cx, proxy, id, vp, found)) {
     return false;
--- a/dom/base/nsIContent.h
+++ b/dom/base/nsIContent.h
@@ -1003,36 +1003,46 @@ public:
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIContent, NS_ICONTENT_IID)
 
 inline nsIContent* nsINode::AsContent()
 {
   MOZ_ASSERT(IsContent());
   return static_cast<nsIContent*>(this);
 }
 
-#define NS_IMPL_FROMCONTENT_HELPER(_class, _check)                             \
-  static _class* FromContent(nsINode* aContent)                                \
-  {                                                                            \
-    return aContent->_check ? static_cast<_class*>(aContent) : nullptr;        \
-  }                                                                            \
-  static const _class* FromContent(const nsINode* aContent)                    \
-  {                                                                            \
-    return aContent->_check ? static_cast<const _class*>(aContent) : nullptr;  \
-  }                                                                            \
-  static _class* FromContentOrNull(nsINode* aContent)                          \
-  {                                                                            \
-    return aContent ? FromContent(aContent) : nullptr;                         \
-  }                                                                            \
-  static const _class* FromContentOrNull(const nsINode* aContent)              \
-  {                                                                            \
-    return aContent ? FromContent(aContent) : nullptr;                         \
+// Some checks are faster to do on nsIContent or Element than on
+// nsINode, so spit out FromNode versions taking those types too.
+#define NS_IMPL_FROMNODE_HELPER(_class, _check)                         \
+  template<typename ArgType>                                            \
+  static _class* FromNode(ArgType&& aNode)                              \
+  {                                                                     \
+    /* We need the double-cast in case aNode is a smartptr.  Those */   \
+    /* can cast to superclasses of the type they're templated on, */    \
+    /* but not directly to subclasses.  */                              \
+    return aNode->_check ?                                              \
+      static_cast<_class*>(static_cast<nsINode*>(aNode)) : nullptr;     \
+  }                                                                     \
+  template<typename ArgType>                                            \
+  static _class* FromNodeOrNull(ArgType&& aNode)                        \
+  {                                                                     \
+    return aNode ? FromNode(aNode) : nullptr;                           \
+  }                                                                     \
+  template<typename ArgType>                                            \
+  static const _class* FromNode(const ArgType* aNode)                   \
+  {                                                                     \
+    return aNode->_check ? static_cast<const _class*>(aNode) : nullptr; \
+  }                                                                     \
+  template<typename ArgType>                                            \
+  static const _class* FromNodeOrNull(const ArgType* aNode)             \
+  {                                                                     \
+    return aNode ? FromNode(aNode) : nullptr;                           \
   }
 
-#define NS_IMPL_FROMCONTENT(_class, _nsid)                                     \
-  NS_IMPL_FROMCONTENT_HELPER(_class, IsInNamespace(_nsid))
+#define NS_IMPL_FROMNODE(_class, _nsid)                                     \
+  NS_IMPL_FROMNODE_HELPER(_class, IsInNamespace(_nsid))
 
-#define NS_IMPL_FROMCONTENT_WITH_TAG(_class, _nsid, _tag)                      \
-  NS_IMPL_FROMCONTENT_HELPER(_class, NodeInfo()->Equals(nsGkAtoms::_tag, _nsid))
+#define NS_IMPL_FROMNODE_WITH_TAG(_class, _nsid, _tag)                      \
+  NS_IMPL_FROMNODE_HELPER(_class, NodeInfo()->Equals(nsGkAtoms::_tag, _nsid))
 
-#define NS_IMPL_FROMCONTENT_HTML_WITH_TAG(_class, _tag)                        \
-  NS_IMPL_FROMCONTENT_WITH_TAG(_class, kNameSpaceID_XHTML, _tag)
+#define NS_IMPL_FROMNODE_HTML_WITH_TAG(_class, _tag)                        \
+  NS_IMPL_FROMNODE_WITH_TAG(_class, kNameSpaceID_XHTML, _tag)
 
 #endif /* nsIContent_h___ */
--- a/dom/base/nsIContentInlines.h
+++ b/dom/base/nsIContentInlines.h
@@ -90,17 +90,17 @@ GetFlattenedTreeParentNode(const nsINode
 
   if (parentAsContent->GetShadowRoot()) {
     // If it's not assigned to any slot it's not part of the flat tree, and thus
     // we return null.
     return content->GetAssignedSlot();
   }
 
   if (parentAsContent->IsInShadowTree()) {
-    if (auto* slot = mozilla::dom::HTMLSlotElement::FromContent(parentAsContent)) {
+    if (auto* slot = mozilla::dom::HTMLSlotElement::FromNode(parentAsContent)) {
       // If the assigned nodes list is empty, we're fallback content which is
       // active, otherwise we are not part of the flat tree.
       return slot->AssignedNodes().IsEmpty()
         ? parent
         : nullptr;
     }
 
     if (auto* shadowRoot = mozilla::dom::ShadowRoot::FromNode(parentAsContent)) {
rename from dom/base/nsIFrameLoader.idl
rename to dom/base/nsIFrameLoaderOwner.idl
--- a/dom/base/nsIFrameLoader.idl
+++ b/dom/base/nsIFrameLoaderOwner.idl
@@ -1,236 +1,37 @@
 /* -*- Mode: IDL; 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/. */
 
 #include "nsISupports.idl"
 
 interface nsFrameLoader;
-interface nsIDocShell;
-interface nsIURI;
-interface nsIFrame;
-interface nsSubDocumentFrame;
-interface nsIMessageSender;
-interface nsIVariant;
-interface nsIDOMElement;
-interface nsITabParent;
-interface nsILoadContext;
-interface nsIPrintSettings;
-interface nsIWebProgressListener;
-
-[builtinclass, uuid(1645af04-1bc7-4363-8f2c-eb9679220ab1)]
-interface nsIFrameLoader : nsISupports
-{
-  /**
-   * Get the docshell from the frame loader.
-   */
-  readonly attribute nsIDocShell docShell;
-
-  /**
-   * Get this frame loader's TabParent, if it has a remote frame.  Otherwise,
-   * returns null.
-   */
-  readonly attribute nsITabParent tabParent;
-
-  /**
-   * Get an nsILoadContext for the top-level docshell. For remote
-   * frames, a shim is returned that contains private browsing and app
-   * information.
-   */
-  readonly attribute nsILoadContext loadContext;
-
-  /**
-   * Start loading the frame. This method figures out what to load
-   * from the owner content in the frame loader.
-   */
-  void loadFrame(in boolean originalSrc);
-
-  /**
-   * Loads the specified URI in this frame. Behaves identically to loadFrame,
-   * except that this method allows specifying the URI to load.
-   */
-  void loadURI(in nsIURI aURI, in boolean originalSrc);
-
-  /**
-   * Adds a blocking promise for the current cross process navigation.
-   * This method can only be called while the "BrowserWillChangeProcess" event
-   * is being fired.
-   */
-  [implicit_jscontext]
-  void addProcessChangeBlockingPromise(in jsval aPromise);
-
-  /**
-   * Destroy the frame loader and everything inside it. This will
-   * clear the weak owner content reference.
-   */
-  void destroy();
-
-  /**
-   * Find out whether the loader's frame is at too great a depth in
-   * the frame tree.  This can be used to decide what operations may
-   * or may not be allowed on the loader's docshell.
-   */
-  readonly attribute boolean depthTooGreat;
-
-  /**
-   * Updates the position and size of the subdocument loaded by this frameloader.
-   *
-   *  @param aIFrame The nsIFrame for the content node that owns this frameloader
-   */
-  [noscript] void updatePositionAndSize(in nsSubDocumentFrame aIFrame);
-
-  /**
-   * Activate remote frame.
-   * Throws an exception with non-remote frames.
-   */
-  void activateRemoteFrame();
-
-  /**
-   * Deactivate remote frame.
-   * Throws an exception with non-remote frames.
-   */
-  void deactivateRemoteFrame();
-
-  /**
-   * @see nsIDOMWindowUtils sendMouseEvent.
-   */
-  void sendCrossProcessMouseEvent(in AString aType,
-                                  in float aX,
-                                  in float aY,
-                                  in long aButton,
-                                  in long aClickCount,
-                                  in long aModifiers,
-                                  [optional] in boolean aIgnoreRootScrollFrame);
-
-  /**
-   * Activate event forwarding from client (remote frame) to parent.
-   */
-  void activateFrameEvent(in AString aType, in boolean capture);
-
-  // Note, when frameloaders are swapped, also messageManagers are swapped.
-  readonly attribute nsIMessageSender messageManager;
-
-  /**
-   * Request that the next time a remote layer transaction has been
-   * received by the Compositor, a MozAfterRemoteFrame event be sent
-   * to the window.
-   */
-  void requestNotifyAfterRemotePaint();
-
-  /**
-   * Close the window through the ownerElement.
-   */
-  void requestFrameLoaderClose();
-
-  /**
-   * Print the current document.
-   *
-   * @param aOuterWindowID the ID of the outer window to print
-   * @param aPrintSettings optional print settings to use; printSilent can be
-   *                       set to prevent prompting.
-   * @param aProgressListener optional print progress listener.
-   */
-  void print(in unsigned long long aOuterWindowID,
-             in nsIPrintSettings aPrintSettings,
-             in nsIWebProgressListener aProgressListener);
-
-  /**
-   * The default event mode automatically forwards the events
-   * handled in EventStateManager::HandleCrossProcessEvent to
-   * the child content process when these events are targeted to
-   * the remote browser element.
-   *
-   * Used primarly for input events (mouse, keyboard)
-   */
-  const unsigned long EVENT_MODE_NORMAL_DISPATCH = 0x00000000;
-
-  /**
-   * With this event mode, it's the application's responsability to
-   * convert and forward events to the content process
-   */
-  const unsigned long EVENT_MODE_DONT_FORWARD_TO_CHILD = 0x00000001;
-
-  attribute unsigned long eventMode;
-
-  /**
-   * If false, then the subdocument is not clipped to its CSS viewport, and the
-   * subdocument's viewport scrollbar(s) are not rendered.
-   * Defaults to true.
-   */
-  attribute boolean clipSubdocument;
-
-  /**
-   * If false, then the subdocument's scroll coordinates will not be clamped
-   * to their scroll boundaries.
-   * Defaults to true.
-   */
-  attribute boolean clampScrollPosition;
-
-  /**
-   * The element which owns this frame loader.
-   *
-   * For example, if this is a frame loader for an <iframe>, this attribute
-   * returns the iframe element.
-   */
-  readonly attribute nsIDOMElement ownerElement;
-
-
-  /**
-   * Cached childID of the ContentParent owning the TabParent in this frame
-   * loader. This can be used to obtain the childID after the TabParent died.
-   */
-  readonly attribute unsigned long long childID;
-
-  /**
-   * Find out whether the owner content really is a mozbrowser. <xul:browser>
-   * is not considered to be a mozbrowser frame.
-   */
-  readonly attribute boolean ownerIsMozBrowserFrame;
-
-  /**
-   * The last known width of the frame. Reading this property will not trigger
-   * a reflow, and therefore may not reflect the current state of things. It
-   * should only be used in asynchronous APIs where values are not guaranteed
-   * to be up-to-date when received.
-   */
-  readonly attribute unsigned long lazyWidth;
-
-  /**
-   * The last known height of the frame. Reading this property will not trigger
-   * a reflow, and therefore may not reflect the current state of things. It
-   * should only be used in asynchronous APIs where values are not guaranteed
-   * to be up-to-date when received.
-   */
-  readonly attribute unsigned long lazyHeight;
-
-  /**
-   * Is `true` if the frameloader is dead (destroy has been called on it)
-   */
-  [infallible] readonly attribute boolean isDead;
-};
 
 %{C++
 class nsFrameLoader;
 %}
 
 native alreadyAddRefed_nsFrameLoader(already_AddRefed<nsFrameLoader>);
 
-[scriptable, uuid(adc1b3ba-8deb-4943-8045-e6de0044f2ce)]
+// We define a "native" type for nsFrameLoader so that the rust xpidl
+// codegen doesn't try to do anything with it.
+[ptr] native nativeFrameLoader(nsFrameLoader);
+
+[scriptable, builtinclass, uuid(adc1b3ba-8deb-4943-8045-e6de0044f2ce)]
 interface nsIFrameLoaderOwner : nsISupports
 {
   /**
    * The frame loader owned by this nsIFrameLoaderOwner
    */
-  [binaryname(FrameLoaderXPCOM)] readonly attribute nsIFrameLoader frameLoader;
   [noscript, notxpcom] alreadyAddRefed_nsFrameLoader GetFrameLoader();
 
   /**
    * This method is used internally by SwapFrameLoaders to set the frame loader
    * on the target nsFrameLoader.
    *
    * Avoid using this method outside of that context, and instead prefer using
    * SwapFrameLoaders.
    */
   [noscript, notxpcom] void
-  internalSetFrameLoader(in nsIFrameLoader aNewFrameLoader);
+  internalSetFrameLoader(in nativeFrameLoader aNewFrameLoader);
 };
--- a/dom/base/nsIMessageManager.idl
+++ b/dom/base/nsIMessageManager.idl
@@ -4,18 +4,22 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
 interface mozIDOMWindowProxy;
 interface nsIDocShell;
 interface nsIContent;
 interface nsIEventTarget;
-interface nsIFrameLoader;
 interface nsIPrincipal;
+interface nsFrameLoader;
+
+// We define a "native" type for nsFrameLoader so that the rust xpidl
+// codegen doesn't try to do anything with it.
+native nativeFrameLoader(nsFrameLoader*);
 
 /**
  * Message managers provide a way for chrome-privileged JS code to
  * communicate with each other, even across process boundaries.
  *
  * Message managers are separated into "parent side" and "child side".
  * These don't always correspond to process boundaries, but can.  For
  * each child-side message manager, there is always exactly one
@@ -412,17 +416,17 @@ interface nsIContentFrameMessageManager 
    */
   readonly attribute nsIEventTarget tabEventTarget;
 };
 
 [uuid(b39a3324-b574-4f85-8cdb-274d04f807ef)]
 interface nsIInProcessContentFrameMessageManager : nsIContentFrameMessageManager
 {
   [notxpcom] nsIContent getOwnerContent();
-  [notxpcom] void cacheFrameLoader(in nsIFrameLoader aFrameLoader);
+  [notxpcom] void cacheFrameLoader(in nativeFrameLoader aFrameLoader);
 };
 
 [uuid(6d12e467-2446-46db-9965-e4e93cb87ca5)]
 interface nsIContentProcessMessageManager : nsIMessageManagerGlobal
 {
   /**
    * Read out a copy of the object that was initialized in the parent
    * process via nsIProcessScriptLoader.initialProcessData.
deleted file mode 100644
--- a/dom/base/nsIScriptNameSpaceManager.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef nsIScriptNameSpaceManager_h__
-#define nsIScriptNameSpaceManager_h__
-
-#define JAVASCRIPT_GLOBAL_CONSTRUCTOR_CATEGORY \
-  "JavaScript-global-constructor"
-
-#define JAVASCRIPT_GLOBAL_PROPERTY_CATEGORY \
-  "JavaScript-global-property"
-
-// a global property that is only accessible to privileged script
-#define JAVASCRIPT_GLOBAL_PRIVILEGED_PROPERTY_CATEGORY \
-  "JavaScript-global-privileged-property"
-
-#endif /* nsIScriptNameSpaceManager_h__ */
--- a/dom/base/nsInProcessTabChildGlobal.cpp
+++ b/dom/base/nsInProcessTabChildGlobal.cpp
@@ -34,17 +34,17 @@ nsInProcessTabChildGlobal::DoSendBlockin
                                                  bool aIsSync)
 {
   SameProcessMessageQueue* queue = SameProcessMessageQueue::Get();
   queue->Flush();
 
   if (mChromeMessageManager) {
     SameProcessCpowHolder cpows(JS::RootingContext::get(aCx), aCpows);
     RefPtr<nsFrameMessageManager> mm = mChromeMessageManager;
-    nsCOMPtr<nsIFrameLoader> fl = GetFrameLoader();
+    RefPtr<nsFrameLoader> fl = GetFrameLoader();
     mm->ReceiveMessage(mOwner, fl, aMessage, true, &aData, &cpows, aPrincipal,
                        aRetVal);
   }
   return true;
 }
 
 class nsAsyncMessageToParent : public nsSameProcessAsyncMessageBase,
                                public SameProcessMessageQueue::Runnable
@@ -54,17 +54,17 @@ public:
                          JS::Handle<JSObject*> aCpows,
                          nsInProcessTabChildGlobal* aTabChild)
     : nsSameProcessAsyncMessageBase(aRootingCx, aCpows)
     , mTabChild(aTabChild)
   { }
 
   virtual nsresult HandleMessage() override
   {
-    nsCOMPtr<nsIFrameLoader> fl = mTabChild->GetFrameLoader();
+    RefPtr<nsFrameLoader> fl = mTabChild->GetFrameLoader();
     ReceiveMessage(mTabChild->mOwner, fl, mTabChild->mChromeMessageManager);
     return NS_OK;
   }
   RefPtr<nsInProcessTabChildGlobal> mTabChild;
 };
 
 nsresult
 nsInProcessTabChildGlobal::DoSendAsyncMessage(JSContext* aCx,
@@ -184,17 +184,17 @@ nsInProcessTabChildGlobal::WrapGlobalObj
   if (ok) {
     // Since we can't rewrap we have to preserve the global's wrapper here.
     PreserveWrapper(ToSupports(this));
   }
   return ok;
 }
 
 void
-nsInProcessTabChildGlobal::CacheFrameLoader(nsIFrameLoader* aFrameLoader)
+nsInProcessTabChildGlobal::CacheFrameLoader(nsFrameLoader* aFrameLoader)
 {
   mFrameLoader = aFrameLoader;
 }
 
 already_AddRefed<nsPIDOMWindowOuter>
 nsInProcessTabChildGlobal::GetContent(ErrorResult& aError)
 {
   nsCOMPtr<nsPIDOMWindowOuter> content;
@@ -377,18 +377,18 @@ nsInProcessTabChildGlobal::LoadFrameScri
   }
   bool tmp = mLoadingScript;
   mLoadingScript = true;
   JS::Rooted<JSObject*> global(mozilla::dom::RootingCx(), GetWrapper());
   LoadScriptInternal(global, aURL, aRunInGlobalScope);
   mLoadingScript = tmp;
 }
 
-already_AddRefed<nsIFrameLoader>
+already_AddRefed<nsFrameLoader>
 nsInProcessTabChildGlobal::GetFrameLoader()
 {
   nsCOMPtr<nsIFrameLoaderOwner> owner = do_QueryInterface(mOwner);
-  nsCOMPtr<nsIFrameLoader> fl = owner ? owner->GetFrameLoader() : nullptr;
+  RefPtr<nsFrameLoader> fl = owner ? owner->GetFrameLoader() : nullptr;
   if (!fl) {
     fl = mFrameLoader;
   }
   return fl.forget();
 }
--- a/dom/base/nsInProcessTabChildGlobal.h
+++ b/dom/base/nsInProcessTabChildGlobal.h
@@ -116,17 +116,17 @@ public:
     mChromeMessageManager = aParent;
   }
 
   virtual JSObject* GetGlobalJSObject() override
   {
     return GetWrapper();
   }
 
-  already_AddRefed<nsIFrameLoader> GetFrameLoader();
+  already_AddRefed<nsFrameLoader> GetFrameLoader();
 
 protected:
   virtual ~nsInProcessTabChildGlobal();
 
   nsresult Init();
   nsresult InitTabChildGlobal();
   nsCOMPtr<nsIDocShell> mDocShell;
   bool mInitialized;
@@ -135,15 +135,15 @@ protected:
   // Is this the message manager for an in-process <iframe mozbrowser>? This
   // affects where events get sent, so it affects GetEventTargetParent.
   bool mIsBrowserFrame;
   bool mPreventEventsEscaping;
 
   // We keep a strong reference to the frameloader after we've started
   // teardown. This allows us to dispatch message manager messages during this
   // time.
-  nsCOMPtr<nsIFrameLoader> mFrameLoader;
+  RefPtr<nsFrameLoader> mFrameLoader;
 public:
   nsIContent* mOwner;
   nsFrameMessageManager* mChromeMessageManager;
 };
 
 #endif
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -48,17 +48,16 @@
 #include "jsapi.h"
 #include "js/Wrapper.h"
 #include "js/SliceBudget.h"
 #include "nsIArray.h"
 #include "nsIObjectInputStream.h"
 #include "nsIObjectOutputStream.h"
 #include "WrapperFactory.h"
 #include "nsGlobalWindow.h"
-#include "nsScriptNameSpaceManager.h"
 #include "mozilla/AutoRestore.h"
 #include "mozilla/MainThreadIdlePeriod.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/dom/DOMException.h"
 #include "mozilla/dom/DOMExceptionBinding.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/ErrorEvent.h"
 #include "mozilla/dom/FetchUtil.h"
@@ -194,17 +193,16 @@ static uint32_t sRemovedPurples = 0;
 static uint32_t sForgetSkippableBeforeCC = 0;
 static uint32_t sPreviousSuspectedCount = 0;
 static uint32_t sCleanupsSinceLastGC = UINT32_MAX;
 static bool sNeedsFullCC = false;
 static bool sNeedsFullGC = false;
 static bool sNeedsGCAfterCC = false;
 static bool sIncrementalCC = false;
 static int32_t sActiveIntersliceGCBudget = 5; // ms;
-static nsScriptNameSpaceManager *gNameSpaceManager;
 
 static PRTime sFirstCollectionTime;
 
 static bool sIsInitialized;
 static bool sDidShutdown;
 static bool sShuttingDown;
 
 // nsJSEnvironmentObserver observes the memory-pressure notifications
@@ -2462,17 +2460,16 @@ mozilla::dom::StartupJSEnvironment()
   sLoadingInProgress = false;
   sCCollectedWaitingForGC = 0;
   sCCollectedZonesWaitingForGC = 0;
   sLikelyShortLivingObjectsNeedingGC = 0;
   sPostGCEventsToConsole = false;
   sNeedsFullCC = false;
   sNeedsFullGC = true;
   sNeedsGCAfterCC = false;
-  gNameSpaceManager = nullptr;
   sIsInitialized = false;
   sDidShutdown = false;
   sShuttingDown = false;
   gCCStats.Init();
 }
 
 static void
 SetGCParameter(JSGCParamKey aParam, uint32_t aValue)
@@ -2800,46 +2797,21 @@ nsJSContext::EnsureStatics()
   obs->AddObserver(observer, "user-interaction-inactive", false);
   obs->AddObserver(observer, "user-interaction-active", false);
   obs->AddObserver(observer, "quit-application", false);
   obs->AddObserver(observer, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
 
   sIsInitialized = true;
 }
 
-nsScriptNameSpaceManager*
-mozilla::dom::GetNameSpaceManager()
-{
-  if (sDidShutdown)
-    return nullptr;
-
-  if (!gNameSpaceManager) {
-    gNameSpaceManager = new nsScriptNameSpaceManager;
-    NS_ADDREF(gNameSpaceManager);
-
-    nsresult rv = gNameSpaceManager->Init();
-    NS_ENSURE_SUCCESS(rv, nullptr);
-  }
-
-  return gNameSpaceManager;
-}
-
-nsScriptNameSpaceManager*
-mozilla::dom::PeekNameSpaceManager()
-{
-  return gNameSpaceManager;
-}
-
 void
 mozilla::dom::ShutdownJSEnvironment()
 {
   KillTimers();
 
-  NS_IF_RELEASE(gNameSpaceManager);
-
   sShuttingDown = true;
   sDidShutdown = true;
 }
 
 // A fast-array class for JS.  This class supports both nsIJSScriptArray and
 // nsIArray.  If it is JS itself providing and consuming this class, all work
 // can be done via nsIJSScriptArray, and avoid the conversion of elements
 // to/from nsISupports.
--- a/dom/base/nsJSEnvironment.h
+++ b/dom/base/nsJSEnvironment.h
@@ -15,17 +15,16 @@
 #include "nsIXPConnect.h"
 #include "nsIArray.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/TimeStamp.h"
 #include "nsThreadUtils.h"
 #include "xpcpublic.h"
 
 class nsICycleCollectorListener;
-class nsScriptNameSpaceManager;
 class nsIDocShell;
 
 namespace mozilla {
 template <class> class Maybe;
 struct CycleCollectorResults;
 } // namespace mozilla
 
 // The amount of time we wait between a request to GC (due to leaving
@@ -163,22 +162,16 @@ private:
 };
 
 namespace mozilla {
 namespace dom {
 
 void StartupJSEnvironment();
 void ShutdownJSEnvironment();
 
-// Get the NameSpaceManager, creating if necessary
-nsScriptNameSpaceManager* GetNameSpaceManager();
-
-// Peek the NameSpaceManager, without creating it.
-nsScriptNameSpaceManager* PeekNameSpaceManager();
-
 // Runnable that's used to do async error reporting
 class AsyncErrorReporter final : public mozilla::Runnable
 {
 public:
   // aWindow may be null if this error report is not associated with a window
   explicit AsyncErrorReporter(xpc::ErrorReport* aReport)
     : Runnable("dom::AsyncErrorReporter")
     , mReport(aReport)
--- a/dom/base/nsNodeUtils.cpp
+++ b/dom/base/nsNodeUtils.cpp
@@ -555,17 +555,17 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNod
             window->SetHasSelectionChangeEventListeners();
           }
         }
       }
     }
 
     if (wasRegistered && oldDoc != newDoc) {
       nsIContent* content = aNode->AsContent();
-      if (auto mediaElem = HTMLMediaElement::FromContentOrNull(content)) {
+      if (auto mediaElem = HTMLMediaElement::FromNodeOrNull(content)) {
         mediaElem->NotifyOwnerDocumentActivityChanged();
       }
       nsCOMPtr<nsIObjectLoadingContent> objectLoadingContent(do_QueryInterface(aNode));
       if (objectLoadingContent) {
         nsObjectLoadingContent* olc = static_cast<nsObjectLoadingContent*>(objectLoadingContent.get());
         olc->NotifyOwnerDocumentActivityChanged();
       }
     }
--- a/dom/base/nsObjectLoadingContent.cpp
+++ b/dom/base/nsObjectLoadingContent.cpp
@@ -577,18 +577,19 @@ nsObjectLoadingContent::SetupDocShell(ns
     return nullptr;
   }
 
   nsCOMPtr<nsIDocShell> docShell;
 
   if (aRecursionCheckURI) {
     nsresult rv = mFrameLoader->CheckForRecursiveLoad(aRecursionCheckURI);
     if (NS_SUCCEEDED(rv)) {
-      rv = mFrameLoader->GetDocShell(getter_AddRefs(docShell));
-      if (NS_FAILED(rv)) {
+      IgnoredErrorResult result;
+      docShell = mFrameLoader->GetDocShell(result);
+      if (result.Failed()) {
         NS_NOTREACHED("Could not get DocShell from mFrameLoader?");
       }
     } else {
       LOG(("OBJLC [%p]: Aborting recursive load", this));
     }
   }
 
   if (!docShell) {
@@ -884,17 +885,17 @@ nsObjectLoadingContent::GetNestedParams(
     element->GetAttribute(NS_LITERAL_STRING("name"), name);
 
     if (name.IsEmpty())
       continue;
 
     nsCOMPtr<nsIContent> parent = element->GetParent();
     RefPtr<HTMLObjectElement> objectElement;
     while (!objectElement && parent) {
-      objectElement = HTMLObjectElement::FromContent(parent);
+      objectElement = HTMLObjectElement::FromNode(parent);
       parent = parent->GetParent();
     }
 
     if (objectElement) {
       parent = objectElement;
     } else {
       continue;
     }
@@ -1117,38 +1118,31 @@ nsObjectLoadingContent::OnDataAvailable(
   // We shouldn't have a connected channel with no final listener
   NS_NOTREACHED("Got data for channel with no connected final listener");
   mChannel = nullptr;
 
   return NS_ERROR_UNEXPECTED;
 }
 
 // nsIFrameLoaderOwner
-NS_IMETHODIMP
-nsObjectLoadingContent::GetFrameLoaderXPCOM(nsIFrameLoader** aFrameLoader)
-{
-  NS_IF_ADDREF(*aFrameLoader = mFrameLoader);
-  return NS_OK;
-}
-
 NS_IMETHODIMP_(already_AddRefed<nsFrameLoader>)
 nsObjectLoadingContent::GetFrameLoader()
 {
   RefPtr<nsFrameLoader> loader = mFrameLoader;
   return loader.forget();
 }
 
 void
 nsObjectLoadingContent::PresetOpenerWindow(mozIDOMWindowProxy* aWindow, mozilla::ErrorResult& aRv)
 {
   aRv.Throw(NS_ERROR_FAILURE);
 }
 
 void
-nsObjectLoadingContent::InternalSetFrameLoader(nsIFrameLoader* aNewFrameLoader)
+nsObjectLoadingContent::InternalSetFrameLoader(nsFrameLoader* aNewFrameLoader)
 {
   MOZ_CRASH("You shouldn't be calling this function, it doesn't make any sense on this type.");
 }
 
 NS_IMETHODIMP
 nsObjectLoadingContent::GetActualType(nsACString& aType)
 {
   aType = mContentType;
@@ -2573,18 +2567,17 @@ nsObjectLoadingContent::DestroyContent()
   }
 }
 
 /* static */
 void
 nsObjectLoadingContent::Traverse(nsObjectLoadingContent *tmp,
                                  nsCycleCollectionTraversalCallback &cb)
 {
-  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mFrameLoader");
-  cb.NoteXPCOMChild(static_cast<nsIFrameLoader*>(tmp->mFrameLoader));
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFrameLoader);
 }
 
 void
 nsObjectLoadingContent::UnloadObject(bool aResetState)
 {
   // Don't notify in CancelImageRequests until we transition to a new loaded
   // state
   CancelImageRequests(false);
@@ -2964,20 +2957,20 @@ nsObjectLoadingContent::LoadFallback(Fal
       // those subtrees themselves if they end up falling back.
       bool skipChildDescendants = false;
       if (aType != eFallbackAlternate &&
           !child->IsHTMLElement(nsGkAtoms::param) &&
           nsStyleUtil::IsSignificantChild(child, false)) {
         aType = eFallbackAlternate;
       }
       if (thisIsObject) {
-        if (auto embed = HTMLEmbedElement::FromContent(child)) {
+        if (auto embed = HTMLEmbedElement::FromNode(child)) {
           embed->StartObjectLoad(true, true);
           skipChildDescendants = true;
-        } else if (auto object = HTMLObjectElement::FromContent(child)) {
+        } else if (auto object = HTMLObjectElement::FromNode(child)) {
           object->StartObjectLoad(true, true);
           skipChildDescendants = true;
         }
       }
 
       if (skipChildDescendants) {
         child = child->GetNextNonChildNode(thisContent);
       } else {
@@ -3797,17 +3790,17 @@ nsObjectLoadingContent::BlockEmbedOrObje
        parent;
        parent = parent->GetParent()) {
     if (parent->IsAnyOfHTMLElements(nsGkAtoms::video, nsGkAtoms::audio)) {
       return true;
     }
     // If we have an ancestor that is an object with a source, it'll have an
     // associated displayed type. If that type is not null, don't load content
     // for the embed.
-    if (HTMLObjectElement* object = HTMLObjectElement::FromContent(parent)) {
+    if (HTMLObjectElement* object = HTMLObjectElement::FromNode(parent)) {
       uint32_t type = object->DisplayedType();
       if (type != eType_Null) {
         return true;
       }
     }
   }
   return false;
 }
--- a/dom/base/nsObjectLoadingContent.h
+++ b/dom/base/nsObjectLoadingContent.h
@@ -18,17 +18,17 @@
 #include "nsImageLoadingContent.h"
 #include "nsIStreamListener.h"
 #include "nsIChannelEventSink.h"
 #include "nsIContentPolicy.h"
 #include "nsIObjectLoadingContent.h"
 #include "nsIRunnable.h"
 #include "nsIThreadInternal.h"
 #include "nsIFrame.h"
-#include "nsIFrameLoader.h"
+#include "nsIFrameLoaderOwner.h"
 
 class nsAsyncInstantiateEvent;
 class nsStopPluginRunnable;
 class AutoSetInstantiatingToFalse;
 class nsIPrincipal;
 class nsFrameLoader;
 class nsPluginFrame;
 class nsXULElement;
--- a/dom/base/nsOpenURIInFrameParams.h
+++ b/dom/base/nsOpenURIInFrameParams.h
@@ -2,17 +2,17 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/BasePrincipal.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsIBrowserDOMWindow.h"
-#include "nsIFrameLoader.h"
+#include "nsIFrameLoaderOwner.h"
 #include "nsString.h"
 
 namespace mozilla {
 class OriginAttributes;
 }
 
 class nsOpenURIInFrameParams final : public nsIOpenURIInFrameParams
 {
--- a/dom/base/nsRange.cpp
+++ b/dom/base/nsRange.cpp
@@ -2283,17 +2283,17 @@ nsRange::CutContents(DocumentFragment** 
     handled = false;
 
     // If it's CharacterData, make sure we might need to delete
     // part of the data, instead of removing the whole node.
     //
     // XXX_kin: We need to also handle ProcessingInstruction
     // XXX_kin: according to the spec.
 
-    if (auto charData = CharacterData::FromContent(node)) {
+    if (auto charData = CharacterData::FromNode(node)) {
       uint32_t dataLength = 0;
 
       if (node == startContainer) {
         if (node == endContainer) {
           // This range is completely contained within a single text node.
           // Delete or extract the data between startOffset and endOffset.
 
           if (endOffset > startOffset) {
@@ -2720,17 +2720,17 @@ nsRange::CloneContents(ErrorResult& aRv)
     }
 
     // If it's CharacterData, make sure we only clone what
     // is in the range.
     //
     // XXX_kin: We need to also handle ProcessingInstruction
     // XXX_kin: according to the spec.
 
-    if (auto charData = CharacterData::FromContent(clone))
+    if (auto charData = CharacterData::FromNode(clone))
     {
       if (node == mEnd.Container()) {
         // We only need the data before mEndOffset, so get rid of any
         // data after it.
 
         uint32_t dataLength = charData->Length();
         if (dataLength > (uint32_t)mEnd.Offset())
         {
deleted file mode 100644
--- a/dom/base/nsScriptNameSpaceManager.cpp
+++ /dev/null
@@ -1,434 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsScriptNameSpaceManager.h"
-#include "nsCOMPtr.h"
-#include "nsIComponentManager.h"
-#include "nsIComponentRegistrar.h"
-#include "nsICategoryManager.h"
-#include "nsIServiceManager.h"
-#include "nsXPCOM.h"
-#include "nsISupportsPrimitives.h"
-#include "nsIScriptNameSpaceManager.h"
-#include "nsIScriptContext.h"
-#include "nsIInterfaceInfoManager.h"
-#include "nsIInterfaceInfo.h"
-#include "xptinfo.h"
-#include "nsString.h"
-#include "nsReadableUtils.h"
-#include "nsHashKeys.h"
-#include "nsDOMClassInfo.h"
-#include "nsCRT.h"
-#include "nsIObserverService.h"
-#include "nsISimpleEnumerator.h"
-#include "mozilla/dom/BindingUtils.h"
-#include "mozilla/dom/WebIDLGlobalNameHash.h"
-#include "mozilla/MemoryReporting.h"
-#include "mozilla/Preferences.h"
-#include "mozilla/Services.h"
-
-#define NS_INTERFACE_PREFIX "nsI"
-#define NS_DOM_INTERFACE_PREFIX "nsIDOM"
-
-using namespace mozilla;
-using namespace mozilla::dom;
-
-static PLDHashNumber
-GlobalNameHashHashKey(const void *key)
-{
-  const nsAString *str = static_cast<const nsAString *>(key);
-  return HashString(*str);
-}
-
-static bool
-GlobalNameHashMatchEntry(const PLDHashEntryHdr *entry, const void *key)
-{
-  const GlobalNameMapEntry *e =
-    static_cast<const GlobalNameMapEntry *>(entry);
-  const nsAString *str = static_cast<const nsAString *>(key);
-
-  return str->Equals(e->mKey);
-}
-
-static void
-GlobalNameHashClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
-{
-  GlobalNameMapEntry *e = static_cast<GlobalNameMapEntry *>(entry);
-
-  // An entry is being cleared, let the key (nsString) do its own
-  // cleanup.
-  e->mKey.~nsString();
-
-  // This will set e->mGlobalName.mType to
-  // nsGlobalNameStruct::eTypeNotInitialized
-  memset(&e->mGlobalName, 0, sizeof(nsGlobalNameStruct));
-}
-
-static void
-GlobalNameHashInitEntry(PLDHashEntryHdr *entry, const void *key)
-{
-  GlobalNameMapEntry *e = static_cast<GlobalNameMapEntry *>(entry);
-  const nsAString *keyStr = static_cast<const nsAString *>(key);
-
-  // Initialize the key in the entry with placement new
-  new (&e->mKey) nsString(*keyStr);
-
-  // This will set e->mGlobalName.mType to
-  // nsGlobalNameStruct::eTypeNotInitialized
-  memset(&e->mGlobalName, 0, sizeof(nsGlobalNameStruct));
-}
-
-NS_IMPL_ISUPPORTS(
-  nsScriptNameSpaceManager,
-  nsIObserver,
-  nsISupportsWeakReference,
-  nsIMemoryReporter)
-
-static const PLDHashTableOps hash_table_ops =
-{
-  GlobalNameHashHashKey,
-  GlobalNameHashMatchEntry,
-  PLDHashTable::MoveEntryStub,
-  GlobalNameHashClearEntry,
-  GlobalNameHashInitEntry
-};
-
-#define GLOBALNAME_HASHTABLE_INITIAL_LENGTH          32
-
-nsScriptNameSpaceManager::nsScriptNameSpaceManager()
-  : mGlobalNames(&hash_table_ops, sizeof(GlobalNameMapEntry),
-                 GLOBALNAME_HASHTABLE_INITIAL_LENGTH)
-{
-}
-
-nsScriptNameSpaceManager::~nsScriptNameSpaceManager()
-{
-  UnregisterWeakMemoryReporter(this);
-}
-
-nsGlobalNameStruct *
-nsScriptNameSpaceManager::AddToHash(const char *aKey,
-                                    const char16_t **aClassName)
-{
-  NS_ConvertASCIItoUTF16 key(aKey);
-  auto entry = static_cast<GlobalNameMapEntry*>(mGlobalNames.Add(&key, fallible));
-  if (!entry) {
-    return nullptr;
-  }
-
-  WebIDLGlobalNameHash::Remove(aKey, key.Length());
-
-  if (aClassName) {
-    *aClassName = entry->mKey.get();
-  }
-
-  return &entry->mGlobalName;
-}
-
-void
-nsScriptNameSpaceManager::RemoveFromHash(const nsAString *aKey)
-{
-  mGlobalNames.Remove(aKey);
-}
-
-nsresult
-nsScriptNameSpaceManager::FillHash(nsICategoryManager *aCategoryManager,
-                                   const char *aCategory)
-{
-  nsCOMPtr<nsISimpleEnumerator> e;
-  nsresult rv = aCategoryManager->EnumerateCategory(aCategory,
-                                                    getter_AddRefs(e));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr<nsISupports> entry;
-  while (NS_SUCCEEDED(e->GetNext(getter_AddRefs(entry)))) {
-    rv = AddCategoryEntryToHash(aCategoryManager, aCategory, entry);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-  }
-
-  return NS_OK;
-}
-
-
-nsresult
-nsScriptNameSpaceManager::Init()
-{
-  RegisterWeakMemoryReporter(this);
-
-  nsresult rv = NS_OK;
-
-  nsCOMPtr<nsICategoryManager> cm =
-    do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = FillHash(cm, JAVASCRIPT_GLOBAL_CONSTRUCTOR_CATEGORY);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = FillHash(cm, JAVASCRIPT_GLOBAL_PROPERTY_CATEGORY);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = FillHash(cm, JAVASCRIPT_GLOBAL_PRIVILEGED_PROPERTY_CATEGORY);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // Initial filling of the has table has been done.
-  // Now, listen for changes.
-  nsCOMPtr<nsIObserverService> serv =
-    mozilla::services::GetObserverService();
-
-  if (serv) {
-    serv->AddObserver(this, NS_XPCOM_CATEGORY_ENTRY_ADDED_OBSERVER_ID, true);
-    serv->AddObserver(this, NS_XPCOM_CATEGORY_ENTRY_REMOVED_OBSERVER_ID, true);
-  }
-
-  return NS_OK;
-}
-
-const nsGlobalNameStruct*
-nsScriptNameSpaceManager::LookupName(const nsAString& aName,
-                                     const char16_t **aClassName)
-{
-  auto entry = static_cast<GlobalNameMapEntry*>(mGlobalNames.Search(&aName));
-
-  if (entry) {
-    if (aClassName) {
-      *aClassName = entry->mKey.get();
-    }
-    return &entry->mGlobalName;
-  }
-
-  if (aClassName) {
-    *aClassName = nullptr;
-  }
-  return nullptr;
-}
-
-nsresult
-nsScriptNameSpaceManager::RegisterClassName(const char *aClassName,
-                                            int32_t aDOMClassInfoID,
-                                            bool aPrivileged,
-                                            bool aXBLAllowed,
-                                            const char16_t **aResult)
-{
-  if (!nsCRT::IsAscii(aClassName)) {
-    NS_ERROR("Trying to register a non-ASCII class name");
-    return NS_OK;
-  }
-  nsGlobalNameStruct *s = AddToHash(aClassName, aResult);
-  NS_ENSURE_TRUE(s, NS_ERROR_OUT_OF_MEMORY);
-
-  if (s->mType == nsGlobalNameStruct::eTypeClassConstructor) {
-    return NS_OK;
-  }
-
-  // If a external constructor is already defined with aClassName we
-  // won't overwrite it.
-
-  if (s->mType == nsGlobalNameStruct::eTypeExternalConstructor) {
-    return NS_OK;
-  }
-
-  NS_ASSERTION(s->mType == nsGlobalNameStruct::eTypeNotInitialized,
-               "Whaaa, JS environment name clash!");
-
-  s->mType = nsGlobalNameStruct::eTypeClassConstructor;
-  s->mDOMClassInfoID = aDOMClassInfoID;
-  s->mChromeOnly = aPrivileged;
-  s->mAllowXBL = aXBLAllowed;
-
-  return NS_OK;
-}
-
-nsresult
-nsScriptNameSpaceManager::RegisterClassProto(const char *aClassName,
-                                             const nsIID *aConstructorProtoIID,
-                                             bool *aFoundOld)
-{
-  NS_ENSURE_ARG_POINTER(aConstructorProtoIID);
-
-  *aFoundOld = false;
-
-  nsGlobalNameStruct *s = AddToHash(aClassName);
-  NS_ENSURE_TRUE(s, NS_ERROR_OUT_OF_MEMORY);
-
-  if (s->mType != nsGlobalNameStruct::eTypeNotInitialized) {
-    *aFoundOld = true;
-
-    return NS_OK;
-  }
-
-  s->mType = nsGlobalNameStruct::eTypeClassProto;
-  s->mIID = *aConstructorProtoIID;
-
-  return NS_OK;
-}
-
-nsresult
-nsScriptNameSpaceManager::OperateCategoryEntryHash(nsICategoryManager* aCategoryManager,
-                                                   const char* aCategory,
-                                                   nsISupports* aEntry,
-                                                   bool aRemove)
-{
-  MOZ_ASSERT(aCategoryManager);
-  // Get the type from the category name.
-  // NOTE: we could have passed the type in FillHash() and guessed it in
-  // Observe() but this way, we have only one place to update and this is
-  // not performance sensitive.
-  nsGlobalNameStruct::nametype type;
-  if (strcmp(aCategory, JAVASCRIPT_GLOBAL_CONSTRUCTOR_CATEGORY) == 0) {
-    type = nsGlobalNameStruct::eTypeExternalConstructor;
-  } else if (strcmp(aCategory, JAVASCRIPT_GLOBAL_PROPERTY_CATEGORY) == 0 ||
-             strcmp(aCategory, JAVASCRIPT_GLOBAL_PRIVILEGED_PROPERTY_CATEGORY) == 0) {
-    type = nsGlobalNameStruct::eTypeProperty;
-  } else {
-    return NS_OK;
-  }
-
-  nsCOMPtr<nsISupportsCString> strWrapper = do_QueryInterface(aEntry);
-
-  if (!strWrapper) {
-    NS_WARNING("Category entry not an nsISupportsCString!");
-    return NS_OK;
-  }
-
-  nsAutoCString categoryEntry;
-  nsresult rv = strWrapper->GetData(categoryEntry);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // We need to handle removal before calling GetCategoryEntry
-  // because the category entry is already removed before we are
-  // notified.
-  if (aRemove) {
-    NS_ConvertASCIItoUTF16 entry(categoryEntry);
-    const nsGlobalNameStruct *s = LookupName(entry);
-    // Verify mType so that this API doesn't remove names
-    // registered by others.
-    if (!s || s->mType != type) {
-      return NS_OK;
-    }
-
-    RemoveFromHash(&entry);
-    return NS_OK;
-  }
-
-  nsCString contractId;
-  rv = aCategoryManager->GetCategoryEntry(aCategory, categoryEntry.get(),
-                                          getter_Copies(contractId));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr<nsIComponentRegistrar> registrar;
-  rv = NS_GetComponentRegistrar(getter_AddRefs(registrar));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCID *cidPtr;
-  rv = registrar->ContractIDToCID(contractId.get(), &cidPtr);
-
-  if (NS_FAILED(rv)) {
-    NS_WARNING("Bad contract id registed with the script namespace manager");
-    return NS_OK;
-  }
-
-  // Copy CID onto the stack, so we can free it right away and avoid having
-  // to add cleanup code at every exit point from this function.
-  nsCID cid = *cidPtr;
-  free(cidPtr);
-
-  nsGlobalNameStruct *s = AddToHash(categoryEntry.get());
-  NS_ENSURE_TRUE(s, NS_ERROR_OUT_OF_MEMORY);
-
-  if (s->mType == nsGlobalNameStruct::eTypeNotInitialized) {
-    s->mType = type;
-    s->mCID = cid;
-    s->mChromeOnly =
-      strcmp(aCategory, JAVASCRIPT_GLOBAL_PRIVILEGED_PROPERTY_CATEGORY) == 0;
-  } else {
-    NS_WARNING("Global script name not overwritten!");
-  }
-
-  return NS_OK;
-}
-
-nsresult
-nsScriptNameSpaceManager::AddCategoryEntryToHash(nsICategoryManager* aCategoryManager,
-                                                 const char* aCategory,
-                                                 nsISupports* aEntry)
-{
-  return OperateCategoryEntryHash(aCategoryManager, aCategory, aEntry,
-                                  /* aRemove = */ false);
-}
-
-nsresult
-nsScriptNameSpaceManager::RemoveCategoryEntryFromHash(nsICategoryManager* aCategoryManager,
-                                                      const char* aCategory,
-                                                      nsISupports* aEntry)
-{
-  return OperateCategoryEntryHash(aCategoryManager, aCategory, aEntry,
-                                  /* aRemove = */ true);
-}
-
-NS_IMETHODIMP
-nsScriptNameSpaceManager::Observe(nsISupports* aSubject, const char* aTopic,
-                                  const char16_t* aData)
-{
-  if (!aData) {
-    return NS_OK;
-  }
-
-  if (!strcmp(aTopic, NS_XPCOM_CATEGORY_ENTRY_ADDED_OBSERVER_ID)) {
-    nsCOMPtr<nsICategoryManager> cm =
-      do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
-    if (!cm) {
-      return NS_OK;
-    }
-
-    return AddCategoryEntryToHash(cm, NS_ConvertUTF16toUTF8(aData).get(),
-                                  aSubject);
-  } else if (!strcmp(aTopic, NS_XPCOM_CATEGORY_ENTRY_REMOVED_OBSERVER_ID)) {
-    nsCOMPtr<nsICategoryManager> cm =
-      do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
-    if (!cm) {
-      return NS_OK;
-    }
-
-    return RemoveCategoryEntryFromHash(cm, NS_ConvertUTF16toUTF8(aData).get(),
-                                       aSubject);
-  }
-
-  // TODO: we could observe NS_XPCOM_CATEGORY_CLEARED_OBSERVER_ID
-  // but we are safe without it. See bug 600460.
-
-  return NS_OK;
-}
-
-MOZ_DEFINE_MALLOC_SIZE_OF(ScriptNameSpaceManagerMallocSizeOf)
-
-NS_IMETHODIMP
-nsScriptNameSpaceManager::CollectReports(
-  nsIHandleReportCallback* aHandleReport, nsISupports* aData, bool aAnonymize)
-{
-  MOZ_COLLECT_REPORT(
-    "explicit/script-namespace-manager", KIND_HEAP, UNITS_BYTES,
-    SizeOfIncludingThis(ScriptNameSpaceManagerMallocSizeOf),
-    "Memory used for the script namespace manager.");
-
-  return NS_OK;
-}
-
-size_t
-nsScriptNameSpaceManager::SizeOfIncludingThis(
-    mozilla::MallocSizeOf aMallocSizeOf) const
-{
-  size_t n = 0;
-
-  n += mGlobalNames.ShallowSizeOfExcludingThis(aMallocSizeOf);
-  for (auto iter = mGlobalNames.ConstIter(); !iter.Done(); iter.Next()) {
-    auto entry = static_cast<GlobalNameMapEntry*>(iter.Get());
-    n += entry->SizeOfExcludingThis(aMallocSizeOf);
-  }
-
-  return n;
-}
deleted file mode 100644
--- a/dom/base/nsScriptNameSpaceManager.h
+++ /dev/null
@@ -1,163 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef nsScriptNameSpaceManager_h__
-#define nsScriptNameSpaceManager_h__
-
-#include "mozilla/MemoryReporting.h"
-#include "nsBaseHashtable.h"
-#include "nsIMemoryReporter.h"
-#include "nsIScriptNameSpaceManager.h"
-#include "nsString.h"
-#include "nsID.h"
-#include "PLDHashTable.h"
-#include "nsDOMClassInfo.h"
-#include "nsIObserver.h"
-#include "nsWeakReference.h"
-#include "xpcpublic.h"
-
-struct nsGlobalNameStruct
-{
-  enum nametype {
-    eTypeNotInitialized,
-    eTypeProperty,
-    eTypeExternalConstructor,
-    eTypeClassConstructor,
-    eTypeClassProto,
-  } mType;
-
-  bool mChromeOnly : 1;
-  bool mAllowXBL : 1;
-
-  union {
-    int32_t mDOMClassInfoID; // eTypeClassConstructor
-    nsIID mIID; // eTypeClassProto
-    nsCID mCID; // All other types
-  };
-};
-
-class GlobalNameMapEntry : public PLDHashEntryHdr
-{
-public:
-  // Our hash table ops don't care about the order of these members.
-  nsString mKey;
-  nsGlobalNameStruct mGlobalName;
-
-  size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
-    // Measurement of the following members may be added later if DMD finds it
-    // is worthwhile:
-    // - mGlobalName
-    return mKey.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
-  }
-};
-
-class nsICategoryManager;
-
-class nsScriptNameSpaceManager : public nsIObserver,
-                                 public nsSupportsWeakReference,
-                                 public nsIMemoryReporter
-{
-public:
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSIOBSERVER
-  NS_DECL_NSIMEMORYREPORTER
-
-  nsScriptNameSpaceManager();
-
-  nsresult Init();
-
-  // Returns a nsGlobalNameStruct for aName, or null if one is not
-  // found. The returned nsGlobalNameStruct is only guaranteed to be
-  // valid until the next call to any of the methods in this class.
-  // It also returns a pointer to the string buffer of the classname
-  // in the nsGlobalNameStruct.
-  const nsGlobalNameStruct* LookupName(const nsAString& aName,
-                                       const char16_t **aClassName = nullptr);
-
-  nsresult RegisterClassName(const char *aClassName,
-                             int32_t aDOMClassInfoID,
-                             bool aPrivileged,
-                             bool aXBLAllowed,
-                             const char16_t **aResult);
-
-  nsresult RegisterClassProto(const char *aClassName,
-                              const nsIID *aConstructorProtoIID,
-                              bool *aFoundOld);
-
-  class NameIterator : public PLDHashTable::Iterator
-  {
-  public:
-    typedef PLDHashTable::Iterator Base;
-    explicit NameIterator(PLDHashTable* aTable) : Base(aTable) {}
-    NameIterator(NameIterator&& aOther) : Base(mozilla::Move(aOther.mTable)) {}
-
-    const GlobalNameMapEntry* Get() const
-    {
-      return static_cast<const GlobalNameMapEntry*>(Base::Get());
-    }
-
-  private:
-    NameIterator() = delete;
-    NameIterator(const NameIterator&) = delete;
-    NameIterator& operator=(const NameIterator&) = delete;
-    NameIterator& operator=(const NameIterator&&) = delete;
-  };
-
-  NameIterator GlobalNameIter()    { return NameIterator(&mGlobalNames); }
-
-  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
-
-private:
-  virtual ~nsScriptNameSpaceManager();
-
-  // Adds a new entry to the hash and returns the nsGlobalNameStruct
-  // that aKey will be mapped to. If mType in the returned
-  // nsGlobalNameStruct is != eTypeNotInitialized, an entry for aKey
-  // already existed.
-  nsGlobalNameStruct *AddToHash(const char *aKey,
-                                const char16_t **aClassName = nullptr);
-
-  // Removes an existing entry from the hash.
-  void RemoveFromHash(const nsAString *aKey);
-
-  nsresult FillHash(nsICategoryManager *aCategoryManager,
-                    const char *aCategory);
-
-  /**
-   * Add a new category entry into the hash table.
-   * Only some categories can be added (see the beginning of the definition).
-   * The other ones will be ignored.
-   *
-   * @aCategoryManager Instance of the category manager service.
-   * @aCategory        Category where the entry comes from.
-   * @aEntry           The entry that should be added.
-   */
-  nsresult AddCategoryEntryToHash(nsICategoryManager* aCategoryManager,
-                                  const char* aCategory,
-                                  nsISupports* aEntry);
-
-  /**
-   * Remove an existing category entry from the hash table.
-   * Only some categories can be removed (see the beginning of the definition).
-   * The other ones will be ignored.
-   *
-   * @aCategory        Category where the entry will be removed from.
-   * @aEntry           The entry that should be removed.
-   */
-  nsresult RemoveCategoryEntryFromHash(nsICategoryManager* aCategoryManager,
-                                       const char* aCategory,
-                                       nsISupports* aEntry);
-
-  // common helper for AddCategoryEntryToHash and RemoveCategoryEntryFromHash
-  nsresult OperateCategoryEntryHash(nsICategoryManager* aCategoryManager,
-                                    const char* aCategory,
-                                    nsISupports* aEntry,
-                                    bool aRemove);
-
-  PLDHashTable mGlobalNames;
-};
-
-#endif /* nsScriptNameSpaceManager_h__ */
--- a/dom/base/nsWindowRoot.cpp
+++ b/dom/base/nsWindowRoot.cpp
@@ -219,32 +219,32 @@ nsWindowRoot::GetControllers(bool aForVi
     aForVisibleWindow ? nsFocusManager::eIncludeVisibleDescendants :
                         nsFocusManager::eIncludeAllDescendants;
   nsCOMPtr<nsPIDOMWindowOuter> focusedWindow;
   nsIContent* focusedContent =
     nsFocusManager::GetFocusedDescendant(mWindow, searchRange,
                                          getter_AddRefs(focusedWindow));
   if (focusedContent) {
 #ifdef MOZ_XUL
-    RefPtr<nsXULElement> xulElement = nsXULElement::FromContent(focusedContent);
+    RefPtr<nsXULElement> xulElement = nsXULElement::FromNode(focusedContent);
     if (xulElement) {
       ErrorResult rv;
       *aResult = xulElement->GetControllers(rv);
       NS_IF_ADDREF(*aResult);
       return rv.StealNSResult();
     }
 #endif
 
     HTMLTextAreaElement* htmlTextArea =
-      HTMLTextAreaElement::FromContent(focusedContent);
+      HTMLTextAreaElement::FromNode(focusedContent);
     if (htmlTextArea)
       return htmlTextArea->GetControllers(aResult);
 
     HTMLInputElement* htmlInputElement =
-      HTMLInputElement::FromContent(focusedContent);
+      HTMLInputElement::FromNode(focusedContent);
     if (htmlInputElement)
       return htmlInputElement->GetControllers(aResult);
 
     if (focusedContent->IsEditable() && focusedWindow)
       return focusedWindow->GetControllers(aResult);
   }
   else {
     return focusedWindow->GetControllers(aResult);
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -1714,17 +1714,16 @@ addExternalIface('Cookie', nativeType='n
 addExternalIface('HitRegionOptions', nativeType='nsISupports')
 addExternalIface('imgINotificationObserver', nativeType='imgINotificationObserver')
 addExternalIface('imgIRequest', nativeType='imgIRequest', notflattened=True)
 addExternalIface('LoadContext', nativeType='nsILoadContext', notflattened=True)
 addExternalIface('LoadInfo', nativeType='nsILoadInfo',
                  headerFile='nsILoadInfo.h', notflattened=True)
 addExternalIface('MenuBuilder', nativeType='nsIMenuBuilder', notflattened=True)
 addExternalIface('XULControllers', nativeType='nsIControllers', notflattened=True)
-addExternalIface('MozFrameLoader', nativeType='nsIFrameLoader', notflattened=True)
 addExternalIface('MozObserver', nativeType='nsIObserver', notflattened=True)
 addExternalIface('MozRDFCompositeDataSource', nativeType='nsIRDFCompositeDataSource',
                  notflattened=True)
 addExternalIface('MozRDFResource', nativeType='nsIRDFResource', notflattened=True)
 addExternalIface('MozTreeView', nativeType='nsITreeView',
                   headerFile='nsITreeView.h', notflattened=True)
 addExternalIface('MozWakeLockListener', headerFile='nsIDOMWakeLockListener.h')
 addExternalIface('nsIBrowserDOMWindow', nativeType='nsIBrowserDOMWindow',
--- a/dom/browser-element/BrowserElementParent.cpp
+++ b/dom/browser-element/BrowserElementParent.cpp
@@ -279,18 +279,17 @@ BrowserElementParent::OpenWindowInProces
   if (opened != BrowserElementParent::OPEN_WINDOW_ADDED) {
     return opened;
   }
 
   // Return popupFrameElement's window.
   RefPtr<nsFrameLoader> frameLoader = popupFrameElement->GetFrameLoader();
   NS_ENSURE_TRUE(frameLoader, BrowserElementParent::OPEN_WINDOW_IGNORED);
 
-  nsCOMPtr<nsIDocShell> docshell;
-  frameLoader->GetDocShell(getter_AddRefs(docshell));
+  nsCOMPtr<nsIDocShell> docshell = frameLoader->GetDocShell(IgnoreErrors());
   NS_ENSURE_TRUE(docshell, BrowserElementParent::OPEN_WINDOW_IGNORED);
 
   nsCOMPtr<nsPIDOMWindowOuter> window = docshell->GetWindow();
   window.forget(aReturnWindow);
 
   return !!*aReturnWindow ? opened : BrowserElementParent::OPEN_WINDOW_CANCELLED;
 }
 
--- a/dom/browser-element/BrowserElementParent.js
+++ b/dom/browser-element/BrowserElementParent.js
@@ -76,17 +76,17 @@ BrowserElementParent.prototype = {
   contractID: "@mozilla.org/dom/browser-element-api;1",
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIBrowserElementAPI,
                                          Ci.nsIObserver,
                                          Ci.nsISupportsWeakReference]),
 
   setFrameLoader: function(frameLoader) {
     debug("Setting frameLoader");
     this._frameLoader = frameLoader;
-    this._frameElement = frameLoader.QueryInterface(Ci.nsIFrameLoader).ownerElement;
+    this._frameElement = frameLoader.ownerElement;
     if (!this._frameElement) {
       debug("No frame element?");
       return;
     }
     // Listen to visibilitychange on the iframe's owner window, and forward
     // changes down to the child.  We want to do this while registering as few
     // visibilitychange listeners on _window as possible, because such a listener
     // may live longer than this BrowserElementParent object.
--- a/dom/browser-element/nsIBrowserElementAPI.idl
+++ b/dom/browser-element/nsIBrowserElementAPI.idl
@@ -2,17 +2,16 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
 interface nsIDOMDOMRequest;
-interface nsIFrameLoader;
 
 [scriptable, function, uuid(00d0e19d-bd67-491f-8e85-b9905224d3bb)]
 interface nsIBrowserElementNextPaintListener : nsISupports
 {
   void recvNextPaint();
 };
 
 %{C++
@@ -35,17 +34,18 @@ interface nsIBrowserElementAPI : nsISupp
   const long FIND_FORWARD = 0;
   const long FIND_BACKWARD = 1;
 
   /**
    * Notify frame scripts that support the API to destroy.
    */
   void destroyFrameScripts();
 
-  void setFrameLoader(in nsIFrameLoader frameLoader);
+  // The argument should be a FrameLoader.  Fix that when bug 1444991 is fixed.
+  void setFrameLoader(in nsISupports frameLoader);
 
   void sendMouseEvent(in DOMString type,
                       in uint32_t x,
                       in uint32_t y,
                       in uint32_t button,
                       in uint32_t clickCount,
                       in uint32_t mifiers);
   void sendTouchEvent(in DOMString aType,
--- a/dom/chrome-webidl/MessageManager.webidl
+++ b/dom/chrome-webidl/MessageManager.webidl
@@ -1,14 +1,13 @@
 /* -*- Mode: IDL; 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/. */
 
-interface MozFrameLoader;
 interface nsIEventTarget;
 interface Principal;
 
 dictionary ReceiveMessageArgument
 {
   /**
    * The target of the message. Either an element owning the message manager, or message
    * manager itself if no element owns it.
@@ -39,17 +38,17 @@ dictionary ReceiveMessageArgument
 
   sequence<MessagePort> ports;
 
   /**
    * Principal for the window app.
    */
   required Principal? principal;
 
-  MozFrameLoader targetFrameLoader;
+  FrameLoader targetFrameLoader;
 };
 
 callback interface MessageListener
 {
   /**
    * Each listener is invoked with its own copy of the message
    * parameter.
    *
--- a/dom/events/EventListenerService.cpp
+++ b/dom/events/EventListenerService.cpp
@@ -7,17 +7,16 @@
 #include "EventListenerService.h"
 #include "mozilla/BasicEvents.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventListenerManager.h"
 #include "mozilla/JSEventHandler.h"
 #include "mozilla/Maybe.h"
 #include "nsArrayUtils.h"
 #include "nsCOMArray.h"
-#include "nsDOMClassInfoID.h"
 #include "nsIXPConnect.h"
 #include "nsJSUtils.h"
 #include "nsMemory.h"
 #include "nsServiceManagerUtils.h"
 #include "nsArray.h"
 #include "nsThreadUtils.h"
 
 namespace mozilla {
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -13,16 +13,17 @@
 #include "mozilla/MathAlgorithms.h"
 #include "mozilla/MouseEvents.h"
 #include "mozilla/TextComposition.h"
 #include "mozilla/TextEvents.h"
 #include "mozilla/TouchEvents.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/DragEvent.h"
 #include "mozilla/dom/Event.h"
+#include "mozilla/dom/FrameLoaderBinding.h"
 #include "mozilla/dom/MouseEventBinding.h"
 #include "mozilla/dom/TabChild.h"
 #include "mozilla/dom/TabParent.h"
 #include "mozilla/dom/UIEvent.h"
 #include "mozilla/dom/WheelEventBinding.h"
 
 #include "ContentEventHandler.h"
 #include "IMEContentObserver.h"
@@ -1433,19 +1434,18 @@ EventStateManager::HandleCrossProcessEve
       continue;
     }
 
     RefPtr<nsFrameLoader> frameLoader = loaderOwner->GetFrameLoader();
     if (!frameLoader) {
       continue;
     }
 
-    uint32_t eventMode;
-    frameLoader->GetEventMode(&eventMode);
-    if (eventMode == nsIFrameLoader::EVENT_MODE_DONT_FORWARD_TO_CHILD) {
+    if (frameLoader->EventMode() ==
+          FrameLoaderBinding::EVENT_MODE_DONT_FORWARD_TO_CHILD) {
       continue;
     }
 
     DispatchCrossProcessEvent(aEvent, frameLoader, aStatus);
   }
   return aEvent->HasBeenPostedToRemoteProcess();
 }
 
@@ -1988,17 +1988,17 @@ EventStateManager::DetermineDragTargetAn
   nsIContent* originalDragContent = dragContent;
 
   // If a selection isn't being dragged, look for an ancestor with the
   // draggable property set. If one is found, use that as the target of the
   // drag instead of the node that was clicked on. If a draggable node wasn't
   // found, just use the clicked node.
   if (!*aSelection) {
     while (dragContent) {
-      if (auto htmlElement = nsGenericHTMLElement::FromContent(dragContent)) {
+      if (auto htmlElement = nsGenericHTMLElement::FromNode(dragContent)) {
         if (htmlElement->Draggable()) {
           break;
         }
       }
       else {
         if (dragContent->IsXULElement()) {
           // All XUL elements are draggable, so if a XUL element is
           // encountered, stop looking for draggable nodes and just use the
@@ -4253,18 +4253,17 @@ EventStateManager::NotifyMouseOut(Widget
   if (wrapper->mLastOverElement == wrapper->mFirstOutEventElement)
     return;
 
   if (wrapper->mLastOverFrame) {
     // if the frame is associated with a subdocument,
     // tell the subdocument that we're moving out of it
     nsSubDocumentFrame* subdocFrame = do_QueryFrame(wrapper->mLastOverFrame.GetFrame());
     if (subdocFrame) {
-      nsCOMPtr<nsIDocShell> docshell;
-      subdocFrame->GetDocShell(getter_AddRefs(docshell));
+      nsIDocShell* docshell = subdocFrame->GetDocShell();
       if (docshell) {
         RefPtr<nsPresContext> presContext;
         docshell->GetPresContext(getter_AddRefs(presContext));
 
         if (presContext) {
           EventStateManager* kidESM = presContext->EventStateManager();
           // Not moving into any element in this subdocument
           kidESM->NotifyMouseOut(aMouseEvent, nullptr);
@@ -5004,17 +5003,17 @@ EventStateManager::GetEventTargetContent
 
   return content.forget();
 }
 
 static Element*
 GetLabelTarget(nsIContent* aPossibleLabel)
 {
   mozilla::dom::HTMLLabelElement* label =
-    mozilla::dom::HTMLLabelElement::FromContent(aPossibleLabel);
+    mozilla::dom::HTMLLabelElement::FromNode(aPossibleLabel);
   if (!label)
     return nullptr;
 
   return label->GetLabeledElement();
 }
 
 static nsIContent*
 FindCommonAncestor(nsIContent* aNode1, nsIContent* aNode2)
--- a/dom/events/IMEStateManager.cpp
+++ b/dom/events/IMEStateManager.cpp
@@ -1290,17 +1290,17 @@ IMEStateManager::SetIMEState(const IMESt
       aContent->IsAnyOfHTMLElements(nsGkAtoms::input, nsGkAtoms::textarea)) {
     if (!aContent->IsHTMLElement(nsGkAtoms::textarea)) {
       // <input type=number> has an anonymous <input type=text> descendant
       // that gets focus whenever anyone tries to focus the number control. We
       // need to check if aContent is one of those anonymous text controls and,
       // if so, use the number control instead:
       Element* element = aContent->AsElement();
       HTMLInputElement* inputElement =
-        HTMLInputElement::FromContentOrNull(aContent);
+        HTMLInputElement::FromNodeOrNull(aContent);
       if (inputElement) {
         HTMLInputElement* ownerNumberControl =
           inputElement->GetOwnerNumberControl();
         if (ownerNumberControl) {
           element = ownerNumberControl; // an <input type=number>
         }
       }
       element->GetAttr(kNameSpaceID_None, nsGkAtoms::type,
--- a/dom/file/FileReaderSync.cpp
+++ b/dom/file/FileReaderSync.cpp
@@ -10,17 +10,16 @@
 #include "mozilla/Unused.h"
 #include "mozilla/Base64.h"
 #include "mozilla/dom/File.h"
 #include "mozilla/Encoding.h"
 #include "mozilla/dom/FileReaderSyncBinding.h"
 #include "nsCExternalHandlerService.h"
 #include "nsComponentManagerUtils.h"
 #include "nsCOMPtr.h"
-#include "nsDOMClassInfoID.h"
 #include "nsError.h"
 #include "nsIConverterInputStream.h"
 #include "nsIInputStream.h"
 #include "nsIMultiplexInputStream.h"
 #include "nsStreamUtils.h"
 #include "nsStringStream.h"
 #include "nsISupportsImpl.h"
 #include "nsNetUtil.h"
--- a/dom/file/MultipartBlobImpl.cpp
+++ b/dom/file/MultipartBlobImpl.cpp
@@ -4,17 +4,16 @@
  * 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 "MultipartBlobImpl.h"
 #include "jsfriendapi.h"
 #include "mozilla/dom/BlobSet.h"
 #include "mozilla/dom/FileBinding.h"
 #include "mozilla/dom/UnionTypes.h"
-#include "nsDOMClassInfoID.h"
 #include "nsIMultiplexInputStream.h"
 #include "nsRFPService.h"
 #include "nsStringStream.h"
 #include "nsTArray.h"
 #include "nsJSUtils.h"
 #include "nsContentUtils.h"
 #include "nsIScriptError.h"
 #include "nsIXPConnect.h"
--- a/dom/geolocation/nsGeolocation.cpp
+++ b/dom/geolocation/nsGeolocation.cpp
@@ -14,17 +14,16 @@
 #include "mozilla/Telemetry.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/Unused.h"
 #include "mozilla/WeakPtr.h"
 #include "mozilla/EventStateManager.h"
 #include "nsComponentManagerUtils.h"
 #include "nsContentPermissionHelper.h"
 #include "nsContentUtils.h"
-#include "nsDOMClassInfoID.h"
 #include "nsGlobalWindow.h"
 #include "nsIDocument.h"
 #include "nsINamed.h"
 #include "nsIObserverService.h"
 #include "nsIScriptError.h"
 #include "nsPIDOMWindow.h"
 #include "nsServiceManagerUtils.h"
 #include "nsThreadUtils.h"
--- a/dom/html/HTMLAllCollection.cpp
+++ b/dom/html/HTMLAllCollection.cpp
@@ -88,17 +88,17 @@ IsAllNamedElement(nsIContent* aContent)
 static bool
 DocAllResultMatch(Element* aElement, int32_t aNamespaceID, nsAtom* aAtom,
                   void* aData)
 {
   if (aElement->GetID() == aAtom) {
     return true;
   }
 
-  nsGenericHTMLElement* elm = nsGenericHTMLElement::FromContent(aElement);
+  nsGenericHTMLElement* elm = nsGenericHTMLElement::FromNode(aElement);
   if (!elm) {
     return false;
   }
 
   if (!IsAllNamedElement(elm)) {
     return false;
   }
 
@@ -168,17 +168,17 @@ HTMLAllCollection::GetSupportedNames(nsT
       nsAtom* id = content->GetID();
       MOZ_ASSERT(id != nsGkAtoms::_empty,
                  "Empty ids don't get atomized");
       if (!atoms.Contains(id)) {
         atoms.AppendElement(id);
       }
     }
 
-    nsGenericHTMLElement* el = nsGenericHTMLElement::FromContent(content);
+    nsGenericHTMLElement* el = nsGenericHTMLElement::FromNode(content);
     if (el) {
       // Note: nsINode::HasName means the name is exposed on the document,
       // which is false for options, so we don't check it here.
       const nsAttrValue* val = el->GetParsedAttr(nsGkAtoms::name);
       if (val && val->Type() == nsAttrValue::eAtom &&
           IsAllNamedElement(content)) {
         nsAtom* name = val->GetAtomValue();
         MOZ_ASSERT(name != nsGkAtoms::_empty,
--- a/dom/html/HTMLAnchorElement.h
+++ b/dom/html/HTMLAnchorElement.h
@@ -32,17 +32,17 @@ public:
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // CC
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLAnchorElement,
                                            nsGenericHTMLElement)
 
-  NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLAnchorElement, a);
+  NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLAnchorElement, a);
 
   virtual int32_t TabIndexDefault() override;
   virtual bool Draggable() const override;
 
   // Element
   virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const override;
 
   // DOM memory reporter participant
--- a/dom/html/HTMLAreaElement.h
+++ b/dom/html/HTMLAreaElement.h
@@ -30,17 +30,17 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
 
   // CC
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLAreaElement,
                                            nsGenericHTMLElement)
 
   NS_DECL_ADDSIZEOFEXCLUDINGTHIS
 
-  NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLAreaElement, area)
+  NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLAreaElement, area)
 
   virtual int32_t TabIndexDefault() override;
 
   virtual nsresult GetEventTargetParent(
                      EventChainPreVisitor& aVisitor) override;
   virtual nsresult PostHandleEvent(EventChainPostVisitor& aVisitor) override;
   virtual bool IsLink(nsIURI** aURI) const override;
   virtual void GetLinkTarget(nsAString& aTarget) override;
--- a/dom/html/HTMLAudioElement.h
+++ b/dom/html/HTMLAudioElement.h
@@ -16,17 +16,17 @@ typedef uint16_t nsMediaReadyState;
 namespace mozilla {
 namespace dom {
 
 class HTMLAudioElement final : public HTMLMediaElement
 {
 public:
   typedef mozilla::dom::NodeInfo NodeInfo;
 
-  NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLAudioElement, audio)
+  NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLAudioElement, audio)
 
   explicit HTMLAudioElement(already_AddRefed<NodeInfo>& aNodeInfo);
 
   // Element
   virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const override;
 
   // nsIDOMHTMLMediaElement
   using HTMLMediaElement::GetPaused;
--- a/dom/html/HTMLBodyElement.h
+++ b/dom/html/HTMLBodyElement.h
@@ -26,17 +26,17 @@ public:
   explicit HTMLBodyElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
     : nsGenericHTMLElement(aNodeInfo)
   {
   }
 
   // nsISupports
   NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLBodyElement, nsGenericHTMLElement)
 
-  NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLBodyElement, body);
+  NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLBodyElement, body);
 
   // Event listener stuff; we need to declare only the ones we need to
   // forward to window that don't come from nsIDOMHTMLBodyElement.
 #define EVENT(name_, id_, type_, struct_) /* nothing; handled by the shim */
 #define WINDOW_EVENT_HELPER(name_, type_)                               \
   type_* GetOn##name_();                                                \
   void SetOn##name_(type_* handler);
 #define WINDOW_EVENT(name_, id_, type_, struct_)                        \
--- a/dom/html/HTMLButtonElement.h
+++ b/dom/html/HTMLButtonElement.h
@@ -28,17 +28,17 @@ public:
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLButtonElement,
                                            nsGenericHTMLFormElementWithState)
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   virtual int32_t TabIndexDefault() override;
 
-  NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLButtonElement, button)
+  NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLButtonElement, button)
 
   // Element
   virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const override
   {
     return true;
   }
 
   // overriden nsIFormControl methods
--- a/dom/html/HTMLCanvasElement.h
+++ b/dom/html/HTMLCanvasElement.h
@@ -128,17 +128,17 @@ class HTMLCanvasElement final : public n
   typedef layers::CanvasLayer CanvasLayer;
   typedef layers::Layer Layer;
   typedef layers::LayerManager LayerManager;
   typedef layers::WebRenderCanvasData WebRenderCanvasData;
 
 public:
   explicit HTMLCanvasElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
 
-  NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLCanvasElement, canvas)
+  NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLCanvasElement, canvas)
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // CC
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLCanvasElement,
                                            nsGenericHTMLElement)
 
--- a/dom/html/HTMLDetailsElement.h
+++ b/dom/html/HTMLDetailsElement.h
@@ -24,17 +24,17 @@ class HTMLDetailsElement final : public 
 public:
   using NodeInfo = mozilla::dom::NodeInfo;
 
   explicit HTMLDetailsElement(already_AddRefed<NodeInfo>& aNodeInfo)
     : nsGenericHTMLElement(aNodeInfo)
   {
   }
 
-  NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLDetailsElement, details)
+  NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLDetailsElement, details)
 
   nsIContent* GetFirstSummary() const;
 
   nsresult Clone(NodeInfo* aNodeInfo, nsINode** aResult,
                  bool aPreallocateChildren) const override;
 
   nsChangeHint GetAttributeChangeHint(const nsAtom* aAttribute,
                                       int32_t aModType) const override;
--- a/dom/html/HTMLDialogElement.h
+++ b/dom/html/HTMLDialogElement.h
@@ -17,17 +17,17 @@ namespace dom {
 
 class HTMLDialogElement final : public nsGenericHTMLElement
 {
 public:
   explicit HTMLDialogElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo) : nsGenericHTMLElement(aNodeInfo)
   {
   }
 
-  NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLDialogElement, dialog)
+  NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLDialogElement, dialog)
 
   virtual nsresult Clone(mozilla::dom::NodeInfo* aNodeInfo, nsINode** aResult,
                          bool aPreallocateChildren) const override;
 
   static bool IsDialogEnabled();
 
   bool Open() const { return GetBoolAttr(nsGkAtoms::open); }
   void SetOpen(bool aOpen, ErrorResult& aError)
--- a/dom/html/HTMLEmbedElement.h
+++ b/dom/html/HTMLEmbedElement.h
@@ -20,17 +20,17 @@ class HTMLEmbedElement final : public ns
                              , public nsObjectLoadingContent
 {
 public:
   explicit HTMLEmbedElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
                             mozilla::dom::FromParser aFromParser = mozilla::dom::NOT_FROM_PARSER);
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
-  NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLEmbedElement, embed)
+  NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLEmbedElement, embed)
   virtual int32_t TabIndexDefault() override;
 
 #ifdef XP_MACOSX
   // nsIDOMEventTarget
   NS_IMETHOD PostHandleEvent(EventChainPostVisitor& aVisitor) override;
 #endif
 
   // EventTarget
--- a/dom/html/HTMLFieldSetElement.cpp
+++ b/dom/html/HTMLFieldSetElement.cpp
@@ -258,17 +258,17 @@ HTMLFieldSetElement::RemoveChildNode(nsI
 
 void
 HTMLFieldSetElement::AddElement(nsGenericHTMLFormElement* aElement)
 {
   mDependentElements.AppendElement(aElement);
 
   // If the element that we are adding aElement is a fieldset, then all the
   // invalid elements in aElement are also invalid elements of this.
-  HTMLFieldSetElement* fieldSet = FromContent(aElement);
+  HTMLFieldSetElement* fieldSet = FromNode(aElement);
   if (fieldSet) {
     for (int32_t i = 0; i < fieldSet->mInvalidElementsCount; i++) {
       UpdateValidity(false);
     }
     return;
   }
 
   // We need to update the validity of the fieldset.
@@ -276,17 +276,17 @@ HTMLFieldSetElement::AddElement(nsGeneri
   if (cvElmt &&
       cvElmt->IsCandidateForConstraintValidation() && !cvElmt->IsValid()) {
     UpdateValidity(false);
   }
 
 #if DEBUG
   int32_t debugInvalidElementsCount = 0;
   for (uint32_t i = 0; i < mDependentElements.Length(); i++) {
-    HTMLFieldSetElement* fieldSet = FromContent(mDependentElements[i]);
+    HTMLFieldSetElement* fieldSet = FromNode(mDependentElements[i]);
     if (fieldSet) {
       debugInvalidElementsCount += fieldSet->mInvalidElementsCount;
       continue;
     }
     nsCOMPtr<nsIConstraintValidation>
       cvElmt = do_QueryObject(mDependentElements[i]);
     if (cvElmt &&
         cvElmt->IsCandidateForConstraintValidation() &&
@@ -300,17 +300,17 @@ HTMLFieldSetElement::AddElement(nsGeneri
 
 void
 HTMLFieldSetElement::RemoveElement(nsGenericHTMLFormElement* aElement)
 {
   mDependentElements.RemoveElement(aElement);
 
   // If the element that we are removing aElement is a fieldset, then all the
   // invalid elements in aElement are also removed from this.
-  HTMLFieldSetElement* fieldSet = FromContent(aElement);
+  HTMLFieldSetElement* fieldSet = FromNode(aElement);
   if (fieldSet) {
     for (int32_t i = 0; i < fieldSet->mInvalidElementsCount; i++) {
       UpdateValidity(true);
     }
     return;
   }
 
   // We need to update the validity of the fieldset.
@@ -318,17 +318,17 @@ HTMLFieldSetElement::RemoveElement(nsGen
   if (cvElmt &&
       cvElmt->IsCandidateForConstraintValidation() && !cvElmt->IsValid()) {
     UpdateValidity(true);
   }
 
 #if DEBUG
   int32_t debugInvalidElementsCount = 0;
   for (uint32_t i = 0; i < mDependentElements.Length(); i++) {
-    HTMLFieldSetElement* fieldSet = FromContent(mDependentElements[i]);
+    HTMLFieldSetElement* fieldSet = FromNode(mDependentElements[i]);
     if (fieldSet) {
       debugInvalidElementsCount += fieldSet->mInvalidElementsCount;
       continue;
     }
     nsCOMPtr<nsIConstraintValidation>
       cvElmt = do_QueryObject(mDependentElements[i]);
     if (cvElmt &&
         cvElmt->IsCandidateForConstraintValidation() &&
--- a/dom/html/HTMLFieldSetElement.h
+++ b/dom/html/HTMLFieldSetElement.h
@@ -22,17 +22,17 @@ class HTMLFieldSetElement final : public
 {
 public:
   using nsGenericHTMLFormElement::GetForm;
   using nsIConstraintValidation::GetValidationMessage;
   using nsIConstraintValidation::SetCustomValidity;
 
   explicit HTMLFieldSetElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
 
-  NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLFieldSetElement, fieldset)
+  NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLFieldSetElement, fieldset)
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIContent
   virtual nsresult GetEventTargetParent(
                      EventChainPreVisitor& aVisitor) override;
   virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
--- a/dom/html/HTMLFormElement.cpp
+++ b/dom/html/HTMLFormElement.cpp
@@ -1619,21 +1619,21 @@ HTMLFormElement::GetActionURL(nsIURI** a
   if (aOriginatingElement &&
       aOriginatingElement->HasAttr(kNameSpaceID_None, nsGkAtoms::formaction)) {
 #ifdef DEBUG
     nsCOMPtr<nsIFormControl> formControl = do_QueryInterface(aOriginatingElement);
     NS_ASSERTION(formControl && formControl->IsSubmitControl(),
                  "The originating element must be a submit form control!");
 #endif // DEBUG
 
-    HTMLInputElement* inputElement = HTMLInputElement::FromContent(aOriginatingElement);
+    HTMLInputElement* inputElement = HTMLInputElement::FromNode(aOriginatingElement);
     if (inputElement) {
       inputElement->GetFormAction(action);
     } else {
-      auto buttonElement = HTMLButtonElement::FromContent(aOriginatingElement);
+      auto buttonElement = HTMLButtonElement::FromNode(aOriginatingElement);
       if (buttonElement) {
         buttonElement->GetFormAction(action);
       } else {
         NS_ERROR("Originating element must be an input or button element!");
         return NS_ERROR_UNEXPECTED;
       }
     }
   } else {
@@ -2196,17 +2196,17 @@ HTMLFormElement::GetNextRadioButton(cons
     if (aPrevious) {
       if (--index < 0) {
         index = numRadios -1;
       }
     }
     else if (++index >= (int32_t)numRadios) {
       index = 0;
     }
-    radio = HTMLInputElement::FromContentOrNull(radioGroup->Item(index));
+    radio = HTMLInputElement::FromNodeOrNull(radioGroup->Item(index));
     isRadio = radio && radio->ControlType() == NS_FORM_INPUT_RADIO;
     if (!isRadio) {
       continue;
     }
 
     nsAutoString name;
     radio->GetName(name);
     isRadio = aName.Equals(name);
--- a/dom/html/HTMLFormElement.h
+++ b/dom/html/HTMLFormElement.h
@@ -37,17 +37,17 @@ class HTMLImageElement;
 class HTMLFormElement final : public nsGenericHTMLElement,
                               public nsIWebProgressListener,
                               public nsIForm,
                               public nsIRadioGroupContainer
 {
   friend class HTMLFormControlsCollection;
 
 public:
-  NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLFormElement, form)
+  NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLFormElement, form)
 
   explicit HTMLFormElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
 
   enum {
     FORM_CONTROL_LIST_HASHTABLE_LENGTH = 8
   };
 
   // nsISupports
--- a/dom/html/HTMLFrameElement.h
+++ b/dom/html/HTMLFrameElement.h
@@ -21,17 +21,17 @@ public:
 
   explicit HTMLFrameElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
                             FromParser aFromParser = NOT_FROM_PARSER);
 
   // nsISupports
   NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLFrameElement,
                                        nsGenericHTMLFrameElement)
 
-  NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLFrameElement, frame)
+  NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLFrameElement, frame)
 
   // nsIContent
   virtual bool ParseAttribute(int32_t aNamespaceID,
                               nsAtom* aAttribute,
                               const nsAString& aValue,
                               nsIPrincipal* aMaybeScriptedPrincipal,
                               nsAttrValue& aResult) override;
   virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,
--- a/dom/html/HTMLFrameSetElement.h
+++ b/dom/html/HTMLFrameSetElement.h
@@ -50,17 +50,17 @@ public:
     : nsGenericHTMLElement(aNodeInfo),
       mNumRows(0),
       mNumCols(0),
       mCurrentRowColHint(NS_STYLE_HINT_REFLOW)
   {
     SetHasWeirdParserInsertionMode();
   }
 
-  NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLFrameSetElement, frameset)
+  NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLFrameSetElement, frameset)
 
   // nsISupports
   NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLFrameSetElement,
                                        nsGenericHTMLElement)
 
   void GetCols(DOMString& aCols)
   {
     GetHTMLAttr(nsGkAtoms::cols, aCols);
--- a/dom/html/HTMLIFrameElement.h
+++ b/dom/html/HTMLIFrameElement.h
@@ -15,17 +15,17 @@ namespace mozilla {
 namespace dom {
 
 class HTMLIFrameElement final : public nsGenericHTMLFrameElement
 {
 public:
   explicit HTMLIFrameElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
                              FromParser aFromParser = NOT_FROM_PARSER);
 
-  NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLIFrameElement, iframe)
+  NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLIFrameElement, iframe)
 
   // nsISupports
   NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLIFrameElement,
                                        nsGenericHTMLFrameElement)
 
   // Element
   virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const override
   {
--- a/dom/html/HTMLImageElement.cpp
+++ b/dom/html/HTMLImageElement.cpp
@@ -1038,17 +1038,17 @@ HTMLImageElement::PictureSourceSrcsetCha
     mResponsiveSelector ? mResponsiveSelector->Content() : nullptr;
 
   if (aSourceNode == currentSrc) {
     // We're currently using this node as our responsive selector
     // source.
     nsCOMPtr<nsIPrincipal> principal;
     if (aSourceNode == this) {
       principal = mSrcsetTriggeringPrincipal;
-    } else if (auto* source = HTMLSourceElement::FromContent(aSourceNode)) {
+    } else if (auto* source = HTMLSourceElement::FromNode(aSourceNode)) {
       principal = source->GetSrcsetTriggeringPrincipal();
     }
     mResponsiveSelector->SetCandidatesFromSourceSet(aNewValue, principal);
   }
 
   if (!mInDocResponsiveContent && IsInComposedDoc()) {
     nsIDocument* doc = GetOurOwnerDoc();
     if (doc) {
@@ -1234,17 +1234,17 @@ HTMLImageElement::TryCreateResponsiveSel
   nsCOMPtr<nsIPrincipal> principal;
 
   // Skip if this is not a <source> with matching media query
   bool isSourceTag = aSourceElement->IsHTMLElement(nsGkAtoms::source);
   if (isSourceTag) {
     if (!SourceElementMatches(aSourceElement)) {
       return false;
     }
-    auto* source = HTMLSourceElement::FromContent(aSourceElement);
+    auto* source = HTMLSourceElement::FromNode(aSourceElement);
     principal = source->GetSrcsetTriggeringPrincipal();
   } else if (aSourceElement->IsHTMLElement(nsGkAtoms::img)) {
     // Otherwise this is the <img> tag itself
     MOZ_ASSERT(aSourceElement == this);
     principal = mSrcsetTriggeringPrincipal;
   }
 
   // Skip if has no srcset or an empty srcset
--- a/dom/html/HTMLImageElement.h
+++ b/dom/html/HTMLImageElement.h
@@ -44,17 +44,17 @@ public:
   virtual bool Draggable() const override;
 
   // Element
   virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const override;
 
   // EventTarget
   virtual void AsyncEventRunning(AsyncEventDispatcher* aEvent) override;
 
-  NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLImageElement, img)
+  NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLImageElement, img)
 
   // override from nsImageLoadingContent
   CORSMode GetCORSMode() override;
 
   // nsIContent
   virtual bool ParseAttribute(int32_t aNamespaceID,
                                 nsAtom* aAttribute,
                                 const nsAString& aValue,
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -2460,17 +2460,17 @@ HTMLInputElement::MozIsTextField(bool aE
 
 HTMLInputElement*
 HTMLInputElement::GetOwnerNumberControl()
 {
   if (IsInNativeAnonymousSubtree() &&
       mType == NS_FORM_INPUT_TEXT &&
       GetParent() && GetParent()->GetParent()) {
     HTMLInputElement* grandparent =
-      HTMLInputElement::FromContentOrNull(GetParent()->GetParent());
+      HTMLInputElement::FromNodeOrNull(GetParent()->GetParent());
     if (grandparent && grandparent->mType == NS_FORM_INPUT_NUMBER) {
       return grandparent;
     }
   }
   return nullptr;
 }
 
 void
@@ -4239,17 +4239,17 @@ HTMLInputElement::PostHandleEvent(EventC
   if (mCheckedIsToggled && outerActivateEvent) {
     if (aVisitor.mEventStatus == nsEventStatus_eConsumeNoDefault) {
       // if it was cancelled and a radio button, then set the old
       // selected btn to TRUE. if it is a checkbox then set it to its
       // original value
       if (oldType == NS_FORM_INPUT_RADIO) {
         nsCOMPtr<nsIContent> content = do_QueryInterface(aVisitor.mItemData);
         HTMLInputElement* selectedRadioButton =
-          HTMLInputElement::FromContentOrNull(content);
+          HTMLInputElement::FromNodeOrNull(content);
         if (selectedRadioButton) {
           selectedRadioButton->SetChecked(true);
         }
         // If there was no checked radio button or this one is no longer a
         // radio button we must reset it back to false to cancel the action.
         // See how the web of hack grows?
         if (!selectedRadioButton || mType != NS_FORM_INPUT_RADIO) {
           DoSetChecked(false, true, true);
@@ -4275,17 +4275,17 @@ HTMLInputElement::PostHandleEvent(EventC
         FireEventForAccessibility(this, aVisitor.mPresContext,
                                   eFormCheckboxStateChange);
       } else {
         FireEventForAccessibility(this, aVisitor.mPresContext,
                                   eFormRadioStateChange);
         // Fire event for the previous selected radio.
         nsCOMPtr<nsIContent> content = do_QueryInterface(aVisitor.mItemData);
         HTMLInputElement* previous =
-          HTMLInputElement::FromContentOrNull(content);
+          HTMLInputElement::FromNodeOrNull(content);
         if (previous) {
           FireEventForAccessibility(previous, aVisitor.mPresContext,
                                     eFormRadioStateChange);
         }
       }
 #endif
     }
   }
--- a/dom/html/HTMLInputElement.h
+++ b/dom/html/HTMLInputElement.h
@@ -140,17 +140,17 @@ public:
   using nsGenericHTMLFormElementWithState::GetFormAction;
 
   enum class FromClone { no, yes };
 
   HTMLInputElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
                    mozilla::dom::FromParser aFromParser,
                    FromClone aFromClone = FromClone::no);
 
-  NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLInputElement, input)
+  NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLInputElement, input)
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   virtual int32_t TabIndexDefault() override;
   using nsGenericHTMLElement::Focus;
   virtual void Blur(ErrorResult& aError) override;
   virtual void Focus(ErrorResult& aError) override;
--- a/dom/html/HTMLLabelElement.h
+++ b/dom/html/HTMLLabelElement.h
@@ -21,17 +21,17 @@ class HTMLLabelElement final : public ns
 {
 public:
   explicit HTMLLabelElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
     : nsGenericHTMLElement(aNodeInfo),
       mHandlingEvent(false)
   {
   }
 
-  NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLLabelElement, label)
+  NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLLabelElement, label)
 
   // nsISupports
   NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLLabelElement, nsGenericHTMLElement)
 
   // Element
   virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const override
   {
     return true;
--- a/dom/html/HTMLLegendElement.h
+++ b/dom/html/HTMLLegendElement.h
@@ -17,17 +17,17 @@ namespace dom {
 class HTMLLegendElement final : public nsGenericHTMLElement
 {
 public:
   explicit HTMLLegendElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
     : nsGenericHTMLElement(aNodeInfo)
   {
   }
 
-  NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLLegendElement, legend)
+  NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLLegendElement, legend)
 
   using nsGenericHTMLElement::Focus;
   virtual void Focus(ErrorResult& aError) override;
 
   virtual bool PerformAccesskey(bool aKeyCausesActivation,
                                 bool aIsTrustedEvent) override;
 
   // nsIContent
--- a/dom/html/HTMLLinkElement.h
+++ b/dom/html/HTMLLinkElement.h
@@ -26,17 +26,17 @@ public:
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // CC
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLLinkElement,
                                            nsGenericHTMLElement)
 
-  NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLLinkElement, link);
+  NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLLinkElement, link);
   NS_DECL_ADDSIZEOFEXCLUDINGTHIS
 
   void LinkAdded();
   void LinkRemoved();
 
   // nsIDOMEventTarget
   virtual nsresult GetEventTargetParent(
                      EventChainPreVisitor& aVisitor) override;
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -2392,17 +2392,17 @@ void HTMLMediaElement::LoadFromSourceChi
         OwnerDoc(), type, canPlay != CANPLAY_NO, __func__);
       if (canPlay == CANPLAY_NO) {
         const char16_t* params[] = { type.get(), src.get() };
         ReportLoadError("MediaLoadUnsupportedTypeAttribute", params, ArrayLength(params));
         DealWithFailedElement(child);
         return;
       }
     }
-    HTMLSourceElement *childSrc = HTMLSourceElement::FromContent(child);
+    HTMLSourceElement *childSrc = HTMLSourceElement::FromNode(child);
     LOG(LogLevel::Debug, ("%p Trying load from <source>=%s type=%s", this,
       NS_ConvertUTF16toUTF8(src).get(), NS_ConvertUTF16toUTF8(type).get()));
 
     nsCOMPtr<nsIURI> uri;
     NewURIFromString(src, getter_AddRefs(uri));
     if (!uri) {
       const char16_t* params[] = { src.get() };
       ReportLoadError("MediaLoadInvalidURI", params, ArrayLength(params));
@@ -4506,17 +4506,17 @@ HTMLMediaElement::ReportTelemetry()
     }
   }
 
   Telemetry::Accumulate(Telemetry::VIDEO_UNLOAD_STATE, state);
   LOG(LogLevel::Debug, ("%p VIDEO_UNLOAD_STATE = %d", this, state));
 
   FrameStatisticsData data;
 
-  if (HTMLVideoElement* vid = HTMLVideoElement::FromContentOrNull(this)) {
+  if (HTMLVideoElement* vid = HTMLVideoElement::FromNodeOrNull(this)) {
     FrameStatistics* stats = vid->GetFrameStatistics();
     if (stats) {
       data = stats->GetFrameStatisticsData();
       if (data.mParsedFrames) {
         MOZ_ASSERT(data.mDroppedFrames <= data.mParsedFrames);
         // Dropped frames <= total frames, so 'percentage' cannot be higher than
         // 100 and therefore can fit in a uint32_t (that Telemetry takes).
         uint32_t percentage = 100 * data.mDroppedFrames / data.mParsedFrames;
--- a/dom/html/HTMLMediaElement.h
+++ b/dom/html/HTMLMediaElement.h
@@ -134,17 +134,17 @@ public:
    * notifications for the stream
    */
   nsresult LoadWithChannel(nsIChannel *aChannel, nsIStreamListener **aListener);
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLMediaElement,
                                            nsGenericHTMLElement)
-  NS_IMPL_FROMCONTENT_HELPER(HTMLMediaElement,
+  NS_IMPL_FROMNODE_HELPER(HTMLMediaElement,
                              IsAnyOfHTMLElements(nsGkAtoms::video,
                                                  nsGkAtoms::audio))
 
   // nsIDOMEventTarget
   virtual nsresult
   GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
 
   virtual bool ParseAttribute(int32_t aNamespaceID,