mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-05-15 23:52:57 +00:00
While the code that did this referred to the HTML spec, other browsers appear not to have this behavior when parsing XML, and it breaks a WPT subtest. This change does not appear to break any tests, and fixes 1 WPT subtest.
237 lines
11 KiB
HTML
237 lines
11 KiB
HTML
<!DOCTYPE HTML>
|
|
<meta charset=utf-8>
|
|
<html>
|
|
<head>
|
|
<title>domparsing Test: XMLSerializer.serializeToString</title>
|
|
<script src="../resources/testharness.js"></script>
|
|
<script src="../resources/testharnessreport.js"></script>
|
|
</head>
|
|
<body>
|
|
<h1>domparsing_XMLSerializer_serializeToString</h1>
|
|
<script>
|
|
const XMLNS_URI = 'http://www.w3.org/2000/xmlns/';
|
|
|
|
function createXmlDoc(){
|
|
var input = '<?xml version="1.0" encoding="UTF-8"?><root><child1>value1</child1></root>';
|
|
var parser = new DOMParser();
|
|
return parser.parseFromString(input, 'text/xml');
|
|
}
|
|
|
|
// Returns the root element.
|
|
function parse(xmlString) {
|
|
return (new DOMParser()).parseFromString(xmlString, 'text/xml').documentElement;
|
|
}
|
|
|
|
function serialize(node) {
|
|
return (new XMLSerializer()).serializeToString(node);
|
|
}
|
|
|
|
test(function() {
|
|
var root = createXmlDoc().documentElement;
|
|
assert_equals(serialize(root), '<root><child1>value1</child1></root>');
|
|
}, 'check XMLSerializer.serializeToString method could parsing xmldoc to string');
|
|
|
|
test(function() {
|
|
var root = parse('<html><head></head><body><div></div><span></span></body></html>');
|
|
assert_equals(serialize(root.ownerDocument), '<html><head/><body><div/><span/></body></html>');
|
|
}, 'check XMLSerializer.serializeToString method could parsing document to string');
|
|
|
|
test(function() {
|
|
var root = createXmlDoc().documentElement;
|
|
var element = root.ownerDocument.createElementNS('urn:foo', 'another');
|
|
var child1 = root.firstChild;
|
|
root.replaceChild(element, child1);
|
|
element.appendChild(child1);
|
|
assert_equals(serialize(root), '<root><another xmlns="urn:foo"><child1 xmlns="">value1</child1></another></root>');
|
|
}, 'Check if the default namespace is correctly reset.');
|
|
|
|
test(function() {
|
|
var root = parse('<root xmlns="urn:bar"><outer xmlns=""><inner>value1</inner></outer></root>');
|
|
assert_equals(serialize(root), '<root xmlns="urn:bar"><outer xmlns=""><inner>value1</inner></outer></root>');
|
|
}, 'Check if there is no redundant empty namespace declaration.');
|
|
|
|
// https://github.com/w3c/DOM-Parsing/issues/47
|
|
test(function() {
|
|
assert_equals(serialize(parse('<root><child xmlns=""/></root>')),
|
|
'<root><child/></root>');
|
|
assert_equals(serialize(parse('<root xmlns=""><child xmlns=""/></root>')),
|
|
'<root><child/></root>');
|
|
assert_equals(serialize(parse('<root xmlns="u1"><child xmlns="u1"/></root>')),
|
|
'<root xmlns="u1"><child/></root>');
|
|
}, 'Check if redundant xmlns="..." is dropped.');
|
|
|
|
test(function() {
|
|
const root = parse('<root xmlns="uri1"/>');
|
|
const child = root.ownerDocument.createElement('child');
|
|
child.setAttributeNS(XMLNS_URI, 'xmlns', 'FAIL1');
|
|
root.appendChild(child);
|
|
const child2 = root.ownerDocument.createElementNS('uri2', 'child2');
|
|
child2.setAttributeNS(XMLNS_URI, 'xmlns', 'FAIL2');
|
|
root.appendChild(child2);
|
|
const child3 = root.ownerDocument.createElementNS('uri1', 'child3');
|
|
child3.setAttributeNS(XMLNS_URI, 'xmlns', 'FAIL3');
|
|
root.appendChild(child3);
|
|
const child4 = root.ownerDocument.createElementNS('uri4', 'child4');
|
|
child4.setAttributeNS(XMLNS_URI, 'xmlns', 'uri4');
|
|
root.appendChild(child4);
|
|
const child5 = root.ownerDocument.createElement('child5');
|
|
child5.setAttributeNS(XMLNS_URI, 'xmlns', '');
|
|
root.appendChild(child5);
|
|
assert_equals(serialize(root), '<root xmlns="uri1"><child xmlns=""/><child2 xmlns="uri2"/><child3/><child4 xmlns="uri4"/><child5 xmlns=""/></root>');
|
|
}, 'Check if inconsistent xmlns="..." is dropped.');
|
|
|
|
test(function() {
|
|
let root = parse('<r xmlns:xx="uri"></r>');
|
|
root.setAttributeNS('uri', 'name', 'v');
|
|
assert_equals(serialize(root), '<r xmlns:xx="uri" xx:name="v"/>');
|
|
|
|
let root2 = parse('<r xmlns:xx="uri"><b/></r>');
|
|
let child = root2.firstChild;
|
|
child.setAttributeNS('uri', 'name', 'v');
|
|
assert_equals(serialize(root2), '<r xmlns:xx="uri"><b xx:name="v"/></r>');
|
|
|
|
let root3 = parse('<r xmlns:x0="uri" xmlns:x2="uri"><b xmlns:x1="uri"/></r>');
|
|
let child3 = root3.firstChild;
|
|
child3.setAttributeNS('uri', 'name', 'v');
|
|
assert_equals(serialize(root3),
|
|
'<r xmlns:x0="uri" xmlns:x2="uri"><b xmlns:x1="uri" x1:name="v"/></r>',
|
|
'Should choose the nearest prefix');
|
|
}, 'Check if an attribute with namespace and no prefix is serialized with the nearest-declared prefix');
|
|
|
|
// https://github.com/w3c/DOM-Parsing/issues/45
|
|
test(function() {
|
|
let root = parse('<el1 xmlns:p="u1" xmlns:q="u1"><el2 xmlns:q="u2"/></el1>');
|
|
root.firstChild.setAttributeNS('u1', 'name', 'v');
|
|
assert_equals(serialize(root),
|
|
'<el1 xmlns:p="u1" xmlns:q="u1"><el2 xmlns:q="u2" q:name="v"/></el1>');
|
|
}, 'Check if an attribute with namespace and no prefix is serialized with the nearest-declared prefix even if the prefix is assigned to another namespace.');
|
|
|
|
test(function() {
|
|
let root = parse('<r xmlns:xx="uri"></r>');
|
|
root.setAttributeNS('uri', 'p:name', 'v');
|
|
assert_equals(serialize(root), '<r xmlns:xx="uri" xx:name="v"/>');
|
|
|
|
let root2 = parse('<r xmlns:xx="uri"><b/></r>');
|
|
let child = root2.firstChild;
|
|
child.setAttributeNS('uri', 'p:name', 'value');
|
|
assert_equals(serialize(root2),
|
|
'<r xmlns:xx="uri"><b xx:name="value"/></r>');
|
|
}, 'Check if the prefix of an attribute is replaced with another existing prefix mapped to the same namespace URI.');
|
|
|
|
// https://github.com/w3c/DOM-Parsing/issues/29
|
|
test(function() {
|
|
let root = parse('<r xmlns:xx="uri"></r>');
|
|
root.setAttributeNS('uri2', 'p:name', 'value');
|
|
assert_equals(serialize(root),
|
|
'<r xmlns:xx="uri" xmlns:ns1="uri2" ns1:name="value"/>');
|
|
}, 'Check if the prefix of an attribute is NOT preserved in a case where neither its prefix nor its namespace URI is not already used.');
|
|
|
|
test(function() {
|
|
let root = parse('<r xmlns:xx="uri"></r>');
|
|
root.setAttributeNS('uri2', 'xx:name', 'value');
|
|
assert_equals(serialize(root),
|
|
'<r xmlns:xx="uri" xmlns:ns1="uri2" ns1:name="value"/>');
|
|
}, 'Check if the prefix of an attribute is replaced with a generated one in a case where the prefix is already mapped to a different namespace URI.');
|
|
|
|
test(function() {
|
|
var root = parse('<root />');
|
|
root.setAttribute('attr', '\t');
|
|
assert_in_array(serialize(root), [
|
|
'<root attr="	"/>', '<root attr="	"/>']);
|
|
root.setAttribute('attr', '\n');
|
|
assert_in_array(serialize(root), [
|
|
'<root attr="
"/>', '<root attr=" "/>']);
|
|
root.setAttribute('attr', '\r');
|
|
assert_in_array(serialize(root), [
|
|
'<root attr="
"/>', '<root attr=" "/>']);
|
|
}, 'check XMLSerializer.serializeToString escapes attribute values for roundtripping');
|
|
|
|
test(function() {
|
|
const root = (new Document()).createElement('root');
|
|
root.setAttributeNS('uri1', 'p:foobar', 'value1');
|
|
root.setAttributeNS(XMLNS_URI, 'xmlns:p', 'uri2');
|
|
assert_equals(serialize(root), '<root xmlns:ns1="uri1" ns1:foobar="value1" xmlns:p="uri2"/>');
|
|
}, 'Check if attribute serialization takes into account of following xmlns:* attributes');
|
|
|
|
test(function() {
|
|
const root = parse('<root xmlns:p="uri1"><child/></root>');
|
|
root.firstChild.setAttributeNS('uri2', 'p:foobar', 'v');
|
|
assert_equals(serialize(root), '<root xmlns:p="uri1"><child xmlns:ns1="uri2" ns1:foobar="v"/></root>');
|
|
}, 'Check if attribute serialization takes into account of the same prefix declared in an ancestor element');
|
|
|
|
test(function() {
|
|
assert_equals(serialize(parse('<root><child/></root>')), '<root><child/></root>');
|
|
assert_equals(serialize(parse('<root xmlns="u1"><p:child xmlns:p="u1"/></root>')), '<root xmlns="u1"><child xmlns:p="u1"/></root>');
|
|
}, 'Check if start tag serialization drops element prefix if the namespace is same as inherited default namespace.');
|
|
|
|
test(function() {
|
|
const root = parse('<root xmlns:p1="u1"><child xmlns:p2="u1"/></root>');
|
|
const child2 = root.ownerDocument.createElementNS('u1', 'child2');
|
|
root.firstChild.appendChild(child2);
|
|
assert_equals(serialize(root), '<root xmlns:p1="u1"><child xmlns:p2="u1"><p2:child2/></child></root>');
|
|
}, 'Check if start tag serialization finds an appropriate prefix.');
|
|
|
|
test(function() {
|
|
const root = (new Document()).createElementNS('uri1', 'p:root');
|
|
root.setAttributeNS(XMLNS_URI, 'xmlns:p', 'uri2');
|
|
assert_equals(serialize(root), '<ns1:root xmlns:ns1="uri1" xmlns:p="uri2"/>');
|
|
}, 'Check if start tag serialization takes into account of its xmlns:* attributes');
|
|
|
|
test(function() {
|
|
const root = (new Document()).createElement('root');
|
|
root.setAttributeNS(XMLNS_URI, 'xmlns:p', 'uri2');
|
|
const child = root.ownerDocument.createElementNS('uri1', 'p:child');
|
|
root.appendChild(child);
|
|
assert_equals(serialize(root), '<root xmlns:p="uri2"><p:child xmlns:p="uri1"/></root>');
|
|
}, 'Check if start tag serialization applied the original prefix even if it is declared in an ancestor element.');
|
|
|
|
// https://github.com/w3c/DOM-Parsing/issues/52
|
|
test(function() {
|
|
assert_equals(serialize(parse('<root xmlns:x="uri1"><table xmlns="uri1"></table></root>')),
|
|
'<root xmlns:x="uri1"><x:table xmlns="uri1"/></root>');
|
|
}, 'Check if start tag serialization does NOT apply the default namespace if its namespace is declared in an ancestor.');
|
|
|
|
test(function() {
|
|
const root = parse('<root><child1/><child2/></root>');
|
|
root.firstChild.setAttributeNS('uri1', 'attr1', 'value1');
|
|
root.firstChild.setAttributeNS('uri2', 'attr2', 'value2');
|
|
root.lastChild.setAttributeNS('uri3', 'attr3', 'value3');
|
|
assert_equals(serialize(root), '<root><child1 xmlns:ns1="uri1" ns1:attr1="value1" xmlns:ns2="uri2" ns2:attr2="value2"/><child2 xmlns:ns3="uri3" ns3:attr3="value3"/></root>');
|
|
}, 'Check if generated prefixes match to "ns${index}".');
|
|
|
|
// https://github.com/w3c/DOM-Parsing/issues/44
|
|
// According to 'DOM Parsing and Serialization' draft as of 2018-12-11,
|
|
// 'generate a prefix' result can conflict with an existing xmlns:ns* declaration.
|
|
test(function() {
|
|
const root = parse('<root xmlns:ns2="uri2"><child xmlns:ns1="uri1"/></root>');
|
|
root.firstChild.setAttributeNS('uri3', 'attr1', 'value1');
|
|
assert_equals(serialize(root), '<root xmlns:ns2="uri2"><child xmlns:ns1="uri1" xmlns:ns1="uri3" ns1:attr1="value1"/></root>');
|
|
}, 'Check if "ns1" is generated even if the element already has xmlns:ns1.');
|
|
|
|
test(function() {
|
|
const root = (new Document()).createElement('root');
|
|
root.setAttributeNS('http://www.w3.org/1999/xlink', 'href', 'v');
|
|
assert_equals(serialize(root), '<root xmlns:ns1="http://www.w3.org/1999/xlink" ns1:href="v"/>');
|
|
|
|
const root2 = (new Document()).createElement('root');
|
|
root2.setAttributeNS('http://www.w3.org/1999/xlink', 'xl:type', 'v');
|
|
assert_equals(serialize(root2), '<root xmlns:xl="http://www.w3.org/1999/xlink" xl:type="v"/>');
|
|
}, 'Check if no special handling for XLink namespace unlike HTML serializer.');
|
|
|
|
test(function() {
|
|
var root = new DocumentFragment;
|
|
root.append(document.createElement('div'));
|
|
root.append(document.createElement('span'));
|
|
assert_equals(serialize(root), '<div xmlns="http://www.w3.org/1999/xhtml"></div><span xmlns="http://www.w3.org/1999/xhtml"></span>');
|
|
}, 'Check if document fragment serializes.');
|
|
|
|
test(function () {
|
|
const root = document.createElement("img");
|
|
root.append(document.createElement("style"));
|
|
root.append(document.createElement("style"));
|
|
assert_equals(serialize(root), '<img xmlns=\"http://www.w3.org/1999/xhtml\"><style></style><style></style></img>');
|
|
}, 'Check children were included for void elements')
|
|
|
|
</script>
|
|
</body>
|
|
</html>
|