@stacksjs/ts-css 0.1.1 → 0.1.3
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/CHANGELOG.md +28 -0
- package/dist/chunk-1kmkypmr.js +3 -0
- package/dist/chunk-2wsah70r.js +2 -0
- package/dist/chunk-9ep6bwwb.js +2 -0
- package/dist/chunk-edwg811g.js +2 -0
- package/dist/chunk-thy3p95k.js +3 -0
- package/dist/index.js +57 -12868
- package/dist/optimize/index.js +1 -3389
- package/dist/parse/index.js +1 -2368
- package/dist/select/index.js +1 -1288
- package/dist/what/index.js +1 -513
- package/package.json +1 -1
package/dist/parse/index.js
CHANGED
|
@@ -1,2369 +1,2 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
|
|
3
|
-
var __returnValue = (v) => v;
|
|
4
|
-
function __exportSetter(name, newValue) {
|
|
5
|
-
this[name] = __returnValue.bind(null, newValue);
|
|
6
|
-
}
|
|
7
|
-
var __export = (target, all) => {
|
|
8
|
-
for (var name in all)
|
|
9
|
-
__defProp(target, name, {
|
|
10
|
-
get: all[name],
|
|
11
|
-
enumerable: true,
|
|
12
|
-
configurable: true,
|
|
13
|
-
set: __exportSetter.bind(all, name)
|
|
14
|
-
});
|
|
15
|
-
};
|
|
16
|
-
var __require = import.meta.require;
|
|
17
|
-
|
|
18
|
-
// src/parse/index.ts
|
|
19
|
-
var exports_parse = {};
|
|
20
|
-
__export(exports_parse, {
|
|
21
|
-
walk: () => walk,
|
|
22
|
-
parse: () => parse,
|
|
23
|
-
makeList: () => makeList,
|
|
24
|
-
generate: () => generate,
|
|
25
|
-
decodeName: () => decodeName,
|
|
26
|
-
clone: () => clone,
|
|
27
|
-
Tokenizer: () => Tokenizer,
|
|
28
|
-
TokenType: () => TokenType,
|
|
29
|
-
List: () => CssList
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
// src/parse/list.ts
|
|
33
|
-
function createItem(data) {
|
|
34
|
-
return { prev: null, next: null, data };
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
class CssList {
|
|
38
|
-
head = null;
|
|
39
|
-
tail = null;
|
|
40
|
-
cursors = [];
|
|
41
|
-
allocateCursor(prev, next) {
|
|
42
|
-
const cursor = { prev, next };
|
|
43
|
-
this.cursors.push(cursor);
|
|
44
|
-
return cursor;
|
|
45
|
-
}
|
|
46
|
-
releaseCursor() {
|
|
47
|
-
this.cursors.pop();
|
|
48
|
-
}
|
|
49
|
-
updateCursors(prevOld, prevNew, nextOld, nextNew) {
|
|
50
|
-
for (const c of this.cursors) {
|
|
51
|
-
if (c.prev === prevOld)
|
|
52
|
-
c.prev = prevNew;
|
|
53
|
-
if (c.next === nextOld)
|
|
54
|
-
c.next = nextNew;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
static createItem(data) {
|
|
58
|
-
return createItem(data);
|
|
59
|
-
}
|
|
60
|
-
createItem(data) {
|
|
61
|
-
return createItem(data);
|
|
62
|
-
}
|
|
63
|
-
get isEmpty() {
|
|
64
|
-
return this.head === null;
|
|
65
|
-
}
|
|
66
|
-
get first() {
|
|
67
|
-
return this.head?.data ?? null;
|
|
68
|
-
}
|
|
69
|
-
get last() {
|
|
70
|
-
return this.tail?.data ?? null;
|
|
71
|
-
}
|
|
72
|
-
*[Symbol.iterator]() {
|
|
73
|
-
for (let cur = this.head;cur != null; cur = cur.next)
|
|
74
|
-
yield cur.data;
|
|
75
|
-
}
|
|
76
|
-
fromArray(items) {
|
|
77
|
-
let prev = null;
|
|
78
|
-
this.head = null;
|
|
79
|
-
for (const data of items) {
|
|
80
|
-
const item = createItem(data);
|
|
81
|
-
item.prev = prev;
|
|
82
|
-
if (prev)
|
|
83
|
-
prev.next = item;
|
|
84
|
-
else
|
|
85
|
-
this.head = item;
|
|
86
|
-
prev = item;
|
|
87
|
-
}
|
|
88
|
-
this.tail = prev;
|
|
89
|
-
return this;
|
|
90
|
-
}
|
|
91
|
-
toArray() {
|
|
92
|
-
const out = [];
|
|
93
|
-
for (let cur = this.head;cur != null; cur = cur.next)
|
|
94
|
-
out.push(cur.data);
|
|
95
|
-
return out;
|
|
96
|
-
}
|
|
97
|
-
toJSON() {
|
|
98
|
-
return this.toArray();
|
|
99
|
-
}
|
|
100
|
-
forEach(fn, thisArg) {
|
|
101
|
-
const cursor = this.allocateCursor(null, this.head);
|
|
102
|
-
while (cursor.next !== null) {
|
|
103
|
-
const item = cursor.next;
|
|
104
|
-
cursor.prev = item;
|
|
105
|
-
cursor.next = item.next;
|
|
106
|
-
fn.call(thisArg, item.data, item, this);
|
|
107
|
-
}
|
|
108
|
-
this.releaseCursor();
|
|
109
|
-
}
|
|
110
|
-
forEachRight(fn, thisArg) {
|
|
111
|
-
const cursor = this.allocateCursor(this.tail, null);
|
|
112
|
-
while (cursor.prev !== null) {
|
|
113
|
-
const item = cursor.prev;
|
|
114
|
-
cursor.next = item;
|
|
115
|
-
cursor.prev = item.prev;
|
|
116
|
-
fn.call(thisArg, item.data, item, this);
|
|
117
|
-
}
|
|
118
|
-
this.releaseCursor();
|
|
119
|
-
}
|
|
120
|
-
reduce(fn, initial) {
|
|
121
|
-
let acc = initial;
|
|
122
|
-
let i = 0;
|
|
123
|
-
for (let cur = this.head;cur != null; cur = cur.next)
|
|
124
|
-
acc = fn(acc, cur.data, i++, this);
|
|
125
|
-
return acc;
|
|
126
|
-
}
|
|
127
|
-
some(fn) {
|
|
128
|
-
let i = 0;
|
|
129
|
-
for (let cur = this.head;cur != null; cur = cur.next) {
|
|
130
|
-
if (fn(cur.data, i++, this))
|
|
131
|
-
return true;
|
|
132
|
-
}
|
|
133
|
-
return false;
|
|
134
|
-
}
|
|
135
|
-
map(fn) {
|
|
136
|
-
const result = new CssList;
|
|
137
|
-
let prev = null;
|
|
138
|
-
let i = 0;
|
|
139
|
-
for (let cur = this.head;cur != null; cur = cur.next) {
|
|
140
|
-
const item = createItem(fn(cur.data, i++, this));
|
|
141
|
-
item.prev = prev;
|
|
142
|
-
if (prev)
|
|
143
|
-
prev.next = item;
|
|
144
|
-
else
|
|
145
|
-
result.head = item;
|
|
146
|
-
prev = item;
|
|
147
|
-
}
|
|
148
|
-
result.tail = prev;
|
|
149
|
-
return result;
|
|
150
|
-
}
|
|
151
|
-
filter(fn) {
|
|
152
|
-
const result = new CssList;
|
|
153
|
-
let prev = null;
|
|
154
|
-
let i = 0;
|
|
155
|
-
for (let cur = this.head;cur != null; cur = cur.next) {
|
|
156
|
-
if (fn(cur.data, i++, this)) {
|
|
157
|
-
const item = createItem(cur.data);
|
|
158
|
-
item.prev = prev;
|
|
159
|
-
if (prev)
|
|
160
|
-
prev.next = item;
|
|
161
|
-
else
|
|
162
|
-
result.head = item;
|
|
163
|
-
prev = item;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
result.tail = prev;
|
|
167
|
-
return result;
|
|
168
|
-
}
|
|
169
|
-
clear() {
|
|
170
|
-
let cur = this.head;
|
|
171
|
-
while (cur) {
|
|
172
|
-
const nxt = cur.next;
|
|
173
|
-
cur.prev = null;
|
|
174
|
-
cur.next = null;
|
|
175
|
-
cur = nxt;
|
|
176
|
-
}
|
|
177
|
-
this.head = null;
|
|
178
|
-
this.tail = null;
|
|
179
|
-
}
|
|
180
|
-
copy() {
|
|
181
|
-
const result = new CssList;
|
|
182
|
-
let prev = null;
|
|
183
|
-
for (let cur = this.head;cur != null; cur = cur.next) {
|
|
184
|
-
const item = createItem(cur.data);
|
|
185
|
-
item.prev = prev;
|
|
186
|
-
if (prev)
|
|
187
|
-
prev.next = item;
|
|
188
|
-
else
|
|
189
|
-
result.head = item;
|
|
190
|
-
prev = item;
|
|
191
|
-
}
|
|
192
|
-
result.tail = prev;
|
|
193
|
-
return result;
|
|
194
|
-
}
|
|
195
|
-
prepend(item) {
|
|
196
|
-
return this.insert(item, this.head);
|
|
197
|
-
}
|
|
198
|
-
prependData(data) {
|
|
199
|
-
return this.insert(createItem(data), this.head);
|
|
200
|
-
}
|
|
201
|
-
append(item) {
|
|
202
|
-
return this.insert(item, null);
|
|
203
|
-
}
|
|
204
|
-
appendData(data) {
|
|
205
|
-
return this.insert(createItem(data), null);
|
|
206
|
-
}
|
|
207
|
-
insert(item, before = null) {
|
|
208
|
-
if (before != null) {
|
|
209
|
-
this.updateCursors(before.prev, item, before, item);
|
|
210
|
-
if (before.prev === null) {
|
|
211
|
-
if (this.head !== before)
|
|
212
|
-
throw new Error("before doesn't belong to list");
|
|
213
|
-
this.head = item;
|
|
214
|
-
before.prev = item;
|
|
215
|
-
item.next = before;
|
|
216
|
-
this.updateCursors(null, item, null, null);
|
|
217
|
-
} else {
|
|
218
|
-
before.prev.next = item;
|
|
219
|
-
item.prev = before.prev;
|
|
220
|
-
before.prev = item;
|
|
221
|
-
item.next = before;
|
|
222
|
-
}
|
|
223
|
-
} else {
|
|
224
|
-
this.updateCursors(this.tail, item, null, item);
|
|
225
|
-
if (this.tail !== null) {
|
|
226
|
-
this.tail.next = item;
|
|
227
|
-
item.prev = this.tail;
|
|
228
|
-
this.tail = item;
|
|
229
|
-
} else {
|
|
230
|
-
this.head = item;
|
|
231
|
-
this.tail = item;
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
return this;
|
|
235
|
-
}
|
|
236
|
-
insertData(data, before = null) {
|
|
237
|
-
return this.insert(createItem(data), before);
|
|
238
|
-
}
|
|
239
|
-
remove(item) {
|
|
240
|
-
this.updateCursors(item, item.prev, item, item.next);
|
|
241
|
-
if (item.prev !== null)
|
|
242
|
-
item.prev.next = item.next;
|
|
243
|
-
else if (this.head === item)
|
|
244
|
-
this.head = item.next;
|
|
245
|
-
else
|
|
246
|
-
throw new Error("item doesn't belong to list");
|
|
247
|
-
if (item.next !== null)
|
|
248
|
-
item.next.prev = item.prev;
|
|
249
|
-
else if (this.tail === item)
|
|
250
|
-
this.tail = item.prev;
|
|
251
|
-
else
|
|
252
|
-
throw new Error("item doesn't belong to list");
|
|
253
|
-
item.prev = null;
|
|
254
|
-
item.next = null;
|
|
255
|
-
return item;
|
|
256
|
-
}
|
|
257
|
-
push(data) {
|
|
258
|
-
this.insert(createItem(data), null);
|
|
259
|
-
}
|
|
260
|
-
pop() {
|
|
261
|
-
if (this.tail === null)
|
|
262
|
-
return null;
|
|
263
|
-
return this.remove(this.tail);
|
|
264
|
-
}
|
|
265
|
-
unshift(data) {
|
|
266
|
-
this.prependData(data);
|
|
267
|
-
}
|
|
268
|
-
shift() {
|
|
269
|
-
if (this.head === null)
|
|
270
|
-
return null;
|
|
271
|
-
return this.remove(this.head);
|
|
272
|
-
}
|
|
273
|
-
prependList(list) {
|
|
274
|
-
return this.insertList(list, this.head);
|
|
275
|
-
}
|
|
276
|
-
appendList(list) {
|
|
277
|
-
return this.insertList(list, null);
|
|
278
|
-
}
|
|
279
|
-
insertList(list, before = null) {
|
|
280
|
-
if (list.head === null)
|
|
281
|
-
return this;
|
|
282
|
-
if (before !== null) {
|
|
283
|
-
this.updateCursors(before.prev, list.tail, before, list.head);
|
|
284
|
-
if (before.prev !== null) {
|
|
285
|
-
before.prev.next = list.head;
|
|
286
|
-
list.head.prev = before.prev;
|
|
287
|
-
} else {
|
|
288
|
-
this.head = list.head;
|
|
289
|
-
}
|
|
290
|
-
before.prev = list.tail;
|
|
291
|
-
list.tail.next = before;
|
|
292
|
-
} else {
|
|
293
|
-
this.updateCursors(this.tail, list.tail, null, list.head);
|
|
294
|
-
if (this.tail !== null) {
|
|
295
|
-
this.tail.next = list.head;
|
|
296
|
-
list.head.prev = this.tail;
|
|
297
|
-
} else {
|
|
298
|
-
this.head = list.head;
|
|
299
|
-
}
|
|
300
|
-
this.tail = list.tail;
|
|
301
|
-
}
|
|
302
|
-
list.head = null;
|
|
303
|
-
list.tail = null;
|
|
304
|
-
return this;
|
|
305
|
-
}
|
|
306
|
-
replace(oldItem, newItemOrList) {
|
|
307
|
-
if (newItemOrList instanceof CssList) {
|
|
308
|
-
this.insertList(newItemOrList, oldItem);
|
|
309
|
-
this.remove(oldItem);
|
|
310
|
-
} else {
|
|
311
|
-
this.insert(newItemOrList, oldItem);
|
|
312
|
-
this.remove(oldItem);
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
function makeList() {
|
|
317
|
-
return new CssList;
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
// src/parse/clone.ts
|
|
321
|
-
function clone(node) {
|
|
322
|
-
return cloneAny(node);
|
|
323
|
-
}
|
|
324
|
-
function cloneAny(value) {
|
|
325
|
-
if (value === null || typeof value !== "object")
|
|
326
|
-
return value;
|
|
327
|
-
if (value instanceof CssList) {
|
|
328
|
-
const out2 = new CssList;
|
|
329
|
-
for (const child of value)
|
|
330
|
-
out2.appendData(cloneAny(child));
|
|
331
|
-
return out2;
|
|
332
|
-
}
|
|
333
|
-
if (Array.isArray(value))
|
|
334
|
-
return value.map(cloneAny);
|
|
335
|
-
if ("type" in value && typeof value.type === "string") {
|
|
336
|
-
const out2 = { type: value.type };
|
|
337
|
-
for (const k of Object.keys(value)) {
|
|
338
|
-
if (k === "type")
|
|
339
|
-
continue;
|
|
340
|
-
out2[k] = cloneAny(value[k]);
|
|
341
|
-
}
|
|
342
|
-
return out2;
|
|
343
|
-
}
|
|
344
|
-
const out = {};
|
|
345
|
-
for (const k of Object.keys(value))
|
|
346
|
-
out[k] = cloneAny(value[k]);
|
|
347
|
-
return out;
|
|
348
|
-
}
|
|
349
|
-
// src/parse/generator.ts
|
|
350
|
-
function generate(node) {
|
|
351
|
-
switch (node.type) {
|
|
352
|
-
case "StyleSheet":
|
|
353
|
-
return joinChildren(node.children, "");
|
|
354
|
-
case "Rule":
|
|
355
|
-
return `${generate(node.prelude)}{${generate(node.block)}}`;
|
|
356
|
-
case "Block":
|
|
357
|
-
return joinBlockChildren(node.children);
|
|
358
|
-
case "Atrule": {
|
|
359
|
-
let out = `@${node.name}`;
|
|
360
|
-
if (node.prelude) {
|
|
361
|
-
const p = generate(node.prelude);
|
|
362
|
-
if (p)
|
|
363
|
-
out += ` ${p}`;
|
|
364
|
-
}
|
|
365
|
-
if (node.block) {
|
|
366
|
-
out += `{${generate(node.block)}}`;
|
|
367
|
-
} else {
|
|
368
|
-
out += ";";
|
|
369
|
-
}
|
|
370
|
-
return out;
|
|
371
|
-
}
|
|
372
|
-
case "AtrulePrelude":
|
|
373
|
-
return joinChildren(node.children, "");
|
|
374
|
-
case "SelectorList":
|
|
375
|
-
return joinChildren(node.children, ",");
|
|
376
|
-
case "Selector":
|
|
377
|
-
return joinChildren(node.children, "");
|
|
378
|
-
case "TypeSelector":
|
|
379
|
-
return node.name;
|
|
380
|
-
case "IdSelector":
|
|
381
|
-
return `#${node.name}`;
|
|
382
|
-
case "ClassSelector":
|
|
383
|
-
return `.${node.name}`;
|
|
384
|
-
case "NestingSelector":
|
|
385
|
-
return "&";
|
|
386
|
-
case "AttributeSelector": {
|
|
387
|
-
let out = `[${node.name.name}`;
|
|
388
|
-
if (node.matcher && node.value) {
|
|
389
|
-
out += node.matcher;
|
|
390
|
-
if (node.value.type === "String")
|
|
391
|
-
out += `"${escapeStringContent(node.value.value)}"`;
|
|
392
|
-
else
|
|
393
|
-
out += node.value.name;
|
|
394
|
-
}
|
|
395
|
-
if (node.flags)
|
|
396
|
-
out += ` ${node.flags}`;
|
|
397
|
-
out += "]";
|
|
398
|
-
return out;
|
|
399
|
-
}
|
|
400
|
-
case "PseudoClassSelector":
|
|
401
|
-
return node.children ? `:${node.name}(${joinChildren(node.children, "")})` : `:${node.name}`;
|
|
402
|
-
case "PseudoElementSelector":
|
|
403
|
-
return node.children ? `::${node.name}(${joinChildren(node.children, "")})` : `::${node.name}`;
|
|
404
|
-
case "Combinator":
|
|
405
|
-
return node.name === " " ? " " : node.name;
|
|
406
|
-
case "Declaration":
|
|
407
|
-
return `${node.property}:${generate(node.value)}${node.important ? "!important" : ""}`;
|
|
408
|
-
case "DeclarationList":
|
|
409
|
-
return joinChildren(node.children, ";");
|
|
410
|
-
case "Value":
|
|
411
|
-
return joinChildren(node.children, "");
|
|
412
|
-
case "Identifier":
|
|
413
|
-
return node.name;
|
|
414
|
-
case "Number":
|
|
415
|
-
return node.value;
|
|
416
|
-
case "Percentage":
|
|
417
|
-
return `${node.value}%`;
|
|
418
|
-
case "Dimension":
|
|
419
|
-
return node.value + node.unit;
|
|
420
|
-
case "String":
|
|
421
|
-
return `"${escapeStringContent(node.value)}"`;
|
|
422
|
-
case "Url":
|
|
423
|
-
return /[\s"'()\\\u0000-\u001F\u007F]/.test(node.value) ? `url("${escapeStringContent(node.value)}")` : `url(${node.value})`;
|
|
424
|
-
case "Hash":
|
|
425
|
-
return `#${node.name}`;
|
|
426
|
-
case "Operator":
|
|
427
|
-
return node.value;
|
|
428
|
-
case "Function":
|
|
429
|
-
return `${node.name}(${joinChildren(node.children, "")})`;
|
|
430
|
-
case "Parentheses":
|
|
431
|
-
return `(${joinChildren(node.children, "")})`;
|
|
432
|
-
case "Brackets":
|
|
433
|
-
return `[${joinChildren(node.children, "")}]`;
|
|
434
|
-
case "Raw":
|
|
435
|
-
return node.value;
|
|
436
|
-
case "Comment":
|
|
437
|
-
return node.value.startsWith("!") ? `/*${node.value}*/` : "";
|
|
438
|
-
case "WhiteSpace":
|
|
439
|
-
return " ";
|
|
440
|
-
case "CDO":
|
|
441
|
-
return "<!--";
|
|
442
|
-
case "CDC":
|
|
443
|
-
return "-->";
|
|
444
|
-
case "AnPlusB": {
|
|
445
|
-
const a = node.a ?? "";
|
|
446
|
-
const b = node.b ?? "";
|
|
447
|
-
if (a && b) {
|
|
448
|
-
const bn = Number(b);
|
|
449
|
-
return `${a === "1" ? "" : a === "-1" ? "-" : a}n${bn >= 0 ? `+${b}` : b}`;
|
|
450
|
-
}
|
|
451
|
-
if (a)
|
|
452
|
-
return `${a === "1" ? "" : a === "-1" ? "-" : a}n`;
|
|
453
|
-
return b;
|
|
454
|
-
}
|
|
455
|
-
case "Ratio":
|
|
456
|
-
return `${node.left.value}/${node.right.value}`;
|
|
457
|
-
case "UnicodeRange":
|
|
458
|
-
return node.value;
|
|
459
|
-
case "Nth":
|
|
460
|
-
return node.selector ? `${generate(node.nth)} of ${generate(node.selector)}` : generate(node.nth);
|
|
461
|
-
case "MediaQueryList":
|
|
462
|
-
return joinChildren(node.children, ",");
|
|
463
|
-
case "MediaQuery":
|
|
464
|
-
return joinChildren(node.children, "");
|
|
465
|
-
case "MediaFeature": {
|
|
466
|
-
let out = `(${node.name}`;
|
|
467
|
-
if (node.value)
|
|
468
|
-
out += `:${generate(node.value)}`;
|
|
469
|
-
out += ")";
|
|
470
|
-
return out;
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
return "";
|
|
474
|
-
}
|
|
475
|
-
function joinChildren(list, separator) {
|
|
476
|
-
let out = "";
|
|
477
|
-
let first = true;
|
|
478
|
-
let prev = null;
|
|
479
|
-
let cur = list.head;
|
|
480
|
-
while (cur != null) {
|
|
481
|
-
const child = cur.data;
|
|
482
|
-
if (child.type === "WhiteSpace") {
|
|
483
|
-
const nextNode = cur.next ? cur.next.data : null;
|
|
484
|
-
if (isCompactOperator(prev) || isCompactOperator(nextNode)) {
|
|
485
|
-
cur = cur.next;
|
|
486
|
-
continue;
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
const text = generate(child);
|
|
490
|
-
if (!text) {
|
|
491
|
-
cur = cur.next;
|
|
492
|
-
continue;
|
|
493
|
-
}
|
|
494
|
-
if (!first && separator && !isStructuralSeparator(prev))
|
|
495
|
-
out += separator;
|
|
496
|
-
first = false;
|
|
497
|
-
out += text;
|
|
498
|
-
prev = child;
|
|
499
|
-
cur = cur.next;
|
|
500
|
-
}
|
|
501
|
-
return out;
|
|
502
|
-
}
|
|
503
|
-
function joinBlockChildren(list) {
|
|
504
|
-
let out = "";
|
|
505
|
-
let prev = null;
|
|
506
|
-
let cur = list.head;
|
|
507
|
-
while (cur != null) {
|
|
508
|
-
const child = cur.data;
|
|
509
|
-
const text = generate(child);
|
|
510
|
-
if (!text) {
|
|
511
|
-
cur = cur.next;
|
|
512
|
-
continue;
|
|
513
|
-
}
|
|
514
|
-
if (prev && needsSemicolon(prev, child))
|
|
515
|
-
out += ";";
|
|
516
|
-
out += text;
|
|
517
|
-
prev = child;
|
|
518
|
-
cur = cur.next;
|
|
519
|
-
}
|
|
520
|
-
return out;
|
|
521
|
-
}
|
|
522
|
-
function needsSemicolon(prev, next) {
|
|
523
|
-
return prev.type === "Declaration" && next.type !== "Comment";
|
|
524
|
-
}
|
|
525
|
-
function isCompactOperator(node) {
|
|
526
|
-
if (!node || node.type !== "Operator")
|
|
527
|
-
return false;
|
|
528
|
-
const v = node.value;
|
|
529
|
-
return v === ":" || v === "," || v === "/";
|
|
530
|
-
}
|
|
531
|
-
function isStructuralSeparator(node) {
|
|
532
|
-
if (!node)
|
|
533
|
-
return false;
|
|
534
|
-
return node.type === "Operator" || node.type === "Combinator";
|
|
535
|
-
}
|
|
536
|
-
function escapeStringContent(s) {
|
|
537
|
-
let out = "";
|
|
538
|
-
for (let i = 0;i < s.length; i++) {
|
|
539
|
-
const ch = s.charCodeAt(i);
|
|
540
|
-
if (ch === 92) {
|
|
541
|
-
out += "\\\\";
|
|
542
|
-
} else if (ch === 34) {
|
|
543
|
-
out += "\\\"";
|
|
544
|
-
} else if (ch < 32 || ch === 127) {
|
|
545
|
-
const hex = ch.toString(16);
|
|
546
|
-
const next = i + 1 < s.length ? s.charCodeAt(i + 1) : -1;
|
|
547
|
-
const needsSpace = next === 32 || next === 9 || next === 10 || next === 12 || next === 13 || next >= 48 && next <= 57 || next >= 65 && next <= 70 || next >= 97 && next <= 102;
|
|
548
|
-
out += `\\${hex}${needsSpace ? " " : ""}`;
|
|
549
|
-
} else {
|
|
550
|
-
out += s[i];
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
return out;
|
|
554
|
-
}
|
|
555
|
-
// src/parse/tokenizer.ts
|
|
556
|
-
var TokenType;
|
|
557
|
-
((TokenType2) => {
|
|
558
|
-
TokenType2[TokenType2["EOF"] = 0] = "EOF";
|
|
559
|
-
TokenType2[TokenType2["Ident"] = 1] = "Ident";
|
|
560
|
-
TokenType2[TokenType2["Function"] = 2] = "Function";
|
|
561
|
-
TokenType2[TokenType2["AtKeyword"] = 3] = "AtKeyword";
|
|
562
|
-
TokenType2[TokenType2["Hash"] = 4] = "Hash";
|
|
563
|
-
TokenType2[TokenType2["String"] = 5] = "String";
|
|
564
|
-
TokenType2[TokenType2["BadString"] = 6] = "BadString";
|
|
565
|
-
TokenType2[TokenType2["Url"] = 7] = "Url";
|
|
566
|
-
TokenType2[TokenType2["BadUrl"] = 8] = "BadUrl";
|
|
567
|
-
TokenType2[TokenType2["Delim"] = 9] = "Delim";
|
|
568
|
-
TokenType2[TokenType2["Number"] = 10] = "Number";
|
|
569
|
-
TokenType2[TokenType2["Percentage"] = 11] = "Percentage";
|
|
570
|
-
TokenType2[TokenType2["Dimension"] = 12] = "Dimension";
|
|
571
|
-
TokenType2[TokenType2["WhiteSpace"] = 13] = "WhiteSpace";
|
|
572
|
-
TokenType2[TokenType2["CDO"] = 14] = "CDO";
|
|
573
|
-
TokenType2[TokenType2["CDC"] = 15] = "CDC";
|
|
574
|
-
TokenType2[TokenType2["Colon"] = 16] = "Colon";
|
|
575
|
-
TokenType2[TokenType2["Semicolon"] = 17] = "Semicolon";
|
|
576
|
-
TokenType2[TokenType2["Comma"] = 18] = "Comma";
|
|
577
|
-
TokenType2[TokenType2["LeftSquareBracket"] = 19] = "LeftSquareBracket";
|
|
578
|
-
TokenType2[TokenType2["RightSquareBracket"] = 20] = "RightSquareBracket";
|
|
579
|
-
TokenType2[TokenType2["LeftParenthesis"] = 21] = "LeftParenthesis";
|
|
580
|
-
TokenType2[TokenType2["RightParenthesis"] = 22] = "RightParenthesis";
|
|
581
|
-
TokenType2[TokenType2["LeftCurlyBracket"] = 23] = "LeftCurlyBracket";
|
|
582
|
-
TokenType2[TokenType2["RightCurlyBracket"] = 24] = "RightCurlyBracket";
|
|
583
|
-
TokenType2[TokenType2["Comment"] = 25] = "Comment";
|
|
584
|
-
})(TokenType ||= {});
|
|
585
|
-
var REPLACEMENT = 65533;
|
|
586
|
-
var CHAR_CLASS = (() => {
|
|
587
|
-
const t = new Uint8Array(128);
|
|
588
|
-
for (let c = 0;c < 128; c++) {
|
|
589
|
-
let bits = 0;
|
|
590
|
-
if (c === 32 || c === 9 || c === 10 || c === 12 || c === 13)
|
|
591
|
-
bits |= 1;
|
|
592
|
-
if (c >= 48 && c <= 57)
|
|
593
|
-
bits |= 2;
|
|
594
|
-
if (c >= 48 && c <= 57 || c >= 65 && c <= 70 || c >= 97 && c <= 102)
|
|
595
|
-
bits |= 4;
|
|
596
|
-
if (c >= 65 && c <= 90 || c >= 97 && c <= 122 || c === 95)
|
|
597
|
-
bits |= 8;
|
|
598
|
-
if (c === 10 || c === 12 || c === 13)
|
|
599
|
-
bits |= 16;
|
|
600
|
-
t[c] = bits;
|
|
601
|
-
}
|
|
602
|
-
return t;
|
|
603
|
-
})();
|
|
604
|
-
function isDigit(code) {
|
|
605
|
-
return code < 128 && (CHAR_CLASS[code] & 2) !== 0;
|
|
606
|
-
}
|
|
607
|
-
function isHexDigit(code) {
|
|
608
|
-
return code < 128 && (CHAR_CLASS[code] & 4) !== 0;
|
|
609
|
-
}
|
|
610
|
-
function isNameStart(code) {
|
|
611
|
-
return code >= 128 || code < 128 && (CHAR_CLASS[code] & 8) !== 0;
|
|
612
|
-
}
|
|
613
|
-
function isName(code) {
|
|
614
|
-
return code === 45 || code >= 128 || code < 128 && (CHAR_CLASS[code] & (2 | 8)) !== 0;
|
|
615
|
-
}
|
|
616
|
-
function isNonPrintable(code) {
|
|
617
|
-
return code >= 0 && code <= 8 || code === 11 || code >= 14 && code <= 31 || code === 127;
|
|
618
|
-
}
|
|
619
|
-
function isNewline(code) {
|
|
620
|
-
return code < 128 && (CHAR_CLASS[code] & 16) !== 0;
|
|
621
|
-
}
|
|
622
|
-
function isWhitespace(code) {
|
|
623
|
-
return code < 128 && (CHAR_CLASS[code] & 1) !== 0;
|
|
624
|
-
}
|
|
625
|
-
function isValidEscape(c1, c2) {
|
|
626
|
-
if (c1 !== 92)
|
|
627
|
-
return false;
|
|
628
|
-
if (isNewline(c2))
|
|
629
|
-
return false;
|
|
630
|
-
return true;
|
|
631
|
-
}
|
|
632
|
-
function startsIdentifier(c1, c2, c3) {
|
|
633
|
-
if (c1 === 45) {
|
|
634
|
-
return isNameStart(c2) || c2 === 45 || isValidEscape(c2, c3);
|
|
635
|
-
}
|
|
636
|
-
if (isNameStart(c1))
|
|
637
|
-
return true;
|
|
638
|
-
if (c1 === 92)
|
|
639
|
-
return isValidEscape(c1, c2);
|
|
640
|
-
return false;
|
|
641
|
-
}
|
|
642
|
-
function startsNumber(c1, c2, c3) {
|
|
643
|
-
if (c1 === 43 || c1 === 45) {
|
|
644
|
-
if (isDigit(c2))
|
|
645
|
-
return true;
|
|
646
|
-
if (c2 === 46 && isDigit(c3))
|
|
647
|
-
return true;
|
|
648
|
-
return false;
|
|
649
|
-
}
|
|
650
|
-
if (c1 === 46)
|
|
651
|
-
return isDigit(c2);
|
|
652
|
-
return isDigit(c1);
|
|
653
|
-
}
|
|
654
|
-
|
|
655
|
-
class Tokenizer {
|
|
656
|
-
source;
|
|
657
|
-
offset = 0;
|
|
658
|
-
types;
|
|
659
|
-
starts;
|
|
660
|
-
ends;
|
|
661
|
-
count = 0;
|
|
662
|
-
_tokens = null;
|
|
663
|
-
_lineStarts = null;
|
|
664
|
-
constructor(source) {
|
|
665
|
-
this.source = source;
|
|
666
|
-
const cap = Math.max(64, Math.ceil(source.length / 3));
|
|
667
|
-
this.types = new Uint8Array(cap);
|
|
668
|
-
this.starts = new Uint32Array(cap);
|
|
669
|
-
this.ends = new Uint32Array(cap);
|
|
670
|
-
this.tokenize();
|
|
671
|
-
}
|
|
672
|
-
get lineStarts() {
|
|
673
|
-
if (this._lineStarts == null)
|
|
674
|
-
this._lineStarts = buildLineStarts(this.source);
|
|
675
|
-
return this._lineStarts;
|
|
676
|
-
}
|
|
677
|
-
get tokens() {
|
|
678
|
-
if (this._tokens != null)
|
|
679
|
-
return this._tokens;
|
|
680
|
-
const out = Array.from({ length: this.count });
|
|
681
|
-
for (let i = 0;i < this.count; i++)
|
|
682
|
-
out[i] = { type: this.types[i], start: this.starts[i], end: this.ends[i] };
|
|
683
|
-
this._tokens = out;
|
|
684
|
-
return out;
|
|
685
|
-
}
|
|
686
|
-
addToken(type, start, end) {
|
|
687
|
-
if (this.count >= this.types.length)
|
|
688
|
-
this.grow();
|
|
689
|
-
this.types[this.count] = type;
|
|
690
|
-
this.starts[this.count] = start;
|
|
691
|
-
this.ends[this.count] = end;
|
|
692
|
-
this.count++;
|
|
693
|
-
}
|
|
694
|
-
grow() {
|
|
695
|
-
const oldLen = this.types.length;
|
|
696
|
-
const newLen = oldLen * 2;
|
|
697
|
-
const t = new Uint8Array(newLen);
|
|
698
|
-
t.set(this.types);
|
|
699
|
-
this.types = t;
|
|
700
|
-
const s = new Uint32Array(newLen);
|
|
701
|
-
s.set(this.starts);
|
|
702
|
-
this.starts = s;
|
|
703
|
-
const e = new Uint32Array(newLen);
|
|
704
|
-
e.set(this.ends);
|
|
705
|
-
this.ends = e;
|
|
706
|
-
}
|
|
707
|
-
tokenize() {
|
|
708
|
-
const src = this.source;
|
|
709
|
-
let i = 0;
|
|
710
|
-
const len = src.length;
|
|
711
|
-
while (i < len) {
|
|
712
|
-
const c1 = src.charCodeAt(i);
|
|
713
|
-
if (c1 === 47 && src.charCodeAt(i + 1) === 42) {
|
|
714
|
-
const start = i;
|
|
715
|
-
i += 2;
|
|
716
|
-
while (i < len && !(src.charCodeAt(i) === 42 && src.charCodeAt(i + 1) === 47))
|
|
717
|
-
i++;
|
|
718
|
-
i = i < len ? i + 2 : len;
|
|
719
|
-
this.addToken(25 /* Comment */, start, i);
|
|
720
|
-
continue;
|
|
721
|
-
}
|
|
722
|
-
if (isWhitespace(c1)) {
|
|
723
|
-
const start = i;
|
|
724
|
-
while (i < len && isWhitespace(src.charCodeAt(i)))
|
|
725
|
-
i++;
|
|
726
|
-
this.addToken(13 /* WhiteSpace */, start, i);
|
|
727
|
-
continue;
|
|
728
|
-
}
|
|
729
|
-
if (c1 === 34 || c1 === 39) {
|
|
730
|
-
i = this.consumeString(c1, i);
|
|
731
|
-
continue;
|
|
732
|
-
}
|
|
733
|
-
if (c1 === 35) {
|
|
734
|
-
if (i + 1 < len && (isName(src.charCodeAt(i + 1)) || isValidEscape(src.charCodeAt(i + 1), src.charCodeAt(i + 2)))) {
|
|
735
|
-
const start = i;
|
|
736
|
-
i++;
|
|
737
|
-
i = this.consumeName(i);
|
|
738
|
-
this.addToken(4 /* Hash */, start, i);
|
|
739
|
-
continue;
|
|
740
|
-
}
|
|
741
|
-
this.addToken(9 /* Delim */, i, i + 1);
|
|
742
|
-
i++;
|
|
743
|
-
continue;
|
|
744
|
-
}
|
|
745
|
-
switch (c1) {
|
|
746
|
-
case 40:
|
|
747
|
-
this.addToken(21 /* LeftParenthesis */, i, i + 1);
|
|
748
|
-
i++;
|
|
749
|
-
continue;
|
|
750
|
-
case 41:
|
|
751
|
-
this.addToken(22 /* RightParenthesis */, i, i + 1);
|
|
752
|
-
i++;
|
|
753
|
-
continue;
|
|
754
|
-
case 91:
|
|
755
|
-
this.addToken(19 /* LeftSquareBracket */, i, i + 1);
|
|
756
|
-
i++;
|
|
757
|
-
continue;
|
|
758
|
-
case 93:
|
|
759
|
-
this.addToken(20 /* RightSquareBracket */, i, i + 1);
|
|
760
|
-
i++;
|
|
761
|
-
continue;
|
|
762
|
-
case 123:
|
|
763
|
-
this.addToken(23 /* LeftCurlyBracket */, i, i + 1);
|
|
764
|
-
i++;
|
|
765
|
-
continue;
|
|
766
|
-
case 125:
|
|
767
|
-
this.addToken(24 /* RightCurlyBracket */, i, i + 1);
|
|
768
|
-
i++;
|
|
769
|
-
continue;
|
|
770
|
-
case 44:
|
|
771
|
-
this.addToken(18 /* Comma */, i, i + 1);
|
|
772
|
-
i++;
|
|
773
|
-
continue;
|
|
774
|
-
case 58:
|
|
775
|
-
this.addToken(16 /* Colon */, i, i + 1);
|
|
776
|
-
i++;
|
|
777
|
-
continue;
|
|
778
|
-
case 59:
|
|
779
|
-
this.addToken(17 /* Semicolon */, i, i + 1);
|
|
780
|
-
i++;
|
|
781
|
-
continue;
|
|
782
|
-
}
|
|
783
|
-
if (c1 === 60 && src.startsWith("!--", i + 1)) {
|
|
784
|
-
this.addToken(14 /* CDO */, i, i + 4);
|
|
785
|
-
i += 4;
|
|
786
|
-
continue;
|
|
787
|
-
}
|
|
788
|
-
if (c1 === 45 && src.startsWith("->", i + 1)) {
|
|
789
|
-
this.addToken(15 /* CDC */, i, i + 3);
|
|
790
|
-
i += 3;
|
|
791
|
-
continue;
|
|
792
|
-
}
|
|
793
|
-
if (c1 === 64) {
|
|
794
|
-
const c22 = src.charCodeAt(i + 1);
|
|
795
|
-
const c32 = src.charCodeAt(i + 2);
|
|
796
|
-
const c4 = src.charCodeAt(i + 3);
|
|
797
|
-
if (startsIdentifier(c22, c32, c4)) {
|
|
798
|
-
const start = i;
|
|
799
|
-
i++;
|
|
800
|
-
i = this.consumeName(i);
|
|
801
|
-
this.addToken(3 /* AtKeyword */, start, i);
|
|
802
|
-
continue;
|
|
803
|
-
}
|
|
804
|
-
this.addToken(9 /* Delim */, i, i + 1);
|
|
805
|
-
i++;
|
|
806
|
-
continue;
|
|
807
|
-
}
|
|
808
|
-
const c2 = src.charCodeAt(i + 1);
|
|
809
|
-
const c3 = src.charCodeAt(i + 2);
|
|
810
|
-
if (startsNumber(c1, c2, c3)) {
|
|
811
|
-
i = this.consumeNumeric(i);
|
|
812
|
-
continue;
|
|
813
|
-
}
|
|
814
|
-
if (startsIdentifier(c1, c2, c3)) {
|
|
815
|
-
i = this.consumeIdentLike(i);
|
|
816
|
-
continue;
|
|
817
|
-
}
|
|
818
|
-
if (c1 === 92) {
|
|
819
|
-
if (isValidEscape(c1, c2)) {
|
|
820
|
-
i = this.consumeIdentLike(i);
|
|
821
|
-
continue;
|
|
822
|
-
}
|
|
823
|
-
this.addToken(9 /* Delim */, i, i + 1);
|
|
824
|
-
i++;
|
|
825
|
-
continue;
|
|
826
|
-
}
|
|
827
|
-
this.addToken(9 /* Delim */, i, i + 1);
|
|
828
|
-
i++;
|
|
829
|
-
}
|
|
830
|
-
this.addToken(0 /* EOF */, len, len);
|
|
831
|
-
}
|
|
832
|
-
consumeString(quote, start) {
|
|
833
|
-
const src = this.source;
|
|
834
|
-
const len = src.length;
|
|
835
|
-
let i = start + 1;
|
|
836
|
-
while (i < len) {
|
|
837
|
-
const c = src.charCodeAt(i);
|
|
838
|
-
if (c === quote) {
|
|
839
|
-
i++;
|
|
840
|
-
this.addToken(5 /* String */, start, i);
|
|
841
|
-
return i;
|
|
842
|
-
}
|
|
843
|
-
if (isNewline(c)) {
|
|
844
|
-
this.addToken(6 /* BadString */, start, i);
|
|
845
|
-
return i;
|
|
846
|
-
}
|
|
847
|
-
if (c === 92) {
|
|
848
|
-
const c2 = src.charCodeAt(i + 1);
|
|
849
|
-
if (isNewline(c2)) {
|
|
850
|
-
i += 2;
|
|
851
|
-
continue;
|
|
852
|
-
}
|
|
853
|
-
if (i + 1 < len) {
|
|
854
|
-
i = this.consumeEscapeSkip(i + 1);
|
|
855
|
-
continue;
|
|
856
|
-
}
|
|
857
|
-
}
|
|
858
|
-
i++;
|
|
859
|
-
}
|
|
860
|
-
this.addToken(5 /* String */, start, i);
|
|
861
|
-
return i;
|
|
862
|
-
}
|
|
863
|
-
consumeEscapeSkip(i) {
|
|
864
|
-
const src = this.source;
|
|
865
|
-
if (i >= src.length)
|
|
866
|
-
return i;
|
|
867
|
-
const c = src.charCodeAt(i);
|
|
868
|
-
if (isHexDigit(c)) {
|
|
869
|
-
let n = 1;
|
|
870
|
-
i++;
|
|
871
|
-
while (n < 6 && i < src.length && isHexDigit(src.charCodeAt(i))) {
|
|
872
|
-
i++;
|
|
873
|
-
n++;
|
|
874
|
-
}
|
|
875
|
-
if (i < src.length && isWhitespace(src.charCodeAt(i)))
|
|
876
|
-
i++;
|
|
877
|
-
return i;
|
|
878
|
-
}
|
|
879
|
-
return i + 1;
|
|
880
|
-
}
|
|
881
|
-
consumeName(start) {
|
|
882
|
-
const src = this.source;
|
|
883
|
-
const len = src.length;
|
|
884
|
-
let i = start;
|
|
885
|
-
while (i < len) {
|
|
886
|
-
const c = src.charCodeAt(i);
|
|
887
|
-
if (c < 128 && (CHAR_CLASS[c] & (2 | 8)) !== 0) {
|
|
888
|
-
i++;
|
|
889
|
-
continue;
|
|
890
|
-
}
|
|
891
|
-
if (c === 45) {
|
|
892
|
-
i++;
|
|
893
|
-
continue;
|
|
894
|
-
}
|
|
895
|
-
if (c >= 128) {
|
|
896
|
-
i++;
|
|
897
|
-
continue;
|
|
898
|
-
}
|
|
899
|
-
if (c === 92 && isValidEscape(c, src.charCodeAt(i + 1))) {
|
|
900
|
-
i = this.consumeEscapeSkip(i + 1);
|
|
901
|
-
continue;
|
|
902
|
-
}
|
|
903
|
-
break;
|
|
904
|
-
}
|
|
905
|
-
return i;
|
|
906
|
-
}
|
|
907
|
-
consumeNumber(start) {
|
|
908
|
-
const src = this.source;
|
|
909
|
-
let i = start;
|
|
910
|
-
if (src.charCodeAt(i) === 43 || src.charCodeAt(i) === 45)
|
|
911
|
-
i++;
|
|
912
|
-
while (i < src.length && isDigit(src.charCodeAt(i)))
|
|
913
|
-
i++;
|
|
914
|
-
if (src.charCodeAt(i) === 46 && isDigit(src.charCodeAt(i + 1))) {
|
|
915
|
-
i += 2;
|
|
916
|
-
while (i < src.length && isDigit(src.charCodeAt(i)))
|
|
917
|
-
i++;
|
|
918
|
-
}
|
|
919
|
-
const eC = src.charCodeAt(i);
|
|
920
|
-
if (eC === 69 || eC === 101) {
|
|
921
|
-
const next = src.charCodeAt(i + 1);
|
|
922
|
-
const next2 = src.charCodeAt(i + 2);
|
|
923
|
-
if (isDigit(next)) {
|
|
924
|
-
i += 2;
|
|
925
|
-
while (i < src.length && isDigit(src.charCodeAt(i)))
|
|
926
|
-
i++;
|
|
927
|
-
} else if ((next === 43 || next === 45) && isDigit(next2)) {
|
|
928
|
-
i += 3;
|
|
929
|
-
while (i < src.length && isDigit(src.charCodeAt(i)))
|
|
930
|
-
i++;
|
|
931
|
-
}
|
|
932
|
-
}
|
|
933
|
-
return i;
|
|
934
|
-
}
|
|
935
|
-
consumeNumeric(start) {
|
|
936
|
-
const src = this.source;
|
|
937
|
-
const numEnd = this.consumeNumber(start);
|
|
938
|
-
const c1 = src.charCodeAt(numEnd);
|
|
939
|
-
const c2 = src.charCodeAt(numEnd + 1);
|
|
940
|
-
const c3 = src.charCodeAt(numEnd + 2);
|
|
941
|
-
if (startsIdentifier(c1, c2, c3)) {
|
|
942
|
-
const end = this.consumeName(numEnd);
|
|
943
|
-
this.addToken(12 /* Dimension */, start, end);
|
|
944
|
-
return end;
|
|
945
|
-
}
|
|
946
|
-
if (c1 === 37) {
|
|
947
|
-
this.addToken(11 /* Percentage */, start, numEnd + 1);
|
|
948
|
-
return numEnd + 1;
|
|
949
|
-
}
|
|
950
|
-
this.addToken(10 /* Number */, start, numEnd);
|
|
951
|
-
return numEnd;
|
|
952
|
-
}
|
|
953
|
-
consumeIdentLike(start) {
|
|
954
|
-
const src = this.source;
|
|
955
|
-
const nameEnd = this.consumeName(start);
|
|
956
|
-
const c = src.charCodeAt(nameEnd);
|
|
957
|
-
if (c === 40 && nameEnd - start === 3) {
|
|
958
|
-
const c0 = src.charCodeAt(start) | 32;
|
|
959
|
-
const c1 = src.charCodeAt(start + 1) | 32;
|
|
960
|
-
const c2 = src.charCodeAt(start + 2) | 32;
|
|
961
|
-
if (c0 === 117 && c1 === 114 && c2 === 108) {
|
|
962
|
-
let i = nameEnd + 1;
|
|
963
|
-
while (i < src.length && isWhitespace(src.charCodeAt(i)))
|
|
964
|
-
i++;
|
|
965
|
-
const next = src.charCodeAt(i);
|
|
966
|
-
if (next === 34 || next === 39) {
|
|
967
|
-
this.addToken(2 /* Function */, start, nameEnd + 1);
|
|
968
|
-
return nameEnd + 1;
|
|
969
|
-
}
|
|
970
|
-
return this.consumeUrl(start, nameEnd);
|
|
971
|
-
}
|
|
972
|
-
}
|
|
973
|
-
if (c === 40) {
|
|
974
|
-
this.addToken(2 /* Function */, start, nameEnd + 1);
|
|
975
|
-
return nameEnd + 1;
|
|
976
|
-
}
|
|
977
|
-
this.addToken(1 /* Ident */, start, nameEnd);
|
|
978
|
-
return nameEnd;
|
|
979
|
-
}
|
|
980
|
-
consumeUrl(start, nameEnd) {
|
|
981
|
-
const src = this.source;
|
|
982
|
-
const len = src.length;
|
|
983
|
-
let i = nameEnd + 1;
|
|
984
|
-
while (i < len && isWhitespace(src.charCodeAt(i)))
|
|
985
|
-
i++;
|
|
986
|
-
while (i < len) {
|
|
987
|
-
const c = src.charCodeAt(i);
|
|
988
|
-
if (c === 41) {
|
|
989
|
-
i++;
|
|
990
|
-
this.addToken(7 /* Url */, start, i);
|
|
991
|
-
return i;
|
|
992
|
-
}
|
|
993
|
-
if (isWhitespace(c)) {
|
|
994
|
-
const wsStart = i;
|
|
995
|
-
while (i < len && isWhitespace(src.charCodeAt(i)))
|
|
996
|
-
i++;
|
|
997
|
-
if (i >= len) {
|
|
998
|
-
this.addToken(7 /* Url */, start, i);
|
|
999
|
-
return i;
|
|
1000
|
-
}
|
|
1001
|
-
if (src.charCodeAt(i) === 41) {
|
|
1002
|
-
i++;
|
|
1003
|
-
this.addToken(7 /* Url */, start, i);
|
|
1004
|
-
return i;
|
|
1005
|
-
}
|
|
1006
|
-
return this.consumeBadUrl(start, wsStart);
|
|
1007
|
-
}
|
|
1008
|
-
if (c === 34 || c === 39 || c === 40 || isNonPrintable(c)) {
|
|
1009
|
-
return this.consumeBadUrl(start, i);
|
|
1010
|
-
}
|
|
1011
|
-
if (c === 92) {
|
|
1012
|
-
if (isValidEscape(c, src.charCodeAt(i + 1))) {
|
|
1013
|
-
i = this.consumeEscapeSkip(i + 1);
|
|
1014
|
-
continue;
|
|
1015
|
-
}
|
|
1016
|
-
return this.consumeBadUrl(start, i);
|
|
1017
|
-
}
|
|
1018
|
-
i++;
|
|
1019
|
-
}
|
|
1020
|
-
this.addToken(7 /* Url */, start, i);
|
|
1021
|
-
return i;
|
|
1022
|
-
}
|
|
1023
|
-
consumeBadUrl(start, from) {
|
|
1024
|
-
const src = this.source;
|
|
1025
|
-
let i = from;
|
|
1026
|
-
while (i < src.length) {
|
|
1027
|
-
const c = src.charCodeAt(i);
|
|
1028
|
-
if (c === 41) {
|
|
1029
|
-
i++;
|
|
1030
|
-
break;
|
|
1031
|
-
}
|
|
1032
|
-
if (c === 92 && isValidEscape(c, src.charCodeAt(i + 1))) {
|
|
1033
|
-
i = this.consumeEscapeSkip(i + 1);
|
|
1034
|
-
continue;
|
|
1035
|
-
}
|
|
1036
|
-
i++;
|
|
1037
|
-
}
|
|
1038
|
-
this.addToken(8 /* BadUrl */, start, i);
|
|
1039
|
-
return i;
|
|
1040
|
-
}
|
|
1041
|
-
locate(offset) {
|
|
1042
|
-
const ls = this.lineStarts;
|
|
1043
|
-
let lo = 0;
|
|
1044
|
-
let hi = ls.length - 1;
|
|
1045
|
-
while (lo < hi) {
|
|
1046
|
-
const mid = lo + hi + 1 >> 1;
|
|
1047
|
-
if (ls[mid] <= offset)
|
|
1048
|
-
lo = mid;
|
|
1049
|
-
else
|
|
1050
|
-
hi = mid - 1;
|
|
1051
|
-
}
|
|
1052
|
-
const lineStart = ls[lo];
|
|
1053
|
-
return { line: lo + 1, column: offset - lineStart + 1 };
|
|
1054
|
-
}
|
|
1055
|
-
}
|
|
1056
|
-
function buildLineStarts(source) {
|
|
1057
|
-
const out = [0];
|
|
1058
|
-
const len = source.length;
|
|
1059
|
-
for (let i = 0;i < len; i++) {
|
|
1060
|
-
const c = source.charCodeAt(i);
|
|
1061
|
-
if (c === 10) {
|
|
1062
|
-
out.push(i + 1);
|
|
1063
|
-
} else if (c === 13) {
|
|
1064
|
-
if (source.charCodeAt(i + 1) !== 10)
|
|
1065
|
-
out.push(i + 1);
|
|
1066
|
-
}
|
|
1067
|
-
}
|
|
1068
|
-
return out;
|
|
1069
|
-
}
|
|
1070
|
-
function decodeString(source, start, end) {
|
|
1071
|
-
for (let k = start;k < end; k++) {
|
|
1072
|
-
if (source.charCodeAt(k) === 92)
|
|
1073
|
-
return decodeStringSlow(source, start, end, k);
|
|
1074
|
-
}
|
|
1075
|
-
return source.slice(start, end);
|
|
1076
|
-
}
|
|
1077
|
-
function decodeStringSlow(source, start, end, firstEscape) {
|
|
1078
|
-
let out = source.slice(start, firstEscape);
|
|
1079
|
-
let i = firstEscape;
|
|
1080
|
-
while (i < end) {
|
|
1081
|
-
const c = source.charCodeAt(i);
|
|
1082
|
-
if (c !== 92) {
|
|
1083
|
-
out += source[i];
|
|
1084
|
-
i++;
|
|
1085
|
-
continue;
|
|
1086
|
-
}
|
|
1087
|
-
if (i + 1 >= end) {
|
|
1088
|
-
i++;
|
|
1089
|
-
continue;
|
|
1090
|
-
}
|
|
1091
|
-
const next = source.charCodeAt(i + 1);
|
|
1092
|
-
if (next === 10) {
|
|
1093
|
-
i += 2;
|
|
1094
|
-
continue;
|
|
1095
|
-
}
|
|
1096
|
-
if (next === 13) {
|
|
1097
|
-
i += source.charCodeAt(i + 2) === 10 ? 3 : 2;
|
|
1098
|
-
continue;
|
|
1099
|
-
}
|
|
1100
|
-
if (isHexDigit(next)) {
|
|
1101
|
-
let j = i + 1;
|
|
1102
|
-
let hex = "";
|
|
1103
|
-
while (hex.length < 6 && j < end && isHexDigit(source.charCodeAt(j))) {
|
|
1104
|
-
hex += source[j];
|
|
1105
|
-
j++;
|
|
1106
|
-
}
|
|
1107
|
-
const code = Number.parseInt(hex, 16);
|
|
1108
|
-
if (j < end && isWhitespace(source.charCodeAt(j)))
|
|
1109
|
-
j++;
|
|
1110
|
-
out += code === 0 || code >= 55296 && code <= 57343 || code > 1114111 ? String.fromCodePoint(REPLACEMENT) : String.fromCodePoint(code);
|
|
1111
|
-
i = j;
|
|
1112
|
-
continue;
|
|
1113
|
-
}
|
|
1114
|
-
out += source[i + 1];
|
|
1115
|
-
i += 2;
|
|
1116
|
-
}
|
|
1117
|
-
return out;
|
|
1118
|
-
}
|
|
1119
|
-
function decodeName(source, start, end) {
|
|
1120
|
-
for (let k = start;k < end; k++) {
|
|
1121
|
-
if (source.charCodeAt(k) === 92)
|
|
1122
|
-
return decodeNameSlow(source, start, end, k);
|
|
1123
|
-
}
|
|
1124
|
-
return source.slice(start, end);
|
|
1125
|
-
}
|
|
1126
|
-
function decodeNameSlow(source, start, end, firstEscape) {
|
|
1127
|
-
let out = source.slice(start, firstEscape);
|
|
1128
|
-
let i = firstEscape;
|
|
1129
|
-
while (i < end) {
|
|
1130
|
-
const c = source.charCodeAt(i);
|
|
1131
|
-
if (c !== 92) {
|
|
1132
|
-
out += source[i];
|
|
1133
|
-
i++;
|
|
1134
|
-
continue;
|
|
1135
|
-
}
|
|
1136
|
-
let j = i + 1;
|
|
1137
|
-
let hex = "";
|
|
1138
|
-
while (hex.length < 6 && j < end && isHexDigit(source.charCodeAt(j))) {
|
|
1139
|
-
hex += source[j];
|
|
1140
|
-
j++;
|
|
1141
|
-
}
|
|
1142
|
-
if (hex.length > 0) {
|
|
1143
|
-
const code = Number.parseInt(hex, 16);
|
|
1144
|
-
if (j < end && isWhitespace(source.charCodeAt(j)))
|
|
1145
|
-
j++;
|
|
1146
|
-
out += code === 0 || code >= 55296 && code <= 57343 || code > 1114111 ? String.fromCodePoint(REPLACEMENT) : String.fromCodePoint(code);
|
|
1147
|
-
i = j;
|
|
1148
|
-
continue;
|
|
1149
|
-
}
|
|
1150
|
-
if (j < end) {
|
|
1151
|
-
out += source[j];
|
|
1152
|
-
i = j + 1;
|
|
1153
|
-
continue;
|
|
1154
|
-
}
|
|
1155
|
-
out += String.fromCodePoint(REPLACEMENT);
|
|
1156
|
-
i = j;
|
|
1157
|
-
}
|
|
1158
|
-
return out;
|
|
1159
|
-
}
|
|
1160
|
-
|
|
1161
|
-
// src/parse/parser/index.ts
|
|
1162
|
-
function makeState(source, options) {
|
|
1163
|
-
const tokenizer = new Tokenizer(source);
|
|
1164
|
-
return {
|
|
1165
|
-
source,
|
|
1166
|
-
types: tokenizer.types,
|
|
1167
|
-
starts: tokenizer.starts,
|
|
1168
|
-
ends: tokenizer.ends,
|
|
1169
|
-
count: tokenizer.count,
|
|
1170
|
-
end: tokenizer.count,
|
|
1171
|
-
pos: 0,
|
|
1172
|
-
positions: options.positions ?? false,
|
|
1173
|
-
filename: options.filename,
|
|
1174
|
-
parseValue: options.parseValue ?? true,
|
|
1175
|
-
parseAtrulePrelude: options.parseAtrulePrelude ?? true,
|
|
1176
|
-
parseCustomProperty: options.parseCustomProperty ?? false,
|
|
1177
|
-
parseRulePrelude: options.parseRulePrelude ?? true,
|
|
1178
|
-
onParseError: options.onParseError,
|
|
1179
|
-
tokenizer
|
|
1180
|
-
};
|
|
1181
|
-
}
|
|
1182
|
-
function peekType(s) {
|
|
1183
|
-
return s.pos < s.end ? s.types[s.pos] : 0 /* EOF */;
|
|
1184
|
-
}
|
|
1185
|
-
function peek(s) {
|
|
1186
|
-
const i = s.pos;
|
|
1187
|
-
if (i >= s.end)
|
|
1188
|
-
return { type: 0 /* EOF */, start: s.starts[i] ?? s.source.length, end: s.ends[i] ?? s.source.length };
|
|
1189
|
-
return { type: s.types[i], start: s.starts[i], end: s.ends[i] };
|
|
1190
|
-
}
|
|
1191
|
-
function consume(s) {
|
|
1192
|
-
const i = s.pos++;
|
|
1193
|
-
if (i >= s.end)
|
|
1194
|
-
return { type: 0 /* EOF */, start: s.starts[i] ?? s.source.length, end: s.ends[i] ?? s.source.length };
|
|
1195
|
-
return { type: s.types[i], start: s.starts[i], end: s.ends[i] };
|
|
1196
|
-
}
|
|
1197
|
-
function tokenSlice(s, t) {
|
|
1198
|
-
return s.source.slice(t.start, t.end);
|
|
1199
|
-
}
|
|
1200
|
-
function skipWhitespace(s) {
|
|
1201
|
-
const types = s.types;
|
|
1202
|
-
const end = s.end;
|
|
1203
|
-
while (s.pos < end) {
|
|
1204
|
-
const t = types[s.pos];
|
|
1205
|
-
if (t === 13 /* WhiteSpace */ || t === 25 /* Comment */)
|
|
1206
|
-
s.pos++;
|
|
1207
|
-
else
|
|
1208
|
-
break;
|
|
1209
|
-
}
|
|
1210
|
-
}
|
|
1211
|
-
function skipWhitespaceOnly(s) {
|
|
1212
|
-
const types = s.types;
|
|
1213
|
-
const end = s.end;
|
|
1214
|
-
while (s.pos < end && types[s.pos] === 13 /* WhiteSpace */)
|
|
1215
|
-
s.pos++;
|
|
1216
|
-
}
|
|
1217
|
-
function loc(s, startTok, endTok) {
|
|
1218
|
-
if (!s.positions)
|
|
1219
|
-
return null;
|
|
1220
|
-
const start = s.tokenizer.locate(startTok.start);
|
|
1221
|
-
const end = s.tokenizer.locate(endTok.end);
|
|
1222
|
-
return {
|
|
1223
|
-
source: s.filename ?? "<unknown>",
|
|
1224
|
-
start: { offset: startTok.start, line: start.line, column: start.column },
|
|
1225
|
-
end: { offset: endTok.end, line: end.line, column: end.column }
|
|
1226
|
-
};
|
|
1227
|
-
}
|
|
1228
|
-
function emptyLoc(s) {
|
|
1229
|
-
if (!s.positions)
|
|
1230
|
-
return null;
|
|
1231
|
-
const t = peek(s);
|
|
1232
|
-
const p = s.tokenizer.locate(t.start);
|
|
1233
|
-
return {
|
|
1234
|
-
source: s.filename ?? "<unknown>",
|
|
1235
|
-
start: { offset: t.start, line: p.line, column: p.column },
|
|
1236
|
-
end: { offset: t.start, line: p.line, column: p.column }
|
|
1237
|
-
};
|
|
1238
|
-
}
|
|
1239
|
-
function rawNode(value, start, end, s) {
|
|
1240
|
-
return { type: "Raw", value, loc: loc(s, start, end) };
|
|
1241
|
-
}
|
|
1242
|
-
function newList() {
|
|
1243
|
-
return new CssList;
|
|
1244
|
-
}
|
|
1245
|
-
function reportError(s, message, at, fallback) {
|
|
1246
|
-
if (s.onParseError) {
|
|
1247
|
-
const { line, column } = s.tokenizer.locate(at.start);
|
|
1248
|
-
const err = new SyntaxError(`${s.filename ?? "<input>"}:${line}:${column}: ${message}`);
|
|
1249
|
-
err.line = line;
|
|
1250
|
-
err.column = column;
|
|
1251
|
-
err.offset = at.start;
|
|
1252
|
-
s.onParseError(err, fallback);
|
|
1253
|
-
}
|
|
1254
|
-
return fallback;
|
|
1255
|
-
}
|
|
1256
|
-
function parse(source, options = {}) {
|
|
1257
|
-
const s = makeState(source, options);
|
|
1258
|
-
const ctx = options.context ?? "stylesheet";
|
|
1259
|
-
switch (ctx) {
|
|
1260
|
-
case "stylesheet":
|
|
1261
|
-
return parseStyleSheet(s);
|
|
1262
|
-
case "atrule":
|
|
1263
|
-
return parseAtrule(s) ?? makeEmptyStyleSheet(s);
|
|
1264
|
-
case "atrulePrelude":
|
|
1265
|
-
return parseAtrulePreludeContext(s);
|
|
1266
|
-
case "mediaQuery":
|
|
1267
|
-
case "mediaQueryList":
|
|
1268
|
-
return parseRawAsValue(s);
|
|
1269
|
-
case "rule":
|
|
1270
|
-
return parseRule(s);
|
|
1271
|
-
case "selectorList":
|
|
1272
|
-
return parseSelectorList(s);
|
|
1273
|
-
case "selector":
|
|
1274
|
-
return parseSelector(s);
|
|
1275
|
-
case "block":
|
|
1276
|
-
return parseBlock(s);
|
|
1277
|
-
case "declarationList":
|
|
1278
|
-
return parseDeclarationList(s);
|
|
1279
|
-
case "declaration":
|
|
1280
|
-
return parseDeclaration(s) ?? makeEmptyStyleSheet(s);
|
|
1281
|
-
case "value":
|
|
1282
|
-
return parseValue(s);
|
|
1283
|
-
case "raw":
|
|
1284
|
-
return parseRawAsValue(s);
|
|
1285
|
-
default:
|
|
1286
|
-
return parseStyleSheet(s);
|
|
1287
|
-
}
|
|
1288
|
-
}
|
|
1289
|
-
function makeEmptyStyleSheet(s) {
|
|
1290
|
-
return { type: "StyleSheet", children: newList(), loc: emptyLoc(s) };
|
|
1291
|
-
}
|
|
1292
|
-
function parseRawAsValue(s) {
|
|
1293
|
-
const start = peek(s);
|
|
1294
|
-
let end = start;
|
|
1295
|
-
while (peekType(s) !== 0 /* EOF */) {
|
|
1296
|
-
end = consume(s);
|
|
1297
|
-
}
|
|
1298
|
-
return { type: "Raw", value: s.source.slice(start.start, end.end), loc: loc(s, start, end) };
|
|
1299
|
-
}
|
|
1300
|
-
function parseStyleSheet(s) {
|
|
1301
|
-
const startTok = peek(s);
|
|
1302
|
-
const children = newList();
|
|
1303
|
-
const types = s.types;
|
|
1304
|
-
const end = s.end;
|
|
1305
|
-
while (s.pos < end) {
|
|
1306
|
-
const t = types[s.pos];
|
|
1307
|
-
if (t === 13 /* WhiteSpace */) {
|
|
1308
|
-
s.pos++;
|
|
1309
|
-
continue;
|
|
1310
|
-
}
|
|
1311
|
-
if (t === 25 /* Comment */) {
|
|
1312
|
-
const tok = { type: 25 /* Comment */, start: s.starts[s.pos], end: s.ends[s.pos] };
|
|
1313
|
-
const node = makeComment(s, tok);
|
|
1314
|
-
s.pos++;
|
|
1315
|
-
children.appendData(node);
|
|
1316
|
-
continue;
|
|
1317
|
-
}
|
|
1318
|
-
if (t === 0 /* EOF */)
|
|
1319
|
-
break;
|
|
1320
|
-
if (t === 14 /* CDO */ || t === 15 /* CDC */) {
|
|
1321
|
-
s.pos++;
|
|
1322
|
-
continue;
|
|
1323
|
-
}
|
|
1324
|
-
if (t === 3 /* AtKeyword */) {
|
|
1325
|
-
const at = parseAtrule(s);
|
|
1326
|
-
if (at)
|
|
1327
|
-
children.appendData(at);
|
|
1328
|
-
continue;
|
|
1329
|
-
}
|
|
1330
|
-
if (t === 24 /* RightCurlyBracket */) {
|
|
1331
|
-
s.pos++;
|
|
1332
|
-
continue;
|
|
1333
|
-
}
|
|
1334
|
-
const before = s.pos;
|
|
1335
|
-
const r = parseRule(s);
|
|
1336
|
-
children.appendData(r);
|
|
1337
|
-
if (s.pos === before)
|
|
1338
|
-
s.pos++;
|
|
1339
|
-
}
|
|
1340
|
-
const lastIdx = s.end - 1;
|
|
1341
|
-
const endTok = lastIdx >= 0 ? { type: s.types[lastIdx], start: s.starts[lastIdx], end: s.ends[lastIdx] } : { type: 0 /* EOF */, start: 0, end: 0 };
|
|
1342
|
-
return { type: "StyleSheet", children, loc: loc(s, startTok, endTok) };
|
|
1343
|
-
}
|
|
1344
|
-
function makeComment(s, t) {
|
|
1345
|
-
return { type: "Comment", value: s.source.slice(t.start + 2, t.end - 2), loc: loc(s, t, t) };
|
|
1346
|
-
}
|
|
1347
|
-
function parseAtrule(s) {
|
|
1348
|
-
const startTok = peek(s);
|
|
1349
|
-
if (startTok.type !== 3 /* AtKeyword */)
|
|
1350
|
-
return null;
|
|
1351
|
-
s.pos++;
|
|
1352
|
-
const name = lowerIfNeeded(s.source, startTok.start + 1, startTok.end);
|
|
1353
|
-
skipWhitespace(s);
|
|
1354
|
-
const preludeStartPos = s.pos;
|
|
1355
|
-
const preludeStartTok = peek(s);
|
|
1356
|
-
const types = s.types;
|
|
1357
|
-
const tend = s.end;
|
|
1358
|
-
let scanPos = preludeStartPos;
|
|
1359
|
-
let preludeEndPos = preludeStartPos;
|
|
1360
|
-
while (scanPos < tend) {
|
|
1361
|
-
const t = types[scanPos];
|
|
1362
|
-
if (t === 0 /* EOF */ || t === 17 /* Semicolon */ || t === 23 /* LeftCurlyBracket */)
|
|
1363
|
-
break;
|
|
1364
|
-
if (t !== 13 /* WhiteSpace */ && t !== 25 /* Comment */)
|
|
1365
|
-
preludeEndPos = scanPos + 1;
|
|
1366
|
-
scanPos++;
|
|
1367
|
-
}
|
|
1368
|
-
let prelude = null;
|
|
1369
|
-
if (preludeEndPos > preludeStartPos) {
|
|
1370
|
-
const preludeStartByte = s.starts[preludeStartPos];
|
|
1371
|
-
const preludeEndByte = s.ends[preludeEndPos - 1];
|
|
1372
|
-
const preludeEndTok = { type: types[preludeEndPos - 1], start: s.starts[preludeEndPos - 1], end: preludeEndByte };
|
|
1373
|
-
const raw = s.source.slice(preludeStartByte, preludeEndByte).trim();
|
|
1374
|
-
if (raw.length > 0) {
|
|
1375
|
-
if (s.parseAtrulePrelude) {
|
|
1376
|
-
try {
|
|
1377
|
-
const savedEnd = s.end;
|
|
1378
|
-
s.end = preludeEndPos;
|
|
1379
|
-
s.pos = preludeStartPos;
|
|
1380
|
-
const children = newList();
|
|
1381
|
-
while (peekType(s) !== 0 /* EOF */) {
|
|
1382
|
-
const node = parseValueChild(s);
|
|
1383
|
-
if (node)
|
|
1384
|
-
children.appendData(node);
|
|
1385
|
-
}
|
|
1386
|
-
promoteRatiosDeep(children);
|
|
1387
|
-
s.end = savedEnd;
|
|
1388
|
-
s.pos = scanPos;
|
|
1389
|
-
if (children.isEmpty)
|
|
1390
|
-
prelude = rawNode(raw, preludeStartTok, preludeEndTok, s);
|
|
1391
|
-
else
|
|
1392
|
-
prelude = { type: "AtrulePrelude", children, loc: null };
|
|
1393
|
-
} catch (err) {
|
|
1394
|
-
const fallback = rawNode(raw, preludeStartTok, preludeEndTok, s);
|
|
1395
|
-
reportError(s, `Failed to parse @${name} prelude: ${err.message}`, preludeStartTok, fallback);
|
|
1396
|
-
prelude = fallback;
|
|
1397
|
-
s.pos = scanPos;
|
|
1398
|
-
}
|
|
1399
|
-
} else {
|
|
1400
|
-
prelude = rawNode(raw, preludeStartTok, preludeEndTok, s);
|
|
1401
|
-
s.pos = scanPos;
|
|
1402
|
-
}
|
|
1403
|
-
} else {
|
|
1404
|
-
s.pos = scanPos;
|
|
1405
|
-
}
|
|
1406
|
-
} else {
|
|
1407
|
-
s.pos = scanPos;
|
|
1408
|
-
}
|
|
1409
|
-
let block = null;
|
|
1410
|
-
if (peekType(s) === 17 /* Semicolon */) {
|
|
1411
|
-
consume(s);
|
|
1412
|
-
} else if (peekType(s) === 23 /* LeftCurlyBracket */) {
|
|
1413
|
-
block = parseBlock(s, AT_RULES_WITH_NESTED_RULES.has(name));
|
|
1414
|
-
}
|
|
1415
|
-
return { type: "Atrule", name, prelude, block, loc: loc(s, startTok, peek(s)) };
|
|
1416
|
-
}
|
|
1417
|
-
var SELECTOR_LIST_PSEUDOS_PARSE = new Set([
|
|
1418
|
-
"is",
|
|
1419
|
-
"not",
|
|
1420
|
-
"where",
|
|
1421
|
-
"has",
|
|
1422
|
-
"matches",
|
|
1423
|
-
"-moz-any",
|
|
1424
|
-
"-webkit-any"
|
|
1425
|
-
]);
|
|
1426
|
-
var AT_RULES_WITH_NESTED_RULES = new Set([
|
|
1427
|
-
"media",
|
|
1428
|
-
"supports",
|
|
1429
|
-
"document",
|
|
1430
|
-
"layer",
|
|
1431
|
-
"container",
|
|
1432
|
-
"scope",
|
|
1433
|
-
"starting-style",
|
|
1434
|
-
"-moz-document",
|
|
1435
|
-
"keyframes",
|
|
1436
|
-
"-webkit-keyframes",
|
|
1437
|
-
"-moz-keyframes",
|
|
1438
|
-
"-o-keyframes"
|
|
1439
|
-
]);
|
|
1440
|
-
function parseAtrulePreludeContext(s) {
|
|
1441
|
-
const startTok = peek(s);
|
|
1442
|
-
const children = newList();
|
|
1443
|
-
while (peekType(s) !== 0 /* EOF */) {
|
|
1444
|
-
const t = peek(s);
|
|
1445
|
-
if (t.type === 13 /* WhiteSpace */) {
|
|
1446
|
-
s.pos++;
|
|
1447
|
-
continue;
|
|
1448
|
-
}
|
|
1449
|
-
const node = parseValueChild(s);
|
|
1450
|
-
if (node)
|
|
1451
|
-
children.appendData(node);
|
|
1452
|
-
}
|
|
1453
|
-
return { type: "AtrulePrelude", children, loc: loc(s, startTok, peek(s)) };
|
|
1454
|
-
}
|
|
1455
|
-
function parseRule(s) {
|
|
1456
|
-
const startTok = peek(s);
|
|
1457
|
-
let prelude;
|
|
1458
|
-
if (s.parseRulePrelude) {
|
|
1459
|
-
prelude = parseSelectorList(s);
|
|
1460
|
-
} else {
|
|
1461
|
-
const preludeStart = peek(s);
|
|
1462
|
-
let preludeEnd = preludeStart;
|
|
1463
|
-
while (peekType(s) !== 0 /* EOF */ && peekType(s) !== 23 /* LeftCurlyBracket */)
|
|
1464
|
-
preludeEnd = consume(s);
|
|
1465
|
-
const preludeText = s.source.slice(preludeStart.start, preludeEnd.end).trim();
|
|
1466
|
-
prelude = rawNode(preludeText, preludeStart, preludeEnd, s);
|
|
1467
|
-
}
|
|
1468
|
-
const block = parseBlock(s, true);
|
|
1469
|
-
return { type: "Rule", prelude, block, loc: loc(s, startTok, peek(s)) };
|
|
1470
|
-
}
|
|
1471
|
-
function parseBlock(s, allowNested = false) {
|
|
1472
|
-
const startTok = peek(s);
|
|
1473
|
-
if (peekType(s) !== 23 /* LeftCurlyBracket */)
|
|
1474
|
-
return { type: "Block", children: newList(), loc: emptyLoc(s) };
|
|
1475
|
-
s.pos++;
|
|
1476
|
-
const children = newList();
|
|
1477
|
-
const types = s.types;
|
|
1478
|
-
const end = s.end;
|
|
1479
|
-
while (s.pos < end) {
|
|
1480
|
-
const t = types[s.pos];
|
|
1481
|
-
if (t === 24 /* RightCurlyBracket */ || t === 0 /* EOF */)
|
|
1482
|
-
break;
|
|
1483
|
-
if (t === 13 /* WhiteSpace */) {
|
|
1484
|
-
s.pos++;
|
|
1485
|
-
continue;
|
|
1486
|
-
}
|
|
1487
|
-
if (t === 25 /* Comment */) {
|
|
1488
|
-
const tok = { type: 25 /* Comment */, start: s.starts[s.pos], end: s.ends[s.pos] };
|
|
1489
|
-
s.pos++;
|
|
1490
|
-
children.appendData(makeComment(s, tok));
|
|
1491
|
-
continue;
|
|
1492
|
-
}
|
|
1493
|
-
if (t === 3 /* AtKeyword */) {
|
|
1494
|
-
const at = parseAtrule(s);
|
|
1495
|
-
if (at)
|
|
1496
|
-
children.appendData(at);
|
|
1497
|
-
continue;
|
|
1498
|
-
}
|
|
1499
|
-
if (allowNested && lookahead(s, isCurlyAheadBeforeSemicolon)) {
|
|
1500
|
-
const r = parseRule(s);
|
|
1501
|
-
children.appendData(r);
|
|
1502
|
-
continue;
|
|
1503
|
-
}
|
|
1504
|
-
const decl = parseDeclaration(s);
|
|
1505
|
-
if (decl)
|
|
1506
|
-
children.appendData(decl);
|
|
1507
|
-
if (s.pos < end && types[s.pos] === 17 /* Semicolon */)
|
|
1508
|
-
s.pos++;
|
|
1509
|
-
}
|
|
1510
|
-
if (peekType(s) === 24 /* RightCurlyBracket */)
|
|
1511
|
-
s.pos++;
|
|
1512
|
-
return { type: "Block", children, loc: loc(s, startTok, peek(s)) };
|
|
1513
|
-
}
|
|
1514
|
-
function lookahead(s, predicate) {
|
|
1515
|
-
const saved = s.pos;
|
|
1516
|
-
const r = predicate(s);
|
|
1517
|
-
s.pos = saved;
|
|
1518
|
-
return r;
|
|
1519
|
-
}
|
|
1520
|
-
function isCurlyAheadBeforeSemicolon(s) {
|
|
1521
|
-
const types = s.types;
|
|
1522
|
-
const end = s.end;
|
|
1523
|
-
while (s.pos < end) {
|
|
1524
|
-
const t = types[s.pos];
|
|
1525
|
-
if (t === 23 /* LeftCurlyBracket */)
|
|
1526
|
-
return true;
|
|
1527
|
-
if (t === 17 /* Semicolon */ || t === 24 /* RightCurlyBracket */ || t === 0 /* EOF */)
|
|
1528
|
-
return false;
|
|
1529
|
-
s.pos++;
|
|
1530
|
-
}
|
|
1531
|
-
return false;
|
|
1532
|
-
}
|
|
1533
|
-
function parseDeclarationList(s) {
|
|
1534
|
-
const startTok = peek(s);
|
|
1535
|
-
const children = newList();
|
|
1536
|
-
while (peekType(s) !== 0 /* EOF */ && peekType(s) !== 24 /* RightCurlyBracket */) {
|
|
1537
|
-
const t = peek(s);
|
|
1538
|
-
if (t.type === 13 /* WhiteSpace */) {
|
|
1539
|
-
s.pos++;
|
|
1540
|
-
continue;
|
|
1541
|
-
}
|
|
1542
|
-
if (t.type === 25 /* Comment */) {
|
|
1543
|
-
children.appendData(makeComment(s, consume(s)));
|
|
1544
|
-
continue;
|
|
1545
|
-
}
|
|
1546
|
-
if (t.type === 17 /* Semicolon */) {
|
|
1547
|
-
s.pos++;
|
|
1548
|
-
continue;
|
|
1549
|
-
}
|
|
1550
|
-
if (t.type === 3 /* AtKeyword */) {
|
|
1551
|
-
const at = parseAtrule(s);
|
|
1552
|
-
if (at)
|
|
1553
|
-
children.appendData(at);
|
|
1554
|
-
continue;
|
|
1555
|
-
}
|
|
1556
|
-
const decl = parseDeclaration(s);
|
|
1557
|
-
if (decl)
|
|
1558
|
-
children.appendData(decl);
|
|
1559
|
-
if (peekType(s) === 17 /* Semicolon */)
|
|
1560
|
-
consume(s);
|
|
1561
|
-
}
|
|
1562
|
-
return { type: "DeclarationList", children, loc: loc(s, startTok, peek(s)) };
|
|
1563
|
-
}
|
|
1564
|
-
function parseDeclaration(s) {
|
|
1565
|
-
skipWhitespace(s);
|
|
1566
|
-
const startTok = peek(s);
|
|
1567
|
-
if (startTok.type !== 1 /* Ident */ && startTok.type !== 4 /* Hash */ && !(startTok.type === 9 /* Delim */ && s.source[startTok.start] === "*" && s.source[startTok.start + 1] === " ")) {
|
|
1568
|
-
if (startTok.type === 9 /* Delim */ && s.source[startTok.start] === "*") {
|
|
1569
|
-
s.pos++;
|
|
1570
|
-
} else {
|
|
1571
|
-
reportError(s, `Expected property name`, startTok, { type: "Raw", value: "", loc: null });
|
|
1572
|
-
const types2 = s.types;
|
|
1573
|
-
const end = s.end;
|
|
1574
|
-
while (s.pos < end) {
|
|
1575
|
-
const t = types2[s.pos];
|
|
1576
|
-
if (t === 0 /* EOF */ || t === 17 /* Semicolon */ || t === 24 /* RightCurlyBracket */)
|
|
1577
|
-
break;
|
|
1578
|
-
s.pos++;
|
|
1579
|
-
}
|
|
1580
|
-
return null;
|
|
1581
|
-
}
|
|
1582
|
-
}
|
|
1583
|
-
const propStart = s.starts[s.pos];
|
|
1584
|
-
const propEnd = s.ends[s.pos];
|
|
1585
|
-
s.pos++;
|
|
1586
|
-
const property = s.source.slice(propStart, propEnd);
|
|
1587
|
-
skipWhitespaceOnly(s);
|
|
1588
|
-
if (peekType(s) !== 16 /* Colon */) {
|
|
1589
|
-
reportError(s, `Expected ':' after property "${property}"`, peek(s), { type: "Raw", value: "", loc: null });
|
|
1590
|
-
const types2 = s.types;
|
|
1591
|
-
const end = s.end;
|
|
1592
|
-
while (s.pos < end) {
|
|
1593
|
-
const t = types2[s.pos];
|
|
1594
|
-
if (t === 0 /* EOF */ || t === 17 /* Semicolon */ || t === 24 /* RightCurlyBracket */)
|
|
1595
|
-
break;
|
|
1596
|
-
s.pos++;
|
|
1597
|
-
}
|
|
1598
|
-
return null;
|
|
1599
|
-
}
|
|
1600
|
-
s.pos++;
|
|
1601
|
-
skipWhitespaceOnly(s);
|
|
1602
|
-
const types = s.types;
|
|
1603
|
-
const starts = s.starts;
|
|
1604
|
-
const tend = s.end;
|
|
1605
|
-
const valueStartPos = s.pos;
|
|
1606
|
-
let scanPos = valueStartPos;
|
|
1607
|
-
let lastNonWsPos = valueStartPos;
|
|
1608
|
-
let importantIdentPos = -1;
|
|
1609
|
-
let bangPos = -1;
|
|
1610
|
-
while (scanPos < tend) {
|
|
1611
|
-
const t = types[scanPos];
|
|
1612
|
-
if (t === 0 /* EOF */ || t === 17 /* Semicolon */ || t === 24 /* RightCurlyBracket */)
|
|
1613
|
-
break;
|
|
1614
|
-
if (t === 9 /* Delim */ && s.source.charCodeAt(starts[scanPos]) === 33) {
|
|
1615
|
-
let look = scanPos + 1;
|
|
1616
|
-
while (look < tend && types[look] === 13 /* WhiteSpace */)
|
|
1617
|
-
look++;
|
|
1618
|
-
if (look < tend && types[look] === 1 /* Ident */) {
|
|
1619
|
-
const ts = starts[look];
|
|
1620
|
-
const te = s.ends[look];
|
|
1621
|
-
if (te - ts === 9 && (s.source.charCodeAt(ts) | 32) === 105 && (s.source.charCodeAt(ts + 1) | 32) === 109 && (s.source.charCodeAt(ts + 2) | 32) === 112 && (s.source.charCodeAt(ts + 3) | 32) === 111 && (s.source.charCodeAt(ts + 4) | 32) === 114 && (s.source.charCodeAt(ts + 5) | 32) === 116 && (s.source.charCodeAt(ts + 6) | 32) === 97 && (s.source.charCodeAt(ts + 7) | 32) === 110 && (s.source.charCodeAt(ts + 8) | 32) === 116) {
|
|
1622
|
-
bangPos = scanPos;
|
|
1623
|
-
importantIdentPos = look;
|
|
1624
|
-
scanPos = look + 1;
|
|
1625
|
-
continue;
|
|
1626
|
-
}
|
|
1627
|
-
}
|
|
1628
|
-
}
|
|
1629
|
-
if (t !== 13 /* WhiteSpace */ && t !== 25 /* Comment */)
|
|
1630
|
-
lastNonWsPos = scanPos + 1;
|
|
1631
|
-
scanPos++;
|
|
1632
|
-
}
|
|
1633
|
-
const valueEndPos = lastNonWsPos;
|
|
1634
|
-
const importantTok = importantIdentPos >= 0 ? { type: 1 /* Ident */, start: starts[importantIdentPos], end: s.ends[importantIdentPos] } : null;
|
|
1635
|
-
const isCustom = property.startsWith("--");
|
|
1636
|
-
let value;
|
|
1637
|
-
const valueStartByte = starts[valueStartPos];
|
|
1638
|
-
const valueEndByte = valueEndPos > valueStartPos ? s.ends[valueEndPos - 1] : valueStartByte;
|
|
1639
|
-
const valueStartTok = { type: types[valueStartPos], start: valueStartByte, end: s.ends[valueStartPos] };
|
|
1640
|
-
const valueEndTok = valueEndPos > valueStartPos ? { type: types[valueEndPos - 1], start: starts[valueEndPos - 1], end: valueEndByte } : valueStartTok;
|
|
1641
|
-
if (isCustom && !s.parseCustomProperty || !s.parseValue) {
|
|
1642
|
-
const valueText = s.source.slice(valueStartByte, valueEndByte).trim();
|
|
1643
|
-
value = { type: "Raw", value: valueText, loc: loc(s, valueStartTok, valueEndTok) };
|
|
1644
|
-
} else if (valueEndPos === valueStartPos) {
|
|
1645
|
-
value = { type: "Value", children: newList(), loc: loc(s, valueStartTok, valueEndTok) };
|
|
1646
|
-
} else {
|
|
1647
|
-
const savedEnd = s.end;
|
|
1648
|
-
s.end = valueEndPos;
|
|
1649
|
-
s.pos = valueStartPos;
|
|
1650
|
-
value = parseValueChildren(s);
|
|
1651
|
-
s.end = savedEnd;
|
|
1652
|
-
}
|
|
1653
|
-
s.pos = scanPos;
|
|
1654
|
-
return {
|
|
1655
|
-
type: "Declaration",
|
|
1656
|
-
property,
|
|
1657
|
-
important: importantTok ? true : false,
|
|
1658
|
-
value,
|
|
1659
|
-
loc: loc(s, startTok, peek(s))
|
|
1660
|
-
};
|
|
1661
|
-
}
|
|
1662
|
-
function parseValue(s) {
|
|
1663
|
-
return parseValueChildren(s);
|
|
1664
|
-
}
|
|
1665
|
-
function parseValueChildren(s) {
|
|
1666
|
-
const startTok = peek(s);
|
|
1667
|
-
const children = newList();
|
|
1668
|
-
while (peekType(s) !== 0 /* EOF */ && peekType(s) !== 17 /* Semicolon */ && peekType(s) !== 24 /* RightCurlyBracket */ && peekType(s) !== 22 /* RightParenthesis */ && peekType(s) !== 20 /* RightSquareBracket */) {
|
|
1669
|
-
const node = parseValueChild(s);
|
|
1670
|
-
if (node)
|
|
1671
|
-
children.appendData(node);
|
|
1672
|
-
}
|
|
1673
|
-
promoteRatios(children);
|
|
1674
|
-
return { type: "Value", children, loc: loc(s, startTok, peek(s)) };
|
|
1675
|
-
}
|
|
1676
|
-
function promoteRatiosDeep(list) {
|
|
1677
|
-
for (const child of list) {
|
|
1678
|
-
if ("children" in child && child.children instanceof CssList)
|
|
1679
|
-
promoteRatiosDeep(child.children);
|
|
1680
|
-
}
|
|
1681
|
-
promoteRatios(list);
|
|
1682
|
-
}
|
|
1683
|
-
function promoteRatios(list) {
|
|
1684
|
-
let cur = list.head;
|
|
1685
|
-
while (cur) {
|
|
1686
|
-
if (cur.data.type === "Number") {
|
|
1687
|
-
let slashItem = cur.next;
|
|
1688
|
-
while (slashItem && slashItem.data.type === "WhiteSpace")
|
|
1689
|
-
slashItem = slashItem.next;
|
|
1690
|
-
if (slashItem && slashItem.data.type === "Operator" && slashItem.data.value === "/") {
|
|
1691
|
-
let rightItem = slashItem.next;
|
|
1692
|
-
while (rightItem && rightItem.data.type === "WhiteSpace")
|
|
1693
|
-
rightItem = rightItem.next;
|
|
1694
|
-
if (rightItem && rightItem.data.type === "Number") {
|
|
1695
|
-
const ratio = {
|
|
1696
|
-
type: "Ratio",
|
|
1697
|
-
left: cur.data,
|
|
1698
|
-
right: rightItem.data,
|
|
1699
|
-
loc: null
|
|
1700
|
-
};
|
|
1701
|
-
let toRemove = cur.next;
|
|
1702
|
-
while (toRemove && toRemove !== rightItem.next) {
|
|
1703
|
-
const nxt = toRemove.next;
|
|
1704
|
-
list.remove(toRemove);
|
|
1705
|
-
toRemove = nxt;
|
|
1706
|
-
}
|
|
1707
|
-
list.replace(cur, list.createItem(ratio));
|
|
1708
|
-
cur = list.head;
|
|
1709
|
-
continue;
|
|
1710
|
-
}
|
|
1711
|
-
}
|
|
1712
|
-
}
|
|
1713
|
-
cur = cur.next;
|
|
1714
|
-
}
|
|
1715
|
-
}
|
|
1716
|
-
function parseValueChild(s) {
|
|
1717
|
-
const i = s.pos;
|
|
1718
|
-
if (i >= s.end)
|
|
1719
|
-
return null;
|
|
1720
|
-
const ttype = s.types[i];
|
|
1721
|
-
const tstart = s.starts[i];
|
|
1722
|
-
const tend = s.ends[i];
|
|
1723
|
-
const src = s.source;
|
|
1724
|
-
switch (ttype) {
|
|
1725
|
-
case 13 /* WhiteSpace */: {
|
|
1726
|
-
s.pos++;
|
|
1727
|
-
return s.positions ? { type: "WhiteSpace", value: " ", loc: locRange(s, tstart, tend) } : { type: "WhiteSpace", value: " ", loc: null };
|
|
1728
|
-
}
|
|
1729
|
-
case 25 /* Comment */: {
|
|
1730
|
-
s.pos++;
|
|
1731
|
-
return { type: "Comment", value: src.slice(tstart + 2, tend - 2), loc: s.positions ? locRange(s, tstart, tend) : null };
|
|
1732
|
-
}
|
|
1733
|
-
case 10 /* Number */: {
|
|
1734
|
-
s.pos++;
|
|
1735
|
-
return { type: "Number", value: src.slice(tstart, tend), loc: s.positions ? locRange(s, tstart, tend) : null };
|
|
1736
|
-
}
|
|
1737
|
-
case 11 /* Percentage */: {
|
|
1738
|
-
s.pos++;
|
|
1739
|
-
return { type: "Percentage", value: src.slice(tstart, tend - 1), loc: s.positions ? locRange(s, tstart, tend) : null };
|
|
1740
|
-
}
|
|
1741
|
-
case 12 /* Dimension */: {
|
|
1742
|
-
s.pos++;
|
|
1743
|
-
let unitStart = tstart;
|
|
1744
|
-
const c0 = src.charCodeAt(unitStart);
|
|
1745
|
-
if (c0 === 43 || c0 === 45)
|
|
1746
|
-
unitStart++;
|
|
1747
|
-
let sawDot = false;
|
|
1748
|
-
while (unitStart < tend) {
|
|
1749
|
-
const c = src.charCodeAt(unitStart);
|
|
1750
|
-
if (c >= 48 && c <= 57) {
|
|
1751
|
-
unitStart++;
|
|
1752
|
-
continue;
|
|
1753
|
-
}
|
|
1754
|
-
if (c === 46 && !sawDot) {
|
|
1755
|
-
sawDot = true;
|
|
1756
|
-
unitStart++;
|
|
1757
|
-
continue;
|
|
1758
|
-
}
|
|
1759
|
-
break;
|
|
1760
|
-
}
|
|
1761
|
-
const eC = src.charCodeAt(unitStart);
|
|
1762
|
-
if (eC === 69 || eC === 101) {
|
|
1763
|
-
let look = unitStart + 1;
|
|
1764
|
-
const sgn = src.charCodeAt(look);
|
|
1765
|
-
if (sgn === 43 || sgn === 45)
|
|
1766
|
-
look++;
|
|
1767
|
-
let any = false;
|
|
1768
|
-
while (look < tend) {
|
|
1769
|
-
const c = src.charCodeAt(look);
|
|
1770
|
-
if (c >= 48 && c <= 57) {
|
|
1771
|
-
look++;
|
|
1772
|
-
any = true;
|
|
1773
|
-
continue;
|
|
1774
|
-
}
|
|
1775
|
-
break;
|
|
1776
|
-
}
|
|
1777
|
-
if (any)
|
|
1778
|
-
unitStart = look;
|
|
1779
|
-
}
|
|
1780
|
-
return {
|
|
1781
|
-
type: "Dimension",
|
|
1782
|
-
value: src.slice(tstart, unitStart),
|
|
1783
|
-
unit: src.slice(unitStart, tend),
|
|
1784
|
-
loc: s.positions ? locRange(s, tstart, tend) : null
|
|
1785
|
-
};
|
|
1786
|
-
}
|
|
1787
|
-
case 1 /* Ident */: {
|
|
1788
|
-
s.pos++;
|
|
1789
|
-
return { type: "Identifier", name: decodeName(src, tstart, tend), loc: s.positions ? locRange(s, tstart, tend) : null };
|
|
1790
|
-
}
|
|
1791
|
-
case 5 /* String */: {
|
|
1792
|
-
s.pos++;
|
|
1793
|
-
const innerStart = tstart + 1;
|
|
1794
|
-
const closesProperly = tend - tstart >= 2 && src.charCodeAt(tend - 1) === src.charCodeAt(tstart);
|
|
1795
|
-
const innerEnd = closesProperly ? tend - 1 : tend;
|
|
1796
|
-
const value = decodeString(src, innerStart, innerEnd);
|
|
1797
|
-
return { type: "String", value, loc: s.positions ? locRange(s, tstart, tend) : null };
|
|
1798
|
-
}
|
|
1799
|
-
case 7 /* Url */: {
|
|
1800
|
-
s.pos++;
|
|
1801
|
-
let a = tstart + 4;
|
|
1802
|
-
while (a < tend && isWhitespaceCode(src.charCodeAt(a)))
|
|
1803
|
-
a++;
|
|
1804
|
-
let b = tend;
|
|
1805
|
-
if (b > a && src.charCodeAt(b - 1) === 41)
|
|
1806
|
-
b--;
|
|
1807
|
-
while (b > a && isWhitespaceCode(src.charCodeAt(b - 1)))
|
|
1808
|
-
b--;
|
|
1809
|
-
let value;
|
|
1810
|
-
if (b - a >= 2) {
|
|
1811
|
-
const q0 = src.charCodeAt(a);
|
|
1812
|
-
const q1 = src.charCodeAt(b - 1);
|
|
1813
|
-
if ((q0 === 34 || q0 === 39) && q0 === q1)
|
|
1814
|
-
value = src.slice(a + 1, b - 1);
|
|
1815
|
-
else
|
|
1816
|
-
value = src.slice(a, b);
|
|
1817
|
-
} else {
|
|
1818
|
-
value = src.slice(a, b);
|
|
1819
|
-
}
|
|
1820
|
-
return { type: "Url", value, loc: s.positions ? locRange(s, tstart, tend) : null };
|
|
1821
|
-
}
|
|
1822
|
-
case 4 /* Hash */: {
|
|
1823
|
-
s.pos++;
|
|
1824
|
-
return { type: "Hash", name: src.slice(tstart + 1, tend), loc: s.positions ? locRange(s, tstart, tend) : null };
|
|
1825
|
-
}
|
|
1826
|
-
case 2 /* Function */: {
|
|
1827
|
-
return parseFunction(s);
|
|
1828
|
-
}
|
|
1829
|
-
case 21 /* LeftParenthesis */: {
|
|
1830
|
-
return parseParentheses(s);
|
|
1831
|
-
}
|
|
1832
|
-
case 18 /* Comma */: {
|
|
1833
|
-
s.pos++;
|
|
1834
|
-
return { type: "Operator", value: ",", loc: s.positions ? locRange(s, tstart, tend) : null };
|
|
1835
|
-
}
|
|
1836
|
-
case 16 /* Colon */: {
|
|
1837
|
-
s.pos++;
|
|
1838
|
-
return { type: "Operator", value: ":", loc: s.positions ? locRange(s, tstart, tend) : null };
|
|
1839
|
-
}
|
|
1840
|
-
case 9 /* Delim */: {
|
|
1841
|
-
s.pos++;
|
|
1842
|
-
const code = src.charCodeAt(tstart);
|
|
1843
|
-
const ch = src[tstart];
|
|
1844
|
-
if (isValueOperatorChar(code))
|
|
1845
|
-
return { type: "Operator", value: ch, loc: s.positions ? locRange(s, tstart, tend) : null };
|
|
1846
|
-
return { type: "Identifier", name: ch, loc: s.positions ? locRange(s, tstart, tend) : null };
|
|
1847
|
-
}
|
|
1848
|
-
case 19 /* LeftSquareBracket */: {
|
|
1849
|
-
s.pos++;
|
|
1850
|
-
const children = newList();
|
|
1851
|
-
while (peekType(s) !== 0 /* EOF */ && peekType(s) !== 20 /* RightSquareBracket */) {
|
|
1852
|
-
const inner = parseValueChild(s);
|
|
1853
|
-
if (inner)
|
|
1854
|
-
children.appendData(inner);
|
|
1855
|
-
}
|
|
1856
|
-
const endByte = s.pos < s.end ? s.ends[s.pos] : tend;
|
|
1857
|
-
if (peekType(s) === 20 /* RightSquareBracket */)
|
|
1858
|
-
s.pos++;
|
|
1859
|
-
return { type: "Brackets", children, loc: s.positions ? locRange(s, tstart, endByte) : null };
|
|
1860
|
-
}
|
|
1861
|
-
case 3 /* AtKeyword */:
|
|
1862
|
-
case 23 /* LeftCurlyBracket */:
|
|
1863
|
-
case 24 /* RightCurlyBracket */:
|
|
1864
|
-
case 22 /* RightParenthesis */:
|
|
1865
|
-
case 20 /* RightSquareBracket */:
|
|
1866
|
-
case 17 /* Semicolon */:
|
|
1867
|
-
case 0 /* EOF */:
|
|
1868
|
-
case 14 /* CDO */:
|
|
1869
|
-
case 15 /* CDC */:
|
|
1870
|
-
case 6 /* BadString */:
|
|
1871
|
-
case 8 /* BadUrl */: {
|
|
1872
|
-
s.pos++;
|
|
1873
|
-
return { type: "Raw", value: src.slice(tstart, tend), loc: s.positions ? locRange(s, tstart, tend) : null };
|
|
1874
|
-
}
|
|
1875
|
-
}
|
|
1876
|
-
s.pos++;
|
|
1877
|
-
return null;
|
|
1878
|
-
}
|
|
1879
|
-
function isWhitespaceCode(c) {
|
|
1880
|
-
return c === 32 || c === 9 || c === 10 || c === 12 || c === 13;
|
|
1881
|
-
}
|
|
1882
|
-
function isValueOperatorChar(code) {
|
|
1883
|
-
return code === 47 || code === 43 || code === 45 || code === 42 || code === 61 || code === 62 || code === 60 || code === 126 || code === 124 || code === 36 || code === 94 || code === 33 || code === 38;
|
|
1884
|
-
}
|
|
1885
|
-
function lowerIfNeeded(source, start, end) {
|
|
1886
|
-
for (let i = start;i < end; i++) {
|
|
1887
|
-
const c = source.charCodeAt(i);
|
|
1888
|
-
if (c >= 65 && c <= 90)
|
|
1889
|
-
return source.slice(start, end).toLowerCase();
|
|
1890
|
-
}
|
|
1891
|
-
return source.slice(start, end);
|
|
1892
|
-
}
|
|
1893
|
-
function locRange(s, startByte, endByte) {
|
|
1894
|
-
const start = s.tokenizer.locate(startByte);
|
|
1895
|
-
const end = s.tokenizer.locate(endByte);
|
|
1896
|
-
return {
|
|
1897
|
-
source: s.filename ?? "<unknown>",
|
|
1898
|
-
start: { offset: startByte, line: start.line, column: start.column },
|
|
1899
|
-
end: { offset: endByte, line: end.line, column: end.column }
|
|
1900
|
-
};
|
|
1901
|
-
}
|
|
1902
|
-
function parseFunction(s) {
|
|
1903
|
-
const startTok = consume(s);
|
|
1904
|
-
const name = lowerIfNeeded(s.source, startTok.start, startTok.end - 1);
|
|
1905
|
-
const children = newList();
|
|
1906
|
-
while (peekType(s) !== 0 /* EOF */ && peekType(s) !== 22 /* RightParenthesis */) {
|
|
1907
|
-
const node = parseValueChild(s);
|
|
1908
|
-
if (node)
|
|
1909
|
-
children.appendData(node);
|
|
1910
|
-
}
|
|
1911
|
-
if (peekType(s) === 22 /* RightParenthesis */)
|
|
1912
|
-
consume(s);
|
|
1913
|
-
if (name === "url") {
|
|
1914
|
-
for (let cur = children.head;cur != null; cur = cur.next) {
|
|
1915
|
-
if (cur.data.type === "String")
|
|
1916
|
-
return { type: "Url", value: cur.data.value, loc: loc(s, startTok, peek(s)) };
|
|
1917
|
-
}
|
|
1918
|
-
}
|
|
1919
|
-
return { type: "Function", name, children, loc: loc(s, startTok, peek(s)) };
|
|
1920
|
-
}
|
|
1921
|
-
function parseParentheses(s) {
|
|
1922
|
-
const startTok = consume(s);
|
|
1923
|
-
const children = newList();
|
|
1924
|
-
while (peekType(s) !== 0 /* EOF */ && peekType(s) !== 22 /* RightParenthesis */) {
|
|
1925
|
-
const node = parseValueChild(s);
|
|
1926
|
-
if (node)
|
|
1927
|
-
children.appendData(node);
|
|
1928
|
-
}
|
|
1929
|
-
if (peekType(s) === 22 /* RightParenthesis */)
|
|
1930
|
-
consume(s);
|
|
1931
|
-
return { type: "Parentheses", children, loc: loc(s, startTok, peek(s)) };
|
|
1932
|
-
}
|
|
1933
|
-
function parseSelectorList(s) {
|
|
1934
|
-
const startTok = peek(s);
|
|
1935
|
-
const children = newList();
|
|
1936
|
-
while (peekType(s) !== 0 /* EOF */) {
|
|
1937
|
-
skipWhitespace(s);
|
|
1938
|
-
if (peekType(s) === 0 /* EOF */ || peekType(s) === 23 /* LeftCurlyBracket */)
|
|
1939
|
-
break;
|
|
1940
|
-
const sel = parseSelector(s);
|
|
1941
|
-
if (sel.children.head !== null)
|
|
1942
|
-
children.appendData(sel);
|
|
1943
|
-
skipWhitespace(s);
|
|
1944
|
-
if (peekType(s) === 18 /* Comma */) {
|
|
1945
|
-
consume(s);
|
|
1946
|
-
continue;
|
|
1947
|
-
}
|
|
1948
|
-
break;
|
|
1949
|
-
}
|
|
1950
|
-
return { type: "SelectorList", children, loc: loc(s, startTok, peek(s)) };
|
|
1951
|
-
}
|
|
1952
|
-
function parseSelector(s) {
|
|
1953
|
-
const startTok = peek(s);
|
|
1954
|
-
const children = newList();
|
|
1955
|
-
let lastWasCombinator = true;
|
|
1956
|
-
while (peekType(s) !== 0 /* EOF */ && peekType(s) !== 18 /* Comma */ && peekType(s) !== 23 /* LeftCurlyBracket */) {
|
|
1957
|
-
const t = peek(s);
|
|
1958
|
-
if (t.type === 13 /* WhiteSpace */) {
|
|
1959
|
-
consume(s);
|
|
1960
|
-
if (!lastWasCombinator && peekType(s) !== 0 /* EOF */ && peekType(s) !== 18 /* Comma */ && peekType(s) !== 23 /* LeftCurlyBracket */ && !isExplicitCombinator(s) && !isColumnCombinator(s)) {
|
|
1961
|
-
const c = { type: "Combinator", name: " ", loc: loc(s, t, t) };
|
|
1962
|
-
children.appendData(c);
|
|
1963
|
-
lastWasCombinator = true;
|
|
1964
|
-
}
|
|
1965
|
-
continue;
|
|
1966
|
-
}
|
|
1967
|
-
if (t.type === 9 /* Delim */ && s.source.charCodeAt(t.start) === 124 && s.types[s.pos + 1] === 9 /* Delim */ && s.source.charCodeAt(s.starts[s.pos + 1]) === 124) {
|
|
1968
|
-
const startCol = peek(s);
|
|
1969
|
-
consume(s);
|
|
1970
|
-
const endCol = consume(s);
|
|
1971
|
-
const c = { type: "Combinator", name: "||", loc: loc(s, startCol, endCol) };
|
|
1972
|
-
children.appendData(c);
|
|
1973
|
-
lastWasCombinator = true;
|
|
1974
|
-
skipWhitespace(s);
|
|
1975
|
-
continue;
|
|
1976
|
-
}
|
|
1977
|
-
if (isExplicitCombinator(s)) {
|
|
1978
|
-
const ct = consume(s);
|
|
1979
|
-
const ch = s.source[ct.start];
|
|
1980
|
-
const c = { type: "Combinator", name: ch, loc: loc(s, ct, ct) };
|
|
1981
|
-
children.appendData(c);
|
|
1982
|
-
lastWasCombinator = true;
|
|
1983
|
-
skipWhitespace(s);
|
|
1984
|
-
continue;
|
|
1985
|
-
}
|
|
1986
|
-
const seg = parseSelectorSegment(s);
|
|
1987
|
-
if (!seg)
|
|
1988
|
-
break;
|
|
1989
|
-
children.appendData(seg);
|
|
1990
|
-
lastWasCombinator = false;
|
|
1991
|
-
}
|
|
1992
|
-
while (children.tail && children.tail.data.type === "Combinator")
|
|
1993
|
-
children.remove(children.tail);
|
|
1994
|
-
return { type: "Selector", children, loc: loc(s, startTok, peek(s)) };
|
|
1995
|
-
}
|
|
1996
|
-
function isExplicitCombinator(s) {
|
|
1997
|
-
const t = peek(s);
|
|
1998
|
-
if (t.type !== 9 /* Delim */)
|
|
1999
|
-
return false;
|
|
2000
|
-
const ch = s.source[t.start];
|
|
2001
|
-
return ch === ">" || ch === "+" || ch === "~";
|
|
2002
|
-
}
|
|
2003
|
-
function isColumnCombinator(s) {
|
|
2004
|
-
if (s.types[s.pos] !== 9 /* Delim */)
|
|
2005
|
-
return false;
|
|
2006
|
-
if (s.source.charCodeAt(s.starts[s.pos]) !== 124)
|
|
2007
|
-
return false;
|
|
2008
|
-
if (s.types[s.pos + 1] !== 9 /* Delim */)
|
|
2009
|
-
return false;
|
|
2010
|
-
return s.source.charCodeAt(s.starts[s.pos + 1]) === 124;
|
|
2011
|
-
}
|
|
2012
|
-
function parseSelectorSegment(s) {
|
|
2013
|
-
const t = peek(s);
|
|
2014
|
-
switch (t.type) {
|
|
2015
|
-
case 1 /* Ident */: {
|
|
2016
|
-
consume(s);
|
|
2017
|
-
if (peekType(s) === 9 /* Delim */ && s.source[peek(s).start] === "|" && s.source[peek(s).start + 1] !== "=" && !(s.types[s.pos + 1] === 9 /* Delim */ && s.source.charCodeAt(s.starts[s.pos + 1]) === 124)) {
|
|
2018
|
-
consume(s);
|
|
2019
|
-
if (peekType(s) === 1 /* Ident */) {
|
|
2020
|
-
const local = consume(s);
|
|
2021
|
-
const node2 = {
|
|
2022
|
-
type: "TypeSelector",
|
|
2023
|
-
name: `${tokenSlice(s, t)}|${tokenSlice(s, local)}`,
|
|
2024
|
-
loc: loc(s, t, local)
|
|
2025
|
-
};
|
|
2026
|
-
return node2;
|
|
2027
|
-
}
|
|
2028
|
-
if (peekType(s) === 9 /* Delim */ && s.source[peek(s).start] === "*") {
|
|
2029
|
-
const star = consume(s);
|
|
2030
|
-
const node2 = {
|
|
2031
|
-
type: "TypeSelector",
|
|
2032
|
-
name: `${tokenSlice(s, t)}|*`,
|
|
2033
|
-
loc: loc(s, t, star)
|
|
2034
|
-
};
|
|
2035
|
-
return node2;
|
|
2036
|
-
}
|
|
2037
|
-
}
|
|
2038
|
-
const node = { type: "TypeSelector", name: tokenSlice(s, t), loc: loc(s, t, t) };
|
|
2039
|
-
return node;
|
|
2040
|
-
}
|
|
2041
|
-
case 11 /* Percentage */: {
|
|
2042
|
-
consume(s);
|
|
2043
|
-
const node = { type: "TypeSelector", name: tokenSlice(s, t), loc: loc(s, t, t) };
|
|
2044
|
-
return node;
|
|
2045
|
-
}
|
|
2046
|
-
case 10 /* Number */: {
|
|
2047
|
-
consume(s);
|
|
2048
|
-
const node = { type: "TypeSelector", name: tokenSlice(s, t), loc: loc(s, t, t) };
|
|
2049
|
-
return node;
|
|
2050
|
-
}
|
|
2051
|
-
case 9 /* Delim */: {
|
|
2052
|
-
const ch = s.source[t.start];
|
|
2053
|
-
if (ch === "*") {
|
|
2054
|
-
consume(s);
|
|
2055
|
-
const node = { type: "TypeSelector", name: "*", loc: loc(s, t, t) };
|
|
2056
|
-
return node;
|
|
2057
|
-
}
|
|
2058
|
-
if (ch === ".") {
|
|
2059
|
-
consume(s);
|
|
2060
|
-
if (peekType(s) === 1 /* Ident */) {
|
|
2061
|
-
const id = consume(s);
|
|
2062
|
-
const node = { type: "ClassSelector", name: tokenSlice(s, id), loc: loc(s, t, id) };
|
|
2063
|
-
return node;
|
|
2064
|
-
}
|
|
2065
|
-
return null;
|
|
2066
|
-
}
|
|
2067
|
-
if (ch === "&") {
|
|
2068
|
-
consume(s);
|
|
2069
|
-
return { type: "NestingSelector", loc: loc(s, t, t) };
|
|
2070
|
-
}
|
|
2071
|
-
consume(s);
|
|
2072
|
-
return null;
|
|
2073
|
-
}
|
|
2074
|
-
case 4 /* Hash */: {
|
|
2075
|
-
consume(s);
|
|
2076
|
-
const node = { type: "IdSelector", name: s.source.slice(t.start + 1, t.end), loc: loc(s, t, t) };
|
|
2077
|
-
return node;
|
|
2078
|
-
}
|
|
2079
|
-
case 16 /* Colon */: {
|
|
2080
|
-
consume(s);
|
|
2081
|
-
const isElement = peekType(s) === 16 /* Colon */;
|
|
2082
|
-
if (isElement)
|
|
2083
|
-
consume(s);
|
|
2084
|
-
return parsePseudo(s, isElement, t);
|
|
2085
|
-
}
|
|
2086
|
-
case 19 /* LeftSquareBracket */: {
|
|
2087
|
-
return parseAttribute(s);
|
|
2088
|
-
}
|
|
2089
|
-
}
|
|
2090
|
-
return null;
|
|
2091
|
-
}
|
|
2092
|
-
function parsePseudo(s, isElement, startTok) {
|
|
2093
|
-
const t = peek(s);
|
|
2094
|
-
if (t.type === 1 /* Ident */) {
|
|
2095
|
-
consume(s);
|
|
2096
|
-
const name = lowerIfNeeded(s.source, t.start, t.end);
|
|
2097
|
-
const node = isElement ? { type: "PseudoElementSelector", name, children: null, loc: loc(s, startTok, t) } : { type: "PseudoClassSelector", name, children: null, loc: loc(s, startTok, t) };
|
|
2098
|
-
return node;
|
|
2099
|
-
}
|
|
2100
|
-
if (t.type === 2 /* Function */) {
|
|
2101
|
-
consume(s);
|
|
2102
|
-
const name = lowerIfNeeded(s.source, t.start, t.end - 1);
|
|
2103
|
-
const children = newList();
|
|
2104
|
-
const isSelectorListPseudo = !isElement && SELECTOR_LIST_PSEUDOS_PARSE.has(name);
|
|
2105
|
-
if (isSelectorListPseudo) {
|
|
2106
|
-
const argStart = peek(s);
|
|
2107
|
-
let argEnd = argStart;
|
|
2108
|
-
let depth = 1;
|
|
2109
|
-
while (peekType(s) !== 0 /* EOF */ && depth > 0) {
|
|
2110
|
-
if (peekType(s) === 21 /* LeftParenthesis */ || peekType(s) === 2 /* Function */)
|
|
2111
|
-
depth++;
|
|
2112
|
-
else if (peekType(s) === 22 /* RightParenthesis */) {
|
|
2113
|
-
depth--;
|
|
2114
|
-
if (depth === 0)
|
|
2115
|
-
break;
|
|
2116
|
-
}
|
|
2117
|
-
argEnd = consume(s);
|
|
2118
|
-
}
|
|
2119
|
-
if (peekType(s) === 22 /* RightParenthesis */)
|
|
2120
|
-
consume(s);
|
|
2121
|
-
const inner = s.source.slice(argStart.start, argEnd.end).trim();
|
|
2122
|
-
if (inner.length > 0) {
|
|
2123
|
-
const sub = makeState(inner, { positions: false });
|
|
2124
|
-
const list = parseSelectorList(sub);
|
|
2125
|
-
children.appendData(list);
|
|
2126
|
-
}
|
|
2127
|
-
} else {
|
|
2128
|
-
while (peekType(s) !== 0 /* EOF */ && peekType(s) !== 22 /* RightParenthesis */) {
|
|
2129
|
-
const inner = parseValueChild(s);
|
|
2130
|
-
if (inner)
|
|
2131
|
-
children.appendData(inner);
|
|
2132
|
-
}
|
|
2133
|
-
if (peekType(s) === 22 /* RightParenthesis */)
|
|
2134
|
-
consume(s);
|
|
2135
|
-
}
|
|
2136
|
-
if (isElement) {
|
|
2137
|
-
const node2 = { type: "PseudoElementSelector", name, children, loc: loc(s, startTok, peek(s)) };
|
|
2138
|
-
return node2;
|
|
2139
|
-
}
|
|
2140
|
-
const node = { type: "PseudoClassSelector", name, children, loc: loc(s, startTok, peek(s)) };
|
|
2141
|
-
return node;
|
|
2142
|
-
}
|
|
2143
|
-
return null;
|
|
2144
|
-
}
|
|
2145
|
-
function parseAttribute(s) {
|
|
2146
|
-
const startTok = consume(s);
|
|
2147
|
-
skipWhitespace(s);
|
|
2148
|
-
const nameTok = peek(s);
|
|
2149
|
-
if (nameTok.type !== 1 /* Ident */)
|
|
2150
|
-
return null;
|
|
2151
|
-
consume(s);
|
|
2152
|
-
const name = { type: "Identifier", name: tokenSlice(s, nameTok), loc: loc(s, nameTok, nameTok) };
|
|
2153
|
-
skipWhitespace(s);
|
|
2154
|
-
let matcher = null;
|
|
2155
|
-
let value = null;
|
|
2156
|
-
let flags = null;
|
|
2157
|
-
const next = peek(s);
|
|
2158
|
-
if (next.type === 9 /* Delim */) {
|
|
2159
|
-
const ch = s.source[next.start];
|
|
2160
|
-
const ch2 = s.source[next.start + 1];
|
|
2161
|
-
if (ch === "=") {
|
|
2162
|
-
matcher = "=";
|
|
2163
|
-
consume(s);
|
|
2164
|
-
} else if ((ch === "~" || ch === "|" || ch === "^" || ch === "$" || ch === "*") && ch2 === "=") {
|
|
2165
|
-
consume(s);
|
|
2166
|
-
const eq = peek(s);
|
|
2167
|
-
if (eq.type === 9 /* Delim */ && s.source[eq.start] === "=") {
|
|
2168
|
-
consume(s);
|
|
2169
|
-
matcher = `${ch}=`;
|
|
2170
|
-
}
|
|
2171
|
-
}
|
|
2172
|
-
skipWhitespace(s);
|
|
2173
|
-
const v = peek(s);
|
|
2174
|
-
if (v.type === 5 /* String */) {
|
|
2175
|
-
consume(s);
|
|
2176
|
-
const closesProperly = v.end - v.start >= 2 && s.source.charCodeAt(v.end - 1) === s.source.charCodeAt(v.start);
|
|
2177
|
-
const text = decodeString(s.source, v.start + 1, closesProperly ? v.end - 1 : v.end);
|
|
2178
|
-
value = { type: "String", value: text, loc: loc(s, v, v) };
|
|
2179
|
-
} else if (v.type === 1 /* Ident */) {
|
|
2180
|
-
consume(s);
|
|
2181
|
-
value = { type: "Identifier", name: tokenSlice(s, v), loc: loc(s, v, v) };
|
|
2182
|
-
}
|
|
2183
|
-
skipWhitespace(s);
|
|
2184
|
-
const flagTok = peek(s);
|
|
2185
|
-
if (flagTok.type === 1 /* Ident */) {
|
|
2186
|
-
consume(s);
|
|
2187
|
-
flags = tokenSlice(s, flagTok);
|
|
2188
|
-
}
|
|
2189
|
-
}
|
|
2190
|
-
skipWhitespace(s);
|
|
2191
|
-
let endTok = peek(s);
|
|
2192
|
-
if (peekType(s) === 20 /* RightSquareBracket */) {
|
|
2193
|
-
endTok = consume(s);
|
|
2194
|
-
}
|
|
2195
|
-
return { type: "AttributeSelector", name, matcher, value, flags, loc: loc(s, startTok, endTok) };
|
|
2196
|
-
}
|
|
2197
|
-
// src/parse/walker.ts
|
|
2198
|
-
var SKIP = Symbol("walkSkip");
|
|
2199
|
-
var STOP = Symbol("walkStop");
|
|
2200
|
-
function newContext(root) {
|
|
2201
|
-
return {
|
|
2202
|
-
root,
|
|
2203
|
-
stylesheet: null,
|
|
2204
|
-
atrule: null,
|
|
2205
|
-
atrulePrelude: null,
|
|
2206
|
-
rule: null,
|
|
2207
|
-
selector: null,
|
|
2208
|
-
block: null,
|
|
2209
|
-
declaration: null,
|
|
2210
|
-
function: null
|
|
2211
|
-
};
|
|
2212
|
-
}
|
|
2213
|
-
function walkImpl(root, visitor) {
|
|
2214
|
-
const ctx = newContext(root);
|
|
2215
|
-
const enter = typeof visitor === "function" ? visitor : visitor.enter;
|
|
2216
|
-
const leave = typeof visitor === "function" ? null : visitor.leave ?? null;
|
|
2217
|
-
const filter = typeof visitor === "function" ? null : visitor.visit ?? null;
|
|
2218
|
-
const reverse = typeof visitor === "function" ? false : visitor.reverse ?? false;
|
|
2219
|
-
function visitNode(node, item, list) {
|
|
2220
|
-
let pushed = null;
|
|
2221
|
-
let prev;
|
|
2222
|
-
switch (node.type) {
|
|
2223
|
-
case "StyleSheet":
|
|
2224
|
-
pushed = "stylesheet";
|
|
2225
|
-
prev = ctx.stylesheet;
|
|
2226
|
-
ctx.stylesheet = node;
|
|
2227
|
-
break;
|
|
2228
|
-
case "Atrule":
|
|
2229
|
-
pushed = "atrule";
|
|
2230
|
-
prev = ctx.atrule;
|
|
2231
|
-
ctx.atrule = node;
|
|
2232
|
-
break;
|
|
2233
|
-
case "AtrulePrelude":
|
|
2234
|
-
pushed = "atrulePrelude";
|
|
2235
|
-
prev = ctx.atrulePrelude;
|
|
2236
|
-
ctx.atrulePrelude = node;
|
|
2237
|
-
break;
|
|
2238
|
-
case "Rule":
|
|
2239
|
-
pushed = "rule";
|
|
2240
|
-
prev = ctx.rule;
|
|
2241
|
-
ctx.rule = node;
|
|
2242
|
-
break;
|
|
2243
|
-
case "Selector":
|
|
2244
|
-
pushed = "selector";
|
|
2245
|
-
prev = ctx.selector;
|
|
2246
|
-
ctx.selector = node;
|
|
2247
|
-
break;
|
|
2248
|
-
case "Block":
|
|
2249
|
-
pushed = "block";
|
|
2250
|
-
prev = ctx.block;
|
|
2251
|
-
ctx.block = node;
|
|
2252
|
-
break;
|
|
2253
|
-
case "Declaration":
|
|
2254
|
-
pushed = "declaration";
|
|
2255
|
-
prev = ctx.declaration;
|
|
2256
|
-
ctx.declaration = node;
|
|
2257
|
-
break;
|
|
2258
|
-
case "Function":
|
|
2259
|
-
pushed = "function";
|
|
2260
|
-
prev = ctx.function;
|
|
2261
|
-
ctx.function = node;
|
|
2262
|
-
break;
|
|
2263
|
-
}
|
|
2264
|
-
let result;
|
|
2265
|
-
if ((filter === null || filter === node.type) && enter) {
|
|
2266
|
-
const r = enter.call(ctx, node, item, list);
|
|
2267
|
-
if (r === SKIP) {
|
|
2268
|
-
if (pushed)
|
|
2269
|
-
ctx[pushed] = prev;
|
|
2270
|
-
return;
|
|
2271
|
-
}
|
|
2272
|
-
if (r === STOP) {
|
|
2273
|
-
if (pushed)
|
|
2274
|
-
ctx[pushed] = prev;
|
|
2275
|
-
return STOP;
|
|
2276
|
-
}
|
|
2277
|
-
}
|
|
2278
|
-
result = walkChildren(node, reverse, visitNode);
|
|
2279
|
-
if (result === STOP) {
|
|
2280
|
-
if (pushed)
|
|
2281
|
-
ctx[pushed] = prev;
|
|
2282
|
-
return STOP;
|
|
2283
|
-
}
|
|
2284
|
-
if ((filter === null || filter === node.type) && leave) {
|
|
2285
|
-
const r = leave.call(ctx, node, item, list);
|
|
2286
|
-
if (r === STOP) {
|
|
2287
|
-
if (pushed)
|
|
2288
|
-
ctx[pushed] = prev;
|
|
2289
|
-
return STOP;
|
|
2290
|
-
}
|
|
2291
|
-
}
|
|
2292
|
-
if (pushed)
|
|
2293
|
-
ctx[pushed] = prev;
|
|
2294
|
-
return;
|
|
2295
|
-
}
|
|
2296
|
-
return visitNode(root, null, null);
|
|
2297
|
-
}
|
|
2298
|
-
var walk = Object.assign(walkImpl, { skip: SKIP, stop: STOP });
|
|
2299
|
-
function walkChildren(node, reverse, visitNode) {
|
|
2300
|
-
if ("children" in node && node.children instanceof CssList) {
|
|
2301
|
-
return walkList(node.children, reverse, visitNode);
|
|
2302
|
-
}
|
|
2303
|
-
if (node.type === "Rule") {
|
|
2304
|
-
const r1 = visitNode(node.prelude, null, null);
|
|
2305
|
-
if (r1 === STOP)
|
|
2306
|
-
return STOP;
|
|
2307
|
-
const r2 = visitNode(node.block, null, null);
|
|
2308
|
-
if (r2 === STOP)
|
|
2309
|
-
return STOP;
|
|
2310
|
-
return;
|
|
2311
|
-
}
|
|
2312
|
-
if (node.type === "Atrule") {
|
|
2313
|
-
if (node.prelude) {
|
|
2314
|
-
const r = visitNode(node.prelude, null, null);
|
|
2315
|
-
if (r === STOP)
|
|
2316
|
-
return STOP;
|
|
2317
|
-
}
|
|
2318
|
-
if (node.block) {
|
|
2319
|
-
const r = visitNode(node.block, null, null);
|
|
2320
|
-
if (r === STOP)
|
|
2321
|
-
return STOP;
|
|
2322
|
-
}
|
|
2323
|
-
return;
|
|
2324
|
-
}
|
|
2325
|
-
if (node.type === "Declaration") {
|
|
2326
|
-
return visitNode(node.value, null, null);
|
|
2327
|
-
}
|
|
2328
|
-
if (node.type === "AttributeSelector") {
|
|
2329
|
-
const r = visitNode(node.name, null, null);
|
|
2330
|
-
if (r === STOP)
|
|
2331
|
-
return STOP;
|
|
2332
|
-
if (node.value)
|
|
2333
|
-
return visitNode(node.value, null, null);
|
|
2334
|
-
return;
|
|
2335
|
-
}
|
|
2336
|
-
return;
|
|
2337
|
-
}
|
|
2338
|
-
function walkList(list, reverse, visitNode) {
|
|
2339
|
-
let stopped;
|
|
2340
|
-
if (reverse) {
|
|
2341
|
-
list.forEachRight((data, item, l) => {
|
|
2342
|
-
if (stopped)
|
|
2343
|
-
return;
|
|
2344
|
-
const r = visitNode(data, item, l);
|
|
2345
|
-
if (r === STOP)
|
|
2346
|
-
stopped = STOP;
|
|
2347
|
-
});
|
|
2348
|
-
} else {
|
|
2349
|
-
list.forEach((data, item, l) => {
|
|
2350
|
-
if (stopped)
|
|
2351
|
-
return;
|
|
2352
|
-
const r = visitNode(data, item, l);
|
|
2353
|
-
if (r === STOP)
|
|
2354
|
-
stopped = STOP;
|
|
2355
|
-
});
|
|
2356
|
-
}
|
|
2357
|
-
return stopped;
|
|
2358
|
-
}
|
|
2359
|
-
export {
|
|
2360
|
-
walk,
|
|
2361
|
-
parse,
|
|
2362
|
-
makeList,
|
|
2363
|
-
generate,
|
|
2364
|
-
decodeName,
|
|
2365
|
-
clone,
|
|
2366
|
-
Tokenizer,
|
|
2367
|
-
TokenType,
|
|
2368
|
-
CssList as List
|
|
2369
|
-
};
|
|
2
|
+
import{q as a,r as b,s as c,t as d,u as e,v as f,w as g,x as h,y as i}from"../chunk-9ep6bwwb.js";import"../chunk-1kmkypmr.js";export{i as walk,h as parse,b as makeList,d as generate,g as decodeName,c as clone,f as Tokenizer,e as TokenType,a as List};
|