Merge.
authorDavid Anderson <danderson@mozilla.com>
Wed, 01 Aug 2012 11:30:00 -0700
changeset 106615 3e6c62bf74fcd73d8b017e790866916b32112d20
parent 106613 07e292dd5d3f752361c66715542ad31332e7e0f1 (current diff)
parent 101086 bcfe6817a2139bccbf423afe588554a57d56ba7b (diff)
child 106616 21f15c00b5df06b87b1b57b3cd738f0bd86c1f8f
push id23447
push userdanderson@mozilla.com
push dateTue, 11 Sep 2012 17:34:27 +0000
treeherdermozilla-central@fdfaef738a00 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone17.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.
accessible/src/generic/DocAccessible.cpp
b2g/confvars.sh
browser/base/content/browser.js
caps/include/nsPrincipal.h
caps/src/nsNullPrincipal.cpp
caps/src/nsPrincipal.cpp
caps/src/nsSystemPrincipal.cpp
config/autoconf.mk.in
configure.in
content/base/public/FragmentOrElement.h
content/base/public/nsIContent.h
content/base/public/nsINode.h
content/base/src/FragmentOrElement.cpp
content/base/src/Makefile.in
content/base/src/nsAttrName.h
content/base/src/nsAttrValue.h
content/base/src/nsContentList.h
content/base/src/nsDOMAttributeMap.h
content/base/src/nsDOMTokenList.cpp
content/base/src/nsDOMTokenList.h
content/base/src/nsDocumentFragment.cpp
content/base/src/nsGenericElement.cpp
content/base/src/nsGenericElement.h
content/base/src/nsStyledElement.h
content/base/src/nsXMLHttpRequest.cpp
content/canvas/src/WebGLContext.h
content/canvas/src/WebGLContextGL.cpp
content/canvas/src/nsCanvasRenderingContext2D.cpp
content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
content/events/src/nsDOMSettingsEvent.cpp
content/events/src/nsDOMSettingsEvent.h
content/events/src/nsEventDispatcher.cpp
content/html/content/src/nsHTMLAudioElement.cpp
content/html/content/src/nsHTMLFormElement.cpp
content/html/content/src/nsHTMLSelectElement.cpp
content/html/content/src/nsHTMLSelectElement.h
content/media/ogg/nsOggReader.cpp
content/smil/nsISMILAttr.h
content/xul/document/src/nsXULDocument.cpp
content/xul/document/src/nsXULDocument.h
content/xul/templates/src/nsXULTemplateQueryProcessorRDF.cpp
content/xul/templates/src/nsXULTemplateQueryProcessorRDF.h
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfoClasses.h
dom/base/nsGlobalWindow.cpp
dom/base/nsIScriptGlobalObject.h
dom/base/nsJSEnvironment.cpp
dom/base/nsJSEnvironment.h
dom/bindings/Codegen.py
dom/interfaces/css/nsIDOMCSS2Properties.idl
dom/ipc/TabChild.cpp
dom/plugins/base/nsNPAPIPlugin.cpp
dom/plugins/base/nsPluginInstanceOwner.cpp
dom/plugins/base/nsPluginInstanceOwner.h
dom/plugins/base/nsPluginNativeWindowGtk2.cpp
dom/plugins/ipc/PluginInstanceChild.cpp
dom/plugins/ipc/PluginInstanceChild.h
dom/plugins/ipc/PluginInstanceParent.cpp
dom/plugins/ipc/PluginInstanceParent.h
dom/src/storage/nsDOMStorage.cpp
dom/src/storage/nsDOMStorage.h
dom/wifi/WifiWorker.js
embedding/components/commandhandler/src/nsCommandManager.cpp
embedding/components/commandhandler/src/nsCommandManager.h
extensions/spellcheck/src/mozInlineSpellWordUtil.cpp
gfx/2d/QuartzSupport.mm
gfx/gl/GLContextProviderEGL.cpp
gfx/gl/GLContextProviderGLX.cpp
gfx/layers/ImageLayers.h
gfx/layers/Layers.cpp
gfx/layers/Layers.h
gfx/layers/basic/BasicCanvasLayer.cpp
gfx/layers/basic/BasicLayerManager.cpp
gfx/layers/basic/BasicThebesLayer.cpp
gfx/layers/ipc/PLayers.ipdl
gfx/layers/ipc/ShadowLayerUtilsX11.cpp
gfx/layers/ipc/ShadowLayers.cpp
gfx/layers/ipc/ShadowLayers.h
gfx/layers/ipc/ShadowLayersParent.cpp
gfx/layers/opengl/CanvasLayerOGL.cpp
gfx/layers/opengl/CanvasLayerOGL.h
gfx/thebes/gfxPlatform.h
gfx/thebes/gfxPlatformMac.cpp
gfx/thebes/gfxPlatformMac.h
gfx/thebes/nsCoreAnimationSupport.h
gfx/thebes/nsCoreAnimationSupport.mm
gfx/thebes/nsIOSurface.h
js/src/frontend/BytecodeCompiler.cpp
js/src/frontend/BytecodeEmitter.cpp
js/src/frontend/ParseNode.h
js/src/frontend/Parser.cpp
js/src/frontend/Parser.h
js/src/js.msg
js/src/jsanalyze.cpp
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jscntxt.cpp
js/src/jscntxtinlines.h
js/src/jscompartment.cpp
js/src/jsfriendapi.cpp
js/src/jsfriendapi.h
js/src/jsfun.cpp
js/src/jsgc.cpp
js/src/jsgc.h
js/src/jsinfer.cpp
js/src/jsinterp.cpp
js/src/jsinterpinlines.h
js/src/jsopcode.tbl
js/src/jsscript.cpp
js/src/jsscript.h
js/src/jstypedarray.cpp
js/src/jsxml.cpp
js/src/methodjit/Compiler.cpp
js/src/methodjit/Compiler.h
js/src/methodjit/PolyIC.cpp
js/src/methodjit/PolyIC.h
js/src/shell/js.cpp
js/src/tests/shell.js
js/src/vm/GlobalObject.cpp
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/nsXPConnect.cpp
layout/base/FrameLayerBuilder.cpp
layout/base/nsDisplayList.cpp
layout/base/nsDisplayList.h
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
layout/generic/crashtests/crashtests.list
layout/generic/nsColumnSetFrame.cpp
layout/generic/nsFrame.cpp
layout/generic/nsIFrame.h
layout/generic/nsObjectFrame.cpp
layout/ipc/RenderFrameParent.cpp
layout/reftests/svg/reftest.list
layout/style/AnimationCommon.cpp
layout/style/AnimationCommon.h
layout/style/nsAnimationManager.cpp
layout/style/nsAnimationManager.h
layout/style/nsCSSParser.cpp
layout/style/nsCSSProps.cpp
layout/style/nsCSSProps.h
layout/style/nsComputedDOMStyle.cpp
layout/style/nsComputedDOMStyle.h
layout/style/nsRuleNode.cpp
layout/style/nsStyleAnimation.cpp
layout/style/nsStyleAnimation.h
layout/style/nsStyleStruct.cpp
layout/style/nsStyleStruct.h
layout/style/nsStyleTransformMatrix.cpp
layout/style/nsStyleTransformMatrix.h
layout/style/nsTransitionManager.cpp
layout/style/nsTransitionManager.h
layout/style/test/property_database.js
layout/style/test/test_transitions_per_property.html
layout/svg/base/src/nsSVGEffects.cpp
layout/svg/base/src/nsSVGIntegrationUtils.cpp
layout/svg/base/src/nsSVGPatternFrame.cpp
layout/svg/base/src/nsSVGPatternFrame.h
mobile/android/base/GeckoApp.java
mobile/android/chrome/content/browser.js
modules/libpref/src/init/all.js
netwerk/protocol/http/nsHttpHandler.cpp
security/manager/boot/src/nsSecureBrowserUIImpl.cpp
security/manager/boot/src/nsSecureBrowserUIImpl.h
uriloader/base/nsDocLoader.cpp
uriloader/prefetch/nsPrefetchService.cpp
uriloader/prefetch/nsPrefetchService.h
widget/android/AndroidBridge.cpp
widget/android/AndroidBridge.h
widget/shared/nsShmImage.h
widget/windows/nsClipboard.cpp
widget/windows/nsDataObj.cpp
widget/windows/nsImageClipboard.cpp
xpcom/ds/TimeStamp.h
xpcom/threads/nsProcess.h
xpcom/threads/nsProcessCommon.cpp
--- a/accessible/src/generic/DocAccessible.cpp
+++ b/accessible/src/generic/DocAccessible.cpp
@@ -80,17 +80,18 @@ DocAccessible::
                   nsIPresShell* aPresShell) :
   HyperTextAccessibleWrap(aRootContent, this),
   mDocument(aDocument), mScrollPositionChangedTicks(0),
   mLoadState(eTreeConstructionPending), mLoadEventType(0),
   mVirtualCursor(nullptr),
   mPresShell(aPresShell)
 {
   mFlags |= eDocAccessible;
-  mPresShell->SetAccDocument(this);
+  if (mPresShell)
+    mPresShell->SetAccDocument(this);
 
   mDependentIDsHash.Init();
   // XXX aaronl should we use an algorithm for the initial cache size?
   mAccessibleCache.Init(kDefaultCacheSize);
   mNodeToAccessibleMap.Init(kDefaultCacheSize);
 
   // If this is a XUL Document, it should not implement nsHyperText
   if (mDocument && mDocument->IsXUL())
--- a/b2g/confvars.sh
+++ b/b2g/confvars.sh
@@ -1,16 +1,18 @@
 # 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/.
 
 MOZ_APP_BASENAME=B2G
 MOZ_APP_VENDOR=Mozilla
 
 MOZ_APP_VERSION=17.0a1
+
+MOZ_UA_OS_AGNOSTIC=1
 MOZ_APP_UA_NAME=Firefox
 
 MOZ_BRANDING_DIRECTORY=b2g/branding/unofficial
 MOZ_OFFICIAL_BRANDING_DIRECTORY=b2g/branding/official
 # MOZ_APP_DISPLAYNAME is set by branding/configure.sh
 
 MOZ_SAFE_BROWSING=
 MOZ_SERVICES_SYNC=1
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -2489,174 +2489,218 @@ function BrowserOnAboutPageLoad(document
     if (!ss.canRestoreLastSession)
       document.getElementById("launcher").removeAttribute("session");
   }
 }
 
 /**
  * Handle command events bubbling up from error page content
  */
-function BrowserOnClick(event) {
-    if (!event.isTrusted || // Don't trust synthetic events
-        event.button == 2 || event.target.localName != "button")
+let BrowserOnClick = {
+  handleEvent: function BrowserOnClick_handleEvent(aEvent) {
+    if (!aEvent.isTrusted || // Don't trust synthetic events
+        aEvent.button == 2 || aEvent.target.localName != "button") {
       return;
-
-    var ot = event.originalTarget;
-    var ownerDoc = ot.ownerDocument;
+    }
+
+    let originalTarget = aEvent.originalTarget;
+    let ownerDoc = originalTarget.ownerDocument;
 
     // If the event came from an ssl error page, it is probably either the "Add
     // Exception…" or "Get me out of here!" button
     if (/^about:certerror/.test(ownerDoc.documentURI)) {
-      if (ot == ownerDoc.getElementById('exceptionDialogButton')) {
-        var params = { exceptionAdded : false, handlePrivateBrowsing : true };
+      this.onAboutCertError(originalTarget, ownerDoc);
+    }
+    else if (/^about:blocked/.test(ownerDoc.documentURI)) {
+      this.onAboutBlocked(originalTarget, ownerDoc);
+    }
+    else if (/^about:home$/i.test(ownerDoc.documentURI)) {
+      this.onAboutHome(originalTarget, ownerDoc);
+    }
+  },
+
+  onAboutCertError: function BrowserOnClick_onAboutCertError(aTargetElm, aOwnerDoc) {
+    let elmId = aTargetElm.getAttribute("id");
+
+    switch (elmId) {
+      case "exceptionDialogButton":
+        let params = { exceptionAdded : false, handlePrivateBrowsing : true };
 
         try {
-          switch (gPrefService.getIntPref("browser.ssl_override_behavior")) {
+          switch (Services.prefs.getIntPref("browser.ssl_override_behavior")) {
             case 2 : // Pre-fetch & pre-populate
               params.prefetchCert = true;
             case 1 : // Pre-populate
-              params.location = ownerDoc.location.href;
+              params.location = aOwnerDoc.location.href;
           }
         } catch (e) {
           Components.utils.reportError("Couldn't get ssl_override pref: " + e);
         }
 
         window.openDialog('chrome://pippki/content/exceptionDialog.xul',
                           '','chrome,centerscreen,modal', params);
 
         // If the user added the exception cert, attempt to reload the page
-        if (params.exceptionAdded)
-          ownerDoc.location.reload();
-      }
-      else if (ot == ownerDoc.getElementById('getMeOutOfHereButton')) {
+        if (params.exceptionAdded) {
+          aOwnerDoc.location.reload();
+        }
+        break;
+
+      case "getMeOutOfHereButton":
         getMeOutOfHere();
-      }
-    }
-    else if (/^about:blocked/.test(ownerDoc.documentURI)) {
-      // The event came from a button on a malware/phishing block page
-      // First check whether it's malware or phishing, so that we can
-      // use the right strings/links
-      var isMalware = /e=malwareBlocked/.test(ownerDoc.documentURI);
-
-      if (ot == ownerDoc.getElementById('getMeOutButton')) {
+        break;
+    }
+  },
+
+  onAboutBlocked: function BrowserOnClick_onAboutBlocked(aTargetElm, aOwnerDoc) {
+    let elmId = aTargetElm.getAttribute("id");
+
+    // The event came from a button on a malware/phishing block page
+    // First check whether it's malware or phishing, so that we can
+    // use the right strings/links
+    let isMalware = /e=malwareBlocked/.test(aOwnerDoc.documentURI);
+
+    switch (elmId) {
+      case "getMeOutButton":
         getMeOutOfHere();
-      }
-      else if (ot == ownerDoc.getElementById('reportButton')) {
+        break;
+
+      case "reportButton":
         // This is the "Why is this site blocked" button.  For malware,
         // we can fetch a site-specific report, for phishing, we redirect
         // to the generic page describing phishing protection.
 
         if (isMalware) {
           // Get the stop badware "why is this blocked" report url,
           // append the current url, and go there.
           try {
             let reportURL = formatURL("browser.safebrowsing.malware.reportURL", true);
-            reportURL += ownerDoc.location.href;
+            reportURL += aOwnerDoc.location.href;
             content.location = reportURL;
           } catch (e) {
             Components.utils.reportError("Couldn't get malware report URL: " + e);
           }
         }
         else { // It's a phishing site, not malware
           try {
             content.location = formatURL("browser.safebrowsing.warning.infoURL", true);
           } catch (e) {
             Components.utils.reportError("Couldn't get phishing info URL: " + e);
           }
         }
-      }
-      else if (ot == ownerDoc.getElementById('ignoreWarningButton')) {
-        // Allow users to override and continue through to the site,
-        // but add a notify bar as a reminder, so that they don't lose
-        // track after, e.g., tab switching.
-        gBrowser.loadURIWithFlags(content.location.href,
-                                  nsIWebNavigation.LOAD_FLAGS_BYPASS_CLASSIFIER,
-                                  null, null, null);
-
-        Services.perms.add(makeURI(content.location.href), "safe-browsing",
-                           Ci.nsIPermissionManager.ALLOW_ACTION,
-                           Ci.nsIPermissionManager.EXPIRE_SESSION);
-
-        let buttons = [{
-          label: gNavigatorBundle.getString("safebrowsing.getMeOutOfHereButton.label"),
-          accessKey: gNavigatorBundle.getString("safebrowsing.getMeOutOfHereButton.accessKey"),
-          callback: function() { getMeOutOfHere(); }
-        }];
-
-        let title;
-        if (isMalware) {
-          title = gNavigatorBundle.getString("safebrowsing.reportedAttackSite");
-          buttons[1] = {
-            label: gNavigatorBundle.getString("safebrowsing.notAnAttackButton.label"),
-            accessKey: gNavigatorBundle.getString("safebrowsing.notAnAttackButton.accessKey"),
-            callback: function() {
-              openUILinkIn(gSafeBrowsing.getReportURL('MalwareError'), 'tab');
-            }
-          };
-        } else {
-          title = gNavigatorBundle.getString("safebrowsing.reportedWebForgery");
-          buttons[1] = {
-            label: gNavigatorBundle.getString("safebrowsing.notAForgeryButton.label"),
-            accessKey: gNavigatorBundle.getString("safebrowsing.notAForgeryButton.accessKey"),
-            callback: function() {
-              openUILinkIn(gSafeBrowsing.getReportURL('Error'), 'tab');
-            }
-          };
+        break;
+
+      case "ignoreWarningButton":
+        this.ignoreWarningButton(isMalware);
+        break;
+    }
+  },
+
+  ignoreWarningButton: function BrowserOnClick_ignoreWarningButton(aIsMalware) {
+    // Allow users to override and continue through to the site,
+    // but add a notify bar as a reminder, so that they don't lose
+    // track after, e.g., tab switching.
+    gBrowser.loadURIWithFlags(content.location.href,
+                              nsIWebNavigation.LOAD_FLAGS_BYPASS_CLASSIFIER,
+                              null, null, null);
+
+    Services.perms.add(makeURI(content.location.href), "safe-browsing",
+                       Ci.nsIPermissionManager.ALLOW_ACTION,
+                       Ci.nsIPermissionManager.EXPIRE_SESSION);
+
+    let buttons = [{
+      label: gNavigatorBundle.getString("safebrowsing.getMeOutOfHereButton.label"),
+      accessKey: gNavigatorBundle.getString("safebrowsing.getMeOutOfHereButton.accessKey"),
+      callback: function() { getMeOutOfHere(); }
+    }];
+
+    let title;
+    if (aIsMalware) {
+      title = gNavigatorBundle.getString("safebrowsing.reportedAttackSite");
+      buttons[1] = {
+        label: gNavigatorBundle.getString("safebrowsing.notAnAttackButton.label"),
+        accessKey: gNavigatorBundle.getString("safebrowsing.notAnAttackButton.accessKey"),
+        callback: function() {
+          openUILinkIn(gSafeBrowsing.getReportURL('MalwareError'), 'tab');
         }
-
-        let notificationBox = gBrowser.getNotificationBox();
-        let value = "blocked-badware-page";
-
-        let previousNotification = notificationBox.getNotificationWithValue(value);
-        if (previousNotification)
-          notificationBox.removeNotification(previousNotification);
-
-        let notification = notificationBox.appendNotification(
-          title,
-          value,
-          "chrome://global/skin/icons/blacklist_favicon.png",
-          notificationBox.PRIORITY_CRITICAL_HIGH,
-          buttons
-        );
-        // Persist the notification until the user removes so it
-        // doesn't get removed on redirects.
-        notification.persistence = -1;
-      }
-    }
-    else if (/^about:home$/i.test(ownerDoc.documentURI)) {
-      if (ot == ownerDoc.getElementById("restorePreviousSession")) {
+      };
+    } else {
+      title = gNavigatorBundle.getString("safebrowsing.reportedWebForgery");
+      buttons[1] = {
+        label: gNavigatorBundle.getString("safebrowsing.notAForgeryButton.label"),
+        accessKey: gNavigatorBundle.getString("safebrowsing.notAForgeryButton.accessKey"),
+        callback: function() {
+          openUILinkIn(gSafeBrowsing.getReportURL('Error'), 'tab');
+        }
+      };
+    }
+
+    let notificationBox = gBrowser.getNotificationBox();
+    let value = "blocked-badware-page";
+
+    let previousNotification = notificationBox.getNotificationWithValue(value);
+    if (previousNotification) {
+      notificationBox.removeNotification(previousNotification);
+    }
+
+    let notification = notificationBox.appendNotification(
+      title,
+      value,
+      "chrome://global/skin/icons/blacklist_favicon.png",
+      notificationBox.PRIORITY_CRITICAL_HIGH,
+      buttons
+    );
+    // Persist the notification until the user removes so it
+    // doesn't get removed on redirects.
+    notification.persistence = -1;
+  },
+
+  onAboutHome: function BrowserOnClick_onAboutHome(aTargetElm, aOwnerDoc) {
+    let elmId = aTargetElm.getAttribute("id");
+
+    switch (elmId) {
+      case "restorePreviousSession":
         let ss = Cc["@mozilla.org/browser/sessionstore;1"].
                  getService(Ci.nsISessionStore);
-        if (ss.canRestoreLastSession)
+        if (ss.canRestoreLastSession) {
           ss.restoreLastSession();
-        ownerDoc.getElementById("launcher").removeAttribute("session");
-      }
-      else if (ot == ownerDoc.getElementById("downloads")) {
+        }
+        aOwnerDoc.getElementById("launcher").removeAttribute("session");
+        break;
+
+      case "downloads":
         BrowserDownloadsUI();
-      }
-      else if (ot == ownerDoc.getElementById("bookmarks")) {
+        break;
+
+      case "bookmarks":
         PlacesCommandHook.showPlacesOrganizer("AllBookmarks");
-      }
-      else if (ot == ownerDoc.getElementById("history")) {
+        break;
+
+      case "history":
         PlacesCommandHook.showPlacesOrganizer("History");
-      }
-      else if (ot == ownerDoc.getElementById("apps")) {
+        break;
+
+      case "apps":
         openUILinkIn("https://marketplace.mozilla.org/", "tab");
-      }
-      else if (ot == ownerDoc.getElementById("addons")) {
+        break;
+
+      case "addons":
         BrowserOpenAddonsMgr();
-      }
-      else if (ot == ownerDoc.getElementById("sync")) {
+        break;
+
+      case "sync":
         openPreferences("paneSync");
-      }
-      else if (ot == ownerDoc.getElementById("settings")) {
+        break;
+
+      case "settings":
         openPreferences();
-      }
-    }
-}
+        break;
+    }
+  },
+};
 
 /**
  * Re-direct the browser to a known-safe page.  This function is
  * used when, for example, the user browses to a known malware page
  * and is presented with about:blocked.  The "Get me out of here!"
  * button should take the user to the default start page so that even
  * when their own homepage is infected, we can get them somewhere safe.
  */
--- a/browser/base/content/test/browser_alltabslistener.js
+++ b/browser/base/content/test/browser_alltabslistener.js
@@ -126,16 +126,17 @@ function startTest1() {
 }
 
 function startTest2() {
   info("\nTest 2");
   gAllNotifications = [
     "onStateChange",
     "onLocationChange",
     "onSecurityChange",
+    "onSecurityChange",
     "onStateChange"
   ];
   gFrontNotifications = gAllNotifications;
   runTest(gForegroundBrowser, "https://example.com" + gTestPage, startTest3);
 }
 
 function startTest3() {
   info("\nTest 3");
@@ -150,16 +151,17 @@ function startTest3() {
 }
 
 function startTest4() {
   info("\nTest 4");
   gAllNotifications = [
     "onStateChange",
     "onLocationChange",
     "onSecurityChange",
+    "onSecurityChange",
     "onStateChange"
   ];
   gFrontNotifications = [];
   runTest(gBackgroundBrowser, "https://example.com" + gTestPage, startTest5);
 }
 
 function startTest5() {
   info("\nTest 5");
--- a/browser/components/preferences/advanced.js
+++ b/browser/components/preferences/advanced.js
@@ -1,16 +1,17 @@
 # -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 # 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/.
 
 // Load DownloadUtils module for convertByteUnits
 Components.utils.import("resource://gre/modules/DownloadUtils.jsm");
 Components.utils.import("resource://gre/modules/ctypes.jsm");
+Components.utils.import("resource://gre/modules/Services.jsm");
 
 var gAdvancedPane = {
   _inited: false,
 
   /**
    * Brings the appropriate tab to the front and initializes various bits of UI.
    */
   init: function ()
@@ -34,16 +35,19 @@ var gAdvancedPane = {
     this.updateReadPrefs();
 #endif
     this.updateOfflineApps();
 #ifdef MOZ_CRASHREPORTER
     this.initSubmitCrashes();
 #endif
     this.updateActualCacheSize("disk");
     this.updateActualCacheSize("offline");
+
+    // Notify observers that the UI is now ready
+    Services.obs.notifyObservers(window, "advanced-pane-loaded", null);
   },
 
   /**
    * Stores the identity of the current tab in preferences so that the selected
    * tab can be persisted between openings of the preferences window.
    */
   tabSelectionChanged: function ()
   {
@@ -691,26 +695,32 @@ var gAdvancedPane = {
    */
 
   /**
    * Show button for setting browser as default browser or information that
    * browser is already the default browser.
    */
   updateSetDefaultBrowser: function()
   {
-    var shellSvc = Components.classes["@mozilla.org/browser/shell-service;1"]
-                             .getService(Components.interfaces.nsIShellService);
+    let shellSvc = getShellService();
+    let setDefaultPane = document.getElementById("setDefaultPane");
+    if (!shellSvc) {
+      setDefaultPane.hidden = true;
+      document.getElementById("alwaysCheckDefault").disabled = true;
+      return;
+    }
     let selectedIndex = shellSvc.isDefaultBrowser(false) ? 1 : 0;
-    document.getElementById("setDefaultPane").selectedIndex = selectedIndex;
+    setDefaultPane.selectedIndex = selectedIndex;
   },
 
   /**
    * Set browser as the operating system default browser.
    */
   setDefaultBrowser: function()
   {
-    var shellSvc = Components.classes["@mozilla.org/browser/shell-service;1"]
-                             .getService(Components.interfaces.nsIShellService);
+    let shellSvc = getShellService();
+    if (!shellSvc)
+      return;
     shellSvc.setDefaultBrowser(true, false);
     document.getElementById("setDefaultPane").selectedIndex = 1;
   }
 #endif
 };
--- a/browser/components/preferences/in-content/advanced.js
+++ b/browser/components/preferences/in-content/advanced.js
@@ -670,26 +670,32 @@ var gAdvancedPane = {
    */
 
   /**
    * Show button for setting browser as default browser or information that
    * browser is already the default browser.
    */
   updateSetDefaultBrowser: function()
   {
-    var shellSvc = Components.classes["@mozilla.org/browser/shell-service;1"]
-                             .getService(Components.interfaces.nsIShellService);
+    let shellSvc = getShellService();
+    let setDefaultPane = document.getElementById("setDefaultPane");
+    if (!shellSvc) {
+      setDefaultPane.hidden = true;
+      document.getElementById("alwaysCheckDefault").disabled = true;
+      return;
+    }
     let selectedIndex = shellSvc.isDefaultBrowser(false) ? 1 : 0;
-    document.getElementById("setDefaultPane").selectedIndex = selectedIndex;
+    setDefaultPane.selectedIndex = selectedIndex;
   },
 
   /**
    * Set browser as the operating system default browser.
    */
   setDefaultBrowser: function()
   {
-    var shellSvc = Components.classes["@mozilla.org/browser/shell-service;1"]
-                             .getService(Components.interfaces.nsIShellService);
+    let shellSvc = getShellService();
+    if (!shellSvc)
+      return;
     shellSvc.setDefaultBrowser(true, false);
     document.getElementById("setDefaultPane").selectedIndex = 1;
   }
 #endif
 };
--- a/browser/components/preferences/in-content/tests/Makefile.in
+++ b/browser/components/preferences/in-content/tests/Makefile.in
@@ -8,16 +8,17 @@ srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = browser/components/preferences/in-content/tests
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _BROWSER_FILES = \
     head.js \
+    browser_advanced_update.js \
     browser_bug410900.js \
     browser_bug567487.js \
     browser_bug731866.js \
     browser_connection.js \
     privacypane_tests.js \
     browser_privacypane_1.js \
     browser_privacypane_2.js \
     browser_privacypane_3.js \
new file mode 100644
--- /dev/null
+++ b/browser/components/preferences/in-content/tests/browser_advanced_update.js
@@ -0,0 +1,40 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+function test() {
+  waitForExplicitFinish();
+  resetPreferences();
+
+  registerCleanupFunction(resetPreferences);
+  Services.prefs.setBoolPref("browser.search.update", false);
+
+  open_preferences(runTest);
+}
+
+function runTest(win) {
+  let doc = win.document;
+  let enableSearchUpdate = doc.getElementById("enableSearchUpdate");
+
+  win.gotoPref("paneAdvanced");
+
+  let advancedPrefs = doc.getElementById("advancedPrefs");
+  let updateTab = doc.getElementById("updateTab");
+  advancedPrefs.selectedTab = updateTab;
+
+  is_element_visible(enableSearchUpdate, "Check search update preference is visible");
+
+  // Ensure that the update pref dialog reflects the actual pref value.
+  ok(!enableSearchUpdate.checked, "Ensure search updates are disabled");
+  Services.prefs.setBoolPref("browser.search.update", true);
+  ok(enableSearchUpdate.checked, "Ensure search updates are enabled");
+
+  gBrowser.removeCurrentTab();
+  win.close();
+  finish();
+}
+
+function resetPreferences() {
+  Services.prefs.clearUserPref("browser.search.update");
+}
--- a/browser/components/preferences/in-content/tests/browser_bug731866.js
+++ b/browser/components/preferences/in-content/tests/browser_bug731866.js
@@ -1,21 +1,17 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 Components.utils.import("resource://gre/modules/PlacesUtils.jsm");
 Components.utils.import("resource://gre/modules/NetUtil.jsm");
 
 function test() {
   waitForExplicitFinish();
-  let newTabBrowser = gBrowser.getBrowserForTab(gBrowser.selectedTab = gBrowser.addTab("about:preferences"));
-  newTabBrowser.addEventListener("load", function () {
-    newTabBrowser.removeEventListener("load", arguments.callee, true);
-    runTest(gBrowser.contentWindow);
-  }, true);
+  open_preferences(runTest);
 }
 
 function runTest(win) {
   is(gBrowser.currentURI.spec, "about:preferences", "about:preferences loaded");
 
   let tab = win.document;
   let elements = tab.getElementById("mainPrefPane").children;
 
--- a/browser/components/preferences/in-content/tests/browser_connection.js
+++ b/browser/components/preferences/in-content/tests/browser_connection.js
@@ -58,25 +58,21 @@ function test() {
     }
   }
 
   /*
   The connection dialog alone won't save onaccept since it uses type="child",
   so it has to be opened as a sub dialog of the main pref tab.
   Open the main tab here.
   */
-  gBrowser.selectedTab = gBrowser.addTab("about:preferences");
-  let newTabBrowser = gBrowser.getBrowserForTab(gBrowser.selectedTab);
-  newTabBrowser.addEventListener("load", function tabLoadListener() {
-    newTabBrowser.removeEventListener("load", tabLoadListener, true);
+  open_preferences(function tabOpened(aContentWindow) {
     is(gBrowser.currentURI.spec, "about:preferences", "about:preferences loaded");
     windowWatcher.registerNotification(observer);
     gBrowser.contentWindow.gAdvancedPane.showConnections();
-  }, true);
-
+  });
 }
 
 // run a bunch of tests on the window containing connection.xul
 function runConnectionTests(win) {
   let doc = win.document;
   let networkProxyNone = doc.getElementById("networkProxyNone");
   let networkProxyNonePref = doc.getElementById("network.proxy.no_proxies_on");
   let networkProxyTypePref = doc.getElementById("network.proxy.type");
--- a/browser/components/preferences/in-content/tests/head.js
+++ b/browser/components/preferences/in-content/tests/head.js
@@ -18,9 +18,18 @@ function is_hidden(aElement) {
 function is_element_visible(aElement, aMsg) {
   isnot(aElement, null, "Element should not be null, when checking visibility");
   ok(!is_hidden(aElement), aMsg);
 }
 
 function is_element_hidden(aElement, aMsg) {
   isnot(aElement, null, "Element should not be null, when checking visibility");
   ok(is_hidden(aElement), aMsg);
-}
\ No newline at end of file
+}
+
+function open_preferences(aCallback) {
+  gBrowser.selectedTab = gBrowser.addTab("about:preferences");
+  let newTabBrowser = gBrowser.getBrowserForTab(gBrowser.selectedTab);
+  newTabBrowser.addEventListener("load", function () {
+    newTabBrowser.removeEventListener("load", arguments.callee, true);
+    aCallback(gBrowser.contentWindow);
+  }, true);
+}
--- a/browser/components/preferences/tests/Makefile.in
+++ b/browser/components/preferences/tests/Makefile.in
@@ -7,16 +7,17 @@ topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = browser/components/preferences/tests
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _BROWSER_FILES = \
+    browser_advanced_update.js \
     browser_bug410900.js \
     browser_bug567487.js \
     browser_bug705422.js \
     privacypane_tests.js \
     browser_privacypane_1.js \
     browser_privacypane_2.js \
     browser_privacypane_3.js \
     browser_privacypane_4.js \
new file mode 100644
--- /dev/null
+++ b/browser/components/preferences/tests/browser_advanced_update.js
@@ -0,0 +1,36 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function test() {
+  waitForExplicitFinish();
+  resetPreferences();
+
+  registerCleanupFunction(resetPreferences);
+
+  function observer(win, topic, data) {
+    Services.obs.removeObserver(observer, "advanced-pane-loaded");
+    runTest(win);
+  }
+  Services.obs.addObserver(observer, "advanced-pane-loaded", false);
+
+  Services.prefs.setBoolPref("browser.search.update", false);
+  openDialog("chrome://browser/content/preferences/preferences.xul", "Preferences",
+             "chrome,titlebar,toolbar,centerscreen,dialog=no", "paneAdvanced");
+}
+
+function runTest(win) {
+  let doc = win.document;
+  let enableSearchUpdate = doc.getElementById("enableSearchUpdate");
+
+  // Ensure that the update pref dialog reflects the actual pref value.
+  ok(!enableSearchUpdate.checked, "Ensure search updates are disabled");
+  Services.prefs.setBoolPref("browser.search.update", true);
+  ok(enableSearchUpdate.checked, "Ensure search updates are enabled");
+
+  win.close();
+  finish();
+}
+
+function resetPreferences() {
+  Services.prefs.clearUserPref("browser.search.update");
+}
--- a/browser/devtools/scratchpad/scratchpad.js
+++ b/browser/devtools/scratchpad/scratchpad.js
@@ -31,16 +31,54 @@ const SCRATCHPAD_CONTEXT_CONTENT = 1;
 const SCRATCHPAD_CONTEXT_BROWSER = 2;
 const SCRATCHPAD_L10N = "chrome://browser/locale/devtools/scratchpad.properties";
 const DEVTOOLS_CHROME_ENABLED = "devtools.chrome.enabled";
 const PREF_RECENT_FILES_MAX = "devtools.scratchpad.recentFilesMax";
 const BUTTON_POSITION_SAVE = 0;
 const BUTTON_POSITION_CANCEL = 1;
 const BUTTON_POSITION_DONT_SAVE = 2;
 
+let keysbundle = Services.strings.createBundle("chrome://global-platform/locale/platformKeys.properties");
+
+
+function SP_Pretty_Key(aElemKey) {
+
+  let elemString = "";
+  let elemMod = aElemKey.getAttribute("modifiers");
+
+  if (elemMod.match("accel")) {
+    if (navigator.platform.indexOf("Mac") !== -1) {
+      elemString += keysbundle.GetStringFromName("VK_META") +
+                    keysbundle.GetStringFromName("MODIFIER_SEPARATOR");
+    } else {
+      elemString += keysbundle.GetStringFromName("VK_CONTROL") +
+                    keysbundle.GetStringFromName("MODIFIER_SEPARATOR");
+    }
+  }
+
+  if (elemMod.match("shift")) {
+    elemString += keysbundle.GetStringFromName("VK_SHIFT") +
+                  keysbundle.GetStringFromName("MODIFIER_SEPARATOR");
+  }
+  if (elemMod.match("alt")) {
+    elemString += keysbundle.GetStringFromName("VK_ALT") +
+                  keysbundle.GetStringFromName("MODIFIER_SEPARATOR");
+  }
+  if (elemMod.match("ctrl")) {
+    elemString += keysbundle.GetStringFromName("VK_CONTROL") +
+                  keysbundle.GetStringFromName("MODIFIER_SEPARATOR");
+  }
+  if (elemMod.match("meta")) {
+    elemString += keysbundle.GetStringFromName("VK_META") +
+                  keysbundle.GetStringFromName("MODIFIER_SEPARATOR");
+  }
+
+  return elemString + aElemKey.getAttribute("key").toUpperCase();
+}
+
 /**
  * The scratchpad object handles the Scratchpad window functionality.
  */
 var Scratchpad = {
   _initialWindowTitle: document.title,
 
   /**
    * The script execution context. This tells Scratchpad in which context the
@@ -966,17 +1004,24 @@ var Scratchpad = {
       let errorConsoleCommand = document.getElementById("sp-cmd-errorConsole");
       let chromeContextCommand = document.getElementById("sp-cmd-browserContext");
       environmentMenu.removeAttribute("hidden");
       chromeContextCommand.removeAttribute("disabled");
       errorConsoleCommand.removeAttribute("disabled");
     }
 
     let state = null;
-    let initialText = this.strings.GetStringFromName("scratchpadIntro");
+
+    let initialText = this.strings.formatStringFromName(
+      "scratchpadIntro1",
+      [SP_Pretty_Key(document.getElementById("sp-key-run")),
+       SP_Pretty_Key(document.getElementById("sp-key-inspect")),
+       SP_Pretty_Key(document.getElementById("sp-key-display"))],
+      3);
+
     if ("arguments" in window &&
          window.arguments[0] instanceof Ci.nsIDialogParamBlock) {
       state = JSON.parse(window.arguments[0].GetString(0));
       this.setState(state);
       initialText = state.text;
     }
 
     this.editor = new SourceEditor();
--- a/browser/devtools/scratchpad/test/browser_scratchpad_open.js
+++ b/browser/devtools/scratchpad/test/browser_scratchpad_open.js
@@ -20,19 +20,17 @@ function test()
   testOpenWithState();
   testOpenInvalidState();
 }
 
 function testOpen()
 {
   openScratchpad(function(win) {
     is(win.Scratchpad.filename, undefined, "Default filename is undefined");
-    is(win.Scratchpad.getText(),
-       win.Scratchpad.strings.GetStringFromName("scratchpadIntro"),
-       "Default text is loaded")
+    isnot(win.Scratchpad.getText(), null, "Default text should not be null");
     is(win.Scratchpad.executionContext, win.SCRATCHPAD_CONTEXT_CONTENT,
       "Default execution context is content");
 
     win.close();
     done();
   }, {noFocus: true});
 }
 
--- a/browser/locales/en-US/chrome/browser/devtools/scratchpad.properties
+++ b/browser/locales/en-US/chrome/browser/devtools/scratchpad.properties
@@ -52,17 +52,17 @@ confirmClose=Do you want to save the cha
 
 # LOCALIZATION NOTE  (confirmClose.title): This is title of the prompt dialog when
 # you try to close a scratchpad with unsaved changes.
 confirmClose.title=Unsaved Changes
 
 # LOCALIZATION NOTE  (scratchpadIntro): This is a multi-line comment explaining
 # how to use the Scratchpad. Note that this should be a valid JavaScript
 # comment inside /* and */.
-scratchpadIntro=/*\n * This is a JavaScript Scratchpad.\n *\n * Enter some JavaScript, then Right Click or choose from the Execute Menu:\n * 1. Run to evaluate the selected text,\n * 2. Inspect to bring up an Object Inspector on the result, or,\n * 3. Display to insert the result in a comment after the selection.\n */\n\n
+scratchpadIntro1=/*\n * This is a JavaScript Scratchpad.\n *\n * Enter some JavaScript, then Right Click or choose from the Execute Menu:\n * 1. Run to evaluate the selected text (%1$S),\n * 2. Inspect to bring up an Object Inspector on the result (%2$S), or,\n * 3. Display to insert the result in a comment after the selection. (%3$S)\n */\n\n
 
 # LOCALIZATION NOTE  (notification.browserContext): This is the message displayed
 # over the top of the editor when the user has switched to browser context.
 browserContext.notification=This scratchpad executes in the Browser context.
 
 # LOCALIZATION NOTE (help.openDocumentationPage): This returns a localized link with
 # documentation for Scratchpad on MDN.
 help.openDocumentationPage=https://developer.mozilla.org/en/Tools/Scratchpad
--- a/build/mobile/sutagent/android/RunCmdThread.java
+++ b/build/mobile/sutagent/android/RunCmdThread.java
@@ -42,40 +42,28 @@ public class RunCmdThread extends Thread
 
     public void StopListening()
         {
         bListening = false;
         }
 
     public void run() {
         try {
-            int    nIterations = 0;
-
             SvrSocket.setSoTimeout(5000);
             while (bListening)
                 {
                 try
                     {
                     socket = SvrSocket.accept();
                     CmdWorkerThread theWorker = new CmdWorkerThread(this, socket);
                     theWorker.start();
                     theWorkers.add(theWorker);
                     }
                 catch (SocketTimeoutException toe)
                     {
-                    if (++nIterations > 60)
-                        {
-                        nIterations = 0;
-                        String sRet = SendPing("www.mozilla.org");
-                        if (sRet.contains("3 received"))
-                            handler.post(new doCancelNotification());
-                        else
-                            handler.post(new doSendNotification("SUTAgent - Network Connectivity Error", sRet));
-                        sRet = null;
-                        }
                     continue;
                     }
                 catch (IOException e)
                     {
                     e.printStackTrace();
                     continue;
                     }
                 }
--- a/build/mobile/sutagent/android/SUTAgentAndroid.java
+++ b/build/mobile/sutagent/android/SUTAgentAndroid.java
@@ -372,16 +372,49 @@ public class SUTAgentAndroid extends Act
             System.exit(0);
             }
         else
             {
             logToFile(dc.GetTestRoot(), dc.GetSystemTime(), "onDestroy - not finishing");
             }
         }
 
+    @Override
+    public void onLowMemory()
+        {
+        System.gc();
+        DoCommand dc = new DoCommand(getApplication());
+        if (dc != null)
+            {
+            logToFile(dc.GetTestRoot(), dc.GetSystemTime(), "onLowMemory");
+            logToFile(dc.GetTestRoot(), dc.GetSystemTime(), dc.GetMemoryInfo());
+            String procInfo = dc.GetProcessInfo();
+            if (procInfo != null)
+                {
+                String lines[] = procInfo.split("\n");
+                for (String line : lines) 
+                    {
+                    if (line.contains("mozilla"))
+                        {
+                        logToFile(dc.GetTestRoot(), dc.GetSystemTime(), line);
+                        String words[] = line.split("\t");
+                        if ((words != null) && (words.length > 1))
+                            {
+                            logToFile(dc.GetTestRoot(), dc.GetSystemTime(), dc.StatProcess(words[1]));
+                            }
+                        }
+                    }
+                }
+            }
+        else
+            {
+            Log.e("SUTAgentAndroid", "onLowMemory: unable to log to file!");
+            }
+        }
+
     private void monitorBatteryState()
         {
         battReceiver = new BroadcastReceiver()
             {
             public void onReceive(Context context, Intent intent)
                 {
                 StringBuilder sb = new StringBuilder();
 
new file mode 100755
--- /dev/null
+++ b/build/unix/build-clang/create-manifest.py
@@ -0,0 +1,55 @@
+#!/bin/python
+
+import os
+import simplejson
+import sys
+import subprocess
+import urllib
+import glob
+
+def check_run(args):
+    r = subprocess.call(args)
+    assert r == 0
+
+old_files = glob.glob('*.manifest') + ['tooltool.py', 'setup.sh']
+for f in old_files:
+    try:
+        os.unlink(f)
+    except:
+        pass
+
+urllib.urlretrieve('https://raw.github.com/jhford/tooltool/master/tooltool.py',
+                   'tooltool.py')
+urllib.urlretrieve('https://hg.mozilla.org/mozilla-central/raw-file/tip/build/unix/build-clang/setup.sh',
+                   'setup.sh')
+
+check_run(['python', 'tooltool.py', '-m', 'linux32.manifest', 'add',
+           'clang-linux32.tar.bz2', 'setup.sh'])
+check_run(['python', 'tooltool.py', '-m', 'linux64.manifest', 'add',
+           'clang-linux64.tar.bz2', 'setup.sh'])
+check_run(['python', 'tooltool.py', '-m', 'darwin.manifest', 'add',
+           'clang-darwin.tar.bz2', 'setup.sh'])
+
+def key_sort(item):
+    item = item[0]
+    if item == 'size':
+        return 0
+    if item == 'digest':
+        return 1
+    if item == 'algorithm':
+        return 3
+    return 4
+
+rev = os.path.basename(os.getcwd()).split('-')[1]
+
+for platform in ['darwin', 'linux32', 'linux64']:
+    old_name = 'clang-' + platform + '.tar.bz2'
+    manifest = platform + '.manifest'
+    data = eval(file(manifest).read())
+    new_name = data[1]['digest']
+    data[1]['filename'] = 'clang.tar.bz2'
+    data = [{'clang_version' : 'r%s' % rev }] + data
+    out = file(manifest,'w')
+    simplejson.dump(data, out, indent=0, item_sort_key=key_sort)
+    out.write('\n')
+    os.rename(old_name, new_name)
--- a/caps/idl/nsIPrincipal.idl
+++ b/caps/idl/nsIPrincipal.idl
@@ -16,17 +16,17 @@ struct JSPrincipals;
 
 interface nsIURI;
 interface nsIContentSecurityPolicy;
 
 [ptr] native JSContext(JSContext);
 [ptr] native JSPrincipals(JSPrincipals);
 [ptr] native PrincipalArray(nsTArray<nsCOMPtr<nsIPrincipal> >);
 
-[scriptable, uuid(fbb93cc7-9a94-4743-8e89-9e6939cac083)]
+[scriptable, uuid(8a74b011-667d-4cfa-b2a2-b27582ba5f38)]
 interface nsIPrincipal : nsISerializable
 {
     /**
      * Values of capabilities for each principal. Order is
      * significant: if an operation is performed on a set
      * of capabilities, the minimum is computed.
      */
     const short ENABLE_DENIED                = 1;
@@ -240,16 +240,21 @@ interface nsIPrincipal : nsISerializable
      */
     readonly attribute unsigned short appStatus;
 
     /**
      * Returns the app id the principal is in.
      * Returns nsIAppsService::NO_APP_ID if this principal isn't part of an app.
      */
     readonly attribute unsigned long appId;
+
+    /**
+     * Returns true iif the principal is inside a browser element.
+     */
+    readonly attribute boolean isInBrowserElement;
 };
 
 /**
  * If nsSystemPrincipal is too risky to use, but we want a principal to access 
  * more than one origin, nsExpandedPrincipals letting us define an array of 
  * principals it subsumes. So script with an nsExpandedPrincipals will gain
  * same origin access when at least one of its principals it contains gained 
  * sameorigin acccess. An nsExpandedPrincipal will be subsumed by the system
--- a/caps/include/nsPrincipal.h
+++ b/caps/include/nsPrincipal.h
@@ -122,16 +122,17 @@ public:
   NS_IMETHOD SetDomain(nsIURI* aDomain);
   NS_IMETHOD GetOrigin(char** aOrigin);
   NS_IMETHOD Subsumes(nsIPrincipal* other, bool* _retval);
   NS_IMETHOD SubsumesIgnoringDomain(nsIPrincipal* other, bool* _retval);
   NS_IMETHOD CheckMayLoad(nsIURI* uri, bool report);
   NS_IMETHOD GetExtendedOrigin(nsACString& aExtendedOrigin);
   NS_IMETHOD GetAppStatus(PRUint16* aAppStatus);
   NS_IMETHOD GetAppId(PRUint32* aAppStatus);
+  NS_IMETHOD GetIsInBrowserElement(bool* aIsInBrowserElement);
 #ifdef DEBUG
   virtual void dumpImpl();
 #endif
 
   nsPrincipal();
 
   // Either Init() or InitFromPersistent() must be called before
   // the principal is in a usable state.
@@ -200,16 +201,17 @@ public:
   NS_IMETHOD SetDomain(nsIURI* aDomain);
   NS_IMETHOD GetOrigin(char** aOrigin);
   NS_IMETHOD Subsumes(nsIPrincipal* other, bool* _retval);
   NS_IMETHOD SubsumesIgnoringDomain(nsIPrincipal* other, bool* _retval);
   NS_IMETHOD CheckMayLoad(nsIURI* uri, bool report);
   NS_IMETHOD GetExtendedOrigin(nsACString& aExtendedOrigin);
   NS_IMETHOD GetAppStatus(PRUint16* aAppStatus);
   NS_IMETHOD GetAppId(PRUint32* aAppStatus);
+  NS_IMETHOD GetIsInBrowserElement(bool* aIsInBrowserElement);
 #ifdef DEBUG
   virtual void dumpImpl();
 #endif
   
   virtual void GetScriptLocation(nsACString &aStr) MOZ_OVERRIDE;
 
 private:
   nsTArray< nsCOMPtr<nsIPrincipal> > mPrincipals;
--- a/caps/src/nsNullPrincipal.cpp
+++ b/caps/src/nsNullPrincipal.cpp
@@ -330,16 +330,23 @@ nsNullPrincipal::GetAppStatus(PRUint16* 
 
 NS_IMETHODIMP
 nsNullPrincipal::GetAppId(PRUint32* aAppId)
 {
   *aAppId = nsIScriptSecurityManager::NO_APP_ID;
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsNullPrincipal::GetIsInBrowserElement(bool* aIsInBrowserElement)
+{
+  *aIsInBrowserElement = false;
+  return NS_OK;
+}
+
 /**
  * nsISerializable implementation
  */
 NS_IMETHODIMP
 nsNullPrincipal::Read(nsIObjectInputStream* aStream)
 {
   // no-op: CID is sufficient to create a useful nsNullPrincipal, since the URI
   // is not really relevant.
--- a/caps/src/nsPrincipal.cpp
+++ b/caps/src/nsPrincipal.cpp
@@ -1089,16 +1089,23 @@ nsPrincipal::GetAppId(PRUint32* aAppId)
     return NS_OK;
   }
 
   *aAppId = mAppId;
   return NS_OK;
 }
 
 NS_IMETHODIMP
+nsPrincipal::GetIsInBrowserElement(bool* aIsInBrowserElement)
+{
+  *aIsInBrowserElement = mInMozBrowser;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsPrincipal::Read(nsIObjectInputStream* aStream)
 {
   bool hasCapabilities;
   nsresult rv = aStream->ReadBoolean(&hasCapabilities);
   if (NS_SUCCEEDED(rv) && hasCapabilities) {
     mCapabilities = new nsHashtable(aStream, ReadAnnotationEntry,
                                     FreeAnnotationEntry, &rv);
     NS_ENSURE_TRUE(mCapabilities, NS_ERROR_OUT_OF_MEMORY);
@@ -1471,16 +1478,22 @@ nsExpandedPrincipal::GetAppStatus(PRUint
 }
 
 NS_IMETHODIMP
 nsExpandedPrincipal::GetAppId(PRUint32* aAppId)
 {
   return NS_ERROR_NOT_AVAILABLE;
 }
 
+NS_IMETHODIMP
+nsExpandedPrincipal::GetIsInBrowserElement(bool* aIsInBrowserElement)
+{
+  return NS_ERROR_NOT_AVAILABLE;
+}
+
 void
 nsExpandedPrincipal::GetScriptLocation(nsACString& aStr)
 {
   if (mCert) {
     aStr.Assign(mCert->fingerprint);
   } else {
     // Is that a good idea to list it's principals?
     aStr.Assign(EXPANDED_PRINCIPAL_SPEC);
--- a/caps/src/nsSystemPrincipal.cpp
+++ b/caps/src/nsSystemPrincipal.cpp
@@ -253,16 +253,23 @@ nsSystemPrincipal::GetAppStatus(PRUint16
 
 NS_IMETHODIMP
 nsSystemPrincipal::GetAppId(PRUint32* aAppId)
 {
   *aAppId = nsIScriptSecurityManager::NO_APP_ID;
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsSystemPrincipal::GetIsInBrowserElement(bool* aIsInBrowserElement)
+{
+  *aIsInBrowserElement = false;
+  return NS_OK;
+}
+
 //////////////////////////////////////////
 // Methods implementing nsISerializable //
 //////////////////////////////////////////
 
 NS_IMETHODIMP
 nsSystemPrincipal::Read(nsIObjectInputStream* aStream)
 {
     // no-op: CID is sufficient to identify the mSystemPrincipal singleton
--- a/caps/tests/mochitest/test_principal_extendedorigin_appid_appstatus.html
+++ b/caps/tests/mochitest/test_principal_extendedorigin_appid_appstatus.html
@@ -246,16 +246,17 @@ var gData = [
   // browser containing an iframe is part of the browser
   {
     src: "http://example.org/",
     isapp: false,
     browser: true,
     child: {
       src: "http://example.org/chrome/",
       isapp: false,
+      inBrowser: true,
     },
     test: [ "child-has-same-eo" ],
   },
 ];
 
 // The list of all data ids generated by this test.
 var eoList = [];
 
@@ -305,24 +306,30 @@ function checkIFrame(aFrame, data) {
     is(eoList.indexOf(principal.extendedOrigin), -1,
        "extendedOrigin should be unique");
   }
   if (data.test.indexOf("eo-as-last") != -1) {
     is(principal.extendedOrigin, eoList[eoList.length-1],
        "extendedOrigin should be the same as the last inserted one");
   }
 
+  is(principal.isInBrowserElement, !!data.browser,
+     "check principal.isInBrowserElement");
+
   if (data.child) {
     let childPrincipal = aFrame.contentWindow.frames[0].document.nodePrincipal;
 
     if (data.child.isapp) {
       is(childPrincipal.appStatus, Ci.nsIPrincipal.APP_STATUS_INSTALLED,
          "child should be an installed app");
     }
 
+    is(childPrincipal.isInBrowserElement, !!data.child.browser || !!data.child.inBrowser,
+       "check childPrincipal.isInBrowserElement");
+
     if (data.test.indexOf("child-has-same-eo") != -1) {
       is(childPrincipal.extendedOrigin, principal.extendedOrigin,
          "child should have the same extendedOrigin as parent");
       is(childPrincipal.appStatus, principal.appStatus,
          "child should have the same appStatus if it has the same extendedOrigin");
       is(childPrincipal.appId, principal.appId,
          "child should have the same appId if it has the same extendedOrigin");
     }
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -17,16 +17,17 @@ MOZ_APP_BASENAME = @MOZ_APP_BASENAME@
 MOZ_APP_VENDOR = @MOZ_APP_VENDOR@
 MOZ_APP_PROFILE = @MOZ_APP_PROFILE@
 MOZ_APP_ID = @MOZ_APP_ID@
 MAR_CHANNEL_ID = @MAR_CHANNEL_ID@
 ACCEPTED_MAR_CHANNEL_IDS = @ACCEPTED_MAR_CHANNEL_IDS@
 MOZ_PROFILE_MIGRATOR = @MOZ_PROFILE_MIGRATOR@
 MOZ_EXTENSION_MANAGER = @MOZ_EXTENSION_MANAGER@
 MOZ_APP_UA_NAME = @MOZ_APP_UA_NAME@
+MOZ_UA_OS_AGNOSTIC = @MOZ_UA_OS_AGNOSTIC@
 MOZ_APP_VERSION = @MOZ_APP_VERSION@
 MOZ_APP_MAXVERSION = @MOZ_APP_MAXVERSION@
 MOZ_MACBUNDLE_NAME = @MOZ_MACBUNDLE_NAME@
 MOZ_MACBUNDLE_ID = @MOZ_MACBUNDLE_ID@
 MOZ_APP_STATIC_INI = @MOZ_APP_STATIC_INI@
 
 MOZ_PKG_SPECIAL = @MOZ_PKG_SPECIAL@
 
--- a/configure.in
+++ b/configure.in
@@ -8406,16 +8406,20 @@ AC_SUBST(MOZ_PROFILE_MIGRATOR)
 AC_SUBST(MOZ_EXTENSION_MANAGER)
 AC_DEFINE_UNQUOTED(MOZ_APP_UA_NAME, "$MOZ_APP_UA_NAME")
 AC_SUBST(MOZ_APP_UA_NAME)
 AC_DEFINE_UNQUOTED(MOZ_APP_UA_VERSION, "$MOZ_APP_VERSION")
 AC_SUBST(MOZ_APP_VERSION)
 AC_SUBST(MOZ_APP_MAXVERSION)
 AC_DEFINE_UNQUOTED(FIREFOX_VERSION,$FIREFOX_VERSION)
 AC_SUBST(FIREFOX_VERSION)
+AC_SUBST(MOZ_UA_OS_AGNOSTIC)
+if test -n "$MOZ_UA_OS_AGNOSTIC"; then
+  AC_DEFINE(MOZ_UA_OS_AGNOSTIC)
+fi
 
 # We can't use the static application.ini data when building against
 # a libxul SDK.
 if test -n "$LIBXUL_SDK"; then
     MOZ_APP_STATIC_INI=
 fi
 AC_SUBST(MOZ_APP_STATIC_INI)
 
--- a/content/base/public/Element.h
+++ b/content/base/public/Element.h
@@ -2,17 +2,17 @@
  * vim: sw=2 ts=2 et :
  * 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_Element_h__
 #define mozilla_dom_Element_h__
 
-#include "nsIContent.h"
+#include "mozilla/dom/FragmentOrElement.h"
 #include "nsEventStates.h"
 
 class nsEventStateManager;
 class nsGlobalWindow;
 class nsFocusManager;
 class nsICSSDeclaration;
 
 // Element-specific flags
@@ -55,22 +55,22 @@ namespace dom {
 
 class Link;
 
 // IID for the dom::Element interface
 #define NS_ELEMENT_IID \
 { 0xc6c049a1, 0x96e8, 0x4580, \
   { 0xa6, 0x93, 0xb9, 0x5f, 0x53, 0xbe, 0xe8, 0x1c } }
 
-class Element : public nsIContent
+class Element : public FragmentOrElement
 {
 public:
 #ifdef MOZILLA_INTERNAL_API
   Element(already_AddRefed<nsINodeInfo> aNodeInfo) :
-    nsIContent(aNodeInfo),
+    FragmentOrElement(aNodeInfo),
     mState(NS_EVENT_STATE_MOZ_READONLY)
   {}
 #endif // MOZILLA_INTERNAL_API
 
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ELEMENT_IID)
 
   /**
    * Method to get the full state of this element.  See nsEventStates.h for
@@ -184,16 +184,41 @@ public:
    */
   virtual nsICSSDeclaration* GetSMILOverrideStyle() = 0;
 
   /**
    * Returns if the element is labelable as per HTML specification.
    */
   virtual bool IsLabelable() const = 0;
 
+  /**
+   * Is the attribute named stored in the mapped attributes?
+   *
+   * // XXXbz we use this method in HasAttributeDependentStyle, so svg
+   *    returns true here even though it stores nothing in the mapped
+   *    attributes.
+   */
+  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const = 0;
+
+  /**
+   * Get a hint that tells the style system what to do when
+   * an attribute on this node changes, if something needs to happen
+   * in response to the change *other* than the result of what is
+   * mapped into style data via any type of style rule.
+   */
+  virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
+                                              PRInt32 aModType) const = 0;
+
+  /**
+   * Returns an atom holding the name of the "class" attribute on this
+   * content node (if applicable).  Returns null if there is no
+   * "class" attribute for this type of content node.
+   */
+  virtual nsIAtom *GetClassAttributeName() const = 0;
+
 protected:
   /**
    * Method to get the _intrinsic_ content state of this element.  This is the
    * state that is independent of the element's presentation.  To get the full
    * content state, use State().  See nsEventStates.h for
    * the possible bits that could be set here.
    */
   virtual nsEventStates IntrinsicState() const;
copy from content/base/src/nsGenericElement.h
copy to content/base/public/FragmentOrElement.h
--- a/content/base/src/nsGenericElement.h
+++ b/content/base/public/FragmentOrElement.h
@@ -1,25 +1,25 @@
 /* -*- 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/. */
 
 /*
- * Base class for all element classes; this provides an implementation
- * of DOM Core's nsIDOMElement, implements nsIContent, provides
+ * Base class for all element classes as well as nsDocumentFragment.  This
+ * provides an implementation of nsIDOMNode, implements nsIContent, provides
  * utility methods for subclasses, and so forth.
  */
 
-#ifndef nsGenericElement_h___
-#define nsGenericElement_h___
+#ifndef FragmentOrElement_h___
+#define FragmentOrElement_h___
 
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
-#include "mozilla/dom/Element.h"
+#include "nsIContent.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMDocumentFragment.h"
 #include "nsILinkHandler.h"
 #include "nsNodeUtils.h"
 #include "nsAttrAndChildArray.h"
 #include "mozFlushType.h"
 #include "nsDOMAttributeMap.h"
 #include "nsIWeakReference.h"
@@ -96,17 +96,17 @@ public:
   }
 
 private:
   // The node whose children make up the list (weak reference)
   nsINode* mNode;
 };
 
 /**
- * A tearoff class for nsGenericElement to implement additional interfaces
+ * A tearoff class for FragmentOrElement to implement additional interfaces
  */
 class nsNode3Tearoff : public nsIDOMXPathNSResolver
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
   NS_DECL_CYCLE_COLLECTION_CLASS(nsNode3Tearoff)
 
@@ -171,17 +171,17 @@ public:
 
   NS_DECL_CYCLE_COLLECTION_CLASS(nsNodeSupportsWeakRefTearoff)
 
 private:
   nsCOMPtr<nsINode> mNode;
 };
 
 /**
- * A tearoff class for nsGenericElement to implement NodeSelector
+ * A tearoff class for FragmentOrElement to implement NodeSelector
  */
 class nsNodeSelectorTearoff MOZ_FINAL : public nsIDOMNodeSelector
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
   NS_DECL_NSIDOMNODESELECTOR
 
@@ -201,24 +201,27 @@ private:
 // Forward declare to allow being a friend
 class nsTouchEventReceiverTearoff;
 class nsInlineEventHandlersTearoff;
 
 /**
  * A generic base class for DOM elements, implementing many nsIContent,
  * nsIDOMNode and nsIDOMElement methods.
  */
-class nsGenericElement : public mozilla::dom::Element
+namespace mozilla {
+namespace dom {
+
+class FragmentOrElement : public nsIContent
 {
 public:
-  nsGenericElement(already_AddRefed<nsINodeInfo> aNodeInfo);
-  virtual ~nsGenericElement();
+  FragmentOrElement(already_AddRefed<nsINodeInfo> aNodeInfo);
+  virtual ~FragmentOrElement();
 
-  friend class nsTouchEventReceiverTearoff;
-  friend class nsInlineEventHandlersTearoff;
+  friend class ::nsTouchEventReceiverTearoff;
+  friend class ::nsInlineEventHandlersTearoff;
 
   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.
@@ -232,150 +235,38 @@ public:
   virtual PRInt32 IndexOf(nsINode* aPossibleChild) const;
   virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
                                  bool aNotify);
   virtual void RemoveChildAt(PRUint32 aIndex, bool aNotify);
   NS_IMETHOD GetTextContent(nsAString &aTextContent);
   NS_IMETHOD SetTextContent(const nsAString& aTextContent);
 
   // nsIContent interface methods
-  virtual void UpdateEditableState(bool aNotify);
-
-  virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
-                              nsIContent* aBindingParent,
-                              bool aCompileEventHandlers);
-  virtual void UnbindFromTree(bool aDeep = true,
-                              bool aNullParent = true);
   virtual already_AddRefed<nsINodeList> GetChildren(PRUint32 aFilter);
-  virtual nsIAtom *GetClassAttributeName() const;
-  virtual already_AddRefed<nsINodeInfo> GetExistingAttrNameFromQName(const nsAString& aStr) const;
-  nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
-                   const nsAString& aValue, bool aNotify)
-  {
-    return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify);
-  }
-  /**
-   * Helper for SetAttr/SetParsedAttr. This method will return true if aNotify
-   * is true or there are mutation listeners that must be triggered, the
-   * attribute is currently set, and the new value that is about to be set is
-   * different to the current value. As a perf optimization the new and old
-   * values will not actually be compared if we aren't notifying and we don't
-   * have mutation listeners (in which case it's cheap to just return false
-   * and let the caller go ahead and set the value).
-   * @param aOldValue Set to the old value of the attribute, but only if there
-   *   are event listeners. If set, the type of aOldValue will be either
-   *   nsAttrValue::eString or nsAttrValue::eAtom.
-   * @param aModType Set to nsIDOMMutationEvent::MODIFICATION or to
-   *   nsIDOMMutationEvent::ADDITION, but only if this helper returns true
-   * @param aHasListeners Set to true if there are mutation event listeners
-   *   listening for NS_EVENT_BITS_MUTATION_ATTRMODIFIED
-   */
-  bool MaybeCheckSameAttrVal(PRInt32 aNamespaceID, nsIAtom* aName,
-                             nsIAtom* aPrefix,
-                             const nsAttrValueOrString& aValue,
-                             bool aNotify, nsAttrValue& aOldValue,
-                             PRUint8* aModType, bool* aHasListeners);
-  virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, nsIAtom* aPrefix,
-                           const nsAString& aValue, bool aNotify);
-  virtual nsresult SetParsedAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
-                                 nsIAtom* aPrefix, nsAttrValue& aParsedValue,
-                                 bool aNotify);
-  virtual bool GetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
-                         nsAString& aResult) const;
-  virtual bool HasAttr(PRInt32 aNameSpaceID, nsIAtom* aName) const;
-  virtual bool AttrValueIs(PRInt32 aNameSpaceID, nsIAtom* aName,
-                             const nsAString& aValue,
-                             nsCaseTreatment aCaseSensitive) const;
-  virtual bool AttrValueIs(PRInt32 aNameSpaceID, nsIAtom* aName,
-                             nsIAtom* aValue,
-                             nsCaseTreatment aCaseSensitive) const;
-  virtual PRInt32 FindAttrValueIn(PRInt32 aNameSpaceID,
-                                  nsIAtom* aName,
-                                  AttrValuesArray* aValues,
-                                  nsCaseTreatment aCaseSensitive) const;
-  virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
-                             bool aNotify);
-  virtual const nsAttrName* GetAttrNameAt(PRUint32 aIndex) const;
-  virtual PRUint32 GetAttrCount() const;
   virtual const nsTextFragment *GetText();
   virtual PRUint32 TextLength() const;
   virtual nsresult SetText(const PRUnichar* aBuffer, PRUint32 aLength,
                            bool aNotify);
   // Need to implement this here too to avoid hiding.
   nsresult SetText(const nsAString& aStr, bool aNotify)
   {
     return SetText(aStr.BeginReading(), aStr.Length(), aNotify);
   }
   virtual nsresult AppendText(const PRUnichar* aBuffer, PRUint32 aLength,
                               bool aNotify);
   virtual bool TextIsOnlyWhitespace();
   virtual void AppendTextTo(nsAString& aResult);
   virtual nsIContent *GetBindingParent() const;
-  virtual bool IsNodeOfType(PRUint32 aFlags) const;
   virtual bool IsLink(nsIURI** aURI) const;
 
   virtual void DestroyContent();
   virtual void SaveSubtreeState();
 
-  virtual nsISMILAttr* GetAnimatedAttr(PRInt32 /*aNamespaceID*/, nsIAtom* /*aName*/)
-  {
-    return nullptr;
-  }
-  virtual nsICSSDeclaration* GetSMILOverrideStyle();
-  virtual mozilla::css::StyleRule* GetSMILOverrideStyleRule();
-  virtual nsresult SetSMILOverrideStyleRule(mozilla::css::StyleRule* aStyleRule,
-                                            bool aNotify);
-  virtual bool IsLabelable() const;
-
-#ifdef DEBUG
-  virtual void List(FILE* out, PRInt32 aIndent) const
-  {
-    List(out, aIndent, EmptyCString());
-  }
-  virtual void DumpContent(FILE* out, PRInt32 aIndent, bool aDumpAll) const;
-  void List(FILE* out, PRInt32 aIndent, const nsCString& aPrefix) const;
-  void ListAttributes(FILE* out) const;
-#endif
-
   virtual const nsAttrValue* DoGetClasses() const;
   NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker);
-  virtual mozilla::css::StyleRule* GetInlineStyleRule();
-  virtual nsresult SetInlineStyleRule(mozilla::css::StyleRule* aStyleRule,
-                                      const nsAString* aSerialized,
-                                      bool aNotify);
-  NS_IMETHOD_(bool)
-    IsAttributeMapped(const nsIAtom* aAttribute) const;
-  virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
-                                              PRInt32 aModType) const;
-  /*
-   * Attribute Mapping Helpers
-   */
-  struct MappedAttributeEntry {
-    nsIAtom** attribute;
-  };
-
-  /**
-   * A common method where you can just pass in a list of maps to check
-   * for attribute dependence. Most implementations of
-   * IsAttributeMapped should use this function as a default
-   * handler.
-   */
-  template<size_t N>
-  static bool
-  FindAttributeDependence(const nsIAtom* aAttribute,
-                          const MappedAttributeEntry* const (&aMaps)[N])
-  {
-    return FindAttributeDependence(aAttribute, aMaps, N);
-  }
-
-private:
-  static bool
-  FindAttributeDependence(const nsIAtom* aAttribute,
-                          const MappedAttributeEntry* const aMaps[],
-                          PRUint32 aMapCount);
 
 public:
   // nsIDOMNode method implementation
   NS_IMETHOD GetNodeName(nsAString& aNodeName);
   NS_IMETHOD GetLocalName(nsAString& aLocalName);
   NS_IMETHOD GetNodeValue(nsAString& aNodeValue);
   NS_IMETHOD SetNodeValue(const nsAString& aNodeValue);
   NS_IMETHOD GetNodeType(PRUint16* aNodeType);
@@ -400,61 +291,40 @@ public:
   {
     return nsINode::RemoveChild(aOldChild, aReturn);
   }
   nsresult AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn)
   {
     return InsertBefore(aNewChild, nullptr, aReturn);
   }
 
-  // nsIDOMElement method implementation
-  NS_DECL_NSIDOMELEMENT
-
   nsresult CloneNode(bool aDeep, PRUint8 aOptionalArgc, nsIDOMNode **aResult)
   {
     if (!aOptionalArgc) {
       aDeep = true;
     }
     
     return nsNodeUtils::CloneNodeImpl(this, aDeep, true, aResult);
   }
 
   //----------------------------------------
 
   /**
-   * Add a script event listener with the given event handler name
-   * (like onclick) and with the value as JS
-   * @param aEventName the event listener name
-   * @param aValue the JS to attach
-   * @param aDefer indicates if deferred execution is allowed
-   */
-  nsresult AddScriptEventListener(nsIAtom* aEventName,
-                                  const nsAString& aValue,
-                                  bool aDefer = true);
-
-  /**
-   * Do whatever needs to be done when the mouse leaves a link
-   */
-  nsresult LeaveLink(nsPresContext* aPresContext);
-
-  /**
    * Check whether a spec feature/version is supported.
    * @param aObject the object, which should support the feature,
    *        for example nsIDOMNode or nsIDOMDOMImplementation
    * @param aFeature the feature ("Views", "Core", "HTML", "Range" ...)
    * @param aVersion the version ("1.0", "2.0", ...)
    * @param aReturn whether the feature is supported or not [OUT]
    */
   static nsresult InternalIsSupported(nsISupports* aObject,
                                       const nsAString& aFeature,
                                       const nsAString& aVersion,
                                       bool* aReturn);
 
-  static bool ShouldBlur(nsIContent *aContent);
-
   /**
    * If there are listeners for DOMNodeInserted event, fires the event on all
    * aNodes
    */
   static void FireNodeInserted(nsIDocument* aDoc,
                                nsINode* aParent,
                                nsTArray<nsCOMPtr<nsIContent> >& aNodes);
 
@@ -462,136 +332,17 @@ public:
    * Helper methods for implementing querySelector/querySelectorAll
    */
   static nsIContent* doQuerySelector(nsINode* aRoot, const nsAString& aSelector,
                                      nsresult *aResult);
   static nsresult doQuerySelectorAll(nsINode* aRoot,
                                      const nsAString& aSelector,
                                      nsIDOMNodeList **aReturn);
 
-  /**
-   * Method to create and dispatch a left-click event loosely based on
-   * aSourceEvent. If aFullDispatch is true, the event will be dispatched
-   * through the full dispatching of the presshell of the aPresContext; if it's
-   * false the event will be dispatched only as a DOM event.
-   * If aPresContext is nullptr, this does nothing.
-   */
-  static nsresult DispatchClickEvent(nsPresContext* aPresContext,
-                                     nsInputEvent* aSourceEvent,
-                                     nsIContent* aTarget,
-                                     bool aFullDispatch,
-                                     PRUint32 aFlags,
-                                     nsEventStatus* aStatus);
-
-  /**
-   * Method to dispatch aEvent to aTarget. If aFullDispatch is true, the event
-   * will be dispatched through the full dispatching of the presshell of the
-   * aPresContext; if it's false the event will be dispatched only as a DOM
-   * event.
-   * If aPresContext is nullptr, this does nothing.
-   */
-  using nsIContent::DispatchEvent;
-  static nsresult DispatchEvent(nsPresContext* aPresContext,
-                                nsEvent* aEvent,
-                                nsIContent* aTarget,
-                                bool aFullDispatch,
-                                nsEventStatus* aStatus);
-
-  /**
-   * Get the primary frame for this content with flushing
-   *
-   * @param aType the kind of flush to do, typically Flush_Frames or
-   *              Flush_Layout
-   * @return the primary frame
-   */
-  nsIFrame* GetPrimaryFrame(mozFlushType aType);
-  // Work around silly C++ name hiding stuff
-  nsIFrame* GetPrimaryFrame() const { return nsIContent::GetPrimaryFrame(); }
-
-  /**
-   * Struct that stores info on an attribute.  The name and value must
-   * either both be null or both be non-null.
-   */
-  struct nsAttrInfo {
-    nsAttrInfo(const nsAttrName* aName, const nsAttrValue* aValue) :
-      mName(aName), mValue(aValue) {}
-    nsAttrInfo(const nsAttrInfo& aOther) :
-      mName(aOther.mName), mValue(aOther.mValue) {}
-
-    const nsAttrName* mName;
-    const nsAttrValue* mValue;
-  };
-
-  // Be careful when using this method. This does *NOT* handle
-  // XUL prototypes. You may want to use GetAttrInfo.
-  const nsAttrValue* GetParsedAttr(nsIAtom* aAttr) const
-  {
-    return mAttrsAndChildren.GetAttr(aAttr);
-  }
-
-  /**
-   * Returns the attribute map, if there is one.
-   *
-   * @return existing attribute map or nullptr.
-   */
-  nsDOMAttributeMap *GetAttributeMap()
-  {
-    nsDOMSlots *slots = GetExistingDOMSlots();
-
-    return slots ? slots->mAttributeMap.get() : nullptr;
-  }
-
-  virtual void RecompileScriptEventListeners()
-  {
-  }
-
-  PRInt32 GetScrollTop();
-  PRInt32 GetScrollLeft();
-  PRInt32 GetScrollHeight();
-  PRInt32 GetScrollWidth();
-  PRInt32 GetScrollLeftMax();
-  PRInt32 GetScrollTopMax();
-  PRInt32 GetClientTop()
-  {
-    return nsPresContext::AppUnitsToIntCSSPixels(GetClientAreaRect().y);
-  }
-  PRInt32 GetClientLeft()
-  {
-    return nsPresContext::AppUnitsToIntCSSPixels(GetClientAreaRect().x);
-  }
-  PRInt32 GetClientHeight()
-  {
-    return nsPresContext::AppUnitsToIntCSSPixels(GetClientAreaRect().height);
-  }
-  PRInt32 GetClientWidth()
-  {
-    return nsPresContext::AppUnitsToIntCSSPixels(GetClientAreaRect().width);
-  }
-  nsIContent* GetFirstElementChild();
-  nsIContent* GetLastElementChild();
-  nsIContent* GetPreviousElementSibling();
-  nsIContent* GetNextElementSibling();
-  nsDOMTokenList* GetClassList(nsresult *aResult);
-  bool MozMatchesSelector(const nsAString& aSelector, nsresult* aResult);
-
-  /**
-   * Get the attr info for the given namespace ID and attribute name.  The
-   * namespace ID must not be kNameSpaceID_Unknown and the name must not be
-   * null.  Note that this can only return info on attributes that actually
-   * live on this element (and is only virtual to handle XUL prototypes).  That
-   * is, this should only be called from methods that only care about attrs
-   * that effectively live in mAttrsAndChildren.
-   */
-  virtual nsAttrInfo GetAttrInfo(PRInt32 aNamespaceID, nsIAtom* aName) const;
-
-  NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(nsGenericElement)
-
-  virtual void NodeInfoChanged(nsINodeInfo* aOldNodeInfo)
-  {
-  }
+  NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(FragmentOrElement)
 
   /**
    * Fire a DOMNodeRemoved mutation event for all children of this node
    */
   void FireNodeRemovedForChildren();
 
   virtual bool OwnedOnlyByTheDOMTree()
   {
@@ -619,199 +370,22 @@ public:
   static bool CanSkipThis(nsINode* aNode);
   static void MarkNodeChildren(nsINode* aNode);
   static void InitCCCallbacks();
   static void MarkUserData(void* aObject, nsIAtom* aKey, void* aChild,
                            void *aData);
   static void MarkUserDataHandler(void* aObject, nsIAtom* aKey, void* aChild,
                                   void* aData);
 
-  /**
-   * Parse a string into an nsAttrValue for a CORS attribute.  This
-   * never fails.  The resulting value is an enumerated value whose
-   * GetEnumValue() returns one of the above constants.
-   */
-  static void ParseCORSValue(const nsAString& aValue, nsAttrValue& aResult);
-
-  /**
-   * Return the CORS mode for a given string
-   */
-  static mozilla::CORSMode StringToCORSMode(const nsAString& aValue);
-  
-  /**
-   * Return the CORS mode for a given nsAttrValue (which may be null,
-   * but if not should have been parsed via ParseCORSValue).
-   */
-  static mozilla::CORSMode AttrValueToCORSMode(const nsAttrValue* aValue);
-
 protected:
-  /*
-   * Named-bools for use with SetAttrAndNotify to make call sites easier to
-   * read.
-   */
-  static const bool kFireMutationEvent           = true;
-  static const bool kDontFireMutationEvent       = false;
-  static const bool kNotifyDocumentObservers     = true;
-  static const bool kDontNotifyDocumentObservers = false;
-  static const bool kCallAfterSetAttr            = true;
-  static const bool kDontCallAfterSetAttr        = false;
-
-  /**
-   * Set attribute and (if needed) notify documentobservers and fire off
-   * mutation events.  This will send the AttributeChanged notification.
-   * Callers of this method are responsible for calling AttributeWillChange,
-   * since that needs to happen before the new attr value has been set, and
-   * in particular before it has been parsed.
-   *
-   * For the boolean parameters, consider using the named bools above to aid
-   * code readability.
-   *
-   * @param aNamespaceID  namespace of attribute
-   * @param aAttribute    local-name of attribute
-   * @param aPrefix       aPrefix of attribute
-   * @param aOldValue     previous value of attribute. Only needed if
-   *                      aFireMutation is true.
-   * @param aParsedValue  parsed new value of attribute
-   * @param aModType      nsIDOMMutationEvent::MODIFICATION or ADDITION.  Only
-   *                      needed if aFireMutation or aNotify is true.
-   * @param aFireMutation should mutation-events be fired?
-   * @param aNotify       should we notify document-observers?
-   * @param aCallAfterSetAttr should we call AfterSetAttr?
-   */
-  nsresult SetAttrAndNotify(PRInt32 aNamespaceID,
-                            nsIAtom* aName,
-                            nsIAtom* aPrefix,
-                            const nsAttrValue& aOldValue,
-                            nsAttrValue& aParsedValue,
-                            PRUint8 aModType,
-                            bool aFireMutation,
-                            bool aNotify,
-                            bool aCallAfterSetAttr);
-
-  /**
-   * Convert an attribute string value to attribute type based on the type of
-   * attribute.  Called by SetAttr().  Note that at the moment we only do this
-   * for attributes in the null namespace (kNameSpaceID_None).
-   *
-   * @param aNamespaceID the namespace of the attribute to convert
-   * @param aAttribute the attribute to convert
-   * @param aValue the string value to convert
-   * @param aResult the nsAttrValue [OUT]
-   * @return true if the parsing was successful, false otherwise
-   */
-  virtual bool ParseAttribute(PRInt32 aNamespaceID,
-                                nsIAtom* aAttribute,
-                                const nsAString& aValue,
-                                nsAttrValue& aResult);
-
-  /**
-   * Try to set the attribute as a mapped attribute, if applicable.  This will
-   * only be called for attributes that are in the null namespace and only on
-   * attributes that returned true when passed to IsAttributeMapped.  The
-   * caller will not try to set the attr in any other way if this method
-   * returns true (the value of aRetval does not matter for that purpose).
-   *
-   * @param aDocument the current document of this node (an optimization)
-   * @param aName the name of the attribute
-   * @param aValue the nsAttrValue to set
-   * @param [out] aRetval the nsresult status of the operation, if any.
-   * @return true if the setting was attempted, false otherwise.
-   */
-  virtual bool SetMappedAttribute(nsIDocument* aDocument,
-                                    nsIAtom* aName,
-                                    nsAttrValue& aValue,
-                                    nsresult* aRetval);
-
-  /**
-   * Hook that is called by nsGenericElement::SetAttr to allow subclasses to
-   * deal with attribute sets.  This will only be called after we verify that
-   * we're actually doing an attr set and will be called before
-   * AttributeWillChange and before ParseAttribute and hence before we've set
-   * the new value.
-   *
-   * @param aNamespaceID the namespace of the attr being set
-   * @param aName the localname of the attribute being set
-   * @param aValue the value it's being set to represented as either a string or
-   *        a parsed nsAttrValue. Alternatively, if the attr is being removed it
-   *        will be null.
-   * @param aNotify Whether we plan to notify document observers.
-   */
-  // Note that this is inlined so that when subclasses call it it gets
-  // inlined.  Those calls don't go through a vtable.
-  virtual nsresult BeforeSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
-                                 const nsAttrValueOrString* aValue,
-                                 bool aNotify)
-  {
-    return NS_OK;
-  }
-
-  /**
-   * Hook that is called by nsGenericElement::SetAttr to allow subclasses to
-   * deal with attribute sets.  This will only be called after we have called
-   * SetAndTakeAttr and AttributeChanged (that is, after we have actually set
-   * the attr).  It will always be called under a scriptblocker.
-   *
-   * @param aNamespaceID the namespace of the attr being set
-   * @param aName the localname of the attribute being set
-   * @param aValue the value it's being set to.  If null, the attr is being
-   *        removed.
-   * @param aNotify Whether we plan to notify document observers.
-   */
-  // Note that this is inlined so that when subclasses call it it gets
-  // inlined.  Those calls don't go through a vtable.
-  virtual nsresult AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
-                                const nsAttrValue* aValue, bool aNotify)
-  {
-    return NS_OK;
-  }
-
-  /**
-   * Hook to allow subclasses to produce a different nsEventListenerManager if
-   * needed for attachment of attribute-defined handlers
-   */
-  virtual nsEventListenerManager*
-    GetEventListenerManagerForAttr(nsIAtom* aAttrName, bool* aDefer);
-
   /**
    * Copy attributes and state to another element
    * @param aDest the object to copy to
    */
-  nsresult CopyInnerTo(nsGenericElement* aDest);
-
-  /**
-   * Internal hook for converting an attribute name-string to an atomized name
-   */
-  virtual const nsAttrName* InternalGetExistingAttrNameFromQName(const nsAString& aStr) const;
-
-  /**
-   * Retrieve the rectangle for the offsetX properties, which
-   * are coordinates relative to the returned aOffsetParent.
-   *
-   * @param aRect offset rectangle
-   * @param aOffsetParent offset parent
-   */
-  virtual void GetOffsetRect(nsRect& aRect, nsIContent** aOffsetParent);
-
-  /**
-   * Retrieve the size of the padding rect of this element.
-   *
-   * @param aSize the size of the padding rect
-   */
-  nsIntSize GetPaddingRectSize();
-
-  nsIFrame* GetStyledFrame();
-
-  virtual mozilla::dom::Element* GetNameSpaceElement()
-  {
-    return this;
-  }
-
-  nsresult GetAttributeNodeNSInternal(const nsAString& aNamespaceURI,
-                                      const nsAString& aLocalName,
-                                      nsIDOMAttr** aReturn);
+  nsresult CopyInnerTo(FragmentOrElement* aDest);
 
 public:
   // Because of a bug in MS C++ compiler nsDOMSlots must be declared public,
   // otherwise nsXULElement::nsXULSlots doesn't compile.
   /**
    * There are a set of DOM- and scripting-specific instance variables
    * that may only be instantiated when a content object is accessed
    * through the DOM. Rather than burn actual slots in the content
@@ -849,24 +423,24 @@ public:
 
     /**
      * Holds any SMIL override style rules for this element.
      */
     nsRefPtr<mozilla::css::StyleRule> mSMILOverrideStyleRule;
 
     /**
      * An object implementing nsIDOMNamedNodeMap for this content (attributes)
-     * @see nsGenericElement::GetAttributes
+     * @see FragmentOrElement::GetAttributes
      */
     nsRefPtr<nsDOMAttributeMap> mAttributeMap;
 
     union {
       /**
       * The nearest enclosing content node with a binding that created us.
-      * @see nsGenericElement::GetBindingParent
+      * @see FragmentOrElement::GetBindingParent
       */
       nsIContent* mBindingParent;  // [Weak]
 
       /**
       * The controllers of the XUL Element.
       */
       nsIControllers* mControllers; // [OWNER]
     };
@@ -891,222 +465,70 @@ protected:
     return static_cast<nsDOMSlots*>(GetSlots());
   }
 
   nsDOMSlots *GetExistingDOMSlots() const
   {
     return static_cast<nsDOMSlots*>(GetExistingSlots());
   }
 
-  void RegisterFreezableElement() {
-    OwnerDoc()->RegisterFreezableElement(this);
-  }
-  void UnregisterFreezableElement() {
-    OwnerDoc()->UnregisterFreezableElement(this);
-  }
-
-  /**
-   * Add/remove this element to the documents id cache
-   */
-  void AddToIdTable(nsIAtom* aId) {
-    NS_ASSERTION(HasID(), "Node doesn't have an ID?");
-    nsIDocument* doc = GetCurrentDoc();
-    if (doc && (!IsInAnonymousSubtree() || doc->IsXUL())) {
-      doc->AddToIdTable(this, aId);
-    }
-  }
-  void RemoveFromIdTable() {
-    if (HasID()) {
-      nsIDocument* doc = GetCurrentDoc();
-      if (doc) {
-        nsIAtom* id = DoGetID();
-        // id can be null during mutation events evilness. Also, XUL elements
-        // loose their proto attributes during cc-unlink, so this can happen
-        // during cc-unlink too.
-        if (id) {
-          doc->RemoveFromIdTable(this, DoGetID());
-        }
-      }
-    }
-  }
-
-  /**
-   * Functions to carry out event default actions for links of all types
-   * (HTML links, XLinks, SVG "XLinks", etc.)
-   */
-
-  /**
-   * Check that we meet the conditions to handle a link event
-   * and that we are actually on a link.
-   *
-   * @param aVisitor event visitor
-   * @param aURI the uri of the link, set only if the return value is true [OUT]
-   * @return true if we can handle the link event, false otherwise
-   */
-  bool CheckHandleEventForLinksPrecondition(nsEventChainVisitor& aVisitor,
-                                              nsIURI** aURI) const;
-
-  /**
-   * Handle status bar updates before they can be cancelled.
-   */
-  nsresult PreHandleEventForLinks(nsEventChainPreVisitor& aVisitor);
-
-  /**
-   * Handle default actions for link event if the event isn't consumed yet.
-   */
-  nsresult PostHandleEventForLinks(nsEventChainPostVisitor& aVisitor);
-
-  /**
-   * Get the target of this link element. Consumers should established that
-   * this element is a link (probably using IsLink) before calling this
-   * function (or else why call it?)
-   *
-   * Note: for HTML this gets the value of the 'target' attribute; for XLink
-   * this gets the value of the xlink:_moz_target attribute, or failing that,
-   * the value of xlink:show, converted to a suitably equivalent named target
-   * (e.g. _blank).
-   */
-  virtual void GetLinkTarget(nsAString& aTarget);
-
-  friend class ContentUnbinder;
+  friend class ::ContentUnbinder;
   /**
    * Array containing all attributes and children for this element
    */
   nsAttrAndChildArray mAttrsAndChildren;
 
-private:
-  /**
-   * Get this element's client area rect in app units.
-   * @return the frame's client area
-   */
-  nsRect GetClientAreaRect();
-
-  nsIScrollableFrame* GetScrollFrame(nsIFrame **aStyledFrame = nullptr);
-
   nsContentList* GetChildrenList();
 };
 
-/**
- * Macros to implement Clone(). _elementName is the class for which to implement
- * Clone.
- */
-#define NS_IMPL_ELEMENT_CLONE(_elementName)                                 \
-nsresult                                                                    \
-_elementName::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const        \
-{                                                                           \
-  *aResult = nullptr;                                                        \
-  nsCOMPtr<nsINodeInfo> ni = aNodeInfo;                                     \
-  _elementName *it = new _elementName(ni.forget());                         \
-  if (!it) {                                                                \
-    return NS_ERROR_OUT_OF_MEMORY;                                          \
-  }                                                                         \
-                                                                            \
-  nsCOMPtr<nsINode> kungFuDeathGrip = it;                                   \
-  nsresult rv = const_cast<_elementName*>(this)->CopyInnerTo(it);           \
-  if (NS_SUCCEEDED(rv)) {                                                   \
-    kungFuDeathGrip.swap(*aResult);                                         \
-  }                                                                         \
-                                                                            \
-  return rv;                                                                \
-}
-
-#define NS_IMPL_ELEMENT_CLONE_WITH_INIT(_elementName)                       \
-nsresult                                                                    \
-_elementName::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const        \
-{                                                                           \
-  *aResult = nullptr;                                                        \
-  nsCOMPtr<nsINodeInfo> ni = aNodeInfo;                                     \
-  _elementName *it = new _elementName(ni.forget());                         \
-  if (!it) {                                                                \
-    return NS_ERROR_OUT_OF_MEMORY;                                          \
-  }                                                                         \
-                                                                            \
-  nsCOMPtr<nsINode> kungFuDeathGrip = it;                                   \
-  nsresult rv = it->Init();                                                 \
-  nsresult rv2 = const_cast<_elementName*>(this)->CopyInnerTo(it);          \
-  if (NS_FAILED(rv2)) {                                                     \
-    rv = rv2;                                                               \
-  }                                                                         \
-  if (NS_SUCCEEDED(rv)) {                                                   \
-    kungFuDeathGrip.swap(*aResult);                                         \
-  }                                                                         \
-                                                                            \
-  return rv;                                                                \
-}
-
-#define DOMCI_NODE_DATA(_interface, _class)                             \
-  DOMCI_DATA(_interface, _class)                                        \
-  nsXPCClassInfo* _class::GetClassInfo()                                \
-  {                                                                     \
-    return static_cast<nsXPCClassInfo*>(                                \
-      NS_GetDOMClassInfoInstance(eDOMClassInfo_##_interface##_id));     \
-  }
-
-/**
- * A macro to implement the getter and setter for a given string
- * valued content property. The method uses the generic GetAttr and
- * SetAttr methods.  We use the 5-argument form of SetAttr, because
- * some consumers only implement that one, hiding superclass
- * 4-argument forms.
- */
-#define NS_IMPL_STRING_ATTR(_class, _method, _atom)                     \
-  NS_IMETHODIMP                                                         \
-  _class::Get##_method(nsAString& aValue)                               \
-  {                                                                     \
-    GetAttr(kNameSpaceID_None, nsGkAtoms::_atom, aValue);               \
-    return NS_OK;                                                       \
-  }                                                                     \
-  NS_IMETHODIMP                                                         \
-  _class::Set##_method(const nsAString& aValue)                         \
-  {                                                                     \
-    return SetAttr(kNameSpaceID_None, nsGkAtoms::_atom, nullptr, aValue, true); \
-  }
+} // namespace dom
+} // namespace mozilla
 
 /**
  * Tearoff class to implement nsITouchEventReceiver
  */
 class nsTouchEventReceiverTearoff MOZ_FINAL : public nsITouchEventReceiver
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
   NS_FORWARD_NSITOUCHEVENTRECEIVER(mElement->)
 
   NS_DECL_CYCLE_COLLECTION_CLASS(nsTouchEventReceiverTearoff)
 
-  nsTouchEventReceiverTearoff(nsGenericElement *aElement) : mElement(aElement)
+  nsTouchEventReceiverTearoff(mozilla::dom::FragmentOrElement *aElement) : mElement(aElement)
   {
   }
 
 private:
-  nsRefPtr<nsGenericElement> mElement;
+  nsRefPtr<mozilla::dom::FragmentOrElement> mElement;
 };
 
 /**
  * Tearoff class to implement nsIInlineEventHandlers
  */
 class nsInlineEventHandlersTearoff MOZ_FINAL : public nsIInlineEventHandlers
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
   NS_FORWARD_NSIINLINEEVENTHANDLERS(mElement->)
 
   NS_DECL_CYCLE_COLLECTION_CLASS(nsInlineEventHandlersTearoff)
 
-  nsInlineEventHandlersTearoff(nsGenericElement *aElement) : mElement(aElement)
+  nsInlineEventHandlersTearoff(mozilla::dom::FragmentOrElement *aElement) : mElement(aElement)
   {
   }
 
 private:
-  nsRefPtr<nsGenericElement> mElement;
+  nsRefPtr<mozilla::dom::FragmentOrElement> mElement;
 };
 
 #define NS_ELEMENT_INTERFACE_TABLE_TO_MAP_SEGUE                               \
-    rv = nsGenericElement::QueryInterface(aIID, aInstancePtr);                \
+    rv = FragmentOrElement::QueryInterface(aIID, aInstancePtr);                \
     if (NS_SUCCEEDED(rv))                                                     \
       return rv;                                                              \
                                                                               \
     NS_OFFSET_AND_INTERFACE_TABLE_TO_MAP_SEGUE
 
 #define NS_ELEMENT_INTERFACE_MAP_END                                          \
     {                                                                         \
       return PostQueryInterface(aIID, aInstancePtr);                          \
@@ -1114,9 +536,9 @@ private:
                                                                               \
     NS_ADDREF(foundInterface);                                                \
                                                                               \
     *aInstancePtr = foundInterface;                                           \
                                                                               \
     return NS_OK;                                                             \
   }
 
-#endif /* nsGenericElement_h___ */
+#endif /* FragmentOrElement_h___ */
--- a/content/base/public/Makefile.in
+++ b/content/base/public/Makefile.in
@@ -44,16 +44,17 @@ nsTreeSanitizer.h \
 nsXMLNameSpaceMap.h \
 nsIXFormsUtilityService.h \
 $(NULL)
 
 EXPORTS_NAMESPACES = mozilla/dom mozilla
 
 EXPORTS_mozilla/dom = \
 		Element.h \
+		FragmentOrElement.h \
 		FromParser.h \
 		$(NULL)
 
 EXPORTS_mozilla = \
 		CORSMode.h \
 		$(NULL)
 
 SDK_XPIDLSRCS   = \
--- a/content/base/public/nsIContent.h
+++ b/content/base/public/nsIContent.h
@@ -6,16 +6,17 @@
 #define nsIContent_h___
 
 #include "nsCOMPtr.h" // for already_AddRefed
 #include "nsStringGlue.h"
 #include "nsCaseTreatment.h"
 #include "nsChangeHint.h"
 #include "nsINode.h"
 #include "nsIDocument.h" // for IsInHTMLDocument
+#include "nsCSSProperty.h"
 
 // Forward declarations
 class nsIAtom;
 class nsIDOMEvent;
 class nsIContent;
 class nsEventListenerManager;
 class nsIURI;
 class nsRuleWalker;
@@ -757,41 +758,16 @@ public:
 
   /**
    * Walk aRuleWalker over the content style rules (presentational
    * hint rules) for this content node.
    */
   NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker) = 0;
 
   /**
-   * Is the attribute named stored in the mapped attributes?
-   *
-   * // XXXbz we use this method in HasAttributeDependentStyle, so svg
-   *    returns true here even though it stores nothing in the mapped
-   *    attributes.
-   */
-  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const = 0;
-
-  /**
-   * Get a hint that tells the style system what to do when 
-   * an attribute on this node changes, if something needs to happen
-   * in response to the change *other* than the result of what is
-   * mapped into style data via any type of style rule.
-   */
-  virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
-                                              PRInt32 aModType) const = 0;
-
-  /**
-   * Returns an atom holding the name of the "class" attribute on this
-   * content node (if applicable).  Returns null if there is no
-   * "class" attribute for this type of content node.
-   */
-  virtual nsIAtom *GetClassAttributeName() const = 0;
-
-  /**
    * Should be called when the node can become editable or when it can stop
    * being editable (for example when its contentEditable attribute changes,
    * when it is moved into an editable parent, ...).  If aNotify is true and
    * the node is an element, this will notify the state change.
    */
   virtual void UpdateEditableState(bool aNotify);
 
   /**
--- a/content/base/public/nsINode.h
+++ b/content/base/public/nsINode.h
@@ -1286,16 +1286,18 @@ private:
     // Set if the element has some style states locked
     ElementHasLockedStyleStates,
     // Set if element has pointer locked
     ElementHasPointerLock,
     // Set if the node may have DOMMutationObserver attached to it.
     NodeMayHaveDOMMutationObserver,
     // Set if node is Content
     NodeIsContent,
+    // Set if the node has animations or transitions
+    ElementHasAnimations,
     // Guard value
     BooleanFlagCount
   };
 
   void SetBoolFlag(BooleanFlag name, bool value) {
     PR_STATIC_ASSERT(BooleanFlagCount <= 8*sizeof(mBoolFlags));
     mBoolFlags = (mBoolFlags & ~(1 << name)) | (value << name);
   }
@@ -1351,23 +1353,24 @@ public:
   bool MayHaveDOMMutationObserver()
     { return GetBoolFlag(NodeMayHaveDOMMutationObserver); }
   void SetMayHaveDOMMutationObserver()
     { SetBoolFlag(NodeMayHaveDOMMutationObserver, true); }
   bool HasListenerManager() { return HasFlag(NODE_HAS_LISTENERMANAGER); }
   bool HasPointerLock() const { return GetBoolFlag(ElementHasPointerLock); }
   void SetPointerLock() { SetBoolFlag(ElementHasPointerLock); }
   void ClearPointerLock() { ClearBoolFlag(ElementHasPointerLock); }
+  bool MayHaveAnimations() { return GetBoolFlag(ElementHasAnimations); }
+  void SetMayHaveAnimations() { SetBoolFlag(ElementHasAnimations); }
 protected:
   void SetParentIsContent(bool aValue) { SetBoolFlag(ParentIsContent, aValue); }
   void SetInDocument() { SetBoolFlag(IsInDocument); }
   void SetNodeIsContent() { SetBoolFlag(NodeIsContent); }
   void ClearInDocument() { ClearBoolFlag(IsInDocument); }
   void SetIsElement() { SetBoolFlag(NodeIsElement); }
-  void ClearIsElement() { ClearBoolFlag(NodeIsElement); }
   void SetHasID() { SetBoolFlag(ElementHasID); }
   void ClearHasID() { ClearBoolFlag(ElementHasID); }
   void SetMayHaveStyle() { SetBoolFlag(ElementMayHaveStyle); }
   void SetHasName() { SetBoolFlag(ElementHasName); }
   void ClearHasName() { ClearBoolFlag(ElementHasName); }
   void SetMayHaveContentEditableAttr()
     { SetBoolFlag(ElementMayHaveContentEditableAttr); }
   bool HasExplicitBaseURI() const { return GetBoolFlag(NodeHasExplicitBaseURI); }
copy from content/base/src/nsGenericElement.cpp
copy to content/base/src/FragmentOrElement.cpp
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/FragmentOrElement.cpp
@@ -7,17 +7,17 @@
 /*
  * Base class for all element classes; this provides an implementation
  * of DOM Core's nsIDOMElement, implements nsIContent, provides
  * utility methods for subclasses, and so forth.
  */
 
 #include "mozilla/Util.h"
 
-#include "nsGenericElement.h"
+#include "mozilla/dom/FragmentOrElement.h"
 
 #include "nsDOMAttribute.h"
 #include "nsDOMAttributeMap.h"
 #include "nsIAtom.h"
 #include "nsINodeInfo.h"
 #include "nsIDocument.h"
 #include "nsIDOMNodeList.h"
 #include "nsIDOMDocument.h"
@@ -130,191 +130,16 @@ using namespace mozilla;
 using namespace mozilla::dom;
 
 NS_DEFINE_IID(kThisPtrOffsetsSID, NS_THISPTROFFSETS_SID);
 
 PRInt32 nsIContent::sTabFocusModel = eTabFocus_any;
 bool nsIContent::sTabFocusModelAppliesToXUL = false;
 PRUint32 nsMutationGuard::sMutationCount = 0;
 
-nsEventStates
-Element::IntrinsicState() const
-{
-  return IsEditable() ? NS_EVENT_STATE_MOZ_READWRITE :
-                        NS_EVENT_STATE_MOZ_READONLY;
-}
-
-void
-Element::NotifyStateChange(nsEventStates aStates)
-{
-  nsIDocument* doc = GetCurrentDoc();
-  if (doc) {
-    nsAutoScriptBlocker scriptBlocker;
-    doc->ContentStateChanged(this, aStates);
-  }
-}
-
-void
-Element::UpdateLinkState(nsEventStates aState)
-{
-  NS_ABORT_IF_FALSE(!aState.HasAtLeastOneOfStates(~(NS_EVENT_STATE_VISITED |
-                                                    NS_EVENT_STATE_UNVISITED)),
-                    "Unexpected link state bits");
-  mState =
-    (mState & ~(NS_EVENT_STATE_VISITED | NS_EVENT_STATE_UNVISITED)) |
-    aState;
-}
-
-void
-Element::UpdateState(bool aNotify)
-{
-  nsEventStates oldState = mState;
-  mState = IntrinsicState() | (oldState & ESM_MANAGED_STATES);
-  if (aNotify) {
-    nsEventStates changedStates = oldState ^ mState;
-    if (!changedStates.IsEmpty()) {
-      nsIDocument* doc = GetCurrentDoc();
-      if (doc) {
-        nsAutoScriptBlocker scriptBlocker;
-        doc->ContentStateChanged(this, changedStates);
-      }
-    }
-  }
-}
-
-void
-nsIContent::UpdateEditableState(bool aNotify)
-{
-  // Guaranteed to be non-element content
-  NS_ASSERTION(!IsElement(), "What happened here?");
-  nsIContent *parent = GetParent();
-
-  SetEditableFlag(parent && parent->HasFlag(NODE_IS_EDITABLE));
-}
-
-void
-nsGenericElement::UpdateEditableState(bool aNotify)
-{
-  nsIContent *parent = GetParent();
-
-  SetEditableFlag(parent && parent->HasFlag(NODE_IS_EDITABLE));
-  if (aNotify) {
-    UpdateState(aNotify);
-  } else {
-    // Avoid calling UpdateState in this very common case, because
-    // this gets called for pretty much every single element on
-    // insertion into the document and UpdateState can be slow for
-    // some kinds of elements even when not notifying.
-    if (IsEditable()) {
-      RemoveStatesSilently(NS_EVENT_STATE_MOZ_READONLY);
-      AddStatesSilently(NS_EVENT_STATE_MOZ_READWRITE);
-    } else {
-      RemoveStatesSilently(NS_EVENT_STATE_MOZ_READWRITE);
-      AddStatesSilently(NS_EVENT_STATE_MOZ_READONLY);
-    }
-  }
-}
-
-nsEventStates
-Element::StyleStateFromLocks() const
-{
-  nsEventStates locks = LockedStyleStates();
-  nsEventStates state = mState | locks;
-
-  if (locks.HasState(NS_EVENT_STATE_VISITED)) {
-    return state & ~NS_EVENT_STATE_UNVISITED;
-  }
-  if (locks.HasState(NS_EVENT_STATE_UNVISITED)) {
-    return state & ~NS_EVENT_STATE_VISITED;
-  }
-  return state;
-}
-
-nsEventStates
-Element::LockedStyleStates() const
-{
-  nsEventStates *locks =
-    static_cast<nsEventStates*> (GetProperty(nsGkAtoms::lockedStyleStates));
-  if (locks) {
-    return *locks;
-  }
-  return nsEventStates();
-}
-
-static void
-nsEventStatesPropertyDtor(void *aObject, nsIAtom *aProperty,
-                          void *aPropertyValue, void *aData)
-{
-  nsEventStates *states = static_cast<nsEventStates*>(aPropertyValue);
-  delete states;
-}
-
-void
-Element::NotifyStyleStateChange(nsEventStates aStates)
-{
-  nsIDocument* doc = GetCurrentDoc();
-  if (doc) {
-    nsIPresShell *presShell = doc->GetShell();
-    if (presShell) {
-      nsAutoScriptBlocker scriptBlocker;
-      presShell->ContentStateChanged(doc, this, aStates);
-    }
-  }
-}
-
-void
-Element::LockStyleStates(nsEventStates aStates)
-{
-  nsEventStates *locks = new nsEventStates(LockedStyleStates());
-
-  *locks |= aStates;
-
-  if (aStates.HasState(NS_EVENT_STATE_VISITED)) {
-    *locks &= ~NS_EVENT_STATE_UNVISITED;
-  }
-  if (aStates.HasState(NS_EVENT_STATE_UNVISITED)) {
-    *locks &= ~NS_EVENT_STATE_VISITED;
-  }
-
-  SetProperty(nsGkAtoms::lockedStyleStates, locks, nsEventStatesPropertyDtor);
-  SetHasLockedStyleStates();
-
-  NotifyStyleStateChange(aStates);
-}
-
-void
-Element::UnlockStyleStates(nsEventStates aStates)
-{
-  nsEventStates *locks = new nsEventStates(LockedStyleStates());
-
-  *locks &= ~aStates;
-
-  if (locks->IsEmpty()) {
-    DeleteProperty(nsGkAtoms::lockedStyleStates);
-    ClearHasLockedStyleStates();
-    delete locks;
-  }
-  else {
-    SetProperty(nsGkAtoms::lockedStyleStates, locks, nsEventStatesPropertyDtor);
-  }
-
-  NotifyStyleStateChange(aStates);
-}
-
-void
-Element::ClearStyleStateLocks()
-{
-  nsEventStates locks = LockedStyleStates();
-
-  DeleteProperty(nsGkAtoms::lockedStyleStates);
-  ClearHasLockedStyleStates();
-
-  NotifyStyleStateChange(locks);
-}
-
 nsIContent*
 nsIContent::FindFirstNonNativeAnonymous() const
 {
   // This handles also nested native anonymous content.
   for (const nsIContent *content = this; content;
        content = content->GetBindingParent()) {
     if (!content->IsInNativeAnonymousSubtree()) {
       // Oops, this function signature allows casting const to
@@ -623,572 +448,30 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(nsNode3
 
 NS_IMETHODIMP
 nsNode3Tearoff::LookupNamespaceURI(const nsAString& aNamespacePrefix,
                                    nsAString& aNamespaceURI)
 {
   return mNode->LookupNamespaceURI(aNamespacePrefix, aNamespaceURI);
 }
 
-nsIContent*
-nsGenericElement::GetFirstElementChild()
-{
-  nsAttrAndChildArray& children = mAttrsAndChildren;
-  PRUint32 i, count = children.ChildCount();
-  for (i = 0; i < count; ++i) {
-    nsIContent* child = children.ChildAt(i);
-    if (child->IsElement()) {
-      return child;
-    }
-  }
-  
-  return nullptr;
-}
-
-nsIContent*
-nsGenericElement::GetLastElementChild()
-{
-  nsAttrAndChildArray& children = mAttrsAndChildren;
-  PRUint32 i = children.ChildCount();
-  while (i > 0) {
-    nsIContent* child = children.ChildAt(--i);
-    if (child->IsElement()) {
-      return child;
-    }
-  }
-  
-  return nullptr;
-}
-
-nsIContent*
-nsGenericElement::GetPreviousElementSibling()
-{
-  nsIContent* parent = GetParent();
-  if (!parent) {
-    return nullptr;
-  }
-
-  NS_ASSERTION(parent->IsElement() ||
-               parent->IsNodeOfType(nsINode::eDOCUMENT_FRAGMENT),
-               "Parent content must be an element or a doc fragment");
-
-  nsAttrAndChildArray& children =
-    static_cast<nsGenericElement*>(parent)->mAttrsAndChildren;
-  PRInt32 index = children.IndexOfChild(this);
-  if (index < 0) {
-    return nullptr;
-  }
-
-  PRUint32 i = index;
-  while (i > 0) {
-    nsIContent* child = children.ChildAt((PRUint32)--i);
-    if (child->IsElement()) {
-      return child;
-    }
-  }
-  
-  return nullptr;
-}
-
-nsIContent*
-nsGenericElement::GetNextElementSibling()
+nsContentList*
+FragmentOrElement::GetChildrenList()
 {
-  nsIContent* parent = GetParent();
-  if (!parent) {
-    return nullptr;
-  }
-
-  NS_ASSERTION(parent->IsElement() ||
-               parent->IsNodeOfType(nsINode::eDOCUMENT_FRAGMENT),
-               "Parent content must be an element or a doc fragment");
-
-  nsAttrAndChildArray& children =
-    static_cast<nsGenericElement*>(parent)->mAttrsAndChildren;
-  PRInt32 index = children.IndexOfChild(this);
-  if (index < 0) {
-    return nullptr;
-  }
-
-  PRUint32 i, count = children.ChildCount();
-  for (i = (PRUint32)index + 1; i < count; ++i) {
-    nsIContent* child = children.ChildAt(i);
-    if (child->IsElement()) {
-      return child;
-    }
-  }
-  
-  return nullptr;
-}
-
-NS_IMETHODIMP
-nsGenericElement::GetChildElementCount(PRUint32* aResult)
-{
-  *aResult = GetChildrenList()->Length(true);
-  return NS_OK;
-}
-
-// readonly attribute nsIDOMNodeList children
-NS_IMETHODIMP
-nsGenericElement::GetChildElements(nsIDOMNodeList** aResult)
-{
-  NS_ADDREF(*aResult = GetChildrenList());
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsGenericElement::GetFirstElementChild(nsIDOMElement** aResult)
-{
-  *aResult = nullptr;
-
-  nsIContent *result = GetFirstElementChild();
-
-  return result ? CallQueryInterface(result, aResult) : NS_OK;
-}
-
-NS_IMETHODIMP
-nsGenericElement::GetLastElementChild(nsIDOMElement** aResult)
-{
-  *aResult = nullptr;
-
-  nsIContent *result = GetLastElementChild();
-
-  return result ? CallQueryInterface(result, aResult) : NS_OK;
-}
-
-NS_IMETHODIMP
-nsGenericElement::GetPreviousElementSibling(nsIDOMElement** aResult)
-{
-  *aResult = nullptr;
-
-  nsIContent *result = GetPreviousElementSibling();
-
-  return result ? CallQueryInterface(result, aResult) : NS_OK;
-}
-
-NS_IMETHODIMP
-nsGenericElement::GetNextElementSibling(nsIDOMElement** aResult)
-{
-  *aResult = nullptr;
-
-  nsIContent *result = GetNextElementSibling();
-
-  return result ? CallQueryInterface(result, aResult) : NS_OK;
-}
-
-nsContentList*
-nsGenericElement::GetChildrenList()
-{
-  nsGenericElement::nsDOMSlots *slots = DOMSlots();
+  FragmentOrElement::nsDOMSlots *slots = DOMSlots();
 
   if (!slots->mChildrenList) {
     slots->mChildrenList = new nsContentList(this, kNameSpaceID_Wildcard, 
                                              nsGkAtoms::_asterix, nsGkAtoms::_asterix,
                                              false);
   }
 
   return slots->mChildrenList;
 }
 
-nsDOMTokenList*
-nsGenericElement::GetClassList(nsresult *aResult)
-{
-  *aResult = NS_ERROR_OUT_OF_MEMORY;
-
-  nsGenericElement::nsDOMSlots *slots = DOMSlots();
-
-  if (!slots->mClassList) {
-    nsCOMPtr<nsIAtom> classAttr = GetClassAttributeName();
-    if (!classAttr) {
-      *aResult = NS_OK;
-
-      return nullptr;
-    }
-
-    slots->mClassList = new nsDOMTokenList(this, classAttr);
-  }
-
-  *aResult = NS_OK;
-
-  return slots->mClassList;
-}
-
-NS_IMETHODIMP
-nsGenericElement::GetClassList(nsIDOMDOMTokenList** aResult)
-{
-  *aResult = nullptr;
-
-  nsresult rv;
-  nsIDOMDOMTokenList* list = GetClassList(&rv);
-  NS_ENSURE_TRUE(list, rv);
-
-  NS_ADDREF(*aResult = list);
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsGenericElement::SetCapture(bool aRetargetToElement)
-{
-  // If there is already an active capture, ignore this request. This would
-  // occur if a splitter, frame resizer, etc had already captured and we don't
-  // want to override those.
-  if (nsIPresShell::GetCapturingContent())
-    return NS_OK;
-
-  nsIPresShell::SetCapturingContent(this, CAPTURE_PREVENTDRAG |
-    (aRetargetToElement ? CAPTURE_RETARGETTOELEMENT : 0));
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsGenericElement::ReleaseCapture()
-{
-  if (nsIPresShell::GetCapturingContent() == this) {
-    nsIPresShell::SetCapturingContent(nullptr, 0);
-  }
-
-  return NS_OK;
-}
-
-nsIFrame*
-nsGenericElement::GetStyledFrame()
-{
-  nsIFrame *frame = GetPrimaryFrame(Flush_Layout);
-  return frame ? nsLayoutUtils::GetStyleFrame(frame) : nullptr;
-}
-
-void
-nsGenericElement::GetOffsetRect(nsRect& aRect, nsIContent** aOffsetParent)
-{
-  *aOffsetParent = nullptr;
-  aRect = nsRect();
-
-  nsIFrame* frame = GetStyledFrame();
-  if (!frame) {
-    return;
-  }
-
-  nsPoint origin = frame->GetPosition();
-  aRect.x = nsPresContext::AppUnitsToIntCSSPixels(origin.x);
-  aRect.y = nsPresContext::AppUnitsToIntCSSPixels(origin.y);
-
-  // Get the union of all rectangles in this and continuation frames.
-  // It doesn't really matter what we use as aRelativeTo here, since
-  // we only care about the size. Using 'parent' might make things
-  // a bit faster by speeding up the internal GetOffsetTo operations.
-  nsIFrame* parent = frame->GetParent() ? frame->GetParent() : frame;
-  nsRect rcFrame = nsLayoutUtils::GetAllInFlowRectsUnion(frame, parent);
-  aRect.width = nsPresContext::AppUnitsToIntCSSPixels(rcFrame.width);
-  aRect.height = nsPresContext::AppUnitsToIntCSSPixels(rcFrame.height);
-}
-
-nsIntSize
-nsGenericElement::GetPaddingRectSize()
-{
-  nsIFrame* frame = GetStyledFrame();
-  if (!frame) {
-    return nsIntSize(0, 0);
-  }
-
-  NS_ASSERTION(frame->GetParent(), "Styled frame has no parent");
-  nsRect rcFrame = nsLayoutUtils::GetAllInFlowPaddingRectsUnion(frame, frame->GetParent());
-  return nsIntSize(nsPresContext::AppUnitsToIntCSSPixels(rcFrame.width),
-                   nsPresContext::AppUnitsToIntCSSPixels(rcFrame.height));
-}
-
-nsIScrollableFrame*
-nsGenericElement::GetScrollFrame(nsIFrame **aStyledFrame)
-{
-  // it isn't clear what to return for SVG nodes, so just return nothing
-  if (IsSVG()) {
-    if (aStyledFrame) {
-      *aStyledFrame = nullptr;
-    }
-    return nullptr;
-  }
-
-  nsIFrame* frame = GetStyledFrame();
-
-  if (aStyledFrame) {
-    *aStyledFrame = frame;
-  }
-  if (!frame) {
-    return nullptr;
-  }
-
-  // menu frames implement GetScrollTargetFrame but we don't want
-  // to use it here.  Similar for comboboxes.
-  if (frame->GetType() != nsGkAtoms::menuFrame &&
-      frame->GetType() != nsGkAtoms::comboboxControlFrame) {
-    nsIScrollableFrame *scrollFrame = frame->GetScrollTargetFrame();
-    if (scrollFrame)
-      return scrollFrame;
-  }
-
-  nsIDocument* doc = OwnerDoc();
-  bool quirksMode = doc->GetCompatibilityMode() == eCompatibility_NavQuirks;
-  Element* elementWithRootScrollInfo =
-    quirksMode ? doc->GetBodyElement() : doc->GetRootElement();
-  if (this == elementWithRootScrollInfo) {
-    // In quirks mode, the scroll info for the body element should map to the
-    // root scrollable frame.
-    // In strict mode, the scroll info for the root element should map to the
-    // the root scrollable frame.
-    return frame->PresContext()->PresShell()->GetRootScrollFrameAsScrollable();
-  }
-
-  return nullptr;
-}
-
-PRInt32
-nsGenericElement::GetScrollTop()
-{
-  nsIScrollableFrame* sf = GetScrollFrame();
-
-  return sf ?
-         nsPresContext::AppUnitsToIntCSSPixels(sf->GetScrollPosition().y) :
-         0;
-}
-
-NS_IMETHODIMP
-nsGenericElement::GetScrollTop(PRInt32* aScrollTop)
-{
-  *aScrollTop = GetScrollTop();
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsGenericElement::SetScrollTop(PRInt32 aScrollTop)
-{
-  nsIScrollableFrame* sf = GetScrollFrame();
-  if (sf) {
-    nsPoint pt = sf->GetScrollPosition();
-    sf->ScrollToCSSPixels(nsIntPoint(nsPresContext::AppUnitsToIntCSSPixels(pt.x),
-                                     aScrollTop));
-  }
-  return NS_OK;
-}
-
-PRInt32
-nsGenericElement::GetScrollLeft()
-{
-  nsIScrollableFrame* sf = GetScrollFrame();
-
-  return sf ?
-         nsPresContext::AppUnitsToIntCSSPixels(sf->GetScrollPosition().x) :
-         0;
-}
-
-NS_IMETHODIMP
-nsGenericElement::GetScrollLeft(PRInt32* aScrollLeft)
-{
-  *aScrollLeft = GetScrollLeft();
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsGenericElement::SetScrollLeft(PRInt32 aScrollLeft)
-{
-  nsIScrollableFrame* sf = GetScrollFrame();
-  if (sf) {
-    nsPoint pt = sf->GetScrollPosition();
-    sf->ScrollToCSSPixels(nsIntPoint(aScrollLeft,
-                                     nsPresContext::AppUnitsToIntCSSPixels(pt.y)));
-  }
-  return NS_OK;
-}
-
-PRInt32
-nsGenericElement::GetScrollHeight()
-{
-  if (IsSVG())
-    return 0;
-
-  nsIScrollableFrame* sf = GetScrollFrame();
-  if (!sf) {
-    return GetPaddingRectSize().height;
-  }
-
-  nscoord height = sf->GetScrollRange().height + sf->GetScrollPortRect().height;
-  return nsPresContext::AppUnitsToIntCSSPixels(height);
-}
-
-NS_IMETHODIMP
-nsGenericElement::GetScrollHeight(PRInt32* aScrollHeight)
-{
-  *aScrollHeight = GetScrollHeight();
-
-  return NS_OK;
-}
-
-PRInt32
-nsGenericElement::GetScrollWidth()
-{
-  if (IsSVG())
-    return 0;
-
-  nsIScrollableFrame* sf = GetScrollFrame();
-  if (!sf) {
-    return GetPaddingRectSize().width;
-  }
-
-  nscoord width = sf->GetScrollRange().width + sf->GetScrollPortRect().width;
-  return nsPresContext::AppUnitsToIntCSSPixels(width);
-}
-
-NS_IMETHODIMP
-nsGenericElement::GetScrollWidth(PRInt32 *aScrollWidth)
-{
-  *aScrollWidth = GetScrollWidth();
-
-  return NS_OK;
-}
-
-PRInt32
-nsGenericElement::GetScrollLeftMax()
-{
-  nsIScrollableFrame* sf = GetScrollFrame();
-  if (!sf) {
-    return 0;
-  }
-
-  return nsPresContext::AppUnitsToIntCSSPixels(sf->GetScrollRange().XMost());
-}
-
-NS_IMETHODIMP
-nsGenericElement::GetScrollLeftMax(PRInt32 *aScrollLeftMax)
-{
-  *aScrollLeftMax = GetScrollLeftMax();
-
-  return NS_OK;
-}
-
-PRInt32
-nsGenericElement::GetScrollTopMax()
-{
-  nsIScrollableFrame* sf = GetScrollFrame();
-  if (!sf) {
-    return 0;
-  }
-
-  return nsPresContext::AppUnitsToIntCSSPixels(sf->GetScrollRange().YMost());
-}
-
-NS_IMETHODIMP
-nsGenericElement::GetScrollTopMax(PRInt32 *aScrollTopMax)
-{
-  *aScrollTopMax = GetScrollTopMax();
-
-  return NS_OK;
-}
-
-nsRect
-nsGenericElement::GetClientAreaRect()
-{
-  nsIFrame* styledFrame;
-  nsIScrollableFrame* sf = GetScrollFrame(&styledFrame);
-
-  if (sf) {
-    return sf->GetScrollPortRect();
-  }
-
-  if (styledFrame &&
-      (styledFrame->GetStyleDisplay()->mDisplay != NS_STYLE_DISPLAY_INLINE ||
-       styledFrame->IsFrameOfType(nsIFrame::eReplaced))) {
-    // Special case code to make client area work even when there isn't
-    // a scroll view, see bug 180552, bug 227567.
-    return styledFrame->GetPaddingRect() - styledFrame->GetPositionIgnoringScrolling();
-  }
-
-  // SVG nodes reach here and just return 0
-  return nsRect(0, 0, 0, 0);
-}
-
-NS_IMETHODIMP
-nsGenericElement::GetClientTop(PRInt32 *aClientTop)
-{
-  *aClientTop = GetClientTop();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsGenericElement::GetClientLeft(PRInt32 *aClientLeft)
-{
-  *aClientLeft = GetClientLeft();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsGenericElement::GetClientHeight(PRInt32 *aClientHeight)
-{
-  *aClientHeight = GetClientHeight();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsGenericElement::GetClientWidth(PRInt32 *aClientWidth)
-{
-  *aClientWidth = GetClientWidth();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsGenericElement::GetBoundingClientRect(nsIDOMClientRect** aResult)
-{
-  // Weak ref, since we addref it below
-  nsClientRect* rect = new nsClientRect();
-  NS_ADDREF(*aResult = rect);
-  
-  nsIFrame* frame = GetPrimaryFrame(Flush_Layout);
-  if (!frame) {
-    // display:none, perhaps? Return the empty rect
-    return NS_OK;
-  }
-
-  nsRect r = nsLayoutUtils::GetAllInFlowRectsUnion(frame,
-          nsLayoutUtils::GetContainingBlockForClientRect(frame),
-          nsLayoutUtils::RECTS_ACCOUNT_FOR_TRANSFORMS);
-  rect->SetLayoutRect(r);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsGenericElement::GetElementsByClassName(const nsAString& aClasses,
-                                         nsIDOMNodeList** aReturn)
-{
-  return nsContentUtils::GetElementsByClassName(this, aClasses, aReturn);
-}
-
-NS_IMETHODIMP
-nsGenericElement::GetClientRects(nsIDOMClientRectList** aResult)
-{
-  *aResult = nullptr;
-
-  nsRefPtr<nsClientRectList> rectList = new nsClientRectList(this);
-
-  nsIFrame* frame = GetPrimaryFrame(Flush_Layout);
-  if (!frame) {
-    // display:none, perhaps? Return an empty list
-    *aResult = rectList.forget().get();
-    return NS_OK;
-  }
-
-  nsLayoutUtils::RectListBuilder builder(rectList);
-  nsLayoutUtils::GetAllInFlowRects(frame,
-          nsLayoutUtils::GetContainingBlockForClientRect(frame), &builder,
-          nsLayoutUtils::RECTS_ACCOUNT_FOR_TRANSFORMS);
-  if (NS_FAILED(builder.mRV))
-    return builder.mRV;
-  *aResult = rectList.forget().get();
-  return NS_OK;
-}
-
 
 //----------------------------------------------------------------------
 
 
 NS_IMPL_ISUPPORTS1(nsNodeWeakReference,
                    nsIWeakReference)
 
 nsNodeWeakReference::~nsNodeWeakReference()
@@ -1245,25 +528,25 @@ NS_INTERFACE_MAP_END_AGGREGATED(mNode)
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsNodeSelectorTearoff)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsNodeSelectorTearoff)
 
 NS_IMETHODIMP
 nsNodeSelectorTearoff::QuerySelector(const nsAString& aSelector,
                                      nsIDOMElement **aReturn)
 {
   nsresult rv;
-  nsIContent* result = nsGenericElement::doQuerySelector(mNode, aSelector, &rv);
+  nsIContent* result = FragmentOrElement::doQuerySelector(mNode, aSelector, &rv);
   return result ? CallQueryInterface(result, aReturn) : rv;
 }
 
 NS_IMETHODIMP
 nsNodeSelectorTearoff::QuerySelectorAll(const nsAString& aSelector,
                                         nsIDOMNodeList **aReturn)
 {
-  return nsGenericElement::doQuerySelectorAll(mNode, aSelector, aReturn);
+  return FragmentOrElement::doQuerySelectorAll(mNode, aSelector, aReturn);
 }
 
 //----------------------------------------------------------------------
 
 NS_IMPL_CYCLE_COLLECTION_1(nsTouchEventReceiverTearoff, mElement)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsTouchEventReceiverTearoff)
   NS_INTERFACE_MAP_ENTRY(nsITouchEventReceiver)
@@ -1279,36 +562,36 @@ NS_IMPL_CYCLE_COLLECTION_1(nsInlineEvent
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsInlineEventHandlersTearoff)
   NS_INTERFACE_MAP_ENTRY(nsIInlineEventHandlers)
 NS_INTERFACE_MAP_END_AGGREGATED(mElement)
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsInlineEventHandlersTearoff)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsInlineEventHandlersTearoff)
 
 //----------------------------------------------------------------------
-nsGenericElement::nsDOMSlots::nsDOMSlots()
+FragmentOrElement::nsDOMSlots::nsDOMSlots()
   : nsINode::nsSlots(),
     mDataset(nullptr),
     mBindingParent(nullptr)
 {
 }
 
-nsGenericElement::nsDOMSlots::~nsDOMSlots()
+FragmentOrElement::nsDOMSlots::~nsDOMSlots()
 {
   if (mAttributeMap) {
     mAttributeMap->DropReference();
   }
 
   if (mClassList) {
     mClassList->DropReference();
   }
 }
 
 void
-nsGenericElement::nsDOMSlots::Traverse(nsCycleCollectionTraversalCallback &cb, bool aIsXUL)
+FragmentOrElement::nsDOMSlots::Traverse(nsCycleCollectionTraversalCallback &cb, bool aIsXUL)
 {
   NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mStyle");
   cb.NoteXPCOMChild(mStyle.get());
 
   NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mSMILOverrideStyle");
   cb.NoteXPCOMChild(mSMILOverrideStyle.get());
 
   NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mAttributeMap");
@@ -1322,107 +605,99 @@ nsGenericElement::nsDOMSlots::Traverse(n
   NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mChildrenList");
   cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIDOMNodeList*, mChildrenList));
 
   NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mClassList");
   cb.NoteXPCOMChild(mClassList.get());
 }
 
 void
-nsGenericElement::nsDOMSlots::Unlink(bool aIsXUL)
+FragmentOrElement::nsDOMSlots::Unlink(bool aIsXUL)
 {
   mStyle = nullptr;
   mSMILOverrideStyle = nullptr;
   if (mAttributeMap) {
     mAttributeMap->DropReference();
     mAttributeMap = nullptr;
   }
   if (aIsXUL)
     NS_IF_RELEASE(mControllers);
   mChildrenList = nullptr;
   if (mClassList) {
     mClassList->DropReference();
     mClassList = nullptr;
   }
 }
 
-nsGenericElement::nsGenericElement(already_AddRefed<nsINodeInfo> aNodeInfo)
-  : Element(aNodeInfo)
+FragmentOrElement::FragmentOrElement(already_AddRefed<nsINodeInfo> aNodeInfo)
+  : nsIContent(aNodeInfo)
 {
-  NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::ELEMENT_NODE ||
-                    (mNodeInfo->NodeType() ==
-                       nsIDOMNode::DOCUMENT_FRAGMENT_NODE &&
-                     mNodeInfo->Equals(nsGkAtoms::documentFragmentNodeName,
-                                       kNameSpaceID_None)),
-                    "Bad NodeType in aNodeInfo");
-
-  SetIsElement();
 }
 
-nsGenericElement::~nsGenericElement()
+FragmentOrElement::~FragmentOrElement()
 {
   NS_PRECONDITION(!IsInDoc(),
                   "Please remove this from the document properly");
   if (GetParent()) {
     NS_RELEASE(mParent);
   }
 }
 
 NS_IMETHODIMP
-nsGenericElement::GetNodeName(nsAString& aNodeName)
+FragmentOrElement::GetNodeName(nsAString& aNodeName)
 {
   aNodeName = NodeName();
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsGenericElement::GetLocalName(nsAString& aLocalName)
+FragmentOrElement::GetLocalName(nsAString& aLocalName)
 {
   aLocalName = LocalName();
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsGenericElement::GetNodeValue(nsAString& aNodeValue)
+FragmentOrElement::GetNodeValue(nsAString& aNodeValue)
 {
   SetDOMStringToNull(aNodeValue);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsGenericElement::SetNodeValue(const nsAString& aNodeValue)
+FragmentOrElement::SetNodeValue(const nsAString& aNodeValue)
 {
   // The DOM spec says that when nodeValue is defined to be null "setting it
   // has no effect", so we don't throw an exception.
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsGenericElement::GetNodeType(PRUint16* aNodeType)
+FragmentOrElement::GetNodeType(PRUint16* aNodeType)
 {
   *aNodeType = NodeType();
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsGenericElement::GetNamespaceURI(nsAString& aNamespaceURI)
+FragmentOrElement::GetNamespaceURI(nsAString& aNamespaceURI)
 {
   return mNodeInfo->GetNamespaceURI(aNamespaceURI);
 }
 
 NS_IMETHODIMP
-nsGenericElement::GetPrefix(nsAString& aPrefix)
+FragmentOrElement::GetPrefix(nsAString& aPrefix)
 {
   mNodeInfo->GetPrefix(aPrefix);
   return NS_OK;
 }
 
 nsresult
-nsGenericElement::InternalIsSupported(nsISupports* aObject,
+FragmentOrElement::InternalIsSupported(nsISupports* aObject,
                                       const nsAString& aFeature,
                                       const nsAString& aVersion,
                                       bool* aReturn)
 {
   NS_ENSURE_ARG_POINTER(aReturn);
   *aReturn = false;
 
   // Convert the incoming UTF16 strings to raw char*'s to save us some
@@ -1476,763 +751,62 @@ nsGenericElement::InternalIsSupported(ns
       *aReturn = true;
     }
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsGenericElement::IsSupported(const nsAString& aFeature,
-                              const nsAString& aVersion,
-                              bool* aReturn)
+FragmentOrElement::IsSupported(const nsAString& aFeature,
+                               const nsAString& aVersion,
+                               bool* aReturn)
 {
   return InternalIsSupported(this, aFeature, aVersion, aReturn);
 }
 
 NS_IMETHODIMP
-nsGenericElement::HasAttributes(bool* aReturn)
+FragmentOrElement::HasAttributes(bool* aReturn)
 {
   NS_ENSURE_ARG_POINTER(aReturn);
 
   *aReturn = GetAttrCount() > 0;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsGenericElement::GetAttributes(nsIDOMNamedNodeMap** aAttributes)
+FragmentOrElement::GetAttributes(nsIDOMNamedNodeMap** aAttributes)
 {
   if (!IsElement()) {
     *aAttributes = nullptr;
     return NS_OK;
   }
 
   nsDOMSlots *slots = DOMSlots();
 
   if (!slots->mAttributeMap) {
-    slots->mAttributeMap = new nsDOMAttributeMap(this);
+    slots->mAttributeMap = new nsDOMAttributeMap(this->AsElement());
   }
 
   NS_ADDREF(*aAttributes = slots->mAttributeMap);
 
   return NS_OK;
 }
 
 nsresult
-nsGenericElement::HasChildNodes(bool* aReturn)
+FragmentOrElement::HasChildNodes(bool* aReturn)
 {
   *aReturn = mAttrsAndChildren.ChildCount() > 0;
 
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsGenericElement::GetTagName(nsAString& aTagName)
-{
-  aTagName = NodeName();
-  return NS_OK;
-}
-
-nsresult
-nsGenericElement::GetAttribute(const nsAString& aName,
-                               nsAString& aReturn)
-{
-  const nsAttrValue* val =
-    mAttrsAndChildren.GetAttr(aName,
-                              IsHTML() && IsInHTMLDocument() ?
-                                eIgnoreCase : eCaseMatters);
-  if (val) {
-    val->ToString(aReturn);
-  } else {
-    if (IsXUL()) {
-      // XXX should be SetDOMStringToNull(aReturn);
-      // See bug 232598
-      aReturn.Truncate();
-    } else {
-      SetDOMStringToNull(aReturn);
-    }
-  }
-
-  return NS_OK;
-}
-
-nsresult
-nsGenericElement::SetAttribute(const nsAString& aName,
-                               const nsAString& aValue)
-{
-  const nsAttrName* name = InternalGetExistingAttrNameFromQName(aName);
-
-  if (!name) {
-    nsresult rv = nsContentUtils::CheckQName(aName, false);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    nsCOMPtr<nsIAtom> nameAtom = do_GetAtom(aName);
-    NS_ENSURE_TRUE(nameAtom, NS_ERROR_OUT_OF_MEMORY);
-
-    return SetAttr(kNameSpaceID_None, nameAtom, aValue, true);
-  }
-
-  return SetAttr(name->NamespaceID(), name->LocalName(), name->GetPrefix(),
-                 aValue, true);
-}
-
-nsresult
-nsGenericElement::RemoveAttribute(const nsAString& aName)
-{
-  const nsAttrName* name = InternalGetExistingAttrNameFromQName(aName);
-
-  if (!name) {
-    // If there is no canonical nsAttrName for this attribute name, then the
-    // attribute does not exist and we can't get its namespace ID and
-    // local name below, so we return early.
-    return NS_OK;
-  }
-
-  // Hold a strong reference here so that the atom or nodeinfo doesn't go
-  // away during UnsetAttr. If it did UnsetAttr would be left with a
-  // dangling pointer as argument without knowing it.
-  nsAttrName tmp(*name);
-
-  return UnsetAttr(name->NamespaceID(), name->LocalName(), true);
-}
-
-nsresult
-nsGenericElement::GetAttributeNode(const nsAString& aName,
-                                   nsIDOMAttr** aReturn)
-{
-  NS_ENSURE_ARG_POINTER(aReturn);
-  *aReturn = nullptr;
-
-  nsIDocument* document = OwnerDoc();
-  if (document) {
-    document->WarnOnceAbout(nsIDocument::eGetAttributeNode);
-  }
-
-  nsCOMPtr<nsIDOMNamedNodeMap> map;
-  nsresult rv = GetAttributes(getter_AddRefs(map));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr<nsIDOMNode> node;
-  rv = map->GetNamedItem(aName, getter_AddRefs(node));
-
-  if (NS_SUCCEEDED(rv) && node) {
-    rv = CallQueryInterface(node, aReturn);
-  }
-
-  return rv;
-}
-
-nsresult
-nsGenericElement::SetAttributeNode(nsIDOMAttr* aAttribute,
-                                   nsIDOMAttr** aReturn)
-{
-  NS_ENSURE_ARG_POINTER(aReturn);
-  NS_ENSURE_ARG_POINTER(aAttribute);
-
-  *aReturn = nullptr;
-
-  OwnerDoc()->WarnOnceAbout(nsIDocument::eSetAttributeNode);
-
-  nsCOMPtr<nsIDOMNamedNodeMap> map;
-  nsresult rv = GetAttributes(getter_AddRefs(map));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr<nsIDOMNode> returnNode;
-  rv = map->SetNamedItem(aAttribute, getter_AddRefs(returnNode));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (returnNode) {
-    rv = CallQueryInterface(returnNode, aReturn);
-  }
-
-  return rv;
-}
-
-nsresult
-nsGenericElement::RemoveAttributeNode(nsIDOMAttr* aAttribute,
-                                      nsIDOMAttr** aReturn)
-{
-  NS_ENSURE_ARG_POINTER(aReturn);
-  NS_ENSURE_ARG_POINTER(aAttribute);
-
-  *aReturn = nullptr;
-
-  OwnerDoc()->WarnOnceAbout(nsIDocument::eRemoveAttributeNode);
-
-  nsCOMPtr<nsIDOMNamedNodeMap> map;
-  nsresult rv = GetAttributes(getter_AddRefs(map));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsAutoString name;
-
-  rv = aAttribute->GetName(name);
-  if (NS_SUCCEEDED(rv)) {
-    nsCOMPtr<nsIDOMNode> node;
-    rv = map->RemoveNamedItem(name, getter_AddRefs(node));
-
-    if (NS_SUCCEEDED(rv) && node) {
-      rv = CallQueryInterface(node, aReturn);
-    }
-  }
-
-  return rv;
-}
-
-nsresult
-nsGenericElement::GetElementsByTagName(const nsAString& aTagname,
-                                       nsIDOMNodeList** aReturn)
-{
-  nsContentList *list = NS_GetContentList(this, kNameSpaceID_Unknown, 
-                                          aTagname).get();
-
-  // transfer ref to aReturn
-  *aReturn = list;
-  return NS_OK;
-}
-
-nsresult
-nsGenericElement::GetAttributeNS(const nsAString& aNamespaceURI,
-                                 const nsAString& aLocalName,
-                                 nsAString& aReturn)
-{
-  PRInt32 nsid =
-    nsContentUtils::NameSpaceManager()->GetNameSpaceID(aNamespaceURI);
-
-  if (nsid == kNameSpaceID_Unknown) {
-    // Unknown namespace means no attribute.
-    SetDOMStringToNull(aReturn);
-    return NS_OK;
-  }
-
-  nsCOMPtr<nsIAtom> name = do_GetAtom(aLocalName);
-  bool hasAttr = GetAttr(nsid, name, aReturn);
-  if (!hasAttr) {
-    SetDOMStringToNull(aReturn);
-  }
-
-  return NS_OK;
-}
-
-nsresult
-nsGenericElement::SetAttributeNS(const nsAString& aNamespaceURI,
-                                 const nsAString& aQualifiedName,
-                                 const nsAString& aValue)
-{
-  nsCOMPtr<nsINodeInfo> ni;
-  nsresult rv =
-    nsContentUtils::GetNodeInfoFromQName(aNamespaceURI, aQualifiedName,
-                                         mNodeInfo->NodeInfoManager(),
-                                         nsIDOMNode::ATTRIBUTE_NODE,
-                                         getter_AddRefs(ni));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  return SetAttr(ni->NamespaceID(), ni->NameAtom(), ni->GetPrefixAtom(),
-                 aValue, true);
-}
-
-nsresult
-nsGenericElement::RemoveAttributeNS(const nsAString& aNamespaceURI,
-                                    const nsAString& aLocalName)
-{
-  nsCOMPtr<nsIAtom> name = do_GetAtom(aLocalName);
-  PRInt32 nsid =
-    nsContentUtils::NameSpaceManager()->GetNameSpaceID(aNamespaceURI);
-
-  if (nsid == kNameSpaceID_Unknown) {
-    // If the namespace ID is unknown, it means there can't possibly be an
-    // existing attribute. We would need a known namespace ID to pass into
-    // UnsetAttr, so we return early if we don't have one.
-    return NS_OK;
-  }
-
-  UnsetAttr(nsid, name, true);
-
-  return NS_OK;
-}
-
-nsresult
-nsGenericElement::GetAttributeNodeNS(const nsAString& aNamespaceURI,
-                                     const nsAString& aLocalName,
-                                     nsIDOMAttr** aReturn)
-{
-  NS_ENSURE_ARG_POINTER(aReturn);
-  *aReturn = nullptr;
-
-  OwnerDoc()->WarnOnceAbout(nsIDocument::eGetAttributeNodeNS);
-
-  return GetAttributeNodeNSInternal(aNamespaceURI, aLocalName, aReturn);
-}
-
-nsresult
-nsGenericElement::GetAttributeNodeNSInternal(const nsAString& aNamespaceURI,
-                                             const nsAString& aLocalName,
-                                             nsIDOMAttr** aReturn)
-{
-  nsCOMPtr<nsIDOMNamedNodeMap> map;
-  nsresult rv = GetAttributes(getter_AddRefs(map));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr<nsIDOMNode> node;
-  rv = map->GetNamedItemNS(aNamespaceURI, aLocalName, getter_AddRefs(node));
-
-  if (NS_SUCCEEDED(rv) && node) {
-    rv = CallQueryInterface(node, aReturn);
-  }
-
-  return rv;
-}
-
-nsresult
-nsGenericElement::SetAttributeNodeNS(nsIDOMAttr* aNewAttr,
-                                     nsIDOMAttr** aReturn)
-{
-  NS_ENSURE_ARG_POINTER(aReturn);
-  NS_ENSURE_ARG_POINTER(aNewAttr);
-  *aReturn = nullptr;
-
-  OwnerDoc()->WarnOnceAbout(nsIDocument::eSetAttributeNodeNS);
-
-  nsCOMPtr<nsIDOMNamedNodeMap> map;
-  nsresult rv = GetAttributes(getter_AddRefs(map));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr<nsIDOMNode> returnNode;
-  rv = map->SetNamedItemNS(aNewAttr, getter_AddRefs(returnNode));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (returnNode) {
-    rv = CallQueryInterface(returnNode, aReturn);
-  }
-
-  return rv;
-}
-
-nsresult
-nsGenericElement::GetElementsByTagNameNS(const nsAString& aNamespaceURI,
-                                         const nsAString& aLocalName,
-                                         nsIDOMNodeList** aReturn)
-{
-  PRInt32 nameSpaceId = kNameSpaceID_Wildcard;
-
-  if (!aNamespaceURI.EqualsLiteral("*")) {
-    nsresult rv =
-      nsContentUtils::NameSpaceManager()->RegisterNameSpace(aNamespaceURI,
-                                                            nameSpaceId);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  NS_ASSERTION(nameSpaceId != kNameSpaceID_Unknown, "Unexpected namespace ID!");
-
-  nsContentList *list = NS_GetContentList(this, nameSpaceId, aLocalName).get();
-
-  // transfer ref to aReturn
-  *aReturn = list;
-  return NS_OK;
-}
-
-nsresult
-nsGenericElement::HasAttribute(const nsAString& aName, bool* aReturn)
-{
-  NS_ENSURE_ARG_POINTER(aReturn);
-
-  const nsAttrName* name = InternalGetExistingAttrNameFromQName(aName);
-  *aReturn = (name != nullptr);
-
-  return NS_OK;
-}
-
-nsresult
-nsGenericElement::HasAttributeNS(const nsAString& aNamespaceURI,
-                                 const nsAString& aLocalName,
-                                 bool* aReturn)
-{
-  NS_ENSURE_ARG_POINTER(aReturn);
-
-  PRInt32 nsid =
-    nsContentUtils::NameSpaceManager()->GetNameSpaceID(aNamespaceURI);
-
-  if (nsid == kNameSpaceID_Unknown) {
-    // Unknown namespace means no attr...
-
-    *aReturn = false;
-
-    return NS_OK;
-  }
-
-  nsCOMPtr<nsIAtom> name = do_GetAtom(aLocalName);
-  *aReturn = HasAttr(nsid, name);
-
-  return NS_OK;
-}
-
-static nsXBLBinding*
-GetFirstBindingWithContent(nsBindingManager* aBmgr, nsIContent* aBoundElem)
-{
-  nsXBLBinding* binding = aBmgr->GetBinding(aBoundElem);
-  while (binding) {
-    if (binding->GetAnonymousContent()) {
-      return binding;
-    }
-    binding = binding->GetBaseBinding();
-  }
-  
-  return nullptr;
-}
-
-static nsresult
-BindNodesInInsertPoints(nsXBLBinding* aBinding, nsIContent* aInsertParent,
-                        nsIDocument* aDocument)
-{
-  NS_PRECONDITION(aBinding && aInsertParent, "Missing arguments");
-
-  nsresult rv;
-  // These should be refcounted or otherwise protectable.
-  nsInsertionPointList* inserts =
-    aBinding->GetExistingInsertionPointsFor(aInsertParent);
-  if (inserts) {
-    bool allowScripts = aBinding->AllowScripts();
-#ifdef MOZ_XUL
-    nsCOMPtr<nsIXULDocument> xulDoc = do_QueryInterface(aDocument);
-#endif
-    PRUint32 i;
-    for (i = 0; i < inserts->Length(); ++i) {
-      nsCOMPtr<nsIContent> insertRoot =
-        inserts->ElementAt(i)->GetDefaultContent();
-      if (insertRoot) {
-        for (nsCOMPtr<nsIContent> child = insertRoot->GetFirstChild();
-             child;
-             child = child->GetNextSibling()) {
-          rv = child->BindToTree(aDocument, aInsertParent,
-                                 aBinding->GetBoundElement(), allowScripts);
-          NS_ENSURE_SUCCESS(rv, rv);
-
-#ifdef MOZ_XUL
-          if (xulDoc) {
-            xulDoc->AddSubtreeToDocument(child);
-          }
-#endif
-        }
-      }
-    }
-  }
-
-  return NS_OK;
-}
-
-nsresult
-nsGenericElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
-                             nsIContent* aBindingParent,
-                             bool aCompileEventHandlers)
-{
-  NS_PRECONDITION(aParent || aDocument, "Must have document if no parent!");
-  NS_PRECONDITION(HasSameOwnerDoc(NODE_FROM(aParent, aDocument)),
-                  "Must have the same owner document");
-  NS_PRECONDITION(!aParent || aDocument == aParent->GetCurrentDoc(),
-                  "aDocument must be current doc of aParent");
-  NS_PRECONDITION(!GetCurrentDoc(), "Already have a document.  Unbind first!");
-  // Note that as we recurse into the kids, they'll have a non-null parent.  So
-  // only assert if our parent is _changing_ while we have a parent.
-  NS_PRECONDITION(!GetParent() || aParent == GetParent(),
-                  "Already have a parent.  Unbind first!");
-  NS_PRECONDITION(!GetBindingParent() ||
-                  aBindingParent == GetBindingParent() ||
-                  (!aBindingParent && aParent &&
-                   aParent->GetBindingParent() == GetBindingParent()),
-                  "Already have a binding parent.  Unbind first!");
-  NS_PRECONDITION(!aParent || !aDocument ||
-                  !aParent->HasFlag(NODE_FORCE_XBL_BINDINGS),
-                  "Parent in document but flagged as forcing XBL");
-  NS_PRECONDITION(aBindingParent != this,
-                  "Content must not be its own binding parent");
-  NS_PRECONDITION(!IsRootOfNativeAnonymousSubtree() ||
-                  aBindingParent == aParent,
-                  "Native anonymous content must have its parent as its "
-                  "own binding parent");
-  NS_PRECONDITION(aBindingParent || !aParent ||
-                  aBindingParent == aParent->GetBindingParent(),
-                  "We should be passed the right binding parent");
-
-#ifdef MOZ_XUL
-  // First set the binding parent
-  nsXULElement* xulElem = nsXULElement::FromContent(this);
-  if (xulElem) {
-    xulElem->SetXULBindingParent(aBindingParent);
-  }
-  else 
-#endif
-  {
-    if (aBindingParent) {
-      nsDOMSlots *slots = DOMSlots();
-
-      slots->mBindingParent = aBindingParent; // Weak, so no addref happens.
-    }
-  }
-  NS_ASSERTION(!aBindingParent || IsRootOfNativeAnonymousSubtree() ||
-               !HasFlag(NODE_IS_IN_ANONYMOUS_SUBTREE) ||
-               (aParent && aParent->IsInNativeAnonymousSubtree()),
-               "Trying to re-bind content from native anonymous subtree to "
-               "non-native anonymous parent!");
-  if (aParent && aParent->IsInNativeAnonymousSubtree()) {
-    SetFlags(NODE_IS_IN_ANONYMOUS_SUBTREE);
-  }
-
-  bool hadForceXBL = HasFlag(NODE_FORCE_XBL_BINDINGS);
-
-  // Now set the parent and set the "Force attach xbl" flag if needed.
-  if (aParent) {
-    if (!GetParent()) {
-      NS_ADDREF(aParent);
-    }
-    mParent = aParent;
-
-    if (aParent->HasFlag(NODE_FORCE_XBL_BINDINGS)) {
-      SetFlags(NODE_FORCE_XBL_BINDINGS);
-    }
-  }
-  else {
-    mParent = aDocument;
-  }
-  SetParentIsContent(aParent);
-
-  // XXXbz sXBL/XBL2 issue!
-
-  // Finally, set the document
-  if (aDocument) {
-    // Notify XBL- & nsIAnonymousContentCreator-generated
-    // anonymous content that the document is changing.
-    // XXXbz ordering issues here?  Probably not, since ChangeDocumentFor is
-    // just pretty broken anyway....  Need to get it working.
-    // XXXbz XBL doesn't handle this (asserts), and we don't really want
-    // to be doing this during parsing anyway... sort this out.    
-    //    aDocument->BindingManager()->ChangeDocumentFor(this, nullptr,
-    //                                                   aDocument);
-
-    // We no longer need to track the subtree pointer (and in fact we'll assert
-    // if we do this any later).
-    ClearSubtreeRootPointer();
-
-    // Being added to a document.
-    SetInDocument();
-
-    // Unset this flag since we now really are in a document.
-    UnsetFlags(NODE_FORCE_XBL_BINDINGS |
-               // And clear the lazy frame construction bits.
-               NODE_NEEDS_FRAME | NODE_DESCENDANTS_NEED_FRAMES |
-               // And the restyle bits
-               ELEMENT_ALL_RESTYLE_FLAGS);
-  } else {
-    // If we're not in the doc, update our subtree pointer.
-    SetSubtreeRootPointer(aParent->SubtreeRoot());
-  }
-
-  // If NODE_FORCE_XBL_BINDINGS was set we might have anonymous children
-  // that also need to be told that they are moving.
-  nsresult rv;
-  if (hadForceXBL) {
-    nsBindingManager* bmgr = OwnerDoc()->BindingManager();
-
-    // First check if we have a binding...
-    nsXBLBinding* contBinding =
-      GetFirstBindingWithContent(bmgr, this);
-    if (contBinding) {
-      nsCOMPtr<nsIContent> anonRoot = contBinding->GetAnonymousContent();
-      bool allowScripts = contBinding->AllowScripts();
-      for (nsCOMPtr<nsIContent> child = anonRoot->GetFirstChild();
-           child;
-           child = child->GetNextSibling()) {
-        rv = child->BindToTree(aDocument, this, this, allowScripts);
-        NS_ENSURE_SUCCESS(rv, rv);
-      }
-
-      // ...then check if we have content in insertion points that are
-      // direct children of the <content>
-      rv = BindNodesInInsertPoints(contBinding, this, aDocument);
-      NS_ENSURE_SUCCESS(rv, rv);
-    }
-
-    // ...and finally check if we're in a binding where we have content in
-    // insertion points.
-    if (aBindingParent) {
-      nsXBLBinding* binding = bmgr->GetBinding(aBindingParent);
-      if (binding) {
-        rv = BindNodesInInsertPoints(binding, this, aDocument);
-        NS_ENSURE_SUCCESS(rv, rv);
-      }
-    }
-  }
-
-  UpdateEditableState(false);
-
-  // Now recurse into our kids
-  for (nsIContent* child = GetFirstChild(); child;
-       child = child->GetNextSibling()) {
-    rv = child->BindToTree(aDocument, this, aBindingParent,
-                           aCompileEventHandlers);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  nsNodeUtils::ParentChainChanged(this);
-
-  if (aDocument && HasID() && !aBindingParent) {
-    aDocument->AddToIdTable(this, DoGetID());
-  }
-
-  if (MayHaveStyle() && !IsXUL()) {
-    // XXXbz if we already have a style attr parsed, this won't do
-    // anything... need to fix that.
-    // If MayHaveStyle() is true, we must be an nsStyledElement
-    static_cast<nsStyledElement*>(this)->ReparseStyleAttribute(false);
-  }
-
-  if (aDocument) {
-    // If we're in a document now, let our mapped attrs know what their new
-    // sheet is.  This is safe to run for non-mapped-attribute elements too;
-    // it'll just do a small bit of unnecessary work.  But most elements in
-    // practice are mapped-attribute elements.
-    nsHTMLStyleSheet* sheet = aDocument->GetAttributeStyleSheet();
-    if (sheet) {
-      mAttrsAndChildren.SetMappedAttrStyleSheet(sheet);
-    }
-  }
-
-  // XXXbz script execution during binding can trigger some of these
-  // postcondition asserts....  But we do want that, since things will
-  // generally be quite broken when that happens.
-  NS_POSTCONDITION(aDocument == GetCurrentDoc(), "Bound to wrong document");
-  NS_POSTCONDITION(aParent == GetParent(), "Bound to wrong parent");
-  NS_POSTCONDITION(aBindingParent == GetBindingParent(),
-                   "Bound to wrong binding parent");
-
-  return NS_OK;
-}
-
-class RemoveFromBindingManagerRunnable : public nsRunnable {
-public:
-  RemoveFromBindingManagerRunnable(nsBindingManager* aManager,
-                                   Element* aElement,
-                                   nsIDocument* aDoc,
-                                   nsIContent* aBindingParent):
-    mManager(aManager), mElement(aElement), mDoc(aDoc),
-    mBindingParent(aBindingParent)
-  {}
-
-  NS_IMETHOD Run()
-  {
-    mManager->RemovedFromDocumentInternal(mElement, mDoc, mBindingParent);
-    return NS_OK;
-  }
-
-private:
-  nsRefPtr<nsBindingManager> mManager;
-  nsRefPtr<Element> mElement;
-  nsCOMPtr<nsIDocument> mDoc;
-  nsCOMPtr<nsIContent> mBindingParent;
-};
-
-void
-nsGenericElement::UnbindFromTree(bool aDeep, bool aNullParent)
-{
-  NS_PRECONDITION(aDeep || (!GetCurrentDoc() && !GetBindingParent()),
-                  "Shallow unbind won't clear document and binding parent on "
-                  "kids!");
-
-  RemoveFromIdTable();
-
-  // Make sure to unbind this node before doing the kids
-  nsIDocument *document =
-    HasFlag(NODE_FORCE_XBL_BINDINGS) ? OwnerDoc() : GetCurrentDoc();
-
-  if (aNullParent) {
-    if (IsFullScreenAncestor()) {
-      // The element being removed is an ancestor of the full-screen element,
-      // exit full-screen state.
-      nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
-                                      "DOM", OwnerDoc(),
-                                      nsContentUtils::eDOM_PROPERTIES,
-                                      "RemovedFullScreenElement");
-      // Fully exit full-screen.
-      nsIDocument::ExitFullScreen(false);
-    }
-    if (HasPointerLock()) {
-      nsIDocument::UnlockPointer();
-    }
-    if (GetParent()) {
-      NS_RELEASE(mParent);
-    } else {
-      mParent = nullptr;
-    }
-    SetParentIsContent(false);
-  }
-  ClearInDocument();
-
-  // Begin keeping track of our subtree root.
-  SetSubtreeRootPointer(aNullParent ? this : mParent->SubtreeRoot());
-
-  if (document) {
-    // Notify XBL- & nsIAnonymousContentCreator-generated
-    // anonymous content that the document is changing.
-    if (HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
-      nsContentUtils::AddScriptRunner(
-        new RemoveFromBindingManagerRunnable(document->BindingManager(), this,
-                                             document, GetBindingParent()));
-    }
-
-    document->ClearBoxObjectFor(this);
-  }
-
-  // Ensure that CSS transitions don't continue on an element at a
-  // different place in the tree (even if reinserted before next
-  // animation refresh).
-  // FIXME (Bug 522599): Need a test for this.
-  if (HasFlag(NODE_HAS_PROPERTIES)) {
-    DeleteProperty(nsGkAtoms::transitionsOfBeforeProperty);
-    DeleteProperty(nsGkAtoms::transitionsOfAfterProperty);
-    DeleteProperty(nsGkAtoms::transitionsProperty);
-    DeleteProperty(nsGkAtoms::animationsOfBeforeProperty);
-    DeleteProperty(nsGkAtoms::animationsOfAfterProperty);
-    DeleteProperty(nsGkAtoms::animationsProperty);
-  }
-
-  // Unset this since that's what the old code effectively did.
-  UnsetFlags(NODE_FORCE_XBL_BINDINGS);
-  
-#ifdef MOZ_XUL
-  nsXULElement* xulElem = nsXULElement::FromContent(this);
-  if (xulElem) {
-    xulElem->SetXULBindingParent(nullptr);
-  }
-  else
-#endif
-  {
-    nsDOMSlots *slots = GetExistingDOMSlots();
-    if (slots) {
-      slots->mBindingParent = nullptr;
-    }
-  }
-
-  if (aDeep) {
-    // Do the kids. Don't call GetChildCount() here since that'll force
-    // XUL to generate template children, which there is no need for since
-    // all we're going to do is unbind them anyway.
-    PRUint32 i, n = mAttrsAndChildren.ChildCount();
-
-    for (i = 0; i < n; ++i) {
-      // Note that we pass false for aNullParent here, since we don't want
-      // the kids to forget us.  We _do_ want them to forget their binding
-      // parent, though, since this only walks non-anonymous kids.
-      mAttrsAndChildren.ChildAt(i)->UnbindFromTree(true, false);
-    }
-  }
-
-  nsNodeUtils::ParentChainChanged(this);
-}
-
 already_AddRefed<nsINodeList>
-nsGenericElement::GetChildren(PRUint32 aFilter)
+FragmentOrElement::GetChildren(PRUint32 aFilter)
 {
   nsRefPtr<nsSimpleContentList> list = new nsSimpleContentList(this);
   if (!list) {
     return nullptr;
   }
 
   nsIFrame *frame = GetPrimaryFrame();
 
@@ -2420,312 +994,82 @@ nsIContent::PreHandleEvent(nsEventChainP
     aVisitor.mParentTarget = parent;
   } else {
     aVisitor.mParentTarget = GetCurrentDoc();
   }
   return NS_OK;
 }
 
 const nsAttrValue*
-nsGenericElement::DoGetClasses() const
+FragmentOrElement::DoGetClasses() const
 {
   NS_NOTREACHED("Shouldn't ever be called");
   return nullptr;
 }
 
 NS_IMETHODIMP
-nsGenericElement::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
-{
-  return NS_OK;
-}
-
-nsICSSDeclaration*
-nsGenericElement::GetSMILOverrideStyle()
-{
-  nsGenericElement::nsDOMSlots *slots = DOMSlots();
-
-  if (!slots->mSMILOverrideStyle) {
-    slots->mSMILOverrideStyle = new nsDOMCSSAttributeDeclaration(this, true);
-  }
-
-  return slots->mSMILOverrideStyle;
-}
-
-css::StyleRule*
-nsGenericElement::GetSMILOverrideStyleRule()
+FragmentOrElement::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
 {
-  nsGenericElement::nsDOMSlots *slots = GetExistingDOMSlots();
-  return slots ? slots->mSMILOverrideStyleRule.get() : nullptr;
-}
-
-nsresult
-nsGenericElement::SetSMILOverrideStyleRule(css::StyleRule* aStyleRule,
-                                           bool aNotify)
-{
-  nsGenericElement::nsDOMSlots *slots = DOMSlots();
-
-  slots->mSMILOverrideStyleRule = aStyleRule;
-
-  if (aNotify) {
-    nsIDocument* doc = GetCurrentDoc();
-    // Only need to request a restyle if we're in a document.  (We might not
-    // be in a document, if we're clearing animation effects on a target node
-    // that's been detached since the previous animation sample.)
-    if (doc) {
-      nsCOMPtr<nsIPresShell> shell = doc->GetShell();
-      if (shell) {
-        shell->RestyleForAnimation(this, eRestyle_Self);
-      }
-    }
-  }
-
   return NS_OK;
 }
 
 bool
-nsGenericElement::IsLabelable() const
-{
-  return false;
-}
-
-css::StyleRule*
-nsGenericElement::GetInlineStyleRule()
-{
-  return nullptr;
-}
-
-nsresult
-nsGenericElement::SetInlineStyleRule(css::StyleRule* aStyleRule,
-                                     const nsAString* aSerialized,
-                                     bool aNotify)
-{
-  NS_NOTYETIMPLEMENTED("nsGenericElement::SetInlineStyleRule");
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP_(bool)
-nsGenericElement::IsAttributeMapped(const nsIAtom* aAttribute) const
-{
-  return false;
-}
-
-nsChangeHint
-nsGenericElement::GetAttributeChangeHint(const nsIAtom* aAttribute,
-                                         PRInt32 aModType) const
-{
-  return nsChangeHint(0);
-}
-
-nsIAtom *
-nsGenericElement::GetClassAttributeName() const
-{
-  return nullptr;
-}
-
-bool
-nsGenericElement::FindAttributeDependence(const nsIAtom* aAttribute,
-                                          const MappedAttributeEntry* const aMaps[],
-                                          PRUint32 aMapCount)
-{
-  for (PRUint32 mapindex = 0; mapindex < aMapCount; ++mapindex) {
-    for (const MappedAttributeEntry* map = aMaps[mapindex];
-         map->attribute; ++map) {
-      if (aAttribute == *map->attribute) {
-        return true;
-      }
-    }
-  }
-
-  return false;
-}
-
-already_AddRefed<nsINodeInfo>
-nsGenericElement::GetExistingAttrNameFromQName(const nsAString& aStr) const
-{
-  const nsAttrName* name = InternalGetExistingAttrNameFromQName(aStr);
-  if (!name) {
-    return nullptr;
-  }
-
-  nsINodeInfo* nodeInfo;
-  if (name->IsAtom()) {
-    nodeInfo = mNodeInfo->NodeInfoManager()->
-      GetNodeInfo(name->Atom(), nullptr, kNameSpaceID_None,
-                  nsIDOMNode::ATTRIBUTE_NODE).get();
-  }
-  else {
-    NS_ADDREF(nodeInfo = name->NodeInfo());
-  }
-
-  return nodeInfo;
-}
-
-bool
-nsGenericElement::IsLink(nsIURI** aURI) const
+FragmentOrElement::IsLink(nsIURI** aURI) const
 {
   *aURI = nullptr;
   return false;
 }
 
-// static
-bool
-nsGenericElement::ShouldBlur(nsIContent *aContent)
-{
-  // Determine if the current element is focused, if it is not focused
-  // then we should not try to blur
-  nsIDocument *document = aContent->GetDocument();
-  if (!document)
-    return false;
-
-  nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(document->GetWindow());
-  if (!window)
-    return false;
-
-  nsCOMPtr<nsPIDOMWindow> focusedFrame;
-  nsIContent* contentToBlur =
-    nsFocusManager::GetFocusedDescendant(window, false, getter_AddRefs(focusedFrame));
-  if (contentToBlur == aContent)
-    return true;
-
-  // if focus on this element would get redirected, then check the redirected
-  // content as well when blurring.
-  return (contentToBlur && nsFocusManager::GetRedirectedFocus(aContent) == contentToBlur);
-}
-
 nsIContent*
-nsGenericElement::GetBindingParent() const
+FragmentOrElement::GetBindingParent() const
 {
   nsDOMSlots *slots = GetExistingDOMSlots();
 
   if (slots) {
     return slots->mBindingParent;
   }
   return nullptr;
 }
 
-bool
-nsGenericElement::IsNodeOfType(PRUint32 aFlags) const
-{
-  return !(aFlags & ~eCONTENT);
-}
-
 nsresult
-nsGenericElement::InsertChildAt(nsIContent* aKid,
+FragmentOrElement::InsertChildAt(nsIContent* aKid,
                                 PRUint32 aIndex,
                                 bool aNotify)
 {
   NS_PRECONDITION(aKid, "null ptr");
 
   return doInsertChildAt(aKid, aIndex, aNotify, mAttrsAndChildren);
 }
 
 void
-nsGenericElement::RemoveChildAt(PRUint32 aIndex, bool aNotify)
+FragmentOrElement::RemoveChildAt(PRUint32 aIndex, bool aNotify)
 {
   nsCOMPtr<nsIContent> oldKid = mAttrsAndChildren.GetSafeChildAt(aIndex);
   NS_ASSERTION(oldKid == GetChildAt(aIndex), "Unexpected child in RemoveChildAt");
 
   if (oldKid) {
     doRemoveChildAt(aIndex, aNotify, oldKid, mAttrsAndChildren);
   }
 }
 
 NS_IMETHODIMP
-nsGenericElement::GetTextContent(nsAString &aTextContent)
+FragmentOrElement::GetTextContent(nsAString &aTextContent)
 {
   nsContentUtils::GetNodeTextContent(this, true, aTextContent);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsGenericElement::SetTextContent(const nsAString& aTextContent)
+FragmentOrElement::SetTextContent(const nsAString& aTextContent)
 {
   return nsContentUtils::SetNodeTextContent(this, aTextContent, false);
 }
 
-/* static */
-nsresult
-nsGenericElement::DispatchEvent(nsPresContext* aPresContext,
-                                nsEvent* aEvent,
-                                nsIContent* aTarget,
-                                bool aFullDispatch,
-                                nsEventStatus* aStatus)
-{
-  NS_PRECONDITION(aTarget, "Must have target");
-  NS_PRECONDITION(aEvent, "Must have source event");
-  NS_PRECONDITION(aStatus, "Null out param?");
-
-  if (!aPresContext) {
-    return NS_OK;
-  }
-
-  nsCOMPtr<nsIPresShell> shell = aPresContext->GetPresShell();
-  if (!shell) {
-    return NS_OK;
-  }
-
-  if (aFullDispatch) {
-    return shell->HandleEventWithTarget(aEvent, nullptr, aTarget, aStatus);
-  }
-
-  return shell->HandleDOMEventWithTarget(aTarget, aEvent, aStatus);
-}
-
-/* static */
-nsresult
-nsGenericElement::DispatchClickEvent(nsPresContext* aPresContext,
-                                     nsInputEvent* aSourceEvent,
-                                     nsIContent* aTarget,
-                                     bool aFullDispatch,
-                                     PRUint32 aFlags,
-                                     nsEventStatus* aStatus)
-{
-  NS_PRECONDITION(aTarget, "Must have target");
-  NS_PRECONDITION(aSourceEvent, "Must have source event");
-  NS_PRECONDITION(aStatus, "Null out param?");
-
-  nsMouseEvent event(NS_IS_TRUSTED_EVENT(aSourceEvent), NS_MOUSE_CLICK,
-                     aSourceEvent->widget, nsMouseEvent::eReal);
-  event.refPoint = aSourceEvent->refPoint;
-  PRUint32 clickCount = 1;
-  float pressure = 0;
-  PRUint16 inputSource = 0;
-  if (aSourceEvent->eventStructType == NS_MOUSE_EVENT) {
-    clickCount = static_cast<nsMouseEvent*>(aSourceEvent)->clickCount;
-    pressure = static_cast<nsMouseEvent*>(aSourceEvent)->pressure;
-    inputSource = static_cast<nsMouseEvent*>(aSourceEvent)->inputSource;
-  } else if (aSourceEvent->eventStructType == NS_KEY_EVENT) {
-    inputSource = nsIDOMMouseEvent::MOZ_SOURCE_KEYBOARD;
-  }
-  event.pressure = pressure;
-  event.clickCount = clickCount;
-  event.inputSource = inputSource;
-  event.modifiers = aSourceEvent->modifiers;
-  event.flags |= aFlags; // Be careful not to overwrite existing flags!
-
-  return DispatchEvent(aPresContext, &event, aTarget, aFullDispatch, aStatus);
-}
-
-nsIFrame*
-nsGenericElement::GetPrimaryFrame(mozFlushType aType)
-{
-  nsIDocument* doc = GetCurrentDoc();
-  if (!doc) {
-    return nullptr;
-  }
-
-  // Cause a flush, so we get up-to-date frame
-  // information
-  doc->FlushPendingNotifications(aType);
-
-  return GetPrimaryFrame();
-}
-
 void
-nsGenericElement::DestroyContent()
+FragmentOrElement::DestroyContent()
 {
   nsIDocument *document = OwnerDoc();
   document->BindingManager()->RemovedFromDocument(this, document);
   document->ClearBoxObjectFor(this);
 
   // XXX We really should let cycle collection do this, but that currently still
   //     leaks (see https://bugzilla.mozilla.org/show_bug.cgi?id=406684).
   nsContentUtils::ReleaseWrapper(this, this);
@@ -2733,30 +1077,30 @@ nsGenericElement::DestroyContent()
   PRUint32 i, count = mAttrsAndChildren.ChildCount();
   for (i = 0; i < count; ++i) {
     // The child can remove itself from the parent in BindToTree.
     mAttrsAndChildren.ChildAt(i)->DestroyContent();
   }
 }
 
 void
-nsGenericElement::SaveSubtreeState()
+FragmentOrElement::SaveSubtreeState()
 {
   PRUint32 i, count = mAttrsAndChildren.ChildCount();
   for (i = 0; i < count; ++i) {
     mAttrsAndChildren.ChildAt(i)->SaveSubtreeState();
   }
 }
 
 //----------------------------------------------------------------------
 
 // Generic DOMNode implementations
 
 void
-nsGenericElement::FireNodeInserted(nsIDocument* aDoc,
+FragmentOrElement::FireNodeInserted(nsIDocument* aDoc,
                                    nsINode* aParent,
                                    nsTArray<nsCOMPtr<nsIContent> >& aNodes)
 {
   PRUint32 count = aNodes.Length();
   for (PRUint32 i = 0; i < count; ++i) {
     nsIContent* childContent = aNodes[i];
 
     if (nsContentUtils::HasMutationListeners(childContent,
@@ -2769,17 +1113,17 @@ nsGenericElement::FireNodeInserted(nsIDo
     }
   }
 }
 
 //----------------------------------------------------------------------
 
 // nsISupports implementation
 
-NS_IMPL_CYCLE_COLLECTION_CLASS(nsGenericElement)
+NS_IMPL_CYCLE_COLLECTION_CLASS(FragmentOrElement)
 
 #define SUBTREE_UNBINDINGS_PER_RUNNABLE 500
 
 class ContentUnbinder : public nsRunnable
 {
 public:
   ContentUnbinder()
   {
@@ -2794,17 +1138,17 @@ public:
   }
 
   void UnbindSubtree(nsIContent* aNode)
   {
     if (aNode->NodeType() != nsIDOMNode::ELEMENT_NODE &&
         aNode->NodeType() != nsIDOMNode::DOCUMENT_FRAGMENT_NODE) {
       return;  
     }
-    nsGenericElement* container = static_cast<nsGenericElement*>(aNode);
+    FragmentOrElement* container = static_cast<FragmentOrElement*>(aNode);
     PRUint32 childCount = container->mAttrsAndChildren.ChildCount();
     if (childCount) {
       while (childCount-- > 0) {
         // Hold a strong ref to the node when we remove it, because we may be
         // the last reference to it.  We need to call TakeChildAt() and
         // update mFirstChild before calling UnbindFromTree, since this last
         // can notify various observers and they should really see consistent
         // tree state.
@@ -2878,22 +1222,22 @@ private:
   nsRefPtr<ContentUnbinder>                     mNext;
   ContentUnbinder*                              mLast;
   static ContentUnbinder*                       sContentUnbinder;
 };
 
 ContentUnbinder* ContentUnbinder::sContentUnbinder = nullptr;
 
 void
-nsGenericElement::ClearContentUnbinder()
+FragmentOrElement::ClearContentUnbinder()
 {
   ContentUnbinder::UnbindAll();
 }
 
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGenericElement)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(FragmentOrElement)
   nsINode::Unlink(tmp);
 
   if (tmp->HasProperties()) {
     if (tmp->IsHTML()) {
       tmp->DeleteProperty(nsGkAtoms::microdataProperties);
       tmp->DeleteProperty(nsGkAtoms::itemtype);
       tmp->DeleteProperty(nsGkAtoms::itemref);
       tmp->DeleteProperty(nsGkAtoms::itemprop);
@@ -2940,53 +1284,53 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
   {
     nsIDocument *doc;
     if (!tmp->GetNodeParent() && (doc = tmp->OwnerDoc())) {
       doc->BindingManager()->RemovedFromDocument(tmp, doc);
     }
   }
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
-NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsGenericElement)
+NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(FragmentOrElement)
   nsINode::Trace(tmp, aCallback, aClosure);
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 void
-nsGenericElement::MarkUserData(void* aObject, nsIAtom* aKey, void* aChild,
+FragmentOrElement::MarkUserData(void* aObject, nsIAtom* aKey, void* aChild,
                                void* aData)
 {
   PRUint32* gen = static_cast<PRUint32*>(aData);
   xpc_MarkInCCGeneration(static_cast<nsISupports*>(aChild), *gen);
 }
 
 void
-nsGenericElement::MarkUserDataHandler(void* aObject, nsIAtom* aKey,
+FragmentOrElement::MarkUserDataHandler(void* aObject, nsIAtom* aKey,
                                       void* aChild, void* aData)
 {
   xpc_TryUnmarkWrappedGrayObject(static_cast<nsISupports*>(aChild));
 }
 
 void
-nsGenericElement::MarkNodeChildren(nsINode* aNode)
+FragmentOrElement::MarkNodeChildren(nsINode* aNode)
 {
   JSObject* o = GetJSObjectChild(aNode);
   xpc_UnmarkGrayObject(o);
 
   nsEventListenerManager* elm = aNode->GetListenerManager(false);
   if (elm) {
     elm->UnmarkGrayJSListeners();
   }
 
   if (aNode->HasProperties()) {
     nsIDocument* ownerDoc = aNode->OwnerDoc();
     ownerDoc->PropertyTable(DOM_USER_DATA)->
-      Enumerate(aNode, nsGenericElement::MarkUserData,
+      Enumerate(aNode, FragmentOrElement::MarkUserData,
                 &nsCCUncollectableMarker::sGeneration);
     ownerDoc->PropertyTable(DOM_USER_DATA_HANDLER)->
-      Enumerate(aNode, nsGenericElement::MarkUserDataHandler,
+      Enumerate(aNode, FragmentOrElement::MarkUserDataHandler,
                 &nsCCUncollectableMarker::sGeneration);
   }
 }
 
 nsINode*
 FindOptimizableSubtreeRoot(nsINode* aNode)
 {
   nsINode* p;
@@ -3018,17 +1362,17 @@ ClearBlackMarkedNodes()
     n->SetInCCBlackTree(false);
   }
   delete gCCBlackMarkedNodes;
   gCCBlackMarkedNodes = nullptr;
 }
 
 // static
 bool
-nsGenericElement::CanSkipInCC(nsINode* aNode)
+FragmentOrElement::CanSkipInCC(nsINode* aNode)
 {
   // Don't try to optimize anything during shutdown.
   if (nsCCUncollectableMarker::sGeneration == 0) {
     return false;
   }
 
   nsIDocument* currentDoc = aNode->GetCurrentDoc();
   if (currentDoc &&
@@ -3195,17 +1539,17 @@ OwnedByBindingManager(nsIDocument* aCurr
 
 // CanSkip checks if aNode is black, and if it is, returns
 // true. If aNode is in a black DOM tree, CanSkip may also remove other objects
 // from purple buffer and unmark event listeners and user data.
 // If the root of the DOM tree is a document, less optimizations are done
 // since checking the blackness of the current document is usually fast and we
 // don't want slow down such common cases.
 bool
-nsGenericElement::CanSkip(nsINode* aNode, bool aRemovingAllowed)
+FragmentOrElement::CanSkip(nsINode* aNode, bool aRemovingAllowed)
 {
   // Don't try to optimize anything during shutdown.
   if (nsCCUncollectableMarker::sGeneration == 0) {
     return false;
   }
 
   bool unoptimizable = aNode->UnoptimizableCCNode();
   nsIDocument* currentDoc = aNode->GetCurrentDoc();
@@ -3324,47 +1668,47 @@ nsGenericElement::CanSkip(nsINode* aNode
     if ((n != aNode || aRemovingAllowed) && n->IsPurple()) {
       n->RemovePurple();
     }
   }
   return true;
 }
 
 bool
-nsGenericElement::CanSkipThis(nsINode* aNode)
+FragmentOrElement::CanSkipThis(nsINode* aNode)
 {
   if (nsCCUncollectableMarker::sGeneration == 0) {
     return false;
   }
   if (aNode->IsBlack()) {
     return true;
   }
   nsIDocument* c = aNode->GetCurrentDoc();
   return 
     ((c && nsCCUncollectableMarker::InGeneration(c->GetMarkedCCGeneration())) ||
      aNode->InCCBlackTree()) && !NeedsScriptTraverse(aNode);
 }
 
 void
-nsGenericElement::InitCCCallbacks()
+FragmentOrElement::InitCCCallbacks()
 {
   nsCycleCollector_setForgetSkippableCallback(ClearCycleCollectorCleanupData);
   nsCycleCollector_setBeforeUnlinkCallback(ClearBlackMarkedNodes);
 }
 
-NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsGenericElement)
-  return nsGenericElement::CanSkip(tmp, aRemovingAllowed);
+NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(FragmentOrElement)
+  return FragmentOrElement::CanSkip(tmp, aRemovingAllowed);
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
 
-NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(nsGenericElement)
-  return nsGenericElement::CanSkipInCC(tmp);
+NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(FragmentOrElement)
+  return FragmentOrElement::CanSkipInCC(tmp);
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END
 
-NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(nsGenericElement)
-  return nsGenericElement::CanSkipThis(tmp);
+NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(FragmentOrElement)
+  return FragmentOrElement::CanSkipThis(tmp);
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
 
 static const char* kNSURIs[] = {
   " ([none])",
   " (xmlns)",
   " (xml)",
   " (xhtml)",
   " (XLink)",
@@ -3372,17 +1716,17 @@ static const char* kNSURIs[] = {
   " (XBL)",
   " (MathML)",
   " (RDF)",
   " (XUL)",
   " (SVG)",
   " (XML Events)"
 };
 
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGenericElement)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(FragmentOrElement)
   if (NS_UNLIKELY(cb.WantDebugInfo())) {
     char name[512];
     PRUint32 nsid = tmp->GetNameSpaceID();
     nsAtomCString localName(tmp->NodeInfo()->NameAtom());
     nsCAutoString uri;
     if (tmp->OwnerDoc()->GetDocumentURI()) {
       tmp->OwnerDoc()->GetDocumentURI()->GetSpec(uri);
     }
@@ -3402,27 +1746,27 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
       nsAutoString classString;
       classAttrValue->ToString(classString);
       classString.ReplaceChar(PRUnichar('\n'), PRUnichar(' '));
       classes.Append(classString);
       classes.AppendLiteral("'");
     }
 
     const char* nsuri = nsid < ArrayLength(kNSURIs) ? kNSURIs[nsid] : "";
-    PR_snprintf(name, sizeof(name), "nsGenericElement%s %s%s%s %s",
+    PR_snprintf(name, sizeof(name), "FragmentOrElement%s %s%s%s %s",
                 nsuri,
                 localName.get(),
                 NS_ConvertUTF16toUTF8(id).get(),
                 NS_ConvertUTF16toUTF8(classes).get(),
                 uri.get());
-    cb.DescribeRefCountedNode(tmp->mRefCnt.get(), sizeof(nsGenericElement),
+    cb.DescribeRefCountedNode(tmp->mRefCnt.get(), sizeof(FragmentOrElement),
                               name);
   }
   else {
-    NS_IMPL_CYCLE_COLLECTION_DESCRIBE(nsGenericElement, tmp->mRefCnt.get())
+    NS_IMPL_CYCLE_COLLECTION_DESCRIBE(FragmentOrElement, tmp->mRefCnt.get())
   }
 
   // Always need to traverse script objects, so do that before we check
   // if we're uncollectable.
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
 
   if (!nsINode::Traverse(tmp, cb)) {
     return NS_SUCCESS_INTERRUPTED_TRAVERSE;
@@ -3476,19 +1820,19 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
     nsDOMSlots *slots = tmp->GetExistingDOMSlots();
     if (slots) {
       slots->Traverse(cb, tmp->IsXUL());
     }
   }
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 
-NS_INTERFACE_MAP_BEGIN(nsGenericElement)
+NS_INTERFACE_MAP_BEGIN(FragmentOrElement)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
-  NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsGenericElement)
+  NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(FragmentOrElement)
   NS_INTERFACE_MAP_ENTRY(Element)
   NS_INTERFACE_MAP_ENTRY(nsIContent)
   NS_INTERFACE_MAP_ENTRY(nsINode)
   NS_INTERFACE_MAP_ENTRY(nsIDOMEventTarget)
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsISupportsWeakReference,
                                  new nsNodeSupportsWeakRefTearoff(this))
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMNodeSelector,
                                  new nsNodeSelectorTearoff(this))
@@ -3500,975 +1844,126 @@ NS_INTERFACE_MAP_BEGIN(nsGenericElement)
                                  new nsInlineEventHandlersTearoff(this))
   // nsNodeSH::PreCreate() depends on the identity pointer being the
   // same as nsINode (which nsIContent inherits), so if you change the
   // below line, make sure nsNodeSH::PreCreate() still does the right
   // thing!
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContent)
 NS_INTERFACE_MAP_END
 
-NS_IMPL_CYCLE_COLLECTING_ADDREF(nsGenericElement)
-NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_DESTROY(nsGenericElement,
+NS_IMPL_CYCLE_COLLECTING_ADDREF(FragmentOrElement)
+NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_DESTROY(FragmentOrElement,
                                               nsNodeUtils::LastRelease(this))
 
 nsresult
-nsGenericElement::PostQueryInterface(REFNSIID aIID, void** aInstancePtr)
+FragmentOrElement::PostQueryInterface(REFNSIID aIID, void** aInstancePtr)
 {
   return OwnerDoc()->BindingManager()->GetBindingImplementation(this, aIID,
                                                                 aInstancePtr);
 }
 
 //----------------------------------------------------------------------
-nsresult
-nsGenericElement::LeaveLink(nsPresContext* aPresContext)
-{
-  nsILinkHandler *handler = aPresContext->GetLinkHandler();
-  if (!handler) {
-    return NS_OK;
-  }
-
-  return handler->OnLeaveLink();
-}
 
 nsresult
-nsGenericElement::AddScriptEventListener(nsIAtom* aEventName,
-                                         const nsAString& aValue,
-                                         bool aDefer)
-{
-  nsIDocument *ownerDoc = OwnerDoc();
-  if (ownerDoc->IsLoadedAsData()) {
-    // Make this a no-op rather than throwing an error to avoid
-    // the error causing problems setting the attribute.
-    return NS_OK;
-  }
-
-  NS_PRECONDITION(aEventName, "Must have event name!");
-  bool defer = true;
-  nsEventListenerManager* manager = GetEventListenerManagerForAttr(aEventName,
-                                                                   &defer);
-  if (!manager) {
-    return NS_OK;
-  }
-
-  defer = defer && aDefer; // only defer if everyone agrees...
-  manager->AddScriptEventListener(aEventName, aValue, nsIProgrammingLanguage::JAVASCRIPT,
-                                  defer, !nsContentUtils::IsChromeDoc(ownerDoc));
-  return NS_OK;
-}
-
-
-//----------------------------------------------------------------------
-
-const nsAttrName*
-nsGenericElement::InternalGetExistingAttrNameFromQName(const nsAString& aStr) const
-{
-  return mAttrsAndChildren.GetExistingAttrNameFromQName(aStr);
-}
-
-nsresult
-nsGenericElement::CopyInnerTo(nsGenericElement* aDst)
+FragmentOrElement::CopyInnerTo(FragmentOrElement* aDst)
 {
   PRUint32 i, count = mAttrsAndChildren.AttrCount();
   for (i = 0; i < count; ++i) {
     const nsAttrName* name = mAttrsAndChildren.AttrNameAt(i);
     const nsAttrValue* value = mAttrsAndChildren.AttrAt(i);
     nsAutoString valStr;
     value->ToString(valStr);
     nsresult rv = aDst->SetAttr(name->NamespaceID(), name->LocalName(),
                                 name->GetPrefix(), valStr, false);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   return NS_OK;
 }
 
-bool
-nsGenericElement::MaybeCheckSameAttrVal(PRInt32 aNamespaceID,
-                                        nsIAtom* aName,
-                                        nsIAtom* aPrefix,
-                                        const nsAttrValueOrString& aValue,
-                                        bool aNotify,
-                                        nsAttrValue& aOldValue,
-                                        PRUint8* aModType,
-                                        bool* aHasListeners)
-{
-  bool modification = false;
-  *aHasListeners = aNotify &&
-    nsContentUtils::HasMutationListeners(this,
-                                         NS_EVENT_BITS_MUTATION_ATTRMODIFIED,
-                                         this);
-
-  // If we have no listeners and aNotify is false, we are almost certainly
-  // coming from the content sink and will almost certainly have no previous
-  // value.  Even if we do, setting the value is cheap when we have no
-  // listeners and don't plan to notify.  The check for aNotify here is an
-  // optimization, the check for *aHasListeners is a correctness issue.
-  if (*aHasListeners || aNotify) {
-    nsAttrInfo info(GetAttrInfo(aNamespaceID, aName));
-    if (info.mValue) {
-      // Check whether the old value is the same as the new one.  Note that we
-      // only need to actually _get_ the old value if we have listeners.
-      if (*aHasListeners) {
-        // Need to store the old value.
-        //
-        // If the current attribute value contains a pointer to some other data
-        // structure that gets updated in the process of setting the attribute
-        // we'll no longer have the old value of the attribute. Therefore, we
-        // should serialize the attribute value now to keep a snapshot.
-        //
-        // We have to serialize the value anyway in order to create the
-        // mutation event so there's no cost in doing it now.
-        aOldValue.SetToSerialized(*info.mValue);
-      }
-      bool valueMatches = aValue.EqualsAsStrings(*info.mValue);
-      if (valueMatches && aPrefix == info.mName->GetPrefix()) {
-        if (OwnerDoc()->MayHaveDOMMutationObservers()) {
-          // For backward compatibility, don't fire mutation events
-          // when setting an attribute to its old value.
-          *aHasListeners = false;
-        } else {
-          return true;
-        }
-      }
-      modification = true;
-    }
-  }
-  *aModType = modification ?
-    static_cast<PRUint8>(nsIDOMMutationEvent::MODIFICATION) :
-    static_cast<PRUint8>(nsIDOMMutationEvent::ADDITION);
-  return false;
-}
-
-nsresult
-nsGenericElement::SetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
-                          nsIAtom* aPrefix, const nsAString& aValue,
-                          bool aNotify)
-{
-  // Keep this in sync with SetParsedAttr below
-
-  NS_ENSURE_ARG_POINTER(aName);
-  NS_ASSERTION(aNamespaceID != kNameSpaceID_Unknown,
-               "Don't call SetAttr with unknown namespace");
-
-  if (!mAttrsAndChildren.CanFitMoreAttrs()) {
-    return NS_ERROR_FAILURE;
-  }
-
-  PRUint8 modType;
-  bool hasListeners;
-  nsAttrValueOrString value(aValue);
-  nsAttrValue oldValue;
-
-  if (MaybeCheckSameAttrVal(aNamespaceID, aName, aPrefix, value, aNotify,
-                            oldValue, &modType, &hasListeners)) {
-    return NS_OK;
-  }
-
-  nsresult rv = BeforeSetAttr(aNamespaceID, aName, &value, aNotify);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (aNotify) {
-    nsNodeUtils::AttributeWillChange(this, aNamespaceID, aName, modType);
-  }
-
-  // Hold a script blocker while calling ParseAttribute since that can call
-  // out to id-observers
-  nsAutoScriptBlocker scriptBlocker;
-
-  nsAttrValue attrValue;
-  if (!ParseAttribute(aNamespaceID, aName, aValue, attrValue)) {
-    attrValue.SetTo(aValue);
-  }
-
-  return SetAttrAndNotify(aNamespaceID, aName, aPrefix, oldValue,
-                          attrValue, modType, hasListeners, aNotify,
-                          kCallAfterSetAttr);
-}
-
-nsresult
-nsGenericElement::SetParsedAttr(PRInt32 aNamespaceID, nsIAtom* aName,
-                                nsIAtom* aPrefix, nsAttrValue& aParsedValue,
-                                bool aNotify)
-{
-  // Keep this in sync with SetAttr above
-
-  NS_ENSURE_ARG_POINTER(aName);
-  NS_ASSERTION(aNamespaceID != kNameSpaceID_Unknown,
-               "Don't call SetAttr with unknown namespace");
-
-  if (!mAttrsAndChildren.CanFitMoreAttrs()) {
-    return NS_ERROR_FAILURE;
-  }
-
-
-  PRUint8 modType;
-  bool hasListeners;
-  nsAttrValueOrString value(aParsedValue);
-  nsAttrValue oldValue;
-
-  if (MaybeCheckSameAttrVal(aNamespaceID, aName, aPrefix, value, aNotify,
-                            oldValue, &modType, &hasListeners)) {
-    return NS_OK;
-  }
-
-  nsresult rv = BeforeSetAttr(aNamespaceID, aName, &value, aNotify);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (aNotify) {
-    nsNodeUtils::AttributeWillChange(this, aNamespaceID, aName, modType);
-  }
-
-  return SetAttrAndNotify(aNamespaceID, aName, aPrefix, oldValue,
-                          aParsedValue, modType, hasListeners, aNotify,
-                          kCallAfterSetAttr);
-}
-
-nsresult
-nsGenericElement::SetAttrAndNotify(PRInt32 aNamespaceID,
-                                   nsIAtom* aName,
-                                   nsIAtom* aPrefix,
-                                   const nsAttrValue& aOldValue,
-                                   nsAttrValue& aParsedValue,
-                                   PRUint8 aModType,
-                                   bool aFireMutation,
-                                   bool aNotify,
-                                   bool aCallAfterSetAttr)
-{
-  nsresult rv;
-
-  nsIDocument* document = GetCurrentDoc();
-  mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify);
-
-  nsMutationGuard::DidMutate();
-
-  // Copy aParsedValue for later use since it will be lost when we call
-  // SetAndTakeMappedAttr below
-  nsAttrValue aValueForAfterSetAttr;
-  if (aCallAfterSetAttr) {
-    aValueForAfterSetAttr.SetTo(aParsedValue);
-  }
-
-  if (aNamespaceID == kNameSpaceID_None) {
-    // XXXbz Perhaps we should push up the attribute mapping function
-    // stuff to nsGenericElement?
-    if (!IsAttributeMapped(aName) ||
-        !SetMappedAttribute(document, aName, aParsedValue, &rv)) {
-      rv = mAttrsAndChildren.SetAndTakeAttr(aName, aParsedValue);
-    }
-  }
-  else {
-    nsCOMPtr<nsINodeInfo> ni;
-    ni = mNodeInfo->NodeInfoManager()->GetNodeInfo(aName, aPrefix,
-                                                   aNamespaceID,
-                                                   nsIDOMNode::ATTRIBUTE_NODE);
-    NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
-
-    rv = mAttrsAndChildren.SetAndTakeAttr(ni, aParsedValue);
-  }
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (document || HasFlag(NODE_FORCE_XBL_BINDINGS)) {
-    nsRefPtr<nsXBLBinding> binding =
-      OwnerDoc()->BindingManager()->GetBinding(this);
-    if (binding) {
-      binding->AttributeChanged(aName, aNamespaceID, false, aNotify);
-    }
-  }
-
-  UpdateState(aNotify);
-
-  if (aNotify) {
-    nsNodeUtils::AttributeChanged(this, aNamespaceID, aName, aModType);
-  }
-
-  if (aNamespaceID == kNameSpaceID_XMLEvents && 
-      aName == nsGkAtoms::event && mNodeInfo->GetDocument()) {
-    mNodeInfo->GetDocument()->AddXMLEventsContent(this);
-  }
-  if (aCallAfterSetAttr) {
-    rv = AfterSetAttr(aNamespaceID, aName, &aValueForAfterSetAttr, aNotify);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  if (aFireMutation) {
-    nsMutationEvent mutation(true, NS_MUTATION_ATTRMODIFIED);
-
-    nsCOMPtr<nsIDOMAttr> attrNode;
-    nsAutoString ns;
-    nsContentUtils::NameSpaceManager()->GetNameSpaceURI(aNamespaceID, ns);
-    GetAttributeNodeNSInternal(ns, nsDependentAtomString(aName),
-                               getter_AddRefs(attrNode));
-    mutation.mRelatedNode = attrNode;
-
-    mutation.mAttrName = aName;
-    nsAutoString newValue;
-    GetAttr(aNamespaceID, aName, newValue);
-    if (!newValue.IsEmpty()) {
-      mutation.mNewAttrValue = do_GetAtom(newValue);
-    }
-    if (!aOldValue.IsEmptyString()) {
-      mutation.mPrevAttrValue = aOldValue.GetAsAtom();
-    }
-    mutation.mAttrChange = aModType;
-
-    mozAutoSubtreeModified subtree(OwnerDoc(), this);
-    (new nsAsyncDOMEvent(this, mutation))->RunDOMEventWhenSafe();
-  }
-
-  return NS_OK;
-}
-
-bool
-nsGenericElement::ParseAttribute(PRInt32 aNamespaceID,
-                                 nsIAtom* aAttribute,
-                                 const nsAString& aValue,
-                                 nsAttrValue& aResult)
-{
-  return false;
-}
-
-bool
-nsGenericElement::SetMappedAttribute(nsIDocument* aDocument,
-                                     nsIAtom* aName,
-                                     nsAttrValue& aValue,
-                                     nsresult* aRetval)
-{
-  *aRetval = NS_OK;
-  return false;
-}
-
-nsEventListenerManager*
-nsGenericElement::GetEventListenerManagerForAttr(nsIAtom* aAttrName,
-                                                 bool* aDefer)
-{
-  *aDefer = true;
-  return GetListenerManager(true);
-}
-
-nsGenericElement::nsAttrInfo
-nsGenericElement::GetAttrInfo(PRInt32 aNamespaceID, nsIAtom* aName) const
-{
-  NS_ASSERTION(nullptr != aName, "must have attribute name");
-  NS_ASSERTION(aNamespaceID != kNameSpaceID_Unknown,
-               "must have a real namespace ID!");
-
-  PRInt32 index = mAttrsAndChildren.IndexOfAttr(aName, aNamespaceID);
-  if (index >= 0) {
-    return nsAttrInfo(mAttrsAndChildren.AttrNameAt(index),
-                      mAttrsAndChildren.AttrAt(index));
-  }
-
-  return nsAttrInfo(nullptr, nullptr);
-}
-  
-
-bool
-nsGenericElement::GetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
-                          nsAString& aResult) const
-{
-  NS_ASSERTION(nullptr != aName, "must have attribute name");
-  NS_ASSERTION(aNameSpaceID != kNameSpaceID_Unknown,
-               "must have a real namespace ID!");
-
-  const nsAttrValue* val = mAttrsAndChildren.GetAttr(aName, aNameSpaceID);
-  if (!val) {
-    // Since we are returning a success code we'd better do
-    // something about the out parameters (someone may have
-    // given us a non-empty string).
-    aResult.Truncate();
-    
-    return false;
-  }
-
-  val->ToString(aResult);
-
-  return true;
-}
-
-bool
-nsGenericElement::HasAttr(PRInt32 aNameSpaceID, nsIAtom* aName) const
-{
-  NS_ASSERTION(nullptr != aName, "must have attribute name");
-  NS_ASSERTION(aNameSpaceID != kNameSpaceID_Unknown,
-               "must have a real namespace ID!");
-
-  return mAttrsAndChildren.IndexOfAttr(aName, aNameSpaceID) >= 0;
-}
-
-bool
-nsGenericElement::AttrValueIs(PRInt32 aNameSpaceID,
-                              nsIAtom* aName,
-                              const nsAString& aValue,
-                              nsCaseTreatment aCaseSensitive) const
-{
-  NS_ASSERTION(aName, "Must have attr name");
-  NS_ASSERTION(aNameSpaceID != kNameSpaceID_Unknown, "Must have namespace");
-
-  const nsAttrValue* val = mAttrsAndChildren.GetAttr(aName, aNameSpaceID);
-  return val && val->Equals(aValue, aCaseSensitive);
-}
-
-bool
-nsGenericElement::AttrValueIs(PRInt32 aNameSpaceID,
-                              nsIAtom* aName,
-                              nsIAtom* aValue,
-                              nsCaseTreatment aCaseSensitive) const
-{
-  NS_ASSERTION(aName, "Must have attr name");
-  NS_ASSERTION(aNameSpaceID != kNameSpaceID_Unknown, "Must have namespace");
-  NS_ASSERTION(aValue, "Null value atom");
-
-  const nsAttrValue* val = mAttrsAndChildren.GetAttr(aName, aNameSpaceID);
-  return val && val->Equals(aValue, aCaseSensitive);
-}
-
-PRInt32
-nsGenericElement::FindAttrValueIn(PRInt32 aNameSpaceID,
-                                  nsIAtom* aName,
-                                  AttrValuesArray* aValues,
-                                  nsCaseTreatment aCaseSensitive) const
-{
-  NS_ASSERTION(aName, "Must have attr name");
-  NS_ASSERTION(aNameSpaceID != kNameSpaceID_Unknown, "Must have namespace");
-  NS_ASSERTION(aValues, "Null value array");
-  
-  const nsAttrValue* val = mAttrsAndChildren.GetAttr(aName, aNameSpaceID);
-  if (val) {
-    for (PRInt32 i = 0; aValues[i]; ++i) {
-      if (val->Equals(*aValues[i], aCaseSensitive)) {
-        return i;
-      }
-    }
-    return ATTR_VALUE_NO_MATCH;
-  }
-  return ATTR_MISSING;
-}
-
-nsresult
-nsGenericElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
-                            bool aNotify)
-{
-  NS_ASSERTION(nullptr != aName, "must have attribute name");
-
-  PRInt32 index = mAttrsAndChildren.IndexOfAttr(aName, aNameSpaceID);
-  if (index < 0) {
-    return NS_OK;
-  }
-
-  nsresult rv = BeforeSetAttr(aNameSpaceID, aName, nullptr, aNotify);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsIDocument *document = GetCurrentDoc();
-  mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify);
-
-  if (aNotify) {
-    nsNodeUtils::AttributeWillChange(this, aNameSpaceID, aName,
-                                     nsIDOMMutationEvent::REMOVAL);
-  }
-
-  bool hasMutationListeners = aNotify &&
-    nsContentUtils::HasMutationListeners(this,
-                                         NS_EVENT_BITS_MUTATION_ATTRMODIFIED,
-                                         this);
-
-  // Grab the attr node if needed before we remove it from the attr map
-  nsCOMPtr<nsIDOMAttr> attrNode;
-  if (hasMutationListeners) {
-    nsAutoString ns;
-    nsContentUtils::NameSpaceManager()->GetNameSpaceURI(aNameSpaceID, ns);
-    GetAttributeNodeNSInternal(ns, nsDependentAtomString(aName),
-                               getter_AddRefs(attrNode));
-  }
-
-  // Clear binding to nsIDOMNamedNodeMap
-  nsDOMSlots *slots = GetExistingDOMSlots();
-  if (slots && slots->mAttributeMap) {
-    slots->mAttributeMap->DropAttribute(aNameSpaceID, aName);
-  }
-
-  // The id-handling code, and in the future possibly other code, need to
-  // react to unexpected attribute changes.
-  nsMutationGuard::DidMutate();
-
-  nsAttrValue oldValue;
-  rv = mAttrsAndChildren.RemoveAttrAt(index, oldValue);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (document || HasFlag(NODE_FORCE_XBL_BINDINGS)) {
-    nsRefPtr<nsXBLBinding> binding =
-      OwnerDoc()->BindingManager()->GetBinding(this);
-    if (binding) {
-      binding->AttributeChanged(aName, aNameSpaceID, true, aNotify);
-    }
-  }
-
-  UpdateState(aNotify);
-
-  if (aNotify) {
-    nsNodeUtils::AttributeChanged(this, aNameSpaceID, aName,
-                                  nsIDOMMutationEvent::REMOVAL);
-  }
-
-  rv = AfterSetAttr(aNameSpaceID, aName, nullptr, aNotify);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (hasMutationListeners) {
-    nsCOMPtr<nsIDOMEventTarget> node = do_QueryObject(this);
-    nsMutationEvent mutation(true, NS_MUTATION_ATTRMODIFIED);
-
-    mutation.mRelatedNode = attrNode;
-    mutation.mAttrName = aName;
-
-    nsAutoString value;
-    oldValue.ToString(value);
-    if (!value.IsEmpty())
-      mutation.mPrevAttrValue = do_GetAtom(value);
-    mutation.mAttrChange = nsIDOMMutationEvent::REMOVAL;
-
-    mozAutoSubtreeModified subtree(OwnerDoc(), this);
-    (new nsAsyncDOMEvent(this, mutation))->RunDOMEventWhenSafe();
-  }
-
-  return NS_OK;
-}
-
-const nsAttrName*
-nsGenericElement::GetAttrNameAt(PRUint32 aIndex) const
-{
-  return mAttrsAndChildren.GetSafeAttrNameAt(aIndex);
-}
-
-PRUint32
-nsGenericElement::GetAttrCount() const
-{
-  return mAttrsAndChildren.AttrCount();
-}
-
 const nsTextFragment*
-nsGenericElement::GetText()
+FragmentOrElement::GetText()
 {
   return nullptr;
 }
 
 PRUint32
-nsGenericElement::TextLength() const
+FragmentOrElement::TextLength() const
 {
   // We can remove this assertion if it turns out to be useful to be able
   // to depend on this returning 0
-  NS_NOTREACHED("called nsGenericElement::TextLength");
+  NS_NOTREACHED("called FragmentOrElement::TextLength");
 
   return 0;
 }
 
 nsresult
-nsGenericElement::SetText(const PRUnichar* aBuffer, PRUint32 aLength,
+FragmentOrElement::SetText(const PRUnichar* aBuffer, PRUint32 aLength,
                           bool aNotify)
 {
-  NS_ERROR("called nsGenericElement::SetText");
+  NS_ERROR("called FragmentOrElement::SetText");
 
   return NS_ERROR_FAILURE;
 }
 
 nsresult
-nsGenericElement::AppendText(const PRUnichar* aBuffer, PRUint32 aLength,
+FragmentOrElement::AppendText(const PRUnichar* aBuffer, PRUint32 aLength,
                              bool aNotify)
 {
-  NS_ERROR("called nsGenericElement::AppendText");
+  NS_ERROR("called FragmentOrElement::AppendText");
 
   return NS_ERROR_FAILURE;
 }
 
 bool
-nsGenericElement::TextIsOnlyWhitespace()
+FragmentOrElement::TextIsOnlyWhitespace()
 {
   return false;
 }
 
 void
-nsGenericElement::AppendTextTo(nsAString& aResult)
+FragmentOrElement::AppendTextTo(nsAString& aResult)
 {
   // We can remove this assertion if it turns out to be useful to be able
   // to depend on this appending nothing.
-  NS_NOTREACHED("called nsGenericElement::TextLength");
-}
-
-#ifdef DEBUG
-void
-nsGenericElement::ListAttributes(FILE* out) const
-{
-  PRUint32 index, count = mAttrsAndChildren.AttrCount();
-  for (index = 0; index < count; index++) {
-    nsAutoString buffer;
-
-    // name
-    mAttrsAndChildren.AttrNameAt(index)->GetQualifiedName(buffer);
-
-    // value
-    buffer.AppendLiteral("=\"");
-    nsAutoString value;
-    mAttrsAndChildren.AttrAt(index)->ToString(value);
-    for (int i = value.Length(); i >= 0; --i) {
-      if (value[i] == PRUnichar('"'))
-        value.Insert(PRUnichar('\\'), PRUint32(i));
-    }
-    buffer.Append(value);
-    buffer.AppendLiteral("\"");
-
-    fputs(" ", out);
-    fputs(NS_LossyConvertUTF16toASCII(buffer).get(), out);
-  }
+  NS_NOTREACHED("called FragmentOrElement::TextLength");
 }
 
-void
-nsGenericElement::List(FILE* out, PRInt32 aIndent,
-                       const nsCString& aPrefix) const
-{
-  PRInt32 indent;
-  for (indent = aIndent; --indent >= 0; ) fputs("  ", out);
-
-  fputs(aPrefix.get(), out);
-
-  fputs(NS_LossyConvertUTF16toASCII(mNodeInfo->QualifiedName()).get(), out);
-
-  fprintf(out, "@%p", (void *)this);
-
-  ListAttributes(out);
-
-  fprintf(out, " state=[%llx]", State().GetInternalValue());
-  fprintf(out, " flags=[%08x]", static_cast<unsigned int>(GetFlags()));
-  if (IsCommonAncestorForRangeInSelection()) {
-    nsRange::RangeHashTable* ranges =
-      static_cast<nsRange::RangeHashTable*>(GetProperty(nsGkAtoms::range));
-    fprintf(out, " ranges:%d", ranges ? ranges->Count() : 0);
-  }
-  fprintf(out, " primaryframe=%p", static_cast<void*>(GetPrimaryFrame()));
-  fprintf(out, " refcount=%d<", mRefCnt.get());
-
-  nsIContent* child = GetFirstChild();
-  if (child) {
-    fputs("\n", out);
-    
-    for (; child; child = child->GetNextSibling()) {
-      child->List(out, aIndent + 1);
-    }
-
-    for (indent = aIndent; --indent >= 0; ) fputs("  ", out);
-  }
-
-  fputs(">\n", out);
-  
-  nsGenericElement* nonConstThis = const_cast<nsGenericElement*>(this);
-
-  // XXX sXBL/XBL2 issue! Owner or current document?
-  nsIDocument *document = OwnerDoc();
-
-  // Note: not listing nsIAnonymousContentCreator-created content...
-
-  nsBindingManager* bindingManager = document->BindingManager();
-  nsCOMPtr<nsIDOMNodeList> anonymousChildren;
-  bindingManager->GetAnonymousNodesFor(nonConstThis,
-                                       getter_AddRefs(anonymousChildren));
-
-  if (anonymousChildren) {
-    PRUint32 length;
-    anonymousChildren->GetLength(&length);
-    if (length > 0) {
-      for (indent = aIndent; --indent >= 0; ) fputs("  ", out);
-      fputs("anonymous-children<\n", out);
-
-      for (PRUint32 i = 0; i < length; ++i) {
-        nsCOMPtr<nsIDOMNode> node;
-        anonymousChildren->Item(i, getter_AddRefs(node));
-        nsCOMPtr<nsIContent> child = do_QueryInterface(node);
-        child->List(out, aIndent + 1);
-      }
-
-      for (indent = aIndent; --indent >= 0; ) fputs("  ", out);
-      fputs(">\n", out);
-    }
-  }
-
-  if (bindingManager->HasContentListFor(nonConstThis)) {
-    nsCOMPtr<nsIDOMNodeList> contentList;
-    bindingManager->GetContentListFor(nonConstThis,
-                                      getter_AddRefs(contentList));
-
-    NS_ASSERTION(contentList != nullptr, "oops, binding manager lied");
-    
-    PRUint32 length;
-    contentList->GetLength(&length);
-    if (length > 0) {
-      for (indent = aIndent; --indent >= 0; ) fputs("  ", out);
-      fputs("content-list<\n", out);
-
-      for (PRUint32 i = 0; i < length; ++i) {
-        nsCOMPtr<nsIDOMNode> node;
-        contentList->Item(i, getter_AddRefs(node));
-        nsCOMPtr<nsIContent> child = do_QueryInterface(node);
-        child->List(out, aIndent + 1);
-      }
-
-      for (indent = aIndent; --indent >= 0; ) fputs("  ", out);
-      fputs(">\n", out);
-    }
-  }
-}
-
-void
-nsGenericElement::DumpContent(FILE* out, PRInt32 aIndent,
-                              bool aDumpAll) const
-{
-  PRInt32 indent;
-  for (indent = aIndent; --indent >= 0; ) fputs("  ", out);
-
-  const nsString& buf = mNodeInfo->QualifiedName();
-  fputs("<", out);
-  fputs(NS_LossyConvertUTF16toASCII(buf).get(), out);
-
-  if(aDumpAll) ListAttributes(out);
-
-  fputs(">", out);
-
-  if(aIndent) fputs("\n", out);
-
-  for (nsIContent* child = GetFirstChild();
-       child;
-       child = child->GetNextSibling()) {
-    PRInt32 indent = aIndent ? aIndent + 1 : 0;
-    child->DumpContent(out, indent, aDumpAll);
-  }
-  for (indent = aIndent; --indent >= 0; ) fputs("  ", out);
-  fputs("</", out);
-  fputs(NS_LossyConvertUTF16toASCII(buf).get(), out);
-  fputs(">", out);
-
-  if(aIndent) fputs("\n", out);
-}
-#endif
-
 PRUint32
-nsGenericElement::GetChildCount() const
+FragmentOrElement::GetChildCount() const
 {
   return mAttrsAndChildren.ChildCount();
 }
 
 nsIContent *
-nsGenericElement::GetChildAt(PRUint32 aIndex) const
+FragmentOrElement::GetChildAt(PRUint32 aIndex) const
 {
   return mAttrsAndChildren.GetSafeChildAt(aIndex);
 }
 
 nsIContent * const *
-nsGenericElement::GetChildArray(PRUint32* aChildCount) const
+FragmentOrElement::GetChildArray(PRUint32* aChildCount) const
 {
   return mAttrsAndChildren.GetChildArray(aChildCount);
 }
 
 PRInt32
-nsGenericElement::IndexOf(nsINode* aPossibleChild) const
+FragmentOrElement::IndexOf(nsINode* aPossibleChild) const
 {
   return mAttrsAndChildren.IndexOfChild(aPossibleChild);
 }
 
 nsINode::nsSlots*
-nsGenericElement::CreateSlots()
+FragmentOrElement::CreateSlots()
 {
   return new nsDOMSlots();
 }
 
-bool
-nsGenericElement::CheckHandleEventForLinksPrecondition(nsEventChainVisitor& aVisitor,
-                                                       nsIURI** aURI) const
-{
-  if (aVisitor.mEventStatus == nsEventStatus_eConsumeNoDefault ||
-      (!NS_IS_TRUSTED_EVENT(aVisitor.mEvent) &&
-       (aVisitor.mEvent->message != NS_MOUSE_CLICK) &&
-       (aVisitor.mEvent->message != NS_KEY_PRESS) &&
-       (aVisitor.mEvent->message != NS_UI_ACTIVATE)) ||
-      !aVisitor.mPresContext ||
-      (aVisitor.mEvent->flags & NS_EVENT_FLAG_PREVENT_MULTIPLE_ACTIONS)) {
-    return false;
-  }
-
-  // Make sure we actually are a link
-  return IsLink(aURI);
-}
-
-nsresult
-nsGenericElement::PreHandleEventForLinks(nsEventChainPreVisitor& aVisitor)
-{
-  // Optimisation: return early if this event doesn't interest us.
-  // IMPORTANT: this switch and the switch below it must be kept in sync!
-  switch (aVisitor.mEvent->message) {
-  case NS_MOUSE_ENTER_SYNTH:
-  case NS_FOCUS_CONTENT:
-  case NS_MOUSE_EXIT_SYNTH:
-  case NS_BLUR_CONTENT:
-    break;
-  default:
-    return NS_OK;
-  }
-
-  // Make sure we meet the preconditions before continuing
-  nsCOMPtr<nsIURI> absURI;
-  if (!CheckHandleEventForLinksPrecondition(aVisitor, getter_AddRefs(absURI))) {
-    return NS_OK;
-  }
-
-  nsresult rv = NS_OK;
-
-  // We do the status bar updates in PreHandleEvent so that the status bar gets
-  // updated even if the event is consumed before we have a chance to set it.
-  switch (aVisitor.mEvent->message) {
-  // Set the status bar similarly for mouseover and focus
-  case NS_MOUSE_ENTER_SYNTH:
-    aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
-    // FALL THROUGH
-  case NS_FOCUS_CONTENT:
-    if (aVisitor.mEvent->eventStructType != NS_FOCUS_EVENT ||
-        !static_cast<nsFocusEvent*>(aVisitor.mEvent)->isRefocus) {
-      nsAutoString target;
-      GetLinkTarget(target);
-      nsContentUtils::TriggerLink(this, aVisitor.mPresContext, absURI, target,
-                                  false, true, true);
-      // Make sure any ancestor links don't also TriggerLink
-      aVisitor.mEvent->flags |= NS_EVENT_FLAG_PREVENT_MULTIPLE_ACTIONS;
-    }
-    break;
-
-  case NS_MOUSE_EXIT_SYNTH:
-    aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
-    // FALL THROUGH
-  case NS_BLUR_CONTENT:
-    rv = LeaveLink(aVisitor.mPresContext);
-    if (NS_SUCCEEDED(rv)) {
-      aVisitor.mEvent->flags |= NS_EVENT_FLAG_PREVENT_MULTIPLE_ACTIONS;
-    }
-    break;
-
-  default:
-    // switch not in sync with the optimization switch earlier in this function
-    NS_NOTREACHED("switch statements not in sync");
-    return NS_ERROR_UNEXPECTED;
-  }
-
-  return rv;
-}
-
-nsresult
-nsGenericElement::PostHandleEventForLinks(nsEventChainPostVisitor& aVisitor)
-{
-  // Optimisation: return early if this event doesn't interest us.
-  // IMPORTANT: this switch and the switch below it must be kept in sync!
-  switch (aVisitor.mEvent->message) {
-  case NS_MOUSE_BUTTON_DOWN:
-  case NS_MOUSE_CLICK:
-  case NS_UI_ACTIVATE:
-  case NS_KEY_PRESS:
-    break;
-  default:
-    return NS_OK;
-  }
-
-  // Make sure we meet the preconditions before continuing
-  nsCOMPtr<nsIURI> absURI;
-  if (!CheckHandleEventForLinksPrecondition(aVisitor, getter_AddRefs(absURI))) {
-    return NS_OK;
-  }
-
-  nsresult rv = NS_OK;
-
-  switch (aVisitor.mEvent->message) {
-  case NS_MOUSE_BUTTON_DOWN:
-    {
-      if (aVisitor.mEvent->eventStructType == NS_MOUSE_EVENT &&
-          static_cast<nsMouseEvent*>(aVisitor.mEvent)->button ==
-          nsMouseEvent::eLeftButton) {
-        // don't make the link grab the focus if there is no link handler
-        nsILinkHandler *handler = aVisitor.mPresContext->GetLinkHandler();
-        nsIDocument *document = GetCurrentDoc();
-        if (handler && document) {
-          nsIFocusManager* fm = nsFocusManager::GetFocusManager();
-          if (fm) {
-            aVisitor.mEvent->flags |= NS_EVENT_FLAG_PREVENT_MULTIPLE_ACTIONS;
-            nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(this);
-            fm->SetFocus(elem, nsIFocusManager::FLAG_BYMOUSE |
-                               nsIFocusManager::FLAG_NOSCROLL);
-          }
-
-          nsEventStateManager::SetActiveManager(
-            aVisitor.mPresContext->EventStateManager(), this);
-        }
-      }
-    }
-    break;
-
-  case NS_MOUSE_CLICK:
-    if (NS_IS_MOUSE_LEFT_CLICK(aVisitor.mEvent)) {
-      nsInputEvent* inputEvent = static_cast<nsInputEvent*>(aVisitor.mEvent);
-      if (inputEvent->IsControl() || inputEvent->IsMeta() ||
-          inputEvent->IsAlt() ||inputEvent->IsShift()) {
-        break;
-      }
-
-      // The default action is simply to dispatch DOMActivate
-      nsCOMPtr<nsIPresShell> shell = aVisitor.mPresContext->GetPresShell();
-      if (shell) {
-        // single-click
-        nsEventStatus status = nsEventStatus_eIgnore;
-        nsUIEvent actEvent(NS_IS_TRUSTED_EVENT(aVisitor.mEvent),
-                           NS_UI_ACTIVATE, 1);
-
-        rv = shell->HandleDOMEventWithTarget(this, &actEvent, &status);
-        if (NS_SUCCEEDED(rv)) {
-          aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
-        }
-      }
-    }
-    break;
-
-  case NS_UI_ACTIVATE:
-    {
-      if (aVisitor.mEvent->originalTarget == this) {
-        nsAutoString target;
-        GetLinkTarget(target);
-        nsContentUtils::TriggerLink(this, aVisitor.mPresContext, absURI, target,
-                                    true, true, NS_IS_TRUSTED_EVENT(aVisitor.mEvent));
-        aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
-      }
-    }
-    break;
-
-  case NS_KEY_PRESS:
-    {
-      if (aVisitor.mEvent->eventStructType == NS_KEY_EVENT) {
-        nsKeyEvent* keyEvent = static_cast<nsKeyEvent*>(aVisitor.mEvent);
-        if (keyEvent->keyCode == NS_VK_RETURN) {
-          nsEventStatus status = nsEventStatus_eIgnore;
-          rv = DispatchClickEvent(aVisitor.mPresContext, keyEvent, this,
-                                  false, 0, &status);
-          if (NS_SUCCEEDED(rv)) {
-            aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
-          }
-        }
-      }
-    }
-    break;
-
-  default:
-    // switch not in sync with the optimization switch earlier in this function
-    NS_NOTREACHED("switch statements not in sync");
-    return NS_ERROR_UNEXPECTED;
-  }
-
-  return rv;
-}
-
 void
-nsGenericElement::FireNodeRemovedForChildren()
+FragmentOrElement::FireNodeRemovedForChildren()
 {
   nsIDocument* doc = OwnerDoc();
   // Optimize the common case
   if (!nsContentUtils::
         HasMutationListeners(doc, NS_EVENT_BITS_MUTATION_NODEREMOVED)) {
     return;
   }
 
@@ -4477,22 +1972,16 @@ nsGenericElement::FireNodeRemovedForChil
   nsCOMPtr<nsINode> child;
   for (child = GetFirstChild();
        child && child->GetNodeParent() == this;
        child = child->GetNextSibling()) {
     nsContentUtils::MaybeFireNodeRemoved(child, this, doc);
   }
 }
 
-void
-nsGenericElement::GetLinkTarget(nsAString& aTarget)
-{
-  aTarget.Truncate();
-}
-
 // NOTE: The aPresContext pointer is NOT addrefed.
 // *aSelectorList might be null even if NS_OK is returned; this
 // happens when all the selectors were pseudo-element selectors.
 static nsresult
 ParseSelectorList(nsINode* aNode,
                   const nsAString& aSelectorString,
                   nsCSSSelectorList** aSelectorList)
 {
@@ -4614,199 +2103,41 @@ struct ElementHolder {
     NS_ABORT_IF_FALSE(!mElement, "Should only get one element");
     mElement = aElement;
   }
   Element* mElement;
 };
 
 /* static */
 nsIContent*
-nsGenericElement::doQuerySelector(nsINode* aRoot, const nsAString& aSelector,
+FragmentOrElement::doQuerySelector(nsINode* aRoot, const nsAString& aSelector,
                                   nsresult *aResult)
 {
   NS_PRECONDITION(aResult, "Null out param?");
 
   ElementHolder holder;
   *aResult = FindMatchingElements<true>(aRoot, aSelector, holder);
 
   return holder.mElement;
 }
 
 /* static */
 nsresult
-nsGenericElement::doQuerySelectorAll(nsINode* aRoot,
+FragmentOrElement::doQuerySelectorAll(nsINode* aRoot,
                                      const nsAString& aSelector,
                                      nsIDOMNodeList **aReturn)
 {
   NS_PRECONDITION(aReturn, "Null out param?");
 
   nsSimpleContentList* contentList = new nsSimpleContentList(aRoot);
   NS_ENSURE_TRUE(contentList, NS_ERROR_OUT_OF_MEMORY);
   NS_ADDREF(*aReturn = contentList);
   
   return FindMatchingElements<false>(aRoot, aSelector, *contentList);
 }
 
 
-bool
-nsGenericElement::MozMatchesSelector(const nsAString& aSelector, nsresult* aResult)
+size_t
+FragmentOrElement::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
 {
-  nsAutoPtr<nsCSSSelectorList> selectorList;
-  bool matches = false;
-
-  *aResult = ParseSelectorList(this, aSelector, getter_Transfers(selectorList));
-
-  if (NS_SUCCEEDED(*aResult)) {
-    OwnerDoc()->FlushPendingLinkUpdates();
-    TreeMatchContext matchingContext(false,
-                                     nsRuleWalker::eRelevantLinkUnvisited,
-                                     OwnerDoc(),
-                                     TreeMatchContext::eNeverMatchVisited);
-    matches = nsCSSRuleProcessor::SelectorListMatches(this, matchingContext,
-                                                      selectorList);
-  }
-
-  return matches;
-}
-
-NS_IMETHODIMP
-nsGenericElement::MozMatchesSelector(const nsAString& aSelector, bool* aReturn)
-{
-  NS_PRECONDITION(aReturn, "Null out param?");
-
-  nsresult rv;
-  *aReturn = MozMatchesSelector(aSelector, &rv);
-
-  return rv;
-}
-
-size_t
-nsGenericElement::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
-{
-  return Element::SizeOfExcludingThis(aMallocSizeOf) +
+  return nsIContent::SizeOfExcludingThis(aMallocSizeOf) +
          mAttrsAndChildren.SizeOfExcludingThis(aMallocSizeOf);
 }
-
-static const nsAttrValue::EnumTable kCORSAttributeTable[] = {
-  // Order matters here
-  // See ParseCORSValue
-  { "anonymous",       CORS_ANONYMOUS       },
-  { "use-credentials", CORS_USE_CREDENTIALS },
-  { 0 }
-};
-
-/* static */ void
-nsGenericElement::ParseCORSValue(const nsAString& aValue,
-                                 nsAttrValue& aResult)
-{
-  DebugOnly<bool> success =
-    aResult.ParseEnumValue(aValue, kCORSAttributeTable, false,
-                           // default value is anonymous if aValue is
-                           // not a value we understand
-                           &kCORSAttributeTable[0]);
-  MOZ_ASSERT(success);
-}
-
-/* static */ CORSMode
-nsGenericElement::StringToCORSMode(const nsAString& aValue)
-{
-  if (aValue.IsVoid()) {
-    return CORS_NONE;
-  }
-
-  nsAttrValue val;
-  nsGenericElement::ParseCORSValue(aValue, val);
-  return CORSMode(val.GetEnumValue());
-}
-
-/* static */ CORSMode
-nsGenericElement::AttrValueToCORSMode(const nsAttrValue* aValue)
-{
-  if (!aValue) {
-    return CORS_NONE;
-  }
-
-  return CORSMode(aValue->GetEnumValue());
-}
-
-NS_IMETHODIMP
-nsGenericElement::GetOnmouseenter(JSContext* cx, JS::Value* vp)
-{
-  return nsINode::GetOnmouseenter(cx, vp);
-}
-
-NS_IMETHODIMP
-nsGenericElement::SetOnmouseenter(JSContext* cx, const JS::Value& v)
-{
-  return nsINode::SetOnmouseenter(cx, v);
-}
-
-NS_IMETHODIMP
-nsGenericElement::GetOnmouseleave(JSContext* cx, JS::Value* vp)
-{
-  return nsINode::GetOnmouseleave(cx, vp);
-}
-
-NS_IMETHODIMP
-nsGenericElement::SetOnmouseleave(JSContext* cx, const JS::Value& v)
-{
-  return nsINode::SetOnmouseleave(cx, v);
-}
-
-NS_IMETHODIMP
-nsGenericElement::MozRequestPointerLock()
-{
-  OwnerDoc()->RequestPointerLock(this);
-  return NS_OK;
-}
-
-static const char*
-GetFullScreenError(nsIDocument* aDoc)
-{
-  nsCOMPtr<nsPIDOMWindow> win = aDoc->GetWindow();
-  if (win && win->IsInAppOrigin()) {
-    // Request is in a web app and in the same origin as the web app.
-    // Don't enforce as strict security checks for web apps, the user
-    // is supposed to have trust in them. However documents cross-origin
-    // to the web app must still confirm to the normal security checks.
-    return nullptr;
-  }
-
-  if (!nsContentUtils::IsRequestFullScreenAllowed()) {
-    return "FullScreenDeniedNotInputDriven";
-  }
-
-  if (nsContentUtils::IsSitePermDeny(aDoc->NodePrincipal(), "fullscreen")) {
-    return "FullScreenDeniedBlocked";
-  }
-
-  return nullptr;
-}
-
-nsresult nsGenericElement::MozRequestFullScreen()
-{
-  // Only grant full-screen requests if this is called from inside a trusted
-  // event handler (i.e. inside an event handler for a user initiated event).
-  // This stops the full-screen from being abused similar to the popups of old,
-  // and it also makes it harder for bad guys' script to go full-screen and
-  // spoof the browser chrome/window and phish logins etc.
-  // Note that requests for fullscreen inside a web app's origin are exempt
-  // from this restriction.
-  const char* error = GetFullScreenError(OwnerDoc());
-  if (error) {
-    nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
-                                    "DOM", OwnerDoc(),
-                                    nsContentUtils::eDOM_PROPERTIES,
-                                    error);
-    nsRefPtr<nsAsyncDOMEvent> e =
-      new nsAsyncDOMEvent(OwnerDoc(),
-                          NS_LITERAL_STRING("mozfullscreenerror"),
-                          true,
-                          false);
-    e->PostDOMEvent();
-    return NS_OK;
-  }
-
-  OwnerDoc()->AsyncRequestFullScreen(this);
-
-  return NS_OK;
-}
-
--- a/content/base/src/Makefile.in
+++ b/content/base/src/Makefile.in
@@ -120,16 +120,17 @@ CPPSRCS		= \
 		nsTraversal.cpp \
 		nsTreeSanitizer.cpp \
 		nsTreeWalker.cpp \
 		nsWebSocket.cpp \
 		nsXHTMLContentSerializer.cpp \
 		nsXMLContentSerializer.cpp \
 		nsXMLHttpRequest.cpp \
 		nsXMLNameSpaceMap.cpp \
+		FragmentOrElement.cpp \
 		Link.cpp \
 		nsBlobProtocolHandler.cpp \
 		nsFrameMessageManager.cpp \
 		nsInProcessTabChildGlobal.cpp \
 		ThirdPartyUtil.cpp \
 		nsEventSource.cpp \
 		FileIOObject.cpp \
 		nsDOMMutationObserver.cpp \
--- a/content/base/src/nsAttrName.h
+++ b/content/base/src/nsAttrName.h
@@ -153,25 +153,27 @@ public:
     if (IsAtom()) {
       Atom()->ToString(aStr);
     }
     else {
       aStr = NodeInfo()->QualifiedName();
     }
   }
 
+#ifdef MOZILLA_INTERNAL_API
   void GetPrefix(nsAString& aStr) const
   {
     if (IsAtom()) {
       SetDOMStringToNull(aStr);
     }
     else {
       NodeInfo()->GetPrefix(aStr);
     }
   }
+#endif
 
   PRUint32 HashValue() const
   {
     // mBits and PRUint32 might have different size. This should silence
     // any warnings or compile-errors. This is what the implementation of
     // NS_PTR_TO_INT32 does to take care of the same problem.
     return mBits - 0;
   }
--- a/content/base/src/nsAttrValue.h
+++ b/content/base/src/nsAttrValue.h
@@ -7,17 +7,17 @@
  * A struct that represents the value (type and actual data) of an
  * attribute.
  */
 
 #ifndef nsAttrValue_h___
 #define nsAttrValue_h___
 
 #include "nscore.h"
-#include "nsString.h"
+#include "nsStringGlue.h"
 #include "nsStringBuffer.h"
 #include "nsColor.h"
 #include "nsCaseTreatment.h"
 #include "nsMargin.h"
 #include "nsCOMPtr.h"
 #include "SVGAttrValueWrapper.h"
 
 typedef PRUptrdiff PtrBits;
--- a/content/base/src/nsContentList.h
+++ b/content/base/src/nsContentList.h
@@ -9,17 +9,17 @@
  * getElementsByTagName, some properties on nsIDOMHTMLDocument, etc).
  */
 
 #ifndef nsContentList_h___
 #define nsContentList_h___
 
 #include "nsISupports.h"
 #include "nsTArray.h"
-#include "nsString.h"
+#include "nsStringGlue.h"
 #include "nsIHTMLCollection.h"
 #include "nsIDOMNodeList.h"
 #include "nsINodeList.h"
 #include "nsStubMutationObserver.h"
 #include "nsIAtom.h"
 #include "nsINameSpaceManager.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsWrapperCache.h"
--- a/content/base/src/nsDOMAttributeMap.h
+++ b/content/base/src/nsDOMAttributeMap.h
@@ -6,17 +6,17 @@
 /*
  * Implementation of the |attributes| property of DOM Core's nsIDOMNode object.
  */
 
 #ifndef nsDOMAttributeMap_h___
 #define nsDOMAttributeMap_h___
 
 #include "nsIDOMNamedNodeMap.h"
-#include "nsString.h"
+#include "nsStringGlue.h"
 #include "nsRefPtrHashtable.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsIDOMNode.h"
 
 class nsIAtom;
 class nsDOMAttribute;
 class nsINodeInfo;
 class nsIDocument;
--- a/content/base/src/nsDOMTokenList.cpp
+++ b/content/base/src/nsDOMTokenList.cpp
@@ -9,18 +9,20 @@
 #include "nsDOMTokenList.h"
 
 #include "nsAttrValue.h"
 #include "nsContentUtils.h"
 #include "nsDOMError.h"
 #include "nsGenericElement.h"
 #include "dombindings.h"
 
+using namespace mozilla;
+using namespace mozilla::dom;
 
-nsDOMTokenList::nsDOMTokenList(nsGenericElement *aElement, nsIAtom* aAttrAtom)
+nsDOMTokenList::nsDOMTokenList(nsGenericElement* aElement, nsIAtom* aAttrAtom)
   : mElement(aElement),
     mAttrAtom(aAttrAtom)
 {
   // We don't add a reference to our element. If it goes away,
   // we'll be told to drop our reference
   SetIsDOMBinding();
 }
 
--- a/content/base/src/nsDocumentFragment.cpp
+++ b/content/base/src/nsDocumentFragment.cpp
@@ -2,82 +2,124 @@
 /* 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/. */
 
 /*
  * Implementation of DOM Core's nsIDOMDocumentFragment.
  */
 
-#include "nsISupports.h"
-#include "nsIContent.h"
 #include "nsIDOMDocumentFragment.h"
-#include "nsGenericElement.h"
+#include "mozilla/dom/FragmentOrElement.h"
+#include "nsGenericElement.h" // for DOMCI_NODE_DATA
 #include "nsINameSpaceManager.h"
 #include "nsINodeInfo.h"
 #include "nsNodeInfoManager.h"
 #include "nsDOMError.h"
 #include "nsGkAtoms.h"
 #include "nsDOMString.h"
 #include "nsContentUtils.h"
 
-class nsDocumentFragment : public nsGenericElement,
+using namespace mozilla;
+using namespace mozilla::dom;
+
+class nsDocumentFragment : public FragmentOrElement,
                            public nsIDOMDocumentFragment
 {
 public:
+  using FragmentOrElement::GetFirstChild;
+
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // interface nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericElement::)
+  NS_FORWARD_NSIDOMNODE(FragmentOrElement::)
 
   // interface nsIDOMDocumentFragment
   // NS_DECL_NSIDOCUMENTFRAGMENT  Empty
 
   nsDocumentFragment(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsDocumentFragment()
   {
   }
 
   // nsIContent
+  virtual already_AddRefed<nsINodeInfo>
+    GetExistingAttrNameFromQName(const nsAString& aStr) const
+  {
+    return nullptr;
+  }
+
   nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
                    const nsAString& aValue, bool aNotify)
   {
     return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify);
   }
   virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
                            nsIAtom* aPrefix, const nsAString& aValue,
                            bool aNotify)
   {
     return NS_OK;
   }
   virtual bool GetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, 
                          nsAString& aResult) const
   {
     return false;
   }
+  virtual bool HasAttr(PRInt32 aNameSpaceID, nsIAtom* aName) const
+  {
+    return false;
+  }
   virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute, 
                              bool aNotify)
   {
     return NS_OK;
   }
   virtual const nsAttrName* GetAttrNameAt(PRUint32 aIndex) const
   {
     return nullptr;
   }
+  virtual PRUint32 GetAttrCount() const
+  {
+    return 0;
+  }
 
   virtual bool IsNodeOfType(PRUint32 aFlags) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
 
   virtual nsIDOMNode* AsDOMNode() { return this; }
 
   virtual nsIAtom* DoGetID() const;
   virtual nsIAtom *GetIDAttributeName() const;
 
+  virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
+                              nsIContent* aBindingParent,
+                              bool aCompileEventHandlers)
+  {
+    NS_ASSERTION(false, "Trying to bind a fragment to a tree");
+    return NS_ERROR_NOT_IMPLEMENTED;
+  }
+
+  virtual void UnbindFromTree(bool aDeep, bool aNullParent)
+  {
+    NS_ASSERTION(false, "Trying to unbind a fragment from a tree");
+    return;
+  }
+
+  virtual Element* GetNameSpaceElement()
+  {
+    return nullptr;
+  }
+
+#ifdef DEBUG
+  virtual void List(FILE* out, PRInt32 aIndent) const;
+  virtual void DumpContent(FILE* out, PRInt32 aIndent, bool aDumpAll) const;
+#endif
+
 protected:
   nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 };
 
 nsresult
 NS_NewDocumentFragment(nsIDOMDocumentFragment** aInstancePtrResult,
                        nsNodeInfoManager *aNodeInfoManager)
 {
@@ -95,19 +137,23 @@ NS_NewDocumentFragment(nsIDOMDocumentFra
   }
 
   NS_ADDREF(*aInstancePtrResult = it);
 
   return NS_OK;
 }
 
 nsDocumentFragment::nsDocumentFragment(already_AddRefed<nsINodeInfo> aNodeInfo)
-  : nsGenericElement(aNodeInfo)
+  : FragmentOrElement(aNodeInfo)
 {
-  ClearIsElement();
+  NS_ABORT_IF_FALSE(mNodeInfo->NodeType() ==
+                    nsIDOMNode::DOCUMENT_FRAGMENT_NODE &&
+                    mNodeInfo->Equals(nsGkAtoms::documentFragmentNodeName,
+                                      kNameSpaceID_None),
+                    "Bad NodeType in aNodeInfo");
 }
 
 bool
 nsDocumentFragment::IsNodeOfType(PRUint32 aFlags) const
 {
   return !(aFlags & ~(eCONTENT | eDOCUMENT_FRAGMENT));
 }
 
@@ -118,16 +164,79 @@ nsDocumentFragment::DoGetID() const
 }
 
 nsIAtom*
 nsDocumentFragment::GetIDAttributeName() const
 {
   return nullptr;
 }
 
+#ifdef DEBUG
+void
+nsDocumentFragment::List(FILE* out, PRInt32 aIndent) const
+{
+  PRInt32 indent;
+  for (indent = aIndent; --indent >= 0; ) {
+    fputs("  ", out);
+  }
+
+  fprintf(out, "DocumentFragment@%p", (void *)this);
+
+  fprintf(out, " flags=[%08x]", static_cast<unsigned int>(GetFlags()));
+  fprintf(out, " refcount=%d<", mRefCnt.get());
+
+  nsIContent* child = GetFirstChild();
+  if (child) {
+    fputs("\n", out);
+
+    for (; child; child = child->GetNextSibling()) {
+      child->List(out, aIndent + 1);
+    }
+
+    for (indent = aIndent; --indent >= 0; ) {
+      fputs("  ", out);
+    }
+  }
+
+  fputs(">\n", out);
+}
+
+void
+nsDocumentFragment::DumpContent(FILE* out, PRInt32 aIndent,
+                                bool aDumpAll) const
+{
+  PRInt32 indent;
+  for (indent = aIndent; --indent >= 0; ) {
+    fputs("  ", out);
+  }
+
+  fputs("<DocumentFragment>", out);
+
+  if(aIndent) {
+    fputs("\n", out);
+  }
+
+  for (nsIContent* child = GetFirstChild();
+       child;
+       child = child->GetNextSibling()) {
+    PRInt32 indent = aIndent ? aIndent + 1 : 0;
+    child->DumpContent(out, indent, aDumpAll);
+  }
+  for (indent = aIndent; --indent >= 0; ) {
+    fputs("  ", out);
+  }
+  fputs("</DocumentFragment>", out);
+
+  if(aIndent) {
+    fputs("\n", out);
+  }
+}
+#endif
+
+
 DOMCI_NODE_DATA(DocumentFragment, nsDocumentFragment)
 
 // QueryInterface implementation for nsDocumentFragment
 NS_INTERFACE_MAP_BEGIN(nsDocumentFragment)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsDocumentFragment)
   NS_INTERFACE_MAP_ENTRY(nsIContent)
   NS_INTERFACE_MAP_ENTRY(nsINode)
@@ -141,12 +250,12 @@ NS_INTERFACE_MAP_BEGIN(nsDocumentFragmen
   // nsNodeSH::PreCreate() depends on the identity pointer being the
   // same as nsINode (which nsIContent inherits), so if you change the
   // below line, make sure nsNodeSH::PreCreate() still does the right
   // thing!
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContent)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DocumentFragment)
 NS_INTERFACE_MAP_END
 
-NS_IMPL_ADDREF_INHERITED(nsDocumentFragment, nsGenericElement)
-NS_IMPL_RELEASE_INHERITED(nsDocumentFragment, nsGenericElement)
+NS_IMPL_ADDREF_INHERITED(nsDocumentFragment, FragmentOrElement)
+NS_IMPL_RELEASE_INHERITED(nsDocumentFragment, FragmentOrElement)
 
 NS_IMPL_ELEMENT_CLONE(nsDocumentFragment)
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -124,22 +124,16 @@
 
 #include "mozilla/CORSMode.h"
 
 #include "nsStyledElement.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
-NS_DEFINE_IID(kThisPtrOffsetsSID, NS_THISPTROFFSETS_SID);
-
-PRInt32 nsIContent::sTabFocusModel = eTabFocus_any;
-bool nsIContent::sTabFocusModelAppliesToXUL = false;
-PRUint32 nsMutationGuard::sMutationCount = 0;
-
 nsEventStates
 Element::IntrinsicState() const
 {
   return IsEditable() ? NS_EVENT_STATE_MOZ_READWRITE :
                         NS_EVENT_STATE_MOZ_READONLY;
 }
 
 void
@@ -306,334 +300,16 @@ Element::ClearStyleStateLocks()
 
   DeleteProperty(nsGkAtoms::lockedStyleStates);
   ClearHasLockedStyleStates();
 
   NotifyStyleStateChange(locks);
 }
 
 nsIContent*
-nsIContent::FindFirstNonNativeAnonymous() const
-{
-  // This handles also nested native anonymous content.
-  for (const nsIContent *content = this; content;
-       content = content->GetBindingParent()) {
-    if (!content->IsInNativeAnonymousSubtree()) {
-      // Oops, this function signature allows casting const to
-      // non-const.  (Then again, so does GetChildAt(0)->GetParent().)
-      return const_cast<nsIContent*>(content);
-    }
-  }
-  return nullptr;
-}
-
-nsIContent*
-nsIContent::GetFlattenedTreeParent() const
-{
-  nsIContent *parent = GetParent();
-  if (parent && parent->HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
-    nsIDocument *doc = parent->OwnerDoc();
-    nsIContent* insertionElement =
-      doc->BindingManager()->GetNestedInsertionPoint(parent, this);
-    if (insertionElement) {
-      parent = insertionElement;
-    }
-  }
-  return parent;
-}
-
-nsIContent::IMEState
-nsIContent::GetDesiredIMEState()
-{
-  if (!IsEditableInternal()) {
-    // Check for the special case where we're dealing with elements which don't
-    // have the editable flag set, but are readwrite (such as text controls).
-    if (!IsElement() ||
-        !AsElement()->State().HasState(NS_EVENT_STATE_MOZ_READWRITE)) {
-      return IMEState(IMEState::DISABLED);
-    }
-  }
-  // NOTE: The content for independent editors (e.g., input[type=text],
-  // textarea) must override this method, so, we don't need to worry about
-  // that here.
-  nsIContent *editableAncestor = GetEditingHost();
-
-  // This is in another editable content, use the result of it.
-  if (editableAncestor && editableAncestor != this) {
-    return editableAncestor->GetDesiredIMEState();
-  }
-  nsIDocument* doc = GetCurrentDoc();
-  if (!doc) {
-    return IMEState(IMEState::DISABLED);
-  }
-  nsIPresShell* ps = doc->GetShell();
-  if (!ps) {
-    return IMEState(IMEState::DISABLED);
-  }
-  nsPresContext* pc = ps->GetPresContext();
-  if (!pc) {
-    return IMEState(IMEState::DISABLED);
-  }
-  nsIEditor* editor = nsContentUtils::GetHTMLEditor(pc);
-  nsCOMPtr<nsIEditorIMESupport> imeEditor = do_QueryInterface(editor);
-  if (!imeEditor) {
-    return IMEState(IMEState::DISABLED);
-  }
-  IMEState state;
-  imeEditor->GetPreferredIMEState(&state);
-  return state;
-}
-
-bool
-nsIContent::HasIndependentSelection()
-{
-  nsIFrame* frame = GetPrimaryFrame();
-  return (frame && frame->GetStateBits() & NS_FRAME_INDEPENDENT_SELECTION);
-}
-
-dom::Element*
-nsIContent::GetEditingHost()
-{
-  // If this isn't editable, return NULL.
-  NS_ENSURE_TRUE(IsEditableInternal(), nullptr);
-
-  nsIDocument* doc = GetCurrentDoc();
-  NS_ENSURE_TRUE(doc, nullptr);
-  // If this is in designMode, we should return <body>
-  if (doc->HasFlag(NODE_IS_EDITABLE)) {
-    return doc->GetBodyElement();
-  }
-
-  nsIContent* content = this;
-  for (dom::Element* parent = GetElementParent();
-       parent && parent->HasFlag(NODE_IS_EDITABLE);
-       parent = content->GetElementParent()) {
-    content = parent;
-  }
-  return content->AsElement();
-}
-
-nsresult
-nsIContent::LookupNamespaceURIInternal(const nsAString& aNamespacePrefix,
-                                       nsAString& aNamespaceURI) const
-{
-  if (aNamespacePrefix.EqualsLiteral("xml")) {
-    // Special-case for xml prefix
-    aNamespaceURI.AssignLiteral("http://www.w3.org/XML/1998/namespace");
-    return NS_OK;
-  }
-
-  if (aNamespacePrefix.EqualsLiteral("xmlns")) {
-    // Special-case for xmlns prefix
-    aNamespaceURI.AssignLiteral("http://www.w3.org/2000/xmlns/");
-    return NS_OK;
-  }
-
-  nsCOMPtr<nsIAtom> name;
-  if (!aNamespacePrefix.IsEmpty()) {
-    name = do_GetAtom(aNamespacePrefix);
-    NS_ENSURE_TRUE(name, NS_ERROR_OUT_OF_MEMORY);
-  }
-  else {
-    name = nsGkAtoms::xmlns;
-  }
-  // Trace up the content parent chain looking for the namespace
-  // declaration that declares aNamespacePrefix.
-  const nsIContent* content = this;
-  do {
-    if (content->GetAttr(kNameSpaceID_XMLNS, name, aNamespaceURI))
-      return NS_OK;
-  } while ((content = content->GetParent()));
-  return NS_ERROR_FAILURE;
-}
-
-already_AddRefed<nsIURI>
-nsIContent::GetBaseURI() const
-{
-  nsIDocument* doc = OwnerDoc();
-  // Start with document base
-  nsCOMPtr<nsIURI> base = doc->GetDocBaseURI();
-
-  // Collect array of xml:base attribute values up the parent chain. This
-  // is slightly slower for the case when there are xml:base attributes, but
-  // faster for the far more common case of there not being any such
-  // attributes.
-  // Also check for SVG elements which require special handling
-  nsAutoTArray<nsString, 5> baseAttrs;
-  nsString attr;
-  const nsIContent *elem = this;
-  do {
-    // First check for SVG specialness (why is this SVG specific?)
-    if (elem->IsSVG()) {
-      nsIContent* bindingParent = elem->GetBindingParent();
-      if (bindingParent) {
-        nsXBLBinding* binding =
-          bindingParent->OwnerDoc()->BindingManager()->GetBinding(bindingParent);
-        if (binding) {
-          // XXX sXBL/XBL2 issue
-          // If this is an anonymous XBL element use the binding
-          // document for the base URI. 
-          // XXX Will fail with xml:base
-          base = binding->PrototypeBinding()->DocURI();
-          break;
-        }
-      }
-    }
-
-    nsIURI* explicitBaseURI = elem->GetExplicitBaseURI();
-    if (explicitBaseURI) {
-      base = explicitBaseURI;
-      break;
-    }
-    
-    // Otherwise check for xml:base attribute
-    elem->GetAttr(kNameSpaceID_XML, nsGkAtoms::base, attr);
-    if (!attr.IsEmpty()) {
-      baseAttrs.AppendElement(attr);
-    }
-    elem = elem->GetParent();
-  } while(elem);
-  
-  // Now resolve against all xml:base attrs
-  for (PRUint32 i = baseAttrs.Length() - 1; i != PRUint32(-1); --i) {
-    nsCOMPtr<nsIURI> newBase;
-    nsresult rv = NS_NewURI(getter_AddRefs(newBase), baseAttrs[i],
-                            doc->GetDocumentCharacterSet().get(), base);
-    // Do a security check, almost the same as nsDocument::SetBaseURL()
-    // Only need to do this on the final uri
-    if (NS_SUCCEEDED(rv) && i == 0) {
-      rv = nsContentUtils::GetSecurityManager()->
-        CheckLoadURIWithPrincipal(NodePrincipal(), newBase,
-                                  nsIScriptSecurityManager::STANDARD);
-    }
-    if (NS_SUCCEEDED(rv)) {
-      base.swap(newBase);
-    }
-  }
-
-  return base.forget();
-}
-
-//----------------------------------------------------------------------
-
-static inline JSObject*
-GetJSObjectChild(nsWrapperCache* aCache)
-{
-  return aCache->PreservingWrapper() ? aCache->GetWrapperPreserveColor() : NULL;
-}
-
-static bool
-NeedsScriptTraverse(nsWrapperCache* aCache)
-{
-  JSObject* o = GetJSObjectChild(aCache);
-  return o && xpc_IsGrayGCThing(o);
-}
-
-//----------------------------------------------------------------------
-
-NS_IMPL_CYCLE_COLLECTING_ADDREF(nsChildContentList)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(nsChildContentList)
-
-// If nsChildContentList is changed so that any additional fields are
-// traversed by the cycle collector, then CAN_SKIP must be updated to
-// check that the additional fields are null.
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(nsChildContentList)
-
-// nsChildContentList only ever has a single child, its wrapper, so if
-// the wrapper is black, the list can't be part of a garbage cycle.
-NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsChildContentList)
-  return !NeedsScriptTraverse(tmp);
-NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
-
-NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(nsChildContentList)
-  return !NeedsScriptTraverse(tmp);
-NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END
-
-// CanSkipThis returns false to avoid problems with incomplete unlinking.
-NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(nsChildContentList)
-NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
-
-NS_INTERFACE_TABLE_HEAD(nsChildContentList)
-  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
-  NS_NODELIST_OFFSET_AND_INTERFACE_TABLE_BEGIN(nsChildContentList)
-    NS_INTERFACE_TABLE_ENTRY(nsChildContentList, nsINodeList)
-    NS_INTERFACE_TABLE_ENTRY(nsChildContentList, nsIDOMNodeList)
-  NS_OFFSET_AND_INTERFACE_TABLE_END
-  NS_OFFSET_AND_INTERFACE_TABLE_TO_MAP_SEGUE
-  NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsChildContentList)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(NodeList)
-NS_INTERFACE_MAP_END
-
-JSObject*
-nsChildContentList::WrapObject(JSContext *cx, JSObject *scope,
-                               bool *triedToWrap)
-{
-  return mozilla::dom::binding::NodeList::create(cx, scope, this, triedToWrap);
-}
-
-NS_IMETHODIMP
-nsChildContentList::GetLength(PRUint32* aLength)
-{
-  *aLength = mNode ? mNode->GetChildCount() : 0;
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsChildContentList::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
-{
-  nsINode* node = GetNodeAt(aIndex);
-  if (!node) {
-    *aReturn = nullptr;
-
-    return NS_OK;
-  }
-
-  return CallQueryInterface(node, aReturn);
-}
-
-nsIContent*
-nsChildContentList::GetNodeAt(PRUint32 aIndex)
-{
-  if (mNode) {
-    return mNode->GetChildAt(aIndex);
-  }
-
-  return nullptr;
-}
-
-PRInt32
-nsChildContentList::IndexOf(nsIContent* aContent)
-{
-  if (mNode) {
-    return mNode->IndexOf(aContent);
-  }
-
-  return -1;
-}
-
-//----------------------------------------------------------------------
-
-NS_IMPL_CYCLE_COLLECTION_1(nsNode3Tearoff, mNode)
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsNode3Tearoff)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMXPathNSResolver)
-NS_INTERFACE_MAP_END_AGGREGATED(mNode)
-
-NS_IMPL_CYCLE_COLLECTING_ADDREF(nsNode3Tearoff)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(nsNode3Tearoff)
-
-NS_IMETHODIMP
-nsNode3Tearoff::LookupNamespaceURI(const nsAString& aNamespacePrefix,
-                                   nsAString& aNamespaceURI)
-{
-  return mNode->LookupNamespaceURI(aNamespacePrefix, aNamespaceURI);
-}
-
-nsIContent*
 nsGenericElement::GetFirstElementChild()
 {
   nsAttrAndChildArray& children = mAttrsAndChildren;
   PRUint32 i, count = children.ChildCount();
   for (i = 0; i < count; ++i) {
     nsIContent* child = children.ChildAt(i);
     if (child->IsElement()) {
       return child;
@@ -768,30 +444,16 @@ nsGenericElement::GetNextElementSibling(
 {
   *aResult = nullptr;
 
   nsIContent *result = GetNextElementSibling();
 
   return result ? CallQueryInterface(result, aResult) : NS_OK;
 }
 
-nsContentList*
-nsGenericElement::GetChildrenList()
-{
-  nsGenericElement::nsDOMSlots *slots = DOMSlots();
-
-  if (!slots->mChildrenList) {
-    slots->mChildrenList = new nsContentList(this, kNameSpaceID_Wildcard, 
-                                             nsGkAtoms::_asterix, nsGkAtoms::_asterix,
-                                             false);
-  }
-
-  return slots->mChildrenList;
-}
-
 nsDOMTokenList*
 nsGenericElement::GetClassList(nsresult *aResult)
 {
   *aResult = NS_ERROR_OUT_OF_MEMORY;
 
   nsGenericElement::nsDOMSlots *slots = DOMSlots();
 
   if (!slots->mClassList) {
@@ -1183,353 +845,25 @@ nsGenericElement::GetClientRects(nsIDOMC
   *aResult = rectList.forget().get();
   return NS_OK;
 }
 
 
 //----------------------------------------------------------------------
 
 
-NS_IMPL_ISUPPORTS1(nsNodeWeakReference,
-                   nsIWeakReference)
-
-nsNodeWeakReference::~nsNodeWeakReference()
-{
-  if (mNode) {
-    NS_ASSERTION(mNode->GetSlots() &&
-                 mNode->GetSlots()->mWeakReference == this,
-                 "Weak reference has wrong value");
-    mNode->GetSlots()->mWeakReference = nullptr;
-  }
-}
-
-NS_IMETHODIMP
-nsNodeWeakReference::QueryReferent(const nsIID& aIID, void** aInstancePtr)
-{
-  return mNode ? mNode->QueryInterface(aIID, aInstancePtr) :
-                 NS_ERROR_NULL_POINTER;
-}
-
-
-NS_IMPL_CYCLE_COLLECTION_1(nsNodeSupportsWeakRefTearoff, mNode)
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsNodeSupportsWeakRefTearoff)
-  NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
-NS_INTERFACE_MAP_END_AGGREGATED(mNode)
-
-NS_IMPL_CYCLE_COLLECTING_ADDREF(nsNodeSupportsWeakRefTearoff)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(nsNodeSupportsWeakRefTearoff)
-
-NS_IMETHODIMP
-nsNodeSupportsWeakRefTearoff::GetWeakReference(nsIWeakReference** aInstancePtr)
-{
-  nsINode::nsSlots* slots = mNode->GetSlots();
-  NS_ENSURE_TRUE(slots, NS_ERROR_OUT_OF_MEMORY);
-
-  if (!slots->mWeakReference) {
-    slots->mWeakReference = new nsNodeWeakReference(mNode);
-    NS_ENSURE_TRUE(slots->mWeakReference, NS_ERROR_OUT_OF_MEMORY);
-  }
-
-  NS_ADDREF(*aInstancePtr = slots->mWeakReference);
-
-  return NS_OK;
-}
-
-//----------------------------------------------------------------------
-
-NS_IMPL_CYCLE_COLLECTION_1(nsNodeSelectorTearoff, mNode)
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsNodeSelectorTearoff)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMNodeSelector)
-NS_INTERFACE_MAP_END_AGGREGATED(mNode)
-
-NS_IMPL_CYCLE_COLLECTING_ADDREF(nsNodeSelectorTearoff)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(nsNodeSelectorTearoff)
-
-NS_IMETHODIMP
-nsNodeSelectorTearoff::QuerySelector(const nsAString& aSelector,
-                                     nsIDOMElement **aReturn)
-{
-  nsresult rv;
-  nsIContent* result = nsGenericElement::doQuerySelector(mNode, aSelector, &rv);
-  return result ? CallQueryInterface(result, aReturn) : rv;
-}
-
-NS_IMETHODIMP
-nsNodeSelectorTearoff::QuerySelectorAll(const nsAString& aSelector,
-                                        nsIDOMNodeList **aReturn)
-{
-  return nsGenericElement::doQuerySelectorAll(mNode, aSelector, aReturn);
-}
-
-//----------------------------------------------------------------------
-
-NS_IMPL_CYCLE_COLLECTION_1(nsTouchEventReceiverTearoff, mElement)
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsTouchEventReceiverTearoff)
-  NS_INTERFACE_MAP_ENTRY(nsITouchEventReceiver)
-NS_INTERFACE_MAP_END_AGGREGATED(mElement)
-
-NS_IMPL_CYCLE_COLLECTING_ADDREF(nsTouchEventReceiverTearoff)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(nsTouchEventReceiverTearoff)
-
-//----------------------------------------------------------------------
-
-NS_IMPL_CYCLE_COLLECTION_1(nsInlineEventHandlersTearoff, mElement)
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsInlineEventHandlersTearoff)
-  NS_INTERFACE_MAP_ENTRY(nsIInlineEventHandlers)
-NS_INTERFACE_MAP_END_AGGREGATED(mElement)
-
-NS_IMPL_CYCLE_COLLECTING_ADDREF(nsInlineEventHandlersTearoff)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(nsInlineEventHandlersTearoff)
-
-//----------------------------------------------------------------------
-nsGenericElement::nsDOMSlots::nsDOMSlots()
-  : nsINode::nsSlots(),
-    mDataset(nullptr),
-    mBindingParent(nullptr)
-{
-}
-
-nsGenericElement::nsDOMSlots::~nsDOMSlots()
-{
-  if (mAttributeMap) {
-    mAttributeMap->DropReference();
-  }
-
-  if (mClassList) {
-    mClassList->DropReference();
-  }
-}
-
-void
-nsGenericElement::nsDOMSlots::Traverse(nsCycleCollectionTraversalCallback &cb, bool aIsXUL)
-{
-  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mStyle");
-  cb.NoteXPCOMChild(mStyle.get());
-
-  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mSMILOverrideStyle");
-  cb.NoteXPCOMChild(mSMILOverrideStyle.get());
-
-  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mAttributeMap");
-  cb.NoteXPCOMChild(mAttributeMap.get());
-
-  if (aIsXUL) {
-    NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mControllers");
-    cb.NoteXPCOMChild(mControllers);
-  }
-
-  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mChildrenList");
-  cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIDOMNodeList*, mChildrenList));
-
-  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mClassList");
-  cb.NoteXPCOMChild(mClassList.get());
-}
-
-void
-nsGenericElement::nsDOMSlots::Unlink(bool aIsXUL)
-{
-  mStyle = nullptr;
-  mSMILOverrideStyle = nullptr;
-  if (mAttributeMap) {
-    mAttributeMap->DropReference();
-    mAttributeMap = nullptr;
-  }
-  if (aIsXUL)
-    NS_IF_RELEASE(mControllers);
-  mChildrenList = nullptr;
-  if (mClassList) {
-    mClassList->DropReference();
-    mClassList = nullptr;
-  }
-}
-
 nsGenericElement::nsGenericElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : Element(aNodeInfo)
 {
-  NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::ELEMENT_NODE ||
-                    (mNodeInfo->NodeType() ==
-                       nsIDOMNode::DOCUMENT_FRAGMENT_NODE &&
-                     mNodeInfo->Equals(nsGkAtoms::documentFragmentNodeName,
-                                       kNameSpaceID_None)),
+  NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::ELEMENT_NODE,
                     "Bad NodeType in aNodeInfo");
 
   SetIsElement();
 }
 
-nsGenericElement::~nsGenericElement()
-{
-  NS_PRECONDITION(!IsInDoc(),
-                  "Please remove this from the document properly");
-  if (GetParent()) {
-    NS_RELEASE(mParent);
-  }
-}
-
-NS_IMETHODIMP
-nsGenericElement::GetNodeName(nsAString& aNodeName)
-{
-  aNodeName = NodeName();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsGenericElement::GetLocalName(nsAString& aLocalName)
-{
-  aLocalName = LocalName();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsGenericElement::GetNodeValue(nsAString& aNodeValue)
-{
-  SetDOMStringToNull(aNodeValue);
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsGenericElement::SetNodeValue(const nsAString& aNodeValue)
-{
-  // The DOM spec says that when nodeValue is defined to be null "setting it
-  // has no effect", so we don't throw an exception.
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsGenericElement::GetNodeType(PRUint16* aNodeType)
-{
-  *aNodeType = NodeType();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsGenericElement::GetNamespaceURI(nsAString& aNamespaceURI)
-{
-  return mNodeInfo->GetNamespaceURI(aNamespaceURI);
-}
-
-NS_IMETHODIMP
-nsGenericElement::GetPrefix(nsAString& aPrefix)
-{
-  mNodeInfo->GetPrefix(aPrefix);
-  return NS_OK;
-}
-
-nsresult
-nsGenericElement::InternalIsSupported(nsISupports* aObject,
-                                      const nsAString& aFeature,
-                                      const nsAString& aVersion,
-                                      bool* aReturn)
-{
-  NS_ENSURE_ARG_POINTER(aReturn);
-  *aReturn = false;
-
-  // Convert the incoming UTF16 strings to raw char*'s to save us some
-  // code when doing all those string compares.
-  NS_ConvertUTF16toUTF8 feature(aFeature);
-  NS_ConvertUTF16toUTF8 version(aVersion);
-
-  const char *f = feature.get();
-  const char *v = version.get();
-
-  if (PL_strcasecmp(f, "XML") == 0 ||
-      PL_strcasecmp(f, "HTML") == 0) {
-    if (aVersion.IsEmpty() ||
-        PL_strcmp(v, "1.0") == 0 ||
-        PL_strcmp(v, "2.0") == 0) {
-      *aReturn = true;
-    }
-  } else if (PL_strcasecmp(f, "Views") == 0 ||
-             PL_strcasecmp(f, "StyleSheets") == 0 ||
-             PL_strcasecmp(f, "Core") == 0 ||
-             PL_strcasecmp(f, "CSS") == 0 ||
-             PL_strcasecmp(f, "CSS2") == 0 ||
-             PL_strcasecmp(f, "Events") == 0 ||
-             PL_strcasecmp(f, "UIEvents") == 0 ||
-             PL_strcasecmp(f, "MouseEvents") == 0 ||
-             // Non-standard!
-             PL_strcasecmp(f, "MouseScrollEvents") == 0 ||
-             PL_strcasecmp(f, "HTMLEvents") == 0 ||
-             PL_strcasecmp(f, "Range") == 0 ||
-             PL_strcasecmp(f, "XHTML") == 0) {
-    if (aVersion.IsEmpty() ||
-        PL_strcmp(v, "2.0") == 0) {
-      *aReturn = true;
-    }
-  } else if (PL_strcasecmp(f, "XPath") == 0) {
-    if (aVersion.IsEmpty() ||
-        PL_strcmp(v, "3.0") == 0) {
-      *aReturn = true;
-    }
-  } else if (PL_strcasecmp(f, "SVGEvents") == 0 ||
-             PL_strcasecmp(f, "SVGZoomEvents") == 0 ||
-             nsSVGFeatures::HasFeature(aObject, aFeature)) {
-    if (aVersion.IsEmpty() ||
-        PL_strcmp(v, "1.0") == 0 ||
-        PL_strcmp(v, "1.1") == 0) {
-      *aReturn = true;
-    }
-  }
-  else if (NS_SMILEnabled() && PL_strcasecmp(f, "TimeControl") == 0) {
-    if (aVersion.IsEmpty() || PL_strcmp(v, "1.0") == 0) {
-      *aReturn = true;
-    }
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsGenericElement::IsSupported(const nsAString& aFeature,
-                              const nsAString& aVersion,
-                              bool* aReturn)
-{
-  return InternalIsSupported(this, aFeature, aVersion, aReturn);
-}
-
-NS_IMETHODIMP
-nsGenericElement::HasAttributes(bool* aReturn)
-{
-  NS_ENSURE_ARG_POINTER(aReturn);
-
-  *aReturn = GetAttrCount() > 0;
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsGenericElement::GetAttributes(nsIDOMNamedNodeMap** aAttributes)
-{
-  if (!IsElement()) {
-    *aAttributes = nullptr;
-    return NS_OK;
-  }
-
-  nsDOMSlots *slots = DOMSlots();
-
-  if (!slots->mAttributeMap) {
-    slots->mAttributeMap = new nsDOMAttributeMap(this);
-  }
-
-  NS_ADDREF(*aAttributes = slots->mAttributeMap);
-
-  return NS_OK;
-}
-
-nsresult
-nsGenericElement::HasChildNodes(bool* aReturn)
-{
-  *aReturn = mAttrsAndChildren.ChildCount() > 0;
-
-  return NS_OK;
-}
-
 NS_IMETHODIMP
 nsGenericElement::GetTagName(nsAString& aTagName)
 {
   aTagName = NodeName();
   return NS_OK;
 }
 
 nsresult
@@ -2221,227 +1555,16 @@ nsGenericElement::UnbindFromTree(bool aD
       // parent, though, since this only walks non-anonymous kids.
       mAttrsAndChildren.ChildAt(i)->UnbindFromTree(true, false);
     }
   }
 
   nsNodeUtils::ParentChainChanged(this);
 }
 
-already_AddRefed<nsINodeList>
-nsGenericElement::GetChildren(PRUint32 aFilter)
-{
-  nsRefPtr<nsSimpleContentList> list = new nsSimpleContentList(this);
-  if (!list) {
-    return nullptr;
-  }
-
-  nsIFrame *frame = GetPrimaryFrame();
-
-  // Append :before generated content.
-  if (frame) {
-    nsIFrame *beforeFrame = nsLayoutUtils::GetBeforeFrame(frame);
-    if (beforeFrame) {
-      list->AppendElement(beforeFrame->GetContent());
-    }
-  }
-
-  // If XBL is bound to this node then append XBL anonymous content including
-  // explict content altered by insertion point if we were requested for XBL
-  // anonymous content, otherwise append explicit content with respect to
-  // insertion point if any.
-  nsINodeList *childList = nullptr;
-
-  nsIDocument* document = OwnerDoc();
-  if (!(aFilter & eAllButXBL)) {
-    childList = document->BindingManager()->GetXBLChildNodesFor(this);
-    if (!childList) {
-      childList = GetChildNodesList();
-    }
-
-  } else {
-    childList = document->BindingManager()->GetContentListFor(this);
-  }
-
-  if (childList) {
-    PRUint32 length = 0;
-    childList->GetLength(&length);
-    for (PRUint32 idx = 0; idx < length; idx++) {
-      nsIContent* child = childList->GetNodeAt(idx);
-      list->AppendElement(child);
-    }
-  }
-
-  if (frame) {
-    // Append native anonymous content to the end.
-    nsIAnonymousContentCreator* creator = do_QueryFrame(frame);
-    if (creator) {
-      creator->AppendAnonymousContentTo(*list, aFilter);
-    }
-
-    // Append :after generated content.
-    nsIFrame *afterFrame = nsLayoutUtils::GetAfterFrame(frame);
-    if (afterFrame) {
-      list->AppendElement(afterFrame->GetContent());
-    }
-  }
-
-  nsINodeList* returnList = nullptr;
-  list.forget(&returnList);
-  return returnList;
-}
-
-static nsIContent*
-FindNativeAnonymousSubtreeOwner(nsIContent* aContent)
-{
-  if (aContent->IsInNativeAnonymousSubtree()) {
-    bool isNativeAnon = false;
-    while (aContent && !isNativeAnon) {
-      isNativeAnon = aContent->IsRootOfNativeAnonymousSubtree();
-      aContent = aContent->GetParent();
-    }
-  }
-  return aContent;
-}
-
-nsresult
-nsIContent::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
-{
-  //FIXME! Document how this event retargeting works, Bug 329124.
-  aVisitor.mCanHandle = true;
-  aVisitor.mMayHaveListenerManager = HasListenerManager();
-
-  // Don't propagate mouseover and mouseout events when mouse is moving
-  // inside native anonymous content.
-  bool isAnonForEvents = IsRootOfNativeAnonymousSubtree();
-  if ((aVisitor.mEvent->message == NS_MOUSE_ENTER_SYNTH ||
-       aVisitor.mEvent->message == NS_MOUSE_EXIT_SYNTH) &&
-      // Check if we should stop event propagation when event has just been
-      // dispatched or when we're about to propagate from
-      // native anonymous subtree.
-      ((this == aVisitor.mEvent->originalTarget &&
-        !IsInNativeAnonymousSubtree()) || isAnonForEvents)) {
-     nsCOMPtr<nsIContent> relatedTarget =
-       do_QueryInterface(static_cast<nsMouseEvent*>
-                                    (aVisitor.mEvent)->relatedTarget);
-    if (relatedTarget &&
-        relatedTarget->OwnerDoc() == OwnerDoc()) {
-
-      // If current target is anonymous for events or we know that related
-      // target is descendant of an element which is anonymous for events,
-      // we may want to stop event propagation.
-      // If this is the original target, aVisitor.mRelatedTargetIsInAnon
-      // must be updated.
-      if (isAnonForEvents || aVisitor.mRelatedTargetIsInAnon ||
-          (aVisitor.mEvent->originalTarget == this &&
-           (aVisitor.mRelatedTargetIsInAnon =
-            relatedTarget->IsInNativeAnonymousSubtree()))) {
-        nsIContent* anonOwner = FindNativeAnonymousSubtreeOwner(this);
-        if (anonOwner) {
-          nsIContent* anonOwnerRelated =
-            FindNativeAnonymousSubtreeOwner(relatedTarget);
-          if (anonOwnerRelated) {
-            // Note, anonOwnerRelated may still be inside some other
-            // native anonymous subtree. The case where anonOwner is still
-            // inside native anonymous subtree will be handled when event
-            // propagates up in the DOM tree.
-            while (anonOwner != anonOwnerRelated &&
-                   anonOwnerRelated->IsInNativeAnonymousSubtree()) {
-              anonOwnerRelated = FindNativeAnonymousSubtreeOwner(anonOwnerRelated);
-            }
-            if (anonOwner == anonOwnerRelated) {
-#ifdef DEBUG_smaug
-              nsCOMPtr<nsIContent> originalTarget =
-                do_QueryInterface(aVisitor.mEvent->originalTarget);
-              nsAutoString ot, ct, rt;
-              if (originalTarget) {
-                originalTarget->Tag()->ToString(ot);
-              }
-              Tag()->ToString(ct);
-              relatedTarget->Tag()->ToString(rt);
-              printf("Stopping %s propagation:"
-                     "\n\toriginalTarget=%s \n\tcurrentTarget=%s %s"
-                     "\n\trelatedTarget=%s %s \n%s",
-                     (aVisitor.mEvent->message == NS_MOUSE_ENTER_SYNTH)
-                       ? "mouseover" : "mouseout",
-                     NS_ConvertUTF16toUTF8(ot).get(),
-                     NS_ConvertUTF16toUTF8(ct).get(),
-                     isAnonForEvents
-                       ? "(is native anonymous)"
-                       : (IsInNativeAnonymousSubtree()
-                           ? "(is in native anonymous subtree)" : ""),
-                     NS_ConvertUTF16toUTF8(rt).get(),
-                     relatedTarget->IsInNativeAnonymousSubtree()
-                       ? "(is in native anonymous subtree)" : "",
-                     (originalTarget && relatedTarget->FindFirstNonNativeAnonymous() ==
-                       originalTarget->FindFirstNonNativeAnonymous())
-                       ? "" : "Wrong event propagation!?!\n");
-#endif
-              aVisitor.mParentTarget = nullptr;
-              // Event should not propagate to non-anon content.
-              aVisitor.mCanHandle = isAnonForEvents;
-              return NS_OK;
-            }
-          }
-        }
-      }
-    }
-  }
-
-  nsIContent* parent = GetParent();
-  // Event may need to be retargeted if this is the root of a native
-  // anonymous content subtree or event is dispatched somewhere inside XBL.
-  if (isAnonForEvents) {
-    // If a DOM event is explicitly dispatched using node.dispatchEvent(), then
-    // all the events are allowed even in the native anonymous content..
-    NS_ASSERTION(aVisitor.mEvent->eventStructType != NS_MUTATION_EVENT ||
-                 aVisitor.mDOMEvent,
-                 "Mutation event dispatched in native anonymous content!?!");
-    aVisitor.mEventTargetAtParent = parent;
-  } else if (parent && aVisitor.mOriginalTargetIsInAnon) {
-    nsCOMPtr<nsIContent> content(do_QueryInterface(aVisitor.mEvent->target));
-    if (content && content->GetBindingParent() == parent) {
-      aVisitor.mEventTargetAtParent = parent;
-    }
-  }
-
-  // check for an anonymous parent
-  // XXX XBL2/sXBL issue
-  if (HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
-    nsIContent* insertionParent = OwnerDoc()->BindingManager()->
-      GetInsertionParent(this);
-    NS_ASSERTION(!(aVisitor.mEventTargetAtParent && insertionParent &&
-                   aVisitor.mEventTargetAtParent != insertionParent),
-                 "Retargeting and having insertion parent!");
-    if (insertionParent) {
-      parent = insertionParent;
-    }
-  }
-
-  if (parent) {
-    aVisitor.mParentTarget = parent;
-  } else {
-    aVisitor.mParentTarget = GetCurrentDoc();
-  }
-  return NS_OK;
-}
-
-const nsAttrValue*
-nsGenericElement::DoGetClasses() const
-{
-  NS_NOTREACHED("Shouldn't ever be called");
-  return nullptr;
-}
-
-NS_IMETHODIMP
-nsGenericElement::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
-{
-  return NS_OK;
-}
-
 nsICSSDeclaration*
 nsGenericElement::GetSMILOverrideStyle()
 {
   nsGenericElement::nsDOMSlots *slots = DOMSlots();
 
   if (!slots->mSMILOverrideStyle) {
     slots->mSMILOverrideStyle = new nsDOMCSSAttributeDeclaration(this, true);
   }
@@ -2553,23 +1676,16 @@ nsGenericElement::GetExistingAttrNameFro
   }
   else {
     NS_ADDREF(nodeInfo = name->NodeInfo());
   }
 
   return nodeInfo;
 }
 
-bool
-nsGenericElement::IsLink(nsIURI** aURI) const
-{
-  *aURI = nullptr;
-  return false;
-}
-
 // static
 bool
 nsGenericElement::ShouldBlur(nsIContent *aContent)
 {
   // Determine if the current element is focused, if it is not focused
   // then we should not try to blur
   nsIDocument *document = aContent->GetDocument();
   if (!document)
@@ -2585,67 +1701,22 @@ nsGenericElement::ShouldBlur(nsIContent 
   if (contentToBlur == aContent)
     return true;
 
   // if focus on this element would get redirected, then check the redirected
   // content as well when blurring.
   return (contentToBlur && nsFocusManager::GetRedirectedFocus(aContent) == contentToBlur);
 }
 
-nsIContent*
-nsGenericElement::GetBindingParent() const
-{
-  nsDOMSlots *slots = GetExistingDOMSlots();
-
-  if (slots) {
-    return slots->mBindingParent;
-  }
-  return nullptr;
-}
-
 bool
 nsGenericElement::IsNodeOfType(PRUint32 aFlags) const
 {
   return !(aFlags & ~eCONTENT);
 }
 
-nsresult
-nsGenericElement::InsertChildAt(nsIContent* aKid,
-                                PRUint32 aIndex,
-                                bool aNotify)
-{
-  NS_PRECONDITION(aKid, "null ptr");
-
-  return doInsertChildAt(aKid, aIndex, aNotify, mAttrsAndChildren);
-}
-
-void
-nsGenericElement::RemoveChildAt(PRUint32 aIndex, bool aNotify)
-{
-  nsCOMPtr<nsIContent> oldKid = mAttrsAndChildren.GetSafeChildAt(aIndex);
-  NS_ASSERTION(oldKid == GetChildAt(aIndex), "Unexpected child in RemoveChildAt");
-
-  if (oldKid) {
-    doRemoveChildAt(aIndex, aNotify, oldKid, mAttrsAndChildren);
-  }
-}
-
-NS_IMETHODIMP
-nsGenericElement::GetTextContent(nsAString &aTextContent)
-{
-  nsContentUtils::GetNodeTextContent(this, true, aTextContent);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsGenericElement::SetTextContent(const nsAString& aTextContent)
-{
-  return nsContentUtils::SetNodeTextContent(this, aTextContent, false);
-}
-
 /* static */
 nsresult
 nsGenericElement::DispatchEvent(nsPresContext* aPresContext,
                                 nsEvent* aEvent,
                                 nsIContent* aTarget,
                                 bool aFullDispatch,
                                 nsEventStatus* aStatus)
 {
@@ -2714,813 +1785,16 @@ nsGenericElement::GetPrimaryFrame(mozFlu
 
   // Cause a flush, so we get up-to-date frame
   // information
   doc->FlushPendingNotifications(aType);
 
   return GetPrimaryFrame();
 }
 
-void
-nsGenericElement::DestroyContent()
-{
-  nsIDocument *document = OwnerDoc();
-  document->BindingManager()->RemovedFromDocument(this, document);
-  document->ClearBoxObjectFor(this);
-
-  // XXX We really should let cycle collection do this, but that currently still
-  //     leaks (see https://bugzilla.mozilla.org/show_bug.cgi?id=406684).
-  nsContentUtils::ReleaseWrapper(this, this);
-
-  PRUint32 i, count = mAttrsAndChildren.ChildCount();
-  for (i = 0; i < count; ++i) {
-    // The child can remove itself from the parent in BindToTree.
-    mAttrsAndChildren.ChildAt(i)->DestroyContent();
-  }
-}
-
-void
-nsGenericElement::SaveSubtreeState()
-{
-  PRUint32 i, count = mAttrsAndChildren.ChildCount();
-  for (i = 0; i < count; ++i) {
-    mAttrsAndChildren.ChildAt(i)->SaveSubtreeState();
-  }
-}
-
-//----------------------------------------------------------------------
-
-// Generic DOMNode implementations
-
-void
-nsGenericElement::FireNodeInserted(nsIDocument* aDoc,
-                                   nsINode* aParent,
-                                   nsTArray<nsCOMPtr<nsIContent> >& aNodes)
-{
-  PRUint32 count = aNodes.Length();
-  for (PRUint32 i = 0; i < count; ++i) {
-    nsIContent* childContent = aNodes[i];
-
-    if (nsContentUtils::HasMutationListeners(childContent,
-          NS_EVENT_BITS_MUTATION_NODEINSERTED, aParent)) {
-      nsMutationEvent mutation(true, NS_MUTATION_NODEINSERTED);
-      mutation.mRelatedNode = do_QueryInterface(aParent);
-
-      mozAutoSubtreeModified subtree(aDoc, aParent);
-      (new nsAsyncDOMEvent(childContent, mutation))->RunDOMEventWhenSafe();
-    }
-  }
-}
-
-//----------------------------------------------------------------------
-
-// nsISupports implementation
-
-NS_IMPL_CYCLE_COLLECTION_CLASS(nsGenericElement)
-
-#define SUBTREE_UNBINDINGS_PER_RUNNABLE 500
-
-class ContentUnbinder : public nsRunnable
-{
-public:
-  ContentUnbinder()
-  {
-    nsLayoutStatics::AddRef();
-    mLast = this;
-  }
-
-  ~ContentUnbinder()
-  {
-    Run();
-    nsLayoutStatics::Release();
-  }
-
-  void UnbindSubtree(nsIContent* aNode)
-  {
-    if (aNode->NodeType() != nsIDOMNode::ELEMENT_NODE &&
-        aNode->NodeType() != nsIDOMNode::DOCUMENT_FRAGMENT_NODE) {
-      return;  
-    }
-    nsGenericElement* container = static_cast<nsGenericElement*>(aNode);
-    PRUint32 childCount = container->mAttrsAndChildren.ChildCount();
-    if (childCount) {
-      while (childCount-- > 0) {
-        // Hold a strong ref to the node when we remove it, because we may be
-        // the last reference to it.  We need to call TakeChildAt() and
-        // update mFirstChild before calling UnbindFromTree, since this last
-        // can notify various observers and they should really see consistent
-        // tree state.
-        nsCOMPtr<nsIContent> child =
-          container->mAttrsAndChildren.TakeChildAt(childCount);
-        if (childCount == 0) {
-          container->mFirstChild = nullptr;
-        }
-        UnbindSubtree(child);
-        child->UnbindFromTree();
-      }
-    }
-  }
-
-  NS_IMETHOD Run()
-  {
-    nsAutoScriptBlocker scriptBlocker;
-    PRUint32 len = mSubtreeRoots.Length();
-    if (len) {
-      PRTime start = PR_Now();
-      for (PRUint32 i = 0; i < len; ++i) {
-        UnbindSubtree(mSubtreeRoots[i]);
-      }
-      mSubtreeRoots.Clear();
-      Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_CONTENT_UNBIND,
-                            PRUint32(PR_Now() - start) / PR_USEC_PER_MSEC);
-    }
-    if (this == sContentUnbinder) {
-      sContentUnbinder = nullptr;
-      if (mNext) {
-        nsRefPtr<ContentUnbinder> next;
-        next.swap(mNext);
-        sContentUnbinder = next;
-        next->mLast = mLast;
-        mLast = nullptr;
-        NS_DispatchToMainThread(next);
-      }
-    }
-    return NS_OK;
-  }
-
-  static void UnbindAll()
-  {
-    nsRefPtr<ContentUnbinder> ub = sContentUnbinder;
-    sContentUnbinder = nullptr;
-    while (ub) {
-      ub->Run();
-      ub = ub->mNext;
-    }
-  }
-
-  static void Append(nsIContent* aSubtreeRoot)
-  {
-    if (!sContentUnbinder) {
-      sContentUnbinder = new ContentUnbinder();
-      nsCOMPtr<nsIRunnable> e = sContentUnbinder;
-      NS_DispatchToMainThread(e);
-    }
-
-    if (sContentUnbinder->mLast->mSubtreeRoots.Length() >=
-        SUBTREE_UNBINDINGS_PER_RUNNABLE) {
-      sContentUnbinder->mLast->mNext = new ContentUnbinder();
-      sContentUnbinder->mLast = sContentUnbinder->mLast->mNext;
-    }
-    sContentUnbinder->mLast->mSubtreeRoots.AppendElement(aSubtreeRoot);
-  }
-
-private:
-  nsAutoTArray<nsCOMPtr<nsIContent>,
-               SUBTREE_UNBINDINGS_PER_RUNNABLE> mSubtreeRoots;
-  nsRefPtr<ContentUnbinder>                     mNext;
-  ContentUnbinder*                              mLast;
-  static ContentUnbinder*                       sContentUnbinder;
-};
-
-ContentUnbinder* ContentUnbinder::sContentUnbinder = nullptr;
-
-void
-nsGenericElement::ClearContentUnbinder()
-{
-  ContentUnbinder::UnbindAll();
-}
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGenericElement)
-  nsINode::Unlink(tmp);
-
-  if (tmp->HasProperties()) {
-    if (tmp->IsHTML()) {
-      tmp->DeleteProperty(nsGkAtoms::microdataProperties);
-      tmp->DeleteProperty(nsGkAtoms::itemtype);
-      tmp->DeleteProperty(nsGkAtoms::itemref);
-      tmp->DeleteProperty(nsGkAtoms::itemprop);
-    } else if (tmp->IsXUL()) {
-      tmp->DeleteProperty(nsGkAtoms::contextmenulistener);
-      tmp->DeleteProperty(nsGkAtoms::popuplistener);
-    }
-  }
-
-  // Unlink child content (and unbind our subtree).
-  if (tmp->UnoptimizableCCNode() || !nsCCUncollectableMarker::sGeneration) {
-    PRUint32 childCount = tmp->mAttrsAndChildren.ChildCount();
-    if (childCount) {
-      // Don't allow script to run while we're unbinding everything.
-      nsAutoScriptBlocker scriptBlocker;
-      while (childCount-- > 0) {
-        // Hold a strong ref to the node when we remove it, because we may be
-        // the last reference to it.  We need to call TakeChildAt() and
-        // update mFirstChild before calling UnbindFromTree, since this last
-        // can notify various observers and they should really see consistent
-        // tree state.
-        nsCOMPtr<nsIContent> child = tmp->mAttrsAndChildren.TakeChildAt(childCount);
-        if (childCount == 0) {
-          tmp->mFirstChild = nullptr;
-        }
-        child->UnbindFromTree();
-      }
-    }
-  } else if (!tmp->GetParent() && tmp->mAttrsAndChildren.ChildCount()) {
-    ContentUnbinder::Append(tmp);
-  } /* else {
-    The subtree root will end up to a ContentUnbinder, and that will
-    unbind the child nodes.
-  } */
-
-  // Unlink any DOM slots of interest.
-  {
-    nsDOMSlots *slots = tmp->GetExistingDOMSlots();
-    if (slots) {
-      slots->Unlink(tmp->IsXUL());
-    }
-  }
-
-  {
-    nsIDocument *doc;
-    if (!tmp->GetNodeParent() && (doc = tmp->OwnerDoc())) {
-      doc->BindingManager()->RemovedFromDocument(tmp, doc);
-    }
-  }
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
-NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsGenericElement)
-  nsINode::Trace(tmp, aCallback, aClosure);
-NS_IMPL_CYCLE_COLLECTION_TRACE_END
-
-void
-nsGenericElement::MarkUserData(void* aObject, nsIAtom* aKey, void* aChild,
-                               void* aData)
-{
-  PRUint32* gen = static_cast<PRUint32*>(aData);
-  xpc_MarkInCCGeneration(static_cast<nsISupports*>(aChild), *gen);
-}
-
-void
-nsGenericElement::MarkUserDataHandler(void* aObject, nsIAtom* aKey,
-                                      void* aChild, void* aData)
-{
-  xpc_TryUnmarkWrappedGrayObject(static_cast<nsISupports*>(aChild));
-}
-
-void
-nsGenericElement::MarkNodeChildren(nsINode* aNode)
-{
-  JSObject* o = GetJSObjectChild(aNode);
-  xpc_UnmarkGrayObject(o);
-
-  nsEventListenerManager* elm = aNode->GetListenerManager(false);
-  if (elm) {
-    elm->UnmarkGrayJSListeners();
-  }
-
-  if (aNode->HasProperties()) {
-    nsIDocument* ownerDoc = aNode->OwnerDoc();
-    ownerDoc->PropertyTable(DOM_USER_DATA)->
-      Enumerate(aNode, nsGenericElement::MarkUserData,
-                &nsCCUncollectableMarker::sGeneration);
-    ownerDoc->PropertyTable(DOM_USER_DATA_HANDLER)->
-      Enumerate(aNode, nsGenericElement::MarkUserDataHandler,
-                &nsCCUncollectableMarker::sGeneration);
-  }
-}
-
-nsINode*
-FindOptimizableSubtreeRoot(nsINode* aNode)
-{
-  nsINode* p;
-  while ((p = aNode->GetNodeParent())) {
-    if (aNode->UnoptimizableCCNode()) {
-      return nullptr;
-    }
-    aNode = p;
-  }
-  
-  if (aNode->UnoptimizableCCNode()) {
-    return nullptr;
-  }
-  return aNode;
-}
-
-nsAutoTArray<nsINode*, 1020>* gCCBlackMarkedNodes = nullptr;
-
-void
-ClearBlackMarkedNodes()
-{
-  if (!gCCBlackMarkedNodes) {
-    return;
-  }
-  PRUint32 len = gCCBlackMarkedNodes->Length();
-  for (PRUint32 i = 0; i < len; ++i) {
-    nsINode* n = gCCBlackMarkedNodes->ElementAt(i);
-    n->SetCCMarkedRoot(false);
-    n->SetInCCBlackTree(false);
-  }
-  delete gCCBlackMarkedNodes;
-  gCCBlackMarkedNodes = nullptr;
-}
-
-// static
-bool
-nsGenericElement::CanSkipInCC(nsINode* aNode)
-{
-  // Don't try to optimize anything during shutdown.
-  if (nsCCUncollectableMarker::sGeneration == 0) {
-    return false;
-  }
-
-  nsIDocument* currentDoc = aNode->GetCurrentDoc();
-  if (currentDoc &&
-      nsCCUncollectableMarker::InGeneration(currentDoc->GetMarkedCCGeneration())) {
-    return !NeedsScriptTraverse(aNode);
-  }
-
-  // Bail out early if aNode is somewhere in anonymous content,
-  // or otherwise unusual.
-  if (aNode->UnoptimizableCCNode()) {
-    return false;
-  }
-
-  nsINode* root =
-    currentDoc ? static_cast<nsINode*>(currentDoc) :
-                 FindOptimizableSubtreeRoot(aNode);
-  if (!root) {
-    return false;
-  }
-  
-  // Subtree has been traversed already.
-  if (root->CCMarkedRoot()) {
-    return root->InCCBlackTree() && !NeedsScriptTraverse(aNode);
-  }
-
-  if (!gCCBlackMarkedNodes) {
-    gCCBlackMarkedNodes = new nsAutoTArray<nsINode*, 1020>;
-  }
-
-  // nodesToUnpurple contains nodes which will be removed
-  // from the purple buffer if the DOM tree is black.
-  nsAutoTArray<nsIContent*, 1020> nodesToUnpurple;
-  // grayNodes need script traverse, so they aren't removed from
-  // the purple buffer, but are marked to be in black subtree so that
-  // traverse is faster.
-  nsAutoTArray<nsINode*, 1020> grayNodes;
-
-  bool foundBlack = root->IsBlack();
-  if (root != currentDoc) {
-    currentDoc = nullptr;
-    if (NeedsScriptTraverse(root)) {
-      grayNodes.AppendElement(root);
-    } else if (static_cast<nsIContent*>(root)->IsPurple()) {
-      nodesToUnpurple.AppendElement(static_cast<nsIContent*>(root));
-    }
-  }
-
-  // Traverse the subtree and check if we could know without CC
-  // that it is black.
-  // Note, this traverse is non-virtual and inline, so it should be a lot faster
-  // than CC's generic traverse.
-  for (nsIContent* node = root->GetFirstChild(); node;
-       node = node->GetNextNode(root)) {
-    foundBlack = foundBlack || node->IsBlack();
-    if (foundBlack && currentDoc) {
-      // If we can mark the whole document black, no need to optimize
-      // so much, since when the next purple node in the document will be
-      // handled, it is fast to check that currentDoc is in CCGeneration.
-      break;
-    }
-    if (NeedsScriptTraverse(node)) {
-      // Gray nodes need real CC traverse.
-      grayNodes.AppendElement(node);
-    } else if (node->IsPurple()) {
-      nodesToUnpurple.AppendElement(node);
-    }
-  }
-
-  root->SetCCMarkedRoot(true);
-  root->SetInCCBlackTree(foundBlack);
-  gCCBlackMarkedNodes->AppendElement(root);
-
-  if (!foundBlack) {
-    return false;
-  }
-
-  if (currentDoc) {
-    // Special case documents. If we know the document is black,
-    // we can mark the document to be in CCGeneration.
-    currentDoc->
-      MarkUncollectableForCCGeneration(nsCCUncollectableMarker::sGeneration);
-  } else {
-    for (PRUint32 i = 0; i < grayNodes.Length(); ++i) {
-      nsINode* node = grayNodes[i];
-      node->SetInCCBlackTree(true);
-    }
-    gCCBlackMarkedNodes->AppendElements(grayNodes);
-  }
-
-  // Subtree is black, we can remove non-gray purple nodes from
-  // purple buffer.
-  for (PRUint32 i = 0; i < nodesToUnpurple.Length(); ++i) {
-    nsIContent* purple = nodesToUnpurple[i];
-    // Can't remove currently handled purple node.
-    if (purple != aNode) {
-      purple->RemovePurple();
-    }
-  }
-  return !NeedsScriptTraverse(aNode);
-}
-
-nsAutoTArray<nsINode*, 1020>* gPurpleRoots = nullptr;
-nsAutoTArray<nsIContent*, 1020>* gNodesToUnbind = nullptr;
-
-void ClearCycleCollectorCleanupData()
-{
-  if (gPurpleRoots) {
-    PRUint32 len = gPurpleRoots->Length();
-    for (PRUint32 i = 0; i < len; ++i) {
-      nsINode* n = gPurpleRoots->ElementAt(i);
-      n->SetIsPurpleRoot(false);
-    }
-    delete gPurpleRoots;
-    gPurpleRoots = nullptr;
-  }
-  if (gNodesToUnbind) {
-    PRUint32 len = gNodesToUnbind->Length();
-    for (PRUint32 i = 0; i < len; ++i) {
-      nsIContent* c = gNodesToUnbind->ElementAt(i);
-      c->SetIsPurpleRoot(false);
-      ContentUnbinder::Append(c);
-    }
-    delete gNodesToUnbind;
-    gNodesToUnbind = nullptr;
-  }
-}
-
-static bool
-ShouldClearPurple(nsIContent* aContent)
-{
-  if (aContent && aContent->IsPurple()) {
-    return true;
-  }
-
-  JSObject* o = GetJSObjectChild(aContent);
-  if (o && xpc_IsGrayGCThing(o)) {
-    return true;
-  }
-
-  if (aContent->HasListenerManager()) {
-    return true;
-  }
-
-  return aContent->HasProperties();
-}
-
-// If aNode is not optimizable, but is an element
-// with a frame in a document which has currently active presshell,
-// we can act as if it was optimizable. When the primary frame dies, aNode
-// will end up to the purple buffer because of the refcount change.
-bool
-NodeHasActiveFrame(nsIDocument* aCurrentDoc, nsINode* aNode)
-{
-  return aCurrentDoc->GetShell() && aNode->IsElement() &&
-         aNode->AsElement()->GetPrimaryFrame();
-}
-
-bool
-OwnedByBindingManager(nsIDocument* aCurrentDoc, nsINode* aNode)
-{
-  return aNode->IsElement() &&
-    aCurrentDoc->BindingManager()->GetBinding(aNode->AsElement());
-}
-
-// CanSkip checks if aNode is black, and if it is, returns
-// true. If aNode is in a black DOM tree, CanSkip may also remove other objects
-// from purple buffer and unmark event listeners and user data.
-// If the root of the DOM tree is a document, less optimizations are done
-// since checking the blackness of the current document is usually fast and we
-// don't want slow down such common cases.
-bool
-nsGenericElement::CanSkip(nsINode* aNode, bool aRemovingAllowed)
-{
-  // Don't try to optimize anything during shutdown.
-  if (nsCCUncollectableMarker::sGeneration == 0) {
-    return false;
-  }
-
-  bool unoptimizable = aNode->UnoptimizableCCNode();
-  nsIDocument* currentDoc = aNode->GetCurrentDoc();
-  if (currentDoc &&
-      nsCCUncollectableMarker::InGeneration(currentDoc->GetMarkedCCGeneration()) &&
-      (!unoptimizable || NodeHasActiveFrame(currentDoc, aNode) ||
-       OwnedByBindingManager(currentDoc, aNode))) {
-    MarkNodeChildren(aNode);
-    return true;
-  }
-
-  if (unoptimizable) {
-    return false;
-  }
-
-  nsINode* root = currentDoc ? static_cast<nsINode*>(currentDoc) :
-                               FindOptimizableSubtreeRoot(aNode);
-  if (!root) {
-    return false;
-  }
- 
-  // Subtree has been traversed already, and aNode has
-  // been handled in a way that doesn't require revisiting it.
-  if (root->IsPurpleRoot()) {
-    return false;
-  }
-
-  // nodesToClear contains nodes which are either purple or
-  // gray.
-  nsAutoTArray<nsIContent*, 1020> nodesToClear;
-
-  bool foundBlack = root->IsBlack();
-  bool domOnlyCycle = false;
-  if (root != currentDoc) {
-    currentDoc = nullptr;
-    if (!foundBlack) {
-      domOnlyCycle = static_cast<nsIContent*>(root)->OwnedOnlyByTheDOMTree();
-    }
-    if (ShouldClearPurple(static_cast<nsIContent*>(root))) {
-      nodesToClear.AppendElement(static_cast<nsIContent*>(root));
-    }
-  }
-
-  // Traverse the subtree and check if we could know without CC
-  // that it is black.
-  // Note, this traverse is non-virtual and inline, so it should be a lot faster
-  // than CC's generic traverse.
-  for (nsIContent* node = root->GetFirstChild(); node;
-       node = node->GetNextNode(root)) {
-    foundBlack = foundBlack || node->IsBlack();
-    if (foundBlack) {
-      domOnlyCycle = false;
-      if (currentDoc) {
-        // If we can mark the whole document black, no need to optimize
-        // so much, since when the next purple node in the document will be
-        // handled, it is fast to check that the currentDoc is in CCGeneration.
-        break;
-      }
-      // No need to put stuff to the nodesToClear array, if we can clear it
-      // already here.
-      if (node->IsPurple() && (node != aNode || aRemovingAllowed)) {
-        node->RemovePurple();
-      }
-      MarkNodeChildren(node);
-    } else {
-      domOnlyCycle = domOnlyCycle && node->OwnedOnlyByTheDOMTree();
-      if (ShouldClearPurple(node)) {
-        // Collect interesting nodes which we can clear if we find that
-        // they are kept alive in a black tree or are in a DOM-only cycle.
-        nodesToClear.AppendElement(node);
-      }
-    }
-  }
-
-  if (!currentDoc || !foundBlack) { 
-    root->SetIsPurpleRoot(true);
-    if (domOnlyCycle) {
-      if (!gNodesToUnbind) {
-        gNodesToUnbind = new nsAutoTArray<nsIContent*, 1020>();
-      }
-      gNodesToUnbind->AppendElement(static_cast<nsIContent*>(root));
-      for (PRUint32 i = 0; i < nodesToClear.Length(); ++i) {
-        nsIContent* n = nodesToClear[i];
-        if ((n != aNode || aRemovingAllowed) && n->IsPurple()) {
-          n->RemovePurple();
-        }
-      }
-      return true;
-    } else {
-      if (!gPurpleRoots) {
-        gPurpleRoots = new nsAutoTArray<nsINode*, 1020>();
-      }
-      gPurpleRoots->AppendElement(root);
-    }
-  }
-
-  if (!foundBlack) {
-    return false;
-  }
-
-  if (currentDoc) {
-    // Special case documents. If we know the document is black,
-    // we can mark the document to be in CCGeneration.
-    currentDoc->
-      MarkUncollectableForCCGeneration(nsCCUncollectableMarker::sGeneration);
-    MarkNodeChildren(currentDoc);
-  }
-
-  // Subtree is black, so we can remove purple nodes from
-  // purple buffer and mark stuff that to be certainly alive.
-  for (PRUint32 i = 0; i < nodesToClear.Length(); ++i) {
-    nsIContent* n = nodesToClear[i];
-    MarkNodeChildren(n);
-    // Can't remove currently handled purple node,
-    // unless aRemovingAllowed is true. 
-    if ((n != aNode || aRemovingAllowed) && n->IsPurple()) {
-      n->RemovePurple();
-    }
-  }
-  return true;
-}
-
-bool
-nsGenericElement::CanSkipThis(nsINode* aNode)
-{
-  if (nsCCUncollectableMarker::sGeneration == 0) {
-    return false;
-  }
-  if (aNode->IsBlack()) {
-    return true;
-  }
-  nsIDocument* c = aNode->GetCurrentDoc();
-  return 
-    ((c && nsCCUncollectableMarker::InGeneration(c->GetMarkedCCGeneration())) ||
-     aNode->InCCBlackTree()) && !NeedsScriptTraverse(aNode);
-}
-
-void
-nsGenericElement::InitCCCallbacks()
-{
-  nsCycleCollector_setForgetSkippableCallback(ClearCycleCollectorCleanupData);
-  nsCycleCollector_setBeforeUnlinkCallback(ClearBlackMarkedNodes);
-}
-
-NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsGenericElement)
-  return nsGenericElement::CanSkip(tmp, aRemovingAllowed);
-NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
-
-NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(nsGenericElement)
-  return nsGenericElement::CanSkipInCC(tmp);
-NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END
-
-NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(nsGenericElement)
-  return nsGenericElement::CanSkipThis(tmp);
-NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
-
-static const char* kNSURIs[] = {
-  " ([none])",
-  " (xmlns)",
-  " (xml)",
-  " (xhtml)",
-  " (XLink)",
-  " (XSLT)",
-  " (XBL)",
-  " (MathML)",
-  " (RDF)",
-  " (XUL)",
-  " (SVG)",
-  " (XML Events)"
-};
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGenericElement)
-  if (NS_UNLIKELY(cb.WantDebugInfo())) {
-    char name[512];
-    PRUint32 nsid = tmp->GetNameSpaceID();
-    nsAtomCString localName(tmp->NodeInfo()->NameAtom());
-    nsCAutoString uri;
-    if (tmp->OwnerDoc()->GetDocumentURI()) {
-      tmp->OwnerDoc()->GetDocumentURI()->GetSpec(uri);
-    }
-
-    nsAutoString id;
-    nsIAtom* idAtom = tmp->GetID();
-    if (idAtom) {
-      id.AppendLiteral(" id='");
-      id.Append(nsDependentAtomString(idAtom));
-      id.AppendLiteral("'");
-    }
-
-    nsAutoString classes;
-    const nsAttrValue* classAttrValue = tmp->GetClasses();
-    if (classAttrValue) {
-      classes.AppendLiteral(" class='");
-      nsAutoString classString;
-      classAttrValue->ToString(classString);
-      classString.ReplaceChar(PRUnichar('\n'), PRUnichar(' '));
-      classes.Append(classString);
-      classes.AppendLiteral("'");
-    }
-
-    const char* nsuri = nsid < ArrayLength(kNSURIs) ? kNSURIs[nsid] : "";
-    PR_snprintf(name, sizeof(name), "nsGenericElement%s %s%s%s %s",
-                nsuri,
-                localName.get(),
-                NS_ConvertUTF16toUTF8(id).get(),
-                NS_ConvertUTF16toUTF8(classes).get(),
-                uri.get());
-    cb.DescribeRefCountedNode(tmp->mRefCnt.get(), sizeof(nsGenericElement),
-                              name);
-  }
-  else {
-    NS_IMPL_CYCLE_COLLECTION_DESCRIBE(nsGenericElement, tmp->mRefCnt.get())
-  }
-
-  // Always need to traverse script objects, so do that before we check
-  // if we're uncollectable.
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
-
-  if (!nsINode::Traverse(tmp, cb)) {
-    return NS_SUCCESS_INTERRUPTED_TRAVERSE;
-  }
-
-  tmp->OwnerDoc()->BindingManager()->Traverse(tmp, cb);
-
-  if (tmp->HasProperties()) {
-    if (tmp->IsHTML()) {
-      nsISupports* property = static_cast<nsISupports*>
-                                         (tmp->GetProperty(nsGkAtoms::microdataProperties));
-      cb.NoteXPCOMChild(property);
-      property = static_cast<nsISupports*>(tmp->GetProperty(nsGkAtoms::itemref));
-      cb.NoteXPCOMChild(property);
-      property = static_cast<nsISupports*>(tmp->GetProperty(nsGkAtoms::itemprop));
-      cb.NoteXPCOMChild(property);
-      property = static_cast<nsISupports*>(tmp->GetProperty(nsGkAtoms::itemtype));
-      cb.NoteXPCOMChild(property);
-    } else if (tmp->IsXUL()) {
-      nsISupports* property = static_cast<nsISupports*>
-                                         (tmp->GetProperty(nsGkAtoms::contextmenulistener));
-      cb.NoteXPCOMChild(property);
-      property = static_cast<nsISupports*>
-                            (tmp->GetProperty(nsGkAtoms::popuplistener));
-      cb.NoteXPCOMChild(property);
-    }
-  }
-
-  // Traverse attribute names and child content.
-  {
-    PRUint32 i;
-    PRUint32 attrs = tmp->mAttrsAndChildren.AttrCount();
-    for (i = 0; i < attrs; i++) {
-      const nsAttrName* name = tmp->mAttrsAndChildren.AttrNameAt(i);
-      if (!name->IsAtom()) {
-        NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb,
-                                           "mAttrsAndChildren[i]->NodeInfo()");
-        cb.NoteXPCOMChild(name->NodeInfo());
-      }
-    }
-
-    PRUint32 kids = tmp->mAttrsAndChildren.ChildCount();
-    for (i = 0; i < kids; i++) {
-      NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mAttrsAndChildren[i]");
-      cb.NoteXPCOMChild(tmp->mAttrsAndChildren.GetSafeChildAt(i));
-    }
-  }
-
-  // Traverse any DOM slots of interest.
-  {
-    nsDOMSlots *slots = tmp->GetExistingDOMSlots();
-    if (slots) {
-      slots->Traverse(cb, tmp->IsXUL());
-    }
-  }
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-
-NS_INTERFACE_MAP_BEGIN(nsGenericElement)
-  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
-  NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsGenericElement)
-  NS_INTERFACE_MAP_ENTRY(Element)
-  NS_INTERFACE_MAP_ENTRY(nsIContent)
-  NS_INTERFACE_MAP_ENTRY(nsINode)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMEventTarget)
-  NS_INTERFACE_MAP_ENTRY_TEAROFF(nsISupportsWeakReference,
-                                 new nsNodeSupportsWeakRefTearoff(this))
-  NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMNodeSelector,
-                                 new nsNodeSelectorTearoff(this))
-  NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMXPathNSResolver,
-                                 new nsNode3Tearoff(this))
-  NS_INTERFACE_MAP_ENTRY_TEAROFF(nsITouchEventReceiver,
-                                 new nsTouchEventReceiverTearoff(this))
-  NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIInlineEventHandlers,
-                                 new nsInlineEventHandlersTearoff(this))
-  // nsNodeSH::PreCreate() depends on the identity pointer being the
-  // same as nsINode (which nsIContent inherits), so if you change the
-  // below line, make sure nsNodeSH::PreCreate() still does the right
-  // thing!
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContent)
-NS_INTERFACE_MAP_END
-
-NS_IMPL_CYCLE_COLLECTING_ADDREF(nsGenericElement)
-NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_DESTROY(nsGenericElement,
-                                              nsNodeUtils::LastRelease(this))
-
-nsresult
-nsGenericElement::PostQueryInterface(REFNSIID aIID, void** aInstancePtr)
-{
-  return OwnerDoc()->BindingManager()->GetBindingImplementation(this, aIID,
-                                                                aInstancePtr);
-}
-
 //----------------------------------------------------------------------
 nsresult
 nsGenericElement::LeaveLink(nsPresContext* aPresContext)
 {
   nsILinkHandler *handler = aPresContext->GetLinkHandler();
   if (!handler) {
     return NS_OK;
   }
@@ -3558,33 +1832,16 @@ nsGenericElement::AddScriptEventListener
 //----------------------------------------------------------------------
 
 const nsAttrName*
 nsGenericElement::InternalGetExistingAttrNameFromQName(const nsAString& aStr) const
 {
   return mAttrsAndChildren.GetExistingAttrNameFromQName(aStr);
 }
 
-nsresult
-nsGenericElement::CopyInnerTo(nsGenericElement* aDst)
-{
-  PRUint32 i, count = mAttrsAndChildren.AttrCount();
-  for (i = 0; i < count; ++i) {
-    const nsAttrName* name = mAttrsAndChildren.AttrNameAt(i);
-    const nsAttrValue* value = mAttrsAndChildren.AttrAt(i);
-    nsAutoString valStr;
-    value->ToString(valStr);
-    nsresult rv = aDst->SetAttr(name->NamespaceID(), name->LocalName(),
-                                name->GetPrefix(), valStr, false);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  return NS_OK;
-}
-
 bool
 nsGenericElement::MaybeCheckSameAttrVal(PRInt32 aNamespaceID,
                                         nsIAtom* aName,
                                         nsIAtom* aPrefix,
                                         const nsAttrValueOrString& aValue,
                                         bool aNotify,
                                         nsAttrValue& aOldValue,
                                         PRUint8* aModType,
@@ -4037,64 +2294,16 @@ nsGenericElement::GetAttrNameAt(PRUint32
 }
 
 PRUint32
 nsGenericElement::GetAttrCount() const
 {
   return mAttrsAndChildren.AttrCount();
 }
 
-const nsTextFragment*
-nsGenericElement::GetText()
-{
-  return nullptr;
-}
-
-PRUint32
-nsGenericElement::TextLength() const
-{
-  // We can remove this assertion if it turns out to be useful to be able
-  // to depend on this returning 0
-  NS_NOTREACHED("called nsGenericElement::TextLength");
-
-  return 0;
-}
-
-nsresult
-nsGenericElement::SetText(const PRUnichar* aBuffer, PRUint32 aLength,
-                          bool aNotify)
-{
-  NS_ERROR("called nsGenericElement::SetText");
-
-  return NS_ERROR_FAILURE;
-}
-
-nsresult
-nsGenericElement::AppendText(const PRUnichar* aBuffer, PRUint32 aLength,
-                             bool aNotify)
-{
-  NS_ERROR("called nsGenericElement::AppendText");
-
-  return NS_ERROR_FAILURE;
-}
-
-bool
-nsGenericElement::TextIsOnlyWhitespace()
-{
-  return false;
-}
-
-void
-nsGenericElement::AppendTextTo(nsAString& aResult)
-{
-  // We can remove this assertion if it turns out to be useful to be able
-  // to depend on this appending nothing.
-  NS_NOTREACHED("called nsGenericElement::TextLength");
-}
-
 #ifdef DEBUG
 void
 nsGenericElement::ListAttributes(FILE* out) const
 {
   PRUint32 index, count = mAttrsAndChildren.AttrCount();
   for (index = 0; index < count; index++) {
     nsAutoString buffer;
 
@@ -4239,46 +2448,16 @@ nsGenericElement::DumpContent(FILE* out,
   fputs("</", out);
   fputs(NS_LossyConvertUTF16toASCII(buf).get(), out);
   fputs(">", out);
 
   if(aIndent) fputs("\n", out);
 }
 #endif
 
-PRUint32
-nsGenericElement::GetChildCount() const
-{
-  return mAttrsAndChildren.ChildCount();
-}
-
-nsIContent *
-nsGenericElement::GetChildAt(PRUint32 aIndex) const
-{
-  return mAttrsAndChildren.GetSafeChildAt(aIndex);
-}
-
-nsIContent * const *
-nsGenericElement::GetChildArray(PRUint32* aChildCount) const
-{
-  return mAttrsAndChildren.GetChildArray(aChildCount);
-}
-
-PRInt32
-nsGenericElement::IndexOf(nsINode* aPossibleChild) const
-{
-  return mAttrsAndChildren.IndexOfChild(aPossibleChild);
-}
-
-nsINode::nsSlots*
-nsGenericElement::CreateSlots()
-{
-  return new nsDOMSlots();
-}
-
 bool
 nsGenericElement::CheckHandleEventForLinksPrecondition(nsEventChainVisitor& aVisitor,
                                                        nsIURI** aURI) const
 {
   if (aVisitor.mEventStatus == nsEventStatus_eConsumeNoDefault ||
       (!NS_IS_TRUSTED_EVENT(aVisitor.mEvent) &&
        (aVisitor.mEvent->message != NS_MOUSE_CLICK) &&
        (aVisitor.mEvent->message != NS_KEY_PRESS) &&
@@ -4458,36 +2637,16 @@ nsGenericElement::PostHandleEventForLink
     NS_NOTREACHED("switch statements not in sync");
     return NS_ERROR_UNEXPECTED;
   }
 
   return rv;
 }
 
 void
-nsGenericElement::FireNodeRemovedForChildren()
-{
-  nsIDocument* doc = OwnerDoc();
-  // Optimize the common case
-  if (!nsContentUtils::
-        HasMutationListeners(doc, NS_EVENT_BITS_MUTATION_NODEREMOVED)) {
-    return;
-  }
-
-  nsCOMPtr<nsIDocument> owningDoc = doc;
-
-  nsCOMPtr<nsINode> child;
-  for (child = GetFirstChild();
-       child && child->GetNodeParent() == this;
-       child = child->GetNextSibling()) {
-    nsContentUtils::MaybeFireNodeRemoved(child, this, doc);
-  }
-}
-
-void
 nsGenericElement::GetLinkTarget(nsAString& aTarget)
 {
   aTarget.Truncate();
 }
 
 // NOTE: The aPresContext pointer is NOT addrefed.
 // *aSelectorList might be null even if NS_OK is returned; this
 // happens when all the selectors were pseudo-element selectors.
@@ -4520,136 +2679,16 @@ ParseSelectorList(nsINode* aNode,
       slot = &cur->mNext;
     }
   } while (*slot);
   *aSelectorList = selectorList;
 
   return NS_OK;
 }
 
-// Actually find elements matching aSelectorList (which must not be
-// null) and which are descendants of aRoot and put them in aList.  If
-// onlyFirstMatch, then stop once the first one is found.
-template<bool onlyFirstMatch, class T>
-inline static nsresult FindMatchingElements(nsINode* aRoot,
-                                            const nsAString& aSelector,
-                                            T &aList)
-{
-  nsAutoPtr<nsCSSSelectorList> selectorList;
-  nsresult rv = ParseSelectorList(aRoot, aSelector,
-                                  getter_Transfers(selectorList));
-  NS_ENSURE_SUCCESS(rv, rv);
-  NS_ENSURE_TRUE(selectorList, NS_OK);
-
-  NS_ASSERTION(selectorList->mSelectors,
-               "How can we not have any selectors?");
-
-  nsIDocument* doc = aRoot->OwnerDoc();  
-  TreeMatchContext matchingContext(false, nsRuleWalker::eRelevantLinkUnvisited,
-                                   doc, TreeMatchContext::eNeverMatchVisited);
-  doc->FlushPendingLinkUpdates();
-
-  // Fast-path selectors involving IDs.  We can only do this if aRoot
-  // is in the document and the document is not in quirks mode, since
-  // ID selectors are case-insensitive in quirks mode.  Also, only do
-  // this if selectorList only has one selector, because otherwise
-  // ordering the elements correctly is a pain.
-  NS_ASSERTION(aRoot->IsElement() || aRoot->IsNodeOfType(nsINode::eDOCUMENT) ||
-               !aRoot->IsInDoc(),
-               "The optimization below to check ContentIsDescendantOf only for "
-               "elements depends on aRoot being either an element or a "
-               "document if it's in the document.");
-  if (aRoot->IsInDoc() &&
-      doc->GetCompatibilityMode() != eCompatibility_NavQuirks &&
-      !selectorList->mNext &&
-      selectorList->mSelectors->mIDList) {
-    nsIAtom* id = selectorList->mSelectors->mIDList->mAtom;
-    const nsSmallVoidArray* elements =
-      doc->GetAllElementsForId(nsDependentAtomString(id));
-
-    // XXXbz: Should we fall back to the tree walk if aRoot is not the
-    // document and |elements| is long, for some value of "long"?
-    if (elements) {
-      for (PRInt32 i = 0; i < elements->Count(); ++i) {
-        Element *element = static_cast<Element*>(elements->ElementAt(i));
-        if (!aRoot->IsElement() ||
-            (element != aRoot &&
-             nsContentUtils::ContentIsDescendantOf(element, aRoot))) {
-          // We have an element with the right id and it's a strict descendant
-          // of aRoot.  Make sure it really matches the selector.
-          if (nsCSSRuleProcessor::SelectorListMatches(element, matchingContext,
-                                                      selectorList)) {
-            aList.AppendElement(element);
-            if (onlyFirstMatch) {
-              return NS_OK;
-            }
-          }
-        }
-      }
-    }
-
-    // No elements with this id, or none of them are our descendants,
-    // or none of them match.  We're done here.
-    return NS_OK;
-  }
-
-  for (nsIContent* cur = aRoot->GetFirstChild();
-       cur;
-       cur = cur->GetNextNode(aRoot)) {
-    if (cur->IsElement() &&
-        nsCSSRuleProcessor::SelectorListMatches(cur->AsElement(),
-                                                matchingContext,
-                                                selectorList)) {
-      aList.AppendElement(cur->AsElement());
-      if (onlyFirstMatch) {
-        return NS_OK;
-      }
-    }
-  }
-
-  return NS_OK;
-}
-
-struct ElementHolder {
-  ElementHolder() : mElement(nullptr) {}
-  void AppendElement(Element* aElement) {
-    NS_ABORT_IF_FALSE(!mElement, "Should only get one element");
-    mElement = aElement;
-  }
-  Element* mElement;
-};
-
-/* static */
-nsIContent*
-nsGenericElement::doQuerySelector(nsINode* aRoot, const nsAString& aSelector,
-                                  nsresult *aResult)
-{
-  NS_PRECONDITION(aResult, "Null out param?");
-
-  ElementHolder holder;
-  *aResult = FindMatchingElements<true>(aRoot, aSelector, holder);
-
-  return holder.mElement;
-}
-
-/* static */
-nsresult
-nsGenericElement::doQuerySelectorAll(nsINode* aRoot,
-                                     const nsAString& aSelector,
-                                     nsIDOMNodeList **aReturn)
-{
-  NS_PRECONDITION(aReturn, "Null out param?");
-
-  nsSimpleContentList* contentList = new nsSimpleContentList(aRoot);
-  NS_ENSURE_TRUE(contentList, NS_ERROR_OUT_OF_MEMORY);
-  NS_ADDREF(*aReturn = contentList);
-  
-  return FindMatchingElements<false>(aRoot, aSelector, *contentList);
-}
-
 
 bool
 nsGenericElement::MozMatchesSelector(const nsAString& aSelector, nsresult* aResult)
 {
   nsAutoPtr<nsCSSSelectorList> selectorList;
   bool matches = false;
 
   *aResult = ParseSelectorList(this, aSelector, getter_Transfers(selectorList));
@@ -4673,23 +2712,16 @@ nsGenericElement::MozMatchesSelector(con
   NS_PRECONDITION(aReturn, "Null out param?");
 
   nsresult rv;
   *aReturn = MozMatchesSelector(aSelector, &rv);
 
   return rv;
 }
 
-size_t
-nsGenericElement::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
-{
-  return Element::SizeOfExcludingThis(aMallocSizeOf) +
-         mAttrsAndChildren.SizeOfExcludingThis(aMallocSizeOf);
-}
-
 static const nsAttrValue::EnumTable kCORSAttributeTable[] = {
   // Order matters here
   // See ParseCORSValue
   { "anonymous",       CORS_ANONYMOUS       },
   { "use-credentials", CORS_USE_CREDENTIALS },
   { 0 }
 };
 
@@ -4804,9 +2836,8 @@ nsresult nsGenericElement::MozRequestFul
     e->PostDOMEvent();
     return NS_OK;
   }
 
   OwnerDoc()->AsyncRequestFullScreen(this);
 
   return NS_OK;
 }
-
--- a/content/base/src/nsGenericElement.h
+++ b/content/base/src/nsGenericElement.h
@@ -9,16 +9,17 @@
  * utility methods for subclasses, and so forth.
  */
 
 #ifndef nsGenericElement_h___
 #define nsGenericElement_h___
 
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
+#include "mozilla/dom/FragmentOrElement.h"
 #include "mozilla/dom/Element.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMDocumentFragment.h"
 #include "nsILinkHandler.h"
 #include "nsNodeUtils.h"
 #include "nsAttrAndChildArray.h"
 #include "mozFlushType.h"
 #include "nsDOMAttributeMap.h"
@@ -53,203 +54,30 @@ class nsAttrValueOrString;
 class nsContentList;
 class nsDOMTokenList;
 class ContentUnbinder;
 struct nsRect;
 
 typedef PRUptrdiff PtrBits;
 
 /**
- * Class that implements the nsIDOMNodeList interface (a list of children of
- * the content), by holding a reference to the content and delegating GetLength
- * and Item to its existing child list.
- * @see nsIDOMNodeList
- */
-class nsChildContentList MOZ_FINAL : public nsINodeList
-{
-public:
-  nsChildContentList(nsINode* aNode)
-    : mNode(aNode)
-  {
-    SetIsDOMBinding();
-  }
-
-  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(nsChildContentList)
-
-  // nsWrapperCache
-  virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
-                               bool *triedToWrap);
-
-  // nsIDOMNodeList interface
-  NS_DECL_NSIDOMNODELIST
-
-  // nsINodeList interface
-  virtual PRInt32 IndexOf(nsIContent* aContent);
-
-  void DropReference()
-  {
-    mNode = nullptr;
-  }
-
-  virtual nsINode* GetParentObject()
-  {
-    return mNode;
-  }
-
-private:
-  // The node whose children make up the list (weak reference)
-  nsINode* mNode;
-};
-
-/**
- * A tearoff class for nsGenericElement to implement additional interfaces
- */
-class nsNode3Tearoff : public nsIDOMXPathNSResolver
-{
-public:
-  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-
-  NS_DECL_CYCLE_COLLECTION_CLASS(nsNode3Tearoff)
-
-  NS_DECL_NSIDOMXPATHNSRESOLVER
-
-  nsNode3Tearoff(nsINode *aNode) : mNode(aNode)
-  {
-  }
-
-protected:
-  virtual ~nsNode3Tearoff() {}
-
-private:
-  nsCOMPtr<nsINode> mNode;
-};
-
-/**
- * A class that implements nsIWeakReference
- */
-
-class nsNodeWeakReference MOZ_FINAL : public nsIWeakReference
-{
-public:
-  nsNodeWeakReference(nsINode* aNode)
-    : mNode(aNode)
-  {
-  }
-
-  ~nsNodeWeakReference();
-
-  // nsISupports
-  NS_DECL_ISUPPORTS
-
-  // nsIWeakReference
-  NS_DECL_NSIWEAKREFERENCE
-
-  void NoticeNodeDestruction()
-  {
-    mNode = nullptr;
-  }
-
-private:
-  nsINode* mNode;
-};
-
-/**
- * Tearoff to use for nodes to implement nsISupportsWeakReference
- */
-class nsNodeSupportsWeakRefTearoff MOZ_FINAL : public nsISupportsWeakReference
-{
-public:
-  nsNodeSupportsWeakRefTearoff(nsINode* aNode)
-    : mNode(aNode)
-  {
-  }
-
-  // nsISupports
-  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-
-  // nsISupportsWeakReference
-  NS_DECL_NSISUPPORTSWEAKREFERENCE
-
-  NS_DECL_CYCLE_COLLECTION_CLASS(nsNodeSupportsWeakRefTearoff)
-
-private:
-  nsCOMPtr<nsINode> mNode;
-};
-
-/**
- * A tearoff class for nsGenericElement to implement NodeSelector
- */
-class nsNodeSelectorTearoff MOZ_FINAL : public nsIDOMNodeSelector
-{
-public:
-  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-
-  NS_DECL_NSIDOMNODESELECTOR
-
-  NS_DECL_CYCLE_COLLECTION_CLASS(nsNodeSelectorTearoff)
-
-  nsNodeSelectorTearoff(nsINode *aNode) : mNode(aNode)
-  {
-  }
-
-private:
-  ~nsNodeSelectorTearoff() {}
-
-private:
-  nsCOMPtr<nsINode> mNode;
-};
-
-// Forward declare to allow being a friend
-class nsTouchEventReceiverTearoff;
-class nsInlineEventHandlersTearoff;
-
-/**
  * A generic base class for DOM elements, implementing many nsIContent,
  * nsIDOMNode and nsIDOMElement methods.
  */
 class nsGenericElement : public mozilla::dom::Element
 {
 public:
   nsGenericElement(already_AddRefed<nsINodeInfo> aNodeInfo);
-  virtual ~nsGenericElement();
-
-  friend class nsTouchEventReceiverTearoff;
-  friend class nsInlineEventHandlersTearoff;
-
-  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 PRUint32 GetChildCount() const;
-  virtual nsIContent *GetChildAt(PRUint32 aIndex) const;
-  virtual nsIContent * const * GetChildArray(PRUint32* aChildCount) const;
-  virtual PRInt32 IndexOf(nsINode* aPossibleChild) const;
-  virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
-                                 bool aNotify);
-  virtual void RemoveChildAt(PRUint32 aIndex, bool aNotify);
-  NS_IMETHOD GetTextContent(nsAString &aTextContent);
-  NS_IMETHOD SetTextContent(const nsAString& aTextContent);
-
-  // nsIContent interface methods
   virtual void UpdateEditableState(bool aNotify);
 
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               bool aCompileEventHandlers);
   virtual void UnbindFromTree(bool aDeep = true,
                               bool aNullParent = true);
-  virtual already_AddRefed<nsINodeList> GetChildren(PRUint32 aFilter);
   virtual nsIAtom *GetClassAttributeName() const;
   virtual already_AddRefed<nsINodeInfo> GetExistingAttrNameFromQName(const nsAString& aStr) const;
   nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
                    const nsAString& aValue, bool aNotify)
   {
     return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify);
   }
   /**
@@ -290,35 +118,17 @@ public:
   virtual PRInt32 FindAttrValueIn(PRInt32 aNameSpaceID,
                                   nsIAtom* aName,
                                   AttrValuesArray* aValues,
                                   nsCaseTreatment aCaseSensitive) const;
   virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
                              bool aNotify);
   virtual const nsAttrName* GetAttrNameAt(PRUint32 aIndex) const;
   virtual PRUint32 GetAttrCount() const;
-  virtual const nsTextFragment *GetText();
-  virtual PRUint32 TextLength() const;
-  virtual nsresult SetText(const PRUnichar* aBuffer, PRUint32 aLength,
-                           bool aNotify);
-  // Need to implement this here too to avoid hiding.
-  nsresult SetText(const nsAString& aStr, bool aNotify)
-  {
-    return SetText(aStr.BeginReading(), aStr.Length(), aNotify);
-  }
-  virtual nsresult AppendText(const PRUnichar* aBuffer, PRUint32 aLength,
-                              bool aNotify);
-  virtual bool TextIsOnlyWhitespace();
-  virtual void AppendTextTo(nsAString& aResult);
-  virtual nsIContent *GetBindingParent() const;
   virtual bool IsNodeOfType(PRUint32 aFlags) const;
-  virtual bool IsLink(nsIURI** aURI) const;
-
-  virtual void DestroyContent();
-  virtual void SaveSubtreeState();
 
   virtual nsISMILAttr* GetAnimatedAttr(PRInt32 /*aNamespaceID*/, nsIAtom* /*aName*/)
   {
     return nullptr;
   }
   virtual nsICSSDeclaration* GetSMILOverrideStyle();
   virtual mozilla::css::StyleRule* GetSMILOverrideStyleRule();
   virtual nsresult SetSMILOverrideStyleRule(mozilla::css::StyleRule* aStyleRule,
@@ -330,18 +140,16 @@ public:
   {
     List(out, aIndent, EmptyCString());
   }
   virtual void DumpContent(FILE* out, PRInt32 aIndent, bool aDumpAll) const;
   void List(FILE* out, PRInt32 aIndent, const nsCString& aPrefix) const;
   void ListAttributes(FILE* out) const;
 #endif
 
-  virtual const nsAttrValue* DoGetClasses() const;
-  NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker);
   virtual mozilla::css::StyleRule* GetInlineStyleRule();
   virtual nsresult SetInlineStyleRule(mozilla::css::StyleRule* aStyleRule,
                                       const nsAString* aSerialized,
                                       bool aNotify);
   NS_IMETHOD_(bool)
     IsAttributeMapped(const nsIAtom* aAttribute) const;
   virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
                                               PRInt32 aModType) const;
@@ -368,60 +176,19 @@ public:
 
 private:
   static bool
   FindAttributeDependence(const nsIAtom* aAttribute,
                           const MappedAttributeEntry* const aMaps[],
                           PRUint32 aMapCount);
 
 public:
-  // nsIDOMNode method implementation
-  NS_IMETHOD GetNodeName(nsAString& aNodeName);
-  NS_IMETHOD GetLocalName(nsAString& aLocalName);
-  NS_IMETHOD GetNodeValue(nsAString& aNodeValue);
-  NS_IMETHOD SetNodeValue(const nsAString& aNodeValue);
-  NS_IMETHOD GetNodeType(PRUint16* aNodeType);
-  NS_IMETHOD GetAttributes(nsIDOMNamedNodeMap** aAttributes);
-  NS_IMETHOD GetNamespaceURI(nsAString& aNamespaceURI);
-  NS_IMETHOD GetPrefix(nsAString& aPrefix);
-  NS_IMETHOD IsSupported(const nsAString& aFeature,
-                         const nsAString& aVersion, bool* aReturn);
-  NS_IMETHOD HasAttributes(bool* aHasAttributes);
-  NS_IMETHOD HasChildNodes(bool* aHasChildNodes);
-  nsresult InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild,
-                        nsIDOMNode** aReturn)
-  {
-    return ReplaceOrInsertBefore(false, aNewChild, aRefChild, aReturn);
-  }
-  nsresult ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild,
-                        nsIDOMNode** aReturn)
-  {
-    return ReplaceOrInsertBefore(true, aNewChild, aOldChild, aReturn);
-  }
-  nsresult RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn)
-  {
-    return nsINode::RemoveChild(aOldChild, aReturn);
-  }
-  nsresult AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn)
-  {
-    return InsertBefore(aNewChild, nullptr, aReturn);
-  }
-
   // nsIDOMElement method implementation
   NS_DECL_NSIDOMELEMENT
 
-  nsresult CloneNode(bool aDeep, PRUint8 aOptionalArgc, nsIDOMNode **aResult)
-  {
-    if (!aOptionalArgc) {
-      aDeep = true;
-    }
-    
-    return nsNodeUtils::CloneNodeImpl(this, aDeep, true, aResult);
-  }
-
   //----------------------------------------
 
   /**
    * Add a script event listener with the given event handler name
    * (like onclick) and with the value as JS
    * @param aEventName the event listener name
    * @param aValue the JS to attach
    * @param aDefer indicates if deferred execution is allowed
@@ -430,49 +197,19 @@ public:
                                   const nsAString& aValue,