determine-registration.html (6937B)
1 <!DOCTYPE html> 2 <link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api-1/#determining-registration"> 3 <script src="/resources/testharness.js"></script> 4 <script src="/resources/testharnessreport.js"></script> 5 <script src="./resources/utils.js"></script> 6 <div id=outer> 7 <div id=div></div> 8 </div> 9 <script> 10 11 test_with_at_property({ 12 syntax: '"<length>"', 13 inherits: false, 14 initialValue: '1px' 15 }, (name) => { 16 assert_equals(getComputedStyle(div).getPropertyValue(name), '1px'); 17 }, '@property determines the registration when uncontested'); 18 19 test_with_at_property({ 20 syntax: '"<length>"', 21 inherits: false, 22 initialValue: '2px' 23 }, (name) => { 24 CSS.registerProperty({ 25 name: name, 26 syntax: '<color>', 27 inherits: false, 28 initialValue: 'green' 29 }); 30 assert_equals(getComputedStyle(div).getPropertyValue(name), 'rgb(0, 128, 0)'); 31 }, 'CSS.registerProperty wins over @property'); 32 33 test_with_at_property({ 34 syntax: '"<length>"', 35 inherits: false, 36 initialValue: '3px' 37 }, (name1) => { 38 with_at_property({ 39 name: name1, 40 syntax: '"<integer>"', 41 inherits: false, 42 initialValue: '6' 43 }, (name2) => { 44 assert_equals(name1, name2); 45 assert_equals(getComputedStyle(div).getPropertyValue(name2), '6'); 46 }); 47 }, '@property later in document order wins'); 48 49 test_with_at_property({ 50 syntax: '"<length>"', 51 inherits: false, 52 initialValue: '10px' 53 }, (name1) => { 54 with_at_property({ 55 name: name1, 56 syntax: '"<length>"', 57 inherits: true, 58 initialValue: '20px' 59 }, (name2) => { 60 assert_equals(name1, name2); 61 assert_equals(getComputedStyle(div).getPropertyValue(name2), '20px'); 62 }); 63 }, '@property later in document order wins (overridding definition with inherits=true)'); 64 65 test_with_at_property({ 66 syntax: '"<length>"', 67 inherits: true, 68 initialValue: '10px' 69 }, (name1) => { 70 with_at_property({ 71 name: name1, 72 syntax: '"<length>"', 73 inherits: false, 74 initialValue: '20px' 75 }, (name2) => { 76 assert_equals(name1, name2); 77 assert_equals(getComputedStyle(div).getPropertyValue(name2), '20px'); 78 }); 79 }, '@property later in document order wins (overridding definition with inherits=false)'); 80 81 test(() => { 82 let name = generate_name(); 83 84 with_style_node(` 85 @property ${name} { 86 syntax: "<length>"; 87 inherits: false; 88 initial-value: 4px; 89 } 90 91 @property ${name} { 92 syntax: "<color>"; 93 inherits: false; 94 initial-value: red; 95 } 96 `, () => { 97 assert_equals(getComputedStyle(div).getPropertyValue(name), 'rgb(255, 0, 0)'); 98 }); 99 }, '@property later in stylesheet wins'); 100 101 test(() => { 102 let name = generate_name(); 103 CSS.registerProperty({ 104 name: name, 105 syntax: '<color>', 106 inherits: false, 107 initialValue: 'green' 108 }); 109 assert_equals(getComputedStyle(div).getPropertyValue(name), 'rgb(0, 128, 0)'); 110 }, 'CSS.registerProperty determines the registration when uncontested'); 111 112 test(() => { 113 let name = generate_name(); 114 115 // ${name} is initially not registered, hence has no initial value. 116 assert_equals(getComputedStyle(div).getPropertyValue(name), ''); 117 118 with_at_property({ 119 name: name, 120 syntax: '"<length>"', 121 inherits: false, 122 initialValue: '10px' 123 }, () => { 124 assert_equals(getComputedStyle(div).getPropertyValue(name), '10px'); 125 }); 126 127 // When the style node is removed, ${name} should be unregistered again. 128 assert_equals(getComputedStyle(div).getPropertyValue(name), ''); 129 }, '@property registrations are cleared when rule removed'); 130 131 test(() => { 132 let name = generate_name(); 133 134 with_style_node(`div { ${name}: calc(1px + 1px); }`, () => { 135 // ${name} should be a token sequence at this point. 136 assert_equals(getComputedStyle(div).getPropertyValue(name), 'calc(1px + 1px)'); 137 138 with_at_property({ 139 name: name, 140 syntax: '"<length>"', 141 inherits: false, 142 initialValue: '0px' 143 }, () => { 144 // ${name} is now a <length>, hence the calc() should be simplified. 145 assert_equals(getComputedStyle(div).getPropertyValue(name), '2px'); 146 }); 147 148 // ${name} should be a token sequence again. 149 assert_equals(getComputedStyle(div).getPropertyValue(name), 'calc(1px + 1px)'); 150 }); 151 }, 'Computed value becomes token sequence when @property is removed'); 152 153 test(() => { 154 let name = generate_name(); 155 156 with_style_node(`#outer { ${name}: 10px; }`, () => { 157 assert_equals(getComputedStyle(div).getPropertyValue(name), '10px'); 158 159 with_at_property({ 160 name: name, 161 syntax: '"<length>"', 162 inherits: false, 163 initialValue: '0px' 164 }, () => { 165 // ${name} is no longer inherited 166 assert_equals(getComputedStyle(div).getPropertyValue(name), '0px'); 167 }); 168 169 assert_equals(getComputedStyle(div).getPropertyValue(name), '10px'); 170 }); 171 }, 'Inherited status is reflected in computed styles when @property is removed'); 172 173 test(() => { 174 let name = generate_name(); 175 176 with_style_node(` 177 @property ${name} { 178 syntax: "<length>"; 179 inherits: false; 180 initial-value: 1px; 181 } 182 183 @property ${name} { 184 inherits: false; 185 initial-value: green; 186 } 187 `, () => { 188 assert_equals(getComputedStyle(div).getPropertyValue(name), '1px'); 189 }); 190 }, 'Invalid @property rule (missing syntax) does not overwrite previous valid rule'); 191 192 test(() => { 193 let name = generate_name(); 194 195 with_style_node(` 196 @property ${name} { 197 syntax: "<length>"; 198 inherits: false; 199 initial-value: 1px; 200 } 201 202 @property ${name} { 203 syntax: "<color>"; 204 initial-value: green; 205 } 206 `, () => { 207 assert_equals(getComputedStyle(div).getPropertyValue(name), '1px'); 208 }); 209 }, 'Invalid @property rule (missing inherits descriptor) does not overwrite previous valid rule'); 210 211 test(() => { 212 let name = generate_name(); 213 214 with_style_node(` 215 @property ${name} { 216 syntax: "<length>"; 217 inherits: false; 218 initial-value: 1px; 219 } 220 221 @property ${name} { 222 syntax: "<color>"; 223 inherits: false; 224 } 225 `, () => { 226 assert_equals(getComputedStyle(div).getPropertyValue(name), '1px'); 227 }); 228 }, 'Invalid @property rule (missing initial-value) does not overwrite previous valid rule'); 229 230 test(() => { 231 let name = generate_name(); 232 233 with_style_node(` 234 @property ${name} { 235 syntax: "<color>"; 236 inherits: false; 237 } 238 239 @property ${name} { 240 syntax: "<length>"; 241 inherits: false; 242 initial-value: 1px; 243 } 244 `, () => { 245 assert_equals(getComputedStyle(div).getPropertyValue(name), '1px'); 246 }); 247 }, 'Previous invalid rule does not prevent valid rule from causing registration'); 248 249 test(() => { 250 let name = generate_name(); 251 252 with_style_node(` 253 @property ${name} { 254 syntax: "<length>"; 255 inherits: false; 256 initial-value: 1px; 257 quite-unknown: 200; 258 } 259 `, () => { 260 assert_equals(getComputedStyle(div).getPropertyValue(name), '1px'); 261 }); 262 }, 'Unknown descriptors are ignored and do not invalidate rule'); 263 264 </script>