DOMTokenList.html (11683B)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>Custom Elements: CEReactions on DOMTokenList interface</title> 5 <meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org"> 6 <meta name="assert" content="add, remove, toggle, replace, and the stringifier of DOMTokenList interface must have CEReactions"> 7 <meta name="help" content="https://dom.spec.whatwg.org/#node"> 8 <script src="/resources/testharness.js"></script> 9 <script src="/resources/testharnessreport.js"></script> 10 <script src="../resources/custom-elements-helpers.js"></script> 11 <script src="./resources/reactions.js"></script> 12 </head> 13 <body> 14 <script> 15 16 test(function () { 17 var element = define_new_custom_element(['class']); 18 var instance = document.createElement(element.name); 19 assert_array_equals(element.takeLog().types(), ['constructed']); 20 instance.classList.add('foo'); 21 var logEntries = element.takeLog(); 22 assert_array_equals(logEntries.types(), ['attributeChanged']); 23 assert_attribute_log_entry(logEntries.last(), {name: 'class', oldValue: null, newValue: 'foo', namespace: null}); 24 }, 'add on DOMTokenList must enqueue an attributeChanged reaction when adding an attribute'); 25 26 test(function () { 27 var element = define_new_custom_element(['style']); 28 var instance = document.createElement(element.name); 29 assert_array_equals(element.takeLog().types(), ['constructed']); 30 instance.classList.add('foo'); 31 assert_array_equals(element.takeLog().types(), []); 32 }, 'add on DOMTokenList must not enqueue an attributeChanged reaction when adding an unobserved attribute'); 33 34 test(function () { 35 var element = define_new_custom_element(['class']); 36 var instance = document.createElement(element.name); 37 instance.setAttribute('class', 'hello'); 38 assert_array_equals(element.takeLog().types(), ['constructed', 'attributeChanged']); 39 instance.classList.add('world'); 40 var logEntries = element.takeLog(); 41 assert_array_equals(logEntries.types(), ['attributeChanged']); 42 assert_attribute_log_entry(logEntries.last(), {name: 'class', oldValue: 'hello', newValue: 'hello world', namespace: null}); 43 }, 'add on DOMTokenList must enqueue an attributeChanged reaction when adding a value to an existing attribute'); 44 45 test(function () { 46 var element = define_new_custom_element(['contenteditable']); 47 var instance = document.createElement(element.name); 48 instance.setAttribute('class', 'hello'); 49 assert_array_equals(element.takeLog().types(), ['constructed']); 50 instance.classList.add('world'); 51 assert_array_equals(element.takeLog().types(), []); 52 }, 'add on DOMTokenList must not enqueue an attributeChanged reaction when adding a value to an unobserved attribute'); 53 54 test(function () { 55 var element = define_new_custom_element(['class']); 56 var instance = document.createElement(element.name); 57 assert_array_equals(element.takeLog().types(), ['constructed']); 58 instance.classList.add('hello', 'world'); 59 var logEntries = element.takeLog(); 60 assert_array_equals(logEntries.types(), ['attributeChanged']); 61 assert_attribute_log_entry(logEntries.last(), {name: 'class', oldValue: null, newValue: 'hello world', namespace: null}); 62 }, 'add on DOMTokenList must enqueue exactly one attributeChanged reaction when adding multiple values to an attribute'); 63 64 test(function () { 65 var element = define_new_custom_element(['class']); 66 var instance = document.createElement(element.name); 67 instance.setAttribute('class', 'hello world'); 68 assert_array_equals(element.takeLog().types(), ['constructed', 'attributeChanged']); 69 instance.classList.remove('world'); 70 var logEntries = element.takeLog(); 71 assert_array_equals(logEntries.types(), ['attributeChanged']); 72 assert_attribute_log_entry(logEntries.last(), {name: 'class', oldValue: 'hello world', newValue: 'hello', namespace: null}); 73 }, 'remove on DOMTokenList must enqueue an attributeChanged reaction when removing a value from an attribute'); 74 75 test(function () { 76 var element = define_new_custom_element(['class']); 77 var instance = document.createElement(element.name); 78 instance.setAttribute('class', 'hello foo world bar'); 79 assert_array_equals(element.takeLog().types(), ['constructed', 'attributeChanged']); 80 instance.classList.remove('hello', 'world'); 81 var logEntries = element.takeLog(); 82 assert_array_equals(logEntries.types(), ['attributeChanged']); 83 assert_attribute_log_entry(logEntries.last(), {name: 'class', oldValue: 'hello foo world bar', newValue: 'foo bar', namespace: null}); 84 }, 'remove on DOMTokenList must enqueue exactly one attributeChanged reaction when removing multiple values to an attribute'); 85 86 test(function () { 87 var element = define_new_custom_element(['class']); 88 var instance = document.createElement(element.name); 89 instance.setAttribute('class', 'hello world'); 90 assert_array_equals(element.takeLog().types(), ['constructed', 'attributeChanged']); 91 instance.classList.remove('foo'); 92 var logEntries = element.takeLog(); 93 assert_array_equals(logEntries.types(), ['attributeChanged']); 94 assert_attribute_log_entry(logEntries.last(), {name: 'class', oldValue: 'hello world', newValue: 'hello world', namespace: null}); 95 }, 'remove on DOMTokenList must enqueue an attributeChanged reaction even when removing a non-existent value from an attribute'); 96 97 test(function () { 98 var element = define_new_custom_element(['title']); 99 var instance = document.createElement(element.name); 100 instance.setAttribute('class', 'hello world'); 101 assert_array_equals(element.takeLog().types(), ['constructed']); 102 instance.classList.remove('world'); 103 assert_array_equals(element.takeLog().types(), []); 104 }, 'remove on DOMTokenList must not enqueue an attributeChanged reaction when removing a value from an unobserved attribute'); 105 106 test(function () { 107 var element = define_new_custom_element(['class']); 108 var instance = document.createElement(element.name); 109 instance.setAttribute('class', 'hello'); 110 assert_array_equals(element.takeLog().types(), ['constructed', 'attributeChanged']); 111 instance.classList.toggle('world'); 112 var logEntries = element.takeLog(); 113 assert_array_equals(logEntries.types(), ['attributeChanged']); 114 assert_attribute_log_entry(logEntries.last(), {name: 'class', oldValue: 'hello', newValue: 'hello world', namespace: null}); 115 }, 'toggle on DOMTokenList must enqueue an attributeChanged reaction when adding a value to an attribute'); 116 117 test(function () { 118 var element = define_new_custom_element(['class']); 119 var instance = document.createElement(element.name); 120 instance.setAttribute('class', 'hello world'); 121 assert_array_equals(element.takeLog().types(), ['constructed', 'attributeChanged']); 122 instance.classList.toggle('world'); 123 var logEntries = element.takeLog(); 124 assert_array_equals(logEntries.types(), ['attributeChanged']); 125 assert_attribute_log_entry(logEntries.last(), {name: 'class', oldValue: 'hello world', newValue: 'hello', namespace: null}); 126 }, 'toggle on DOMTokenList must enqueue an attributeChanged reaction when removing a value from an attribute'); 127 128 test(function () { 129 var element = define_new_custom_element(['class']); 130 var instance = document.createElement(element.name); 131 instance.setAttribute('class', 'hello'); 132 assert_array_equals(element.takeLog().types(), ['constructed', 'attributeChanged']); 133 instance.classList.replace('hello', 'world'); 134 var logEntries = element.takeLog(); 135 assert_array_equals(logEntries.types(), ['attributeChanged']); 136 assert_attribute_log_entry(logEntries.last(), {name: 'class', oldValue: 'hello', newValue: 'world', namespace: null}); 137 }, 'replace on DOMTokenList must enqueue an attributeChanged reaction when replacing a value in an attribute'); 138 139 test(function () { 140 var element = define_new_custom_element(['class']); 141 var instance = document.createElement(element.name); 142 instance.setAttribute('class', 'hello world'); 143 assert_array_equals(element.takeLog().types(), ['constructed', 'attributeChanged']); 144 instance.classList.replace('foo', 'bar'); 145 assert_array_equals(element.takeLog().types(), []); 146 }, 'replace on DOMTokenList must not enqueue an attributeChanged reaction when the token to replace does not exist in the attribute'); 147 148 test(function () { 149 var element = define_new_custom_element(['title']); 150 var instance = document.createElement(element.name); 151 instance.setAttribute('class', 'hello'); 152 assert_array_equals(element.takeLog().types(), ['constructed']); 153 instance.classList.replace('hello', 'world'); 154 assert_array_equals(element.takeLog().types(), []); 155 }, 'replace on DOMTokenList must not enqueue an attributeChanged reaction when replacing a value in an unobserved attribute'); 156 157 test(function () { 158 var element = define_new_custom_element(['class']); 159 var instance = document.createElement(element.name); 160 assert_array_equals(element.takeLog().types(), ['constructed']); 161 instance.classList = 'hello'; 162 var logEntries = element.takeLog(); 163 assert_array_equals(logEntries.types(), ['attributeChanged']); 164 assert_attribute_log_entry(logEntries.last(), {name: 'class', oldValue: null, newValue: 'hello', namespace: null}); 165 }, 'the stringifier of DOMTokenList must enqueue an attributeChanged reaction when adding an observed attribute'); 166 167 test(function () { 168 var element = define_new_custom_element(['id']); 169 var instance = document.createElement(element.name); 170 instance.setAttribute('class', 'hello'); 171 assert_array_equals(element.takeLog().types(), ['constructed']); 172 instance.classList = 'hello'; 173 var logEntries = element.takeLog(); 174 assert_array_equals(element.takeLog().types(), []); 175 }, 'the stringifier of DOMTokenList must not enqueue an attributeChanged reaction when adding an unobserved attribute'); 176 177 test(function () { 178 var element = define_new_custom_element(['class']); 179 var instance = document.createElement(element.name); 180 instance.setAttribute('class', 'hello'); 181 assert_array_equals(element.takeLog().types(), ['constructed', 'attributeChanged']); 182 instance.classList = 'world'; 183 var logEntries = element.takeLog(); 184 assert_array_equals(logEntries.types(), ['attributeChanged']); 185 assert_attribute_log_entry(logEntries.last(), {name: 'class', oldValue: 'hello', newValue: 'world', namespace: null}); 186 }, 'the stringifier of DOMTokenList must enqueue an attributeChanged reaction when mutating the value of an observed attribute'); 187 188 test(function () { 189 var element = define_new_custom_element([]); 190 var instance = document.createElement(element.name); 191 instance.setAttribute('class', 'hello'); 192 assert_array_equals(element.takeLog().types(), ['constructed']); 193 instance.classList = 'world'; 194 assert_array_equals(element.takeLog().types(), []); 195 }, 'the stringifier of DOMTokenList must not enqueue an attributeChanged reaction when mutating the value of an unobserved attribute'); 196 197 test(function () { 198 var element = define_new_custom_element(['class']); 199 var instance = document.createElement(element.name); 200 instance.setAttribute('class', 'hello'); 201 assert_array_equals(element.takeLog().types(), ['constructed', 'attributeChanged']); 202 instance.classList = 'hello'; 203 var logEntries = element.takeLog(); 204 assert_array_equals(logEntries.types(), ['attributeChanged']); 205 assert_attribute_log_entry(logEntries.last(), {name: 'class', oldValue: 'hello', newValue: 'hello', namespace: null}); 206 }, 'the stringifier of DOMTokenList must enqueue an attributeChanged reaction when the setter is called with the original value of the attribute'); 207 208 </script> 209 </body> 210 </html>