crass 0.2.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +4 -0
  3. data/HISTORY.md +22 -1
  4. data/LICENSE +1 -1
  5. data/README.md +64 -72
  6. data/Rakefile +4 -0
  7. data/crass.gemspec +2 -2
  8. data/lib/crass.rb +1 -1
  9. data/lib/crass/parser.rb +231 -96
  10. data/lib/crass/scanner.rb +21 -21
  11. data/lib/crass/token-scanner.rb +8 -1
  12. data/lib/crass/tokenizer.rb +133 -131
  13. data/lib/crass/version.rb +1 -1
  14. data/test/css-parsing-tests/An+B.json +156 -0
  15. data/test/css-parsing-tests/LICENSE +8 -0
  16. data/test/css-parsing-tests/README.rst +301 -0
  17. data/test/css-parsing-tests/color3.json +142 -0
  18. data/test/css-parsing-tests/color3_hsl.json +3890 -0
  19. data/test/css-parsing-tests/color3_keywords.json +803 -0
  20. data/test/css-parsing-tests/component_value_list.json +432 -0
  21. data/test/css-parsing-tests/declaration_list.json +44 -0
  22. data/test/css-parsing-tests/make_color3_hsl.py +17 -0
  23. data/test/css-parsing-tests/make_color3_keywords.py +191 -0
  24. data/test/css-parsing-tests/one_component_value.json +27 -0
  25. data/test/css-parsing-tests/one_declaration.json +46 -0
  26. data/test/css-parsing-tests/one_rule.json +36 -0
  27. data/test/css-parsing-tests/rule_list.json +48 -0
  28. data/test/css-parsing-tests/stylesheet.json +44 -0
  29. data/test/css-parsing-tests/stylesheet_bytes.json +146 -0
  30. data/test/shared/parse_rules.rb +377 -434
  31. data/test/support/common.rb +124 -0
  32. data/test/support/serialization/animate.css +3158 -0
  33. data/test/support/serialization/html5-boilerplate.css +268 -0
  34. data/test/support/serialization/misc.css +9 -0
  35. data/test/test_css_parsing_tests.rb +150 -0
  36. data/test/test_parse_properties.rb +136 -211
  37. data/test/test_parse_rules.rb +0 -52
  38. data/test/test_parse_stylesheet.rb +0 -39
  39. data/test/test_serialization.rb +13 -4
  40. metadata +44 -7
  41. data/test/test_tokenizer.rb +0 -1562
