Merge mozilla-central to autoland. a=merge CLOSED TREE
authorCosmin Sabou <csabou@mozilla.com>
Fri, 27 Apr 2018 13:12:22 +0300
changeset 472117 6c8dfef176b5c0d698529810f60ada56b5be7b43
parent 472116 dcbdde8d683c1f2aedbdc1f484e3d1eaa9eaa3f5 (current diff)
parent 472103 d2d518b1f8730eb61554df7179ef9a2aeed4d843 (diff)
child 472118 91f269ab84959f18c7e9373bcb19ee66975824d7
push id1728
push userjlund@mozilla.com
push dateMon, 18 Jun 2018 21:12:27 +0000
treeherdermozilla-release@c296fde26f5f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge mozilla-central to autoland. a=merge CLOSED TREE
dom/interfaces/core/nsIDOMElement.idl
extensions/spellcheck/hunspell/src/filemgr.cxx
gfx/skia/skia/src/core/SkDeviceLooper.cpp
gfx/skia/skia/src/core/SkDeviceLooper.h
--- a/accessible/base/FocusManager.cpp
+++ b/accessible/base/FocusManager.cpp
@@ -194,17 +194,17 @@ FocusManager::ActiveItemChanged(Accessib
   mActiveItem = aItem;
 
   // If mActiveItem is null we may need to shift a11y focus back to a tab
   // document. For example, when combobox popup is closed, then
   // the focus should be moved back to the combobox.
   if (!mActiveItem && XRE_IsParentProcess()) {
     nsFocusManager* domfm = nsFocusManager::GetFocusManager();
     if (domfm) {
-      nsIContent* focusedElm = domfm->GetFocusedContent();
+      nsIContent* focusedElm = domfm->GetFocusedElement();
       if (EventStateManager::IsRemoteTarget(focusedElm)) {
         dom::TabParent* tab = dom::TabParent::GetFrom(focusedElm);
         if (tab) {
           a11y::DocAccessibleParent* dap = tab->GetTopLevelDocAccessible();
           if (dap) {
             Unused << dap->SendRestoreFocus();
           }
         }
@@ -394,17 +394,17 @@ FocusManager::ProcessFocusEvent(AccEvent
     targetDocument->SetAnchorJump(nullptr);
   }
 }
 
 nsINode*
 FocusManager::FocusedDOMNode() const
 {
   nsFocusManager* DOMFocusManager = nsFocusManager::GetFocusManager();
-  nsIContent* focusedElm = DOMFocusManager->GetFocusedContent();
+  nsIContent* focusedElm = DOMFocusManager->GetFocusedElement();
 
   // No focus on remote target elements like xul:browser having DOM focus and
   // residing in chrome process because it means an element in content process
   // keeps the focus.
   if (focusedElm) {
     if (EventStateManager::IsRemoteTarget(focusedElm)) {
       return nullptr;
     }
--- a/accessible/base/nsCoreUtils.cpp
+++ b/accessible/base/nsCoreUtils.cpp
@@ -69,23 +69,22 @@ nsCoreUtils::HasClickListener(nsIContent
      listenerManager->HasListenersFor(nsGkAtoms::onmouseup));
 }
 
 void
 nsCoreUtils::DispatchClickEvent(nsITreeBoxObject *aTreeBoxObj,
                                 int32_t aRowIndex, nsITreeColumn *aColumn,
                                 const nsAString& aPseudoElt)
 {
-  nsCOMPtr<nsIDOMElement> tcElm;
+  RefPtr<dom::Element> tcElm;
   aTreeBoxObj->GetTreeBody(getter_AddRefs(tcElm));
   if (!tcElm)
     return;
 
-  nsCOMPtr<nsIContent> tcContent(do_QueryInterface(tcElm));
-  nsIDocument *document = tcContent->GetUncomposedDoc();
+  nsIDocument *document = tcElm->GetUncomposedDoc();
   if (!document)
     return;
 
   nsCOMPtr<nsIPresShell> presShell = document->GetShell();
   if (!presShell)
     return;
 
   // Ensure row is visible.
@@ -105,36 +104,36 @@ nsCoreUtils::DispatchClickEvent(nsITreeB
 
   int32_t tcX = 0;
   tcBoxObj->GetX(&tcX);
 
   int32_t tcY = 0;
   tcBoxObj->GetY(&tcY);
 
   // Dispatch mouse events.
-  AutoWeakFrame tcFrame = tcContent->GetPrimaryFrame();
+  AutoWeakFrame tcFrame = tcElm->GetPrimaryFrame();
   nsIFrame* rootFrame = presShell->GetRootFrame();
 
   nsPoint offset;
   nsIWidget *rootWidget =
     rootFrame->GetView()->GetNearestWidget(&offset);
 
   RefPtr<nsPresContext> presContext = presShell->GetPresContext();
 
   int32_t cnvdX = presContext->CSSPixelsToDevPixels(tcX + x + 1) +
     presContext->AppUnitsToDevPixels(offset.x);
   int32_t cnvdY = presContext->CSSPixelsToDevPixels(tcY + y + 1) +
     presContext->AppUnitsToDevPixels(offset.y);
 
   // XUL is just desktop, so there is no real reason for senfing touch events.
   DispatchMouseEvent(eMouseDown, cnvdX, cnvdY,
-                     tcContent, tcFrame, presShell, rootWidget);
+                     tcElm, tcFrame, presShell, rootWidget);
 
   DispatchMouseEvent(eMouseUp, cnvdX, cnvdY,
-                     tcContent, tcFrame, presShell, rootWidget);
+                     tcElm, tcFrame, presShell, rootWidget);
 }
 
 void
 nsCoreUtils::DispatchMouseEvent(EventMessage aMessage, int32_t aX, int32_t aY,
                                 nsIContent *aContent, nsIFrame *aFrame,
                                 nsIPresShell *aPresShell, nsIWidget *aRootWidget)
 {
   WidgetMouseEvent event(true, aMessage, aRootWidget,
@@ -486,20 +485,19 @@ nsCoreUtils::GetLanguageFor(nsIContent *
          (!walkUp->IsElement() ||
           !walkUp->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::lang, aLanguage)))
     walkUp = walkUp->GetParent();
 }
 
 already_AddRefed<nsIBoxObject>
 nsCoreUtils::GetTreeBodyBoxObject(nsITreeBoxObject *aTreeBoxObj)
 {
-  nsCOMPtr<nsIDOMElement> tcElm;
+  RefPtr<dom::Element> tcElm;
   aTreeBoxObj->GetTreeBody(getter_AddRefs(tcElm));
-  nsCOMPtr<nsIContent> tcContent(do_QueryInterface(tcElm));
-  RefPtr<nsXULElement> tcXULElm = nsXULElement::FromNodeOrNull(tcContent);
+  RefPtr<nsXULElement> tcXULElm = nsXULElement::FromNodeOrNull(tcElm);
   if (!tcXULElm)
     return nullptr;
 
   return tcXULElm->GetBoxObject(IgnoreErrors());
 }
 
 already_AddRefed<nsITreeBoxObject>
 nsCoreUtils::GetTreeBoxObject(nsIContent *aContent)
@@ -609,20 +607,19 @@ nsCoreUtils::GetPreviousSensibleColumn(n
   }
 
   return prevColumn.forget();
 }
 
 bool
 nsCoreUtils::IsColumnHidden(nsITreeColumn *aColumn)
 {
-  nsCOMPtr<nsIDOMElement> element;
+  RefPtr<Element> element;
   aColumn->GetElement(getter_AddRefs(element));
-  nsCOMPtr<Element> content = do_QueryInterface(element);
-  return content->AttrValueIs(kNameSpaceID_None, nsGkAtoms::hidden,
+  return element->AttrValueIs(kNameSpaceID_None, nsGkAtoms::hidden,
                               nsGkAtoms::_true, eCaseMatters);
 }
 
 void
 nsCoreUtils::ScrollTo(nsIPresShell* aPresShell, nsIContent* aContent,
                       uint32_t aScrollType)
 {
   nsIPresShell::ScrollAxis vertical, horizontal;
--- a/accessible/generic/Accessible.cpp
+++ b/accessible/generic/Accessible.cpp
@@ -25,17 +25,16 @@
 #include "RootAccessible.h"
 #include "States.h"
 #include "StyleInfo.h"
 #include "TableAccessible.h"
 #include "TableCellAccessible.h"
 #include "TreeWalker.h"
 #include "XULDocument.h"
 
-#include "nsIDOMElement.h"
 #include "nsIDOMXULButtonElement.h"
 #include "nsIDOMXULLabelElement.h"
 #include "nsIDOMXULSelectCntrlEl.h"
 #include "nsIDOMXULSelectCntrlItemEl.h"
 #include "nsINodeList.h"
 #include "nsPIDOMWindow.h"
 
 #include "nsIDocument.h"
--- a/accessible/html/HTMLImageMapAccessible.cpp
+++ b/accessible/html/HTMLImageMapAccessible.cpp
@@ -6,17 +6,16 @@
 #include "HTMLImageMapAccessible.h"
 
 #include "ARIAMap.h"
 #include "nsAccUtils.h"
 #include "DocAccessible-inl.h"
 #include "Role.h"
 
 #include "nsIServiceManager.h"
-#include "nsIDOMElement.h"
 #include "nsIFrame.h"
 #include "nsImageFrame.h"
 #include "nsImageMap.h"
 #include "nsIURI.h"
 #include "mozilla/dom/HTMLAreaElement.h"
 
 using namespace mozilla::a11y;
 
--- a/accessible/html/HTMLTableAccessible.cpp
+++ b/accessible/html/HTMLTableAccessible.cpp
@@ -13,17 +13,16 @@
 #include "DocAccessible.h"
 #include "nsTextEquivUtils.h"
 #include "Relation.h"
 #include "Role.h"
 #include "States.h"
 #include "TreeWalker.h"
 
 #include "mozilla/dom/HTMLTableElement.h"
-#include "nsIDOMElement.h"
 #include "nsIDOMRange.h"
 #include "nsISelectionPrivate.h"
 #include "nsIHTMLCollection.h"
 #include "nsIDocument.h"
 #include "nsIMutableArray.h"
 #include "nsIPersistentProperties2.h"
 #include "nsIPresShell.h"
 #include "nsITableCellLayout.h"
--- a/accessible/jsat/EventManager.jsm
+++ b/accessible/jsat/EventManager.jsm
@@ -99,23 +99,17 @@ this.EventManager.prototype = {
          { moveMethod: delta > 0 ? "moveNext" : "movePrevious",
            onScreenOnly: true, noOpIfOnScreen: true, delay: 500 });
         break;
       }
       case "scroll":
       case "resize":
       {
         // the target could be an element, document or window
-        let window = null;
-        if (aEvent.target instanceof Ci.nsIDOMWindow)
-          window = aEvent.target;
-        else if (aEvent.target instanceof Ci.nsIDOMDocument)
-          window = aEvent.target.defaultView;
-        else if (aEvent.target instanceof Ci.nsIDOMElement)
-          window = aEvent.target.ownerGlobal;
+        let window = aEvent.target.ownerGlobal;
         this.present(Presentation.viewportChanged(window));
         break;
       }
       }
     } catch (x) {
       Logger.logException(x, "Error handling DOM event");
     }
   },
--- a/accessible/windows/msaa/AccessibleWrap.cpp
+++ b/accessible/windows/msaa/AccessibleWrap.cpp
@@ -914,16 +914,20 @@ AccessibleWrap::accLocation(
     return hr;
   }
 
   if (accessible) {
     return accessible->accLocation(pxLeft, pyTop, pcxWidth, pcyHeight,
                                    kVarChildIdSelf);
   }
 
+  if (IsDefunct()) {
+    return CO_E_OBJNOTCONNECTED;
+  }
+
   nsIntRect rect = Bounds();
 
   *pxLeft = rect.X();
   *pyTop = rect.Y();
   *pcxWidth = rect.Width();
   *pcyHeight = rect.Height();
   return S_OK;
 }
--- a/accessible/xul/XULColorPickerAccessible.cpp
+++ b/accessible/xul/XULColorPickerAccessible.cpp
@@ -6,17 +6,16 @@
 #include "XULColorPickerAccessible.h"
 
 #include "Accessible-inl.h"
 #include "nsAccUtils.h"
 #include "DocAccessible.h"
 #include "Role.h"
 #include "States.h"
 
-#include "nsIDOMElement.h"
 #include "nsMenuPopupFrame.h"
 
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
 // XULColorPickerTileAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
--- a/accessible/xul/XULMenuAccessible.cpp
+++ b/accessible/xul/XULMenuAccessible.cpp
@@ -8,17 +8,16 @@
 #include "Accessible-inl.h"
 #include "nsAccessibilityService.h"
 #include "nsAccUtils.h"
 #include "DocAccessible.h"
 #include "Role.h"
 #include "States.h"
 #include "XULFormControlAccessible.h"
 
-#include "nsIDOMElement.h"
 #include "nsIMutableArray.h"
 #include "nsIDOMXULContainerElement.h"
 #include "nsIDOMXULSelectCntrlItemEl.h"
 #include "nsIDOMXULMultSelectCntrlEl.h"
 #include "nsIServiceManager.h"
 #include "nsIPresShell.h"
 #include "nsIContent.h"
 #include "nsMenuBarFrame.h"
--- a/accessible/xul/XULSelectControlAccessible.cpp
+++ b/accessible/xul/XULSelectControlAccessible.cpp
@@ -7,17 +7,16 @@
 #include "XULSelectControlAccessible.h"
 
 #include "nsAccessibilityService.h"
 #include "DocAccessible.h"
 
 #include "nsIDOMXULContainerElement.h"
 #include "nsIDOMXULSelectCntrlItemEl.h"
 #include "nsIDOMXULMultSelectCntrlEl.h"
-#include "nsIDOMElement.h"
 #include "nsIMutableArray.h"
 #include "nsIServiceManager.h"
 
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/KeyboardEventBinding.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
--- a/accessible/xul/XULSliderAccessible.h
+++ b/accessible/xul/XULSliderAccessible.h
@@ -3,18 +3,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_a11y_XULSliderAccessible_h__
 #define mozilla_a11y_XULSliderAccessible_h__
 
 #include "AccessibleWrap.h"
 
-#include "nsIDOMElement.h"
-
 namespace mozilla {
 namespace a11y {
 
 /**
  * Used for XUL slider and scale elements.
  */
 class XULSliderAccessible : public AccessibleWrap
 {
--- a/accessible/xul/XULTreeGridAccessible.cpp
+++ b/accessible/xul/XULTreeGridAccessible.cpp
@@ -15,18 +15,20 @@
 #include "States.h"
 #include "nsQueryObject.h"
 
 #include "nsIBoxObject.h"
 #include "nsIMutableArray.h"
 #include "nsIPersistentProperties2.h"
 #include "nsITreeSelection.h"
 #include "nsComponentManagerUtils.h"
+#include "mozilla/dom/Element.h"
 
 using namespace mozilla::a11y;
+using namespace mozilla;
 
 XULTreeGridAccessible::~XULTreeGridAccessible()
 {
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // XULTreeGridAccessible: Table
 
@@ -626,21 +628,20 @@ uint32_t
 XULTreeGridCellAccessible::RowIdx() const
 {
   return mRow;
 }
 
 void
 XULTreeGridCellAccessible::ColHeaderCells(nsTArray<Accessible*>* aHeaderCells)
 {
-  nsCOMPtr<nsIDOMElement> columnElm;
+  RefPtr<dom::Element> columnElm;
   mColumn->GetElement(getter_AddRefs(columnElm));
 
-  nsCOMPtr<nsIContent> columnContent(do_QueryInterface(columnElm));
-  Accessible* headerCell = mDoc->GetAccessible(columnContent);
+  Accessible* headerCell = mDoc->GetAccessible(columnElm);
   if (headerCell)
     aHeaderCells->AppendElement(headerCell);
 }
 
 bool
 XULTreeGridCellAccessible::Selected()
 {
   nsCOMPtr<nsITreeSelection> selection;
@@ -821,24 +822,23 @@ XULTreeGridCellAccessible::IsEditable() 
 
   // XXX: logic corresponds to tree.xml, it's preferable to have interface
   // method to check it.
   bool isEditable = false;
   nsresult rv = mTreeView->IsEditable(mRow, mColumn, &isEditable);
   if (NS_FAILED(rv) || !isEditable)
     return false;
 
-  nsCOMPtr<nsIDOMElement> columnElm;
+  RefPtr<dom::Element> columnElm;
   mColumn->GetElement(getter_AddRefs(columnElm));
   if (!columnElm)
     return false;
 
-  nsCOMPtr<Element> columnContent(do_QueryInterface(columnElm));
-  if (!columnContent->AttrValueIs(kNameSpaceID_None,
-                                  nsGkAtoms::editable,
-                                  nsGkAtoms::_true,
-                                  eCaseMatters))
+  if (!columnElm->AttrValueIs(kNameSpaceID_None,
+                              nsGkAtoms::editable,
+                              nsGkAtoms::_true,
+                              eCaseMatters))
     return false;
 
   return mContent->AsElement()->AttrValueIs(kNameSpaceID_None,
                                             nsGkAtoms::editable,
                                             nsGkAtoms::_true, eCaseMatters);
 }
--- a/browser/components/places/PlacesUIUtils.jsm
+++ b/browser/components/places/PlacesUIUtils.jsm
@@ -4,16 +4,18 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 var EXPORTED_SYMBOLS = ["PlacesUIUtils"];
 
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.import("resource://gre/modules/Timer.jsm");
 
+Cu.importGlobalProperties(["Element"]);
+
 XPCOMUtils.defineLazyModuleGetters(this, {
   AppConstants: "resource://gre/modules/AppConstants.jsm",
   BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.jsm",
   OpenInTabsUtils: "resource:///modules/OpenInTabsUtils.jsm",
   PlacesTransactions: "resource://gre/modules/PlacesTransactions.jsm",
   PlacesUtils: "resource://gre/modules/PlacesUtils.jsm",
   PluralForm: "resource://gre/modules/PluralForm.jsm",
   PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.jsm",
@@ -329,17 +331,17 @@ var PlacesUIUtils = {
     }
 
     // The view for a <menu> of which its associated menupopup is a places
     // view, is the menupopup.
     if (node.localName == "menu" && !node._placesNode &&
         node.lastChild._placesView)
       return node.lastChild._placesView;
 
-    while (node instanceof Ci.nsIDOMElement) {
+    while (Element.isInstance(node)) {
       if (node._placesView)
         return node._placesView;
       if (node.localName == "tree" && node.getAttribute("type") == "places")
         return node;
 
       node = node.parentNode;
     }
 
@@ -1123,17 +1125,17 @@ function canMoveUnwrappedNode(unwrappedN
  * For example, if it detects the left-hand library pane, then it will look for
  * and return the reference to the right-hand pane.
  *
  * @param {Object} viewOrElement The item to check.
  * @return {Object} Will return the best result node to batch, or null
  *                  if one could not be found.
  */
 function getResultForBatching(viewOrElement) {
-  if (viewOrElement && viewOrElement instanceof Ci.nsIDOMElement &&
+  if (viewOrElement && Element.isInstance(viewOrElement) &&
       viewOrElement.id === "placesList") {
     // Note: fall back to the existing item if we can't find the right-hane pane.
     viewOrElement = viewOrElement.ownerDocument.getElementById("placeContent") || viewOrElement;
   }
 
   if (viewOrElement && viewOrElement.result) {
     return viewOrElement.result;
   }
--- a/browser/components/places/content/browserPlacesViews.js
+++ b/browser/components/places/content/browserPlacesViews.js
@@ -733,17 +733,17 @@ PlacesViewBase.prototype = {
         }
       }, Cu.reportError);
   },
 
   /**
    * Checks whether the popup associated with the provided element is open.
    * This method may be overridden by classes that extend this base class.
    *
-   * @param  {nsIDOMElement} elt
+   * @param  {Element} elt
    * @return {Boolean}
    */
   _isPopupOpen(elt) {
     return !!elt.parentNode.open;
   },
 
   invalidateContainer: function PVB_invalidateContainer(aPlacesNode) {
     let elt = this._getDOMNodeForPlacesNode(aPlacesNode);
--- a/browser/components/shell/nsGNOMEShellService.cpp
+++ b/browser/components/shell/nsGNOMEShellService.cpp
@@ -18,21 +18,21 @@
 #include "nsIGConfService.h"
 #include "nsIGIOService.h"
 #include "nsIGSettingsService.h"
 #include "nsIStringBundle.h"
 #include "nsIOutputStream.h"
 #include "nsIProcess.h"
 #include "nsServiceManagerUtils.h"
 #include "nsComponentManagerUtils.h"
-#include "nsIDOMElement.h"
 #include "nsIImageLoadingContent.h"
 #include "imgIRequest.h"
 #include "imgIContainer.h"
 #include "mozilla/Sprintf.h"
+#include "mozilla/dom/Element.h"
 #if defined(MOZ_WIDGET_GTK)
 #include "nsIImageToPixbuf.h"
 #endif
 #include "nsXULAppAPI.h"
 #include "gfxPlatform.h"
 
 #include <glib.h>
 #include <glib-object.h>
@@ -406,17 +406,17 @@ WriteImage(const nsCString& aPath, imgIC
   gboolean res = gdk_pixbuf_save(pixbuf, aPath.get(), "png", nullptr, nullptr);
 
   g_object_unref(pixbuf);
   return res ? NS_OK : NS_ERROR_FAILURE;
 #endif
 }
 
 NS_IMETHODIMP
-nsGNOMEShellService::SetDesktopBackground(nsIDOMElement* aElement,
+nsGNOMEShellService::SetDesktopBackground(dom::Element* aElement,
                                           int32_t aPosition,
                                           const nsACString& aImageName)
 {
   nsresult rv;
   nsCOMPtr<nsIImageLoadingContent> imageContent = do_QueryInterface(aElement, &rv);
   if (!imageContent) return rv;
 
   // get the image container
--- a/browser/components/shell/nsIShellService.idl
+++ b/browser/components/shell/nsIShellService.idl
@@ -1,18 +1,19 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
-interface nsIDOMElement;
 interface nsIFile;
 
+webidl Element;
+
 [scriptable, uuid(2d1a95e4-5bd8-4eeb-b0a8-c1455fd2a357)]
 interface nsIShellService : nsISupports
 {
   /**
    * Determines whether or not Firefox is the "Default Browser."
    * This is simply whether or not Firefox is registered to handle
    * http links.
    *
@@ -53,17 +54,17 @@ interface nsIShellService : nsISupports
      *
      * @param aImageElement Either a HTML <IMG> element or an element with
      *                      a background image from which to source the
      *                      background image. 
      * @param aPosition     How to place the image on the desktop
      * @param aImageName    The image name. Equivalent to the leaf name of the
      *                      location.href.
      */
-  void setDesktopBackground(in nsIDOMElement aElement,
+  void setDesktopBackground(in Element aElement,
                             in long aPosition,
                             in ACString aImageName);
 
   /**
    * Constants identifying applications that can be opened with
    * openApplication.
    */
   const long APPLICATION_MAIL        = 0;
--- a/browser/components/shell/nsMacShellService.cpp
+++ b/browser/components/shell/nsMacShellService.cpp
@@ -1,15 +1,14 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsDirectoryServiceDefs.h"
-#include "nsIDOMElement.h"
 #include "nsIImageLoadingContent.h"
 #include "nsIDocument.h"
 #include "nsIContent.h"
 #include "nsILocalFileMac.h"
 #include "nsIObserverService.h"
 #include "nsIPrefService.h"
 #include "nsIServiceManager.h"
 #include "nsIStringBundle.h"
@@ -17,20 +16,23 @@
 #include "nsIWebBrowserPersist.h"
 #include "nsMacShellService.h"
 #include "nsIProperties.h"
 #include "nsServiceManagerUtils.h"
 #include "nsShellService.h"
 #include "nsString.h"
 #include "nsIDocShell.h"
 #include "nsILoadContext.h"
+#include "mozilla/dom/Element.h"
 
 #include <CoreFoundation/CoreFoundation.h>
 #include <ApplicationServices/ApplicationServices.h>
 
+using mozilla::dom::Element;
+
 #define NETWORK_PREFPANE NS_LITERAL_CSTRING("/System/Library/PreferencePanes/Network.prefPane")
 #define DESKTOP_PREFPANE NS_LITERAL_CSTRING("/System/Library/PreferencePanes/DesktopScreenEffectsPref.prefPane")
 
 #define SAFARI_BUNDLE_IDENTIFIER "com.apple.Safari"
 
 NS_IMPL_ISUPPORTS(nsMacShellService, nsIMacShellService, nsIShellService, nsIWebProgressListener)
 
 NS_IMETHODIMP
@@ -92,36 +94,32 @@ nsMacShellService::SetDefaultBrowser(boo
     // before it is silenced.
     (void) prefs->SetIntPref(PREF_DEFAULTBROWSERCHECKCOUNT, 0);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsMacShellService::SetDesktopBackground(nsIDOMElement* aElement,
+nsMacShellService::SetDesktopBackground(Element* aElement,
                                         int32_t aPosition,
                                         const nsACString& aImageName)
 {
   // Note: We don't support aPosition on OS X.
 
   // Get the image URI:
   nsresult rv;
   nsCOMPtr<nsIImageLoadingContent> imageContent = do_QueryInterface(aElement,
                                                                     &rv);
   NS_ENSURE_SUCCESS(rv, rv);
   nsCOMPtr<nsIURI> imageURI;
   rv = imageContent->GetCurrentURI(getter_AddRefs(imageURI));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  // We need the referer URI for nsIWebBrowserPersist::saveURI
-  nsCOMPtr<nsIContent> content = do_QueryInterface(aElement, &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsIURI *docURI = content->OwnerDoc()->GetDocumentURI();
+  nsIURI *docURI = aElement->OwnerDoc()->GetDocumentURI();
   if (!docURI)
     return NS_ERROR_FAILURE;
 
   nsCOMPtr<nsIProperties> fileLocator
     (do_GetService("@mozilla.org/file/directory_service;1", &rv));
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Get the current user's "Pictures" folder (That's ~/Pictures):
@@ -144,24 +142,24 @@ nsMacShellService::SetDesktopBackground(
   uint32_t flags = nsIWebBrowserPersist::PERSIST_FLAGS_NO_CONVERSION |
                    nsIWebBrowserPersist::PERSIST_FLAGS_REPLACE_EXISTING_FILES |
                    nsIWebBrowserPersist::PERSIST_FLAGS_FROM_CACHE;
 
   wbp->SetPersistFlags(flags);
   wbp->SetProgressListener(this);
 
   nsCOMPtr<nsILoadContext> loadContext;
-  nsCOMPtr<nsISupports> container = content->OwnerDoc()->GetContainer();
+  nsCOMPtr<nsISupports> container = aElement->OwnerDoc()->GetContainer();
   nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(container);
   if (docShell) {
     loadContext = do_QueryInterface(docShell);
   }
 
   return wbp->SaveURI(imageURI, 0,
-                      docURI, content->OwnerDoc()->GetReferrerPolicy(),
+                      docURI, aElement->OwnerDoc()->GetReferrerPolicy(),
                       nullptr, nullptr,
                       mBackgroundFile, loadContext);
 }
 
 NS_IMETHODIMP
 nsMacShellService::OnProgressChange(nsIWebProgress* aWebProgress,
                                     nsIRequest* aRequest,
                                     int32_t aCurSelfProgress,
--- a/browser/components/shell/nsWindowsShellService.cpp
+++ b/browser/components/shell/nsWindowsShellService.cpp
@@ -7,17 +7,16 @@
 
 #include "BinaryPath.h"
 #include "city.h"
 #include "imgIContainer.h"
 #include "imgIRequest.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/RefPtr.h"
 #include "nsIContent.h"
-#include "nsIDOMElement.h"
 #include "nsIImageLoadingContent.h"
 #include "nsIOutputStream.h"
 #include "nsIPrefService.h"
 #include "nsIPrefLocalizedString.h"
 #include "nsIServiceManager.h"
 #include "nsIStringBundle.h"
 #include "nsNetUtil.h"
 #include "nsServiceManagerUtils.h"
@@ -28,16 +27,17 @@
 #include "nsDirectoryServiceUtils.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsIWindowsRegKey.h"
 #include "nsUnicharUtils.h"
 #include "nsIURLFormatter.h"
 #include "nsXULAppAPI.h"
 #include "mozilla/WindowsVersion.h"
+#include "mozilla/dom/Element.h"
 
 #include "windows.h"
 #include "shellapi.h"
 
 #ifdef _WIN32_WINNT
 #undef _WIN32_WINNT
 #endif
 #define _WIN32_WINNT 0x0600
@@ -570,22 +570,21 @@ WriteBitmap(nsIFile* aFile, imgIContaine
   }
 
   dataSurface->Unmap();
 
   return rv;
 }
 
 NS_IMETHODIMP
-nsWindowsShellService::SetDesktopBackground(nsIDOMElement* aElement,
+nsWindowsShellService::SetDesktopBackground(dom::Element* aElement,
                                             int32_t aPosition,
                                             const nsACString& aImageName)
 {
-  nsCOMPtr<nsIContent> content(do_QueryInterface(aElement));
-  if (!content || !content->IsHTMLElement(nsGkAtoms::img)) {
+  if (!aElement || !aElement->IsHTMLElement(nsGkAtoms::img)) {
     // XXX write background loading stuff!
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   nsresult rv;
   nsCOMPtr<nsIImageLoadingContent> imageContent =
     do_QueryInterface(aElement, &rv);
   if (!imageContent)
--- a/devtools/client/accessibility/test/head.js
+++ b/devtools/client/accessibility/test/head.js
@@ -117,17 +117,17 @@ async function disableAccessibilityInspe
   EventUtils.sendMouseEvent({ type: "click" },
     doc.getElementById("accessibility-disable-button"), win);
   await shutdown;
 }
 
 /**
  * Open the Accessibility panel for the given tab.
  *
- * @param {nsIDOMElement} tab
+ * @param {Element} tab
  *        Optional tab element for which you want open the Accessibility panel.
  *        The default tab is taken from the global variable |tab|.
  * @return a promise that is resolved once the panel is open.
  */
 async function initAccessibilityPanel(tab = gBrowser.selectedTab) {
   let target = TargetFactory.forTab(tab);
   let toolbox = await gDevTools.showToolbox(target, "accessibility");
   return toolbox.getCurrentPanel();
--- a/devtools/client/debugger/new/README.mozilla
+++ b/devtools/client/debugger/new/README.mozilla
@@ -1,13 +1,13 @@
 This is the debugger.html project output.
 See https://github.com/devtools-html/debugger.html
 
-Version 44.0
+Version 45.0
 
-Comparison: https://github.com/devtools-html/debugger.html/compare/release-43...release-44
+Comparison: https://github.com/devtools-html/debugger.html/compare/release-44...release-45
 
 Packages:
 - babel-plugin-transform-es2015-modules-commonjs @6.26.0
 - babel-preset-react @6.24.1
 - react @16.2.0
 - react-dom @16.2.0
 - webpack @3.11.0
--- a/devtools/client/debugger/new/debugger.css
+++ b/devtools/client/debugger/new/debugger.css
@@ -2369,26 +2369,28 @@ button.jump-definition {
 .popover .preview-popup .header-container {
   width: 100%;
   line-height: 15px;
   display: flex;
   flex-direction: row;
   margin-bottom: 5px;
 }
 
-.popover .preview-popup .immutable-logo {
+.popover .preview-popup .logo {
   width: 20px;
   margin-right: 5px;
 }
 
 .popover .preview-popup .header-container h3 {
   margin: 0;
   margin-bottom: 5px;
   font-weight: normal;
   font-size: 14px;
+  line-height: 20px;
+  margin-left: 4px;
 }
 
 .popover .preview-popup .header .link {
   align-self: flex-end;
   color: var(--theme-highlight-blue);
   text-decoration: underline;
 }
 
@@ -2855,41 +2857,57 @@ debug-expression-error {
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
 
 .breakpoints-toggle {
   margin: 2px 3px;
 }
 
+.pane.breakpoints-list {
+  padding-bottom: 0.35em;
+}
+
 .breakpoints-list * {
   user-select: none;
 }
 
 .breakpoints-list .breakpoint-heading {
   text-overflow: ellipsis;
   overflow: hidden;
+  padding-top: 0.75em;
 }
 
 .breakpoints-list .breakpoint-heading,
 .breakpoints-list .breakpoint {
   font-size: 12px;
   color: var(--theme-content-color1);
   position: relative;
   transition: all 0.25s ease;
 }
 
 .breakpoints-list .breakpoint-heading,
 .breakpoints-list .breakpoint,
 .breakpoints-exceptions {
-  padding: 0.5em 1em 0.5em 0.5em;
+  padding: 0.25em 1em 0.25em 0.5em;
+}
+
+.breakpoints-exceptions {
+  padding-bottom: 0.5em;
+  padding-top: 0.5em;
+}
+
+.breakpoints-list .breakpoint {
+    padding-top: 0.25em;
+    padding-bottom: 0.25em;
 }
 
 .breakpoints-exceptions-caught {
   padding: 0 1em 0.5em 2em;
+  margin-top: -0.25em;
 }
 
 html[dir="rtl"] .breakpoints-exceptions-caught {
   padding: 0 2em 0.5em 1em;
 }
 
 .breakpoints-exceptions-options:not(.empty) {
   border-bottom: 1px solid var(--theme-splitter-color);
@@ -2957,17 +2975,17 @@ html .breakpoints-list .breakpoint.pause
 .breakpoints-list .breakpoint .breakpoint-line,
 .breakpoints-list .breakpoint-label {
   font-family: var(--monospace-font-family);
 }
 
 .breakpoints-list .breakpoint .breakpoint-line {
   font-size: 11px;
   color: var(--theme-comment);
-  padding-top: 3px;
+  padding-top: 4px;
   padding-inline-end: 2px;
   min-width: 14px;
   text-align: right;
 }
 
 html[dir="rtl"] .breakpoints-list .breakpoint .breakpoint-line {
   text-align: left;
 }
@@ -2985,16 +3003,17 @@ html[dir="rtl"] .breakpoints-list .break
   display: inline-block;
   padding-inline-start: 2px;
   padding-inline-end: 8px;
   cursor: default;
   flex-grow: 1;
   text-overflow: ellipsis;
   overflow: hidden;
   padding-top: 3px;
+  font-size: 11px;
 }
 
 .breakpoint-label .breakpoint-checkbox {
   margin-inline-start: 0;
   vertical-align: text-bottom;
 }
 
 .breakpoint-label .location {
@@ -3010,17 +3029,17 @@ html[dir="rtl"] .breakpoints-list .break
   flex: 0 1 content;
   order: 3;
 }
 
 .breakpoint .close-btn {
   position: absolute;
   offset-inline-end: 13px;
   offset-inline-start: auto;
-  top: 9px;
+  top: 6px;
   display: none;
 }
 
 .breakpoint:hover .close-btn {
   display: flex;
 }
 
 .breakpoint .close {
@@ -3054,20 +3073,16 @@ html[dir="rtl"] .breakpoints-list .break
 .CodeMirror.cm-s-mozilla-breakpoint .CodeMirror-code,
 .CodeMirror.cm-s-mozilla-breakpoint .CodeMirror-scroll {
   cursor: default;
 }
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
 
-.watch-expressions-pane .plus {
-  margin-top: -2px;
-}
-
 .expression-input-form {
   width: 100%;
 }
 
 .input-expression {
   width: 100%;
   margin: 0;
   border: 1px;
@@ -3112,16 +3127,20 @@ html[dir="rtl"] .breakpoints-list .break
   display: flex;
   border: 1px solid transparent;
 }
 
 .expression-input-container.focused {
   border: 1px solid var(--theme-highlight-blue);
 }
 
+:root.theme-dark .expression-input-container.focused {
+  border: 1px solid var(--blue-50);
+}
+
 .expression-input-container.error {
   border: 1px solid red;
 }
 
 .expression-container {
   border: 1px;
   padding: 0.25em 1em 0.25em 0.5em;
   width: 100%;
@@ -3770,20 +3789,24 @@ img.skipPausing {
   user-select: none;
   cursor: default;
 }
 
 .secondary-panes .breakpoints-buttons {
   display: flex;
 }
 
+.secondary-panes .accordion .plus {
+  margin-top: -2px;
+}
+
 .secondary-panes .accordion .plus svg {
   width: 12px;
   margin-top: 3px;
-  fill: var(--theme-comment-alt);
+  fill: var(--theme-body-color);
 }
 
 .secondary-panes .accordion .plus.active svg {
   fill: var(--theme-highlight-blue);
 }
 
 .dropdown {
   width: 20em;
--- a/devtools/client/debugger/new/debugger.js
+++ b/devtools/client/debugger/new/debugger.js
@@ -17019,19 +17019,20 @@ class SourcesTree extends _react.Compone
     const isCustomRoot = projectRoot !== "";
     let roots = () => sourceTree.contents;
 
     let clearProjectRootButton = null;
 
     // The "sourceTree.contents[0]" check ensures that there are contents
     // A custom root with no existing sources will be ignored
     if (isCustomRoot) {
+      const sourceContents = sourceTree.contents[0];
       let rootLabel = projectRoot.split("/").pop();
-      const sourceContents = sourceTree.contents[0];
-      if (sourceContents) {
+      roots = () => sourceContents.contents;
+      if (sourceContents && sourceContents.name !== rootLabel) {
         rootLabel = sourceContents.contents[0].name;
         roots = () => sourceContents.contents[0].contents;
       }
 
       clearProjectRootButton = _react2.default.createElement(
         "button",
         {
           className: "sources-clear-root",
@@ -18678,18 +18679,16 @@ var _Popover = __webpack_require__(1586)
 var _Popover2 = _interopRequireDefault(_Popover);
 
 var _PreviewFunction = __webpack_require__(1446);
 
 var _PreviewFunction2 = _interopRequireDefault(_PreviewFunction);
 
 var _editor = __webpack_require__(1358);
 
-var _preview = __webpack_require__(1807);
-
 var _Svg = __webpack_require__(1359);
 
 var _Svg2 = _interopRequireDefault(_Svg);
 
 var _firefox = __webpack_require__(1500);
 
 __webpack_require__(1328);
 
@@ -18698,39 +18697,37 @@ function _interopRequireDefault(obj) { r
 const { REPS: { Rep }, MODE, ObjectInspector, ObjectInspectorUtils } = _devtoolsReps2.default; /* This Source Code Form is subject to the terms of the Mozilla Public
                                                                                                 * License, v. 2.0. If a copy of the MPL was not distributed with this
                                                                                                 * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
 
 const {
   createNode,
   getChildren,
   getValue,
-  nodeIsPrimitive
+  nodeIsPrimitive,
+  NODE_TYPES
 } = ObjectInspectorUtils.node;
 const { loadItemProperties } = ObjectInspectorUtils.loadProperties;
 
 class Popup extends _react.Component {
 
   async componentWillMount() {
     const {
       value,
-      expression,
       setPopupObjectProperties,
       popupObjectProperties
     } = this.props;
-    const root = createNode({
-      name: expression,
-      contents: { value }
-    });
+
+    const root = this.getRoot();
 
     if (!nodeIsPrimitive(root) && value && value.actor && !popupObjectProperties[value.actor]) {
       const onLoadItemProperties = loadItemProperties(root, _firefox.createObjectClient);
       if (onLoadItemProperties !== null) {
         const properties = await onLoadItemProperties;
-        setPopupObjectProperties(value, properties);
+        setPopupObjectProperties(root.contents.value, properties);
       }
     }
   }
 
   componentDidMount() {
     const { value, editor, range } = this.props;
 
     if (!value || !value.type == "object") {
@@ -18742,23 +18739,28 @@ class Popup extends _react.Component {
 
   componentWillUnmount() {
     if (this.marker) {
       this.marker.clear();
     }
   }
 
   getRoot() {
-    const { expression, value } = this.props;
-
-    return {
+    const { expression, value, extra } = this.props;
+
+    let rootValue = value;
+    if (extra.immutable) {
+      rootValue = extra.immutable.entries;
+    }
+
+    return createNode({
       name: expression,
       path: expression,
-      contents: { value }
-    };
+      contents: { value: rootValue }
+    });
   }
 
   getChildren() {
     const { popupObjectProperties } = this.props;
 
     const root = this.getRoot();
     const value = getValue(root);
     const actor = value ? value.actor : null;
@@ -18795,89 +18797,75 @@ class Popup extends _react.Component {
       },
       _react2.default.createElement(_PreviewFunction2.default, { func: value })
     );
   }
 
   renderReact(react, roots) {
     const reactHeader = react.displayName || "React Component";
 
-    const header = _react2.default.createElement(
+    return _react2.default.createElement(
       "div",
       { className: "header-container" },
+      _react2.default.createElement(_Svg2.default, { name: "react", className: "logo" }),
       _react2.default.createElement(
         "h3",
         null,
         reactHeader
       )
     );
-
-    roots = roots.filter(r => ["state", "props"].includes(r.name));
-    return _react2.default.createElement(
-      "div",
-      { className: "preview-popup" },
-      header,
-      this.renderObjectInspector(roots)
-    );
   }
 
   renderImmutable(immutable) {
     const immutableHeader = immutable.type || "Immutable";
 
-    const header = _react2.default.createElement(
+    return _react2.default.createElement(
       "div",
       { className: "header-container" },
-      _react2.default.createElement(_Svg2.default, { name: "immutable", className: "immutable-logo" }),
+      _react2.default.createElement(_Svg2.default, { name: "immutable", className: "logo" }),
       _react2.default.createElement(
         "h3",
         null,
         immutableHeader
       )
     );
-
-    const roots = [createNode({ name: "entries", contents: { value: immutable.entries } })];
+  }
+
+  renderObjectPreview() {
+    const { extra } = this.props;
+    const root = this.getRoot();
+
+    if (nodeIsPrimitive(root)) {
+      return null;
+    }
+
+    let roots = this.getChildren();
+    if (!Array.isArray(roots) || roots.length === 0) {
+      return null;
+    }
+
+    let header = null;
+    if (extra.immutable) {
+      header = this.renderImmutable(extra.immutable);
+      roots = roots.filter(r => r.type != NODE_TYPES.PROTOTYPE);
+    }
+
+    if (extra.react) {
+      header = this.renderReact(extra.react);
+      roots = roots.filter(r => ["state", "props"].includes(r.name));
+    }
 
     return _react2.default.createElement(
       "div",
       { className: "preview-popup" },
       header,
       this.renderObjectInspector(roots)
     );
   }
 
-  renderObjectPreview() {
-    const root = this.getRoot();
-
-    if (nodeIsPrimitive(root)) {
-      return null;
-    }
-
-    const roots = this.getChildren();
-    if (!Array.isArray(roots) || roots.length === 0) {
-      return null;
-    }
-
-    const { extra: { react, immutable } } = this.props;
-    const grip = getValue(root);
-
-    if ((0, _preview.isReactComponent)(grip)) {
-      return this.renderReact(react, roots);
-    }
-
-    if ((0, _preview.isImmutable)(grip)) {
-      return this.renderImmutable(immutable);
-    }
-
-    return _react2.default.createElement(
-      "div",
-      { className: "preview-popup" },
-      this.renderObjectInspector(roots)
-    );
-  }
-
   renderSimplePreview(value) {
     const { openLink } = this.props;
     return _react2.default.createElement(
       "div",
       { className: "preview-popup" },
       Rep({
         object: value,
         mode: MODE.LONG,
@@ -22593,20 +22581,22 @@ var _ast = __webpack_require__(1638);
 var _indentation = __webpack_require__(1438);
 
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
 
 function findFunctionText(line, source, symbols) {
   const func = (0, _ast.findClosestFunction)(symbols, {
+    sourceId: source.id,
     line,
     column: Infinity
   });
-  if (!func) {
+
+  if (!func || !source.text) {
     return null;
   }
 
   const { location: { start, end } } = func;
   const lines = source.text.split("\n");
   const firstLine = lines[start.line - 1].slice(start.column);
   const lastLine = lines[end.line - 1].slice(0, end.column);
   const middle = lines.slice(start.line, end.line - 1);
@@ -23275,20 +23265,16 @@ function isCurrentlyPausedAtBreakpoint(f
     return false;
   }
 
   const bpId = (0, _breakpoint.makeLocationId)(breakpoint.location);
   const pausedId = (0, _breakpoint.makeLocationId)(frame.location);
   return bpId === pausedId;
 }
 
-function getBreakpointFilename(source) {
-  return source ? (0, _source.getFilename)(source) : "";
-}
-
 function createExceptionOption(label, value, onChange, className) {
   return _react2.default.createElement(
     "div",
     { className: className, onClick: onChange },
     _react2.default.createElement("input", {
       type: "checkbox",
       checked: value ? "checked" : "",
       onChange: e => e.stopPropagation() && onChange()
@@ -23296,16 +23282,30 @@ function createExceptionOption(label, va
     _react2.default.createElement(
       "div",
       { className: "breakpoint-exceptions-label" },
       label
     )
   );
 }
 
+function sortFilenames(urlA, urlB) {
+  const filenameA = (0, _source.getFilenameFromURL)(urlA);
+  const filenameB = (0, _source.getFilenameFromURL)(urlB);
+
+  if (filenameA > filenameB) {
+    return 1;
+  }
+  if (filenameA < filenameB) {
+    return -1;
+  }
+
+  return 0;
+}
+
 class Breakpoints extends _react.Component {
   handleBreakpointCheckbox(breakpoint) {
     if (breakpoint.loading) {
       return;
     }
 
     if (breakpoint.disabled) {
       this.props.enableBreakpoint(breakpoint.location);
@@ -23364,24 +23364,36 @@ class Breakpoints extends _react.Compone
   }
 
   renderBreakpoints() {
     const { breakpoints } = this.props;
     if (breakpoints.size == 0) {
       return;
     }
 
-    const groupedBreakpoints = (0, _lodash.groupBy)((0, _lodash.sortBy)([...breakpoints.valueSeq()], bp => bp.location.line), bp => getBreakpointFilename(bp.source));
-
-    return [...Object.keys(groupedBreakpoints).sort().map(filename => {
+    const groupedBreakpoints = (0, _lodash.groupBy)((0, _lodash.sortBy)([...breakpoints.valueSeq()], bp => bp.location.line), bp => bp.source.url);
+
+    return [...Object.keys(groupedBreakpoints).sort(sortFilenames).map(url => {
+      const file = (0, _source.getFilenameFromURL)(url);
+      const groupBreakpoints = groupedBreakpoints[url].filter(bp => !bp.hidden && (bp.text || bp.originalText));
+
+      if (!groupBreakpoints.length) {
+        return null;
+      }
+
       return [_react2.default.createElement(
         "div",
-        { className: "breakpoint-heading", title: filename, key: filename },
-        filename
-      ), ...groupedBreakpoints[filename].filter(bp => !bp.hidden && bp.text).map(bp => this.renderBreakpoint(bp))];
+        {
+          className: "breakpoint-heading",
+          title: url,
+          key: url,
+          onClick: () => this.props.selectSource(groupBreakpoints[0].source.id)
+        },
+        file
+      ), ...groupBreakpoints.map(bp => this.renderBreakpoint(bp))];
     })];
   }
 
   render() {
     return _react2.default.createElement(
       "div",
       { className: "pane breakpoints-list" },
       this.renderExceptionsOptions(),
@@ -26690,19 +26702,22 @@ var _lodash = __webpack_require__(2);
 
 var _pausePoints = __webpack_require__(3622);
 
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
 
 function findBestMatchExpression(symbols, tokenPos) {
-  const { memberExpressions, identifiers, literals } = symbols;
+  if (symbols.loading) {
+    return null;
+  }
+
   const { line, column } = tokenPos;
-
+  const { memberExpressions, identifiers, literals } = symbols;
   const members = memberExpressions.filter(({ computed }) => !computed);
 
   return [].concat(identifiers, members, literals).reduce((found, expression) => {
     const overlaps = expression.location.start.line == line && expression.location.start.column <= column && expression.location.end.column >= column;
 
     if (overlaps) {
       return expression;
     }
@@ -26761,23 +26776,29 @@ function findClosestofSymbol(declaration
       return found;
     }
 
     return currNode;
   }, null);
 }
 
 function findClosestFunction(symbols, location) {
-  const { functions } = symbols;
-  return findClosestofSymbol(functions, location);
+  if (!symbols || symbols.loading) {
+    return null;
+  }
+
+  return findClosestofSymbol(symbols.functions, location);
 }
 
 function findClosestClass(symbols, location) {
-  const { classes } = symbols;
-  return findClosestofSymbol(classes, location);
+  if (!symbols || symbols.loading) {
+    return null;
+  }
+
+  return findClosestofSymbol(symbols.functions, location);
 }
 
 /***/ }),
 
 /***/ 1639:
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -39241,18 +39262,24 @@ class Breakpoint extends _react.Componen
     return _react2.default.createElement(
       "label",
       { className: "breakpoint-label", title: text },
       text
     );
   }
 
   renderLineClose() {
-    const { breakpoint, onCloseClick } = this.props;
-    const { line, column } = breakpoint.location;
+    const { breakpoint, onCloseClick, selectedSource } = this.props;
+    const { location } = breakpoint;
+
+    let { line, column } = location;
+    if (selectedSource && (0, _devtoolsSourceMap.isGeneratedId)(selectedSource.id) && breakpoint.generatedLocation) {
+      line = breakpoint.generatedLocation.line;
+      column = breakpoint.generatedLocation.column;
+    }
 
     return _react2.default.createElement(
       "div",
       { className: "breakpoint-line-close" },
       _react2.default.createElement(
         "div",
         { className: "breakpoint-line" },
         getBreakpointLocation(breakpoint.source, line, column)
--- a/devtools/client/debugger/new/parser-worker.js
+++ b/devtools/client/debugger/new/parser-worker.js
@@ -19116,16 +19116,17 @@ function tsPrintSignatureDeclarationBase
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
+exports.buildScopeList = undefined;
 exports.default = getScopes;
 exports.clearScopes = clearScopes;
 
 var _visitor = __webpack_require__(2414);
 
 let parsedScopesCache = new Map(); /* This Source Code Form is subject to the terms of the Mozilla Public
                                     * License, v. 2.0. If a copy of the MPL was not distributed with this
                                     * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
@@ -19139,19 +19140,22 @@ function getScopes(location) {
   }
   return parsedScopes ? findScopes(parsedScopes, location) : [];
 }
 
 function clearScopes() {
   parsedScopesCache = new Map();
 }
 
+exports.buildScopeList = _visitor.buildScopeList;
+
 /**
  * Searches all scopes and their bindings at the specific location.
  */
+
 function findScopes(scopes, location) {
   // Find inner most in the tree structure.
   let searchInScopes = scopes;
   const found = [];
   while (searchInScopes) {
     const foundOne = searchInScopes.some(s => {
       if (compareLocations(s.start, location) <= 0 && compareLocations(location, s.end) < 0) {
         // Found the next scope, trying to search recusevly in its children.
@@ -19190,16 +19194,17 @@ function compareLocations(a, b) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.parseSourceScopes = parseSourceScopes;
+exports.buildScopeList = buildScopeList;
 
 var _isEmpty = __webpack_require__(963);
 
 var _isEmpty2 = _interopRequireDefault(_isEmpty);
 
 var _types = __webpack_require__(2268);
 
 var t = _interopRequireWildcard(_types);
@@ -19241,16 +19246,22 @@ function _interopRequireDefault(obj) { r
 // Location information about the expression immediartely surrounding a
 // given binding reference.
 function parseSourceScopes(sourceId) {
   const ast = (0, _ast.getAst)(sourceId);
   if ((0, _isEmpty2.default)(ast)) {
     return null;
   }
 
+  return buildScopeList(ast, sourceId);
+} /* This Source Code Form is subject to the terms of the Mozilla Public
+   * License, v. 2.0. If a copy of the MPL was not distributed with this
+   * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
+
+function buildScopeList(ast, sourceId) {
   const { global, lexical } = createGlobalScope(ast, sourceId);
 
   const state = {
     sourceId,
     freeVariables: new Map(),
     freeVariableStack: [],
     scope: lexical,
     scopeStack: [],
@@ -19274,19 +19285,17 @@ function parseSourceScopes(sourceId) {
   // TODO: This should probably check for ".mjs" extension on the
   // original file, and should also be skipped if the the generated
   // code is an ES6 module rather than a script.
   if ((0, _devtoolsSourceMap.isGeneratedId)(sourceId) || ast.program.sourceType === "script" && !looksLikeCommonJS(global)) {
     stripModuleScope(global);
   }
 
   return toParsedScopes([global], sourceId) || [];
-} /* This Source Code Form is subject to the terms of the Mozilla Public
-   * License, v. 2.0. If a copy of the MPL was not distributed with this
-   * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
+}
 
 function toParsedScopes(children, sourceId) {
   if (!children || children.length === 0) {
     return undefined;
   }
   return children.map(scope => {
     // Removing unneed information from TempScope such as parent reference.
     // We also need to convert BabelLocation to the Location type.
@@ -21345,16 +21354,18 @@ function addBreakPoint(state, location) 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.default = mapOriginalExpression;
 
 var _ast = __webpack_require__(1375);
 
+var _getScopes = __webpack_require__(2413);
+
 var _generator = __webpack_require__(2365);
 
 var _generator2 = _interopRequireDefault(_generator);
 
 var _types = __webpack_require__(2268);
 
 var t = _interopRequireWildcard(_types);
 
@@ -21379,54 +21390,75 @@ function getFirstExpression(ast) {
   const statements = ast.program.body;
   if (statements.length == 0) {
     return null;
   }
 
   return statements[0].expression;
 }
 
+function locationKey(start) {
+  return `${start.line}:${start.column}`;
+}
+
 function mapOriginalExpression(expression, mappings) {
-  let didReplace = false;
-
   const ast = (0, _ast.parseScript)(expression);
-  t.traverse(ast, (node, ancestors) => {
-    const parent = ancestors[ancestors.length - 1];
-    if (!parent) {
-      return;
-    }
-
-    const parentNode = parent.node;
-
-    let name = null;
-    if (t.isIdentifier(node) && t.isReferenced(node, parentNode)) {
-      name = node.name;
-    } else if (t.isThisExpression(node)) {
-      name = "this";
-    } else {
-      return;
-    }
-
-    if (mappings.hasOwnProperty(name)) {
-      const mapping = mappings[name];
-      if (mapping && mapping !== name) {
-        const mappingNode = getFirstExpression((0, _ast.parseScript)(mapping));
-        replaceNode(ancestors, mappingNode);
-
-        didReplace = true;
-      }
-    }
-  });
-
-  if (!didReplace) {
+  const scopes = (0, _getScopes.buildScopeList)(ast, "");
+
+  const nodes = new Map();
+
+  const replacements = new Map();
+
+  // The ref-only global bindings are the ones that are accessed, but not
+  // declared anywhere in the parsed code, meaning they are either global,
+  // or declared somewhere in a scope outside the parsed code, so we
+  // rewrite all of those specifically to avoid rewritting declarations that
+  // shadow outer mappings.
+  for (const name of Object.keys(scopes[0].bindings)) {
+    const { refs } = scopes[0].bindings[name];
+    const mapping = mappings[name];
+    if (!refs.every(ref => ref.type === "ref") || !mapping || mapping === name) {
+      continue;
+    }
+
+    let node = nodes.get(name);
+    if (!node) {
+      node = getFirstExpression((0, _ast.parseScript)(mapping));
+      nodes.set(name, node);
+    }
+
+    for (const ref of refs) {
+      let { line, column } = ref.start;
+
+      // This shouldn't happen, just keeping Flow happy.
+      if (typeof column !== "number") {
+        column = 0;
+      }
+
+      replacements.set(locationKey({ line, column }), node);
+    }
+  }
+
+  if (replacements.size === 0) {
     // Avoid the extra code generation work and also avoid potentially
     // reformatting the user's code unnecessarily.
     return expression;
   }
 
+  t.traverse(ast, (node, ancestors) => {
+    if (!t.isIdentifier(node) && !t.isThisExpression(node)) {
+      return;
+    }
+
+    const replacement = replacements.get(locationKey(node.loc.start));
+    if (replacement) {
+      replaceNode(ancestors, t.cloneNode(replacement));
+    }
+  });
+
   return (0, _generator2.default)(ast).code;
 }
 
 /***/ }),
 
 /***/ 398:
 /***/ (function(module, exports, __webpack_require__) {
 
--- a/devtools/client/dom/test/head.js
+++ b/devtools/client/dom/test/head.js
@@ -52,17 +52,17 @@ function addTestTab(url) {
       });
     });
   });
 }
 
 /**
  * Open the DOM panel for the given tab.
  *
- * @param {nsIDOMElement} tab
+ * @param {Element} tab
  *        Optional tab element for which you want open the DOM panel.
  *        The default tab is taken from the global variable |tab|.
  * @return a promise that is resolved once the web console is open.
  */
 function initDOMPanel(tab) {
   return new Promise(resolve => {
     let target = TargetFactory.forTab(tab || gBrowser.selectedTab);
     gDevTools.showToolbox(target, "dom").then(toolbox => {
--- a/devtools/client/shared/developer-toolbar.js
+++ b/devtools/client/shared/developer-toolbar.js
@@ -757,17 +757,17 @@ DeveloperToolbar.prototype._updateErrors
   }
 
   this.emit("errors-counter-updated");
 };
 
 /**
  * Reset the errors counter for the given tab.
  *
- * @param nsIDOMElement tab The xul:tab for which you want to reset the page
+ * @param Element tab The xul:tab for which you want to reset the page
  * errors counters.
  */
 DeveloperToolbar.prototype.resetErrorsCount = function(tab) {
   let tabId = tab.linkedPanel;
   if (tabId in this._errorsCount || tabId in this._warningsCount) {
     this._errorsCount[tabId] = 0;
     this._warningsCount[tabId] = 0;
     this._updateErrorsCount(tabId);
--- a/devtools/client/shared/test/shared-head.js
+++ b/devtools/client/shared/test/shared-head.js
@@ -481,19 +481,19 @@ function evalInDebuggee(script, browser 
       resolve(data.value);
     }
   });
 }
 
 /**
  * Wait for a context menu popup to open.
  *
- * @param nsIDOMElement popup
+ * @param Element popup
  *        The XUL popup you expect to open.
- * @param nsIDOMElement button
+ * @param Element button
  *        The button/element that receives the contextmenu event. This is
  *        expected to open the popup.
  * @param function onShown
  *        Function to invoke on popupshown event.
  * @param function onHidden
  *        Function to invoke on popuphidden event.
  * @return object
  *         A Promise object that is resolved after the popuphidden event
--- a/devtools/client/webconsole/components/JSTerm.js
+++ b/devtools/client/webconsole/components/JSTerm.js
@@ -245,17 +245,17 @@ class JSTerm extends Component {
    *          Resolves once the changes have been persisted.
    */
   storeHistory() {
     return asyncStorage.setItem("webConsoleHistory", this.history);
   }
 
   /**
    * Getter for the element that holds the messages we display.
-   * @type nsIDOMElement
+   * @type Element
    */
   get outputNode() {
     return this.hud.outputNode;
   }
 
   /**
    * Getter for the debugger WebConsoleClient.
    * @type object
--- a/devtools/client/webconsole/hudservice.js
+++ b/devtools/client/webconsole/hudservice.js
@@ -303,25 +303,25 @@ WebConsole.prototype = {
     if (this.browserWindow) {
       return this.browserWindow;
     }
     return this.chromeWindow.top;
   },
 
   /**
    * Getter for the xul:popupset that holds any popups we open.
-   * @type nsIDOMElement
+   * @type Element
    */
   get mainPopupSet() {
     return this.chromeUtilsWindow.document.getElementById("mainPopupSet");
   },
 
   /**
    * Getter for the output element that holds messages we display.
-   * @type nsIDOMElement
+   * @type Element
    */
   get outputNode() {
     return this.ui ? this.ui.outputNode : null;
   },
 
   get gViewSourceUtils() {
     return this.chromeUtilsWindow.gViewSourceUtils;
   },
--- a/devtools/client/webconsole/test/mochitest/head.js
+++ b/devtools/client/webconsole/test/mochitest/head.js
@@ -442,32 +442,32 @@ async function openInspector(options = {
   const toolbox = await gDevTools.showToolbox(target, "inspector");
 
   return toolbox.getCurrentPanel();
 }
 
 /**
  * Open the Web Console for the given tab, or the current one if none given.
  *
- * @param nsIDOMElement tab
+ * @param Element tab
  *        Optional tab element for which you want open the Web Console.
  *        Defaults to current selected tab.
  * @return Promise
  *         A promise that is resolved with the console hud once the web console is open.
  */
 async function openConsole(tab) {
   let target = TargetFactory.forTab(tab || gBrowser.selectedTab);
   const toolbox = await gDevTools.showToolbox(target, "webconsole");
   return toolbox.getCurrentPanel().hud;
 }
 
 /**
  * Close the Web Console for the given tab.
  *
- * @param nsIDOMElement [tab]
+ * @param Element [tab]
  *        Optional tab element for which you want close the Web Console.
  *        Defaults to current selected tab.
  * @return object
  *         A promise that is resolved once the web console is closed.
  */
 async function closeConsole(tab = gBrowser.selectedTab) {
   let target = TargetFactory.forTab(tab);
   let toolbox = gDevTools.getToolbox(target);
--- a/devtools/client/webconsole/utils.js
+++ b/devtools/client/webconsole/utils.js
@@ -231,18 +231,18 @@ var WebConsoleUtils = {
       WebConsoleUtils._usageCount = newUC;
       Services.prefs.setIntPref("devtools.selfxss.count", newUC);
     }
   },
   /**
    * The inputNode "paste" event handler generator. Helps prevent
    * self-xss attacks
    *
-   * @param nsIDOMElement inputField
-   * @param nsIDOMElement notificationBox
+   * @param Element inputField
+   * @param Element notificationBox
    * @returns A function to be added as a handler to 'paste' and
    *'drop' events on the input field
    */
   pasteHandlerGen: function(inputField, notificationBox, msg, okstring) {
     let handler = function(event) {
       if (WebConsoleUtils.usageCount >= CONSOLE_ENTRY_THRESHOLD) {
         inputField.removeEventListener("paste", handler);
         inputField.removeEventListener("drop", handler);
--- a/devtools/server/actors/inspector/css-logic.js
+++ b/devtools/server/actors/inspector/css-logic.js
@@ -99,17 +99,17 @@ CssLogic.prototype = {
     this._matchedRules = null;
     this._matchedSelectors = null;
     this._keyframesRules = [];
   },
 
   /**
    * Focus on a new element - remove the style caches.
    *
-   * @param {nsIDOMElement} aViewedElement the element the user has highlighted
+   * @param {Element} aViewedElement the element the user has highlighted
    * in the Inspector.
    */
   highlight: function(viewedElement) {
     if (!viewedElement) {
       this.viewedElement = null;
       this.viewedDocument = null;
       this._computedStyle = null;
       this.reset();
@@ -606,17 +606,17 @@ CssLogic.prototype = {
 
 /**
  * If the element has an id, return '#id'. Otherwise return 'tagname[n]' where
  * n is the index of this element in its siblings.
  * <p>A technically more 'correct' output from the no-id case might be:
  * 'tagname:nth-of-type(n)' however this is unlikely to be more understood
  * and it is longer.
  *
- * @param {nsIDOMElement} element the element for which you want the short name.
+ * @param {Element} element the element for which you want the short name.
  * @return {string} the string to be displayed for element.
  */
 CssLogic.getShortName = function(element) {
   if (!element) {
     return "null";
   }
   if (element.id) {
     return "#" + element.id;
--- a/devtools/server/actors/object/previewers.js
+++ b/devtools/server/actors/object/previewers.js
@@ -614,17 +614,17 @@ previewers.Object = [
         for (let node of rawObj.childNodes) {
           let actor = hooks.createValueGrip(obj.makeDebuggeeValue(node));
           preview.childNodes.push(actor);
           if (preview.childNodes.length == OBJECT_PREVIEW_MAX_ITEMS) {
             break;
           }
         }
       }
-    } else if (rawObj instanceof Ci.nsIDOMElement) {
+    } else if (Element.isInstance(rawObj)) {
       // For HTML elements (in an HTML document, at least), the nodeName is an
       // uppercased version of the actual element name.  Check for HTML
       // elements, that is elements in the HTML namespace, and lowercase the
       // nodeName in that case.
       if (rawObj.namespaceURI == "http://www.w3.org/1999/xhtml") {
         preview.nodeName = preview.nodeName.toLowerCase();
       }
 
--- a/devtools/server/actors/webbrowser.js
+++ b/devtools/server/actors/webbrowser.js
@@ -208,17 +208,17 @@ function BrowserTabList(connection) {
 
 BrowserTabList.prototype.constructor = BrowserTabList;
 
 /**
  * Get the selected browser for the given navigator:browser window.
  * @private
  * @param window nsIChromeWindow
  *        The navigator:browser window for which you want the selected browser.
- * @return nsIDOMElement|null
+ * @return Element|null
  *         The currently selected xul:browser element, if any. Note that the
  *         browser window might not be loaded yet - the function will return
  *         |null| in such cases.
  */
 BrowserTabList.prototype._getSelectedBrowser = function(window) {
   return window.gBrowser ? window.gBrowser.selectedBrowser : null;
 };
 
--- a/devtools/server/actors/webconsole/utils.js
+++ b/devtools/server/actors/webconsole/utils.js
@@ -466,17 +466,17 @@ WebConsoleCommands._registerOriginal("cd
     owner.consoleActor.evalWindow = null;
     owner.helperResult = { type: "cd" };
     return;
   }
 
   if (typeof window == "string") {
     window = owner.window.document.querySelector(window);
   }
-  if (window instanceof Ci.nsIDOMElement && window.contentWindow) {
+  if (Element.isInstance(window) && window.contentWindow) {
     window = window.contentWindow;
   }
   if (!(window instanceof Ci.nsIDOMWindow)) {
     owner.helperResult = {
       type: "error",
       message: "cdFunctionInvalidArgument"
     };
     return;
@@ -571,17 +571,17 @@ WebConsoleCommands._registerOriginal("pr
  *
  * @param any value
  *        A value you want to copy as a string.
  * @return void
  */
 WebConsoleCommands._registerOriginal("copy", function(owner, value) {
   let payload;
   try {
-    if (value instanceof Ci.nsIDOMElement) {
+    if (Element.isInstance(value)) {
       payload = value.outerHTML;
     } else if (typeof value == "string") {
       payload = value;
     } else {
       payload = JSON.stringify(value, null, "  ");
     }
   } catch (ex) {
     payload = "/* " + ex + " */";
--- a/devtools/server/main.js
+++ b/devtools/server/main.js
@@ -965,17 +965,17 @@ var DebuggerServer = {
   _childMessageManagers: new Set(),
 
   /**
    * Start a DevTools server in a remote frame's process and add it as a child server for
    * an active connection.
    *
    * @param object connection
    *        The debugger server connection to use.
-   * @param nsIDOMElement frame
+   * @param Element frame
    *        The frame element with remote content to connect to.
    * @param function [onDestroy]
    *        Optional function to invoke when the child process closes
    *        or the connection shuts down. (Need to forget about the
    *        related TabActor)
    * @return object
    *         A promise object that is resolved once the connection is
    *         established.
--- a/devtools/shared/async-utils.js
+++ b/devtools/shared/async-utils.js
@@ -11,17 +11,17 @@
  * returned value. If it throws the promise rejects with the thrown error.
  *
  * See Task documentation at https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/Task.jsm.
  */
 
 /**
  * Adds an event listener to the given element, and then removes its event
  * listener once the event is called, returning the event object as a promise.
- * @param  nsIDOMElement element
+ * @param  Element element
  *         The DOM element to listen on
  * @param  String event
  *         The name of the event type to listen for
  * @param  Boolean useCapture
  *         Should we initiate the capture phase?
  * @return Promise
  *         The promise resolved with the event object when the event first
  *         happens
--- a/devtools/shared/builtin-modules.js
+++ b/devtools/shared/builtin-modules.js
@@ -28,16 +28,17 @@ const {
 // Sandbox are memory expensive, so we should create as little as possible.
 const {
   atob,
   btoa,
   ChromeUtils,
   CSS,
   CSSRule,
   DOMParser,
+  Element,
   Event,
   FileReader,
   FormData,
   indexedDB,
   InspectorUtils,
   TextDecoder,
   TextEncoder,
   URL,
@@ -45,16 +46,17 @@ const {
 } = Cu.Sandbox(CC("@mozilla.org/systemprincipal;1", "nsIPrincipal")(), {
   wantGlobalProperties: [
     "atob",
     "btoa",
     "ChromeUtils",
     "CSS",
     "CSSRule",
     "DOMParser",
+    "Element",
     "Event",
     "FileReader",
     "FormData",
     "indexedDB",
     "TextDecoder",
     "TextEncoder",
     "InspectorUtils",
     "URL",
@@ -262,17 +264,17 @@ exports.globals = {
   //   });
   //
   // Bug 1248830 will work out a better plan here for our content module
   // loading needs, especially as we head towards devtools.html.
   define(factory) {
     factory(this.require, this.exports, this.module);
   },
   DOMParser,
-  Element: Ci.nsIDOMElement,
+  Element,
   Event,
   FormData,
   isWorker: false,
   loader: {
     lazyGetter: defineLazyGetter,
     lazyImporter: defineLazyModuleGetter,
     lazyServiceGetter: defineLazyServiceGetter,
     lazyRequireGetter: lazyRequireGetter,
--- a/devtools/shared/webconsole/network-helper.js
+++ b/devtools/shared/webconsole/network-helper.js
@@ -209,17 +209,17 @@ var NetworkHelper = {
   },
 
   /**
    * Gets the topFrameElement that is associated with request. This
    * works in single-process and multiprocess contexts. It may cross
    * the content/chrome boundary.
    *
    * @param nsIHttpChannel request
-   * @returns nsIDOMElement|null
+   * @returns Element|null
    *          The top frame element for the given request.
    */
   getTopFrameForRequest: function(request) {
     try {
       return this.getRequestLoadContext(request).topFrameElement;
     } catch (ex) {
       // request loadContent is not always available.
     }
--- a/docshell/base/LoadContext.cpp
+++ b/docshell/base/LoadContext.cpp
@@ -3,16 +3,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/Assertions.h"
 #include "mozilla/BasePrincipal.h"
 #include "mozilla/LoadContext.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/dom/Element.h"
 #include "mozilla/dom/ScriptSettings.h" // for AutoJSAPI
 #include "nsContentUtils.h"
 #include "xpcpublic.h"
 
 namespace mozilla {
 
 NS_IMPL_ISUPPORTS(LoadContext, nsILoadContext, nsIInterfaceRequestor)
 
@@ -55,19 +56,19 @@ LoadContext::GetTopWindow(mozIDOMWindowP
 {
   MOZ_ASSERT(mIsNotNull);
 
   // can't support this in the parent process
   return NS_ERROR_UNEXPECTED;
 }
 
 NS_IMETHODIMP
-LoadContext::GetTopFrameElement(nsIDOMElement** aElement)
+LoadContext::GetTopFrameElement(dom::Element** aElement)
 {
-  nsCOMPtr<nsIDOMElement> element = do_QueryReferent(mTopFrameElement);
+  nsCOMPtr<dom::Element> element = do_QueryReferent(mTopFrameElement);
   element.forget(aElement);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 LoadContext::GetNestedFrameId(uint64_t* aId)
 {
   NS_ENSURE_ARG(aId);
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -77,17 +77,16 @@
 #include "nsIContentViewer.h"
 #include "nsIController.h"
 #include "nsICookieService.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsIDocShellTreeOwner.h"
 #include "nsIDocument.h"
 #include "nsIDocumentLoaderFactory.h"
 #include "nsIDOMDocument.h"
-#include "nsIDOMElement.h"
 #include "nsIDOMNode.h"
 #include "nsIDOMStorage.h"
 #include "nsIDOMWindow.h"
 #include "nsIEditingSession.h"
 #include "nsIExternalProtocolService.h"
 #include "nsIFormPOSTActionChannel.h"
 #include "nsIFrame.h"
 #include "nsIGlobalHistory2.h"
@@ -7310,17 +7309,17 @@ nsDocShell::EndPageLoad(nsIWebProgress* 
     }
 
     // Handle iframe document not loading error because source was
     // a tracking URL. We make a note of this iframe node by including
     // it in a dedicated array of blocked tracking nodes under its parent
     // document. (document of parent window of blocked document)
     if (isTopFrame == false && aStatus == NS_ERROR_TRACKING_URI) {
       // frameElement is our nsIContent to be annotated
-      nsCOMPtr<nsIDOMElement> frameElement;
+      RefPtr<Element> frameElement;
       nsPIDOMWindowOuter* thisWindow = GetWindow();
       if (!thisWindow) {
         return NS_OK;
       }
 
       frameElement = thisWindow->GetFrameElement();
       if (!frameElement) {
         return NS_OK;
@@ -7334,18 +7333,17 @@ nsDocShell::EndPageLoad(nsIWebProgress* 
       }
 
       nsCOMPtr<nsIDocument> parentDoc;
       parentDoc = parentItem->GetDocument();
       if (!parentDoc) {
         return NS_OK;
       }
 
-      nsCOMPtr<nsIContent> cont = do_QueryInterface(frameElement);
-      parentDoc->AddBlockedTrackingNode(cont);
+      parentDoc->AddBlockedTrackingNode(frameElement);
 
       return NS_OK;
     }
 
     if (sURIFixup) {
       //
       // Try and make an alternative URI from the old one
       //
@@ -13074,32 +13072,31 @@ nsDocShell::GetTopWindow(mozIDOMWindowPr
   if (win) {
     win = win->GetTop();
   }
   win.forget(aWindow);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDocShell::GetTopFrameElement(nsIDOMElement** aElement)
+nsDocShell::GetTopFrameElement(Element** aElement)
 {
   *aElement = nullptr;
   nsCOMPtr<nsPIDOMWindowOuter> win = GetWindow();
   if (!win) {
     return NS_OK;
   }
 
   nsCOMPtr<nsPIDOMWindowOuter> top = win->GetScriptableTop();
   NS_ENSURE_TRUE(top, NS_ERROR_FAILURE);
 
   // GetFrameElementInternal, /not/ GetScriptableFrameElement -- if |top| is
   // inside <iframe mozbrowser>, we want to return the iframe, not null.
   // And we want to cross the content/chrome boundary.
-  nsCOMPtr<nsIDOMElement> elt =
-    do_QueryInterface(top->GetFrameElementInternal());
+  RefPtr<Element> elt = top->GetFrameElementInternal();
   elt.forget(aElement);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocShell::GetNestedFrameId(uint64_t* aId)
 {
   *aId = 0;
@@ -13697,19 +13694,18 @@ nsDocShell::OnOverLink(nsIContent* aCont
   NS_ConvertUTF8toUTF16 uStr(spec);
 
   mozilla::net::PredictorPredict(aURI, mCurrentURI,
                                  nsINetworkPredictor::PREDICT_LINK,
                                  aContent->NodePrincipal()->OriginAttributesRef(),
                                  nullptr);
 
   if (browserChrome2) {
-    nsCOMPtr<nsIDOMElement> element = do_QueryInterface(aContent);
     rv = browserChrome2->SetStatusWithContext(nsIWebBrowserChrome::STATUS_LINK,
-                                              uStr, element);
+                                              uStr, aContent);
   } else {
     rv = browserChrome->SetStatus(nsIWebBrowserChrome::STATUS_LINK, uStr.get());
   }
   return rv;
 }
 
 NS_IMETHODIMP
 nsDocShell::OnLeaveLink()
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -227,17 +227,17 @@ public:
                         nsIURI* aURI,
                         const char16_t* aTargetSpec) override;
   NS_IMETHOD OnLeaveLink() override;
 
   // Don't use NS_DECL_NSILOADCONTEXT because some of nsILoadContext's methods
   // are shared with nsIDocShell (appID, etc.) and can't be declared twice.
   NS_IMETHOD GetAssociatedWindow(mozIDOMWindowProxy**) override;
   NS_IMETHOD GetTopWindow(mozIDOMWindowProxy**) override;
-  NS_IMETHOD GetTopFrameElement(nsIDOMElement**) override;
+  NS_IMETHOD GetTopFrameElement(mozilla::dom::Element**) override;
   NS_IMETHOD GetNestedFrameId(uint64_t*) override;
   NS_IMETHOD GetIsContent(bool*) override;
   NS_IMETHOD GetUsePrivateBrowsing(bool*) override;
   NS_IMETHOD SetUsePrivateBrowsing(bool) override;
   NS_IMETHOD SetPrivateBrowsing(bool) override;
   NS_IMETHOD GetUseRemoteTabs(bool*) override;
   NS_IMETHOD SetRemoteTabs(bool) override;
   NS_IMETHOD GetScriptableOriginAttributes(JS::MutableHandle<JS::Value>) override;
--- a/docshell/base/nsDocShellTreeOwner.cpp
+++ b/docshell/base/nsDocShellTreeOwner.cpp
@@ -21,17 +21,16 @@
 #include "nsUnicharUtils.h"
 #include "nsISimpleEnumerator.h"
 #include "mozilla/LookAndFeel.h"
 
 // Interfaces needed to be included
 #include "nsPresContext.h"
 #include "nsITooltipListener.h"
 #include "nsIDOMNode.h"
-#include "nsIDOMElement.h"
 #include "Link.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/MouseEvent.h"
 #include "mozilla/dom/SVGTitleElement.h"
 #include "nsIFormControl.h"
 #include "nsIImageLoadingContent.h"
 #include "nsIWebNavigation.h"
 #include "nsIPresShell.h"
--- a/docshell/base/nsILoadContext.idl
+++ b/docshell/base/nsILoadContext.idl
@@ -2,17 +2,18 @@
  * vim: ft=cpp tw=78 sw=2 et ts=2 sts=2 cin
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
 interface mozIDOMWindowProxy;
-interface nsIDOMElement;
+
+webidl Element;
 
 [ref] native OriginAttributes(mozilla::OriginAttributes);
 
 %{C++
 #ifdef MOZILLA_INTERNAL_API
 #include "mozilla/BasePrincipal.h" // for OriginAttributes
 #endif
 %}
@@ -47,17 +48,17 @@ interface nsILoadContext : nsISupports
    * contains the topWindow with which the load is associated.
    *
    * Note that we may have a topFrameElement even when we don't have an
    * associatedWindow, if the topFrameElement's content lives out of process.
    * topFrameElement is available in single-process and multiprocess contexts.
    * Note that topFrameElement may be in chrome even when the nsILoadContext is
    * associated with content.
    */
-  readonly attribute nsIDOMElement topFrameElement;
+  readonly attribute Element topFrameElement;
 
   /**
    * If this LoadContext corresponds to a nested remote iframe, we don't have
    * access to the topFrameElement.  Instead, we must use this id to send
    * messages. A return value of 0 signifies that this load context is not for
    * a nested frame.
    */
   readonly attribute unsigned long long nestedFrameId;
--- a/dom/base/CustomElementRegistry.cpp
+++ b/dom/base/CustomElementRegistry.cpp
@@ -23,19 +23,17 @@ namespace dom {
 // CustomElementUpgradeReaction
 
 class CustomElementUpgradeReaction final : public CustomElementReaction
 {
 public:
   explicit CustomElementUpgradeReaction(CustomElementDefinition* aDefinition)
     : mDefinition(aDefinition)
   {
-#if DEBUG
     mIsUpgradeReaction = true;
-#endif
   }
 
 private:
   virtual void Invoke(Element* aElement, ErrorResult& aRv) override
   {
     CustomElementRegistry::Upgrade(aElement, mDefinition, aRv);
   }
 
@@ -1179,18 +1177,20 @@ CustomElementReactionsStack::Enqueue(Ele
     elementData->mReactionQueue.AppendElement(aReaction);
     return;
   }
 
   // If the custom element reactions stack is empty, then:
   // Add element to the backup element queue.
   MOZ_ASSERT(mReactionsStack.IsEmpty(),
              "custom element reactions stack should be empty");
-  MOZ_ASSERT(!aReaction->IsUpgradeReaction(),
-             "Upgrade reaction should not be scheduled to backup queue");
+  MOZ_ASSERT(!aReaction->IsUpgradeReaction() ||
+             nsContentUtils::IsChromeDoc(aElement->OwnerDoc()),
+             "Upgrade reaction should not be scheduled to backup queue "
+             "except when Custom Element is used inside XBL (in chrome).");
   mBackupQueue.AppendElement(aElement);
   elementData->mReactionQueue.AppendElement(aReaction);
 
   if (mIsBackupQueueProcessing) {
     return;
   }
 
   CycleCollectedJSContext* context = CycleCollectedJSContext::Get();
@@ -1234,27 +1234,38 @@ CustomElementReactionsStack::InvokeReact
       // This happens when the document is destroyed and the element is already
       // unlinked, no need to fire the callbacks in this case.
       continue;
     }
 
     auto& reactions = elementData->mReactionQueue;
     for (uint32_t j = 0; j < reactions.Length(); ++j) {
       // Transfer the ownership of the entry due to reentrant invocation of
-      // this funciton. The entry will be removed when bug 1379573 is landed.
+      // this function.
       auto reaction(Move(reactions.ElementAt(j)));
       if (reaction) {
+        if (!aGlobal && reaction->IsUpgradeReaction()) {
+          // This is for the special case when custom element is included
+          // inside XBL.
+          MOZ_ASSERT(nsContentUtils::IsChromeDoc(element->OwnerDoc()));
+          nsIGlobalObject* global = element->GetOwnerGlobal();
+          MOZ_ASSERT(!aes);
+          aes.emplace(global, "custom elements reaction invocation");
+        }
         ErrorResult rv;
         reaction->Invoke(element, rv);
         if (aes) {
           JSContext* cx = aes->cx();
           if (rv.MaybeSetPendingException(cx)) {
             aes->ReportException();
           }
           MOZ_ASSERT(!JS_IsExceptionPending(cx));
+          if (!aGlobal && reaction->IsUpgradeReaction()) {
+            aes.reset();
+          }
         }
         MOZ_ASSERT(!rv.Failed());
       }
     }
     reactions.Clear();
   }
   aElementQueue->Clear();
 }
--- a/dom/base/CustomElementRegistry.h
+++ b/dom/base/CustomElementRegistry.h
@@ -194,25 +194,23 @@ class CustomElementReaction
 {
 public:
   virtual ~CustomElementReaction() = default;
   virtual void Invoke(Element* aElement, ErrorResult& aRv) = 0;
   virtual void Traverse(nsCycleCollectionTraversalCallback& aCb) const
   {
   }
 
-#if DEBUG
   bool IsUpgradeReaction()
   {
     return mIsUpgradeReaction;
   }
 
 protected:
   bool mIsUpgradeReaction = false;
-#endif
 };
 
 // https://html.spec.whatwg.org/multipage/scripting.html#custom-element-reactions-stack
 class CustomElementReactionsStack
 {
 public:
   NS_INLINE_DECL_REFCOUNTING(CustomElementReactionsStack)
 
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -1,17 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /*
  * Base class for all element classes; this provides an implementation
- * of DOM Core's nsIDOMElement, implements nsIContent, provides
+ * of DOM Core's Element, implements nsIContent, provides
  * utility methods for subclasses, and so forth.
  */
 
 #include "mozilla/dom/ElementInlines.h"
 
 #include "AnimationCommon.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/dom/Animation.h"
--- a/dom/base/Element.h
+++ b/dom/base/Element.h
@@ -1,29 +1,28 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /*
  * Base class for all element classes; this provides an implementation
- * of DOM Core's nsIDOMElement, implements nsIContent, provides
+ * of DOM Core's Element, implements nsIContent, provides
  * utility methods for subclasses, and so forth.
  */
 
 #ifndef mozilla_dom_Element_h__
 #define mozilla_dom_Element_h__
 
 #include "mozilla/dom/FragmentOrElement.h" // for base class
 #include "nsChangeHint.h"                  // for enum
 #include "mozilla/EventStates.h"           // for member
 #include "mozilla/ServoTypes.h"
 #include "mozilla/dom/DirectionalityUtils.h"
-#include "nsIDOMElement.h"
 #include "nsILinkHandler.h"
 #include "nsINodeList.h"
 #include "nsNodeUtils.h"
 #include "nsAttrAndChildArray.h"
 #include "mozilla/FlushType.h"
 #include "nsDOMAttributeMap.h"
 #include "nsPresContext.h"
 #include "mozilla/CORSMode.h"
--- a/dom/base/FragmentOrElement.cpp
+++ b/dom/base/FragmentOrElement.cpp
@@ -1,18 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /*
- * Base class for all element classes; this provides an implementation
- * of DOM Core's nsIDOMElement, implements nsIContent, provides
- * utility methods for subclasses, and so forth.
+ * Base class for all element classes and DocumentFragment.
  */
 
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/Likely.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/StaticPtr.h"
 
 #include "mozilla/dom/FragmentOrElement.h"
--- a/dom/base/FragmentOrElement.h
+++ b/dom/base/FragmentOrElement.h
@@ -65,18 +65,18 @@ public:
 
 private:
   ~nsNodeSupportsWeakRefTearoff() {}
 
   nsCOMPtr<nsINode> mNode;
 };
 
 /**
- * A generic base class for DOM elements, implementing many nsIContent,
- * nsIDOMNode and nsIDOMElement methods.
+ * A generic base class for DOM elements and document fragments,
+ * implementing many nsIContent, nsIDOMNode and Element methods.
  */
 namespace mozilla {
 namespace dom {
 
 class ShadowRoot;
 
 class FragmentOrElement : public nsIContent
 {
--- a/dom/base/IDTracker.cpp
+++ b/dom/base/IDTracker.cpp
@@ -8,17 +8,16 @@
 
 #include "mozilla/Encoding.h"
 #include "nsContentUtils.h"
 #include "nsIURI.h"
 #include "nsBindingManager.h"
 #include "nsEscape.h"
 #include "nsXBLPrototypeBinding.h"
 #include "nsIDOMNode.h"
-#include "nsIDOMElement.h"
 #include "nsCycleCollectionParticipant.h"
 
 namespace mozilla {
 namespace dom {
 
 void
 IDTracker::Reset(nsIContent* aFromContent, nsIURI* aURI,
                  bool aWatch, bool aReferenceImage)
--- a/dom/base/nsAttrAndChildArray.cpp
+++ b/dom/base/nsAttrAndChildArray.cpp
@@ -30,17 +30,17 @@ It should be small enough to not cause c
 large enough to make sure that all indexes are used. The size below is based
 on the size of the smallest possible element (currently 24[*] bytes) which is
 the smallest distance between two nsAttrAndChildArray. 24/(2^_5_) is 0.75.
 This means that two adjacent nsAttrAndChildArrays will overlap one in 4 times.
 However not all elements will have enough children to get cached. And any
 allocator that doesn't return addresses aligned to 64 bytes will ensure that
 any index will get used.
 
-[*] sizeof(Element) + 4 bytes for nsIDOMElement vtable pointer.
+[*] sizeof(Element) + 4 bytes for nsIDOMNode vtable pointer.
 */
 
 #define CACHE_POINTER_SHIFT 5
 #define CACHE_NUM_SLOTS 128
 #define CACHE_CHILD_LIMIT 10
 
 #define CACHE_GET_INDEX(_array) \
   ((NS_PTR_TO_INT32(_array) >> CACHE_POINTER_SHIFT) & \
--- a/dom/base/nsContentPermissionHelper.cpp
+++ b/dom/base/nsContentPermissionHelper.cpp
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include <map>
 #include "nsCOMPtr.h"
-#include "nsIDOMElement.h"
 #include "nsIPrincipal.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/Event.h"
 #include "mozilla/dom/PContentPermission.h"
 #include "mozilla/dom/PermissionMessageUtils.h"
 #include "mozilla/dom/PContentPermissionRequestParent.h"
@@ -641,24 +640,24 @@ nsContentPermissionRequestProxy::GetPrin
     return NS_ERROR_FAILURE;
   }
 
   NS_ADDREF(*aRequestingPrincipal = mParent->mPrincipal);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsContentPermissionRequestProxy::GetElement(nsIDOMElement * *aRequestingElement)
+nsContentPermissionRequestProxy::GetElement(Element** aRequestingElement)
 {
   NS_ENSURE_ARG_POINTER(aRequestingElement);
   if (mParent == nullptr) {
     return NS_ERROR_FAILURE;
   }
 
-  nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(mParent->mElement);
+  nsCOMPtr<Element> elem = mParent->mElement;
   elem.forget(aRequestingElement);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsContentPermissionRequestProxy::GetIsHandlingUserInput(bool* aIsHandlingUserInput)
 {
   NS_ENSURE_ARG_POINTER(aIsHandlingUserInput);
--- a/dom/base/nsContentPolicy.cpp
+++ b/dom/base/nsContentPolicy.cpp
@@ -12,17 +12,16 @@
 
 #include "nsISupports.h"
 #include "nsXPCOM.h"
 #include "nsContentPolicyUtils.h"
 #include "mozilla/dom/nsCSPService.h"
 #include "nsContentPolicy.h"
 #include "nsIURI.h"
 #include "nsIDocShell.h"
-#include "nsIDOMElement.h"
 #include "nsIDOMNode.h"
 #include "nsIDOMWindow.h"
 #include "nsITabChild.h"
 #include "nsIContent.h"
 #include "nsIImageLoadingContent.h"
 #include "nsILoadContext.h"
 #include "nsCOMArray.h"
 #include "nsContentUtils.h"
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -129,17 +129,16 @@
 #include "nsIContentSink.h"
 #include "nsIContentViewer.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeOwner.h"
 #include "nsIDocument.h"
 #include "nsIDocumentEncoder.h"
 #include "nsIDOMChromeWindow.h"
 #include "nsIDOMDocument.h"
-#include "nsIDOMElement.h"
 #include "nsIDOMNode.h"
 #include "nsIDOMWindowUtils.h"
 #include "nsIDragService.h"
 #include "nsIFormControl.h"
 #include "nsIForm.h"
 #include "nsIFragmentContentSink.h"
 #include "nsContainerFrame.h"
 #include "nsIHTMLDocument.h"
@@ -2045,28 +2044,16 @@ nsContentUtils::Shutdown()
  * Checks whether two nodes come from the same origin. aTrustedNode is
  * considered 'safe' in that a user can operate on it and that it isn't
  * a js-object that implements nsIDOMNode.
  * Never call this function with the first node provided by script, it
  * must always be known to be a 'real' node!
  */
 // static
 nsresult
-nsContentUtils::CheckSameOrigin(const nsINode *aTrustedNode,
-                                nsIDOMNode *aUnTrustedNode)
-{
-  MOZ_ASSERT(aTrustedNode);
-
-  // Make sure it's a real node.
-  nsCOMPtr<nsINode> unTrustedNode = do_QueryInterface(aUnTrustedNode);
-  NS_ENSURE_TRUE(unTrustedNode, NS_ERROR_UNEXPECTED);
-  return CheckSameOrigin(aTrustedNode, unTrustedNode);
-}
-
-nsresult
 nsContentUtils::CheckSameOrigin(const nsINode* aTrustedNode,
                                 const nsINode* unTrustedNode)
 {
   MOZ_ASSERT(aTrustedNode);
   MOZ_ASSERT(unTrustedNode);
 
   /*
    * Get hold of each node's principal
@@ -6695,17 +6682,17 @@ nsContentUtils::AllocClassMatchingInfo(n
 }
 
 // static
 bool
 nsContentUtils::IsFocusedContent(const nsIContent* aContent)
 {
   nsFocusManager* fm = nsFocusManager::GetFocusManager();
 
-  return fm && fm->GetFocusedContent() == aContent;
+  return fm && fm->GetFocusedElement() == aContent;
 }
 
 bool
 nsContentUtils::IsSubDocumentTabbable(nsIContent* aContent)
 {
   //XXXsmaug Shadow DOM spec issue!
   //         We may need to change this to GetComposedDoc().
   nsIDocument* doc = aContent->GetUncomposedDoc();
@@ -9707,23 +9694,22 @@ nsContentUtils::GetPresentationURL(nsIDo
       if (tabChild) {
         aPresentationUrl = tabChild->PresentationURL();
       }
       return;
     }
   }
 
   nsCOMPtr<nsILoadContext> loadContext(do_QueryInterface(aDocShell));
-  nsCOMPtr<nsIDOMElement> topFrameElement;
-  loadContext->GetTopFrameElement(getter_AddRefs(topFrameElement));
-  if (!topFrameElement) {
+  RefPtr<Element> topFrameElt;
+  loadContext->GetTopFrameElement(getter_AddRefs(topFrameElt));
+  if (!topFrameElt) {
     return;
   }
 
-  nsCOMPtr<Element> topFrameElt = do_QueryInterface(topFrameElement);
   topFrameElt->GetAttribute(NS_LITERAL_STRING("mozpresentation"), aPresentationUrl);
 }
 
 /* static */ nsIDocShell*
 nsContentUtils::GetDocShellForEventTarget(EventTarget* aTarget)
 {
   nsCOMPtr<nsPIDOMWindowInner> innerWindow;
 
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -586,18 +586,16 @@ public:
   static int32_t ParseLegacyFontSize(const nsAString& aValue);
 
   static void Shutdown();
 
   /**
    * Checks whether two nodes come from the same origin.
    */
   static nsresult CheckSameOrigin(const nsINode* aTrustedNode,
-                                  nsIDOMNode* aUnTrustedNode);
-  static nsresult CheckSameOrigin(const nsINode* aTrustedNode,
                                   const nsINode* unTrustedNode);
 
   // Check if the (JS) caller can access aNode.
   static bool CanCallerAccess(nsIDOMNode *aNode);
   static bool CanCallerAccess(nsINode* aNode);
 
   // Check if the (JS) caller can access aWindow.
   // aWindow can be either outer or inner window.
--- a/dom/base/nsCopySupport.cpp
+++ b/dom/base/nsCopySupport.cpp
@@ -27,17 +27,16 @@
 #include "nsIDocShell.h"
 #include "nsIContentViewerEdit.h"
 #include "nsIClipboardHelper.h"
 #include "nsISelectionController.h"
 
 #include "nsPIDOMWindow.h"
 #include "nsIDocument.h"
 #include "nsIDOMNode.h"
-#include "nsIDOMElement.h"
 #include "nsIDOMDocument.h"
 #include "nsIHTMLDocument.h"
 #include "nsGkAtoms.h"
 #include "nsIFrame.h"
 #include "nsIURI.h"
 #include "nsIURIMutator.h"
 #include "nsISimpleEnumerator.h"
 
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -435,66 +435,60 @@ nsDOMWindowUtils::GetViewportInfo(uint32
   *aHeight = size.height;
   *aAutoSize = info.IsAutoSizeEnabled();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::SetDisplayPortForElement(float aXPx, float aYPx,
                                            float aWidthPx, float aHeightPx,
-                                           nsIDOMElement* aElement,
+                                           Element* aElement,
                                            uint32_t aPriority)
 {
   nsIPresShell* presShell = GetPresShell();
   if (!presShell) {
     return NS_ERROR_FAILURE;
   }
 
   if (!aElement) {
     return NS_ERROR_INVALID_ARG;
   }
 
-  nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
-
-  if (!content) {
-    return NS_ERROR_INVALID_ARG;
-  }
-
-  if (content->GetUncomposedDoc() != presShell->GetDocument()) {
+  if (aElement->GetUncomposedDoc() != presShell->GetDocument()) {
     return NS_ERROR_INVALID_ARG;
   }
 
   DisplayPortPropertyData* currentData =
-    static_cast<DisplayPortPropertyData*>(content->GetProperty(nsGkAtoms::DisplayPort));
+    static_cast<DisplayPortPropertyData*>(aElement->GetProperty(nsGkAtoms::DisplayPort));
   if (currentData && currentData->mPriority > aPriority) {
     return NS_OK;
   }
 
   nsRect displayport(nsPresContext::CSSPixelsToAppUnits(aXPx),
                      nsPresContext::CSSPixelsToAppUnits(aYPx),
                      nsPresContext::CSSPixelsToAppUnits(aWidthPx),
                      nsPresContext::CSSPixelsToAppUnits(aHeightPx));
 
-  content->SetProperty(nsGkAtoms::DisplayPort,
-                       new DisplayPortPropertyData(displayport, aPriority),
-                       nsINode::DeleteProperty<DisplayPortPropertyData>);
+  aElement->SetProperty(nsGkAtoms::DisplayPort,
+                        new DisplayPortPropertyData(displayport, aPriority),
+                        nsINode::DeleteProperty<DisplayPortPropertyData>);
 
   if (gfxPrefs::LayoutUseContainersForRootFrames()) {
     nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
     if (rootScrollFrame &&
-        content == rootScrollFrame->GetContent() &&
+        aElement == rootScrollFrame->GetContent() &&
         nsLayoutUtils::UsesAsyncScrolling(rootScrollFrame))
     {
       // We are setting a root displayport for a document.
       // The pres shell needs a special flag set.
       presShell->SetIgnoreViewportScrolling(true);
     }
   }
 
-  nsLayoutUtils::InvalidateForDisplayPortChange(content, !!currentData,
+  nsLayoutUtils::InvalidateForDisplayPortChange(aElement, !!currentData,
     currentData ? currentData->mRect : nsRect(), displayport);
 
   nsIFrame* rootFrame = presShell->GetRootFrame();
   if (rootFrame) {
     rootFrame->SchedulePaint();
 
     // If we are hiding something that is a display root then send empty paint
     // transaction in order to release retained layers because it won't get
@@ -518,79 +512,67 @@ nsDOMWindowUtils::SetDisplayPortForEleme
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::SetDisplayPortMarginsForElement(float aLeftMargin,
                                                   float aTopMargin,
                                                   float aRightMargin,
                                                   float aBottomMargin,
-                                                  nsIDOMElement* aElement,
+                                                  Element* aElement,
                                                   uint32_t aPriority)
 {
   nsIPresShell* presShell = GetPresShell();
   if (!presShell) {
     return NS_ERROR_FAILURE;
   }
 
   if (!aElement) {
     return NS_ERROR_INVALID_ARG;
   }
 
-  nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
-
-  if (!content) {
-    return NS_ERROR_INVALID_ARG;
-  }
-
-  if (content->GetUncomposedDoc() != presShell->GetDocument()) {
+  if (aElement->GetUncomposedDoc() != presShell->GetDocument()) {
     return NS_ERROR_INVALID_ARG;
   }
 
   // Note order change of arguments between our function signature and
   // ScreenMargin constructor.
   ScreenMargin displayportMargins(aTopMargin,
                                   aRightMargin,
                                   aBottomMargin,
                                   aLeftMargin);
 
-  nsLayoutUtils::SetDisplayPortMargins(content, presShell, displayportMargins,
+  nsLayoutUtils::SetDisplayPortMargins(aElement, presShell, displayportMargins,
                                        aPriority);
 
   return NS_OK;
 }
 
 
 NS_IMETHODIMP
 nsDOMWindowUtils::SetDisplayPortBaseForElement(int32_t aX,
                                                int32_t aY,
                                                int32_t aWidth,
                                                int32_t aHeight,
-                                               nsIDOMElement* aElement)
+                                               Element* aElement)
 {
   nsIPresShell* presShell = GetPresShell();
   if (!presShell) {
     return NS_ERROR_FAILURE;
   }
 
   if (!aElement) {
     return NS_ERROR_INVALID_ARG;
   }
 
-  nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
-
-  if (!content) {
+  if (aElement->GetUncomposedDoc() != presShell->GetDocument()) {
     return NS_ERROR_INVALID_ARG;
   }
 
-  if (content->GetUncomposedDoc() != presShell->GetDocument()) {
-    return NS_ERROR_INVALID_ARG;
-  }
-
-  nsLayoutUtils::SetDisplayPortBase(content, nsRect(aX, aY, aWidth, aHeight));
+  nsLayoutUtils::SetDisplayPortBase(aElement, nsRect(aX, aY, aWidth, aHeight));
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::SetResolution(float aResolution)
 {
   nsIPresShell* presShell = GetPresShell();
@@ -1012,17 +994,17 @@ nsDOMWindowUtils::SendNativeKeyEvent(int
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::SendNativeMouseEvent(int32_t aScreenX,
                                        int32_t aScreenY,
                                        int32_t aNativeMessage,
                                        int32_t aModifierFlags,
-                                       nsIDOMElement* aElement,
+                                       Element* aElement,
                                        nsIObserver* aObserver)
 {
   // get the widget to send the event to
   nsCOMPtr<nsIWidget> widget = GetWidgetForElement(aElement);
   if (!widget)
     return NS_ERROR_FAILURE;
 
   NS_DispatchToMainThread(NativeInputRunnable::Create(
@@ -1035,17 +1017,17 @@ nsDOMWindowUtils::SendNativeMouseEvent(i
       aModifierFlags,
       aObserver)));
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::SendNativeMouseMove(int32_t aScreenX,
                                       int32_t aScreenY,
-                                      nsIDOMElement* aElement,
+                                      Element* aElement,
                                       nsIObserver* aObserver)
 {
   // get the widget to send the event to
   nsCOMPtr<nsIWidget> widget = GetWidgetForElement(aElement);
   if (!widget)
     return NS_ERROR_FAILURE;
 
   NS_DispatchToMainThread(NativeInputRunnable::Create(
@@ -1062,17 +1044,17 @@ NS_IMETHODIMP
 nsDOMWindowUtils::SendNativeMouseScrollEvent(int32_t aScreenX,
                                              int32_t aScreenY,
                                              uint32_t aNativeMessage,
                                              double aDeltaX,
                                              double aDeltaY,
                                              double aDeltaZ,
                                              uint32_t aModifierFlags,
                                              uint32_t aAdditionalFlags,
-                                             nsIDOMElement* aElement,
+                                             Element* aElement,
                                              nsIObserver* aObserver)
 {
   // get the widget to send the event to
   nsCOMPtr<nsIWidget> widget = GetWidgetForElement(aElement);
   if (!widget) {
     return NS_ERROR_FAILURE;
   }
 
@@ -1228,27 +1210,26 @@ nsDOMWindowUtils::GetWidget(nsPoint* aOf
       return nsContentUtils::GetWidget(presShell, aOffset);
     }
   }
 
   return nullptr;
 }
 
 nsIWidget*
-nsDOMWindowUtils::GetWidgetForElement(nsIDOMElement* aElement)
+nsDOMWindowUtils::GetWidgetForElement(Element* aElement)
 {
   if (!aElement)
     return GetWidget();
 
-  nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
-  nsIDocument* doc = content->GetUncomposedDoc();
+  nsIDocument* doc = aElement->GetUncomposedDoc();
   nsIPresShell* presShell = doc ? doc->GetShell() : nullptr;
 
   if (presShell) {
-    nsIFrame* frame = content->GetPrimaryFrame();
+    nsIFrame* frame = aElement->GetPrimaryFrame();
     if (!frame) {
       frame = presShell->GetRootFrame();
     }
     if (frame)
       return frame->GetNearestWidget();
   }
 
   return nullptr;
@@ -1349,25 +1330,24 @@ nsDOMWindowUtils::SendSimpleGestureEvent
   nsEventStatus status;
   return widget->DispatchEvent(&event, status);
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::ElementFromPoint(float aX, float aY,
                                    bool aIgnoreRootScrollFrame,
                                    bool aFlushLayout,
-                                   nsIDOMElement** aReturn)
+                                   Element** aReturn)
 {
   nsCOMPtr<nsIDocument> doc = GetDocument();
   NS_ENSURE_STATE(doc);
 
-  Element* el =
+  RefPtr<Element> el =
     doc->ElementFromPointHelper(aX, aY, aIgnoreRootScrollFrame, aFlushLayout);
-  nsCOMPtr<nsIDOMElement> retval = do_QueryInterface(el);
-  retval.forget(aReturn);
+  el.forget(aReturn);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::NodesFromRect(float aX, float aY,
                                 float aTopSize, float aRightSize,
                                 float aBottomSize, float aLeftSize,
                                 bool aIgnoreRootScrollFrame,
@@ -1664,28 +1644,26 @@ nsDOMWindowUtils::GetScrollbarSize(bool 
   nsMargin sizes = scrollFrame->GetActualScrollbarSizes();
   *aWidth = nsPresContext::AppUnitsToIntCSSPixels(sizes.LeftRight());
   *aHeight = nsPresContext::AppUnitsToIntCSSPixels(sizes.TopBottom());
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMWindowUtils::GetBoundsWithoutFlushing(nsIDOMElement *aElement,
+nsDOMWindowUtils::GetBoundsWithoutFlushing(Element *aElement,
                                            DOMRect** aResult)
 {
   nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
   NS_ENSURE_STATE(window);
 
-  nsresult rv;
-  nsCOMPtr<nsIContent> content = do_QueryInterface(aElement, &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
+  NS_ENSURE_ARG_POINTER(aElement);
 
   RefPtr<DOMRect> rect = new DOMRect(window);
-  nsIFrame* frame = content->GetPrimaryFrame();
+  nsIFrame* frame = aElement->GetPrimaryFrame();
 
   if (frame) {
     nsRect r = nsLayoutUtils::GetAllInFlowRectsUnion(frame,
                nsLayoutUtils::GetContainingBlockForClientRect(frame),
                nsLayoutUtils::RECTS_ACCOUNT_FOR_TRANSFORMS);
     rect->SetLayoutRect(r);
   }
 
@@ -1811,20 +1789,19 @@ nsDOMWindowUtils::GetFocusedInputType(ns
     return NS_ERROR_FAILURE;
   }
 
   aType = widget->GetInputContext().mHTMLInputType;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMWindowUtils::GetViewId(nsIDOMElement* aElement, nsViewID* aResult)
+nsDOMWindowUtils::GetViewId(Element* aElement, nsViewID* aResult)
 {
-  nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
-  if (content && nsLayoutUtils::FindIDFor(content, aResult)) {
+  if (aElement && nsLayoutUtils::FindIDFor(aElement, aResult)) {
     return NS_OK;
   }
   return NS_ERROR_NOT_AVAILABLE;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::GetScreenPixelsPerCSSPixel(float* aScreenPixels)
 {
@@ -2149,31 +2126,30 @@ nsDOMWindowUtils::GetClassName(JS::Handl
 
   *aName = NS_strdup(JS_GetClass(aObject.toObjectOrNull())->name);
   MOZ_ASSERT(*aName, "NS_strdup should be infallible.");
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::GetVisitedDependentComputedStyle(
-                    nsIDOMElement *aElement, const nsAString& aPseudoElement,
+                    Element *aElement, const nsAString& aPseudoElement,
                     const nsAString& aPropertyName, nsAString& aResult)
 {
   aResult.Truncate();
 
   nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
-  nsCOMPtr<Element> element = do_QueryInterface(aElement);
-  NS_ENSURE_STATE(window && element);
+  NS_ENSURE_STATE(window && aElement);
   nsCOMPtr<nsPIDOMWindowInner> innerWindow = window->GetCurrentInnerWindow();
   NS_ENSURE_STATE(window);
 
   nsCOMPtr<nsICSSDeclaration> decl;
   {
     ErrorResult rv;
-    decl = innerWindow->GetComputedStyle(*element, aPseudoElement, rv);
+    decl = innerWindow->GetComputedStyle(*aElement, aPseudoElement, rv);
     ENSURE_SUCCESS(rv, rv.StealNSResult());
   }
 
   static_cast<nsComputedDOMStyle*>(decl.get())->SetExposeVisitedStyle(true);
   nsresult rv = decl->GetPropertyValue(aPropertyName, aResult);
   static_cast<nsComputedDOMStyle*>(decl.get())->SetExposeVisitedStyle(false);
 
   return rv;
@@ -2641,17 +2617,17 @@ nsDOMWindowUtils::ZoomToFocusedInput()
     return NS_OK;
   }
 
   nsFocusManager* fm = nsFocusManager::GetFocusManager();
   if (!fm) {
     return NS_OK;
   }
 
-  nsIContent* content = fm->GetFocusedContent();
+  nsIContent* content = fm->GetFocusedElement();
   if (!content) {
     return NS_OK;
   }
 
   nsIPresShell* shell = APZCCallbackHelper::GetRootContentDocumentPresShellForContent(content);
   if (!shell) {
     return NS_OK;
   }
@@ -2707,86 +2683,82 @@ nsDOMWindowUtils::ZoomToFocusedInput()
     bounds.Inflate(15.0f, 0.0f);
     widget->ZoomToRect(presShellId, viewId, bounds, flags);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMWindowUtils::ComputeAnimationDistance(nsIDOMElement* aElement,
+nsDOMWindowUtils::ComputeAnimationDistance(Element* aElement,
                                            const nsAString& aProperty,
                                            const nsAString& aValue1,
                                            const nsAString& aValue2,
                                            double* aResult)
 {
-  nsresult rv;
-  nsCOMPtr<nsIContent> content = do_QueryInterface(aElement, &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
+  NS_ENSURE_ARG_POINTER(aElement);
 
   nsCSSPropertyID property =
     nsCSSProps::LookupProperty(aProperty, CSSEnabledState::eIgnoreEnabledState);
   if (property == eCSSProperty_UNKNOWN ||
       nsCSSProps::IsShorthand(property)) {
     return NS_ERROR_ILLEGAL_VALUE;
   }
 
-  Element* element = content->AsElement();
-  AnimationValue v1 = AnimationValue::FromString(property, aValue1, element);
-  AnimationValue v2 = AnimationValue::FromString(property, aValue2, element);
+  AnimationValue v1 = AnimationValue::FromString(property, aValue1, aElement);
+  AnimationValue v2 = AnimationValue::FromString(property, aValue2, aElement);
   if (v1.IsNull() || v2.IsNull()) {
     return NS_ERROR_ILLEGAL_VALUE;
   }
 
   RefPtr<ComputedStyle> computedStyle =
-    nsComputedDOMStyle::GetComputedStyle(element, nullptr);
+    nsComputedDOMStyle::GetComputedStyle(aElement, nullptr);
   *aResult = v1.ComputeDistance(property, v2, computedStyle);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMWindowUtils::GetUnanimatedComputedStyle(nsIDOMElement* aElement,
+nsDOMWindowUtils::GetUnanimatedComputedStyle(Element* aElement,
                                              const nsAString& aPseudoElement,
                                              const nsAString& aProperty,
                                              int32_t aFlushType,
                                              nsAString& aResult)
 {
-  nsCOMPtr<Element> element = do_QueryInterface(aElement);
-  if (!element) {
+  if (!aElement) {
     return NS_ERROR_INVALID_ARG;
   }
 
   nsCSSPropertyID propertyID =
     nsCSSProps::LookupProperty(aProperty, CSSEnabledState::eForAllContent);
   if (propertyID == eCSSProperty_UNKNOWN ||
       nsCSSProps::IsShorthand(propertyID)) {
     return NS_ERROR_INVALID_ARG;
   }
 
   switch (aFlushType) {
     case FLUSH_NONE:
       break;
     case FLUSH_STYLE: {
-      if (nsIDocument* doc = element->GetComposedDoc()) {
+      if (nsIDocument* doc = aElement->GetComposedDoc()) {
         doc->FlushPendingNotifications(FlushType::Style);
       }
       break;
     }
     default:
       return NS_ERROR_INVALID_ARG;
   }
 
   nsIPresShell* shell = GetPresShell();
   if (!shell) {
     return NS_ERROR_FAILURE;
   }
 
   RefPtr<nsAtom> pseudo = nsCSSPseudoElements::GetPseudoAtom(aPseudoElement);
   RefPtr<ComputedStyle> computedStyle =
-    nsComputedDOMStyle::GetUnanimatedComputedStyleNoFlush(element, pseudo);
+    nsComputedDOMStyle::GetUnanimatedComputedStyleNoFlush(aElement, pseudo);
   if (!computedStyle) {
     return NS_ERROR_FAILURE;
   }
 
   RefPtr<RawServoAnimationValue> value =
     Servo_ComputedValues_ExtractAnimationValue(computedStyle,
                                                propertyID).Consume();
   if (!value) {
@@ -2821,24 +2793,22 @@ nsDOMWindowUtils::GetDisplayDPI(float *a
     return NS_ERROR_FAILURE;
 
   *aDPI = widget->GetDPI();
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMWindowUtils::GetContainerElement(nsIDOMElement** aResult)
+nsDOMWindowUtils::GetContainerElement(Element** aResult)
 {
   nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
   NS_ENSURE_STATE(window);
 
-  nsCOMPtr<nsIDOMElement> element =
-    do_QueryInterface(window->GetFrameElementInternal());
-
+  RefPtr<Element> element = window->GetFrameElementInternal();
   element.forget(aResult);
   return NS_OK;
 }
 
 #ifdef DEBUG
 static bool
 CheckLeafLayers(Layer* aLayer, const nsIntPoint& aOffset, nsIntRegion* aCoveredRegion)
 {
@@ -2896,94 +2866,82 @@ nsDOMWindowUtils::LeafLayersPartitionWin
   if (!coveredRegion.IsEqual(root->GetVisibleRegion().ToUnknownRegion())) {
     *aResult = false;
   }
 #endif
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMWindowUtils::CheckAndClearPaintedState(nsIDOMElement* aElement, bool* aResult)
+nsDOMWindowUtils::CheckAndClearPaintedState(Element* aElement, bool* aResult)
 {
   if (!aElement) {
     return NS_ERROR_INVALID_ARG;
   }
 
-  nsresult rv;
-  nsCOMPtr<nsIContent> content = do_QueryInterface(aElement, &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsIFrame* frame = content->GetPrimaryFrame();
+  nsIFrame* frame = aElement->GetPrimaryFrame();
 
   if (!frame) {
     *aResult = false;
     return NS_OK;
   }
 
   // Get the outermost frame for the content node, so that we can test
   // canvasframe invalidations by observing the documentElement.
   for (;;) {
     nsIFrame* parentFrame = frame->GetParent();
-    if (parentFrame && parentFrame->GetContent() == content) {
+    if (parentFrame && parentFrame->GetContent() == aElement) {
       frame = parentFrame;
     } else {
       break;
     }
   }
 
   *aResult = frame->CheckAndClearPaintedState();
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMWindowUtils::CheckAndClearDisplayListState(nsIDOMElement* aElement, bool* aResult)
+nsDOMWindowUtils::CheckAndClearDisplayListState(Element* aElement, bool* aResult)
 {
   if (!aElement) {
     return NS_ERROR_INVALID_ARG;
   }
 
-  nsresult rv;
-  nsCOMPtr<nsIContent> content = do_QueryInterface(aElement, &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsIFrame* frame = content->GetPrimaryFrame();
+  nsIFrame* frame = aElement->GetPrimaryFrame();
 
   if (!frame) {
     *aResult = false;
     return NS_OK;
   }
 
   // Get the outermost frame for the content node, so that we can test
   // canvasframe invalidations by observing the documentElement.
   for (;;) {
     nsIFrame* parentFrame = frame->GetParent();
-    if (parentFrame && parentFrame->GetContent() == content) {
+    if (parentFrame && parentFrame->GetContent() == aElement) {
       frame = parentFrame;
     } else {
       break;
     }
   }
 
   *aResult = frame->CheckAndClearDisplayListState();
   return NS_OK;
 
 }
 
 NS_IMETHODIMP
-nsDOMWindowUtils::IsPartOfOpaqueLayer(nsIDOMElement* aElement, bool* aResult)
+nsDOMWindowUtils::IsPartOfOpaqueLayer(Element* aElement, bool* aResult)
 {
   if (!aElement) {
     return NS_ERROR_INVALID_ARG;
   }
 
-  nsresult rv;
-  nsCOMPtr<nsIContent> content = do_QueryInterface(aElement, &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsIFrame* frame = content->GetPrimaryFrame();
+  nsIFrame* frame = aElement->GetPrimaryFrame();
   if (!frame) {
     return NS_ERROR_FAILURE;
   }
 
   ColorLayer* colorLayer = FrameLayerBuilder::GetDebugSingleOldLayerForFrame<ColorLayer>(frame);
   if (colorLayer) {
     auto color = colorLayer->GetColor();
     *aResult = color.a == 1.0f;
@@ -2995,31 +2953,27 @@ nsDOMWindowUtils::IsPartOfOpaqueLayer(ns
     *aResult = paintedLayer->IsOpaque();
     return NS_OK;
   }
 
   return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
-nsDOMWindowUtils::NumberOfAssignedPaintedLayers(nsIDOMElement** aElements,
+nsDOMWindowUtils::NumberOfAssignedPaintedLayers(Element** aElements,
                                                 uint32_t aCount,
                                                 uint32_t* aResult)
 {
   if (!aElements) {
     return NS_ERROR_INVALID_ARG;
   }
 
   nsTHashtable<nsPtrHashKey<PaintedLayer>> layers;
-  nsresult rv;
   for (uint32_t i = 0; i < aCount; i++) {
-    nsCOMPtr<nsIContent> content = do_QueryInterface(aElements[i], &rv);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    nsIFrame* frame = content->GetPrimaryFrame();
+    nsIFrame* frame = aElements[i]->GetPrimaryFrame();
     if (!frame) {
       return NS_ERROR_FAILURE;
     }
 
     PaintedLayer* layer = FrameLayerBuilder::GetDebugSingleOldLayerForFrame<PaintedLayer>(frame);
     if (!layer) {
       return NS_ERROR_FAILURE;
     }
@@ -3276,17 +3230,17 @@ nsDOMWindowUtils::SetScrollPositionClamp
   }
 
   nsLayoutUtils::SetScrollPositionClampingScrollPortSize(presShell, CSSSize(aWidth, aHeight));
 
   return NS_OK;
 }
 
 nsresult
-nsDOMWindowUtils::RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement)
+nsDOMWindowUtils::RemoteFrameFullscreenChanged(Element* aFrameElement)
 {
   nsCOMPtr<nsIDocument> doc = GetDocument();
   NS_ENSURE_STATE(doc);
 
   doc->RemoteFrameFullscreenChanged(aFrameElement);
   return NS_OK;
 }
 
@@ -3674,33 +3628,32 @@ nsDOMWindowUtils::RequestCompositorPrope
       return NS_OK;
     }
   }
 
   return NS_ERROR_NOT_AVAILABLE;
 }
 
 NS_IMETHODIMP
-nsDOMWindowUtils::GetOMTAStyle(nsIDOMElement* aElement,
+nsDOMWindowUtils::GetOMTAStyle(Element* aElement,
                                const nsAString& aProperty,
                                const nsAString& aPseudoElement,
                                nsAString& aResult)
 {
-  nsCOMPtr<Element> element = do_QueryInterface(aElement);
-  if (!element) {
+  if (!aElement) {
     return NS_ERROR_INVALID_ARG;
   }
 
   RefPtr<nsROCSSPrimitiveValue> cssValue = nullptr;
-  nsIFrame* frame = element->GetPrimaryFrame();
+  nsIFrame* frame = aElement->GetPrimaryFrame();
   if (!aPseudoElement.IsEmpty()) {
     if (aPseudoElement.EqualsLiteral("::before")) {
-      frame = nsLayoutUtils::GetBeforeFrame(element);
+      frame = nsLayoutUtils::GetBeforeFrame(aElement);
     } else if (aPseudoElement.EqualsLiteral("::after")) {
-      frame = nsLayoutUtils::GetAfterFrame(element);
+      frame = nsLayoutUtils::GetAfterFrame(aElement);
     } else {
       return NS_ERROR_INVALID_ARG;
     }
   }
   if (frame && nsLayoutUtils::AreAsyncAnimationsEnabled()) {
     RefPtr<LayerManager> widgetLayerManager;
     if (nsIWidget* widget = GetWidget()) {
       widgetLayerManager = widget->GetLayerManager();
@@ -3883,24 +3836,23 @@ nsDOMWindowUtils::GetCompositorAPZTestDa
       return NS_ERROR_FAILURE;
     }
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMWindowUtils::PostRestyleSelfEvent(nsIDOMElement* aElement)
+nsDOMWindowUtils::PostRestyleSelfEvent(Element* aElement)
 {
-  nsCOMPtr<Element> element = do_QueryInterface(aElement);
-  if (!element) {
+  if (!aElement) {
     return NS_ERROR_INVALID_ARG;
   }
 
-  nsLayoutUtils::PostRestyleEvent(element, eRestyle_Self, nsChangeHint(0));
+  nsLayoutUtils::PostRestyleEvent(aElement, eRestyle_Self, nsChangeHint(0));
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::GetMediaSuspend(uint32_t* aSuspend)
 {
   nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
   NS_ENSURE_STATE(window);
@@ -4223,48 +4175,46 @@ GetEventStateForString(const nsAString& 
     if (aStateString.EqualsASCII(entry->mStateString)) {
       return entry->mState;
     }
   }
   return EventStates();
 }
 
 NS_IMETHODIMP
-nsDOMWindowUtils::AddManuallyManagedState(nsIDOMElement* aElement,
+nsDOMWindowUtils::AddManuallyManagedState(Element* aElement,
                                           const nsAString& aStateString)
 {
-  nsCOMPtr<Element> element = do_QueryInterface(aElement);
-  if (!element) {
+  if (!aElement) {
     return NS_ERROR_INVALID_ARG;
   }
 
   EventStates state = GetEventStateForString(aStateString);
   if (state.IsEmpty()) {
     return NS_ERROR_INVALID_ARG;
   }
 
-  element->AddManuallyManagedStates(state);
+  aElement->AddManuallyManagedStates(state);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMWindowUtils::RemoveManuallyManagedState(nsIDOMElement* aElement,
+nsDOMWindowUtils::RemoveManuallyManagedState(Element* aElement,
                                              const nsAString& aStateString)
 {
-  nsCOMPtr<Element> element = do_QueryInterface(aElement);
-  if (!element) {
+  if (!aElement) {
     return NS_ERROR_INVALID_ARG;
   }
 
   EventStates state = GetEventStateForString(aStateString);
   if (state.IsEmpty()) {
     return NS_ERROR_INVALID_ARG;
   }
 
-  element->RemoveManuallyManagedStates(state);
+  aElement->RemoveManuallyManagedStates(state);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::GetStorageUsage(nsIDOMStorage* aStorage, int64_t* aRetval)
 {
   RefPtr<Storage> storage = static_cast<Storage*>(aStorage);
   if (!storage) {
--- a/dom/base/nsDOMWindowUtils.h
+++ b/dom/base/nsDOMWindowUtils.h
@@ -17,16 +17,19 @@ class nsGlobalWindowOuter;
 class nsIPresShell;
 class nsIWidget;
 class nsPresContext;
 class nsIDocument;
 class nsView;
 struct nsPoint;
 
 namespace mozilla {
+  namespace dom {
+    class Element;
+  } // namespace dom
   namespace layers {
     class LayerTransactionChild;
     class WebRenderBridgeChild;
   } // namespace layers
 } // namespace mozilla
 
 class nsTranslationNodeList final : public nsITranslationNodeList
 {
@@ -71,17 +74,17 @@ protected:
 
   nsWeakPtr mWindow;
 
   // If aOffset is non-null, it gets filled in with the offset of the root
   // frame of our window to the nearest widget in the app units of our window.
   // Add this offset to any event offset we're given to make it relative to the
   // widget returned by GetWidget.
   nsIWidget* GetWidget(nsPoint* aOffset = nullptr);
-  nsIWidget* GetWidgetForElement(nsIDOMElement* aElement);
+  nsIWidget* GetWidgetForElement(mozilla::dom::Element* aElement);
 
   nsIPresShell* GetPresShell();
   nsPresContext* GetPresContext();
   nsIDocument* GetDocument();
   mozilla::layers::LayerTransactionChild* GetLayerTransaction();
   mozilla::layers::WebRenderBridgeChild* GetWebRenderBridge();
 
   // Until callers are annotated.
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -108,17 +108,16 @@
 #include "nsIScriptSecurityManager.h"
 #include "nsIPermissionManager.h"
 #include "nsIPrincipal.h"
 #include "ExpandedPrincipal.h"
 #include "NullPrincipal.h"
 
 #include "nsIDOMWindow.h"
 #include "nsPIDOMWindow.h"
-#include "nsIDOMElement.h"
 #include "nsFocusManager.h"
 
 // for radio group stuff
 #include "nsIRadioVisitor.h"
 #include "nsIFormControl.h"
 
 #include "nsBidiUtils.h"
 
@@ -9351,17 +9350,17 @@ public:
       FindTopWindowForElement(mElement);
     if (currentTopWindow != mTopWindow) {
       // The element's top window changed from when the event was queued.
       // Don't take away focus from an unrelated window.
       return NS_OK;
     }
 
     // Don't steal focus from the user.
-    if (mTopWindow->GetFocusedNode()) {
+    if (mTopWindow->GetFocusedElement()) {
       return NS_OK;
     }
 
     mozilla::ErrorResult rv;
     mElement->Focus(rv);
     return rv.StealNSResult();
   }
 private:
@@ -10941,23 +10940,22 @@ IsInActiveTab(nsIDocument* aDoc)
   fm->GetActiveWindow(getter_AddRefs(activeWindow));
   if (!activeWindow) {
     return false;
   }
 
   return activeWindow == rootWin;
 }
 
-nsresult nsIDocument::RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement)
+nsresult nsIDocument::RemoteFrameFullscreenChanged(Element* aFrameElement)
 {
   // Ensure the frame element is the fullscreen element in this document.
   // If the frame element is already the fullscreen element in this document,
   // this has no effect.
-  nsCOMPtr<nsIContent> content(do_QueryInterface(aFrameElement));
-  auto request = MakeUnique<FullscreenRequest>(content->AsElement());
+  auto request = MakeUnique<FullscreenRequest>(aFrameElement);
   request->mIsCallerChrome = false;
   request->mShouldNotifyNewOrigin = false;
   RequestFullScreen(Move(request));
 
   return NS_OK;
 }
 
 nsresult nsIDocument::RemoteFrameFullscreenReverted()
@@ -11051,29 +11049,24 @@ nsIDocument::FullscreenElementReadyCheck
     DispatchFullscreenError("FullscreenDeniedNotDescendant");
     return false;
   }
   if (!nsContentUtils::IsChromeDoc(this) && !IsInActiveTab(this)) {
     DispatchFullscreenError("FullscreenDeniedNotFocusedTab");
     return false;
   }
   // Deny requests when a windowed plugin is focused.
-  nsIFocusManager* fm = nsFocusManager::GetFocusManager();
+  nsFocusManager* fm = nsFocusManager::GetFocusManager();
   if (!fm) {
     NS_WARNING("Failed to retrieve focus manager in full-screen request.");
     return false;
   }
-  nsCOMPtr<nsIDOMElement> focusedElement;
-  fm->GetFocusedElement(getter_AddRefs(focusedElement));
-  if (focusedElement) {
-    nsCOMPtr<nsIContent> content = do_QueryInterface(focusedElement);
-    if (nsContentUtils::HasPluginWithUncontrolledEventDispatch(content)) {
-      DispatchFullscreenError("FullscreenDeniedFocusedPlugin");
-      return false;
-    }
+  if (nsContentUtils::HasPluginWithUncontrolledEventDispatch(fm->GetFocusedElement())) {
+    DispatchFullscreenError("FullscreenDeniedFocusedPlugin");
+    return false;
   }
   return true;
 }
 
 FullscreenRequest::FullscreenRequest(Element* aElement)
   : mElement(aElement)
   , mDocument(static_cast<nsDocument*>(aElement->OwnerDoc()))
 {
--- a/dom/base/nsDocumentEncoder.cpp
+++ b/dom/base/nsDocumentEncoder.cpp
@@ -15,17 +15,16 @@
 #include "nsIFactory.h"
 #include "nsISupports.h"
 #include "nsIDocument.h"
 #include "nsIHTMLDocument.h"
 #include "nsCOMPtr.h"
 #include "nsIContentSerializer.h"
 #include "mozilla/Encoding.h"
 #include "nsIOutputStream.h"
-#include "nsIDOMElement.h"
 #include "nsRange.h"
 #include "nsIDOMDocument.h"
 #include "nsGkAtoms.h"
 #include "nsIContent.h"
 #include "nsIScriptContext.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIScriptSecurityManager.h"
 #include "mozilla/dom/Selection.h"
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -13,17 +13,16 @@
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsGkAtoms.h"
 #include "nsGlobalWindow.h"
 #include "nsContentUtils.h"
 #include "nsDocument.h"
 #include "nsIContentParent.h"
 #include "nsPIDOMWindow.h"
 #include "nsIDOMChromeWindow.h"
-#include "nsIDOMElement.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMRange.h"
 #include "nsIHTMLDocument.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeOwner.h"
 #include "nsIFormControl.h"
 #include "nsLayoutUtils.h"
 #include "nsIPresShell.h"
@@ -160,17 +159,17 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsFocusManager)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsFocusManager)
 
 NS_IMPL_CYCLE_COLLECTION(nsFocusManager,
                          mActiveWindow,
                          mFocusedWindow,
-                         mFocusedContent,
+                         mFocusedElement,
                          mFirstBlurEvent,
                          mFirstFocusEvent,
                          mWindowBeingLowered,
                          mDelayedBlurFocusEvents,
                          mMouseButtonEventHandlingDocument)
 
 nsFocusManager* nsFocusManager::sInstance = nullptr;
 bool nsFocusManager::sMouseFocusesFormControl = false;
@@ -253,17 +252,17 @@ nsFocusManager::Observe(nsISupports *aSu
                              false);
     }
     else if (data.EqualsLiteral("focusmanager.testmode")) {
       sTestMode = Preferences::GetBool("focusmanager.testmode", false);
     }
   } else if (!nsCRT::strcmp(aTopic, "xpcom-shutdown")) {
     mActiveWindow = nullptr;
     mFocusedWindow = nullptr;
-    mFocusedContent = nullptr;
+    mFocusedElement = nullptr;
     mFirstBlurEvent = nullptr;
     mFirstFocusEvent = nullptr;
     mWindowBeingLowered = nullptr;
     mDelayedBlurFocusEvents.Clear();
     mMouseButtonEventHandlingDocument = nullptr;
   }
 
   return NS_OK;
@@ -281,20 +280,20 @@ GetContentWindow(nsIContent* aContent)
   }
 
   return nullptr;
 }
 
 bool
 nsFocusManager::IsFocused(nsIContent* aContent)
 {
-  if (!aContent || !mFocusedContent) {
+  if (!aContent || !mFocusedElement) {
     return false;
   }
-  return aContent == mFocusedContent.get();
+  return aContent == mFocusedElement;
 }
 
 // get the current window for the given content node
 static nsPIDOMWindowOuter*
 GetCurrentWindow(nsIContent* aContent)
 {
   nsIDocument* doc = aContent->GetComposedDoc();
   return doc ? doc->GetWindow() : nullptr;
@@ -305,26 +304,26 @@ Element*
 nsFocusManager::GetFocusedDescendant(nsPIDOMWindowOuter* aWindow,
                                      SearchRange aSearchRange,
                                      nsPIDOMWindowOuter** aFocusedWindow)
 {
   NS_ENSURE_TRUE(aWindow, nullptr);
 
   *aFocusedWindow = nullptr;
 
-  Element* currentContent = nullptr;
+  Element* currentElement = nullptr;
   nsPIDOMWindowOuter* window = aWindow;
   for (;;) {
     *aFocusedWindow = window;
-    currentContent = window->GetFocusedNode();
-    if (!currentContent || aSearchRange == eOnlyCurrentWindow) {
+    currentElement = window->GetFocusedElement();
+    if (!currentElement || aSearchRange == eOnlyCurrentWindow) {
       break;
     }
 
-    window = GetContentWindow(currentContent);
+    window = GetContentWindow(currentElement);
     if (!window) {
       break;
     }
 
     if (aSearchRange == eIncludeAllDescendants) {
       continue;
     }
 
@@ -339,17 +338,17 @@ nsFocusManager::GetFocusedDescendant(nsP
     nsIPresShell* presShell = docShell->GetPresShell();
     if (!presShell) {
       break;
     }
   }
 
   NS_IF_ADDREF(*aFocusedWindow);
 
-  return currentContent;
+  return currentElement;
 }
 
 // static
 Element*
 nsFocusManager::GetRedirectedFocus(nsIContent* aContent)
 {
   // For input number, redirect focus to our anonymous text control.
   if (aContent->IsHTMLElement(nsGkAtoms::input)) {
@@ -462,39 +461,37 @@ NS_IMETHODIMP nsFocusManager::SetFocused
     // and scrolling does not occur.
     SetFocusInner(frameElement, 0, false, true);
   }
   else {
     // this is a top-level window. If the window has a child frame focused,
     // clear the focus. Otherwise, focus should already be in this frame, or
     // already cleared. This ensures that focus will be in this frame and not
     // in a child.
-    nsIContent* content = windowToFocus->GetFocusedNode();
+    nsIContent* content = windowToFocus->GetFocusedElement();
     if (content) {
       if (nsCOMPtr<nsPIDOMWindowOuter> childWindow = GetContentWindow(content))
         ClearFocus(windowToFocus);
     }
   }
 
   nsCOMPtr<nsPIDOMWindowOuter> rootWindow = windowToFocus->GetPrivateRoot();
   if (rootWindow)
     RaiseWindow(rootWindow);
 
   LOGFOCUS(("<<SetFocusedWindow end>>"));
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsFocusManager::GetFocusedElement(nsIDOMElement** aFocusedElement)
+nsFocusManager::GetFocusedElement(Element** aFocusedElement)
 {
-  if (mFocusedContent)
-    CallQueryInterface(mFocusedContent, aFocusedElement);
-  else
-    *aFocusedElement = nullptr;
+  RefPtr<Element> focusedElement = mFocusedElement;
+  focusedElement.forget(aFocusedElement);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsFocusManager::GetLastFocusMethod(mozIDOMWindowProxy* aWindow, uint32_t* aLastFocusMethod)
 {
   // the focus method is stored on the inner window
   nsCOMPtr<nsPIDOMWindowOuter> window;
@@ -548,17 +545,17 @@ nsFocusManager::MoveFocus(mozIDOMWindowP
     nsIDocument* doc = mFocusedWindow->GetExtantDoc();
     if (doc && doc->GetDocumentURI()) {
       LOGFOCUS((" Focused Window: %p %s",
                 mFocusedWindow.get(),
                 doc->GetDocumentURI()->GetSpecOrDefault().get()));
     }
   }
 
-  LOGCONTENT("  Current Focus: %s", mFocusedContent.get());
+  LOGCONTENT("  Current Focus: %s", mFocusedElement.get());
 
   // use FLAG_BYMOVEFOCUS when switching focus with MoveFocus unless one of
   // the other focus methods is already set, or we're just moving to the root
   // or caret position.
   if (aType != MOVEFOCUS_ROOT && aType != MOVEFOCUS_CARET &&
       (aFlags & FOCUSMETHOD_MASK) == 0) {
     aFlags |= FLAG_BYMOVEFOCUS;
   }
@@ -619,45 +616,45 @@ nsFocusManager::ClearFocus(mozIDOMWindow
     if (Blur(window, nullptr, isAncestor, true)) {
       // if we are clearing the focus on an ancestor of the focused window,
       // the ancestor will become the new focused window, so focus it
       if (isAncestor)
         Focus(window, nullptr, 0, true, false, false, true);
     }
   }
   else {
-    window->SetFocusedNode(nullptr);
+    window->SetFocusedElement(nullptr);
   }
 
   LOGFOCUS(("<<ClearFocus end>>"));
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsFocusManager::GetFocusedElementForWindow(mozIDOMWindowProxy* aWindow,
                                            bool aDeep,
                                            mozIDOMWindowProxy** aFocusedWindow,
-                                           nsIDOMElement** aElement)
+                                           Element** aElement)
 {
   *aElement = nullptr;
   if (aFocusedWindow)
     *aFocusedWindow = nullptr;
 
   NS_ENSURE_TRUE(aWindow, NS_ERROR_INVALID_ARG);
   nsCOMPtr<nsPIDOMWindowOuter> window = nsPIDOMWindowOuter::From(aWindow);
 
   nsCOMPtr<nsPIDOMWindowOuter> focusedWindow;
-  nsCOMPtr<nsIContent> focusedContent =
+  RefPtr<Element> focusedElement =
     GetFocusedDescendant(window,
                          aDeep ? nsFocusManager::eIncludeAllDescendants :
                                  nsFocusManager::eOnlyCurrentWindow,
                          getter_AddRefs(focusedWindow));
-  if (focusedContent)
-    CallQueryInterface(focusedContent, aElement);
+
+  focusedElement.forget(aElement);
 
   if (aFocusedWindow)
     NS_IF_ADDREF(*aFocusedWindow = focusedWindow);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
@@ -675,17 +672,17 @@ nsFocusManager::MoveCaretToFocus(mozIDOM
       docShell->GetEditable(&isEditable);
       if (isEditable)
         return NS_OK;
 
       nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
       NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
 
       nsCOMPtr<nsPIDOMWindowOuter> window = nsPIDOMWindowOuter::From(aWindow);
-      nsCOMPtr<nsIContent> content = window->GetFocusedNode();
+      nsCOMPtr<nsIContent> content = window->GetFocusedElement();
       if (content)
         MoveCaretToFocus(presShell, content);
     }
   }
 
   return NS_OK;
 }
 
@@ -845,25 +842,25 @@ nsFocusManager::ContentRemoved(nsIDocume
 
   nsPIDOMWindowOuter *window = aDocument->GetWindow();
   if (!window)
     return NS_OK;
 
   // if the content is currently focused in the window, or is an
   // shadow-including inclusive ancestor of the currently focused element,
   // reset the focus within that window.
-  nsIContent* content = window->GetFocusedNode();
+  nsIContent* content = window->GetFocusedElement();
   if (content && nsContentUtils::ContentIsHostIncludingDescendantOf(content, aContent)) {
     bool shouldShowFocusRing = window->ShouldShowFocusRing();
-    window->SetFocusedNode(nullptr);
+    window->SetFocusedElement(nullptr);
 
     // if this window is currently focused, clear the global focused
     // element as well, but don't fire any events.
     if (window == mFocusedWindow) {
-      mFocusedContent = nullptr;
+      mFocusedElement = nullptr;
     } else {
       // Check if the node that was focused is an iframe or similar by looking
       // if it has a subdocument. This would indicate that this focused iframe
       // and its descendants will be going away. We will need to move the
       // focus somewhere else, so just clear the focus in the toplevel window
       // so that no element is focused.
       nsIDocument* subdoc = aDocument->GetSubDocumentFor(content);
       if (subdoc) {
@@ -987,32 +984,32 @@ nsFocusManager::WindowHidden(mozIDOMWind
 
   if (!IsSameOrAncestor(window, mFocusedWindow))
     return NS_OK;
 
   // at this point, we know that the window being hidden is either the focused
   // window, or an ancestor of the focused window. Either way, the focus is no
   // longer valid, so it needs to be updated.
 
-  nsCOMPtr<nsIContent> oldFocusedContent = mFocusedContent.forget();
+  RefPtr<Element> oldFocusedElement = mFocusedElement.forget();
 
   nsCOMPtr<nsIDocShell> focusedDocShell = mFocusedWindow->GetDocShell();
   nsCOMPtr<nsIPresShell> presShell = focusedDocShell->GetPresShell();
 
-  if (oldFocusedContent && oldFocusedContent->IsInComposedDoc()) {
-    NotifyFocusStateChange(oldFocusedContent,
+  if (oldFocusedElement && oldFocusedElement->IsInComposedDoc()) {
+    NotifyFocusStateChange(oldFocusedElement,
                            nullptr,
                            mFocusedWindow->ShouldShowFocusRing(),
                            false);
     window->UpdateCommands(NS_LITERAL_STRING("focus"), nullptr, 0);
 
     if (presShell) {
       SendFocusOrBlurEvent(eBlur, presShell,
-                           oldFocusedContent->GetComposedDoc(),
-                           oldFocusedContent, 1, false);
+                           oldFocusedElement->GetComposedDoc(),
+                           oldFocusedElement, 1, false);
     }
   }
 
   nsPresContext* focusedPresContext =
     presShell ? presShell->GetPresContext() : nullptr;
   IMEStateManager::OnChangeFocus(focusedPresContext, nullptr,
                                  GetFocusMoveActionCause(0));
   if (presShell) {
@@ -1050,17 +1047,17 @@ nsFocusManager::WindowHidden(mozIDOMWind
   if (window != mFocusedWindow) {
     nsCOMPtr<nsIDocShellTreeItem> dsti =
       mFocusedWindow ? mFocusedWindow->GetDocShell() : nullptr;
     if (dsti) {
       nsCOMPtr<nsIDocShellTreeItem> parentDsti;
       dsti->GetParent(getter_AddRefs(parentDsti));
       if (parentDsti) {
         if (nsCOMPtr<nsPIDOMWindowOuter> parentWindow = parentDsti->GetWindow())
-          parentWindow->SetFocusedNode(nullptr);
+          parentWindow->SetFocusedElement(nullptr);
       }
     }
 
     SetFocusedWindowInternal(window);
   }
 
   return NS_OK;
 }
@@ -1221,43 +1218,47 @@ nsFocusManager::ActivateOrDeactivate(nsP
                                           (void *)aActive);
 }
 
 void
 nsFocusManager::SetFocusInner(Element* aNewContent, int32_t aFlags,
                               bool aFocusChanged, bool aAdjustWidget)
 {
   // if the element is not focusable, just return and leave the focus as is
-  RefPtr<Element> contentToFocus = CheckIfFocusable(aNewContent, aFlags);
-  if (!contentToFocus)
+  RefPtr<Element> elementToFocus = CheckIfFocusable(aNewContent, aFlags);
+  if (!elementToFocus) {
     return;
+  }
 
   // check if the element to focus is a frame (iframe) containing a child
   // document. Frames are never directly focused; instead focusing a frame
   // means focus what is inside the frame. To do this, the descendant content
   // within the frame is retrieved and that will be focused instead.
   nsCOMPtr<nsPIDOMWindowOuter> newWindow;
-  nsCOMPtr<nsPIDOMWindowOuter> subWindow = GetContentWindow(contentToFocus);
+  nsCOMPtr<nsPIDOMWindowOuter> subWindow = GetContentWindow(elementToFocus);
   if (subWindow) {
-    contentToFocus = GetFocusedDescendant(subWindow, eIncludeAllDescendants,
+    elementToFocus = GetFocusedDescendant(subWindow, eIncludeAllDescendants,
                                           getter_AddRefs(newWindow));
     // since a window is being refocused, clear aFocusChanged so that the
     // caret position isn't updated.
     aFocusChanged = false;
   }
 
   // unless it was set above, retrieve the window for the element to focus
-  if (!newWindow)
-    newWindow = GetCurrentWindow(contentToFocus);
+  if (!newWindow) {
+    newWindow = GetCurrentWindow(elementToFocus);
+  }
 
   // if the element is already focused, just return. Note that this happens
   // after the frame check above so that we compare the element that will be
   // focused rather than the frame it is in.
-  if (!newWindow || (newWindow == mFocusedWindow && contentToFocus == mFocusedContent))
+  if (!newWindow ||
+      (newWindow == mFocusedWindow && elementToFocus == mFocusedElement)) {
     return;
+  }
 
   // don't allow focus to be placed in docshells or descendants of docshells
   // that are being destroyed. Also, ensure that the page hasn't been
   // unloaded. The prevents content from being refocused during an unload event.
   nsCOMPtr<nsIDocShell> newDocShell = newWindow->GetDocShell();
   nsCOMPtr<nsIDocShell> docShell = newDocShell;
   while (docShell) {
     bool inUnload;
@@ -1312,26 +1313,26 @@ nsFocusManager::SetFocusInner(Element* a
   }
 
   // Exit fullscreen if we're focusing a windowed plugin on a non-MacOSX
   // system. We don't control event dispatch to windowed plugins on non-MacOSX,
   // so we can't display the "Press ESC to leave fullscreen mode" warning on
   // key input if a windowed plugin is focused, so just exit fullscreen
   // to guard against phishing.
 #ifndef XP_MACOSX
-  if (contentToFocus &&
+  if (elementToFocus &&
       nsContentUtils::
-        GetRootDocument(contentToFocus->OwnerDoc())->GetFullscreenElement() &&
-      nsContentUtils::HasPluginWithUncontrolledEventDispatch(contentToFocus)) {
+        GetRootDocument(elementToFocus->OwnerDoc())->GetFullscreenElement() &&
+      nsContentUtils::HasPluginWithUncontrolledEventDispatch(elementToFocus)) {
     nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
                                     NS_LITERAL_CSTRING("DOM"),
-                                    contentToFocus->OwnerDoc(),
+                                    elementToFocus->OwnerDoc(),
                                     nsContentUtils::eDOM_PROPERTIES,
                                     "FocusedWindowedPluginWhileFullscreen");
-    nsIDocument::AsyncExitFullscreen(contentToFocus->OwnerDoc());
+    nsIDocument::AsyncExitFullscreen(elementToFocus->OwnerDoc());
   }
 #endif
 
   // if the FLAG_NOSWITCHFRAME flag is used, only allow the focus to be
   // shifted away from the current element if the new shell to focus is
   // the same or an ancestor shell of the currently focused shell.
   bool allowFrameSwitch = !(aFlags & FLAG_NOSWITCHFRAME) ||
                             IsSameOrAncestor(newWindow, mFocusedWindow);
@@ -1341,39 +1342,39 @@ nsFocusManager::SetFocusInner(Element* a
   bool sendFocusEvent =
     isElementInActiveWindow && allowFrameSwitch && IsWindowVisible(newWindow);
 
   // When the following conditions are true:
   //  * an element has focus
   //  * isn't called by trusted event (i.e., called by untrusted event or by js)
   //  * the focus is moved to another document's element
   // we need to check the permission.
-  if (sendFocusEvent && mFocusedContent && !nsContentUtils::LegacyIsCallerNativeCode() &&
-      mFocusedContent->OwnerDoc() != aNewContent->OwnerDoc()) {
+  if (sendFocusEvent && mFocusedElement && !nsContentUtils::LegacyIsCallerNativeCode() &&
+      mFocusedElement->OwnerDoc() != aNewContent->OwnerDoc()) {
     // If the caller cannot access the current focused node, the caller should
     // not be able to steal focus from it. E.g., When the current focused node
     // is in chrome, any web contents should not be able to steal the focus.
-    nsCOMPtr<nsIDOMNode> domNode(do_QueryInterface(mFocusedContent));
+    nsCOMPtr<nsIDOMNode> domNode(do_QueryInterface(mFocusedElement));
     sendFocusEvent = nsContentUtils::CanCallerAccess(domNode);
     if (!sendFocusEvent && mMouseButtonEventHandlingDocument) {
       // However, while mouse button event is handling, the handling document's
       // script should be able to steal focus.
       domNode = do_QueryInterface(mMouseButtonEventHandlingDocument);
       sendFocusEvent = nsContentUtils::CanCallerAccess(domNode);
     }
   }
 
-  LOGCONTENT("Shift Focus: %s", contentToFocus.get());
+  LOGCONTENT("Shift Focus: %s", elementToFocus.get());
   LOGFOCUS((" Flags: %x Current Window: %p New Window: %p Current Element: %p",
-           aFlags, mFocusedWindow.get(), newWindow.get(), mFocusedContent.get()));
+           aFlags, mFocusedWindow.get(), newWindow.get(), mFocusedElement.get()));
   LOGFOCUS((" In Active Window: %d In Focused Window: %d SendFocus: %d",
            isElementInActiveWindow, isElementInFocusedWindow, sendFocusEvent));
 
   if (sendFocusEvent) {
-    RefPtr<Element> oldFocusedContent = mFocusedContent;
+    RefPtr<Element> oldFocusedElement = mFocusedElement;
     // return if blurring fails or the focus changes during the blur
     if (mFocusedWindow) {
       // if the focus is being moved to another element in the same document,
       // or to a descendant, pass the existing window to Blur so that the
       // current node in the existing window is cleared. If moving to a
       // window elsewhere, we want to maintain the current node in the
       // window but still blur it.
       bool currentIsSameOrAncestor = IsSameOrAncestor(mFocusedWindow, newWindow);
@@ -1390,39 +1391,40 @@ nsFocusManager::SetFocusInner(Element* a
       // to clear out the focus in A, otherwise A would still maintain that B
       // was focused, and B that D was focused.
       nsCOMPtr<nsPIDOMWindowOuter> commonAncestor;
       if (!isElementInFocusedWindow)
         commonAncestor = GetCommonAncestor(newWindow, mFocusedWindow);
 
       if (!Blur(currentIsSameOrAncestor ? mFocusedWindow.get() : nullptr,
                 commonAncestor, !isElementInFocusedWindow, aAdjustWidget,
-                contentToFocus))
+                elementToFocus)) {
         return;
+      }
     }
 
-    Focus(newWindow, contentToFocus, aFlags, !isElementInFocusedWindow,
-          aFocusChanged, false, aAdjustWidget, oldFocusedContent);
+    Focus(newWindow, elementToFocus, aFlags, !isElementInFocusedWindow,
+          aFocusChanged, false, aAdjustWidget, oldFocusedElement);
   }
   else {
     // otherwise, for inactive windows and when the caller cannot steal the
     // focus, update the node in the window, and  raise the window if desired.
     if (allowFrameSwitch)
       AdjustWindowFocus(newWindow, true);
 
     // set the focus node and method as needed
     uint32_t focusMethod = aFocusChanged ? aFlags & FOCUSMETHODANDRING_MASK :
                            newWindow->GetFocusMethod() | (aFlags & FLAG_SHOWRING);
-    newWindow->SetFocusedNode(contentToFocus, focusMethod);
+    newWindow->SetFocusedElement(elementToFocus, focusMethod);
     if (aFocusChanged) {
       nsCOMPtr<nsIDocShell> docShell = newWindow->GetDocShell();
 
       nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
       if (presShell && presShell->DidInitialize())
-        ScrollIntoView(presShell, contentToFocus, aFlags);
+        ScrollIntoView(presShell, elementToFocus, aFlags);
     }
 
     // update the commands even when inactive so that the attributes for that
     // window are up to date.
     if (allowFrameSwitch)
       newWindow->UpdateCommands(NS_LITERAL_STRING("focus"), nullptr, 0);
 
     if (aFlags & FLAG_RAISE)
@@ -1526,17 +1528,17 @@ nsFocusManager::AdjustWindowFocus(nsPIDO
       // When aCheckPermission is true, we should check whether the caller can
       // access the window or not.  If it cannot access, we should stop the
       // adjusting.
       if (aCheckPermission && !nsContentUtils::LegacyIsCallerNativeCode() &&
           !nsContentUtils::CanCallerAccess(window->GetCurrentInnerWindow())) {
         break;
       }
 
-      window->SetFocusedNode(frameElement);
+      window->SetFocusedElement(frameElement);
     }
   }
 }
 
 bool
 nsFocusManager::IsWindowVisible(nsPIDOMWindowOuter* aWindow)
 {
   if (!aWindow || aWindow->IsFrozen())
@@ -1573,164 +1575,164 @@ nsFocusManager::IsNonFocusableRoot(nsICo
   nsIDocument* doc = aContent->GetComposedDoc();
   NS_ASSERTION(doc, "aContent must have current document");
   return aContent == doc->GetRootElement() &&
            (doc->HasFlag(NODE_IS_EDITABLE) || !aContent->IsEditable() ||
             nsContentUtils::IsUserFocusIgnored(aContent));
 }
 
 Element*
-nsFocusManager::CheckIfFocusable(Element* aContent, uint32_t aFlags)
+nsFocusManager::CheckIfFocusable(Element* aElement, uint32_t aFlags)
 {
-  if (!aContent)
+  if (!aElement)
     return nullptr;
 
   // this is a special case for some XUL elements or input number, where an
   // anonymous child is actually focusable and not the element itself.
-  RefPtr<Element> redirectedFocus = GetRedirectedFocus(aContent);
+  RefPtr<Element> redirectedFocus = GetRedirectedFocus(aElement);
   if (redirectedFocus) {
     return CheckIfFocusable(redirectedFocus, aFlags);
   }
 
-  nsCOMPtr<nsIDocument> doc = aContent->GetComposedDoc();
+  nsCOMPtr<nsIDocument> doc = aElement->GetComposedDoc();
   // can't focus elements that are not in documents
   if (!doc) {
-    LOGCONTENT("Cannot focus %s because content not in document", aContent)
+    LOGCONTENT("Cannot focus %s because content not in document", aElement)
     return nullptr;
   }
 
   // Make sure that our frames are up to date while ensuring the presshell is
   // also initialized in case we come from a script calling focus() early.
   mEventHandlingNeedsFlush = false;
   doc->FlushPendingNotifications(FlushType::EnsurePresShellInitAndFrames);
 
   nsIPresShell *shell = doc->GetShell();
   if (!shell)
     return nullptr;
 
   // the root content can always be focused,
   // except in userfocusignored context.
-  if (aContent == doc->GetRootElement()) {
-    return nsContentUtils::IsUserFocusIgnored(aContent) ? nullptr : aContent;
+  if (aElement == doc->GetRootElement()) {
+    return nsContentUtils::IsUserFocusIgnored(aElement) ? nullptr : aElement;
   }
 
   // cannot focus content in print preview mode. Only the root can be focused.
   nsPresContext* presContext = shell->GetPresContext();
   if (presContext && presContext->Type() == nsPresContext::eContext_PrintPreview) {
-    LOGCONTENT("Cannot focus %s while in print preview", aContent)
+    LOGCONTENT("Cannot focus %s while in print preview", aElement)
     return nullptr;
   }
 
-  nsIFrame* frame = aContent->GetPrimaryFrame();
+  nsIFrame* frame = aElement->GetPrimaryFrame();
   if (!frame) {
-    LOGCONTENT("Cannot focus %s as it has no frame", aContent)
+    LOGCONTENT("Cannot focus %s as it has no frame", aElement)
     return nullptr;
   }
 
-  if (aContent->IsHTMLElement(nsGkAtoms::area)) {
+  if (aElement->IsHTMLElement(nsGkAtoms::area)) {
     // HTML areas do not have their own frame, and the img frame we get from
     // GetPrimaryFrame() is not relevant as to whether it is focusable or
     // not, so we have to do all the relevant checks manually for them.
     return frame->IsVisibleConsideringAncestors() &&
-           aContent->IsFocusable() ? aContent : nullptr;
+           aElement->IsFocusable() ? aElement : nullptr;
   }
 
   // if this is a child frame content node, check if it is visible and
   // call the content node's IsFocusable method instead of the frame's
   // IsFocusable method. This skips checking the style system and ensures that
   // offscreen browsers can still be focused.
-  nsIDocument* subdoc = doc->GetSubDocumentFor(aContent);
+  nsIDocument* subdoc = doc->GetSubDocumentFor(aElement);
   if (subdoc && IsWindowVisible(subdoc->GetWindow())) {
     const nsStyleUserInterface* ui = frame->StyleUserInterface();
     int32_t tabIndex = (ui->mUserFocus == StyleUserFocus::Ignore ||
                         ui->mUserFocus == StyleUserFocus::None) ? -1 : 0;
-    return aContent->IsFocusable(&tabIndex, aFlags & FLAG_BYMOUSE) ? aContent : nullptr;
+    return aElement->IsFocusable(&tabIndex, aFlags & FLAG_BYMOUSE) ? aElement : nullptr;
   }
 
-  return frame->IsFocusable(nullptr, aFlags & FLAG_BYMOUSE) ? aContent : nullptr;
+  return frame->IsFocusable(nullptr, aFlags & FLAG_BYMOUSE) ? aElement : nullptr;
 }
 
 bool
 nsFocusManager::Blur(nsPIDOMWindowOuter* aWindowToClear,
                      nsPIDOMWindowOuter* aAncestorWindowToFocus,
                      bool aIsLeavingDocument,
                      bool aAdjustWidgets,
                      nsIContent* aContentToFocus)
 {
   LOGFOCUS(("<<Blur begin>>"));
 
   // hold a reference to the focused content, which may be null
-  RefPtr<Element> content = mFocusedContent;
-  if (content) {
-    if (!content->IsInComposedDoc()) {
-      mFocusedContent = nullptr;
+  RefPtr<Element> element = mFocusedElement;
+  if (element) {
+    if (!element->IsInComposedDoc()) {
+      mFocusedElement = nullptr;
       return true;
     }
-    if (content == mFirstBlurEvent)
+    if (element == mFirstBlurEvent)
       return true;
   }
 
   // hold a reference to the focused window
   nsCOMPtr<nsPIDOMWindowOuter> window = mFocusedWindow;
   if (!window) {
-    mFocusedContent = nullptr;
+    mFocusedElement = nullptr;
     return true;
   }
 
   nsCOMPtr<nsIDocShell> docShell = window->GetDocShell();
   if (!docShell) {
-    mFocusedContent = nullptr;
+    mFocusedElement = nullptr;
     return true;
   }
 
   // Keep a ref to presShell since dispatching the DOM event may cause
   // the document to be destroyed.
   nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
   if (!presShell) {
-    mFocusedContent = nullptr;
+    mFocusedElement = nullptr;
     return true;
   }
 
   bool clearFirstBlurEvent = false;
   if (!mFirstBlurEvent) {
-    mFirstBlurEvent = content;
+    mFirstBlurEvent = element;
     clearFirstBlurEvent = true;
   }
 
   nsPresContext* focusedPresContext =
     mActiveWindow ? presShell->GetPresContext() : nullptr;
   IMEStateManager::OnChangeFocus(focusedPresContext, nullptr,
                                  GetFocusMoveActionCause(0));
 
   // now adjust the actual focus, by clearing the fields in the focus manager
   // and in the window.
-  mFocusedContent = nullptr;
+  mFocusedElement = nullptr;
   bool shouldShowFocusRing = window->ShouldShowFocusRing();
   if (aWindowToClear)
-    aWindowToClear->SetFocusedNode(nullptr);
-
-  LOGCONTENT("Element %s has been blurred", content.get());
+    aWindowToClear->SetFocusedElement(nullptr);
+
+  LOGCONTENT("Element %s has been blurred", element.get());
 
   // Don't fire blur event on the root content which isn't editable.
   bool sendBlurEvent =
-    content && content->IsInComposedDoc() && !IsNonFocusableRoot(content);
-  if (content) {
+    element && element->IsInComposedDoc() && !IsNonFocusableRoot(element);
+  if (element) {
     if (sendBlurEvent) {
-      NotifyFocusStateChange(content,
+      NotifyFocusStateChange(element,
                              aContentToFocus,
                              shouldShowFocusRing,
                              false);
     }
 
     // if an object/plug-in/remote browser is being blurred, move the system focus
     // to the parent window, otherwise events will still get fired at the plugin.
     // But don't do this if we are blurring due to the window being lowered,
     // otherwise, the parent window can get raised again.
     if (mActiveWindow) {
-      nsIFrame* contentFrame = content->GetPrimaryFrame();
+      nsIFrame* contentFrame = element->GetPrimaryFrame();
       nsIObjectFrame* objectFrame = do_QueryFrame(contentFrame);
       if (aAdjustWidgets && objectFrame && !sTestMode) {
         if (XRE_IsContentProcess()) {
           // set focus to the top level window via the chrome process.
           nsCOMPtr<nsITabChild> tabChild = docShell->GetTabChild();
           if (tabChild) {
             static_cast<TabChild*>(tabChild.get())->SendDispatchFocusToTopLevelWindow();
           }
@@ -1746,67 +1748,67 @@ nsFocusManager::Blur(nsPIDOMWindowOuter*
               widget->SetFocus(false);
             }
           }
         }
       }
     }
 
       // if the object being blurred is a remote browser, deactivate remote content
-    if (TabParent* remote = TabParent::GetFrom(content)) {
+    if (TabParent* remote = TabParent::GetFrom(element)) {
       remote->Deactivate();
       LOGFOCUS(("Remote browser deactivated"));
     }
   }
 
   bool result = true;
   if (sendBlurEvent) {
     // if there is an active window, update commands. If there isn't an active
     // window, then this was a blur caused by the active window being lowered,
     // so there is no need to update the commands
     if (mActiveWindow)
       window->UpdateCommands(NS_LITERAL_STRING("focus"), nullptr, 0);
 
     SendFocusOrBlurEvent(eBlur, presShell,
-                         content->GetComposedDoc(), content, 1,
+                         element->GetComposedDoc(), element, 1,
                          false, false, aContentToFocus);
   }
 
   // if we are leaving the document or the window was lowered, make the caret
   // invisible.
   if (aIsLeavingDocument || !mActiveWindow) {
     SetCaretVisible(presShell, false, nullptr);
   }
 
   RefPtr<AccessibleCaretEventHub> eventHub = presShell->GetAccessibleCaretEventHub();
   if (eventHub) {
     eventHub->NotifyBlur(aIsLeavingDocument || !mActiveWindow);
   }
 
   // at this point, it is expected that this window will be still be
-  // focused, but the focused content will be null, as it was cleared before
+  // focused, but the focused element will be null, as it was cleared before
   // the event. If this isn't the case, then something else was focused during
   // the blur event above and we should just return. However, if
   // aIsLeavingDocument is set, a new document is desired, so make sure to
   // blur the document and window.
   if (mFocusedWindow != window ||
-      (mFocusedContent != nullptr && !aIsLeavingDocument)) {
+      (mFocusedElement != nullptr && !aIsLeavingDocument)) {
     result = false;
   }
   else if (aIsLeavingDocument) {
     window->TakeFocus(false, 0);
 
     // clear the focus so that the ancestor frame hierarchy is in the correct
     // state. Pass true because aAncestorWindowToFocus is thought to be
     // focused at this point.
     if (aAncestorWindowToFocus)
-      aAncestorWindowToFocus->SetFocusedNode(nullptr, 0, true);
+      aAncestorWindowToFocus->SetFocusedElement(nullptr, 0, true);
 
     SetFocusedWindowInternal(nullptr);
-    mFocusedContent = nullptr;
+    mFocusedElement = nullptr;
 
     // pass 1 for the focus method when calling SendFocusOrBlurEvent just so
     // that the check is made for suppressed documents. Check to ensure that
     // the document isn't null in case someone closed it during the blur above
     nsIDocument* doc = window->GetExtantDoc();
     if (doc)
       SendFocusOrBlurEvent(eBlur, presShell, doc, doc, 1, false);
     if (mFocusedWindow == nullptr)
@@ -1828,30 +1830,30 @@ nsFocusManager::Blur(nsPIDOMWindowOuter*
   if (clearFirstBlurEvent)
     mFirstBlurEvent = nullptr;
 
   return result;
 }
 
 void
 nsFocusManager::Focus(nsPIDOMWindowOuter* aWindow,
-                      Element* aContent,
+                      Element* aElement,
                       uint32_t aFlags,
                       bool aIsNewDocument,
                       bool aFocusChanged,
                       bool aWindowRaised,
                       bool aAdjustWidgets,
                       nsIContent* aContentLostFocus)
 {
   LOGFOCUS(("<<Focus begin>>"));
 
   if (!aWindow)
     return;
 
-  if (aContent && (aContent == mFirstFocusEvent || aContent == mFirstBlurEvent))
+  if (aElement && (aElement == mFirstFocusEvent || aElement == mFirstBlurEvent))
     return;
 
   // Keep a reference to the presShell since dispatching the DOM event may
   // cause the document to be destroyed.
   nsCOMPtr<nsIDocShell> docShell = aWindow->GetDocShell();
   if (!docShell)
     return;
 
@@ -1863,31 +1865,31 @@ nsFocusManager::Focus(nsPIDOMWindowOuter
   // Otherwise, just get the current focus method and use that. This ensures
   // that the method is set during the document and window focus events.
   uint32_t focusMethod = aFocusChanged ? aFlags & FOCUSMETHODANDRING_MASK :
                          aWindow->GetFocusMethod() | (aFlags & FLAG_SHOWRING);
 
   if (!IsWindowVisible(aWindow)) {
     // if the window isn't visible, for instance because it is a hidden tab,
     // update the current focus and scroll it into view but don't do anything else
-    if (CheckIfFocusable(aContent, aFlags)) {
-      aWindow->SetFocusedNode(aContent, focusMethod);
+    if (CheckIfFocusable(aElement, aFlags)) {
+      aWindow->SetFocusedElement(aElement, focusMethod);
       if (aFocusChanged)
-        ScrollIntoView(presShell, aContent, aFlags);
+        ScrollIntoView(presShell, aElement, aFlags);
     }
     return;
   }
 
   bool clearFirstFocusEvent = false;
   if (!mFirstFocusEvent) {
-    mFirstFocusEvent = aContent;
+    mFirstFocusEvent = aElement;
     clearFirstFocusEvent = true;
   }
 
-  LOGCONTENT("Element %s has been focused", aContent);
+  LOGCONTENT("Element %s has been focused", aElement);
 
   if (MOZ_LOG_TEST(gFocusLog, LogLevel::Debug)) {
     nsIDocument* docm = aWindow->GetExtantDoc();
     if (docm) {
       LOGCONTENT(" from %s", docm->GetRootElement());
     }
     LOGFOCUS((" [Newdoc: %d FocusChanged: %d Raised: %d Flags: %x]",
              aIsNewDocument, aFocusChanged, aWindowRaised, aFlags));
@@ -1902,21 +1904,21 @@ nsFocusManager::Focus(nsPIDOMWindowOuter
 
   // indicate that the window has taken focus.
   if (aWindow->TakeFocus(true, focusMethod))
     aIsNewDocument = true;
 
   SetFocusedWindowInternal(aWindow);
 
   // Update the system focus by focusing the root widget.  But avoid this
-  // if 1) aAdjustWidgets is false or 2) aContent is a plugin that has its
+  // if 1) aAdjustWidgets is false or 2) aElement is a plugin that has its
   // own widget and is either already focused or is about to be focused.
   nsCOMPtr<nsIWidget> objectFrameWidget;
-  if (aContent) {
-    nsIFrame* contentFrame = aContent->GetPrimaryFrame();
+  if (aElement) {
+    nsIFrame* contentFrame = aElement->GetPrimaryFrame();
     nsIObjectFrame* objectFrame = do_QueryFrame(contentFrame);
     if (objectFrame)
       objectFrameWidget = objectFrame->GetWidget();
   }
   if (aAdjustWidgets && !objectFrameWidget && !sTestMode) {
     nsViewManager* vm = presShell->GetViewManager();
     if (vm) {
       nsCOMPtr<nsIWidget> widget;
@@ -1926,128 +1928,130 @@ nsFocusManager::Focus(nsPIDOMWindowOuter
     }
   }
 
   // if switching to a new document, first fire the focus event on the
   // document and then the window.
   if (aIsNewDocument) {
     nsIDocument* doc = aWindow->GetExtantDoc();
     // The focus change should be notified to IMEStateManager from here if
-    // the focused content is a designMode editor since any content won't
+    // the focused element is a designMode editor since any content won't
     // receive focus event.
     if (doc && doc->HasFlag(NODE_IS_EDITABLE)) {
       IMEStateManager::OnChangeFocus(presShell->GetPresContext(), nullptr,
                                      GetFocusMoveActionCause(aFlags));
     }
-    if (doc)
+    if (doc) {
       SendFocusOrBlurEvent(eFocus, presShell, doc,
                            doc, aFlags & FOCUSMETHOD_MASK, aWindowRaised);
-    if (mFocusedWindow == aWindow && mFocusedContent == nullptr)
+    }
+    if (mFocusedWindow == aWindow && mFocusedElement == nullptr) {
       SendFocusOrBlurEvent(eFocus, presShell, doc,
                            aWindow->GetCurrentInnerWindow(),
                            aFlags & FOCUSMETHOD_MASK, aWindowRaised);
+    }
   }
 
   // check to ensure that the element is still focusable, and that nothing
   // else was focused during the events above.
-  if (CheckIfFocusable(aContent, aFlags) &&
-      mFocusedWindow == aWindow && mFocusedContent == nullptr) {
-    mFocusedContent = aContent;
-
-    nsIContent* focusedNode = aWindow->GetFocusedNode();
-    bool isRefocus = focusedNode && focusedNode->IsEqualNode(aContent);
-
-    aWindow->SetFocusedNode(aContent, focusMethod);
+  if (CheckIfFocusable(aElement, aFlags) &&
+      mFocusedWindow == aWindow && mFocusedElement == nullptr) {
+    mFocusedElement = aElement;
+
+    nsIContent* focusedNode = aWindow->GetFocusedElement();
+    bool isRefocus = focusedNode && focusedNode->IsEqualNode(aElement);
+
+    aWindow->SetFocusedElement(aElement, focusMethod);
 
     // if the focused element changed, scroll it into view
-    if (aContent && aFocusChanged) {
-      ScrollIntoView(presShell, aContent, aFlags);
+    if (aElement && aFocusChanged) {
+      ScrollIntoView(presShell, aElement, aFlags);
     }
 
     bool sendFocusEvent =
-      aContent && aContent->IsInComposedDoc() && !IsNonFocusableRoot(aContent);
+      aElement && aElement->IsInComposedDoc() && !IsNonFocusableRoot(aElement);
     nsPresContext* presContext = presShell->GetPresContext();
     if (sendFocusEvent) {
-      NotifyFocusStateChange(aContent,
+      NotifyFocusStateChange(aElement,
                              nullptr,
                              aWindow->ShouldShowFocusRing(),
                              true);
 
       // if this is an object/plug-in/remote browser, focus its widget.  Note that we might
       // no longer be in the same document, due to the events we fired above when
       // aIsNewDocument.
-      if (presShell->GetDocument() == aContent->GetComposedDoc()) {
+      if (presShell->GetDocument() == aElement->GetComposedDoc()) {
         if (aAdjustWidgets && objectFrameWidget && !sTestMode)
           objectFrameWidget->SetFocus(false);
 
         // if the object being focused is a remote browser, activate remote content
-        if (TabParent* remote = TabParent::GetFrom(aContent)) {
+        if (TabParent* remote = TabParent::GetFrom(aElement)) {
           remote->Activate();
           LOGFOCUS(("Remote browser activated"));
         }
       }
 
-      IMEStateManager::OnChangeFocus(presContext, aContent,
+      IMEStateManager::OnChangeFocus(presContext, aElement,
                                      GetFocusMoveActionCause(aFlags));
 
       // as long as this focus wasn't because a window was raised, update the
       // commands
       // XXXndeakin P2 someone could adjust the focus during the update
       if (!aWindowRaised)
         aWindow->UpdateCommands(NS_LITERAL_STRING("focus"), nullptr, 0);
 
       SendFocusOrBlurEvent(eFocus, presShell,
-                           aContent->GetComposedDoc(),
-                           aContent, aFlags & FOCUSMETHOD_MASK,
+                           aElement->GetComposedDoc(),
+                           aElement, aFlags & FOCUSMETHOD_MASK,
                            aWindowRaised, isRefocus, aContentLostFocus);
     } else {
       IMEStateManager::OnChangeFocus(presContext, nullptr,
                                      GetFocusMoveActionCause(aFlags));
       if (!aWindowRaised) {
         aWindow->UpdateCommands(NS_LITERAL_STRING("focus"), nullptr, 0);
       }
     }
   }
   else {
     // If the window focus event (fired above when aIsNewDocument) caused
     // the plugin not to be focusable, update the system focus by focusing
     // the root widget.
     if (aAdjustWidgets && objectFrameWidget &&
-        mFocusedWindow == aWindow && mFocusedContent == nullptr &&
+        mFocusedWindow == aWindow && mFocusedElement == nullptr &&
         !sTestMode) {
       nsViewManager* vm = presShell->GetViewManager();
       if (vm) {
         nsCOMPtr<nsIWidget> widget;
         vm->GetRootWidget(getter_AddRefs(widget));
         if (widget)
           widget->SetFocus(false);
       }
     }
 
-    if (!mFocusedContent) {
-      // When there is no focused content, IMEStateManager needs to adjust IME
+    if (!mFocusedElement) {
+      // When there is no focused element, IMEStateManager needs to adjust IME
       // enabled state with the document.
       nsPresContext* presContext = presShell->GetPresContext();
       IMEStateManager::OnChangeFocus(presContext, nullptr,
                                      GetFocusMoveActionCause(aFlags));
     }
 
     if (!aWindowRaised)
       aWindow->UpdateCommands(NS_LITERAL_STRING("focus"), nullptr, 0);
   }
 
   // update the caret visibility and position to match the newly focused
   // element. However, don't update the position if this was a focus due to a
   // mouse click as the selection code would already have moved the caret as
   // needed. If this is a different document than was focused before, also
   // update the caret's visibility. If this is the same document, the caret
   // visibility should be the same as before so there is no need to update it.
-  if (mFocusedContent == aContent)
+  if (mFocusedElement == aElement)
     UpdateCaret(aFocusChanged && !(aFlags & FLAG_BYMOUSE), aIsNewDocument,
-                mFocusedContent);
+                mFocusedElement);
 
   if (clearFirstFocusEvent)
     mFirstFocusEvent = nullptr;
 }
 
 class FocusBlurEvent : public Runnable
 {
 public:
@@ -2103,17 +2107,17 @@ public:
     , mOriginalFocusedContent(aOriginalFocusedContent)
     , mRelatedTarget(aRelatedTarget)
   {
   }
 
   NS_IMETHOD Run() override
   {
     nsCOMPtr<nsIContent> originalWindowFocus = mOriginalFocusedWindow ?
-        mOriginalFocusedWindow->GetFocusedNode() :
+        mOriginalFocusedWindow->GetFocusedElement() :
         nullptr;
     // Blink does not check that focus is the same after blur, but WebKit does.
     // Opt to follow Blink's behavior (see bug 687787).
     if (mEventMessage == eFocusOut ||
         originalWindowFocus == mOriginalFocusedContent) {
       InternalFocusEvent event(true, mEventMessage);
       event.mFlags.mBubbles = true;
       event.mFlags.mCancelable = false;
@@ -2226,17 +2230,17 @@ nsFocusManager::FireFocusOrBlurEvent(Eve
                                      EventTarget* aRelatedTarget)
 {
   nsCOMPtr<EventTarget> eventTarget = do_QueryInterface(aTarget);
   nsCOMPtr<nsIDocument> eventTargetDoc = GetDocumentHelper(eventTarget);
   nsCOMPtr<nsPIDOMWindowOuter> currentWindow = mFocusedWindow;
   nsCOMPtr<nsPIDOMWindowInner> targetWindow = do_QueryInterface(aTarget);
   nsCOMPtr<nsIDocument> targetDocument = do_QueryInterface(aTarget);
   nsCOMPtr<nsIContent> currentFocusedContent = currentWindow ?
-      currentWindow->GetFocusedNode() : nullptr;
+      currentWindow->GetFocusedElement() : nullptr;
 
   bool dontDispatchEvent =
     eventTargetDoc && nsContentUtils::IsUserFocusIgnored(eventTargetDoc);
 
 #ifdef ACCESSIBILITY
   nsAccessibilityService* accService = GetAccService();
   if (accService) {
     if (aEventMessage == eFocus) {
@@ -2347,17 +2351,17 @@ nsFocusManager::RaiseWindow(nsPIDOMWindo
       widget->SetFocus(true);
   }
 #endif
 }
 
 void
 nsFocusManager::UpdateCaretForCaretBrowsingMode()
 {
-  UpdateCaret(false, true, mFocusedContent);
+  UpdateCaret(false, true, mFocusedElement);
 }
 
 void
 nsFocusManager::UpdateCaret(bool aMoveCaretToFocus,
                             bool aUpdateVisibility,
                             nsIContent* aContent)
 {
   LOGFOCUS(("Update Caret: %d %d", aMoveCaretToFocus, aUpdateVisibility));
@@ -2681,17 +2685,17 @@ nsFocusManager::DetermineElementToMoveFo
       startContent = GetFocusedDescendant(aWindow, eIncludeAllDescendants,
                                           getter_AddRefs(focusedWindow));
     }
     else if (aType != MOVEFOCUS_LASTDOC) {
       // Otherwise, start at the focused node. If MOVEFOCUS_LASTDOC is used,
       // then we are document-navigating backwards from chrome to the content
       // process, and we don't want to use this so that we start from the end
       // of the document.
-      startContent = aWindow->GetFocusedNode();
+      startContent = aWindow->GetFocusedElement();
     }
   }
 
   nsCOMPtr<nsIDocument> doc;
   if (startContent)
     doc = startContent->GetComposedDoc();
   else
     doc = aWindow->GetExtantDoc();
@@ -3008,23 +3012,23 @@ nsFocusManager::DetermineElementToMoveFo
         }
       }
     }
     else {
       // There is no parent, so call the tree owner. This will tell the
       // embedder or parent process that it should take the focus.
       bool tookFocus;
       docShell->TabToTreeOwner(forward, forDocumentNavigation, &tookFocus);
-      // If the tree owner took the focus, blur the current content.
+      // If the tree owner took the focus, blur the current element.
       if (tookFocus) {
         nsCOMPtr<nsPIDOMWindowOuter> window = docShell->GetWindow();
-        if (window->GetFocusedNode() == mFocusedContent)
+        if (window->GetFocusedElement() == mFocusedElement)
           Blur(mFocusedWindow, nullptr, true, true);
         else
-          window->SetFocusedNode(nullptr);
+          window->SetFocusedElement(nullptr);
         return NS_OK;
       }
 
       // If we have reached the end of the top-level document, focus the
       // first element in the top-level document. This should always happen
       // when navigating by document forwards but when navigating backwards,
       // only do this if we started in another document or within a popup frame.
       // If the focus started in this window outside a popup however, we should
@@ -3951,17 +3955,17 @@ nsFocusManager::GetFocusInSelection(nsPI
                                     nsIContent* aEndSelection,
                                     nsIContent** aFocusedContent)
 {
   *aFocusedContent = nullptr;
 
   nsCOMPtr<nsIContent> testContent = aStartSelection;
   nsCOMPtr<nsIContent> nextTestContent = aEndSelection;
 
-  nsCOMPtr<nsIContent> currentFocus = aWindow->GetFocusedNode();
+  nsCOMPtr<nsIContent> currentFocus = aWindow->GetFocusedElement();
 
   // We now have the correct start node in selectionContent!
   // Search for focusable elements, starting with selectionContent
 
   // Method #1: Keep going up while we look - an ancestor might be focusable
   // We could end the loop earlier, such as when we're no longer
   // in the same frame, by comparing selectionContent->GetPrimaryFrame()
   // with a variable holding the starting selectionContent
@@ -4118,18 +4122,18 @@ nsFocusManager::MarkUncollectableForCCGe
   if (sInstance->mFocusedWindow) {
     sInstance->mFocusedWindow->
       MarkUncollectableForCCGeneration(aGeneration);
   }
   if (sInstance->mWindowBeingLowered) {
     sInstance->mWindowBeingLowered->
       MarkUncollectableForCCGeneration(aGeneration);
   }
-  if (sInstance->mFocusedContent) {
-    sInstance->mFocusedContent->OwnerDoc()->
+  if (sInstance->mFocusedElement) {
+    sInstance->mFocusedElement->OwnerDoc()->
       MarkUncollectableForCCGeneration(aGeneration);
   }
   if (sInstance->mFirstBlurEvent) {
     sInstance->mFirstBlurEvent->OwnerDoc()->
       MarkUncollectableForCCGeneration(aGeneration);
   }
   if (sInstance->mFirstFocusEvent) {
     sInstance->mFirstFocusEvent->OwnerDoc()->
@@ -4144,32 +4148,32 @@ nsFocusManager::MarkUncollectableForCCGe
 bool
 nsFocusManager::CanSkipFocus(nsIContent* aContent)
 {
   if (!aContent ||
       nsContentUtils::IsChromeDoc(aContent->OwnerDoc())) {
     return false;
   }
 
-  if (mFocusedContent == aContent) {
+  if (mFocusedElement == aContent) {
     return true;
   }
 
   nsIDocShell* ds = aContent->OwnerDoc()->GetDocShell();
   if (!ds) {
     return true;
   }
 
   nsCOMPtr<nsIDocShellTreeItem> root;
   ds->GetRootTreeItem(getter_AddRefs(root));
   nsCOMPtr<nsPIDOMWindowOuter> newRootWindow =
     root ? root->GetWindow() : nullptr;
   if (mActiveWindow != newRootWindow) {
     nsPIDOMWindowOuter* outerWindow = aContent->OwnerDoc()->GetWindow();
-    if (outerWindow && outerWindow->GetFocusedNode() == aContent) {
+    if (outerWindow && outerWindow->GetFocusedElement() == aContent) {
       return true;
     }
   }
 
   return false;
 }
 
 nsresult
--- a/dom/base/nsFocusManager.h
+++ b/dom/base/nsFocusManager.h
@@ -59,20 +59,20 @@ public:
 
   /**
    * Retrieve the single focus manager.
    */
   static nsFocusManager* GetFocusManager() { return sInstance; }
 
   /**
    * A faster version of nsIFocusManager::GetFocusedElement, returning a
-   * raw Element pointer (instead of having AddRef-ed nsIDOMElement
+   * raw Element pointer (instead of having AddRef-ed Element
    * pointer filled in to an out-parameter).
    */
-  mozilla::dom::Element* GetFocusedContent() { return mFocusedContent; }
+  mozilla::dom::Element* GetFocusedElement() { return mFocusedElement; }
 
   /**
    * Returns true if aContent currently has focus.
    */
   bool IsFocused(nsIContent* aContent);
 
   /**
    * Return a focused window. Version of nsIFocusManager::GetFocusedWindow.
@@ -97,17 +97,17 @@ public:
   {
     nsCOMPtr<nsIDocument> handlingDocument = mMouseButtonEventHandlingDocument;
     mMouseButtonEventHandlingDocument = aDocument;
     return handlingDocument.forget();
   }
 
   void NeedsFlushBeforeEventHandling(mozilla::dom::Element* aElement)
   {
-    if (mFocusedContent == aElement) {
+    if (mFocusedElement == aElement) {
       mEventHandlingNeedsFlush = true;
     }
   }
 
   bool CanSkipFocus(nsIContent* aContent);
 
   void FlushBeforeEventHandlingIfNeeded(nsIContent* aContent)
   {
@@ -640,17 +640,17 @@ private:
   // the child or top-level window that is currently focused. This window will
   // either be the same window as mActiveWindow or a descendant of it.
   // Except during shutdown use SetFocusedWindowInternal to set mFocusedWindow!
   nsCOMPtr<nsPIDOMWindowOuter> mFocusedWindow;
 
   // the currently focused content, which is always inside mFocusedWindow. This
   // is a cached copy of the mFocusedWindow's current content. This may be null
   // if no content is focused.
-  RefPtr<mozilla::dom::Element> mFocusedContent;
+  RefPtr<mozilla::dom::Element> mFocusedElement;
 
   // these fields store a content node temporarily while it is being focused
   // or blurred to ensure that a recursive call doesn't refire the same event.
   // They will always be cleared afterwards.
   nsCOMPtr<nsIContent> mFirstBlurEvent;
   nsCOMPtr<nsIContent> mFirstFocusEvent;
 
   // keep track of a window while it is being lowered
--- a/dom/base/nsGlobalWindowCommands.cpp
+++ b/dom/base/nsGlobalWindowCommands.cpp
@@ -3,17 +3,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 
 #include "nsGlobalWindowCommands.h"
 
 #include "nsIComponentManager.h"
-#include "nsIDOMElement.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsCRT.h"
 #include "nsString.h"
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/Preferences.h"
 
 #include "nsIControllerCommandTable.h"
--- a/dom/base/nsGlobalWindowInner.cpp
+++ b/dom/base/nsGlobalWindowInner.cpp
@@ -106,17 +106,16 @@
 #include "nsIWidgetListener.h"
 #include "nsIBaseWindow.h"
 #include "nsIDeviceSensors.h"
 #include "nsIContent.h"
 #include "nsIDocShell.h"
 #include "nsIDocument.h"
 #include "Crypto.h"
 #include "nsIDOMDocument.h"
-#include "nsIDOMElement.h"
 #include "nsIDOMOfflineResourceList.h"
 #include "nsDOMString.h"
 #include "nsIEmbeddingSiteWindow.h"
 #include "nsThreadUtils.h"
 #include "nsILoadContext.h"
 #include "nsIPresShell.h"
 #include "nsIScrollableFrame.h"
 #include "nsView.h"
@@ -1214,17 +1213,17 @@ nsGlobalWindowInner::FreeInnerObjects()
       nsIPresShell* shell = mDoc->GetShell();
       if (shell) {
         Unused << shell->RemovePostRefreshObserver(this);
       }
     }
   }
 
   // Remove our reference to the document and the document principal.
-  mFocusedNode = nullptr;
+  mFocusedElement = nullptr;
 
   if (mApplicationCache) {
     static_cast<nsDOMOfflineResourceList*>(mApplicationCache.get())->Disconnect();
     mApplicationCache = nullptr;
   }
 
   if (mIndexedDB) {
     mIndexedDB->DisconnectFromWindow(this);
@@ -1446,17 +1445,17 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGamepads)
 
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCacheStorage)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVRDisplays)
 
   // Traverse stuff from nsPIDOMWindow
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChromeEventHandler)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParentTarget)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFocusedNode)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFocusedElement)
 
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMenubar)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mToolbar)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLocationbar)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPersonalbar)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStatusbar)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mScrollbars)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCrypto)
@@ -1534,17 +1533,17 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mGamepads)
 
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mCacheStorage)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mVRDisplays)
 
   // Unlink stuff from nsPIDOMWindow
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mChromeEventHandler)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mParentTarget)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK(mFocusedNode)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mFocusedElement)
 
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mMenubar)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mToolbar)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mLocationbar)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mPersonalbar)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mStatusbar)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mScrollbars)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mCrypto)
@@ -1695,17 +1694,17 @@ nsGlobalWindowInner::InnerSetNewDocument
     nsIURI *uri = aDocument->GetDocumentURI();
     MOZ_LOG(gDOMLeakPRLogInner, LogLevel::Debug,
             ("DOMWINDOW %p SetNewDocument %s",
              this, uri ? uri->GetSpecOrDefault().get() : ""));
   }
 
   mDoc = aDocument;
   ClearDocumentDependentSlots(aCx);
-  mFocusedNode = nullptr;
+  mFocusedElement = nullptr;
   mLocalStorage = nullptr;
   mSessionStorage = nullptr;
 
 #ifdef DEBUG
   mLastOpenedURI = aDocument->GetDocumentURI();
 #endif
 
   Telemetry::Accumulate(Telemetry::INNERWINDOWS_WITH_MUTATION_LISTENERS,
@@ -4295,24 +4294,20 @@ nsGlobalWindowInner::GetRealFrameElement
 {
   FORWARD_TO_OUTER_OR_THROW(GetRealFrameElementOuter, (), aError, nullptr);
 }
 
 /**
  * nsIGlobalWindow::GetFrameElement (when called from C++) is just a wrapper
  * around GetRealFrameElement.
  */
-already_AddRefed<nsIDOMElement>
+Element*
 nsGlobalWindowInner::GetFrameElement()
 {
-  ErrorResult dummy;
-  nsCOMPtr<nsIDOMElement> frameElement =
-    do_QueryInterface(GetRealFrameElement(dummy));
-  dummy.SuppressException();
-  return frameElement.forget();
+  return GetRealFrameElement(IgnoreErrors());
 }
 
 /* static */ bool
 nsGlobalWindowInner::TokenizeDialogOptions(nsAString& aToken,
                                            nsAString::const_iterator& aIter,
                                            nsAString::const_iterator aEnd)
 {
   while (aIter != aEnd && nsCRT::IsAsciiSpace(*aIter)) {
@@ -4647,50 +4642,50 @@ static bool ShouldShowFocusRingIfFocused
   if (!aNode) {
     return true;
   }
   return !nsContentUtils::ContentIsLink(aNode) &&
     !aNode->IsAnyOfHTMLElements(nsGkAtoms::video, nsGkAtoms::audio);
 }
 
 void
-nsGlobalWindowInner::SetFocusedNode(Element* aNode,
-                                    uint32_t aFocusMethod,
-                                    bool aNeedsFocus)
-{
-  if (aNode && aNode->GetComposedDoc() != mDoc) {
+nsGlobalWindowInner::SetFocusedElement(Element* aElement,
+                                       uint32_t aFocusMethod,
+                                       bool aNeedsFocus)
+{
+  if (aElement && aElement->GetComposedDoc() != mDoc) {
     NS_WARNING("Trying to set focus to a node from a wrong document");
     return;
   }
 
   if (IsDying()) {
-    NS_ASSERTION(!aNode, "Trying to focus cleaned up window!");
-    aNode = nullptr;
+    NS_ASSERTION(!aElement, "Trying to focus cleaned up window!");
+    aElement = nullptr;
     aNeedsFocus = false;
   }
-  if (mFocusedNode != aNode) {
-    UpdateCanvasFocus(false, aNode);
-    mFocusedNode = aNode;
+  if (mFocusedElement != aElement) {
+    UpdateCanvasFocus(false, aElement);
+    mFocusedElement = aElement;
     mFocusMethod = aFocusMethod & FOCUSMETHOD_MASK;
     mShowFocusRingForContent = false;
   }
 
-  if (mFocusedNode) {
+  if (mFocusedElement) {
     // if a node was focused by a keypress, turn on focus rings for the
     // window.
     if (mFocusMethod & nsIFocusManager::FLAG_BYKEY) {
       mFocusByKeyOccurred = true;
     } else if (
       // otherwise, we set mShowFocusRingForContent, as we don't want this to
       // be permanent for the window. On Windows, focus rings are only shown
       // when the FLAG_SHOWRING flag is used. On other platforms, focus rings
       // are only visible on some elements.
 #ifndef XP_WIN
       !(mFocusMethod & nsIFocusManager::FLAG_BYMOUSE) ||
-      ShouldShowFocusRingIfFocusedByMouse(aNode) ||
+      ShouldShowFocusRingIfFocusedByMouse(aElement) ||
 #endif
       aFocusMethod & nsIFocusManager::FLAG_SHOWRING) {
         mShowFocusRingForContent = true;
     }
   }
 
   if (aNeedsFocus)
     mNeedsFocus = aNeedsFocus;
@@ -4720,17 +4715,17 @@ nsGlobalWindowInner::TakeFocus(bool aFoc
     return false;
   }
 
   if (aFocus)
     mFocusMethod = aFocusMethod & FOCUSMETHOD_MASK;
 
   if (mHasFocus != aFocus) {
     mHasFocus = aFocus;
-    UpdateCanvasFocus(true, mFocusedNode);
+    UpdateCanvasFocus(true, mFocusedElement);
   }
 
   // if mNeedsFocus is true, then the document has not yet received a
   // document-level focus event. If there is a root content node, then return
   // true to tell the calling focus manager that a focus event is expected. If
   // there is no root content node, the document hasn't loaded enough yet, or
   // there isn't one and there is no point in firing a focus event.
   if (aFocus && mNeedsFocus && mDoc && mDoc->GetRootElement() != nullptr) {
@@ -4936,17 +4931,17 @@ nsGlobalWindowInner::UpdateCanvasFocus(b
 
   nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
   if (!presShell || !mDoc)
     return;
 
   Element *rootElement = mDoc->GetRootElement();
   if (rootElement) {
       if ((mHasFocus || aFocusChanged) &&
-          (mFocusedNode == rootElement || aNewContent == rootElement)) {
+          (mFocusedElement == rootElement || aNewContent == rootElement)) {
           nsIFrame* frame = rootElement->GetPrimaryFrame();
           if (frame) {
               frame = frame->GetParent();
               nsCanvasFrame* canvasFrame = do_QueryFrame(frame);
               if (canvasFrame) {
                   canvasFrame->SetHasFocus(mHasFocus && rootElement == aNewContent);
               }
           }
@@ -4973,38 +4968,16 @@ nsGlobalWindowInner::GetComputedStyle(El
 already_AddRefed<nsICSSDeclaration>
 nsGlobalWindowInner::GetDefaultComputedStyle(Element& aElt,
                                              const nsAString& aPseudoElt,
                                              ErrorResult& aError)
 {
   return GetComputedStyleHelper(aElt, aPseudoElt, true, aError);
 }
 
-nsresult
-nsGlobalWindowInner::GetComputedStyleHelper(nsIDOMElement* aElt,
-                                            const nsAString& aPseudoElt,
-                                            bool aDefaultStylesOnly,
-                                            nsICSSDeclaration** aReturn)
-{
-  NS_ENSURE_ARG_POINTER(aReturn);
-  *aReturn = nullptr;
-
-  nsCOMPtr<dom::Element> element = do_QueryInterface(aElt);
-  if (!element) {
-    return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
-  }
-
-  ErrorResult rv;
-  nsCOMPtr<nsICSSDeclaration> cs =
-    GetComputedStyleHelper(*element, aPseudoElt, aDefaultStylesOnly, rv);
-  cs.forget(aReturn);
-
-  return rv.StealNSResult();
-}
-
 already_AddRefed<nsICSSDeclaration>
 nsGlobalWindowInner::GetComputedStyleHelper(Element& aElt,
                                             const nsAString& aPseudoElt,
                                             bool aDefaultStylesOnly,
                                             ErrorResult& aError)
 {
   FORWARD_TO_OUTER_OR_THROW(GetComputedStyleHelperOuter,
                             (aElt, aPseudoElt, aDefaultStylesOnly),
--- a/dom/base/nsGlobalWindowInner.h
+++ b/dom/base/nsGlobalWindowInner.h
@@ -665,17 +665,17 @@ public:
   void SetOpener(JSContext* aCx, JS::Handle<JS::Value> aOpener,
                  mozilla::ErrorResult& aError);
   already_AddRefed<nsPIDOMWindowOuter> GetParent(mozilla::ErrorResult& aError);
   nsPIDOMWindowOuter* GetScriptableParent() override;
   nsPIDOMWindowOuter* GetScriptableParentOrNull() override;
   mozilla::dom::Element*
   GetFrameElement(nsIPrincipal& aSubjectPrincipal,
                   mozilla::ErrorResult& aError);
-  already_AddRefed<nsIDOMElement> GetFrameElement() override;
+  mozilla::dom::Element* GetFrameElement() override;
   already_AddRefed<nsPIDOMWindowOuter>
   Open(const nsAString& aUrl,
        const nsAString& aName,
        const nsAString& aOptions,
        mozilla::ErrorResult& aError);
   nsIDOMOfflineResourceList* GetApplicationCache(mozilla::ErrorResult& aError);
   already_AddRefed<nsIDOMOfflineResourceList> GetApplicationCache() override;
 
@@ -1192,19 +1192,19 @@ public:
 
   bool IsFrame();
 
   already_AddRefed<nsIWidget> GetMainWidget();
   nsIWidget* GetNearestWidget() const;
 
   bool IsInModalState();
 
-  virtual void SetFocusedNode(mozilla::dom::Element* aNode,
-                              uint32_t aFocusMethod = 0,
-                              bool aNeedsFocus = false) override;
+  virtual void SetFocusedElement(mozilla::dom::Element* aElement,
+                                 uint32_t aFocusMethod = 0,
+                                 bool aNeedsFocus = false) override;
 
   virtual uint32_t GetFocusMethod() override;
 
   virtual bool ShouldShowFocusRing() override;
 
   // Inner windows only.
   void UpdateCanvasFocus(bool aFocusChanged, nsIContent* aNewContent);
 
@@ -1236,20 +1236,16 @@ protected:
                     mozilla::ErrorResult& aRv);
 
 protected:
   already_AddRefed<nsICSSDeclaration>
     GetComputedStyleHelper(mozilla::dom::Element& aElt,
                            const nsAString& aPseudoElt,
                            bool aDefaultStylesOnly,
                            mozilla::ErrorResult& aError);
-  nsresult GetComputedStyleHelper(nsIDOMElement* aElt,
-                                  const nsAString& aPseudoElt,
-                                  bool aDefaultStylesOnly,
-                                  nsICSSDeclaration** aReturn);
 
   nsGlobalWindowInner* InnerForSetTimeoutOrInterval(mozilla::ErrorResult& aError);
 
   void PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
                       const nsAString& aTargetOrigin,
                       JS::Handle<JS::Value> aTransfer,
                       nsIPrincipal& aSubjectPrincipal,
                       mozilla::ErrorResult& aError);
--- a/dom/base/nsGlobalWindowOuter.cpp
+++ b/dom/base/nsGlobalWindowOuter.cpp
@@ -103,17 +103,16 @@
 #include "nsIWidgetListener.h"
 #include "nsIBaseWindow.h"
 #include "nsIDeviceSensors.h"
 #include "nsIContent.h"
 #include "nsIDocShell.h"
 #include "nsIDocument.h"
 #include "Crypto.h"
 #include "nsIDOMDocument.h"
-#include "nsIDOMElement.h"
 #include "nsIDOMOfflineResourceList.h"
 #include "nsDOMString.h"
 #include "nsIEmbeddingSiteWindow.h"
 #include "nsThreadUtils.h"
 #include "nsILoadContext.h"
 #include "nsIPresShell.h"
 #include "nsIScrollableFrame.h"
 #include "nsView.h"
@@ -4868,20 +4867,19 @@ nsGlobalWindowOuter::BlurOuter()
   nsCOMPtr<nsIEmbeddingSiteWindow> siteWindow(do_GetInterface(treeOwner));
   if (siteWindow) {
     // This method call may cause mDocShell to become nullptr.
     siteWindow->Blur();
 
     // if the root is focused, clear the focus
     nsIFocusManager* fm = nsFocusManager::GetFocusManager();
     if (fm && mDoc) {
-      nsCOMPtr<nsIDOMElement> element;
+      RefPtr<Element> element;
       fm->GetFocusedElementForWindow(this, false, nullptr, getter_AddRefs(element));
-      nsCOMPtr<nsIContent> content = do_QueryInterface(element);
-      if (content == mDoc->GetRootElement()) {
+      if (element == mDoc->GetRootElement()) {
         fm->ClearFocus(this);
       }
     }
   }
 }
 
 void
 nsGlobalWindowOuter::BackOuter(ErrorResult& aError)
@@ -6212,17 +6210,17 @@ nsGlobalWindowOuter::GetRealFrameElement
 
   return mFrameElement;
 }
 
 /**
  * nsIGlobalWindow::GetFrameElement (when called from C++) is just a wrapper
  * around GetRealFrameElement.
  */
-already_AddRefed<nsIDOMElement>
+Element*
 nsGlobalWindowOuter::GetFrameElement()
 {
   FORWARD_TO_INNER(GetFrameElement, (), nullptr);
 }
 
 namespace {
 class ChildCommandDispatcher : public Runnable
 {
@@ -6621,21 +6619,22 @@ nsGlobalWindowOuter::SetChromeEventHandl
     inner = static_cast<nsGlobalWindowInner*>(node);
     NS_ASSERTION(!inner->mOuterWindow || inner->mOuterWindow == this,
                  "bad outer window pointer");
     inner->SetChromeEventHandlerInternal(aChromeEventHandler);
   }
 }
 
 void
-nsGlobalWindowOuter::SetFocusedNode(Element* aNode,
-                                    uint32_t aFocusMethod,
-                                    bool aNeedsFocus)
-{
-  FORWARD_TO_INNER_VOID(SetFocusedNode, (aNode, aFocusMethod, aNeedsFocus));
+nsGlobalWindowOuter::SetFocusedElement(Element* aElement,
+                                       uint32_t aFocusMethod,
+                                       bool aNeedsFocus)
+{
+  FORWARD_TO_INNER_VOID(SetFocusedElement,
+                        (aElement, aFocusMethod, aNeedsFocus));
 }
 
 uint32_t
 nsGlobalWindowOuter::GetFocusMethod()
 {
   FORWARD_TO_INNER(GetFocusMethod, (), 0);
 }
 
@@ -6672,23 +6671,23 @@ nsGlobalWindowOuter::SetKeyboardIndicato
   }
 
   nsContentUtils::SetKeyboardIndicatorsOnRemoteChildren(GetOuterWindow(),
                                                         aShowAccelerators,
                                                         aShowFocusRings);
 
   bool newShouldShowFocusRing = ShouldShowFocusRing();
   if (mInnerWindow && nsGlobalWindowInner::Cast(mInnerWindow)->mHasFocus &&
-      mInnerWindow->mFocusedNode &&
+      mInnerWindow->mFocusedElement &&
       oldShouldShowFocusRing != newShouldShowFocusRing) {
     // Update focusedNode's state.
     if (newShouldShowFocusRing) {
-      mInnerWindow->mFocusedNode->AddStates(NS_EVENT_STATE_FOCUSRING);
+      mInnerWindow->mFocusedElement->AddStates(NS_EVENT_STATE_FOCUSRING);
     } else {
-      mInnerWindow->mFocusedNode->RemoveStates(NS_EVENT_STATE_FOCUSRING);
+      mInnerWindow->mFocusedElement->RemoveStates(NS_EVENT_STATE_FOCUSRING);
     }
   }
 }
 
 bool
 nsGlobalWindowOuter::TakeFocus(bool aFocus, uint32_t aFocusMethod)
 {
   FORWARD_TO_INNER(TakeFocus, (aFocus, aFocusMethod), false);
@@ -7253,24 +7252,24 @@ nsGlobalWindowOuter::RestoreWindowState(
   printf("restoring window state, state = %p\n", (void*)holder);
 #endif
 
   // And we're ready to go!
   nsGlobalWindowInner *inner = GetCurrentInnerWindowInternal();
 
   // if a link is focused, refocus with the FLAG_SHOWRING flag set. This makes
   // it easy to tell which link was last clicked when going back a page.
-  Element* focusedNode = inner->GetFocusedNode();
-  if (nsContentUtils::ContentIsLink(focusedNode)) {
+  Element* focusedElement = inner->GetFocusedElement();
+  if (nsContentUtils::ContentIsLink(focusedElement)) {
     nsIFocusManager* fm = nsFocusManager::GetFocusManager();
     if (fm) {
       // XXXbz Do we need the stack strong ref here?
-      RefPtr<Element> focusedElement = focusedNode;
-      fm->SetFocus(focusedElement, nsIFocusManager::FLAG_NOSCROLL |
-                                   nsIFocusManager::FLAG_SHOWRING);
+      RefPtr<Element> kungFuDeathGrip(focusedElement);
+      fm->SetFocus(kungFuDeathGrip, nsIFocusManager::FLAG_NOSCROLL |
+                                    nsIFocusManager::FLAG_SHOWRING);
     }
   }
 
   inner->Thaw();
 
   holder->DidRestoreWindow();
 
   return NS_OK;
--- a/dom/base/nsGlobalWindowOuter.h
+++ b/dom/base/nsGlobalWindowOuter.h
@@ -598,17 +598,17 @@ public:
 
   already_AddRefed<nsPIDOMWindowOuter> GetOpener() override;
   already_AddRefed<nsPIDOMWindowOuter> GetParentOuter();
   already_AddRefed<nsPIDOMWindowOuter> GetParent() override;
   nsPIDOMWindowOuter* GetScriptableParent() override;
   nsPIDOMWindowOuter* GetScriptableParentOrNull() override;
   mozilla::dom::Element*
   GetFrameElementOuter(nsIPrincipal& aSubjectPrincipal);
-  already_AddRefed<nsIDOMElement> GetFrameElement() override;
+  mozilla::dom::Element* GetFrameElement() override;
   already_AddRefed<nsPIDOMWindowOuter>
   OpenOuter(const nsAString& aUrl,
             const nsAString& aName,
             const nsAString& aOptions,
             mozilla::ErrorResult& aError);
   nsresult Open(const nsAString& aUrl, const nsAString& aName,
                 const nsAString& aOptions,
                 nsIDocShellLoadInfo* aLoadInfo,
@@ -974,19 +974,19 @@ public:
   // Convenience functions for the many methods that need to scale
   // from device to CSS pixels or vice versa.  Note: if a presentation
   // context is not available, they will assume a 1:1 ratio.
   int32_t DevToCSSIntPixels(int32_t px);
   int32_t CSSToDevIntPixels(int32_t px);
   nsIntSize DevToCSSIntPixels(nsIntSize px);
   nsIntSize CSSToDevIntPixels(nsIntSize px);
 
-  virtual void SetFocusedNode(mozilla::dom::Element* aNode,
-                              uint32_t aFocusMethod = 0,
-                              bool aNeedsFocus = false) override;
+  virtual void SetFocusedElement(mozilla::dom::Element* aElement,
+                                 uint32_t aFocusMethod = 0,
+                                 bool aNeedsFocus = false) override;
 
   virtual uint32_t GetFocusMethod() override;
 
   virtual bool ShouldShowFocusRing() override;
 
   virtual void SetKeyboardIndicators(UIStateChangeType aShowAccelerators,
                                      UIStateChangeType aShowFocusRings) override;
 
--- a/dom/base/nsHTMLContentSerializer.cpp
+++ b/dom/base/nsHTMLContentSerializer.cpp
@@ -7,17 +7,16 @@
 /*
  * nsIContentSerializer implementation that can be used with an
  * nsIDocumentEncoder to convert an HTML (not XHTML!) DOM to an HTML
  * string that could be parsed into more or less the original DOM.
  */
 
 #include "nsHTMLContentSerializer.h"
 
-#include "nsIDOMElement.h"
 #include "nsIContent.h"
 #include "nsIDocument.h"
 #include "nsElementTable.h"
 #include "nsNameSpaceManager.h"
 #include "nsString.h"
 #include "nsUnicharUtils.h"
 #include "nsIServiceManager.h"
 #include "nsIDocumentEncoder.h"
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -89,17 +89,16 @@ class nsIBFCacheEntry;
 class nsIChannel;
 class nsIContent;
 class nsIContentSink;
 class nsIDocShell;
 class nsIDocShellTreeItem;
 class nsIDocumentEncoder;
 class nsIDocumentObserver;
 class nsIDOMDocument;
-class nsIDOMElement;
 class nsIHTMLCollection;
 class nsILayoutHistoryState;
 class nsILoadContext;
 class nsIObjectLoadingContent;
 class nsIObserver;
 class nsIPrincipal;
 class nsIRequest;
 class nsIRunnable;
@@ -1785,17 +1784,17 @@ public:
   void FullScreenStackPop();
 
   /**
    * Called when a frame in a child process has entered fullscreen or when a
    * fullscreen frame in a child process changes to another origin.
    * aFrameElement is the frame element which contains the child-process
    * fullscreen document.
    */
-  nsresult RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement);
+  nsresult RemoteFrameFullscreenChanged(mozilla::dom::Element* aFrameElement);
 
   /**
    * Called when a frame in a remote child document has rolled back fullscreen
    * so that all its fullscreen element stacks are empty; we must continue the
    * rollback in this parent process' doc tree branch which is fullscreen.
    * Note that only one branch of the document tree can have its documents in
    * fullscreen state at one time. We're in inconsistent state if a
    * fullscreen document has a parent and that parent isn't fullscreen. We
--- a/dom/base/nsINode.h
+++ b/dom/base/nsINode.h
@@ -37,17 +37,16 @@
 #endif
 
 class nsAttrAndChildArray;
 class nsAttrChildContentList;
 class nsDOMAttributeMap;
 class nsIAnimationObserver;
 class nsIContent;
 class nsIDocument;
-class nsIDOMElement;
 class nsIFrame;
 class nsIMutationObserver;
 class nsINode;
 class nsINodeList;
 class nsIPresShell;
 class nsIPrincipal;
 class nsIURI;
 class nsNodeSupportsWeakRefTearoff;
--- a/dom/base/nsIObjectLoadingContent.idl
+++ b/dom/base/nsIObjectLoadingContent.idl
@@ -4,17 +4,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
 interface nsIRequest;
 interface nsIFrame;
 interface nsIObjectFrame;
 interface nsIPluginTag;
-interface nsIDOMElement;
 interface nsIURI;
 
 %{C++
 class nsNPAPIPluginInstance;
 %}
 [ptr] native nsNPAPIPluginInstancePtr(nsNPAPIPluginInstance);
 
 /**
--- a/dom/base/nsInProcessTabChildGlobal.h
+++ b/dom/base/nsInProcessTabChildGlobal.h
@@ -12,17 +12,16 @@
 #include "mozilla/dom/ContentFrameMessageManager.h"
 #include "nsCOMPtr.h"
 #include "nsFrameMessageManager.h"
 #include "nsIScriptContext.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsIScriptContext.h"
 #include "nsIClassInfo.h"
 #include "nsIDocShell.h"
-#include "nsIDOMElement.h"
 #include "nsCOMArray.h"
 #include "nsIRunnable.h"
 #include "nsIGlobalObject.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsWeakReference.h"
 
 namespace mozilla {
 class EventChainPreVisitor;
--- a/dom/base/nsPIDOMWindow.h
+++ b/dom/base/nsPIDOMWindow.h
@@ -479,20 +479,20 @@ public:
   /*
    * Get and set the currently focused element within the document. If
    * aNeedsFocus is true, then set mNeedsFocus to true to indicate that a
    * document focus event is needed.
    *
    * DO NOT CALL EITHER OF THESE METHODS DIRECTLY. USE THE FOCUS MANAGER
    * INSTEAD.
    */
-  inline mozilla::dom::Element* GetFocusedNode() const;
-  virtual void SetFocusedNode(mozilla::dom::Element* aNode,
-                              uint32_t aFocusMethod = 0,
-                              bool aNeedsFocus = false) = 0;
+  inline mozilla::dom::Element* GetFocusedElement() const;
+  virtual void SetFocusedElement(mozilla::dom::Element* aElement,
+                                 uint32_t aFocusMethod = 0,
+                                 bool aNeedsFocus = false) = 0;
 
   /**
    * Retrieves the method that was used to focus the current node.
    */
   virtual uint32_t GetFocusMethod() = 0;
 
   /*
    * Tells the window that it now has focus or has lost focus, based on the
@@ -591,17 +591,17 @@ public:
 
   virtual nsresult GetInnerWidth(int32_t* aWidth) = 0;
   virtual nsresult GetInnerHeight(int32_t* aHeight) = 0;
 
   virtual already_AddRefed<nsICSSDeclaration>
   GetComputedStyle(mozilla::dom::Element& aElt, const nsAString& aPseudoElt,
                    mozilla::ErrorResult& aError) = 0;
 
-  virtual already_AddRefed<nsIDOMElement> GetFrameElement() = 0;
+  virtual mozilla::dom::Element* GetFrameElement() = 0;
 
   virtual already_AddRefed<nsIDOMOfflineResourceList> GetApplicationCache() = 0;
 
   virtual bool GetFullScreen() = 0;
 
   virtual nsresult Focus() = 0;
   virtual nsresult Close() = 0;
 
@@ -653,19 +653,19 @@ protected:
   bool mMayHaveMouseEnterLeaveEventListener;
   bool mMayHavePointerEnterLeaveEventListener;
 
   bool mAudioCaptured;
 
   // Our inner window's outer window.
   nsCOMPtr<nsPIDOMWindowOuter> mOuterWindow;
 
-  // the element within the document that is currently focused when this
+  // The element within the document that is currently focused when this
   // window is active.
-  RefPtr<mozilla::dom::Element> mFocusedNode;
+  RefPtr<mozilla::dom::Element> mFocusedElement;
 
   // The AudioContexts created for the current document, if any.
   nsTArray<mozilla::dom::AudioContext*> mAudioContexts; // Weak
 
   RefPtr<mozilla::dom::TabGroup> mTabGroup;
 
   // A unique (as long as our 64-bit counter doesn't roll over) id for
   // this window.
@@ -968,20 +968,20 @@ public:
   /*
    * Get and set the currently focused element within the document. If
    * aNeedsFocus is true, then set mNeedsFocus to true to indicate that a
    * document focus event is needed.
    *
    * DO NOT CALL EITHER OF THESE METHODS DIRECTLY. USE THE FOCUS MANAGER
    * INSTEAD.
    */
-  inline mozilla::dom::Element* GetFocusedNode() const;
-  virtual void SetFocusedNode(mozilla::dom::Element* aNode,
-                              uint32_t aFocusMethod = 0,
-                              bool aNeedsFocus = false) = 0;
+  inline mozilla::dom::Element* GetFocusedElement() const;
+  virtual void SetFocusedElement(mozilla::dom::Element* aElement,
+                                 uint32_t aFocusMethod = 0,
+                                 bool aNeedsFocus = false) = 0;
 
   /**
    * Retrieves the method that was used to focus the current node.
    */
   virtual uint32_t GetFocusMethod() = 0;
 
   /*
    * Tells the window that it now has focus or has lost focus, based on the
@@ -1102,17 +1102,17 @@ public:
   virtual nsresult OpenDialog(const nsAString& aUrl, const nsAString& aName,
                               const nsAString& aOptions,
                               nsISupports* aExtraArgument,
                               nsPIDOMWindowOuter** _retval) = 0;
 
   virtual nsresult GetInnerWidth(int32_t* aWidth) = 0;
   virtual nsresult GetInnerHeight(int32_t* aHeight) = 0;
 
-  virtual already_AddRefed<nsIDOMElement> GetFrameElement() = 0;
+  virtual mozilla::dom::Element* GetFrameElement() = 0;
 
   virtual bool Closed() = 0;
   virtual bool GetFullScreen() = 0;
   virtual nsresult SetFullScreen(bool aFullScreen) = 0;
 
   virtual nsresult Focus() = 0;
   virtual nsresult Close() = 0;
 
--- a/dom/base/nsPIDOMWindowInlines.h
+++ b/dom/base/nsPIDOMWindowInlines.h
@@ -85,18 +85,18 @@ nsPIDOMWindowOuter::GetDocShell() const
 
 nsIDocShell*
 nsPIDOMWindowInner::GetDocShell() const
 {
   return mOuterWindow ? mOuterWindow->GetDocShell() : nullptr;
 }
 
 mozilla::dom::Element*
-nsPIDOMWindowOuter::GetFocusedNode() const
+nsPIDOMWindowOuter::GetFocusedElement() const
 {
-  return mInnerWindow ? mInnerWindow->GetFocusedNode() : nullptr;
+  return mInnerWindow ? mInnerWindow->GetFocusedElement() : nullptr;
 }
 
 mozilla::dom::Element*
-nsPIDOMWindowInner::GetFocusedNode() const
+nsPIDOMWindowInner::GetFocusedElement() const
 {
-  return mFocusedNode;
+  return mFocusedElement;
 }
--- a/dom/base/nsXHTMLContentSerializer.cpp
+++ b/dom/base/nsXHTMLContentSerializer.cpp
@@ -7,17 +7,16 @@
 /*
  * nsIContentSerializer implementation that can be used with an
  * nsIDocumentEncoder to convert an XHTML (not HTML!) DOM to an XHTML
  * string that could be parsed into more or less the original DOM.
  */
 
 #include "nsXHTMLContentSerializer.h"
 
-#include "nsIDOMElement.h"
 #include "nsIContent.h"
 #include "nsIDocument.h"
 #include "nsElementTable.h"
 #include "nsNameSpaceManager.h"
 #include "nsString.h"
 #include "nsUnicharUtils.h"
 #include "nsIServiceManager.h"
 #include "nsIDocumentEncoder.h"
--- a/dom/base/test/unit/head_xml.js
+++ b/dom/base/test/unit/head_xml.js
@@ -8,20 +8,19 @@ const I                    = Ci;
 const C                    = Cc;
 
 const nsIFile         = I.nsIFile;
 const nsIProperties        = I.nsIProperties;
 const nsIFileInputStream   = I.nsIFileInputStream;
 const nsIInputStream       = I.nsIInputStream;
 
 const nsIDOMDocument       = I.nsIDOMDocument;
-const nsIDOMElement        = I.nsIDOMElement;
 const nsIDOMNode           = I.nsIDOMNode;
 
-Cu.importGlobalProperties(["DOMParser", "XMLSerializer"]);
+Cu.importGlobalProperties(["DOMParser", "Element", "XMLSerializer"]);
 
 function getParser() {
   var parser = new DOMParser();
   parser.forceEnableXULXBL();
   return parser;
 }
 
 var __testsDirectory = null;
--- a/dom/base/test/unit/test_nodelist.js
+++ b/dom/base/test/unit/test_nodelist.js
@@ -35,17 +35,17 @@ function test_getElementsByTagName()
   // the right thing.
   Assert.equal(doc.getElementsByTagName("*").item(0), root);
 
   // Check that we get the right things in the right order
   var numTests = doc.getElementsByTagName("test").length;
   Assert.equal(numTests, 5);
 
   for (var i = 1; i <= numTests; ++i) {
-    Assert.ok(doc.getElementById("test" + i) instanceof nsIDOMElement);
+    Assert.ok(Element.isInstance(doc.getElementById("test" + i)));
     Assert.equal(doc.getElementById("test" + i),
                  doc.getElementsByTagName("test").item(i-1));
   }
 
   // Check that we handle tagnames containing ':' correctly
   Assert.equal(ChromeUtils.getClassName(doc.getElementsByTagName("foo:test")),
                "HTMLCollection");
   Assert.equal(doc.getElementsByTagName("foo:test").length, 2);
@@ -98,17 +98,17 @@ function test_getElementsByTagNameNS()
 
   // Check that we get the right things in the right order
 
      
   var numTests = doc.getElementsByTagNameNS("*", "test").length;
   Assert.equal(numTests, 14);
 
   for (var i = 1; i <= numTests; ++i) {
-    Assert.ok(doc.getElementById("test" + i) instanceof nsIDOMElement);
+    Assert.ok(Element.isInstance(doc.getElementById("test" + i)));
     Assert.equal(doc.getElementById("test" + i),
                  doc.getElementsByTagNameNS("*", "test").item(i-1));
   }
 
   // Check general proper functioning of having a non-wildcard namespace.
   var test2 = doc.getElementById("test2");
   Assert.equal(doc.getElementsByTagNameNS("", "test").length,
                3);
--- a/dom/base/test/unit/test_range.js
+++ b/dom/base/test/unit/test_range.js
@@ -143,17 +143,17 @@ function evalXPathInDocumentFragment(aCo
  * Get a DOM range corresponding to the test's source node.
  *
  * @param aSourceNode <source/> element with range information.
  * @param aFragment   DocumentFragment generated with getFragment().
  *
  * @return Range object.
  */
 function getRange(aSourceNode, aFragment) {
-  Assert.ok(aSourceNode instanceof Ci.nsIDOMElement);
+  Assert.ok(Element.isInstance(aSourceNode));
   Assert.equal(ChromeUtils.getClassName(aFragment), "DocumentFragment");
   var doc = aSourceNode.ownerDocument;
 
   var containerPath = aSourceNode.getAttribute("startContainer");
   var startContainer = evalXPathInDocumentFragment(aFragment, containerPath);
   var startOffset = Number(aSourceNode.getAttribute("startOffset"));
 
   containerPath = aSourceNode.getAttribute("endContainer");
--- a/dom/base/test/unit/test_xml_parser.js
+++ b/dom/base/test/unit/test_xml_parser.js
@@ -4,33 +4,33 @@ function run_test () {
       do_throw(tests[i][1]);
     }
   }
 }
 
 var tests = [
   [ test1, "Unable to parse basic XML document" ],
   [ test2, "ParseXML doesn't return nsIDOMDocument" ],
-  [ test3, "ParseXML return value's documentElement is not nsIDOMElement" ],
+  [ test3, "ParseXML return value's documentElement is not Element" ],
   [ test4, "" ],
   [ test5, "" ],
   [ test6, "" ],
   [ null ]
 ];
 
 function test1() {
   return ParseXML("<root/>");
 }
 
 function test2() {
   return (ParseXML("<root/>") instanceof nsIDOMDocument);
 }
 
 function test3() {
-  return (ParseXML("<root/>").documentElement instanceof nsIDOMElement);
+  return Element.isInstance(ParseXML("<root/>").documentElement);
 }
 
 function test4() {
   var doc = ParseXML("<root/>");
   Assert.equal(doc.documentElement.namespaceURI, null); 
   return true;
 }
 
--- a/dom/base/test/unit/test_xml_serializer.js
+++ b/dom/base/test/unit/test_xml_serializer.js
@@ -129,18 +129,17 @@ function test4() {
   Assert.equal(SerializeXML(doc),
                  '<root xmlns="ns1" a0:local="val" xmlns:a0="ns1"/>');
 
   // Tree-walking test
   doc = ParseXML('<root xmlns="ns1" xmlns:a="ns2">'+
                  '<child xmlns:b="ns2" xmlns:a="ns3">'+
                  '<child2/></child></root>');
   root = doc.documentElement;
-  // Have to QI here -- no classinfo flattening in xpcshell, apparently
-  var node = root.firstChild.firstChild.QueryInterface(nsIDOMElement);
+  var node = root.firstChild.firstChild;
   node.setAttributeNS("ns4", "l1", "v1");
   node.setAttributeNS("ns4", "p2:l2", "v2");
   node.setAttributeNS("", "l3", "v3");
   node.setAttributeNS("ns3", "l4", "v4");
   node.setAttributeNS("ns3", "p5:l5", "v5");
   node.setAttributeNS("ns3", "a:l6", "v6");
   node.setAttributeNS("ns2", "l7", "v7");
   node.setAttributeNS("ns2", "p8:l8", "v8");
@@ -246,33 +245,31 @@ function test7() {
                       "http://www.w3.org/1999/xhtml");
   do_check_serialize(doc);
   Assert.equal(SerializeXML(doc), '<root><child1/></root>');
 
   doc = ParseXML('<root xmlns="http://www.w3.org/1999/xhtml">' +
                  '<child1 xmlns=""><child2/></child1></root>')
   root = doc.documentElement;
 
-  // No interface flattening in xpcshell
-  var child1 = root.firstChild.QueryInterface(nsIDOMElement);
+  var child1 = root.firstChild;
   child1.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns",
                         "http://www.w3.org/1999/xhtml");
   do_check_serialize(doc);
   Assert.equal(SerializeXML(doc),
                '<root xmlns="http://www.w3.org/1999/xhtml"><child1 xmlns="">' +
                '<child2/></child1></root>');
 
   doc = ParseXML('<root xmlns="http://www.w3.org/1999/xhtml">' +
                  '<child1 xmlns="">' +
                  '<child2 xmlns="http://www.w3.org/1999/xhtml"></child2>' +
                  '</child1></root>')
   root = doc.documentElement;
-  // No interface flattening in xpcshell
-  child1 = root.firstChild.QueryInterface(nsIDOMElement);
-  var child2 = child1.firstChild.QueryInterface(nsIDOMElement);
+  child1 = root.firstChild;
+  var child2 = child1.firstChild;
   child1.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns",
                         "http://www.w3.org/1999/xhtml");
   child2.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", "");
   do_check_serialize(doc);
   Assert.equal(SerializeXML(doc),
                '<root xmlns="http://www.w3.org/1999/xhtml"><child1 xmlns="">' +
                '<a0:child2 xmlns:a0="http://www.w3.org/1999/xhtml" xmlns=""></a0:child2></child1></root>');
 }
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -177,16 +177,22 @@ struct TErrorResult<CleanupPolicy>::Mess
 
   nsTArray<nsString> mArgs;
   dom::ErrNum mErrorNumber;
 
   bool HasCorrectNumberOfArguments()
   {
     return GetErrorArgCount(mErrorNumber) == mArgs.Length();
   }
+
+  bool operator==(const TErrorResult<CleanupPolicy>::Message& aRight)
+  {
+    return mErrorNumber == aRight.mErrorNumber &&
+           mArgs == aRight.mArgs;
+  }
 };
 
 template<typename CleanupPolicy>
 nsTArray<nsString>&
 TErrorResult<CleanupPolicy>::CreateErrorMessageHelper(const dom::ErrNum errorNumber,
                                                       nsresult errorType)
 {
   AssertInOwningThread();
@@ -328,16 +334,22 @@ template<typename CleanupPolicy>
 struct TErrorResult<CleanupPolicy>::DOMExceptionInfo {
   DOMExceptionInfo(nsresult rv, const nsACString& message)
     : mMessage(message)
     , mRv(rv)
   {}
 
   nsCString mMessage;
   nsresult mRv;
+
+  bool operator==(const TErrorResult<CleanupPolicy>::DOMExceptionInfo& aRight)
+  {
+    return mRv == aRight.mRv &&
+           mMessage == aRight.mMessage;
+  }
 };
 
 template<typename CleanupPolicy>
 void
 TErrorResult<CleanupPolicy>::SerializeDOMExceptionInfo(IPC::Message* aMsg) const
 {
   using namespace IPC;
   AssertInOwningThread();
@@ -497,17 +509,16 @@ TErrorResult<CleanupPolicy>::operator=(T
 }
 
 template<typename CleanupPolicy>
 void
 TErrorResult<CleanupPolicy>::CloneTo(TErrorResult& aRv) const
 {
   AssertInOwningThread();
   aRv.AssertInOwningThread();
-
   aRv.ClearUnionData();
   aRv.mResult = mResult;
 #ifdef DEBUG
   aRv.mMightHaveUnreportedJSException = mMightHaveUnreportedJSException;
 #endif
 
   if (IsErrorWithMessage()) {
 #ifdef DEBUG
@@ -607,16 +618,17 @@ TErrorResult<CleanupPolicy>::NoteJSConte
   } else {
     mResult = NS_ERROR_UNCATCHABLE_EXCEPTION;
   }
 }
 
 template class TErrorResult<JustAssertCleanupPolicy>;
 template class TErrorResult<AssertAndSuppressCleanupPolicy>;
 template class TErrorResult<JustSuppressCleanupPolicy>;
+template class TErrorResult<ThreadSafeJustSuppressCleanupPolicy>;
 
 } // namespace binding_danger
 
 namespace dom {
 
 bool
 DefineConstants(JSContext* cx, JS::Handle<JSObject*> obj,
                 const ConstantSpec* cs)
--- a/dom/bindings/ErrorIPCUtils.h
+++ b/dom/bindings/ErrorIPCUtils.h
@@ -74,11 +74,28 @@ struct ParamTraits<mozilla::ErrorResult>
                !readValue.DeserializeDOMExceptionInfo(aMsg, aIter)) {
       return false;
     }
     *aResult = Move(readValue);
     return true;
   }
 };
 
+template<>
+struct ParamTraits<mozilla::CopyableErrorResult>
+{
+  typedef mozilla::CopyableErrorResult paramType;
+
+  static void Write(Message* aMsg, const paramType& aParam)
+  {
+    ParamTraits<mozilla::ErrorResult>::Write(aMsg, aParam);
+  }
+
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
+  {
+    mozilla::ErrorResult& ref = static_cast<mozilla::ErrorResult&>(*aResult);
+    return ParamTraits<mozilla::ErrorResult>::Read(aMsg, aIter, &ref);
+  }
+};
+
 } // namespace IPC
 
 #endif
--- a/dom/bindings/ErrorResult.h
+++ b/dom/bindings/ErrorResult.h
@@ -160,16 +160,17 @@ public:
 
   explicit TErrorResult(nsresult aRv)
     : TErrorResult()
   {
     AssignErrorCode(aRv);
   }
 
   operator ErrorResult&();
+  operator const ErrorResult&() const;
   operator OOMReporter&();
 
   void MOZ_MUST_RETURN_FROM_CALLER Throw(nsresult rv) {
     MOZ_ASSERT(NS_FAILED(rv), "Please don't try throwing success");
     AssignErrorCode(rv);
   }
 
   // This method acts identically to the `Throw` method, however, it does not
@@ -386,16 +387,18 @@ public:
     return mResult == rv;
   }
 
   // For use in logging ONLY.
   uint32_t ErrorCodeAsInt() const {
     return static_cast<uint32_t>(ErrorCode());
   }
 
+  bool operator==(const ErrorResult& aRight) const;
+
 protected:
   nsresult ErrorCode() const {
     return mResult;
   }
 
 private:
 #ifdef DEBUG
   enum UnionState {
@@ -434,17 +437,19 @@ private:
                                      Forward<Ts>(messageArgs)...);
 #ifdef DEBUG
     mUnionState = HasMessage;
 #endif // DEBUG
   }
 
   MOZ_ALWAYS_INLINE void AssertInOwningThread() const {
 #ifdef DEBUG
-    NS_ASSERT_OWNINGTHREAD(TErrorResult);
+    if (CleanupPolicy::assertSameThread) {
+      NS_ASSERT_OWNINGTHREAD(TErrorResult);
+    }
 #endif
   }
 
   void AssignErrorCode(nsresult aRv) {
     MOZ_ASSERT(aRv != NS_ERROR_INTERNAL_ERRORRESULT_TYPEERROR,
                "Use ThrowTypeError()");
     MOZ_ASSERT(aRv != NS_ERROR_INTERNAL_ERRORRESULT_RANGEERROR,
                "Use ThrowRangeError()");
@@ -561,26 +566,35 @@ private:
   // reference, not by value.
   TErrorResult(const TErrorResult&) = delete;
   void operator=(const TErrorResult&) = delete;
 };
 
 struct JustAssertCleanupPolicy {
   static const bool assertHandled = true;
   static const bool suppress = false;
+  static const bool assertSameThread = true;
 };
 
 struct AssertAndSuppressCleanupPolicy {
   static const bool assertHandled = true;
   static const bool suppress = true;
+  static const bool assertSameThread = true;
 };
 
 struct JustSuppressCleanupPolicy {
   static const bool assertHandled = false;
   static const bool suppress = true;
+  static const bool assertSameThread = true;
+};
+
+struct ThreadSafeJustSuppressCleanupPolicy {
+  static const bool assertHandled = false;
+  static const bool suppress = true;
+  static const bool assertSameThread = false;
 };
 
 } // namespace binding_danger
 
 // A class people should normally use on the stack when they plan to actually
 // do something with the exception.
 class ErrorResult :
     public binding_danger::TErrorResult<binding_danger::AssertAndSuppressCleanupPolicy>
@@ -620,24 +634,125 @@ private:
 
 template<typename CleanupPolicy>
 binding_danger::TErrorResult<CleanupPolicy>::operator ErrorResult&()
 {
   return *static_cast<ErrorResult*>(
      reinterpret_cast<TErrorResult<AssertAndSuppressCleanupPolicy>*>(this));
 }
 
+template<typename CleanupPolicy>
+binding_danger::TErrorResult<CleanupPolicy>::operator const ErrorResult&() const
+{
+  return *static_cast<const ErrorResult*>(
+     reinterpret_cast<const TErrorResult<AssertAndSuppressCleanupPolicy>*>(this));
+}
+
+template<typename CleanupPolicy>
+bool
+binding_danger::TErrorResult<CleanupPolicy>::operator==(const ErrorResult& aRight) const
+{
+  auto right = reinterpret_cast<const TErrorResult<CleanupPolicy>*>(&aRight);
+
+  if (mResult != right->mResult) {
+    return false;
+  }
+
+  if (IsJSException()) {
+    // js exceptions are always non-equal
+    return false;
+  }
+
+  if (IsErrorWithMessage()) {
+    return *mExtra.mMessage == *right->mExtra.mMessage;
+  }
+
+  if (IsDOMException()) {
+    return *mExtra.mDOMExceptionInfo == *right->mExtra.mDOMExceptionInfo;
+  }
+
+  return true;
+}
+
 // A class for use when an ErrorResult should just automatically be ignored.
 // This doesn't inherit from ErrorResult so we don't make two separate calls to
 // SuppressException.
 class IgnoredErrorResult :
     public binding_danger::TErrorResult<binding_danger::JustSuppressCleanupPolicy>
 {
 };
 
+// A class for use when an ErrorResult needs to be copied to a lambda, into
+// an IPDL structure, etc.  Since this will often involve crossing thread
+// boundaries this class will assert if you try to copy a JS exception.  Only
+// use this if you are propagating internal errors.  In general its best
+// to use ErrorResult by default and only convert to a CopyableErrorResult when
+// you need it.
+class CopyableErrorResult :
+    public binding_danger::TErrorResult<binding_danger::ThreadSafeJustSuppressCleanupPolicy>
+{
+  typedef binding_danger::TErrorResult<binding_danger::ThreadSafeJustSuppressCleanupPolicy> BaseErrorResult;
+
+public:
+  CopyableErrorResult()
+    : BaseErrorResult()
+  {}
+
+  explicit CopyableErrorResult(const ErrorResult& aRight)
+    : BaseErrorResult()
+  {
+    auto val = reinterpret_cast<const CopyableErrorResult&>(aRight);
+    operator=(val);
+  }
+
+  CopyableErrorResult(CopyableErrorResult&& aRHS)
+    : BaseErrorResult(Move(aRHS))
+  {}
+
+  explicit CopyableErrorResult(nsresult aRv)
+    : BaseErrorResult(aRv)
+  {}
+
+  void operator=(nsresult rv)
+  {
+    BaseErrorResult::operator=(rv);
+  }
+
+  CopyableErrorResult& operator=(CopyableErrorResult&& aRHS)
+  {
+    BaseErrorResult::operator=(Move(aRHS));
+    return *this;
+  }
+
+  CopyableErrorResult(const CopyableErrorResult& aRight)
+    : BaseErrorResult()
+  {
+    operator=(aRight);
+  }
+
+  CopyableErrorResult&
+  operator=(const CopyableErrorResult& aRight)
+  {
+    // We must not copy JS exceptions since it can too easily lead to
+    // off-thread use.  Assert this and fall back to a generic error
+    // in release builds.
+    MOZ_DIAGNOSTIC_ASSERT(!IsJSException(),
+                          "Attempt to copy to ErrorResult with a JS exception value.");
+    MOZ_DIAGNOSTIC_ASSERT(!aRight.IsJSException(),
+                          "Attempt to copy from ErrorResult with a JS exception value.");
+    if (aRight.IsJSException()) {
+      SuppressException();
+      Throw(NS_ERROR_FAILURE);
+    } else {
+      aRight.CloneTo(*this);
+    }
+    return *this;
+  }
+};
+
 namespace dom {
 namespace binding_detail {
 class FastErrorResult :
     public mozilla::binding_danger::TErrorResult<
       mozilla::binding_danger::JustAssertCleanupPolicy>
 {
 };
 } // namespace binding_detail
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -3374,22 +3374,20 @@ bool CanvasRenderingContext2D::DrawCusto
   EnsureUserSpacePath();
 
   HTMLCanvasElement* canvas = GetCanvas();
 
   if (!canvas|| !nsContentUtils::ContentIsDescendantOf(&aElement, canvas)) {
     return false;
   }
 
-  nsIFocusManager* fm = nsFocusManager::GetFocusManager();
+  nsFocusManager* fm = nsFocusManager::GetFocusManager();
   if (fm) {
-    // check that the element i focused
-    nsCOMPtr<nsIDOMElement> focusedElement;
-    fm->GetFocusedElement(getter_AddRefs(focusedElement));
-    if (SameCOMIdentity(aElement.AsDOMNode(), focusedElement)) {
+    // check that the element is focused
+    if (&aElement == fm->GetFocusedElement()) {
       if (nsPIDOMWindowOuter* window = aElement.OwnerDoc()->GetWindow()) {
         return window->ShouldShowFocusRing();
       }
     }
   }
 
   return false;
 }
--- a/dom/chrome-webidl/ChannelWrapper.webidl
+++ b/dom/chrome-webidl/ChannelWrapper.webidl
@@ -289,16 +289,19 @@ interface ChannelWrapper : EventTarget {
    */
   [Cached, Constant]
   readonly attribute long long parentWindowId;
 
   /**
    * For cross-process requests, the <browser> or <iframe> element to which the
    * content loading this request belongs. For requests that don't originate
    * from a remote browser, this is null.
+   *
+   * This is not an Element because those are by default only exposed in
+   * Window, but we're exposed in System.
    */
   [Cached, Pure]
   readonly attribute nsISupports? browserElement;
 
   /**
    * Returns an array of objects that combine the url and frameId from the
    * ancestorPrincipals and ancestorOuterWindowIDs on loadInfo.
    * The immediate parent is the first entry, the last entry is always the top
--- a/dom/events/DataTransfer.h
+++ b/dom/events/DataTransfer.h
@@ -6,17 +6,16 @@
 
 #ifndef mozilla_dom_DataTransfer_h
 #define mozilla_dom_DataTransfer_h
 
 #include "nsString.h"
 #include "nsTArray.h"
 #include "nsIVariant.h"
 #include "nsIPrincipal.h"
-#include "nsIDOMElement.h"
 #include "nsIDragService.h"
 #include "nsCycleCollectionParticipant.h"
 
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/EventForwards.h"
 #include "mozilla/dom/BindingDeclarations.h"
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -3348,23 +3348,20 @@ EventStateManager::PostHandleEvent(nsPre
         }
 
         // The rest is left button-specific.
         if (mouseEvent->button != WidgetMouseEvent::eLeftButton) {
           break;
         }
 
         if (activeContent) {
-          // The nearest enclosing element goes into the
-          // :active state.  If we fail the QI to DOMElement,
-          // then we know we're only a node, and that we need
-          // to obtain our parent element and put it into :active
-          // instead.
-          nsCOMPtr<nsIDOMElement> elt(do_QueryInterface(activeContent));
-          if (!elt) {
+          // The nearest enclosing element goes into the :active state.  If
+          // we're not an element (so we're text or something) we need to obtain
+          // our parent element and put it into :active instead.
+          if (!activeContent->IsElement()) {
             nsIContent* par = activeContent->GetParent();
             if (par)
               activeContent = par;
           }
         }
       }
       else {
         // if we're here, the event handler returned false, so stop
@@ -5584,17 +5581,17 @@ EventStateManager::DoContentCommandEvent
     bool canDoIt;
     rv = controller->IsCommandEnabled(cmd, &canDoIt);
     NS_ENSURE_SUCCESS(rv, rv);
     aEvent->mIsEnabled = canDoIt;
     if (canDoIt && !aEvent->mOnlyEnabledCheck) {
       switch (aEvent->mMessage) {
         case eContentCommandPasteTransferable: {
           nsFocusManager* fm = nsFocusManager::GetFocusManager();
-          nsIContent* focusedContent = fm ? fm->GetFocusedContent() : nullptr;
+          nsIContent* focusedContent = fm ? fm->GetFocusedElement() : nullptr;
           RefPtr<TabParent> remote = TabParent::GetFrom(focusedContent);
           if (remote) {
             NS_ENSURE_TRUE(remote->Manager()->IsContentParent(), NS_ERROR_FAILURE);
 
             nsCOMPtr<nsITransferable> transferable = aEvent->mTransferable;
             IPCDataTransfer ipcDataTransfer;
             ContentParent* cp = remote->Manager()->AsContentParent();
             nsContentUtils::TransferableToIPCTransferable(transferable,
--- a/dom/geolocation/nsGeolocation.cpp
+++ b/dom/geolocation/nsGeolocation.cpp
@@ -391,17 +391,17 @@ nsGeolocationRequest::GetWindow(mozIDOMW
 
   nsCOMPtr<nsPIDOMWindowInner> window = do_QueryReferent(mLocator->GetOwner());
   window.forget(aRequestingWindow);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsGeolocationRequest::GetElement(nsIDOMElement * *aRequestingElement)
+nsGeolocationRequest::GetElement(Element** aRequestingElement)
 {
   NS_ENSURE_ARG_POINTER(aRequestingElement);
   *aRequestingElement = nullptr;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsGeolocationRequest::GetIsHandlingUserInput(bool* aIsHandlingUserInput)
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -3278,33 +3278,31 @@ HTMLInputElement::Select()
       // down event recorded to adjust the caret during the mouse up event.
       // We are probably called from the focus event handler.  We should override
       // the delayed caret data in this case to ensure that this select() call
       // takes effect.
       fs->SetDelayedCaretData(nullptr);
     }
   }
 
-  nsIFocusManager* fm = nsFocusManager::GetFocusManager();
+  nsFocusManager* fm = nsFocusManager::GetFocusManager();
 
   RefPtr<nsPresContext> presContext = GetPresContext(eForComposedDoc);
   if (state == eInactiveWindow) {
     if (fm)
       fm->SetFocus(this, nsIFocusManager::FLAG_NOSCROLL);
     SelectAll(presContext);
     return;
   }
 
   if (DispatchSelectEvent(presContext) && fm) {
     fm->SetFocus(this, nsIFocusManager::FLAG_NOSCROLL);
 
     // ensure that the element is actually focused
-    nsCOMPtr<nsIDOMElement> focusedElement;
-    fm->GetFocusedElement(getter_AddRefs(focusedElement));
-    if (SameCOMIdentity(static_cast<nsIDOMNode*>(this), focusedElement)) {
+    if (this == fm->GetFocusedElement()) {
       // Now Select all the text!
       SelectAll(presContext);
     }
   }
 }
 
 bool
 HTMLInputElement::DispatchSelectEvent(nsPresContext* aPresContext)
--- a/dom/html/HTMLObjectElement.cpp
+++ b/dom/html/HTMLObjectElement.cpp
@@ -187,22 +187,18 @@ HTMLObjectElement::HandlePluginCrashed(E
 
 void
 HTMLObjectElement::HandlePluginInstantiated(Element* aElement)
 {
   // If aElement is already focused when a plugin is instantiated, we need
   // to initiate a call to nsIWidget::SetPluginFocused(true).  Otherwise
   // keyboard input won't work in a click-to-play plugin until aElement
   // loses focus and regains it.
-  nsIContent* focusedContent = nullptr;
   nsFocusManager *fm = nsFocusManager::GetFocusManager();
-  if (fm) {
-    focusedContent = fm->GetFocusedContent();
-  }
-  if (SameCOMIdentity(focusedContent, aElement)) {
+  if (fm && fm->GetFocusedElement() == aElement) {
     OnFocusBlurPlugin(aElement, true);
   }
 }
 
 void
 HTMLObjectElement::HandleFocusBlurPlugin(Element* aElement,
                                          WidgetEvent* aEvent)
 {
--- a/dom/html/HTMLTextAreaElement.cpp
+++ b/dom/html/HTMLTextAreaElement.cpp
@@ -128,17 +128,17 @@ HTMLTextAreaElement::Select()
   // XXX Bug?  We have to give the input focus before contents can be
   // selected
 
   FocusTristate state = FocusState();
   if (state == eUnfocusable) {
     return;
   }
 
-  nsIFocusManager* fm = nsFocusManager::GetFocusManager();
+  nsFocusManager* fm = nsFocusManager::GetFocusManager();
 
   RefPtr<nsPresContext> presContext = GetPresContext(eForComposedDoc);
   if (state == eInactiveWindow) {
     if (fm)
       fm->SetFocus(this, nsIFocusManager::FLAG_NOSCROLL);
     SelectAll(presContext);
     return;
   }
@@ -151,19 +151,17 @@ HTMLTextAreaElement::Select()
 
   // If the DOM event was not canceled (e.g. by a JS event handler
   // returning false)
   if (status == nsEventStatus_eIgnore) {
     if (fm) {
       fm->SetFocus(this, nsIFocusManager::FLAG_NOSCROLL);
 
       // ensure that the element is actually focused
-      nsCOMPtr<nsIDOMElement> focusedElement;
-      fm->GetFocusedElement(getter_AddRefs(focusedElement));
-      if (SameCOMIdentity(static_cast<nsIDOMNode*>(this), focusedElement)) {
+      if (this == fm->GetFocusedElement()) {
         // Now Select all the text!
         SelectAll(presContext);
       }
     }
   }
 }
 
 NS_IMETHODIMP
--- a/dom/html/ImageDocument.cpp
+++ b/dom/html/ImageDocument.cpp
@@ -26,17 +26,16 @@
 #include "imgIContainer.h"
 #include "imgINotificationObserver.h"
 #include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "nsIChannel.h"
 #include "nsIContentPolicy.h"
 #include "nsContentPolicyUtils.h"
 #include "nsPIDOMWindow.h"
-#include "nsIDOMElement.h"
 #include "nsError.h"
 #include "nsURILoader.h"
 #include "nsIDocShell.h"
 #include "nsIContentViewer.h"
 #include "nsThreadUtils.h"
 #include "nsIScrollableFrame.h"
 #include "nsContentUtils.h"
 #include "mozilla/Preferences.h"
--- a/dom/html/nsBrowserElement.cpp
+++ b/dom/html/nsBrowserElement.cpp
@@ -10,17 +10,16 @@
 #include "mozilla/Services.h"
 #include "mozilla/dom/BrowserElementBinding.h"
 #include "mozilla/dom/DOMRequest.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/dom/ToJSValue.h"
 
 #include "nsComponentManagerUtils.h"
 #include "nsFrameLoader.h"
-#include "nsIDOMElement.h"
 #include "nsIMozBrowserFrame.h"
 #include "nsINode.h"
 #include "nsIPrincipal.h"
 
 using namespace mozilla::dom;
 
 namespace mozilla {
 
--- a/dom/html/nsGenericHTMLElement.cpp
+++ b/dom/html/nsGenericHTMLElement.cpp
@@ -103,17 +103,16 @@
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 NS_IMPL_ADDREF_INHERITED(nsGenericHTMLElement, nsGenericHTMLElementBase)
 NS_IMPL_RELEASE_INHERITED(nsGenericHTMLElement, nsGenericHTMLElementBase)
 
 NS_INTERFACE_MAP_BEGIN(nsGenericHTMLElement)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMElement)
   NS_INTERFACE_MAP_ENTRY(nsIDOMNode)
 NS_INTERFACE_MAP_END_INHERITING(nsGenericHTMLElementBase)
 
 nsresult
 nsGenericHTMLElement::CopyInnerTo(Element* aDst, bool aPreallocateChildren)
 {
   MOZ_ASSERT(!aDst->GetUncomposedDoc(),
              "Should not CopyInnerTo an Element in a document");
@@ -2565,17 +2564,17 @@ nsGenericHTMLElement::PerformAccesskey(b
   // It's hard to say what HTML4 wants us to do in all cases.
   bool focused = true;
   nsFocusManager* fm = nsFocusManager::GetFocusManager();
   if (fm) {
     fm->SetFocus(this, nsIFocusManager::FLAG_BYKEY);
 
     // Return true if the element became the current focus within its window.
     nsPIDOMWindowOuter* window = OwnerDoc()->GetWindow();
-    focused = (window && window->GetFocusedNode());
+    focused = (window && window->GetFocusedElement());
   }
 
   if (aKeyCausesActivation) {
     // Click on it if the users prefs indicate to do so.
     nsAutoPopupStatePusher popupStatePusher(aIsTrustedEvent ?
                                             openAllowed : openAbused);
     DispatchSimulatedClick(this, aIsTrustedEvent, presContext);
   }
--- a/dom/html/nsGenericHTMLElement.h
+++ b/dom/html/nsGenericHTMLElement.h
@@ -4,17 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #ifndef nsGenericHTMLElement_h___
 #define nsGenericHTMLElement_h___
 
 #include "mozilla/Attributes.h"
 #include "mozilla/EventForwards.h"
 #include "nsMappedAttributeElement.h"
-#include "nsIDOMElement.h"
+#include "nsIDOMNode.h"
 #include "nsNameSpaceManager.h"  // for kNameSpaceID_None
 #include "nsIFormControl.h"
 #include "nsGkAtoms.h"
 #include "nsContentCreatorFunctions.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/dom/BindingDeclarations.h"
 #include "mozilla/dom/DOMRect.h"
 #include "mozilla/dom/ValidityState.h"
@@ -42,17 +42,17 @@ class HTMLMenuElement;
 } // namespace mozilla
 
 typedef nsMappedAttributeElement nsGenericHTMLElementBase;
 
 /**
  * A common superclass for HTML elements
  */
 class nsGenericHTMLElement : public nsGenericHTMLElementBase,
-                             public nsIDOMElement
+                             public nsIDOMNode
 {
 public:
   using Element::SetTabIndex;
   using Element::Focus;
   explicit nsGenericHTMLElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
     : nsGenericHTMLElementBase(aNodeInfo)
   {
     NS_ASSERTION(mNodeInfo->NamespaceID() == kNameSpaceID_XHTML,
--- a/dom/html/nsHTMLDocument.cpp
+++ b/dom/html/nsHTMLDocument.cpp
@@ -18,17 +18,16 @@
 #include "nsIHTMLContentSink.h"
 #include "nsIXMLContentSink.h"
 #include "nsHTMLParts.h"
 #include "nsHTMLStyleSheet.h"
 #include "nsGkAtoms.h"
 #include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "nsIDOMNode.h" // for Find
-#include "nsIDOMElement.h"
 #include "nsPIDOMWindow.h"
 #include "nsDOMString.h"
 #include "nsIStreamListener.h"
 #include "nsIURI.h"
 #include "nsIURIMutator.h"
 #include "nsIIOService.h"
 #include "nsNetUtil.h"
 #include "nsIPrivateBrowsingChannel.h"
--- a/dom/html/nsIMenuBuilder.idl
+++ b/dom/html/nsIMenuBuilder.idl
@@ -1,16 +1,16 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
-interface nsIDOMElement;
+webidl Element;
 
 /**
  * An interface used to construct native toolbar or context menus from <menu>
  */
 
 [scriptable, uuid(93F4A48F-D043-4F45-97FD-9771EA1AF976)]
 interface nsIMenuBuilder : nsISupports
 {
@@ -23,17 +23,17 @@ interface nsIMenuBuilder : nsISupports
   void openContainer(in DOMString aLabel);
 
   /**
    * Add a new menu item. All menu item details can be obtained from
    * the element. This method is not called for hidden elements or elements
    * with no or empty label. The icon should be loaded only if aCanLoadIcon
    * is true.
    */
-  void addItemFor(in nsIDOMElement aElement,
+  void addItemFor(in Element aElement,
                   in boolean aCanLoadIcon);
 
   /**
    * Create a new separator.
    */
   void addSeparator();
 
   /**
--- a/dom/html/test/test_bug389797.html
+++ b/dom/html/test/test_bug389797.html
@@ -30,18 +30,17 @@ function getClassName(tag) {
 function HTML_TAG(aTagName, aImplClass) {
   allTags.push(aTagName);
   classInfos[aTagName] = aImplClass;
   interfaces[aTagName] = [];
 
   // Some interfaces don't appear in classinfo because other interfaces that
   // inherit from them do.
   interfacesNonClassinfo[aTagName] =
-    [ "nsIDOMNode",
-      "nsIDOMElement" ];
+    [ "nsIDOMNode" ];
 
   var interfaceName = "nsIDOM" + getClassName(aTagName);
   if (interfaceName in SpecialPowers.Ci) {  // no nsIDOMHTMLSpanElement
     interfaces[aTagName].push(interfaceName);
   }
 
   var interfaceNameNS = "nsIDOMNS" + getClassName(aTagName);
   if (interfaceNameNS in SpecialPowers.Ci) {
--- a/dom/interfaces/base/domstubs.idl
+++ b/dom/interfaces/base/domstubs.idl
@@ -12,17 +12,16 @@ class nsWrapperCache;
 [ptr] native nsWrapperCachePtr(nsWrapperCache);
 
 typedef unsigned long long DOMTimeStamp;
 typedef double DOMHighResTimeStamp;
 typedef unsigned long long nsViewID;
 
 // Core
 interface nsIDOMDocument;
-interface nsIDOMElement;
 interface nsIDOMNode;
 
 // Needed for raises() in our IDL
 %{C++
 namespace mozilla {
 namespace dom {
 class DOMException;
 }
--- a/dom/interfaces/base/nsIContentPermissionPrompt.idl
+++ b/dom/interfaces/base/nsIContentPermissionPrompt.idl
@@ -1,19 +1,20 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
 interface nsIPrincipal;
 interface mozIDOMWindow;
-interface nsIDOMElement;
 interface nsIArray;
 
+webidl Element;
+
 /**
  *  Interface provides the request type and its access.
  */
 [scriptable, uuid(ef4db3b8-ca9c-4b1d-8f81-fd88ec32af13)]
 interface nsIContentPermissionType : nsISupports {
   /**
    *  The type of the permission request, such as
    *  "geolocation".
@@ -80,17 +81,17 @@ interface nsIContentPermissionRequest : 
 
   /**
    *  The window or element that the permission request was
    *  originated in.  Typically the element will be non-null
    *  in when using out of process content.  window or
    *  element can be null but not both.
    */
   readonly attribute mozIDOMWindow window;
-  readonly attribute nsIDOMElement element;
+  readonly attribute Element element;
 
   readonly attribute boolean isHandlingUserInput;
 
   /**
    *  The requester to get the required information of
    *  the window.
    */
   readonly attribute nsIContentPermissionRequester requester;
--- a/dom/interfaces/base/nsIContentProcess.idl
+++ b/dom/interfaces/base/nsIContentProcess.idl
@@ -1,15 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
-interface nsIDOMElement;
 interface nsIURI;
 
 [scriptable, builtinclass, uuid(456f58be-29dd-4973-885b-95aece1c9a8a)]
 interface nsIContentProcessInfo : nsISupports
 {
   /**
    * Is this content process alive?
    */
--- a/dom/interfaces/base/nsIDOMChromeWindow.idl
+++ b/dom/interfaces/base/nsIDOMChromeWindow.idl
@@ -1,17 +1,16 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "domstubs.idl"
 
 interface nsIBrowserDOMWindow;
-interface nsIDOMElement;
 interface mozIDOMWindowProxy;
 
 // Scriptable only so Components.interfaces.nsIDOMChromeWindow works.
 [scriptable, builtinclass, uuid(78bdcb41-1efa-409f-aaba-70842213f80f)]
 interface nsIDOMChromeWindow : nsISupports
 {
   /**
    * browserDOMWindow provides access to yet another layer of
--- a/dom/interfaces/base/nsIDOMWindowUtils.idl
+++ b/dom/interfaces/base/nsIDOMWindowUtils.idl
@@ -27,34 +27,34 @@ struct nsRect;
 
 [ref] native nsConstRect(const nsRect);
 native nscolor(nscolor);
 [ptr] native gfxContext(gfxContext);
 
 interface nsIArray;
 interface nsICycleCollectorListener;
 interface nsIDOMNode;
-interface nsIDOMElement;
 interface nsIPreloadedStyleSheet;
 interface nsITransferable;
 interface nsIQueryContentEventResult;
 interface nsIDOMWindow;
 interface nsIFile;
 interface nsIURI;
 interface nsIRunnable;
 interface nsITranslationNodeList;
 interface nsIJSRAIIHelper;
 interface nsIContentPermissionRequest;
 interface nsIObserver;
 interface nsIDOMStorage;
 
 webidl DOMRect;
-webidl NodeList;
+webidl Element;
 webidl EventTarget;
 webidl Event;
+webidl NodeList;
 
 [scriptable, uuid(4d6732ca-9da7-4176-b8a1-8dde15cd0bf9)]
 interface nsIDOMWindowUtils : nsISupports {
 
   /**
    * Image animation mode of the window. When this attribute's value
    * is changed, the implementation should set all images in the window
    * to the given value. That is, when set to kDontAnimMode, all images
@@ -158,17 +158,17 @@ interface nsIDOMWindowUtils : nsISupport
    * displayport.
    *
    * aPriority is recorded along with the displayport rectangle. If this
    * method is called with a lower priority than the current priority, the
    * call is ignored.
    */
   void setDisplayPortForElement(in float aXPx, in float aYPx,
                                 in float aWidthPx, in float aHeightPx,
-                                in nsIDOMElement aElement,
+                                in Element aElement,
                                 in uint32_t aPriority);
   /**
    * An alternate way to represent a displayport rect as a set of margins and a
    * base rect to apply those margins to. A consumer of pixels may ask for as
    * many extra pixels as it would like in each direction. Layout then sets
    * the base rect to the "visible rect" of the element, which is just the
    * subrect of the element that is drawn (it does not take in account content
    * covering the element).
@@ -183,24 +183,24 @@ interface nsIDOMWindowUtils : nsISupport
    * Note that both the margin values and alignment are treated as values in
    * ScreenPixels. Refer to layout/base/Units.h for a description of this unit.
    * The base rect values are in app units.
    */
   void setDisplayPortMarginsForElement(in float aLeftMargin,
                                        in float aTopMargin,
                                        in float aRightMargin,
                                        in float aBottomMargin,
-                                       in nsIDOMElement aElement,
+                                       in Element aElement,
                                        in uint32_t aPriority);
 
   void setDisplayPortBaseForElement(in int32_t aX,
                                     in int32_t aY,
                                     in int32_t aWidth,
                                     in int32_t aHeight,
-                                    in nsIDOMElement aElement);
+                                    in Element aElement);
 
   /**
    * Get/set the resolution at which rescalable web content is drawn.
    *
    * Setting a new resolution does *not* trigger reflow.  This API is
    * entirely separate from textZoom and fullZoom; a resolution scale
    * can be applied together with both textZoom and fullZoom.
    *
@@ -492,24 +492,24 @@ interface nsIDOMWindowUtils : nsISupport
    * NOTE: The synthesized native event will be fired asynchronously, and upon
    * completion the observer, if provided, will be notified with a "mouseevent"
    * topic.
    */
   void sendNativeMouseEvent(in long aScreenX,
                             in long aScreenY,
                             in long aNativeMessage,
                             in long aModifierFlags,
-                            in nsIDOMElement aElement,
+                            in Element aElement,
                             [optional] in nsIObserver aObserver);
   /**
    * See nsIWidget::SynthesizeNativeMouseMove and sendNativeMouseEvent
    */
   void sendNativeMouseMove(in long aScreenX,
                            in long aScreenY,
-                           in nsIDOMElement aElement,
+                           in Element aElement,
                            [optional] in nsIObserver aObserver);
 
   /**
    * Suppress animations that are applied to a window by OS when
    * resizing, moving, changing size mode, ...
    */
   void suppressAnimation(in boolean aSuppress);
 
@@ -558,17 +558,17 @@ interface nsIDOMWindowUtils : nsISupport
   void sendNativeMouseScrollEvent(in long aScreenX,
                                   in long aScreenY,
                                   in unsigned long aNativeMessage,
                                   in double aDeltaX,
                                   in double aDeltaY,
                                   in double aDeltaZ,
                                   in unsigned long aModifierFlags,
                                   in unsigned long aAdditionalFlags,
-                                  in nsIDOMElement aElement,
+                                  in Element aElement,
                                   [optional] in nsIObserver aObserver);
 
   /**
    * Touch states for sendNativeTouchPoint. These values match
    * nsIWidget's TouchPointerState.
    */
 
   // The pointer is in a hover state above the digitizer
@@ -739,20 +739,20 @@ interface nsIDOMWindowUtils : nsISupport
   /**
    * Retrieve the element at point aX, aY in the window's document.
    *
    * @param aIgnoreRootScrollFrame whether or not to ignore the root scroll
    *        frame when retrieving the element. If false, this method returns
    *        null for coordinates outside of the viewport.
    * @param aFlushLayout flushes layout if true. Otherwise, no flush occurs.
    */
-  nsIDOMElement elementFromPoint(in float aX,
-                                 in float aY,
-                                 in boolean aIgnoreRootScrollFrame,
-                                 in boolean aFlushLayout);
+  Element elementFromPoint(in float aX,
+                           in float aY,
+                           in boolean aIgnoreRootScrollFrame,
+                           in boolean aFlushLayout);
 
   /**
    * Retrieve all nodes that intersect a rect in the window's document.
    *
    * @param aX x reference for the rectangle in CSS pixels
    * @param aY y reference for the rectangle in CSS pixels
    * @param aTopSize How much to expand up the rectangle
    * @param aRightSize How much to expand right the rectangle
@@ -840,17 +840,17 @@ interface nsIDOMWindowUtils : nsISupport
    *
    * @param aFlushLayout flushes layout if true. Otherwise, no flush occurs.
    */
   void getScrollbarSize(in boolean aFlushLayout, out long aWidth, out long aHeight);
 
   /**
    * Returns the given element's bounds without flushing pending layout changes.
    */
-  DOMRect getBoundsWithoutFlushing(in nsIDOMElement aElement);
+  DOMRect getBoundsWithoutFlushing(in Element aElement);
 
   const long FLUSH_NONE = -1;
   const long FLUSH_STYLE = 0;
   const long FLUSH_LAYOUT = 1;
   const long FLUSH_DISPLAY = 2;
 
   /**
    * Returns true if a flush of the given type is needed.
@@ -1120,17 +1120,17 @@ interface nsIDOMWindowUtils : nsISupport
   const unsigned long QUERY_TEXT_RECT_ARRAY                     = 3209;
 
   /**
    * Called when the remote child frame has changed its fullscreen state,
    * when entering fullscreen, and when the origin which is fullscreen changes.
    * aFrameElement is the iframe element which contains the child-process
    * fullscreen document.
    */
-  void remoteFrameFullscreenChanged(in nsIDOMElement aFrameElement);
+  void remoteFrameFullscreenChanged(in Element aFrameElement);
 
   /**
    * Called when the remote frame has popped all fullscreen elements off its
    * stack, so that the operation can complete on the parent side.
    */
   void remoteFrameFullscreenReverted();
 
   /**
@@ -1215,17 +1215,17 @@ interface nsIDOMWindowUtils : nsISupport
    * would have if allowed all properties to change as a result of
    * :visited selectors (except for cases where getComputedStyle uses
    * data from the frame).
    *
    * This is easier to implement than adding our property restrictions
    * to this API, and is sufficient for the present testing
    * requirements (which are essentially testing 'color').
    */
-  AString getVisitedDependentComputedStyle(in nsIDOMElement aElement,
+  AString getVisitedDependentComputedStyle(in Element aElement,
                                            in AString aPseudoElement,
                                            in AString aPropertyName);
 
   /**
    * Get the id of the outer window of this window.  This will never throw.
    */
   readonly attribute unsigned long long outerWindowID;
 
@@ -1341,17 +1341,17 @@ interface nsIDOMWindowUtils : nsISupport
    * The DPI of the display
    */
   readonly attribute float displayDPI;
 
   /**
    * Return this window's frame element.
    * Ignores all chrome/content or mozbrowser boundaries.
    */
-  readonly attribute nsIDOMElement containerElement;
+  readonly attribute Element containerElement;
 
   [noscript] void RenderDocument(in nsConstRect aRect,
                                  in uint32_t aFlags,
                                  in nscolor aBackgroundColor,
                                  in gfxContext aThebesContext);
 
   /**
    * advanceTimeAndRefresh allows the caller to take over the refresh
@@ -1424,81 +1424,81 @@ interface nsIDOMWindowUtils : nsISupport
 
   /**
    * Method for testing StyleAnimationValue::ComputeDistance.
    *
    * Returns the distance between the two values as reported by
    * StyleAnimationValue::ComputeDistance for the given element and
    * property.
    */
-  double computeAnimationDistance(in nsIDOMElement element,
+  double computeAnimationDistance(in Element element,
                                   in AString property,
                                   in AString value1,
                                   in AString value2);
 
   /**
    * Returns the computed style for the specified property of given pseudo type
    * on the given element after removing styles from declarative animations.
    * @param aElement - A target element
    * @param aPseudoElement - A pseudo type (e.g. '::before' or null)
    * @param aProperty - A longhand CSS property (e.g. 'background-color')
    * @param aFlushType - FLUSH_NONE if any pending styles should not happen,
    *                     FLUSH_STYLE to flush pending styles.
    */
-  AString getUnanimatedComputedStyle(in nsIDOMElement aElement,
+  AString getUnanimatedComputedStyle(in Element aElement,
                                      in AString aPseudoElement,
                                      in AString aProperty,
                                      in long aFlushType);
 
   /**
    * Get the type of the currently focused html input, if any.
    */
   readonly attribute AString focusedInputType;
 
   /**
    * Find the view ID for a given element. This is the reverse of
    * findElementWithViewId().
    */
-  nsViewID getViewId(in nsIDOMElement aElement);
+  nsViewID getViewId(in Element aElement);
 
   /**
    * Checks the layer tree for this window and returns true
    * if all layers have transforms that are translations by integers,
    * no leaf layers overlap, and the union of the leaf layers is exactly
    * the bounds of the window. Always returns true in non-DEBUG builds.
    */
   boolean leafLayersPartitionWindow();
 
   /**
    * Check if any PaintedLayer painting has been done for this element,
    * clears the painted flags if they have.
    */
-  boolean checkAndClearPaintedState(in nsIDOMElement aElement);
+  boolean checkAndClearPaintedState(in Element aElement);
 
   /**
    * Check if any display list building has been done for this element,
    * clears the display list flags if they have.
    */
-  boolean checkAndClearDisplayListState(in nsIDOMElement aElement);
+  boolean checkAndClearDisplayListState(in Element aElement);
 
   /**
    * Check whether all display items of the primary frame of aElement have been
    * assigned to the same single PaintedLayer in the last paint. If that is the
    * case, returns whether that PaintedLayer is opaque; if it's not the case, an
    * exception is thrown.
    */
-  boolean isPartOfOpaqueLayer(in nsIDOMElement aElement);
+  boolean isPartOfOpaqueLayer(in Element aElement);
 
   /**
    * Count the number of different PaintedLayers that the supplied elements have
    * been assigned to in the last paint. Throws an exception if any of the
    * elements doesn't have a primary frame, or if that frame's display items are
    * assigned to any other layers than just a single PaintedLayer per element.
    */
-  unsigned long numberOfAssignedPaintedLayers([array, size_is(count)] in nsIDOMElement aElements,
+  unsigned long numberOfAssignedPaintedLayers([array, size_is(count)] in Element aElements,
                                               in uint32_t count);
 
   /**
    * Get internal id of the stored blob, file or file handle.
    */
   [implicit_jscontext] long long getFileId(in jsval aFile);
 
   /**
@@ -1684,17 +1684,17 @@ interface nsIDOMWindowUtils : nsISupport
    */
   attribute boolean paintFlashing;
 
   /*
    * Returns the value of a given property animated on the compositor thread.
    * If the property is NOT currently being animated on the compositor thread,
    * returns an empty string.
    */
-  AString getOMTAStyle(in nsIDOMElement aElement, in AString aProperty,
+  AString getOMTAStyle(in Element aElement, in AString aProperty,
                        [optional] in AString aPseudoElement);
 
   /**
    * Special function that gets a property syncronously from the last composite
    * that occured.
    *
    * Supported properties:
    *   "overdraw": Report a percentage between 0 and 999 indicate how many times
@@ -1716,17 +1716,17 @@ interface nsIDOMWindowUtils : nsISupport
    * The return values are of type APZTestData (see APZTestData.webidl).
    */
   [implicit_jscontext] jsval getContentAPZTestData();
   [implicit_jscontext] jsval getCompositorAPZTestData();
 
   /**
    * Posts an eRestyle_Self restyle event for the given element.
    */
-  void postRestyleSelfEvent(in nsIDOMElement aElement);
+  void postRestyleSelfEvent(in Element aElement);
 
   /**
    * Used to pause or resume all media in this window. Use-cases are audio
    * competing, remote media control and to prevent auto-playing media.
    */
   attribute uint32_t mediaSuspend;
 
   /**
@@ -1871,25 +1871,25 @@ interface nsIDOMWindowUtils : nsISupport
    * Adds an EventStates bit to the element.
    *
    * The state string must be one of the following:
    *   * (none yet; but for example "higlighted" for NS_EVENT_STATE_HIGHLIGHTED)
    *
    * The supported state strings are defined in kManuallyManagedStates
    * in nsDOMWindowUtils.cpp.
    */
-  void addManuallyManagedState(in nsIDOMElement element,
+  void addManuallyManagedState(in Element element,
                                in AString state);
 
   /**
    * Removes the specified EventStates bits from the element.
    *
    * See above for the strings that can be passed for |state|.
    */
-  void removeManuallyManagedState(in nsIDOMElement element,
+  void removeManuallyManagedState(in Element element,
                                   in AString state);
 
   /**
    * Returns usage data for a given storage object.
    *
    * @param aStorage
    *    The storage object to get usage data for.
    */
--- a/dom/interfaces/base/nsIFocusManager.idl
+++ b/dom/interfaces/base/nsIFocusManager.idl
@@ -62,17 +62,17 @@ interface nsIFocusManager : nsISupports
    */
   attribute mozIDOMWindowProxy focusedWindow;
 
   /**
    * The element that is currently focused. This will always be an element
    * within the document loaded in focusedWindow or null if no element in that
    * document is focused.
    */
-  readonly attribute nsIDOMElement focusedElement;
+  readonly attribute Element focusedElement;
 
   /**
    * Returns the method that was used to focus the element in window. This
    * will either be 0, FLAG_BYMOUSE or FLAG_BYKEY. If window is null, then
    * the current focusedWindow will be used by default. This has the result
    * of retrieving the method that was used to focus the currently focused
    * element.
    */
@@ -126,19 +126,19 @@ interface nsIFocusManager : nsISupports
    * focus is in a child frame.
    *
    * aFocusedWindow will be set to the currently focused descendant window of
    * aWindow, or to aWindow if aDeep is false. This will be set even if no
    * element is focused.
    *
    * @throws NS_ERROR_INVALID_ARG if aWindow is null
    */
-  nsIDOMElement getFocusedElementForWindow(in mozIDOMWindowProxy aWindow,
-                                           in boolean aDeep,
-                                           out mozIDOMWindowProxy aFocusedWindow);
+  Element getFocusedElementForWindow(in mozIDOMWindowProxy aWindow,
+                                     in boolean aDeep,
+                                     out mozIDOMWindowProxy aFocusedWindow);
 
   /**
    * Moves the selection caret within aWindow to the current focus.
    */
   void moveCaretToFocus(in mozIDOMWindowProxy aWindow);
 
   /***
    * Check if given element is focusable.
--- a/dom/interfaces/core/moz.build
+++ b/dom/interfaces/core/moz.build
@@ -4,15 +4,14 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 with Files("**"):
     BUG_COMPONENT = ("Core", "DOM")
 
 XPIDL_SOURCES += [
     'nsIDOMDocument.idl',
-    'nsIDOMElement.idl',
     'nsIDOMNode.idl',
     'nsIDOMNSEditableElement.idl',
 ]
 
 XPIDL_MODULE = 'dom_core'
 
deleted file mode 100644
--- a/dom/interfaces/core/nsIDOMElement.idl
+++ /dev/null
@@ -1,30 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsIDOMNode.idl"
-
-interface nsIDOMMozNamedAttrMap;
-
-%{C++
-// Undo the windows.h damage
-#undef GetMessage
-#undef CreateEvent
-#undef GetClassName
-#undef GetBinaryType
-#undef RemoveDirectory
-%}
-
-/**
- * The nsIDOMElement interface represents an element in an HTML or 
- * XML document. 
- *
- * For more information on this interface please see 
- * http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#interface-element
- */
-
-[shim(Element), uuid(6289999b-1008-4269-b42a-413ec5a9d3f4)]
-interface nsIDOMElement : nsIDOMNode
-{
-};
--- a/dom/interfaces/xul/nsIDOMXULCheckboxElement.idl
+++ b/dom/interfaces/xul/nsIDOMXULCheckboxElement.idl
@@ -1,12 +1,11 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "nsIDOMElement.idl"
 #include "nsIDOMXULLabeledControlEl.idl"
 
 [scriptable, uuid(674965d9-aff4-411d-a382-7cb32c0f25a1)]
 interface nsIDOMXULCheckboxElement : nsIDOMXULLabeledControlElement {
   attribute boolean checked;
 };
--- a/dom/interfaces/xul/nsIDOMXULCommandDispatcher.idl
+++ b/dom/interfaces/xul/nsIDOMXULCommandDispatcher.idl
@@ -1,32 +1,31 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
-interface nsIDOMElement;
 interface nsIController;
 interface nsIControllers;
 interface mozIDOMWindowProxy;
 
 webidl Element;
 
 [scriptable, uuid(a9fa9fd3-8d62-4f94-9ed8-3ea9c3cf0773)]
 interface nsIDOMXULCommandDispatcher : nsISupports
 {
             attribute Element focusedElement;
             attribute mozIDOMWindowProxy focusedWindow;
 
-  void                      addCommandUpdater(in nsIDOMElement updater,
+  void                      addCommandUpdater(in Element updater,
                                               in DOMString events,
                                               in DOMString targets);
-  void                      removeCommandUpdater(in nsIDOMElement updater);
+  void                      removeCommandUpdater(in Element updater);
 
   void                      updateCommands(in DOMString eventName);
 
   nsIController             getControllerForCommand(in string command);
   nsIControllers            getControllers();
 
   void advanceFocus();
   void rewindFocus();
--- a/dom/interfaces/xul/nsIDOMXULLabeledControlEl.idl
+++ b/dom/interfaces/xul/nsIDOMXULLabeledControlEl.idl
@@ -1,14 +1,13 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "nsIDOMElement.idl"
 #include "nsIDOMXULControlElement.idl"
 
 [scriptable, uuid(c58a159f-e27d-40c8-865a-d4dcfd928f62)]
 interface nsIDOMXULLabeledControlElement : nsIDOMXULControlElement {
   attribute DOMString crop;
   attribute DOMString image;
   attribute DOMString label;
   attribute DOMString accessKey;
--- a/dom/ipc/ProcessHangMonitor.cpp
+++ b/dom/ipc/ProcessHangMonitor.cpp
@@ -165,31 +165,17 @@ class HangMonitoredProcess final
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
 
   HangMonitoredProcess(HangMonitorParent* aActor,
                        ContentParent* aContentParent)
     : mActor(aActor), mContentParent(aContentParent) {}
 
-  NS_IMETHOD GetHangType(uint32_t* aHangType) override;
-  NS_IMETHOD GetScriptBrowser(nsIDOMElement** aBrowser) override;
-  NS_IMETHOD GetScriptFileName(nsACString& aFileName) override;
-  NS_IMETHOD GetAddonId(nsAString& aAddonId) override;
-
-  NS_IMETHOD GetPluginName(nsACString& aPluginName) override;
-
-  NS_IMETHOD TerminateScript() override;
-  NS_IMETHOD TerminateGlobal() override;
-  NS_IMETHOD BeginStartingDebugger() override;
-  NS_IMETHOD EndStartingDebugger() override;
-  NS_IMETHOD TerminatePlugin() override;
-  NS_IMETHOD UserCanceled() override;
-
-  NS_IMETHOD IsReportForBrowser(nsFrameLoader* aFrameLoader, bool* aResult) override;
+  NS_DECL_NSIHANGREPORT
 
   // Called when a content process shuts down.
   void Clear() {
     mContentParent = nullptr;
     mActor = nullptr;
   }
 
   /**
@@ -943,34 +929,34 @@ HangMonitoredProcess::GetHangType(uint32
     MOZ_ASSERT_UNREACHABLE("Unexpected HangData type");
     return NS_ERROR_UNEXPECTED;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-HangMonitoredProcess::GetScriptBrowser(nsIDOMElement** aBrowser)
+HangMonitoredProcess::GetScriptBrowser(Element** aBrowser)
 {
   MOZ_RELEASE_ASSERT(NS_IsMainThread());
   if (mHangData.type() != HangData::TSlowScriptData) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   TabId tabId = mHangData.get_SlowScriptData().tabId();
   if (!mContentParent) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   nsTArray<PBrowserParent*> tabs;
   mContentParent->ManagedPBrowserParent(tabs);
   for (size_t i = 0; i < tabs.Length(); i++) {
     TabParent* tp = TabParent::GetFrom(tabs[i]);
     if (tp->GetTabId() == tabId) {
-      nsCOMPtr<nsIDOMElement> node = do_QueryInterface(tp->GetOwnerElement());
+      RefPtr<Element> node = tp->GetOwnerElement();
       node.forget(aBrowser);
       return NS_OK;
     }
   }
 
   *aBrowser = nullptr;
   return NS_OK;
 }
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -49,17 +49,16 @@
 #include "nsFocusManager.h"
 #include "nsFrameLoader.h"
 #include "nsFrameManager.h"
 #include "nsIBaseWindow.h"
 #include "nsIBrowser.h"
 #include "nsIContent.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeOwner.h"
-#include "nsIDOMElement.h"
 #include "nsIDOMWindow.h"
 #include "nsIDOMWindowUtils.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsILoadInfo.h"
 #include "nsIPromptFactory.h"
 #include "nsIURI.h"
 #include "nsIWindowWatcher.h"
 #include "nsIWebBrowserChrome.h"
@@ -2585,18 +2584,17 @@ TabParent::GetAuthPrompt(uint32_t aPromp
   // Get an auth prompter for our window so that the parenting
   // of the dialogs works as it should when using tabs.
   nsCOMPtr<nsISupports> prompt;
   rv = wwatch->GetPrompt(window, iid, getter_AddRefs(prompt));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsILoginManagerPrompter> prompter = do_QueryInterface(prompt);
   if (prompter) {
-    nsCOMPtr<nsIDOMElement> browser = do_QueryInterface(mFrameElement);
-    prompter->SetBrowser(browser);
+    prompter->SetBrowser(mFrameElement);
   }
 
   *aResult = prompt.forget().take();
   return NS_OK;
 }
 
 PColorPickerParent*
 TabParent::AllocPColorPickerParent(const nsString& aTitle,
@@ -3221,19 +3219,19 @@ public:
   NS_IMETHOD OnAuthAvailable(nsISupports *aContext, nsIAuthInformation *aAuthInfo) override;
   NS_IMETHOD OnAuthCancelled(nsISupports *aContext, bool userCancel) override;
   NS_IMETHOD GetInterface(const nsIID & uuid, void **result) override
   {
     return QueryInterface(uuid, result);
   }
   NS_IMETHOD GetAssociatedWindow(mozIDOMWindowProxy**) NO_IMPL
   NS_IMETHOD GetTopWindow(mozIDOMWindowProxy**) NO_IMPL
-  NS_IMETHOD GetTopFrameElement(nsIDOMElement** aElement) override
+  NS_IMETHOD GetTopFrameElement(Element** aElement) override
   {
-    nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(mElement);
+    nsCOMPtr<Element> elem = mElement;
     elem.forget(aElement);
     return NS_OK;
   }
   NS_IMETHOD GetNestedFrameId(uint64_t*) NO_IMPL
   NS_IMETHOD GetIsContent(bool*) NO_IMPL
   NS_IMETHOD GetUsePrivateBrowsing(bool*) NO_IMPL
   NS_IMETHOD SetUsePrivateBrowsing(bool) NO_IMPL
   NS_IMETHOD SetPrivateBrowsing(bool) NO_IMPL
--- a/dom/ipc/nsIHangReport.idl
+++ b/dom/ipc/nsIHangReport.idl
@@ -1,19 +1,18 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
-interface nsIDOMElement;
-
 webidl FrameLoader;
+webidl Element;
 
 /**
  * When a content process hangs, Gecko notifies "process-hang-report" observers
  * and passes an nsIHangReport for the subject parameter. There is at most one
  * nsIHangReport associated with a given content process. As long as the content
  * process stays stuck, the "process-hang-report" observer will continue to be
  * notified at regular intervals (approximately once per second). The content
  * process will continue to run uninhibitedly during this time.
@@ -26,17 +25,17 @@ interface nsIHangReport : nsISupports
   const unsigned long PLUGIN_HANG = 2;
 
   // The type of hang being reported: SLOW_SCRIPT or PLUGIN_HANG.
   readonly attribute unsigned long hangType;
 
   // For SLOW_SCRIPT reports, these fields contain information about the
   // slow script.
   // Only valid for SLOW_SCRIPT reports.
-  readonly attribute nsIDOMElement scriptBrowser;
+  readonly attribute Element scriptBrowser;
   readonly attribute ACString scriptFileName;
   readonly attribute AString addonId;
 
   // For PLUGIN_HANGs, this field contains information about the plugin.
   // Only valid for PLUGIN_HANG reports.
   readonly attribute ACString pluginName;
 
   // Called by front end code when user ignores or cancels
--- a/dom/mathml/nsMathMLElement.cpp
+++ b/dom/mathml/nsMathMLElement.cpp
@@ -31,17 +31,17 @@
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 //----------------------------------------------------------------------
 // nsISupports methods:
 
 NS_IMPL_ISUPPORTS_INHERITED(nsMathMLElement, nsMathMLElementBase,
-                            nsIDOMElement, nsIDOMNode, Link)
+                            nsIDOMNode, Link)
 
 static nsresult
 WarnDeprecated(const char16_t* aDeprecatedAttribute,
                const char16_t* aFavoredAttribute, nsIDocument* aDocument)
 {
   const char16_t *argv[] =
     { aDeprecatedAttribute, aFavoredAttribute };
   return nsContentUtils::
--- a/dom/mathml/nsMathMLElement.h
+++ b/dom/mathml/nsMathMLElement.h
@@ -5,34 +5,34 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsMathMLElement_h
 #define nsMathMLElement_h
 
 #include "mozilla/Attributes.h"
 #include "mozilla/dom/Element.h"
 #include "nsMappedAttributeElement.h"
-#include "nsIDOMElement.h"
+#include "nsIDOMNode.h"
 #include "Link.h"
 #include "mozilla/dom/DOMRect.h"
 
 class nsCSSValue;
 
 typedef nsMappedAttributeElement nsMathMLElementBase;
 
 namespace mozilla {
 class EventChainPostVisitor;
 class EventChainPreVisitor;
 } // namespace mozilla
 
 /*
  * The base class for MathML elements.
  */
 class nsMathMLElement final : public nsMathMLElementBase,
-                              public nsIDOMElement,
+                              public nsIDOMNode,
                               public mozilla::dom::Link
 {
 public:
   explicit nsMathMLElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
   explicit nsMathMLElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
   // Implementation of nsISupports is inherited from nsMathMLElementBase
   NS_DECL_ISUPPORTS_INHERITED
--- a/dom/midi/MIDIPermissionRequest.cpp
+++ b/dom/midi/MIDIPermissionRequest.cpp
@@ -86,17 +86,17 @@ NS_IMETHODIMP
 MIDIPermissionRequest::GetWindow(mozIDOMWindow** aRequestingWindow)
 {
   NS_ENSURE_ARG_POINTER(aRequestingWindow);
   NS_IF_ADDREF(*aRequestingWindow = mWindow);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-MIDIPermissionRequest::GetElement(nsIDOMElement** aRequestingElement)
+MIDIPermissionRequest::GetElement(Element** aRequestingElement)
 {
   NS_ENSURE_ARG_POINTER(aRequestingElement);
   *aRequestingElement = nullptr;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 MIDIPermissionRequest::Cancel()
--- a/dom/notification/Notification.cpp
+++ b/dom/notification/Notification.cpp
@@ -589,17 +589,17 @@ NotificationPermissionRequest::GetPrinci
 NS_IMETHODIMP
 NotificationPermissionRequest::GetWindow(mozIDOMWindow** aRequestingWindow)
 {
   NS_ADDREF(*aRequestingWindow = mWindow);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-NotificationPermissionRequest::GetElement(nsIDOMElement** aElement)
+NotificationPermissionRequest::GetElement(Element** aElement)
 {
   NS_ENSURE_ARG_POINTER(aElement);
   *aElement = nullptr;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 NotificationPermissionRequest::GetIsHandlingUserInput(bool* aIsHandlingUserInput)
--- a/dom/plugins/base/nsJSNPRuntime.cpp
+++ b/dom/plugins/base/nsJSNPRuntime.cpp
@@ -16,17 +16,16 @@
 #include "nsIGlobalObject.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIScriptContext.h"
 #include "nsDOMJSUtils.h"
 #include "nsJSUtils.h"
 #include "nsIDocument.h"
 #include "nsIXPConnect.h"
 #include "xpcpublic.h"
-#include "nsIDOMElement.h"
 #include "nsIContent.h"
 #include "nsPluginInstanceOwner.h"
 #include "nsWrapperCacheInlines.h"
 #include "js/GCHashTable.h"
 #include "js/TracingAPI.h"
 #include "js/Wrapper.h"
 #include "mozilla/HashFunctions.h"
 #include "mozilla/dom/ScriptSettings.h"
--- a/dom/plugins/base/nsNPAPIPlugin.cpp
+++ b/dom/plugins/base/nsNPAPIPlugin.cpp
@@ -21,29 +21,30 @@
 #include "nsIServiceManager.h"
 #include "nsThreadUtils.h"
 #include "mozilla/Preferences.h"
 #include "nsPluginInstanceOwner.h"
 
 #include "nsPluginsDir.h"
 #include "nsPluginLogging.h"
 
-#include "nsIDOMElement.h"
 #include "nsPIDOMWindow.h"
 #include "nsGlobalWindow.h"
 #include "nsIDocument.h"
 #include "nsIContent.h"
 #include "nsIIDNService.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIScriptContext.h"
 #include "nsDOMJSUtils.h"
 #include "nsIPrincipal.h"
 #include "nsWildCard.h"
 #include "nsContentUtils.h"
+#include "mozilla/dom/Element.h"
 #include "mozilla/dom/ScriptSettings.h"
+#include "mozilla/dom/ToJSValue.h"
 #include "nsIXULRuntime.h"
 #include "nsIXPConnect.h"
 
 #include "nsIObserverService.h"
 #include <prinrval.h>
 
 #ifdef MOZ_WIDGET_COCOA
 #include <Carbon/Carbon.h>
@@ -708,17 +709,17 @@ NPObject*
     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_getpluginelement called from the wrong thread\n"));
     return nullptr;
   }
 
   nsNPAPIPluginInstance* inst = static_cast<nsNPAPIPluginInstance*>(npp->ndata);
   if (!inst)
     return nullptr;
 
-  nsCOMPtr<nsIDOMElement> element;
+  RefPtr<dom::Element> element;
   inst->GetDOMElement(getter_AddRefs(element));
 
   if (!element)
     return nullptr;
 
   nsIDocument *doc = GetDocumentFromNPP(npp);
   if (NS_WARN_IF(!doc)) {
     return nullptr;
@@ -728,20 +729,26 @@ NPObject*
   if (NS_WARN_IF(!jsapi.Init(doc->GetInnerWindow()))) {
     return nullptr;
   }
   JSContext* cx = jsapi.cx();
 
   nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID()));
   NS_ENSURE_TRUE(xpc, nullptr);
 
-  JS::RootedObject obj(cx);
-  xpc->WrapNative(cx, ::JS::CurrentGlobalOrNull(cx), element,
-                  NS_GET_IID(nsIDOMElement), obj.address());
-  NS_ENSURE_TRUE(obj, nullptr);
+  JS::RootedValue val(cx);
+  if (!ToJSValue(cx, element, &val)) {
+    return nullptr;
+  }
+
+  if (NS_WARN_IF(!val.isObject())) {
+    return nullptr;
+  }
+
+  JS::RootedObject obj(cx, &val.toObject());
 
   return nsJSObjWrapper::GetNewOrUsed(npp, obj);
 }
 
 NPIdentifier
 _getstringidentifier(const NPUTF8* name)
 {
   if (!name) {
@@ -1446,28 +1453,23 @@ NPError
   }
 
   case NPNVdocumentOrigin: {
     nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)npp->ndata;
     if (!inst) {
       return NPERR_GENERIC_ERROR;
     }
 
-    nsCOMPtr<nsIDOMElement> element;
+    RefPtr<dom::Element> element;
     inst->GetDOMElement(getter_AddRefs(element));
     if (!element) {
       return NPERR_GENERIC_ERROR;
     }
 
-    nsCOMPtr<nsIContent> content(do_QueryInterface(element));
-    if (!content) {
-      return NPERR_GENERIC_ERROR;
-    }
-
-    nsIPrincipal* principal = content->NodePrincipal();
+    nsIPrincipal* principal = element->NodePrincipal();
 
     nsAutoString utf16Origin;
     res = nsContentUtils::GetUTFOrigin(principal, utf16Origin);
     if (NS_FAILED(res)) {
       return NPERR_GENERIC_ERROR;
     }
 
     nsCOMPtr<nsIIDNService> idnService = do_GetService(NS_IDNSERVICE_CONTRACTID);
--- a/dom/plugins/base/nsNPAPIPluginInstance.cpp
+++ b/dom/plugins/base/nsNPAPIPluginInstance.cpp
@@ -13,31 +13,31 @@
 #include "nsNPAPIPlugin.h"
 #include "nsNPAPIPluginStreamListener.h"
 #include "nsPluginHost.h"
 #include "nsPluginLogging.h"
 #include "nsContentUtils.h"
 #include "nsPluginInstanceOwner.h"
 
 #include "nsThreadUtils.h"
-#include "nsIDOMElement.h"
 #include "nsIDocument.h"
 #include "nsIDocShell.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIScriptContext.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsJSNPRuntime.h"
 #include "nsPluginStreamListenerPeer.h"
 #include "nsSize.h"
 #include "nsNetCID.h"
 #include "nsIContent.h"
 #include "nsVersionComparator.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Unused.h"
 #include "nsILoadContext.h"
+#include "mozilla/dom/Element.h"
 #include "mozilla/dom/HTMLObjectElementBinding.h"
 #include "AudioChannelService.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 using namespace mozilla;
 using namespace mozilla::plugins::parent;
@@ -1083,17 +1083,17 @@ nsNPAPIPluginInstance::ConvertPoint(doub
   if (mOwner) {
     return mOwner->ConvertPoint(sourceX, sourceY, sourceSpace, destX, destY, destSpace);
   }
 
   return false;
 }
 
 nsresult
-nsNPAPIPluginInstance::GetDOMElement(nsIDOMElement* *result)
+nsNPAPIPluginInstance::GetDOMElement(Element** result)
 {
   if (!mOwner) {
     *result = nullptr;
     return NS_ERROR_FAILURE;
   }
 
   return mOwner->GetDOMElement(result);
 }
--- a/dom/plugins/base/nsNPAPIPluginInstance.h
+++ b/dom/plugins/base/nsNPAPIPluginInstance.h
@@ -26,16 +26,22 @@
 #include "mozilla/WeakPtr.h"
 
 class nsPluginStreamListenerPeer; // browser-initiated stream class
 class nsNPAPIPluginStreamListener; // plugin-initiated stream class
 class nsIPluginInstanceOwner;
 class nsIOutputStream;
 class nsPluginInstanceOwner;
 
+namespace mozilla {
+namespace dom {
+class Element;
+} // namespace dom
+} // namespace mozilla
+
 #if defined(OS_WIN)
 const NPDrawingModel kDefaultDrawingModel = NPDrawingModelSyncWin;
 #elif defined(MOZ_X11)
 const NPDrawingModel kDefaultDrawingModel = NPDrawingModelSyncX;
 #elif defined(XP_MACOSX)
 #ifndef NP_NO_QUICKDRAW
 const NPDrawingModel kDefaultDrawingModel = NPDrawingModelQuickDraw; // Not supported
 #else
@@ -185,17 +191,17 @@ public:
   void SetCached(bool aCache);
 
   already_AddRefed<nsPIDOMWindowOuter> GetDOMWindow();
 
   nsresult PrivateModeStateChanged(bool aEnabled);
 
   nsresult IsPrivateBrowsing(bool *aEnabled);
 
-  nsresult GetDOMElement(nsIDOMElement* *result);
+  nsresult GetDOMElement(mozilla::dom::Element* *result);
 
   nsNPAPITimer* TimerWithID(uint32_t id, uint32_t* index);
   uint32_t      ScheduleTimer(uint32_t interval, NPBool repeat, void (*timerFunc)(NPP npp, uint32_t timerID));
   void          UnscheduleTimer(uint32_t timerID);
   NPBool        ConvertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace);
 
 
   nsTArray<nsNPAPIPluginStreamListener*> *StreamListeners();
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
@@ -47,16 +47,17 @@
 #include "nsIBlocklistService.h"
 #include "nsVersionComparator.h"
 #include "nsIObjectLoadingContent.h"
 #include "nsIWritablePropertyBag2.h"
 #include "nsICategoryManager.h"
 #include "nsPluginStreamListenerPeer.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/ContentParent.h"
+#include "mozilla/dom/Element.h"
 #include "mozilla/dom/FakePluginTagInitBinding.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/LoadInfo.h"
 #include "mozilla/plugins/PluginBridge.h"
 #include "mozilla/plugins/PluginTypes.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/ipc/URIUtils.h"
 
@@ -65,17 +66,16 @@
 #include "nsXPCOMCID.h"
 #include "nsISupportsPrimitives.h"
 
 #include "nsXULAppAPI.h"
 #include "nsIXULRuntime.h"
 
 // for the dialog
 #include "nsIWindowWatcher.h"
-#include "nsIDOMElement.h"
 #include "nsIDOMWindow.h"
 
 #include "nsNetCID.h"
 #include "mozilla/Sprintf.h"
 #include "nsThreadUtils.h"
 #include "nsIInputStreamTee.h"
 #include "nsQueryObject.h"
 
@@ -3292,34 +3292,33 @@ nsresult nsPluginHost::NewPluginURLStrea
   NS_ENSURE_SUCCESS(rv, rv);
 
   RefPtr<nsPluginStreamListenerPeer> listenerPeer = new nsPluginStreamListenerPeer();
   NS_ENSURE_TRUE(listenerPeer, NS_ERROR_OUT_OF_MEMORY);
 
   rv = listenerPeer->Initialize(url, aInstance, aListener);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCOMPtr<nsIDOMElement> element;
+  RefPtr<dom::Element> element;
   nsCOMPtr<nsIDocument> doc;
   if (owner) {
     owner->GetDOMElement(getter_AddRefs(element));
     owner->GetDocument(getter_AddRefs(doc));
   }
 
-  nsCOMPtr<nsINode> requestingNode(do_QueryInterface(element));
-  NS_ENSURE_TRUE(requestingNode, NS_ERROR_FAILURE);
+  NS_ENSURE_TRUE(element, NS_ERROR_FAILURE);
 
   nsCOMPtr<nsIChannel> channel;
   // @arg loadgroup:
   // do not add this internal plugin's channel on the
   // load group otherwise this channel could be canceled
   // form |nsDocShell::OnLinkClickSync| bug 166613
   rv = NS_NewChannel(getter_AddRefs(channel),
                      url,
-                     requestingNode,
+                     element,
                      nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS |
                      nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL,
                      nsIContentPolicy::TYPE_OBJECT_SUBREQUEST,
                      nullptr, // aPerformanceStorage
                      nullptr,  // aLoadGroup
                      listenerPeer,
                      nsIRequest::LOAD_NORMAL | nsIChannel::LOAD_CLASSIFY_URI |
                      nsIChannel::LOAD_BYPASS_SERVICE_WORKER);
@@ -3852,17 +3851,17 @@ nsPluginHost::PluginCrashed(nsNPAPIPlugi
 
   // Invalidate each nsPluginInstanceTag for the crashed plugin
 
   for (uint32_t i = mInstances.Length(); i > 0; i--) {
     nsNPAPIPluginInstance* instance = mInstances[i - 1];
     if (instance->GetPlugin() == aPlugin) {
       // notify the content node (nsIObjectLoadingContent) that the
       // plugin has crashed
-      nsCOMPtr<nsIDOMElement> domElement;
+      RefPtr<dom::Element> domElement;
       instance->GetDOMElement(getter_AddRefs(domElement));
       nsCOMPtr<nsIObjectLoadingContent> objectContent(do_QueryInterface(domElement));
       if (objectContent) {
         objectContent->PluginCrashed(crashedPluginTag, pluginDumpID, browserDumpID,
                                      submittedCrashReport);
       }
 
       instance->Destroy();
@@ -3947,17 +3946,17 @@ nsPluginHost::DestroyRunningInstances(ns
     if (instance->IsRunning() && (!aPluginTag || aPluginTag == TagForPlugin(instance->GetPlugin()))) {
       instance->SetWindow(nullptr);
       instance->Stop();
 
       // Get rid of all the instances without the possibility of caching.
       nsPluginTag* pluginTag = TagForPlugin(instance->GetPlugin());
       instance->SetWindow(nullptr);
 
-      nsCOMPtr<nsIDOMElement> domElement;
+      RefPtr<dom::Element> domElement;
       instance->GetDOMElement(getter_AddRefs(domElement));
       nsCOMPtr<nsIObjectLoadingContent> objectContent =
         do_QueryInterface(domElement);
 
       instance->Destroy();
 
       mInstances.RemoveElement(instance);
       OnPluginInstanceDestroyed(pluginTag);
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -47,16 +47,17 @@ using mozilla::DefaultXDisplay;
 #include "ImageContainer.h"
 #include "GLContext.h"
 #include "EGLUtils.h"
 #include "nsIContentInlines.h"
 #include "mozilla/MiscEvents.h"
 #include "mozilla/MouseEvents.h"
 #include "mozilla/TextEvents.h"
 #include "mozilla/dom/DragEvent.h"
+#include "mozilla/dom/Element.h"
 #include "mozilla/dom/Event.h"
 #include "mozilla/dom/HTMLObjectElementBinding.h"
 #include "mozilla/dom/TabChild.h"
 #include "mozilla/dom/WheelEventBinding.h"
 #include "nsFrameSelection.h"
 #include "PuppetWidget.h"
 #include "nsPIWindowRoot.h"
 #include "mozilla/IMEStateManager.h"
@@ -382,17 +383,17 @@ void nsPluginInstanceOwner::GetAttribute
 {
   nsCOMPtr<nsIObjectLoadingContent> content = do_QueryReferent(mContent);
   nsObjectLoadingContent *loadingContent =
     static_cast<nsObjectLoadingContent*>(content.get());
 
   loadingContent->GetPluginAttributes(attributes);
 }
 
-NS_IMETHODIMP nsPluginInstanceOwner::GetDOMElement(nsIDOMElement* *result)
+NS_IMETHODIMP nsPluginInstanceOwner::GetDOMElement(Element** result)
 {
   return CallQueryReferent(mContent.get(), result);
 }
 
 nsresult nsPluginInstanceOwner::GetInstance(nsNPAPIPluginInstance **aInstance)
 {
   NS_ENSURE_ARG_POINTER(aInstance);
 
@@ -3292,17 +3293,17 @@ void nsPluginInstanceOwner::SetFrame(nsP
       mPluginFrame->PrepForDrawing(mWidget);
     }
     mPluginFrame->FixupWindow(mPluginFrame->GetContentRectRelativeToSelf().Size());
     mPluginFrame->InvalidateFrame();
 
     nsFocusManager* fm = nsFocusManager::GetFocusManager();
     const nsIContent* content = aFrame->GetContent();
     if (fm && content) {
-      mContentFocused = (content == fm->GetFocusedContent());
+      mContentFocused = (content == fm->GetFocusedElement());
     }
 
     // Register for widget-focus events on the window root.
     if (content && content->OwnerDoc()->GetWindow()) {
       nsCOMPtr<EventTarget> windowRoot = content->OwnerDoc()->GetWindow()->GetTopWindowRoot();
       if (windowRoot) {
         windowRoot->AddEventListener(NS_LITERAL_STRING("activate"),
                                            this, false, false);
--- a/dom/plugins/base/nsPluginInstanceOwner.h
+++ b/dom/plugins/base/nsPluginInstanceOwner.h
@@ -32,16 +32,17 @@ class nsDisplayListBuilder;
 
 #if defined(MOZ_X11)
 class gfxContext;
 #endif
 
 namespace mozilla {
 class TextComposition;
 namespace dom {
+class Element;
 class Event;
 struct MozPluginParameter;
 } // namespace dom
 namespace widget {
 class PuppetWidget;
 } // namespace widget
 } // namespace mozilla
 
@@ -90,17 +91,17 @@ public:
 
   /**
    * Returns the DOM element corresponding to the tag which references
    * this plugin in the document.
    *
    * @param aDOMElement - resulting DOM element
    * @result - NS_OK if this operation was successful
    */
-  NS_IMETHOD GetDOMElement(nsIDOMElement* * aResult);
+  NS_IMETHOD GetDOMElement(mozilla::dom::Element** aResult);
 
   // nsIDOMEventListener interfaces
   NS_DECL_NSIDOMEVENTLISTENER
 
   nsresult ProcessMouseDown(mozilla::dom::Event* aMouseEvent);
   nsresult ProcessKeyPress(mozilla::dom::Event* aKeyEvent);
   nsresult Destroy();
 
--- a/dom/plugins/base/nsPluginStreamListenerPeer.cpp
+++ b/dom/plugins/base/nsPluginStreamListenerPeer.cpp
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsPluginStreamListenerPeer.h"
 #include "nsIContentPolicy.h"
 #include "nsContentPolicyUtils.h"
-#include "nsIDOMElement.h"
 #include "nsIStreamConverterService.h"
 #include "nsIStreamLoader.h"
 #include "nsIHttpChannel.h"
 #include "nsIHttpChannelInternal.h"
 #include "nsIFileChannel.h"
 #include "nsMimeTypes.h"
 #include "nsISupportsPrimitives.h"
 #include "nsNetCID.h"
--- a/dom/plugins/ipc/PluginInstanceParent.cpp
+++ b/dom/plugins/ipc/PluginInstanceParent.cpp
@@ -21,17 +21,16 @@
 #include "gfxASurface.h"
 #include "gfxContext.h"
 #include "gfxPlatform.h"
 #include "gfxSharedImageSurface.h"
 #include "nsNetUtil.h"
 #include "nsNPAPIPluginInstance.h"
 #include "nsPluginInstanceOwner.h"
 #include "nsFocusManager.h"
-#include "nsIDOMElement.h"
 #ifdef MOZ_X11
 #include "gfxXlibSurface.h"
 #endif
 #include "gfxUtils.h"
 #include "mozilla/gfx/2D.h"
 #include "Layers.h"
 #include "ImageContainer.h"
 #include "GLContext.h"
@@ -2217,21 +2216,20 @@ PluginInstanceParent::AnswerPluginFocusC
     // when it's plugin window (or one of it's children) receives keyboard
     // focus. We detect this and forward a notification here so we can update
     // focus.
 #if defined(OS_WIN)
     if (gotFocus) {
       nsPluginInstanceOwner* owner = GetOwner();
       if (owner) {
         nsIFocusManager* fm = nsFocusManager::GetFocusManager();
-        nsCOMPtr<nsIDOMElement> element;
+        RefPtr<dom::Element> element;
         owner->GetDOMElement(getter_AddRefs(element));
         if (fm && element) {
-          nsCOMPtr<dom::Element> domElement(do_QueryInterface(element));
-          fm->SetFocus(domElement, 0);
+          fm->SetFocus(element, 0);
         }
       }
     }
     return IPC_OK();
 #else
     NS_NOTREACHED("PluginInstanceParent::AnswerPluginFocusChange not implemented!");
     return IPC_FAIL_NO_REASON(this);
 #endif
--- a/dom/plugins/ipc/PluginModuleParent.cpp
+++ b/dom/plugins/ipc/PluginModuleParent.cpp
@@ -8,16 +8,17 @@
 
 #include "base/process_util.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/AutoRestore.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/ipc/CrashReporterClient.h"
 #include "mozilla/ipc/CrashReporterHost.h"
+#include "mozilla/dom/Element.h"
 #include "mozilla/ipc/GeckoChildProcessHost.h"
 #include "mozilla/ipc/MessageChannel.h"
 #include "mozilla/ipc/ProtocolUtils.h"
 #include "mozilla/plugins/BrowserStreamParent.h"
 #include "mozilla/plugins/PluginBridge.h"
 #include "mozilla/plugins/PluginInstanceParent.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/ProcessHangMonitor.h"
@@ -2467,20 +2468,20 @@ PluginModuleParent::NPP_NewInternal(NPMI
 #endif
     }
 
     instance->pdata = parentInstance;
 
     // Any IPC messages for the PluginInstance actor should be dispatched to the
     // DocGroup for the plugin's document.
     RefPtr<nsPluginInstanceOwner> owner = parentInstance->GetOwner();
-    nsCOMPtr<nsIDOMElement> elt;
+    RefPtr<dom::Element> elt;
     owner->GetDOMElement(getter_AddRefs(elt));
-    if (nsCOMPtr<nsINode> node = do_QueryInterface(elt)) {
-        nsCOMPtr<nsIDocument> doc = node->OwnerDoc();
+    if (elt) {
+        nsCOMPtr<nsIDocument> doc = elt->OwnerDoc();
         if (doc) {
             nsCOMPtr<nsIEventTarget> eventTarget = doc->EventTargetFor(TaskCategory::Other);
             SetEventTargetForActor(parentInstance, eventTarget);
         }
     }
 
     if (!SendPPluginInstanceConstructor(parentInstance,
                                         nsDependentCString(pluginType),
--- a/dom/quota/StorageManager.cpp
+++ b/dom/quota/StorageManager.cpp
@@ -737,17 +737,17 @@ PersistentStoragePermissionRequest::GetW
   MOZ_ASSERT(mWindow);
 
   NS_ADDREF(*aRequestingWindow = mWindow);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-PersistentStoragePermissionRequest::GetElement(nsIDOMElement** aElement)
+PersistentStoragePermissionRequest::GetElement(Element** aElement)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aElement);
 
   *aElement = nullptr;
   return NS_OK;
 }
 
--- a/dom/serviceworkers/ServiceWorkerContainer.cpp
+++ b/dom/serviceworkers/ServiceWorkerContainer.cpp
@@ -16,16 +16,17 @@
 #include "nsNetUtil.h"
 #include "nsPIDOMWindow.h"
 #include "mozilla/Services.h"
 
 #include "nsCycleCollectionParticipant.h"
 #include "nsServiceManagerUtils.h"
 
 #include "mozilla/LoadInfo.h"
+#include "mozilla/dom/DOMMozPromiseRequestHolder.h"
 #include "mozilla/dom/DOMPrefs.h"
 #include "mozilla/dom/Navigator.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/ServiceWorker.h"
 #include "mozilla/dom/ServiceWorkerContainerBinding.h"
 
 #include "ServiceWorker.h"
 #include "ServiceWorkerContainerImpl.h"
@@ -352,33 +353,37 @@ ServiceWorkerContainer::Register(const n
   window->NoteCalledRegisterForServiceWorkerScope(cleanedScopeURL);
 
   RefPtr<Promise> outer = Promise::Create(global, aRv);
   if (aRv.Failed()) {
     return nullptr;
   }
 
   RefPtr<ServiceWorkerContainer> self = this;
+  RefPtr<DOMMozPromiseRequestHolder<ServiceWorkerRegistrationPromise>> holder =
+    new DOMMozPromiseRequestHolder<ServiceWorkerRegistrationPromise>(global);
 
   mInner->Register(clientInfo.ref(), cleanedScopeURL, cleanedScriptURL,
                    aOptions.mUpdateViaCache)->Then(
     global->EventTargetFor(TaskCategory::Other), __func__,
-    [self, outer] (const ServiceWorkerRegistrationDescriptor& aDesc) {
+    [self, outer, holder] (const ServiceWorkerRegistrationDescriptor& aDesc) {
+      holder->Complete();
       ErrorResult rv;
       nsIGlobalObject* global = self->GetGlobalIfValid(rv);
       if (rv.Failed()) {
         outer->MaybeReject(rv);
         return;
       }
       RefPtr<ServiceWorkerRegistration> reg =
         global->GetOrCreateServiceWorkerRegistration(aDesc);
       outer->MaybeResolve(reg);
-    }, [self, outer] (ErrorResult&& aRv) {
-      outer->MaybeReject(aRv);
-    });
+    }, [self, outer, holder] (const CopyableErrorResult& aRv) {
+      holder->Complete();
+      outer->MaybeReject(CopyableErrorResult(aRv));
+    })->Track(*holder);
 
   return outer.forget();
 }
 
 already_AddRefed<ServiceWorker>
 ServiceWorkerContainer::GetController()
 {
   RefPtr<ServiceWorker> ref = mControllerWorker;
@@ -405,38 +410,42 @@ ServiceWorkerContainer::GetRegistrations
   }
 
   RefPtr<Promise> outer = Promise::Create(global, aRv);
   if (aRv.Failed()) {
     return nullptr;
   }
 
   RefPtr<ServiceWorkerContainer> self = this;
+  RefPtr<DOMMozPromiseRequestHolder<ServiceWorkerRegistrationListPromise>> holder =
+    new DOMMozPromiseRequestHolder<ServiceWorkerRegistrationListPromise>(global);
 
   mInner->GetRegistrations(clientInfo.ref())->Then(
     global->EventTargetFor(TaskCategory::Other), __func__,
-    [self, outer] (const nsTArray<ServiceWorkerRegistrationDescriptor>& aDescList) {
+    [self, outer, holder] (const nsTArray<ServiceWorkerRegistrationDescriptor>& aDescList) {
+      holder->Complete();
       ErrorResult rv;
       nsIGlobalObject* global = self->GetGlobalIfValid(rv);
       if (rv.Failed()) {
         outer->MaybeReject(rv);
         return;
       }
       nsTArray<RefPtr<ServiceWorkerRegistration>> regList;
       for (auto& desc : aDescList) {
         RefPtr<ServiceWorkerRegistration> reg =
           global->GetOrCreateServiceWorkerRegistration(desc);
         if (reg) {
           regList.AppendElement(Move(reg));
         }
       }
       outer->MaybeResolve(regList);
-    }, [self, outer] (ErrorResult&& aRv) {
-      outer->MaybeReject(aRv);
-    });
+    }, [self, outer, holder] (const CopyableErrorResult& aRv) {
+      holder->Complete();
+      outer->MaybeReject(CopyableErrorResult(aRv));
+    })->Track(*holder);
 
   return outer.forget();
 }
 
 already_AddRefed<Promise>
 ServiceWorkerContainer::GetRegistration(const nsAString& aURL,
                                         ErrorResult& aRv)
 {
@@ -474,37 +483,42 @@ ServiceWorkerContainer::GetRegistration(
   }
 
   RefPtr<Promise> outer = Promise::Create(global, aRv);
   if (aRv.Failed()) {
     return nullptr;
   }
 
   RefPtr<ServiceWorkerContainer> self = this;
+  RefPtr<DOMMozPromiseRequestHolder<ServiceWorkerRegistrationPromise>> holder =
+    new DOMMozPromiseRequestHolder<ServiceWorkerRegistrationPromise>(global);
 
   mInner->GetRegistration(clientInfo.ref(), spec)->Then(
     global->EventTargetFor(TaskCategory::Other), __func__,
-    [self, outer] (const ServiceWorkerRegistrationDescriptor& aDescriptor) {
+    [self, outer, holder] (const ServiceWorkerRegistrationDescriptor& aDescriptor) {
+      holder->Complete();
       ErrorResult rv;
       nsIGlobalObject* global = self->GetGlobalIfValid(rv);
       if (rv.Failed()) {
         outer->MaybeReject(rv);
         return;
       }
       RefPtr<ServiceWorkerRegistration> reg =
         global->GetOrCreateServiceWorkerRegistration(aDescriptor);
       outer->MaybeResolve(reg);
-    }, [self, outer] (ErrorResult&& aRv) {
-      Unused << self->GetGlobalIfValid(aRv);
-      if (!aRv.Failed()) {
+    }, [self, outer, holder] (const CopyableErrorResult& aRv) {
+      holder->Complete();
+      ErrorResult rv;
+      Unused << self->GetGlobalIfValid(rv);
+      if (!rv.Failed() && !aRv.Failed()) {
         outer->MaybeResolveWithUndefined();
         return;
       }
-      outer->MaybeReject(aRv);
-    });
+      outer->MaybeReject(CopyableErrorResult(aRv));
+    })->Track(*holder);
 
   return outer.forget();
 }
 
 Promise*
 ServiceWorkerContainer::GetReady(ErrorResult& aRv)
 {
   if (mReadyPromise) {
@@ -525,33 +539,37 @@ ServiceWorkerContainer::GetReady(ErrorRe
 
   mReadyPromise = Promise::Create(global, aRv);
   if (aRv.Failed()) {
     return nullptr;
   }
 
   RefPtr<ServiceWorkerContainer> self = this;
   RefPtr<Promise> outer = mReadyPromise;
+  RefPtr<DOMMozPromiseRequestHolder<ServiceWorkerRegistrationPromise>> holder =
+    new DOMMozPromiseRequestHolder<ServiceWorkerRegistrationPromise>(global);
 
   mInner->GetReady(clientInfo.ref())->Then(
     global->EventTargetFor(TaskCategory::Other), __func__,
-    [self, outer] (const ServiceWorkerRegistrationDescriptor& aDescriptor) {
+    [self, outer, holder] (const ServiceWorkerRegistrationDescriptor& aDescriptor) {
+      holder->Complete();
       ErrorResult rv;
       nsIGlobalObject* global = self->GetGlobalIfValid(rv);
       if (rv.Failed()) {
         outer->MaybeReject(rv);
         return;
       }
       RefPtr<ServiceWorkerRegistration> reg =
         global->GetOrCreateServiceWorkerRegistration(aDescriptor);
       NS_ENSURE_TRUE_VOID(reg);
       outer->MaybeResolve(reg);
-    }, [self, outer] (ErrorResult&& aRv) {
-      outer->MaybeReject(aRv);
-    });
+    }, [self, outer, holder] (const CopyableErrorResult& aRv) {
+      holder->Complete();
+      outer->MaybeReject(CopyableErrorResult(aRv));
+    })->Track(*holder);
 
   return mReadyPromise;
 }
 
 // Testing only.
 void
 ServiceWorkerContainer::GetScopeForUrl(const nsAString& aUrl,
                                        nsString& aScope,
--- a/dom/serviceworkers/ServiceWorkerDescriptor.cpp
+++ b/dom/serviceworkers/ServiceWorkerDescriptor.cpp
@@ -7,16 +7,19 @@
 #include "ServiceWorkerDescriptor.h"
 #include "mozilla/dom/IPCServiceWorkerDescriptor.h"
 #include "mozilla/dom/ServiceWorkerBinding.h"
 #include "mozilla/ipc/PBackgroundSharedTypes.h"
 
 namespace mozilla {
 namespace dom {
 
+using mozilla::ipc::PrincipalInfo;
+using mozilla::ipc::PrincipalInfoToPrincipal;
+
 ServiceWorkerDescriptor::ServiceWorkerDescriptor(uint64_t aId,
                                                  nsIPrincipal* aPrincipal,
                                                  const nsACString& aScope,
                                                  const nsACString& aScriptURL,
                                                  ServiceWorkerState aState)
   : mData(MakeUnique<IPCServiceWorkerDescriptor>())
 {
   MOZ_ALWAYS_SUCCEEDS(
@@ -90,16 +93,24 @@ ServiceWorkerDescriptor::Id() const
 }
 
 const mozilla::ipc::PrincipalInfo&
 ServiceWorkerDescriptor::PrincipalInfo() const
 {
   return mData->principalInfo();
 }
 
+nsCOMPtr<nsIPrincipal>
+ServiceWorkerDescriptor::GetPrincipal() const
+{
+  AssertIsOnMainThread();
+  nsCOMPtr<nsIPrincipal> ref =  PrincipalInfoToPrincipal(mData->principalInfo());
+  return Move(ref);
+}
+
 const nsCString&
 ServiceWorkerDescriptor::Scope() const
 {
   return mData->scope();
 }
 
 const nsCString&
 ServiceWorkerDescriptor::ScriptURL() const
--- a/dom/serviceworkers/ServiceWorkerDescriptor.h
+++ b/dom/serviceworkers/ServiceWorkerDescriptor.h
@@ -2,16 +2,17 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #ifndef _mozilla_dom_ServiceWorkerDescriptor_h
 #define _mozilla_dom_ServiceWorkerDescriptor_h
 
 #include "mozilla/UniquePtr.h"
+#include "nsCOMPtr.h"
 #include "nsString.h"
 
 class nsIPrincipal;
 
 namespace mozilla {
 
 namespace ipc {
 class PrincipalInfo;
@@ -64,16 +65,19 @@ public:
   operator==(const ServiceWorkerDescriptor& aRight) const;
 
   uint64_t
   Id() const;
 
   const mozilla::ipc::PrincipalInfo&
   PrincipalInfo() const;
 
+  nsCOMPtr<nsIPrincipal>
+  GetPrincipal() const;
+
   const nsCString&
   Scope() const;
 
   const nsCString&
   ScriptURL() const;
 
   ServiceWorkerState
   State() const;
--- a/dom/serviceworkers/ServiceWorkerRegistration.cpp
+++ b/dom/serviceworkers/ServiceWorkerRegistration.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ServiceWorkerRegistration.h"
 
+#include "mozilla/dom/DOMMozPromiseRequestHolder.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/PushManager.h"
 #include "mozilla/dom/ServiceWorker.h"
 #include "mozilla/dom/ServiceWorkerRegistrationBinding.h"
 #include "mozilla/dom/WorkerPrivate.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsISupportsPrimitives.h"
 #include "nsPIDOMWindow.h"
@@ -193,17 +194,51 @@ ServiceWorkerRegistration::GetUpdateViaC
 
 already_AddRefed<Promise>
 ServiceWorkerRegistration::Update(ErrorResult& aRv)
 {
   if (!mInner) {
     aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     return nullptr;
   }
-  return mInner->Update(aRv);
+
+  nsIGlobalObject* global = GetParentObject();
+  if (!global) {
+    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+    return nullptr;
+  }
+
+  RefPtr<Promise> outer = Promise::Create(global, aRv);
+  if (NS_WARN_IF(aRv.Failed())) {
+    return nullptr;
+  }
+
+  RefPtr<ServiceWorkerRegistration> self = this;
+  RefPtr<DOMMozPromiseRequestHolder<ServiceWorkerRegistrationPromise>> holder =
+    new DOMMozPromiseRequestHolder<ServiceWorkerRegistrationPromise>(global);
+
+  mInner->Update(aRv)->Then(
+    global->EventTargetFor(TaskCategory::Other), __func__,
+    [outer, self, holder](const ServiceWorkerRegistrationDescriptor& aDesc) {
+      holder->Complete();
+      nsIGlobalObject* global = self->GetParentObject();
+      MOZ_DIAGNOSTIC_ASSERT(global);
+      RefPtr<ServiceWorkerRegistration> ref =
+        global->GetOrCreateServiceWorkerRegistration(aDesc);
+      if (!ref) {
+        outer->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
+        return;
+      }
+      outer->MaybeResolve(ref);
+    }, [outer, holder] (const CopyableErrorResult& aRv) {
+      holder->Complete();
+      outer->MaybeReject(CopyableErrorResult(aRv));
+    })->Track(*holder);
+
+  return outer.forget();
 }
 
 already_AddRefed<Promise>
 ServiceWorkerRegistration::Unregister(ErrorResult& aRv)
 {
   if (!mInner) {
     aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     return nullptr;
--- a/dom/serviceworkers/ServiceWorkerRegistration.h
+++ b/dom/serviceworkers/ServiceWorkerRegistration.h
@@ -7,16 +7,17 @@
 #ifndef mozilla_dom_ServiceWorkerRegistration_h
 #define mozilla_dom_ServiceWorkerRegistration_h
 
 #include "mozilla/DOMEventTargetHelper.h"
 #include "mozilla/dom/DOMPrefs.h"
 #include "mozilla/dom/ServiceWorkerBinding.h"
 #include "mozilla/dom/ServiceWorkerRegistrationBinding.h"
 #include "mozilla/dom/ServiceWorkerRegistrationDescriptor.h"
+#include "mozilla/dom/ServiceWorkerUtils.h"
 
 // Support for Notification API extension.
 #include "mozilla/dom/NotificationBinding.h"
 
 class nsIGlobalObject;
 
 namespace mozilla {
 namespace dom {
@@ -38,17 +39,17 @@ public:
     NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
 
     virtual void
     SetServiceWorkerRegistration(ServiceWorkerRegistration* aReg) = 0;
 
     virtual void
     ClearServiceWorkerRegistration(ServiceWorkerRegistration* aReg) = 0;
 
-    virtual already_AddRefed<Promise>
+    virtual RefPtr<ServiceWorkerRegistrationPromise>
     Update(ErrorResult& aRv) = 0;
 
     virtual already_AddRefed<Promise>
     Unregister(ErrorResult& aRv) = 0;
 
     virtual already_AddRefed<Promise>
     ShowNotification(JSContext* aCx,
                      const nsAString& aTitle,
--- a/dom/serviceworkers/ServiceWorkerRegistrationDescriptor.cpp
+++ b/dom/serviceworkers/ServiceWorkerRegistrationDescriptor.cpp
@@ -8,16 +8,19 @@
 
 #include "mozilla/dom/IPCServiceWorkerRegistrationDescriptor.h"
 #include "mozilla/ipc/PBackgroundSharedTypes.h"
 #include "ServiceWorkerInfo.h"
 
 namespace mozilla {
 namespace dom {
 
+using mozilla::ipc::PrincipalInfo;
+using mozilla::ipc::PrincipalInfoToPrincipal;
+
 Maybe<IPCServiceWorkerDescriptor>
 ServiceWorkerRegistrationDescriptor::NewestInternal() const
 {
   Maybe<IPCServiceWorkerDescriptor> result;
   if (mData->installing().type() != OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
     result.emplace(mData->installing().get_IPCServiceWorkerDescriptor());
   } else if (mData->waiting().type() != OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
     result.emplace(mData->waiting().get_IPCServiceWorkerDescriptor());
@@ -125,16 +128,24 @@ ServiceWorkerRegistrationDescriptor::Upd
 }
 
 const mozilla::ipc::PrincipalInfo&
 ServiceWorkerRegistrationDescriptor::PrincipalInfo() const
 {
   return mData->principalInfo();
 }
 
+nsCOMPtr<nsIPrincipal>
+ServiceWorkerRegistrationDescriptor::GetPrincipal() const
+{
+  AssertIsOnMainThread();
+  nsCOMPtr<nsIPrincipal> ref =  PrincipalInfoToPrincipal(mData->principalInfo());
+  return Move(ref);
+}
+
 const nsCString&
 ServiceWorkerRegistrationDescriptor::Scope() const
 {
   return mData->scope();
 }
 
 Maybe<ServiceWorkerDescriptor>
 ServiceWorkerRegistrationDescriptor::GetInstalling() const
--- a/dom/serviceworkers/ServiceWorkerRegistrationDescriptor.h
+++ b/dom/serviceworkers/ServiceWorkerRegistrationDescriptor.h
@@ -68,16 +68,19 @@ public:
   Id() const;
 
   ServiceWorkerUpdateViaCache
   UpdateViaCache() const;
 
   const mozilla::ipc::PrincipalInfo&
   PrincipalInfo() const;
 
+  nsCOMPtr<nsIPrincipal>
+  GetPrincipal() const;
+
   const nsCString&
   Scope() const;
 
   Maybe<ServiceWorkerDescriptor>
   GetInstalling() const;
 
   Maybe<ServiceWorkerDescriptor>
   GetWaiting() const;
--- a/dom/serviceworkers/ServiceWorkerRegistrationImpl.cpp
+++ b/dom/serviceworkers/ServiceWorkerRegistrationImpl.cpp
@@ -38,16 +38,17 @@
 namespace mozilla {
 namespace dom {
 
 ////////////////////////////////////////////////////
 // Main Thread implementation
 
 ServiceWorkerRegistrationMainThread::ServiceWorkerRegistrationMainThread(const ServiceWorkerRegistrationDescriptor& aDescriptor)
   : mOuter(nullptr)
+  , mDescriptor(aDescriptor)
   , mScope(NS_ConvertUTF8toUTF16(aDescriptor.Scope()))
   , mListeningForEvents(false)
 {
   MOZ_ASSERT(NS_IsMainThread());
 }
 
 ServiceWorkerRegistrationMainThread::~ServiceWorkerRegistrationMainThread()
 {
@@ -101,16 +102,17 @@ void
 ServiceWorkerRegistrationMainThread::UpdateFound()
 {
   mOuter->DispatchTrustedEvent(NS_LITERAL_STRING("updatefound"));
 }
 
 void
 ServiceWorkerRegistrationMainThread::UpdateState(const ServiceWorkerRegistrationDescriptor& aDescriptor)
 {
+  mDescriptor = aDescriptor;
   mOuter->UpdateState(aDescriptor);
 }
 
 void
 ServiceWorkerRegistrationMainThread::RegistrationRemoved()
 {
   // Queue a runnable to clean up the registration.  This is necessary
   // because there may be runnables in the event queue already to
@@ -163,141 +165,76 @@ UpdateInternal(nsIPrincipal* aPrincipal,
     return;
   }
 
   swm->Update(aPrincipal, aScope, aCallback);
 }
 
 class MainThreadUpdateCallback final : public ServiceWorkerUpdateFinishCallback
 {
-  PromiseWindowProxy mPromise;
+  RefPtr<ServiceWorkerRegistrationPromise::Private> mPromise;
 
   ~MainThreadUpdateCallback()
-  { }
+  {
+    mPromise->Reject(NS_ERROR_DOM_ABORT_ERR, __func__);
+  }
 
 public:
-  explicit MainThreadUpdateCallback(nsPIDOMWindowInner* aWindow,
-                                    Promise* aPromise)
-    : mPromise(aWindow, aPromise)
+  MainThreadUpdateCallback()
+    : mPromise(new ServiceWorkerRegistrationPromise::Private(__func__))
+  {
+  }
+
+  void
+  UpdateSucceeded(ServiceWorkerRegistrationInfo* aRegistration) override
+  {
+    mPromise->Resolve(aRegistration->Descriptor(), __func__);
+  }
+
+  void
+  UpdateFailed(ErrorResult& aStatus) override
+  {
+    mPromise->Reject(Move(aStatus), __func__);
+  }
+
+  RefPtr<ServiceWorkerRegistrationPromise>
+  Promise() const
+  {
+    return mPromise;
+  }
+};
+
+class WorkerThreadUpdateCallback final : public ServiceWorkerUpdateFinishCallback
+{
+  RefPtr<ThreadSafeWorkerRef> mWorkerRef;
+  RefPtr<ServiceWorkerRegistrationPromise::Private> mPromise;
+
+  ~WorkerThreadUpdateCallback() = default;
+
+public:
+  WorkerThreadUpdateCallback(RefPtr<ThreadSafeWorkerRef>&& aWorkerRef,
+                             ServiceWorkerRegistrationPromise::Private* aPromise)
+    : mWorkerRef(Move(aWorkerRef))
+    , mPromise(aPromise)
   {
     MOZ_ASSERT(NS_IsMainThread());
   }
 
   void
   UpdateSucceeded(ServiceWorkerRegistrationInfo* aRegistration) override
   {
-    RefPtr<Promise> promise = mPromise.Get();
-    nsCOMPtr<nsPIDOMWindowInner> win = mPromise.GetWindow();
-    if (!promise || !win) {
-      return;
-    }
-
-    nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
-      "MainThreadUpdateCallback::UpdateSucceeded",
-      [promise = Move(promise)] () {
-        promise->MaybeResolveWithUndefined();
-      });
-    MOZ_ALWAYS_SUCCEEDS(
-      win->EventTargetFor(TaskCategory::Other)->Dispatch(r.forget()));
+    mPromise->Resolve(aRegistration->Descriptor(), __func__);
+    mWorkerRef = nullptr;
   }
 
   void
   UpdateFailed(ErrorResult& aStatus) override
   {
-    if (RefPtr<Promise> promise = mPromise.Get()) {
-      promise->MaybeReject(aStatus);
-    }
-  }
-};
-
-class UpdateResultRunnable final : public WorkerRunnable
-{
-  RefPtr<PromiseWorkerProxy> mPromiseProxy;
-  IPC::Message mSerializedErrorResult;
-
-  ~UpdateResultRunnable()
-  {}
-
-public:
-  UpdateResultRunnable(PromiseWorkerProxy* aPromiseProxy, ErrorResult& aStatus)
-    : WorkerRunnable(aPromiseProxy->GetWorkerPrivate())
-    , mPromiseProxy(aPromiseProxy)
-  {
-    // ErrorResult is not thread safe.  Serialize it for transfer across
-    // threads.
-    IPC::WriteParam(&mSerializedErrorResult, aStatus);
-    aStatus.SuppressException();
-  }
-
-  bool
-  WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
-  {
-    // Deserialize the ErrorResult now that we are back in the worker
-    // thread.
-    ErrorResult status;
-    PickleIterator iter = PickleIterator(mSerializedErrorResult);
-    Unused << IPC::ReadParam(&mSerializedErrorResult, &iter, &status);
-
-    Promise* promise = mPromiseProxy->WorkerPromise();
-    if (status.Failed()) {
-      promise->MaybeReject(status);
-    } else {
-      promise->MaybeResolveWithUndefined();
-    }
-    status.SuppressException();
-    mPromiseProxy->CleanUp();
-    return true;
-  }
-};
-
-class WorkerThreadUpdateCallback final : public ServiceWorkerUpdateFinishCallback
-{
-  RefPtr<PromiseWorkerProxy> mPromiseProxy;
-
-  ~WorkerThreadUpdateCallback()
-  {
-  }
-
-public:
-  explicit WorkerThreadUpdateCallback(PromiseWorkerProxy* aPromiseProxy)
-    : mPromiseProxy(aPromiseProxy)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-  }
-
-  void
-  UpdateSucceeded(ServiceWorkerRegistrationInfo* aRegistration) override
-  {
-    ErrorResult rv(NS_OK);
-    Finish(rv);
-  }
-
-  void
-  UpdateFailed(ErrorResult& aStatus) override
-  {
-    Finish(aStatus);
-  }
-
-  void
-  Finish(ErrorResult& aStatus)
-  {
-    if (!mPromiseProxy) {
-      return;
-    }
-
-    RefPtr<PromiseWorkerProxy> proxy = mPromiseProxy.forget();
-
-    MutexAutoLock lock(proxy->Lock());
-    if (proxy->CleanedUp()) {
-      return;
-    }
-
-    RefPtr<UpdateResultRunnable> r =
-      new UpdateResultRunnable(proxy, aStatus);
-    r->Dispatch();
+    mPromise->Reject(Move(aStatus), __func__);
+    mWorkerRef = nullptr;
   }
 };
 
 class SWRUpdateRunnable final : public Runnable
 {
   class TimerCallback final : public nsITimerCallback
   {
     RefPtr<ServiceWorkerPrivate> mPrivate;
@@ -325,52 +262,45 @@ class SWRUpdateRunnable final : public R
     NS_DECL_THREADSAFE_ISUPPORTS
 
   private:
     ~TimerCallback()
     { }
   };
 
 public:
-  explicit SWRUpdateRunnable(PromiseWorkerProxy* aPromiseProxy)
+  SWRUpdateRunnable(StrongWorkerRef* aWorkerRef,
+                    ServiceWorkerRegistrationPromise::Private* aPromise,
+                    const ServiceWorkerDescriptor& aDescriptor)
     : Runnable("dom::SWRUpdateRunnable")
-    , mPromiseProxy(aPromiseProxy)
-    , mDescriptor(aPromiseProxy->GetWorkerPrivate()->GetServiceWorkerDescriptor())
+    , mMutex("SWRUpdateRunnable")
+    , mWorkerRef(new ThreadSafeWorkerRef(aWorkerRef))
+    , mPromise(aPromise)
+    , mDescriptor(aDescriptor)
     , mDelayed(false)
   {
-    MOZ_ASSERT(mPromiseProxy);
-
-    // This runnable is used for update calls originating from a worker thread,
-    // which may be delayed in some cases.
-    MOZ_ASSERT(mPromiseProxy->GetWorkerPrivate()->IsServiceWorker());
-    MOZ_ASSERT(mPromiseProxy->GetWorkerPrivate());
-    mPromiseProxy->GetWorkerPrivate()->AssertIsOnWorkerThread();
+    MOZ_DIAGNOSTIC_ASSERT(mWorkerRef);
+    MOZ_DIAGNOSTIC_ASSERT(mPromise);
   }
 
   NS_IMETHOD
   Run() override
   {
     MOZ_ASSERT(NS_IsMainThread());
     ErrorResult result;
 
-    nsCOMPtr<nsIPrincipal> principal;
-    // UpdateInternal may try to reject the promise synchronously leading
-    // to a deadlock.
-    {
-      MutexAutoLock lock(mPromiseProxy->Lock());
-      if (mPromiseProxy->CleanedUp()) {
-        return NS_OK;
-      }
-
-      principal = mPromiseProxy->GetWorkerPrivate()->GetPrincipal();
+    nsCOMPtr<nsIPrincipal> principal = mDescriptor.GetPrincipal();
+    if (NS_WARN_IF(!principal)) {
+      mPromise->Reject(NS_ERROR_DOM_INVALID_STATE_ERR, __func__);
+      return NS_OK;
     }
-    MOZ_ASSERT(principal);
 
     RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
     if (NS_WARN_IF(!swm)) {
+      mPromise->Reject(NS_ERROR_DOM_INVALID_STATE_ERR, __func__);
       return NS_OK;
     }
 
     // This will delay update jobs originating from a service worker thread.
     // We don't currently handle ServiceWorkerRegistration.update() from other
     // worker types. Also, we assume this registration matches self.registration
     // on the service worker global. This is ok for now because service worker globals
     // are the only worker contexts where we expose ServiceWorkerRegistration.
@@ -405,29 +335,43 @@ public:
         // and let the update runnable be destroyed.
         timer->Cancel();
         return NS_OK;
       }
 
       return NS_OK;
     }
 
+    RefPtr<ServiceWorkerRegistrationPromise::Private> promise;
+    {
+      MutexAutoLock lock(mMutex);
+      promise.swap(mPromise);
+    }
+
     RefPtr<WorkerThreadUpdateCallback> cb =
-      new WorkerThreadUpdateCallback(mPromiseProxy);
+      new WorkerThreadUpdateCallback(Move(mWorkerRef), promise);
     UpdateInternal(principal, mDescriptor.Scope(), cb);
+
     return NS_OK;
   }
 
 private:
   ~SWRUpdateRunnable()
   {
-    MOZ_ASSERT(NS_IsMainThread());
+    MutexAutoLock lock(mMutex);
+    if (mPromise) {
+      mPromise->Reject(NS_ERROR_DOM_INVALID_STATE_ERR, __func__);
+    }
   }
 
-  RefPtr<PromiseWorkerProxy> mPromiseProxy;
+  // Protects promise access across threads
+  Mutex mMutex;
+
+  RefPtr<ThreadSafeWorkerRef> mWorkerRef;
+  RefPtr<ServiceWorkerRegistrationPromise::Private> mPromise;
   const ServiceWorkerDescriptor mDescriptor;
   bool mDelayed;
 };
 
 NS_IMPL_ISUPPORTS(SWRUpdateRunnable::TimerCallback, nsITimerCallback)
 
 class UnregisterCallback final : public nsIServiceWorkerUnregisterCallback
 {
@@ -616,41 +560,32 @@ public:
       cb->UnregisterFailed();
     }
 
     return NS_OK;
   }
 };
 } // namespace
 
-already_AddRefed<Promise>
+RefPtr<ServiceWorkerRegistrationPromise>
 ServiceWorkerRegistrationMainThread::Update(ErrorResult& aRv)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_DIAGNOSTIC_ASSERT(mOuter);
 
-  nsCOMPtr<nsIGlobalObject> go = mOuter->GetParentObject();
-  if (!go) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
+  nsCOMPtr<nsIPrincipal> principal = mDescriptor.GetPrincipal();
+  if (!principal) {
+    return ServiceWorkerRegistrationPromise::CreateAndReject(
+      NS_ERROR_DOM_INVALID_STATE_ERR, __func__);
   }
 
-  RefPtr<Promise> promise = Promise::Create(go, aRv);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return nullptr;
-  }
+  RefPtr<MainThreadUpdateCallback> cb = new MainThreadUpdateCallback();
+  UpdateInternal(principal, NS_ConvertUTF16toUTF8(mScope), cb);
 
-  nsCOMPtr<nsIDocument> doc = mOuter->GetOwner()->GetExtantDoc();
-  MOZ_ASSERT(doc);
-
-  RefPtr<MainThreadUpdateCallback> cb =
-    new MainThreadUpdateCallback(mOuter->GetOwner(), promise);
-  UpdateInternal(doc->NodePrincipal(), NS_ConvertUTF16toUTF8(mScope), cb);
-
-  return promise.forget();
+  return cb->Promise();
 }
 
 already_AddRefed<Promise>
 ServiceWorkerRegistrationMainThread::Unregister(ErrorResult& aRv)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_DIAGNOSTIC_ASSERT(mOuter);
 
@@ -885,16 +820,17 @@ private:
   ~WorkerListener()
   {
     MOZ_ASSERT(!mListeningForEvents);
   }
 };
 
 ServiceWorkerRegistrationWorkerThread::ServiceWorkerRegistrationWorkerThread(const ServiceWorkerRegistrationDescriptor& aDescriptor)
   : mOuter(nullptr)
+  , mDescriptor(aDescriptor)
   , mScope(NS_ConvertUTF8toUTF16(aDescriptor.Scope()))
 {
 }
 
 ServiceWorkerRegistrationWorkerThread::~ServiceWorkerRegistrationWorkerThread()
 {
   MOZ_DIAGNOSTIC_ASSERT(!mListener);
   MOZ_DIAGNOSTIC_ASSERT(!mOuter);
@@ -923,46 +859,62 @@ ServiceWorkerRegistrationWorkerThread::S
 void
 ServiceWorkerRegistrationWorkerThread::ClearServiceWorkerRegistration(ServiceWorkerRegistration* aReg)
 {
   MOZ_ASSERT_IF(mOuter, mOuter == aReg);
   ReleaseListener();
   mOuter = nullptr;
 }
 
-already_AddRefed<Promise>
+RefPtr<ServiceWorkerRegistrationPromise>
 ServiceWorkerRegistrationWorkerThread::Update(ErrorResult& aRv)
 {
-  WorkerPrivate* worker = GetCurrentThreadWorkerPrivate();
-  MOZ_ASSERT(worker);
-  worker->AssertIsOnWorkerThread();
+  if (NS_WARN_IF(!mWorkerRef->GetPrivate())) {
+    return ServiceWorkerRegistrationPromise::CreateAndReject(
+      NS_ERROR_DOM_INVALID_STATE_ERR, __func__);
+  }
 
-  RefPtr<Promise> promise = Promise::Create(worker->GlobalScope(), aRv);
-  if (aRv.Failed()) {
-    return nullptr;
+  RefPtr<StrongWorkerRef> workerRef =
+    StrongWorkerRef::Create(mWorkerRef->GetPrivate(),
+                            "ServiceWorkerRegistration::Update");
+  if (NS_WARN_IF(!workerRef)) {
+    return ServiceWorkerRegistrationPromise::CreateAndReject(
+      NS_ERROR_DOM_INVALID_STATE_ERR, __func__);
   }
 
   // Avoid infinite update loops by ignoring update() calls during top
   // level script evaluation.  See:
   // https://github.com/slightlyoff/ServiceWorker/issues/800
-  if (worker->LoadScriptAsPartOfLoadingServiceWorkerScript()) {
-    promise->MaybeResolveWithUndefined();
-    return promise.forget();
+  if (workerRef->Private()->LoadScriptAsPartOfLoadingServiceWorkerScript()) {
+    return ServiceWorkerRegistrationPromise::CreateAndResolve(mDescriptor,
+                                                              __func__);
+  }
+
+  // Eventually we need to support all workers, but for right now this
+  // code assumes we're on a service worker global as self.registration.
+  if (NS_WARN_IF(!workerRef->Private()->IsServiceWorker())) {
+    return ServiceWorkerRegistrationPromise::CreateAndReject(
+      NS_ERROR_DOM_INVALID_STATE_ERR, __func__);
   }
 
-  RefPtr<PromiseWorkerProxy> proxy = PromiseWorkerProxy::Create(worker, promise);
-  if (!proxy) {
-    aRv.Throw(NS_ERROR_DOM_ABORT_ERR);
-    return nullptr;
+  RefPtr<ServiceWorkerRegistrationPromise::Private> outer =
+    new ServiceWorkerRegistrationPromise::Private(__func__);
+
+  RefPtr<SWRUpdateRunnable> r =
+    new SWRUpdateRunnable(workerRef,
+                          outer,
+                          workerRef->Private()->GetServiceWorkerDescriptor());
+
+  nsresult rv = workerRef->Private()->DispatchToMainThread(r.forget());
+  if (NS_FAILED(rv)) {
+    outer->Reject(NS_ERROR_DOM_INVALID_STATE_ERR, __func__);
+    return outer.forget();
   }
 
-  RefPtr<SWRUpdateRunnable> r = new SWRUpdateRunnable(proxy);
-  MOZ_ALWAYS_SUCCEEDS(worker->DispatchToMainThread(r.forget()));
-
-  return promise.forget();
+  return outer.forget();
 }
 
 already_AddRefed<Promise>
 ServiceWorkerRegistrationWorkerThread::Unregister(ErrorResult& aRv)
 {
   WorkerPrivate* worker = GetCurrentThreadWorkerPrivate();
   MOZ_ASSERT(worker);
   worker->AssertIsOnWorkerThread();
--- a/dom/serviceworkers/ServiceWorkerRegistrationImpl.h
+++ b/dom/serviceworkers/ServiceWorkerRegistrationImpl.h
@@ -37,17 +37,17 @@ public:
 
   // ServiceWorkerRegistration::Inner
   void
   SetServiceWorkerRegistration(ServiceWorkerRegistration* aReg) override;
 
   void
   ClearServiceWorkerRegistration(ServiceWorkerRegistration* aReg) override;
 
-  already_AddRefed<Promise>
+  RefPtr<ServiceWorkerRegistrationPromise>
   Update(ErrorResult& aRv) override;
 
   already_AddRefed<Promise>
   Unregister(ErrorResult& aRv) override;
 
   already_AddRefed<Promise>
   ShowNotification(JSContext* aCx,
                    const nsAString& aTitle,
@@ -88,16 +88,17 @@ private:
 
   void
   StopListeningForEvents();
 
   void
   RegistrationRemovedInternal();
 
   ServiceWorkerRegistration* mOuter;
+  ServiceWorkerRegistrationDescriptor mDescriptor;
   const nsString mScope;
   bool mListeningForEvents;
 };
 
 ////////////////////////////////////////////////////
 // Worker Thread implementation
 
 class WorkerListener;
@@ -116,17 +117,17 @@ public:
 
   // ServiceWorkerRegistration::Inner
   void
   SetServiceWorkerRegistration(ServiceWorkerRegistration* aReg) override;
 
   void
   ClearServiceWorkerRegistration(ServiceWorkerRegistration* aReg) override;
 
-  already_AddRefed<Promise>
+  RefPtr<ServiceWorkerRegistrationPromise>
   Update(ErrorResult& aRv) override;
 
   already_AddRefed<Promise>
   Unregister(ErrorResult& aRv) override;
 
   already_AddRefed<Promise>
   ShowNotification(JSContext* aCx,
                    const nsAString& aTitle,
@@ -152,16 +153,17 @@ private:
   void
   ReleaseListener();
 
   // This can be called only by WorkerListener.
   WorkerPrivate*
   GetWorkerPrivate(const MutexAutoLock& aProofOfLock);
 
   ServiceWorkerRegistration* mOuter;
+  const ServiceWorkerRegistrationDescriptor mDescriptor;
   const nsString mScope;
   RefPtr<WorkerListener> mListener;
   RefPtr<WeakWorkerRef> mWorkerRef;
 };
 
 } // dom namespace
 } // mozilla namespace
 
--- a/dom/serviceworkers/ServiceWorkerUtils.h
+++ b/dom/serviceworkers/ServiceWorkerUtils.h
@@ -14,24 +14,20 @@ namespace mozilla {
 
 class ErrorResult;
 
 namespace dom {
 
 class ServiceWorkerRegistrationData;
 class ServiceWorkerRegistrationDescriptor;
 
-// Note: These are exclusive promise types.  Only one Then() or ChainTo()
-//       call is allowed.  This is necessary since ErrorResult cannot
-//       be copied.
-
-typedef MozPromise<ServiceWorkerRegistrationDescriptor, ErrorResult, true>
+typedef MozPromise<ServiceWorkerRegistrationDescriptor, CopyableErrorResult, false>
         ServiceWorkerRegistrationPromise;
 
-typedef MozPromise<nsTArray<ServiceWorkerRegistrationDescriptor>, ErrorResult, true>
+typedef MozPromise<nsTArray<ServiceWorkerRegistrationDescriptor>, CopyableErrorResult, false>
         ServiceWorkerRegistrationListPromise;
 
 bool
 ServiceWorkerParentInterceptEnabled();
 
 bool
 ServiceWorkerRegistrationDataIsValid(const ServiceWorkerRegistrationData& aData);
 
--- a/dom/serviceworkers/test/worker_update.js
+++ b/dom/serviceworkers/test/worker_update.js
@@ -1,14 +1,14 @@
 // For now this test only calls update to verify that our registration
 // job queueing works properly when called from the worker thread. We should
 // test actual update scenarios with a SJS test.
 onmessage = function(e) {
   self.registration.update().then(function(v) {
-    return v === undefined ? 'FINISH' : 'FAIL';
+    return v instanceof ServiceWorkerRegistration ? 'FINISH' : 'FAIL';
   }).catch(function(e) {
     return 'FAIL';
   }).then(function(result) {
     clients.matchAll().then(function(c) {
       if (c.length == 0) {
         dump("!!!!!!!!!!! WORKER HAS NO CLIENTS TO FINISH TEST !!!!!!!!!!!!\n");
         return;
       }
--- a/dom/smil/nsSMILTimedElement.cpp
+++ b/dom/smil/nsSMILTimedElement.cpp
@@ -312,17 +312,17 @@ dom::Element*
 nsSMILTimedElement::GetTargetElement()
 {
   return mAnimationElement ?
       mAnimationElement->GetTargetElementContent() :
       nullptr;
 }
 
 //----------------------------------------------------------------------
-// nsIDOMElementTimeControl methods
+// ElementTimeControl methods
 //
 // The definition of the ElementTimeControl interface differs between SMIL
 // Animation and SVG 1.1. In SMIL Animation all methods have a void return
 // type and the new instance time is simply added to the list and restart
 // semantics are applied as with any other instance time. In the SVG definition
 // the methods return a bool depending on the restart mode.
 //
 // This inconsistency has now been addressed by an erratum in SVG 1.1:
--- a/dom/smil/nsSMILTimedElement.h
+++ b/dom/smil/nsSMILTimedElement.h
@@ -58,17 +58,17 @@ public:
 
   /*
    * Returns the element targeted by the animation element. Needed for
    * registering event listeners against the appropriate element.
    */
   mozilla::dom::Element* GetTargetElement();
 
   /**
-   * Methods for supporting the nsIDOMElementTimeControl interface.
+   * Methods for supporting the ElementTimeControl interface.
    */
 
   /*
    * Adds a new begin instance time at the current container time plus or minus
    * the specified offset.
    *
    * @param aOffsetSeconds A real number specifying the number of seconds to add
    *                       to the current container time.
--- a/dom/svg/DOMSVGLength.h
+++ b/dom/svg/DOMSVGLength.h
@@ -178,17 +178,17 @@ public:
   void GetValueAsString(nsAString& aValue);
   void SetValueAsString(const nsAString& aValue, ErrorResult& aRv);
   void NewValueSpecifiedUnits(uint16_t aUnit, float aValue,
                               ErrorResult& aRv);
   void ConvertToSpecifiedUnits(uint16_t aUnit, ErrorResult& aRv);
 
   nsISupports* GetParentObject() const {
     auto svgElement = mList ? Element() : mSVGElement.get();
-    return static_cast<nsIDOMElement*>(svgElement);
+    return static_cast<nsIDOMNode*>(svgElement);
   }
 
   JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
 private:
 
   nsSVGElement* Element() const {
     return mList->Element();
--- a/dom/svg/SVGAElement.cpp
+++ b/dom/svg/SVGAElement.cpp
@@ -41,17 +41,16 @@ const DOMTokenListSupportedToken SVGAEle
   nullptr
 };
 
 //----------------------------------------------------------------------
 // nsISupports methods
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SVGAElement)
   NS_INTERFACE_MAP_ENTRY(nsIDOMNode)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMElement)
   NS_INTERFACE_MAP_ENTRY(Link)
 NS_INTERFACE_MAP_END_INHERITING(SVGAElementBase)
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED(SVGAElement,
                                    SVGAElementBase,
                                    mRelList)
 
 NS_IMPL_ADDREF_INHERITED(SVGAElement, SVGAElementBase)
--- a/dom/svg/SVGFEFloodElement.cpp
+++ b/dom/svg/SVGFEFloodElement.cpp
@@ -55,16 +55,17 @@ SVGFEFloodElement::GetPrimitiveDescripti
 
 //----------------------------------------------------------------------
 // nsIContent methods
 
 NS_IMETHODIMP_(bool)
 SVGFEFloodElement::IsAttributeMapped(const nsAtom* name) const
 {
   static const MappedAttributeEntry* const map[] = {
+    sColorMap,
     sFEFloodMap
   };
 
   return FindAttributeDependence(name, map) ||
     SVGFEFloodElementBase::IsAttributeMapped(name);
 }
 
 //----------------------------------------------------------------------
--- a/dom/svg/SVGFEImageElement.cpp
+++ b/dom/svg/SVGFEImageElement.cpp
@@ -38,17 +38,17 @@ nsSVGElement::StringInfo SVGFEImageEleme
   { &nsGkAtoms::href, kNameSpaceID_None, true },
   { &nsGkAtoms::href, kNameSpaceID_XLink, true }
 };
 
 //----------------------------------------------------------------------
 // nsISupports methods
 
 NS_IMPL_ISUPPORTS_INHERITED(SVGFEImageElement, SVGFEImageElementBase,
-                            nsIDOMNode, nsIDOMElement,
+                            nsIDOMNode,
                             imgINotificationObserver, nsIImageLoadingContent)
 
 //----------------------------------------------------------------------
 // Implementation
 
 SVGFEImageElement::SVGFEImageElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
   : SVGFEImageElementBase(aNodeInfo)
 {
--- a/dom/svg/SVGFilterElement.cpp
+++ b/dom/svg/SVGFilterElement.cpp
@@ -116,16 +116,17 @@ SVGFilterElement::Href()
 
 //----------------------------------------------------------------------
 // nsIContent methods
 
 NS_IMETHODIMP_(bool)
 SVGFilterElement::IsAttributeMapped(const nsAtom* name) const
 {
   static const MappedAttributeEntry* const map[] = {
+    sColorMap,
     sFEFloodMap,
     sFiltersMap,
     sFontSpecificationMap,
     sGradientStopMap,
     sLightingEffectsMap,
     sMarkersMap,
     sTextContentElementsMap,
     sViewportsMap
--- a/dom/svg/SVGImageElement.cpp
+++ b/dom/svg/SVGImageElement.cpp
@@ -44,17 +44,17 @@ nsSVGElement::StringInfo SVGImageElement
   { &nsGkAtoms::href, kNameSpaceID_None, true },
   { &nsGkAtoms::href, kNameSpaceID_XLink, true }
 };
 
 //----------------------------------------------------------------------
 // nsISupports methods
 
 NS_IMPL_ISUPPORTS_INHERITED(SVGImageElement, SVGImageElementBase,
-                            nsIDOMNode, nsIDOMElement,
+                            nsIDOMNode,
                             imgINotificationObserver,
                             nsIImageLoadingContent)
 
 //----------------------------------------------------------------------
 // Implementation
 
 SVGImageElement::SVGImageElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
   : SVGImageElementBase(aNodeInfo)
--- a/dom/svg/SVGMPathElement.cpp
+++ b/dom/svg/SVGMPathElement.cpp
@@ -45,17 +45,16 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 //----------------------------------------------------------------------
 // nsISupports methods
 
 NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED(SVGMPathElement,
                                              SVGMPathElementBase,
                                              nsIDOMNode,
-                                             nsIDOMElement,
                                              nsIMutationObserver)
 
 // Constructor
 SVGMPathElement::SVGMPathElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
   : SVGMPathElementBase(aNodeInfo)
   , mPathTracker(this)
 {
 }
--- a/dom/svg/SVGSVGElement.cpp
+++ b/dom/svg/SVGSVGElement.cpp
@@ -67,17 +67,17 @@ DOMSVGPoint*
 DOMSVGTranslatePoint::Copy()
 {
   return new DOMSVGPoint(mPt.GetX(), mPt.GetY());
 }
 
 nsISupports*
 DOMSVGTranslatePoint::GetParentObject()
 {
-  return static_cast<nsIDOMElement*>(mElement);
+  return static_cast<nsIDOMNode*>(mElement);
 }
 
 void
 DOMSVGTranslatePoint::SetX(float aValue, ErrorResult& rv)
 {
   mElement->SetCurrentTranslate(aValue, mPt.GetY());
 }
 
@@ -120,18 +120,17 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
                                                   SVGSVGElementBase)
   if (tmp->mTimedDocumentRoot) {
     tmp->mTimedDocumentRoot->Traverse(&cb);
   }
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED(SVGSVGElement,
                                              SVGSVGElementBase,
-                                             nsIDOMNode,
-                                             nsIDOMElement)
+                                             nsIDOMNode)
 
 SVGView::SVGView()
 {
   mZoomAndPan.Init(SVGSVGElement::ZOOMANDPAN,
                    SVG_ZOOMANDPAN_MAGNIFY);
   mViewBox.Init();
   mPreserveAspectRatio.Init();
 }
--- a/dom/svg/SVGScriptElement.cpp
+++ b/dom/svg/SVGScriptElement.cpp
@@ -27,17 +27,17 @@ nsSVGElement::StringInfo SVGScriptElemen
   { &nsGkAtoms::href, kNameSpaceID_None, false },
   { &nsGkAtoms::href, kNameSpaceID_XLink, false }
 };
 
 //----------------------------------------------------------------------
 // nsISupports methods
 
 NS_IMPL_ISUPPORTS_INHERITED(SVGScriptElement, SVGScriptElementBase,
-                            nsIDOMNode, nsIDOMElement,
+                            nsIDOMNode,
                             nsIScriptLoaderObserver,
                             nsIScriptElement, nsIMutationObserver)
 
 //----------------------------------------------------------------------
 // Implementation
 
 SVGScriptElement::SVGScriptElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
                                    FromParser aFromParser)
--- a/dom/svg/SVGSymbolElement.cpp
+++ b/dom/svg/SVGSymbolElement.cpp
@@ -17,17 +17,17 @@ SVGSymbolElement::WrapNode(JSContext *aC
 {
   return SVGSymbolElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 //----------------------------------------------------------------------
 // nsISupports methods
 
 NS_IMPL_ISUPPORTS_INHERITED(SVGSymbolElement, SVGSymbolElementBase,
-                            nsIDOMNode, nsIDOMElement,
+                            nsIDOMNode,
                             mozilla::dom::SVGTests)
 
 //----------------------------------------------------------------------
 // Implementation
 
 SVGSymbolElement::SVGSymbolElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
   : SVGSymbolElementBase(aNodeInfo)
 {
--- a/dom/svg/SVGTitleElement.cpp
+++ b/dom/svg/SVGTitleElement.cpp
@@ -17,17 +17,17 @@ SVGTitleElement::WrapNode(JSContext *aCx
 {
   return SVGTitleElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 //----------------------------------------------------------------------
 // nsISupports methods
 
 NS_IMPL_ISUPPORTS_INHERITED(SVGTitleElement, SVGTitleElementBase,
-                            nsIDOMNode, nsIDOMElement,
+                            nsIDOMNode,
                             nsIMutationObserver)
 
 //----------------------------------------------------------------------
 // Implementation
 
 SVGTitleElement::SVGTitleElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
   : SVGTitleElementBase(aNodeInfo)
 {
--- a/dom/svg/nsSVGElement.cpp
+++ b/dom/svg/nsSVGElement.cpp
@@ -227,17 +227,17 @@ nsSVGElement::Init()
 
   return NS_OK;
 }
 
 //----------------------------------------------------------------------
 // nsISupports methods
 
 NS_IMPL_ISUPPORTS_INHERITED(nsSVGElement, nsSVGElementBase,
-                            nsIDOMNode, nsIDOMElement)
+                            nsIDOMNode)
 
 //----------------------------------------------------------------------
 // Implementation
 
 //----------------------------------------------------------------------
 // nsIContent methods
 
 nsresult
@@ -1055,17 +1055,17 @@ nsSVGElement::sLightingEffectsMap[] = {
 // PresentationAttributes-mask
 /* static */ const Element::MappedAttributeEntry
 nsSVGElement::sMaskMap[] = {
   { &nsGkAtoms::mask_type },
   { nullptr }
 };
 
 //----------------------------------------------------------------------
-// nsIDOMElement methods
+// Element methods
 
 // forwarded to Element implementations
 
 
 //----------------------------------------------------------------------
 
 SVGSVGElement*
 nsSVGElement::GetOwnerSVGElement()
@@ -2400,17 +2400,17 @@ nsSVGElement::GetStringListInfo()
 }
 
 nsAttrValue
 nsSVGElement::WillChangeStringList(bool aIsConditionalProcessingAttribute,
                                    uint8_t aAttrEnum)
 {
   nsAtom* name;
   if (aIsConditionalProcessingAttribute) {
-    nsCOMPtr<SVGTests> tests(do_QueryInterface(static_cast<nsIDOMElement*>(this)));
+    nsCOMPtr<SVGTests> tests(do_QueryInterface(static_cast<nsIDOMNode*>(this)));
     name = tests->GetAttrName(aAttrEnum);
   } else {
     name = *GetStringListInfo().mStringListInfo[aAttrEnum].mName;
   }
   return WillChangeValue(name);
 }
 
 void
--- a/dom/svg/nsSVGElement.h
+++ b/dom/svg/nsSVGElement.h
@@ -19,17 +19,17 @@
 #include "nsCycleCollectionParticipant.h"
 #include "nsError.h"
 #include "mozilla/dom/DOMRect.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/gfx/MatrixFwd.h"
 #include "nsISupportsImpl.h"
 #include "nsStyledElement.h"
 #include "nsSVGClass.h"
-#include "nsIDOMElement.h"
+#include "nsIDOMNode.h"
 #include "SVGContentUtils.h"
 #include "gfxMatrix.h"
 
 class nsSVGAngle;
 class nsSVGBoolean;
 class nsSVGEnum;
 class nsSVGInteger;
 class nsSVGIntegerPair;
@@ -61,17 +61,17 @@ class DOMSVGStringList;
 
 } // namespace mozilla
 
 struct nsSVGEnumMapping;
 
 typedef nsStyledElement nsSVGElementBase;
 
 class nsSVGElement : public nsSVGElementBase    // nsIContent
-                   , public nsIDOMElement
+                   , public nsIDOMNode
 {
 protected:
   explicit nsSVGElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
   friend nsresult NS_NewSVGElement(mozilla::dom::Element **aResult,
                                    already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   nsresult Init();
   virtual ~nsSVGElement();
 
@@ -123,18 +123,16 @@ public:
   static const MappedAttributeEntry sViewportsMap[];
   static const MappedAttributeEntry sMarkersMap[];
   static const MappedAttributeEntry sColorMap[];
   static const MappedAttributeEntry sFiltersMap[];
   static const MappedAttributeEntry sFEFloodMap[];
   static const MappedAttributeEntry sLightingEffectsMap[];
   static const MappedAttributeEntry sMaskMap[];
 
-  NS_DECL_NSIDOMELEMENT
-
   NS_IMPL_FROMNODE(nsSVGElement, kNameSpaceID_SVG)
 
   // Gets the element that establishes the rectangular viewport against which
   // we should resolve percentage lengths (our "coordinate context"). Returns
   // nullptr for outer <svg> or SVG without an <svg> parent (invalid SVG).
   mozilla::dom::SVGViewportElement* GetCtx() const;
 
   /**
--- a/dom/svg/nsSVGFilters.cpp
+++ b/dom/svg/nsSVGFilters.cpp
@@ -456,16 +456,17 @@ nsSVGElement::StringInfo nsSVGFELighting
 
 //----------------------------------------------------------------------
 // Implementation
 
 NS_IMETHODIMP_(bool)
 nsSVGFELightingElement::IsAttributeMapped(const nsAtom* name) const
 {
   static const MappedAttributeEntry* const map[] = {
+    sColorMap,
     sLightingEffectsMap
   };
 
   return FindAttributeDependence(name, map) ||
     nsSVGFELightingElementBase::IsAttributeMapped(name);
 }
 
 void
--- a/dom/svg/nsSVGFilters.h
+++ b/dom/svg/nsSVGFilters.h
@@ -185,18 +185,16 @@ public:
   // interfaces:
   NS_INLINE_DECL_REFCOUNTING_INHERITED(nsSVGFELightingElement,
                                        nsSVGFELightingElementBase)
 
   virtual bool AttributeAffectsRendering(
           int32_t aNameSpaceID, nsAtom* aAttribute) const override;
   virtual nsSVGString& GetResultImageName() override { return mStringAttributes[RESULT]; }
   virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources) override;
-  NS_FORWARD_NSIDOMELEMENT(nsSVGFELightingElementBase::)
-
   NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
 
 protected:
   virtual bool OperatesOnSRGB(int32_t aInputIndex,
                               bool aInputIsAlreadySRGB) override { return true; }
 
   virtual NumberAttributesInfo GetNumberInfo() override;
   virtual NumberPairAttributesInfo GetNumberPairInfo() override;
--- a/dom/tests/mochitest/general/test_domWindowUtils.html
+++ b/dom/tests/mochitest/general/test_domWindowUtils.html
@@ -27,20 +27,20 @@
 <script type="application/javascript">
 
 SimpleTest.waitForExplicitFinish();
 
 var domWindowUtils = SpecialPowers.getDOMWindowUtils(window);
 
 var gTests = [
 /*
-  nsIDOMElement elementFromPoint(in long aX,
-                                 in long aY,
-                                 in boolean aIgnoreRootScrollFrame,
-                                 in boolean aFlushLayout);
+  Element elementFromPoint(in long aX,
+                           in long aY,
+                           in boolean aIgnoreRootScrollFrame,
+                           in boolean aFlushLayout);
 */
 async function testElementFromPoint() {
   let onscreen = document.getElementById("onscreen");
   let offscreen = document.getElementById("offscreen");
   let htmldoc = document.documentElement;
   ok(onscreen, "on screen element exists");
   ok(offscreen, "off screen element exists");
   ok(htmldoc, "htmldoc element exists");
--- a/dom/xbl/XBLChildrenElement.cpp
+++ b/dom/xbl/XBLChildrenElement.cpp
@@ -13,18 +13,17 @@ namespace mozilla {
 namespace dom {
 
 XBLChildrenElement::~XBLChildrenElement()
 {
 }
 
 NS_IMPL_ISUPPORTS_INHERITED(XBLChildrenElement,
                             Element,
-                            nsIDOMNode,
-                            nsIDOMElement)
+                            nsIDOMNode)
 
 NS_IMPL_ELEMENT_CLONE(XBLChildrenElement)
 
 nsresult
 XBLChildrenElement::BeforeSetAttr(int32_t aNamespaceID, nsAtom* aName,
                                   const nsAttrValueOrString* aValue,
                                   bool aNotify)
 {
--- a/dom/xbl/XBLChildrenElement.h
+++ b/dom/xbl/XBLChildrenElement.h
@@ -2,17 +2,17 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsXBLChildrenElement_h___
 #define nsXBLChildrenElement_h___
 
-#include "nsIDOMElement.h"
+#include "nsIDOMNode.h"
 #include "nsINodeList.h"
 #include "nsBindingManager.h"
 #include "mozilla/dom/nsXMLElement.h"
 
 class nsAnonymousContentList;
 
 namespace mozilla {
 namespace dom {
--- a/dom/xbl/nsBindingManager.cpp
+++ b/dom/xbl/nsBindingManager.cpp
@@ -12,17 +12,16 @@
 #include "nsIInputStream.h"
 #include "nsIURI.h"
 #include "nsIURL.h"
 #include "nsIChannel.h"
 #include "nsString.h"
 #include "plstr.h"
 #include "nsIContent.h"
 #include "nsIContentInlines.h"
-#include "nsIDOMElement.h"
 #include "nsIDocument.h"
 #include "nsContentUtils.h"
 #include "nsIPresShell.h"
 #include "nsIPresShellInlines.h"
 #include "nsIXMLContentSink.h"
 #include "nsContentCID.h"
 #include "mozilla/dom/XMLDocument.h"
 #include "nsIStreamListener.h"
--- a/dom/xbl/nsXBLService.cpp
+++ b/dom/xbl/nsXBLService.cpp
@@ -9,17 +9,16 @@
 
 #include "nsCOMPtr.h"
 #include "nsNetUtil.h"
 #include "nsXBLService.h"
 #include "nsXBLWindowKeyHandler.h"
 #include "nsIInputStream.h"
 #include "nsNameSpaceManager.h"
 #include "nsIURI.h"
-#include "nsIDOMElement.h"
 #include "nsIURL.h"
 #include "nsIChannel.h"
 #include "nsString.h"
 #include "plstr.h"
 #include "nsIContent.h"
 #include "nsIDocument.h"
 #include "nsIXMLContentSink.h"
 #include "nsContentCID.h"
@@ -611,17 +610,18 @@ nsXBLService::AttachGlobalKeyHandler(Eve
   EventListenerManager* manager = piTarget->GetOrCreateListenerManager();
   if (!manager)
     return NS_ERROR_FAILURE;
 
   // the listener already exists, so skip this
   if (contentNode && contentNode->GetProperty(nsGkAtoms::listener))
     return NS_OK;
 
-  nsCOMPtr<nsIDOMElement> elt(do_QueryInterface(contentNode));
+  Element* elt =
+   contentNode && contentNode->IsElement() ? contentNode->AsElement() : nullptr;
 
   // Create the key handler
   RefPtr<nsXBLWindowKeyHandler> handler =
     NS_NewXBLWindowKeyHandler(elt, piTarget);
 
   handler->InstallKeyboardEventListenersTo(manager);
 
   if (contentNode)
--- a/dom/xbl/nsXBLWindowKeyHandler.cpp
+++ b/dom/xbl/nsXBLWindowKeyHandler.cpp
@@ -8,17 +8,16 @@
 #include "nsXBLPrototypeHandler.h"
 #include "nsXBLWindowKeyHandler.h"
 #include "nsIContent.h"
 #include "nsAtom.h"
 #include "nsXBLService.h"
 #include "nsIServiceManager.h"
 #include "nsGkAtoms.h"
 #include "nsXBLDocumentInfo.h"
-#include "nsIDOMElement.h"
 #include "nsFocusManager.h"
 #include "nsIURI.h"
 #include "nsNetUtil.h"
 #include "nsContentUtils.h"
 #include "nsXBLPrototypeBinding.h"
 #include "nsPIDOMWindow.h"
 #include "nsIDocShell.h"
 #include "nsIDOMDocument.h"
@@ -157,17 +156,17 @@ uint32_t nsXBLWindowKeyHandler::sRefCnt 
 nsXBLWindowKeyHandler::EnsureSpecialDocInfo()
 {
   if (!sXBLSpecialDocInfo) {
     sXBLSpecialDocInfo = new nsXBLSpecialDocInfo();
   }
   sXBLSpecialDocInfo->LoadDocInfo();
 }
 
-nsXBLWindowKeyHandler::nsXBLWindowKeyHandler(nsIDOMElement* aElement,
+nsXBLWindowKeyHandler::nsXBLWindowKeyHandler(Element* aElement,
                                              EventTarget* aTarget)
   : mTarget(aTarget),
     mHandler(nullptr),
     mUserHandler(nullptr)
 {
   mWeakPtrForElement = do_GetWeakReference(aElement);
   ++sRefCnt;
 }
@@ -586,17 +585,17 @@ nsXBLWindowKeyHandler::HandleEventOnCapt
   // DOM tree again.
   widgetEvent->StopImmediatePropagation();
   widgetEvent->MarkAsWaitingReplyFromRemoteProcess();
 }
 
 bool
 nsXBLWindowKeyHandler::IsHTMLEditableFieldFocused()
 {
-  nsIFocusManager* fm = nsFocusManager::GetFocusManager();
+  nsFocusManager* fm = nsFocusManager::GetFocusManager();
   if (!fm)
     return false;
 
   nsCOMPtr<mozIDOMWindowProxy> focusedWindow;
   fm->GetFocusedWindow(getter_AddRefs(focusedWindow));
   if (!focusedWindow)
     return false;
 
@@ -612,20 +611,18 @@ nsXBLWindowKeyHandler::IsHTMLEditableFie
   }
 
   nsCOMPtr<nsIDocument> doc = htmlEditor->GetDocument();
   if (doc->HasFlag(NODE_IS_EDITABLE)) {
     // Don't need to perform any checks in designMode documents.
     return true;
   }
 
-  nsCOMPtr<nsIDOMElement> focusedElement;
-  fm->GetFocusedElement(getter_AddRefs(focusedElement));
-  nsCOMPtr<nsINode> focusedNode = do_QueryInterface(focusedElement);
-  if (focusedNode) {
+  nsINode* focusedNode = fm->GetFocusedElement();
+  if (focusedNode && focusedNode->IsElement()) {
     // If there is a focused element, make sure it's in the active editing host.
     // Note that GetActiveEditingHost finds the current editing host based on
     // the document's selection.  Even though the document selection is usually
     // collapsed to where the focus is, but the page may modify the selection
     // without our knowledge, in which case this check will do something useful.
     nsCOMPtr<Element> activeEditingHost = htmlEditor->GetActiveEditingHost();
     if (!activeEditingHost) {
       return false;
@@ -950,14 +947,14 @@ nsXBLWindowKeyHandler::IsExecutableEleme
   }
 
   return true;
 }
 
 ///////////////////////////////////////////////////////////////////////////////////
 
 already_AddRefed<nsXBLWindowKeyHandler>
-NS_NewXBLWindowKeyHandler(nsIDOMElement* aElement, EventTarget* aTarget)
+NS_NewXBLWindowKeyHandler(Element* aElement, EventTarget* aTarget)
 {
   RefPtr<nsXBLWindowKeyHandler> result =
     new nsXBLWindowKeyHandler(aElement, aTarget);
   return result.forget();
 }
--- a/dom/xbl/nsXBLWindowKeyHandler.h
+++ b/dom/xbl/nsXBLWindowKeyHandler.h
@@ -8,17 +8,16 @@
 #define nsXBLWindowKeyHandler_h__
 
 #include "mozilla/EventForwards.h"
 #include "mozilla/layers/KeyboardMap.h"
 #include "nsWeakPtr.h"
 #include "nsIDOMEventListener.h"
 
 class nsAtom;
-class nsIDOMElement;
 class nsXBLPrototypeHandler;
 
 namespace mozilla {
 class EventListenerManager;
 class WidgetKeyboardEvent;
 struct IgnoreModifierState;
 namespace dom {
 class Element;
@@ -30,17 +29,18 @@ class KeyboardEvent;
 class nsXBLWindowKeyHandler : public nsIDOMEventListener
 {
   typedef mozilla::EventListenerManager EventListenerManager;
   typedef mozilla::IgnoreModifierState IgnoreModifierState;
   typedef mozilla::layers::KeyboardMap KeyboardMap;
   typedef mozilla::dom::KeyboardEvent KeyboardEvent;
 
 public:
-  nsXBLWindowKeyHandler(nsIDOMElement* aElement, mozilla::dom::EventTarget* aTarget);
+  nsXBLWindowKeyHandler(mozilla::dom::Element* aElement,
+                        mozilla::dom::EventTarget* aTarget);
 
   void InstallKeyboardEventListenersTo(
          EventListenerManager* aEventListenerManager);
   void RemoveKeyboardEventListenersFrom(
          EventListenerManager* aEventListenerManager);
 
   static KeyboardMap CollectKeyboardShortcuts();
 
@@ -133,12 +133,12 @@ protected:
   nsXBLPrototypeHandler* mHandler;     // platform bindings
   nsXBLPrototypeHandler* mUserHandler; // user-specific bindings
 
   // holds reference count to document info about bindings
   static uint32_t sRefCnt;
 };
 
 already_AddRefed<nsXBLWindowKeyHandler>
-NS_NewXBLWindowKeyHandler(nsIDOMElement* aElement,
+NS_NewXBLWindowKeyHandler(mozilla::dom::Element* aElement,
                           mozilla::dom::EventTarget* aTarget);
 
 #endif
--- a/dom/xml/XMLDocument.cpp
+++ b/dom/xml/XMLDocument.cpp
@@ -10,17 +10,16 @@
 #include "nsCharsetSource.h"
 #include "nsIXMLContentSink.h"
 #include "nsPresContext.h"
 #include "nsIContent.h"
 #include "nsIContentViewer.h"
 #include "nsIDocShell.h"
 #include "nsHTMLParts.h"
 #include "nsIComponentManager.h"
-#include "nsIDOMElement.h"
 #include "nsIBaseWindow.h"
 #include "nsIDOMWindow.h"
 #include "nsCOMPtr.h"
 #include "nsString.h"
 #include "nsIHttpChannelInternal.h"
 #include "nsIURI.h"
 #include "nsIServiceManager.h"
 #include "nsNetUtil.h"
--- a/dom/xml/nsXMLElement.cpp
+++ b/dom/xml/nsXMLElement.cpp
@@ -17,17 +17,17 @@ NS_NewXMLElement(Element** aInstancePtrR
                  already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
 {
   nsXMLElement* it = new nsXMLElement(aNodeInfo);
   NS_ADDREF(*aInstancePtrResult = it);
   return NS_OK;
 }
 
 NS_IMPL_ISUPPORTS_INHERITED(nsXMLElement, Element,
-                            nsIDOMNode, nsIDOMElement)
+                            nsIDOMNode)
 
 JSObject*
 nsXMLElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
   return ElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 void
--- a/dom/xml/nsXMLElement.h
+++ b/dom/xml/nsXMLElement.h
@@ -3,22 +3,22 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsXMLElement_h___
 #define nsXMLElement_h___
 
 #include "mozilla/Attributes.h"
-#include "nsIDOMElement.h"
+#include "nsIDOMNode.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/DOMRect.h"
 
 class nsXMLElement : public mozilla::dom::Element,
-                     public nsIDOMElement
+                     public nsIDOMNode
 {
 public:
   explicit nsXMLElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
     : mozilla::dom::Element(aNodeInfo)
   {
   }
 
   // nsISupports
--- a/dom/xml/nsXMLPrettyPrinter.cpp
+++ b/dom/xml/nsXMLPrettyPrinter.cpp
@@ -4,17 +4,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsXMLPrettyPrinter.h"
 #include "nsContentUtils.h"
 #include "nsICSSDeclaration.h"
 #include "nsIObserver.h"
 #include "nsSyncLoadService.h"
 #include "nsPIDOMWindow.h"
-#include "nsIDOMElement.h"
 #include "nsIServiceManager.h"
 #include "nsNetUtil.h"
 #include "mozilla/dom/Element.h"
 #include "nsBindingManager.h"
 #include "nsXBLService.h"
 #include "nsIScriptSecurityManager.h"
 #include "mozilla/Preferences.h"
 #include "nsIDocument.h"
--- a/dom/xslt/xpath/txMozillaXPathTreeWalker.cpp
+++ b/dom/xslt/xpath/txMozillaXPathTreeWalker.cpp
@@ -2,17 +2,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "txXPathTreeWalker.h"
 #include "nsAtom.h"
 #include "nsIAttribute.h"
 #include "nsIDOMDocument.h"
-#include "nsIDOMElement.h"
 #include "nsINode.h"
 #include "nsPrintfCString.h"
 #include "nsReadableUtils.h"
 #include "nsString.h"
 #include "nsTextFragment.h"
 #include "txXMLUtils.h"
 #include "txLog.h"
 #include "nsUnicharUtils.h"
--- a/dom/xslt/xslt/txMozillaXSLTProcessor.cpp
+++ b/dom/xslt/xslt/txMozillaXSLTProcessor.cpp
@@ -3,17 +3,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "txMozillaXSLTProcessor.h"
 #include "nsContentCID.h"
 #include "nsError.h"
 #include "nsIChannel.h"
 #include "mozilla/dom/Element.h"
-#include "nsIDOMElement.h"
 #include "nsIDocument.h"
 #include "nsIDOMDocument.h"
 #include "nsIIOService.h"
 #include "nsILoadGroup.h"
 #include "nsIStringBundle.h"
 #include "nsIURI.h"
 #include "nsMemory.h"
 #include "XPathResult.h"
--- a/dom/xul/XULDocument.cpp
+++ b/dom/xul/XULDocument.cpp
@@ -1522,22 +1522,17 @@ XULDocument::RemoveSubtreeFromDocument(n
         nsAutoScriptBlocker scriptBlocker;
         RemoveFromIdTable(aElement, id);
     }
 
     // 3. If the element is a 'command updater', then remove the
     // element from the document's command dispatcher.
     if (aElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::commandupdater,
                               nsGkAtoms::_true, eCaseMatters)) {
-        nsCOMPtr<nsIDOMElement> domelement = do_QueryInterface(aElement);
-        NS_ASSERTION(domelement != nullptr, "not a DOM element");
-        if (! domelement)
-            return NS_ERROR_UNEXPECTED;
-
-        rv = mCommandDispatcher->RemoveCommandUpdater(domelement);
+        rv = mCommandDispatcher->RemoveCommandUpdater(aElement);
         if (NS_FAILED(rv)) return rv;
     }
 
     // 4. Remove the element from our broadcaster map, since it is no longer
     // in the document.
     nsCOMPtr<Element> broadcaster, listener;
     nsAutoString attribute, broadcasterID;
     rv = FindBroadcaster(aElement, getter_AddRefs(listener),
--- a/dom/xul/nsXULCommandDispatcher.cpp
+++ b/dom/xul/nsXULCommandDispatcher.cpp
@@ -9,17 +9,16 @@
   This file provides the implementation for the XUL Command Dispatcher.
 
  */
 
 #include "nsIContent.h"
 #include "nsFocusManager.h"
 #include "nsIControllers.h"
 #include "nsIDOMDocument.h"
-#include "nsIDOMElement.h"
 #include "nsIDOMWindow.h"
 #include "nsIDocument.h"
 #include "nsPresContext.h"
 #include "nsIPresShell.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsPIDOMWindow.h"
 #include "nsPIWindowRoot.h"
 #include "nsRDFCID.h"
@@ -235,17 +234,17 @@ nsXULCommandDispatcher::AdvanceFocusInto
   nsIFocusManager* fm = nsFocusManager::GetFocusManager();
   if (fm)
     return fm->MoveFocus(win, aElt, nsIFocusManager::MOVEFOCUS_FORWARD,
                          0, getter_AddRefs(result));
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXULCommandDispatcher::AddCommandUpdater(nsIDOMElement* aElement,
+nsXULCommandDispatcher::AddCommandUpdater(Element* aElement,
                                           const nsAString& aEvents,
                                           const nsAString& aTargets)
 {
   NS_PRECONDITION(aElement != nullptr, "null ptr");
   if (! aElement)
     return NS_ERROR_NULL_POINTER;
 
   NS_ENSURE_TRUE(mDocument, NS_ERROR_UNEXPECTED);
@@ -305,17 +304,17 @@ nsXULCommandDispatcher::AddCommandUpdate
 #endif
 
   // If we get here, this is a new updater. Append it to the list.
   *link = new Updater(aElement, aEvents, aTargets);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXULCommandDispatcher::RemoveCommandUpdater(nsIDOMElement* aElement)
+nsXULCommandDispatcher::RemoveCommandUpdater(Element* aElement)
 {
   NS_PRECONDITION(aElement != nullptr, "null ptr");
   if (! aElement)
     return NS_ERROR_NULL_POINTER;
 
   Updater* updater = mUpdaters;
   Updater** link = &mUpdaters;
 
--- a/dom/xul/nsXULCommandDispatcher.h
+++ b/dom/xul/nsXULCommandDispatcher.h
@@ -14,18 +14,18 @@
 #define nsXULCommandDispatcher_h__
 
 #include "nsCOMPtr.h"
 #include "nsIDOMXULCommandDispatcher.h"
 #include "nsWeakReference.h"
 #include "nsIDOMNode.h"
 #include "nsString.h"
 #include "nsCycleCollectionParticipant.h"
+#include "mozilla/RefPtr.h"
 
-class nsIDOMElement;
 class nsPIWindowRoot;
 
 namespace mozilla {
 namespace dom {
 class Element;
 } // namespace dom
 } // namespace mozilla
 
@@ -51,26 +51,26 @@ protected:
 
     mozilla::dom::Element*
       GetRootFocusedContentAndWindow(nsPIDOMWindowOuter** aWindow);
 
     nsCOMPtr<nsIDocument> mDocument;
 
     class Updater {
     public:
-      Updater(nsIDOMElement* aElement,
+      Updater(mozilla::dom::Element* aElement,
               const nsAString& aEvents,
               const nsAString& aTargets)
           : mElement(aElement),
             mEvents(aEvents),
             mTargets(aTargets),
             mNext(nullptr)
       {}
 
-      nsCOMPtr<nsIDOMElement> mElement;
+      RefPtr<mozilla::dom::Element> mElement;
       nsString                mEvents;
       nsString                mTargets;
       Updater*                mNext;
     };
 
     Updater* mUpdaters;
 
     bool Matches(const nsString& aList,
--- a/dom/xul/nsXULContentUtils.cpp
+++ b/dom/xul/nsXULContentUtils.cpp
@@ -13,17 +13,16 @@
 
 #include "mozilla/ArrayUtils.h"
 
 #include "nsCollationCID.h"
 #include "nsCOMPtr.h"
 #include "nsIContent.h"
 #include "nsICollation.h"
 #include "nsIDocument.h"
-#include "nsIDOMElement.h"
 #include "nsIDOMXULCommandDispatcher.h"
 #include "nsIRDFService.h"
 #include "nsIServiceManager.h"
 #include "nsXULContentUtils.h"
 #include "nsLayoutCID.h"
 #include "nsRDFCID.h"
 #include "nsString.h"
 #include "nsGkAtoms.h"
@@ -138,19 +137,14 @@ nsXULContentUtils::SetCommandUpdater(nsI
         events.Assign('*');
 
     nsAutoString targets;
     aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::targets, targets);
 
     if (targets.IsEmpty())
         targets.Assign('*');
 
-    nsCOMPtr<nsIDOMElement> domelement = do_QueryInterface(aElement);
-    NS_ASSERTION(domelement != nullptr, "not a DOM element");
-    if (! domelement)
-        return NS_ERROR_UNEXPECTED;
-
-    rv = dispatcher->AddCommandUpdater(domelement, events, targets);
+    rv = dispatcher->AddCommandUpdater(aElement, events, targets);
     if (NS_FAILED(rv)) return rv;
 
     return NS_OK;
 }
 
--- a/dom/xul/nsXULControllers.cpp
+++ b/dom/xul/nsXULControllers.cpp
@@ -8,17 +8,16 @@
   This file provides the implementation for the XUL "controllers"
   object.
 
 */
 
 #include "nsString.h"
 
 #include "nsIControllers.h"
-#include "nsIDOMElement.h"
 #include "nsXULControllers.h"
 #include "nsIController.h"
 
 //----------------------------------------------------------------------
 
 nsXULControllers::nsXULControllers()
 : mCurControllerID(0)
 {
--- a/dom/xul/nsXULElement.cpp
+++ b/dom/xul/nsXULElement.cpp
@@ -5,17 +5,16 @@
 
 #include "nsCOMPtr.h"
 #include "nsDOMCID.h"
 #include "nsError.h"
 #include "nsDOMString.h"
 #include "nsAtom.h"
 #include "nsIBaseWindow.h"
 #include "nsIDOMDocument.h"
-#include "nsIDOMElement.h"
 #include "nsIDOMEventListener.h"
 #include "nsIDOMXULCommandDispatcher.h"
 #include "nsIDOMXULSelectCntrlItemEl.h"
 #include "nsIDocument.h"
 #include "mozilla/AsyncEventDispatcher.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/EventListenerManager.h"
 #include "mozilla/EventStateManager.h"
@@ -286,17 +285,17 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_IN
     // Why aren't we unlinking the prototype?
     tmp->ClearHasID();
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_ADDREF_INHERITED(nsXULElement, nsStyledElement)
 NS_IMPL_RELEASE_INHERITED(nsXULElement, nsStyledElement)
 
 NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsXULElement)
-    NS_INTERFACE_TABLE_INHERITED(nsXULElement, nsIDOMNode, nsIDOMElement)
+    NS_INTERFACE_TABLE_INHERITED(nsXULElement, nsIDOMNode)
     NS_ELEMENT_INTERFACE_TABLE_TO_MAP_SEGUE
     NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIFrameLoaderOwner,
                                    new nsXULElementTearoff(this))
 NS_INTERFACE_MAP_END_INHERITING(nsStyledElement)
 
 //----------------------------------------------------------------------
 // nsIDOMNode interface
 
@@ -593,17 +592,17 @@ nsXULElement::PerformAccesskey(bool aKey
             } else {
               elementToFocus = content;
             }
             if (elementToFocus) {
               fm->SetFocus(elementToFocus, nsIFocusManager::FLAG_BYKEY);
 
               // Return true if the element became focused.
               nsPIDOMWindowOuter* window = OwnerDoc()->GetWindow();
-              focused = (window && window->GetFocusedNode());
+              focused = (window && window->GetFocusedElement());
             }
           }
         }
         if (aKeyCausesActivation &&
             !content->IsAnyOfXULElements(nsGkAtoms::textbox, nsGkAtoms::menulist)) {
           elm->ClickWithInputSource(MouseEventBinding::MOZ_SOURCE_KEYBOARD, aIsTrustedEvent);
         }
     } else {
@@ -828,44 +827,42 @@ nsXULElement::RemoveChildAt_Deprecated(u
       controlElement = do_QueryObject(this);
 
       // If it's not, look at our parent
       if (!controlElement)
         GetParentTree(getter_AddRefs(controlElement));
       nsCOMPtr<nsIContent> controlContent(do_QueryInterface(controlElement));
       RefPtr<nsXULElement> xulElement = FromNodeOrNull(controlContent);
 
-      nsCOMPtr<nsIDOMElement> oldKidElem = do_QueryInterface(oldKid);
-      if (xulElement && oldKidElem) {
+      if (xulElement) {
         // Iterate over all of the items and find out if they are contained inside
         // the removed subtree.
         int32_t length;
         controlElement->GetSelectedCount(&length);
         for (int32_t i = 0; i < length; i++) {
-          nsCOMPtr<nsIDOMXULSelectControlItemElement> node;
-          controlElement->MultiGetSelectedItem(i, getter_AddRefs(node));
-          // we need to QI here to do an XPCOM-correct pointercompare
-          nsCOMPtr<nsIDOMElement> selElem = do_QueryInterface(node);
-          if (selElem == oldKidElem &&
-              NS_SUCCEEDED(controlElement->RemoveItemFromSelection(node))) {
+          nsCOMPtr<nsIDOMXULSelectControlItemElement> item;
+          controlElement->MultiGetSelectedItem(i, getter_AddRefs(item));
+          nsCOMPtr<nsINode> node = do_QueryInterface(item);
+          if (node == oldKid &&
+              NS_SUCCEEDED(controlElement->RemoveItemFromSelection(item))) {
             length--;
             i--;
             fireSelectionHandler = true;
           }
         }
 
         nsCOMPtr<nsIDOMXULSelectControlItemElement> curItem;
         controlElement->GetCurrentItem(getter_AddRefs(curItem));
         nsCOMPtr<nsIContent> curNode = do_QueryInterface(curItem);
         if (curNode && nsContentUtils::ContentIsDescendantOf(curNode, oldKid)) {
             // Current item going away
             nsCOMPtr<nsIBoxObject> box = xulElement->GetBoxObject(IgnoreErrors());
             listBox = do_QueryInterface(box);
-            if (listBox && oldKidElem) {
-              listBox->GetIndexOfItem(oldKidElem, &newCurrentIndex);
+            if (listBox) {
+              listBox->GetIndexOfItem(oldKid->AsElement(), &newCurrentIndex);
             }
 
             // If any of this fails, we'll just set the current item to null
             if (newCurrentIndex == -1)
               newCurrentIndex = -2;
         }
       }
     }
@@ -875,17 +872,17 @@ nsXULElement::RemoveChildAt_Deprecated(u
     if (newCurrentIndex == -2) {
         controlElement->SetCurrentItem(nullptr);
     } else if (newCurrentIndex > -1) {
         // Make sure the index is still valid
         int32_t treeRows;
         listBox->GetRowCount(&treeRows);
         if (treeRows > 0) {
             newCurrentIndex = std::min((treeRows - 1), newCurrentIndex);
-            nsCOMPtr<nsIDOMElement> newCurrentItem;
+            RefPtr<Element> newCurrentItem;
             listBox->GetItemAtIndex(newCurrentIndex, getter_AddRefs(newCurrentItem));
             nsCOMPtr<nsIDOMXULSelectControlItemElement> xulCurItem = do_QueryInterface(newCurrentItem);
             if (xulCurItem)
                 controlElement->SetCurrentItem(xulCurItem);
         } else {
             controlElement->SetCurrentItem(nullptr);
         }
     }
@@ -922,44 +919,42 @@ nsXULElement::RemoveChildNode(nsIContent
       controlElement = do_QueryObject(this);
 
       // If it's not, look at our parent
       if (!controlElement)
         GetParentTree(getter_AddRefs(controlElement));
       nsCOMPtr<nsIContent> controlContent(do_QueryInterface(controlElement));
       RefPtr<nsXULElement> xulElement = FromNodeOrNull(controlContent);
 
-      nsCOMPtr<nsIDOMElement> oldKidElem = do_QueryInterface(aKid);
-      if (xulElement && oldKidElem) {
+      if (xulElement) {
         // Iterate over all of the items and find out if they are contained inside
         // the removed subtree.
         int32_t length;
         controlElement->GetSelectedCount(&length);
         for (int32_t i = 0; i < length; i++) {
-          nsCOMPtr<nsIDOMXULSelectControlItemElement> node;
-          controlElement->MultiGetSelectedItem(i, getter_AddRefs(node));
-          // we need to QI here to do an XPCOM-correct pointercompare
-          nsCOMPtr<nsIDOMElement> selElem = do_QueryInterface(node);
-          if (selElem == oldKidElem &&
-              NS_SUCCEEDED(controlElement->RemoveItemFromSelection(node))) {
+          nsCOMPtr<nsIDOMXULSelectControlItemElement> item;
+          controlElement->MultiGetSelectedItem(i, getter_AddRefs(item));
+          nsCOMPtr<nsINode> node = do_QueryInterface(item);
+          if (node == aKid &&
+              NS_SUCCEEDED(controlElement->RemoveItemFromSelection(item))) {
             length--;
             i--;
             fireSelectionHandler = true;
           }
         }
 
         nsCOMPtr<nsIDOMXULSelectControlItemElement> curItem;
         controlElement->GetCurrentItem(getter_AddRefs(curItem));
         nsCOMPtr<nsIContent> curNode = do_QueryInterface(curItem);
         if (curNode && nsContentUtils::ContentIsDescendantOf(curNode, aKid)) {
             // Current item going away
             nsCOMPtr<nsIBoxObject> box = xulElement->GetBoxObject(IgnoreErrors());
             listBox = do_QueryInterface(box);
-            if (listBox && oldKidElem) {
-              listBox->GetIndexOfItem(oldKidElem, &newCurrentIndex);
+            if (listBox) {
+              listBox->GetIndexOfItem(aKid->AsElement(), &newCurrentIndex);
             }
 
             // If any of this fails, we'll just set the current item to null
             if (newCurrentIndex == -1)
               newCurrentIndex = -2;
         }
       }
     }
@@ -969,17 +964,17 @@ nsXULElement::RemoveChildNode(nsIContent
     if (newCurrentIndex == -2) {
         controlElement->SetCurrentItem(nullptr);
     } else if (newCurrentIndex > -1) {
         // Make sure the index is still valid
         int32_t treeRows;
         listBox->GetRowCount(&treeRows);
         if (treeRows > 0) {
             newCurrentIndex = std::min((treeRows - 1), newCurrentIndex);
-            nsCOMPtr<nsIDOMElement> newCurrentItem;
+            RefPtr<Element> newCurrentItem;
             listBox->GetItemAtIndex(newCurrentIndex, getter_AddRefs(newCurrentItem));
             nsCOMPtr<nsIDOMXULSelectControlItemElement> xulCurItem = do_QueryInterface(newCurrentItem);
             if (xulCurItem)
                 controlElement->SetCurrentItem(xulCurItem);
         } else {
             controlElement->SetCurrentItem(nullptr);
         }
     }
--- a/dom/xul/nsXULElement.h
+++ b/dom/xul/nsXULElement.h
@@ -13,17 +13,17 @@
 #define nsXULElement_h__
 
 #include "js/TracingAPI.h"
 #include "mozilla/Attributes.h"
 #include "nsIServiceManager.h"
 #include "nsAtom.h"
 #include "mozilla/dom/NodeInfo.h"
 #include "nsIControllers.h"
-#include "nsIDOMElement.h"
+#include "nsIDOMNode.h"
 #include "nsIDOMXULMultSelectCntrlEl.h"
 #include "nsIURI.h"
 #include "nsLayoutCID.h"
 #include "nsAttrAndChildArray.h"
 #include "nsGkAtoms.h"
 #include "nsStringFwd.h"
 #include "nsStyledElement.h"
 #include "nsIFrameLoaderOwner.h"
@@ -328,17 +328,17 @@ enum {
   XUL_ELEMENT_HAS_POPUP_LISTENER =        XUL_ELEMENT_FLAG_BIT(1)
 };
 
 ASSERT_NODE_FLAGS_SPACE(ELEMENT_TYPE_SPECIFIC_BITS_OFFSET + 2);
 
 #undef XUL_ELEMENT_FLAG_BIT
 
 class nsXULElement final : public nsStyledElement,
-                           public nsIDOMElement
+                           public nsIDOMNode
 {
 public:
     using Element::Blur;
     using Element::Focus;
     explicit nsXULElement(already_AddRefed<mozilla::dom::NodeInfo> aNodeInfo);
 
     static nsresult
     Create(nsXULPrototypeElement* aPrototype, nsIDocument* aDocument,
@@ -645,21 +645,16 @@ protected:
     ~nsXULElement();
 
     // This can be removed if EnsureContentsGenerated dies.
     friend class nsNSElementTearoff;
 
     // Implementation methods
     nsresult EnsureContentsGenerated(void) const;
 
-    nsresult ExecuteOnBroadcastHandler(nsIDOMElement* anElement, const nsAString& attrName);
-
-    static nsresult
-    ExecuteJSCode(nsIDOMElement* anElement, mozilla::WidgetEvent* aEvent);
-
     // Helper routine that crawls a parent chain looking for a tree element.
     NS_IMETHOD GetParentTree(nsIDOMXULMultiSelectControlElement** aTreeElement);
 
     nsresult AddPopupListener(nsAtom* aName);
 
     void LoadSrc();
 
     /**
--- a/dom/xul/nsXULPopupListener.cpp
+++ b/dom/xul/nsXULPopupListener.cpp
@@ -215,17 +215,16 @@ nsXULPopupListener::HandleEvent(Event* a
 
 #ifndef NS_CONTEXT_MENU_IS_MOUSEUP
 nsresult
 nsXULPopupListener::FireFocusOnTargetContent(nsIDOMNode* aTargetNode, bool aIsTouch)
 {
   nsCOMPtr<nsIContent> content = do_QueryInterface(aTargetNode);
   nsCOMPtr<nsIDocument> doc = content->OwnerDoc();
 
-  // Get nsIDOMElement for targetNode
   // strong reference to keep this from going away between events
   // XXXbz between what events?  We don't use this local at all!
   RefPtr<nsPresContext> context = doc->GetPresContext();
   if (!context) {
     return NS_ERROR_FAILURE;
   }
 
   nsIFrame* targetFrame = content->GetPrimaryFrame();
--- a/dom/xul/nsXULPopupListener.h
+++ b/dom/xul/nsXULPopupListener.h
@@ -8,17 +8,16 @@
  */
 
 #ifndef nsXULPopupListener_h___
 #define nsXULPopupListener_h___
 
 #include "nsCOMPtr.h"
 
 #include "mozilla/dom/Element.h"
-#include "nsIDOMElement.h"
 #include "nsIDOMEventListener.h"
 #include "nsCycleCollectionParticipant.h"
 
 namespace mozilla {
 namespace dom {
 class MouseEvent;
 } // namespace dom
 } // namespace mozilla
--- a/dom/xul/nsXULSortService.cpp
+++ b/dom/xul/nsXULSortService.cpp
@@ -4,17 +4,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /*
   This file provides the implementation for the sort service manager.
  */
 
 #include "nsCOMPtr.h"
 #include "nsIContent.h"
-#include "nsIDOMElement.h"
 #include "nsIDOMNode.h"
 #include "nsIServiceManager.h"
 #include "nsGkAtoms.h"
 #include "nsNameSpaceManager.h"
 #include "nsXULContentUtils.h"
 #include "nsString.h"
 #include "nsQuickSort.h"
 #include "nsWhitespaceTokenizer.h"
--- a/editor/composer/nsComposerCommands.cpp
+++ b/editor/composer/nsComposerCommands.cpp
@@ -17,17 +17,16 @@
 #include "nsComposerCommands.h"
 #include "nsDebug.h"                    // for NS_ENSURE_TRUE, etc
 #include "nsError.h"                    // for NS_OK, NS_ERROR_FAILURE, etc
 #include "nsGkAtoms.h"                  // for nsGkAtoms, nsGkAtoms::font, etc
 #include "nsAtom.h"                    // for nsAtom, etc
 #include "nsIClipboard.h"               // for nsIClipboard, etc
 #include "nsICommandParams.h"           // for nsICommandParams, etc
 #include "nsID.h"
-#include "nsIDOMElement.h"              // for nsIDOMElement
 #include "nsIEditor.h"                  // for nsIEditor
 #include "nsIHTMLEditor.h"              // for nsIHTMLEditor, etc
 #include "nsLiteralString.h"            // for NS_LITERAL_STRING
 #include "nsReadableUtils.h"            // for EmptyString
 #include "nsString.h"                   // for nsAutoString, nsString, etc
 #include "nsStringFwd.h"                // for nsString
 
 class nsISupports;
@@ -1450,22 +1449,22 @@ nsInsertTagCommand::DoCommand(const char
   if (NS_WARN_IF(!editor)) {
     return NS_ERROR_FAILURE;
   }
   mozilla::HTMLEditor* htmlEditor = editor->AsHTMLEditor();
   if (NS_WARN_IF(!htmlEditor)) {
     return NS_ERROR_FAILURE;
   }
 
-  nsCOMPtr<nsIDOMElement> domElem;
+  RefPtr<Element> newElement;
   nsresult rv = htmlEditor->CreateElementWithDefaults(
-    nsDependentAtomString(mTagName), getter_AddRefs(domElem));
+    nsDependentAtomString(mTagName), getter_AddRefs(newElement));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  return htmlEditor->InsertElementAtSelection(domElem, true);
+  return htmlEditor->InsertElementAtSelection(newElement, true);
 }
 
 NS_IMETHODIMP
 nsInsertTagCommand::DoCommandParams(const char *aCommandName,
                                     nsICommandParams *aParams,
                                     nsISupports *refCon)
 {
   NS_ENSURE_ARG_POINTER(refCon);
@@ -1501,33 +1500,32 @@ nsInsertTagCommand::DoCommandParams(cons
   if (mTagName == nsGkAtoms::a) {
     attributeType.AssignLiteral("href");
   } else if (mTagName == nsGkAtoms::img) {
     attributeType.AssignLiteral("src");
   } else {
     return NS_ERROR_NOT_IMPLEMENTED;
   }
 
-  nsCOMPtr<nsIDOMElement> domElem;
+  RefPtr<Element> elem;
   rv = htmlEditor->CreateElementWithDefaults(nsDependentAtomString(mTagName),
-                                             getter_AddRefs(domElem));
+                                             getter_AddRefs(elem));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCOMPtr<Element> elem = do_QueryInterface(domElem);
   ErrorResult err;
   elem->SetAttribute(attributeType, attrib, err);
   if (NS_WARN_IF(err.Failed())) {
     return err.StealNSResult();
   }
 
   // do actual insertion
   if (mTagName == nsGkAtoms::a) {
-    return htmlEditor->InsertLinkAroundSelection(domElem);
+    return htmlEditor->InsertLinkAroundSelection(elem);
   }
-  return htmlEditor->InsertElementAtSelection(domElem, true);
+  return htmlEditor->InsertElementAtSelection(elem, true);
 }
 
 NS_IMETHODIMP
 nsInsertTagCommand::GetCommandStateParams(const char *aCommandName,
                                           nsICommandParams *aParams,
                                           nsISupports *refCon)
 {
   NS_ENSURE_ARG_POINTER(aParams);
--- a/editor/libeditor/EditorBase.cpp
+++ b/editor/libeditor/EditorBase.cpp
@@ -69,17 +69,16 @@
 #include "nsFocusManager.h"             // for nsFocusManager
 #include "nsFrameSelection.h"           // for nsFrameSelection
 #include "nsGenericHTMLElement.h"       // for nsGenericHTMLElement
 #include "nsGkAtoms.h"                  // for nsGkAtoms, nsGkAtoms::dir
 #include "nsIAbsorbingTransaction.h"    // for nsIAbsorbingTransaction
 #include "nsAtom.h"                    // for nsAtom
 #include "nsIContent.h"                 // for nsIContent
 #include "nsIDOMDocument.h"             // for nsIDOMDocument
-#include "nsIDOMElement.h"              // for nsIDOMElement
 #include "nsIDOMEventListener.h"        // for nsIDOMEventListener
 #include "nsIDOMNode.h"                 // for nsIDOMNode, etc.
 #include "nsIDocumentStateListener.h"   // for nsIDocumentStateListener
 #include "nsIEditActionListener.h"      // for nsIEditActionListener
 #include "nsIEditorObserver.h"          // for nsIEditorObserver
 #include "nsIEditorSpellCheck.h"        // for nsIEditorSpellCheck
 #include "nsIFrame.h"                   // for nsIFrame
 #include "nsIHTMLDocument.h"            // for nsIHTMLDocument
@@ -1194,75 +1193,72 @@ EditorBase::CanPaste(int32_t aSelectionT
 NS_IMETHODIMP
 EditorBase::CanPasteTransferable(nsITransferable* aTransferable,
                                  bool* aCanPaste)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-EditorBase::SetAttribute(nsIDOMElement* aElement,
+EditorBase::SetAttribute(Element* aElement,
                          const nsAString& aAttribute,
                          const nsAString& aValue)
 {
   if (NS_WARN_IF(aAttribute.IsEmpty())) {
     return NS_ERROR_INVALID_ARG;
   }
-  nsCOMPtr<Element> element = do_QueryInterface(aElement);
-  if (NS_WARN_IF(!element)) {
+  if (NS_WARN_IF(!aElement)) {
     return NS_ERROR_INVALID_ARG;
   }
   RefPtr<nsAtom> attribute = NS_Atomize(aAttribute);
-  return SetAttributeWithTransaction(*element, *attribute, aValue);
+  return SetAttributeWithTransaction(*aElement, *attribute, aValue);
 }
 
 nsresult
 EditorBase::SetAttributeWithTransaction(Element& aElement,
                                         nsAtom& aAttribute,
                                         const nsAString& aValue)
 {
   RefPtr<ChangeAttributeTransaction> transaction =
     ChangeAttributeTransaction::Create(aElement, aAttribute, aValue);
   return DoTransaction(transaction);
 }
 
 NS_IMETHODIMP
-EditorBase::GetAttributeValue(nsIDOMElement* aElement,
+EditorBase::GetAttributeValue(Element* aElement,
                               const nsAString& aAttribute,
                               nsAString& aResultValue,
                               bool* aResultIsSet)
 {
   NS_ENSURE_TRUE(aResultIsSet, NS_ERROR_NULL_POINTER);
   *aResultIsSet = false;
   if (!aElement) {
     return NS_OK;
   }
-  nsCOMPtr<Element> element = do_QueryInterface(aElement);
   nsAutoString value;
-  element->GetAttribute(aAttribute, value);
+  aElement->GetAttribute(aAttribute, value);
   if (!DOMStringIsNull(value)) {
     *aResultIsSet = true;
     aResultValue = value;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
-EditorBase::RemoveAttribute(nsIDOMElement* aElement,
+EditorBase::RemoveAttribute(Element* aElement,
                             const nsAString& aAttribute)
 {
   if (NS_WARN_IF(aAttribute.IsEmpty())) {
     return NS_ERROR_INVALID_ARG;
   }
-  nsCOMPtr<Element> element = do_QueryInterface(aElement);
-  if (NS_WARN_IF(!element)) {
+  if (NS_WARN_IF(!aElement)) {
     return NS_ERROR_INVALID_ARG;
   }
   RefPtr<nsAtom> attribute = NS_Atomize(aAttribute);
-  return RemoveAttributeWithTransaction(*element, *attribute);
+  return RemoveAttributeWithTransaction(*aElement, *attribute);
 }
 
 nsresult
 EditorBase::RemoveAttributeWithTransaction(Element& aElement,
                                            nsAtom& aAttribute)
 {
   // XXX If aElement doesn't have aAttribute, shouldn't we stop creating
   //     the transaction?  Otherwise, there will be added a transaction
@@ -2395,21 +2391,21 @@ NS_IMETHODIMP
 EditorBase::GetComposing(bool* aResult)
 {
   NS_ENSURE_ARG_POINTER(aResult);
   *aResult = IsIMEComposing();
   return NS_OK;
 }
 
 NS_IMETHODIMP
-EditorBase::GetRootElement(nsIDOMElement** aRootElement)
+EditorBase::GetRootElement(Element** aRootElement)
 {
   NS_ENSURE_ARG_POINTER(aRootElement);
   NS_ENSURE_TRUE(mRootElement, NS_ERROR_NOT_AVAILABLE);
-  nsCOMPtr<nsIDOMElement> rootElement = do_QueryInterface(mRootElement);
+  RefPtr<Element> rootElement = mRootElement;
   rootElement.forget(aRootElement);
   return NS_OK;
 }
 
 /**
  * All editor operations which alter the doc should be prefaced
  * with a call to StartOperation, naming the action and direction.
  */
@@ -4489,35 +4485,34 @@ EditorBase::CreateTxnForDeleteRange(nsRa
   if (NS_WARN_IF(!deleteNodeTransaction)) {
     return nullptr;
   }
   selectedNode.forget(aRemovingNode);
   return deleteNodeTransaction.forget();
 }
 
 nsresult
-EditorBase::CreateRange(nsIDOMNode* aStartContainer,
+EditorBase::CreateRange(nsINode* aStartContainer,
                         int32_t aStartOffset,
-                        nsIDOMNode* aEndContainer,
+                        nsINode* aEndContainer,
                         int32_t aEndOffset,
                         nsRange** aRange)
 {
   return nsRange::CreateRange(aStartContainer, aStartOffset,
                               aEndContainer, aEndOffset, aRange);
 }
 
 nsresult
-EditorBase::AppendNodeToSelectionAsRange(nsIDOMNode* aNode)
+EditorBase::AppendNodeToSelectionAsRange(nsINode* aNode)
 {
   NS_ENSURE_TRUE(aNode, NS_ERROR_NULL_POINTER);
   RefPtr<Selection> selection = GetSelection();
   NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
 
-  nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
-  nsCOMPtr<nsIDOMNode> parentNode = do_QueryInterface(node->GetParentNode());
+  nsCOMPtr<nsINode> parentNode = aNode->GetParentNode();
   NS_ENSURE_TRUE(parentNode, NS_ERROR_NULL_POINTER);
 
   int32_t offset = GetChildOffset(aNode, parentNode);
 
   RefPtr<nsRange> range;
   nsresult rv = CreateRange(parentNode, offset, parentNode, offset + 1,
                             getter_AddRefs(range));
   NS_ENSURE_SUCCESS(rv, rv);
@@ -4568,41 +4563,39 @@ EditorBase::CreateTextNode(nsIDocument& 
   RefPtr<nsTextNode> text = aDocument.CreateEmptyTextNode();
   text->MarkAsMaybeModifiedFrequently();
   // Don't notify; this node is still being created.
   text->SetText(aData, false);
   return text.forget();
 }
 
 NS_IMETHODIMP
-EditorBase::SetAttributeOrEquivalent(nsIDOMElement* aElement,
+EditorBase::SetAttributeOrEquivalent(Element* aElement,
                                      const nsAString& aAttribute,
                                      const nsAString& aValue,
                                      bool aSuppressTransaction)
 {
-  nsCOMPtr<Element> element = do_QueryInterface(aElement);
-  if (NS_WARN_IF(!element)) {
+  if (NS_WARN_IF(!aElement)) {
     return NS_ERROR_NULL_POINTER;
   }
   RefPtr<nsAtom> attribute = NS_Atomize(aAttribute);
-  return SetAttributeOrEquivalent(element, attribute, aValue,
+  return SetAttributeOrEquivalent(aElement, attribute, aValue,
                                   aSuppressTransaction);
 }
 
 NS_IMETHODIMP
-EditorBase::RemoveAttributeOrEquivalent(nsIDOMElement* aElement,
+EditorBase::RemoveAttributeOrEquivalent(Element* aElement,
                                         const nsAString& aAttribute,
                                         bool aSuppressTransaction)
 {
-  nsCOMPtr<Element> element = do_QueryInterface(aElement);
-  if (NS_WARN_IF(!element)) {
+  if (NS_WARN_IF(!aElement)) {
     return NS_ERROR_NULL_POINTER;
   }
   RefPtr<nsAtom> attribute = NS_Atomize(aAttribute);
-  return RemoveAttributeOrEquivalent(element, attribute, aSuppressTransaction);
+  return RemoveAttributeOrEquivalent(aElement, attribute, aSuppressTransaction);
 }
 
 nsresult
 EditorBase::HandleKeyPressEvent(WidgetKeyboardEvent* aKeyboardEvent)
 {
   // NOTE: When you change this method, you should also change:
   //   * editor/libeditor/tests/test_texteditor_keyevent_handling.html
   //   * editor/libeditor/tests/test_htmleditor_keyevent_handling.html
@@ -4953,17 +4946,17 @@ EditorBase::GetFocusedContent()
   EventTarget* piTarget = GetDOMEventTarget();
   if (!piTarget) {
     return nullptr;
   }
 
   nsFocusManager* fm = nsFocusManager::GetFocusManager();
   NS_ENSURE_TRUE(fm, nullptr);
 
-  nsIContent* content = fm->GetFocusedContent();
+  nsIContent* content = fm->GetFocusedElement();
   MOZ_ASSERT((content == piTarget) == SameCOMIdentity(content, piTarget));
 
   return (content == piTarget) ? content : nullptr;
 }
 
 already_AddRefed<nsIContent>
 EditorBase::GetFocusedContentForIME()
 {
--- a/editor/libeditor/EditorBase.h
+++ b/editor/libeditor/EditorBase.h
@@ -1446,25 +1446,25 @@ public:
    * CollapseSelectionToEnd() collapses the selection to the end of the editor.
    */
   nsresult CollapseSelectionToEnd(Selection* aSelection);
 
   /**
    * Helpers to add a node to the selection.
    * Used by table cell selection methods.
    */
-  nsresult CreateRange(nsIDOMNode* aStartContainer, int32_t aStartOffset,
-                       nsIDOMNode* aEndContainer, int32_t aEndOffset,
+  nsresult CreateRange(nsINode* aStartContainer, int32_t aStartOffset,
+                       nsINode* aEndContainer, int32_t aEndOffset,
                        nsRange** aRange);
 
   /**
    * Creates a range with just the supplied node and appends that to the
    * selection.
    */
-  nsresult AppendNodeToSelectionAsRange(nsIDOMNode *aNode);
+  nsresult AppendNodeToSelectionAsRange(nsINode* aNode);
 
   /**
    * When you are using AppendNodeToSelectionAsRange(), call this first to
    * start a new selection.
    */
   nsresult ClearSelection();
 
   static bool IsPreformatted(nsINode* aNode);
@@ -1825,17 +1825,17 @@ protected:
   nsCString mContentMIMEType;
 
   RefPtr<mozInlineSpellChecker> mInlineSpellChecker;
   // Reference to text services document for mInlineSpellChecker.
   RefPtr<TextServicesDocument> mTextServicesDocument;
 
   RefPtr<TransactionManager> mTransactionManager;
   // Cached root node.
-  nsCOMPtr<Element> mRootElement;
+  RefPtr<Element> mRootElement;
   // The form field as an event receiver.
   nsCOMPtr<dom::EventTarget> mEventTarget;
   RefPtr<EditorEventListener> mEventListener;
   // Strong reference to placeholder for begin/end batch purposes.
   RefPtr<PlaceholderTransaction> mPlaceholderTransaction;
   // Name of placeholder transaction.
   nsAtom* mPlaceholderName;
   // Saved selection state for placeholder transaction batching.
--- a/editor/libeditor/EditorEventListener.cpp
+++ b/editor/libeditor/EditorEventListener.cpp
@@ -213,17 +213,17 @@ EditorEventListener::Disconnect()
 {
   if (DetachedFromEditor()) {
     return;
   }
   UninstallFromEditor();
 
   nsFocusManager* fm = nsFocusManager::GetFocusManager();
   if (fm) {
-    nsIContent* focusedContent = fm->GetFocusedContent();
+    nsIContent* focusedContent = fm->GetFocusedElement();
     mozilla::dom::Element* root = mEditorBase->GetRoot();
     if (focusedContent && root &&
         nsContentUtils::ContentIsDescendantOf(focusedContent, root)) {
       // Reset the Selection ancestor limiter and SelectionController state
       // that EditorBase::InitializeSelection set up.
       mEditorBase->FinalizeSelection();
     }
   }
@@ -1100,17 +1100,17 @@ EditorEventListener::Focus(InternalFocus
     nsCOMPtr<nsIContent> editableRoot = editorBase->FindSelectionRoot(content);
 
     // make sure that the element is really focused in case an earlier
     // listener in the chain changed the focus.
     if (editableRoot) {
       nsFocusManager* fm = nsFocusManager::GetFocusManager();
       NS_ENSURE_TRUE(fm, NS_OK);
 
-      nsIContent* focusedContent = fm->GetFocusedContent();
+      nsIContent* focusedContent = fm->GetFocusedElement();
       if (!focusedContent) {
         return NS_OK;
       }
 
       nsCOMPtr<nsIContent> originalTargetAsContent =
         do_QueryInterface(aFocusEvent->GetOriginalDOMEventTarget());
 
       if (!SameCOMIdentity(
@@ -1142,18 +1142,18 @@ EditorEventListener::Blur(InternalFocusE
     return NS_OK;
   }
 
   // check if something else is focused. If another element is focused, then
   // we should not change the selection.
   nsFocusManager* fm = nsFocusManager::GetFocusManager();
   NS_ENSURE_TRUE(fm, NS_OK);
 
-  nsIContent* content = fm->GetFocusedContent();
-  if (!content || !content->IsElement()) {
+  Element* focusedElement = fm->GetFocusedElement();
+  if (!focusedElement) {
     RefPtr<EditorBase> editorBase(mEditorBase);
     editorBase->FinalizeSelection();
   }
   return NS_OK;
 }
 
 void
 EditorEventListener::SpellCheckIfNeeded()
--- a/editor/libeditor/HTMLAbsPositionEditor.cpp
+++ b/editor/libeditor/HTMLAbsPositionEditor.cpp
@@ -23,17 +23,16 @@
 #include "nsAlgorithm.h"
 #include "nsCOMPtr.h"
 #include "nsComputedDOMStyle.h"
 #include "nsDebug.h"
 #include "nsError.h"
 #include "nsGkAtoms.h"
 #include "nsIContent.h"
 #include "nsROCSSPrimitiveValue.h"
-#include "nsIDOMElement.h"
 #include "nsIDOMEventListener.h"
 #include "nsDOMCSSRGBColor.h"
 #include "nsIDOMWindow.h"
 #include "nsIHTMLObjectResizer.h"
 #include "nsINode.h"
 #include "nsIPresShell.h"
 #include "nsISupportsImpl.h"
 #include "nsISupportsUtils.h"
@@ -569,26 +568,16 @@ HTMLEditor::SetTopAndLeft(Element& aElem
                           int32_t aX,
                           int32_t aY)
 {
   AutoPlaceholderBatch batchIt(this);
   mCSSEditUtils->SetCSSPropertyPixels(aElement, *nsGkAtoms::left, aX);
   mCSSEditUtils->SetCSSPropertyPixels(aElement, *nsGkAtoms::top, aY);
 }
 
-// self-explanatory
-NS_IMETHODIMP
-HTMLEditor::GetPositionedElement(nsIDOMElement** aReturn)
-{
-  nsCOMPtr<nsIDOMElement> ret =
-    static_cast<nsIDOMElement*>(GetAsDOMNode(GetPositionedElement()));
-  ret.forget(aReturn);
-  return NS_OK;
-}
-
 nsresult
 HTMLEditor::GetTemporaryStyleForFocusedPositionedElement(Element& aElement,
                                                          nsAString& aReturn)
 {
   // we are going to outline the positioned element and bring it to the
   // front to overlap any other element intersecting with it. But
   // first, let's see what's the background and foreground colors of the
   // positioned element.
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -36,17 +36,16 @@
 #include "nsDebug.h"
 #include "nsError.h"
 #include "nsGkAtoms.h"
 #include "nsAtom.h"
 #include "nsHTMLDocument.h"
 #include "nsIContent.h"
 #include "nsIContentIterator.h"
 #include "nsID.h"
-#include "nsIDOMElement.h"
 #include "nsIFrame.h"
 #include "nsIHTMLAbsPosEditor.h"
 #include "nsINode.h"
 #include "nsLiteralString.h"
 #include "nsRange.h"
 #include "nsReadableUtils.h"
 #include "nsString.h"
 #include "nsStringFwd.h"
@@ -2206,17 +2205,17 @@ HTMLEditRules::WillDeleteSelection(Selec
 
   // If there is only bogus content, cancel the operation
   if (mBogusNode) {
     *aCancel = true;
     return NS_OK;
   }
 
   // First check for table selection mode.  If so, hand off to table editor.
-  nsCOMPtr<nsIDOMElement> cell;
+  RefPtr<Element> cell;
   NS_ENSURE_STATE(mHTMLEditor);
   nsresult rv =
     mHTMLEditor->GetFirstSelectedCell(nullptr, getter_AddRefs(cell));
   if (NS_SUCCEEDED(rv) && cell) {
     NS_ENSURE_STATE(mHTMLEditor);
     rv = mHTMLEditor->DeleteTableCellContents();
     *aHandled = true;
     return rv;
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -1096,17 +1096,17 @@ HTMLEditor::TabInTable(bool inIsShift,
     // If we haven't handled it yet, then we must have run off the end of the
     // table.  Insert a new row.
     rv = InsertTableRow(1, true);
     NS_ENSURE_SUCCESS(rv, rv);
     *outHandled = true;
     // Put selection in right place.  Use table code to get selection and index
     // to new row...
     RefPtr<Selection> selection;
-    nsCOMPtr<nsIDOMElement> tblElement, cell;
+    RefPtr<Element> tblElement, cell;
     int32_t row;
     rv = GetCellContext(getter_AddRefs(selection),
                         getter_AddRefs(tblElement),
                         getter_AddRefs(cell),
                         nullptr, nullptr,
                         &row, nullptr);
     NS_ENSURE_SUCCESS(rv, rv);
     // ...so that we can ask for first cell in that row...
@@ -1512,24 +1512,23 @@ HTMLEditor::GetBetterInsertionPointFor(n
   EditorRawD