layer-import.html (7425B)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>CSS Cascade Layers: Imports</title> 5 <meta name="assert" content="Import functionality of CSS Cascade Layers"> 6 <link rel="author" title="Antti Koivisto" href="mailto:antti@apple.com"> 7 <link rel="help" href="https://www.w3.org/TR/css-cascade-5/#layering"> 8 <script src="/resources/testharness.js"></script> 9 <script src="/resources/testharnessreport.js"></script> 10 </head> 11 <body> 12 <target class="first"></target> 13 <div id="log"></div> 14 <script> 15 16 // In all test cases, the rule specified as "color: green" should win. 17 const imports = { 18 "basic-green.css": ` 19 target { color: green; } 20 `, 21 "basic-red.css": ` 22 target { color: red; } 23 `, 24 "layer-green.css": ` 25 @layer { 26 target { color: green; } 27 } 28 `, 29 "layer-red.css": ` 30 @layer { 31 target { color: red; } 32 } 33 `, 34 "layer-A-green.css": ` 35 @layer A { 36 target { color: green; } 37 } 38 `, 39 "layer-A-red.css": ` 40 @layer A { 41 target { color: red; } 42 } 43 `, 44 "layer-B-green.css": ` 45 @layer B { 46 target { color: green; } 47 } 48 `, 49 "layer-B-red.css": ` 50 @layer B { 51 target { color: red; } 52 } 53 `, 54 }; 55 56 const testCases = [ 57 { 58 title: 'A1 Layer rules with import', 59 style: ` 60 @import url(basic-green.css); 61 @layer { 62 target { color: red; } 63 } 64 ` 65 }, 66 { 67 title: 'A2 Layer rules with import', 68 style: ` 69 @import url(layer-red.css); 70 target { color: green; } 71 ` 72 }, 73 { 74 title: 'A3 Layer rules with import', 75 style: ` 76 @import url(basic-green.css); 77 @import url(layer-red.css); 78 ` 79 }, 80 { 81 title: 'A4 Layer rules with import', 82 style: ` 83 @import url(layer-A-red.css); 84 @layer B { 85 target { color: green; } 86 } 87 @layer A { 88 target { color: red; } 89 } 90 ` 91 }, 92 { 93 title: 'B1 Anonymous imports', 94 style: ` 95 @import url(basic-red.css) layer; 96 target { color: green; } 97 ` 98 }, 99 { 100 title: 'B2 Anonymous imports', 101 style: ` 102 @import url(basic-red.css) layer; 103 @import url(basic-green.css) layer; 104 ` 105 }, 106 { 107 title: 'B3 Anonymous imports', 108 style: ` 109 @import url(basic-red.css) layer; 110 @layer { 111 target { color: green; } 112 } 113 ` 114 }, 115 { 116 title: 'B4 Anonymous imports', 117 style: ` 118 @import url(layer-red.css); 119 @import url(basic-green.css) layer; 120 ` 121 }, 122 { 123 title: 'C1 Named imports', 124 style: ` 125 @import url(basic-red.css) layer(A); 126 target { color: green; } 127 ` 128 }, 129 { 130 title: 'C2 Named imports', 131 style: ` 132 @import url(basic-red.css) layer(A); 133 @import url(basic-green.css) layer(A); 134 ` 135 }, 136 { 137 title: 'C3 Named imports', 138 style: ` 139 @import url(basic-red.css) layer(A); 140 @layer A { 141 target { color: green; } 142 } 143 ` 144 }, 145 { 146 title: 'C4 Named imports', 147 style: ` 148 @import url(layer-red.css) layer(A); 149 @layer A { 150 target { color: green; } 151 } 152 ` 153 }, 154 { 155 title: 'C5 Named imports', 156 style: ` 157 @import url(layer-A-red.css) layer(A); 158 @layer A.A { 159 target { color: green; } 160 } 161 ` 162 }, 163 { 164 title: 'C6 Named imports', 165 style: ` 166 @import url(layer-A-red.css) layer(A); 167 @layer B { 168 target { color: green; } 169 } 170 @layer A.B { 171 target { color: red; } 172 } 173 ` 174 }, 175 { 176 title: 'C7 Named imports', 177 style: ` 178 @import url(basic-green.css) layer(A); 179 @import url(basic-red.css) layer(B); 180 @import url(basic-green.css) layer(C); 181 ` 182 }, 183 { 184 title: 'C8 Named imports', 185 style: ` 186 @import url(basic-red.css) layer(A); 187 @import url(basic-green.css) layer(B); 188 @import url(basic-red.css) layer(A); 189 ` 190 }, 191 { 192 title: 'C9 Named imports', 193 style: ` 194 @import url(basic-red.css) layer(A); 195 @import url(basic-red.css) layer(B.A); 196 @import url(basic-green.css) layer(B); 197 ` 198 }, 199 { 200 title: 'D1 Layer statement with imports', 201 style: ` 202 @import url(basic-red.css) layer(A); 203 @import url(basic-green.css) layer(B); 204 @layer B, A; 205 ` 206 }, 207 { 208 title: 'D2 Layer statement with imports', 209 style: ` 210 @layer B; 211 @import url(basic-green.css) layer(A); 212 @layer B { 213 target { color: red; } 214 } 215 ` 216 }, 217 { 218 title: 'D3 Layer statement with imports', 219 style: ` 220 @layer B; 221 @import url(basic-green.css) layer(A); 222 @import url(basic-red.css) layer(B); 223 ` 224 }, 225 { 226 title: 'D4 Layer statement with imports', 227 style: ` 228 @layer C, B, A; 229 @import url(basic-green.css) layer(A); 230 @import url(basic-red.css) layer(B); 231 @layer C { 232 target { color: red; } 233 } 234 ` 235 }, 236 { 237 title: 'D5 Layer statement with imports', 238 style: ` 239 @layer A.B, A.A; 240 @import url(basic-green.css) layer(A.A); 241 @import url(layer-B-red.css) layer(A); 242 ` 243 }, 244 { 245 title: 'D6 Layer statement with imports', 246 style: ` 247 @layer B, A; 248 @import url(layer-A-red.css) layer(A); 249 @import url(layer-A-red.css) layer(B); 250 @layer A.B { 251 target { color: green; } 252 } 253 ` 254 }, 255 { 256 title: 'E1 Named imports establish layer even with network errors', 257 style: ` 258 @import "nonexist.css" layer(A); 259 @layer B { 260 target { color: green; } 261 } 262 @layer A { 263 target { color: red; } 264 } 265 `, 266 }, 267 ]; 268 269 for (let testCase of testCases) { 270 promise_test(async t => { 271 const styleElement = document.createElement('style'); 272 const styleText = testCase['style'].replaceAll(/url\((.+?)\)/g, (match, p1) => { 273 return `url(data:text/css,${ encodeURI(imports[p1]) })`; 274 }); 275 styleElement.textContent = styleText; 276 277 await new Promise(resolve => { 278 styleElement.onload = resolve; 279 styleElement.onerror = resolve; 280 document.head.append(styleElement); 281 }); 282 283 try { 284 const targets = document.querySelectorAll('target'); 285 for (target of targets) 286 assert_equals(window.getComputedStyle(target).color, 'rgb(0, 128, 0)', testCase['title'] + ", target '" + target.classList[0] + "'"); 287 } finally { 288 styleElement.remove(); 289 } 290 }, testCase['title']); 291 } 292 </script> 293 </body> 294 </html>