parser-uses-registry-of-owner-document.html (7137B)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>Custom Elements: HTML parser must use the owner document's custom element registry</title> 5 <meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org"> 6 <meta name="assert" content="HTML parser must use the owner document's custom element registry"> 7 <link rel="help" href="https://html.spec.whatwg.org/#create-an-element-for-the-token"> 8 <link rel="help" href="https://dom.spec.whatwg.org/#concept-create-element"> 9 <script src="/resources/testharness.js"></script> 10 <script src="/resources/testharnessreport.js"></script> 11 <script src="../resources/custom-elements-helpers.js"></script> 12 </head> 13 <body> 14 <div id="log"></div> 15 <script> 16 17 class MyCustomElement extends HTMLElement { }; 18 customElements.define('my-custom-element', MyCustomElement); 19 20 document.write('<template><my-custom-element></my-custom-element></template>'); 21 22 test(function () { 23 var template = document.querySelector('template'); 24 var instance = template.content.firstChild; 25 26 assert_true(instance instanceof HTMLElement, 27 'A custom element inside a template element must be an instance of HTMLElement'); 28 assert_false(instance instanceof MyCustomElement, 29 'A custom element must not be instantiated inside a template element using the registry of the template element\'s owner document'); 30 assert_equals(instance.ownerDocument, template.content.ownerDocument, 31 'Custom elements inside a template must use the appropriate template contents owner document as the owner document'); 32 33 }, 'HTML parser must not instantiate custom elements inside template elements'); 34 35 var iframe = document.createElement('iframe'); 36 document.body.appendChild(iframe); 37 iframe.contentDocument.body.innerHTML = '<my-custom-element></my-custom-element>'; 38 39 test(function () { 40 var instance = iframe.contentDocument.querySelector('my-custom-element'); 41 42 assert_true(instance instanceof iframe.contentWindow.HTMLElement); 43 assert_false(instance instanceof MyCustomElement); 44 45 }, 'HTML parser must not use the registry of the owner element\'s document inside an iframe'); 46 47 class ElementInIFrame extends iframe.contentWindow.HTMLElement { }; 48 iframe.contentWindow.customElements.define('element-in-iframe', ElementInIFrame); 49 iframe.contentDocument.body.innerHTML = '<element-in-iframe></element-in-iframe>'; 50 51 test(function () { 52 var instance = iframe.contentDocument.querySelector('element-in-iframe'); 53 54 assert_true(instance instanceof iframe.contentWindow.HTMLElement, 'A custom element inside an iframe must be an instance of HTMLElement'); 55 assert_true(instance instanceof ElementInIFrame, 56 'A custom element must be instantiated inside an iframe using the registry of the content document'); 57 assert_equals(instance.ownerDocument, iframe.contentDocument, 58 'The owner document of custom elements inside an iframe must be the content document of the iframe'); 59 60 }, 'HTML parser must use the registry of the content document inside an iframe'); 61 62 document.write('<element-in-iframe></element-in-iframe>'); 63 64 test(function () { 65 var instance = document.querySelector('element-in-iframe'); 66 67 assert_true(instance instanceof HTMLElement); 68 assert_false(instance instanceof ElementInIFrame); 69 70 }, 'HTML parser must not instantiate a custom element defined inside an frame in frame element\'s owner document'); 71 72 document.body.removeChild(iframe); 73 74 test(function () { 75 var windowlessDocument = (new DOMParser()).parseFromString('<my-custom-element></my-custom-element>', "text/html"); 76 77 var instance = windowlessDocument.querySelector('my-custom-element'); 78 79 assert_true(instance instanceof HTMLElement); 80 assert_false(instance instanceof MyCustomElement); 81 82 }, 'HTML parser must use the registry of window.document in a document created by DOMParser'); 83 84 test(function () { 85 var windowlessDocument = document.implementation.createDocument ('http://www.w3.org/1999/xhtml', 'html', null); 86 windowlessDocument.documentElement.innerHTML = '<my-custom-element></my-custom-element>'; 87 88 var instance = windowlessDocument.querySelector('my-custom-element'); 89 assert_true(instance instanceof HTMLElement); 90 assert_false(instance instanceof MyCustomElement); 91 92 }, 'HTML parser must use the registry of window.document in a document created by document.implementation.createXHTMLDocument()'); 93 94 test(function () { 95 var windowlessDocument = new Document; 96 windowlessDocument.appendChild(windowlessDocument.createElement('html')); 97 windowlessDocument.documentElement.innerHTML = '<my-custom-element></my-custom-element>'; 98 99 var instance = windowlessDocument.querySelector('my-custom-element'); 100 101 assert_true(instance instanceof Element); 102 assert_false(instance instanceof MyCustomElement); 103 104 }, 'HTML parser must use the registry of window.document in a document created by new Document'); 105 106 promise_test(function () { 107 return new Promise(function (resolve, reject) { 108 var xhr = new XMLHttpRequest(); 109 xhr.open('GET', '../resources/my-custom-element-html-document.html'); 110 xhr.overrideMimeType('text/xml'); 111 xhr.onload = function () { resolve(xhr.responseXML); } 112 xhr.onerror = function () { reject('Failed to fetch the document'); } 113 xhr.send(); 114 }).then(function (doc) { 115 var instance = doc.querySelector('my-custom-element'); 116 assert_true(instance instanceof Element); 117 assert_false(instance instanceof MyCustomElement); 118 119 doc.documentElement.innerHTML = '<my-custom-element></my-custom-element>'; 120 var instance2 = doc.querySelector('my-custom-element'); 121 assert_true(instance2 instanceof Element); 122 assert_false(instance2 instanceof MyCustomElement); 123 }); 124 }, 'HTML parser must use the registry of window.document in a document created by XMLHttpRequest'); 125 126 test_with_window(function (contentWindow, contentDocument) { 127 const element = define_custom_element_in_window(contentWindow, 'my-custom-element', []); 128 // document-open-steps spec doesn't do anything with the custom element 129 // registry, so it should just stick around. 130 contentDocument.write('<my-custom-element></my-custom-element>'); 131 132 var instance = contentDocument.querySelector('my-custom-element'); 133 134 assert_true(instance instanceof contentWindow.HTMLElement); 135 assert_true(instance instanceof element.class); 136 137 }, 'document.write() must not instantiate a custom element without a defined insertion point'); 138 139 test_with_window(function (contentWindow, contentDocument) { 140 const element = define_custom_element_in_window(contentWindow, 'my-custom-element', []); 141 // document-open-steps spec doesn't do anything with the custom element 142 // registry, so it should just stick around. 143 contentDocument.writeln('<my-custom-element></my-custom-element>'); 144 145 var instance = contentDocument.querySelector('my-custom-element'); 146 147 assert_true(instance instanceof contentWindow.HTMLElement); 148 assert_true(instance instanceof element.class); 149 150 }, 'document.writeln() must not instantiate a custom element without a defined insertion point'); 151 152 </script> 153 </body> 154 </html>