layer-rules-cssom.html (3016B)
1 <!DOCTYPE html> 2 <title>The CSSOM API for Cascade Layers</title> 3 <link rel="help" href="https://drafts.csswg.org/css-cascade-5/#layer-apis"> 4 <link rel="author" href="mailto:xiaochengh@chromium.org"> 5 <script src="/resources/testharness.js"></script> 6 <script src="/resources/testharnessreport.js"></script> 7 <script> 8 const testCases = [ 9 { 10 style: `@layer foo { }`, 11 expectedNames: ['foo'], 12 title: 'Basic layer block name', 13 }, 14 { 15 style: `@layer { }`, 16 expectedNames: [''], 17 title: 'Anonymous layer block name', 18 }, 19 { 20 style: ` 21 @layer foo; 22 `, 23 expectedNames: [['foo']], 24 title: 'Basic layer statement name', 25 }, 26 { 27 style: ` 28 @layer foo, bar; 29 `, 30 expectedNames: [['foo', 'bar']], 31 title: 'Layer statement with multiple names', 32 }, 33 { 34 style: ` 35 @layer outer { 36 @layer foo.bar { } 37 } 38 @layer outer.foo.bar { } 39 `, 40 expectedNames: ['outer', 'foo.bar', 'outer.foo.bar'], 41 title: 'Nested layer block names', 42 }, 43 { 44 style: ` 45 @layer outer { 46 @layer foo.bar, baz; 47 } 48 @layer outer.foo.bar, outer.baz; 49 `, 50 expectedNames: ['outer', ['foo.bar', 'baz'], ['outer.foo.bar', 'outer.baz']], 51 title: 'Nested layer statement name lists', 52 }, 53 { 54 style: ` 55 @import url('data:text/css,') layer; 56 `, 57 expectedNames: [''], 58 title: 'Import into anonymous layer', 59 }, 60 { 61 style: ` 62 @import url('data:text/css,') layer(foo); 63 `, 64 expectedNames: ['foo'], 65 title: 'Import into named layer', 66 }, 67 { 68 style: ` 69 @import url('data:text/css,'); 70 `, 71 expectedNames: [null], 72 title: 'Import without layer', 73 }, 74 ]; 75 76 for (let testCase of testCases) { 77 promise_test(async function (t) { 78 assert_implements(window.CSSLayerBlockRule); 79 assert_implements(window.CSSLayerStatementRule); 80 81 const style = document.createElement('style'); 82 t.add_cleanup(() => style.remove()); 83 84 const isLoadAsync = testCase.style.includes("@import"); 85 const load = new Promise(resolve => { 86 style.addEventListener("load", resolve, { once: true }); 87 }); 88 89 style.appendChild(document.createTextNode(testCase.style)); 90 document.head.appendChild(style); 91 92 if (isLoadAsync) { 93 await load; 94 } 95 96 let index = 0; 97 function compareNames(ruleOrSheet) { 98 if (ruleOrSheet instanceof CSSLayerBlockRule) 99 assert_equals(ruleOrSheet.name, testCase.expectedNames[index++]); 100 else if (ruleOrSheet instanceof CSSImportRule) 101 assert_equals(ruleOrSheet.layerName, testCase.expectedNames[index++]); 102 else if (ruleOrSheet instanceof CSSLayerStatementRule) 103 assert_array_equals(ruleOrSheet.nameList, testCase.expectedNames[index++]); 104 if (ruleOrSheet.cssRules) { 105 for (let i = 0; i < ruleOrSheet.cssRules.length; ++i) 106 compareNames(ruleOrSheet.cssRules.item(i)); 107 } 108 } 109 compareNames(style.sheet); 110 assert_equals(index, testCase.expectedNames.length); 111 }, testCase.title); 112 } 113 </script>