@tbela99/css-parser 0.0.1-rc4 → 0.0.1-rc6
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/README.md +59 -1
- package/dist/config.json.js +49 -0
- package/dist/index-umd-web.js +3742 -3489
- package/dist/index.cjs +3742 -3489
- package/dist/index.d.ts +38 -26
- package/dist/lib/ast/expand.js +159 -0
- package/dist/lib/ast/minify.js +89 -87
- package/dist/lib/ast/walk.js +10 -1
- package/dist/lib/parser/declaration/list.js +2 -1
- package/dist/lib/parser/declaration/map.js +10 -1
- package/dist/lib/parser/parse.js +60 -53
- package/dist/lib/parser/tokenize.js +144 -124
- package/dist/lib/parser/utils/syntax.js +36 -28
- package/dist/lib/parser/utils/type.js +1 -1
- package/dist/lib/renderer/render.js +21 -28
- package/dist/lib/transform.js +5 -1
- package/dist/node/index.js +8 -7
- package/dist/web/index.js +8 -7
- package/package.json +1 -1
package/dist/lib/parser/parse.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isPseudo, isAtKeyword, isFunction, isNumber, isDimension, parseDimension, isPercentage, isIdent, isHexColor, isHash, isIdentStart } from './utils/syntax.js';
|
|
1
|
+
import { isPseudo, isAtKeyword, isFunction, isNumber, isDimension, parseDimension, isPercentage, isIdent, isHexColor, isHash, isIdentStart, isColor } from './utils/syntax.js';
|
|
2
2
|
import { renderToken } from '../renderer/render.js';
|
|
3
3
|
import { COLORS_NAMES } from '../renderer/utils/color.js';
|
|
4
4
|
import { minify, combinators } from '../ast/minify.js';
|
|
@@ -52,19 +52,19 @@ async function parse(iterator, opt = {}) {
|
|
|
52
52
|
let tokens = results.map(mapToken);
|
|
53
53
|
let i;
|
|
54
54
|
let loc;
|
|
55
|
-
// if ((<Token>tokens.at(-1))?.typ == 'EOF') {
|
|
56
|
-
//
|
|
57
|
-
// tokens.pop();
|
|
58
|
-
// }
|
|
59
55
|
for (i = 0; i < tokens.length; i++) {
|
|
60
|
-
if (tokens[i].typ == 'Comment') {
|
|
61
|
-
// @ts-ignore
|
|
62
|
-
context.chi.push(tokens[i]);
|
|
56
|
+
if (tokens[i].typ == 'Comment' || tokens[i].typ == 'CDOCOMM') {
|
|
63
57
|
const position = map.get(tokens[i]);
|
|
58
|
+
if (tokens[i].typ == 'CDOCOMM' && context.typ != 'StyleSheet') {
|
|
59
|
+
errors.push({ action: 'drop', message: `CDOCOMM not allowed here ${JSON.stringify(tokens[i], null, 1)}`, location: { src, ...position } });
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
64
62
|
loc = {
|
|
65
63
|
sta: position,
|
|
66
64
|
src
|
|
67
65
|
};
|
|
66
|
+
// @ts-ignore
|
|
67
|
+
context.chi.push(tokens[i]);
|
|
68
68
|
if (options.sourcemap) {
|
|
69
69
|
tokens[i].loc = loc;
|
|
70
70
|
}
|
|
@@ -95,7 +95,7 @@ async function parse(iterator, opt = {}) {
|
|
|
95
95
|
const atRule = tokens.shift();
|
|
96
96
|
const position = map.get(atRule);
|
|
97
97
|
if (atRule.val == 'charset' && position.ind > 0) {
|
|
98
|
-
errors.push({ action: 'drop', message: 'invalid @charset', location: { src, ...position } });
|
|
98
|
+
errors.push({ action: 'drop', message: 'parse: invalid @charset', location: { src, ...position } });
|
|
99
99
|
return null;
|
|
100
100
|
}
|
|
101
101
|
// @ts-ignore
|
|
@@ -125,12 +125,12 @@ async function parse(iterator, opt = {}) {
|
|
|
125
125
|
}
|
|
126
126
|
// @ts-ignore
|
|
127
127
|
if (tokens[0]?.typ != 'String' && tokens[0]?.typ != 'UrlFunc') {
|
|
128
|
-
errors.push({ action: 'drop', message: 'invalid @import', location: { src, ...position } });
|
|
128
|
+
errors.push({ action: 'drop', message: 'parse: invalid @import', location: { src, ...position } });
|
|
129
129
|
return null;
|
|
130
130
|
}
|
|
131
131
|
// @ts-ignore
|
|
132
132
|
if (tokens[0].typ == 'UrlFunc' && tokens[1]?.typ != 'Url-token' && tokens[1]?.typ != 'String') {
|
|
133
|
-
errors.push({ action: 'drop', message: 'invalid @import', location: { src, ...position } });
|
|
133
|
+
errors.push({ action: 'drop', message: 'parse: invalid @import', location: { src, ...position } });
|
|
134
134
|
return null;
|
|
135
135
|
}
|
|
136
136
|
}
|
|
@@ -166,7 +166,8 @@ async function parse(iterator, opt = {}) {
|
|
|
166
166
|
return null;
|
|
167
167
|
}
|
|
168
168
|
catch (error) {
|
|
169
|
-
|
|
169
|
+
// @ts-ignore
|
|
170
|
+
errors.push({ action: 'ignore', message: 'parse: ' + error.message, error });
|
|
170
171
|
}
|
|
171
172
|
}
|
|
172
173
|
}
|
|
@@ -183,7 +184,7 @@ async function parse(iterator, opt = {}) {
|
|
|
183
184
|
nam: renderToken(atRule, { removeComments: true }),
|
|
184
185
|
val: raw.join('')
|
|
185
186
|
};
|
|
186
|
-
Object.defineProperty(node, 'raw', { enumerable: false, writable:
|
|
187
|
+
Object.defineProperty(node, 'raw', { enumerable: false, configurable: true, writable: true, value: raw });
|
|
187
188
|
if (delim.typ == 'Block-start') {
|
|
188
189
|
node.chi = [];
|
|
189
190
|
}
|
|
@@ -231,7 +232,7 @@ async function parse(iterator, opt = {}) {
|
|
|
231
232
|
chi: []
|
|
232
233
|
};
|
|
233
234
|
let raw = [...uniq.values()];
|
|
234
|
-
Object.defineProperty(node, 'raw', { enumerable: false, writable: true, value: raw });
|
|
235
|
+
Object.defineProperty(node, 'raw', { enumerable: false, configurable: true, writable: true, value: raw });
|
|
235
236
|
loc = {
|
|
236
237
|
sta: position,
|
|
237
238
|
src
|
|
@@ -273,7 +274,7 @@ async function parse(iterator, opt = {}) {
|
|
|
273
274
|
if (name[i].typ != 'Whitespace' && name[i].typ != 'Comment') {
|
|
274
275
|
errors.push({
|
|
275
276
|
action: 'drop',
|
|
276
|
-
message: 'invalid declaration',
|
|
277
|
+
message: 'parse: invalid declaration',
|
|
277
278
|
location: { src, ...position }
|
|
278
279
|
});
|
|
279
280
|
return null;
|
|
@@ -283,7 +284,7 @@ async function parse(iterator, opt = {}) {
|
|
|
283
284
|
if (value == null) {
|
|
284
285
|
errors.push({
|
|
285
286
|
action: 'drop',
|
|
286
|
-
message: 'invalid declaration',
|
|
287
|
+
message: 'parse: invalid declaration',
|
|
287
288
|
location: { src, ...position }
|
|
288
289
|
});
|
|
289
290
|
return null;
|
|
@@ -291,7 +292,7 @@ async function parse(iterator, opt = {}) {
|
|
|
291
292
|
if (value.length == 0) {
|
|
292
293
|
errors.push({
|
|
293
294
|
action: 'drop',
|
|
294
|
-
message: 'invalid declaration',
|
|
295
|
+
message: 'parse: invalid declaration',
|
|
295
296
|
location: { src, ...position }
|
|
296
297
|
});
|
|
297
298
|
return null;
|
|
@@ -309,7 +310,7 @@ async function parse(iterator, opt = {}) {
|
|
|
309
310
|
if (node.val.length == 0) {
|
|
310
311
|
errors.push({
|
|
311
312
|
action: 'drop',
|
|
312
|
-
message: 'invalid declaration',
|
|
313
|
+
message: 'parse: invalid declaration',
|
|
313
314
|
location: { src, ...position }
|
|
314
315
|
});
|
|
315
316
|
return null;
|
|
@@ -327,13 +328,14 @@ async function parse(iterator, opt = {}) {
|
|
|
327
328
|
}
|
|
328
329
|
const iter = tokenize(iterator);
|
|
329
330
|
let item;
|
|
330
|
-
while (
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
331
|
+
while (item = iter.next().value) {
|
|
332
|
+
bytesIn = item.bytesIn;
|
|
333
|
+
// parse error
|
|
334
|
+
if (item.hint != null && item.hint.startsWith('Bad-')) {
|
|
335
|
+
// bad token
|
|
336
|
+
continue;
|
|
334
337
|
}
|
|
335
338
|
tokens.push(item);
|
|
336
|
-
bytesIn = item.bytesIn;
|
|
337
339
|
if (item.token == ';' || item.token == '{') {
|
|
338
340
|
let node = await parseNode(tokens);
|
|
339
341
|
if (node != null) {
|
|
@@ -377,15 +379,28 @@ async function parse(iterator, opt = {}) {
|
|
|
377
379
|
if (tokens.length > 0) {
|
|
378
380
|
await parseNode(tokens);
|
|
379
381
|
}
|
|
382
|
+
while (stack.length > 0 && context != ast) {
|
|
383
|
+
const previousNode = stack.pop();
|
|
384
|
+
// @ts-ignore
|
|
385
|
+
context = stack[stack.length - 1] || ast;
|
|
386
|
+
// @ts-ignore
|
|
387
|
+
if (options.removeEmpty && previousNode != null && previousNode.chi.length == 0 && context.chi[context.chi.length - 1] == previousNode) {
|
|
388
|
+
context.chi.pop();
|
|
389
|
+
continue;
|
|
390
|
+
}
|
|
391
|
+
break;
|
|
392
|
+
}
|
|
380
393
|
const endParseTime = performance.now();
|
|
381
394
|
if (options.minify) {
|
|
382
395
|
if (ast.chi.length > 0) {
|
|
383
|
-
minify(ast, options, true);
|
|
396
|
+
minify(ast, options, true, errors);
|
|
384
397
|
}
|
|
385
398
|
}
|
|
386
399
|
const endTime = performance.now();
|
|
387
400
|
return {
|
|
388
|
-
ast,
|
|
401
|
+
ast,
|
|
402
|
+
errors,
|
|
403
|
+
stats: {
|
|
389
404
|
bytesIn,
|
|
390
405
|
parse: `${(endParseTime - startTime).toFixed(2)}ms`,
|
|
391
406
|
minify: `${(endTime - endParseTime).toFixed(2)}ms`,
|
|
@@ -641,41 +656,33 @@ function parseTokens(tokens, options = {}) {
|
|
|
641
656
|
// @ts-ignore
|
|
642
657
|
t.chi.pop();
|
|
643
658
|
}
|
|
644
|
-
let isColor = true;
|
|
645
659
|
// @ts-ignore
|
|
646
|
-
if (options.parseColor &&
|
|
660
|
+
if (options.parseColor && t.typ == 'Func' && isColor(t)) {
|
|
661
|
+
// if (isColor) {
|
|
647
662
|
// @ts-ignore
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
if (isColor) {
|
|
655
|
-
// @ts-ignore
|
|
656
|
-
t.typ = 'Color';
|
|
657
|
-
// @ts-ignore
|
|
658
|
-
t.kin = t.val;
|
|
663
|
+
t.typ = 'Color';
|
|
664
|
+
// @ts-ignore
|
|
665
|
+
t.kin = t.val;
|
|
666
|
+
// @ts-ignore
|
|
667
|
+
let m = t.chi.length;
|
|
668
|
+
while (m-- > 0) {
|
|
659
669
|
// @ts-ignore
|
|
660
|
-
|
|
661
|
-
while (m-- > 0) {
|
|
670
|
+
if (['Literal'].concat(trimWhiteSpace).includes(t.chi[m].typ)) {
|
|
662
671
|
// @ts-ignore
|
|
663
|
-
if (
|
|
672
|
+
if (t.chi[m + 1]?.typ == 'Whitespace') {
|
|
664
673
|
// @ts-ignore
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
674
|
+
t.chi.splice(m + 1, 1);
|
|
675
|
+
}
|
|
676
|
+
// @ts-ignore
|
|
677
|
+
if (t.chi[m - 1]?.typ == 'Whitespace') {
|
|
669
678
|
// @ts-ignore
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
t.chi.splice(m - 1, 1);
|
|
673
|
-
m--;
|
|
674
|
-
}
|
|
679
|
+
t.chi.splice(m - 1, 1);
|
|
680
|
+
m--;
|
|
675
681
|
}
|
|
676
682
|
}
|
|
677
|
-
continue;
|
|
678
683
|
}
|
|
684
|
+
continue;
|
|
685
|
+
// }
|
|
679
686
|
}
|
|
680
687
|
if (t.typ == 'UrlFunc') {
|
|
681
688
|
// @ts-ignore
|
|
@@ -700,7 +707,7 @@ function parseTokens(tokens, options = {}) {
|
|
|
700
707
|
// @ts-ignore
|
|
701
708
|
if (t.chi.length > 0) {
|
|
702
709
|
// @ts-ignore
|
|
703
|
-
parseTokens(t.chi,
|
|
710
|
+
parseTokens(t.chi, options);
|
|
704
711
|
if (t.typ == 'Pseudo-class-func' && t.val == ':is' && options.minify) {
|
|
705
712
|
//
|
|
706
713
|
const count = t.chi.filter(t => t.typ != 'Comment').length;
|
|
@@ -719,7 +726,7 @@ function parseTokens(tokens, options = {}) {
|
|
|
719
726
|
if (t.typ == 'Iden') {
|
|
720
727
|
// named color
|
|
721
728
|
const value = t.val.toLowerCase();
|
|
722
|
-
if (
|
|
729
|
+
if (value in COLORS_NAMES) {
|
|
723
730
|
Object.assign(t, {
|
|
724
731
|
typ: 'Color',
|
|
725
732
|
val: COLORS_NAMES[value].length < value.length ? COLORS_NAMES[value] : value,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isWhiteSpace, isDigit,
|
|
1
|
+
import { isWhiteSpace, isNewLine, isDigit, isNonPrintable } from './utils/syntax.js';
|
|
2
2
|
|
|
3
3
|
function* tokenize(iterator) {
|
|
4
4
|
let ind = -1;
|
|
@@ -55,23 +55,7 @@ function* tokenize(iterator) {
|
|
|
55
55
|
}
|
|
56
56
|
break;
|
|
57
57
|
}
|
|
58
|
-
|
|
59
|
-
if (isNewLine(codepoint)) {
|
|
60
|
-
if (i == 1) {
|
|
61
|
-
buffer += value + escapeSequence.slice(0, i);
|
|
62
|
-
next(i + 1);
|
|
63
|
-
continue;
|
|
64
|
-
}
|
|
65
|
-
// else {
|
|
66
|
-
yield pushToken(buffer + value + escapeSequence.slice(0, i), 'Bad-string');
|
|
67
|
-
buffer = '';
|
|
68
|
-
// }
|
|
69
|
-
next(i + 1);
|
|
70
|
-
break;
|
|
71
|
-
}
|
|
72
|
-
// not hex or new line
|
|
73
|
-
// @ts-ignore
|
|
74
|
-
else if (i == 1) {
|
|
58
|
+
if (i == 1) {
|
|
75
59
|
buffer += value + sequence[i];
|
|
76
60
|
next(2);
|
|
77
61
|
continue;
|
|
@@ -88,7 +72,7 @@ function* tokenize(iterator) {
|
|
|
88
72
|
else {
|
|
89
73
|
buffer += String.fromCodePoint(codepoint);
|
|
90
74
|
}
|
|
91
|
-
next(escapeSequence.length + 1);
|
|
75
|
+
next(escapeSequence.length + 1 + (isWhiteSpace(peek()?.charCodeAt(0)) ? 1 : 0));
|
|
92
76
|
continue;
|
|
93
77
|
}
|
|
94
78
|
buffer += next(2);
|
|
@@ -154,31 +138,18 @@ function* tokenize(iterator) {
|
|
|
154
138
|
return char;
|
|
155
139
|
}
|
|
156
140
|
while (value = next()) {
|
|
157
|
-
if (ind >= iterator.length) {
|
|
158
|
-
if (buffer.length > 0) {
|
|
159
|
-
yield pushToken(buffer);
|
|
160
|
-
buffer = '';
|
|
161
|
-
}
|
|
162
|
-
break;
|
|
163
|
-
}
|
|
164
141
|
if (isWhiteSpace(value.charCodeAt(0))) {
|
|
165
142
|
if (buffer.length > 0) {
|
|
166
143
|
yield pushToken(buffer);
|
|
167
144
|
buffer = '';
|
|
168
145
|
}
|
|
169
146
|
while (value = next()) {
|
|
170
|
-
if (ind >= iterator.length) {
|
|
171
|
-
break;
|
|
172
|
-
}
|
|
173
147
|
if (!isWhiteSpace(value.charCodeAt(0))) {
|
|
174
148
|
break;
|
|
175
149
|
}
|
|
176
150
|
}
|
|
177
151
|
yield pushToken('', 'Whitespace');
|
|
178
152
|
buffer = '';
|
|
179
|
-
if (ind >= iterator.length) {
|
|
180
|
-
break;
|
|
181
|
-
}
|
|
182
153
|
}
|
|
183
154
|
switch (value) {
|
|
184
155
|
case '/':
|
|
@@ -192,34 +163,12 @@ function* tokenize(iterator) {
|
|
|
192
163
|
}
|
|
193
164
|
buffer += value;
|
|
194
165
|
if (peek() == '*') {
|
|
195
|
-
buffer +=
|
|
196
|
-
// i++;
|
|
197
|
-
next();
|
|
166
|
+
buffer += next();
|
|
198
167
|
while (value = next()) {
|
|
199
|
-
if (ind >= iterator.length) {
|
|
200
|
-
yield pushToken(buffer, 'Bad-comment');
|
|
201
|
-
break;
|
|
202
|
-
}
|
|
203
|
-
if (value == '\\') {
|
|
204
|
-
buffer += value;
|
|
205
|
-
value = next();
|
|
206
|
-
if (ind >= iterator.length) {
|
|
207
|
-
yield pushToken(buffer, 'Bad-comment');
|
|
208
|
-
break;
|
|
209
|
-
}
|
|
210
|
-
buffer += value;
|
|
211
|
-
continue;
|
|
212
|
-
}
|
|
213
168
|
if (value == '*') {
|
|
214
169
|
buffer += value;
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
yield pushToken(buffer, 'Bad-comment');
|
|
218
|
-
break;
|
|
219
|
-
}
|
|
220
|
-
buffer += value;
|
|
221
|
-
if (value == '/') {
|
|
222
|
-
yield pushToken(buffer, 'Comment');
|
|
170
|
+
if (peek() == '/') {
|
|
171
|
+
yield pushToken(buffer + next(), 'Comment');
|
|
223
172
|
buffer = '';
|
|
224
173
|
break;
|
|
225
174
|
}
|
|
@@ -228,6 +177,8 @@ function* tokenize(iterator) {
|
|
|
228
177
|
buffer += value;
|
|
229
178
|
}
|
|
230
179
|
}
|
|
180
|
+
yield pushToken(buffer, 'Bad-comment');
|
|
181
|
+
buffer = '';
|
|
231
182
|
}
|
|
232
183
|
break;
|
|
233
184
|
case '<':
|
|
@@ -241,32 +192,26 @@ function* tokenize(iterator) {
|
|
|
241
192
|
break;
|
|
242
193
|
}
|
|
243
194
|
buffer += value;
|
|
244
|
-
value = next();
|
|
245
|
-
if (ind >= iterator.length) {
|
|
246
|
-
break;
|
|
247
|
-
}
|
|
248
195
|
if (peek(3) == '!--') {
|
|
196
|
+
buffer += next(3);
|
|
249
197
|
while (value = next()) {
|
|
250
|
-
if (ind >= iterator.length) {
|
|
251
|
-
break;
|
|
252
|
-
}
|
|
253
198
|
buffer += value;
|
|
254
|
-
if (value == '
|
|
255
|
-
yield pushToken(buffer, 'CDOCOMM');
|
|
256
|
-
buffer = '';
|
|
199
|
+
if (value == '-' && peek(2) == '->') {
|
|
257
200
|
break;
|
|
258
201
|
}
|
|
259
202
|
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
203
|
+
if (value === '') {
|
|
204
|
+
yield pushToken(buffer, 'Bad-cdo');
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
yield pushToken(buffer + next(2), 'CDOCOMM');
|
|
208
|
+
}
|
|
263
209
|
buffer = '';
|
|
264
210
|
}
|
|
265
211
|
break;
|
|
266
212
|
case '\\':
|
|
267
|
-
value = next();
|
|
268
213
|
// EOF
|
|
269
|
-
if (
|
|
214
|
+
if (!(value = next())) {
|
|
270
215
|
// end of stream ignore \\
|
|
271
216
|
yield pushToken(buffer);
|
|
272
217
|
buffer = '';
|
|
@@ -285,8 +230,7 @@ function* tokenize(iterator) {
|
|
|
285
230
|
buffer = '';
|
|
286
231
|
}
|
|
287
232
|
buffer += value;
|
|
288
|
-
value = next()
|
|
289
|
-
if (ind >= iterator.length) {
|
|
233
|
+
if (!(value = next())) {
|
|
290
234
|
yield pushToken(buffer);
|
|
291
235
|
buffer = '';
|
|
292
236
|
break;
|
|
@@ -364,73 +308,150 @@ function* tokenize(iterator) {
|
|
|
364
308
|
if (buffer == 'url(') {
|
|
365
309
|
yield pushToken(buffer);
|
|
366
310
|
buffer = '';
|
|
367
|
-
|
|
368
|
-
let whitespace = '';
|
|
369
|
-
value = peek();
|
|
370
|
-
while (isWhiteSpace(value.charCodeAt(0))) {
|
|
371
|
-
whitespace += value;
|
|
372
|
-
}
|
|
373
|
-
if (whitespace.length > 0) {
|
|
374
|
-
next(whitespace.length);
|
|
375
|
-
}
|
|
311
|
+
consumeWhiteSpace();
|
|
376
312
|
value = peek();
|
|
313
|
+
let cp;
|
|
314
|
+
let whitespace = '';
|
|
315
|
+
let hasWhiteSpace = false;
|
|
316
|
+
let errorState = false;
|
|
377
317
|
if (value == '"' || value == "'") {
|
|
378
|
-
|
|
318
|
+
const quote = value;
|
|
319
|
+
let inquote = true;
|
|
320
|
+
let hasNewLine = false;
|
|
321
|
+
buffer = next();
|
|
322
|
+
while (value = next()) {
|
|
323
|
+
cp = value.charCodeAt(0);
|
|
324
|
+
// consume an invalid string
|
|
325
|
+
if (inquote) {
|
|
326
|
+
buffer += value;
|
|
327
|
+
if (isNewLine(cp)) {
|
|
328
|
+
hasNewLine = true;
|
|
329
|
+
while (value = next()) {
|
|
330
|
+
buffer += value;
|
|
331
|
+
if (value == ';') {
|
|
332
|
+
inquote = false;
|
|
333
|
+
break;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
if (value === '') {
|
|
337
|
+
yield pushToken(buffer, 'Bad-string');
|
|
338
|
+
buffer = '';
|
|
339
|
+
break;
|
|
340
|
+
}
|
|
341
|
+
cp = value.charCodeAt(0);
|
|
342
|
+
}
|
|
343
|
+
// '\\'
|
|
344
|
+
if (cp == 0x5c) {
|
|
345
|
+
buffer += next();
|
|
346
|
+
}
|
|
347
|
+
else if (value == quote) {
|
|
348
|
+
inquote = false;
|
|
349
|
+
}
|
|
350
|
+
continue;
|
|
351
|
+
}
|
|
352
|
+
if (!inquote) {
|
|
353
|
+
if (isWhiteSpace(cp)) {
|
|
354
|
+
whitespace += value;
|
|
355
|
+
while (value = peek()) {
|
|
356
|
+
hasWhiteSpace = true;
|
|
357
|
+
if (isWhiteSpace(value?.charCodeAt(0))) {
|
|
358
|
+
whitespace += next();
|
|
359
|
+
continue;
|
|
360
|
+
}
|
|
361
|
+
break;
|
|
362
|
+
}
|
|
363
|
+
if (!(value = next())) {
|
|
364
|
+
yield pushToken(buffer, hasNewLine ? 'Bad-url-token' : 'Url-token');
|
|
365
|
+
buffer = '';
|
|
366
|
+
break;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
cp = value.charCodeAt(0);
|
|
370
|
+
// ')'
|
|
371
|
+
if (cp == 0x29) {
|
|
372
|
+
yield pushToken(buffer, hasNewLine ? 'Bad-string' : 'String');
|
|
373
|
+
yield pushToken('', 'End-parens');
|
|
374
|
+
buffer = '';
|
|
375
|
+
break;
|
|
376
|
+
}
|
|
377
|
+
while (value = next()) {
|
|
378
|
+
cp = value.charCodeAt(0);
|
|
379
|
+
if (cp == 0x5c) {
|
|
380
|
+
buffer += value + next();
|
|
381
|
+
continue;
|
|
382
|
+
}
|
|
383
|
+
if (cp == 0x29) {
|
|
384
|
+
yield pushToken(buffer, 'Bad-string');
|
|
385
|
+
yield pushToken('', 'End-parens');
|
|
386
|
+
buffer = '';
|
|
387
|
+
break;
|
|
388
|
+
}
|
|
389
|
+
buffer += value;
|
|
390
|
+
}
|
|
391
|
+
if (hasNewLine) {
|
|
392
|
+
yield pushToken(buffer, 'Bad-string');
|
|
393
|
+
buffer = '';
|
|
394
|
+
}
|
|
395
|
+
break;
|
|
396
|
+
}
|
|
397
|
+
buffer += value;
|
|
398
|
+
}
|
|
379
399
|
break;
|
|
380
400
|
}
|
|
381
401
|
else {
|
|
382
402
|
buffer = '';
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
// EOF -
|
|
386
|
-
if (cp == null) {
|
|
387
|
-
yield pushToken('', 'Bad-url-token');
|
|
388
|
-
break;
|
|
389
|
-
}
|
|
403
|
+
while (value = next()) {
|
|
404
|
+
cp = value.charCodeAt(0);
|
|
390
405
|
// ')'
|
|
391
|
-
if (cp == 0x29
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
else {
|
|
396
|
-
yield pushToken(buffer, 'Url-token');
|
|
397
|
-
}
|
|
398
|
-
if (cp != null) {
|
|
399
|
-
yield pushToken(next());
|
|
400
|
-
}
|
|
406
|
+
if (cp == 0x29) {
|
|
407
|
+
yield pushToken(buffer, 'Url-token');
|
|
408
|
+
yield pushToken('', 'End-parens');
|
|
409
|
+
buffer = '';
|
|
401
410
|
break;
|
|
402
411
|
}
|
|
403
412
|
if (isWhiteSpace(cp)) {
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
413
|
+
hasWhiteSpace = true;
|
|
414
|
+
whitespace = value;
|
|
415
|
+
while (isWhiteSpace(peek()?.charCodeAt(0))) {
|
|
416
|
+
whitespace += next();
|
|
417
|
+
}
|
|
418
|
+
continue;
|
|
419
|
+
}
|
|
420
|
+
if (isNonPrintable(cp) ||
|
|
421
|
+
// '"'
|
|
422
|
+
cp == 0x22 ||
|
|
423
|
+
// "'"
|
|
424
|
+
cp == 0x27 ||
|
|
425
|
+
// \('
|
|
426
|
+
cp == 0x28 ||
|
|
427
|
+
hasWhiteSpace) {
|
|
428
|
+
errorState = true;
|
|
429
|
+
}
|
|
430
|
+
if (errorState) {
|
|
431
|
+
buffer += whitespace + value;
|
|
432
|
+
while (value = peek()) {
|
|
407
433
|
cp = value.charCodeAt(0);
|
|
408
|
-
if (
|
|
409
|
-
|
|
434
|
+
if (cp == 0x5c) {
|
|
435
|
+
buffer += next(2);
|
|
410
436
|
continue;
|
|
411
437
|
}
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
if (cp == null || cp == 0x29) {
|
|
415
|
-
continue;
|
|
416
|
-
}
|
|
417
|
-
// bad url token
|
|
418
|
-
buffer += next(whitespace.length);
|
|
419
|
-
do {
|
|
420
|
-
value = peek();
|
|
421
|
-
cp = value.charCodeAt(0);
|
|
422
|
-
if (cp == null || cp == 0x29) {
|
|
438
|
+
// ')'
|
|
439
|
+
if (cp == 0x29) {
|
|
423
440
|
break;
|
|
424
441
|
}
|
|
425
442
|
buffer += next();
|
|
426
|
-
}
|
|
443
|
+
}
|
|
427
444
|
yield pushToken(buffer, 'Bad-url-token');
|
|
428
|
-
|
|
445
|
+
buffer = '';
|
|
446
|
+
break;
|
|
429
447
|
}
|
|
430
|
-
buffer +=
|
|
431
|
-
|
|
432
|
-
|
|
448
|
+
buffer += value;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
if (buffer !== '') {
|
|
452
|
+
yield pushToken(buffer, 'Url-token');
|
|
433
453
|
buffer = '';
|
|
454
|
+
break;
|
|
434
455
|
}
|
|
435
456
|
break;
|
|
436
457
|
}
|
|
@@ -453,8 +474,7 @@ function* tokenize(iterator) {
|
|
|
453
474
|
yield pushToken(buffer);
|
|
454
475
|
buffer = '';
|
|
455
476
|
}
|
|
456
|
-
|
|
457
|
-
if (important == 'important') {
|
|
477
|
+
if (peek(9) == 'important') {
|
|
458
478
|
yield pushToken('', 'Important');
|
|
459
479
|
next(9);
|
|
460
480
|
buffer = '';
|