perform-microtask-checkpoint-before-construction.html (6311B)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>Custom Elements: create an element for a token must perform a microtask checkpoint</title> 5 <meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org"> 6 <meta name="assert" content="When the HTML parser creates an element for a token, it must perform a microtask checkpoint before invoking the constructor"> 7 <meta name="help" content="https://html.spec.whatwg.org/multipage/parsing.html#create-an-element-for-the-token"> 8 <meta name="help" content="https://html.spec.whatwg.org/multipage/webappapis.html#perform-a-microtask-checkpoint"> 9 <meta name="help" content="https://html.spec.whatwg.org/multipage/parsing.html#adoption-agency-algorithm"> 10 <script src="/resources/testharness.js"></script> 11 <script src="/resources/testharnessreport.js"></script> 12 <script src="resources/custom-elements-helpers.js"></script> 13 </head> 14 <body> 15 <div id="log"></div> 16 <script> 17 18 async function construct_custom_element_in_parser(test, markup) 19 { 20 const window = await create_window_in_test(test, ` 21 <!DOCTYPE html> 22 <html> 23 <body><script> 24 class SomeElement extends HTMLElement { 25 constructor() { 26 super(); 27 window.recordsListInConstructor = recordsList.map((records) => records.slice(0)); 28 } 29 } 30 customElements.define('some-element', SomeElement); 31 32 const recordsList = []; 33 const observer = new MutationObserver((records) => { 34 recordsList.push(records); 35 }); 36 observer.observe(document.body, {childList: true, subtree: true}); 37 38 window.onload = () => { 39 window.recordsListInDOMContentLoaded = recordsList.map((records) => records.slice(0)); 40 } 41 42 </scr` + `ipt>${markup}</body></html>`); 43 return window; 44 } 45 46 promise_test(async function () { 47 const contentWindow = await construct_custom_element_in_parser(this, '<b><some-element></b>'); 48 const contentDocument = contentWindow.document; 49 50 let recordsList = contentWindow.recordsListInConstructor; 51 assert_true(Array.isArray(recordsList)); 52 assert_equals(recordsList.length, 1); 53 assert_true(Array.isArray(recordsList[0])); 54 assert_equals(recordsList[0].length, 1); 55 let record = recordsList[0][0]; 56 assert_equals(record.type, 'childList'); 57 assert_equals(record.target, contentDocument.body); 58 assert_equals(record.previousSibling, contentDocument.querySelector('script')); 59 assert_equals(record.nextSibling, null); 60 assert_equals(record.removedNodes.length, 0); 61 assert_equals(record.addedNodes.length, 1); 62 assert_equals(record.addedNodes[0], contentDocument.querySelector('b')); 63 64 recordsList = contentWindow.recordsListInDOMContentLoaded; 65 assert_true(Array.isArray(recordsList)); 66 assert_equals(recordsList.length, 2); 67 assert_true(Array.isArray(recordsList[1])); 68 assert_equals(recordsList[1].length, 1); 69 record = recordsList[1][0]; 70 assert_equals(record.type, 'childList'); 71 assert_equals(record.target, contentDocument.querySelector('b')); 72 assert_equals(record.previousSibling, null); 73 assert_equals(record.nextSibling, null); 74 assert_equals(record.removedNodes.length, 0); 75 assert_equals(record.addedNodes.length, 1); 76 assert_equals(record.addedNodes[0], contentDocument.querySelector('some-element')); 77 }, 'HTML parser must perform a microtask checkpoint before constructing a custom element'); 78 79 promise_test(async function () { 80 const contentWindow = await construct_custom_element_in_parser(this, '<b><i>hello</b><some-element>'); 81 const contentDocument = contentWindow.document; 82 let recordsList = contentWindow.recordsListInConstructor; 83 assert_true(Array.isArray(recordsList)); 84 assert_equals(recordsList.length, 1); 85 assert_true(Array.isArray(recordsList[0])); 86 assert_equals(recordsList[0].length, 4); 87 88 let record = recordsList[0][0]; 89 assert_equals(record.type, 'childList'); 90 assert_equals(record.target, contentDocument.body); 91 assert_equals(record.previousSibling, contentDocument.querySelector('script')); 92 assert_equals(record.nextSibling, null); 93 assert_equals(record.removedNodes.length, 0); 94 assert_equals(record.addedNodes.length, 1); 95 assert_equals(record.addedNodes[0], contentDocument.querySelector('b')); 96 97 record = recordsList[0][1]; 98 assert_equals(record.type, 'childList'); 99 assert_equals(record.target, contentDocument.querySelector('b')); 100 assert_equals(record.previousSibling, null); 101 assert_equals(record.nextSibling, null); 102 assert_equals(record.removedNodes.length, 0); 103 assert_equals(record.addedNodes.length, 1); 104 assert_equals(record.addedNodes[0], contentDocument.querySelector('i')); 105 106 record = recordsList[0][2]; 107 assert_equals(record.type, 'childList'); 108 assert_equals(record.target, contentDocument.querySelector('i')); 109 assert_equals(record.previousSibling, null); 110 assert_equals(record.nextSibling, null); 111 assert_equals(record.removedNodes.length, 0); 112 assert_equals(record.addedNodes.length, 1); 113 assert_equals(record.addedNodes[0].nodeType, Node.TEXT_NODE); 114 assert_equals(record.addedNodes[0].data, "hello"); 115 116 record = recordsList[0][3]; 117 assert_equals(record.type, 'childList'); 118 assert_equals(record.target, contentDocument.body); 119 assert_equals(record.previousSibling, contentDocument.querySelector('b')); 120 assert_equals(record.nextSibling, null); 121 assert_equals(record.removedNodes.length, 0); 122 assert_equals(record.addedNodes.length, 1); 123 assert_equals(record.addedNodes[0], contentDocument.querySelectorAll('i')[1]); 124 125 recordsList = contentWindow.recordsListInDOMContentLoaded; 126 assert_true(Array.isArray(recordsList)); 127 assert_equals(recordsList.length, 2); 128 assert_true(Array.isArray(recordsList[1])); 129 assert_equals(recordsList[1].length, 1); 130 131 record = recordsList[1][0]; 132 assert_equals(record.type, 'childList'); 133 assert_equals(record.target, contentDocument.querySelectorAll('i')[1]); 134 assert_equals(record.previousSibling, null); 135 assert_equals(record.nextSibling, null); 136 assert_equals(record.removedNodes.length, 0); 137 assert_equals(record.addedNodes.length, 1); 138 assert_equals(record.addedNodes[0], contentDocument.querySelector('some-element')); 139 }, 'HTML parser must perform a microtask checkpoint before constructing a custom element during the adoption agency algorithm'); 140 141 </script> 142 </body> 143 </html>