cssstyle 5.2.1 → 5.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/lib/CSSStyleDeclaration.js +250 -254
  2. package/lib/generated/allProperties.js +39 -1
  3. package/lib/generated/implementedProperties.js +2219 -80
  4. package/lib/generated/properties.js +5253 -1904
  5. package/lib/normalize.js +1417 -0
  6. package/lib/parsers.js +372 -389
  7. package/lib/properties/background.js +76 -63
  8. package/lib/properties/backgroundAttachment.js +37 -22
  9. package/lib/properties/backgroundClip.js +37 -22
  10. package/lib/properties/backgroundColor.js +35 -15
  11. package/lib/properties/backgroundImage.js +49 -19
  12. package/lib/properties/backgroundOrigin.js +37 -22
  13. package/lib/properties/backgroundPosition.js +145 -128
  14. package/lib/properties/backgroundRepeat.js +55 -48
  15. package/lib/properties/backgroundSize.js +86 -46
  16. package/lib/properties/border.js +139 -22
  17. package/lib/properties/borderBottom.js +137 -21
  18. package/lib/properties/borderBottomColor.js +41 -16
  19. package/lib/properties/borderBottomStyle.js +39 -30
  20. package/lib/properties/borderBottomWidth.js +49 -16
  21. package/lib/properties/borderCollapse.js +32 -8
  22. package/lib/properties/borderColor.js +96 -23
  23. package/lib/properties/borderLeft.js +137 -21
  24. package/lib/properties/borderLeftColor.js +41 -16
  25. package/lib/properties/borderLeftStyle.js +39 -30
  26. package/lib/properties/borderLeftWidth.js +49 -16
  27. package/lib/properties/borderRight.js +137 -21
  28. package/lib/properties/borderRightColor.js +41 -16
  29. package/lib/properties/borderRightStyle.js +39 -30
  30. package/lib/properties/borderRightWidth.js +49 -16
  31. package/lib/properties/borderSpacing.js +42 -25
  32. package/lib/properties/borderStyle.js +96 -34
  33. package/lib/properties/borderTop.js +131 -15
  34. package/lib/properties/borderTopColor.js +41 -16
  35. package/lib/properties/borderTopStyle.js +39 -30
  36. package/lib/properties/borderTopWidth.js +49 -16
  37. package/lib/properties/borderWidth.js +108 -23
  38. package/lib/properties/bottom.js +40 -12
  39. package/lib/properties/clear.js +32 -22
  40. package/lib/properties/clip.js +46 -32
  41. package/lib/properties/color.js +34 -13
  42. package/lib/properties/display.js +169 -179
  43. package/lib/properties/flex.js +137 -38
  44. package/lib/properties/flexBasis.js +43 -14
  45. package/lib/properties/flexGrow.js +42 -9
  46. package/lib/properties/flexShrink.js +42 -9
  47. package/lib/properties/float.js +32 -9
  48. package/lib/properties/floodColor.js +34 -13
  49. package/lib/properties/font.js +145 -44
  50. package/lib/properties/fontFamily.js +66 -67
  51. package/lib/properties/fontSize.js +43 -26
  52. package/lib/properties/fontStyle.js +42 -11
  53. package/lib/properties/fontVariant.js +52 -15
  54. package/lib/properties/fontWeight.js +47 -15
  55. package/lib/properties/height.js +40 -13
  56. package/lib/properties/left.js +40 -12
  57. package/lib/properties/lightingColor.js +34 -13
  58. package/lib/properties/lineHeight.js +45 -18
  59. package/lib/properties/margin.js +73 -36
  60. package/lib/properties/marginBottom.js +43 -19
  61. package/lib/properties/marginLeft.js +43 -19
  62. package/lib/properties/marginRight.js +43 -19
  63. package/lib/properties/marginTop.js +43 -19
  64. package/lib/properties/opacity.js +41 -28
  65. package/lib/properties/outlineColor.js +34 -13
  66. package/lib/properties/padding.js +71 -36
  67. package/lib/properties/paddingBottom.js +44 -21
  68. package/lib/properties/paddingLeft.js +44 -19
  69. package/lib/properties/paddingRight.js +44 -19
  70. package/lib/properties/paddingTop.js +44 -19
  71. package/lib/properties/right.js +40 -12
  72. package/lib/properties/stopColor.js +34 -13
  73. package/lib/properties/top.js +40 -12
  74. package/lib/properties/webkitBorderAfterColor.js +34 -13
  75. package/lib/properties/webkitBorderBeforeColor.js +34 -13
  76. package/lib/properties/webkitBorderEndColor.js +34 -13
  77. package/lib/properties/webkitBorderStartColor.js +34 -13
  78. package/lib/properties/webkitColumnRuleColor.js +34 -13
  79. package/lib/properties/webkitTapHighlightColor.js +34 -13
  80. package/lib/properties/webkitTextEmphasisColor.js +34 -13
  81. package/lib/properties/webkitTextFillColor.js +34 -13
  82. package/lib/properties/webkitTextStrokeColor.js +34 -13
  83. package/lib/properties/width.js +40 -13
  84. package/lib/{allWebkitProperties.js → utils/allExtraProperties.js} +42 -1
  85. package/lib/utils/propertyDescriptors.js +6 -3
  86. package/package.json +11 -10
  87. package/lib/allExtraProperties.js +0 -49
  88. package/lib/shorthandProperties.js +0 -21
