Bug 599590 - Attrib.value can return empty for case-sensitive attributes after calling removeAttribute, r=sicking, a=jst

--HG--
extra : rebase_source : 3c2c925ae51aca7d32bc3021cbbf1a43735d2035
This commit is contained in:
Olli Pettay 2010-10-14 17:07:20 +03:00
Родитель 6124108b99
Коммит 0ae127e88d
7 изменённых файлов: 41 добавлений и 19 удалений

Просмотреть файл

@ -46,8 +46,8 @@ class nsDOMAttributeMap;
class nsIContent; class nsIContent;
#define NS_IATTRIBUTE_IID \ #define NS_IATTRIBUTE_IID \
{ 0x9bb7e4f2, 0xf89d, 0x46ee, \ { 0x0330a680, 0x6b05, 0x453b, \
{ 0xa4, 0x62, 0x68, 0xcb, 0x0b, 0xf5, 0x71, 0x53 } } { 0x84, 0x7a, 0xb0, 0x6c, 0x9c, 0x5d, 0x08, 0x85 } }
class nsIAttribute : public nsINode class nsIAttribute : public nsINode
{ {
@ -76,13 +76,15 @@ public:
protected: protected:
#ifdef MOZILLA_INTERNAL_API #ifdef MOZILLA_INTERNAL_API
nsIAttribute(nsDOMAttributeMap *aAttrMap, already_AddRefed<nsINodeInfo> aNodeInfo) nsIAttribute(nsDOMAttributeMap *aAttrMap, already_AddRefed<nsINodeInfo> aNodeInfo,
: nsINode(aNodeInfo), mAttrMap(aAttrMap) PRBool aNsAware)
: nsINode(aNodeInfo), mAttrMap(aAttrMap), mNsAware(aNsAware)
{ {
} }
#endif //MOZILLA_INTERNAL_API #endif //MOZILLA_INTERNAL_API
nsDOMAttributeMap *mAttrMap; // WEAK nsDOMAttributeMap *mAttrMap; // WEAK
PRBool mNsAware;
}; };
NS_DEFINE_STATIC_IID_ACCESSOR(nsIAttribute, NS_IATTRIBUTE_IID) NS_DEFINE_STATIC_IID_ACCESSOR(nsIAttribute, NS_IATTRIBUTE_IID)

Просмотреть файл

