Bug 1527540 [wpt PR 15343] - domparsing: Fix an issue that XMLSerializer generates new prefix for an attribute with an existing namespace, a=testonly
authorKent Tamura <tkent@chromium.org>
Tue, 05 Mar 2019 11:11:22 +0000
changeset 464516 2e35ac1f3c2141c3986777b67b155216346bb028
parent 464515 5ed7c1d98107bfd6ad021d706e1b09c3a3b4ac82
child 464517 41177907128bdc7babb664a503c90d36fc842f0d
push id35717
push useraciure@mozilla.com
push dateSun, 17 Mar 2019 09:45:26 +0000
treeherdermozilla-central@e0861be8d6c0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstestonly
bugs1527540, 15343, 906807, 1445033, 631573
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1527540 [wpt PR 15343] - domparsing: Fix an issue that XMLSerializer generates new prefix for an attribute with an existing namespace, a=testonly Automatic update from web-platform-tests domparsing: Fix an issue that XMLSerializer generates new prefix for an attribute with an existing namespace Add an implementation of "retrieving a preferred prefix string" [1], and apply it to attribute serialization. As the specification defines, this CL introduces another map [2] like: namespace URI => [older prefix, ..., newer prefix] in order to retrieve most-recently-declared prefix. When we search the map for a prefix, we check availability of the prefix by the existing prefix-namespace map. There are two failing test cases in XMLSerializer-serializeToString.html. They follow the specification. * The first failing one: An non-well-formed XML is produced if we follow the specification. Chrome's new behavior matches to Firefox. Safari also produces a bad XML. * The second failing one: Firefox, Safari, and Chrome without this CL preserve prefix in such case. This CL keeps the interoperable behavior. [1] https://w3c.github.io/DOM-Parsing/#dfn-retrieving-a-preferred-prefix-string [2] https://w3c.github.io/DOM-Parsing/#dfn-namespace-prefix-map Bug: 906807 Change-Id: Idaea590ba19c9c21acbaf456ea91ce550c74db5a Reviewed-on: https://chromium-review.googlesource.com/c/1445033 Commit-Queue: Kent Tamura <tkent@chromium.org> Reviewed-by: Yoshifumi Inoue <yosin@chromium.org> Auto-Submit: Kent Tamura <tkent@chromium.org> Cr-Commit-Position: refs/heads/master@{#631573} -- wpt-commits: 2647e1e8f6995d12f44edbf0b4fce752e5cb7ec5 wpt-pr: 15343
testing/web-platform/tests/domparsing/XMLSerializer-serializeToString.html
--- a/testing/web-platform/tests/domparsing/XMLSerializer-serializeToString.html
+++ b/testing/web-platform/tests/domparsing/XMLSerializer-serializeToString.html
@@ -10,16 +10,25 @@
     <h1>domparsing_XMLSerializer_serializeToString</h1>
   <script>
 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 serializer = new XMLSerializer();
   var root = createXmlDoc().documentElement;
   var xmlString = serializer.serializeToString(root);
   assert_equals(xmlString, '<root><child1>value1</child1></root>');
 }, 'check XMLSerializer.serializeToString method could parsing xmldoc to string');
 
 test(function() {
@@ -36,16 +45,68 @@ test(function() {
 test(function() {
   var input = '<root xmlns="urn:bar"><outer xmlns=""><inner>value1</inner></outer></root>';
   var root = (new DOMParser()).parseFromString(input, 'text/xml').documentElement;
   var xmlString = (new XMLSerializer()).serializeToString(root);
   assert_equals(xmlString, '<root xmlns="urn:bar"><outer xmlns=""><inner>value1</inner></outer></root>');
 }, 'Check if there is no redundant empty namespace declaration.');
 
 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');
+
+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>');
+  // Maybe this is a specification error.
+}, '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.');
+
+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 serializer = new XMLSerializer();
   var parser = new DOMParser();
   var root = parser.parseFromString('<root />', 'text/xml').documentElement;
   root.setAttribute('attr', '\t');
   assert_in_array(serializer.serializeToString(root), [
     '<root attr="&#9;"/>', '<root attr="&#x9;"/>']);
   root.setAttribute('attr', '\n');
   assert_in_array(serializer.serializeToString(root), [