cssstyle 5.3.7 → 6.0.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 (93) hide show
  1. package/lib/CSSStyleDeclaration.js +359 -395
  2. package/lib/generated/.gitkeep +0 -0
  3. package/lib/generated/propertyDefinitions.js +3685 -1498
  4. package/lib/generated/propertyDescriptors.js +1705 -0
  5. package/lib/index.js +9 -0
  6. package/lib/normalize.js +127 -253
  7. package/lib/parsers.js +152 -164
  8. package/lib/properties/background.js +201 -202
  9. package/lib/properties/backgroundAttachment.js +35 -33
  10. package/lib/properties/backgroundClip.js +35 -33
  11. package/lib/properties/backgroundColor.js +26 -24
  12. package/lib/properties/backgroundImage.js +36 -34
  13. package/lib/properties/backgroundOrigin.js +35 -33
  14. package/lib/properties/backgroundPosition.js +57 -57
  15. package/lib/properties/backgroundRepeat.js +40 -37
  16. package/lib/properties/backgroundSize.js +38 -34
  17. package/lib/properties/border.js +41 -34
  18. package/lib/properties/{webkitBorderEndColor.js → borderBlockEndColor.js} +26 -22
  19. package/lib/properties/{webkitBorderAfterColor.js → borderBlockStartColor.js} +26 -22
  20. package/lib/properties/borderBottom.js +40 -36
  21. package/lib/properties/borderBottomColor.js +25 -21
  22. package/lib/properties/borderBottomStyle.js +25 -21
  23. package/lib/properties/borderBottomWidth.js +28 -24
  24. package/lib/properties/borderCollapse.js +25 -21
  25. package/lib/properties/borderColor.js +36 -33
  26. package/lib/properties/{webkitBorderStartColor.js → borderInlineEndColor.js} +26 -22
  27. package/lib/properties/borderInlineStartColor.js +49 -0
  28. package/lib/properties/borderLeft.js +40 -36
  29. package/lib/properties/borderLeftColor.js +25 -21
  30. package/lib/properties/borderLeftStyle.js +25 -21
  31. package/lib/properties/borderLeftWidth.js +28 -24
  32. package/lib/properties/borderRight.js +40 -36
  33. package/lib/properties/borderRightColor.js +25 -21
  34. package/lib/properties/borderRightStyle.js +25 -21
  35. package/lib/properties/borderRightWidth.js +28 -24
  36. package/lib/properties/borderSpacing.js +33 -29
  37. package/lib/properties/borderStyle.js +36 -33
  38. package/lib/properties/borderTop.js +40 -36
  39. package/lib/properties/borderTopColor.js +25 -21
  40. package/lib/properties/borderTopStyle.js +25 -21
  41. package/lib/properties/borderTopWidth.js +28 -24
  42. package/lib/properties/borderWidth.js +36 -33
  43. package/lib/properties/bottom.js +27 -23
  44. package/lib/properties/clear.js +25 -21
  45. package/lib/properties/clip.js +37 -31
  46. package/lib/properties/color.js +25 -21
  47. package/lib/properties/display.js +36 -30
  48. package/lib/properties/flex.js +53 -45
  49. package/lib/properties/flexBasis.js +28 -26
  50. package/lib/properties/flexGrow.js +28 -26
  51. package/lib/properties/flexShrink.js +28 -26
  52. package/lib/properties/float.js +25 -21
  53. package/lib/properties/floodColor.js +25 -21
  54. package/lib/properties/font.js +89 -118
  55. package/lib/properties/fontFamily.js +38 -33
  56. package/lib/properties/fontSize.js +29 -27
  57. package/lib/properties/fontStyle.js +38 -34
  58. package/lib/properties/fontVariant.js +35 -33
  59. package/lib/properties/fontWeight.js +33 -31
  60. package/lib/properties/height.js +28 -24
  61. package/lib/properties/left.js +27 -23
  62. package/lib/properties/lightingColor.js +25 -21
  63. package/lib/properties/lineHeight.js +28 -26
  64. package/lib/properties/margin.js +40 -34
  65. package/lib/properties/marginBottom.js +30 -27
  66. package/lib/properties/marginLeft.js +30 -27
  67. package/lib/properties/marginRight.js +30 -27
  68. package/lib/properties/marginTop.js +30 -27
  69. package/lib/properties/opacity.js +27 -23
  70. package/lib/properties/outlineColor.js +25 -21
  71. package/lib/properties/padding.js +40 -34
  72. package/lib/properties/paddingBottom.js +31 -28
  73. package/lib/properties/paddingLeft.js +31 -28
  74. package/lib/properties/paddingRight.js +31 -28
  75. package/lib/properties/paddingTop.js +31 -28
  76. package/lib/properties/right.js +27 -23
  77. package/lib/properties/stopColor.js +25 -21
  78. package/lib/properties/{webkitBorderBeforeColor.js → textEmphasisColor.js} +26 -22
  79. package/lib/properties/top.js +27 -23
  80. package/lib/properties/webkitTextFillColor.js +25 -21
  81. package/lib/properties/webkitTextStrokeColor.js +25 -21
  82. package/lib/properties/width.js +28 -24
  83. package/lib/utils/propertyDescriptors.js +129 -42
  84. package/lib/utils/strings.js +11 -156
  85. package/package.json +11 -21
  86. package/lib/generated/allProperties.js +0 -653
  87. package/lib/generated/implementedProperties.js +0 -1466
  88. package/lib/generated/properties.js +0 -6637
  89. package/lib/properties/webkitColumnRuleColor.js +0 -45
  90. package/lib/properties/webkitTapHighlightColor.js +0 -45
  91. package/lib/properties/webkitTextEmphasisColor.js +0 -45
  92. package/lib/utils/allExtraProperties.js +0 -155
  93. package/lib/utils/camelize.js +0 -37