@@ -3,19 +3,26 @@
3
3
  * https://github.com/NV/CSSOM
4
4
  */
5
5
  "use strict";
6
- const allExtraProperties = require("./allExtraProperties");
7
- const { shorthandProperties } = require("./shorthandProperties");
6
+
8
7
  const allProperties = require("./generated/allProperties");
9
8
  const implementedProperties = require("./generated/implementedProperties");
10
9
  const generatedProperties = require("./generated/properties");
10
+ const {
11
+ borderProperties,
12
+ getPositionValue,
13
+ normalizeBorderProperties,
14
+ prepareBorderProperties,
15
+ prepareProperties,
16
+ shorthandProperties
17
+ } = require("./normalize");
11
18
  const {
12
19
  hasVarFunc,
13
- isValidPropertyValue,
20
+ isGlobalKeyword,
14
21
  parseCSS,
15
- parseShorthand,
16
- prepareValue,
17
- splitValue
22
+ parsePropertyValue,
23
+ prepareValue
18
24
  } = require("./parsers");
25
+ const allExtraProperties = require("./utils/allExtraProperties");
19
26
  const { dashedToCamelCase } = require("./utils/camelize");
20
27
  const { getPropertyDescriptor } = require("./utils/propertyDescriptors");
21
28
  const { asciiLowercase } = require("./utils/strings");
