@tbela99/css-parser 0.7.0 → 0.8.0

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.
Files changed (82) hide show
  1. package/README.md +142 -81
  2. package/dist/index-umd-web.js +7027 -51519
  3. package/dist/index.cjs +7022 -51515
  4. package/dist/index.d.ts +189 -60
  5. package/dist/lib/ast/expand.js +87 -2
  6. package/dist/lib/ast/features/calc.js +76 -12
  7. package/dist/lib/ast/features/inlinecssvariables.js +6 -1
  8. package/dist/lib/ast/features/prefix.js +17 -9
  9. package/dist/lib/ast/features/shorthand.js +1 -0
  10. package/dist/lib/ast/math/expression.js +299 -11
  11. package/dist/lib/ast/math/math.js +7 -1
  12. package/dist/lib/ast/minify.js +1 -1
  13. package/dist/lib/ast/types.js +58 -49
  14. package/dist/lib/ast/walk.js +80 -18
  15. package/dist/lib/parser/declaration/list.js +1 -0
  16. package/dist/lib/parser/declaration/map.js +1 -0
  17. package/dist/lib/parser/declaration/set.js +1 -0
  18. package/dist/lib/parser/parse.js +285 -72
  19. package/dist/lib/parser/tokenize.js +23 -3
  20. package/dist/lib/parser/utils/declaration.js +2 -2
  21. package/dist/lib/parser/utils/type.js +6 -6
  22. package/dist/lib/renderer/color/a98rgb.js +1 -0
  23. package/dist/lib/renderer/color/color.js +1 -0
  24. package/dist/lib/renderer/color/colormix.js +1 -0
  25. package/dist/lib/renderer/color/hex.js +1 -0
  26. package/dist/lib/renderer/color/hsl.js +1 -0
  27. package/dist/lib/renderer/color/hwb.js +1 -0
  28. package/dist/lib/renderer/color/lab.js +1 -0
  29. package/dist/lib/renderer/color/lch.js +1 -0
  30. package/dist/lib/renderer/color/oklab.js +1 -0
  31. package/dist/lib/renderer/color/oklch.js +1 -0
  32. package/dist/lib/renderer/color/p3.js +1 -0
  33. package/dist/lib/renderer/color/prophotoRgb.js +56 -0
  34. package/dist/lib/renderer/color/rec2020.js +1 -0
  35. package/dist/lib/renderer/color/relativecolor.js +52 -28
  36. package/dist/lib/renderer/color/rgb.js +1 -0
  37. package/dist/lib/renderer/color/srgb.js +1 -0
  38. package/dist/lib/renderer/color/utils/components.js +1 -0
  39. package/dist/lib/renderer/color/utils/constants.js +1 -0
  40. package/dist/lib/renderer/color/xyz.js +1 -0
  41. package/dist/lib/renderer/color/xyzd50.js +1 -0
  42. package/dist/lib/renderer/render.js +28 -6
  43. package/dist/lib/syntax/syntax.js +27 -4
  44. package/dist/lib/validation/at-rules/counter-style.js +78 -0
  45. package/dist/lib/validation/at-rules/document.js +114 -0
  46. package/dist/lib/validation/at-rules/font-feature-values.js +49 -0
  47. package/dist/lib/validation/at-rules/import.js +196 -0
  48. package/dist/lib/validation/at-rules/keyframes.js +70 -0
  49. package/dist/lib/validation/at-rules/layer.js +27 -0
  50. package/dist/lib/validation/at-rules/media.js +166 -0
  51. package/dist/lib/validation/at-rules/namespace.js +85 -0
  52. package/dist/lib/validation/at-rules/page-margin-box.js +56 -0
  53. package/dist/lib/validation/at-rules/page.js +88 -0
  54. package/dist/lib/validation/at-rules/supports.js +262 -0
  55. package/dist/lib/validation/atrule.js +172 -0
  56. package/dist/lib/validation/config.js +30 -2
  57. package/dist/lib/validation/config.json.js +1560 -50902
  58. package/dist/lib/validation/declaration.js +72 -0
  59. package/dist/lib/validation/parser/parse.js +1059 -7
  60. package/dist/lib/validation/parser/types.js +27 -12
  61. package/dist/lib/validation/selector.js +23 -444
  62. package/dist/lib/validation/syntax.js +1429 -0
  63. package/dist/lib/validation/syntaxes/complex-selector-list.js +41 -0
  64. package/dist/lib/validation/syntaxes/complex-selector.js +283 -0
  65. package/dist/lib/validation/syntaxes/family-name.js +91 -0
  66. package/dist/lib/validation/syntaxes/keyframe-block-list.js +27 -0
  67. package/dist/lib/validation/syntaxes/keyframe-selector.js +137 -0
  68. package/dist/lib/validation/syntaxes/layer-name.js +67 -0
  69. package/dist/lib/validation/syntaxes/relative-selector-list.js +27 -0
  70. package/dist/lib/validation/syntaxes/relative-selector.js +36 -0
  71. package/dist/lib/validation/syntaxes/selector-list.js +5 -0
  72. package/dist/lib/validation/syntaxes/selector.js +5 -0
  73. package/dist/lib/validation/syntaxes/url.js +75 -0
  74. package/dist/lib/validation/utils/list.js +24 -0
  75. package/dist/lib/validation/utils/whitespace.js +22 -0
  76. package/dist/node/index.js +13 -0
  77. package/dist/web/index.js +13 -0
  78. package/dist/web/load.js +1 -0
  79. package/package.json +17 -15
  80. package/dist/lib/ast/utils/minifyfeature.js +0 -9
  81. package/dist/lib/iterable/weakset.js +0 -58
  82. package/dist/lib/parser/utils/syntax.js +0 -450
