Merge inbound to mozilla-central. a=merge
authorCosmin Sabou <csabou@mozilla.com>
Fri, 27 Apr 2018 13:04:36 +0300
changeset 416017 d2d518b1f8730eb61554df7179ef9a2aeed4d843
parent 416016 8229360171458d5e2a36fd562e9ba1da6af9b6ba (current diff)
parent 415903 4b0e963b050b63441999b49a23cc03b6e4406cd5 (diff)
child 416018 d8c8620f0be8c16a45d8a3b6c3f47a01b2869087
child 416067 6c8dfef176b5c0d698529810f60ada56b5be7b43
child 416072 a90bf0a31015017868527c8f11a79a1cdc83c537
push id102694
push usercsabou@mozilla.com
push dateFri, 27 Apr 2018 10:15:42 +0000
treeherdermozilla-inbound@d8c8620f0be8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone61.0a1
first release with
nightly linux32
d2d518b1f873 / 61.0a1 / 20180427102245 / files
nightly linux64
d2d518b1f873 / 61.0a1 / 20180427102245 / files
nightly mac
d2d518b1f873 / 61.0a1 / 20180427102245 / files
nightly win32
d2d518b1f873 / 61.0a1 / 20180427102245 / files
nightly win64
d2d518b1f873 / 61.0a1 / 20180427102245 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to mozilla-central. a=merge
dom/base/nsDocument.cpp
dom/base/nsFocusManager.cpp
dom/html/nsHTMLDocument.cpp
dom/interfaces/core/nsIDOMElement.idl
extensions/spellcheck/hunspell/src/filemgr.cxx
gfx/layers/moz.build
gfx/skia/skia/src/core/SkDeviceLooper.cpp
gfx/skia/skia/src/core/SkDeviceLooper.h
layout/base/PresShell.cpp
toolkit/components/extensions/Extension.jsm
toolkit/components/typeaheadfind/nsTypeAheadFind.cpp
toolkit/mozapps/extensions/internal/XPIProvider.jsm
widget/cocoa/nsCocoaWindow.mm
--- 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;
 }