Bug 659539 Part 1: Give nsINodeInfos a nodeType, nodeName and localName. r=bz
authorJonas Sicking <jonas@sicking.cc>
Tue, 14 Jun 2011 00:56:49 -0700
changeset 71575 dd6e523b0b82af5da86c18bd3f1354a8f33f5b9f
parent 71574 0438ee84824cd63e174806b1abc665726e0e9aaf
child 71576 af6c49e8893331fb2b093e2fea3bd2918eb0027e
push id159
push usereakhgari@mozilla.com
push dateTue, 16 Aug 2011 17:53:11 +0000
treeherdermozilla-beta@8786e3e49240 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs659539
milestone7.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 659539 Part 1: Give nsINodeInfos a nodeType, nodeName and localName. r=bz
content/base/public/nsContentUtils.h
content/base/public/nsINodeInfo.h
content/base/src/nsCommentNode.cpp
content/base/src/nsContentUtils.cpp
content/base/src/nsDOMAttribute.cpp
content/base/src/nsDOMAttributeMap.cpp
content/base/src/nsDOMDocumentType.cpp
content/base/src/nsDOMDocumentType.h
content/base/src/nsDocument.cpp
content/base/src/nsDocumentFragment.cpp
content/base/src/nsGenericDOMDataNode.cpp
content/base/src/nsGenericElement.cpp
content/base/src/nsGkAtomList.h
content/base/src/nsNodeInfo.cpp
content/base/src/nsNodeInfo.h
content/base/src/nsNodeInfoManager.cpp
content/base/src/nsNodeInfoManager.h
content/base/src/nsNodeUtils.cpp
content/base/src/nsTextNode.cpp
content/html/content/src/nsHTMLAudioElement.cpp
content/html/content/src/nsHTMLImageElement.cpp
content/html/content/src/nsHTMLOptionElement.cpp
content/html/content/src/nsTextEditorState.cpp
content/html/document/src/ImageDocument.cpp
content/html/document/src/MediaDocument.cpp
content/html/document/src/PluginDocument.cpp
content/html/document/src/VideoDocument.cpp
content/html/document/src/nsHTMLContentSink.cpp
content/html/document/src/nsHTMLFragmentContentSink.cpp
content/svg/content/src/nsSVGElement.cpp
content/svg/content/src/nsSVGUseElement.cpp
content/xbl/src/nsXBLContentSink.cpp
content/xml/content/src/nsXMLCDATASection.cpp
content/xml/content/src/nsXMLProcessingInstruction.cpp
content/xml/content/src/nsXMLProcessingInstruction.h
content/xml/content/src/nsXMLStylesheetPI.cpp
content/xml/document/src/nsXMLContentSink.cpp
content/xml/document/src/nsXMLFragmentContentSink.cpp
content/xslt/src/xslt/txMozillaTextOutput.cpp
content/xslt/src/xslt/txMozillaXMLOutput.cpp
content/xtf/src/nsXTFElementWrapper.cpp
content/xul/content/src/nsXULElement.cpp
content/xul/document/src/nsXULContentSink.cpp
content/xul/document/src/nsXULDocument.cpp
content/xul/document/src/nsXULPrototypeDocument.cpp
content/xul/templates/src/nsXULContentBuilder.cpp
layout/base/nsCSSFrameConstructor.cpp
layout/build/nsContentDLF.cpp
layout/forms/nsComboboxControlFrame.cpp
layout/forms/nsFileControlFrame.cpp
layout/forms/nsIsIndexFrame.cpp
layout/forms/nsProgressFrame.cpp
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsVideoFrame.cpp
layout/xul/base/src/nsDocElementBoxFrame.cpp
parser/html/nsHtml5TreeOperation.cpp
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -541,16 +541,17 @@ public:
 
   static nsresult SplitQName(const nsIContent* aNamespaceResolver,
                              const nsAFlatString& aQName,
                              PRInt32 *aNamespace, nsIAtom **aLocalName);
 
   static nsresult GetNodeInfoFromQName(const nsAString& aNamespaceURI,
                                        const nsAString& aQualifiedName,
                                        nsNodeInfoManager* aNodeInfoManager,
+                                       PRUint16 aNodeType,
                                        nsINodeInfo** aNodeInfo);
 
   static void SplitExpatName(const PRUnichar *aExpatName, nsIAtom **aPrefix,
                              nsIAtom **aTagName, PRInt32 *aNameSpaceID);
 
   // Get a permission-manager setting for the given uri and type.
   // If the pref doesn't exist or if it isn't ALLOW_ACTION, PR_FALSE is
   // returned, otherwise PR_TRUE is returned.
@@ -684,17 +685,19 @@ public:
    * from aNodeInfo.
    */
   static nsresult NameChanged(nsINodeInfo *aNodeInfo, nsIAtom *aName,
                               nsINodeInfo** aResult)
   {
     nsNodeInfoManager *niMgr = aNodeInfo->NodeInfoManager();
 
     *aResult = niMgr->GetNodeInfo(aName, aNodeInfo->GetPrefixAtom(),
-                                  aNodeInfo->NamespaceID()).get();
+                                  aNodeInfo->NamespaceID(),
+                                  aNodeInfo->NodeType(),
+                                  aNodeInfo->GetExtraName()).get();
     return *aResult ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
   }
 
   /**
    * Returns the appropriate event argument names for the specified
    * namespace and event name.  Added because we need to switch between
    * SVG's "evt" and the rest of the world's "event", and because onerror
    * takes 3 args.
--- a/content/base/public/nsINodeInfo.h
+++ b/content/base/public/nsINodeInfo.h
@@ -76,17 +76,17 @@ class nsIPrincipal;
  { 0x95, 0x90, 0xcc, 0x43, 0x6b, 0xe9, 0xcf, 0xa0 } }
 
 class nsINodeInfo : public nsISupports
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_INODEINFO_IID)
 
   nsINodeInfo()
-    : mInner(nsnull, nsnull, kNameSpaceID_None),
+    : mInner(nsnull, nsnull, kNameSpaceID_None, 0, nsnull),
       mOwnerManager(nsnull)
   {
   }
 
   /*
    * Get the name from this node as a string, this does not include the prefix.
    *
    * For the HTML element "<body>" this will return "body" and for the XML
@@ -154,41 +154,46 @@ public:
    */
   nsIAtom* GetPrefixAtom() const
   {
     return mInner.mPrefix;
   }
 
   /*
    * Get the namespace URI for a node, if the node has a namespace URI.
-   *
-   * For the HTML element "<body>" in a HTML document this will return a null
-   * string and for the XML element "<html:body>" (assuming that this element,
-   * or one of its ancestors has an
-   * xmlns:html='http://www.w3.org/1999/xhtml' attribute) this will return
-   * the string "http://www.w3.org/1999/xhtml".
    */
   virtual nsresult GetNamespaceURI(nsAString& aNameSpaceURI) const = 0;
 
   /*
    * Get the namespace ID for a node if the node has a namespace, if not this
    * returns kNameSpaceID_None.
-   *
-   * For the HTML element "<body>" in a HTML document this will return
-   * kNameSpaceID_None and for the XML element "<html:body>" (assuming that
-   * this element, or one of its ancestors has an
-   * xmlns:html='http://www.w3.org/1999/xhtml' attribute) this will return
-   * the namespace ID for "http://www.w3.org/1999/xhtml".
    */
   PRInt32 NamespaceID() const
   {
     return mInner.mNamespaceID;
   }
 
   /*
+   * Get the nodetype for the node. Returns the values specified in nsIDOMNode
+   * for nsIDOMNode.nodeType
+   */
+  PRUint16 NodeType() const
+  {
+    return mInner.mNodeType;
+  }
+
+  /*
+   * Get the extra name, used by PIs and DocTypes, for the node.
+   */
+  nsIAtom* GetExtraName() const
+  {
+    return mInner.mExtraName;
+  }
+
+  /*
    * Get and set the ID attribute atom for this node.
    * See http://www.w3.org/TR/1998/REC-xml-19980210#sec-attribute-types
    * for the definition of an ID attribute.
    *
    */
   nsIAtom* GetIDAttributeAtom() const
   {
     return mIDAttributeAtom;
@@ -317,34 +322,38 @@ protected:
    * the key is automatically deleted.
    */
 
   class nsNodeInfoInner
   {
   public:
     nsNodeInfoInner()
       : mName(nsnull), mPrefix(nsnull), mNamespaceID(kNameSpaceID_Unknown),
-        mNameString(nsnull)
+        mNodeType(0), mNameString(nsnull), mExtraName(nsnull)
     {
     }
-    nsNodeInfoInner(nsIAtom *aName, nsIAtom *aPrefix, PRInt32 aNamespaceID)
+    nsNodeInfoInner(nsIAtom *aName, nsIAtom *aPrefix, PRInt32 aNamespaceID,
+                    PRUint16 aNodeType, nsIAtom* aExtraName)
       : mName(aName), mPrefix(aPrefix), mNamespaceID(aNamespaceID),
-        mNameString(nsnull)
+        mNodeType(aNodeType), mNameString(nsnull), mExtraName(aExtraName)
     {
     }
-    nsNodeInfoInner(const nsAString& aTmpName, nsIAtom *aPrefix, PRInt32 aNamespaceID)
+    nsNodeInfoInner(const nsAString& aTmpName, nsIAtom *aPrefix,
+                    PRInt32 aNamespaceID, PRUint16 aNodeType)
       : mName(nsnull), mPrefix(aPrefix), mNamespaceID(aNamespaceID),
-        mNameString(&aTmpName)
+        mNodeType(aNodeType), mNameString(&aTmpName), mExtraName(nsnull)
     {
     }
 
     nsIAtom*            mName;
     nsIAtom*            mPrefix;
     PRInt32             mNamespaceID;
+    PRUint16            mNodeType; // As defined by nsIDOMNode.nodeType
     const nsAString*    mNameString;
+    nsIAtom*            mExtraName; // Only used by PIs and DocTypes
   };
 
   // nsNodeInfoManager needs to pass mInner to the hash table.
   friend class nsNodeInfoManager;
 
   nsNodeInfoInner mInner;
 
   nsCOMPtr<nsIAtom> mIDAttributeAtom;
@@ -356,13 +365,20 @@ protected:
    */
 
   // Qualified name
   nsString mQualifiedName;
 
   // Qualified name in "corrected case"; this will depend on our
   // document and on mNamespaceID.
   nsString mQualifiedNameCorrectedCase;
+
+  // nodeName for the node.
+  nsString mNodeName;
+
+  // localName for the node. This is either equal to mInner.mName, or a
+  // void string, depending on mInner.mNodeType.
+  nsString mLocalName;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsINodeInfo, NS_INODEINFO_IID)
 
 #endif /* nsINodeInfo_h___ */
--- a/content/base/src/nsCommentNode.cpp
+++ b/content/base/src/nsCommentNode.cpp
@@ -101,16 +101,18 @@ NS_NewCommentNode(nsIContent** aInstance
   NS_ADDREF(*aInstancePtrResult = instance);
 
   return NS_OK;
 }
 
 nsCommentNode::nsCommentNode(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsGenericDOMDataNode(aNodeInfo)
 {
+  NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::COMMENT_NODE,
+                    "Bad NodeType in aNodeInfo");
 }
 
 nsCommentNode::~nsCommentNode()
 {
 }
 
 DOMCI_NODE_DATA(Comment, nsCommentNode)
 
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -2083,16 +2083,17 @@ nsContentUtils::SplitQName(const nsICont
   return NS_OK;
 }
 
 // static
 nsresult
 nsContentUtils::GetNodeInfoFromQName(const nsAString& aNamespaceURI,
                                      const nsAString& aQualifiedName,
                                      nsNodeInfoManager* aNodeInfoManager,
+                                     PRUint16 aNodeType,
                                      nsINodeInfo** aNodeInfo)
 {
   nsIParserService* parserService = GetParserService();
   NS_ENSURE_TRUE(parserService, NS_ERROR_FAILURE);
 
   const nsAFlatString& qName = PromiseFlatString(aQualifiedName);
   const PRUnichar* colon;
   nsresult rv = parserService->CheckQName(qName, PR_TRUE, &colon);
@@ -2102,21 +2103,21 @@ nsContentUtils::GetNodeInfoFromQName(con
   sNameSpaceManager->RegisterNameSpace(aNamespaceURI, nsID);
   if (colon) {
     const PRUnichar* end;
     qName.EndReading(end);
 
     nsCOMPtr<nsIAtom> prefix = do_GetAtom(Substring(qName.get(), colon));
 
     rv = aNodeInfoManager->GetNodeInfo(Substring(colon + 1, end), prefix,
-                                       nsID, aNodeInfo);
+                                       nsID, aNodeType, aNodeInfo);
   }
   else {
     rv = aNodeInfoManager->GetNodeInfo(aQualifiedName, nsnull, nsID,
-                                       aNodeInfo);
+                                       aNodeType, aNodeInfo);
   }
   NS_ENSURE_SUCCESS(rv, rv);
 
   return nsContentUtils::IsValidNodeName((*aNodeInfo)->NameAtom(),
                                          (*aNodeInfo)->GetPrefixAtom(),
                                          (*aNodeInfo)->NamespaceID()) ?
          NS_OK : NS_ERROR_DOM_NAMESPACE_ERR;
 }
--- a/content/base/src/nsDOMAttribute.cpp
+++ b/content/base/src/nsDOMAttribute.cpp
@@ -67,17 +67,18 @@ using namespace mozilla::dom;
 PRBool nsDOMAttribute::sInitialized;
 
 nsDOMAttribute::nsDOMAttribute(nsDOMAttributeMap *aAttrMap,
                                already_AddRefed<nsINodeInfo> aNodeInfo,
                                const nsAString   &aValue, PRBool aNsAware)
   : nsIAttribute(aAttrMap, aNodeInfo, aNsAware), mValue(aValue), mChild(nsnull)
 {
   NS_ABORT_IF_FALSE(mNodeInfo, "We must get a nodeinfo here!");
-
+  NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::ATTRIBUTE_NODE,
+                    "Wrong nodeType");
 
   // We don't add a reference to our content. It will tell us
   // to drop our reference when it goes away.
 
   EnsureChildState();
 
   nsIContent* content = GetContentInternal();
   if (content) {
@@ -187,17 +188,18 @@ nsDOMAttribute::SetOwnerDocument(nsIDocu
   NS_ASSERTION(doc != aDocument, "bad call to nsDOMAttribute::SetOwnerDocument");
   if (doc) {
     doc->DeleteAllPropertiesFor(this);
   }
 
   nsCOMPtr<nsINodeInfo> newNodeInfo;
   newNodeInfo = aDocument->NodeInfoManager()->
     GetNodeInfo(mNodeInfo->NameAtom(), mNodeInfo->GetPrefixAtom(),
-                mNodeInfo->NamespaceID());
+                mNodeInfo->NamespaceID(),
+                nsIDOMNode::ATTRIBUTE_NODE);
   NS_ENSURE_TRUE(newNodeInfo, NS_ERROR_OUT_OF_MEMORY);
   NS_ASSERTION(newNodeInfo, "GetNodeInfo lies");
   mNodeInfo.swap(newNodeInfo);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
--- a/content/base/src/nsDOMAttributeMap.cpp
+++ b/content/base/src/nsDOMAttributeMap.cpp
@@ -336,17 +336,18 @@ nsDOMAttributeMap::SetNamedItemInternal(
         if (mContent->IsInHTMLDocument() &&
             mContent->IsHTML()) {
           nsAutoString lower;
           ToLowerCase(name, lower);
           name = lower;
         }
 
         rv = mContent->NodeInfo()->NodeInfoManager()->
-          GetNodeInfo(name, nsnull, kNameSpaceID_None, getter_AddRefs(ni));
+          GetNodeInfo(name, nsnull, kNameSpaceID_None,
+                      nsIDOMNode::ATTRIBUTE_NODE, getter_AddRefs(ni));
         NS_ENSURE_SUCCESS(rv, rv);
         // value is already empty
       }
     }
 
     nsAutoString value;
     attribute->GetValue(value);
 
