| OLD | NEW |
| (Empty) |
| 1 <!DOCTYPE html> | |
| 2 <title>Custom Elements: upgrade element</title> | |
| 3 <link rel="help" href="https://html.spec.whatwg.org/multipage/scripting.html#con
cept-upgrade-an-element"> | |
| 4 <script src="../../resources/testharness.js"></script> | |
| 5 <script src="../../resources/testharnessreport.js"></script> | |
| 6 <script src="resources/custom-elements-helpers.js"></script> | |
| 7 <body> | |
| 8 <script> | |
| 9 | |
| 10 'use strict' | |
| 11 // 6. "attributeChangedCallback" and "connectedCallback" should execute after C
and | |
| 12 // the rest of the upgrade process finishes. | |
| 13 test_with_window((w) => { | |
| 14 let invocations = []; | |
| 15 let changedCallbackArgs; | |
| 16 let a = w.document.createElement('a-a'); | |
| 17 w.document.body.appendChild(a); | |
| 18 a.setAttribute('x', '1'); | |
| 19 class X extends w.HTMLElement { | |
| 20 constructor() { | |
| 21 super(); | |
| 22 invocations.push(['constructor', this]); | |
| 23 } | |
| 24 connectedCallback() { invocations.push(['connected', this]); } | |
| 25 static get observedAttributes() { return ['x']; } | |
| 26 attributeChangedCallback() { | |
| 27 invocations.push(['attributeChanged', this]); | |
| 28 changedCallbackArgs = arguments; | |
| 29 } | |
| 30 } | |
| 31 w.customElements.define('a-a', X); | |
| 32 assert_equals(invocations.length, 3); | |
| 33 assert_array_equals(invocations[0], ['constructor', a], 'constructor should ex
ecute first'); | |
| 34 assert_array_equals(invocations[1], ['attributeChanged', a], 'attributeChanged
Callback should execute after the constructor'); | |
| 35 assert_array_equals(changedCallbackArgs, ['x', null, '1', '']); | |
| 36 assert_array_equals(invocations[2], ['connected', a], 'connectedCallback shoul
d execute after the constructor'); | |
| 37 }, '"connectedCallback", "attributeChangedCallback" reactions should execute aft
er the constructor'); | |
| 38 | |
| 39 // 6. If C non-conformantly uses an API decorated with the [CEReactions] extende
d attribute, | |
| 40 // then the reactions enqueued at the beginning of upgrade will execute during t
his step, | |
| 41 // before C finishes and control returns to this algorithm. | |
| 42 test_with_window((w) => { | |
| 43 let invocations = []; | |
| 44 let changedCallbackArgs; | |
| 45 let a = w.document.createElement('a-a'); | |
| 46 w.document.body.appendChild(a); | |
| 47 class X extends w.HTMLElement { | |
| 48 constructor() { | |
| 49 super(); | |
| 50 this.setAttribute('x', '1'); | |
| 51 invocations.push(['constructor', this]); | |
| 52 } | |
| 53 connectedCallback() { invocations.push(['connected', this]); } | |
| 54 static get observedAttributes() { return ['x']; } | |
| 55 attributeChangedCallback() { | |
| 56 invocations.push(['attributeChanged', this]); | |
| 57 changedCallbackArgs = arguments; | |
| 58 } | |
| 59 } | |
| 60 w.customElements.define('a-a', X); | |
| 61 assert_equals(invocations.length, 3); | |
| 62 assert_array_equals(invocations[0], ['connected', a], 'connectedCallback execu
tes before the constructor'); | |
| 63 assert_array_equals(invocations[1], ['attributeChanged', a], 'attributeChanged
Callback executes before the constructor'); | |
| 64 assert_array_equals(changedCallbackArgs, ['x', null, '1', '']); | |
| 65 assert_array_equals(invocations[2], ['constructor', a], 'constructor executes
last'); | |
| 66 }, 'The constructor non-conformatly uses API decorated with the [CEReactions]'); | |
| 67 | |
| 68 // 8. If constructResult is an abrupt completion, then return constructResult | |
| 69 // (i.e., rethrow the exception). | |
| 70 test_with_window((w) => { | |
| 71 let error_log = []; | |
| 72 let doc = w.document; | |
| 73 doc.body.appendChild(doc.createElement('a-a')); | |
| 74 w.onerror = function (msg, url, lineNo, columnNo, error) { | |
| 75 error_log.push(error); | |
| 76 return true; | |
| 77 }; | |
| 78 class X extends w.HTMLElement { | |
| 79 constructor() { | |
| 80 super(); | |
| 81 assert_false(this.matches(':defined'), 'calling super() with non-empty con
struction stack should not define the element'); | |
| 82 throw 'constructor throws'; | |
| 83 } | |
| 84 } | |
| 85 w.customElements.define('a-a', X); | |
| 86 assert_array_equals(error_log, ['constructor throws'], 'rethrow any exception
thrown from constructor'); | |
| 87 }, 'Upgrading an element with a throwing constructor should rethrow that excepti
on'); | |
| 88 | |
| 89 // 9. If SameValue(constructResult.[[value]], element) is false, then throw an | |
| 90 // "InvalidStateError" DOMException and terminate these steps. | |
| 91 test_with_window((w) => { | |
| 92 let error_log = []; | |
| 93 w.onerror = function (msg, url, lineNo, columnNo, error) { | |
| 94 error_log.push(error); | |
| 95 return true; | |
| 96 }; | |
| 97 let a = w.document.createElement('a-a'); | |
| 98 w.document.body.appendChild(a); | |
| 99 class X extends w.HTMLElement { | |
| 100 constructor() { | |
| 101 super(); | |
| 102 return ['aaaa']; | |
| 103 } | |
| 104 } | |
| 105 w.customElements.define('a-a', X); | |
| 106 assert_array_equals(error_log, ['InvalidStateError'], 'returning object that i
s different from element should throw "InvalidStateError"'); | |
| 107 }, 'Upgrading an element with invalid constructor'); | |
| 108 </script> | |
| 109 </body> | |
| OLD | NEW |