From 192aa0c82e5bb63608a4d5a2ebafa65f0e025892 Mon Sep 17 00:00:00 2001 From: "jst%netscape.com" Date: Fri, 23 Jun 2000 00:21:32 +0000 Subject: [PATCH] Fixing nsbeta2+ bug 33477, completing (more or less) the DOM Level 2 NamedNodeMap implementation, this includes modifying the XML content sink to properly pass attribute prefixes to the content objects. r=vidur@netscape.com --- content/base/src/nsDOMAttribute.cpp | 142 +++++--- content/base/src/nsDOMAttribute.h | 9 +- content/base/src/nsDOMAttributeMap.cpp | 333 ++++++++++++++---- content/base/src/nsDOMAttributeMap.h | 9 - content/base/src/nsDocument.cpp | 17 +- content/base/src/nsDocumentFragment.cpp | 2 +- content/base/src/nsGenericDOMDataNode.cpp | 6 +- content/base/src/nsGenericElement.cpp | 149 ++++---- content/base/src/nsNameSpaceManager.cpp | 2 +- content/xml/content/src/nsXMLElement.cpp | 41 +-- content/xml/document/src/nsXMLContentSink.cpp | 45 ++- layout/base/src/nsDOMAttribute.cpp | 142 +++++--- layout/base/src/nsDOMAttribute.h | 9 +- layout/base/src/nsDOMAttributeMap.cpp | 333 ++++++++++++++---- layout/base/src/nsDOMAttributeMap.h | 9 - layout/base/src/nsDocument.cpp | 17 +- layout/base/src/nsDocumentFragment.cpp | 2 +- layout/base/src/nsGenericDOMDataNode.cpp | 6 +- layout/base/src/nsGenericElement.cpp | 149 ++++---- layout/base/src/nsNameSpaceManager.cpp | 2 +- layout/xml/content/src/nsXMLElement.cpp | 41 +-- layout/xml/document/src/nsXMLContentSink.cpp | 45 ++- 22 files changed, 956 insertions(+), 554 deletions(-) diff --git a/content/base/src/nsDOMAttribute.cpp b/content/base/src/nsDOMAttribute.cpp index 82255773a3b..e70431065b4 100644 --- a/content/base/src/nsDOMAttribute.cpp +++ b/content/base/src/nsDOMAttribute.cpp @@ -35,10 +35,12 @@ static NS_DEFINE_IID(kIDOMNodeListIID, NS_IDOMNODELIST_IID); //---------------------------------------------------------------------- nsDOMAttribute::nsDOMAttribute(nsIContent* aContent, - const nsString& aName, + nsINodeInfo *aNodeInfo, const nsString& aValue) - : mName(aName), mValue(aValue) + : mNodeInfo(aNodeInfo), mValue(aValue) { + NS_ABORT_IF_FALSE(mNodeInfo, "We must get a nodeinfo here!"); + NS_INIT_REFCNT(); // We don't add a reference to our content. It will tell us // to drop our reference when it goes away. @@ -117,15 +119,7 @@ NS_IMETHODIMP nsDOMAttribute::GetContent(nsIContent** aContent) { *aContent = mContent; - NS_IF_ADDREF(mContent); - - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttribute::SetName(const nsString& aName) -{ - mName=aName; + NS_IF_ADDREF(*aContent); return NS_OK; } @@ -163,29 +157,30 @@ nsDOMAttribute::SetScriptObject(void *aScriptObject) nsresult nsDOMAttribute::GetName(nsString& aName) { - aName=mName; - return NS_OK; + NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_FAILURE); + + return mNodeInfo->GetQualifiedName(aName); } nsresult nsDOMAttribute::GetValue(nsString& aValue) { + NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_FAILURE); + nsresult result = NS_OK; if (nsnull != mContent) { - nsIAtom* nameAtom; - PRInt32 nameSpaceID; nsresult attrResult; + PRInt32 nameSpaceID; + nsCOMPtr name; + + mNodeInfo->GetNameAtom(*getter_AddRefs(name)); + mNodeInfo->GetNamespaceID(nameSpaceID); - mContent->ParseAttributeString(mName, nameAtom, nameSpaceID); - if (kNameSpaceID_Unknown == nameSpaceID) { - nameSpaceID = kNameSpaceID_None; // ignore unknown prefix XXX is this correct? - } nsAutoString tmpValue; - attrResult = mContent->GetAttribute(nameSpaceID, nameAtom, tmpValue); + attrResult = mContent->GetAttribute(nameSpaceID, name, tmpValue); if (NS_CONTENT_ATTR_NOT_THERE != attrResult) { mValue = tmpValue; } - NS_IF_RELEASE(nameAtom); } aValue=mValue; return result; @@ -194,17 +189,11 @@ nsDOMAttribute::GetValue(nsString& aValue) nsresult nsDOMAttribute::SetValue(const nsString& aValue) { + NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_FAILURE); + nsresult result = NS_OK; if (nsnull != mContent) { - nsIAtom* nameAtom; - PRInt32 nameSpaceID; - - mContent->ParseAttributeString(mName, nameAtom, nameSpaceID); - if (kNameSpaceID_Unknown == nameSpaceID) { - nameSpaceID = kNameSpaceID_None; // ignore unknown prefix XXX is this correct? - } - result = mContent->SetAttribute(nameSpaceID, nameAtom, aValue, PR_TRUE); - NS_IF_RELEASE(nameAtom); + result = mContent->SetAttribute(mNodeInfo, aValue, PR_TRUE); } mValue=aValue; @@ -214,22 +203,22 @@ nsDOMAttribute::SetValue(const nsString& aValue) nsresult nsDOMAttribute::GetSpecified(PRBool* aSpecified) { + NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_FAILURE); + NS_ENSURE_ARG_POINTER(aSpecified); + nsresult result = NS_OK; if (nsnull == mContent) { *aSpecified = PR_FALSE; - } - else { + } else { nsAutoString value; nsresult attrResult; - nsIAtom* nameAtom; PRInt32 nameSpaceID; + nsCOMPtr name; - mContent->ParseAttributeString(mName, nameAtom, nameSpaceID); - if (kNameSpaceID_Unknown == nameSpaceID) { - nameSpaceID = kNameSpaceID_None; // ignore unknown prefix XXX is this correct? - } - attrResult = mContent->GetAttribute(nameSpaceID, nameAtom, value); - NS_IF_RELEASE(nameAtom); + mNodeInfo->GetNameAtom(*getter_AddRefs(name)); + mNodeInfo->GetNamespaceID(nameSpaceID); + + attrResult = mContent->GetAttribute(nameSpaceID, name, value); if (NS_CONTENT_ATTR_HAS_VALUE == attrResult) { *aSpecified = PR_TRUE; } @@ -277,6 +266,8 @@ nsDOMAttribute::SetNodeValue(const nsString& aNodeValue) NS_IMETHODIMP nsDOMAttribute::GetNodeType(PRUint16* aNodeType) { + NS_ENSURE_ARG_POINTER(aNodeType); + *aNodeType = (PRUint16)nsIDOMNode::ATTRIBUTE_NODE; return NS_OK; } @@ -284,6 +275,8 @@ nsDOMAttribute::GetNodeType(PRUint16* aNodeType) NS_IMETHODIMP nsDOMAttribute::GetParentNode(nsIDOMNode** aParentNode) { + NS_ENSURE_ARG_POINTER(aParentNode); + *aParentNode = nsnull; return NS_OK; } @@ -360,6 +353,8 @@ nsDOMAttribute::GetLastChild(nsIDOMNode** aLastChild) NS_IMETHODIMP nsDOMAttribute::GetPreviousSibling(nsIDOMNode** aPreviousSibling) { + NS_ENSURE_ARG_POINTER(aPreviousSibling); + *aPreviousSibling = nsnull; return NS_OK; } @@ -367,6 +362,8 @@ nsDOMAttribute::GetPreviousSibling(nsIDOMNode** aPreviousSibling) NS_IMETHODIMP nsDOMAttribute::GetNextSibling(nsIDOMNode** aNextSibling) { + NS_ENSURE_ARG_POINTER(aNextSibling); + *aNextSibling = nsnull; return NS_OK; } @@ -374,6 +371,8 @@ nsDOMAttribute::GetNextSibling(nsIDOMNode** aNextSibling) NS_IMETHODIMP nsDOMAttribute::GetAttributes(nsIDOMNamedNodeMap** aAttributes) { + NS_ENSURE_ARG_POINTER(aAttributes); + *aAttributes = nsnull; return NS_OK; } @@ -409,18 +408,17 @@ nsDOMAttribute::CloneNode(PRBool aDeep, nsIDOMNode** aReturn) if (nsnull != mContent) { nsAutoString value; - nsIAtom* nameAtom; PRInt32 nameSpaceID; + nsCOMPtr name; + + mNodeInfo->GetNameAtom(*getter_AddRefs(name)); + mNodeInfo->GetNamespaceID(nameSpaceID); - mContent->ParseAttributeString(mName, nameAtom, nameSpaceID); - if (kNameSpaceID_Unknown == nameSpaceID) { - nameSpaceID = kNameSpaceID_None; // ignore unknown prefix XXX is this correct? - } - mContent->GetAttribute(nameSpaceID, nameAtom, value); - newAttr = new nsDOMAttribute(nsnull, mName, value); + mContent->GetAttribute(nameSpaceID, name, value); + newAttr = new nsDOMAttribute(nsnull, mNodeInfo, value); } else { - newAttr = new nsDOMAttribute(nsnull, mName, mValue); + newAttr = new nsDOMAttribute(nsnull, mNodeInfo, mValue); } if (nsnull == newAttr) { @@ -452,35 +450,67 @@ nsDOMAttribute::GetOwnerDocument(nsIDOMDocument** aOwnerDocument) NS_IMETHODIMP nsDOMAttribute::GetNamespaceURI(nsString& aNamespaceURI) { - NS_NOTYETIMPLEMENTED("write me!"); - return NS_ERROR_NOT_IMPLEMENTED; + NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_FAILURE); + + return mNodeInfo->GetNamespaceURI(aNamespaceURI); } NS_IMETHODIMP nsDOMAttribute::GetPrefix(nsString& aPrefix) { - NS_NOTYETIMPLEMENTED("write me!"); - return NS_ERROR_NOT_IMPLEMENTED; + NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_FAILURE); + + return mNodeInfo->GetPrefix(aPrefix); } NS_IMETHODIMP nsDOMAttribute::SetPrefix(const nsString& aPrefix) { - NS_NOTYETIMPLEMENTED("write me!"); - return NS_ERROR_NOT_IMPLEMENTED; + NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_FAILURE); + nsCOMPtr newNodeInfo; + nsCOMPtr prefix; + nsresult rv = NS_OK; + + if (aPrefix.Length()) + prefix = dont_AddRef(NS_NewAtom(aPrefix)); + + rv = mNodeInfo->PrefixChanged(prefix, *getter_AddRefs(newNodeInfo)); + NS_ENSURE_SUCCESS(rv, rv); + + if (mContent) { + nsCOMPtr name; + PRInt32 nameSpaceID; + nsAutoString tmpValue; + + mNodeInfo->GetNameAtom(*getter_AddRefs(name)); + mNodeInfo->GetNamespaceID(nameSpaceID); + + rv = mContent->GetAttribute(nameSpaceID, name, tmpValue); + if (rv == NS_CONTENT_ATTR_HAS_VALUE) { + mContent->UnsetAttribute(nameSpaceID, name, PR_TRUE); + + mContent->SetAttribute(newNodeInfo, tmpValue, PR_TRUE); + } + } + + mNodeInfo = newNodeInfo; + + return NS_OK; } NS_IMETHODIMP nsDOMAttribute::GetLocalName(nsString& aLocalName) { - return GetName(aLocalName); + NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_FAILURE); + + return mNodeInfo->GetLocalName(aLocalName); } NS_IMETHODIMP nsDOMAttribute::Normalize() { - NS_NOTYETIMPLEMENTED("write me!"); - return NS_ERROR_NOT_IMPLEMENTED; + // Nothing to do here + return NS_OK; } NS_IMETHODIMP diff --git a/content/base/src/nsDOMAttribute.h b/content/base/src/nsDOMAttribute.h index 73e1069b857..a114d481a82 100644 --- a/content/base/src/nsDOMAttribute.h +++ b/content/base/src/nsDOMAttribute.h @@ -28,6 +28,8 @@ #include "nsIScriptObjectOwner.h" #include "nsGenericDOMNodeList.h" #include "nsString.h" +#include "nsCOMPtr.h" +#include "nsINodeInfo.h" class nsIContent; class nsDOMAttribute; @@ -41,7 +43,6 @@ public: NS_IMETHOD DropReference() = 0; NS_IMETHOD SetContent(nsIContent* aContent) = 0; NS_IMETHOD GetContent(nsIContent** aContent) = 0; - NS_IMETHOD SetName(const nsString& aName) = 0; }; // bogus child list for an attribute @@ -69,8 +70,7 @@ class nsDOMAttribute : public nsIDOMAttr, public nsIDOMAttributePrivate { public: - nsDOMAttribute(nsIContent* aContent, - const nsString& aName, + nsDOMAttribute(nsIContent* aContent, nsINodeInfo *aNodeInfo, const nsString& aValue); virtual ~nsDOMAttribute(); @@ -89,11 +89,10 @@ public: NS_IMETHOD DropReference(); NS_IMETHOD SetContent(nsIContent* aContent); NS_IMETHOD GetContent(nsIContent** aContent); - NS_IMETHOD SetName(const nsString& aName); private: nsIContent* mContent; - nsString mName; + nsCOMPtr mNodeInfo; nsString mValue; // XXX For now, there's only a single child - a text // element representing the value diff --git a/content/base/src/nsDOMAttributeMap.cpp b/content/base/src/nsDOMAttributeMap.cpp index f13cf6c44b1..c4113cd04c9 100644 --- a/content/base/src/nsDOMAttributeMap.cpp +++ b/content/base/src/nsDOMAttributeMap.cpp @@ -89,28 +89,6 @@ nsDOMAttributeMap::SetScriptObject(void *aScriptObject) return NS_OK; } -void -nsDOMAttributeMap::GetNormalizedName(PRInt32 aNameSpaceID, - nsIAtom* aNameAtom, - nsString& aAttrName) -{ - nsCOMPtr prefix; - aAttrName.Truncate(); - mContent->GetNameSpacePrefixFromId(aNameSpaceID, *getter_AddRefs(prefix)); - - if (prefix) { - prefix->ToString(aAttrName); - aAttrName.AppendWithConversion(":"); - } - - if (aNameAtom) { - nsAutoString tmp; - - aNameAtom->ToString(tmp); - aAttrName.Append(tmp); - } -} - nsresult nsDOMAttributeMap::GetNamedItem(const nsString &aAttrName, nsIDOMNode** aAttribute) @@ -120,29 +98,51 @@ nsDOMAttributeMap::GetNamedItem(const nsString &aAttrName, nsresult rv = NS_OK; if (mContent) { - nsCOMPtr nameAtom; - PRInt32 nameSpaceID; - nsAutoString normalizedName; - - mContent->ParseAttributeString(aAttrName, *getter_AddRefs(nameAtom), - nameSpaceID); - if (kNameSpaceID_Unknown == nameSpaceID) { - return NS_ERROR_DOM_NOT_FOUND_ERR; - } - - GetNormalizedName(nameSpaceID, nameAtom, normalizedName); - + nsCOMPtr nameAtom(dont_AddRef(NS_NewAtom(aAttrName))); + nsCOMPtr prefix; nsresult attrResult; nsAutoString value; - attrResult = mContent->GetAttribute(nameSpaceID, nameAtom, value); + + attrResult = mContent->GetAttribute(kNameSpaceID_Unknown, nameAtom, + *getter_AddRefs(prefix), value); if (NS_CONTENT_ATTR_NOT_THERE != attrResult && NS_SUCCEEDED(attrResult)) { - nsDOMAttribute* domAttribute; - domAttribute = new nsDOMAttribute(mContent, normalizedName, value); - if (!domAttribute) { - rv = NS_ERROR_OUT_OF_MEMORY; + PRInt32 nameSpaceID = kNameSpaceID_None; + + if (prefix) { + nsCOMPtr tmpName, tmpPrefix; + PRInt32 tmpNameSpaceID, attrCount; + + mContent->GetAttributeCount(attrCount); + + while (attrCount--) { + mContent->GetAttributeNameAt(attrCount, tmpNameSpaceID, + *getter_AddRefs(tmpName), + *getter_AddRefs(tmpPrefix)); + + if (tmpName == nameAtom && tmpPrefix == prefix) { + nameSpaceID = tmpNameSpaceID; + break; + } + } } + nsCOMPtr ni; + mContent->GetNodeInfo(*getter_AddRefs(ni)); + NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE); + + nsCOMPtr nimgr; + ni->GetNodeInfoManager(*getter_AddRefs(nimgr)); + NS_ENSURE_TRUE(nimgr, NS_ERROR_FAILURE); + + nimgr->GetNodeInfo(nameAtom, prefix, nameSpaceID, + *getter_AddRefs(ni)); + NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE); + + nsDOMAttribute* domAttribute; + domAttribute = new nsDOMAttribute(mContent, ni, value); + NS_ENSURE_TRUE(domAttribute, NS_ERROR_OUT_OF_MEMORY); + rv = domAttribute->QueryInterface(NS_GET_IID(nsIDOMAttr), (void **)aAttribute); } @@ -172,24 +172,30 @@ nsDOMAttributeMap::SetNamedItem(nsIDOMNode *aNode, nsIDOMNode **aReturn) nsAutoString name, value; nsCOMPtr nameAtom; - PRInt32 nameSpaceID; - // Get normalized attribute name attribute->GetName(name); - mContent->ParseAttributeString(name, *getter_AddRefs(nameAtom), - nameSpaceID); - if (kNameSpaceID_Unknown == nameSpaceID) { - nameSpaceID = kNameSpaceID_None; // ignore unknown prefix XXX is this correct? - } - GetNormalizedName(nameSpaceID, nameAtom, name); - nsresult attrResult = mContent->GetAttribute(nameSpaceID, nameAtom, value); + nsCOMPtr ni; + mContent->GetNodeInfo(*getter_AddRefs(ni)); + NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE); + + nsCOMPtr nimgr; + ni->GetNodeInfoManager(*getter_AddRefs(nimgr)); + NS_ENSURE_TRUE(nimgr, NS_ERROR_FAILURE); + + nimgr->GetNodeInfo(name, nsnull, kNameSpaceID_None, *getter_AddRefs(ni)); + NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE); + + ni->GetNameAtom(*getter_AddRefs(nameAtom)); + + nsresult attrResult = mContent->GetAttribute(kNameSpaceID_Unknown, + nameAtom, value); if (NS_CONTENT_ATTR_NOT_THERE != attrResult && NS_SUCCEEDED(attrResult)) { nsDOMAttribute* domAttribute; // We pass a null content here since the attr node we return isn't // tied to this content anymore. - domAttribute = new nsDOMAttribute(nsnull, name, value); + domAttribute = new nsDOMAttribute(nsnull, ni, value); if (!domAttribute) { return NS_ERROR_OUT_OF_MEMORY; } @@ -200,7 +206,7 @@ nsDOMAttributeMap::SetNamedItem(nsIDOMNode *aNode, nsIDOMNode **aReturn) attribute->GetValue(value); - rv = mContent->SetAttribute(nameSpaceID, nameAtom, value, PR_TRUE); + rv = mContent->SetAttribute(kNameSpaceID_None, nameAtom, value, PR_TRUE); } return rv; @@ -215,25 +221,48 @@ nsDOMAttributeMap::RemoveNamedItem(const nsString& aName, nsIDOMNode** aReturn) nsresult rv = NS_OK; if (mContent) { + nsCOMPtr nameAtom(dont_AddRef(NS_NewAtom(aName))); + PRInt32 nameSpaceID = kNameSpaceID_None; nsCOMPtr attribute; - nsCOMPtr nameAtom; - PRInt32 nameSpaceID; - nsAutoString name; name.Assign(aName); - - mContent->ParseAttributeString(aName, *getter_AddRefs(nameAtom), - nameSpaceID); - if (kNameSpaceID_Unknown == nameSpaceID) { - return NS_ERROR_DOM_NOT_FOUND_ERR; - } - GetNormalizedName(nameSpaceID, nameAtom, name); + nsCOMPtr prefix; nsresult attrResult; nsAutoString value; - attrResult = mContent->GetAttribute(nameSpaceID, nameAtom, value); + attrResult = mContent->GetAttribute(kNameSpaceID_Unknown, nameAtom, + *getter_AddRefs(prefix), value); if (NS_CONTENT_ATTR_NOT_THERE != attrResult && NS_SUCCEEDED(attrResult)) { + if (prefix) { + nsCOMPtr tmpName, tmpPrefix; + PRInt32 tmpNameSpaceID, attrCount; + + mContent->GetAttributeCount(attrCount); + + while (attrCount--) { + mContent->GetAttributeNameAt(attrCount, tmpNameSpaceID, + *getter_AddRefs(tmpName), + *getter_AddRefs(tmpPrefix)); + + if (tmpName == nameAtom && tmpPrefix == prefix) { + nameSpaceID = tmpNameSpaceID; + break; + } + } + } + + nsCOMPtr ni; + mContent->GetNodeInfo(*getter_AddRefs(ni)); + NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE); + + nsCOMPtr nimgr; + ni->GetNodeInfoManager(*getter_AddRefs(nimgr)); + NS_ENSURE_TRUE(nimgr, NS_ERROR_FAILURE); + + nimgr->GetNodeInfo(nameAtom, prefix, nameSpaceID, *getter_AddRefs(ni)); + NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE); + nsDOMAttribute* domAttribute; - domAttribute = new nsDOMAttribute(nsnull, name, value); + domAttribute = new nsDOMAttribute(nsnull, ni, value); if (!domAttribute) { return NS_ERROR_OUT_OF_MEMORY; } @@ -254,6 +283,7 @@ nsDOMAttributeMap::RemoveNamedItem(const nsString& aName, nsIDOMNode** aReturn) nsresult nsDOMAttributeMap::Item(PRUint32 aIndex, nsIDOMNode** aReturn) { + NS_ENSURE_ARG_POINTER(aReturn); PRInt32 nameSpaceID; nsCOMPtr nameAtom, prefix; @@ -266,14 +296,19 @@ nsDOMAttributeMap::Item(PRUint32 aIndex, nsIDOMNode** aReturn) nsAutoString value, name; mContent->GetAttribute(nameSpaceID, nameAtom, value); - GetNormalizedName(nameSpaceID, nameAtom, name); + nsCOMPtr ni; + mContent->GetNodeInfo(*getter_AddRefs(ni)); + NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE); - nsDOMAttribute* domAttribute; + nsCOMPtr nimgr; + ni->GetNodeInfoManager(*getter_AddRefs(nimgr)); + NS_ENSURE_TRUE(nimgr, NS_ERROR_FAILURE); - domAttribute = new nsDOMAttribute(mContent, name, value); - if (!domAttribute) { - return NS_ERROR_OUT_OF_MEMORY; - } + nimgr->GetNodeInfo(nameAtom, prefix, nameSpaceID, *getter_AddRefs(ni)); + NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE); + + nsDOMAttribute* domAttribute = new nsDOMAttribute(mContent, ni, value); + NS_ENSURE_TRUE(domAttribute, NS_ERROR_OUT_OF_MEMORY); rv = domAttribute->QueryInterface(NS_GET_IID(nsIDOMAttr), (void **)aReturn); @@ -309,21 +344,175 @@ nsDOMAttributeMap::GetNamedItemNS(const nsString& aNamespaceURI, const nsString& aLocalName, nsIDOMNode** aReturn) { - return NS_ERROR_NOT_IMPLEMENTED; + NS_ENSURE_ARG_POINTER(aReturn); + *aReturn = nsnull; + + nsresult rv = NS_OK; + if (mContent) { + nsCOMPtr nameAtom(dont_AddRef(NS_NewAtom(aLocalName))); + PRInt32 nameSpaceID = kNameSpaceID_None; + nsCOMPtr prefix; + + nsCOMPtr ni; + mContent->GetNodeInfo(*getter_AddRefs(ni)); + NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE); + + nsCOMPtr nimgr; + ni->GetNodeInfoManager(*getter_AddRefs(nimgr)); + NS_ENSURE_TRUE(nimgr, NS_ERROR_FAILURE); + + if (aNamespaceURI.Length()) { + nsCOMPtr nsmgr; + nimgr->GetNamespaceManager(*getter_AddRefs(nsmgr)); + NS_ENSURE_TRUE(nsmgr, NS_ERROR_FAILURE); + + nsmgr->GetNameSpaceID(aNamespaceURI, nameSpaceID); + + if (nameSpaceID == kNameSpaceID_Unknown) + return NS_OK; + } + + nsresult attrResult; + nsAutoString value; + + attrResult = mContent->GetAttribute(nameSpaceID, nameAtom, + *getter_AddRefs(prefix), value); + + if (NS_CONTENT_ATTR_NOT_THERE != attrResult && NS_SUCCEEDED(attrResult)) { + nimgr->GetNodeInfo(nameAtom, prefix, nameSpaceID, *getter_AddRefs(ni)); + NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE); + + nsDOMAttribute* domAttribute; + domAttribute = new nsDOMAttribute(mContent, ni, value); + NS_ENSURE_TRUE(domAttribute, NS_ERROR_OUT_OF_MEMORY); + + rv = domAttribute->QueryInterface(NS_GET_IID(nsIDOMAttr), + (void **)aReturn); + } + } + + return rv; } nsresult nsDOMAttributeMap::SetNamedItemNS(nsIDOMNode* aArg, nsIDOMNode** aReturn) { - return NS_ERROR_NOT_IMPLEMENTED; + NS_ENSURE_ARG_POINTER(aReturn); + + nsresult rv = NS_OK; + *aReturn = nsnull; + + if (mContent) { + nsCOMPtr attribute(do_QueryInterface(aArg)); + + if (!attribute) { + return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR; + } + + nsAutoString name, nsURI, value; + nsCOMPtr nameAtom; + PRInt32 nameSpaceID; + + attribute->GetName(name); + attribute->GetNamespaceURI(nsURI); + + nsCOMPtr ni; + mContent->GetNodeInfo(*getter_AddRefs(ni)); + NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE); + + nsCOMPtr nimgr; + ni->GetNodeInfoManager(*getter_AddRefs(nimgr)); + NS_ENSURE_TRUE(nimgr, NS_ERROR_FAILURE); + + nimgr->GetNodeInfo(name, nsURI, *getter_AddRefs(ni)); + NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE); + + ni->GetNameAtom(*getter_AddRefs(nameAtom)); + ni->GetNamespaceID(nameSpaceID); + + nsresult attrResult = mContent->GetAttribute(nameSpaceID, nameAtom, value); + + if (NS_CONTENT_ATTR_NOT_THERE != attrResult && NS_SUCCEEDED(attrResult)) { + nsDOMAttribute* domAttribute; + // We pass a null content here since the attr node we return isn't + // tied to this content anymore. + domAttribute = new nsDOMAttribute(nsnull, ni, value); + if (!domAttribute) { + return NS_ERROR_OUT_OF_MEMORY; + } + + rv = domAttribute->QueryInterface(NS_GET_IID(nsIDOMAttr), + (void **)aReturn); + } + + attribute->GetValue(value); + + rv = mContent->SetAttribute(ni, value, PR_TRUE); + } + + return rv; } nsresult nsDOMAttributeMap::RemoveNamedItemNS(const nsString& aNamespaceURI, - const nsString&aLocalName, + const nsString& aLocalName, nsIDOMNode** aReturn) { - return NS_ERROR_NOT_IMPLEMENTED; + NS_ENSURE_ARG_POINTER(aReturn); + *aReturn = nsnull; + + nsresult rv = NS_OK; + + if (mContent) { + nsCOMPtr nameAtom(dont_AddRef(NS_NewAtom(aLocalName))); + PRInt32 nameSpaceID = kNameSpaceID_None; + nsCOMPtr attribute; + nsCOMPtr prefix; + + nsCOMPtr ni; + mContent->GetNodeInfo(*getter_AddRefs(ni)); + NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE); + + nsCOMPtr nimgr; + ni->GetNodeInfoManager(*getter_AddRefs(nimgr)); + NS_ENSURE_TRUE(nimgr, NS_ERROR_FAILURE); + + if (aNamespaceURI.Length()) { + nsCOMPtr nsmgr; + nimgr->GetNamespaceManager(*getter_AddRefs(nsmgr)); + NS_ENSURE_TRUE(nsmgr, NS_ERROR_FAILURE); + + nsmgr->GetNameSpaceID(aNamespaceURI, nameSpaceID); + + if (nameSpaceID == kNameSpaceID_Unknown) + return NS_ERROR_DOM_NOT_FOUND_ERR; + } + + nsresult attrResult; + nsAutoString value; + attrResult = mContent->GetAttribute(nameSpaceID, nameAtom, + *getter_AddRefs(prefix), value); + + if (NS_CONTENT_ATTR_NOT_THERE != attrResult && NS_SUCCEEDED(attrResult)) { + nimgr->GetNodeInfo(nameAtom, prefix, nameSpaceID, *getter_AddRefs(ni)); + NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE); + + nsDOMAttribute* domAttribute; + domAttribute = new nsDOMAttribute(nsnull, ni, value); + if (!domAttribute) { + return NS_ERROR_OUT_OF_MEMORY; + } + + rv = domAttribute->QueryInterface(NS_GET_IID(nsIDOMAttr), + (void **)aReturn); + } else { + return NS_ERROR_DOM_NOT_FOUND_ERR; + } + + rv = mContent->UnsetAttribute(nameSpaceID, nameAtom, PR_TRUE); + } + + return rv; } diff --git a/content/base/src/nsDOMAttributeMap.h b/content/base/src/nsDOMAttributeMap.h index 5220ad605b2..720a925d4e0 100644 --- a/content/base/src/nsDOMAttributeMap.h +++ b/content/base/src/nsDOMAttributeMap.h @@ -63,15 +63,6 @@ public: PRUint32* aResult); #endif -protected: - nsresult GetNamedItemCommon(const nsString& aAttrName, - PRInt32 aNameSpaceID, - nsIAtom* aNameAtom, - nsIDOMNode** aAttribute); - void GetNormalizedName(PRInt32 aNameSpaceID, - nsIAtom* aNameAtom, - nsString& aAttrName); - private: nsIContent* mContent; void* mScriptObject; diff --git a/content/base/src/nsDocument.cpp b/content/base/src/nsDocument.cpp index f637c4a4efb..1d5542f03f7 100644 --- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -2146,14 +2146,19 @@ NS_IMETHODIMP nsDocument::CreateAttribute(const nsString& aName, nsIDOMAttr** aReturn) { + NS_ENSURE_ARG_POINTER(aReturn); + NS_ENSURE_TRUE(mNodeInfoManager, NS_ERROR_NOT_INITIALIZED); + nsAutoString value; nsDOMAttribute* attribute; - - value.Truncate(); - attribute = new nsDOMAttribute(nsnull, aName, value); - if (nsnull == attribute) { - return NS_ERROR_OUT_OF_MEMORY; - } + + nsCOMPtr nodeInfo; + nsresult rv = mNodeInfoManager->GetNodeInfo(aName, nsnull, kNameSpaceID_None, + *getter_AddRefs(nodeInfo)); + NS_ENSURE_SUCCESS(rv, rv); + + attribute = new nsDOMAttribute(nsnull, nodeInfo, value); + NS_ENSURE_TRUE(attribute, NS_ERROR_OUT_OF_MEMORY); return attribute->QueryInterface(NS_GET_IID(nsIDOMAttr), (void**)aReturn); } diff --git a/content/base/src/nsDocumentFragment.cpp b/content/base/src/nsDocumentFragment.cpp index 185dea1d765..e79c01b14b6 100644 --- a/content/base/src/nsDocumentFragment.cpp +++ b/content/base/src/nsDocumentFragment.cpp @@ -425,7 +425,7 @@ nsDocumentFragment::CloneNode(PRBool aDeep, nsIDOMNode** aReturn) NS_IMETHODIMP nsDocumentFragment::Normalize() { - NS_NOTYETIMPLEMENTED("write me!"); + // Nothing to do here yet return NS_OK; } diff --git a/content/base/src/nsGenericDOMDataNode.cpp b/content/base/src/nsGenericDOMDataNode.cpp index b65a886777c..8db9e3e7b9a 100644 --- a/content/base/src/nsGenericDOMDataNode.cpp +++ b/content/base/src/nsGenericDOMDataNode.cpp @@ -217,28 +217,26 @@ nsGenericDOMDataNode::GetOwnerDocument(nsIDOMDocument** aOwnerDocument) nsresult nsGenericDOMDataNode::GetNamespaceURI(nsString& aNamespaceURI) { - NS_NOTYETIMPLEMENTED("write me!"); + aNamespaceURI.Truncate(); return NS_OK; } nsresult nsGenericDOMDataNode::GetPrefix(nsString& aPrefix) { - NS_NOTYETIMPLEMENTED("write me!"); + aPrefix.Truncate(); return NS_OK; } nsresult nsGenericDOMDataNode::SetPrefix(const nsString& aPrefix) { - NS_NOTYETIMPLEMENTED("write me!"); return NS_ERROR_DOM_NAMESPACE_ERR; } nsresult nsGenericDOMDataNode::Normalize() { - NS_NOTYETIMPLEMENTED("write me!"); return NS_OK; } diff --git a/content/base/src/nsGenericElement.cpp b/content/base/src/nsGenericElement.cpp index ba1726b305d..57852563ad9 100644 --- a/content/base/src/nsGenericElement.cpp +++ b/content/base/src/nsGenericElement.cpp @@ -714,15 +714,9 @@ nsGenericElement::GetTagName(nsString& aTagName) nsresult nsGenericElement::GetAttribute(const nsString& aName, nsString& aReturn) { - nsIAtom* nameAtom; - PRInt32 nameSpaceID; + nsCOMPtr nameAtom(dont_AddRef(NS_NewAtom(aName))); - mContent->ParseAttributeString(aName, nameAtom, nameSpaceID); - if (kNameSpaceID_Unknown == nameSpaceID) { - nameSpaceID = kNameSpaceID_None; // ignore unknown prefix XXX is this correct? - } - mContent->GetAttribute(nameSpaceID, nameAtom, aReturn); - NS_RELEASE(nameAtom); + mContent->GetAttribute(kNameSpaceID_Unknown, nameAtom, aReturn); return NS_OK; } @@ -1071,15 +1065,10 @@ nsGenericElement::HasAttribute(const nsString& aName, PRBool* aReturn) { NS_ENSURE_ARG_POINTER(aReturn); - nsCOMPtr name; - PRInt32 nsid; - - nsresult rv = mContent->ParseAttributeString(aName, *getter_AddRefs(name), - nsid); - NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr name(dont_AddRef(NS_NewAtom(aName))); nsAutoString tmp; - rv = mContent->GetAttribute(nsid, name, tmp); + nsresult rv = mContent->GetAttribute(kNameSpaceID_Unknown, name, tmp); *aReturn = rv == NS_CONTENT_ATTR_NOT_THERE ? PR_FALSE : PR_TRUE; @@ -2601,70 +2590,17 @@ nsGenericContainerElement::SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, const nsString& aValue, PRBool aNotify) { - NS_ASSERTION(kNameSpaceID_Unknown != aNameSpaceID, "must have name space ID"); - if (kNameSpaceID_Unknown == aNameSpaceID) { - return NS_ERROR_ILLEGAL_VALUE; - } - NS_ASSERTION(nsnull != aName, "must have attribute name"); - if (nsnull == aName) { - return NS_ERROR_NULL_POINTER; - } + nsresult rv; + nsCOMPtr nimgr; + rv = mNodeInfo->GetNodeInfoManager(*getter_AddRefs(nimgr)); + NS_ENSURE_SUCCESS(rv, rv); - nsresult rv = NS_ERROR_OUT_OF_MEMORY; + nsCOMPtr ni; + rv = nimgr->GetNodeInfo(aName, nsnull, aNameSpaceID, + *getter_AddRefs(ni)); + NS_ENSURE_SUCCESS(rv, rv); - if (nsnull == mAttributes) { - mAttributes = new nsVoidArray(); - } - - if (aNotify && (nsnull != mDocument)) { - mDocument->BeginUpdate(); - } - - if (nsnull != mAttributes) { - nsGenericAttribute* attr; - PRInt32 index; - PRInt32 count = mAttributes->Count(); - for (index = 0; index < count; index++) { - attr = (nsGenericAttribute*)mAttributes->ElementAt(index); - if (attr->mNodeInfo->Equals(aName, aNameSpaceID)) { - attr->mValue = aValue; - rv = NS_OK; - break; - } - } - - if (index >= count) { // didn't find it - nsCOMPtr nimgr; - mNodeInfo->GetNodeInfoManager(*getter_AddRefs(nimgr)); - - nsCOMPtr ni; - rv = nimgr->GetNodeInfo(aName, nsnull, aNameSpaceID, - *getter_AddRefs(ni)); - NS_ENSURE_SUCCESS(rv, rv); - - attr = new nsGenericAttribute(ni, aValue); - if (nsnull != attr) { - mAttributes->AppendElement(attr); - rv = NS_OK; - } - } - } - - if (mDocument && NS_SUCCEEDED(rv)) { - nsCOMPtr bindingManager; - mDocument->GetBindingManager(getter_AddRefs(bindingManager)); - nsCOMPtr binding; - bindingManager->GetBinding(mContent, getter_AddRefs(binding)); - if (binding) - binding->AttributeChanged(aName, aNameSpaceID, PR_FALSE); - - if (aNotify) { - mDocument->AttributeChanged(mContent, aNameSpaceID, aName, NS_STYLE_HINT_UNKNOWN); - mDocument->EndUpdate(); - } - } - - return rv; + return SetAttribute(ni, aValue, aNotify); } nsresult @@ -2674,15 +2610,58 @@ nsGenericContainerElement::SetAttribute(nsINodeInfo* aNodeInfo, { NS_ENSURE_ARG_POINTER(aNodeInfo); - nsCOMPtr atom; - PRInt32 nsid; + nsresult rv = NS_ERROR_OUT_OF_MEMORY; - aNodeInfo->GetNameAtom(*getter_AddRefs(atom)); - aNodeInfo->GetNamespaceID(nsid); + if (!mAttributes) { + mAttributes = new nsVoidArray(); + NS_ENSURE_TRUE(mAttributes, NS_ERROR_OUT_OF_MEMORY); + } + + if (aNotify && (nsnull != mDocument)) { + mDocument->BeginUpdate(); + } + + nsGenericAttribute* attr; + PRInt32 index; + PRInt32 count = mAttributes->Count(); + for (index = 0; index < count; index++) { + attr = (nsGenericAttribute*)mAttributes->ElementAt(index); + if (attr->mNodeInfo == aNodeInfo) { + attr->mValue = aValue; + rv = NS_OK; + break; + } + } + + if (index >= count) { // didn't find it + attr = new nsGenericAttribute(aNodeInfo, aValue); + NS_ENSURE_TRUE(attr, NS_ERROR_OUT_OF_MEMORY); - // We still rely on the old way of setting the attribute. + mAttributes->AppendElement(attr); + rv = NS_OK; + } - return SetAttribute(nsid, atom, aValue, aNotify); + if (mDocument && NS_SUCCEEDED(rv)) { + nsCOMPtr name; + PRInt32 nameSpaceID; + + aNodeInfo->GetNameAtom(*getter_AddRefs(name)); + aNodeInfo->GetNamespaceID(nameSpaceID); + + nsCOMPtr bindingManager; + mDocument->GetBindingManager(getter_AddRefs(bindingManager)); + nsCOMPtr binding; + bindingManager->GetBinding(mContent, getter_AddRefs(binding)); + if (binding) + binding->AttributeChanged(name, nameSpaceID, PR_FALSE); + + if (aNotify) { + mDocument->AttributeChanged(mContent, nameSpaceID, name, NS_STYLE_HINT_UNKNOWN); + mDocument->EndUpdate(); + } + } + + return rv; } nsresult @@ -2710,7 +2689,7 @@ nsGenericContainerElement::GetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, PRInt32 index; for (index = 0; index < count; index++) { const nsGenericAttribute* attr = (const nsGenericAttribute*)mAttributes->ElementAt(index); - if ((attr->mNodeInfo->NamespaceEquals(kNameSpaceID_Unknown) || + if ((aNameSpaceID == kNameSpaceID_Unknown || attr->mNodeInfo->NamespaceEquals(aNameSpaceID)) && (attr->mNodeInfo->Equals(aName))) { attr->mNodeInfo->GetPrefixAtom(aPrefix); @@ -2754,7 +2733,7 @@ nsGenericContainerElement::UnsetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, PRBool found = PR_FALSE; for (index = 0; index < count; index++) { nsGenericAttribute* attr = (nsGenericAttribute*)mAttributes->ElementAt(index); - if ((attr->mNodeInfo->NamespaceEquals(kNameSpaceID_Unknown) || + if ((aNameSpaceID == kNameSpaceID_Unknown || attr->mNodeInfo->NamespaceEquals(aNameSpaceID)) && attr->mNodeInfo->Equals(aName)) { if (aNotify && (nsnull != mDocument)) { diff --git a/content/base/src/nsNameSpaceManager.cpp b/content/base/src/nsNameSpaceManager.cpp index 523dd9a4a9c..a3fad0a4429 100644 --- a/content/base/src/nsNameSpaceManager.cpp +++ b/content/base/src/nsNameSpaceManager.cpp @@ -31,7 +31,7 @@ static NS_DEFINE_IID(kINameSpaceManagerIID, NS_INAMESPACEMANAGER_IID); static NS_DEFINE_IID(kINameSpaceIID, NS_INAMESPACE_IID); -static const char kXMLNSNameSpaceURI[] = ""; +static const char kXMLNSNameSpaceURI[] = "http://www.w3.org/2000/xmlns"; static const char kXMLNameSpaceURI[] = "http://www.w3.org/XML/1998/namespace"; static const char kHTMLNameSpaceURI[] = "http://www.w3.org/TR/REC-html40"; // XXX?? "urn:w3-org-ns:HTML"?? // XXX To be removed: Bug 7834 --- diff --git a/content/xml/content/src/nsXMLElement.cpp b/content/xml/content/src/nsXMLElement.cpp index b590c3ac198..2010ebcd54b 100644 --- a/content/xml/content/src/nsXMLElement.cpp +++ b/content/xml/content/src/nsXMLElement.cpp @@ -219,8 +219,26 @@ nsXMLElement::SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, const nsString& aValue, PRBool aNotify) { - if ((kNameSpaceID_XLink == aNameSpaceID) && - (kTypeAtom == aName)) { + nsresult rv; + nsCOMPtr nimgr; + rv = mInner.mNodeInfo->GetNodeInfoManager(*getter_AddRefs(nimgr)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr ni; + rv = nimgr->GetNodeInfo(aName, nsnull, aNameSpaceID, + *getter_AddRefs(ni)); + NS_ENSURE_SUCCESS(rv, rv); + + return SetAttribute(ni, aValue, aNotify); +} + +NS_IMETHODIMP +nsXMLElement::SetAttribute(nsINodeInfo *aNodeInfo, const nsString& aValue, + PRBool aNotify) +{ + NS_ENSURE_ARG_POINTER(aNodeInfo); + + if (aNodeInfo->Equals(kTypeAtom, kNameSpaceID_XLink)) { if (aValue.EqualsAtom(kSimpleAtom, PR_FALSE)) { // NOTE: This really is a link according to the XLink spec, // we do not need to check other attributes. If there @@ -237,24 +255,7 @@ nsXMLElement::SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, // We will check for actuate="onLoad" in MaybeTriggerAutoLink } - return mInner.SetAttribute(aNameSpaceID, aName, aValue, aNotify); -} - -NS_IMETHODIMP -nsXMLElement::SetAttribute(nsINodeInfo *aNodeInfo, const nsString& aValue, - PRBool aNotify) -{ - NS_ENSURE_ARG_POINTER(aNodeInfo); - - nsCOMPtr atom; - PRInt32 nsid; - - aNodeInfo->GetNameAtom(*getter_AddRefs(atom)); - aNodeInfo->GetNamespaceID(nsid); - - // We still rely on the old way of setting the attribute. - - return SetAttribute(nsid, atom, aValue, aNotify); + return mInner.SetAttribute(aNodeInfo, aValue, aNotify); } static nsresult WebShellToPresContext(nsIWebShell *aShell, nsIPresContext **aPresContext) diff --git a/content/xml/document/src/nsXMLContentSink.cpp b/content/xml/document/src/nsXMLContentSink.cpp index f43cd4a3677..1bf8a01b1cb 100644 --- a/content/xml/document/src/nsXMLContentSink.cpp +++ b/content/xml/document/src/nsXMLContentSink.cpp @@ -560,30 +560,39 @@ nsXMLContentSink::AddAttributes(const nsIParserNode& aNode, name.Truncate(); name.Append(key); - nsIAtom* nameSpacePrefix = CutNameSpacePrefix(name); - nsIAtom* nameAtom = NS_NewAtom(name); - PRInt32 nameSpaceID = (nsnull == nameSpacePrefix) ? kNameSpaceID_None : GetNameSpaceId(nameSpacePrefix); - if (kNameSpaceID_Unknown == nameSpaceID) { - nameSpaceID = kNameSpaceID_None; // XXX is this correct? or is it a bad document? + nsCOMPtr nameSpacePrefix(dont_AddRef(CutNameSpacePrefix(name))); + nsCOMPtr nameAtom(dont_AddRef(NS_NewAtom(name))); + PRInt32 nameSpaceID; + + if (nameSpacePrefix) { + nameSpaceID = GetNameSpaceId(nameSpacePrefix); + } else { + if (nameAtom.get() == nsLayoutAtoms::xmlnsNameSpace) + nameSpaceID = kNameSpaceID_XMLNS; + else + nameSpaceID = kNameSpaceID_None; } - if ((kNameSpaceID_XMLNS == nameSpaceID) && aIsHTML) { - NS_RELEASE(nameAtom); + + if (kNameSpaceID_Unknown == nameSpaceID) { + nameSpaceID = kNameSpaceID_None; + nameAtom = dont_AddRef(NS_NewAtom(key)); + nameSpacePrefix = nsnull; + } else if ((kNameSpaceID_XMLNS == nameSpaceID) && aIsHTML) { name.InsertWithConversion("xmlns:", 0); - nameAtom = NS_NewAtom(name); + nameAtom = dont_AddRef(NS_NewAtom(name)); nameSpaceID = kNameSpaceID_HTML; // XXX this is wrong, but necessary until HTML can store other namespaces for attrs } - nsAutoString value; - if (NS_CONTENT_ATTR_NOT_THERE == - aContent->GetAttribute(nameSpaceID, nameAtom, value)) { - // Get value and remove mandatory quotes - GetAttributeValueAt(aNode, i, v); + nsCOMPtr ni; + mNodeInfoManager->GetNodeInfo(nameAtom, nameSpacePrefix, nameSpaceID, + *getter_AddRefs(ni)); + NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE); - // Add attribute to content - aContent->SetAttribute(nameSpaceID, nameAtom, v, PR_FALSE); - } - NS_RELEASE(nameAtom); - NS_IF_RELEASE(nameSpacePrefix); + // Get value and remove mandatory quotes + GetAttributeValueAt(aNode, i, v); + + // Add attribute to content + aContent->SetAttribute(ni, v, PR_FALSE); } // Give autoloading links a chance to fire diff --git a/layout/base/src/nsDOMAttribute.cpp b/layout/base/src/nsDOMAttribute.cpp index 82255773a3b..e70431065b4 100644 --- a/layout/base/src/nsDOMAttribute.cpp +++ b/layout/base/src/nsDOMAttribute.cpp @@ -35,10 +35,12 @@ static NS_DEFINE_IID(kIDOMNodeListIID, NS_IDOMNODELIST_IID); //---------------------------------------------------------------------- nsDOMAttribute::nsDOMAttribute(nsIContent* aContent, - const nsString& aName, + nsINodeInfo *aNodeInfo, const nsString& aValue) - : mName(aName), mValue(aValue) + : mNodeInfo(aNodeInfo), mValue(aValue) { + NS_ABORT_IF_FALSE(mNodeInfo, "We must get a nodeinfo here!"); + NS_INIT_REFCNT(); // We don't add a reference to our content. It will tell us // to drop our reference when it goes away. @@ -117,15 +119,7 @@ NS_IMETHODIMP nsDOMAttribute::GetContent(nsIContent** aContent) { *aContent = mContent; - NS_IF_ADDREF(mContent); - - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttribute::SetName(const nsString& aName) -{ - mName=aName; + NS_IF_ADDREF(*aContent); return NS_OK; } @@ -163,29 +157,30 @@ nsDOMAttribute::SetScriptObject(void *aScriptObject) nsresult nsDOMAttribute::GetName(nsString& aName) { - aName=mName; - return NS_OK; + NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_FAILURE); + + return mNodeInfo->GetQualifiedName(aName); } nsresult nsDOMAttribute::GetValue(nsString& aValue) { + NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_FAILURE); + nsresult result = NS_OK; if (nsnull != mContent) { - nsIAtom* nameAtom; - PRInt32 nameSpaceID; nsresult attrResult; + PRInt32 nameSpaceID; + nsCOMPtr name; + + mNodeInfo->GetNameAtom(*getter_AddRefs(name)); + mNodeInfo->GetNamespaceID(nameSpaceID); - mContent->ParseAttributeString(mName, nameAtom, nameSpaceID); - if (kNameSpaceID_Unknown == nameSpaceID) { - nameSpaceID = kNameSpaceID_None; // ignore unknown prefix XXX is this correct? - } nsAutoString tmpValue; - attrResult = mContent->GetAttribute(nameSpaceID, nameAtom, tmpValue); + attrResult = mContent->GetAttribute(nameSpaceID, name, tmpValue); if (NS_CONTENT_ATTR_NOT_THERE != attrResult) { mValue = tmpValue; } - NS_IF_RELEASE(nameAtom); } aValue=mValue; return result; @@ -194,17 +189,11 @@ nsDOMAttribute::GetValue(nsString& aValue) nsresult nsDOMAttribute::SetValue(const nsString& aValue) { + NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_FAILURE); + nsresult result = NS_OK; if (nsnull != mContent) { - nsIAtom* nameAtom; - PRInt32 nameSpaceID; - - mContent->ParseAttributeString(mName, nameAtom, nameSpaceID); - if (kNameSpaceID_Unknown == nameSpaceID) { - nameSpaceID = kNameSpaceID_None; // ignore unknown prefix XXX is this correct? - } - result = mContent->SetAttribute(nameSpaceID, nameAtom, aValue, PR_TRUE); - NS_IF_RELEASE(nameAtom); + result = mContent->SetAttribute(mNodeInfo, aValue, PR_TRUE); } mValue=aValue; @@ -214,22 +203,22 @@ nsDOMAttribute::SetValue(const nsString& aValue) nsresult nsDOMAttribute::GetSpecified(PRBool* aSpecified) { + NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_FAILURE); + NS_ENSURE_ARG_POINTER(aSpecified); + nsresult result = NS_OK; if (nsnull == mContent) { *aSpecified = PR_FALSE; - } - else { + } else { nsAutoString value; nsresult attrResult; - nsIAtom* nameAtom; PRInt32 nameSpaceID; + nsCOMPtr name; - mContent->ParseAttributeString(mName, nameAtom, nameSpaceID); - if (kNameSpaceID_Unknown == nameSpaceID) { - nameSpaceID = kNameSpaceID_None; // ignore unknown prefix XXX is this correct? - } - attrResult = mContent->GetAttribute(nameSpaceID, nameAtom, value); - NS_IF_RELEASE(nameAtom); + mNodeInfo->GetNameAtom(*getter_AddRefs(name)); + mNodeInfo->GetNamespaceID(nameSpaceID); + + attrResult = mContent->GetAttribute(nameSpaceID, name, value); if (NS_CONTENT_ATTR_HAS_VALUE == attrResult) { *aSpecified = PR_TRUE; } @@ -277,6 +266,8 @@ nsDOMAttribute::SetNodeValue(const nsString& aNodeValue) NS_IMETHODIMP nsDOMAttribute::GetNodeType(PRUint16* aNodeType) { + NS_ENSURE_ARG_POINTER(aNodeType); + *aNodeType = (PRUint16)nsIDOMNode::ATTRIBUTE_NODE; return NS_OK; } @@ -284,6 +275,8 @@ nsDOMAttribute::GetNodeType(PRUint16* aNodeType) NS_IMETHODIMP nsDOMAttribute::GetParentNode(nsIDOMNode** aParentNode) { + NS_ENSURE_ARG_POINTER(aParentNode); + *aParentNode = nsnull; return NS_OK; } @@ -360,6 +353,8 @@ nsDOMAttribute::GetLastChild(nsIDOMNode** aLastChild) NS_IMETHODIMP nsDOMAttribute::GetPreviousSibling(nsIDOMNode** aPreviousSibling) { + NS_ENSURE_ARG_POINTER(aPreviousSibling); + *aPreviousSibling = nsnull; return NS_OK; } @@ -367,6 +362,8 @@ nsDOMAttribute::GetPreviousSibling(nsIDOMNode** aPreviousSibling) NS_IMETHODIMP nsDOMAttribute::GetNextSibling(nsIDOMNode** aNextSibling) { + NS_ENSURE_ARG_POINTER(aNextSibling); + *aNextSibling = nsnull; return NS_OK; } @@ -374,6 +371,8 @@ nsDOMAttribute::GetNextSibling(nsIDOMNode** aNextSibling) NS_IMETHODIMP nsDOMAttribute::GetAttributes(nsIDOMNamedNodeMap** aAttributes) { + NS_ENSURE_ARG_POINTER(aAttributes); + *aAttributes = nsnull; return NS_OK; } @@ -409,18 +408,17 @@ nsDOMAttribute::CloneNode(PRBool aDeep, nsIDOMNode** aReturn) if (nsnull != mContent) { nsAutoString value; - nsIAtom* nameAtom; PRInt32 nameSpaceID; + nsCOMPtr name; + + mNodeInfo->GetNameAtom(*getter_AddRefs(name)); + mNodeInfo->GetNamespaceID(nameSpaceID); - mContent->ParseAttributeString(mName, nameAtom, nameSpaceID); - if (kNameSpaceID_Unknown == nameSpaceID) { - nameSpaceID = kNameSpaceID_None; // ignore unknown prefix XXX is this correct? - } - mContent->GetAttribute(nameSpaceID, nameAtom, value); - newAttr = new nsDOMAttribute(nsnull, mName, value); + mContent->GetAttribute(nameSpaceID, name, value); + newAttr = new nsDOMAttribute(nsnull, mNodeInfo, value); } else { - newAttr = new nsDOMAttribute(nsnull, mName, mValue); + newAttr = new nsDOMAttribute(nsnull, mNodeInfo, mValue); } if (nsnull == newAttr) { @@ -452,35 +450,67 @@ nsDOMAttribute::GetOwnerDocument(nsIDOMDocument** aOwnerDocument) NS_IMETHODIMP nsDOMAttribute::GetNamespaceURI(nsString& aNamespaceURI) { - NS_NOTYETIMPLEMENTED("write me!"); - return NS_ERROR_NOT_IMPLEMENTED; + NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_FAILURE); + + return mNodeInfo->GetNamespaceURI(aNamespaceURI); } NS_IMETHODIMP nsDOMAttribute::GetPrefix(nsString& aPrefix) { - NS_NOTYETIMPLEMENTED("write me!"); - return NS_ERROR_NOT_IMPLEMENTED; + NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_FAILURE); + + return mNodeInfo->GetPrefix(aPrefix); } NS_IMETHODIMP nsDOMAttribute::SetPrefix(const nsString& aPrefix) { - NS_NOTYETIMPLEMENTED("write me!"); - return NS_ERROR_NOT_IMPLEMENTED; + NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_FAILURE); + nsCOMPtr newNodeInfo; + nsCOMPtr prefix; + nsresult rv = NS_OK; + + if (aPrefix.Length()) + prefix = dont_AddRef(NS_NewAtom(aPrefix)); + + rv = mNodeInfo->PrefixChanged(prefix, *getter_AddRefs(newNodeInfo)); + NS_ENSURE_SUCCESS(rv, rv); + + if (mContent) { + nsCOMPtr name; + PRInt32 nameSpaceID; + nsAutoString tmpValue; + + mNodeInfo->GetNameAtom(*getter_AddRefs(name)); + mNodeInfo->GetNamespaceID(nameSpaceID); + + rv = mContent->GetAttribute(nameSpaceID, name, tmpValue); + if (rv == NS_CONTENT_ATTR_HAS_VALUE) { + mContent->UnsetAttribute(nameSpaceID, name, PR_TRUE); + + mContent->SetAttribute(newNodeInfo, tmpValue, PR_TRUE); + } + } + + mNodeInfo = newNodeInfo; + + return NS_OK; } NS_IMETHODIMP nsDOMAttribute::GetLocalName(nsString& aLocalName) { - return GetName(aLocalName); + NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_FAILURE); + + return mNodeInfo->GetLocalName(aLocalName); } NS_IMETHODIMP nsDOMAttribute::Normalize() { - NS_NOTYETIMPLEMENTED("write me!"); - return NS_ERROR_NOT_IMPLEMENTED; + // Nothing to do here + return NS_OK; } NS_IMETHODIMP diff --git a/layout/base/src/nsDOMAttribute.h b/layout/base/src/nsDOMAttribute.h index 73e1069b857..a114d481a82 100644 --- a/layout/base/src/nsDOMAttribute.h +++ b/layout/base/src/nsDOMAttribute.h @@ -28,6 +28,8 @@ #include "nsIScriptObjectOwner.h" #include "nsGenericDOMNodeList.h" #include "nsString.h" +#include "nsCOMPtr.h" +#include "nsINodeInfo.h" class nsIContent; class nsDOMAttribute; @@ -41,7 +43,6 @@ public: NS_IMETHOD DropReference() = 0; NS_IMETHOD SetContent(nsIContent* aContent) = 0; NS_IMETHOD GetContent(nsIContent** aContent) = 0; - NS_IMETHOD SetName(const nsString& aName) = 0; }; // bogus child list for an attribute @@ -69,8 +70,7 @@ class nsDOMAttribute : public nsIDOMAttr, public nsIDOMAttributePrivate { public: - nsDOMAttribute(nsIContent* aContent, - const nsString& aName, + nsDOMAttribute(nsIContent* aContent, nsINodeInfo *aNodeInfo, const nsString& aValue); virtual ~nsDOMAttribute(); @@ -89,11 +89,10 @@ public: NS_IMETHOD DropReference(); NS_IMETHOD SetContent(nsIContent* aContent); NS_IMETHOD GetContent(nsIContent** aContent); - NS_IMETHOD SetName(const nsString& aName); private: nsIContent* mContent; - nsString mName; + nsCOMPtr mNodeInfo; nsString mValue; // XXX For now, there's only a single child - a text // element representing the value diff --git a/layout/base/src/nsDOMAttributeMap.cpp b/layout/base/src/nsDOMAttributeMap.cpp index f13cf6c44b1..c4113cd04c9 100644 --- a/layout/base/src/nsDOMAttributeMap.cpp +++ b/layout/base/src/nsDOMAttributeMap.cpp @@ -89,28 +89,6 @@ nsDOMAttributeMap::SetScriptObject(void *aScriptObject) return NS_OK; } -void -nsDOMAttributeMap::GetNormalizedName(PRInt32 aNameSpaceID, - nsIAtom* aNameAtom, - nsString& aAttrName) -{ - nsCOMPtr prefix; - aAttrName.Truncate(); - mContent->GetNameSpacePrefixFromId(aNameSpaceID, *getter_AddRefs(prefix)); - - if (prefix) { - prefix->ToString(aAttrName); - aAttrName.AppendWithConversion(":"); - } - - if (aNameAtom) { - nsAutoString tmp; - - aNameAtom->ToString(tmp); - aAttrName.Append(tmp); - } -} - nsresult nsDOMAttributeMap::GetNamedItem(const nsString &aAttrName, nsIDOMNode** aAttribute) @@ -120,29 +98,51 @@ nsDOMAttributeMap::GetNamedItem(const nsString &aAttrName, nsresult rv = NS_OK; if (mContent) { - nsCOMPtr nameAtom; - PRInt32 nameSpaceID; - nsAutoString normalizedName; - - mContent->ParseAttributeString(aAttrName, *getter_AddRefs(nameAtom), - nameSpaceID); - if (kNameSpaceID_Unknown == nameSpaceID) { - return NS_ERROR_DOM_NOT_FOUND_ERR; - } - - GetNormalizedName(nameSpaceID, nameAtom, normalizedName); - + nsCOMPtr nameAtom(dont_AddRef(NS_NewAtom(aAttrName))); + nsCOMPtr prefix; nsresult attrResult; nsAutoString value; - attrResult = mContent->GetAttribute(nameSpaceID, nameAtom, value); + + attrResult = mContent->GetAttribute(kNameSpaceID_Unknown, nameAtom, + *getter_AddRefs(prefix), value); if (NS_CONTENT_ATTR_NOT_THERE != attrResult && NS_SUCCEEDED(attrResult)) { - nsDOMAttribute* domAttribute; - domAttribute = new nsDOMAttribute(mContent, normalizedName, value); - if (!domAttribute) { - rv = NS_ERROR_OUT_OF_MEMORY; + PRInt32 nameSpaceID = kNameSpaceID_None; + + if (prefix) { + nsCOMPtr tmpName, tmpPrefix; + PRInt32 tmpNameSpaceID, attrCount; + + mContent->GetAttributeCount(attrCount); + + while (attrCount--) { + mContent->GetAttributeNameAt(attrCount, tmpNameSpaceID, + *getter_AddRefs(tmpName), + *getter_AddRefs(tmpPrefix)); + + if (tmpName == nameAtom && tmpPrefix == prefix) { + nameSpaceID = tmpNameSpaceID; + break; + } + } } + nsCOMPtr ni; + mContent->GetNodeInfo(*getter_AddRefs(ni)); + NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE); + + nsCOMPtr nimgr; + ni->GetNodeInfoManager(*getter_AddRefs(nimgr)); + NS_ENSURE_TRUE(nimgr, NS_ERROR_FAILURE); + + nimgr->GetNodeInfo(nameAtom, prefix, nameSpaceID, + *getter_AddRefs(ni)); + NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE); + + nsDOMAttribute* domAttribute; + domAttribute = new nsDOMAttribute(mContent, ni, value); + NS_ENSURE_TRUE(domAttribute, NS_ERROR_OUT_OF_MEMORY); + rv = domAttribute->QueryInterface(NS_GET_IID(nsIDOMAttr), (void **)aAttribute); } @@ -172,24 +172,30 @@ nsDOMAttributeMap::SetNamedItem(nsIDOMNode *aNode, nsIDOMNode **aReturn) nsAutoString name, value; nsCOMPtr nameAtom; - PRInt32 nameSpaceID; - // Get normalized attribute name attribute->GetName(name); - mContent->ParseAttributeString(name, *getter_AddRefs(nameAtom), - nameSpaceID); - if (kNameSpaceID_Unknown == nameSpaceID) { - nameSpaceID = kNameSpaceID_None; // ignore unknown prefix XXX is this correct? - } - GetNormalizedName(nameSpaceID, nameAtom, name); - nsresult attrResult = mContent->GetAttribute(nameSpaceID, nameAtom, value); + nsCOMPtr ni; + mContent->GetNodeInfo(*getter_AddRefs(ni)); + NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE); + + nsCOMPtr nimgr; + ni->GetNodeInfoManager(*getter_AddRefs(nimgr)); + NS_ENSURE_TRUE(nimgr, NS_ERROR_FAILURE); + + nimgr->GetNodeInfo(name, nsnull, kNameSpaceID_None, *getter_AddRefs(ni)); + NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE); + + ni->GetNameAtom(*getter_AddRefs(nameAtom)); + + nsresult attrResult = mContent->GetAttribute(kNameSpaceID_Unknown, + nameAtom, value); if (NS_CONTENT_ATTR_NOT_THERE != attrResult && NS_SUCCEEDED(attrResult)) { nsDOMAttribute* domAttribute; // We pass a null content here since the attr node we return isn't // tied to this content anymore. - domAttribute = new nsDOMAttribute(nsnull, name, value); + domAttribute = new nsDOMAttribute(nsnull, ni, value); if (!domAttribute) { return NS_ERROR_OUT_OF_MEMORY; } @@ -200,7 +206,7 @@ nsDOMAttributeMap::SetNamedItem(nsIDOMNode *aNode, nsIDOMNode **aReturn) attribute->GetValue(value); - rv = mContent->SetAttribute(nameSpaceID, nameAtom, value, PR_TRUE); + rv = mContent->SetAttribute(kNameSpaceID_None, nameAtom, value, PR_TRUE); } return rv; @@ -215,25 +221,48 @@ nsDOMAttributeMap::RemoveNamedItem(const nsString& aName, nsIDOMNode** aReturn) nsresult rv = NS_OK; if (mContent) { + nsCOMPtr nameAtom(dont_AddRef(NS_NewAtom(aName))); + PRInt32 nameSpaceID = kNameSpaceID_None; nsCOMPtr attribute; - nsCOMPtr nameAtom; - PRInt32 nameSpaceID; - nsAutoString name; name.Assign(aName); - - mContent->ParseAttributeString(aName, *getter_AddRefs(nameAtom), - nameSpaceID); - if (kNameSpaceID_Unknown == nameSpaceID) { - return NS_ERROR_DOM_NOT_FOUND_ERR; - } - GetNormalizedName(nameSpaceID, nameAtom, name); + nsCOMPtr prefix; nsresult attrResult; nsAutoString value; - attrResult = mContent->GetAttribute(nameSpaceID, nameAtom, value); + attrResult = mContent->GetAttribute(kNameSpaceID_Unknown, nameAtom, + *getter_AddRefs(prefix), value); if (NS_CONTENT_ATTR_NOT_THERE != attrResult && NS_SUCCEEDED(attrResult)) { + if (prefix) { + nsCOMPtr tmpName, tmpPrefix; + PRInt32 tmpNameSpaceID, attrCount; + + mContent->GetAttributeCount(attrCount); + + while (attrCount--) { + mContent->GetAttributeNameAt(attrCount, tmpNameSpaceID, + *getter_AddRefs(tmpName), + *getter_AddRefs(tmpPrefix)); + + if (tmpName == nameAtom && tmpPrefix == prefix) { + nameSpaceID = tmpNameSpaceID; + break; + } + } + } + + nsCOMPtr ni; + mContent->GetNodeInfo(*getter_AddRefs(ni)); + NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE); + + nsCOMPtr nimgr; + ni->GetNodeInfoManager(*getter_AddRefs(nimgr)); + NS_ENSURE_TRUE(nimgr, NS_ERROR_FAILURE); + + nimgr->GetNodeInfo(nameAtom, prefix, nameSpaceID, *getter_AddRefs(ni)); + NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE); + nsDOMAttribute* domAttribute; - domAttribute = new nsDOMAttribute(nsnull, name, value); + domAttribute = new nsDOMAttribute(nsnull, ni, value); if (!domAttribute) { return NS_ERROR_OUT_OF_MEMORY; } @@ -254,6 +283,7 @@ nsDOMAttributeMap::RemoveNamedItem(const nsString& aName, nsIDOMNode** aReturn) nsresult nsDOMAttributeMap::Item(PRUint32 aIndex, nsIDOMNode** aReturn) { + NS_ENSURE_ARG_POINTER(aReturn); PRInt32 nameSpaceID; nsCOMPtr nameAtom, prefix; @@ -266,14 +296,19 @@ nsDOMAttributeMap::Item(PRUint32 aIndex, nsIDOMNode** aReturn) nsAutoString value, name; mContent->GetAttribute(nameSpaceID, nameAtom, value); - GetNormalizedName(nameSpaceID, nameAtom, name); + nsCOMPtr ni; + mContent->GetNodeInfo(*getter_AddRefs(ni)); + NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE); - nsDOMAttribute* domAttribute; + nsCOMPtr nimgr; + ni->GetNodeInfoManager(*getter_AddRefs(nimgr)); + NS_ENSURE_TRUE(nimgr, NS_ERROR_FAILURE); - domAttribute = new nsDOMAttribute(mContent, name, value); - if (!domAttribute) { - return NS_ERROR_OUT_OF_MEMORY; - } + nimgr->GetNodeInfo(nameAtom, prefix, nameSpaceID, *getter_AddRefs(ni)); + NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE); + + nsDOMAttribute* domAttribute = new nsDOMAttribute(mContent, ni, value); + NS_ENSURE_TRUE(domAttribute, NS_ERROR_OUT_OF_MEMORY); rv = domAttribute->QueryInterface(NS_GET_IID(nsIDOMAttr), (void **)aReturn); @@ -309,21 +344,175 @@ nsDOMAttributeMap::GetNamedItemNS(const nsString& aNamespaceURI, const nsString& aLocalName, nsIDOMNode** aReturn) { - return NS_ERROR_NOT_IMPLEMENTED; + NS_ENSURE_ARG_POINTER(aReturn); + *aReturn = nsnull; + + nsresult rv = NS_OK; + if (mContent) { + nsCOMPtr nameAtom(dont_AddRef(NS_NewAtom(aLocalName))); + PRInt32 nameSpaceID = kNameSpaceID_None; + nsCOMPtr prefix; + + nsCOMPtr ni; + mContent->GetNodeInfo(*getter_AddRefs(ni)); + NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE); + + nsCOMPtr nimgr; + ni->GetNodeInfoManager(*getter_AddRefs(nimgr)); + NS_ENSURE_TRUE(nimgr, NS_ERROR_FAILURE); + + if (aNamespaceURI.Length()) { + nsCOMPtr nsmgr; + nimgr->GetNamespaceManager(*getter_AddRefs(nsmgr)); + NS_ENSURE_TRUE(nsmgr, NS_ERROR_FAILURE); + + nsmgr->GetNameSpaceID(aNamespaceURI, nameSpaceID); + + if (nameSpaceID == kNameSpaceID_Unknown) + return NS_OK; + } + + nsresult attrResult; + nsAutoString value; + + attrResult = mContent->GetAttribute(nameSpaceID, nameAtom, + *getter_AddRefs(prefix), value); + + if (NS_CONTENT_ATTR_NOT_THERE != attrResult && NS_SUCCEEDED(attrResult)) { + nimgr->GetNodeInfo(nameAtom, prefix, nameSpaceID, *getter_AddRefs(ni)); + NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE); + + nsDOMAttribute* domAttribute; + domAttribute = new nsDOMAttribute(mContent, ni, value); + NS_ENSURE_TRUE(domAttribute, NS_ERROR_OUT_OF_MEMORY); + + rv = domAttribute->QueryInterface(NS_GET_IID(nsIDOMAttr), + (void **)aReturn); + } + } + + return rv; } nsresult nsDOMAttributeMap::SetNamedItemNS(nsIDOMNode* aArg, nsIDOMNode** aReturn) { - return NS_ERROR_NOT_IMPLEMENTED; + NS_ENSURE_ARG_POINTER(aReturn); + + nsresult rv = NS_OK; + *aReturn = nsnull; + + if (mContent) { + nsCOMPtr attribute(do_QueryInterface(aArg)); + + if (!attribute) { + return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR; + } + + nsAutoString name, nsURI, value; + nsCOMPtr nameAtom; + PRInt32 nameSpaceID; + + attribute->GetName(name); + attribute->GetNamespaceURI(nsURI); + + nsCOMPtr ni; + mContent->GetNodeInfo(*getter_AddRefs(ni)); + NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE); + + nsCOMPtr nimgr; + ni->GetNodeInfoManager(*getter_AddRefs(nimgr)); + NS_ENSURE_TRUE(nimgr, NS_ERROR_FAILURE); + + nimgr->GetNodeInfo(name, nsURI, *getter_AddRefs(ni)); + NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE); + + ni->GetNameAtom(*getter_AddRefs(nameAtom)); + ni->GetNamespaceID(nameSpaceID); + + nsresult attrResult = mContent->GetAttribute(nameSpaceID, nameAtom, value); + + if (NS_CONTENT_ATTR_NOT_THERE != attrResult && NS_SUCCEEDED(attrResult)) { + nsDOMAttribute* domAttribute; + // We pass a null content here since the attr node we return isn't + // tied to this content anymore. + domAttribute = new nsDOMAttribute(nsnull, ni, value); + if (!domAttribute) { + return NS_ERROR_OUT_OF_MEMORY; + } + + rv = domAttribute->QueryInterface(NS_GET_IID(nsIDOMAttr), + (void **)aReturn); + } + + attribute->GetValue(value); + + rv = mContent->SetAttribute(ni, value, PR_TRUE); + } + + return rv; } nsresult nsDOMAttributeMap::RemoveNamedItemNS(const nsString& aNamespaceURI, - const nsString&aLocalName, + const nsString& aLocalName, nsIDOMNode** aReturn) { - return NS_ERROR_NOT_IMPLEMENTED; + NS_ENSURE_ARG_POINTER(aReturn); + *aReturn = nsnull; + + nsresult rv = NS_OK; + + if (mContent) { + nsCOMPtr nameAtom(dont_AddRef(NS_NewAtom(aLocalName))); + PRInt32 nameSpaceID = kNameSpaceID_None; + nsCOMPtr attribute; + nsCOMPtr prefix; + + nsCOMPtr ni; + mContent->GetNodeInfo(*getter_AddRefs(ni)); + NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE); + + nsCOMPtr nimgr; + ni->GetNodeInfoManager(*getter_AddRefs(nimgr)); + NS_ENSURE_TRUE(nimgr, NS_ERROR_FAILURE); + + if (aNamespaceURI.Length()) { + nsCOMPtr nsmgr; + nimgr->GetNamespaceManager(*getter_AddRefs(nsmgr)); + NS_ENSURE_TRUE(nsmgr, NS_ERROR_FAILURE); + + nsmgr->GetNameSpaceID(aNamespaceURI, nameSpaceID); + + if (nameSpaceID == kNameSpaceID_Unknown) + return NS_ERROR_DOM_NOT_FOUND_ERR; + } + + nsresult attrResult; + nsAutoString value; + attrResult = mContent->GetAttribute(nameSpaceID, nameAtom, + *getter_AddRefs(prefix), value); + + if (NS_CONTENT_ATTR_NOT_THERE != attrResult && NS_SUCCEEDED(attrResult)) { + nimgr->GetNodeInfo(nameAtom, prefix, nameSpaceID, *getter_AddRefs(ni)); + NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE); + + nsDOMAttribute* domAttribute; + domAttribute = new nsDOMAttribute(nsnull, ni, value); + if (!domAttribute) { + return NS_ERROR_OUT_OF_MEMORY; + } + + rv = domAttribute->QueryInterface(NS_GET_IID(nsIDOMAttr), + (void **)aReturn); + } else { + return NS_ERROR_DOM_NOT_FOUND_ERR; + } + + rv = mContent->UnsetAttribute(nameSpaceID, nameAtom, PR_TRUE); + } + + return rv; } diff --git a/layout/base/src/nsDOMAttributeMap.h b/layout/base/src/nsDOMAttributeMap.h index 5220ad605b2..720a925d4e0 100644 --- a/layout/base/src/nsDOMAttributeMap.h +++ b/layout/base/src/nsDOMAttributeMap.h @@ -63,15 +63,6 @@ public: PRUint32* aResult); #endif -protected: - nsresult GetNamedItemCommon(const nsString& aAttrName, - PRInt32 aNameSpaceID, - nsIAtom* aNameAtom, - nsIDOMNode** aAttribute); - void GetNormalizedName(PRInt32 aNameSpaceID, - nsIAtom* aNameAtom, - nsString& aAttrName); - private: nsIContent* mContent; void* mScriptObject; diff --git a/layout/base/src/nsDocument.cpp b/layout/base/src/nsDocument.cpp index f637c4a4efb..1d5542f03f7 100644 --- a/layout/base/src/nsDocument.cpp +++ b/layout/base/src/nsDocument.cpp @@ -2146,14 +2146,19 @@ NS_IMETHODIMP nsDocument::CreateAttribute(const nsString& aName, nsIDOMAttr** aReturn) { + NS_ENSURE_ARG_POINTER(aReturn); + NS_ENSURE_TRUE(mNodeInfoManager, NS_ERROR_NOT_INITIALIZED); + nsAutoString value; nsDOMAttribute* attribute; - - value.Truncate(); - attribute = new nsDOMAttribute(nsnull, aName, value); - if (nsnull == attribute) { - return NS_ERROR_OUT_OF_MEMORY; - } + + nsCOMPtr nodeInfo; + nsresult rv = mNodeInfoManager->GetNodeInfo(aName, nsnull, kNameSpaceID_None, + *getter_AddRefs(nodeInfo)); + NS_ENSURE_SUCCESS(rv, rv); + + attribute = new nsDOMAttribute(nsnull, nodeInfo, value); + NS_ENSURE_TRUE(attribute, NS_ERROR_OUT_OF_MEMORY); return attribute->QueryInterface(NS_GET_IID(nsIDOMAttr), (void**)aReturn); } diff --git a/layout/base/src/nsDocumentFragment.cpp b/layout/base/src/nsDocumentFragment.cpp index 185dea1d765..e79c01b14b6 100644 --- a/layout/base/src/nsDocumentFragment.cpp +++ b/layout/base/src/nsDocumentFragment.cpp @@ -425,7 +425,7 @@ nsDocumentFragment::CloneNode(PRBool aDeep, nsIDOMNode** aReturn) NS_IMETHODIMP nsDocumentFragment::Normalize() { - NS_NOTYETIMPLEMENTED("write me!"); + // Nothing to do here yet return NS_OK; } diff --git a/layout/base/src/nsGenericDOMDataNode.cpp b/layout/base/src/nsGenericDOMDataNode.cpp index b65a886777c..8db9e3e7b9a 100644 --- a/layout/base/src/nsGenericDOMDataNode.cpp +++ b/layout/base/src/nsGenericDOMDataNode.cpp @@ -217,28 +217,26 @@ nsGenericDOMDataNode::GetOwnerDocument(nsIDOMDocument** aOwnerDocument) nsresult nsGenericDOMDataNode::GetNamespaceURI(nsString& aNamespaceURI) { - NS_NOTYETIMPLEMENTED("write me!"); + aNamespaceURI.Truncate(); return NS_OK; } nsresult nsGenericDOMDataNode::GetPrefix(nsString& aPrefix) { - NS_NOTYETIMPLEMENTED("write me!"); + aPrefix.Truncate(); return NS_OK; } nsresult nsGenericDOMDataNode::SetPrefix(const nsString& aPrefix) { - NS_NOTYETIMPLEMENTED("write me!"); return NS_ERROR_DOM_NAMESPACE_ERR; } nsresult nsGenericDOMDataNode::Normalize() { - NS_NOTYETIMPLEMENTED("write me!"); return NS_OK; } diff --git a/layout/base/src/nsGenericElement.cpp b/layout/base/src/nsGenericElement.cpp index ba1726b305d..57852563ad9 100644 --- a/layout/base/src/nsGenericElement.cpp +++ b/layout/base/src/nsGenericElement.cpp @@ -714,15 +714,9 @@ nsGenericElement::GetTagName(nsString& aTagName) nsresult nsGenericElement::GetAttribute(const nsString& aName, nsString& aReturn) { - nsIAtom* nameAtom; - PRInt32 nameSpaceID; + nsCOMPtr nameAtom(dont_AddRef(NS_NewAtom(aName))); - mContent->ParseAttributeString(aName, nameAtom, nameSpaceID); - if (kNameSpaceID_Unknown == nameSpaceID) { - nameSpaceID = kNameSpaceID_None; // ignore unknown prefix XXX is this correct? - } - mContent->GetAttribute(nameSpaceID, nameAtom, aReturn); - NS_RELEASE(nameAtom); + mContent->GetAttribute(kNameSpaceID_Unknown, nameAtom, aReturn); return NS_OK; } @@ -1071,15 +1065,10 @@ nsGenericElement::HasAttribute(const nsString& aName, PRBool* aReturn) { NS_ENSURE_ARG_POINTER(aReturn); - nsCOMPtr name; - PRInt32 nsid; - - nsresult rv = mContent->ParseAttributeString(aName, *getter_AddRefs(name), - nsid); - NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr name(dont_AddRef(NS_NewAtom(aName))); nsAutoString tmp; - rv = mContent->GetAttribute(nsid, name, tmp); + nsresult rv = mContent->GetAttribute(kNameSpaceID_Unknown, name, tmp); *aReturn = rv == NS_CONTENT_ATTR_NOT_THERE ? PR_FALSE : PR_TRUE; @@ -2601,70 +2590,17 @@ nsGenericContainerElement::SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, const nsString& aValue, PRBool aNotify) { - NS_ASSERTION(kNameSpaceID_Unknown != aNameSpaceID, "must have name space ID"); - if (kNameSpaceID_Unknown == aNameSpaceID) { - return NS_ERROR_ILLEGAL_VALUE; - } - NS_ASSERTION(nsnull != aName, "must have attribute name"); - if (nsnull == aName) { - return NS_ERROR_NULL_POINTER; - } + nsresult rv; + nsCOMPtr nimgr; + rv = mNodeInfo->GetNodeInfoManager(*getter_AddRefs(nimgr)); + NS_ENSURE_SUCCESS(rv, rv); - nsresult rv = NS_ERROR_OUT_OF_MEMORY; + nsCOMPtr ni; + rv = nimgr->GetNodeInfo(aName, nsnull, aNameSpaceID, + *getter_AddRefs(ni)); + NS_ENSURE_SUCCESS(rv, rv); - if (nsnull == mAttributes) { - mAttributes = new nsVoidArray(); - } - - if (aNotify && (nsnull != mDocument)) { - mDocument->BeginUpdate(); - } - - if (nsnull != mAttributes) { - nsGenericAttribute* attr; - PRInt32 index; - PRInt32 count = mAttributes->Count(); - for (index = 0; index < count; index++) { - attr = (nsGenericAttribute*)mAttributes->ElementAt(index); - if (attr->mNodeInfo->Equals(aName, aNameSpaceID)) { - attr->mValue = aValue; - rv = NS_OK; - break; - } - } - - if (index >= count) { // didn't find it - nsCOMPtr nimgr; - mNodeInfo->GetNodeInfoManager(*getter_AddRefs(nimgr)); - - nsCOMPtr ni; - rv = nimgr->GetNodeInfo(aName, nsnull, aNameSpaceID, - *getter_AddRefs(ni)); - NS_ENSURE_SUCCESS(rv, rv); - - attr = new nsGenericAttribute(ni, aValue); - if (nsnull != attr) { - mAttributes->AppendElement(attr); - rv = NS_OK; - } - } - } - - if (mDocument && NS_SUCCEEDED(rv)) { - nsCOMPtr bindingManager; - mDocument->GetBindingManager(getter_AddRefs(bindingManager)); - nsCOMPtr binding; - bindingManager->GetBinding(mContent, getter_AddRefs(binding)); - if (binding) - binding->AttributeChanged(aName, aNameSpaceID, PR_FALSE); - - if (aNotify) { - mDocument->AttributeChanged(mContent, aNameSpaceID, aName, NS_STYLE_HINT_UNKNOWN); - mDocument->EndUpdate(); - } - } - - return rv; + return SetAttribute(ni, aValue, aNotify); } nsresult @@ -2674,15 +2610,58 @@ nsGenericContainerElement::SetAttribute(nsINodeInfo* aNodeInfo, { NS_ENSURE_ARG_POINTER(aNodeInfo); - nsCOMPtr atom; - PRInt32 nsid; + nsresult rv = NS_ERROR_OUT_OF_MEMORY; - aNodeInfo->GetNameAtom(*getter_AddRefs(atom)); - aNodeInfo->GetNamespaceID(nsid); + if (!mAttributes) { + mAttributes = new nsVoidArray(); + NS_ENSURE_TRUE(mAttributes, NS_ERROR_OUT_OF_MEMORY); + } + + if (aNotify && (nsnull != mDocument)) { + mDocument->BeginUpdate(); + } + + nsGenericAttribute* attr; + PRInt32 index; + PRInt32 count = mAttributes->Count(); + for (index = 0; index < count; index++) { + attr = (nsGenericAttribute*)mAttributes->ElementAt(index); + if (attr->mNodeInfo == aNodeInfo) { + attr->mValue = aValue; + rv = NS_OK; + break; + } + } + + if (index >= count) { // didn't find it + attr = new nsGenericAttribute(aNodeInfo, aValue); + NS_ENSURE_TRUE(attr, NS_ERROR_OUT_OF_MEMORY); - // We still rely on the old way of setting the attribute. + mAttributes->AppendElement(attr); + rv = NS_OK; + } - return SetAttribute(nsid, atom, aValue, aNotify); + if (mDocument && NS_SUCCEEDED(rv)) { + nsCOMPtr name; + PRInt32 nameSpaceID; + + aNodeInfo->GetNameAtom(*getter_AddRefs(name)); + aNodeInfo->GetNamespaceID(nameSpaceID); + + nsCOMPtr bindingManager; + mDocument->GetBindingManager(getter_AddRefs(bindingManager)); + nsCOMPtr binding; + bindingManager->GetBinding(mContent, getter_AddRefs(binding)); + if (binding) + binding->AttributeChanged(name, nameSpaceID, PR_FALSE); + + if (aNotify) { + mDocument->AttributeChanged(mContent, nameSpaceID, name, NS_STYLE_HINT_UNKNOWN); + mDocument->EndUpdate(); + } + } + + return rv; } nsresult @@ -2710,7 +2689,7 @@ nsGenericContainerElement::GetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, PRInt32 index; for (index = 0; index < count; index++) { const nsGenericAttribute* attr = (const nsGenericAttribute*)mAttributes->ElementAt(index); - if ((attr->mNodeInfo->NamespaceEquals(kNameSpaceID_Unknown) || + if ((aNameSpaceID == kNameSpaceID_Unknown || attr->mNodeInfo->NamespaceEquals(aNameSpaceID)) && (attr->mNodeInfo->Equals(aName))) { attr->mNodeInfo->GetPrefixAtom(aPrefix); @@ -2754,7 +2733,7 @@ nsGenericContainerElement::UnsetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, PRBool found = PR_FALSE; for (index = 0; index < count; index++) { nsGenericAttribute* attr = (nsGenericAttribute*)mAttributes->ElementAt(index); - if ((attr->mNodeInfo->NamespaceEquals(kNameSpaceID_Unknown) || + if ((aNameSpaceID == kNameSpaceID_Unknown || attr->mNodeInfo->NamespaceEquals(aNameSpaceID)) && attr->mNodeInfo->Equals(aName)) { if (aNotify && (nsnull != mDocument)) { diff --git a/layout/base/src/nsNameSpaceManager.cpp b/layout/base/src/nsNameSpaceManager.cpp index 523dd9a4a9c..a3fad0a4429 100644 --- a/layout/base/src/nsNameSpaceManager.cpp +++ b/layout/base/src/nsNameSpaceManager.cpp @@ -31,7 +31,7 @@ static NS_DEFINE_IID(kINameSpaceManagerIID, NS_INAMESPACEMANAGER_IID); static NS_DEFINE_IID(kINameSpaceIID, NS_INAMESPACE_IID); -static const char kXMLNSNameSpaceURI[] = ""; +static const char kXMLNSNameSpaceURI[] = "http://www.w3.org/2000/xmlns"; static const char kXMLNameSpaceURI[] = "http://www.w3.org/XML/1998/namespace"; static const char kHTMLNameSpaceURI[] = "http://www.w3.org/TR/REC-html40"; // XXX?? "urn:w3-org-ns:HTML"?? // XXX To be removed: Bug 7834 --- diff --git a/layout/xml/content/src/nsXMLElement.cpp b/layout/xml/content/src/nsXMLElement.cpp index b590c3ac198..2010ebcd54b 100644 --- a/layout/xml/content/src/nsXMLElement.cpp +++ b/layout/xml/content/src/nsXMLElement.cpp @@ -219,8 +219,26 @@ nsXMLElement::SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, const nsString& aValue, PRBool aNotify) { - if ((kNameSpaceID_XLink == aNameSpaceID) && - (kTypeAtom == aName)) { + nsresult rv; + nsCOMPtr nimgr; + rv = mInner.mNodeInfo->GetNodeInfoManager(*getter_AddRefs(nimgr)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr ni; + rv = nimgr->GetNodeInfo(aName, nsnull, aNameSpaceID, + *getter_AddRefs(ni)); + NS_ENSURE_SUCCESS(rv, rv); + + return SetAttribute(ni, aValue, aNotify); +} + +NS_IMETHODIMP +nsXMLElement::SetAttribute(nsINodeInfo *aNodeInfo, const nsString& aValue, + PRBool aNotify) +{ + NS_ENSURE_ARG_POINTER(aNodeInfo); + + if (aNodeInfo->Equals(kTypeAtom, kNameSpaceID_XLink)) { if (aValue.EqualsAtom(kSimpleAtom, PR_FALSE)) { // NOTE: This really is a link according to the XLink spec, // we do not need to check other attributes. If there @@ -237,24 +255,7 @@ nsXMLElement::SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, // We will check for actuate="onLoad" in MaybeTriggerAutoLink } - return mInner.SetAttribute(aNameSpaceID, aName, aValue, aNotify); -} - -NS_IMETHODIMP -nsXMLElement::SetAttribute(nsINodeInfo *aNodeInfo, const nsString& aValue, - PRBool aNotify) -{ - NS_ENSURE_ARG_POINTER(aNodeInfo); - - nsCOMPtr atom; - PRInt32 nsid; - - aNodeInfo->GetNameAtom(*getter_AddRefs(atom)); - aNodeInfo->GetNamespaceID(nsid); - - // We still rely on the old way of setting the attribute. - - return SetAttribute(nsid, atom, aValue, aNotify); + return mInner.SetAttribute(aNodeInfo, aValue, aNotify); } static nsresult WebShellToPresContext(nsIWebShell *aShell, nsIPresContext **aPresContext) diff --git a/layout/xml/document/src/nsXMLContentSink.cpp b/layout/xml/document/src/nsXMLContentSink.cpp index f43cd4a3677..1bf8a01b1cb 100644 --- a/layout/xml/document/src/nsXMLContentSink.cpp +++ b/layout/xml/document/src/nsXMLContentSink.cpp @@ -560,30 +560,39 @@ nsXMLContentSink::AddAttributes(const nsIParserNode& aNode, name.Truncate(); name.Append(key); - nsIAtom* nameSpacePrefix = CutNameSpacePrefix(name); - nsIAtom* nameAtom = NS_NewAtom(name); - PRInt32 nameSpaceID = (nsnull == nameSpacePrefix) ? kNameSpaceID_None : GetNameSpaceId(nameSpacePrefix); - if (kNameSpaceID_Unknown == nameSpaceID) { - nameSpaceID = kNameSpaceID_None; // XXX is this correct? or is it a bad document? + nsCOMPtr nameSpacePrefix(dont_AddRef(CutNameSpacePrefix(name))); + nsCOMPtr nameAtom(dont_AddRef(NS_NewAtom(name))); + PRInt32 nameSpaceID; + + if (nameSpacePrefix) { + nameSpaceID = GetNameSpaceId(nameSpacePrefix); + } else { + if (nameAtom.get() == nsLayoutAtoms::xmlnsNameSpace) + nameSpaceID = kNameSpaceID_XMLNS; + else + nameSpaceID = kNameSpaceID_None; } - if ((kNameSpaceID_XMLNS == nameSpaceID) && aIsHTML) { - NS_RELEASE(nameAtom); + + if (kNameSpaceID_Unknown == nameSpaceID) { + nameSpaceID = kNameSpaceID_None; + nameAtom = dont_AddRef(NS_NewAtom(key)); + nameSpacePrefix = nsnull; + } else if ((kNameSpaceID_XMLNS == nameSpaceID) && aIsHTML) { name.InsertWithConversion("xmlns:", 0); - nameAtom = NS_NewAtom(name); + nameAtom = dont_AddRef(NS_NewAtom(name)); nameSpaceID = kNameSpaceID_HTML; // XXX this is wrong, but necessary until HTML can store other namespaces for attrs } - nsAutoString value; - if (NS_CONTENT_ATTR_NOT_THERE == - aContent->GetAttribute(nameSpaceID, nameAtom, value)) { - // Get value and remove mandatory quotes - GetAttributeValueAt(aNode, i, v); + nsCOMPtr ni; + mNodeInfoManager->GetNodeInfo(nameAtom, nameSpacePrefix, nameSpaceID, + *getter_AddRefs(ni)); + NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE); - // Add attribute to content - aContent->SetAttribute(nameSpaceID, nameAtom, v, PR_FALSE); - } - NS_RELEASE(nameAtom); - NS_IF_RELEASE(nameSpacePrefix); + // Get value and remove mandatory quotes + GetAttributeValueAt(aNode, i, v); + + // Add attribute to content + aContent->SetAttribute(ni, v, PR_FALSE); } // Give autoloading links a chance to fire