upgrading-enqueue-reactions.html (7137B)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>Custom Elements: Upgrading custom elements should enqueue attributeChanged and connected callbacks</title> 5 <meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org"> 6 <meta name="assert" content="Upgrading custom elements should enqueue attributeChanged and connected callbacksml"> 7 <meta name="help" content="https://html.spec.whatwg.org/#upgrades"> 8 <script src="/resources/testharness.js"></script> 9 <script src="/resources/testharnessreport.js"></script> 10 <script src="../resources/custom-elements-helpers.js"></script> 11 </head> 12 <body> 13 <div id="log"></div> 14 <script> 15 setup({allow_uncaught_exception:true}); 16 17 test_with_window(function (contentWindow) { 18 const contentDocument = contentWindow.document; 19 contentDocument.write('<test-element id="some" title="This is a test">'); 20 21 const undefinedElement = contentDocument.querySelector('test-element'); 22 assert_equals(Object.getPrototypeOf(undefinedElement), contentWindow.HTMLElement.prototype); 23 24 let log = []; 25 class TestElement extends contentWindow.HTMLElement { 26 constructor() { 27 super(); 28 log.push(create_constructor_log(this)); 29 } 30 attributeChangedCallback(...args) { 31 log.push(create_attribute_changed_callback_log(this, ...args)); 32 } 33 static get observedAttributes() { return ['id', 'title']; } 34 } 35 contentWindow.customElements.define('test-element', TestElement); 36 assert_equals(Object.getPrototypeOf(undefinedElement), TestElement.prototype); 37 38 assert_equals(log.length, 3); 39 assert_constructor_log_entry(log[0], undefinedElement); 40 assert_attribute_log_entry(log[1], {name: 'id', oldValue: null, newValue: 'some', namespace: null}); 41 assert_attribute_log_entry(log[2], {name: 'title', oldValue: null, newValue: 'This is a test', namespace: null}); 42 }, 'Upgrading a custom element must enqueue attributeChangedCallback on each attribute'); 43 44 test_with_window(function (contentWindow) { 45 const contentDocument = contentWindow.document; 46 contentDocument.write('<test-element id="some" title="This is a test" class="foo">'); 47 48 const undefinedElement = contentDocument.querySelector('test-element'); 49 assert_equals(Object.getPrototypeOf(undefinedElement), contentWindow.HTMLElement.prototype); 50 51 let log = []; 52 class TestElement extends contentWindow.HTMLElement { 53 constructor() { 54 super(); 55 log.push(create_constructor_log(this)); 56 } 57 attributeChangedCallback(...args) { 58 log.push(create_attribute_changed_callback_log(this, ...args)); 59 } 60 static get observedAttributes() { return ['class', 'id']; } 61 } 62 contentWindow.customElements.define('test-element', TestElement); 63 assert_equals(Object.getPrototypeOf(undefinedElement), TestElement.prototype); 64 65 assert_equals(log.length, 3); 66 assert_constructor_log_entry(log[0], undefinedElement); 67 assert_attribute_log_entry(log[1], {name: 'id', oldValue: null, newValue: 'some', namespace: null}); 68 assert_attribute_log_entry(log[2], {name: 'class', oldValue: null, newValue: 'foo', namespace: null}); 69 }, 'Upgrading a custom element not must enqueue attributeChangedCallback on unobserved attributes'); 70 71 test_with_window(function (contentWindow) { 72 const contentDocument = contentWindow.document; 73 contentDocument.write('<test-element id="some" title="This is a test" class="foo">'); 74 75 const undefinedElement = contentDocument.querySelector('test-element'); 76 assert_equals(Object.getPrototypeOf(undefinedElement), contentWindow.HTMLElement.prototype); 77 78 let log = []; 79 class TestElement extends contentWindow.HTMLElement { 80 constructor() { 81 super(); 82 log.push(create_constructor_log(this)); 83 } 84 connectedCallback(...args) { 85 log.push(create_connected_callback_log(this, ...args)); 86 } 87 } 88 contentWindow.customElements.define('test-element', TestElement); 89 assert_equals(Object.getPrototypeOf(undefinedElement), TestElement.prototype); 90 91 assert_equals(log.length, 2); 92 assert_constructor_log_entry(log[0], undefinedElement); 93 assert_connected_log_entry(log[1], undefinedElement); 94 }, 'Upgrading a custom element must enqueue connectedCallback if the element in the document'); 95 96 test_with_window(function (contentWindow) { 97 const contentDocument = contentWindow.document; 98 contentDocument.write('<test-element id="some" title="This is a test" class="foo">'); 99 100 const undefinedElement = contentDocument.querySelector('test-element'); 101 assert_equals(Object.getPrototypeOf(undefinedElement), contentWindow.HTMLElement.prototype); 102 103 let log = []; 104 class TestElement extends contentWindow.HTMLElement { 105 constructor() { 106 super(); 107 log.push(create_constructor_log(this)); 108 } 109 connectedCallback(...args) { 110 log.push(create_connected_callback_log(this, ...args)); 111 } 112 attributeChangedCallback(...args) { 113 log.push(create_attribute_changed_callback_log(this, ...args)); 114 } 115 static get observedAttributes() { return ['class', 'id']; } 116 } 117 contentWindow.customElements.define('test-element', TestElement); 118 assert_equals(Object.getPrototypeOf(undefinedElement), TestElement.prototype); 119 120 assert_equals(log.length, 4); 121 assert_constructor_log_entry(log[0], undefinedElement); 122 assert_attribute_log_entry(log[1], {name: 'id', oldValue: null, newValue: 'some', namespace: null}); 123 assert_attribute_log_entry(log[2], {name: 'class', oldValue: null, newValue: 'foo', namespace: null}); 124 assert_connected_log_entry(log[3], undefinedElement); 125 }, 'Upgrading a custom element must enqueue attributeChangedCallback before connectedCallback'); 126 127 test_with_window(function (contentWindow) { 128 const contentDocument = contentWindow.document; 129 contentDocument.write('<test-element id="some" title="This is a test" class="foo">'); 130 131 const undefinedElement = contentDocument.querySelector('test-element'); 132 assert_equals(Object.getPrototypeOf(undefinedElement), contentWindow.HTMLElement.prototype); 133 134 let log = []; 135 class TestElement extends contentWindow.HTMLElement { 136 constructor() { 137 super(); 138 log.push(create_constructor_log(this)); 139 throw 'Exception thrown as a part of test'; 140 } 141 connectedCallback(...args) { 142 log.push(create_connected_callback_log(this, ...args)); 143 } 144 attributeChangedCallback(...args) { 145 log.push(create_attribute_changed_callback_log(this, ...args)); 146 } 147 static get observedAttributes() { return ['class', 'id']; } 148 } 149 contentWindow.customElements.define('test-element', TestElement); 150 assert_equals(Object.getPrototypeOf(undefinedElement), TestElement.prototype); 151 152 assert_equals(log.length, 1); 153 assert_constructor_log_entry(log[0], undefinedElement); 154 }, 'Upgrading a custom element must not invoke attributeChangedCallback and connectedCallback when the element failed to upgrade'); 155 156 </script> 157 </body> 158 </html>