outertext-setter.html (7706B)
1 <!DOCTYPE html> 2 <title>outerText setter test</title> 3 <script src="/resources/testharness.js"></script> 4 <script src="/resources/testharnessreport.js"></script> 5 6 <ul> 7 <li>A <span id="testReplacePrevious">B</span></li> 8 <li><span id="testReplaceFollowing">A</span> B</li> 9 <li>A <span id="testReplaceBoth">B</span> C</li> 10 <li><span id="testRemove">Testing</span> removing node using outerText.</li> 11 <li><span id="testNewlines">Replace this child with lots of newlines</span></li> 12 </ul> 13 14 <div id="container"></div> 15 16 <script> 17 "use strict"; 18 19 test(() => { 20 const node = document.getElementById("testReplacePrevious"); 21 const parent = node.parentNode; 22 23 node.outerText = "Replaced"; 24 25 assert_equals(parent.innerHTML, "A Replaced"); 26 assert_equals(parent.childNodes.length, 1, "It got merged with the previous text node"); 27 }, "Replacing a node and merging with the previous text node"); 28 29 test(() => { 30 const node = document.getElementById("testReplaceFollowing"); 31 const parent = node.parentNode; 32 33 node.outerText = "Replaced"; 34 35 assert_equals(parent.innerHTML, "Replaced B"); 36 assert_equals(parent.childNodes.length, 1, "It got merged with the following text node"); 37 }, "Replacing a node and merging with the following text node"); 38 39 test(() => { 40 const node = document.getElementById("testReplaceBoth"); 41 const parent = node.parentNode; 42 43 node.outerText = "Replaced"; 44 45 assert_equals(parent.innerHTML, "A Replaced C"); 46 assert_equals(parent.childNodes.length, 1, "It got merged with the previous and following text node"); 47 }, "Replacing a node and merging with the previous and following text node"); 48 49 test(t => { 50 const container = document.getElementById("container"); 51 t.add_cleanup(() => { container.textContent = ""; }); 52 53 container.append("A", "B", document.createElement("span"), "D", "E"); 54 assert_equals(container.childNodes.length, 5, "Precondition check: five separate nodes"); 55 56 const node = container.childNodes[2]; 57 node.outerText = "Replaced"; 58 59 assert_equals(container.innerHTML, "ABReplacedDE"); 60 assert_equals(container.childNodes.length, 3, "It got merged with the previous and following text node"); 61 assert_equals(container.childNodes[0].data, "A"); 62 assert_equals(container.childNodes[1].data, "BReplacedD"); 63 assert_equals(container.childNodes[2].data, "E"); 64 }, "Only merges with the previous and following text nodes, does not completely normalize"); 65 66 test(t => { 67 const container = document.getElementById("container"); 68 t.add_cleanup(() => { container.textContent = ""; }); 69 70 container.append(document.createElement("span")); 71 const node = container.childNodes[0]; 72 node.outerText = ""; 73 74 assert_equals(container.childNodes.length, 1, "Creates text node for the empty string"); 75 assert_equals(container.childNodes[0].data, ""); 76 }, "Empty string"); 77 78 test(t => { 79 const container = document.getElementById("container"); 80 t.add_cleanup(() => { container.textContent = ""; }); 81 82 container.append("1", "2", document.createElement("span"), "3", "4"); 83 const node = container.childNodes[2]; 84 node.outerText = ""; 85 86 assert_equals(container.childNodes.length, 3, "It got merged with the previous and following text node"); 87 assert_equals(container.childNodes[0].data, "1"); 88 assert_equals(container.childNodes[1].data, "23"); 89 assert_equals(container.childNodes[2].data, "4"); 90 }, "Empty string with surrounding text nodes"); 91 92 test(t => { 93 const node = document.getElementById("testNewlines"); 94 const parent = node.parentNode; 95 96 node.outerText = "\n\r\n\r"; 97 98 assert_equals(parent.innerHTML, "<br><br><br>"); 99 assert_equals(parent.childNodes.length, 3); 100 assert_equals(parent.childNodes[0].localName, "br", "node 1"); 101 assert_equals(parent.childNodes[1].localName, "br", "node 2"); 102 assert_equals(parent.childNodes[2].localName, "br", "node 3"); 103 }, "Setting outerText to a bunch of newlines creates a bunch of <br>s with no text nodes"); 104 105 test(() => { 106 const node = document.getElementById("testRemove"); 107 const parent = node.parentNode; 108 109 node.outerText = ""; 110 111 assert_equals(parent.innerHTML, " removing node using outerText."); 112 }, "Removing a node"); 113 114 test(() => { 115 const node = document.createElement("span"); 116 117 assert_throws_dom("NoModificationAllowedError", () => { node.outerText = ""; }); 118 }, "Detached node"); 119 120 testText("<div>", "abc", "abc", "Simplest possible test"); 121 testHTML("<div>", "abc\ndef", "abc<br>def", "Newlines convert to <br> in non-white-space:pre elements"); 122 testHTML("<pre>", "abc\ndef", "abc<br>def", "Newlines convert to <br> in <pre> element"); 123 testHTML("<textarea>", "abc\ndef", "abc<br>def", "Newlines convert to <br> in <textarea> element"); 124 testHTML("<div style='white-space:pre'>", "abc\ndef", "abc<br>def", "Newlines convert to <br> in white-space:pre element"); 125 testHTML("<div>", "abc\rdef", "abc<br>def", "CRs convert to <br> in non-white-space:pre elements"); 126 testHTML("<pre>", "abc\rdef", "abc<br>def", "CRs convert to <br> in <pre> element"); 127 testHTML("<div>", "abc\r\ndef", "abc<br>def", "Newline/CR pair converts to <br> in non-white-space:pre element"); 128 testHTML("<div>", "abc\n\ndef", "abc<br><br>def", "Newline/newline pair converts to two <br>s in non-white-space:pre element"); 129 testHTML("<div>", "abc\r\rdef", "abc<br><br>def", "CR/CR pair converts to two <br>s in non-white-space:pre element"); 130 testHTML("<div style='white-space:pre'>", "abc\rdef", "abc<br>def", "CRs convert to <br> in white-space:pre element"); 131 testText("<div>", "abc<def", "abc<def", "< preserved"); 132 testText("<div>", "abc>def", "abc>def", "> preserved"); 133 testText("<div>", "abc&", "abc&", "& preserved"); 134 testText("<div>", "abc\"def", "abc\"def", "\" preserved"); 135 testText("<div>", "abc\'def", "abc\'def", "\' preserved"); 136 testHTML("<svg>", "abc", "<svg></svg>", "outerText not supported on SVG elements"); 137 testHTML("<math>", "abc", "<math></math>", "outerText not supported on MathML elements"); 138 testText("<div>", "abc\0def", "abc\0def", "Null characters preserved"); 139 testText("<div>", "abc\tdef", "abc\tdef", "Tabs preserved"); 140 testText("<div>", " abc", " abc", "Leading whitespace preserved"); 141 testText("<div>", "abc ", "abc ", "Trailing whitespace preserved"); 142 testText("<div>", "abc def", "abc def", "Whitespace not compressed"); 143 testText("<div>abc\n\n", "abc", "abc", "Existing text deleted"); 144 testText("<div><br>", "abc", "abc", "Existing <br> deleted"); 145 testHTML("<div>", "", "", "Assigning the empty string"); 146 testHTML("<div>", null, "", "Assigning null"); 147 testHTML("<div>", undefined, "undefined", "Assigning undefined"); 148 testHTML("<div>", "\rabc", "<br>abc", "Start with CR"); 149 testHTML("<div>", "\nabc", "<br>abc", "Start with LF"); 150 testHTML("<div>", "\r\nabc", "<br>abc", "Start with CRLF"); 151 testHTML("<div>", "abc\r", "abc<br>", "End with CR"); 152 testHTML("<div>", "abc\n", "abc<br>", "End with LF"); 153 testHTML("<div>", "abc\r\n", "abc<br>", "End with CRLF"); 154 155 function testText(startingHTML, outerText, expected, description) { 156 test(t => { 157 const container = document.getElementById("container"); 158 t.add_cleanup(() => { container.textContent = ""; }); 159 160 container.innerHTML = startingHTML; 161 const elementToReplace = container.firstElementChild; 162 163 elementToReplace.outerText = outerText; 164 assert_equals(container.textContent, expected); 165 }, description); 166 } 167 168 function testHTML(startingHTML, outerText, expected, description) { 169 test(t => { 170 const container = document.getElementById("container"); 171 t.add_cleanup(() => { container.textContent = ""; }); 172 173 container.innerHTML = startingHTML; 174 const elementToReplace = container.firstElementChild; 175 176 elementToReplace.outerText = outerText; 177 assert_equals(container.innerHTML, expected); 178 }, description); 179 } 180 </script>