cssstyle 5.3.7 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/CSSStyleDeclaration.js +359 -395
- package/lib/generated/.gitkeep +0 -0
- package/lib/generated/propertyDefinitions.js +3685 -1498
- package/lib/generated/propertyDescriptors.js +1705 -0
- package/lib/index.js +9 -0
- package/lib/normalize.js +127 -253
- package/lib/parsers.js +152 -164
- package/lib/properties/background.js +201 -202
- package/lib/properties/backgroundAttachment.js +35 -33
- package/lib/properties/backgroundClip.js +35 -33
- package/lib/properties/backgroundColor.js +26 -24
- package/lib/properties/backgroundImage.js +36 -34
- package/lib/properties/backgroundOrigin.js +35 -33
- package/lib/properties/backgroundPosition.js +57 -57
- package/lib/properties/backgroundRepeat.js +40 -37
- package/lib/properties/backgroundSize.js +38 -34
- package/lib/properties/border.js +41 -34
- package/lib/properties/{webkitBorderEndColor.js → borderBlockEndColor.js} +26 -22
- package/lib/properties/{webkitBorderAfterColor.js → borderBlockStartColor.js} +26 -22
- package/lib/properties/borderBottom.js +40 -36
- package/lib/properties/borderBottomColor.js +25 -21
- package/lib/properties/borderBottomStyle.js +25 -21
- package/lib/properties/borderBottomWidth.js +28 -24
- package/lib/properties/borderCollapse.js +25 -21
- package/lib/properties/borderColor.js +36 -33
- package/lib/properties/{webkitBorderStartColor.js → borderInlineEndColor.js} +26 -22
- package/lib/properties/borderInlineStartColor.js +49 -0
- package/lib/properties/borderLeft.js +40 -36
- package/lib/properties/borderLeftColor.js +25 -21
- package/lib/properties/borderLeftStyle.js +25 -21
- package/lib/properties/borderLeftWidth.js +28 -24
- package/lib/properties/borderRight.js +40 -36
- package/lib/properties/borderRightColor.js +25 -21
- package/lib/properties/borderRightStyle.js +25 -21
- package/lib/properties/borderRightWidth.js +28 -24
- package/lib/properties/borderSpacing.js +33 -29
- package/lib/properties/borderStyle.js +36 -33
- package/lib/properties/borderTop.js +40 -36
- package/lib/properties/borderTopColor.js +25 -21
- package/lib/properties/borderTopStyle.js +25 -21
- package/lib/properties/borderTopWidth.js +28 -24
- package/lib/properties/borderWidth.js +36 -33
- package/lib/properties/bottom.js +27 -23
- package/lib/properties/clear.js +25 -21
- package/lib/properties/clip.js +37 -31
- package/lib/properties/color.js +25 -21
- package/lib/properties/display.js +36 -30
- package/lib/properties/flex.js +53 -45
- package/lib/properties/flexBasis.js +28 -26
- package/lib/properties/flexGrow.js +28 -26
- package/lib/properties/flexShrink.js +28 -26
- package/lib/properties/float.js +25 -21
- package/lib/properties/floodColor.js +25 -21
- package/lib/properties/font.js +89 -118
- package/lib/properties/fontFamily.js +38 -33
- package/lib/properties/fontSize.js +29 -27
- package/lib/properties/fontStyle.js +38 -34
- package/lib/properties/fontVariant.js +35 -33
- package/lib/properties/fontWeight.js +33 -31
- package/lib/properties/height.js +28 -24
- package/lib/properties/left.js +27 -23
- package/lib/properties/lightingColor.js +25 -21
- package/lib/properties/lineHeight.js +28 -26
- package/lib/properties/margin.js +40 -34
- package/lib/properties/marginBottom.js +30 -27
- package/lib/properties/marginLeft.js +30 -27
- package/lib/properties/marginRight.js +30 -27
- package/lib/properties/marginTop.js +30 -27
- package/lib/properties/opacity.js +27 -23
- package/lib/properties/outlineColor.js +25 -21
- package/lib/properties/padding.js +40 -34
- package/lib/properties/paddingBottom.js +31 -28
- package/lib/properties/paddingLeft.js +31 -28
- package/lib/properties/paddingRight.js +31 -28
- package/lib/properties/paddingTop.js +31 -28
- package/lib/properties/right.js +27 -23
- package/lib/properties/stopColor.js +25 -21
- package/lib/properties/{webkitBorderBeforeColor.js → textEmphasisColor.js} +26 -22
- package/lib/properties/top.js +27 -23
- package/lib/properties/webkitTextFillColor.js +25 -21
- package/lib/properties/webkitTextStrokeColor.js +25 -21
- package/lib/properties/width.js +28 -24
- package/lib/utils/propertyDescriptors.js +129 -42
- package/lib/utils/strings.js +11 -156
- package/package.json +11 -21
- package/lib/generated/allProperties.js +0 -653
- package/lib/generated/implementedProperties.js +0 -1466
- package/lib/generated/properties.js +0 -6637
- package/lib/properties/webkitColumnRuleColor.js +0 -45
- package/lib/properties/webkitTapHighlightColor.js +0 -45
- package/lib/properties/webkitTextEmphasisColor.js +0 -45
- package/lib/utils/allExtraProperties.js +0 -155
- package/lib/utils/camelize.js +0 -37
|
@@ -4,9 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
"use strict";
|
|
6
6
|
|
|
7
|
-
const
|
|
8
|
-
const implementedProperties = require("./generated/implementedProperties");
|
|
9
|
-
const generatedProperties = require("./generated/properties");
|
|
7
|
+
const propertyDescriptors = require("./generated/propertyDescriptors");
|
|
10
8
|
const {
|
|
11
9
|
borderProperties,
|
|
12
10
|
getPositionValue,
|
|
@@ -15,16 +13,7 @@ const {
|
|
|
15
13
|
prepareProperties,
|
|
16
14
|
shorthandProperties
|
|
17
15
|
} = require("./normalize");
|
|
18
|
-
const {
|
|
19
|
-
hasVarFunc,
|
|
20
|
-
isGlobalKeyword,
|
|
21
|
-
parseCSS,
|
|
22
|
-
parsePropertyValue,
|
|
23
|
-
prepareValue
|
|
24
|
-
} = require("./parsers");
|
|
25
|
-
const allExtraProperties = require("./utils/allExtraProperties");
|
|
26
|
-
const { dashedToCamelCase } = require("./utils/camelize");
|
|
27
|
-
const { getPropertyDescriptor } = require("./utils/propertyDescriptors");
|
|
16
|
+
const { hasVarFunc, isGlobalKeyword, parseCSS, parsePropertyValue, prepareValue } = require("./parsers");
|
|
28
17
|
const { asciiLowercase } = require("./utils/strings");
|
|
29
18
|
|
|
30
19
|
/**
|
|
@@ -32,88 +21,38 @@ const { asciiLowercase } = require("./utils/strings");
|
|
|
32
21
|
*/
|
|
33
22
|
class CSSStyleDeclaration {
|
|
34
23
|
/**
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* @param {
|
|
24
|
+
* Creates a new CSSStyleDeclaration instance.
|
|
25
|
+
*
|
|
26
|
+
* @param {Function} [onChangeCallback] - Callback triggered when style changes.
|
|
27
|
+
* @param {object} [opt] - Options.
|
|
28
|
+
* @param {object} [opt.context] - The context object (Window, Element, or CSSRule).
|
|
38
29
|
*/
|
|
39
|
-
constructor(onChangeCallback,
|
|
40
|
-
//
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
enumerable: false,
|
|
58
|
-
writable: true
|
|
59
|
-
},
|
|
60
|
-
|
|
61
|
-
// CSSRule
|
|
62
|
-
_parentNode: {
|
|
63
|
-
value: null,
|
|
64
|
-
enumerable: false,
|
|
65
|
-
writable: true
|
|
66
|
-
},
|
|
67
|
-
|
|
68
|
-
_onChange: {
|
|
69
|
-
value: null,
|
|
70
|
-
enumerable: false,
|
|
71
|
-
writable: true
|
|
72
|
-
},
|
|
73
|
-
|
|
74
|
-
_values: {
|
|
75
|
-
value: new Map(),
|
|
76
|
-
enumerable: false,
|
|
77
|
-
writable: true
|
|
78
|
-
},
|
|
30
|
+
constructor(onChangeCallback, { context } = {}) {
|
|
31
|
+
// Internals for jsdom
|
|
32
|
+
this._global = globalThis;
|
|
33
|
+
this._onChange = onChangeCallback;
|
|
34
|
+
|
|
35
|
+
// Internals for CSS declaration block
|
|
36
|
+
// @see https://drafts.csswg.org/cssom/#css-declaration-blocks
|
|
37
|
+
this._computed = false;
|
|
38
|
+
this._ownerNode = null;
|
|
39
|
+
this._parentRule = null;
|
|
40
|
+
this._readonly = false;
|
|
41
|
+
this._updating = false;
|
|
42
|
+
|
|
43
|
+
// Other internals
|
|
44
|
+
this._length = 0;
|
|
45
|
+
this._propertyIndices = new Map();
|
|
46
|
+
this._priorities = new Map();
|
|
47
|
+
this._values = new Map();
|
|
79
48
|
|
|
80
|
-
_priorities: {
|
|
81
|
-
value: new Map(),
|
|
82
|
-
enumerable: false,
|
|
83
|
-
writable: true
|
|
84
|
-
},
|
|
85
|
-
|
|
86
|
-
_length: {
|
|
87
|
-
value: 0,
|
|
88
|
-
enumerable: false,
|
|
89
|
-
writable: true
|
|
90
|
-
},
|
|
91
|
-
|
|
92
|
-
_computed: {
|
|
93
|
-
value: false,
|
|
94
|
-
enumerable: false,
|
|
95
|
-
writable: true
|
|
96
|
-
},
|
|
97
|
-
|
|
98
|
-
_readonly: {
|
|
99
|
-
value: false,
|
|
100
|
-
enumerable: false,
|
|
101
|
-
writable: true
|
|
102
|
-
},
|
|
103
|
-
|
|
104
|
-
_setInProgress: {
|
|
105
|
-
value: false,
|
|
106
|
-
enumerable: false,
|
|
107
|
-
writable: true
|
|
108
|
-
}
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
const { context } = opt;
|
|
112
49
|
if (context) {
|
|
113
50
|
if (typeof context.getComputedStyle === "function") {
|
|
114
51
|
this._global = context;
|
|
115
52
|
this._computed = true;
|
|
116
|
-
|
|
53
|
+
// FIXME: The `_readonly` flag should initially be `false` to be editable,
|
|
54
|
+
// but should eventually be set to `true`.
|
|
55
|
+
// this._readonly = true;
|
|
117
56
|
} else if (context.nodeType === 1 && Object.hasOwn(context, "style")) {
|
|
118
57
|
this._global = context.ownerDocument.defaultView;
|
|
119
58
|
this._ownerNode = context;
|
|
@@ -126,11 +65,13 @@ class CSSStyleDeclaration {
|
|
|
126
65
|
}
|
|
127
66
|
}
|
|
128
67
|
}
|
|
129
|
-
if (typeof onChangeCallback === "function") {
|
|
130
|
-
this._onChange = onChangeCallback;
|
|
131
|
-
}
|
|
132
68
|
}
|
|
133
69
|
|
|
70
|
+
/**
|
|
71
|
+
* Returns the textual representation of the declaration block.
|
|
72
|
+
*
|
|
73
|
+
* @returns {string} The serialized CSS text.
|
|
74
|
+
*/
|
|
134
75
|
get cssText() {
|
|
135
76
|
if (this._computed) {
|
|
136
77
|
return "";
|
|
@@ -162,28 +103,27 @@ class CSSStyleDeclaration {
|
|
|
162
103
|
return parts.join(" ");
|
|
163
104
|
}
|
|
164
105
|
|
|
165
|
-
|
|
106
|
+
/**
|
|
107
|
+
* Sets the textual representation of the declaration block.
|
|
108
|
+
* This clears all existing properties and parses the new CSS text.
|
|
109
|
+
*
|
|
110
|
+
* @param {string} text - The new CSS text.
|
|
111
|
+
*/
|
|
112
|
+
set cssText(text) {
|
|
166
113
|
if (this._readonly) {
|
|
167
114
|
const msg = "cssText can not be modified.";
|
|
168
115
|
const name = "NoModificationAllowedError";
|
|
169
116
|
throw new this._global.DOMException(msg, name);
|
|
170
117
|
}
|
|
171
|
-
|
|
118
|
+
this._clearIndexedProperties();
|
|
172
119
|
this._values.clear();
|
|
173
120
|
this._priorities.clear();
|
|
174
|
-
if (this._parentRule || (this._ownerNode && this.
|
|
121
|
+
if (this._parentRule || (this._ownerNode && this._updating)) {
|
|
175
122
|
return;
|
|
176
123
|
}
|
|
177
124
|
try {
|
|
178
|
-
this.
|
|
179
|
-
const valueObj = parseCSS(
|
|
180
|
-
val,
|
|
181
|
-
{
|
|
182
|
-
context: "declarationList",
|
|
183
|
-
parseValue: false
|
|
184
|
-
},
|
|
185
|
-
true
|
|
186
|
-
);
|
|
125
|
+
this._updating = true;
|
|
126
|
+
const valueObj = parseCSS(text, { context: "declarationList", parseValue: false });
|
|
187
127
|
if (valueObj?.children) {
|
|
188
128
|
const properties = new Map();
|
|
189
129
|
let shouldSkipNext = false;
|
|
@@ -217,9 +157,7 @@ class CSSStyleDeclaration {
|
|
|
217
157
|
properties.set(property, { property, value, priority });
|
|
218
158
|
}
|
|
219
159
|
} else {
|
|
220
|
-
const parsedValue = parsePropertyValue(property, value
|
|
221
|
-
globalObject: this._global
|
|
222
|
-
});
|
|
160
|
+
const parsedValue = parsePropertyValue(property, value);
|
|
223
161
|
if (parsedValue) {
|
|
224
162
|
if (properties.has(property)) {
|
|
225
163
|
const { priority: itemPriority } = properties.get(property);
|
|
@@ -235,9 +173,7 @@ class CSSStyleDeclaration {
|
|
|
235
173
|
}
|
|
236
174
|
}
|
|
237
175
|
}
|
|
238
|
-
const parsedProperties = prepareProperties(properties
|
|
239
|
-
globalObject: this._global
|
|
240
|
-
});
|
|
176
|
+
const parsedProperties = prepareProperties(properties);
|
|
241
177
|
for (const [property, item] of parsedProperties) {
|
|
242
178
|
const { priority, value } = item;
|
|
243
179
|
this._priorities.set(property, priority);
|
|
@@ -247,49 +183,64 @@ class CSSStyleDeclaration {
|
|
|
247
183
|
} catch {
|
|
248
184
|
return;
|
|
249
185
|
} finally {
|
|
250
|
-
this.
|
|
186
|
+
this._updating = false;
|
|
251
187
|
}
|
|
252
|
-
if (
|
|
188
|
+
if (this._onChange) {
|
|
253
189
|
this._onChange(this.cssText);
|
|
254
190
|
}
|
|
255
191
|
}
|
|
256
192
|
|
|
193
|
+
/**
|
|
194
|
+
* Returns the number of properties in the declaration block.
|
|
195
|
+
*
|
|
196
|
+
* @returns {number} The property count.
|
|
197
|
+
*/
|
|
257
198
|
get length() {
|
|
258
199
|
return this._length;
|
|
259
200
|
}
|
|
260
201
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
delete this[i];
|
|
267
|
-
}
|
|
268
|
-
this._length = len;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
// Readonly
|
|
202
|
+
/**
|
|
203
|
+
* Returns the CSSRule that is the parent of this declaration block.
|
|
204
|
+
*
|
|
205
|
+
* @returns {object|null} The parent CSSRule or null.
|
|
206
|
+
*/
|
|
272
207
|
get parentRule() {
|
|
273
208
|
return this._parentRule;
|
|
274
209
|
}
|
|
275
210
|
|
|
211
|
+
/**
|
|
212
|
+
* Alias for the "float" property.
|
|
213
|
+
*
|
|
214
|
+
* @returns {string} The value of the "float" property.
|
|
215
|
+
*/
|
|
276
216
|
get cssFloat() {
|
|
277
217
|
return this.getPropertyValue("float");
|
|
278
218
|
}
|
|
279
219
|
|
|
220
|
+
/**
|
|
221
|
+
* Sets the "float" property.
|
|
222
|
+
*
|
|
223
|
+
* @param {string} value - The new value for "float".
|
|
224
|
+
*/
|
|
280
225
|
set cssFloat(value) {
|
|
281
226
|
this._setProperty("float", value);
|
|
282
227
|
}
|
|
283
228
|
|
|
284
229
|
/**
|
|
285
|
-
*
|
|
230
|
+
* Returns the priority of the specified property (e.g. "important").
|
|
231
|
+
*
|
|
232
|
+
* @param {string} property - The property name.
|
|
233
|
+
* @returns {string} The priority string, or empty string if not set.
|
|
286
234
|
*/
|
|
287
235
|
getPropertyPriority(property) {
|
|
288
236
|
return this._priorities.get(property) || "";
|
|
289
237
|
}
|
|
290
238
|
|
|
291
239
|
/**
|
|
292
|
-
*
|
|
240
|
+
* Returns the value of the specified property.
|
|
241
|
+
*
|
|
242
|
+
* @param {string} property - The property name.
|
|
243
|
+
* @returns {string} The property value, or empty string if not set.
|
|
293
244
|
*/
|
|
294
245
|
getPropertyValue(property) {
|
|
295
246
|
if (this._values.has(property)) {
|
|
@@ -299,7 +250,10 @@ class CSSStyleDeclaration {
|
|
|
299
250
|
}
|
|
300
251
|
|
|
301
252
|
/**
|
|
302
|
-
*
|
|
253
|
+
* Returns the property name at the specified index.
|
|
254
|
+
*
|
|
255
|
+
* @param {...number} args - The index (only the first argument is used).
|
|
256
|
+
* @returns {string} The property name, or empty string if index is invalid.
|
|
303
257
|
*/
|
|
304
258
|
item(...args) {
|
|
305
259
|
if (!args.length) {
|
|
@@ -315,7 +269,10 @@ class CSSStyleDeclaration {
|
|
|
315
269
|
}
|
|
316
270
|
|
|
317
271
|
/**
|
|
318
|
-
*
|
|
272
|
+
* Removes the specified property from the declaration block.
|
|
273
|
+
*
|
|
274
|
+
* @param {string} property - The property name to remove.
|
|
275
|
+
* @returns {string} The value of the removed property.
|
|
319
276
|
*/
|
|
320
277
|
removeProperty(property) {
|
|
321
278
|
if (this._readonly) {
|
|
@@ -329,10 +286,10 @@ class CSSStyleDeclaration {
|
|
|
329
286
|
const prevValue = this._values.get(property);
|
|
330
287
|
this._values.delete(property);
|
|
331
288
|
this._priorities.delete(property);
|
|
332
|
-
const index =
|
|
289
|
+
const index = this._getIndexOf(property);
|
|
333
290
|
if (index >= 0) {
|
|
334
|
-
|
|
335
|
-
if (
|
|
291
|
+
this._removeIndexedProperty(index);
|
|
292
|
+
if (this._onChange) {
|
|
336
293
|
this._onChange(this.cssText);
|
|
337
294
|
}
|
|
338
295
|
}
|
|
@@ -340,30 +297,34 @@ class CSSStyleDeclaration {
|
|
|
340
297
|
}
|
|
341
298
|
|
|
342
299
|
/**
|
|
343
|
-
*
|
|
344
|
-
*
|
|
345
|
-
* @param {string}
|
|
300
|
+
* Sets a property value with an optional priority.
|
|
301
|
+
*
|
|
302
|
+
* @param {string} property - The property name.
|
|
303
|
+
* @param {string} value - The property value.
|
|
304
|
+
* @param {string} [priority=""] - The priority (e.g. "important").
|
|
346
305
|
*/
|
|
347
|
-
setProperty(
|
|
306
|
+
setProperty(property, value, priority = "") {
|
|
348
307
|
if (this._readonly) {
|
|
349
|
-
const msg = `Property ${
|
|
308
|
+
const msg = `Property ${property} can not be modified.`;
|
|
350
309
|
const name = "NoModificationAllowedError";
|
|
351
310
|
throw new this._global.DOMException(msg, name);
|
|
352
311
|
}
|
|
353
|
-
|
|
312
|
+
value = prepareValue(value);
|
|
354
313
|
if (value === "") {
|
|
355
|
-
|
|
356
|
-
|
|
314
|
+
if (Object.hasOwn(propertyDescriptors, property)) {
|
|
315
|
+
// TODO: Refactor handlers to not require `.call()`.
|
|
316
|
+
propertyDescriptors[property].set.call(this, value);
|
|
317
|
+
}
|
|
318
|
+
this.removeProperty(property);
|
|
357
319
|
return;
|
|
358
320
|
}
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
this._setProperty(prop, value, priority);
|
|
321
|
+
// Custom property
|
|
322
|
+
if (property.startsWith("--")) {
|
|
323
|
+
this._setProperty(property, value, priority);
|
|
363
324
|
return;
|
|
364
325
|
}
|
|
365
|
-
|
|
366
|
-
if (!
|
|
326
|
+
property = asciiLowercase(property);
|
|
327
|
+
if (!Object.hasOwn(propertyDescriptors, property)) {
|
|
367
328
|
return;
|
|
368
329
|
}
|
|
369
330
|
if (priority) {
|
|
@@ -371,279 +332,282 @@ class CSSStyleDeclaration {
|
|
|
371
332
|
} else {
|
|
372
333
|
this._priorities.delete(property);
|
|
373
334
|
}
|
|
374
|
-
|
|
335
|
+
propertyDescriptors[property].set.call(this, value);
|
|
375
336
|
}
|
|
376
|
-
}
|
|
377
337
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
if (val === "") {
|
|
391
|
-
this.removeProperty(property);
|
|
392
|
-
return;
|
|
393
|
-
}
|
|
394
|
-
let originalText = "";
|
|
395
|
-
if (typeof this._onChange === "function" && !this._setInProgress) {
|
|
396
|
-
originalText = this.cssText;
|
|
397
|
-
}
|
|
398
|
-
if (this._values.has(property)) {
|
|
399
|
-
const index = Array.prototype.indexOf.call(this, property);
|
|
400
|
-
// The property already exists but is not indexed into `this` so add it.
|
|
401
|
-
if (index < 0) {
|
|
402
|
-
this[this._length] = property;
|
|
403
|
-
this._length++;
|
|
404
|
-
}
|
|
405
|
-
} else {
|
|
406
|
-
// New property.
|
|
407
|
-
this[this._length] = property;
|
|
408
|
-
this._length++;
|
|
409
|
-
}
|
|
410
|
-
if (priority === "important") {
|
|
411
|
-
this._priorities.set(property, priority);
|
|
412
|
-
} else {
|
|
413
|
-
this._priorities.delete(property);
|
|
414
|
-
}
|
|
415
|
-
this._values.set(property, val);
|
|
416
|
-
if (
|
|
417
|
-
typeof this._onChange === "function" &&
|
|
418
|
-
!this._setInProgress &&
|
|
419
|
-
this.cssText !== originalText
|
|
420
|
-
) {
|
|
421
|
-
this._onChange(this.cssText);
|
|
422
|
-
}
|
|
423
|
-
},
|
|
424
|
-
enumerable: false
|
|
425
|
-
},
|
|
338
|
+
/**
|
|
339
|
+
* Clears all indexed properties, properties indices and resets length to 0.
|
|
340
|
+
*
|
|
341
|
+
* @private
|
|
342
|
+
*/
|
|
343
|
+
_clearIndexedProperties() {
|
|
344
|
+
this._propertyIndices.clear();
|
|
345
|
+
for (let i = 0; i < this._length; i++) {
|
|
346
|
+
delete this[i];
|
|
347
|
+
}
|
|
348
|
+
this._length = 0;
|
|
349
|
+
}
|
|
426
350
|
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
} else {
|
|
444
|
-
for (let i = 0; i < this._length; i++) {
|
|
445
|
-
const property = this[i];
|
|
446
|
-
if (borderProperties.has(property)) {
|
|
447
|
-
const value = this.getPropertyValue(property);
|
|
448
|
-
const longhandPriority = this._priorities.get(property) ?? "";
|
|
449
|
-
let priority = longhandPriority;
|
|
450
|
-
if (prop === property && typeof prior === "string") {
|
|
451
|
-
priority = prior;
|
|
452
|
-
}
|
|
453
|
-
properties.set(property, { property, value, priority });
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
const parsedProperties = prepareBorderProperties(prop, val, prior, properties, {
|
|
458
|
-
globalObject: this._global
|
|
459
|
-
});
|
|
460
|
-
for (const [property, item] of parsedProperties) {
|
|
461
|
-
const { priority, value } = item;
|
|
462
|
-
this._setProperty(property, value, priority);
|
|
463
|
-
}
|
|
464
|
-
},
|
|
465
|
-
enumerable: false
|
|
466
|
-
},
|
|
351
|
+
/**
|
|
352
|
+
* Removes an indexed property at the specified index, shifts others, and updates indices.
|
|
353
|
+
*
|
|
354
|
+
* @private
|
|
355
|
+
* @param {number} index - The index of the property to remove.
|
|
356
|
+
*/
|
|
357
|
+
_removeIndexedProperty(index) {
|
|
358
|
+
this._propertyIndices.delete(this[index]);
|
|
359
|
+
for (let i = index; i < this._length - 1; i++) {
|
|
360
|
+
const property = this[i + 1];
|
|
361
|
+
this[i] = property;
|
|
362
|
+
this._propertyIndices.set(property, i);
|
|
363
|
+
}
|
|
364
|
+
delete this[this._length - 1];
|
|
365
|
+
this._length--;
|
|
366
|
+
}
|
|
467
367
|
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
}
|
|
479
|
-
const shorthandPriority = this._priorities.get(shorthandProperty);
|
|
480
|
-
this.removeProperty(shorthandProperty);
|
|
481
|
-
let priority = "";
|
|
482
|
-
if (typeof prior === "string") {
|
|
483
|
-
priority = prior;
|
|
484
|
-
} else {
|
|
485
|
-
priority = this._priorities.get(prop) ?? "";
|
|
486
|
-
}
|
|
487
|
-
this.removeProperty(prop);
|
|
488
|
-
if (shorthandPriority && priority) {
|
|
489
|
-
this._setProperty(prop, val);
|
|
490
|
-
} else {
|
|
491
|
-
this._setProperty(prop, val, priority);
|
|
492
|
-
}
|
|
493
|
-
if (val && !hasVarFunc(val)) {
|
|
494
|
-
const longhandValues = [];
|
|
495
|
-
const shorthandItem = shorthandProperties.get(shorthandProperty);
|
|
496
|
-
let hasGlobalKeyword = false;
|
|
497
|
-
for (const [longhandProperty] of shorthandItem.shorthandFor) {
|
|
498
|
-
if (longhandProperty === prop) {
|
|
499
|
-
if (isGlobalKeyword(val)) {
|
|
500
|
-
hasGlobalKeyword = true;
|
|
501
|
-
}
|
|
502
|
-
longhandValues.push(val);
|
|
503
|
-
} else {
|
|
504
|
-
const longhandValue = this.getPropertyValue(longhandProperty);
|
|
505
|
-
const longhandPriority = this._priorities.get(longhandProperty) ?? "";
|
|
506
|
-
if (!longhandValue || longhandPriority !== priority) {
|
|
507
|
-
break;
|
|
508
|
-
}
|
|
509
|
-
if (isGlobalKeyword(longhandValue)) {
|
|
510
|
-
hasGlobalKeyword = true;
|
|
511
|
-
}
|
|
512
|
-
longhandValues.push(longhandValue);
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
if (longhandValues.length === shorthandItem.shorthandFor.size) {
|
|
516
|
-
if (hasGlobalKeyword) {
|
|
517
|
-
const [firstValue, ...restValues] = longhandValues;
|
|
518
|
-
if (restValues.every((value) => value === firstValue)) {
|
|
519
|
-
this._setProperty(shorthandProperty, firstValue, priority);
|
|
520
|
-
}
|
|
521
|
-
} else {
|
|
522
|
-
const parsedValue = shorthandItem.parse(longhandValues.join(" "));
|
|
523
|
-
const shorthandValue = Object.values(parsedValue).join(" ");
|
|
524
|
-
this._setProperty(shorthandProperty, shorthandValue, priority);
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
},
|
|
529
|
-
enumerable: false
|
|
530
|
-
},
|
|
368
|
+
/**
|
|
369
|
+
* Returns the index of the specified property.
|
|
370
|
+
*
|
|
371
|
+
* @private
|
|
372
|
+
* @param {string} property - The property name to search for.
|
|
373
|
+
* @returns {number} The index of the property, or -1 if not found.
|
|
374
|
+
*/
|
|
375
|
+
_getIndexOf(property) {
|
|
376
|
+
return this._propertyIndices.get(property) ?? -1;
|
|
377
|
+
}
|
|
531
378
|
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
379
|
+
/**
|
|
380
|
+
* Sets a property and update indices.
|
|
381
|
+
*
|
|
382
|
+
* @private
|
|
383
|
+
* @param {string} property - The property name.
|
|
384
|
+
* @param {string} value - The property value.
|
|
385
|
+
* @param {string} priority - The priority.
|
|
386
|
+
*/
|
|
387
|
+
_setProperty(property, value, priority) {
|
|
388
|
+
if (typeof value !== "string") {
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
if (value === "") {
|
|
392
|
+
this.removeProperty(property);
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
let originalText = "";
|
|
396
|
+
if (this._onChange && !this._updating) {
|
|
397
|
+
originalText = this.cssText;
|
|
398
|
+
}
|
|
399
|
+
if (!this._values.has(property)) {
|
|
400
|
+
// New property.
|
|
401
|
+
this[this._length] = property;
|
|
402
|
+
this._propertyIndices.set(property, this._length);
|
|
403
|
+
this._length++;
|
|
404
|
+
}
|
|
405
|
+
if (priority === "important") {
|
|
406
|
+
this._priorities.set(property, priority);
|
|
407
|
+
} else {
|
|
408
|
+
this._priorities.delete(property);
|
|
409
|
+
}
|
|
410
|
+
this._values.set(property, value);
|
|
411
|
+
if (this._onChange && !this._updating && this.cssText !== originalText) {
|
|
412
|
+
this._onChange(this.cssText);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Helper to handle border property expansion.
|
|
418
|
+
*
|
|
419
|
+
* @private
|
|
420
|
+
* @param {string} property - The property name (e.g. "border").
|
|
421
|
+
* @param {object|Array|string} value - The value to set.
|
|
422
|
+
* @param {string} priority - The priority.
|
|
423
|
+
*/
|
|
424
|
+
_borderSetter(property, value, priority) {
|
|
425
|
+
const properties = new Map();
|
|
426
|
+
if (typeof priority !== "string") {
|
|
427
|
+
priority = this._priorities.get(property) ?? "";
|
|
428
|
+
}
|
|
429
|
+
if (property === "border") {
|
|
430
|
+
properties.set(property, { propery: property, value, priority });
|
|
431
|
+
} else {
|
|
432
|
+
for (let i = 0; i < this._length; i++) {
|
|
433
|
+
const itemProperty = this[i];
|
|
434
|
+
if (borderProperties.has(itemProperty)) {
|
|
435
|
+
const itemValue = this.getPropertyValue(itemProperty);
|
|
436
|
+
const longhandPriority = this._priorities.get(itemProperty) ?? "";
|
|
437
|
+
let itemPriority = longhandPriority;
|
|
438
|
+
if (itemProperty === property) {
|
|
439
|
+
itemPriority = priority;
|
|
569
440
|
}
|
|
441
|
+
properties.set(itemProperty, {
|
|
442
|
+
property: itemProperty,
|
|
443
|
+
value: itemValue,
|
|
444
|
+
priority: itemPriority
|
|
445
|
+
});
|
|
570
446
|
}
|
|
571
447
|
}
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
enumerable: false
|
|
580
|
-
},
|
|
448
|
+
}
|
|
449
|
+
const parsedProperties = prepareBorderProperties(property, value, priority, properties);
|
|
450
|
+
for (const [itemProperty, item] of parsedProperties) {
|
|
451
|
+
const { priority: itemPriority, value: itemValue } = item;
|
|
452
|
+
this._setProperty(itemProperty, itemValue, itemPriority);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
581
455
|
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
456
|
+
/**
|
|
457
|
+
* Helper to handle flexbox shorthand expansion.
|
|
458
|
+
*
|
|
459
|
+
* @private
|
|
460
|
+
* @param {string} property - The property name.
|
|
461
|
+
* @param {string} value - The property value.
|
|
462
|
+
* @param {string} priority - The priority.
|
|
463
|
+
* @param {string} shorthandProperty - The shorthand property name.
|
|
464
|
+
*/
|
|
465
|
+
_flexBoxSetter(property, value, priority, shorthandProperty) {
|
|
466
|
+
if (!shorthandProperty || !shorthandProperties.has(shorthandProperty)) {
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
const shorthandPriority = this._priorities.get(shorthandProperty);
|
|
470
|
+
this.removeProperty(shorthandProperty);
|
|
471
|
+
if (typeof priority !== "string") {
|
|
472
|
+
priority = this._priorities.get(property) ?? "";
|
|
473
|
+
}
|
|
474
|
+
this.removeProperty(property);
|
|
475
|
+
if (shorthandPriority && priority) {
|
|
476
|
+
this._setProperty(property, value);
|
|
477
|
+
} else {
|
|
478
|
+
this._setProperty(property, value, priority);
|
|
479
|
+
}
|
|
480
|
+
if (value && !hasVarFunc(value)) {
|
|
481
|
+
const longhandValues = [];
|
|
482
|
+
const shorthandItem = shorthandProperties.get(shorthandProperty);
|
|
483
|
+
let hasGlobalKeyword = false;
|
|
484
|
+
for (const [longhandProperty] of shorthandItem.shorthandFor) {
|
|
485
|
+
if (longhandProperty === property) {
|
|
486
|
+
if (isGlobalKeyword(value)) {
|
|
487
|
+
hasGlobalKeyword = true;
|
|
488
|
+
}
|
|
489
|
+
longhandValues.push(value);
|
|
490
|
+
} else {
|
|
612
491
|
const longhandValue = this.getPropertyValue(longhandProperty);
|
|
613
492
|
const longhandPriority = this._priorities.get(longhandProperty) ?? "";
|
|
614
493
|
if (!longhandValue || longhandPriority !== priority) {
|
|
615
|
-
|
|
494
|
+
break;
|
|
495
|
+
}
|
|
496
|
+
if (isGlobalKeyword(longhandValue)) {
|
|
497
|
+
hasGlobalKeyword = true;
|
|
616
498
|
}
|
|
617
499
|
longhandValues.push(longhandValue);
|
|
618
500
|
}
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
501
|
+
}
|
|
502
|
+
if (longhandValues.length === shorthandItem.shorthandFor.size) {
|
|
503
|
+
if (hasGlobalKeyword) {
|
|
504
|
+
const [firstValue, ...restValues] = longhandValues;
|
|
505
|
+
if (restValues.every((val) => val === 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);
|
|
622
512
|
}
|
|
623
513
|
}
|
|
624
|
-
}
|
|
625
|
-
enumerable: false
|
|
514
|
+
}
|
|
626
515
|
}
|
|
627
|
-
});
|
|
628
516
|
|
|
629
|
-
|
|
630
|
-
|
|
517
|
+
/**
|
|
518
|
+
* Helper to handle position shorthand expansion.
|
|
519
|
+
*
|
|
520
|
+
* @private
|
|
521
|
+
* @param {string} property - The property name.
|
|
522
|
+
* @param {Array|string} value - The property value.
|
|
523
|
+
* @param {string} priority - The priority.
|
|
524
|
+
*/
|
|
525
|
+
_positionShorthandSetter(property, value, priority) {
|
|
526
|
+
if (!shorthandProperties.has(property)) {
|
|
527
|
+
return;
|
|
528
|
+
}
|
|
529
|
+
const shorthandValues = [];
|
|
530
|
+
if (Array.isArray(value)) {
|
|
531
|
+
shorthandValues.push(...value);
|
|
532
|
+
} else if (typeof value === "string") {
|
|
533
|
+
shorthandValues.push(value);
|
|
534
|
+
} else {
|
|
535
|
+
return;
|
|
536
|
+
}
|
|
537
|
+
if (typeof priority !== "string") {
|
|
538
|
+
priority = this._priorities.get(property) ?? "";
|
|
539
|
+
}
|
|
540
|
+
const { position, shorthandFor } = shorthandProperties.get(property);
|
|
541
|
+
let hasPriority = false;
|
|
542
|
+
for (const [longhandProperty, longhandItem] of shorthandFor) {
|
|
543
|
+
const { position: longhandPosition } = longhandItem;
|
|
544
|
+
const longhandValue = getPositionValue(shorthandValues, longhandPosition);
|
|
545
|
+
if (priority) {
|
|
546
|
+
this._setProperty(longhandProperty, longhandValue, priority);
|
|
547
|
+
} else {
|
|
548
|
+
const longhandPriority = this._priorities.get(longhandProperty) ?? "";
|
|
549
|
+
if (longhandPriority) {
|
|
550
|
+
hasPriority = true;
|
|
551
|
+
} else {
|
|
552
|
+
this._setProperty(longhandProperty, longhandValue, priority);
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
if (hasPriority) {
|
|
557
|
+
this.removeProperty(property);
|
|
558
|
+
} else {
|
|
559
|
+
const shorthandValue = getPositionValue(shorthandValues, position);
|
|
560
|
+
this._setProperty(property, shorthandValue, priority);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
631
563
|
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
564
|
+
/**
|
|
565
|
+
* Helper to handle position longhand updates affecting shorthands.
|
|
566
|
+
*
|
|
567
|
+
* @private
|
|
568
|
+
* @param {string} property - The property name.
|
|
569
|
+
* @param {string} value - The property value.
|
|
570
|
+
* @param {string} priority - The priority.
|
|
571
|
+
* @param {string} shorthandProperty - The shorthand property name.
|
|
572
|
+
*/
|
|
573
|
+
_positionLonghandSetter(property, value, priority, shorthandProperty) {
|
|
574
|
+
if (!shorthandProperty || !shorthandProperties.has(shorthandProperty)) {
|
|
575
|
+
return;
|
|
576
|
+
}
|
|
577
|
+
const shorthandPriority = this._priorities.get(shorthandProperty);
|
|
578
|
+
this.removeProperty(shorthandProperty);
|
|
579
|
+
if (typeof priority !== "string") {
|
|
580
|
+
priority = this._priorities.get(property) ?? "";
|
|
581
|
+
}
|
|
582
|
+
this.removeProperty(property);
|
|
583
|
+
if (shorthandPriority && priority) {
|
|
584
|
+
this._setProperty(property, value);
|
|
585
|
+
} else {
|
|
586
|
+
this._setProperty(property, value, priority);
|
|
587
|
+
}
|
|
588
|
+
if (value && !hasVarFunc(value)) {
|
|
589
|
+
const longhandValues = [];
|
|
590
|
+
const { shorthandFor, position: shorthandPosition } = shorthandProperties.get(shorthandProperty);
|
|
591
|
+
for (const [longhandProperty] of shorthandFor) {
|
|
592
|
+
const longhandValue = this.getPropertyValue(longhandProperty);
|
|
593
|
+
const longhandPriority = this._priorities.get(longhandProperty) ?? "";
|
|
594
|
+
if (!longhandValue || longhandPriority !== priority) {
|
|
595
|
+
return;
|
|
596
|
+
}
|
|
597
|
+
longhandValues.push(longhandValue);
|
|
598
|
+
}
|
|
599
|
+
if (longhandValues.length === shorthandFor.size) {
|
|
600
|
+
const replacedValue = getPositionValue(longhandValues, shorthandPosition);
|
|
601
|
+
this._setProperty(shorthandProperty, replacedValue);
|
|
602
|
+
}
|
|
642
603
|
}
|
|
643
604
|
}
|
|
644
|
-
}
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
// TODO: Remove once the CSSStyleDeclaration is fully spec-compliant.
|
|
608
|
+
// @see https://github.com/jsdom/cssstyle/issues/255#issuecomment-3630183207
|
|
609
|
+
Object.defineProperties(CSSStyleDeclaration.prototype, propertyDescriptors);
|
|
645
610
|
|
|
646
611
|
module.exports = {
|
|
647
|
-
CSSStyleDeclaration
|
|
648
|
-
propertyList: Object.fromEntries(implementedProperties)
|
|
612
|
+
CSSStyleDeclaration
|
|
649
613
|
};
|