package/lib/parsers.js CHANGED
@@ -7,8 +7,12 @@ const {
7
7
  const { next: syntaxes } = require("@csstools/css-syntax-patches-for-csstree");
8
8
  const csstree = require("css-tree");
9
9
  const { LRUCache } = require("lru-cache");
10
+ const propertyDefinitions = require("./generated/propertyDefinitions");
10
11
  const { asciiLowercase } = require("./utils/strings");
11
12
 
13
+ // Constants
14
+ const CALC_FUNC_NAMES = "(?:a?(?:cos|sin|tan)|abs|atan2|calc|clamp|exp|hypot|log|max|min|mod|pow|rem|round|sign|sqrt)";
15
+
12
16
  // CSS global keywords
13
17
  // @see https://drafts.csswg.org/css-cascade-5/#defaulting-keywords
14
18
  const GLOBAL_KEYS = new Set(["initial", "inherit", "unset", "revert", "revert-layer"]);
@@ -76,8 +80,6 @@ const AST_TYPES = Object.freeze({
76
80
  });
77
81
 
78
82
  // Regular expressions
79
- const CALC_FUNC_NAMES =
80
- "(?:a?(?:cos|sin|tan)|abs|atan2|calc|clamp|exp|hypot|log|max|min|mod|pow|rem|round|sign|sqrt)";
81
83
  const calcRegEx = new RegExp(`^${CALC_FUNC_NAMES}\\(`);
82
84
  const calcContainedRegEx = new RegExp(`(?<=[*/\\s(])${CALC_FUNC_NAMES}\\(`);
83
85
  const calcNameRegEx = new RegExp(`^${CALC_FUNC_NAMES}$`);
@@ -98,14 +100,14 @@ const lruCache = new LRUCache({
98
100
  * @param {string|number|null|undefined} value - The value to prepare.
99
101
  * @returns {string} The prepared value.
100
102
  */
101
- const prepareValue = (value) => {
103
+ function prepareValue(value) {
102
104
  // `null` is converted to an empty string.
103
105
  // @see https://webidl.spec.whatwg.org/#LegacyNullToEmptyString
104
106
  if (value === null) {
105
107
  return "";
106
108
  }
107
109
  return `${value}`.trim();
108
- };
110
+ }
109
111
 
110
112
  /**
111
113
  * Checks if the value is a global keyword.
@@ -113,9 +115,9 @@ const prepareValue = (value) => {
113
115
  * @param {string} val - The value to check.
114
116
  * @returns {boolean} True if the value is a global keyword, false otherwise.
115
117
  */
116
- const isGlobalKeyword = (val) => {
118
+ function isGlobalKeyword(val) {
117
119
  return GLOBAL_KEYS.has(asciiLowercase(val));
118
- };
120
+ }
119
121
 
120
122
  /**
121
123
  * Checks if the value starts with or contains a CSS var() function.
@@ -123,9 +125,9 @@ const isGlobalKeyword = (val) => {
123
125
  * @param {string} val - The value to check.
124
126
  * @returns {boolean} True if the value contains a var() function, false otherwise.
125
127
  */
126
- const hasVarFunc = (val) => {
128
+ function hasVarFunc(val) {
127
129
  return varRegEx.test(val) || varContainedRegEx.test(val);
128
- };
130
+ }
129
131
 
130
132
  /**
131
133
  * Checks if the value starts with or contains CSS calc() or math functions.
@@ -133,26 +135,20 @@ const hasVarFunc = (val) => {
133
135
  * @param {string} val - The value to check.
134
136
  * @returns {boolean} True if the value contains calc() or math functions, false otherwise.
135
137
  */
136
- const hasCalcFunc = (val) => {
138
+ function hasCalcFunc(val) {
137
139
  return calcRegEx.test(val) || calcContainedRegEx.test(val);
138
- };
140
+ }
139
141
 
140
142
  /**
141
143
  * Parses a CSS string into an AST.
142
144
  *
143
145
  * @param {string} val - The CSS string to parse.
144
146
  * @param {object} opt - The options for parsing.
145
- * @param {boolean} [toObject=false] - Whether to return a plain object.
146
- * @returns {object} The AST or a plain object.
147
+ * @returns {object} The AST.
147
148
  */
148
- const parseCSS = (val, opt, toObject = false) => {
149
- val = prepareValue(val);
150
- const ast = cssTree.parse(val, opt);
151
- if (toObject) {
152
- return cssTree.toPlainObject(ast);
153
- }
154
- return ast;
155
- };
149
+ function parseCSS(val, opt) {
150
+ return cssTree.parse(prepareValue(val), opt);
151
+ }
156
152
 
157
153
  /**
158
154
  * Checks if the value is a valid property value.
@@ -162,20 +158,14 @@ const parseCSS = (val, opt, toObject = false) => {
162
158
  * @param {string} val - The property value.
163
159
  * @returns {boolean} True if the value is valid, false otherwise.
164
160
  */
165
- const isValidPropertyValue = (prop, val) => {
161
+ function isValidPropertyValue(prop, val) {
162
+ if (!propertyDefinitions.has(prop)) {
163
+ return false;
164
+ }
166
165
  val = prepareValue(val);
167
166
  if (val === "") {
168
167
  return true;
169
168
  }
170
- // cssTree.lexer does not support deprecated system colors
171
- // @see https://github.com/w3c/webref/issues/1519#issuecomment-3120290261
172
- // @see https://github.com/w3c/webref/issues/1647
173
- if (SYS_COLORS.has(asciiLowercase(val))) {
174
- if (/^(?:-webkit-)?(?:[a-z][a-z\d]*-)*color$/i.test(prop)) {
175
- return true;
176
- }
177
- return false;
178
- }
179
169
  const cacheKey = `isValidPropertyValue_${prop}_${val}`;
180
170
  const cachedValue = lruCache.get(cacheKey);
181
171
  if (typeof cachedValue === "boolean") {
@@ -193,7 +183,7 @@ const isValidPropertyValue = (prop, val) => {
193
183
  }
194
184
  lruCache.set(cacheKey, result);
195
185
  return result;
196
- };
186
+ }
197
187
 
198
188
  /**
199
189
  * Resolves CSS math functions.
@@ -202,7 +192,7 @@ const isValidPropertyValue = (prop, val) => {
202
192
  * @param {object} [opt={ format: "specifiedValue" }] - The options for resolving.
203
193
  * @returns {string|undefined} The resolved value.
204
194
  */
205
- const resolveCalc = (val, opt = { format: "specifiedValue" }) => {
195
+ function resolveCalc(val, opt = { format: "specifiedValue" }) {
206
196
  val = prepareValue(val);
207
197
  if (val === "" || hasVarFunc(val) || !hasCalcFunc(val)) {
208
198
  return val;
@@ -212,13 +202,12 @@ const resolveCalc = (val, opt = { format: "specifiedValue" }) => {
212
202
  if (typeof cachedValue === "string") {
213
203
  return cachedValue;
214
204
  }
215
- const obj = parseCSS(val, { context: "value" }, true);
216
- if (!obj?.children) {
205
+ const ast = parseCSS(val, { context: "value" });
206
+ if (!ast?.children) {
217
207
  return;
218
208
  }
219
- const { children: items } = obj;
220
209
  const values = [];
221
- for (const item of items) {
210
+ for (const item of ast.children) {
222
211
  const { type: itemType, name: itemName, value: itemValue } = item;
223
212
  if (itemType === AST_TYPES.FUNCTION) {
224
213
  const value = cssTree
@@ -240,7 +229,7 @@ const resolveCalc = (val, opt = { format: "specifiedValue" }) => {
240
229
  const resolvedValue = values.join(" ");
241
230
  lruCache.set(cacheKey, resolvedValue);
242
231
  return resolvedValue;
243
- };
232
+ }
244
233
 
245
234
  /**
246
235
  * Parses a property value.
@@ -251,8 +240,11 @@ const resolveCalc = (val, opt = { format: "specifiedValue" }) => {
251
240
  * @param {object} [opt={}] - The options for parsing.
252
241
  * @returns {string|Array<object>|undefined} The parsed value.
253
242
  */
254
- const parsePropertyValue = (prop, val, opt = {}) => {
255
- const { caseSensitive, inArray } = opt;
243
+ function parsePropertyValue(prop, val, opt = {}) {
244
+ if (!propertyDefinitions.has(prop)) {
245
+ return;
246
+ }
247
+ const { caseSensitive } = opt;
256
248
  val = prepareValue(val);
257
249
  if (val === "" || hasVarFunc(val)) {
258
250
  return val;
@@ -269,41 +261,18 @@ const parsePropertyValue = (prop, val, opt = {}) => {
269
261
  const cachedValue = lruCache.get(cacheKey);
270
262
  if (cachedValue === false) {
271
263
  return;
272
- } else if (inArray) {
273
- if (Array.isArray(cachedValue)) {
274
- return cachedValue;
275
- }
276
- } else if (typeof cachedValue === "string") {
264
+ } else if (cachedValue !== undefined) {
277
265
  return cachedValue;
278
266
  }
279
267
  let parsedValue;
280
268
  const lowerCasedValue = asciiLowercase(val);
281
269
  if (GLOBAL_KEYS.has(lowerCasedValue)) {
282
- if (inArray) {
283
- parsedValue = [
284
- {
285
- type: AST_TYPES.GLOBAL_KEYWORD,
286
- name: lowerCasedValue
287
- }
288
- ];
289
- } else {
290
- parsedValue = lowerCasedValue;
291
- }
292
- } else if (SYS_COLORS.has(lowerCasedValue)) {
293
- if (/^(?:(?:-webkit-)?(?:[a-z][a-z\d]*-)*color|border)$/i.test(prop)) {
294
- if (inArray) {
295
- parsedValue = [
296
- {
297
- type: AST_TYPES.IDENTIFIER,
298
- name: lowerCasedValue
299
- }
300
- ];
301
- } else {
302
- parsedValue = lowerCasedValue;
270
+ parsedValue = [
271
+ {
272
+ type: AST_TYPES.GLOBAL_KEYWORD,
273
+ name: lowerCasedValue
303
274
  }
304
- } else {
305
- parsedValue = false;
306
- }
275
+ ];
307
276
  } else {
308
277
  try {
309
278
  const ast = parseCSS(val, {
@@ -312,9 +281,9 @@ const parsePropertyValue = (prop, val, opt = {}) => {
312
281
  const { error, matched } = cssTree.lexer.matchProperty(prop, ast);
313
282
  if (error || !matched) {
314
283
  parsedValue = false;
315
- } else if (inArray) {
316
- const obj = cssTree.toPlainObject(ast);
317
- const items = obj.children;
284
+ } else {
285
+ const items = ast.children;
286
+ const itemCount = items.size;
318
287
  const values = [];
319
288
  for (const item of items) {
320
289
  const { children, name, type, value, unit } = item;
@@ -332,12 +301,12 @@ const parsePropertyValue = (prop, val, opt = {}) => {
332
301
  .generate(item)
333
302
  .replace(/\)(?!\)|\s|,)/g, ") ")
334
303
  .trim();
335
- const raw = items.length === 1 ? val : css;
304
+ const raw = itemCount === 1 ? val : css;
336
305
  // Remove "${name}(" from the start and ")" from the end
337
306
  const itemValue = raw.slice(name.length + 1, -1).trim();
338
307
  if (name === "calc") {
339
- if (children.length === 1) {
340
- const [child] = children;
308
+ if (children.size === 1) {
309
+ const child = children.first;
341
310
  if (child.type === AST_TYPES.NUMBER) {
342
311
  values.push({
343
312
  type: AST_TYPES.CALC,
@@ -391,8 +360,6 @@ const parsePropertyValue = (prop, val, opt = {}) => {
391
360
  }
392
361
  }
393
362
  parsedValue = values;
394
- } else {
395
- parsedValue = val;
396
363
  }
397
364
  } catch {
398
365
  parsedValue = false;
@@ -403,18 +370,18 @@ const parsePropertyValue = (prop, val, opt = {}) => {
403
370
  return;
404
371
  }
405
372
  return parsedValue;
406
- };
373
+ }
407
374
 
408
375
  /**
409
376
  * Parses a numeric value (number, dimension, percentage).
410
- * Helper function for parseNumber, parseLength, etc.
377
+ * Helper function for serializeNumber, serializeLength, etc.
411
378
  *
412
379
  * @param {Array<object>} val - The AST value.
413
380
  * @param {object} [opt={}] - The options for parsing.
414
381
  * @param {Function} validateType - Function to validate the node type.
415
382
  * @returns {object|undefined} The parsed result containing num and unit, or undefined.
416
383
  */
417
- const parseNumericValue = (val, opt, validateType) => {
384
+ function parseNumericValue(val, opt, validateType) {
418
385
  const [item] = val;
419
386
  const { type, value, unit } = item ?? {};
420
387
  if (!validateType(type, value, unit)) {
@@ -438,31 +405,31 @@ const parseNumericValue = (val, opt, validateType) => {
438
405
  unit: unit ? asciiLowercase(unit) : null,
439
406
  type
440
407
  };
441
- };
408
+ }
442
409
 
443
410
  /**
444
- * Parses a <number> value.
411
+ * Serializes a <number> value.
445
412
  *
446
413
  * @param {Array<object>} val - The AST value.
447
414
  * @param {object} [opt={}] - The options for parsing.
448
415
  * @returns {string|undefined} The parsed number.
449
416
  */
450
- const parseNumber = (val, opt = {}) => {
417
+ function serializeNumber(val, opt = {}) {
451
418
  const res = parseNumericValue(val, opt, (type) => type === AST_TYPES.NUMBER);
452
419
  if (!res) {
453
420
  return;
454
421
  }
455
422
  return `${res.num}`;
456
- };
423
+ }
457
424
 
458
425
  /**
459
- * Parses a <length> value.
426
+ * Serializes an <angle> value.
460
427
  *
461
428
  * @param {Array<object>} val - The AST value.
462
429
  * @param {object} [opt={}] - The options for parsing.
463
- * @returns {string|undefined} The parsed length.
430
+ * @returns {string|undefined} The serialized angle.
464
431
  */
465
- const parseLength = (val, opt = {}) => {
432
+ function serializeAngle(val, opt = {}) {
466
433
  const res = parseNumericValue(
467
434
  val,
468
435
  opt,
@@ -472,67 +439,85 @@ const parseLength = (val, opt = {}) => {
472
439
  return;
473
440
  }
474
441
  const { num, unit } = res;
475
- if (num === 0 && !unit) {
476
- return `${num}px`;
477
- } else if (unit) {
442
+ if (unit) {
443
+ if (!/^(?:deg|g?rad|turn)$/i.test(unit)) {
444
+ return;
445
+ }
478
446
  return `${num}${unit}`;
447
+ } else if (num === 0) {
448
+ return `${num}deg`;
479
449
  }
480
- };
450
+ }
481
451
 
482
452
  /**
483
- * Parses a <percentage> value.
453
+ * Serializes a <length> value.
484
454
  *
485
455
  * @param {Array<object>} val - The AST value.
486
456
  * @param {object} [opt={}] - The options for parsing.
487
- * @returns {string|undefined} The parsed percentage.
457
+ * @returns {string|undefined} The serialized length.
488
458
  */
489
- const parsePercentage = (val, opt = {}) => {
459
+ function serializeLength(val, opt = {}) {
490
460
  const res = parseNumericValue(
491
461
  val,
492
462
  opt,
493
- (type, value) => type === AST_TYPES.PERCENTAGE || (type === AST_TYPES.NUMBER && value === "0")
463
+ (type, value) => type === AST_TYPES.DIMENSION || (type === AST_TYPES.NUMBER && value === "0")
494
464
  );
495
465
  if (!res) {
496
466
  return;
497
467
  }
498
- const { num } = res;
499
- return `${num}%`;
500
- };
468
+ const { num, unit } = res;
469
+ if (num === 0 && !unit) {
470
+ return `${num}px`;
471
+ } else if (unit) {
472
+ return `${num}${unit}`;
473
+ }
474
+ }
501
475
 
502
476
  /**
503
- * Parses an <angle> value.
477
+ * Serializes a <dimension> value, e.g. <frequency>, <time> and <resolution>.
504
478
  *
505
479
  * @param {Array<object>} val - The AST value.
506
480
  * @param {object} [opt={}] - The options for parsing.
507
- * @returns {string|undefined} The parsed angle.
481
+ * @returns {string|undefined} The serialized dimension.
508
482
  */
509
- const parseAngle = (val, opt = {}) => {
510
- const res = parseNumericValue(
511
- val,
512
- opt,
513
- (type, value) => type === AST_TYPES.DIMENSION || (type === AST_TYPES.NUMBER && value === "0")
514
- );
483
+ function serializeDimension(val, opt = {}) {
484
+ const res = parseNumericValue(val, opt, (type) => type === AST_TYPES.DIMENSION);
515
485
  if (!res) {
516
486
  return;
517
487
  }
518
488
  const { num, unit } = res;
519
489
  if (unit) {
520
- if (!/^(?:deg|g?rad|turn)$/i.test(unit)) {
521
- return;
522
- }
523
490
  return `${num}${unit}`;
524
- } else if (num === 0) {
525
- return `${num}deg`;
526
491
  }
527
- };
492
+ }
528
493
 
529
494
  /**
530
- * Parses a <url> value.
495
+ * Serializes a <percentage> value.
531
496
  *
532
497
  * @param {Array<object>} val - The AST value.
533
- * @returns {string|undefined} The parsed url.
498
+ * @param {object} [opt={}] - The options for parsing.
499
+ * @returns {string|undefined} The serialized percentage.
534
500
  */
535
- const parseUrl = (val) => {
501
+ function serializePercentage(val, opt = {}) {
502
+ const res = parseNumericValue(
503
+ val,
504
+ opt,
505
+ (type, value) => type === AST_TYPES.PERCENTAGE || (type === AST_TYPES.NUMBER && value === "0")
506
+ );
507
+ if (!res) {
508
+ return;
509
+ }
510
+ const { num } = res;
511
+ return `${num}%`;
512
+ }
513
+
514
+ /**
515
+ * Serializes a <url> value.
516
+ *
517
+ * @param {Array<object>} val - The AST value.
518
+ * @returns {string|undefined} The serialized url.
519
+ */
520
+ function serializeURL(val) {
536
521
  const [item] = val;
537
522
  const { type, value } = item ?? {};
538
523
  if (type !== AST_TYPES.URL) {
@@ -540,15 +525,15 @@ const parseUrl = (val) => {
540
525
  }
541
526
  const str = value.replace(/\\\\/g, "\\").replaceAll('"', '\\"');
542
527
  return `url("${str}")`;
543
- };
528
+ }
544
529
 
545
530
  /**
546
- * Parses a <string> value.
531
+ * Serializes a <string> value.
547
532
  *
548
533
  * @param {Array<object>} val - The AST value.
549
- * @returns {string|undefined} The parsed string.
534
+ * @returns {string|undefined} The serialized string.
550
535
  */
551
- const parseString = (val) => {
536
+ function serializeString(val) {
552
537
  const [item] = val;
553
538
  const { type, value } = item ?? {};
554
539
  if (type !== AST_TYPES.STRING) {
@@ -556,15 +541,15 @@ const parseString = (val) => {
556
541
  }
557
542
  const str = value.replace(/\\\\/g, "\\").replaceAll('"', '\\"');
558
543
  return `"${str}"`;
559
- };
544
+ }
560
545
 
561
546
  /**
562
- * Parses a <color> value.
547
+ * Serializes a <color> value.
563
548
  *
564
549
  * @param {Array<object>} val - The AST value.
565
- * @returns {string|undefined} The parsed color.
550
+ * @returns {string|undefined} The serialized color.
566
551
  */
567
- const parseColor = (val) => {
552
+ function serializeColor(val) {
568
553
  const [item] = val;
569
554
  const { name, type, value } = item ?? {};
570
555
  switch (type) {
@@ -600,15 +585,15 @@ const parseColor = (val) => {
600
585
  }
601
586
  default:
602
587
  }
603
- };
588
+ }
604
589
 
605
590
  /**
606
- * Parses a <gradient> value.
591
+ * Serializes a <gradient> value.
607
592
  *
608
593
  * @param {Array<object>} val - The AST value.
609
- * @returns {string|undefined} The parsed gradient.
594
+ * @returns {string|undefined} The serialized gradient.
610
595
  */
611
- const parseGradient = (val) => {
596
+ function serializeGradient(val) {
612
597
  const [item] = val;
613
598
  const { name, type, value } = item ?? {};
614
599
  if (type !== AST_TYPES.FUNCTION) {
@@ -620,7 +605,7 @@ const parseGradient = (val) => {
620
605
  if (res) {
621
606
  return res;
622
607
  }
623
- };
608
+ }
624
609
 
625
610
  /**
626
611
  * Resolves a keyword value.
@@ -629,7 +614,7 @@ const parseGradient = (val) => {
629
614
  * @param {object} [opt={}] - The options for parsing.
630
615
  * @returns {string|undefined} The resolved keyword or undefined.
631
616
  */
632
- const resolveKeywordValue = (value, opt = {}) => {
617
+ function resolveKeywordValue(value, opt = {}) {
633
618
  const [{ name, type }] = value;
634
619
  const { length } = opt;
635
620
  switch (type) {
@@ -644,7 +629,7 @@ const resolveKeywordValue = (value, opt = {}) => {
644
629
  }
645
630
  default:
646
631
  }
647
- };
632
+ }
648
633
 
649
634
  /**
650
635
  * Resolves a function value.
@@ -653,7 +638,7 @@ const resolveKeywordValue = (value, opt = {}) => {
653
638
  * @param {object} [opt={}] - The options for parsing.
654
639
  * @returns {string|undefined} The resolved function or undefined.
655
640
  */
656
- const resolveFunctionValue = (value, opt = {}) => {
641
+ function resolveFunctionValue(value, opt = {}) {
657
642
  const [{ name, type, value: itemValue }] = value;
658
643
  const { length } = opt;
659
644
  switch (type) {
@@ -671,16 +656,16 @@ const resolveFunctionValue = (value, opt = {}) => {
671
656
  }
672
657
  default:
673
658
  }
674
- };
659
+ }
675
660
 
676
661
  /**
677
- * Resolves a length or percentage or number value.
662
+ * Resolves a numeric value.
678
663
  *
679
- * @param {Array<object>} value - The AST node array containing the value.
664
+ * @param {Array<object>} value - The AST node array containing the numeric value.
680
665
  * @param {object} [opt={}] - The options for parsing.
681
666
  * @returns {string|undefined} The resolved length/percentage/number or undefined.
682
667
  */
683
- const resolveNumericValue = (value, opt = {}) => {
668
+ function resolveNumericValue(value, opt = {}) {
684
669
  const [{ name, type: itemType, value: itemValue }] = value;
685
670
  const { length, type } = opt;
686
671
  switch (itemType) {
@@ -689,9 +674,11 @@ const resolveNumericValue = (value, opt = {}) => {
689
674
  }
690
675
  case AST_TYPES.DIMENSION: {
691
676
  if (type === "angle") {
692
- return parseAngle(value, opt);
677
+ return serializeAngle(value, opt);
678
+ } else if (type === "length") {
679
+ return serializeLength(value, opt);
693
680
  }
694
- return parseLength(value, opt);
681
+ return serializeDimension(value, opt);
695
682
  }
696
683
  case AST_TYPES.GLOBAL_KEYWORD: {
697
684
  if (length > 1) {
@@ -705,25 +692,25 @@ const resolveNumericValue = (value, opt = {}) => {
705
692
  case AST_TYPES.NUMBER: {
706
693
  switch (type) {
707
694
  case "angle": {
708
- return parseAngle(value, opt);
695
+ return serializeAngle(value, opt);
709
696
  }
710
697
  case "length": {
711
- return parseLength(value, opt);
698
+ return serializeLength(value, opt);
712
699
  }
713
700
  case "percentage": {
714
- return parsePercentage(value, opt);
701
+ return serializePercentage(value, opt);
715
702
  }
716
703
  default: {
717
- return parseNumber(value, opt);
704
+ return serializeNumber(value, opt);
718
705
  }
719
706
  }
720
707
  }
721
708
  case AST_TYPES.PERCENTAGE: {
722
- return parsePercentage(value, opt);
709
+ return serializePercentage(value, opt);
723
710
  }
724
711
  default:
725
712
  }
726
- };
713
+ }
727
714
 
728
715
  /**
729
716
  * Resolves a color value.
@@ -732,7 +719,7 @@ const resolveNumericValue = (value, opt = {}) => {
732
719
  * @param {object} [opt={}] - The options for parsing.
733
720
  * @returns {string|undefined} The resolved color or undefined.
734
721
  */
735
- const resolveColorValue = (value, opt = {}) => {
722
+ function resolveColorValue(value, opt = {}) {
736
723
  const [{ name, type }] = value;
737
724
  const { length } = opt;
738
725
  switch (type) {
@@ -743,19 +730,19 @@ const resolveColorValue = (value, opt = {}) => {
743
730
  return name;
744
731
  }
745
732
  default: {
746
- return parseColor(value, opt);
733
+ return serializeColor(value, opt);
747
734
  }
748
735
  }
749
- };
736
+ }
750
737
 
751
738
  /**
752
- * Resolves a gradient or URL value.
739
+ * Resolves an image value.
753
740
  *
754
- * @param {Array<object>} value - The AST node array containing the color value.
741
+ * @param {Array<object>} value - The AST node array containing the image value.
755
742
  * @param {object} [opt={}] - The options for parsing.
756
743
  * @returns {string|undefined} The resolved gradient/url or undefined.
757
744
  */
758
- const resolveGradientUrlValue = (value, opt = {}) => {
745
+ function resolveImageValue(value, opt = {}) {
759
746
  const [{ name, type }] = value;
760
747
  const { length } = opt;
761
748
  switch (type) {
@@ -769,13 +756,13 @@ const resolveGradientUrlValue = (value, opt = {}) => {
769
756
  return name;
770
757
  }
771
758
  case AST_TYPES.URL: {
772
- return parseUrl(value, opt);
759
+ return serializeURL(value, opt);
773
760
  }
774
761
  default: {
775
- return parseGradient(value, opt);
762
+ return serializeGradient(value, opt);
776
763
  }
777
764
  }
778
- };
765
+ }
779
766
 
780
767
  /**
781
768
  * Resolves a border shorthand value.
@@ -785,7 +772,7 @@ const resolveGradientUrlValue = (value, opt = {}) => {
785
772
  * @param {Map} parsedValues - The Map of parsed values.
786
773
  * @returns {Array|string|undefined} - The resolved [prop, value] pair, keyword or undefined.
787
774
  */
788
- const resolveBorderShorthandValue = (value, subProps, parsedValues) => {
775
+ function resolveBorderShorthandValue(value, subProps, parsedValues) {
789
776
  const [{ isNumber, name, type, value: itemValue }] = value;
790
777
  const { color: colorProp, style: styleProp, width: widthProp } = subProps;
791
778
  switch (type) {
@@ -800,7 +787,7 @@ const resolveBorderShorthandValue = (value, subProps, parsedValues) => {
800
787
  if (parsedValues.has(widthProp)) {
801
788
  return;
802
789
  }
803
- const parsedValue = parseLength(value, { min: 0 });
790
+ const parsedValue = serializeLength(value, { min: 0 });
804
791
  if (!parsedValue) {
805
792
  return;
806
793
  }
@@ -811,7 +798,7 @@ const resolveBorderShorthandValue = (value, subProps, parsedValues) => {
811
798
  if (parsedValues.has(colorProp)) {
812
799
  return;
813
800
  }
814
- const parsedValue = parseColor(value);
801
+ const parsedValue = serializeColor(value);
815
802
  if (!parsedValue) {
816
803
  return;
817
804
  }
@@ -841,7 +828,7 @@ const resolveBorderShorthandValue = (value, subProps, parsedValues) => {
841
828
  }
842
829
  default:
843
830
  }
844
- };
831
+ }
845
832
 
846
833
  module.exports = {
847
834
  AST_TYPES,
@@ -849,23 +836,24 @@ module.exports = {
849
836
  hasVarFunc,
850
837
  isGlobalKeyword,
851
838
  isValidPropertyValue,
852
- parseAngle,
853
839
  parseCSS,
854
- parseColor,
855
- parseGradient,
856
- parseLength,
857
- parseNumber,
858
- parsePercentage,
859
840
  parsePropertyValue,
860
- parseString,
861
- parseUrl,
862
841
  prepareValue,
863
842
  resolveBorderShorthandValue,
864
843
  resolveCalc,
865
844
  resolveColorValue,
866
845
  resolveFunctionValue,
867
- resolveGradientUrlValue,
846
+ resolveImageValue,
868
847
  resolveKeywordValue,
869
848
  resolveNumericValue,
849
+ serializeAngle,
850
+ serializeColor,
851
+ serializeDimension,
852
+ serializeGradient,
853
+ serializeLength,
854
+ serializeNumber,
855
+ serializePercentage,
856
+ serializeString,
857
+ serializeURL,
870
858
  splitValue
871
859
  };