cssstyle 5.3.4 → 5.3.6

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 (86) hide show
  1. package/lib/CSSStyleDeclaration.js +2 -2
  2. package/lib/generated/implementedProperties.js +245 -1096
  3. package/lib/generated/properties.js +1959 -2272
  4. package/lib/generated/propertyDefinitions.js +13033 -0
  5. package/lib/normalize.js +1259 -1095
  6. package/lib/parsers.js +588 -228
  7. package/lib/properties/background.js +89 -79
  8. package/lib/properties/backgroundAttachment.js +11 -14
  9. package/lib/properties/backgroundClip.js +11 -14
  10. package/lib/properties/backgroundColor.js +8 -13
  11. package/lib/properties/backgroundImage.js +11 -26
  12. package/lib/properties/backgroundOrigin.js +11 -14
  13. package/lib/properties/backgroundPosition.js +29 -18
  14. package/lib/properties/backgroundRepeat.js +11 -7
  15. package/lib/properties/backgroundSize.js +22 -16
  16. package/lib/properties/border.js +30 -87
  17. package/lib/properties/borderBottom.js +30 -86
  18. package/lib/properties/borderBottomColor.js +8 -14
  19. package/lib/properties/borderBottomStyle.js +8 -13
  20. package/lib/properties/borderBottomWidth.js +11 -23
  21. package/lib/properties/borderCollapse.js +4 -9
  22. package/lib/properties/borderColor.js +17 -23
  23. package/lib/properties/borderLeft.js +30 -86
  24. package/lib/properties/borderLeftColor.js +8 -14
  25. package/lib/properties/borderLeftStyle.js +8 -13
  26. package/lib/properties/borderLeftWidth.js +11 -23
  27. package/lib/properties/borderRight.js +30 -86
  28. package/lib/properties/borderRightColor.js +8 -14
  29. package/lib/properties/borderRightStyle.js +8 -13
  30. package/lib/properties/borderRightWidth.js +11 -23
  31. package/lib/properties/borderSpacing.js +12 -9
  32. package/lib/properties/borderStyle.js +17 -23
  33. package/lib/properties/borderTop.js +30 -86
  34. package/lib/properties/borderTopColor.js +8 -14
  35. package/lib/properties/borderTopStyle.js +8 -13
  36. package/lib/properties/borderTopWidth.js +11 -23
  37. package/lib/properties/borderWidth.js +18 -36
  38. package/lib/properties/bottom.js +6 -17
  39. package/lib/properties/clear.js +4 -9
  40. package/lib/properties/clip.js +11 -6
  41. package/lib/properties/color.js +4 -10
  42. package/lib/properties/display.js +11 -8
  43. package/lib/properties/flex.js +55 -53
  44. package/lib/properties/flexBasis.js +10 -20
  45. package/lib/properties/flexGrow.js +10 -19
  46. package/lib/properties/flexShrink.js +10 -19
  47. package/lib/properties/float.js +4 -9
  48. package/lib/properties/floodColor.js +4 -10
  49. package/lib/properties/font.js +46 -33
  50. package/lib/properties/fontFamily.js +16 -12
  51. package/lib/properties/fontSize.js +11 -22
  52. package/lib/properties/fontStyle.js +14 -8
  53. package/lib/properties/fontVariant.js +11 -18
  54. package/lib/properties/fontWeight.js +14 -25
  55. package/lib/properties/height.js +7 -17
  56. package/lib/properties/left.js +6 -17
  57. package/lib/properties/lightingColor.js +4 -10
  58. package/lib/properties/lineHeight.js +10 -24
  59. package/lib/properties/margin.js +14 -32
  60. package/lib/properties/marginBottom.js +10 -20
  61. package/lib/properties/marginLeft.js +10 -20
  62. package/lib/properties/marginRight.js +10 -20
  63. package/lib/properties/marginTop.js +10 -20
  64. package/lib/properties/opacity.js +6 -18
  65. package/lib/properties/outlineColor.js +4 -10
  66. package/lib/properties/padding.js +15 -30
  67. package/lib/properties/paddingBottom.js +11 -21
  68. package/lib/properties/paddingLeft.js +11 -21
  69. package/lib/properties/paddingRight.js +11 -21
  70. package/lib/properties/paddingTop.js +11 -21
  71. package/lib/properties/right.js +6 -17
  72. package/lib/properties/stopColor.js +4 -10
  73. package/lib/properties/top.js +7 -17
  74. package/lib/properties/webkitBorderAfterColor.js +4 -10
  75. package/lib/properties/webkitBorderBeforeColor.js +4 -10
  76. package/lib/properties/webkitBorderEndColor.js +4 -10
  77. package/lib/properties/webkitBorderStartColor.js +4 -10
  78. package/lib/properties/webkitColumnRuleColor.js +4 -10
  79. package/lib/properties/webkitTapHighlightColor.js +4 -10
  80. package/lib/properties/webkitTextEmphasisColor.js +4 -10
  81. package/lib/properties/webkitTextFillColor.js +4 -10
  82. package/lib/properties/webkitTextStrokeColor.js +4 -10
  83. package/lib/properties/width.js +7 -17
  84. package/lib/utils/propertyDescriptors.js +49 -13
  85. package/lib/utils/strings.js +6 -0
  86. package/package.json +16 -40
package/lib/normalize.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
 
3
- const implementedProperties = require("./generated/implementedProperties");
3
+ const propertyDefinitions = require("./generated/propertyDefinitions");
4
4
  const { hasVarFunc, isGlobalKeyword, isValidPropertyValue, splitValue } = require("./parsers");
5
5
  const background = require("./properties/background");
6
6
  const border = require("./properties/border");
@@ -16,38 +16,66 @@ const font = require("./properties/font");
16
16
  const margin = require("./properties/margin");
17
17
  const padding = require("./properties/padding");
18
18
 
19
- const borderImageProperty = "border-image";
19
+ /* constants */
20
+ const BACKGROUND = "background";
21
+ const BACKGROUND_COLOR = "background-color";
22
+ const BACKGROUND_SIZE = "background-size";
23
+ const BORDER = "border";
24
+ const BORDER_BOTTOM = "border-bottom";
25
+ const BORDER_COLOR = "border-color";
26
+ const BORDER_IMAGE = "border-image";
27
+ const BORDER_LEFT = "border-left";
28
+ const BORDER_RIGHT = "border-right";
29
+ const BORDER_STYLE = "border-style";
30
+ const BORDER_TOP = "border-top";
31
+ const BORDER_WIDTH = "border-width";
32
+ const TOP = "top";
33
+ const RIGHT = "right";
34
+ const BOTTOM = "bottom";
35
+ const LEFT = "left";
36
+ const WIDTH = "width";
37
+ const STYLE = "style";
38
+ const COLOR = "color";
39
+ const NONE = "none";
40
+ const TRBL_INDICES = {
41
+ [TOP]: 0,
42
+ [RIGHT]: 1,
43
+ [BOTTOM]: 2,
44
+ [LEFT]: 3
45
+ };
20
46
 
