Backed out 2 changesets (bug 1423167) for build bustage on OSX and Windows on a CLOSED TREE
authorGurzau Raul <rgurzau@mozilla.com>
Wed, 06 Dec 2017 12:18:24 +0200
changeset 395241 70b8084a6d191bfde4a6f52be1bbdebd76105712
parent 395240 a83339d160f144645852d80a4fda04c48f7119bb
child 395242 0966f2eb06c5178d001df03895c70a52de847552
push id33037
push userdluca@mozilla.com
push dateWed, 06 Dec 2017 21:58:29 +0000
treeherdermozilla-central@155c25df7f18 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1423167
milestone59.0a1
backs outa83339d160f144645852d80a4fda04c48f7119bb
a27e933a27b65f220dabf6a5949ce15003485fd6
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out 2 changesets (bug 1423167) for build bustage on OSX and Windows on a CLOSED TREE Backed out changeset a83339d160f1 (bug 1423167) Backed out changeset a27e933a27b6 (bug 1423167)
accessible/base/ARIAMap.cpp
accessible/base/ARIAMap.h
accessible/base/nsAccessibilityService.cpp
accessible/generic/ARIAGridAccessible.cpp
accessible/generic/Accessible.cpp
accessible/html/HTMLSelectAccessible.cpp
accessible/xul/XULSliderAccessible.cpp
accessible/xul/XULSliderAccessible.h
dom/base/DocumentFragment.h
dom/base/Element.h
dom/base/FragmentOrElement.cpp
dom/base/FragmentOrElement.h
dom/base/nsContentCreatorFunctions.h
dom/base/nsContentUtils.cpp
dom/base/nsDocument.cpp
dom/base/nsGenericDOMDataNode.cpp
dom/base/nsGenericDOMDataNode.h
dom/base/nsHTMLContentSerializer.cpp
dom/base/nsHTMLContentSerializer.h
dom/base/nsIContent.h
dom/base/nsINode.cpp
dom/base/nsIdentifierMapEntry.h
dom/base/nsMappedAttributeElement.h
dom/base/nsObjectLoadingContent.cpp
dom/base/nsTreeSanitizer.cpp
dom/base/nsTreeSanitizer.h
dom/base/nsXHTMLContentSerializer.cpp
dom/base/nsXHTMLContentSerializer.h
dom/base/nsXMLContentSerializer.cpp
dom/base/nsXMLContentSerializer.h
dom/svg/SVGAElement.h
dom/svg/SVGStyleElement.h
dom/xbl/nsXBLBinding.cpp
dom/xbl/nsXBLBinding.h
dom/xbl/nsXBLContentSink.cpp
dom/xbl/nsXBLContentSink.h
dom/xbl/nsXBLPrototypeBinding.cpp
dom/xbl/nsXBLPrototypeBinding.h
dom/xbl/nsXBLService.cpp
dom/xbl/nsXBLService.h
dom/xml/nsXMLContentSink.cpp
dom/xml/nsXMLContentSink.h
dom/xml/nsXMLPrettyPrinter.cpp
dom/xslt/xpath/txMozillaXPathTreeWalker.cpp
dom/xslt/xslt/txMozillaTextOutput.cpp
dom/xslt/xslt/txMozillaTextOutput.h
dom/xslt/xslt/txMozillaXMLOutput.cpp
dom/xslt/xslt/txMozillaXMLOutput.h
dom/xul/XULDocument.cpp
dom/xul/XULDocument.h
dom/xul/nsIXULDocument.h
dom/xul/nsXULElement.cpp
dom/xul/nsXULElement.h
dom/xul/templates/nsIXULTemplateBuilder.idl
dom/xul/templates/nsXULContentBuilder.cpp
dom/xul/templates/nsXULContentUtils.cpp
dom/xul/templates/nsXULContentUtils.h
dom/xul/templates/nsXULSortService.cpp
dom/xul/templates/nsXULSortService.h
dom/xul/templates/nsXULTemplateBuilder.cpp
dom/xul/templates/nsXULTemplateBuilder.h
dom/xul/templates/nsXULTemplateQueryProcessorRDF.cpp
dom/xul/templates/nsXULTemplateQueryProcessorRDF.h
dom/xul/templates/nsXULTreeBuilder.cpp
dom/xul/templates/nsXULTreeBuilder.h
editor/libeditor/EditorBase.cpp
editor/libeditor/HTMLEditor.h
editor/libeditor/HTMLStyleEditor.cpp
editor/libeditor/TextEditRules.cpp
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
layout/forms/nsButtonFrameRenderer.cpp
layout/forms/nsComboboxControlFrame.h
layout/forms/nsDateTimeControlFrame.h
layout/forms/nsFileControlFrame.h
layout/forms/nsHTMLButtonControlFrame.cpp
layout/generic/ScrollbarActivity.cpp
layout/generic/ScrollbarActivity.h
layout/generic/nsFrameSetFrame.cpp
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsGfxScrollFrame.h
layout/generic/nsVideoFrame.cpp
layout/generic/nsVideoFrame.h
layout/mathml/nsMathMLmactionFrame.cpp
layout/xul/PopupBoxObject.cpp
layout/xul/nsDeckFrame.cpp
layout/xul/nsIRootBox.h
layout/xul/nsMenuFrame.cpp
layout/xul/nsMenuPopupFrame.cpp
layout/xul/nsProgressMeterFrame.cpp
layout/xul/nsResizerFrame.cpp
layout/xul/nsRootBoxFrame.cpp
layout/xul/nsScrollbarButtonFrame.cpp
layout/xul/nsScrollbarFrame.cpp
layout/xul/nsSliderFrame.cpp
layout/xul/nsSplitterFrame.cpp
layout/xul/nsXULPopupManager.cpp
layout/xul/nsXULPopupManager.h
layout/xul/nsXULTooltipListener.cpp
layout/xul/tree/nsTreeBodyFrame.cpp
layout/xul/tree/nsTreeBodyFrame.h
layout/xul/tree/nsTreeColumns.cpp
layout/xul/tree/nsTreeContentView.cpp
layout/xul/tree/nsTreeContentView.h
layout/xul/tree/nsTreeUtils.cpp
layout/xul/tree/nsTreeUtils.h
parser/html/nsHtml5TreeOperation.cpp
--- a/accessible/base/ARIAMap.cpp
+++ b/accessible/base/ARIAMap.cpp
@@ -1381,40 +1381,40 @@ aria::HasDefinedARIAHidden(nsIContent* a
 
 ////////////////////////////////////////////////////////////////////////////////
 // AttrIterator class
 
 bool
 AttrIterator::Next(nsAString& aAttrName, nsAString& aAttrValue)
 {
   while (mAttrIdx < mAttrCount) {
-    const nsAttrName* attr = mElement->GetAttrNameAt(mAttrIdx);
+    const nsAttrName* attr = mContent->GetAttrNameAt(mAttrIdx);
     mAttrIdx++;
     if (attr->NamespaceEquals(kNameSpaceID_None)) {
       nsAtom* attrAtom = attr->Atom();
       nsDependentAtomString attrStr(attrAtom);
       if (!StringBeginsWith(attrStr, NS_LITERAL_STRING("aria-")))
         continue; // Not ARIA
 
       uint8_t attrFlags = aria::AttrCharacteristicsFor(attrAtom);
       if (attrFlags & ATTR_BYPASSOBJ)
         continue; // No need to handle exposing as obj attribute here
 
       if ((attrFlags & ATTR_VALTOKEN) &&
-           !nsAccUtils::HasDefinedARIAToken(mElement, attrAtom))
+           !nsAccUtils::HasDefinedARIAToken(mContent, attrAtom))
         continue; // only expose token based attributes if they are defined
 
       if ((attrFlags & ATTR_BYPASSOBJ_IF_FALSE) &&
-          mElement->AttrValueIs(kNameSpaceID_None, attrAtom,
+          mContent->AttrValueIs(kNameSpaceID_None, attrAtom,
                                 nsGkAtoms::_false, eCaseMatters)) {
         continue; // only expose token based attribute if value is not 'false'.
       }
 
       nsAutoString value;
-      if (mElement->GetAttr(kNameSpaceID_None, attrAtom, value)) {
+      if (mContent->GetAttr(kNameSpaceID_None, attrAtom, value)) {
         aAttrName.Assign(Substring(attrStr, 5));
         aAttrValue.Assign(value);
         return true;
       }
     }
   }
 
   return false;
--- a/accessible/base/ARIAMap.h
+++ b/accessible/base/ARIAMap.h
@@ -9,17 +9,16 @@
 #define mozilla_a11y_aria_ARIAMap_h_
 
 #include "ARIAStateMap.h"
 #include "mozilla/a11y/AccTypes.h"
 #include "mozilla/a11y/Role.h"
 
 #include "nsAtom.h"
 #include "nsIContent.h"
-#include "mozilla/dom/Element.h"
 
 class nsINode;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Value constants
 
 /**
  * Used to define if role requires to expose Value interface.
@@ -284,31 +283,30 @@ bool HasDefinedARIAHidden(nsIContent* aC
 
  /**
   * Represents a simple enumerator for iterating through ARIA attributes
   * exposed as object attributes on a given accessible.
   */
 class AttrIterator
 {
 public:
-  explicit AttrIterator(nsIContent* aContent)
-    : mElement(aContent->IsElement() ? aContent->AsElement() : nullptr)
-    , mAttrIdx(0)
+  explicit AttrIterator(nsIContent* aContent) :
+    mContent(aContent), mAttrIdx(0)
   {
-    mAttrCount = mElement ? mElement->GetAttrCount() : 0;
+    mAttrCount = mContent->GetAttrCount();
   }
 
   bool Next(nsAString& aAttrName, nsAString& aAttrValue);
 
 private:
   AttrIterator() = delete;
   AttrIterator(const AttrIterator&) = delete;
   AttrIterator& operator= (const AttrIterator&) = delete;
 
-  dom::Element* mElement;
+  nsIContent* mContent;
   uint32_t mAttrIdx;
   uint32_t mAttrCount;
 };
 
 } // namespace aria
 } // namespace a11y
 } // namespace mozilla
 
--- a/accessible/base/nsAccessibilityService.cpp
+++ b/accessible/base/nsAccessibilityService.cpp
@@ -109,32 +109,30 @@ using namespace mozilla::dom;
  * Return true if the element must be accessible.
  */
 static bool
 MustBeAccessible(nsIContent* aContent, DocAccessible* aDocument)
 {
   if (aContent->GetPrimaryFrame()->IsFocusable())
     return true;
 
-  if (aContent->IsElement()) {
-    uint32_t attrCount = aContent->AsElement()->GetAttrCount();
-    for (uint32_t attrIdx = 0; attrIdx < attrCount; attrIdx++) {
-      const nsAttrName* attr = aContent->AsElement()->GetAttrNameAt(attrIdx);
-      if (attr->NamespaceEquals(kNameSpaceID_None)) {
-        nsAtom* attrAtom = attr->Atom();
-        nsDependentAtomString attrStr(attrAtom);
-        if (!StringBeginsWith(attrStr, NS_LITERAL_STRING("aria-")))
-          continue; // not ARIA
+  uint32_t attrCount = aContent->GetAttrCount();
+  for (uint32_t attrIdx = 0; attrIdx < attrCount; attrIdx++) {
+    const nsAttrName* attr = aContent->GetAttrNameAt(attrIdx);
+    if (attr->NamespaceEquals(kNameSpaceID_None)) {
+      nsAtom* attrAtom = attr->Atom();
+      nsDependentAtomString attrStr(attrAtom);
+      if (!StringBeginsWith(attrStr, NS_LITERAL_STRING("aria-")))
+        continue; // not ARIA
 
-        // A global state or a property and in case of token defined.
-        uint8_t attrFlags = aria::AttrCharacteristicsFor(attrAtom);
-        if ((attrFlags & ATTR_GLOBAL) && (!(attrFlags & ATTR_VALTOKEN) ||
-             nsAccUtils::HasDefinedARIAToken(aContent, attrAtom))) {
-          return true;
-        }
+      // A global state or a property and in case of token defined.
+      uint8_t attrFlags = aria::AttrCharacteristicsFor(attrAtom);
+      if ((attrFlags & ATTR_GLOBAL) && (!(attrFlags & ATTR_VALTOKEN) ||
+           nsAccUtils::HasDefinedARIAToken(aContent, attrAtom))) {
+        return true;
       }
     }
   }
 
   // If the given ID is referred by relation attribute then create an accessible
   // for it.
   nsAutoString id;
   if (nsCoreUtils::GetID(aContent, id) && !id.IsEmpty())
--- a/accessible/generic/ARIAGridAccessible.cpp
+++ b/accessible/generic/ARIAGridAccessible.cpp
@@ -460,28 +460,26 @@ ARIAGridAccessible::GetCellInRowAt(Acces
 
 nsresult
 ARIAGridAccessible::SetARIASelected(Accessible* aAccessible,
                                     bool aIsSelected, bool aNotify)
 {
   if (IsARIARole(nsGkAtoms::table))
     return NS_OK;
 
-  nsIContent* content = aAccessible->GetContent();
+  nsIContent *content = aAccessible->GetContent();
   NS_ENSURE_STATE(content);
 
   nsresult rv = NS_OK;
-  if (content->IsElement()) {
-    if (aIsSelected)
-      rv = content->AsElement()->SetAttr(kNameSpaceID_None, nsGkAtoms::aria_selected,
-                                         NS_LITERAL_STRING("true"), aNotify);
-    else
-      rv = content->AsElement()->SetAttr(kNameSpaceID_None, nsGkAtoms::aria_selected,
-                                         NS_LITERAL_STRING("false"), aNotify);
-  }
+  if (aIsSelected)
+    rv = content->SetAttr(kNameSpaceID_None, nsGkAtoms::aria_selected,
+                          NS_LITERAL_STRING("true"), aNotify);
+  else
+    rv = content->SetAttr(kNameSpaceID_None, nsGkAtoms::aria_selected,
+                          NS_LITERAL_STRING("false"), aNotify);
 
   NS_ENSURE_SUCCESS(rv, rv);
 
   // No "smart" select/unselect for internal call.
   if (!aNotify)
     return NS_OK;
 
   // If row or cell accessible was selected then we're able to not bother about
--- a/accessible/generic/Accessible.cpp
+++ b/accessible/generic/Accessible.cpp
@@ -699,24 +699,22 @@ void
 Accessible::SetSelected(bool aSelect)
 {
   if (!HasOwnContent())
     return;
 
   Accessible* select = nsAccUtils::GetSelectableContainer(this, State());
   if (select) {
     if (select->State() & states::MULTISELECTABLE) {
-      if (mContent->IsElement() && ARIARoleMap()) {
+      if (ARIARoleMap()) {
         if (aSelect) {
-          mContent->AsElement()->SetAttr(kNameSpaceID_None,
-                                         nsGkAtoms::aria_selected,
-                                         NS_LITERAL_STRING("true"), true);
+          mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::aria_selected,
+                            NS_LITERAL_STRING("true"), true);
         } else {
-          mContent->AsElement()->UnsetAttr(kNameSpaceID_None,
-                                           nsGkAtoms::aria_selected, true);
+          mContent->UnsetAttr(kNameSpaceID_None, nsGkAtoms::aria_selected, true);
         }
       }
       return;
     }
 
     if (aSelect)
       TakeFocus();
   }
@@ -1413,22 +1411,18 @@ Accessible::SetCurValue(double aValue)
 
   checkValue = MaxValue();
   if (!IsNaN(checkValue) && aValue > checkValue)
     return false;
 
   nsAutoString strValue;
   strValue.AppendFloat(aValue);
 
-  if (!mContent->IsElement())
-    return true;
-
   return NS_SUCCEEDED(
-    mContent->AsElement()->SetAttr(kNameSpaceID_None, nsGkAtoms::aria_valuenow,
-                                   strValue, true));
+    mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::aria_valuenow, strValue, true));
 }
 
 role
 Accessible::ARIATransformRole(role aRole)
 {
   // Beginning with ARIA 1.1, user agents are expected to use the native host
   // language role of the element when the region role is used without a name.
   // https://rawgit.com/w3c/aria/master/core-aam/core-aam.html#role-map-region
@@ -2571,20 +2565,18 @@ Accessible::CurrentItem()
 
 void
 Accessible::SetCurrentItem(Accessible* aItem)
 {
   nsAtom* id = aItem->GetContent()->GetID();
   if (id) {
     nsAutoString idStr;
     id->ToString(idStr);
-    mContent->AsElement()->SetAttr(kNameSpaceID_None,
-                                   nsGkAtoms::aria_activedescendant,
-                                   idStr,
-                                   true);
+    mContent->SetAttr(kNameSpaceID_None,
+                      nsGkAtoms::aria_activedescendant, idStr, true);
   }
 }
 
 Accessible*
 Accessible::ContainerWidget() const
 {
   if (HasARIARole() && mContent->HasID()) {
     for (Accessible* parent = Parent(); parent; parent = parent->Parent()) {
--- a/accessible/html/HTMLSelectAccessible.cpp
+++ b/accessible/html/HTMLSelectAccessible.cpp
@@ -105,23 +105,19 @@ HTMLSelectListAccessible::CurrentItem()
     }
   }
   return nullptr;
 }
 
 void
 HTMLSelectListAccessible::SetCurrentItem(Accessible* aItem)
 {
-  if (!aItem->GetContent()->IsElement())
-    return;
-
-  aItem->GetContent()->AsElement()->SetAttr(kNameSpaceID_None,
-                                            nsGkAtoms::selected,
-                                            NS_LITERAL_STRING("true"),
-                                            true);
+  aItem->GetContent()->SetAttr(kNameSpaceID_None,
+                               nsGkAtoms::selected, NS_LITERAL_STRING("true"),
+                               true);
 }
 
 bool
 HTMLSelectListAccessible::IsAcceptableChild(nsIContent* aEl) const
 {
   return aEl->IsAnyOfHTMLElements(nsGkAtoms::option, nsGkAtoms::optgroup);
 }
 
--- a/accessible/xul/XULSliderAccessible.cpp
+++ b/accessible/xul/XULSliderAccessible.cpp
@@ -8,18 +8,17 @@
 #include "nsAccessibilityService.h"
 #include "Role.h"
 #include "States.h"
 
 #include "nsIFrame.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/FloatingPoint.h"
 
-namespace mozilla {
-namespace a11y {
+using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
 // XULSliderAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 XULSliderAccessible::
   XULSliderAccessible(nsIContent* aContent, DocAccessible* aDoc) :
   AccessibleWrap(aContent, aDoc)
@@ -36,17 +35,17 @@ XULSliderAccessible::NativeRole()
 }
 
 uint64_t
 XULSliderAccessible::NativeInteractiveState() const
  {
   if (NativelyUnavailable())
     return states::UNAVAILABLE;
 
-  dom::Element* sliderElm = GetSliderElement();
+  nsIContent* sliderElm = GetSliderElement();
   if (sliderElm) {
     nsIFrame* frame = sliderElm->GetPrimaryFrame();
     if (frame && frame->IsFocusable())
       return states::FOCUSABLE;
   }
 
   return 0;
 }
@@ -79,17 +78,17 @@ XULSliderAccessible::ActionNameAt(uint8_
 }
 
 bool
 XULSliderAccessible::DoAction(uint8_t aIndex)
 {
   if (aIndex != 0)
     return false;
 
-  dom::Element* sliderElm = GetSliderElement();
+  nsIContent* sliderElm = GetSliderElement();
   if (sliderElm)
     DoCommand(sliderElm);
 
   return true;
 }
 
 double
 XULSliderAccessible::MaxValue() const
@@ -125,27 +124,27 @@ XULSliderAccessible::SetCurValue(double 
   if (AccessibleWrap::SetCurValue(aValue))
     return true;
 
   return SetSliderAttr(nsGkAtoms::curpos, aValue);
 }
 
 // Utils
 
-dom::Element*
+nsIContent*
 XULSliderAccessible::GetSliderElement() const
 {
-  if (!mSliderElement) {
+  if (!mSliderNode) {
     // XXX: we depend on anonymous content.
-    mSliderElement = mContent->OwnerDoc()->
+    mSliderNode = mContent->OwnerDoc()->
       GetAnonymousElementByAttribute(mContent, nsGkAtoms::anonid,
                                      NS_LITERAL_STRING("slider"));
   }
 
-  return mSliderElement;
+  return mSliderNode;
 }
 
 nsresult
 XULSliderAccessible::GetSliderAttr(nsAtom* aName, nsAString& aValue) const
 {
   aValue.Truncate();
 
   if (IsDefunct())
@@ -159,17 +158,18 @@ XULSliderAccessible::GetSliderAttr(nsAto
 }
 
 nsresult
 XULSliderAccessible::SetSliderAttr(nsAtom* aName, const nsAString& aValue)
 {
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  if (dom::Element* sliderElm = GetSliderElement())
+  nsIContent* sliderElm = GetSliderElement();
+  if (sliderElm)
     sliderElm->SetAttr(kNameSpaceID_None, aName, aValue, true);
 
   return NS_OK;
 }
 
 double
 XULSliderAccessible::GetSliderAttr(nsAtom* aName) const
 {
@@ -207,10 +207,8 @@ XULThumbAccessible::
 // XULThumbAccessible: Accessible
 
 role
 XULThumbAccessible::NativeRole()
 {
   return roles::INDICATOR;
 }
 
-}
-}
--- a/accessible/xul/XULSliderAccessible.h
+++ b/accessible/xul/XULSliderAccessible.h
@@ -38,26 +38,26 @@ public:
   virtual uint8_t ActionCount() override;
   virtual void ActionNameAt(uint8_t aIndex, nsAString& aName) override;
   virtual bool DoAction(uint8_t aIndex) override;
 
 protected:
   /**
    * Return anonymous slider element.
    */
-  dom::Element* GetSliderElement() const;
+  nsIContent* GetSliderElement() const;
 
   nsresult GetSliderAttr(nsAtom *aName, nsAString& aValue) const;
   nsresult SetSliderAttr(nsAtom *aName, const nsAString& aValue);
 
   double GetSliderAttr(nsAtom *aName) const;
   bool SetSliderAttr(nsAtom *aName, double aValue);
 
 private:
-  mutable RefPtr<dom::Element> mSliderElement;
+  mutable nsCOMPtr<nsIContent> mSliderNode;
 };
 
 
 /**
  * Used for slider's thumb element.
  */
 class XULThumbAccessible : public AccessibleWrap
 {
--- a/dom/base/DocumentFragment.h
+++ b/dom/base/DocumentFragment.h
@@ -64,16 +64,43 @@ public:
                                             nsIDOMNode::DOCUMENT_FRAGMENT_NODE)),
       mHost(nullptr)
   {
     Init();
   }
 
   virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
 
+  // nsIContent
+  using nsIContent::SetAttr;
+  virtual nsresult SetAttr(int32_t aNameSpaceID, nsAtom* aName,
+                           nsAtom* aPrefix, const nsAString& aValue,
+                           nsIPrincipal* aSubjectPrincipal,
+                           bool aNotify) override
+  {
+    return NS_OK;
+  }
+  virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsAtom* aAttribute,
+                             bool aNotify) override
+  {
+    return NS_OK;
+  }
+  virtual const nsAttrName* GetAttrNameAt(uint32_t aIndex) const override
+  {
+    return nullptr;
+  }
+  virtual BorrowedAttrInfo GetAttrInfoAt(uint32_t aIndex) const override
+  {
+    return BorrowedAttrInfo(nullptr, nullptr);
+  }
+  virtual uint32_t GetAttrCount() const override
+  {
+    return 0;
+  }
+
   virtual bool IsNodeOfType(uint32_t aFlags) const override;
 
   virtual nsIDOMNode* AsDOMNode() override { return this; }
 
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               bool aCompileEventHandlers) override
   {
--- a/dom/base/Element.h
+++ b/dom/base/Element.h
@@ -425,21 +425,16 @@ public:
    * Get a hint that tells the style system what to do when
    * an attribute on this node changes, if something needs to happen
    * in response to the change *other* than the result of what is
    * mapped into style data via any type of style rule.
    */
   virtual nsChangeHint GetAttributeChangeHint(const nsAtom* aAttribute,
                                               int32_t aModType) const;
 
-  virtual nsresult WalkContentStyleRules(nsRuleWalker* aRuleWalker)
-  {
-    return NS_OK;
-  }
-
   inline Directionality GetDirectionality() const {
     if (HasFlag(NODE_HAS_DIRECTION_RTL)) {
       return eDir_RTL;
     }
 
     if (HasFlag(NODE_HAS_DIRECTION_LTR)) {
       return eDir_LTR;
     }
@@ -697,16 +692,18 @@ public:
    * null otherwise.
    *
    * @param aStr the unparsed attribute string
    * @return the node info. May be nullptr.
    */
   already_AddRefed<mozilla::dom::NodeInfo>
   GetExistingAttrNameFromQName(const nsAString& aStr) const;
 
+  using nsIContent::SetAttr;
+
   /**
    * Helper for SetAttr/SetParsedAttr. This method will return true if aNotify
    * is true or there are mutation listeners that must be triggered, the
    * attribute is currently set, and the new value that is about to be set is
    * different to the current value. As a perf optimization the new and old
    * values will not actually be compared if we aren't notifying and we don't
    * have mutation listeners (in which case it's cheap to just return false
    * and let the caller go ahead and set the value).
@@ -756,137 +753,57 @@ public:
 
   /**
    * Sets the class attribute to a value that contains no whitespace.
    * Assumes that we are not notifying and that the attribute hasn't been
    * set previously.
    */
   nsresult SetSingleClassFromParser(nsAtom* aSingleClassName);
 
+  virtual nsresult SetAttr(int32_t aNameSpaceID, nsAtom* aName, nsAtom* aPrefix,
+                           const nsAString& aValue, nsIPrincipal* aSubjectPrincipal,
+                           bool aNotify) override;
   // aParsedValue receives the old value of the attribute. That's useful if
   // either the input or output value of aParsedValue is StoresOwnData.
   nsresult SetParsedAttr(int32_t aNameSpaceID, nsAtom* aName, nsAtom* aPrefix,
                          nsAttrValue& aParsedValue, bool aNotify);
   // GetAttr is not inlined on purpose, to keep down codesize from all
   // the inlined nsAttrValue bits for C++ callers.
   bool GetAttr(int32_t aNameSpaceID, nsAtom* aName,
                nsAString& aResult) const;
   inline bool HasAttr(int32_t aNameSpaceID, nsAtom* aName) const;
   // aCaseSensitive == eIgnoreCaase means ASCII case-insensitive matching.
   inline bool AttrValueIs(int32_t aNameSpaceID, nsAtom* aName,
                           const nsAString& aValue,
                           nsCaseTreatment aCaseSensitive) const;
   inline bool AttrValueIs(int32_t aNameSpaceID, nsAtom* aName,
                           nsAtom* aValue,
                           nsCaseTreatment aCaseSensitive) const;
-  int32_t FindAttrValueIn(int32_t aNameSpaceID,
-                          nsAtom* aName,
-                          AttrValuesArray* aValues,
-                          nsCaseTreatment aCaseSensitive) const override;
-
-  /**
-   * Set attribute values. All attribute values are assumed to have a
-   * canonical string representation that can be used for these
-   * methods. The SetAttr method is assumed to perform a translation
-   * of the canonical form into the underlying content specific
-   * form.
-   *
-   * @param aNameSpaceID the namespace of the attribute
-   * @param aName the name of the attribute
-   * @param aValue the value to set
-   * @param aNotify specifies how whether or not the document should be
-   *        notified of the attribute change.
-   */
-  nsresult SetAttr(int32_t aNameSpaceID, nsAtom* aName,
-                   const nsAString& aValue, bool aNotify)
-  {
-    return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify);
-  }
-  nsresult SetAttr(int32_t aNameSpaceID, nsAtom* aName, nsAtom* aPrefix,
-                   const nsAString& aValue, bool aNotify)
-  {
-    return SetAttr(aNameSpaceID, aName, aPrefix, aValue, nullptr, aNotify);
-  }
-  nsresult SetAttr(int32_t aNameSpaceID, nsAtom* aName, const nsAString& aValue,
-                   nsIPrincipal* aTriggeringPrincipal, bool aNotify)
-  {
-    return SetAttr(aNameSpaceID, aName, nullptr, aValue, aTriggeringPrincipal, aNotify);
-  }
+  virtual int32_t FindAttrValueIn(int32_t aNameSpaceID,
+                                  nsAtom* aName,
+                                  AttrValuesArray* aValues,
+                                  nsCaseTreatment aCaseSensitive) const override;
+  virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsAtom* aAttribute,
+                             bool aNotify) override;
 
-  /**
-   * Set attribute values. All attribute values are assumed to have a
-   * canonical String representation that can be used for these
-   * methods. The SetAttr method is assumed to perform a translation
-   * of the canonical form into the underlying content specific
-   * form.
-   *
-   * @param aNameSpaceID the namespace of the attribute
-   * @param aName the name of the attribute
-   * @param aPrefix the prefix of the attribute
-   * @param aValue the value to set
-   * @param aMaybeScriptedPrincipal the principal of the scripted caller responsible
-   *        for setting the attribute, or null if no scripted caller can be
-   *        determined. A null value here does not guarantee that there is no
-   *        scripted caller, but a non-null value does guarantee that a scripted
-   *        caller with the given principal is directly responsible for the
-   *        attribute change.
-   * @param aNotify specifies how whether or not the document should be
-   *        notified of the attribute change.
-   */
-  virtual nsresult SetAttr(int32_t aNameSpaceID, nsAtom* aName,
-                           nsAtom* aPrefix, const nsAString& aValue,
-                           nsIPrincipal* aMaybeScriptedPrincipal,
-                           bool aNotify);
-
-  /**
-   * Remove an attribute so that it is no longer explicitly specified.
-   *
-   * @param aNameSpaceID the namespace id of the attribute
-   * @param aAttr the name of the attribute to unset
-   * @param aNotify specifies whether or not the document should be
-   * notified of the attribute change
-   */
-  virtual nsresult UnsetAttr(int32_t aNameSpaceID,
-                             nsAtom* aAttribute,
-                             bool aNotify);
-
-  /**
-   * Get the namespace / name / prefix of a given attribute.
-   *
-   * @param   aIndex the index of the attribute name
-   * @returns The name at the given index, or null if the index is
-   *          out-of-bounds.
-   * @note    The document returned by NodeInfo()->GetDocument() (if one is
-   *          present) is *not* necessarily the owner document of the element.
-   * @note    The pointer returned by this function is only valid until the
-   *          next call of either GetAttrNameAt or SetAttr on the element.
-   */
-  const nsAttrName* GetAttrNameAt(uint32_t aIndex) const
+  virtual const nsAttrName* GetAttrNameAt(uint32_t aIndex) const final override
   {
     return mAttrsAndChildren.GetSafeAttrNameAt(aIndex);
   }
 
-  /**
-   * Gets the attribute info (name and value) for this element at a given index.
-   */
-  BorrowedAttrInfo GetAttrInfoAt(uint32_t aIndex) const
+  virtual BorrowedAttrInfo GetAttrInfoAt(uint32_t aIndex) const final override
   {
     if (aIndex >= mAttrsAndChildren.AttrCount()) {
       return BorrowedAttrInfo(nullptr, nullptr);
     }
 
     return mAttrsAndChildren.AttrInfoAt(aIndex);
   }
 
-  /**
-   * Get the number of all specified attributes.
-   *
-   * @return the number of attributes
-   */
-  uint32_t GetAttrCount() const
+  virtual uint32_t GetAttrCount() const final override
   {
     return mAttrsAndChildren.AttrCount();
   }
 
   virtual bool IsNodeOfType(uint32_t aFlags) const override;
 
   /**
    * Get the class list of this element (this corresponds to the value of the
@@ -1548,17 +1465,17 @@ public:
    */
   void SetAttr(nsAtom* aAttr, const nsAString& aValue, ErrorResult& aError)
   {
     aError = SetAttr(kNameSpaceID_None, aAttr, aValue, true);
   }
 
   void SetAttr(nsAtom* aAttr, const nsAString& aValue, nsIPrincipal& aTriggeringPrincipal, ErrorResult& aError)
   {
-    aError = SetAttr(kNameSpaceID_None, aAttr, aValue, &aTriggeringPrincipal, true);
+    aError = nsIContent::SetAttr(kNameSpaceID_None, aAttr, aValue, &aTriggeringPrincipal, true);
   }
 
   /**
    * Set a content attribute via a reflecting nullable string IDL
    * attribute (e.g. a CORS attribute).  If DOMStringIsNull(aValue),
    * this will actually remove the content attribute.
    */
   void SetOrRemoveNullableStringAttr(nsAtom* aName, const nsAString& aValue,
--- a/dom/base/FragmentOrElement.cpp
+++ b/dom/base/FragmentOrElement.cpp
@@ -386,35 +386,31 @@ nsIContent::LookupNamespaceURIInternal(c
   }
   else {
     name = nsGkAtoms::xmlns;
   }
   // Trace up the content parent chain looking for the namespace
   // declaration that declares aNamespacePrefix.
   const nsIContent* content = this;
   do {
-    if (content->IsElement() &&
-        content->AsElement()->GetAttr(kNameSpaceID_XMLNS, name, aNamespaceURI))
+    if (content->GetAttr(kNameSpaceID_XMLNS, name, aNamespaceURI))
       return NS_OK;
   } while ((content = content->GetParent()));
   return NS_ERROR_FAILURE;
 }
 
 nsAtom*
 nsIContent::GetLang() const
 {
   for (const auto* content = this; content; content = content->GetParent()) {
-    if (!content->IsElement()) {
+    if (!content->GetAttrCount() || !content->IsElement()) {
       continue;
     }
 
     auto* element = content->AsElement();
-    if (!element->GetAttrCount()) {
-      continue;
-    }
 
     // xml:lang has precedence over lang on HTML elements (see
     // XHTML1 section C.7).
     const nsAttrValue* attr =
       element->GetParsedAttr(nsGkAtoms::lang, kNameSpaceID_XML);
     if (!attr && element->SupportsLangAttr()) {
       attr = element->GetParsedAttr(nsGkAtoms::lang);
     }
@@ -1178,16 +1174,22 @@ bool
 nsIContent::IsFocusableInternal(int32_t* aTabIndex, bool aWithMouse)
 {
   if (aTabIndex) {
     *aTabIndex = -1; // Default, not tabbable
   }
   return false;
 }
 
+NS_IMETHODIMP
+FragmentOrElement::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
+{
+  return NS_OK;
+}
+
 bool
 FragmentOrElement::IsLink(nsIURI** aURI) const
 {
   *aURI = nullptr;
   return false;
 }
 
 nsIContent*
@@ -2234,18 +2236,18 @@ FragmentOrElement::CopyInnerTo(FragmentO
   NS_ENSURE_SUCCESS(rv, rv);
 
   uint32_t i, count = mAttrsAndChildren.AttrCount();
   for (i = 0; i < count; ++i) {
     const nsAttrName* name = mAttrsAndChildren.AttrNameAt(i);
     const nsAttrValue* value = mAttrsAndChildren.AttrAt(i);
     nsAutoString valStr;
     value->ToString(valStr);
-    rv = aDst->AsElement()->SetAttr(name->NamespaceID(), name->LocalName(),
-                                    name->GetPrefix(), valStr, false);
+    rv = aDst->SetAttr(name->NamespaceID(), name->LocalName(),
+                                name->GetPrefix(), valStr, false);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   return NS_OK;
 }
 
 const nsTextFragment*
 FragmentOrElement::GetText()
--- a/dom/base/FragmentOrElement.h
+++ b/dom/base/FragmentOrElement.h
@@ -160,16 +160,18 @@ public:
   virtual void SetAssignedSlot(mozilla::dom::HTMLSlotElement* aSlot) override;
   virtual nsIContent *GetXBLInsertionPoint() const override;
   virtual void SetXBLInsertionPoint(nsIContent* aContent) override;
   virtual bool IsLink(nsIURI** aURI) const override;
 
   virtual void DestroyContent() override;
   virtual void SaveSubtreeState() override;
 
+  NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker) override;
+
   nsIHTMLCollection* Children();
   uint32_t ChildElementCount()
   {
     return Children()->Length();
   }
 
   /**
    * Sets the IsElementInStyleScope flag on each element in the subtree rooted
--- a/dom/base/nsContentCreatorFunctions.h
+++ b/dom/base/nsContentCreatorFunctions.h
@@ -58,17 +58,17 @@ NS_NewMathMLElement(mozilla::dom::Elemen
 
 #ifdef MOZ_XUL
 nsresult
 NS_NewXULElement(mozilla::dom::Element** aResult,
                  already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                  mozilla::dom::FromParser aFromParser);
 
 void
-NS_TrustedNewXULElement(mozilla::dom::Element** aResult,
+NS_TrustedNewXULElement(nsIContent** aResult,
                         already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 #endif
 
 nsresult
 NS_NewSVGElement(mozilla::dom::Element** aResult,
                  already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                  mozilla::dom::FromParser aFromParser);
 
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -5053,23 +5053,23 @@ nsContentUtils::CreateContextualFragment
   if (content && !content->IsElement())
     content = content->GetParent();
 
   while (content && content->IsElement()) {
     nsString& tagName = *tagStack.AppendElement();
     tagName = content->NodeInfo()->QualifiedName();
 
     // see if we need to add xmlns declarations
-    uint32_t count = content->AsElement()->GetAttrCount();
+    uint32_t count = content->GetAttrCount();
     bool setDefaultNamespace = false;
     if (count > 0) {
       uint32_t index;
 
       for (index = 0; index < count; index++) {
-        const BorrowedAttrInfo info = content->AsElement()->GetAttrInfoAt(index);
+        const BorrowedAttrInfo info = content->GetAttrInfoAt(index);
         const nsAttrName* name = info.mName;
         if (name->NamespaceEquals(kNameSpaceID_XMLNS)) {
           info.mValue->ToString(uriStr);
 
           // really want something like nsXMLContentSerializer::SerializeAttr
           tagName.AppendLiteral(" xmlns"); // space important
           if (name->GetPrefix()) {
             tagName.Append(char16_t(':'));
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -416,20 +416,20 @@ nsIdentifierMapEntry::GetIdElement()
 
 Element*
 nsIdentifierMapEntry::GetImageIdElement()
 {
   return mImageElement ? mImageElement.get() : GetIdElement();
 }
 
 void
-nsIdentifierMapEntry::AppendAllIdContent(nsCOMArray<Element>* aElements)
-{
-  for (Element* element : mIdContentList) {
-    aElements->AppendObject(element);
+nsIdentifierMapEntry::AppendAllIdContent(nsCOMArray<nsIContent>* aElements)
+{
+  for (size_t i = 0; i < mIdContentList.Length(); ++i) {
+    aElements->AppendObject(mIdContentList[i]);
   }
 }
 
 void
 nsIdentifierMapEntry::AddContentChangeCallback(nsIDocument::IDTargetObserver aCallback,
                                                void* aData, bool aForImage)
 {
   if (!mChangeCallbacks) {
--- a/dom/base/nsGenericDOMDataNode.cpp
+++ b/dom/base/nsGenericDOMDataNode.cpp
@@ -632,29 +632,62 @@ nsGenericDOMDataNode::UnbindFromTree(boo
 }
 
 already_AddRefed<nsINodeList>
 nsGenericDOMDataNode::GetChildren(uint32_t aFilter)
 {
   return nullptr;
 }
 
+nsresult
+nsGenericDOMDataNode::SetAttr(int32_t aNameSpaceID, nsAtom* aAttr,
+                              nsAtom* aPrefix, const nsAString& aValue,
+                              nsIPrincipal* aContentPrincipal,
+                              bool aNotify)
+{
+  return NS_OK;
+}
+
+nsresult
+nsGenericDOMDataNode::UnsetAttr(int32_t aNameSpaceID, nsAtom* aAttr,
+                                bool aNotify)
+{
+  return NS_OK;
+}
+
+const nsAttrName*
+nsGenericDOMDataNode::GetAttrNameAt(uint32_t aIndex) const
+{
+  return nullptr;
+}
+
+BorrowedAttrInfo
+nsGenericDOMDataNode::GetAttrInfoAt(uint32_t aIndex) const
+{
+  return BorrowedAttrInfo(nullptr, nullptr);
+}
+
+uint32_t
+nsGenericDOMDataNode::GetAttrCount() const
+{
+  return 0;
+}
+
 uint32_t
 nsGenericDOMDataNode::GetChildCount() const
 {
   return 0;
 }
 
 nsIContent *
 nsGenericDOMDataNode::GetChildAt(uint32_t aIndex) const
 {
   return nullptr;
 }
 
-
 int32_t
 nsGenericDOMDataNode::IndexOf(const nsINode* aPossibleChild) const
 {
   return -1;
 }
 
 nsresult
 nsGenericDOMDataNode::InsertChildAt(nsIContent* aKid, uint32_t aIndex,
@@ -1085,16 +1118,36 @@ nsGenericDOMDataNode::AppendTextTo(nsASt
 already_AddRefed<nsAtom>
 nsGenericDOMDataNode::GetCurrentValueAtom()
 {
   nsAutoString val;
   GetData(val);
   return NS_Atomize(val);
 }
 
+NS_IMETHODIMP
+nsGenericDOMDataNode::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
+{
+  return NS_OK;
+}
+
+NS_IMETHODIMP_(bool)
+nsGenericDOMDataNode::IsAttributeMapped(const nsAtom* aAttribute) const
+{
+  return false;
+}
+
+nsChangeHint
+nsGenericDOMDataNode::GetAttributeChangeHint(const nsAtom* aAttribute,
+                                             int32_t aModType) const
+{
+  NS_NOTREACHED("Shouldn't be calling this!");
+  return nsChangeHint(0);
+}
+
 void
 nsGenericDOMDataNode::AddSizeOfExcludingThis(nsWindowSizes& aSizes,
                                              size_t* aNodeSize) const
 {
   nsIContent::AddSizeOfExcludingThis(aSizes, aNodeSize);
   *aNodeSize += mText.SizeOfExcludingThis(aSizes.mState.mMallocSizeOf);
 }
 
--- a/dom/base/nsGenericDOMDataNode.h
+++ b/dom/base/nsGenericDOMDataNode.h
@@ -128,16 +128,27 @@ public:
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               bool aCompileEventHandlers) override;
   virtual void UnbindFromTree(bool aDeep = true,
                               bool aNullParent = true) override;
 
   virtual already_AddRefed<nsINodeList> GetChildren(uint32_t aFilter) override;
 
+
+  using nsIContent::SetAttr;
+  virtual nsresult SetAttr(int32_t aNameSpaceID, nsAtom* aAttribute,
+                           nsAtom* aPrefix, const nsAString& aValue,
+                           nsIPrincipal* aSubjectPrincipal,
+                           bool aNotify) override;
+  virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsAtom* aAttribute,
+                             bool aNotify) override;
+  virtual const nsAttrName* GetAttrNameAt(uint32_t aIndex) const override;
+  virtual mozilla::dom::BorrowedAttrInfo GetAttrInfoAt(uint32_t aIndex) const override;
+  virtual uint32_t GetAttrCount() const override;
   virtual const nsTextFragment *GetText() override;
   virtual uint32_t TextLength() const override;
   virtual nsresult SetText(const char16_t* aBuffer, uint32_t aLength,
                            bool aNotify) override;
   // Need to implement this here too to avoid hiding.
   nsresult SetText(const nsAString& aStr, bool aNotify)
   {
     return SetText(aStr.BeginReading(), aStr.Length(), aNotify);
@@ -168,16 +179,21 @@ public:
   virtual void SetShadowRoot(mozilla::dom::ShadowRoot* aShadowRoot) override;
   virtual mozilla::dom::HTMLSlotElement* GetAssignedSlot() const override;
   virtual void SetAssignedSlot(mozilla::dom::HTMLSlotElement* aSlot) override;
   virtual nsIContent *GetXBLInsertionPoint() const override;
   virtual void SetXBLInsertionPoint(nsIContent* aContent) override;
   virtual bool IsNodeOfType(uint32_t aFlags) const override;
   virtual bool IsLink(nsIURI** aURI) const override;
 
+  NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker) override;
+  NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const;
+  virtual nsChangeHint GetAttributeChangeHint(const nsAtom* aAttribute,
+                                              int32_t aModType) const;
+
   virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,
                          bool aPreallocateChildren) const override
   {
     nsCOMPtr<nsINode> result = CloneDataNode(aNodeInfo, true);
     result.forget(aResult);
 
     if (!*aResult) {
       return NS_ERROR_OUT_OF_MEMORY;
--- a/dom/base/nsHTMLContentSerializer.cpp
+++ b/dom/base/nsHTMLContentSerializer.cpp
@@ -59,44 +59,44 @@ nsHTMLContentSerializer::~nsHTMLContentS
 NS_IMETHODIMP
 nsHTMLContentSerializer::AppendDocumentStart(nsIDocument *aDocument,
                                              nsAString& aStr)
 {
   return NS_OK;
 }
 
 bool
-nsHTMLContentSerializer::SerializeHTMLAttributes(Element* aElement,
-                                                 Element* aOriginalElement,
+nsHTMLContentSerializer::SerializeHTMLAttributes(nsIContent* aContent,
+                                                 nsIContent *aOriginalElement,
                                                  nsAString& aTagPrefix,
                                                  const nsAString& aTagNamespaceURI,
                                                  nsAtom* aTagName,
                                                  int32_t aNamespace,
                                                  nsAString& aStr)
 {
-  int32_t count = aElement->GetAttrCount();
+  int32_t count = aContent->GetAttrCount();
   if (!count)
     return true;
 
   nsresult rv;
   nsAutoString valueStr;
   NS_NAMED_LITERAL_STRING(_mozStr, "_moz");
 
   for (int32_t index = 0; index < count; index++) {
-    const nsAttrName* name = aElement->GetAttrNameAt(index);
+    const nsAttrName* name = aContent->GetAttrNameAt(index);
     int32_t namespaceID = name->NamespaceID();
     nsAtom* attrName = name->LocalName();
 
     // Filter out any attribute starting with [-|_]moz
     nsDependentAtomString attrNameStr(attrName);
     if (StringBeginsWith(attrNameStr, NS_LITERAL_STRING("_moz")) ||
         StringBeginsWith(attrNameStr, NS_LITERAL_STRING("-moz"))) {
       continue;
     }
-    aElement->GetAttr(namespaceID, attrName, valueStr);
+    aContent->GetAttr(namespaceID, attrName, valueStr);
 
     //
     // Filter out special case of <br type="_moz"> or <br _moz*>,
     // used by the editor.  Bug 16988.  Yuck.
     //
     if (aTagName == nsGkAtoms::br && aNamespace == kNameSpaceID_XHTML &&
         attrName == nsGkAtoms::type && namespaceID == kNameSpaceID_None &&
         StringBeginsWith(valueStr, _mozStr)) {
@@ -104,45 +104,45 @@ nsHTMLContentSerializer::SerializeHTMLAt
     }
 
     if (mIsCopying && mIsFirstChildOfOL &&
         aTagName == nsGkAtoms::li && aNamespace == kNameSpaceID_XHTML &&
         attrName == nsGkAtoms::value && namespaceID == kNameSpaceID_None){
       // This is handled separately in SerializeLIValueAttribute()
       continue;
     }
-    bool isJS = IsJavaScript(aElement, attrName, namespaceID, valueStr);
+    bool isJS = IsJavaScript(aContent, attrName, namespaceID, valueStr);
 
     if (((attrName == nsGkAtoms::href &&
           (namespaceID == kNameSpaceID_None ||
            namespaceID == kNameSpaceID_XLink)) ||
          (attrName == nsGkAtoms::src && namespaceID == kNameSpaceID_None))) {
       // Make all links absolute when converting only the selection:
       if (mFlags & nsIDocumentEncoder::OutputAbsoluteLinks) {
         // Would be nice to handle OBJECT tags, but that gets more complicated
         // since we have to search the tag list for CODEBASE as well. For now,
         // just leave them relative.
-        nsCOMPtr<nsIURI> uri = aElement->GetBaseURI();
+        nsCOMPtr<nsIURI> uri = aContent->GetBaseURI();
         if (uri) {
           nsAutoString absURI;
           rv = NS_MakeAbsoluteURI(absURI, valueStr, uri);
           if (NS_SUCCEEDED(rv)) {
             valueStr = absURI;
           }
         }
       }
     }
 
     if (mRewriteEncodingDeclaration && aTagName == nsGkAtoms::meta &&
         aNamespace == kNameSpaceID_XHTML && attrName == nsGkAtoms::content
         && namespaceID == kNameSpaceID_None) {
       // If we're serializing a <meta http-equiv="content-type">,
       // use the proper value, rather than what's in the document.
       nsAutoString header;
-      aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::httpEquiv, header);
+      aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::httpEquiv, header);
       if (header.LowerCaseEqualsLiteral("content-type")) {
         valueStr = NS_LITERAL_STRING("text/html; charset=") +
           NS_ConvertASCIItoUTF16(mCharset);
       }
     }
 
     nsDependentAtomString nameStr(attrName);
     nsAutoString prefix;
@@ -168,30 +168,32 @@ nsHTMLContentSerializer::SerializeHTMLAt
 
 NS_IMETHODIMP
 nsHTMLContentSerializer::AppendElementStart(Element* aElement,
                                             Element* aOriginalElement,
                                             nsAString& aStr)
 {
   NS_ENSURE_ARG(aElement);
 
+  nsIContent* content = aElement;
+
   bool forceFormat = false;
   nsresult rv = NS_OK;
-  if (!CheckElementStart(aElement, forceFormat, aStr, rv)) {
+  if (!CheckElementStart(content, forceFormat, aStr, rv)) {
     // When we go to AppendElementEnd for this element, we're going to
     // MaybeLeaveFromPreContent().  So make sure to MaybeEnterInPreContent()
     // now, so our PreLevel() doesn't get confused.
-    MaybeEnterInPreContent(aElement);
+    MaybeEnterInPreContent(content);
     return rv;
   }
 
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsAtom *name = aElement->NodeInfo()->NameAtom();
-  int32_t ns = aElement->GetNameSpaceID();
+  nsAtom *name = content->NodeInfo()->NameAtom();
+  int32_t ns = content->GetNameSpaceID();
 
   bool lineBreakBeforeOpen = LineBreakBeforeOpen(ns, name);
 
   if ((mDoFormat || forceFormat) && !mDoRaw && !PreLevel()) {
     if (mColPos && lineBreakBeforeOpen) {
       NS_ENSURE_TRUE(AppendNewLineToString(aStr), NS_ERROR_OUT_OF_MEMORY);
     }
     else {
@@ -217,17 +219,17 @@ nsHTMLContentSerializer::AppendElementSt
   // Always reset to avoid false newlines in case MaybeAddNewlineForRootNode wasn't
   // called
   mAddNewlineForRootNode = false;
 
   NS_ENSURE_TRUE(AppendToString(kLessThan, aStr), NS_ERROR_OUT_OF_MEMORY);
 
   NS_ENSURE_TRUE(AppendToString(nsDependentAtomString(name), aStr), NS_ERROR_OUT_OF_MEMORY);
 
-  MaybeEnterInPreContent(aElement);
+  MaybeEnterInPreContent(content);
 
   // for block elements, we increase the indentation
   if ((mDoFormat || forceFormat) && !mDoRaw && !PreLevel())
     NS_ENSURE_TRUE(IncrIndentation(name), NS_ERROR_OUT_OF_MEMORY);
 
   // Need to keep track of OL and LI elements in order to get ordinal number
   // for the LI.
   if (mIsCopying && name == nsGkAtoms::ol && ns == kNameSpaceID_XHTML){
@@ -257,17 +259,17 @@ nsHTMLContentSerializer::AppendElementSt
       // If OL is parent of this LI, serialize attributes in different manner.
       NS_ENSURE_TRUE(SerializeLIValueAttribute(aElement, aStr), NS_ERROR_OUT_OF_MEMORY);
     }
   }
 
   // Even LI passed above have to go through this
   // for serializing attributes other than "value".
   nsAutoString dummyPrefix;
-  NS_ENSURE_TRUE(SerializeHTMLAttributes(aElement,
+  NS_ENSURE_TRUE(SerializeHTMLAttributes(content,
                                          aOriginalElement,
                                          dummyPrefix,
                                          EmptyString(),
                                          name,
                                          ns,
                                          aStr), NS_ERROR_OUT_OF_MEMORY);
 
   NS_ENSURE_TRUE(AppendToString(kGreaterThan, aStr), NS_ERROR_OUT_OF_MEMORY);
@@ -280,39 +282,42 @@ nsHTMLContentSerializer::AppendElementSt
     ++mDisableEntityEncoding;
   }
 
   if ((mDoFormat || forceFormat) && !mDoRaw && !PreLevel() &&
     LineBreakAfterOpen(ns, name)) {
     NS_ENSURE_TRUE(AppendNewLineToString(aStr), NS_ERROR_OUT_OF_MEMORY);
   }
 
-  NS_ENSURE_TRUE(AfterElementStart(aElement, aOriginalElement, aStr), NS_ERROR_OUT_OF_MEMORY);
+  NS_ENSURE_TRUE(AfterElementStart(content, aOriginalElement, aStr), NS_ERROR_OUT_OF_MEMORY);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsHTMLContentSerializer::AppendElementEnd(Element* aElement, nsAString& aStr)
+nsHTMLContentSerializer::AppendElementEnd(Element* aElement,
+                                          nsAString& aStr)
 {
   NS_ENSURE_ARG(aElement);
 
-  nsAtom *name = aElement->NodeInfo()->NameAtom();
-  int32_t ns = aElement->GetNameSpaceID();
+  nsIContent* content = aElement;
+
+  nsAtom *name = content->NodeInfo()->NameAtom();
+  int32_t ns = content->GetNameSpaceID();
 
   if (ns == kNameSpaceID_XHTML &&
       (name == nsGkAtoms::script ||
        name == nsGkAtoms::style ||
        name == nsGkAtoms::noscript ||
        name == nsGkAtoms::noframes)) {
     --mDisableEntityEncoding;
   }
 
   bool forceFormat = !(mFlags & nsIDocumentEncoder::OutputIgnoreMozDirty) &&
-                     aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::mozdirty);
+                     content->HasAttr(kNameSpaceID_None, nsGkAtoms::mozdirty);
 
   if ((mDoFormat || forceFormat) && !mDoRaw && !PreLevel()) {
     DecrIndentation(name);
   }
 
   if (name == nsGkAtoms::script) {
     nsCOMPtr<nsIScriptElement> script = do_QueryInterface(aElement);
 
@@ -334,17 +339,17 @@ nsHTMLContentSerializer::AppendElementEn
   }
 
   if (ns == kNameSpaceID_XHTML) {
     bool isContainer =
       nsHTMLElement::IsContainer(nsHTMLTags::CaseSensitiveAtomTagToId(name));
     if (!isContainer) {
       // Keep this in sync with the cleanup at the end of this method.
       MOZ_ASSERT(name != nsGkAtoms::body);
-      MaybeLeaveFromPreContent(aElement);
+      MaybeLeaveFromPreContent(content);
       return NS_OK;
     }
   }
 
   if ((mDoFormat || forceFormat) && !mDoRaw && !PreLevel()) {
 
     bool lineBreakBeforeClose = LineBreakBeforeClose(ns, name);
 
@@ -366,17 +371,17 @@ nsHTMLContentSerializer::AppendElementEn
     NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY);
   }
 
   NS_ENSURE_TRUE(AppendToString(kEndTag, aStr), NS_ERROR_OUT_OF_MEMORY);
   NS_ENSURE_TRUE(AppendToString(nsDependentAtomString(name), aStr), NS_ERROR_OUT_OF_MEMORY);
   NS_ENSURE_TRUE(AppendToString(kGreaterThan, aStr), NS_ERROR_OUT_OF_MEMORY);
 
   // Keep this cleanup in sync with the IsContainer() early return above.
-  MaybeLeaveFromPreContent(aElement);
+  MaybeLeaveFromPreContent(content);
 
   if ((mDoFormat || forceFormat)&& !mDoRaw  && !PreLevel()
       && LineBreakAfterClose(ns, name)) {
     NS_ENSURE_TRUE(AppendNewLineToString(aStr), NS_ERROR_OUT_OF_MEMORY);
   }
   else {
     MaybeFlagNewlineForRootNode(aElement);
   }
--- a/dom/base/nsHTMLContentSerializer.h
+++ b/dom/base/nsHTMLContentSerializer.h
@@ -12,16 +12,17 @@
 
 #ifndef nsHTMLContentSerializer_h__
 #define nsHTMLContentSerializer_h__
 
 #include "mozilla/Attributes.h"
 #include "nsXHTMLContentSerializer.h"
 #include "nsString.h"
 
+class nsIContent;
 class nsAtom;
 
 class nsHTMLContentSerializer final : public nsXHTMLContentSerializer {
  public:
   nsHTMLContentSerializer();
   virtual ~nsHTMLContentSerializer();
 
   NS_IMETHOD AppendElementStart(mozilla::dom::Element* aElement,
@@ -31,18 +32,18 @@ class nsHTMLContentSerializer final : pu
   NS_IMETHOD AppendElementEnd(mozilla::dom::Element* aElement,
                               nsAString& aStr) override;
 
   NS_IMETHOD AppendDocumentStart(nsIDocument *aDocument,
                                  nsAString& aStr) override;
  protected:
 
   MOZ_MUST_USE
-  virtual bool SerializeHTMLAttributes(mozilla::dom::Element* aContent,
-                                       mozilla::dom::Element* aOriginalElement,
+  virtual bool SerializeHTMLAttributes(nsIContent* aContent,
+                                       nsIContent *aOriginalElement,
                                        nsAString& aTagPrefix,
                                        const nsAString& aTagNamespaceURI,
                                        nsAtom* aTagName,
                                        int32_t aNamespace,
                                        nsAString& aStr);
 
   MOZ_MUST_USE
   virtual bool AppendAndTranslateEntities(const nsAString& aStr,
--- a/dom/base/nsIContent.h
+++ b/dom/base/nsIContent.h
@@ -10,16 +10,17 @@
 #include "mozilla/dom/BorrowedAttrInfo.h"
 #include "nsCaseTreatment.h" // for enum, cannot be forward-declared
 #include "nsINode.h"
 #include "nsStringFwd.h"
 
 // Forward declarations
 class nsAtom;
 class nsIURI;
+class nsRuleWalker;
 class nsAttrValue;
 class nsAttrName;
 class nsTextFragment;
 class nsIFrame;
 class nsXBLBinding;
 class nsITextControlElement;
 
 namespace mozilla {
@@ -351,26 +352,78 @@ public:
 
   bool IsGeneratedContentContainerForAfter() const
   {
     return IsRootOfNativeAnonymousSubtree() &&
            mNodeInfo->NameAtom() == nsGkAtoms::mozgeneratedcontentafter;
   }
 
   /**
+   * Set attribute values. All attribute values are assumed to have a
+   * canonical string representation that can be used for these
+   * methods. The SetAttr method is assumed to perform a translation
+   * of the canonical form into the underlying content specific
+   * form.
+   *
+   * @param aNameSpaceID the namespace of the attribute
+   * @param aName the name of the attribute
+   * @param aValue the value to set
+   * @param aNotify specifies how whether or not the document should be
+   *        notified of the attribute change.
+   */
+  nsresult SetAttr(int32_t aNameSpaceID, nsAtom* aName,
+                   const nsAString& aValue, bool aNotify)
+  {
+    return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify);
+  }
+  nsresult SetAttr(int32_t aNameSpaceID, nsAtom* aName, nsAtom* aPrefix,
+                   const nsAString& aValue, bool aNotify)
+  {
+    return SetAttr(aNameSpaceID, aName, aPrefix, aValue, nullptr, aNotify);
+  }
+  nsresult SetAttr(int32_t aNameSpaceID, nsAtom* aName, const nsAString& aValue,
+                   nsIPrincipal* aTriggeringPrincipal, bool aNotify)
+  {
+    return SetAttr(aNameSpaceID, aName, nullptr, aValue, aTriggeringPrincipal, aNotify);
+  }
+
+  /**
+   * Set attribute values. All attribute values are assumed to have a
+   * canonical String representation that can be used for these
+   * methods. The SetAttr method is assumed to perform a translation
+   * of the canonical form into the underlying content specific
+   * form.
+   *
+   * @param aNameSpaceID the namespace of the attribute
+   * @param aName the name of the attribute
+   * @param aPrefix the prefix of the attribute
+   * @param aValue the value to set
+   * @param aMaybeScriptedPrincipal the principal of the scripted caller responsible
+   *        for setting the attribute, or null if no scripted caller can be
+   *        determined. A null value here does not guarantee that there is no
+   *        scripted caller, but a non-null value does guarantee that a scripted
+   *        caller with the given principal is directly responsible for the
+   *        attribute change.
+   * @param aNotify specifies how whether or not the document should be
+   *        notified of the attribute change.
+   */
+  virtual nsresult SetAttr(int32_t aNameSpaceID, nsAtom* aName,
+                           nsAtom* aPrefix, const nsAString& aValue,
+                           nsIPrincipal* aMaybeScriptedPrincipal,
+                           bool aNotify) = 0;
+
+  /**
    * Get the current value of the attribute. This returns a form that is
    * suitable for passing back into SetAttr.
    *
    * @param aNameSpaceID the namespace of the attr
    * @param aName the name of the attr
    * @param aResult the value (may legitimately be the empty string) [OUT]
    * @returns true if the attribute was set (even when set to empty string)
    *          false when not set.
-   *
-   * FIXME(emilio): Move to Element.
    */
   bool GetAttr(int32_t aNameSpaceID, nsAtom* aName,
                nsAString& aResult) const;
 
   /**
    * Determine if an attribute has been set (empty string or otherwise).
    *
    * @param aNameSpaceId the namespace id of the attribute
@@ -435,16 +488,53 @@ public:
                                   nsAtom* aName,
                                   AttrValuesArray* aValues,
                                   nsCaseTreatment aCaseSensitive) const
   {
     return ATTR_MISSING;
   }
 
   /**
+   * Remove an attribute so that it is no longer explicitly specified.
+   *
+   * @param aNameSpaceID the namespace id of the attribute
+   * @param aAttr the name of the attribute to unset
+   * @param aNotify specifies whether or not the document should be
+   * notified of the attribute change
+   */
+  virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsAtom* aAttr,
+                             bool aNotify) = 0;
+
+
+  /**
+   * Get the namespace / name / prefix of a given attribute.
+   *
+   * @param   aIndex the index of the attribute name
+   * @returns The name at the given index, or null if the index is
+   *          out-of-bounds.
+   * @note    The document returned by NodeInfo()->GetDocument() (if one is
+   *          present) is *not* necessarily the owner document of the element.
+   * @note    The pointer returned by this function is only valid until the
+   *          next call of either GetAttrNameAt or SetAttr on the element.
+   */
+  virtual const nsAttrName* GetAttrNameAt(uint32_t aIndex) const = 0;
+
+  /**
+   * Gets the attribute info (name and value) for this content at a given index.
+   */
+  virtual mozilla::dom::BorrowedAttrInfo GetAttrInfoAt(uint32_t aIndex) const = 0;
+
+  /**
+   * Get the number of all specified attributes.
+   *
+   * @return the number of attributes
+   */
+  virtual uint32_t GetAttrCount() const = 0;
+
+  /**
    * Get direct access (but read only) to the text in the text content.
    * NOTE: For elements this is *not* the concatenation of all text children,
    * it is simply null;
    */
   virtual const nsTextFragment *GetText() = 0;
 
   /**
    * Get the length of the text content.
@@ -831,16 +921,22 @@ public:
   nsAtom* GetID() const {
     if (HasID()) {
       return DoGetID();
     }
     return nullptr;
   }
 
   /**
+   * Walk aRuleWalker over the content style rules (presentational
+   * hint rules) for this content node.
+   */
+  NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker) = 0;
+
+  /**
    * Should be called when the node can become editable or when it can stop
    * being editable (for example when its contentEditable attribute changes,
    * when it is moved into an editable parent, ...).  If aNotify is true and
    * the node is an element, this will notify the state change.
    */
   virtual void UpdateEditableState(bool aNotify);
 
   /**
--- a/dom/base/nsINode.cpp
+++ b/dom/base/nsINode.cpp
@@ -773,32 +773,27 @@ nsINode::LookupPrefix(const nsAString& a
   if (element) {
     // XXX Waiting for DOM spec to list error codes.
 
     // Trace up the content parent chain looking for the namespace
     // declaration that defines the aNamespaceURI namespace. Once found,
     // return the prefix (i.e. the attribute localName).
     for (nsIContent* content = element; content;
          content = content->GetParent()) {
-      if (!content->IsElement()) {
-        continue;
-      }
-
-      Element* element = content->AsElement();
-      uint32_t attrCount = element->GetAttrCount();
+      uint32_t attrCount = content->GetAttrCount();
 
       for (uint32_t i = 0; i < attrCount; ++i) {
-        const nsAttrName* name = element->GetAttrNameAt(i);
+        const nsAttrName* name = content->GetAttrNameAt(i);
 
         if (name->NamespaceEquals(kNameSpaceID_XMLNS) &&
-            element->AttrValueIs(kNameSpaceID_XMLNS, name->LocalName(),
+            content->AttrValueIs(kNameSpaceID_XMLNS, name->LocalName(),
                                  aNamespaceURI, eCaseMatters)) {
           // If the localName is "xmlns", the prefix we output should be
           // null.
-          nsAtom* localName = name->LocalName();
+          nsAtom *localName = name->LocalName();
 
           if (localName != nsGkAtoms::xmlns) {
             localName->ToString(aPrefix);
           }
           else {
             SetDOMStringToNull(aPrefix);
           }
           return;
--- a/dom/base/nsIdentifierMapEntry.h
+++ b/dom/base/nsIdentifierMapEntry.h
@@ -147,17 +147,17 @@ public:
   /**
    * If this entry has a non-null image element set (using SetImageElement),
    * the image element will be returned, otherwise the same as GetIdElement().
    */
   Element* GetImageIdElement();
   /**
    * Append all the elements with this id to aElements
    */
-  void AppendAllIdContent(nsCOMArray<Element>* aElements);
+  void AppendAllIdContent(nsCOMArray<nsIContent>* aElements);
   /**
    * This can fire ID change callbacks.
    * @return true if the content could be added, false if we failed due
    * to OOM.
    */
   bool AddIdElement(Element* aElement);
   /**
    * This can fire ID change callbacks.
--- a/dom/base/nsMappedAttributeElement.h
+++ b/dom/base/nsMappedAttributeElement.h
@@ -34,17 +34,17 @@ protected:
   {}
 
 public:
   virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const;
 
   static void MapNoAttributesInto(const nsMappedAttributes* aAttributes,
                                   mozilla::GenericSpecifiedValues* aGenericData);
 
-  virtual nsresult WalkContentStyleRules(nsRuleWalker* aRuleWalker) override;
+  NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker) override;
   virtual bool SetAndSwapMappedAttribute(nsAtom* aName,
                                          nsAttrValue& aValue,
                                          bool* aValueWasSet,
                                          nsresult* aRetval) override;
 
   virtual void NodeInfoChanged(nsIDocument* aOldDoc) override;
 };
 
--- a/dom/base/nsObjectLoadingContent.cpp
+++ b/dom/base/nsObjectLoadingContent.cpp
@@ -919,24 +919,24 @@ nsObjectLoadingContent::GetNestedParams(
 nsresult
 nsObjectLoadingContent::BuildParametersArray()
 {
   if (mCachedAttributes.Length() || mCachedParameters.Length()) {
     MOZ_ASSERT(false, "Parameters array should be empty.");
     return NS_OK;
   }
 
-  nsCOMPtr<Element> element =
+  nsCOMPtr<nsIContent> content =
     do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
 
-  for (uint32_t i = 0; i != element->GetAttrCount(); i += 1) {
+  for (uint32_t i = 0; i != content->GetAttrCount(); i += 1) {
     MozPluginParameter param;
-    const nsAttrName* attrName = element->GetAttrNameAt(i);
+    const nsAttrName* attrName = content->GetAttrNameAt(i);
     nsAtom* atom = attrName->LocalName();
-    element->GetAttr(attrName->NamespaceID(), atom, param.mValue);
+    content->GetAttr(attrName->NamespaceID(), atom, param.mValue);
     atom->ToString(param.mName);
     mCachedAttributes.AppendElement(param);
   }
 
   nsAutoCString wmodeOverride;
   Preferences::GetCString("plugins.force.wmode", wmodeOverride);
 
   for (uint32_t i = 0; i < mCachedAttributes.Length(); i++) {
@@ -953,20 +953,20 @@ nsObjectLoadingContent::BuildParametersA
     mCachedAttributes.AppendElement(param);
   }
 
   // Some plugins were never written to understand the "data" attribute of the OBJECT tag.
   // Real and WMP will not play unless they find a "src" attribute, see bug 152334.
   // Nav 4.x would simply replace the "data" with "src". Because some plugins correctly
   // look for "data", lets instead copy the "data" attribute and add another entry
   // to the bottom of the array if there isn't already a "src" specified.
-  if (element->IsHTMLElement(nsGkAtoms::object) &&
-      !element->HasAttr(kNameSpaceID_None, nsGkAtoms::src)) {
+  if (content->IsHTMLElement(nsGkAtoms::object) &&
+      !content->HasAttr(kNameSpaceID_None, nsGkAtoms::src)) {
     MozPluginParameter param;
-    element->GetAttr(kNameSpaceID_None, nsGkAtoms::data, param.mValue);
+    content->GetAttr(kNameSpaceID_None, nsGkAtoms::data, param.mValue);
     if (!param.mValue.IsEmpty()) {
       param.mName = NS_LITERAL_STRING("SRC");
       mCachedAttributes.AppendElement(param);
     }
   }
 
   GetNestedParams(mCachedParameters);
 
--- a/dom/base/nsTreeSanitizer.cpp
+++ b/dom/base/nsTreeSanitizer.cpp
@@ -1396,22 +1396,20 @@ nsTreeSanitizer::SanitizeChildren(nsINod
   while (node) {
     if (node->IsElement()) {
       mozilla::dom::Element* elt = node->AsElement();
       mozilla::dom::NodeInfo* nodeInfo = node->NodeInfo();
       nsAtom* localName = nodeInfo->NameAtom();
       int32_t ns = nodeInfo->NamespaceID();
 
       if (MustPrune(ns, localName, elt)) {
-        RemoveAllAttributes(elt);
+        RemoveAllAttributes(node);
         nsIContent* descendant = node;
         while ((descendant = descendant->GetNextNode(node))) {
-          if (descendant->IsElement()) {
-            RemoveAllAttributes(descendant->AsElement());
-          }
+          RemoveAllAttributes(descendant);
         }
         nsIContent* next = node->GetNextNonChildNode(aRoot);
         node->RemoveFromParent();
         node = next;
         continue;
       }
       if (nsGkAtoms::style == localName) {
         // If styles aren't allowed, style elements got pruned above. Even
@@ -1447,17 +1445,17 @@ nsTreeSanitizer::SanitizeChildren(nsINod
                              true,
                              mAllowStyles,
                              false);
         }
         node = node->GetNextNonChildNode(aRoot);
         continue;
       }
       if (MustFlatten(ns, localName)) {
-        RemoveAllAttributes(elt);
+        RemoveAllAttributes(node);
         nsCOMPtr<nsIContent> next = node->GetNextNode(aRoot);
         nsCOMPtr<nsIContent> parent = node->GetParent();
         nsCOMPtr<nsIContent> child; // Must keep the child alive during move
         ErrorResult rv;
         while ((child = node->GetFirstChild())) {
           nsCOMPtr<nsINode> refNode = node;
           parent->InsertBefore(*child, refNode, rv);
           if (rv.Failed()) {
@@ -1502,17 +1500,17 @@ nsTreeSanitizer::SanitizeChildren(nsINod
     if (!mAllowComments && node->IsNodeOfType(nsINode::eCOMMENT)) {
       node->RemoveFromParent();
     }
     node = next;
   }
 }
 
 void
-nsTreeSanitizer::RemoveAllAttributes(Element* aElement)
+nsTreeSanitizer::RemoveAllAttributes(nsIContent* aElement)
 {
   const nsAttrName* attrName;
   while ((attrName = aElement->GetAttrNameAt(0))) {
     int32_t attrNs = attrName->NamespaceID();
     RefPtr<nsAtom> attrLocal = attrName->LocalName();
     aElement->UnsetAttr(attrNs, attrLocal, false);
   }
 }
--- a/dom/base/nsTreeSanitizer.h
+++ b/dom/base/nsTreeSanitizer.h
@@ -141,18 +141,18 @@ class MOZ_STACK_CLASS nsTreeSanitizer {
      * security check.
      *
      * @param aElement the element whose attribute to possibly modify
      * @param aNamespace the namespace of the URL attribute
      * @param aLocalName the local name of the URL attribute
      * @return true if the attribute was removed and false otherwise
      */
     bool SanitizeURL(mozilla::dom::Element* aElement,
-                     int32_t aNamespace,
-                     nsAtom* aLocalName);
+                       int32_t aNamespace,
+                       nsAtom* aLocalName);
 
     /**
      * Checks a style rule for the presence of the 'binding' CSS property and
      * removes that property from the rule.
      *
      * @param aDeclaration The style declaration to check
      * @return true if the rule was modified and false otherwise
      */
@@ -173,17 +173,17 @@ class MOZ_STACK_CLASS nsTreeSanitizer {
     bool SanitizeStyleSheet(const nsAString& aOriginal,
                               nsAString& aSanitized,
                               nsIDocument* aDocument,
                               nsIURI* aBaseURI);
 
     /**
      * Removes all attributes from an element node.
      */
-    void RemoveAllAttributes(mozilla::dom::Element* aElement);
+    void RemoveAllAttributes(nsIContent* aElement);
 
     /**
      * The whitelist of HTML elements.
      */
     static nsTHashtable<nsRefPtrHashKey<nsAtom>>* sElementsHTML;
 
     /**
      * The whitelist of non-presentational HTML attributes.
--- a/dom/base/nsXHTMLContentSerializer.cpp
+++ b/dom/base/nsXHTMLContentSerializer.cpp
@@ -151,46 +151,46 @@ nsXHTMLContentSerializer::AppendText(nsI
       NS_ENSURE_TRUE(AppendToStringConvertLF(data, aStr), NS_ERROR_OUT_OF_MEMORY);
     }
   }
 
   return NS_OK;
 }
 
 bool
-nsXHTMLContentSerializer::SerializeAttributes(Element* aElement,
-                                              Element* aOriginalElement,
+nsXHTMLContentSerializer::SerializeAttributes(nsIContent* aContent,
+                                              nsIContent *aOriginalElement,
                                               nsAString& aTagPrefix,
                                               const nsAString& aTagNamespaceURI,
                                               nsAtom* aTagName,
                                               nsAString& aStr,
                                               uint32_t aSkipAttr,
                                               bool aAddNSAttr)
 {
   nsresult rv;
   uint32_t index, count;
   nsAutoString prefixStr, uriStr, valueStr;
   nsAutoString xmlnsStr;
   xmlnsStr.AssignLiteral(kXMLNS);
 
-  int32_t contentNamespaceID = aElement->GetNameSpaceID();
+  int32_t contentNamespaceID = aContent->GetNameSpaceID();
 
   // this method is not called by nsHTMLContentSerializer
   // so we don't have to check HTML element, just XHTML
 
   if (mIsCopying && kNameSpaceID_XHTML == contentNamespaceID) {
 
     // Need to keep track of OL and LI elements in order to get ordinal number
     // for the LI.
     if (aTagName == nsGkAtoms::ol) {
       // We are copying and current node is an OL;
       // Store its start attribute value in olState->startVal.
       nsAutoString start;
       int32_t startAttrVal = 0;
-      aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::start, start);
+      aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::start, start);
       if (!start.IsEmpty()) {
         nsresult rv = NS_OK;
         startAttrVal = start.ToInteger(&rv);
         //If OL has "start" attribute, first LI element has to start with that value
         //Therefore subtracting 1 as all the LI elements are incrementing it before using it;
         //In failure of ToInteger(), default StartAttrValue to 0.
         if (NS_SUCCEEDED(rv))
           --startAttrVal;
@@ -199,17 +199,17 @@ nsXHTMLContentSerializer::SerializeAttri
       }
       olState state (startAttrVal, true);
       mOLStateStack.AppendElement(state);
     }
     else if (aTagName == nsGkAtoms::li) {
       mIsFirstChildOfOL = IsFirstChildOfOL(aOriginalElement);
       if (mIsFirstChildOfOL) {
         // If OL is parent of this LI, serialize attributes in different manner.
-        NS_ENSURE_TRUE(SerializeLIValueAttribute(aElement, aStr), false);
+        NS_ENSURE_TRUE(SerializeLIValueAttribute(aContent, aStr), false);
       }
     }
   }
 
   // If we had to add a new namespace declaration, serialize
   // and push it on the namespace stack
   if (aAddNSAttr) {
     if (aTagPrefix.IsEmpty()) {
@@ -223,28 +223,28 @@ nsXHTMLContentSerializer::SerializeAttri
                                    aTagNamespaceURI,
                                    aStr, true), false);
     }
     PushNameSpaceDecl(aTagPrefix, aTagNamespaceURI, aOriginalElement);
   }
 
   NS_NAMED_LITERAL_STRING(_mozStr, "_moz");
 
-  count = aElement->GetAttrCount();
+  count = aContent->GetAttrCount();
 
   // Now serialize each of the attributes
   // XXX Unfortunately we need a namespace manager to get
   // attribute URIs.
   for (index = 0; index < count; index++) {
 
     if (aSkipAttr == index) {
         continue;
     }
 
-    mozilla::dom::BorrowedAttrInfo info = aElement->GetAttrInfoAt(index);
+    mozilla::dom::BorrowedAttrInfo info = aContent->GetAttrInfoAt(index);
     const nsAttrName* name = info.mName;
 
     int32_t namespaceID = name->NamespaceID();
     nsAtom* attrName = name->LocalName();
     nsAtom* attrPrefix = name->GetPrefix();
 
     // Filter out any attribute starting with [-|_]moz
     nsDependentAtomString attrNameStr(attrName);
@@ -282,57 +282,57 @@ nsXHTMLContentSerializer::SerializeAttri
       }
 
       if (mIsCopying && mIsFirstChildOfOL && (aTagName == nsGkAtoms::li)
           && (attrName == nsGkAtoms::value)) {
         // This is handled separately in SerializeLIValueAttribute()
         continue;
       }
 
-      isJS = IsJavaScript(aElement, attrName, namespaceID, valueStr);
+      isJS = IsJavaScript(aContent, attrName, namespaceID, valueStr);
 
       if (namespaceID == kNameSpaceID_None &&
           ((attrName == nsGkAtoms::href) ||
           (attrName == nsGkAtoms::src))) {
         // Make all links absolute when converting only the selection:
         if (mFlags & nsIDocumentEncoder::OutputAbsoluteLinks) {
           // Would be nice to handle OBJECT tags,
           // but that gets more complicated since we have to
           // search the tag list for CODEBASE as well.
           // For now, just leave them relative.
-          nsCOMPtr<nsIURI> uri = aElement->GetBaseURI();
+          nsCOMPtr<nsIURI> uri = aContent->GetBaseURI();
           if (uri) {
             nsAutoString absURI;
             rv = NS_MakeAbsoluteURI(absURI, valueStr, uri);
             if (NS_SUCCEEDED(rv)) {
               valueStr = absURI;
             }
           }
         }
       }
 
       if (mRewriteEncodingDeclaration && aTagName == nsGkAtoms::meta &&
           attrName == nsGkAtoms::content) {
         // If we're serializing a <meta http-equiv="content-type">,
         // use the proper value, rather than what's in the document.
         nsAutoString header;
-        aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::httpEquiv, header);
+        aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::httpEquiv, header);
         if (header.LowerCaseEqualsLiteral("content-type")) {
           valueStr = NS_LITERAL_STRING("text/html; charset=") +
             NS_ConvertASCIItoUTF16(mCharset);
         }
       }
 
       // Expand shorthand attribute.
       if (namespaceID == kNameSpaceID_None && IsShorthandAttr(attrName, aTagName) && valueStr.IsEmpty()) {
         valueStr = nameStr;
       }
     }
     else {
-      isJS = IsJavaScript(aElement, attrName, namespaceID, valueStr);
+      isJS = IsJavaScript(aContent, attrName, namespaceID, valueStr);
     }
 
     NS_ENSURE_TRUE(SerializeAttr(prefixStr, nameStr, valueStr, aStr, !isJS), false);
 
     if (addNSAttr) {
       NS_ASSERTION(!prefixStr.IsEmpty(),
                    "Namespaced attributes must have a prefix");
       NS_ENSURE_TRUE(SerializeAttr(xmlnsStr, prefixStr, uriStr, aStr, true), false);
@@ -409,37 +409,37 @@ nsXHTMLContentSerializer::AppendDocument
 {
   if (!mBodyOnly)
     return nsXMLContentSerializer::AppendDocumentStart(aDocument, aStr);
 
   return NS_OK;
 }
 
 bool
-nsXHTMLContentSerializer::CheckElementStart(Element* aElement,
-                                            bool& aForceFormat,
+nsXHTMLContentSerializer::CheckElementStart(nsIContent * aContent,
+                                            bool & aForceFormat,
                                             nsAString& aStr,
                                             nsresult& aResult)
 {
   aResult = NS_OK;
 
   // The _moz_dirty attribute is emitted by the editor to
   // indicate that this element should be pretty printed
   // even if we're not in pretty printing mode
   aForceFormat = !(mFlags & nsIDocumentEncoder::OutputIgnoreMozDirty) &&
-                 aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::mozdirty);
+                 aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::mozdirty);
 
-  if (aElement->IsHTMLElement(nsGkAtoms::br) &&
+  if (aContent->IsHTMLElement(nsGkAtoms::br) &&
       (mFlags & nsIDocumentEncoder::OutputNoFormattingInPre) &&
       PreLevel() > 0) {
     aResult = AppendNewLineToString(aStr) ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
     return false;
   }
 
-  if (aElement->IsHTMLElement(nsGkAtoms::body)) {
+  if (aContent->IsHTMLElement(nsGkAtoms::body)) {
     ++mInBody;
   }
 
   return true;
 }
 
 bool
 nsXHTMLContentSerializer::CheckElementEnd(mozilla::dom::Element* aElement,
@@ -829,17 +829,17 @@ nsXHTMLContentSerializer::IsFirstChildOf
 
     return false;
   }
   else
     return false;
 }
 
 bool
-nsXHTMLContentSerializer::HasNoChildren(nsIContent* aContent) {
+nsXHTMLContentSerializer::HasNoChildren(nsIContent * aContent) {
 
   for (nsIContent* child = aContent->GetFirstChild();
        child;
        child = child->GetNextSibling()) {
 
     if (!child->IsNodeOfType(nsINode::eTEXT))
       return false;
 
--- a/dom/base/nsXHTMLContentSerializer.h
+++ b/dom/base/nsXHTMLContentSerializer.h
@@ -43,20 +43,20 @@ class nsXHTMLContentSerializer : public 
                         nsAString& aStr) override;
 
   NS_IMETHOD AppendDocumentStart(nsIDocument *aDocument,
                                  nsAString& aStr) override;
 
  protected:
 
 
-  virtual bool CheckElementStart(mozilla::dom::Element* aElement,
-                                 bool& aForceFormat,
-                                 nsAString& aStr,
-                                 nsresult& aResult) override;
+  virtual bool CheckElementStart(nsIContent * aContent,
+                          bool & aForceFormat,
+                          nsAString& aStr,
+                          nsresult& aResult) override;
 
   MOZ_MUST_USE
   virtual bool AfterElementStart(nsIContent* aContent,
                                  nsIContent* aOriginalElement,
                                  nsAString& aStr) override;
 
   virtual bool CheckElementEnd(mozilla::dom::Element* aContent,
                                bool& aForceFormat,
@@ -72,24 +72,24 @@ class nsXHTMLContentSerializer : public 
 
   bool HasLongLines(const nsString& text, int32_t& aLastNewlineOffset);
 
   // functions to check if we enter in or leave from a preformated content
   virtual void MaybeEnterInPreContent(nsIContent* aNode) override;
   virtual void MaybeLeaveFromPreContent(nsIContent* aNode) override;
 
   MOZ_MUST_USE
-  virtual bool SerializeAttributes(mozilla::dom::Element* aContent,
-                                   mozilla::dom::Element* aOriginalElement,
-                                   nsAString& aTagPrefix,
-                                   const nsAString& aTagNamespaceURI,
-                                   nsAtom* aTagName,
-                                   nsAString& aStr,
-                                   uint32_t aSkipAttr,
-                                   bool aAddNSAttr) override;
+  virtual bool SerializeAttributes(nsIContent* aContent,
+                           nsIContent *aOriginalElement,
+                           nsAString& aTagPrefix,
+                           const nsAString& aTagNamespaceURI,
+                           nsAtom* aTagName,
+                           nsAString& aStr,
+                           uint32_t aSkipAttr,
+                           bool aAddNSAttr) override;
 
   bool IsFirstChildOfOL(nsIContent* aElement);
 
   MOZ_MUST_USE
   bool SerializeLIValueAttribute(nsIContent* aElement,
                                  nsAString& aStr);
   bool IsShorthandAttr(const nsAtom* aAttrName,
                          const nsAtom* aElementName);
--- a/dom/base/nsXMLContentSerializer.cpp
+++ b/dom/base/nsXMLContentSerializer.cpp
@@ -707,30 +707,30 @@ nsXMLContentSerializer::SerializeAttr(co
   else {
     NS_ENSURE_TRUE(AppendToStringConvertLF(attrString, aStr), false);
   }
 
   return true;
 }
 
 uint32_t
-nsXMLContentSerializer::ScanNamespaceDeclarations(Element* aElement,
-                                                  Element* aOriginalElement,
+nsXMLContentSerializer::ScanNamespaceDeclarations(nsIContent* aContent,
+                                                  nsIContent *aOriginalElement,
                                                   const nsAString& aTagNamespaceURI)
 {
   uint32_t index, count;
   nsAutoString uriStr, valueStr;
 
-  count = aElement->GetAttrCount();
+  count = aContent->GetAttrCount();
 
   // First scan for namespace declarations, pushing each on the stack
   uint32_t skipAttr = count;
   for (index = 0; index < count; index++) {
 
-    const BorrowedAttrInfo info = aElement->GetAttrInfoAt(index);
+    const BorrowedAttrInfo info = aContent->GetAttrInfoAt(index);
     const nsAttrName* name = info.mName;
 
     int32_t namespaceID = name->NamespaceID();
     nsAtom *attrName = name->LocalName();
 
     if (namespaceID == kNameSpaceID_XMLNS ||
         // Also push on the stack attrs named "xmlns" in the null
         // namespace... because once we serialize those out they'll look like
@@ -794,18 +794,18 @@ nsXMLContentSerializer::IsJavaScript(nsI
       return false;
   }
 
   return aContent->IsEventAttributeName(aAttrNameAtom);
 }
 
 
 bool
-nsXMLContentSerializer::SerializeAttributes(Element* aElement,
-                                            Element* aOriginalElement,
+nsXMLContentSerializer::SerializeAttributes(nsIContent* aContent,
+                                            nsIContent *aOriginalElement,
                                             nsAString& aTagPrefix,
                                             const nsAString& aTagNamespaceURI,
                                             nsAtom* aTagName,
                                             nsAString& aStr,
                                             uint32_t aSkipAttr,
                                             bool aAddNSAttr)
 {
 
@@ -823,27 +823,27 @@ nsXMLContentSerializer::SerializeAttribu
     }
     else {
       // Serialize namespace decl
       NS_ENSURE_TRUE(SerializeAttr(xmlnsStr, aTagPrefix, aTagNamespaceURI, aStr, true), false);
     }
     PushNameSpaceDecl(aTagPrefix, aTagNamespaceURI, aOriginalElement);
   }
 
-  count = aElement->GetAttrCount();
+  count = aContent->GetAttrCount();
 
   // Now serialize each of the attributes
   // XXX Unfortunately we need a namespace manager to get
   // attribute URIs.
   for (index = 0; index < count; index++) {
     if (aSkipAttr == index) {
         continue;
     }
 
-    const nsAttrName* name = aElement->GetAttrNameAt(index);
+    const nsAttrName* name = aContent->GetAttrNameAt(index);
     int32_t namespaceID = name->NamespaceID();
     nsAtom* attrName = name->LocalName();
     nsAtom* attrPrefix = name->GetPrefix();
 
     // Filter out any attribute starting with [-|_]moz
     nsDependentAtomString attrNameStr(attrName);
     if (StringBeginsWith(attrNameStr, NS_LITERAL_STRING("_moz")) ||
         StringBeginsWith(attrNameStr, NS_LITERAL_STRING("-moz"))) {
@@ -858,20 +858,20 @@ nsXMLContentSerializer::SerializeAttribu
     }
 
     bool addNSAttr = false;
     if (kNameSpaceID_XMLNS != namespaceID) {
       nsContentUtils::NameSpaceManager()->GetNameSpaceURI(namespaceID, uriStr);
       addNSAttr = ConfirmPrefix(prefixStr, uriStr, aOriginalElement, true);
     }
 
-    aElement->GetAttr(namespaceID, attrName, valueStr);
+    aContent->GetAttr(namespaceID, attrName, valueStr);
 
     nsDependentAtomString nameStr(attrName);
-    bool isJS = IsJavaScript(aElement, attrName, namespaceID, valueStr);
+    bool isJS = IsJavaScript(aContent, attrName, namespaceID, valueStr);
 
     NS_ENSURE_TRUE(SerializeAttr(prefixStr, nameStr, valueStr, aStr, !isJS), false);
 
     if (addNSAttr) {
       NS_ASSERTION(!prefixStr.IsEmpty(),
                    "Namespaced attributes must have a prefix");
       NS_ENSURE_TRUE(SerializeAttr(xmlnsStr, prefixStr, uriStr, aStr, true), false);
       PushNameSpaceDecl(prefixStr, uriStr, aOriginalElement);
@@ -883,39 +883,40 @@ nsXMLContentSerializer::SerializeAttribu
 
 NS_IMETHODIMP
 nsXMLContentSerializer::AppendElementStart(Element* aElement,
                                            Element* aOriginalElement,
                                            nsAString& aStr)
 {
   NS_ENSURE_ARG(aElement);
 
+  nsIContent* content = aElement;
+
   bool forceFormat = false;
   nsresult rv = NS_OK;
-  if (!CheckElementStart(aElement, forceFormat, aStr, rv)) {
+  if (!CheckElementStart(content, forceFormat, aStr, rv)) {
     // When we go to AppendElementEnd for this element, we're going to
     // MaybeLeaveFromPreContent().  So make sure to MaybeEnterInPreContent()
     // now, so our PreLevel() doesn't get confused.
-    MaybeEnterInPreContent(aElement);
+    MaybeEnterInPreContent(content);
     return rv;
   }
 
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAutoString tagPrefix, tagLocalName, tagNamespaceURI;
   aElement->NodeInfo()->GetPrefix(tagPrefix);
   aElement->NodeInfo()->GetName(tagLocalName);
   aElement->NodeInfo()->GetNamespaceURI(tagNamespaceURI);
 
-  uint32_t skipAttr =
-    ScanNamespaceDeclarations(aElement, aOriginalElement, tagNamespaceURI);
+  uint32_t skipAttr = ScanNamespaceDeclarations(content,
+                          aOriginalElement, tagNamespaceURI);
 
-  nsAtom *name = aElement->NodeInfo()->NameAtom();
-  bool lineBreakBeforeOpen =
-    LineBreakBeforeOpen(aElement->GetNameSpaceID(), name);
+  nsAtom *name = content->NodeInfo()->NameAtom();
+  bool lineBreakBeforeOpen = LineBreakBeforeOpen(content->GetNameSpaceID(), name);
 
   if ((mDoFormat || forceFormat) && !mDoRaw && !PreLevel()) {
     if (mColPos && lineBreakBeforeOpen) {
       NS_ENSURE_TRUE(AppendNewLineToString(aStr), NS_ERROR_OUT_OF_MEMORY);
     }
     else {
       NS_ENSURE_TRUE(MaybeAddNewlineForRootNode(aStr), NS_ERROR_OUT_OF_MEMORY);
     }
@@ -946,36 +947,35 @@ nsXMLContentSerializer::AppendElementSta
   // Serialize the qualified name of the element
   NS_ENSURE_TRUE(AppendToString(kLessThan, aStr), NS_ERROR_OUT_OF_MEMORY);
   if (!tagPrefix.IsEmpty()) {
     NS_ENSURE_TRUE(AppendToString(tagPrefix, aStr), NS_ERROR_OUT_OF_MEMORY);
     NS_ENSURE_TRUE(AppendToString(NS_LITERAL_STRING(":"), aStr), NS_ERROR_OUT_OF_MEMORY);
   }
   NS_ENSURE_TRUE(AppendToString(tagLocalName, aStr), NS_ERROR_OUT_OF_MEMORY);
 
-  MaybeEnterInPreContent(aElement);
+  MaybeEnterInPreContent(content);
 
   if ((mDoFormat || forceFormat) && !mDoRaw && !PreLevel()) {
     NS_ENSURE_TRUE(IncrIndentation(name), NS_ERROR_OUT_OF_MEMORY);
   }
 
-  NS_ENSURE_TRUE(SerializeAttributes(aElement, aOriginalElement, tagPrefix,
-                                     tagNamespaceURI, name, aStr, skipAttr,
-                                     addNSAttr),
+  NS_ENSURE_TRUE(SerializeAttributes(content, aOriginalElement, tagPrefix, tagNamespaceURI,
+                                     name, aStr, skipAttr, addNSAttr),
                  NS_ERROR_OUT_OF_MEMORY);
 
   NS_ENSURE_TRUE(AppendEndOfElementStart(aElement, aOriginalElement, aStr),
                  NS_ERROR_OUT_OF_MEMORY);
 
   if ((mDoFormat || forceFormat) && !mDoRaw && !PreLevel()
-    && LineBreakAfterOpen(aElement->GetNameSpaceID(), name)) {
+    && LineBreakAfterOpen(content->GetNameSpaceID(), name)) {
     NS_ENSURE_TRUE(AppendNewLineToString(aStr), NS_ERROR_OUT_OF_MEMORY);
   }
 
-  NS_ENSURE_TRUE(AfterElementStart(aElement, aOriginalElement, aStr), NS_ERROR_OUT_OF_MEMORY);
+  NS_ENSURE_TRUE(AfterElementStart(content, aOriginalElement, aStr), NS_ERROR_OUT_OF_MEMORY);
 
   return NS_OK;
 }
 
 // aElement is the actual element we're outputting.  aOriginalElement is the one
 // in the original DOM, which is the one we have to test for kids.
 static bool
 ElementNeedsSeparateEndTag(Element* aElement, Element* aOriginalElement)
@@ -1140,18 +1140,18 @@ nsXMLContentSerializer::AppendDocumentSt
 
   NS_ENSURE_TRUE(aStr.AppendLiteral("?>", mozilla::fallible), NS_ERROR_OUT_OF_MEMORY);
   mAddNewlineForRootNode = true;
 
   return NS_OK;
 }
 
 bool
-nsXMLContentSerializer::CheckElementStart(Element*,
-                                          bool& aForceFormat,
+nsXMLContentSerializer::CheckElementStart(nsIContent * aContent,
+                                          bool & aForceFormat,
                                           nsAString& aStr,
                                           nsresult& aResult)
 {
   aResult = NS_OK;
   aForceFormat = false;
   return true;
 }
 
--- a/dom/base/nsXMLContentSerializer.h
+++ b/dom/base/nsXMLContentSerializer.h
@@ -204,23 +204,23 @@ class nsXMLContentSerializer : public ns
                        const nsAString& aURI,
                        nsIContent* aElement,
                        bool aIsAttribute);
   /**
    * GenerateNewPrefix generates a new prefix and writes it to aPrefix
    */
   void GenerateNewPrefix(nsAString& aPrefix);
 
-  uint32_t ScanNamespaceDeclarations(mozilla::dom::Element* aContent,
-                                     mozilla::dom::Element* aOriginalElement,
+  uint32_t ScanNamespaceDeclarations(nsIContent* aContent,
+                                     nsIContent *aOriginalElement,
                                      const nsAString& aTagNamespaceURI);
 
   MOZ_MUST_USE
-  virtual bool SerializeAttributes(mozilla::dom::Element* aContent,
-                                   mozilla::dom::Element* aOriginalElement,
+  virtual bool SerializeAttributes(nsIContent* aContent,
+                                   nsIContent *aOriginalElement,
                                    nsAString& aTagPrefix,
                                    const nsAString& aTagNamespaceURI,
                                    nsAtom* aTagName,
                                    nsAString& aStr,
                                    uint32_t aSkipAttr,
                                    bool aAddNSAttr);
 
   MOZ_MUST_USE
@@ -238,20 +238,20 @@ class nsXMLContentSerializer : public ns
   /**
    * This method can be redefined to check if the element can be serialized.
    * It is called when the serialization of the start tag is asked
    * (AppendElementStart)
    * In this method you can also force the formating
    * by setting aForceFormat to true.
    * @return boolean  true if the element can be output
    */
-  virtual bool CheckElementStart(Element* aElement,
-                                 bool & aForceFormat,
-                                 nsAString& aStr,
-                                 nsresult& aResult);
+  virtual bool CheckElementStart(nsIContent * aContent,
+                                   bool & aForceFormat,
+                                   nsAString& aStr,
+                                   nsresult& aResult);
 
   /**
    * This method is responsible for appending the '>' at the end of the start
    * tag, possibly preceded by '/' and maybe a ' ' before that too.
    *
    * aElement and aOriginalElement are the same as the corresponding arguments
    * to AppendElementStart.
    */
--- a/dom/svg/SVGAElement.h
+++ b/dom/svg/SVGAElement.h
@@ -51,17 +51,17 @@ public:
                               bool aNullParent = true) override;
   NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
   virtual int32_t TabIndexDefault() override;
   virtual bool IsSVGFocusable(bool* aIsFocusable, int32_t* aTabIndex) override;
   virtual bool IsLink(nsIURI** aURI) const override;
   virtual void GetLinkTarget(nsAString& aTarget) override;
   virtual already_AddRefed<nsIURI> GetHrefURI() const override;
   virtual EventStates IntrinsicState() const override;
-  using Element::SetAttr;
+  using nsIContent::SetAttr;
   virtual nsresult SetAttr(int32_t aNameSpaceID, nsAtom* aName,
                            nsAtom* aPrefix, const nsAString& aValue,
                            nsIPrincipal* aSubjectPrincipal,
                            bool aNotify) override;
   virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsAtom* aAttribute,
                              bool aNotify) override;
 
   // Link
--- a/dom/svg/SVGStyleElement.h
+++ b/dom/svg/SVGStyleElement.h
@@ -39,17 +39,17 @@ public:
                                            SVGStyleElementBase)
 
   // nsIContent
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               bool aCompileEventHandlers) override;
   virtual void UnbindFromTree(bool aDeep = true,
                               bool aNullParent = true) override;
-  using Element::SetAttr;
+  using nsIContent::SetAttr;
   virtual nsresult SetAttr(int32_t aNameSpaceID, nsAtom* aName,
                            nsAtom* aPrefix, const nsAString& aValue,
                            nsIPrincipal* aSubjectPrincipal,
                            bool aNotify) override;
   virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsAtom* aAttribute,
                              bool aNotify) override;
   virtual bool ParseAttribute(int32_t aNamespaceID,
                               nsAtom* aAttribute,
--- a/dom/xbl/nsXBLBinding.cpp
+++ b/dom/xbl/nsXBLBinding.cpp
@@ -257,17 +257,17 @@ nsXBLBinding::UnbindAnonymousContent(nsI
     if (xuldoc) {
       xuldoc->RemoveSubtreeFromDocument(child);
     }
 #endif
   }
 }
 
 void
-nsXBLBinding::SetBoundElement(Element* aElement)
+nsXBLBinding::SetBoundElement(nsIContent* aElement)
 {
   mBoundElement = aElement;
   if (mNextBinding)
     mNextBinding->SetBoundElement(aElement);
 
   if (!mBoundElement) {
     return;
   }
@@ -296,17 +296,17 @@ nsXBLBinding::HasStyleSheets() const
 
 void
 nsXBLBinding::GenerateAnonymousContent()
 {
   NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(),
                "Someone forgot a script blocker");
 
   // Fetch the content element for this binding.
-  Element* content =
+  nsIContent* content =
     mPrototypeBinding->GetImmediateChild(nsGkAtoms::content);
 
   if (!content) {
     // We have no anonymous content.
     if (mNextBinding)
       mNextBinding->GenerateAnonymousContent();
 
     return;
@@ -412,22 +412,18 @@ nsXBLBinding::GenerateAnonymousContent()
         nsAutoString value2;
         attrInfo.mValue->ToString(value2);
         mBoundElement->SetAttr(namespaceID, name, attrInfo.mName->GetPrefix(),
                                value2, false);
       }
     }
 
     // Conserve space by wiping the attributes off the clone.
-    //
-    // FIXME(emilio): It'd be nice to make `mContent` a `RefPtr<Element>`, but
-    // as of right now it can also be a ShadowRoot (we don't enter in this
-    // codepath though). Move Shadow DOM outside XBL and then fix that.
     if (mContent)
-      mContent->AsElement()->UnsetAttr(namespaceID, name, false);
+      mContent->UnsetAttr(namespaceID, name, false);
   }
 }
 
 nsIURI*
 nsXBLBinding::GetSourceDocURI()
 {
   nsIContent* targetContent =
     mPrototypeBinding->GetImmediateChild(nsGkAtoms::content);
--- a/dom/xbl/nsXBLBinding.h
+++ b/dom/xbl/nsXBLBinding.h
@@ -59,18 +59,18 @@ public:
 
   nsXBLPrototypeBinding* PrototypeBinding() const { return mPrototypeBinding; }
   nsIContent* GetAnonymousContent() { return mContent.get(); }
   nsXBLBinding* GetBindingWithContent();
 
   nsXBLBinding* GetBaseBinding() const { return mNextBinding; }
   void SetBaseBinding(nsXBLBinding *aBinding);
 
-  mozilla::dom::Element* GetBoundElement() { return mBoundElement; }
-  void SetBoundElement(mozilla::dom::Element* aElement);
+  nsIContent* GetBoundElement() { return mBoundElement; }
+  void SetBoundElement(nsIContent *aElement);
 
   /*
    * Does a lookup for a method or attribute provided by one of the bindings'
    * prototype implementation. If found, |desc| will be set up appropriately,
    * and wrapped into cx->compartment.
    *
    * May only be called when XBL code is being run in a separate scope, because
    * otherwise we don't have untainted data with which to do a proper lookup.
@@ -168,17 +168,17 @@ protected:
   bool mMarkedForDeath;
   bool mUsingContentXBLScope;
   bool mIsShadowRootBinding;
 
   nsXBLPrototypeBinding* mPrototypeBinding; // Weak, but we're holding a ref to the docinfo
   nsCOMPtr<nsIContent> mContent; // Strong. Our anonymous content stays around with us.
   RefPtr<nsXBLBinding> mNextBinding; // Strong. The derived binding owns the base class bindings.
 
-  mozilla::dom::Element* mBoundElement; // [WEAK] We have a reference, but we don't own it.
+  nsIContent* mBoundElement; // [WEAK] We have a reference, but we don't own it.
 
   // The <xbl:children> elements that we found in our <xbl:content> when we
   // processed this binding. The default insertion point has no includes
   // attribute and all other insertion points must have at least one includes
   // attribute. These points must be up-to-date with respect to their parent's
   // children, even if their parent has another binding attached to it,
   // preventing us from rendering their contents directly.
   RefPtr<mozilla::dom::XBLChildrenElement> mDefaultInsertionPoint;
--- a/dom/xbl/nsXBLContentSink.cpp
+++ b/dom/xbl/nsXBLContentSink.cpp
@@ -530,18 +530,17 @@ nsXBLContentSink::OnOpenContainer(const 
   return ret && mState != eXBL_InResources && mState != eXBL_InImplementation;
 }
 
 #undef ENSURE_XBL_STATE
 
 nsresult
 nsXBLContentSink::ConstructBinding(uint32_t aLineNumber)
 {
-  // This is only called from HandleStartElement, so it'd better be an element.
-  RefPtr<Element> binding = GetCurrentContent()->AsElement();
+  nsCOMPtr<nsIContent> binding = GetCurrentContent();
   binding->GetAttr(kNameSpaceID_None, nsGkAtoms::id, mCurrentBindingID);
   NS_ConvertUTF16toUTF8 cid(mCurrentBindingID);
 
   nsresult rv = NS_OK;
 
   // Don't create a binding with no id. nsXBLPrototypeBinding::Read also
   // performs this check.
   if (!cid.IsEmpty()) {
@@ -876,22 +875,23 @@ nsXBLContentSink::CreateElement(const ch
   Element* result;
   nsresult rv = nsXULElement::Create(prototype, mDocument, false, false, &result);
   *aResult = result;
   return rv;
 #endif
 }
 
 nsresult
-nsXBLContentSink::AddAttributes(const char16_t** aAtts, Element* aElement)
+nsXBLContentSink::AddAttributes(const char16_t** aAtts,
+                                nsIContent* aContent)
 {
-  if (aElement->IsXULElement())
+  if (aContent->IsXULElement())
     return NS_OK; // Nothing to do, since the proto already has the attrs.
 
-  return nsXMLContentSink::AddAttributes(aAtts, aElement);
+  return nsXMLContentSink::AddAttributes(aAtts, aContent);
 }
 
 #ifdef MOZ_XUL
 nsresult
 nsXBLContentSink::AddAttributesToXULPrototype(const char16_t **aAtts,
                                               uint32_t aAttsCount,
                                               nsXULPrototypeElement* aElement)
 {
--- a/dom/xbl/nsXBLContentSink.h
+++ b/dom/xbl/nsXBLContentSink.h
@@ -87,17 +87,18 @@ protected:
 
     bool NotifyForDocElement() override { return false; }
 
     nsresult CreateElement(const char16_t** aAtts, uint32_t aAttsCount,
                            mozilla::dom::NodeInfo* aNodeInfo, uint32_t aLineNumber,
                            nsIContent** aResult, bool* aAppendContent,
                            mozilla::dom::FromParser aFromParser) override;
 
-    nsresult AddAttributes(const char16_t** aAtts, Element* aElement) override;
+    nsresult AddAttributes(const char16_t** aAtts,
+                           nsIContent* aContent) override;
 
 #ifdef MOZ_XUL
     nsresult AddAttributesToXULPrototype(const char16_t **aAtts,
                                          uint32_t aAttsCount,
                                          nsXULPrototypeElement* aElement);
 #endif
 
     // Our own helpers for constructing XBL prototype objects.
--- a/dom/xbl/nsXBLPrototypeBinding.cpp
+++ b/dom/xbl/nsXBLPrototypeBinding.cpp
@@ -57,38 +57,38 @@ using namespace mozilla::dom;
 // Helper Classes =====================================================================
 
 // nsXBLAttributeEntry and helpers.  This class is used to efficiently handle
 // attribute changes in anonymous content.
 
 class nsXBLAttributeEntry {
 public:
   nsXBLAttributeEntry(nsAtom* aSrcAtom, nsAtom* aDstAtom,
-                      int32_t aDstNameSpace, Element* aElement)
-    : mElement(aElement),
+                      int32_t aDstNameSpace, nsIContent* aContent)
+    : mElement(aContent),
       mSrcAttribute(aSrcAtom),
       mDstAttribute(aDstAtom),
       mDstNameSpace(aDstNameSpace),
       mNext(nullptr) { }
 
   ~nsXBLAttributeEntry() {
     NS_CONTENT_DELETE_LIST_MEMBER(nsXBLAttributeEntry, this, mNext);
   }
 
   nsAtom* GetSrcAttribute() { return mSrcAttribute; }
   nsAtom* GetDstAttribute() { return mDstAttribute; }
   int32_t GetDstNameSpace() { return mDstNameSpace; }
 
-  Element* GetElement() { return mElement; }
+  nsIContent* GetElement() { return mElement; }
 
   nsXBLAttributeEntry* GetNext() { return mNext; }
   void SetNext(nsXBLAttributeEntry* aEntry) { mNext = aEntry; }
 
 protected:
-  Element* mElement;
+  nsIContent* mElement;
 
   RefPtr<nsAtom> mSrcAttribute;
   RefPtr<nsAtom> mDstAttribute;
   int32_t mDstNameSpace;
   nsXBLAttributeEntry* mNext;
 };
 
 // =============================================================================
@@ -108,17 +108,17 @@ nsXBLPrototypeBinding::nsXBLPrototypeBin
   mBaseNameSpaceID(kNameSpaceID_None)
 {
   MOZ_COUNT_CTOR(nsXBLPrototypeBinding);
 }
 
 nsresult
 nsXBLPrototypeBinding::Init(const nsACString& aID,
                             nsXBLDocumentInfo* aInfo,
-                            Element* aElement,
+                            nsIContent* aElement,
                             bool aFirstBinding)
 {
   nsresult rv = aInfo->DocumentURI()->Clone(getter_AddRefs(mBindingURI));
   NS_ENSURE_SUCCESS(rv, rv);
 
   // The binding URI might be an immutable URI (e.g. for about: URIs). In that case,
   // we'll fail in SetRef below, but that doesn't matter much for now.
   if (aFirstBinding) {
@@ -175,17 +175,18 @@ nsXBLPrototypeBinding::Trace(const Trace
 {
   if (mImplementation)
     mImplementation->Trace(aCallbacks, aClosure);
 }
 
 void
 nsXBLPrototypeBinding::Initialize()
 {
-  if (Element* content = GetImmediateChild(nsGkAtoms::content)) {
+  nsIContent* content = GetImmediateChild(nsGkAtoms::content);
+  if (content) {
     ConstructAttributeTable(content);
   }
 }
 
 nsXBLPrototypeBinding::~nsXBLPrototypeBinding(void)
 {
   delete mImplementation;
   MOZ_COUNT_DTOR(nsXBLPrototypeBinding);
@@ -201,17 +202,17 @@ nsXBLPrototypeBinding::SetBasePrototype(
     NS_ERROR("Base XBL prototype binding is already defined!");
     return;
   }
 
   mBaseBinding = aBinding;
 }
 
 void
-nsXBLPrototypeBinding::SetBindingElement(Element* aElement)
+nsXBLPrototypeBinding::SetBindingElement(nsIContent* aElement)
 {
   mBinding = aElement;
   if (mBinding->AttrValueIs(kNameSpaceID_None, nsGkAtoms::inheritstyle,
                             nsGkAtoms::_false, eCaseMatters))
     mInheritStyle = false;
 
   mChromeOnlyContent = mBinding->AttrValueIs(kNameSpaceID_None,
                                              nsGkAtoms::chromeOnlyContent,
@@ -317,38 +318,39 @@ nsXBLPrototypeBinding::InstallImplementa
   return NS_OK;
 }
 
 // XXXbz this duplicates lots of SetAttrs
 void
 nsXBLPrototypeBinding::AttributeChanged(nsAtom* aAttribute,
                                         int32_t aNameSpaceID,
                                         bool aRemoveFlag,
-                                        Element* aChangedElement,
+                                        nsIContent* aChangedElement,
                                         nsIContent* aAnonymousContent,
                                         bool aNotify)
 {
   if (!mAttributeTable)
     return;
 
   InnerAttributeTable *attributesNS = mAttributeTable->Get(aNameSpaceID);
   if (!attributesNS)
     return;
 
   nsXBLAttributeEntry* xblAttr = attributesNS->Get(aAttribute);
   if (!xblAttr)
     return;
 
   // Iterate over the elements in the array.
-  RefPtr<Element> content = GetImmediateChild(nsGkAtoms::content);
+  nsCOMPtr<nsIContent> content = GetImmediateChild(nsGkAtoms::content);
   while (xblAttr) {
-    Element* element = xblAttr->GetElement();
+    nsIContent* element = xblAttr->GetElement();
 
-    RefPtr<Element> realElement =
-      LocateInstance(aChangedElement, content, aAnonymousContent, element);
+    nsCOMPtr<nsIContent> realElement = LocateInstance(aChangedElement, content,
+                                                      aAnonymousContent,
+                                                      element);
 
     if (realElement) {
       // Hold a strong reference here so that the atom doesn't go away during
       // UnsetAttr.
       RefPtr<nsAtom> dstAttr = xblAttr->GetDstAttribute();
       int32_t dstNs = xblAttr->GetDstNameSpace();
 
       if (aRemoveFlag)
@@ -429,24 +431,24 @@ bool
 nsXBLPrototypeBinding::ImplementsInterface(REFNSIID aIID) const
 {
   // Check our IID table.
   return !!mInterfaceTable.GetWeak(aIID);
 }
 
 // Internal helpers ///////////////////////////////////////////////////////////////////////
 
-Element*
+nsIContent*
 nsXBLPrototypeBinding::GetImmediateChild(nsAtom* aTag)
 {
   for (nsIContent* child = mBinding->GetFirstChild();
        child;
        child = child->GetNextSibling()) {
     if (child->NodeInfo()->Equals(aTag, kNameSpaceID_XBL)) {
-      return child->AsElement();
+      return child;
     }
   }
 
   return nullptr;
 }
 
 nsresult
 nsXBLPrototypeBinding::InitClass(const nsString& aClassName,
@@ -454,51 +456,45 @@ nsXBLPrototypeBinding::InitClass(const n
                                  JS::Handle<JSObject*> aScriptObject,
                                  JS::MutableHandle<JSObject*> aClassObject,
                                  bool* aNew)
 {
   return nsXBLBinding::DoInitJSClass(aContext, aScriptObject,
                                      aClassName, this, aClassObject, aNew);
 }
 
-Element*
-nsXBLPrototypeBinding::LocateInstance(Element* aBoundElement,
+nsIContent*
+nsXBLPrototypeBinding::LocateInstance(nsIContent* aBoundElement,
                                       nsIContent* aTemplRoot,
                                       nsIContent* aCopyRoot,
-                                      Element* aTemplChild)
+                                      nsIContent* aTemplChild)
 {
   // XXX We will get in trouble if the binding instantiation deviates from the template
   // in the prototype.
   if (aTemplChild == aTemplRoot || !aTemplChild)
     return nullptr;
 
-  Element* templParent = aTemplChild->GetParentElement();
+  nsIContent* templParent = aTemplChild->GetParent();
 
   // We may be disconnected from our parent during cycle collection.
   if (!templParent)
     return nullptr;
 
   nsIContent *copyParent =
     templParent == aTemplRoot ? aCopyRoot :
                    LocateInstance(aBoundElement, aTemplRoot, aCopyRoot, templParent);
 
   if (!copyParent)
     return nullptr;
 
-  nsIContent* child = copyParent->GetChildAt(templParent->IndexOf(aTemplChild));
-  if (child && child->IsElement()) {
-    return child->AsElement();
-  }
-  return nullptr;
+  return copyParent->GetChildAt(templParent->IndexOf(aTemplChild));
 }
 
 void
-nsXBLPrototypeBinding::SetInitialAttributes(
-    Element* aBoundElement,
-    nsIContent* aAnonymousContent)
+nsXBLPrototypeBinding::SetInitialAttributes(nsIContent* aBoundElement, nsIContent* aAnonymousContent)
 {
   if (!mAttributeTable) {
     return;
   }
 
   for (auto iter1 = mAttributeTable->Iter(); !iter1.Done(); iter1.Next()) {
     InnerAttributeTable* xblAttributes = iter1.UserData();
     if (xblAttributes) {
@@ -527,19 +523,19 @@ nsXBLPrototypeBinding::SetInitialAttribu
 
         if (attrPresent) {
           nsIContent* content = GetImmediateChild(nsGkAtoms::content);
 
           nsXBLAttributeEntry* curr = entry;
           while (curr) {
             nsAtom* dst = curr->GetDstAttribute();
             int32_t dstNs = curr->GetDstNameSpace();
-            Element* element = curr->GetElement();
+            nsIContent* element = curr->GetElement();
 
-            Element* realElement =
+            nsIContent* realElement =
               LocateInstance(aBoundElement, content,
                              aAnonymousContent, element);
 
             if (realElement) {
               realElement->SetAttr(dstNs, dst, value, false);
 
               // XXXndeakin shouldn't this be done in lieu of SetAttr?
               if ((dst == nsGkAtoms::text && dstNs == kNameSpaceID_XBL) ||
@@ -594,39 +590,39 @@ nsXBLPrototypeBinding::EnsureAttributeTa
     mAttributeTable =
         new nsClassHashtable<nsUint32HashKey, InnerAttributeTable>(2);
   }
 }
 
 void
 nsXBLPrototypeBinding::AddToAttributeTable(int32_t aSourceNamespaceID, nsAtom* aSourceTag,
                                            int32_t aDestNamespaceID, nsAtom* aDestTag,
-                                           Element* aElement)
+                                           nsIContent* aContent)
 {
     InnerAttributeTable* attributesNS = mAttributeTable->Get(aSourceNamespaceID);
     if (!attributesNS) {
       attributesNS = new InnerAttributeTable(2);
       mAttributeTable->Put(aSourceNamespaceID, attributesNS);
     }
 
     nsXBLAttributeEntry* xblAttr =
-      new nsXBLAttributeEntry(aSourceTag, aDestTag, aDestNamespaceID, aElement);
+      new nsXBLAttributeEntry(aSourceTag, aDestTag, aDestNamespaceID, aContent);
 
     nsXBLAttributeEntry* entry = attributesNS->Get(aSourceTag);
     if (!entry) {
       attributesNS->Put(aSourceTag, xblAttr);
     } else {
       while (entry->GetNext())
         entry = entry->GetNext();
       entry->SetNext(xblAttr);
     }
 }
 
 void
-nsXBLPrototypeBinding::ConstructAttributeTable(Element* aElement)
+nsXBLPrototypeBinding::ConstructAttributeTable(nsIContent* aElement)
 {
   // Don't add entries for <children> elements, since those will get
   // removed from the DOM when we construct the insertion point table.
   if (!aElement->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) {
     nsAutoString inherits;
     aElement->GetAttr(kNameSpaceID_XBL, nsGkAtoms::inherits, inherits);
 
     if (!inherits.IsEmpty()) {
@@ -691,19 +687,17 @@ nsXBLPrototypeBinding::ConstructAttribut
       free(str);
     }
   }
 
   // Recur into our children.
   for (nsIContent* child = aElement->GetFirstChild();
        child;
        child = child->GetNextSibling()) {
-    if (child->IsElement()) {
-      ConstructAttributeTable(child->AsElement());
-    }
+    ConstructAttributeTable(child);
   }
 }
 
 nsresult
 nsXBLPrototypeBinding::ConstructInterfaceTable(const nsAString& aImpls)
 {
   if (!aImpls.IsEmpty()) {
     // Obtain the interface info manager that can tell us the IID
@@ -1196,21 +1190,22 @@ nsXBLPrototypeBinding::ReadContentNode(n
   int32_t namespaceID;
   nsresult rv = ReadNamespace(aStream, namespaceID);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // There is no content to read so just return.
   if (namespaceID == XBLBinding_Serialize_NoContent)
     return NS_OK;
 
+  nsCOMPtr<nsIContent> content;
+
   // If this is a text type, just read the string and return.
   if (namespaceID == XBLBinding_Serialize_TextNode ||
       namespaceID == XBLBinding_Serialize_CDATANode ||
       namespaceID == XBLBinding_Serialize_CommentNode) {
-    nsCOMPtr<nsIContent> content;
     switch (namespaceID) {
       case XBLBinding_Serialize_TextNode:
         content = new nsTextNode(aNim);
         break;
       case XBLBinding_Serialize_CDATANode:
         content = new CDATASection(aNim);
         break;
       case XBLBinding_Serialize_CommentNode:
@@ -1244,17 +1239,16 @@ nsXBLPrototypeBinding::ReadContentNode(n
   RefPtr<nsAtom> tagAtom = NS_Atomize(tag);
   RefPtr<NodeInfo> nodeInfo =
     aNim->GetNodeInfo(tagAtom, prefixAtom, namespaceID, nsIDOMNode::ELEMENT_NODE);
 
   uint32_t attrCount;
   rv = aStream->Read32(&attrCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  RefPtr<Element> element;
   // Create XUL prototype elements, or regular elements for other namespaces.
   // This needs to match the code in nsXBLContentSink::CreateElement.
 #ifdef MOZ_XUL
   if (namespaceID == kNameSpaceID_XUL) {
     nsIURI* documentURI = aDocument->GetDocumentURI();
 
     RefPtr<nsXULPrototypeElement> prototype = new nsXULPrototypeElement();
 
@@ -1294,22 +1288,27 @@ nsXBLPrototypeBinding::ReadContentNode(n
                             namespaceID, nsIDOMNode::ATTRIBUTE_NODE);
         attrs[i].mName.SetTo(ni);
       }
 
       rv = prototype->SetAttrAt(i, val, documentURI);
       NS_ENSURE_SUCCESS(rv, rv);
     }
 
+    nsCOMPtr<Element> result;
     nsresult rv =
-      nsXULElement::Create(prototype, aDocument, false, false, getter_AddRefs(element));
+      nsXULElement::Create(prototype, aDocument, false, false, getter_AddRefs(result));
     NS_ENSURE_SUCCESS(rv, rv);
-  } else {
+    content = result;
+  }
+  else {
 #endif
+    nsCOMPtr<Element> element;
     NS_NewElement(getter_AddRefs(element), nodeInfo.forget(), NOT_FROM_PARSER);
+    content = element;
 
     for (uint32_t i = 0; i < attrCount; i++) {
       rv = ReadNamespace(aStream, namespaceID);
       NS_ENSURE_SUCCESS(rv, rv);
 
       nsAutoString prefix, name, val;
       rv = aStream->ReadString(prefix);
       NS_ENSURE_SUCCESS(rv, rv);
@@ -1318,17 +1317,17 @@ nsXBLPrototypeBinding::ReadContentNode(n
       rv = aStream->ReadString(val);
       NS_ENSURE_SUCCESS(rv, rv);
 
       RefPtr<nsAtom> prefixAtom;
       if (!prefix.IsEmpty())
         prefixAtom = NS_Atomize(prefix);
 
       RefPtr<nsAtom> nameAtom = NS_Atomize(name);
-      element->SetAttr(namespaceID, nameAtom, prefixAtom, val, false);
+      content->SetAttr(namespaceID, nameAtom, prefixAtom, val, false);
     }
 
 #ifdef MOZ_XUL
   }
 #endif
 
   // Now read the attribute forwarding entries (xbl:inherits)
 
@@ -1344,38 +1343,38 @@ nsXBLPrototypeBinding::ReadContentNode(n
     NS_ENSURE_SUCCESS(rv, rv);
     rv = aStream->ReadString(destAttribute);
     NS_ENSURE_SUCCESS(rv, rv);
 
     RefPtr<nsAtom> srcAtom = NS_Atomize(srcAttribute);
     RefPtr<nsAtom> destAtom = NS_Atomize(destAttribute);
 
     EnsureAttributeTable();
-    AddToAttributeTable(srcNamespaceID, srcAtom, destNamespaceID, destAtom, element);
+    AddToAttributeTable(srcNamespaceID, srcAtom, destNamespaceID, destAtom, content);
 
     rv = ReadNamespace(aStream, srcNamespaceID);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   // Finally, read in the child nodes.
   uint32_t childCount;
   rv = aStream->Read32(&childCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
   for (uint32_t i = 0; i < childCount; i++) {
     nsCOMPtr<nsIContent> child;
     ReadContentNode(aStream, aDocument, aNim, getter_AddRefs(child));
 
     // Child may be null if this was a comment for example and can just be ignored.
     if (child) {
-      element->AppendChildTo(child, false);
+      content->AppendChildTo(child, false);
     }
   }
 
-  element.forget(aContent);
+  content.swap(*aContent);
   return NS_OK;
 }
 
 nsresult
 nsXBLPrototypeBinding::WriteContentNode(nsIObjectOutputStream* aStream,
                                         nsIContent* aNode)
 {
   nsresult rv;
@@ -1401,41 +1400,40 @@ nsXBLPrototypeBinding::WriteContentNode(
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsAutoString content;
     aNode->GetText()->AppendTo(content);
     return aStream->WriteWStringZ(content.get());
   }
 
   // Otherwise, this is an element.
-  Element* element = aNode->AsElement();
 
   // Write the namespace id followed by the tag name
-  rv = WriteNamespace(aStream, element->GetNameSpaceID());
+  rv = WriteNamespace(aStream, aNode->GetNameSpaceID());
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAutoString prefixStr;
-  element->NodeInfo()->GetPrefix(prefixStr);
+  aNode->NodeInfo()->GetPrefix(prefixStr);
   rv = aStream->WriteWStringZ(prefixStr.get());
   NS_ENSURE_SUCCESS(rv, rv);
 
-  rv = aStream->WriteWStringZ(nsDependentAtomString(element->NodeInfo()->NameAtom()).get());
+  rv = aStream->WriteWStringZ(nsDependentAtomString(aNode->NodeInfo()->NameAtom()).get());
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Write attributes
-  uint32_t count = element->GetAttrCount();
+  uint32_t count = aNode->GetAttrCount();
   rv = aStream->Write32(count);
   NS_ENSURE_SUCCESS(rv, rv);
 
   uint32_t i;
   for (i = 0; i < count; i++) {
     // Write out the namespace id, the namespace prefix, the local tag name,
     // and the value, in that order.
 
-    const BorrowedAttrInfo attrInfo = element->GetAttrInfoAt(i);
+    const BorrowedAttrInfo attrInfo = aNode->GetAttrInfoAt(i);
     const nsAttrName* name = attrInfo.mName;
 
     // XXXndeakin don't write out xbl:inherits?
     int32_t namespaceID = name->NamespaceID();
     rv = WriteNamespace(aStream, namespaceID);
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsAutoString prefixStr;
@@ -1459,17 +1457,17 @@ nsXBLPrototypeBinding::WriteContentNode(
     for (auto iter1 = mAttributeTable->Iter(); !iter1.Done(); iter1.Next()) {
       int32_t srcNamespace = iter1.Key();
       InnerAttributeTable* xblAttributes = iter1.UserData();
 
       for (auto iter2 = xblAttributes->Iter(); !iter2.Done(); iter2.Next()) {
         nsXBLAttributeEntry* entry = iter2.UserData();
 
         do {
-          if (entry->GetElement() == element) {
+          if (entry->GetElement() == aNode) {
             WriteNamespace(aStream, srcNamespace);
             aStream->WriteWStringZ(
               nsDependentAtomString(entry->GetSrcAttribute()).get());
             WriteNamespace(aStream, entry->GetDstNameSpace());
             aStream->WriteWStringZ(
               nsDependentAtomString(entry->GetDstAttribute()).get());
           }
 
@@ -1477,22 +1475,22 @@ nsXBLPrototypeBinding::WriteContentNode(
         } while (entry);
       }
     }
   }
   rv = aStream->Write8(XBLBinding_Serialize_NoMoreAttributes);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Finally, write out the child nodes.
-  count = element->GetChildCount();
+  count = aNode->GetChildCount();
   rv = aStream->Write32(count);
   NS_ENSURE_SUCCESS(rv, rv);
 
   for (i = 0; i < count; i++) {
-    rv = WriteContentNode(aStream, element->GetChildAt(i));
+    rv = WriteContentNode(aStream, aNode->GetChildAt(i));
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   return NS_OK;
 }
 
 nsresult
 nsXBLPrototypeBinding::ReadNamespace(nsIObjectInputStream* aStream,
--- a/dom/xbl/nsXBLPrototypeBinding.h
+++ b/dom/xbl/nsXBLPrototypeBinding.h
@@ -36,18 +36,18 @@ class nsXBLProtoImplField;
 // by XBLDocumentInfo().  Consumers who want to refcount things should refcount
 // that.
 class nsXBLPrototypeBinding final :
   public mozilla::SupportsWeakPtr<nsXBLPrototypeBinding>
 {
 public:
   MOZ_DECLARE_WEAKREFERENCE_TYPENAME(nsXBLPrototypeBinding)
 
-  mozilla::dom::Element* GetBindingElement() const { return mBinding; }
-  void SetBindingElement(mozilla::dom::Element* aElement);
+  nsIContent* GetBindingElement() const { return mBinding; }
+  void SetBindingElement(nsIContent* aElement);
 
   nsIURI* BindingURI() const { return mBindingURI; }
   nsIURI* AlternateBindingURI() const { return mAlternateBindingURI; }
   nsIURI* DocURI() const { return mXBLDocInfoWeak->DocumentURI(); }
   nsIURI* GetBaseBindingURI() const { return mBaseBindingURI; }
 
   // Checks if aURI refers to this binding by comparing to both possible
   // binding URIs.
@@ -106,28 +106,26 @@ public:
   nsresult ConstructInterfaceTable(const nsAString& aImpls);
 
   void SetImplementation(nsXBLProtoImpl* aImpl) { mImplementation = aImpl; }
   nsXBLProtoImpl* GetImplementation() { return mImplementation; }
   nsresult InstallImplementation(nsXBLBinding* aBinding);
   bool HasImplementation() const { return mImplementation != nullptr; }
 
   void AttributeChanged(nsAtom* aAttribute, int32_t aNameSpaceID,
-                        bool aRemoveFlag,
-                        mozilla::dom::Element* aChangedElement,
+                        bool aRemoveFlag, nsIContent* aChangedElement,
                         nsIContent* aAnonymousContent, bool aNotify);
 
   void SetBasePrototype(nsXBLPrototypeBinding* aBinding);
   nsXBLPrototypeBinding* GetBasePrototype() { return mBaseBinding; }
 
   nsXBLDocumentInfo* XBLDocumentInfo() const { return mXBLDocInfoWeak; }
   bool IsChrome() { return mXBLDocInfoWeak->IsChrome(); }
 
-  void SetInitialAttributes(mozilla::dom::Element* aBoundElement,
-                            nsIContent* aAnonymousContent);
+  void SetInitialAttributes(nsIContent* aBoundElement, nsIContent* aAnonymousContent);
 
   void AppendStyleSheet(mozilla::StyleSheet* aSheet);
   void RemoveStyleSheet(mozilla::StyleSheet* aSheet);
   void InsertStyleSheetAt(size_t aIndex, mozilla::StyleSheet* aSheet);
   mozilla::StyleSheet* StyleSheetAt(size_t aIndex) const;
   size_t SheetCount() const;
   bool HasStyleSheets() const;
   void AppendStyleSheetsTo(nsTArray<mozilla::StyleSheet*>& aResult) const;
@@ -243,58 +241,58 @@ public:
   ~nsXBLPrototypeBinding();
 
   // Init must be called after construction to initialize the prototype
   // binding.  It may well throw errors (eg on out-of-memory).  Do not confuse
   // this with the Initialize() method, which must be called after the
   // binding's handlers, properties, etc are all set.
   nsresult Init(const nsACString& aRef,
                 nsXBLDocumentInfo* aInfo,
-                mozilla::dom::Element* aElement,
+                nsIContent* aElement,
                 bool aFirstBinding = false);
 
   void Traverse(nsCycleCollectionTraversalCallback &cb) const;
   void Unlink();
   void Trace(const TraceCallbacks& aCallbacks, void *aClosure) const;
 
 // Internal member functions.
 public:
   /**
    * GetImmediateChild locates the immediate child of our binding element which
    * has the localname given by aTag and is in the XBL namespace.
    */
-  mozilla::dom::Element* GetImmediateChild(nsAtom* aTag);
-  mozilla::dom::Element* LocateInstance(mozilla::dom::Element* aBoundElt,
-                                        nsIContent* aTemplRoot,
-                                        nsIContent* aCopyRoot,
-                                        mozilla::dom::Element* aTemplChild);
+  nsIContent* GetImmediateChild(nsAtom* aTag);
+  nsIContent* LocateInstance(nsIContent* aBoundElt,
+                             nsIContent* aTemplRoot,
+                             nsIContent* aCopyRoot,
+                             nsIContent* aTemplChild);
 
   bool ChromeOnlyContent() { return mChromeOnlyContent; }
   bool BindToUntrustedContent() { return mBindToUntrustedContent; }
 
   typedef nsClassHashtable<nsRefPtrHashKey<nsAtom>, nsXBLAttributeEntry> InnerAttributeTable;
 
 protected:
   // Ensure that mAttributeTable has been created.
   void EnsureAttributeTable();
   // Ad an entry to the attribute table
   void AddToAttributeTable(int32_t aSourceNamespaceID, nsAtom* aSourceTag,
                            int32_t aDestNamespaceID, nsAtom* aDestTag,
-                           mozilla::dom::Element* aContent);
-  void ConstructAttributeTable(mozilla::dom::Element* aElement);
+                           nsIContent* aContent);
+  void ConstructAttributeTable(nsIContent* aElement);
   void CreateKeyHandlers();
 
 private:
   void EnsureResources();
 
 // MEMBER VARIABLES
 protected:
   nsCOMPtr<nsIURI> mBindingURI;
   nsCOMPtr<nsIURI> mAlternateBindingURI; // Alternate id-less URI that is only non-null on the first binding.
-  RefPtr<mozilla::dom::Element> mBinding; // Strong. We own a ref to our content element in the binding doc.
+  nsCOMPtr<nsIContent> mBinding; // Strong. We own a ref to our content element in the binding doc.
   nsAutoPtr<nsXBLPrototypeHandler> mPrototypeHandler; // Strong. DocInfo owns us, and we own the handlers.
 
   // the url of the base binding
   nsCOMPtr<nsIURI> mBaseBindingURI;
 
   nsXBLProtoImpl* mImplementation; // Our prototype implementation (includes methods, properties, fields,
                                    // the constructor, and the destructor).
 
--- a/dom/xbl/nsXBLService.cpp
+++ b/dom/xbl/nsXBLService.cpp
@@ -474,89 +474,89 @@ private:
   Element* mElement;
   bool mHadData;
   bool* mResolveStyle;
 };
 
 // This function loads a particular XBL file and installs all of the bindings
 // onto the element.
 nsresult
-nsXBLService::LoadBindings(Element* aElement, nsIURI* aURL,
+nsXBLService::LoadBindings(nsIContent* aContent, nsIURI* aURL,
                            nsIPrincipal* aOriginPrincipal,
                            nsXBLBinding** aBinding, bool* aResolveStyle)
 {
   NS_PRECONDITION(aOriginPrincipal, "Must have an origin principal");
 
   *aBinding = nullptr;
   *aResolveStyle = false;
 
-  AutoEnsureSubtreeStyled subtreeStyled(aElement);
+  AutoEnsureSubtreeStyled subtreeStyled(aContent->AsElement());
 
   if (MOZ_UNLIKELY(!aURL)) {
     return NS_OK;
   }
 
   // Easy case: The binding was already loaded.
-  nsXBLBinding* binding = aElement->GetXBLBinding();
+  nsXBLBinding* binding = aContent->GetXBLBinding();
   if (binding && !binding->MarkedForDeath() &&
       binding->PrototypeBinding()->CompareBindingURI(aURL)) {
     return NS_OK;
   }
 
-  nsCOMPtr<nsIDocument> document = aElement->OwnerDoc();
+  nsCOMPtr<nsIDocument> document = aContent->OwnerDoc();
 
   nsAutoCString urlspec;
   nsresult rv;
   bool ok = nsContentUtils::GetWrapperSafeScriptFilename(document, aURL,
                                                          urlspec, &rv);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   if (ok) {
     // Block an attempt to load a binding that has special wrapper
     // automation needs.
     return NS_OK;
   }
 
   if (binding) {
-    FlushStyleBindings(aElement);
+    FlushStyleBindings(aContent);
     binding = nullptr;
   }
 
   bool ready;
   RefPtr<nsXBLBinding> newBinding;
-  if (NS_FAILED(rv = GetBinding(aElement, aURL, false, aOriginPrincipal,
+  if (NS_FAILED(rv = GetBinding(aContent, aURL, false, aOriginPrincipal,
                                 &ready, getter_AddRefs(newBinding)))) {
     return rv;
   }
 
   if (!newBinding) {
 #ifdef DEBUG
     nsAutoCString str(NS_LITERAL_CSTRING("Failed to locate XBL binding. XBL is now using id instead of name to reference bindings. Make sure you have switched over.  The invalid binding name is: ") + aURL->GetSpecOrDefault());
     NS_ERROR(str.get());
 #endif
     return NS_OK;
   }
 
-  if (::IsAncestorBinding(document, aURL, aElement)) {
+  if (::IsAncestorBinding(document, aURL, aContent)) {
     return NS_ERROR_ILLEGAL_VALUE;
   }
 
-  AutoStyleElement styleElement(aElement, aResolveStyle);
+  AutoStyleElement styleElement(aContent->AsElement(), aResolveStyle);
 
   // We loaded a style binding.  It goes on the end.
   // Install the binding on the content node.
-  aElement->SetXBLBinding(newBinding);
+  aContent->SetXBLBinding(newBinding);
 
   {
     nsAutoScriptBlocker scriptBlocker;
 
     // Set the binding's bound element.
-    newBinding->SetBoundElement(aElement);
+    newBinding->SetBoundElement(aContent);
 
     // Tell the binding to build the anonymous content.
     newBinding->GenerateAnonymousContent();
 
     // Tell the binding to install event handlers
     newBinding->InstallEventHandlers();
 
     // Set up our properties
@@ -567,28 +567,30 @@ nsXBLService::LoadBindings(Element* aEle
     *aResolveStyle = newBinding->HasStyleSheets();
 
     newBinding.forget(aBinding);
   }
 
   return NS_OK;
 }
 
-void
-nsXBLService::FlushStyleBindings(Element* aElement)
+nsresult
+nsXBLService::FlushStyleBindings(nsIContent* aContent)
 {
-  nsCOMPtr<nsIDocument> document = aElement->OwnerDoc();
+  nsCOMPtr<nsIDocument> document = aContent->OwnerDoc();
 
-  nsXBLBinding* binding = aElement->GetXBLBinding();
+  nsXBLBinding *binding = aContent->GetXBLBinding();
   if (binding) {
     // Clear out the script references.
     binding->ChangeDocument(document, nullptr);
 
-    aElement->SetXBLBinding(nullptr); // Flush old style bindings
+    aContent->SetXBLBinding(nullptr); // Flush old style bindings
   }
+
+  return NS_OK;
 }
 
 //
 // AttachGlobalKeyHandler
 //
 // Creates a new key handler and prepares to listen to key events on the given
 // event receiver (either a document or an content node). If the receiver is content,
 // then extra work needs to be done to hook it up to the document (XXX WHY??)
--- a/dom/xbl/nsXBLService.h
+++ b/dom/xbl/nsXBLService.h
@@ -41,17 +41,17 @@ class nsXBLService final : public nsSupp
   }
 
   static nsXBLService* GetInstance() { return gInstance; }
 
   static bool IsChromeOrResourceURI(nsIURI* aURI);
 
   // This function loads a particular XBL file and installs all of the bindings
   // onto the element.  aOriginPrincipal must not be null here.
-  nsresult LoadBindings(mozilla::dom::Element* aElement, nsIURI* aURL,
+  nsresult LoadBindings(nsIContent* aContent, nsIURI* aURL,
                         nsIPrincipal* aOriginPrincipal,
                         nsXBLBinding** aBinding, bool* aResolveStyle);
 
   // Indicates whether or not a binding is fully loaded.
   nsresult BindingReady(nsIContent* aBoundElement, nsIURI* aURI, bool* aIsReady);
 
   // This method checks the hashtable and then calls FetchBindingDocument on a
   // miss.  aOriginPrincipal or aBoundDocument may be null to bypass security
@@ -67,18 +67,18 @@ class nsXBLService final : public nsSupp
   static nsresult AttachGlobalKeyHandler(mozilla::dom::EventTarget* aTarget);
   static nsresult DetachGlobalKeyHandler(mozilla::dom::EventTarget* aTarget);
 
 private:
   nsXBLService();
   virtual ~nsXBLService();
 
 protected:
-  // This function clears out the bindings on a given element.
-  void FlushStyleBindings(mozilla::dom::Element*);
+  // This function clears out the bindings on a given content node.
+  nsresult FlushStyleBindings(nsIContent* aContent);
 
   // This method synchronously loads and parses an XBL file.
   nsresult FetchBindingDocument(nsIContent* aBoundElement, nsIDocument* aBoundDocument,
                                 nsIURI* aDocumentURI, nsIURI* aBindingURI,
                                 nsIPrincipal* aOriginPrincipal, bool aForceSyncLoad,
                                 nsIDocument** aResult);
 
   /**
--- a/dom/xml/nsXMLContentSink.cpp
+++ b/dom/xml/nsXMLContentSink.cpp
@@ -975,17 +975,17 @@ nsXMLContentSink::HandleStartElement(con
   // on the stack inside CreateElement (which is effectively what the HTML sink
   // does), but that's hard with all the subclass overrides going on.
   nsCOMPtr<nsIContent> parent = GetCurrentContent();
 
   result = PushContent(content);
   NS_ENSURE_SUCCESS(result, result);
 
   // Set the attributes on the new content element
-  result = AddAttributes(aAtts, content->AsElement());
+  result = AddAttributes(aAtts, content);
 
   if (NS_OK == result) {
     // Store the element
     if (!SetDocElement(nameSpaceID, localName, content) && appendContent) {
       NS_ENSURE_TRUE(parent, NS_ERROR_UNEXPECTED);
 
       parent->AppendChildTo(content, false);
     }
@@ -1408,17 +1408,17 @@ nsXMLContentSink::ReportError(const char
 
   FlushTags();
 
   return NS_OK;
 }
 
 nsresult
 nsXMLContentSink::AddAttributes(const char16_t** aAtts,
-                                Element* aContent)
+                                nsIContent* aContent)
 {
   // Add tag attributes to the content attributes
   RefPtr<nsAtom> prefix, localName;
   while (*aAtts) {
     int32_t nameSpaceID;
     nsContentUtils::SplitExpatName(aAtts[0], getter_AddRefs(prefix),
                                    getter_AddRefs(localName), &nameSpaceID);
 
--- a/dom/xml/nsXMLContentSink.h
+++ b/dom/xml/nsXMLContentSink.h
@@ -94,17 +94,17 @@ protected:
 
   void ContinueInterruptedParsingIfEnabled();
 
   // Start layout.  If aIgnorePendingSheets is true, this will happen even if
   // we still have stylesheet loads pending.  Otherwise, we'll wait until the
   // stylesheets are all done loading.
   virtual void MaybeStartLayout(bool aIgnorePendingSheets);
 
-  virtual nsresult AddAttributes(const char16_t** aNode, Element* aElement);
+  virtual nsresult AddAttributes(const char16_t** aNode, nsIContent* aContent);
   nsresult AddText(const char16_t* aString, int32_t aLength);
 
   virtual bool OnOpenContainer(const char16_t **aAtts,
                                  uint32_t aAttsCount,
                                  int32_t aNameSpaceID,
                                  nsAtom* aTagName,
                                  uint32_t aLineNumber) { return true; }
   // Set the given content as the root element for the created document
--- a/dom/xml/nsXMLPrettyPrinter.cpp
+++ b/dom/xml/nsXMLPrettyPrinter.cpp
@@ -139,51 +139,51 @@ nsXMLPrettyPrinter::PrettyPrint(nsIDocum
 
     // Compute the binding URI.
     nsCOMPtr<nsIURI> bindingUri;
     rv = NS_NewURI(getter_AddRefs(bindingUri),
         NS_LITERAL_STRING("chrome://global/content/xml/XMLPrettyPrint.xml#prettyprint"));
     NS_ENSURE_SUCCESS(rv, rv);
 
     // Compute the bound element.
-    RefPtr<Element> rootElement = aDocument->GetRootElement();
-    NS_ENSURE_TRUE(rootElement, NS_ERROR_UNEXPECTED);
+    nsCOMPtr<nsIContent> rootCont = aDocument->GetRootElement();
+    NS_ENSURE_TRUE(rootCont, NS_ERROR_UNEXPECTED);
 
     // Grab the system principal.
     nsCOMPtr<nsIPrincipal> sysPrincipal;
     nsContentUtils::GetSecurityManager()->
         GetSystemPrincipal(getter_AddRefs(sysPrincipal));
 
     // Destroy any existing frames before we unbind anonymous content.
     // Note that the shell might be Destroy'ed by now (see bug 1415541).
-    if (!shell->IsDestroying()) {
-        shell->DestroyFramesForAndRestyle(rootElement);
+    if (!shell->IsDestroying() && rootCont->IsElement()) {
+        shell->DestroyFramesForAndRestyle(rootCont->AsElement());
     }
 
     // Load the bindings.
     RefPtr<nsXBLBinding> unused;
     bool ignored;
-    rv = xblService->LoadBindings(rootElement, bindingUri, sysPrincipal,
+    rv = xblService->LoadBindings(rootCont, bindingUri, sysPrincipal,
                                   getter_AddRefs(unused), &ignored);
     NS_ENSURE_SUCCESS(rv, rv);
 
     // Fire an event at the bound element to pass it |resultFragment|.
     RefPtr<CustomEvent> event =
-      NS_NewDOMCustomEvent(rootElement, nullptr, nullptr);
+      NS_NewDOMCustomEvent(rootCont, nullptr, nullptr);
     MOZ_ASSERT(event);
     nsCOMPtr<nsIWritableVariant> resultFragmentVariant = new nsVariant();
     rv = resultFragmentVariant->SetAsISupports(resultFragment);
     MOZ_ASSERT(NS_SUCCEEDED(rv));
     rv = event->InitCustomEvent(NS_LITERAL_STRING("prettyprint-dom-created"),
                                 /* bubbles = */ false, /* cancelable = */ false,
                                 /* detail = */ resultFragmentVariant);
     NS_ENSURE_SUCCESS(rv, rv);
     event->SetTrusted(true);
     bool dummy;
-    rv = rootElement->DispatchEvent(event, &dummy);
+    rv = rootCont->DispatchEvent(event, &dummy);
     NS_ENSURE_SUCCESS(rv, rv);
 
     // Observe the document so we know when to switch to "normal" view
     aDocument->AddObserver(this);
     mDocument = aDocument;
 
     NS_ADDREF_THIS();
 
--- a/dom/xslt/xpath/txMozillaXPathTreeWalker.cpp
+++ b/dom/xslt/xpath/txMozillaXPathTreeWalker.cpp
@@ -115,52 +115,45 @@ txXPathTreeWalker::moveToNextAttribute()
     return moveToValidAttribute(mPosition.mIndex + 1);
 }
 
 bool
 txXPathTreeWalker::moveToValidAttribute(uint32_t aStartIndex)
 {
     NS_ASSERTION(!mPosition.isDocument(), "documents doesn't have attrs");
 
-    if (!mPosition.Content()->IsElement()) {
-      return false;
-    }
-
-    Element* element = mPosition.Content()->AsElement();
-    uint32_t total = element->GetAttrCount();
+    uint32_t total = mPosition.Content()->GetAttrCount();
     if (aStartIndex >= total) {
         return false;
     }
 
     uint32_t index;
     for (index = aStartIndex; index < total; ++index) {
-        const nsAttrName* name = element->GetAttrNameAt(index);
+        const nsAttrName* name = mPosition.Content()->GetAttrNameAt(index);
 
         // We need to ignore XMLNS attributes.
         if (name->NamespaceID() != kNameSpaceID_XMLNS) {
             mPosition.mIndex = index;
 
             return true;
         }
     }
     return false;
 }
 
 bool
 txXPathTreeWalker::moveToNamedAttribute(nsAtom* aLocalName, int32_t aNSID)
 {
-    if (!mPosition.isContent() || !mPosition.Content()->IsElement()) {
+    if (!mPosition.isContent()) {
         return false;
     }
 
-    Element* element = mPosition.Content()->AsElement();
-
     const nsAttrName* name;
     uint32_t i;
-    for (i = 0; (name = element->GetAttrNameAt(i)); ++i) {
+    for (i = 0; (name = mPosition.Content()->GetAttrNameAt(i)); ++i) {
         if (name->Equals(aLocalName, aNSID)) {
             mPosition.mIndex = i;
 
             return true;
         }
     }
     return false;
 }
@@ -312,19 +305,18 @@ txXPathNodeUtils::getLocalName(const txX
             node->GetNodeName(target);
 
             return NS_Atomize(target);
         }
 
         return nullptr;
     }
 
-    // This is an attribute node, so we necessarily come from an element.
-    RefPtr<nsAtom> localName =
-      aNode.Content()->AsElement()->GetAttrNameAt(aNode.mIndex)->LocalName();
+    RefPtr<nsAtom> localName = aNode.Content()->
+        GetAttrNameAt(aNode.mIndex)->LocalName();
 
     return localName.forget();
 }
 
 nsAtom*
 txXPathNodeUtils::getPrefix(const txXPathNode& aNode)
 {
     if (aNode.isDocument()) {
@@ -332,17 +324,17 @@ txXPathNodeUtils::getPrefix(const txXPat
     }
 
     if (aNode.isContent()) {
         // All other nsIContent node types but elements have a null prefix
         // which is what we want here.
         return aNode.Content()->NodeInfo()->GetPrefixAtom();
     }
 
-    return aNode.Content()->AsElement()->GetAttrNameAt(aNode.mIndex)->GetPrefix();
+    return aNode.Content()->GetAttrNameAt(aNode.mIndex)->GetPrefix();
 }
 
 /* static */
 void
 txXPathNodeUtils::getLocalName(const txXPathNode& aNode, nsAString& aLocalName)
 {
     if (aNode.isDocument()) {
         aLocalName.Truncate();
@@ -365,17 +357,17 @@ txXPathNodeUtils::getLocalName(const txX
             return;
         }
 
         aLocalName.Truncate();
 
         return;
     }
 
-    aNode.Content()->AsElement()->GetAttrNameAt(aNode.mIndex)->LocalName()->
+    aNode.Content()->GetAttrNameAt(aNode.mIndex)->LocalName()->
       ToString(aLocalName);
 
     // Check for html
     if (aNode.Content()->NodeInfo()->NamespaceEquals(kNameSpaceID_None) &&
         aNode.Content()->IsHTMLElement()) {
         nsContentUtils::ASCIIToUpper(aLocalName);
     }
 }
@@ -399,32 +391,32 @@ txXPathNodeUtils::getNodeName(const txXP
             return;
         }
 
         aName.Truncate();
 
         return;
     }
 
-    aNode.Content()->AsElement()->GetAttrNameAt(aNode.mIndex)->GetQualifiedName(aName);
+    aNode.Content()->GetAttrNameAt(aNode.mIndex)->GetQualifiedName(aName);
 }
 
 /* static */
 int32_t
 txXPathNodeUtils::getNamespaceID(const txXPathNode& aNode)
 {
     if (aNode.isDocument()) {
         return kNameSpaceID_None;
     }
 
     if (aNode.isContent()) {
         return aNode.Content()->GetNameSpaceID();
     }
 
-    return aNode.Content()->AsElement()->GetAttrNameAt(aNode.mIndex)->NamespaceID();
+    return aNode.Content()->GetAttrNameAt(aNode.mIndex)->NamespaceID();
 }
 
 /* static */
 void
 txXPathNodeUtils::getNamespaceURI(const txXPathNode& aNode, nsAString& aURI)
 {
     nsContentUtils::NameSpaceManager()->GetNameSpaceURI(getNamespaceID(aNode), aURI);
 }
@@ -444,17 +436,17 @@ txXPathNodeUtils::getNodeType(const txXP
     return txXPathNodeType::ATTRIBUTE_NODE;
 }
 
 /* static */
 void
 txXPathNodeUtils::appendNodeValue(const txXPathNode& aNode, nsAString& aResult)
 {
     if (aNode.isAttribute()) {
-        const nsAttrName* name = aNode.Content()->AsElement()->GetAttrNameAt(aNode.mIndex);
+        const nsAttrName* name = aNode.Content()->GetAttrNameAt(aNode.mIndex);
 
         if (aResult.IsEmpty()) {
             aNode.Content()->GetAttr(name->NamespaceID(), name->LocalName(),
                                      aResult);
         }
         else {
             nsAutoString result;
             aNode.Content()->GetAttr(name->NamespaceID(), name->LocalName(),
@@ -695,18 +687,17 @@ txXPathNativeNode::createXPathNode(nsIDO
 /* static */
 nsINode*
 txXPathNativeNode::getNode(const txXPathNode& aNode)
 {
     if (!aNode.isAttribute()) {
         return aNode.mNode;
     }
 
-    const nsAttrName* name =
-      aNode.Content()->AsElement()->GetAttrNameAt(aNode.mIndex);
+    const nsAttrName* name = aNode.Content()->GetAttrNameAt(aNode.mIndex);
 
     nsAutoString namespaceURI;
     nsContentUtils::NameSpaceManager()->GetNameSpaceURI(name->NamespaceID(), namespaceURI);
 
     nsCOMPtr<Element> element = do_QueryInterface(aNode.mNode);
     nsDOMAttributeMap* map = element->Attributes();
     return map->GetNamedItemNS(namespaceURI,
                                nsDependentAtomString(name->LocalName()));
--- a/dom/xslt/xslt/txMozillaTextOutput.cpp
+++ b/dom/xslt/xslt/txMozillaTextOutput.cpp
@@ -15,17 +15,16 @@
 #include "txURIUtils.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsContentUtils.h"
 #include "nsGkAtoms.h"
 #include "mozilla/Encoding.h"
 #include "nsTextNode.h"
 #include "nsNameSpaceManager.h"
 
-using namespace mozilla;
 using namespace mozilla::dom;
 
 txMozillaTextOutput::txMozillaTextOutput(nsITransformObserver* aObserver)
 {
     MOZ_COUNT_CTOR(txMozillaTextOutput);
     mObserver = do_GetWeakReference(aObserver);
 }
 
@@ -192,43 +191,38 @@ txMozillaTextOutput::createResultDocumen
           mDocument->CreateElem(nsDependentAtomString(nsGkAtoms::result),
                                 nsGkAtoms::transformiix, namespaceID);
 
 
         rv = mDocument->AppendChildTo(mTextParent, true);
         NS_ENSURE_SUCCESS(rv, rv);
     }
     else {
-        RefPtr<Element> html, head, body;
+        nsCOMPtr<nsIContent> html, head, body;
         rv = createXHTMLElement(nsGkAtoms::html, getter_AddRefs(html));
         NS_ENSURE_SUCCESS(rv, rv);
 
         rv = createXHTMLElement(nsGkAtoms::head, getter_AddRefs(head));
         NS_ENSURE_SUCCESS(rv, rv);
 
         rv = html->AppendChildTo(head, false);
         NS_ENSURE_SUCCESS(rv, rv);
 
         rv = createXHTMLElement(nsGkAtoms::body, getter_AddRefs(body));
         NS_ENSURE_SUCCESS(rv, rv);
 
         rv = html->AppendChildTo(body, false);
         NS_ENSURE_SUCCESS(rv, rv);
 
-        {
-          RefPtr<Element> textParent;
-          rv = createXHTMLElement(nsGkAtoms::pre, getter_AddRefs(textParent));
-          NS_ENSURE_SUCCESS(rv, rv);
-          mTextParent = textParent.forget();
-        }
+        rv = createXHTMLElement(nsGkAtoms::pre, getter_AddRefs(mTextParent));
+        NS_ENSURE_SUCCESS(rv, rv);
 
-        rv = mTextParent->AsElement()->SetAttr(kNameSpaceID_None,
-                                               nsGkAtoms::id,
-                                               NS_LITERAL_STRING("transformiixResult"),
-                                               false);
+        rv = mTextParent->SetAttr(kNameSpaceID_None, nsGkAtoms::id,
+                                  NS_LITERAL_STRING("transformiixResult"),
+                                  false);
         NS_ENSURE_SUCCESS(rv, rv);
 
         rv = body->AppendChildTo(mTextParent, false);
         NS_ENSURE_SUCCESS(rv, rv);
 
         rv = mDocument->AppendChildTo(html, true);
         NS_ENSURE_SUCCESS(rv, rv);
     }
@@ -251,14 +245,15 @@ txMozillaTextOutput::startElement(nsAtom
 }
 
 void txMozillaTextOutput::getOutputDocument(nsIDOMDocument** aDocument)
 {
     CallQueryInterface(mDocument, aDocument);
 }
 
 nsresult
-txMozillaTextOutput::createXHTMLElement(nsAtom* aName, Element** aResult)
+txMozillaTextOutput::createXHTMLElement(nsAtom* aName,
+                                        nsIContent** aResult)
 {
     nsCOMPtr<Element> element = mDocument->CreateHTMLElement(aName);
     element.forget(aResult);
     return NS_OK;
 }
--- a/dom/xslt/xslt/txMozillaTextOutput.h
+++ b/dom/xslt/xslt/txMozillaTextOutput.h
@@ -11,37 +11,31 @@
 #include "nsWeakPtr.h"
 #include "txOutputFormat.h"
 
 class nsIDOMDocumentFragment;
 class nsITransformObserver;
 class nsIDocument;
 class nsIContent;
 
-namespace mozilla {
-namespace dom {
-class Element;
-}
-}
-
 class txMozillaTextOutput : public txAOutputXMLEventHandler
 {
 public:
     explicit txMozillaTextOutput(nsITransformObserver* aObserver);
     explicit txMozillaTextOutput(nsIDOMDocumentFragment* aDest);
     virtual ~txMozillaTextOutput();
 
     TX_DECL_TXAXMLEVENTHANDLER
     TX_DECL_TXAOUTPUTXMLEVENTHANDLER
 
     nsresult createResultDocument(nsIDocument* aSourceDocument,
                                   bool aLoadedAsData);
 
 private:
-    nsresult createXHTMLElement(nsAtom* aName, mozilla::dom::Element** aResult);
+    nsresult createXHTMLElement(nsAtom* aName, nsIContent** aResult);
 
     nsCOMPtr<nsIContent> mTextParent;
     nsWeakPtr mObserver;
     nsCOMPtr<nsIDocument> mDocument;
     txOutputFormat mOutputFormat;
     nsString mText;
 };
 
--- a/dom/xslt/xslt/txMozillaXMLOutput.cpp
+++ b/dom/xslt/xslt/txMozillaXMLOutput.cpp
@@ -683,17 +683,17 @@ txMozillaXMLOutput::startHTMLElement(nsI
         mTableStateStack.pop();
     }
 
     if (aElement->IsHTMLElement(nsGkAtoms::table) && aIsHTML) {
         mTableState = TABLE;
     }
     else if (aElement->IsHTMLElement(nsGkAtoms::tr) && aIsHTML &&
              NS_PTR_TO_INT32(mTableStateStack.peek()) == TABLE) {
-        RefPtr<Element> tbody;
+        nsCOMPtr<nsIContent> tbody;
         rv = createHTMLElement(nsGkAtoms::tbody, getter_AddRefs(tbody));
         NS_ENSURE_SUCCESS(rv, rv);
 
         rv = mCurrentNode->AppendChildTo(tbody, true);
         NS_ENSURE_SUCCESS(rv, rv);
 
         rv = mTableStateStack.push(NS_INT32_TO_PTR(ADDED_TBODY));
         NS_ENSURE_SUCCESS(rv, rv);
@@ -703,17 +703,17 @@ txMozillaXMLOutput::startHTMLElement(nsI
         }
 
         mCurrentNode = tbody;
     }
     else if (aElement->IsHTMLElement(nsGkAtoms::head) &&
              mOutputFormat.mMethod == eHTMLOutput) {
         // Insert META tag, according to spec, 16.2, like
         // <META http-equiv="Content-Type" content="text/html; charset=EUC-JP">
-        RefPtr<Element> meta;
+        nsCOMPtr<nsIContent> meta;
         rv = createHTMLElement(nsGkAtoms::meta, getter_AddRefs(meta));
         NS_ENSURE_SUCCESS(rv, rv);
 
         rv = meta->SetAttr(kNameSpaceID_None, nsGkAtoms::httpEquiv,
                            NS_LITERAL_STRING("Content-Type"), false);
         NS_ENSURE_SUCCESS(rv, rv);
 
         nsAutoString metacontent;
@@ -910,17 +910,18 @@ txMozillaXMLOutput::createResultDocument
             NS_ENSURE_SUCCESS(rv, rv);
         }
     }
 
     return NS_OK;
 }
 
 nsresult
-txMozillaXMLOutput::createHTMLElement(nsAtom* aName, Element** aResult)
+txMozillaXMLOutput::createHTMLElement(nsAtom* aName,
+                                      nsIContent** aResult)
 {
     NS_ASSERTION(mOutputFormat.mMethod == eHTMLOutput,
                  "need to adjust createHTMLElement");
 
     *aResult = nullptr;
 
     RefPtr<NodeInfo> ni;
     ni = mNodeInfoManager->GetNodeInfo(aName, nullptr,
--- a/dom/xslt/xslt/txMozillaXMLOutput.h
+++ b/dom/xslt/xslt/txMozillaXMLOutput.h
@@ -77,17 +77,17 @@ public:
                                   bool aLoadedAsData);
 
 private:
     nsresult createTxWrapper();
     nsresult startHTMLElement(nsIContent* aElement, bool aXHTML);
     nsresult endHTMLElement(nsIContent* aElement);
     void processHTTPEquiv(nsAtom* aHeader, const nsString& aValue);
     nsresult createHTMLElement(nsAtom* aName,
-                               mozilla::dom::Element** aResult);
+                               nsIContent** aResult);
 
     nsresult attributeInternal(nsAtom* aPrefix, nsAtom* aLocalName,
                                int32_t aNsID, const nsString& aValue);
     nsresult startElementInternal(nsAtom* aPrefix, nsAtom* aLocalName,
                                   int32_t aNsID);
 
     nsCOMPtr<nsIDocument> mDocument;
     nsCOMPtr<nsINode> mCurrentNode;     // This is updated once an element is
--- a/dom/xul/XULDocument.cpp
+++ b/dom/xul/XULDocument.cpp
@@ -153,17 +153,17 @@ struct BroadcasterMapEntry : public PLDH
 
 Element*
 nsRefMapEntry::GetFirstElement()
 {
     return mRefContentList.SafeElementAt(0);
 }
 
 void
-nsRefMapEntry::AppendAll(nsCOMArray<Element>* aElements)
+nsRefMapEntry::AppendAll(nsCOMArray<nsIContent>* aElements)
 {
     for (size_t i = 0; i < mRefContentList.Length(); ++i) {
         aElements->AppendObject(mRefContentList[i]);
     }
 }
 
 bool
 nsRefMapEntry::AddElement(Element* aElement)
@@ -1093,17 +1093,17 @@ XULDocument::ContentRemoved(nsIDocument*
 
 //----------------------------------------------------------------------
 //
 // nsIXULDocument interface
 //
 
 void
 XULDocument::GetElementsForID(const nsAString& aID,
-                              nsCOMArray<Element>& aElements)
+                              nsCOMArray<nsIContent>& aElements)
 {
     aElements.Clear();
 
     nsIdentifierMapEntry *entry = mIdentifierMap.GetEntry(aID);
     if (entry) {
         entry->AppendAllIdContent(&aElements);
     }
     nsRefMapEntry *refEntry = mRefMap.GetEntry(aID);
@@ -2054,17 +2054,17 @@ XULDocument::ApplyPersistentAttributes()
 
     return NS_OK;
 }
 
 
 nsresult
 XULDocument::ApplyPersistentAttributesInternal()
 {
-    nsCOMArray<Element> elements;
+    nsCOMArray<nsIContent> elements;
 
     nsAutoCString utf8uri;
     nsresult rv = mDocumentURI->GetSpec(utf8uri);
     if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
     }
     NS_ConvertUTF8toUTF16 uri(utf8uri);
 
@@ -2102,17 +2102,17 @@ XULDocument::ApplyPersistentAttributesIn
     }
 
     return NS_OK;
 }
 
 
 nsresult
 XULDocument::ApplyPersistentAttributesToElements(const nsAString &aID,
-                                                 nsCOMArray<Element>& aElements)
+                                                 nsCOMArray<nsIContent>& aElements)
 {
     nsAutoCString utf8uri;
     nsresult rv = mDocumentURI->GetSpec(utf8uri);
     if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
     }
     NS_ConvertUTF8toUTF16 uri(utf8uri);
 
@@ -2142,22 +2142,22 @@ XULDocument::ApplyPersistentAttributesTo
         RefPtr<nsAtom> attr = NS_Atomize(attrstr);
         if (NS_WARN_IF(!attr)) {
             return NS_ERROR_OUT_OF_MEMORY;
         }
 
         uint32_t cnt = aElements.Count();
 
         for (int32_t i = int32_t(cnt) - 1; i >= 0; --i) {
-            RefPtr<Element> element = aElements.SafeObjectAt(i);
+            nsCOMPtr<nsIContent> element = aElements.SafeObjectAt(i);
             if (!element) {
                  continue;
             }
 
-            Unused << element->SetAttr(kNameSpaceID_None, attr, value, true);
+            rv = element->SetAttr(kNameSpaceID_None, attr, value, PR_TRUE);
         }
     }
 
     return NS_OK;
 }
 
 void
 XULDocument::TraceProtos(JSTracer* aTrc)
@@ -3148,17 +3148,17 @@ XULDocument::MaybeBroadcast()
             }
             return;
         }
         if (!mHandlingDelayedAttrChange) {
             mHandlingDelayedAttrChange = true;
             for (uint32_t i = 0; i < mDelayedAttrChangeBroadcasts.Length(); ++i) {
                 nsAtom* attrName = mDelayedAttrChangeBroadcasts[i].mAttrName;
                 if (mDelayedAttrChangeBroadcasts[i].mNeedsAttrChange) {
-                    nsCOMPtr<Element> listener =
+                    nsCOMPtr<nsIContent> listener =
                         do_QueryInterface(mDelayedAttrChangeBroadcasts[i].mListener);
                     const nsString& value = mDelayedAttrChangeBroadcasts[i].mAttr;
                     if (mDelayedAttrChangeBroadcasts[i].mSetAttr) {
                         listener->SetAttr(kNameSpaceID_None, attrName, value,
                                           true);
                     } else {
                         listener->UnsetAttr(kNameSpaceID_None, attrName,
                                             true);
@@ -3605,17 +3605,17 @@ XULDocument::CreateOverlayElement(nsXULP
     if (NS_FAILED(rv)) return rv;
 
     element.forget(aResult);
     return NS_OK;
 }
 
 nsresult
 XULDocument::AddAttributes(nsXULPrototypeElement* aPrototype,
-                           Element* aElement)
+                           nsIContent* aElement)
 {
     nsresult rv;
 
     for (uint32_t i = 0; i < aPrototype->mNumAttributes; ++i) {
         nsXULPrototypeAttribute* protoattr = &(aPrototype->mAttributes[i]);
         nsAutoString  valueStr;
         protoattr->mValue.ToString(valueStr);
 
@@ -3689,22 +3689,22 @@ XULDocument::CreateTemplateBuilder(Eleme
     if (isTreeBuilder) {
         // Create and initialize a tree builder.
         RefPtr<nsXULTreeBuilder> builder = new nsXULTreeBuilder(aElement);
         nsresult rv = builder->Init();
         NS_ENSURE_SUCCESS(rv, rv);
 
         // Create a <treechildren> if one isn't there already.
         // XXXvarga what about attributes?
-        RefPtr<Element> bodyContent;
+        nsCOMPtr<nsIContent> bodyContent;
         nsXULContentUtils::FindChildByTag(aElement, kNameSpaceID_XUL,
                                           nsGkAtoms::treechildren,
                                           getter_AddRefs(bodyContent));
 
-        if (!bodyContent) {
+        if (! bodyContent) {
             bodyContent =
                 document->CreateElem(nsDependentAtomString(nsGkAtoms::treechildren),
                                      nullptr, kNameSpaceID_XUL);
 
             aElement->AppendChildTo(bodyContent, false);
         }
     }
     else {
@@ -3755,17 +3755,17 @@ XULDocument::AddPrototypeSheets()
 //
 
 nsForwardReference::Result
 XULDocument::OverlayForwardReference::Resolve()
 {
     // Resolve a forward reference from an overlay element; attempt to
     // hook it up into the main document.
     nsresult rv;
-    RefPtr<Element> target;
+    nsCOMPtr<nsIContent> target;
 
     nsIPresShell *shell = mDocument->GetShell();
     bool notify = shell && shell->DidInitialize();
 
     nsAutoString id;
     mOverlay->GetAttr(kNameSpaceID_None, nsGkAtoms::id, id);
     if (id.IsEmpty()) {
         // mOverlay is a direct child of <overlay> and has no id.
@@ -3813,157 +3813,160 @@ XULDocument::OverlayForwardReference::Re
 
     mResolved = true;
     return eResolve_Succeeded;
 }
 
 
 
 nsresult
-XULDocument::OverlayForwardReference::Merge(Element* aTargetElement,
-                                            Element* aOverlayElement,
+XULDocument::OverlayForwardReference::Merge(nsIContent* aTargetNode,
+                                            nsIContent* aOverlayNode,
                                             bool aNotify)
 {
     // This function is given:
-    // aTargetElement:  the element in the document whose 'id' attribute
-    //                  matches a toplevel node in our overlay.
-    // aOverlayElement: the element in the overlay document that matches
-    //                  an element in the actual document.
-    // aNotify:         whether or not content manipulation methods should
-    //                  use the aNotify parameter. After the initial
-    //                  reflow (i.e. in the dynamic overlay merge case),
-    //                  we want all the content manipulation methods we
-    //                  call to notify so that frames are constructed
-    //                  etc. Otherwise do not, since that's during initial
-    //                  document construction before StartLayout has been
-    //                  called which will do everything for us.
+    // aTargetNode:  the node in the document whose 'id' attribute
+    //               matches a toplevel node in our overlay.
+    // aOverlayNode: the node in the overlay document that matches
+    //               a node in the actual document.
+    // aNotify:      whether or not content manipulation methods should
+    //               use the aNotify parameter. After the initial
+    //               reflow (i.e. in the dynamic overlay merge case),
+    //               we want all the content manipulation methods we
+    //               call to notify so that frames are constructed
+    //               etc. Otherwise do not, since that's during initial
+    //               document construction before StartLayout has been
+    //               called which will do everything for us.
     //
     // This function merges the tree from the overlay into the tree in
     // the document, overwriting attributes and appending child content
     // nodes appropriately. (See XUL overlay reference for details)
 
     nsresult rv;
 
     // Merge attributes from the overlay content node to that of the
     // actual document.
     uint32_t i;
     const nsAttrName* name;
-    for (i = 0; (name = aOverlayElement->GetAttrNameAt(i)); ++i) {
+    for (i = 0; (name = aOverlayNode->GetAttrNameAt(i)); ++i) {
         // We don't want to swap IDs, they should be the same.
         if (name->Equals(nsGkAtoms::id))
             continue;
 
         // In certain cases merging command or observes is unsafe, so don't.
         if (!aNotify) {
-            if (aTargetElement->NodeInfo()->Equals(nsGkAtoms::observes,
-                                                   kNameSpaceID_XUL))
+            if (aTargetNode->NodeInfo()->Equals(nsGkAtoms::observes,
+                                                kNameSpaceID_XUL))
                 continue;
 
             if (name->Equals(nsGkAtoms::observes) &&
-                aTargetElement->HasAttr(kNameSpaceID_None, nsGkAtoms::observes))
+                aTargetNode->HasAttr(kNameSpaceID_None, nsGkAtoms::observes))
                 continue;
 
             if (name->Equals(nsGkAtoms::command) &&
-                aTargetElement->HasAttr(kNameSpaceID_None, nsGkAtoms::command) &&
-                !aTargetElement->NodeInfo()->Equals(nsGkAtoms::key,
-                                                    kNameSpaceID_XUL) &&
-                !aTargetElement->NodeInfo()->Equals(nsGkAtoms::menuitem,
-                                                   kNameSpaceID_XUL))
+                aTargetNode->HasAttr(kNameSpaceID_None, nsGkAtoms::command) &&
+                !aTargetNode->NodeInfo()->Equals(nsGkAtoms::key,
+                                                 kNameSpaceID_XUL) &&
+                !aTargetNode->NodeInfo()->Equals(nsGkAtoms::menuitem,
+                                                 kNameSpaceID_XUL))
                 continue;
         }
 
         int32_t nameSpaceID = name->NamespaceID();
         nsAtom* attr = name->LocalName();
         nsAtom* prefix = name->GetPrefix();
 
         nsAutoString value;
-        aOverlayElement->GetAttr(nameSpaceID, attr, value);
+        aOverlayNode->GetAttr(nameSpaceID, attr, value);
 
         // Element in the overlay has the 'removeelement' attribute set
         // so remove it from the actual document.
-        if (attr == nsGkAtoms::removeelement && value.EqualsLiteral("true")) {
-            nsCOMPtr<nsINode> parent = aTargetElement->GetParentNode();
+        if (attr == nsGkAtoms::removeelement &&
+            value.EqualsLiteral("true")) {
+
+            nsCOMPtr<nsINode> parent = aTargetNode->GetParentNode();
             if (!parent) return NS_ERROR_FAILURE;
-            rv = RemoveElement(parent, aTargetElement);
+            rv = RemoveElement(parent, aTargetNode);
             if (NS_FAILED(rv)) return rv;
+
             return NS_OK;
         }
 
-        rv = aTargetElement->SetAttr(nameSpaceID, attr, prefix, value, aNotify);
-        if (!NS_FAILED(rv) && !aNotify) {
-            rv = mDocument->BroadcastAttributeChangeFromOverlay(
-                    aTargetElement, nameSpaceID, attr, prefix, value);
-        }
+        rv = aTargetNode->SetAttr(nameSpaceID, attr, prefix, value, aNotify);
+        if (!NS_FAILED(rv) && !aNotify)
+            rv = mDocument->BroadcastAttributeChangeFromOverlay(aTargetNode,
+                                                                nameSpaceID,
+                                                                attr, prefix,
+                                                                value);
         if (NS_FAILED(rv)) return rv;
     }
 
 
     // Walk our child nodes, looking for elements that have the 'id'
     // attribute set. If we find any, we must do a parent check in the
     // actual document to ensure that the structure matches that of
     // the actual document. If it does, we can call ourselves and attempt
     // to merge inside that subtree. If not, we just append the tree to
     // the parent like any other.
 
-    uint32_t childCount = aOverlayElement->GetChildCount();
+    uint32_t childCount = aOverlayNode->GetChildCount();
 
     // This must be a strong reference since it will be the only
     // reference to a content object during part of this loop.
     nsCOMPtr<nsIContent> currContent;
 
     for (i = 0; i < childCount; ++i) {
-        currContent = aOverlayElement->GetFirstChild();
+        currContent = aOverlayNode->GetFirstChild();
 
         nsAtom *idAtom = currContent->GetID();
 
-        Element* elementInDocument = nullptr;
+        nsIContent *elementInDocument = nullptr;
         if (idAtom) {
             nsDependentAtomString id(idAtom);
 
             if (!id.IsEmpty()) {
-                nsIDocument *doc = aTargetElement->GetUncomposedDoc();
+                nsIDocument *doc = aTargetNode->GetUncomposedDoc();
                 //XXXsmaug should we use ShadowRoot::GetElementById()
                 //         if doc is null?
                 if (!doc) return NS_ERROR_FAILURE;
 
                 elementInDocument = doc->GetElementById(id);
             }
         }
 
         // The item has an 'id' attribute set, and we need to check with
         // the actual document to see if an item with this id exists at
         // this locale. If so, we want to merge the subtree under that
         // node. Otherwise, we just do an append as if the element had
         // no id attribute.
         if (elementInDocument) {
-            // Given two parents, aTargetElement and aOverlayElement, we want
+            // Given two parents, aTargetNode and aOverlayNode, we want
             // to call merge on currContent if we find an associated
             // node in the document with the same id as currContent that
             // also has aTargetNode as its parent.
 
-            nsIContent* elementParent = elementInDocument->GetParent();
+            nsIContent *elementParent = elementInDocument->GetParent();
 
             nsAtom *parentID = elementParent->GetID();
-            if (parentID && aTargetElement->GetID() == parentID) {
+            if (parentID &&
+                aTargetNode->AttrValueIs(kNameSpaceID_None, nsGkAtoms::id,
+                                         nsDependentAtomString(parentID),
+                                         eCaseMatters)) {
                 // The element matches. "Go Deep!"
-                //
-                // Note that currContent is necessarily an element, because
-                // elementInDocument can only be non-null when currContent has a
-                // non-null ID.
-                rv = Merge(elementInDocument, currContent->AsElement(), aNotify);
+                rv = Merge(elementInDocument, currContent, aNotify);
                 if (NS_FAILED(rv)) return rv;
-                aOverlayElement->RemoveChildAt(0, false);
+                aOverlayNode->RemoveChildAt(0, false);
 
                 continue;
             }
         }
 
-        aOverlayElement->RemoveChildAt(0, false);
-
-        rv = InsertElement(aTargetElement, currContent, aNotify);
+        aOverlayNode->RemoveChildAt(0, false);
+
+        rv = InsertElement(aTargetNode, currContent, aNotify);
         if (NS_FAILED(rv)) return rv;
     }
 
     return NS_OK;
 }
 
 
 
@@ -4084,17 +4087,17 @@ XULDocument::BroadcastAttributeChangeFro
     // We've got listeners: push the value.
     for (size_t i = entry->mListeners.Length() - 1; i != (size_t)-1; --i) {
         BroadcastListener* bl = entry->mListeners[i];
 
         if ((bl->mAttribute != aAttribute) &&
             (bl->mAttribute != nsGkAtoms::_asterisk))
             continue;
 
-        nsCOMPtr<Element> l = do_QueryReferent(bl->mListener);
+        nsCOMPtr<nsIContent> l = do_QueryReferent(bl->mListener);
         if (l) {
             rv = l->SetAttr(aNameSpaceID, aAttribute,
                             aPrefix, aValue, false);
             if (NS_FAILED(rv)) return rv;
         }
     }
     return rv;
 }
@@ -4247,17 +4250,18 @@ XULDocument::CheckBroadcasterHookup(Elem
     }
 
     *aNeedsHookup = false;
     *aDidResolve = true;
     return NS_OK;
 }
 
 nsresult
-XULDocument::InsertElement(nsINode* aParent, nsIContent* aChild, bool aNotify)
+XULDocument::InsertElement(nsINode* aParent, nsIContent* aChild,
+                           bool aNotify)
 {
     // Insert aChild appropriately into aParent, accounting for a
     // 'pos' attribute set on aChild.
 
     nsAutoString posStr;
     bool wasInserted = false;
 
     // insert after an element of a given id
@@ -4297,16 +4301,17 @@ XULDocument::InsertElement(nsINode* aPar
                     return rv;
 
                 wasInserted = true;
             }
         }
     }
 
     if (!wasInserted) {
+
         aChild->GetAttr(kNameSpaceID_None, nsGkAtoms::position, posStr);
         if (!posStr.IsEmpty()) {
             nsresult rv;
             // Positions are one-indexed.
             int32_t pos = posStr.ToInteger(&rv);
             // Note: if the insertion index (which is |pos - 1|) would be less
             // than 0 or greater than the number of children aParent has, then
             // don't insert, since the position is bogus.  Just skip on to
--- a/dom/xul/XULDocument.h
+++ b/dom/xul/XULDocument.h
@@ -59,17 +59,17 @@ public:
   }
   nsRefMapEntry(const nsRefMapEntry& aOther) :
     nsStringHashKey(&aOther.GetKey())
   {
     NS_ERROR("Should never be called");
   }
 
   mozilla::dom::Element* GetFirstElement();
-  void AppendAll(nsCOMArray<mozilla::dom::Element>* aElements);
+  void AppendAll(nsCOMArray<nsIContent>* aElements);
   /**
    * @return true if aElement was added, false if we failed due to OOM
    */
   bool AddElement(mozilla::dom::Element* aElement);
   /**
    * @return true if aElement was removed and it was the last content for
    * this ref, so this entry should be removed from the map
    */
@@ -121,17 +121,17 @@ public:
     NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
     NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
     NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
     NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
     NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTEWILLCHANGE
 
     // nsIXULDocument interface
     virtual void GetElementsForID(const nsAString& aID,
-                                  nsCOMArray<mozilla::dom::Element>& aElements) override;
+                                  nsCOMArray<nsIContent>& aElements) override;
 
     NS_IMETHOD AddSubtreeToDocument(nsIContent* aContent) override;
     NS_IMETHOD RemoveSubtreeFromDocument(nsIContent* aContent) override;
     NS_IMETHOD SetTemplateBuilderFor(nsIContent* aContent,
                                      nsIXULTemplateBuilder* aBuilder) override;
     NS_IMETHOD GetTemplateBuilderFor(nsIContent* aContent,
                                      nsIXULTemplateBuilder** aResult) override;
     NS_IMETHOD OnPrototypeLoadDone(bool aResumeWalk) override;
@@ -257,17 +257,17 @@ protected:
 
     nsresult
     LoadOverlayInternal(nsIURI* aURI, bool aIsDynamic, bool* aShouldReturn,
                         bool* aFailureFromContent);
 
     nsresult ApplyPersistentAttributes();
     nsresult ApplyPersistentAttributesInternal();
     nsresult ApplyPersistentAttributesToElements(const nsAString &aID,
-                                                 nsCOMArray<Element>& aElements);
+                                                 nsCOMArray<nsIContent>& aElements);
 
     nsresult
     AddElementToDocumentPre(Element* aElement);
 
     nsresult
     AddElementToDocumentPost(Element* aElement);
 
     nsresult
@@ -435,17 +435,17 @@ protected:
      * later resolution.
      */
     nsresult CreateOverlayElement(nsXULPrototypeElement* aPrototype,
                                   Element** aResult);
 
     /**
      * Add attributes from the prototype to the element.
      */
-    nsresult AddAttributes(nsXULPrototypeElement* aPrototype, Element* aElement);
+    nsresult AddAttributes(nsXULPrototypeElement* aPrototype, nsIContent* aElement);
 
     /**
      * The prototype-script of the current transcluded script that is being
      * loaded.  For document.write('<script src="nestedwrite.js"><\/script>')
      * to work, these need to be in a stack element type, and we need to hold
      * the top of stack here.
      */
     nsXULPrototypeScript* mCurrentScriptProto;
@@ -540,23 +540,23 @@ protected:
 
     /**
      * Used to hook up overlays
      */
     class OverlayForwardReference : public nsForwardReference
     {
     protected:
         XULDocument* mDocument;      // [WEAK]
-        nsCOMPtr<Element> mOverlay; // [OWNER]
+        nsCOMPtr<nsIContent> mOverlay; // [OWNER]
         bool mResolved;
 
-        nsresult Merge(Element* aTargetNode, Element* aOverlayNode, bool aNotify);
+        nsresult Merge(nsIContent* aTargetNode, nsIContent* aOverlayNode, bool aNotify);
 
     public:
-        OverlayForwardReference(XULDocument* aDocument, Element* aOverlay)
+        OverlayForwardReference(XULDocument* aDocument, nsIContent* aOverlay)
             : mDocument(aDocument), mOverlay(aOverlay), mResolved(false) {}
 
         virtual ~OverlayForwardReference();
 
         virtual Phase GetPhase() override { return eConstruction; }
         virtual Result Resolve() override;
     };
 
@@ -593,18 +593,16 @@ protected:
                            bool* aNeedsHookup,
                            bool* aDidResolve);
 
     void
     SynchronizeBroadcastListener(Element *aBroadcaster,
                                  Element *aListener,
                                  const nsAString &aAttr);
 
-    // FIXME: This should probably be renamed, there's nothing guaranteeing that
-    // aChild is an Element as far as I can tell!
     static
     nsresult
     InsertElement(nsINode* aParent, nsIContent* aChild, bool aNotify);
 
     static
     nsresult
     RemoveElement(nsINode* aParent, nsINode* aChild);
 
--- a/dom/xul/nsIXULDocument.h
+++ b/dom/xul/nsIXULDocument.h
@@ -8,22 +8,16 @@
 
 #include "nsISupports.h"
 #include "nsString.h"
 #include "nsCOMArray.h"
 
 class nsIXULTemplateBuilder;
 class nsIContent;
 
-namespace mozilla {
-namespace dom {
-class Element;
-}
-}
-
 
 // 81ba4be5-6cc5-478a-9b08-b3e7ed524455
 #define NS_IXULDOCUMENT_IID \
   {0x81ba4be5, 0x6cc5, 0x478a, {0x9b, 0x08, 0xb3, 0xe7, 0xed, 0x52, 0x44, 0x55}}
 
 
 /*
  * An XUL-specific extension to nsIDocument. Includes methods for
@@ -35,18 +29,17 @@ class nsIXULDocument : public nsISupport
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IXULDOCUMENT_IID)
 
   /**
    * Get the elements for a particular resource --- all elements whose 'id'
    * or 'ref' is aID. The nsCOMArray will be truncated and filled in with
    * nsIContent pointers.
    */
-  virtual void GetElementsForID(const nsAString& aID,
-                                nsCOMArray<mozilla::dom::Element>& aElements) = 0;
+  virtual void GetElementsForID(const nsAString& aID, nsCOMArray<nsIContent>& aElements) = 0;
 
   /**
    * Notify the XUL document that a subtree has been added
    */
   NS_IMETHOD AddSubtreeToDocument(nsIContent* aElement) = 0;
 
   /**
    * Notify the XUL document that a subtree has been removed
--- a/dom/xul/nsXULElement.cpp
+++ b/dom/xul/nsXULElement.cpp
@@ -275,17 +275,17 @@ NS_NewXULElement(Element** aResult, alre
     if (doc && !doc->AllowXULXBL()) {
         return NS_ERROR_NOT_AVAILABLE;
     }
 
     return nsContentUtils::NewXULOrHTMLElement(aResult, nodeInfo, aFromParser, nullptr, nullptr);
 }
 
 void
-NS_TrustedNewXULElement(Element** aResult,
+NS_TrustedNewXULElement(nsIContent** aResult,
                         already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
 {
     RefPtr<mozilla::dom::NodeInfo> ni = aNodeInfo;
     NS_PRECONDITION(ni, "need nodeinfo for non-proto Create");
 
     // Create an nsXULElement with the specified namespace and tag.
     NS_ADDREF(*aResult = new nsXULElement(ni.forget()));
 }
--- a/dom/xul/nsXULElement.h
+++ b/dom/xul/nsXULElement.h
@@ -798,17 +798,17 @@ protected:
 
     void UnregisterAccessKey(const nsAString& aOldValue);
     bool BoolAttrIsTrue(nsAtom* aName) const;
 
     friend nsresult
     NS_NewXULElement(mozilla::dom::Element** aResult, mozilla::dom::NodeInfo *aNodeInfo,
                      mozilla::dom::FromParser aFromParser, const nsAString* aIs);
     friend void
-    NS_TrustedNewXULElement(mozilla::dom::Element** aResult, mozilla::dom::NodeInfo *aNodeInfo);
+    NS_TrustedNewXULElement(nsIContent** aResult, mozilla::dom::NodeInfo *aNodeInfo);
 
     static already_AddRefed<nsXULElement>
     Create(nsXULPrototypeElement* aPrototype, mozilla::dom::NodeInfo *aNodeInfo,
            bool aIsScriptable, bool aIsRoot);
 
     bool IsReadWriteTextElement() const
     {
         return IsAnyOfXULElements(nsGkAtoms::textbox, nsGkAtoms::textarea) &&
--- a/dom/xul/templates/nsIXULTemplateBuilder.idl
+++ b/dom/xul/templates/nsIXULTemplateBuilder.idl
@@ -13,17 +13,16 @@ interface nsIXULTemplateQueryProcessor;
 interface nsIRDFResource;
 interface nsIRDFCompositeDataSource;
 interface nsIDOMDataTransfer;
 
 %{C++
 class nsAtom;
 %}
 [ptr] native nsAtomPtr(nsAtom);
-[ptr] native Element (mozilla::dom::Element);
 
 /**
  * A template builder, given an input source of data, a template, and a
  * reference point, generates a list of results from the input, and copies
  * part of the template for each result. Templates may generate content
  * recursively, using the same template, but with the previous iteration's
  * results as the reference point. As an example, for an XML datasource the
  * initial reference point would be a specific node in the DOM tree and a
@@ -289,17 +288,17 @@ interface nsIXULTemplateBuilder : nsISup
     void addRuleFilter(in nsIDOMNode aRule, in nsIXULTemplateRuleFilter aFilter);
 
     /**
      * Invoked lazily by a XUL element that needs its child content built.
      * If aForceCreation is true, then the contents of an element will be
      * generated even if it is closed. If false, the element will only
      * generate its contents if it is open. This behaviour is used with menus.
      */
-    [noscript] void createContents(in Element aElement,
+    [noscript] void createContents(in nsIContent aElement,
                                    in boolean aForceCreation);
 
     /**
      * Add a listener to this template builder. The template builder
      * holds a strong reference to the listener.
      */
     void addListener(in nsIXULBuilderListener aListener);
 
--- a/dom/xul/templates/nsXULContentBuilder.cpp
+++ b/dom/xul/templates/nsXULContentBuilder.cpp
@@ -67,17 +67,17 @@ using namespace mozilla::dom;
  *
  * If recursion is allowed, generation continues, where the generation node
  * becomes the container to insert into.
  */
 class nsXULContentBuilder : public nsXULTemplateBuilder
 {
 public:
     // nsIXULTemplateBuilder interface
-    NS_IMETHOD CreateContents(Element* aElement, bool aForceCreation) override;
+    NS_IMETHOD CreateContents(nsIContent* aElement, bool aForceCreation) override;
 
     using nsIXULTemplateBuilder::HasGeneratedContent;
     bool HasGeneratedContent(nsIRDFResource* aResource,
                              const nsAString& aTag,
                              ErrorResult& aError) override;
 
     using nsIXULTemplateBuilder::GetResultForContent;
     nsIXULTemplateResult* GetResultForContent(Element& aElement) override;
@@ -96,65 +96,65 @@ protected:
     {
         mSortState.Traverse(aCb);
     }
 
     virtual void Uninit(bool aIsFinal) override;
 
     // Implementation methods
     nsresult
-    OpenContainer(Element* aElement);
+    OpenContainer(nsIContent* aElement);
 
     nsresult
-    CloseContainer(Element* aElement);
+    CloseContainer(nsIContent* aElement);
 
     /**
      * Build content from a template for a given result. This will be called
      * recursively or on demand and will be called for every node in the
      * generated content tree.
      */
     nsresult
     BuildContentFromTemplate(nsIContent *aTemplateNode,
                              nsIContent *aResourceNode,
-                             Element* aRealElement,
+                             nsIContent *aRealNode,
                              bool aIsUnique,
                              bool aIsSelfReference,
                              nsIXULTemplateResult* aChild,
                              bool aNotify,
                              nsTemplateMatch* aMatch,
-                             Element** aContainer,
+                             nsIContent** aContainer,
                              int32_t* aNewIndexInContainer);
 
     /**
      * Copy the attributes from the template node to the node generated
      * from it, performing any substitutions.
      *
-     * @param aTemplateElement element within template
-     * @param aRealElement generated element to set attibutes upon
+     * @param aTemplateNode node within template
+     * @param aRealNode generated node to set attibutes upon
      * @param aResult result to look up variable->value bindings in
      * @param aNotify true to notify of DOM changes
      */
     nsresult
-    CopyAttributesToElement(Element* aTemplateElement,
-                            Element* aRealElement,
+    CopyAttributesToElement(nsIContent* aTemplateNode,
+                            nsIContent* aRealNode,
                             nsIXULTemplateResult* aResult,
                             bool aNotify);
 
     /**
      * Add any necessary persistent attributes (persist="...") from the
      * local store to a generated node.
      *
      * @param aTemplateNode node within template
      * @param aRealNode generated node to set persisted attibutes upon
      * @param aResult result to look up variable->value bindings in
      */
     nsresult
-    AddPersistentAttributes(Element* aTemplateElement,
+    AddPersistentAttributes(Element* aTemplateNode,
                             nsIXULTemplateResult* aResult,
-                            Element* aRealElement);
+                            nsIContent* aRealNode);
 
     /**
      * Recalculate any attributes that have variable references. This will
      * be called when a binding has been changed to update the attributes.
      * The attributes are copied from the node aTemplateNode in the template
      * to the generated node aRealNode, using the values from the result
      * aResult. This method will operate recursively.
      *
@@ -177,80 +177,80 @@ protected:
     /**
      * Create the appropriate generated content for aElement, by calling
      * CreateContainerContents.
      *
      * @param aElement element to generate content inside
      * @param aForceCreation true to force creation for closed items such as menus
      */
     nsresult
-    CreateTemplateAndContainerContents(Element* aElement,
+    CreateTemplateAndContainerContents(nsIContent* aElement,
                                        bool aForceCreation);
 
     /**
      * Generate the results for a template, by calling
      * CreateContainerContentsForQuerySet for each queryset.
      *
      * @param aElement element to generate content inside
      * @param aResult reference point for query
      * @param aForceCreation true to force creation for closed items such as menus
      * @param aNotify true to notify of DOM changes as each element is inserted
      * @param aNotifyAtEnd notify at the end of all DOM changes
      */
     nsresult
-    CreateContainerContents(Element* aElement,
+    CreateContainerContents(nsIContent* aElement,
                             nsIXULTemplateResult* aResult,
                             bool aForceCreation,
                             bool aNotify,
                             bool aNotifyAtEnd);
 
     /**
      * Generate the results for a query.
      *
      * @param aElement element to generate content inside
      * @param aResult reference point for query
      * @param aNotify true to notify of DOM changes
      * @param aContainer container content was added inside
      * @param aNewIndexInContainer index with container in which content was added
      */
     nsresult
-    CreateContainerContentsForQuerySet(Element* aElement,
+    CreateContainerContentsForQuerySet(nsIContent* aElement,
                                        nsIXULTemplateResult* aResult,
                                        bool aNotify,
                                        nsTemplateQuerySet* aQuerySet,
-                                       Element** aContainer,
+                                       nsIContent** aContainer,
                                        int32_t* aNewIndexInContainer);
 
     /**
      * Check if an element with a particular tag exists with a container.
      * If it is not present, append a new element with that tag into the
      * container.
      *
      * @param aParent parent container
      * @param aNameSpaceID namespace of tag to locate or create
      * @param aTag tag to locate or create
      * @param aNotify true to notify of DOM changes
      * @param aResult set to the found or created node.
      */
     nsresult
-    EnsureElementHasGenericChild(Element* aParent,
+    EnsureElementHasGenericChild(nsIContent* aParent,
                                  int32_t aNameSpaceID,
                                  nsAtom* aTag,
                                  bool aNotify,
-                                 Element** aResult);
+                                 nsIContent** aResult);
 
     bool
     IsOpen(nsIContent* aElement);
 
     nsresult
     RemoveGeneratedContent(nsIContent* aElement);
 
     nsresult
     GetElementsForResult(nsIXULTemplateResult* aResult,
-                         nsCOMArray<Element>& aElements);
+                         nsCOMArray<nsIContent>& aElements);
 
     nsresult
     CreateElement(int32_t aNameSpaceID,
                   nsAtom* aTag,
                   Element** aResult);
 
     /**
      * Set the container and empty attributes on a node. If
@@ -259,17 +259,17 @@ protected:
      * false.
      *
      * @param aElement element to set attributes on
      * @param aResult result to use to determine state of attributes
      * @param aIgnoreNonContainers true to not change for non-containers
      * @param aNotify true to notify of DOM changes
      */
     nsresult
-    SetContainerAttrs(Element* aElement,
+    SetContainerAttrs(nsIContent *aElement,
                       nsIXULTemplateResult* aResult,
                       bool aIgnoreNonContainers,
                       bool aNotify);
 
     virtual nsresult
     RebuildAll() override;
 
     // GetInsertionLocations, ReplaceMatch and SynchronizeResult are inherited
@@ -277,27 +277,27 @@ protected:
 
     /**
      * Return true if the result can be inserted into the template as
      * generated content. For the content builder, aLocations will be set
      * to the list of containers where the content should be inserted.
      */
     virtual bool
     GetInsertionLocations(nsIXULTemplateResult* aOldResult,
-                          nsCOMArray<Element>** aLocations) override;
+                          nsCOMArray<nsIContent>** aLocations) override;
 
     /**
      * Remove the content associated with aOldResult which no longer matches,
      * and/or generate content for a new match.
      */
     virtual nsresult
     ReplaceMatch(nsIXULTemplateResult* aOldResult,
                  nsTemplateMatch* aNewMatch,
                  nsTemplateRule* aNewMatchRule,
-                 Element* aContext) override;
+                 void *aContext) override;
 
     /**
      * Synchronize a result bindings with the generated content for that
      * result. This will be called as a result of the template builder's
      * ResultBindingChanged method.
      */
     virtual nsresult
     SynchronizeResult(nsIXULTemplateResult* aResult) override;
@@ -312,17 +312,17 @@ protected:
                         int32_t* aSortOrder);
 
     /**
      * Insert a generated node into the container where it should go according
      * to the current sort. aNode is the generated content node and aResult is
      * the result for the generated node.
      */
     nsresult
-    InsertSortedNode(Element* aContainer,
+    InsertSortedNode(nsIContent* aContainer,
                      nsIContent* aNode,
                      nsIXULTemplateResult* aResult,
                      bool aNotify);
 
     /**
      * Maintains a mapping between elements in the DOM and the matches
      * that they support.
      */
@@ -373,40 +373,40 @@ nsXULContentBuilder::Uninit(bool aIsFina
     mSortState.initialized = false;
 
     nsXULTemplateBuilder::Uninit(aIsFinal);
 }
 
 nsresult
 nsXULContentBuilder::BuildContentFromTemplate(nsIContent *aTemplateNode,
                                               nsIContent *aResourceNode,
-                                              Element* aRealElement,
+                                              nsIContent *aRealNode,
                                               bool aIsUnique,
                                               bool aIsSelfReference,
                                               nsIXULTemplateResult* aChild,
                                               bool aNotify,
                                               nsTemplateMatch* aMatch,
-                                              Element** aContainer,
+                                              nsIContent** aContainer,
                                               int32_t* aNewIndexInContainer)
 {
     // This is the mother lode. Here is where we grovel through an
     // element in the template, copying children from the template
     // into the "real" content tree, performing substitution as we go
     // by looking stuff up using the results.
     //
     //   |aTemplateNode| is the element in the "template tree", whose
     //   children we will duplicate and move into the "real" content
     //   tree.
     //
     //   |aResourceNode| is the element in the "real" content tree that
     //   has the "id" attribute set to an result's id. This is
     //   not directly used here, but rather passed down to the XUL
     //   sort service to perform container-level sort.
     //
-    //   |aRealElement| is the element in the "real" content tree to which
+    //   |aRealNode| is the element in the "real" content tree to which
     //   the new elements will be copied.
     //
     //   |aIsUnique| is set to "true" so long as content has been
     //   "unique" (or "above" the resource element) so far in the
     //   template.
     //
     //   |aIsSelfReference| should be set to "true" for cases where
     //   the reference and member variables are the same, indicating
@@ -443,24 +443,25 @@ nsXULContentBuilder::BuildContentFromTem
 
         nsAutoString id;
         aChild->GetId(id);
 
         MOZ_LOG(gXULTemplateLog, LogLevel::Debug,
                ("Tags: [Template: %s  Resource: %s  Real: %s] for id %s",
                 nsAtomCString(aTemplateNode->NodeInfo()->NameAtom()).get(),
                 nsAtomCString(aResourceNode->NodeInfo()->NameAtom()).get(),
-                nsAtomCString(aRealElement->NodeInfo()->NameAtom()).get(), NS_ConvertUTF16toUTF8(id).get()));
+                nsAtomCString(aRealNode->NodeInfo()->NameAtom()).get(), NS_ConvertUTF16toUTF8(id).get()));
     }
 
     // Iterate through all of the template children, constructing
     // "real" content model nodes for each "template" child.
     for (nsIContent* tmplKid = aTemplateNode->GetFirstChild();
          tmplKid;
          tmplKid = tmplKid->GetNextSibling()) {
+
         int32_t nameSpaceID = tmplKid->GetNameSpaceID();
 
         // Check whether this element is the generation element. The generation
         // element is the element that is cookie-cutter copied once for each
         // different result specified by |aChild|.
         //
         // Nodes that appear -above- the generation element
         // (that is, are ancestors of the generation element in the
@@ -505,65 +506,53 @@ nsXULContentBuilder::BuildContentFromTem
         // "uri='...'" syntax.)
         if (tmplKid->HasAttr(kNameSpaceID_None, nsGkAtoms::uri) && aMatch->IsActive()) {
             isGenerationElement = true;
             isUnique = false;
         }
 
         MOZ_ASSERT_IF(isGenerationElement, tmplKid->IsElement());
 
-        nsAtom* tag = tmplKid->NodeInfo()->NameAtom();
+        nsAtom *tag = tmplKid->NodeInfo()->NameAtom();
 
         if (MOZ_LOG_TEST(gXULTemplateLog, LogLevel::Debug)) {
             MOZ_LOG(gXULTemplateLog, LogLevel::Debug,
                    ("xultemplate[%p]     building %s %s %s",
                     this, nsAtomCString(tag).get(),
                     (isGenerationElement ? "[resource]" : ""),
                     (isUnique ? "[unique]" : "")));
         }
 
         // Set to true if the child we're trying to create now
         // already existed in the content model.
         bool realKidAlreadyExisted = false;
 
-        RefPtr<Element> realKid;
+        nsCOMPtr<nsIContent> realKid;
         if (isUnique) {
             // The content is "unique"; that is, we haven't descended
             // far enough into the template to hit the generation
             // element yet. |EnsureElementHasGenericChild()| will
             // conditionally create the element iff it isn't there
             // already.
-            //
-            // FIXME(emilio): The code below doesn't really make much sense if
-            // tmplKid is not an element. If it ever wasn't, we'd either find a
-            // child by tag, which doesn't really make sense, and event worse...
-            // If we didn't find it, we'd create an actual element with a text
-            // node tag for it.
-            //
-            // Both are completely bogus in tons of ways, so just avoid calling
-            // into EnsureElementHasGenericChild for non-elements, assuming the
-            // node is already there.
-            rv = NS_ELEMENT_WAS_THERE;
-            if (tmplKid->IsElement()) {
-              rv = EnsureElementHasGenericChild(aRealElement, nameSpaceID, tag, aNotify, getter_AddRefs(realKid));
-              if (NS_FAILED(rv))
-                  return rv;
-            }
+            rv = EnsureElementHasGenericChild(aRealNode, nameSpaceID, tag, aNotify, getter_AddRefs(realKid));
+            if (NS_FAILED(rv))
+                return rv;
 
             if (rv == NS_ELEMENT_WAS_THERE) {
                 realKidAlreadyExisted = true;
-            } else {
+            }
+            else {
                 // Potentially remember the index of this element as the first
                 // element that we've generated. Note that we remember
                 // this -before- we recurse!
                 if (aContainer && !*aContainer) {
-                    *aContainer = aRealElement;
+                    *aContainer = aRealNode;
                     NS_ADDREF(*aContainer);
 
-                    uint32_t indx = aRealElement->GetChildCount();
+                    uint32_t indx = aRealNode->GetChildCount();
 
                     // Since EnsureElementHasGenericChild() added us, make
                     // sure to subtract one for our real index.
                     *aNewIndexInContainer = indx - 1;
                 }
             }
 
             // Recurse until we get to the resource element. Since
@@ -572,17 +561,18 @@ nsXULContentBuilder::BuildContentFromTem
             // of the function will trip this to |false| as soon as we
             // encounter it.
             rv = BuildContentFromTemplate(tmplKid, aResourceNode, realKid, true,
                                           aIsSelfReference, aChild, aNotify, aMatch,
                                           aContainer, aNewIndexInContainer);
 
             if (NS_FAILED(rv))
                 return rv;
-        } else if (isGenerationElement) {
+        }
+        else if (isGenerationElement) {
             // It's the "resource" element. Create a new element using
             // the namespace ID and tag from the template element.
             nsCOMPtr<Element> element;
             rv = CreateElement(nameSpaceID, tag, getter_AddRefs(element));
             if (NS_FAILED(rv))
                 return rv;
             realKid = element.forget();
 
@@ -597,18 +587,19 @@ nsXULContentBuilder::BuildContentFromTem
                 return rv;
 
             rv = realKid->SetAttr(kNameSpaceID_None, nsGkAtoms::id, id, false);
             if (NS_FAILED(rv))
                 return rv;
 
             // Set up the element's 'container' and 'empty' attributes.
             SetContainerAttrs(realKid, aChild, true, false);
-        } else if (tag == nsGkAtoms::textnode &&
-                   nameSpaceID == kNameSpaceID_XUL) {
+        }
+        else if (tag == nsGkAtoms::textnode &&
+                 nameSpaceID == kNameSpaceID_XUL) {
             // <xul:text value="..."> is replaced by text of the
             // actual value of the 'rdf:resource' attribute for the
             // given node.
             // SynchronizeUsingTemplate contains code used to update textnodes,
             // so make sure to modify both when changing this
             nsAutoString attrValue;
             tmplKid->GetAttr(kNameSpaceID_None, nsGkAtoms::value, attrValue);
             if (!attrValue.IsEmpty()) {
@@ -616,68 +607,68 @@ nsXULContentBuilder::BuildContentFromTem
                 rv = SubstituteText(aChild, attrValue, value);
                 if (NS_FAILED(rv)) return rv;
 
                 RefPtr<nsTextNode> content =
                   new nsTextNode(mRoot->NodeInfo()->NodeInfoManager());
 
                 content->SetText(value, false);
 
-                rv = aRealElement->AppendChildTo(content, aNotify);
+                rv = aRealNode->AppendChildTo(content, aNotify);
                 if (NS_FAILED(rv)) return rv;
 
                 // XXX Don't bother remembering text nodes as the
                 // first element we've generated?
             }
-        } else if (tmplKid->IsNodeOfType(nsINode::eTEXT)) {
+        }
+        else if (tmplKid->IsNodeOfType(nsINode::eTEXT)) {
             nsCOMPtr<nsIDOMNode> tmplTextNode = do_QueryInterface(tmplKid);
             if (!tmplTextNode) {
                 NS_ERROR("textnode not implementing nsIDOMNode??");
                 return NS_ERROR_FAILURE;
             }
             nsCOMPtr<nsIDOMNode> clonedNode;
             tmplTextNode->CloneNode(false, 1, getter_AddRefs(clonedNode));
             nsCOMPtr<nsIContent> clonedContent = do_QueryInterface(clonedNode);
             if (!clonedContent) {
                 NS_ERROR("failed to clone textnode");
                 return NS_ERROR_FAILURE;
             }
-            rv = aRealElement->AppendChildTo(clonedContent, aNotify);
+            rv = aRealNode->AppendChildTo(clonedContent, aNotify);
             if (NS_FAILED(rv)) return rv;
-        } else {
+        }
+        else {
             // It's just a generic element. Create it!
             nsCOMPtr<Element> element;
             rv = CreateElement(nameSpaceID, tag, getter_AddRefs(element));
             if (NS_FAILED(rv)) return rv;
             realKid = element.forget();
         }
 
         if (realKid && !realKidAlreadyExisted) {
             // Potentially remember the index of this element as the
             // first element that we've generated.
             if (aContainer && !*aContainer) {
-                *aContainer = aRealElement;
+                *aContainer = aRealNode;
                 NS_ADDREF(*aContainer);
 
-                uint32_t indx = aRealElement->GetChildCount();
+                uint32_t indx = aRealNode->GetChildCount();
 
                 // Since we haven't inserted any content yet, our new
                 // index in the container will be the current count of
                 // elements in the container.
                 *aNewIndexInContainer = indx;
             }
 
             // Remember the template kid from which we created the
             // real kid. This allows us to sync back up with the
             // template to incrementally build content.
             mTemplateMap.Put(realKid, tmplKid);
 
-            rv = CopyAttributesToElement(tmplKid->AsElement(),
-                                         realKid, aChild,
-                                         false);
+            rv = CopyAttributesToElement(tmplKid, realKid, aChild, false);
             if (NS_FAILED(rv)) return rv;
 
             // Add any persistent attributes
             if (isGenerationElement) {
                 rv = AddPersistentAttributes(tmplKid->AsElement(), aChild,
                                              realKid);
                 if (NS_FAILED(rv)) return rv;
             }
@@ -707,85 +698,85 @@ nsXULContentBuilder::BuildContentFromTem
 
             // We'll _already_ have added the unique elements; but if
             // it's -not- unique, then use the XUL sort service now to
             // append the element to the content model.
             if (! isUnique) {
                 rv = NS_ERROR_UNEXPECTED;
 
                 if (isGenerationElement)
-                    rv = InsertSortedNode(aRealElement, realKid, aChild, aNotify);
+                    rv = InsertSortedNode(aRealNode, realKid, aChild, aNotify);
 
                 if (NS_FAILED(rv)) {
-                    rv = aRealElement->AppendChildTo(realKid, aNotify);
+                    rv = aRealNode->AppendChildTo(realKid, aNotify);
                     NS_ASSERTION(NS_SUCCEEDED(rv), "unable to insert element");
                 }
             }
         }
     }
 
     return NS_OK;
 }
 
 nsresult
-nsXULContentBuilder::CopyAttributesToElement(Element* aTemplateElement,
-                                             Element* aRealElement,
+nsXULContentBuilder::CopyAttributesToElement(nsIContent* aTemplateNode,
+                                             nsIContent* aRealNode,
                                              nsIXULTemplateResult* aResult,
                                              bool aNotify)
 {
     nsresult rv;
 
     // Copy all attributes from the template to the new element
-    uint32_t numAttribs = aTemplateElement->GetAttrCount();
+    uint32_t numAttribs = aTemplateNode->GetAttrCount();
 
     for (uint32_t attr = 0; attr < numAttribs; attr++) {
-        const nsAttrName* name = aTemplateElement->GetAttrNameAt(attr);
+        const nsAttrName* name = aTemplateNode->GetAttrNameAt(attr);
         int32_t attribNameSpaceID = name->NamespaceID();
         // Hold a strong reference here so that the atom doesn't go away
         // during UnsetAttr.
         RefPtr<nsAtom> attribName = name->LocalName();
 
         // XXXndeakin ignore namespaces until bug 321182 is fixed
         if (attribName != nsGkAtoms::id && attribName != nsGkAtoms::uri) {
             nsAutoString attribValue;
-            aTemplateElement->GetAttr(attribNameSpaceID, attribName, attribValue);
+            aTemplateNode->GetAttr(attribNameSpaceID, attribName, attribValue);
             if (!attribValue.IsEmpty()) {
                 nsAutoString value;
                 rv = SubstituteText(aResult, attribValue, value);
                 if (NS_FAILED(rv))
                     return rv;
 
                 // if the string is empty after substitutions, remove the
                 // attribute
                 if (!value.IsEmpty()) {
-                    rv = aRealElement->SetAttr(attribNameSpaceID,
+                    rv = aRealNode->SetAttr(attribNameSpaceID,
                                             attribName,
                                             name->GetPrefix(),
                                             value,
                                             aNotify);
                 }
                 else {
-                    rv = aRealElement->UnsetAttr(attribNameSpaceID,
+                    rv = aRealNode->UnsetAttr(attribNameSpaceID,
                                               attribName,
                                               aNotify);
                 }
 
                 if (NS_FAILED(rv))
                     return rv;
             }
         }
     }
 
     return NS_OK;
 }
 
 nsresult
 nsXULContentBuilder::AddPersistentAttributes(Element* aTemplateNode,
                                              nsIXULTemplateResult* aResult,
-                                             Element* aRealElement)
+                                             nsIContent* aRealNode)
 {
     if (!mRoot)
         return NS_OK;
 
     nsCOMPtr<nsIRDFResource> resource;
     nsresult rv = GetResultResource(aResult, getter_AddRefs(resource));
     NS_ENSURE_SUCCESS(rv, rv);
 
@@ -841,47 +832,45 @@ nsXULContentBuilder::AddPersistentAttrib
         NS_ASSERTION(value != nullptr, "unable to stomach that sort of node");
         if (! value)
             continue;
 
         const char16_t* valueStr;
         rv = value->GetValueConst(&valueStr);
         NS_ENSURE_SUCCESS(rv, rv);
 
-        rv = aRealElement->SetAttr(nameSpaceID, tag, nsDependentString(valueStr),
-                                   false);
+        rv = aRealNode->SetAttr(nameSpaceID, tag, nsDependentString(valueStr),
+                                false);
         NS_ENSURE_SUCCESS(rv, rv);
     }
 
     return NS_OK;
 }
 
 nsresult
 nsXULContentBuilder::SynchronizeUsingTemplate(nsIContent* aTemplateNode,
-                                              nsIContent* aRealNode,
+                                              nsIContent* aRealElement,
                                               nsIXULTemplateResult* aResult)
 {
     // check all attributes on the template node; if they reference a resource,
     // update the equivalent attribute on the content node
     nsresult rv;
-    if (aTemplateNode->IsElement() && aRealNode->IsElement()) {
-        rv = CopyAttributesToElement(aTemplateNode->AsElement(), aRealNode->AsElement(), aResult, true);
-        if (NS_FAILED(rv))
-            return rv;
-    }
+    rv = CopyAttributesToElement(aTemplateNode, aRealElement, aResult, true);
+    if (NS_FAILED(rv))
+        return rv;
 
     uint32_t count = aTemplateNode->GetChildCount();
 
     for (uint32_t loop = 0; loop < count; ++loop) {
         nsIContent *tmplKid = aTemplateNode->GetChildAt(loop);
 
         if (! tmplKid)
             break;
 
-        nsIContent *realKid = aRealNode->GetChildAt(loop);
+        nsIContent *realKid = aRealElement->GetChildAt(loop);
         if (! realKid)
             break;
 
         // check for text nodes and update them accordingly.
         // This code is similar to that in BuildContentFromTemplate
         if (tmplKid->NodeInfo()->Equals(nsGkAtoms::textnode,
                                         kNameSpaceID_XUL)) {
             nsAutoString attrValue;
@@ -922,17 +911,17 @@ nsXULContentBuilder::RemoveMember(nsICon
 
     // Remove from the template map
     mTemplateMap.Remove(aContent);
 
     return NS_OK;
 }
 
 nsresult
-nsXULContentBuilder::CreateTemplateAndContainerContents(Element* aElement,
+nsXULContentBuilder::CreateTemplateAndContainerContents(nsIContent* aElement,
                                                         bool aForceCreation)
 {
     // Generate both 1) the template content for the current element,
     // and 2) recursive subcontent (if the current element refers to a
     // container result).
 
     MOZ_LOG(gXULTemplateLog, LogLevel::Info,
            ("nsXULContentBuilder::CreateTemplateAndContainerContents start - flags: %d",
@@ -972,17 +961,17 @@ nsXULContentBuilder::CreateTemplateAndCo
 
     MOZ_LOG(gXULTemplateLog, LogLevel::Info,
            ("nsXULContentBuilder::CreateTemplateAndContainerContents end"));
 
     return NS_OK;
 }
 
 nsresult
-nsXULContentBuilder::CreateContainerContents(Element* aElement,
+nsXULContentBuilder::CreateContainerContents(nsIContent* aElement,
                                              nsIXULTemplateResult* aResult,
                                              bool aForceCreation,
                                              bool aNotify,
                                              bool aNotifyAtEnd)
 {
     if (!aForceCreation && !IsOpen(aElement))
         return NS_OK;
 
@@ -1027,17 +1016,17 @@ nsXULContentBuilder::CreateContainerCont
             return NS_OK;
 
         // Now mark the element's contents as being generated so that
         // any re-entrant calls don't trigger an infinite recursion.
         xulcontent->SetTemplateGenerated();
     }
 
     int32_t newIndexInContainer = -1;
-    Element* container = nullptr;
+    nsIContent* container = nullptr;
 
     int32_t querySetCount = mQuerySets.Length();
 
     for (int32_t r = 0; r < querySetCount; r++) {
         nsTemplateQuerySet* queryset = mQuerySets[r];
 
         nsAtom* tag = queryset->GetTag();
         if (tag && tag != aElement->NodeInfo()->NameAtom())
@@ -1055,21 +1044,21 @@ nsXULContentBuilder::CreateContainerCont
     }
 
     NS_IF_RELEASE(container);
 
     return NS_OK;
 }
 
 nsresult
-nsXULContentBuilder::CreateContainerContentsForQuerySet(Element* aElement,
+nsXULContentBuilder::CreateContainerContentsForQuerySet(nsIContent* aElement,
                                                         nsIXULTemplateResult* aResult,
                                                         bool aNotify,
                                                         nsTemplateQuerySet* aQuerySet,
-                                                        Element** aContainer,
+                                                        nsIContent** aContainer,
                                                         int32_t* aNewIndexInContainer)
 {
     if (MOZ_LOG_TEST(gXULTemplateLog, LogLevel::Debug)) {
         nsAutoString id;
         aResult->GetId(id);
         MOZ_LOG(gXULTemplateLog, LogLevel::Debug,
                ("nsXULContentBuilder::CreateContainerContentsForQuerySet start for ref %s\n",
                NS_ConvertUTF16toUTF8(id).get()));
@@ -1208,21 +1197,21 @@ nsXULContentBuilder::CreateContainerCont
             newmatch->mNext = existingmatch;
         }
     }
 
     return rv;
 }
 
 nsresult
-nsXULContentBuilder::EnsureElementHasGenericChild(Element* parent,
+nsXULContentBuilder::EnsureElementHasGenericChild(nsIContent* parent,
                                                   int32_t nameSpaceID,
                                                   nsAtom* tag,
                                                   bool aNotify,
-                                                  Element** result)
+                                                  nsIContent** result)
 {
     nsresult rv;
 
     rv = nsXULContentUtils::FindChildByTag(parent, nameSpaceID, tag, result);
     if (NS_FAILED(rv))
         return rv;
 
     if (rv == NS_RDF_NO_VALUE) {
@@ -1317,17 +1306,17 @@ nsXULContentBuilder::RemoveGeneratedCont
         }
     }
 
     return NS_OK;
 }
 
 nsresult
 nsXULContentBuilder::GetElementsForResult(nsIXULTemplateResult* aResult,
-                                          nsCOMArray<Element>& aElements)
+                                          nsCOMArray<nsIContent>& aElements)
 {
     // if the root has been removed from the document, just return
     // since there won't be any generated content any more
     nsCOMPtr<nsIXULDocument> xuldoc = do_QueryInterface(mRoot->GetComposedDoc());
     if (! xuldoc)
         return NS_OK;
 
     nsAutoString id;
@@ -1351,17 +1340,17 @@ nsXULContentBuilder::CreateElement(int32
     RefPtr<mozilla::dom::NodeInfo> nodeInfo =
         doc->NodeInfoManager()->GetNodeInfo(aTag, nullptr, aNameSpaceID,
                                             nsIDOMNode::ELEMENT_NODE);
 
     return NS_NewElement(aResult, nodeInfo.forget(), NOT_FROM_PARSER);
 }
 
 nsresult
-nsXULContentBuilder::SetContainerAttrs(Element* aElement,
+nsXULContentBuilder::SetContainerAttrs(nsIContent *aElement,
                                        nsIXULTemplateResult* aResult,
                                        bool aIgnoreNonContainers,
                                        bool aNotify)
 {
     NS_PRECONDITION(aResult != nullptr, "null ptr");
     if (! aResult)
         return NS_ERROR_NULL_POINTER;
 
@@ -1396,17 +1385,17 @@ nsXULContentBuilder::SetContainerAttrs(E
 
 
 //----------------------------------------------------------------------
 //
 // nsIXULTemplateBuilder methods
 //
 
 NS_IMETHODIMP
-nsXULContentBuilder::CreateContents(Element* aElement, bool aForceCreation)
+nsXULContentBuilder::CreateContents(nsIContent* aElement, bool aForceCreation)
 {
     NS_PRECONDITION(aElement != nullptr, "null ptr");
     if (! aElement)
         return NS_ERROR_NULL_POINTER;
 
     // don't build contents for closed elements. aForceCreation will be true
     // when a menu is about to be opened, so the content should be built anyway.
     if (!aForceCreation && !IsOpen(aElement))
@@ -1442,17 +1431,17 @@ nsXULContentBuilder::HasGeneratedContent
     NS_ConvertUTF8toUTF16 refID(uri);
 
     // just return if the node is no longer in a document
     nsCOMPtr<nsIXULDocument> xuldoc = do_QueryInterface(mRoot->GetComposedDoc());
     if (!xuldoc) {
         return false;
     }
 
-    nsCOMArray<Element> elements;
+    nsCOMArray<nsIContent> elements;
     xuldoc->GetElementsForID(refID, elements);
 
     uint32_t cnt = elements.Count();
 
     for (int32_t i = int32_t(cnt) - 1; i >= 0; --i) {
         nsCOMPtr<nsIContent> content = elements.SafeObjectAt(i);
 
         do {
@@ -1535,30 +1524,30 @@ nsXULContentBuilder::NodeWillBeDestroyed
 
 //----------------------------------------------------------------------
 //
 // nsXULTemplateBuilder methods
 //
 
 bool
 nsXULContentBuilder::GetInsertionLocations(nsIXULTemplateResult* aResult,
-                                           nsCOMArray<Element>** aLocations)
+                                           nsCOMArray<nsIContent>** aLocations)
 {
     *aLocations = nullptr;
 
     nsAutoString ref;
     nsresult rv = aResult->GetBindingFor(mRefVariable, ref);
     if (NS_FAILED(rv))
         return false;
 
     nsCOMPtr<nsIXULDocument> xuldoc = do_QueryInterface(mRoot->GetComposedDoc());
     if (! xuldoc)
         return false;
 
-    *aLocations = new nsCOMArray<Element>;
+    *aLocations = new nsCOMArray<nsIContent>;
     NS_ENSURE_TRUE(*aLocations, false);
 
     xuldoc->GetElementsForID(ref, **aLocations);
     uint32_t count = (*aLocations)->Count();
 
     bool found = false;
 
     for (uint32_t t = 0; t < count; t++) {
@@ -1584,83 +1573,84 @@ nsXULContentBuilder::GetInsertionLocatio
 
     return found;
 }
 
 nsresult
 nsXULContentBuilder::ReplaceMatch(nsIXULTemplateResult* aOldResult,
                                   nsTemplateMatch* aNewMatch,
                                   nsTemplateRule* aNewMatchRule,
-                                  Element* aContext)
+                                  void *aContext)
 
 {
     nsresult rv;
+    nsIContent* content = static_cast<nsIContent*>(aContext);
 
     // update the container attributes for the match
-    if (aContext) {
+    if (content) {
         nsAutoString ref;
         if (aNewMatch)
             rv = aNewMatch->mResult->GetBindingFor(mRefVariable, ref);
         else
             rv = aOldResult->GetBindingFor(mRefVariable, ref);
         if (NS_FAILED(rv))
             return rv;
 
         if (!ref.IsEmpty()) {
             nsCOMPtr<nsIXULTemplateResult> refResult;
             rv = GetResultForId(ref, getter_AddRefs(refResult));
             if (NS_FAILED(rv))
                 return rv;
 
             if (refResult)
-                SetContainerAttrs(aContext, refResult, false, true);
+                SetContainerAttrs(content, refResult, false, true);
         }
     }
 
     if (aOldResult) {
-        nsCOMArray<Element> elements;
+        nsCOMArray<nsIContent> elements;
         rv = GetElementsForResult(aOldResult, elements);
         if (NS_FAILED(rv))
             return rv;
 
         uint32_t count = elements.Count();
 
         for (int32_t e = int32_t(count) - 1; e >= 0; --e) {
             nsCOMPtr<nsIContent> child = elements.SafeObjectAt(e);
 
             nsTemplateMatch* match;
             if (mContentSupportMap.Get(child, &match)) {
-                if (aContext == match->GetContainer())
+                if (content == match->GetContainer())
                     RemoveMember(child);
             }
         }
     }
 
     if (aNewMatch) {
         nsCOMPtr<nsIContent> action = aNewMatchRule->GetAction();
-        return BuildContentFromTemplate(action, aContext, aContext, true,
+        return BuildContentFromTemplate(action, content, content, true,
                                         mRefVariable == aNewMatchRule->GetMemberVariable(),
                                         aNewMatch->mResult, true, aNewMatch,
                                         nullptr, nullptr);
     }
 
     return NS_OK;
 }
 
 
 nsresult
 nsXULContentBuilder::SynchronizeResult(nsIXULTemplateResult* aResult)
 {
-    nsCOMArray<Element> elements;
+    nsCOMArray<nsIContent> elements;
     GetElementsForResult(aResult, elements);
 
     uint32_t cnt = elements.Count();
 
     for (int32_t i = int32_t(cnt) - 1; i >= 0; --i) {
-        nsCOMPtr<Element> element = elements.SafeObjectAt(i);
+        nsCOMPtr<nsIContent> element = elements.SafeObjectAt(i);
 
         nsTemplateMatch* match;
         if (! mContentSupportMap.Get(element, &match))
             continue;
 
         nsCOMPtr<nsIContent> templateNode;
         mTemplateMap.GetTemplateFor(element, getter_AddRefs(templateNode));
 
@@ -1676,17 +1666,17 @@ nsXULContentBuilder::SynchronizeResult(n
 }
 
 //----------------------------------------------------------------------
 //
 // Implementation methods
 //
 
 nsresult
-nsXULContentBuilder::OpenContainer(Element* aElement)
+nsXULContentBuilder::OpenContainer(nsIContent* aElement)
 {
     if (aElement != mRoot) {
         if (mFlags & eDontRecurse)
             return NS_OK;
 
         bool rightBuilder = false;
 
         nsCOMPtr<nsIXULDocument> xuldoc = do_QueryInterface(aElement->GetComposedDoc());
@@ -1712,17 +1702,17 @@ nsXULContentBuilder::OpenContainer(Eleme
     }
 
     CreateTemplateAndContainerContents(aElement, false);
 
     return NS_OK;
 }
 
 nsresult
-nsXULContentBuilder::CloseContainer(Element* aElement)
+nsXULContentBuilder::CloseContainer(nsIContent* aElement)
 {
     return NS_OK;
 }
 
 nsresult
 nsXULContentBuilder::RebuildAll()
 {
     NS_ENSURE_TRUE(mRoot, NS_ERROR_NOT_INITIALIZED);
@@ -1798,17 +1788,17 @@ nsXULContentBuilder::CompareResultToNode
     // flip the sort order if performing a descending sorting
     if (mSortState.direction == nsSortState_descending)
         *aSortOrder = -*aSortOrder;
 
     return NS_OK;
 }
 
 nsresult
-nsXULContentBuilder::InsertSortedNode(Element* aContainer,
+nsXULContentBuilder::InsertSortedNode(nsIContent* aContainer,
                                       nsIContent* aNode,
                                       nsIXULTemplateResult* aResult,
                                       bool aNotify)
 {
     nsresult rv;
 
     if (!mSortState.initialized) {
         nsAutoString sort, sortDirection, sortHints;
--- a/dom/xul/templates/nsXULContentUtils.cpp
+++ b/dom/xul/templates/nsXULContentUtils.cpp
@@ -121,25 +121,25 @@ nsXULContentUtils::GetCollation()
 }
 
 //------------------------------------------------------------------------
 
 nsresult
 nsXULContentUtils::FindChildByTag(nsIContent* aElement,
                                   int32_t aNameSpaceID,
                                   nsAtom* aTag,
-                                  Element** aResult)
+                                  nsIContent** aResult)
 {
     for (nsIContent* child = aElement->GetFirstChild();
          child;
          child = child->GetNextSibling()) {
 
-        if (child->IsElement() &&
-            child->NodeInfo()->Equals(aTag, aNameSpaceID)) {
-            NS_ADDREF(*aResult = child->AsElement());
+        if (child->NodeInfo()->Equals(aTag, aNameSpaceID)) {
+            NS_ADDREF(*aResult = child);
+
             return NS_OK;
         }
     }
 
     *aResult = nullptr;
     return NS_RDF_NO_VALUE; // not found
 }
 
--- a/dom/xul/templates/nsXULContentUtils.h
+++ b/dom/xul/templates/nsXULContentUtils.h
@@ -18,22 +18,16 @@ class nsAtom;
 class nsIContent;
 class nsIDocument;
 class nsIRDFNode;
 class nsIRDFResource;
 class nsIRDFLiteral;
 class nsIRDFService;
 class nsICollation;
 
-namespace mozilla {
-namespace dom {
-class Element;
-}
-}
-
 // errors to pass to LogTemplateError
 #define ERROR_TEMPLATE_INVALID_QUERYPROCESSOR                           \
         "querytype attribute doesn't specify a valid query processor"
 #define ERROR_TEMPLATE_INVALID_QUERYSET                                 \
         "unexpected <queryset> element"
 #define ERROR_TEMPLATE_NO_MEMBERVAR                                     \
         "no member variable found. Action body should have an element with uri attribute"
 #define ERROR_TEMPLATE_WHERE_NO_SUBJECT                                 \
@@ -104,17 +98,17 @@ public:
 
     static nsresult
     Finish();
 
     static nsresult
     FindChildByTag(nsIContent *aElement,
                    int32_t aNameSpaceID,
                    nsAtom* aTag,
-                   mozilla::dom::Element** aResult);
+                   nsIContent **aResult);
 
     static nsresult
     FindChildByResource(nsIContent* aElement,
                         nsIRDFResource* aResource,
                         nsIContent** aResult);
 
     static nsresult
     GetTextForNode(nsIRDFNode* aNode, nsAString& aResult);
--- a/dom/xul/templates/nsXULSortService.cpp
+++ b/dom/xul/templates/nsXULSortService.cpp
@@ -23,36 +23,36 @@
 #include "nsIXULTemplateBuilder.h"
 #include "nsTemplateMatch.h"
 #include "nsICollation.h"
 #include "nsUnicharUtils.h"
 
 NS_IMPL_ISUPPORTS(XULSortServiceImpl, nsIXULSortService)
 
 void
-XULSortServiceImpl::SetSortHints(Element* aElement, nsSortState* aSortState)
+XULSortServiceImpl::SetSortHints(nsIContent *aNode, nsSortState* aSortState)
 {
   // set sort and sortDirection attributes when is sort is done
-  aElement->SetAttr(kNameSpaceID_None, nsGkAtoms::sort,
-                    aSortState->sort, true);
+  aNode->SetAttr(kNameSpaceID_None, nsGkAtoms::sort,
+                 aSortState->sort, true);
 
   nsAutoString direction;
   if (aSortState->direction == nsSortState_descending)
     direction.AssignLiteral("descending");
   else if (aSortState->direction == nsSortState_ascending)
     direction.AssignLiteral("ascending");
-  aElement->SetAttr(kNameSpaceID_None, nsGkAtoms::sortDirection,
-                    direction, true);
+  aNode->SetAttr(kNameSpaceID_None, nsGkAtoms::sortDirection,
+                 direction, true);
 
   // for trees, also set the sort info on the currently sorted column
-  if (aElement->NodeInfo()->Equals(nsGkAtoms::tree, kNameSpaceID_XUL)) {
+  if (aNode->NodeInfo()->Equals(nsGkAtoms::tree, kNameSpaceID_XUL)) {
     if (aSortState->sortKeys.Length() >= 1) {
       nsAutoString sortkey;
       aSortState->sortKeys[0]->ToString(sortkey);
-      SetSortColumnHints(aElement, sortkey, direction);
+      SetSortColumnHints(aNode, sortkey, direction);
     }
   }
 }
 
 void
 XULSortServiceImpl::SetSortColumnHints(nsIContent *content,
                                        const nsAString &sortResource,
                                        const nsAString &sortDirection)
@@ -66,28 +66,27 @@ XULSortServiceImpl::SetSortColumnHints(n
       SetSortColumnHints(child, sortResource, sortDirection);
     } else if (child->IsXULElement(nsGkAtoms::treecol)) {
       nsAutoString value;
       child->GetAttr(kNameSpaceID_None, nsGkAtoms::sort, value);
       // also check the resource attribute for older code
       if (value.IsEmpty())
         child->GetAttr(kNameSpaceID_None, nsGkAtoms::resource, value);
       if (value == sortResource) {
-        child->AsElement()->SetAttr(kNameSpaceID_None, nsGkAtoms::sortActive,
-                                    NS_LITERAL_STRING("true"), true);
-
-        child->AsElement()->SetAttr(kNameSpaceID_None, nsGkAtoms::sortDirection,
-                                    sortDirection, true);
+        child->SetAttr(kNameSpaceID_None, nsGkAtoms::sortActive,
+                       NS_LITERAL_STRING("true"), true);
+        child->SetAttr(kNameSpaceID_None, nsGkAtoms::sortDirection,
+                       sortDirection, true);
         // Note: don't break out of loop; want to set/unset
         // attribs on ALL sort columns
       } else if (!value.IsEmpty()) {
-        child->AsElement()->UnsetAttr(kNameSpaceID_None, nsGkAtoms::sortActive,
-                                      true);
-        child->AsElement()->UnsetAttr(kNameSpaceID_None,
-                                      nsGkAtoms::sortDirection, true);
+        child->UnsetAttr(kNameSpaceID_None, nsGkAtoms::sortActive,
+                         true);
+        child->UnsetAttr(kNameSpaceID_None, nsGkAtoms::sortDirection,
+                         true);
       }
     }
   }
 }
 
 nsresult
 XULSortServiceImpl::GetItemsToSort(nsIContent *aContainer,
                                    nsSortState* aSortState,
@@ -105,17 +104,17 @@ XULSortServiceImpl::GetItemsToSort(nsICo
         return rv;
 
       return GetTemplateItemsToSort(aContainer, builder, aSortState, aSortItems);
     }
   }
 
   // if there is no template builder, just get the children. For trees,
   // get the treechildren element as use that as the parent
-  RefPtr<Element> treechildren;
+  nsCOMPtr<nsIContent> treechildren;
   if (aContainer->NodeInfo()->Equals(nsGkAtoms::tree, kNameSpaceID_XUL)) {
     nsXULContentUtils::FindChildByTag(aContainer,
                                       kNameSpaceID_XUL,
                                       nsGkAtoms::treechildren,
                                       getter_AddRefs(treechildren));
     if (!treechildren)
       return NS_OK;
 
@@ -319,18 +318,18 @@ XULSortServiceImpl::InvertSortInfo(nsTAr
     while (half-- > 0) {
       aData[downPoint--].swap(aData[upPoint++]);
     }
   }
   return NS_OK;
 }
 
 nsresult
-XULSortServiceImpl::InitializeSortState(Element* aRootElement,
-                                        Element* aContainer,
+XULSortServiceImpl::InitializeSortState(nsIContent* aRootElement,
+                                        nsIContent* aContainer,
                                         const nsAString& aSortKey,
                                         const nsAString& aSortHints,
                                         nsSortState* aSortState)
 {
   // used as an optimization for the content builder
   if (aContainer != aSortState->lastContainer.get()) {
     aSortState->lastContainer = aContainer;
     aSortState->lastWasFirst = false;
@@ -463,17 +462,17 @@ XULSortServiceImpl::CompareValues(const 
 }
 
 NS_IMETHODIMP
 XULSortServiceImpl::Sort(nsIDOMNode* aNode,
                          const nsAString& aSortKey,
                          const nsAString& aSortHints)
 {
   // get root content node
-  nsCOMPtr<Element> sortNode = do_QueryInterface(aNode);
+  nsCOMPtr<nsIContent> sortNode = do_QueryInterface(aNode);
   if (!sortNode)
     return NS_ERROR_FAILURE;
 
   nsSortState sortState;
   nsresult rv = InitializeSortState(sortNode, sortNode,
                                     aSortKey, aSortHints, &sortState);
   NS_ENSURE_SUCCESS(rv, rv);
 
--- a/dom/xul/templates/nsXULSortService.h
+++ b/dom/xul/templates/nsXULSortService.h
@@ -91,17 +91,17 @@ public:
 
   // nsISortService
   NS_DECL_NSIXULSORTSERVICE
 
   /**
    * Set sort and sortDirection attributes when a sort is done.
    */
   void
-  SetSortHints(mozilla::dom::Element* aElement, nsSortState* aSortState);
+  SetSortHints(nsIContent *aNode, nsSortState* aSortState);
 
   /**
    * Set sortActive and sortDirection attributes on a tree column when a sort
    * is done. The column to change is the one with a sort attribute that
    * matches the sort key. The sort attributes are removed from the other
    * columns.
    */
   void
@@ -151,18 +151,18 @@ public:
    *
    * @param aRootElement the element that contains sort attributes
    * @param aContainer the container to sort, usually equal to aRootElement
    * @param aSortKey space separated list of sort keys
    * @param aSortDirection direction to sort in
    * @param aSortState structure filled in with sort data
    */
   static nsresult
-  InitializeSortState(mozilla::dom::Element* aRootElement,
-                      mozilla::dom::Element* aContainer,
+  InitializeSortState(nsIContent* aRootElement,
+                      nsIContent* aContainer,
                       const nsAString& aSortKey,
                       const nsAString& aSortDirection,
                       nsSortState* aSortState);
 
   /**
    * Compares aLeft and aRight and returns < 0, 0, or > 0. The sort
    * hints are checked for case matching and integer sorting.
    */
--- a/dom/xul/templates/nsXULTemplateBuilder.cpp
+++ b/dom/xul/templates/nsXULTemplateBuilder.cpp
@@ -471,17 +471,17 @@ nsXULTemplateBuilder::Init()
     if (NS_SUCCEEDED(rv)) {
         StartObserving(doc);
     }
 
     return rv;
 }
 
 NS_IMETHODIMP
-nsXULTemplateBuilder::CreateContents(Element* aElement, bool aForceCreation)
+nsXULTemplateBuilder::CreateContents(nsIContent* aElement, bool aForceCreation)
 {
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULTemplateBuilder::HasGeneratedContent(nsIRDFResource* aResource,
                                           nsAtom* aTag,
                                           bool* aGenerated)
@@ -570,17 +570,17 @@ nsXULTemplateBuilder::UpdateResult(nsIXU
       return NS_OK;
 
     // get the containers where content may be inserted. If
     // GetInsertionLocations returns false, no container has generated
     // any content yet so new content should not be generated either. This
     // will be false if the result applies to content that is in a closed menu
     // or treeitem for example.
 
-    nsAutoPtr<nsCOMArray<Element> > insertionPoints;
+    nsAutoPtr<nsCOMArray<nsIContent> > insertionPoints;
     bool mayReplace = GetInsertionLocations(aOldResult ? aOldResult : aNewResult,
                                               getter_Transfers(insertionPoints));
     if (! mayReplace)
         return NS_OK;
 
     nsresult rv = NS_OK;
 
     nsCOMPtr<nsIRDFResource> oldId, newId;
@@ -627,17 +627,17 @@ nsXULTemplateBuilder::UpdateResult(nsIXU
             return NS_OK;
     }
 
     if (insertionPoints) {
         // iterate over each insertion point and add or remove the result from
         // that container
         uint32_t count = insertionPoints->Count();
         for (uint32_t t = 0; t < count; t++) {
-            nsCOMPtr<Element> insertionPoint = insertionPoints->SafeObjectAt(t);
+            nsCOMPtr<nsIContent> insertionPoint = insertionPoints->SafeObjectAt(t);
             if (insertionPoint) {
                 rv = UpdateResultInContainer(aOldResult, aNewResult, queryset,
                                              oldId, newId, insertionPoint);
                 if (NS_FAILED(rv))
                     return rv;
             }
         }
     }
@@ -652,17 +652,17 @@ nsXULTemplateBuilder::UpdateResult(nsIXU
 }
 
 nsresult
 nsXULTemplateBuilder::UpdateResultInContainer(nsIXULTemplateResult* aOldResult,
                                               nsIXULTemplateResult* aNewResult,
                                               nsTemplateQuerySet* aQuerySet,
                                               nsIRDFResource* aOldId,
                                               nsIRDFResource* aNewId,
-                                              Element* aInsertionPoint)
+                                              nsIContent* aInsertionPoint)
 {
     // This method takes a result that no longer applies (aOldResult) and
     // replaces it with a new result (aNewResult). Either may be null
     // indicating to just remove a result or add a new one without replacing.
     //
     // Matches are stored in the hashtable mMatchMap, keyed by result id. If
     // there is more than one query, or the same id is found in different
     // containers, the values in the hashtable will be a linked list of all
@@ -1699,21 +1699,22 @@ nsXULTemplateBuilder::SubstituteTextRepl
     }
 
     c->str += replacementText;
 }
 
 bool
 nsXULTemplateBuilder::IsTemplateElement(nsIContent* aContent)
 {
-    return aContent->NodeInfo()->Equals(nsGkAtoms::_template, kNameSpaceID_XUL);
+    return aContent->NodeInfo()->Equals(nsGkAtoms::_template,
+                                        kNameSpaceID_XUL);
 }
 
 nsresult
-nsXULTemplateBuilder::GetTemplateRoot(Element** aResult)
+nsXULTemplateBuilder::GetTemplateRoot(nsIContent** aResult)
 {
     NS_PRECONDITION(mRoot != nullptr, "not initialized");
     if (! mRoot)
         return NS_ERROR_NOT_INITIALIZED;
 
     // First, check and see if the root has a template attribute. This
     // allows a template to be specified "out of line"; e.g.,
     //
@@ -1729,58 +1730,58 @@ nsXULTemplateBuilder::GetTemplateRoot(El
         nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(mRoot->GetComposedDoc());
         if (! domDoc)
             return NS_OK;
 
         nsCOMPtr<nsIDOMElement> domElement;
         domDoc->GetElementById(templateID, getter_AddRefs(domElement));
 
         if (domElement) {
-            nsCOMPtr<Element> content = do_QueryInterface(domElement);
+            nsCOMPtr<nsIContent> content = do_QueryInterface(domElement);
             NS_ENSURE_STATE(content &&
                             !nsContentUtils::ContentIsDescendantOf(mRoot,
                                                                    content));
             content.forget(aResult);
             return NS_OK;
         }
     }
 
     // If root node has no template attribute, then look for a child
     // node which is a template tag.
     for (nsIContent* child = mRoot->GetFirstChild();
          child;
          child = child->GetNextSibling()) {
 
         if (IsTemplateElement(child)) {
-            NS_ADDREF(*aResult = child->AsElement());
+            NS_ADDREF(*aResult = child);
             return NS_OK;
         }
     }
 
     // Look through the anonymous children as well. Although FlattenedChildIterator
     // will find a template element that has been placed in an insertion point, many
     // bindings do not have a specific insertion point for the template element, which
     // would cause it to not be part of the flattened content tree. The check above to
     // check the explicit children as well handles this case.
     FlattenedChildIterator iter(mRoot);
     for (nsIContent* child = iter.GetNextChild(); child; child = iter.GetNextChild()) {
         if (IsTemplateElement(child)) {
-            NS_ADDREF(*aResult = child->AsElement());
+            NS_ADDREF(*aResult = child);
             return NS_OK;
         }
     }
 
     *aResult = nullptr;
     return NS_OK;
 }
 
 nsresult
 nsXULTemplateBuilder::CompileQueries()
 {
-    nsCOMPtr<Element> tmpl;
+    nsCOMPtr<nsIContent> tmpl;
     GetTemplateRoot(getter_AddRefs(tmpl));
     if (! tmpl)
         return NS_OK;
 
     if (! mRoot)
         return NS_ERROR_NOT_INITIALIZED;
 
     // Determine if there are any special settings we need to observe
@@ -1861,17 +1862,17 @@ nsXULTemplateBuilder::CompileQueries()
     }
 
     mQueriesCompiled = true;
 
     return NS_OK;
 }
 
 nsresult
-nsXULTemplateBuilder::CompileTemplate(Element* aTemplate,
+nsXULTemplateBuilder::CompileTemplate(nsIContent* aTemplate,
                                       nsTemplateQuerySet* aQuerySet,
                                       bool aIsQuerySet,
                                       int32_t* aPriority,
                                       bool* aCanUseTemplate)
 {
     NS_ASSERTION(aQuerySet, "No queryset supplied");
 
     nsresult rv = NS_OK;
@@ -1909,29 +1910,27 @@ nsXULTemplateBuilder::CompileTemplate(El
                 if (!mQuerySets.AppendElement(aQuerySet)) {
                     delete aQuerySet;
                     return NS_ERROR_OUT_OF_MEMORY;
                 }
             }
 
             hasQuerySet = true;
 
-            // Known to be a <xul:queryset>.
-            rv = CompileTemplate(rulenode->AsElement(), aQuerySet, true,
-                                 aPriority, aCanUseTemplate);
+            rv = CompileTemplate(rulenode, aQuerySet, true, aPriority, aCanUseTemplate);
             if (NS_FAILED(rv))
                 return rv;
         }
 
         // once a queryset is used, everything must be a queryset
         if (isQuerySetMode)
             continue;
 
         if (ni->Equals(nsGkAtoms::rule, kNameSpaceID_XUL)) {
-            RefPtr<Element> action;
+            nsCOMPtr<nsIContent> action;
             nsXULContentUtils::FindChildByTag(rulenode,
                                               kNameSpaceID_XUL,
                                               nsGkAtoms::action,
                                               getter_AddRefs(action));
 
             if (action){
                 RefPtr<nsAtom> memberVariable = mMemberVariable;
                 if (!memberVariable) {
@@ -1955,32 +1954,30 @@ nsXULTemplateBuilder::CompileTemplate(El
                         rv = mQueryProcessor->CompileQuery(this, query,
                                                            mRefVariable, memberVariable,
                                                            getter_AddRefs(aQuerySet->mCompiledQuery));
                         if (NS_FAILED(rv))
                             return rv;
                     }
 
                     if (aQuerySet->mCompiledQuery) {
-                        // It's an element (we test it for <xul:rule>, plus it
-                        // has `action` as a kid).
-                        rv = CompileExtendedQuery(rulenode->AsElement(),
-                                                  action, memberVariable,
+                        rv = CompileExtendedQuery(rulenode, action, memberVariable,
                                                   aQuerySet);
                         if (NS_FAILED(rv))
                             return rv;
 
                         *aCanUseTemplate = true;
                     }
-                } else {
+                }
+                else {
                     // backwards-compatible RDF template syntax where there is
                     // an <action> node but no <query> node. In this case,
                     // use the conditions as if it was the query.
 
-                    RefPtr<Element> conditions;
+                    nsCOMPtr<nsIContent> conditions;
                     nsXULContentUtils::FindChildByTag(rulenode,
                                                       kNameSpaceID_XUL,
                                                       nsGkAtoms::conditions,
                                                       getter_AddRefs(conditions));
 
                     if (conditions) {
                         // create a new queryset if one hasn't been created already
                         if (hasQuerySet) {
@@ -2004,58 +2001,56 @@ nsXULTemplateBuilder::CompileTemplate(El
                         rv = mQueryProcessor->CompileQuery(this, conditionsnode,
                                                            mRefVariable,
                                                            memberVariable,
                                                            getter_AddRefs(aQuerySet->mCompiledQuery));
                         if (NS_FAILED(rv))
                             return rv;
 
                         if (aQuerySet->mCompiledQuery) {
-                            // Known to be a <xul:rule>, plus known to have
-                            // kids.
-                            rv = CompileExtendedQuery(rulenode->AsElement(),
-                                                      action, memberVariable,
+                            rv = CompileExtendedQuery(rulenode, action, memberVariable,
                                                       aQuerySet);
                             if (NS_FAILED(rv))
                                 return rv;
 
                             *aCanUseTemplate = true;
                         }
                     }
                 }
-            } else {
+            }
+            else {
                 if (hasQuery)
                     continue;
 
                 // a new queryset must always be created in this case
                 if (hasQuerySet) {
                     aQuerySet = new nsTemplateQuerySet(++*aPriority);
                     if (!mQuerySets.AppendElement(aQuerySet)) {
                         delete aQuerySet;
                         return NS_ERROR_OUT_OF_MEMORY;
                     }
                 }
 
                 hasQuerySet = true;
 
-                // Known to be a <xul:rule>.
-                rv = CompileSimpleQuery(rulenode->AsElement(), aQuerySet,
-                                        aCanUseTemplate);
+                rv = CompileSimpleQuery(rulenode, aQuerySet, aCanUseTemplate);
                 if (NS_FAILED(rv))
                     return rv;
             }
 
             hasRule = true;
-        } else if (ni->Equals(nsGkAtoms::query, kNameSpaceID_XUL)) {
+        }
+        else if (ni->Equals(nsGkAtoms::query, kNameSpaceID_XUL)) {
             if (hasQuery)
               continue;
 
             aQuerySet->mQueryNode = rulenode;
             hasQuery = true;
-        } else if (ni->Equals(nsGkAtoms::action, kNameSpaceID_XUL)) {
+        }
+        else if (ni->Equals(nsGkAtoms::action, kNameSpaceID_XUL)) {
             // the query must appear before the action
             if (! hasQuery)
                 continue;
 
             RefPtr<nsAtom> tag;
             DetermineRDFQueryRef(aQuerySet->mQueryNode, getter_AddRefs(tag));
             if (tag)
                 aQuerySet->SetTag(tag);
@@ -2094,30 +2089,30 @@ nsXULTemplateBuilder::CompileTemplate(El
         // <template> tag are the one-and-only template.
         rv = CompileSimpleQuery(aTemplate, aQuerySet, aCanUseTemplate);
      }
 
     return rv;
 }
 
 nsresult
-nsXULTemplateBuilder::CompileExtendedQuery(Element* aRuleElement,
+nsXULTemplateBuilder::CompileExtendedQuery(nsIContent* aRuleElement,
                                            nsIContent* aActionElement,
                                            nsAtom* aMemberVariable,
                                            nsTemplateQuerySet* aQuerySet)
 {
     // Compile an "extended" <template> rule. An extended rule may have
     // a <conditions> child, an <action> child, and a <bindings> child.
     nsresult rv;
 
     nsTemplateRule* rule = aQuerySet->NewRule(aRuleElement, aActionElement, aQuerySet);
     if (! rule)
          return NS_ERROR_OUT_OF_MEMORY;
 
-    RefPtr<Element> conditions;
+    nsCOMPtr<nsIContent> conditions;
     nsXULContentUtils::FindChildByTag(aRuleElement,
                                       kNameSpaceID_XUL,
                                       nsGkAtoms::conditions,
                                       getter_AddRefs(conditions));
 
     // allow the conditions to be placed directly inside the rule
     if (!conditions)
         conditions = aRuleElement;
@@ -2127,17 +2122,17 @@ nsXULTemplateBuilder::CompileExtendedQue
     if (NS_FAILED(rv)) {
         aQuerySet->RemoveRule(rule);
         return rv;
     }
 
     rule->SetVars(mRefVariable, aMemberVariable);
 
     // If we've got bindings, add 'em.
-    RefPtr<Element> bindings;
+    nsCOMPtr<nsIContent> bindings;
     nsXULContentUtils::FindChildByTag(aRuleElement,
                                       kNameSpaceID_XUL,
                                       nsGkAtoms::bindings,
                                       getter_AddRefs(bindings));
 
     // allow bindings to be placed directly inside rule
     if (!bindings)
         bindings = aRuleElement;
@@ -2170,17 +2165,17 @@ nsXULTemplateBuilder::DetermineMemberVar
 
     return nullptr;
 }
 
 void
 nsXULTemplateBuilder::DetermineRDFQueryRef(nsIContent* aQueryElement, nsAtom** aTag)
 {
     // check for a tag
-    RefPtr<Element> content;
+    nsCOMPtr<nsIContent> content;
     nsXULContentUtils::FindChildByTag(aQueryElement,
                                       kNameSpaceID_XUL,
                                       nsGkAtoms::content,
                                       getter_AddRefs(content));
 
     if (! content) {
         // look for older treeitem syntax as well
         nsXULContentUtils::FindChildByTag(aQueryElement,
@@ -2200,17 +2195,17 @@ nsXULTemplateBuilder::DetermineRDFQueryR
         content->GetAttr(kNameSpaceID_None, nsGkAtoms::tag, tag);
 
         if (!tag.IsEmpty())
             *aTag = NS_Atomize(tag).take();
     }
 }
 
 nsresult
-nsXULTemplateBuilder::CompileSimpleQuery(Element* aRuleElement,
+nsXULTemplateBuilder::CompileSimpleQuery(nsIContent* aRuleElement,
                                          nsTemplateQuerySet* aQuerySet,
                                          bool* aCanUseTemplate)
 {
     // compile a simple query, which is a query with no <query> or
     // <conditions>. This means that a default query is used.
     nsCOMPtr<nsIDOMNode> query(do_QueryInterface(aRuleElement));
 
     RefPtr<nsAtom> memberVariable;
@@ -2457,30 +2452,30 @@ nsXULTemplateBuilder::CompileBinding(nsT
         return NS_OK;
     }
 
     return aRule->AddBinding(svar, predicate, ovar);
 }
 
 nsresult
 nsXULTemplateBuilder::AddSimpleRuleBindings(nsTemplateRule* aRule,
-                                            Element* aElement)
+                                            nsIContent* aElement)
 {
     // Crawl the content tree of a "simple" rule, adding a variable
     // assignment for any attribute whose value is "rdf:".
 
-    AutoTArray<Element*, 8> elements;
+    AutoTArray<nsIContent*, 8> elements;
 
     if (elements.AppendElement(aElement) == nullptr)
         return NS_ERROR_OUT_OF_MEMORY;
 
     while (elements.Length()) {
         // Pop the next element off the stack
         uint32_t i = elements.Length() - 1;
-        Element* element = elements[i];
+        nsIContent* element = elements[i];
         elements.RemoveElementAt(i);
 
         // Iterate through its attributes, looking for substitutions
         // that we need to add as bindings.
         uint32_t count = element->GetAttrCount();
 
         for (i = 0; i < count; ++i) {
             const nsAttrName* name = element->GetAttrNameAt(i);
@@ -2495,20 +2490,18 @@ nsXULTemplateBuilder::AddSimpleRuleBindi
                 ParseAttribute(value, AddBindingsFor, nullptr, aRule);
             }
         }
 
         // Push kids onto the stack, and search them next.
         for (nsIContent* child = element->GetLastChild();
              child;
              child = child->GetPreviousSibling()) {
-            if (!child->IsElement())
-                continue;
-
-            if (!elements.AppendElement(child->AsElement()))
+
+            if (!elements.AppendElement(child))
                 return NS_ERROR_OUT_OF_MEMORY;
         }
     }
 
     aRule->AddBindingsToQueryProcessor(mQueryProcessor);
 
     return NS_OK;
 }
--- a/dom/xul/templates/nsXULTemplateBuilder.h
+++ b/dom/xul/templates/nsXULTemplateBuilder.h
@@ -154,17 +154,17 @@ public:
      * @param aInsertionPoint container to remove or add result inside
      */
     nsresult
     UpdateResultInContainer(nsIXULTemplateResult* aOldResult,
                             nsIXULTemplateResult* aNewResult,
                             nsTemplateQuerySet* aQuerySet,
                             nsIRDFResource* aOldId,
                             nsIRDFResource* aNewId,
-                            Element* aInsertionPoint);
+                            nsIContent* aInsertionPoint);
 
     nsresult
     ComputeContainmentProperties();
 
     static bool
     IsTemplateElement(nsIContent* aContent);
 
     virtual nsresult
@@ -188,17 +188,17 @@ public:
     // generated content can be removed during uninitialization.
     void UninitFalse() { Uninit(false); mRoot = nullptr; }
     void UninitTrue() { Uninit(true); mRoot = nullptr; }
 
     /**
      * Find the <template> tag that applies for this builder
      */
     nsresult
-    GetTemplateRoot(Element** aResult);
+    GetTemplateRoot(nsIContent** aResult);
 
     /**
      * Compile the template's queries
      */
     nsresult
     CompileQueries();
 
     /**
@@ -213,33 +213,33 @@ public:
      *
      * @param aTemplate <template> to compile
      * @param aQuerySet first queryset
      * @param aIsQuerySet true if
      * @param aPriority the queryset index, incremented when a new one is added
      * @param aCanUseTemplate true if template is valid
      */
     nsresult
-    CompileTemplate(Element* aTemplate,
+    CompileTemplate(nsIContent* aTemplate,
                     nsTemplateQuerySet* aQuerySet,
                     bool aIsQuerySet,
                     int32_t* aPriority,
                     bool* aCanUseTemplate);
 
     /**
      * Compile a query using the extended syntax. For backwards compatible RDF
      * syntax where there is no <query>, the <conditions> becomes the query.
      *
      * @param aRuleElement <rule> element
      * @param aActionElement <action> element
      * @param aMemberVariable member variable for the query
      * @param aQuerySet the queryset
      */
     nsresult
-    CompileExtendedQuery(Element* aRuleElement,
+    CompileExtendedQuery(nsIContent* aRuleElement,
                          nsIContent* aActionElement,
                          nsAtom* aMemberVariable,
                          nsTemplateQuerySet* aQuerySet);
 
     /**
      * Determine the ref variable and tag from inside a RDF query.
      */
     void DetermineRDFQueryRef(nsIContent* aQueryElement, nsAtom** tag);
@@ -255,17 +255,17 @@ public:
      * <query> and should use a default query which would normally just return
      * a list of children of the reference point.
      *
      * @param aRuleElement the <rule>
      * @param aQuerySet the query set
      * @param aCanUseTemplate true if the query is valid
      */
     nsresult
-    CompileSimpleQuery(Element* aRuleElement,
+    CompileSimpleQuery(nsIContent* aRuleElement,
                        nsTemplateQuerySet* aQuerySet,
                        bool* aCanUseTemplate);
 
     /**
      * Compile the <conditions> tag in a rule
      *
      * @param aRule template rule
      * @param aConditions <conditions> element
@@ -299,17 +299,17 @@ public:
      */
     nsresult
     CompileBinding(nsTemplateRule* aRule, nsIContent* aBinding);
 
     /**
      * Add automatic bindings for simple rules
      */
     nsresult
-    AddSimpleRuleBindings(nsTemplateRule* aRule, Element* aElement);
+    AddSimpleRuleBindings(nsTemplateRule* aRule, nsIContent* aElement);
 
     static void
     AddBindingsFor(nsXULTemplateBuilder* aSelf,
                    const nsAString& aVariable,
                    void* aClosure);
 
     /**
      * Load the datasources for the template. shouldDelayBuilding is an out
@@ -489,29 +489,29 @@ protected:
      * Those results will be generated when the container is opened.
      * If false is returned, no content should be generated. Possible
      * insertion locations may optionally be set for new content, depending on
      * the builder being used. Note that *aLocations or some items within
      * aLocations may be null.
      */
     virtual bool
     GetInsertionLocations(nsIXULTemplateResult* aResult,
-                          nsCOMArray<Element>** aLocations) = 0;
+                          nsCOMArray<nsIContent>** aLocations) = 0;
 
     /**
      * Must be implemented by subclasses. Handle removing the generated
      * output for aOldMatch and adding new output for aNewMatch. Either
      * aOldMatch or aNewMatch may be null. aContext is the location returned
      * from the call to MayGenerateResult.
      */
     virtual nsresult
     ReplaceMatch(nsIXULTemplateResult* aOldResult,
                  nsTemplateMatch* aNewMatch,
                  nsTemplateRule* aNewMatchRule,
-                 Element* aContext) = 0;
+                 void *aContext) = 0;
 
     /**
      * Must be implemented by subclasses. Handle change in bound
      * variable values for aResult. aModifiedVars contains the set
      * of variables that have changed.
      * @param aResult the ersult for which variable bindings has changed.
      * @param aModifiedVars the set of variables for which the bindings
      * have changed.
--- a/dom/xul/templates/nsXULTemplateQueryProcessorRDF.cpp
+++ b/dom/xul/templates/nsXULTemplateQueryProcessorRDF.cpp
@@ -359,24 +359,24 @@ nsXULTemplateQueryProcessorRDF::CompileQ
 
     if (content->NodeInfo()->Equals(nsGkAtoms::_template, kNameSpaceID_XUL)) {
         // simplified syntax with no rules
 
         query->SetSimple();
         NS_ASSERTION(!mSimpleRuleMemberTest,
                      "CompileQuery called twice with the same template");
         if (!mSimpleRuleMemberTest)
-            rv = CompileSimpleQuery(query, content->AsElement(), &lastnode);
+            rv = CompileSimpleQuery(query, content, &lastnode);
         else
             rv = NS_ERROR_FAILURE;
     }
     else if (content->NodeInfo()->Equals(nsGkAtoms::rule, kNameSpaceID_XUL)) {
         // simplified syntax with at least one rule
         query->SetSimple();
-        rv = CompileSimpleQuery(query, content->AsElement(), &lastnode);
+        rv = CompileSimpleQuery(query, content, &lastnode);
     }
     else {
         rv = CompileExtendedQuery(query, content, &lastnode);
     }
 
     if (NS_FAILED(rv))
         return rv;
 
@@ -1476,17 +1476,17 @@ nsXULTemplateQueryProcessorRDF::AddDefau
     mSimpleRuleMemberTest = membernode;
     *aChildNode = membernode;
 
     return NS_OK;
 }
 
 nsresult
 nsXULTemplateQueryProcessorRDF::CompileSimpleQuery(nsRDFQuery* aQuery,
-                                                   Element* aQueryElement,
+                                                   nsIContent* aQueryElement,
                                                    TestNode** aLastNode)
 {
     // Compile a "simple" (or old-school style) <template> query.
     nsresult rv;
 
     TestNode* parentNode;
 
     if (! mSimpleRuleMemberTest) {
--- a/dom/xul/templates/nsXULTemplateQueryProcessorRDF.h
+++ b/dom/xul/templates/nsXULTemplateQueryProcessorRDF.h
@@ -29,22 +29,16 @@
 #include "mozilla/Attributes.h"
 
 #include "mozilla/Logging.h"
 extern mozilla::LazyLogModule gXULTemplateLog;
 
 class nsIContent;
 class nsXULTemplateResultRDF;
 
-namespace mozilla {
-namespace dom {
-class Element;
-}
-}
-
 /**
  * An object that generates results from a query on an RDF graph
  */
 class nsXULTemplateQueryProcessorRDF final : public nsIXULTemplateQueryProcessor,
                                              public nsIRDFObserver
 {
 public:
     typedef nsTArray<RefPtr<nsXULTemplateResultRDF> > ResultArray;
@@ -184,18 +178,18 @@ public:
     /**
      * Compile a query that's specified using the simple template
      * syntax. Each  TestNode is created in a chain, the last compiled node
      * is returned as aLastNode. All nodes will have been added to mAllTests
      * which owns the nodes.
      */
     nsresult
     CompileSimpleQuery(nsRDFQuery* aQuery,
-                       mozilla::dom::Element* aQueryElement,
-                       TestNode** aLastNode);
+                      nsIContent* aQueryElement,
+                      TestNode** aLastNode);
 
     RDFBindingSet*
     GetBindingsForRule(nsIDOMNode* aRule);
 
     /*
      * Indicate that a result is dependant on a particular resource. When an
      * assertion is added to or removed from the graph involving that
      * resource, that result must be recalculated.
--- a/dom/xul/templates/nsXULTreeBuilder.cpp
+++ b/dom/xul/templates/nsXULTreeBuilder.cpp
@@ -275,17 +275,17 @@ void
 nsXULTreeBuilder::GetRowProperties(int32_t aRow, nsAString& aProperties,
                                    ErrorResult& aError)
 {
     if (!IsValidRowIndex(aRow)) {
         aError.Throw(NS_ERROR_INVALID_ARG);
         return;
     }
 
-    nsCOMPtr<Element> row;
+    nsCOMPtr<nsIContent> row;
     GetTemplateActionRowFor(aRow, getter_AddRefs(row));
     if (row) {
         nsAutoString raw;
         row->GetAttr(kNameSpaceID_None, nsGkAtoms::properties, raw);
 
         if (!raw.IsEmpty()) {
             SubstituteText(mRows[aRow]->mMatch->mResult, raw, aProperties);
         }
@@ -1041,17 +1041,17 @@ nsXULTreeBuilder::HasGeneratedContent(ns
     }
 
     return aResource == rootresource ||
            mRows.FindByResource(aResource) != mRows.Last();
 }
 
 bool
 nsXULTreeBuilder::GetInsertionLocations(nsIXULTemplateResult* aResult,
-                                        nsCOMArray<Element>** aLocations)
+                                        nsCOMArray<nsIContent>** aLocations)
 {
     *aLocations = nullptr;
 
     // Get the reference point and check if it is an open container. Rows
     // should not be generated otherwise.
 
     nsAutoString ref;
     nsresult rv = aResult->GetBindingFor(mRefVariable, ref);
@@ -1084,17 +1084,17 @@ struct ResultComparator
         return mTreebuilder->CompareResults(mResult, aSubtree.mMatch->mResult);
     }
 };
 
 nsresult
 nsXULTreeBuilder::ReplaceMatch(nsIXULTemplateResult* aOldResult,
                                nsTemplateMatch* aNewMatch,
                                nsTemplateRule* aNewMatchRule,
-                               Element*)
+                               void *aLocation)
 {
     if (! mBoxObject)
         return NS_OK;
 
     if (aOldResult) {
         // Grovel through the rows looking for oldresult.
         nsTreeRows::iterator iter = mRows.Find(aOldResult);
 
@@ -1245,17 +1245,17 @@ nsXULTreeBuilder::SynchronizeResult(nsIX
 
 //----------------------------------------------------------------------
 
 nsresult
 nsXULTreeBuilder::EnsureSortVariables()
 {
     // Grovel through <treecols> kids to find the <treecol>
     // with the sort attributes.
-    nsCOMPtr<Element> treecols;
+    nsCOMPtr<nsIContent> treecols;
 
     nsXULContentUtils::FindChildByTag(mRoot, kNameSpaceID_XUL,
                                       nsGkAtoms::treecols,
                                       getter_AddRefs(treecols));
 
     if (!treecols)
         return NS_OK;
 
@@ -1339,36 +1339,36 @@ nsXULTreeBuilder::RebuildAll()
     if (mBoxObject) {
         mBoxObject->EndUpdateBatch();
     }
 
     return rv;
 }
 
 nsresult
-nsXULTreeBuilder::GetTemplateActionRowFor(int32_t aRow, Element** aResult)
+nsXULTreeBuilder::GetTemplateActionRowFor(int32_t aRow, nsIContent** aResult)
 {
     // Get the template in the DOM from which we're supposed to
     // generate text
     nsTreeRows::Row& row = *(mRows[aRow]);
 
     // The match stores the indices of the rule and query to use. Use these
     // to look up the right nsTemplateRule and use that rule's action to get
     // the treerow in the template.
     int16_t ruleindex = row.mMatch->RuleIndex();
     if (ruleindex >= 0) {
         nsTemplateQuerySet* qs = mQuerySets[row.mMatch->QuerySetPriority()];
         nsTemplateRule* rule = qs->GetRuleAt(ruleindex);
         if (rule) {
-            nsCOMPtr<Element> children;
+            nsCOMPtr<nsIContent> children;
             nsXULContentUtils::FindChildByTag(rule->GetAction(), kNameSpaceID_XUL,
                                               nsGkAtoms::treechildren,
                                               getter_AddRefs(children));
             if (children) {
-                nsCOMPtr<Element> item;
+                nsCOMPtr<nsIContent> item;
                 nsXULContentUtils::FindChildByTag(children, kNameSpaceID_XUL,
                                                   nsGkAtoms::treeitem,
                                                   getter_AddRefs(item));
                 if (item)
                     return nsXULContentUtils::FindChildByTag(item,
                                                              kNameSpaceID_XUL,
                                                              nsGkAtoms::treerow,
                                                              aResult);
@@ -1378,17 +1378,17 @@ nsXULTreeBuilder::GetTemplateActionRowFo
 
     *aResult = nullptr;
     return NS_OK;
 }
 
 nsIContent*
 nsXULTreeBuilder::GetTemplateActionCellFor(int32_t aRow, nsTreeColumn& aCol)
 {
-    RefPtr<Element> row;
+    nsCOMPtr<nsIContent> row;
     GetTemplateActionRowFor(aRow, getter_AddRefs(row));
     if (!row) {
         return nullptr;
     }
 
     RefPtr<nsAtom> colAtom(aCol.GetAtom());
     int32_t colIndex(aCol.GetIndex());
 
--- a/dom/xul/templates/nsXULTreeBuilder.h
+++ b/dom/xul/templates/nsXULTreeBuilder.h
@@ -156,17 +156,17 @@ protected:
     virtual nsresult
     RebuildAll() override;
 
     /**
      * Given a row, use the row's match to figure out the appropriate
      * <treerow> in the rule's <action>.
      */
     nsresult
-    GetTemplateActionRowFor(int32_t aRow, mozilla::dom::Element** aResult);
+    GetTemplateActionRowFor(int32_t aRow, nsIContent** aResult);
 
     /**
      * Given a row and a column ID, use the row's match to figure out
      * the appropriate <treecell> in the rule's <action>.
      */
     nsIContent*
     GetTemplateActionCellFor(int32_t aRow, nsTreeColumn& aCol);
 
@@ -243,26 +243,26 @@ protected:
     // from nsXULTemplateBuilder
 
     /**
      * Return true if the result can be inserted into the template as a new
      * row.
      */
     bool
     GetInsertionLocations(nsIXULTemplateResult* aResult,
-                          nsCOMArray<Element>** aLocations) override;
+                          nsCOMArray<nsIContent>** aLocations) override;
 
     /**
      * Implement result replacement
      */
     virtual nsresult
     ReplaceMatch(nsIXULTemplateResult* aOldResult,
                  nsTemplateMatch* aNewMatch,
                  nsTemplateRule* aNewMatchRule,
-                 Element* aContext) override;
+                 void* aContext) override;
 
     /**
      * Implement match synchronization
      */
     virtual nsresult
     SynchronizeResult(nsIXULTemplateResult* aResult) override;
 
     bool IsValidRowIndex(int32_t aRowIndex);
--- a/editor/libeditor/EditorBase.cpp
+++ b/editor/libeditor/EditorBase.cpp
@@ -5343,17 +5343,17 @@ EditorBase::DetermineCurrentDirection()
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 EditorBase::SwitchTextDirection()
 {
   // Get the current root direction from its frame
-  Element* rootElement = GetExposedRoot();
+  nsIContent* rootElement = GetExposedRoot();
 
   nsresult rv = DetermineCurrentDirection();
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Apply the opposite direction
   if (IsRightToLeft()) {
     NS_ASSERTION(!IsLeftToRight(),
                  "Unexpected mutually exclusive flag");
@@ -5374,17 +5374,17 @@ EditorBase::SwitchTextDirection()
 
   return rv;
 }
 
 void
 EditorBase::SwitchTextDirectionTo(uint32_t aDirection)
 {
   // Get the current root direction from its frame
-  Element* rootElement = GetExposedRoot();
+  nsIContent* rootElement = GetExposedRoot();
 
   nsresult rv = DetermineCurrentDirection();
   NS_ENSURE_SUCCESS_VOID(rv);
 
   // Apply the requested direction
   if (aDirection == nsIPlaintextEditor::eEditorLeftToRight &&
       IsRightToLeft()) {
     NS_ASSERTION(!(mFlags & nsIPlaintextEditor::eEditorLeftToRight),
--- a/editor/libeditor/HTMLEditor.h
+++ b/editor/libeditor/HTMLEditor.h
@@ -750,17 +750,17 @@ protected:
                              const nsAString* aAttribute,
                              const bool aChildrenOnly = false);
   nsresult RemoveInlinePropertyImpl(nsAtom* aProperty,
                                     const nsAString* aAttribute);
 
   bool NodeIsProperty(nsINode& aNode);
   bool IsAtFrontOfNode(nsINode& aNode, int32_t aOffset);
   bool IsAtEndOfNode(nsINode& aNode, int32_t aOffset);
-  bool IsOnlyAttribute(const Element* aElement, const nsAString& aAttribute);
+  bool IsOnlyAttribute(const nsIContent* aElement, const nsAString& aAttribute);
 
   nsresult RemoveBlockContainer(nsIContent& aNode);
 
   nsIContent* GetPriorHTMLSibling(nsINode* aNode);
 
   nsIContent* GetNextHTMLSibling(nsINode* aNode);
 
   /**
--- a/editor/libeditor/HTMLStyleEditor.cpp
+++ b/editor/libeditor/HTMLStyleEditor.cpp
@@ -726,29 +726,31 @@ HTMLEditor::RemoveStyleInside(nsIContent
           CloneAttribute(nsGkAtoms::style, spanNode, aNode.AsElement());
         NS_ENSURE_SUCCESS(rv, rv);
         rv =
           CloneAttribute(nsGkAtoms::_class, spanNode, aNode.AsElement());
         NS_ENSURE_SUCCESS(rv, rv);
       }
       nsresult rv = RemoveContainer(&aNode);
       NS_ENSURE_SUCCESS(rv, rv);
-    } else if (aNode.IsElement()) {
+    } else {
       // otherwise we just want to eliminate the attribute
       RefPtr<nsAtom> attribute = NS_Atomize(*aAttribute);
-      if (aNode.AsElement()->HasAttr(kNameSpaceID_None, attribute)) {
+      if (aNode.HasAttr(kNameSpaceID_None, attribute)) {
         // if this matching attribute is the ONLY one on the node,
         // then remove the whole node.  Otherwise just nix the attribute.
-        if (IsOnlyAttribute(aNode.AsElement(), *aAttribute)) {
+        if (IsOnlyAttribute(&aNode, *aAttribute)) {
           nsresult rv = RemoveContainer(&aNode);
           if (NS_WARN_IF(NS_FAILED(rv))) {
             return rv;
           }
         } else {
-          nsresult rv = RemoveAttribute(aNode.AsElement(), attribute);
+          nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(&aNode);
+          NS_ENSURE_TRUE(elem, NS_ERROR_NULL_POINTER);
+          nsresult rv = RemoveAttribute(elem, *aAttribute);
           if (NS_WARN_IF(NS_FAILED(rv))) {
             return rv;
           }
         }
       }
     }
   }
 
@@ -789,24 +791,24 @@ HTMLEditor::RemoveStyleInside(nsIContent
       aAttribute && aAttribute->LowerCaseEqualsLiteral("size")) {
     // if we are setting font size, remove any nested bigs and smalls
     return RemoveContainer(&aNode);
   }
   return NS_OK;
 }
 
 bool
-HTMLEditor::IsOnlyAttribute(const Element* aElement,
+HTMLEditor::IsOnlyAttribute(const nsIContent* aContent,
                             const nsAString& aAttribute)
 {
-  MOZ_ASSERT(aElement);
+  MOZ_ASSERT(aContent);
 
-  uint32_t attrCount = aElement->GetAttrCount();
+  uint32_t attrCount = aContent->GetAttrCount();
   for (uint32_t i = 0; i < attrCount; ++i) {
-    const nsAttrName* name = aElement->GetAttrNameAt(i);
+    const nsAttrName* name = aContent->GetAttrNameAt(i);
     if (!name->NamespaceEquals(kNameSpaceID_None)) {
       return false;
     }
 
     nsAutoString attrString;
     name->LocalName()->ToString(attrString);
     // if it's the attribute we know about, or a special _moz attribute,
     // keep looking
--- a/editor/libeditor/TextEditRules.cpp
+++ b/editor/libeditor/TextEditRules.cpp
@@ -1380,22 +1380,19 @@ TextEditRules::CreateTrailingBRIfNeeded(
 
   // Check to see if the trailing BR is a former bogus node - this will have
   // stuck around if we previously morphed a trailing node into a bogus node.
   if (!mTextEditor->IsMozEditorBogusNode(lastChild)) {
     return NS_OK;
   }
 
   // Morph it back to a mozBR
-  lastChild->AsElement()->UnsetAttr(kNameSpaceID_None,
-                                    kMOZEditorBogusNodeAttrAtom,
-                                    false);
-  lastChild->AsElement()->SetAttr(kNameSpaceID_None, nsGkAtoms::type,
-                                  NS_LITERAL_STRING("_moz"),
-                                  true);
+  lastChild->UnsetAttr(kNameSpaceID_None, kMOZEditorBogusNodeAttrAtom, false);
+  lastChild->SetAttr(kNameSpaceID_None, nsGkAtoms::type,
+                     NS_LITERAL_STRING("_moz"), true);
   return NS_OK;
 }
 
 nsresult
 TextEditRules::CreateBogusNodeIfNeeded(Selection* aSelection)
 {
   NS_ENSURE_TRUE(aSelection, NS_ERROR_NULL_POINTER);
   NS_ENSURE_TRUE(mTextEditor, NS_ERROR_NULL_POINTER);
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -5884,17 +5884,17 @@ nsCSSFrameConstructor::AddFrameConstruct
       if (!xblService)
         return;
 
       bool resolveStyle;
 
       nsAutoPtr<PendingBinding> newPendingBinding(new PendingBinding());
 
       nsresult rv = xblService->LoadBindings(
-        aContent->AsElement(), display->mBinding->GetURI(),
+        aContent, display->mBinding->GetURI(),
         display->mBinding->mExtraData->GetPrincipal(),
         getter_AddRefs(newPendingBinding->mBinding), &resolveStyle);
       if (NS_FAILED(rv) && rv != NS_ERROR_XBL_BLOCKED)
         return;
 
       if (newPendingBinding->mBinding) {
         pendingBinding = newPendingBinding;
         // aState takes over owning newPendingBinding
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -8472,57 +8472,57 @@ nsLayoutUtils::PostRestyleEvent(Element*
     nsCOMPtr<nsIPresShell> presShell = doc->GetShell();
     if (presShell) {
       presShell->GetPresContext()->RestyleManager()->PostRestyleEvent(
         aElement, aRestyleHint, aMinChangeHint);
     }
   }
 }
 
-nsSetAttrRunnable::nsSetAttrRunnable(Element* aElement,
+nsSetAttrRunnable::nsSetAttrRunnable(nsIContent* aContent,
                                      nsAtom* aAttrName,
                                      const nsAString& aValue)
   : mozilla::Runnable("nsSetAttrRunnable")
-  , mElement(aElement)
+  , mContent(aContent)
   , mAttrName(aAttrName)
   , mValue(aValue)
 {
-  NS_ASSERTION(aElement && aAttrName, "Missing stuff, prepare to crash");
-}
-
-nsSetAttrRunnable::nsSetAttrRunnable(Element* aElement,
+  NS_ASSERTION(aContent && aAttrName, "Missing stuff, prepare to crash");
+}
+
+nsSetAttrRunnable::nsSetAttrRunnable(nsIContent* aContent,
                                      nsAtom* aAttrName,
                                      int32_t aValue)
   : mozilla::Runnable("nsSetAttrRunnable")
-  , mElement(aElement)
+  , mContent(aContent)
   , mAttrName(aAttrName)
 {
-  NS_ASSERTION(aElement && aAttrName, "Missing stuff, prepare to crash");
+  NS_ASSERTION(aContent && aAttrName, "Missing stuff, prepare to crash");
   mValue.AppendInt(aValue);
 }
 
 NS_IMETHODIMP
 nsSetAttrRunnable::Run()
 {
-  return mElement->SetAttr(kNameSpaceID_None, mAttrName, mValue, true);
-}
-
-nsUnsetAttrRunnable::nsUnsetAttrRunnable(Element* aElement,
+  return mContent->SetAttr(kNameSpaceID_None, mAttrName, mValue, true);
+}
+
+nsUnsetAttrRunnable::nsUnsetAttrRunnable(nsIContent* aContent,
                                          nsAtom* aAttrName)
   : mozilla::Runnable("nsUnsetAttrRunnable")
-  , mElement(aElement)
+  , mContent(aContent)
   , mAttrName(aAttrName)
 {
-  NS_ASSERTION(aElement && aAttrName, "Missing stuff, prepare to crash");
+  NS_ASSERTION(aContent && aAttrName, "Missing stuff, prepare to crash");
 }
 
 NS_IMETHODIMP
 nsUnsetAttrRunnable::Run()
 {
-  return mElement->UnsetAttr(kNameSpaceID_None, mAttrName, true);
+  return mContent->UnsetAttr(kNameSpaceID_None, mAttrName, true);
 }
 
 /**
  * Compute the minimum font size inside of a container with the given
  * width, such that **when the user zooms the container to fill the full
  * width of the device**, the fonts satisfy our minima.
  */
 static nscoord
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -3249,36 +3249,36 @@ void StrokeLineWithSnapping(const nsPoin
                                           nsPresContext* aPresContext);
 
   } // namespace layout
 } // namespace mozilla
 
 class nsSetAttrRunnable : public mozilla::Runnable
 {
 public:
-  nsSetAttrRunnable(mozilla::dom::Element* aElement, nsAtom* aAttrName,
+  nsSetAttrRunnable(nsIContent* aContent, nsAtom* aAttrName,
                     const nsAString& aValue);
-  nsSetAttrRunnable(mozilla::dom::Element* aElement, nsAtom* aAttrName,
+  nsSetAttrRunnable(nsIContent* aContent, nsAtom* aAttrName,
                     int32_t aValue);
 
   NS_DECL_NSIRUNNABLE
 
-  RefPtr<Element> mElement;
+  nsCOMPtr<nsIContent> mContent;
   RefPtr<nsAtom> mAttrName;
   nsAutoString mValue;
 };
 
 class nsUnsetAttrRunnable : public mozilla::Runnable
 {
 public:
-  nsUnsetAttrRunnable(mozilla::dom::Element* aElement, nsAtom* aAttrName);
+  nsUnsetAttrRunnable(nsIContent* aContent, nsAtom* aAttrName);
 
   NS_DECL_NSIRUNNABLE
 
-  RefPtr<Element> mElement;
+  nsCOMPtr<nsIContent> mContent;
   RefPtr<nsAtom> mAttrName;
 };
 
 // This class allows you to easily set any pointer variable and ensure it's
 // set to nullptr when leaving its scope.
 template<typename T>
 class MOZ_RAII SetAndNullOnExit
 {
--- a/layout/forms/nsButtonFrameRenderer.cpp
+++ b/layout/forms/nsButtonFrameRenderer.cpp
@@ -55,24 +55,23 @@ nsButtonFrameRenderer::SetFrame(nsFrame*
 
 nsIFrame*
 nsButtonFrameRenderer::GetFrame()
 {
   return mFrame;
 }
 
 void
-nsButtonFrameRenderer::SetDisabled(bool aDisabled, bool aNotify)
+nsButtonFrameRenderer::SetDisabled(bool aDisabled, bool notify)
 {
-  Element* element = mFrame->GetContent()->AsElement();
   if (aDisabled)
-    element->SetAttr(kNameSpaceID_None, nsGkAtoms::disabled, EmptyString(),
-                     aNotify);
+    mFrame->GetContent()->SetAttr(kNameSpaceID_None, nsGkAtoms::disabled, EmptyString(),
+                                  notify);
   else
-    element->UnsetAttr(kNameSpaceID_None, nsGkAtoms::disabled, aNotify);
+    mFrame->GetContent()->UnsetAttr(kNameSpaceID_None, nsGkAtoms::disabled, notify);
 }
 
 bool
 nsButtonFrameRenderer::isDisabled()
 {
   return mFrame->GetContent()->AsElement()->
     State().HasState(NS_EVENT_STATE_DISABLED);
 }
--- a/layout/forms/nsComboboxControlFrame.h
+++ b/layout/forms/nsComboboxControlFrame.h
@@ -279,17 +279,17 @@ protected:
 private:
   // If our total transform to the root frame of the root document is only a 2d
   // translation then return that translation, otherwise returns (0,0).
   nsPoint GetCSSTransformTranslation();
 
 protected:
   nsFrameList              mPopupFrames;             // additional named child list
   nsCOMPtr<nsIContent>     mDisplayContent;          // Anonymous content used to display the current selection
-  RefPtr<Element>     mButtonContent;                // Anonymous content for the button
+  nsCOMPtr<nsIContent>     mButtonContent;           // Anonymous content for the button
   nsContainerFrame*        mDisplayFrame;            // frame to display selection
   nsIFrame*                mButtonFrame;             // button frame
   nsIFrame*                mDropdownFrame;           // dropdown list frame
   nsIListControlFrame *    mListControlFrame;        // ListControl Interface for the dropdown frame
 
   // The inline size of our display area.  Used by that frame's reflow
   // to size to the full inline size except the drop-marker.
   nscoord mDisplayISize;
--- a/layout/forms/nsDateTimeControlFrame.h
+++ b/layout/forms/nsDateTimeControlFrame.h
@@ -109,12 +109,12 @@ private:
 
   /**
    * Sync the disabled state of the anonymous children up with our content's.
    */
   void SyncDisabledState();
 
   // Anonymous child which is bound via XBL to an element that wraps the input
   // area and reset button.
-  RefPtr<mozilla::dom::Element> mInputAreaContent;
+  nsCOMPtr<nsIContent> mInputAreaContent;
 };
 
 #endif // nsDateTimeControlFrame_h__
--- a/layout/forms/nsFileControlFrame.h
+++ b/layout/forms/nsFileControlFrame.h
@@ -131,22 +131,22 @@ protected:
     return nsBlockFrame::IsFrameOfType(aFlags &
       ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock));
   }
 
   /**
    * The text box input.
    * @see nsFileControlFrame::CreateAnonymousContent
    */
-  RefPtr<Element> mTextContent;
+  nsCOMPtr<nsIContent> mTextContent;
   /**
    * The button to open a file or directory picker.
    * @see nsFileControlFrame::CreateAnonymousContent
    */
-  RefPtr<Element> mBrowseFilesOrDirs;
+  nsCOMPtr<nsIContent> mBrowseFilesOrDirs;
 
   /**
    * Drag and drop mouse listener.
    * This makes sure we don't get used after destruction.
    */
   RefPtr<DnDListener> mMouseListener;
 
 protected:
--- a/layout/forms/nsHTMLButtonControlFrame.cpp
+++ b/layout/forms/nsHTMLButtonControlFrame.cpp
@@ -371,18 +371,18 @@ nsHTMLButtonControlFrame::GetNaturalBase
     *aBaseline += BSize(aWM) - (innerBStart + inner->BSize(aWM));
   }
   return true;
 }
 
 nsresult nsHTMLButtonControlFrame::SetFormProperty(nsAtom* aName, const nsAString& aValue)
 {
   if (nsGkAtoms::value == aName) {
-    return mContent->AsElement()->SetAttr(kNameSpaceID_None, nsGkAtoms::value,
-                                          aValue, true);
+    return mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::value,
+                             aValue, true);
   }
   return NS_OK;
 }
 
 nsStyleContext*
 nsHTMLButtonControlFrame::GetAdditionalStyleContext(int32_t aIndex) const
 {
   return mRenderer.GetStyleContext(aIndex);
--- a/layout/generic/ScrollbarActivity.cpp
+++ b/layout/generic/ScrollbarActivity.cpp
@@ -11,17 +11,16 @@
 #include "nsIDOMEvent.h"
 #include "nsIDOMCSSStyleDeclaration.h"
 #include "nsIFrame.h"
 #include "nsContentUtils.h"
 #include "nsAString.h"
 #include "nsQueryFrame.h"
 #include "nsComponentManagerUtils.h"
 #include "nsStyledElement.h"
-#include "mozilla/dom/Element.h"
 #include "mozilla/LookAndFeel.h"
 #include "mozilla/Preferences.h"
 
 namespace mozilla {
 namespace layout {
 
 NS_IMPL_ISUPPORTS(ScrollbarActivity, nsIDOMEventListener)
 
@@ -155,17 +154,17 @@ bool
 ScrollbarActivity::IsStillFading(TimeStamp aTime)
 {
   return !mFadeBeginTime.IsNull() && (aTime - mFadeBeginTime < FadeDuration());
 }
 
 void
 ScrollbarActivity::HandleEventForScrollbar(const nsAString& aType,
                                            nsIContent* aTarget,
-                                           Element* aScrollbar,
+                                           nsIContent* aScrollbar,
                                            bool* aStoredHoverState)
 {
   if (!aTarget || !aScrollbar ||
       !nsContentUtils::ContentIsDescendantOf(aTarget, aScrollbar))
     return;
 
   if (aType.EqualsLiteral("mousedown")) {
     ActivityStarted();
@@ -319,24 +318,24 @@ ScrollbarActivity::UnregisterFromRefresh
 {
   nsRefreshDriver* refreshDriver = GetRefreshDriver();
   if (refreshDriver) {
     refreshDriver->RemoveRefreshObserver(this, FlushType::Style);
   }
 }
 
 static void
-SetBooleanAttribute(Element* aElement, nsAtom* aAttribute, bool aValue)
+SetBooleanAttribute(nsIContent* aContent, nsAtom* aAttribute, bool aValue)
 {
-  if (aElement) {
+  if (aContent) {
     if (aValue) {
-      aElement->SetAttr(kNameSpaceID_None, aAttribute,
+      aContent->SetAttr(kNameSpaceID_None, aAttribute,
                         NS_LITERAL_STRING("true"), true);
     } else {
-      aElement->UnsetAttr(kNameSpaceID_None, aAttribute, true);
+      aContent->UnsetAttr(kNameSpaceID_None, aAttribute, true);
     }
   }
 }
 
 void
 ScrollbarActivity::SetIsActive(bool aNewActive)
 {
   if (mIsActive == aNewActive)
@@ -441,31 +440,31 @@ void
 ScrollbarActivity::CancelFadeBeginTimer()
 {
   if (mFadeBeginTimer) {
     mFadeBeginTimer->Cancel();
   }
 }
 
 void
-ScrollbarActivity::HoveredScrollbar(Element* aScrollbar)
+ScrollbarActivity::HoveredScrollbar(nsIContent* aScrollbar)
 {
   SetBooleanAttribute(GetHorizontalScrollbar(), nsGkAtoms::hover, false);
   SetBooleanAttribute(GetVerticalScrollbar(), nsGkAtoms::hover, false);
   SetBooleanAttribute(aScrollbar, nsGkAtoms::hover, true);
 }
 
 nsRefreshDriver*
 ScrollbarActivity::GetRefreshDriver()
 {
   nsIFrame* scrollableFrame = do_QueryFrame(mScrollableFrame);
   return scrollableFrame->PresContext()->RefreshDriver();
 }
 
-Element*
+nsIContent*
 ScrollbarActivity::GetScrollbarContent(bool aVertical)
 {
   nsIFrame* box = mScrollableFrame->GetScrollbarBox(aVertical);
-  return box ? box->GetContent()->AsElement() : nullptr;
+  return box ? box->GetContent() : nullptr;
 }
 
 } // namespace layout
 } // namespace mozilla
--- a/layout/generic/ScrollbarActivity.h
+++ b/layout/generic/ScrollbarActivity.h
@@ -97,17 +97,17 @@ protected:
 
   bool IsActivityOngoing()
   { return mNestedActivityCounter > 0; }
   bool IsStillFading(TimeStamp aTime);
   void QueryLookAndFeelVals();
 
   void HandleEventForScrollbar(const nsAString& aType,
                                nsIContent* aTarget,
-                               dom::Element* aScrollbar,
+                               nsIContent* aScrollbar,
                                bool* aStoredHoverState);
 
   void SetIsActive(bool aNewActive);
   bool SetIsFading(bool aNewFading); // returns false if 'this' was destroyed
 
   void BeginFade();
   void EndFade();
 
@@ -120,22 +120,22 @@ protected:
   void StopListeningForScrollAreaEvents();
   void AddScrollbarEventListeners(nsIDOMEventTarget* aScrollbar);
   void RemoveScrollbarEventListeners(nsIDOMEventTarget* aScrollbar);
 
   void RegisterWithRefreshDriver();
   void UnregisterFromRefreshDriver();
 
   bool UpdateOpacity(TimeStamp aTime); // returns false if 'this' was destroyed
-  void HoveredScrollbar(dom::Element* aScrollbar);
+  void HoveredScrollbar(nsIContent* aScrollbar);
 
   nsRefreshDriver* GetRefreshDriver();
-  dom::Element* GetScrollbarContent(bool aVertical);
-  dom::Element* GetHorizontalScrollbar() { return GetScrollbarContent(false); }
-  dom::Element* GetVerticalScrollbar() { return GetScrollbarContent(true); }
+  nsIContent* GetScrollbarContent(bool aVertical);
+  nsIContent* GetHorizontalScrollbar() { return GetScrollbarContent(false); }
+  nsIContent* GetVerticalScrollbar() { return GetScrollbarContent(true); }
 
   const TimeDuration FadeDuration() {
     return TimeDuration::FromMilliseconds(mScrollbarFadeDuration);
   }
 
   nsIScrollbarMediator* mScrollableFrame;
   TimeStamp mFadeBeginTime;
   nsCOMPtr<nsITimer> mFadeBeginTimer;
--- a/layout/generic/nsFrameSetFrame.cpp
+++ b/layout/generic/nsFrameSetFrame.cpp
@@ -1258,18 +1258,17 @@ nsHTMLFramesetFrame::MouseDrag(nsPresCon
       HTMLFrameSetElement* ourContent = HTMLFrameSetElement::FromContent(mContent);
       NS_ASSERTION(ourContent, "Someone gave us a broken frameset element!");
       const nsFramesetSpec* colSpecs = nullptr;
       ourContent->GetColSpec(&mNumCols, &colSpecs);
       nsAutoString newColAttr;
       GenerateRowCol(aPresContext, width, mNumCols, colSpecs, mColSizes.get(),
                      newColAttr);
       // Setting the attr will trigger a reflow
-      mContent->AsElement()->SetAttr(kNameSpaceID_None, nsGkAtoms::cols,
-                                     newColAttr, true);
+      mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::cols, newColAttr, true);
     }
   } else {
     change = aPresContext->DevPixelsToAppUnits(
                              aEvent->mRefPoint.y - mFirstDragPoint.y);
     if (change > mNextNeighborOrigSize - mMinDrag) {
       change = mNextNeighborOrigSize - mMinDrag;
     } else if (change <= mMinDrag - mPrevNeighborOrigSize) {
       change = mMinDrag - mPrevNeighborOrigSize;
@@ -1283,18 +1282,17 @@ nsHTMLFramesetFrame::MouseDrag(nsPresCon
       HTMLFrameSetElement* ourContent = HTMLFrameSetElement::FromContent(mContent);
       NS_ASSERTION(ourContent, "Someone gave us a broken frameset element!");
       const nsFramesetSpec* rowSpecs = nullptr;
       ourContent->GetRowSpec(&mNumRows, &rowSpecs);
       nsAutoString newRowAttr;
       GenerateRowCol(aPresContext, height, mNumRows, rowSpecs, mRowSizes.get(),
                      newRowAttr);
       // Setting the attr will trigger a reflow
-      mContent->AsElement()->SetAttr(kNameSpaceID_None, nsGkAtoms::rows,
-                                     newRowAttr, true);
+      mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::rows, newRowAttr, true);
     }
   }
 
   ENSURE_TRUE(weakFrame.IsAlive());
   if (change != 0) {
     mDrag.Reset(mDragger->mVertical, mDragger->mPrevNeighbor, change, this);
   }
 }
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -4770,24 +4770,24 @@ ScrollFrameHelper::Destroy(PostDestroyDa
 void
 ScrollFrameHelper::UpdateScrollbarPosition()
 {
   AutoWeakFrame weakFrame(mOuter);
   mFrameIsUpdatingScrollbar = true;
 
   nsPoint pt = GetScrollPosition();
   if (mVScrollbarBox) {
-    SetCoordAttribute(mVScrollbarBox->GetContent()->AsElement(),
-                      nsGkAtoms::curpos, pt.y - GetScrolledRect().y);
+    SetCoordAttribute(mVScrollbarBox->GetContent(), nsGkAtoms::curpos,
+                      pt.y - GetScrolledRect().y);
     if (!weakFrame.IsAlive()) {
       return;
     }
   }
   if (mHScrollbarBox) {
-    SetCoordAttribute(mHScrollbarBox->GetContent()->AsElement(), nsGkAtoms::curpos,
+    SetCoordAttribute(mHScrollbarBox->GetContent(), nsGkAtoms::curpos,
                       pt.x - GetScrolledRect().x);
     if (!weakFrame.IsAlive()) {
       return;
     }
   }
 
   mFrameIsUpdatingScrollbar = false;
 }
@@ -5446,28 +5446,28 @@ nsXULScrollFrame::XULLayout(nsBoxLayoutS
 
   mHelper.UpdatePrevScrolledRect();
 
   mHelper.PostOverflowEvent();
   return NS_OK;
 }
 
 void
-ScrollFrameHelper::FinishReflowForScrollbar(Element* aElement,
-                                            nscoord aMinXY, nscoord aMaxXY,
-                                            nscoord aCurPosXY,
-                                            nscoord aPageIncrement,
-                                            nscoord aIncrement)
+ScrollFrameHelper::FinishReflowForScrollbar(nsIContent* aContent,
+                                                nscoord aMinXY, nscoord aMaxXY,
+                                                nscoord aCurPosXY,
+                                                nscoord aPageIncrement,
+                                                nscoord aIncrement)
 {
   // Scrollbars assume zero is the minimum position, so translate for them.
-  SetCoordAttribute(aElement, nsGkAtoms::curpos, aCurPosXY - aMinXY);
-  SetScrollbarEnabled(aElement, aMaxXY - aMinXY);
-  SetCoordAttribute(aElement, nsGkAtoms::maxpos, aMaxXY - aMinXY);
-  SetCoordAttribute(aElement, nsGkAtoms::pageincrement, aPageIncrement);
-  SetCoordAttribute(aElement, nsGkAtoms::increment, aIncrement);
+  SetCoordAttribute(aContent, nsGkAtoms::curpos, aCurPosXY - aMinXY);
+  SetScrollbarEnabled(aContent, aMaxXY - aMinXY);
+  SetCoordAttribute(aContent, nsGkAtoms::maxpos, aMaxXY - aMinXY);
+  SetCoordAttribute(aContent, nsGkAtoms::pageincrement, aPageIncrement);
+  SetCoordAttribute(aContent, nsGkAtoms::increment, aIncrement);
 }
 
 bool
 ScrollFrameHelper::ReflowFinished()
 {
   mPostedReflowCallback = false;
 
   bool doScroll = true;
@@ -5521,21 +5521,20 @@ ScrollFrameHelper::ReflowFinished()
   nscoord maxX = scrolledContentRect.XMost() - scrollClampingScrollPort.width;
   nscoord minY = scrolledContentRect.y;
   nscoord maxY = scrolledContentRect.YMost() - scrollClampingScrollPort.height;
 
   // Suppress handling of the curpos attribute changes we make here.
   NS_ASSERTION(!mFrameIsUpdatingScrollbar, "We shouldn't be reentering here");
   mFrameIsUpdatingScrollbar = true;
 
-  // FIXME(emilio): Why this instead of mHScrollbarContent / mVScrollbarContent?
-  RefPtr<Element> vScroll =
-    mVScrollbarBox ? mVScrollbarBox->GetContent()->AsElement() : nullptr;
-  RefPtr<Element> hScroll =
-    mHScrollbarBox ? mHScrollbarBox->GetContent()->AsElement() : nullptr;
+  nsCOMPtr<nsIContent> vScroll =
+    mVScrollbarBox ? mVScrollbarBox->GetContent() : nullptr;
+  nsCOMPtr<nsIContent> hScroll =
+    mHScrollbarBox ? mHScrollbarBox->GetContent() : nullptr;
 
   // Note, in some cases mOuter may get deleted while finishing reflow
   // for scrollbars. XXXmats is this still true now that we have a script
   // blocker in this scope? (if not, remove the weak frame checks below).
   if (vScroll || hScroll) {
     AutoWeakFrame weakFrame(mOuter);
     nsPoint scrollPos = GetScrollPosition();
     nsSize lineScrollAmount = GetLineScrollAmount();
@@ -5867,50 +5866,50 @@ ScrollFrameHelper::LayoutScrollbars(nsBo
 static bool ShellIsAlive(nsWeakPtr& aWeakPtr)
 {
   nsCOMPtr<nsIPresShell> shell(do_QueryReferent(aWeakPtr));
   return !!shell;
 }
 #endif
 
 void
-ScrollFrameHelper::SetScrollbarEnabled(Element* aElement, nscoord aMaxPos)
+ScrollFrameHelper::SetScrollbarEnabled(nsIContent* aContent, nscoord aMaxPos)
 {
   DebugOnly<nsWeakPtr> weakShell(
     do_GetWeakReference(mOuter->PresShell()));
   if (aMaxPos) {
-    aElement->UnsetAttr(kNameSpaceID_None, nsGkAtoms::disabled, true);
+    aContent->UnsetAttr(kNameSpaceID_None, nsGkAtoms::disabled, true);
   } else {
-    aElement->SetAttr(kNameSpaceID_None, nsGkAtoms::disabled,
+    aContent->SetAttr(kNameSpaceID_None, nsGkAtoms::disabled,
                       NS_LITERAL_STRING("true"), true);
   }
   MOZ_ASSERT(ShellIsAlive(weakShell), "pres shell was destroyed by scrolling");
 }
 
 void
-ScrollFrameHelper::SetCoordAttribute(Element* aElement, nsAtom* aAtom,
-                                     nscoord aSize)
+ScrollFrameHelper::SetCoordAttribute(nsIContent* aContent, nsAtom* aAtom,
+                                         nscoord aSize)
 {
   DebugOnly<nsWeakPtr> weakShell(
     do_GetWeakReference(mOuter->PresShell()));
   // convert to pixels
   int32_t pixelSize = nsPresContext::AppUnitsToIntCSSPixels(aSize);
 
   // only set the attribute if it changed.
 
   nsAutoString newValue;
   newValue.AppendInt(pixelSize);
 
-  if (aElement->AttrValueIs(kNameSpaceID_None, aAtom, newValue, eCaseMatters)) {
+  if (aContent->AttrValueIs(kNameSpaceID_None, aAtom, newValue, eCaseMatters)) {
     return;
   }
 
   AutoWeakFrame weakFrame(mOuter);
-  RefPtr<Element> kungFuDeathGrip = aElement;
-  aElement->SetAttr(kNameSpaceID_None, aAtom, newValue, true);
+  nsCOMPtr<nsIContent> kungFuDeathGrip = aContent;
+  aContent->SetAttr(kNameSpaceID_None, aAtom, newValue, true);
   MOZ_ASSERT(ShellIsAlive(weakShell), "pres shell was destroyed by scrolling");
   if (!weakFrame.IsAlive()) {
     return;
   }
 
   if (mScrollbarActivity) {
     RefPtr<ScrollbarActivity> scrollbarActivity(mScrollbarActivity);
     scrollbarActivity->ActivityOccurred();
--- a/layout/generic/nsGfxScrollFrame.h
+++ b/layout/generic/nsGfxScrollFrame.h
@@ -165,30 +165,28 @@ public:
     void Revoke() { mHelper = nullptr; }
   private:
     ScrollFrameHelper *mHelper;
   };
 
   /**
    * @note This method might destroy the frame, pres shell and other objects.
    */
-  void FinishReflowForScrollbar(mozilla::dom::Element* aElement,
-                                nscoord aMinXY, nscoord aMaxXY,
-                                nscoord aCurPosXY, nscoord aPageIncrement,
+  void FinishReflowForScrollbar(nsIContent* aContent, nscoord aMinXY,
+                                nscoord aMaxXY, nscoord aCurPosXY,
+                                nscoord aPageIncrement,
                                 nscoord aIncrement);
   /**
    * @note This method might destroy the frame, pres shell and other objects.
    */
-  void SetScrollbarEnabled(mozilla::dom::Element* aElement, nscoord aMaxPos);
+  void SetScrollbarEnabled(nsIContent* aContent, nscoord aMaxPos);
   /**
    * @note This method might destroy the frame, pres shell and other objects.
    */
-  void SetCoordAttribute(mozilla::dom::Element* aElement,
-                         nsAtom* aAtom,
-                         nscoord aSize);
+  void SetCoordAttribute(nsIContent* aContent, nsAtom* aAtom, nscoord aSize);
 
   nscoord GetCoordAttribute(nsIFrame* aFrame, nsAtom* aAtom, nscoord aDefaultValue,
                             nscoord* aRangeStart, nscoord* aRangeLength);
 
   /**
    * @note This method might destroy the frame, pres shell and other objects.
    * Update scrollbar curpos attributes to reflect current scroll position
    */
@@ -497,20 +495,20 @@ public:
 
   bool DragScroll(WidgetEvent* aEvent);
 
   void AsyncScrollbarDragRejected();
 
   bool IsRootScrollFrameOfDocument() const { return mIsRoot; }
 
   // owning references to the nsIAnonymousContentCreator-built content
-  nsCOMPtr<mozilla::dom::Element> mHScrollbarContent;
-  nsCOMPtr<mozilla::dom::Element> mVScrollbarContent;
-  nsCOMPtr<mozilla::dom::Element> mScrollCornerContent;
-  nsCOMPtr<mozilla::dom::Element> mResizerContent;
+  nsCOMPtr<nsIContent> mHScrollbarContent;
+  nsCOMPtr<nsIContent> mVScrollbarContent;
+  nsCOMPtr<nsIContent> mScrollCornerContent;
+  nsCOMPtr<nsIContent> mResizerContent;
 
   RefPtr<ScrollEvent> mScrollEvent;
   RefPtr<ScrollEndEvent> mScrollEndEvent;
   nsRevocableEventPtr<AsyncScrollPortEvent> mAsyncScrollPortEvent;
   nsRevocableEventPtr<ScrolledAreaEvent> mScrolledAreaEvent;
   nsIFrame* mHScrollbarBox;
   nsIFrame* mVScrollbarBox;
   nsIFrame* mScrolledFrame;
--- a/layout/generic/nsVideoFrame.cpp
+++ b/layout/generic/nsVideoFrame.cpp
@@ -88,39 +88,41 @@ NS_QUERYFRAME_HEAD(nsVideoFrame)
   NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
 NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
 
 nsresult
 nsVideoFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
 {
   nsNodeInfoManager *nodeInfoManager = GetContent()->GetComposedDoc()->NodeInfoManager();
   RefPtr<NodeInfo> nodeInfo;
+  Element *element;
 
   if (HasVideoElement()) {
     // Create an anonymous image element as a child to hold the poster
     // image. We may not have a poster image now, but one could be added
     // before we load, or on a subsequent load.
     nodeInfo = nodeInfoManager->GetNodeInfo(nsGkAtoms::img,
                                             nullptr,
                                             kNameSpaceID_XHTML,
                                             nsIDOMNode::ELEMENT_NODE);
     NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
-    mPosterImage = NS_NewHTMLImageElement(nodeInfo.forget());
+    element = NS_NewHTMLImageElement(nodeInfo.forget());
+    mPosterImage = element;
     NS_ENSURE_TRUE(mPosterImage, NS_ERROR_OUT_OF_MEMORY);
 
     // Set the nsImageLoadingContent::ImageState() to 0. This means that the
     // image will always report its state as 0, so it will never be reframed
     // to show frames for loading or the broken image icon. This is important,
     // as the image is native anonymous, and so can't be reframed (currently).
     nsCOMPtr<nsIImageLoadingContent> imgContent = do_QueryInterface(mPosterImage);
     NS_ENSURE_TRUE(imgContent, NS_ERROR_FAILURE);
 
     imgContent->ForceImageState(true, 0);
     // And now have it update its internal state
-    mPosterImage->UpdateState(false);
+    element->UpdateState(false);
 
     UpdatePosterSource(false);
 
     if (!aElements.AppendElement(mPosterImage))
       return NS_ERROR_OUT_OF_MEMORY;
 
     // Set up the caption overlay div for showing any TextTrack data
     nodeInfo = nodeInfoManager->GetNodeInfo(nsGkAtoms::div,
--- a/layout/generic/nsVideoFrame.h
+++ b/layout/generic/nsVideoFrame.h
@@ -83,17 +83,17 @@ public:
     return nsSplittableFrame::IsFrameOfType(aFlags &
       ~(nsIFrame::eReplaced | nsIFrame::eReplacedSizing));
   }
 
   nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) override;
   void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                 uint32_t aFilters) override;
 
-  mozilla::dom::Element* GetPosterImage() { return mPosterImage; }
+  nsIContent* GetPosterImage() { return mPosterImage; }
 
   // Returns true if we should display the poster. Note that once we show
   // a video frame, the poster will never be displayed again.
   bool ShouldDisplayPoster();
 
   nsIContent *GetCaptionOverlay() { return mCaptionDiv; }
 
   nsIContent *GetVideoControls() { return mVideoControls; }
@@ -124,19 +124,19 @@ protected:
   void UpdatePosterSource(bool aNotify);
 
   // Notify the mediaElement that the mCaptionDiv was created.
   void UpdateTextTrack();
 
   virtual ~nsVideoFrame();
 
   // Anonymous child which is bound via XBL to the video controls.
-  RefPtr<mozilla::dom::Element> mVideoControls;
+  nsCOMPtr<nsIContent> mVideoControls;
 
   // Anonymous child which is the image element of the poster frame.
-  RefPtr<mozilla::dom::Element> mPosterImage;
+  nsCOMPtr<nsIContent> mPosterImage;
 
   // Anonymous child which is the text track caption display div.
   nsCOMPtr<nsIContent> mCaptionDiv;
 
 };
 
 #endif /* nsVideoFrame_h___ */
--- a/layout/mathml/nsMathMLmactionFrame.cpp
+++ b/layout/mathml/nsMathMLmactionFrame.cpp
@@ -325,18 +325,17 @@ void
 nsMathMLmactionFrame::MouseClick()
 {
   if (NS_MATHML_ACTION_TYPE_TOGGLE == mActionType) {
     if (mChildCount > 1) {
       int32_t selection = (mSelection == mChildCount)? 1 : mSelection + 1;
       nsAutoString value;
       value.AppendInt(selection);
       bool notify = false; // don't yet notify the document
-      mContent->AsElement()->SetAttr(kNameSpaceID_None, nsGkAtoms::selection_,
-                                     value, notify);
+      mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::selection_, value, notify);
 
       // Now trigger a content-changed reflow...
       PresShell()->
         FrameNeedsReflow(mSelectedFrame, nsIPresShell::eTreeChange,
                          NS_FRAME_IS_DIRTY);
     }
   }
 }
--- a/layout/xul/PopupBoxObject.cpp
+++ b/layout/xul/PopupBoxObject.cpp
@@ -156,25 +156,25 @@ PopupBoxObject::SizeTo(int32_t aWidth, i
 {
   if (!mContent)
     return;
 
   nsAutoString width, height;
   width.AppendInt(aWidth);
   height.AppendInt(aHeight);
 
-  RefPtr<Element> element = mContent->AsElement();
+  nsCOMPtr<nsIContent> content = mContent;
 
   // We only want to pass aNotify=true to SetAttr once, but must make sure
   // we pass it when a value is being changed.  Thus, we check if the height
   // is the same and if so, pass true when setting the width.
-  bool heightSame = element->AttrValueIs(kNameSpaceID_None, nsGkAtoms::height, height, eCaseMatters);
+  bool heightSame = content->AttrValueIs(kNameSpaceID_None, nsGkAtoms::height, height, eCaseMatters);
 
-  element->SetAttr(kNameSpaceID_None, nsGkAtoms::width, width, heightSame);
-  element->SetAttr(kNameSpaceID_None, nsGkAtoms::height, height, true);
+  content->SetAttr(kNameSpaceID_None, nsGkAtoms::width, width, heightSame);
+  content->SetAttr(kNameSpaceID_None, nsGkAtoms::height, height, true);
 }
 
 bool
 PopupBoxObject::AutoPosition()
 {
   nsMenuPopupFrame *menuPopupFrame = mContent ? do_QueryFrame(mContent->GetPrimaryFrame()) : nullptr;
   if (menuPopupFrame) {
     return menuPopupFrame->GetAutoPosition();
@@ -209,21 +209,20 @@ PopupBoxObject::SetConsumeRollupEvent(ui
 void
 PopupBoxObject::EnableKeyboardNavigator(bool aEnableKeyboardNavigator)
 {
   if (!mContent)
     return;
 
   // Use ignorekeys="true" on the popup instead of using this function.
   if (aEnableKeyboardNavigator)
-    mContent->AsElement()->UnsetAttr(kNameSpaceID_None, nsGkAtoms::ignorekeys,
-                                     true);
+    mContent->UnsetAttr(kNameSpaceID_None, nsGkAtoms::ignorekeys, true);
   else
-    mContent->AsElement()->SetAttr(kNameSpaceID_None, nsGkAtoms::ignorekeys,
-                                   NS_LITERAL_STRING("true"), true);
+    mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::ignorekeys,
+                      NS_LITERAL_STRING("true"), true);
 }
 
 void
 PopupBoxObject::GetPopupState(nsString& aState)
 {
   // set this here in case there's no frame for the popup
   aState.AssignLiteral("closed");
 
--- a/layout/xul/nsDeckFrame.cpp
+++ b/layout/xul/nsDeckFrame.cpp
@@ -173,17 +173,17 @@ nsDeckFrame::RemoveFrame(ChildListID aLi
     int32_t removedIndex = mFrames.IndexOf(aOldFrame);
     MOZ_ASSERT(removedIndex >= 0,
                "A deck child was removed that was not in mFrames.");
     if (removedIndex < mIndex) {
       mIndex--;
       // This is going to cause us to handle the index change in IndexedChanged,
       // but since the new index will match mIndex, it's essentially a noop.
       nsContentUtils::AddScriptRunner(new nsSetAttrRunnable(
-        mContent->AsElement(), nsGkAtoms::selectedIndex, mIndex));
+        mContent, nsGkAtoms::selectedIndex, mIndex));
     }
   }
   nsBoxFrame::RemoveFrame(aListID, aOldFrame);
 }
 
 void
 nsDeckFrame::BuildDisplayListForChildren(nsDisplayListBuilder*   aBuilder,
                                          const nsDisplayListSet& aLists)
--- a/layout/xul/nsIRootBox.h
+++ b/layout/xul/nsIRootBox.h
@@ -5,35 +5,29 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 
 #ifndef nsIRootBox_h___
 #define nsIRootBox_h___
 
 #include "nsQueryFrame.h"
 class nsPopupSetFrame;
+class nsIContent;
 class nsIPresShell;
-class nsIContent;
-
-namespace mozilla {
-namespace dom {
-class Element;
-}
-}
 
 class nsIRootBox
 {
 public:
   NS_DECL_QUERYFRAME_TARGET(nsIRootBox)
 
   virtual nsPopupSetFrame* GetPopupSetFrame() = 0;
   virtual void SetPopupSetFrame(nsPopupSetFrame* aPopupSet) = 0;
 
-  virtual mozilla::dom::Element* GetDefaultTooltip() = 0;
-  virtual void SetDefaultTooltip(mozilla::dom::Element* aTooltip) = 0;
+  virtual nsIContent* GetDefaultTooltip() = 0;
+  virtual void SetDefaultTooltip(nsIContent* aTooltip) = 0;
 
   virtual nsresult AddTooltipSupport(nsIContent* aNode) = 0;
   virtual nsresult RemoveTooltipSupport(nsIContent* aNode) = 0;
 
   static nsIRootBox* GetRootBox(nsIPresShell* aShell);
 };
 
 #endif
--- a/layout/xul/nsMenuFrame.cpp
+++ b/layout/xul/nsMenuFrame.cpp
@@ -64,17 +64,17 @@ NS_DECLARE_FRAME_PROPERTY_FRAMELIST(Popu
 static int32_t gMenuJustOpenedOrClosed = false;
 
 const int32_t kBlinkDelay = 67; // milliseconds
 
 // this class is used for dispatching menu activation events asynchronously.
 class nsMenuActivateEvent : public Runnable
 {
 public:
-  nsMenuActivateEvent(Element* aMenu,
+  nsMenuActivateEvent(nsIContent* aMenu,
                       nsPresContext* aPresContext,
                       bool aIsActivate)
     : mozilla::Runnable("nsMenuActivateEvent")
     , mMenu(aMenu)
     , mPresContext(aPresContext)
     , mIsActivate(aIsActivate)
   {
   }
@@ -104,17 +104,17 @@ public:
 
     EventDispatcher::DispatchDOMEvent(mMenu, nullptr, event,
         mPresContext, nullptr);
 
     return NS_OK;
   }
 
 private:
-  RefPtr<Element> mMenu;
+  nsCOMPtr<nsIContent> mMenu;
   RefPtr<nsPresContext> mPresContext;
   bool mIsActivate;
 };
 
 class nsMenuAttributeChangedEvent : public Runnable
 {
 public:
   nsMenuAttributeChangedEvent(nsIFrame* aFrame, nsAtom* aAttr)
@@ -332,18 +332,17 @@ nsMenuFrame::DestroyFrom(nsIFrame* aDest
   StopBlinking();
 
   // Null out the pointer to this frame in the mediator wrapper so that it
   // doesn't try to interact with a deallocated frame.
   mTimerMediator->ClearFrame();
 
   // if the menu content is just being hidden, it may be made visible again
   // later, so make sure to clear the highlighting.
-  mContent->AsElement()->UnsetAttr(kNameSpaceID_None, nsGkAtoms::menuactive,
-                                   false);
+  mContent->UnsetAttr(kNameSpaceID_None, nsGkAtoms::menuactive, false);
 
   // are we our menu parent's current menu item?
   nsMenuParent* menuParent = GetMenuParent();
   if (menuParent && menuParent->GetCurrentMenuItem() == this) {
     // yes; tell it that we're going away
     menuParent->CurrentMenuIsBeingDestroyed();
   }
 
@@ -549,18 +548,18 @@ nsMenuFrame::ToggleMenuState()
 }
 
 void
 nsMenuFrame::PopupOpened()
 {
   gMenuJustOpenedOrClosed = true;
 
   AutoWeakFrame weakFrame(this);
-  mContent->AsElement()->SetAttr(kNameSpaceID_None, nsGkAtoms::open,
-                                 NS_LITERAL_STRING("true"), true);
+  mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::open,
+                    NS_LITERAL_STRING("true"), true);
   if (!weakFrame.IsAlive())
     return;
 
   nsMenuParent* menuParent = GetMenuParent();
   if (menuParent) {
     menuParent->SetActive(true);
     // Make sure the current menu which is being toggled on
     // the menubar is highlighted
@@ -568,17 +567,17 @@ nsMenuFrame::PopupOpened()
   }
 }
 
 void
 nsMenuFrame::PopupClosed(bool aDeselectMenu)
 {
   AutoWeakFrame weakFrame(this);
   nsContentUtils::AddScriptRunner(
-    new nsUnsetAttrRunnable(mContent->AsElement(), nsGkAtoms::open));
+    new nsUnsetAttrRunnable(mContent, nsGkAtoms::open));
   if (!weakFrame.IsAlive())
     return;
 
   // if the popup is for a menu on a menubar, inform menubar to deactivate
   nsMenuParent* menuParent = GetMenuParent();
   if (menuParent && menuParent->MenuClosed()) {
     if (aDeselectMenu) {
       SelectMenu(false);
@@ -600,17 +599,17 @@ nsMenuFrame::PopupClosed(bool aDeselectM
           nsMenuBarFrame* menubar = do_QueryFrame(parent);
           if (menubar && menubar->GetStayActive())
             return;
 
           parent = parent->GetParent();
         }
 
         nsCOMPtr<nsIRunnable> event =
-          new nsMenuActivateEvent(current->GetContent()->AsElement(),
+          new nsMenuActivateEvent(current->GetContent(),
                                   PresContext(), true);
         mContent->OwnerDoc()->Dispatch(TaskCategory::Other,
                                        event.forget());
       }
     }
   }
 }
 
@@ -651,17 +650,17 @@ nsMenuFrame::SelectMenu(bool aActivateFl
     // cancel the close timer if selecting a menu within the popup to be closed
     nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
     if (pm) {
       nsMenuParent* menuParent = GetMenuParent();
       pm->CancelMenuTimer(menuParent);
     }
 
     nsCOMPtr<nsIRunnable> event =
-      new nsMenuActivateEvent(mContent->AsElement(), PresContext(), aActivateFlag);
+      new nsMenuActivateEvent(mContent, PresContext(), aActivateFlag);
     mContent->OwnerDoc()->Dispatch(TaskCategory::Other,
                                    event.forget());
   }
 
   return NS_OK;
 }
 
 nsresult
@@ -902,19 +901,18 @@ nsMenuFrame::Notify(nsITimer* aTimer)
       case 0:
         NS_ASSERTION(false, "Blink timer fired while not blinking");
         StopBlinking();
         break;
       case 1:
         {
           // Turn the highlight back on and wait for a while before closing the menu.
           AutoWeakFrame weakFrame(this);
-          mContent->AsElement()->SetAttr(kNameSpaceID_None,
-                                         nsGkAtoms::menuactive,
-                                         NS_LITERAL_STRING("true"), true);
+          mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::menuactive,
+                            NS_LITERAL_STRING("true"), true);
           if (weakFrame.IsAlive()) {
             aTimer->InitWithCallback(mTimerMediator, kBlinkDelay, nsITimer::TYPE_ONE_SHOT);
           }
         }
         break;
       default: {
         nsMenuParent* menuParent = GetMenuParent();
         if (menuParent) {
@@ -948,18 +946,18 @@ nsMenuFrame::UpdateMenuType()
     case 1:
       mType = eMenuType_Radio;
       mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::name, mGroupName);
       break;
 
     default:
       if (mType != eMenuType_Normal) {
         AutoWeakFrame weakFrame(this);
-        mContent->AsElement()->UnsetAttr(kNameSpaceID_None, nsGkAtoms::checked,
-                                         true);
+        mContent->UnsetAttr(kNameSpaceID_None, nsGkAtoms::checked,
+                            true);
         ENSURE_TRUE(weakFrame.IsAlive());
       }
       mType = eMenuType_Normal;
       break;
   }
   UpdateMenuSpecialState();
 }
 
@@ -1012,18 +1010,18 @@ nsMenuFrame::UpdateMenuSpecialState()
   nsIFrame* firstMenuItem = nsXULPopupManager::GetNextMenuItem(GetParent(), nullptr, true, false);
   nsIFrame* sib = firstMenuItem;
   while (sib) {
     nsMenuFrame* menu = do_QueryFrame(sib);
     if (sib != this) {
       if (menu && menu->GetMenuType() == eMenuType_Radio &&
           menu->IsChecked() && menu->GetRadioGroupName() == mGroupName) {
         /* uncheck the old item */
-        sib->GetContent()->AsElement()->UnsetAttr(
-            kNameSpaceID_None, nsGkAtoms::checked, true);
+        sib->GetContent()->UnsetAttr(kNameSpaceID_None, nsGkAtoms::checked,
+                                     true);
         /* XXX in DEBUG, check to make sure that there aren't two checked items */
         return;
       }
     }
     sib = nsXULPopupManager::GetNextMenuItem(GetParent(), menu, true, true);
     if (sib == firstMenuItem) {
       break;
     }
@@ -1042,17 +1040,17 @@ nsMenuFrame::BuildAcceleratorText(bool a
   }
   // accelText is definitely empty here.
 
   // Now we're going to compute the accelerator text, so remember that we did.
   AddStateBits(NS_STATE_ACCELTEXT_IS_DERIVED);
 
   // If anything below fails, just leave the accelerator text blank.
   AutoWeakFrame weakFrame(this);
-  mContent->AsElement()->UnsetAttr(kNameSpaceID_None, nsGkAtoms::acceltext, aNotify);
+  mContent->UnsetAttr(kNameSpaceID_None, nsGkAtoms::acceltext, aNotify);
   ENSURE_TRUE(weakFrame.IsAlive());
 
   // See if we have a key node and use that instead.
   nsAutoString keyValue;
   mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::key, keyValue);
   if (keyValue.IsEmpty())
     return;
 
@@ -1177,18 +1175,17 @@ nsMenuFrame::BuildAcceleratorText(bool a
     token = nsCRT::strtok(newStr, ", \t", &newStr);
   }
 
   free(str);
 
   accelText += accelString;
 
   mIgnoreAccelTextChange = true;
-  mContent->AsElement()->SetAttr(kNameSpaceID_None, nsGkAtoms::acceltext,
-                                 accelText, aNotify);
+  mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::acceltext, accelText, aNotify);
   ENSURE_TRUE(weakFrame.IsAlive());
 
   mIgnoreAccelTextChange = false;
 }
 
 void
 nsMenuFrame::Execute(WidgetGUIEvent* aEvent)
 {
@@ -1229,17 +1226,17 @@ nsMenuFrame::StartBlinking(WidgetGUIEven
 
   if (!ShouldBlink()) {
     PassMenuCommandEventToPopupManager();
     return;
   }
 
   // Blink off.
   AutoWeakFrame weakFrame(this);
-  mContent->AsElement()->UnsetAttr(kNameSpaceID_None, nsGkAtoms::menuactive, true);
+  mContent->UnsetAttr(kNameSpaceID_None, nsGkAtoms::menuactive, true);
   if (!weakFrame.IsAlive())
     return;
 
   nsMenuParent* menuParent = GetMenuParent();
   if (menuParent) {
     // Make this menu ignore events from now on.
     menuParent->LockMenuUntilClosed(true);
   }
@@ -1281,18 +1278,18 @@ nsMenuFrame::CreateMenuCommandEvent(Widg
   }
 
   // Because the command event is firing asynchronously, a flag is needed to
   // indicate whether user input is being handled. This ensures that a popup
   // window won't get blocked.
   bool userinput = EventStateManager::IsHandlingUserInput();
 
   mDelayedMenuCommandEvent =
-    new nsXULMenuCommandEvent(mContent->AsElement(), isTrusted, shift, control,
-                              alt, meta, userinput, aFlipChecked);
+    new nsXULMenuCommandEvent(mContent, isTrusted, shift, control, alt, meta,
+                              userinput, aFlipChecked);
 }
 
 void
 nsMenuFrame::PassMenuCommandEventToPopupManager()
 {
   nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
   nsMenuParent* menuParent = GetMenuParent();
   if (pm && menuParent && mDelayedMenuCommandEvent) {
--- a/layout/xul/nsMenuPopupFrame.cpp
+++ b/layout/xul/nsMenuPopupFrame.cpp
@@ -179,17 +179,17 @@ nsMenuPopupFrame::Init(nsIContent*      
   }
 
   if (aContent->NodeInfo()->Equals(nsGkAtoms::tooltip, kNameSpaceID_XUL) &&
       aContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::_default,
                             nsGkAtoms::_true, eIgnoreCase)) {
     nsIRootBox* rootBox =
       nsIRootBox::GetRootBox(PresContext()->GetPresShell());
     if (rootBox) {
-      rootBox->SetDefaultTooltip(aContent->AsElement());
+      rootBox->SetDefaultTooltip(aContent);
     }
   }
 
   AddStateBits(NS_FRAME_IN_POPUP);
 }
 
 bool
 nsMenuPopupFrame::HasRemoteContent() const
@@ -2342,17 +2342,17 @@ nsMenuPopupFrame::DestroyFrom(nsIFrame* 
     PresShell()->CancelReflowCallback(this);
     mReflowCallbackData.Clear();
   }
 
   nsMenuFrame* menu = do_QueryFrame(GetParent());
   if (menu) {
     // clear the open attribute on the parent menu
     nsContentUtils::AddScriptRunner(
-      new nsUnsetAttrRunnable(menu->GetContent()->AsElement(), nsGkAtoms::open));
+      new nsUnsetAttrRunnable(menu->GetContent(), nsGkAtoms::open));
   }
 
   ClearPopupShownDispatcher();
 
   nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
   if (pm)
     pm->PopupDestroyed(this);
 
@@ -2392,17 +2392,17 @@ nsMenuPopupFrame::MoveTo(const CSSIntPoi
 
   nsPresContext* presContext = PresContext();
   mAnchorType = MenuPopupAnchorType_Point;
   mScreenRect.x = aPos.x - presContext->AppUnitsToIntCSSPixels(margin.left);
   mScreenRect.y = aPos.y - presContext->AppUnitsToIntCSSPixels(margin.top);
 
   SetPopupPosition(nullptr, true, false, true);
 
-  RefPtr<Element> popup = mContent->AsElement();
+  nsCOMPtr<nsIContent> popup = mContent;
   if (aUpdateAttrs && (popup->HasAttr(kNameSpaceID_None, nsGkAtoms::left) ||
                        popup->HasAttr(kNameSpaceID_None, nsGkAtoms::top)))
   {
     nsAutoString left, top;
     left.AppendInt(aPos.x);
     top.AppendInt(aPos.y);
     popup->SetAttr(kNameSpaceID_None, nsGkAtoms::left, left, false);
     popup->SetAttr(kNameSpaceID_None, nsGkAtoms::top, top, false);
--- a/layout/xul/nsProgressMeterFrame.cpp
+++ b/layout/xul/nsProgressMeterFrame.cpp
@@ -134,21 +134,21 @@ nsProgressMeterFrame::AttributeChanged(i
 
   // did the progress change?
   bool undetermined = mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::mode,
                                             nsGkAtoms::undetermined, eCaseMatters);
   if (nsGkAtoms::mode == aAttribute ||
       (!undetermined &&
        (nsGkAtoms::value == aAttribute || nsGkAtoms::max == aAttribute))) {
     nsIFrame* barChild = PrincipalChildList().FirstChild();
-    if (!barChild || !barChild->GetContent()->IsElement()) return NS_OK;
+    if (!barChild) return NS_OK;
     nsIFrame* remainderChild = barChild->GetNextSibling();
     if (!remainderChild) return NS_OK;
     nsCOMPtr<nsIContent> remainderContent = remainderChild->GetContent();
-    if (!remainderContent->IsElement()) return NS_OK;
+    if (!remainderContent) return NS_OK;
 
     int32_t flex = 1, maxFlex = 1;
     if (!undetermined) {
       nsAutoString value, maxValue;
       mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::value, value);
       mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::max, maxValue);
 
       nsresult error;
@@ -164,19 +164,19 @@ nsProgressMeterFrame::AttributeChanged(i
         flex = 0;
       }
       if (flex > maxFlex) {
         flex = maxFlex;
       }
     }
 
     nsContentUtils::AddScriptRunner(new nsSetAttrRunnable(
-      barChild->GetContent()->AsElement(), nsGkAtoms::flex, flex));
+      barChild->GetContent(), nsGkAtoms::flex, flex));
     nsContentUtils::AddScriptRunner(new nsSetAttrRunnable(
-      remainderContent->AsElement(), nsGkAtoms::flex, maxFlex - flex));
+      remainderContent, nsGkAtoms::flex, maxFlex - flex));
     nsContentUtils::AddScriptRunner(new nsReflowFrameRunnable(
       this, nsIPresShell::eTreeChange, NS_FRAME_IS_DIRTY));
   }
   return NS_OK;
 }
 
 #ifdef DEBUG_FRAME_DUMP
 nsresult
--- a/layout/xul/nsResizerFrame.cpp
+++ b/layout/xul/nsResizerFrame.cpp
@@ -411,24 +411,23 @@ nsResizerFrame::ResizeContent(nsIContent
     if (aOriginalSizeInfo) {
       aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::width,
                         aOriginalSizeInfo->width);
       aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::height,
                         aOriginalSizeInfo->height);
     }
     // only set the property if the element could have changed in that direction
     if (aDirection.mHorizontal) {
-      aContent->AsElement()->SetAttr(kNameSpaceID_None, nsGkAtoms::width,
-                                     aSizeInfo.width, true);
+      aContent->SetAttr(kNameSpaceID_None, nsGkAtoms::width, aSizeInfo.width, true);
     }
     if (aDirection.mVertical) {
-      aContent->AsElement()->SetAttr(kNameSpaceID_None, nsGkAtoms::height,
-                                     aSizeInfo.height, true);
+      aContent->SetAttr(kNameSpaceID_None, nsGkAtoms::height, aSizeInfo.height, true);
     }
-  } else {
+  }
+  else {
     nsCOMPtr<nsStyledElement> inlineStyleContent =
       do_QueryInterface(aContent);
     if (inlineStyleContent) {
       nsICSSDeclaration* decl = inlineStyleContent->Style();
 
       if (aOriginalSizeInfo) {
         decl->GetPropertyValue(NS_LITERAL_STRING("width"),
                                aOriginalSizeInfo->width);
--- a/layout/xul/nsRootBoxFrame.cpp
+++ b/layout/xul/nsRootBoxFrame.cpp
@@ -50,18 +50,18 @@ public:
 
   explicit nsRootBoxFrame(nsStyleContext* aContext);
 
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS(nsRootBoxFrame)
 
   virtual nsPopupSetFrame* GetPopupSetFrame() override;
   virtual void SetPopupSetFrame(nsPopupSetFrame* aPopupSet) override;
-  virtual Element* GetDefaultTooltip() override;
-  virtual void SetDefaultTooltip(Element* aTooltip) override;
+  virtual nsIContent* GetDefaultTooltip() override;
+  virtual void SetDefaultTooltip(nsIContent* aTooltip) override;
   virtual nsresult AddTooltipSupport(nsIContent* aNode) override;
   virtual nsresult RemoveTooltipSupport(nsIContent* aNode) override;
 
   virtual void AppendFrames(ChildListID     aListID,
                             nsFrameList&    aFrameList) override;
   virtual void InsertFrames(ChildListID     aListID,
                             nsIFrame*       aPrevFrame,
                             nsFrameList&    aFrameList) override;
@@ -89,17 +89,17 @@ public:
 
 #ifdef DEBUG_FRAME_DUMP
   virtual nsresult GetFrameName(nsAString& aResult) const override;
 #endif
 
   nsPopupSetFrame* mPopupSetFrame;
 
 protected:
-  Element* mDefaultTooltip;
+  nsIContent* mDefaultTooltip;
 };
 
 //----------------------------------------------------------------------
 
 nsContainerFrame*
 NS_NewRootBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsRootBoxFrame(aContext);
@@ -226,24 +226,24 @@ nsRootBoxFrame::SetPopupSetFrame(nsPopup
   // element box frame is created.
   if (!mPopupSetFrame || !aPopupSet) {
     mPopupSetFrame = aPopupSet;
   } else {
     NS_NOTREACHED("Popup set is already defined! Only 1 allowed.");
   }
 }
 
-Element*
+nsIContent*
 nsRootBoxFrame::GetDefaultTooltip()
 {
   return mDefaultTooltip;
 }
 
 void
-nsRootBoxFrame::SetDefaultTooltip(Element* aTooltip)
+nsRootBoxFrame::SetDefaultTooltip(nsIContent* aTooltip)
 {
   mDefaultTooltip = aTooltip;
 }
 
 nsresult
 nsRootBoxFrame::AddTooltipSupport(nsIContent* aNode)
 {
   NS_ENSURE_TRUE(aNode, NS_ERROR_NULL_POINTER);
--- a/layout/xul/nsScrollbarButtonFrame.cpp
+++ b/layout/xul/nsScrollbarButtonFrame.cpp
@@ -113,32 +113,31 @@ nsScrollbarButtonFrame::HandleButtonPres
   GetParentWithTag(nsGkAtoms::scrollbar, this, scrollbar);
 
   if (scrollbar == nullptr)
     return false;
 
   static nsIContent::AttrValuesArray strings[] = { &nsGkAtoms::increment,
                                                    &nsGkAtoms::decrement,
                                                    nullptr };
-  int32_t index = mContent->AsElement()->FindAttrValueIn(kNameSpaceID_None,
-                                                         nsGkAtoms::type,
-                                                         strings, eCaseMatters);
+  int32_t index = mContent->FindAttrValueIn(kNameSpaceID_None,
+                                            nsGkAtoms::type,
+                                            strings, eCaseMatters);
   int32_t direction;
   if (index == 0)
     direction = 1;
   else if (index == 1)
     direction = -1;
   else
     return false;
 
   bool repeat = pressedButtonAction != 2;
   // set this attribute so we can style it later
   AutoWeakFrame weakFrame(this);
-  mContent->AsElement()->SetAttr(kNameSpaceID_None, nsGkAtoms::active,
-                                 NS_LITERAL_STRING("true"), true);
+  mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::active, NS_LITERAL_STRING("true"), true);
 
   nsIPresShell::SetCapturingContent(mContent, CAPTURE_IGNOREALLOWED);
 
   if (!weakFrame.IsAlive()) {
     return false;
   }
 
   nsScrollbarFrame* sb = do_QueryFrame(scrollbar);
@@ -191,17 +190,17 @@ nsScrollbarButtonFrame::HandleButtonPres
 
 NS_IMETHODIMP
 nsScrollbarButtonFrame::HandleRelease(nsPresContext* aPresContext,
                                       WidgetGUIEvent* aEvent,
                                       nsEventStatus* aEventStatus)
 {
   nsIPresShell::SetCapturingContent(nullptr, 0);
   // we're not active anymore
-  mContent->AsElement()->UnsetAttr(kNameSpaceID_None, nsGkAtoms::active, true);
+  mContent->UnsetAttr(kNameSpaceID_None, nsGkAtoms::active, true);
   StopRepeat();
   nsIFrame* scrollbar;
   GetParentWithTag(nsGkAtoms::scrollbar, this, scrollbar);
   nsScrollbarFrame* sb = do_QueryFrame(scrollbar);
   if (sb) {
     nsIScrollbarMediator* m = sb->GetScrollbarMediator();
     if (m) {
       m->ScrollbarReleased(sb);
--- a/layout/xul/nsScrollbarFrame.cpp
+++ b/layout/xul/nsScrollbarFrame.cpp
@@ -232,17 +232,17 @@ nsScrollbarFrame::SetIncrementToWhole(in
   // of a page.
   mSmoothScroll = false;
 }
 
 int32_t
 nsScrollbarFrame::MoveToNewPosition()
 {
   // get the scrollbar's content node
-  RefPtr<Element> content = GetContent()->AsElement();
+  nsCOMPtr<nsIContent> content = GetContent();
 
   // get the current pos
   int32_t curpos = nsSliderFrame::GetCurrentPosition(content);
 
   // get the max pos
   int32_t maxpos = nsSliderFrame::GetMaxPosition(content);
 
   // increment the given amount
--- a/layout/xul/nsSliderFrame.cpp
+++ b/layout/xul/nsSliderFrame.cpp
@@ -258,17 +258,18 @@ nsSliderFrame::AttributeChanged(int32_t 
   // if the current position changes
   if (aAttribute == nsGkAtoms::curpos) {
      CurrentPositionChanged();
   } else if (aAttribute == nsGkAtoms::minpos ||
              aAttribute == nsGkAtoms::maxpos) {
       // bounds check it.
 
       nsIFrame* scrollbarBox = GetScrollbar();
-      nsCOMPtr<nsIContent> scrollbar = GetContentOfBox(scrollbarBox);
+      nsCOMPtr<nsIContent> scrollbar;
+      scrollbar = GetContentOfBox(scrollbarBox);
       int32_t current = GetCurrentPosition(scrollbar);
       int32_t min = GetMinPosition(scrollbar);
       int32_t max = GetMaxPosition(scrollbar);
 
       // inform the parent <scale> that the minimum or maximum changed
       nsIFrame* parent = GetParent();
       if (parent) {
         nsCOMPtr<nsISliderListener> sliderListener = do_QueryInterface(parent->GetContent());
@@ -298,17 +299,17 @@ nsSliderFrame::AttributeChanged(int32_t 
           if (mediator) {
             mediator->ScrollByWhole(scrollbarFrame, direction,
                                     nsIScrollbarMediator::ENABLE_SNAP);
           }
         }
         // 'this' might be destroyed here
 
         nsContentUtils::AddScriptRunner(
-          new nsSetAttrRunnable(scrollbar->AsElement(), nsGkAtoms::curpos, current));
+          new nsSetAttrRunnable(scrollbar, nsGkAtoms::curpos, current));
       }
   }
 
   if (aAttribute == nsGkAtoms::minpos ||
       aAttribute == nsGkAtoms::maxpos ||
       aAttribute == nsGkAtoms::pageincrement ||
       aAttribute == nsGkAtoms::increment) {
 
@@ -499,17 +500,18 @@ nsSliderFrame::DoXULLayout(nsBoxLayoutSt
 #endif
 
   // get the content area inside our borders
   nsRect clientRect;
   GetXULClientRect(clientRect);
 
   // get the scrollbar
   nsIFrame* scrollbarBox = GetScrollbar();
-  nsCOMPtr<nsIContent> scrollbar = GetContentOfBox(scrollbarBox);
+  nsCOMPtr<nsIContent> scrollbar;
+  scrollbar = GetContentOfBox(scrollbarBox);
 
   // get the thumb's pref size
   nsSize thumbSize = thumbBox->GetXULPrefSize(aState);
 
   if (IsXULHorizontal())
     thumbSize.height = clientRect.height;
   else
     thumbSize.width = clientRect.width;
@@ -695,17 +697,17 @@ nsSliderFrame::HandleEvent(nsPresContext
     AutoWeakFrame weakFrame(this);
     // should aMaySnap be true here?
     SetCurrentThumbPosition(scrollbar, pos - thumbLength/2, false, false);
     NS_ENSURE_TRUE(weakFrame.IsAlive(), NS_OK);
 
     DragThumb(true);
 
 #ifdef MOZ_WIDGET_GTK
-    RefPtr<Element> thumb = thumbFrame->GetContent()->AsElement();
+    nsCOMPtr<nsIContent> thumb = thumbFrame->GetContent();
     thumb->SetAttr(kNameSpaceID_None, nsGkAtoms::active, NS_LITERAL_STRING("true"), true);
 #endif
 
     if (aEvent->mClass == eTouchEventClass) {
       *aEventStatus = nsEventStatus_eConsumeNoDefault;
     }
 
     if (isHorizontal)
@@ -809,17 +811,18 @@ nsSliderFrame::PageUpDown(nscoord change
   SetCurrentPositionInternal(scrollbar, newpos, true);
 }
 
 // called when the current position changed and we need to update the thumb's location
 void
 nsSliderFrame::CurrentPositionChanged()
 {
   nsIFrame* scrollbarBox = GetScrollbar();
-  nsCOMPtr<nsIContent> scrollbar = GetContentOfBox(scrollbarBox);
+  nsCOMPtr<nsIContent> scrollbar;
+  scrollbar = GetContentOfBox(scrollbarBox);
 
   // get the current position
   int32_t curPos = GetCurrentPosition(scrollbar);
 
   // do nothing if the position did not change
   if (mCurPos == curPos)
     return;
 
@@ -882,17 +885,17 @@ nsSliderFrame::CurrentPositionChanged()
     nsCOMPtr<nsISliderListener> sliderListener = do_QueryInterface(parent->GetContent());
     if (sliderListener) {
       nsContentUtils::AddScriptRunner(
         new nsValueChangedRunnable(sliderListener, nsGkAtoms::curpos, mCurPos, mUserChanged));
     }
   }
 }
 
-static void UpdateAttribute(Element* aScrollbar, nscoord aNewPos, bool aNotify, bool aIsSmooth) {
+static void UpdateAttribute(nsIContent* aScrollbar, nscoord aNewPos, bool aNotify, bool aIsSmooth) {
   nsAutoString str;
   str.AppendInt(aNewPos);
 
   if (aIsSmooth) {
     aScrollbar->SetAttr(kNameSpaceID_None, nsGkAtoms::smooth, NS_LITERAL_STRING("true"), false);
   }
   aScrollbar->SetAttr(kNameSpaceID_None, nsGkAtoms::curpos, str, aNotify);
   if (aIsSmooth) {
@@ -968,24 +971,24 @@ nsSliderFrame::SetCurrentPositionInterna
     nsIScrollbarMediator* mediator = scrollbarFrame->GetScrollbarMediator();
     if (mediator) {
       nscoord oldPos = nsPresContext::CSSPixelsToAppUnits(GetCurrentPosition(scrollbar));
       nscoord newPos = nsPresContext::CSSPixelsToAppUnits(aNewPos);
       mediator->ThumbMoved(scrollbarFrame, oldPos, newPos);
       if (!weakFrame.IsAlive()) {
         return;
       }
-      UpdateAttribute(scrollbar->AsElement(), aNewPos, /* aNotify */false, aIsSmooth);
+      UpdateAttribute(scrollbar, aNewPos, /* aNotify */false, aIsSmooth);
       CurrentPositionChanged();
       mUserChanged = false;
       return;
     }
   }
 
-  UpdateAttribute(scrollbar->AsElement(), aNewPos, true, aIsSmooth);
+  UpdateAttribute(scrollbar, aNewPos, true, aIsSmooth);
   if (!weakFrame.IsAlive()) {
     return;
   }
   mUserChanged = false;
 
 #ifdef DEBUG_SLIDER
   printf("Current Pos=%d\n",aNewPos);
 #endif
@@ -1213,17 +1216,17 @@ nsSliderFrame::StartDrag(nsIDOMEvent* aE
   }
 
   nsIFrame* thumbFrame = mFrames.FirstChild();
   if (!thumbFrame) {
     return NS_OK;
   }
 
 #ifdef MOZ_WIDGET_GTK
-  RefPtr<Element> thumb = thumbFrame->GetContent()->AsElement();
+  nsCOMPtr<nsIContent> thumb = thumbFrame->GetContent();
   thumb->SetAttr(kNameSpaceID_None, nsGkAtoms::active, NS_LITERAL_STRING("true"), true);
 #endif
 
   if (isHorizontal)
     mThumbStart = thumbFrame->GetPosition().x;
   else
     mThumbStart = thumbFrame->GetPosition().y;
 
@@ -1251,17 +1254,17 @@ nsSliderFrame::StopDrag()
 
   mScrollingWithAPZ = false;
 
   UnsuppressDisplayport();
 
 #ifdef MOZ_WIDGET_GTK
   nsIFrame* thumbFrame = mFrames.FirstChild();
   if (thumbFrame) {
-    RefPtr<Element> thumb = thumbFrame->GetContent()->AsElement();
+    nsCOMPtr<nsIContent> thumb = thumbFrame->GetContent();
     thumb->UnsetAttr(kNameSpaceID_None, nsGkAtoms::active, true);
   }
 #endif
 
   if (mChange) {
     StopRepeat();
     mChange = 0;
   }
--- a/layout/xul/nsSplitterFrame.cpp
+++ b/layout/xul/nsSplitterFrame.cpp
@@ -279,18 +279,18 @@ nsSplitterFrame::Init(nsIContent*       
   // determine orientation of parent, and if vertical, set orient to vertical
   // on splitter content, then re-resolve style
   // XXXbz this is pretty messed up, since this can change whether we should
   // have a frame at all.  This really needs a better solution.
   if (aParent && aParent->IsXULBoxFrame()) {
     if (!aParent->IsXULHorizontal()) {
       if (!nsContentUtils::HasNonEmptyAttr(aContent, kNameSpaceID_None,
                                            nsGkAtoms::orient)) {
-        aContent->AsElement()->SetAttr(kNameSpaceID_None, nsGkAtoms::orient,
-                                       NS_LITERAL_STRING("vertical"), false);
+        aContent->SetAttr(kNameSpaceID_None, nsGkAtoms::orient,
+                          NS_LITERAL_STRING("vertical"), false);
         if (StyleContext()->IsGecko()) {
           // FIXME(emilio): Even if we did this in Servo, this just won't
           // work, and we'd need a specific "really re-resolve the style" API...
           GeckoStyleContext* parentStyleContext =
             StyleContext()->AsGecko()->GetParent();
           RefPtr<nsStyleContext> newContext = PresContext()->StyleSet()->
             ResolveStyleFor(aContent->AsElement(), parentStyleContext,
                             LazyComputeBehavior::Allow);
@@ -417,21 +417,18 @@ nsSplitterFrameInner::MouseUp(nsPresCont
 {
   if (mDragging && mOuter) {
     AdjustChildren(aPresContext);
     AddListener();
     nsIPresShell::SetCapturingContent(nullptr, 0); // XXXndeakin is this needed?
     mDragging = false;
     State newState = GetState();
     // if the state is dragging then make it Open.
-    if (newState == Dragging) {
-      mOuter->mContent->AsElement()->SetAttr(kNameSpaceID_None,
-                                             nsGkAtoms::state, EmptyString(),
-                                             true);
-    }
+    if (newState == Dragging)
+      mOuter->mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::state, EmptyString(), true);
 
     mPressed = false;
 
     // if we dragged then fire a command event.
     if (mDidDrag) {
       RefPtr<nsXULElement> element =
         nsXULElement::FromContent(mOuter->GetContent());
       element->DoCommand();
@@ -511,49 +508,45 @@ nsSplitterFrameInner::MouseDrag(nsPresCo
     {
       // and we are not collapsed then collapse
       if (currentState == Dragging) {
         if (pastEnd)
         {
           //printf("Collapse right\n");
           if (supportsAfter)
           {
-            RefPtr<Element> outer = mOuter->mContent->AsElement();
+            nsCOMPtr<nsIContent> outer = mOuter->mContent;
             outer->SetAttr(kNameSpaceID_None, nsGkAtoms::substate,
                            NS_LITERAL_STRING("after"),
                            true);
             outer->SetAttr(kNameSpaceID_None, nsGkAtoms::state,
                            NS_LITERAL_STRING("collapsed"),
                            true);
           }
 
         } else if (pastBegin)
         {
           //printf("Collapse left\n");
           if (supportsBefore)
           {
-            RefPtr<Element> outer = mOuter->mContent->AsElement();
+            nsCOMPtr<nsIContent> outer = mOuter->mContent;
             outer->SetAttr(kNameSpaceID_None, nsGkAtoms::substate,
                            NS_LITERAL_STRING("before"),
                            true);
             outer->SetAttr(kNameSpaceID_None, nsGkAtoms::state,
                            NS_LITERAL_STRING("collapsed"),
                            true);
           }
         }
       }
     } else {
       // if we are not in a collapsed position and we are not dragging make sure
       // we are dragging.
-      if (currentState != Dragging) {
-        mOuter->mContent->AsElement()->SetAttr(kNameSpaceID_None,
-                                               nsGkAtoms::state,
-                                               NS_LITERAL_STRING("dragging"),
-                                               true);
-      }
+      if (currentState != Dragging)
+        mOuter->mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::state, NS_LITERAL_STRING("dragging"), true);
       AdjustChildren(aPresContext);
     }
 
     mDidDrag = true;
   }
 }
 
 void
@@ -695,21 +688,20 @@ nsSplitterFrameInner::MouseDown(nsIDOMEv
 
         nsMargin margin(0,0,0,0);
         childBox->GetXULMargin(margin);
         nsRect r(childBox->GetRect());
         r.Inflate(margin);
 
         // We need to check for hidden attribute too, since treecols with
         // the hidden="true" attribute are not really hidden, just collapsed
-        if (!content->IsElement() ||
-            (!content->AttrValueIs(kNameSpaceID_None, nsGkAtoms::fixed,
-                                   nsGkAtoms::_true, eCaseMatters) &&
-             !content->AttrValueIs(kNameSpaceID_None, nsGkAtoms::hidden,
-                                   nsGkAtoms::_true, eCaseMatters))) {
+        if (!content->AttrValueIs(kNameSpaceID_None, nsGkAtoms::fixed,
+                                  nsGkAtoms::_true, eCaseMatters) &&
+            !content->AttrValueIs(kNameSpaceID_None, nsGkAtoms::hidden,
+                                  nsGkAtoms::_true, eCaseMatters)) {
             if (count < childIndex && (resizeBefore != Flex || flex > 0)) {
                 mChildInfosBefore[mChildInfosBeforeCount].childElem = content;
                 mChildInfosBefore[mChildInfosBeforeCount].min     = isHorizontal ? minSize.width : minSize.height;
                 mChildInfosBefore[mChildInfosBeforeCount].max     = isHorizontal ? maxSize.width : maxSize.height;
                 mChildInfosBefore[mChildInfosBeforeCount].current = isHorizontal ? r.width : r.height;
                 mChildInfosBefore[mChildInfosBeforeCount].flex    = flex;
                 mChildInfosBefore[mChildInfosBeforeCount].index   = count;
                 mChildInfosBefore[mChildInfosBeforeCount].changed = mChildInfosBefore[mChildInfosBeforeCount].current;
@@ -783,18 +775,18 @@ nsSplitterFrameInner::MouseMove(nsIDOMEv
   NS_ENSURE_TRUE(mOuter, NS_OK);
   if (!mPressed)
     return NS_OK;
 
   if (mDragging)
     return NS_OK;
 
   nsCOMPtr<nsIDOMEventListener> kungfuDeathGrip(this);
-  mOuter->mContent->AsElement()->SetAttr(kNameSpaceID_None, nsGkAtoms::state,
-                                         NS_LITERAL_STRING("dragging"), true);
+  mOuter->mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::state,
+                            NS_LITERAL_STRING("dragging"), true);
 
   RemoveListener();
   mDragging = true;
 
   return NS_OK;
 }
 
 void
@@ -860,31 +852,31 @@ nsSplitterFrameInner::UpdateState()
     if (newState == CollapsedBefore || mState == CollapsedBefore) {
       splitterSibling = mOuter->GetPrevSibling();
     } else {
       splitterSibling = mOuter->GetNextSibling();
     }
 
     if (splitterSibling) {
       nsCOMPtr<nsIContent> sibling = splitterSibling->GetContent();
-      if (sibling && sibling->IsElement()) {
+      if (sibling) {
         if (mState == CollapsedBefore || mState == CollapsedAfter) {
           // CollapsedBefore -> Open
           // CollapsedBefore -> Dragging
           // CollapsedAfter -> Open
           // CollapsedAfter -> Dragging
           nsContentUtils::AddScriptRunner(
-            new nsUnsetAttrRunnable(sibling->AsElement(), nsGkAtoms::collapsed));
+            new nsUnsetAttrRunnable(sibling, nsGkAtoms::collapsed));
         } else if ((mState == Open || mState == Dragging)
                    && (newState == CollapsedBefore ||
                        newState == CollapsedAfter)) {
           // Open -> CollapsedBefore / CollapsedAfter
           // Dragging -> CollapsedBefore / CollapsedAfter
           nsContentUtils::AddScriptRunner(
-            new nsSetAttrRunnable(sibling->AsElement(), nsGkAtoms::collapsed,
+            new nsSetAttrRunnable(sibling, nsGkAtoms::collapsed,
                                   NS_LITERAL_STRING("true")));
         }
       }
     }
   }
   mState = newState;
 }
 
@@ -977,30 +969,26 @@ nsSplitterFrameInner::SetPreferredSize(n
     pref -= (margin.left + margin.right);
     attribute = nsGkAtoms::width;
   } else {
     pref -= (margin.top + margin.bottom);
     attribute = nsGkAtoms::height;
   }
 
   nsIContent* content = aChildBox->GetContent();
-  if (!content->IsElement()) {
-    return;
-  }
 
   // set its preferred size.
   nsAutoString prefValue;
   prefValue.AppendInt(pref/aOnePixel);
   if (content->AttrValueIs(kNameSpaceID_None, attribute,
-                           prefValue, eCaseMatters)) {
+                           prefValue, eCaseMatters))
      return;
-  }
 
   AutoWeakFrame weakBox(aChildBox);
-  content->AsElement()->SetAttr(kNameSpaceID_None, attribute, prefValue, true);
+  content->SetAttr(kNameSpaceID_None, attribute, prefValue, true);
   ENSURE_TRUE(weakBox.IsAlive());
   aState.PresShell()->FrameNeedsReflow(aChildBox, nsIPresShell::eStyleChange,
                                        NS_FRAME_IS_DIRTY);
 }
 
 
 void
 nsSplitterFrameInner::AddRemoveSpace(nscoord aDiff,
--- a/layout/xul/nsXULPopupManager.cpp
+++ b/layout/xul/nsXULPopupManager.cpp
@@ -543,17 +543,17 @@ nsXULPopupManager::PopupResized(nsIFrame
   if (!view)
     return;
 
   LayoutDeviceIntRect curDevSize = view->CalcWidgetBounds(eWindowType_popup);
   // If the size is what we think it is, we have nothing to do.
   if (curDevSize.width == aSize.width && curDevSize.height == aSize.height)
     return;
 
-  Element* popup = menuPopupFrame->GetContent()->AsElement();
+  nsIContent* popup = menuPopupFrame->GetContent();
 
   // Only set the width and height if the popup already has these attributes.
   if (!popup->HasAttr(kNameSpaceID_None, nsGkAtoms::width) ||
       !popup->HasAttr(kNameSpaceID_None, nsGkAtoms::height)) {
     return;
   }
 
   // The size is different. Convert the actual size to css pixels and store it
@@ -705,17 +705,17 @@ nsXULPopupManager::ShowMenu(nsIContent *
   // have been created yet.
   if (aMenu) {
     nsIContent* element = aMenu;
     do {
       RefPtr<nsXULElement> xulelem = nsXULElement::FromContent(element);
       if (xulelem) {
         nsCOMPtr<nsIXULTemplateBuilder> builder = xulelem->GetBuilder();
         if (builder) {
-          builder->CreateContents(aMenu->AsElement(), true);
+          builder->CreateContents(aMenu, true);
           break;
         }
       }
       element = element->GetParent();
     } while (element);
   }
 
   nsMenuFrame* menuFrame = do_QueryFrame(aMenu->GetPrimaryFrame());
@@ -1994,45 +1994,44 @@ nsXULPopupManager::UpdateMenuItems(nsICo
     if (grandChild->IsXULElement(nsGkAtoms::menugroup)) {
       if (grandChild->GetChildCount() == 0) {
         continue;
       }
       grandChild = grandChild->GetFirstChild();
     }
     if (grandChild->IsXULElement(nsGkAtoms::menuitem)) {
       // See if we have a command attribute.
-      Element* grandChildElement = grandChild->AsElement();
       nsAutoString command;
-      grandChildElement->GetAttr(kNameSpaceID_None, nsGkAtoms::command, command);
+      grandChild->GetAttr(kNameSpaceID_None, nsGkAtoms::command, command);
       if (!command.IsEmpty()) {
         // We do! Look it up in our document
         RefPtr<dom::Element> commandElement =
           document->GetElementById(command);
         if (commandElement) {
           nsAutoString commandValue;
           // The menu's disabled state needs to be updated to match the command.
           if (commandElement->GetAttr(kNameSpaceID_None, nsGkAtoms::disabled, commandValue))
-            grandChildElement->SetAttr(kNameSpaceID_None, nsGkAtoms::disabled, commandValue, true);
+            grandChild->SetAttr(kNameSpaceID_None, nsGkAtoms::disabled, commandValue, true);
           else
-            grandChildElement->UnsetAttr(kNameSpaceID_None, nsGkAtoms::disabled, true);
+            grandChild->UnsetAttr(kNameSpaceID_None, nsGkAtoms::disabled, true);
 
           // The menu's label, accesskey checked and hidden states need to be updated
           // to match the command. Note that unlike the disabled state if the
           // command has *no* value, we assume the menu is supplying its own.
           if (commandElement->GetAttr(kNameSpaceID_None, nsGkAtoms::label, commandValue))
-            grandChildElement->SetAttr(kNameSpaceID_None, nsGkAtoms::label, commandValue, true);
+            grandChild->SetAttr(kNameSpaceID_None, nsGkAtoms::label, commandValue, true);
 
           if (commandElement->GetAttr(kNameSpaceID_None, nsGkAtoms::accesskey, commandValue))
-            grandChildElement->SetAttr(kNameSpaceID_None, nsGkAtoms::accesskey, commandValue, true);
+            grandChild->SetAttr(kNameSpaceID_None, nsGkAtoms::accesskey, commandValue, true);
 
           if (commandElement->GetAttr(kNameSpaceID_None, nsGkAtoms::checked, commandValue))
-            grandChildElement->SetAttr(kNameSpaceID_None, nsGkAtoms::checked, commandValue, true);
+            grandChild->SetAttr(kNameSpaceID_None, nsGkAtoms::checked, commandValue, true);
 
           if (commandElement->GetAttr(kNameSpaceID_None, nsGkAtoms::hidden, commandValue))
-            grandChildElement->SetAttr(kNameSpaceID_None, nsGkAtoms::hidden, commandValue, true);
+            grandChild->SetAttr(kNameSpaceID_None, nsGkAtoms::hidden, commandValue, true);
         }
       }
     }
     if (!grandChild->GetNextSibling() &&
         grandChild->GetParent()->IsXULElement(nsGkAtoms::menugroup)) {
       grandChild = grandChild->GetParent();
     }
   }
--- a/layout/xul/nsXULPopupManager.h
+++ b/layout/xul/nsXULPopupManager.h
@@ -284,17 +284,17 @@ private:
   bool mIsContextMenu;
   bool mSelectFirstItem;
 };
 
 // this class is used for dispatching menu command events asynchronously.
 class nsXULMenuCommandEvent : public mozilla::Runnable
 {
 public:
-  nsXULMenuCommandEvent(mozilla::dom::Element* aMenu,
+  nsXULMenuCommandEvent(nsIContent* aMenu,
                         bool aIsTrusted,
                         bool aShift,
                         bool aControl,
                         bool aAlt,
                         bool aMeta,
                         bool aUserInput,
                         bool aFlipChecked)
     : mozilla::Runnable("nsXULMenuCommandEvent")
@@ -311,17 +311,17 @@ public:
     NS_ASSERTION(aMenu, "null menu supplied to nsXULMenuCommandEvent constructor");
   }
 
   NS_IMETHOD Run() override;
 
   void SetCloseMenuMode(CloseMenuMode aCloseMenuMode) { mCloseMenuMode = aCloseMenuMode; }
 
 private:
-  RefPtr<mozilla::dom::Element> mMenu;
+  nsCOMPtr<nsIContent> mMenu;
   bool mIsTrusted;
   bool mShift;
   bool mControl;
   bool mAlt;
   bool mMeta;
   bool mUserInput;
   bool mFlipChecked;
   CloseMenuMode mCloseMenuMode;
--- a/layout/xul/nsXULTooltipListener.cpp
+++ b/layout/xul/nsXULTooltipListener.cpp
@@ -472,17 +472,17 @@ GetTreeCellCoords(nsITreeBoxObject* aTre
   bx->GetX(&myX);
   bx->GetY(&myY);
   *aX += myX;
   *aY += myY;
 }
 #endif
 
 static void
-SetTitletipLabel(nsITreeBoxObject* aTreeBox, Element* aTooltip,
+SetTitletipLabel(nsITreeBoxObject* aTreeBox, nsIContent* aTooltip,
                  int32_t aRow, nsITreeColumn* aCol)
 {
   nsCOMPtr<nsITreeView> view;
   aTreeBox->GetView(getter_AddRefs(view));
   if (view) {
     nsAutoString label;
 #ifdef DEBUG
     nsresult rv =
@@ -492,17 +492,17 @@ SetTitletipLabel(nsITreeBoxObject* aTree
     aTooltip->SetAttr(kNameSpaceID_None, nsGkAtoms::label, label, true);
   }
 }
 #endif
 
 void
 nsXULTooltipListener::LaunchTooltip()
 {
-  nsCOMPtr<Element> currentTooltip = do_QueryReferent(mCurrentTooltip);
+  nsCOMPtr<nsIContent> currentTooltip = do_QueryReferent(mCurrentTooltip);
   if (!currentTooltip)
     return;
 
 #ifdef MOZ_XUL
   if (mIsSourceTree && mNeedTitletip) {
     nsCOMPtr<nsITreeBoxObject> obx;
     GetSourceTreeBoxObject(getter_AddRefs(obx));
 
@@ -587,19 +587,20 @@ nsXULTooltipListener::FindTooltip(nsICon
   }
 
   nsAutoString tooltipText;
   aTarget->GetAttr(kNameSpaceID_None, nsGkAtoms::tooltiptext, tooltipText);
   if (!tooltipText.IsEmpty()) {
     // specifying tooltiptext means we will always use the default tooltip
     nsIRootBox* rootBox = nsIRootBox::GetRootBox(document->GetShell());
     NS_ENSURE_STATE(rootBox);
-    if (RefPtr<Element> tooltip = rootBox->GetDefaultTooltip()) {
-      tooltip->SetAttr(kNameSpaceID_None, nsGkAtoms::label, tooltipText, true);
-      tooltip.forget(aTooltip);
+    *aTooltip = rootBox->GetDefaultTooltip();
+    if (*aTooltip) {
+      NS_ADDREF(*aTooltip);
+      (*aTooltip)->SetAttr(kNameSpaceID_None, nsGkAtoms::label, tooltipText, true);
     }
     return NS_OK;
   }
 
   nsAutoString tooltipId;
   aTarget->GetAttr(kNameSpaceID_None, nsGkAtoms::tooltip, tooltipId);
 
   // if tooltip == _child, look for first <tooltip> child
--- a/layout/xul/tree/nsTreeBodyFrame.cpp
+++ b/layout/xul/tree/nsTreeBodyFrame.cpp
@@ -831,22 +831,22 @@ nsTreeBodyFrame::ScrollParts nsTreeBodyF
     baseElement ? baseElement->GetPrimaryFrame() : nullptr;
   if (treeFrame) {
     // The way we do this, searching through the entire frame subtree, is pretty
     // dumb! We should know where these frames are.
     FindScrollParts(treeFrame, &result);
     if (result.mHScrollbar) {
       result.mHScrollbar->SetScrollbarMediatorContent(GetContent());
       nsIFrame* f = do_QueryFrame(result.mHScrollbar);
-      result.mHScrollbarContent = f->GetContent()->AsElement();
+      result.mHScrollbarContent = f->GetContent();
     }
     if (result.mVScrollbar) {
       result.mVScrollbar->SetScrollbarMediatorContent(GetContent());
       nsIFrame* f = do_QueryFrame(result.mVScrollbar);
-      result.mVScrollbarContent = f->GetContent()->AsElement();
+      result.mVScrollbarContent = f->GetContent();
     }
   }
   return result;
 }
 
 void
 nsTreeBodyFrame::UpdateScrollbars(const ScrollParts& aParts)
 {
--- a/layout/xul/tree/nsTreeBodyFrame.h
+++ b/layout/xul/tree/nsTreeBodyFrame.h
@@ -178,19 +178,19 @@ public:
 
   virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) override;
 
   friend nsIFrame* NS_NewTreeBodyFrame(nsIPresShell* aPresShell);
   friend class nsTreeColumn;
 
   struct ScrollParts {
     nsScrollbarFrame*    mVScrollbar;
-    RefPtr<Element>      mVScrollbarContent;
+    nsCOMPtr<nsIContent> mVScrollbarContent;
     nsScrollbarFrame*    mHScrollbar;
-    RefPtr<Element>      mHScrollbarContent;
+    nsCOMPtr<nsIContent> mHScrollbarContent;
     nsIFrame*            mColumnsFrame;
     nsIScrollableFrame*  mColumnsScrollFrame;
   };
 
   DrawResult PaintTreeBody(gfxContext& aRenderingContext,
                            const nsRect& aDirtyRect, nsPoint aPt,
                            nsDisplayListBuilder* aBuilder);
 
--- a/layout/xul/tree/nsTreeColumns.cpp
+++ b/layout/xul/tree/nsTreeColumns.cpp
@@ -268,17 +268,17 @@ nsTreeColumn::Invalidate()
   mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::id, mId);
 
   // If we have an Id, cache the Id as an atom.
   if (!mId.IsEmpty()) {
     mAtom = NS_Atomize(mId);
   }
 
   // Cache our index.
-  nsTreeUtils::GetColumnIndex(mContent->AsElement(), &mIndex);
+  nsTreeUtils::GetColumnIndex(mContent, &mIndex);
 
   const nsStyleVisibility* vis = frame->StyleVisibility();
 
   // Cache our text alignment policy.
   const nsStyleText* textStyle = frame->StyleText();
 
   mTextAlignment = textStyle->mTextAlign;
   // START or END alignment sometimes means RIGHT
@@ -674,20 +674,17 @@ nsTreeColumns::RestoreNaturalOrder()
     nsTreeUtils::GetImmediateChild(content, nsGkAtoms::treecols);
   if (!colsContent)
     return NS_OK;
 
   for (uint32_t i = 0; i < colsContent->GetChildCount(); ++i) {
     nsCOMPtr<nsIContent> child = colsContent->GetChildAt(i);
     nsAutoString ordinal;
     ordinal.AppendInt(i);
-    if (child->IsElement()) {
-      child->AsElement()->SetAttr(kNameSpaceID_None, nsGkAtoms::ordinal, ordinal,
-                                  true);
-    }
+    child->SetAttr(kNameSpaceID_None, nsGkAtoms::ordinal, ordinal, true);
   }
 
   nsTreeColumns::InvalidateColumns();
 
   if (mTree) {
     mTree->Invalidate();
   }
   return NS_OK;
--- a/layout/xul/tree/nsTreeContentView.cpp
+++ b/layout/xul/tree/nsTreeContentView.cpp
@@ -822,17 +822,17 @@ nsTreeContentView::SetCellValue(int32_t 
     return;
   }
 
   Row* row = mRows[aRow].get();
 
   nsIContent* realRow =
     nsTreeUtils::GetImmediateChild(row->mContent, nsGkAtoms::treerow);
   if (realRow) {
-    Element* cell = GetCell(realRow, aColumn);
+    nsIContent* cell = GetCell(realRow, aColumn);
     if (cell)
       cell->SetAttr(kNameSpaceID_None, nsGkAtoms::value, aValue, true);
   }
 }
 
 NS_IMETHODIMP
 nsTreeContentView::SetCellValue(int32_t aRow, nsITreeColumn* aCol, const nsAString& aValue)
 {
@@ -853,17 +853,17 @@ nsTreeContentView::SetCellText(int32_t a
     return;
   }
 
   Row* row = mRows[aRow].get();
 
   nsIContent* realRow =
     nsTreeUtils::GetImmediateChild(row->mContent, nsGkAtoms::treerow);
   if (realRow) {
-    Element* cell = GetCell(realRow, aColumn);
+    nsIContent* cell = GetCell(realRow, aColumn);
     if (cell)
       cell->SetAttr(kNameSpaceID_None, nsGkAtoms::label, aValue, true);
   }
 }
 
 NS_IMETHODIMP
 nsTreeContentView::SetCellText(int32_t aRow, nsITreeColumn* aCol, const nsAString& aValue)
 {
@@ -1560,36 +1560,36 @@ nsTreeContentView::UpdateParentIndexes(i
   for (int32_t i = aIndex + aSkip; i < count; i++) {
     Row* row = mRows[i].get();
     if (row->mParentIndex > aIndex) {
       row->mParentIndex += aCount;
     }
   }
 }
 
-Element*
+nsIContent*
 nsTreeContentView::GetCell(nsIContent* aContainer, nsTreeColumn& aCol)
 {
   RefPtr<nsAtom> colAtom(aCol.GetAtom());
   int32_t colIndex(aCol.GetIndex());
 
   // Traverse through cells, try to find the cell by "ref" attribute or by cell
   // index in a row. "ref" attribute has higher priority.
-  Element* result = nullptr;
+  nsIContent* result = nullptr;
   int32_t j = 0;
   dom::FlattenedChildIterator iter(aContainer);
   for (nsIContent* cell = iter.GetNextChild(); cell; cell = iter.GetNextChild()) {
     if (cell->IsXULElement(nsGkAtoms::treecell)) {
       if (colAtom && cell->AttrValueIs(kNameSpaceID_None, nsGkAtoms::ref,
                                        colAtom, eCaseMatters)) {
-        result = cell->AsElement();
+        result = cell;
         break;
       }
       else if (j == colIndex) {
-        result = cell->AsElement();
+        result = cell;
       }
       j++;
     }
   }
 
   return result;
 }
 
--- a/layout/xul/tree/nsTreeContentView.h
+++ b/layout/xul/tree/nsTreeContentView.h
@@ -167,17 +167,17 @@ class nsTreeContentView final : public n
 
     int32_t FindContent(nsIContent* aContent);
 
     void UpdateSubtreeSizes(int32_t aIndex, int32_t aCount);
 
     void UpdateParentIndexes(int32_t aIndex, int32_t aSkip, int32_t aCount);
 
     // Content helpers.
-    mozilla::dom::Element* GetCell(nsIContent* aContainer, nsTreeColumn& aCol);
+    nsIContent* GetCell(nsIContent* aContainer, nsTreeColumn& aCol);
 
   private:
     bool IsValidRowIndex(int32_t aRowIndex);
 
     nsCOMPtr<nsITreeBoxObject>          mBoxObject;
     nsCOMPtr<nsITreeSelection>          mSelection;
     nsCOMPtr<nsIContent>                mRoot;
     nsCOMPtr<nsIContent>                mBody;
--- a/layout/xul/tree/nsTreeUtils.cpp
+++ b/layout/xul/tree/nsTreeUtils.cpp
@@ -79,17 +79,17 @@ nsTreeUtils::GetDescendantChild(nsIConte
       return child;
     }
   }
 
   return nullptr;
 }
 
 nsresult
-nsTreeUtils::UpdateSortIndicators(Element* aColumn, const nsAString& aDirection)
+nsTreeUtils::UpdateSortIndicators(nsIContent* aColumn, const nsAString& aDirection)
 {
   aColumn->SetAttr(kNameSpaceID_None, nsGkAtoms::sortDirection, aDirection, true);
   aColumn->SetAttr(kNameSpaceID_None, nsGkAtoms::sortActive, NS_LITERAL_STRING("true"), true);
 
   // Unset sort attribute(s) on the other columns
   nsCOMPtr<nsIContent> parentContent = aColumn->GetParent();
   if (parentContent &&
       parentContent->NodeInfo()->Equals(nsGkAtoms::treecols,
@@ -97,38 +97,38 @@ nsTreeUtils::UpdateSortIndicators(Elemen
     uint32_t i, numChildren = parentContent->GetChildCount();
     for (i = 0; i < numChildren; ++i) {
       nsCOMPtr<nsIContent> childContent = parentContent->GetChildAt(i);
 
       if (childContent &&
           childContent != aColumn &&
           childContent->NodeInfo()->Equals(nsGkAtoms::treecol,
                                            kNameSpaceID_XUL)) {
-        childContent->AsElement()->UnsetAttr(kNameSpaceID_None,
-                                             nsGkAtoms::sortDirection, true);
-        childContent->AsElement()->UnsetAttr(kNameSpaceID_None,
-                                             nsGkAtoms::sortActive, true);
+        childContent->UnsetAttr(kNameSpaceID_None,
+                                nsGkAtoms::sortDirection, true);
+        childContent->UnsetAttr(kNameSpaceID_None,
+                                nsGkAtoms::sortActive, true);
       }
     }
   }
 
   return NS_OK;
 }
 
 nsresult
-nsTreeUtils::GetColumnIndex(Element* aColumn, int32_t* aResult)
+nsTreeUtils::GetColumnIndex(nsIContent* aColumn, int32_t* aResult)
 {
   nsIContent* parentContent = aColumn->GetParent();
   if (parentContent &&
       parentContent->NodeInfo()->Equals(nsGkAtoms::treecols,
                                         kNameSpaceID_XUL)) {
     uint32_t i, numChildren = parentContent->GetChildCount();
     int32_t colIndex = 0;
     for (i = 0; i < numChildren; ++i) {
-      nsIContent* childContent = parentContent->GetChildAt(i);
+      nsIContent *childContent = parentContent->GetChildAt(i);
       if (childContent &&
           childContent->NodeInfo()->Equals(nsGkAtoms::treecol,
                                            kNameSpaceID_XUL)) {
         if (childContent == aColumn) {
           *aResult = colIndex;
           return NS_OK;
         }
         ++colIndex;
--- a/layout/xul/tree/nsTreeUtils.h
+++ b/layout/xul/tree/nsTreeUtils.h
@@ -9,21 +9,16 @@
 
 #include "mozilla/AtomArray.h"
 #include "nsError.h"
 #include "nsString.h"
 #include "nsTreeStyleCache.h"
 
 class nsAtom;
 class nsIContent;
-namespace mozilla {
-namespace dom {
-class Element;
-}
-}
 
 class nsTreeUtils
 {
   public:
     /**
      * Parse a whitespace separated list of properties into an array
      * of atoms.
      */
@@ -33,15 +28,15 @@ class nsTreeUtils
 
     static nsIContent*
     GetImmediateChild(nsIContent* aContainer, nsAtom* aTag);
 
     static nsIContent*
     GetDescendantChild(nsIContent* aContainer, nsAtom* aTag);
 
     static nsresult
-    UpdateSortIndicators(mozilla::dom::Element* aColumn, const nsAString& aDirection);
+    UpdateSortIndicators(nsIContent* aColumn, const nsAString& aDirection);
 
     static nsresult
-    GetColumnIndex(mozilla::dom::Element* aColumn, int32_t* aResult);
+    GetColumnIndex(nsIContent* aColumn, int32_t* aResult);
 };
 
 #endif // nsTreeUtils_h__
--- a/parser/html/nsHtml5TreeOperation.cpp
+++ b/parser/html/nsHtml5TreeOperation.cpp
@@ -1076,33 +1076,33 @@ nsHtml5TreeOperation::Perform(nsHtml5Tre
       return NS_OK;
     }
     case eTreeOpDisableEncodingMenu: {
       nsIDocument* doc = aBuilder->GetDocument();
       doc->DisableEncodingMenu();
       return NS_OK;
     }
     case eTreeOpAddClass: {
-      Element* element = (*(mOne.node))->AsElement();
+      nsIContent* node = *(mOne.node);
       char16_t* str = mTwo.unicharPtr;
       nsDependentString depStr(str);
       // See viewsource.css for the possible classes
       nsAutoString klass;
-      element->GetAttr(kNameSpaceID_None, nsGkAtoms::_class, klass);
+      node->GetAttr(kNameSpaceID_None, nsGkAtoms::_class, klass);
       if (!klass.IsEmpty()) {
         klass.Append(' ');
         klass.Append(depStr);
-        element->SetAttr(kNameSpaceID_None, nsGkAtoms::_class, klass, true);
+        node->SetAttr(kNameSpaceID_None, nsGkAtoms::_class, klass, true);
       } else {
-        element->SetAttr(kNameSpaceID_None, nsGkAtoms::_class, depStr, true);
+        node->SetAttr(kNameSpaceID_None, nsGkAtoms::_class, depStr, true);
       }
       return NS_OK;
     }
     case eTreeOpAddViewSourceHref: {
-      Element* element = (*mOne.node)->AsElement();
+      nsIContent* node = *mOne.node;
       char16_t* buffer = mTwo.unicharPtr;
       int32_t length = mFour.integer;
 
       nsDependentString relative(buffer, length);
 
       nsIDocument* doc = aBuilder->GetDocument();
 
       auto encoding = doc->GetDocumentCharacterSet();
@@ -1144,42 +1144,42 @@ nsHtml5TreeOperation::Perform(nsHtml5Tre
       rv = uri->GetSpec(spec);
       NS_ENSURE_SUCCESS(rv, rv);
 
       viewSourceUrl.Append(spec);
 
       nsAutoString utf16;
       CopyUTF8toUTF16(viewSourceUrl, utf16);
 
-      element->SetAttr(kNameSpaceID_None, nsGkAtoms::href, utf16, true);
+      node->SetAttr(kNameSpaceID_None, nsGkAtoms::href, utf16, true);
       return NS_OK;
     }
     case eTreeOpAddViewSourceBase: {
       char16_t* buffer = mTwo.unicharPtr;
       int32_t length = mFour.integer;
       nsDependentString baseUrl(buffer, length);
       aBuilder->AddBase(baseUrl);
       return NS_OK;
     }
     case eTreeOpAddError: {
-      Element* element = (*(mOne.node))->AsElement();
+      nsIContent* node = *(mOne.node);
       char* msgId = mTwo.charPtr;
       RefPtr<nsAtom> atom = Reget(mThree.atom);
       RefPtr<nsAtom> otherAtom = Reget(mFour.atom);
       // See viewsource.css for the possible classes in addition to "error".
       nsAutoString klass;
-      element->GetAttr(kNameSpaceID_None, nsGkAtoms::_class, klass);
+      node->GetAttr(kNameSpaceID_None, nsGkAtoms::_class, klass);
       if (!klass.IsEmpty()) {
         klass.AppendLiteral(" error");
-        element->SetAttr(kNameSpaceID_None, nsGkAtoms::_class, klass, true);
+        node->SetAttr(kNameSpaceID_None, nsGkAtoms::_class, klass, true);
       } else {
-        element->SetAttr(kNameSpaceID_None,
-                         nsGkAtoms::_class,
-                         NS_LITERAL_STRING("error"),
-                         true);
+        node->SetAttr(kNameSpaceID_None,
+                      nsGkAtoms::_class,
+                      NS_LITERAL_STRING("error"),
+                      true);
       }
 
       nsresult rv;
       nsAutoString message;
       if (otherAtom) {
         const char16_t* params[] = { atom->GetUTF16String(),
                                       otherAtom->GetUTF16String() };
         rv = nsContentUtils::FormatLocalizedString(
@@ -1192,32 +1192,32 @@ nsHtml5TreeOperation::Perform(nsHtml5Tre
         NS_ENSURE_SUCCESS(rv, NS_OK);
       } else {
         rv = nsContentUtils::GetLocalizedString(
           nsContentUtils::eHTMLPARSER_PROPERTIES, msgId, message);
         NS_ENSURE_SUCCESS(rv, NS_OK);
       }
 
       nsAutoString title;
-      element->GetAttr(kNameSpaceID_None, nsGkAtoms::title, title);
+      node->GetAttr(kNameSpaceID_None, nsGkAtoms::title, title);
       if (!title.IsEmpty()) {
         title.Append('\n');
         title.Append(message);
-        element->SetAttr(kNameSpaceID_None, nsGkAtoms::title, title, true);
+        node->SetAttr(kNameSpaceID_None, nsGkAtoms::title, title, true);
       } else {
-        element->SetAttr(kNameSpaceID_None, nsGkAtoms::title, message, true);
+        node->SetAttr(kNameSpaceID_None, nsGkAtoms::title, message, true);
       }
       return rv;
     }
     case eTreeOpAddLineNumberId: {
-      Element* element = (*(mOne.node))->AsElement();
+      nsIContent* node = *(mOne.node);
       int32_t lineNumber = mFour.integer;
       nsAutoString val(NS_LITERAL_STRING("line"));
       val.AppendInt(lineNumber);
-      element->SetAttr(kNameSpaceID_None, nsGkAtoms::id, val, true);
+      node->SetAttr(kNameSpaceID_None, nsGkAtoms::id, val, true);
       return NS_OK;
     }
     case eTreeOpStartLayout: {
       aBuilder->StartLayout(aInterrupted); // this causes a notification flush anyway
       return NS_OK;
     }
     default: {
       MOZ_CRASH("Bogus tree op");