<!DOCTYPE html> <title>innerHTML in HTML</title> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <div id="log"></div> <!-- test elments. Each has an expected innerHTML and outerHTML in an array in the <script>--> <div id="test" style="display:none"> <span></span> <span><a></a></span> <span><a b=c></a></span> <span><a b='c'></a></span> <span><a b='&'></a></span> <span><a b=' '></a></span> <span><a b='"'></a></span> <span><a b="<"></a></span> <span><a b=">"></a></span> <span><svg xlink:href="a"></svg></span> <span><svg xmlns:svg="test"></svg></span> <span>a</span> <span>&</span> <span> </span> <span><</span> <span>></span> <span>"</span> <span><style><&></style></span> <span><script type="test"><&></script></span> <span><xmp><&></xmp></span> <span><iframe><&></iframe></span> <span><noembed><&></noembed></span> <span><noframes><&></noframes></span> <span><noscript><&></noscript></span> <span><!--data--></span> <span><a><b><c></c></b><d>e</d><f><g>h</g></f></a></span> <span b=c></span> </div> <!-- TODO: template element --> <script> var test_data = document.getElementById("test").getElementsByTagName("span"); var expected = [ ["", "<span></span>"], ["<a></a>", "<span><a></a></span>"], ["<a b=\"c\"></a>", "<span><a b=\"c\"></a></span>"], ["<a b=\"c\"></a>", "<span><a b=\"c\"></a></span>"], ["<a b=\"&\"></a>", "<span><a b=\"&\"></a></span>"], ["<a b=\" \"></a>", "<span><a b=\" \"></a></span>"], ["<a b=\""\"></a>", "<span><a b=\""\"></a></span>"], ["<a b=\"<\"></a>", "<span><a b=\"<\"></a></span>"], ["<a b=\">\"></a>", "<span><a b=\">\"></a></span>"], ["<svg xlink:href=\"a\"></svg>", "<span><svg xlink:href=\"a\"></svg></span>"], ["<svg xmlns:svg=\"test\"></svg>", "<span><svg xmlns:svg=\"test\"></svg></span>"], ["a", "<span>a</span>"], ["&", "<span>&</span>"], [" ", "<span> </span>"], ["<", "<span><</span>"], [">", "<span>></span>"], ["\"", "<span>\"</span>"], ["<style><&></style>", "<span><style><&></style></span>"], ["<script type=\"test\"><&><\/script>", "<span><script type=\"test\"><&><\/script></span>"], ["<xmp><&></xmp>", "<span><xmp><&></xmp></span>"], ["<iframe><&></iframe>", "<span><iframe><&></iframe></span>"], ["<noembed><&></noembed>", "<span><noembed><&></noembed></span>"], ["<noframes><&></noframes>", "<span><noframes><&></noframes></span>"], ["<noscript><&></noscript>", "<span><noscript><&></noscript></span>"], ["<!--data-->", "<span><!--data--></span>"], ["<a><b><c></c></b><d>e</d><f><g>h</g></f></a>", "<span><a><b><c></c></b><d>e</d><f><g>h</g></f></a></span>"], ["", "<span b=\"c\"></span>"] ]; var dom_tests = [ ["Attribute in the XML namespace", function() { var span = document.createElement("span"); var svg = document.createElement("svg"); svg.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:foo", "test"); span.appendChild(svg); return span; }, '<svg xml:foo="test"></svg>', '<span><svg xml:foo="test"></svg></span>'], ["Attribute in the XML namespace with the prefix not set to xml:", function() { var span = document.createElement("span"); var svg = document.createElement("svg"); svg.setAttributeNS("http://www.w3.org/XML/1998/namespace", "abc:foo", "test"); span.appendChild(svg); return span; }, '<svg xml:foo="test"></svg>', '<span><svg xml:foo="test"></svg></span>'], ["Non-'xmlns' attribute in the xmlns namespace", function() { var span = document.createElement("span"); var svg = document.createElement("svg"); svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:foo", "test") span.appendChild(svg); return span; }, '<svg xmlns:foo="test"></svg>', '<span><svg xmlns:foo="test"></svg></span>'], ["'xmlns' attribute in the xmlns namespace", function() { var span = document.createElement("span"); var svg = document.createElement("svg"); svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", "test") span.appendChild(svg); return span; }, '<svg xmlns="test"></svg>', '<span><svg xmlns="test"></svg></span>'], ["Attribute in non-standard namespace", function() { var span = document.createElement("span"); var svg = document.createElement("svg"); svg.setAttributeNS("fake_ns", "abc:def", "test") span.appendChild(svg); return span; }, '<svg abc:def="test"></svg>', '<span><svg abc:def="test"></svg></span>'], ["<span> starting with U+000A", function() { var elem = document.createElement("span"); elem.appendChild(document.createTextNode("\x0A")); return elem; }, "\x0A", "<span>\x0A</span>"], //TODO: Processing instructions ] var text_elements = ["pre", "textarea", "listing"]; var text_tests = [ ["<%text> context starting with U+000A", function(elem) { elem.appendChild(document.createTextNode("\x0A")); return elem; }, "\x0A", "<%text>\x0A</%text>"], ["<%text> context not starting with U+000A", function(elem) { elem.appendChild(document.createTextNode("a\x0A")); return elem; }, "a\x0A", "<%text>a\x0A</%text>"], ["<%text> non-context starting with U+000A", function(elem) { var span = document.createElement("span"); elem.appendChild(document.createTextNode("\x0A")); span.appendChild(elem); return span; }, "<%text>\x0A</%text>", "<span><%text>\x0A</%text></span>"], ["<%text> non-context not starting with U+000A", function(elem) { var span = document.createElement("span"); elem.appendChild(document.createTextNode("a\x0A")); span.appendChild(elem); return span; }, "<%text>a\x0A</%text>", "<span><%text>a\x0A</%text></span>"], ] var void_elements = [ "area", "base", "basefont", "bgsound", "br", "col", "embed", "frame", "hr", "img", "input", "keygen", "link", "menuitem", "meta", "param", "source", "track", "wbr" ]; var void_tests = [ ["Void context node", function (void_elem) { return void_elem; }, "", "<%void>" ], ["void as first child with following siblings", function (void_elem) { var span = document.createElement("span"); span.appendChild(void_elem); span.appendChild(document.createElement("a")).appendChild(document.createTextNode("test")); span.appendChild(document.createElement("b")) return span }, "<%void><a>test</a><b></b>", "<span><%void><a>test</a><b></b></span>" ], ["void as second child with following siblings", function (void_elem) { var span = document.createElement("span"); span.appendChild(document.createElement("a")).appendChild(document.createTextNode("test")); span.appendChild(void_elem); span.appendChild(document.createElement("b")) return span; }, "<a>test</a><%void><b></b>", "<span><a>test</a><%void><b></b></span>" ], ["void as last child with preceding siblings", function (void_elem) { var span = document.createElement("span"); span.appendChild(document.createElement("a")).appendChild(document.createTextNode("test")); span.appendChild(document.createElement("b")) span.appendChild(void_elem); return span; }, "<a>test</a><b></b><%void>", "<span><a>test</a><b></b><%void></span>" ], ] function cross_map(a1, a2, f) { var rv = []; a1.forEach(function(a1_elem) { a2.forEach(function(a2_elem) { rv.push(f(a1_elem, a2_elem)); }) }); return rv; } function innerHTML_test(func, elem, expected) { assert_equals(func(elem).innerHTML, expected); } function outerHTML_test(func, elem, expected) { assert_equals(func(elem).outerHTML, expected); } function make_void(name) { var rv = document.createElement(name); rv.appendChild(document.createElement("a")).appendChild(document.createComment("abc")) rv.appendChild(document.createElement("b")). appendChild(document.createElement("c")). appendChild(document.createTextNode("abc")) return rv; } function make_text(name) { return document.createElement(name); } generate_tests(innerHTML_test, expected.map(function(item, i) { return ["innerHTML " + i + " " + expected[i][0], function() {return test_data[i]}, null, item[0]]; })) generate_tests(outerHTML_test, expected.map(function(item, i) { return ["outerHTML " + i + " " + expected[i][1], function() {return test_data[i]}, null, item[1]]; })) generate_tests(innerHTML_test, dom_tests.map(function(item) { return ["innerHTML " + item[0], item[1], null, item[2]]; })) generate_tests(outerHTML_test, dom_tests.map(function(item) { return ["outerHTML " + item[0], item[1], null, item[3]]; })) generate_tests(innerHTML_test, cross_map(text_tests, text_elements, function(test_data, elem_name) { var rv = ["innerHTML " + test_data[0].replace(/%text/g, elem_name), test_data[1], document.createElement(elem_name), test_data[2].replace(/%text/g, elem_name)]; return rv; })) generate_tests(outerHTML_test, cross_map(text_tests, text_elements, function(test_data, elem_name) { var rv = ["outerHTML " + test_data[0].replace(/%text/g, elem_name), test_data[1], document.createElement(elem_name), test_data[3].replace(/%text/g, elem_name)]; return rv; })) generate_tests(innerHTML_test, cross_map(void_tests, void_elements, function(test_data, elem_name) { var rv = ["innerHTML " + test_data[0] + " " + elem_name, test_data[1], make_void(elem_name), test_data[2].replace(/%void/g, elem_name)]; return rv; })) generate_tests(outerHTML_test, cross_map(void_tests, void_elements, function(test_data, elem_name) { var rv = ["outerHTML " + test_data[0] + " " + elem_name, test_data[1], make_void(elem_name), test_data[3].replace(/%void/g, elem_name)]; return rv; })) </script>