@tbela99/css-parser 1.3.0 → 1.3.1

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.
@@ -4,7 +4,7 @@ import '../parser/utils/config.js';
4
4
  import { EnumToken } from './types.js';
5
5
  import { walkValues } from './walk.js';
6
6
  import { doRender, renderToken } from '../renderer/render.js';
7
- import '../syntax/color/utils/constants.js';
7
+ import '../renderer/sourcemap/lib/encode.js';
8
8
  import { isWhiteSpace, isIdent, isFunction, isIdentStart } from '../syntax/syntax.js';
9
9
  import { eq } from '../parser/utils/eq.js';
10
10
  import * as index from './features/index.js';
@@ -16,13 +16,14 @@ const notEndingWith = ['(', '['].concat(combinators);
16
16
  // @ts-ignore
17
17
  const features = Object.values(index).sort((a, b) => a.ordering - b.ordering);
18
18
  /**
19
- * minify ast
19
+ * apply minification rules to the ast tree
20
20
  * @param ast
21
21
  * @param options
22
22
  * @param recursive
23
23
  * @param errors
24
24
  * @param nestingContent
25
- * @param context
25
+ *
26
+ * @private
26
27
  */
27
28
  function minify(ast, options = {}, recursive = false, errors, nestingContent, context = {}) {
28
29
  let preprocess = false;
@@ -88,7 +89,6 @@ function minify(ast, options = {}, recursive = false, errors, nestingContent, co
88
89
  doMinify(ast, options, recursive, errors, nestingContent, context);
89
90
  parents = [ast];
90
91
  for (const parent of parents) {
91
- // parent = parents.shift() as AstNode;
92
92
  if (parent.typ == EnumToken.CommentTokenType ||
93
93
  parent.typ == EnumToken.CDOCOMMTokenType) {
94
94
  continue;
@@ -121,6 +121,15 @@ function minify(ast, options = {}, recursive = false, errors, nestingContent, co
121
121
  }
122
122
  return ast;
123
123
  }
124
+ /**
125
+ * reduce selectors
126
+ * @param acc
127
+ * @param curr
128
+ * @param index
129
+ * @param array
130
+ *
131
+ * @private
132
+ */
124
133
  function reduce(acc, curr, index, array) {
125
134
  // trim :is()
126
135
  // if (array.length == 1 && array[0][0] == ':is(' && array[0].at(-1) == ')') {
@@ -131,20 +140,21 @@ function reduce(acc, curr, index, array) {
131
140
  if (curr[1] == ' ' && !isIdent(curr[2]) && !isFunction(curr[2])) {
132
141
  curr.splice(0, 2);
133
142
  }
134
- // else if (combinators.includes(curr[1])) {
135
- //
136
- // curr.shift();
137
- // }
138
143
  }
139
- // else { // @ts-ignore
140
- // if (this.typ == EnumToken.RuleNodeType && (isIdent(curr[0]) || isFunction(curr[0]))) {
141
- //
142
- // curr.unshift('&', ' ');
143
- // }
144
- // }
145
144
  acc.push(curr.join(''));
146
145
  return acc;
147
146
  }
147
+ /**
148
+ * apply minification rules to the ast tree
149
+ * @param ast
150
+ * @param options
151
+ * @param recursive
152
+ * @param errors
153
+ * @param nestingContent
154
+ * @param context
155
+ *
156
+ * @private
157
+ */
148
158
  function doMinify(ast, options = {}, recursive = false, errors, nestingContent, context = {}) {
149
159
  if (!('nodes' in context)) {
150
160
  context.nodes = new Set;
@@ -171,13 +181,6 @@ function doMinify(ast, options = {}, recursive = false, errors, nestingContent,
171
181
  }
172
182
  // @ts-ignore
173
183
  node = ast.chi[i];
174
- // @ts-ignore
175
- // if (previous == node) {
176
- //
177
- // // @ts-ignore
178
- // ast.chi.splice(i--, 1);
179
- // continue;
180
- // }
181
184
  if (node.typ == EnumToken.AtRuleNodeType && node.nam == 'font-face') {
182
185
  continue;
183
186
  }
@@ -329,12 +332,7 @@ function doMinify(ast, options = {}, recursive = false, errors, nestingContent,
329
332
  curr.splice(0, 2);
330
333
  }
331
334
  else {
332
- // if (ast.typ != EnumToken.RuleNodeType && combinators.includes(curr[1])) {
333
- //
334
- // wrap = false;
335
- // } else {
336
335
  curr.splice(0, 1);
337
- // }
338
336
  }
339
337
  }
340
338
  else if (combinators.includes(curr[0])) {
@@ -376,11 +374,6 @@ function doMinify(ast, options = {}, recursive = false, errors, nestingContent,
376
374
  }
377
375
  // @ts-ignore
378
376
  let sel = wrap ? node.optimized.optimized.join('') + `:is(${rule})` : rule;
379
- // if (rule.includes('&')) {
380
- //
381
- // // @ts-ignore
382
- // rule = replaceCompound(rule, node.optimized.optimized[0]);
383
- // }
384
377
  if (sel.length < node.sel.length) {
385
378
  node.sel = sel;
386
379
  }
@@ -413,13 +406,6 @@ function doMinify(ast, options = {}, recursive = false, errors, nestingContent,
413
406
  node.chi.unshift(...previous.chi);
414
407
  // @ts-ignore
415
408
  ast.chi.splice(nodeIndex, 1);
416
- // @ts-ignore
417
- // if (!hasDeclaration(node)) {
418
- // // @ts-ignore
419
- // // minifyRule(node, <MinifyOptions>options, ast, context);
420
- // // } else {
421
- // doMinify(node, options, recursive, errors, nestingContent, context);
422
- // }
423
409
  i--;
424
410
  previous = node;
425
411
  nodeIndex = i;
@@ -431,13 +417,10 @@ function doMinify(ast, options = {}, recursive = false, errors, nestingContent,
431
417
  if (intersect.node1.chi.length == 0) {
432
418
  // @ts-ignore
433
419
  ast.chi.splice(i--, 1);
434
- // @ts-ignore
435
- // node = ast.chi[i];
436
420
  }
437
421
  else {
438
422
  // @ts-ignore
439
423
  ast.chi.splice(i--, 1, intersect.node1);
440
- // node = ast.chi intersect.node1;
441
424
  }
442
425
  if (intersect.node2.chi.length == 0) {
443
426
  // @ts-ignore
@@ -470,33 +453,11 @@ function doMinify(ast, options = {}, recursive = false, errors, nestingContent,
470
453
  if (recursive && previous != node) {
471
454
  // @ts-ignore
472
455
  if (!hasDeclaration(previous)) {
473
- // @ts-ignore
474
- // minifyRule(previous, <MinifyOptions>options, ast, context);
475
- // } else {
476
456
  doMinify(previous, options, recursive, errors, nestingContent, context);
477
457
  }
478
458
  }
479
459
  }
480
- // else {
481
- //
482
- // if ('chi' in previous) {
483
- //
484
- // // @ts-ignore
485
- // if (!hasDeclaration(previous)) {
486
- //
487
- // // @ts-ignore
488
- // // minifyRule(previous, <MinifyOptions>options, ast, context);
489
- // // } else {
490
- //
491
- // doMinify(previous, options, recursive, errors, nestingContent, context);
492
- // }
493
- // }
494
- // }
495
460
  }
496
- // else if ('chi' in node) {
497
- //
498
- // doMinify(node, options, recursive, errors, nestingContent, context);
499
- // }
500
461
  if (!nestingContent &&
501
462
  // @ts-ignore
502
463
  previous != null &&
@@ -529,6 +490,12 @@ function doMinify(ast, options = {}, recursive = false, errors, nestingContent,
529
490
  }
530
491
  return ast;
531
492
  }
493
+ /**
494
+ * check if a rule has a declaration
495
+ * @param node
496
+ *
497
+ * @private
498
+ */
532
499
  function hasDeclaration(node) {
533
500
  // @ts-ignore
534
501
  for (let i = 0; i < node.chi?.length; i++) {
@@ -544,11 +511,10 @@ function hasDeclaration(node) {
544
511
  /**
545
512
  * optimize selector
546
513
  * @param selector
514
+ *
515
+ * @private
547
516
  */
548
517
  function optimizeSelector(selector) {
549
- // if (selector.length == 0) {
550
- // return null;
551
- // }
552
518
  selector = selector.reduce((acc, curr) => {
553
519
  // @ts-ignore
554
520
  if (curr.length > 0 && curr.at(-1).startsWith(':is(')) {
@@ -596,11 +562,6 @@ function optimizeSelector(selector) {
596
562
  break;
597
563
  }
598
564
  selector.forEach((selector) => selector.splice(0, optimized.length));
599
- // combinator
600
- // if (combinators.includes(<string>optimized.at(-1))) {
601
- // const combinator: string = <string>optimized.pop();
602
- // selector.forEach((selector: string[]) => selector.unshift(combinator));
603
- // }
604
565
  let reducible = optimized.length == 1;
605
566
  if (optimized[0] == '&') {
606
567
  if (optimized[1] == ' ') {
@@ -648,6 +609,8 @@ function optimizeSelector(selector) {
648
609
  /**
649
610
  * split selector string
650
611
  * @param buffer
612
+ *
613
+ * @internal
651
614
  */
652
615
  function splitRule(buffer) {
653
616
  const result = [[]];
@@ -655,17 +618,6 @@ function splitRule(buffer) {
655
618
  for (let i = 0; i < buffer.length; i++) {
656
619
  let chr = buffer.charAt(i);
657
620
  if (isWhiteSpace(chr.charCodeAt(0))) {
658
- // let k: number = i;
659
- // while (k + 1 < buffer.length) {
660
- //
661
- // if (isWhiteSpace(buffer[k + 1].charCodeAt(0))) {
662
- //
663
- // k++;
664
- // continue;
665
- // }
666
- //
667
- // break;
668
- // }
669
621
  if (str !== '') {
670
622
  // @ts-ignore
671
623
  result.at(-1).push(str);
@@ -727,22 +679,6 @@ function splitRule(buffer) {
727
679
  str += buffer.charAt(++i);
728
680
  continue;
729
681
  }
730
- // if (chr == '"' || chr == "'") {
731
- //
732
- // let k = i;
733
- // while (++k < buffer.length) {
734
- // chr = buffer.charAt(k);
735
- // str += chr;
736
- // if (chr == '//') {
737
- // str += buffer.charAt(++k);
738
- // continue;
739
- // }
740
- // if (chr == buffer.charAt(i)) {
741
- // break;
742
- // }
743
- // }
744
- // continue;
745
- // }
746
682
  if (chr == '(' || chr == '[') {
747
683
  const open = chr;
748
684
  const close = chr == '(' ? ')' : ']';
@@ -775,11 +711,14 @@ function splitRule(buffer) {
775
711
  }
776
712
  return result;
777
713
  }
714
+ /**
715
+ * reduce selector
716
+ * @param acc
717
+ * @param curr
718
+ *
719
+ * @private
720
+ */
778
721
  function reduceSelector(acc, curr) {
779
- // if (acc === null) {
780
- //
781
- // return null;
782
- // }
783
722
  let hasCompoundSelector = true;
784
723
  // @ts-ignore
785
724
  curr = curr.slice(this.match[0].length);
@@ -791,16 +730,6 @@ function reduceSelector(acc, curr) {
791
730
  }
792
731
  break;
793
732
  }
794
- // invalid function match
795
- // if (curr.length > 0 && curr[0].endsWith('(') && curr.at(-1) != ')') {
796
- //
797
- // return null;
798
- // }
799
- //
800
- // if (curr.length == 1 && combinators.includes(curr[0].charAt(0))) {
801
- //
802
- // return null;
803
- // }
804
733
  if (hasCompoundSelector && curr.length > 0) {
805
734
  hasCompoundSelector = !['&'].concat(combinators).includes(curr[0].charAt(0));
806
735
  }
@@ -810,15 +739,6 @@ function reduceSelector(acc, curr) {
810
739
  if (index == 0) {
811
740
  canReduce = curr[1] == '&';
812
741
  }
813
- // else if (token.endsWith('(')) {
814
- //
815
- // if (inFunction == 0) {
816
- //
817
- // canReduce = false;
818
- // }
819
- //
820
- // inFunction++;
821
- // }
822
742
  else if (token == ')') ;
823
743
  else if (token == ',') {
824
744
  if (!canReduce) {
@@ -830,10 +750,6 @@ function reduceSelector(acc, curr) {
830
750
  acc.at(-1)?.push(token);
831
751
  return acc;
832
752
  }, [[]]);
833
- // if (inFunction > 0) {
834
- //
835
- // canReduce = false;
836
- // }
837
753
  if (canReduce) {
838
754
  curr = isCompound.reduce((acc, curr) => {
839
755
  if (acc.length > 0) {
@@ -848,7 +764,14 @@ function reduceSelector(acc, curr) {
848
764
  acc.push(this.match.length == 0 ? ['&'] : (hasCompoundSelector && curr[0] != '&' && (curr.length == 0 || !combinators.includes(curr[0].charAt(0))) ? ['&'].concat(curr) : curr));
849
765
  return acc;
850
766
  }
851
- function matchSelectors(selector1, selector2, parentType, errors) {
767
+ /**
768
+ * match selectors
769
+ * @param selector1
770
+ * @param selector2
771
+ *
772
+ * @private
773
+ */
774
+ function matchSelectors(selector1, selector2 /*, parentType: EnumToken, errors: ErrorDescription[] */) {
852
775
  let match = [[]];
853
776
  const j = Math.min(selector1.reduce((acc, curr) => Math.min(acc, curr.length), selector1.length > 0 ? selector1[0].length : 0), selector2.reduce((acc, curr) => Math.min(acc, curr.length), selector2.length > 0 ? selector2[0].length : 0));
854
777
  let i = 0;
@@ -879,52 +802,15 @@ function matchSelectors(selector1, selector2, parentType, errors) {
879
802
  if (!matching) {
880
803
  break;
881
804
  }
882
- // if (token == ',') {
883
- //
884
- // match.push([]);
885
- // } else {
886
805
  if (token.endsWith('(')) {
887
806
  matchFunction++;
888
807
  }
889
- // if (token.endsWith('[')) {
890
- //
891
- // inAttr++;
892
- // } else if (token == ')') {
893
- //
894
- // matchFunction--;
895
- // } else if (token == ']') {
896
- //
897
- // inAttr--;
898
- // }
899
808
  match.at(-1).push(token);
900
- // }
901
809
  }
902
810
  // invalid function
903
811
  if (matchFunction != 0 || inAttr != 0) {
904
812
  return null;
905
813
  }
906
- // if (parentType != EnumToken.RuleNodeType) {
907
- //
908
- // for (const part of match) {
909
- //
910
- // if (part.length > 0 && combinators.includes(part[0].charAt(0))) {
911
- //
912
- // return null;
913
- // }
914
- // }
915
- // }
916
- // if (match.length > 1) {
917
- //
918
- // errors?.push({
919
- // action: 'ignore',
920
- // message: `minify: unsupported multilevel matching\n${JSON.stringify({
921
- // match,
922
- // selector1,
923
- // selector2
924
- // }, null, 1)}`
925
- // });
926
- // return null;
927
- // }
928
814
  for (const part of match) {
929
815
  while (part.length > 0) {
930
816
  const token = part.at(-1);
@@ -953,6 +839,12 @@ function matchSelectors(selector1, selector2, parentType, errors) {
953
839
  selector2
954
840
  };
955
841
  }
842
+ /**
843
+ * fix selector
844
+ * @param node
845
+ *
846
+ * @private
847
+ */
956
848
  function fixSelector(node) {
957
849
  // @ts-ignore
958
850
  if (node.sel.includes('&')) {
@@ -970,6 +862,18 @@ function fixSelector(node) {
970
862
  node.sel = attributes.reduce((acc, curr) => acc + renderToken(curr), '');
971
863
  }
972
864
  }
865
+ /**
866
+ * wrap nodes
867
+ * @param previous
868
+ * @param node
869
+ * @param match
870
+ * @param ast
871
+ * @param reducer
872
+ * @param i
873
+ * @param nodeIndex
874
+ *
875
+ * @private
876
+ */
973
877
  function wrapNodes(previous, node, match, ast, reducer, i, nodeIndex) {
974
878
  // @ts-ignore
975
879
  let pSel = match.selector1.reduce(reducer, []).join(',');
@@ -1015,6 +919,15 @@ function wrapNodes(previous, node, match, ast, reducer, i, nodeIndex) {
1015
919
  reduceRuleSelector(wrapper);
1016
920
  return wrapper;
1017
921
  }
922
+ /**
923
+ * diff nodes
924
+ * @param n1
925
+ * @param n2
926
+ * @param reducer
927
+ * @param options
928
+ *
929
+ * @private
930
+ */
1018
931
  function diff(n1, n2, reducer, options = {}) {
1019
932
  if (!('cache' in options)) {
1020
933
  options.cache = new WeakMap();
@@ -1030,10 +943,6 @@ function diff(n1, n2, reducer, options = {}) {
1030
943
  }
1031
944
  let i = node1.chi.length;
1032
945
  let j = node2.chi.length;
1033
- // if (i == 0 || j == 0) {
1034
- //
1035
- // return null;
1036
- // }
1037
946
  const raw1 = node1.raw;
1038
947
  const raw2 = node2.raw;
1039
948
  if (raw1 != null && raw2 != null) {
@@ -1104,10 +1013,6 @@ function diff(n1, n2, reducer, options = {}) {
1104
1013
  continue;
1105
1014
  }
1106
1015
  j = node2.chi.length;
1107
- // if (j == 0) {
1108
- //
1109
- // break;
1110
- // }
1111
1016
  while (j--) {
1112
1017
  if (node2.chi[j].typ == EnumToken.CommentNodeType) {
1113
1018
  continue;
@@ -1145,6 +1050,12 @@ function diff(n1, n2, reducer, options = {}) {
1145
1050
  }
1146
1051
  return { result, node1: exchanged ? node2 : node1, node2: exchanged ? node1 : node2 };
1147
1052
  }
1053
+ /**
1054
+ * reduce rule selector
1055
+ * @param node
1056
+ *
1057
+ * @private
1058
+ */
1148
1059
  function reduceRuleSelector(node) {
1149
1060
  if (node.raw == null) {
1150
1061
  Object.defineProperty(node, 'raw', { ...definedPropertySettings, value: splitRule(node.sel) });