@projectwallace/css-parser 0.7.3 → 0.8.0
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/arena.js +31 -41
- package/dist/css-node.d.ts +7 -4
- package/dist/css-node.js +50 -17
- package/dist/parse-selector.js +2 -16
- package/dist/parse.js +1 -5
- package/dist/string-utils.d.ts +1 -0
- package/dist/string-utils.js +4 -0
- package/package.json +1 -1
package/dist/arena.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
let BYTES_PER_NODE =
|
|
1
|
+
let BYTES_PER_NODE = 32;
|
|
2
2
|
const STYLESHEET = 1;
|
|
3
3
|
const STYLE_RULE = 2;
|
|
4
4
|
const AT_RULE = 3;
|
|
@@ -38,7 +38,6 @@ const PRELUDE_OPERATOR = 38;
|
|
|
38
38
|
const FLAG_IMPORTANT = 1 << 0;
|
|
39
39
|
const FLAG_HAS_ERROR = 1 << 1;
|
|
40
40
|
const FLAG_HAS_BLOCK = 1 << 3;
|
|
41
|
-
const FLAG_VENDOR_PREFIXED = 1 << 4;
|
|
42
41
|
const FLAG_HAS_DECLARATIONS = 1 << 5;
|
|
43
42
|
const FLAG_HAS_PARENS = 1 << 6;
|
|
44
43
|
const ATTR_OPERATOR_NONE = 0;
|
|
@@ -99,59 +98,55 @@ class CSSDataArena {
|
|
|
99
98
|
}
|
|
100
99
|
// Read start offset in source
|
|
101
100
|
get_start_offset(node_index) {
|
|
102
|
-
return this.view.getUint32(this.node_offset(node_index) +
|
|
101
|
+
return this.view.getUint32(this.node_offset(node_index) + 12, true);
|
|
103
102
|
}
|
|
104
103
|
// Read length in source
|
|
105
104
|
get_length(node_index) {
|
|
106
|
-
return this.view.getUint16(this.node_offset(node_index) +
|
|
105
|
+
return this.view.getUint16(this.node_offset(node_index) + 2, true);
|
|
107
106
|
}
|
|
108
107
|
// Read content start offset (stored as delta from startOffset)
|
|
109
108
|
get_content_start(node_index) {
|
|
110
109
|
const startOffset = this.get_start_offset(node_index);
|
|
111
|
-
const delta = this.view.getUint16(this.node_offset(node_index) +
|
|
110
|
+
const delta = this.view.getUint16(this.node_offset(node_index) + 16, true);
|
|
112
111
|
return startOffset + delta;
|
|
113
112
|
}
|
|
114
113
|
// Read content length
|
|
115
114
|
get_content_length(node_index) {
|
|
116
|
-
return this.view.getUint16(this.node_offset(node_index) +
|
|
115
|
+
return this.view.getUint16(this.node_offset(node_index) + 20, true);
|
|
117
116
|
}
|
|
118
117
|
// Read attribute operator (for NODE_SELECTOR_ATTRIBUTE)
|
|
119
118
|
get_attr_operator(node_index) {
|
|
120
|
-
return this.view.getUint8(this.node_offset(node_index) +
|
|
119
|
+
return this.view.getUint8(this.node_offset(node_index) + 30);
|
|
121
120
|
}
|
|
122
121
|
// Read attribute flags (for NODE_SELECTOR_ATTRIBUTE)
|
|
123
122
|
get_attr_flags(node_index) {
|
|
124
|
-
return this.view.getUint8(this.node_offset(node_index) +
|
|
123
|
+
return this.view.getUint8(this.node_offset(node_index) + 31);
|
|
125
124
|
}
|
|
126
125
|
// Read first child index (0 = no children)
|
|
127
126
|
get_first_child(node_index) {
|
|
128
|
-
return this.view.getUint32(this.node_offset(node_index) +
|
|
129
|
-
}
|
|
130
|
-
// Read last child index (0 = no children)
|
|
131
|
-
get_last_child(node_index) {
|
|
132
|
-
return this.view.getUint32(this.node_offset(node_index) + 24, true);
|
|
127
|
+
return this.view.getUint32(this.node_offset(node_index) + 4, true);
|
|
133
128
|
}
|
|
134
129
|
// Read next sibling index (0 = no sibling)
|
|
135
130
|
get_next_sibling(node_index) {
|
|
136
|
-
return this.view.getUint32(this.node_offset(node_index) +
|
|
131
|
+
return this.view.getUint32(this.node_offset(node_index) + 8, true);
|
|
137
132
|
}
|
|
138
133
|
// Read start line
|
|
139
134
|
get_start_line(node_index) {
|
|
140
|
-
return this.view.getUint32(this.node_offset(node_index) +
|
|
135
|
+
return this.view.getUint32(this.node_offset(node_index) + 24, true);
|
|
141
136
|
}
|
|
142
137
|
// Read start column
|
|
143
138
|
get_start_column(node_index) {
|
|
144
|
-
return this.view.getUint16(this.node_offset(node_index) +
|
|
139
|
+
return this.view.getUint16(this.node_offset(node_index) + 28, true);
|
|
145
140
|
}
|
|
146
141
|
// Read value start offset (stored as delta from startOffset, declaration value / at-rule prelude)
|
|
147
142
|
get_value_start(node_index) {
|
|
148
143
|
const startOffset = this.get_start_offset(node_index);
|
|
149
|
-
const delta = this.view.getUint16(this.node_offset(node_index) +
|
|
144
|
+
const delta = this.view.getUint16(this.node_offset(node_index) + 18, true);
|
|
150
145
|
return startOffset + delta;
|
|
151
146
|
}
|
|
152
147
|
// Read value length
|
|
153
148
|
get_value_length(node_index) {
|
|
154
|
-
return this.view.getUint16(this.node_offset(node_index) +
|
|
149
|
+
return this.view.getUint16(this.node_offset(node_index) + 22, true);
|
|
155
150
|
}
|
|
156
151
|
// --- Write Methods ---
|
|
157
152
|
// Write node type
|
|
@@ -164,55 +159,51 @@ class CSSDataArena {
|
|
|
164
159
|
}
|
|
165
160
|
// Write start offset in source
|
|
166
161
|
set_start_offset(node_index, offset) {
|
|
167
|
-
this.view.setUint32(this.node_offset(node_index) +
|
|
162
|
+
this.view.setUint32(this.node_offset(node_index) + 12, offset, true);
|
|
168
163
|
}
|
|
169
164
|
// Write length in source
|
|
170
165
|
set_length(node_index, length) {
|
|
171
|
-
this.view.setUint16(this.node_offset(node_index) +
|
|
166
|
+
this.view.setUint16(this.node_offset(node_index) + 2, length, true);
|
|
172
167
|
}
|
|
173
168
|
// Write content start delta (offset from startOffset)
|
|
174
169
|
set_content_start_delta(node_index, delta) {
|
|
175
|
-
this.view.setUint16(this.node_offset(node_index) +
|
|
170
|
+
this.view.setUint16(this.node_offset(node_index) + 16, delta, true);
|
|
176
171
|
}
|
|
177
172
|
// Write content length
|
|
178
173
|
set_content_length(node_index, length) {
|
|
179
|
-
this.view.setUint16(this.node_offset(node_index) +
|
|
174
|
+
this.view.setUint16(this.node_offset(node_index) + 20, length, true);
|
|
180
175
|
}
|
|
181
176
|
// Write attribute operator (for NODE_SELECTOR_ATTRIBUTE)
|
|
182
177
|
set_attr_operator(node_index, operator) {
|
|
183
|
-
this.view.setUint8(this.node_offset(node_index) +
|
|
178
|
+
this.view.setUint8(this.node_offset(node_index) + 30, operator);
|
|
184
179
|
}
|
|
185
180
|
// Write attribute flags (for NODE_SELECTOR_ATTRIBUTE)
|
|
186
181
|
set_attr_flags(node_index, flags) {
|
|
187
|
-
this.view.setUint8(this.node_offset(node_index) +
|
|
182
|
+
this.view.setUint8(this.node_offset(node_index) + 31, flags);
|
|
188
183
|
}
|
|
189
184
|
// Write first child index
|
|
190
185
|
set_first_child(node_index, childIndex) {
|
|
191
|
-
this.view.setUint32(this.node_offset(node_index) +
|
|
192
|
-
}
|
|
193
|
-
// Write last child index
|
|
194
|
-
set_last_child(node_index, childIndex) {
|
|
195
|
-
this.view.setUint32(this.node_offset(node_index) + 24, childIndex, true);
|
|
186
|
+
this.view.setUint32(this.node_offset(node_index) + 4, childIndex, true);
|
|
196
187
|
}
|
|
197
188
|
// Write next sibling index
|
|
198
189
|
set_next_sibling(node_index, siblingIndex) {
|
|
199
|
-
this.view.setUint32(this.node_offset(node_index) +
|
|
190
|
+
this.view.setUint32(this.node_offset(node_index) + 8, siblingIndex, true);
|
|
200
191
|
}
|
|
201
192
|
// Write start line
|
|
202
193
|
set_start_line(node_index, line) {
|
|
203
|
-
this.view.setUint32(this.node_offset(node_index) +
|
|
194
|
+
this.view.setUint32(this.node_offset(node_index) + 24, line, true);
|
|
204
195
|
}
|
|
205
196
|
// Write start column
|
|
206
197
|
set_start_column(node_index, column) {
|
|
207
|
-
this.view.setUint16(this.node_offset(node_index) +
|
|
198
|
+
this.view.setUint16(this.node_offset(node_index) + 28, column, true);
|
|
208
199
|
}
|
|
209
200
|
// Write value start delta (offset from startOffset, declaration value / at-rule prelude)
|
|
210
201
|
set_value_start_delta(node_index, delta) {
|
|
211
|
-
this.view.setUint16(this.node_offset(node_index) +
|
|
202
|
+
this.view.setUint16(this.node_offset(node_index) + 18, delta, true);
|
|
212
203
|
}
|
|
213
204
|
// Write value length
|
|
214
205
|
set_value_length(node_index, length) {
|
|
215
|
-
this.view.setUint16(this.node_offset(node_index) +
|
|
206
|
+
this.view.setUint16(this.node_offset(node_index) + 22, length, true);
|
|
216
207
|
}
|
|
217
208
|
// --- Node Creation ---
|
|
218
209
|
// Grow the arena by 1.3x when capacity is exceeded
|
|
@@ -234,10 +225,10 @@ class CSSDataArena {
|
|
|
234
225
|
this.count++;
|
|
235
226
|
const offset = node_index * BYTES_PER_NODE;
|
|
236
227
|
this.view.setUint8(offset, type);
|
|
237
|
-
this.view.
|
|
238
|
-
this.view.
|
|
239
|
-
this.view.setUint32(offset +
|
|
240
|
-
this.view.setUint16(offset +
|
|
228
|
+
this.view.setUint16(offset + 2, length, true);
|
|
229
|
+
this.view.setUint32(offset + 12, start_offset, true);
|
|
230
|
+
this.view.setUint32(offset + 24, start_line, true);
|
|
231
|
+
this.view.setUint16(offset + 28, start_column, true);
|
|
241
232
|
return node_index;
|
|
242
233
|
}
|
|
243
234
|
// --- Tree Building Helpers ---
|
|
@@ -246,8 +237,7 @@ class CSSDataArena {
|
|
|
246
237
|
append_children(parent_index, children) {
|
|
247
238
|
if (children.length === 0) return;
|
|
248
239
|
const offset = this.node_offset(parent_index);
|
|
249
|
-
this.view.setUint32(offset +
|
|
250
|
-
this.view.setUint32(offset + 24, children[children.length - 1], true);
|
|
240
|
+
this.view.setUint32(offset + 4, children[0], true);
|
|
251
241
|
for (let i = 0; i < children.length - 1; i++) {
|
|
252
242
|
this.set_next_sibling(children[i], children[i + 1]);
|
|
253
243
|
}
|
|
@@ -277,4 +267,4 @@ class CSSDataArena {
|
|
|
277
267
|
}
|
|
278
268
|
}
|
|
279
269
|
|
|
280
|
-
export { ATTRIBUTE_SELECTOR, ATTR_FLAG_CASE_INSENSITIVE, ATTR_FLAG_CASE_SENSITIVE, ATTR_FLAG_NONE, ATTR_OPERATOR_CARET_EQUAL, ATTR_OPERATOR_DOLLAR_EQUAL, ATTR_OPERATOR_EQUAL, ATTR_OPERATOR_NONE, ATTR_OPERATOR_PIPE_EQUAL, ATTR_OPERATOR_STAR_EQUAL, ATTR_OPERATOR_TILDE_EQUAL, AT_RULE, BLOCK, CLASS_SELECTOR, COMBINATOR, COMMENT, CONTAINER_QUERY, CSSDataArena, DECLARATION, DIMENSION, FLAG_HAS_BLOCK, FLAG_HAS_DECLARATIONS, FLAG_HAS_ERROR, FLAG_HAS_PARENS, FLAG_IMPORTANT,
|
|
270
|
+
export { ATTRIBUTE_SELECTOR, ATTR_FLAG_CASE_INSENSITIVE, ATTR_FLAG_CASE_SENSITIVE, ATTR_FLAG_NONE, ATTR_OPERATOR_CARET_EQUAL, ATTR_OPERATOR_DOLLAR_EQUAL, ATTR_OPERATOR_EQUAL, ATTR_OPERATOR_NONE, ATTR_OPERATOR_PIPE_EQUAL, ATTR_OPERATOR_STAR_EQUAL, ATTR_OPERATOR_TILDE_EQUAL, AT_RULE, BLOCK, CLASS_SELECTOR, COMBINATOR, COMMENT, CONTAINER_QUERY, CSSDataArena, DECLARATION, DIMENSION, FLAG_HAS_BLOCK, FLAG_HAS_DECLARATIONS, FLAG_HAS_ERROR, FLAG_HAS_PARENS, FLAG_IMPORTANT, FUNCTION, HASH, IDENTIFIER, ID_SELECTOR, LANG_SELECTOR, LAYER_NAME, MEDIA_FEATURE, MEDIA_QUERY, MEDIA_TYPE, NESTING_SELECTOR, NTH_OF_SELECTOR, NTH_SELECTOR, NUMBER, OPERATOR, PARENTHESIS, PRELUDE_OPERATOR, PSEUDO_CLASS_SELECTOR, PSEUDO_ELEMENT_SELECTOR, SELECTOR, SELECTOR_LIST, STRING, STYLESHEET, STYLE_RULE, SUPPORTS_QUERY, TYPE_SELECTOR, UNIVERSAL_SELECTOR, URL };
|
package/dist/css-node.d.ts
CHANGED
|
@@ -47,7 +47,7 @@ export interface CloneOptions {
|
|
|
47
47
|
*/
|
|
48
48
|
deep?: boolean;
|
|
49
49
|
/**
|
|
50
|
-
* Include location information (line, column,
|
|
50
|
+
* Include location information (line, column, start, length)
|
|
51
51
|
* @default false
|
|
52
52
|
*/
|
|
53
53
|
locations?: boolean;
|
|
@@ -71,8 +71,9 @@ export type PlainCSSNode = {
|
|
|
71
71
|
nth_b?: string | null;
|
|
72
72
|
line?: number;
|
|
73
73
|
column?: number;
|
|
74
|
-
|
|
74
|
+
start?: number;
|
|
75
75
|
length?: number;
|
|
76
|
+
end?: number;
|
|
76
77
|
};
|
|
77
78
|
export declare class CSSNode {
|
|
78
79
|
private arena;
|
|
@@ -86,6 +87,7 @@ export declare class CSSNode {
|
|
|
86
87
|
get name(): string;
|
|
87
88
|
get property(): string;
|
|
88
89
|
get value(): string | number | null;
|
|
90
|
+
get value_as_number(): number | null;
|
|
89
91
|
get prelude(): string | null;
|
|
90
92
|
get attr_operator(): number;
|
|
91
93
|
get attr_flags(): number;
|
|
@@ -102,8 +104,9 @@ export declare class CSSNode {
|
|
|
102
104
|
get value_count(): number;
|
|
103
105
|
get line(): number;
|
|
104
106
|
get column(): number;
|
|
105
|
-
get
|
|
107
|
+
get start(): number;
|
|
106
108
|
get length(): number;
|
|
109
|
+
get end(): number;
|
|
107
110
|
get first_child(): CSSNode | null;
|
|
108
111
|
get next_sibling(): CSSNode | null;
|
|
109
112
|
get has_next(): boolean;
|
|
@@ -128,7 +131,7 @@ export declare class CSSNode {
|
|
|
128
131
|
*
|
|
129
132
|
* @param options - Cloning configuration
|
|
130
133
|
* @param options.deep - Recursively clone children (default: true)
|
|
131
|
-
* @param options.locations - Include line/column/
|
|
134
|
+
* @param options.locations - Include line/column/start/length (default: false)
|
|
132
135
|
* @returns Plain object with children as array
|
|
133
136
|
*
|
|
134
137
|
* @example
|
package/dist/css-node.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { str_starts_with, is_whitespace, CHAR_MINUS_HYPHEN, CHAR_PLUS } from './string-utils.js';
|
|
1
|
+
import { DIMENSION, NUMBER, URL, STRING, DECLARATION, FLAG_IMPORTANT, IDENTIFIER, FUNCTION, AT_RULE, PSEUDO_ELEMENT_SELECTOR, PSEUDO_CLASS_SELECTOR, FLAG_HAS_ERROR, FLAG_HAS_BLOCK, FLAG_HAS_DECLARATIONS, STYLE_RULE, BLOCK, COMMENT, FLAG_HAS_PARENS, NTH_SELECTOR, NTH_OF_SELECTOR, SELECTOR_LIST, SELECTOR, COMBINATOR, ATTRIBUTE_SELECTOR, PRELUDE_OPERATOR, LAYER_NAME, SUPPORTS_QUERY, CONTAINER_QUERY, MEDIA_TYPE, MEDIA_FEATURE, MEDIA_QUERY, LANG_SELECTOR, NESTING_SELECTOR, UNIVERSAL_SELECTOR, ID_SELECTOR, CLASS_SELECTOR, TYPE_SELECTOR, PARENTHESIS, OPERATOR, HASH, STYLESHEET } from './arena.js';
|
|
2
|
+
import { str_starts_with, is_vendor_prefixed, is_whitespace, CHAR_MINUS_HYPHEN, CHAR_PLUS } from './string-utils.js';
|
|
3
3
|
import { parse_dimension } from './parse-utils.js';
|
|
4
4
|
|
|
5
5
|
const TYPE_NAMES = {
|
|
@@ -85,15 +85,21 @@ class CSSNode {
|
|
|
85
85
|
// For URL nodes with quoted string: returns the string with quotes (consistent with STRING node)
|
|
86
86
|
// For URL nodes with unquoted URL: returns the URL content without quotes
|
|
87
87
|
get value() {
|
|
88
|
-
|
|
89
|
-
|
|
88
|
+
let { type, text } = this;
|
|
89
|
+
if (type === DIMENSION) {
|
|
90
|
+
return parse_dimension(text).value;
|
|
91
|
+
}
|
|
92
|
+
if (type === NUMBER) {
|
|
93
|
+
return Number.parseFloat(this.text);
|
|
94
|
+
}
|
|
95
|
+
if (type === URL) {
|
|
96
|
+
let firstChild = this.first_child;
|
|
90
97
|
if (firstChild && firstChild.type === STRING) {
|
|
91
98
|
return firstChild.text;
|
|
92
99
|
}
|
|
93
|
-
const text = this.text;
|
|
94
100
|
if (str_starts_with(text, "url(")) {
|
|
95
|
-
|
|
96
|
-
|
|
101
|
+
let openParen = text.indexOf("(");
|
|
102
|
+
let closeParen = text.lastIndexOf(")");
|
|
97
103
|
if (openParen !== -1 && closeParen !== -1 && closeParen > openParen) {
|
|
98
104
|
let content = text.substring(openParen + 1, closeParen).trim();
|
|
99
105
|
return content;
|
|
@@ -102,14 +108,21 @@ class CSSNode {
|
|
|
102
108
|
return text;
|
|
103
109
|
}
|
|
104
110
|
}
|
|
105
|
-
if (this.type === DIMENSION || this.type === NUMBER) {
|
|
106
|
-
return parse_dimension(this.text).value;
|
|
107
|
-
}
|
|
108
111
|
let start = this.arena.get_value_start(this.index);
|
|
109
112
|
let length = this.arena.get_value_length(this.index);
|
|
110
113
|
if (length === 0) return null;
|
|
111
114
|
return this.source.substring(start, start + length);
|
|
112
115
|
}
|
|
116
|
+
get value_as_number() {
|
|
117
|
+
let text = this.text;
|
|
118
|
+
if (this.type === NUMBER) {
|
|
119
|
+
return Number.parseFloat(text);
|
|
120
|
+
}
|
|
121
|
+
if (this.type === DIMENSION) {
|
|
122
|
+
return parse_dimension(text).value;
|
|
123
|
+
}
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
113
126
|
// Get the prelude text (for at-rules: "(min-width: 768px)" in "@media (min-width: 768px)")
|
|
114
127
|
// This is an alias for `value` to make at-rule usage more semantic
|
|
115
128
|
get prelude() {
|
|
@@ -136,9 +149,23 @@ class CSSNode {
|
|
|
136
149
|
if (this.type !== DECLARATION) return null;
|
|
137
150
|
return this.arena.has_flag(this.index, FLAG_IMPORTANT);
|
|
138
151
|
}
|
|
139
|
-
// Check if this has a vendor prefix (
|
|
152
|
+
// Check if this has a vendor prefix (computed on-demand)
|
|
140
153
|
get is_vendor_prefixed() {
|
|
141
|
-
|
|
154
|
+
switch (this.type) {
|
|
155
|
+
case DECLARATION:
|
|
156
|
+
return is_vendor_prefixed(this.name);
|
|
157
|
+
case PSEUDO_CLASS_SELECTOR:
|
|
158
|
+
case PSEUDO_ELEMENT_SELECTOR:
|
|
159
|
+
return is_vendor_prefixed(this.name);
|
|
160
|
+
case AT_RULE:
|
|
161
|
+
return is_vendor_prefixed(this.name);
|
|
162
|
+
case FUNCTION:
|
|
163
|
+
return is_vendor_prefixed(this.name);
|
|
164
|
+
case IDENTIFIER:
|
|
165
|
+
return is_vendor_prefixed(this.text);
|
|
166
|
+
default:
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
142
169
|
}
|
|
143
170
|
// Check if this node has an error
|
|
144
171
|
get has_error() {
|
|
@@ -221,13 +248,18 @@ class CSSNode {
|
|
|
221
248
|
return this.arena.get_start_column(this.index);
|
|
222
249
|
}
|
|
223
250
|
// Get start offset in source
|
|
224
|
-
get
|
|
251
|
+
get start() {
|
|
225
252
|
return this.arena.get_start_offset(this.index);
|
|
226
253
|
}
|
|
227
254
|
// Get length in source
|
|
228
255
|
get length() {
|
|
229
256
|
return this.arena.get_length(this.index);
|
|
230
257
|
}
|
|
258
|
+
// Get end offset in source
|
|
259
|
+
// End is not stored, must be calculated
|
|
260
|
+
get end() {
|
|
261
|
+
return this.start + this.length;
|
|
262
|
+
}
|
|
231
263
|
// --- Tree Traversal ---
|
|
232
264
|
// Get first child node
|
|
233
265
|
get first_child() {
|
|
@@ -399,8 +431,8 @@ class CSSNode {
|
|
|
399
431
|
let child = this.first_child;
|
|
400
432
|
while (child) {
|
|
401
433
|
if (child.type === COMBINATOR) break;
|
|
402
|
-
if (start === -1) start = child.
|
|
403
|
-
end = child.
|
|
434
|
+
if (start === -1) start = child.start;
|
|
435
|
+
end = child.start + child.length;
|
|
404
436
|
child = child.next_sibling;
|
|
405
437
|
}
|
|
406
438
|
if (start === -1) return "";
|
|
@@ -415,7 +447,7 @@ class CSSNode {
|
|
|
415
447
|
*
|
|
416
448
|
* @param options - Cloning configuration
|
|
417
449
|
* @param options.deep - Recursively clone children (default: true)
|
|
418
|
-
* @param options.locations - Include line/column/
|
|
450
|
+
* @param options.locations - Include line/column/start/length (default: false)
|
|
419
451
|
* @returns Plain object with children as array
|
|
420
452
|
*
|
|
421
453
|
* @example
|
|
@@ -459,8 +491,9 @@ class CSSNode {
|
|
|
459
491
|
if (locations) {
|
|
460
492
|
plain.line = this.line;
|
|
461
493
|
plain.column = this.column;
|
|
462
|
-
plain.
|
|
494
|
+
plain.start = this.start;
|
|
463
495
|
plain.length = this.length;
|
|
496
|
+
plain.end = this.end;
|
|
464
497
|
}
|
|
465
498
|
if (deep) {
|
|
466
499
|
for (let child of this.children) {
|
package/dist/parse-selector.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Lexer } from './lexer.js';
|
|
2
|
-
import { CSSDataArena, SELECTOR_LIST, SELECTOR, COMBINATOR, NESTING_SELECTOR, ID_SELECTOR, TYPE_SELECTOR, UNIVERSAL_SELECTOR, CLASS_SELECTOR, ATTRIBUTE_SELECTOR, ATTR_OPERATOR_NONE, ATTR_FLAG_NONE, ATTR_OPERATOR_EQUAL, ATTR_OPERATOR_TILDE_EQUAL, ATTR_OPERATOR_PIPE_EQUAL, ATTR_OPERATOR_CARET_EQUAL, ATTR_OPERATOR_DOLLAR_EQUAL, ATTR_OPERATOR_STAR_EQUAL, ATTR_FLAG_CASE_INSENSITIVE, ATTR_FLAG_CASE_SENSITIVE, PSEUDO_ELEMENT_SELECTOR, PSEUDO_CLASS_SELECTOR,
|
|
2
|
+
import { CSSDataArena, SELECTOR_LIST, SELECTOR, COMBINATOR, NESTING_SELECTOR, ID_SELECTOR, TYPE_SELECTOR, UNIVERSAL_SELECTOR, CLASS_SELECTOR, ATTRIBUTE_SELECTOR, ATTR_OPERATOR_NONE, ATTR_FLAG_NONE, ATTR_OPERATOR_EQUAL, ATTR_OPERATOR_TILDE_EQUAL, ATTR_OPERATOR_PIPE_EQUAL, ATTR_OPERATOR_CARET_EQUAL, ATTR_OPERATOR_DOLLAR_EQUAL, ATTR_OPERATOR_STAR_EQUAL, ATTR_FLAG_CASE_INSENSITIVE, ATTR_FLAG_CASE_SENSITIVE, PSEUDO_ELEMENT_SELECTOR, PSEUDO_CLASS_SELECTOR, FLAG_HAS_PARENS, LANG_SELECTOR, NTH_OF_SELECTOR } from './arena.js';
|
|
3
3
|
import { TOKEN_COMMA, TOKEN_DELIM, TOKEN_EOF, TOKEN_WHITESPACE, TOKEN_FUNCTION, TOKEN_COLON, TOKEN_LEFT_BRACKET, TOKEN_HASH, TOKEN_IDENT, TOKEN_RIGHT_BRACKET, TOKEN_LEFT_PAREN, TOKEN_RIGHT_PAREN, TOKEN_STRING } from './token-types.js';
|
|
4
4
|
import { skip_whitespace_and_comments_forward, skip_whitespace_and_comments_backward, skip_whitespace_forward } from './parse-utils.js';
|
|
5
|
-
import { CHAR_GREATER_THAN, CHAR_PLUS, CHAR_TILDE, CHAR_PERIOD, CHAR_ASTERISK, CHAR_AMPERSAND, CHAR_PIPE, CHAR_SPACE, CHAR_NEWLINE, CHAR_CARRIAGE_RETURN, CHAR_FORM_FEED, is_combinator, is_whitespace, CHAR_EQUALS, CHAR_CARET, CHAR_DOLLAR, CHAR_SINGLE_QUOTE, CHAR_DOUBLE_QUOTE, CHAR_COLON,
|
|
5
|
+
import { CHAR_GREATER_THAN, CHAR_PLUS, CHAR_TILDE, CHAR_PERIOD, CHAR_ASTERISK, CHAR_AMPERSAND, CHAR_PIPE, CHAR_SPACE, CHAR_NEWLINE, CHAR_CARRIAGE_RETURN, CHAR_FORM_FEED, is_combinator, is_whitespace, CHAR_EQUALS, CHAR_CARET, CHAR_DOLLAR, CHAR_SINGLE_QUOTE, CHAR_DOUBLE_QUOTE, CHAR_COLON, str_equals } from './string-utils.js';
|
|
6
6
|
import { ANplusBParser } from './parse-anplusb.js';
|
|
7
7
|
import { CSSNode } from './css-node.js';
|
|
8
8
|
|
|
@@ -44,7 +44,6 @@ class SelectorParser {
|
|
|
44
44
|
next_sibling = this.arena.get_next_sibling(last_component);
|
|
45
45
|
}
|
|
46
46
|
this.arena.set_first_child(selector_wrapper, complex_selector);
|
|
47
|
-
this.arena.set_last_child(selector_wrapper, last_component);
|
|
48
47
|
selectors.push(selector_wrapper);
|
|
49
48
|
}
|
|
50
49
|
this.skip_whitespace();
|
|
@@ -422,9 +421,6 @@ class SelectorParser {
|
|
|
422
421
|
let node = this.create_node(is_pseudo_element ? PSEUDO_ELEMENT_SELECTOR : PSEUDO_CLASS_SELECTOR, start, this.lexer.token_end);
|
|
423
422
|
this.arena.set_content_start_delta(node, this.lexer.token_start - start);
|
|
424
423
|
this.arena.set_content_length(node, this.lexer.token_end - this.lexer.token_start);
|
|
425
|
-
if (is_vendor_prefixed(this.source, this.lexer.token_start, this.lexer.token_end)) {
|
|
426
|
-
this.arena.set_flag(node, FLAG_VENDOR_PREFIXED);
|
|
427
|
-
}
|
|
428
424
|
return node;
|
|
429
425
|
} else if (token_type === TOKEN_FUNCTION) {
|
|
430
426
|
return this.parse_pseudo_function_after_colon(start, is_pseudo_element);
|
|
@@ -462,16 +458,12 @@ class SelectorParser {
|
|
|
462
458
|
this.arena.set_content_start_delta(node, func_name_start - start);
|
|
463
459
|
this.arena.set_content_length(node, func_name_end - func_name_start);
|
|
464
460
|
this.arena.set_flag(node, FLAG_HAS_PARENS);
|
|
465
|
-
if (is_vendor_prefixed(this.source, func_name_start, func_name_end)) {
|
|
466
|
-
this.arena.set_flag(node, FLAG_VENDOR_PREFIXED);
|
|
467
|
-
}
|
|
468
461
|
if (content_end > content_start) {
|
|
469
462
|
let func_name_substr = this.source.substring(func_name_start, func_name_end);
|
|
470
463
|
if (this.is_nth_pseudo(func_name_substr)) {
|
|
471
464
|
let child = this.parse_nth_expression(content_start, content_end);
|
|
472
465
|
if (child !== null) {
|
|
473
466
|
this.arena.set_first_child(node, child);
|
|
474
|
-
this.arena.set_last_child(node, child);
|
|
475
467
|
}
|
|
476
468
|
} else if (str_equals("lang", func_name_substr)) {
|
|
477
469
|
this.parse_lang_identifiers(content_start, content_end, node);
|
|
@@ -484,7 +476,6 @@ class SelectorParser {
|
|
|
484
476
|
this.lexer.restore_position(saved);
|
|
485
477
|
if (child_selector !== null) {
|
|
486
478
|
this.arena.set_first_child(node, child_selector);
|
|
487
|
-
this.arena.set_last_child(node, child_selector);
|
|
488
479
|
}
|
|
489
480
|
}
|
|
490
481
|
}
|
|
@@ -531,9 +522,6 @@ class SelectorParser {
|
|
|
531
522
|
if (first_child !== null) {
|
|
532
523
|
this.arena.set_first_child(parent_node, first_child);
|
|
533
524
|
}
|
|
534
|
-
if (last_child !== null) {
|
|
535
|
-
this.arena.set_last_child(parent_node, last_child);
|
|
536
|
-
}
|
|
537
525
|
this.selector_end = saved_selector_end;
|
|
538
526
|
this.lexer.restore_position(saved);
|
|
539
527
|
}
|
|
@@ -562,11 +550,9 @@ class SelectorParser {
|
|
|
562
550
|
);
|
|
563
551
|
if (anplusb_node !== null && selector_list !== null) {
|
|
564
552
|
this.arena.set_first_child(of_node, anplusb_node);
|
|
565
|
-
this.arena.set_last_child(of_node, selector_list);
|
|
566
553
|
this.arena.set_next_sibling(anplusb_node, selector_list);
|
|
567
554
|
} else if (anplusb_node !== null) {
|
|
568
555
|
this.arena.set_first_child(of_node, anplusb_node);
|
|
569
|
-
this.arena.set_last_child(of_node, anplusb_node);
|
|
570
556
|
}
|
|
571
557
|
return of_node;
|
|
572
558
|
} else {
|
package/dist/parse.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { Lexer } from './lexer.js';
|
|
2
|
-
import { CSSDataArena, STYLESHEET, STYLE_RULE, FLAG_HAS_BLOCK, BLOCK, FLAG_HAS_DECLARATIONS, SELECTOR_LIST, DECLARATION,
|
|
2
|
+
import { CSSDataArena, STYLESHEET, STYLE_RULE, FLAG_HAS_BLOCK, BLOCK, FLAG_HAS_DECLARATIONS, SELECTOR_LIST, DECLARATION, FLAG_IMPORTANT, AT_RULE } from './arena.js';
|
|
3
3
|
import { CSSNode } from './css-node.js';
|
|
4
4
|
import { ValueParser } from './parse-value.js';
|
|
5
5
|
import { SelectorParser } from './parse-selector.js';
|
|
6
6
|
import { AtRulePreludeParser } from './parse-atrule-prelude.js';
|
|
7
7
|
import { TOKEN_EOF, TOKEN_AT_KEYWORD, TOKEN_LEFT_BRACE, TOKEN_RIGHT_BRACE, TOKEN_IDENT, TOKEN_COLON, TOKEN_SEMICOLON, TOKEN_DELIM } from './token-types.js';
|
|
8
|
-
import { is_vendor_prefixed } from './string-utils.js';
|
|
9
8
|
import { trim_boundaries } from './parse-utils.js';
|
|
10
9
|
|
|
11
10
|
let DECLARATION_AT_RULES = /* @__PURE__ */ new Set(["font-face", "font-feature-values", "page", "property", "counter-style"]);
|
|
@@ -213,9 +212,6 @@ class Parser {
|
|
|
213
212
|
);
|
|
214
213
|
this.arena.set_content_start_delta(declaration, 0);
|
|
215
214
|
this.arena.set_content_length(declaration, prop_end - prop_start);
|
|
216
|
-
if (is_vendor_prefixed(this.source, prop_start, prop_end)) {
|
|
217
|
-
this.arena.set_flag(declaration, FLAG_VENDOR_PREFIXED);
|
|
218
|
-
}
|
|
219
215
|
let value_start = this.lexer.token_start;
|
|
220
216
|
let value_end = value_start;
|
|
221
217
|
let has_important = false;
|
package/dist/string-utils.d.ts
CHANGED
|
@@ -65,4 +65,5 @@ export declare function str_index_of(str: string, searchChar: string): number;
|
|
|
65
65
|
* - `--custom-property` → false (CSS custom property)
|
|
66
66
|
* - `border-radius` → false (doesn't start with hyphen)
|
|
67
67
|
*/
|
|
68
|
+
export declare function is_vendor_prefixed(text: string): boolean;
|
|
68
69
|
export declare function is_vendor_prefixed(source: string, start: number, end: number): boolean;
|
package/dist/string-utils.js
CHANGED
|
@@ -88,6 +88,10 @@ function str_index_of(str, searchChar) {
|
|
|
88
88
|
return -1;
|
|
89
89
|
}
|
|
90
90
|
function is_vendor_prefixed(source, start, end) {
|
|
91
|
+
if (start === void 0 || end === void 0) {
|
|
92
|
+
start = 0;
|
|
93
|
+
end = source.length;
|
|
94
|
+
}
|
|
91
95
|
if (source.charCodeAt(start) !== CHAR_MINUS_HYPHEN) {
|
|
92
96
|
return false;
|
|
93
97
|
}
|
package/package.json
CHANGED