serialize-consecutive-tokens.html (4748B)
1 <!doctype html> 2 <title>Serialization of consecutive tokens.</title> 3 <script src="/resources/testharness.js"></script> 4 <script src="/resources/testharnessreport.js"></script> 5 6 <meta name="author" title="Tab Atkins-Bittner"> 7 <link rel=help href="https://drafts.csswg.org/css-syntax/#serialization"> 8 <body> 9 <!-- 10 The serialization chapter provides a table listing all the combinations of consecutive tokens that will, 11 if naively serialized next to each other, 12 produce a different set of tokens when re-parsed. 13 The spec requires that a comment must be inserted between such tokens in the serialization, 14 to ensure that they round-trip correctly. 15 --> 16 17 <script> 18 19 function testTokenPairs(t1, t2) { 20 const b = document.body; 21 test(()=>{ 22 b.style.setProperty("--t1", t1); 23 b.style.setProperty("--t2", t2); 24 b.style.setProperty("--result", "var(--t1)var(--t2)"); 25 const result = getComputedStyle(b).getPropertyValue("--result"); 26 assert_equals(result.slice(0, t1.length), t1, `Result must start with ${t1}`); 27 assert_equals(result.slice(-t2.length), t2, `Result must end with ${t2}`); 28 assert_not_equals(result, t1+t2, `Result must have a comment between ${t1} and ${t2}`); 29 }, `Serialization of consecutive ${t1} and ${t2} tokens.`); 30 } 31 testTokenPairs("foo", "bar"); 32 testTokenPairs("foo", "bar()"); 33 testTokenPairs("foo", "url(bar)"); 34 testTokenPairs("foo", "-"); 35 testTokenPairs("foo", "123"); 36 testTokenPairs("foo", "123%"); 37 testTokenPairs("foo", "123em"); 38 testTokenPairs("foo", "-->"); 39 testTokenPairs("foo", "()"); 40 41 testTokenPairs("@foo", "bar"); 42 testTokenPairs("@foo", "bar()"); 43 testTokenPairs("@foo", "url(bar)"); 44 testTokenPairs("@foo", "-"); 45 testTokenPairs("@foo", "123"); 46 testTokenPairs("@foo", "123%"); 47 testTokenPairs("@foo", "123em"); 48 testTokenPairs("@foo", "-->"); 49 50 testTokenPairs("#foo", "bar"); 51 testTokenPairs("#foo", "bar()"); 52 testTokenPairs("#foo", "url(bar)"); 53 testTokenPairs("#foo", "-"); 54 testTokenPairs("#foo", "123"); 55 testTokenPairs("#foo", "123%"); 56 testTokenPairs("#foo", "123em"); 57 testTokenPairs("#foo", "-->"); 58 59 testTokenPairs("123foo", "bar"); 60 testTokenPairs("123foo", "bar()"); 61 testTokenPairs("123foo", "url(bar)"); 62 testTokenPairs("123foo", "-"); 63 testTokenPairs("123foo", "123"); 64 testTokenPairs("123foo", "123%"); 65 testTokenPairs("123foo", "123em"); 66 testTokenPairs("123foo", "-->"); 67 68 testTokenPairs("#", "bar"); 69 testTokenPairs("#", "bar()"); 70 testTokenPairs("#", "url(bar)"); 71 testTokenPairs("#", "-"); 72 testTokenPairs("#", "123"); 73 testTokenPairs("#", "123%"); 74 testTokenPairs("#", "123em"); 75 76 testTokenPairs("-", "bar"); 77 testTokenPairs("-", "bar()"); 78 testTokenPairs("-", "url(bar)"); 79 testTokenPairs("-", "-"); 80 testTokenPairs("-", "123"); 81 testTokenPairs("-", "123%"); 82 testTokenPairs("-", "123em"); 83 84 testTokenPairs("123", "bar"); 85 testTokenPairs("123", "bar()"); 86 testTokenPairs("123", "url(bar)"); 87 testTokenPairs("123", "123"); 88 testTokenPairs("123", "123%"); 89 testTokenPairs("123", "123em"); 90 testTokenPairs("123", "%"); 91 92 testTokenPairs("@", "bar"); 93 testTokenPairs("@", "bar()"); 94 testTokenPairs("@", "url(bar)"); 95 testTokenPairs("@", "-"); 96 97 testTokenPairs(".", "123"); 98 testTokenPairs(".", "123%"); 99 testTokenPairs(".", "123em"); 100 101 testTokenPairs("+", "123"); 102 testTokenPairs("+", "123%"); 103 testTokenPairs("+", "123em"); 104 105 testTokenPairs("/", "*"); 106 107 // Test that interior comments are preserved, but exterior ones are not. 108 function testComments(text, t1, expected) { 109 const b = document.body; 110 test(()=>{ 111 b.style.setProperty("--t1", t1); 112 b.style.setProperty("--result", text); 113 const result = getComputedStyle(b).getPropertyValue("--result"); 114 assert_equals(result, expected); 115 }, `Comments are handled correctly when computing ${text} using t1:${t1}.`); 116 } 117 testComments("a/* comment */b", "", "a/* comment */b"); 118 testComments("a/* comment */var(--t1)", "b", "a/**/b"); 119 testComments("var(--t1)b", "a/* comment */", "a/**/b"); 120 121 // Test comments within quotes. 122 testComments("var(--t1)b", "'a/* unfinished '", "'a/* unfinished 'b"); 123 testComments("var(--t1)b", "\"a/* unfinished \"", "\"a/* unfinished \"b"); 124 testComments("var(--t1)b", "'a \" '/* comment */", "'a \" 'b"); 125 126 test(()=>{ 127 const b = document.body; 128 b.style.setProperty("--t1", "a"); 129 b.style.setProperty("--t2", "b"); 130 b.style.setProperty("--result", "var(--t1)var(--does-not-exist,)var(--t2)"); 131 const result = getComputedStyle(b).getPropertyValue("--result"); 132 assert_equals(result[0], "a", `Result must start with a`); 133 assert_equals(result[result.length - 1], "b", `Result must end with b`); 134 assert_not_equals(result, "ab", `Result must have a comment between a and b`); 135 }, 'Empty fallback between tokens must not disturb comment insertion'); 136 137 </script>