@tbela99/css-parser 0.0.1-rc3 → 0.0.1-rc5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index-umd-web.js +1652 -1586
- package/dist/index.cjs +1652 -1586
- package/dist/index.d.ts +15 -4
- package/dist/lib/ast/minify.js +11 -0
- package/dist/lib/parser/declaration/list.js +1 -0
- package/dist/lib/parser/declaration/map.js +9 -4
- package/dist/lib/parser/parse.js +36 -37
- package/dist/lib/parser/tokenize.js +52 -72
- package/dist/lib/parser/utils/syntax.js +42 -34
- package/dist/lib/parser/utils/type.js +1 -1
- package/dist/lib/renderer/render.js +102 -38
- package/dist/lib/renderer/utils/color.js +2 -2
- package/dist/lib/transform.js +1 -0
- package/dist/node/index.js +9 -3
- package/dist/web/index.js +5 -5
- package/package.json +8 -7
- package/dist/index.js +0 -11
package/dist/index.d.ts
CHANGED
|
@@ -91,12 +91,14 @@ interface BlockEndToken {
|
|
|
91
91
|
}
|
|
92
92
|
interface AttrStartToken {
|
|
93
93
|
typ: 'Attr-start';
|
|
94
|
+
chi?: Token[];
|
|
94
95
|
}
|
|
95
96
|
interface AttrEndToken {
|
|
96
97
|
typ: 'Attr-end';
|
|
97
98
|
}
|
|
98
99
|
interface ParensStartToken {
|
|
99
100
|
typ: 'Start-parens';
|
|
101
|
+
chi?: Token[];
|
|
100
102
|
}
|
|
101
103
|
interface ParensEndToken {
|
|
102
104
|
typ: 'End-parens';
|
|
@@ -117,7 +119,7 @@ interface CDOCommentToken {
|
|
|
117
119
|
val: string;
|
|
118
120
|
}
|
|
119
121
|
interface BadCDOCommentToken {
|
|
120
|
-
typ: '
|
|
122
|
+
typ: 'Bad-cdo';
|
|
121
123
|
val: string;
|
|
122
124
|
}
|
|
123
125
|
interface IncludesToken {
|
|
@@ -131,9 +133,15 @@ interface DashMatchToken {
|
|
|
131
133
|
interface LessThanToken {
|
|
132
134
|
typ: 'Lt';
|
|
133
135
|
}
|
|
136
|
+
interface LessThanOrEqualToken {
|
|
137
|
+
typ: 'Lte';
|
|
138
|
+
}
|
|
134
139
|
interface GreaterThanToken {
|
|
135
140
|
typ: 'Gt';
|
|
136
141
|
}
|
|
142
|
+
interface GreaterThanOrEqualToken {
|
|
143
|
+
typ: 'Gte';
|
|
144
|
+
}
|
|
137
145
|
interface PseudoClassToken {
|
|
138
146
|
typ: 'Pseudo-class';
|
|
139
147
|
val: string;
|
|
@@ -171,7 +179,7 @@ interface AttrToken {
|
|
|
171
179
|
typ: 'Attr';
|
|
172
180
|
chi: Token[];
|
|
173
181
|
}
|
|
174
|
-
declare type Token = LiteralToken | IdentToken | CommaToken | ColonToken | SemiColonToken | NumberToken | AtRuleToken | PercentageToken | FunctionURLToken | FunctionToken | DimensionToken | LengthToken | AngleToken | StringToken | TimeToken | FrequencyToken | ResolutionToken | UnclosedStringToken | HashToken | BadStringToken | BlockStartToken | BlockEndToken | AttrStartToken | AttrEndToken | ParensStartToken | ParensEndToken | CDOCommentToken | BadCDOCommentToken | CommentToken | BadCommentToken | WhitespaceToken | IncludesToken | DashMatchToken | LessThanToken | GreaterThanToken | PseudoClassToken | PseudoClassFunctionToken | DelimToken | BadUrlToken | UrlToken | ImportantToken | ColorToken | AttrToken | EOFToken;
|
|
182
|
+
declare type Token = LiteralToken | IdentToken | CommaToken | ColonToken | SemiColonToken | NumberToken | AtRuleToken | PercentageToken | FunctionURLToken | FunctionToken | DimensionToken | LengthToken | AngleToken | StringToken | TimeToken | FrequencyToken | ResolutionToken | UnclosedStringToken | HashToken | BadStringToken | BlockStartToken | BlockEndToken | AttrStartToken | AttrEndToken | ParensStartToken | ParensEndToken | CDOCommentToken | BadCDOCommentToken | CommentToken | BadCommentToken | WhitespaceToken | IncludesToken | DashMatchToken | LessThanToken | LessThanOrEqualToken | GreaterThanToken | GreaterThanOrEqualToken | PseudoClassToken | PseudoClassFunctionToken | DelimToken | BadUrlToken | UrlToken | ImportantToken | ColorToken | AttrToken | EOFToken;
|
|
175
183
|
|
|
176
184
|
interface PropertyMapType {
|
|
177
185
|
default: string[];
|
|
@@ -634,6 +642,7 @@ declare function isResolution(dimension: DimensionToken): boolean;
|
|
|
634
642
|
declare function isAngle(dimension: DimensionToken): boolean;
|
|
635
643
|
declare function isTime(dimension: DimensionToken): boolean;
|
|
636
644
|
declare function isFrequency(dimension: DimensionToken): boolean;
|
|
645
|
+
declare function isColor(token: Token): boolean;
|
|
637
646
|
declare function isIdentStart(codepoint: number): boolean;
|
|
638
647
|
declare function isDigit(codepoint: number): boolean;
|
|
639
648
|
declare function isIdentCodepoint(codepoint: number): boolean;
|
|
@@ -653,10 +662,12 @@ declare function isWhiteSpace(codepoint: number): boolean;
|
|
|
653
662
|
|
|
654
663
|
declare const getConfig: () => PropertiesConfig;
|
|
655
664
|
|
|
665
|
+
declare const funcList: string[];
|
|
656
666
|
declare function matchType(val: Token, properties: PropertyMapType): boolean;
|
|
657
667
|
|
|
668
|
+
declare const colorsFunc: string[];
|
|
658
669
|
declare function render(data: AstNode, opt?: RenderOptions): RenderResult;
|
|
659
|
-
declare function renderToken(token: Token, options?: RenderOptions): string;
|
|
670
|
+
declare function renderToken(token: Token, options?: RenderOptions, reducer?: (acc: string, curr: Token) => string): string;
|
|
660
671
|
|
|
661
672
|
declare const combinators: string[];
|
|
662
673
|
declare function minify(ast: AstNode, options?: ParserOptions, recursive?: boolean): AstNode;
|
|
@@ -687,4 +698,4 @@ declare function resolve(url: string, currentDirectory: string, cwd?: string): {
|
|
|
687
698
|
declare function parse(iterator: string, opt?: ParserOptions): Promise<ParseResult>;
|
|
688
699
|
declare function transform(css: string, options?: TransformOptions): Promise<TransformResult>;
|
|
689
700
|
|
|
690
|
-
export { combinators, dirname, getConfig, hasDeclaration, isAngle, isAtKeyword, isDigit, isDimension, isFrequency, isFunction, isHash, isHexColor, isHexDigit, isIdent, isIdentCodepoint, isIdentStart, isLength, isNewLine, isNumber, isPercentage, isPseudo, isResolution, isTime, isWhiteSpace, load, matchType, matchUrl, minify, minifyRule, parse, parseDimension, parseString, reduceSelector, render, renderToken, resolve, tokenize, transform, urlTokenMatcher, walk };
|
|
701
|
+
export { colorsFunc, combinators, dirname, funcList, getConfig, hasDeclaration, isAngle, isAtKeyword, isColor, isDigit, isDimension, isFrequency, isFunction, isHash, isHexColor, isHexDigit, isIdent, isIdentCodepoint, isIdentStart, isLength, isNewLine, isNumber, isPercentage, isPseudo, isResolution, isTime, isWhiteSpace, load, matchType, matchUrl, minify, minifyRule, parse, parseDimension, parseString, reduceSelector, render, renderToken, resolve, tokenize, transform, urlTokenMatcher, walk };
|
package/dist/lib/ast/minify.js
CHANGED
|
@@ -344,6 +344,17 @@ function minify(ast, options = {}, recursive = false) {
|
|
|
344
344
|
continue;
|
|
345
345
|
// }
|
|
346
346
|
}
|
|
347
|
+
// @ts-ignore
|
|
348
|
+
if (hasDeclaration(node)) {
|
|
349
|
+
// @ts-ignore
|
|
350
|
+
minifyRule(node);
|
|
351
|
+
}
|
|
352
|
+
else {
|
|
353
|
+
minify(node, options, recursive);
|
|
354
|
+
}
|
|
355
|
+
previous = node;
|
|
356
|
+
nodeIndex = i;
|
|
357
|
+
continue;
|
|
347
358
|
}
|
|
348
359
|
// @ts-ignore
|
|
349
360
|
if (node.typ == 'Rule') {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { eq } from '../utils/eq.js';
|
|
2
|
+
import { renderToken } from '../../renderer/render.js';
|
|
3
|
+
import '../../renderer/utils/color.js';
|
|
2
4
|
import { getConfig } from '../utils/config.js';
|
|
3
5
|
import { matchType } from '../utils/type.js';
|
|
4
|
-
import { renderToken } from '../../renderer/render.js';
|
|
5
6
|
import { parseString } from '../parse.js';
|
|
6
7
|
import { PropertySet } from './set.js';
|
|
7
8
|
|
|
@@ -55,6 +56,7 @@ class PropertyMap {
|
|
|
55
56
|
i--;
|
|
56
57
|
continue;
|
|
57
58
|
}
|
|
59
|
+
// @ts-ignore
|
|
58
60
|
if (('propertyName' in acc[i] && acc[i].propertyName == property) || matchType(acc[i], props)) {
|
|
59
61
|
if ('prefix' in props && props.previous != null && !(props.previous in tokens)) {
|
|
60
62
|
return acc;
|
|
@@ -220,17 +222,18 @@ class PropertyMap {
|
|
|
220
222
|
if (props.multiple && props.separator != null && props.separator.typ == val.typ && eq(props.separator, val)) {
|
|
221
223
|
continue;
|
|
222
224
|
}
|
|
223
|
-
|
|
225
|
+
// @ts-ignore
|
|
226
|
+
match = val.typ == 'Comment' || matchType(val, curr[1]);
|
|
224
227
|
if (isShorthand) {
|
|
225
228
|
isShorthand = match;
|
|
226
229
|
}
|
|
230
|
+
// @ts-ignore
|
|
227
231
|
if (('propertyName' in val && val.propertyName == property) || match) {
|
|
228
232
|
if (!(curr[0] in tokens)) {
|
|
229
233
|
tokens[curr[0]] = [[]];
|
|
230
234
|
}
|
|
231
235
|
// is default value
|
|
232
236
|
tokens[curr[0]][current].push(val);
|
|
233
|
-
// continue;
|
|
234
237
|
}
|
|
235
238
|
else {
|
|
236
239
|
acc.push(curr[0]);
|
|
@@ -247,7 +250,9 @@ class PropertyMap {
|
|
|
247
250
|
if (!isShorthand || Object.entries(this.config.properties).some(entry => {
|
|
248
251
|
// missing required property
|
|
249
252
|
return entry[1].required && !(entry[0] in tokens);
|
|
250
|
-
}) ||
|
|
253
|
+
}) ||
|
|
254
|
+
// @ts-ignore
|
|
255
|
+
!Object.values(tokens).every(v => v.filter(t => t.typ != 'Comment').length == count)) {
|
|
251
256
|
// @ts-ignore
|
|
252
257
|
iterable = this.declarations.values();
|
|
253
258
|
}
|
package/dist/lib/parser/parse.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
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';
|
|
5
5
|
import { tokenize } from './tokenize.js';
|
|
6
6
|
|
|
7
7
|
const urlTokenMatcher = /^(["']?)[a-zA-Z0-9_/.-][a-zA-Z0-9_/:.#?-]+(\1)$/;
|
|
8
|
+
const trimWhiteSpace = ['Gt', 'Gte', 'Lt', 'Lte'];
|
|
8
9
|
const funcLike = ['Start-parens', 'Func', 'UrlFunc', 'Pseudo-class-func'];
|
|
9
10
|
/**
|
|
10
11
|
*
|
|
@@ -169,7 +170,7 @@ async function parse(iterator, opt = {}) {
|
|
|
169
170
|
// https://www.w3.org/TR/css-nesting-1/#conditionals
|
|
170
171
|
// allowed nesting at-rules
|
|
171
172
|
// there must be a top level rule in the stack
|
|
172
|
-
const raw = tokens.reduce((acc, curr) => {
|
|
173
|
+
const raw = parseTokens(tokens, { minify: options.minify }).reduce((acc, curr) => {
|
|
173
174
|
acc.push(renderToken(curr, { removeComments: true }));
|
|
174
175
|
return acc;
|
|
175
176
|
}, []);
|
|
@@ -200,8 +201,8 @@ async function parse(iterator, opt = {}) {
|
|
|
200
201
|
const uniq = new Map;
|
|
201
202
|
parseTokens(tokens, { minify: options.minify }).reduce((acc, curr, index, array) => {
|
|
202
203
|
if (curr.typ == 'Whitespace') {
|
|
203
|
-
if (array[index - 1]?.typ
|
|
204
|
-
array[index + 1]?.typ
|
|
204
|
+
if (trimWhiteSpace.includes(array[index - 1]?.typ) ||
|
|
205
|
+
trimWhiteSpace.includes(array[index + 1]?.typ) ||
|
|
205
206
|
combinators.includes(array[index - 1]?.val) ||
|
|
206
207
|
combinators.includes(array[index + 1]?.val)) {
|
|
207
208
|
return acc;
|
|
@@ -327,6 +328,11 @@ async function parse(iterator, opt = {}) {
|
|
|
327
328
|
if (item == null) {
|
|
328
329
|
break;
|
|
329
330
|
}
|
|
331
|
+
// console.debug({item});
|
|
332
|
+
if (item.hint != null && item.hint.startsWith('Bad-')) {
|
|
333
|
+
// bad token
|
|
334
|
+
continue;
|
|
335
|
+
}
|
|
330
336
|
tokens.push(item);
|
|
331
337
|
bytesIn = item.bytesIn;
|
|
332
338
|
if (item.token == ';' || item.token == '{') {
|
|
@@ -405,7 +411,7 @@ function getTokenType(val, hint) {
|
|
|
405
411
|
return ([
|
|
406
412
|
'Whitespace', 'Semi-colon', 'Colon', 'Block-start',
|
|
407
413
|
'Block-start', 'Attr-start', 'Attr-end', 'Start-parens', 'End-parens',
|
|
408
|
-
'Comma', 'Gt', 'Lt'
|
|
414
|
+
'Comma', 'Gt', 'Lt', 'Gte', 'Lte', 'EOF'
|
|
409
415
|
].includes(hint) ? { typ: hint } : { typ: hint, val });
|
|
410
416
|
}
|
|
411
417
|
if (val == ' ') {
|
|
@@ -533,11 +539,12 @@ function parseTokens(tokens, options = {}) {
|
|
|
533
539
|
const t = tokens[i];
|
|
534
540
|
if (t.typ == 'Whitespace' && ((i == 0 ||
|
|
535
541
|
i + 1 == tokens.length ||
|
|
536
|
-
['Comma'].includes(tokens[i + 1].typ) ||
|
|
542
|
+
['Comma', 'Gte', 'Lte'].includes(tokens[i + 1].typ)) ||
|
|
537
543
|
(i > 0 &&
|
|
538
|
-
tokens[i + 1]?.typ != 'Literal'
|
|
539
|
-
funcLike.includes(tokens[i - 1].typ) &&
|
|
540
|
-
!['var', 'calc'].includes(tokens[i - 1].val))))
|
|
544
|
+
// tokens[i + 1]?.typ != 'Literal' ||
|
|
545
|
+
// funcLike.includes(tokens[i - 1].typ) &&
|
|
546
|
+
// !['var', 'calc'].includes((<FunctionToken>tokens[i - 1]).val)))) &&
|
|
547
|
+
trimWhiteSpace.includes(tokens[i - 1].typ)))) {
|
|
541
548
|
tokens.splice(i--, 1);
|
|
542
549
|
continue;
|
|
543
550
|
}
|
|
@@ -635,41 +642,33 @@ function parseTokens(tokens, options = {}) {
|
|
|
635
642
|
// @ts-ignore
|
|
636
643
|
t.chi.pop();
|
|
637
644
|
}
|
|
638
|
-
let isColor = true;
|
|
639
645
|
// @ts-ignore
|
|
640
|
-
if (options.parseColor &&
|
|
646
|
+
if (options.parseColor && t.typ == 'Func' && isColor(t)) {
|
|
647
|
+
// if (isColor) {
|
|
641
648
|
// @ts-ignore
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
if (isColor) {
|
|
649
|
-
// @ts-ignore
|
|
650
|
-
t.typ = 'Color';
|
|
651
|
-
// @ts-ignore
|
|
652
|
-
t.kin = t.val;
|
|
649
|
+
t.typ = 'Color';
|
|
650
|
+
// @ts-ignore
|
|
651
|
+
t.kin = t.val;
|
|
652
|
+
// @ts-ignore
|
|
653
|
+
let m = t.chi.length;
|
|
654
|
+
while (m-- > 0) {
|
|
653
655
|
// @ts-ignore
|
|
654
|
-
|
|
655
|
-
while (m-- > 0) {
|
|
656
|
+
if (['Literal'].concat(trimWhiteSpace).includes(t.chi[m].typ)) {
|
|
656
657
|
// @ts-ignore
|
|
657
|
-
if (t.chi[m]
|
|
658
|
+
if (t.chi[m + 1]?.typ == 'Whitespace') {
|
|
658
659
|
// @ts-ignore
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
660
|
+
t.chi.splice(m + 1, 1);
|
|
661
|
+
}
|
|
662
|
+
// @ts-ignore
|
|
663
|
+
if (t.chi[m - 1]?.typ == 'Whitespace') {
|
|
663
664
|
// @ts-ignore
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
t.chi.splice(m - 1, 1);
|
|
667
|
-
m--;
|
|
668
|
-
}
|
|
665
|
+
t.chi.splice(m - 1, 1);
|
|
666
|
+
m--;
|
|
669
667
|
}
|
|
670
668
|
}
|
|
671
|
-
continue;
|
|
672
669
|
}
|
|
670
|
+
continue;
|
|
671
|
+
// }
|
|
673
672
|
}
|
|
674
673
|
if (t.typ == 'UrlFunc') {
|
|
675
674
|
// @ts-ignore
|
|
@@ -694,7 +693,7 @@ function parseTokens(tokens, options = {}) {
|
|
|
694
693
|
// @ts-ignore
|
|
695
694
|
if (t.chi.length > 0) {
|
|
696
695
|
// @ts-ignore
|
|
697
|
-
parseTokens(t.chi,
|
|
696
|
+
parseTokens(t.chi, options);
|
|
698
697
|
if (t.typ == 'Pseudo-class-func' && t.val == ':is' && options.minify) {
|
|
699
698
|
//
|
|
700
699
|
const count = t.chi.filter(t => t.typ != 'Comment').length;
|
|
@@ -713,7 +712,7 @@ function parseTokens(tokens, options = {}) {
|
|
|
713
712
|
if (t.typ == 'Iden') {
|
|
714
713
|
// named color
|
|
715
714
|
const value = t.val.toLowerCase();
|
|
716
|
-
if (
|
|
715
|
+
if (value in COLORS_NAMES) {
|
|
717
716
|
Object.assign(t, {
|
|
718
717
|
typ: 'Color',
|
|
719
718
|
val: COLORS_NAMES[value].length < value.length ? COLORS_NAMES[value] : value,
|
|
@@ -36,11 +36,6 @@ function* tokenize(iterator) {
|
|
|
36
36
|
}
|
|
37
37
|
buffer += quoteStr;
|
|
38
38
|
while (value = peek()) {
|
|
39
|
-
// if (ind >= iterator.length) {
|
|
40
|
-
//
|
|
41
|
-
// yield pushToken(buffer, hasNewLine ? 'Bad-string' : 'Unclosed-string');
|
|
42
|
-
// break;
|
|
43
|
-
// }
|
|
44
39
|
if (value == '\\') {
|
|
45
40
|
const sequence = peek(6);
|
|
46
41
|
let escapeSequence = '';
|
|
@@ -60,9 +55,23 @@ function* tokenize(iterator) {
|
|
|
60
55
|
}
|
|
61
56
|
break;
|
|
62
57
|
}
|
|
58
|
+
// @ts-ignore
|
|
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
|
+
}
|
|
63
72
|
// not hex or new line
|
|
64
73
|
// @ts-ignore
|
|
65
|
-
if (i == 1
|
|
74
|
+
else if (i == 1) {
|
|
66
75
|
buffer += value + sequence[i];
|
|
67
76
|
next(2);
|
|
68
77
|
continue;
|
|
@@ -82,13 +91,6 @@ function* tokenize(iterator) {
|
|
|
82
91
|
next(escapeSequence.length + 1);
|
|
83
92
|
continue;
|
|
84
93
|
}
|
|
85
|
-
// buffer += value;
|
|
86
|
-
// if (ind >= iterator.length) {
|
|
87
|
-
//
|
|
88
|
-
// // drop '\\' at the end
|
|
89
|
-
// yield pushToken(buffer);
|
|
90
|
-
// break;
|
|
91
|
-
// }
|
|
92
94
|
buffer += next(2);
|
|
93
95
|
continue;
|
|
94
96
|
}
|
|
@@ -98,20 +100,28 @@ function* tokenize(iterator) {
|
|
|
98
100
|
next();
|
|
99
101
|
// i += value.length;
|
|
100
102
|
buffer = '';
|
|
101
|
-
|
|
103
|
+
return;
|
|
102
104
|
}
|
|
103
105
|
if (isNewLine(value.charCodeAt(0))) {
|
|
104
106
|
hasNewLine = true;
|
|
105
107
|
}
|
|
106
108
|
if (hasNewLine && value == ';') {
|
|
107
|
-
yield pushToken(buffer, 'Bad-string');
|
|
109
|
+
yield pushToken(buffer + value, 'Bad-string');
|
|
108
110
|
buffer = '';
|
|
111
|
+
next();
|
|
109
112
|
break;
|
|
110
113
|
}
|
|
111
114
|
buffer += value;
|
|
112
|
-
// i += value.length;
|
|
113
115
|
next();
|
|
114
116
|
}
|
|
117
|
+
if (hasNewLine) {
|
|
118
|
+
yield pushToken(buffer, 'Bad-string');
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
// EOF - 'Unclosed-string' fixed
|
|
122
|
+
yield pushToken(buffer + quote, 'String');
|
|
123
|
+
}
|
|
124
|
+
buffer = '';
|
|
115
125
|
}
|
|
116
126
|
function peek(count = 1) {
|
|
117
127
|
if (count == 1) {
|
|
@@ -144,31 +154,18 @@ function* tokenize(iterator) {
|
|
|
144
154
|
return char;
|
|
145
155
|
}
|
|
146
156
|
while (value = next()) {
|
|
147
|
-
if (ind >= iterator.length) {
|
|
148
|
-
if (buffer.length > 0) {
|
|
149
|
-
yield pushToken(buffer);
|
|
150
|
-
buffer = '';
|
|
151
|
-
}
|
|
152
|
-
break;
|
|
153
|
-
}
|
|
154
157
|
if (isWhiteSpace(value.charCodeAt(0))) {
|
|
155
158
|
if (buffer.length > 0) {
|
|
156
159
|
yield pushToken(buffer);
|
|
157
160
|
buffer = '';
|
|
158
161
|
}
|
|
159
162
|
while (value = next()) {
|
|
160
|
-
if (ind >= iterator.length) {
|
|
161
|
-
break;
|
|
162
|
-
}
|
|
163
163
|
if (!isWhiteSpace(value.charCodeAt(0))) {
|
|
164
164
|
break;
|
|
165
165
|
}
|
|
166
166
|
}
|
|
167
167
|
yield pushToken('', 'Whitespace');
|
|
168
168
|
buffer = '';
|
|
169
|
-
if (ind >= iterator.length) {
|
|
170
|
-
break;
|
|
171
|
-
}
|
|
172
169
|
}
|
|
173
170
|
switch (value) {
|
|
174
171
|
case '/':
|
|
@@ -182,34 +179,12 @@ function* tokenize(iterator) {
|
|
|
182
179
|
}
|
|
183
180
|
buffer += value;
|
|
184
181
|
if (peek() == '*') {
|
|
185
|
-
buffer +=
|
|
186
|
-
// i++;
|
|
187
|
-
next();
|
|
182
|
+
buffer += next();
|
|
188
183
|
while (value = next()) {
|
|
189
|
-
if (ind >= iterator.length) {
|
|
190
|
-
yield pushToken(buffer, 'Bad-comment');
|
|
191
|
-
break;
|
|
192
|
-
}
|
|
193
|
-
if (value == '\\') {
|
|
194
|
-
buffer += value;
|
|
195
|
-
value = next();
|
|
196
|
-
if (ind >= iterator.length) {
|
|
197
|
-
yield pushToken(buffer, 'Bad-comment');
|
|
198
|
-
break;
|
|
199
|
-
}
|
|
200
|
-
buffer += value;
|
|
201
|
-
continue;
|
|
202
|
-
}
|
|
203
184
|
if (value == '*') {
|
|
204
185
|
buffer += value;
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
yield pushToken(buffer, 'Bad-comment');
|
|
208
|
-
break;
|
|
209
|
-
}
|
|
210
|
-
buffer += value;
|
|
211
|
-
if (value == '/') {
|
|
212
|
-
yield pushToken(buffer, 'Comment');
|
|
186
|
+
if (peek() == '/') {
|
|
187
|
+
yield pushToken(buffer + next(), 'Comment');
|
|
213
188
|
buffer = '';
|
|
214
189
|
break;
|
|
215
190
|
}
|
|
@@ -218,6 +193,8 @@ function* tokenize(iterator) {
|
|
|
218
193
|
buffer += value;
|
|
219
194
|
}
|
|
220
195
|
}
|
|
196
|
+
yield pushToken(buffer, 'Bad-comment');
|
|
197
|
+
buffer = '';
|
|
221
198
|
}
|
|
222
199
|
break;
|
|
223
200
|
case '<':
|
|
@@ -225,16 +202,15 @@ function* tokenize(iterator) {
|
|
|
225
202
|
yield pushToken(buffer);
|
|
226
203
|
buffer = '';
|
|
227
204
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
205
|
+
if (peek() == '=') {
|
|
206
|
+
yield pushToken('', 'Lte');
|
|
207
|
+
next();
|
|
231
208
|
break;
|
|
232
209
|
}
|
|
210
|
+
buffer += value;
|
|
233
211
|
if (peek(3) == '!--') {
|
|
212
|
+
buffer += next(3);
|
|
234
213
|
while (value = next()) {
|
|
235
|
-
if (ind >= iterator.length) {
|
|
236
|
-
break;
|
|
237
|
-
}
|
|
238
214
|
buffer += value;
|
|
239
215
|
if (value == '>' && prev(2) == '--') {
|
|
240
216
|
yield pushToken(buffer, 'CDOCOMM');
|
|
@@ -243,15 +219,14 @@ function* tokenize(iterator) {
|
|
|
243
219
|
}
|
|
244
220
|
}
|
|
245
221
|
}
|
|
246
|
-
if (
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
}
|
|
222
|
+
// if (!peek()) {
|
|
223
|
+
yield pushToken(buffer, 'Bad-cdo');
|
|
224
|
+
buffer = '';
|
|
225
|
+
// }
|
|
250
226
|
break;
|
|
251
227
|
case '\\':
|
|
252
|
-
value = next();
|
|
253
228
|
// EOF
|
|
254
|
-
if (
|
|
229
|
+
if (!(value = next())) {
|
|
255
230
|
// end of stream ignore \\
|
|
256
231
|
yield pushToken(buffer);
|
|
257
232
|
buffer = '';
|
|
@@ -270,8 +245,7 @@ function* tokenize(iterator) {
|
|
|
270
245
|
buffer = '';
|
|
271
246
|
}
|
|
272
247
|
buffer += value;
|
|
273
|
-
value = next()
|
|
274
|
-
if (ind >= iterator.length) {
|
|
248
|
+
if (!(value = next())) {
|
|
275
249
|
yield pushToken(buffer);
|
|
276
250
|
buffer = '';
|
|
277
251
|
break;
|
|
@@ -293,7 +267,13 @@ function* tokenize(iterator) {
|
|
|
293
267
|
yield pushToken(buffer);
|
|
294
268
|
buffer = '';
|
|
295
269
|
}
|
|
296
|
-
|
|
270
|
+
if (peek() == '=') {
|
|
271
|
+
yield pushToken('', 'Gte');
|
|
272
|
+
next();
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
yield pushToken('', 'Gt');
|
|
276
|
+
}
|
|
297
277
|
consumeWhiteSpace();
|
|
298
278
|
break;
|
|
299
279
|
case '.':
|
|
@@ -335,7 +315,7 @@ function* tokenize(iterator) {
|
|
|
335
315
|
break;
|
|
336
316
|
case '(':
|
|
337
317
|
if (buffer.length == 0) {
|
|
338
|
-
yield pushToken(
|
|
318
|
+
yield pushToken(value);
|
|
339
319
|
break;
|
|
340
320
|
}
|
|
341
321
|
buffer += value;
|
|
@@ -432,8 +412,7 @@ function* tokenize(iterator) {
|
|
|
432
412
|
yield pushToken(buffer);
|
|
433
413
|
buffer = '';
|
|
434
414
|
}
|
|
435
|
-
|
|
436
|
-
if (important == 'important') {
|
|
415
|
+
if (peek(9) == 'important') {
|
|
437
416
|
yield pushToken('', 'Important');
|
|
438
417
|
next(9);
|
|
439
418
|
buffer = '';
|
|
@@ -449,6 +428,7 @@ function* tokenize(iterator) {
|
|
|
449
428
|
if (buffer.length > 0) {
|
|
450
429
|
yield pushToken(buffer);
|
|
451
430
|
}
|
|
431
|
+
// yield pushToken('', 'EOF');
|
|
452
432
|
}
|
|
453
433
|
|
|
454
434
|
export { tokenize };
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { colorsFunc } from '../../renderer/render.js';
|
|
2
|
+
import { COLORS_NAMES } from '../../renderer/utils/color.js';
|
|
3
|
+
|
|
1
4
|
// https://www.w3.org/TR/CSS21/syndata.html#syntax
|
|
2
5
|
// https://www.w3.org/TR/2021/CRD-css-syntax-3-20211224/#typedef-ident-token
|
|
3
6
|
// '\\'
|
|
@@ -23,6 +26,25 @@ function isTime(dimension) {
|
|
|
23
26
|
function isFrequency(dimension) {
|
|
24
27
|
return 'unit' in dimension && ['hz', 'khz'].includes(dimension.unit.toLowerCase());
|
|
25
28
|
}
|
|
29
|
+
function isColor(token) {
|
|
30
|
+
if (token.typ == 'Color') {
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
if (token.typ == 'Iden') {
|
|
34
|
+
// named color
|
|
35
|
+
return token.val.toLowerCase() in COLORS_NAMES;
|
|
36
|
+
}
|
|
37
|
+
if (token.typ == 'Func' && token.chi.length > 0 && colorsFunc.includes(token.val)) {
|
|
38
|
+
// @ts-ignore
|
|
39
|
+
for (const v of token.chi) {
|
|
40
|
+
if (!['Number', 'Perc', 'Comma', 'Whitespace'].includes(v.typ)) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
26
48
|
function isLetter(codepoint) {
|
|
27
49
|
// lowercase
|
|
28
50
|
return (codepoint >= 0x61 && codepoint <= 0x7a) ||
|
|
@@ -75,19 +97,12 @@ function isIdent(name) {
|
|
|
75
97
|
return true;
|
|
76
98
|
}
|
|
77
99
|
function isPseudo(name) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
if (name.endsWith('(')) {
|
|
82
|
-
return isIdent(name.charAt(1) == ':' ? name.slice(2, -1) : name.slice(1, -1));
|
|
83
|
-
}
|
|
84
|
-
return isIdent(name.charAt(1) == ':' ? name.slice(2) : name.slice(1));
|
|
100
|
+
return name.charAt(0) == ':' &&
|
|
101
|
+
((name.endsWith('(') && isIdent(name.charAt(1) == ':' ? name.slice(2, -1) : name.slice(1, -1))) ||
|
|
102
|
+
isIdent(name.charAt(1) == ':' ? name.slice(2) : name.slice(1)));
|
|
85
103
|
}
|
|
86
104
|
function isHash(name) {
|
|
87
|
-
|
|
88
|
-
return false;
|
|
89
|
-
}
|
|
90
|
-
return isIdent(name.charAt(1));
|
|
105
|
+
return name.charAt(0) == '#' && isIdent(name.charAt(1));
|
|
91
106
|
}
|
|
92
107
|
function isNumber(name) {
|
|
93
108
|
if (name.length == 0) {
|
|
@@ -159,37 +174,30 @@ function isNumber(name) {
|
|
|
159
174
|
return true;
|
|
160
175
|
}
|
|
161
176
|
function isDimension(name) {
|
|
162
|
-
let index =
|
|
163
|
-
while (index
|
|
164
|
-
if (
|
|
165
|
-
|
|
166
|
-
break;
|
|
167
|
-
}
|
|
168
|
-
if (index == 3) {
|
|
169
|
-
break;
|
|
177
|
+
let index = name.length;
|
|
178
|
+
while (index--) {
|
|
179
|
+
if (isLetter(name.charCodeAt(index))) {
|
|
180
|
+
continue;
|
|
170
181
|
}
|
|
182
|
+
index++;
|
|
183
|
+
break;
|
|
171
184
|
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
}
|
|
175
|
-
const number = name.slice(0, -index);
|
|
176
|
-
return number.length > 0 && isIdentStart(name.charCodeAt(name.length - index)) && isNumber(number);
|
|
185
|
+
const number = name.slice(0, index);
|
|
186
|
+
return number.length > 0 && isIdentStart(name.charCodeAt(index)) && isNumber(number);
|
|
177
187
|
}
|
|
178
188
|
function isPercentage(name) {
|
|
179
189
|
return name.endsWith('%') && isNumber(name.slice(0, -1));
|
|
180
190
|
}
|
|
181
191
|
function parseDimension(name) {
|
|
182
|
-
let index =
|
|
183
|
-
while (index
|
|
184
|
-
if (
|
|
185
|
-
|
|
186
|
-
break;
|
|
187
|
-
}
|
|
188
|
-
if (index == 3) {
|
|
189
|
-
break;
|
|
192
|
+
let index = name.length;
|
|
193
|
+
while (index--) {
|
|
194
|
+
if (isLetter(name.charCodeAt(index))) {
|
|
195
|
+
continue;
|
|
190
196
|
}
|
|
197
|
+
index++;
|
|
198
|
+
break;
|
|
191
199
|
}
|
|
192
|
-
const dimension = { typ: 'Dimension', val: name.slice(0,
|
|
200
|
+
const dimension = { typ: 'Dimension', val: name.slice(0, index), unit: name.slice(index) };
|
|
193
201
|
if (isAngle(dimension)) {
|
|
194
202
|
// @ts-ignore
|
|
195
203
|
dimension.typ = 'Angle';
|
|
@@ -263,4 +271,4 @@ function isWhiteSpace(codepoint) {
|
|
|
263
271
|
codepoint == 0xa || codepoint == 0xc || codepoint == 0xd;
|
|
264
272
|
}
|
|
265
273
|
|
|
266
|
-
export { isAngle, isAtKeyword, isDigit, isDimension, isFrequency, isFunction, isHash, isHexColor, isHexDigit, isIdent, isIdentCodepoint, isIdentStart, isLength, isNewLine, isNumber, isPercentage, isPseudo, isResolution, isTime, isWhiteSpace, parseDimension };
|
|
274
|
+
export { isAngle, isAtKeyword, isColor, isDigit, isDimension, isFrequency, isFunction, isHash, isHexColor, isHexDigit, isIdent, isIdentCodepoint, isIdentStart, isLength, isNewLine, isNumber, isPercentage, isPseudo, isResolution, isTime, isWhiteSpace, parseDimension };
|