@tbela99/css-parser 0.0.1-rc6 → 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.
@@ -772,7 +772,8 @@
772
772
  }
773
773
  return val + unit;
774
774
  case 'Perc':
775
- return token.val + '%';
775
+ const perc = reduceNumber(token.val);
776
+ return options.minify && perc == '0' ? '0' : perc + '%';
776
777
  case 'Number':
777
778
  return reduceNumber(token.val);
778
779
  case 'Comment':
@@ -2244,12 +2245,16 @@
2244
2245
  }
2245
2246
  function next(count = 1) {
2246
2247
  let char = '';
2247
- while (count-- > 0 && ind < iterator.length) {
2248
+ let chr = '';
2249
+ if (count < 0) {
2250
+ return '';
2251
+ }
2252
+ while (count-- && (chr = iterator.charAt(ind + 1))) {
2253
+ char += chr;
2248
2254
  const codepoint = iterator.charCodeAt(++ind);
2249
2255
  if (isNaN(codepoint)) {
2250
2256
  return char;
2251
2257
  }
2252
- char += iterator.charAt(ind);
2253
2258
  if (isNewLine(codepoint)) {
2254
2259
  lin++;
2255
2260
  col = 0;
@@ -2816,7 +2821,7 @@
2816
2821
  if (delim.typ == 'Block-start') {
2817
2822
  const position = map.get(tokens[0]);
2818
2823
  const uniq = new Map;
2819
- parseTokens(tokens, { minify: options.minify }).reduce((acc, curr, index, array) => {
2824
+ parseTokens(tokens, { minify: true }).reduce((acc, curr, index, array) => {
2820
2825
  if (curr.typ == 'Whitespace') {
2821
2826
  if (trimWhiteSpace.includes(array[index - 1]?.typ) ||
2822
2827
  trimWhiteSpace.includes(array[index + 1]?.typ) ||
@@ -2825,7 +2830,7 @@
2825
2830
  return acc;
2826
2831
  }
2827
2832
  }
2828
- let t = renderToken(curr, { minify: true });
2833
+ let t = renderToken(curr, { minify: false });
2829
2834
  if (t == ',') {
2830
2835
  acc.push([]);
2831
2836
  }
@@ -3826,10 +3831,180 @@
3826
3831
  }
3827
3832
  }
3828
3833
 
3834
+ function* walk(node, parent, root) {
3835
+ yield { node, parent, root };
3836
+ if ('chi' in node) {
3837
+ for (const child of node.chi) {
3838
+ yield* walk(child, node, (root ?? node));
3839
+ }
3840
+ }
3841
+ }
3842
+ function* walkValues(values, parent) {
3843
+ for (const value of values) {
3844
+ // @ts-ignore
3845
+ yield { value, parent };
3846
+ if ('chi' in value) {
3847
+ yield* walkValues(value.chi, value);
3848
+ }
3849
+ }
3850
+ }
3851
+
3852
+ function expand(ast) {
3853
+ //
3854
+ if (!['Rule', 'StyleSheet', 'AtRule'].includes(ast.typ)) {
3855
+ return ast;
3856
+ }
3857
+ if ('Rule' == ast.typ) {
3858
+ return {
3859
+ typ: 'StyleSheet',
3860
+ chi: expandRule(ast)
3861
+ };
3862
+ }
3863
+ if (!('chi' in ast)) {
3864
+ return { ...ast };
3865
+ }
3866
+ const result = { ...ast, chi: [] };
3867
+ // @ts-ignore
3868
+ for (let i = 0; i < ast.chi.length; i++) {
3869
+ // @ts-ignore
3870
+ const node = ast.chi[i];
3871
+ if (node.typ == 'Rule') {
3872
+ // @ts-ignore
3873
+ result.chi.push(...expandRule(node));
3874
+ // i += expanded.length - 1;
3875
+ }
3876
+ else if (node.typ == 'AtRule' && 'chi' in node) {
3877
+ let hasRule = false;
3878
+ let j = node.chi.length;
3879
+ while (j--) {
3880
+ if (node.chi[j].typ == 'Rule' || node.chi[j].typ == 'AtRule') {
3881
+ hasRule = true;
3882
+ break;
3883
+ }
3884
+ }
3885
+ // @ts-ignore
3886
+ result.chi.push({ ...(hasRule ? expand(node) : node) });
3887
+ }
3888
+ else {
3889
+ // @ts-ignore
3890
+ result.chi.push(node);
3891
+ }
3892
+ }
3893
+ return result;
3894
+ }
3895
+ function expandRule(node) {
3896
+ const ast = { ...node, chi: node.chi.slice() };
3897
+ const result = [];
3898
+ if (ast.typ == 'Rule') {
3899
+ let i = 0;
3900
+ // @ts-ignore
3901
+ delete ast.raw;
3902
+ // @ts-ignore
3903
+ delete ast.optimized;
3904
+ for (; i < ast.chi.length; i++) {
3905
+ if (ast.chi[i].typ == 'Rule') {
3906
+ const rule = ast.chi[i];
3907
+ if (!rule.sel.includes('&')) {
3908
+ const selRule = splitRule(rule.sel);
3909
+ selRule.forEach(arr => combinators.includes(arr[0].charAt(0)) ? arr.unshift(ast.sel) : arr.unshift(ast.sel, ' '));
3910
+ rule.sel = selRule.reduce((acc, curr) => {
3911
+ acc.push(curr.join(''));
3912
+ return acc;
3913
+ }, []).join(',');
3914
+ }
3915
+ else {
3916
+ rule.sel = replaceCompound(rule.sel, ast.sel);
3917
+ }
3918
+ delete rule.raw;
3919
+ delete rule.optimized;
3920
+ ast.chi.splice(i--, 1);
3921
+ result.push(...expandRule(rule));
3922
+ }
3923
+ else if (ast.chi[i].typ == 'AtRule') {
3924
+ let astAtRule = ast.chi[i];
3925
+ const values = [];
3926
+ if (astAtRule.nam == 'scope') {
3927
+ if (astAtRule.val.includes('&')) {
3928
+ astAtRule.val = replaceCompound(astAtRule.val, ast.sel);
3929
+ }
3930
+ // @ts-ignore
3931
+ astAtRule = expand(astAtRule);
3932
+ }
3933
+ else {
3934
+ // @ts-ignore
3935
+ const clone = { ...ast, chi: astAtRule.chi.slice() };
3936
+ // @ts-ignore
3937
+ astAtRule.chi.length = 0;
3938
+ for (const r of expandRule(clone)) {
3939
+ if (r.typ == 'AtRule' && 'chi' in r) {
3940
+ if (astAtRule.val !== '' && r.val !== '') {
3941
+ if (astAtRule.nam == 'media' && r.nam == 'media') {
3942
+ r.val = astAtRule.val + ' and ' + r.val;
3943
+ }
3944
+ else if (astAtRule.nam == 'layer' && r.nam == 'layer') {
3945
+ r.val = astAtRule.val + '.' + r.val;
3946
+ }
3947
+ }
3948
+ // @ts-ignore
3949
+ values.push(r);
3950
+ }
3951
+ else if (r.typ == 'Rule') {
3952
+ // @ts-ignore
3953
+ astAtRule.chi.push(...expandRule(r));
3954
+ }
3955
+ else {
3956
+ // @ts-ignore
3957
+ astAtRule.chi.push(r);
3958
+ }
3959
+ }
3960
+ }
3961
+ // @ts-ignore
3962
+ result.push(...(astAtRule.chi.length > 0 ? [astAtRule].concat(values) : values));
3963
+ ast.chi.splice(i--, 1);
3964
+ }
3965
+ }
3966
+ }
3967
+ // @ts-ignore
3968
+ return ast.chi.length > 0 ? [ast].concat(result) : result;
3969
+ }
3970
+ function replaceCompound(input, replace) {
3971
+ const tokens = parseString(input);
3972
+ for (const t of walkValues(tokens)) {
3973
+ if (t.value.typ == 'Literal') {
3974
+ if (t.value.val == '&') {
3975
+ t.value.val = replace;
3976
+ }
3977
+ else if (t.value.val.length > 1 && t.value.val.charAt(0) == '&') {
3978
+ t.value.val = replaceCompoundLiteral(t.value.val, replace);
3979
+ }
3980
+ }
3981
+ }
3982
+ return tokens.reduce((acc, curr) => acc + renderToken(curr), '');
3983
+ }
3984
+ function replaceCompoundLiteral(selector, replace) {
3985
+ const tokens = [''];
3986
+ let i = 0;
3987
+ for (; i < selector.length; i++) {
3988
+ if (selector.charAt(i) == '&') {
3989
+ tokens.push('&');
3990
+ tokens.push('');
3991
+ }
3992
+ else {
3993
+ tokens[tokens.length - 1] += selector.charAt(i);
3994
+ }
3995
+ }
3996
+ return tokens.sort((a, b) => {
3997
+ if (a == '&') {
3998
+ return 1;
3999
+ }
4000
+ return b == '&' ? -1 : 0;
4001
+ }).reduce((acc, curr) => acc + (curr == '&' ? replace : curr), '');
4002
+ }
4003
+
3829
4004
  const combinators = ['+', '>', '~'];
3830
4005
  const notEndingWith = ['(', '['].concat(combinators);
3831
4006
  const definedPropertySettings = { configurable: true, enumerable: false, writable: true };
3832
- function minify(ast, options = {}, recursive = false, errors) {
4007
+ function minify(ast, options = {}, recursive = false, errors, nestingContent) {
3833
4008
  function wrapNodes(previous, node, match, ast, i, nodeIndex) {
3834
4009
  // @ts-ignore
3835
4010
  let pSel = match.selector1.reduce(reducer, []).join(',');
@@ -4118,8 +4293,28 @@
4118
4293
  selector2
4119
4294
  };
4120
4295
  }
4296
+ function fixSelector(node) {
4297
+ // @ts-ignore
4298
+ if (node.sel.includes('&')) {
4299
+ const attributes = parseString(node.sel);
4300
+ for (const attr of walkValues(attributes)) {
4301
+ if (attr.value.typ == 'Pseudo-class-func' && attr.value.val == ':is') {
4302
+ let i = attr.value.chi.length;
4303
+ while (i--) {
4304
+ if (attr.value.chi[i].typ == 'Literal' && attr.value.chi[i].val == '&') {
4305
+ attr.value.chi.splice(i, 1);
4306
+ }
4307
+ }
4308
+ }
4309
+ }
4310
+ node.sel = attributes.reduce((acc, curr) => acc + renderToken(curr), '');
4311
+ }
4312
+ }
4121
4313
  // @ts-ignore
4122
4314
  if (('chi' in ast) && ast.chi?.length > 0) {
4315
+ if (!nestingContent) {
4316
+ nestingContent = options.nestingRules && ast.typ == 'Rule';
4317
+ }
4123
4318
  let i = 0;
4124
4319
  let previous;
4125
4320
  let node;
@@ -4134,7 +4329,6 @@
4134
4329
  node = ast.chi[i];
4135
4330
  // @ts-ignore
4136
4331
  if (previous == node) {
4137
- // console.error('idem!');
4138
4332
  // @ts-ignore
4139
4333
  ast.chi.splice(i, 1);
4140
4334
  i--;
@@ -4150,7 +4344,6 @@
4150
4344
  i--;
4151
4345
  continue;
4152
4346
  }
4153
- // console.debug({previous, node});
4154
4347
  // @ts-ignore
4155
4348
  if (previous?.typ == 'AtRule' &&
4156
4349
  previous.nam == node.nam &&
@@ -4170,7 +4363,7 @@
4170
4363
  minifyRule(node);
4171
4364
  }
4172
4365
  else {
4173
- minify(node, options, recursive, errors);
4366
+ minify(node, options, recursive, errors, nestingContent);
4174
4367
  }
4175
4368
  previous = node;
4176
4369
  nodeIndex = i;
@@ -4224,7 +4417,7 @@
4224
4417
  nodeIndex = --i;
4225
4418
  // @ts-ignore
4226
4419
  previous = ast.chi[nodeIndex];
4227
- minify(wrapper, options, recursive, errors);
4420
+ minify(wrapper, options, recursive, errors, nestingContent);
4228
4421
  continue;
4229
4422
  }
4230
4423
  // @ts-ignore
@@ -4257,7 +4450,7 @@
4257
4450
  let wrap = true;
4258
4451
  // @ts-ignore
4259
4452
  const selector = node.optimized.selector.reduce((acc, curr) => {
4260
- if (curr[0] == '&') {
4453
+ if (curr[0] == '&' && curr.length > 1) {
4261
4454
  if (curr[1] == ' ') {
4262
4455
  curr.splice(0, 2);
4263
4456
  }
@@ -4281,7 +4474,7 @@
4281
4474
  if (!wrap) {
4282
4475
  wrap = selector.some(s => s[0] != '&');
4283
4476
  }
4284
- const rule = selector.map(s => {
4477
+ let rule = selector.map(s => {
4285
4478
  if (s[0] == '&') {
4286
4479
  // @ts-ignore
4287
4480
  s[0] = node.optimized.optimized[0];
@@ -4289,7 +4482,14 @@
4289
4482
  return s.join('');
4290
4483
  }).join(',');
4291
4484
  // @ts-ignore
4292
- node.sel = wrap ? node.optimized.optimized[0] + `:is(${rule})` : rule;
4485
+ let sel = wrap ? node.optimized.optimized[0] + `:is(${rule})` : rule;
4486
+ if (rule.includes('&')) {
4487
+ // @ts-ignore
4488
+ rule = replaceCompound(rule, node.optimized.optimized[0]);
4489
+ }
4490
+ if (sel.length < node.sel.length) {
4491
+ node.sel = sel;
4492
+ }
4293
4493
  }
4294
4494
  }
4295
4495
  // @ts-ignore
@@ -4325,7 +4525,7 @@
4325
4525
  minifyRule(node);
4326
4526
  }
4327
4527
  else {
4328
- minify(node, options, recursive, errors);
4528
+ minify(node, options, recursive, errors, nestingContent);
4329
4529
  }
4330
4530
  i--;
4331
4531
  previous = node;
@@ -4370,7 +4570,7 @@
4370
4570
  minifyRule(previous);
4371
4571
  }
4372
4572
  else {
4373
- minify(previous, options, recursive, errors);
4573
+ minify(previous, options, recursive, errors, nestingContent);
4374
4574
  }
4375
4575
  }
4376
4576
  }
@@ -4382,11 +4582,19 @@
4382
4582
  minifyRule(previous);
4383
4583
  }
4384
4584
  else {
4385
- minify(previous, options, recursive, errors);
4585
+ minify(previous, options, recursive, errors, nestingContent);
4386
4586
  }
4387
4587
  }
4388
4588
  }
4389
4589
  }
4590
+ if (!nestingContent &&
4591
+ // @ts-ignore
4592
+ previous != null &&
4593
+ // previous.optimized != null &&
4594
+ previous.typ == 'Rule' &&
4595
+ previous.sel.includes('&')) {
4596
+ fixSelector(previous);
4597
+ }
4390
4598
  previous = node;
4391
4599
  nodeIndex = i;
4392
4600
  }
@@ -4399,10 +4607,18 @@
4399
4607
  else {
4400
4608
  // @ts-ignore
4401
4609
  if (!(node.typ == 'AtRule' && node.nam != 'font-face')) {
4402
- minify(node, options, recursive, errors);
4610
+ minify(node, options, recursive, errors, nestingContent);
4403
4611
  }
4404
4612
  }
4405
4613
  }
4614
+ if (!nestingContent &&
4615
+ // @ts-ignore
4616
+ node != null &&
4617
+ // previous.optimized != null &&
4618
+ node.typ == 'Rule' &&
4619
+ node.sel.includes('&')) {
4620
+ fixSelector(node);
4621
+ }
4406
4622
  }
4407
4623
  return ast;
4408
4624
  }
@@ -4641,181 +4857,6 @@
4641
4857
  Object.defineProperty(node, 'raw', { ...definedPropertySettings, value: raw });
4642
4858
  }
