Merge inbound to mozilla-central. a=merge
authorCosmin Sabou <csabou@mozilla.com>
Thu, 01 Feb 2018 01:14:44 +0200
changeset 401932 17ade9f88b6ed2232be51bc02c6860562c3d31dc
parent 401870 c783229694e5ed33b553b7825d753aa247844d7f (current diff)
parent 401931 48e318052aaa7cf995892f171dc697b2a0c9e3fc (diff)
child 401978 0a48259236671c5403af942a0cf1963b8510e401
push id33358
push usercsabou@mozilla.com
push dateWed, 31 Jan 2018 23:15:12 +0000
treeherdermozilla-central@17ade9f88b6e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone60.0a1
first release with
nightly linux32
17ade9f88b6e / 60.0a1 / 20180201100326 / files
nightly linux64
17ade9f88b6e / 60.0a1 / 20180201100326 / files
nightly mac
17ade9f88b6e / 60.0a1 / 20180201100326 / files
nightly win32
17ade9f88b6e / 60.0a1 / 20180201100326 / files
nightly win64
17ade9f88b6e / 60.0a1 / 20180201100326 / 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/nsGlobalWindowInner.cpp
dom/interfaces/xul/nsIDOMXULDocument.idl
dom/xul/nsIXULDocument.h
--- a/accessible/generic/Accessible.cpp
+++ b/accessible/generic/Accessible.cpp
@@ -23,27 +23,28 @@
 #include "Relation.h"
 #include "Role.h"
 #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 "nsIDOMNodeFilter.h"
 #include "nsIDOMKeyEvent.h"
 #include "nsIDOMTreeWalker.h"
 #include "nsIDOMXULButtonElement.h"
-#include "nsIDOMXULDocument.h"
 #include "nsIDOMXULElement.h"
 #include "nsIDOMXULLabelElement.h"
 #include "nsIDOMXULSelectCntrlEl.h"
 #include "nsIDOMXULSelectCntrlItemEl.h"
+#include "nsINodeList.h"
 #include "nsPIDOMWindow.h"
 
 #include "nsIDocument.h"
 #include "nsIContent.h"
 #include "nsIForm.h"
 #include "nsIFormControl.h"
 
 #include "nsDeckFrame.h"