@@ -402,17 +403,18 @@ nsDOMAttributeMap::GetItemAt(PRUint32 aI
   nsDOMAttribute* node = nsnull;
 
   const nsAttrName* name;
   if (mContent && (name = mContent->GetAttrNameAt(aIndex))) {
     // Don't use the nodeinfo even if one exists since it can
     // have the wrong owner document.
     nsCOMPtr<nsINodeInfo> ni;
     ni = mContent->NodeInfo()->NodeInfoManager()->
-      GetNodeInfo(name->LocalName(), name->GetPrefix(), name->NamespaceID());
+      GetNodeInfo(name->LocalName(), name->GetPrefix(), name->NamespaceID(),
+                  nsIDOMNode::ATTRIBUTE_NODE);
     if (ni) {
       node = GetAttribute(ni, PR_TRUE);
     }
     else {
       *aResult = NS_ERROR_OUT_OF_MEMORY;
     }
   }
 
@@ -479,17 +481,18 @@ nsDOMAttributeMap::GetNamedItemNSInterna
     const nsAttrName* name = mContent->GetAttrNameAt(i);
     PRInt32 attrNS = name->NamespaceID();
     nsIAtom* nameAtom = name->LocalName();
 
     if (nameSpaceID == attrNS &&
         nameAtom->Equals(aLocalName)) {
       nsCOMPtr<nsINodeInfo> ni;
       ni = mContent->NodeInfo()->NodeInfoManager()->
-        GetNodeInfo(nameAtom, name->GetPrefix(), nameSpaceID);
+        GetNodeInfo(nameAtom, name->GetPrefix(), nameSpaceID,
+                    nsIDOMNode::ATTRIBUTE_NODE);
       NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
 
       if (aRemove) {
         return RemoveAttribute(ni, aReturn);
       }
 
       NS_ADDREF(*aReturn = GetAttribute(ni, PR_TRUE));
 
--- a/content/base/src/nsDOMDocumentType.cpp
+++ b/content/base/src/nsDOMDocumentType.cpp
@@ -73,39 +73,41 @@ NS_NewDOMDocumentType(nsIDOMDocumentType
   else {
     nimgr = new nsNodeInfoManager();
     nsresult rv = nimgr->Init(nsnull);
     NS_ENSURE_SUCCESS(rv, rv);
 
     nimgr->SetDocumentPrincipal(aPrincipal);
   }
 
-  nsCOMPtr<nsINodeInfo> ni;
-  ni = nimgr->GetNodeInfo(nsGkAtoms::documentTypeNodeName, nsnull,
-                          kNameSpaceID_None);
+  nsCOMPtr<nsINodeInfo> ni =
+    nimgr->GetNodeInfo(nsGkAtoms::documentTypeNodeName, nsnull,
+                       kNameSpaceID_None,
+                       nsIDOMNode::DOCUMENT_TYPE_NODE,
+                       aName);
   NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
 
-  *aDocType = new nsDOMDocumentType(ni.forget(), aName, aPublicId, aSystemId,
+  *aDocType = new nsDOMDocumentType(ni.forget(), aPublicId, aSystemId,
                                     aInternalSubset);
   NS_ADDREF(*aDocType);
 
   return NS_OK;
 }
 
 nsDOMDocumentType::nsDOMDocumentType(already_AddRefed<nsINodeInfo> aNodeInfo,
-                                     nsIAtom *aName,
                                      const nsAString& aPublicId,
                                      const nsAString& aSystemId,
                                      const nsAString& aInternalSubset) :
   nsDOMDocumentTypeForward(aNodeInfo),
-  mName(aName),
   mPublicId(aPublicId),
   mSystemId(aSystemId),
   mInternalSubset(aInternalSubset)
 {
+  NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::DOCUMENT_TYPE_NODE,
+                    "Bad NodeType in aNodeInfo");
 }
 
 nsDOMDocumentType::~nsDOMDocumentType()
 {
 }
 
 DOMCI_NODE_DATA(DocumentType, nsDOMDocumentType)
 
@@ -128,17 +130,17 @@ nsDOMDocumentType::IsNodeOfType(PRUint32
   // data nodes (they have a null .nodeValue and don't implement
   // nsIDOMCharacterData)
   return !(aFlags & ~eCONTENT);
 }
 
 void
 nsDOMDocumentType::NodeName(nsAString& aNodeName)
 {
-  mName->ToString(aNodeName);
+  mNodeInfo->GetExtraName()->ToString(aNodeName);
 }
 
 PRUint16
 nsDOMDocumentType::NodeType()
 {
   return (PRUint16)nsIDOMNode::DOCUMENT_TYPE_NODE;
 }
 
@@ -146,17 +148,17 @@ const nsTextFragment*
 nsDOMDocumentType::GetText()
 {
   return nsnull;
 }
 
 NS_IMETHODIMP    
 nsDOMDocumentType::GetName(nsAString& aName)
 {
-  mName->ToString(aName);
+  mNodeInfo->GetExtraName()->ToString(aName);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMDocumentType::GetPublicId(nsAString& aPublicId)
 {
   aPublicId = mPublicId;
 
@@ -177,17 +179,17 @@ nsDOMDocumentType::GetInternalSubset(nsA
   aInternalSubset = mInternalSubset;
   return NS_OK;
 }
 
 nsGenericDOMDataNode*
 nsDOMDocumentType::CloneDataNode(nsINodeInfo *aNodeInfo, PRBool aCloneText) const
 {
   nsCOMPtr<nsINodeInfo> ni = aNodeInfo;
-  return new nsDOMDocumentType(ni.forget(), mName, mPublicId, mSystemId,
+  return new nsDOMDocumentType(ni.forget(), mPublicId, mSystemId,
                                mInternalSubset);
 }
 
 nsresult
 nsDOMDocumentType::BindToTree(nsIDocument *aDocument, nsIContent *aParent,
                               nsIContent *aBindingParent,
                               PRBool aCompileEventHandlers)
 {
@@ -203,17 +205,19 @@ nsDOMDocumentType::BindToTree(nsIDocumen
     //     break inserting DOMDocumentType nodes through other DOM methods
     //     though.
     nsNodeInfoManager *nimgr = aParent ?
       aParent->NodeInfo()->NodeInfoManager() :
       aDocument->NodeInfoManager();
     nsCOMPtr<nsINodeInfo> newNodeInfo;
     newNodeInfo = nimgr->GetNodeInfo(mNodeInfo->NameAtom(),
                                      mNodeInfo->GetPrefixAtom(),
-                                     mNodeInfo->NamespaceID());
+                                     mNodeInfo->NamespaceID(),
+                                     nsIDOMNode::DOCUMENT_TYPE_NODE,
+                                     mNodeInfo->GetExtraName());
     NS_ENSURE_TRUE(newNodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
     mNodeInfo.swap(newNodeInfo);
 
     JSObject *oldScope = GetWrapper();
     if (oldScope) {
       nsIXPConnect *xpc = nsContentUtils::XPConnect();
 
--- a/content/base/src/nsDOMDocumentType.h
+++ b/content/base/src/nsDOMDocumentType.h
@@ -65,17 +65,16 @@ public:
   // nsIDOMNode
   NS_FORWARD_NSIDOMNODE(nsGenericDOMDataNode::)
 };
 
 class nsDOMDocumentType : public nsDOMDocumentTypeForward
 {
 public:
   nsDOMDocumentType(already_AddRefed<nsINodeInfo> aNodeInfo,
-                    nsIAtom *aName,
                     const nsAString& aPublicId,
                     const nsAString& aSystemId,
                     const nsAString& aInternalSubset);
 
   virtual ~nsDOMDocumentType();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
@@ -108,17 +107,16 @@ public:
                               nsIContent *aBindingParent,
                               PRBool aCompileEventHandlers);
 
   virtual nsGenericDOMDataNode* CloneDataNode(nsINodeInfo *aNodeInfo,
                                               PRBool aCloneText) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
 protected:
-  nsCOMPtr<nsIAtom> mName;
   nsString mPublicId;
   nsString mSystemId;
   nsString mInternalSubset;
 };
 
 nsresult
 NS_NewDOMDocumentType(nsIDOMDocumentType** aDocType,
                       nsNodeInfoManager *aOwnerDoc,
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -1992,16 +1992,18 @@ nsDocument::Init()
 
   NS_ADDREF(mNodeInfoManager);
 
   nsresult  rv = mNodeInfoManager->Init(this);
   NS_ENSURE_SUCCESS(rv, rv);
 
   mNodeInfo = mNodeInfoManager->GetDocumentNodeInfo();
   NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_OUT_OF_MEMORY);
+  NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::DOCUMENT_NODE,
+                    "Bad NodeType in aNodeInfo");
 
   NS_ASSERTION(GetOwnerDoc() == this, "Our nodeinfo is busted!");
 
   mScriptLoader = new nsScriptLoader(this);
   NS_ENSURE_TRUE(mScriptLoader, NS_ERROR_OUT_OF_MEMORY);
 
   if (!mImageTracker.Init()) {
     return NS_ERROR_OUT_OF_MEMORY;
@@ -4379,16 +4381,17 @@ nsresult
 nsDocument::CreateElementNS(const nsAString& aNamespaceURI,
                             const nsAString& aQualifiedName,
                             nsIContent** aReturn)
 {
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nsresult rv = nsContentUtils::GetNodeInfoFromQName(aNamespaceURI,
                                                      aQualifiedName,
                                                      mNodeInfoManager,
+                                                     nsIDOMNode::ELEMENT_NODE,
                                                      getter_AddRefs(nodeInfo));
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRInt32 ns = nodeInfo->NamespaceID();
   return NS_NewElement(aReturn, ns,
                        nodeInfo.forget(), NOT_FROM_PARSER);
 }
 
@@ -4511,16 +4514,17 @@ nsDocument::CreateAttribute(const nsAStr
   nsresult rv = nsContentUtils::CheckQName(aName, PR_FALSE);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAutoString value;
   nsDOMAttribute* attribute;
 
   nsCOMPtr<nsINodeInfo> nodeInfo;
   rv = mNodeInfoManager->GetNodeInfo(aName, nsnull, kNameSpaceID_None,
+                                     nsIDOMNode::ATTRIBUTE_NODE,
                                      getter_AddRefs(nodeInfo));
   NS_ENSURE_SUCCESS(rv, rv);
 
   attribute = new nsDOMAttribute(nsnull, nodeInfo.forget(), value, PR_FALSE);
   NS_ENSURE_TRUE(attribute, NS_ERROR_OUT_OF_MEMORY);
 
   return CallQueryInterface(attribute, aReturn);
 }
@@ -4532,16 +4536,17 @@ nsDocument::CreateAttributeNS(const nsAS
 {
   NS_ENSURE_ARG_POINTER(aResult);
   *aResult = nsnull;
 
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nsresult rv = nsContentUtils::GetNodeInfoFromQName(aNamespaceURI,
                                                      aQualifiedName,
                                                      mNodeInfoManager,
+                                                     nsIDOMNode::ATTRIBUTE_NODE,
                                                      getter_AddRefs(nodeInfo));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAutoString value;
   nsDOMAttribute* attribute =
     new nsDOMAttribute(nsnull, nodeInfo.forget(), value, PR_TRUE);
   NS_ENSURE_TRUE(attribute, NS_ERROR_OUT_OF_MEMORY);
 
@@ -5194,17 +5199,18 @@ nsDocument::SetTitle(const nsAString& aT
   if (!title) {
     Element *head = GetHeadElement();
     if (!head)
       return NS_OK;
 
     {
       nsCOMPtr<nsINodeInfo> titleInfo;
       titleInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::title, nsnull,
-                                                kNameSpaceID_XHTML);
+                                                kNameSpaceID_XHTML,
+                                                nsIDOMNode::ELEMENT_NODE);
       if (!titleInfo)
         return NS_OK;
       title = NS_NewHTMLTitleElement(titleInfo.forget());
       if (!title)
         return NS_OK;
     }
 
     head->AppendChildTo(title, PR_TRUE);
@@ -6924,16 +6930,17 @@ nsDocument::CreateElem(const nsAString& 
 
   *aResult = nsnull;
   
   PRInt32 elementType = aDocumentDefaultType ? mDefaultElementType :
     aNamespaceID;
 
   nsCOMPtr<nsINodeInfo> nodeInfo;
   mNodeInfoManager->GetNodeInfo(aName, aPrefix, aNamespaceID,
+                                nsIDOMNode::ELEMENT_NODE,
                                 getter_AddRefs(nodeInfo));
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   return NS_NewElement(aResult, elementType, nodeInfo.forget(),
                        NOT_FROM_PARSER);
 }
 
 PRBool
--- a/content/base/src/nsDocumentFragment.cpp
+++ b/content/base/src/nsDocumentFragment.cpp
@@ -137,17 +137,18 @@ protected:
 nsresult
 NS_NewDocumentFragment(nsIDOMDocumentFragment** aInstancePtrResult,
                        nsNodeInfoManager *aNodeInfoManager)
 {
   NS_ENSURE_ARG(aNodeInfoManager);
 
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nodeInfo = aNodeInfoManager->GetNodeInfo(nsGkAtoms::documentFragmentNodeName,
-                                           nsnull, kNameSpaceID_None);
+                                           nsnull, kNameSpaceID_None,
+                                           nsIDOMNode::DOCUMENT_FRAGMENT_NODE);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   nsDocumentFragment *it = new nsDocumentFragment(nodeInfo.forget());
   if (!it) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   NS_ADDREF(*aInstancePtrResult = it);
--- a/content/base/src/nsGenericDOMDataNode.cpp
+++ b/content/base/src/nsGenericDOMDataNode.cpp
@@ -67,16 +67,23 @@
 #include "pldhash.h"
 #include "prprf.h"
 
 namespace css = mozilla::css;
 
 nsGenericDOMDataNode::nsGenericDOMDataNode(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsIContent(aNodeInfo)
 {
+  NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::TEXT_NODE ||
+                    mNodeInfo->NodeType() == nsIDOMNode::CDATA_SECTION_NODE ||
+                    mNodeInfo->NodeType() == nsIDOMNode::COMMENT_NODE ||
+                    mNodeInfo->NodeType() ==
+                      nsIDOMNode::PROCESSING_INSTRUCTION_NODE ||
+                    mNodeInfo->NodeType() == nsIDOMNode::DOCUMENT_TYPE_NODE,
+                    "Bad NodeType in aNodeInfo");
 }
 
 nsGenericDOMDataNode::~nsGenericDOMDataNode()
 {
   NS_PRECONDITION(!IsInDoc(),
                   "Please remove this from the document properly");
 }
 
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -2218,16 +2218,23 @@ nsGenericElement::nsDOMSlots::~nsDOMSlot
   if (mClassList) {
     mClassList->DropReference();
   }
 }
 
 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)),
+                    "Bad NodeType in aNodeInfo");
+
   // Set the default scriptID to JS - but skip SetScriptTypeID as it
   // does extra work we know isn't necessary here...
   SetFlags((nsIProgrammingLanguage::JAVASCRIPT << NODE_SCRIPT_TYPE_OFFSET));
   SetIsElement();
 }
 
 nsGenericElement::~nsGenericElement()
 {
@@ -2574,16 +2581,17 @@ 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, PR_TRUE);
 }
 
 nsresult
@@ -3450,18 +3458,19 @@ nsGenericElement::GetExistingAttrNameFro
 {
   const nsAttrName* name = InternalGetExistingAttrNameFromQName(aStr);
   if (!name) {
     return nsnull;
   }
 
   nsINodeInfo* nodeInfo;
   if (name->IsAtom()) {
-    nodeInfo = mNodeInfo->NodeInfoManager()->GetNodeInfo(name->Atom(), nsnull,
-                                                         kNameSpaceID_None).get();
+    nodeInfo = mNodeInfo->NodeInfoManager()->
+      GetNodeInfo(name->Atom(), nsnull, kNameSpaceID_None,
+                  nsIDOMNode::ATTRIBUTE_NODE).get();
   }
   else {
     NS_ADDREF(nodeInfo = name->NodeInfo());
   }
 
   return nodeInfo;
 }
 
@@ -4690,17 +4699,18 @@ nsGenericElement::SetAttrAndNotify(PRInt
     if (!IsAttributeMapped(aName) ||
         !SetMappedAttribute(document, aName, aParsedValue, &rv)) {
       rv = mAttrsAndChildren.SetAndTakeAttr(aName, aParsedValue);
     }
   }
   else {
     nsCOMPtr<nsINodeInfo> ni;
     ni = mNodeInfo->NodeInfoManager()->GetNodeInfo(aName, aPrefix,
-                                                   aNamespaceID);
+                                                   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)) {
     nsIDocument* ownerDoc = GetOwnerDoc();
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -1084,16 +1084,17 @@ GK_ATOM(headerWindowTarget, "window-targ
 GK_ATOM(withParam, "with-param")
 GK_ATOM(wizard, "wizard")
 GK_ATOM(wrap, "wrap")
 GK_ATOM(headerDNSPrefetchControl,"x-dns-prefetch-control")
 GK_ATOM(headerCSP, "x-content-security-policy")
 GK_ATOM(headerCSPReportOnly, "x-content-security-policy-report-only")
 GK_ATOM(headerXFO, "x-frame-options")
 GK_ATOM(xml, "xml")
+GK_ATOM(xml_stylesheet, "xml-stylesheet")
 GK_ATOM(xmlns, "xmlns")
 GK_ATOM(xmp, "xmp")
 GK_ATOM(xulcontentsgenerated, "xulcontentsgenerated")
 GK_ATOM(yes, "yes")
 GK_ATOM(z_index, "z-index")
 GK_ATOM(zeroDigit, "zero-digit")
 
 
--- a/content/base/src/nsNodeInfo.cpp
+++ b/content/base/src/nsNodeInfo.cpp
@@ -64,16 +64,17 @@ static const PRInt32 kNodeInfoPoolInitia
   (NS_SIZE_IN_HEAP(sizeof(nsNodeInfo))) * 64;
 
 // static
 nsFixedSizeAllocator* nsNodeInfo::sNodeInfoPool = nsnull;
 
 // static
 nsNodeInfo*
 nsNodeInfo::Create(nsIAtom *aName, nsIAtom *aPrefix, PRInt32 aNamespaceID,
+                   PRUint16 aNodeType, nsIAtom *aExtraName,
                    nsNodeInfoManager *aOwnerManager)
 {
   if (!sNodeInfoPool) {
     sNodeInfoPool = new nsFixedSizeAllocator();
     if (!sNodeInfoPool)
       return nsnull;
 
     nsresult rv = sNodeInfoPool->Init("NodeInfo Pool", kNodeInfoPoolSizes,
@@ -83,66 +84,90 @@ nsNodeInfo::Create(nsIAtom *aName, nsIAt
       sNodeInfoPool = nsnull;
       return nsnull;
     }
   }
 
   // Create a new one
   void* place = sNodeInfoPool->Alloc(sizeof(nsNodeInfo));
   return place ?
-    new (place) nsNodeInfo(aName, aPrefix, aNamespaceID, aOwnerManager) :
+    new (place) nsNodeInfo(aName, aPrefix, aNamespaceID, aNodeType, aExtraName,
+                           aOwnerManager) :
     nsnull;
 }
 
 nsNodeInfo::~nsNodeInfo()
 {
   mOwnerManager->RemoveNodeInfo(this);
   NS_RELEASE(mOwnerManager);
 
   NS_RELEASE(mInner.mName);
   NS_IF_RELEASE(mInner.mPrefix);
+  NS_IF_RELEASE(mInner.mExtraName);
 }
 
 
 nsNodeInfo::nsNodeInfo(nsIAtom *aName, nsIAtom *aPrefix, PRInt32 aNamespaceID,
+                       PRUint16 aNodeType, nsIAtom* aExtraName,
                        nsNodeInfoManager *aOwnerManager)
 {
-  NS_ABORT_IF_FALSE(aName, "Must have a name");
-  NS_ABORT_IF_FALSE(aOwnerManager, "Must have an owner manager");
-
-  mInner.mName = aName;
-  NS_ADDREF(mInner.mName);
+  CHECK_VALID_NODEINFO(aNodeType, aName, aNamespaceID, aExtraName);
+  NS_ABORT_IF_FALSE(aOwnerManager, "Invalid aOwnerManager");
 
-  mInner.mPrefix = aPrefix;
-  NS_IF_ADDREF(mInner.mPrefix);
-
+  // Initialize mInner
+  NS_ADDREF(mInner.mName = aName);
+  NS_IF_ADDREF(mInner.mPrefix = aPrefix);
   mInner.mNamespaceID = aNamespaceID;
-
-  mOwnerManager = aOwnerManager;
-  NS_ADDREF(mOwnerManager);
+  mInner.mNodeType = aNodeType;
+  NS_ADDREF(mOwnerManager = aOwnerManager);
+  NS_IF_ADDREF(mInner.mExtraName = aExtraName);
 
   // Now compute our cached members.
 
   // Qualified name.  If we have no prefix, use ToString on
   // mInner.mName so that we get to share its buffer.
   if (aPrefix) {
-    aPrefix->ToString(mQualifiedName);
-    mQualifiedName.Append(PRUnichar(':'));
-    mQualifiedName.Append(nsDependentAtomString(mInner.mName));
+    mQualifiedName = nsDependentAtomString(mInner.mPrefix) +
+                     NS_LITERAL_STRING(":") +
+                     nsDependentAtomString(mInner.mName);
   } else {
     mInner.mName->ToString(mQualifiedName);
   }
 
   // Qualified name in corrected case
   if (aNamespaceID == kNameSpaceID_XHTML && GetDocument() &&
       GetDocument()->IsHTML()) {
     nsContentUtils::ASCIIToUpper(mQualifiedName, mQualifiedNameCorrectedCase);
   } else {
     mQualifiedNameCorrectedCase = mQualifiedName;
   }
+
+  switch (aNodeType) {
+    case nsIDOMNode::ELEMENT_NODE:
+    case nsIDOMNode::ATTRIBUTE_NODE:
+      mNodeName = mQualifiedNameCorrectedCase;
+      mInner.mName->ToString(mLocalName);
+      break;
+    case nsIDOMNode::TEXT_NODE:
+    case nsIDOMNode::CDATA_SECTION_NODE:
+    case nsIDOMNode::COMMENT_NODE:
+    case nsIDOMNode::DOCUMENT_NODE:
+    case nsIDOMNode::DOCUMENT_FRAGMENT_NODE:
+      mInner.mName->ToString(mNodeName);
+      SetDOMStringToNull(mLocalName);
+      break;
+    case nsIDOMNode::PROCESSING_INSTRUCTION_NODE:
+    case nsIDOMNode::DOCUMENT_TYPE_NODE:
+      mInner.mExtraName->ToString(mNodeName);
+      SetDOMStringToNull(mLocalName);
+      break;
+    default:
+      NS_ABORT_IF_FALSE(aNodeType == PR_UINT16_MAX,
+                        "Unknown node type");
+  }
 }
 
 
 // nsISupports
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsNodeInfo)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_0(nsNodeInfo)
 
--- a/content/base/src/nsNodeInfo.h
+++ b/content/base/src/nsNodeInfo.h
@@ -64,22 +64,24 @@ public:
 
   // nsNodeInfo
   // Create objects with Create
 public:
   /*
    * aName and aOwnerManager may not be null.
    */
   static nsNodeInfo *Create(nsIAtom *aName, nsIAtom *aPrefix,
-                            PRInt32 aNamespaceID,
+                            PRInt32 aNamespaceID, PRUint16 aNodeType,
+                            nsIAtom *aExtraName,
                             nsNodeInfoManager *aOwnerManager);
 private:
   nsNodeInfo(); // Unimplemented
   nsNodeInfo(const nsNodeInfo& aOther); // Unimplemented
   nsNodeInfo(nsIAtom *aName, nsIAtom *aPrefix, PRInt32 aNamespaceID,
+             PRUint16 aNodeType, nsIAtom *aExtraName,
              nsNodeInfoManager *aOwnerManager);
 protected:
   virtual ~nsNodeInfo();
 
 public:
   /**
    * Call before shutdown to clear the cache and free memory for this class.
    */
@@ -91,9 +93,47 @@ private:
   /**
    * This method gets called by Release() when it's time to delete 
    * this object, instead of always deleting the object we'll put the
    * object in the cache unless the cache is already full.
    */
    void LastRelease();
 };
 
+#define CHECK_VALID_NODEINFO(_nodeType, _name, _namespaceID, _extraName)    \
+NS_ABORT_IF_FALSE(_nodeType == nsIDOMNode::ELEMENT_NODE ||                  \
+                  _nodeType == nsIDOMNode::ATTRIBUTE_NODE ||                \
+                  _nodeType == nsIDOMNode::TEXT_NODE ||                     \
+                  _nodeType == nsIDOMNode::CDATA_SECTION_NODE ||            \
+                  _nodeType == nsIDOMNode::PROCESSING_INSTRUCTION_NODE ||   \
+                  _nodeType == nsIDOMNode::COMMENT_NODE ||                  \
+                  _nodeType == nsIDOMNode::DOCUMENT_NODE ||                 \
+                  _nodeType == nsIDOMNode::DOCUMENT_TYPE_NODE ||            \
+                  _nodeType == nsIDOMNode::DOCUMENT_FRAGMENT_NODE ||        \
+                  _nodeType == PR_UINT16_MAX,                               \
+                  "Invalid nodeType");                                      \
+NS_ABORT_IF_FALSE((_nodeType == nsIDOMNode::PROCESSING_INSTRUCTION_NODE ||  \
+                   _nodeType == nsIDOMNode::DOCUMENT_TYPE_NODE) ==          \
+                  (_extraName != nsnull),                                   \
+                  "Supply aExtraName for and only for PIs and doctypes");   \
+NS_ABORT_IF_FALSE(_nodeType == nsIDOMNode::ELEMENT_NODE ||                  \
+                  _nodeType == nsIDOMNode::ATTRIBUTE_NODE ||                \
+                  _nodeType == PR_UINT16_MAX ||                             \
+                  aNamespaceID == kNameSpaceID_None,                        \
+                  "Only attributes and elements can be in a namespace");    \
+NS_ABORT_IF_FALSE(_name && _name != nsGkAtoms::_empty, "Invalid localName");\
+NS_ABORT_IF_FALSE(((_nodeType == nsIDOMNode::TEXT_NODE) ==                  \
+                   (_name == nsGkAtoms::textTagName)) &&                    \
+                  ((_nodeType == nsIDOMNode::CDATA_SECTION_NODE) ==         \
+                   (_name == nsGkAtoms::cdataTagName)) &&                   \
+                  ((_nodeType == nsIDOMNode::COMMENT_NODE) ==               \
+                   (_name == nsGkAtoms::commentTagName)) &&                 \
+                  ((_nodeType == nsIDOMNode::DOCUMENT_NODE) ==              \
+                   (_name == nsGkAtoms::documentNodeName)) &&               \
+                  ((_nodeType == nsIDOMNode::DOCUMENT_FRAGMENT_NODE) ==     \
+                   (_name == nsGkAtoms::documentFragmentNodeName)) &&       \
+                  ((_nodeType == nsIDOMNode::DOCUMENT_TYPE_NODE) ==         \
+                   (_name == nsGkAtoms::documentTypeNodeName)) &&           \
+                  ((_nodeType == nsIDOMNode::PROCESSING_INSTRUCTION_NODE) ==\
+                   (_name == nsGkAtoms::processingInstructionTagName)),     \
+                  "Wrong localName for nodeType");
+
 #endif /* nsNodeInfo_h___ */
--- a/content/base/src/nsNodeInfoManager.cpp
+++ b/content/base/src/nsNodeInfoManager.cpp
@@ -86,17 +86,19 @@ nsNodeInfoManager::NodeInfoInnerKeyCompa
   NS_ASSERTION(key1 && key2, "Null key passed to NodeInfoInnerKeyCompare!");
 
   const nsINodeInfo::nsNodeInfoInner *node1 =
     reinterpret_cast<const nsINodeInfo::nsNodeInfoInner *>(key1);
   const nsINodeInfo::nsNodeInfoInner *node2 =
     reinterpret_cast<const nsINodeInfo::nsNodeInfoInner *>(key2);
 
   if (node1->mPrefix != node2->mPrefix ||
-      node1->mNamespaceID != node2->mNamespaceID) {
+      node1->mNamespaceID != node2->mNamespaceID ||
+      node1->mNodeType != node2->mNodeType ||
+      node1->mExtraName != node2->mExtraName) {
     return 0;
   }
 
   if (node1->mName) {
     if (node2->mName) {
       return (node1->mName == node2->mName);
     }
     return (node1->mName->Equals(*(node2->mNameString)));
@@ -200,36 +202,37 @@ nsNodeInfoManager::DropDocumentReference
   }
 
   mDocument = nsnull;
 }
 
 
 already_AddRefed<nsINodeInfo>
 nsNodeInfoManager::GetNodeInfo(nsIAtom *aName, nsIAtom *aPrefix,
-                               PRInt32 aNamespaceID)
+                               PRInt32 aNamespaceID, PRUint16 aNodeType,
+                               nsIAtom* aExtraName /* = nsnull */)
 {
-  NS_ENSURE_TRUE(aName, nsnull);
-  NS_ASSERTION(!aName->Equals(EmptyString()),
-               "Don't pass an empty string to GetNodeInfo, fix caller.");
+  CHECK_VALID_NODEINFO(aNodeType, aName, aNamespaceID, aExtraName);
 
-  nsINodeInfo::nsNodeInfoInner tmpKey(aName, aPrefix, aNamespaceID);
+  nsINodeInfo::nsNodeInfoInner tmpKey(aName, aPrefix, aNamespaceID, aNodeType,
+                                      aExtraName);
 
   void *node = PL_HashTableLookup(mNodeInfoHash, &tmpKey);
 
   if (node) {
     nsINodeInfo* nodeInfo = static_cast<nsINodeInfo *>(node);
 
     NS_ADDREF(nodeInfo);
 
     return nodeInfo;
   }
 
   nsRefPtr<nsNodeInfo> newNodeInfo =
-    nsNodeInfo::Create(aName, aPrefix, aNamespaceID, this);
+    nsNodeInfo::Create(aName, aPrefix, aNamespaceID, aNodeType, aExtraName,
+                       this);
   NS_ENSURE_TRUE(newNodeInfo, nsnull);
   
   PLHashEntry *he;
   he = PL_HashTableAdd(mNodeInfoHash, &newNodeInfo->mInner, newNodeInfo);
   NS_ENSURE_TRUE(he, nsnull);
 
   // Have to do the swap thing, because already_AddRefed<nsNodeInfo>
   // doesn't cast to already_AddRefed<nsINodeInfo>
@@ -237,102 +240,111 @@ nsNodeInfoManager::GetNodeInfo(nsIAtom *
   newNodeInfo.swap(nodeInfo);
 
   return nodeInfo;
 }
 
 
 nsresult
 nsNodeInfoManager::GetNodeInfo(const nsAString& aName, nsIAtom *aPrefix,
-                               PRInt32 aNamespaceID, nsINodeInfo** aNodeInfo)
+                               PRInt32 aNamespaceID, PRUint16 aNodeType,
+                               nsINodeInfo** aNodeInfo)
 {
-  NS_ASSERTION(!aName.IsEmpty(),
-               "Don't pass an empty string to GetNodeInfo, fix caller.");
+#ifdef DEBUG
+  {
+    nsCOMPtr<nsIAtom> nameAtom = do_GetAtom(aName);
+    CHECK_VALID_NODEINFO(aNodeType, nameAtom, aNamespaceID, nsnull);
+  }
+#endif
 
-  nsINodeInfo::nsNodeInfoInner tmpKey(aName, aPrefix, aNamespaceID);
+  nsINodeInfo::nsNodeInfoInner tmpKey(aName, aPrefix, aNamespaceID, aNodeType);
 
   void *node = PL_HashTableLookup(mNodeInfoHash, &tmpKey);
 
   if (node) {
     nsINodeInfo* nodeInfo = static_cast<nsINodeInfo *>(node);
 
     NS_ADDREF(*aNodeInfo = nodeInfo);
 
     return NS_OK;
   }
 
   
   nsCOMPtr<nsIAtom> nameAtom = do_GetAtom(aName);
   NS_ENSURE_TRUE(nameAtom, NS_ERROR_OUT_OF_MEMORY);
 
   nsRefPtr<nsNodeInfo> newNodeInfo =
-      nsNodeInfo::Create(nameAtom, aPrefix, aNamespaceID, this);
+      nsNodeInfo::Create(nameAtom, aPrefix, aNamespaceID, aNodeType, nsnull,
+                         this);
   NS_ENSURE_TRUE(newNodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   PLHashEntry *he;
   he = PL_HashTableAdd(mNodeInfoHash, &newNodeInfo->mInner, newNodeInfo);
   NS_ENSURE_TRUE(he, NS_ERROR_FAILURE);
 
   newNodeInfo.forget(aNodeInfo);
 
   return NS_OK;
 }
 
 
 nsresult
 nsNodeInfoManager::GetNodeInfo(const nsAString& aName, nsIAtom *aPrefix,
                                const nsAString& aNamespaceURI,
+                               PRUint16 aNodeType,
                                nsINodeInfo** aNodeInfo)
 {
-  nsCOMPtr<nsIAtom> nameAtom = do_GetAtom(aName);
-  NS_ENSURE_TRUE(nameAtom, NS_ERROR_OUT_OF_MEMORY);
-
   PRInt32 nsid = kNameSpaceID_None;
 
   if (!aNamespaceURI.IsEmpty()) {
     nsresult rv = nsContentUtils::NameSpaceManager()->
       RegisterNameSpace(aNamespaceURI, nsid);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
-  *aNodeInfo = GetNodeInfo(nameAtom, aPrefix, nsid).get();
-  return *aNodeInfo ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
+  return GetNodeInfo(aName, aPrefix, nsid, aNodeType, aNodeInfo);
 }
 
 already_AddRefed<nsINodeInfo>
 nsNodeInfoManager::GetTextNodeInfo()
 {
   if (!mTextNodeInfo) {
-    mTextNodeInfo = GetNodeInfo(nsGkAtoms::textTagName, nsnull, kNameSpaceID_None).get();
+    mTextNodeInfo = GetNodeInfo(nsGkAtoms::textTagName, nsnull,
+                                kNameSpaceID_None,
+                                nsIDOMNode::TEXT_NODE, nsnull).get();
   }
   else {
     NS_ADDREF(mTextNodeInfo);
   }
 
   return mTextNodeInfo;
 }
 
 already_AddRefed<nsINodeInfo>
 nsNodeInfoManager::GetCommentNodeInfo()
 {
   if (!mCommentNodeInfo) {
-    mCommentNodeInfo = GetNodeInfo(nsGkAtoms::commentTagName, nsnull, kNameSpaceID_None).get();
+    mCommentNodeInfo = GetNodeInfo(nsGkAtoms::commentTagName, nsnull,
+                                   kNameSpaceID_None,
+                                   nsIDOMNode::COMMENT_NODE, nsnull).get();
   }
   else {
     NS_ADDREF(mCommentNodeInfo);
   }
 
   return mCommentNodeInfo;
 }
 
 already_AddRefed<nsINodeInfo>
 nsNodeInfoManager::GetDocumentNodeInfo()
 {
   if (!mDocumentNodeInfo) {
-    mDocumentNodeInfo = GetNodeInfo(nsGkAtoms::documentNodeName, nsnull, kNameSpaceID_None).get();
+    mDocumentNodeInfo = GetNodeInfo(nsGkAtoms::documentNodeName, nsnull,
+                                    kNameSpaceID_None,
+                                    nsIDOMNode::DOCUMENT_NODE, nsnull).get();
   }
   else {
     NS_ADDREF(mDocumentNodeInfo);
   }
 
   return mDocumentNodeInfo;
 }
 
--- a/content/base/src/nsNodeInfoManager.h
+++ b/content/base/src/nsNodeInfoManager.h
@@ -80,21 +80,24 @@ public:
    * the document is going away.
    */
   void DropDocumentReference();
 
   /**
    * Methods for creating nodeinfo's from atoms and/or strings.
    */
   already_AddRefed<nsINodeInfo> GetNodeInfo(nsIAtom *aName, nsIAtom *aPrefix,
-                                            PRInt32 aNamespaceID);
+                                            PRInt32 aNamespaceID,
+                                            PRUint16 aNodeType,
+                                            nsIAtom* aExtraName = nsnull);
   nsresult GetNodeInfo(const nsAString& aName, nsIAtom *aPrefix,
-                       PRInt32 aNamespaceID, nsINodeInfo** aNodeInfo);
+                       PRInt32 aNamespaceID, PRUint16 aNodeType,
+                       nsINodeInfo** aNodeInfo);
   nsresult GetNodeInfo(const nsAString& aName, nsIAtom *aPrefix,
-                       const nsAString& aNamespaceURI,
+                       const nsAString& aNamespaceURI, PRUint16 aNodeType,
                        nsINodeInfo** aNodeInfo);
 
   /**
    * Returns the nodeinfo for text nodes. Can return null if OOM.
    */
   already_AddRefed<nsINodeInfo> GetTextNodeInfo();
 
   /**
--- a/content/base/src/nsNodeUtils.cpp
+++ b/content/base/src/nsNodeUtils.cpp
@@ -497,17 +497,19 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNod
       NS_ENSURE_STATE(currentDoc &&
                       (nsContentUtils::IsChromeDoc(currentDoc) ||
                        (!currentDoc->GetScriptHandlingObject(hasHadScriptHandlingObject) &&
                         !hasHadScriptHandlingObject)));
     }
 
     newNodeInfo = nodeInfoManager->GetNodeInfo(nodeInfo->NameAtom(),
                                                nodeInfo->GetPrefixAtom(),
-                                               nodeInfo->NamespaceID());
+                                               nodeInfo->NamespaceID(),
+                                               nodeInfo->NodeType(),
+                                               nodeInfo->GetExtraName());
     NS_ENSURE_TRUE(newNodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
     nodeInfo = newNodeInfo;
   }
 
   nsGenericElement *elem = aNode->IsElement() ?
                            static_cast<nsGenericElement*>(aNode) :
                            nsnull;
--- a/content/base/src/nsTextNode.cpp
+++ b/content/base/src/nsTextNode.cpp
@@ -138,16 +138,18 @@ NS_NewTextNode(nsIContent** aInstancePtr
   NS_ADDREF(*aInstancePtrResult = instance);
 
   return NS_OK;
 }
 
 nsTextNode::nsTextNode(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsGenericDOMDataNode(aNodeInfo)
 {
+  NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::TEXT_NODE,
+                    "Bad NodeType in aNodeInfo");
 }
 
 nsTextNode::~nsTextNode()
 {
 }
 
 NS_IMPL_ADDREF_INHERITED(nsTextNode, nsGenericDOMDataNode)
 NS_IMPL_RELEASE_INHERITED(nsTextNode, nsGenericDOMDataNode)
--- a/content/html/content/src/nsHTMLAudioElement.cpp
+++ b/content/html/content/src/nsHTMLAudioElement.cpp
@@ -79,17 +79,18 @@ NS_NewHTMLAudioElement(already_AddRefed<
    */
   nsCOMPtr<nsINodeInfo> nodeInfo(aNodeInfo);
   if (!nodeInfo) {
     nsCOMPtr<nsIDocument> doc =
       do_QueryInterface(nsContentUtils::GetDocumentFromCaller());
     NS_ENSURE_TRUE(doc, nsnull);
 
     nodeInfo = doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::audio, nsnull,
-                                                   kNameSpaceID_XHTML);
+                                                   kNameSpaceID_XHTML,
+                                                   nsIDOMNode::ELEMENT_NODE);
     NS_ENSURE_TRUE(nodeInfo, nsnull);
   }
 
   return new nsHTMLAudioElement(nodeInfo.forget(), aFromParser);
 }
 
 NS_IMPL_ADDREF_INHERITED(nsHTMLAudioElement, nsHTMLMediaElement)
 NS_IMPL_RELEASE_INHERITED(nsHTMLAudioElement, nsHTMLMediaElement)
