Merge mozilla-inbound to mozilla-central. a=merge
authorAndreea Pavel <apavel@mozilla.com>
Thu, 22 Mar 2018 11:31:19 +0200
changeset 409462 7771df14ea181add1dc4133f0f5559bf620bf976
parent 409461 f82d56c64966a27cd87ab53025ebc774936b3657 (current diff)
parent 409406 912c50cd3b665c2048174079b817bf6381cf7803 (diff)
child 409463 9dd29f87106500717371eb180fff29bf1b9d5f2a
child 409549 96a4b10d1b2f5df7a82da3f78287e5d397875f1c
child 409597 8e52cfef41eb0283b40e88b051d4f0f3f84751f4
push id101201
push userapavel@mozilla.com
push dateThu, 22 Mar 2018 09:36:03 +0000
treeherdermozilla-inbound@9dd29f871065 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone61.0a1
first release with
nightly linux32
7771df14ea18 / 61.0a1 / 20180322100349 / files
nightly linux64
7771df14ea18 / 61.0a1 / 20180322100349 / files
nightly mac
7771df14ea18 / 61.0a1 / 20180322100349 / files
nightly win32
7771df14ea18 / 61.0a1 / 20180322100349 / files
nightly win64
7771df14ea18 / 61.0a1 / 20180322100349 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge 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,
--- a/dom/html/HTMLMenuElement.cpp
+++ b/dom/html/HTMLMenuElement.cpp
@@ -180,23 +180,23 @@ HTMLMenuElement::CanLoadIcon(nsIContent*
 void
 HTMLMenuElement::TraverseContent(nsIContent* aContent,
                                  nsIMenuBuilder* aBuilder,
                                  int8_t& aSeparator)
 {
   nsCOMPtr<nsIContent> child;
   for (child = aContent->GetFirstChild(); child;
        child = child->GetNextSibling()) {
-    nsGenericHTMLElement* element = nsGenericHTMLElement::FromContent(child);
+    nsGenericHTMLElement* element = nsGenericHTMLElement::FromNode(child);
     if (!element) {
       continue;
     }
 
     if (child->IsHTMLElement(nsGkAtoms::menuitem)) {
-      HTMLMenuItemElement* menuitem = HTMLMenuItemElement::FromContent(child);
+      HTMLMenuItemElement* menuitem = HTMLMenuItemElement::FromNode(child);
 
       if (menuitem->IsHidden()) {
         continue;
       }
 
       nsAutoString label;
       menuitem->GetLabel(label);
       if (label.IsEmpty()) {
--- a/dom/html/HTMLMenuElement.h
+++ b/dom/html/HTMLMenuElement.h
@@ -15,17 +15,17 @@ class nsIMenuBuilder;
 namespace mozilla {
 namespace dom {
 
 class HTMLMenuElement final : public nsGenericHTMLElement
 {
 public:
   explicit HTMLMenuElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
 
-  NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLMenuElement, menu)
+  NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLMenuElement, menu)
 
   // nsISupports
   NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLMenuElement, nsGenericHTMLElement)
 
   virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsAtom* aName,
                                 const nsAttrValue* aValue,
                                 const nsAttrValue* aOldValue,
                                 nsIPrincipal* aSubjectPrincipal,
--- a/dom/html/HTMLMenuItemElement.cpp
+++ b/dom/html/HTMLMenuItemElement.cpp
@@ -279,17 +279,17 @@ HTMLMenuItemElement::PostHandleEvent(Eve
   if (aVisitor.mEvent->mMessage == eMouseClick &&
       aVisitor.mItemFlags & NS_CHECKED_IS_TOGGLED &&
       aVisitor.mEventStatus == nsEventStatus_eConsumeNoDefault) {
     bool originalCheckedValue =