@ -67,8 +67,8 @@ PRBool nsDOMAttribute::sInitialized;
nsDOMAttribute::nsDOMAttribute(nsDOMAttributeMap *aAttrMap, nsDOMAttribute::nsDOMAttribute(nsDOMAttributeMap *aAttrMap,
already_AddRefed<nsINodeInfo> aNodeInfo, already_AddRefed<nsINodeInfo> aNodeInfo,
const nsAString &aValue) const nsAString &aValue, PRBool aNsAware)
: nsIAttribute(aAttrMap, aNodeInfo), mValue(aValue), mChild(nsnull) : nsIAttribute(aAttrMap, aNodeInfo, aNsAware), mValue(aValue), mChild(nsnull)
{ {
NS_ABORT_IF_FALSE(mNodeInfo, "We must get a nodeinfo here!"); NS_ABORT_IF_FALSE(mNodeInfo, "We must get a nodeinfo here!");
@ -214,7 +214,8 @@ already_AddRefed<nsIAtom>
nsDOMAttribute::GetNameAtom(nsIContent* aContent) nsDOMAttribute::GetNameAtom(nsIContent* aContent)
{ {
nsIAtom* result = nsnull; nsIAtom* result = nsnull;
if (mNodeInfo->NamespaceID() == kNameSpaceID_None && if (!mNsAware &&
mNodeInfo->NamespaceID() == kNameSpaceID_None &&
aContent->IsInHTMLDocument() && aContent->IsInHTMLDocument() &&
aContent->IsHTML()) { aContent->IsHTML()) {
nsAutoString name; nsAutoString name;
@ -434,7 +435,7 @@ nsDOMAttribute::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
const_cast<nsDOMAttribute*>(this)->GetValue(value); const_cast<nsDOMAttribute*>(this)->GetValue(value);
nsCOMPtr<nsINodeInfo> ni = aNodeInfo; nsCOMPtr<nsINodeInfo> ni = aNodeInfo;
*aResult = new nsDOMAttribute(nsnull, ni.forget(), value); *aResult = new nsDOMAttribute(nsnull, ni.forget(), value, mNsAware);
if (!*aResult) { if (!*aResult) {
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
} }

Просмотреть файл

@ -65,7 +65,8 @@ class nsDOMAttribute : public nsIAttribute,
public: public:
nsDOMAttribute(nsDOMAttributeMap* aAttrMap, nsDOMAttribute(nsDOMAttributeMap* aAttrMap,
already_AddRefed<nsINodeInfo> aNodeInfo, already_AddRefed<nsINodeInfo> aNodeInfo,
const nsAString& aValue); const nsAString& aValue,
PRBool aNsAware);
virtual ~nsDOMAttribute(); virtual ~nsDOMAttribute();
NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTING_ISUPPORTS

Просмотреть файл

@ -181,7 +181,7 @@ nsDOMAttributeMap::RemoveAttribute(nsINodeInfo* aNodeInfo, nsIDOMNode** aReturn)
mContent->GetAttr(aNodeInfo->NamespaceID(), aNodeInfo->NameAtom(), value); mContent->GetAttr(aNodeInfo->NamespaceID(), aNodeInfo->NameAtom(), value);
nsCOMPtr<nsINodeInfo> ni = aNodeInfo; nsCOMPtr<nsINodeInfo> ni = aNodeInfo;
nsCOMPtr<nsIDOMNode> newAttr = nsCOMPtr<nsIDOMNode> newAttr =
new nsDOMAttribute(nsnull, ni.forget(), value); new nsDOMAttribute(nsnull, ni.forget(), value, PR_TRUE);
if (!newAttr) { if (!newAttr) {
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
} }
@ -201,7 +201,7 @@ nsDOMAttributeMap::RemoveAttribute(nsINodeInfo* aNodeInfo, nsIDOMNode** aReturn)
} }
nsDOMAttribute* nsDOMAttribute*
nsDOMAttributeMap::GetAttribute(nsINodeInfo* aNodeInfo) nsDOMAttributeMap::GetAttribute(nsINodeInfo* aNodeInfo, PRBool aNsAware)
{ {
NS_ASSERTION(aNodeInfo, "GetAttribute() called with aNodeInfo == nsnull!"); NS_ASSERTION(aNodeInfo, "GetAttribute() called with aNodeInfo == nsnull!");
@ -211,7 +211,7 @@ nsDOMAttributeMap::GetAttribute(nsINodeInfo* aNodeInfo)
if (!node) { if (!node) {
nsCOMPtr<nsINodeInfo> ni = aNodeInfo; nsCOMPtr<nsINodeInfo> ni = aNodeInfo;
nsRefPtr<nsDOMAttribute> newAttr = nsRefPtr<nsDOMAttribute> newAttr =
new nsDOMAttribute(this, ni.forget(), EmptyString()); new nsDOMAttribute(this, ni.forget(), EmptyString(), aNsAware);
if (newAttr && mAttributeCache.Put(attr, newAttr)) { if (newAttr && mAttributeCache.Put(attr, newAttr)) {
node = newAttr; node = newAttr;
} }
@ -229,7 +229,7 @@ nsDOMAttributeMap::GetNamedItem(const nsAString& aAttrName, nsresult *aResult)
nsCOMPtr<nsINodeInfo> ni = nsCOMPtr<nsINodeInfo> ni =
mContent->GetExistingAttrNameFromQName(aAttrName); mContent->GetExistingAttrNameFromQName(aAttrName);
if (ni) { if (ni) {
return GetAttribute(ni); return GetAttribute(ni, PR_FALSE);
} }
} }
@ -384,7 +384,7 @@ nsDOMAttributeMap::RemoveNamedItem(const nsAString& aName,
return NS_ERROR_DOM_NOT_FOUND_ERR; return NS_ERROR_DOM_NOT_FOUND_ERR;
} }
NS_ADDREF(*aReturn = GetAttribute(ni)); NS_ADDREF(*aReturn = GetAttribute(ni, PR_TRUE));
// This removes the attribute node from the attribute map. // This removes the attribute node from the attribute map.
rv = mContent->UnsetAttr(ni->NamespaceID(), ni->NameAtom(), PR_TRUE); rv = mContent->UnsetAttr(ni->NamespaceID(), ni->NameAtom(), PR_TRUE);
@ -409,7 +409,7 @@ nsDOMAttributeMap::GetItemAt(PRUint32 aIndex, nsresult *aResult)
ni = mContent->NodeInfo()->NodeInfoManager()-> ni = mContent->NodeInfo()->NodeInfoManager()->
GetNodeInfo(name->LocalName(), name->GetPrefix(), name->NamespaceID()); GetNodeInfo(name->LocalName(), name->GetPrefix(), name->NamespaceID());
if (ni) { if (ni) {
node = GetAttribute(ni); node = GetAttribute(ni, PR_TRUE);
} }
else { else {
*aResult = NS_ERROR_OUT_OF_MEMORY; *aResult = NS_ERROR_OUT_OF_MEMORY;
@ -491,7 +491,7 @@ nsDOMAttributeMap::GetNamedItemNSInternal(const nsAString& aNamespaceURI,
return RemoveAttribute(ni, aReturn); return RemoveAttribute(ni, aReturn);
} }
NS_ADDREF(*aReturn = GetAttribute(ni)); NS_ADDREF(*aReturn = GetAttribute(ni, PR_TRUE));
return NS_OK; return NS_OK;
} }

Просмотреть файл

@ -225,7 +225,7 @@ private:
nsIDOMNode** aReturn, nsIDOMNode** aReturn,
PRBool aRemove = PR_FALSE); PRBool aRemove = PR_FALSE);
nsDOMAttribute* GetAttribute(nsINodeInfo* aNodeInfo); nsDOMAttribute* GetAttribute(nsINodeInfo* aNodeInfo, PRBool aNsAware);
/** /**
* Remove an attribute, returns the removed node. * Remove an attribute, returns the removed node.

Просмотреть файл

@ -4601,7 +4601,7 @@ nsDocument::CreateAttribute(const nsAString& aName,
getter_AddRefs(nodeInfo)); getter_AddRefs(nodeInfo));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
attribute = new nsDOMAttribute(nsnull, nodeInfo.forget(), value); attribute = new nsDOMAttribute(nsnull, nodeInfo.forget(), value, PR_FALSE);
NS_ENSURE_TRUE(attribute, NS_ERROR_OUT_OF_MEMORY); NS_ENSURE_TRUE(attribute, NS_ERROR_OUT_OF_MEMORY);
return CallQueryInterface(attribute, aReturn); return CallQueryInterface(attribute, aReturn);
@ -4624,7 +4624,7 @@ nsDocument::CreateAttributeNS(const nsAString & aNamespaceURI,
nsAutoString value; nsAutoString value;
nsDOMAttribute* attribute = nsDOMAttribute* attribute =
new nsDOMAttribute(nsnull, nodeInfo.forget(), value); new nsDOMAttribute(nsnull, nodeInfo.forget(), value, PR_TRUE);
NS_ENSURE_TRUE(attribute, NS_ERROR_OUT_OF_MEMORY); NS_ENSURE_TRUE(attribute, NS_ERROR_OUT_OF_MEMORY);
return CallQueryInterface(attribute, aResult); return CallQueryInterface(attribute, aResult);

Просмотреть файл

@ -163,6 +163,24 @@ is(node.getAttributeNode('myAttrib').name, "myAttrib", "(10)");
is(node.getAttributeNode('myattrib').name, "myAttrib", "(11)"); is(node.getAttributeNode('myattrib').name, "myAttrib", "(11)");
is(attrib.name, "myAttrib", "(12)"); is(attrib.name, "myAttrib", "(12)");
var o = document.createElement("div");
o.setAttribute("myAttrib","htmlattr");
o.setAttributeNS("","myAttrib","123");
is(o.getAttributeNodeNS("","myAttrib").nodeName, "myAttrib", "nodeName should be case-sensitive.");
is(o.getAttributeNode("myAttrib").nodeName, "myattrib", "nodeName shouldn't be case-sensitive.");
is(o.getAttributeNodeNS("","myAttrib").value, "123", "Should have got the case-sensitive attribute.");
is(o.attributes.length, 2, "Should have two attributes.");
o.setAttribute("myAttrib2", "htmlattr");
o.setAttributeNS("", "myAttrib2", "123");
is(o.attributes.length, 4, "Should have four attributes.");
var an = o.attributes.removeNamedItem("myAttrib2");
is(o.attributes.length, 3, "An attribute should have been removed.");
is(an.value, "htmlattr", "The removed attribute should have been the case-insensitive attribute.");
is(o.getAttribute("myAttrib2"), null, "Element shouldn't have case-insensitive attribute anymore.");
var an2 = o.attributes.removeNamedItemNS("", "myAttrib2");
is(an2.localName, "myAttrib2", "The removed attribute should be case-sensitive.");
is(o.attributes.length, 2, "Element should have two attributes.");
</script> </script>
</pre> </pre>
</body> </body>