merge mozilla-central to b2g-inbound
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Thu, 08 Aug 2013 14:46:05 +0200
changeset 154774 d373fb87f36a6b85fb6588acdeee9b6b70510222
parent 154773 1d5d9f6bb99da6dcf6c60343fb35a5edf16faf2b (current diff)
parent 154695 264e54846d4ac3e3c8fbb9d08e11271ec3392058 (diff)
child 154775 60ff38dd16945e3f30a882e66a345a054151a998
push id2961
push userlsblakk@mozilla.com
push dateMon, 28 Oct 2013 21:59:28 +0000
treeherdermozilla-beta@73ef4f13486f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone26.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
merge mozilla-central to b2g-inbound
config/tests/unit-writemozinfo.py
config/writemozinfo.py
content/html/content/public/nsILink.h
--- a/accessible/src/generic/BaseAccessibles.cpp
+++ b/accessible/src/generic/BaseAccessibles.cpp
@@ -9,17 +9,16 @@
 #include "HyperTextAccessibleWrap.h"
 #include "nsAccessibilityService.h"
 #include "nsAccUtils.h"
 #include "nsCoreUtils.h"
 #include "Role.h"
 #include "States.h"
 
 #include "nsGUIEvent.h"
-#include "nsILink.h"
 #include "nsINameSpaceManager.h"
 #include "nsIURI.h"
 
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
 // LeafAccessible
 ////////////////////////////////////////////////////////////////////////////////
--- a/accessible/src/generic/ImageAccessible.cpp
+++ b/accessible/src/generic/ImageAccessible.cpp
@@ -10,17 +10,16 @@
 #include "AccIterator.h"
 #include "States.h"
 
 #include "imgIContainer.h"
 #include "imgIRequest.h"
 #include "nsGenericHTMLElement.h"
 #include "nsIDocument.h"
 #include "nsIImageLoadingContent.h"
-#include "nsILink.h"
 #include "nsIPresShell.h"
 #include "nsIServiceManager.h"
 #include "nsIDOMHTMLImageElement.h"
 #include "nsPIDOMWindow.h"
 
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -619,16 +619,19 @@ pref("network.protocol-handler.warn-exte
 // It will also try to open link clicks inside the browser before
 // failing over to the system handlers.
 pref("network.protocol-handler.expose-all", true);
 pref("network.protocol-handler.expose.mailto", false);
 pref("network.protocol-handler.expose.news", false);
 pref("network.protocol-handler.expose.snews", false);
 pref("network.protocol-handler.expose.nntp", false);
 
+// Warning for about:networking page
+pref("network.warnOnAboutNetworking", true);
+
 pref("accessibility.typeaheadfind", false);
 pref("accessibility.typeaheadfind.timeout", 5000);
 pref("accessibility.typeaheadfind.linksonly", false);
 pref("accessibility.typeaheadfind.flashBar", 1);
 
 // plugin finder service url
 pref("pfs.datasource.url", "https://pfs.mozilla.org/plugins/PluginFinderService.php?mimetype=%PLUGIN_MIMETYPE%&appID=%APP_ID%&appVersion=%APP_VERSION%&clientOS=%CLIENT_OS%&chromeLocale=%CHROME_LOCALE%&appRelease=%APP_RELEASE%");
 
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -4,17 +4,17 @@
 
 @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
 @namespace html url("http://www.w3.org/1999/xhtml");
 
 searchbar {
   -moz-binding: url("chrome://browser/content/search/search.xml#searchbar");
 }
 
-browser[remote="true"] {
+.browserStack > browser[remote="true"] {
   -moz-binding: url("chrome://global/content/bindings/remote-browser.xml#remote-browser");
 }
 
 tabbrowser {
   -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser");
 }
 
 .tabbrowser-tabs {
--- a/browser/base/content/content.js
+++ b/browser/base/content/content.js
@@ -33,17 +33,21 @@ addMessageListener("Browser:HideSessionR
   let doc = content.document;
   let container;
   if (doc.documentURI.toLowerCase() == "about:home" &&
       (container = doc.getElementById("sessionRestoreContainer"))){
     container.hidden = true;
   }
 });
 
-if (!Services.prefs.getBoolPref("browser.tabs.remote")) {
+if (Services.prefs.getBoolPref("browser.tabs.remote")) {
+  addEventListener("contextmenu", function (event) {
+    sendAsyncMessage("contextmenu", {}, { event: event });
+  }, false);
+} else {
   addEventListener("DOMContentLoaded", function(event) {
     LoginManagerContent.onContentLoaded(event);
   });
   addEventListener("DOMFormHasPassword", function(event) {
     InsecurePasswordUtils.checkForInsecurePasswords(event.target);
   });
   addEventListener("DOMAutoComplete", function(event) {
     LoginManagerContent.onUsernameInput(event);
--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -1,14 +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/.
 
 Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
 
+var gContextMenuContentData = null;
+
 function nsContextMenu(aXulMenu, aIsShift) {
   this.shouldDisplay = true;
   this.initMenu(aXulMenu, aIsShift);
 }
 
 // Prototype for nsContextMenu "class."
 nsContextMenu.prototype = {
   initMenu: function CM_initMenu(aXulMenu, aIsShift) {
@@ -34,16 +36,17 @@ nsContextMenu.prototype = {
     this.isContentSelected = this.isContentSelection();
     this.onPlainTextLink = false;
 
     // Initialize (disable/remove) menu items.
     this.initItems();
   },
 
   hiding: function CM_hiding() {
+    gContextMenuContentData = null;
     InlineSpellCheckerUI.clearSuggestionsFromMenu();
     InlineSpellCheckerUI.clearDictionaryListFromMenu();
     InlineSpellCheckerUI.uninit();
   },
 
   initItems: function CM_initItems() {
     this.initPageMenuSeparator();
     this.initOpenItems();
@@ -495,16 +498,25 @@ nsContextMenu.prototype = {
     return gDevTools.showToolbox(tt, "inspector").then(function(toolbox) {
       let inspector = toolbox.getCurrentPanel();
       inspector.selection.setNode(this.target, "browser-context-menu");
     }.bind(this));
   },
 
   // Set various context menu attributes based on the state of the world.
   setTarget: function (aNode, aRangeParent, aRangeOffset) {
+    // If gContextMenuContentData is not null, this event was forwarded from a
+    // child process, so use that information instead.
+    if (gContextMenuContentData) {
+      this.isRemote = true;
+      aNode = gContextMenuContentData.event.target;
+    } else {
+      this.isRemote = false;
+    }
+
     const xulNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
     if (aNode.namespaceURI == xulNS ||
         aNode.nodeType == Node.DOCUMENT_NODE ||
         this.isDisabledForEvents(aNode)) {
       this.shouldDisplay = false;
       return;
     }
 
@@ -534,21 +546,27 @@ nsContextMenu.prototype = {
     this.bgImageURL        = "";
     this.onEditableArea    = false;
     this.isDesignMode      = false;
     this.onCTPPlugin       = false;
 
     // Remember the node that was clicked.
     this.target = aNode;
 
-    this.browser = this.target.ownerDocument.defaultView
-                                .QueryInterface(Ci.nsIInterfaceRequestor)
-                                .getInterface(Ci.nsIWebNavigation)
-                                .QueryInterface(Ci.nsIDocShell)
-                                .chromeEventHandler;
+    // If this is a remote context menu event, use the information from
+    // gContextMenuContentData instead.
+    if (this.isRemote) {
+      this.browser = gContextMenuContentData.browser;
+    } else {
+      this.browser = this.target.ownerDocument.defaultView
+                                  .QueryInterface(Ci.nsIInterfaceRequestor)
+                                  .getInterface(Ci.nsIWebNavigation)
+                                  .QueryInterface(Ci.nsIDocShell)
+                                  .chromeEventHandler;
+    }
     this.onSocial = !!this.browser.getAttribute("origin");
 
     // Check if we are in a synthetic document (stand alone image, video, etc.).
     this.inSyntheticDoc =  this.target.ownerDocument.mozSyntheticDocument;
     // First, do checks for nodes that never have children.
     if (this.target.nodeType == Node.ELEMENT_NODE) {
       // See if the user clicked on an image.
       if (this.target instanceof Ci.nsIImageLoadingContent &&
@@ -767,48 +785,60 @@ nsContextMenu.prototype = {
     // until we do.
     return this.linkProtocol && !(
              this.linkProtocol == "mailto"     ||
              this.linkProtocol == "javascript" ||
              this.linkProtocol == "news"       ||
              this.linkProtocol == "snews"      );
   },
 
+  _unremotePrincipal: function(aRemotePrincipal) {
+    if (this.isRemote) {
+      return Cc["@mozilla.org/scriptsecuritymanager;1"]
+               .getService(Ci.nsIScriptSecurityManager)
+               .getAppCodebasePrincipal(aRemotePrincipal.URI,
+                                        aRemotePrincipal.appId,
+                                        aRemotePrincipal.isInBrowserElement);
+    }
+
+    return aRemotePrincipal;
+  },
+
   // Open linked-to URL in a new window.
   openLink : function () {
     var doc = this.target.ownerDocument;
-    urlSecurityCheck(this.linkURL, doc.nodePrincipal);
+    urlSecurityCheck(this.linkURL, this._unremotePrincipal(doc.nodePrincipal));
     openLinkIn(this.linkURL, "window",
                { charset: doc.characterSet,
                  referrerURI: doc.documentURIObject });
   },
 
   // Open linked-to URL in a new private window.
   openLinkInPrivateWindow : function () {
     var doc = this.target.ownerDocument;
-    urlSecurityCheck(this.linkURL, doc.nodePrincipal);
+    urlSecurityCheck(this.linkURL, this._unremotePrincipal(doc.nodePrincipal));
     openLinkIn(this.linkURL, "window",
                { charset: doc.characterSet,
                  referrerURI: doc.documentURIObject,
                  private: true });
   },
 
   // Open linked-to URL in a new tab.
   openLinkInTab: function() {
     var doc = this.target.ownerDocument;
-    urlSecurityCheck(this.linkURL, doc.nodePrincipal);
+    urlSecurityCheck(this.linkURL, this._unremotePrincipal(doc.nodePrincipal));
     openLinkIn(this.linkURL, "tab",
                { charset: doc.characterSet,
                  referrerURI: doc.documentURIObject });
   },
 
   // open URL in current tab
   openLinkInCurrent: function() {
     var doc = this.target.ownerDocument;
-    urlSecurityCheck(this.linkURL, doc.nodePrincipal);
+    urlSecurityCheck(this.linkURL, this._unremotePrincipal(doc.nodePrincipal));
     openLinkIn(this.linkURL, "current",
                { charset: doc.characterSet,
                  referrerURI: doc.documentURIObject });
   },
 
   // Open frame in a new tab.
   openFrameInTab: function() {
     var doc = this.target.ownerDocument;
@@ -834,17 +864,18 @@ nsContextMenu.prototype = {
                  referrerURI: referrer ? makeURI(referrer) : null });
   },
 
   // Open clicked-in frame in the same window.
   showOnlyThisFrame: function() {
     var doc = this.target.ownerDocument;
     var frameURL = doc.location.href;
 
-    urlSecurityCheck(frameURL, this.browser.contentPrincipal,
+    urlSecurityCheck(frameURL,
+                     this._unremotePrincipal(this.browser.contentPrincipal),
                      Ci.nsIScriptSecurityManager.DISALLOW_SCRIPT);
     var referrer = doc.referrer;
     openUILinkIn(frameURL, "current", { disallowInheritPrincipal: true,
                                         referrerURI: referrer ? makeURI(referrer) : null });
   },
 
   reload: function(event) {
     if (this.onSocial) {
@@ -897,55 +928,57 @@ nsContextMenu.prototype = {
 
   viewImageInfo: function() {
     BrowserPageInfo(this.target.ownerDocument.defaultView.top.document,
                     "mediaTab", this.target);
   },
 
   viewImageDesc: function(e) {
     var doc = this.target.ownerDocument;
-    urlSecurityCheck(this.imageDescURL, this.browser.contentPrincipal,
+    urlSecurityCheck(this.imageDescURL,
+                     this._unremotePrincipal(this.browser.contentPrincipal),
                      Ci.nsIScriptSecurityManager.DISALLOW_SCRIPT);
     openUILink(this.imageDescURL, e, { disallowInheritPrincipal: true,
                              referrerURI: doc.documentURIObject });
   },
 
   viewFrameInfo: function() {
     BrowserPageInfo(this.target.ownerDocument);
   },
 
   reloadImage: function(e) {
     urlSecurityCheck(this.mediaURL,
-                     this.browser.contentPrincipal,
+                     this._unremotePrincipal(this.browser.contentPrincipal),
                      Ci.nsIScriptSecurityManager.DISALLOW_SCRIPT);
 
     if (this.target instanceof Ci.nsIImageLoadingContent)
       this.target.forceReload();
   },
 
   // Change current window to the URL of the image, video, or audio.
   viewMedia: function(e) {
     var viewURL;
 
     if (this.onCanvas)
       viewURL = this.target.toDataURL();
     else {
       viewURL = this.mediaURL;
       urlSecurityCheck(viewURL,
-                       this.browser.contentPrincipal,
+                       this._unremotePrincipal(this.browser.contentPrincipal),
                        Ci.nsIScriptSecurityManager.DISALLOW_SCRIPT);
     }
 
     var doc = this.target.ownerDocument;
     openUILink(viewURL, e, { disallowInheritPrincipal: true,
                              referrerURI: doc.documentURIObject });
   },
 
   saveVideoFrameAsImage: function () {
-    urlSecurityCheck(this.mediaURL, this.browser.contentPrincipal,
+    urlSecurityCheck(this.mediaURL,
+                     this._unremotePrincipal(this.browser.contentPrincipal),
                      Ci.nsIScriptSecurityManager.DISALLOW_SCRIPT);
     let name = "";
     try {
       let uri = makeURI(this.mediaURL);
       let url = uri.QueryInterface(Ci.nsIURL);
       if (url.fileBaseName)
         name = decodeURI(url.fileBaseName) + ".jpg";
     } catch (e) { }
@@ -968,17 +1001,17 @@ nsContextMenu.prototype = {
 
   leaveDOMFullScreen: function() {
     document.mozCancelFullScreen();
   },
 
   // Change current window to the URL of the background image.
   viewBGImage: function(e) {
     urlSecurityCheck(this.bgImageURL,
-                     this.browser.contentPrincipal,
+                     this._unremotePrincipal(this.browser.contentPrincipal),
                      Ci.nsIScriptSecurityManager.DISALLOW_SCRIPT);
     var doc = this.target.ownerDocument;
     openUILink(this.bgImageURL, e, { disallowInheritPrincipal: true,
                                      referrerURI: doc.documentURIObject });
   },
 
   disableSetDesktopBackground: function() {
     // Disable the Set as Desktop Background menu item if we're still trying
@@ -1002,18 +1035,19 @@ nsContextMenu.prototype = {
   },
 
   setDesktopBackground: function() {
     // Paranoia: check disableSetDesktopBackground again, in case the
     // image changed since the context menu was initiated.
     if (this.disableSetDesktopBackground())
       return;
 
+    var doc = this.target.ownerDocument;
     urlSecurityCheck(this.target.currentURI.spec,
-                     this.target.ownerDocument.nodePrincipal);
+                     this._unremotePrincipal(doc.nodePrincipal));
 
     // Confirm since it's annoying if you hit this accidentally.
     const kDesktopBackgroundURL = 
                   "chrome://browser/content/setDesktopBackground.xul";
 #ifdef XP_MACOSX
     // On Mac, the Set Desktop Background window is not modal.
     // Don't open more than one Set Desktop Background window.
     var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
@@ -1180,17 +1214,17 @@ nsContextMenu.prototype = {
   saveLink: function() {
     var doc =  this.target.ownerDocument;
     var linkText;
     // If selected text is found to match valid URL pattern.
     if (this.onPlainTextLink)
       linkText = document.commandDispatcher.focusedWindow.getSelection().toString().trim();
     else
       linkText = this.linkText();
-    urlSecurityCheck(this.linkURL, doc.nodePrincipal);
+    urlSecurityCheck(this.linkURL, this._unremotePrincipal(doc.nodePrincipal));
 
     this.saveHelper(this.linkURL, linkText, null, true, doc);
   },
 
   // Backwards-compatibility wrapper
   saveImage : function() {
     if (this.onCanvas || this.onImage)
         this.saveMedia();
@@ -1200,22 +1234,24 @@ nsContextMenu.prototype = {
   saveMedia: function() {
     var doc =  this.target.ownerDocument;
     if (this.onCanvas) {
       // Bypass cache, since it's a data: URL.
       saveImageURL(this.target.toDataURL(), "canvas.png", "SaveImageTitle",
                    true, false, doc.documentURIObject, doc);
     }
     else if (this.onImage) {
-      urlSecurityCheck(this.mediaURL, doc.nodePrincipal);
+      urlSecurityCheck(this.mediaURL,
+                       this._unremotePrincipal(doc.nodePrincipal));
       saveImageURL(this.mediaURL, null, "SaveImageTitle", false,
                    false, doc.documentURIObject, doc);
     }
     else if (this.onVideo || this.onAudio) {
-      urlSecurityCheck(this.mediaURL, doc.nodePrincipal);
+      urlSecurityCheck(this.mediaURL,
+                       this._unremotePrincipal(doc.nodePrincipal));
       var dialogTitle = this.onVideo ? "SaveVideoTitle" : "SaveAudioTitle";
       this.saveHelper(this.mediaURL, null, dialogTitle, false, doc);
     }
   },
 
   // Backwards-compatibility wrapper
   sendImage : function() {
     if (this.onCanvas || this.onImage)
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -2640,16 +2640,17 @@
             this._updateBrowserRemoteness(this.mCurrentBrowser, this._shouldBrowserBeRemote(aURI));
             try {
 #endif
             return this.mCurrentBrowser.loadURI(aURI, aReferrerURI, aCharset);
 #ifdef MAKE_E10S_WORK
             } catch (e) {
               let url = this.mCurrentBrowser.currentURI.spec;
               this._updateBrowserRemoteness(this.mCurrentBrowser, this._shouldBrowserBeRemote(url));
+              throw e;
             }
 #endif
           ]]>
         </body>
       </method>
 
       <!-- throws exception for unknown schemes -->
       <method name="loadURIWithFlags">
@@ -2664,16 +2665,17 @@
             this._updateBrowserRemoteness(this.mCurrentBrowser, this._shouldBrowserBeRemote(aURI));
             try {
 #endif
             return this.mCurrentBrowser.loadURIWithFlags(aURI, aFlags, aReferrerURI, aCharset, aPostData);
 #ifdef MAKE_E10S_WORK
             } catch (e) {
               let url = this.mCurrentBrowser.currentURI.spec;
               this._updateBrowserRemoteness(this.mCurrentBrowser, this._shouldBrowserBeRemote(url));
+              throw e;
             }
 #endif
           ]]>
         </body>
       </method>
 
       <method name="goHome">
         <body>
@@ -2903,30 +2905,34 @@
           switch (aMessage.name) {
             case "DOMTitleChanged":
               let tab = this._getTabForBrowser(browser);
               if (!tab)
                 return;
               let titleChanged = this.setTabTitle(tab);
               if (titleChanged && !tab.selected && !tab.hasAttribute("busy"))
                 tab.setAttribute("titlechanged", "true");
+              break;
+            case "contextmenu":
+              gContextMenuContentData = { event: aMessage.objects.event,
+                                          browser: browser };
+              let popup = browser.ownerDocument.getElementById("contentAreaContextMenu");
+              popup.openPopup(browser, "overlap",
+                              gContextMenuContentData.event.clientX,
+                              gContextMenuContentData.event.clientY,
+                              true, false, null);
+              break;
           }
         ]]></body>
       </method>
 
       <constructor>
         <![CDATA[
           let browserStack = document.getAnonymousElementByAttribute(this, "anonid", "browserStack");
           this.mCurrentBrowser = document.getAnonymousElementByAttribute(this, "anonid", "initialBrowser");
-          if (Services.prefs.getBoolPref("browser.tabs.remote")) {
-            browserStack.removeChild(this.mCurrentBrowser);
-            this.mCurrentBrowser.setAttribute("remote", true);
-            browserStack.appendChild(this.mCurrentBrowser);
-            this.tabContainer.firstChild.setAttribute("remote", "true");
-          }
 
           this.mCurrentTab = this.tabContainer.firstChild;
           document.addEventListener("keypress", this, false);
           window.addEventListener("sizemodechange", this, false);
 
           var uniqueId = "panel" + Date.now();
           this.mPanelContainer.childNodes[0].id = uniqueId;
           this.mCurrentTab.linkedPanel = uniqueId;
@@ -2952,18 +2958,20 @@
           this.mTabFilters[0] = filter;
           this.init();
 
           this.style.backgroundColor =
             Services.prefs.getBoolPref("browser.display.use_system_colors") ?
               "-moz-default-background-color" :
               Services.prefs.getCharPref("browser.display.background_color");
 
-          if (Services.prefs.getBoolPref("browser.tabs.remote"))
+          if (Services.prefs.getBoolPref("browser.tabs.remote")) {
             messageManager.addMessageListener("DOMTitleChanged", this);
+            messageManager.addMessageListener("contextmenu", this);
+          }
         ]]>
       </constructor>
 
       <method name="init">
         <body><![CDATA[
           if (!this._initialProgressListenerAdded) {
             this._initialProgressListenerAdded = true;
             try {
@@ -2988,18 +2996,20 @@
             this.mTabFilters[i].removeProgressListener(this.mTabListeners[i]);
             this.mTabFilters[i] = null;
             this.mTabListeners[i].destroy();
             this.mTabListeners[i] = null;
           }
           document.removeEventListener("keypress", this, false);
           window.removeEventListener("sizemodechange", this, false);
 
-          if (Services.prefs.getBoolPref("browser.tabs.remote"))
+          if (Services.prefs.getBoolPref("browser.tabs.remote")) {
             messageManager.removeMessageListener("DOMTitleChanged", this);
+            messageManager.removeMessageListener("contextmenu", this);
+          }
         ]]>
       </destructor>
 
       <!-- Deprecated stuff, implemented for backwards compatibility. -->
       <method name="enterTabbedMode">
         <body>
           Application.console.log("enterTabbedMode is an obsolete method and " +
                                   "will be removed in a future release.");
--- a/browser/base/content/test/newtab/head.js
+++ b/browser/base/content/test/newtab/head.js
@@ -460,19 +460,21 @@ function synthesizeNativeMouseMove(aElem
  * @param aOffsetY The top offset that is added to the position (optional).
  */
 function synthesizeNativeMouseEvent(aElement, aMsg, aOffsetX = 0, aOffsetY = 0) {
   let rect = aElement.getBoundingClientRect();
   let win = aElement.ownerDocument.defaultView;
   let x = aOffsetX + win.mozInnerScreenX + rect.left + rect.width / 2;
   let y = aOffsetY + win.mozInnerScreenY + rect.top + rect.height / 2;
 
-  win.QueryInterface(Ci.nsIInterfaceRequestor)
-     .getInterface(Ci.nsIDOMWindowUtils)
-     .sendNativeMouseEvent(x, y, aMsg, 0, null);
+  let utils = win.QueryInterface(Ci.nsIInterfaceRequestor)
+                 .getInterface(Ci.nsIDOMWindowUtils);
+
+  let scale = utils.screenPixelsPerCSSPixel;
+  utils.sendNativeMouseEvent(x * scale, y * scale, aMsg, 0, null);
 }
 
 /**
  * Sends a custom drag event to a given DOM element.
  * @param aEventType The drag event's type.
  * @param aTarget The DOM element that the event is dispatched to.
  * @param aData The event's drag data (optional).
  */
--- a/browser/components/sessionstore/src/SessionStore.jsm
+++ b/browser/components/sessionstore/src/SessionStore.jsm
@@ -3002,16 +3002,20 @@ let SessionStoreInternal = {
       }
     }
 
     if (!this._isWindowLoaded(aWindow)) {
       // from now on, the data will come from the actual window
       delete this._statesToRestore[aWindow.__SS_restoreID];
       delete aWindow.__SS_restoreID;
       delete this._windows[aWindow.__SSi]._restoring;
+
+      // It's important to set the window state to dirty so that
+      // we collect their data for the first time when saving state.
+      this._dirtyWindows[aWindow.__SSi] = true;
     }
 
     if (aTabs.length == 0) {
       // this is normally done in restoreHistory() but as we're returning early
       // here we need to take care of it.
       this._setWindowStateReady(aWindow);
       return;
     }
--- a/browser/components/sessionstore/test/Makefile.in
+++ b/browser/components/sessionstore/test/Makefile.in
@@ -117,16 +117,18 @@ MOCHITEST_BROWSER_FILES = \
 	browser_615394-SSWindowState_events.js \
 	browser_618151.js \
 	browser_623779.js \
 	browser_624727.js \
 	browser_625257.js \
 	browser_628270.js \
 	browser_635418.js \
 	browser_636279.js \
+	browser_637020.js \
+	browser_637020_slow.sjs \
 	browser_644409-scratchpads.js \
 	browser_645428.js \
 	browser_659591.js \
 	browser_662743.js \
 	browser_662743_sample.html \
 	browser_662812.js \
 	browser_665702-state_session.js \
 	browser_682507.js \
new file mode 100644
--- /dev/null
+++ b/browser/components/sessionstore/test/browser_637020.js
@@ -0,0 +1,65 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const TEST_URL = "http://mochi.test:8888/browser/browser/components/" +
+                 "sessionstore/test/browser_637020_slow.sjs";
+
+const TEST_STATE = {
+  windows: [{
+    tabs: [
+      { entries: [{ url: "about:mozilla" }] },
+      { entries: [{ url: "about:robots" }] }
+    ]
+  }, {
+    tabs: [
+      { entries: [{ url: TEST_URL }] },
+      { entries: [{ url: TEST_URL }] }
+    ]
+  }]
+};
+
+function test() {
+  TestRunner.run();
+}
+
+/**
+ * This test ensures that windows that have just been restored will be marked
+ * as dirty, otherwise _getCurrentState() might ignore them when collecting
+ * state for the first time and we'd just save them as empty objects.
+ *
+ * The dirty state acts as a cache to not collect data from all windows all the
+ * time, so at the beginning, each window must be dirty so that we collect
+ * their state at least once.
+ */
+
+function runTests() {
+  let win;
+
+  // Wait until the new window has been opened.
+  Services.obs.addObserver(function onOpened(subject) {
+    Services.obs.removeObserver(onOpened, "domwindowopened");
+    win = subject;
+    executeSoon(next);
+  }, "domwindowopened", false);
+
+  // Set the new browser state that will
+  // restore a window with two slowly loading tabs.
+  yield SessionStore.setBrowserState(JSON.stringify(TEST_STATE));
+
+  // The window has now been opened. Check the state that is returned,
+  // this should come from the cache while the window isn't restored, yet.
+  info("the window has been opened");
+  checkWindows();
+
+  // The history has now been restored and the tabs are loading. The data must
+  // now come from the window, if it's correctly been marked as dirty before.
+  yield whenDelayedStartupFinished(win, next);
+  info("the delayed startup has finished");
+  checkWindows();
+}
+
+function checkWindows() {
+  let state = JSON.parse(SessionStore.getBrowserState());
+  is(state.windows[0].tabs.length, 2, "first window has two tabs");
+  is(state.windows[1].tabs.length, 2, "second window has two tabs");
+}
new file mode 100644
--- /dev/null
+++ b/browser/components/sessionstore/test/browser_637020_slow.sjs
@@ -0,0 +1,21 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+const DELAY_MS = "2000";
+
+let timer;
+
+function handleRequest(req, resp) {
+  resp.processAsync();
+  resp.setHeader("Cache-Control", "no-cache", false);
+  resp.setHeader("Content-Type", "text/html;charset=utf-8", false);
+
+  timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+  timer.init(() => {
+    resp.write("hi");
+    resp.finish();
+  }, DELAY_MS, Ci.nsITimer.TYPE_ONE_SHOT);
+}
--- a/browser/metro/base/content/appbar.js
+++ b/browser/metro/base/content/appbar.js
@@ -65,18 +65,18 @@ var Appbar = {
    * updated.
    */
   update: function update() {
     this._updatePinButton();
     this._updateStarButton();
   },
 
   onDownloadButton: function() {
-    // TODO: Bug 883962: Toggle the downloads infobar when the
-    // download button is clicked
+    let notificationBox = Browser.getNotificationBox();
+    notificationBox.notificationsHidden = !notificationBox.notificationsHidden;
     ContextUI.dismiss();
   },
 
   onPinButton: function() {
     if (this.pinButton.checked) {
       Browser.pinSite();
     } else {
       Browser.unpinSite();
--- a/browser/metro/base/content/browser.xul
+++ b/browser/metro/base/content/browser.xul
@@ -853,20 +853,11 @@
       </vbox>
     </box>
 
     <box id="autofill-container" class="menu-container" hidden="true">
       <vbox id="autofill-popup" class="menu-popup">
         <richlistbox id="menupopup-commands" onclick="if (event.target != this) AutofillMenuUI.selectByIndex(this.selectedIndex);" flex="1"/>
       </vbox>
     </box>
-
-    <!-- alerts for content -->
-    <hbox id="alerts-container" hidden="true" align="start" bottom="0" onclick="AlertsHelper.click(event);">
-      <image id="alerts-image"/>
-      <vbox flex="1">
-        <label id="alerts-title" value=""/>
-        <description id="alerts-text" flex="1"/>
-      </vbox>
-    </hbox>
   </stack>
 
 </window>
--- a/browser/metro/base/content/downloads.js
+++ b/browser/metro/base/content/downloads.js
@@ -1,14 +1,15 @@
 // -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 const URI_GENERIC_ICON_DOWNLOAD = "chrome://browser/skin/images/alert-downloads-30.png";
+const TOAST_URI_GENERIC_ICON_DOWNLOAD = "ms-appx:///metro/chrome/chrome/skin/images/alert-downloads-30.png"
 
 var Downloads = {
   /**
    * _downloadCount keeps track of the number of downloads that a single
    * notification bar groups together. A download is grouped with other
    * downloads if it starts before other downloads have completed.
    */
   _downloadCount: 0,
@@ -149,39 +150,31 @@ var Downloads = {
   showPage: function dh_showPage(aDownload) {
     let id = aDownload.getAttribute("downloadId");
     let download = this.manager.getDownload(id);
     let uri = this._getReferrerOrSource(download);
     if (uri)
       BrowserUI.newTab(uri, Browser.selectedTab);
   },
 
-  showAlert: function dh_showAlert(aName, aMessage, aTitle, aIcon) {
+  showAlert: function dh_showAlert(aName, aMessage, aTitle, aIcon, aObserver) {
     var notifier = Cc["@mozilla.org/alerts-service;1"]
                      .getService(Ci.nsIAlertsService);
 
-    // Callback for tapping on the alert popup
-    let observer = {
-      observe: function (aSubject, aTopic, aData) {
-        if (aTopic == "alertclickcallback") {
-          // TODO: Bug 783232 turns this alert into a native toast. 
-        }
-      }
-    };
-
     if (!aTitle)
       aTitle = Strings.browser.GetStringFromName("alertDownloads");
 
     if (!aIcon)
-      aIcon = URI_GENERIC_ICON_DOWNLOAD;
+      aIcon = TOAST_URI_GENERIC_ICON_DOWNLOAD;
 
-    notifier.showAlertNotification(aIcon, aTitle, aMessage, true, "", observer, aName);
+    notifier.showAlertNotification(aIcon, aTitle, aMessage, true, "", aObserver, aName);
   },
 
   showNotification: function dh_showNotification(title, msg, buttons, priority) {
+    this._notificationBox.notificationsHidden = false;
     return this._notificationBox.appendNotification(msg,
                                               title,
                                               URI_GENERIC_ICON_DOWNLOAD,
                                               priority,
                                               buttons);
   },
 
   _showDownloadFailedNotification: function (aDownload) {
@@ -252,16 +245,63 @@ var Downloads = {
           Downloads._downloadProgressIndicator.reset();
         }
       });
     }
     this.showNotification("download-complete", message, buttons,
       this._notificationBox.PRIORITY_WARNING_MEDIUM);
   },
 
+  _showDownloadCompleteToast: function (aDownload) {
+    let name = "DownloadComplete";
+    let msg = "";
+    let title = "";
+    let observer = null;
+    if (this._downloadCount > 1) {
+      title = PluralForm.get(this._downloadCount,
+                             Strings.browser.GetStringFromName("alertMultipleDownloadsComplete"))
+                             .replace("#1", this._downloadCount)
+      msg = PluralForm.get(2, Strings.browser.GetStringFromName("downloadShowInFiles"));
+
+      observer = {
+        observe: function (aSubject, aTopic, aData) {
+          switch (aTopic) {
+            case "alertclickcallback":
+              let fileURI = aDownload.target;
+              let file = Downloads._getLocalFile(fileURI);
+              file.reveal();
+
+              let downloadCompleteNotification =
+                Downloads._notificationBox.getNotificationWithValue("download-complete");
+              Downloads._notificationBox.removeNotification(downloadCompleteNotification);
+              break;
+          }
+        }
+      }
+    } else {
+      title = Strings.browser.formatStringFromName("alertDownloadsDone",
+        [aDownload.displayName], 1);
+      msg = Strings.browser.GetStringFromName("downloadRunNow");
+      observer = {
+        observe: function (aSubject, aTopic, aData) {
+          switch (aTopic) {
+            case "alertclickcallback":
+              Downloads.openDownload(aDownload);
+
+              let downloadCompleteNotification =
+                Downloads._notificationBox.getNotificationWithValue("download-complete");
+              Downloads._notificationBox.removeNotification(downloadCompleteNotification);
+              break;
+          }
+        }
+      }
+    }
+    this.showAlert(name, msg, title, null, observer);
+  },
+
   _updateCircularProgressMeter: function dv_updateCircularProgressMeter() {
     if (!this._progressNotificationInfo) {
       return;
     }
 
     let totPercent = 0;
     for (let info of this._progressNotificationInfo) {
       // info[0]          => download guid
@@ -386,16 +426,17 @@ var Downloads = {
         let runAfterDownload = this._runDownloadBooleanMap.get(download.targetFile.path);
         if (runAfterDownload) {
           this.openDownload(download);
         }
 
         this._runDownloadBooleanMap.delete(download.targetFile.path);
         if (this._downloadsInProgress == 0) {
           if (this._downloadCount > 1 || !runAfterDownload) {
+            this._showDownloadCompleteToast(download);
             this._showDownloadCompleteNotification(download);
           }
           this._progressNotificationInfo.clear();
           this._downloadCount = 0;
           this._notificationBox.removeNotification(this._progressNotification);
           this._progressNotification = null;
         }
         break;
--- a/browser/metro/base/content/helperui/AlertsHelper.js
+++ b/browser/metro/base/content/helperui/AlertsHelper.js
@@ -1,82 +1,25 @@
 /* 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/. */
 
 var AlertsHelper = {
-  _timeoutID: -1,
   _listener: null,
   _cookie: "",
-  _clickable: false,
-  get container() {
-    delete this.container;
-    let container = document.getElementById("alerts-container");
-
-    let self = this;
-    container.addEventListener("transitionend", function() {
-      self.alertTransitionOver();
-    }, true);
-
-    return this.container = container;
-  },
 
   showAlertNotification: function ah_show(aImageURL, aTitle, aText, aTextClickable, aCookie, aListener) {
-    this._clickable = aTextClickable || false;
-    this._listener = aListener || null;
-    this._cookie = aCookie || "";
-
-    // Reset the container settings from the last time so layout can happen naturally
-    let container = this.container;
-    container.removeAttribute("width");
-    let alertText = document.getElementById("alerts-text");
-    alertText.style.whiteSpace = "";
-
-    document.getElementById("alerts-image").setAttribute("src", aImageURL);
-    document.getElementById("alerts-title").value = aTitle;
-    alertText.textContent = aText;
+    Services.obs.addObserver(this, "metro_native_toast_clicked", false);
+    this._listener = aListener;
+    this._cookie = aCookie;
 
-    container.hidden = false;
-    let bcr = container.getBoundingClientRect();
-    if (bcr.width > window.innerWidth - 50) {
-      // If the window isn't wide enough, we need to re-layout
-      container.setAttribute("width", window.innerWidth - 50); // force a max width
-      alertText.style.whiteSpace = "pre-wrap"; // wrap text as needed
-      bcr = container.getBoundingClientRect(); // recalculate the bcr
-    }
-    container.setAttribute("width", bcr.width); // redundant but cheap
-    container.setAttribute("height", bcr.height);
-
-    container.classList.add("showing");
-
-    let timeout = Services.prefs.getIntPref("alerts.totalOpenTime");
-    let self = this;
-    if (this._timeoutID)
-      clearTimeout(this._timeoutID);
-    this._timeoutID = setTimeout(function() { self._timeoutAlert(); }, timeout);
+    MetroUtils.showNativeToast(aTitle, aText, aImageURL);
   },
 
-  _timeoutAlert: function ah__timeoutAlert() {
-    this._timeoutID = -1;
-
-    this.container.classList.remove("showing");
-    if (this._listener)
-      this._listener.observe(null, "alertfinished", this._cookie);
-  },
-
-  alertTransitionOver: function ah_alertTransitionOver() {
-    let container = this.container;
-    if (!container.classList.contains("showing")) {
-      container.height = 0;
-      container.hidden = true;
-    }
-  },
-
-  click: function ah_click(aEvent) {
-    if (this._clickable && this._listener)
-      this._listener.observe(null, "alertclickcallback", this._cookie);
-
-    if (this._timeoutID != -1) {
-      clearTimeout(this._timeoutID);
-      this._timeoutAlert();
+  observe: function(aSubject, aTopic, aData) {
+    switch (aTopic) {
+      case "metro_native_toast_clicked":
+        Services.obs.removeObserver(this, "metro_native_toast_clicked");
+        this._listener.observe(null, "alertclickcallback", this._cookie);
+        break;
     }
   }
 };
--- a/browser/metro/components/AlertsService.js
+++ b/browser/metro/components/AlertsService.js
@@ -15,13 +15,34 @@ Cu.import("resource://gre/modules/Servic
 function AlertsService() { }
 
 AlertsService.prototype = {
   classID: Components.ID("{fe33c107-82a4-41d6-8c64-5353267e04c9}"),
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIAlertsService]),
 
   showAlertNotification: function(aImageUrl, aTitle, aText, aTextClickable, aCookie, aAlertListener, aName) {
     let browser = Services.wm.getMostRecentWindow("navigator:browser");
-    browser.AlertsHelper.showAlertNotification(aImageUrl, aTitle, aText, aTextClickable, aCookie, aAlertListener);
+    try {
+      browser.AlertsHelper.showAlertNotification(aImageUrl, aTitle, aText, aTextClickable, aCookie, aAlertListener);
+    } catch (ex) {
+      let chromeWin = this._getChromeWindow(browser).wrappedJSObject;
+      let notificationBox = chromeWin.Browser.getNotificationBox();
+      notificationBox.appendNotification(aTitle,
+                                         aText,
+                                         aImageUrl,
+                                         notificationBox.PRIORITY_WARNING_MEDIUM,
+                                         null);
+    }
+  },
+
+  _getChromeWindow: function (aWindow) {
+      let chromeWin = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+                            .getInterface(Ci.nsIWebNavigation)
+                            .QueryInterface(Ci.nsIDocShellTreeItem)
+                            .rootTreeItem
+                            .QueryInterface(Ci.nsIInterfaceRequestor)
+                            .getInterface(Ci.nsIDOMWindow)
+                            .QueryInterface(Ci.nsIDOMChromeWindow);
+     return chromeWin;
   }
 };
 
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([AlertsService]);
--- a/browser/metro/components/HelperAppDialog.js
+++ b/browser/metro/components/HelperAppDialog.js
@@ -96,16 +96,17 @@ HelperAppLauncherDialog.prototype = {
     let notificationBox = chromeWin.Browser.getNotificationBox();
     downloadSize = this._getDownloadSize(aLauncher.contentLength);
 
     let msg = browserBundle.GetStringFromName("alertDownloadSave")
       .replace("#1", aLauncher.suggestedFileName)
       .replace("#2", downloadSize)
       .replace("#3", aLauncher.source.host);
 
+    notificationBox.notificationsHidden = false;
     let newBar = notificationBox.appendNotification(msg,
                                                     "save-download",
                                                     URI_GENERIC_ICON_DOWNLOAD,
                                                     notificationBox.PRIORITY_WARNING_HIGH,
                                                     buttons);
   },
 
   promptForSaveToFile: function hald_promptForSaveToFile(aLauncher, aContext, aDefaultFile, aSuggestedFileExt, aForcePrompt) {
--- a/browser/metro/locales/en-US/chrome/browser.properties
+++ b/browser/metro/locales/en-US/chrome/browser.properties
@@ -56,16 +56,17 @@ browserForSaveLocation=Save Location
 browserForOpenLocation=Open Location
 
 # Download Manager
 downloadsUnknownSize=Unknown size
 downloadRun=Run
 downloadSave=Save
 downloadCancel=Cancel
 downloadTryAgain=Try Again
+downloadRunNow=Run it now
 # LOCALIZATION NOTE (downloadShowInFiles): 'Files' refers to the Windows 8 file explorer
 downloadShowInFiles=Show in Files
 
 # Alerts
 alertLinkBookmarked=Bookmark added
 alertDownloads=Downloads
 alertDownloadsStart=Downloading: %S
 alertDownloadsDone=%S has finished downloading
--- a/browser/metro/theme/browser.css
+++ b/browser/metro/theme/browser.css
@@ -1240,42 +1240,9 @@ setting[type="radio"] > vbox {
 #clearprivacythrobber .progressBall {
   margin: 2px;
   width: 22px;
   height: 22px;
 }
 
 #clear-notification-done {
   font-weight: bold;
-}
-
-/* Alert Popup ============================================================= */
-
-#alerts-container {
-  color: white;
-  background-color: #5e6166;
-  border: @border_width_small@ solid #767973;
-  border-radius: @border_radius_normal@;
-  box-shadow: black 0 @border_radius_tiny@ @border_radius_tiny@;
-  padding: @padding_normal@; /* core spacing on top/bottom */
-  margin-bottom: @margin_large@;
-  transition-property: opacity;
-  transition-duration: 0.5s;
-  opacity: 0;
-}
-
-#alerts-container.showing {
-  opacity: 1;
-}
-
-#alerts-title {
-  font-size: @font_small@ !important;
-}
-
-#alerts-text {
-  font-size: @font_xsmall@ !important;
-  white-space: pre;
-}
-
-#alerts-container {
-  -moz-margin-end: @margin_large@;
-}
-
+}
\ No newline at end of file
--- a/browser/themes/linux/devtools/debugger.css
+++ b/browser/themes/linux/devtools/debugger.css
@@ -45,16 +45,20 @@
   height: 24px;
   border: 0;
 }
 
 .side-menu-widget-item-checkbox[checked] > .checkbox-check {
   background-position: 0 0;
 }
 
+.side-menu-widget-item-checkbox:not([checked]) ~ .side-menu-widget-item-contents {
+  color: #888;
+}
+
 .side-menu-widget-item-checkbox:not([checked]) ~ .side-menu-widget-item-contents > .dbg-breakpoint {
   display: none;
 }
 
 /* Black box message */
 
 #black-boxed-message {
   /* Prevent the container deck from aquiring the height from this message. */
--- a/browser/themes/osx/devtools/debugger.css
+++ b/browser/themes/osx/devtools/debugger.css
@@ -47,16 +47,20 @@
   height: 24px;
   border: 0;
 }
 
 .side-menu-widget-item-checkbox[checked] > .checkbox-check {
   background-position: 0 0;
 }
 
+.side-menu-widget-item-checkbox:not([checked]) ~ .side-menu-widget-item-contents {
+  color: #888;
+}
+
 .side-menu-widget-item-checkbox:not([checked]) ~ .side-menu-widget-item-contents > .dbg-breakpoint {
   display: none;
 }
 
 /* Black box message */
 
 #black-boxed-message {
   /* Prevent the container deck from aquiring the height from this message. */
--- a/browser/themes/windows/devtools/debugger.css
+++ b/browser/themes/windows/devtools/debugger.css
@@ -45,16 +45,20 @@
   height: 24px;
   border: 0;
 }
 
 .side-menu-widget-item-checkbox[checked] > .checkbox-check {
   background-position: 0 0;
 }
 
+.side-menu-widget-item-checkbox:not([checked]) ~ .side-menu-widget-item-contents {
+  color: #888;
+}
+
 .side-menu-widget-item-checkbox:not([checked]) ~ .side-menu-widget-item-contents > .dbg-breakpoint {
   display: none;
 }
 
 /* Black box message */
 
 #black-boxed-message {
   /* Prevent the container deck from aquiring the height from this message. */
--- a/build/ConfigStatus.py
+++ b/build/ConfigStatus.py
@@ -14,18 +14,17 @@ import sys
 
 from optparse import OptionParser
 
 from mach.logging import LoggingManager
 from mozbuild.backend.configenvironment import ConfigEnvironment
 from mozbuild.backend.recursivemake import RecursiveMakeBackend
 from mozbuild.frontend.emitter import TreeMetadataEmitter
 from mozbuild.frontend.reader import BuildReader
-
-from Preprocessor import Preprocessor
+from mozbuild.mozinfo import write_mozinfo
 
 
 log_manager = LoggingManager()
 
 
 def config_status(topobjdir = '.', topsrcdir = '.',
                   defines = [], non_global_defines = [], substs = [],
                   files = [], headers = []):
@@ -82,16 +81,21 @@ def config_status(topobjdir = '.', topsr
 
     # Without -n, the current directory is meant to be the top object directory
     if not options.not_topobjdir:
         topobjdir = os.path.abspath('.')
 
     env = ConfigEnvironment(topsrcdir, topobjdir, defines=defines,
             non_global_defines=non_global_defines, substs=substs)
 
+    # mozinfo.json only needs written if configure changes and configure always
+    # passes this environment variable.
+    if 'WRITE_MOZINFO' in os.environ:
+        write_mozinfo(os.path.join(topobjdir, 'mozinfo.json'), env, os.environ)
+
     reader = BuildReader(env)
     emitter = TreeMetadataEmitter(env)
     backend = RecursiveMakeBackend(env)
     # This won't actually do anything because of the magic of generators.
     definitions = emitter.emit(reader.read_topsrcdir())
 
     if options.recheck:
         # Execute configure from the top object directory
--- a/build/automation.py.in
+++ b/build/automation.py.in
@@ -513,19 +513,28 @@ class Automation(object):
     # ASan specific environment stuff
     if self.IS_ASAN and (self.IS_LINUX or self.IS_MAC):
       try:
         totalMemory = int(os.popen("free").readlines()[1].split()[1])
 
         # Only 2 GB RAM or less available? Use custom ASan options to reduce
         # the amount of resources required to do the tests. Standard options 
         # will otherwise lead to OOM conditions on the current test slaves.
+        # 
+        # If we have more than 2 GB or RAM but still less than 4 GB, we need
+        # another set of options to prevent OOM in some memory-intensive
+        # tests.
         if totalMemory <= 1024 * 1024 * 2:
           self.log.info("INFO | automation.py | ASan running in low-memory configuration")
           env["ASAN_OPTIONS"] = "quarantine_size=50331648:redzone=64"
+        elif totalMemory <= 1024 * 1024 * 4:
+          self.log.info("INFO | automation.py | ASan running in mid-memory configuration")
+          env["ASAN_OPTIONS"] = "quarantine_size=100663296:redzone=64"
+        else:
+          self.log.info("INFO | automation.py | ASan running in default memory configuration")
       except OSError,err:
         self.log.info("Failed determine available memory, disabling ASan low-memory configuration: %s", err.strerror)
       except:
         self.log.info("Failed determine available memory, disabling ASan low-memory configuration")
 
     return env
 
   if IS_WIN32:
--- a/caps/src/nsScriptSecurityManager.cpp
+++ b/caps/src/nsScriptSecurityManager.cpp
@@ -427,44 +427,44 @@ JSBool
 nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction(JSContext *cx)
 {
     // Get the security manager
     nsScriptSecurityManager *ssm =
         nsScriptSecurityManager::GetScriptSecurityManager();
 
     NS_ASSERTION(ssm, "Failed to get security manager service");
     if (!ssm)
-        return JS_FALSE;
+        return false;
 
     nsresult rv;
     nsIPrincipal* subjectPrincipal = ssm->GetSubjectPrincipal(cx, &rv);
 
     NS_ASSERTION(NS_SUCCEEDED(rv), "CSP: Failed to get nsIPrincipal from js context");
     if (NS_FAILED(rv))
-        return JS_FALSE; // Not just absence of principal, but failure.
+        return false; // Not just absence of principal, but failure.
 
     if (!subjectPrincipal)
-        return JS_TRUE;
+        return true;
 
     nsCOMPtr<nsIContentSecurityPolicy> csp;
     rv = subjectPrincipal->GetCsp(getter_AddRefs(csp));
     NS_ASSERTION(NS_SUCCEEDED(rv), "CSP: Failed to get CSP from principal.");
 
     // don't do anything unless there's a CSP
     if (!csp)
-        return JS_TRUE;
+        return true;
 
     bool evalOK = true;
     bool reportViolation = false;
     rv = csp->GetAllowsEval(&reportViolation, &evalOK);
 
     if (NS_FAILED(rv))
     {
         NS_WARNING("CSP: failed to get allowsEval");
-        return JS_TRUE; // fail open to not break sites.
+        return true; // fail open to not break sites.
     }
 
     if (reportViolation) {
         nsAutoString fileName;
         unsigned lineNum = 0;
         NS_NAMED_LITERAL_STRING(scriptSample, "call to eval() or related function blocked by CSP");
 
         JSScript *script;
@@ -489,17 +489,17 @@ nsScriptSecurityManager::CheckObjectAcce
                                            JS::MutableHandle<JS::Value> vp)
 {
     // Get the security manager
     nsScriptSecurityManager *ssm =
         nsScriptSecurityManager::GetScriptSecurityManager();
 
     NS_WARN_IF_FALSE(ssm, "Failed to get security manager service");
     if (!ssm)
-        return JS_FALSE;
+        return false;
 
     // Get the object being accessed.  We protect these cases:
     // 1. The Function.prototype.caller property's value, which might lead
     //    an attacker up a call-stack to a function or another object from
     //    a different trust domain.
     // 2. A user-defined getter or setter function accessible on another
     //    trust domain's window or document object.
     // vp can be a primitive, in that case, we use obj as the target
@@ -510,19 +510,19 @@ nsScriptSecurityManager::CheckObjectAcce
     // Pass the parent object's class name, as we have no class-info for it.
     nsresult rv =
         ssm->CheckPropertyAccess(cx, target, js::GetObjectClass(obj)->name, id,
                                  (mode & JSACC_WRITE) ?
                                  (int32_t)nsIXPCSecurityManager::ACCESS_SET_PROPERTY :
                                  (int32_t)nsIXPCSecurityManager::ACCESS_GET_PROPERTY);
 
     if (NS_FAILED(rv))
-        return JS_FALSE; // Security check failed (XXX was an error reported?)
-
-    return JS_TRUE;
+        return false; // Security check failed (XXX was an error reported?)
+
+    return true;
 }
 
 NS_IMETHODIMP
 nsScriptSecurityManager::CheckPropertyAccess(JSContext* cx,
                                              JSObject* aJSObject,
                                              const char* aClassName,
                                              jsid aProperty,
                                              uint32_t aAction)
--- a/configure.in
+++ b/configure.in
@@ -9049,17 +9049,19 @@ HAVE_SYS_MOUNT_H
 AC_CONFIG_HEADER(
 netwerk/necko-config.h
 xpcom/xpcom-config.h
 xpcom/xpcom-private.h
 )
 
 AC_SUBST(STLPORT_LIBS)
 
+export WRITE_MOZINFO=1
 AC_OUTPUT([mozilla-config.h])
+unset WRITE_MOZINFO
 
 # Hack around an Apple bug that affects the egrep that comes with OS X 10.7.
 # "env ARCHPREFERENCE=i386,x86_64 arch egrep" first tries to use the 32-bit
 # Intel part of the egrep fat binary, even on 64-bit systems, and falls back on
 # the 64-bit part if it's not a fat binary, as can happen with MacPorts. We
 # (apparently) only need this hack when egrep's "pattern" is particularly long
 # (as in the following code) and the first egrep on our $PATH is Apple's.  See
 # bug 655339.
@@ -9196,34 +9198,16 @@ dnl so that regeneration via dependencie
      $GYP_WEBRTC_OPTIONS \
      --generator-output=${_objdir}/media/mtransport/third_party/nICEr \
      ${srcdir}/media/mtransport/third_party/nICEr/nicer.gyp
    if test "$?" != 0; then
       AC_MSG_ERROR([failed to generate nICEr Makefiles])
    fi
 fi
 
-# Generate a JSON config file for unittest harnesses etc to read
-# build configuration details from in a standardized way.
-OS_TARGET=${OS_TARGET} \
-TARGET_CPU=${TARGET_CPU} \
-MOZ_DEBUG=${MOZ_DEBUG} \
-MOZ_WIDGET_TOOLKIT=${MOZ_WIDGET_TOOLKIT} \
-UNIVERSAL_BINARY=${UNIVERSAL_BINARY} \
-MOZ_CRASHREPORTER=${MOZ_CRASHREPORTER} \
-MOZ_APP_NAME=${MOZ_APP_NAME} \
-TOPSRCDIR=${_topsrcdir} \
-MOZ_ASAN=${MOZ_ASAN} \
-  $PYTHON ${_topsrcdir}/config/writemozinfo.py ./mozinfo.json.tmp
-if cmp -s ./mozinfo.json.tmp ./mozinfo.json; then
-  rm ./mozinfo.json.tmp
-else
-  mv -f ./mozinfo.json.tmp ./mozinfo.json
-fi
-
 # Run jemalloc configure script
 
 if test -z "$MOZ_NATIVE_JEMALLOC" -a "$MOZ_MEMORY" && test -n "$MOZ_JEMALLOC3" -o -n "$MOZ_REPLACE_MALLOC"; then
   ac_configure_args="$_SUBDIR_CONFIG_ARGS --build=$build --host=$target --enable-stats --with-jemalloc-prefix=je_"
   if test -n "$MOZ_REPLACE_MALLOC"; then
     # When using replace_malloc, we always want memalign and valloc exported from jemalloc.
     ac_configure_args="$ac_configure_args ac_cv_func_memalign=yes"
     ac_configure_args="$ac_configure_args ac_cv_func_valloc=yes"
--- a/content/base/public/DirectionalityUtils.h
+++ b/content/base/public/DirectionalityUtils.h
@@ -90,18 +90,22 @@ void SetDirectionFromChangedTextNode(nsI
  * When a text node is appended to an element, find any ancestors with dir=auto
  * whose directionality will be determined by the text node
  */
 void SetDirectionFromNewTextNode(nsIContent* aTextNode);
 
 /**
  * When a text node is removed from a document, find any ancestors whose
  * directionality it determined and redetermine their directionality
+ *
+ * @param aTextNode the text node
+ * @param aNullParent whether the the parent is also being removed
+ *        (passed from UnbindFromTree)
  */
-void ResetDirectionSetByTextNode(nsTextNode* aTextNode);
+void ResetDirectionSetByTextNode(nsTextNode* aTextNode, bool aNullParent);
 
 /**
  * Set the directionality of an element according to the directionality of the
  * text in aValue
  */
 void SetDirectionalityFromValue(mozilla::dom::Element* aElement,
                                 const nsAString& aValue,
                                 bool aNotify);
--- a/content/base/public/Element.h
+++ b/content/base/public/Element.h
@@ -128,16 +128,18 @@ public:
     NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::ELEMENT_NODE,
                       "Bad NodeType in aNodeInfo");
     SetIsElement();
   }
 #endif // MOZILLA_INTERNAL_API
 
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ELEMENT_IID)
 
+  NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
+
   /**
    * Method to get the full state of this element.  See nsEventStates.h for
    * the possible bits that could be set here.
    */
   nsEventStates State() const {
     // mState is maintained by having whoever might have changed it
     // call UpdateState() or one of the other mState mutators.
     return mState;
--- a/content/base/public/FragmentOrElement.h
+++ b/content/base/public/FragmentOrElement.h
@@ -167,22 +167,16 @@ class FragmentOrElement : public nsICont
 public:
   FragmentOrElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~FragmentOrElement();
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
   NS_DECL_SIZEOF_EXCLUDING_THIS
 
-  /**
-   * Called during QueryInterface to give the binding manager a chance to
-   * get an interface for this element.
-   */
-  nsresult PostQueryInterface(REFNSIID aIID, void** aInstancePtr);
-
   // nsINode interface methods
   virtual uint32_t GetChildCount() const MOZ_OVERRIDE;
   virtual nsIContent *GetChildAt(uint32_t aIndex) const MOZ_OVERRIDE;
   virtual nsIContent * const * GetChildArray(uint32_t* aChildCount) const MOZ_OVERRIDE;
   virtual int32_t IndexOf(const nsINode* aPossibleChild) const MOZ_OVERRIDE;
   virtual nsresult InsertChildAt(nsIContent* aKid, uint32_t aIndex,
                                  bool aNotify) MOZ_OVERRIDE;
   virtual void RemoveChildAt(uint32_t aIndex, bool aNotify) MOZ_OVERRIDE;
@@ -397,21 +391,9 @@ protected:
 
 #define NS_ELEMENT_INTERFACE_TABLE_TO_MAP_SEGUE                               \
     if (NS_SUCCEEDED(rv))                                                     \
       return rv;                                                              \
                                                                               \
     rv = FragmentOrElement::QueryInterface(aIID, aInstancePtr);               \
     NS_INTERFACE_TABLE_TO_MAP_SEGUE
 
-#define NS_ELEMENT_INTERFACE_MAP_END                                          \
-    {                                                                         \
-      return PostQueryInterface(aIID, aInstancePtr);                          \
-    }                                                                         \
-                                                                              \
-    NS_ADDREF(foundInterface);                                                \
-                                                                              \
-    *aInstancePtr = foundInterface;                                           \
-                                                                              \
-    return NS_OK;                                                             \
-  }
-
 #endif /* FragmentOrElement_h___ */
--- a/content/base/public/nsCopySupport.h
+++ b/content/base/public/nsCopySupport.h
@@ -75,16 +75,19 @@ class nsCopySupport
      * point of the selection. If a cut or copy event is not cancelled, the
      * selection is copied to the clipboard and true is returned. Paste events
      * have no default behaviour but true will be returned. It is expected
      * that the caller will execute any needed default paste behaviour. Also,
      * note that this method only copies text to the clipboard, the caller is
      * responsible for removing the content during a cut operation if true is
      * returned.
      *
+     * aClipboardType specifies which clipboard to use, from nsIClipboard.
+     *
      * If the event is cancelled or an error occurs, false will be returned.
      */
     static bool FireClipboardEvent(int32_t aType,
-                                     nsIPresShell* aPresShell,
-                                     nsISelection* aSelection);
+                                   int32_t aClipboardType,
+                                   nsIPresShell* aPresShell,
+                                   nsISelection* aSelection);
 };
 
 #endif
--- a/content/base/src/DirectionalityUtils.cpp
+++ b/content/base/src/DirectionalityUtils.cpp
@@ -497,17 +497,17 @@ private:
   static PLDHashOperator ResetNodeDirection(nsPtrHashKey<Element>* aEntry, void* aData)
   {
     MOZ_ASSERT(aEntry->GetKey()->IsElement(), "Must be an Element");
     // run the downward propagation algorithm
     // and remove the text node from the map
     nsINode* oldTextNode = static_cast<Element*>(aData);
     Element* rootNode = aEntry->GetKey();
     nsINode* newTextNode = nullptr;
-    if (rootNode->HasDirAuto()) {
+    if (oldTextNode && rootNode->HasDirAuto()) {
       newTextNode = WalkDescendantsSetDirectionFromText(rootNode, true,
                                                         oldTextNode);
     }
     if (newTextNode) {
       nsTextNodeDirectionalityMap::AddEntryToMap(newTextNode, rootNode);
     } else {
       rootNode->ClearHasDirAutoSet();
       rootNode->UnsetProperty(nsGkAtoms::dirAutoSetBy);
@@ -524,16 +524,21 @@ private:
   }
 
 public:
   void UpdateAutoDirection(Directionality aDir)
   {
     mElements.EnumerateEntries(SetNodeDirection, &aDir);
   }
 
+  void ClearAutoDirection()
+  {
+    mElements.EnumerateEntries(ResetNodeDirection, nullptr);
+  }
+
   void ResetAutoDirection(nsINode* aTextNode)
   {
     mElements.EnumerateEntries(ResetNodeDirection, aTextNode);
   }
 
   void EnsureMapIsClear(nsINode* aTextNode)
   {
     DebugOnly<uint32_t> clearedEntries =
@@ -560,16 +565,23 @@ public:
 
   static void UpdateTextNodeDirection(nsINode* aTextNode, Directionality aDir)
   {
     MOZ_ASSERT(aTextNode->HasTextNodeDirectionalityMap(),
                "Map missing in UpdateTextNodeDirection");
     GetDirectionalityMap(aTextNode)->UpdateAutoDirection(aDir);
   }
 
+  static void ClearTextNodeDirection(nsINode* aTextNode)
+  {
+    MOZ_ASSERT(aTextNode->HasTextNodeDirectionalityMap(),
+               "Map missing in ResetTextNodeDirection");
+    GetDirectionalityMap(aTextNode)->ClearAutoDirection();
+  }
+
   static void ResetTextNodeDirection(nsINode* aTextNode)
   {
     MOZ_ASSERT(aTextNode->HasTextNodeDirectionalityMap(),
                "Map missing in ResetTextNodeDirection");
     GetDirectionalityMap(aTextNode)->ResetAutoDirection(aTextNode);
   }
 
   static void EnsureMapIsClearFor(nsINode* aTextNode)
@@ -866,26 +878,30 @@ SetDirectionFromNewTextNode(nsIContent* 
 
   Directionality dir = GetDirectionFromText(aTextNode->GetText());
   if (dir != eDir_NotSet) {
     SetAncestorDirectionIfAuto(aTextNode, dir);
   }
 }
 
 void
-ResetDirectionSetByTextNode(nsTextNode* aTextNode)
+ResetDirectionSetByTextNode(nsTextNode* aTextNode, bool aNullParent)
 {
   if (!NodeAffectsDirAutoAncestor(aTextNode)) {
     nsTextNodeDirectionalityMap::EnsureMapIsClearFor(aTextNode);
     return;
   }
 
   Directionality dir = GetDirectionFromText(aTextNode->GetText());
   if (dir != eDir_NotSet && aTextNode->HasTextNodeDirectionalityMap()) {
-    nsTextNodeDirectionalityMap::ResetTextNodeDirection(aTextNode);
+    if (aNullParent) {
+      nsTextNodeDirectionalityMap::ClearTextNodeDirection(aTextNode);
+    } else {
+      nsTextNodeDirectionalityMap::ResetTextNodeDirection(aTextNode);
+    }
   }
 }
 
 void
 SetDirectionalityFromValue(Element* aElement, const nsAString& value,
                            bool aNotify)
 {
   Directionality dir = GetDirectionFromText(PromiseFlatString(value).get(),
--- a/content/base/src/Element.cpp
+++ b/content/base/src/Element.cpp
@@ -122,21 +122,37 @@
 #include "mozilla/Telemetry.h"
 
 #include "mozilla/CORSMode.h"
 
 #include "nsStyledElement.h"
 #include "nsXBLService.h"
 #include "nsContentCID.h"
 #include "nsITextControlElement.h"
+#include "nsISupportsImpl.h"
 #include "mozilla/dom/DocumentFragment.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
+NS_IMETHODIMP
+Element::QueryInterface(REFNSIID aIID, void** aInstancePtr)
+{
+  NS_ASSERTION(aInstancePtr,
+               "QueryInterface requires a non-NULL destination!");
+  nsresult rv = FragmentOrElement::QueryInterface(aIID, aInstancePtr);
+  if (NS_SUCCEEDED(rv)) {
+    return NS_OK;
+  }
+
+  // Give the binding manager a chance to get an interface for this element.
+  return OwnerDoc()->BindingManager()->GetBindingImplementation(this, aIID,
+                                                                aInstancePtr);
+}
+
 nsEventStates
 Element::IntrinsicState() const
 {
   return IsEditable() ? NS_EVENT_STATE_MOZ_READWRITE :
                         NS_EVENT_STATE_MOZ_READONLY;
 }
 
 void
--- a/content/base/src/FragmentOrElement.cpp
+++ b/content/base/src/FragmentOrElement.cpp
@@ -101,17 +101,16 @@
 #include "nsTextNode.h"
 #include "mozilla/dom/NodeListBinding.h"
 #include "mozilla/dom/UndoManager.h"
 
 #ifdef MOZ_XUL
 #include "nsIXULDocument.h"
 #endif /* MOZ_XUL */
 
-#include "nsCycleCollectionParticipant.h"
 #include "nsCCUncollectableMarker.h"
 
 #include "mozAutoDocUpdate.h"
 
 #include "prprf.h"
 #include "nsDOMMutationObserver.h"
 #include "nsWrapperCacheInlines.h"
 #include "nsCycleCollector.h"
@@ -1745,23 +1744,16 @@ NS_INTERFACE_MAP_BEGIN(FragmentOrElement
   // same as nsINode (which nsIContent inherits).
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContent)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(FragmentOrElement)
 NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_LAST_RELEASE(FragmentOrElement,
                                                    nsNodeUtils::LastRelease(this))
 
-nsresult
-FragmentOrElement::PostQueryInterface(REFNSIID aIID, void** aInstancePtr)
-{
-  return OwnerDoc()->BindingManager()->GetBindingImplementation(this, aIID,
-                                                                aInstancePtr);
-}
-
 //----------------------------------------------------------------------
 
 nsresult
 FragmentOrElement::CopyInnerTo(FragmentOrElement* aDst)
 {
   uint32_t i, count = mAttrsAndChildren.AttrCount();
   for (i = 0; i < count; ++i) {
     const nsAttrName* name = mAttrsAndChildren.AttrNameAt(i);
--- a/content/base/src/nsContentAreaDragDrop.cpp
+++ b/content/base/src/nsContentAreaDragDrop.cpp
@@ -47,16 +47,19 @@
 #include "nsIWebBrowserPersist.h"
 #include "nsEscape.h"
 #include "nsContentUtils.h"
 #include "nsIMIMEService.h"
 #include "imgIContainer.h"
 #include "imgIRequest.h"
 #include "nsDOMDataTransfer.h"
 #include "mozilla/dom/Element.h"
+#include "mozilla/dom/HTMLAreaElement.h"
+
+using mozilla::dom::HTMLAreaElement;
 
 class MOZ_STACK_CLASS DragDataProducer
 {
 public:
   DragDataProducer(nsPIDOMWindow* aWindow,
                    nsIContent* aTarget,
                    nsIContent* aSelectionTargetNode,
                    bool aIsAltKeyPressed);
@@ -500,20 +503,21 @@ DragDataProducer::Produce(nsDOMDataTrans
     }
 
     {
       // set for linked images, and links
       nsCOMPtr<nsIContent> linkNode;
 
       if (area) {
         // use the alt text (or, if missing, the href) as the title
-        area->GetAttribute(NS_LITERAL_STRING("alt"), mTitleString);
+        HTMLAreaElement* areaElem = static_cast<HTMLAreaElement*>(area.get());
+        areaElem->GetAttribute(NS_LITERAL_STRING("alt"), mTitleString);
         if (mTitleString.IsEmpty()) {
           // this can be a relative link
-          area->GetAttribute(NS_LITERAL_STRING("href"), mTitleString);
+          areaElem->GetAttribute(NS_LITERAL_STRING("href"), mTitleString);
         }
 
         // we'll generate HTML like <a href="absurl">alt text</a>
         mIsAnchor = true;
 
         // gives an absolute link
         GetAnchorURL(draggedNode, mUrlString);
 
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -4955,17 +4955,17 @@ nsContentUtils::SetDataTransferInEvent(n
 
   nsCOMPtr<nsIDOMDataTransfer> initialDataTransfer;
   dragSession->GetDataTransfer(getter_AddRefs(initialDataTransfer));
   if (!initialDataTransfer) {
     // A dataTransfer won't exist when a drag was started by some other
     // means, for instance calling the drag service directly, or a drag
     // from another application. In either case, a new dataTransfer should
     // be created that reflects the data.
-    initialDataTransfer = new nsDOMDataTransfer(aDragEvent->message, true);
+    initialDataTransfer = new nsDOMDataTransfer(aDragEvent->message, true, -1);
 
     NS_ENSURE_TRUE(initialDataTransfer, NS_ERROR_OUT_OF_MEMORY);
 
     // now set it in the drag session so we don't need to create it again
     dragSession->SetDataTransfer(initialDataTransfer);
   }
 
   bool isCrossDomainSubFrameDrop = false;
--- a/content/base/src/nsCopySupport.cpp
+++ b/content/base/src/nsCopySupport.cpp
@@ -568,17 +568,17 @@ nsCopySupport::CanCopy(nsIDocument* aDoc
   NS_ENSURE_TRUE(sel, false);
 
   bool isCollapsed;
   sel->GetIsCollapsed(&isCollapsed);
   return !isCollapsed;
 }
 
 bool
-nsCopySupport::FireClipboardEvent(int32_t aType, nsIPresShell* aPresShell, nsISelection* aSelection)
+nsCopySupport::FireClipboardEvent(int32_t aType, int32_t aClipboardType, nsIPresShell* aPresShell, nsISelection* aSelection)
 {
   NS_ASSERTION(aType == NS_CUT || aType == NS_COPY || aType == NS_PASTE,
                "Invalid clipboard event type");
 
   nsCOMPtr<nsIPresShell> presShell = aPresShell;
   if (!presShell)
     return false;
 
@@ -628,17 +628,17 @@ nsCopySupport::FireClipboardEvent(int32_
   if (!nsContentUtils::IsSafeToRunScript())
     return false;
 
   // next, fire the cut, copy or paste event
   // XXXndeakin Bug 844941 - why was a preference added here without a running-in-chrome check?
   bool doDefault = true;
   nsRefPtr<nsDOMDataTransfer> clipboardData;
   if (Preferences::GetBool("dom.event.clipboardevents.enabled", true)) {
-    clipboardData = new nsDOMDataTransfer(aType, aType == NS_PASTE);
+    clipboardData = new nsDOMDataTransfer(aType, aType == NS_PASTE, aClipboardType);
 
     nsEventStatus status = nsEventStatus_eIgnore;
     nsClipboardEvent evt(true, aType);
     evt.clipboardData = clipboardData;
     nsEventDispatcher::Dispatch(content, presShell->GetPresContext(), &evt, nullptr,
                                 &status);
     // If the event was cancelled, don't do the clipboard operation
     doDefault = (status != nsEventStatus_eConsumeNoDefault);
@@ -670,34 +670,34 @@ nsCopySupport::FireClipboardEvent(int32_
   if (doDefault) {
     // get the data from the selection if any
     bool isCollapsed;
     sel->GetIsCollapsed(&isCollapsed);
     if (isCollapsed) {
       return false;
     }
     // call the copy code
-    rv = HTMLCopy(sel, doc, nsIClipboard::kGlobalClipboard);
+    rv = HTMLCopy(sel, doc, aClipboardType);
     if (NS_FAILED(rv)) {
       return false;
     }
   } else if (clipboardData) {
     // check to see if any data was put on the data transfer.
     clipboardData->GetMozItemCount(&count);
     if (count) {
       nsCOMPtr<nsIClipboard> clipboard(do_GetService("@mozilla.org/widget/clipboard;1"));
       NS_ENSURE_TRUE(clipboard, false);
 
       nsCOMPtr<nsITransferable> transferable =
         clipboardData->GetTransferable(0, doc->GetLoadContext());
 
       NS_ENSURE_TRUE(transferable, false);
 
       // put the transferable on the clipboard
-      rv = clipboard->SetData(transferable, nullptr, nsIClipboard::kGlobalClipboard);
+      rv = clipboard->SetData(transferable, nullptr, aClipboardType);
       if (NS_FAILED(rv)) {
         return false;
       }
     }
   }
 
   // Now that we have copied, update the clipboard commands. This should have
   // the effect of updating the enabled state of the paste menu item.
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -107,17 +107,16 @@
 #include "nsContentCreatorFunctions.h"
 
 #include "nsIScriptContext.h"
 #include "nsBindingManager.h"
 #include "nsIDOMHTMLDocument.h"
 #include "nsHTMLDocument.h"
 #include "nsIDOMHTMLFormElement.h"
 #include "nsIRequest.h"
-#include "nsILink.h"
 #include "nsHostObjectProtocolHandler.h"
 
 #include "nsCharsetAlias.h"
 #include "nsCharsetSource.h"
 #include "nsIParser.h"
 #include "nsIContentSink.h"
 
 #include "nsDateTimeFormatCID.h"
@@ -144,16 +143,17 @@
 #include "nsIDOMStyleSheetChangeEvent.h"
 #include "nsIDOMStyleSheetApplicableStateChangeEvent.h"
 #include "nsJSUtils.h"
 #include "nsFrameLoader.h"
 #include "nsEscape.h"
 #include "nsObjectLoadingContent.h"
 #include "nsHtml5TreeOpExecutor.h"
 #include "nsIDOMElementReplaceEvent.h"
+#include "mozilla/dom/HTMLLinkElement.h"
 #include "mozilla/dom/HTMLMediaElement.h"
 #ifdef MOZ_WEBRTC
 #include "IPeerConnection.h"
 #endif // MOZ_WEBRTC
 
 #include "mozAutoDocUpdate.h"
 #include "nsGlobalWindow.h"
 #include "mozilla/dom/EncodingUtils.h"
@@ -189,16 +189,17 @@
 #include "imgRequestProxy.h"
 #include "nsWrapperCacheInlines.h"
 #include "nsSandboxFlags.h"
 #include "nsIAppsService.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/DocumentFragment.h"
 #include "mozilla/dom/WebComponentsBinding.h"
 #include "mozilla/dom/HTMLBodyElement.h"
+#include "mozilla/dom/HTMLInputElement.h"
 #include "mozilla/dom/NodeFilterBinding.h"
 #include "mozilla/dom/UndoManager.h"
 #include "nsFrame.h"
 #include "nsDOMCaretPosition.h"
 #include "nsIDOMHTMLTextAreaElement.h"
 #include "nsViewportInfo.h"
 #include "nsDOMEvent.h"
 #include "nsIContentPermissionPrompt.h"
@@ -7585,49 +7586,49 @@ nsDocument::Sanitize()
 
   nsCOMPtr<nsIContent> item;
   nsAutoString value;
 
   uint32_t length = nodes->Length(true);
   for (uint32_t i = 0; i < length; ++i) {
     NS_ASSERTION(nodes->Item(i), "null item in node list!");
 
-    nsCOMPtr<nsIDOMHTMLInputElement> input = do_QueryInterface(nodes->Item(i));
+    nsRefPtr<HTMLInputElement> input = HTMLInputElement::FromContentOrNull(nodes->Item(i));
     if (!input)
       continue;
 
     bool resetValue = false;
 
     input->GetAttribute(NS_LITERAL_STRING("autocomplete"), value);
     if (value.LowerCaseEqualsLiteral("off")) {
       resetValue = true;
     } else {
       input->GetType(value);
       if (value.LowerCaseEqualsLiteral("password"))
         resetValue = true;
     }
 
     if (resetValue) {
-      nsCOMPtr<nsIFormControl> fc = do_QueryInterface(input);
-      fc->Reset();
+      input->Reset();
     }
   }
 
   // Now locate all _form_ elements that have autocomplete=off and reset them
   nodes = GetElementsByTagName(NS_LITERAL_STRING("form"));
 
   length = nodes->Length(true);
   for (uint32_t i = 0; i < length; ++i) {
     NS_ASSERTION(nodes->Item(i), "null item in nodelist");
 
     nsCOMPtr<nsIDOMHTMLFormElement> form = do_QueryInterface(nodes->Item(i));
     if (!form)
       continue;
 
-    form->GetAttribute(NS_LITERAL_STRING("autocomplete"), value);
+    nodes->Item(i)->AsElement()->GetAttr(kNameSpaceID_None,
+                                         nsGkAtoms::autocomplete, value);
     if (value.LowerCaseEqualsLiteral("off"))
       form->Reset();
   }
 }
 
 struct SubDocEnumArgs
 {
   nsIDocument::nsSubDocEnumFunc callback;
@@ -8061,25 +8062,22 @@ nsDocument::OnPageShow(bool aPersisted,
 
   EnumerateFreezableElements(NotifyActivityChanged, nullptr);
   EnumerateExternalResources(NotifyPageShow, &aPersisted);
 
   Element* root = GetRootElement();
   if (aPersisted && root) {
     // Send out notifications that our <link> elements are attached.
     nsRefPtr<nsContentList> links = NS_GetContentList(root,
-                                                      kNameSpaceID_Unknown,
+                                                      kNameSpaceID_XHTML,
                                                       NS_LITERAL_STRING("link"));
 
     uint32_t linkCount = links->Length(true);
     for (uint32_t i = 0; i < linkCount; ++i) {
-      nsCOMPtr<nsILink> link = do_QueryInterface(links->Item(i, false));
-      if (link) {
-        link->LinkAdded();
-      }
+      static_cast<HTMLLinkElement*>(links->Item(i, false))->LinkAdded();
     }
   }
 
   // See nsIDocument
   if (!aDispatchStartTarget) {
     // Set mIsShowing before firing events, in case those event handlers
     // move us around.
     mIsShowing = true;
@@ -8125,25 +8123,22 @@ void
 nsDocument::OnPageHide(bool aPersisted,
                        EventTarget* aDispatchStartTarget)
 {
   // Send out notifications that our <link> elements are detached,
   // but only if this is not a full unload.
   Element* root = GetRootElement();
   if (aPersisted && root) {
     nsRefPtr<nsContentList> links = NS_GetContentList(root,
-                                                      kNameSpaceID_Unknown,
+                                                      kNameSpaceID_XHTML,
                                                       NS_LITERAL_STRING("link"));
 
     uint32_t linkCount = links->Length(true);
     for (uint32_t i = 0; i < linkCount; ++i) {
-      nsCOMPtr<nsILink> link = do_QueryInterface(links->Item(i, false));
-      if (link) {
-        link->LinkRemoved();
-      }
+      static_cast<HTMLLinkElement*>(links->Item(i, false))->LinkRemoved();
     }
   }
 
   // See nsIDocument
   if (!aDispatchStartTarget) {
     // Set mIsShowing before firing events, in case those event handlers
     // move us around.
     mIsShowing = false;
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -1474,20 +1474,20 @@ nsObjectLoadingContent::UpdateObjectPara
               domobject = do_QueryInterface(parent);
               domapplet = do_QueryInterface(parent);
               nsCOMPtr<nsIDOMNode> temp;
               parent->GetParentNode(getter_AddRefs(temp));
               parent = temp;
             }
             if (domapplet || domobject) {
               if (domapplet) {
-                parent = domapplet;
+                parent = do_QueryInterface(domapplet);
               }
               else {
-                parent = domobject;
+                parent = do_QueryInterface(domobject);
               }
               nsCOMPtr<nsIDOMNode> mydomNode = do_QueryInterface(mydomElement);
               if (parent == mydomNode) {
                 hasCodebase = true;
                 domelement->GetAttribute(NS_LITERAL_STRING("value"),
                                          codebaseStr);
                 codebaseStr.Trim(" \n\r\t\b", true, true, false);
               }
--- a/content/base/src/nsTextNode.cpp
+++ b/content/base/src/nsTextNode.cpp
@@ -142,17 +142,17 @@ nsTextNode::BindToTree(nsIDocument* aDoc
 
   SetDirectionFromNewTextNode(this);
 
   return NS_OK;
 }
 
 void nsTextNode::UnbindFromTree(bool aDeep, bool aNullParent)
 {
-  ResetDirectionSetByTextNode(this);
+  ResetDirectionSetByTextNode(this, aNullParent);
 
   nsGenericDOMDataNode::UnbindFromTree(aDeep, aNullParent);
 }
 
 #ifdef DEBUG
 void
 nsTextNode::List(FILE* out, int32_t aIndent) const
 {
--- a/content/canvas/src/CanvasRenderingContext2D.cpp
+++ b/content/canvas/src/CanvasRenderingContext2D.cpp
@@ -750,16 +750,17 @@ CanvasRenderingContext2D::RedrawUser(con
 void CanvasRenderingContext2D::Demote()
 {
   if (!IsTargetValid() || mForceSoftware)
     return;
 
   RefPtr<SourceSurface> snapshot = mTarget->Snapshot();
   RefPtr<DrawTarget> oldTarget = mTarget;
   mTarget = nullptr;
+  mResetLayer = true;
   mForceSoftware = true;
 
   // Recreate target, now demoted to software only
   EnsureTarget();
   if (!IsTargetValid())
     return;
 
   // Put back the content from the old DrawTarget
@@ -3034,16 +3035,34 @@ CanvasRenderingContext2D::DrawImage(cons
                 mgfx::Rect(dx, dy, dw, dh),
                 mgfx::Rect(sx, sy, sw, sh),
                 DrawSurfaceOptions(filter),
                 DrawOptions(CurrentState().globalAlpha, UsedOperation()));
 
   RedrawUser(gfxRect(dx, dy, dw, dh));
 }
 
+#ifdef USE_SKIA_GPU
+static bool
+IsStandardCompositeOp(CompositionOp op)
+{
+    return (op == OP_SOURCE ||
+            op == OP_ATOP ||
+            op == OP_IN ||
+            op == OP_OUT ||
+            op == OP_OVER ||
+            op == OP_DEST_IN ||
+            op == OP_DEST_OUT ||
+            op == OP_DEST_OVER ||
+            op == OP_DEST_ATOP ||
+            op == OP_ADD ||
+            op == OP_XOR);
+}
+#endif
+
 void
 CanvasRenderingContext2D::SetGlobalCompositeOperation(const nsAString& op,
                                                       ErrorResult& error)
 {
   CompositionOp comp_op;
 
 #define CANVAS_OP_TO_GFX_OP(cvsop, op2d) \
   if (op.EqualsLiteral(cvsop))   \
@@ -3073,16 +3092,22 @@ CanvasRenderingContext2D::SetGlobalCompo
   else CANVAS_OP_TO_GFX_OP("exclusion", EXCLUSION)
   else CANVAS_OP_TO_GFX_OP("hue", HUE)
   else CANVAS_OP_TO_GFX_OP("saturation", SATURATION)
   else CANVAS_OP_TO_GFX_OP("color", COLOR)
   else CANVAS_OP_TO_GFX_OP("luminosity", LUMINOSITY)
   // XXX ERRMSG we need to report an error to developers here! (bug 329026)
   else return;
 
+#ifdef USE_SKIA_GPU
+  if (!IsStandardCompositeOp(comp_op)) {
+    Demote();
+  }
+#endif
+
 #undef CANVAS_OP_TO_GFX_OP
   CurrentState().op = comp_op;
 }
 
 void
 CanvasRenderingContext2D::GetGlobalCompositeOperation(nsAString& op,
                                                       ErrorResult& error)
 {
@@ -3117,16 +3142,22 @@ CanvasRenderingContext2D::GetGlobalCompo
   else CANVAS_OP_TO_GFX_OP("hue", HUE)
   else CANVAS_OP_TO_GFX_OP("saturation", SATURATION)
   else CANVAS_OP_TO_GFX_OP("color", COLOR)
   else CANVAS_OP_TO_GFX_OP("luminosity", LUMINOSITY)
   else {
     error.Throw(NS_ERROR_FAILURE);
   }
 
+#ifdef USE_SKIA_GPU
+  if (!IsStandardCompositeOp(comp_op)) {
+    Demote();
+  }
+#endif
+
 #undef CANVAS_OP_TO_GFX_OP
 }
 
 void
 CanvasRenderingContext2D::DrawWindow(nsIDOMWindow* window, double x,
                                      double y, double w, double h,
                                      const nsAString& bgColor,
                                      uint32_t flags, ErrorResult& error)
--- a/content/canvas/test/Makefile.in
+++ b/content/canvas/test/Makefile.in
@@ -84,19 +84,16 @@ MOCHITEST_FILES = \
 	test_bug866575.html \
 	test_drawImage_edge_cases.html \
 	test_drawImage_document_domain.html \
 	test_mozDashOffset.html \
 	file_drawImage_document_domain.html \
 	test_windingRuleUndefined.html \
 	$(NULL)
 
-ifneq ($(MOZ_WIDGET_TOOLKIT), android)
-ifneq ($(MOZ_WIDGET_TOOLKIT), gonk)
-
 # SkiaGL on Android/Gonk does not implement these composite ops yet
 
 MOCHITEST_FILES += \
 	test_2d.composite.canvas.color-burn.html \
 	test_2d.composite.canvas.color-dodge.html \
 	test_2d.composite.canvas.darken.html \
 	test_2d.composite.canvas.difference.html \
 	test_2d.composite.canvas.exclusion.html \
@@ -118,19 +115,16 @@ MOCHITEST_FILES += \
 	test_2d.composite.solid.luminosity.html \
 	test_2d.composite.solid.multiply.html \
 	test_2d.composite.solid.overlay.html \
 	test_2d.composite.solid.saturation.html \
 	test_2d.composite.solid.screen.html \
 	test_2d.composite.solid.soft-light.html \
 	$(NULL)
 
-endif
-endif
-
 ifneq (1_Linux,$(MOZ_SUITE)_$(OS_ARCH))
 # This test fails in Suite on Linux for some reason, disable it there
 MOCHITEST_FILES += test_2d.composite.uncovered.image.destination-atop.html
 endif
 
 # xor and lighter aren't well handled by cairo; they mostly work, but we don't want
 # to test that
 #	test_2d.composite.solid.xor.html \
--- a/content/events/src/nsDOMClipboardEvent.cpp
+++ b/content/events/src/nsDOMClipboardEvent.cpp
@@ -2,16 +2,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsDOMClipboardEvent.h"
 #include "nsContentUtils.h"
 #include "nsClientRect.h"
 #include "nsDOMDataTransfer.h"
+#include "nsIClipboard.h"
 
 nsDOMClipboardEvent::nsDOMClipboardEvent(mozilla::dom::EventTarget* aOwner,
                                          nsPresContext* aPresContext,
                                          nsClipboardEvent* aEvent)
   : nsDOMEvent(aOwner, aPresContext, aEvent ? aEvent :
                new nsClipboardEvent(false, 0))
 {
   if (aEvent) {
@@ -63,17 +64,17 @@ nsDOMClipboardEvent::Constructor(const m
 
   nsRefPtr<nsDOMDataTransfer> clipboardData;
   if (e->mEventIsInternal) {
     nsClipboardEvent* event = static_cast<nsClipboardEvent*>(e->mEvent);
     if (event) {
       // Always create a clipboardData for the copy event. If this is changed to
       // support other types of events, make sure that read/write privileges are
       // checked properly within nsDOMDataTransfer.
-      clipboardData = new nsDOMDataTransfer(NS_COPY, false);
+      clipboardData = new nsDOMDataTransfer(NS_COPY, false, -1);
       clipboardData->SetData(aParam.mDataType, aParam.mData);
     }
   }
 
   aRv = e->InitClipboardEvent(aType, aParam.mBubbles, aParam.mCancelable,
                               clipboardData);
   e->SetTrusted(trusted);
   return e.forget();
@@ -88,20 +89,20 @@ nsDOMClipboardEvent::GetClipboardData(ns
 
 nsIDOMDataTransfer*
 nsDOMClipboardEvent::GetClipboardData()
 {
   nsClipboardEvent* event = static_cast<nsClipboardEvent*>(mEvent);
 
   if (!event->clipboardData) {
     if (mEventIsInternal) {
-      event->clipboardData = new nsDOMDataTransfer(NS_COPY, false);
+      event->clipboardData = new nsDOMDataTransfer(NS_COPY, false, -1);
     } else {
       event->clipboardData =
-        new nsDOMDataTransfer(event->message, event->message == NS_PASTE);
+        new nsDOMDataTransfer(event->message, event->message == NS_PASTE, nsIClipboard::kGlobalClipboard);
     }
   }
 
   return event->clipboardData;
 }
 
 nsresult NS_NewDOMClipboardEvent(nsIDOMEvent** aInstancePtrResult,
                                  mozilla::dom::EventTarget* aOwner,
--- a/content/events/src/nsDOMDataTransfer.cpp
+++ b/content/events/src/nsDOMDataTransfer.cpp
@@ -58,25 +58,26 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DataTransfer)
 NS_INTERFACE_MAP_END
 
 // the size of the array
 const char nsDOMDataTransfer::sEffects[8][9] = {
   "none", "copy", "move", "copyMove", "link", "copyLink", "linkMove", "all"
 };
 
-nsDOMDataTransfer::nsDOMDataTransfer(uint32_t aEventType, bool aIsExternal)
+nsDOMDataTransfer::nsDOMDataTransfer(uint32_t aEventType, bool aIsExternal, int32_t aClipboardType)
   : mEventType(aEventType),
     mDropEffect(nsIDragService::DRAGDROP_ACTION_NONE),
     mEffectAllowed(nsIDragService::DRAGDROP_ACTION_UNINITIALIZED),
     mCursorState(false),
     mReadOnly(true),
     mIsExternal(aIsExternal),
     mUserCancelled(false),
     mIsCrossDomainSubFrameDrop(false),
+    mClipboardType(aClipboardType),
     mDragImageX(0),
     mDragImageY(0)
 {
   // For these events, we want to be able to add data to the data transfer, so
   // clear the readonly state. Otherwise, the data is already present. For
   // external usage, cache the data from the native clipboard or drag.
   if (aEventType == NS_CUT ||
       aEventType == NS_COPY ||
@@ -93,28 +94,30 @@ nsDOMDataTransfer::nsDOMDataTransfer(uin
 }
 
 nsDOMDataTransfer::nsDOMDataTransfer(uint32_t aEventType,
                                      const uint32_t aEffectAllowed,
                                      bool aCursorState,
                                      bool aIsExternal,
                                      bool aUserCancelled,
                                      bool aIsCrossDomainSubFrameDrop,
+                                     int32_t aClipboardType,
                                      nsTArray<nsTArray<TransferItem> >& aItems,
                                      nsIDOMElement* aDragImage,
                                      uint32_t aDragImageX,
                                      uint32_t aDragImageY)
   : mEventType(aEventType),
     mDropEffect(nsIDragService::DRAGDROP_ACTION_NONE),
     mEffectAllowed(aEffectAllowed),
     mCursorState(aCursorState),
     mReadOnly(true),
     mIsExternal(aIsExternal),
     mUserCancelled(aUserCancelled),
     mIsCrossDomainSubFrameDrop(aIsCrossDomainSubFrameDrop),
+    mClipboardType(aClipboardType),
     mItems(aItems),
     mDragImage(aDragImage),
     mDragImageX(aDragImageX),
     mDragImageY(aDragImageY)
 {
   // The items are copied from aItems into mItems. There is no need to copy
   // the actual data in the items as the data transfer will be read only. The
   // draggesture and dragstart events are the only times when items are
@@ -648,17 +651,17 @@ nsDOMDataTransfer::AddElement(nsIDOMElem
 nsresult
 nsDOMDataTransfer::Clone(uint32_t aEventType, bool aUserCancelled,
                          bool aIsCrossDomainSubFrameDrop,
                          nsIDOMDataTransfer** aNewDataTransfer)
 {
   nsDOMDataTransfer* newDataTransfer =
     new nsDOMDataTransfer(aEventType, mEffectAllowed, mCursorState,
                           mIsExternal, aUserCancelled, aIsCrossDomainSubFrameDrop,
-                          mItems, mDragImage, mDragImageX, mDragImageY);
+                          mClipboardType, mItems, mDragImage, mDragImageX, mDragImageY);
   NS_ENSURE_TRUE(newDataTransfer, NS_ERROR_OUT_OF_MEMORY);
 
   *aNewDataTransfer = newDataTransfer;
   NS_ADDREF(*aNewDataTransfer);
   return NS_OK;
 }
 
 already_AddRefed<nsISupportsArray>
@@ -974,33 +977,32 @@ nsDOMDataTransfer::CacheExternalClipboar
 {
   NS_ASSERTION(mEventType == NS_PASTE, "caching clipboard data for invalid event");
 
   // Called during the constructor for paste events to cache the formats
   // available on the clipboard. As with CacheExternalDragFormats, the
   // data will only be retrieved when needed.
 
   nsCOMPtr<nsIClipboard> clipboard = do_GetService("@mozilla.org/widget/clipboard;1");
-  if (!clipboard) {
+  if (!clipboard || mClipboardType < 0) {
     return;
   }
 
   nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
   nsCOMPtr<nsIPrincipal> sysPrincipal;
   ssm->GetSystemPrincipal(getter_AddRefs(sysPrincipal));
 
   // there isn't a way to get a list of the formats that might be available on
   // all platforms, so just check for the types that can actually be imported
   const char* formats[] = { kFileMime, kHTMLMime, kURLMime, kURLDataMime, kUnicodeMime };
 
   for (uint32_t f = 0; f < mozilla::ArrayLength(formats); ++f) {
     // check each format one at a time
     bool supported;
-    clipboard->HasDataMatchingFlavors(&(formats[f]), 1,
-                                      nsIClipboard::kGlobalClipboard, &supported);
+    clipboard->HasDataMatchingFlavors(&(formats[f]), 1, mClipboardType, &supported);
     // if the format is supported, add an item to the array with null as
     // the data. When retrieved, GetRealData will read the data.
     if (supported) {
       CacheExternalData(formats[f], 0, sysPrincipal);
     }
   }
 }
 
@@ -1031,21 +1033,21 @@ nsDOMDataTransfer::FillInExternalData(Tr
 
   trans->Init(nullptr);
   trans->AddDataFlavor(format);
 
   if (mEventType == NS_PASTE) {
     MOZ_ASSERT(aIndex == 0, "index in clipboard must be 0");
 
     nsCOMPtr<nsIClipboard> clipboard = do_GetService("@mozilla.org/widget/clipboard;1");
-    if (!clipboard) {
+    if (!clipboard || mClipboardType < 0) {
       return;
     }
 
-    clipboard->GetData(trans, nsIClipboard::kGlobalClipboard);
+    clipboard->GetData(trans, mClipboardType);
   } else {
     nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession();
     if (!dragSession) {
       return;
     }
 
 #ifdef DEBUG
     // Since this is an external drag, the source document will always be null.
--- a/content/events/src/nsDOMDataTransfer.h
+++ b/content/events/src/nsDOMDataTransfer.h
@@ -53,16 +53,17 @@ protected:
   // this constructor is used only by the Clone method to copy the fields as
   // needed to a new data transfer.
   nsDOMDataTransfer(uint32_t aEventType,
                     const uint32_t aEffectAllowed,
                     bool aCursorState,
                     bool aIsExternal,
                     bool aUserCancelled,
                     bool aIsCrossDomainSubFrameDrop,
+                    int32_t aClipboardType,
                     nsTArray<nsTArray<TransferItem> >& aItems,
                     nsIDOMElement* aDragImage,
                     uint32_t aDragImageX,
                     uint32_t aDragImageY);
 
   ~nsDOMDataTransfer()
   {
     if (mFiles) {
@@ -77,18 +78,20 @@ public:
   // Constructor for nsDOMDataTransfer.
   //
   // aEventType is an event constant (such as NS_DRAGDROP_START)
   //
   // aIsExternal must only be true when used to create a dataTransfer for a
   // paste or a drag that was started without using a data transfer. The
   // latter will occur when an external drag occurs, that is, a drag where the
   // source is another application, or a drag is started by calling the drag
-  // service directly.
-  nsDOMDataTransfer(uint32_t aEventType, bool aIsExternal);
+  // service directly. For clipboard operations, aClipboardType indicates
+  // which clipboard to use, from nsIClipboard, or -1 for non-clipboard operations,
+  // or if access to the system clipboard should not be allowed.
+  nsDOMDataTransfer(uint32_t aEventType, bool aIsExternal, int32_t aClipboardType);
 
   void GetDragTarget(nsIDOMElement** aDragTarget)
   {
     *aDragTarget = mDragTarget;
     NS_IF_ADDREF(*aDragTarget);
   }
 
   // a readonly dataTransfer cannot have new data added or existing data removed.
@@ -173,16 +176,20 @@ protected:
 
   // true if the user cancelled the drag. Used only for the dragend event.
   bool mUserCancelled;
 
   // true if this is a cross-domain drop from a subframe where access to the
   // data should be prevented
   bool mIsCrossDomainSubFrameDrop;
 
+  // Indicates which clipboard type to use for clipboard operations. Ignored for
+  // drag and drop.
+  int32_t mClipboardType;
+
   // array of items, each containing an array of format->data pairs
   nsTArray<nsTArray<TransferItem> > mItems;
 
   // array of files, containing only the files present in the dataTransfer
   nsRefPtr<nsDOMFileList> mFiles;
 
   // the target of the drag. The drag and dragend events will fire at this.
   nsCOMPtr<nsIDOMElement> mDragTarget;
--- a/content/events/src/nsEventDispatcher.cpp
+++ b/content/events/src/nsEventDispatcher.cpp
@@ -49,71 +49,37 @@ private:
 #define NS_TARGET_CHAIN_MAY_HAVE_MANAGER        (1 << 2)
 
 // nsEventTargetChainItem represents a single item in the event target chain.
 class nsEventTargetChainItem
 {
 private:
   nsEventTargetChainItem(EventTarget* aTarget,
                          nsEventTargetChainItem* aChild = nullptr);
+public:
+  nsEventTargetChainItem()
+  : mChild(nullptr), mParent(nullptr), mFlags(0), mItemFlags(0)
+  {
+  }
 
-  // This is the ETCI recycle pool, which is used to avoid some malloc/free
-  // churn.  It's implemented as a linked list.
-  static nsEventTargetChainItem* sEtciRecyclePool;
-  static uint32_t sNumRecycledEtcis;
-  static const uint32_t kMaxNumRecycledEtcis = 128;
-
-public:
-  static nsEventTargetChainItem* Create(EventTarget* aTarget,
+  static nsEventTargetChainItem* Create(nsTArray<nsEventTargetChainItem>& aPool,
+                                        EventTarget* aTarget,
                                         nsEventTargetChainItem* aChild = nullptr)
   {
-    // Allocate from the ETCI recycle pool if possible.
-    void* place = nullptr;
-    if (sNumRecycledEtcis > 0) {
-      MOZ_ASSERT(sEtciRecyclePool);
-      place = sEtciRecyclePool;
-      sEtciRecyclePool = sEtciRecyclePool->mNext;
-      --sNumRecycledEtcis;
-    } else {
-      place = malloc(sizeof(nsEventTargetChainItem));
-    }
-    return place
-      ? ::new (place) nsEventTargetChainItem(aTarget, aChild)
-      : nullptr;
+    
+    return new (aPool.AppendElement()) nsEventTargetChainItem(aTarget, aChild);
   }
 
   static void Destroy(nsEventTargetChainItem* aItem)
   {
-    // ::Destroy deletes ancestor chain.
-    nsEventTargetChainItem* item = aItem;
-    if (item->mChild) {
-      item->mChild->mParent = nullptr;
-      item->mChild = nullptr;
-    }
-    // Put destroyed ETCIs into the recycle pool if it's not already full.
-    while (item) {
-      nsEventTargetChainItem* parent = item->mParent;
-      item->~nsEventTargetChainItem();
-      if (sNumRecycledEtcis < kMaxNumRecycledEtcis) {
-        item->mNext = sEtciRecyclePool;
-        sEtciRecyclePool = item;
-        ++sNumRecycledEtcis;
-      } else {
-        free(item);
-      }
-      item = parent;
-    }
-  }
-
-  static void ShutdownRecyclePool()
-  {
-    while (sEtciRecyclePool) {
-      nsEventTargetChainItem* tmp = sEtciRecyclePool;
-      sEtciRecyclePool = sEtciRecyclePool->mNext;
-      free(tmp);
+    // nsEventTargetChainItem objects are deleted when the pool goes out of
+    // the scope.
+    if (aItem->mChild) {
+      aItem->mChild->mParent = nullptr;
+      aItem->mChild = nullptr;
     }
   }
 
   bool IsValid()
   {
     NS_WARN_IF_FALSE(!!(mTarget), "Event target is not valid!");
     return !!(mTarget);
   }
@@ -228,46 +194,28 @@ public:
   }
 
   /**
    * Copies mItemFlags and mItemData to aVisitor and calls PostHandleEvent.
    */
   nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor,
                            nsCxPusher* aPusher);
 
-  static uint32_t MaxEtciCount() { return sMaxEtciCount; }
-
-  static void ResetMaxEtciCount()
-  {
-    MOZ_ASSERT(!sCurrentEtciCount, "Wrong time to call ResetMaxEtciCount()!");
-    sMaxEtciCount = 0;
-  }
-
   nsCOMPtr<EventTarget>             mTarget;
   nsEventTargetChainItem*           mChild;
-  union {
-    nsEventTargetChainItem*         mParent;
-     // This is used only when recycling ETCIs.
-    nsEventTargetChainItem*         mNext;
-  };
+  nsEventTargetChainItem*           mParent;
   uint16_t                          mFlags;
   uint16_t                          mItemFlags;
   nsCOMPtr<nsISupports>             mItemData;
   // Event retargeting must happen whenever mNewTarget is non-null.
   nsCOMPtr<EventTarget>             mNewTarget;
   // Cache mTarget's event listener manager.
   nsRefPtr<nsEventListenerManager>  mManager;
-
-  static uint32_t                   sMaxEtciCount;
-  static uint32_t                   sCurrentEtciCount;
 };
 
-nsEventTargetChainItem* nsEventTargetChainItem::sEtciRecyclePool = nullptr;
-uint32_t nsEventTargetChainItem::sNumRecycledEtcis = 0;
-
 nsEventTargetChainItem::nsEventTargetChainItem(EventTarget* aTarget,
                                                nsEventTargetChainItem* aChild)
 : mTarget(aTarget), mChild(aChild), mParent(nullptr), mFlags(0), mItemFlags(0)
 {
   MOZ_ASSERT(!aTarget || mTarget == aTarget->GetTargetForEventTargetChain());
   if (mChild) {
     mChild->mParent = this;
   }
@@ -400,36 +348,32 @@ nsEventTargetChainItem::HandleEventTarge
     // system group listeners don't affect to the event.
     aVisitor.mEvent->mFlags.mPropagationStopped = false;
     aVisitor.mEvent->mFlags.mImmediatePropagationStopped = false;
   }
 
   return NS_OK;
 }
 
-void NS_ShutdownEventTargetChainItemRecyclePool()
-{
-  nsEventTargetChainItem::ShutdownRecyclePool();
-}
-
 nsEventTargetChainItem*
-EventTargetChainItemForChromeTarget(nsINode* aNode,
+EventTargetChainItemForChromeTarget(nsTArray<nsEventTargetChainItem>& aPool,
+                                    nsINode* aNode,
                                     nsEventTargetChainItem* aChild = nullptr)
 {
   if (!aNode->IsInDoc()) {
     return nullptr;
   }
   nsPIDOMWindow* win = aNode->OwnerDoc()->GetInnerWindow();
   EventTarget* piTarget = win ? win->GetParentTarget() : nullptr;
   NS_ENSURE_TRUE(piTarget, nullptr);
 
   nsEventTargetChainItem* etci =
-    nsEventTargetChainItem::Create(piTarget->GetTargetForEventTargetChain(),
+    nsEventTargetChainItem::Create(aPool,
+                                   piTarget->GetTargetForEventTargetChain(),
                                    aChild);
-  NS_ENSURE_TRUE(etci, nullptr);
   if (!etci->IsValid()) {
     nsEventTargetChainItem::Destroy(etci);
     return nullptr;
   }
   return etci;
 }
 
 /* static */ nsresult
@@ -517,20 +461,22 @@ nsEventDispatcher::Dispatch(nsISupports*
 
   nsresult rv = NS_OK;
   bool externalDOMEvent = !!(aDOMEvent);
 
   // If we have a PresContext, make sure it doesn't die before
   // event dispatching is finished.
   nsRefPtr<nsPresContext> kungFuDeathGrip(aPresContext);
 
+  // Try to limit malloc/free churn by using an array as a pool.
+  nsTArray<nsEventTargetChainItem> pool(128);
+
   // Create the event target chain item for the event target.
   nsEventTargetChainItem* targetEtci =
-    nsEventTargetChainItem::Create(target->GetTargetForEventTargetChain());
-  NS_ENSURE_TRUE(targetEtci, NS_ERROR_OUT_OF_MEMORY);
+    nsEventTargetChainItem::Create(pool, target->GetTargetForEventTargetChain());
   if (!targetEtci->IsValid()) {
     nsEventTargetChainItem::Destroy(targetEtci);
     return NS_ERROR_FAILURE;
   }
 
   // Make sure that nsIDOMEvent::target and nsIDOMEvent::originalTarget
   // point to the last item in the chain.
   if (!aEvent->target) {
@@ -566,34 +512,30 @@ nsEventDispatcher::Dispatch(nsISupports*
   nsEventStatus status = aEventStatus ? *aEventStatus : nsEventStatus_eIgnore;
   nsEventChainPreVisitor preVisitor(aPresContext, aEvent, aDOMEvent, status,
                                     isInAnon);
   targetEtci->PreHandleEvent(preVisitor);
 
   if (!preVisitor.mCanHandle && preVisitor.mAutomaticChromeDispatch && content) {
     // Event target couldn't handle the event. Try to propagate to chrome.
     nsEventTargetChainItem::Destroy(targetEtci);
-    targetEtci = EventTargetChainItemForChromeTarget(content);
+    targetEtci = EventTargetChainItemForChromeTarget(pool, content);
     NS_ENSURE_STATE(targetEtci);
     targetEtci->PreHandleEvent(preVisitor);
   }
   if (preVisitor.mCanHandle) {
     // At least the original target can handle the event.
     // Setting the retarget to the |target| simplifies retargeting code.
     nsCOMPtr<EventTarget> t = do_QueryInterface(aEvent->target);
     targetEtci->SetNewTarget(t);
     nsEventTargetChainItem* topEtci = targetEtci;
     while (preVisitor.mParentTarget) {
       EventTarget* parentTarget = preVisitor.mParentTarget;
       nsEventTargetChainItem* parentEtci =
-        nsEventTargetChainItem::Create(preVisitor.mParentTarget, topEtci);
-      if (!parentEtci) {
-        rv = NS_ERROR_OUT_OF_MEMORY;
-        break;
-      }
+        nsEventTargetChainItem::Create(pool, preVisitor.mParentTarget, topEtci);
       if (!parentEtci->IsValid()) {
         rv = NS_ERROR_FAILURE;
         break;
       }
 
       // Item needs event retargetting.
       if (preVisitor.mEventTargetAtParent) {
         // Need to set the target of the event
@@ -608,17 +550,18 @@ nsEventDispatcher::Dispatch(nsISupports*
       } else {
         nsEventTargetChainItem::Destroy(parentEtci);
         parentEtci = nullptr;
         if (preVisitor.mAutomaticChromeDispatch && content) {
           // Even if the current target can't handle the event, try to
           // propagate to chrome.
           nsCOMPtr<nsINode> disabledTarget = do_QueryInterface(parentTarget);
           if (disabledTarget) {
-            parentEtci = EventTargetChainItemForChromeTarget(disabledTarget,
+            parentEtci = EventTargetChainItemForChromeTarget(pool,
+                                                             disabledTarget,
                                                              topEtci);
             if (parentEtci) {
               parentEtci->PreHandleEvent(preVisitor);
               if (preVisitor.mCanHandle) {
                 targetEtci->SetNewTarget(parentTarget);
                 topEtci = parentEtci;
                 continue;
               }
--- a/content/events/src/nsEventStateManager.cpp
+++ b/content/events/src/nsEventStateManager.cpp
@@ -1580,16 +1580,17 @@ CrossProcessSafeEvent(const nsEvent& aEv
   case NS_KEY_EVENT:
   case NS_WHEEL_EVENT:
     return true;
   case NS_MOUSE_EVENT:
     switch (aEvent.message) {
     case NS_MOUSE_BUTTON_DOWN:
     case NS_MOUSE_BUTTON_UP:
     case NS_MOUSE_MOVE:
+    case NS_CONTEXTMENU:
       return true;
     default:
       return false;
     }
   case NS_TOUCH_EVENT:
     switch (aEvent.message) {
     case NS_TOUCH_START:
     case NS_TOUCH_MOVE:
@@ -2022,17 +2023,17 @@ nsEventStateManager::GenerateDragGesture
         DeprecatedAbs(pt.y - mGestureDownPoint.y) > pixelThresholdY) {
       if (mClickHoldContextMenu) {
         // stop the click-hold before we fire off the drag gesture, in case
         // it takes a long time
         KillClickHoldTimer();
       }
 
       nsRefPtr<nsDOMDataTransfer> dataTransfer =
-        new nsDOMDataTransfer(NS_DRAGDROP_START, false);
+        new nsDOMDataTransfer(NS_DRAGDROP_START, false, -1);
       if (!dataTransfer)
         return;
 
       nsCOMPtr<nsISelection> selection;
       nsCOMPtr<nsIContent> eventContent, targetContent;
       mCurrentTarget->GetContentForEvent(aEvent, getter_AddRefs(eventContent));
       if (eventContent)
         DetermineDragTarget(aPresContext, eventContent, dataTransfer,
--- a/content/html/content/public/HTMLAudioElement.h
+++ b/content/html/content/public/HTMLAudioElement.h
@@ -24,25 +24,16 @@ class HTMLAudioElement MOZ_FINAL : publi
 {
 public:
   HTMLAudioElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~HTMLAudioElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   // nsIDOMHTMLMediaElement
   using HTMLMediaElement::GetPaused;
   NS_FORWARD_NSIDOMHTMLMEDIAELEMENT(HTMLMediaElement::)
 
   // nsIAudioChannelAgentCallback
   NS_DECL_NSIAUDIOCHANNELAGENTCALLBACK
 
   // NS_DECL_NSITIMERCALLBACK
--- a/content/html/content/public/HTMLCanvasElement.h
+++ b/content/html/content/public/HTMLCanvasElement.h
@@ -49,25 +49,16 @@ public:
   HTMLCanvasElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~HTMLCanvasElement();
 
   NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLCanvasElement, canvas)
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   // nsIDOMHTMLCanvasElement
   NS_DECL_NSIDOMHTMLCANVASELEMENT
 
   // CC
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLCanvasElement,
                                            nsGenericHTMLElement)
 
   // WebIDL
@@ -219,18 +210,16 @@ public:
   // Call this whenever we need future changes to the canvas
   // to trigger fresh invalidation requests. This needs to be called
   // whenever we render the canvas contents to the screen, or whenever we
   // take a snapshot of the canvas that needs to be "live" (e.g. -moz-element).
   void MarkContextClean();
 
   nsresult GetContext(const nsAString& aContextId, nsISupports** aContext);
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
-
 protected:
   virtual JSObject* WrapNode(JSContext* aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
   nsIntSize GetWidthHeight();
 
   nsresult UpdateContext(JSContext* aCx, JS::Handle<JS::Value> options);
   nsresult ParseParams(JSContext* aCx,
--- a/content/html/content/public/HTMLVideoElement.h
+++ b/content/html/content/public/HTMLVideoElement.h
@@ -23,25 +23,16 @@ public:
   HTMLVideoElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~HTMLVideoElement();
 
   NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLVideoElement, video)
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   // nsIDOMHTMLMediaElement
   using HTMLMediaElement::GetPaused;
   NS_FORWARD_NSIDOMHTMLMEDIAELEMENT(HTMLMediaElement::)
 
   // nsIDOMHTMLVideoElement
   NS_DECL_NSIDOMHTMLVIDEOELEMENT
 
   virtual bool ParseAttribute(int32_t aNamespaceID,
@@ -57,18 +48,16 @@ public:
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   // Set size with the current video frame's height and width.
   // If there is no video frame, returns NS_ERROR_FAILURE.
   nsresult GetVideoSize(nsIntSize* size);
 
   virtual nsresult SetAcceptHeader(nsIHttpChannel* aChannel);
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
-
   // WebIDL
 
   uint32_t Width() const
   {
     return GetIntAttr(nsGkAtoms::width, 0);
   }
 
   void SetWidth(uint32_t aValue, ErrorResult& aRv)
--- a/content/html/content/public/moz.build
+++ b/content/html/content/public/moz.build
@@ -17,17 +17,16 @@ MODULE = 'content'
 
 EXPORTS += [
     'nsFormSubmission.h',
     'nsIConstraintValidation.h',
     'nsIForm.h',
     'nsIFormControl.h',
     'nsIFormProcessor.h',
     'nsIHTMLCollection.h',
-    'nsILink.h',
     'nsIRadioGroupContainer.h',
     'nsIRadioVisitor.h',
     'nsITextControlElement.h',
 ]
 
 EXPORTS.mozilla.dom += [
     'HTMLAudioElement.h',
     'HTMLCanvasElement.h',
deleted file mode 100644
--- a/content/html/content/public/nsILink.h
+++ /dev/null
@@ -1,52 +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 nsILink_h___
-#define nsILink_h___
-
-#include "nsISupports.h"
-#include "nsILinkHandler.h" // definition of nsLinkState
-
-class nsIURI;
-
-// IID for the nsILink interface
-#define NS_ILINK_IID    \
-{ 0x6f374a11, 0x212d, 0x47d6, \
-  { 0x94, 0xd1, 0xe6, 0x7c, 0x23, 0x4d, 0x34, 0x99 } }
-
-/**
- * This interface allows SelectorMatches to get the canonical
- * URL pointed to by an element representing a link and allows
- * it to store the visited state of a link element in the link.
- * It is needed for performance reasons (to prevent copying of
- * strings and excessive calls to history).
- */
-class nsILink : public nsISupports {
-public:
-  NS_DECLARE_STATIC_IID_ACCESSOR(NS_ILINK_IID)
-
-  /**
-   * SetLinkState/GetHrefURI were moved to nsIContent.
-   * @see nsIContent
-   */
-
-  /**
-   * Dispatch a LinkAdded event to the chrome event handler for this document.
-   * This is used to notify the chrome listeners when restoring a page
-   * presentation.  Currently, this only applies to HTML <link> elements.
-   */
-  NS_IMETHOD LinkAdded() = 0;
-
-  /**
-   * Dispatch a LinkRemoved event to the chrome event handler for this
-   * document.  This is used to notify the chrome listeners when saving a page
-   * presentation (since the document is not torn down).  Currently, this only
-   * applies to HTML <link> elements.
-   */
-  NS_IMETHOD LinkRemoved() = 0;
-};
-
-NS_DEFINE_STATIC_IID_ACCESSOR(nsILink, NS_ILINK_IID)
-
-#endif /* nsILink_h___ */
--- a/content/html/content/src/HTMLAnchorElement.cpp
+++ b/content/html/content/src/HTMLAnchorElement.cpp
@@ -35,29 +35,18 @@ enum {
 ASSERT_NODE_FLAGS_SPACE(ELEMENT_TYPE_SPECIFIC_BITS_OFFSET + 2);
 
 #undef ANCHOR_ELEMENT_FLAG_BIT
 
 HTMLAnchorElement::~HTMLAnchorElement()
 {
 }
 
-NS_IMPL_ADDREF_INHERITED(HTMLAnchorElement, Element)
-NS_IMPL_RELEASE_INHERITED(HTMLAnchorElement, Element)
-
-// QueryInterface implementation for HTMLAnchorElement
-NS_INTERFACE_TABLE_HEAD(HTMLAnchorElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-  NS_INTERFACE_TABLE_INHERITED3(HTMLAnchorElement,
-                                nsIDOMHTMLAnchorElement,
-                                nsILink,
-                                Link)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
-
+NS_IMPL_ISUPPORTS_INHERITED2(HTMLAnchorElement, nsGenericHTMLElement,
+                             nsIDOMHTMLAnchorElement, Link)
 
 NS_IMPL_ELEMENT_CLONE(HTMLAnchorElement)
 
 JSObject*
 HTMLAnchorElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aScope)
 {
   return HTMLAnchorElementBinding::Wrap(aCx, aScope, this);
 }
--- a/content/html/content/src/HTMLAnchorElement.h
+++ b/content/html/content/src/HTMLAnchorElement.h
@@ -6,62 +6,47 @@
 
 #ifndef mozilla_dom_HTMLAnchorElement_h
 #define mozilla_dom_HTMLAnchorElement_h
 
 #include "mozilla/Attributes.h"
 #include "mozilla/dom/Link.h"
 #include "nsGenericHTMLElement.h"
 #include "nsIDOMHTMLAnchorElement.h"
-#include "nsILink.h"
 
 namespace mozilla {
 namespace dom {
 
 class HTMLAnchorElement MOZ_FINAL : public nsGenericHTMLElement,
                                     public nsIDOMHTMLAnchorElement,
-                                    public nsILink,
                                     public Link
 {
 public:
   using Element::GetText;
   using Element::SetText;
 
   HTMLAnchorElement(already_AddRefed<nsINodeInfo> aNodeInfo)
     : nsGenericHTMLElement(aNodeInfo)
     , Link(MOZ_THIS_IN_INITIALIZER_LIST())
   {
   }
   virtual ~HTMLAnchorElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   virtual int32_t TabIndexDefault() MOZ_OVERRIDE;
   virtual bool Draggable() const MOZ_OVERRIDE;
 
   // nsIDOMHTMLAnchorElement
   NS_DECL_NSIDOMHTMLANCHORELEMENT
 
   // DOM memory reporter participant
   NS_DECL_SIZEOF_EXCLUDING_THIS
 
-  // nsILink
-  NS_IMETHOD LinkAdded() MOZ_OVERRIDE { return NS_OK; }
-  NS_IMETHOD LinkRemoved() MOZ_OVERRIDE { return NS_OK; }
-
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               bool aCompileEventHandlers) MOZ_OVERRIDE;
   virtual void UnbindFromTree(bool aDeep = true,
                               bool aNullParent = true) MOZ_OVERRIDE;
   virtual bool IsHTMLFocusable(bool aWithMouse, bool *aIsFocusable, int32_t *aTabIndex) MOZ_OVERRIDE;
 
   virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
@@ -84,18 +69,16 @@ public:
                                 nsIAtom* aAttribute,
                                 const nsAString& aValue,
                                 nsAttrValue& aResult) MOZ_OVERRIDE;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   virtual nsEventStates IntrinsicState() const MOZ_OVERRIDE;
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
-
   virtual void OnDNSPrefetchDeferred();
   virtual void OnDNSPrefetchRequested();
   virtual bool HasDeferredDNSPrefetchRequest();
 
   // WebIDL API
   void GetHref(nsString& aValue)
   {
     GetHTMLURIAttr(nsGkAtoms::href, aValue);
--- a/content/html/content/src/HTMLAreaElement.cpp
+++ b/content/html/content/src/HTMLAreaElement.cpp
@@ -20,29 +20,18 @@ HTMLAreaElement::HTMLAreaElement(already
   , Link(MOZ_THIS_IN_INITIALIZER_LIST())
 {
 }
 
 HTMLAreaElement::~HTMLAreaElement()
 {
 }
 
-NS_IMPL_ADDREF_INHERITED(HTMLAreaElement, Element)
-NS_IMPL_RELEASE_INHERITED(HTMLAreaElement, Element)
-
-// QueryInterface implementation for HTMLAreaElement
-NS_INTERFACE_TABLE_HEAD(HTMLAreaElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-  NS_INTERFACE_TABLE_INHERITED3(HTMLAreaElement,
-                                nsIDOMHTMLAreaElement,
-                                nsILink,
-                                Link)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
-
+NS_IMPL_ISUPPORTS_INHERITED2(HTMLAreaElement, nsGenericHTMLElement,
+                             nsIDOMHTMLAreaElement, Link)
 
 NS_IMPL_ELEMENT_CLONE(HTMLAreaElement)
 
 
 NS_IMPL_STRING_ATTR(HTMLAreaElement, Alt, alt)
 NS_IMPL_STRING_ATTR(HTMLAreaElement, Coords, coords)
 NS_IMPL_URI_ATTR(HTMLAreaElement, Href, href)
 NS_IMPL_BOOL_ATTR(HTMLAreaElement, NoHref, nohref)
--- a/content/html/content/src/HTMLAreaElement.h
+++ b/content/html/content/src/HTMLAreaElement.h
@@ -7,57 +7,42 @@
 #ifndef mozilla_dom_HTMLAreaElement_h
 #define mozilla_dom_HTMLAreaElement_h
 
 #include "mozilla/Attributes.h"
 #include "mozilla/dom/Link.h"
 #include "nsGenericHTMLElement.h"
 #include "nsGkAtoms.h"
 #include "nsIDOMHTMLAreaElement.h"
-#include "nsILink.h"
 #include "nsIURL.h"
 
 class nsIDocument;
 
 namespace mozilla {
 namespace dom {
 
 class HTMLAreaElement MOZ_FINAL : public nsGenericHTMLElement,
                                   public nsIDOMHTMLAreaElement,
-                                  public nsILink,
                                   public Link
 {
 public:
   HTMLAreaElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~HTMLAreaElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // DOM memory reporter participant
   NS_DECL_SIZEOF_EXCLUDING_THIS
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   virtual int32_t TabIndexDefault() MOZ_OVERRIDE;
 
   // nsIDOMHTMLAreaElement
   NS_DECL_NSIDOMHTMLAREAELEMENT
 
-  // nsILink
-  NS_IMETHOD LinkAdded() MOZ_OVERRIDE { return NS_OK; }
-  NS_IMETHOD LinkRemoved() MOZ_OVERRIDE { return NS_OK; }
-
   virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
   virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor) MOZ_OVERRIDE;
   virtual bool IsLink(nsIURI** aURI) const MOZ_OVERRIDE;
   virtual void GetLinkTarget(nsAString& aTarget) MOZ_OVERRIDE;
   virtual already_AddRefed<nsIURI> GetHrefURI() const MOZ_OVERRIDE;
 
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
@@ -74,18 +59,16 @@ public:
                            bool aNotify) MOZ_OVERRIDE;
   virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
                              bool aNotify) MOZ_OVERRIDE;
 
   virtual nsresult Clone(nsINodeInfo* aNodeInfo, nsINode** aResult) const MOZ_OVERRIDE;
 
   virtual nsEventStates IntrinsicState() const MOZ_OVERRIDE;
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
-
   // WebIDL
 
   // The XPCOM GetAlt is OK for us
   void SetAlt(const nsAString& aAlt, ErrorResult& aError)
   {
     SetHTMLAttr(nsGkAtoms::alt, aAlt, aError);
   }
 
--- a/content/html/content/src/HTMLAudioElement.cpp
+++ b/content/html/content/src/HTMLAudioElement.cpp
@@ -25,26 +25,19 @@ IsAudioAPIEnabled()
   return mozilla::Preferences::GetBool("media.audio_data.enabled", true);
 }
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Audio)
 
 namespace mozilla {
 namespace dom {
 
-NS_IMPL_ADDREF_INHERITED(HTMLAudioElement, HTMLMediaElement)
-NS_IMPL_RELEASE_INHERITED(HTMLAudioElement, HTMLMediaElement)
-
-NS_INTERFACE_TABLE_HEAD(HTMLAudioElement)
-  NS_HTML_CONTENT_INTERFACES(HTMLMediaElement)
-  NS_INTERFACE_TABLE_INHERITED4(HTMLAudioElement, nsIDOMHTMLMediaElement,
-                                nsIDOMHTMLAudioElement, nsITimerCallback,
-                                nsIAudioChannelAgentCallback)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
+NS_IMPL_ISUPPORTS_INHERITED4(HTMLAudioElement, HTMLMediaElement,
+                             nsIDOMHTMLMediaElement, nsIDOMHTMLAudioElement,
+                             nsITimerCallback, nsIAudioChannelAgentCallback)
 
 NS_IMPL_ELEMENT_CLONE(HTMLAudioElement)
 
 
 HTMLAudioElement::HTMLAudioElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : HTMLMediaElement(aNodeInfo),
     mTimerActivated(false)
 {
--- a/content/html/content/src/HTMLBRElement.cpp
+++ b/content/html/content/src/HTMLBRElement.cpp
@@ -22,27 +22,18 @@ HTMLBRElement::HTMLBRElement(already_Add
   : nsGenericHTMLElement(aNodeInfo)
 {
 }
 
 HTMLBRElement::~HTMLBRElement()
 {
 }
 
-NS_IMPL_ADDREF_INHERITED(HTMLBRElement, Element)
-NS_IMPL_RELEASE_INHERITED(HTMLBRElement, Element)
-
-
-// QueryInterface implementation for HTMLBRElement
-NS_INTERFACE_TABLE_HEAD(HTMLBRElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-  NS_INTERFACE_TABLE_INHERITED1(HTMLBRElement, nsIDOMHTMLBRElement)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
-
+NS_IMPL_ISUPPORTS_INHERITED1(HTMLBRElement, nsGenericHTMLElement,
+                             nsIDOMHTMLBRElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLBRElement)
 
 
 NS_IMPL_STRING_ATTR(HTMLBRElement, Clear, clear)
 
 static const nsAttrValue::EnumTable kClearTable[] = {
   { "left", NS_STYLE_CLEAR_LEFT },
--- a/content/html/content/src/HTMLBRElement.h
+++ b/content/html/content/src/HTMLBRElement.h
@@ -19,36 +19,26 @@ class HTMLBRElement MOZ_FINAL : public n
 {
 public:
   HTMLBRElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~HTMLBRElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   // nsIDOMHTMLBRElement
   NS_DECL_NSIDOMHTMLBRELEMENT
 
   virtual bool ParseAttribute(int32_t aNamespaceID,
                                 nsIAtom* aAttribute,
                                 const nsAString& aValue,
                                 nsAttrValue& aResult) MOZ_OVERRIDE;
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
   virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const MOZ_OVERRIDE;
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
 
   bool Clear()
   {
     return GetBoolAttr(nsGkAtoms::clear);
   }
   void SetClear(const nsAString& aClear, ErrorResult& aError)
   {
     return SetHTMLAttr(nsGkAtoms::clear, aClear, aError);
--- a/content/html/content/src/HTMLBodyElement.cpp
+++ b/content/html/content/src/HTMLBodyElement.cpp
@@ -194,25 +194,18 @@ HTMLBodyElement::~HTMLBodyElement()
 }
 
 JSObject*
 HTMLBodyElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aScope)
 {
   return HTMLBodyElementBinding::Wrap(aCx, aScope, this);
 }
 
-NS_IMPL_ADDREF_INHERITED(HTMLBodyElement, Element)
-NS_IMPL_RELEASE_INHERITED(HTMLBodyElement, Element)
-
-// QueryInterface implementation for HTMLBodyElement
-NS_INTERFACE_TABLE_HEAD(HTMLBodyElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-  NS_INTERFACE_TABLE_INHERITED1(HTMLBodyElement, nsIDOMHTMLBodyElement)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
+NS_IMPL_ISUPPORTS_INHERITED1(HTMLBodyElement, nsGenericHTMLElement,
+                             nsIDOMHTMLBodyElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLBodyElement)
 
 NS_IMETHODIMP 
 HTMLBodyElement::SetBackground(const nsAString& aBackground)
 {
   ErrorResult rv;
   SetBackground(aBackground, rv);
--- a/content/html/content/src/HTMLBodyElement.h
+++ b/content/html/content/src/HTMLBodyElement.h
@@ -44,25 +44,16 @@ public:
     : nsGenericHTMLElement(aNodeInfo)
   {
   }
   virtual ~HTMLBodyElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   // nsIDOMHTMLBodyElement
   NS_DECL_NSIDOMHTMLBODYELEMENT
 
   // Event listener stuff; we need to declare only the ones we need to
   // forward to window that don't come from nsIDOMHTMLBodyElement.
 #define EVENT(name_, id_, type_, struct_) /* nothing; handled by the shim */
 #define FORWARDED_EVENT(name_, id_, type_, struct_)                     \
   NS_IMETHOD GetOn##name_(JSContext *cx, JS::Value *vp);                \
@@ -136,17 +127,16 @@ public:
                               nsAttrValue& aResult) MOZ_OVERRIDE;
   virtual void UnbindFromTree(bool aDeep = true,
                               bool aNullParent = true) MOZ_OVERRIDE;
   virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const MOZ_OVERRIDE;
   NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker) MOZ_OVERRIDE;
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
   virtual already_AddRefed<nsIEditor> GetAssociatedEditor() MOZ_OVERRIDE;
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
 
   virtual bool IsEventAttributeName(nsIAtom* aName) MOZ_OVERRIDE;
 
 private:
   nsresult GetColorHelper(nsIAtom* aAtom, nsAString& aColor);
 
 protected:
   virtual JSObject* WrapNode(JSContext *aCx,
--- a/content/html/content/src/HTMLButtonElement.cpp
+++ b/content/html/content/src/HTMLButtonElement.cpp
@@ -78,22 +78,20 @@ NS_IMPL_CYCLE_COLLECTION_INHERITED_1(HTM
                                      mValidity)
 
 NS_IMPL_ADDREF_INHERITED(HTMLButtonElement, Element)
 NS_IMPL_RELEASE_INHERITED(HTMLButtonElement, Element)
 
 
 // QueryInterface implementation for HTMLButtonElement
 NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(HTMLButtonElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLFormElementWithState)
   NS_INTERFACE_TABLE_INHERITED2(HTMLButtonElement,
                                 nsIDOMHTMLButtonElement,
                                 nsIConstraintValidation)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
+NS_INTERFACE_TABLE_TAIL_INHERITING(nsGenericHTMLFormElementWithState)
 
 // nsIConstraintValidation
 NS_IMPL_NSICONSTRAINTVALIDATION(HTMLButtonElement)
 
 // nsIDOMHTMLButtonElement
 
 
 NS_IMPL_ELEMENT_CLONE(HTMLButtonElement)
--- a/content/html/content/src/HTMLButtonElement.h
+++ b/content/html/content/src/HTMLButtonElement.h
@@ -26,26 +26,19 @@ public:
   virtual ~HTMLButtonElement();
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLButtonElement,
                                            nsGenericHTMLFormElementWithState)
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
+  virtual int32_t TabIndexDefault() MOZ_OVERRIDE;
 
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
-  virtual int32_t TabIndexDefault() MOZ_OVERRIDE;
+  NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLButtonElement, button)
 
   // nsIDOMHTMLButtonElement
   NS_DECL_NSIDOMHTMLBUTTONELEMENT
 
   // overriden nsIFormControl methods
   NS_IMETHOD_(uint32_t) GetType() const { return mType; }
   NS_IMETHOD Reset() MOZ_OVERRIDE;
   NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission) MOZ_OVERRIDE;
@@ -54,17 +47,16 @@ public:
   virtual bool IsDisabledForEvents(uint32_t aMessage) MOZ_OVERRIDE;
 
   // nsIDOMEventTarget
   virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
   virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor) MOZ_OVERRIDE;
 
   // nsINode
   virtual nsresult Clone(nsINodeInfo* aNodeInfo, nsINode** aResult) const MOZ_OVERRIDE;
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
   virtual JSObject* WrapNode(JSContext* aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
   // nsIContent
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               bool aCompileEventHandlers) MOZ_OVERRIDE;
   virtual void UnbindFromTree(bool aDeep = true,
--- a/content/html/content/src/HTMLCanvasElement.cpp
+++ b/content/html/content/src/HTMLCanvasElement.cpp
@@ -159,22 +159,20 @@ HTMLCanvasElement::~HTMLCanvasElement()
 NS_IMPL_CYCLE_COLLECTION_INHERITED_4(HTMLCanvasElement, nsGenericHTMLElement,
                                      mCurrentContext, mPrintCallback,
                                      mPrintState, mOriginalCanvas)
 
 NS_IMPL_ADDREF_INHERITED(HTMLCanvasElement, Element)
 NS_IMPL_RELEASE_INHERITED(HTMLCanvasElement, Element)
 
 NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(HTMLCanvasElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
   NS_INTERFACE_TABLE_INHERITED2(HTMLCanvasElement,
                                 nsIDOMHTMLCanvasElement,
                                 nsICanvasElementExternal)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
+NS_INTERFACE_TABLE_TAIL_INHERITING(nsGenericHTMLElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLCanvasElement)
 
 /* virtual */ JSObject*
 HTMLCanvasElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aScope)
 {
   return HTMLCanvasElementBinding::Wrap(aCx, aScope, this);
 }
--- a/content/html/content/src/HTMLDataElement.cpp
+++ b/content/html/content/src/HTMLDataElement.cpp
@@ -16,23 +16,16 @@ HTMLDataElement::HTMLDataElement(already
   : nsGenericHTMLElement(aNodeInfo)
 {
 }
 
 HTMLDataElement::~HTMLDataElement()
 {
 }
 
-NS_IMPL_ADDREF_INHERITED(HTMLDataElement, Element)
-NS_IMPL_RELEASE_INHERITED(HTMLDataElement, Element)
-
-NS_INTERFACE_MAP_BEGIN(HTMLDataElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-NS_ELEMENT_INTERFACE_MAP_END
-
 NS_IMPL_ELEMENT_CLONE(HTMLDataElement)
 
 JSObject*
 HTMLDataElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aScope)
 {
   return HTMLDataElementBinding::Wrap(aCx, aScope, this);
 }
 
--- a/content/html/content/src/HTMLDataElement.h
+++ b/content/html/content/src/HTMLDataElement.h
@@ -9,50 +9,36 @@
 #include "mozilla/Attributes.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsGenericHTMLElement.h"
 #include "nsGkAtoms.h"
 
 namespace mozilla {
 namespace dom {
 
-class HTMLDataElement MOZ_FINAL : public nsGenericHTMLElement,
-                                  public nsIDOMHTMLElement
+class HTMLDataElement MOZ_FINAL : public nsGenericHTMLElement
 {
 public:
   HTMLDataElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~HTMLDataElement();
 
-  // nsISupports
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   // HTMLDataElement WebIDL
   void GetValue(nsAString& aValue)
   {
     GetHTMLAttr(nsGkAtoms::value, aValue);
   }
 
   void SetValue(const nsAString& aValue, ErrorResult& aError)
   {
     SetHTMLAttr(nsGkAtoms::value, aValue, aError);
   }
 
   virtual void GetItemValueText(nsAString& text) MOZ_OVERRIDE;
   virtual void SetItemValueText(const nsAString& text) MOZ_OVERRIDE;
   virtual nsresult Clone(nsINodeInfo* aNodeInfo, nsINode** aResult) const MOZ_OVERRIDE;
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
 
 protected:
   virtual JSObject* WrapNode(JSContext* aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/content/html/content/src/HTMLDataListElement.cpp
+++ b/content/html/content/src/HTMLDataListElement.cpp
@@ -23,18 +23,17 @@ HTMLDataListElement::WrapNode(JSContext 
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED_1(HTMLDataListElement, nsGenericHTMLElement,
                                      mOptions)
 
 NS_IMPL_ADDREF_INHERITED(HTMLDataListElement, Element)
 NS_IMPL_RELEASE_INHERITED(HTMLDataListElement, Element)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(HTMLDataListElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-NS_ELEMENT_INTERFACE_MAP_END
+NS_INTERFACE_MAP_END_INHERITING(nsGenericHTMLElement)
 
 
 NS_IMPL_ELEMENT_CLONE(HTMLDataListElement)
 
 bool
 HTMLDataListElement::MatchOptions(nsIContent* aContent, int32_t aNamespaceID,
                                   nsIAtom* aAtom, void* aData)
 {
--- a/content/html/content/src/HTMLDataListElement.h
+++ b/content/html/content/src/HTMLDataListElement.h
@@ -7,38 +7,28 @@
 
 #include "mozilla/Attributes.h"
 #include "nsGenericHTMLElement.h"
 #include "nsContentList.h"
 
 namespace mozilla {
 namespace dom {
 
-class HTMLDataListElement MOZ_FINAL : public nsGenericHTMLElement,
-                                      public nsIDOMHTMLElement
+class HTMLDataListElement MOZ_FINAL : public nsGenericHTMLElement
 {
 public:
   HTMLDataListElement(already_AddRefed<nsINodeInfo> aNodeInfo)
     : nsGenericHTMLElement(aNodeInfo)
   {
   }
   virtual ~HTMLDataListElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   nsContentList* Options()
   {
     if (!mOptions) {
       mOptions = new nsContentList(this, MatchOptions, nullptr, nullptr, true);
     }
 
     return mOptions;
   }
@@ -47,18 +37,16 @@ public:
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   // This function is used to generate the nsContentList (option elements).
   static bool MatchOptions(nsIContent* aContent, int32_t aNamespaceID,
                              nsIAtom* aAtom, void* aData);
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLDataListElement,
                                            nsGenericHTMLElement)
-
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
 protected:
   virtual JSObject* WrapNode(JSContext *aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
   // <option>'s list inside the datalist element.
   nsRefPtr<nsContentList> mOptions;
 };
 
--- a/content/html/content/src/HTMLDivElement.cpp
+++ b/content/html/content/src/HTMLDivElement.cpp
@@ -15,25 +15,18 @@ NS_IMPL_NS_NEW_HTML_ELEMENT(Div)
 
 namespace mozilla {
 namespace dom {
 
 HTMLDivElement::~HTMLDivElement()
 {
 }
 
-NS_IMPL_ADDREF_INHERITED(HTMLDivElement, Element)
-NS_IMPL_RELEASE_INHERITED(HTMLDivElement, Element)
-
-// QueryInterface implementation for HTMLDivElement
-NS_INTERFACE_TABLE_HEAD(HTMLDivElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-  NS_INTERFACE_TABLE_INHERITED1(HTMLDivElement, nsIDOMHTMLDivElement)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
+NS_IMPL_ISUPPORTS_INHERITED1(HTMLDivElement, nsGenericHTMLElement,
+                             nsIDOMHTMLDivElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLDivElement)
 
 JSObject*
 HTMLDivElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aScope)
 {
   return dom::HTMLDivElementBinding::Wrap(aCx, aScope, this);
 }
--- a/content/html/content/src/HTMLDivElement.h
+++ b/content/html/content/src/HTMLDivElement.h
@@ -20,25 +20,16 @@ public:
     : nsGenericHTMLElement(aNodeInfo)
   {
   }
   virtual ~HTMLDivElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   // nsIDOMHTMLDivElement
   NS_IMETHOD GetAlign(nsAString& aAlign) MOZ_OVERRIDE
   {
     nsString align;
     GetAlign(align);
     aAlign = align;
     return NS_OK;
   }
@@ -61,18 +52,16 @@ public:
   virtual bool ParseAttribute(int32_t aNamespaceID,
                               nsIAtom* aAttribute,
                               const nsAString& aValue,
                               nsAttrValue& aResult) MOZ_OVERRIDE;
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
   virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const MOZ_OVERRIDE;
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
-
 protected:
   virtual JSObject* WrapNode(JSContext *aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 };
 
 } // namespace dom
 } // namespace mozilla
 
--- a/content/html/content/src/HTMLElement.cpp
+++ b/content/html/content/src/HTMLElement.cpp
@@ -5,64 +5,43 @@
 
 #include "nsGenericHTMLElement.h"
 #include "mozilla/dom/HTMLElementBinding.h"
 #include "nsContentUtils.h"
 
 namespace mozilla {
 namespace dom {
 
-class HTMLElement MOZ_FINAL : public nsGenericHTMLElement,
-                              public nsIDOMHTMLElement
+class HTMLElement MOZ_FINAL : public nsGenericHTMLElement
 {
 public:
   HTMLElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~HTMLElement();
 
-  // nsISupports
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
+  using nsGenericHTMLElement::GetInnerHTML;
   virtual void GetInnerHTML(nsAString& aInnerHTML,
                             mozilla::ErrorResult& aError) MOZ_OVERRIDE;
 
   virtual nsresult Clone(nsINodeInfo* aNodeInfo,
                          nsINode** aResult) const MOZ_OVERRIDE;
 
-  virtual nsIDOMNode* AsDOMNode() { return this; }
-
 protected:
   virtual JSObject* WrapNode(JSContext *aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 };
 
 HTMLElement::HTMLElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsGenericHTMLElement(aNodeInfo)
 {
 }
 
 HTMLElement::~HTMLElement()
 {
 }
 
-NS_IMPL_ADDREF_INHERITED(HTMLElement, Element)
-NS_IMPL_RELEASE_INHERITED(HTMLElement, Element)
-
-NS_INTERFACE_MAP_BEGIN(HTMLElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-NS_ELEMENT_INTERFACE_MAP_END
-
 NS_IMPL_ELEMENT_CLONE(HTMLElement)
 
 void
 HTMLElement::GetInnerHTML(nsAString& aInnerHTML, ErrorResult& aError)
 {
   /**
    * nsGenericHTMLElement::GetInnerHTML escapes < and > characters (at least).
    * .innerHTML should return the HTML code for xmp and plaintext element.
--- a/content/html/content/src/HTMLFieldSetElement.cpp
+++ b/content/html/content/src/HTMLFieldSetElement.cpp
@@ -38,22 +38,20 @@ HTMLFieldSetElement::~HTMLFieldSetElemen
 NS_IMPL_CYCLE_COLLECTION_INHERITED_2(HTMLFieldSetElement, nsGenericHTMLFormElement,
                                      mValidity, mElements)
 
 NS_IMPL_ADDREF_INHERITED(HTMLFieldSetElement, Element)
 NS_IMPL_RELEASE_INHERITED(HTMLFieldSetElement, Element)
 
 // QueryInterface implementation for HTMLFieldSetElement
 NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(HTMLFieldSetElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLFormElement)
   NS_INTERFACE_TABLE_INHERITED2(HTMLFieldSetElement,
                                 nsIDOMHTMLFieldSetElement,
                                 nsIConstraintValidation)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
+NS_INTERFACE_TABLE_TAIL_INHERITING(nsGenericHTMLFormElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLFieldSetElement)
 
 
 NS_IMPL_BOOL_ATTR(HTMLFieldSetElement, Disabled, disabled)
 NS_IMPL_STRING_ATTR(HTMLFieldSetElement, Name, name)
 
 // nsIConstraintValidation
--- a/content/html/content/src/HTMLFieldSetElement.h
+++ b/content/html/content/src/HTMLFieldSetElement.h
@@ -29,25 +29,16 @@ public:
   HTMLFieldSetElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~HTMLFieldSetElement();
 
   NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLFieldSetElement, fieldset)
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   // nsIDOMHTMLFieldSetElement
   NS_DECL_NSIDOMHTMLFIELDSETELEMENT
 
   // nsIContent
   virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
   virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
                                 const nsAttrValue* aValue, bool aNotify) MOZ_OVERRIDE;
 
@@ -56,17 +47,16 @@ public:
   virtual void RemoveChildAt(uint32_t aIndex, bool aNotify) MOZ_OVERRIDE;
 
   // nsIFormControl
   NS_IMETHOD_(uint32_t) GetType() const MOZ_OVERRIDE { return NS_FORM_FIELDSET; }
   NS_IMETHOD Reset() MOZ_OVERRIDE;
   NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission) MOZ_OVERRIDE;
   virtual bool IsDisabledForEvents(uint32_t aMessage) MOZ_OVERRIDE;
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
 
   const nsIContent* GetFirstLegend() const { return mFirstLegend; }
 
   void AddElement(nsGenericHTMLFormElement* aElement) {
     mDependentElements.AppendElement(aElement);
   }
 
   void RemoveElement(nsGenericHTMLFormElement* aElement) {
--- a/content/html/content/src/HTMLFontElement.cpp
+++ b/content/html/content/src/HTMLFontElement.cpp
@@ -22,25 +22,16 @@ HTMLFontElement::~HTMLFontElement()
 }
 
 JSObject*
 HTMLFontElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aScope)
 {
   return HTMLFontElementBinding::Wrap(aCx, aScope, this);
 }
 
-NS_IMPL_ADDREF_INHERITED(HTMLFontElement, Element)
-NS_IMPL_RELEASE_INHERITED(HTMLFontElement, Element)
-
-// QueryInterface implementation for HTMLFontElement
-NS_INTERFACE_MAP_BEGIN(HTMLFontElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-NS_ELEMENT_INTERFACE_MAP_END
-
-
 NS_IMPL_ELEMENT_CLONE(HTMLFontElement)
 
 bool
 HTMLFontElement::ParseAttribute(int32_t aNamespaceID,
                                 nsIAtom* aAttribute,
                                 const nsAString& aValue,
                                 nsAttrValue& aResult)
 {
--- a/content/html/content/src/HTMLFontElement.h
+++ b/content/html/content/src/HTMLFontElement.h
@@ -6,38 +6,25 @@
 #define HTMLFontElement_h___
 
 #include "mozilla/Attributes.h"
 #include "nsGenericHTMLElement.h"
 
 namespace mozilla {
 namespace dom {
 
-class HTMLFontElement MOZ_FINAL : public nsGenericHTMLElement,
-                                  public nsIDOMHTMLElement
+class HTMLFontElement MOZ_FINAL : public nsGenericHTMLElement
 {
 public:
   HTMLFontElement(already_AddRefed<nsINodeInfo> aNodeInfo)
     : nsGenericHTMLElement(aNodeInfo)
   {
   }
   virtual ~HTMLFontElement();
 
-  // nsISupports
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   void GetColor(nsString& aColor)
   {
     GetHTMLAttr(nsGkAtoms::color, aColor);
   }
   void SetColor(const nsAString& aColor, ErrorResult& aError)
   {
     SetHTMLAttr(nsGkAtoms::color, aColor, aError);
   }
@@ -60,17 +47,16 @@ public:
 
   virtual bool ParseAttribute(int32_t aNamespaceID,
                                 nsIAtom* aAttribute,
                                 const nsAString& aValue,
                                 nsAttrValue& aResult) MOZ_OVERRIDE;
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
   virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const MOZ_OVERRIDE;
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
 
 protected:
   virtual JSObject* WrapNode(JSContext *aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/content/html/content/src/HTMLFormElement.cpp
+++ b/content/html/content/src/HTMLFormElement.cpp
@@ -323,24 +323,22 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INH
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_IMPL_ADDREF_INHERITED(HTMLFormElement, Element)
 NS_IMPL_RELEASE_INHERITED(HTMLFormElement, Element)
 
 
 // QueryInterface implementation for HTMLFormElement
 NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(HTMLFormElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
   NS_INTERFACE_TABLE_INHERITED4(HTMLFormElement,
                                 nsIDOMHTMLFormElement,
                                 nsIForm,
                                 nsIWebProgressListener,
                                 nsIRadioGroupContainer)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
+NS_INTERFACE_TABLE_TAIL_INHERITING(nsGenericHTMLElement)
 
 
 // nsIDOMHTMLFormElement
 
 NS_IMPL_ELEMENT_CLONE_WITH_INIT(HTMLFormElement)
 
 nsIHTMLCollection*
 HTMLFormElement::Elements()
@@ -1855,35 +1853,34 @@ HTMLFormElement::CheckFormValidity(nsIMu
     return false;
   }
 
   uint32_t len = sortedControls.Length();
 
   // Hold a reference to the elements so they can't be deleted while calling
   // the invalid events.
   for (uint32_t i = 0; i < len; ++i) {
-    static_cast<nsGenericHTMLElement*>(sortedControls[i])->AddRef();
+    sortedControls[i]->AddRef();
   }
 
   for (uint32_t i = 0; i < len; ++i) {
-    nsCOMPtr<nsIConstraintValidation> cvElmt =
-      do_QueryInterface((nsGenericHTMLElement*)sortedControls[i]);
+    nsCOMPtr<nsIConstraintValidation> cvElmt = do_QueryObject(sortedControls[i]);
     if (cvElmt && cvElmt->IsCandidateForConstraintValidation() &&
         !cvElmt->IsValid()) {
       ret = false;
       bool defaultAction = true;
       nsContentUtils::DispatchTrustedEvent(sortedControls[i]->OwnerDoc(),
                                            static_cast<nsIContent*>(sortedControls[i]),
                                            NS_LITERAL_STRING("invalid"),
                                            false, true, &defaultAction);
 
       // Add all unhandled invalid controls to aInvalidElements if the caller
       // requested them.
       if (defaultAction && aInvalidElements) {
-        aInvalidElements->AppendElement((nsGenericHTMLElement*)sortedControls[i],
+        aInvalidElements->AppendElement(ToSupports(sortedControls[i]),
                                         false);
       }
     }
   }
 
   // Release the references.
   for (uint32_t i = 0; i < len; ++i) {
     static_cast<nsGenericHTMLElement*>(sortedControls[i])->Release();
--- a/content/html/content/src/HTMLFormElement.h
+++ b/content/html/content/src/HTMLFormElement.h
@@ -47,25 +47,16 @@ public:
   HTMLFormElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~HTMLFormElement();
 
   nsresult Init();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   // nsIDOMHTMLFormElement
   NS_DECL_NSIDOMHTMLFORMELEMENT
 
   // nsIWebProgressListener
   NS_DECL_NSIWEBPROGRESSLISTENER
 
   // nsIForm
   NS_IMETHOD_(nsIFormControl*) GetElementAt(int32_t aIndex) const;
@@ -277,18 +268,16 @@ public:
    *
    * @return Whether the form is valid.
    *
    * @note Do not call this method if novalidate/formnovalidate is used.
    * @note This method might disappear with bug 592124, hopefuly.
    */
   bool CheckValidFormSubmission();
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
-
   /**
    * Walk over the form elements and call SubmitNamesValues() on them to get
    * their data pumped into the FormSubmitter.
    *
    * @param aFormSubmission the form submission object
    */
   nsresult WalkFormElements(nsFormSubmission* aFormSubmission);
 
--- a/content/html/content/src/HTMLFrameElement.cpp
+++ b/content/html/content/src/HTMLFrameElement.cpp
@@ -20,27 +20,18 @@ HTMLFrameElement::HTMLFrameElement(alrea
 {
 }
 
 HTMLFrameElement::~HTMLFrameElement()
 {
 }
 
 
-NS_IMPL_ADDREF_INHERITED(HTMLFrameElement, Element)
-NS_IMPL_RELEASE_INHERITED(HTMLFrameElement, Element)
-
-
-// QueryInterface implementation for HTMLFrameElement
-NS_INTERFACE_TABLE_HEAD(HTMLFrameElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLFrameElement)
-  NS_INTERFACE_TABLE_INHERITED1(HTMLFrameElement, nsIDOMHTMLFrameElement)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
-
+NS_IMPL_ISUPPORTS_INHERITED1(HTMLFrameElement, nsGenericHTMLFrameElement,
+                             nsIDOMHTMLFrameElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLFrameElement)
 
 
 NS_IMPL_STRING_ATTR(HTMLFrameElement, FrameBorder, frameborder)
 NS_IMPL_URI_ATTR(HTMLFrameElement, LongDesc, longdesc)
 NS_IMPL_STRING_ATTR(HTMLFrameElement, MarginHeight, marginheight)
 NS_IMPL_STRING_ATTR(HTMLFrameElement, MarginWidth, marginwidth)
--- a/content/html/content/src/HTMLFrameElement.h
+++ b/content/html/content/src/HTMLFrameElement.h
@@ -24,37 +24,27 @@ public:
 
   HTMLFrameElement(already_AddRefed<nsINodeInfo> aNodeInfo,
                    FromParser aFromParser = NOT_FROM_PARSER);
   virtual ~HTMLFrameElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   // nsIDOMHTMLFrameElement
   NS_DECL_NSIDOMHTMLFRAMEELEMENT
 
   // nsIContent
   virtual bool ParseAttribute(int32_t aNamespaceID,
                               nsIAtom* aAttribute,
                               const nsAString& aValue,
                               nsAttrValue& aResult) MOZ_OVERRIDE;
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
   nsMapRuleToAttributesFunc GetAttributeMappingFunction() const MOZ_OVERRIDE;
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
 
   // WebIDL API
   // The XPCOM GetFrameBorder is OK for us
   void SetFrameBorder(const nsAString& aFrameBorder, ErrorResult& aError)
   {
     SetHTMLAttr(nsGkAtoms::frameborder, aFrameBorder, aError);
   }
 
--- a/content/html/content/src/HTMLFrameSetElement.cpp
+++ b/content/html/content/src/HTMLFrameSetElement.cpp
@@ -18,27 +18,18 @@ HTMLFrameSetElement::~HTMLFrameSetElemen
 }
 
 JSObject*
 HTMLFrameSetElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aScope)
 {
   return HTMLFrameSetElementBinding::Wrap(aCx, aScope, this);
 }
 
-NS_IMPL_ADDREF_INHERITED(HTMLFrameSetElement, Element)
-NS_IMPL_RELEASE_INHERITED(HTMLFrameSetElement, Element)
-
-// QueryInterface implementation for HTMLFrameSetElement
-NS_INTERFACE_TABLE_HEAD(HTMLFrameSetElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-  NS_INTERFACE_TABLE_INHERITED1(HTMLFrameSetElement,
-                                nsIDOMHTMLFrameSetElement)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
-
+NS_IMPL_ISUPPORTS_INHERITED1(HTMLFrameSetElement, nsGenericHTMLElement,
+                             nsIDOMHTMLFrameSetElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLFrameSetElement)
 
 NS_IMETHODIMP 
 HTMLFrameSetElement::SetCols(const nsAString& aCols)
 {
   ErrorResult rv;
   SetCols(aCols, rv);
--- a/content/html/content/src/HTMLFrameSetElement.h
+++ b/content/html/content/src/HTMLFrameSetElement.h
@@ -55,25 +55,16 @@ public:
   }
   virtual ~HTMLFrameSetElement();
 
   NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLFrameSetElement, frameset)
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   // nsIDOMHTMLFrameSetElement
   NS_DECL_NSIDOMHTMLFRAMESETELEMENT
 
   void GetCols(nsString& aCols)
   {
     GetHTMLAttr(nsGkAtoms::cols, aCols);
   }
   void SetCols(const nsAString& aCols, ErrorResult& aError)
@@ -143,17 +134,16 @@ public:
   virtual bool ParseAttribute(int32_t aNamespaceID,
                                 nsIAtom* aAttribute,
                                 const nsAString& aValue,
                                 nsAttrValue& aResult) MOZ_OVERRIDE;
   virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
                                               int32_t aModType) const MOZ_OVERRIDE;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
 
 protected:
   virtual JSObject* WrapNode(JSContext *aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
 private:
   nsresult ParseRowCol(const nsAString& aValue,
                        int32_t&         aNumSpecs,
--- a/content/html/content/src/HTMLHRElement.cpp
+++ b/content/html/content/src/HTMLHRElement.cpp
@@ -15,27 +15,18 @@ HTMLHRElement::HTMLHRElement(already_Add
   : nsGenericHTMLElement(aNodeInfo)
 {
 }
 
 HTMLHRElement::~HTMLHRElement()
 {
 }
 
-NS_IMPL_ADDREF_INHERITED(HTMLHRElement, Element)
-NS_IMPL_RELEASE_INHERITED(HTMLHRElement, Element)
-
-// QueryInterface implementation for HTMLHRElement
-NS_INTERFACE_TABLE_HEAD(HTMLHRElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-  NS_INTERFACE_TABLE_INHERITED1(HTMLHRElement,
-                                nsIDOMHTMLHRElement)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
-
+NS_IMPL_ISUPPORTS_INHERITED1(HTMLHRElement, nsGenericHTMLElement,
+                             nsIDOMHTMLHRElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLHRElement)
 
 
 NS_IMPL_STRING_ATTR(HTMLHRElement, Align, align)
 NS_IMPL_BOOL_ATTR(HTMLHRElement, NoShade, noshade)
 NS_IMPL_STRING_ATTR(HTMLHRElement, Size, size)
 NS_IMPL_STRING_ATTR(HTMLHRElement, Width, width)
--- a/content/html/content/src/HTMLHRElement.h
+++ b/content/html/content/src/HTMLHRElement.h
@@ -21,36 +21,26 @@ class HTMLHRElement MOZ_FINAL : public n
 {
 public:
   HTMLHRElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~HTMLHRElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   // nsIDOMHTMLHRElement
   NS_DECL_NSIDOMHTMLHRELEMENT
 
   virtual bool ParseAttribute(int32_t aNamespaceID,
                               nsIAtom* aAttribute,
                               const nsAString& aValue,
                               nsAttrValue& aResult) MOZ_OVERRIDE;
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
   virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const MOZ_OVERRIDE;
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
 
   // WebIDL API
   void SetAlign(const nsAString& aAlign, ErrorResult& aError)
   {
     SetHTMLAttr(nsGkAtoms::align, aAlign, aError);
   }
 
   // The XPCOM GetColor is OK for us
--- a/content/html/content/src/HTMLHeadingElement.cpp
+++ b/content/html/content/src/HTMLHeadingElement.cpp
@@ -17,27 +17,18 @@ NS_IMPL_NS_NEW_HTML_ELEMENT(Heading)
 
 namespace mozilla {
 namespace dom {
 
 HTMLHeadingElement::~HTMLHeadingElement()
 {
 }
 
-NS_IMPL_ADDREF_INHERITED(HTMLHeadingElement, Element)
-NS_IMPL_RELEASE_INHERITED(HTMLHeadingElement, Element)
-
-// QueryInterface implementation for HTMLHeadingElement
-NS_INTERFACE_TABLE_HEAD(HTMLHeadingElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-  NS_INTERFACE_TABLE_INHERITED1(HTMLHeadingElement,
-                                nsIDOMHTMLHeadingElement)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
-
+NS_IMPL_ISUPPORTS_INHERITED1(HTMLHeadingElement, nsGenericHTMLElement,
+                             nsIDOMHTMLHeadingElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLHeadingElement)
 
 JSObject*
 HTMLHeadingElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aScope)
 {
   return HTMLHeadingElementBinding::Wrap(aCx, aScope, this);
 }
--- a/content/html/content/src/HTMLHeadingElement.h
+++ b/content/html/content/src/HTMLHeadingElement.h
@@ -21,36 +21,26 @@ public:
     : nsGenericHTMLElement(aNodeInfo)
   {
   }
   virtual ~HTMLHeadingElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   // nsIDOMHTMLHeadingElement
   NS_DECL_NSIDOMHTMLHEADINGELEMENT
 
   virtual bool ParseAttribute(int32_t aNamespaceID,
                               nsIAtom* aAttribute,
                               const nsAString& aValue,
                               nsAttrValue& aResult) MOZ_OVERRIDE;
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
   nsMapRuleToAttributesFunc GetAttributeMappingFunction() const MOZ_OVERRIDE;
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
 
   // The XPCOM versions of GetAlign and SetAlign are fine for us for
   // use from WebIDL.
 
 protected:
   virtual JSObject* WrapNode(JSContext *aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 };
--- a/content/html/content/src/HTMLIFrameElement.cpp
+++ b/content/html/content/src/HTMLIFrameElement.cpp
@@ -24,26 +24,18 @@ HTMLIFrameElement::HTMLIFrameElement(alr
   : nsGenericHTMLFrameElement(aNodeInfo, aFromParser)
 {
 }
 
 HTMLIFrameElement::~HTMLIFrameElement()
 {
 }
 
-NS_IMPL_ADDREF_INHERITED(HTMLIFrameElement, Element)
-NS_IMPL_RELEASE_INHERITED(HTMLIFrameElement, Element)
-
-// QueryInterface implementation for HTMLIFrameElement
-NS_INTERFACE_TABLE_HEAD(HTMLIFrameElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLFrameElement)
-  NS_INTERFACE_TABLE_INHERITED1(HTMLIFrameElement,
-                                nsIDOMHTMLIFrameElement)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
+NS_IMPL_ISUPPORTS_INHERITED1(HTMLIFrameElement, nsGenericHTMLFrameElement,
+                             nsIDOMHTMLIFrameElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLIFrameElement)
 
 NS_IMPL_STRING_ATTR(HTMLIFrameElement, Align, align)
 NS_IMPL_STRING_ATTR(HTMLIFrameElement, FrameBorder, frameborder)
 NS_IMPL_STRING_ATTR(HTMLIFrameElement, Height, height)
 NS_IMPL_URI_ATTR(HTMLIFrameElement, LongDesc, longdesc)
 NS_IMPL_STRING_ATTR(HTMLIFrameElement, MarginHeight, marginheight)
--- a/content/html/content/src/HTMLIFrameElement.h
+++ b/content/html/content/src/HTMLIFrameElement.h
@@ -21,38 +21,28 @@ public:
                     FromParser aFromParser = NOT_FROM_PARSER);
   virtual ~HTMLIFrameElement();
 
   NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLIFrameElement, iframe)
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   // nsIDOMHTMLIFrameElement
   NS_DECL_NSIDOMHTMLIFRAMEELEMENT
 
   // nsIContent
   virtual bool ParseAttribute(int32_t aNamespaceID,
                                 nsIAtom* aAttribute,
                                 const nsAString& aValue,
                                 nsAttrValue& aResult) MOZ_OVERRIDE;
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
   virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const MOZ_OVERRIDE;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
 
   nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
                    const nsAString& aValue, bool aNotify)
   {
     return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify);
   }
   virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
                            nsIAtom* aPrefix, const nsAString& aValue,
--- a/content/html/content/src/HTMLImageElement.cpp
+++ b/content/html/content/src/HTMLImageElement.cpp
@@ -61,24 +61,22 @@ HTMLImageElement::~HTMLImageElement()
 
 
 NS_IMPL_ADDREF_INHERITED(HTMLImageElement, Element)
 NS_IMPL_RELEASE_INHERITED(HTMLImageElement, Element)
 
 
 // QueryInterface implementation for HTMLImageElement
 NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(HTMLImageElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
   NS_INTERFACE_TABLE_INHERITED4(HTMLImageElement,
                                 nsIDOMHTMLImageElement,
                                 nsIImageLoadingContent,
                                 imgIOnloadBlocker,
                                 imgINotificationObserver)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
+NS_INTERFACE_TABLE_TAIL_INHERITING(nsGenericHTMLElement)
 
 
 NS_IMPL_ELEMENT_CLONE(HTMLImageElement)
 
 
 NS_IMPL_STRING_ATTR(HTMLImageElement, Name, name)
 NS_IMPL_STRING_ATTR(HTMLImageElement, Align, align)
 NS_IMPL_STRING_ATTR(HTMLImageElement, Alt, alt)
--- a/content/html/content/src/HTMLImageElement.h
+++ b/content/html/content/src/HTMLImageElement.h
@@ -26,25 +26,16 @@ public:
 
   static already_AddRefed<HTMLImageElement>
     Image(const GlobalObject& aGlobal, const Optional<uint32_t>& aWidth,
           const Optional<uint32_t>& aHeight, ErrorResult& aError);
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   virtual bool Draggable() const MOZ_OVERRIDE;
 
   // nsIDOMHTMLImageElement
   NS_DECL_NSIDOMHTMLIMAGEELEMENT
 
   // override from nsImageLoadingContent
   CORSMode GetCORSMode();
 
@@ -81,17 +72,16 @@ public:
   virtual void UnbindFromTree(bool aDeep, bool aNullParent) MOZ_OVERRIDE;
 
   virtual nsEventStates IntrinsicState() const MOZ_OVERRIDE;
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   nsresult CopyInnerTo(Element* aDest);
 
   void MaybeLoadImage();
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
 
   bool IsMap()
   {
     return GetBoolAttr(nsGkAtoms::ismap);
   }
   void SetIsMap(bool aIsMap, ErrorResult& aError)
   {
     SetHTMLBoolAttr(nsGkAtoms::ismap, aIsMap, aError);
--- a/content/html/content/src/HTMLInputElement.cpp
+++ b/content/html/content/src/HTMLInputElement.cpp
@@ -849,28 +849,26 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_IN
   //XXX should unlink more?
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_ADDREF_INHERITED(HTMLInputElement, Element)
 NS_IMPL_RELEASE_INHERITED(HTMLInputElement, Element)
 
 // QueryInterface implementation for HTMLInputElement
 NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(HTMLInputElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLFormElementWithState)
   NS_INTERFACE_TABLE_INHERITED8(HTMLInputElement,
                                 nsIDOMHTMLInputElement,
                                 nsITextControlElement,
                                 nsIPhonetic,
                                 imgINotificationObserver,
                                 nsIImageLoadingContent,
                                 imgIOnloadBlocker,
                                 nsIDOMNSEditableElement,
                                 nsIConstraintValidation)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
+NS_INTERFACE_TABLE_TAIL_INHERITING(nsGenericHTMLFormElementWithState)
 
 // nsIConstraintValidation
 NS_IMPL_NSICONSTRAINTVALIDATION_EXCEPT_SETCUSTOMVALIDITY(HTMLInputElement)
 
 // nsIDOMNode
 
 nsresult
 HTMLInputElement::Clone(nsINodeInfo* aNodeInfo, nsINode** aResult) const
@@ -3114,17 +3112,18 @@ HTMLInputElement::PostHandleEvent(nsEven
                 nsAutoString name;
                 GetAttr(kNameSpaceID_None, nsGkAtoms::name, name);
                 nsCOMPtr<nsIDOMHTMLInputElement> selectedRadioButton;
                 container->GetNextRadioButton(name, isMovingBack, this,
                                               getter_AddRefs(selectedRadioButton));
                 nsCOMPtr<nsIContent> radioContent =
                   do_QueryInterface(selectedRadioButton);
                 if (radioContent) {
-                  rv = selectedRadioButton->Focus();
+                  nsCOMPtr<nsIDOMHTMLElement> elem = do_QueryInterface(selectedRadioButton);
+                  rv = elem->Focus();
                   if (NS_SUCCEEDED(rv)) {
                     nsEventStatus status = nsEventStatus_eIgnore;
                     nsMouseEvent event(aVisitor.mEvent->mFlags.mIsTrusted,
                                        NS_MOUSE_CLICK, nullptr,
                                        nsMouseEvent::eReal);
                     event.inputSource = nsIDOMMouseEvent::MOZ_SOURCE_KEYBOARD;
                     rv = nsEventDispatcher::Dispatch(radioContent,
                                                      aVisitor.mPresContext,
--- a/content/html/content/src/HTMLInputElement.h
+++ b/content/html/content/src/HTMLInputElement.h
@@ -96,25 +96,18 @@ public:
                    mozilla::dom::FromParser aFromParser);
   virtual ~HTMLInputElement();
 
   NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLInputElement, input)
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
   virtual int32_t TabIndexDefault() MOZ_OVERRIDE;
+  using nsGenericHTMLElement::Focus;
   virtual void Focus(ErrorResult& aError) MOZ_OVERRIDE;
 
   // nsIDOMHTMLInputElement
   NS_DECL_NSIDOMHTMLINPUTELEMENT
 
   // nsIPhonetic
   NS_DECL_NSIPHONETIC
 
@@ -228,18 +221,16 @@ public:
   static UploadLastDir* gUploadLastDir;
   // create and destroy the static UploadLastDir object for remembering
   // which directory was last used on a site-by-site basis
   static void InitUploadLastDir();
   static void DestroyUploadLastDir();
 
   void MaybeLoadImage();
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
-
   // nsIConstraintValidation
   bool     IsTooLong();
   bool     IsValueMissing() const;
   bool     HasTypeMismatch() const;
   bool     HasPatternMismatch() const;
   bool     IsRangeOverflow() const;
   bool     IsRangeUnderflow() const;
   bool     HasStepMismatch() const;
--- a/content/html/content/src/HTMLLIElement.cpp
+++ b/content/html/content/src/HTMLLIElement.cpp
@@ -16,26 +16,18 @@ NS_IMPL_NS_NEW_HTML_ELEMENT(LI)
 
 namespace mozilla {
 namespace dom {
 
 HTMLLIElement::~HTMLLIElement()
 {
 }
 
-NS_IMPL_ADDREF_INHERITED(HTMLLIElement, Element)
-NS_IMPL_RELEASE_INHERITED(HTMLLIElement, Element)
-
-
-// QueryInterface implementation for nsHTMLLIElement
-NS_INTERFACE_TABLE_HEAD(HTMLLIElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-  NS_INTERFACE_TABLE_INHERITED1(HTMLLIElement, nsIDOMHTMLLIElement)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
+NS_IMPL_ISUPPORTS_INHERITED1(HTMLLIElement, nsGenericHTMLElement,
+                             nsIDOMHTMLLIElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLLIElement)
 
 NS_IMPL_STRING_ATTR(HTMLLIElement, Type, type)
 NS_IMPL_INT_ATTR(HTMLLIElement, Value, value)
 
 // values that are handled case-insensitively
 static const nsAttrValue::EnumTable kUnorderedListItemTypeTable[] = {
--- a/content/html/content/src/HTMLLIElement.h
+++ b/content/html/content/src/HTMLLIElement.h
@@ -22,36 +22,26 @@ public:
     : nsGenericHTMLElement(aNodeInfo)
   {
   }
   virtual ~HTMLLIElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   // nsIDOMHTMLLIElement
   NS_DECL_NSIDOMHTMLLIELEMENT
 
   virtual bool ParseAttribute(int32_t aNamespaceID,
                                 nsIAtom* aAttribute,
                                 const nsAString& aValue,
                                 nsAttrValue& aResult) MOZ_OVERRIDE;
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
   virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const MOZ_OVERRIDE;
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
 
   // WebIDL API
   void GetType(nsString& aType)
   {
     GetHTMLAttr(nsGkAtoms::type, aType);
   }
   void SetType(const nsAString& aType, mozilla::ErrorResult& rv)
   {
--- a/content/html/content/src/HTMLLabelElement.cpp
+++ b/content/html/content/src/HTMLLabelElement.cpp
@@ -25,43 +25,33 @@ HTMLLabelElement::~HTMLLabelElement()
 JSObject*
 HTMLLabelElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aScope)
 {
   return HTMLLabelElementBinding::Wrap(aCx, aScope, this);
 }
 
 // nsISupports
 
-
-NS_IMPL_ADDREF_INHERITED(HTMLLabelElement, Element)
-NS_IMPL_RELEASE_INHERITED(HTMLLabelElement, Element)
-
-// QueryInterface implementation for HTMLLabelElement
-NS_INTERFACE_TABLE_HEAD(HTMLLabelElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLFormElement)
-  NS_INTERFACE_TABLE_INHERITED1(HTMLLabelElement,
-                                nsIDOMHTMLLabelElement)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
-
+NS_IMPL_ISUPPORTS_INHERITED1(HTMLLabelElement, nsGenericHTMLFormElement,
+                             nsIDOMHTMLLabelElement)
 
 // nsIDOMHTMLLabelElement
 
 NS_IMPL_ELEMENT_CLONE(HTMLLabelElement)
 
 NS_IMETHODIMP
 HTMLLabelElement::GetForm(nsIDOMHTMLFormElement** aForm)
 {
   return nsGenericHTMLFormElement::GetForm(aForm);
 }
 
 NS_IMETHODIMP
 HTMLLabelElement::GetControl(nsIDOMHTMLElement** aElement)
 {
-  nsCOMPtr<nsIDOMHTMLElement> element = do_QueryInterface(GetLabeledElement());
+  nsCOMPtr<nsIDOMHTMLElement> element = do_QueryObject(GetLabeledElement());
   element.forget(aElement);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HTMLLabelElement::SetHtmlFor(const nsAString& aHtmlFor)
 {
   ErrorResult rv;
@@ -79,17 +69,17 @@ HTMLLabelElement::GetHtmlFor(nsAString& 
 }
 
 void
 HTMLLabelElement::Focus(ErrorResult& aError)
 {
   // retarget the focus method at the for content
   nsIFocusManager* fm = nsFocusManager::GetFocusManager();
   if (fm) {
-    nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(GetLabeledElement());
+    nsCOMPtr<nsIDOMElement> elem = do_QueryObject(GetLabeledElement());
     if (elem)
       fm->SetFocus(elem, 0);
   }
 }
 
 static bool
 EventTargetIn(nsEvent *aEvent, nsIContent *aChild, nsIContent *aStop)
 {
--- a/content/html/content/src/HTMLLabelElement.h
+++ b/content/html/content/src/HTMLLabelElement.h
@@ -27,59 +27,49 @@ public:
   }
   virtual ~HTMLLabelElement();
 
   NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLLabelElement, label)
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
   // nsIDOMHTMLLabelElement
   NS_DECL_NSIDOMHTMLLABELELEMENT
 
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   using nsGenericHTMLFormElement::GetForm;
   void GetHtmlFor(nsString& aHtmlFor)
   {
     GetHTMLAttr(nsGkAtoms::_for, aHtmlFor);
   }
   void SetHtmlFor(const nsAString& aHtmlFor, ErrorResult& aError)
   {
     SetHTMLAttr(nsGkAtoms::_for, aHtmlFor, aError);
   }
   nsGenericHTMLElement* GetControl() const
   {
     return GetLabeledElement();
   }
 
+  using nsGenericHTMLElement::Focus;
   virtual void Focus(mozilla::ErrorResult& aError) MOZ_OVERRIDE;
 
   // nsIFormControl
   NS_IMETHOD_(uint32_t) GetType() const MOZ_OVERRIDE { return NS_FORM_LABEL; }
   NS_IMETHOD Reset() MOZ_OVERRIDE;
   NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission) MOZ_OVERRIDE;
 
   virtual bool IsDisabled() const MOZ_OVERRIDE { return false; }
 
   // nsIContent
   virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor) MOZ_OVERRIDE;
   virtual void PerformAccesskey(bool aKeyCausesActivation,
                                 bool aIsTrustedEvent) MOZ_OVERRIDE;
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
-
   nsGenericHTMLElement* GetLabeledElement() const;
 protected:
   virtual JSObject* WrapNode(JSContext *aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
   nsGenericHTMLElement* GetFirstLabelableDescendant() const;
 
   // XXX It would be nice if we could use an event flag instead.
--- a/content/html/content/src/HTMLLegendElement.cpp
+++ b/content/html/content/src/HTMLLegendElement.cpp
@@ -14,27 +14,16 @@ NS_IMPL_NS_NEW_HTML_ELEMENT(Legend)
 namespace mozilla {
 namespace dom {
 
 
 HTMLLegendElement::~HTMLLegendElement()
 {
 }
 
-
-NS_IMPL_ADDREF_INHERITED(HTMLLegendElement, Element)
-NS_IMPL_RELEASE_INHERITED(HTMLLegendElement, Element)
-
-
-// QueryInterface implementation for HTMLLegendElement
-NS_INTERFACE_MAP_BEGIN(HTMLLegendElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-NS_ELEMENT_INTERFACE_MAP_END
-
-
 NS_IMPL_ELEMENT_CLONE(HTMLLegendElement)
 
 // this contains center, because IE4 does
 static const nsAttrValue::EnumTable kAlignTable[] = {
   { "left", NS_STYLE_TEXT_ALIGN_LEFT },
   { "right", NS_STYLE_TEXT_ALIGN_RIGHT },
   { "center", NS_STYLE_TEXT_ALIGN_CENTER },
   { "bottom", NS_STYLE_VERTICAL_ALIGN_BOTTOM },
--- a/content/html/content/src/HTMLLegendElement.h
+++ b/content/html/content/src/HTMLLegendElement.h
@@ -8,40 +8,28 @@
 
 #include "mozilla/Attributes.h"
 #include "nsGenericHTMLElement.h"
 #include "mozilla/dom/HTMLFormElement.h"
 
 namespace mozilla {
 namespace dom {
 
-class HTMLLegendElement MOZ_FINAL : public nsGenericHTMLElement,
-                                    public nsIDOMHTMLElement
+class HTMLLegendElement MOZ_FINAL : public nsGenericHTMLElement
 {
 public:
   HTMLLegendElement(already_AddRefed<nsINodeInfo> aNodeInfo)
     : nsGenericHTMLElement(aNodeInfo)
   {
   }
   virtual ~HTMLLegendElement();
 
   NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLLegendElement, legend)
 
-  // nsISupports
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
+  using nsGenericHTMLElement::Focus;
   virtual void Focus(ErrorResult& aError) MOZ_OVERRIDE;
 
   virtual void PerformAccesskey(bool aKeyCausesActivation,
                                 bool aIsTrustedEvent) MOZ_OVERRIDE;
 
   // nsIContent
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
@@ -69,18 +57,16 @@ public:
 
   Element* GetFormElement()
   {
     nsCOMPtr<nsIFormControl> fieldsetControl = do_QueryInterface(GetFieldSet());
 
     return fieldsetControl ? fieldsetControl->GetFormElement() : nullptr;
   }
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
-
   /**
    * WebIDL Interface
    */
 
   already_AddRefed<HTMLFormElement> GetForm();
 
   void GetAlign(nsAString& aAlign)
   {
--- a/content/html/content/src/HTMLLinkElement.cpp
+++ b/content/html/content/src/HTMLLinkElement.cpp
@@ -10,17 +10,16 @@
 #include "mozilla/MemoryReporting.h"
 #include "nsAsyncDOMEvent.h"
 #include "nsContentUtils.h"
 #include "nsGenericHTMLElement.h"
 #include "nsGkAtoms.h"
 #include "nsIDocument.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMStyleSheet.h"
-#include "nsILink.h"
 #include "nsIStyleSheet.h"
 #include "nsIStyleSheetLinkingElement.h"
 #include "nsIURL.h"
 #include "nsNetUtil.h"
 #include "nsPIDOMWindow.h"
 #include "nsReadableUtils.h"
 #include "nsStyleConsts.h"
 #include "nsUnicharUtils.h"
@@ -53,25 +52,22 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_IN
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_ADDREF_INHERITED(HTMLLinkElement, Element)
 NS_IMPL_RELEASE_INHERITED(HTMLLinkElement, Element)
 
 
 // QueryInterface implementation for HTMLLinkElement
 NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(HTMLLinkElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-  NS_INTERFACE_TABLE_INHERITED5(HTMLLinkElement,
+  NS_INTERFACE_TABLE_INHERITED4(HTMLLinkElement,
                                 nsIDOMHTMLLinkElement,
                                 nsIDOMLinkStyle,
-                                nsILink,
                                 nsIStyleSheetLinkingElement,
                                 Link)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
+NS_INTERFACE_TABLE_TAIL_INHERITING(nsGenericHTMLElement)
 
 
 NS_IMPL_ELEMENT_CLONE(HTMLLinkElement)
 
 bool
 HTMLLinkElement::Disabled()
 {
   nsCSSStyleSheet* ss = GetSheet();
@@ -144,28 +140,26 @@ HTMLLinkElement::BindToTree(nsIDocument*
   void (HTMLLinkElement::*update)() = &HTMLLinkElement::UpdateStyleSheetInternal;
   nsContentUtils::AddScriptRunner(NS_NewRunnableMethod(this, update));
 
   CreateAndDispatchEvent(aDocument, NS_LITERAL_STRING("DOMLinkAdded"));
 
   return rv;
 }
 
-NS_IMETHODIMP
+void
 HTMLLinkElement::LinkAdded()
 {
   CreateAndDispatchEvent(OwnerDoc(), NS_LITERAL_STRING("DOMLinkAdded"));
-  return NS_OK;
 }
 
-NS_IMETHODIMP
+void
 HTMLLinkElement::LinkRemoved()
 {
   CreateAndDispatchEvent(OwnerDoc(), NS_LITERAL_STRING("DOMLinkRemoved"));
-  return NS_OK;
 }
 
 void
 HTMLLinkElement::UnbindFromTree(bool aDeep, bool aNullParent)
 {
   // If this link is ever reinserted into a document, it might
   // be under a different xml:base, so forget the cached state now.
   Link::ResetLinkState(false, Link::ElementHasHref());
--- a/content/html/content/src/HTMLLinkElement.h
+++ b/content/html/content/src/HTMLLinkElement.h
@@ -5,65 +5,52 @@
 
 #ifndef mozilla_dom_HTMLLinkElement_h
 #define mozilla_dom_HTMLLinkElement_h
 
 #include "mozilla/Attributes.h"
 #include "mozilla/dom/Link.h"
 #include "nsGenericHTMLElement.h"
 #include "nsIDOMHTMLLinkElement.h"
-#include "nsILink.h"
 #include "nsStyleLinkElement.h"
 
 namespace mozilla {
 namespace dom {
 
 class HTMLLinkElement MOZ_FINAL : public nsGenericHTMLElement,
                                   public nsIDOMHTMLLinkElement,
-                                  public nsILink,
                                   public nsStyleLinkElement,
                                   public Link
 {
 public:
   HTMLLinkElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~HTMLLinkElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // CC
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLLinkElement,
                                            nsGenericHTMLElement)
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   // nsIDOMHTMLLinkElement
   NS_DECL_NSIDOMHTMLLINKELEMENT
 
   // DOM memory reporter participant
   NS_DECL_SIZEOF_EXCLUDING_THIS
 
-  // nsILink
-  NS_IMETHOD    LinkAdded() MOZ_OVERRIDE;
-  NS_IMETHOD    LinkRemoved() MOZ_OVERRIDE;
+  void LinkAdded();
+  void LinkRemoved();
 
   // nsIDOMEventTarget
   virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
   virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor) MOZ_OVERRIDE;
 
   // nsINode
   virtual nsresult Clone(nsINodeInfo* aNodeInfo, nsINode** aResult) const MOZ_OVERRIDE;
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
   virtual JSObject* WrapNode(JSContext* aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
   // nsIContent
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               bool aCompileEventHandlers) MOZ_OVERRIDE;
   virtual void UnbindFromTree(bool aDeep = true,
--- a/content/html/content/src/HTMLMapElement.cpp
+++ b/content/html/content/src/HTMLMapElement.cpp
@@ -28,20 +28,18 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_ADDREF_INHERITED(HTMLMapElement, Element)
 NS_IMPL_RELEASE_INHERITED(HTMLMapElement, Element)
 
 
 // QueryInterface implementation for HTMLMapElement
 NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(HTMLMapElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
   NS_INTERFACE_TABLE_INHERITED1(HTMLMapElement, nsIDOMHTMLMapElement)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
+NS_INTERFACE_TABLE_TAIL_INHERITING(nsGenericHTMLElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLMapElement)
 
 
 nsIHTMLCollection*
 HTMLMapElement::Areas()
 {
   if (!mAreas) {
--- a/content/html/content/src/HTMLMapElement.h
+++ b/content/html/content/src/HTMLMapElement.h
@@ -21,35 +21,24 @@ class HTMLMapElement MOZ_FINAL : public 
                                  public nsIDOMHTMLMapElement
 {
 public:
   HTMLMapElement(already_AddRefed<nsINodeInfo> aNodeInfo);
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   // nsIDOMHTMLMapElement
   NS_DECL_NSIDOMHTMLMAPELEMENT
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(HTMLMapElement,
                                                      nsGenericHTMLElement)
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
-
   // XPCOM GetName is fine.
   void SetName(const nsAString& aName, ErrorResult& aError)
   {
     SetHTMLAttr(nsGkAtoms::name, aName, aError);
   }
   nsIHTMLCollection* Areas();
 
   virtual JSObject* WrapNode(JSContext* aCx,
--- a/content/html/content/src/HTMLMenuElement.cpp
+++ b/content/html/content/src/HTMLMenuElement.cpp
@@ -45,29 +45,18 @@ HTMLMenuElement::HTMLMenuElement(already
   : nsGenericHTMLElement(aNodeInfo), mType(MENU_TYPE_LIST)
 {
 }
 
 HTMLMenuElement::~HTMLMenuElement()
 {
 }
 
-
-NS_IMPL_ADDREF_INHERITED(HTMLMenuElement, Element)
-NS_IMPL_RELEASE_INHERITED(HTMLMenuElement, Element)
-
-
-// QueryInterface implementation for HTMLMenuElement
-NS_INTERFACE_TABLE_HEAD(HTMLMenuElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-  NS_INTERFACE_TABLE_INHERITED2(HTMLMenuElement,
-                                nsIDOMHTMLMenuElement,
-                                nsIHTMLMenu)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
+NS_IMPL_ISUPPORTS_INHERITED2(HTMLMenuElement, nsGenericHTMLElement,
+                             nsIDOMHTMLMenuElement, nsIHTMLMenu)
 
 NS_IMPL_ELEMENT_CLONE(HTMLMenuElement)
 
 NS_IMPL_BOOL_ATTR(HTMLMenuElement, Compact, compact)
 NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(HTMLMenuElement, Type, type,
                                 kMenuDefaultType->tag)
 NS_IMPL_STRING_ATTR(HTMLMenuElement, Label, label)
 
--- a/content/html/content/src/HTMLMenuElement.h
+++ b/content/html/content/src/HTMLMenuElement.h
@@ -22,40 +22,29 @@ public:
   HTMLMenuElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~HTMLMenuElement();
 
   NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLMenuElement, menu)
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   // nsIDOMHTMLMenuElement
   NS_DECL_NSIDOMHTMLMENUELEMENT
 
   // nsIHTMLMenu
   NS_DECL_NSIHTMLMENU
 
   virtual bool ParseAttribute(int32_t aNamespaceID,
                                 nsIAtom* aAttribute,
                                 const nsAString& aValue,
                                 nsAttrValue& aResult) MOZ_OVERRIDE;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
-
   uint8_t GetType() const { return mType; }
 
   // WebIDL
 
   // The XPCOM GetType is OK for us
   void SetType(const nsAString& aType, ErrorResult& aError)
   {
     SetHTMLAttr(nsGkAtoms::type, aType, aError);
--- a/content/html/content/src/HTMLMenuItemElement.cpp
+++ b/content/html/content/src/HTMLMenuItemElement.cpp
@@ -164,27 +164,18 @@ HTMLMenuItemElement::HTMLMenuItemElement
   mParserCreating = aFromParser;
 }
 
 HTMLMenuItemElement::~HTMLMenuItemElement()
 {
 }
 
 
-NS_IMPL_ADDREF_INHERITED(HTMLMenuItemElement, Element)
-NS_IMPL_RELEASE_INHERITED(HTMLMenuItemElement, Element)
-
-
-// QueryInterface implementation for HTMLMenuItemElement
-NS_INTERFACE_TABLE_HEAD(HTMLMenuItemElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-  NS_INTERFACE_TABLE_INHERITED1(HTMLMenuItemElement,
-                                nsIDOMHTMLMenuItemElement)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
+NS_IMPL_ISUPPORTS_INHERITED1(HTMLMenuItemElement, nsGenericHTMLElement,
+                             nsIDOMHTMLMenuItemElement)
 
 //NS_IMPL_ELEMENT_CLONE(HTMLMenuItemElement)
 nsresult
 HTMLMenuItemElement::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
 {
   *aResult = nullptr;
   nsCOMPtr<nsINodeInfo> ni = aNodeInfo;
   nsRefPtr<HTMLMenuItemElement> it =
--- a/content/html/content/src/HTMLMenuItemElement.h
+++ b/content/html/content/src/HTMLMenuItemElement.h
@@ -25,25 +25,16 @@ public:
                       mozilla::dom::FromParser aFromParser);
   virtual ~HTMLMenuItemElement();
 
   NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLMenuItemElement, menuitem)
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   // nsIDOMHTMLMenuItemElement
   NS_DECL_NSIDOMHTMLMENUITEMELEMENT
 
   virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
   virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor) MOZ_OVERRIDE;
 
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
@@ -53,18 +44,16 @@ public:
                                 nsIAtom* aAttribute,
                                 const nsAString& aValue,
                                 nsAttrValue& aResult) MOZ_OVERRIDE;
 
   virtual void DoneCreatingElement() MOZ_OVERRIDE;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
-
   uint8_t GetType() const { return mType; }
 
   /**
    * Syntax sugar to make it easier to check for checked and checked dirty
    */
   bool IsChecked() const { return mChecked; }
   bool IsCheckedDirty() const { return mCheckedDirty; }
 
--- a/content/html/content/src/HTMLMetaElement.cpp
+++ b/content/html/content/src/HTMLMetaElement.cpp
@@ -19,27 +19,18 @@ HTMLMetaElement::HTMLMetaElement(already
 {
 }
 
 HTMLMetaElement::~HTMLMetaElement()
 {
 }
 
 
-NS_IMPL_ADDREF_INHERITED(HTMLMetaElement, Element)
-NS_IMPL_RELEASE_INHERITED(HTMLMetaElement, Element)
-
-
-// QueryInterface implementation for HTMLMetaElement
-NS_INTERFACE_TABLE_HEAD(HTMLMetaElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-  NS_INTERFACE_TABLE_INHERITED1(HTMLMetaElement, nsIDOMHTMLMetaElement)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
-
+NS_IMPL_ISUPPORTS_INHERITED1(HTMLMetaElement, nsGenericHTMLElement,
+                             nsIDOMHTMLMetaElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLMetaElement)
 
 
 NS_IMPL_STRING_ATTR(HTMLMetaElement, Content, content)
 NS_IMPL_STRING_ATTR(HTMLMetaElement, HttpEquiv, httpEquiv)
 NS_IMPL_STRING_ATTR(HTMLMetaElement, Name, name)
 NS_IMPL_STRING_ATTR(HTMLMetaElement, Scheme, scheme)
--- a/content/html/content/src/HTMLMetaElement.h
+++ b/content/html/content/src/HTMLMetaElement.h
@@ -18,39 +18,28 @@ class HTMLMetaElement MOZ_FINAL : public
 {
 public:
   HTMLMetaElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~HTMLMetaElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   // nsIDOMHTMLMetaElement
   NS_DECL_NSIDOMHTMLMETAELEMENT
 
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               bool aCompileEventHandlers) MOZ_OVERRIDE;
   virtual void UnbindFromTree(bool aDeep = true,
                               bool aNullParent = true) MOZ_OVERRIDE;
   void CreateAndDispatchEvent(nsIDocument* aDoc, const nsAString& aEventName);
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
-
   // XPCOM GetName is fine.
   void SetName(const nsAString& aName, ErrorResult& aRv)
   {
     SetHTMLAttr(nsGkAtoms::name, aName, aRv);
   }
   // XPCOM GetHttpEquiv is fine.
   void SetHttpEquiv(const nsAString& aHttpEquiv, ErrorResult& aRv)
   {
--- a/content/html/content/src/HTMLMeterElement.cpp
+++ b/content/html/content/src/HTMLMeterElement.cpp
@@ -20,27 +20,18 @@ HTMLMeterElement::HTMLMeterElement(alrea
   : nsGenericHTMLElement(aNodeInfo)
 {
 }
 
 HTMLMeterElement::~HTMLMeterElement()
 {
 }
 
-NS_IMPL_ADDREF_INHERITED(HTMLMeterElement, Element)
-NS_IMPL_RELEASE_INHERITED(HTMLMeterElement, Element)
-
-
-NS_INTERFACE_MAP_BEGIN(HTMLMeterElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-NS_ELEMENT_INTERFACE_MAP_END
-
 NS_IMPL_ELEMENT_CLONE(HTMLMeterElement)
 
-
 nsEventStates
 HTMLMeterElement::IntrinsicState() const
 {
   nsEventStates state = nsGenericHTMLElement::IntrinsicState();
 
   state |= GetOptimumState();
 
   return state;
--- a/content/html/content/src/HTMLMeterElement.h
+++ b/content/html/content/src/HTMLMeterElement.h
@@ -12,44 +12,29 @@
 #include "nsAttrValueInlines.h"
 #include "nsEventStateManager.h"
 #include "nsAlgorithm.h"
 #include <algorithm>
 
 namespace mozilla {
 namespace dom {
 
-class HTMLMeterElement MOZ_FINAL : public nsGenericHTMLElement,
-                                   public nsIDOMHTMLElement
+class HTMLMeterElement MOZ_FINAL : public nsGenericHTMLElement
 {
 public:
   HTMLMeterElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~HTMLMeterElement();
 
-  /* nsISupports */
-  NS_DECL_ISUPPORTS_INHERITED
-
-  /* nsIDOMNode */
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  /* nsIDOMElement */
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  /* nsIDOMHTMLElement */
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   virtual nsEventStates IntrinsicState() const MOZ_OVERRIDE;
 
   nsresult Clone(nsINodeInfo* aNodeInfo, nsINode** aResult) const MOZ_OVERRIDE;
 
   bool ParseAttribute(int32_t aNamespaceID, nsIAtom* aAttribute,
                       const nsAString& aValue, nsAttrValue& aResult) MOZ_OVERRIDE;
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
-
   // WebIDL
 
   /* @return the value */
   double Value() const;
   void SetValue(double aValue, ErrorResult& aRv)
   {
     aRv = SetDoubleAttr(nsGkAtoms::value, aValue);
   }
--- a/content/html/content/src/HTMLModElement.cpp
+++ b/content/html/content/src/HTMLModElement.cpp
@@ -16,26 +16,16 @@ HTMLModElement::HTMLModElement(already_A
   : nsGenericHTMLElement(aNodeInfo)
 {
 }
 
 HTMLModElement::~HTMLModElement()
 {
 }
 
-
-NS_IMPL_ADDREF_INHERITED(HTMLModElement, Element)
-NS_IMPL_RELEASE_INHERITED(HTMLModElement, Element)
-
-// QueryInterface implementation for HTMLModElement
-NS_INTERFACE_MAP_BEGIN(HTMLModElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-NS_ELEMENT_INTERFACE_MAP_END
-
-
 NS_IMPL_ELEMENT_CLONE(HTMLModElement)
 
 JSObject*
 HTMLModElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aScope)
 {
   return HTMLModElementBinding::Wrap(aCx, aScope, this);
 }
 
--- a/content/html/content/src/HTMLModElement.h
+++ b/content/html/content/src/HTMLModElement.h
@@ -8,39 +8,24 @@
 
 #include "mozilla/Attributes.h"
 #include "nsGenericHTMLElement.h"
 #include "nsGkAtoms.h"
 
 namespace mozilla {
 namespace dom {
 
-class HTMLModElement MOZ_FINAL : public nsGenericHTMLElement,
-                                 public nsIDOMHTMLElement
+class HTMLModElement MOZ_FINAL : public nsGenericHTMLElement
 {
 public:
   HTMLModElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~HTMLModElement();
 
-  // nsISupports
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
-
   void GetCite(nsString& aCite)
   {
     GetHTMLURIAttr(nsGkAtoms::cite, aCite);
   }
   void SetCite(const nsAString& aCite, ErrorResult& aRv)
   {
     SetHTMLAttr(nsGkAtoms::cite, aCite, aRv);
   }
--- a/content/html/content/src/HTMLObjectElement.cpp
+++ b/content/html/content/src/HTMLObjectElement.cpp
@@ -75,30 +75,28 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_IN
                                                 nsGenericHTMLFormElement)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mValidity)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_ADDREF_INHERITED(HTMLObjectElement, Element)
 NS_IMPL_RELEASE_INHERITED(HTMLObjectElement, Element)
 
 NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(HTMLObjectElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLFormElement)
   NS_INTERFACE_TABLE_INHERITED10(HTMLObjectElement,
                                  nsIDOMHTMLObjectElement,
                                  imgINotificationObserver,
                                  nsIRequestObserver,
                                  nsIStreamListener,
                                  nsIFrameLoaderOwner,
                                  nsIObjectLoadingContent,
                                  nsIImageLoadingContent,
                                  imgIOnloadBlocker,
                                  nsIChannelEventSink,
                                  nsIConstraintValidation)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
+NS_INTERFACE_TABLE_TAIL_INHERITING(nsGenericHTMLFormElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLObjectElement)
 
 // nsIConstraintValidation
 NS_IMPL_NSICONSTRAINTVALIDATION(HTMLObjectElement)
 
 NS_IMETHODIMP
 HTMLObjectElement::GetForm(nsIDOMHTMLFormElement **aForm)
--- a/content/html/content/src/HTMLObjectElement.h
+++ b/content/html/content/src/HTMLObjectElement.h
@@ -24,25 +24,16 @@ class HTMLObjectElement MOZ_FINAL : publ
 public:
   HTMLObjectElement(already_AddRefed<nsINodeInfo> aNodeInfo,
                     FromParser aFromParser = NOT_FROM_PARSER);
   virtual ~HTMLObjectElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   virtual int32_t TabIndexDefault() MOZ_OVERRIDE;
 
   // nsIDOMHTMLObjectElement
   NS_DECL_NSIDOMHTMLOBJECTELEMENT
 
   virtual nsresult BindToTree(nsIDocument *aDocument, nsIContent *aParent,
                               nsIContent *aBindingParent,
                               bool aCompileEventHandlers) MOZ_OVERRIDE;
@@ -87,18 +78,16 @@ public:
 
   nsresult CopyInnerTo(Element* aDest);
 
   void StartObjectLoad() { StartObjectLoad(true); }
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLObjectElement,
                                            nsGenericHTMLFormElement)
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
-
   // Web IDL binding methods
   // XPCOM GetData is ok; note that it's a URI attribute with a weird base URI
   void SetData(const nsAString& aValue, ErrorResult& aRv)
   {
     SetHTMLAttr(nsGkAtoms::data, aValue, aRv);
   }
   void GetType(DOMString& aValue)
   {
--- a/content/html/content/src/HTMLOptGroupElement.cpp
+++ b/content/html/content/src/HTMLOptGroupElement.cpp
@@ -32,29 +32,18 @@ HTMLOptGroupElement::HTMLOptGroupElement
   AddStatesSilently(NS_EVENT_STATE_ENABLED);
 }
 
 HTMLOptGroupElement::~HTMLOptGroupElement()
 {
 }
 
 
-NS_IMPL_ADDREF_INHERITED(HTMLOptGroupElement, Element)
-NS_IMPL_RELEASE_INHERITED(HTMLOptGroupElement, Element)
-
-
-
-// QueryInterface implementation for HTMLOptGroupElement
-NS_INTERFACE_TABLE_HEAD(HTMLOptGroupElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-  NS_INTERFACE_TABLE_INHERITED1(HTMLOptGroupElement,
-                                nsIDOMHTMLOptGroupElement)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
-
+NS_IMPL_ISUPPORTS_INHERITED1(HTMLOptGroupElement, nsGenericHTMLElement,
+                             nsIDOMHTMLOptGroupElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLOptGroupElement)
 
 
 NS_IMPL_BOOL_ATTR(HTMLOptGroupElement, Disabled, disabled)
 NS_IMPL_STRING_ATTR(HTMLOptGroupElement, Label, label)
 
 
--- a/content/html/content/src/HTMLOptGroupElement.h
+++ b/content/html/content/src/HTMLOptGroupElement.h
@@ -20,25 +20,16 @@ public:
   HTMLOptGroupElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~HTMLOptGroupElement();
 
   NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLOptGroupElement, optgroup)
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   // nsIDOMHTMLOptGroupElement
   NS_DECL_NSIDOMHTMLOPTGROUPELEMENT
 
   // nsINode
   virtual nsresult InsertChildAt(nsIContent* aKid, uint32_t aIndex,
                                  bool aNotify) MOZ_OVERRIDE;
   virtual void RemoveChildAt(uint32_t aIndex, bool aNotify) MOZ_OVERRIDE;
 
--- a/content/html/content/src/HTMLOptionElement.cpp
+++ b/content/html/content/src/HTMLOptionElement.cpp
@@ -46,31 +46,18 @@ HTMLOptionElement::HTMLOptionElement(alr
   // We start off enabled
   AddStatesSilently(NS_EVENT_STATE_ENABLED);
 }
 
 HTMLOptionElement::~HTMLOptionElement()
 {
 }
 
-// ISupports
-
-
-NS_IMPL_ADDREF_INHERITED(HTMLOptionElement, Element)
-NS_IMPL_RELEASE_INHERITED(HTMLOptionElement, Element)
-
-
-// QueryInterface implementation for HTMLOptionElement
-NS_INTERFACE_TABLE_HEAD(HTMLOptionElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-  NS_INTERFACE_TABLE_INHERITED1(HTMLOptionElement,
-                                nsIDOMHTMLOptionElement)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
-
+NS_IMPL_ISUPPORTS_INHERITED1(HTMLOptionElement, nsGenericHTMLElement,
+                             nsIDOMHTMLOptionElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLOptionElement)
 
 
 NS_IMETHODIMP
 HTMLOptionElement::GetForm(nsIDOMHTMLFormElement** aForm)
 {
   NS_IF_ADDREF(*aForm = GetForm());
--- a/content/html/content/src/HTMLOptionElement.h
+++ b/content/html/content/src/HTMLOptionElement.h
@@ -31,25 +31,16 @@ public:
            const Optional<bool>& aDefaultSelected,
            const Optional<bool>& aSelected, ErrorResult& aError);
 
   NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLOptionElement, option)
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   // nsIDOMHTMLOptionElement
   using mozilla::dom::Element::SetText;
   using mozilla::dom::Element::GetText;
   NS_DECL_NSIDOMHTMLOPTIONELEMENT
 
   bool Selected() const;
   bool DefaultSelected() const;
 
@@ -70,18 +61,16 @@ public:
 
   // nsIContent
   virtual nsEventStates IntrinsicState() const MOZ_OVERRIDE;
 
   virtual nsresult Clone(nsINodeInfo* aNodeInfo, nsINode** aResult) const MOZ_OVERRIDE;
 
   nsresult CopyInnerTo(mozilla::dom::Element* aDest);
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
-
   virtual bool IsDisabled() const MOZ_OVERRIDE {
     return HasAttr(kNameSpaceID_None, nsGkAtoms::disabled);
   }
 
   bool Disabled() const
   {
     return GetBoolAttr(nsGkAtoms::disabled);
   }
--- a/content/html/content/src/HTMLOptionsCollection.cpp
+++ b/content/html/content/src/HTMLOptionsCollection.cpp
@@ -163,27 +163,30 @@ HTMLOptionsCollection::SetOption(uint32_
     rv = SetLength(index);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   NS_ASSERTION(index <= mElements.Length(), "SetLength lied");
   
   nsCOMPtr<nsIDOMNode> ret;
   if (index == mElements.Length()) {
-    rv = mSelect->AppendChild(aOption, getter_AddRefs(ret));
+    nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aOption);
+    rv = mSelect->AppendChild(node, getter_AddRefs(ret));
   } else {
     // Find the option they're talking about and replace it
     // hold a strong reference to follow COM rules.
-    nsCOMPtr<nsIDOMHTMLOptionElement> refChild = ItemAsOption(index);
+    nsRefPtr<HTMLOptionElement> refChild = ItemAsOption(index);
     NS_ENSURE_TRUE(refChild, NS_ERROR_UNEXPECTED);
 
-    nsCOMPtr<nsIDOMNode> parent;
-    refChild->GetParentNode(getter_AddRefs(parent));
+    nsCOMPtr<nsINode> parent = refChild->GetParent();
     if (parent) {
-      rv = parent->ReplaceChild(aOption, refChild, getter_AddRefs(ret));
+      nsCOMPtr<nsINode> node = do_QueryInterface(aOption);
+      ErrorResult res;
+      parent->ReplaceChild(*node, *refChild, res);
+      rv = res.ErrorCode();
     }
   }
 
   return rv;
 }
 
 int32_t
 HTMLOptionsCollection::GetSelectedIndex(ErrorResult& aError)
@@ -341,17 +344,18 @@ HTMLOptionsCollection::Add(nsIDOMHTMLOpt
   if (!aOption) {
     return NS_ERROR_INVALID_ARG;
   }
 
   if (!mSelect) {
     return NS_ERROR_NOT_INITIALIZED;
   }
 
-  return mSelect->Add(aOption, aBefore);
+  nsCOMPtr<nsIDOMHTMLElement> elem = do_QueryInterface(aOption);
+  return mSelect->Add(elem, aBefore);
 }
 
 void
 HTMLOptionsCollection::Add(const HTMLOptionOrOptGroupElement& aElement,
                            const Nullable<HTMLElementOrLong>& aBefore,
                            ErrorResult& aError)
 {
   mSelect->Add(aElement, aBefore, aError);
--- a/content/html/content/src/HTMLOutputElement.cpp
+++ b/content/html/content/src/HTMLOutputElement.cpp
@@ -49,22 +49,20 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mValidity)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTokenList)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_ADDREF_INHERITED(HTMLOutputElement, Element)
 NS_IMPL_RELEASE_INHERITED(HTMLOutputElement, Element)
 
 NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(HTMLOutputElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLFormElement)
   NS_INTERFACE_TABLE_INHERITED2(HTMLOutputElement,
                                 nsIMutationObserver,
                                 nsIConstraintValidation)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
+NS_INTERFACE_TABLE_TAIL_INHERITING(nsGenericHTMLFormElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLOutputElement)
 
 void
 HTMLOutputElement::SetCustomValidity(const nsAString& aError)
 {
   nsIConstraintValidation::SetCustomValidity(aError);
 
--- a/content/html/content/src/HTMLOutputElement.h
+++ b/content/html/content/src/HTMLOutputElement.h
@@ -10,38 +10,28 @@
 #include "nsGenericHTMLElement.h"
 #include "nsStubMutationObserver.h"
 #include "nsIConstraintValidation.h"
 
 namespace mozilla {
 namespace dom {
 
 class HTMLOutputElement MOZ_FINAL : public nsGenericHTMLFormElement,
-                                    public nsIDOMHTMLElement,
                                     public nsStubMutationObserver,
                                     public nsIConstraintValidation
 {
 public:
   using nsIConstraintValidation::GetValidationMessage;
 
   HTMLOutputElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~HTMLOutputElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   // nsIFormControl
   NS_IMETHOD_(uint32_t) GetType() const { return NS_FORM_OUTPUT; }
   NS_IMETHOD Reset() MOZ_OVERRIDE;
   NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission) MOZ_OVERRIDE;
 
   virtual bool IsDisabled() const MOZ_OVERRIDE { return false; }
 
   nsresult Clone(nsINodeInfo* aNodeInfo, nsINode** aResult) const MOZ_OVERRIDE;
@@ -63,17 +53,16 @@ public:
   NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLOutputElement,
                                            nsGenericHTMLFormElement)
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
   virtual JSObject* WrapNode(JSContext* aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
   // WebIDL
   nsDOMSettableTokenList* HtmlFor();
   // nsGenericHTMLFormElement::GetForm is fine.
   void GetName(nsAString& aName)
   {
--- a/content/html/content/src/HTMLParagraphElement.cpp
+++ b/content/html/content/src/HTMLParagraphElement.cpp
@@ -15,26 +15,18 @@ NS_IMPL_NS_NEW_HTML_ELEMENT(Paragraph)
 
 namespace mozilla {
 namespace dom {
 
 HTMLParagraphElement::~HTMLParagraphElement()
 {
 }
 
-NS_IMPL_ADDREF_INHERITED(HTMLParagraphElement, Element)
-NS_IMPL_RELEASE_INHERITED(HTMLParagraphElement, Element)
-
-// QueryInterface implementation for nsHTMLParagraphElement
-NS_INTERFACE_TABLE_HEAD(HTMLParagraphElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-  NS_INTERFACE_TABLE_INHERITED1(HTMLParagraphElement,
-                                nsIDOMHTMLParagraphElement)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
+NS_IMPL_ISUPPORTS_INHERITED1(HTMLParagraphElement, nsGenericHTMLElement,
+                             nsIDOMHTMLParagraphElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLParagraphElement)
 
 NS_IMPL_STRING_ATTR(HTMLParagraphElement, Align, align)
 
 bool
 HTMLParagraphElement::ParseAttribute(int32_t aNamespaceID,
                                      nsIAtom* aAttribute,
--- a/content/html/content/src/HTMLParagraphElement.h
+++ b/content/html/content/src/HTMLParagraphElement.h
@@ -23,39 +23,28 @@ public:
     : nsGenericHTMLElement(aNodeInfo)
   {
   }
   virtual ~HTMLParagraphElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   // nsIDOMHTMLParagraphElement
   NS_DECL_NSIDOMHTMLPARAGRAPHELEMENT
 
   virtual bool ParseAttribute(int32_t aNamespaceID,
                                 nsIAtom* aAttribute,
                                 const nsAString& aValue,
                                 nsAttrValue& aResult) MOZ_OVERRIDE;
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
   virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const MOZ_OVERRIDE;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
-
   // WebIDL API
   // The XPCOM GetAlign is fine for our purposes
   void SetAlign(const nsAString& aValue, mozilla::ErrorResult& rv)
   {
     SetHTMLAttr(nsGkAtoms::align, aValue, rv);
   }
 
 protected:
--- a/content/html/content/src/HTMLPreElement.cpp
+++ b/content/html/content/src/HTMLPreElement.cpp
@@ -16,25 +16,18 @@ NS_IMPL_NS_NEW_HTML_ELEMENT(Pre)
 
 namespace mozilla {
 namespace dom {
 
 HTMLPreElement::~HTMLPreElement()
 {
 }
 
-NS_IMPL_ADDREF_INHERITED(HTMLPreElement, Element)
-NS_IMPL_RELEASE_INHERITED(HTMLPreElement, Element)
-
-// QueryInterface implementation for HTMLPreElement
-NS_INTERFACE_TABLE_HEAD(HTMLPreElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-  NS_INTERFACE_TABLE_INHERITED1(HTMLPreElement, nsIDOMHTMLPreElement)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
+NS_IMPL_ISUPPORTS_INHERITED1(HTMLPreElement, nsGenericHTMLElement,
+                             nsIDOMHTMLPreElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLPreElement)
 
 NS_IMPL_INT_ATTR(HTMLPreElement, Width, width)
 
 bool
 HTMLPreElement::ParseAttribute(int32_t aNamespaceID,
                                nsIAtom* aAttribute,
--- a/content/html/content/src/HTMLPreElement.h
+++ b/content/html/content/src/HTMLPreElement.h
@@ -23,40 +23,29 @@ public:
     : nsGenericHTMLElement(aNodeInfo)
   {
   }
   virtual ~HTMLPreElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   // nsIDOMHTMLPreElement
   NS_IMETHOD GetWidth(int32_t* aWidth) MOZ_OVERRIDE;
   NS_IMETHOD SetWidth(int32_t aWidth) MOZ_OVERRIDE;
 
   virtual bool ParseAttribute(int32_t aNamespaceID,
                                 nsIAtom* aAttribute,
                                 const nsAString& aValue,
                                 nsAttrValue& aResult) MOZ_OVERRIDE;
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
   virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const MOZ_OVERRIDE;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
-
   // WebIDL API
   int32_t Width() const
   {
     return GetIntAttr(nsGkAtoms::width, 0);
   }
   void SetWidth(int32_t aWidth, mozilla::ErrorResult& rv)
   {
     rv = SetIntAttr(nsGkAtoms::width, aWidth);
--- a/content/html/content/src/HTMLProgressElement.cpp
+++ b/content/html/content/src/HTMLProgressElement.cpp
@@ -22,24 +22,16 @@ HTMLProgressElement::HTMLProgressElement
   // We start out indeterminate
   AddStatesSilently(NS_EVENT_STATE_INDETERMINATE);
 }
 
 HTMLProgressElement::~HTMLProgressElement()
 {
 }
 
-NS_IMPL_ADDREF_INHERITED(HTMLProgressElement, Element)
-NS_IMPL_RELEASE_INHERITED(HTMLProgressElement, Element)
-
-
-NS_INTERFACE_MAP_BEGIN(HTMLProgressElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-NS_ELEMENT_INTERFACE_MAP_END
-
 NS_IMPL_ELEMENT_CLONE(HTMLProgressElement)
 
 
 nsEventStates
 HTMLProgressElement::IntrinsicState() const
 {
   nsEventStates state = nsGenericHTMLElement::IntrinsicState();
 
--- a/content/html/content/src/HTMLProgressElement.h
+++ b/content/html/content/src/HTMLProgressElement.h
@@ -11,44 +11,29 @@
 #include "nsAttrValue.h"
 #include "nsAttrValueInlines.h"
 #include "nsEventStateManager.h"
 #include <algorithm>
 
 namespace mozilla {
 namespace dom {
 
-class HTMLProgressElement MOZ_FINAL : public nsGenericHTMLElement,
-                                      public nsIDOMHTMLElement
+class HTMLProgressElement MOZ_FINAL : public nsGenericHTMLElement
 {
 public:
   HTMLProgressElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~HTMLProgressElement();
 
-  // nsISupports
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   nsEventStates IntrinsicState() const MOZ_OVERRIDE;
 
   nsresult Clone(nsINodeInfo* aNodeInfo, nsINode** aResult) const MOZ_OVERRIDE;
 
   bool ParseAttribute(int32_t aNamespaceID, nsIAtom* aAttribute,
                         const nsAString& aValue, nsAttrValue& aResult) MOZ_OVERRIDE;
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
-
   // WebIDL
   double Value() const;
   void SetValue(double aValue, ErrorResult& aRv)
   {
     aRv = SetDoubleAttr(nsGkAtoms::value, aValue);
   }
   double Max() const;
   void SetMax(double aValue, ErrorResult& aRv)
--- a/content/html/content/src/HTMLPropertiesCollection.h
+++ b/content/html/content/src/HTMLPropertiesCollection.h
@@ -112,17 +112,17 @@ protected:
 
   // the itemprop attribute of the properties
   nsRefPtr<PropertyStringList> mNames;
 
   // The cached PropertyNodeLists that are NamedItems of this collection
   nsRefPtrHashtable<nsStringHashKey, PropertyNodeList> mNamedItemEntries;
 
   // The element this collection is rooted at
-  nsCOMPtr<nsGenericHTMLElement> mRoot;
+  nsRefPtr<nsGenericHTMLElement> mRoot;
 
   // The document mRoot is in, if any
   nsCOMPtr<nsIDocument> mDoc;
 
   // True if there have been DOM modifications since the last EnsureFresh call.
   bool mIsDirty;
 };
 
--- a/content/html/content/src/HTMLScriptElement.cpp
+++ b/content/html/content/src/HTMLScriptElement.cpp
@@ -15,16 +15,17 @@
 #include "nsIScriptContext.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIXPConnect.h"
 #include "nsServiceManagerUtils.h"
 #include "nsError.h"
 #include "nsIArray.h"
 #include "nsTArray.h"
 #include "nsDOMJSUtils.h"
+#include "nsISupportsImpl.h"
 #include "mozilla/dom/HTMLScriptElement.h"
 #include "mozilla/dom/HTMLScriptElementBinding.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Script)
 
 namespace mozilla {
 namespace dom {
 
@@ -41,31 +42,21 @@ HTMLScriptElement::HTMLScriptElement(alr
 {
   AddMutationObserver(this);
 }
 
 HTMLScriptElement::~HTMLScriptElement()
 {
 }
 
-
-NS_IMPL_ADDREF_INHERITED(HTMLScriptElement, Element)
-NS_IMPL_RELEASE_INHERITED(HTMLScriptElement, Element)
-
-// QueryInterface implementation for HTMLScriptElement
-NS_INTERFACE_TABLE_HEAD(HTMLScriptElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-  NS_INTERFACE_TABLE_INHERITED4(HTMLScriptElement,
-                                nsIDOMHTMLScriptElement,
-                                nsIScriptLoaderObserver,
-                                nsIScriptElement,
-                                nsIMutationObserver)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
-
+NS_IMPL_ISUPPORTS_INHERITED4(HTMLScriptElement, nsGenericHTMLElement,
+                             nsIDOMHTMLScriptElement,
+                             nsIScriptLoaderObserver,
+                             nsIScriptElement,
+                             nsIMutationObserver)
 
 nsresult
 HTMLScriptElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               bool aCompileEventHandlers)
 {
   nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
                                                  aBindingParent,
--- a/content/html/content/src/HTMLScriptElement.h
+++ b/content/html/content/src/HTMLScriptElement.h
@@ -25,27 +25,20 @@ public:
 
   HTMLScriptElement(already_AddRefed<nsINodeInfo> aNodeInfo,
                       FromParser aFromParser);
   virtual ~HTMLScriptElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
+  using nsGenericHTMLElement::GetInnerHTML;
   virtual void GetInnerHTML(nsAString& aInnerHTML,
                             mozilla::ErrorResult& aError) MOZ_OVERRIDE;
+  using nsGenericHTMLElement::SetInnerHTML;
   virtual void SetInnerHTML(const nsAString& aInnerHTML,
                             mozilla::ErrorResult& aError) MOZ_OVERRIDE;
 
   // nsIDOMHTMLScriptElement
   NS_DECL_NSIDOMHTMLSCRIPTELEMENT
 
   // nsIScriptElement
   virtual void GetScriptType(nsAString& type) MOZ_OVERRIDE;
@@ -64,18 +57,16 @@ public:
                               nsAttrValue& aResult) MOZ_OVERRIDE;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   // Element
   virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
                                 const nsAttrValue* aValue, bool aNotify) MOZ_OVERRIDE;
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
-
   // WebIDL
   void SetText(const nsAString& aValue, ErrorResult& rv);
   void SetCharset(const nsAString& aCharset, ErrorResult& rv);
   void SetDefer(bool aDefer, ErrorResult& rv);
   bool Defer();
   void SetSrc(const nsAString& aSrc, ErrorResult& rv);
   void SetType(const nsAString& aType, ErrorResult& rv);
   void SetHtmlFor(const nsAString& aHtmlFor, ErrorResult& rv);
--- a/content/html/content/src/HTMLSelectElement.cpp
+++ b/content/html/content/src/HTMLSelectElement.cpp
@@ -145,22 +145,20 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_IN
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mValidity)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_ADDREF_INHERITED(HTMLSelectElement, Element)
 NS_IMPL_RELEASE_INHERITED(HTMLSelectElement, Element)
 
 // QueryInterface implementation for HTMLSelectElement
 NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(HTMLSelectElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLFormElementWithState)
   NS_INTERFACE_TABLE_INHERITED2(HTMLSelectElement,
                                 nsIDOMHTMLSelectElement,
                                 nsIConstraintValidation)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
+NS_INTERFACE_TABLE_TAIL_INHERITING(nsGenericHTMLFormElementWithState)
 
 
 // nsIDOMHTMLSelectElement
 
 
 NS_IMPL_ELEMENT_CLONE(HTMLSelectElement)
 
 // nsIConstraintValidation
@@ -604,23 +602,23 @@ HTMLSelectElement::Add(const HTMLOptionE
 }
 
 void
 HTMLSelectElement::Add(nsGenericHTMLElement& aElement,
                        nsGenericHTMLElement* aBefore,
                        ErrorResult& aError)
 {
   if (!aBefore) {
-    nsGenericHTMLElement::AppendChild(aElement, aError);
+    Element::AppendChild(aElement, aError);
     return;
   }
 
   // Just in case we're not the parent, get the parent of the reference
   // element
-  nsINode* parent = aBefore->GetParentNode();
+  nsINode* parent = aBefore->Element::GetParentNode();
   if (!parent || !nsContentUtils::ContentIsDescendantOf(parent, this)) {
     // NOT_FOUND_ERR: Raised if before is not a descendant of the SELECT
     // element.
     aError.Throw(NS_ERROR_DOM_NOT_FOUND_ERR);
     return;
   }
 
   // If the before parameter is not null, we are equivalent to the
--- a/content/html/content/src/HTMLSelectElement.h
+++ b/content/html/content/src/HTMLSelectElement.h
@@ -114,25 +114,16 @@ public:
                     FromParser aFromParser = NOT_FROM_PARSER);
   virtual ~HTMLSelectElement();
 
   NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLSelectElement, select)
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   virtual int32_t TabIndexDefault() MOZ_OVERRIDE;
 
   // nsIDOMHTMLSelectElement
   NS_DECL_NSIDOMHTMLSELECTELEMENT
 
   // WebIdl HTMLSelectElement
   bool Autofocus() const
   {
@@ -371,18 +362,16 @@ public:
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLSelectElement,
                                            nsGenericHTMLFormElementWithState)
 
   HTMLOptionsCollection* GetOptions()
   {
     return mOptions;
   }
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
-
   // nsIConstraintValidation
   nsresult GetValidationMessage(nsAString& aValidationMessage,
                                 ValidityStateType aType) MOZ_OVERRIDE;
 
   /**
    * Insert aElement before the node given by aBefore
    */
   void Add(nsGenericHTMLElement& aElement, nsGenericHTMLElement* aBefore,
--- a/content/html/content/src/HTMLSharedElement.cpp
+++ b/content/html/content/src/HTMLSharedElement.cpp
@@ -28,25 +28,23 @@ HTMLSharedElement::~HTMLSharedElement()
 {
 }
 
 NS_IMPL_ADDREF_INHERITED(HTMLSharedElement, Element)
 NS_IMPL_RELEASE_INHERITED(HTMLSharedElement, Element)
 
 // QueryInterface implementation for HTMLSharedElement
 NS_INTERFACE_MAP_BEGIN(HTMLSharedElement)
-  NS_HTML_CONTENT_INTERFACES_AMBIGUOUS(nsGenericHTMLElement,
-                                       nsIDOMHTMLBaseElement)
   NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLBaseElement, base)
   NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLDirectoryElement, dir)
   NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLQuoteElement, q)
   NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLQuoteElement, blockquote)
   NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLHeadElement, head)
   NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLHtmlElement, html)
-NS_ELEMENT_INTERFACE_MAP_END
+NS_INTERFACE_MAP_END_INHERITING(nsGenericHTMLElement)
 
 
 NS_IMPL_ELEMENT_CLONE(HTMLSharedElement)
 
 // nsIDOMHTMLQuoteElement
 NS_IMPL_URI_ATTR(HTMLSharedElement, Cite, cite)
 
 // nsIDOMHTMLHeadElement
--- a/content/html/content/src/HTMLSharedElement.h
+++ b/content/html/content/src/HTMLSharedElement.h
@@ -33,25 +33,16 @@ public:
     : nsGenericHTMLElement(aNodeInfo)
   {
   }
   virtual ~HTMLSharedElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   // nsIDOMHTMLBaseElement
   NS_DECL_NSIDOMHTMLBASEELEMENT
 
   // nsIDOMHTMLQuoteElement
   NS_DECL_NSIDOMHTMLQUOTEELEMENT
 
   // nsIDOMHTMLHeadElement
   NS_DECL_NSIDOMHTMLHEADELEMENT
@@ -83,21 +74,16 @@ public:
   virtual void UnbindFromTree(bool aDeep = true,
                               bool aNullParent = true) MOZ_OVERRIDE;
 
   virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const MOZ_OVERRIDE;
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE
-  {
-    return static_cast<nsIDOMHTMLBaseElement*>(this);
-  }
-
   // WebIDL API
   // HTMLParamElement
   void GetName(DOMString& aValue)
   {
     MOZ_ASSERT(mNodeInfo->Equals(nsGkAtoms::param));
     GetHTMLAttr(nsGkAtoms::name, aValue);
   }
   void SetName(const nsAString& aValue, ErrorResult& aResult)
--- a/content/html/content/src/HTMLSharedListElement.cpp
+++ b/content/html/content/src/HTMLSharedListElement.cpp
@@ -24,21 +24,19 @@ HTMLSharedListElement::~HTMLSharedListEl
 {
 }
 
 NS_IMPL_ADDREF_INHERITED(HTMLSharedListElement, Element)
 NS_IMPL_RELEASE_INHERITED(HTMLSharedListElement, Element)
 
 // QueryInterface implementation for nsHTMLSharedListElement
 NS_INTERFACE_MAP_BEGIN(HTMLSharedListElement)
-  NS_HTML_CONTENT_INTERFACES_AMBIGUOUS(nsGenericHTMLElement,
-                                       nsIDOMHTMLOListElement)
   NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLOListElement, ol)
   NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLUListElement, ul)
-NS_ELEMENT_INTERFACE_MAP_END
+NS_INTERFACE_MAP_END_INHERITING(nsGenericHTMLElement)
 
 
 NS_IMPL_ELEMENT_CLONE(HTMLSharedListElement)
 
 
 NS_IMPL_BOOL_ATTR(HTMLSharedListElement, Compact, compact)
 NS_IMPL_INT_ATTR_DEFAULT_VALUE(HTMLSharedListElement, Start, start, 1)
 NS_IMPL_STRING_ATTR(HTMLSharedListElement, Type, type)
--- a/content/html/content/src/HTMLSharedListElement.h
+++ b/content/html/content/src/HTMLSharedListElement.h
@@ -24,44 +24,30 @@ public:
     : nsGenericHTMLElement(aNodeInfo)
   {
   }
   virtual ~HTMLSharedListElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   // nsIDOMHTMLOListElement
   NS_DECL_NSIDOMHTMLOLISTELEMENT
 
   // nsIDOMHTMLUListElement
   // fully declared by NS_DECL_NSIDOMHTMLOLISTELEMENT
 
   virtual bool ParseAttribute(int32_t aNamespaceID,
                                 nsIAtom* aAttribute,
                                 const nsAString& aValue,
                                 nsAttrValue& aResult) MOZ_OVERRIDE;
   virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const MOZ_OVERRIDE;
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE
-  {
-    return static_cast<nsIDOMHTMLOListElement*>(this);
-  }
-
   bool Reversed() const
   {
     return GetBoolAttr(nsGkAtoms::reversed);
   }
   void SetReversed(bool aReversed, mozilla::ErrorResult& rv)
   {
     SetHTMLBoolAttr(nsGkAtoms::reversed, aReversed, rv);
   }
--- a/content/html/content/src/HTMLSharedObjectElement.cpp
+++ b/content/html/content/src/HTMLSharedObjectElement.cpp
@@ -86,31 +86,29 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
                                                   nsGenericHTMLElement)
   nsObjectLoadingContent::Traverse(tmp, cb);
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_ADDREF_INHERITED(HTMLSharedObjectElement, Element)
 NS_IMPL_RELEASE_INHERITED(HTMLSharedObjectElement, Element)
 
 NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(HTMLSharedObjectElement)
-  NS_HTML_CONTENT_INTERFACES_AMBIGUOUS(nsGenericHTMLElement,
-                                       nsIDOMHTMLAppletElement)
   NS_INTERFACE_TABLE_INHERITED8(HTMLSharedObjectElement,
                                 nsIRequestObserver,
                                 nsIStreamListener,
                                 nsIFrameLoaderOwner,
                                 nsIObjectLoadingContent,
                                 imgINotificationObserver,
                                 nsIImageLoadingContent,
                                 imgIOnloadBlocker,
                                 nsIChannelEventSink)
   NS_INTERFACE_TABLE_TO_MAP_SEGUE
   NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLAppletElement, applet)
   NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLEmbedElement, embed)
-NS_ELEMENT_INTERFACE_MAP_END
+NS_INTERFACE_MAP_END_INHERITING(nsGenericHTMLElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLSharedObjectElement)
 
 nsresult
 HTMLSharedObjectElement::BindToTree(nsIDocument *aDocument,
                                     nsIContent *aParent,
                                     nsIContent *aBindingParent,
                                     bool aCompileEventHandlers)
--- a/content/html/content/src/HTMLSharedObjectElement.h
+++ b/content/html/content/src/HTMLSharedObjectElement.h
@@ -26,25 +26,16 @@ class HTMLSharedObjectElement MOZ_FINAL 
 public:
   HTMLSharedObjectElement(already_AddRefed<nsINodeInfo> aNodeInfo,
                           mozilla::dom::FromParser aFromParser = mozilla::dom::NOT_FROM_PARSER);
   virtual ~HTMLSharedObjectElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   virtual int32_t TabIndexDefault() MOZ_OVERRIDE;
 
   // nsIDOMHTMLAppletElement
   NS_DECL_NSIDOMHTMLAPPLETELEMENT
 
   // Can't use macro for nsIDOMHTMLEmbedElement because it has conflicts with
   // NS_DECL_NSIDOMHTMLAPPLETELEMENT.
 
@@ -85,21 +76,16 @@ public:
 
   nsresult CopyInnerTo(Element* aDest);
 
   void StartObjectLoad() { StartObjectLoad(true); }
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(HTMLSharedObjectElement,
                                                      nsGenericHTMLElement)
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE
-  {
-    return static_cast<nsIDOMHTMLAppletElement*>(this);
-  }
-
   // WebIDL API for <applet>
   void GetAlign(DOMString& aValue)
   {
     GetHTMLAttr(nsGkAtoms::align, aValue);
   }
   void SetAlign(const nsAString& aValue, ErrorResult& aRv)
   {
     SetHTMLAttr(nsGkAtoms::align, aValue, aRv);
--- a/content/html/content/src/HTMLSourceElement.cpp
+++ b/content/html/content/src/HTMLSourceElement.cpp
@@ -16,29 +16,18 @@ HTMLSourceElement::HTMLSourceElement(alr
   : nsGenericHTMLElement(aNodeInfo)
 {
 }
 
 HTMLSourceElement::~HTMLSourceElement()
 {
 }
 
-
-NS_IMPL_ADDREF_INHERITED(HTMLSourceElement, Element)
-NS_IMPL_RELEASE_INHERITED(HTMLSourceElement, Element)
-
-
-
-// QueryInterface implementation for HTMLSourceElement
-NS_INTERFACE_TABLE_HEAD(HTMLSourceElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-  NS_INTERFACE_TABLE_INHERITED1(HTMLSourceElement, nsIDOMHTMLSourceElement)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
-
+NS_IMPL_ISUPPORTS_INHERITED1(HTMLSourceElement, nsGenericHTMLElement,
+                             nsIDOMHTMLSourceElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLSourceElement)
 
 
 NS_IMPL_URI_ATTR(HTMLSourceElement, Src, src)
 NS_IMPL_STRING_ATTR(HTMLSourceElement, Type, type)
 NS_IMPL_STRING_ATTR(HTMLSourceElement, Media, media)
 
--- a/content/html/content/src/HTMLSourceElement.h
+++ b/content/html/content/src/HTMLSourceElement.h
@@ -20,38 +20,27 @@ class HTMLSourceElement MOZ_FINAL : publ
 {
 public:
   HTMLSourceElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~HTMLSourceElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   // nsIDOMHTMLSourceElement
   NS_DECL_NSIDOMHTMLSOURCEELEMENT
 
   virtual nsresult Clone(nsINodeInfo* aNodeInfo, nsINode** aResult) const MOZ_OVERRIDE;
 
   // Override BindToTree() so that we can trigger a load when we add a
   // child source element.
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               bool aCompileEventHandlers) MOZ_OVERRIDE;
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
-
   // WebIDL
   void GetSrc(nsString& aSrc)
   {
     GetURIAttr(nsGkAtoms::src, nullptr, aSrc);
   }
   void SetSrc(const nsAString& aSrc, mozilla::ErrorResult& rv)
   {
     SetHTMLAttr(nsGkAtoms::src, aSrc, rv);
--- a/content/html/content/src/HTMLSpanElement.cpp
+++ b/content/html/content/src/HTMLSpanElement.cpp
@@ -15,25 +15,16 @@ NS_IMPL_NS_NEW_HTML_ELEMENT(Span)
 
 namespace mozilla {
 namespace dom {
 
 HTMLSpanElement::~HTMLSpanElement()
 {
 }
 
-NS_IMPL_ADDREF_INHERITED(HTMLSpanElement, Element)
-NS_IMPL_RELEASE_INHERITED(HTMLSpanElement, Element)
-
-// QueryInterface implementation for HTMLSpanElement
-NS_INTERFACE_MAP_BEGIN(HTMLSpanElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-NS_ELEMENT_INTERFACE_MAP_END
-
-
 NS_IMPL_ELEMENT_CLONE(HTMLSpanElement)
 
 JSObject*
 HTMLSpanElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aScope)
 {
   return HTMLSpanElementBinding::Wrap(aCx, aScope, this);
 }
 
--- a/content/html/content/src/HTMLSpanElement.h
+++ b/content/html/content/src/HTMLSpanElement.h
@@ -12,42 +12,27 @@
 #include "nsGkAtoms.h"
 #include "nsStyleConsts.h"
 #include "nsIAtom.h"
 #include "nsRuleData.h"
 
 namespace mozilla {
 namespace dom {
 
-class HTMLSpanElement MOZ_FINAL : public nsGenericHTMLElement,
-                                  public nsIDOMHTMLElement
+class HTMLSpanElement MOZ_FINAL : public nsGenericHTMLElement
 {
 public:
   HTMLSpanElement(already_AddRefed<nsINodeInfo> aNodeInfo)
     : nsGenericHTMLElement(aNodeInfo)
   {
   }
   virtual ~HTMLSpanElement();
 
-  // nsISupports
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
-
 protected:
   virtual JSObject* WrapNode(JSContext *aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 };
 
 } // namespace dom
 } // namespace mozilla
 
--- a/content/html/content/src/HTMLStyleElement.cpp
+++ b/content/html/content/src/HTMLStyleElement.cpp
@@ -44,24 +44,22 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_IN
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_ADDREF_INHERITED(HTMLStyleElement, Element)
 NS_IMPL_RELEASE_INHERITED(HTMLStyleElement, Element)
 
 
 // QueryInterface implementation for HTMLStyleElement
 NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(HTMLStyleElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
   NS_INTERFACE_TABLE_INHERITED4(HTMLStyleElement,
                                 nsIDOMHTMLStyleElement,
                                 nsIDOMLinkStyle,
                                 nsIStyleSheetLinkingElement,
                                 nsIMutationObserver)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
+NS_INTERFACE_TABLE_TAIL_INHERITING(nsGenericHTMLElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLStyleElement)
 
 
 NS_IMETHODIMP
 HTMLStyleElement::GetMozDisabled(bool* aDisabled)
 {
   NS_ENSURE_ARG_POINTER(aDisabled);
--- a/content/html/content/src/HTMLStyleElement.h
+++ b/content/html/content/src/HTMLStyleElement.h
@@ -28,27 +28,20 @@ public:
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // CC
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLStyleElement,
                                            nsGenericHTMLElement)
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
+  using nsGenericHTMLElement::GetInnerHTML;
   virtual void GetInnerHTML(nsAString& aInnerHTML,
                             mozilla::ErrorResult& aError) MOZ_OVERRIDE;
+  using nsGenericHTMLElement::SetInnerHTML;
   virtual void SetInnerHTML(const nsAString& aInnerHTML,
                             mozilla::ErrorResult& aError) MOZ_OVERRIDE;
 
   // nsIDOMHTMLStyleElement
   NS_DECL_NSIDOMHTMLSTYLEELEMENT
 
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
@@ -91,17 +84,16 @@ public:
   void SetScoped(bool aScoped, ErrorResult& aError)
   {
     SetHTMLBoolAttr(nsGkAtoms::scoped, aScoped, aError);
   }
 
   virtual JSObject* WrapNode(JSContext *aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
 protected:
   already_AddRefed<nsIURI> GetStyleSheetURL(bool* aIsInline) MOZ_OVERRIDE;
   void GetStyleSheetInfo(nsAString& aTitle,
                          nsAString& aType,
                          nsAString& aMedia,
                          bool* aIsScoped,
                          bool* aIsAlternate) MOZ_OVERRIDE;
   /**
--- a/content/html/content/src/HTMLTableCaptionElement.cpp
+++ b/content/html/content/src/HTMLTableCaptionElement.cpp
@@ -21,26 +21,18 @@ HTMLTableCaptionElement::~HTMLTableCapti
 }
 
 JSObject*
 HTMLTableCaptionElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aScope)
 {
   return HTMLTableCaptionElementBinding::Wrap(aCx, aScope, this);
 }
 
-NS_IMPL_ADDREF_INHERITED(HTMLTableCaptionElement, Element)
-NS_IMPL_RELEASE_INHERITED(HTMLTableCaptionElement, Element)
-
-// QueryInterface implementation for HTMLTableCaptionElement
-NS_INTERFACE_TABLE_HEAD(HTMLTableCaptionElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-  NS_INTERFACE_TABLE_INHERITED1(HTMLTableCaptionElement,
-                                nsIDOMHTMLTableCaptionElement)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
+NS_IMPL_ISUPPORTS_INHERITED1(HTMLTableCaptionElement, nsGenericHTMLElement,
+                             nsIDOMHTMLTableCaptionElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLTableCaptionElement)
 
 NS_IMPL_STRING_ATTR(HTMLTableCaptionElement, Align, align)
 
 static const nsAttrValue::EnumTable kCaptionAlignTable[] = {
   { "left",   NS_STYLE_CAPTION_SIDE_LEFT },
   { "right",  NS_STYLE_CAPTION_SIDE_RIGHT },
--- a/content/html/content/src/HTMLTableCaptionElement.h
+++ b/content/html/content/src/HTMLTableCaptionElement.h
@@ -20,25 +20,16 @@ public:
     : nsGenericHTMLElement(aNodeInfo)
   {
   }
   virtual ~HTMLTableCaptionElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   // nsIDOMHTMLTableCaptionElement
   NS_DECL_NSIDOMHTMLTABLECAPTIONELEMENT
 
   void GetAlign(nsString& aAlign)
   {
     GetHTMLAttr(nsGkAtoms::align, aAlign);
   }
   void SetAlign(const nsAString& aAlign, ErrorResult& aError)
@@ -50,18 +41,16 @@ public:
                                 nsIAtom* aAttribute,
                                 const nsAString& aValue,
                                 nsAttrValue& aResult) MOZ_OVERRIDE;
   virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const MOZ_OVERRIDE;
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
-
 protected:
   virtual JSObject* WrapNode(JSContext *aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 };
 
 } // namespace dom
 } // namespace mozilla
 
--- a/content/html/content/src/HTMLTableCellElement.cpp
+++ b/content/html/content/src/HTMLTableCellElement.cpp
@@ -25,27 +25,18 @@ HTMLTableCellElement::~HTMLTableCellElem
 }
 
 JSObject*
 HTMLTableCellElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aScope)
 {
   return HTMLTableCellElementBinding::Wrap(aCx, aScope, this);
 }
 
-NS_IMPL_ADDREF_INHERITED(HTMLTableCellElement, Element)
-NS_IMPL_RELEASE_INHERITED(HTMLTableCellElement, Element)
-
-// QueryInterface implementation for HTMLTableCellElement
-NS_INTERFACE_TABLE_HEAD(HTMLTableCellElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-  NS_INTERFACE_TABLE_INHERITED1(HTMLTableCellElement,
-                                nsIDOMHTMLTableCellElement)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
-
+NS_IMPL_ISUPPORTS_INHERITED1(HTMLTableCellElement, nsGenericHTMLElement,
+                             nsIDOMHTMLTableCellElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLTableCellElement)
 
 
 // protected method
 HTMLTableRowElement*
 HTMLTableCellElement::GetRow() const
 {
--- a/content/html/content/src/HTMLTableCellElement.h
+++ b/content/html/content/src/HTMLTableCellElement.h
@@ -24,25 +24,16 @@ public:
     : nsGenericHTMLElement(aNodeInfo)
   {
   }
   virtual ~HTMLTableCellElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   // nsIDOMHTMLTableCellElement
   NS_DECL_NSIDOMHTMLTABLECELLELEMENT
 
   uint32_t ColSpan() const
   {
     return GetIntAttr(nsGkAtoms::colspan, 1);
   }
   void SetColSpan(uint32_t aColSpan, ErrorResult& aError)
@@ -159,17 +150,16 @@ public:
                               const nsAString& aValue,
                               nsAttrValue& aResult) MOZ_OVERRIDE;
   virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const MOZ_OVERRIDE;
   NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker) MOZ_OVERRIDE;
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
 protected:
   virtual JSObject* WrapNode(JSContext *aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
   HTMLTableElement* GetTable() const;
 
   HTMLTableRowElement* GetRow() const;
 };
--- a/content/html/content/src/HTMLTableColElement.cpp
+++ b/content/html/content/src/HTMLTableColElement.cpp
@@ -25,24 +25,16 @@ HTMLTableColElement::~HTMLTableColElemen
 }
 
 JSObject*
 HTMLTableColElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aScope)
 {
   return HTMLTableColElementBinding::Wrap(aCx, aScope, this);
 }
 
-NS_IMPL_ADDREF_INHERITED(HTMLTableColElement, Element)
-NS_IMPL_RELEASE_INHERITED(HTMLTableColElement, Element)
-
-// QueryInterface implementation for HTMLTableColElement
-NS_INTERFACE_MAP_BEGIN(HTMLTableColElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-NS_ELEMENT_INTERFACE_MAP_END
-
 NS_IMPL_ELEMENT_CLONE(HTMLTableColElement)
 
 bool
 HTMLTableColElement::ParseAttribute(int32_t aNamespaceID,
                                     nsIAtom* aAttribute,
                                     const nsAString& aValue,
                                     nsAttrValue& aResult)
 {
--- a/content/html/content/src/HTMLTableColElement.h
+++ b/content/html/content/src/HTMLTableColElement.h
@@ -6,38 +6,25 @@
 #define mozilla_dom_HTMLTableColElement_h
 
 #include "mozilla/Attributes.h"
 #include "nsGenericHTMLElement.h"
 
 namespace mozilla {
 namespace dom {
 
-class HTMLTableColElement MOZ_FINAL : public nsGenericHTMLElement,
-                                      public nsIDOMHTMLElement
+class HTMLTableColElement MOZ_FINAL : public nsGenericHTMLElement
 {
 public:
   HTMLTableColElement(already_AddRefed<nsINodeInfo> aNodeInfo)
     : nsGenericHTMLElement(aNodeInfo)
   {
   }
   virtual ~HTMLTableColElement();
 
-  // nsISupports
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   uint32_t Span() const
   {
     return GetIntAttr(nsGkAtoms::span, 1);
   }
   void SetSpan(uint32_t aSpan, ErrorResult& aError)
   {
     SetHTMLIntAttr(nsGkAtoms::span, aSpan, aError);
   }
@@ -87,18 +74,16 @@ public:
                                 nsIAtom* aAttribute,
                                 const nsAString& aValue,
                                 nsAttrValue& aResult) MOZ_OVERRIDE;
   nsMapRuleToAttributesFunc GetAttributeMappingFunction() const MOZ_OVERRIDE;
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
-
 protected:
   virtual JSObject* WrapNode(JSContext *aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 };
 
 } // namespace dom
 } // namespace mozilla
 
--- a/content/html/content/src/HTMLTableElement.cpp
+++ b/content/html/content/src/HTMLTableElement.cpp
@@ -327,20 +327,18 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRows)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_ADDREF_INHERITED(HTMLTableElement, Element)
 NS_IMPL_RELEASE_INHERITED(HTMLTableElement, Element)
 
 // QueryInterface implementation for HTMLTableElement
 NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(HTMLTableElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
   NS_INTERFACE_TABLE_INHERITED1(HTMLTableElement, nsIDOMHTMLTableElement)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
+NS_INTERFACE_TABLE_TAIL_INHERITING(nsGenericHTMLElement)
 
 
 NS_IMPL_ELEMENT_CLONE(HTMLTableElement)
 
 
 // the DOM spec says border, cellpadding, cellSpacing are all "wstring"
 // in fact, they are integers or they are meaningless.  so we store them
 // here as ints.
@@ -468,17 +466,17 @@ already_AddRefed<nsGenericHTMLElement>
 HTMLTableElement::CreateTBody()
 {
   nsCOMPtr<nsINodeInfo> nodeInfo =
     OwnerDoc()->NodeInfoManager()->GetNodeInfo(nsGkAtoms::tbody, nullptr,
                                                kNameSpaceID_XHTML,
                                                nsIDOMNode::ELEMENT_NODE);
   MOZ_ASSERT(nodeInfo);
 
-  nsCOMPtr<nsGenericHTMLElement> newBody =
+  nsRefPtr<nsGenericHTMLElement> newBody =
     NS_NewHTMLTableSectionElement(nodeInfo.forget());
   MOZ_ASSERT(newBody);
 
   nsIContent* referenceNode = nullptr;
   for (nsIContent* child = nsINode::GetLastChild();
        child;
        child = child->GetPreviousSibling()) {
     if (child->IsHTML(nsGkAtoms::tbody)) {
--- a/content/html/content/src/HTMLTableElement.h
+++ b/content/html/content/src/HTMLTableElement.h
@@ -25,25 +25,16 @@ public:
   HTMLTableElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~HTMLTableElement();
 
   NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLTableElement, table)
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   HTMLTableCaptionElement* GetCaption() const
   {
     return static_cast<HTMLTableCaptionElement*>(GetChild(nsGkAtoms::caption));
   }
   void SetCaption(HTMLTableCaptionElement* aCaption)
   {
     DeleteCaption();
     if (aCaption) {
@@ -183,17 +174,16 @@ public:
                                 nsIAtom* aAttribute,
                                 const nsAString& aValue,
                                 nsAttrValue& aResult) MOZ_OVERRIDE;
   virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const MOZ_OVERRIDE;
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               bool aCompileEventHandlers) MOZ_OVERRIDE;
   virtual void UnbindFromTree(bool aDeep = true,
                               bool aNullParent = true) MOZ_OVERRIDE;
   /**
    * Called when an attribute is about to be changed
    */
--- a/content/html/content/src/HTMLTableRowElement.cpp
+++ b/content/html/content/src/HTMLTableRowElement.cpp
@@ -33,18 +33,17 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCells)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_ADDREF_INHERITED(HTMLTableRowElement, Element)
 NS_IMPL_RELEASE_INHERITED(HTMLTableRowElement, Element)
 
 // QueryInterface implementation for HTMLTableRowElement
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(HTMLTableRowElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-NS_ELEMENT_INTERFACE_MAP_END
+NS_INTERFACE_MAP_END_INHERITING(nsGenericHTMLElement)
 
 
 NS_IMPL_ELEMENT_CLONE(HTMLTableRowElement)
 
 
 // protected method
 HTMLTableSectionElement*
 HTMLTableRowElement::GetSection() const
--- a/content/html/content/src/HTMLTableRowElement.h
+++ b/content/html/content/src/HTMLTableRowElement.h
@@ -11,39 +11,29 @@
 class nsIDOMHTMLTableElement;
 class nsContentList;
 
 namespace mozilla {
 namespace dom {
 
 class HTMLTableSectionElement;
 
-class HTMLTableRowElement MOZ_FINAL : public nsGenericHTMLElement,
-                                      public nsIDOMHTMLElement
+class HTMLTableRowElement MOZ_FINAL : public nsGenericHTMLElement
 {
 public:
   HTMLTableRowElement(already_AddRefed<nsINodeInfo> aNodeInfo)
     : nsGenericHTMLElement(aNodeInfo)
   {
   }
 
   NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLTableRowElement, tr)
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   int32_t RowIndex() const;
   int32_t SectionRowIndex() const;
   nsIHTMLCollection* Cells();
   already_AddRefed<nsGenericHTMLElement>
     InsertCell(int32_t aIndex, ErrorResult& aError);
   void DeleteCell(int32_t aValue, ErrorResult& aError);
 
   void GetAlign(nsString& aAlign)
@@ -91,18 +81,16 @@ public:
                                 nsIAtom* aAttribute,
                                 const nsAString& aValue,
                                 nsAttrValue& aResult) MOZ_OVERRIDE;
   virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const MOZ_OVERRIDE;
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
-
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(HTMLTableRowElement,
                                                      nsGenericHTMLElement)
 
 protected:
   virtual JSObject* WrapNode(JSContext *aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
   HTMLTableSectionElement* GetSection() const;
--- a/content/html/content/src/HTMLTableSectionElement.cpp
+++ b/content/html/content/src/HTMLTableSectionElement.cpp
@@ -33,18 +33,17 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRows)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_ADDREF_INHERITED(HTMLTableSectionElement, Element)
 NS_IMPL_RELEASE_INHERITED(HTMLTableSectionElement, Element)
 
 // QueryInterface implementation for HTMLTableSectionElement
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(HTMLTableSectionElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-NS_ELEMENT_INTERFACE_MAP_END
+NS_INTERFACE_MAP_END_INHERITING(nsGenericHTMLElement)
 
 
 NS_IMPL_ELEMENT_CLONE(HTMLTableSectionElement)
 
 nsIHTMLCollection*
 HTMLTableSectionElement::Rows()
 {
   if (!mRows) {
--- a/content/html/content/src/HTMLTableSectionElement.h
+++ b/content/html/content/src/HTMLTableSectionElement.h
@@ -7,37 +7,27 @@
 
 #include "mozilla/Attributes.h"
 #include "nsGenericHTMLElement.h"
 #include "nsContentList.h" // For ctor.
 
 namespace mozilla {
 namespace dom {
 
-class HTMLTableSectionElement MOZ_FINAL : public nsGenericHTMLElement,
-                                          public nsIDOMHTMLElement
+class HTMLTableSectionElement MOZ_FINAL : public nsGenericHTMLElement
 {
 public:
   HTMLTableSectionElement(already_AddRefed<nsINodeInfo> aNodeInfo)
     : nsGenericHTMLElement(aNodeInfo)
   {
   }
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   nsIHTMLCollection* Rows();
   already_AddRefed<nsGenericHTMLElement>
     InsertRow(int32_t aIndex, ErrorResult& aError);
   void DeleteRow(int32_t aValue, ErrorResult& aError);
 
   void GetAlign(nsString& aAlign)
   {
     GetHTMLAttr(nsGkAtoms::align, aAlign);
@@ -77,18 +67,16 @@ public:
                               nsAttrValue& aResult) MOZ_OVERRIDE;
   virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const MOZ_OVERRIDE;
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(HTMLTableSectionElement,
                                                      nsGenericHTMLElement)
-
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
 protected:
   virtual JSObject* WrapNode(JSContext *aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
   nsRefPtr<nsContentList> mRows;
 };
 
 } // namespace dom
--- a/content/html/content/src/HTMLTemplateElement.cpp
+++ b/content/html/content/src/HTMLTemplateElement.cpp
@@ -66,18 +66,17 @@ NS_IMPL_ADDREF_INHERITED(HTMLTemplateEle
 NS_IMPL_RELEASE_INHERITED(HTMLTemplateElement, Element)
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED_1(HTMLTemplateElement,
                                      nsGenericHTMLElement,
                                      mContent)
 
 // QueryInterface implementation for HTMLTemplateElement
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(HTMLTemplateElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-NS_ELEMENT_INTERFACE_MAP_END
+NS_INTERFACE_MAP_END_INHERITING(nsGenericHTMLElement)
 
 NS_IMPL_ELEMENT_CLONE_WITH_INIT(HTMLTemplateElement)
 
 JSObject*
 HTMLTemplateElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aScope)
 {
   return HTMLTemplateElementBinding::Wrap(aCx, aScope, this);
 }
--- a/content/html/content/src/HTMLTemplateElement.h
+++ b/content/html/content/src/HTMLTemplateElement.h
@@ -9,42 +9,30 @@
 #include "mozilla/Attributes.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsGenericHTMLElement.h"
 #include "mozilla/dom/DocumentFragment.h"
 
 namespace mozilla {
 namespace dom {
 
-class HTMLTemplateElement MOZ_FINAL : public nsGenericHTMLElement,
-                                      public nsIDOMHTMLElement
+class HTMLTemplateElement MOZ_FINAL : public nsGenericHTMLElement
 {
 public:
   HTMLTemplateElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~HTMLTemplateElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLTemplateElement,
                                            nsGenericHTMLElement)
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
-
   nsresult Init();
 
   DocumentFragment* Content()
   {
     return mContent;
   }
 
 protected:
--- a/content/html/content/src/HTMLTextAreaElement.cpp
+++ b/content/html/content/src/HTMLTextAreaElement.cpp
@@ -80,25 +80,23 @@ NS_IMPL_CYCLE_COLLECTION_INHERITED_3(HTM
                                      mState)
 
 NS_IMPL_ADDREF_INHERITED(HTMLTextAreaElement, Element)
 NS_IMPL_RELEASE_INHERITED(HTMLTextAreaElement, Element)
 
 
 // QueryInterface implementation for HTMLTextAreaElement
 NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(HTMLTextAreaElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLFormElementWithState)
   NS_INTERFACE_TABLE_INHERITED5(HTMLTextAreaElement,
                                 nsIDOMHTMLTextAreaElement,
                                 nsITextControlElement,
                                 nsIDOMNSEditableElement,
                                 nsIMutationObserver,
                                 nsIConstraintValidation)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
+NS_INTERFACE_TABLE_TAIL_INHERITING(nsGenericHTMLFormElementWithState)
 
 
 // nsIDOMHTMLTextAreaElement
 
 
 NS_IMPL_ELEMENT_CLONE(HTMLTextAreaElement)
 
 // nsIConstraintValidation
--- a/content/html/content/src/HTMLTextAreaElement.h
+++ b/content/html/content/src/HTMLTextAreaElement.h
@@ -41,25 +41,16 @@ public:
   using nsIConstraintValidation::GetValidationMessage;
 
   HTMLTextAreaElement(already_AddRefed<nsINodeInfo> aNodeInfo,
                       FromParser aFromParser = NOT_FROM_PARSER);
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   virtual int32_t TabIndexDefault() MOZ_OVERRIDE;
 
   // nsIDOMHTMLTextAreaElement
   NS_DECL_NSIDOMHTMLTEXTAREAELEMENT
 
   // nsIDOMNSEditableElement
   NS_IMETHOD GetEditor(nsIEditor** aEditor) MOZ_OVERRIDE
   {
@@ -144,18 +135,16 @@ public:
   NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLTextAreaElement,
                                            nsGenericHTMLFormElementWithState)
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
-
   // nsIConstraintValidation
   bool     IsTooLong();
   bool     IsValueMissing() const;
   void     UpdateTooLongValidityState();
   void     UpdateValueMissingValidityState();
   void     UpdateBarredFromConstraintValidation();
   nsresult GetValidationMessage(nsAString& aValidationMessage,
                                 ValidityStateType aType) MOZ_OVERRIDE;
--- a/content/html/content/src/HTMLTimeElement.cpp
+++ b/content/html/content/src/HTMLTimeElement.cpp
@@ -19,23 +19,16 @@ HTMLTimeElement::HTMLTimeElement(already
   : nsGenericHTMLElement(aNodeInfo)
 {
 }
 
 HTMLTimeElement::~HTMLTimeElement()
 {
 }
 
-NS_IMPL_ADDREF_INHERITED(HTMLTimeElement, Element)
-NS_IMPL_RELEASE_INHERITED(HTMLTimeElement, Element)
-
-NS_INTERFACE_MAP_BEGIN(HTMLTimeElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-NS_ELEMENT_INTERFACE_MAP_END
-
 NS_IMPL_ELEMENT_CLONE(HTMLTimeElement)
 
 JSObject*
 HTMLTimeElement::WrapNode(JSContext* cx, JS::Handle<JSObject*> scope)
 {
   return HTMLTimeElementBinding::Wrap(cx, scope, this);
 }
 
--- a/content/html/content/src/HTMLTimeElement.h
+++ b/content/html/content/src/HTMLTimeElement.h
@@ -9,50 +9,36 @@
 #include "mozilla/Attributes.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsGenericHTMLElement.h"
 #include "nsGkAtoms.h"
 
 namespace mozilla {
 namespace dom {
 
-class HTMLTimeElement MOZ_FINAL : public nsGenericHTMLElement,
-                                  public nsIDOMHTMLElement
+class HTMLTimeElement MOZ_FINAL : public nsGenericHTMLElement
 {
 public:
   HTMLTimeElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~HTMLTimeElement();
 
-  // nsISupports
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   // HTMLTimeElement WebIDL
   void GetDateTime(nsAString& aDateTime)
   {
     GetHTMLAttr(nsGkAtoms::datetime, aDateTime);
   }
 
   void SetDateTime(const nsAString& aDateTime, ErrorResult& aError)
   {
     SetHTMLAttr(nsGkAtoms::datetime, aDateTime, aError);
   }
 
   virtual void GetItemValueText(nsAString& text) MOZ_OVERRIDE;
   virtual void SetItemValueText(const nsAString& text) MOZ_OVERRIDE;
   virtual nsresult Clone(nsINodeInfo* aNodeInfo, nsINode** aResult) const MOZ_OVERRIDE;
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
 
 protected:
   virtual JSObject* WrapNode(JSContext* aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/content/html/content/src/HTMLTitleElement.cpp
+++ b/content/html/content/src/HTMLTitleElement.cpp
@@ -22,35 +22,18 @@ HTMLTitleElement::HTMLTitleElement(alrea
 {
   AddMutationObserver(this);
 }
 
 HTMLTitleElement::~HTMLTitleElement()
 {
 }
 
-
-NS_IMPL_ADDREF_INHERITED(HTMLTitleElement, Element)
-NS_IMPL_RELEASE_INHERITED(HTMLTitleElement, Element)
-
-} // namespace dom
-} // namespace mozilla
-
-namespace mozilla {
-namespace dom {
-
-// QueryInterface implementation for HTMLTitleElement
-NS_INTERFACE_TABLE_HEAD(HTMLTitleElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-  NS_INTERFACE_TABLE_INHERITED2(HTMLTitleElement,
-                                nsIDOMHTMLTitleElement,
-                                nsIMutationObserver)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
-
+NS_IMPL_ISUPPORTS_INHERITED2(HTMLTitleElement, nsGenericHTMLElement,
+                             nsIDOMHTMLTitleElement, nsIMutationObserver)
 
 NS_IMPL_ELEMENT_CLONE(HTMLTitleElement)
 
 JSObject*
 HTMLTitleElement::WrapNode(JSContext* cx, JS::Handle<JSObject*> scope)
 {
   return HTMLTitleElementBinding::Wrap(cx, scope, this);
 }
--- a/content/html/content/src/HTMLTitleElement.h
+++ b/content/html/content/src/HTMLTitleElement.h
@@ -25,25 +25,16 @@ public:
   using Element::SetText;
 
   HTMLTitleElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~HTMLTitleElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   // nsIDOMHTMLTitleElement
   NS_DECL_NSIDOMHTMLTITLEELEMENT
 
   //HTMLTitleElement
   //The xpcom GetTextContent() never fails so we just use that.
   void SetText(const nsAString& aText, ErrorResult& aError)
   {
     aError = SetText(aText);
@@ -61,18 +52,16 @@ public:
                               nsIContent *aBindingParent,
                               bool aCompileEventHandlers) MOZ_OVERRIDE;
 
   virtual void UnbindFromTree(bool aDeep = true,
                               bool aNullParent = true) MOZ_OVERRIDE;
 
   virtual void DoneAddingChildren(bool aHaveNotified) MOZ_OVERRIDE;
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
-
 protected:
 
   virtual JSObject* WrapNode(JSContext* cx, JS::Handle<JSObject*> scope)
     MOZ_OVERRIDE MOZ_FINAL;
 
 private:
   void SendTitleChangeEvent(bool aBound);
 };
--- a/content/html/content/src/HTMLTrackElement.cpp
+++ b/content/html/content/src/HTMLTrackElement.cpp
@@ -83,18 +83,17 @@ NS_IMPL_ELEMENT_CLONE(HTMLTrackElement)
 NS_IMPL_ADDREF_INHERITED(HTMLTrackElement, Element)
 NS_IMPL_RELEASE_INHERITED(HTMLTrackElement, Element)
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED_4(HTMLTrackElement, nsGenericHTMLElement,
                                      mTrack, mChannel, mMediaParent,
                                      mLoadListener)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(HTMLTrackElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-NS_ELEMENT_INTERFACE_MAP_END
+NS_INTERFACE_MAP_END_INHERITING(nsGenericHTMLElement)
 
 void
 HTMLTrackElement::OnChannelRedirect(nsIChannel* aChannel,
                                     nsIChannel* aNewChannel,
                                     uint32_t aFlags)
 {
   NS_ASSERTION(aChannel == mChannel, "Channels should match!");
   mChannel = aNewChannel;
@@ -216,17 +215,17 @@ HTMLTrackElement::LoadResource()
     CheckLoadURIWithPrincipal(NodePrincipal(), uri,
                               nsIScriptSecurityManager::STANDARD);
   NS_ENSURE_TRUE_VOID(NS_SUCCEEDED(rv));
 
   int16_t shouldLoad = nsIContentPolicy::ACCEPT;
   rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_MEDIA,
                                  uri,
                                  NodePrincipal(),
-                                 static_cast<nsGenericHTMLElement*>(this),
+                                 static_cast<Element*>(this),
                                  NS_LITERAL_CSTRING("text/vtt"), // mime type
                                  nullptr, // extra
                                  &shouldLoad,
                                  nsContentUtils::GetContentPolicy(),
                                  nsContentUtils::GetSecurityManager());
   NS_ENSURE_TRUE_VOID(NS_SUCCEEDED(rv));
   if (NS_CP_REJECTED(shouldLoad)) {
     return;
--- a/content/html/content/src/HTMLTrackElement.h
+++ b/content/html/content/src/HTMLTrackElement.h
@@ -19,36 +19,26 @@
 #include "nsIHttpChannel.h"
 
 namespace mozilla {
 namespace dom {
 
 class WebVTTLoadListener;
 
 class HTMLTrackElement MOZ_FINAL : public nsGenericHTMLElement
-                                 , public nsIDOMHTMLElement
 {
 public:
   HTMLTrackElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~HTMLTrackElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLTrackElement,
                                            nsGenericHTMLElement)
 
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   // HTMLTrackElement WebIDL
   TextTrackKind Kind() const;
   void SetKind(TextTrackKind aKind, ErrorResult& aError);
 
   void GetSrc(DOMString& aSrc) const
   {
     GetHTMLURIAttr(nsGkAtoms::src, aSrc);
   }
@@ -102,17 +92,16 @@ public:
   uint16_t ReadyState() const
   {
     return mReadyState;
   }
 
   TextTrack* Track();
 
   virtual nsresult Clone(nsINodeInfo* aNodeInfo, nsINode** aResult) const MOZ_OVERRIDE;
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
 
   // For Track, ItemValue reflects the src attribute
   virtual void GetItemValueText(nsAString& aText) MOZ_OVERRIDE
   {
     DOMString value;
     GetSrc(value);
     aText = value;
   }
--- a/content/html/content/src/HTMLUnknownElement.cpp
+++ b/content/html/content/src/HTMLUnknownElement.cpp
@@ -7,19 +7,16 @@
 #include "mozilla/dom/HTMLUnknownElement.h"
 #include "mozilla/dom/HTMLElementBinding.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Unknown)
 
 namespace mozilla {
 namespace dom {
 
-NS_IMPL_ADDREF_INHERITED(HTMLUnknownElement, Element)
-NS_IMPL_RELEASE_INHERITED(HTMLUnknownElement, Element)
-
 JSObject*
 HTMLUnknownElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aScope)
 {
   JS::Rooted<JSObject*> obj(aCx,
     HTMLUnknownElementBinding::Wrap(aCx, aScope, this));
   if (obj && Substring(NodeName(), 0, 2).LowerCaseEqualsLiteral("x-")) {
     // If we have a registered x-tag then we fix the prototype.
     JSAutoCompartment ac(aCx, obj);
@@ -29,17 +26,12 @@ HTMLUnknownElement::WrapNode(JSContext *
     if (prototype) {
       NS_ENSURE_TRUE(JS_WrapObject(aCx, prototype.address()), nullptr);
       NS_ENSURE_TRUE(JS_SetPrototype(aCx, obj, prototype), nullptr);
     }
   }
   return obj;
 }
 
-// QueryInterface implementation for HTMLUnknownElement
-NS_INTERFACE_MAP_BEGIN(HTMLUnknownElement)
-  NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
-NS_ELEMENT_INTERFACE_MAP_END
-
 NS_IMPL_ELEMENT_CLONE(HTMLUnknownElement)
 
 } // namespace dom
 } // namespace mozilla
--- a/content/html/content/src/HTMLUnknownElement.h
+++ b/content/html/content/src/HTMLUnknownElement.h
@@ -7,43 +7,28 @@
 
 #include "mozilla/Attributes.h"
 #include "nsGenericHTMLElement.h"
 
 namespace mozilla {
 namespace dom {
 
 class HTMLUnknownElement MOZ_FINAL : public nsGenericHTMLElement
-                                   , public nsIDOMHTMLElement
 {
 public:
   HTMLUnknownElement(already_AddRefed<nsINodeInfo> aNodeInfo)
     : nsGenericHTMLElement(aNodeInfo)
   {
     if (NodeInfo()->Equals(nsGkAtoms::bdi)) {
       SetHasDirAuto();
     }
   }
 
-  // nsISupports
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
-
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
-  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
-
 protected:
   virtual JSObject* WrapNode(JSContext *aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 };
 
 } // namespace dom
 } // namespace mozilla
 
--- a/content/html/content/src/HTMLVideoElement.cpp
+++ b/content/html/content/src/HTMLVideoElement.cpp
@@ -37,24 +37,18 @@
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Video)
 
 namespace mozilla {
 namespace dom {
 
 static bool sVideoStatsEnabled;
 
-NS_IMPL_ADDREF_INHERITED(HTMLVideoElement, HTMLMediaElement)
-NS_IMPL_RELEASE_INHERITED(HTMLVideoElement, HTMLMediaElement)
-
-NS_INTERFACE_TABLE_HEAD(HTMLVideoElement)
-  NS_HTML_CONTENT_INTERFACES(HTMLMediaElement)
-  NS_INTERFACE_TABLE_INHERITED2(HTMLVideoElement, nsIDOMHTMLMediaElement, nsIDOMHTMLVideoElement)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
+NS_IMPL_ISUPPORTS_INHERITED2(HTMLVideoElement, HTMLMediaElement,
+                             nsIDOMHTMLMediaElement, nsIDOMHTMLVideoElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLVideoElement)
 
 // nsIDOMHTMLVideoElement
 NS_IMPL_INT_ATTR(HTMLVideoElement, Width, width)
 NS_IMPL_INT_ATTR(HTMLVideoElement, Height, height)
 
 // nsIDOMHTMLVideoElement
--- a/content/html/content/src/nsGenericHTMLElement.cpp
+++ b/content/html/content/src/nsGenericHTMLElement.cpp
@@ -23,17 +23,16 @@
 #include "nsIDOMHTMLMenuElement.h"
 #include "nsIDOMElementCSSInlineStyle.h"
 #include "nsIDOMWindow.h"
 #include "nsIDOMDocument.h"
 #include "nsEventListenerManager.h"
 #include "nsMappedAttributes.h"
 #include "nsHTMLStyleSheet.h"
 #include "nsIHTMLDocument.h"
-#include "nsILink.h"
 #include "nsPIDOMWindow.h"
 #include "nsIStyleRule.h"
 #include "nsIURL.h"
 #include "nsNetUtil.h"
 #include "nsEscape.h"
 #include "nsIFrame.h"
 #include "nsIScrollableFrame.h"
 #include "nsView.h"
@@ -80,16 +79,17 @@
 #include "nsITextControlElement.h"
 #include "mozilla/dom/Element.h"
 #include "HTMLFieldSetElement.h"
 #include "HTMLMenuElement.h"
 #include "nsAsyncDOMEvent.h"
 #include "nsDOMMutationObserver.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/FromParser.h"
+#include "mozilla/dom/Link.h"
 #include "mozilla/dom/UndoManager.h"
 #include "mozilla/BloomFilter.h"
 
 #include "HTMLPropertiesCollection.h"
 #include "nsVariant.h"
 #include "nsDOMSettableTokenList.h"
 #include "nsThreadUtils.h"
 #include "nsTextFragment.h"
@@ -249,36 +249,26 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(nsGeneri
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsGenericHTMLElementTearoff)
 
 NS_INTERFACE_TABLE_HEAD(nsGenericHTMLElementTearoff)
   NS_INTERFACE_TABLE_INHERITED1(nsGenericHTMLElementTearoff,
                                 nsIDOMElementCSSInlineStyle)
   NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(nsGenericHTMLElementTearoff)
 NS_INTERFACE_MAP_END_AGGREGATED(mElement)
 
-nsresult
-nsGenericHTMLElement::DOMQueryInterface(nsIDOMHTMLElement *aElement,
-                                        REFNSIID aIID, void **aInstancePtr)
-{
-  NS_PRECONDITION(aInstancePtr, "null out param");
-
-  nsresult rv = NS_ERROR_FAILURE;
-
-  NS_INTERFACE_TABLE_BEGIN
-    NS_INTERFACE_TABLE_ENTRY(nsIDOMHTMLElement, nsIDOMNode)
-    NS_INTERFACE_TABLE_ENTRY(nsIDOMHTMLElement, nsIDOMElement)
-    NS_INTERFACE_TABLE_ENTRY(nsIDOMHTMLElement, nsIDOMHTMLElement)
-  NS_INTERFACE_TABLE_END_WITH_PTR(aElement)
-
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
+NS_IMPL_ADDREF_INHERITED(nsGenericHTMLElement, nsGenericHTMLElementBase)
+NS_IMPL_RELEASE_INHERITED(nsGenericHTMLElement, nsGenericHTMLElementBase)
+
+NS_INTERFACE_MAP_BEGIN(nsGenericHTMLElement)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMHTMLElement)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMElement)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMNode)
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMElementCSSInlineStyle,
                                  new nsGenericHTMLElementTearoff(this))
-  NS_INTERFACE_MAP_END
-
-// No closing bracket, because NS_INTERFACE_MAP_END does that for us.
+NS_INTERFACE_MAP_END_INHERITING(nsGenericHTMLElementBase)
 
 nsresult
 nsGenericHTMLElement::CopyInnerTo(Element* aDst)
 {
   nsresult rv;
   int32_t i, count = GetAttrCount();
   for (i = 0; i < count; ++i) {
     const nsAttrName *name = mAttrsAndChildren.AttrNameAt(i);
@@ -320,17 +310,17 @@ nsGenericHTMLElement::Dataset()
     // AddRef is called before returning the pointer.
     slots->mDataset = new nsDOMStringMap(this);
   }
 
   nsRefPtr<nsDOMStringMap> ret = slots->mDataset;
   return ret.forget();
 }
 
-nsresult
+NS_IMETHODIMP
 nsGenericHTMLElement::GetDataset(nsISupports** aDataset)
 {
   *aDataset = Dataset().get();
   return NS_OK;
 }
 
 nsresult
 nsGenericHTMLElement::ClearDataset()
@@ -347,17 +337,17 @@ nsGenericHTMLElement::ClearDataset()
 static const nsAttrValue::EnumTable kDirTable[] = {
   { "ltr", eDir_LTR },
   { "rtl", eDir_RTL },
   { "auto", eDir_Auto },
   { 0 }
 };
 
 void
-nsGenericHTMLElement::GetAccessKeyLabel(nsAString& aLabel)
+nsGenericHTMLElement::GetAccessKeyLabel(nsString& aLabel)
 {
   nsPresContext *presContext = GetPresContext();
 
   if (presContext) {
     nsAutoString suffix;
     GetAccessKey(suffix);
     if (!suffix.IsEmpty() && 
         presContext->EventStateManager()->GetAccessKeyLabelPrefix(aLabel)) {
@@ -523,17 +513,17 @@ nsGenericHTMLElement::Spellcheck()
   }
 
   // Is this a chrome element?
   if (nsContentUtils::IsChromeDoc(OwnerDoc())) {
     return false;                       // Not spellchecked by default
   }
 
   // Anything else that's not a form control is not spellchecked by default
-  nsCOMPtr<nsIFormControl> formControl = do_QueryInterface(this);
+  nsCOMPtr<nsIFormControl> formControl = do_QueryObject(this);
   if (!formControl) {
     return false;                       // Not spellchecked by default
   }
 
   // Is this a multiline plaintext input?
   int32_t controlType = formControl->GetType();
   if (controlType == NS_FORM_TEXTAREA) {
     return true;             // Spellchecked by default
@@ -699,18 +689,18 @@ nsGenericHTMLElement::FindAncestorForm(H
   }
 
   return nullptr;
 }
 
 bool
 nsGenericHTMLElement::CheckHandleEventForAnchorsPreconditions(nsEventChainVisitor& aVisitor)
 {
-  NS_PRECONDITION(nsCOMPtr<nsILink>(do_QueryInterface(this)),
-                  "should be called only when |this| implements |nsILink|");
+  NS_PRECONDITION(nsCOMPtr<Link>(do_QueryObject(this)),
+                  "should be called only when |this| implements |Link|");
 
   if (!aVisitor.mPresContext) {
     // We need a pres context to do link stuff. Some events (e.g. mutation
     // events) don't have one.
     // XXX: ideally, shouldn't we be able to do what we need without one?
     return false; 
   }
 
@@ -754,17 +744,17 @@ nsGenericHTMLElement::IsHTMLLink(nsIURI*
   *aURI = GetHrefURIForAnchors().get();
   // We promise out param is non-null if we return true, so base rv on it
   return *aURI != nullptr;
 }
 
 already_AddRefed<nsIURI>
 nsGenericHTMLElement::GetHrefURIForAnchors() const
 {
-  // This is used by the three nsILink implementations and
+  // This is used by the three Link implementations and
   // nsHTMLStyleElement.
 
   // Get href= attribute (relative URI).
 
   // We use the nsAttrValue's copy of the URI string to avoid copying.
   nsCOMPtr<nsIURI> uri;
   GetURIAttr(nsGkAtoms::href, nullptr, getter_AddRefs(uri));
 
@@ -1920,20 +1910,21 @@ nsGenericHTMLElement::GetContextMenu() c
     nsIDocument* doc = GetCurrentDoc();
     if (doc) {
       return HTMLMenuElement::FromContentOrNull(doc->GetElementById(value));
     }
   }
   return nullptr;
 }
 
-void
-nsGenericHTMLElement::GetContextMenu(nsIDOMHTMLMenuElement** aContextMenu) const
+NS_IMETHODIMP
+nsGenericHTMLElement::GetContextMenu(nsIDOMHTMLMenuElement** aContextMenu)
 {
   NS_IF_ADDREF(*aContextMenu = GetContextMenu());
+  return NS_OK;
 }
 
 bool
 nsGenericHTMLElement::IsLabelable() const
 {
   return Tag() == nsGkAtoms::progress ||
          Tag() == nsGkAtoms::meter;
 }
@@ -2034,19 +2025,19 @@ nsGenericHTMLFormElement::~nsGenericHTML
   if (mFieldSet) {
     mFieldSet->RemoveElement(this);
   }
 
   // Check that this element doesn't know anything about its form at this point.
   NS_ASSERTION(!mForm, "mForm should be null at this point!");
 }
 
-NS_IMPL_QUERY_INTERFACE_INHERITED1(nsGenericHTMLFormElement,
-                                   nsGenericHTMLElement,
-                                   nsIFormControl)
+NS_IMPL_ISUPPORTS_INHERITED1(nsGenericHTMLFormElement,
+                             nsGenericHTMLElement,
+                             nsIFormControl)
 
 nsINode*
 nsGenericHTMLFormElement::GetParentObject() const
 {
   // We use the parent chain to implement the scope for event handlers.
   return mForm ? static_cast<nsINode*>(mForm)
                : static_cast<nsINode*>(OwnerDoc());
 }
@@ -2711,18 +2702,17 @@ nsGenericHTMLElement::Blur(mozilla::Erro
   }
 }
 
 void
 nsGenericHTMLElement::Focus(ErrorResult& aError)
 {
   nsIFocusManager* fm = nsFocusManager::GetFocusManager();
   if (fm) {
-    nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(this);
-    aError = fm->SetFocus(elem, 0);
+    aError = fm->SetFocus(this, 0);
   }
 }
 
 void
 nsGenericHTMLElement::Click()
 {
   if (HandlingClick())
     return;
@@ -2743,17 +2733,17 @@ nsGenericHTMLElement::Click()
 
   // Click() is never called from native code, but it may be
   // called from chrome JS. Mark this event trusted if Click()
   // is called from chrome code.
   nsMouseEvent event(nsContentUtils::IsCallerChrome(),
                      NS_MOUSE_CLICK, nullptr, nsMouseEvent::eReal);
   event.inputSource = nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN;
 
-  nsEventDispatcher::Dispatch(this, context, &event);
+  nsEventDispatcher::Dispatch(static_cast<nsIContent*>(this), context, &event);
 
   ClearHandlingClick();
 }
 
 bool
 nsGenericHTMLElement::IsHTMLFocusable(bool aWithMouse,
                                       bool *aIsFocusable,
                                       int32_t *aTabIndex)
@@ -2837,30 +2827,29 @@ nsGenericHTMLElement::PerformAccesskey(b
 {
   nsPresContext *presContext = GetPresContext();
   if (!presContext)
     return;
 
   // It's hard to say what HTML4 wants us to do in all cases.
   nsIFocusManager* fm = nsFocusManager::GetFocusManager();
   if (fm) {
-    nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(this);
-    fm->SetFocus(elem, nsIFocusManager::FLAG_BYKEY);
+    fm->SetFocus(this, nsIFocusManager::FLAG_BYKEY);
   }
 
   if (aKeyCausesActivation) {
     // Click on it if the users prefs indicate to do so.
     nsMouseEvent event(aIsTrustedEvent, NS_MOUSE_CLICK,
                        nullptr, nsMouseEvent::eReal);
     event.inputSource = nsIDOMMouseEvent::MOZ_SOURCE_KEYBOARD;
 
     nsAutoPopupStatePusher popupStatePusher(aIsTrustedEvent ?
                                             openAllowed : openAbused);
 
-    nsEventDispatcher::Dispatch(this, presContext, &event);
+    nsEventDispatcher::Dispatch(static_cast<nsIContent*>(this), presContext, &event);
   }
 }
 
 const nsAttrName*
 nsGenericHTMLElement::InternalGetExistingAttrNameFromQName(const nsAString& aStr) const
 {
   if (IsInHTMLDocument()) {
     nsAutoString lower;
@@ -3183,17 +3172,17 @@ nsGenericHTMLElement::GetItemValue(nsIVa
 
   if (!HasAttr(kNameSpaceID_None, nsGkAtoms::itemprop)) {
     out->SetAsEmpty();
     out.forget(aValue);
     return NS_OK;
   }
 
   if (ItemScope()) {
-    out->SetAsISupports(static_cast<nsISupports*>(this));
+    out->SetAsISupports(static_cast<nsIContent*>(this));
   } else {
     nsAutoString string;
     GetItemValueText(string);
     out->SetAsAString(string);
   }
 
   out.forget(aValue);
   return NS_OK;
@@ -3307,20 +3296,21 @@ nsGenericHTMLElement::Properties()
   if (!properties) {
      properties = new HTMLPropertiesCollection(this);
      NS_ADDREF(properties);
      SetProperty(nsGkAtoms::microdataProperties, properties, HTMLPropertiesCollectionDestructor);
   }
   return properties;
 }
 
-void
+NS_IMETHODIMP
 nsGenericHTMLElement::GetProperties(nsISupports** aProperties)
 {
   NS_ADDREF(*aProperties = static_cast<nsIHTMLCollection*>(Properties()));
+  return NS_OK;
 }
 
 nsSize
 nsGenericHTMLElement::GetWidthHeightForImage(imgIRequest *aImageRequest)
 {
   nsSize size(0,0);
 
   nsIFrame* frame = GetPrimaryFrame(Flush_Layout);
--- a/content/html/content/src/nsGenericHTMLElement.h
+++ b/content/html/content/src/nsGenericHTMLElement.h
@@ -45,61 +45,55 @@ class HTMLMenuElement;
 }
 }
 
 typedef nsMappedAttributeElement nsGenericHTMLElementBase;
 
 /**
  * A common superclass for HTML elements
  */
-class nsGenericHTMLElement : public nsGenericHTMLElementBase
+class nsGenericHTMLElement : public nsGenericHTMLElementBase,
+                             public nsIDOMHTMLElement
 {
 public:
   nsGenericHTMLElement(already_AddRefed<nsINodeInfo> aNodeInfo)
     : nsGenericHTMLElementBase(aNodeInfo)
   {
     NS_ASSERTION(mNodeInfo->NamespaceID() == kNameSpaceID_XHTML,
                  "Unexpected namespace");
     AddStatesSilently(NS_EVENT_STATE_LTR);
     SetFlags(NODE_HAS_DIRECTION_LTR);
   }
 
-  NS_IMPL_FROMCONTENT(nsGenericHTMLElement, kNameSpaceID_XHTML)
+  NS_DECL_ISUPPORTS_INHERITED
 
-  /**
-   * Handle QI for the standard DOM interfaces (DOMNode, DOMElement,
-   * DOMHTMLElement) and handles tearoffs for other standard interfaces.
-   * @param aElement the element as nsIDOMHTMLElement*
-   * @param aIID the IID to QI to
-   * @param aInstancePtr the QI'd method [OUT]
-   * @see nsGenericHTMLElementTearoff
-   */
-  nsresult DOMQueryInterface(nsIDOMHTMLElement *aElement, REFNSIID aIID,
-                             void **aInstancePtr);
+  NS_IMPL_FROMCONTENT(nsGenericHTMLElement, kNameSpaceID_XHTML)
 
   // From Element
   nsresult CopyInnerTo(mozilla::dom::Element* aDest);
 
-  void GetTitle(nsAString& aTitle) const
+  void GetTitle(nsString& aTitle)
   {
     GetHTMLAttr(nsGkAtoms::title, aTitle);
   }
-  void SetTitle(const nsAString& aTitle)
+  NS_IMETHODIMP SetTitle(const nsAString& aTitle)
   {
     SetHTMLAttr(nsGkAtoms::title, aTitle);
+    return NS_OK;
   }
-  void GetLang(nsAString& aLang) const
+  void GetLang(nsString& aLang)
   {
     GetHTMLAttr(nsGkAtoms::lang, aLang);
   }
-  void SetLang(const nsAString& aLang)
+  NS_IMETHODIMP SetLang(const nsAString& aLang)
   {
     SetHTMLAttr(nsGkAtoms::lang, aLang);
+    return NS_OK;
   }
-  void GetDir(nsAString& aDir) const
+  void GetDir(nsString& aDir)
   {
     GetHTMLEnumAttr(nsGkAtoms::dir, aDir);
   }
   void SetDir(const nsAString& aDir, mozilla::ErrorResult& aError)
   {
     SetHTMLAttr(nsGkAtoms::dir, aDir, aError);
   }
   already_AddRefed<nsDOMStringMap> Dataset();
@@ -110,17 +104,17 @@ public:
   void SetItemScope(bool aItemScope, mozilla::ErrorResult& aError)
   {
     SetHTMLBoolAttr(nsGkAtoms::itemscope, aItemScope, aError);
   }
   nsDOMSettableTokenList* ItemType()
   {
     return GetTokenList(nsGkAtoms::itemtype);
   }
-  void GetItemId(nsAString& aItemId) const
+  void GetItemId(nsString& aItemId)
   {
     GetHTMLURIAttr(nsGkAtoms::itemid, aItemId);
   }
   void SetItemId(const nsAString& aItemID, mozilla::ErrorResult& aError)
   {
     SetHTMLAttr(nsGkAtoms::itemid, aItemID, aError);
   }
   nsDOMSettableTokenList* ItemRef()
@@ -158,38 +152,38 @@ public:
     return GetIntAttr(nsGkAtoms::tabindex, TabIndexDefault());
   }
   void SetTabIndex(int32_t aTabIndex, mozilla::ErrorResult& aError)
   {
     SetHTMLIntAttr(nsGkAtoms::tabindex, aTabIndex, aError);
   }
   virtual void Focus(mozilla::ErrorResult& aError);
   void Blur(mozilla::ErrorResult& aError);
-  void GetAccessKey(nsAString& aAccessKey) const
+  void GetAccessKey(nsString& aAccessKey)
   {
     GetHTMLAttr(nsGkAtoms::accesskey, aAccessKey);
   }
   void SetAccessKey(const nsAString& aAccessKey, mozilla::ErrorResult& aError)
   {
     SetHTMLAttr(nsGkAtoms::accesskey, aAccessKey, aError);
   }
-  void GetAccessKeyLabel(nsAString& aAccessKeyLabel);
+  void GetAccessKeyLabel(nsString& aAccessKeyLabel);
   virtual bool Draggable() const
   {
     return AttrValueIs(kNameSpaceID_None, nsGkAtoms::draggable,
                        nsGkAtoms::_true, eIgnoreCase);
   }
   void SetDraggable(bool aDraggable, mozilla::ErrorResult& aError)
   {
     SetHTMLAttr(nsGkAtoms::draggable,
                 aDraggable ? NS_LITERAL_STRING("true")
                            : NS_LITERAL_STRING("false"),
                 aError);
   }
-  void GetContentEditable(nsAString& aContentEditable) const
+  void GetContentEditable(nsString& aContentEditable)
   {
     ContentEditableTristate value = GetContentEditableValue();
     if (value == eTrue) {
       aContentEditable.AssignLiteral("true");
     } else if (value == eFalse) {
       aContentEditable.AssignLiteral("false");
     } else {
       aContentEditable.AssignLiteral("inherit");
@@ -252,17 +246,17 @@ public:
   using nsINode::SetOn##name_;                                                \
   already_AddRefed<mozilla::dom::EventHandlerNonNull> GetOn##name_();         \
   void SetOn##name_(mozilla::dom::EventHandlerNonNull* handler,               \
                     mozilla::ErrorResult& error);
 #include "nsEventNameList.h"
 #undef ERROR_EVENT
 #undef FORWARDED_EVENT
 #undef EVENT
-  void GetClassName(nsAString& aClassName)
+  void GetClassName(nsString& aClassName)
   {
     GetAttr(kNameSpaceID_None, nsGkAtoms::_class, aClassName);
   }
   void SetClassName(const nsAString& aClassName)
   {
     SetAttr(kNameSpaceID_None, nsGkAtoms::_class, aClassName, true);
   }
   mozilla::dom::Element* GetOffsetParent()
@@ -294,48 +288,268 @@ public:
   int32_t OffsetHeight()
   {
     mozilla::CSSIntRect rcFrame;
     GetOffsetRect(rcFrame);
 
     return rcFrame.height;
   }
 
-  // nsIDOMHTMLElement methods. Note that these are non-virtual
-  // methods, implementations are expected to forward calls to these
-  // methods.
-  NS_IMETHOD InsertAdjacentHTML(const nsAString& aPosition,
-                                const nsAString& aText);
-  NS_IMETHOD GetItemValue(nsIVariant** aValue);
-  NS_IMETHOD SetItemValue(nsIVariant* aValue);
 protected:
-  void GetProperties(nsISupports** aProperties);
-  void GetContextMenu(nsIDOMHTMLMenuElement** aContextMenu) const;
-
   // These methods are used to implement element-specific behavior of Get/SetItemValue
   // when an element has @itemprop but no @itemscope.
   virtual void GetItemValueText(nsAString& text);
   virtual void SetItemValueText(const nsAString& text);
   nsDOMSettableTokenList* GetTokenList(nsIAtom* aAtom);
   void GetTokenList(nsIAtom* aAtom, nsIVariant** aResult);
   nsresult SetTokenList(nsIAtom* aAtom, nsIVariant* aValue);
 public:
-  nsresult SetContentEditable(const nsAString &aContentEditable);
   virtual already_AddRefed<mozilla::dom::UndoManager> GetUndoManager();
   virtual bool UndoScope() MOZ_OVERRIDE;
   virtual void SetUndoScope(bool aUndoScope, mozilla::ErrorResult& aError) MOZ_OVERRIDE;
-  nsresult GetDataset(nsISupports** aDataset);
   // Callback for destructor of of dataset to ensure to null out weak pointer.
   nsresult ClearDataset();
 
   /**
    * Get width and height, using given image request if attributes are unset.
    */
   nsSize GetWidthHeightForImage(imgIRequest *aImageRequest);
 
+  // XPIDL methods
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
+
+  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
+
+  NS_IMETHOD GetId(nsAString& aId) MOZ_FINAL {
+    mozilla::dom::Element::GetId(aId);
+    return NS_OK;
+  }
+  NS_IMETHOD SetId(const nsAString& aId) MOZ_FINAL {
+    mozilla::dom::Element::SetId(aId);
+    return NS_OK;
+  }
+  NS_IMETHOD GetTitle(nsAString& aTitle) MOZ_FINAL {
+    nsString title;
+    GetTitle(title);
+    aTitle.Assign(title);
+    return NS_OK;
+  }
+  NS_IMETHOD GetLang(nsAString& aLang) MOZ_FINAL {
+    nsString lang;
+    GetLang(lang);
+    aLang.Assign(lang);
+    return NS_OK;
+  }
+  NS_IMETHOD GetDir(nsAString& aDir) MOZ_FINAL {
+    nsString dir;
+    GetDir(dir);
+    aDir.Assign(dir);
+    return NS_OK;
+  }
+  NS_IMETHOD SetDir(const nsAString& aDir) MOZ_FINAL {
+    mozilla::ErrorResult rv;
+    SetDir(aDir, rv);
+    return rv.ErrorCode();
+  }
+  NS_IMETHOD GetDOMClassName(nsAString& aClassName) MOZ_FINAL {
+    GetHTMLAttr(nsGkAtoms::_class, aClassName);
+    return NS_OK;
+  }
+  NS_IMETHOD SetDOMClassName(const nsAString& aClassName) MOZ_FINAL {
+    SetClassName(aClassName);
+    return NS_OK;
+  }
+  NS_IMETHOD GetDataset(nsISupports** aDataset) MOZ_FINAL;
+  NS_IMETHOD GetHidden(bool* aHidden) MOZ_FINAL {
+    *aHidden = Hidden();
+    return NS_OK;
+  }
+  NS_IMETHOD SetHidden(bool aHidden) MOZ_FINAL {
+    mozilla::ErrorResult rv;
+    SetHidden(aHidden, rv);
+    return rv.ErrorCode();
+  }
+  NS_IMETHOD DOMBlur() MOZ_FINAL {
+    mozilla::ErrorResult rv;
+    Blur(rv);
+    return rv.ErrorCode();
+  }
+  NS_IMETHOD GetItemScope(bool* aItemScope) MOZ_FINAL {
+    *aItemScope = ItemScope();
+    return NS_OK;
+  }
+  NS_IMETHOD SetItemScope(bool aItemScope) MOZ_FINAL {
+    mozilla::ErrorResult rv;
+    SetItemScope(aItemScope, rv);
+    return rv.ErrorCode();
+  }
+  NS_IMETHOD GetItemType(nsIVariant** aType) MOZ_FINAL {
+    GetTokenList(nsGkAtoms::itemtype, aType);
+    return NS_OK;
+  }
+  NS_IMETHOD SetItemType(nsIVariant* aType) MOZ_FINAL {
+    return SetTokenList(nsGkAtoms::itemtype, aType);
+  }
+  NS_IMETHOD GetItemId(nsAString& aId) MOZ_FINAL {
+    nsString id;
+    GetItemId(id);
+    aId.Assign(aId);
+    return NS_OK;
+  }
+  NS_IMETHOD SetItemId(const nsAString& aId) MOZ_FINAL {
+    mozilla::ErrorResult rv;
+    SetItemId(aId, rv);
+    return rv.ErrorCode();
+  }
+  NS_IMETHOD GetProperties(nsISupports** aReturn) MOZ_FINAL;
+  NS_IMETHOD GetItemValue(nsIVariant** aValue) MOZ_FINAL;
+  NS_IMETHOD SetItemValue(nsIVariant* aValue) MOZ_FINAL;
+  NS_IMETHOD GetItemRef(nsIVariant** aRef) MOZ_FINAL {
+    GetTokenList(nsGkAtoms::itemref, aRef);
+    return NS_OK;
+  }
+  NS_IMETHOD SetItemRef(nsIVariant* aRef) MOZ_FINAL {
+    return SetTokenList(nsGkAtoms::itemref, aRef);
+  }
+  NS_IMETHOD GetItemProp(nsIVariant** aProp) MOZ_FINAL {
+    GetTokenList(nsGkAtoms::itemprop, aProp);
+    return NS_OK;
+  }
+  NS_IMETHOD SetItemProp(nsIVariant* aProp) MOZ_FINAL {
+    return SetTokenList(nsGkAtoms::itemprop, aProp);
+  }
+  NS_IMETHOD GetAccessKey(nsAString& aAccessKey) MOZ_FINAL {
+    nsString accessKey;
+    GetAccessKey(accessKey);
+    aAccessKey.Assign(accessKey);
+    return NS_OK;
+  }
+  NS_IMETHOD SetAccessKey(const nsAString& aAccessKey) MOZ_FINAL {
+    mozilla::ErrorResult rv;
+    SetAccessKey(aAccessKey, rv);
+    return rv.ErrorCode();
+  }
+  NS_IMETHOD GetAccessKeyLabel(nsAString& aAccessKeyLabel) MOZ_FINAL {
+    nsString accessKeyLabel;
+    GetAccessKeyLabel(accessKeyLabel);
+    aAccessKeyLabel.Assign(accessKeyLabel);
+    return NS_OK;
+  }
+  NS_IMETHOD SetDraggable(bool aDraggable) MOZ_FINAL {
+    mozilla::ErrorResult rv;
+    SetDraggable(aDraggable, rv);
+    return rv.ErrorCode();
+  }
+  NS_IMETHOD GetContentEditable(nsAString& aContentEditable) MOZ_FINAL {
+    nsString contentEditable;
+    GetContentEditable(contentEditable);
+    aContentEditable.Assign(contentEditable);
+    return NS_OK;
+  }
+  NS_IMETHOD SetContentEditable(const nsAString& aContentEditable) MOZ_FINAL {
+    mozilla::ErrorResult rv;
+    SetContentEditable(aContentEditable, rv);
+    return rv.ErrorCode();
+  }
+  NS_IMETHOD GetIsContentEditable(bool* aIsContentEditable) MOZ_FINAL {
+    *aIsContentEditable = IsContentEditable();
+    return NS_OK;
+  }
+  NS_IMETHOD GetContextMenu(nsIDOMHTMLMenuElement** aContextMenu) MOZ_FINAL;
+  NS_IMETHOD GetSpellcheck(bool* aSpellcheck) MOZ_FINAL {
+    *aSpellcheck = Spellcheck();
+    return NS_OK;
+  }
+  NS_IMETHOD SetSpellcheck(bool aSpellcheck) MOZ_FINAL {
+    mozilla::ErrorResult rv;
+    SetSpellcheck(aSpellcheck, rv);
+    return rv.ErrorCode();
+  }
+  NS_IMETHOD GetOuterHTML(nsAString& aOuterHTML) MOZ_FINAL {
+    mozilla::ErrorResult rv;
+    mozilla::dom::Element::GetOuterHTML(aOuterHTML, rv);
+    return rv.ErrorCode();
+  }
+  NS_IMETHOD SetOuterHTML(const nsAString& aOuterHTML) MOZ_FINAL {
+    mozilla::ErrorResult rv;
+    mozilla::dom::Element::SetOuterHTML(aOuterHTML, rv);
+    return rv.ErrorCode();
+  }                                                                            \
+  NS_IMETHOD InsertAdjacentHTML(const nsAString& position,
+                                const nsAString& text) MOZ_FINAL;
+  NS_IMETHOD ScrollIntoView(bool top, uint8_t _argc) MOZ_FINAL {
+    if (!_argc) {
+      top = true;
+    }
+    mozilla::dom::Element::ScrollIntoView(top);
+    return NS_OK;
+  }
+  NS_IMETHOD GetOffsetParent(nsIDOMElement** aOffsetParent) MOZ_FINAL {
+    mozilla::dom::Element* offsetParent = GetOffsetParent();
+    if (!offsetParent) {
+      *aOffsetParent = nullptr;
+      return NS_OK;
+    }
+    return CallQueryInterface(offsetParent, aOffsetParent);
+  }
+  NS_IMETHOD GetOffsetTop(int32_t* aOffsetTop) MOZ_FINAL {
+    *aOffsetTop = OffsetTop();
+    return NS_OK;
+  }
+  NS_IMETHOD GetOffsetLeft(int32_t* aOffsetLeft) MOZ_FINAL {
+    *aOffsetLeft = OffsetLeft();
+    return NS_OK;
+  }
+  NS_IMETHOD GetOffsetWidth(int32_t* aOffsetWidth) MOZ_FINAL {
+    *aOffsetWidth = OffsetWidth();
+    return NS_OK;
+  }
+  NS_IMETHOD GetOffsetHeight(int32_t* aOffsetHeight) MOZ_FINAL {
+    *aOffsetHeight = OffsetHeight();
+    return NS_OK;
+  }
+  NS_IMETHOD DOMClick() MOZ_FINAL {
+    Click();
+    return NS_OK;
+  }
+  NS_IMETHOD GetTabIndex(int32_t* aTabIndex) MOZ_FINAL {
+    *aTabIndex = TabIndex();
+    return NS_OK;
+  }
+  NS_IMETHOD SetTabIndex(int32_t aTabIndex) MOZ_FINAL {
+    mozilla::ErrorResult rv;
+    SetTabIndex(aTabIndex, rv);
+    return rv.ErrorCode();
+  }
+  NS_IMETHOD Focus() MOZ_FINAL {
+    mozilla::ErrorResult rv;
+    Focus(rv);
+    return rv.ErrorCode();
+  }
+  NS_IMETHOD GetDraggable(bool* aDraggable) MOZ_FINAL {
+    *aDraggable = Draggable();
+    return NS_OK;
+  }
+  using mozilla::dom::Element::GetInnerHTML;
+  NS_IMETHOD GetInnerHTML(nsAString& aInnerHTML) MOZ_FINAL {
+    mozilla::ErrorResult rv;
+    GetInnerHTML(aInnerHTML, rv);
+    return rv.ErrorCode();
+  }
+  using mozilla::dom::Element::SetInnerHTML;
+  NS_IMETHOD SetInnerHTML(const nsAString& aInnerHTML) MOZ_FINAL {
+    mozilla::ErrorResult rv;
+    SetInnerHTML(aInnerHTML, rv);
+    return rv.ErrorCode();
+  }
+
+  using nsGenericHTMLElementBase::GetOwnerDocument;
+
+  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
+
 public:
   // Implementation for nsIContent
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               bool aCompileEventHandlers) MOZ_OVERRIDE;
   virtual void UnbindFromTree(bool aDeep = true,
                               bool aNullParent = true) MOZ_OVERRIDE;
   nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
@@ -1048,17 +1262,17 @@ ASSERT_NODE_FLAGS_SPACE(ELEMENT_TYPE_SPE
  */
 class nsGenericHTMLFormElement : public nsGenericHTMLElement,
                                  public nsIFormControl
 {
 public:
   nsGenericHTMLFormElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsGenericHTMLFormElement();
 
-  NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) MOZ_OVERRIDE;
+  NS_DECL_ISUPPORTS_INHERITED
 
   nsINode* GetParentObject() const;
 
   virtual bool IsNodeOfType(uint32_t aFlags) const MOZ_OVERRIDE;
   virtual void SaveSubtreeState() MOZ_OVERRIDE;
 
   // nsIFormControl
   virtual mozilla::dom::Element* GetFormElement() MOZ_OVERRIDE;
@@ -1452,276 +1666,21 @@ protected:
     return NS_OK;                                                                                 \
   }                                                                                               \
   NS_IMETHODIMP                                                                                   \
   _class::Set##_method(const nsAString& aValue)                                                   \
   {                                                                                               \
     return SetAttrHelper(nsGkAtoms::_atom, aValue);                                               \
   }
 
-/**
- * QueryInterface() implementation helper macros
- */
-
-#define NS_HTML_CONTENT_INTERFACES_AMBIGUOUS(_base, _base_if)                 \
-  {                                                                           \
-    nsresult html_rv = _base::QueryInterface(aIID, aInstancePtr);             \
-    if (NS_SUCCEEDED(html_rv))                                                \
-      return html_rv;                                                         \
-                                                                              \
-    html_rv = DOMQueryInterface(static_cast<_base_if *>(this), aIID,          \
-                                aInstancePtr);                                \
-    if (NS_SUCCEEDED(html_rv))                                                \
-      return html_rv;                                                         \
-  }
-
-#define NS_HTML_CONTENT_INTERFACES(_base)                                     \
-  NS_HTML_CONTENT_INTERFACES_AMBIGUOUS(_base, nsIDOMHTMLElement)
-
 #define NS_INTERFACE_MAP_ENTRY_IF_TAG(_interface, _tag)                       \
   NS_INTERFACE_MAP_ENTRY_CONDITIONAL(_interface,                              \
                                      mNodeInfo->Equals(nsGkAtoms::_tag))
 
 
-#define NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC                                \
-  NS_IMETHOD GetId(nsAString& aId) MOZ_FINAL {                                 \
-    mozilla::dom::Element::GetId(aId);                                         \
-    return NS_OK;                                                              \
-  }                                                                            \
-  NS_IMETHOD SetId(const nsAString& aId) MOZ_FINAL {                           \
-    mozilla::dom::Element::SetId(aId);                                         \
-    return NS_OK;                                                              \
-  }                                                                            \
-  NS_IMETHOD GetTitle(nsAString& aTitle) MOZ_FINAL {                           \
-    nsGenericHTMLElement::GetTitle(aTitle);                                    \
-    return NS_OK;                                                              \
-  }                                                                            \
-  NS_IMETHOD SetTitle(const nsAString& aTitle) MOZ_FINAL {                     \
-    nsGenericHTMLElement::SetTitle(aTitle);                                    \
-    return NS_OK;                                                              \
-  }                                                                            \
-  NS_IMETHOD GetLang(nsAString& aLang) MOZ_FINAL {                             \
-    nsGenericHTMLElement::GetLang(aLang);                                      \
-    return NS_OK;                                                              \
-  }                                                                            \
-  NS_IMETHOD SetLang(const nsAString& aLang) MOZ_FINAL {                       \
-    nsGenericHTMLElement::SetLang(aLang);                                      \
-    return NS_OK;                                                              \
-  }                                                                            \
-  NS_IMETHOD GetDir(nsAString& aDir) MOZ_FINAL {                               \
-    nsGenericHTMLElement::GetDir(aDir);                                        \
-    return NS_OK;                                                              \
-  }                                                                            \
-  NS_IMETHOD SetDir(const nsAString& aDir) MOZ_FINAL {                         \
-    mozilla::ErrorResult rv;                                                   \
-    nsGenericHTMLElement::SetDir(aDir, rv);                                    \
-    return rv.ErrorCode();                                                     \
-  }                                                                            \
-  NS_IMETHOD GetClassName(nsAString& aClassName) MOZ_FINAL {                   \
-    nsGenericHTMLElement::GetClassName(aClassName);                            \
-    return NS_OK;                                                              \
-  }                                                                            \
-  NS_IMETHOD SetClassName(const nsAString& aClassName) MOZ_FINAL {             \
-    nsGenericHTMLElement::SetClassName(aClassName);                            \
-    return NS_OK;                                                              \
-  }                                                                            \
-  NS_IMETHOD GetDataset(nsISupports** aDataset) MOZ_FINAL {                    \
-    return nsGenericHTMLElement::GetDataset(aDataset);                         \
-  }                                                                            \
-  NS_IMETHOD GetHidden(bool* aHidden) MOZ_FINAL {                              \
-    *aHidden = nsGenericHTMLElement::Hidden();                                 \
-    return NS_OK;                                                              \
-  }                                                                            \
-  NS_IMETHOD SetHidden(bool aHidden) MOZ_FINAL {                               \
-    mozilla::ErrorResult rv;                                                   \
-    nsGenericHTMLElement::SetHidden(aHidden, rv);                              \
-    return rv.ErrorCode();                                                     \
-  }                                                                            \
-  NS_IMETHOD DOMBlur() MOZ_FINAL {                                             \
-    mozilla::ErrorResult rv;                                                   \
-    nsGenericHTMLElement::Blur(rv);                                            \
-    return rv.ErrorCode();                                                     \
-  }                                                                            \
-  NS_IMETHOD GetItemScope(bool* aItemScope) MOZ_FINAL {                        \
-    *aItemScope = nsGenericHTMLElement::ItemScope();                           \
-    return NS_OK;                                                              \
-  }                                                                            \
-  NS_IMETHOD SetItemScope(bool aItemScope) MOZ_FINAL {                         \
-    mozilla::ErrorResult rv;                                                   \
-    nsGenericHTMLElement::SetItemScope(aItemScope, rv);                        \
-    return rv.ErrorCode();                                                     \
-  }                                                                            \
-  NS_IMETHOD GetItemType(nsIVariant** aType) MOZ_FINAL {                       \
-    GetTokenList(nsGkAtoms::itemtype, aType);                                  \
-    return NS_OK;                                                              \
-  }                                                                            \
-  NS_IMETHOD SetItemType(nsIVariant* aType) MOZ_FINAL {                        \
-    return nsGenericHTMLElement::SetTokenList(nsGkAtoms::itemtype, aType);     \
-  }                                                                            \
-  NS_IMETHOD GetItemId(nsAString& aId) MOZ_FINAL {                             \
-    nsGenericHTMLElement::GetItemId(aId);                                      \
-    return NS_OK;                                                              \
-  }                                                                            \
-  NS_IMETHOD SetItemId(const nsAString& aId) MOZ_FINAL {                       \
-    mozilla::ErrorResult rv;                                                   \
-    nsGenericHTMLElement::SetItemId(aId, rv);                                  \
-    return rv.ErrorCode();                                                     \
-  }                                                                            \
-  NS_IMETHOD GetProperties(nsISupports** aReturn)                              \
-      MOZ_FINAL {                                                              \
-    nsGenericHTMLElement::GetProperties(aReturn);                              \
-    return NS_OK;                                                              \
-  }                                                                            \
-  NS_IMETHOD GetItemValue(nsIVariant** aValue) MOZ_FINAL {                     \
-    return nsGenericHTMLElement::GetItemValue(aValue);                         \
-  }                                                                            \
-  NS_IMETHOD SetItemValue(nsIVariant* aValue) MOZ_FINAL {                      \
-    return nsGenericHTMLElement::SetItemValue(aValue);                         \
-  }                                                                            \
-  NS_IMETHOD GetItemRef(nsIVariant** aRef) MOZ_FINAL {                         \
-    GetTokenList(nsGkAtoms::itemref, aRef);                                    \
-    return NS_OK;                                                              \
-  }                                                                            \
-  NS_IMETHOD SetItemRef(nsIVariant* aRef) MOZ_FINAL {                          \
-    return nsGenericHTMLElement::SetTokenList(nsGkAtoms::itemref, aRef);       \
-  }                                                                            \
-  NS_IMETHOD GetItemProp(nsIVariant** aProp) MOZ_FINAL {                       \
-    GetTokenList(nsGkAtoms::itemprop, aProp);                                  \
-    return NS_OK;                                                              \
-  }                                                                            \
-  NS_IMETHOD SetItemProp(nsIVariant* aProp) MOZ_FINAL {                        \
-    return nsGenericHTMLElement::SetTokenList(nsGkAtoms::itemprop, aProp);     \
-  }                                                                            \
-  NS_IMETHOD GetAccessKey(nsAString& aAccessKey) MOZ_FINAL {                   \
-    nsGenericHTMLElement::GetAccessKey(aAccessKey);                            \
-    return NS_OK;                                                              \
-  }                                                                            \
-  NS_IMETHOD SetAccessKey(const nsAString& aAccessKey) MOZ_FINAL {             \
-    mozilla::ErrorResult rv;                                                   \
-    nsGenericHTMLElement::SetAccessKey(aAccessKey, rv);                        \
-    return rv.ErrorCode();                                                     \
-  }                                                                            \
-  NS_IMETHOD GetAccessKeyLabel(nsAString& aAccessKeyLabel) MOZ_FINAL {         \
-    nsGenericHTMLElement::GetAccessKeyLabel(aAccessKeyLabel);                  \
-    return NS_OK;                                                              \
-  }                                                                            \
-  NS_IMETHOD SetDraggable(bool aDraggable) MOZ_FINAL {                         \
-    mozilla::ErrorResult rv;                                                   \
-    nsGenericHTMLElement::SetDraggable(aDraggable, rv);                        \
-    return rv.ErrorCode();                                                     \
-  }                                                                            \
-  NS_IMETHOD GetContentEditable(nsAString& aContentEditable) MOZ_FINAL {       \
-    nsGenericHTMLElement::GetContentEditable(aContentEditable);                \
-    return NS_OK;                                                              \
-  }                                                                            \
-  NS_IMETHOD SetContentEditable(const nsAString& aContentEditable) MOZ_FINAL { \
-    mozilla::ErrorResult rv;                                                   \
-    nsGenericHTMLElement::SetContentEditable(aContentEditable, rv);            \
-    return rv.ErrorCode();                                                     \
-  }                                                                            \
-  NS_IMETHOD GetIsContentEditable(bool* aIsContentEditable) MOZ_FINAL {        \
-    *aIsContentEditable = nsGenericHTMLElement::IsContentEditable();           \
-    return NS_OK;                                                              \
-  }                                                                            \
-  NS_IMETHOD GetContextMenu(nsIDOMHTMLMenuElement** aContextMenu) MOZ_FINAL {  \
-    nsGenericHTMLElement::GetContextMenu(aContextMenu);                        \
-    return NS_OK;                                                              \
-  }                                                                            \
-  NS_IMETHOD GetSpellcheck(bool* aSpellcheck) MOZ_FINAL {                      \
-    *aSpellcheck = nsGenericHTMLElement::Spellcheck();                         \
-    return NS_OK;                                                              \
-  }                                                                            \
-  NS_IMETHOD SetSpellcheck(bool aSpellcheck) MOZ_FINAL {                       \
-    mozilla::ErrorResult rv;                                                   \
-    nsGenericHTMLElement::SetSpellcheck(aSpellcheck, rv);                      \
-    return rv.ErrorCode();                                                     \
-  }                                                                            \
-  NS_IMETHOD GetOuterHTML(nsAString& aOuterHTML) MOZ_FINAL {                   \
-    mozilla::ErrorResult rv;                                                   \
-    nsGenericHTMLElement::GetOuterHTML(aOuterHTML, rv);                        \
-    return rv.ErrorCode();                                                     \
-  }                                                                            \
-  NS_IMETHOD SetOuterHTML(const nsAString& aOuterHTML) MOZ_FINAL {             \
-    mozilla::ErrorResult rv;                                                   \
-    nsGenericHTMLElement::SetOuterHTML(aOuterHTML, rv);                        \
-    return rv.ErrorCode();                                                     \
-  }                                                                            \
-  NS_IMETHOD InsertAdjacentHTML(const nsAString& position,                     \
-                                const nsAString& text) MOZ_FINAL {             \
-    return nsGenericHTMLElement::InsertAdjacentHTML(position, text);           \
-  }                                                                            \
-  NS_IMETHOD ScrollIntoView(bool top, uint8_t _argc) MOZ_FINAL {               \
-    if (!_argc) {                                                              \
-      top = true;                                                              \
-    }                                                                          \
-    mozilla::dom::Element::ScrollIntoView(top);                                \
-    return NS_OK;                                                              \
-  }                                                                            \
-  NS_IMETHOD GetOffsetParent(nsIDOMElement** aOffsetParent) MOZ_FINAL {        \
-    mozilla::dom::Element* offsetParent =                                      \
-      nsGenericHTMLElement::GetOffsetParent();                                 \
-    if (!offsetParent) {                                                       \
-      *aOffsetParent = nullptr;                                                \
-      return NS_OK;                                                            \
-    }                                                                          \
-    return CallQueryInterface(offsetParent, aOffsetParent);                    \
-  }                                                                            \
-  NS_IMETHOD GetOffsetTop(int32_t* aOffsetTop) MOZ_FINAL {                     \
-    *aOffsetTop = nsGenericHTMLElement::OffsetTop();                           \
-    return NS_OK;                                                              \
-  }                                                                            \
-  NS_IMETHOD GetOffsetLeft(int32_t* aOffsetLeft) MOZ_FINAL {                   \
-    *aOffsetLeft = nsGenericHTMLElement::OffsetLeft();                         \
-    return NS_OK;                                                              \
-  }                                                                            \
-  NS_IMETHOD GetOffsetWidth(int32_t* aOffsetWidth) MOZ_FINAL {                 \
-    *aOffsetWidth = nsGenericHTMLElement::OffsetWidth();                       \
-    return NS_OK;                                                              \
-  }                                                                            \
-  NS_IMETHOD GetOffsetHeight(int32_t* aOffsetHeight) MOZ_FINAL {               \
-    *aOffsetHeight = nsGenericHTMLElement::OffsetHeight();                     \
-    return NS_OK;                                                              \
-  }                                                                            \
-  NS_IMETHOD DOMClick() MOZ_FINAL {                                            \
-    Click();                                                                   \
-    return NS_OK;                                                              \
-  }                                                                            \
-  NS_IMETHOD GetTabIndex(int32_t* aTabIndex) MOZ_FINAL {                       \
-    *aTabIndex = TabIndex();                                                   \
-    return NS_OK;                                                              \
-  }                                                                            \
-  using nsGenericHTMLElement::SetTabIndex;                                     \
-  NS_IMETHOD SetTabIndex(int32_t aTabIndex) MOZ_FINAL {                        \
-    mozilla::ErrorResult rv;                                                   \
-    nsGenericHTMLElement::SetTabIndex(aTabIndex, rv);                          \
-    return rv.ErrorCode();                                                     \
-  }                                                                            \
-  using nsGenericHTMLElement::Focus;                                           \
-  NS_IMETHOD Focus() MOZ_FINAL {                                               \
-    mozilla::ErrorResult rv;                                                   \
-    Focus(rv);                                                                 \
-    return rv.ErrorCode();                                                     \
-  }                                                                            \
-  NS_IMETHOD GetDraggable(bool* aDraggable) MOZ_FINAL {                        \
-    *aDraggable = Draggable();                                                 \
-    return NS_OK;                                                              \
-  }                                                                            \
-  using Element::GetInnerHTML;                                                 \
-  NS_IMETHOD GetInnerHTML(nsAString& aInnerHTML) MOZ_FINAL {                   \
-    mozilla::ErrorResult rv;                                                   \
-    GetInnerHTML(aInnerHTML, rv);                                              \
-    return rv.ErrorCode();                                                     \
-  }                                                                            \
-  using Element::SetInnerHTML;                                                 \
-  NS_IMETHOD SetInnerHTML(const nsAString& aInnerHTML) MOZ_FINAL {             \
-    mozilla::ErrorResult rv;                                                   \
-    SetInnerHTML(aInnerHTML, rv);                                              \
-    return rv.ErrorCode();                                                     \
-  }
-
 /**
  * A macro to declare the NS_NewHTMLXXXElement() functions.
  */
 #define NS_DECLARE_NS_NEW_HTML_ELEMENT(_elementName)                       \
 namespace mozilla {                                                        \
 namespace dom {                                                            \
 class HTML##_elementName##Element;                                         \
 }                                                                          \
@@ -1827,18 +1786,18 @@ NS_DECLARE_NS_NEW_HTML_ELEMENT(Time)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Title)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Track)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Unknown)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Video)
 
 inline nsISupports*
 ToSupports(nsGenericHTMLElement* aHTMLElement)
 {
-  return aHTMLElement;
+  return static_cast<nsIContent*>(aHTMLElement);
 }
 
 inline nsISupports*
 ToCanonicalSupports(nsGenericHTMLElement* aHTMLElement)
 {
-  return aHTMLElement;
+  return static_cast<nsIContent*>(aHTMLElement);
 }
 
 #endif /* nsGenericHTMLElement_h___ */
--- a/content/html/content/src/nsGenericHTMLFrameElement.cpp
+++ b/content/html/content/src/nsGenericHTMLFrameElement.cpp
@@ -21,23 +21,25 @@ using namespace mozilla::dom;
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsGenericHTMLFrameElement)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsGenericHTMLFrameElement,
                                                   nsGenericHTMLElement)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFrameLoader)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
-NS_INTERFACE_TABLE_HEAD(nsGenericHTMLFrameElement)
+NS_IMPL_ADDREF_INHERITED(nsGenericHTMLFrameElement, nsGenericHTMLElement)
+NS_IMPL_RELEASE_INHERITED(nsGenericHTMLFrameElement, nsGenericHTMLElement)
+
+NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsGenericHTMLFrameElement)
   NS_INTERFACE_TABLE_INHERITED3(nsGenericHTMLFrameElement,
                                 nsIFrameLoaderOwner,
                                 nsIDOMMozBrowserFrame,
                                 nsIMozBrowserFrame)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(nsGenericHTMLFrameElement)
-NS_INTERFACE_MAP_END_INHERITING(nsGenericHTMLElement)
+NS_INTERFACE_TABLE_TAIL_INHERITING(nsGenericHTMLElement)
 
 NS_IMPL_BOOL_ATTR(nsGenericHTMLFrameElement, Mozbrowser, mozbrowser)
 
 int32_t
 nsGenericHTMLFrameElement::TabIndexDefault()
 {
   return 0;
 }
--- a/content/html/content/src/nsGenericHTMLFrameElement.h
+++ b/content/html/content/src/nsGenericHTMLFrameElement.h
@@ -33,17 +33,18 @@ public:
     , mNetworkCreated(aFromParser == mozilla::dom::FROM_PARSER_NETWORK)
     , mBrowserFrameListenersRegistered(false)
     , mFrameLoaderCreationDisallowed(false)
   {
   }
 
   virtual ~nsGenericHTMLFrameElement();
 
-  NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) MOZ_OVERRIDE;
+  NS_DECL_ISUPPORTS_INHERITED
+
   NS_DECL_NSIFRAMELOADEROWNER
   NS_DECL_NSIDOMMOZBROWSERFRAME
   NS_DECL_NSIMOZBROWSERFRAME
 
   // nsIContent
   virtual bool IsHTMLFocusable(bool aWithMouse, bool *aIsFocusable, int32_t *aTabIndex) MOZ_OVERRIDE;
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
--- a/content/mathml/content/src/nsMathMLElement.cpp
+++ b/content/mathml/content/src/nsMathMLElement.cpp
@@ -24,29 +24,20 @@
 #include "mozilla/dom/ElementBinding.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 //----------------------------------------------------------------------
 // nsISupports methods:
 
-NS_INTERFACE_TABLE_HEAD(nsMathMLElement)
-  NS_INTERFACE_TABLE_INHERITED4(nsMathMLElement,
-                                nsIDOMNode,
-                                nsIDOMElement,
-                                nsILink,
-                                Link)
-  NS_ELEMENT_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
+NS_IMPL_ISUPPORTS_INHERITED3(nsMathMLElement, nsMathMLElementBase,
+                             nsIDOMElement, nsIDOMNode, Link)
 
-NS_IMPL_ADDREF_INHERITED(nsMathMLElement, nsMathMLElementBase)
-NS_IMPL_RELEASE_INHERITED(nsMathMLElement, nsMathMLElementBase)
-
-static nsresult 
+static nsresult
 WarnDeprecated(const PRUnichar* aDeprecatedAttribute, 
                const PRUnichar* aFavoredAttribute, nsIDocument* aDocument)
 {
   const PRUnichar *argv[] = 
     { aDeprecatedAttribute, aFavoredAttribute };
   return nsContentUtils::
           ReportToConsole(nsIScriptError::warningFlag, "MathML", aDocument,
                           nsContentUtils::eMATHML_PROPERTIES,
--- a/content/mathml/content/src/nsMathMLElement.h
+++ b/content/mathml/content/src/nsMathMLElement.h
@@ -4,29 +4,27 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsMathMLElement_h
 #define nsMathMLElement_h
 
 #include "mozilla/Attributes.h"
 #include "nsMappedAttributeElement.h"
 #include "nsIDOMElement.h"
-#include "nsILink.h"
 #include "Link.h"
 
 class nsCSSValue;
 
 typedef nsMappedAttributeElement nsMathMLElementBase;
 
 /*
  * The base class for MathML elements.
  */
 class nsMathMLElement MOZ_FINAL : public nsMathMLElementBase,
                                   public nsIDOMElement,
-                                  public nsILink,
                                   public mozilla::dom::Link
 {
 public:
   nsMathMLElement(already_AddRefed<nsINodeInfo> aNodeInfo);
 
   // Implementation of nsISupports is inherited from nsMathMLElementBase
   NS_DECL_ISUPPORTS_INHERITED
 
@@ -75,18 +73,16 @@ public:
 
   // Set during reflow as necessary. Does a style change notification,
   // aNotify must be true.
   void SetIncrementScriptLevel(bool aIncrementScriptLevel, bool aNotify);
   bool GetIncrementScriptLevel() const {
     return mIncrementScriptLevel;
   }
 
-  NS_IMETHOD LinkAdded() MOZ_OVERRIDE { return NS_OK; }
-  NS_IMETHOD LinkRemoved() MOZ_OVERRIDE { return NS_OK; }
   virtual bool IsFocusable(int32_t *aTabIndex = nullptr,
                              bool aWithMouse = false) MOZ_OVERRIDE;
   virtual bool IsLink(nsIURI** aURI) const MOZ_OVERRIDE;
   virtual void GetLinkTarget(nsAString& aTarget) MOZ_OVERRIDE;
   virtual already_AddRefed<nsIURI> GetHrefURI() const MOZ_OVERRIDE;
   nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
                    const nsAString& aValue, bool aNotify)
   {
--- a/content/media/wmf/WMFReader.cpp
+++ b/content/media/wmf/WMFReader.cpp
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "WMFReader.h"
 #include "WMFDecoder.h"
 #include "WMFUtils.h"
 #include "WMFByteStream.h"
 #include "WMFSourceReaderCallback.h"
 #include "mozilla/dom/TimeRanges.h"
+#include "mozilla/dom/HTMLMediaElement.h"
 #include "mozilla/Preferences.h"
 #include "DXVA2Manager.h"
 #include "ImageContainer.h"
 #include "Layers.h"
 #include "mozilla/layers/LayersTypes.h"
 
 #ifndef MOZ_SAMPLE_TYPE_FLOAT32
 #error We expect 32bit float audio samples on desktop for the Windows Media Foundation media backend.
@@ -111,20 +112,18 @@ WMFReader::InitializeDXVA()
   // CPU memory grinds painting to a halt, and makes playback performance
   // *worse*.
   MediaDecoderOwner* owner = mDecoder->GetOwner();
   NS_ENSURE_TRUE(owner, false);
 
   HTMLMediaElement* element = owner->GetMediaElement();
   NS_ENSURE_TRUE(element, false);
 
-  nsIDocument* doc = element->GetOwnerDocument();
-  NS_ENSURE_TRUE(doc, false);
-
-  nsRefPtr<LayerManager> layerManager = nsContentUtils::LayerManagerForDocument(doc);
+  nsRefPtr<LayerManager> layerManager =
+    nsContentUtils::LayerManagerForDocument(element->OwnerDoc());
   NS_ENSURE_TRUE(layerManager, false);
 
   if (layerManager->GetBackendType() != LayersBackend::LAYERS_D3D9 &&
       layerManager->GetBackendType() != LayersBackend::LAYERS_D3D10) {
     return false;
   }
 
   mDXVA2Manager = DXVA2Manager::Create();
--- a/content/smil/nsSMILCSSProperty.cpp
+++ b/content/smil/nsSMILCSSProperty.cpp
@@ -240,17 +240,16 @@ nsSMILCSSProperty::IsPropertyAnimatable(
     case eCSSProperty_stroke_dasharray:
     case eCSSProperty_stroke_dashoffset:
     case eCSSProperty_stroke_linecap:
     case eCSSProperty_stroke_linejoin:
     case eCSSProperty_stroke_miterlimit:
     case eCSSProperty_stroke_opacity:
     case eCSSProperty_stroke_width:
     case eCSSProperty_text_anchor:
-    case eCSSProperty_text_blink:
     case eCSSProperty_text_decoration:
     case eCSSProperty_text_decoration_line:
     case eCSSProperty_text_rendering:
     case eCSSProperty_vector_effect:
     case eCSSProperty_width:
     case eCSSProperty_visibility:
     case eCSSProperty_word_spacing:
       return true;
--- a/content/svg/content/src/SVGAElement.cpp
+++ b/content/svg/content/src/SVGAElement.cpp
@@ -5,17 +5,16 @@
 
 #include "mozilla/dom/SVGAElement.h"
 
 #include "mozilla/Attributes.h"
 #include "mozilla/dom/SVGAElementBinding.h"
 #include "nsCOMPtr.h"
 #include "nsContentUtils.h"
 #include "nsGkAtoms.h"
-#include "nsILink.h"
 #include "nsSVGString.h"
 
 NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(A)
 
 namespace mozilla {
 namespace dom {
 
 JSObject*
@@ -29,21 +28,20 @@ nsSVGElement::StringInfo SVGAElement::sS
   { &nsGkAtoms::href, kNameSpaceID_XLink, true },
   { &nsGkAtoms::target, kNameSpaceID_None, true }
 };
 
 
 //----------------------------------------------------------------------
 // nsISupports methods
 
-NS_IMPL_ISUPPORTS_INHERITED5(SVGAElement, SVGAElementBase,
+NS_IMPL_ISUPPORTS_INHERITED4(SVGAElement, SVGAElementBase,
                              nsIDOMNode,
                              nsIDOMElement,
                              nsIDOMSVGElement,
-                             nsILink,
                              Link)
 
 
 //----------------------------------------------------------------------
 // Implementation
 
 SVGAElement::SVGAElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : SVGAElementBase(aNodeInfo)
--- a/content/svg/content/src/SVGAElement.h
+++ b/content/svg/content/src/SVGAElement.h
@@ -2,30 +2,28 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_SVGAElement_h
 #define mozilla_dom_SVGAElement_h
 
 #include "Link.h"
-#include "nsILink.h"
 #include "nsSVGString.h"
 #include "mozilla/dom/SVGGraphicsElement.h"
 
 nsresult NS_NewSVGAElement(nsIContent **aResult,
                            already_AddRefed<nsINodeInfo> aNodeInfo);
 
 namespace mozilla {
 namespace dom {
 
 typedef SVGGraphicsElement SVGAElementBase;
 
 class SVGAElement MOZ_FINAL : public SVGAElementBase,
-                              public nsILink,
                               public Link
 {
 protected:
   SVGAElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   friend nsresult (::NS_NewSVGAElement(nsIContent **aResult,
                                        already_AddRefed<nsINodeInfo> aNodeInfo));
   virtual JSObject* WrapNode(JSContext *cx,
                              JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
@@ -33,20 +31,16 @@ protected:
 public:
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsINode interface methods
   virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
   virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor) MOZ_OVERRIDE;
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
-  // nsILink
-  NS_IMETHOD LinkAdded() MOZ_OVERRIDE { return NS_OK; }
-  NS_IMETHOD LinkRemoved() MOZ_OVERRIDE { return NS_OK; }
-
   // nsIContent
   virtual nsresult BindToTree(nsIDocument *aDocument, nsIContent *aParent,
                               nsIContent *aBindingParent,
                               bool aCompileEventHandlers) MOZ_OVERRIDE;
   virtual void UnbindFromTree(bool aDeep = true,
                               bool aNullParent = true) MOZ_OVERRIDE;
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
   virtual bool IsFocusable(int32_t *aTabIndex = nullptr, bool aWithMouse = false) MOZ_OVERRIDE;
--- a/content/svg/content/src/SVGLengthListSMILType.cpp
+++ b/content/svg/content/src/SVGLengthListSMILType.cpp
@@ -88,22 +88,16 @@ SVGLengthListSMILType::Add(nsSMILValue& 
   // and *not* vice versa! It's okay in the case of adding a shorter list to a
   // longer list because during the add operation we'll end up adding the
   // zeros to actual specified values. It's *not* okay in the case of adding a
   // longer list to a shorter list because then we end up adding to implicit
   // zeros when we'd actually need to add to whatever the underlying values
   // should be, not zeros, and those values are not explicit or otherwise
   // available.
 
-  if (dest.IsEmpty() && valueToAdd.IsEmpty()) {
-    // Adding two identity values, no-op.  This occurs when performing a
-    // discrete by-animation on an attribute with no specified base value.
-    return NS_OK;
-  }
-
   if (!valueToAdd.Element()) { // Adding identity value - no-op
     NS_ABORT_IF_FALSE(valueToAdd.IsEmpty(),
                       "Identity values should be empty");
     return NS_OK;
   }
 
   if (!dest.Element()) { // Adding *to* an identity value
     NS_ABORT_IF_FALSE(dest.IsEmpty(),
new file mode 100644
--- /dev/null
+++ b/content/svg/content/src/crashtests/898915-1.svg
@@ -0,0 +1,5 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+  <text>
+    <animate attributeName="y" by="" />
+  </text>
+</svg>
--- a/content/svg/content/src/crashtests/crashtests.list
+++ b/content/svg/content/src/crashtests/crashtests.list
@@ -66,8 +66,9 @@ load 831561.html
 load 837450-1.svg
 load 842463-1.html
 load 864509.svg
 load 880544-1.svg
 load 880544-2.svg
 load 880544-3.svg
 load 880544-4.svg
 load 880544-5.svg
+load 898915-1.svg
--- a/content/svg/content/src/nsSVGElement.cpp
+++ b/content/svg/content/src/nsSVGElement.cpp
@@ -1103,33 +1103,24 @@ NS_IMETHODIMP nsSVGElement::SetId(const 
 {
   return SetAttr(kNameSpaceID_None, nsGkAtoms::id, aId, true);
 }
 
 /* readonly attribute nsIDOMSVGSVGElement ownerSVGElement; */
 NS_IMETHODIMP
 nsSVGElement::GetOwnerSVGElement(nsIDOMSVGElement * *aOwnerSVGElement)
 {
-  ErrorResult rv;
-  NS_IF_ADDREF(*aOwnerSVGElement = GetOwnerSVGElement(rv));
-  return rv.ErrorCode();
+  NS_IF_ADDREF(*aOwnerSVGElement = GetOwnerSVGElement());
+  return NS_OK;
 }
 
 SVGSVGElement*
-nsSVGElement::GetOwnerSVGElement(ErrorResult& rv)
+nsSVGElement::GetOwnerSVGElement()
 {
-  SVGSVGElement* ownerSVGElement = GetCtx();
-
-  // If we didn't find anything and we're not the outermost SVG element,
-  // we've got an invalid structure
-  if (!ownerSVGElement && Tag() != nsGkAtoms::svg) {
-    rv.Throw(NS_ERROR_FAILURE);
-  }
-
-  return ownerSVGElement;
+  return GetCtx(); // this may return nullptr
 }
 
 /* readonly attribute nsIDOMSVGElement viewportElement; */
 NS_IMETHODIMP
 nsSVGElement::GetViewportElement(nsIDOMSVGElement * *aViewportElement)
 {
   nsSVGElement* elem = GetViewportElement();
   NS_ADDREF(*aViewportElement = elem);
--- a/content/svg/content/src/nsSVGElement.h
+++ b/content/svg/content/src/nsSVGElement.h
@@ -299,17 +299,17 @@ public:
   virtual nsIAtom* GetTransformListAttrName() const {
     return nullptr;
   }
 
   virtual nsIDOMNode* AsDOMNode() MOZ_FINAL MOZ_OVERRIDE { return this; }
   virtual bool IsTransformable() { return false; }
 
   // WebIDL
-  mozilla::dom::SVGSVGElement* GetOwnerSVGElement(mozilla::ErrorResult& rv);
+  mozilla::dom::SVGSVGElement* GetOwnerSVGElement();
   nsSVGElement* GetViewportElement();
   already_AddRefed<mozilla::dom::SVGAnimatedString> ClassName();
   already_AddRefed<mozilla::dom::CSSValue> GetPresentationAttribute(const nsAString& aName, mozilla::ErrorResult& rv);
 protected:
   virtual JSObject* WrapNode(JSContext *cx,
                              JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
 
 #ifdef DEBUG
--- a/content/svg/content/test/test_viewport.html
+++ b/content/svg/content/test/test_viewport.html
@@ -27,16 +27,25 @@ function runTest()
   var inner = doc.getElementById("inner");
   var g1 = doc.getElementById("g1");
   var outer = doc.getElementById("outer");
   var g2 = doc.getElementById("g2");
   var g3 = doc.getElementById("g3");
   var sym = doc.getElementById("sym");
   var symbolRect = doc.getElementById("symbolRect");
 
+  <!-- ownerSVGElement -->
+  is(root.ownerSVGElement, null, "root.ownerSVGElement");
+  is(inner.ownerSVGElement, root, "inner.ownerSVGElement");
+  is(g1.ownerSVGElement, inner, "g1.ownerSVGElement");
+  is(outer.ownerSVGElement, null, "outer.ownerSVGElement");
+  is(g2.ownerSVGElement, outer, "g2.ownerSVGElement");
+  is(g3.ownerSVGElement, null, "g3.ownerSVGElement");
+  is(symbolRect.ownerSVGElement, root, "symbolRect.ownerSVGElement");
+
   <!-- viewportElement -->
   is(root.viewportElement, null, "root.viewportElement");
   is(inner.viewportElement, root, "inner.viewportElement");
   is(g1.viewportElement, inner, "g1.viewportElement");
   is(outer.viewportElement, null, "outer.viewportElement");
   is(g2.viewportElement, outer, "g2.viewportElement");
   is(g3.viewportElement, null, "g3.viewportElement");
   is(symbolRect.viewportElement, sym, "symbolRect.viewportElement");
--- a/content/xbl/src/nsXBLDocumentInfo.cpp
+++ b/content/xbl/src/nsXBLDocumentInfo.cpp
@@ -92,29 +92,29 @@ protected:
 
 JSBool
 nsXBLDocGlobalObject::doCheckAccess(JSContext *cx, JS::Handle<JSObject*> obj,
                                     JS::Handle<jsid> id, uint32_t accessType)
 {
   nsIScriptSecurityManager *ssm = nsContentUtils::GetSecurityManager();
   if (!ssm) {
     ::JS_ReportError(cx, "Unable to verify access to a global object property.");
-    return JS_FALSE;
+    return false;
   }
 
   // Make sure to actually operate on our object, and not some object further
   // down on the proto chain.
   JS::Rooted<JSObject*> base(cx, obj);
   while (JS_GetClass(base) != &nsXBLDocGlobalObject::gSharedGlobalClass) {
     if (!::JS_GetPrototype(cx, base, &base)) {
-      return JS_FALSE;
+      return false;
     }
     if (!base) {
       ::JS_ReportError(cx, "Invalid access to a global object property.");
-      return JS_FALSE;
+      return false;
     }
   }
 
   nsresult rv = ssm->CheckPropertyAccess(cx, base, JS_GetClass(base)->name,
                                          id, accessType);
   return NS_SUCCEEDED(rv);
 }
 
@@ -161,17 +161,17 @@ nsXBLDocGlobalObject_finalize(JSFreeOp *
 
   // The addref was part of JSObject construction
   NS_RELEASE(nativeThis);
 }
 
 static JSBool
 nsXBLDocGlobalObject_resolve(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id)
 {
-  JSBool did_resolve = JS_FALSE;
+  JSBool did_resolve = false;
   return JS_ResolveStandardClass(cx, obj, id, &did_resolve);
 }
 
 
 JSClass nsXBLDocGlobalObject::gSharedGlobalClass = {
     "nsXBLPrototypeScript compilation scope",
     JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS |
     JSCLASS_IMPLEMENTS_BARRIERS | JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(0),
--- a/content/xbl/src/nsXBLProtoImplMethod.cpp
+++ b/content/xbl/src/nsXBLProtoImplMethod.cpp
@@ -337,17 +337,17 @@ nsXBLProtoImplAnonymousMethod::Execute(n
     return NS_ERROR_OUT_OF_MEMORY;
 
   // Now call the method
 
   // Check whether it's OK to call the method.
   rv = nsContentUtils::GetSecurityManager()->CheckFunctionAccess(cx, method,
                                                                  thisObject);
 
-  JSBool ok = JS_TRUE;
+  JSBool ok = true;
   if (NS_SUCCEEDED(rv)) {
     JS::Rooted<JS::Value> retval(cx);
     ok = ::JS_CallFunctionValue(cx, thisObject, OBJECT_TO_JSVAL(method),
                                 0 /* argc */, nullptr /* argv */, retval.address());
   }
 
   if (!ok) {
     // If a constructor or destructor threw an exception, it doesn't stop
--- a/content/xml/content/src/nsXMLElement.cpp
+++ b/content/xml/content/src/nsXMLElement.cpp
@@ -12,24 +12,18 @@ using namespace mozilla::dom;
 nsresult
 NS_NewXMLElement(nsIContent** aInstancePtrResult, already_AddRefed<nsINodeInfo> aNodeInfo)
 {
   nsXMLElement* it = new nsXMLElement(aNodeInfo);
   NS_ADDREF(*aInstancePtrResult = it);
   return NS_OK;
 }
 
-// QueryInterface implementation for nsXMLElement
-NS_INTERFACE_TABLE_HEAD(nsXMLElement)
-  NS_INTERFACE_TABLE_INHERITED2(nsXMLElement, nsIDOMNode, nsIDOMElement)
-  NS_ELEMENT_INTERFACE_TABLE_TO_MAP_SEGUE
-NS_ELEMENT_INTERFACE_MAP_END
-
-NS_IMPL_ADDREF_INHERITED(nsXMLElement, Element)
-NS_IMPL_RELEASE_INHERITED(nsXMLElement, Element)
+NS_IMPL_ISUPPORTS_INHERITED2(nsXMLElement, Element,
+                             nsIDOMNode, nsIDOMElement)
 
 JSObject*
 nsXMLElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aScope)
 {
   return ElementBinding::Wrap(aCx, aScope, this);
 }
 
 NS_IMPL_ELEMENT_CLONE(nsXMLElement)
--- a/content/xul/content/src/nsXULContextMenuBuilder.cpp
+++ b/content/xul/content/src/nsXULContextMenuBuilder.cpp
@@ -72,17 +72,18 @@ NS_IMETHODIMP
 nsXULContextMenuBuilder::AddItemFor(nsIDOMHTMLMenuItemElement* aElement,
                                     bool aCanLoadIcon)
 {
   if (!mFragment) {
     return NS_ERROR_NOT_INITIALIZED;
   }
 
   nsCOMPtr<nsIContent> menuitem;
-  nsresult rv = CreateElement(nsGkAtoms::menuitem, aElement,
+  nsCOMPtr<nsIDOMHTMLElement> element = do_QueryInterface(aElement);
+  nsresult rv = CreateElement(nsGkAtoms::menuitem, element,
                               getter_AddRefs(menuitem));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAutoString type;
   aElement->GetType(type);
   if (type.EqualsLiteral("checkbox") || type.EqualsLiteral("radio")) {
     // The menu is only temporary, so we don't need to handle
     // the radio type precisely.
--- a/content/xul/content/src/nsXULElement.cpp
+++ b/content/xul/content/src/nsXULElement.cpp
@@ -341,17 +341,17 @@ NS_IMPL_RELEASE_INHERITED(nsXULElement, 
 NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsXULElement)
     NS_INTERFACE_TABLE_INHERITED3(nsXULElement, nsIDOMNode, nsIDOMElement,
                                   nsIDOMXULElement)
     NS_ELEMENT_INTERFACE_TABLE_TO_MAP_SEGUE
     NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMElementCSSInlineStyle,
                                    new nsXULElementTearoff(this))
     NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIFrameLoaderOwner,
                                    new nsXULElementTearoff(this))
-NS_ELEMENT_INTERFACE_MAP_END
+NS_INTERFACE_MAP_END_INHERITING(nsStyledElement)
 
 //----------------------------------------------------------------------
 // nsIDOMNode interface
 
 nsresult
 nsXULElement::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
 {
     *aResult = nullptr;
--- a/content/xul/content/src/nsXULPopupListener.cpp
+++ b/content/xul/content/src/nsXULPopupListener.cpp
@@ -131,16 +131,26 @@ nsXULPopupListener::HandleEvent(nsIDOMEv
     nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
     if (doc)
       targetNode = do_QueryInterface(doc->GetRootElement());
     if (!targetNode) {
       return NS_ERROR_FAILURE;
     }
   }
 
+  nsCOMPtr<nsIContent> targetContent = do_QueryInterface(target);
+  if (!targetContent) {
+    return NS_OK;
+  }
+  if (targetContent->Tag() == nsGkAtoms::browser &&
+      targetContent->IsXUL() &&
+      nsEventStateManager::IsRemoteTarget(targetContent)) {
+    return NS_OK;
+  }
+
   bool preventDefault;
   mouseEvent->GetDefaultPrevented(&preventDefault);
   if (preventDefault && targetNode && mIsContext) {
     // Someone called preventDefault on a context menu.
     // Let's make sure they are allowed to do so.
     bool eventEnabled =
       Preferences::GetBool("dom.event.contextmenu.enabled", true);
     if (!eventEnabled) {
@@ -175,17 +185,16 @@ nsXULPopupListener::HandleEvent(nsIDOMEv
     return NS_OK;
   }
 
   // prevent popups on menu and menuitems as they handle their own popups
   // This was added for bug 96920.
   // If a menu item child was clicked on that leads to a popup needing
   // to show, we know (guaranteed) that we're dealing with a menu or
   // submenu of an already-showing popup.  We don't need to do anything at all.
-  nsCOMPtr<nsIContent> targetContent = do_QueryInterface(target);
   if (!mIsContext) {
     nsIAtom *tag = targetContent ? targetContent->Tag() : nullptr;
     if (tag == nsGkAtoms::menu || tag == nsGkAtoms::menuitem)
       return NS_OK;
   }
 
   if (mIsContext) {
 #ifndef NS_CONTEXT_MENU_IS_MOUSEUP
--- a/content/xul/document/src/nsXULPrototypeDocument.cpp
+++ b/content/xul/document/src/nsXULPrototypeDocument.cpp
@@ -96,17 +96,17 @@ nsXULPDGlobalObject_finalize(JSFreeOp *f
     // The addref was part of JSObject construction
     nsContentUtils::DeferredFinalize(nativeThis);
 }
 
 
 JSBool
 nsXULPDGlobalObject_resolve(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id)
 {
-    JSBool did_resolve = JS_FALSE;
+    JSBool did_resolve = false;
 
     return JS_ResolveStandardClass(cx, obj, id, &did_resolve);
 }
 
 
 JSClass nsXULPDGlobalObject::gSharedGlobalClass = {
     "nsXULPrototypeScript compilation scope",
     JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS |
--- a/docshell/base/nsAboutRedirector.cpp
+++ b/docshell/base/nsAboutRedirector.cpp
@@ -60,16 +60,18 @@ static RedirEntry kRedirMap[] = {
       nsIAboutModule::ALLOW_SCRIPT },
     { "newaddon", "chrome://mozapps/content/extensions/newaddon.xul",
       nsIAboutModule::ALLOW_SCRIPT |
       nsIAboutModule::HIDE_FROM_ABOUTABOUT },
     { "support", "chrome://global/content/aboutSupport.xhtml",
       nsIAboutModule::ALLOW_SCRIPT },
     { "telemetry", "chrome://global/content/aboutTelemetry.xhtml",
       nsIAboutModule::ALLOW_SCRIPT },
+    { "networking", "chrome://global/content/aboutNetworking.xhtml",
+       nsIAboutModule::ALLOW_SCRIPT },
     // about:srcdoc is unresolvable by specification.  It is included here
     // because the security manager would disallow srcdoc iframes otherwise.
     { "srcdoc", "about:blank",
       nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
       nsIAboutModule::HIDE_FROM_ABOUTABOUT }
 };
 static const int kRedirTotal = NS_ARRAY_LENGTH(kRedirMap);
 
--- a/docshell/build/nsDocShellModule.cpp
+++ b/docshell/build/nsDocShellModule.cpp
@@ -178,16 +178,17 @@ const mozilla::Module::ContractIDEntry k
   { NS_ABOUT_MODULE_CONTRACTID_PREFIX "license", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
   { NS_ABOUT_MODULE_CONTRACTID_PREFIX "neterror", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
   { NS_ABOUT_MODULE_CONTRACTID_PREFIX "compartments", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
   { NS_ABOUT_MODULE_CONTRACTID_PREFIX "memory", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
   { NS_ABOUT_MODULE_CONTRACTID_PREFIX "addons", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
   { NS_ABOUT_MODULE_CONTRACTID_PREFIX "newaddon", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
   { NS_ABOUT_MODULE_CONTRACTID_PREFIX "support", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
   { NS_ABOUT_MODULE_CONTRACTID_PREFIX "telemetry", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
+  { NS_ABOUT_MODULE_CONTRACTID_PREFIX "networking", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
   { NS_ABOUT_MODULE_CONTRACTID_PREFIX "srcdoc", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
   { NS_URI_LOADER_CONTRACTID, &kNS_URI_LOADER_CID },
   { NS_DOCUMENTLOADER_SERVICE_CONTRACTID, &kNS_DOCUMENTLOADER_SERVICE_CID },
   { NS_EXTERNALHELPERAPPSERVICE_CONTRACTID, &kNS_EXTERNALHELPERAPPSERVICE_CID },
   { NS_EXTERNALPROTOCOLSERVICE_CONTRACTID, &kNS_EXTERNALHELPERAPPSERVICE_CID },
   { NS_MIMESERVICE_CONTRACTID, &kNS_EXTERNALHELPERAPPSERVICE_CID },
   { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX"default", &kNS_EXTERNALPROTOCOLHANDLER_CID },
   { NS_PREFETCHSERVICE_CONTRACTID, &kNS_PREFETCHSERVICE_CID },
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -1732,16 +1732,24 @@ bool Navigator::HasUserMediaSupport(JSCo
 {
   // Make enabling peerconnection enable getUserMedia() as well
   return Preferences::GetBool("media.navigator.enabled", false) ||
          Preferences::GetBool("media.peerconnection.enabled", false);
 }
 #endif // MOZ_MEDIA_NAVIGATOR
 
 /* static */
+bool Navigator::HasPushNotificationsSupport(JSContext* /* unused */,
+                                            JSObject* aGlobal)
+{
+  nsCOMPtr<nsPIDOMWindow> win = GetWindowFromGlobal(aGlobal);
+  return win && Preferences::GetBool("services.push.enabled", false) && CheckPermission(win, "push");
+}
+
+/* static */
 already_AddRefed<nsPIDOMWindow>
 Navigator::GetWindowFromGlobal(JSObject* aGlobal)
 {
   nsCOMPtr<nsPIDOMWindow> win =
     do_QueryInterface(nsJSUtils::GetStaticScriptGlobal(aGlobal));
   MOZ_ASSERT(!win || win->IsInnerWindow());
   return win.forget();
 }
--- a/dom/base/Navigator.h
+++ b/dom/base/Navigator.h
@@ -278,16 +278,19 @@ public:
 #ifdef MOZ_TIME_MANAGER
   static bool HasTimeSupport(JSContext* /* unused */, JSObject* aGlobal);
 #endif // MOZ_TIME_MANAGER
 #ifdef MOZ_MEDIA_NAVIGATOR
   static bool HasUserMediaSupport(JSContext* /* unused */,
                                   JSObject* /* unused */);
 #endif // MOZ_MEDIA_NAVIGATOR
 
+  static bool HasPushNotificationsSupport(JSContext* /* unused */,
+                                          JSObject* aGlobal);
+
   nsPIDOMWindow* GetParentObject() const
   {
     return GetWindow();
   }
 
   virtual JSObject* WrapObject(JSContext* cx,
                                JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
 
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -2357,20 +2357,20 @@ nsWindowSH::GlobalScopePolluterGetProper
     sSecMan->CheckPropertyAccess(cx, ::JS_GetGlobalForObject(cx, obj),
                                  "Window", id,
                                  nsIXPCSecurityManager::ACCESS_GET_PROPERTY);
 
   if (NS_FAILED(rv)) {
     // The security check failed. The security manager set a JS
     // exception for us.
 
-    return JS_FALSE;
+    return false;
   }
 
-  return JS_TRUE;
+  return true;
 }
 
 // Gets a subframe.
 static JSBool
 ChildWindowGetter(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
                   JS::MutableHandle<JS::Value> vp)
 {
   MOZ_ASSERT(JSID_IS_STRING(id));
@@ -2408,17 +2408,17 @@ GetDocument(JSObject *obj)
 // static
 JSBool
 nsWindowSH::GlobalScopePolluterNewResolve(JSContext *cx, JS::Handle<JSObject*> obj,
                                           JS::Handle<jsid> id, unsigned flags,
                                           JS::MutableHandle<JSObject*> objp)
 {
   if (!JSID_IS_STRING(id)) {
     // Nothing to do if we're resolving a non-string property.
-    return JS_TRUE;
+    return true;
   }
 
   // Crash reports from the wild seem to get here during shutdown when there's
   // no more XPConnect singleton.
   nsIXPConnect *xpc = XPConnect();
   NS_ENSURE_TRUE(xpc, true);
 
   // Grab the DOM window.
@@ -2445,26 +2445,26 @@ nsWindowSH::GlobalScopePolluterNewResolv
 
       objp.set(obj);
       return true;
     }
   }
 
   JS::Rooted<JSObject*> proto(cx);
   if (!::JS_GetPrototype(cx, obj, &proto)) {
-    return JS_FALSE;
+    return false;
   }
   JSBool hasProp;
 
   if (!proto || !::JS_HasPropertyById(cx, proto, id, &hasProp) ||
       hasProp) {
     // No prototype, or the property exists on the prototype. Do
     // nothing.
 
-    return JS_TRUE;
+    return true;
   }
 
   //
   // The rest of this function is for HTML documents only.
   //
   nsCOMPtr<nsIHTMLDocument> htmlDoc =
     do_QueryInterface(win->GetExtantDoc());
   if (!htmlDoc)
@@ -2484,63 +2484,63 @@ nsWindowSH::GlobalScopePolluterNewResolv
     result = document->ResolveName(str, &cache);
   }
 
   if (result) {
     JS::Rooted<JS::Value> v(cx);
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
     nsresult rv = WrapNative(cx, obj, result, cache, true, v.address(),
                              getter_AddRefs(holder));
-    NS_ENSURE_SUCCESS(rv, JS_FALSE);
+    NS_ENSURE_SUCCESS(rv, false);
 
     if (!JS_WrapValue(cx, v.address()) ||
         !JS_DefinePropertyById(cx, obj, id, v, JS_PropertyStub, JS_StrictPropertyStub, 0)) {
-      return JS_FALSE;
+      return false;
     }
 
     objp.set(obj);
   }
 
-  return JS_TRUE;
+  return true;
 }
 
 // static
 JSBool
 nsWindowSH::InvalidateGlobalScopePolluter(JSContext *cx,
                                           JS::Handle<JSObject*> aObj)
 {
   JS::Rooted<JSObject*> proto(cx);
   JS::Rooted<JSObject*> obj(cx, aObj);
 
   for (;;) {
     if (!::JS_GetPrototype(cx, obj, &proto)) {
-      return JS_FALSE;
+      return false;
     }
     if (!proto) {
       break;
     }
 
     if (JS_GetClass(proto) == &sGlobalScopePolluterClass) {
 
       JS::Rooted<JSObject*> proto_proto(cx);
       if (!::JS_GetPrototype(cx, proto, &proto_proto)) {
-        return JS_FALSE;
+        return false;
       }
 
       // Pull the global scope polluter out of the prototype chain so
       // that it can be freed.
       ::JS_SplicePrototype(cx, obj, proto_proto);
 
       break;
     }
 
     obj = proto;
   }
 
-  return JS_TRUE;
+  return true;
 }
 
 // static
 nsresult
 nsWindowSH::InstallGlobalScopePolluter(JSContext *cx, JS::Handle<JSObject*> obj)
 {
   JS::Rooted<JSObject*> gsp(cx, ::JS_NewObjectWithUniqueType(cx, &sGlobalScopePolluterClass, nullptr, obj));
   if (!gsp) {
@@ -3013,17 +3013,17 @@ nsDOMConstructor::Construct(nsIXPConnect
                             bool *_retval)
 {
   MOZ_ASSERT(obj);
 
   const nsGlobalNameStruct *name_struct = GetNameStruct();
   NS_ENSURE_TRUE(name_struct, NS_ERROR_FAILURE);
 
   if (!IsConstructable(name_struct)) {
-    // ignore return value, we return JS_FALSE anyway
+    // ignore return value, we return false anyway
     return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
   }
 
   return BaseStubConstructor(mWeakOwner, name_struct, cx, obj, args);
 }
 
 nsresult
 nsDOMConstructor::HasInstance(nsIXPConnectWrappedNative *wrapper,
@@ -3094,17 +3094,17 @@ nsDOMConstructor::HasInstance(nsIXPConne
     // Doesn't have DOM interfaces.
     return NS_OK;
   }
 
   const nsGlobalNameStruct *class_name_struct = GetNameStruct();
   NS_ENSURE_TRUE(class_name_struct, NS_ERROR_FAILURE);
 
   if (name_struct == class_name_struct) {
-    *bp = JS_TRUE;
+    *bp = true;
 
     return NS_OK;
   }
 
   nsScriptNameSpaceManager *nameSpaceManager =
     nsJSRuntime::GetNameSpaceManager();
   NS_ASSERTION(nameSpaceManager, "Can't get namespace manager?");
 
@@ -3130,17 +3130,17 @@ nsDOMConstructor::HasInstance(nsIXPConne
         sClassInfoData[alias_struct->mDOMClassInfoID].mProtoChainInterface;
     } else if (alias_struct->mType == nsGlobalNameStruct::eTypeExternalClassInfo) {
       class_iid = alias_struct->mData->mProtoChainInterface;
     } else {
       NS_ERROR("Expected eTypeClassConstructor or eTypeExternalClassInfo.");
       return NS_ERROR_UNEXPECTED;
     }
   } else {
-    *bp = JS_FALSE;
+    *bp = false;
 
     return NS_OK;
   }
 
   if (name_struct->mType == nsGlobalNameStruct::eTypeExternalConstructorAlias) {
     name_struct = nameSpaceManager->GetConstructorProto(name_struct);
     if (!name_struct) {
       NS_ERROR("Couldn't get constructor prototype.");
@@ -3167,17 +3167,17 @@ nsDOMConstructor::HasInstance(nsIXPConne
     return NS_ERROR_UNEXPECTED;
   }
 
   nsCOMPtr<nsIInterfaceInfo> if_info;
   uint32_t count = 0;
   const nsIID* class_interface;
   while ((class_interface = ci_data->mInterfaces[count++])) {
     if (class_iid->Equals(*class_interface)) {
-      *bp = JS_TRUE;
+      *bp = true;
 
       return NS_OK;
     }
 
     iim->GetInfoForIID(class_interface, getter_AddRefs(if_info));
     if (!if_info) {
       NS_ERROR("nsDOMConstructor::HasInstance can't get interface info.");
       return NS_ERROR_UNEXPECTED;
@@ -3844,20 +3844,20 @@ LocationSetterGuts(JSContext *cx, JSObje
 template<class Interface>
 static JSBool
 LocationSetter(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JSBool strict,
                JS::MutableHandle<JS::Value> vp)
 {
   nsresult rv = LocationSetterGuts<Interface>(cx, obj, vp.address());
   if (NS_FAILED(rv)) {
     xpc::Throw(cx, rv);
-    return JS_FALSE;
+    return false;
   }
 
-  return JS_TRUE;
+  return true;
 }
 
 static JSBool
 LocationSetterUnwrapper(JSContext *cx, JS::Handle<JSObject*> obj_, JS::Handle<jsid> id,
                         JSBool strict, JS::MutableHandle<JS::Value> vp)
 {
   JS::RootedObject obj(cx, obj_);
 
@@ -3977,18 +3977,18 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
   nsGlobalWindow *win = nsGlobalWindow::FromWrapper(wrapper);
   MOZ_ASSERT(win->IsInnerWindow());
 
   nsIScriptContext *my_context = win->GetContextInternal();
 
   // Don't resolve standard classes on XrayWrappers, only resolve them if we're
   // resolving on the real global object.
   if (!xpc::WrapperFactory::IsXrayWrapper(obj)) {
-    JSBool did_resolve = JS_FALSE;
-    JSBool ok = JS_TRUE;
+    JSBool did_resolve = false;
+    JSBool ok = true;
     JS::Rooted<JS::Value> exn(cx, JSVAL_VOID);
 
     {
       // Resolve standard classes on my_context's JSContext (or on cx,
       // if we don't have a my_context yet), in case the two contexts
       // have different origins.  We want lazy standard class
       // initialization to behave as if it were done eagerly, on each
       // window's own context (not on some other window-caller's
@@ -4012,17 +4012,17 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
         // JS_SetPendingException is important in the case that my_cx == cx.
 
         JS_ClearPendingException(my_cx);
       }
     }
 
     if (!ok) {
       JS_SetPendingException(cx, exn);
-      *_retval = JS_FALSE;
+      *_retval = false;
       return NS_OK;
     }
 
     if (did_resolve) {
       *objp = obj;
       return NS_OK;
     }
   }
@@ -4210,26 +4210,26 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
   // defined on our prototype chain. This way we can access this
   // expando w/o ever getting back into XPConnect.
   if (flags & JSRESOLVE_ASSIGNING) {
     JS::Rooted<JSObject*> realObj(cx, wrapper->GetJSObject());
 
     if (obj == realObj) {
       JS::Rooted<JSObject*> proto(cx);
       if (!js::GetObjectProto(cx, obj, &proto)) {
-          *_retval = JS_FALSE;
+          *_retval = false;
           return NS_OK;
       }
       if (proto) {
         JS::Rooted<JSObject*> pobj(cx);
         JS::Rooted<JS::Value> val(cx);
 
         if (!::JS_LookupPropertyWithFlagsById(cx, proto, id, flags,
                                               pobj.address(), &val)) {
-          *_retval = JS_FALSE;
+          *_retval = false;
 
           return NS_OK;
         }
 
         if (pobj) {
           // A property was found on the prototype chain.
           *objp = pobj;
           return NS_OK;
@@ -4245,17 +4245,17 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
       //
       // Since we always create the undeclared property here, shortcutting the
       // normal process, we go out of our way to tell the JS engine to report
       // strict warnings/errors using js::ReportIfUndeclaredVarAssignment.
       JS::Rooted<JSString*> str(cx, JSID_TO_STRING(id));
       if (!js::ReportIfUndeclaredVarAssignment(cx, str) ||
           !::JS_DefinePropertyById(cx, obj, id, JSVAL_VOID, JS_PropertyStub,
                                    JS_StrictPropertyStub, JSPROP_ENUMERATE)) {
-        *_retval = JS_FALSE;
+        *_retval = false;
 
         return NS_OK;
       }
 
       *objp = obj;
     }
   }
 
@@ -4660,45 +4660,45 @@ nsHTMLDocumentSH::GetDocumentAllNodeList
 
     // ... and store it in our reserved slot.
     JS_SetReservedSlot(obj, 0, collection);
   }
 
   if (NS_FAILED(rv)) {
     xpc::Throw(cx, NS_ERROR_FAILURE);
 
-    return JS_FALSE;
+    return false;
   }
 
   return *nodeList != nullptr;
 }
 
 JSBool
 nsHTMLDocumentSH::DocumentAllGetProperty(JSContext *cx, JS::Handle<JSObject*> obj_,
                                          JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp)
 {
   JS::Rooted<JSObject*> obj(cx, obj_);
 
   // document.all.item and .namedItem get their value in the
   // newResolve hook, so nothing to do for those properties here. And
   // we need to return early to prevent <div id="item"> from shadowing
   // document.all.item(), etc.
   if (nsDOMClassInfo::sItem_id == id || nsDOMClassInfo::sNamedItem_id == id) {
-    return JS_TRUE;
+    return true;
   }
 
   JS::Rooted<JSObject*> proto(cx);
   while (js::GetObjectJSClass(obj) != &sHTMLDocumentAllClass) {
     if (!js::GetObjectProto(cx, obj, &proto)) {
-      return JS_FALSE;
+      return false;
     }
 
     if (!proto) {
       NS_ERROR("The JS engine lies!");
-      return JS_TRUE;
+      return true;
     }
 
     obj = proto;
   }
 
   nsHTMLDocument *doc = GetDocument(obj);
   nsISupports *result;
   nsWrapperCache *cache;
@@ -4707,70 +4707,70 @@ nsHTMLDocumentSH::DocumentAllGetProperty
   if (JSID_IS_STRING(id)) {
     if (nsDOMClassInfo::sLength_id == id) {
       // Map document.all.length to the length of the collection
       // document.getElementsByTagName("*"), and make sure <div
       // id="length"> doesn't shadow document.all.length.
 
       nsRefPtr<nsContentList> nodeList;
       if (!GetDocumentAllNodeList(cx, obj, doc, getter_AddRefs(nodeList))) {
-        return JS_FALSE;
+        return false;
       }
 
       uint32_t length;
       rv = nodeList->GetLength(&length);
 
       if (NS_FAILED(rv)) {
         xpc::Throw(cx, rv);
 
-        return JS_FALSE;
+        return false;
       }
 
       vp.set(INT_TO_JSVAL(length));
 
-      return JS_TRUE;
+      return true;
     }
 
     // For all other strings, look for an element by id or name.
     nsDependentJSString str(id);
     result = doc->GetDocumentAllResult(str, &cache, &rv);
 
     if (NS_FAILED(rv)) {
       xpc::Throw(cx, rv);
-      return JS_FALSE;
+      return false;
     }
   } else if (JSID_IS_INT(id) && JSID_TO_INT(id) >= 0) {
     // Map document.all[n] (where n is a number) to the n:th item in
     // the document.all node list.
 
     nsRefPtr<nsContentList> nodeList;
     if (!GetDocumentAllNodeList(cx, obj, doc, getter_AddRefs(nodeList))) {
-      return JS_FALSE;
+      return false;
     }
 
     nsIContent *node = nodeList->Item(JSID_TO_INT(id));
 
     result = node;
     cache = node;
   } else {
     result = nullptr;
   }
 
   if (result) {
     rv = WrapNative(cx, JS::CurrentGlobalOrNull(cx), result, cache, true, vp.address());
     if (NS_FAILED(rv)) {
       xpc::Throw(cx, rv);
 
-      return JS_FALSE;
+      return false;
     }
   } else {
     vp.setUndefined();
   }
 
-  return JS_TRUE;
+  return true;
 }
 
 JSBool
 nsHTMLDocumentSH::DocumentAllNewResolve(JSContext *cx, JS::Handle<JSObject*> obj,
                                         JS::Handle<jsid> id, unsigned flags,
                                         JS::MutableHandle<JSObject*> objp)
 {
   JS::RootedValue v(cx);
@@ -4789,21 +4789,21 @@ nsHTMLDocumentSH::DocumentAllNewResolve(
     // document.all.length. Any jsval other than undefined would do
     // here, all we need is to get into the code below that defines
     // this propery on obj, the rest happens in
     // DocumentAllGetProperty().
 
     v = JSVAL_ONE;
   } else {
     if (!DocumentAllGetProperty(cx, obj, id, &v)) {
-      return JS_FALSE;
+      return false;
     }
   }
 
-  JSBool ok = JS_TRUE;
+  JSBool ok = true;
 
   if (v.get() != JSVAL_VOID) {
     ok = ::JS_DefinePropertyById(cx, obj, id, v, nullptr, nullptr, 0);
     objp.set(obj);
   }
 
   return ok;
 }
--- a/dom/base/nsDOMClassInfoID.h
+++ b/dom/base/nsDOMClassInfoID.h
@@ -52,18 +52,17 @@ DOMCI_CASTABLE_INTERFACE(nsINode, nsINod
 DOMCI_CASTABLE_NODECL_INTERFACE(mozilla::dom::Element,  mozilla::dom::Element,\
                                 1, _extra)                                    \
 /* If this is ever removed, the IID for EventTarget can go away */            \
 DOMCI_CASTABLE_NODECL_INTERFACE(mozilla::dom::EventTarget,                    \
                                 mozilla::dom::EventTarget, 2, _extra)         \
 DOMCI_CASTABLE_INTERFACE(nsDOMEvent, nsIDOMEvent, 3, _extra)                  \
 DOMCI_CASTABLE_INTERFACE(nsIDocument, nsIDocument, 4, _extra)                 \
 DOMCI_CASTABLE_INTERFACE(nsDocument, nsIDocument, 5, _extra)                  \
-DOMCI_CASTABLE_INTERFACE(nsGenericHTMLElement, nsGenericHTMLElement, 6,       \
-                         _extra)                                              \
+DOMCI_CASTABLE_INTERFACE(nsGenericHTMLElement, nsIContent, 6, _extra)         \
 DOMCI_CASTABLE_INTERFACE(nsHTMLDocument, nsIDocument, 7, _extra)              \
 DOMCI_CASTABLE_INTERFACE(nsStyledElement, nsStyledElement, 8, _extra)         \
 DOMCI_CASTABLE_INTERFACE(nsSVGElement, nsIContent, 9, _extra)                 \
 /* NOTE: When removing the casts below, remove the nsDOMEventBase class */    \
 DOMCI_CASTABLE_INTERFACE(nsDOMMouseEvent, nsDOMEventBase, 10, _extra)         \
 DOMCI_CASTABLE_INTERFACE(nsDOMUIEvent, nsDOMEventBase, 11, _extra)
 
 // Make sure all classes mentioned in DOMCI_CASTABLE_INTERFACES
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -5355,17 +5355,20 @@ nsGlobalWindow::CanMoveResizeWindows()
       uint32_t itemCount;
       if (NS_SUCCEEDED(treeOwner->GetTargetableShellCount(&itemCount)) &&
           itemCount > 1) {
         return false;
       }
     }
   }
 
-  if (mDocShell) {
+  // The preference is useful for the webapp runtime. Webapps should be able
+  // to resize or move their window.
+  if (mDocShell && !Preferences::GetBool("dom.always_allow_move_resize_window",
+                                         false)) {
     bool allow;
     nsresult rv = mDocShell->GetAllowWindowControl(&allow);
     if (NS_SUCCEEDED(rv) && !allow)
       return false;
   }
 
   if (gMouseDown && !gDragServiceDisabled) {
     nsCOMPtr<nsIDragService> ds =
@@ -6765,17 +6768,17 @@ PostMessageWriteStructuredClone(JSContex
 
   const JSStructuredCloneCallbacks* runtimeCallbacks =
     js::GetContextStructuredCloneCallbacks(cx);
 
   if (runtimeCallbacks) {
     return runtimeCallbacks->write(cx, writer, obj, nullptr);
   }
 
-  return JS_FALSE;
+  return false;
 }
 
 JSStructuredCloneCallbacks kPostMessageCallbacks = {
   PostMessageReadStructuredClone,
   PostMessageWriteStructuredClone,
   nullptr
 };
 
--- a/dom/base/nsGlobalWindowCommands.cpp
+++ b/dom/base/nsGlobalWindowCommands.cpp
@@ -20,16 +20,17 @@
 #include "nsIPresShell.h"
 #include "nsIDocShell.h"
 #include "nsISelectionController.h"
 #include "nsIWebNavigation.h"
 #include "nsIContentViewerEdit.h"
 #include "nsIContentViewer.h"
 #include "nsFocusManager.h"
 #include "nsCopySupport.h"
+#include "nsIClipboard.h"
 #include "nsGUIEvent.h"
 #include "mozilla/Attributes.h"
 
 #include "nsIClipboardDragDropHooks.h"
 #include "nsIClipboardDragDropHookList.h"
 
 using namespace mozilla;
 
@@ -360,17 +361,17 @@ nsClipboardCommand::DoCommand(const char
   NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
 
   nsIDocShell *docShell = window->GetDocShell();
   NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
 
   nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
   NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
 
-  nsCopySupport::FireClipboardEvent(NS_COPY, presShell, nullptr);
+  nsCopySupport::FireClipboardEvent(NS_COPY, nsIClipboard::kGlobalClipboard, presShell, nullptr);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsClipboardCommand::GetCommandStateParams(const char *aCommandName,
                                               nsICommandParams *aParams, nsISupports *aCommandContext)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -699,17 +699,17 @@ nsJSContext::DOMOperationCallback(JSCont
 {
   nsresult rv;
 
   // Get the native context
   nsJSContext *ctx = static_cast<nsJSContext *>(::JS_GetContextPrivate(cx));
 
   if (!ctx) {
     // Can happen; see bug 355811
-    return JS_TRUE;
+    return true;
   }
 
   // XXX Save the operation callback time so we can restore it after the GC,
   // because GCing can cause JS to run on our context, causing our
   // ScriptEvaluated to be called, and clearing our operation callback time.
   // See bug 302333.
   PRTime callbackTime = ctx->mOperationCallbackTime;
   PRTime modalStateTime = ctx->mModalStateTime;
@@ -719,51 +719,51 @@ nsJSContext::DOMOperationCallback(JSCont
   ctx->mModalStateTime = modalStateTime;
 
   PRTime now = PR_Now();
 
   if (callbackTime == 0) {
     // Initialize mOperationCallbackTime to start timing how long the
     // script has run
     ctx->mOperationCallbackTime = now;
-    return JS_TRUE;
+    return true;
   }
 
   if (ctx->mModalStateDepth) {
     // We're waiting on a modal dialog, nothing more to do here.
-    return JS_TRUE;
+    return true;
   }
 
   PRTime duration = now - callbackTime;
 
   // Check the amount of time this script has been running, or if the
   // dialog is disabled.
   JSObject* global = ::JS::CurrentGlobalOrNull(cx);
   bool isTrackingChromeCodeTime =
     global && xpc::AccessCheck::isChrome(js::GetObjectCompartment(global));
   if (duration < (isTrackingChromeCodeTime ?
                   sMaxChromeScriptRunTime : sMaxScriptRunTime)) {
-    return JS_TRUE;
+    return true;
   }
 
   if (!nsContentUtils::IsSafeToRunScript()) {
     // If it isn't safe to run script, then it isn't safe to bring up the
     // prompt (since that will cause the event loop to spin). In this case
     // (which is rare), we just stop the script... But report a warning so
     // that developers have some idea of what went wrong.
 
     JS_ReportWarning(cx, "A long running script was terminated");
-    return JS_FALSE;
+    return false;
   }
 
   // If we get here we're most likely executing an infinite loop in JS,
   // we'll tell the user about this and we'll give the user the option
   // of stopping the execution of the script.
   nsCOMPtr<nsIPrompt> prompt = GetPromptFromContext(ctx);
-  NS_ENSURE_TRUE(prompt, JS_FALSE);
+  NS_ENSURE_TRUE(prompt, false);
 
   // Check if we should offer the option to debug
   JS::RootedScript script(cx);
   unsigned lineno;
   JSBool hasFrame = ::JS_DescribeScriptedCaller(cx, script.address(), &lineno);
 
   bool debugPossible = hasFrame && js::CanCallContextDebugHandler(cx);
 #ifdef MOZ_JSDEBUGGER
@@ -839,17 +839,17 @@ nsJSContext::DOMOperationCallback(JSCont
       rv = tmp;
     }
   }
 
   //GetStringFromName can return NS_OK and still give NULL string
   if (NS_FAILED(rv) || !title || !msg || !stopButton || !waitButton ||
       (!debugButton && debugPossible) || !neverShowDlg) {
     NS_ERROR("Failed to get localized strings.");
-    return JS_TRUE;
+    return true;
   }
 
   // Append file and line number information, if available
   if (script) {
     const char *filename = ::JS_GetScriptFilename(cx, script);
     if (filename) {
       nsXPIDLString scriptLocation;
       NS_ConvertUTF8toUTF16 filenameUTF16(filename);
@@ -897,24 +897,24 @@ nsJSContext::DOMOperationCallback(JSCont
         sMaxChromeScriptRunTime = NS_UNLIMITED_SCRIPT_RUNTIME;
       } else {
         Preferences::SetInt("dom.max_script_run_time", 0);
         sMaxScriptRunTime = NS_UNLIMITED_SCRIPT_RUNTIME;
       }
     }
 
     ctx->mOperationCallbackTime = PR_Now();
-    return JS_TRUE;
+    return true;
   }
   else if ((buttonPressed == 2) && debugPossible) {
     return js_CallContextDebugHandler(cx);
   }
 
   JS_ClearPendingException(cx);
-  return JS_FALSE;
+  return false;
 }
 
 void
 nsJSContext::EnterModalState()
 {
   if (!mModalStateDepth) {
     mModalStateTime =  mOperationCallbackTime ? PR_Now() : 0;
   }
@@ -3321,17 +3321,17 @@ NS_DOMWriteStructuredClone(JSContext* cx
                            JS::Handle<JSObject*> obj,
                            void *closure)
 {
   ImageData* imageData;
   nsresult rv = UnwrapObject<ImageData>(cx, obj, imageData);
   if (NS_FAILED(rv)) {
     // Don't know what this is. Bail.
     xpc::Throw(cx, NS_ERROR_DOM_DATA_CLONE_ERR);
-    return JS_FALSE;
+    return false;
   }
 
   // Prepare the ImageData internals.
   uint32_t width = imageData->Width();
   uint32_t height = imageData->Height();
   JS::Rooted<JSObject*> dataArray(cx, imageData->GetDataObject());
 
   // Write the internals to the stream.
--- a/dom/base/nsJSUtils.cpp
+++ b/dom/base/nsJSUtils.cpp
@@ -33,23 +33,23 @@
 JSBool
 nsJSUtils::GetCallingLocation(JSContext* aContext, const char* *aFilename,
                               uint32_t* aLineno)
 {
   JSScript* script = nullptr;
   unsigned lineno = 0;
 
   if (!JS_DescribeScriptedCaller(aContext, &script, &lineno)) {
-    return JS_FALSE;
+    return false;
   }
 
   *aFilename = ::JS_GetScriptFilename(aContext, script);
   *aLineno = lineno;
 
-  return JS_TRUE;
+  return true;
 }
 
 nsIScriptGlobalObject *
 nsJSUtils::GetStaticScriptGlobal(JSObject* aObj)
 {
   JSClass* clazz;
   JSObject* glob = aObj; // starting point for search
 
--- a/dom/base/nsJSUtils.h
+++ b/dom/base/nsJSUtils.h
@@ -99,22 +99,22 @@ public:
   {
   }
 
   JSBool init(JSContext* aContext, JSString* str)
   {
       size_t length;
       const jschar* chars = JS_GetStringCharsZAndLength(aContext, str, &length);
       if (!chars)
-          return JS_FALSE;
+          return false;
 
       NS_ASSERTION(IsEmpty(), "init() on initialized string");
       nsDependentString* base = this;
       new(base) nsDependentString(chars, length);
-      return JS_TRUE;
+      return true;
   }
 
   JSBool init(JSContext* aContext, const JS::Value &v)
   {
       return init(aContext, JSVAL_TO_STRING(v));
   }
 
   void init(JSFlatString* fstr)
--- a/dom/bluetooth/BluetoothHfpManager.cpp
+++ b/dom/bluetooth/BluetoothHfpManager.cpp
@@ -544,17 +544,17 @@ BluetoothHfpManager::HandleVolumeChanged
   JS::Rooted<JSObject*> obj(cx, &val.toObject());
   JS::Rooted<JS::Value> key(cx);
   if (!JS_GetProperty(cx, obj, "key", &key) || !key.isString()) {
     return;
   }
 
   JSBool match;
   if (!JS_StringEqualsAscii(cx, key.toString(), AUDIO_VOLUME_BT_SCO_ID, &match) ||
-      (match != JS_TRUE)) {
+      !match) {
     return;
   }
 
   JS::Rooted<JS::Value> value(cx);
   if (!JS_GetProperty(cx, obj, "value", &value)||
       !value.isNumber()) {
     return;
   }
--- a/dom/imptests/editing/implementation.js
+++ b/dom/imptests/editing/implementation.js
@@ -1966,18 +1966,17 @@ function isSimpleModifiableElement(node)
 	// "text-decoration", which is set to "line-through" or "underline" or
 	// "overline" or "none"."
 	//
 	// The weird extra node.style.length check is for Firefox, which as of
 	// 8.0a2 has annoying and weird behavior here.
 	if (["A", "FONT", "S", "SPAN", "STRIKE", "U"].indexOf(node.tagName) != -1
 	&& node.hasAttribute("style")
 	&& (node.style.length == 1
-	|| (node.style.length == 4
-		&& "MozTextBlink" in node.style
+	|| (node.style.length == 3
 		&& "MozTextDecorationColor" in node.style
 		&& "MozTextDecorationLine" in node.style
 		&& "MozTextDecorationStyle" in node.style)
 	)
 	&& (node.style.textDecoration == "line-through"
 	|| node.style.textDecoration == "underline"
 	|| node.style.textDecoration == "overline"
 	|| node.style.textDecoration == "none")) {
--- a/dom/indexedDB/KeyPath.cpp
+++ b/dom/indexedDB/KeyPath.cpp
@@ -44,17 +44,17 @@ IsValidKeyPathString(JSContext* aCx, con
     jsval stringVal;
     if (!xpc::StringToJsval(aCx, token, &stringVal)) {
       return false;
     }
 
     NS_ASSERTION(JSVAL_IS_STRING(stringVal), "This should never happen");
     JSString* str = JSVAL_TO_STRING(stringVal);
 
-    JSBool isIdentifier = JS_FALSE;
+    JSBool isIdentifier = false;
     if (!JS_IsIdentifier(aCx, str, &isIdentifier) || !isIdentifier) {
       return false;
     }
   }
 
   // If the very last character was a '.', the tokenizer won't give us an empty
   // token, but the keyPath is still invalid.
   if (!aKeyPath.IsEmpty() &&
--- a/dom/interfaces/html/nsIDOMHTMLAnchorElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLAnchorElement.idl
@@ -11,18 +11,18 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(76ec122a-db6d-4b3f-8a24-15faf117f695)]
-interface nsIDOMHTMLAnchorElement : nsIDOMHTMLElement
+[scriptable, uuid(339c01c8-2d41-4626-b231-eec63f0241b6)]
+interface nsIDOMHTMLAnchorElement : nsISupports
 {
            attribute DOMString        href;
            attribute DOMString        target;
 
            attribute DOMString        ping;
            attribute DOMString        download;
 
            attribute DOMString        rel;
--- a/dom/interfaces/html/nsIDOMHTMLAppletElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLAppletElement.idl
@@ -11,18 +11,18 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(6f52375a-c9da-47fc-abf8-d009d1515426)]
-interface nsIDOMHTMLAppletElement : nsIDOMHTMLElement
+[scriptable, uuid(0b7d12c9-4cd3-47db-99c6-0b5ff910446c)]
+interface nsIDOMHTMLAppletElement : nsISupports
 {
            attribute DOMString        align;
            attribute DOMString        alt;
            attribute DOMString        archive;
            attribute DOMString        code;
            attribute DOMString        codeBase;
            attribute DOMString        height;
   // Modified in DOM Level 2:
--- a/dom/interfaces/html/nsIDOMHTMLAreaElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLAreaElement.idl
@@ -11,18 +11,18 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(d2379fff-180b-4c8d-be2d-70c9048fa5a1)]
-interface nsIDOMHTMLAreaElement : nsIDOMHTMLElement
+[scriptable, uuid(40c78026-36dc-40ca-9221-de73267e9e99)]
+interface nsIDOMHTMLAreaElement : nsISupports
 {
            attribute DOMString        alt;
            attribute DOMString        coords;
            attribute DOMString        shape;
            attribute DOMString        href;
            attribute DOMString        target;
 
            attribute DOMString        ping;
--- a/dom/interfaces/html/nsIDOMHTMLAudioElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLAudioElement.idl
@@ -11,12 +11,12 @@
  * <audio> element.
  *
  * For more information on this interface, please see
  * http://www.whatwg.org/specs/web-apps/current-work/#audio
  *
  * @status UNDER_DEVELOPMENT
  */
 
-[scriptable, uuid(fdfda110-e96b-4e98-8716-167a6555c80a)]
+[scriptable, uuid(75a7f3ca-0761-4b63-863b-6fd6a87ed51c)]
 interface nsIDOMHTMLAudioElement : nsIDOMHTMLMediaElement
 {
 };
--- a/dom/interfaces/html/nsIDOMHTMLBRElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLBRElement.idl
@@ -11,13 +11,13 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(e619cdc1-b869-4ebf-a77c-754c68017240)]
-interface nsIDOMHTMLBRElement : nsIDOMHTMLElement
+[scriptable, uuid(ba8fb51a-e552-4272-b3df-5e63a60b86ee)]
+interface nsIDOMHTMLBRElement : nsISupports
 {
            attribute DOMString        clear;
 };
--- a/dom/interfaces/html/nsIDOMHTMLBaseElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLBaseElement.idl
@@ -11,14 +11,14 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(56d283c1-1715-4844-b58c-c4ab72072872)]
-interface nsIDOMHTMLBaseElement : nsIDOMHTMLElement
+[scriptable, uuid(a348ac22-7880-4613-af4c-984ec2ef5adc)]
+interface nsIDOMHTMLBaseElement : nsISupports
 {
            attribute DOMString        href;
            attribute DOMString        target;
 };
--- a/dom/interfaces/html/nsIDOMHTMLBodyElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLBodyElement.idl
@@ -15,18 +15,18 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(8b29a62f-b448-49f3-9242-241d5cf94ea9)]
-interface nsIDOMHTMLBodyElement : nsIDOMHTMLElement
+[scriptable, uuid(cc19f3c8-82fe-4337-8174-d4cde5bedcee)]
+interface nsIDOMHTMLBodyElement : nsISupports
 {
            attribute DOMString        aLink;
            attribute DOMString        background;
            attribute DOMString        bgColor;
            attribute DOMString        link;
            attribute DOMString        text;
            attribute DOMString        vLink;
 
--- a/dom/interfaces/html/nsIDOMHTMLButtonElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLButtonElement.idl
@@ -13,18 +13,18 @@
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
 interface nsIDOMValidityState;
 
-[scriptable, uuid(5564816e-2ab5-46ee-95a4-8f4688bdb449)]
-interface nsIDOMHTMLButtonElement : nsIDOMHTMLElement
+[scriptable, uuid(44b7a468-7dba-4f0c-9b4e-ee46dc0f26c7)]
+interface nsIDOMHTMLButtonElement : nsISupports
 {
            attribute boolean               autofocus;
            attribute boolean               disabled;
   readonly attribute nsIDOMHTMLFormElement form;
            attribute DOMString             formAction;
            attribute DOMString             formEnctype;
            attribute DOMString             formMethod;
            attribute boolean               formNoValidate;
--- a/dom/interfaces/html/nsIDOMHTMLCanvasElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLCanvasElement.idl
@@ -41,18 +41,18 @@ interface nsIPrintCallback : nsISupports
   void render(in nsIDOMMozCanvasPrintState ctx);
 };
 
 [scriptable, function, uuid(6e9ffb59-2067-4aef-a51c-65e65a3e0d81)]
 interface nsIFileCallback : nsISupports {
   void receive(in nsIDOMBlob file);
 };
 
-[scriptable, uuid(788f69a4-30e0-42b4-804d-b99549f9d463)]
-interface nsIDOMHTMLCanvasElement : nsIDOMHTMLElement
+[scriptable, uuid(8978d1c5-2981-4678-a1c3-b0b7bae04fbc)]
+interface nsIDOMHTMLCanvasElement : nsISupports
 {
   attribute unsigned long width;
   attribute unsigned long height;
   attribute boolean mozOpaque;
 
   // Valid calls are:
   //  toDataURL();              -- defaults to image/png
   //  toDataURL(type);          -- uses given type
--- a/dom/interfaces/html/nsIDOMHTMLDirectoryElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLDirectoryElement.idl
@@ -12,12 +12,12 @@
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
 // Exists so that | element instanceof Ci.nsIDOMHTMLDirectoryElement | works.
-[scriptable, uuid(cf50373e-e004-4cec-bc65-be9250d9e4c8)]
-interface nsIDOMHTMLDirectoryElement : nsIDOMHTMLElement
+[scriptable, uuid(8cfff7a4-8b14-4ce0-97b0-babe78da16f8)]
+interface nsIDOMHTMLDirectoryElement : nsISupports
 {
 };
--- a/dom/interfaces/html/nsIDOMHTMLDivElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLDivElement.idl
@@ -11,13 +11,13 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(f18a1930-0701-443b-9420-a937b61964d9)]
-interface nsIDOMHTMLDivElement : nsIDOMHTMLElement
+[scriptable, uuid(d1b51f44-38e0-4496-8236-b795e36df0e2)]
+interface nsIDOMHTMLDivElement : nsISupports
 {
            attribute DOMString        align;
 };
--- a/dom/interfaces/html/nsIDOMHTMLElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLElement.idl
@@ -22,16 +22,17 @@ interface nsIDOMHTMLMenuElement;
 [scriptable, uuid(e29ddc73-ac40-40fe-8bbd-14bf2d52c53a)]
 interface nsIDOMHTMLElement : nsIDOMElement
 {
   // metadata attributes
            attribute DOMString        id;
            attribute DOMString        title;
            attribute DOMString        lang;
            attribute DOMString        dir;
+  [binaryname(DOMClassName)]
            attribute DOMString        className;
   readonly attribute nsISupports      dataset;
 
            attribute boolean                        itemScope;
            attribute nsIVariant                     itemType;
            attribute DOMString                      itemId;
   readonly attribute nsISupports                    properties;
   // The following attributes are really nsDOMSettableTokenList, which has
--- a/dom/interfaces/html/nsIDOMHTMLEmbedElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLEmbedElement.idl
@@ -8,18 +8,18 @@
 /**
  * The nsIDOMHTMLEmbedElement interface is the interface to a [X]HTML
  * embed element.
  *
  * For more information on this interface, please see
  * http://www.whatwg.org/specs/web-apps/current-work/#the-embed-element
  */
 
-[scriptable, uuid(749531cf-af23-4ba7-97ae-2a0a200f833b)]
-interface nsIDOMHTMLEmbedElement : nsIDOMHTMLElement
+[scriptable, uuid(adae53da-713d-4570-81ad-dabdd6d46241)]
+interface nsIDOMHTMLEmbedElement : nsISupports
 {
            attribute DOMString        align;
            attribute DOMString        height;
            attribute DOMString        name;
            attribute DOMString        src;
            attribute DOMString        type;
            attribute DOMString        width;
 };
--- a/dom/interfaces/html/nsIDOMHTMLFieldSetElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLFieldSetElement.idl
@@ -13,18 +13,18 @@
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
 interface nsIDOMValidityState;
 
-[scriptable, uuid(eb09f2e9-f0fc-4000-ab15-e68b0ac09bbd)]
-interface nsIDOMHTMLFieldSetElement : nsIDOMHTMLElement
+[scriptable, uuid(e3d91535-9da3-4c4b-a809-f17d85a4fb9f)]
+interface nsIDOMHTMLFieldSetElement : nsISupports
 {
            attribute boolean                disabled;
   readonly attribute nsIDOMHTMLFormElement  form;
            attribute DOMString              name;
 
   readonly attribute DOMString              type;
 
   readonly attribute nsIDOMHTMLCollection   elements;
--- a/dom/interfaces/html/nsIDOMHTMLFormElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLFormElement.idl
@@ -11,18 +11,18 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(5e49bff8-fb61-41e3-b6a9-2017865a6d74)]
-interface nsIDOMHTMLFormElement : nsIDOMHTMLElement
+[scriptable, uuid(ad9b2ad0-9d29-43f6-b1a2-a1fd24627e6b)]
+interface nsIDOMHTMLFormElement : nsISupports
 {
            attribute DOMString            acceptCharset;
            attribute DOMString            action;
            attribute DOMString            autocomplete;
            attribute DOMString            enctype;
            attribute DOMString            encoding;
            attribute DOMString            method;
            attribute DOMString            name;
--- a/dom/interfaces/html/nsIDOMHTMLFrameElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLFrameElement.idl
@@ -11,18 +11,18 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(1a79af54-dbbb-4532-be48-944f3995e7e9)]
-interface nsIDOMHTMLFrameElement : nsIDOMHTMLElement
+[scriptable, uuid(60ab25b9-3246-4f50-b0d4-21e73ba88cd6)]
+interface nsIDOMHTMLFrameElement : nsISupports
 {
            attribute DOMString        frameBorder;
            attribute DOMString        longDesc;
            attribute DOMString        marginHeight;
            attribute DOMString        marginWidth;
            attribute DOMString        name;
            attribute boolean          noResize;
            attribute DOMString        scrolling;
--- a/dom/interfaces/html/nsIDOMHTMLFrameSetElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLFrameSetElement.idl
@@ -15,18 +15,18 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(2531cc4f-c918-4e6d-9021-7d89216c1ebe)]
-interface nsIDOMHTMLFrameSetElement : nsIDOMHTMLElement
+[scriptable, uuid(aea59d1c-ff6f-4b26-88dc-2f9b4be1a138)]
+interface nsIDOMHTMLFrameSetElement : nsISupports
 {
            attribute DOMString        cols;
            attribute DOMString        rows;
 
            [implicit_jscontext] attribute jsval            onafterprint;
            [implicit_jscontext] attribute jsval            onbeforeprint;
            [implicit_jscontext] attribute jsval            onbeforeunload;
            [implicit_jscontext] attribute jsval            onhashchange;
--- a/dom/interfaces/html/nsIDOMHTMLHRElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLHRElement.idl
@@ -11,17 +11,17 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(26260ff8-6a9e-4bf5-9f61-93200f37e53a)]
-interface nsIDOMHTMLHRElement : nsIDOMHTMLElement
+[scriptable, uuid(30771953-b9f4-44de-b0fe-e490949af98b)]
+interface nsIDOMHTMLHRElement : nsISupports
 {
            attribute DOMString        align;
            attribute boolean          noShade;
            attribute DOMString        size;
            attribute DOMString        width;
            attribute DOMString        color;
 };
--- a/dom/interfaces/html/nsIDOMHTMLHeadElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLHeadElement.idl
@@ -11,12 +11,12 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(889602bb-4681-4b01-8582-4fad1fbb8325)]
-interface nsIDOMHTMLHeadElement : nsIDOMHTMLElement
+[scriptable, uuid(59b80014-00f5-412d-846f-725494122d42)]
+interface nsIDOMHTMLHeadElement : nsISupports
 {
 };
--- a/dom/interfaces/html/nsIDOMHTMLHeadingElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLHeadingElement.idl
@@ -11,13 +11,13 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(e601aadf-e9e7-4605-a6f9-2cd2006723de)]
-interface nsIDOMHTMLHeadingElement : nsIDOMHTMLElement
+[scriptable, uuid(a40b92f7-9da7-4c9f-8a0c-cf5b9e28bb30)]
+interface nsIDOMHTMLHeadingElement : nsISupports
 {
            attribute DOMString        align;
 };
--- a/dom/interfaces/html/nsIDOMHTMLHtmlElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLHtmlElement.idl
@@ -11,13 +11,13 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(a624104d-10e8-42f3-9f61-45b64217ba4c)]
-interface nsIDOMHTMLHtmlElement : nsIDOMHTMLElement
+[scriptable, uuid(6a5d2ce7-2c45-43c1-bdab-9df7a06caed1)]
+interface nsIDOMHTMLHtmlElement : nsISupports
 {
            attribute DOMString        version;
 };
--- a/dom/interfaces/html/nsIDOMHTMLIFrameElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLIFrameElement.idl
@@ -11,18 +11,18 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(60D9BCF1-3B0C-4704-AE8C-5B6AC0180B2E)]
-interface nsIDOMHTMLIFrameElement : nsIDOMHTMLElement
+[scriptable, uuid(9fd7b656-1055-4cb2-b8b1-ed13efe24457)]
+interface nsIDOMHTMLIFrameElement : nsISupports
 {
            attribute DOMString        align;
            attribute DOMString        frameBorder;
            attribute DOMString        height;
            attribute DOMString        longDesc;
            attribute DOMString        marginHeight;
            attribute DOMString        marginWidth;
            attribute DOMString        name;
--- a/dom/interfaces/html/nsIDOMHTMLImageElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLImageElement.idl
@@ -11,18 +11,18 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(98c38ca0-5e3a-4c71-90a4-69d12a3c8d16)]
-interface nsIDOMHTMLImageElement : nsIDOMHTMLElement
+[scriptable, uuid(d3e488b9-3b29-410a-bcf4-18fb874c170a)]
+interface nsIDOMHTMLImageElement : nsISupports
 {
            attribute DOMString        alt;
            attribute DOMString        src;
            attribute DOMString        crossOrigin;
            attribute DOMString        useMap;
            attribute boolean          isMap;
            attribute unsigned long    width;
            attribute unsigned long    height;
--- a/dom/interfaces/html/nsIDOMHTMLInputElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLInputElement.idl
@@ -15,18 +15,18 @@ interface nsIDOMValidityState;
   *
   * This interface is trying to follow the DOM Level 2 HTML specification:
   * http://www.w3.org/TR/DOM-Level-2-HTML/
   *
   * with changes from the work-in-progress WHATWG HTML specification:
   * http://www.whatwg.org/specs/web-apps/current-work/
   */
 
-[scriptable, uuid(d57537ed-39d0-46ea-8516-0ce0a5bfb805)]
-interface nsIDOMHTMLInputElement : nsIDOMHTMLElement
+[scriptable, uuid(64aeda0b-e9b5-4868-a4f9-e4776e32e733)]
+interface nsIDOMHTMLInputElement : nsISupports
 {
            attribute DOMString             accept;
            attribute DOMString             alt;
 
            attribute DOMString             autocomplete;
            attribute boolean               autofocus;
            attribute boolean               defaultChecked;
            attribute boolean               checked;
--- a/dom/interfaces/html/nsIDOMHTMLLIElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLLIElement.idl
@@ -11,14 +11,14 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(e2d41287-964c-472c-ba40-24dcdc9489c2)]
-interface nsIDOMHTMLLIElement : nsIDOMHTMLElement
+[scriptable, uuid(17bd5c1c-3746-4268-a9f6-45018025f09c)]
+interface nsIDOMHTMLLIElement : nsISupports
 {
            attribute DOMString           type;
            attribute long                value;
 };
--- a/dom/interfaces/html/nsIDOMHTMLLabelElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLLabelElement.idl
@@ -11,15 +11,15 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(cbffa708-f51e-4c74-9644-19f9d417aac5)]
-interface nsIDOMHTMLLabelElement : nsIDOMHTMLElement
+[scriptable, uuid(efc0eaf2-5756-4388-a229-fbec2033529d)]
+interface nsIDOMHTMLLabelElement : nsISupports
 {
   readonly attribute nsIDOMHTMLFormElement form;
            attribute DOMString             htmlFor;
   readonly attribute nsIDOMHTMLElement     control;
 };
--- a/dom/interfaces/html/nsIDOMHTMLLinkElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLLinkElement.idl
@@ -11,18 +11,18 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(ad43cb9b-3253-446d-8ba9-50ee50ff017e)]
-interface nsIDOMHTMLLinkElement : nsIDOMHTMLElement
+[scriptable, uuid(95d6ec66-2754-45bd-a068-49ac1fb45004)]
+interface nsIDOMHTMLLinkElement : nsISupports
 {
            [binaryname(MozDisabled)]
            attribute boolean          disabled;
            attribute DOMString        charset;
            attribute DOMString        href;
            attribute DOMString        hreflang;
            attribute DOMString        media;
            attribute DOMString        rel;
--- a/dom/interfaces/html/nsIDOMHTMLMapElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLMapElement.idl
@@ -11,14 +11,14 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(828f3b64-1df7-4592-b903-757d2fc3a4ca)]
-interface nsIDOMHTMLMapElement : nsIDOMHTMLElement
+[scriptable, uuid(3f49f8c6-2e9d-4323-b30c-2404d5ff1f57)]
+interface nsIDOMHTMLMapElement : nsISupports
 {
   readonly attribute nsIDOMHTMLCollection areas;
            attribute DOMString            name;
 };