--- a/content/html/content/src/nsHTMLImageElement.cpp
+++ b/content/html/content/src/nsHTMLImageElement.cpp
@@ -165,17 +165,18 @@ NS_NewHTMLImageElement(already_AddRefed<
    */
   nsCOMPtr<nsINodeInfo> nodeInfo(aNodeInfo);
   if (!nodeInfo) {
     nsCOMPtr<nsIDocument> doc =
       do_QueryInterface(nsContentUtils::GetDocumentFromCaller());
     NS_ENSURE_TRUE(doc, nsnull);
 
     nodeInfo = doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::img, nsnull,
-                                                   kNameSpaceID_XHTML);
+                                                   kNameSpaceID_XHTML,
+                                                   nsIDOMNode::ELEMENT_NODE);
     NS_ENSURE_TRUE(nodeInfo, nsnull);
   }
 
   return new nsHTMLImageElement(nodeInfo.forget());
 }
 
 nsHTMLImageElement::nsHTMLImageElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsGenericHTMLElement(aNodeInfo)
--- a/content/html/content/src/nsHTMLOptionElement.cpp
+++ b/content/html/content/src/nsHTMLOptionElement.cpp
@@ -102,17 +102,18 @@ NS_NewHTMLOptionElement(already_AddRefed
    */
   nsCOMPtr<nsINodeInfo> nodeInfo(aNodeInfo);
   if (!nodeInfo) {
     nsCOMPtr<nsIDocument> doc =
       do_QueryInterface(nsContentUtils::GetDocumentFromCaller());
     NS_ENSURE_TRUE(doc, nsnull);
 
     nodeInfo = doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::option, nsnull,
-                                                   kNameSpaceID_XHTML);
+                                                   kNameSpaceID_XHTML,
+                                                   nsIDOMNode::ELEMENT_NODE);
     NS_ENSURE_TRUE(nodeInfo, nsnull);
   }
 
   return new nsHTMLOptionElement(nodeInfo.forget());
 }
 
 nsHTMLOptionElement::nsHTMLOptionElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsGenericHTMLElement(aNodeInfo),