@@ -0,0 +1,17 @@
1
+ import colorsys # It turns out Python already does HSL -> RGB!
2
+ trim = lambda s: s if not s.endswith('.0') else s[:-2]
3
+ print('[')
4
+ print(',\n'.join(
5
+ '"hsl%s(%s, %s%%, %s%%%s)", [%s, %s, %s, %s]' % (
6
+ ('a' if a is not None else '', h, trim(str(s/10.)), trim(str(l/10.)),
7
+ ', %s' % a if a is not None else '')
8
+ + tuple(trim(str(round(v, 10)))
9
+ for v in colorsys.hls_to_rgb(h/360., l/1000., s/1000.))
10
+ + (a if a is not None else 1,)
11
+ )
12
+ for a in [None, 1, .2, 0]
13
+ for l in range(0, 1001, 125)
14
+ for s in range(0, 1001, 125)
15
+ for h in range(0, 360, 30)
16
+ ))
17
+ print(']')
@@ -0,0 +1,191 @@
1
+ all_keywords = [
2
+ ('transparent', (0, 0, 0, 0)),
3
+
4
+ ('black', (0, 0, 0, 1)),
5
+ ('silver', (192, 192, 192, 1)),
6
+ ('gray', (128, 128, 128, 1)),
7
+ ('white', (255, 255, 255, 1)),
8
+ ('maroon', (128, 0, 0, 1)),
9
+ ('red', (255, 0, 0, 1)),
10
+ ('purple', (128, 0, 128, 1)),
11
+ ('fuchsia', (255, 0, 255, 1)),
12
+ ('green', (0, 128, 0, 1)),
13
+ ('lime', (0, 255, 0, 1)),
14
+ ('olive', (128, 128, 0, 1)),
15
+ ('yellow', (255, 255, 0, 1)),
16
+ ('navy', (0, 0, 128, 1)),
17
+ ('blue', (0, 0, 255, 1)),
18
+ ('teal', (0, 128, 128, 1)),
19
+ ('aqua', (0, 255, 255, 1)),
20
+
21
+ ('aliceblue', (240, 248, 255, 1)),
22
+ ('antiquewhite', (250, 235, 215, 1)),
23
+ ('aqua', (0, 255, 255, 1)),
24
+ ('aquamarine', (127, 255, 212, 1)),
25
+ ('azure', (240, 255, 255, 1)),
26
+ ('beige', (245, 245, 220, 1)),
27
+ ('bisque', (255, 228, 196, 1)),
28
+ ('black', (0, 0, 0, 1)),
29
+ ('blanchedalmond', (255, 235, 205, 1)),
30
+ ('blue', (0, 0, 255, 1)),
31
+ ('blueviolet', (138, 43, 226, 1)),
32
+ ('brown', (165, 42, 42, 1)),
33
+ ('burlywood', (222, 184, 135, 1)),
34
+ ('cadetblue', (95, 158, 160, 1)),
35
+ ('chartreuse', (127, 255, 0, 1)),
36
+ ('chocolate', (210, 105, 30, 1)),
37
+ ('coral', (255, 127, 80, 1)),
38
+ ('cornflowerblue', (100, 149, 237, 1)),
39
+ ('cornsilk', (255, 248, 220, 1)),
40
+ ('crimson', (220, 20, 60, 1)),
41
+ ('cyan', (0, 255, 255, 1)),
42
+ ('darkblue', (0, 0, 139, 1)),
43
+ ('darkcyan', (0, 139, 139, 1)),
44
+ ('darkgoldenrod', (184, 134, 11, 1)),
45
+ ('darkgray', (169, 169, 169, 1)),
46
+ ('darkgreen', (0, 100, 0, 1)),
47
+ ('darkgrey', (169, 169, 169, 1)),
48
+ ('darkkhaki', (189, 183, 107, 1)),
49
+ ('darkmagenta', (139, 0, 139, 1)),
50
+ ('darkolivegreen', (85, 107, 47, 1)),
51
+ ('darkorange', (255, 140, 0, 1)),
52
+ ('darkorchid', (153, 50, 204, 1)),
53
+ ('darkred', (139, 0, 0, 1)),
54
+ ('darksalmon', (233, 150, 122, 1)),
55
+ ('darkseagreen', (143, 188, 143, 1)),
56
+ ('darkslateblue', (72, 61, 139, 1)),
57
+ ('darkslategray', (47, 79, 79, 1)),
58
+ ('darkslategrey', (47, 79, 79, 1)),
59
+ ('darkturquoise', (0, 206, 209, 1)),
60
+ ('darkviolet', (148, 0, 211, 1)),
61
+ ('deeppink', (255, 20, 147, 1)),
62
+ ('deepskyblue', (0, 191, 255, 1)),
63
+ ('dimgray', (105, 105, 105, 1)),
64
+ ('dimgrey', (105, 105, 105, 1)),
65
+ ('dodgerblue', (30, 144, 255, 1)),
66
+ ('firebrick', (178, 34, 34, 1)),
67
+ ('floralwhite', (255, 250, 240, 1)),
68
+ ('forestgreen', (34, 139, 34, 1)),
69
+ ('fuchsia', (255, 0, 255, 1)),
70
+ ('gainsboro', (220, 220, 220, 1)),
71
+ ('ghostwhite', (248, 248, 255, 1)),
72
+ ('gold', (255, 215, 0, 1)),
73
+ ('goldenrod', (218, 165, 32, 1)),
74
+ ('gray', (128, 128, 128, 1)),
75
+ ('green', (0, 128, 0, 1)),
76
+ ('greenyellow', (173, 255, 47, 1)),
77
+ ('grey', (128, 128, 128, 1)),
78
+ ('honeydew', (240, 255, 240, 1)),
79
+ ('hotpink', (255, 105, 180, 1)),
80
+ ('indianred', (205, 92, 92, 1)),
81
+ ('indigo', (75, 0, 130, 1)),
82
+ ('ivory', (255, 255, 240, 1)),
83
+ ('khaki', (240, 230, 140, 1)),
84
+ ('lavender', (230, 230, 250, 1)),
85
+ ('lavenderblush', (255, 240, 245, 1)),
86
+ ('lawngreen', (124, 252, 0, 1)),
87
+ ('lemonchiffon', (255, 250, 205, 1)),
88
+ ('lightblue', (173, 216, 230, 1)),
89
+ ('lightcoral', (240, 128, 128, 1)),
90
+ ('lightcyan', (224, 255, 255, 1)),
91
+ ('lightgoldenrodyellow', (250, 250, 210, 1)),
92
+ ('lightgray', (211, 211, 211, 1)),
93
+ ('lightgreen', (144, 238, 144, 1)),
94
+ ('lightgrey', (211, 211, 211, 1)),
95
+ ('lightpink', (255, 182, 193, 1)),
96
+ ('lightsalmon', (255, 160, 122, 1)),
97
+ ('lightseagreen', (32, 178, 170, 1)),
98
+ ('lightskyblue', (135, 206, 250, 1)),
99
+ ('lightslategray', (119, 136, 153, 1)),
100
+ ('lightslategrey', (119, 136, 153, 1)),
101
+ ('lightsteelblue', (176, 196, 222, 1)),
102
+ ('lightyellow', (255, 255, 224, 1)),
103
+ ('lime', (0, 255, 0, 1)),
104
+ ('limegreen', (50, 205, 50, 1)),
105
+ ('linen', (250, 240, 230, 1)),
106
+ ('magenta', (255, 0, 255, 1)),
107
+ ('maroon', (128, 0, 0, 1)),
108
+ ('mediumaquamarine', (102, 205, 170, 1)),
109
+ ('mediumblue', (0, 0, 205, 1)),
110
+ ('mediumorchid', (186, 85, 211, 1)),
111
+ ('mediumpurple', (147, 112, 219, 1)),
112
+ ('mediumseagreen', (60, 179, 113, 1)),
113
+ ('mediumslateblue', (123, 104, 238, 1)),
114
+ ('mediumspringgreen', (0, 250, 154, 1)),
115
+ ('mediumturquoise', (72, 209, 204, 1)),
116
+ ('mediumvioletred', (199, 21, 133, 1)),
117
+ ('midnightblue', (25, 25, 112, 1)),
118
+ ('mintcream', (245, 255, 250, 1)),
119
+ ('mistyrose', (255, 228, 225, 1)),
120
+ ('moccasin', (255, 228, 181, 1)),
121
+ ('navajowhite', (255, 222, 173, 1)),
122
+ ('navy', (0, 0, 128, 1)),
123
+ ('oldlace', (253, 245, 230, 1)),
124
+ ('olive', (128, 128, 0, 1)),
125
+ ('olivedrab', (107, 142, 35, 1)),
126
+ ('orange', (255, 165, 0, 1)),
127
+ ('orangered', (255, 69, 0, 1)),
128
+ ('orchid', (218, 112, 214, 1)),
129
+ ('palegoldenrod', (238, 232, 170, 1)),
130
+ ('palegreen', (152, 251, 152, 1)),
131
+ ('paleturquoise', (175, 238, 238, 1)),
132
+ ('palevioletred', (219, 112, 147, 1)),
133
+ ('papayawhip', (255, 239, 213, 1)),
134
+ ('peachpuff', (255, 218, 185, 1)),
135
+ ('peru', (205, 133, 63, 1)),
136
+ ('pink', (255, 192, 203, 1)),
137
+ ('plum', (221, 160, 221, 1)),
138
+ ('powderblue', (176, 224, 230, 1)),
139
+ ('purple', (128, 0, 128, 1)),
140
+ ('red', (255, 0, 0, 1)),
141
+ ('rosybrown', (188, 143, 143, 1)),
142
+ ('royalblue', (65, 105, 225, 1)),
143
+ ('saddlebrown', (139, 69, 19, 1)),
144
+ ('salmon', (250, 128, 114, 1)),
145
+ ('sandybrown', (244, 164, 96, 1)),
146
+ ('seagreen', (46, 139, 87, 1)),
147
+ ('seashell', (255, 245, 238, 1)),
148
+ ('sienna', (160, 82, 45, 1)),
149
+ ('silver', (192, 192, 192, 1)),
150
+ ('skyblue', (135, 206, 235, 1)),
151
+ ('slateblue', (106, 90, 205, 1)),
152
+ ('slategray', (112, 128, 144, 1)),
153
+ ('slategrey', (112, 128, 144, 1)),
154
+ ('snow', (255, 250, 250, 1)),
155
+ ('springgreen', (0, 255, 127, 1)),
156
+ ('steelblue', (70, 130, 180, 1)),
157
+ ('tan', (210, 180, 140, 1)),
158
+ ('teal', (0, 128, 128, 1)),
159
+ ('thistle', (216, 191, 216, 1)),
160
+ ('tomato', (255, 99, 71, 1)),
161
+ ('turquoise', (64, 224, 208, 1)),
162
+ ('violet', (238, 130, 238, 1)),
163
+ ('wheat', (245, 222, 179, 1)),
164
+ ('white', (255, 255, 255, 1)),
165
+ ('whitesmoke', (245, 245, 245, 1)),
166
+ ('yellow', (255, 255, 0, 1)),
167
+ ('yellowgreen', (154, 205, 50, 1)),
168
+ ]
169
+
170
+
171
+ def replace(s, i, r):
172
+ i %= len(s)
173
+ return s[:i] + r(s[i]) + s[i + 1:]
174
+
175
+ print('[')
176
+ print(',\n'.join(
177
+ '"%s", %s' % (css, list(rgba) if valid else 'null')
178
+ for i, (keyword, rgba) in enumerate(all_keywords)
179
+ for css, valid, run in [
180
+ (keyword, True, True),
181
+ (replace(keyword, i, str.upper), True, True),
182
+ (replace(keyword, i, lambda c: r'\\' + c), True,
183
+ keyword[i % len(keyword)] not in 'abcdef'),
184
+ (replace(keyword, i, lambda c: r'\\%X ' % ord(c)), True, True),
185
+ (replace(keyword, i, lambda c: ''), False, True),
186
+ # Kelving sign: u'K'.lower() == u'k', but should not match in CSS
187
+ (keyword.replace('k', u'K'), False, 'k' in keyword)
188
+ ]
189
+ if run
190
+ ))
191
+ print(']')
@@ -0,0 +1,27 @@
1
+ [
2
+
3
+ "", ["error", "empty"],
4
+ " ", ["error", "empty"],
5
+ "/**/", ["error", "empty"],
6
+ " /**/\t/* a */\n\n", ["error", "empty"],
7
+
8
+ ".", ".",
9
+ "a", ["ident", "a"],
10
+ "/**/ 4px", ["dimension", "4", 4, "integer", "px"],
11
+ "rgba(100%, 0%, 50%, .5)", ["function", "rgba",
12
+ ["percentage", "100", 100, "integer"], ",", " ",
13
+ ["percentage", "0", 0, "integer"], ",", " ",
14
+ ["percentage", "50", 50, "integer"], ",", " ",
15
+ ["number", ".5", 0.5, "number"]
16
+ ],
17
+
18
+ " /**/ { foo: bar; @baz [)", ["{}",
19
+ " ", ["ident", "foo"], ":", " ", ["ident", "bar"], ";", " ",
20
+ ["at-keyword", "baz"], " ", ["[]",
21
+ ["error", ")"]
22
+ ]
23
+ ],
24
+
25
+ ".foo", ["error", "extra-input"]
26
+
27
+ ]
@@ -0,0 +1,46 @@
1
+ [
2
+
3
+ "", ["error", "empty"],
4
+ " /**/\n", ["error", "empty"],
5
+ " ;", ["error", "invalid"],
6
+ "foo", ["error", "invalid"],
7
+ "@foo:", ["error", "invalid"],
8
+ "#foo:", ["error", "invalid"],
9
+ ".foo:", ["error", "invalid"],
10
+ "foo*:", ["error", "invalid"],
11
+ "foo.. 9000", ["error", "invalid"],
12
+ "foo:", ["declaration", "foo", [], false],
13
+ "foo :", ["declaration", "foo", [], false],
14
+ "\n/**/ foo: ", ["declaration", "foo", [" "], false],
15
+ "foo:;", ["declaration", "foo", [";"], false],
16
+ " /**/ foo /**/ :", ["declaration", "foo", [], false],
17
+ "foo:;bar:;", ["declaration", "foo", [";", ["ident", "bar"], ":", ";"], false],
18
+
19
+ "foo: 9000 !Important", ["declaration", "foo", [
20
+ " ", ["number", "9000", 9000, "integer"], " "
21
+ ], true],
22
+ "foo: 9000 ! /**/\t IMPORTant /**/\f", ["declaration", "foo", [
23
+ " ", ["number", "9000", 9000, "integer"], " "
24
+ ], true],
25
+
26
+ "foo: 9000 /* Dotted capital I */!İmportant", ["declaration", "foo", [
27
+ " ", ["number", "9000", 9000, "integer"], " ", "!", ["ident", "İmportant"]
28
+ ], false],
29
+ "foo: 9000 !important!", ["declaration", "foo", [
30
+ " ", ["number", "9000", 9000, "integer"], " ", "!", ["ident", "important"], "!"
31
+ ], false],
32
+
33
+ "foo: 9000 important", ["declaration", "foo", [
34
+ " ", ["number", "9000", 9000, "integer"], " ", ["ident", "important"]
35
+ ], false],
36
+ "foo:important", ["declaration", "foo", [
37
+ ["ident", "important"]
38
+ ], false],
39
+
40
+ "foo: 9000 @bar{ !important", ["declaration", "foo", [
41
+ " ", ["number", "9000", 9000, "integer"], " ", ["at-keyword", "bar"], ["{}",
42
+ " ", "!", ["ident", "important"]
43
+ ]
44
+ ], false]
45
+
46
+ ]
@@ -0,0 +1,36 @@
1
+ [
2
+
3
+ "", ["error", "empty"],
4
+ "foo", ["error", "invalid"],
5
+ "foo 4", ["error", "invalid"],
6
+
7
+ "@foo", ["at-rule", "foo", [], null],
8
+
9
+ "@foo bar; \t/* comment */", ["at-rule", "foo", [" ", ["ident", "bar"]], null],
10
+ " /**/ @foo bar{[(4", ["at-rule", "foo",
11
+ [" ", ["ident", "bar"]],
12
+ [["[]", ["()", ["number", "4", 4, "integer"]]]]
13
+ ],
14
+
15
+ "@foo { bar", ["at-rule", "foo", [" "], [" ", ["ident", "bar"]]],
16
+ "@foo [ bar", ["at-rule", "foo", [" ", ["[]", " ", ["ident", "bar"]]], null],
17
+
18
+ " /**/ div > p { color: #aaa; } /**/ ", ["qualified rule",
19
+ [["ident", "div"], " ", ">", " ", ["ident", "p"], " "],
20
+ [" ", ["ident", "color"], ":", " ", ["hash", "aaa", "id"], ";", " "]
21
+ ],
22
+
23
+ " /**/ { color: #aaa ", ["qualified rule",
24
+ [],
25
+ [" ", ["ident", "color"], ":", " ", ["hash", "aaa", "id"], " "]
26
+ ],
27
+
28
+ " /* CDO/CDC are not special */ <!-- --> {", ["qualified rule",
29
+ ["<!--", " ", "-->", " "], []
30
+ ],
31
+
32
+ "div { color: #aaa; } p{}", ["error", "extra-input"],
33
+ "div {} -->", ["error", "extra-input"],
34
+ "{}a", ["error", "extra-input"]
35
+
36
+ ]
@@ -0,0 +1,48 @@
1
+ [
2
+
3
+ "", [],
4
+ "foo", [["error", "invalid"]],
5
+ "foo 4", [["error", "invalid"]],
6
+
7
+ "@foo", [["at-rule", "foo", [], null]],
8
+
9
+ "@foo bar; \t/* comment */", [["at-rule", "foo", [" ", ["ident", "bar"]], null]],
10
+
11
+ " /**/ @foo bar{[(4", [["at-rule", "foo",
12
+ [" ", ["ident", "bar"]],
13
+ [["[]", ["()", ["number", "4", 4, "integer"]]]]
14
+ ]],
15
+
16
+ "@foo { bar", [["at-rule", "foo", [" "], [" ", ["ident", "bar"]]]],
17
+ "@foo [ bar", [["at-rule", "foo", [" ", ["[]", " ", ["ident", "bar"]]], null]],
18
+
19
+ " /**/ div > p { color: #aaa; } /**/ ", [["qualified rule",
20
+ [["ident", "div"], " ", ">", " ", ["ident", "p"], " "],
21
+ [" ", ["ident", "color"], ":", " ", ["hash", "aaa", "id"], ";", " "]
22
+ ]],
23
+
24
+ " /**/ { color: #aaa ", [["qualified rule",
25
+ [],
26
+ [" ", ["ident", "color"], ":", " ", ["hash", "aaa", "id"], " "]
27
+ ]],
28
+
29
+ " /* CDO/CDC are not special */ <!-- --> {", [["qualified rule",
30
+ ["<!--", " ", "-->", " "], []
31
+ ]],
32
+
33
+ "div { color: #aaa; } p{}", [
34
+ ["qualified rule", [["ident", "div"], " "],
35
+ [" ", ["ident", "color"], ":", " ", ["hash", "aaa", "id"], ";", " "]
36
+ ],
37
+ ["qualified rule", [["ident", "p"]], []]
38
+ ],
39
+
40
+ "div {} -->", [
41
+ ["qualified rule", [["ident", "div"], " "], []],
42
+ ["error", "invalid"]
43
+ ],
44
+
45
+ "{}a", [["qualified rule", [], []], ["error", "invalid"]],
46
+ "{}@a", [["qualified rule", [], []], ["at-rule", "a", [], null]]
47
+
48
+ ]
@@ -0,0 +1,44 @@
1
+ [
2
+
3
+ "", [],
4
+ "foo", [["error", "invalid"]],
5
+ "foo 4", [["error", "invalid"]],
6
+
7
+ "@foo", [["at-rule", "foo", [], null]],
8
+
9
+ "@foo bar; \t/* comment */", [["at-rule", "foo", [" ", ["ident", "bar"]], null]],
10
+
11
+ " /**/ @foo bar{[(4", [["at-rule", "foo",
12
+ [" ", ["ident", "bar"]],
13
+ [["[]", ["()", ["number", "4", 4, "integer"]]]]
14
+ ]],
15
+
16
+ "@foo { bar", [["at-rule", "foo", [" "], [" ", ["ident", "bar"]]]],
17
+ "@foo [ bar", [["at-rule", "foo", [" ", ["[]", " ", ["ident", "bar"]]], null]],
18
+
19
+ " /**/ div > p { color: #aaa; } /**/ ", [["qualified rule",
20
+ [["ident", "div"], " ", ">", " ", ["ident", "p"], " "],
21
+ [" ", ["ident", "color"], ":", " ", ["hash", "aaa", "id"], ";", " "]
22
+ ]],
23
+
24
+ " /**/ { color: #aaa ", [["qualified rule",
25
+ [],
26
+ [" ", ["ident", "color"], ":", " ", ["hash", "aaa", "id"], " "]
27
+ ]],
28
+
29
+ " /* CDO/CDC are ignored between rules */ <!-- --> {", [["qualified rule", [], []]],
30
+ " <!-- --> a<!---->{", [["qualified rule", [["ident", "a"], "<!--", "-->"], []]],
31
+
32
+ "div { color: #aaa; } p{}", [
33
+ ["qualified rule", [["ident", "div"], " "],
34
+ [" ", ["ident", "color"], ":", " ", ["hash", "aaa", "id"], ";", " "]
35
+ ],
36
+ ["qualified rule", [["ident", "p"]], []]
37
+ ],
38
+
39
+ "div {} -->", [["qualified rule", [["ident", "div"], " "], []]],
40
+
41
+ "{}a", [["qualified rule", [], []], ["error", "invalid"]],
42
+ "{}@a", [["qualified rule", [], []], ["at-rule", "a", [], null]]
43
+
44
+ ]
@@ -0,0 +1,146 @@
1
+ [
2
+
3
+ {"css_bytes": ""},
4
+ [[], "utf-8"],
5
+
6
+ {"css_bytes": "@\u00C3\u00A9",
7
+ "protocol_encoding": null, "environment_encoding": null},
8
+ [[["at-rule", "é", [], null]], "utf-8"],
9
+
10
+ {"css_bytes": "@\u00C3\u00A9"},
11
+ [[["at-rule", "é", [], null]], "utf-8"],
12
+
13
+ {"css_bytes": "@\u0000\u00E9\u0000",
14
+ "comment": "Untagged UTF-16, parsed as UTF-8"},
15
+ [[["at-rule", "���", [], null]], "utf-8"],
16
+
17
+ {"css_bytes": "\u00FF\u00FE@\u0000\u00E9\u0000",
18
+ "comment": "UTF-16 with a BOM"},
19
+ [[["at-rule", "é", [], null]], "utf-16le"],
20
+
21
+ {"css_bytes": "\u00FE\u00FF\u0000@\u0000\u00E9"},
22
+ [[["at-rule", "é", [], null]], "utf-16be"],
23
+
24
+ {"css_bytes": "@\u00E9"},
25
+ [[["at-rule", "�", [], null]], "utf-8"],
26
+
27
+
28
+ {"css_bytes": "@\u00E9", "protocol_encoding": "ISO-8859-2"},
29
+ [[["at-rule", "é", [], null]], "iso-8859-2"],
30
+
31
+ {"css_bytes": "@\u00E9", "protocol_encoding": "ISO-8859-5"},
32
+ [[["at-rule", "щ", [], null]], "iso-8859-5"],
33
+
34
+ {"css_bytes": "@\u00C3\u00A9", "protocol_encoding": "ISO-8859-2"},
35
+ [[["at-rule", "ĂŠ", [], null]], "iso-8859-2"],
36
+
37
+ {"css_bytes": "\u00EF\u00BB\u00BF @\u00C3\u00A9",
38
+ "protocol_encoding": "ISO-8859-2",
39
+ "comment": "BOM takes precedence over protocol"},
40
+ [[["at-rule", "é", [], null]], "utf-8"],
41
+
42
+
43
+ {"css_bytes": "@charset \"ISO-8859-5\"; @\u00E9"},
44
+ [[["at-rule", "charset", [" ", ["string", "ISO-8859-5"]], null],
45
+ ["at-rule", "щ", [], null]],
46
+ "iso-8859-5"],
47
+
48
+ {"css_bytes": "@Charset \"ISO-8859-5\"; @\u00E9",
49
+ "comment": "@charset has to match an exact byte pattern"},
50
+ [[["at-rule", "Charset", [" ", ["string", "ISO-8859-5"]], null],
51
+ ["at-rule", "�", [], null]],
52
+ "utf-8"],
53
+
54
+ {"css_bytes": "@charset \"ISO-8859-5\"; @\u00E9",
55
+ "comment": "@charset has to match an exact byte pattern"},
56
+ [[["at-rule", "charset", [" ", ["string", "ISO-8859-5"]], null],
57
+ ["at-rule", "�", [], null]],
58
+ "utf-8"],
59
+
60
+ {"css_bytes": "@charset 'ISO-8859-5'; @\u00E9",
61
+ "comment": "@charset has to match an exact byte pattern"},
62
+ [[["at-rule", "charset", [" ", ["string", "ISO-8859-5"]], null],
63
+ ["at-rule", "�", [], null]],
64
+ "utf-8"],
65
+
66
+ {"css_bytes": "@charset \"ISO-8859-5\" ; @\u00E9",
67
+ "comment": "@charset has to match an exact byte pattern"},
68
+ [[["at-rule", "charset", [" ", ["string", "ISO-8859-5"], " "], null],
69
+ ["at-rule", "�", [], null]],
70
+ "utf-8"],
71
+
72
+
73
+ {"css_bytes": "@\u0000c\u0000h\u0000a\u0000r\u0000s\u0000e\u0000t\u0000 \u0000\"\u0000U\u0000T\u0000F\u0000-\u00001\u00006\u0000L\u0000E\u0000\"\u0000;\u0000@\u0000\u00e9\u0000",
74
+ "comment": "@charset has to be ASCII-compatible itself"},
75
+ [[["at-rule", "�c�h�a�r�s�e�t�",
76
+ [" ", ["ident", "�"], ["string", "�U�T�F�-�1�6�L�E�"], ["ident", "�"]], null],
77
+ ["error", "invalid"]],
78
+ "utf-8"],
79
+
80
+ {"css_bytes": "@charset \"UTF-16LE\"; @\u00C3\u00A9",
81
+ "comment": "@charset can only specify ASCII-compatible encodings"},
82
+ [[["at-rule", "charset", [" ", ["string", "UTF-16LE"]], null],
83
+ ["at-rule", "é", [], null]],
84
+ "utf-8"],
85
+
86
+
87
+ {"css_bytes": "\u00EF\u00BB\u00BF @charset \"ISO-8859-5\"; @\u00E9",
88
+ "comment": "BOM takes precedence over @charset"},
89
+ [[["at-rule", "charset", [" ", ["string", "ISO-8859-5"]], null],
90
+ ["at-rule", "�", [], null]],
91
+ "utf-8"],
92
+
93
+ {"css_bytes": "\u00EF\u00BB\u00BF @charset \"ISO-8859-5\"; @\u00C3\u00A9",
94
+ "comment": "BOM takes precedence over @charset"},
95
+ [[["at-rule", "charset", [" ", ["string", "ISO-8859-5"]], null],
96
+ ["at-rule", "é", [], null]],
97
+ "utf-8"],
98
+
99
+ {"css_bytes": "@charset \"ISO-8859-5\"; @\u00E9",
100
+ "protocol_encoding": " Iso-8859-2",
101
+ "comment": "Protocol takes precedence over @charset"},
102
+ [[["at-rule", "charset", [" ", ["string", "ISO-8859-5"]], null],
103
+ ["at-rule", "é", [], null]],
104
+ "iso-8859-2"],
105
+
106
+ {"css_bytes": "@charset \"ISO-8859-5\"; @\u00E9",
107
+ "protocol_encoding": "kamoulox",
108
+ "comment": "Unknow protocol encoding falls back to @charset"},
109
+ [[["at-rule", "charset", [" ", ["string", "ISO-8859-5"]], null],
110
+ ["at-rule", "щ", [], null]],
111
+ "iso-8859-5"],
112
+
113
+
114
+ {"css_bytes": "@\u00E9", "environment_encoding": "ISO-8859-2"},
115
+ [[["at-rule", "é", [], null]], "iso-8859-2"],
116
+
117
+ {"css_bytes": "@\u00E9", "environment_encoding": "ISO-8859-5"},
118
+ [[["at-rule", "щ", [], null]], "iso-8859-5"],
119
+
120
+ {"css_bytes": "@charset \"ISO-8859-5\"; @\u00E9",
121
+ "environment_encoding": "ISO-8859-2",
122
+ "comment": "@character takes precedence over environment"},
123
+ [[["at-rule", "charset", [" ", ["string", "ISO-8859-5"]], null],
124
+ ["at-rule", "щ", [], null]],
125
+ "iso-8859-5"],
126
+
127
+ {"css_bytes": "@charset \"kamoulox\"; @\u00E9",
128
+ "environment_encoding": "ISO-8859-2",
129
+ "comment": "@character with unknown encoding falls back to environment encoding"},
130
+ [[["at-rule", "charset", [" ", ["string", "kamoulox"]], null],
131
+ ["at-rule", "é", [], null]],
132
+ "iso-8859-2"],
133
+
134
+ {"css_bytes": "@\u00E9",
135
+ "protocol_encoding": "ISO-8859-2",
136
+ "environment_encoding": "ISO-8859-5",
137
+ "comment": "protocol takes precedence over environment"},
138
+ [[["at-rule", "é", [], null]], "iso-8859-2"],
139
+
140
+ {"css_bytes": "\u00EF\u00BB\u00BF @\u00C3\u00A9",
141
+ "environment_encoding": "ISO-8859-5",
142
+ "comment": "BOM takes precedence over environment"},
143
+ [[["at-rule", "é", [], null]], "utf-8"]
144
+
145
+
146
+ ]