stream-html-unsafe.html (7509B)
1 <!DOCTYPE HTML> 2 <meta charset="utf-8" /> 3 <title>HTML partial updates - streamHTMLUnsafe</title> 4 <link rel=help href="https://github.com/WICG/declarative-partial-updates"> 5 <script src="/resources/testharness.js"></script> 6 <script src="/resources/testharnessreport.js"></script> 7 <style id="style"></style> 8 <p id="target"></p> 9 <script> 10 11 promise_test(async t => { 12 const placeholder = document.createElement("div"); 13 placeholder.innerHTML = "A"; 14 const writable = placeholder.streamHTMLUnsafe(); 15 assert_true(writable instanceof WritableStream, "node.streamHTMLUnsafe() returns a writable stream"); 16 const response = new Response("<span>B</span>", {headers: {"Content-Type": "text/html"}}); 17 await response.body.pipeThrough(new TextDecoderStream()).pipeTo(writable); 18 assert_equals(placeholder.textContent, "B"); 19 assert_true(response.bodyUsed); 20 }, "piping a response into streamHTMLUnsafe()"); 21 22 promise_test(async t => { 23 const placeholder = document.createElement("div"); 24 placeholder.innerHTML = "<span>A</span>"; 25 const writable = placeholder.streamHTMLUnsafe(); 26 assert_true(writable instanceof WritableStream, "node.streamHTMLUnsafe() returns a writable stream"); 27 const writer = writable.getWriter(); 28 await writer.write("B"); 29 await writer.close(); 30 assert_equals(placeholder.textContent, "B"); 31 }, "writing a string to streamHTMLUnsafe()"); 32 33 promise_test(async t => { 34 const placeholder = document.createElement("div"); 35 placeholder.innerHTML = "<span>A</span>"; 36 const writable = placeholder.streamHTMLUnsafe(); 37 assert_true(writable instanceof WritableStream, "node.streamHTMLUnsafe() returns a writable stream"); 38 assert_equals(placeholder.textContent, ""); 39 const writer = writable.getWriter(); 40 await writer.write("B"); 41 await writer.close(); 42 assert_equals(placeholder.textContent, "B"); 43 }, "streamHTMLUnsafe() should remove existing content immediately"); 44 45 promise_test(async t => { 46 const placeholder = document.createElement("div"); 47 placeholder.innerHTML = "<span>A</span>"; 48 const writable = placeholder.streamHTMLUnsafe(); 49 assert_true(writable instanceof WritableStream, "node.streamHTMLUnsafe() returns a writable stream"); 50 const writer = writable.getWriter(); 51 await writer.write("<span>B</span>"); 52 assert_equals(placeholder.textContent, "B"); 53 await writer.close(); 54 }, "streamHTMLUnsafe() does not buffer until close()"); 55 56 promise_test(async t => { 57 const placeholder = document.createElement("div"); 58 placeholder.innerHTML = "Before"; 59 const writable = placeholder.streamHTMLUnsafe(); 60 assert_true(writable instanceof WritableStream, "streamHTMLUnsafe() returns a writable stream"); 61 const writer = writable.getWriter(); 62 await promise_rejects_js(t, TypeError, writer.write(Symbol("sym"))); 63 assert_equals(placeholder.textContent, ""); 64 }, "writing a Symbol to streamHTMLUnsafe()"); 65 66 promise_test(async t => { 67 const placeholder = document.createElement("div"); 68 placeholder.innerHTML = "12"; 69 const writable = placeholder.streamHTMLUnsafe(); 70 assert_true(writable instanceof WritableStream, "node.streamHTMLUnsafe() returns a writable stream"); 71 const writer = writable.getWriter(); 72 await writer.write(345); 73 await writer.close(); 74 assert_equals(placeholder.textContent, "345"); 75 assert_equals(placeholder.childNodes.length, 1); 76 assert_equals(placeholder.firstChild.nodeType, Node.TEXT_NODE); 77 assert_equals(placeholder.firstChild.textContent, "345"); 78 }, "writing numbers to streamHTMLUnsafe()"); 79 80 promise_test(async t => { 81 const placeholder = document.createElement("div"); 82 placeholder.innerHTML = "start "; 83 const writable = placeholder.streamHTMLUnsafe(); 84 assert_true(writable instanceof WritableStream, "node.streamHTMLUnsafe() returns a writable stream"); 85 const writer = writable.getWriter(); 86 await writer.write(null); 87 await writer.write(" "); 88 await writer.write(undefined); 89 await writer.close(); 90 assert_equals(placeholder.textContent, "null undefined"); 91 }, "writing null or undefined to streamHTMLUnsafe()"); 92 93 promise_test(async t => { 94 const style = document.querySelector("#style"); 95 const writable = style.streamHTMLUnsafe(); 96 assert_true(writable instanceof WritableStream, "node.streamHTMLUnsafe() returns a writable stream"); 97 const writer = await writable.getWriter(); 98 await writer.write("#target { color: rgba(100, 0, 100); }"); 99 await writer.close(); 100 assert_equals(getComputedStyle(document.querySelector("#target")).color, "rgb(100, 0, 100)"); 101 }, "streamHTMLUnsafe() can stream into <style>"); 102 103 promise_test(async t => { 104 const placeholder = document.createElement("div"); 105 placeholder.innerHTML = "start "; 106 const writable = placeholder.streamHTMLUnsafe(); 107 const writer = writable.getWriter(); 108 await writer.write("ABC"); 109 await writer.abort("abort-reason"); 110 await writer.write("DEF").catch(() => {}); 111 assert_equals(placeholder.textContent, "ABC"); 112 }, "Aborting streamHTMLUnsafe()"); 113 114 promise_test(async t => { 115 const placeholder = document.createElement("div"); 116 placeholder.innerHTML = "before"; 117 const writer1 = placeholder.streamHTMLUnsafe().getWriter(); 118 const writer2 = placeholder.streamHTMLUnsafe().getWriter(); 119 await writer1.write("<span>A</span>"); 120 await writer2.write("<span>B</span>"); 121 await new Promise(resolve => requestAnimationFrame(resolve)); 122 await writer1.write("C"); 123 await writer1.close(); 124 await writer2.close(); 125 assert_equals(placeholder.textContent, "ABC"); 126 }, "Interleaved streamHTMLUnsafe() writes"); 127 128 promise_test(async t => { 129 const element = document.createElement("div"); 130 const shadowRoot = element.attachShadow({mode: "open"}); 131 shadowRoot.innerHTML = "before"; 132 const writer = shadowRoot.streamHTMLUnsafe().getWriter(); 133 await writer.write("<div id=added>A</div>"); 134 assert_equals(shadowRoot.getElementById("added").textContent, "A"); 135 }, "streamHTMLUnsafe into a ShadowRoot"); 136 137 promise_test(async t => { 138 const element = document.createElement("template"); 139 element.innerHTML = "before"; 140 const writer = element.streamHTMLUnsafe().getWriter(); 141 await writer.write("<div id=added>A</div>"); 142 assert_equals(element.content.getElementById("added").textContent, "A"); 143 }, "streamHTMLUnsafe into a template"); 144 145 promise_test(async t => { 146 const element = document.createElement("div"); 147 document.body.append(element); 148 window.did_eval_script = false; 149 const writer = element.streamHTMLUnsafe().getWriter(); 150 assert_false(window.did_eval_script); 151 await writer.write("<script>window.did_eval_script = true;"); 152 assert_false(window.did_eval_script); 153 await writer.write("<"); 154 assert_false(window.did_eval_script); 155 await writer.write("/script>"); 156 assert_true(window.did_eval_script); 157 }, "streamHTMLUnsafe should execute scripts when connected"); 158 159 promise_test(async t => { 160 const element = document.createElement("div"); 161 window.did_eval_script = false; 162 const writer = element.streamHTMLUnsafe().getWriter(); 163 assert_false(window.did_eval_script); 164 await writer.write("<script>window.did_eval_script = true;"); 165 assert_false(window.did_eval_script); 166 await writer.write("<"); 167 assert_false(window.did_eval_script); 168 await writer.write("/script>"); 169 assert_false(window.did_eval_script); 170 }, "streamHTMLUnsafe should not execute scripts when disconnected"); 171 </script>