--- a/content/html/content/src/nsTextEditorState.cpp
+++ b/content/html/content/src/nsTextEditorState.cpp
@@ -1557,17 +1557,18 @@ nsTextEditorState::CreateRootNode()
   NS_ENSURE_TRUE(shell, NS_ERROR_FAILURE);
 
   nsIDocument *doc = shell->GetDocument();
   NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
 
   // Now create a DIV and add it to the anonymous content child list.
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nodeInfo = doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::div, nsnull,
-                                                 kNameSpaceID_XHTML);
+                                                 kNameSpaceID_XHTML,
+                                                 nsIDOMNode::ELEMENT_NODE);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   nsresult rv = NS_NewHTMLElement(getter_AddRefs(mRootNode), nodeInfo.forget(),
                                   NOT_FROM_PARSER);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Set the necessary classes on the text control. We use class values
   // instead of a 'style' attribute so that the style comes from a user-agent
@@ -1634,17 +1635,18 @@ be called if @placeholder is the empty s
 
   nsresult rv;
   nsCOMPtr<nsIContent> placeholderText;
 
   // Create a DIV for the placeholder
   // and add it to the anonymous content child list
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nodeInfo = pNodeInfoManager->GetNodeInfo(nsGkAtoms::div, nsnull,
-                                           kNameSpaceID_XHTML);
+                                           kNameSpaceID_XHTML,
+                                           nsIDOMNode::ELEMENT_NODE);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   rv = NS_NewHTMLElement(getter_AddRefs(mPlaceholderDiv), nodeInfo.forget(),
                          NOT_FROM_PARSER);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Create the text node for the placeholder text before doing anything else
   rv = NS_NewTextNode(getter_AddRefs(placeholderText), pNodeInfoManager);
--- a/content/html/document/src/ImageDocument.cpp
+++ b/content/html/document/src/ImageDocument.cpp
@@ -646,17 +646,18 @@ ImageDocument::CreateSyntheticDocument()
   Element* body = GetBodyElement();
   if (!body) {
     NS_WARNING("no body on image document!");
     return NS_ERROR_FAILURE;
   }
 
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::img, nsnull,
-                                           kNameSpaceID_XHTML);
+                                           kNameSpaceID_XHTML,
+                                           nsIDOMNode::ELEMENT_NODE);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   mImageContent = NS_NewHTMLImageElement(nodeInfo.forget());
   if (!mImageContent) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
   nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mImageContent);
   NS_ENSURE_TRUE(imageLoader, NS_ERROR_UNEXPECTED);
--- a/content/html/document/src/MediaDocument.cpp
+++ b/content/html/document/src/MediaDocument.cpp
@@ -232,42 +232,45 @@ MediaDocument::StartDocumentLoad(const c
 nsresult
 MediaDocument::CreateSyntheticDocument()
 {
   // Synthesize an empty html document
   nsresult rv;
 
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::html, nsnull,
-                                           kNameSpaceID_XHTML);
+                                           kNameSpaceID_XHTML,
+                                           nsIDOMNode::ELEMENT_NODE);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   nsRefPtr<nsGenericHTMLElement> root = NS_NewHTMLHtmlElement(nodeInfo.forget());
   if (!root) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   NS_ASSERTION(GetChildCount() == 0, "Shouldn't have any kids");
   rv = AppendChildTo(root, PR_FALSE);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::head, nsnull,
-                                           kNameSpaceID_XHTML);
+                                           kNameSpaceID_XHTML,
+                                           nsIDOMNode::ELEMENT_NODE);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   // Create a <head> so our title has somewhere to live
   nsRefPtr<nsGenericHTMLElement> head = NS_NewHTMLHeadElement(nodeInfo.forget());
   if (!head) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   root->AppendChildTo(head, PR_FALSE);
 
   nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::body, nsnull,
-                                           kNameSpaceID_XHTML);
+                                           kNameSpaceID_XHTML,
+                                           nsIDOMNode::ELEMENT_NODE);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   nsRefPtr<nsGenericHTMLElement> body = NS_NewHTMLBodyElement(nodeInfo.forget());
   if (!body) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   root->AppendChildTo(body, PR_FALSE);
