@tbela99/css-parser 0.0.1-alpha4 → 0.0.1-alpha5

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.
@@ -1,4 +1,4 @@
1
- import { isWhiteSpace, isPseudo, isAtKeyword, isFunction, isNumber, isDimension, parseDimension, isPercentage, isIdent, isHash, isNewLine, isIdentStart, isHexColor } from './utils/syntax.js';
1
+ import { isWhiteSpace, isDigit, isPseudo, isAtKeyword, isFunction, isNumber, isDimension, parseDimension, isPercentage, isIdent, isHash, isNewLine, isIdentStart, isHexColor } 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 { deduplicate } from './deduplicate.js';
@@ -306,7 +306,7 @@ async function parse(iterator, opt = {}) {
306
306
  // https://www.w3.org/TR/css-nesting-1/#conditionals
307
307
  // allowed nesting at-rules
308
308
  // there must be a top level rule in the stack
309
- const raw = tokens.reduce((acc, curr, index, array) => {
309
+ const raw = tokens.reduce((acc, curr) => {
310
310
  acc.push(renderToken(curr, { removeComments: true }));
311
311
  return acc;
312
312
  }, []);
@@ -341,7 +341,12 @@ async function parse(iterator, opt = {}) {
341
341
  }
342
342
  }
343
343
  const uniq = new Map;
344
- parseTokens(tokens, { compress: options.compress }).reduce((acc, curr) => {
344
+ parseTokens(tokens, 'Rule', { compress: options.compress }).reduce((acc, curr, index, array) => {
345
+ if (curr.typ == 'Whitespace') {
346
+ if (array[index - 1]?.val == '+' || array[index + 1]?.val == '+') {
347
+ return acc;
348
+ }
349
+ }
345
350
  let t = renderToken(curr, { compress: true });
346
351
  if (t == ',') {
347
352
  acc.push([]);
@@ -385,7 +390,7 @@ async function parse(iterator, opt = {}) {
385
390
  }
386
391
  if (tokens[i].typ == 'Colon') {
387
392
  name = tokens.slice(0, i);
388
- value = parseTokens(tokens.slice(i + 1), {
393
+ value = parseTokens(tokens.slice(i + 1), 'Declaration', {
389
394
  parseColor: true,
390
395
  src: options.src,
391
396
  resolveUrls: options.resolveUrls,
@@ -474,7 +479,6 @@ async function parse(iterator, opt = {}) {
474
479
  position.ind = ind;
475
480
  position.lin = lin;
476
481
  position.col = col == 0 ? 1 : col;
477
- // }
478
482
  }
479
483
  function consumeWhiteSpace() {
480
484
  let count = 0;
@@ -706,6 +710,9 @@ async function parse(iterator, opt = {}) {
706
710
  break;
707
711
  case '~':
708
712
  case '|':
713
+ if (tokens.at(-1)?.typ == 'Whitespace') {
714
+ tokens.pop();
715
+ }
709
716
  if (buffer.length > 0) {
710
717
  pushToken(getType(buffer));
711
718
  buffer = '';
@@ -727,19 +734,32 @@ async function parse(iterator, opt = {}) {
727
734
  break;
728
735
  }
729
736
  pushToken(getType(buffer));
737
+ while (isWhiteSpace(value.charCodeAt(0))) {
738
+ value = next();
739
+ }
730
740
  buffer = value;
731
741
  break;
732
742
  case '>':
733
- if (tokens[tokens.length - 1]?.typ == 'Whitespace') {
734
- tokens.pop();
735
- }
736
743
  if (buffer !== '') {
737
744
  pushToken(getType(buffer));
738
745
  buffer = '';
739
746
  }
747
+ if (tokens[tokens.length - 1]?.typ == 'Whitespace') {
748
+ tokens.pop();
749
+ }
740
750
  pushToken({ typ: 'Gt' });
741
751
  consumeWhiteSpace();
742
752
  break;
753
+ case '.':
754
+ const codepoint = peek().charCodeAt(0);
755
+ if (!isDigit(codepoint) && buffer !== '') {
756
+ pushToken(getType(buffer));
757
+ buffer = value;
758
+ break;
759
+ }
760
+ buffer += value;
761
+ break;
762
+ case '+':
743
763
  case ':':
744
764
  case ',':
745
765
  case '=':
@@ -753,6 +773,9 @@ async function parse(iterator, opt = {}) {
753
773
  }
754
774
  pushToken(getType(value));
755
775
  buffer = '';
776
+ if (value == '+' && isWhiteSpace(peek().charCodeAt(0))) {
777
+ pushToken(getType(next()));
778
+ }
756
779
  while (isWhiteSpace(peek().charCodeAt(0))) {
757
780
  next();
758
781
  }
@@ -930,13 +953,14 @@ async function parse(iterator, opt = {}) {
930
953
  }
931
954
  return { ast, errors, bytesIn };
932
955
  }
933
- function parseTokens(tokens, options = {}) {
956
+ function parseTokens(tokens, nodeType, options = {}) {
934
957
  for (let i = 0; i < tokens.length; i++) {
935
958
  const t = tokens[i];
936
959
  if (t.typ == 'Whitespace' && ((i == 0 ||
937
960
  i + 1 == tokens.length ||
938
961
  ['Comma'].includes(tokens[i + 1].typ) ||
939
962
  (i > 0 &&
963
+ tokens[i + 1]?.typ != 'Literal' &&
940
964
  funcLike.includes(tokens[i - 1].typ) &&
941
965
  !['var', 'calc'].includes(tokens[i - 1].val))))) {
942
966
  tokens.splice(i--, 1);
@@ -983,7 +1007,7 @@ function parseTokens(tokens, options = {}) {
983
1007
  if (t.chi.length > 1) {
984
1008
  /*(<AttrToken>t).chi =*/
985
1009
  // @ts-ignore
986
- parseTokens(t.chi, options);
1010
+ parseTokens(t.chi, t.typ, options);
987
1011
  }
988
1012
  // @ts-ignore
989
1013
  t.chi.forEach(val => {
@@ -1095,7 +1119,7 @@ function parseTokens(tokens, options = {}) {
1095
1119
  // @ts-ignore
1096
1120
  if (t.chi.length > 0) {
1097
1121
  // @ts-ignore
1098
- parseTokens(t.chi, options);
1122
+ parseTokens(t.chi, t.typ, options);
1099
1123
  if (t.typ == 'Pseudo-class-func' && t.val == ':is' && options.compress) {
1100
1124
  //
1101
1125
  const count = t.chi.filter(t => t.typ != 'Comment').length;
@@ -1,6 +1,5 @@
1
1
  import { rgb2Hex, hsl2Hex, hwb2hex, cmyk2hex, NAMES_COLORS } from './utils/color.js';
2
2
 
3
- const indents = [];
4
3
  function render(data, opt = {}) {
5
4
  const options = Object.assign(opt.compress ? {
6
5
  indent: '',
@@ -18,27 +17,12 @@ function render(data, opt = {}) {
18
17
  return acc;
19
18
  }
20
19
  }
21
- // if (options.compress && curr.typ == 'Whitespace') {
22
- //
23
- // if (original[index + 1]?.typ == 'Start-parens' ||
24
- // (index > 0 && (original[index - 1].typ == 'Pseudo-class-func' ||
25
- // original[index - 1].typ == 'End-parens' ||
26
- // original[index - 1].typ == 'UrlFunc' ||
27
- // original[index - 1].typ == 'Func' ||
28
- // (
29
- // original[index - 1].typ == 'Color' &&
30
- // (<ColorToken>original[index - 1]).kin != 'hex' &&
31
- // (<ColorToken>original[index - 1]).kin != 'lit')))) {
32
- //
33
- // return acc;
34
- // }
35
- // }
36
20
  return acc + renderToken(curr, options);
37
21
  }
38
- return { code: doRender(data, options, reducer) };
22
+ return { code: doRender(data, options, reducer, 0) };
39
23
  }
40
24
  // @ts-ignore
41
- function doRender(data, options, reducer, level = 0) {
25
+ function doRender(data, options, reducer, level = 0, indents = []) {
42
26
  if (indents.length < level + 1) {
43
27
  indents.push(options.indent.repeat(level));
44
28
  }
@@ -52,7 +36,7 @@ function doRender(data, options, reducer, level = 0) {
52
36
  return options.removeComments ? '' : data.val;
53
37
  case 'StyleSheet':
54
38
  return data.chi.reduce((css, node) => {
55
- const str = doRender(node, options, reducer, level);
39
+ const str = doRender(node, options, reducer, level, indents);
56
40
  if (str === '') {
57
41
  return css;
58
42
  }
@@ -79,7 +63,7 @@ function doRender(data, options, reducer, level = 0) {
79
63
  str = `@${node.nam} ${node.val};`;
80
64
  }
81
65
  else {
82
- str = doRender(node, options, reducer, level + 1);
66
+ str = doRender(node, options, reducer, level + 1, indents);
83
67
  }
84
68
  if (css === '') {
85
69
  return str;
@@ -87,8 +71,7 @@ function doRender(data, options, reducer, level = 0) {
87
71
  if (str === '') {
88
72
  return css;
89
73
  }
90
- if (str !== '')
91
- return `${css}${options.newLine}${indentSub}${str}`;
74
+ return `${css}${options.newLine}${indentSub}${str}`;
92
75
  }, '');
93
76
  if (children.endsWith(';')) {
94
77
  children = children.slice(0, -1);
@@ -6,7 +6,7 @@ function* doWalk(node, parent, root) {
6
6
  yield { node, parent, root };
7
7
  if ('chi' in node) {
8
8
  for (const child of node.chi) {
9
- yield* doWalk(child, node, (root == null ? node : root));
9
+ yield* doWalk(child, node, (root ?? node));
10
10
  }
11
11
  }
12
12
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tbela99/css-parser",
3
3
  "description": "CSS parser for node and the browser",
4
- "version": "0.0.1-alpha4",
4
+ "version": "0.0.1-alpha5",
5
5
  "exports": {
6
6
  ".": "./dist/index.js",
7
7
  "./web": "./dist/web/index.js",
@@ -11,8 +11,9 @@
11
11
  "typings": "dist/index.d.ts",
12
12
  "scripts": {
13
13
  "build": "rollup -c",
14
- "debug": "web-test-runner \"test/**/*.web.js\" --manual --open --node-resolve --root-dir=./test/",
15
- "test": "web-test-runner \"test/**/*.web.js\" --node-resolve --root-dir=./test/; mocha --reporter-options='maxDiffSize=181920' \"test/**/*.test.js\""
14
+ "debug": "web-test-runner \"test/**/*.web.js\" --manual --open --node-resolve --root-dir=.",
15
+ "test": "web-test-runner \"test/**/*.web-spec.js\" --node-resolve --root-dir=.; mocha --reporter-options='maxDiffSize=181920' \"test/**/*.spec.js\"",
16
+ "test:cov": "web-test-runner \"test/**/*.web-spec.js\" --node-resolve --root-dir=. --coverage; c8 --reporter=html --reporter=text --reporter=json-summary mocha --reporter-options='maxDiffSize=181920' \"test/**/*.spec.js\""
16
17
  },
17
18
  "repository": {
18
19
  "type": "git",
@@ -43,7 +44,7 @@
43
44
  "@types/node": "^18.15.10",
44
45
  "@web/test-runner": "^0.16.1",
45
46
  "@webref/css": "^6.5.9",
46
- "glob": "^10.3.0",
47
+ "c8": "^8.0.1",
47
48
  "mocha": "^10.2.0",
48
49
  "rollup": "^3.20.1",
49
50
  "rollup-plugin-dts": "^5.3.0",