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 71060 dd6e523b0b82af5da86c18bd3f1354a8f33f5b9f
parent 71059 0438ee84824cd63e174806b1abc665726e0e9aaf
child 71061 af6c49e8893331fb2b093e2fea3bd2918eb0027e
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersbz
bugs659539
milestone7.0a1
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 ?