--- a/content/html/document/src/PluginDocument.cpp
+++ b/content/html/document/src/PluginDocument.cpp
@@ -293,17 +293,18 @@ PluginDocument::CreateSyntheticPluginDoc
   NS_NAMED_LITERAL_STRING(zero, "0");
   body->SetAttr(kNameSpaceID_None, nsGkAtoms::marginwidth, zero, PR_FALSE);
   body->SetAttr(kNameSpaceID_None, nsGkAtoms::marginheight, zero, PR_FALSE);
 
 
   // make plugin content
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::embed, nsnull,
-                                           kNameSpaceID_XHTML);
+                                           kNameSpaceID_XHTML,
+                                           nsIDOMNode::ELEMENT_NODE);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
   rv = NS_NewHTMLElement(getter_AddRefs(mPluginContent), nodeInfo.forget(),
                          NOT_FROM_PARSER);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // make it a named element
   mPluginContent->SetAttr(kNameSpaceID_None, nsGkAtoms::name,
                           NS_LITERAL_STRING("plugin"), PR_FALSE);
--- a/content/html/document/src/VideoDocument.cpp
+++ b/content/html/document/src/VideoDocument.cpp
@@ -107,17 +107,18 @@ VideoDocument::CreateSyntheticVideoDocum
   if (!body) {
     NS_WARNING("no body on video document!");
     return NS_ERROR_FAILURE;
   }
 
   // make content
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::video, nsnull,
-                                           kNameSpaceID_XHTML);
+                                           kNameSpaceID_XHTML,
+                                           nsIDOMNode::ELEMENT_NODE);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_FAILURE);
 
   nsRefPtr<nsHTMLMediaElement> element =
     static_cast<nsHTMLMediaElement*>(NS_NewHTMLVideoElement(nodeInfo.forget(),
                                                             NOT_FROM_PARSER));
   if (!element)
     return NS_ERROR_OUT_OF_MEMORY;
   element->SetAutoplay(PR_TRUE);
--- a/content/html/document/src/nsHTMLContentSink.cpp
+++ b/content/html/document/src/nsHTMLContentSink.cpp
@@ -529,30 +529,32 @@ HTMLContentSink::CreateContentObject(con
   // Find/create atom for the tag name
 
   nsCOMPtr<nsINodeInfo> nodeInfo;
 
   if (aNodeType == eHTMLTag_userdefined) {
     nsAutoString lower;
     nsContentUtils::ASCIIToLower(aNode.GetText(), lower);
     nsCOMPtr<nsIAtom> name = do_GetAtom(lower);
-    nodeInfo = mNodeInfoManager->GetNodeInfo(name, nsnull, kNameSpaceID_XHTML);
+    nodeInfo = mNodeInfoManager->GetNodeInfo(name, nsnull, kNameSpaceID_XHTML,
+                                             nsIDOMNode::ELEMENT_NODE);
   }
   else if (mNodeInfoCache[aNodeType]) {
     nodeInfo = mNodeInfoCache[aNodeType];
   }
   else {
     nsIParserService *parserService = nsContentUtils::GetParserService();
     if (!parserService)
       return nsnull;
 
     nsIAtom *name = parserService->HTMLIdToAtomTag(aNodeType);
     NS_ASSERTION(name, "What? Reverse mapping of id to string broken!!!");
 
-    nodeInfo = mNodeInfoManager->GetNodeInfo(name, nsnull, kNameSpaceID_XHTML);
+    nodeInfo = mNodeInfoManager->GetNodeInfo(name, nsnull, kNameSpaceID_XHTML,
+                                             nsIDOMNode::ELEMENT_NODE);
     NS_IF_ADDREF(mNodeInfoCache[aNodeType] = nodeInfo);
   }
 
   NS_ENSURE_TRUE(nodeInfo, nsnull);
 
   // Make the content object
   return CreateHTMLElement(aNodeType, nodeInfo.forget(), FROM_PARSER_NETWORK);
 }
@@ -1597,33 +1599,35 @@ HTMLContentSink::Init(nsIDocument* aDoc,
 
 
   // Changed from 8192 to greatly improve page loading performance on
   // large pages.  See bugzilla bug 77540.
   mMaxTextRun = Preferences::GetInt("content.maxtextrun", 8191);
 
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::html, nsnull,
-                                           kNameSpaceID_XHTML);
+                                           kNameSpaceID_XHTML,
+                                           nsIDOMNode::ELEMENT_NODE);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   // Make root part
   mRoot = NS_NewHTMLHtmlElement(nodeInfo.forget());
   if (!mRoot) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   NS_ASSERTION(mDocument->GetChildCount() == 0,
                "Document should have no kids here!");
   rv = mDocument->AppendChildTo(mRoot, PR_FALSE);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Make head part
   nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::head,
-                                           nsnull, kNameSpaceID_XHTML);
+                                           nsnull, kNameSpaceID_XHTML,
+                                           nsIDOMNode::ELEMENT_NODE);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   mHead = NS_NewHTMLHeadElement(nodeInfo.forget());
   if (NS_FAILED(rv)) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   mRoot->AppendChildTo(mHead, PR_FALSE);
@@ -2590,17 +2594,19 @@ nsresult
 HTMLContentSink::ProcessLINKTag(const nsIParserNode& aNode)
 {
   nsresult  result = NS_OK;
 
   if (mCurrentContext) {
     // Create content object
     nsCOMPtr<nsIContent> element;
     nsCOMPtr<nsINodeInfo> nodeInfo;
-    nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::link, nsnull, kNameSpaceID_XHTML);
+    nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::link, nsnull,
+                                             kNameSpaceID_XHTML,
+                                             nsIDOMNode::ELEMENT_NODE);
 
     result = NS_NewHTMLElement(getter_AddRefs(element), nodeInfo.forget(),
                                NOT_FROM_PARSER);
     NS_ENSURE_SUCCESS(result, result);
 
     nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(element));
 
     if (ssle) {
--- a/content/html/document/src/nsHTMLFragmentContentSink.cpp
+++ b/content/html/document/src/nsHTMLFragmentContentSink.cpp
@@ -362,33 +362,35 @@ nsHTMLFragmentContentSink::OpenContainer
     nsCOMPtr<nsINodeInfo> nodeInfo;
 
     if (nodeType == eHTMLTag_userdefined) {
       nsAutoString lower;
       nsContentUtils::ASCIIToLower(aNode.GetText(), lower);
       nsCOMPtr<nsIAtom> name = do_GetAtom(lower);
       nodeInfo = mNodeInfoManager->GetNodeInfo(name, 
                                                nsnull, 
-                                               kNameSpaceID_XHTML);
+                                               kNameSpaceID_XHTML,
+                                               nsIDOMNode::ELEMENT_NODE);
       NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
     }
     else if (mNodeInfoCache[nodeType]) {
       nodeInfo = mNodeInfoCache[nodeType];
     }
     else {
       nsIParserService* parserService = nsContentUtils::GetParserService();
       if (!parserService)
         return NS_ERROR_OUT_OF_MEMORY;
 
       nsIAtom *name = parserService->HTMLIdToAtomTag(nodeType);
       NS_ASSERTION(name, "This should not happen!");
 
       nodeInfo = mNodeInfoManager->GetNodeInfo(name, 
                                                nsnull, 
-                                               kNameSpaceID_XHTML);
+                                               kNameSpaceID_XHTML,
+                                               nsIDOMNode::ELEMENT_NODE);
       NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
       NS_ADDREF(mNodeInfoCache[nodeType] = nodeInfo);
     }
 
     content =
       CreateHTMLElement(nodeType, nodeInfo.forget(), NOT_FROM_PARSER).get();
     NS_ENSURE_TRUE(content, NS_ERROR_OUT_OF_MEMORY);
@@ -456,28 +458,30 @@ nsHTMLFragmentContentSink::AddLeaf(const
 
         nsCOMPtr<nsINodeInfo> nodeInfo;
 
         if (nodeType == eHTMLTag_userdefined) {
           nsAutoString lower;
           nsContentUtils::ASCIIToLower(aNode.GetText(), lower);
           nsCOMPtr<nsIAtom> name = do_GetAtom(lower);
           nodeInfo = mNodeInfoManager->GetNodeInfo(name, nsnull,
-                                                   kNameSpaceID_XHTML);
+                                                   kNameSpaceID_XHTML,
+                                                   nsIDOMNode::ELEMENT_NODE);
           NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
         }
         else if (mNodeInfoCache[nodeType]) {
           nodeInfo = mNodeInfoCache[nodeType];
         }
         else {
           nsIAtom *name = parserService->HTMLIdToAtomTag(nodeType);
           NS_ASSERTION(name, "This should not happen!");
 
           nodeInfo = mNodeInfoManager->GetNodeInfo(name, nsnull,
-                                                   kNameSpaceID_XHTML);
+                                                   kNameSpaceID_XHTML,
+                                                   nsIDOMNode::ELEMENT_NODE);
           NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
           NS_ADDREF(mNodeInfoCache[nodeType] = nodeInfo);
         }
 
         content =
           CreateHTMLElement(nodeType, nodeInfo.forget(), NOT_FROM_PARSER);
         NS_ENSURE_TRUE(content, NS_ERROR_OUT_OF_MEMORY);
 
@@ -939,23 +943,17 @@ nsresult
 nsHTMLParanoidFragmentSink::NameFromNode(const nsIParserNode& aNode,
                                          nsIAtom **aResult)
 {
   nsresult rv;
   eHTMLTags type = (eHTMLTags)aNode.GetNodeType();
   
   *aResult = nsnull;
   if (type == eHTMLTag_userdefined) {
-    nsCOMPtr<nsINodeInfo> nodeInfo;
-    rv =
-      mNodeInfoManager->GetNodeInfo(aNode.GetText(), nsnull,
-                                    kNameSpaceID_XHTML,
-                                    getter_AddRefs(nodeInfo));
-    NS_ENSURE_SUCCESS(rv, rv);
-    NS_IF_ADDREF(*aResult = nodeInfo->NameAtom());
+    *aResult = NS_NewAtom(aNode.GetText());
   } else {
     rv = NameFromType(type, aResult);
   }
   return rv;
 }
 
 void
 nsHTMLParanoidFragmentSink::AllowStyles()
--- a/content/svg/content/src/nsSVGElement.cpp
+++ b/content/svg/content/src/nsSVGElement.cpp
@@ -1359,17 +1359,18 @@ nsSVGElement::AddMappedSVGValue(nsIAtom*
 
   if (aNamespaceID == kNameSpaceID_None) {
     rv = mMappedAttributes.SetAndTakeAttr(aName, attrVal);
     NS_ENSURE_SUCCESS(rv, rv);
   }
   else {
     nsCOMPtr<nsINodeInfo> ni;
     ni = mNodeInfo->NodeInfoManager()->GetNodeInfo(aName, nsnull,
-                                                   aNamespaceID);
+                                                   aNamespaceID,
+                                                   nsIDOMNode::ATTRIBUTE_NODE);
     NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
 
     rv = mMappedAttributes.SetAndTakeAttr(ni, attrVal);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   return NS_OK;
 }
--- a/content/svg/content/src/nsSVGUseElement.cpp
+++ b/content/svg/content/src/nsSVGUseElement.cpp
@@ -334,17 +334,19 @@ nsSVGUseElement::CreateAnonymousContent(
     if (!document)
       return nsnull;
 
     nsNodeInfoManager *nodeInfoManager = document->NodeInfoManager();
     if (!nodeInfoManager)
       return nsnull;
 
     nsCOMPtr<nsINodeInfo> nodeInfo;
-    nodeInfo = nodeInfoManager->GetNodeInfo(nsGkAtoms::svg, nsnull, kNameSpaceID_SVG);
+    nodeInfo = nodeInfoManager->GetNodeInfo(nsGkAtoms::svg, nsnull,
+                                            kNameSpaceID_SVG,
+                                            nsIDOMNode::ELEMENT_NODE);
     if (!nodeInfo)
       return nsnull;
 
     nsCOMPtr<nsIContent> svgNode;
     NS_NewSVGSVGElement(getter_AddRefs(svgNode), nodeInfo.forget(),
                         NOT_FROM_PARSER);
 
     if (!svgNode)
--- a/content/xbl/src/nsXBLContentSink.cpp
+++ b/content/xbl/src/nsXBLContentSink.cpp
@@ -949,17 +949,18 @@ nsXBLContentSink::AddAttributesToXULProt
     nsContentUtils::SplitExpatName(aAtts[i * 2], getter_AddRefs(prefix),
                                    getter_AddRefs(localName), &nameSpaceID);
 
     if (nameSpaceID == kNameSpaceID_None) {
       attrs[i].mName.SetTo(localName);
     }
     else {
       nsCOMPtr<nsINodeInfo> ni;
-      ni = mNodeInfoManager->GetNodeInfo(localName, prefix, nameSpaceID);
+      ni = mNodeInfoManager->GetNodeInfo(localName, prefix, nameSpaceID,
+                                         nsIDOMNode::ATTRIBUTE_NODE);
       attrs[i].mName.SetTo(ni);
     }
     
     rv = aElement->SetAttrAt(i, nsDependentString(aAtts[i * 2 + 1]),
                              mDocumentURI); 
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
--- a/content/xml/content/src/nsXMLCDATASection.cpp
+++ b/content/xml/content/src/nsXMLCDATASection.cpp
@@ -84,32 +84,35 @@ NS_NewXMLCDATASection(nsIContent** aInst
                       nsNodeInfoManager *aNodeInfoManager)
 {
   NS_PRECONDITION(aNodeInfoManager, "Missing nodeinfo manager");
 
   *aInstancePtrResult = nsnull;
 
   nsCOMPtr<nsINodeInfo> ni;
   ni = aNodeInfoManager->GetNodeInfo(nsGkAtoms::cdataTagName,
-                                     nsnull, kNameSpaceID_None);
+                                     nsnull, kNameSpaceID_None,
+                                     nsIDOMNode::CDATA_SECTION_NODE);
   NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
 
   nsXMLCDATASection *instance = new nsXMLCDATASection(ni.forget());
   if (!instance) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   NS_ADDREF(*aInstancePtrResult = instance);
 
   return NS_OK;
 }
 
 nsXMLCDATASection::nsXMLCDATASection(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsGenericDOMDataNode(aNodeInfo)
 {
+  NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::CDATA_SECTION_NODE,
+                    "Bad NodeType in aNodeInfo");
 }
 
 nsXMLCDATASection::~nsXMLCDATASection()
 {
 }
 
 
 DOMCI_NODE_DATA(CDATASection, nsXMLCDATASection)
--- a/content/xml/content/src/nsXMLProcessingInstruction.cpp
+++ b/content/xml/content/src/nsXMLProcessingInstruction.cpp
@@ -45,45 +45,52 @@
 nsresult
 NS_NewXMLProcessingInstruction(nsIContent** aInstancePtrResult,
                                nsNodeInfoManager *aNodeInfoManager,
                                const nsAString& aTarget,
                                const nsAString& aData)
 {
   NS_PRECONDITION(aNodeInfoManager, "Missing nodeinfo manager");
 
-  if (aTarget.EqualsLiteral("xml-stylesheet")) {
+  nsCOMPtr<nsIAtom> target = do_GetAtom(aTarget);
+  NS_ENSURE_TRUE(target, NS_ERROR_OUT_OF_MEMORY);
+
+  if (target == nsGkAtoms::xml_stylesheet) {
     return NS_NewXMLStylesheetProcessingInstruction(aInstancePtrResult,
                                                     aNodeInfoManager, aData);
   }
 
   *aInstancePtrResult = nsnull;
 
   nsCOMPtr<nsINodeInfo> ni;
   ni = aNodeInfoManager->GetNodeInfo(nsGkAtoms::processingInstructionTagName,
-                                     nsnull, kNameSpaceID_None);
+                                     nsnull, kNameSpaceID_None,
+                                     nsIDOMNode::PROCESSING_INSTRUCTION_NODE,
+                                     target);
   NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
 
   nsXMLProcessingInstruction *instance =
-    new nsXMLProcessingInstruction(ni.forget(), aTarget, aData);
+    new nsXMLProcessingInstruction(ni.forget(), aData);
   if (!instance) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   NS_ADDREF(*aInstancePtrResult = instance);
 
   return NS_OK;
 }
 
 nsXMLProcessingInstruction::nsXMLProcessingInstruction(already_AddRefed<nsINodeInfo> aNodeInfo,
-                                                       const nsAString& aTarget,
                                                        const nsAString& aData)
