upgrading-parser-created-element.html (5086B)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>Custom Elements: Upgrading unresolved elements</title> 5 <meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org"> 6 <meta name="assert" content="HTML parser must add an unresolved custom element to the upgrade candidates map"> 7 <link rel="help" href="https://html.spec.whatwg.org/#upgrades"> 8 <script src="/resources/testharness.js"></script> 9 <script src="/resources/testharnessreport.js"></script> 10 </head> 11 <body> 12 <div id="log"></div> 13 <my-custom-element></my-custom-element> 14 <instantiates-itself-after-super></instantiates-itself-after-super> 15 <instantiates-itself-before-super></instantiates-itself-before-super> 16 <my-other-element id="instance"></my-other-element> 17 <my-other-element id="otherInstance"></my-other-element> 18 <not-an-element></not-an-element> 19 <not-an-html-element></not-an-html-element> 20 <script> 21 22 setup({allow_uncaught_exception:true}); 23 24 test(function () { 25 class MyCustomElement extends HTMLElement { } 26 27 var instance = document.querySelector('my-custom-element'); 28 assert_true(instance instanceof HTMLElement); 29 assert_false(instance instanceof HTMLUnknownElement, 30 'an unresolved custom element should not be an instance of HTMLUnknownElement'); 31 assert_false(instance instanceof MyCustomElement); 32 33 customElements.define('my-custom-element', MyCustomElement); 34 35 assert_true(instance instanceof HTMLElement); 36 assert_true(instance instanceof MyCustomElement, 37 'Calling customElements.define must upgrade existing custom elements'); 38 39 }, 'Element.prototype.createElement must add an unresolved custom element to the upgrade candidates map'); 40 41 test(function () { 42 class InstantiatesItselfAfterSuper extends HTMLElement { 43 constructor(doNotCreateItself) { 44 super(); 45 if (!doNotCreateItself) 46 new InstantiatesItselfAfterSuper(true); 47 } 48 } 49 50 var uncaughtError; 51 window.onerror = function (message, url, lineNumber, columnNumber, error) { uncaughtError = error; return true; } 52 customElements.define('instantiates-itself-after-super', InstantiatesItselfAfterSuper); 53 assert_equals(uncaughtError.name, 'TypeError'); 54 }, 'HTMLElement constructor must throw an TypeError when the top of the construction stack is marked AlreadyConstructed' 55 + ' due to a custom element constructor constructing itself after super() call'); 56 57 test(function () { 58 class InstantiatesItselfBeforeSuper extends HTMLElement { 59 constructor(doNotCreateItself) { 60 if (!doNotCreateItself) 61 new InstantiatesItselfBeforeSuper(true); 62 super(); 63 } 64 } 65 66 var uncaughtError; 67 window.onerror = function (message, url, lineNumber, columnNumber, error) { uncaughtError = error; return true; } 68 customElements.define('instantiates-itself-before-super', InstantiatesItselfBeforeSuper); 69 assert_equals(uncaughtError.name, 'TypeError'); 70 }, 'HTMLElement constructor must throw an TypeError when the top of the construction stack is marked AlreadyConstructed' 71 + ' due to a custom element constructor constructing itself before super() call'); 72 73 test(function () { 74 class MyOtherElement extends HTMLElement { 75 constructor() { 76 super(); 77 if (this == instance) 78 return otherInstance; 79 } 80 } 81 var instance = document.getElementById('instance'); 82 var otherInstance = document.getElementById('otherInstance'); 83 84 assert_false(instance instanceof MyOtherElement); 85 assert_false(otherInstance instanceof MyOtherElement); 86 87 var uncaughtError; 88 window.onerror = function (message, url, lineNumber, columnNumber, error) { uncaughtError = error; return true; } 89 customElements.define('my-other-element', MyOtherElement); 90 assert_equals(uncaughtError.name, 'TypeError'); 91 92 assert_true(document.createElement('my-other-element') instanceof MyOtherElement, 93 'Upgrading of custom elements must happen after the definition was added to the registry.'); 94 95 }, 'Upgrading a custom element must throw an TypeError when the returned element is not SameValue as the upgraded element'); 96 97 test(() => { 98 class NotAnElement extends HTMLElement { 99 constructor() { 100 return new Text(); 101 } 102 } 103 104 let uncaughtError; 105 window.onerror = function (message, url, lineNumber, columnNumber, error) { uncaughtError = error; return true; } 106 customElements.define("not-an-element", NotAnElement); 107 assert_equals(uncaughtError.name, "TypeError"); 108 }, "Upgrading a custom element whose constructor returns a Text node must throw"); 109 110 test(() => { 111 class NotAnHTMLElement extends HTMLElement { 112 constructor() { 113 return document.createElementNS("", "test"); 114 } 115 } 116 117 let uncaughtError; 118 window.onerror = function (message, url, lineNumber, columnNumber, error) { uncaughtError = error; return true; } 119 customElements.define("not-an-html-element", NotAnHTMLElement); 120 assert_equals(uncaughtError.name, "TypeError"); 121 }, "Upgrading a custom element whose constructor returns an Element must throw"); 122 123 </script> 124 </body> 125 </html>