@@ -0,0 +1,36 @@
1
+ import { consumeWhitespace } from '../utils/whitespace.js';
2
+ import { ValidationLevel } from '../../ast/types.js';
3
+ import '../../ast/minify.js';
4
+ import '../../ast/walk.js';
5
+ import '../../parser/parse.js';
6
+ import '../../renderer/color/utils/constants.js';
7
+ import '../../renderer/sourcemap/lib/encode.js';
8
+ import '../../parser/utils/config.js';
9
+ import { validateSelector } from './selector.js';
10
+ import { combinatorsTokens } from './complex-selector.js';
11
+
12
+ function validateRelativeSelector(tokens, root, options) {
13
+ tokens = tokens.slice();
14
+ consumeWhitespace(tokens);
15
+ if (tokens.length == 0) {
16
+ // @ts-ignore
17
+ return {
18
+ valid: ValidationLevel.Drop,
19
+ matches: [],
20
+ // @ts-ignore
21
+ node: root,
22
+ // @ts-ignore
23
+ syntax: null,
24
+ error: 'expected selector',
25
+ tokens
26
+ };
27
+ }
28
+ // , EnumToken.DescendantCombinatorTokenType
29
+ if (combinatorsTokens.includes(tokens[0].typ)) {
30
+ tokens.shift();
31
+ consumeWhitespace(tokens);
32
+ }
33
+ return validateSelector(tokens, root, options);
34
+ }
35
+
36
+ export { validateRelativeSelector };
@@ -0,0 +1,5 @@
1
+ import { validateComplexSelectorList } from './complex-selector-list.js';
2
+
3
+ const validateSelectorList = validateComplexSelectorList;
4
+
5
+ export { validateSelectorList };
@@ -0,0 +1,5 @@
1
+ import { validateComplexSelector } from './complex-selector.js';
2
+
3
+ const validateSelector = validateComplexSelector;
4
+
5
+ export { validateSelector };
@@ -0,0 +1,75 @@
1
+ import { EnumToken, ValidationLevel } from '../../ast/types.js';
2
+ import '../../ast/minify.js';
3
+ import '../../ast/walk.js';
4
+ import '../../parser/parse.js';
5
+ import '../../renderer/color/utils/constants.js';
6
+ import '../../renderer/sourcemap/lib/encode.js';
7
+ import '../../parser/utils/config.js';
8
+ import { consumeWhitespace } from '../utils/whitespace.js';
9
+
10
+ function validateURL(token) {
11
+ if (token.typ == EnumToken.UrlTokenTokenType) {
12
+ // @ts-ignore
13
+ return {
14
+ valid: ValidationLevel.Valid,
15
+ matches: [],
16
+ node: token,
17
+ // @ts-ignore
18
+ syntax: 'url()',
19
+ error: '',
20
+ tokens: []
21
+ };
22
+ }
23
+ if (token.typ != EnumToken.UrlFunctionTokenType) {
24
+ // @ts-ignore
25
+ return {
26
+ valid: ValidationLevel.Drop,
27
+ matches: [],
28
+ node: token,
29
+ // @ts-ignore
30
+ syntax: 'url()',
31
+ error: 'expected url()',
32
+ tokens: []
33
+ };
34
+ }
35
+ const children = token.chi.slice();
36
+ consumeWhitespace(children);
37
+ if (children.length == 0 || ![EnumToken.UrlTokenTokenType, EnumToken.StringTokenType, EnumToken.HashTokenType].includes(children[0].typ)) {
38
+ // @ts-ignore
39
+ return {
40
+ valid: ValidationLevel.Drop,
41
+ matches: [],
42
+ node: children[0] ?? token,
43
+ // @ts-ignore
44
+ syntax: 'url()',
45
+ error: 'expected url-token',
46
+ tokens: children
47
+ };
48
+ }
49
+ children.shift();
50
+ consumeWhitespace(children);
51
+ if (children.length > 0) {
52
+ // @ts-ignore
53
+ return {
54
+ valid: ValidationLevel.Drop,
55
+ matches: [],
56
+ node: children[0] ?? token,
57
+ // @ts-ignore
58
+ syntax: 'url()',
59
+ error: 'unexpected token',
60
+ tokens: children
61
+ };
62
+ }
63
+ // @ts-ignore
64
+ return {
65
+ valid: ValidationLevel.Valid,
66
+ matches: [],
67
+ node: token,
68
+ // @ts-ignore
69
+ syntax: 'url()',
70
+ error: '',
71
+ tokens: []
72
+ };
73
+ }
74
+
75
+ export { validateURL };
@@ -0,0 +1,24 @@
1
+ import { EnumToken } from '../../ast/types.js';
2
+ import '../../ast/minify.js';
3
+ import '../../ast/walk.js';
4
+ import '../../parser/parse.js';
5
+ import '../../renderer/color/utils/constants.js';
6
+ import '../../renderer/sourcemap/lib/encode.js';
7
+ import '../../parser/utils/config.js';
8
+
9
+ function splitTokenList(tokenList) {
10
+ return tokenList.reduce((acc, curr) => {
11
+ if (curr.typ == EnumToken.CommentTokenType) {
12
+ return acc;
13
+ }
14
+ if (curr.typ == EnumToken.CommaTokenType) {
15
+ acc.push([]);
16
+ }
17
+ else {
18
+ acc[acc.length - 1].push(curr);
19
+ }
20
+ return acc;
21
+ }, [[]]);
22
+ }
23
+
24
+ export { splitTokenList };
@@ -0,0 +1,22 @@
1
+ import { EnumToken } from '../../ast/types.js';
2
+ import '../../ast/minify.js';
3
+ import '../../ast/walk.js';
4
+ import '../../parser/parse.js';
5
+ import '../../renderer/color/utils/constants.js';
6
+ import '../../renderer/sourcemap/lib/encode.js';
7
+ import '../../parser/utils/config.js';
8
+
9
+ function consumeWhitespace(tokens) {
10
+ if (tokens.length == 0) {
11
+ return true;
12
+ }
13
+ if (tokens[0].typ != EnumToken.WhitespaceTokenType && tokens[0].typ != EnumToken.DescendantCombinatorTokenType) {
14
+ return false;
15
+ }
16
+ while (tokens.length > 0 && (tokens[0].typ == EnumToken.WhitespaceTokenType || tokens[0].typ == EnumToken.DescendantCombinatorTokenType)) {
17
+ tokens.shift();
18
+ }
19
+ return true;
20
+ }
21
+
22
+ export { consumeWhitespace };
@@ -9,15 +9,28 @@ import { doParse } from '../lib/parser/parse.js';
9
9
  export { parseString, parseTokens } from '../lib/parser/parse.js';