-  : nsGenericDOMDataNode(aNodeInfo),
-    mTarget(aTarget)
+  : nsGenericDOMDataNode(aNodeInfo)
 {
+  NS_ABORT_IF_FALSE(mNodeInfo->NodeType() ==
+                      nsIDOMNode::PROCESSING_INSTRUCTION_NODE,
+                    "Bad NodeType in aNodeInfo");
+
   SetTextInternal(0, mText.GetLength(),
                   aData.BeginReading(), aData.Length(),
                   PR_FALSE);  // Don't notify (bug 420429).
 }
 
 nsXMLProcessingInstruction::~nsXMLProcessingInstruction()
 {
 }
@@ -105,17 +112,17 @@ NS_INTERFACE_MAP_END_INHERITING(nsGeneri
 
 NS_IMPL_ADDREF_INHERITED(nsXMLProcessingInstruction, nsGenericDOMDataNode)
 NS_IMPL_RELEASE_INHERITED(nsXMLProcessingInstruction, nsGenericDOMDataNode)
 
 
 NS_IMETHODIMP
 nsXMLProcessingInstruction::GetTarget(nsAString& aTarget)
 {
-  aTarget.Assign(mTarget);
+  NodeInfo()->GetExtraName()->ToString(aTarget);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXMLProcessingInstruction::SetData(const nsAString& aData)
 {
   return SetNodeValue(aData);
@@ -146,41 +153,41 @@ PRUint16
 nsXMLProcessingInstruction::NodeType()
 {
   return (PRUint16)nsIDOMNode::PROCESSING_INSTRUCTION_NODE;
 }
 
 void
 nsXMLProcessingInstruction::NodeName(nsAString& aNodeName)
 {
-  aNodeName.Assign(mTarget);
+  NodeInfo()->GetExtraName()->ToString(aNodeName);
 }
 
 nsGenericDOMDataNode*
 nsXMLProcessingInstruction::CloneDataNode(nsINodeInfo *aNodeInfo,
                                           PRBool aCloneText) const
 {
   nsAutoString data;
   nsGenericDOMDataNode::GetData(data);
   nsCOMPtr<nsINodeInfo> ni = aNodeInfo;
-  return new nsXMLProcessingInstruction(ni.forget(), mTarget, data);
+  return new nsXMLProcessingInstruction(ni.forget(), data);
 }
 
 #ifdef DEBUG
 void
 nsXMLProcessingInstruction::List(FILE* out, PRInt32 aIndent) const
 {
   PRInt32 index;
   for (index = aIndent; --index >= 0; ) fputs("  ", out);
 
   fprintf(out, "Processing instruction refcount=%d<", mRefCnt.get());
 
   nsAutoString tmp;
   ToCString(tmp, 0, mText.GetLength());
-  tmp.Insert(mTarget.get(), 0);
+  tmp.Insert(nsDependentAtomString(NodeInfo()->GetExtraName()).get(), 0);
   fputs(NS_LossyConvertUTF16toASCII(tmp).get(), out);
 
   fputs(">\n", out);
 }
 
 void
 nsXMLProcessingInstruction::DumpContent(FILE* out, PRInt32 aIndent,
                                         PRBool aDumpAll) const
--- a/content/xml/content/src/nsXMLProcessingInstruction.h
+++ b/content/xml/content/src/nsXMLProcessingInstruction.h
@@ -45,17 +45,16 @@
 #include "nsAString.h"
 
 
 class nsXMLProcessingInstruction : public nsGenericDOMDataNode,
                                    public nsIDOMProcessingInstruction
 {
 public:
   nsXMLProcessingInstruction(already_AddRefed<nsINodeInfo> aNodeInfo,
-                             const nsAString& aTarget,
                              const nsAString& aData);
   virtual ~nsXMLProcessingInstruction();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
   NS_FORWARD_NSIDOMNODE(nsGenericDOMDataNode::)
@@ -84,13 +83,11 @@ protected:
    * http://www.w3.org/TR/xml-stylesheet/#NT-StyleSheetPI for the specification
    * which is used to parse the content of the PI.
    *
    * @param aName the name of the attribute to get the value for
    * @param aValue [out] the value for the attribute with name specified in
    *                     aAttribute. Empty if the attribute isn't present.
    */
   PRBool GetAttrValue(nsIAtom *aName, nsAString& aValue);
-
-  nsString mTarget;
 };
 
 #endif //nsIXMLProcessingInstruction_h___
--- a/content/xml/content/src/nsXMLStylesheetPI.cpp
+++ b/content/xml/content/src/nsXMLStylesheetPI.cpp
@@ -100,18 +100,17 @@ NS_INTERFACE_TABLE_HEAD(nsXMLStylesheetP
 NS_INTERFACE_MAP_END_INHERITING(nsXMLProcessingInstruction)
 
 NS_IMPL_ADDREF_INHERITED(nsXMLStylesheetPI, nsXMLProcessingInstruction)
 NS_IMPL_RELEASE_INHERITED(nsXMLStylesheetPI, nsXMLProcessingInstruction)
 
 
 nsXMLStylesheetPI::nsXMLStylesheetPI(already_AddRefed<nsINodeInfo> aNodeInfo,
                                      const nsAString& aData)
-  : nsXMLProcessingInstruction(aNodeInfo, NS_LITERAL_STRING("xml-stylesheet"),
-                               aData)
+  : nsXMLProcessingInstruction(aNodeInfo, aData)
 {
 }
 
 nsXMLStylesheetPI::~nsXMLStylesheetPI()
 {
 }
 
 // nsIContent
@@ -261,17 +260,19 @@ NS_NewXMLStylesheetProcessingInstruction
                                          const nsAString& aData)
 {
   NS_PRECONDITION(aNodeInfoManager, "Missing nodeinfo manager");
 
   *aInstancePtrResult = nsnull;
   
   nsCOMPtr<nsINodeInfo> ni;
   ni = aNodeInfoManager->GetNodeInfo(nsGkAtoms::processingInstructionTagName,
-                                     nsnull, kNameSpaceID_None);
+                                     nsnull, kNameSpaceID_None,
+                                     nsIDOMNode::PROCESSING_INSTRUCTION_NODE,
+                                     nsGkAtoms::xml_stylesheet);
   NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
 
   nsXMLStylesheetPI *instance = new nsXMLStylesheetPI(ni.forget(), aData);
   if (!instance) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   NS_ADDREF(*aInstancePtrResult = instance);
--- a/content/xml/document/src/nsXMLContentSink.cpp
+++ b/content/xml/document/src/nsXMLContentSink.cpp
@@ -1007,17 +1007,18 @@ nsXMLContentSink::HandleStartElement(con
   nsContentUtils::SplitExpatName(aName, getter_AddRefs(prefix),
                                  getter_AddRefs(localName), &nameSpaceID);
 
   if (!OnOpenContainer(aAtts, aAttsCount, nameSpaceID, localName, aLineNumber)) {
     return NS_OK;
   }
   
   nsCOMPtr<nsINodeInfo> nodeInfo;
-  nodeInfo = mNodeInfoManager->GetNodeInfo(localName, prefix, nameSpaceID);
+  nodeInfo = mNodeInfoManager->GetNodeInfo(localName, prefix, nameSpaceID,
+                                           nsIDOMNode::ELEMENT_NODE);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   result = CreateElement(aAtts, aAttsCount, nodeInfo, aLineNumber,
                          getter_AddRefs(content), &appendContent,
                          FROM_PARSER_NETWORK);
   NS_ENSURE_SUCCESS(result, result);
 
   // Have to do this before we push the new content on the stack... and have to
--- a/content/xml/document/src/nsXMLFragmentContentSink.cpp
+++ b/content/xml/document/src/nsXMLFragmentContentSink.cpp
@@ -636,30 +636,27 @@ nsXHTMLParanoidFragmentSink::AddAttribut
 
   // scrub URI attributes that point at dangerous content
   // We have to do this here, because this is where we have a base URI,
   // but we can't do all the scrubbing here, because other parts of the
   // code get the attributes before this method is called.
   nsTArray<const PRUnichar *> allowedAttrs;
   PRInt32 nameSpaceID;
   nsCOMPtr<nsIAtom> prefix, localName;
-  nsCOMPtr<nsINodeInfo> nodeInfo;
 
   if (!mNullPrincipal) {
       mNullPrincipal = do_CreateInstance(NS_NULLPRINCIPAL_CONTRACTID, &rv);
       NS_ENSURE_SUCCESS(rv, rv);
   }
 
   while (*aAtts) {
     nsContentUtils::SplitExpatName(aAtts[0], getter_AddRefs(prefix),
                                    getter_AddRefs(localName), &nameSpaceID);
-    nodeInfo = mNodeInfoManager->GetNodeInfo(localName, prefix, nameSpaceID);
-    NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
     // check the attributes we allow that contain URIs
-    if (IsAttrURI(nodeInfo->NameAtom())) {
+    if (IsAttrURI(localName)) {
       if (!aAtts[1])
         rv = NS_ERROR_FAILURE;
       if (!baseURI)
         baseURI = aContent->GetBaseURI();
       nsCOMPtr<nsIURI> attrURI;
       rv = NS_NewURI(getter_AddRefs(attrURI), nsDependentString(aAtts[1]),
                      nsnull, baseURI);
       if (NS_SUCCEEDED(rv)) {
@@ -691,46 +688,37 @@ nsXHTMLParanoidFragmentSink::HandleStart
   nsCOMPtr<nsIAtom> prefix, localName;
   nsContentUtils::SplitExpatName(aName, getter_AddRefs(prefix),
                                  getter_AddRefs(localName), &nameSpaceID);
   
   // If the element is not in the XHTML namespace, bounce it
   if (nameSpaceID != kNameSpaceID_XHTML)
     return NS_OK;
   
-  nsCOMPtr<nsINodeInfo> nodeInfo;
-  nodeInfo = mNodeInfoManager->GetNodeInfo(localName, prefix, nameSpaceID);
-  NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
-  
   // bounce it if it's not on the whitelist or we're inside
   // <script> or <style>
-  nsCOMPtr<nsIAtom> name = nodeInfo->NameAtom();
   if (mSkipLevel != 0 ||
-      name == nsGkAtoms::script ||
-      name == nsGkAtoms::style) {
+      localName == nsGkAtoms::script ||
+      localName == nsGkAtoms::style) {
     ++mSkipLevel; // track this so we don't spew script text
     return NS_OK;
   }  
   
-  if (!sAllowedTags || !sAllowedTags->GetEntry(name))
+  if (!sAllowedTags || !sAllowedTags->GetEntry(localName))
     return NS_OK;
   
   // It's an allowed element, so let's scrub the attributes
   nsTArray<const PRUnichar *> allowedAttrs;
   for (PRUint32 i = 0; i < aAttsCount; i += 2) {
     nsContentUtils::SplitExpatName(aAtts[i], getter_AddRefs(prefix),
                                    getter_AddRefs(localName), &nameSpaceID);
-    nodeInfo = mNodeInfoManager->GetNodeInfo(localName, prefix, nameSpaceID);
-    NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
-    
-    name = nodeInfo->NameAtom();
     // Add if it's xmlns, xml: or on the HTML whitelist
     if (nameSpaceID == kNameSpaceID_XMLNS ||
         nameSpaceID == kNameSpaceID_XML ||
-        (sAllowedAttributes && sAllowedAttributes->GetEntry(name))) {
+        (sAllowedAttributes && sAllowedAttributes->GetEntry(localName))) {
       allowedAttrs.AppendElement(aAtts[i]);
       allowedAttrs.AppendElement(aAtts[i + 1]);
     }
   }
   allowedAttrs.AppendElement((const PRUnichar*) nsnull);
   return
     nsXMLFragmentContentSink::HandleStartElement(aName,
                                                  allowedAttrs.Elements(),
@@ -747,27 +735,22 @@ nsXHTMLParanoidFragmentSink::HandleEndEl
   nsContentUtils::SplitExpatName(aName, getter_AddRefs(prefix),
                                  getter_AddRefs(localName), &nameSpaceID);
   
   // If the element is not in the XHTML namespace, bounce it
   if (nameSpaceID != kNameSpaceID_XHTML) {
     return NS_OK;
   }
   
-  nsCOMPtr<nsINodeInfo> nodeInfo;
-  nodeInfo = mNodeInfoManager->GetNodeInfo(localName, prefix, nameSpaceID);
-  NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
-  
-  nsCOMPtr<nsIAtom> name = nodeInfo->NameAtom();
   if (mSkipLevel != 0) {
     --mSkipLevel;
     return NS_OK;
   }
 
-  if (!sAllowedTags || !sAllowedTags->GetEntry(name)) {
+  if (!sAllowedTags || !sAllowedTags->GetEntry(localName)) {
     return NS_OK;
   }
 
   return nsXMLFragmentContentSink::HandleEndElement(aName);
 }
 
 NS_IMETHODIMP
 nsXHTMLParanoidFragmentSink::
--- a/content/xslt/src/xslt/txMozillaTextOutput.cpp
+++ b/content/xslt/src/xslt/txMozillaTextOutput.cpp
@@ -280,13 +280,14 @@ void txMozillaTextOutput::getOutputDocum
 nsresult
 txMozillaTextOutput::createXHTMLElement(nsIAtom* aName,
                                         nsIContent** aResult)
 {
     *aResult = nsnull;
 
     nsCOMPtr<nsINodeInfo> ni;
     ni = mDocument->NodeInfoManager()->
-        GetNodeInfo(aName, nsnull, kNameSpaceID_XHTML);
+        GetNodeInfo(aName, nsnull, kNameSpaceID_XHTML,
+                    nsIDOMNode::ELEMENT_NODE);
     NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
 
     return NS_NewHTMLElement(aResult, ni.forget(), NOT_FROM_PARSER);
 }
--- a/content/xslt/src/xslt/txMozillaXMLOutput.cpp
+++ b/content/xslt/src/xslt/txMozillaXMLOutput.cpp
@@ -556,17 +556,18 @@ txMozillaXMLOutput::startElementInternal
         return NS_ERROR_OUT_OF_MEMORY;
     }
 
     mTableState = NORMAL;
     mOpenedElementIsHTML = PR_FALSE;
 
     // Create the element
     nsCOMPtr<nsINodeInfo> ni;
-    ni = mNodeInfoManager->GetNodeInfo(aLocalName, aPrefix, aNsID);
+    ni = mNodeInfoManager->GetNodeInfo(aLocalName, aPrefix, aNsID,
+                                       nsIDOMNode::ELEMENT_NODE);
     NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
 
     NS_NewElement(getter_AddRefs(mOpenedElement), aNsID, ni.forget(),
                   mCreatingNewDocument ?
                   FROM_PARSER_XSLT : FROM_PARSER_FRAGMENT);
 
     // Set up the element and adjust state
     if (!mNoFixup) {
@@ -963,17 +964,18 @@ txMozillaXMLOutput::createHTMLElement(ns
 {
     NS_ASSERTION(mOutputFormat.mMethod == eHTMLOutput,
                  "need to adjust createHTMLElement");
 
     *aResult = nsnull;
 
     nsCOMPtr<nsINodeInfo> ni;
     ni = mNodeInfoManager->GetNodeInfo(aName, nsnull,
-                                       kNameSpaceID_XHTML);
+                                       kNameSpaceID_XHTML,
+                                       nsIDOMNode::ELEMENT_NODE);
     NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
 
     return NS_NewHTMLElement(aResult, ni.forget(), mCreatingNewDocument ?
         FROM_PARSER_XSLT : FROM_PARSER_FRAGMENT);
 
 }
 
 txTransformNotifier::txTransformNotifier()
--- a/content/xtf/src/nsXTFElementWrapper.cpp
+++ b/content/xtf/src/nsXTFElementWrapper.cpp
@@ -531,17 +531,19 @@ already_AddRefed<nsINodeInfo>
 nsXTFElementWrapper::GetExistingAttrNameFromQName(const nsAString& aStr) const
 {
   nsINodeInfo* nodeInfo = nsXTFElementWrapperBase::GetExistingAttrNameFromQName(aStr).get();
 
   // Maybe this attribute is handled by our inner element:
   if (!nodeInfo) {
     nsCOMPtr<nsIAtom> nameAtom = do_GetAtom(aStr);
     if (HandledByInner(nameAtom)) 
-      nodeInfo = mNodeInfo->NodeInfoManager()->GetNodeInfo(nameAtom, nsnull, kNameSpaceID_None).get();
+      nodeInfo = mNodeInfo->NodeInfoManager()->
+        GetNodeInfo(nameAtom, nsnull, kNameSpaceID_None,
+                    nsIDOMNode::ATTRIBUTE_NODE).get();
   }
   
   return nodeInfo;
 }
 
 nsEventStates
 nsXTFElementWrapper::IntrinsicState() const
 {
--- a/content/xul/content/src/nsXULElement.cpp
+++ b/content/xul/content/src/nsXULElement.cpp
@@ -324,19 +324,19 @@ nsXULElement::Create(nsXULPrototypeEleme
 
     NS_PRECONDITION(aResult != nsnull, "null ptr");
     if (! aResult)
         return NS_ERROR_NULL_POINTER;
 
     nsCOMPtr<nsINodeInfo> nodeInfo;
     if (aDocument) {
         nsINodeInfo* ni = aPrototype->mNodeInfo;
-        nodeInfo = aDocument->NodeInfoManager()->GetNodeInfo(ni->NameAtom(),
-                                                             ni->GetPrefixAtom(),
-                                                             ni->NamespaceID());
+        nodeInfo = aDocument->NodeInfoManager()->
+          GetNodeInfo(ni->NameAtom(), ni->GetPrefixAtom(), ni->NamespaceID(),
+                      nsIDOMNode::ELEMENT_NODE);
         NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
     }
     else {
         nodeInfo = aPrototype->mNodeInfo;
     }
 
     nsRefPtr<nsXULElement> element = Create(aPrototype, nodeInfo,
                                             aIsScriptable);
@@ -2647,17 +2647,18 @@ nsXULPrototypeElement::Serialize(nsIObje
 
     nsAutoString attributeValue;
     PRUint32 i;
     for (i = 0; i < mNumAttributes; ++i) {
         nsCOMPtr<nsINodeInfo> ni;
         if (mAttributes[i].mName.IsAtom()) {
             ni = mNodeInfo->NodeInfoManager()->
                 GetNodeInfo(mAttributes[i].mName.Atom(), nsnull,
-                            kNameSpaceID_None);
+                            kNameSpaceID_None,
+                            nsIDOMNode::ATTRIBUTE_NODE);
             NS_ASSERTION(ni, "the nodeinfo should already exist");
         }
         else {
             ni = mAttributes[i].mName.NodeInfo();
         }
 
         index = aNodeInfos->IndexOf(ni);
         NS_ASSERTION(index >= 0, "unknown nsINodeInfo index");
--- a/content/xul/document/src/nsXULContentSink.cpp
+++ b/content/xul/document/src/nsXULContentSink.cpp
@@ -460,17 +460,18 @@ XULContentSinkImpl::NormalizeAttributeSt
     if (nameSpaceID == kNameSpaceID_None) {
         aName.SetTo(localName);
 
         return NS_OK;
     }
 
     nsCOMPtr<nsINodeInfo> ni;
     ni = mNodeInfoManager->GetNodeInfo(localName, prefix,
-                                       nameSpaceID);
+                                       nameSpaceID,
+                                       nsIDOMNode::ATTRIBUTE_NODE);
     NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
 
     aName.SetTo(ni);
 
     return NS_OK;
 }
 
 nsresult
@@ -513,17 +514,18 @@ XULContentSinkImpl::HandleStartElement(c
   }
 
   PRInt32 nameSpaceID;
   nsCOMPtr<nsIAtom> prefix, localName;
   nsContentUtils::SplitExpatName(aName, getter_AddRefs(prefix),
                                  getter_AddRefs(localName), &nameSpaceID);
 
   nsCOMPtr<nsINodeInfo> nodeInfo;
-  nodeInfo = mNodeInfoManager->GetNodeInfo(localName, prefix, nameSpaceID);
+  nodeInfo = mNodeInfoManager->GetNodeInfo(localName, prefix, nameSpaceID,
+                                           nsIDOMNode::ELEMENT_NODE);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
   
   nsresult rv = NS_OK;
   switch (mState) {
   case eInProlog:
       // We're the root document element
       rv = OpenRoot(aAtts, aAttsCount, nodeInfo);
       break;
--- a/content/xul/document/src/nsXULDocument.cpp
+++ b/content/xul/document/src/nsXULDocument.cpp
@@ -3699,17 +3699,18 @@ nsXULDocument::CreateElementFromPrototyp
     else {
         // If it's not a XUL element, it's gonna be heavyweight no matter
         // what. So we need to copy everything out of the prototype
         // into the element.  Get a nodeinfo from our nodeinfo manager
         // for this node.
         nsCOMPtr<nsINodeInfo> newNodeInfo;
         newNodeInfo = mNodeInfoManager->GetNodeInfo(aPrototype->mNodeInfo->NameAtom(),
                                                     aPrototype->mNodeInfo->GetPrefixAtom(),
-                                                    aPrototype->mNodeInfo->NamespaceID());
+                                                    aPrototype->mNodeInfo->NamespaceID(),
+                                                    nsIDOMNode::ELEMENT_NODE);
         if (!newNodeInfo) return NS_ERROR_OUT_OF_MEMORY;
         nsCOMPtr<nsIContent> content;
         PRInt32 ns = newNodeInfo->NamespaceID();
         nsCOMPtr<nsINodeInfo> xtfNi = newNodeInfo;
         rv = NS_NewElement(getter_AddRefs(content), ns, newNodeInfo.forget(),
                            NOT_FROM_PARSER);
         if (NS_FAILED(rv))
             return rv;
--- a/content/xul/document/src/nsXULPrototypeDocument.cpp
+++ b/content/xul/document/src/nsXULPrototypeDocument.cpp
@@ -312,17 +312,21 @@ nsXULPrototypeDocument::Read(nsIObjectIn
             prefix = nsnull;
         } else {
             rv |= aStream->ReadString(prefixStr);
             prefix = do_GetAtom(prefixStr);
         }
         rv |= aStream->ReadString(localName);
 
         nsCOMPtr<nsINodeInfo> nodeInfo;
+        // Using PR_UINT16_MAX here as we don't know which nodeinfos will be
+        // used for attributes and which for elements. And that doesn't really
+        // matter.
         rv |= mNodeInfoManager->GetNodeInfo(localName, prefix, namespaceURI,
+                                            PR_UINT16_MAX,
                                             getter_AddRefs(nodeInfo));
         if (!nodeInfos.AppendObject(nodeInfo))
             rv |= NS_ERROR_OUT_OF_MEMORY;
     }
 
     // Document contents
     PRUint32 type;
     while (NS_SUCCEEDED(rv)) {
@@ -364,17 +368,18 @@ GetNodeInfos(nsXULPrototypeElement* aPro
 
     // Search attributes
     PRUint32 i;
     for (i = 0; i < aPrototype->mNumAttributes; ++i) {
         nsCOMPtr<nsINodeInfo> ni;
         nsAttrName* name = &aPrototype->mAttributes[i].mName;
         if (name->IsAtom()) {
             ni = aPrototype->mNodeInfo->NodeInfoManager()->
-                GetNodeInfo(name->Atom(), nsnull, kNameSpaceID_None);
+                GetNodeInfo(name->Atom(), nsnull, kNameSpaceID_None,
+                            nsIDOMNode::ATTRIBUTE_NODE);
             NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
         }
         else {
             ni = name->NodeInfo();
         }
 
         if (aArray.IndexOf(ni) < 0) {
             if (!aArray.AppendObject(ni)) {
--- a/content/xul/templates/src/nsXULContentBuilder.cpp
+++ b/content/xul/templates/src/nsXULContentBuilder.cpp
@@ -1396,17 +1396,18 @@ nsXULContentBuilder::CreateElement(PRInt
     NS_ASSERTION(doc != nsnull, "not initialized");
     if (! doc)
         return NS_ERROR_NOT_INITIALIZED;
 
     nsresult rv;
     nsCOMPtr<nsIContent> result;
 
     nsCOMPtr<nsINodeInfo> nodeInfo;
-    nodeInfo = doc->NodeInfoManager()->GetNodeInfo(aTag, nsnull, aNameSpaceID);
+    nodeInfo = doc->NodeInfoManager()->GetNodeInfo(aTag, nsnull, aNameSpaceID,
+                                                   nsIDOMNode::ELEMENT_NODE);
 
     rv = NS_NewElement(getter_AddRefs(result), aNameSpaceID, nodeInfo.forget(),
                        NOT_FROM_PARSER);
     if (NS_FAILED(rv))
         return rv;
 
     *aResult = result;
     NS_ADDREF(*aResult);
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -1530,18 +1530,19 @@ nsCSSFrameConstructor::CreateGeneratedCo
       // image object
       return nsnull;
     }
     
     // Create an image content object and pass it the image request.
     // XXX Check if it's an image type we can handle...
 
     nsCOMPtr<nsINodeInfo> nodeInfo;
-    nodeInfo = mDocument->NodeInfoManager()->GetNodeInfo(nsGkAtoms::mozgeneratedcontentimage, nsnull,
-                                                         kNameSpaceID_XHTML);
+    nodeInfo = mDocument->NodeInfoManager()->
+      GetNodeInfo(nsGkAtoms::mozgeneratedcontentimage, nsnull,
+                  kNameSpaceID_XHTML, nsIDOMNode::ELEMENT_NODE);
 
     nsCOMPtr<nsIContent> content;
     NS_NewGenConImageContent(getter_AddRefs(content), nodeInfo.forget(),
                              data.mContent.mImage);
     return content.forget();
   }
 
   switch (type) {
@@ -1707,17 +1708,18 @@ nsCSSFrameConstructor::CreateGeneratedCo
   if (!pseudoStyleContext)
     return;
   // |ProbePseudoStyleFor| checked the 'display' property and the
   // |ContentCount()| of the 'content' property for us.
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nsIAtom* elemName = aPseudoElement == nsCSSPseudoElements::ePseudo_before ?
     nsGkAtoms::mozgeneratedcontentbefore : nsGkAtoms::mozgeneratedcontentafter;
   nodeInfo = mDocument->NodeInfoManager()->GetNodeInfo(elemName, nsnull,
-                                                       kNameSpaceID_None);
+                                                       kNameSpaceID_None,
+                                                       nsIDOMNode::ELEMENT_NODE);
   nsCOMPtr<nsIContent> container;
   nsresult rv = NS_NewXMLElement(getter_AddRefs(container), nodeInfo.forget());
   if (NS_FAILED(rv))
     return;
   container->SetNativeAnonymous();
 
   rv = container->BindToTree(mDocument, aParentContent, aParentContent, PR_TRUE);
   if (NS_FAILED(rv)) {
--- a/layout/build/nsContentDLF.cpp
+++ b/layout/build/nsContentDLF.cpp
@@ -373,27 +373,30 @@ nsContentDLF::CreateBlankDocument(nsILoa
   if (NS_SUCCEEDED(rv)) {
     rv = NS_ERROR_FAILURE;
 
     nsNodeInfoManager *nim = blankDoc->NodeInfoManager();
 
     nsCOMPtr<nsINodeInfo> htmlNodeInfo;
 
     // generate an html html element
-    htmlNodeInfo = nim->GetNodeInfo(nsGkAtoms::html, 0, kNameSpaceID_XHTML);
+    htmlNodeInfo = nim->GetNodeInfo(nsGkAtoms::html, 0, kNameSpaceID_XHTML,
+                                    nsIDOMNode::ELEMENT_NODE);
     nsCOMPtr<nsIContent> htmlElement =
       NS_NewHTMLHtmlElement(htmlNodeInfo.forget());
 
     // generate an html head element
-    htmlNodeInfo = nim->GetNodeInfo(nsGkAtoms::head, 0, kNameSpaceID_XHTML);
+    htmlNodeInfo = nim->GetNodeInfo(nsGkAtoms::head, 0, kNameSpaceID_XHTML,
+                                    nsIDOMNode::ELEMENT_NODE);
     nsCOMPtr<nsIContent> headElement =
       NS_NewHTMLHeadElement(htmlNodeInfo.forget());
 
     // generate an html body elemment
-    htmlNodeInfo = nim->GetNodeInfo(nsGkAtoms::body, 0, kNameSpaceID_XHTML);
+    htmlNodeInfo = nim->GetNodeInfo(nsGkAtoms::body, 0, kNameSpaceID_XHTML,
+                                    nsIDOMNode::ELEMENT_NODE);
     nsCOMPtr<nsIContent> bodyElement =
       NS_NewHTMLBodyElement(htmlNodeInfo.forget());
 
     // blat in the structure
     if (htmlElement && headElement && bodyElement) {
       NS_ASSERTION(blankDoc->GetChildCount() == 0,
                    "Shouldn't have children");
       rv = blankDoc->AppendChildTo(htmlElement, PR_FALSE);
--- a/layout/forms/nsComboboxControlFrame.cpp
+++ b/layout/forms/nsComboboxControlFrame.cpp
@@ -1024,17 +1024,18 @@ nsComboboxControlFrame::CreateAnonymousC
     mListControlFrame->GetOptionText(mDisplayedIndex, mDisplayedOptionText);
   }
   ActuallyDisplayText(PR_FALSE);
 
   if (!aElements.AppendElement(mDisplayContent))
     return NS_ERROR_OUT_OF_MEMORY;
 
   nsCOMPtr<nsINodeInfo> nodeInfo;
-  nodeInfo = nimgr->GetNodeInfo(nsGkAtoms::button, nsnull, kNameSpaceID_XHTML);
+  nodeInfo = nimgr->GetNodeInfo(nsGkAtoms::button, nsnull, kNameSpaceID_XHTML,
+                                nsIDOMNode::ELEMENT_NODE);
 
   // create button which drops the list down
   NS_NewHTMLElement(getter_AddRefs(mButtonContent), nodeInfo.forget(),
                     dom::NOT_FROM_PARSER);
   if (!mButtonContent)
     return NS_ERROR_OUT_OF_MEMORY;
 
   // make someone to listen to the button. If its pressed by someone like Accessibility
--- a/layout/forms/nsFileControlFrame.cpp
+++ b/layout/forms/nsFileControlFrame.cpp
@@ -232,17 +232,18 @@ PRBool CapturePickerAcceptCallback(const
 nsresult
 nsFileControlFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
 {
   // Get the NodeInfoManager and tag necessary to create input elements
   nsCOMPtr<nsIDocument> doc = mContent->GetDocument();
 
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nodeInfo = doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::input, nsnull,
-                                                 kNameSpaceID_XHTML);
+                                                 kNameSpaceID_XHTML,
+                                                 nsIDOMNode::ELEMENT_NODE);
 
   // Create the text content
   NS_NewHTMLElement(getter_AddRefs(mTextContent), nodeInfo.forget(),
                     dom::NOT_FROM_PARSER);
   if (!mTextContent)
     return NS_ERROR_OUT_OF_MEMORY;
 
   // Mark the element to be native anonymous before setting any attributes.
@@ -286,17 +287,18 @@ nsFileControlFrame::CreateAnonymousConte
   NS_ENSURE_STATE(dom3TextContent);
   // Register as an event listener of the textbox
   // to open file dialog on mouse click
   dom3TextContent->AddGroupedEventListener(click, mMouseListener, PR_FALSE,
                                            systemGroup);
 
   // Create the browse button
   nodeInfo = doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::input, nsnull,
-                                                 kNameSpaceID_XHTML);
+                                                 kNameSpaceID_XHTML,
+                                                 nsIDOMNode::ELEMENT_NODE);
   NS_NewHTMLElement(getter_AddRefs(mBrowse), nodeInfo.forget(),
                     dom::NOT_FROM_PARSER);
   if (!mBrowse)
     return NS_ERROR_OUT_OF_MEMORY;
 
   // Mark the element to be native anonymous before setting any attributes.
   mBrowse->SetNativeAnonymous();
 
@@ -312,17 +314,18 @@ nsFileControlFrame::CreateAnonymousConte
     CaptureCallbackData data;
     data.picker = capturePicker;
     data.mode = &mode;
     ParseAcceptAttribute(&CapturePickerAcceptCallback, (void*)&data);
 
     if (mode != 0) {
       mCaptureMouseListener->mMode = mode;
       nodeInfo = doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::input, nsnull,
-                                                     kNameSpaceID_XHTML);
+                                                     kNameSpaceID_XHTML,
+                                                     nsIDOMNode::ELEMENT_NODE);
       NS_NewHTMLElement(getter_AddRefs(mCapture), nodeInfo.forget(),
                         dom::NOT_FROM_PARSER);
       if (!mCapture)
         return NS_ERROR_OUT_OF_MEMORY;
 
       // Mark the element to be native anonymous before setting any attributes.
       mCapture->SetNativeAnonymous();
 
--- a/layout/forms/nsIsIndexFrame.cpp
+++ b/layout/forms/nsIsIndexFrame.cpp
@@ -190,17 +190,18 @@ nsresult
 nsIsIndexFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
 {
   // Get the node info manager (used to create hr's and input's)
   nsCOMPtr<nsIDocument> doc = mContent->GetDocument();
   nsNodeInfoManager *nimgr = doc->NodeInfoManager();
 
   // Create an hr
   nsCOMPtr<nsINodeInfo> hrInfo;
-  hrInfo = nimgr->GetNodeInfo(nsGkAtoms::hr, nsnull, kNameSpaceID_XHTML);
+  hrInfo = nimgr->GetNodeInfo(nsGkAtoms::hr, nsnull, kNameSpaceID_XHTML,
+                              nsIDOMNode::ELEMENT_NODE);
 
   NS_NewHTMLElement(getter_AddRefs(mPreHr), hrInfo.forget(),
                     dom::NOT_FROM_PARSER);
   if (!mPreHr || !aElements.AppendElement(mPreHr))
     return NS_ERROR_OUT_OF_MEMORY;
 
   // Add a child text content node for the label
   NS_NewTextNode(getter_AddRefs(mTextContent), nimgr);
@@ -209,17 +210,18 @@ nsIsIndexFrame::CreateAnonymousContent(n
 
   // set the value of the text node and add it to the child list
   UpdatePromptLabel(PR_FALSE);
   if (!aElements.AppendElement(mTextContent))
     return NS_ERROR_OUT_OF_MEMORY;
 
   // Create text input field
   nsCOMPtr<nsINodeInfo> inputInfo;
-  inputInfo = nimgr->GetNodeInfo(nsGkAtoms::input, nsnull, kNameSpaceID_XHTML);
+  inputInfo = nimgr->GetNodeInfo(nsGkAtoms::input, nsnull, kNameSpaceID_XHTML,
+                                 nsIDOMNode::ELEMENT_NODE);
 
   NS_NewHTMLElement(getter_AddRefs(mInputContent), inputInfo.forget(),
                     dom::NOT_FROM_PARSER);
   if (!mInputContent)
     return NS_ERROR_OUT_OF_MEMORY;
 
   mInputContent->SetAttr(kNameSpaceID_None, nsGkAtoms::type,
                          NS_LITERAL_STRING("text"), PR_FALSE);
@@ -227,17 +229,18 @@ nsIsIndexFrame::CreateAnonymousContent(n
   if (!aElements.AppendElement(mInputContent))
     return NS_ERROR_OUT_OF_MEMORY;
 
   // Register as an event listener to submit on Enter press
   mListener = new nsIsIndexFrame::KeyListener(this);
   mInputContent->AddEventListenerByIID(mListener, NS_GET_IID(nsIDOMKeyListener));
 
   // Create an hr
-  hrInfo = nimgr->GetNodeInfo(nsGkAtoms::hr, nsnull, kNameSpaceID_XHTML);
+  hrInfo = nimgr->GetNodeInfo(nsGkAtoms::hr, nsnull, kNameSpaceID_XHTML,
+                              nsIDOMNode::ELEMENT_NODE);
   NS_NewHTMLElement(getter_AddRefs(mPostHr), hrInfo.forget(),
                     dom::NOT_FROM_PARSER);
   if (!mPostHr || !aElements.AppendElement(mPostHr))
     return NS_ERROR_OUT_OF_MEMORY;
 
   return NS_OK;
 }
 
--- a/layout/forms/nsProgressFrame.cpp
+++ b/layout/forms/nsProgressFrame.cpp
@@ -85,17 +85,18 @@ nsProgressFrame::DestroyFrom(nsIFrame* a
 nsresult
 nsProgressFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
 {
   // Get the NodeInfoManager and tag necessary to create the progress bar div.
   nsCOMPtr<nsIDocument> doc = mContent->GetDocument();
 
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nodeInfo = doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::div, nsnull,
-                                                 kNameSpaceID_XHTML);
+                                                 kNameSpaceID_XHTML,
+                                                 nsIDOMNode::ELEMENT_NODE);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   // Create the div.
   nsresult rv = NS_NewHTMLElement(getter_AddRefs(mBarDiv), nodeInfo.forget(),
                                   mozilla::dom::NOT_FROM_PARSER);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Associate ::-moz-progress-bar pseudo-element to the anonymous child.
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -2432,17 +2432,18 @@ nsGfxScrollFrameInner::CreateAnonymousCo
       return NS_OK;
     }
   }
 
   nsNodeInfoManager *nodeInfoManager =
     presContext->Document()->NodeInfoManager();
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nodeInfo = nodeInfoManager->GetNodeInfo(nsGkAtoms::scrollbar, nsnull,
-                                          kNameSpaceID_XUL);
+                                          kNameSpaceID_XUL,
+                                          nsIDOMNode::ELEMENT_NODE);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   if (canHaveHorizontal) {
     nsCOMPtr<nsINodeInfo> ni = nodeInfo;
     NS_TrustedNewXULElement(getter_AddRefs(mHScrollbarContent), ni.forget());
     mHScrollbarContent->SetAttr(kNameSpaceID_None, nsGkAtoms::orient,
                                 NS_LITERAL_STRING("horizontal"), PR_FALSE);
     mHScrollbarContent->SetAttr(kNameSpaceID_None, nsGkAtoms::clickthrough,
@@ -2460,17 +2461,18 @@ nsGfxScrollFrameInner::CreateAnonymousCo
                                 NS_LITERAL_STRING("always"), PR_FALSE);
     if (!aElements.AppendElement(mVScrollbarContent))
       return NS_ERROR_OUT_OF_MEMORY;
   }
 
   if (isResizable) {
     nsCOMPtr<nsINodeInfo> nodeInfo;
     nodeInfo = nodeInfoManager->GetNodeInfo(nsGkAtoms::resizer, nsnull,
-                                            kNameSpaceID_XUL);
+                                            kNameSpaceID_XUL,
+                                            nsIDOMNode::ELEMENT_NODE);
     NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
     NS_TrustedNewXULElement(getter_AddRefs(mResizerContent), nodeInfo.forget());
 
     nsAutoString dir;
     switch (resizeStyle) {
       case NS_STYLE_RESIZE_HORIZONTAL:
         if (IsScrollbarOnRight()) {
@@ -2505,17 +2507,18 @@ nsGfxScrollFrameInner::CreateAnonymousCo
                                   NS_LITERAL_STRING("always"), PR_FALSE);
 
     if (!aElements.AppendElement(mResizerContent))
       return NS_ERROR_OUT_OF_MEMORY;
   }
 
   if (canHaveHorizontal && canHaveVertical) {
     nodeInfo = nodeInfoManager->GetNodeInfo(nsGkAtoms::scrollcorner, nsnull,
-                                            kNameSpaceID_XUL);
+                                            kNameSpaceID_XUL,
+                                            nsIDOMNode::ELEMENT_NODE);
     NS_TrustedNewXULElement(getter_AddRefs(mScrollCornerContent), nodeInfo.forget());
     if (!aElements.AppendElement(mScrollCornerContent))
       return NS_ERROR_OUT_OF_MEMORY;
   }
 
   return NS_OK;
 }
 
--- a/layout/generic/nsVideoFrame.cpp
+++ b/layout/generic/nsVideoFrame.cpp
@@ -95,17 +95,18 @@ nsVideoFrame::CreateAnonymousContent(nsT
   nsNodeInfoManager *nodeInfoManager = GetContent()->GetCurrentDoc()->NodeInfoManager();
   nsCOMPtr<nsINodeInfo> nodeInfo;
   if (HasVideoElement()) {
     // Create an anonymous image element as a child to hold the poster
     // image. We may not have a poster image now, but one could be added
     // before we load, or on a subsequent load.
     nodeInfo = nodeInfoManager->GetNodeInfo(nsGkAtoms::img,
                                             nsnull,
-                                            kNameSpaceID_XHTML);
+                                            kNameSpaceID_XHTML,
+                                            nsIDOMNode::ELEMENT_NODE);
     NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
     Element* element = NS_NewHTMLImageElement(nodeInfo.forget());
     mPosterImage = element;
     NS_ENSURE_TRUE(mPosterImage, NS_ERROR_OUT_OF_MEMORY);
 
     // Push a null JSContext on the stack so that code that runs
     // within the below code doesn't think it's being called by
     // JS. See bug 604262.
@@ -129,17 +130,18 @@ nsVideoFrame::CreateAnonymousContent(nsT
     if (!aElements.AppendElement(mPosterImage))
       return NS_ERROR_OUT_OF_MEMORY;
   }
 
   // Set up "videocontrols" XUL element which will be XBL-bound to the
   // actual controls.
   nodeInfo = nodeInfoManager->GetNodeInfo(nsGkAtoms::videocontrols,
                                           nsnull,
-                                          kNameSpaceID_XUL);
+                                          kNameSpaceID_XUL,
+                                          nsIDOMNode::ELEMENT_NODE);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   NS_TrustedNewXULElement(getter_AddRefs(mVideoControls), nodeInfo.forget());
   if (!aElements.AppendElement(mVideoControls))
     return NS_ERROR_OUT_OF_MEMORY;
 
   return NS_OK;
 }
--- a/layout/xul/base/src/nsDocElementBoxFrame.cpp
+++ b/layout/xul/base/src/nsDocElementBoxFrame.cpp
@@ -117,29 +117,31 @@ nsDocElementBoxFrame::CreateAnonymousCon
     // The page is currently being torn down.  Why bother.
     return NS_ERROR_FAILURE;
   }
   nsNodeInfoManager *nodeInfoManager = doc->NodeInfoManager();
 
   // create the top-secret popupgroup node. shhhhh!
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nodeInfo = nodeInfoManager->GetNodeInfo(nsGkAtoms::popupgroup,
-                                          nsnull, kNameSpaceID_XUL);
+                                          nsnull, kNameSpaceID_XUL,
+                                          nsIDOMNode::ELEMENT_NODE);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   nsresult rv = NS_NewXULElement(getter_AddRefs(mPopupgroupContent),
                                  nodeInfo.forget());
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!aElements.AppendElement(mPopupgroupContent))
     return NS_ERROR_OUT_OF_MEMORY;
 
   // create the top-secret default tooltip node. shhhhh!
   nodeInfo = nodeInfoManager->GetNodeInfo(nsGkAtoms::tooltip, nsnull,
-                                          kNameSpaceID_XUL);
+                                          kNameSpaceID_XUL,
+                                          nsIDOMNode::ELEMENT_NODE);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   rv = NS_NewXULElement(getter_AddRefs(mTooltipContent), nodeInfo.forget());
   NS_ENSURE_SUCCESS(rv, rv);
 
   mTooltipContent->SetAttr(nsnull, nsGkAtoms::_default,
                            NS_LITERAL_STRING("true"), PR_FALSE);
 
--- a/parser/html/nsHtml5TreeOperation.cpp
+++ b/parser/html/nsHtml5TreeOperation.cpp
@@ -372,17 +372,18 @@ nsHtml5TreeOperation::Perform(nsHtml5Tre
       nsHtml5HtmlAttributes* attributes = mThree.attributes;
       
       PRBool isKeygen = (name == nsHtml5Atoms::keygen && ns == kNameSpaceID_XHTML);
       if (NS_UNLIKELY(isKeygen)) {
         name = nsHtml5Atoms::select;
       }
       
       nsCOMPtr<nsIContent> newContent;
-      nsCOMPtr<nsINodeInfo> nodeInfo = aBuilder->GetNodeInfoManager()->GetNodeInfo(name, nsnull, ns);
+      nsCOMPtr<nsINodeInfo> nodeInfo = aBuilder->GetNodeInfoManager()->
+        GetNodeInfo(name, nsnull, ns, nsIDOMNode::ELEMENT_NODE);
       NS_ASSERTION(nodeInfo, "Got null nodeinfo.");
       NS_NewElement(getter_AddRefs(newContent),
                     ns, nodeInfo.forget(),
                     (mOpCode == eTreeOpCreateElementNetwork ?
                      dom::FROM_PARSER_NETWORK
                      : (aBuilder->IsFragmentMode() ?
                         dom::FROM_PARSER_FRAGMENT :
                         dom::FROM_PARSER_DOCUMENT_WRITE)));
@@ -413,17 +414,18 @@ nsHtml5TreeOperation::Perform(nsHtml5Tre
                             nsGkAtoms::moztype, 
                             nsnull, 
                             theAttribute,
                             PR_FALSE);
 
         nsCOMPtr<nsINodeInfo> optionNodeInfo = 
           aBuilder->GetNodeInfoManager()->GetNodeInfo(nsHtml5Atoms::option, 
                                                       nsnull, 
-                                                      kNameSpaceID_XHTML);
+                                                      kNameSpaceID_XHTML,
+                                                      nsIDOMNode::ELEMENT_NODE);
                                                       
         for (PRUint32 i = 0; i < theContent.Length(); ++i) {
           nsCOMPtr<nsIContent> optionElt;
           nsCOMPtr<nsINodeInfo> ni = optionNodeInfo;
           NS_NewElement(getter_AddRefs(optionElt), 
                         optionNodeInfo->NamespaceID(), 
                         ni.forget(),
                         (mOpCode == eTreeOpCreateElementNetwork ?