cssstyle 5.3.5 → 5.3.7

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