sanitizer-names.tentative.html (4112B)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <script src="/resources/testharness.js"></script> 5 <script src="/resources/testharnessreport.js"></script> 6 </head> 7 <body> 8 <script> 9 // Quick sanity tests for namespaced elements. 10 // Each test case is a duo or triplet: 11 // - a Sanitizer config string for an element. 12 // - an HTML probe string. 13 // - the expected result. (If different from the probe.) 14 const SVG_NS = "http://www.w3.org/2000/svg"; 15 const MATHML_NS = "http://www.w3.org/1998/Math/MathML"; 16 [ 17 [ "p", "<p>Hello</p>" ], 18 [ "svg", "<svg>Hello</svg>", "" ], 19 [ { name: "svg", namespace: SVG_NS }, "<svg>Hello</svg>" ], 20 [ "math", "<math>Hello</math>", "" ], 21 [ { name: "math", namespace: SVG_NS }, "<math>Hello</math>", "" ], 22 [ { name: "math", namespace: MATHML_NS }, "<math>Hello</math>" ], 23 ].forEach(([elem, probe, expected], index) => { 24 test(t => { 25 const div = document.createElement("div"); 26 div.setHTML(probe, {sanitizer: {elements: [elem]}}); 27 assert_equals(div.innerHTML, expected ?? probe); 28 }, `Namespaced elements #${index}: elements: [${JSON.stringify(elem)}]`); 29 }); 30 31 // Same for attributes: 32 const XLINK_NS = "http://www.w3.org/1999/xlink"; 33 [ 34 [ { name: "style"}, "<p style=\"bla\"></p>" ], 35 [ { name: "href"}, "<p href=\"bla\"></p>" ], 36 37 // In HTML content, the HTML parser parses "xlink:href" as an attribute 38 // named "xlink:href" in the null namespace. 39 [ { name: "xlink:href"}, "<p xlink:href=\"bla\"></p>" ], 40 [ { name: "href", namespace: XLINK_NS}, "<p xlink:href=\"bla\"></p>", "<p></p>" ], 41 [ { name: "href", namespace: XLINK_NS}, "<p href='bla'></p>", "<p></p>" ], 42 [ { name: "href"}, "<p xlink:href='bla'></p>", "<p></p>" ], 43 44 // For "foreign elements" like <svg>, the HTML parser parses "xlink:href" as 45 // an attribtue named "href" in the XLink namespace. 46 [ { name: "xlink:href"}, "<svg xlink:href=\"bla\"></svg>", "<svg></svg>" ], 47 [ { name: "href", namespace: XLINK_NS}, "<svg xlink:href=\"bla\"></svg>" ], 48 [ { name: "href", namespace: XLINK_NS}, "<svg href='bla'></svg>", "<svg></svg>" ], 49 [ { name: "href"}, "<svg xlink:href='bla'></svg>", "<svg></svg>" ], 50 ].forEach(([attr, probe, expected], index) => { 51 test(t => { 52 const options = {attributes: [attr], 53 elements: ["p", {name: "svg", namespace: SVG_NS}]}; 54 const template = document.createElement("template"); 55 template.setHTML(probe, {sanitizer: options}); 56 assert_equals(template.content.firstElementChild.outerHTML, expected ?? probe); 57 }, `Namespaced attributes #${index}: attributes: [${JSON.stringify(attr)}]`); 58 }); 59 60 // Test for namespaced attribute inside namespace element 61 test(t => { 62 const probe = `<svg><a xlink:href="bla"></a></svg>`; 63 64 const options = { 65 elements: [ 66 {name: "svg", namespace: SVG_NS}, 67 {name: "a", namespace: SVG_NS, attributes: [ 68 { name: "href", namespace: XLINK_NS } 69 ]} 70 ]}; 71 const template = document.createElement("template"); 72 template.setHTML(probe, {sanitizer: options}); 73 assert_equals(template.innerHTML, probe); 74 }, "Namespaced attribute xlink:href inside SVG tree"); 75 76 // Names are case-senstive. Most element and attribute names are 77 // lower-cased, but "foreign content" like SVG and MathML have some 78 // mixed-cased names. Check this is supported. 79 [ 80 [ "feBlend", "<feBlend></feBlend>" ], 81 [ "feColorMatrix", "<feColorMatrix></feColorMatrix>" ], 82 [ "textPath", "<textPath></textPath>" ], 83 ].forEach(([elem, probe], index) => { 84 const sanitize = (elem, probe) => { 85 const options = {elements: [ 86 { name: "svg", namespace: SVG_NS }, 87 { name: elem, namespace: SVG_NS } 88 ]}; 89 const template = document.createElement("template"); 90 template.setHTML(`<svg>${probe}</svg>`, {sanitizer: options}); 91 return template.content.firstElementChild.innerHTML; 92 }; 93 test(t => { 94 assert_equals(sanitize(elem, probe), probe); 95 }, `Mixed-case element names #${index}: "svg:${elem}"`); 96 }); 97 </script> 98 </body> 99 </html>