10
10
  import '../lib/renderer/color/utils/constants.js';
11
11
  import '../lib/parser/utils/config.js';
12
+ import '../lib/validation/config.js';
13
+ import '../lib/validation/parser/types.js';
14
+ import '../lib/validation/parser/parse.js';
15
+ import '../lib/validation/syntaxes/complex-selector.js';
12
16
  import { resolve, dirname } from '../lib/fs/resolve.js';
13
17
  import { load } from './load.js';
14
18
 
19
+ /**
20
+ * render ast node
21
+ */
15
22
  function render(data, options = {}) {
16
23
  return doRender(data, Object.assign(options, { load, resolve, dirname, cwd: options.cwd ?? process.cwd() }));
17
24
  }
25
+ /**
26
+ * parse css
27
+ */
18
28
  async function parse(iterator, opt = {}) {
19
29
  return doParse(iterator, Object.assign(opt, { load, resolve, dirname, cwd: opt.cwd ?? process.cwd() }));
20
30
  }
31
+ /**
32
+ * parse and render css
33
+ */
21
34
  async function transform(css, options = {}) {
22
35
  options = { minify: true, removeEmpty: true, removeCharset: true, ...options };
23
36
  const startTime = performance.now();
package/dist/web/index.js CHANGED
@@ -8,9 +8,16 @@ import { doParse } from '../lib/parser/parse.js';
8
8
  export { parseString, parseTokens } from '../lib/parser/parse.js';
9
9
  import '../lib/renderer/color/utils/constants.js';
10
10
  import '../lib/parser/utils/config.js';
11
+ import '../lib/validation/config.js';
12
+ import '../lib/validation/parser/types.js';
13
+ import '../lib/validation/parser/parse.js';
14
+ import '../lib/validation/syntaxes/complex-selector.js';
11
15
  import { resolve, dirname } from '../lib/fs/resolve.js';
12
16
  import { load } from './load.js';
13
17
 
18
+ /**
19
+ * render ast node
20
+ */
14
21
  function render(data, options = {}) {
15
22
  return doRender(data, Object.assign(options, {
16
23
  load,
@@ -19,6 +26,9 @@ function render(data, options = {}) {
19
26
  cwd: options.cwd ?? self.location.pathname.endsWith('/') ? self.location.pathname : dirname(self.location.pathname)
20
27
  }));
21
28
  }
29
+ /**
30
+ * parse css
31
+ */
22
32
  async function parse(iterator, opt = {}) {
23
33
  return doParse(iterator, Object.assign(opt, {
24
34
  load,
@@ -27,6 +37,9 @@ async function parse(iterator, opt = {}) {
27
37
  cwd: opt.cwd ?? self.location.pathname.endsWith('/') ? self.location.pathname : dirname(self.location.pathname)
28
38
  }));
29
39
  }
40
+ /**
41
+ * parse and render css
42
+ */
30
43
  async function transform(css, options = {}) {
31
44
  options = { minify: true, removeEmpty: true, removeCharset: true, ...options };
32
45
  const startTime = performance.now();
package/dist/web/load.js CHANGED
@@ -16,6 +16,7 @@ async function load(url, currentFile) {
16
16
  }
17
17
  else {
18
18
  const path = resolve(url, currentFile).absolute;
19
+ // @ts-ignore
19
20
  t = new URL(path, self.origin);
20
21
  }
21
22
  // @ts-ignore
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.7.0",
4
+ "version": "0.8.0",
5
5
  "exports": {
6
6
  ".": "./dist/node/index.js",
7
7
  "./umd": "./dist/index-umd-web.js",
@@ -20,6 +20,7 @@
20
20
  "test:cov": "c8 --reporter=html --reporter=text --reporter=json-summary mocha --reporter-options='maxDiffSize=1801920' \"test/**/node.spec.js\"",
21
21
  "test:web-cov": "web-test-runner \"test/**/web.spec.js\" --node-resolve --playwright --browsers chromium firefox webkit --root-dir=. --coverage",
22
22
  "profile": "node --enable-source-maps --inspect-brk test/inspect.js",
23
+ "syntax-update": "esno tools/validation.ts",
23
24
  "debug": "web-test-runner \"test/**/web.spec.js\" --manual --open --node-resolve --root-dir=."
24
25
  },
25
26
  "repository": {
@@ -49,21 +50,22 @@
49
50
  "homepage": "https://github.com/tbela99/css-parser#readme",
50
51
  "devDependencies": {
51
52
  "@esm-bundle/chai": "^4.3.4-fix.0",
52
- "@rollup/plugin-commonjs": "^25.0.7",
53
+ "@rollup/plugin-commonjs": "^28.0.2",
53
54
  "@rollup/plugin-json": "^6.1.0",
54
- "@rollup/plugin-node-resolve": "^15.2.3",
55
- "@rollup/plugin-typescript": "^11.1.6",
56
- "@types/chai": "^4.3.12",
57
- "@types/mocha": "^10.0.6",
58
- "@types/node": "^20.14.11",
59
- "@types/web": "^0.0.151",
60
- "@web/test-runner": "^0.18.1",
55
+ "@rollup/plugin-node-resolve": "^16.0.0",
56
+ "@rollup/plugin-typescript": "^12.1.2",
57
+ "@types/chai": "^5.0.1",
58
+ "@types/mocha": "^10.0.10",
59
+ "@types/node": "^22.10.2",
60
+ "@types/web": "^0.0.187",
61
+ "@web/test-runner": "^0.19.0",
61
62
  "@web/test-runner-playwright": "^0.11.0",
62
- "c8": "^9.1.0",
63
- "mocha": "^10.4.0",
64
- "playwright": "^1.45.2",
65
- "rollup": "^4.13.0",
66
- "rollup-plugin-dts": "^6.1.0",
67
- "tslib": "^2.6.2"
63
+ "c8": "^10.1.3",
64
+ "esno": "^4.8.0",
65
+ "mocha": "^11.0.1",
66
+ "playwright": "^1.49.1",
67
+ "rollup": "^4.29.2",
68
+ "rollup-plugin-dts": "^6.1.1",
69
+ "tslib": "^2.8.1"
68
70
  }
69
71
  }
@@ -1,9 +0,0 @@
1
- class MinifyFeature {
2
- static get ordering() {
3
- return 10000;
4
- }
5
- register(options) {
6
- }
7
- }
8
-
9
- export { MinifyFeature };
@@ -1,58 +0,0 @@
1
- class IterableWeakSet {
2
- #weakset = new WeakSet;
3
- #set = new Set;
4
- // constructor(iterable?: Iterable<any>) {
5
- //
6
- // if (iterable) {
7
- //
8
- // for (const value of iterable) {
9
- //
10
- // const ref: WeakRef<any> = new WeakRef(value);
11
- //
12
- // this.#weakset.add(value);
13
- // this.#set.add(ref);
14
- // }
15
- // }
16
- // }
17
- has(value) {
18
- return this.#weakset.has(value);
19
- }
20
- // delete(value: any): boolean {
21
- //
22
- // if (this.#weakset.has(value)) {
23
- //
24
- // for (const ref of this.#set) {
25
- //
26
- // if (ref.deref() === value) {
27
- //
28
- // this.#set.delete(ref);
29
- // break;
30
- // }
31
- // }
32
- //
33
- // return this.#weakset.delete(value);
34
- // }
35
- //
36
- // return false;
37
- // }
38
- add(value) {
39
- if (!this.#weakset.has(value)) {
40
- this.#weakset.add(value);
41
- this.#set.add(new WeakRef(value));
42
- }
43
- return this;
44
- }
45
- *[Symbol.iterator]() {
46
- for (const ref of new Set(this.#set)) {
47
- const key = ref.deref();
48
- if (key != null) {
49
- yield key;
50
- }
51
- else {
52
- this.#set.delete(ref);
53
- }
54
- }
55
- }
56
- }
57
-
58
- export { IterableWeakSet };