@tbela99/css-parser 1.1.0 → 1.1.1-alpha4

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.d.ts CHANGED
@@ -2,8 +2,17 @@
2
2
  * validation level enum
3
3
  */
4
4
  declare enum ValidationLevel {
5
+ /**
6
+ * disable validation
7
+ */
5
8
  None = 0,
9
+ /**
10
+ * validate selectors and at-rules
11
+ */
6
12
  Default = 1,// selectors + at-rules
13
+ /**
14
+ * validate selectors, at-rules and declarations
15
+ */
7
16
  All = 2
8
17
  }
9
18
  /**
@@ -1160,6 +1169,7 @@ interface ValidationOptions {
1160
1169
  interface MinifyOptions {
1161
1170
 
1162
1171
  minify?: boolean;
1172
+ parseColor?: boolean;
1163
1173
  nestingRules?: boolean;
1164
1174
  expandNestingRules?: boolean;
1165
1175
  removeDuplicateDeclarations?: boolean;
@@ -1179,7 +1189,6 @@ export declare interface ParserOptions extends MinifyOptions, MinifyFeatureOptio
1179
1189
  resolveUrls?: boolean;
1180
1190
  resolveImport?: boolean;
1181
1191
  cwd?: string;
1182
- parseColor?: boolean;
1183
1192
  removePrefix?: boolean;
1184
1193
  load?: (url: string, currentUrl: string) => Promise<string>;
1185
1194
  dirname?: (path: string) => string;
@@ -1248,15 +1257,20 @@ export declare interface TransformOptions extends ParserOptions, RenderOptions {
1248
1257
 
1249
1258
  }
1250
1259
 
1260
+ export declare interface ParseResultStats {
1261
+ src: string;
1262
+ bytesIn: number;
1263
+ importedBytesIn: number;
1264
+ parse: string;
1265
+ minify: string;
1266
+ total: string;
1267
+ imports: ParseResultStats[]
1268
+ }
1269
+
1251
1270
  export declare interface ParseResult {
1252
1271
  ast: AstRuleStyleSheet;
1253
1272
  errors: ErrorDescription[];
1254
- stats: {
1255
- bytesIn: number;
1256
- parse: string;
1257
- minify: string;
1258
- total: string;
1259
- }
1273
+ stats: ParseResultStats
1260
1274
  }
1261
1275
 
1262
1276
  export declare interface RenderResult {
@@ -1271,12 +1285,15 @@ export declare interface RenderResult {
1271
1285
  export declare interface TransformResult extends ParseResult, RenderResult {
1272
1286
 
1273
1287
  stats: {
1288
+ src: string;
1274
1289
  bytesIn: number;
1275
1290
  bytesOut: number;
1291
+ importedBytesIn: number;
1276
1292
  parse: string;
1277
1293
  minify: string;
1278
1294
  render: string;
1279
1295
  total: string;
1296
+ imports: ParseResultStats[];
1280
1297
  }
1281
1298
  }
1282
1299
 
@@ -9,8 +9,17 @@ var SyntaxValidationResult;
9
9
  */
10
10
  var ValidationLevel;
11
11
  (function (ValidationLevel) {
12
+ /**
13
+ * disable validation
14
+ */
12
15
  ValidationLevel[ValidationLevel["None"] = 0] = "None";
16
+ /**
17
+ * validate selectors and at-rules
18
+ */
13
19
  ValidationLevel[ValidationLevel["Default"] = 1] = "Default";
20
+ /**
21
+ * validate selectors, at-rules and declarations
22
+ */
14
23
  ValidationLevel[ValidationLevel["All"] = 2] = "All"; // selectors + at-rules + declarations
15
24
  })(ValidationLevel || (ValidationLevel = {}));
