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