Fix for bug 326994 (XMLSerializer adds namespace declaration for non-empty prefix with empty namespace name). r/sr=bz.

This commit is contained in:
peterv%propagandism.org 2006-02-18 13:01:59 +00:00
Родитель bbc897b35a
Коммит e857af4418
2 изменённых файлов: 72 добавлений и 3 удалений

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

@ -401,6 +401,11 @@ nsXMLContentSerializer::ConfirmPrefix(nsAString& aPrefix,
// can simply push the new namespace URI as the default namespace for
// aElement.
if (!aPrefix.IsEmpty() || decl->mOwner == aElement) {
NS_ASSERTION(!aURI.IsEmpty(),
"Not allowed to add a xmlns attribute with an empty "
"namespace name unless it declares the default "
"namespace.");
GenerateNewPrefix(aPrefix);
// Now we need to validate our new prefix/uri combination; check it
// against the full namespace stack again. Note that just restarting
@ -587,6 +592,7 @@ nsXMLContentSerializer::AppendElementStart(nsIDOMElement *aElement,
count = content->GetAttrCount();
// First scan for namespace declarations, pushing each on the stack
PRUint32 skipAttr = count;
for (index = 0; index < count; index++) {
const nsAttrName* name = content->GetAttrNameAt(index);
@ -604,9 +610,23 @@ nsXMLContentSerializer::AppendElementStart(nsIDOMElement *aElement,
content->GetAttr(namespaceID, attrName, uriStr);
if (!name->GetPrefix()) {
// Default NS attribute does not have prefix (and the name is "xmlns")
PushNameSpaceDecl(EmptyString(), uriStr, aElement);
} else {
if (tagNamespaceURI.IsEmpty() && !uriStr.IsEmpty()) {
// If the element is in no namespace we need to add a xmlns
// attribute to declare that. That xmlns attribute must not have a
// prefix (see http://www.w3.org/TR/REC-xml-names/#dt-prefix), ie it
// must declare the default namespace. We just found an xmlns
// attribute that declares the default namespace to something
// non-empty. We're going to ignore this attribute, for children we
// will detect that we need to add it again and attributes aren't
// affected by the default namespace.
skipAttr = index;
}
else {
// Default NS attribute does not have prefix (and the name is "xmlns")
PushNameSpaceDecl(EmptyString(), uriStr, aElement);
}
}
else {
attrName->ToString(nameStr);
PushNameSpaceDecl(nameStr, uriStr, aElement);
}
@ -643,6 +663,10 @@ nsXMLContentSerializer::AppendElementStart(nsIDOMElement *aElement,
// XXX Unfortunately we need a namespace manager to get
// attribute URIs.
for (index = 0; index < count; index++) {
if (skipAttr == index) {
continue;
}
const nsAttrName* name = content->GetAttrNameAt(index);
PRInt32 namespaceID = name->NamespaceID();
nsIAtom* attrName = name->LocalName();

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

@ -11,6 +11,7 @@ var tests = [
test4,
test5,
test6,
test7,
null
];
@ -211,3 +212,47 @@ function test6() {
'<root xmlns="ns1"><child1 xmlns="ns2"><child2 xmlns="ns1"/>'+
'</child1></root>');
}
function test7() {
// Handle xmlns attribute declaring a default namespace on a non-namespaced
// element (bug 326994).
var doc = ParseXML('<root xmlns=""/>')
var root = doc.documentElement;
root.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns",
"http://www.w3.org/1999/xhtml");
do_check_serialize(doc);
do_check_eq(SerializeXML(doc), '<root/>');
doc = ParseXML('<root xmlns=""><child1/></root>')
root = doc.documentElement;
root.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns",
"http://www.w3.org/1999/xhtml");
do_check_serialize(doc);
do_check_eq(SerializeXML(doc), '<root><child1/></root>');
doc = ParseXML('<root xmlns="http://www.w3.org/1999/xhtml">' +
'<child1 xmlns=""><child2/></child1></root>')
root = doc.documentElement;
var child1 = root.firstChild;
child1.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns",
"http://www.w3.org/1999/xhtml");
do_check_serialize(doc);
do_check_eq(SerializeXML(doc),
'<root xmlns="http://www.w3.org/1999/xhtml"><child1 xmlns="">' +
'<child2/></child1></root>');
doc = ParseXML('<root xmlns="http://www.w3.org/1999/xhtml">' +
'<child1 xmlns="">' +
'<child2 xmlns="http://www.w3.org/1999/xhtml"/>' +
'</child1></root>')
root = doc.documentElement;
child1 = root.firstChild;
var child2 = child1.firstChild;
child1.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns",
"http://www.w3.org/1999/xhtml");
child2.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", "");
do_check_serialize(doc);
do_check_eq(SerializeXML(doc),
'<root xmlns="http://www.w3.org/1999/xhtml"><child1 xmlns="">' +
'<a0:child2 xmlns:a0="http://www.w3.org/1999/xhtml" xmlns=""/></child1></root>');
}