16
25
  /**
@@ -0,0 +1,104 @@
1
+ import { funcLike, ColorKind } from '../../renderer/color/utils/constants.js';
2
+ import { EnumToken } from '../types.js';
3
+ import '../minify.js';
4
+ import '../walk.js';
5
+ import '../../parser/parse.js';
6
+ import '../../parser/tokenize.js';
7
+ import '../../parser/utils/config.js';
8
+ import '../../renderer/sourcemap/lib/encode.js';
9
+ import { minmax } from '../../renderer/color/color.js';
10
+
11
+ function reduceNumber(val) {
12
+ val = String(+val);
13
+ if (val === '0') {
14
+ return '0';
15
+ }
16
+ const chr = val.charAt(0);
17
+ if (chr == '-') {
18
+ const slice = val.slice(0, 2);
19
+ if (slice == '-0') {
20
+ return val.length == 2 ? '0' : '-' + val.slice(2);
21
+ }
22
+ }
23
+ if (chr == '0') {
24
+ return val.slice(1);
25
+ }
26
+ return val;
27
+ }
28
+ /**
29
+ * clamp color values
30
+ * @param token
31
+ */
32
+ function clamp(token) {
33
+ if (token.kin == ColorKind.RGB || token.kin == ColorKind.RGBA) {
34
+ token.chi.filter((token) => ![EnumToken.LiteralTokenType, EnumToken.CommaTokenType, EnumToken.WhitespaceTokenType].includes(token.typ)).forEach((token, index) => {
35
+ if (index <= 2) {
36
+ if (token.typ == EnumToken.NumberTokenType) {
37
+ token.val = String(minmax(+token.val, 0, 255));
38
+ }
39
+ else if (token.typ == EnumToken.PercentageTokenType) {
40
+ token.val = String(minmax(+token.val, 0, 100));
41
+ }
42
+ }
43
+ else {
44
+ if (token.typ == EnumToken.NumberTokenType) {
45
+ token.val = String(minmax(+token.val, 0, 1));
46
+ }
47
+ else if (token.typ == EnumToken.PercentageTokenType) {
48
+ token.val = String(minmax(+token.val, 0, 100));
49
+ }
50
+ }
51
+ });
52
+ }
53
+ return token;
54
+ }
55
+ function getNumber(token) {
56
+ if (token.typ == EnumToken.IdenTokenType && token.val == 'none') {
57
+ return 0;
58
+ }
59
+ // @ts-ignore
60
+ return token.typ == EnumToken.PercentageTokenType ? token.val / 100 : +token.val;
61
+ }
62
+ /**
63
+ * convert angle to turn
64
+ * @param token
65
+ */
66
+ function getAngle(token) {
67
+ if (token.typ == EnumToken.IdenTokenType) {
68
+ if (token.val == 'none') {
69
+ return 0;
70
+ }
71
+ }
72
+ if (token.typ == EnumToken.AngleTokenType) {
73
+ switch (token.unit) {
74
+ case 'deg':
75
+ // @ts-ignore
76
+ return token.val / 360;
77
+ case 'rad':
78
+ // @ts-ignore
79
+ return token.val / (2 * Math.PI);
80
+ case 'grad':
81
+ // @ts-ignore
82
+ return token.val / 400;
83
+ case 'turn':
84
+ // @ts-ignore
85
+ return +token.val;
86
+ }
87
+ }
88
+ // @ts-ignore
89
+ return token.val / 360;
90
+ }
91
+ function filterValues(values) {
92
+ let i = 0;
93
+ for (; i < values.length; i++) {
94
+ if (values[i].typ == EnumToken.ImportantTokenType && values[i - 1]?.typ == EnumToken.WhitespaceTokenType) {
95
+ values.splice(i - 1, 1);
96
+ }
97
+ else if (funcLike.includes(values[i].typ) && !['var', 'calc'].includes(values[i].val) && values[i + 1]?.typ == EnumToken.WhitespaceTokenType) {
98
+ values.splice(i + 1, 1);
99
+ }
100
+ }
101
+ return values;
102
+ }
103
+
104
+ export { clamp, filterValues, getAngle, getNumber, reduceNumber };
@@ -83,11 +83,13 @@ async function doParse(iterator, options = {}) {
83
83
  const src = options.src;
84
84
  const stack = [];
85
85
  const stats = {
86
+ src: options.src ?? '',
86
87
  bytesIn: 0,
87
88
  importedBytesIn: 0,
88
89
  parse: `0ms`,
89
90
  minify: `0ms`,
90
- total: `0ms`
91
+ total: `0ms`,
92
+ imports: []
91
93
  };
92
94
  let ast = {
93
95
  typ: EnumToken.StyleSheetNodeType,
@@ -133,7 +135,7 @@ async function doParse(iterator, options = {}) {
133
135
  ast.loc.end = item.end;
134
136
  }
135
137
  if (item.token == ';' || item.token == '{') {
136
- node = parseNode(tokens, context, stats, options, errors, src, map, rawTokens);
138
+ node = parseNode(tokens, context, options, errors, src, map, rawTokens);
137
139
  rawTokens.length = 0;
138
140
  if (node != null) {
139
141
  if ('chi' in node) {
@@ -172,7 +174,7 @@ async function doParse(iterator, options = {}) {
172
174
  map = new Map;
173
175
  }
174
176
  else if (item.token == '}') {
175
- parseNode(tokens, context, stats, options, errors, src, map, rawTokens);
177
+ parseNode(tokens, context, options, errors, src, map, rawTokens);
176
178
  rawTokens.length = 0;
177
179
  if (context.loc != null) {
178
180
  context.loc.end = item.end;
@@ -193,7 +195,7 @@ async function doParse(iterator, options = {}) {
193
195
  }
194
196
  }
195
197
  if (tokens.length > 0) {
196
- node = parseNode(tokens, context, stats, options, errors, src, map, rawTokens);
198
+ node = parseNode(tokens, context, options, errors, src, map, rawTokens);
197
199
  rawTokens.length = 0;
198
200
  if (node != null) {
199
201
  if (node.typ == EnumToken.AtRuleNodeType && node.nam == 'import') {
@@ -218,7 +220,6 @@ async function doParse(iterator, options = {}) {
218
220
  const url = token.typ == EnumToken.StringTokenType ? token.val.slice(1, -1) : token.val;
219
221
  try {
220
222
  const root = await options.load(url, options.src).then((src) => {
221
- // console.error({url, src: options.src, resolved: options.resolve!(url, options.src as string)})
222
223
  return doParse(src, Object.assign({}, options, {
223
224
  minify: false,
224
225
  setParent: false,
@@ -226,6 +227,7 @@ async function doParse(iterator, options = {}) {
226
227
  }));
227
228
  });
228
229
  stats.importedBytesIn += root.stats.bytesIn;
230
+ stats.imports.push(root.stats);
229
231
  node.parent.chi.splice(node.parent.chi.indexOf(node), 1, ...root.ast.chi);
230
232
  if (root.errors.length > 0) {
231
233
  errors.push(...root.errors);
@@ -317,7 +319,7 @@ function getLastNode(context) {
317
319
  }
318
320
  return null;
319
321
  }
320
- function parseNode(results, context, stats, options, errors, src, map, rawTokens) {
322
+ function parseNode(results, context, options, errors, src, map, rawTokens) {
321
323
  let tokens = [];
322
324
  for (const t of results) {
323
325
  const node = getTokenType(t.token, t.hint);
@@ -545,9 +547,11 @@ function parseNode(results, context, stats, options, errors, src, map, rawTokens
545
547
  removeComments: true
546
548
  }), '');
547
549
  }
548
- // }
549
550
  context.chi.push(node);
550
- Object.defineProperties(node, { parent: { ...definedPropertySettings, value: context }, validSyntax: { ...definedPropertySettings, value: valid.valid == SyntaxValidationResult.Valid } });
551
+ Object.defineProperties(node, {
552
+ parent: { ...definedPropertySettings, value: context },
553
+ validSyntax: { ...definedPropertySettings, value: valid.valid == SyntaxValidationResult.Valid }
554
+ });
551
555
  return node;
552
556
  }
553
557
  else {
@@ -585,11 +589,9 @@ function parseNode(results, context, stats, options, errors, src, map, rawTokens
585
589
  let t = renderToken(curr, { minify: false });
586
590
  if (t == ',') {
587
591
  acc.push([]);
588
- // uniqTokens.push([]);
589
592
  }
590
593
  else {
591
594
  acc[acc.length - 1].push(t);
592
- // uniqTokens[uniqTokens.length - 1].push(curr);
593
595
  }
594
596
  return acc;
595
597
  }, [[]]).reduce((acc, curr) => {
@@ -621,7 +623,6 @@ function parseNode(results, context, stats, options, errors, src, map, rawTokens
621
623
  // @ts-ignore
622
624
  context.chi.push(node);
623
625
  Object.defineProperty(node, 'parent', { ...definedPropertySettings, value: context });
624
- // if (options.validation) {
625
626
  // @ts-ignore
626
627
  const valid = options.validation == ValidationLevel.None ? {
627
628
  valid: SyntaxValidationResult.Valid,
@@ -638,24 +639,10 @@ function parseNode(results, context, stats, options, errors, src, map, rawTokens
638
639
  location
639
640
  });
640
641
  }
641
- // } else {
642
- //
643
- // Object.defineProperty(node, 'tokens', {
644
- // ...definedPropertySettings,
645
- // enumerable: false,
646
- // value: tokens.slice()
647
- // });
648
- //
649
- // let raw: string[][] = [...uniq.values()];
650
- //
651
- // Object.defineProperty(node, 'raw', {
652
- // enumerable: false,
653
- // configurable: true,
654
- // writable: true,
655
- // value: raw
656
- // });
657
- // }
658
- Object.defineProperty(node, 'validSyntax', { ...definedPropertySettings, value: valid.valid == SyntaxValidationResult.Valid });
642
+ Object.defineProperty(node, 'validSyntax', {
643
+ ...definedPropertySettings,
644
+ value: valid.valid == SyntaxValidationResult.Valid
645
+ });
659
646
  return node;
660
647
  }
661
648
  else {
@@ -705,9 +692,7 @@ function parseNode(results, context, stats, options, errors, src, map, rawTokens
705
692
  parseColor(tokens[i]);
706
693
  }
707
694
  }
708
- tokens.splice(i, 0, { typ: EnumToken.ColonTokenType });
709
- // i++;
710
- i--;
695
+ tokens.splice(i--, 0, { typ: EnumToken.ColonTokenType });
711
696
  continue;
712
697
  }
713
698
  if ('chi' in tokens[i]) {
@@ -792,11 +777,15 @@ function parseNode(results, context, stats, options, errors, src, map, rawTokens
792
777
  const result = parseDeclarationNode(node, errors, location);
793
778
  Object.defineProperty(result, 'parent', { ...definedPropertySettings, value: context });
794
779
  if (result != null) {
795
- // console.error(doRender(result), result.val, location);
796
780
  if (options.validation == ValidationLevel.All) {
797
781
  const valid = evaluateSyntax(result, options);
798
- Object.defineProperty(result, 'validSyntax', { ...definedPropertySettings, value: valid.valid == SyntaxValidationResult.Valid });
782
+ Object.defineProperty(result, 'validSyntax', {
783
+ ...definedPropertySettings,
784
+ value: valid.valid == SyntaxValidationResult.Valid
785
+ });
799
786
  if (valid.valid == SyntaxValidationResult.Drop) {
787
+ // console.error({result, valid});
788
+ // console.error(JSON.stringify({result, options, valid}, null, 1));
800
789
  errors.push({
801
790
  action: 'drop',
802
791
  message: valid.error,
@@ -1590,12 +1579,6 @@ function parseTokens(tokens, options = {}) {
1590
1579
  if (t.chi[0].val.slice(1, 5) != 'data:' && urlTokenMatcher.test(value)) {
1591
1580
  // @ts-ignore
1592
1581
  t.chi[0].typ = EnumToken.UrlTokenTokenType;
1593
- // console.error({t, v: t.chi[0], value,
1594
- // src: options.src,
1595
- // resolved: options.src !== '' && options.resolveUrls ? options.resolve(value, options.src).absolute : null,
1596
- // val2: options.src !== '' && options.resolveUrls ? options.resolve(value, options.src).absolute : value});
1597
- //
1598
- // console.error(new Error('resolved'));
1599
1582
  // @ts-ignore
1600
1583
  t.chi[0].val = options.src !== '' && options.resolveUrls ? options.resolve(value, options.src).absolute : value;
1601
1584
  }
@@ -1648,4 +1631,4 @@ function parseTokens(tokens, options = {}) {
1648
1631
  return tokens;
1649
1632
  }
1650
1633
 
1651
- export { doParse, parseAtRulePrelude, parseSelector, parseString, parseTokens, urlTokenMatcher };
1634
+ export { doParse, getTokenType, parseAtRulePrelude, parseSelector, parseString, parseTokens, urlTokenMatcher };
@@ -40,6 +40,8 @@ const pseudoElements = [':before', ':after', ':first-line', ':first-letter'];
40
40
  // https://developer.mozilla.org/en-US/docs/Web/CSS/WebKit_Extensions
41
41
  // https://developer.mozilla.org/en-US/docs/Web/CSS/Mozilla_Extensions
42
42
  const pseudoAliasMap = {
43
+ '-moz-center': 'center',
44
+ '-webkit-center': 'center',
43
45
  '-ms-grid-columns': 'grid-template-columns',
44
46
  '-ms-grid-rows': 'grid-template-rows',
45
47
  '-ms-grid-row': 'grid-row-start',
@@ -52,6 +54,7 @@ const pseudoAliasMap = {
52
54
  '::-ms-input-placeholder': '::placeholder',
53
55
  ':-moz-any()': ':is',
54
56
  '-moz-user-modify': 'user-modify',
57
+ '-webkit-match-parent': 'match-parent',
55
58
  '-moz-background-clip': 'background-clip',
56
59
  '-moz-background-origin': 'background-origin',
57
60
  '-ms-input-placeholder': 'placeholder',
@@ -208,6 +211,7 @@ const webkitExtensions = new Set([
208
211
  '-webkit-min-logical-height',
209
212
  '-webkit-min-logical-width',
210
213
  '-webkit-nbsp-mode',
214
+ '-webkit-match-parent',
211
215
  '-webkit-perspective-origin-x',
212
216
  '-webkit-perspective-origin-y',
213
217
  '-webkit-rtl-ordering',