@@ -132,25 +139,30 @@ class CSSStyleDeclaration {
132
139
  for (let i = 0; i < this._length; i++) {
133
140
  const property = this[i];
134
141
  const value = this.getPropertyValue(property);
135
- const priority = this.getPropertyPriority(property);
136
- if (priority === "important") {
137
- properties.set(property, `${property}: ${value} !${priority};`);
138
- } else {
139
- if (shorthandProperties.has(property)) {
140
- const longhandProperties = shorthandProperties.get(property);
141
- for (const [longhandProperty] of longhandProperties) {
142
- if (properties.has(longhandProperty) && !this.getPropertyPriority(longhandProperty)) {
143
- properties.delete(longhandProperty);
144
- }
142
+ const priority = this._priorities.get(property) ?? "";
143
+ if (shorthandProperties.has(property)) {
144
+ const { shorthandFor } = shorthandProperties.get(property);
145
+ for (const [longhand] of shorthandFor) {
146
+ if (priority || !this._priorities.get(longhand)) {
147
+ properties.delete(longhand);
145
148
  }
146
149
  }
147
- properties.set(property, `${property}: ${value};`);
150
+ }
151
+ properties.set(property, { property, value, priority });
152
+ }
153
+ const normalizedProperties = normalizeBorderProperties(properties);
154
+ const parts = [];
155
+ for (const { property, value, priority } of normalizedProperties.values()) {
156
+ if (priority) {
157
+ parts.push(`${property}: ${value} !${priority};`);
158
+ } else {
159
+ parts.push(`${property}: ${value};`);
148
160
  }
149
161
  }
150
- return [...properties.values()].join(" ");
162
+ return parts.join(" ");
151
163
  }
152
164
 
153
- set cssText(value) {
165
+ set cssText(val) {
154
166
  if (this._readonly) {
155
167
  const msg = "cssText can not be modified.";
156
168
  const name = "NoModificationAllowedError";
@@ -165,7 +177,7 @@ class CSSStyleDeclaration {
165
177
  this._setInProgress = true;
166
178
  try {
167
179
  const valueObj = parseCSS(
168
- value,
180
+ val,
169
181
  {
170
182
  context: "declarationList",
171
183
  parseValue: false
@@ -173,23 +185,52 @@ class CSSStyleDeclaration {
173
185
  true
174
186
  );
175
187
  if (valueObj?.children) {
188
+ const properties = new Map();
176
189
  for (const item of valueObj.children) {
177
190
  const {
178
191
  important,
179
192
  property,
180
- value: { value: rawValue }
193
+ value: { value }
181
194
  } = item;
182
- const isCustomProperty = property.startsWith("--");
183
- if (
184
- isCustomProperty ||
185
- hasVarFunc(rawValue) ||
186
- isValidPropertyValue(property, rawValue)
187
- ) {
188
- this.setProperty(property, rawValue, important ? "important" : "");
189
- } else {
190
- this.removeProperty(property);
195
+ if (typeof property === "string" && typeof value === "string") {
196
+ const priority = important ? "important" : "";
197
+ const isCustomProperty = property.startsWith("--");
198
+ if (isCustomProperty || hasVarFunc(value)) {
199
+ if (properties.has(property)) {
200
+ const { priority: itemPriority } = properties.get(property);
201
+ if (!itemPriority) {
202
+ properties.set(property, { property, value, priority });
203
+ }
204
+ } else {
205
+ properties.set(property, { property, value, priority });
206
+ }
207
+ } else {
208
+ const parsedValue = parsePropertyValue(property, value, {
209
+ globalObject: this._global
210
+ });
211
+ if (parsedValue) {
212
+ if (properties.has(property)) {
213
+ const { priority: itemPriority } = properties.get(property);
214
+ if (!itemPriority) {
215
+ properties.set(property, { property, value, priority });
216
+ }
217
+ } else {
218
+ properties.set(property, { property, value, priority });
219
+ }
220
+ } else {
221
+ this.removeProperty(property);
222
+ }
223
+ }
191
224
  }
192
225
  }
226
+ const parsedProperties = prepareProperties(properties, {
227
+ globalObject: this._global
228
+ });
229
+ for (const [property, item] of parsedProperties) {
230
+ const { priority, value } = item;
231
+ this._priorities.set(property, priority);
232
+ this.setProperty(property, value, priority);
233
+ }
193
234
  }
194
235
  } catch {
195
236
  return;
@@ -252,8 +293,8 @@ class CSSStyleDeclaration {
252
293
  const msg = "1 argument required, but only 0 present.";
253
294
  throw new this._global.TypeError(msg);
254
295
  }
255
- let [index] = args;
256
- index = parseInt(index);
296
+ const [value] = args;
297
+ const index = parseInt(value);
257
298
  if (Number.isNaN(index) || index < 0 || index >= this._length) {
258
299
  return "";
259
300
  }
@@ -286,121 +327,50 @@ class CSSStyleDeclaration {
286
327
  }
287
328
 
288
329
  /**
289
- * @param {string} property
290
- * @param {string} value
291
- * @param {string?} [priority] - "important" or null
330
+ * @param {string} prop
331
+ * @param {string} val
332
+ * @param {string} prior
292
333
  */
293
- setProperty(property, value, priority = null) {
334
+ setProperty(prop, val, prior) {
294
335
  if (this._readonly) {
295
- const msg = `Property ${property} can not be modified.`;
336
+ const msg = `Property ${prop} can not be modified.`;
296
337
  const name = "NoModificationAllowedError";
297
338
  throw new this._global.DOMException(msg, name);
298
339
  }
299
- value = prepareValue(value, this._global);
340
+ const value = prepareValue(val, this._global);
300
341
  if (value === "") {
301
- this[property] = "";
302
- this.removeProperty(property);
342
+ this[prop] = "";
343
+ this.removeProperty(prop);
303
344
  return;
304
345
  }
305
- const isCustomProperty = property.startsWith("--");
346
+ const priority = prior === "important" ? "important" : "";
347
+ const isCustomProperty = prop.startsWith("--");
306
348
  if (isCustomProperty) {
307
- this._setProperty(property, value, priority);
349
+ this._setProperty(prop, value, priority);
308
350
  return;
309
351
  }
310
- property = asciiLowercase(property);
352
+ const property = asciiLowercase(prop);
311
353
  if (!allProperties.has(property) && !allExtraProperties.has(property)) {
312
354
  return;
313
355
  }
314
- this[property] = value;
315
356
  if (priority) {
316
357
  this._priorities.set(property, priority);
317
358
  } else {
318
359
  this._priorities.delete(property);
319
360
  }
361
+ this[property] = value;
320
362
  }
321
363
  }
322
364
 
323
365
  // Internal methods
324
366
  Object.defineProperties(CSSStyleDeclaration.prototype, {
325
- _shorthandGetter: {
326
- /**
327
- * @param {string} property
328
- * @param {object} shorthandFor
329
- */
330
- value(property, shorthandFor) {
331
- const parts = [];
332
- for (const key of shorthandFor.keys()) {
333
- const val = this.getPropertyValue(key);
334
- if (hasVarFunc(val)) {
335
- return "";
336
- }
337
- if (val !== "") {
338
- parts.push(val);
339
- }
340
- }
341
- if (parts.length) {
342
- return parts.join(" ");
343
- }
344
- if (this._values.has(property)) {
345
- return this.getPropertyValue(property);
346
- }
347
- return "";
348
- },
349
- enumerable: false
350
- },
351
-
352
- _implicitGetter: {
353
- /**
354
- * @param {string} property
355
- * @param {Array.<string>} positions
356
- */
357
- value(property, positions = []) {
358
- const parts = [];
359
- for (const position of positions) {
360
- const val = this.getPropertyValue(`${property}-${position}`);
361
- if (val === "" || hasVarFunc(val)) {
362
- return "";
363
- }
364
- parts.push(val);
365
- }
366
- if (!parts.length) {
367
- return "";
368
- }
369
- switch (positions.length) {
370
- case 4: {
371
- const [top, right, bottom, left] = parts;
372
- if (top === right && top === bottom && right === left) {
373
- return top;
374
- }
375
- if (top !== right && top === bottom && right === left) {
376
- return `${top} ${right}`;
377
- }
378
- if (top !== right && top !== bottom && right === left) {
379
- return `${top} ${right} ${bottom}`;
380
- }
381
- return `${top} ${right} ${bottom} ${left}`;
382
- }
383
- case 2: {
384
- const [x, y] = parts;
385
- if (x === y) {
386
- return x;
387
- }
388
- return `${x} ${y}`;
389
- }
390
- default:
391
- return "";
392
- }
393
- },
394
- enumerable: false
395
- },
396
-
397
367
  _setProperty: {
398
368
  /**
399
369
  * @param {string} property
400
370
  * @param {string} val
401
- * @param {string?} [priority]
371
+ * @param {string} priority
402
372
  */
403
- value(property, val, priority = null) {
373
+ value(property, val, priority) {
404
374
  if (typeof val !== "string") {
405
375
  return;
406
376
  }
@@ -424,12 +394,12 @@ Object.defineProperties(CSSStyleDeclaration.prototype, {
424
394
  this[this._length] = property;
425
395
  this._length++;
426
396
  }
427
- this._values.set(property, val);
428
- if (priority) {
397
+ if (priority === "important") {
429
398
  this._priorities.set(property, priority);
430
399
  } else {
431
400
  this._priorities.delete(property);
432
401
  }
402
+ this._values.set(property, val);
433
403
  if (
434
404
  typeof this._onChange === "function" &&
435
405
  this.cssText !== originalText &&
@@ -441,178 +411,201 @@ Object.defineProperties(CSSStyleDeclaration.prototype, {
441
411
  enumerable: false
442
412
  },
443
413
 
444
- _shorthandSetter: {
414
+ _borderSetter: {
445
415
  /**
446
- * @param {string} property
447
- * @param {string} val
448
- * @param {object} shorthandFor
416
+ * @param {string} prop
417
+ * @param {object|Array|string} val
418
+ * @param {string} prior
449
419
  */
450
- value(property, val, shorthandFor) {
451
- val = prepareValue(val, this._global);
452
- const obj = parseShorthand(val, shorthandFor);
453
- if (!obj) {
454
- return;
455
- }
456
- for (const subprop of Object.keys(obj)) {
457
- // In case subprop is an implicit property, this will clear *its*
458
- // subpropertiesX.
459
- const camel = dashedToCamelCase(subprop);
460
- this[camel] = obj[subprop];
461
- // In case it gets translated into something else (0 -> 0px).
462
- obj[subprop] = this[camel];
463
- this.removeProperty(subprop);
464
- // Don't add in empty properties.
465
- if (obj[subprop] !== "") {
466
- this._values.set(subprop, obj[subprop]);
420
+ value(prop, val, prior) {
421
+ const properties = new Map();
422
+ if (prop === "border") {
423
+ let priority = "";
424
+ if (typeof prior === "string") {
425
+ priority = prior;
426
+ } else {
427
+ priority = this._priorities.get(prop) ?? "";
467
428
  }
468
- }
469
- for (const [subprop] of shorthandFor) {
470
- if (!Object.hasOwn(obj, subprop)) {
471
- this.removeProperty(subprop);
472
- this._values.delete(subprop);
429
+ properties.set(prop, { propery: prop, value: val, priority });
430
+ } else {
431
+ for (let i = 0; i < this._length; i++) {
432
+ const property = this[i];
433
+ if (borderProperties.has(property)) {
434
+ const value = this.getPropertyValue(property);
435
+ const longhandPriority = this._priorities.get(property) ?? "";
436
+ let priority = longhandPriority;
437
+ if (prop === property && typeof prior === "string") {
438
+ priority = prior;
439
+ }
440
+ properties.set(property, { property, value, priority });
441
+ }
473
442
  }
474
443
  }
475
- // In case the value is something like 'none' that removes all values,
476
- // check that the generated one is not empty, first remove the property,
477
- // if it already exists, then call the shorthandGetter, if it's an empty
478
- // string, don't set the property.
479
- this.removeProperty(property);
480
- const calculated = this._shorthandGetter(property, shorthandFor);
481
- if (calculated !== "") {
482
- this._setProperty(property, calculated);
444
+ const parsedProperties = prepareBorderProperties(prop, val, prior, properties, {
445
+ globalObject: this._global
446
+ });
447
+ for (const [property, item] of parsedProperties) {
448
+ const { priority, value } = item;
449
+ this._setProperty(property, value, priority);
483
450
  }
484
- return obj;
485
451
  },
486
452
  enumerable: false
487
453
  },
488
454
 
489
- // Companion to shorthandSetter, but for the individual parts which takes
490
- // position value in the middle.
491
- _midShorthandSetter: {
455
+ _flexBoxSetter: {
492
456
  /**
493
- * @param {string} property
457
+ * @param {string} prop
494
458
  * @param {string} val
495
- * @param {object} shorthandFor
496
- * @param {Array.<string>} positions
459
+ * @param {string} prior
460
+ * @param {string} shorthandProperty
497
461
  */
498
- value(property, val, shorthandFor, positions = []) {
499
- val = prepareValue(val, this._global);
500
- const obj = this._shorthandSetter(property, val, shorthandFor);
501
- if (!obj) {
462
+ value(prop, val, prior, shorthandProperty) {
463
+ if (!shorthandProperty || !shorthandProperties.has(shorthandProperty)) {
502
464
  return;
503
465
  }
504
- for (const position of positions) {
505
- this.removeProperty(`${property}-${position}`);
506
- this._values.set(`${property}-${position}`, val);
466
+ const shorthandPriority = this._priorities.get(shorthandProperty);
467
+ this.removeProperty(shorthandProperty);
468
+ let priority = "";
469
+ if (typeof prior === "string") {
470
+ priority = prior;
471
+ } else {
472
+ priority = this._priorities.get(prop) ?? "";
473
+ }
474
+ this.removeProperty(prop);
475
+ if (shorthandPriority && priority) {
476
+ this._setProperty(prop, val);
477
+ } else {
478
+ this._setProperty(prop, val, priority);
479
+ }
480
+ if (val && !hasVarFunc(val)) {
481
+ const longhandValues = [];
482
+ const shorthandItem = shorthandProperties.get(shorthandProperty);
483
+ let hasGlobalKeyword = false;
484
+ for (const [longhandProperty] of shorthandItem.shorthandFor) {
485
+ if (longhandProperty === prop) {
486
+ if (isGlobalKeyword(val)) {
487
+ hasGlobalKeyword = true;
488
+ }
489
+ longhandValues.push(val);
490
+ } else {
491
+ const longhandValue = this.getPropertyValue(longhandProperty);
492
+ const longhandPriority = this._priorities.get(longhandProperty) ?? "";
493
+ if (!longhandValue || longhandPriority !== priority) {
494
+ break;
495
+ }
496
+ if (isGlobalKeyword(longhandValue)) {
497
+ hasGlobalKeyword = true;
498
+ }
499
+ longhandValues.push(longhandValue);
500
+ }
501
+ }
502
+ if (longhandValues.length === shorthandItem.shorthandFor.size) {
503
+ if (hasGlobalKeyword) {
504
+ const [firstValue, ...restValues] = longhandValues;
505
+ if (restValues.every((value) => value === firstValue)) {
506
+ this._setProperty(shorthandProperty, firstValue, priority);
507
+ }
508
+ } else {
509
+ const parsedValue = shorthandItem.parse(longhandValues.join(" "));
510
+ const shorthandValue = Object.values(parsedValue).join(" ");
511
+ this._setProperty(shorthandProperty, shorthandValue, priority);
512
+ }
513
+ }
507
514
  }
508
515
  },
509
516
  enumerable: false
510
517
  },
511
518
 
512
- _implicitSetter: {
519
+ _positionShorthandSetter: {
513
520
  /**
514
- * @param {string} prefix
515
- * @param {string} part
516
- * @param {string} val
517
- * @param {Function} isValid
518
- * @param {Function} parser
519
- * @param {Array.<string>} positions
521
+ * @param {string} prop
522
+ * @param {Array|string} val
523
+ * @param {string} prior
520
524
  */
521
- value(prefix, part, val, isValid, parser, positions = []) {
522
- val = prepareValue(val, this._global);
523
- if (typeof val !== "string") {
525
+ value(prop, val, prior) {
526
+ if (!shorthandProperties.has(prop)) {
524
527
  return;
525
528
  }
526
- part ||= "";
527
- if (part) {
528
- part = `-${part}`;
529
- }
530
- const shorthandProp = `${prefix}${part}`;
531
- let parts = [];
532
- if (val === "") {
533
- parts.push(val);
534
- } else if (isValidPropertyValue(shorthandProp, val)) {
535
- parts.push(...splitValue(val));
536
- }
537
- if (!parts.length || parts.length > positions.length || !parts.every(isValid)) {
529
+ const shorthandValues = [];
530
+ if (Array.isArray(val)) {
531
+ shorthandValues.push(...val);
532
+ } else if (typeof val === "string") {
533
+ shorthandValues.push(val);
534
+ } else {
538
535
  return;
539
536
  }
540
- parts = parts.map((p) => parser(p));
541
- this._setProperty(shorthandProp, parts.join(" "));
542
- switch (positions.length) {
543
- case 4:
544
- if (parts.length === 1) {
545
- parts.push(parts[0], parts[0], parts[0]);
546
- } else if (parts.length === 2) {
547
- parts.push(parts[0], parts[1]);
548
- } else if (parts.length === 3) {
549
- parts.push(parts[1]);
550
- }
551
- break;
552
- case 2:
553
- if (parts.length === 1) {
554
- parts.push(parts[0]);
537
+ let priority = "";
538
+ if (typeof prior === "string") {
539
+ priority = prior;
540
+ } else {
541
+ priority = this._priorities.get(prop) ?? "";
542
+ }
543
+ const { position, shorthandFor } = shorthandProperties.get(prop);
544
+ let hasPriority = false;
545
+ for (const [longhandProperty, longhandItem] of shorthandFor) {
546
+ const { position: longhandPosition } = longhandItem;
547
+ const longhandValue = getPositionValue(shorthandValues, longhandPosition);
548
+ if (priority) {
549
+ this._setProperty(longhandProperty, longhandValue, priority);
550
+ } else {
551
+ const longhandPriority = this._priorities.get(longhandProperty) ?? "";
552
+ if (longhandPriority) {
553
+ hasPriority = true;
554
+ } else {
555
+ this._setProperty(longhandProperty, longhandValue, priority);
555
556
  }
556
- break;
557
- default:
557
+ }
558
558
  }
559
- for (let i = 0; i < positions.length; i++) {
560
- const property = `${prefix}-${positions[i]}${part}`;
561
- this.removeProperty(property);
562
- this._values.set(property, parts[i]);
559
+ if (hasPriority) {
560
+ this.removeProperty(prop);
561
+ } else {
562
+ const shorthandValue = getPositionValue(shorthandValues, position);
563
+ this._setProperty(prop, shorthandValue, priority);
563
564
  }
564
565
  },
565
566
  enumerable: false
566
567
  },
567
568
 
568
- // Companion to implicitSetter, but for the individual parts.
569
- // This sets the individual value, and checks to see if all sub-parts are
570
- // set. If so, it sets the shorthand version and removes the individual parts
571
- // from the cssText.
572
- _subImplicitSetter: {
569
+ _positionLonghandSetter: {
573
570
  /**
574
- * @param {string} prefix
575
- * @param {string} part
571
+ * @param {string} prop
576
572
  * @param {string} val
577
- * @param {Function} isValid
578
- * @param {Function} parser
579
- * @param {Array.<string>} positions
573
+ * @param {string} prior
574
+ * @param {string} shorthandProperty
580
575
  */
581
- value(prefix, part, val, isValid, parser, positions = []) {
582
- val = prepareValue(val, this._global);
583
- if (typeof val !== "string" || !isValid(val)) {
576
+ value(prop, val, prior, shorthandProperty) {
577
+ if (!shorthandProperty || !shorthandProperties.has(shorthandProperty)) {
584
578
  return;
585
579
  }
586
- val = parser(val);
587
- const property = `${prefix}-${part}`;
588
- this._setProperty(property, val);
589
- const combinedPriority = this.getPropertyPriority(prefix);
590
- const subparts = [];
591
- for (const position of positions) {
592
- subparts.push(`${prefix}-${position}`);
580
+ const shorthandPriority = this._priorities.get(shorthandProperty);
581
+ this.removeProperty(shorthandProperty);
582
+ let priority = "";
583
+ if (typeof prior === "string") {
584
+ priority = prior;
585
+ } else {
586
+ priority = this._priorities.get(prop) ?? "";
593
587
  }
594
- const parts = subparts.map((subpart) => this._values.get(subpart));
595
- const priorities = subparts.map((subpart) => this.getPropertyPriority(subpart));
596
- const [priority] = priorities;
597
- // Combine into a single property if all values are set and have the same
598
- // priority.
599
- if (
600
- priority === combinedPriority &&
601
- parts.every((p) => p) &&
602
- priorities.every((p) => p === priority)
603
- ) {
604
- for (let i = 0; i < subparts.length; i++) {
605
- this.removeProperty(subparts[i]);
606
- this._values.set(subparts[i], parts[i]);
607
- }
608
- this._setProperty(prefix, parts.join(" "), priority);
588
+ this.removeProperty(prop);
589
+ if (shorthandPriority && priority) {
590
+ this._setProperty(prop, val);
609
591
  } else {
610
- this.removeProperty(prefix);
611
- for (let i = 0; i < subparts.length; i++) {
612
- // The property we're setting won't be important, the rest will either
613
- // keep their priority or inherit it from the combined property
614
- const subPriority = subparts[i] === property ? "" : priorities[i] || combinedPriority;
615
- this._setProperty(subparts[i], parts[i], subPriority);
592
+ this._setProperty(prop, val, priority);
593
+ }
594
+ if (val && !hasVarFunc(val)) {
595
+ const longhandValues = [];
596
+ const { shorthandFor, position: shorthandPosition } =
597
+ shorthandProperties.get(shorthandProperty);
598
+ for (const [longhandProperty] of shorthandFor) {
599
+ const longhandValue = this.getPropertyValue(longhandProperty);
600
+ const longhandPriority = this._priorities.get(longhandProperty) ?? "";
601
+ if (!longhandValue || longhandPriority !== priority) {
602
+ return;
603
+ }
604
+ longhandValues.push(longhandValue);
605
+ }
606
+ if (longhandValues.length === shorthandFor.size) {
607
+ const replacedValue = getPositionValue(longhandValues, shorthandPosition);
608
+ this._setProperty(shorthandProperty, replacedValue);
616
609
  }
617
610
  }
618
611
  },
@@ -624,7 +617,7 @@ Object.defineProperties(CSSStyleDeclaration.prototype, {
624
617
  Object.defineProperties(CSSStyleDeclaration.prototype, generatedProperties);
625
618
 
626
619
  // Additional properties
627
- [...allProperties, ...allExtraProperties].forEach(function (property) {
620
+ [...allProperties, ...allExtraProperties].forEach((property) => {
628
621
  if (!implementedProperties.has(property)) {
629
622
  const declaration = getPropertyDescriptor(property);
630
623
  Object.defineProperty(CSSStyleDeclaration.prototype, property, declaration);
@@ -637,4 +630,7 @@ Object.defineProperties(CSSStyleDeclaration.prototype, generatedProperties);
637
630
  }
638
631
  });
639
632
 
640
- exports.CSSStyleDeclaration = CSSStyleDeclaration;
633
+ module.exports = {
634
+ CSSStyleDeclaration,
635
+ propertyList: Object.fromEntries(implementedProperties)
636
+ };