@tbela99/css-parser 0.0.1-rc5 → 0.0.1-rc7
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 +2527 -2199
- package/dist/index.cjs +2527 -2199
- package/dist/index.d.ts +36 -26
- package/dist/lib/ast/expand.js +159 -0
- package/dist/lib/ast/minify.js +139 -95
- package/dist/lib/ast/walk.js +12 -7
- package/dist/lib/parser/declaration/list.js +1 -1
- package/dist/lib/parser/declaration/map.js +8 -0
- package/dist/lib/parser/parse.js +38 -24
- package/dist/lib/parser/tokenize.js +142 -76
- package/dist/lib/parser/utils/syntax.js +10 -17
- package/dist/lib/renderer/render.js +18 -25
- package/dist/lib/transform.js +4 -1
- package/dist/node/index.js +5 -4
- package/dist/web/index.js +5 -4
- package/package.json +1 -1
package/dist/lib/ast/walk.js
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
|
-
function* walk(node) {
|
|
2
|
-
// @ts-ignore
|
|
3
|
-
yield* doWalk(node, null, null);
|
|
4
|
-
}
|
|
5
|
-
function* doWalk(node, parent, root) {
|
|
1
|
+
function* walk(node, parent, root) {
|
|
6
2
|
yield { node, parent, root };
|
|
7
3
|
if ('chi' in node) {
|
|
8
4
|
for (const child of node.chi) {
|
|
9
|
-
yield*
|
|
5
|
+
yield* walk(child, node, (root ?? node));
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
function* walkValues(values, parent) {
|
|
10
|
+
for (const value of values) {
|
|
11
|
+
// @ts-ignore
|
|
12
|
+
yield { value, parent };
|
|
13
|
+
if ('chi' in value) {
|
|
14
|
+
yield* walkValues(value.chi, value);
|
|
10
15
|
}
|
|
11
16
|
}
|
|
12
17
|
}
|
|
13
18
|
|
|
14
|
-
export { walk };
|
|
19
|
+
export { walk, walkValues };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { PropertySet } from './set.js';
|
|
2
2
|
import '../../renderer/utils/color.js';
|
|
3
|
-
import { getConfig } from '../utils/config.js';
|
|
4
3
|
import { PropertyMap } from './map.js';
|
|
5
4
|
import { parseString } from '../parse.js';
|
|
5
|
+
import { getConfig } from '../utils/config.js';
|
|
6
6
|
|
|
7
7
|
const config = getConfig();
|
|
8
8
|
class PropertyList {
|
|
@@ -340,6 +340,14 @@ class PropertyMap {
|
|
|
340
340
|
acc.push(...curr);
|
|
341
341
|
return acc;
|
|
342
342
|
}, []);
|
|
343
|
+
if (this.config.mapping != null) {
|
|
344
|
+
const val = values.reduce((acc, curr) => acc + renderToken(curr, { removeComments: true }), '');
|
|
345
|
+
if (val in this.config.mapping) {
|
|
346
|
+
values.length = 0;
|
|
347
|
+
// @ts-ignore
|
|
348
|
+
values.push({ typ: ['"', "'"].includes(val.charAt(0)) ? 'String' : 'Iden', val: this.config.mapping[val] });
|
|
349
|
+
}
|
|
350
|
+
}
|
|
343
351
|
iterable = [{
|
|
344
352
|
typ: 'Declaration',
|
|
345
353
|
nam: this.config.shorthand,
|
package/dist/lib/parser/parse.js
CHANGED
|
@@ -53,14 +53,18 @@ async function parse(iterator, opt = {}) {
|
|
|
53
53
|
let i;
|
|
54
54
|
let loc;
|
|
55
55
|
for (i = 0; i < tokens.length; i++) {
|
|
56
|
-
if (tokens[i].typ == 'Comment') {
|
|
57
|
-
// @ts-ignore
|
|
58
|
-
context.chi.push(tokens[i]);
|
|
56
|
+
if (tokens[i].typ == 'Comment' || tokens[i].typ == 'CDOCOMM') {
|
|
59
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
|
+
}
|
|
60
62
|
loc = {
|
|
61
63
|
sta: position,
|
|
62
64
|
src
|
|
63
65
|
};
|
|
66
|
+
// @ts-ignore
|
|
67
|
+
context.chi.push(tokens[i]);
|
|
64
68
|
if (options.sourcemap) {
|
|
65
69
|
tokens[i].loc = loc;
|
|
66
70
|
}
|
|
@@ -91,7 +95,7 @@ async function parse(iterator, opt = {}) {
|
|
|
91
95
|
const atRule = tokens.shift();
|
|
92
96
|
const position = map.get(atRule);
|
|
93
97
|
if (atRule.val == 'charset' && position.ind > 0) {
|
|
94
|
-
errors.push({ action: 'drop', message: 'invalid @charset', location: { src, ...position } });
|
|
98
|
+
errors.push({ action: 'drop', message: 'parse: invalid @charset', location: { src, ...position } });
|
|
95
99
|
return null;
|
|
96
100
|
}
|
|
97
101
|
// @ts-ignore
|
|
@@ -121,12 +125,12 @@ async function parse(iterator, opt = {}) {
|
|
|
121
125
|
}
|
|
122
126
|
// @ts-ignore
|
|
123
127
|
if (tokens[0]?.typ != 'String' && tokens[0]?.typ != 'UrlFunc') {
|
|
124
|
-
errors.push({ action: 'drop', message: 'invalid @import', location: { src, ...position } });
|
|
128
|
+
errors.push({ action: 'drop', message: 'parse: invalid @import', location: { src, ...position } });
|
|
125
129
|
return null;
|
|
126
130
|
}
|
|
127
131
|
// @ts-ignore
|
|
128
132
|
if (tokens[0].typ == 'UrlFunc' && tokens[1]?.typ != 'Url-token' && tokens[1]?.typ != 'String') {
|
|
129
|
-
errors.push({ action: 'drop', message: 'invalid @import', location: { src, ...position } });
|
|
133
|
+
errors.push({ action: 'drop', message: 'parse: invalid @import', location: { src, ...position } });
|
|
130
134
|
return null;
|
|
131
135
|
}
|
|
132
136
|
}
|
|
@@ -162,7 +166,8 @@ async function parse(iterator, opt = {}) {
|
|
|
162
166
|
return null;
|
|
163
167
|
}
|
|
164
168
|
catch (error) {
|
|
165
|
-
|
|
169
|
+
// @ts-ignore
|
|
170
|
+
errors.push({ action: 'ignore', message: 'parse: ' + error.message, error });
|
|
166
171
|
}
|
|
167
172
|
}
|
|
168
173
|
}
|
|
@@ -179,7 +184,7 @@ async function parse(iterator, opt = {}) {
|
|
|
179
184
|
nam: renderToken(atRule, { removeComments: true }),
|
|
180
185
|
val: raw.join('')
|
|
181
186
|
};
|
|
182
|
-
Object.defineProperty(node, 'raw', { enumerable: false, writable:
|
|
187
|
+
Object.defineProperty(node, 'raw', { enumerable: false, configurable: true, writable: true, value: raw });
|
|
183
188
|
if (delim.typ == 'Block-start') {
|
|
184
189
|
node.chi = [];
|
|
185
190
|
}
|
|
@@ -199,7 +204,7 @@ async function parse(iterator, opt = {}) {
|
|
|
199
204
|
if (delim.typ == 'Block-start') {
|
|
200
205
|
const position = map.get(tokens[0]);
|
|
201
206
|
const uniq = new Map;
|
|
202
|
-
parseTokens(tokens, { minify:
|
|
207
|
+
parseTokens(tokens, { minify: true }).reduce((acc, curr, index, array) => {
|
|
203
208
|
if (curr.typ == 'Whitespace') {
|
|
204
209
|
if (trimWhiteSpace.includes(array[index - 1]?.typ) ||
|
|
205
210
|
trimWhiteSpace.includes(array[index + 1]?.typ) ||
|
|
@@ -208,7 +213,7 @@ async function parse(iterator, opt = {}) {
|
|
|
208
213
|
return acc;
|
|
209
214
|
}
|
|
210
215
|
}
|
|
211
|
-
let t = renderToken(curr, { minify:
|
|
216
|
+
let t = renderToken(curr, { minify: false });
|
|
212
217
|
if (t == ',') {
|
|
213
218
|
acc.push([]);
|
|
214
219
|
}
|
|
@@ -227,7 +232,7 @@ async function parse(iterator, opt = {}) {
|
|
|
227
232
|
chi: []
|
|
228
233
|
};
|
|
229
234
|
let raw = [...uniq.values()];
|
|
230
|
-
Object.defineProperty(node, 'raw', { enumerable: false, writable: true, value: raw });
|
|
235
|
+
Object.defineProperty(node, 'raw', { enumerable: false, configurable: true, writable: true, value: raw });
|
|
231
236
|
loc = {
|
|
232
237
|
sta: position,
|
|
233
238
|
src
|
|
@@ -269,7 +274,7 @@ async function parse(iterator, opt = {}) {
|
|
|
269
274
|
if (name[i].typ != 'Whitespace' && name[i].typ != 'Comment') {
|
|
270
275
|
errors.push({
|
|
271
276
|
action: 'drop',
|
|
272
|
-
message: 'invalid declaration',
|
|
277
|
+
message: 'parse: invalid declaration',
|
|
273
278
|
location: { src, ...position }
|
|
274
279
|
});
|
|
275
280
|
return null;
|
|
@@ -279,7 +284,7 @@ async function parse(iterator, opt = {}) {
|
|
|
279
284
|
if (value == null) {
|
|
280
285
|
errors.push({
|
|
281
286
|
action: 'drop',
|
|
282
|
-
message: 'invalid declaration',
|
|
287
|
+
message: 'parse: invalid declaration',
|
|
283
288
|
location: { src, ...position }
|
|
284
289
|
});
|
|
285
290
|
return null;
|
|
@@ -287,7 +292,7 @@ async function parse(iterator, opt = {}) {
|
|
|
287
292
|
if (value.length == 0) {
|
|
288
293
|
errors.push({
|
|
289
294
|
action: 'drop',
|
|
290
|
-
message: 'invalid declaration',
|
|
295
|
+
message: 'parse: invalid declaration',
|
|
291
296
|
location: { src, ...position }
|
|
292
297
|
});
|
|
293
298
|
return null;
|
|
@@ -305,7 +310,7 @@ async function parse(iterator, opt = {}) {
|
|
|
305
310
|
if (node.val.length == 0) {
|
|
306
311
|
errors.push({
|
|
307
312
|
action: 'drop',
|
|
308
|
-
message: 'invalid declaration',
|
|
313
|
+
message: 'parse: invalid declaration',
|
|
309
314
|
location: { src, ...position }
|
|
310
315
|
});
|
|
311
316
|
return null;
|
|
@@ -323,18 +328,14 @@ async function parse(iterator, opt = {}) {
|
|
|
323
328
|
}
|
|
324
329
|
const iter = tokenize(iterator);
|
|
325
330
|
let item;
|
|
326
|
-
while (
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
break;
|
|
330
|
-
}
|
|
331
|
-
// console.debug({item});
|
|
331
|
+
while (item = iter.next().value) {
|
|
332
|
+
bytesIn = item.bytesIn;
|
|
333
|
+
// parse error
|
|
332
334
|
if (item.hint != null && item.hint.startsWith('Bad-')) {
|
|
333
335
|
// bad token
|
|
334
336
|
continue;
|
|
335
337
|
}
|
|
336
338
|
tokens.push(item);
|
|
337
|
-
bytesIn = item.bytesIn;
|
|
338
339
|
if (item.token == ';' || item.token == '{') {
|
|
339
340
|
let node = await parseNode(tokens);
|
|
340
341
|
if (node != null) {
|
|
@@ -378,15 +379,28 @@ async function parse(iterator, opt = {}) {
|
|
|
378
379
|
if (tokens.length > 0) {
|
|
379
380
|
await parseNode(tokens);
|
|
380
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
|
+
}
|
|
381
393
|
const endParseTime = performance.now();
|
|
382
394
|
if (options.minify) {
|
|
383
395
|
if (ast.chi.length > 0) {
|
|
384
|
-
minify(ast, options, true);
|
|
396
|
+
minify(ast, options, true, errors);
|
|
385
397
|
}
|
|
386
398
|
}
|
|
387
399
|
const endTime = performance.now();
|
|
388
400
|
return {
|
|
389
|
-
ast,
|
|
401
|
+
ast,
|
|
402
|
+
errors,
|
|
403
|
+
stats: {
|
|
390
404
|
bytesIn,
|
|
391
405
|
parse: `${(endParseTime - startTime).toFixed(2)}ms`,
|
|
392
406
|
minify: `${(endTime - endParseTime).toFixed(2)}ms`,
|
|
@@ -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);
|
|
@@ -137,12 +121,16 @@ function* tokenize(iterator) {
|
|
|
137
121
|
}
|
|
138
122
|
function next(count = 1) {
|
|
139
123
|
let char = '';
|
|
140
|
-
|
|
124
|
+
let chr = '';
|
|
125
|
+
if (count < 0) {
|
|
126
|
+
return '';
|
|
127
|
+
}
|
|
128
|
+
while (count-- && (chr = iterator.charAt(ind + 1))) {
|
|
129
|
+
char += chr;
|
|
141
130
|
const codepoint = iterator.charCodeAt(++ind);
|
|
142
131
|
if (isNaN(codepoint)) {
|
|
143
132
|
return char;
|
|
144
133
|
}
|
|
145
|
-
char += iterator.charAt(ind);
|
|
146
134
|
if (isNewLine(codepoint)) {
|
|
147
135
|
lin++;
|
|
148
136
|
col = 0;
|
|
@@ -212,17 +200,18 @@ function* tokenize(iterator) {
|
|
|
212
200
|
buffer += next(3);
|
|
213
201
|
while (value = next()) {
|
|
214
202
|
buffer += value;
|
|
215
|
-
if (value == '
|
|
216
|
-
yield pushToken(buffer, 'CDOCOMM');
|
|
217
|
-
buffer = '';
|
|
203
|
+
if (value == '-' && peek(2) == '->') {
|
|
218
204
|
break;
|
|
219
205
|
}
|
|
220
206
|
}
|
|
207
|
+
if (value === '') {
|
|
208
|
+
yield pushToken(buffer, 'Bad-cdo');
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
yield pushToken(buffer + next(2), 'CDOCOMM');
|
|
212
|
+
}
|
|
213
|
+
buffer = '';
|
|
221
214
|
}
|
|
222
|
-
// if (!peek()) {
|
|
223
|
-
yield pushToken(buffer, 'Bad-cdo');
|
|
224
|
-
buffer = '';
|
|
225
|
-
// }
|
|
226
215
|
break;
|
|
227
216
|
case '\\':
|
|
228
217
|
// EOF
|
|
@@ -323,73 +312,150 @@ function* tokenize(iterator) {
|
|
|
323
312
|
if (buffer == 'url(') {
|
|
324
313
|
yield pushToken(buffer);
|
|
325
314
|
buffer = '';
|
|
326
|
-
|
|
327
|
-
let whitespace = '';
|
|
328
|
-
value = peek();
|
|
329
|
-
while (isWhiteSpace(value.charCodeAt(0))) {
|
|
330
|
-
whitespace += value;
|
|
331
|
-
}
|
|
332
|
-
if (whitespace.length > 0) {
|
|
333
|
-
next(whitespace.length);
|
|
334
|
-
}
|
|
315
|
+
consumeWhiteSpace();
|
|
335
316
|
value = peek();
|
|
317
|
+
let cp;
|
|
318
|
+
let whitespace = '';
|
|
319
|
+
let hasWhiteSpace = false;
|
|
320
|
+
let errorState = false;
|
|
336
321
|
if (value == '"' || value == "'") {
|
|
337
|
-
|
|
322
|
+
const quote = value;
|
|
323
|
+
let inquote = true;
|
|
324
|
+
let hasNewLine = false;
|
|
325
|
+
buffer = next();
|
|
326
|
+
while (value = next()) {
|
|
327
|
+
cp = value.charCodeAt(0);
|
|
328
|
+
// consume an invalid string
|
|
329
|
+
if (inquote) {
|
|
330
|
+
buffer += value;
|
|
331
|
+
if (isNewLine(cp)) {
|
|
332
|
+
hasNewLine = true;
|
|
333
|
+
while (value = next()) {
|
|
334
|
+
buffer += value;
|
|
335
|
+
if (value == ';') {
|
|
336
|
+
inquote = false;
|
|
337
|
+
break;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
if (value === '') {
|
|
341
|
+
yield pushToken(buffer, 'Bad-string');
|
|
342
|
+
buffer = '';
|
|
343
|
+
break;
|
|
344
|
+
}
|
|
345
|
+
cp = value.charCodeAt(0);
|
|
346
|
+
}
|
|
347
|
+
// '\\'
|
|
348
|
+
if (cp == 0x5c) {
|
|
349
|
+
buffer += next();
|
|
350
|
+
}
|
|
351
|
+
else if (value == quote) {
|
|
352
|
+
inquote = false;
|
|
353
|
+
}
|
|
354
|
+
continue;
|
|
355
|
+
}
|
|
356
|
+
if (!inquote) {
|
|
357
|
+
if (isWhiteSpace(cp)) {
|
|
358
|
+
whitespace += value;
|
|
359
|
+
while (value = peek()) {
|
|
360
|
+
hasWhiteSpace = true;
|
|
361
|
+
if (isWhiteSpace(value?.charCodeAt(0))) {
|
|
362
|
+
whitespace += next();
|
|
363
|
+
continue;
|
|
364
|
+
}
|
|
365
|
+
break;
|
|
366
|
+
}
|
|
367
|
+
if (!(value = next())) {
|
|
368
|
+
yield pushToken(buffer, hasNewLine ? 'Bad-url-token' : 'Url-token');
|
|
369
|
+
buffer = '';
|
|
370
|
+
break;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
cp = value.charCodeAt(0);
|
|
374
|
+
// ')'
|
|
375
|
+
if (cp == 0x29) {
|
|
376
|
+
yield pushToken(buffer, hasNewLine ? 'Bad-string' : 'String');
|
|
377
|
+
yield pushToken('', 'End-parens');
|
|
378
|
+
buffer = '';
|
|
379
|
+
break;
|
|
380
|
+
}
|
|
381
|
+
while (value = next()) {
|
|
382
|
+
cp = value.charCodeAt(0);
|
|
383
|
+
if (cp == 0x5c) {
|
|
384
|
+
buffer += value + next();
|
|
385
|
+
continue;
|
|
386
|
+
}
|
|
387
|
+
if (cp == 0x29) {
|
|
388
|
+
yield pushToken(buffer, 'Bad-string');
|
|
389
|
+
yield pushToken('', 'End-parens');
|
|
390
|
+
buffer = '';
|
|
391
|
+
break;
|
|
392
|
+
}
|
|
393
|
+
buffer += value;
|
|
394
|
+
}
|
|
395
|
+
if (hasNewLine) {
|
|
396
|
+
yield pushToken(buffer, 'Bad-string');
|
|
397
|
+
buffer = '';
|
|
398
|
+
}
|
|
399
|
+
break;
|
|
400
|
+
}
|
|
401
|
+
buffer += value;
|
|
402
|
+
}
|
|
338
403
|
break;
|
|
339
404
|
}
|
|
340
405
|
else {
|
|
341
406
|
buffer = '';
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
// EOF -
|
|
345
|
-
if (cp == null) {
|
|
346
|
-
yield pushToken('', 'Bad-url-token');
|
|
347
|
-
break;
|
|
348
|
-
}
|
|
407
|
+
while (value = next()) {
|
|
408
|
+
cp = value.charCodeAt(0);
|
|
349
409
|
// ')'
|
|
350
|
-
if (cp == 0x29
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
else {
|
|
355
|
-
yield pushToken(buffer, 'Url-token');
|
|
356
|
-
}
|
|
357
|
-
if (cp != null) {
|
|
358
|
-
yield pushToken(next());
|
|
359
|
-
}
|
|
410
|
+
if (cp == 0x29) {
|
|
411
|
+
yield pushToken(buffer, 'Url-token');
|
|
412
|
+
yield pushToken('', 'End-parens');
|
|
413
|
+
buffer = '';
|
|
360
414
|
break;
|
|
361
415
|
}
|
|
362
416
|
if (isWhiteSpace(cp)) {
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
417
|
+
hasWhiteSpace = true;
|
|
418
|
+
whitespace = value;
|
|
419
|
+
while (isWhiteSpace(peek()?.charCodeAt(0))) {
|
|
420
|
+
whitespace += next();
|
|
421
|
+
}
|
|
422
|
+
continue;
|
|
423
|
+
}
|
|
424
|
+
if (isNonPrintable(cp) ||
|
|
425
|
+
// '"'
|
|
426
|
+
cp == 0x22 ||
|
|
427
|
+
// "'"
|
|
428
|
+
cp == 0x27 ||
|
|
429
|
+
// \('
|
|
430
|
+
cp == 0x28 ||
|
|
431
|
+
hasWhiteSpace) {
|
|
432
|
+
errorState = true;
|
|
433
|
+
}
|
|
434
|
+
if (errorState) {
|
|
435
|
+
buffer += whitespace + value;
|
|
436
|
+
while (value = peek()) {
|
|
366
437
|
cp = value.charCodeAt(0);
|
|
367
|
-
if (
|
|
368
|
-
|
|
438
|
+
if (cp == 0x5c) {
|
|
439
|
+
buffer += next(2);
|
|
369
440
|
continue;
|
|
370
441
|
}
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
if (cp == null || cp == 0x29) {
|
|
374
|
-
continue;
|
|
375
|
-
}
|
|
376
|
-
// bad url token
|
|
377
|
-
buffer += next(whitespace.length);
|
|
378
|
-
do {
|
|
379
|
-
value = peek();
|
|
380
|
-
cp = value.charCodeAt(0);
|
|
381
|
-
if (cp == null || cp == 0x29) {
|
|
442
|
+
// ')'
|
|
443
|
+
if (cp == 0x29) {
|
|
382
444
|
break;
|
|
383
445
|
}
|
|
384
446
|
buffer += next();
|
|
385
|
-
}
|
|
447
|
+
}
|
|
386
448
|
yield pushToken(buffer, 'Bad-url-token');
|
|
387
|
-
|
|
449
|
+
buffer = '';
|
|
450
|
+
break;
|
|
388
451
|
}
|
|
389
|
-
buffer +=
|
|
390
|
-
|
|
391
|
-
|
|
452
|
+
buffer += value;
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
if (buffer !== '') {
|
|
456
|
+
yield pushToken(buffer, 'Url-token');
|
|
392
457
|
buffer = '';
|
|
458
|
+
break;
|
|
393
459
|
}
|
|
394
460
|
break;
|
|
395
461
|
}
|
|
@@ -96,6 +96,15 @@ function isIdent(name) {
|
|
|
96
96
|
}
|
|
97
97
|
return true;
|
|
98
98
|
}
|
|
99
|
+
function isNonPrintable(codepoint) {
|
|
100
|
+
// null -> backspace
|
|
101
|
+
return (codepoint >= 0 && codepoint <= 0x8) ||
|
|
102
|
+
// tab
|
|
103
|
+
codepoint == 0xb ||
|
|
104
|
+
// delete
|
|
105
|
+
codepoint == 0x7f ||
|
|
106
|
+
(codepoint >= 0xe && codepoint <= 0x1f);
|
|
107
|
+
}
|
|
99
108
|
function isPseudo(name) {
|
|
100
109
|
return name.charAt(0) == ':' &&
|
|
101
110
|
((name.endsWith('(') && isIdent(name.charAt(1) == ':' ? name.slice(2, -1) : name.slice(1, -1))) ||
|
|
@@ -239,22 +248,6 @@ function isHexColor(name) {
|
|
|
239
248
|
}
|
|
240
249
|
return true;
|
|
241
250
|
}
|
|
242
|
-
function isHexDigit(name) {
|
|
243
|
-
if (name.length || name.length > 6) {
|
|
244
|
-
return false;
|
|
245
|
-
}
|
|
246
|
-
for (let chr of name) {
|
|
247
|
-
let codepoint = chr.charCodeAt(0);
|
|
248
|
-
if (!isDigit(codepoint) &&
|
|
249
|
-
// A F
|
|
250
|
-
!(codepoint >= 0x41 && codepoint <= 0x46) &&
|
|
251
|
-
// a f
|
|
252
|
-
!(codepoint >= 0x61 && codepoint <= 0x66)) {
|
|
253
|
-
return false;
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
return true;
|
|
257
|
-
}
|
|
258
251
|
function isFunction(name) {
|
|
259
252
|
return name.endsWith('(') && isIdent(name.slice(0, -1));
|
|
260
253
|
}
|
|
@@ -271,4 +264,4 @@ function isWhiteSpace(codepoint) {
|
|
|
271
264
|
codepoint == 0xa || codepoint == 0xc || codepoint == 0xd;
|
|
272
265
|
}
|
|
273
266
|
|
|
274
|
-
export { isAngle, isAtKeyword, isColor, isDigit, isDimension, isFrequency, isFunction, isHash, isHexColor,
|
|
267
|
+
export { isAngle, isAtKeyword, isColor, isDigit, isDimension, isFrequency, isFunction, isHash, isHexColor, isIdent, isIdentCodepoint, isIdentStart, isLength, isNewLine, isNonPrintable, isNumber, isPercentage, isPseudo, isResolution, isTime, isWhiteSpace, parseDimension };
|