4643
4859
  }
4644
- // }
4645
- }
4646
-
4647
- function* walk(node) {
4648
- // @ts-ignore
4649
- yield* doWalk(node, null, null);
4650
- }
4651
- function* doWalk(node, parent, root) {
4652
- yield { node, parent, root };
4653
- if ('chi' in node) {
4654
- for (const child of node.chi) {
4655
- yield* doWalk(child, node, (root ?? node));
4656
- }
4657
- }
4658
- }
4659
- function* walkValues(values, parent) {
4660
- for (const value of values) {
4661
- // @ts-ignore
4662
- yield { value, parent };
4663
- if ('chi' in value) {
4664
- yield* walkValues(value.chi, value);
4665
- }
4666
- }
4667
- }
4668
-
4669
- function expand(ast) {
4670
- //
4671
- if (!['Rule', 'StyleSheet', 'AtRule'].includes(ast.typ)) {
4672
- return ast;
4673
- }
4674
- if ('Rule' == ast.typ) {
4675
- return {
4676
- typ: 'StyleSheet',
4677
- chi: expandRule(ast)
4678
- };
4679
- }
4680
- if (!('chi' in ast)) {
4681
- return { ...ast };
4682
- }
4683
- const result = { ...ast, chi: [] };
4684
- // @ts-ignore
4685
- for (let i = 0; i < ast.chi.length; i++) {
4686
- // @ts-ignore
4687
- const node = ast.chi[i];
4688
- if (node.typ == 'Rule') {
4689
- // @ts-ignore
4690
- result.chi.push(...expandRule(node));
4691
- // i += expanded.length - 1;
4692
- }
4693
- else if (node.typ == 'AtRule' && 'chi' in node) {
4694
- let hasRule = false;
4695
- let j = node.chi.length;
4696
- while (j--) {
4697
- if (node.chi[j].typ == 'Rule' || node.chi[j].typ == 'AtRule') {
4698
- hasRule = true;
4699
- break;
4700
- }
4701
- }
4702
- // @ts-ignore
4703
- result.chi.push({ ...(hasRule ? expand(node) : node) });
4704
- }
4705
- else {
4706
- // @ts-ignore
4707
- result.chi.push(node);
4708
- }
4709
- }
4710
- return result;
4711
- }
4712
- function expandRule(node) {
4713
- const ast = { ...node, chi: node.chi.slice() };
4714
- const result = [];
4715
- if (ast.typ == 'Rule') {
4716
- let i = 0;
4717
- // @ts-ignore
4718
- delete ast.raw;
4719
- // @ts-ignore
4720
- delete ast.optimized;
4721
- for (; i < ast.chi.length; i++) {
4722
- if (ast.chi[i].typ == 'Rule') {
4723
- const rule = ast.chi[i];
4724
- if (!rule.sel.includes('&')) {
4725
- const selRule = splitRule(rule.sel);
4726
- selRule.forEach(arr => combinators.includes(arr[0].charAt(0)) ? arr.unshift(ast.sel) : arr.unshift(ast.sel, ' '));
4727
- rule.sel = selRule.reduce((acc, curr) => {
4728
- acc.push(curr.join(''));
4729
- return acc;
4730
- }, []).join(',');
4731
- }
4732
- else {
4733
- rule.sel = replaceCompount(rule.sel, ast.sel);
4734
- }
4735
- delete rule.raw;
4736
- delete rule.optimized;
4737
- ast.chi.splice(i--, 1);
4738
- result.push(...expandRule(rule));
4739
- }
4740
- else if (ast.chi[i].typ == 'AtRule') {
4741
- let astAtRule = ast.chi[i];
4742
- const values = [];
4743
- if (astAtRule.nam == 'scope') {
4744
- if (astAtRule.val.includes('&')) {
4745
- astAtRule.val = replaceCompount(astAtRule.val, ast.sel);
4746
- }
4747
- // @ts-ignore
4748
- astAtRule = expand(astAtRule);
4749
- }
4750
- else {
4751
- // @ts-ignore
4752
- const clone = { ...ast, chi: astAtRule.chi.slice() };
4753
- // @ts-ignore
4754
- astAtRule.chi.length = 0;
4755
- for (const r of expandRule(clone)) {
4756
- if (r.typ == 'AtRule' && 'chi' in r) {
4757
- if (astAtRule.val !== '' && r.val !== '') {
4758
- if (astAtRule.nam == 'media' && r.nam == 'media') {
4759
- r.val = astAtRule.val + ' and ' + r.val;
4760
- }
4761
- else if (astAtRule.nam == 'layer' && r.nam == 'layer') {
4762
- r.val = astAtRule.val + '.' + r.val;
4763
- }
4764
- }
4765
- // @ts-ignore
4766
- values.push(r);
4767
- }
4768
- else if (r.typ == 'Rule') {
4769
- // @ts-ignore
4770
- astAtRule.chi.push(...expandRule(r));
4771
- }
4772
- else {
4773
- // @ts-ignore
4774
- astAtRule.chi.push(r);
4775
- }
4776
- }
4777
- }
4778
- // @ts-ignore
4779
- result.push(...(astAtRule.chi.length > 0 ? [astAtRule].concat(values) : values));
4780
- ast.chi.splice(i--, 1);
4781
- }
4782
- }
4783
- }
4784
- // @ts-ignore
4785
- return ast.chi.length > 0 ? [ast].concat(result) : result;
4786
- }
4787
- function replaceCompount(input, replace) {
4788
- const tokens = parseString(input);
4789
- for (const t of walkValues(tokens)) {
4790
- if (t.value.typ == 'Literal') {
4791
- if (t.value.val == '&') {
4792
- t.value.val = replace;
4793
- }
4794
- else if (t.value.val.length > 1 && t.value.val.charAt(0) == '&') {
4795
- t.value.val = replaceCompoundLiteral(t.value.val, replace);
4796
- }
4797
- }
4798
- }
4799
- return tokens.reduce((acc, curr) => acc + renderToken(curr), '');
4800
- }
4801
- function replaceCompoundLiteral(selector, replace) {
4802
- const tokens = [''];
4803
- let i = 0;
4804
- for (; i < selector.length; i++) {
4805
- if (selector.charAt(i) == '&') {
4806
- tokens.push('&');
4807
- tokens.push('');
4808
- }
4809
- else {
4810
- tokens[tokens.length - 1] += selector.charAt(i);
4811
- }
4812
- }
4813
- return tokens.sort((a, b) => {
4814
- if (a == '&') {
4815
- return 1;
4816
- }
4817
- return b == '&' ? -1 : 0;
4818
- }).reduce((acc, curr) => acc + (curr == '&' ? replace : curr), '');
4819
4860
  }
4820
4861
 
4821
4862
  async function transform$1(css, options = {}) {
@@ -5007,6 +5048,7 @@
5007
5048
  exports.reduceSelector = reduceSelector;
5008
5049
  exports.render = render;
5009
5050
  exports.renderToken = renderToken;
5051
+ exports.replaceCompound = replaceCompound;
5010
5052
  exports.resolve = resolve;
5011
5053
  exports.splitRule = splitRule;
5012
5054
  exports.tokenize = tokenize;