21
- exports.shorthandProperties = new Map([
22
- ["background", background],
47
+ /* shorthands */
48
+ const shorthandProperties = new Map([
49
+ [BACKGROUND, background],
23
50
  [
24
- "border",
51
+ BORDER,
25
52
  {
26
53
  definition: border.definition,
27
54
  parse: border.parse,
28
55
  shorthandFor: new Map([
29
56
  ...border.shorthandFor,
30
57
  ...border.positionShorthandFor,
31
- [borderImageProperty, null]
58
+ [BORDER_IMAGE, null]
32
59
  ])
33
60
  }
34
61
  ],
35
- ["border-width", borderWidth],
36
- ["border-style", borderStyle],
37
- ["border-color", borderColor],
38
- ["border-top", borderTop],
39
- ["border-right", borderRight],
40
- ["border-bottom", borderBottom],
41
- ["border-left", borderLeft],
62
+ [BORDER_WIDTH, borderWidth],
63
+ [BORDER_STYLE, borderStyle],
64
+ [BORDER_COLOR, borderColor],
65
+ [BORDER_TOP, borderTop],
66
+ [BORDER_RIGHT, borderRight],
67
+ [BORDER_BOTTOM, borderBottom],
68
+ [BORDER_LEFT, borderLeft],
42
69
  ["flex", flex],
43
70
  ["font", font],
44
71
  ["margin", margin],
45
72
  ["padding", padding]
46
73
  ]);
47
74
 
48
- exports.borderProperties = new Set([
49
- "border",
50
- borderImageProperty,
75
+ /* borders */
76
+ const borderProperties = new Set([
77
+ BORDER,
78
+ BORDER_IMAGE,
51
79
  ...border.shorthandFor.keys(),
52
80
  ...border.positionShorthandFor.keys(),
53
81
  ...borderTop.shorthandFor.keys(),
@@ -55,114 +83,164 @@ exports.borderProperties = new Set([
55
83
  ...borderBottom.shorthandFor.keys(),
56
84
  ...borderLeft.shorthandFor.keys()
57
85
  ]);
86
+ const borderPositions = new Set([TOP, RIGHT, BOTTOM, LEFT]);
87
+ const borderLines = new Set([WIDTH, STYLE, COLOR]);
58
88
 
59
- exports.getPositionValue = (positionValues, position) => {
60
- switch (positionValues.length) {
61
- case 1: {
62
- const [val1] = positionValues;
63
- return val1;
89
+ /**
90
+ * Ensures consistent object shape.
91
+ *
92
+ * @param {string} property - The property name.
93
+ * @param {string} [value=""] - The property value.
94
+ * @param {string} [priority=""] - The priority.
95
+ * @returns {Object} The property item object.
96
+ */
97
+ const createPropertyItem = (property, value = "", priority = "") => ({
98
+ property,
99
+ value,
100
+ priority
101
+ });
102
+
103
+ /**
104
+ * Retrieves a property item from the map or creates a default one if it doesn't exist.
105
+ *
106
+ * @param {string} property - The name of the property.
107
+ * @param {Map} properties - The map containing all properties.
108
+ * @returns {Object} The property item containing name, value, and priority.
109
+ */
110
+ const getPropertyItem = (property, properties) => {
111
+ const propertyItem = properties.get(property) ?? createPropertyItem(property);
112
+ return propertyItem;
113
+ };
114
+
115
+ /**
116
+ * Calculates the value for a specific position (top, right, bottom, left)
117
+ * based on the array of values provided for a shorthand property.
118
+ *
119
+ * @param {string[]} positionValues - The values extracted from the shorthand property.
120
+ * @param {string} position - The specific position (top, right, bottom, left) to retrieve.
121
+ * @returns {string} The calculated value for the position.
122
+ */
123
+ const getPositionValue = (positionValues, position) => {
124
+ const [val1, val2, val3, val4] = positionValues;
125
+ const index = TRBL_INDICES[position] ?? -1;
126
+ // If a specific position (top, right, bottom, left) is requested.
127
+ if (index !== -1) {
128
+ switch (positionValues.length) {
129
+ case 2: {
130
+ // Index 0 (Top) & 2 (Bottom) -> val1
131
+ // Index 1 (Right) & 3 (Left) -> val2
132
+ return index % 2 === 0 ? val1 : val2;
133
+ }
134
+ case 3: {
135
+ // Index 0 (Top) -> val1
136
+ // Index 1 (Right) & 3 (Left) -> val2
137
+ // Index 2 (Bottom) -> val3
138
+ if (index === 2) {
139
+ return val3;
140
+ }
141
+ return index % 2 === 0 ? val1 : val2;
142
+ }
143
+ case 4: {
144
+ return positionValues[index];
145
+ }
146
+ case 1:
147
+ default: {
148
+ return val1;
149
+ }
64
150
  }
151
+ }
152
+ // Fallback logic for when no specific position is requested.
153
+ switch (positionValues.length) {
65
154
  case 2: {
66
- const [val1, val2] = positionValues;
67
- switch (position) {
68
- case "top": {
69
- return val1;
70
- }
71
- case "right": {
72
- return val2;
73
- }
74
- case "bottom": {
75
- return val1;
76
- }
77
- case "left": {
78
- return val2;
79
- }
80
- default: {
81
- if (val1 === val2) {
82
- return val1;
83
- }
84
- return `${val1} ${val2}`;
85
- }
155
+ if (val1 === val2) {
156
+ return val1;
86
157
  }
158
+ return `${val1} ${val2}`;
87
159
  }
88
160
  case 3: {
89
- const [val1, val2, val3] = positionValues;
90
- switch (position) {
91
- case "top": {
161
+ if (val1 === val3) {
162
+ if (val1 === val2) {
92
163
  return val1;
93
164
  }
94
- case "right": {
95
- return val2;
96
- }
97
- case "bottom": {
98
- return val3;
99
- }
100
- case "left": {
101
- return val2;
102
- }
103
- default: {
104
- if (val1 === val3) {
105
- if (val1 === val2) {
106
- return val1;
107
- }
108
- return `${val1} ${val2}`;
109
- }
110
- return `${val1} ${val2} ${val3}`;
111
- }
165
+ return `${val1} ${val2}`;
112
166
  }
167
+ return `${val1} ${val2} ${val3}`;
113
168
  }
114
169
  case 4: {
115
- const [val1, val2, val3, val4] = positionValues;
116
- switch (position) {
117
- case "top": {
118
- return val1;
119
- }
120
- case "right": {
121
- return val2;
122
- }
123
- case "bottom": {
124
- return val3;
125
- }
126
- case "left": {
127
- return val4;
128
- }
129
- default: {
130
- if (val2 === val4) {
131
- if (val1 === val3) {
132
- if (val1 === val2) {
133
- return val1;
134
- }
135
- return `${val1} ${val2}`;
136
- }
137
- return `${val1} ${val2} ${val3}`;
170
+ if (val2 === val4) {
171
+ if (val1 === val3) {
172
+ if (val1 === val2) {
173
+ return val1;
138
174
  }
139
- return `${val1} ${val2} ${val3} ${val4}`;
175
+ return `${val1} ${val2}`;
140
176
  }
177
+ return `${val1} ${val2} ${val3}`;
141
178
  }
179
+ return `${val1} ${val2} ${val3} ${val4}`;
180
+ }
181
+ case 1:
182
+ default: {
183
+ return val1;
142
184
  }
143
- default:
144
185
  }
145
186
  };
146
187
 
147
- const borderElements = {
148
- name: "border",
149
- positions: ["top", "right", "bottom", "left"],
150
- lines: ["width", "style", "color"]
151
- };
152
-
153
- const getPropertyItem = (property, properties) => {
154
- const propertyItem = properties.get(property) ?? {
155
- property,
156
- value: "",
157
- priority: ""
158
- };
159
- return propertyItem;
188
+ /**
189
+ * Replaces the background shorthand property based on individual longhand values.
190
+ *
191
+ * @param {string} property - The specific background longhand property being updated.
192
+ * @param {Map} properties - The map of all properties.
193
+ * @param {Object} opt - Parsing options including global object and configurations.
194
+ * @returns {string} The constructed background shorthand string.
195
+ */
196
+ const replaceBackgroundShorthand = (property, properties, opt) => {
197
+ const { value: propertyValue } = properties.get(property);
198
+ const parsedValue = background.shorthandFor.get(property).parse(propertyValue, opt);
199
+ const values = splitValue(parsedValue, {
200
+ delimiter: ","
201
+ });
202
+ const { value: shorthandValue } = properties.get(BACKGROUND);
203
+ const bgValues = background.parse(shorthandValue, opt);
204
+ const bgLength = bgValues.length;
205
+ if (property === BACKGROUND_COLOR) {
206
+ bgValues[bgLength - 1][property] = parsedValue[0];
207
+ } else {
208
+ for (let i = 0; i < bgLength; i++) {
209
+ bgValues[i][property] = values[i];
210
+ }
211
+ }
212
+ const backgrounds = [];
213
+ for (const bgValue of bgValues) {
214
+ const bg = [];
215
+ for (const [longhand, value] of Object.entries(bgValue)) {
216
+ if (!value || value === background.initialValues.get(longhand)) {
217
+ continue;
218
+ }
219
+ if (longhand === BACKGROUND_SIZE) {
220
+ bg.push(`/ ${value}`);
221
+ } else {
222
+ bg.push(value);
223
+ }
224
+ }
225
+ backgrounds.push(bg.join(" "));
226
+ }
227
+ return backgrounds.join(", ");
160
228
  };
161
229
 
230
+ /**
231
+ * Checks if a property value matches the value within a border shorthand.
232
+ *
233
+ * @param {string} property - The property to check.
234
+ * @param {string} value - The value to compare.
235
+ * @param {string} shorthandValue - The shorthand string to parse and compare against.
236
+ * @param {Object} [opt={}] - Parsing options.
237
+ * @returns {boolean} True if the value matches the shorthand's value.
238
+ */
162
239
  const matchesBorderShorthandValue = (property, value, shorthandValue, opt = {}) => {
163
- const { globalObject } = opt;
240
+ const { globalObject, options } = opt;
164
241
  const obj = border.parse(shorthandValue, {
165
- globalObject
242
+ globalObject,
243
+ options
166
244
  });
167
245
  if (Object.hasOwn(obj, property)) {
168
246
  return value === obj[property];
@@ -170,17 +248,25 @@ const matchesBorderShorthandValue = (property, value, shorthandValue, opt = {})
170
248
  return value === border.initialValues.get(property);
171
249
  };
172
250
 
251
+ /**
252
+ * Replaces or updates a value within a border shorthand string.
253
+ *
254
+ * @param {string} value - The new value to insert.
255
+ * @param {string} shorthandValue - The existing shorthand string.
256
+ * @param {Object} [opt={}] - Parsing options.
257
+ * @returns {string} The updated border shorthand string.
258
+ */
173
259
  const replaceBorderShorthandValue = (value, shorthandValue, opt = {}) => {
174
- const { globalObject } = opt;
260
+ const { globalObject, options } = opt;
175
261
  const borderFirstInitialKey = border.initialValues.keys().next().value;
176
262
  const borderFirstInitialValue = border.initialValues.get(borderFirstInitialKey);
177
- const valueObj = border.parse(value, {
178
- globalObject
179
- });
263
+ const parseOpt = {
264
+ globalObject,
265
+ options
266
+ };
267
+ const valueObj = border.parse(value, parseOpt);
180
268
  const shorthandObj = shorthandValue
181
- ? border.parse(shorthandValue, {
182
- globalObject
183
- })
269
+ ? border.parse(shorthandValue, parseOpt)
184
270
  : {
185
271
  [borderFirstInitialKey]: borderFirstInitialValue
186
272
  };
@@ -212,932 +298,957 @@ const replaceBorderShorthandValue = (value, shorthandValue, opt = {}) => {
212
298
  return Object.values(shorthandObj).join(" ");
213
299
  };
214
300
 
301
+ /**
302
+ * Replaces a value at a specific position (top, right, bottom, left) within a position shorthand.
303
+ *
304
+ * @param {string} value - The new value to set.
305
+ * @param {string[]} positionValues - The array of existing position values.
306
+ * @param {string} position - The position to update.
307
+ * @returns {string} The updated shorthand string.
308
+ */
215
309
  const replacePositionValue = (value, positionValues, position) => {
216
- switch (positionValues.length) {
217
- case 1: {
218
- const [val1] = positionValues;
219
- if (val1 === value) {
220
- return positionValues.join(" ");
221
- }
222
- switch (position) {
223
- case "top": {
224
- return [value, val1, val1].join(" ");
225
- }
226
- case "right": {
227
- return [val1, value, val1, val1].join(" ");
228
- }
229
- case "bottom": {
230
- return [val1, val1, value].join(" ");
231
- }
232
- case "left": {
233
- return [val1, val1, val1, value].join(" ");
234
- }
235
- default:
236
- }
237
- break;
238
- }
239
- case 2: {
240
- const [val1, val2] = positionValues;
241
- if (val1 === val2) {
242
- return replacePositionValue(value, [val1], position);
243
- }
244
- switch (position) {
245
- case "top": {
246
- if (val1 === value) {
247
- return positionValues.join(" ");
310
+ const index = TRBL_INDICES[position] ?? -1;
311
+ let currentValues = positionValues;
312
+ if (index !== -1) {
313
+ // Loop for reducing array length (instead of recursion)
314
+ while (true) {
315
+ const [val1, val2, val3, val4] = currentValues;
316
+ switch (currentValues.length) {
317
+ case 2: {
318
+ if (val1 === val2) {
319
+ currentValues = [val1];
320
+ continue;
321
+ }
322
+ switch (index) {
323
+ // Top
324
+ case 0: {
325
+ if (val1 === value) {
326
+ return currentValues.join(" ");
327
+ }
328
+ return `${value} ${val2} ${val1}`;
329
+ }
330
+ // Right
331
+ case 1: {
332
+ if (val2 === value) {
333
+ return currentValues.join(" ");
334
+ }
335
+ return `${val1} ${value} ${val1} ${val2}`;
336
+ }
337
+ // Bottom
338
+ case 2: {
339
+ if (val1 === value) {
340
+ return currentValues.join(" ");
341
+ }
342
+ return `${val1} ${val2} ${value}`;
343
+ }
344
+ // Left
345
+ case 3:
346
+ default: {
347
+ if (val2 === value) {
348
+ return currentValues.join(" ");
349
+ }
350
+ return `${val1} ${val2} ${val1} ${value}`;
351
+ }
248
352
  }
249
- return [value, val2, val1].join(" ");
250
353
  }
251
- case "right": {
252
- if (val2 === value) {
253
- return positionValues.join(" ");
354
+ case 3: {
355
+ if (val1 === val3) {
356
+ currentValues = [val1, val2];
357
+ continue;
358
+ }
359
+ switch (index) {
360
+ // Top
361
+ case 0: {
362
+ if (val1 === value) {
363
+ return currentValues.join(" ");
364
+ } else if (val3 === value) {
365
+ return `${value} ${val2}`;
366
+ }
367
+ return `${value} ${val2} ${val3}`;
368
+ }
369
+ // Right
370
+ case 1: {
371
+ if (val2 === value) {
372
+ return currentValues.join(" ");
373
+ }
374
+ return `${val1} ${value} ${val3} ${val2}`;
375
+ }
376
+ // Bottom
377
+ case 2: {
378
+ if (val3 === value) {
379
+ return currentValues.join(" ");
380
+ } else if (val1 === value) {
381
+ return `${val1} ${val2}`;
382
+ }
383
+ return `${val1} ${val2} ${value}`;
384
+ }
385
+ // Left
386
+ case 3:
387
+ default: {
388
+ if (val2 === value) {
389
+ return currentValues.join(" ");
390
+ }
391
+ return `${val1} ${val2} ${val3} ${value}`;
392
+ }
254
393
  }
255
- return [val1, value, val1, val2].join(" ");
256
394
  }
257
- case "bottom": {
258
- if (val1 === value) {
259
- return positionValues.join(" ");
395
+ case 4: {
396
+ if (val2 === val4) {
397
+ currentValues = [val1, val2, val3];
398
+ continue;
399
+ }
400
+ switch (index) {
401
+ // Top
402
+ case 0: {
403
+ if (val1 === value) {
404
+ return currentValues.join(" ");
405
+ }
406
+ return `${value} ${val2} ${val3} ${val4}`;
407
+ }
408
+ // Right
409
+ case 1: {
410
+ if (val2 === value) {
411
+ return currentValues.join(" ");
412
+ } else if (val4 === value) {
413
+ return `${val1} ${value} ${val3}`;
414
+ }
415
+ return `${val1} ${value} ${val3} ${val4}`;
416
+ }
417
+ // Bottom
418
+ case 2: {
419
+ if (val3 === value) {
420
+ return currentValues.join(" ");
421
+ }
422
+ return `${val1} ${val2} ${value} ${val4}`;
423
+ }
424
+ // Left
425
+ case 3:
426
+ default: {
427
+ if (val4 === value) {
428
+ return currentValues.join(" ");
429
+ } else if (val2 === value) {
430
+ return `${val1} ${val2} ${val3}`;
431
+ }
432
+ return `${val1} ${val2} ${val3} ${value}`;
433
+ }
260
434
  }
261
- return [val1, val2, value].join(" ");
262
435
  }
263
- case "left": {
264
- if (val2 === value) {
265
- return positionValues.join(" ");
436
+ case 1:
437
+ default: {
438
+ const [val] = currentValues;
439
+ if (val === value) {
440
+ return currentValues.join(" ");
441
+ }
442
+ switch (index) {
443
+ // Top
444
+ case 0: {
445
+ return `${value} ${val} ${val}`;
446
+ }
447
+ // Right
448
+ case 1: {
449
+ return `${val} ${value} ${val} ${val}`;
450
+ }
451
+ // Bottom
452
+ case 2: {
453
+ return `${val} ${val} ${value}`;
454
+ }
455
+ // Left
456
+ case 3:
457
+ default: {
458
+ return `${val} ${val} ${val} ${value}`;
459
+ }
266
460
  }
267
- return [val1, val2, val1, value].join(" ");
268
461
  }
269
- default:
270
462
  }
271
- break;
463
+ }
464
+ }
465
+ // Fallback logic for when no specific position is requested.
466
+ const [val1, val2, val3, val4] = currentValues;
467
+ switch (currentValues.length) {
468
+ case 2: {
469
+ if (val1 === val2) {
470
+ return val1;
471
+ }
472
+ return `${val1} ${val2}`;
272
473
  }
273
474
  case 3: {
274
- const [val1, val2, val3] = positionValues;
275
475
  if (val1 === val3) {
276
- return replacePositionValue(value, [val1, val2], position);
277
- }
278
- switch (position) {
279
- case "top": {
280
- if (val1 === value) {
281
- return positionValues.join(" ");
282
- } else if (val3 === value) {
283
- return [value, val2].join(" ");
284
- }
285
- return [value, val2, val3].join(" ");
286
- }
287
- case "right": {
288
- if (val2 === value) {
289
- return positionValues.join(" ");
290
- }
291
- return [val1, value, val3, val2].join(" ");
292
- }
293
- case "bottom": {
294
- if (val3 === value) {
295
- return positionValues.join(" ");
296
- } else if (val1 === value) {
297
- return [val1, val2].join(" ");
298
- }
299
- return [val1, val2, value].join(" ");
300
- }
301
- case "left": {
302
- if (val2 === value) {
303
- return positionValues.join(" ");
304
- }
305
- return [val1, val2, val3, value].join(" ");
476
+ if (val1 === val2) {
477
+ return val1;
306
478
  }
307
- default:
479
+ return `${val1} ${val2}`;
308
480
  }
309
- break;
481
+ return `${val1} ${val2} ${val3}`;
310
482
  }
311
483
  case 4: {
312
- const [val1, val2, val3, val4] = positionValues;
313
484
  if (val2 === val4) {
314
- return replacePositionValue(value, [val1, val2, val3], position);
315
- }
316
- switch (position) {
317
- case "top": {
318
- if (val1 === value) {
319
- return positionValues.join(" ");
320
- }
321
- return [value, val2, val3, val4].join(" ");
322
- }
323
- case "right": {
324
- if (val2 === value) {
325
- return positionValues.join(" ");
326
- } else if (val4 === value) {
327
- return [val1, value, val3].join(" ");
328
- }
329
- return [val1, value, val3, val4].join(" ");
330
- }
331
- case "bottom": {
332
- if (val3 === value) {
333
- return positionValues.join(" ");
334
- }
335
- return [val1, val2, value, val4].join(" ");
336
- }
337
- case "left": {
338
- if (val4 === value) {
339
- return positionValues.join(" ");
340
- } else if (val2 === value) {
341
- return [val1, val2, val3].join(" ");
485
+ if (val1 === val3) {
486
+ if (val1 === val2) {
487
+ return val1;
342
488
  }
343
- return [val1, val2, val3, value].join(" ");
489
+ return `${val1} ${val2}`;
344
490
  }
345
- default:
491
+ return `${val1} ${val2} ${val3}`;
346
492
  }
347
- break;
493
+ return `${val1} ${val2} ${val3} ${val4}`;
494
+ }
495
+ case 1:
496
+ default: {
497
+ return val1;
348
498
  }
349
- default:
350
499
  }
351
500
  };
352
501
 
353
- exports.prepareBorderProperties = (property, value, priority, properties, opt = {}) => {
354
- if (typeof property !== "string" || value === null) {
355
- return;
356
- }
357
- const { globalObject } = opt;
358
- const { lines, name, positions } = borderElements;
359
- const [prop1, prop2, prop3] = property.split("-");
360
- if (prop1 !== name) {
361
- return;
362
- } else if (positions.includes(prop2)) {
363
- if (prop3) {
364
- if (!lines.includes(prop3)) {
365
- return;
502
+ /**
503
+ * Handles border property preparation when the value is a string.
504
+ *
505
+ * @param {Object} params - The parameters object.
506
+ * @param {string} params.property - The property name.
507
+ * @param {string} params.value - The property value.
508
+ * @param {string} params.priority - The property priority.
509
+ * @param {Map} params.properties - The map of properties.
510
+ * @param {Object} params.parts - The split property name parts.
511
+ * @param {Object} params.opt - Parsing options.
512
+ * @param {Map} params.borderItems - The map to store processed border items.
513
+ */
514
+ const prepareBorderStringValue = ({
515
+ property,
516
+ value,
517
+ priority,
518
+ properties,
519
+ parts,
520
+ opt,
521
+ borderItems
522
+ }) => {
523
+ const { prop1, prop2, prop3 } = parts;
524
+ const { globalObject, options } = opt;
525
+ const parseOpt = {
526
+ globalObject,
527
+ options
528
+ };
529
+ const shorthandItem = getPropertyItem(BORDER, properties);
530
+ const imageItem = getPropertyItem(BORDER_IMAGE, properties);
531
+ // Handle longhand properties.
532
+ if (prop3) {
533
+ const lineProperty = `${prop1}-${prop3}`;
534
+ const lineItem = getPropertyItem(lineProperty, properties);
535
+ const positionProperty = `${prop1}-${prop2}`;
536
+ const positionItem = getPropertyItem(positionProperty, properties);
537
+ const longhandProperty = `${prop1}-${prop2}-${prop3}`;
538
+ const longhandItem = getPropertyItem(longhandProperty, properties);
539
+ longhandItem.value = value;
540
+ longhandItem.priority = priority;
541
+ const propertyValue = hasVarFunc(value) ? "" : value;
542
+ if (propertyValue === "") {
543
+ shorthandItem.value = "";
544
+ lineItem.value = "";
545
+ positionItem.value = "";
546
+ } else if (isGlobalKeyword(propertyValue)) {
547
+ if (shorthandItem.value !== propertyValue) {
548
+ shorthandItem.value = "";
366
549
  }
367
- }
368
- } else if (lines.includes(prop2)) {
369
- if (prop3) {
370
- return;
371
- }
372
- }
373
- const borderItems = new Map();
374
- const nameProperty = prop1;
375
- // Empty string, global keywords, var(), value of longhands.
376
- if (typeof value === "string") {
377
- // longhand properties
378
- if (prop3) {
379
- const nameItem = getPropertyItem(nameProperty, properties);
380
- const imageItem = getPropertyItem(borderImageProperty, properties);
381
- const lineProperty = `${prop1}-${prop3}`;
382
- const lineItem = getPropertyItem(lineProperty, properties);
383
- const positionProperty = `${prop1}-${prop2}`;
384
- const positionItem = getPropertyItem(positionProperty, properties);
385
- const longhandProperty = `${prop1}-${prop2}-${prop3}`;
386
- const longhandItem = getPropertyItem(longhandProperty, properties);
387
- longhandItem.value = value;
388
- longhandItem.priority = priority;
389
- const propertyValue = hasVarFunc(value) ? "" : value;
390
- if (propertyValue === "") {
391
- nameItem.value = "";
550
+ if (lineItem.value !== propertyValue) {
392
551
  lineItem.value = "";
552
+ }
553
+ if (positionItem.value !== propertyValue) {
393
554
  positionItem.value = "";
394
- } else if (isGlobalKeyword(propertyValue)) {
395
- if (nameItem.value !== propertyValue) {
396
- nameItem.value = "";
397
- }
398
- if (lineItem.value !== propertyValue) {
399
- lineItem.value = "";
400
- }
401
- if (positionItem.value !== propertyValue) {
402
- positionItem.value = "";
403
- }
404
- } else {
405
- if (
406
- nameItem.value &&
407
- !matchesBorderShorthandValue(lineProperty, propertyValue, nameItem.value, {
408
- globalObject
409
- })
410
- ) {
411
- nameItem.value = "";
412
- }
413
- if (lineItem.value) {
414
- lineItem.value = replacePositionValue(propertyValue, splitValue(lineItem.value), prop2);
415
- }
416
- if (
417
- positionItem.value &&
418
- !matchesBorderShorthandValue(lineProperty, propertyValue, positionItem.value, {
419
- globalObject
420
- })
421
- ) {
422
- positionItem.value = "";
423
- }
424
555
  }
425
- borderItems.set(nameProperty, nameItem);
426
- borderItems.set(borderImageProperty, imageItem);
427
- borderItems.set(lineProperty, lineItem);
428
- borderItems.set(positionProperty, positionItem);
429
- borderItems.set(longhandProperty, longhandItem);
430
- // border-top, border-right, border-bottom, border-left shorthands
431
- } else if (prop2 && positions.includes(prop2)) {
432
- const nameItem = getPropertyItem(nameProperty, properties);
433
- const imageItem = getPropertyItem(borderImageProperty, properties);
434
- const lineWidthProperty = `${prop1}-width`;
435
- const lineWidthItem = getPropertyItem(lineWidthProperty, properties);
436
- const lineStyleProperty = `${prop1}-style`;
437
- const lineStyleItem = getPropertyItem(lineStyleProperty, properties);
438
- const lineColorProperty = `${prop1}-color`;
439
- const lineColorItem = getPropertyItem(lineColorProperty, properties);
440
- const positionProperty = `${prop1}-${prop2}`;
441
- const positionItem = getPropertyItem(positionProperty, properties);
442
- positionItem.value = value;
443
- positionItem.priority = priority;
444
- const propertyValue = hasVarFunc(value) ? "" : value;
445
- if (propertyValue === "") {
446
- nameItem.value = "";
556
+ } else {
557
+ if (
558
+ shorthandItem.value &&
559
+ !matchesBorderShorthandValue(lineProperty, propertyValue, shorthandItem.value, parseOpt)
560
+ ) {
561
+ shorthandItem.value = "";
562
+ }
563
+ if (lineItem.value) {
564
+ lineItem.value = replacePositionValue(propertyValue, splitValue(lineItem.value), prop2);
565
+ }
566
+ if (
567
+ positionItem.value &&
568
+ !matchesBorderShorthandValue(lineProperty, propertyValue, positionItem.value, parseOpt)
569
+ ) {
570
+ positionItem.value = "";
571
+ }
572
+ }
573
+ borderItems.set(BORDER, shorthandItem);
574
+ borderItems.set(BORDER_IMAGE, imageItem);
575
+ borderItems.set(lineProperty, lineItem);
576
+ borderItems.set(positionProperty, positionItem);
577
+ borderItems.set(longhandProperty, longhandItem);
578
+ // Handle side-specific border shorthands (border-top, border-right, border-bottom, border-left).
579
+ } else if (prop2 && borderPositions.has(prop2)) {
580
+ const lineWidthProperty = `${prop1}-width`;
581
+ const lineWidthItem = getPropertyItem(lineWidthProperty, properties);
582
+ const lineStyleProperty = `${prop1}-style`;
583
+ const lineStyleItem = getPropertyItem(lineStyleProperty, properties);
584
+ const lineColorProperty = `${prop1}-color`;
585
+ const lineColorItem = getPropertyItem(lineColorProperty, properties);
586
+ const positionProperty = `${prop1}-${prop2}`;
587
+ const positionItem = getPropertyItem(positionProperty, properties);
588
+ positionItem.value = value;
589
+ positionItem.priority = priority;
590
+ const propertyValue = hasVarFunc(value) ? "" : value;
591
+ if (propertyValue === "") {
592
+ shorthandItem.value = "";
593
+ lineWidthItem.value = "";
594
+ lineStyleItem.value = "";
595
+ lineColorItem.value = "";
596
+ } else if (isGlobalKeyword(propertyValue)) {
597
+ if (shorthandItem.value !== propertyValue) {
598
+ shorthandItem.value = "";
599
+ }
600
+ if (lineWidthItem.value !== propertyValue) {
447
601
  lineWidthItem.value = "";
602
+ }
603
+ if (lineStyleItem.value !== propertyValue) {
448
604
  lineStyleItem.value = "";
605
+ }
606
+ if (lineColorItem.value !== propertyValue) {
449
607
  lineColorItem.value = "";
450
- } else if (isGlobalKeyword(propertyValue)) {
451
- if (nameItem.value !== propertyValue) {
452
- nameItem.value = "";
453
- }
454
- if (lineWidthItem.value !== propertyValue) {
455
- lineWidthItem.value = "";
456
- }
457
- if (lineStyleItem.value !== propertyValue) {
458
- lineStyleItem.value = "";
459
- }
460
- if (lineColorItem.value !== propertyValue) {
461
- lineColorItem.value = "";
462
- }
463
- } else {
464
- if (
465
- nameItem.value &&
466
- !matchesBorderShorthandValue(property, propertyValue, nameItem.value, {
467
- globalObject
468
- })
469
- ) {
470
- nameItem.value = "";
471
- }
472
- if (lineWidthItem.value && isValidPropertyValue(lineWidthProperty, propertyValue)) {
473
- lineWidthItem.value = propertyValue;
474
- }
475
- if (lineStyleItem.value && isValidPropertyValue(lineStyleProperty, propertyValue)) {
476
- lineStyleItem.value = propertyValue;
477
- }
478
- if (lineColorItem.value && isValidPropertyValue(lineColorProperty, propertyValue)) {
479
- lineColorItem.value = propertyValue;
480
- }
481
608
  }
482
- for (const line of lines) {
483
- const longhandProperty = `${prop1}-${prop2}-${line}`;
484
- const longhandItem = getPropertyItem(longhandProperty, properties);
485
- longhandItem.value = propertyValue;
486
- longhandItem.priority = priority;
487
- borderItems.set(longhandProperty, longhandItem);
609
+ } else {
610
+ if (
611
+ shorthandItem.value &&
612
+ !matchesBorderShorthandValue(property, propertyValue, shorthandItem.value, parseOpt)
613
+ ) {
614
+ shorthandItem.value = "";
615
+ }
616
+ if (
617
+ lineWidthItem.value &&
618
+ isValidPropertyValue(lineWidthProperty, propertyValue, globalObject)
619
+ ) {
620
+ lineWidthItem.value = propertyValue;
621
+ }
622
+ if (
623
+ lineStyleItem.value &&
624
+ isValidPropertyValue(lineStyleProperty, propertyValue, globalObject)
625
+ ) {
626
+ lineStyleItem.value = propertyValue;
627
+ }
628
+ if (
629
+ lineColorItem.value &&
630
+ isValidPropertyValue(lineColorProperty, propertyValue, globalObject)
631
+ ) {
632
+ lineColorItem.value = propertyValue;
633
+ }
634
+ }
635
+ for (const line of borderLines) {
636
+ const longhandProperty = `${prop1}-${prop2}-${line}`;
637
+ const longhandItem = getPropertyItem(longhandProperty, properties);
638
+ longhandItem.value = propertyValue;
639
+ longhandItem.priority = priority;
640
+ borderItems.set(longhandProperty, longhandItem);
641
+ }
642
+ borderItems.set(BORDER, shorthandItem);
643
+ borderItems.set(BORDER_IMAGE, imageItem);
644
+ borderItems.set(lineWidthProperty, lineWidthItem);
645
+ borderItems.set(lineStyleProperty, lineStyleItem);
646
+ borderItems.set(lineColorProperty, lineColorItem);
647
+ borderItems.set(positionProperty, positionItem);
648
+ // Handle property-specific border shorthands (border-width, border-style, border-color).
649
+ } else if (prop2 && borderLines.has(prop2)) {
650
+ const lineProperty = `${prop1}-${prop2}`;
651
+ const lineItem = getPropertyItem(lineProperty, properties);
652
+ lineItem.value = value;
653
+ lineItem.priority = priority;
654
+ const propertyValue = hasVarFunc(value) ? "" : value;
655
+ if (propertyValue === "") {
656
+ shorthandItem.value = "";
657
+ } else if (isGlobalKeyword(propertyValue)) {
658
+ if (shorthandItem.value !== propertyValue) {
659
+ shorthandItem.value = "";
488
660
  }
489
- borderItems.set(nameProperty, nameItem);
490
- borderItems.set(borderImageProperty, imageItem);
491
- borderItems.set(lineWidthProperty, lineWidthItem);
492
- borderItems.set(lineStyleProperty, lineStyleItem);
493
- borderItems.set(lineColorProperty, lineColorItem);
661
+ }
662
+ for (const position of borderPositions) {
663
+ const positionProperty = `${prop1}-${position}`;
664
+ const positionItem = getPropertyItem(positionProperty, properties);
665
+ const longhandProperty = `${prop1}-${position}-${prop2}`;
666
+ const longhandItem = getPropertyItem(longhandProperty, properties);
667
+ if (propertyValue) {
668
+ positionItem.value = replaceBorderShorthandValue(
669
+ propertyValue,
670
+ positionItem.value,
671
+ parseOpt
672
+ );
673
+ } else {
674
+ positionItem.value = "";
675
+ }
676
+ longhandItem.value = propertyValue;
677
+ longhandItem.priority = priority;
494
678
  borderItems.set(positionProperty, positionItem);
495
- // border-width, border-style, border-color
496
- } else if (prop2 && lines.includes(prop2)) {
497
- const nameItem = getPropertyItem(nameProperty, properties);
498
- const imageItem = getPropertyItem(borderImageProperty, properties);
499
- const lineProperty = `${prop1}-${prop2}`;
679
+ borderItems.set(longhandProperty, longhandItem);
680
+ }
681
+ borderItems.set(BORDER, shorthandItem);
682
+ borderItems.set(BORDER_IMAGE, imageItem);
683
+ borderItems.set(lineProperty, lineItem);
684
+ // Handle border shorthand.
685
+ } else {
686
+ const propertyValue = hasVarFunc(value) ? "" : value;
687
+ imageItem.value = propertyValue ? NONE : "";
688
+ for (const line of borderLines) {
689
+ const lineProperty = `${prop1}-${line}`;
500
690
  const lineItem = getPropertyItem(lineProperty, properties);
501
- lineItem.value = value;
691
+ lineItem.value = propertyValue;
502
692
  lineItem.priority = priority;
503
- const propertyValue = hasVarFunc(value) ? "" : value;
504
- if (propertyValue === "") {
505
- nameItem.value = "";
506
- } else if (isGlobalKeyword(propertyValue)) {
507
- if (nameItem.value !== propertyValue) {
508
- nameItem.value = "";
509
- }
510
- }
511
- for (const position of positions) {
512
- const positionProperty = `${prop1}-${position}`;
513
- const positionItem = getPropertyItem(positionProperty, properties);
514
- const longhandProperty = `${prop1}-${position}-${prop2}`;
693
+ borderItems.set(lineProperty, lineItem);
694
+ }
695
+ for (const position of borderPositions) {
696
+ const positionProperty = `${prop1}-${position}`;
697
+ const positionItem = getPropertyItem(positionProperty, properties);
698
+ positionItem.value = propertyValue;
699
+ positionItem.priority = priority;
700
+ borderItems.set(positionProperty, positionItem);
701
+ for (const line of borderLines) {
702
+ const longhandProperty = `${positionProperty}-${line}`;
515
703
  const longhandItem = getPropertyItem(longhandProperty, properties);
516
- if (propertyValue) {
517
- positionItem.value = replaceBorderShorthandValue(propertyValue, positionItem.value, {
518
- globalObject
519
- });
520
- } else {
521
- positionItem.value = "";
522
- }
523
704
  longhandItem.value = propertyValue;
524
705
  longhandItem.priority = priority;
525
- borderItems.set(positionProperty, positionItem);
526
706
  borderItems.set(longhandProperty, longhandItem);
527
707
  }
528
- borderItems.set(nameProperty, nameItem);
529
- borderItems.set(borderImageProperty, imageItem);
530
- borderItems.set(lineProperty, lineItem);
531
- // border shorthand
532
- } else {
533
- const nameItem = getPropertyItem(nameProperty, properties);
534
- const imageItem = getPropertyItem(borderImageProperty, properties);
535
- const propertyValue = hasVarFunc(value) ? "" : value;
536
- imageItem.value = propertyValue ? "none" : "";
537
- for (const line of lines) {
538
- const lineProperty = `${prop1}-${line}`;
539
- const lineItem = getPropertyItem(lineProperty, properties);
540
- lineItem.value = propertyValue;
541
- lineItem.priority = priority;
542
- borderItems.set(lineProperty, lineItem);
543
- }
544
- for (const position of positions) {
545
- const positionProperty = `${prop1}-${position}`;
546
- const positionItem = getPropertyItem(positionProperty, properties);
547
- positionItem.value = propertyValue;
548
- positionItem.priority = priority;
549
- borderItems.set(positionProperty, positionItem);
550
- for (const line of lines) {
551
- const longhandProperty = `${positionProperty}-${line}`;
552
- const longhandItem = getPropertyItem(longhandProperty, properties);
553
- longhandItem.value = propertyValue;
554
- longhandItem.priority = priority;
555
- borderItems.set(longhandProperty, longhandItem);
556
- }
708
+ }
709
+ borderItems.set(property, shorthandItem);
710
+ borderItems.set(BORDER_IMAGE, imageItem);
711
+ }
712
+ };
713
+
714
+ /**
715
+ * Handles border property preparation when the value is an array.
716
+ *
717
+ * @param {Object} params - The parameters object.
718
+ * @param {Array} params.value - The property value.
719
+ * @param {string} params.priority - The property priority.
720
+ * @param {Map} params.properties - The map of properties.
721
+ * @param {Object} params.parts - The split property name parts.
722
+ * @param {Object} params.opt - Parsing options.
723
+ * @param {Map} params.borderItems - The map to store processed border items.
724
+ */
725
+ const prepareBorderArrayValue = ({ value, priority, properties, parts, opt, borderItems }) => {
726
+ const { prop1, prop2 } = parts;
727
+ const { globalObject, options } = opt;
728
+ const parseOpt = {
729
+ globalObject,
730
+ options
731
+ };
732
+ if (!value.length || !borderLines.has(prop2)) {
733
+ return;
734
+ }
735
+ const shorthandItem = getPropertyItem(BORDER, properties);
736
+ const imageItem = getPropertyItem(BORDER_IMAGE, properties);
737
+ const lineProperty = `${prop1}-${prop2}`;
738
+ const lineItem = getPropertyItem(lineProperty, properties);
739
+ if (value.length === 1) {
740
+ const [propertyValue] = value;
741
+ if (shorthandItem.value) {
742
+ if (hasVarFunc(shorthandItem.value)) {
743
+ shorthandItem.value = "";
744
+ } else if (propertyValue) {
745
+ shorthandItem.value = replaceBorderShorthandValue(
746
+ propertyValue,
747
+ shorthandItem.value,
748
+ parseOpt
749
+ );
557
750
  }
558
- borderItems.set(property, nameItem);
559
- borderItems.set(borderImageProperty, imageItem);
560
751
  }
561
- // Values of border-width, border-style, border-color
562
- } else if (Array.isArray(value)) {
563
- if (!value.length || !lines.includes(prop2)) {
564
- return;
752
+ } else {
753
+ shorthandItem.value = "";
754
+ }
755
+ lineItem.value = value.join(" ");
756
+ lineItem.priority = priority;
757
+ const positionValues = {};
758
+ const [val1, val2, val3, val4] = value;
759
+ switch (value.length) {
760
+ case 2: {
761
+ positionValues.top = val1;
762
+ positionValues.right = val2;
763
+ positionValues.bottom = val1;
764
+ positionValues.left = val2;
765
+ break;
766
+ }
767
+ case 3: {
768
+ positionValues.top = val1;
769
+ positionValues.right = val2;
770
+ positionValues.bottom = val3;
771
+ positionValues.left = val2;
772
+ break;
565
773
  }
566
- const nameItem = getPropertyItem(nameProperty, properties);
567
- const imageItem = getPropertyItem(borderImageProperty, properties);
568
- const lineProperty = `${prop1}-${prop2}`;
569
- const lineItem = getPropertyItem(lineProperty, properties);
570
- if (value.length === 1) {
571
- const [propertyValue] = value;
572
- if (nameItem.value && propertyValue) {
573
- nameItem.value = replaceBorderShorthandValue(propertyValue, nameItem.value, {
574
- globalObject
575
- });
576
- }
577
- } else {
578
- nameItem.value = "";
774
+ case 4: {
775
+ positionValues.top = val1;
776
+ positionValues.right = val2;
777
+ positionValues.bottom = val3;
778
+ positionValues.left = val4;
779
+ break;
579
780
  }
580
- lineItem.value = value.join(" ");
581
- lineItem.priority = priority;
582
- const positionValues = {};
583
- switch (value.length) {
584
- case 1: {
585
- const [val1] = value;
586
- positionValues.top = val1;
587
- positionValues.right = val1;
588
- positionValues.bottom = val1;
589
- positionValues.left = val1;
590
- break;
591
- }
592
- case 2: {
593
- const [val1, val2] = value;
594
- positionValues.top = val1;
595
- positionValues.right = val2;
596
- positionValues.bottom = val1;
597
- positionValues.left = val2;
598
- break;
599
- }
600
- case 3: {
601
- const [val1, val2, val3] = value;
602
- positionValues.top = val1;
603
- positionValues.right = val2;
604
- positionValues.bottom = val3;
605
- positionValues.left = val2;
606
- break;
607
- }
608
- case 4: {
609
- const [val1, val2, val3, val4] = value;
610
- positionValues.top = val1;
611
- positionValues.right = val2;
612
- positionValues.bottom = val3;
613
- positionValues.left = val4;
614
- break;
615
- }
616
- default: {
617
- return;
781
+ case 1:
782
+ default: {
783
+ positionValues.top = val1;
784
+ positionValues.right = val1;
785
+ positionValues.bottom = val1;
786
+ positionValues.left = val1;
787
+ }
788
+ }
789
+ for (const position of borderPositions) {
790
+ const positionProperty = `${prop1}-${position}`;
791
+ const positionItem = getPropertyItem(positionProperty, properties);
792
+ if (positionItem.value && positionValues[position]) {
793
+ positionItem.value = replaceBorderShorthandValue(
794
+ positionValues[position],
795
+ positionItem.value,
796
+ parseOpt
797
+ );
798
+ }
799
+ const longhandProperty = `${positionProperty}-${prop2}`;
800
+ const longhandItem = getPropertyItem(longhandProperty, properties);
801
+ longhandItem.value = positionValues[position];
802
+ longhandItem.priority = priority;
803
+ borderItems.set(positionProperty, positionItem);
804
+ borderItems.set(longhandProperty, longhandItem);
805
+ }
806
+ borderItems.set(BORDER, shorthandItem);
807
+ borderItems.set(BORDER_IMAGE, imageItem);
808
+ borderItems.set(lineProperty, lineItem);
809
+ };
810
+
811
+ /**
812
+ * Handles border property preparation when the value is an object.
813
+ *
814
+ * @param {Object} params - The parameters object.
815
+ * @param {string} params.property - The property name.
816
+ * @param {Object} params.value - The property value.
817
+ * @param {string} params.priority - The property priority.
818
+ * @param {Map} params.properties - The map of properties.
819
+ * @param {Object} params.parts - The split property name parts.
820
+ * @param {Object} params.opt - Parsing options.
821
+ * @param {Map} params.borderItems - The map to store processed border items.
822
+ */
823
+ const prepareBorderObjectValue = ({
824
+ property,
825
+ value,
826
+ priority,
827
+ properties,
828
+ parts,
829
+ opt,
830
+ borderItems
831
+ }) => {
832
+ const { prop1, prop2 } = parts;
833
+ const { globalObject, options } = opt;
834
+ const parseOpt = {
835
+ globalObject,
836
+ options
837
+ };
838
+ const imageItem = getPropertyItem(BORDER_IMAGE, properties);
839
+ // Handle position shorthands.
840
+ if (prop2) {
841
+ if (!borderPositions.has(prop2)) {
842
+ return;
843
+ }
844
+ const shorthandItem = getPropertyItem(BORDER, properties);
845
+ const lineWidthProperty = `${prop1}-width`;
846
+ const lineWidthItem = getPropertyItem(lineWidthProperty, properties);
847
+ const lineStyleProperty = `${prop1}-style`;
848
+ const lineStyleItem = getPropertyItem(lineStyleProperty, properties);
849
+ const lineColorProperty = `${prop1}-color`;
850
+ const lineColorItem = getPropertyItem(lineColorProperty, properties);
851
+ const positionProperty = `${prop1}-${prop2}`;
852
+ const positionItem = getPropertyItem(positionProperty, properties);
853
+ if (shorthandItem.value) {
854
+ for (const positionValue of Object.values(value)) {
855
+ if (!matchesBorderShorthandValue(property, positionValue, shorthandItem.value, parseOpt)) {
856
+ shorthandItem.value = "";
857
+ break;
858
+ }
618
859
  }
619
860
  }
620
- for (const position of positions) {
621
- const positionProperty = `${prop1}-${position}`;
622
- const positionItem = getPropertyItem(positionProperty, properties);
623
- if (positionItem.value && positionValues[position]) {
624
- positionItem.value = replaceBorderShorthandValue(
625
- positionValues[position],
626
- positionItem.value,
627
- {
628
- globalObject
629
- }
861
+ positionItem.value = Object.values(value).join(" ");
862
+ positionItem.priority = priority;
863
+ for (const line of borderLines) {
864
+ const longhandProperty = `${prop1}-${prop2}-${line}`;
865
+ const longhandItem = getPropertyItem(longhandProperty, properties);
866
+ const itemValue = Object.hasOwn(value, longhandProperty)
867
+ ? value[longhandProperty]
868
+ : border.initialValues.get(`${prop1}-${line}`);
869
+ if (line === WIDTH && lineWidthItem.value) {
870
+ lineWidthItem.value = replacePositionValue(
871
+ itemValue,
872
+ splitValue(lineWidthItem.value),
873
+ prop2
874
+ );
875
+ } else if (line === STYLE && lineStyleItem.value) {
876
+ lineStyleItem.value = replacePositionValue(
877
+ itemValue,
878
+ splitValue(lineStyleItem.value),
879
+ prop2
880
+ );
881
+ } else if (line === COLOR && lineColorItem.value) {
882
+ lineColorItem.value = replacePositionValue(
883
+ itemValue,
884
+ splitValue(lineColorItem.value),
885
+ prop2
630
886
  );
631
887
  }
632
- const longhandProperty = `${positionProperty}-${prop2}`;
633
- const longhandItem = getPropertyItem(longhandProperty, properties);
634
- longhandItem.value = positionValues[position];
888
+ longhandItem.value = itemValue;
635
889
  longhandItem.priority = priority;
636
- borderItems.set(positionProperty, positionItem);
637
890
  borderItems.set(longhandProperty, longhandItem);
638
891
  }
639
- borderItems.set(nameProperty, nameItem);
640
- borderItems.set(borderImageProperty, imageItem);
641
- borderItems.set(lineProperty, lineItem);
642
- // Values of border, border-top, border-right, border-bottom, border-top.
643
- } else if (value && typeof value === "object") {
644
- // position shorthands
645
- if (prop2) {
646
- if (!positions.includes(prop2)) {
647
- return;
648
- }
649
- const nameItem = getPropertyItem(nameProperty, properties);
650
- const imageItem = getPropertyItem(borderImageProperty, properties);
651
- const lineWidthProperty = `${prop1}-width`;
652
- const lineWidthItem = getPropertyItem(lineWidthProperty, properties);
653
- const lineStyleProperty = `${prop1}-style`;
654
- const lineStyleItem = getPropertyItem(lineStyleProperty, properties);
655
- const lineColorProperty = `${prop1}-color`;
656
- const lineColorItem = getPropertyItem(lineColorProperty, properties);
657
- const positionProperty = `${prop1}-${prop2}`;
892
+ borderItems.set(BORDER, shorthandItem);
893
+ borderItems.set(BORDER_IMAGE, imageItem);
894
+ borderItems.set(lineWidthProperty, lineWidthItem);
895
+ borderItems.set(lineStyleProperty, lineStyleItem);
896
+ borderItems.set(lineColorProperty, lineColorItem);
897
+ borderItems.set(positionProperty, positionItem);
898
+ // Handle border shorthand.
899
+ } else {
900
+ const shorthandItem = getPropertyItem(prop1, properties);
901
+ const lineWidthProperty = `${prop1}-width`;
902
+ const lineWidthItem = getPropertyItem(lineWidthProperty, properties);
903
+ const lineStyleProperty = `${prop1}-style`;
904
+ const lineStyleItem = getPropertyItem(lineStyleProperty, properties);
905
+ const lineColorProperty = `${prop1}-color`;
906
+ const lineColorItem = getPropertyItem(lineColorProperty, properties);
907
+ const propertyValue = Object.values(value).join(" ");
908
+ shorthandItem.value = propertyValue;
909
+ shorthandItem.priority = priority;
910
+ imageItem.value = propertyValue ? NONE : "";
911
+ if (Object.hasOwn(value, lineWidthProperty)) {
912
+ lineWidthItem.value = value[lineWidthProperty];
913
+ } else {
914
+ lineWidthItem.value = border.initialValues.get(lineWidthProperty);
915
+ }
916
+ lineWidthItem.priority = priority;
917
+ if (Object.hasOwn(value, lineStyleProperty)) {
918
+ lineStyleItem.value = value[lineStyleProperty];
919
+ } else {
920
+ lineStyleItem.value = border.initialValues.get(lineStyleProperty);
921
+ }
922
+ lineStyleItem.priority = priority;
923
+ if (Object.hasOwn(value, lineColorProperty)) {
924
+ lineColorItem.value = value[lineColorProperty];
925
+ } else {
926
+ lineColorItem.value = border.initialValues.get(lineColorProperty);
927
+ }
928
+ lineColorItem.priority = priority;
929
+ for (const position of borderPositions) {
930
+ const positionProperty = `${prop1}-${position}`;
658
931
  const positionItem = getPropertyItem(positionProperty, properties);
659
- if (nameItem.value) {
660
- for (const positionValue of Object.values(value)) {
661
- if (
662
- !matchesBorderShorthandValue(property, positionValue, nameItem.value, {
663
- globalObject
664
- })
665
- ) {
666
- nameItem.value = "";
667
- break;
668
- }
669
- }
670
- }
671
- positionItem.value = Object.values(value).join(" ");
932
+ positionItem.value = propertyValue;
672
933
  positionItem.priority = priority;
673
- for (const line of lines) {
674
- const longhandProperty = `${prop1}-${prop2}-${line}`;
934
+ for (const line of borderLines) {
935
+ const longhandProperty = `${positionProperty}-${line}`;
675
936
  const longhandItem = getPropertyItem(longhandProperty, properties);
676
- if (Object.hasOwn(value, longhandProperty)) {
677
- const itemValue = value[longhandProperty];
678
- if (line === "width") {
679
- if (lineWidthItem.value) {
680
- lineWidthItem.value = replacePositionValue(
681
- itemValue,
682
- splitValue(lineWidthItem.value),
683
- prop2
684
- );
685
- }
686
- } else if (line === "style") {
687
- if (lineStyleItem.value) {
688
- lineStyleItem.value = replacePositionValue(
689
- itemValue,
690
- splitValue(lineStyleItem.value),
691
- prop2
692
- );
693
- }
694
- } else if (line === "color") {
695
- if (lineColorItem.value) {
696
- lineColorItem.value = replacePositionValue(
697
- itemValue,
698
- splitValue(lineColorItem.value),
699
- prop2
700
- );
701
- }
702
- }
703
- longhandItem.value = itemValue;
704
- longhandItem.priority = priority;
937
+ const lineProperty = `${prop1}-${line}`;
938
+ if (Object.hasOwn(value, lineProperty)) {
939
+ longhandItem.value = value[lineProperty];
705
940
  } else {
706
- const itemValue = border.initialValues.get(`${prop1}-${line}`);
707
- if (line === "width") {
708
- if (lineWidthItem.value) {
709
- lineWidthItem.value = replacePositionValue(
710
- itemValue,
711
- splitValue(lineWidthItem.value),
712
- prop2
713
- );
714
- }
715
- } else if (line === "style") {
716
- if (lineStyleItem.value) {
717
- lineStyleItem.value = replacePositionValue(
718
- itemValue,
719
- splitValue(lineStyleItem.value),
720
- prop2
721
- );
722
- }
723
- } else if (line === "color") {
724
- if (lineColorItem.value) {
725
- lineColorItem.value = replacePositionValue(
726
- itemValue,
727
- splitValue(lineColorItem.value),
728
- prop2
729
- );
730
- }
731
- }
732
- longhandItem.value = itemValue;
733
- longhandItem.priority = priority;
941
+ longhandItem.value = border.initialValues.get(lineProperty);
734
942
  }
943
+ longhandItem.priority = priority;
735
944
  borderItems.set(longhandProperty, longhandItem);
736
945
  }
737
- borderItems.set(nameProperty, nameItem);
738
- borderItems.set(borderImageProperty, imageItem);
739
- borderItems.set(lineWidthProperty, lineWidthItem);
740
- borderItems.set(lineStyleProperty, lineStyleItem);
741
- borderItems.set(lineColorProperty, lineColorItem);
742
946
  borderItems.set(positionProperty, positionItem);
743
- // border shorthand
947
+ }
948
+ borderItems.set(property, shorthandItem);
949
+ borderItems.set(BORDER_IMAGE, imageItem);
950
+ borderItems.set(lineWidthProperty, lineWidthItem);
951
+ borderItems.set(lineStyleProperty, lineStyleItem);
952
+ borderItems.set(lineColorProperty, lineColorItem);
953
+ }
954
+ };
955
+
956
+ /**
957
+ * Prepares border properties by splitting shorthands and handling updates.
958
+ *
959
+ * @param {string} property - The border property name.
960
+ * @param {string|Array|Object} value - The value of the property.
961
+ * @param {string} priority - The priority of the property (e.g., "important").
962
+ * @param {Map} properties - The map of all properties.
963
+ * @param {Object} [opt={}] - Parsing options.
964
+ * @returns {Map|undefined} A map of expanded or updated border properties.
965
+ */
966
+ const prepareBorderProperties = (property, value, priority, properties, opt = {}) => {
967
+ if (typeof property !== "string" || value === null) {
968
+ return;
969
+ }
970
+ if (!property.startsWith(BORDER)) {
971
+ return;
972
+ }
973
+ let prop2, prop3;
974
+ if (property.length > BORDER.length) {
975
+ // Check if next char is '-'
976
+ if (property.charCodeAt(BORDER.length) !== 45) {
977
+ return;
978
+ }
979
+ // property is like "border-..."
980
+ const remainder = property.substring(BORDER.length + 1);
981
+ const hyphenIndex = remainder.indexOf("-");
982
+ if (hyphenIndex !== -1) {
983
+ prop2 = remainder.substring(0, hyphenIndex);
984
+ prop3 = remainder.substring(hyphenIndex + 1);
744
985
  } else {
745
- const nameItem = getPropertyItem(prop1, properties);
746
- const imageItem = getPropertyItem(borderImageProperty, properties);
747
- const lineWidthProperty = `${prop1}-width`;
748
- const lineWidthItem = getPropertyItem(lineWidthProperty, properties);
749
- const lineStyleProperty = `${prop1}-style`;
750
- const lineStyleItem = getPropertyItem(lineStyleProperty, properties);
751
- const lineColorProperty = `${prop1}-color`;
752
- const lineColorItem = getPropertyItem(lineColorProperty, properties);
753
- const propertyValue = Object.values(value).join(" ");
754
- nameItem.value = propertyValue;
755
- nameItem.priority = priority;
756
- imageItem.value = propertyValue ? "none" : "";
757
- if (Object.hasOwn(value, lineWidthProperty)) {
758
- lineWidthItem.value = value[lineWidthProperty];
759
- } else {
760
- lineWidthItem.value = border.initialValues.get(lineWidthProperty);
761
- }
762
- lineWidthItem.priority = priority;
763
- if (Object.hasOwn(value, lineStyleProperty)) {
764
- lineStyleItem.value = value[lineStyleProperty];
765
- } else {
766
- lineStyleItem.value = border.initialValues.get(lineStyleProperty);
767
- }
768
- lineStyleItem.priority = priority;
769
- if (Object.hasOwn(value, lineColorProperty)) {
770
- lineColorItem.value = value[lineColorProperty];
771
- } else {
772
- lineColorItem.value = border.initialValues.get(lineColorProperty);
773
- }
774
- lineColorItem.priority = priority;
775
- for (const position of positions) {
776
- const positionProperty = `${prop1}-${position}`;
777
- const positionItem = getPropertyItem(positionProperty, properties);
778
- positionItem.value = propertyValue;
779
- positionItem.priority = priority;
780
- for (const line of lines) {
781
- const longhandProperty = `${positionProperty}-${line}`;
782
- const longhandItem = getPropertyItem(longhandProperty, properties);
783
- const lineProperty = `${prop1}-${line}`;
784
- if (Object.hasOwn(value, lineProperty)) {
785
- longhandItem.value = value[lineProperty];
786
- } else {
787
- longhandItem.value = border.initialValues.get(lineProperty);
788
- }
789
- longhandItem.priority = priority;
790
- borderItems.set(longhandProperty, longhandItem);
791
- }
792
- borderItems.set(positionProperty, positionItem);
793
- }
794
- borderItems.set(property, nameItem);
795
- borderItems.set(borderImageProperty, imageItem);
796
- borderItems.set(lineWidthProperty, lineWidthItem);
797
- borderItems.set(lineStyleProperty, lineStyleItem);
798
- borderItems.set(lineColorProperty, lineColorItem);
986
+ prop2 = remainder;
799
987
  }
800
- } else {
988
+ }
989
+ if (
990
+ (borderPositions.has(prop2) && prop3 && !borderLines.has(prop3)) ||
991
+ (borderLines.has(prop2) && prop3)
992
+ ) {
801
993
  return;
802
994
  }
803
- if (!borderItems.has(name)) {
995
+ const parts = {
996
+ prop1: BORDER,
997
+ prop2,
998
+ prop3
999
+ };
1000
+ const borderItems = new Map();
1001
+ if (typeof value === "string") {
1002
+ prepareBorderStringValue({
1003
+ property,
1004
+ value,
1005
+ priority,
1006
+ properties,
1007
+ parts,
1008
+ opt,
1009
+ borderItems
1010
+ });
1011
+ } else if (Array.isArray(value)) {
1012
+ prepareBorderArrayValue({
1013
+ value,
1014
+ priority,
1015
+ properties,
1016
+ parts,
1017
+ opt,
1018
+ borderItems
1019
+ });
1020
+ } else if (value && typeof value === "object") {
1021
+ prepareBorderObjectValue({
1022
+ property,
1023
+ value,
1024
+ priority,
1025
+ properties,
1026
+ parts,
1027
+ opt,
1028
+ borderItems
1029
+ });
1030
+ }
1031
+ if (!borderItems.has(BORDER)) {
804
1032
  return;
805
1033
  }
806
- const borderProperties = new Map([[name, borderItems.get(name)]]);
807
- for (const line of lines) {
808
- const lineProperty = `${name}-${line}`;
809
- const lineItem = borderItems.get(lineProperty) ??
810
- properties.get(lineProperty) ?? {
811
- property: lineProperty,
812
- value: "",
813
- priority: ""
814
- };
815
- borderProperties.set(lineProperty, lineItem);
1034
+ const borderProps = new Map([[BORDER, borderItems.get(BORDER)]]);
1035
+ for (const line of borderLines) {
1036
+ const lineProperty = `${BORDER}-${line}`;
1037
+ const lineItem = borderItems.get(lineProperty) ?? getPropertyItem(lineProperty, properties);
1038
+ borderProps.set(lineProperty, lineItem);
816
1039
  }
817
- for (const position of positions) {
818
- const positionProperty = `${name}-${position}`;
819
- const positionItem = borderItems.get(positionProperty) ??
820
- properties.get(positionProperty) ?? {
821
- property: positionProperty,
822
- value: "",
823
- priority: ""
824
- };
825
- borderProperties.set(positionProperty, positionItem);
826
- for (const line of lines) {
827
- const longhandProperty = `${name}-${position}-${line}`;
828
- const longhandItem = borderItems.get(longhandProperty) ??
829
- properties.get(longhandProperty) ?? {
830
- property: longhandProperty,
831
- value: "",
832
- priority: ""
833
- };
834
- borderProperties.set(longhandProperty, longhandItem);
1040
+ for (const position of borderPositions) {
1041
+ const positionProperty = `${BORDER}-${position}`;
1042
+ const positionItem =
1043
+ borderItems.get(positionProperty) ?? getPropertyItem(positionProperty, properties);
1044
+ borderProps.set(positionProperty, positionItem);
1045
+ for (const line of borderLines) {
1046
+ const longhandProperty = `${BORDER}-${position}-${line}`;
1047
+ const longhandItem =
1048
+ borderItems.get(longhandProperty) ?? getPropertyItem(longhandProperty, properties);
1049
+ borderProps.set(longhandProperty, longhandItem);
835
1050
  }
836
1051
  }
837
- const borderImageItem = borderItems.get(borderImageProperty) ?? {
838
- property: borderImageProperty,
839
- value: "",
840
- priority: ""
841
- };
842
- borderProperties.set(borderImageProperty, borderImageItem);
843
- return borderProperties;
1052
+ const borderImageItem = borderItems.get(BORDER_IMAGE) ?? createPropertyItem(BORDER_IMAGE);
1053
+ borderProps.set(BORDER_IMAGE, borderImageItem);
1054
+ return borderProps;
844
1055
  };
845
1056
 
846
- const generateBorderLineShorthand = (items, property, prior) => {
1057
+ /**
1058
+ * Generates a border line shorthand property if all line components are present.
1059
+ *
1060
+ * @param {Map} items - The map of collected property items.
1061
+ * @param {string} property - The shorthand property name to generate.
1062
+ * @param {string} [priority=""] - The priority of the property.
1063
+ * @returns {Array} A key-value pair for the generated property.
1064
+ */
1065
+ const generateBorderLineShorthand = (items, property, priority = "") => {
847
1066
  const values = [];
848
1067
  for (const [, item] of items) {
849
1068
  const { value: itemValue } = item;
850
1069
  values.push(itemValue);
851
1070
  }
852
- const value = exports.getPositionValue(values);
853
- const priority = prior ? prior : "";
854
- return [property, { property, value, priority }];
1071
+ const value = getPositionValue(values);
1072
+ return [property, createPropertyItem(property, value, priority)];
855
1073
  };
856
1074
 
857
- const generateBorderPositionShorthand = (items, property, prior) => {
1075
+ /**
1076
+ * Generates a border position shorthand property if all position components are present.
1077
+ *
1078
+ * @param {Map} items - The map of collected property items.
1079
+ * @param {string} property - The shorthand property name to generate.
1080
+ * @param {string} [priority=""] - The priority of the property.
1081
+ * @returns {Array} A key-value pair for the generated property.
1082
+ */
1083
+ const generateBorderPositionShorthand = (items, property, priority = "") => {
858
1084
  const values = [];
859
1085
  for (const [, item] of items) {
860
1086
  const { value: itemValue } = item;
861
1087
  values.push(itemValue);
862
1088
  }
863
1089
  const value = values.join(" ");
864
- const priority = prior ? prior : "";
865
- return [property, { property, value, priority }];
1090
+ return [property, createPropertyItem(property, value, priority)];
866
1091
  };
867
1092
 
868
- const generateBorderNameShorthand = (items, property, prior) => {
1093
+ /**
1094
+ * Generates a border shorthand property if all components match.
1095
+ *
1096
+ * @param {Array} items - The collection of property values.
1097
+ * @param {string} property - The shorthand property name to generate.
1098
+ * @param {string} [priority=""] - The priority of the property.
1099
+ * @returns {Array|undefined} A key-value pair for the generated property or undefined.
1100
+ */
1101
+ const generateBorderShorthand = (items, property, priority = "") => {
869
1102
  const values = new Set(items);
870
1103
  if (values.size === 1) {
871
1104
  const value = values.keys().next().value;
872
- const priority = prior ? prior : "";
873
- return [property, { property, value, priority }];
1105
+ return [property, createPropertyItem(property, value, priority)];
874
1106
  }
875
1107
  };
876
1108
 
877
- const prepareBorderShorthands = (properties) => {
878
- const lineWidthItems = new Map();
879
- const lineWidthPriorItems = new Map();
880
- const lineStyleItems = new Map();
881
- const lineStylePriorItems = new Map();
882
- const lineColorItems = new Map();
883
- const lineColorPriorItems = new Map();
884
- const positionTopItems = new Map();
885
- const positionTopPriorItems = new Map();
886
- const positionRightItems = new Map();
887
- const positionRightPriorItems = new Map();
888
- const positionBottomItems = new Map();
889
- const positionBottomPriorItems = new Map();
890
- const positionLeftItems = new Map();
891
- const positionLeftPriorItems = new Map();
892
- for (const [property, { priority, value }] of properties) {
893
- const [, positionPart, linePart] = property.split("-");
894
- switch (linePart) {
895
- case "width": {
896
- if (priority) {
897
- lineWidthPriorItems.set(property, { property, value, priority });
898
- } else {
899
- lineWidthItems.set(property, { property, value, priority });
900
- }
901
- break;
902
- }
903
- case "style": {
904
- if (priority) {
905
- lineStylePriorItems.set(property, { property, value, priority });
906
- } else {
907
- lineStyleItems.set(property, { property, value, priority });
908
- }
909
- break;
910
- }
911
- case "color": {
912
- if (priority) {
913
- lineColorPriorItems.set(property, { property, value, priority });
914
- } else {
915
- lineColorItems.set(property, { property, value, priority });
916
- }
917
- break;
918
- }
919
- default:
920
- }
921
- switch (positionPart) {
922
- case "top": {
923
- if (priority) {
924
- positionTopPriorItems.set(property, { property, value, priority });
925
- } else {
926
- positionTopItems.set(property, { property, value, priority });
927
- }
928
- break;
929
- }
930
- case "right": {
931
- if (priority) {
932
- positionRightPriorItems.set(property, { property, value, priority });
933
- } else {
934
- positionRightItems.set(property, { property, value, priority });
935
- }
936
- break;
937
- }
938
- case "bottom": {
939
- if (priority) {
940
- positionBottomPriorItems.set(property, { property, value, priority });
941
- } else {
942
- positionBottomItems.set(property, { property, value, priority });
943
- }
944
- break;
945
- }
946
- case "left": {
947
- if (priority) {
948
- positionLeftPriorItems.set(property, { property, value, priority });
949
- } else {
950
- positionLeftItems.set(property, { property, value, priority });
951
- }
952
- break;
953
- }
954
- default:
955
- }
956
- }
957
- if (lineWidthItems.size === 4) {
958
- const [property, item] = generateBorderLineShorthand(lineWidthItems, "border-width") ?? [];
959
- if (property && item) {
960
- properties.set(property, item);
961
- }
962
- } else if (lineWidthPriorItems.size === 4) {
963
- const [property, item] =
964
- generateBorderLineShorthand(lineWidthPriorItems, "border-width", "important") ?? [];
965
- if (property && item) {
966
- properties.set(property, item);
967
- }
1109
+ const borderCollectionConfig = {
1110
+ [WIDTH]: {
1111
+ shorthand: BORDER_WIDTH,
1112
+ generator: generateBorderLineShorthand
1113
+ },
1114
+ [STYLE]: {
1115
+ shorthand: BORDER_STYLE,
1116
+ generator: generateBorderLineShorthand
1117
+ },
1118
+ [COLOR]: {
1119
+ shorthand: BORDER_COLOR,
1120
+ generator: generateBorderLineShorthand
1121
+ },
1122
+ [TOP]: {
1123
+ shorthand: BORDER_TOP,
1124
+ generator: generateBorderPositionShorthand
1125
+ },
1126
+ [RIGHT]: {
1127
+ shorthand: BORDER_RIGHT,
1128
+ generator: generateBorderPositionShorthand
1129
+ },
1130
+ [BOTTOM]: {
1131
+ shorthand: BORDER_BOTTOM,
1132
+ generator: generateBorderPositionShorthand
1133
+ },
1134
+ [LEFT]: {
1135
+ shorthand: BORDER_LEFT,
1136
+ generator: generateBorderPositionShorthand
968
1137
  }
969
- if (lineStyleItems.size === 4) {
970
- const [property, item] = generateBorderLineShorthand(lineStyleItems, "border-style") ?? [];
971
- if (property && item) {
972
- properties.set(property, item);
973
- }
974
- } else if (lineStylePriorItems.size === 4) {
975
- const [property, item] =
976
- generateBorderLineShorthand(lineStylePriorItems, "border-style", "important") ?? [];
977
- if (property && item) {
978
- properties.set(property, item);
979
- }
980
- }
981
- if (lineColorItems.size === 4) {
982
- const [property, item] = generateBorderLineShorthand(lineColorItems, "border-color") ?? [];
983
- if (property && item) {
984
- properties.set(property, item);
985
- }
986
- } else if (lineColorPriorItems.size === 4) {
987
- const [property, item] =
988
- generateBorderLineShorthand(lineColorPriorItems, "border-color", "important") ?? [];
989
- if (property && item) {
990
- properties.set(property, item);
991
- }
992
- }
993
- const nameItems = [];
994
- const namePriorItems = [];
995
- if (positionTopItems.size === 3) {
996
- const [property, item] = generateBorderPositionShorthand(positionTopItems, "border-top") ?? [];
997
- if (property && item) {
998
- properties.set(property, item);
999
- if (properties.has(borderImageProperty)) {
1000
- const { value: imageValue } = properties.get(borderImageProperty);
1001
- if (imageValue === "none") {
1002
- const { value: itemValue } = item;
1003
- nameItems.push(itemValue);
1004
- }
1005
- }
1006
- }
1007
- } else if (positionTopPriorItems.size === 3) {
1008
- const [property, item] =
1009
- generateBorderPositionShorthand(positionTopPriorItems, "border-top", "important") ?? [];
1010
- if (property && item) {
1011
- properties.set(property, item);
1012
- if (properties.has(borderImageProperty)) {
1013
- const { value: imageValue } = properties.get(borderImageProperty);
1014
- if (imageValue === "none") {
1015
- const { value: itemValue } = item;
1016
- namePriorItems.push(itemValue);
1017
- }
1018
- }
1019
- }
1138
+ };
1139
+
1140
+ /**
1141
+ * Processes and consolidates border-related longhands into shorthands where possible.
1142
+ *
1143
+ * @param {Map} properties - The map of current properties.
1144
+ * @returns {Map} The updated map with consolidated border properties.
1145
+ */
1146
+ const prepareBorderShorthands = (properties) => {
1147
+ const borderCollections = {};
1148
+ for (const key of Object.keys(borderCollectionConfig)) {
1149
+ borderCollections[key] = {
1150
+ ...borderCollectionConfig[key],
1151
+ items: new Map(),
1152
+ priorityItems: new Map()
1153
+ };
1020
1154
  }
1021
- if (positionRightItems.size === 3) {
1022
- const [property, item] =
1023
- generateBorderPositionShorthand(positionRightItems, "border-right") ?? [];
1024
- if (property && item) {
1025
- properties.set(property, item);
1026
- if (properties.has(borderImageProperty)) {
1027
- const { value: imageValue } = properties.get(borderImageProperty);
1028
- if (imageValue === "none") {
1029
- const { value: itemValue } = item;
1030
- nameItems.push(itemValue);
1031
- }
1032
- }
1033
- }
1034
- } else if (positionRightPriorItems.size === 3) {
1035
- const [property, item] =
1036
- generateBorderPositionShorthand(positionRightPriorItems, "border-right", "important") ?? [];
1037
- if (property && item) {
1038
- properties.set(property, item);
1039
- if (properties.has(borderImageProperty)) {
1040
- const { value: imageValue } = properties.get(borderImageProperty);
1041
- if (imageValue === "none") {
1042
- const { value: itemValue } = item;
1043
- nameItems.push(itemValue);
1044
- }
1155
+ for (const [property, item] of properties) {
1156
+ const { priority, value } = item;
1157
+ let positionPart, linePart;
1158
+ // We can assume property starts with "border-"
1159
+ const firstHyphen = property.indexOf("-");
1160
+ if (firstHyphen !== -1) {
1161
+ const remainder = property.substring(firstHyphen + 1);
1162
+ const secondHyphen = remainder.indexOf("-");
1163
+ if (secondHyphen !== -1) {
1164
+ positionPart = remainder.substring(0, secondHyphen);
1165
+ linePart = remainder.substring(secondHyphen + 1);
1166
+ } else {
1167
+ positionPart = remainder;
1168
+ linePart = undefined;
1045
1169
  }
1046
1170
  }
1047
- }
1048
- if (positionBottomItems.size === 3) {
1049
- const [property, item] =
1050
- generateBorderPositionShorthand(positionBottomItems, "border-bottom") ?? [];
1051
- if (property && item) {
1052
- properties.set(property, item);
1053
- if (properties.has(borderImageProperty)) {
1054
- const { value: imageValue } = properties.get(borderImageProperty);
1055
- if (imageValue === "none") {
1056
- const { value: itemValue } = item;
1057
- nameItems.push(itemValue);
1058
- }
1171
+ if (linePart && borderCollections[linePart]) {
1172
+ const collection = borderCollections[linePart];
1173
+ if (priority) {
1174
+ collection.priorityItems.set(property, { property, value, priority });
1175
+ } else {
1176
+ collection.items.set(property, { property, value, priority });
1059
1177
  }
1060
1178
  }
1061
- } else if (positionBottomPriorItems.size === 3) {
1062
- const [property, item] =
1063
- generateBorderPositionShorthand(positionBottomPriorItems, "border-bottom", "important") ?? [];
1064
- if (property && item) {
1065
- properties.set(property, item);
1066
- if (properties.has(borderImageProperty)) {
1067
- const { value: imageValue } = properties.get(borderImageProperty);
1068
- if (imageValue === "none") {
1069
- const { value: itemValue } = item;
1070
- nameItems.push(itemValue);
1071
- }
1179
+ if (positionPart && borderCollections[positionPart]) {
1180
+ const collection = borderCollections[positionPart];
1181
+ if (priority) {
1182
+ collection.priorityItems.set(property, { property, value, priority });
1183
+ } else {
1184
+ collection.items.set(property, { property, value, priority });
1072
1185
  }
1073
1186
  }
1074
1187
  }
1075
- if (positionLeftItems.size === 3) {
1076
- const [property, item] =
1077
- generateBorderPositionShorthand(positionLeftItems, "border-left") ?? [];
1078
- if (property && item) {
1079
- properties.set(property, item);
1080
- if (properties.has(borderImageProperty)) {
1081
- const { value: imageValue } = properties.get(borderImageProperty);
1082
- if (imageValue === "none") {
1083
- const { value: itemValue } = item;
1084
- nameItems.push(itemValue);
1188
+ const shorthandItems = [];
1189
+ const shorthandPriorityItems = [];
1190
+ for (const [key, collection] of Object.entries(borderCollections)) {
1191
+ const { shorthand, generator, items, priorityItems } = collection;
1192
+ const requiredSize = borderLines.has(key) ? 4 : 3;
1193
+ if (items.size === requiredSize) {
1194
+ const [property, item] = generator(items, shorthand) ?? [];
1195
+ if (property && item) {
1196
+ properties.set(property, item);
1197
+ if (borderPositions.has(key) && properties.has(BORDER_IMAGE)) {
1198
+ const { value: imageValue } = properties.get(BORDER_IMAGE);
1199
+ if (imageValue === NONE) {
1200
+ shorthandItems.push(item.value);
1201
+ }
1085
1202
  }
1086
1203
  }
1087
- }
1088
- } else if (positionLeftPriorItems.size === 3) {
1089
- const [property, item] =
1090
- generateBorderPositionShorthand(positionLeftPriorItems, "border-left", "important") ?? [];
1091
- if (property && item) {
1092
- properties.set(property, item);
1093
- if (properties.has(borderImageProperty)) {
1094
- const { value: imageValue } = properties.get(borderImageProperty);
1095
- if (imageValue === "none") {
1096
- const { value: itemValue } = item;
1097
- nameItems.push(itemValue);
1204
+ } else if (priorityItems.size === requiredSize) {
1205
+ const [property, item] = generator(priorityItems, shorthand, "important") ?? [];
1206
+ if (property && item) {
1207
+ properties.set(property, item);
1208
+ if (borderPositions.has(key) && properties.has(BORDER_IMAGE)) {
1209
+ const { value: imageValue } = properties.get(BORDER_IMAGE);
1210
+ if (imageValue === NONE) {
1211
+ shorthandPriorityItems.push(item.value);
1212
+ }
1098
1213
  }
1099
1214
  }
1100
1215
  }
1101
1216
  }
1102
- const mixedPriorities = nameItems.length && namePriorItems.length;
1103
- const imageItem = {
1104
- property: borderImageProperty,
1105
- value: "none",
1106
- priority: ""
1107
- };
1108
- if (nameItems.length === 4) {
1109
- const [property, item] = generateBorderNameShorthand(nameItems, "border") ?? [];
1217
+ const mixedPriorities = shorthandItems.length && shorthandPriorityItems.length;
1218
+ const imageItem = createPropertyItem(BORDER_IMAGE, NONE);
1219
+ if (shorthandItems.length === 4) {
1220
+ const [property, item] = generateBorderShorthand(shorthandItems, BORDER) ?? [];
1110
1221
  if (property && item) {
1111
1222
  properties.set(property, item);
1112
- properties.delete(borderImageProperty);
1113
- properties.set(borderImageProperty, imageItem);
1223
+ properties.delete(BORDER_IMAGE);
1224
+ properties.set(BORDER_IMAGE, imageItem);
1114
1225
  }
1115
- } else if (namePriorItems.length === 4) {
1226
+ } else if (shorthandPriorityItems.length === 4) {
1116
1227
  const [property, item] =
1117
- generateBorderNameShorthand(namePriorItems, "border", "important") ?? [];
1228
+ generateBorderShorthand(shorthandPriorityItems, BORDER, "important") ?? [];
1118
1229
  if (property && item) {
1119
1230
  properties.set(property, item);
1120
- properties.delete(borderImageProperty);
1121
- properties.set(borderImageProperty, imageItem);
1231
+ properties.delete(BORDER_IMAGE);
1232
+ properties.set(BORDER_IMAGE, imageItem);
1122
1233
  }
1123
- } else if (properties.has(borderImageProperty)) {
1124
- const { value: imageValue } = properties.get(borderImageProperty);
1125
- if (imageValue === "none") {
1234
+ } else if (properties.has(BORDER_IMAGE)) {
1235
+ const { value: imageValue } = properties.get(BORDER_IMAGE);
1236
+ if (imageValue === NONE) {
1126
1237
  if (mixedPriorities) {
1127
- properties.delete(borderImageProperty);
1128
- properties.set(borderImageProperty, imageItem);
1238
+ properties.delete(BORDER_IMAGE);
1239
+ properties.set(BORDER_IMAGE, imageItem);
1129
1240
  } else {
1130
- properties.delete(borderImageProperty);
1241
+ properties.delete(BORDER_IMAGE);
1131
1242
  }
1132
1243
  }
1133
1244
  }
1134
1245
  if (mixedPriorities) {
1135
1246
  const items = [];
1136
- const priorItems = [];
1247
+ const priorityItems = [];
1137
1248
  for (const item of properties) {
1138
1249
  const [, { priority }] = item;
1139
1250
  if (priority) {
1140
- priorItems.push(item);
1251
+ priorityItems.push(item);
1141
1252
  } else {
1142
1253
  items.push(item);
1143
1254
  }
@@ -1145,52 +1256,194 @@ const prepareBorderShorthands = (properties) => {
1145
1256
  const firstPropertyKey = properties.keys().next().value;
1146
1257
  const { priority: firstPropertyPriority } = properties.get(firstPropertyKey);
1147
1258
  if (firstPropertyPriority) {
1148
- return new Map([...priorItems, ...items]);
1259
+ return new Map([...priorityItems, ...items]);
1149
1260
  }
1150
- return new Map([...items, ...priorItems]);
1261
+ return new Map([...items, ...priorityItems]);
1151
1262
  }
1152
- if (properties.has(borderImageProperty)) {
1153
- properties.delete(borderImageProperty);
1154
- properties.set(borderImageProperty, imageItem);
1263
+ if (properties.has(BORDER_IMAGE)) {
1264
+ properties.delete(BORDER_IMAGE);
1265
+ properties.set(BORDER_IMAGE, imageItem);
1155
1266
  }
1156
1267
  return properties;
1157
1268
  };
1158
1269
 
1159
- exports.prepareProperties = (properties, opt = {}) => {
1160
- const { globalObject } = opt;
1161
- const { positions } = borderElements;
1270
+ /**
1271
+ * Processes shorthand properties from the shorthands map.
1272
+ *
1273
+ * @param {Map} shorthands - The map containing shorthand property groups.
1274
+ * @returns {Map} A map of processed shorthand properties.
1275
+ */
1276
+ const processShorthandProperties = (shorthands) => {
1277
+ const shorthandItems = new Map();
1278
+ for (const [property, item] of shorthands) {
1279
+ const shorthandItem = shorthandProperties.get(property);
1280
+ if (item.size === shorthandItem.shorthandFor.size && shorthandItem.position) {
1281
+ const positionValues = [];
1282
+ let priority = "";
1283
+ for (const { value: longhandValue, priority: longhandPriority } of item.values()) {
1284
+ positionValues.push(longhandValue);
1285
+ if (longhandPriority) {
1286
+ priority = longhandPriority;
1287
+ }
1288
+ }
1289
+ const value = getPositionValue(positionValues, shorthandItem.position);
1290
+ shorthandItems.set(property, createPropertyItem(property, value, priority));
1291
+ }
1292
+ }
1293
+ return shorthandItems;
1294
+ };
1295
+
1296
+ /**
1297
+ * Updates the longhand properties map with a new property item.
1298
+ * If a property with normal priority already exists, it will be overwritten by the new item.
1299
+ * If the existing property has "important" priority, it will not be overwritten.
1300
+ *
1301
+ * @param {string} property - The CSS property name.
1302
+ * @param {Object} item - The property item object containing value and priority.
1303
+ * @param {Map} longhandProperties - The map of longhand properties to update.
1304
+ */
1305
+ const updateLonghandProperties = (property, item, longhandProperties) => {
1306
+ if (longhandProperties.has(property)) {
1307
+ const { priority: longhandPriority } = longhandProperties.get(property);
1308
+ if (!longhandPriority) {
1309
+ longhandProperties.delete(property);
1310
+ longhandProperties.set(property, item);
1311
+ }
1312
+ } else {
1313
+ longhandProperties.set(property, item);
1314
+ }
1315
+ };
1316
+
1317
+ /**
1318
+ * Processes border properties from the borders map, expanding and normalizing them.
1319
+ *
1320
+ * @param {Map} borders - The map containing accumulated border properties.
1321
+ * @param {Object} parseOpt - Options for parsing values.
1322
+ * @returns {Map} A map of fully processed and normalized border properties.
1323
+ */
1324
+ const processBorderProperties = (borders, parseOpt) => {
1325
+ const longhandProperties = new Map();
1326
+ for (const [property, item] of borders) {
1327
+ if (shorthandProperties.has(property)) {
1328
+ const { value, priority } = item;
1329
+ if (property === BORDER) {
1330
+ const lineItems = border.parse(value, parseOpt);
1331
+ for (const [key, initialValue] of border.initialValues) {
1332
+ if (!Object.hasOwn(lineItems, key)) {
1333
+ lineItems[key] = initialValue;
1334
+ }
1335
+ }
1336
+ for (const lineProperty of Object.keys(lineItems)) {
1337
+ let namePart, linePart;
1338
+ const hyphenIndex = lineProperty.indexOf("-");
1339
+ if (hyphenIndex !== -1) {
1340
+ namePart = lineProperty.substring(0, hyphenIndex);
1341
+ linePart = lineProperty.substring(hyphenIndex + 1);
1342
+ } else {
1343
+ // fallback for safety, though lineProperty from border.parse keys
1344
+ // should have hyphen
1345
+ namePart = lineProperty;
1346
+ linePart = "";
1347
+ }
1348
+ const lineValue = lineItems[lineProperty];
1349
+ for (const position of borderPositions) {
1350
+ const longhandProperty = `${namePart}-${position}-${linePart}`;
1351
+ const longhandItem = createPropertyItem(longhandProperty, lineValue, priority);
1352
+ updateLonghandProperties(longhandProperty, longhandItem, longhandProperties);
1353
+ }
1354
+ }
1355
+ if (value) {
1356
+ longhandProperties.set(BORDER_IMAGE, createPropertyItem(BORDER_IMAGE, NONE, priority));
1357
+ }
1358
+ } else {
1359
+ const shorthandItem = shorthandProperties.get(property);
1360
+ const parsedItem = shorthandItem.parse(value, parseOpt);
1361
+ if (Array.isArray(parsedItem)) {
1362
+ let namePart, linePart;
1363
+ const hyphenIndex = property.indexOf("-");
1364
+ if (hyphenIndex !== -1) {
1365
+ namePart = property.substring(0, hyphenIndex);
1366
+ linePart = property.substring(hyphenIndex + 1);
1367
+ } else {
1368
+ namePart = property;
1369
+ }
1370
+ for (const position of borderPositions) {
1371
+ const longhandProperty = `${namePart}-${position}-${linePart}`;
1372
+ const longhandValue = getPositionValue(parsedItem, position);
1373
+ const longhandItem = createPropertyItem(longhandProperty, longhandValue, priority);
1374
+ updateLonghandProperties(longhandProperty, longhandItem, longhandProperties);
1375
+ }
1376
+ } else if (parsedItem) {
1377
+ for (const [key, initialValue] of shorthandItem.initialValues) {
1378
+ if (!Object.hasOwn(parsedItem, key)) {
1379
+ parsedItem[key] = initialValue;
1380
+ }
1381
+ }
1382
+ for (const longhandProperty of Object.keys(parsedItem)) {
1383
+ const longhandValue = parsedItem[longhandProperty];
1384
+ const longhandItem = createPropertyItem(longhandProperty, longhandValue, priority);
1385
+ updateLonghandProperties(longhandProperty, longhandItem, longhandProperties);
1386
+ }
1387
+ }
1388
+ }
1389
+ } else if (longhandProperties.has(property)) {
1390
+ const { priority } = longhandProperties.get(property);
1391
+ if (!priority) {
1392
+ longhandProperties.delete(property);
1393
+ longhandProperties.set(property, item);
1394
+ }
1395
+ } else {
1396
+ longhandProperties.set(property, item);
1397
+ }
1398
+ }
1399
+ const borderItems = prepareBorderShorthands(longhandProperties);
1400
+ return borderItems;
1401
+ };
1402
+
1403
+ /**
1404
+ * Normalize and prepare CSS properties, handling shorthands and longhands.
1405
+ *
1406
+ * @param {Map} properties - The initial map of properties.
1407
+ * @param {Object} [opt={}] - Parsing options.
1408
+ * @returns {Map} The normalized map of properties.
1409
+ */
1410
+ const prepareProperties = (properties, opt = {}) => {
1411
+ const { globalObject, options } = opt;
1412
+ const parseOpt = {
1413
+ globalObject,
1414
+ options
1415
+ };
1162
1416
  const parsedProperties = new Map();
1163
- const prepareShorthands = new Map();
1164
- const borderProperties = new Map();
1417
+ const shorthands = new Map();
1418
+ const borders = new Map();
1419
+ let hasPrecedingBackground = false;
1165
1420
  for (const [property, item] of properties) {
1166
1421
  const { value, priority } = item;
1167
- const { logicalPropertyGroup: shorthandProperty } = implementedProperties.get(property) ?? {};
1168
- if (exports.borderProperties.has(property)) {
1169
- borderProperties.set(property, { property, value, priority });
1170
- } else if (exports.shorthandProperties.has(shorthandProperty)) {
1171
- if (!prepareShorthands.has(shorthandProperty)) {
1172
- prepareShorthands.set(shorthandProperty, new Map());
1422
+ const { logicalPropertyGroup: shorthandProperty } = propertyDefinitions.get(property) ?? {};
1423
+ if (borderProperties.has(property)) {
1424
+ borders.set(property, { property, value, priority });
1425
+ } else if (shorthandProperties.has(shorthandProperty)) {
1426
+ if (!shorthands.has(shorthandProperty)) {
1427
+ shorthands.set(shorthandProperty, new Map());
1173
1428
  }
1174
- const longhandItems = prepareShorthands.get(shorthandProperty);
1429
+ const longhandItems = shorthands.get(shorthandProperty);
1175
1430
  if (longhandItems.size) {
1176
1431
  const firstPropertyKey = longhandItems.keys().next().value;
1177
1432
  const { priority: firstPropertyPriority } = longhandItems.get(firstPropertyKey);
1178
1433
  if (priority === firstPropertyPriority) {
1179
1434
  longhandItems.set(property, { property, value, priority });
1180
- prepareShorthands.set(shorthandProperty, longhandItems);
1435
+ shorthands.set(shorthandProperty, longhandItems);
1181
1436
  } else {
1182
1437
  parsedProperties.delete(shorthandProperty);
1183
1438
  }
1184
1439
  } else {
1185
1440
  longhandItems.set(property, { property, value, priority });
1186
- prepareShorthands.set(shorthandProperty, longhandItems);
1441
+ shorthands.set(shorthandProperty, longhandItems);
1187
1442
  }
1188
1443
  parsedProperties.set(property, item);
1189
- } else if (exports.shorthandProperties.has(property)) {
1190
- const shorthandItem = exports.shorthandProperties.get(property);
1191
- const parsedValues = shorthandItem.parse(value, {
1192
- globalObject
1193
- });
1444
+ } else if (shorthandProperties.has(property)) {
1445
+ const shorthandItem = shorthandProperties.get(property);
1446
+ const parsedValues = shorthandItem.parse(value, parseOpt);
1194
1447
  let omitShorthandProperty = false;
1195
1448
  if (Array.isArray(parsedValues)) {
1196
1449
  const [parsedValue] = parsedValues;
@@ -1204,204 +1457,106 @@ exports.prepareProperties = (properties, opt = {}) => {
1204
1457
  }
1205
1458
  }
1206
1459
  const { position } = longhandItem;
1207
- const longhandValue = exports.getPositionValue([parsedValue], position);
1208
- parsedProperties.set(longhandProperty, {
1209
- property: longhandProperty,
1210
- value: longhandValue,
1211
- priority
1212
- });
1460
+ const longhandValue = getPositionValue([parsedValue], position);
1461
+ parsedProperties.set(
1462
+ longhandProperty,
1463
+ createPropertyItem(longhandProperty, longhandValue, priority)
1464
+ );
1213
1465
  }
1214
1466
  } else if (parsedValue) {
1215
1467
  for (const longhandProperty of Object.keys(parsedValue)) {
1216
1468
  const longhandValue = parsedValue[longhandProperty];
1217
- parsedProperties.set(longhandProperty, {
1218
- property: longhandProperty,
1219
- value: longhandValue,
1220
- priority
1221
- });
1469
+ parsedProperties.set(
1470
+ longhandProperty,
1471
+ createPropertyItem(longhandProperty, longhandValue, priority)
1472
+ );
1222
1473
  }
1223
1474
  }
1224
- } else if (parsedValues) {
1475
+ } else if (parsedValues && typeof parsedValues !== "string") {
1225
1476
  for (const longhandProperty of Object.keys(parsedValues)) {
1226
1477
  const longhandValue = parsedValues[longhandProperty];
1227
- parsedProperties.set(longhandProperty, {
1228
- property: longhandProperty,
1229
- value: longhandValue,
1230
- priority
1231
- });
1478
+ parsedProperties.set(
1479
+ longhandProperty,
1480
+ createPropertyItem(longhandProperty, longhandValue, priority)
1481
+ );
1232
1482
  }
1233
1483
  }
1234
1484
  if (!omitShorthandProperty) {
1235
- parsedProperties.set(property, { property, value, priority });
1485
+ if (property === BACKGROUND) {
1486
+ hasPrecedingBackground = true;
1487
+ }
1488
+ parsedProperties.set(property, createPropertyItem(property, value, priority));
1236
1489
  }
1237
1490
  } else {
1238
- parsedProperties.set(property, { property, value, priority });
1239
- }
1240
- }
1241
- if (prepareShorthands.size) {
1242
- for (const [property, item] of prepareShorthands) {
1243
- const shorthandItem = exports.shorthandProperties.get(property);
1244
- if (item.size === shorthandItem.shorthandFor.size) {
1245
- if (shorthandItem.position) {
1246
- const positionValues = [];
1247
- let priority = "";
1248
- for (const { value: longhandValue, priority: longhandPriority } of item.values()) {
1249
- positionValues.push(longhandValue);
1250
- if (longhandPriority) {
1251
- priority = longhandPriority;
1252
- }
1253
- }
1254
- const value = exports.getPositionValue(positionValues, shorthandItem.position);
1255
- parsedProperties.set(property, {
1491
+ parsedProperties.set(property, createPropertyItem(property, value, priority));
1492
+ if (hasPrecedingBackground) {
1493
+ const { value: shorthandValue, priority: shorthandPriority } = properties.get(BACKGROUND);
1494
+ if ((!shorthandPriority || priority) && !hasVarFunc(shorthandValue)) {
1495
+ const replacedShorthandValue = replaceBackgroundShorthand(
1256
1496
  property,
1257
- value,
1258
- priority
1259
- });
1497
+ parsedProperties,
1498
+ parseOpt
1499
+ );
1500
+ properties.delete(BACKGROUND);
1501
+ properties.set(
1502
+ BACKGROUND,
1503
+ createPropertyItem(BACKGROUND, replacedShorthandValue, shorthandPriority)
1504
+ );
1260
1505
  }
1261
1506
  }
1262
1507
  }
1263
1508
  }
1264
- if (borderProperties.size) {
1265
- const longhandProperties = new Map();
1266
- for (const [property, item] of borderProperties) {
1267
- if (exports.shorthandProperties.has(property)) {
1268
- const { value, priority } = item;
1269
- if (property === "border") {
1270
- const lineItems = border.parse(value, {
1271
- globalObject
1272
- });
1273
- for (const [key, initialValue] of border.initialValues) {
1274
- if (!Object.hasOwn(lineItems, key)) {
1275
- lineItems[key] = initialValue;
1276
- }
1277
- }
1278
- for (const lineProperty of Object.keys(lineItems)) {
1279
- const [namePart, linePart] = lineProperty.split("-");
1280
- const lineValue = lineItems[lineProperty];
1281
- for (const position of positions) {
1282
- const longhandProperty = `${namePart}-${position}-${linePart}`;
1283
- const longhandItem = {
1284
- property: longhandProperty,
1285
- value: lineValue,
1286
- priority
1287
- };
1288
- if (longhandProperties.has(longhandProperty)) {
1289
- const { priority: longhandPriority } = longhandProperties.get(longhandProperty);
1290
- if (!longhandPriority) {
1291
- longhandProperties.delete(longhandProperty);
1292
- longhandProperties.set(longhandProperty, longhandItem);
1293
- }
1294
- } else {
1295
- longhandProperties.set(longhandProperty, longhandItem);
1296
- }
1297
- }
1298
- }
1299
- if (value) {
1300
- longhandProperties.set(borderImageProperty, {
1301
- property: borderImageProperty,
1302
- value: "none",
1303
- priority
1304
- });
1305
- }
1306
- } else {
1307
- const shorthandItem = exports.shorthandProperties.get(property);
1308
- const parsedItem = shorthandItem.parse(value, {
1309
- globalObject
1310
- });
1311
- if (Array.isArray(parsedItem)) {
1312
- const [namePart, linePart] = property.split("-");
1313
- for (const position of positions) {
1314
- const longhandProperty = `${namePart}-${position}-${linePart}`;
1315
- const longhandValue = exports.getPositionValue(parsedItem, position);
1316
- const longhandItem = {
1317
- property: longhandProperty,
1318
- value: longhandValue,
1319
- priority
1320
- };
1321
- if (longhandProperties.has(longhandProperty)) {
1322
- const { priority: longhandPriority } = longhandProperties.get(longhandProperty);
1323
- if (!longhandPriority) {
1324
- longhandProperties.delete(longhandProperty);
1325
- longhandProperties.set(longhandProperty, longhandItem);
1326
- }
1327
- } else {
1328
- longhandProperties.set(longhandProperty, longhandItem);
1329
- }
1330
- }
1331
- } else if (parsedItem) {
1332
- for (const [key, initialValue] of shorthandItem.initialValues) {
1333
- if (!Object.hasOwn(parsedItem, key)) {
1334
- parsedItem[key] = initialValue;
1335
- }
1336
- }
1337
- for (const longhandProperty of Object.keys(parsedItem)) {
1338
- const longhandValue = parsedItem[longhandProperty];
1339
- const longhandItem = {
1340
- property: longhandProperty,
1341
- value: longhandValue,
1342
- priority
1343
- };
1344
- if (longhandProperties.has(longhandProperty)) {
1345
- const { priority: longhandPriority } = longhandProperties.get(longhandProperty);
1346
- if (!longhandPriority) {
1347
- longhandProperties.delete(longhandProperty);
1348
- longhandProperties.set(longhandProperty, longhandItem);
1349
- }
1350
- } else {
1351
- longhandProperties.set(longhandProperty, longhandItem);
1352
- }
1353
- }
1354
- }
1355
- }
1356
- } else if (longhandProperties.has(property)) {
1357
- const { priority } = longhandProperties.get(property);
1358
- if (!priority) {
1359
- longhandProperties.delete(property);
1360
- longhandProperties.set(property, item);
1361
- }
1362
- } else {
1363
- longhandProperties.set(property, item);
1364
- }
1509
+ if (shorthands.size) {
1510
+ const shorthandItems = processShorthandProperties(shorthands);
1511
+ for (const [property, item] of shorthandItems) {
1512
+ parsedProperties.set(property, item);
1365
1513
  }
1366
- const normalizedProperties = prepareBorderShorthands(longhandProperties);
1367
- for (const [property, item] of normalizedProperties) {
1514
+ }
1515
+ if (borders.size) {
1516
+ const borderItems = processBorderProperties(borders, parseOpt);
1517
+ for (const [property, item] of borderItems) {
1368
1518
  parsedProperties.set(property, item);
1369
1519
  }
1370
1520
  }
1371
1521
  return parsedProperties;
1372
1522
  };
1373
1523
 
1374
- exports.normalizeBorderProperties = (properties) => {
1375
- const { lines, name, positions } = borderElements;
1376
- if (properties.has(name)) {
1377
- for (const line of lines) {
1378
- properties.delete(`${name}-${line}`);
1524
+ /**
1525
+ * Cleans up redundancy in border properties by removing longhands that are covered by shorthands.
1526
+ *
1527
+ * @param {Map} properties - The map of properties to normalize.
1528
+ * @returns {Map} The normalized properties map.
1529
+ */
1530
+ const normalizeProperties = (properties) => {
1531
+ if (properties.has(BORDER)) {
1532
+ for (const line of borderLines) {
1533
+ properties.delete(`${BORDER}-${line}`);
1379
1534
  }
1380
- for (const position of positions) {
1381
- properties.delete(`${name}-${position}`);
1382
- for (const line of lines) {
1383
- properties.delete(`${name}-${position}-${line}`);
1535
+ for (const position of borderPositions) {
1536
+ properties.delete(`${BORDER}-${position}`);
1537
+ for (const line of borderLines) {
1538
+ properties.delete(`${BORDER}-${position}-${line}`);
1384
1539
  }
1385
1540
  }
1386
- properties.delete(`${name}-image`);
1541
+ properties.delete(`${BORDER}-image`);
1387
1542
  }
1388
- for (const line of lines) {
1389
- const lineProperty = `${name}-${line}`;
1543
+ for (const line of borderLines) {
1544
+ const lineProperty = `${BORDER}-${line}`;
1390
1545
  if (properties.has(lineProperty)) {
1391
- for (const position of positions) {
1392
- const positionProperty = `${name}-${position}`;
1393
- const longhandProperty = `${name}-${position}-${line}`;
1546
+ for (const position of borderPositions) {
1547
+ const positionProperty = `${BORDER}-${position}`;
1548
+ const longhandProperty = `${BORDER}-${position}-${line}`;
1394
1549
  properties.delete(positionProperty);
1395
1550
  properties.delete(longhandProperty);
1396
1551
  }
1397
1552
  }
1398
1553
  }
1399
- for (const position of positions) {
1400
- const positionProperty = `${name}-${position}`;
1554
+ for (const position of borderPositions) {
1555
+ const positionProperty = `${BORDER}-${position}`;
1401
1556
  if (properties.has(positionProperty)) {
1402
1557
  const longhandProperties = [];
1403
- for (const line of lines) {
1404
- const longhandProperty = `${name}-${position}-${line}`;
1558
+ for (const line of borderLines) {
1559
+ const longhandProperty = `${BORDER}-${position}-${line}`;
1405
1560
  longhandProperties.push(longhandProperty);
1406
1561
  }
1407
1562
  if (longhandProperties.length === 3) {
@@ -1415,3 +1570,12 @@ exports.normalizeBorderProperties = (properties) => {
1415
1570
  }
1416
1571
  return properties;
1417
1572
  };
1573
+
1574
+ module.exports = {
1575
+ borderProperties,
1576
+ getPositionValue,
1577
+ normalizeProperties,
1578
+ prepareBorderProperties,
1579
+ prepareProperties,
1580
+ shorthandProperties
1581
+ };