| OLD | NEW |
| (Empty) |
| 1 <!DOCTYPE html> | |
| 2 <html> | |
| 3 <head> | |
| 4 <title>Custom Elements: Each element must have its own custom element reaction q
ueue</title> | |
| 5 <meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org"> | |
| 6 <meta name="assert" content="Each element must have its own custom element react
ion queue"> | |
| 7 <meta name="help" content="https://html.spec.whatwg.org/multipage/scripting.html
#custom-element-reaction-queue"> | |
| 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 | |
| 16 test_with_window(function (contentWindow) { | |
| 17 const contentDocument = contentWindow.document; | |
| 18 contentDocument.write('<test-element id="first-element">'); | |
| 19 contentDocument.write('<test-element id="second-element">'); | |
| 20 | |
| 21 const element1 = contentDocument.getElementById('first-element'); | |
| 22 const element2 = contentDocument.getElementById('second-element'); | |
| 23 assert_equals(Object.getPrototypeOf(element1), contentWindow.HTMLElement.pro
totype); | |
| 24 assert_equals(Object.getPrototypeOf(element2), contentWindow.HTMLElement.pro
totype); | |
| 25 | |
| 26 let log = []; | |
| 27 class TestElement extends contentWindow.HTMLElement { | |
| 28 constructor() { | |
| 29 super(); | |
| 30 log.push(create_constructor_log(this)); | |
| 31 } | |
| 32 connectedCallback(...args) { | |
| 33 log.push(create_connected_callback_log(this, ...args)); | |
| 34 } | |
| 35 attributeChangedCallback(...args) { | |
| 36 log.push(create_attribute_changed_callback_log(this, ...args)); | |
| 37 } | |
| 38 static get observedAttributes() { return ['id']; } | |
| 39 } | |
| 40 contentWindow.customElements.define('test-element', TestElement); | |
| 41 assert_equals(Object.getPrototypeOf(element1), TestElement.prototype); | |
| 42 assert_equals(Object.getPrototypeOf(element2), TestElement.prototype); | |
| 43 | |
| 44 assert_equals(log.length, 6); | |
| 45 assert_constructor_log_entry(log[0], element1); | |
| 46 assert_attribute_log_entry(log[1], {name: 'id', oldValue: null, newValue: 'f
irst-element', namespace: null}); | |
| 47 assert_connected_log_entry(log[2], element1); | |
| 48 assert_constructor_log_entry(log[3], element2); | |
| 49 assert_attribute_log_entry(log[4], {name: 'id', oldValue: null, newValue: 's
econd-element', namespace: null}); | |
| 50 assert_connected_log_entry(log[5], element2); | |
| 51 }, 'Upgrading a custom element must invoke attributeChangedCallback and connecte
dCallback before start upgrading another element'); | |
| 52 | |
| 53 test_with_window(function (contentWindow) { | |
| 54 const contentDocument = contentWindow.document; | |
| 55 contentDocument.write('<test-element id="first-element">'); | |
| 56 contentDocument.write('<test-element id="second-element">'); | |
| 57 | |
| 58 const element1 = contentDocument.getElementById('first-element'); | |
| 59 const element2 = contentDocument.getElementById('second-element'); | |
| 60 assert_equals(Object.getPrototypeOf(element1), contentWindow.HTMLElement.pro
totype); | |
| 61 assert_equals(Object.getPrototypeOf(element2), contentWindow.HTMLElement.pro
totype); | |
| 62 | |
| 63 let log = []; | |
| 64 class TestElement extends contentWindow.HTMLElement { | |
| 65 constructor() { | |
| 66 super(); | |
| 67 log.push(create_constructor_log(this)); | |
| 68 if (this == element1) { | |
| 69 element2.setAttribute('title', 'hi'); | |
| 70 element2.removeAttribute('title'); | |
| 71 element2.setAttribute('class', 'foo'); | |
| 72 } | |
| 73 } | |
| 74 connectedCallback(...args) { | |
| 75 log.push(create_connected_callback_log(this, ...args)); | |
| 76 } | |
| 77 attributeChangedCallback(...args) { | |
| 78 log.push(create_attribute_changed_callback_log(this, ...args)); | |
| 79 } | |
| 80 static get observedAttributes() { return ['id', 'class', 'title']; } | |
| 81 } | |
| 82 contentWindow.customElements.define('test-element', TestElement); | |
| 83 assert_equals(Object.getPrototypeOf(element1), TestElement.prototype); | |
| 84 assert_equals(Object.getPrototypeOf(element2), TestElement.prototype); | |
| 85 | |
| 86 assert_equals(log.length, 7); | |
| 87 assert_constructor_log_entry(log[0], element1); | |
| 88 assert_attribute_log_entry(log[1], {name: 'id', oldValue: null, newValue: 'f
irst-element', namespace: null}); | |
| 89 assert_connected_log_entry(log[2], element1); | |
| 90 assert_constructor_log_entry(log[3], element2); | |
| 91 assert_attribute_log_entry(log[4], {name: 'id', oldValue: null, newValue: 's
econd-element', namespace: null}); | |
| 92 assert_attribute_log_entry(log[5], {name: 'class', oldValue: null, newValue:
'foo', namespace: null}); | |
| 93 assert_connected_log_entry(log[6], element2); | |
| 94 }, 'Mutating a undefined custom element while upgrading a custom element must no
t enqueue or invoke reactions on the mutated element'); | |
| 95 | |
| 96 test_with_window(function (contentWindow) { | |
| 97 let log = []; | |
| 98 let element1; | |
| 99 let element2; | |
| 100 class TestElement extends contentWindow.HTMLElement { | |
| 101 constructor() { | |
| 102 super(); | |
| 103 log.push(create_constructor_log(this)); | |
| 104 } | |
| 105 adoptedCallback(...args) { | |
| 106 log.push(create_adopted_callback_log(this, ...args)); | |
| 107 if (this == element1) | |
| 108 element3.setAttribute('id', 'foo'); | |
| 109 } | |
| 110 connectedCallback(...args) { | |
| 111 log.push(create_connected_callback_log(this, ...args)); | |
| 112 } | |
| 113 attributeChangedCallback(...args) { | |
| 114 log.push(create_attribute_changed_callback_log(this, ...args)); | |
| 115 } | |
| 116 static get observedAttributes() { return ['id', 'class']; } | |
| 117 } | |
| 118 | |
| 119 contentWindow.customElements.define('test-element', TestElement); | |
| 120 | |
| 121 let contentDocument = contentWindow.document; | |
| 122 element1 = contentDocument.createElement('test-element'); | |
| 123 element2 = contentDocument.createElement('test-element'); | |
| 124 element3 = contentDocument.createElement('test-element'); | |
| 125 assert_equals(Object.getPrototypeOf(element1), TestElement.prototype); | |
| 126 assert_equals(Object.getPrototypeOf(element2), TestElement.prototype); | |
| 127 assert_equals(Object.getPrototypeOf(element3), TestElement.prototype); | |
| 128 | |
| 129 assert_equals(log.length, 3); | |
| 130 assert_constructor_log_entry(log[0], element1); | |
| 131 assert_constructor_log_entry(log[1], element2); | |
| 132 assert_constructor_log_entry(log[2], element3); | |
| 133 log = []; | |
| 134 | |
| 135 const container = contentDocument.createElement('div'); | |
| 136 container.appendChild(element1); | |
| 137 container.appendChild(element2); | |
| 138 container.appendChild(element3); | |
| 139 | |
| 140 const anotherDocument = document.implementation.createHTMLDocument(); | |
| 141 anotherDocument.documentElement.appendChild(container); | |
| 142 | |
| 143 assert_equals(log.length, 7); | |
| 144 assert_adopted_log_entry(log[0], element1); | |
| 145 assert_adopted_log_entry(log[1], element3); | |
| 146 assert_connected_log_entry(log[2], element3); | |
| 147 assert_attribute_log_entry(log[3], {name: 'id', oldValue: null, newValue: 'f
oo', namespace: null}); | |
| 148 assert_connected_log_entry(log[4], element1); | |
| 149 assert_adopted_log_entry(log[5], element2); | |
| 150 assert_connected_log_entry(log[6], element2); | |
| 151 | |
| 152 }, 'Mutating another custom element inside adopted callback must invoke all pend
ing callbacks on the mutated element'); | |
| 153 | |
| 154 | |
| 155 </script> | |
| 156 </body> | |
| 157 </html> | |
| OLD | NEW |