@projectwallace/css-parser 0.11.0 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/parse-atrule-prelude.js +22 -10
- package/dist/parse-selector.js +20 -6
- package/dist/parse.js +1 -1
- package/dist/string-utils.d.ts +15 -0
- package/dist/string-utils.js +12 -1
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Lexer } from './tokenize.js';
|
|
2
|
-
import { CSSDataArena, PRELUDE_OPERATOR, MEDIA_TYPE, MEDIA_QUERY, MEDIA_FEATURE, FUNCTION, IDENTIFIER, CONTAINER_QUERY, SUPPORTS_QUERY, LAYER_NAME,
|
|
3
|
-
import { TOKEN_COMMA, TOKEN_IDENT, TOKEN_LEFT_PAREN, TOKEN_RIGHT_PAREN, TOKEN_FUNCTION, TOKEN_EOF, TOKEN_WHITESPACE,
|
|
4
|
-
import { str_equals, CHAR_LESS_THAN, CHAR_GREATER_THAN, CHAR_EQUALS, CHAR_COLON, is_whitespace } from './string-utils.js';
|
|
2
|
+
import { CSSDataArena, PRELUDE_OPERATOR, MEDIA_TYPE, MEDIA_QUERY, MEDIA_FEATURE, FUNCTION, IDENTIFIER, CONTAINER_QUERY, SUPPORTS_QUERY, LAYER_NAME, STRING, URL, DIMENSION, NUMBER, FEATURE_RANGE } from './arena.js';
|
|
3
|
+
import { TOKEN_COMMA, TOKEN_IDENT, TOKEN_LEFT_PAREN, TOKEN_RIGHT_PAREN, TOKEN_FUNCTION, TOKEN_EOF, TOKEN_WHITESPACE, TOKEN_STRING, TOKEN_URL, TOKEN_DIMENSION, TOKEN_PERCENTAGE, TOKEN_NUMBER } from './token-types.js';
|
|
4
|
+
import { strip_vendor_prefix, str_equals, CHAR_LESS_THAN, CHAR_GREATER_THAN, CHAR_EQUALS, CHAR_COLON, is_whitespace } from './string-utils.js';
|
|
5
5
|
import { trim_boundaries, skip_whitespace_forward } from './parse-utils.js';
|
|
6
6
|
import { CSSNode } from './css-node.js';
|
|
7
7
|
|
|
@@ -26,20 +26,23 @@ class AtRulePreludeParser {
|
|
|
26
26
|
}
|
|
27
27
|
// Dispatch to appropriate parser based on at-rule type
|
|
28
28
|
parse_prelude_dispatch(at_rule_name) {
|
|
29
|
-
|
|
29
|
+
let normalized_name = strip_vendor_prefix(at_rule_name);
|
|
30
|
+
if (str_equals("media", normalized_name)) {
|
|
30
31
|
return this.parse_media_query_list();
|
|
31
|
-
} else if (str_equals("container",
|
|
32
|
+
} else if (str_equals("container", normalized_name)) {
|
|
32
33
|
return this.parse_container_query();
|
|
33
|
-
} else if (str_equals("supports",
|
|
34
|
+
} else if (str_equals("supports", normalized_name)) {
|
|
34
35
|
return this.parse_supports_query();
|
|
35
|
-
} else if (str_equals("layer",
|
|
36
|
+
} else if (str_equals("layer", normalized_name)) {
|
|
36
37
|
return this.parse_layer_names();
|
|
37
|
-
} else if (str_equals("keyframes",
|
|
38
|
+
} else if (str_equals("keyframes", normalized_name)) {
|
|
38
39
|
return this.parse_identifier();
|
|
39
|
-
} else if (str_equals("property",
|
|
40
|
+
} else if (str_equals("property", normalized_name)) {
|
|
40
41
|
return this.parse_identifier();
|
|
41
|
-
} else if (str_equals("import",
|
|
42
|
+
} else if (str_equals("import", normalized_name)) {
|
|
42
43
|
return this.parse_import_prelude();
|
|
44
|
+
} else if (str_equals("charset", normalized_name)) {
|
|
45
|
+
return this.parse_charset_prelude();
|
|
43
46
|
}
|
|
44
47
|
return [];
|
|
45
48
|
}
|
|
@@ -303,6 +306,15 @@ class AtRulePreludeParser {
|
|
|
303
306
|
let ident = this.create_node(IDENTIFIER, this.lexer.token_start, this.lexer.token_end);
|
|
304
307
|
return [ident];
|
|
305
308
|
}
|
|
309
|
+
// Parse @charset prelude: "UTF-8"
|
|
310
|
+
parse_charset_prelude() {
|
|
311
|
+
this.skip_whitespace();
|
|
312
|
+
if (this.lexer.pos >= this.prelude_end) return [];
|
|
313
|
+
this.next_token();
|
|
314
|
+
if (this.lexer.token_type !== TOKEN_STRING) return [];
|
|
315
|
+
let str = this.create_node(STRING, this.lexer.token_start, this.lexer.token_end);
|
|
316
|
+
return [str];
|
|
317
|
+
}
|
|
306
318
|
// Parse @import prelude: url() [layer] [supports()] [media-query-list]
|
|
307
319
|
// @import url("styles.css") layer(base) supports(display: grid) screen and (min-width: 768px);
|
|
308
320
|
parse_import_prelude() {
|
package/dist/parse-selector.js
CHANGED
|
@@ -81,7 +81,7 @@ class SelectorParser {
|
|
|
81
81
|
if (token_type === TOKEN_DELIM) {
|
|
82
82
|
let ch = this.source.charCodeAt(this.lexer.token_start);
|
|
83
83
|
if (ch === CHAR_GREATER_THAN || ch === CHAR_PLUS || ch === CHAR_TILDE) {
|
|
84
|
-
let combinator = this.
|
|
84
|
+
let combinator = this.create_node_at(COMBINATOR, this.lexer.token_start, this.lexer.token_end, this.lexer.token_line, this.lexer.token_column);
|
|
85
85
|
components.push(combinator);
|
|
86
86
|
this.skip_whitespace();
|
|
87
87
|
} else {
|
|
@@ -237,40 +237,48 @@ class SelectorParser {
|
|
|
237
237
|
// Parse combinator (>, +, ~, or descendant space)
|
|
238
238
|
try_parse_combinator() {
|
|
239
239
|
let whitespace_start = this.lexer.pos;
|
|
240
|
+
let whitespace_start_line = this.lexer.line;
|
|
241
|
+
let whitespace_start_column = this.lexer.column;
|
|
240
242
|
let has_whitespace = false;
|
|
241
243
|
while (this.lexer.pos < this.selector_end) {
|
|
242
244
|
let ch = this.source.charCodeAt(this.lexer.pos);
|
|
243
245
|
if (ch === CHAR_SPACE || ch === CHAR_TAB || ch === CHAR_NEWLINE || ch === CHAR_CARRIAGE_RETURN || ch === CHAR_FORM_FEED) {
|
|
244
246
|
has_whitespace = true;
|
|
245
|
-
this.lexer.
|
|
247
|
+
this.lexer.advance();
|
|
246
248
|
} else {
|
|
247
249
|
break;
|
|
248
250
|
}
|
|
249
251
|
}
|
|
250
252
|
if (this.lexer.pos >= this.selector_end) {
|
|
251
253
|
this.lexer.pos = whitespace_start;
|
|
254
|
+
this.lexer.line = whitespace_start_line;
|
|
255
|
+
this.lexer.column = whitespace_start_column;
|
|
252
256
|
return null;
|
|
253
257
|
}
|
|
254
258
|
this.lexer.next_token_fast(false);
|
|
255
259
|
if (this.lexer.token_type === TOKEN_DELIM) {
|
|
256
260
|
let ch = this.source.charCodeAt(this.lexer.token_start);
|
|
257
261
|
if (is_combinator(ch)) {
|
|
258
|
-
return this.
|
|
262
|
+
return this.create_node_at(COMBINATOR, this.lexer.token_start, this.lexer.token_end, this.lexer.token_line, this.lexer.token_column);
|
|
259
263
|
}
|
|
260
264
|
}
|
|
261
265
|
if (has_whitespace) {
|
|
262
266
|
this.lexer.pos = whitespace_start;
|
|
267
|
+
this.lexer.line = whitespace_start_line;
|
|
268
|
+
this.lexer.column = whitespace_start_column;
|
|
263
269
|
while (this.lexer.pos < this.selector_end) {
|
|
264
270
|
let ch = this.source.charCodeAt(this.lexer.pos);
|
|
265
271
|
if (ch === CHAR_SPACE || ch === CHAR_TAB || ch === CHAR_NEWLINE || ch === CHAR_CARRIAGE_RETURN || ch === CHAR_FORM_FEED) {
|
|
266
|
-
this.lexer.
|
|
272
|
+
this.lexer.advance();
|
|
267
273
|
} else {
|
|
268
274
|
break;
|
|
269
275
|
}
|
|
270
276
|
}
|
|
271
|
-
return this.
|
|
277
|
+
return this.create_node_at(COMBINATOR, whitespace_start, this.lexer.pos, whitespace_start_line, whitespace_start_column);
|
|
272
278
|
}
|
|
273
279
|
this.lexer.pos = whitespace_start;
|
|
280
|
+
this.lexer.line = whitespace_start_line;
|
|
281
|
+
this.lexer.column = whitespace_start_column;
|
|
274
282
|
return null;
|
|
275
283
|
}
|
|
276
284
|
// Parse class selector (.classname)
|
|
@@ -572,7 +580,13 @@ class SelectorParser {
|
|
|
572
580
|
return -1;
|
|
573
581
|
}
|
|
574
582
|
create_node(type, start, end) {
|
|
575
|
-
let node = this.arena.create_node(type, start, end - start, this.lexer.
|
|
583
|
+
let node = this.arena.create_node(type, start, end - start, this.lexer.token_line, this.lexer.token_column);
|
|
584
|
+
this.arena.set_content_start_delta(node, 0);
|
|
585
|
+
this.arena.set_content_length(node, end - start);
|
|
586
|
+
return node;
|
|
587
|
+
}
|
|
588
|
+
create_node_at(type, start, end, line, column) {
|
|
589
|
+
let node = this.arena.create_node(type, start, end - start, line, column);
|
|
576
590
|
this.arena.set_content_start_delta(node, 0);
|
|
577
591
|
this.arena.set_content_length(node, end - start);
|
|
578
592
|
return node;
|
package/dist/parse.js
CHANGED
|
@@ -226,9 +226,9 @@ class Parser {
|
|
|
226
226
|
this.arena.set_value_start_delta(at_rule, trimmed[0] - at_rule_start);
|
|
227
227
|
this.arena.set_value_length(at_rule, trimmed[1] - trimmed[0]);
|
|
228
228
|
if (this.prelude_parser) {
|
|
229
|
+
prelude_wrapper = this.arena.create_node(AT_RULE_PRELUDE, trimmed[0], trimmed[1] - trimmed[0], at_rule_line, at_rule_column);
|
|
229
230
|
let prelude_nodes = this.prelude_parser.parse_prelude(at_rule_name, trimmed[0], trimmed[1], at_rule_line, at_rule_column);
|
|
230
231
|
if (prelude_nodes.length > 0) {
|
|
231
|
-
prelude_wrapper = this.arena.create_node(AT_RULE_PRELUDE, trimmed[0], trimmed[1] - trimmed[0], at_rule_line, at_rule_column);
|
|
232
232
|
this.arena.append_children(prelude_wrapper, prelude_nodes);
|
|
233
233
|
}
|
|
234
234
|
}
|
package/dist/string-utils.d.ts
CHANGED
|
@@ -82,3 +82,18 @@ export declare function is_vendor_prefixed(source: string, start: number, end: n
|
|
|
82
82
|
* - `color` → false
|
|
83
83
|
*/
|
|
84
84
|
export declare function is_custom(str: string): boolean;
|
|
85
|
+
/**
|
|
86
|
+
* Strip vendor prefix from a string
|
|
87
|
+
*
|
|
88
|
+
* @param str - The string to strip vendor prefix from
|
|
89
|
+
* @returns The string without vendor prefix, or original string if no prefix found
|
|
90
|
+
*
|
|
91
|
+
* Examples:
|
|
92
|
+
* - `-webkit-keyframes` → `keyframes`
|
|
93
|
+
* - `-moz-appearance` → `appearance`
|
|
94
|
+
* - `-ms-filter` → `filter`
|
|
95
|
+
* - `-o-border-image` → `border-image`
|
|
96
|
+
* - `keyframes` → `keyframes` (no change)
|
|
97
|
+
* - `--custom-property` → `--custom-property` (custom property, not vendor prefix)
|
|
98
|
+
*/
|
|
99
|
+
export declare function strip_vendor_prefix(str: string): string;
|
package/dist/string-utils.js
CHANGED
|
@@ -114,5 +114,16 @@ function is_custom(str) {
|
|
|
114
114
|
if (str.length < 3) return false;
|
|
115
115
|
return str.charCodeAt(0) === CHAR_MINUS_HYPHEN && str.charCodeAt(1) === CHAR_MINUS_HYPHEN;
|
|
116
116
|
}
|
|
117
|
+
function strip_vendor_prefix(str) {
|
|
118
|
+
if (!is_vendor_prefixed(str)) {
|
|
119
|
+
return str;
|
|
120
|
+
}
|
|
121
|
+
for (let i = 2; i < str.length; i++) {
|
|
122
|
+
if (str.charCodeAt(i) === CHAR_MINUS_HYPHEN) {
|
|
123
|
+
return str.substring(i + 1);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return str;
|
|
127
|
+
}
|
|
117
128
|
|
|
118
|
-
export { CHAR_AMPERSAND, CHAR_ASTERISK, CHAR_CARET, CHAR_CARRIAGE_RETURN, CHAR_COLON, CHAR_DOLLAR, CHAR_DOUBLE_QUOTE, CHAR_EQUALS, CHAR_FORM_FEED, CHAR_FORWARD_SLASH, CHAR_GREATER_THAN, CHAR_LESS_THAN, CHAR_MINUS_HYPHEN, CHAR_NEWLINE, CHAR_PERIOD, CHAR_PIPE, CHAR_PLUS, CHAR_SINGLE_QUOTE, CHAR_SPACE, CHAR_TAB, CHAR_TILDE, is_combinator, is_custom, is_digit, is_vendor_prefixed, is_whitespace, str_equals, str_index_of, str_starts_with };
|
|
129
|
+
export { CHAR_AMPERSAND, CHAR_ASTERISK, CHAR_CARET, CHAR_CARRIAGE_RETURN, CHAR_COLON, CHAR_DOLLAR, CHAR_DOUBLE_QUOTE, CHAR_EQUALS, CHAR_FORM_FEED, CHAR_FORWARD_SLASH, CHAR_GREATER_THAN, CHAR_LESS_THAN, CHAR_MINUS_HYPHEN, CHAR_NEWLINE, CHAR_PERIOD, CHAR_PIPE, CHAR_PLUS, CHAR_SINGLE_QUOTE, CHAR_SPACE, CHAR_TAB, CHAR_TILDE, is_combinator, is_custom, is_digit, is_vendor_prefixed, is_whitespace, str_equals, str_index_of, str_starts_with, strip_vendor_prefix };
|
package/package.json
CHANGED