@@ -1746,32 +1747,27 @@ Accessible::RelationByType(RelationType 
           if (form) {
             nsCOMPtr<nsIContent> formContent =
               do_QueryInterface(form->GetDefaultSubmitElement());
             return Relation(mDoc, formContent);
           }
         }
       } else {
         // In XUL, use first <button default="true" .../> in the document
-        nsCOMPtr<nsIDOMXULDocument> xulDoc =
-          do_QueryInterface(mContent->OwnerDoc());
+        dom::XULDocument* xulDoc = mContent->OwnerDoc()->AsXULDocument();
         nsCOMPtr<nsIDOMXULButtonElement> buttonEl;
         if (xulDoc) {
-          nsCOMPtr<nsIDOMNodeList> possibleDefaultButtons;
-          xulDoc->GetElementsByAttribute(NS_LITERAL_STRING("default"),
-                                         NS_LITERAL_STRING("true"),
-                                         getter_AddRefs(possibleDefaultButtons));
+          nsCOMPtr<nsINodeList> possibleDefaultButtons =
+            xulDoc->GetElementsByAttribute(NS_LITERAL_STRING("default"),
+                                           NS_LITERAL_STRING("true"));
           if (possibleDefaultButtons) {
-            uint32_t length;
-            possibleDefaultButtons->GetLength(&length);
-            nsCOMPtr<nsIDOMNode> possibleButton;
+            uint32_t length = possibleDefaultButtons->Length();
             // Check for button in list of default="true" elements
             for (uint32_t count = 0; count < length && !buttonEl; count ++) {
-              possibleDefaultButtons->Item(count, getter_AddRefs(possibleButton));
-              buttonEl = do_QueryInterface(possibleButton);
+              buttonEl = do_QueryInterface(possibleDefaultButtons->Item(count));
             }
           }
           if (!buttonEl) { // Check for anonymous accept button in <dialog>
             dom::Element* rootElm = mContent->OwnerDoc()->GetRootElement();
             if (rootElm) {
               nsIContent* possibleButtonEl = rootElm->OwnerDoc()->
                 GetAnonymousElementByAttribute(rootElm, nsGkAtoms::_default,
                                                NS_LITERAL_STRING("true"));
--- a/accessible/generic/DocAccessible.cpp
+++ b/accessible/generic/DocAccessible.cpp
@@ -20,17 +20,16 @@
 #include "xpcAccessibleDocument.h"
 
 #include "nsIMutableArray.h"
 #include "nsICommandManager.h"
 #include "nsIDocShell.h"
 #include "nsIDocument.h"
 #include "nsIDOMCharacterData.h"
 #include "nsIDOMDocument.h"
-#include "nsIDOMXULDocument.h"
 #include "nsIDOMMutationEvent.h"
 #include "nsPIDOMWindow.h"
 #include "nsIEditingSession.h"
 #include "nsIFrame.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsImageFrame.h"
 #include "nsIPersistentProperties2.h"
 #include "nsIPresShell.h"
@@ -45,20 +44,16 @@
 #include "mozilla/Assertions.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/HTMLEditor.h"
 #include "mozilla/TextEditor.h"
 #include "mozilla/dom/TabChild.h"
 #include "mozilla/dom/DocumentType.h"
 #include "mozilla/dom/Element.h"
 
-#ifdef MOZ_XUL
-#include "nsIXULDocument.h"
-#endif
-
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Static member initialization
 
 static nsStaticAtom** kRelationAttrs[] =
 {
@@ -208,18 +203,17 @@ DocAccessible::NativeRole()
     int32_t itemType = docShell->ItemType();
     if (sameTypeRoot == docShell) {
       // Root of content or chrome tree
       if (itemType == nsIDocShellTreeItem::typeChrome)
         return roles::CHROME_WINDOW;
 
       if (itemType == nsIDocShellTreeItem::typeContent) {
 #ifdef MOZ_XUL
-        nsCOMPtr<nsIXULDocument> xulDoc(do_QueryInterface(mDocumentNode));
-        if (xulDoc)
+        if (mDocumentNode && mDocumentNode->IsXULDocument())
           return roles::APPLICATION;
 #endif
         return roles::DOCUMENT;
       }
     }
     else if (itemType == nsIDocShellTreeItem::typeContent) {
       return roles::DOCUMENT;
     }
@@ -387,18 +381,17 @@ DocAccessible::URL(nsAString& aURL) cons
   }
   CopyUTF8toUTF16(theURL, aURL);
 }
 
 void
 DocAccessible::DocType(nsAString& aType) const
 {
 #ifdef MOZ_XUL
-  nsCOMPtr<nsIXULDocument> xulDoc(do_QueryInterface(mDocumentNode));
-  if (xulDoc) {
+  if (mDocumentNode->IsXULDocument()) {
     aType.AssignLiteral("window"); // doctype not implemented for XUL at time of writing - causes assertion
     return;
   }
 #endif
   dom::DocumentType* docType = mDocumentNode->GetDoctype();
   if (docType)
     docType->GetPublicId(aType);
 }
--- a/accessible/generic/RootAccessible.cpp
+++ b/accessible/generic/RootAccessible.cpp
@@ -37,17 +37,16 @@
 #include "nsIServiceManager.h"
 #include "nsPIDOMWindow.h"
 #include "nsIWebBrowserChrome.h"
 #include "nsReadableUtils.h"
 #include "nsFocusManager.h"
 #include "nsGlobalWindow.h"
 
 #ifdef MOZ_XUL
-#include "nsIXULDocument.h"
 #include "nsIXULWindow.h"
 #endif
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 using namespace mozilla::dom;
 
 ////////////////////////////////////////////////////////////////////////////////
--- a/accessible/generic/moz.build
+++ b/accessible/generic/moz.build
@@ -26,16 +26,17 @@ UNIFIED_SOURCES += [
 ]
 
 LOCAL_INCLUDES += [
     '/accessible/base',
     '/accessible/html',
     '/accessible/xpcom',
     '/accessible/xul',
     '/dom/base',
+    '/dom/xul',
     '/layout/generic',
     '/layout/xul',
 ]
 
 if CONFIG['OS_ARCH'] == 'WINNT':
     LOCAL_INCLUDES += [
         '/accessible/ipc/win',
     ]
--- a/devtools/client/inspector/rules/test/browser_rules_computed-lists_01.js
+++ b/devtools/client/inspector/rules/test/browser_rules_computed-lists_01.js
@@ -27,19 +27,19 @@ function* testExpandersShown(inspector, 
   let rule = getRuleViewRuleEditor(view, 1).rule;
 
   info("Check that the correct rules are visible");
   is(rule.selectorText, "#testid", "Second rule is #testid.");
   is(rule.textProps[0].name, "margin", "First property is margin.");
   is(rule.textProps[1].name, "top", "Second property is top.");
 
   info("Check that the expanders are shown correctly");
-  is(rule.textProps[0].editor.expander.style.visibility, "visible",
-      "margin expander is visible.");
-  is(rule.textProps[1].editor.expander.style.visibility, "hidden",
+  is(rule.textProps[0].editor.expander.style.display, "inline-block",
+      "margin expander is displayed.");
+  is(rule.textProps[1].editor.expander.style.display, "none",
       "top expander is hidden.");
   ok(!rule.textProps[0].editor.expander.hasAttribute("open"),
       "margin computed list is closed.");
   ok(!rule.textProps[1].editor.expander.hasAttribute("open"),
       "top computed list is closed.");
   ok(!rule.textProps[0].editor.computed.hasChildNodes(),
       "margin computed list is empty before opening.");
   ok(!rule.textProps[1].editor.computed.hasChildNodes(),
--- a/devtools/client/inspector/rules/views/text-property-editor.js
+++ b/devtools/client/inspector/rules/views/text-property-editor.js
@@ -130,35 +130,35 @@ TextPropertyEditor.prototype = {
     });
 
     // The enable checkbox will disable or enable the rule.
     this.enable = createChild(this.container, "div", {
       class: "ruleview-enableproperty theme-checkbox",
       tabindex: "-1"
     });
 
-    // Click to expand the computed properties of the text property.
-    this.expander = createChild(this.container, "span", {
-      class: "ruleview-expander theme-twisty"
-    });
-    this.expander.addEventListener("click", this._onExpandClicked, true);
-
     this.nameContainer = createChild(this.container, "span", {
       class: "ruleview-namecontainer"
     });
 
     // Property name, editable when focused.  Property name
     // is committed when the editor is unfocused.
     this.nameSpan = createChild(this.nameContainer, "span", {
       class: "ruleview-propertyname theme-fg-color5",
       tabindex: this.ruleEditor.isEditable ? "0" : "-1",
     });
 
     appendText(this.nameContainer, ": ");
 
+    // Click to expand the computed properties of the text property.
+    this.expander = createChild(this.container, "span", {
+      class: "ruleview-expander theme-twisty"
+    });
+    this.expander.addEventListener("click", this._onExpandClicked, true);
+
     // Create a span that will hold the property and semicolon.
     // Use this span to create a slightly larger click target
     // for the value.
     this.valueContainer = createChild(this.container, "span", {
       class: "ruleview-propertyvaluecontainer"
     });
 
     // Property value, editable when focused.  Changes to the
@@ -549,16 +549,17 @@ TextPropertyEditor.prototype = {
     // Update the rule property highlight.
     this.ruleView._updatePropertyHighlight(this);
   },
 
   _onStartEditing: function () {
     this.element.classList.remove("ruleview-overridden");
     this.filterProperty.hidden = true;
     this.enable.style.visibility = "hidden";
+    this.expander.style.display = "none";
   },
 
   /**
    * Update the visibility of the enable checkbox, the warning indicator and
    * the filter property, as well as the overridden state of the property.
    */
   updatePropertyState: function () {
     if (this.prop.enabled) {
@@ -570,16 +571,19 @@ TextPropertyEditor.prototype = {
     }
 
     this.warning.hidden = this.editing || this.isValid();
     this.filterProperty.hidden = this.editing ||
                                  !this.isValid() ||
                                  !this.prop.overridden ||
                                  this.ruleEditor.rule.isUnmatched;
 
+    let showExpander = this.prop.computed.some(c => c.name !== this.prop.name);
+    this.expander.style.display = showExpander ? "inline-block" : "none";
+
     if (!this.editing &&
         (this.prop.overridden || !this.prop.enabled ||
          !this.prop.isKnownProperty())) {
       this.element.classList.add("ruleview-overridden");
     } else {
       this.element.classList.remove("ruleview-overridden");
     }
   },
@@ -587,17 +591,17 @@ TextPropertyEditor.prototype = {
   /**
    * Update the indicator for computed styles. The computed styles themselves
    * are populated on demand, when they become visible.
    */
   _updateComputed: function () {
     this.computed.innerHTML = "";
 
     let showExpander = this.prop.computed.some(c => c.name !== this.prop.name);
-    this.expander.style.visibility = showExpander ? "visible" : "hidden";
+    this.expander.style.display = !this.editing && showExpander ? "inline-block" : "none";
 
     this._populatedComputed = false;
     if (this.expander.hasAttribute("open")) {
       this._populateComputed();
     }
   },
 
   /**
--- a/devtools/client/themes/rules.css
+++ b/devtools/client/themes/rules.css
@@ -154,16 +154,17 @@
 }
 
 .ruleview-expandable-container {
   display: block;
 }
 
 .ruleview-namecontainer {
   cursor: text;
+  padding-left: 3px;
 }
 
 .ruleview-propertyvaluecontainer {
   cursor: text;
   padding-right: 5px;
 }
 
 .ruleview-propertyvaluecontainer a {
@@ -384,17 +385,20 @@
 }
 
 .ruleview-rule:not(:hover) .ruleview-enableproperty {
   visibility: hidden;
 }
 
 .ruleview-expander {
   vertical-align: middle;
-  display: inline-block;
+}
+
+.ruleview-propertycontainer .ruleview-expander {
+  margin-left: -6px;
 }
 
 .ruleview-rule .ruleview-expander.theme-twisty:dir(rtl) {
   /* for preventing .theme-twisty's wrong direction in rtl; Bug 1296648 */
   transform: none;
 }
 
 .ruleview-newproperty {
@@ -410,21 +414,21 @@
 }
 
 .ruleview-computedlist {
   list-style: none;
   padding: 0;
 }
 
 .ruleview-computed {
-  margin-inline-start: 35px;
+  margin-inline-start: 26px;
 }
 
 .ruleview-overridden-items {
-  margin: 0px 0px 0px 5px;
+  margin: 0px 0px 0px 2px;
   list-style: none;
   line-height: 1.5em;
 }
 
 .ruleview-overridden-item {
   position: relative;
 }
 
--- a/devtools/server/actors/webextension.js
+++ b/devtools/server/actors/webextension.js
@@ -7,16 +7,17 @@
 const { Ci, Cu, Cc } = require("chrome");
 const Services = require("Services");
 
 const { ChromeActor } = require("./chrome");
 const makeDebugger = require("./utils/make-debugger");
 
 loader.lazyRequireGetter(this, "mapURIToAddonID", "devtools/server/actors/utils/map-uri-to-addon-id");
 loader.lazyRequireGetter(this, "unwrapDebuggerObjectGlobal", "devtools/server/actors/script", true);
+loader.lazyRequireGetter(this, "ChromeUtils");
 
 const FALLBACK_DOC_MESSAGE = "Your addon does not have any document opened yet.";
 
 /**
  * Creates a TabActor for debugging all the contexts associated to a target WebExtensions
  * add-on running in a child extension process.
  * Most of the implementation is inherited from ChromeActor (which inherits most of its
  * implementation from TabActor).
@@ -342,17 +343,17 @@ WebExtensionChildActor.prototype._should
       // The global might be a sandbox with a window object in its proto chain. If the
       // window navigated away since the sandbox was created, it can throw a security
       // exception during this property check as the sandbox no longer has access to
       // its own proto.
       return false;
     }
 
     // Filter out any global which contains a XUL document.
-    if (global.document instanceof Ci.nsIDOMXULDocument) {
+    if (ChromeUtils.getClassName(global.document) == "XULDocument") {
       return false;
     }
 
     // Change top level document as a simulated frame switching.
     if (global.document.ownerGlobal && this.isExtensionWindow(global)) {
       this._onNewExtensionWindow(global.document.ownerGlobal);
     }
 
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -549,17 +549,19 @@ nsDocShell::GetInterface(const nsIID& aI
               aIID.Equals(NS_GET_IID(nsIGlobalObject)) ||
               aIID.Equals(NS_GET_IID(nsPIDOMWindowOuter)) ||
               aIID.Equals(NS_GET_IID(mozIDOMWindowProxy)) ||
               aIID.Equals(NS_GET_IID(nsIDOMWindow))) &&
              NS_SUCCEEDED(EnsureScriptEnvironment())) {
     return mScriptGlobal->QueryInterface(aIID, aSink);
   } else if (aIID.Equals(NS_GET_IID(nsIDOMDocument)) &&
              NS_SUCCEEDED(EnsureContentViewer())) {
-    mContentViewer->GetDOMDocument((nsIDOMDocument**)aSink);
+    nsCOMPtr<nsIDOMDocument> doc =
+      do_QueryInterface(mContentViewer->GetDocument());
+    doc.forget(aSink);
     return *aSink ? NS_OK : NS_NOINTERFACE;
   } else if (aIID.Equals(NS_GET_IID(nsIDocument)) &&
              NS_SUCCEEDED(EnsureContentViewer())) {
     nsCOMPtr<nsIDocument> doc = mContentViewer->GetDocument();
     doc.forget(aSink);
     return *aSink ? NS_OK : NS_NOINTERFACE;
   } else if (aIID.Equals(NS_GET_IID(nsIApplicationCacheContainer))) {
     *aSink = nullptr;
@@ -567,29 +569,28 @@ nsDocShell::GetInterface(const nsIID& aI
     // Return application cache associated with this docshell, if any
 
     nsCOMPtr<nsIContentViewer> contentViewer;
     GetContentViewer(getter_AddRefs(contentViewer));
     if (!contentViewer) {
       return NS_ERROR_NO_INTERFACE;
     }
 
-    nsCOMPtr<nsIDOMDocument> domDoc;
-    contentViewer->GetDOMDocument(getter_AddRefs(domDoc));
-    NS_ASSERTION(domDoc, "Should have a document.");
-    if (!domDoc) {
+    nsCOMPtr<nsIDocument> doc = contentViewer->GetDocument();
+    NS_ASSERTION(doc, "Should have a document.");
+    if (!doc) {
       return NS_ERROR_NO_INTERFACE;
     }
 
 #if defined(DEBUG)
     MOZ_LOG(gDocShellLog, LogLevel::Debug,
            ("nsDocShell[%p]: returning app cache container %p",
-            this, domDoc.get()));
+            this, doc.get()));
 #endif
-    return domDoc->QueryInterface(aIID, aSink);
+    return doc->QueryInterface(aIID, aSink);
   } else if (aIID.Equals(NS_GET_IID(nsIPrompt)) &&
              NS_SUCCEEDED(EnsureScriptEnvironment())) {
     nsresult rv;
     nsCOMPtr<nsIWindowWatcher> wwatch =
       do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
     NS_ENSURE_SUCCESS(rv, rv);
 
     // Get the an auth prompter for our window so that the parenting
@@ -5193,17 +5194,22 @@ nsDocShell::Stop(uint32_t aStopFlags)
 }
 
 NS_IMETHODIMP
 nsDocShell::GetDocument(nsIDOMDocument** aDocument)
 {
   NS_ENSURE_ARG_POINTER(aDocument);
   NS_ENSURE_SUCCESS(EnsureContentViewer(), NS_ERROR_FAILURE);
 
-  return mContentViewer->GetDOMDocument(aDocument);
+  nsIDocument* doc = mContentViewer->GetDocument();
+  if (!doc) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+
+  return CallQueryInterface(doc, aDocument);
 }
 
 NS_IMETHODIMP
 nsDocShell::GetCurrentURI(nsIURI** aURI)
 {
   NS_ENSURE_ARG_POINTER(aURI);
 
   if (mCurrentURI) {
@@ -7976,19 +7982,17 @@ nsDocShell::BeginRestore(nsIContentViewe
     aContentViewer = mContentViewer;
   }
 
   // Dispatch events for restoring the presentation.  We try to simulate
   // the progress notifications loading the document would cause, so we add
   // the document's channel to the loadgroup to initiate stateChange
   // notifications.
 
-  nsCOMPtr<nsIDOMDocument> domDoc;
-  aContentViewer->GetDOMDocument(getter_AddRefs(domDoc));
-  nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
+  nsCOMPtr<nsIDocument> doc = aContentViewer->GetDocument();
   if (doc) {
     nsIChannel* channel = doc->GetChannel();
     if (channel) {
       mEODForCurrentDocument = false;
       mIsRestoringDocument = true;
       mLoadGroup->AddRequest(channel, nullptr);
       mIsRestoringDocument = false;
     }
@@ -8198,19 +8202,17 @@ nsDocShell::RestoreFromHistory()
     return NS_ERROR_FAILURE;
   }
 
   if (mSavingOldViewer) {
     // We determined that it was safe to cache the document presentation
     // at the time we initiated the new load.  We need to check whether
     // it's still safe to do so, since there may have been DOM mutations
     // or new requests initiated.
-    nsCOMPtr<nsIDOMDocument> domDoc;
-    viewer->GetDOMDocument(getter_AddRefs(domDoc));
-    nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
+    nsCOMPtr<nsIDocument> doc = viewer->GetDocument();
     nsIRequest* request = nullptr;
     if (doc) {
       request = doc->GetChannel();
     }
     mSavingOldViewer = CanSavePresentation(mLoadType, request, doc);
   }
 
   nsCOMPtr<nsIContentViewer> oldCv(mContentViewer);
@@ -8376,18 +8378,17 @@ nsDocShell::RestoreFromHistory()
   // Clearing the viewer from the SHEntry will clear all of this state.
   nsCOMPtr<nsISupports> windowState;
   mLSHE->GetWindowState(getter_AddRefs(windowState));
   mLSHE->SetWindowState(nullptr);
 
   bool sticky;
   mLSHE->GetSticky(&sticky);
 
-  nsCOMPtr<nsIDOMDocument> domDoc;
-  mContentViewer->GetDOMDocument(getter_AddRefs(domDoc));
+  nsCOMPtr<nsIDocument> document = mContentViewer->GetDocument();
 
   nsCOMArray<nsIDocShellTreeItem> childShells;
   int32_t i = 0;
   nsCOMPtr<nsIDocShellTreeItem> child;
   while (NS_SUCCEEDED(mLSHE->ChildShellAt(i++, getter_AddRefs(child))) &&
          child) {
     childShells.AppendObject(child);
   }
@@ -8457,17 +8458,16 @@ nsDocShell::RestoreFromHistory()
   if (oldCv && newCv) {
     newCv->SetMinFontSize(minFontSize);
     newCv->SetTextZoom(textZoom);
     newCv->SetFullZoom(pageZoom);
     newCv->SetOverrideDPPX(overrideDPPX);
     newCv->SetAuthorStyleDisabled(styleDisabled);
   }
 
-  nsCOMPtr<nsIDocument> document = do_QueryInterface(domDoc);
   if (document) {
     RefPtr<nsDocShell> parent = GetParentDocshell();
     if (parent) {
       nsCOMPtr<nsIDocument> d = parent->GetDocument();
       if (d) {
         if (d->EventHandlingSuppressed()) {
           document->SuppressEventHandling(d->EventHandlingSuppressed());
         }
@@ -8715,19 +8715,17 @@ nsDocShell::CreateContentViewer(const ns
   // wrong information :-(
   //
 
   if (mSavingOldViewer) {
     // We determined that it was safe to cache the document presentation
     // at the time we initiated the new load.  We need to check whether
     // it's still safe to do so, since there may have been DOM mutations
     // or new requests initiated.
-    nsCOMPtr<nsIDOMDocument> domDoc;
-    viewer->GetDOMDocument(getter_AddRefs(domDoc));
-    nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
+    nsCOMPtr<nsIDocument> doc = viewer->GetDocument();
     mSavingOldViewer = CanSavePresentation(mLoadType, aRequest, doc);
   }
 
   NS_ASSERTION(!mLoadingURI, "Re-entering unload?");
 
   nsCOMPtr<nsIChannel> aOpenedChannel = do_QueryInterface(aRequest);
   if (aOpenedChannel) {
     aOpenedChannel->GetURI(getter_AddRefs(mLoadingURI));
--- a/docshell/base/nsDocShellTreeOwner.cpp
+++ b/docshell/base/nsDocShellTreeOwner.cpp
@@ -22,18 +22,16 @@
 #include "nsISimpleEnumerator.h"
 #include "mozilla/LookAndFeel.h"
 
 // Interfaces needed to be included
 #include "nsPresContext.h"
 #include "nsITooltipListener.h"
 #include "nsIDOMNode.h"
 #include "nsIDOMNodeList.h"
-#include "nsIDOMDocument.h"
-#include "nsIDOMDocumentType.h"
 #include "nsIDOMElement.h"
 #include "Link.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/SVGTitleElement.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMFileList.h"
 #include "nsIDOMMouseEvent.h"
 #include "nsIFormControl.h"
@@ -409,26 +407,22 @@ nsDocShellTreeOwner::SizeShellTo(nsIDocS
       int32_t width = 0;
       int32_t height = 0;
       shellAsWin->GetSize(&width, &height);
       return tabChild->RemoteSizeShellTo(aCX, aCY, width, height);
     }
     return webBrowserChrome->SizeBrowserTo(aCX, aCY);
   }
 
-  nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(aShellItem));
-  NS_ENSURE_TRUE(webNav, NS_ERROR_FAILURE);
+  NS_ENSURE_TRUE(aShellItem, NS_ERROR_FAILURE);
 
-  nsCOMPtr<nsIDOMDocument> domDocument;
-  webNav->GetDocument(getter_AddRefs(domDocument));
-  NS_ENSURE_TRUE(domDocument, NS_ERROR_FAILURE);
+  nsCOMPtr<nsIDocument> document = aShellItem->GetDocument();
+  NS_ENSURE_TRUE(document, NS_ERROR_FAILURE);
 
-  nsCOMPtr<nsIDOMElement> domElement;
-  domDocument->GetDocumentElement(getter_AddRefs(domElement));
-  NS_ENSURE_TRUE(domElement, NS_ERROR_FAILURE);
+  NS_ENSURE_TRUE(document->GetDocumentElement(), NS_ERROR_FAILURE);
 
   // Set the preferred Size
   //XXX
   NS_ERROR("Implement this");
   /*
   Set the preferred size on the aShellItem.
   */
 
--- a/docshell/base/nsIContentViewer.idl
+++ b/docshell/base/nsIContentViewer.idl
@@ -1,17 +1,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 "nsISupports.idl"
 
 interface nsIDocShell;
 interface nsIDocument;
-interface nsIDOMDocument;
 interface nsIDOMNode;
 interface nsISHEntry;
 interface nsIPrintSettings;
 
 
 %{ C++
 #include "nsTArray.h"
 #include "nsRect.h"
@@ -121,22 +120,31 @@ interface nsIContentViewer : nsISupports
    *      it will never be saved in session history.
    *
    */
   void close(in nsISHEntry historyEntry);
   void destroy();
 
   void stop();
 
-  attribute nsIDOMDocument DOMDocument;
+  /**
+   * Returns the same thing as getDocument(), but for use from script
+   * only.  C++ consumers should use getDocument().
+   */
+  readonly attribute nsISupports DOMDocument;
 
   /**
    * Returns DOMDocument as nsIDocument and without addrefing.
    */
-  [noscript,notxpcom] nsIDocument getDocument();
+  [noscript,notxpcom,nostdcall] nsIDocument getDocument();
+
+  /**
+   * Allows setting the document.
+   */
+  [noscript,nostdcall] void setDocument(in nsIDocument aDocument);
 
   [noscript] void getBounds(in nsIntRectRef aBounds);
   [noscript] void setBounds([const] in nsIntRectRef aBounds);
   /**
    * The 'aFlags' argument to setBoundsWithFlags is a set of these bits.
    */
   const unsigned long eDelayResize = 1;
   [noscript] void setBoundsWithFlags([const] in nsIntRectRef aBounds,
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -112,20 +112,16 @@
 #include "nsView.h"
 #include "nsViewManager.h"
 #include "nsIScrollableFrame.h"
 #include "mozilla/css/StyleRule.h" /* For nsCSSSelectorList */
 #include "nsCSSRuleProcessor.h"
 #include "nsRuleProcessorData.h"
 #include "nsTextNode.h"
 
-#ifdef MOZ_XUL
-#include "nsIXULDocument.h"
-#endif /* MOZ_XUL */
-
 #include "nsCycleCollectionParticipant.h"
 #include "nsCCUncollectableMarker.h"
 
 #include "mozAutoDocUpdate.h"
 
 #include "nsCSSParser.h"
 #include "nsDOMMutationObserver.h"
 #include "nsWrapperCacheInlines.h"
--- a/dom/base/FragmentOrElement.cpp
+++ b/dom/base/FragmentOrElement.cpp
@@ -98,20 +98,16 @@
 #include "nsViewManager.h"
 #include "nsIScrollableFrame.h"
 #include "ChildIterator.h"
 #include "mozilla/css/StyleRule.h" /* For nsCSSSelectorList */
 #include "nsRuleProcessorData.h"
 #include "nsTextNode.h"
 #include "mozilla/dom/NodeListBinding.h"
 
-#ifdef MOZ_XUL
-#include "nsIXULDocument.h"
-#endif /* MOZ_XUL */
-
 #include "nsCCUncollectableMarker.h"
 
 #include "mozAutoDocUpdate.h"
 
 #include "mozilla/Sprintf.h"
 #include "nsDOMMutationObserver.h"
 #include "nsWrapperCacheInlines.h"
 #include "nsCycleCollector.h"
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -40,16 +40,17 @@
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/CustomElementRegistry.h"
 #include "mozilla/dom/DocumentFragment.h"
 #include "mozilla/dom/DOMException.h"
 #include "mozilla/dom/DOMExceptionBinding.h"
 #include "mozilla/dom/DOMTypes.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/ElementInlines.h"
+#include "mozilla/dom/Event.h"
 #include "mozilla/dom/FileSystemSecurity.h"
 #include "mozilla/dom/FileBlobImpl.h"
 #include "mozilla/dom/HTMLInputElement.h"
 #include "mozilla/dom/HTMLSlotElement.h"
 #include "mozilla/dom/HTMLTemplateElement.h"
 #include "mozilla/dom/IDTracker.h"
 #include "mozilla/dom/IPCBlobUtils.h"
 #include "mozilla/dom/NodeBinding.h"
@@ -126,17 +127,16 @@
 #include "nsIContentViewer.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeOwner.h"
 #include "nsIDocument.h"
 #include "nsIDocumentEncoder.h"
 #include "nsIDOMChromeWindow.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMDocumentType.h"
-#include "nsIDOMEvent.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMHTMLFormElement.h"
 #include "nsIDOMHTMLInputElement.h"
 #include "nsIDOMNode.h"
 #include "nsIDOMNodeList.h"
 #include "nsIDOMWindowUtils.h"
 #include "nsIDragService.h"
 #include "nsIFormControl.h"
@@ -4452,29 +4452,30 @@ nsContentUtils::GetEventMessageAndAtomFo
 
 static
 nsresult GetEventAndTarget(nsIDocument* aDoc, nsISupports* aTarget,
                            const nsAString& aEventName,
                            bool aCanBubble, bool aCancelable,
                            bool aTrusted, nsIDOMEvent** aEvent,
                            EventTarget** aTargetOut)
 {
-  nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(aDoc);
   nsCOMPtr<EventTarget> target(do_QueryInterface(aTarget));
-  NS_ENSURE_TRUE(domDoc && target, NS_ERROR_INVALID_ARG);
-
-  nsCOMPtr<nsIDOMEvent> event;
-  nsresult rv =
-    domDoc->CreateEvent(NS_LITERAL_STRING("Events"), getter_AddRefs(event));
-  NS_ENSURE_SUCCESS(rv, rv);
+  NS_ENSURE_TRUE(aDoc && target, NS_ERROR_INVALID_ARG);
+
+  ErrorResult err;
+  RefPtr<Event> event = aDoc->CreateEvent(NS_LITERAL_STRING("Events"),
+                                          CallerType::System, err);
+  if (NS_WARN_IF(err.Failed())) {
+    return err.StealNSResult();
+  }
 
   event->InitEvent(aEventName, aCanBubble, aCancelable);
   event->SetTrusted(aTrusted);
 
-  rv = event->SetTarget(target);
+  nsresult rv = event->SetTarget(target);
   NS_ENSURE_SUCCESS(rv, rv);
 
   event.forget(aEvent);
   target.forget(aTargetOut);
   return NS_OK;
 }
 
 // static
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -148,17 +148,16 @@
 #include "nsCCUncollectableMarker.h"
 #include "nsIContentPolicy.h"
 #include "nsContentPolicyUtils.h"
 #include "nsICategoryManager.h"
 #include "nsIDocumentLoaderFactory.h"
 #include "nsIDocumentLoader.h"
 #include "nsIContentViewer.h"
 #include "nsIXMLContentSink.h"
-#include "nsIXULDocument.h"
 #include "nsIPrompt.h"
 #include "nsIPropertyBag2.h"
 #include "mozilla/dom/PageTransitionEvent.h"
 #include "mozilla/dom/StyleRuleChangeEvent.h"
 #include "mozilla/dom/StyleSheetChangeEvent.h"
 #include "mozilla/dom/StyleSheetApplicableStateChangeEvent.h"
 #include "nsJSUtils.h"
 #include "nsFrameLoader.h"
@@ -982,18 +981,17 @@ nsExternalResourceMap::AddExternalResour
 
   nsresult rv = NS_OK;
 
   nsCOMPtr<nsIDocument> doc;
   if (aViewer) {
     doc = aViewer->GetDocument();
     NS_ASSERTION(doc, "Must have a document");
 
-    nsCOMPtr<nsIXULDocument> xulDoc = do_QueryInterface(doc);
-    if (xulDoc) {
+    if (doc->IsXULDocument()) {
       // We don't handle XUL stuff here yet.
       rv = NS_ERROR_NOT_AVAILABLE;
     } else {
       doc->SetDisplayDocument(aDisplayDocument);
 
       // Make sure that hiding our viewer will tear down its presentation.
       aViewer->SetSticky(false);
 
@@ -3105,23 +3103,16 @@ nsDocument::SetChromeXHRDocURI(nsIURI* a
 }
 
 void
 nsDocument::SetChromeXHRDocBaseURI(nsIURI* aURI)
 {
   mChromeXHRDocBaseURI = aURI;
 }
 
-NS_IMETHODIMP
-nsDocument::GetLastModified(nsAString& aLastModified)
-{
-  nsIDocument::GetLastModified(aLastModified);
-  return NS_OK;
-}
-
 static void
 GetFormattedTimeString(PRTime aTime, nsAString& aFormattedTimeString)
 {
   PRExplodedTime prtime;
   PR_ExplodeTime(aTime, PR_LocalTimeParameters, &prtime);
   // "MM/DD/YYYY hh:mm:ss"
   char formatedTime[24];
   if (SprintfLiteral(formatedTime, "%02d/%02d/%04d %02d:%02d:%02d",
@@ -3336,22 +3327,20 @@ nsDocument::GetApplicationCache(nsIAppli
 NS_IMETHODIMP
 nsDocument::SetApplicationCache(nsIApplicationCache *aApplicationCache)
 {
   mApplicationCache = aApplicationCache;
 
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsDocument::GetContentType(nsAString& aContentType)
+void
+nsIDocument::GetContentType(nsAString& aContentType)
 {
   CopyUTF8toUTF16(GetContentTypeInternal(), aContentType);
-
-  return NS_OK;
 }
 
 void
 nsDocument::SetContentType(const nsAString& aContentType)
 {
   SetContentTypeInternal(NS_ConvertUTF16toUTF8(aContentType));
 }
 
@@ -3442,24 +3431,16 @@ nsIDocument::GetSVGRootElement() const
   if (!root || !root->IsSVGElement(nsGkAtoms::svg)) {
     return nullptr;
   }
   return static_cast<SVGSVGElement*>(root);
 }
 
 /* Return true if the document is in the focused top-level window, and is an
  * ancestor of the focused DOMWindow. */
-NS_IMETHODIMP
-nsDocument::HasFocus(bool* aResult)
-{
-  ErrorResult rv;
-  *aResult = nsIDocument::HasFocus(rv);
-  return rv.StealNSResult();
-}
-
 bool
 nsIDocument::HasFocus(ErrorResult& rv) const
 {
   nsIFocusManager* fm = nsFocusManager::GetFocusManager();
   if (!fm) {
     rv.Throw(NS_ERROR_NOT_AVAILABLE);
     return false;
   }
@@ -3495,23 +3476,16 @@ void
 nsIDocument::SetLastFocusTime(const TimeStamp& aFocusTime)
 {
   MOZ_DIAGNOSTIC_ASSERT(!aFocusTime.IsNull());
   MOZ_DIAGNOSTIC_ASSERT(mLastFocusTime.IsNull() ||
                         aFocusTime >= mLastFocusTime);
   mLastFocusTime = aFocusTime;
 }
 
-NS_IMETHODIMP
-nsDocument::GetReferrer(nsAString& aReferrer)
-{
-  nsIDocument::GetReferrer(aReferrer);
-  return NS_OK;
-}
-
 void
 nsIDocument::GetReferrer(nsAString& aReferrer) const
 {
   if (mIsSrcdocDocument && mParentDocument)
       mParentDocument->GetReferrer(aReferrer);
   else
     CopyUTF8toUTF16(mReferrer, aReferrer);
 }
@@ -3524,24 +3498,16 @@ nsIDocument::GetSrcdocData(nsAString &aS
     if (inStrmChan) {
       return inStrmChan->GetSrcdocData(aSrcdocData);
     }
   }
   aSrcdocData = VoidString();
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsDocument::GetActiveElement(nsIDOMElement **aElement)
-{
-  nsCOMPtr<nsIDOMElement> el(do_QueryInterface(nsIDocument::GetActiveElement()));
-  el.forget(aElement);
-  return NS_OK;
-}
-
 Element*
 nsIDocument::GetActiveElement()
 {
   // Get the focused element.
   Element* focusedElement = GetRetargetedFocusedElement();
   if (focusedElement) {
     return focusedElement;
   }
@@ -3553,40 +3519,23 @@ nsIDocument::GetActiveElement()
     // a body.
     return htmlDoc->GetBody();
   }
 
   // If we couldn't get a BODY, return the root element.
   return GetDocumentElement();
 }
 
-NS_IMETHODIMP
-nsDocument::GetCurrentScript(nsIDOMElement **aElement)
-{
-  nsCOMPtr<nsIDOMElement> el(do_QueryInterface(nsIDocument::GetCurrentScript()));
-  el.forget(aElement);
-  return NS_OK;
-}
-
 Element*
 nsIDocument::GetCurrentScript()
 {
   nsCOMPtr<Element> el(do_QueryInterface(ScriptLoader()->GetCurrentScript()));
   return el;
 }
 
-NS_IMETHODIMP
-nsDocument::ElementFromPoint(float aX, float aY, nsIDOMElement** aReturn)
-{
-  Element* el = nsIDocument::ElementFromPoint(aX, aY);
-  nsCOMPtr<nsIDOMElement> retval = do_QueryInterface(el);
-  retval.forget(aReturn);
-  return NS_OK;
-}
-
 Element*
 nsIDocument::ElementFromPoint(float aX, float aY)
 {
   return ElementFromPointHelper(aX, aY, false, true);
 }
 
 void
 nsIDocument::ElementsFromPoint(float aX, float aY,
@@ -3746,24 +3695,16 @@ nsDocument::NodesFromRectHelper(float aX
       elements->AppendElement(node);
       lastAdded = node;
     }
   }
 
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsDocument::GetElementsByClassName(const nsAString& aClasses,
-                                   nsIDOMNodeList** aReturn)
-{
-  *aReturn = nsIDocument::GetElementsByClassName(aClasses).take();
-  return NS_OK;
-}
-
 void
 nsIDocument::ReleaseCapture() const
 {
   // only release the capture if the caller can access it. This prevents a
   // page from stopping a scrollbar grab for example.
   nsCOMPtr<nsINode> node = nsIPresShell::GetCapturingContent();
   if (node && nsContentUtils::CanCallerAccess(node)) {
     nsIPresShell::SetCapturingContent(nullptr, 0);
@@ -5067,18 +5008,18 @@ nsDocument::SetScriptGlobalObject(nsIScr
         bool allowDNSPrefetch;
         docShell->GetAllowDNSPrefetch(&allowDNSPrefetch);
         mAllowDNSPrefetch = allowDNSPrefetch;
       }
     }
 
     // If we are set in a window that is already focused we should remember this
     // as the time the document gained focus.
-    bool focused = false;
-    Unused << HasFocus(&focused);
+    IgnoredErrorResult ignored;
+    bool focused = HasFocus(ignored);
     if (focused) {
       SetLastFocusTime(TimeStamp::Now());
     }
   }
 
   // Remember the pointer to our window (or lack there of), to avoid
   // having to QI every time it's asked for.
   nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(mScriptGlobalObject);
@@ -5323,29 +5264,16 @@ nsDocument::BeginLoad()
 }
 
 void
 nsDocument::ReportEmptyGetElementByIdArg()
 {
   nsContentUtils::ReportEmptyGetElementByIdArg(this);
 }
 
-NS_IMETHODIMP
-nsDocument::GetElementById(const nsAString& aId, nsIDOMElement** aReturn)
-{
-  Element *content = GetElementById(aId);
-  if (content) {
-    return CallQueryInterface(content, aReturn);
-  }
-
-  *aReturn = nullptr;
-
-  return NS_OK;
-}
-
 Element*
 nsDocument::AddIDTargetObserver(nsAtom* aID, IDTargetObserver aObserver,
                                 void* aData, bool aForImage)
 {
   nsDependentAtomString id(aID);
 
   if (!CheckGetElementByIdArg(id))
     return nullptr;
@@ -5369,25 +5297,16 @@ nsDocument::RemoveIDTargetObserver(nsAto
   nsIdentifierMapEntry* entry = mIdentifierMap.GetEntry(aID);
   if (!entry) {
     return;
   }
 
   entry->RemoveContentChangeCallback(aObserver, aData, aForImage);
 }
 
-NS_IMETHODIMP
-nsDocument::MozSetImageElement(const nsAString& aImageElementId,
-                               nsIDOMElement* aImageElement)
-{
-  nsCOMPtr<Element> el = do_QueryInterface(aImageElement);
-  MozSetImageElement(aImageElementId, el);
-  return NS_OK;
-}
-
 void
 nsDocument::MozSetImageElement(const nsAString& aImageElementId,
                                Element* aElement)
 {
   if (aImageElementId.IsEmpty())
     return;
 
   // Hold a script blocker while calling SetImageElement since that can call
@@ -5472,22 +5391,21 @@ nsDocument::DispatchContentLoadedEvents(
 
   if (mParentDocument) {
     target_frame = mParentDocument->FindContentForSubDocument(this);
   }
 
   if (target_frame) {
     nsCOMPtr<nsIDocument> parent = mParentDocument;
     do {
-      nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(parent);
-
-      nsCOMPtr<nsIDOMEvent> event;
-      if (domDoc) {
-        domDoc->CreateEvent(NS_LITERAL_STRING("Events"),
-                            getter_AddRefs(event));
+      RefPtr<Event> event;
+      if (parent) {
+        IgnoredErrorResult ignored;
+        event = parent->CreateEvent(NS_LITERAL_STRING("Events"),
+                                    CallerType::System, ignored);
 
       }
 
       if (event) {
         event->InitEvent(NS_LITERAL_STRING("DOMFrameContentLoaded"), true,
                          true);
 
         event->SetTarget(target_frame);
@@ -5813,38 +5731,16 @@ nsIDocument::GetDoctype() const
        child = child->GetNextSibling()) {
     if (child->NodeType() == DOCUMENT_TYPE_NODE) {
       return static_cast<DocumentType*>(child);
     }
   }
   return nullptr;
 }
 
-NS_IMETHODIMP
-nsDocument::GetDoctype(nsIDOMDocumentType** aDoctype)
-{
-  MOZ_ASSERT(aDoctype);
-  nsCOMPtr<nsIDOMDocumentType> doctype = nsIDocument::GetDoctype();
-  doctype.forget(aDoctype);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDocument::GetImplementation(nsIDOMDOMImplementation** aImplementation)
-{
-  ErrorResult rv;
-  *aImplementation = GetImplementation(rv);
-  if (rv.Failed()) {
-    MOZ_ASSERT(!*aImplementation);
-    return rv.StealNSResult();
-  }
-  NS_ADDREF(*aImplementation);
-  return NS_OK;
-}
-
 DOMImplementation*
 nsDocument::GetImplementation(ErrorResult& rv)
 {
   if (!mDOMImplementation) {
     nsCOMPtr<nsIURI> uri;
     NS_NewURI(getter_AddRefs(uri), "about:blank");
     if (!uri) {
       rv.Throw(NS_ERROR_OUT_OF_MEMORY);
@@ -5859,45 +5755,16 @@ nsDocument::GetImplementation(ErrorResul
     }
     mDOMImplementation = new DOMImplementation(this,
       scriptObject ? scriptObject : GetScopeObject(), uri, uri);
   }
 
   return mDOMImplementation;
 }
 
-NS_IMETHODIMP
-nsDocument::GetDocumentElement(nsIDOMElement** aDocumentElement)
-{
-  NS_ENSURE_ARG_POINTER(aDocumentElement);
-
-  Element* root = GetRootElement();
-  if (root) {
-    return CallQueryInterface(root, aDocumentElement);
-  }
-
-  *aDocumentElement = nullptr;
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDocument::CreateElement(const nsAString& aTagName,
-                          nsIDOMElement** aReturn)
-{
-  *aReturn = nullptr;
-  ErrorResult rv;
-  ElementCreationOptionsOrString options;
-
-  options.SetAsString();
-  nsCOMPtr<Element> element = CreateElement(aTagName, options, rv);
-  NS_ENSURE_FALSE(rv.Failed(), rv.StealNSResult());
-  return CallQueryInterface(element, aReturn);
-}
-
 bool IsLowercaseASCII(const nsAString& aValue)
 {
   int32_t len = aValue.Length();
   for (int32_t i = 0; i < len; ++i) {
     char16_t c = aValue[i];
     if (!(0x0061 <= (c) && ((c) <= 0x007a))) {
       return false;
     }
@@ -5968,32 +5835,16 @@ nsDocument::CreateElement(const nsAStrin
 
   if (is) {
     elem->SetAttr(kNameSpaceID_None, nsGkAtoms::is, *is, true);
   }
 
   return elem.forget();
 }
 
-NS_IMETHODIMP
-nsDocument::CreateElementNS(const nsAString& aNamespaceURI,
-                            const nsAString& aQualifiedName,
-                            nsIDOMElement** aReturn)
-{
-  *aReturn = nullptr;
-  ElementCreationOptionsOrString options;
-
-  options.SetAsString();
-  ErrorResult rv;
-  nsCOMPtr<Element> element =
-    CreateElementNS(aNamespaceURI, aQualifiedName, options, rv);
-  NS_ENSURE_FALSE(rv.Failed(), rv.StealNSResult());
-  return CallQueryInterface(element, aReturn);
-}
-
 already_AddRefed<Element>
 nsDocument::CreateElementNS(const nsAString& aNamespaceURI,
                             const nsAString& aQualifiedName,
                             const ElementCreationOptionsOrString& aOptions,
                             ErrorResult& rv)
 {
   RefPtr<mozilla::dom::NodeInfo> nodeInfo;
   rv = nsContentUtils::GetNodeInfoFromQName(aNamespaceURI,
@@ -6023,83 +5874,50 @@ nsDocument::CreateElementNS(const nsAStr
 
   if (is) {
     element->SetAttr(kNameSpaceID_None, nsGkAtoms::is, *is, true);
   }
 
   return element.forget();
 }
 
-NS_IMETHODIMP
-nsDocument::CreateTextNode(const nsAString& aData, nsIDOMText** aReturn)
-{
-  *aReturn = nsIDocument::CreateTextNode(aData).take();
-  return NS_OK;
-}
-
 already_AddRefed<nsTextNode>
 nsIDocument::CreateEmptyTextNode() const
 {
   RefPtr<nsTextNode> text = new nsTextNode(mNodeInfoManager);
   return text.forget();
 }
 
 already_AddRefed<nsTextNode>
 nsIDocument::CreateTextNode(const nsAString& aData) const
 {
   RefPtr<nsTextNode> text = new nsTextNode(mNodeInfoManager);
   // Don't notify; this node is still being created.
   text->SetText(aData, false);
   return text.forget();
 }
 
-NS_IMETHODIMP
-nsDocument::CreateDocumentFragment(nsIDOMDocumentFragment** aReturn)
-{
-  *aReturn = nsIDocument::CreateDocumentFragment().take();
-  return NS_OK;
-}
-
 already_AddRefed<DocumentFragment>
 nsIDocument::CreateDocumentFragment() const
 {
   RefPtr<DocumentFragment> frag = new DocumentFragment(mNodeInfoManager);
   return frag.forget();
 }
 
-NS_IMETHODIMP
-nsDocument::CreateComment(const nsAString& aData, nsIDOMComment** aReturn)
-{
-  *aReturn = nsIDocument::CreateComment(aData).take();
-  return NS_OK;
-}
-
 // Unfortunately, bareword "Comment" is ambiguous with some Mac system headers.
 already_AddRefed<dom::Comment>
 nsIDocument::CreateComment(const nsAString& aData) const
 {
   RefPtr<dom::Comment> comment = new dom::Comment(mNodeInfoManager);
 
   // Don't notify; this node is still being created.
   comment->SetText(aData, false);
   return comment.forget();
 }
 
-NS_IMETHODIMP
-nsDocument::CreateCDATASection(const nsAString& aData,
-                               nsISupports** aReturn)
-{
-  NS_ENSURE_ARG_POINTER(aReturn);
-  ErrorResult rv;
-  already_AddRefed<CDATASection> supports =
-    nsIDocument::CreateCDATASection(aData, rv);
-  *aReturn = ToSupports(supports.take());
-  return rv.StealNSResult();
-}
-
 already_AddRefed<CDATASection>
 nsIDocument::CreateCDATASection(const nsAString& aData,
                                 ErrorResult& rv)
 {
   if (IsHTMLDocument()) {
     rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
     return nullptr;
   }
@@ -6112,27 +5930,16 @@ nsIDocument::CreateCDATASection(const ns
   RefPtr<CDATASection> cdata = new CDATASection(mNodeInfoManager);
 
   // Don't notify; this node is still being created.
   cdata->SetText(aData, false);
 
   return cdata.forget();
 }
 
-NS_IMETHODIMP
-nsDocument::CreateProcessingInstruction(const nsAString& aTarget,
-                                        const nsAString& aData,
-                                        nsIDOMProcessingInstruction** aReturn)
-{
-  ErrorResult rv;
-  *aReturn =
-    nsIDocument::CreateProcessingInstruction(aTarget, aData, rv).take();
-  return rv.StealNSResult();
-}
-
 already_AddRefed<ProcessingInstruction>
 nsIDocument::CreateProcessingInstruction(const nsAString& aTarget,
                                          const nsAString& aData,
                                          ErrorResult& rv) const
 {
   nsresult res = nsContentUtils::CheckQName(aTarget, false);
   if (NS_FAILED(res)) {
     rv.Throw(res);
@@ -6228,28 +6035,16 @@ nsDocument::ResolveScheduledSVGPresAttrs
 {
   for (auto iter = mLazySVGPresElements.Iter(); !iter.Done(); iter.Next()) {
     nsSVGElement* svg = iter.Get()->GetKey();
     svg->UpdateContentDeclarationBlock(StyleBackendType::Servo);
   }
   mLazySVGPresElements.Clear();
 }
 
-NS_IMETHODIMP
-nsDocument::GetElementsByTagName(const nsAString& aTagname,
-                                 nsIDOMNodeList** aReturn)
-{
-  RefPtr<nsContentList> list = GetElementsByTagName(aTagname);
-  NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY);
-
-  // transfer ref to aReturn
-  list.forget(aReturn);
-  return NS_OK;
-}
-
 long
 nsDocument::BlockedTrackingNodeCount() const
 {
   return mBlockedTrackingNodes.Length();
 }
 
 already_AddRefed<nsSimpleContentList>
 nsDocument::BlockedTrackingNodes() const
@@ -6268,40 +6063,16 @@ nsDocument::BlockedTrackingNodes() const
     if (node) {
       list->AppendElement(node);
     }
   }
 
   return list.forget();
 }
 
-NS_IMETHODIMP
-nsDocument::GetElementsByTagNameNS(const nsAString& aNamespaceURI,
-                                   const nsAString& aLocalName,
-                                   nsIDOMNodeList** aReturn)
-{
-  ErrorResult rv;
-  RefPtr<nsContentList> list =
-    GetElementsByTagNameNS(aNamespaceURI, aLocalName, rv);
-  if (rv.Failed()) {
-    return rv.StealNSResult();
-  }
-
-  // transfer ref to aReturn
-  list.forget(aReturn);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDocument::GetMozSelectedStyleSheetSet(nsAString& aSheetSet)
-{
-  nsIDocument::GetSelectedStyleSheetSet(aSheetSet);
-  return NS_OK;
-}
-
 void
 nsIDocument::GetSelectedStyleSheetSet(nsAString& aSheetSet)
 {
   aSheetSet.Truncate();
 
   // Look through our sheets, find the selected set title
   size_t count = SheetCount();
   nsAutoString title;
@@ -6321,87 +6092,50 @@ nsIDocument::GetSelectedStyleSheetSet(ns
     } else if (!title.IsEmpty() && !aSheetSet.Equals(title)) {
       // Sheets from multiple sets enabled; return null string, per spec.
       SetDOMStringToNull(aSheetSet);
       return;
     }
   }
 }
 
-NS_IMETHODIMP
-nsDocument::SetMozSelectedStyleSheetSet(const nsAString& aSheetSet)
-{
-  SetSelectedStyleSheetSet(aSheetSet);
-  return NS_OK;
-}
-
 void
 nsDocument::SetSelectedStyleSheetSet(const nsAString& aSheetSet)
 {
   if (DOMStringIsNull(aSheetSet)) {
     return;
   }
 
   // Must update mLastStyleSheetSet before doing anything else with stylesheets
   // or CSSLoaders.
   mLastStyleSheetSet = aSheetSet;
   EnableStyleSheetsForSetInternal(aSheetSet, true);
 }
 
-NS_IMETHODIMP
+void
 nsDocument::GetLastStyleSheetSet(nsAString& aSheetSet)
 {
-  nsString sheetSet;
-  GetLastStyleSheetSet(sheetSet);
-  aSheetSet = sheetSet;
-  return NS_OK;
-}
-
-void
-nsDocument::GetLastStyleSheetSet(nsString& aSheetSet)
-{
   aSheetSet = mLastStyleSheetSet;
 }
 
-NS_IMETHODIMP
-nsDocument::GetPreferredStyleSheetSet(nsAString& aSheetSet)
-{
-  nsIDocument::GetPreferredStyleSheetSet(aSheetSet);
-  return NS_OK;
-}
-
 void
 nsIDocument::GetPreferredStyleSheetSet(nsAString& aSheetSet)
 {
   GetHeaderData(nsGkAtoms::headerDefaultStyle, aSheetSet);
 }
 
-NS_IMETHODIMP
-nsDocument::GetStyleSheetSets(nsISupports** aList)
-{
-  NS_ADDREF(*aList = StyleSheetSets());
-  return NS_OK;
-}
-
 DOMStringList*
 nsDocument::StyleSheetSets()
 {
   if (!mStyleSheetSetList) {
     mStyleSheetSetList = new nsDOMStyleSheetSetList(this);
   }
   return mStyleSheetSetList;
 }
 
-NS_IMETHODIMP
-nsDocument::MozEnableStyleSheetsForSet(const nsAString& aSheetSet)
-{
-  EnableStyleSheetsForSet(aSheetSet);
-  return NS_OK;
-}
-
 void
 nsDocument::EnableStyleSheetsForSet(const nsAString& aSheetSet)
 {
   // Per spec, passing in null is a no-op.
   if (!DOMStringIsNull(aSheetSet)) {
     // Note: must make sure to not change the CSSLoader's preferred sheet --
     // that value should be equal to either our lastStyleSheetSet (if that's
     // non-null) or to our preferredStyleSheetSet.  And this method doesn't
@@ -6427,23 +6161,16 @@ nsDocument::EnableStyleSheetsForSetInter
     }
   }
   if (aUpdateCSSLoader) {
     CSSLoader()->SetPreferredSheet(aSheetSet);
   }
   EndUpdate(UPDATE_STYLE);
 }
 
-NS_IMETHODIMP
-nsDocument::GetCharacterSet(nsAString& aCharacterSet)
-{
-  nsIDocument::GetCharacterSet(aCharacterSet);
-  return NS_OK;
-}
-
 void
 nsIDocument::GetCharacterSet(nsAString& aCharacterSet) const
 {
   nsAutoCString charset;
   GetDocumentCharacterSet()->Name(charset);
   CopyASCIItoUTF16(charset, aCharacterSet);
 }
 
@@ -6636,64 +6363,29 @@ nsDocument::GetAnonymousNodes(nsIDOMElem
 }
 
 nsINodeList*
 nsIDocument::GetAnonymousNodes(Element& aElement)
 {
   return BindingManager()->GetAnonymousNodesFor(&aElement);
 }
 
-NS_IMETHODIMP
-nsDocument::CreateRange(nsIDOMRange** aReturn)
-{
-  ErrorResult rv;
-  *aReturn = nsIDocument::CreateRange(rv).take();
-  return rv.StealNSResult();
-}
-
 already_AddRefed<nsRange>
 nsIDocument::CreateRange(ErrorResult& rv)
 {
   RefPtr<nsRange> range = new nsRange(this);
   nsresult res = range->CollapseTo(this, 0);
   if (NS_FAILED(res)) {
     rv.Throw(res);
     return nullptr;
   }
 
   return range.forget();
 }
 
-NS_IMETHODIMP
-nsDocument::CreateNodeIterator(nsIDOMNode *aRoot,
-                               uint32_t aWhatToShow,
-                               nsIDOMNodeFilter *aFilter,
-                               uint8_t aOptionalArgc,
-                               nsIDOMNodeIterator **_retval)
-{
-  *_retval = nullptr;
-
-  if (!aOptionalArgc) {
-    aWhatToShow = nsIDOMNodeFilter::SHOW_ALL;
-  }
-
-  if (!aRoot) {
-    return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
-  }
-
-  nsCOMPtr<nsINode> root = do_QueryInterface(aRoot);
-  NS_ENSURE_TRUE(root, NS_ERROR_UNEXPECTED);
-
-  ErrorResult rv;
-  *_retval = nsIDocument::CreateNodeIterator(*root, aWhatToShow,
-                                             NodeFilterHolder(aFilter),
-                                             rv).take();
-  return rv.StealNSResult();
-}
-
 already_AddRefed<NodeIterator>
 nsIDocument::CreateNodeIterator(nsINode& aRoot, uint32_t aWhatToShow,
                                 NodeFilter* aFilter,
                                 ErrorResult& rv) const
 {
   return CreateNodeIterator(aRoot, aWhatToShow, NodeFilterHolder(aFilter), rv);
 }
 
@@ -6703,39 +6395,16 @@ nsIDocument::CreateNodeIterator(nsINode&
                                 ErrorResult& rv) const
 {
   nsINode* root = &aRoot;
   RefPtr<NodeIterator> iterator = new NodeIterator(root, aWhatToShow,
                                                    Move(aFilter));
   return iterator.forget();
 }
 
-NS_IMETHODIMP
-nsDocument::CreateTreeWalker(nsIDOMNode *aRoot,
-                             uint32_t aWhatToShow,
-                             nsIDOMNodeFilter *aFilter,
-                             uint8_t aOptionalArgc,
-                             nsIDOMTreeWalker **_retval)
-{
-  *_retval = nullptr;
-
-  if (!aOptionalArgc) {
-    aWhatToShow = nsIDOMNodeFilter::SHOW_ALL;
-  }
-
-  nsCOMPtr<nsINode> root = do_QueryInterface(aRoot);
-  NS_ENSURE_TRUE(root, NS_ERROR_DOM_NOT_SUPPORTED_ERR);
-
-  ErrorResult rv;
-  *_retval = nsIDocument::CreateTreeWalker(*root, aWhatToShow,
-                                           NodeFilterHolder(aFilter),
-                                           rv).take();
-  return rv.StealNSResult();
-}
-
 already_AddRefed<TreeWalker>
 nsIDocument::CreateTreeWalker(nsINode& aRoot, uint32_t aWhatToShow,
                               NodeFilter* aFilter,
                               ErrorResult& rv) const
 {
   return CreateTreeWalker(aRoot, aWhatToShow, NodeFilterHolder(aFilter), rv);
 }
 
@@ -6744,25 +6413,16 @@ nsIDocument::CreateTreeWalker(nsINode& a
                               NodeFilterHolder aFilter, ErrorResult& rv) const
 {
   nsINode* root = &aRoot;
   RefPtr<TreeWalker> walker = new TreeWalker(root, aWhatToShow, Move(aFilter));
   return walker.forget();
 }
 
 
-NS_IMETHODIMP
-nsDocument::GetDefaultView(mozIDOMWindowProxy** aDefaultView)
-{
-  *aDefaultView = nullptr;
-  nsCOMPtr<nsPIDOMWindowOuter> win = GetWindow();
-  win.forget(aDefaultView);
-  return NS_OK;
-}
-
 already_AddRefed<Location>
 nsIDocument::GetLocation() const
 {
   nsCOMPtr<nsPIDOMWindowInner> w = do_QueryInterface(mScriptGlobalObject);
 
   if (!w) {
     return nullptr;
   }
@@ -6874,28 +6534,19 @@ nsDocument::GetTitleElement()
                                                  /* aDeep = */ true,
                                                  /* aLiveList = */ false);
 
   nsIContent* first = list->Item(0, false);
 
   return first ? first->AsElement() : nullptr;
 }
 
-NS_IMETHODIMP
+void
 nsDocument::GetTitle(nsAString& aTitle)
 {
-  nsString title;
-  GetTitle(title);
-  aTitle = title;
-  return NS_OK;
-}
-
-void
-nsDocument::GetTitle(nsString& aTitle)
-{
   aTitle.Truncate();
 
   Element* rootElement = GetRootElement();
   if (!rootElement) {
     return;
   }
 
   nsAutoString tmp;
@@ -6912,28 +6563,29 @@ nsDocument::GetTitle(nsString& aTitle)
     }
     nsContentUtils::GetNodeTextContent(title, false, tmp);
   }
 
   tmp.CompressWhitespace();
   aTitle = tmp;
 }
 
-NS_IMETHODIMP
-nsDocument::SetTitle(const nsAString& aTitle)
+void
+nsDocument::SetTitle(const nsAString& aTitle, ErrorResult& aRv)
 {
   Element* rootElement = GetRootElement();
   if (!rootElement) {
-    return NS_OK;
+    return;
   }
 
 #ifdef MOZ_XUL
   if (rootElement->IsXULElement()) {
-    return rootElement->SetAttr(kNameSpaceID_None, nsGkAtoms::title,
-                                aTitle, true);
+    aRv = rootElement->SetAttr(kNameSpaceID_None, nsGkAtoms::title,
+                               aTitle, true);
+    return;
   }
 #endif
 
   // Batch updates so that mutation events don't change "the title
   // element" under us
   mozAutoDocUpdate updateBatch(this, UPDATE_CONTENT_MODEL, true);
 
   nsCOMPtr<Element> title = GetTitleElement();
@@ -6941,48 +6593,42 @@ nsDocument::SetTitle(const nsAString& aT
     if (!title) {
       RefPtr<mozilla::dom::NodeInfo> titleInfo =
         mNodeInfoManager->GetNodeInfo(nsGkAtoms::title, nullptr,
                                       kNameSpaceID_SVG,
                                       ELEMENT_NODE);
       NS_NewSVGElement(getter_AddRefs(title), titleInfo.forget(),
                        NOT_FROM_PARSER);
       if (!title) {
-        return NS_OK;
+        return;
       }
       rootElement->InsertChildBefore(title, rootElement->GetFirstChild(), true);
     }
   } else if (rootElement->IsHTMLElement()) {
     if (!title) {
       Element* head = GetHeadElement();
       if (!head) {
-        return NS_OK;
+        return;
       }
 
       RefPtr<mozilla::dom::NodeInfo> titleInfo;
       titleInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::title, nullptr,
           kNameSpaceID_XHTML, ELEMENT_NODE);
       title = NS_NewHTMLTitleElement(titleInfo.forget());
       if (!title) {
-        return NS_OK;
+        return;
       }
 
       head->AppendChildTo(title, true);
     }
   } else {
-    return NS_OK;
-  }
-
-  return nsContentUtils::SetNodeTextContent(title, aTitle, false);
-}
-
-void
-nsDocument::SetTitle(const nsAString& aTitle, ErrorResult& rv)
-{
-  rv = SetTitle(aTitle);
+    return;
+  }
+
+  aRv = nsContentUtils::SetNodeTextContent(title, aTitle, false);
 }
 
 void
 nsDocument::NotifyPossibleTitleChange(bool aBoundTitleElement)
 {
   NS_ASSERTION(!mInUnlinkOrDeletion || !aBoundTitleElement,
                "Setting a title while unlinking or destroying the element?");
   if (mInUnlinkOrDeletion) {
@@ -7300,45 +6946,31 @@ nsDocument::GetOrCreatePendingAnimationT
   return mPendingAnimationTracker;
 }
 
 /**
  * Retrieve the "direction" property of the document.
  *
  * @lina 01/09/2001
  */
-NS_IMETHODIMP
-nsDocument::GetDir(nsAString& aDirection)
-{
-  nsIDocument::GetDir(aDirection);
-  return NS_OK;
-}
-
 void
 nsIDocument::GetDir(nsAString& aDirection) const
 {
   aDirection.Truncate();
   Element* rootElement = GetHtmlElement();
   if (rootElement) {
     static_cast<nsGenericHTMLElement*>(rootElement)->GetDir(aDirection);
   }
 }
 
 /**
  * Set the "direction" property of the document.
  *
  * @lina 01/09/2001
  */
-NS_IMETHODIMP
-nsDocument::SetDir(const nsAString& aDirection)
-{
-  nsIDocument::SetDir(aDirection);
-  return NS_OK;
-}
-
 void
 nsIDocument::SetDir(const nsAString& aDirection)
 {
   Element* rootElement = GetHtmlElement();
   if (rootElement) {
     rootElement->SetAttr(kNameSpaceID_None, nsGkAtoms::dir,
                          aDirection, true);
   }
@@ -7364,39 +6996,16 @@ nsIDocument::MatchNameAttribute(Element*
 
 /* static */
 void*
 nsIDocument::UseExistingNameString(nsINode* aRootNode, const nsString* aName)
 {
   return const_cast<nsString*>(aName);
 }
 
-NS_IMETHODIMP
-nsDocument::GetInputEncoding(nsAString& aInputEncoding)
-{
-  nsIDocument::GetCharacterSet(aInputEncoding);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDocument::GetMozSyntheticDocument(bool *aSyntheticDocument)
-{
-  *aSyntheticDocument = mIsSyntheticDocument;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDocument::GetDocumentURI(nsAString& aDocumentURI)
-{
-  nsString temp;
-  nsresult rv = nsIDocument::GetDocumentURI(temp);
-  aDocumentURI = temp;
-  return rv;
-}
-
 nsresult
 nsIDocument::GetDocumentURI(nsString& aDocumentURI) const
 {
   if (mDocumentURI) {
     nsAutoCString uri;
     nsresult rv = mDocumentURI->GetSpec(uri);
     NS_ENSURE_SUCCESS(rv, rv);
 
@@ -7404,22 +7013,16 @@ nsIDocument::GetDocumentURI(nsString& aD
   } else {
     aDocumentURI.Truncate();
   }
 
   return NS_OK;
 }
 
 // Alias of above
-NS_IMETHODIMP
-nsDocument::GetURL(nsAString& aURL)
-{
-  return GetDocumentURI(aURL);
-}
-
 nsresult
 nsIDocument::GetURL(nsString& aURL) const
 {
   return GetDocumentURI(aURL);
 }
 
 void
 nsIDocument::GetDocumentURIFromJS(nsString& aDocumentURI, CallerType aCallerType,
@@ -7853,21 +7456,20 @@ nsDocument::GetViewportInfo(const Screen
                           /*allowZoom*/ true);
   case Unknown:
   {
     nsAutoString viewport;
     GetHeaderData(nsGkAtoms::viewport, viewport);
     if (viewport.IsEmpty()) {
       // If the docType specifies that we are on a site optimized for mobile,
       // then we want to return specially crafted defaults for the viewport info.
-      nsCOMPtr<nsIDOMDocumentType> docType;
-      nsresult rv = GetDoctype(getter_AddRefs(docType));
-      if (NS_SUCCEEDED(rv) && docType) {
+      RefPtr<DocumentType> docType = GetDoctype();
+      if (docType) {
         nsAutoString docId;
-        rv = docType->GetPublicId(docId);
+        nsresult rv = docType->GetPublicId(docId);
         if (NS_SUCCEEDED(rv)) {
           if ((docId.Find("WAP") != -1) ||
               (docId.Find("Mobile") != -1) ||
               (docId.Find("WML") != -1))
           {
             // We're making an assumption that the docType can't change here
             mViewportType = DisplayWidthHeight;
             return nsViewportInfo(aDisplaySize,
@@ -8080,26 +7682,16 @@ nsDocument::GetEventTargetParent(EventCh
   if (aVisitor.mEvent->mMessage != eLoad) {
     nsGlobalWindowOuter* window = nsGlobalWindowOuter::Cast(GetWindow());
     aVisitor.SetParentTarget(
       window ? window->GetTargetForEventTargetChain() : nullptr, false);
   }
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsDocument::CreateEvent(const nsAString& aEventType, nsIDOMEvent** aReturn)
-{
-  NS_ENSURE_ARG_POINTER(aReturn);
-  ErrorResult rv;
-  *aReturn = nsIDocument::CreateEvent(aEventType, CallerType::System,
-                                      rv).take();
-  return rv.StealNSResult();
-}
-
 already_AddRefed<Event>
 nsIDocument::CreateEvent(const nsAString& aEventType, CallerType aCallerType,
                          ErrorResult& rv) const
 {
   nsIPresShell *shell = GetShell();
 
   nsPresContext *presContext = nullptr;
 
@@ -9502,23 +9094,16 @@ nsDocument::SetReadyStateInternal(ReadyS
   RecordNavigationTiming(rs);
 
   RefPtr<AsyncEventDispatcher> asyncDispatcher =
     new AsyncEventDispatcher(this, NS_LITERAL_STRING("readystatechange"),
                              false, false);
   asyncDispatcher->RunDOMEventWhenSafe();
 }
 
-NS_IMETHODIMP
-nsDocument::GetReadyState(nsAString& aReadyState)
-{
-  nsIDocument::GetReadyState(aReadyState);
-  return NS_OK;
-}
-
 void
 nsIDocument::GetReadyState(nsAString& aReadyState) const
 {
   switch(mReadyState) {
   case READYSTATE_LOADING :
     aReadyState.AssignLiteral(u"loading");
     break;
   case READYSTATE_INTERACTIVE :
@@ -10613,24 +10198,16 @@ nsIDocument::CaretPositionFromPoint(floa
 
   RefPtr<nsDOMCaretPosition> aCaretPos = new nsDOMCaretPosition(node, offset);
   if (nodeIsAnonymous) {
     aCaretPos->SetAnonymousContentNode(anonNode);
   }
   return aCaretPos.forget();
 }
 
-NS_IMETHODIMP
-nsDocument::CaretPositionFromPoint(float aX, float aY, nsISupports** aCaretPos)
-{
-  NS_ENSURE_ARG_POINTER(aCaretPos);
-  *aCaretPos = nsIDocument::CaretPositionFromPoint(aX, aY).take();
-  return NS_OK;
-}
-
 bool
 nsIDocument::IsPotentiallyScrollable(HTMLBodyElement* aBody)
 {
   // We rely on correct frame information here, so need to flush frames.
   FlushPendingNotifications(FlushType::Frames);
 
   // An element is potentially scrollable if all of the following conditions are
   // true:
@@ -12369,32 +11946,16 @@ nsDocument::MaybeActiveMediaComponents()
 {
   if (!mWindow) {
     return;
   }
 
   GetWindow()->MaybeActiveMediaComponents();
 }
 
-NS_IMETHODIMP
-nsDocument::GetHidden(bool* aHidden)
-{
-  *aHidden = Hidden();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDocument::GetVisibilityState(nsAString& aState)
-{
-  const EnumEntry& entry =
-    VisibilityStateValues::strings[static_cast<int>(mVisibilityState)];
-  aState.AssignASCII(entry.value, entry.length);
-  return NS_OK;
-}
-
 /* virtual */ void
 nsIDocument::DocAddSizeOfExcludingThis(nsWindowSizes& aSizes) const
 {
   nsINode::AddSizeOfExcludingThis(aSizes, &aSizes.mDOMOtherSize);
 
   if (mPresShell) {
     mPresShell->AddSizeOfIncludingThis(aSizes);
   }
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -373,22 +373,16 @@ public:
   virtual already_AddRefed<nsIParser> CreatorParserOrNull() override;
 
   /**
    * Set the principal responsible for this document.
    */
   virtual void SetPrincipal(nsIPrincipal *aPrincipal) override;
 
   /**
-   * Get the Content-Type of this document.
-   */
-  // NS_IMETHOD GetContentType(nsAString& aContentType);
-  // Already declared in nsIDOMDocument
-
-  /**
    * Set the Content-Type of this document.
    */
   virtual void SetContentType(const nsAString& aContentType) override;
 
   virtual void SetBaseURI(nsIURI* aURI) override;
 
   /**
    * Get/Set the base target of a link in a document.
@@ -954,17 +948,17 @@ public:
 
   virtual nsIDOMNode* AsDOMNode() override { return this; }
 
   // WebIDL bits
   virtual mozilla::dom::DOMImplementation*
     GetImplementation(mozilla::ErrorResult& rv) override;
 
   virtual void SetSelectedStyleSheetSet(const nsAString& aSheetSet) override;
-  virtual void GetLastStyleSheetSet(nsString& aSheetSet) override;
+  virtual void GetLastStyleSheetSet(nsAString& aSheetSet) override;
   virtual mozilla::dom::DOMStringList* StyleSheetSets() override;
   virtual void EnableStyleSheetsForSet(const nsAString& aSheetSet) override;
   virtual already_AddRefed<Element> CreateElement(const nsAString& aTagName,
                                                   const mozilla::dom::ElementCreationOptionsOrString& aOptions,
                                                   ErrorResult& rv) override;
   virtual already_AddRefed<Element> CreateElementNS(const nsAString& aNamespaceURI,
                                                     const nsAString& aQualifiedName,
                                                     const mozilla::dom::ElementCreationOptionsOrString& aOptions,
@@ -1030,17 +1024,17 @@ protected:
    * element is an <svg:svg>, this is the first <svg:title> element that's a
    * child of the root.  For other documents, it's the first HTML title element
    * in the document.
    */
   Element* GetTitleElement();
 
 public:
   // Get our title
-  virtual void GetTitle(nsString& aTitle) override;
+  virtual void GetTitle(nsAString& aTitle) override;
   // Set our title
   virtual void SetTitle(const nsAString& aTitle, mozilla::ErrorResult& rv) override;
 
   js::ExpandoAndGeneration mExpandoAndGeneration;
 
   bool ContainsEMEContent();
 
   bool ContainsMSEContent();
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -15,17 +15,16 @@
 
 #include "nsDocShell.h"
 #include "nsIDOMMozBrowserFrame.h"
 #include "nsIDOMWindow.h"
 #include "nsIPresShell.h"
 #include "nsIContentInlines.h"
 #include "nsIContentViewer.h"
 #include "nsIDocument.h"
-#include "nsIDOMDocument.h"
 #include "nsPIDOMWindow.h"
 #include "nsIWebNavigation.h"
 #include "nsIWebProgress.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeOwner.h"
 #include "nsIDocShellLoadInfo.h"
 #include "nsIBaseWindow.h"
 #include "nsIBrowser.h"
@@ -2979,19 +2978,18 @@ nsFrameLoader::CreateStaticClone(nsIFram
   nsCOMPtr<nsIDocShell> origDocShell;
   GetDocShell(getter_AddRefs(origDocShell));
   NS_ENSURE_STATE(origDocShell);
 
   nsCOMPtr<nsIDocument> doc = origDocShell->GetDocument();
   NS_ENSURE_STATE(doc);
 
   nsCOMPtr<nsIDocument> clonedDoc = doc->CreateStaticClone(dest->mDocShell);
-  nsCOMPtr<nsIDOMDocument> clonedDOMDoc = do_QueryInterface(clonedDoc);
-
-  viewer->SetDOMDocument(clonedDOMDoc);
+
+  viewer->SetDocument(clonedDoc);
   return NS_OK;
 }
 
 bool
 nsFrameLoader::DoLoadMessageManagerScript(const nsAString& aURL, bool aRunInGlobalScope)
 {
   auto* tabParent = TabParent::GetFrom(GetRemoteBrowser());
   if (tabParent) {
--- a/dom/base/nsGlobalWindowInner.cpp
+++ b/dom/base/nsGlobalWindowInner.cpp
@@ -177,20 +177,16 @@
 #include "nsIPrintSettingsService.h"
 #include "nsIWebBrowserPrint.h"
 #endif
 
 #include "nsWindowRoot.h"
 #include "nsNetCID.h"
 #include "nsIArray.h"
 
-// XXX An unfortunate dependency exists here (two XUL files).
-#include "nsIDOMXULDocument.h"
-#include "nsIDOMXULCommandDispatcher.h"
-
 #include "nsBindingManager.h"
 #include "nsXBLService.h"
 
 // used for popup blocking, needs to be converted to something
 // belonging to the back-end like nsIContentPolicy
 #include "nsIPopupWindowManager.h"
 
 #include "nsIDragService.h"
--- a/dom/base/nsGlobalWindowOuter.cpp
+++ b/dom/base/nsGlobalWindowOuter.cpp
@@ -175,18 +175,17 @@
 #include "nsIPrintSettingsService.h"
 #include "nsIWebBrowserPrint.h"
 #endif
 
 #include "nsWindowRoot.h"
 #include "nsNetCID.h"
 #include "nsIArray.h"
 
-// XXX An unfortunate dependency exists here (two XUL files).
-#include "nsIDOMXULDocument.h"
+#include "XULDocument.h"
 #include "nsIDOMXULCommandDispatcher.h"
 
 #include "nsBindingManager.h"
 #include "nsXBLService.h"
 
 // used for popup blocking, needs to be converted to something
 // belonging to the back-end like nsIContentPolicy
 #include "nsIPopupWindowManager.h"
@@ -6380,25 +6379,25 @@ nsGlobalWindowOuter::UpdateCommands(cons
     }
   }
 
   nsPIDOMWindowOuter *rootWindow = GetPrivateRoot();
   if (!rootWindow) {
     return;
   }
 
-  nsCOMPtr<nsIDOMXULDocument> xulDoc =
-    do_QueryInterface(rootWindow->GetExtantDoc());
+  nsIDocument* doc = rootWindow->GetExtantDoc();
+  XULDocument* xulDoc = doc ? doc->AsXULDocument() : nullptr;
   // See if we contain a XUL document.
   // selectionchange action is only used for mozbrowser, not for XUL. So we bypass
   // XUL command dispatch if anAction is "selectionchange".
   if (xulDoc && !anAction.EqualsLiteral("selectionchange")) {
     // Retrieve the command dispatcher and call updateCommands on it.
-    nsCOMPtr<nsIDOMXULCommandDispatcher> xulCommandDispatcher;
-    xulDoc->GetCommandDispatcher(getter_AddRefs(xulCommandDispatcher));
+    nsIDOMXULCommandDispatcher* xulCommandDispatcher =
+      xulDoc->GetCommandDispatcher();
     if (xulCommandDispatcher) {
       nsContentUtils::AddScriptRunner(new CommandDispatcher(xulCommandDispatcher,
                                                             anAction));
     }
   }
 }
 
 Selection*
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -41,16 +41,21 @@
 #include "mozilla/SegmentedVector.h"
 #include "mozilla/ServoBindingTypes.h"
 #include "mozilla/StyleBackendType.h"
 #include "mozilla/StyleSheet.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/UniquePtr.h"
 #include <bitset>                        // for member
 
+// windows.h #defines CreateEvent
+#ifdef CreateEvent
+#undef CreateEvent
+#endif
+
 #ifdef MOZILLA_INTERNAL_API
 #include "mozilla/dom/DocumentBinding.h"
 #else
 namespace mozilla {
 namespace dom {
 class ElementCreationOptionsOrString;
 } // namespace dom
 } // namespace mozilla
@@ -168,16 +173,17 @@ class SVGDocument;
 class SVGSVGElement;
 class Touch;
 class TouchList;
 class TreeWalker;
 class XPathEvaluator;
 class XPathExpression;
 class XPathNSResolver;
 class XPathResult;
+class XULDocument;
 template<typename> class Sequence;
 
 template<typename, typename> class CallbackObjectHolder;
 typedef CallbackObjectHolder<NodeFilter, nsIDOMNodeFilter> NodeFilterHolder;
 
 enum class CallerType : uint32_t;
 
 } // namespace dom
@@ -558,20 +564,18 @@ public:
    * Remove the (aObserver, aData, aForImage) triple for a specific ID, if
    * registered.
    */
   virtual void RemoveIDTargetObserver(nsAtom* aID, IDTargetObserver aObserver,
                                       void* aData, bool aForImage) = 0;
 
   /**
    * Get the Content-Type of this document.
-   * (This will always return NS_OK, but has this signature to be compatible
-   *  with nsIDOMDocument::GetContentType())
    */
-  NS_IMETHOD GetContentType(nsAString& aContentType) = 0;
+  void GetContentType(nsAString& aContentType);
 
   /**
    * Set the Content-Type of this document.
    */
   virtual void SetContentType(const nsAString& aContentType) = 0;
 
   /**
    * Return the language of this document.
@@ -2890,20 +2894,17 @@ public:
                       mozilla::ErrorResult& rv);
   void SetAllowUnsafeHTML(bool aAllow) { mAllowUnsafeHTML = aAllow; }
   bool AllowUnsafeHTML() const;
   void GetInputEncoding(nsAString& aInputEncoding) const;
   already_AddRefed<mozilla::dom::Location> GetLocation() const;
   void GetReferrer(nsAString& aReferrer) const;
   void GetLastModified(nsAString& aLastModified) const;
   void GetReadyState(nsAString& aReadyState) const;
-  // Not const because otherwise the compiler can't figure out whether to call
-  // this GetTitle or the nsAString version from non-const methods, since
-  // neither is an exact match.
-  virtual void GetTitle(nsString& aTitle) = 0;
+  virtual void GetTitle(nsAString& aTitle) = 0;
   virtual void SetTitle(const nsAString& aTitle, mozilla::ErrorResult& rv) = 0;
   void GetDir(nsAString& aDirection) const;
   void SetDir(const nsAString& aDirection);
   already_AddRefed<nsContentList> GetElementsByName(const nsAString& aName)
   {
     return GetFuncStringContentList<nsCachableElementsByNameNodeList>(this,
                                                                       MatchNameAttribute,
                                                                       nullptr,
@@ -2948,17 +2949,17 @@ public:
   }
   mozilla::dom::VisibilityState VisibilityState() const
   {
     return mVisibilityState;
   }
 #endif
   void GetSelectedStyleSheetSet(nsAString& aSheetSet);
   virtual void SetSelectedStyleSheetSet(const nsAString& aSheetSet) = 0;
-  virtual void GetLastStyleSheetSet(nsString& aSheetSet) = 0;
+  virtual void GetLastStyleSheetSet(nsAString& aSheetSet) = 0;
   void GetPreferredStyleSheetSet(nsAString& aSheetSet);
   virtual mozilla::dom::DOMStringList* StyleSheetSets() = 0;
   virtual void EnableStyleSheetsForSet(const nsAString& aSheetSet) = 0;
   Element* ElementFromPoint(float aX, float aY);
   void ElementsFromPoint(float aX,
                          float aY,
                          nsTArray<RefPtr<mozilla::dom::Element>>& aElements);
 
@@ -3037,16 +3038,17 @@ public:
   already_AddRefed<nsIURI> GetMozDocumentURIIfNotForErrorPages();
 
   // ParentNode
   nsIHTMLCollection* Children();
   uint32_t ChildElementCount();
 
   virtual nsHTMLDocument* AsHTMLDocument() { return nullptr; }
   virtual mozilla::dom::SVGDocument* AsSVGDocument() { return nullptr; }
+  virtual mozilla::dom::XULDocument* AsXULDocument() { return nullptr; }
 
   /*
    * Given a node, get a weak reference to it and append that reference to
    * mBlockedTrackingNodes. Can be used later on to look up a node in it.
    * (e.g., by the UI)
    */
   void AddBlockedTrackingNode(nsINode *node)
   {
--- a/dom/base/nsPIWindowRoot.h
+++ b/dom/base/nsPIWindowRoot.h
@@ -9,16 +9,17 @@
 
 #include "nsISupports.h"
 #include "mozilla/dom/EventTarget.h"
 #include "nsWeakReference.h"
 
 class nsPIDOMWindowOuter;
 class nsIControllers;
 class nsIController;
+class nsINode;
 
 namespace mozilla {
 namespace dom {
 class TabParent;
 } // namespace dom
 } // namespace mozilla
 
 #define NS_IWINDOWROOT_IID \
@@ -28,18 +29,18 @@ class TabParent;
 class nsPIWindowRoot : public mozilla::dom::EventTarget
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IWINDOWROOT_IID)
 
   virtual nsPIDOMWindowOuter* GetWindow()=0;
 
   // get and set the node that is the context of a popup menu
-  virtual nsIDOMNode* GetPopupNode() = 0;
-  virtual void SetPopupNode(nsIDOMNode* aNode) = 0;
+  virtual already_AddRefed<nsINode> GetPopupNode() = 0;
+  virtual void SetPopupNode(nsINode* aNode) = 0;
 
   /**
    * @param aForVisibleWindow   true if caller needs controller which is
    *                            associated with visible window.
    */
   virtual nsresult GetControllerForCommand(const char *aCommand,
                                            bool aForVisibleWindow,
                                            nsIController** aResult) = 0;
--- a/dom/base/nsWindowRoot.cpp
+++ b/dom/base/nsWindowRoot.cpp
@@ -366,25 +366,25 @@ nsWindowRoot::GetEnabledDisabledCommands
                                                aEnabledCommands, aDisabledCommands);
     }
 
     nsGlobalWindowOuter* win = nsGlobalWindowOuter::Cast(focusedWindow);
     focusedWindow = win->GetPrivateParent();
   }
 }
 
-nsIDOMNode*
+already_AddRefed<nsINode>
 nsWindowRoot::GetPopupNode()
 {
-  nsCOMPtr<nsIDOMNode> popupNode = do_QueryReferent(mPopupNode);
-  return popupNode;
+  nsCOMPtr<nsINode> popupNode = do_QueryReferent(mPopupNode);
+  return popupNode.forget();
 }
 
 void
-nsWindowRoot::SetPopupNode(nsIDOMNode* aNode)
+nsWindowRoot::SetPopupNode(nsINode* aNode)
 {
   mPopupNode = do_GetWeakReference(aNode);
 }
 
 nsIGlobalObject*
 nsWindowRoot::GetParentObject()
 {
   return xpc::NativeGlobal(xpc::PrivilegedJunkScope());
--- a/dom/base/nsWindowRoot.h
+++ b/dom/base/nsWindowRoot.h
@@ -47,18 +47,18 @@ public:
                                   nsIControllers** aResult) override;
   virtual nsresult GetControllerForCommand(const char * aCommand,
                                            bool aForVisibleWindow,
                                            nsIController** _retval) override;
 
   virtual void GetEnabledDisabledCommands(nsTArray<nsCString>& aEnabledCommands,
                                           nsTArray<nsCString>& aDisabledCommands) override;
 
-  virtual nsIDOMNode* GetPopupNode() override;
-  virtual void SetPopupNode(nsIDOMNode* aNode) override;
+  virtual already_AddRefed<nsINode> GetPopupNode() override;
+  virtual void SetPopupNode(nsINode* aNode) override;
 
   virtual void SetParentTarget(mozilla::dom::EventTarget* aTarget) override
   {
     mParent = aTarget;
   }
   virtual mozilla::dom::EventTarget* GetParentTarget() override { return mParent; }
   virtual nsPIDOMWindowOuter* GetOwnerGlobalForBindings() override;
   virtual nsIGlobalObject* GetOwnerGlobal() const override;
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -71,17 +71,16 @@
 
 #include "imgIContainer.h"
 #include "nsIProperties.h"
 #include "nsISupportsPrimitives.h"
 
 #include "nsServiceManagerUtils.h"
 #include "nsITimer.h"
 #include "nsFontMetrics.h"
-#include "nsIDOMXULDocument.h"
 #include "nsIDragService.h"
 #include "nsIDragSession.h"
 #include "mozilla/dom/DataTransfer.h"
 #include "nsContentAreaDragDrop.h"
 #ifdef MOZ_XUL
 #include "nsTreeBodyFrame.h"
 #endif
 #include "nsIController.h"
@@ -986,19 +985,17 @@ IsAccessKeyTarget(nsIContent* aContent, 
   // Use GetAttr because we want Unicode case=insensitive matching
   // XXXbz shouldn't this be case-sensitive, per spec?
   nsString contentKey;
   if (!aContent->IsElement() ||
       !aContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::accesskey, contentKey) ||
       !contentKey.Equals(aKey, nsCaseInsensitiveStringComparator()))
     return false;
 
-  nsCOMPtr<nsIDOMXULDocument> xulDoc =
-    do_QueryInterface(aContent->OwnerDoc());
-  if (!xulDoc && !aContent->IsXULElement())
+  if (!aContent->OwnerDoc()->IsXULDocument() && !aContent->IsXULElement())
     return true;
 
     // For XUL we do visibility checks.
   if (!aFrame)
     return false;
 
   if (aFrame->IsFocusable())
     return true;
--- a/dom/html/MediaDocument.cpp
+++ b/dom/html/MediaDocument.cpp
@@ -400,25 +400,27 @@ MediaDocument::UpdateTitleAndCharset(con
         mStringBundle->FormatStringFromName(aFormatNames[eWithNoInfo],
                                             formatStrings, 1, title);
       }
     }
   }
 
   // set it on the document
   if (aStatus.IsEmpty()) {
-    SetTitle(title);
+    IgnoredErrorResult ignored;
+    SetTitle(title, ignored);
   }
   else {
     nsAutoString titleWithStatus;
     const nsPromiseFlatString& status = PromiseFlatString(aStatus);
     const char16_t *formatStrings[2] = {title.get(), status.get()};
     mStringBundle->FormatStringFromName("TitleWithStatus", formatStrings,
                                         2, titleWithStatus);
-    SetTitle(titleWithStatus);
+    IgnoredErrorResult ignored;
+    SetTitle(titleWithStatus, ignored);
   }
 }
 
 void
 MediaDocument::SetScriptGlobalObject(nsIScriptGlobalObject* aGlobalObject)
 {
     nsHTMLDocument::SetScriptGlobalObject(aGlobalObject);
     if (!mDocumentElementInserted && aGlobalObject) {
--- a/dom/html/VideoDocument.cpp
+++ b/dom/html/VideoDocument.cpp
@@ -134,17 +134,18 @@ VideoDocument::CreateSyntheticVideoDocum
 void
 VideoDocument::UpdateTitle(nsIChannel* aChannel)
 {
   if (!aChannel)
     return;
 
   nsAutoString fileName;
   GetFileName(fileName, aChannel);
-  SetTitle(fileName);
+  IgnoredErrorResult ignored;
+  SetTitle(fileName, ignored);
 }
 
 } // namespace dom
 } // namespace mozilla
 
 nsresult
 NS_NewVideoDocument(nsIDocument** aResult)
 {
--- a/dom/interfaces/core/nsIDOMDocument.idl
+++ b/dom/interfaces/core/nsIDOMDocument.idl
@@ -1,322 +1,24 @@
 /* -*- 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"
 
-%{ C++
-#include "jspubtd.h"
-
-// windows.h #defines CreateEvent
-#ifdef CreateEvent
-#undef CreateEvent
-#endif
-%}
-
-interface mozIDOMWindowProxy;
-interface nsIDOMNodeIterator;
-interface nsIDOMNodeFilter;
-interface nsIDOMTreeWalker;
-
 /**
  * The nsIDOMDocument interface represents the entire HTML or XML document.
- * Conceptually, it is the root of the document tree, and provides the 
+ * Conceptually, it is the root of the document tree, and provides the
  * primary access to the document's data.
- * Since elements, text nodes, comments, processing instructions, etc. 
- * cannot exist outside the context of a Document, the nsIDOMDocument 
- * interface also contains the factory methods needed to create these 
+ * Since elements, text nodes, comments, processing instructions, etc.
+ * cannot exist outside the context of a Document, the nsIDOMDocument
+ * interface also contains the factory methods needed to create these
  * objects.
  *
- * For more information on this interface please see 
+ * For more information on this interface please see
  * http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html
  */
 
 [uuid(b15fa0f4-97c1-4388-af62-2ceff7a89bdf)]
 interface nsIDOMDocument : nsIDOMNode
 {
-  readonly attribute nsIDOMDocumentType         doctype;
-  readonly attribute nsIDOMDOMImplementation    implementation;
-  readonly attribute nsIDOMElement              documentElement;
-  nsIDOMElement                 createElement([Null(Stringify)] in DOMString tagName)
-                                  raises(DOMException);
-  nsIDOMDocumentFragment        createDocumentFragment();
-  nsIDOMText                    createTextNode(in DOMString data);
-  nsIDOMComment                 createComment(in DOMString data);
-  nsISupports                   createCDATASection(in DOMString data)
-                                  raises(DOMException);
-  nsIDOMProcessingInstruction   createProcessingInstruction(in DOMString target, 
-                                                            in DOMString data)
-                                  raises(DOMException);
-  nsIDOMNodeList                getElementsByTagName(in DOMString tagname);
-
-  // Introduced in DOM Level 2:
-  nsIDOMElement                 createElementNS(in DOMString namespaceURI,
-                                                [Null(Stringify)] in DOMString qualifiedName)
-                                  raises(DOMException);
-  // Introduced in DOM Level 2:
-  nsIDOMNodeList                getElementsByTagNameNS(in DOMString namespaceURI,
-                                                       in DOMString localName);
-  // Introduced in DOM Level 2:
-  nsIDOMElement                 getElementById(in DOMString elementId);
-  // Introduced in DOM Level 3:
-  readonly attribute DOMString       inputEncoding;
-  // Introduced in DOM Level 3:
-  readonly attribute DOMString       documentURI;
-  // Alias introduced for all documents in recent DOM standards
-  readonly attribute DOMString       URL;
-
-  /**
-   * Create a range
-   *
-   * @see http://html5.org/specs/dom-range.html#dom-document-createrange
-   */
-  nsIDOMRange              createRange();
-
-  [optional_argc] nsIDOMNodeIterator createNodeIterator(in nsIDOMNode root,
-                                                        [optional] in unsigned long whatToShow,
-                                                        [optional] in nsIDOMNodeFilter filter)
-                                                          raises(DOMException);
-  [optional_argc] nsIDOMTreeWalker   createTreeWalker(in nsIDOMNode root,
-                                                      [optional] in unsigned long whatToShow,
-                                                      [optional] in nsIDOMNodeFilter filter)
-                                                        raises(DOMException);
-
-  nsIDOMEvent               createEvent(in DOMString eventType)
-                                               raises(DOMException);
-
-
-  // HTML
-  /**
-   * The window associated with this document.
-   *
-   * @see <http://www.whatwg.org/html/#dom-document-defaultview>
-   */
-  readonly attribute mozIDOMWindowProxy   defaultView;
-
-  /**
-   * @see <http://www.whatwg.org/html/#dom-document-characterset>
-   */
-  readonly attribute DOMString      characterSet;
-  /**
-   * @see <http://www.whatwg.org/html/#dom-document-dir>
-   */
-           attribute DOMString      dir;
-
-  /**
-   * @see <http://www.whatwg.org/html/#document.title>
-   */
-           attribute DOMString      title;
-
-  /**
-   * @see <http://www.whatwg.org/html/#dom-document-readystate>
-   */
-  readonly attribute DOMString      readyState;
-  /**
-   * @see <http://www.whatwg.org/html/#dom-document-lastmodified>
-   */
-  readonly attribute DOMString      lastModified;
-  /**
-   * @see <http://www.whatwg.org/html/#dom-document-referrer>
-   */
-  readonly attribute DOMString      referrer;
-
-  /**
-   * @see <http://www.whatwg.org/html/#dom-document-hasfocus>
-   */
-  boolean      hasFocus();
-
-  /**
-   * @see <http://www.whatwg.org/html/#dom-document-activeelement>
-   */
-  readonly attribute nsIDOMElement  activeElement;
-
-  /**
-   * Retrieve elements matching all classes listed in a
-   * space-separated string.
-   *
-   * @see <http://www.whatwg.org/html/#dom-document-getelementsbyclassname>
-   */
-  nsIDOMNodeList getElementsByClassName(in DOMString classes);
-
-
-  // CSSOM
-
-  /**
-   * This attribute must return the preferred style sheet set as set by the
-   * author. It is determined from the order of style sheet declarations and
-   * the Default-Style HTTP headers, as eventually defined elsewhere in the Web
-   * Apps 1.0 specification. If there is no preferred style sheet set, this
-   * attribute must return the empty string. The case of this attribute must
-   * exactly match the case given by the author where the preferred style sheet
-   * is specified or implied. This attribute must never return null.
-   *
-   * @see <http://dev.w3.org/csswg/cssom/#dom-document-preferredStyleSheetSet>
-   */
-  readonly attribute DOMString preferredStyleSheetSet;
-
-  /**
-   * This attribute indicates which style sheet set is in use. This attribute
-   * is live; changing the disabled attribute on style sheets directly will
-   * change the value of this attribute.
-   *
-   * If all the sheets that are enabled and have a title have the same title
-   * (by case-sensitive comparisons) then the value of this attribute must be
-   * exactly equal to the title of the first enabled style sheet with a title
-   * in the styleSheets list. Otherwise, if style sheets from different sets
-   * are enabled, then the return value must be null (there is no way to
-   * determine what the currently selected style sheet set is in those
-   * conditions). Otherwise, either all style sheets that have a title are
-   * disabled, or there are no alternate style sheets, and
-   * selectedStyleSheetSet must return the empty string.
-   *
-   * Setting this attribute to the null value must have no effect.
-   *
-   * Setting this attribute to a non-null value must call
-   * enableStyleSheetsForSet() with that value as the function's argument, and
-   * set lastStyleSheetSet to that value.
-   *
-   * From the DOM's perspective, all views have the same
-   * selectedStyleSheetSet. If a UA supports multiple views with different
-   * selected alternate style sheets, then this attribute (and the StyleSheet
-   * interface's disabled attribute) must return and set the value for the
-   * default view.
-   *
-   * @see <http://dev.w3.org/csswg/cssom/#dom-document-selectedStyleSheetSet>
-   */
-  [binaryname(MozSelectedStyleSheetSet)]
-  attribute DOMString selectedStyleSheetSet;
-
-  /*
-   * This property must initially have the value null. Its value changes when
-   * the selectedStyleSheetSet attribute is set.
-   *
-   * @see <http://dev.w3.org/csswg/cssom/#dom-document-lastStyleSheetSet>
-   */
-  readonly attribute DOMString lastStyleSheetSet;
-  
-  /**
-   * This must return the live list of the currently available style sheet
-   * sets. This list is constructed by enumerating all the style sheets for
-   * this document available to the implementation, in the order they are
-   * listed in the styleSheets attribute, adding the title of each style sheet
-   * with a title to the list, avoiding duplicates by dropping titles that
-   * match (case-sensitively) titles that have already been added to the
-   * list.
-   *
-   * @see <http://dev.w3.org/csswg/cssom/#dom-document-styleSheetSets>
-   */
-  readonly attribute nsISupports styleSheetSets;
-
-  /**
-   * Calling this method must change the disabled attribute on each StyleSheet
-   * object with a title attribute with a length greater than 0 in the
-   * styleSheets attribute, so that all those whose title matches the name
-   * argument are enabled, and all others are disabled. Title matches must be
-   * case-sensitive. Calling this method with the empty string disables all
-   * alternate and preferred style sheets (but does not change the state of
-   * persistent style sheets, that is those with no title attribute).
-   *
-   * Calling this method with a null value must have no effect.
-   *
-   * Style sheets that do not have a title are never affected by this
-   * method. This method does not change the values of the lastStyleSheetSet or
-   * preferredStyleSheetSet attributes.
-   *
-   * @see <http://dev.w3.org/csswg/cssom/#dom-document-enableStyleSheetsForSet>
-   */
-  [binaryname(MozEnableStyleSheetsForSet)]
-  void enableStyleSheetsForSet(in DOMString name);
-
-
-  // CSSOM-View
-  /**
-   * Returns the element from the caller's document at the given point,
-   * relative to the upper-left-most point in the (possibly scrolled)
-   * window or frame.
-   *
-   * If the element at the given point belongs to another document (such as
-   * an iframe's subdocument), the element in the calling document's DOM
-   * (e.g. the iframe) is returned. If the element at the given point is
-   * anonymous or XBL generated content, such as a textbox's scrollbars, then
-   * the first non-anonymous parent element (that is, the textbox) is returned.
-   *
-   * This method returns null if either coordinate is negative, or if the
-   * specified point lies outside the visible bounds of the document.
-   *
-   * Callers from XUL documents should wait until the onload event has fired
-   * before calling this method.
-   *
-   * @see <http://dev.w3.org/csswg/cssom-view/#dom-document-elementfrompoint>
-   */
-  nsIDOMElement             elementFromPoint(in float x, in float y);
-
-
-  // Mozilla extensions
-  /**
-   * @see <https://developer.mozilla.org/en/DOM/document.contentType>
-   */
-  readonly attribute DOMString      contentType;
-
-  /**
-   * True if this document is synthetic : stand alone image, video, audio file,
-   * etc.
-   */
-  readonly attribute boolean        mozSyntheticDocument;
-
-  /**
-   * Returns the script element whose script is currently being processed.
-   *
-   * @see <https://developer.mozilla.org/en/DOM/document.currentScript>
-   */
-  readonly attribute nsIDOMElement  currentScript;
-
-  /**
-   * Use the given DOM element as the source image of target |-moz-element()|.
-   *
-   * This function introduces a new special ID (called "image element ID"),
-   * which is only used by |-moz-element()|, and associates it with the given
-   * DOM element.  Image elements ID's have the higher precedence than general
-   * HTML id's, so if |document.mozSetImageElement(<id>, <element>)| is called,
-   * |-moz-element(#<id>)| uses |<element>| as the source image even if there
-   * is another element with id attribute = |<id>|.  To unregister an image
-   * element ID |<id>|, call |document.mozSetImageElement(<id>, null)|.
-   *
-   * Example:
-   * <script>
-   *   canvas = document.createElement("canvas");
-   *   canvas.setAttribute("width", 100);
-   *   canvas.setAttribute("height", 100);
-   *   // draw to canvas
-   *   document.mozSetImageElement("canvasbg", canvas);
-   * </script>
-   * <div style="background-image: -moz-element(#canvasbg);"></div>
-   *
-   * @param aImageElementId an image element ID to associate with
-   * |aImageElement|
-   * @param aImageElement a DOM element to be used as the source image of
-   * |-moz-element(#aImageElementId)|. If this is null, the function will
-   * unregister the image element ID |aImageElementId|.
-   *
-   * @see <https://developer.mozilla.org/en/DOM/document.mozSetImageElement>
-   */
-  void mozSetImageElement(in DOMString aImageElementId,
-                          in nsIDOMElement aImageElement);
-
-  /**
-   * Retrieve the location of the caret position (DOM node and character
-   * offset within that node), given a point.
-   *
-   * @param x Horizontal point at which to determine the caret position, in
-   *          page coordinates.
-   * @param y Vertical point at which to determine the caret position, in
-   *          page coordinates.
-   */
-  nsISupports /* CaretPosition */ caretPositionFromPoint(in float x, in float y);
-
-  /**
-   * Visibility API implementation.
-   */
-  readonly attribute boolean hidden;
-  readonly attribute DOMString visibilityState;
 };
--- a/dom/interfaces/xul/moz.build
+++ b/dom/interfaces/xul/moz.build
@@ -10,17 +10,16 @@ with Files("**"):
 XPIDL_SOURCES += [
     'nsIDOMXULButtonElement.idl',
     'nsIDOMXULCheckboxElement.idl',
     'nsIDOMXULCommandDispatcher.idl',
     'nsIDOMXULCommandEvent.idl',
     'nsIDOMXULContainerElement.idl',
     'nsIDOMXULControlElement.idl',
     'nsIDOMXULDescriptionElement.idl',
-    'nsIDOMXULDocument.idl',
     'nsIDOMXULElement.idl',
     'nsIDOMXULLabeledControlEl.idl',
     'nsIDOMXULLabelElement.idl',
     'nsIDOMXULMenuListElement.idl',
     'nsIDOMXULMultSelectCntrlEl.idl',
     'nsIDOMXULRelatedElement.idl',
     'nsIDOMXULSelectCntrlEl.idl',
     'nsIDOMXULSelectCntrlItemEl.idl',
deleted file mode 100644
--- a/dom/interfaces/xul/nsIDOMXULDocument.idl
+++ /dev/null
@@ -1,71 +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 "domstubs.idl"
-#include "nsIDOMDocument.idl"
-
-interface nsIDOMXULCommandDispatcher;
-interface nsIObserver;
-interface nsIBoxObject;
-
-[uuid(7790d4c3-e8f0-4e29-9887-d683ed2b2a44)]
-interface nsIDOMXULDocument : nsIDOMDocument
-{
-  attribute nsIDOMNode                          popupNode;
-
-  /**
-   * These attributes correspond to trustedGetPopupNode().rangeOffset and
-   * rangeParent. They will help you find where in the DOM the popup is
-   * happening. Can be accessed from chrome only, and only during a popup
-   * event. Accessing any other time will be an error.
-   */
-  readonly attribute nsIDOMNode                 popupRangeParent;
-  readonly attribute long                       popupRangeOffset;
-
-  attribute nsIDOMNode                          tooltipNode;
-
-  readonly attribute nsIDOMXULCommandDispatcher commandDispatcher;
-
-  readonly attribute long                       width;
-  readonly attribute long                       height;
-
-  nsIDOMNodeList            getElementsByAttribute(in DOMString name,
-                                                   in DOMString value);
-
-  nsIDOMNodeList            getElementsByAttributeNS(in DOMString namespaceURI,
-                                                     in DOMString name,
-                                                     in DOMString value);
-
-  void                      addBroadcastListenerFor(in nsIDOMElement broadcaster,
-                                                    in nsIDOMElement observer,
-                                                    in DOMString attr);
-
-  void                      removeBroadcastListenerFor(in nsIDOMElement broadcaster,
-                                                       in nsIDOMElement observer,
-                                                       in DOMString attr);
-
-  void                      persist(in DOMString id, in DOMString attr);
-
-  nsIBoxObject getBoxObjectFor(in nsIDOMElement elt);
-
-  /**
-   * Loads a XUL overlay and merges it with the current document, notifying an
-   * observer when the merge is complete. 
-   * @param   url
-   *          The URL of the overlay to load and merge
-   * @param   observer
-   *          An object implementing nsIObserver that will be notified with a
-   *          message of topic "xul-overlay-merged" when the merge is complete. 
-   *          The subject parameter of |observe| will QI to a nsIURI - the URI 
-   *          of the merged overlay. This parameter is optional and may be null.
-   *
-   * NOTICE:  In the 2.0 timeframe this API will change such that the 
-   *          implementation will fire a DOMXULOverlayMerged event upon merge
-   *          completion rather than notifying an observer. Do not rely on this
-   *          API's behavior _not_ to change because it will!
-   *          - Ben Goodger (8/23/2005)
-   */
-  void                      loadOverlay(in DOMString url, in nsIObserver aObserver);
-};
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -70,18 +70,16 @@ static NS_DEFINE_CID(kAppShellCID, NS_AP
 #ifdef XP_WIN
 #include <wtypes.h>
 #include <winuser.h>
 #include "mozilla/widget/WinMessages.h"
 #endif // #ifdef XP_WIN
 
 #ifdef XP_MACOSX
 #include "ComplexTextInputPanel.h"
-#include "nsIDOMXULDocument.h"
-#include "nsIDOMXULCommandDispatcher.h"
 #endif
 
 #ifdef MOZ_WIDGET_GTK
 #include <gdk/gdk.h>
 #include <gtk/gtk.h>
 #endif
 
 using namespace mozilla;
--- a/dom/system/nsDeviceSensors.cpp
+++ b/dom/system/nsDeviceSensors.cpp
@@ -5,31 +5,32 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/Hal.h"
 #include "mozilla/HalSensor.h"
 
 #include "nsContentUtils.h"
 #include "nsDeviceSensors.h"
 
-#include "nsIDOMEvent.h"
 #include "nsIDOMWindow.h"
 #include "nsPIDOMWindow.h"
 #include "nsIDOMDocument.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsIServiceManager.h"
 #include "nsIServiceManager.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/Services.h"
 #include "nsIPermissionManager.h"
 #include "mozilla/dom/DeviceLightEvent.h"
 #include "mozilla/dom/DeviceOrientationEvent.h"
 #include "mozilla/dom/DeviceProximityEvent.h"
+#include "mozilla/dom/Event.h"
 #include "mozilla/dom/UserProximityEvent.h"
+#include "mozilla/ErrorResult.h"
 
 #include <cmath>
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace hal;
 
 #undef near
@@ -354,22 +355,22 @@ nsDeviceSensors::Notify(const mozilla::h
   for (uint32_t i = windowListeners.Count(); i > 0 ; ) {
     --i;
 
     nsCOMPtr<nsPIDOMWindowInner> pwindow = do_QueryInterface(windowListeners[i]);
     if (WindowCannotReceiveSensorEvent(pwindow)) {
         continue;
     }
 
-    if (nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(pwindow->GetDoc())) {
+    if (nsCOMPtr<nsIDocument> doc = pwindow->GetDoc()) {
       nsCOMPtr<mozilla::dom::EventTarget> target = do_QueryInterface(windowListeners[i]);
       if (type == nsIDeviceSensorData::TYPE_ACCELERATION ||
         type == nsIDeviceSensorData::TYPE_LINEAR_ACCELERATION ||
         type == nsIDeviceSensorData::TYPE_GYROSCOPE) {
-        FireDOMMotionEvent(domDoc, target, type, timestamp, x, y, z);
+        FireDOMMotionEvent(doc, target, type, timestamp, x, y, z);
       } else if (type == nsIDeviceSensorData::TYPE_ORIENTATION) {
         FireDOMOrientationEvent(target, x, y, z, Orientation::kAbsolute);
       } else if (type == nsIDeviceSensorData::TYPE_ROTATION_VECTOR) {
         const Orientation orient = RotationVectorToOrientation(x, y, z, w);
         FireDOMOrientationEvent(target, orient.alpha, orient.beta, orient.gamma,
                                 Orientation::kAbsolute);
       } else if (type == nsIDeviceSensorData::TYPE_GAME_ROTATION_VECTOR) {
         const Orientation orient = RotationVectorToOrientation(x, y, z, w);
@@ -493,17 +494,17 @@ nsDeviceSensors::FireDOMOrientationEvent
     // For absolute events on devices without support for relative events,
     // we need to additionally dispatch type "deviceorientation" to keep
     // backwards-compatibility.
     Dispatch(aTarget, NS_LITERAL_STRING("deviceorientation"));
   }
 }
 
 void
-nsDeviceSensors::FireDOMMotionEvent(nsIDOMDocument *domdoc,
+nsDeviceSensors::FireDOMMotionEvent(nsIDocument *doc,
                                     EventTarget* target,
                                     uint32_t type,
                                     PRTime timestamp,
                                     double x,
                                     double y,
                                     double z)
 {
   // Attempt to coalesce events
@@ -551,18 +552,22 @@ nsDeviceSensors::FireDOMMotionEvent(nsID
       mLastRotationRate.emplace();
     }
   } else if (!mLastAcceleration ||
              !mLastAccelerationIncludingGravity ||
              !mLastRotationRate) {
     return;
   }
 
-  nsCOMPtr<nsIDOMEvent> event;
-  domdoc->CreateEvent(NS_LITERAL_STRING("DeviceMotionEvent"), getter_AddRefs(event));
+  IgnoredErrorResult ignored;
+  RefPtr<Event> event = doc->CreateEvent(NS_LITERAL_STRING("DeviceMotionEvent"),
+                                         CallerType::System, ignored);
+  if (!event) {
+    return;
+  }
 
   DeviceMotionEvent* me = static_cast<DeviceMotionEvent*>(event.get());
 
   me->InitDeviceMotionEvent(NS_LITERAL_STRING("devicemotion"),
                             true,
                             false,
                             *mLastAcceleration,
                             *mLastAccelerationIncludingGravity,
--- a/dom/system/nsDeviceSensors.h
+++ b/dom/system/nsDeviceSensors.h
@@ -13,16 +13,17 @@
 #include "nsCOMPtr.h"
 #include "nsITimer.h"
 #include "mozilla/dom/DeviceMotionEvent.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/HalSensor.h"
 #include "nsDataHashtable.h"
 
 class nsIDOMWindow;
+class nsIDocument;
 
 namespace mozilla {
 namespace dom {
 class EventTarget;
 } // namespace dom
 } // namespace mozilla
 
 class nsDeviceSensors : public nsIDeviceSensors, public mozilla::hal::ISensorObserver
@@ -55,17 +56,17 @@ private:
                                  bool aNear);
 
   void FireDOMOrientationEvent(mozilla::dom::EventTarget* target,
                                double aAlpha,
                                double aBeta,
                                double aGamma,
                                bool aIsAbsolute);
 
-  void FireDOMMotionEvent(class nsIDOMDocument *domDoc,
+  void FireDOMMotionEvent(nsIDocument* domDoc,
                           mozilla::dom::EventTarget* target,
                           uint32_t type,
                           PRTime timestamp,
                           double x,
                           double y,
                           double z);
 
   bool mEnabled;
--- a/dom/webbrowserpersist/WebBrowserPersistLocalDocument.cpp
+++ b/dom/webbrowserpersist/WebBrowserPersistLocalDocument.cpp
@@ -13,33 +13,33 @@
 #include "mozilla/dom/HTMLAreaElement.h"
 #include "mozilla/dom/HTMLInputElement.h"
 #include "mozilla/dom/HTMLLinkElement.h"
 #include "mozilla/dom/HTMLObjectElement.h"
 #include "mozilla/dom/HTMLOptionElement.h"
 #include "mozilla/dom/HTMLSharedElement.h"
 #include "mozilla/dom/HTMLTextAreaElement.h"
 #include "mozilla/dom/TabParent.h"
+#include "mozilla/dom/TreeWalker.h"
 #include "nsComponentManagerUtils.h"
 #include "nsContentUtils.h"
 #include "nsContentCID.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsDOMAttributeMap.h"
 #include "nsFrameLoader.h"
 #include "nsIComponentRegistrar.h"
 #include "nsIContent.h"
 #include "nsIDOMComment.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMHTMLInputElement.h"
 #include "nsIDOMHTMLMediaElement.h"
 #include "nsIDOMNode.h"
 #include "nsIDOMNodeFilter.h"
 #include "nsIDOMNodeList.h"
 #include "nsIDOMProcessingInstruction.h"
-#include "nsIDOMTreeWalker.h"
 #include "nsIDOMWindowUtils.h"
 #include "nsIDocShell.h"
 #include "nsIDocument.h"
 #include "nsIDocumentEncoder.h"
 #include "nsILoadContext.h"
 #include "nsIProtocolHandler.h"
 #include "nsISHEntry.h"
 #include "nsISupportsPrimitives.h"
@@ -112,21 +112,18 @@ WebBrowserPersistLocalDocument::GetBaseU
     }
     return uri->GetSpec(aURISpec);
 }
 
 NS_IMETHODIMP
 WebBrowserPersistLocalDocument::GetContentType(nsACString& aContentType)
 {
     nsAutoString utf16Type;
-    nsresult rv;
-
-    rv = mDocument->GetContentType(utf16Type);
-    NS_ENSURE_SUCCESS(rv, rv);
-    aContentType = NS_ConvertUTF16toUTF8(utf16Type);
+    mDocument->GetContentType(utf16Type);
+    CopyUTF16toUTF8(utf16Type, aContentType);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 WebBrowserPersistLocalDocument::GetCharacterSet(nsACString& aCharSet)
 {
     GetCharacterSet()->Name(aCharSet);
     return NS_OK;
@@ -1188,28 +1185,29 @@ PersistNodeFixup::FixupNode(nsINode* aNo
 } // unnamed namespace
 
 NS_IMETHODIMP
 WebBrowserPersistLocalDocument::ReadResources(nsIWebBrowserPersistResourceVisitor* aVisitor)
 {
     nsresult rv = NS_OK;
     nsCOMPtr<nsIWebBrowserPersistResourceVisitor> visitor = aVisitor;
 
-    nsCOMPtr<nsIDOMNode> docAsNode = do_QueryInterface(mDocument);
-    NS_ENSURE_TRUE(docAsNode, NS_ERROR_FAILURE);
+    NS_ENSURE_TRUE(mDocument, NS_ERROR_FAILURE);
 
-    nsCOMPtr<nsIDOMTreeWalker> walker;
-    nsCOMPtr<nsIDOMDocument> oldStyleDoc = do_QueryInterface(mDocument);
-    MOZ_ASSERT(oldStyleDoc);
-    rv = oldStyleDoc->CreateTreeWalker(docAsNode,
+    ErrorResult err;
+    nsCOMPtr<nsIDOMTreeWalker> walker =
+        mDocument->CreateTreeWalker(*mDocument,
             nsIDOMNodeFilter::SHOW_ELEMENT |
             nsIDOMNodeFilter::SHOW_DOCUMENT |
             nsIDOMNodeFilter::SHOW_PROCESSING_INSTRUCTION,
-            nullptr, 1, getter_AddRefs(walker));
-    NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
+            nullptr, err);
+
+    if (NS_WARN_IF(err.Failed())) {
+        return err.StealNSResult();
+    }
     MOZ_ASSERT(walker);
 
     RefPtr<ResourceReader> reader = new ResourceReader(this, aVisitor);
     nsCOMPtr<nsIDOMNode> currentNode;
     walker->GetCurrentNode(getter_AddRefs(currentNode));
     while (currentNode) {
         rv = reader->OnWalkDOMNode(currentNode);
         if (NS_WARN_IF(NS_FAILED(rv))) {
--- a/dom/webidl/XULDocument.webidl
+++ b/dom/webidl/XULDocument.webidl
@@ -1,15 +1,12 @@
 /* -*- 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/.
- *
- * The origin of this IDL file is:
- * dom/interfaces/xul/nsIDOMXULDocument.idl
  */
 
 interface XULCommandDispatcher;
 interface MozObserver;
 
 [Func="IsChromeOrXBL"]
 interface XULDocument : Document {
            attribute Node? popupNode;
@@ -47,11 +44,28 @@ interface XULDocument : Document {
                                   DOMString attr);
 
   [Throws]
   void persist([TreatNullAs=EmptyString] DOMString id, DOMString attr);
 
   [Throws]
   BoxObject? getBoxObjectFor(Element? element);
 
+  /**
+   * Loads a XUL overlay and merges it with the current document, notifying an
+   * observer when the merge is complete.
+   * @param   url
+   *          The URL of the overlay to load and merge
+   * @param   observer
+   *          An object implementing nsIObserver that will be notified with a
+   *          message of topic "xul-overlay-merged" when the merge is complete.
+   *          The subject parameter of |observe| will QI to a nsIURI - the URI
+   *          of the merged overlay. This parameter is optional and may be null.
+   *
+   * NOTICE:  In the 2.0 timeframe this API will change such that the
+   *          implementation will fire a DOMXULOverlayMerged event upon merge
+   *          completion rather than notifying an observer. Do not rely on this
+   *          API's behavior _not_ to change because it will!
+   *          - Ben Goodger (8/23/2005)
+   */
   [Throws]
   void loadOverlay(DOMString url, MozObserver? observer);
 };
--- a/dom/xbl/nsXBLBinding.cpp
+++ b/dom/xbl/nsXBLBinding.cpp
@@ -15,17 +15,17 @@
 #include "nsString.h"
 #include "nsReadableUtils.h"
 #include "plstr.h"
 #include "nsIContent.h"
 #include "nsIDocument.h"
 #include "nsContentUtils.h"
 #include "ChildIterator.h"
 #ifdef MOZ_XUL
-#include "nsIXULDocument.h"
+#include "XULDocument.h"
 #endif
 #include "nsIXMLContentSink.h"
 #include "nsContentCID.h"
 #include "mozilla/dom/XMLDocument.h"
 #include "jsapi.h"
 #include "nsXBLService.h"
 #include "nsIXPConnect.h"
 #include "nsIScriptContext.h"
@@ -225,34 +225,34 @@ nsXBLBinding::BindAnonymousContent(nsICo
       child->UnbindFromTree();
       return;
     }
 
 #ifdef MOZ_XUL
     // To make XUL templates work (and other goodies that happen when
     // an element is added to a XUL document), we need to notify the
     // XUL document using its special API.
-    nsCOMPtr<nsIXULDocument> xuldoc(do_QueryInterface(doc));
-    if (xuldoc)
+    XULDocument* xuldoc = doc ? doc->AsXULDocument() : nullptr;
+    if (xuldoc) {
       xuldoc->AddSubtreeToDocument(child);
+    }
 #endif
   }
 }
 
 void
 nsXBLBinding::UnbindAnonymousContent(nsIDocument* aDocument,
                                      nsIContent* aAnonParent,
                                      bool aNullParent)
 {
   nsAutoScriptBlocker scriptBlocker;
   // Hold a strong ref while doing this, just in case.
   nsCOMPtr<nsIContent> anonParent = aAnonParent;
 #ifdef MOZ_XUL
-  nsCOMPtr<nsIXULDocument> xuldoc =
-    do_QueryInterface(aDocument);
+  XULDocument* xuldoc = aDocument ? aDocument->AsXULDocument() : nullptr;
 #endif
   for (nsIContent* child = aAnonParent->GetFirstChild();
        child;
        child = child->GetNextSibling()) {
     child->UnbindFromTree(true, aNullParent);
 #ifdef MOZ_XUL
     if (xuldoc) {
       xuldoc->RemoveSubtreeFromDocument(child);
--- a/dom/xml/nsXMLContentSink.cpp
+++ b/dom/xml/nsXMLContentSink.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 "nsCOMPtr.h"
 #include "nsXMLContentSink.h"
 #include "nsIParser.h"
 #include "nsIDocument.h"
-#include "nsIDOMDocument.h"
 #include "nsIDOMDocumentType.h"
 #include "nsIContent.h"
 #include "nsIURI.h"
 #include "nsNetUtil.h"
 #include "nsIDocShell.h"
 #include "nsIStyleSheetLinkingElement.h"
 #include "nsIDOMComment.h"
 #include "DocumentType.h"
@@ -356,26 +355,24 @@ nsXMLContentSink::OnDocumentCreated(nsID
 NS_IMETHODIMP
 nsXMLContentSink::OnTransformDone(nsresult aResult,
                                   nsIDocument* aResultDocument)
 {
   MOZ_ASSERT(aResultDocument, "Don't notify about transform end without a document.");
 
   mDocumentChildren.Clear();
 
-  nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(aResultDocument);
-
   nsCOMPtr<nsIContentViewer> contentViewer;
   mDocShell->GetContentViewer(getter_AddRefs(contentViewer));
 
   if (NS_FAILED(aResult) && contentViewer) {
     // Transform failed.
     aResultDocument->SetMayStartLayout(false);
     // We have an error document.
-    contentViewer->SetDOMDocument(domDoc);
+    contentViewer->SetDocument(aResultDocument);
   }
 
   nsCOMPtr<nsIDocument> originalDocument = mDocument;
   // Transform succeeded, or it failed and we have an error document to display.
   mDocument = aResultDocument;
   nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(mDocument);
   if (htmlDoc) {
     htmlDoc->SetDocWriteDisabled(false);
--- a/dom/xslt/xslt/txMozillaXSLTProcessor.cpp
+++ b/dom/xslt/xslt/txMozillaXSLTProcessor.cpp
@@ -730,18 +730,17 @@ txMozillaXSLTProcessor::TransformToFragm
     if (!sourceNode) {
         return NS_ERROR_OUT_OF_MEMORY;
     }
 
     txExecutionState es(mStylesheet, IsLoadDisabled());
 
     // XXX Need to add error observers
 
-    rv = aOutput->CreateDocumentFragment(aResult);
-    NS_ENSURE_SUCCESS(rv, rv);
+    *aResult = doc->CreateDocumentFragment().take();
     txToFragmentHandlerFactory handlerFactory(*aResult);
     es.mOutputHandlerFactory = &handlerFactory;
 
     rv = es.init(*sourceNode, &mVariables);
 
     // Process root of XML source document
     if (NS_SUCCEEDED(rv)) {
         rv = txXSLTProcessor::execute(es);
--- a/dom/xul/XULDocument.cpp
+++ b/dom/xul/XULDocument.cpp
@@ -45,16 +45,17 @@
 #include "nsParserCIID.h"
 #include "nsPIBoxObject.h"
 #include "mozilla/dom/BoxObject.h"
 #include "nsString.h"
 #include "nsPIDOMWindow.h"
 #include "nsPIWindowRoot.h"
 #include "nsXULCommandDispatcher.h"
 #include "nsXULElement.h"
+#include "nsXULPrototypeCache.h"
 #include "mozilla/Logging.h"
 #include "nsIFrame.h"
 #include "nsXBLService.h"
 #include "nsCExternalHandlerService.h"
 #include "nsMimeTypes.h"
 #include "nsIObjectInputStream.h"
 #include "nsIObjectOutputStream.h"
 #include "nsContentList.h"
@@ -211,17 +212,17 @@ XULDocument::~XULDocument()
       js_free(mOffThreadCompileStringBuf);
     }
 }
 
 } // namespace dom
 } // namespace mozilla
 
 nsresult
-NS_NewXULDocument(nsIXULDocument** result)
+NS_NewXULDocument(nsIDocument** result)
 {
     NS_PRECONDITION(result != nullptr, "null ptr");
     if (! result)
         return NS_ERROR_NULL_POINTER;
 
     RefPtr<XULDocument> doc = new XULDocument();
 
     nsresult rv;
@@ -277,18 +278,16 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(XULDocument, XMLDocument)
     NS_IMPL_CYCLE_COLLECTION_UNLINK(mCommandDispatcher)
     NS_IMPL_CYCLE_COLLECTION_UNLINK(mLocalStore)
     //XXX We should probably unlink all the objects we traverse.
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED(XULDocument,
                                              XMLDocument,
-                                             nsIXULDocument,
-                                             nsIDOMXULDocument,
                                              nsIStreamLoaderObserver,
                                              nsICSSLoaderObserver,
                                              nsIOffThreadScriptReceiver)
 
 
 //----------------------------------------------------------------------
 //
 // nsIDocument interface
@@ -518,17 +517,17 @@ XULDocument::EndLoad()
         rv = uri->GetSpec(urlspec);
         if (NS_SUCCEEDED(rv)) {
             MOZ_LOG(gXULLog, LogLevel::Warning,
                    ("xul: Finished loading document '%s'", urlspec.get()));
         }
     }
 }
 
-NS_IMETHODIMP
+nsresult
 XULDocument::OnPrototypeLoadDone(bool aResumeWalk)
 {
     nsresult rv;
 
     // Add the style overlays from chrome registry, if any.
     rv = AddPrototypeSheets();
     if (NS_FAILED(rv)) return rv;
 
@@ -672,29 +671,16 @@ XULDocument::SynchronizeBroadcastListene
         // hookup: doing so would potentially run the |onbroadcast|
         // handler before the |onload| handler, which could define JS
         // properties that mask XBL properties, etc.
         ExecuteOnBroadcastHandlerFor(aBroadcaster, aListener, name);
 #endif
     }
 }
 
-NS_IMETHODIMP
-XULDocument::AddBroadcastListenerFor(nsIDOMElement* aBroadcaster,
-                                     nsIDOMElement* aListener,
-                                     const nsAString& aAttr)
-{
-    ErrorResult rv;
-    nsCOMPtr<Element> broadcaster = do_QueryInterface(aBroadcaster);
-    nsCOMPtr<Element> listener = do_QueryInterface(aListener);
-    NS_ENSURE_ARG(broadcaster && listener);
-    AddBroadcastListenerFor(*broadcaster, *listener, aAttr, rv);
-    return rv.StealNSResult();
-}
-
 void
 XULDocument::AddBroadcastListenerFor(Element& aBroadcaster, Element& aListener,
                                      const nsAString& aAttr, ErrorResult& aRv)
 {
     nsresult rv =
         nsContentUtils::CheckSameOrigin(this, &aBroadcaster);
 
     if (NS_FAILED(rv)) {
@@ -753,28 +739,16 @@ XULDocument::AddBroadcastListenerFor(Ele
     bl->mListener  = do_GetWeakReference(&aListener);
     bl->mAttribute = attr;
 
     entry->mListeners.AppendElement(bl);
 
     SynchronizeBroadcastListener(&aBroadcaster, &aListener, aAttr);
 }
 
-NS_IMETHODIMP
-XULDocument::RemoveBroadcastListenerFor(nsIDOMElement* aBroadcaster,
-                                        nsIDOMElement* aListener,
-                                        const nsAString& aAttr)
-{
-    nsCOMPtr<Element> broadcaster = do_QueryInterface(aBroadcaster);
-    nsCOMPtr<Element> listener = do_QueryInterface(aListener);
-    NS_ENSURE_ARG(broadcaster && listener);
-    RemoveBroadcastListenerFor(*broadcaster, *listener, aAttr);
-    return NS_OK;
-}
-
 void
 XULDocument::RemoveBroadcastListenerFor(Element& aBroadcaster,
                                         Element& aListener,
                                         const nsAString& aAttr)
 {
     // If we haven't added any broadcast listeners, then there sure
     // aren't any to remove.
     if (! mBroadcasterMap)
@@ -1010,21 +984,16 @@ XULDocument::ContentRemoved(nsIDocument*
     NS_ASSERTION(aDocument == this, "unexpected doc");
 
     // Might not need this, but be safe for now.
     nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this);
 
     RemoveSubtreeFromDocument(aChild);
 }
 
-//----------------------------------------------------------------------
-//
-// nsIXULDocument interface
-//
-
 nsresult
 XULDocument::AddForwardReference(nsForwardReference* aRef)
 {
     if (mResolutionPhase < aRef->GetPhase()) {
         if (!mForwardReferences.AppendElement(aRef)) {
             delete aRef;
             return NS_ERROR_OUT_OF_MEMORY;
         }
@@ -1096,25 +1065,16 @@ XULDocument::ResolveForwardReferences()
     return NS_OK;
 }
 
 //----------------------------------------------------------------------
 //
 // nsIDOMDocument interface
 //
 
-NS_IMETHODIMP
-XULDocument::GetElementsByAttribute(const nsAString& aAttribute,
-                                    const nsAString& aValue,
-                                    nsIDOMNodeList** aReturn)
-{
-    *aReturn = GetElementsByAttribute(aAttribute, aValue).take();
-    return NS_OK;
-}
-
 already_AddRefed<nsINodeList>
 XULDocument::GetElementsByAttribute(const nsAString& aAttribute,
                                     const nsAString& aValue)
 {
     RefPtr<nsAtom> attrAtom(NS_Atomize(aAttribute));
     void* attrValue = new nsString(aValue);
     RefPtr<nsContentList> list = new nsContentList(this,
                                             MatchAttribute,
@@ -1122,28 +1082,16 @@ XULDocument::GetElementsByAttribute(cons
                                             attrValue,
                                             true,
                                             attrAtom,
                                             kNameSpaceID_Unknown);
 
     return list.forget();
 }
 
-NS_IMETHODIMP
-XULDocument::GetElementsByAttributeNS(const nsAString& aNamespaceURI,
-                                      const nsAString& aAttribute,
-                                      const nsAString& aValue,
-                                      nsIDOMNodeList** aReturn)
-{
-    ErrorResult rv;
-    *aReturn = GetElementsByAttributeNS(aNamespaceURI, aAttribute,
-                                        aValue, rv).take();
-    return rv.StealNSResult();
-}
-
 already_AddRefed<nsINodeList>
 XULDocument::GetElementsByAttributeNS(const nsAString& aNamespaceURI,
                                       const nsAString& aAttribute,
                                       const nsAString& aValue,
                                       ErrorResult& aRv)
 {
     RefPtr<nsAtom> attrAtom(NS_Atomize(aAttribute));
     void* attrValue = new nsString(aValue);
@@ -1164,28 +1112,31 @@ XULDocument::GetElementsByAttributeNS(co
                                             nsContentUtils::DestroyMatchString,
                                             attrValue,
                                             true,
                                             attrAtom,
                                             nameSpaceId);
     return list.forget();
 }
 
-NS_IMETHODIMP
+void
 XULDocument::Persist(const nsAString& aID,
-                     const nsAString& aAttr)
+                     const nsAString& aAttr,
+                     ErrorResult& aRv)
 {
     // If we're currently reading persisted attributes out of the
     // localstore, _don't_ re-enter and try to set them again!
-    if (mApplyingPersistedAttrs)
-        return NS_OK;
+    if (mApplyingPersistedAttrs) {
+        return;
+    }
 
     Element* element = nsDocument::GetElementById(aID);
-    if (!element)
-        return NS_OK;
+    if (!element) {
+        return;
+    }
 
     RefPtr<nsAtom> tag;
     int32_t nameSpaceID;
 
     RefPtr<mozilla::dom::NodeInfo> ni = element->GetExistingAttrNameFromQName(aAttr);
     nsresult rv;
     if (ni) {
         tag = ni->NameAtom();
@@ -1193,31 +1144,36 @@ XULDocument::Persist(const nsAString& aI
     }
     else {
         // Make sure that this QName is going to be valid.
         const char16_t *colon;
         rv = nsContentUtils::CheckQName(PromiseFlatString(aAttr), true, &colon);
 
         if (NS_FAILED(rv)) {
             // There was an invalid character or it was malformed.
-            return NS_ERROR_INVALID_ARG;
+            aRv.Throw(NS_ERROR_INVALID_ARG);
+            return;
         }
 
         if (colon) {
             // We don't really handle namespace qualifiers in attribute names.
-            return NS_ERROR_NOT_IMPLEMENTED;
+            aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
+            return;
         }
 
         tag = NS_Atomize(aAttr);
-        NS_ENSURE_TRUE(tag, NS_ERROR_OUT_OF_MEMORY);
+        if (NS_WARN_IF(!tag)) {
+            aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
+            return;
+        }
 
         nameSpaceID = kNameSpaceID_None;
     }
 
-    return Persist(element, nameSpaceID, tag);
+    aRv = Persist(element, nameSpaceID, tag);
 }
 
 nsresult
 XULDocument::Persist(Element* aElement, int32_t aNameSpaceID,
                      nsAtom* aAttribute)
 {
     // For non-chrome documents, persistance is simply broken
     if (!nsContentUtils::IsSystemPrincipal(NodePrincipal()))
@@ -1276,239 +1232,139 @@ XULDocument::GetViewportSize(int32_t* aW
     nsSize size = frame->GetSize();
 
     *aWidth = nsPresContext::AppUnitsToIntCSSPixels(size.width);
     *aHeight = nsPresContext::AppUnitsToIntCSSPixels(size.height);
 
     return NS_OK;
 }
 
-NS_IMETHODIMP
-XULDocument::GetWidth(int32_t* aWidth)
-{
-    NS_ENSURE_ARG_POINTER(aWidth);
-
-    int32_t height;
-    return GetViewportSize(aWidth, &height);
-}
-
 int32_t
 XULDocument::GetWidth(ErrorResult& aRv)
 {
-    int32_t width;
-    aRv = GetWidth(&width);
+    int32_t width = 0;
+    int32_t height = 0;
+    aRv = GetViewportSize(&width, &height);
     return width;
 }
 
-NS_IMETHODIMP
-XULDocument::GetHeight(int32_t* aHeight)
-{
-    NS_ENSURE_ARG_POINTER(aHeight);
-
-    int32_t width;
-    return GetViewportSize(&width, aHeight);
-}
-
 int32_t
 XULDocument::GetHeight(ErrorResult& aRv)
 {
-    int32_t height;
-    aRv = GetHeight(&height);
+    int32_t width = 0;
+    int32_t height = 0;
+    aRv = GetViewportSize(&width, &height);
     return height;
 }
 
-JSObject*
-GetScopeObjectOfNode(nsIDOMNode* node)
+static JSObject*
+GetScopeObjectOfNode(nsINode* node)
 {
     MOZ_ASSERT(node, "Must not be called with null.");
 
     // Window root occasionally keeps alive a node of a document whose
     // window is already dead. If in this brief period someone calls
     // GetPopupNode and we return that node, nsNodeSH::PreCreate will throw,
     // because it will not know which scope this node belongs to. Returning
     // an orphan node like that to JS would be a bug anyway, so to avoid
     // this, let's do the same check as nsNodeSH::PreCreate does to
     // determine the scope and if it fails let's just return null in
     // XULDocument::GetPopupNode.
-    nsCOMPtr<nsINode> inode = do_QueryInterface(node);
-    MOZ_ASSERT(inode, "How can this happen?");
-
-    nsIDocument* doc = inode->OwnerDoc();
-    MOZ_ASSERT(inode, "This should never happen.");
+    nsIDocument* doc = node->OwnerDoc();
+    MOZ_ASSERT(doc, "This should never happen.");
 
     nsIGlobalObject* global = doc->GetScopeObject();
     return global ? global->GetGlobalJSObject() : nullptr;
 }
 
-//----------------------------------------------------------------------
-//
-// nsIDOMXULDocument interface
-//
-
-NS_IMETHODIMP
-XULDocument::GetPopupNode(nsIDOMNode** aNode)
+already_AddRefed<nsINode>
+XULDocument::GetPopupNode()
 {
-    *aNode = nullptr;
-
-    nsCOMPtr<nsIDOMNode> node;
+    nsCOMPtr<nsINode> node;
     nsCOMPtr<nsPIWindowRoot> rootWin = GetWindowRoot();
-    if (rootWin)
+    if (rootWin) {
         node = rootWin->GetPopupNode(); // addref happens here
+    }
 
     if (!node) {
         nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
         if (pm) {
             node = pm->GetLastTriggerPopupNode(this);
         }
     }
 
     if (node && nsContentUtils::CanCallerAccess(node)
         && GetScopeObjectOfNode(node)) {
-        node.forget(aNode);
+        return node.forget();
     }
 
-    return NS_OK;
-}
-
-already_AddRefed<nsINode>
-XULDocument::GetPopupNode()
-{
-    nsCOMPtr<nsIDOMNode> node;
-    DebugOnly<nsresult> rv = GetPopupNode(getter_AddRefs(node));
-    MOZ_ASSERT(NS_SUCCEEDED(rv));
-    nsCOMPtr<nsINode> retval(do_QueryInterface(node));
-    return retval.forget();
-}
-
-NS_IMETHODIMP
-XULDocument::SetPopupNode(nsIDOMNode* aNode)
-{
-    if (aNode) {
-        // only allow real node objects
-        nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
-        NS_ENSURE_ARG(node);
-    }
-
-    nsCOMPtr<nsPIWindowRoot> rootWin = GetWindowRoot();
-    if (rootWin)
-        rootWin->SetPopupNode(aNode); // addref happens here
-
-    return NS_OK;
+    return nullptr;
 }
 
 void
 XULDocument::SetPopupNode(nsINode* aNode)
 {
-    nsCOMPtr<nsIDOMNode> node(do_QueryInterface(aNode));
-    DebugOnly<nsresult> rv = SetPopupNode(node);
-    MOZ_ASSERT(NS_SUCCEEDED(rv));
+    nsCOMPtr<nsPIWindowRoot> rootWin = GetWindowRoot();
+    if (rootWin) {
+        rootWin->SetPopupNode(aNode);
+    }
 }
 
 // Returns the rangeOffset element from the XUL Popup Manager. This is for
 // chrome callers only.
-NS_IMETHODIMP
-XULDocument::GetPopupRangeParent(nsIDOMNode** aRangeParent)
-{
-    NS_ENSURE_ARG_POINTER(aRangeParent);
-    *aRangeParent = nullptr;
-
-    nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
-    if (!pm)
-        return NS_ERROR_FAILURE;
-
-    int32_t offset;
-    pm->GetMouseLocation(aRangeParent, &offset);
-
-    if (*aRangeParent && !nsContentUtils::CanCallerAccess(*aRangeParent)) {
-        NS_RELEASE(*aRangeParent);
-        return NS_ERROR_DOM_SECURITY_ERR;
-    }
-
-    return NS_OK;
-}
-
-already_AddRefed<nsINode>
+nsINode*
 XULDocument::GetPopupRangeParent(ErrorResult& aRv)
 {
-    nsCOMPtr<nsIDOMNode> node;
-    aRv = GetPopupRangeParent(getter_AddRefs(node));
-    nsCOMPtr<nsINode> retval(do_QueryInterface(node));
-    return retval.forget();
+    nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
+    if (!pm) {
+        aRv.Throw(NS_ERROR_FAILURE);
+        return nullptr;
+    }
+
+    nsINode* rangeParent = pm->GetMouseLocationParent();
+    if (rangeParent && !nsContentUtils::CanCallerAccess(rangeParent)) {
+        aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
+        return nullptr;
+    }
+
+    return rangeParent;
 }
 
-
 // Returns the rangeOffset element from the XUL Popup Manager. We check the
 // rangeParent to determine if the caller has rights to access to the data.
-NS_IMETHODIMP
-XULDocument::GetPopupRangeOffset(int32_t* aRangeOffset)
-{
-    ErrorResult rv;
-    *aRangeOffset = GetPopupRangeOffset(rv);
-    return rv.StealNSResult();
-}
-
 int32_t
 XULDocument::GetPopupRangeOffset(ErrorResult& aRv)
 {
     nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
     if (!pm) {
         aRv.Throw(NS_ERROR_FAILURE);
         return 0;
     }
 
-    int32_t offset;
-    nsCOMPtr<nsIDOMNode> parent;
-    pm->GetMouseLocation(getter_AddRefs(parent), &offset);
-
-    if (parent && !nsContentUtils::CanCallerAccess(parent)) {
+    nsINode* rangeParent = pm->GetMouseLocationParent();
+    if (rangeParent && !nsContentUtils::CanCallerAccess(rangeParent)) {
         aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
         return 0;
     }
-    return offset;
-}
-
-NS_IMETHODIMP
-XULDocument::GetTooltipNode(nsIDOMNode** aNode)
-{
-    *aNode = nullptr;
-
-    nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
-    if (pm) {
-        nsCOMPtr<nsIDOMNode> node = pm->GetLastTriggerTooltipNode(this);
-        if (node && nsContentUtils::CanCallerAccess(node))
-            node.forget(aNode);
-    }
-
-    return NS_OK;
+
+    return pm->MouseLocationOffset();
 }
 
 already_AddRefed<nsINode>
 XULDocument::GetTooltipNode()
 {
-    nsCOMPtr<nsIDOMNode> node;
-    DebugOnly<nsresult> rv = GetTooltipNode(getter_AddRefs(node));
-    MOZ_ASSERT(NS_SUCCEEDED(rv));
-    nsCOMPtr<nsINode> retval(do_QueryInterface(node));
-    return retval.forget();
-}
-
-NS_IMETHODIMP
-XULDocument::SetTooltipNode(nsIDOMNode* aNode)
-{
-    // do nothing
-    return NS_OK;
-}
-
-
-NS_IMETHODIMP
-XULDocument::GetCommandDispatcher(nsIDOMXULCommandDispatcher** aTracker)
-{
-    *aTracker = mCommandDispatcher;
-    NS_IF_ADDREF(*aTracker);
-    return NS_OK;
+    nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
+    if (pm) {
+        nsCOMPtr<nsINode> node = pm->GetLastTriggerTooltipNode(this);
+        if (node && nsContentUtils::CanCallerAccess(node)) {
+            return node.forget();
+        }
+    }
+
+    return nullptr;
 }
 
 nsresult
 XULDocument::AddElementToDocumentPre(Element* aElement)
 {
     // Do a bunch of work that's necessary when an element gets added
     // to the XUL Document.
     nsresult rv;
@@ -1559,17 +1415,17 @@ XULDocument::AddElementToDocumentPost(El
     if (aElement->NodeInfo()->Equals(nsGkAtoms::keyset, kNameSpaceID_XUL)) {
         // Create our XUL key listener and hook it up.
         nsXBLService::AttachGlobalKeyHandler(aElement);
     }
 
     return NS_OK;
 }
 
-NS_IMETHODIMP
+nsresult
 XULDocument::AddSubtreeToDocument(nsIContent* aContent)
 {
     NS_ASSERTION(aContent->GetUncomposedDoc() == this, "Element not in doc!");
     // From here on we only care about elements.
     if (!aContent->IsElement()) {
         return NS_OK;
     }
 
@@ -1588,17 +1444,17 @@ XULDocument::AddSubtreeToDocument(nsICon
         if (NS_FAILED(rv))
             return rv;
     }
 
     // Do post-order addition magic
     return AddElementToDocumentPost(aElement);
 }
 
-NS_IMETHODIMP
+nsresult
 XULDocument::RemoveSubtreeFromDocument(nsIContent* aContent)
 {
     // From here on we only care about elements.
     if (!aContent->IsElement()) {
         return NS_OK;
     }
 
     Element* aElement = aContent->AsElement();
@@ -2302,44 +2158,54 @@ XULDocument::AddChromeOverlays()
 
         // Same comment as in XULDocument::InsertXULOverlayPI
         mUnloadedOverlays.InsertElementAt(0, uri);
     }
 
     return rv;
 }
 
-NS_IMETHODIMP
-XULDocument::LoadOverlay(const nsAString& aURL, nsIObserver* aObserver)
+void
+XULDocument::LoadOverlay(const nsAString& aURL, nsIObserver* aObserver,
+                         ErrorResult& aRv)
 {
     nsresult rv;
 
     nsCOMPtr<nsIURI> uri;
     rv = NS_NewURI(getter_AddRefs(uri), aURL, nullptr);
-    if (NS_FAILED(rv)) return rv;
+    if (NS_FAILED(rv)) {
+        aRv.Throw(rv);
+        return;
+    }
 
     if (aObserver) {
         nsIObserver* obs = nullptr;
         if (!mOverlayLoadObservers) {
           mOverlayLoadObservers = new nsInterfaceHashtable<nsURIHashKey,nsIObserver>;
         }
         obs = mOverlayLoadObservers->GetWeak(uri);
 
         if (obs) {
             // We don't support loading the same overlay twice into the same
             // document - that doesn't make sense anyway.
-            return NS_ERROR_FAILURE;
+            aRv.Throw(NS_ERROR_FAILURE);
+            return;
         }
         mOverlayLoadObservers->Put(uri, aObserver);
     }
     bool shouldReturn, failureFromContent;
     rv = LoadOverlayInternal(uri, true, &shouldReturn, &failureFromContent);
-    if (NS_FAILED(rv) && mOverlayLoadObservers)
-        mOverlayLoadObservers->Remove(uri); // remove the observer if LoadOverlayInternal generated an error
-    return rv;
+    if (NS_FAILED(rv)) {
+        // remove the observer if LoadOverlayInternal generated an error
+        if (mOverlayLoadObservers) {
+            mOverlayLoadObservers->Remove(uri);
+        }
+        aRv.Throw(rv);
+        return;
+    }
 }
 
 nsresult
 XULDocument::LoadOverlayInternal(nsIURI* aURI, bool aIsDynamic,
                                  bool* aShouldReturn,
                                  bool* aFailureFromContent)
 {
     nsresult rv;
@@ -4274,25 +4140,16 @@ XULDocument::ThreadSafeGetDocumentLWThem
                 theme = Doc_Theme_Dark;
             else if (lwTheme.EqualsLiteral("bright"))
                 theme = Doc_Theme_Bright;
         }
     }
     return theme;
 }
 
-NS_IMETHODIMP
-XULDocument::GetBoxObjectFor(nsIDOMElement* aElement, nsIBoxObject** aResult)
-{
-    ErrorResult rv;
-    nsCOMPtr<Element> el = do_QueryInterface(aElement);
-    *aResult = GetBoxObjectFor(el, rv).take();
-    return rv.StealNSResult();
-}
-
 JSObject*
 XULDocument::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
   return XULDocumentBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/xul/XULDocument.h
+++ b/dom/xul/XULDocument.h
@@ -4,63 +4,62 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_XULDocument_h
 #define mozilla_dom_XULDocument_h
 
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "nsXULPrototypeDocument.h"
-#include "nsXULPrototypeCache.h"
 #include "nsTArray.h"
 
 #include "mozilla/dom/XMLDocument.h"
 #include "mozilla/StyleSheet.h"
 #include "nsForwardReference.h"
 #include "nsIContent.h"
 #include "nsIDOMXULCommandDispatcher.h"
-#include "nsIDOMXULDocument.h"
 #include "nsCOMArray.h"
 #include "nsIURI.h"
-#include "nsIXULDocument.h"
 #include "nsIStreamListener.h"
 #include "nsIStreamLoader.h"
 #include "nsICSSLoaderObserver.h"
 #include "nsIXULStore.h"
 
 #include "mozilla/Attributes.h"
 #include "mozilla/dom/ScriptLoader.h"
 
 #include "js/TracingAPI.h"
 #include "js/TypeDecls.h"
 
 class nsIRDFResource;
 class nsIRDFService;
 class nsPIWindowRoot;
+class nsXULPrototypeElement;
 #if 0 // XXXbe save me, scc (need NSCAP_FORWARD_DECL(nsXULPrototypeScript))
 class nsIObjectInputStream;
 class nsIObjectOutputStream;
 #else
 #include "nsIObjectInputStream.h"
 #include "nsIObjectOutputStream.h"
 #include "nsXULElement.h"
 #endif
 #include "nsURIHashKey.h"
 #include "nsInterfaceHashtable.h"
 
 /**
  * The XUL document class
  */
 
+// Factory function.
+nsresult NS_NewXULDocument(nsIDocument** result);
+
 namespace mozilla {
 namespace dom {
 
 class XULDocument final : public XMLDocument,
-                          public nsIXULDocument,
-                          public nsIDOMXULDocument,
                           public nsIStreamLoaderObserver,
                           public nsICSSLoaderObserver,
                           public nsIOffThreadScriptReceiver
 {
 public:
     XULDocument();
 
     // nsISupports interface
@@ -79,27 +78,49 @@ public:
                                        nsIStreamListener **aDocListener,
                                        bool aReset = true,
                                        nsIContentSink* aSink = nullptr) override;
 
     virtual void SetContentType(const nsAString& aContentType) override;
 
     virtual void EndLoad() override;
 
+    virtual XULDocument* AsXULDocument() override {
+        return this;
+    }
+
     // nsIMutationObserver interface
     NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
     NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
     NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
     NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
 
-    // nsIXULDocument interface
-    NS_IMETHOD AddSubtreeToDocument(nsIContent* aContent) override;
-    NS_IMETHOD RemoveSubtreeFromDocument(nsIContent* aContent) override;
-    NS_IMETHOD OnPrototypeLoadDone(bool aResumeWalk) override;
-    bool OnDocumentParserError() override;
+    /**
+     * Notify the XUL document that a subtree has been added
+     */
+    nsresult AddSubtreeToDocument(nsIContent* aContent);
+    /**
+     * Notify the XUL document that a subtree has been removed
+     */
+    nsresult RemoveSubtreeFromDocument(nsIContent* aContent);
+    /**
+     * This is invoked whenever the prototype for this document is loaded
+     * and should be walked, regardless of whether the XUL cache is
+     * disabled, whether the protototype was loaded, whether the
+     * prototype was loaded from the cache or created by parsing the
+     * actual XUL source, etc.
+     *
+     * @param aResumeWalk whether this should also call ResumeWalk().
+     * Sometimes the caller of OnPrototypeLoadDone resumes the walk itself
+     */
+    nsresult OnPrototypeLoadDone(bool aResumeWalk);
+    /**
+     * Callback notifying when a document could not be parsed properly.
+     */
+    bool OnDocumentParserError();
 
     // nsINode interface overrides
     virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,
                            bool aPreallocateChildren) const override;
 
     // nsIDOMDocument interface
     using nsDocument::CreateElement;
     using nsDocument::CreateElementNS;
@@ -108,51 +129,51 @@ public:
     using mozilla::dom::DocumentOrShadowRoot::GetElementById;
     using nsDocument::GetImplementation;
     using nsDocument::GetTitle;
     using nsDocument::SetTitle;
     using nsDocument::GetLastStyleSheetSet;
     using nsDocument::MozSetImageElement;
     using nsIDocument::GetLocation;
 
-    // nsIDOMXULDocument interface
-    NS_DECL_NSIDOMXULDOCUMENT
-
     // nsICSSLoaderObserver
     NS_IMETHOD StyleSheetLoaded(mozilla::StyleSheet* aSheet,
                                 bool aWasAlternate,
                                 nsresult aStatus) override;
 
     virtual void EndUpdate(nsUpdateType aUpdateType) override;
 
     virtual bool IsDocumentRightToLeft() override;
 
-    virtual void ResetDocumentDirection() override;
+    /**
+     * Reset the document direction so that it is recomputed.
+     */
+    void ResetDocumentDirection();
 
     virtual nsIDocument::DocumentTheme GetDocumentLWTheme() override;
     virtual nsIDocument::DocumentTheme ThreadSafeGetDocumentLWTheme() const override;
 
-    virtual void ResetDocumentLWTheme() override { mDocLWTheme = Doc_Theme_Uninitialized; }
+    void ResetDocumentLWTheme() { mDocLWTheme = Doc_Theme_Uninitialized; }
 
     NS_IMETHOD OnScriptCompileComplete(JSScript* aScript, nsresult aStatus) override;
 
     static bool
     MatchAttribute(Element* aContent,
                    int32_t aNameSpaceID,
                    nsAtom* aAttrName,
                    void* aData);
 
     NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(XULDocument, XMLDocument)
 
     void TraceProtos(JSTracer* aTrc);
 
     // WebIDL API
     already_AddRefed<nsINode> GetPopupNode();
     void SetPopupNode(nsINode* aNode);
-    already_AddRefed<nsINode> GetPopupRangeParent(ErrorResult& aRv);
+    nsINode* GetPopupRangeParent(ErrorResult& aRv);
     int32_t GetPopupRangeOffset(ErrorResult& aRv);
     already_AddRefed<nsINode> GetTooltipNode();
     void SetTooltipNode(nsINode* aNode) { /* do nothing */ }
     nsIDOMXULCommandDispatcher* GetCommandDispatcher() const
     {
         return mCommandDispatcher;
     }
     int32_t GetWidth(ErrorResult& aRv);
@@ -164,33 +185,28 @@ public:
       GetElementsByAttributeNS(const nsAString& aNamespaceURI,
                                const nsAString& aAttribute,
                                const nsAString& aValue,
                                ErrorResult& aRv);
     void AddBroadcastListenerFor(Element& aBroadcaster, Element& aListener,
                                  const nsAString& aAttr, ErrorResult& aRv);
     void RemoveBroadcastListenerFor(Element& aBroadcaster, Element& aListener,
                                     const nsAString& aAttr);
-    void Persist(const nsAString& aId, const nsAString& aAttr, ErrorResult& aRv)
-    {
-        aRv = Persist(aId, aAttr);
-    }
+    void Persist(const nsAString& aId, const nsAString& aAttr,
+                 ErrorResult& aRv);
     using nsDocument::GetBoxObjectFor;
     void LoadOverlay(const nsAString& aURL, nsIObserver* aObserver,
-                     ErrorResult& aRv)
-    {
-        aRv = LoadOverlay(aURL, aObserver);
-    }
+                     ErrorResult& aRv);
 
 protected:
     virtual ~XULDocument();
 
     // Implementation methods
     friend nsresult
-    (::NS_NewXULDocument(nsIXULDocument** aResult));
+    (::NS_NewXULDocument(nsIDocument** aResult));
 
     nsresult Init(void) override;
     nsresult StartLayout(void);
 
     nsresult GetViewportSize(int32_t* aWidth, int32_t* aHeight);
 
     nsresult PrepareToLoad(nsISupports* aContainer,
                            const char* aCommand,
--- a/dom/xul/moz.build
+++ b/dom/xul/moz.build
@@ -12,17 +12,16 @@ MOCHITEST_MANIFESTS += ['test/mochitest.
 MOCHITEST_CHROME_MANIFESTS += ['test/chrome.ini']
 
 if CONFIG['MOZ_XUL']:
     XPIDL_SOURCES += [
         'nsIXULOverlayProvider.idl',
     ]
 
     EXPORTS += [
-        'nsIXULDocument.h',
         'nsXULElement.h',
     ]
 
     UNIFIED_SOURCES += [
         'nsXULCommandDispatcher.cpp',
         'nsXULContentSink.cpp',
         'nsXULContentUtils.cpp',
         'nsXULElement.cpp',
deleted file mode 100644
--- a/dom/xul/nsIXULDocument.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/* -*- 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/. */
-
-#ifndef nsIXULDocument_h___
-#define nsIXULDocument_h___
-
-#include "nsISupports.h"
-#include "nsString.h"
-#include "nsCOMArray.h"
-
-class nsIXULTemplateBuilder;
-class nsIContent;
-
-namespace mozilla {
-namespace dom {
-class Element;
-}
-}
-
-
-// 81ba4be5-6cc5-478a-9b08-b3e7ed524455
-#define NS_IXULDOCUMENT_IID \
-  {0x81ba4be5, 0x6cc5, 0x478a, {0x9b, 0x08, 0xb3, 0xe7, 0xed, 0x52, 0x44, 0x55}}
-
-
-/*
- * An XUL-specific extension to nsIDocument. Includes methods for
- * setting the root resource of the document content model, a factory
- * method for constructing the children of a node, etc.
- */
-class nsIXULDocument : public nsISupports
-{
-public:
-  NS_DECLARE_STATIC_IID_ACCESSOR(NS_IXULDOCUMENT_IID)
-
-  /**
-   * Notify the XUL document that a subtree has been added
-   */
-  NS_IMETHOD AddSubtreeToDocument(nsIContent* aElement) = 0;
-
-  /**
-   * Notify the XUL document that a subtree has been removed
-   */
-  NS_IMETHOD RemoveSubtreeFromDocument(nsIContent* aElement) = 0;
-
-  /**
-   * This is invoked whenever the prototype for this document is loaded
-   * and should be walked, regardless of whether the XUL cache is
-   * disabled, whether the protototype was loaded, whether the
-   * prototype was loaded from the cache or created by parsing the
-   * actual XUL source, etc.
-   *
-   * @param aResumeWalk whether this should also call ResumeWalk().
-   * Sometimes the caller of OnPrototypeLoadDone resumes the walk itself
-   */
-  NS_IMETHOD OnPrototypeLoadDone(bool aResumeWalk) = 0;
-
-  /**
-   * Callback notifying when a document could not be parsed properly.
-   */
-  virtual bool OnDocumentParserError() = 0;
-
-  /**
-   * Reset the document direction so that it is recomputed.
-   */
-  virtual void ResetDocumentDirection() = 0;
-
-  virtual void ResetDocumentLWTheme() = 0;
-};
-
-NS_DEFINE_STATIC_IID_ACCESSOR(nsIXULDocument, NS_IXULDOCUMENT_IID)
-
-// factory functions
-nsresult NS_NewXULDocument(nsIXULDocument** result);
-
-#endif // nsIXULDocument_h___
--- a/dom/xul/nsXULContentSink.cpp
+++ b/dom/xul/nsXULContentSink.cpp
@@ -18,27 +18,25 @@
 
 #include "nsCOMPtr.h"
 #include "nsForwardReference.h"
 #include "nsHTMLStyleSheet.h"
 #include "nsIContentSink.h"
 #include "nsIDocument.h"
 #include "nsIDOMEventListener.h"
 #include "nsIDOMHTMLFormElement.h"
-#include "nsIDOMXULDocument.h"
 #include "nsIFormControl.h"
 #include "mozilla/dom/NodeInfo.h"
 #include "nsIScriptContext.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIServiceManager.h"
 #include "nsIURL.h"
 #include "nsNameSpaceManager.h"
 #include "nsParserBase.h"
 #include "nsViewManager.h"
-#include "nsIXULDocument.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsLayoutCID.h"
 #include "nsNetUtil.h"
 #include "nsRDFCID.h"
 #include "nsString.h"
 #include "nsReadableUtils.h"
 #include "nsXULElement.h"
 #include "mozilla/Logging.h"
@@ -50,16 +48,17 @@
 #include "nsUnicharUtils.h"
 #include "nsGkAtoms.h"
 #include "nsContentUtils.h"
 #include "nsAttrName.h"
 #include "nsXMLContentSink.h"
 #include "nsIConsoleService.h"
 #include "nsIScriptError.h"
 #include "nsContentTypeParser.h"
+#include "XULDocument.h"
 
 static mozilla::LazyLogModule gContentSinkLog("nsXULContentSink");;
 
 //----------------------------------------------------------------------
 
 XULContentSinkImpl::ContextStack::ContextStack()
     : mTop(nullptr), mDepth(0)
 {
@@ -670,17 +669,17 @@ XULContentSinkImpl::ReportError(const ch
   mTextLength = 0;
 
   // return leaving the document empty if we're asked to not add a <parsererror> root node
   nsCOMPtr<nsIDocument> idoc = do_QueryReferent(mDocument);
   if (idoc && idoc->SuppressParserErrorElement()) {
     return NS_OK;
   };
 
-  nsCOMPtr<nsIXULDocument> doc = do_QueryReferent(mDocument);
+  XULDocument* doc = idoc ? idoc->AsXULDocument() : nullptr;
   if (doc && !doc->OnDocumentParserError()) {
     // The overlay was broken.  Don't add a messy element to the master doc.
     return NS_OK;
   }
 
   const char16_t* noAtts[] = { 0, 0 };
 
   NS_NAMED_LITERAL_STRING(errorNs,
--- a/dom/xul/nsXULContentUtils.cpp
+++ b/dom/xul/nsXULContentUtils.cpp
@@ -15,26 +15,27 @@
 
 #include "nsCollationCID.h"
 #include "nsCOMPtr.h"
 #include "nsIContent.h"
 #include "nsICollation.h"
 #include "nsIDocument.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMXULCommandDispatcher.h"
-#include "nsIDOMXULDocument.h"
 #include "nsIRDFService.h"
 #include "nsIServiceManager.h"
 #include "nsXULContentUtils.h"
 #include "nsLayoutCID.h"
 #include "nsRDFCID.h"
 #include "nsString.h"
 #include "nsGkAtoms.h"
+#include "XULDocument.h"
 
 using namespace mozilla;
+using dom::XULDocument;
 
 //------------------------------------------------------------------------
 
 nsIRDFService* nsXULContentUtils::gRDF;
 nsICollation *nsXULContentUtils::gCollation;
 
 //------------------------------------------------------------------------
 // Constructors n' stuff
@@ -115,26 +116,23 @@ nsXULContentUtils::SetCommandUpdater(nsI
         return NS_ERROR_NULL_POINTER;
 
     NS_PRECONDITION(aElement != nullptr, "null ptr");
     if (! aElement)
         return NS_ERROR_NULL_POINTER;
 
     nsresult rv;
 
-    nsCOMPtr<nsIDOMXULDocument> xuldoc = do_QueryInterface(aDocument);
+    XULDocument* xuldoc = aDocument->AsXULDocument();
     NS_ASSERTION(xuldoc != nullptr, "not a xul document");
     if (! xuldoc)
         return NS_ERROR_UNEXPECTED;
 
-    nsCOMPtr<nsIDOMXULCommandDispatcher> dispatcher;
-    rv = xuldoc->GetCommandDispatcher(getter_AddRefs(dispatcher));
-    NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get dispatcher");
-    if (NS_FAILED(rv)) return rv;
-
+    nsCOMPtr<nsIDOMXULCommandDispatcher> dispatcher =
+        xuldoc->GetCommandDispatcher();
     NS_ASSERTION(dispatcher != nullptr, "no dispatcher");
     if (! dispatcher)
         return NS_ERROR_UNEXPECTED;
 
     nsAutoString events;
     aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::events, events);
     if (events.IsEmpty())
         events.Assign('*');
--- a/dom/xul/nsXULElement.cpp
+++ b/dom/xul/nsXULElement.cpp
@@ -35,17 +35,16 @@
 #include "nsIScriptContext.h"
 #include "nsIScriptError.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIServiceManager.h"
 #include "mozilla/css/StyleRule.h"
 #include "nsIURL.h"
 #include "nsViewManager.h"
 #include "nsIWidget.h"
-#include "nsIXULDocument.h"
 #include "nsLayoutCID.h"
 #include "nsContentCID.h"
 #include "mozilla/dom/Event.h"
 #include "nsStyleConsts.h"
 #include "nsString.h"
 #include "nsXULControllers.h"
 #include "nsIBoxObject.h"
 #include "nsPIBoxObject.h"
@@ -70,19 +69,16 @@
 #include "nsAttrValueOrString.h"
 #include "nsAttrValueInlines.h"
 #include "mozilla/Attributes.h"
 #include "nsIController.h"
 #include "nsQueryObject.h"
 #include <algorithm>
 #include "nsIDOMChromeWindow.h"
 
-// The XUL doc interface
-#include "nsIDOMXULDocument.h"
-
 #include "nsReadableUtils.h"
 #include "nsIFrame.h"
 #include "nsNodeInfoManager.h"
 #include "nsXBLBinding.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozAutoDocUpdate.h"
 #include "nsIDOMXULCommandEvent.h"
 #include "nsCCUncollectableMarker.h"
@@ -551,32 +547,30 @@ nsXULElement::IsFocusableInternal(int32_
 
 bool
 nsXULElement::PerformAccesskey(bool aKeyCausesActivation,
                                bool aIsTrustedEvent)
 {
     nsCOMPtr<nsIContent> content(this);
 
     if (IsXULElement(nsGkAtoms::label)) {
-        nsCOMPtr<nsIDOMElement> element;
-
         nsAutoString control;
         GetAttr(kNameSpaceID_None, nsGkAtoms::control, control);
-        if (!control.IsEmpty()) {
-            //XXXsmaug Should we use ShadowRoot::GetElementById in case
-            //         content is in Shadow DOM?
-            nsCOMPtr<nsIDOMDocument> domDocument =
-                do_QueryInterface(content->GetUncomposedDoc());
-            if (domDocument)
-                domDocument->GetElementById(control, getter_AddRefs(element));
+        if (control.IsEmpty()) {
+            return false;
         }
-        // here we'll either change |content| to the element referenced by
-        // |element|, or clear it.
-        content = do_QueryInterface(element);
-
+
+        //XXXsmaug Should we use ShadowRoot::GetElementById in case
+        //         content is in Shadow DOM?
+        nsCOMPtr<nsIDocument> document = content->GetUncomposedDoc();
+        if (!document) {
+            return false;
+        }
+
+        content = document->GetElementById(control);
         if (!content) {
             return false;
         }
     }
 
     nsIFrame* frame = content->GetPrimaryFrame();
     if (!frame || !frame->IsVisibleConsideringAncestors()) {
         return false;
@@ -1152,24 +1146,24 @@ nsXULElement::AfterSetAttr(int32_t aName
                 } else if (aName == nsGkAtoms::drawintitlebar) {
                     SetDrawsInTitlebar(
                         aValue->Equals(NS_LITERAL_STRING("true"), eCaseMatters));
                 } else if (aName == nsGkAtoms::drawtitle) {
                     SetDrawsTitle(
                         aValue->Equals(NS_LITERAL_STRING("true"), eCaseMatters));
                 } else if (aName == nsGkAtoms::localedir) {
                     // if the localedir changed on the root element, reset the document direction
-                    nsCOMPtr<nsIXULDocument> xuldoc = do_QueryInterface(document);
+                    XULDocument* xuldoc = document->AsXULDocument();
                     if (xuldoc) {
                         xuldoc->ResetDocumentDirection();
                     }
                 } else if (aName == nsGkAtoms::lwtheme ||
                          aName == nsGkAtoms::lwthemetextcolor) {
                     // if the lwtheme changed, make sure to reset the document lwtheme cache
-                    nsCOMPtr<nsIXULDocument> xuldoc = do_QueryInterface(document);
+                    XULDocument* xuldoc = document->AsXULDocument();
                     if (xuldoc) {
                         xuldoc->ResetDocumentLWTheme();
                         UpdateBrightTitlebarForeground(document);
                     }
                 } else if (aName == nsGkAtoms::brighttitlebarforeground) {
                     UpdateBrightTitlebarForeground(document);
                 }
             }
@@ -1189,24 +1183,24 @@ nsXULElement::AfterSetAttr(int32_t aName
             nsIDocument* doc = GetUncomposedDoc();
             if (doc && doc->GetRootElement() == this) {
                 if ((aName == nsGkAtoms::activetitlebarcolor ||
                      aName == nsGkAtoms::inactivetitlebarcolor)) {
                     // Use 0, 0, 0, 0 as the "none" color.
                     SetTitlebarColor(NS_RGBA(0, 0, 0, 0), aName == nsGkAtoms::activetitlebarcolor);
                 } else if (aName == nsGkAtoms::localedir) {
                     // if the localedir changed on the root element, reset the document direction
-                    nsCOMPtr<nsIXULDocument> xuldoc = do_QueryInterface(doc);
+                    XULDocument* xuldoc = doc->AsXULDocument();
                     if (xuldoc) {
                         xuldoc->ResetDocumentDirection();
                     }
                 } else if ((aName == nsGkAtoms::lwtheme ||
                             aName == nsGkAtoms::lwthemetextcolor)) {
                     // if the lwtheme changed, make sure to restyle appropriately
-                    nsCOMPtr<nsIXULDocument> xuldoc = do_QueryInterface(doc);
+                    XULDocument* xuldoc = doc->AsXULDocument();
                     if (xuldoc) {
                         xuldoc->ResetDocumentLWTheme();
                         UpdateBrightTitlebarForeground(doc);
                     }
                 } else if (aName == nsGkAtoms::brighttitlebarforeground) {
                     UpdateBrightTitlebarForeground(doc);
                 } else if (aName == nsGkAtoms::drawintitlebar) {
                     SetDrawsInTitlebar(false);
@@ -1239,24 +1233,22 @@ nsXULElement::ParseAttribute(int32_t aNa
     }
 
     return true;
 }
 
 void
 nsXULElement::RemoveBroadcaster(const nsAString & broadcasterId)
 {
-    nsCOMPtr<nsIDOMXULDocument> xuldoc = do_QueryInterface(OwnerDoc());
+    XULDocument* xuldoc = OwnerDoc()->AsXULDocument();
     if (xuldoc) {
-        nsCOMPtr<nsIDOMElement> broadcaster;
-        nsCOMPtr<nsIDOMDocument> domDoc (do_QueryInterface(xuldoc));
-        domDoc->GetElementById(broadcasterId, getter_AddRefs(broadcaster));
+        Element* broadcaster = xuldoc->GetElementById(broadcasterId);
         if (broadcaster) {
-            xuldoc->RemoveBroadcastListenerFor(broadcaster, this,
-              NS_LITERAL_STRING("*"));
+            xuldoc->RemoveBroadcastListenerFor(*broadcaster, *this,
+                                               NS_LITERAL_STRING("*"));
         }
     }
 }
 
 void
 nsXULElement::DestroyContent()
 {
     nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
@@ -1296,44 +1288,42 @@ nsXULElement::IsEventStoppedFromAnonymou
              aMessage == eDragStart  || aMessage == eMouseAuxClick));
 }
 
 nsresult
 nsXULElement::DispatchXULCommand(const EventChainVisitor& aVisitor,
                                  nsAutoString& aCommand)
 {
     // XXX sXBL/XBL2 issue! Owner or current document?
-    nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(GetUncomposedDoc()));
-    NS_ENSURE_STATE(domDoc);
-    nsCOMPtr<nsIDOMElement> commandElt;
-    domDoc->GetElementById(aCommand, getter_AddRefs(commandElt));
-    nsCOMPtr<nsIContent> commandContent(do_QueryInterface(commandElt));
-    if (commandContent) {
+    nsCOMPtr<nsIDocument> doc = GetUncomposedDoc();
+    NS_ENSURE_STATE(doc);
+    RefPtr<Element> commandElt = doc->GetElementById(aCommand);
+    if (commandElt) {
         // Create a new command event to dispatch to the element
         // pointed to by the command attribute. The new event's
         // sourceEvent will be the original command event that we're
         // handling.
         nsCOMPtr<nsIDOMEvent> domEvent = aVisitor.mDOMEvent;
         uint16_t inputSource = nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN;
         while (domEvent) {
             Event* event = domEvent->InternalDOMEvent();
             NS_ENSURE_STATE(!SameCOMIdentity(event->GetOriginalTarget(),
-                                            commandContent));
+                                             commandElt));
             nsCOMPtr<nsIDOMXULCommandEvent> commandEvent =
                 do_QueryInterface(domEvent);
             if (commandEvent) {
                 commandEvent->GetSourceEvent(getter_AddRefs(domEvent));
                 commandEvent->GetInputSource(&inputSource);
             } else {
                 domEvent = nullptr;
             }
         }
         WidgetInputEvent* orig = aVisitor.mEvent->AsInputEvent();
         nsContentUtils::DispatchXULCommand(
-          commandContent,
+          commandElt,
           orig->IsTrusted(),
           aVisitor.mDOMEvent,
           nullptr,
           orig->IsControl(),
           orig->IsAlt(),
           orig->IsShift(),
           orig->IsMeta(),
           inputSource);
--- a/dom/xul/nsXULPopupListener.cpp
+++ b/dom/xul/nsXULPopupListener.cpp
@@ -16,17 +16,16 @@
 #include "nsIDOMNodeList.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMDocumentXBL.h"
 #include "nsContentCID.h"
 #include "nsContentUtils.h"
 #include "nsXULPopupManager.h"
 #include "nsIScriptContext.h"
 #include "nsIDOMWindow.h"
-#include "nsIDOMXULDocument.h"
 #include "nsIDocument.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIPrincipal.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsLayoutUtils.h"
 #include "mozilla/ReflowInput.h"
 #include "nsIObjectLoadingContent.h"
 #include "mozilla/EventStateManager.h"
--- a/dom/xul/nsXULPrototypeDocument.h
+++ b/dom/xul/nsXULPrototypeDocument.h
@@ -99,17 +99,17 @@ public:
      * Otherwise sets aLoaded to true.
      */
     nsresult AwaitLoadDone(mozilla::dom::XULDocument* aDocument, bool* aResult);
 
     /**
      * Notifies each document registered via AwaitLoadDone on this
      * prototype document that the prototype has finished loading.
      * The notification is performed by calling
-     * nsIXULDocument::OnPrototypeLoadDone on the registered documents.
+     * XULDocument::OnPrototypeLoadDone on the registered documents.
      */
     nsresult NotifyLoadDone();
 
     nsNodeInfoManager *GetNodeInfoManager();
 
     void MarkInCCGeneration(uint32_t aCCGeneration);
 
     NS_DECL_CYCLE_COLLECTION_CLASS(nsXULPrototypeDocument)
--- a/editor/composer/nsEditingSession.cpp
+++ b/editor/composer/nsEditingSession.cpp
@@ -314,18 +314,18 @@ nsEditingSession::SetupEditorOnWindow(mo
   //must get the content type
   // Note: the doc gets this from the network channel during StartPageLoad,
   //    so we don't have to get it from there ourselves
   nsAutoCString mimeCType;
 
   //then lets check the mime type
   if (nsCOMPtr<nsIDocument> doc = window->GetDoc()) {
     nsAutoString mimeType;
-    if (NS_SUCCEEDED(doc->GetContentType(mimeType)))
-      AppendUTF16toUTF8(mimeType, mimeCType);
+    doc->GetContentType(mimeType);
+    AppendUTF16toUTF8(mimeType, mimeCType);
 
     if (IsSupportedTextType(mimeCType.get())) {
       mEditorType.AssignLiteral("text");
       mimeCType = "text/plain";
     } else if (!mimeCType.EqualsLiteral("text/html") &&
                !mimeCType.EqualsLiteral("application/xhtml+xml")) {
       // Neither an acceptable text or html type.
       mEditorStatus = eEditorErrorCantEditMimeType;
@@ -443,19 +443,18 @@ nsEditingSession::SetupEditorOnWindow(mo
   rv = htmlEditor->SetContentsMIMEType(mimeCType.get());
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIContentViewer> contentViewer;
   rv = docShell->GetContentViewer(getter_AddRefs(contentViewer));
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ENSURE_TRUE(contentViewer, NS_ERROR_FAILURE);
 
-  nsCOMPtr<nsIDOMDocument> domDoc;
-  rv = contentViewer->GetDOMDocument(getter_AddRefs(domDoc));
-  NS_ENSURE_SUCCESS(rv, rv);
+  nsCOMPtr<nsIDOMDocument> domDoc =
+    do_QueryInterface(contentViewer->GetDocument());
   NS_ENSURE_TRUE(domDoc, NS_ERROR_FAILURE);
 
   // Set up as a doc state listener
   // Important! We must have this to broadcast the "obs_documentCreated" message
   rv = htmlEditor->AddDocumentStateListener(mComposerCommandsUpdater);
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = htmlEditor->Init(domDoc, nullptr /* root content */,
--- a/editor/libeditor/TextEditorTest.cpp
+++ b/editor/libeditor/TextEditorTest.cpp
@@ -7,22 +7,24 @@
 
 #include "TextEditorTest.h"
 
 #include <stdio.h>
 
 #include "nsDebug.h"
 #include "nsError.h"
 #include "nsGkAtoms.h"
+#include "nsIDocument.h"
 #include "nsIDOMCharacterData.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMNode.h"
 #include "nsIDOMNodeList.h"
 #include "nsIEditor.h"
 #include "nsIHTMLEditor.h"
+#include "nsINodeList.h"
 #include "nsIPlaintextEditor.h"
 #include "nsISelection.h"
 #include "nsLiteralString.h"
 #include "nsReadableUtils.h"
 #include "nsString.h"
 #include "nsStringFwd.h"
 
 #define TEST_RESULT(r) { if (NS_FAILED(r)) {printf("FAILURE result=%X\n", static_cast<uint32_t>(r)); return r; } }
@@ -125,41 +127,37 @@ nsresult TextEditorTest::TestInsertBreak
   TEST_RESULT(rv);
   mEditor->DebugDumpContent();
 
   return rv;
 }
 
 nsresult TextEditorTest::TestTextProperties()
 {
-  nsCOMPtr<nsIDOMDocument>doc;
-  nsresult rv = mEditor->GetDocument(getter_AddRefs(doc));
+  nsCOMPtr<nsIDOMDocument>domDoc;
+  nsresult rv = mEditor->GetDocument(getter_AddRefs(domDoc));
   TEST_RESULT(rv);
+  TEST_POINTER(domDoc.get());
+  nsCOMPtr<nsIDocument>doc = do_QueryInterface(domDoc);
   TEST_POINTER(doc.get());
-  nsCOMPtr<nsIDOMNodeList>nodeList;
   // XXX This is broken, text nodes are not elements.
   nsAutoString textTag(NS_LITERAL_STRING("#text"));
-  rv = doc->GetElementsByTagName(textTag, getter_AddRefs(nodeList));
-  TEST_RESULT(rv);
+  nsCOMPtr<nsINodeList>nodeList = doc->GetElementsByTagName(textTag);
   TEST_POINTER(nodeList.get());
-  uint32_t count;
-  nodeList->GetLength(&count);
-  NS_ASSERTION(0!=count, "there are no text nodes in the document!");
-  nsCOMPtr<nsIDOMNode> domTextNode;
-  rv = nodeList->Item(count - 1, getter_AddRefs(domTextNode));
-  TEST_RESULT(rv);
-  TEST_POINTER(domTextNode.get());
+  uint32_t count = nodeList->Length();
+  NS_ASSERTION(0 != count, "there are no text nodes in the document!");
+  nsCOMPtr<nsINode>textNode = nodeList->Item(count - 1);
+  TEST_POINTER(textNode.get());
 
   // set the whole text node to bold
   printf("set the whole first text node to bold\n");
   nsCOMPtr<nsISelection>selection;
   rv = mEditor->GetSelection(getter_AddRefs(selection));
   TEST_RESULT(rv);
   TEST_POINTER(selection.get());
-  nsCOMPtr<nsINode> textNode = do_QueryInterface(domTextNode);
   uint32_t length = textNode->Length();
   selection->AsSelection()->Collapse(textNode, 0);
   selection->AsSelection()->Extend(textNode, length);
 
   nsCOMPtr<nsIHTMLEditor> htmlEditor (do_QueryInterface(mTextEditor));
   NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE);
 
   bool any = false;
@@ -220,25 +218,22 @@ nsresult TextEditorTest::TestTextPropert
   rv = htmlEditor->GetInlineProperty(b, empty, empty, &first, &any, &all);
   TEST_RESULT(rv);
   NS_ASSERTION(true==first, "first should be true");
   NS_ASSERTION(true==any, "any should be true");
   NS_ASSERTION(true==all, "all should be true");
   mEditor->DebugDumpContent();
 
   // make all the text underlined, except for the first 2 and last 2 characters
-  rv = doc->GetElementsByTagName(textTag, getter_AddRefs(nodeList));
-  TEST_RESULT(rv);
+  nodeList = doc->GetElementsByTagName(textTag);
   TEST_POINTER(nodeList.get());
-  nodeList->GetLength(&count);
+  count = nodeList->Length();
   NS_ASSERTION(0!=count, "there are no text nodes in the document!");
-  rv = nodeList->Item(count-2, getter_AddRefs(domTextNode));
-  TEST_RESULT(rv);
+  textNode = nodeList->Item(count-2);
   TEST_POINTER(textNode.get());
-  textNode = do_QueryInterface(domTextNode);
   length = textNode->Length();
   NS_ASSERTION(length==915, "wrong text node");
   selection->AsSelection()->Collapse(textNode, 1);
   selection->AsSelection()->Extend(textNode, length-2);
   rv = htmlEditor->SetInlineProperty(u, empty, empty);
   TEST_RESULT(rv);
   rv = htmlEditor->GetInlineProperty(u, empty, empty, &first, &any, &all);
   TEST_RESULT(rv);
--- a/intl/locale/LocaleService.cpp
+++ b/intl/locale/LocaleService.cpp
@@ -437,65 +437,56 @@ LocaleService::LocalesChanged()
  */
 void
 LocaleService::FilterMatches(const nsTArray<nsCString>& aRequested,
                              const nsTArray<nsCString>& aAvailable,
                              LangNegStrategy aStrategy,
                              nsTArray<nsCString>& aRetVal)
 {
   // Local copy of the list of available locales, in Locale form for flexible
-  // matching. We will remove entries from this list as they get appended to
-  // aRetVal, so that no available locale will be found more than once.
+  // matching. We will invalidate entries in this list when they are matched
+  // and the corresponding strings from aAvailable added to aRetVal, so that
+  // no available locale will be found more than once.
   AutoTArray<Locale, 100> availLocales;
   for (auto& avail : aAvailable) {
     availLocales.AppendElement(Locale(avail));
   }
 
-  // Helper to erase an entry from availLocales once we have copied it to
-  // the result list. Returns an iterator pointing to the entry that was
-  // immediately after the one that was erased (or availLocales.end() if
-  // the target was the last in the array).
-  auto eraseFromAvail = [&](nsTArray<Locale>::iterator aIter) {
-    nsTArray<Locale>::size_type index = aIter - availLocales.begin();
-    availLocales.RemoveElementAt(index);
-    return availLocales.begin() + index;
-  };
-
   for (auto& requested : aRequested) {
     if (requested.IsEmpty()) {
       continue;
     }
 
     // 1) Try to find a simple (case-insensitive) string match for the request.
     auto matchesExactly = [&](Locale& aLoc) {
       return requested.Equals(aLoc.AsString(),
                               nsCaseInsensitiveCStringComparator());
     };
     auto match = std::find_if(availLocales.begin(), availLocales.end(),
                               matchesExactly);
     if (match != availLocales.end()) {
-      aRetVal.AppendElement(match->AsString());
-      eraseFromAvail(match);
+      aRetVal.AppendElement(aAvailable[match - availLocales.begin()]);
+      match->Invalidate();
     }
 
     if (!aRetVal.IsEmpty()) {
       HANDLE_STRATEGY;
     }
 
     // 2) Try to match against the available locales treated as ranges.
     auto findRangeMatches = [&](Locale& aReq, bool aAvailRange, bool aReqRange) {
       auto matchesRange = [&](Locale& aLoc) {
         return aLoc.Matches(aReq, aAvailRange, aReqRange);
       };
       bool foundMatch = false;
       auto match = availLocales.begin();
       while ((match = std::find_if(match, availLocales.end(),
                                    matchesRange)) != availLocales.end()) {
-        aRetVal.AppendElement(match->AsString());
-        match = eraseFromAvail(match);
+        aRetVal.AppendElement(aAvailable[match - availLocales.begin()]);
+        match->Invalidate();
         foundMatch = true;
         if (aStrategy != LangNegStrategy::Filtering) {
           return true; // we only want the first match
         }
       }
       return foundMatch;
     };
 
--- a/intl/locale/MozLocale.cpp
+++ b/intl/locale/MozLocale.cpp
@@ -78,24 +78,18 @@ Locale::Locale(const nsACString& aLocale
       nsAutoCString lcSubTag(subTag);
       ToLowerCase(lcSubTag);
       mVariants.InsertElementSorted(lcSubTag);
       position = 4;
     }
   }
 }
 
-bool
-Locale::IsValid()
-{
-  return mIsValid;
-}
-
 const nsCString
-Locale::AsString()
+Locale::AsString() const
 {
   nsCString tag;
 
   if (!mIsValid) {
     tag.AppendLiteral("und");
     return tag;
   }
 
@@ -140,16 +134,20 @@ const nsTArray<nsCString>&
 Locale::GetVariants() const
 {
   return mVariants;
 }
 
 bool
 Locale::Matches(const Locale& aOther, bool aThisRange, bool aOtherRange) const
 {
+  if (!IsValid() || !aOther.IsValid()) {
+    return false;
+  }
+
   if ((!aThisRange || !mLanguage.IsEmpty()) &&
       (!aOtherRange || !aOther.mLanguage.IsEmpty()) &&
       !mLanguage.Equals(aOther.mLanguage)) {
     return false;
   }
 
   if ((!aThisRange || !mScript.IsEmpty()) &&
       (!aOtherRange || !aOther.mScript.IsEmpty()) &&
--- a/intl/locale/MozLocale.h
+++ b/intl/locale/MozLocale.h
@@ -56,30 +56,41 @@ class Locale {
       : Locale(nsDependentCString(aLocale))
       { };
 
     const nsACString& GetLanguage() const;
     const nsACString& GetScript() const;
     const nsACString& GetRegion() const;
     const nsTArray<nsCString>& GetVariants() const;
 
-    bool IsValid();
-    const nsCString AsString();
+    bool IsValid() const {
+      return mIsValid;
+    }
+
+    const nsCString AsString() const;
 
     bool Matches(const Locale& aOther, bool aThisRange, bool aOtherRange) const;
     bool AddLikelySubtags();
     void ClearVariants();
     void ClearRegion();
 
+    // Mark the object as invalid, meaning we shouldn't use it any more.
+    void Invalidate() {
+      mIsValid = false;
+    }
+
     bool operator== (const Locale& aOther) {
-      return mLanguage.Equals(aOther.mLanguage) &&
+      // Note: invalid Locale objects are never treated as equal to anything
+      // (even other invalid ones).
+      return IsValid() &&
+             aOther.IsValid() &&
+             mLanguage.Equals(aOther.mLanguage) &&
              mScript.Equals(aOther.mScript) &&
              mRegion.Equals(aOther.mRegion) &&
              mVariants == aOther.mVariants;
-
     }
 
   private:
     nsAutoCStringN<3> mLanguage;
     nsAutoCStringN<4> mScript;
     nsAutoCStringN<2> mRegion;
     nsTArray<nsCString> mVariants;
     bool mIsValid = true;
--- a/intl/locale/tests/unit/test_localeService_negotiateLanguages.js
+++ b/intl/locale/tests/unit/test_localeService_negotiateLanguages.js
@@ -64,24 +64,24 @@ const data = {
       [["fr"], ["de", "it"], []],
       [["fr"], ["de", "it"], "en-US", ["en-US"]],
       [["fr"], ["de", "en-US"], "en-US", ["en-US"]],
       [["fr", "de-DE"], ["de-DE", "fr-CA"], "en-US", ["fr-CA", "de-DE", "en-US"]],
     ],
     "should handle all matches on the 1st higher than any on the 2nd": [
       [["fr-CA-macos", "de-DE"], ["de-DE", "fr-FR-windows"], ["fr-FR-windows", "de-DE"]],
     ],
-    "should handle cases and underscores": [
+    "should handle cases and underscores, returning the form given in the 'available' list": [
       [["fr_FR"], ["fr-FR"], ["fr-FR"]],
-      [["fr_fr"], ["fr-fr"], ["fr-FR"]],
-      [["fr_Fr"], ["fr-fR"], ["fr-FR"]],
+      [["fr_fr"], ["fr-FR"], ["fr-FR"]],
+      [["fr_Fr"], ["fr-fR"], ["fr-fR"]],
       [["fr_lAtN_fr"], ["fr-Latn-FR"], ["fr-Latn-FR"]],
-      [["fr_FR"], ["fr_FR"], ["fr-FR"]],
-      [["fr-FR"], ["fr_FR"], ["fr-FR"]],
-      [["fr_Cyrl_FR_macos"], ["fr_Cyrl_fr-macos"], ["fr-Cyrl-FR-macos"]],
+      [["fr_FR"], ["fr_FR"], ["fr_FR"]],
+      [["fr-FR"], ["fr_FR"], ["fr_FR"]],
+      [["fr_Cyrl_FR_macos"], ["fr_Cyrl_fr-macos"], ["fr_Cyrl_fr-macos"]],
     ],
     "should handle mozilla specific 3-letter variants": [
       [["ja-JP-mac", "de-DE"], ["ja-JP-mac", "de-DE"], ["ja-JP-mac", "de-DE"]],
     ],
     "should not crash on invalid input": [
       [null, ["fr-FR"], []],
       [[null], [], []],
       [[undefined], [], []],
--- a/layout/base/nsDocumentViewer.cpp
+++ b/layout/base/nsDocumentViewer.cpp
@@ -59,17 +59,16 @@
 #include "nsDocShell.h"
 #include "nsIBaseWindow.h"
 #include "nsILayoutHistoryState.h"
 #include "nsCharsetSource.h"
 #include "mozilla/ReflowInput.h"
 #include "nsIImageLoadingContent.h"
 #include "nsCopySupport.h"
 #ifdef MOZ_XUL
-#include "nsIXULDocument.h"
 #include "nsXULPopupManager.h"
 #endif
 
 #include "nsIClipboardHelper.h"
 
 #include "nsPIDOMWindow.h"
 #include "nsGlobalWindow.h"
 #include "nsDOMNavigationTiming.h"
@@ -276,19 +275,19 @@ private:
                         bool aNeedMakeCX = true,
                         bool aForceSetNewDocument = true);
   /**
    * @param aDoInitialReflow set to true if you want to kick off the initial
    * reflow
    */
   nsresult InitPresentationStuff(bool aDoInitialReflow);
 
-  nsresult GetPopupNode(nsIDOMNode** aNode);
-  nsresult GetPopupLinkNode(nsIDOMNode** aNode);
-  nsresult GetPopupImageNode(nsIImageLoadingContent** aNode);
+  already_AddRefed<nsINode> GetPopupNode();
+  already_AddRefed<nsINode> GetPopupLinkNode();
+  already_AddRefed<nsIImageLoadingContent> GetPopupImageNode();
 
   nsresult GetContentSizeInternal(int32_t* aWidth, int32_t* aHeight,
                                   nscoord aMaxWidth, nscoord aMaxHeight);
 
   void PrepareToStartLoad(void);
 
   nsresult SyncParentSubDocMap();
 
@@ -1843,50 +1842,47 @@ nsDocumentViewer::Stop(void)
     nsCOMPtr<nsIPresShell> shell(mPresShell); // bug 378682
     shell->UnsuppressPainting();
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDocumentViewer::GetDOMDocument(nsIDOMDocument **aResult)
+nsDocumentViewer::GetDOMDocument(nsISupports **aResult)
 {
   NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
   return CallQueryInterface(mDocument, aResult);
 }
 
-NS_IMETHODIMP_(nsIDocument *)
+nsIDocument*
 nsDocumentViewer::GetDocument()
 {
   return mDocument;
 }
 
-NS_IMETHODIMP
-nsDocumentViewer::SetDOMDocument(nsIDOMDocument *aDocument)
+nsresult
+nsDocumentViewer::SetDocument(nsIDocument *aDocument)
 {
   // Assumptions:
   //
   // 1) this document viewer has been initialized with a call to Init().
   // 2) the stylesheets associated with the document have been added
   // to the document.
 
   // XXX Right now, this method assumes that the layout of the current
   // document hasn't started yet.  More cleanup will probably be
   // necessary to make this method work for the case when layout *has*
   // occurred for the current document.
   // That work can happen when and if it is needed.
 
   if (!aDocument)
     return NS_ERROR_NULL_POINTER;
 
-  nsCOMPtr<nsIDocument> newDoc = do_QueryInterface(aDocument);
-  NS_ENSURE_TRUE(newDoc, NS_ERROR_UNEXPECTED);
-
-  return SetDocumentInternal(newDoc, false);
+  return SetDocumentInternal(aDocument, false);
 }
 
 NS_IMETHODIMP
 nsDocumentViewer::SetDocumentInternal(nsIDocument* aDocument,
                                         bool aForceReuseInnerWindow)
 {
   MOZ_ASSERT(aDocument);
 
@@ -2759,18 +2755,17 @@ NS_IMETHODIMP nsDocumentViewer::CopySele
   nsCopySupport::FireClipboardEvent(eCopy, nsIClipboard::kGlobalClipboard,
                                     mPresShell, nullptr);
   return NS_OK;
 }
 
 NS_IMETHODIMP nsDocumentViewer::CopyLinkLocation()
 {
   NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_INITIALIZED);
-  nsCOMPtr<nsIDOMNode> node;
-  GetPopupLinkNode(getter_AddRefs(node));
+  nsCOMPtr<nsINode> node = GetPopupLinkNode();
   // make noise if we're not in a link
   NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
 
   nsCOMPtr<dom::Element> elm(do_QueryInterface(node));
   NS_ENSURE_TRUE(elm, NS_ERROR_FAILURE);
 
   nsAutoString locationText;
   nsContentUtils::GetLinkLocation(elm, locationText);
@@ -2783,18 +2778,17 @@ NS_IMETHODIMP nsDocumentViewer::CopyLink
 
   // copy the href onto the clipboard
   return clipboard->CopyString(locationText);
 }
 
 NS_IMETHODIMP nsDocumentViewer::CopyImage(int32_t aCopyFlags)
 {
   NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_INITIALIZED);
-  nsCOMPtr<nsIImageLoadingContent> node;
-  GetPopupImageNode(getter_AddRefs(node));
+  nsCOMPtr<nsIImageLoadingContent> node = GetPopupImageNode();
   // make noise if we're not in an image
   NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
 
   nsCOMPtr<nsILoadContext> loadContext(mContainer);
   return nsCopySupport::ImageCopy(node, loadContext, aCopyFlags);
 }
 
 
@@ -2844,17 +2838,18 @@ NS_IMETHODIMP nsDocumentViewer::SetComma
   NS_ENSURE_STATE(document);
 
   nsCOMPtr<nsPIDOMWindowOuter> window(document->GetWindow());
   NS_ENSURE_TRUE(window, NS_ERROR_NOT_AVAILABLE);
 
   nsCOMPtr<nsPIWindowRoot> root = window->GetTopWindowRoot();
   NS_ENSURE_STATE(root);
 
-  root->SetPopupNode(aNode);
+  nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
+  root->SetPopupNode(node);
   return NS_OK;
 }
 
 NS_IMETHODIMP nsDocumentViewer::ScrollToNode(nsIDOMNode* aNode)
 {
   NS_ENSURE_ARG(aNode);
   NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
   nsCOMPtr<nsIPresShell> presShell;
@@ -3610,110 +3605,85 @@ nsresult nsDocViewerSelectionListener::I
  * GetPopupNode, GetPopupLinkNode and GetPopupImageNode are helpers
  * for the cmd_copyLink / cmd_copyImageLocation / cmd_copyImageContents family
  * of commands. The focus controller stores the popup node, these retrieve
  * them and munge appropriately. Note that we have to store the popup node
  * rather than retrieving it from EventStateManager::GetFocusedContent because
  * not all content (images included) can receive focus.
  */
 
-nsresult
-nsDocumentViewer::GetPopupNode(nsIDOMNode** aNode)
+already_AddRefed<nsINode>
+nsDocumentViewer::GetPopupNode()
 {
-  NS_ENSURE_ARG_POINTER(aNode);
-
-  *aNode = nullptr;
-
   // get the document
   nsIDocument* document = GetDocument();
-  NS_ENSURE_TRUE(document, NS_ERROR_FAILURE);
+  NS_ENSURE_TRUE(document, nullptr);
 
   // get the private dom window
   nsCOMPtr<nsPIDOMWindowOuter> window(document->GetWindow());
-  NS_ENSURE_TRUE(window, NS_ERROR_NOT_AVAILABLE);
+  NS_ENSURE_TRUE(window, nullptr);
   if (window) {
     nsCOMPtr<nsPIWindowRoot> root = window->GetTopWindowRoot();
-    NS_ENSURE_TRUE(root, NS_ERROR_FAILURE);
+    NS_ENSURE_TRUE(root, nullptr);
 
     // get the popup node
-    nsCOMPtr<nsIDOMNode> node = root->GetPopupNode();
+    nsCOMPtr<nsINode> node = root->GetPopupNode();
 #ifdef MOZ_XUL
     if (!node) {
       nsPIDOMWindowOuter* rootWindow = root->GetWindow();
       if (rootWindow) {
         nsCOMPtr<nsIDocument> rootDoc = rootWindow->GetExtantDoc();
         if (rootDoc) {
           nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
           if (pm) {
             node = pm->GetLastTriggerPopupNode(rootDoc);
           }
         }
       }
     }
 #endif
-    node.swap(*aNode);
+    return node.forget();
   }
 
-  return NS_OK;
+  return nullptr;
 }
 
 // GetPopupLinkNode: return popup link node or fail
-nsresult
-nsDocumentViewer::GetPopupLinkNode(nsIDOMNode** aNode)
+already_AddRefed<nsINode>
+nsDocumentViewer::GetPopupLinkNode()
 {
-  NS_ENSURE_ARG_POINTER(aNode);
-
-  // you get null unless i say so
-  *aNode = nullptr;
-
   // find popup node
-  nsCOMPtr<nsIDOMNode> domNode;
-  nsresult rv = GetPopupNode(getter_AddRefs(domNode));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr<nsINode> node = do_QueryInterface(domNode);
+  nsCOMPtr<nsINode> node = GetPopupNode();
 
   // find out if we have a link in our ancestry
   while (node) {
     nsCOMPtr<nsIContent> content(do_QueryInterface(node));
     if (content) {
       nsCOMPtr<nsIURI> hrefURI = content->GetHrefURI();
       if (hrefURI) {
-        *aNode = node->AsDOMNode();
-        NS_IF_ADDREF(*aNode); // addref
-        return NS_OK;
+        return node.forget();
       }
     }
 
     // get our parent and keep trying...
     node = node->GetParentNode();
   }
 
   // if we have no node, fail
-  return NS_ERROR_FAILURE;
+  return nullptr;
 }
 
 // GetPopupLinkNode: return popup image node or fail
-nsresult
-nsDocumentViewer::GetPopupImageNode(nsIImageLoadingContent** aNode)
+already_AddRefed<nsIImageLoadingContent>
+nsDocumentViewer::GetPopupImageNode()
 {
-  NS_ENSURE_ARG_POINTER(aNode);
-
-  // you get null unless i say so
-  *aNode = nullptr;
-
   // find popup node
-  nsCOMPtr<nsIDOMNode> node;
-  nsresult rv = GetPopupNode(getter_AddRefs(node));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (node)
-    CallQueryInterface(node, aNode);
-
-  return NS_OK;
+  nsCOMPtr<nsINode> node = GetPopupNode();
+  nsCOMPtr<nsIImageLoadingContent> img = do_QueryInterface(node);
+  return img.forget();
 }
 
 /*
  * XXX dr
  * ------
  * These two functions -- GetInLink and GetInImage -- are kind of annoying
  * in that they only get called from the controller (in
  * nsDOMWindowController::IsCommandEnabled). The actual construction of the
@@ -3729,19 +3699,17 @@ NS_IMETHODIMP nsDocumentViewer::GetInLin
 #endif
 
   NS_ENSURE_ARG_POINTER(aInLink);
 
   // we're not in a link unless i say so
   *aInLink = false;
 
   // get the popup link
-  nsCOMPtr<nsIDOMNode> node;
-  nsresult rv = GetPopupLinkNode(getter_AddRefs(node));
-  if (NS_FAILED(rv)) return rv;
+  nsCOMPtr<nsINode> node = GetPopupLinkNode();
   NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
 
   // if we made it here, we're in a link
   *aInLink = true;
   return NS_OK;
 }
 
 NS_IMETHODIMP nsDocumentViewer::GetInImage(bool* aInImage)
@@ -3751,19 +3719,17 @@ NS_IMETHODIMP nsDocumentViewer::GetInIma
 #endif
 
   NS_ENSURE_ARG_POINTER(aInImage);
 
   // we're not in an image unless i say so
   *aInImage = false;
 
   // get the popup image
-  nsCOMPtr<nsIImageLoadingContent> node;
-  nsresult rv = GetPopupImageNode(getter_AddRefs(node));
-  if (NS_FAILED(rv)) return rv;
+  nsCOMPtr<nsIImageLoadingContent> node = GetPopupImageNode();
   if (!node) {
     return NS_ERROR_FAILURE;
   }
 
   // Make sure there is a URI assigned. This allows <input type="image"> to
   // be an image but rejects other <input> types. This matches what
   // nsContextMenu.js does.
   nsCOMPtr<nsIURI> uri;
@@ -3868,18 +3834,17 @@ nsDocViewerFocusListener::Init(nsDocumen
 
 #ifdef NS_PRINTING
 
 NS_IMETHODIMP
 nsDocumentViewer::Print(nsIPrintSettings*       aPrintSettings,
                           nsIWebProgressListener* aWebProgressListener)
 {
   // Printing XUL documents is not supported.
-  nsCOMPtr<nsIXULDocument> xulDoc(do_QueryInterface(mDocument));
-  if (xulDoc) {
+  if (mDocument && mDocument->IsXULDocument()) {
     return NS_ERROR_FAILURE;
   }
 
   if (!mContainer) {
     PR_PL(("Container was destroyed yet we are still trying to use it!"));
     return NS_ERROR_FAILURE;
   }
 
@@ -3984,18 +3949,17 @@ nsDocumentViewer::PrintPreview(nsIPrintS
   nsresult rv = NS_OK;
 
   if (GetIsPrinting()) {
     nsPrintJob::CloseProgressDialog(aWebProgressListener);
     return NS_ERROR_FAILURE;
   }
 
   // Printing XUL documents is not supported.
-  nsCOMPtr<nsIXULDocument> xulDoc(do_QueryInterface(mDocument));
-  if (xulDoc) {
+  if (mDocument && mDocument->IsXULDocument()) {
     nsPrintJob::CloseProgressDialog(aWebProgressListener);
     return NS_ERROR_FAILURE;
   }
 
   nsCOMPtr<nsIDocShell> docShell(mContainer);
   if (!docShell || !mDeviceContext) {
     PR_PL(("Can't Print Preview without device context and docshell"));
     return NS_ERROR_FAILURE;
--- a/layout/build/nsLayoutModule.cpp
+++ b/layout/build/nsLayoutModule.cpp
@@ -139,17 +139,17 @@ class nsIDocumentLoaderFactory;
 
 #ifdef MOZ_XUL
 #include "inDOMView.h"
 #endif /* MOZ_XUL */
 
 #include "inDeepTreeWalker.h"
 
 #ifdef MOZ_XUL
-#include "nsIXULDocument.h"
+#include "XULDocument.h"
 #include "nsIXULSortService.h"
 #endif
 
 static void Shutdown();
 
 #include "nsGeolocation.h"
 #include "nsDeviceSensors.h"
 #include "mozilla/dom/nsContentSecurityManager.h"
@@ -426,17 +426,17 @@ MAKE_CTOR(CreateTextEncoder,            
 MAKE_CTOR(CreateHTMLCopyTextEncoder,      nsIDocumentEncoder,          NS_NewHTMLCopyTextEncoder)
 MAKE_CTOR(CreateXMLContentSerializer,     nsIContentSerializer,        NS_NewXMLContentSerializer)
 MAKE_CTOR(CreateHTMLContentSerializer,    nsIContentSerializer,        NS_NewHTMLContentSerializer)
 MAKE_CTOR(CreateXHTMLContentSerializer,   nsIContentSerializer,        NS_NewXHTMLContentSerializer)
 MAKE_CTOR(CreatePlainTextSerializer,      nsIContentSerializer,        NS_NewPlainTextSerializer)
 MAKE_CTOR(CreateContentPolicy,            nsIContentPolicy,            NS_NewContentPolicy)
 #ifdef MOZ_XUL
 MAKE_CTOR(CreateXULSortService,           nsIXULSortService,           NS_NewXULSortService)
-MAKE_CTOR(CreateXULDocument,              nsIXULDocument,              NS_NewXULDocument)
+MAKE_CTOR(CreateXULDocument,              nsIDocument,                 NS_NewXULDocument)
 // NS_NewXULControllers
 #endif
 MAKE_CTOR(CreateContentDLF,               nsIDocumentLoaderFactory,    NS_NewContentDocumentLoaderFactory)
 MAKE_CTOR(CreateEventListenerService,     nsIEventListenerService,     NS_NewEventListenerService)
 MAKE_CTOR(CreateGlobalMessageManager,     nsIMessageBroadcaster,       NS_NewGlobalMessageManager)
 MAKE_CTOR(CreateParentMessageManager,     nsIMessageBroadcaster,       NS_NewParentProcessMessageManager)
 MAKE_CTOR(CreateChildMessageManager,      nsISyncMessageSender,        NS_NewChildProcessMessageManager)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsDataDocumentContentPolicy)
@@ -955,17 +955,16 @@ static const mozilla::Module::ContractID
   { NS_PARSERUTILS_CONTRACTID, &kNS_PARSERUTILS_CID },
   { NS_SCRIPTABLEUNESCAPEHTML_CONTRACTID, &kNS_SCRIPTABLEUNESCAPEHTML_CID },
   { NS_CONTENTPOLICY_CONTRACTID, &kNS_CONTENTPOLICY_CID },
   { NS_DATADOCUMENTCONTENTPOLICY_CONTRACTID, &kNS_DATADOCUMENTCONTENTPOLICY_CID },
   { NS_NODATAPROTOCOLCONTENTPOLICY_CONTRACTID, &kNS_NODATAPROTOCOLCONTENTPOLICY_CID },
   { "@mozilla.org/xul/xul-controllers;1", &kNS_XULCONTROLLERS_CID },
 #ifdef MOZ_XUL
   { "@mozilla.org/xul/xul-sort-service;1", &kNS_XULSORTSERVICE_CID },
-  { "@mozilla.org/xul/xul-document;1", &kNS_XULDOCUMENT_CID },
 #endif
   { CONTENT_DLF_CONTRACTID, &kNS_CONTENT_DOCUMENT_LOADER_FACTORY_CID },
   { NS_JSPROTOCOLHANDLER_CONTRACTID, &kNS_JSPROTOCOLHANDLER_CID },
   { NS_WINDOWCONTROLLER_CONTRACTID, &kNS_WINDOWCONTROLLER_CID },
   { PLUGIN_DLF_CONTRACTID, &kNS_PLUGINDOCLOADERFACTORY_CID },
   { NS_STYLESHEETSERVICE_CONTRACTID, &kNS_STYLESHEETSERVICE_CID },
   { TRANSFORMIIX_XSLT_PROCESSOR_CONTRACTID, &kTRANSFORMIIX_XSLT_PROCESSOR_CID },
   { NS_XPATH_EVALUATOR_CONTRACTID, &kTRANSFORMIIX_XPATH_EVALUATOR_CID },
--- a/layout/printing/nsPrintJob.cpp
+++ b/layout/printing/nsPrintJob.cpp
@@ -295,18 +295,17 @@ GetDocumentTitleAndURL(nsIDocument* aDoc
                        nsAString& aTitle,
                        nsAString& aURLStr)
 {
   NS_ASSERTION(aDoc, "Pointer is null!");
 
   aTitle.Truncate();
   aURLStr.Truncate();
 
-  nsCOMPtr<nsIDOMDocument> doc = do_QueryInterface(aDoc);
-  doc->GetTitle(aTitle);
+  aDoc->GetTitle(aTitle);
 
   nsIURI* url = aDoc->GetDocumentURI();
   if (!url) return;
 
   nsCOMPtr<nsIURIFixup> urifixup(do_GetService(NS_URIFIXUP_CONTRACTID));
   if (!urifixup) return;
 
   nsCOMPtr<nsIURI> exposableURI;
@@ -452,19 +451,17 @@ MapContentToWebShells(const UniquePtr<ns
 
   // Recursively walk the content from the root item
   // XXX Would be faster to enumerate the subdocuments, although right now
   //     nsIDocument doesn't expose quite what would be needed.
   nsCOMPtr<nsIContentViewer> viewer;
   aPO->mDocShell->GetContentViewer(getter_AddRefs(viewer));
   if (!viewer) return;
 
-  nsCOMPtr<nsIDOMDocument> domDoc;
-  viewer->GetDOMDocument(getter_AddRefs(domDoc));
-  nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
+  nsCOMPtr<nsIDocument> doc = viewer->GetDocument();
   if (!doc) return;
 
   Element* rootElement = doc->GetRootElement();
   if (rootElement) {
     MapContentForPO(aPO, rootElement);
   } else {
     NS_WARNING("Null root content on (sub)document.");
   }
--- a/layout/printing/nsPrintObject.cpp
+++ b/layout/printing/nsPrintObject.cpp
@@ -80,20 +80,19 @@ nsPrintObject::Init(nsIDocShell* aDocShe
     if (window) {
       mContent = window->GetFrameElementInternal();
     }
     mDocument = doc;
     return NS_OK;
   }
 
   mDocument = doc->CreateStaticClone(mDocShell);
-  nsCOMPtr<nsIDOMDocument> clonedDOMDoc = do_QueryInterface(mDocument);
-  NS_ENSURE_STATE(clonedDOMDoc);
+  NS_ENSURE_STATE(mDocument);
 
-  viewer->SetDOMDocument(clonedDOMDoc);
+  viewer->SetDocument(mDocument);
   return NS_OK;
 }
 
 //------------------------------------------------------------------
 // Resets PO by destroying the presentation
 void
 nsPrintObject::DestroyPresentation()
 {
--- a/layout/style/Loader.cpp
+++ b/layout/style/Loader.cpp
@@ -20,17 +20,16 @@
 #include "nsIRunnable.h"
 #include "nsIUnicharStreamLoader.h"
 #include "nsSyncLoadService.h"
 #include "nsCOMPtr.h"
 #include "nsString.h"
 #include "nsIContent.h"
 #include "nsIDocument.h"
 #include "nsIDOMNode.h"
-#include "nsIDOMDocument.h"
 #include "nsIURI.h"
 #include "nsNetUtil.h"
 #include "nsIProtocolHandler.h"
 #include "nsContentUtils.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsContentPolicyUtils.h"
 #include "nsIHttpChannel.h"
 #include "nsIHttpChannelInternal.h"
@@ -394,20 +393,17 @@ Loader::Loader(nsIDocument* aDocument)
   , mSyncCallback(false)
 #endif
 {
   MOZ_ASSERT(mDocument, "We should get a valid document from the caller!");
 
   // We can just use the preferred set, since there are no sheets in the
   // document yet (if there are, how did they get there? _we_ load the sheets!)
   // and hence the selected set makes no sense at this time.
-  nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(mDocument);
-  if (domDoc) {
-    domDoc->GetPreferredStyleSheetSet(mPreferredSheet);
-  }
+  mDocument->GetPreferredStyleSheetSet(mPreferredSheet);
 }
 
 Loader::~Loader()
 {
   NS_ASSERTION(!mSheets || mSheets->mLoadingDatas.Count() == 0,
                "How did we get destroyed when there are loading data?");
   NS_ASSERTION(!mSheets || mSheets->mPendingDatas.Count() == 0,
                "How did we get destroyed when there are pending data?");
@@ -427,22 +423,21 @@ Loader::DropDocumentReference(void)
     StartAlternateLoads();
   }
 }
 
 nsresult
 Loader::SetPreferredSheet(const nsAString& aTitle)
 {
 #ifdef DEBUG
-  nsCOMPtr<nsIDOMDocument> doc = do_QueryInterface(mDocument);
-  if (doc) {
+  if (mDocument) {
     nsAutoString currentPreferred;
-    doc->GetLastStyleSheetSet(currentPreferred);
+    mDocument->GetLastStyleSheetSet(currentPreferred);
     if (DOMStringIsNull(currentPreferred)) {
-      doc->GetPreferredStyleSheetSet(currentPreferred);
+      mDocument->GetPreferredStyleSheetSet(currentPreferred);
     }
     NS_ASSERTION(currentPreferred.Equals(aTitle),
                  "Unexpected argument to SetPreferredSheet");
   }
 #endif
 
   mPreferredSheet = aTitle;
 
--- a/layout/tools/layout-debug/src/nsLayoutDebuggingTools.cpp
+++ b/layout/tools/layout-debug/src/nsLayoutDebuggingTools.cpp
@@ -11,17 +11,16 @@
 #include "nsIContentViewer.h"
 
 #include "nsIServiceManager.h"
 #include "nsAtom.h"
 #include "nsQuickSort.h"
 
 #include "nsIContent.h"
 #include "nsIDocument.h"
-#include "nsIDOMDocument.h"
 
 #include "nsIPresShell.h"
 #include "nsViewManager.h"
 #include "nsIFrame.h"
 
 #include "nsILayoutDebugger.h"
 #include "nsLayoutCID.h"
 static NS_DEFINE_CID(kLayoutDebuggerCID, NS_LAYOUT_DEBUGGER_CID);
@@ -64,21 +63,17 @@ view_manager(nsIDocShell *aDocShell)
 
 #ifdef DEBUG
 static already_AddRefed<nsIDocument>
 document(nsIDocShell *aDocShell)
 {
     nsCOMPtr<nsIContentViewer> cv(doc_viewer(aDocShell));
     if (!cv)
         return nullptr;
-    nsCOMPtr<nsIDOMDocument> domDoc;
-    cv->GetDOMDocument(getter_AddRefs(domDoc));
-    if (!domDoc)
-        return nullptr;
-    nsCOMPtr<nsIDocument> result = do_QueryInterface(domDoc);
+    nsCOMPtr<nsIDocument> result = cv->GetDocument();
     return result.forget();
 }
 #endif
 
 nsLayoutDebuggingTools::nsLayoutDebuggingTools()
   : mPaintFlashing(false),
     mPaintDumping(false),
     mInvalidateDumping(false),
--- a/layout/xul/nsXULPopupManager.cpp
+++ b/layout/xul/nsXULPopupManager.cpp
@@ -10,18 +10,16 @@
 #include "nsMenuPopupFrame.h"
 #include "nsMenuBarFrame.h"
 #include "nsMenuBarListener.h"
 #include "nsContentUtils.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMEvent.h"
 #include "nsXULElement.h"
 #include "nsIDOMXULMenuListElement.h"
-#include "nsIXULDocument.h"
-#include "nsIDOMXULDocument.h"
 #include "nsIDOMXULCommandDispatcher.h"
 #include "nsCSSFrameConstructor.h"
 #include "nsGlobalWindow.h"
 #include "nsLayoutUtils.h"
 #include "nsViewManager.h"
 #include "nsIComponentManager.h"
 #include "nsITimer.h"
 #include "nsFocusManager.h"
@@ -31,18 +29,20 @@
 #include "nsIBaseWindow.h"
 #include "nsIDOMKeyEvent.h"
 #include "nsIDOMMouseEvent.h"
 #include "nsCaret.h"
 #include "nsIDocument.h"
 #include "nsPIWindowRoot.h"
 #include "nsFrameManager.h"
 #include "nsIObserverService.h"
+#include "XULDocument.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/Event.h" // for nsIDOMEvent::InternalDOMEvent()
+#include "mozilla/dom/UIEvent.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventStateManager.h"
 #include "mozilla/LookAndFeel.h"
 #include "mozilla/MouseEvents.h"
 #include "mozilla/Services.h"
 #include "mozilla/widget/nsAutoRollup.h"
 
 using namespace mozilla;
@@ -594,22 +594,26 @@ nsXULPopupManager::GetTopVisibleMenu()
       return item;
     }
     item = item->GetParent();
   }
 
   return nullptr;
 }
 
-void
-nsXULPopupManager::GetMouseLocation(nsIDOMNode** aNode, int32_t* aOffset)
+nsINode*
+nsXULPopupManager::GetMouseLocationParent()
 {
-  *aNode = mRangeParent;
-  NS_IF_ADDREF(*aNode);
-  *aOffset = mRangeOffset;
+  return mRangeParent;
+}
+
+int32_t
+nsXULPopupManager::MouseLocationOffset()
+{
+  return mRangeOffset;
 }
 
 void
 nsXULPopupManager::InitTriggerEvent(nsIDOMEvent* aEvent, nsIContent* aPopup,
                                     nsIContent** aTriggerContent)
 {
   mCachedMousePoint = LayoutDeviceIntPoint(0, 0);
 
@@ -620,20 +624,21 @@ nsXULPopupManager::InitTriggerEvent(nsID
       nsCOMPtr<nsIContent> target = do_QueryInterface(
         aEvent->InternalDOMEvent()->GetTarget());
       target.forget(aTriggerContent);
     }
   }
 
   mCachedModifiers = 0;
 
-  nsCOMPtr<nsIDOMUIEvent> uiEvent = do_QueryInterface(aEvent);
-  if (uiEvent) {
-    uiEvent->GetRangeParent(getter_AddRefs(mRangeParent));
-    uiEvent->GetRangeOffset(&mRangeOffset);
+  nsCOMPtr<nsIDOMUIEvent> domUiEvent = do_QueryInterface(aEvent);
+  if (domUiEvent) {
+    auto uiEvent = static_cast<UIEvent*>(domUiEvent.get());
+    mRangeParent = uiEvent->GetRangeParent();
+    mRangeOffset = uiEvent->RangeOffset();
 
     // get the event coordinates relative to the root frame of the document
     // containing the popup.
     NS_ASSERTION(aPopup, "Expected a popup node");
     WidgetEvent* event = aEvent->WidgetEventPtr();
     if (event) {
       WidgetInputEvent* inputEvent = event->AsInputEvent();
       if (inputEvent) {
@@ -1701,38 +1706,38 @@ nsXULPopupManager::GetVisiblePopups(nsTA
     if (item->Frame()->IsVisible() && !item->Frame()->IsMouseTransparent()) {
       aPopups.AppendElement(item->Frame());
     }
 
     item = item->GetParent();
   }
 }
 
-already_AddRefed<nsIDOMNode>
+already_AddRefed<nsINode>
 nsXULPopupManager::GetLastTriggerNode(nsIDocument* aDocument, bool aIsTooltip)
 {
   if (!aDocument)
     return nullptr;
 
-  nsCOMPtr<nsIDOMNode> node;
+  nsCOMPtr<nsINode> node;
 
   // if mOpeningPopup is set, it means that a popupshowing event is being
   // fired. In this case, just use the cached node, as the popup is not yet in
   // the list of open popups.
   if (mOpeningPopup && mOpeningPopup->GetUncomposedDoc() == aDocument &&
       aIsTooltip == mOpeningPopup->IsXULElement(nsGkAtoms::tooltip)) {
-    node = do_QueryInterface(nsMenuPopupFrame::GetTriggerContent(GetPopupFrameForContent(mOpeningPopup, false)));
+    node = nsMenuPopupFrame::GetTriggerContent(GetPopupFrameForContent(mOpeningPopup, false));
   }
   else {
     nsMenuChainItem* item = mPopups;
     while (item) {
       // look for a popup of the same type and document.
       if ((item->PopupType() == ePopupTypeTooltip) == aIsTooltip &&
           item->Content()->GetUncomposedDoc() == aDocument) {
-        node = do_QueryInterface(nsMenuPopupFrame::GetTriggerContent(item->Frame()));
+        node = nsMenuPopupFrame::GetTriggerContent(item->Frame());
         if (node)
           break;
       }
       item = item->GetParent();
     }
   }
 
   return node.forget();
@@ -1967,20 +1972,20 @@ nsXULPopupManager::UpdateMenuItems(nsICo
   // command attribute. If so, then several attributes must potentially be updated.
 
   nsCOMPtr<nsIDocument> document = aPopup->GetUncomposedDoc();
   if (!document) {
     return;
   }
 
   // When a menu is opened, make sure that command updating is unlocked first.
-  nsCOMPtr<nsIDOMXULDocument> xulDoc = do_QueryInterface(document);
+  XULDocument* xulDoc = document->AsXULDocument();
   if (xulDoc) {
-    nsCOMPtr<nsIDOMXULCommandDispatcher> xulCommandDispatcher;
-    xulDoc->GetCommandDispatcher(getter_AddRefs(xulCommandDispatcher));
+    nsCOMPtr<nsIDOMXULCommandDispatcher> xulCommandDispatcher =
+      xulDoc->GetCommandDispatcher();
     if (xulCommandDispatcher) {
       xulCommandDispatcher->Unlock();
     }
   }
 
   for (nsCOMPtr<nsIContent> grandChild = aPopup->GetFirstChild();
        grandChild;
        grandChild = grandChild->GetNextSibling()) {
--- a/layout/xul/nsXULPopupManager.h
+++ b/layout/xul/nsXULPopupManager.h
@@ -417,19 +417,20 @@ public:
   // when the active menu bar should be defocused. In the latter case, if
   // aMenuBar isn't currently active, yet another menu bar is, that menu bar
   // will remain active.
   void SetActiveMenuBar(nsMenuBarFrame* aMenuBar, bool aActivate);
 
   // retrieve the node and offset of the last mouse event used to open a
   // context menu. This information is determined from the rangeParent and
   // the rangeOffset of the event supplied to ShowPopup or ShowPopupAtScreen.
-  // This is used by the implementation of nsIDOMXULDocument::GetPopupRangeParent
-  // and nsIDOMXULDocument::GetPopupRangeOffset.
-  void GetMouseLocation(nsIDOMNode** aNode, int32_t* aOffset);
+  // This is used by the implementation of XULDocument::GetPopupRangeParent
+  // and XULDocument::GetPopupRangeOffset.
+  nsINode* GetMouseLocationParent();
+  int32_t MouseLocationOffset();
 
   /**
    * Open a <menu> given its content node. If aSelectFirstItem is
    * set to true, the first item on the menu will automatically be
    * selected. If aAsynchronous is true, the event will be dispatched
    * asynchronously. This should be true when called from frame code.
    */
   void ShowMenu(nsIContent *aMenu, bool aSelectFirstItem, bool aAsynchronous);
@@ -591,22 +592,22 @@ public:
    */
   void GetVisiblePopups(nsTArray<nsIFrame *>& aPopups);
 
   /**
    * Get the node that last triggered a popup or tooltip in the document
    * aDocument. aDocument must be non-null and be a document contained within
    * the same window hierarchy as the popup to retrieve.
    */
-  already_AddRefed<nsIDOMNode> GetLastTriggerPopupNode(nsIDocument* aDocument)
+  already_AddRefed<nsINode> GetLastTriggerPopupNode(nsIDocument* aDocument)
   {
     return GetLastTriggerNode(aDocument, false);
   }
 
-  already_AddRefed<nsIDOMNode> GetLastTriggerTooltipNode(nsIDocument* aDocument)
+  already_AddRefed<nsINode> GetLastTriggerTooltipNode(nsIDocument* aDocument)
   {
     return GetLastTriggerNode(aDocument, true);
   }
 
   /**
    * Return false if a popup may not be opened. This will return false if the
    * popup is already open, if the popup is in a content shell that is not
    * focused, or if it is a submenu of another menu that isn't open.
@@ -793,17 +794,17 @@ private:
    * handled and other default handling should not occur.
    */
   bool HandleKeyboardNavigationInPopup(nsMenuChainItem* aItem,
                                          nsMenuPopupFrame* aFrame,
                                          nsNavigationDirection aDir);
 
 protected:
 
-  already_AddRefed<nsIDOMNode> GetLastTriggerNode(nsIDocument* aDocument, bool aIsTooltip);
+  already_AddRefed<nsINode> GetLastTriggerNode(nsIDocument* aDocument, bool aIsTooltip);
 
   /**
    * Set mouse capturing for the current popup. This traps mouse clicks that
    * occur outside the popup so that it can be closed up. aOldPopup should be
    * set to the popup that was previously the current popup.
    */
   void SetCaptureState(nsIContent *aOldPopup);
 
@@ -827,17 +828,17 @@ protected:
 
   // the document the key event listener is attached to
   nsCOMPtr<mozilla::dom::EventTarget> mKeyListener;
 
   // widget that is currently listening to rollup events
   nsCOMPtr<nsIWidget> mWidget;
 
   // range parent and offset set in SetTriggerEvent
-  nsCOMPtr<nsIDOMNode> mRangeParent;
+  nsCOMPtr<nsINode> mRangeParent;
   int32_t mRangeOffset;
   // Device pixels relative to the showing popup's presshell's
   // root prescontext's root frame.
   mozilla::LayoutDeviceIntPoint mCachedMousePoint;
 
   // cached modifiers
   mozilla::Modifiers mCachedModifiers;
 
--- a/layout/xul/nsXULTooltipListener.cpp
+++ b/layout/xul/nsXULTooltipListener.cpp
@@ -2,17 +2,16 @@
 /* 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 "nsXULTooltipListener.h"
 
 #include "nsIDOMMouseEvent.h"
-#include "nsIDOMXULDocument.h"
 #include "nsXULElement.h"
 #include "nsIDocument.h"
 #include "nsGkAtoms.h"
 #include "nsMenuPopupFrame.h"
 #include "nsIServiceManager.h"
 #include "nsIDragService.h"
 #include "nsIDragSession.h"
 #ifdef MOZ_XUL
@@ -98,22 +97,22 @@ nsXULTooltipListener::MouseOut(nsIDOMEve
     return;
 #endif
 
 #ifdef MOZ_XUL
   // check to see if the mouse left the targetNode, and if so,
   // hide the tooltip
   if (currentTooltip) {
     // which node did the mouse leave?
-    nsCOMPtr<nsIDOMNode> targetNode = do_QueryInterface(
+    nsCOMPtr<nsINode> targetNode = do_QueryInterface(
       aEvent->InternalDOMEvent()->GetTarget());
 
     nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
     if (pm) {
-      nsCOMPtr<nsIDOMNode> tooltipNode =
+      nsCOMPtr<nsINode> tooltipNode =
         pm->GetLastTriggerTooltipNode(currentTooltip->GetUncomposedDoc());
       if (tooltipNode == targetNode) {
         // if the target node is the current tooltip target node, the mouse
         // left the node the tooltip appeared on, so close the tooltip.
         HideTooltip();
         // reset special tree tracking
         if (mIsSourceTree) {
           mLastTreeRow = -1;
@@ -399,19 +398,18 @@ nsXULTooltipListener::ShowTooltip()
 
   // get the tooltip content designated for the target node
   nsCOMPtr<nsIContent> tooltipNode;
   GetTooltipFor(sourceNode, getter_AddRefs(tooltipNode));
   if (!tooltipNode || sourceNode == tooltipNode)
     return NS_ERROR_FAILURE; // the target node doesn't need a tooltip
 
   // set the node in the document that triggered the tooltip and show it
-  nsCOMPtr<nsIDOMXULDocument> xulDoc =
-    do_QueryInterface(tooltipNode->GetComposedDoc());
-  if (xulDoc) {
+  if (tooltipNode->GetComposedDoc() &&
+      tooltipNode->GetComposedDoc()->IsXULDocument()) {
     // Make sure the target node is still attached to some document.
     // It might have been deleted.
     if (sourceNode->IsInComposedDoc()) {
 #ifdef MOZ_XUL
       if (!mIsSourceTree) {
         mLastTreeRow = -1;
         mLastTreeCol = nullptr;
       }
--- a/layout/xul/tree/nsTreeBodyFrame.cpp
+++ b/layout/xul/tree/nsTreeBodyFrame.cpp
@@ -33,17 +33,16 @@
 #include "gfxContext.h"
 #include "nsIContent.h"
 #include "nsStyleContext.h"
 #include "nsIBoxObject.h"
 #include "nsIDOMCustomEvent.h"
 #include "nsIDOMMouseEvent.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMNodeList.h"
-#include "nsIDOMDocument.h"
 #include "nsIDOMXULElement.h"
 #include "nsIDocument.h"
 #include "mozilla/css/StyleRule.h"
 #include "nsCSSRendering.h"
 #include "nsString.h"
 #include "nsContainerFrame.h"
 #include "nsView.h"
 #include "nsViewManager.h"
@@ -59,28 +58,30 @@
 #include "imgIRequest.h"
 #include "imgIContainer.h"
 #include "imgILoader.h"
 #include "mozilla/dom/NodeInfo.h"
 #include "nsContentUtils.h"
 #include "nsLayoutUtils.h"
 #include "nsIScrollableFrame.h"
 #include "nsDisplayList.h"
+#include "mozilla/dom/Event.h"
 #include "mozilla/dom/TreeBoxObject.h"
 #include "nsIScriptableRegion.h"
 #include <algorithm>
 #include "ScrollbarActivity.h"
 
 #ifdef ACCESSIBILITY
 #include "nsAccessibilityService.h"
 #include "nsIWritablePropertyBag2.h"
 #endif
 #include "nsBidiUtils.h"
 
 using namespace mozilla;
+using namespace mozilla::dom;
 using namespace mozilla::gfx;
 using namespace mozilla::image;
 using namespace mozilla::layout;
 
 // Function that cancels all the image requests in our cache.
 void
 nsTreeBodyFrame::CancelImageRequests()
 {
@@ -4657,23 +4658,22 @@ nsTreeBodyFrame::RemoveTreeImageListener
 #ifdef ACCESSIBILITY
 void
 nsTreeBodyFrame::FireRowCountChangedEvent(int32_t aIndex, int32_t aCount)
 {
   nsCOMPtr<nsIContent> content(GetBaseElement());
   if (!content)
     return;
 
-  nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(content->OwnerDoc());
-  if (!domDoc)
-    return;
-
-  nsCOMPtr<nsIDOMEvent> event;
-  domDoc->CreateEvent(NS_LITERAL_STRING("customevent"),
-                      getter_AddRefs(event));
+  nsCOMPtr<nsIDocument> doc = content->OwnerDoc();
+  MOZ_ASSERT(doc);
+
+  IgnoredErrorResult ignored;
+  RefPtr<Event> event = doc->CreateEvent(NS_LITERAL_STRING("customevent"),
+                                         CallerType::System, ignored);
 
   nsCOMPtr<nsIDOMCustomEvent> treeEvent(do_QueryInterface(event));
   if (!treeEvent)
     return;
 
   nsCOMPtr<nsIWritablePropertyBag2> propBag(
     do_CreateInstance("@mozilla.org/hash-property-bag;1"));
   if (!propBag)
@@ -4702,23 +4702,21 @@ void
 nsTreeBodyFrame::FireInvalidateEvent(int32_t aStartRowIdx, int32_t aEndRowIdx,
                                      nsITreeColumn *aStartCol,
                                      nsITreeColumn *aEndCol)
 {
   nsCOMPtr<nsIContent> content(GetBaseElement());
   if (!content)
     return;
 
-  nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(content->OwnerDoc());
-  if (!domDoc)
-    return;
-
-  nsCOMPtr<nsIDOMEvent> event;
-  domDoc->CreateEvent(NS_LITERAL_STRING("customevent"),
-                      getter_AddRefs(event));
+  nsCOMPtr<nsIDocument> doc = content->OwnerDoc();
+
+  IgnoredErrorResult ignored;
+  RefPtr<Event> event = doc->CreateEvent(NS_LITERAL_STRING("customevent"),
+                                         CallerType::System, ignored);
 
   nsCOMPtr<nsIDOMCustomEvent> treeEvent(do_QueryInterface(event));
   if (!treeEvent)
     return;
 
   nsCOMPtr<nsIWritablePropertyBag2> propBag(
     do_CreateInstance("@mozilla.org/hash-property-bag;1"));
   if (!propBag)
--- a/taskcluster/ci/repackage-l10n/kind.yml
+++ b/taskcluster/ci/repackage-l10n/kind.yml
@@ -24,21 +24,21 @@ only-for-build-platforms:
    - win64-nightly/opt
    - linux-devedition-nightly/opt
    - linux64-devedition-nightly/opt
    - macosx64-devedition-nightly/opt
    - win32-devedition-nightly/opt
    - win64-devedition-nightly/opt
 
 job-template:
-    mozharness:
-        config:
-            by-build-platform:
-                linux-.*:
-                    - repackage/linux32_signed.py
-                linux64-.*:
-                    - repackage/linux64_signed.py
-                macosx64-.*:
-                    - repackage/osx_signed.py
-                win32-.*:
-                    - repackage/win32_signed.py
-                win64-.*:
-                    - repackage/win64_signed.py
+   mozharness:
+      config:
+         by-build-platform:
+            linux-.*:
+               - repackage/linux32_signed.py
+            linux64-.*:
+               - repackage/linux64_signed.py
+            macosx64-.*:
+               - repackage/osx_signed.py
+            win32-.*:
+               - repackage/win32_signed.py
+            win64-.*:
+               - repackage/win64_signed.py
--- a/taskcluster/taskgraph/transforms/task.py
+++ b/taskcluster/taskgraph/transforms/task.py
@@ -1621,19 +1621,20 @@ def check_caches_are_volumes(task):
     volumes = set(task['worker']['volumes'])
     paths = set(c['mount-point'] for c in task['worker'].get('caches', []))
     missing = paths - volumes
 
     if not missing:
         return
 
     raise Exception('task %s (image %s) has caches that are not declared as '
-                    'Docker volumes: %s' % (task['label'],
-                                            task['worker']['docker-image'],
-                                            ', '.join(sorted(missing))))
+                    'Docker volumes: %s'
+                    'Have you added them as VOLUMEs in the Dockerfile?'
+                    % (task['label'], task['worker']['docker-image'],
+                       ', '.join(sorted(missing))))
 
 
 @transforms.add
 def check_run_task_caches(config, tasks):
     """Audit for caches requiring run-task.
 
     run-task manages caches in certain ways. If a cache managed by run-task
     is used by a non run-task task, it could cause problems. So we audit for
--- a/toolkit/components/satchel/nsFormFillController.cpp
+++ b/toolkit/components/satchel/nsFormFillController.cpp
@@ -21,17 +21,16 @@
 #include "nsIServiceManager.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsPIDOMWindow.h"
 #include "nsIWebNavigation.h"
 #include "nsIContentViewer.h"
 #include "nsIDOMKeyEvent.h"
-#include "nsIDOMDocument.h"
 #include "nsIDOMElement.h"
 #include "nsIDocument.h"
 #include "nsIContent.h"
 #include "nsIPresShell.h"
 #include "nsRect.h"
 #include "nsIDOMHTMLFormElement.h"
 #include "nsILoginManager.h"
 #include "nsIDOMMouseEvent.h"
@@ -681,20 +680,20 @@ nsFormFillController::OnSearchComplete()
 
 NS_IMETHODIMP
 nsFormFillController::OnTextEntered(nsIDOMEvent* aEvent,
                                     bool* aPrevent)
 {
   NS_ENSURE_ARG(aPrevent);
   NS_ENSURE_TRUE(mFocusedInput, NS_OK);
   // Fire off a DOMAutoComplete event
-  nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(mFocusedInput->OwnerDoc());
 
-  nsCOMPtr<nsIDOMEvent> event;
-  domDoc->CreateEvent(NS_LITERAL_STRING("Events"), getter_AddRefs(event));
+  IgnoredErrorResult ignored;
+  RefPtr<Event> event = mFocusedInput->OwnerDoc()->
+    CreateEvent(NS_LITERAL_STRING("Events"), CallerType::System, ignored);
   NS_ENSURE_STATE(event);
 
   event->InitEvent(NS_LITERAL_STRING("DOMAutoComplete"), true, true);
 
   // XXXjst: We mark this event as a trusted event, it's up to the
   // callers of this to ensure that it's only called from trusted
   // code.
   event->SetTrusted(true);
@@ -1435,19 +1434,17 @@ nsFormFillController::GetDocShellForInpu
 
 nsPIDOMWindowOuter*
 nsFormFillController::GetWindowForDocShell(nsIDocShell *aDocShell)
 {
   nsCOMPtr<nsIContentViewer> contentViewer;
   aDocShell->GetContentViewer(getter_AddRefs(contentViewer));
   NS_ENSURE_TRUE(contentViewer, nullptr);
 
-  nsCOMPtr<nsIDOMDocument> domDoc;
-  contentViewer->GetDOMDocument(getter_AddRefs(domDoc));
-  nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
+  nsCOMPtr<nsIDocument> doc = contentViewer->GetDocument();
   NS_ENSURE_TRUE(doc, nullptr);
 
   return doc->GetWindow();
 }
 
 int32_t
 nsFormFillController::GetIndexOfDocShell(nsIDocShell *aDocShell)
 {
--- a/toolkit/content/widgets/textbox.xml
+++ b/toolkit/content/widgets/textbox.xml
@@ -514,17 +514,17 @@
       </field>
 
       <property name="spellCheckerUI" readonly="true">
         <getter><![CDATA[
           if (!this._spellCheckInitialized) {
             this._spellCheckInitialized = true;
 
             const CI = Components.interfaces;
-            if (!(document instanceof CI.nsIDOMXULDocument))
+            if (ChromeUtils.getClassName(document) != "XULDocument")
               return null;
 
             var textbox = document.getBindingParent(this);
             if (!textbox || !(textbox instanceof CI.nsIDOMXULTextBoxElement))
               return null;
 
             try {
               ChromeUtils.import("resource://gre/modules/InlineSpellChecker.jsm", this);
--- a/widget/cocoa/nsMenuBarX.h
+++ b/widget/cocoa/nsMenuBarX.h
@@ -14,16 +14,17 @@
 #include "nsChangeObserver.h"
 #include "nsINativeMenuService.h"
 #include "nsString.h"
 
 class nsMenuBarX;
 class nsMenuX;
 class nsIWidget;
 class nsIContent;
+class nsIDocument;
 
 namespace mozilla {
 namespace dom {
 class Element;
 }
 }
 
 // ApplicationMenuDelegate is used to receive Cocoa notifications.
@@ -129,17 +130,17 @@ public:
   void              ApplicationMenuOpened();
   bool              PerformKeyEquivalent(NSEvent* theEvent);
 
 protected:
   void              ConstructNativeMenus();
   void              ConstructFallbackNativeMenus();
   nsresult          InsertMenuAtIndex(nsMenuX* aMenu, uint32_t aIndex);
   void              RemoveMenuAtIndex(uint32_t aIndex);
-  void              HideItem(nsIDOMDocument* inDoc, const nsAString & inID, nsIContent** outHiddenNode);
+  void              HideItem(nsIDocument* inDoc, const nsAString & inID, nsIContent** outHiddenNode);
   void              AquifyMenuBar();
   NSMenuItem*       CreateNativeAppMenuItem(nsMenuX* inMenu, const nsAString& nodeID, SEL action,
                                             int tag, NativeMenuItemTarget* target);
   nsresult          CreateApplicationMenu(nsMenuX* inMenu);
 
   nsTArray<mozilla::UniquePtr<nsMenuX>> mMenuArray;
   nsIWidget*         mParentWindow;        // [weak]
   GeckoNSMenu*       mNativeMenu;            // root menu, representing entire menu bar
--- a/widget/cocoa/nsMenuBarX.mm
+++ b/widget/cocoa/nsMenuBarX.mm
@@ -17,18 +17,16 @@
 #include "nsString.h"
 #include "nsGkAtoms.h"
 #include "nsObjCExceptions.h"
 #include "nsThreadUtils.h"
 
 #include "nsIContent.h"
 #include "nsIWidget.h"
 #include "nsIDocument.h"
-#include "nsIDOMDocument.h"
-#include "nsIDOMElement.h"
 #include "nsIAppStartup.h"
 #include "nsIStringBundle.h"
 #include "nsToolkitCompsCID.h"
 
 #include "mozilla/dom/Element.h"
 
 NativeMenuItemTarget* nsMenuBarX::sNativeEventTarget = nil;
 nsMenuBarX* nsMenuBarX::sLastGeckoMenuBarPainted = nullptr;
@@ -475,24 +473,22 @@ nsresult nsMenuBarX::Paint()
 // objects.  For example "key_selectAll".  Returns a value that can be
 // compared to the first character of [NSEvent charactersIgnoringModifiers]
 // when [NSEvent modifierFlags] == NSCommandKeyMask.
 char nsMenuBarX::GetLocalizedAccelKey(const char *shortcutID)
 {
   if (!sLastGeckoMenuBarPainted)
     return 0;
 
-  nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(sLastGeckoMenuBarPainted->mContent->OwnerDoc()));
-  if (!domDoc)
+  nsCOMPtr<nsIDocument> doc = sLastGeckoMenuBarPainted->mContent->OwnerDoc();
+  if (!doc)
     return 0;
 
-  NS_ConvertASCIItoUTF16 shortcutIDStr((const char *)shortcutID);
-  nsCOMPtr<nsIDOMElement> shortcutElement;
-  domDoc->GetElementById(shortcutIDStr, getter_AddRefs(shortcutElement));
-  nsCOMPtr<Element> shortcutContent = do_QueryInterface(shortcutElement);
+  NS_ConvertASCIItoUTF16 shortcutIDStr(shortcutID);
+  nsCOMPtr<Element> shortcutContent = doc->GetElementById(shortcutIDStr);
   if (!shortcutContent)
     return 0;
 
   nsAutoString key;
   shortcutContent->GetAttr(kNameSpaceID_None, nsGkAtoms::key, key);
   NS_LossyConvertUTF16toASCII keyASC(key.get());
   const char *keyASCPtr = keyASC.get();
   if (!keyASCPtr)
@@ -535,34 +531,32 @@ void nsMenuBarX::ApplicationMenuOpened()
 bool nsMenuBarX::PerformKeyEquivalent(NSEvent* theEvent)
 {
   return [mNativeMenu performSuperKeyEquivalent:theEvent];
 }
 
 // Hide the item in the menu by setting the 'hidden' attribute. Returns it in |outHiddenNode| so
 // the caller can hang onto it if they so choose. It is acceptable to pass nsull
 // for |outHiddenNode| if the caller doesn't care about the hidden node.
-void nsMenuBarX::HideItem(nsIDOMDocument* inDoc, const nsAString & inID, nsIContent** outHiddenNode)
+void nsMenuBarX::HideItem(nsIDocument* inDoc, const nsAString & inID, nsIContent** outHiddenNode)
 {
-  nsCOMPtr<nsIDOMElement> menuItem;
-  inDoc->GetElementById(inID, getter_AddRefs(menuItem));
-  nsCOMPtr<Element> menuElement(do_QueryInterface(menuItem));
+  nsCOMPtr<Element> menuElement = inDoc->GetElementById(inID);
   if (menuElement) {
     menuElement->SetAttr(kNameSpaceID_None, nsGkAtoms::hidden, NS_LITERAL_STRING("true"), false);
     if (outHiddenNode) {
       *outHiddenNode = menuElement.get();
       NS_IF_ADDREF(*outHiddenNode);
     }
   }
 }
 
 // Do what is necessary to conform to the Aqua guidelines for menus.
 void nsMenuBarX::AquifyMenuBar()
 {
-  nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(mContent->GetComposedDoc()));
+  nsCOMPtr<nsIDocument> domDoc = mContent->GetComposedDoc();
   if (domDoc) {
     // remove the "About..." item and its separator
     HideItem(domDoc, NS_LITERAL_STRING("aboutSeparator"), nullptr);
     HideItem(domDoc, NS_LITERAL_STRING("aboutName"), getter_AddRefs(mAboutItemContent));
     if (!sAboutItemContent)
       sAboutItemContent = mAboutItemContent;
 
     // remove quit item and its separator
--- a/widget/cocoa/nsMenuItemX.mm
+++ b/widget/cocoa/nsMenuItemX.mm
@@ -11,21 +11,23 @@
 #include "nsCocoaUtils.h"
 
 #include "nsObjCExceptions.h"
 
 #include "nsCOMPtr.h"
 #include "nsGkAtoms.h"
 
 #include "mozilla/dom/Element.h"
+#include "mozilla/dom/Event.h"
+#include "mozilla/ErrorResult.h"
 #include "nsIWidget.h"
 #include "nsIDocument.h"
-#include "nsIDOMDocument.h"
-#include "nsIDOMElement.h"
-#include "nsIDOMEvent.h"
+
+using mozilla::dom::Event;
+using mozilla::dom::CallerType;
 
 nsMenuItemX::nsMenuItemX()
 {
   mType           = eRegularMenuItemType;
   mNativeMenuItem = nil;
   mMenuParent     = nullptr;
   mMenuGroupOwner = nullptr;
   mIsChecked      = false;
@@ -172,40 +174,35 @@ void nsMenuItemX::DoCommand()
 nsresult nsMenuItemX::DispatchDOMEvent(const nsString &eventName, bool *preventDefaultCalled)
 {
   if (!mContent)
     return NS_ERROR_FAILURE;
 
   // get owner document for content
   nsCOMPtr<nsIDocument> parentDoc = mContent->OwnerDoc();
 
-  // get interface for creating DOM events from content owner document
-  nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(parentDoc);
-  if (!domDoc) {
-    NS_WARNING("Failed to QI parent nsIDocument to nsIDOMDocument");
-    return NS_ERROR_FAILURE;
-  }
-
   // create DOM event
-  nsCOMPtr<nsIDOMEvent> event;
-  nsresult rv = domDoc->CreateEvent(NS_LITERAL_STRING("Events"), getter_AddRefs(event));
-  if (NS_FAILED(rv)) {
-    NS_WARNING("Failed to create nsIDOMEvent");
-    return rv;
+  ErrorResult rv;
+  RefPtr<Event> event = parentDoc->CreateEvent(NS_LITERAL_STRING("Events"),
+                                               CallerType::System,
+                                               rv);
+  if (rv.Failed()) {
+    NS_WARNING("Failed to create Event");
+    return rv.StealNSResult();
   }
   event->InitEvent(eventName, true, true);
 
   // mark DOM event as trusted
   event->SetTrusted(true);
 
   // send DOM event
-  rv = mContent->DispatchEvent(event, preventDefaultCalled);
-  if (NS_FAILED(rv)) {
+  nsresult err = mContent->DispatchEvent(event, preventDefaultCalled);
+  if (NS_FAILED(err)) {
     NS_WARNING("Failed to send DOM event via EventTarget");
-    return rv;
+    return err;
   }
 
   return NS_OK;
 }
 
 // Walk the sibling list looking for nodes with the same name and
 // uncheck them all.
 void nsMenuItemX::UncheckRadioSiblings(nsIContent* inCheckedContent)
--- a/xpcom/reflect/xptinfo/ShimInterfaceInfo.cpp
+++ b/xpcom/reflect/xptinfo/ShimInterfaceInfo.cpp
@@ -68,17 +68,16 @@
 #include "nsIDOMTreeWalker.h"
 #include "nsIDOMUIEvent.h"
 #include "nsIDOMValidityState.h"
 #include "nsIDOMWheelEvent.h"
 #include "nsIDOMXMLDocument.h"
 #include "nsIDOMXPathEvaluator.h"
 #include "nsIDOMXPathResult.h"
 #include "nsIDOMXULCommandEvent.h"
-#include "nsIDOMXULDocument.h"
 #include "nsIDOMXULElement.h"
 #include "nsIFrameLoader.h"
 #include "nsIListBoxObject.h"
 #include "nsIMenuBoxObject.h"
 #include "nsIScrollBoxObject.h"
 #include "nsISelection.h"
 #include "nsITreeBoxObject.h"
 #include "nsIWebBrowserPersistable.h"
@@ -301,17 +300,16 @@ const ComponentsInterfaceShimEntry kComp
   DEFINE_SHIM_WITH_CUSTOM_INTERFACE(nsIWebBrowserPersistable, FrameLoader),
   DEFINE_SHIM(WheelEvent),
   DEFINE_SHIM(XMLDocument),
   DEFINE_SHIM_WITH_CUSTOM_INTERFACE(nsIXMLHttpRequestEventTarget, XMLHttpRequestEventTarget),
   DEFINE_SHIM_WITH_CUSTOM_INTERFACE(nsIXMLHttpRequestUpload, XMLHttpRequestUpload),
   DEFINE_SHIM(XPathEvaluator),
   DEFINE_SHIM(XPathResult),
   DEFINE_SHIM(XULCommandEvent),
-  DEFINE_SHIM(XULDocument),
   DEFINE_SHIM(XULElement),
   DEFINE_SHIM_WITH_CUSTOM_INTERFACE(nsISelection, Selection),
 };
 
 #undef DEFINE_SHIM
 #undef DEFINE_SHIM_WITH_CUSTOM_INTERFACE
 
 NS_IMPL_ISUPPORTS(ShimInterfaceInfo, nsISupports, nsIInterfaceInfo)
--- a/xpfe/appshell/moz.build
+++ b/xpfe/appshell/moz.build
@@ -34,13 +34,14 @@ UNIFIED_SOURCES += [
     'nsContentTreeOwner.cpp',
     'nsWebShellWindow.cpp',
     'nsWindowMediator.cpp',
     'nsXULWindow.cpp',
 ]
 
 LOCAL_INCLUDES += [
     '/dom/base',
+    '/dom/xul',
 ]
 
 FINAL_LIBRARY = 'xul'
 
 include('/ipc/chromium/chromium-config.mozbuild')
--- a/xpfe/appshell/nsAppShellWindowEnumerator.cpp
+++ b/xpfe/appshell/nsAppShellWindowEnumerator.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 "nsAppShellWindowEnumerator.h"
 
 #include "nsIContentViewer.h"
 #include "nsIDocShell.h"
 #include "nsIDocument.h"
-#include "nsIDOMDocument.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMWindow.h"
 #include "nsIFactory.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIXULWindow.h"
 #include "mozilla/dom/Element.h"
 
@@ -32,22 +31,22 @@ static void GetWindowType(nsIXULWindow* 
 
 nsCOMPtr<nsIDOMNode> GetDOMNodeFromDocShell(nsIDocShell *aShell)
 {
   nsCOMPtr<nsIDOMNode> node;
 
   nsCOMPtr<nsIContentViewer> cv;
   aShell->GetContentViewer(getter_AddRefs(cv));
   if (cv) {
-    nsCOMPtr<nsIDOMDocument> domdoc(do_QueryInterface(cv->GetDocument()));
-    if (domdoc) {
-      nsCOMPtr<nsIDOMElement> element;
-      domdoc->GetDocumentElement(getter_AddRefs(element));
-      if (element)
-        node = element;
+    nsCOMPtr<nsIDocument> doc = cv->GetDocument();
+    if (doc) {
+      Element* element = doc->GetDocumentElement();
+      if (element) {
+        node = element->AsDOMNode();
+      }
     }
   }
 
   return node;
 }
 
 // generic "retrieve the value of a XUL attribute" function
 void GetAttribute(nsIXULWindow *inWindow, const nsAString &inAttribute,
--- a/xpfe/appshell/nsWebShellWindow.cpp
+++ b/xpfe/appshell/nsWebShellWindow.cpp
@@ -28,31 +28,27 @@
 #include "nsIDOMXULElement.h"
 
 #include "nsWidgetInitData.h"
 #include "nsWidgetsCID.h"
 #include "nsIWidget.h"
 #include "nsIWidgetListener.h"
 
 #include "nsIDOMCharacterData.h"
-#include "nsIDOMNodeList.h"
+#include "nsINodeList.h"
 
 #include "nsITimer.h"
 #include "nsXULPopupManager.h"
 
-
-#include "nsIDOMXULDocument.h"
-
 #include "nsFocusManager.h"
 
 #include "nsIWebProgress.h"
 #include "nsIWebProgressListener.h"
 
 #include "nsIDocument.h"
-#include "nsIDOMDocument.h"
 #include "nsIDOMNode.h"
 #include "nsIDOMElement.h"
 #include "nsIDocumentLoaderFactory.h"
 #include "nsIObserverService.h"
 
 #include "nsIScreenManager.h"
 #include "nsIScreen.h"
 
@@ -503,36 +499,36 @@ nsWebShellWindow::WindowDeactivated()
   nsCOMPtr<nsPIDOMWindowOuter> window =
     mDocShell ? mDocShell->GetWindow() : nullptr;
   nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
   if (fm && window)
     fm->WindowLowered(window);
 }
 
 #ifdef USE_NATIVE_MENUS
-static void LoadNativeMenus(nsIDOMDocument *aDOMDoc, nsIWidget *aParentWindow)
+static void LoadNativeMenus(nsIDocument *aDoc, nsIWidget *aParentWindow)
 {
   if (gfxPlatform::IsHeadless()) {
     return;
   }
   nsCOMPtr<nsINativeMenuService> nms = do_GetService("@mozilla.org/widget/nativemenuservice;1");
   if (!nms) {
     return;
   }
 
   // Find the menubar tag (if there is more than one, we ignore all but
   // the first).
-  nsCOMPtr<nsIDOMNodeList> menubarElements;
-  aDOMDoc->GetElementsByTagNameNS(NS_LITERAL_STRING("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"),
-                                  NS_LITERAL_STRING("menubar"),
-                                  getter_AddRefs(menubarElements));
+  nsCOMPtr<nsINodeList> menubarElements =
+    aDoc->GetElementsByTagNameNS(NS_LITERAL_STRING("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"),
+                                 NS_LITERAL_STRING("menubar"));
 
-  nsCOMPtr<nsIDOMNode> menubarNode;
-  if (menubarElements)
-    menubarElements->Item(0, getter_AddRefs(menubarNode));
+  nsCOMPtr<nsINode> menubarNode;
+  if (menubarElements) {
+    menubarNode = menubarElements->Item(0);
+  }
 
   if (menubarNode) {
     nsCOMPtr<Element> menubarContent(do_QueryInterface(menubarNode));
     nms->CreateNativeMenuBar(aParentWindow, menubarContent);
   } else {
     nms->CreateNativeMenuBar(aParentWindow, nullptr);
   }
 }
@@ -650,19 +646,19 @@ nsWebShellWindow::OnStateChange(nsIWebPr
 
 #ifdef USE_NATIVE_MENUS
   ///////////////////////////////
   // Find the Menubar DOM  and Load the menus, hooking them up to the loaded commands
   ///////////////////////////////
   nsCOMPtr<nsIContentViewer> cv;
   mDocShell->GetContentViewer(getter_AddRefs(cv));
   if (cv) {
-    nsCOMPtr<nsIDOMDocument> menubarDOMDoc(do_QueryInterface(cv->GetDocument()));
-    if (menubarDOMDoc)
-      LoadNativeMenus(menubarDOMDoc, mWindow);
+    nsCOMPtr<nsIDocument> menubarDoc = cv->GetDocument();
+    if (menubarDoc)
+      LoadNativeMenus(menubarDoc, mWindow);
   }
 #endif // USE_NATIVE_MENUS
 
   OnChromeLoaded();
 
   return NS_OK;
 }
 
--- a/xpfe/appshell/nsXULWindow.cpp
+++ b/xpfe/appshell/nsXULWindow.cpp
@@ -21,17 +21,16 @@
 
 //Interfaces needed to be included
 #include "nsIAppShell.h"
 #include "nsIAppShellService.h"
 #include "nsIServiceManager.h"
 #include "nsIContentViewer.h"
 #include "nsIDocument.h"
 #include "nsIDOMDocument.h"
-#include "nsIDOMXULDocument.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMXULElement.h"
 #include "nsPIDOMWindow.h"
 #include "nsIDOMScreen.h"
 #include "nsIEmbeddingSiteWindow.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIIOService.h"
@@ -46,16 +45,17 @@
 #include "nsIURI.h"
 #include "nsAppShellCID.h"
 #include "nsReadableUtils.h"
 #include "nsStyleConsts.h"
 #include "nsPresContext.h"
 #include "nsContentUtils.h"
 #include "nsWebShellWindow.h" // get rid of this one, too...
 #include "nsGlobalWindow.h"
+#include "XULDocument.h"
 
 #include "prenv.h"
 #include "mozilla/AutoRestore.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 #include "mozilla/dom/BarProps.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/Event.h"
@@ -1615,90 +1615,96 @@ NS_IMETHODIMP nsXULWindow::SavePersisten
     if (NS_SUCCEEDED(parent->GetPosition(&parentX, &parentY))) {
       rect.MoveBy(-parentX, -parentY);
     }
   }
 
   char                        sizeBuf[10];
   nsAutoString                sizeString;
   nsAutoString                windowElementId;
-  nsCOMPtr<nsIDOMXULDocument> ownerXULDoc;
+  RefPtr<dom::XULDocument>    ownerXULDoc;
 
   // fetch docShellElement's ID and XUL owner document
-  ownerXULDoc = do_QueryInterface(docShellElement->OwnerDoc());
+  ownerXULDoc = docShellElement->OwnerDoc()->AsXULDocument();
   if (docShellElement->IsXULElement()) {
     docShellElement->GetId(windowElementId);
   }
 
   bool shouldPersist = !isFullscreen && ownerXULDoc;
   ErrorResult rv;
   // (only for size elements which are persisted)
   if ((mPersistentAttributesDirty & PAD_POSITION) && gotRestoredBounds) {
     if (persistString.Find("screenX") >= 0) {
       SprintfLiteral(sizeBuf, "%d", NSToIntRound(rect.X() / posScale.scale));
       CopyASCIItoUTF16(sizeBuf, sizeString);
       docShellElement->SetAttribute(SCREENX_ATTRIBUTE, sizeString, rv);
       if (shouldPersist) {
-        ownerXULDoc->Persist(windowElementId, SCREENX_ATTRIBUTE);
+        IgnoredErrorResult err;
+        ownerXULDoc->Persist(windowElementId, SCREENX_ATTRIBUTE, err);
       }
     }
     if (persistString.Find("screenY") >= 0) {
       SprintfLiteral(sizeBuf, "%d", NSToIntRound(rect.Y() / posScale.scale));
       CopyASCIItoUTF16(sizeBuf, sizeString);
       docShellElement->SetAttribute(SCREENY_ATTRIBUTE, sizeString, rv);
       if (shouldPersist) {
-        ownerXULDoc->Persist(windowElementId, SCREENY_ATTRIBUTE);
+        IgnoredErrorResult err;
+        ownerXULDoc->Persist(windowElementId, SCREENY_ATTRIBUTE, err);
       }
     }
   }
 
   if ((mPersistentAttributesDirty & PAD_SIZE) && gotRestoredBounds) {
     if (persistString.Find("width") >= 0) {
       SprintfLiteral(sizeBuf, "%d", NSToIntRound(rect.Width() / sizeScale.scale));
       CopyASCIItoUTF16(sizeBuf, sizeString);
       docShellElement->SetAttribute(WIDTH_ATTRIBUTE, sizeString, rv);
       if (shouldPersist) {
-        ownerXULDoc->Persist(windowElementId, WIDTH_ATTRIBUTE);
+        IgnoredErrorResult err;
+        ownerXULDoc->Persist(windowElementId, WIDTH_ATTRIBUTE, err);
       }
     }
     if (persistString.Find("height") >= 0) {
       SprintfLiteral(sizeBuf, "%d", NSToIntRound(rect.Height() / sizeScale.scale));
       CopyASCIItoUTF16(sizeBuf, sizeString);
       docShellElement->SetAttribute(HEIGHT_ATTRIBUTE, sizeString, rv);
       if (shouldPersist) {
-        ownerXULDoc->Persist(windowElementId, HEIGHT_ATTRIBUTE);
+        IgnoredErrorResult err;
+        ownerXULDoc->Persist(windowElementId, HEIGHT_ATTRIBUTE, err);
       }
     }
   }
 
   if (mPersistentAttributesDirty & PAD_MISC) {
     nsSizeMode sizeMode = mWindow->SizeMode();
 
     if (sizeMode != nsSizeMode_Minimized) {
       if (sizeMode == nsSizeMode_Maximized)
         sizeString.Assign(SIZEMODE_MAXIMIZED);
       else if (sizeMode == nsSizeMode_Fullscreen)
         sizeString.Assign(SIZEMODE_FULLSCREEN);
       else
         sizeString.Assign(SIZEMODE_NORMAL);
       docShellElement->SetAttribute(MODE_ATTRIBUTE, sizeString, rv);
       if (shouldPersist && persistString.Find("sizemode") >= 0) {
-        ownerXULDoc->Persist(windowElementId, MODE_ATTRIBUTE);
+        IgnoredErrorResult err;
+        ownerXULDoc->Persist(windowElementId, MODE_ATTRIBUTE, err);
       }
     }
     if (persistString.Find("zlevel") >= 0) {
       uint32_t zLevel;
       nsCOMPtr<nsIWindowMediator> mediator(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));
       if (mediator) {
         mediator->GetZLevel(this, &zLevel);
         SprintfLiteral(sizeBuf, "%" PRIu32, zLevel);
         CopyASCIItoUTF16(sizeBuf, sizeString);
         docShellElement->SetAttribute(ZLEVEL_ATTRIBUTE, sizeString, rv);
         if (shouldPersist) {
-          ownerXULDoc->Persist(windowElementId, ZLEVEL_ATTRIBUTE);
+          IgnoredErrorResult err;
+          ownerXULDoc->Persist(windowElementId, ZLEVEL_ATTRIBUTE, err);
         }
       }
     }
   }
 
   mPersistentAttributesDirty = 0;
   return NS_OK;
 }