@tbela99/css-parser 0.0.1-rc2 → 0.0.1-rc4

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,5 +1,22 @@
1
- import { COLORS_NAMES, rgb2Hex, hsl2Hex, hwb2hex, cmyk2hex, NAMES_COLORS } from './utils/color.js';
1
+ import { getAngle, COLORS_NAMES, rgb2Hex, hsl2Hex, hwb2hex, cmyk2hex, NAMES_COLORS } from './utils/color.js';
2
2
 
3
+ function reduceNumber(val) {
4
+ val = (+val).toString();
5
+ if (val === '0') {
6
+ return '0';
7
+ }
8
+ const chr = val.charAt(0);
9
+ if (chr == '-') {
10
+ const slice = val.slice(0, 2);
11
+ if (slice == '-0') {
12
+ return val.length == 2 ? '0' : '-' + val.slice(2);
13
+ }
14
+ }
15
+ if (chr == '0') {
16
+ return val.slice(1);
17
+ }
18
+ return val;
19
+ }
3
20
  function render(data, opt = {}) {
4
21
  const startTime = performance.now();
5
22
  const options = Object.assign(opt.minify ?? true ? {
@@ -12,17 +29,19 @@ function render(data, opt = {}) {
12
29
  compress: false,
13
30
  removeComments: false,
14
31
  }, { colorConvert: true, preserveLicense: false }, opt);
15
- function reducer(acc, curr, index, original) {
16
- if (curr.typ == 'Comment' && options.removeComments) {
17
- if (!options.preserveLicense || !curr.val.startsWith('/*!')) {
18
- return acc;
32
+ return {
33
+ code: doRender(data, options, function reducer(acc, curr) {
34
+ if (curr.typ == 'Comment' && options.removeComments) {
35
+ if (!options.preserveLicense || !curr.val.startsWith('/*!')) {
36
+ return acc;
37
+ }
38
+ return acc + curr.val;
19
39
  }
20
- }
21
- return acc + renderToken(curr, options);
22
- }
23
- return { code: doRender(data, options, reducer, 0), stats: {
40
+ return acc + renderToken(curr, options, reducer);
41
+ }, 0), stats: {
24
42
  total: `${(performance.now() - startTime).toFixed(2)}ms`
25
- } };
43
+ }
44
+ };
26
45
  }
27
46
  // @ts-ignore
28
47
  function doRender(data, options, reducer, level = 0, indents = []) {
@@ -35,8 +54,10 @@ function doRender(data, options, reducer, level = 0, indents = []) {
35
54
  const indent = indents[level];
36
55
  const indentSub = indents[level + 1];
37
56
  switch (data.typ) {
57
+ case 'Declaration':
58
+ return `${data.nam}:${options.indent}${data.val.reduce(reducer, '')}`;
38
59
  case 'Comment':
39
- return options.removeComments ? '' : data.val;
60
+ return !options.removeComments || (options.preserveLicense && data.val.startsWith('/*!')) ? data.val : '';
40
61
  case 'StyleSheet':
41
62
  return data.chi.reduce((css, node) => {
42
63
  const str = doRender(node, options, reducer, level, indents);
@@ -57,9 +78,13 @@ function doRender(data, options, reducer, level = 0, indents = []) {
57
78
  let children = data.chi.reduce((css, node) => {
58
79
  let str;
59
80
  if (node.typ == 'Comment') {
60
- str = options.removeComments ? '' : node.val;
81
+ str = options.removeComments && (!options.preserveLicense || !node.val.startsWith('/*!')) ? '' : node.val;
61
82
  }
62
83
  else if (node.typ == 'Declaration') {
84
+ if (node.val.length == 0) {
85
+ console.error(`invalid declaration`, node);
86
+ return '';
87
+ }
63
88
  str = `${node.nam}:${options.indent}${node.val.reduce(reducer, '').trimEnd()};`;
64
89
  }
65
90
  else if (node.typ == 'AtRule' && !('chi' in node)) {
@@ -86,7 +111,18 @@ function doRender(data, options, reducer, level = 0, indents = []) {
86
111
  }
87
112
  return '';
88
113
  }
89
- function renderToken(token, options = {}) {
114
+ function renderToken(token, options = {}, reducer) {
115
+ if (reducer == null) {
116
+ reducer = function (acc, curr) {
117
+ if (curr.typ == 'Comment' && options.removeComments) {
118
+ if (!options.preserveLicense || !curr.val.startsWith('/*!')) {
119
+ return acc;
120
+ }
121
+ return acc + curr.val;
122
+ }
123
+ return acc + renderToken(curr, options, reducer);
124
+ };
125
+ }
90
126
  switch (token.typ) {
91
127
  case 'Color':
92
128
  if (options.minify || options.colorConvert) {
@@ -137,22 +173,19 @@ function renderToken(token, options = {}) {
137
173
  case 'UrlFunc':
138
174
  case 'Pseudo-class-func':
139
175
  // @ts-ignore
140
- return ( /* options.minify && 'Pseudo-class-func' == token.typ && token.val.slice(0, 2) == '::' ? token.val.slice(1) :*/token.val ?? '') + '(' + token.chi.reduce((acc, curr) => {
141
- if (options.removeComments && curr.typ == 'Comment') {
142
- if (!options.preserveLicense || !curr.val.startsWith('/*!')) {
143
- return acc;
144
- }
145
- }
146
- return acc + renderToken(curr, options);
147
- }, '') + ')';
176
+ return ( /* options.minify && 'Pseudo-class-func' == token.typ && token.val.slice(0, 2) == '::' ? token.val.slice(1) :*/token.val ?? '') + '(' + token.chi.reduce(reducer, '') + ')';
148
177
  case 'Includes':
149
178
  return '~=';
150
179
  case 'Dash-match':
151
180
  return '|=';
152
181
  case 'Lt':
153
182
  return '<';
183
+ case 'Lte':
184
+ return '<=';
154
185
  case 'Gt':
155
186
  return '>';
187
+ case 'Gte':
188
+ return '>=';
156
189
  case 'End-parens':
157
190
  return ')';
158
191
  case 'Attr-start':
@@ -170,37 +203,73 @@ function renderToken(token, options = {}) {
170
203
  case 'Important':
171
204
  return '!important';
172
205
  case 'Attr':
173
- return '[' + token.chi.reduce((acc, curr) => acc + renderToken(curr, options), '') + ']';
206
+ return '[' + token.chi.reduce(reducer, '') + ']';
174
207
  case 'Time':
175
- case 'Frequency':
176
208
  case 'Angle':
177
209
  case 'Length':
178
210
  case 'Dimension':
179
- const val = (+token.val).toString();
211
+ case 'Frequency':
212
+ case 'Resolution':
213
+ let val = reduceNumber(token.val);
214
+ let unit = token.unit;
215
+ if (token.typ == 'Angle') {
216
+ const angle = getAngle(token);
217
+ let v;
218
+ let value = val + unit;
219
+ for (const u of ['turn', 'deg', 'rad', 'grad']) {
220
+ if (token.unit == u) {
221
+ continue;
222
+ }
223
+ switch (u) {
224
+ case 'turn':
225
+ v = reduceNumber(angle);
226
+ if (v.length + 4 < value.length) {
227
+ val = v;
228
+ unit = u;
229
+ value = v + u;
230
+ }
231
+ break;
232
+ case 'deg':
233
+ v = reduceNumber(angle * 360);
234
+ if (v.length + 3 < value.length) {
235
+ val = v;
236
+ unit = u;
237
+ value = v + u;
238
+ }
239
+ break;
240
+ case 'rad':
241
+ v = reduceNumber(angle * (2 * Math.PI));
242
+ if (v.length + 3 < value.length) {
243
+ val = v;
244
+ unit = u;
245
+ value = v + u;
246
+ }
247
+ break;
248
+ case 'grad':
249
+ v = reduceNumber(angle * 400);
250
+ if (v.length + 4 < value.length) {
251
+ val = v;
252
+ unit = u;
253
+ value = v + u;
254
+ }
255
+ break;
256
+ }
257
+ }
258
+ }
180
259
  if (val === '0') {
181
- if (token.typ == 'Time') {
260
+ if (unit == 'Time') {
182
261
  return '0s';
183
262
  }
184
- if (token.typ == 'Frequency') {
263
+ if (unit == 'Frequency') {
185
264
  return '0Hz';
186
265
  }
187
266
  // @ts-ignore
188
- if (token.typ == 'Resolution') {
267
+ if (unit == 'Resolution') {
189
268
  return '0x';
190
269
  }
191
270
  return '0';
192
271
  }
193
- const chr = val.charAt(0);
194
- if (chr == '-') {
195
- const slice = val.slice(0, 2);
196
- if (slice == '-0') {
197
- return (val.length == 2 ? '0' : '-' + val.slice(2)) + token.unit;
198
- }
199
- }
200
- else if (chr == '0') {
201
- return val.slice(1) + token.unit;
202
- }
203
- return val + token.unit;
272
+ return val + unit;
204
273
  case 'Perc':
205
274
  return token.val + '%';
206
275
  case 'Number':
@@ -217,7 +286,7 @@ function renderToken(token, options = {}) {
217
286
  }
218
287
  return num;
219
288
  case 'Comment':
220
- if (options.removeComments) {
289
+ if (options.removeComments && (!options.preserveLicense || !token.val.startsWith('/*!'))) {
221
290
  return '';
222
291
  }
223
292
  case 'Url-token':
@@ -418,7 +418,7 @@ function cmyk2hex(token) {
418
418
  return `#${rgb.reduce((acc, curr) => acc + curr.toString(16).padStart(2, '0'), '')}`;
419
419
  }
420
420
  function getAngle(token) {
421
- if (token.typ == 'Dimension') {
421
+ if (token.typ == 'Angle') {
422
422
  switch (token.unit) {
423
423
  case 'deg':
424
424
  // @ts-ignore
@@ -491,4 +491,4 @@ function hsl2rgb(h, s, l, a = null) {
491
491
  return values;
492
492
  }
493
493
 
494
- export { COLORS_NAMES, NAMES_COLORS, cmyk2hex, hsl2Hex, hwb2hex, rgb2Hex };
494
+ export { COLORS_NAMES, NAMES_COLORS, cmyk2hex, getAngle, hsl2Hex, hwb2hex, rgb2Hex };
@@ -1,7 +1,13 @@
1
1
  import { parse as parse$1 } from '../lib/parser/parse.js';
2
2
  export { parseString, urlTokenMatcher } from '../lib/parser/parse.js';
3
- import '../lib/renderer/utils/color.js';
3
+ export { tokenize } from '../lib/parser/tokenize.js';
4
+ export { isAngle, isAtKeyword, isDigit, isDimension, isFrequency, isFunction, isHash, isHexColor, isHexDigit, isIdent, isIdentCodepoint, isIdentStart, isLength, isNewLine, isNumber, isPercentage, isPseudo, isResolution, isTime, isWhiteSpace, parseDimension } from '../lib/parser/utils/syntax.js';
5
+ export { getConfig } from '../lib/parser/utils/config.js';
6
+ export { matchType } from '../lib/parser/utils/type.js';
7
+ export { render, renderToken } from '../lib/renderer/render.js';
4
8
  import { transform as transform$1 } from '../lib/transform.js';
9
+ export { combinators, hasDeclaration, minify, minifyRule, reduceSelector } from '../lib/ast/minify.js';
10
+ export { walk } from '../lib/ast/walk.js';
5
11
  import { load } from './load.js';
6
12
  import { resolve } from '../lib/fs/resolve.js';
7
13
  export { dirname, matchUrl } from '../lib/fs/resolve.js';
package/dist/web/index.js CHANGED
@@ -3,6 +3,7 @@ export { parseString, urlTokenMatcher } from '../lib/parser/parse.js';
3
3
  export { tokenize } from '../lib/parser/tokenize.js';
4
4
  export { isAngle, isAtKeyword, isDigit, isDimension, isFrequency, isFunction, isHash, isHexColor, isHexDigit, isIdent, isIdentCodepoint, isIdentStart, isLength, isNewLine, isNumber, isPercentage, isPseudo, isResolution, isTime, isWhiteSpace, parseDimension } from '../lib/parser/utils/syntax.js';
5
5
  export { getConfig } from '../lib/parser/utils/config.js';
6
+ export { matchType } from '../lib/parser/utils/type.js';
6
7
  export { render, renderToken } from '../lib/renderer/render.js';
7
8
  import { transform as transform$1 } from '../lib/transform.js';
8
9
  export { combinators, hasDeclaration, minify, minifyRule, reduceSelector } from '../lib/ast/minify.js';
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@tbela99/css-parser",
3
3
  "description": "CSS parser for node and the browser",
4
- "version": "0.0.1-rc2",
4
+ "version": "0.0.1-rc4",
5
5
  "exports": {
6
- ".": "./dist/index.js",
6
+ ".": "./dist/node/index.js",
7
7
  "./umd": "./dist/index-umd-web.js",
8
8
  "./web": "./dist/web/index.js",
9
9
  "./cjs": "./dist/index.cjs"
@@ -24,14 +24,16 @@
24
24
  "keywords": [
25
25
  "parser",
26
26
  "css",
27
- "css parser",
28
27
  "css-parser",
29
28
  "node",
30
29
  "ast",
30
+ "nesting",
31
+ "nested",
32
+ "compiler",
31
33
  "browser",
32
- "css nesting",
33
- "css compiler",
34
- "nested css"
34
+ "css-nesting",
35
+ "css-compiler",
36
+ "nested-css"
35
37
  ],
36
38
  "author": "Thierry Bela",
37
39
  "license": "MIT OR LGPL-3.0",
@@ -41,20 +43,18 @@
41
43
  "homepage": "https://github.com/tbela99/css-parser#readme",
42
44
  "devDependencies": {
43
45
  "@esm-bundle/chai": "^4.3.4-fix.0",
44
- "@rollup/plugin-commonjs": "^25.0.2",
46
+ "@rollup/plugin-commonjs": "^25.0.4",
45
47
  "@rollup/plugin-json": "^6.0.0",
46
- "@rollup/plugin-node-resolve": "^15.0.1",
47
- "@rollup/plugin-terser": "^0.4.3",
48
- "@rollup/plugin-typescript": "^11.0.0",
48
+ "@rollup/plugin-node-resolve": "^15.1.0",
49
+ "@rollup/plugin-typescript": "^11.1.2",
49
50
  "@types/chai": "^4.3.5",
50
51
  "@types/mocha": "^10.0.1",
51
- "@types/node": "^18.15.10",
52
- "@web/test-runner": "^0.16.1",
53
- "@webref/css": "^6.5.9",
52
+ "@types/node": "^20.4.10",
53
+ "@web/test-runner": "^0.17.0",
54
54
  "c8": "^8.0.1",
55
55
  "mocha": "^10.2.0",
56
- "rollup": "^3.20.1",
57
- "rollup-plugin-dts": "^5.3.0",
58
- "tslib": "^2.5.0"
56
+ "rollup": "^3.28.0",
57
+ "rollup-plugin-dts": "^5.3.1",
58
+ "tslib": "^2.6.1"
59
59
  }
60
60
  }
package/.gitattributes DELETED
@@ -1,22 +0,0 @@
1
- /test/ export-ignore
2
- /docs/ export-ignore
3
- /benchmark
4
- /tools/ export-ignore
5
- /package-lock.json export-ignore
6
- /.gitignore export-ignore
7
- /.gitattributes export-ignore
8
- /coverage/ export-ignore
9
- /rollup.config.mjs export-ignore
10
- /tsconfig.json export-ignore
11
- # exclude all files in test/ from stats
12
- /test/** linguist-vendored
13
- /docs/** linguist-vendored
14
- /tools/** linguist-vendored
15
- /dist/** linguist-vendored
16
- /coverage/** linguist-vendored
17
- #
18
- # do not replace lf by crlf
19
- *.css text
20
- *.json text
21
- text eol=lf
22
-
package/dist/index.js DELETED
@@ -1,10 +0,0 @@
1
- export { parse, transform } from './node/index.js';
2
- export { parseString, urlTokenMatcher } from './lib/parser/parse.js';
3
- export { tokenize } from './lib/parser/tokenize.js';
4
- export { isAngle, isAtKeyword, isDigit, isDimension, isFrequency, isFunction, isHash, isHexColor, isHexDigit, isIdent, isIdentCodepoint, isIdentStart, isLength, isNewLine, isNumber, isPercentage, isPseudo, isResolution, isTime, isWhiteSpace, parseDimension } from './lib/parser/utils/syntax.js';
5
- export { getConfig } from './lib/parser/utils/config.js';
6
- export { render, renderToken } from './lib/renderer/render.js';
7
- export { combinators, hasDeclaration, minify, minifyRule, reduceSelector } from './lib/ast/minify.js';
8
- export { walk } from './lib/ast/walk.js';
9
- export { load } from './node/load.js';
10
- export { dirname, matchUrl, resolve } from './lib/fs/resolve.js';