cssstyle 5.3.6 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/CSSStyleDeclaration.js +360 -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 +176 -309
- package/lib/parsers.js +155 -191
- 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 +27 -25
- 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} +27 -23
- package/lib/properties/{webkitBorderAfterColor.js → borderBlockStartColor.js} +27 -23
- package/lib/properties/borderBottom.js +40 -36
- package/lib/properties/borderBottomColor.js +26 -22
- package/lib/properties/borderBottomStyle.js +26 -22
- package/lib/properties/borderBottomWidth.js +29 -25
- package/lib/properties/borderCollapse.js +26 -22
- package/lib/properties/borderColor.js +36 -33
- package/lib/properties/{webkitBorderStartColor.js → borderInlineEndColor.js} +27 -23
- package/lib/properties/borderInlineStartColor.js +49 -0
- package/lib/properties/borderLeft.js +40 -36
- package/lib/properties/borderLeftColor.js +26 -22
- package/lib/properties/borderLeftStyle.js +26 -22
- package/lib/properties/borderLeftWidth.js +29 -25
- package/lib/properties/borderRight.js +40 -36
- package/lib/properties/borderRightColor.js +26 -22
- package/lib/properties/borderRightStyle.js +26 -22
- package/lib/properties/borderRightWidth.js +29 -25
- 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 +26 -22
- package/lib/properties/borderTopStyle.js +26 -22
- package/lib/properties/borderTopWidth.js +29 -25
- package/lib/properties/borderWidth.js +36 -33
- package/lib/properties/bottom.js +28 -24
- package/lib/properties/clear.js +26 -22
- package/lib/properties/clip.js +37 -31
- package/lib/properties/color.js +26 -22
- package/lib/properties/display.js +36 -30
- package/lib/properties/flex.js +53 -45
- package/lib/properties/flexBasis.js +29 -27
- package/lib/properties/flexGrow.js +29 -27
- package/lib/properties/flexShrink.js +29 -27
- package/lib/properties/float.js +26 -22
- package/lib/properties/floodColor.js +26 -22
- package/lib/properties/font.js +89 -118
- package/lib/properties/fontFamily.js +38 -33
- package/lib/properties/fontSize.js +30 -28
- package/lib/properties/fontStyle.js +38 -34
- package/lib/properties/fontVariant.js +35 -33
- package/lib/properties/fontWeight.js +34 -32
- package/lib/properties/height.js +29 -25
- package/lib/properties/left.js +28 -24
- package/lib/properties/lightingColor.js +26 -22
- package/lib/properties/lineHeight.js +29 -27
- package/lib/properties/margin.js +40 -34
- package/lib/properties/marginBottom.js +31 -28
- package/lib/properties/marginLeft.js +31 -28
- package/lib/properties/marginRight.js +31 -28
- package/lib/properties/marginTop.js +31 -28
- package/lib/properties/opacity.js +28 -24
- package/lib/properties/outlineColor.js +26 -22
- package/lib/properties/padding.js +40 -34
- package/lib/properties/paddingBottom.js +32 -29
- package/lib/properties/paddingLeft.js +32 -29
- package/lib/properties/paddingRight.js +32 -29
- package/lib/properties/paddingTop.js +32 -29
- package/lib/properties/right.js +28 -24
- package/lib/properties/stopColor.js +26 -22
- package/lib/properties/{webkitBorderBeforeColor.js → textEmphasisColor.js} +27 -23
- package/lib/properties/top.js +28 -25
- package/lib/properties/webkitTextFillColor.js +26 -22
- package/lib/properties/webkitTextStrokeColor.js +26 -22
- package/lib/properties/width.js +29 -25
- 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 -6638
- 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
|
-
this._setInProgress = true;
|
|
178
124
|
try {
|
|
179
|
-
|
|
180
|
-
|
|
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);
|
|
@@ -246,49 +182,65 @@ class CSSStyleDeclaration {
|
|
|
246
182
|
}
|
|
247
183
|
} catch {
|
|
248
184
|
return;
|
|
185
|
+
} finally {
|
|
186
|
+
this._updating = false;
|
|
249
187
|
}
|
|
250
|
-
this.
|
|
251
|
-
if (typeof this._onChange === "function") {
|
|
188
|
+
if (this._onChange) {
|
|
252
189
|
this._onChange(this.cssText);
|
|
253
190
|
}
|
|
254
191
|
}
|
|
255
192
|
|
|
193
|
+
/**
|
|
194
|
+
* Returns the number of properties in the declaration block.
|
|
195
|
+
*
|
|
196
|
+
* @returns {number} The property count.
|
|
197
|
+
*/
|
|
256
198
|
get length() {
|
|
257
199
|
return this._length;
|
|
258
200
|
}
|
|
259
201
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
delete this[i];
|
|
266
|
-
}
|
|
267
|
-
this._length = len;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
// 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
|
+
*/
|
|
271
207
|
get parentRule() {
|
|
272
208
|
return this._parentRule;
|
|
273
209
|
}
|
|
274
210
|
|
|
211
|
+
/**
|
|
212
|
+
* Alias for the "float" property.
|
|
213
|
+
*
|
|
214
|
+
* @returns {string} The value of the "float" property.
|
|
215
|
+
*/
|
|
275
216
|
get cssFloat() {
|
|
276
217
|
return this.getPropertyValue("float");
|
|
277
218
|
}
|
|
278
219
|
|
|
220
|
+
/**
|
|
221
|
+
* Sets the "float" property.
|
|
222
|
+
*
|
|
223
|
+
* @param {string} value - The new value for "float".
|
|
224
|
+
*/
|
|
279
225
|
set cssFloat(value) {
|
|
280
226
|
this._setProperty("float", value);
|
|
281
227
|
}
|
|
282
228
|
|
|
283
229
|
/**
|
|
284
|
-
*
|
|
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.
|
|
285
234
|
*/
|
|
286
235
|
getPropertyPriority(property) {
|
|
287
236
|
return this._priorities.get(property) || "";
|
|
288
237
|
}
|
|
289
238
|
|
|
290
239
|
/**
|
|
291
|
-
*
|
|
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.
|
|
292
244
|
*/
|
|
293
245
|
getPropertyValue(property) {
|
|
294
246
|
if (this._values.has(property)) {
|
|
@@ -298,7 +250,10 @@ class CSSStyleDeclaration {
|
|
|
298
250
|
}
|
|
299
251
|
|
|
300
252
|
/**
|
|
301
|
-
*
|
|
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.
|
|
302
257
|
*/
|
|
303
258
|
item(...args) {
|
|
304
259
|
if (!args.length) {
|
|
@@ -314,7 +269,10 @@ class CSSStyleDeclaration {
|
|
|
314
269
|
}
|
|
315
270
|
|
|
316
271
|
/**
|
|
317
|
-
*
|
|
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.
|
|
318
276
|
*/
|
|
319
277
|
removeProperty(property) {
|
|
320
278
|
if (this._readonly) {
|
|
@@ -328,10 +286,10 @@ class CSSStyleDeclaration {
|
|
|
328
286
|
const prevValue = this._values.get(property);
|
|
329
287
|
this._values.delete(property);
|
|
330
288
|
this._priorities.delete(property);
|
|
331
|
-
const index =
|
|
289
|
+
const index = this._getIndexOf(property);
|
|
332
290
|
if (index >= 0) {
|
|
333
|
-
|
|
334
|
-
if (
|
|
291
|
+
this._removeIndexedProperty(index);
|
|
292
|
+
if (this._onChange) {
|
|
335
293
|
this._onChange(this.cssText);
|
|
336
294
|
}
|
|
337
295
|
}
|
|
@@ -339,30 +297,34 @@ class CSSStyleDeclaration {
|
|
|
339
297
|
}
|
|
340
298
|
|
|
341
299
|
/**
|
|
342
|
-
*
|
|
343
|
-
*
|
|
344
|
-
* @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").
|
|
345
305
|
*/
|
|
346
|
-
setProperty(
|
|
306
|
+
setProperty(property, value, priority = "") {
|
|
347
307
|
if (this._readonly) {
|
|
348
|
-
const msg = `Property ${
|
|
308
|
+
const msg = `Property ${property} can not be modified.`;
|
|
349
309
|
const name = "NoModificationAllowedError";
|
|
350
310
|
throw new this._global.DOMException(msg, name);
|
|
351
311
|
}
|
|
352
|
-
|
|
312
|
+
value = prepareValue(value);
|
|
353
313
|
if (value === "") {
|
|
354
|
-
|
|
355
|
-
|
|
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);
|
|
356
319
|
return;
|
|
357
320
|
}
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
this._setProperty(prop, value, priority);
|
|
321
|
+
// Custom property
|
|
322
|
+
if (property.startsWith("--")) {
|
|
323
|
+
this._setProperty(property, value, priority);
|
|
362
324
|
return;
|
|
363
325
|
}
|
|
364
|
-
|
|
365
|
-
if (!
|
|
326
|
+
property = asciiLowercase(property);
|
|
327
|
+
if (!Object.hasOwn(propertyDescriptors, property)) {
|
|
366
328
|
return;
|
|
367
329
|
}
|
|
368
330
|
if (priority) {
|
|
@@ -370,279 +332,282 @@ class CSSStyleDeclaration {
|
|
|
370
332
|
} else {
|
|
371
333
|
this._priorities.delete(property);
|
|
372
334
|
}
|
|
373
|
-
|
|
335
|
+
propertyDescriptors[property].set.call(this, value);
|
|
374
336
|
}
|
|
375
|
-
}
|
|
376
337
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
if (val === "") {
|
|
390
|
-
this.removeProperty(property);
|
|
391
|
-
return;
|
|
392
|
-
}
|
|
393
|
-
let originalText = "";
|
|
394
|
-
if (typeof this._onChange === "function" && !this._setInProgress) {
|
|
395
|
-
originalText = this.cssText;
|
|
396
|
-
}
|
|
397
|
-
if (this._values.has(property)) {
|
|
398
|
-
const index = Array.prototype.indexOf.call(this, property);
|
|
399
|
-
// The property already exists but is not indexed into `this` so add it.
|
|
400
|
-
if (index < 0) {
|
|
401
|
-
this[this._length] = property;
|
|
402
|
-
this._length++;
|
|
403
|
-
}
|
|
404
|
-
} else {
|
|
405
|
-
// New property.
|
|
406
|
-
this[this._length] = property;
|
|
407
|
-
this._length++;
|
|
408
|
-
}
|
|
409
|
-
if (priority === "important") {
|
|
410
|
-
this._priorities.set(property, priority);
|
|
411
|
-
} else {
|
|
412
|
-
this._priorities.delete(property);
|
|
413
|
-
}
|
|
414
|
-
this._values.set(property, val);
|
|
415
|
-
if (
|
|
416
|
-
typeof this._onChange === "function" &&
|
|
417
|
-
!this._setInProgress &&
|
|
418
|
-
this.cssText !== originalText
|
|
419
|
-
) {
|
|
420
|
-
this._onChange(this.cssText);
|
|
421
|
-
}
|
|
422
|
-
},
|
|
423
|
-
enumerable: false
|
|
424
|
-
},
|
|
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
|
+
}
|
|
425
350
|
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
} else {
|
|
443
|
-
for (let i = 0; i < this._length; i++) {
|
|
444
|
-
const property = this[i];
|
|
445
|
-
if (borderProperties.has(property)) {
|
|
446
|
-
const value = this.getPropertyValue(property);
|
|
447
|
-
const longhandPriority = this._priorities.get(property) ?? "";
|
|
448
|
-
let priority = longhandPriority;
|
|
449
|
-
if (prop === property && typeof prior === "string") {
|
|
450
|
-
priority = prior;
|
|
451
|
-
}
|
|
452
|
-
properties.set(property, { property, value, priority });
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
const parsedProperties = prepareBorderProperties(prop, val, prior, properties, {
|
|
457
|
-
globalObject: this._global
|
|
458
|
-
});
|
|
459
|
-
for (const [property, item] of parsedProperties) {
|
|
460
|
-
const { priority, value } = item;
|
|
461
|
-
this._setProperty(property, value, priority);
|
|
462
|
-
}
|
|
463
|
-
},
|
|
464
|
-
enumerable: false
|
|
465
|
-
},
|
|
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
|
+
}
|
|
466
367
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
}
|
|
478
|
-
const shorthandPriority = this._priorities.get(shorthandProperty);
|
|
479
|
-
this.removeProperty(shorthandProperty);
|
|
480
|
-
let priority = "";
|
|
481
|
-
if (typeof prior === "string") {
|
|
482
|
-
priority = prior;
|
|
483
|
-
} else {
|
|
484
|
-
priority = this._priorities.get(prop) ?? "";
|
|
485
|
-
}
|
|
486
|
-
this.removeProperty(prop);
|
|
487
|
-
if (shorthandPriority && priority) {
|
|
488
|
-
this._setProperty(prop, val);
|
|
489
|
-
} else {
|
|
490
|
-
this._setProperty(prop, val, priority);
|
|
491
|
-
}
|
|
492
|
-
if (val && !hasVarFunc(val)) {
|
|
493
|
-
const longhandValues = [];
|
|
494
|
-
const shorthandItem = shorthandProperties.get(shorthandProperty);
|
|
495
|
-
let hasGlobalKeyword = false;
|
|
496
|
-
for (const [longhandProperty] of shorthandItem.shorthandFor) {
|
|
497
|
-
if (longhandProperty === prop) {
|
|
498
|
-
if (isGlobalKeyword(val)) {
|
|
499
|
-
hasGlobalKeyword = true;
|
|
500
|
-
}
|
|
501
|
-
longhandValues.push(val);
|
|
502
|
-
} else {
|
|
503
|
-
const longhandValue = this.getPropertyValue(longhandProperty);
|
|
504
|
-
const longhandPriority = this._priorities.get(longhandProperty) ?? "";
|
|
505
|
-
if (!longhandValue || longhandPriority !== priority) {
|
|
506
|
-
break;
|
|
507
|
-
}
|
|
508
|
-
if (isGlobalKeyword(longhandValue)) {
|
|
509
|
-
hasGlobalKeyword = true;
|
|
510
|
-
}
|
|
511
|
-
longhandValues.push(longhandValue);
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
if (longhandValues.length === shorthandItem.shorthandFor.size) {
|
|
515
|
-
if (hasGlobalKeyword) {
|
|
516
|
-
const [firstValue, ...restValues] = longhandValues;
|
|
517
|
-
if (restValues.every((value) => value === firstValue)) {
|
|
518
|
-
this._setProperty(shorthandProperty, firstValue, priority);
|
|
519
|
-
}
|
|
520
|
-
} else {
|
|
521
|
-
const parsedValue = shorthandItem.parse(longhandValues.join(" "));
|
|
522
|
-
const shorthandValue = Object.values(parsedValue).join(" ");
|
|
523
|
-
this._setProperty(shorthandProperty, shorthandValue, priority);
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
},
|
|
528
|
-
enumerable: false
|
|
529
|
-
},
|
|
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
|
+
}
|
|
530
378
|
|
|
531
|
-
|
|
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
|
-
|
|
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;
|
|
568
440
|
}
|
|
441
|
+
properties.set(itemProperty, {
|
|
442
|
+
property: itemProperty,
|
|
443
|
+
value: itemValue,
|
|
444
|
+
priority: itemPriority
|
|
445
|
+
});
|
|
569
446
|
}
|
|
570
447
|
}
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
enumerable: false
|
|
579
|
-
},
|
|
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
|
+
}
|
|
580
455
|
|
|
581
|
-
|
|
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
|
-
|
|
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 {
|
|
611
491
|
const longhandValue = this.getPropertyValue(longhandProperty);
|
|
612
492
|
const longhandPriority = this._priorities.get(longhandProperty) ?? "";
|
|
613
493
|
if (!longhandValue || longhandPriority !== priority) {
|
|
614
|
-
|
|
494
|
+
break;
|
|
495
|
+
}
|
|
496
|
+
if (isGlobalKeyword(longhandValue)) {
|
|
497
|
+
hasGlobalKeyword = true;
|
|
615
498
|
}
|
|
616
499
|
longhandValues.push(longhandValue);
|
|
617
500
|
}
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
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);
|
|
621
512
|
}
|
|
622
513
|
}
|
|
623
|
-
}
|
|
624
|
-
enumerable: false
|
|
514
|
+
}
|
|
625
515
|
}
|
|
626
|
-
});
|
|
627
516
|
|
|
628
|
-
|
|
629
|
-
|
|
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
|
+
}
|
|
630
563
|
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
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
|
+
}
|
|
641
603
|
}
|
|
642
604
|
}
|
|
643
|
-
}
|
|
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);
|
|
644
610
|
|
|
645
611
|
module.exports = {
|
|
646
|
-
CSSStyleDeclaration
|
|
647
|
-
propertyList: Object.fromEntries(implementedProperties)
|
|
612
|
+
CSSStyleDeclaration
|
|
648
613
|
};
|