Merge.
authorDavid Anderson <danderson@mozilla.com>
Wed, 01 Aug 2012 11:30:00 -0700
changeset 102941 3e6c62bf74fcd73d8b017e790866916b32112d20
parent 102817 07e292dd5d3f752361c66715542ad31332e7e0f1 (current diff)
parent 102940 bcfe6817a2139bccbf423afe588554a57d56ba7b (diff)
child 102942 21f15c00b5df06b87b1b57b3cd738f0bd86c1f8f
push id18
push usershu@rfrn.org
push dateMon, 06 Aug 2012 22:42:45 +0000
milestone17.0a1
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);</