@acemir/cssom 0.9.16 → 0.9.18
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/build/CSSOM.js +706 -107
- package/lib/CSSFontFaceRule.js +22 -3
- package/lib/CSSGroupingRule.js +46 -7
- package/lib/CSSImportRule.js +5 -5
- package/lib/CSSKeyframeRule.js +22 -3
- package/lib/CSSKeyframesRule.js +199 -5
- package/lib/CSSNestedDeclarations.js +23 -2
- package/lib/CSSRule.js +39 -26
- package/lib/CSSStyleRule.js +39 -7
- package/lib/CSSStyleSheet.js +101 -12
- package/lib/StyleSheet.js +8 -1
- package/lib/clone.js +6 -0
- package/lib/cssstyleTryCatchBlock.js +5 -0
- package/lib/errorUtils.js +107 -0
- package/lib/index.js +5 -0
- package/lib/parse.js +50 -34
- package/package.json +1 -1
package/build/CSSOM.js
CHANGED
|
@@ -1,6 +1,112 @@
|
|
|
1
1
|
var CSSOM = {};
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
// Utility functions for CSSOM error handling
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Gets the appropriate error constructor from the global object context.
|
|
8
|
+
* Tries to find the error constructor from parentStyleSheet.__globalObject,
|
|
9
|
+
* then from __globalObject, then falls back to the native constructor.
|
|
10
|
+
*
|
|
11
|
+
* @param {Object} context - The CSSOM object (rule, stylesheet, etc.)
|
|
12
|
+
* @param {string} errorType - The error type ('TypeError', 'RangeError', 'DOMException', etc.)
|
|
13
|
+
* @return {Function} The error constructor
|
|
14
|
+
*/
|
|
15
|
+
function getErrorConstructor(context, errorType) {
|
|
16
|
+
// Try parentStyleSheet.__globalObject first
|
|
17
|
+
if (context.parentStyleSheet && context.parentStyleSheet.__globalObject && context.parentStyleSheet.__globalObject[errorType]) {
|
|
18
|
+
return context.parentStyleSheet.__globalObject[errorType];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Try __parentStyleSheet (alternative naming)
|
|
22
|
+
if (context.__parentStyleSheet && context.__parentStyleSheet.__globalObject && context.__parentStyleSheet.__globalObject[errorType]) {
|
|
23
|
+
return context.__parentStyleSheet.__globalObject[errorType];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Try __globalObject on the context itself
|
|
27
|
+
if (context.__globalObject && context.__globalObject[errorType]) {
|
|
28
|
+
return context.__globalObject[errorType];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Fall back to native constructor
|
|
32
|
+
return (typeof global !== 'undefined' && global[errorType]) ||
|
|
33
|
+
(typeof window !== 'undefined' && window[errorType]) ||
|
|
34
|
+
eval(errorType);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Creates and throws an appropriate error with context-aware constructor.
|
|
39
|
+
*
|
|
40
|
+
* @param {Object} context - The CSSOM object (rule, stylesheet, etc.)
|
|
41
|
+
* @param {string} errorType - The error type ('TypeError', 'RangeError', 'DOMException', etc.)
|
|
42
|
+
* @param {string} message - The error message
|
|
43
|
+
* @param {string} [name] - Optional name for DOMException
|
|
44
|
+
*/
|
|
45
|
+
function throwError(context, errorType, message, name) {
|
|
46
|
+
var ErrorConstructor = getErrorConstructor(context, errorType);
|
|
47
|
+
var error = new ErrorConstructor(message, name);
|
|
48
|
+
throw error;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Throws a TypeError for missing required arguments.
|
|
53
|
+
*
|
|
54
|
+
* @param {Object} context - The CSSOM object
|
|
55
|
+
* @param {string} methodName - The method name (e.g., 'appendRule')
|
|
56
|
+
* @param {string} objectName - The object name (e.g., 'CSSKeyframesRule')
|
|
57
|
+
* @param {number} [required=1] - Number of required arguments
|
|
58
|
+
* @param {number} [provided=0] - Number of provided arguments
|
|
59
|
+
*/
|
|
60
|
+
function throwMissingArguments(context, methodName, objectName, required, provided) {
|
|
61
|
+
required = required || 1;
|
|
62
|
+
provided = provided || 0;
|
|
63
|
+
var message = "Failed to execute '" + methodName + "' on '" + objectName + "': " +
|
|
64
|
+
required + " argument" + (required > 1 ? "s" : "") + " required, but only " +
|
|
65
|
+
provided + " present.";
|
|
66
|
+
throwError(context, 'TypeError', message);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Throws a DOMException for parse errors.
|
|
71
|
+
*
|
|
72
|
+
* @param {Object} context - The CSSOM object
|
|
73
|
+
* @param {string} methodName - The method name
|
|
74
|
+
* @param {string} objectName - The object name
|
|
75
|
+
* @param {string} rule - The rule that failed to parse
|
|
76
|
+
* @param {string} [name='SyntaxError'] - The DOMException name
|
|
77
|
+
*/
|
|
78
|
+
function throwParseError(context, methodName, objectName, rule, name) {
|
|
79
|
+
var message = "Failed to execute '" + methodName + "' on '" + objectName + "': " +
|
|
80
|
+
"Failed to parse the rule '" + rule + "'.";
|
|
81
|
+
throwError(context, 'DOMException', message, name || 'SyntaxError');
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Throws a DOMException for index errors.
|
|
86
|
+
*
|
|
87
|
+
* @param {Object} context - The CSSOM object
|
|
88
|
+
* @param {string} methodName - The method name
|
|
89
|
+
* @param {string} objectName - The object name
|
|
90
|
+
* @param {number} index - The invalid index
|
|
91
|
+
* @param {number} maxIndex - The maximum valid index
|
|
92
|
+
* @param {string} [name='IndexSizeError'] - The DOMException name
|
|
93
|
+
*/
|
|
94
|
+
function throwIndexError(context, methodName, objectName, index, maxIndex, name) {
|
|
95
|
+
var message = "Failed to execute '" + methodName + "' on '" + objectName + "': " +
|
|
96
|
+
"The index provided (" + index + ") is larger than the maximum index (" + maxIndex + ").";
|
|
97
|
+
throwError(context, 'DOMException', message, name || 'IndexSizeError');
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
var errorUtils = {
|
|
101
|
+
getErrorConstructor: getErrorConstructor,
|
|
102
|
+
throwError: throwError,
|
|
103
|
+
throwMissingArguments: throwMissingArguments,
|
|
104
|
+
throwParseError: throwParseError,
|
|
105
|
+
throwIndexError: throwIndexError
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
|
|
4
110
|
// NOTE: Check viability to add a validation for css values or use a dependency like csstree-validator
|
|
5
111
|
/**
|
|
6
112
|
* Regular expression to detect invalid characters in the value portion of a CSS style declaration.
|
|
@@ -179,58 +285,91 @@ CSSOM.CSSStyleDeclaration.prototype = {
|
|
|
179
285
|
|
|
180
286
|
|
|
181
287
|
|
|
288
|
+
try {
|
|
289
|
+
CSSOM.CSSStyleDeclaration = require("cssstyle").CSSStyleDeclaration;
|
|
290
|
+
} catch (e) {
|
|
291
|
+
// ignore
|
|
292
|
+
}
|
|
293
|
+
|
|
182
294
|
/**
|
|
183
295
|
* @constructor
|
|
184
296
|
* @see http://dev.w3.org/csswg/cssom/#the-cssrule-interface
|
|
185
297
|
* @see http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSRule
|
|
186
298
|
*/
|
|
187
299
|
CSSOM.CSSRule = function CSSRule() {
|
|
188
|
-
this.
|
|
189
|
-
this.
|
|
300
|
+
this.__parentRule = null;
|
|
301
|
+
this.__parentStyleSheet = null;
|
|
190
302
|
};
|
|
191
303
|
|
|
192
|
-
CSSOM.CSSRule.
|
|
193
|
-
|
|
194
|
-
CSSOM.CSSRule
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
}
|
|
304
|
+
Object.defineProperties(CSSOM.CSSRule.prototype, {
|
|
305
|
+
|
|
306
|
+
constructor: { value: CSSOM.CSSRule },
|
|
307
|
+
|
|
308
|
+
parentRule: {
|
|
309
|
+
get: function() {
|
|
310
|
+
return this.__parentRule
|
|
311
|
+
}
|
|
312
|
+
},
|
|
313
|
+
|
|
314
|
+
parentStyleSheet: {
|
|
315
|
+
get: function() {
|
|
316
|
+
return this.__parentStyleSheet
|
|
317
|
+
}
|
|
318
|
+
},
|
|
319
|
+
|
|
320
|
+
UNKNOWN_RULE: { value: 0, enumerable: true }, // obsolet
|
|
321
|
+
STYLE_RULE: { value: 1, enumerable: true },
|
|
322
|
+
CHARSET_RULE: { value: 2, enumerable: true }, // obsolet
|
|
323
|
+
IMPORT_RULE: { value: 3, enumerable: true },
|
|
324
|
+
MEDIA_RULE: { value: 4, enumerable: true },
|
|
325
|
+
FONT_FACE_RULE: { value: 5, enumerable: true },
|
|
326
|
+
PAGE_RULE: { value: 6, enumerable: true },
|
|
327
|
+
KEYFRAMES_RULE: { value: 7, enumerable: true },
|
|
328
|
+
KEYFRAME_RULE: { value: 8, enumerable: true },
|
|
329
|
+
MARGIN_RULE: { value: 9, enumerable: true },
|
|
330
|
+
NAMESPACE_RULE: { value: 10, enumerable: true },
|
|
331
|
+
COUNTER_STYLE_RULE: { value: 11, enumerable: true },
|
|
332
|
+
SUPPORTS_RULE: { value: 12, enumerable: true },
|
|
333
|
+
DOCUMENT_RULE: { value: 13, enumerable: true },
|
|
334
|
+
FONT_FEATURE_VALUES_RULE: { value: 14, enumerable: true },
|
|
335
|
+
VIEWPORT_RULE: { value: 15, enumerable: true },
|
|
336
|
+
REGION_STYLE_RULE: { value: 16, enumerable: true },
|
|
337
|
+
CONTAINER_RULE: { value: 17, enumerable: true },
|
|
338
|
+
LAYER_BLOCK_RULE: { value: 18, enumerable: true },
|
|
339
|
+
STARTING_STYLE_RULE: { value: 1002, enumerable: true },
|
|
340
|
+
})
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
|
|
217
345
|
|
|
218
|
-
exports.CSSRule = CSSOM.CSSRule;
|
|
219
|
-
///CommonJS
|
|
220
346
|
/**
|
|
221
347
|
* @constructor
|
|
222
348
|
* @see https://drafts.csswg.org/css-nesting-1/
|
|
223
349
|
*/
|
|
224
350
|
CSSOM.CSSNestedDeclarations = function CSSNestedDeclarations() {
|
|
225
351
|
CSSOM.CSSRule.call(this);
|
|
226
|
-
this.
|
|
227
|
-
this.
|
|
352
|
+
this.__style = new CSSOM.CSSStyleDeclaration();
|
|
353
|
+
this.__style.parentRule = this;
|
|
228
354
|
};
|
|
229
355
|
|
|
230
356
|
CSSOM.CSSNestedDeclarations.prototype = new CSSOM.CSSRule();
|
|
231
357
|
CSSOM.CSSNestedDeclarations.prototype.constructor = CSSOM.CSSNestedDeclarations;
|
|
232
358
|
CSSOM.CSSNestedDeclarations.prototype.type = 0;
|
|
233
359
|
|
|
360
|
+
Object.defineProperty(CSSOM.CSSNestedDeclarations.prototype, "style", {
|
|
361
|
+
get: function() {
|
|
362
|
+
return this.__style;
|
|
363
|
+
},
|
|
364
|
+
set: function(value) {
|
|
365
|
+
if (typeof value === "string") {
|
|
366
|
+
this.__style.cssText = value;
|
|
367
|
+
} else {
|
|
368
|
+
this.__style = value;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
});
|
|
372
|
+
|
|
234
373
|
Object.defineProperty(CSSOM.CSSNestedDeclarations.prototype, "cssText", {
|
|
235
374
|
get: function () {
|
|
236
375
|
return this.style.cssText;
|
|
@@ -239,6 +378,9 @@ Object.defineProperty(CSSOM.CSSNestedDeclarations.prototype, "cssText", {
|
|
|
239
378
|
enumerable: true,
|
|
240
379
|
});
|
|
241
380
|
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
|
|
242
384
|
/**
|
|
243
385
|
* @constructor
|
|
244
386
|
* @see https://drafts.csswg.org/cssom/#the-cssgroupingrule-interface
|
|
@@ -269,11 +411,42 @@ CSSOM.CSSGroupingRule.prototype.constructor = CSSOM.CSSGroupingRule;
|
|
|
269
411
|
* @return {number} The index within the grouping rule's collection of the newly inserted rule.
|
|
270
412
|
*/
|
|
271
413
|
CSSOM.CSSGroupingRule.prototype.insertRule = function insertRule(rule, index) {
|
|
272
|
-
if (
|
|
273
|
-
|
|
414
|
+
if (rule === undefined && index === undefined) {
|
|
415
|
+
errorUtils.throwMissingArguments(this, 'insertRule', this.constructor.name);
|
|
416
|
+
}
|
|
417
|
+
if (index === void 0) {
|
|
418
|
+
index = 0;
|
|
274
419
|
}
|
|
275
|
-
|
|
276
|
-
|
|
420
|
+
index = Number(index);
|
|
421
|
+
if (index < 0) {
|
|
422
|
+
index = 4294967296 + index;
|
|
423
|
+
}
|
|
424
|
+
if (index > this.cssRules.length) {
|
|
425
|
+
errorUtils.throwIndexError(this, 'insertRule', this.constructor.name, index, this.cssRules.length);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
var ruleToParse = String(rule);
|
|
429
|
+
var parsedSheet = CSSOM.parse(ruleToParse);
|
|
430
|
+
if (parsedSheet.cssRules.length !== 1) {
|
|
431
|
+
errorUtils.throwParseError(this, 'insertRule', this.constructor.name, ruleToParse, 'SyntaxError');
|
|
432
|
+
}
|
|
433
|
+
var cssRule = parsedSheet.cssRules[0];
|
|
434
|
+
|
|
435
|
+
// Check for rules that cannot be inserted inside a CSSGroupingRule
|
|
436
|
+
if (cssRule.constructor.name === 'CSSImportRule' || cssRule.constructor.name === 'CSSNamespaceRule') {
|
|
437
|
+
var ruleKeyword = cssRule.constructor.name === 'CSSImportRule' ? '@import' : '@namespace';
|
|
438
|
+
errorUtils.throwError(this, 'DOMException',
|
|
439
|
+
"Failed to execute 'insertRule' on '" + this.constructor.name + "': " +
|
|
440
|
+
"'" + ruleKeyword + "' rules cannot be inserted inside a group rule.",
|
|
441
|
+
'HierarchyRequestError');
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
// Check for CSSLayerStatementRule (@layer statement rules)
|
|
445
|
+
if (cssRule.constructor.name === 'CSSLayerStatementRule') {
|
|
446
|
+
errorUtils.throwParseError(this, 'insertRule', this.constructor.name, ruleToParse, 'SyntaxError');
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
cssRule.__parentRule = this;
|
|
277
450
|
this.cssRules.splice(index, 0, cssRule);
|
|
278
451
|
return index;
|
|
279
452
|
};
|
|
@@ -291,13 +464,23 @@ CSSOM.CSSGroupingRule.prototype.constructor = CSSOM.CSSGroupingRule;
|
|
|
291
464
|
* @see https://www.w3.org/TR/cssom-1/#dom-cssgroupingrule-deleterule
|
|
292
465
|
*/
|
|
293
466
|
CSSOM.CSSGroupingRule.prototype.deleteRule = function deleteRule(index) {
|
|
294
|
-
if (index
|
|
295
|
-
|
|
467
|
+
if (index === undefined) {
|
|
468
|
+
errorUtils.throwMissingArguments(this, 'deleteRule', this.constructor.name);
|
|
296
469
|
}
|
|
297
|
-
|
|
470
|
+
index = Number(index);
|
|
471
|
+
if (index < 0) {
|
|
472
|
+
index = 4294967296 + index;
|
|
473
|
+
}
|
|
474
|
+
if (index >= this.cssRules.length) {
|
|
475
|
+
errorUtils.throwIndexError(this, 'deleteRule', this.constructor.name, index, this.cssRules.length);
|
|
476
|
+
}
|
|
477
|
+
this.cssRules.splice(index, 1)[0].__parentRule = null;
|
|
298
478
|
};
|
|
299
479
|
|
|
300
480
|
|
|
481
|
+
|
|
482
|
+
|
|
483
|
+
|
|
301
484
|
/**
|
|
302
485
|
* @constructor
|
|
303
486
|
* @see https://drafts.csswg.org/css-counter-styles/#the-csscounterstylerule-interface
|
|
@@ -312,6 +495,9 @@ CSSOM.CSSCounterStyleRule.prototype.constructor = CSSOM.CSSCounterStyleRule;
|
|
|
312
495
|
CSSOM.CSSCounterStyleRule.prototype.type = 11;
|
|
313
496
|
|
|
314
497
|
|
|
498
|
+
|
|
499
|
+
|
|
500
|
+
|
|
315
501
|
/**
|
|
316
502
|
* @constructor
|
|
317
503
|
* @see https://www.w3.org/TR/css-conditional-3/#the-cssconditionrule-interface
|
|
@@ -327,6 +513,9 @@ CSSOM.CSSConditionRule.prototype.conditionText = ''
|
|
|
327
513
|
CSSOM.CSSConditionRule.prototype.cssText = ''
|
|
328
514
|
|
|
329
515
|
|
|
516
|
+
|
|
517
|
+
|
|
518
|
+
|
|
330
519
|
/**
|
|
331
520
|
* @constructor
|
|
332
521
|
* @see http://dev.w3.org/csswg/cssom/#cssstylerule
|
|
@@ -334,14 +523,40 @@ CSSOM.CSSConditionRule.prototype.cssText = ''
|
|
|
334
523
|
*/
|
|
335
524
|
CSSOM.CSSStyleRule = function CSSStyleRule() {
|
|
336
525
|
CSSOM.CSSGroupingRule.call(this);
|
|
337
|
-
this.
|
|
338
|
-
this.
|
|
339
|
-
this.
|
|
526
|
+
this.__selectorText = "";
|
|
527
|
+
this.__style = new CSSOM.CSSStyleDeclaration();
|
|
528
|
+
this.__style.parentRule = this;
|
|
340
529
|
};
|
|
341
530
|
|
|
342
531
|
CSSOM.CSSStyleRule.prototype = new CSSOM.CSSGroupingRule();
|
|
343
532
|
CSSOM.CSSStyleRule.prototype.constructor = CSSOM.CSSStyleRule;
|
|
344
|
-
|
|
533
|
+
|
|
534
|
+
Object.defineProperty(CSSOM.CSSStyleRule.prototype, "type", {
|
|
535
|
+
value: 1,
|
|
536
|
+
writable: false
|
|
537
|
+
});
|
|
538
|
+
|
|
539
|
+
Object.defineProperty(CSSOM.CSSStyleRule.prototype, "selectorText", {
|
|
540
|
+
get: function() {
|
|
541
|
+
return this.__selectorText;
|
|
542
|
+
},
|
|
543
|
+
set: function(value) {
|
|
544
|
+
this.__selectorText = value;
|
|
545
|
+
}
|
|
546
|
+
});
|
|
547
|
+
|
|
548
|
+
Object.defineProperty(CSSOM.CSSStyleRule.prototype, "style", {
|
|
549
|
+
get: function() {
|
|
550
|
+
return this.__style;
|
|
551
|
+
},
|
|
552
|
+
set: function(value) {
|
|
553
|
+
if (typeof value === "string") {
|
|
554
|
+
this.__style.cssText = value;
|
|
555
|
+
} else {
|
|
556
|
+
this.__style = value;
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
});
|
|
345
560
|
|
|
346
561
|
Object.defineProperty(CSSOM.CSSStyleRule.prototype, "cssText", {
|
|
347
562
|
get: function() {
|
|
@@ -354,7 +569,7 @@ Object.defineProperty(CSSOM.CSSStyleRule.prototype, "cssText", {
|
|
|
354
569
|
valuesArr.push(this.cssRules.map(function(rule){ return rule.cssText }).join("\n "));
|
|
355
570
|
values = valuesArr.join("\n ") + "\n}"
|
|
356
571
|
} else {
|
|
357
|
-
values = " { " + this.style.cssText + " }";
|
|
572
|
+
values = " {" + (this.style.cssText ? " " + this.style.cssText : "") + " }";
|
|
358
573
|
}
|
|
359
574
|
text = this.selectorText + values;
|
|
360
575
|
} else {
|
|
@@ -364,8 +579,8 @@ Object.defineProperty(CSSOM.CSSStyleRule.prototype, "cssText", {
|
|
|
364
579
|
},
|
|
365
580
|
set: function(cssText) {
|
|
366
581
|
var rule = CSSOM.CSSStyleRule.parse(cssText);
|
|
367
|
-
this.
|
|
368
|
-
this.
|
|
582
|
+
this.__style = rule.style;
|
|
583
|
+
this.__selectorText = rule.selectorText;
|
|
369
584
|
}
|
|
370
585
|
});
|
|
371
586
|
|
|
@@ -516,6 +731,9 @@ CSSOM.CSSStyleRule.parse = function(ruleText) {
|
|
|
516
731
|
|
|
517
732
|
|
|
518
733
|
|
|
734
|
+
|
|
735
|
+
|
|
736
|
+
|
|
519
737
|
/**
|
|
520
738
|
* @constructor
|
|
521
739
|
* @see http://dev.w3.org/csswg/cssom/#the-medialist-interface
|
|
@@ -570,6 +788,9 @@ CSSOM.MediaList.prototype = {
|
|
|
570
788
|
|
|
571
789
|
|
|
572
790
|
|
|
791
|
+
|
|
792
|
+
|
|
793
|
+
|
|
573
794
|
/**
|
|
574
795
|
* @constructor
|
|
575
796
|
* @see http://dev.w3.org/csswg/cssom/#cssmediarule
|
|
@@ -611,6 +832,9 @@ Object.defineProperties(CSSOM.CSSMediaRule.prototype, {
|
|
|
611
832
|
|
|
612
833
|
|
|
613
834
|
|
|
835
|
+
|
|
836
|
+
|
|
837
|
+
|
|
614
838
|
/**
|
|
615
839
|
* @constructor
|
|
616
840
|
* @see https://drafts.csswg.org/css-contain-3/
|
|
@@ -650,6 +874,9 @@ Object.defineProperties(CSSOM.CSSContainerRule.prototype, {
|
|
|
650
874
|
|
|
651
875
|
|
|
652
876
|
|
|
877
|
+
|
|
878
|
+
|
|
879
|
+
|
|
653
880
|
/**
|
|
654
881
|
* @constructor
|
|
655
882
|
* @see https://drafts.csswg.org/css-conditional-3/#the-csssupportsrule-interface
|
|
@@ -675,6 +902,9 @@ Object.defineProperty(CSSOM.CSSSupportsRule.prototype, "cssText", {
|
|
|
675
902
|
});
|
|
676
903
|
|
|
677
904
|
|
|
905
|
+
|
|
906
|
+
|
|
907
|
+
|
|
678
908
|
/**
|
|
679
909
|
* @constructor
|
|
680
910
|
* @see http://dev.w3.org/csswg/cssom/#cssimportrule
|
|
@@ -696,7 +926,7 @@ CSSOM.CSSImportRule.prototype.type = 3;
|
|
|
696
926
|
Object.defineProperty(CSSOM.CSSImportRule.prototype, "cssText", {
|
|
697
927
|
get: function() {
|
|
698
928
|
var mediaText = this.media.mediaText;
|
|
699
|
-
return "@import url(" + this.href + ")" + (this.layerName !== null ? " layer" + (this.layerName && "(" + this.layerName + ")") : "" ) + (this.supportsText ? " supports(" + this.supportsText + ")" : "" ) + (mediaText ? " " + mediaText : "") + ";";
|
|
929
|
+
return "@import url(\"" + this.href + "\")" + (this.layerName !== null ? " layer" + (this.layerName && "(" + this.layerName + ")") : "" ) + (this.supportsText ? " supports(" + this.supportsText + ")" : "" ) + (mediaText ? " " + mediaText : "") + ";";
|
|
700
930
|
},
|
|
701
931
|
set: function(cssText) {
|
|
702
932
|
var i = 0;
|
|
@@ -714,7 +944,7 @@ Object.defineProperty(CSSOM.CSSImportRule.prototype, "cssText", {
|
|
|
714
944
|
var index;
|
|
715
945
|
|
|
716
946
|
var layerRegExp = /layer\(([^)]*)\)/;
|
|
717
|
-
var layerRuleNameRegExp = /^(-?[_a-zA-Z]+[_a-zA-Z0-9-]*)$/;
|
|
947
|
+
var layerRuleNameRegExp = /^(-?[_a-zA-Z]+(\.[_a-zA-Z]+)*[_a-zA-Z0-9-]*)$/;
|
|
718
948
|
var supportsRegExp = /supports\(([^)]+)\)/;
|
|
719
949
|
var doubleOrMoreSpacesRegExp = /\s{2,}/g;
|
|
720
950
|
|
|
@@ -797,12 +1027,12 @@ Object.defineProperty(CSSOM.CSSImportRule.prototype, "cssText", {
|
|
|
797
1027
|
|
|
798
1028
|
if (layerMatch) {
|
|
799
1029
|
var layerName = layerMatch[1].trim();
|
|
800
|
-
bufferTrimmed = bufferTrimmed.replace(layerRegExp, '')
|
|
801
|
-
.replace(doubleOrMoreSpacesRegExp, ' ') // Replace double or more spaces with single space
|
|
802
|
-
.trim();
|
|
803
1030
|
|
|
804
1031
|
if (layerName.match(layerRuleNameRegExp) !== null) {
|
|
805
1032
|
this.layerName = layerMatch[1].trim();
|
|
1033
|
+
bufferTrimmed = bufferTrimmed.replace(layerRegExp, '')
|
|
1034
|
+
.replace(doubleOrMoreSpacesRegExp, ' ') // Replace double or more spaces with single space
|
|
1035
|
+
.trim();
|
|
806
1036
|
} else {
|
|
807
1037
|
// REVIEW: In the browser, an empty layer() is not processed as a unamed layer
|
|
808
1038
|
// and treats the rest of the string as mediaText, ignoring the parse of supports()
|
|
@@ -847,6 +1077,9 @@ Object.defineProperty(CSSOM.CSSImportRule.prototype, "cssText", {
|
|
|
847
1077
|
|
|
848
1078
|
|
|
849
1079
|
|
|
1080
|
+
|
|
1081
|
+
|
|
1082
|
+
|
|
850
1083
|
/**
|
|
851
1084
|
* @constructor
|
|
852
1085
|
* @see https://drafts.csswg.org/cssom/#the-cssnamespacerule-interface
|
|
@@ -914,14 +1147,17 @@ Object.defineProperty(CSSOM.CSSNamespaceRule.prototype, "cssText", {
|
|
|
914
1147
|
|
|
915
1148
|
|
|
916
1149
|
|
|
1150
|
+
|
|
1151
|
+
|
|
1152
|
+
|
|
917
1153
|
/**
|
|
918
1154
|
* @constructor
|
|
919
1155
|
* @see http://dev.w3.org/csswg/cssom/#css-font-face-rule
|
|
920
1156
|
*/
|
|
921
1157
|
CSSOM.CSSFontFaceRule = function CSSFontFaceRule() {
|
|
922
1158
|
CSSOM.CSSRule.call(this);
|
|
923
|
-
this.
|
|
924
|
-
this.
|
|
1159
|
+
this.__style = new CSSOM.CSSStyleDeclaration();
|
|
1160
|
+
this.__style.parentRule = this;
|
|
925
1161
|
};
|
|
926
1162
|
|
|
927
1163
|
CSSOM.CSSFontFaceRule.prototype = new CSSOM.CSSRule();
|
|
@@ -931,15 +1167,31 @@ CSSOM.CSSFontFaceRule.prototype.type = 5;
|
|
|
931
1167
|
//CSSOM.CSSFontFaceRule.prototype.insertRule = CSSStyleSheet.prototype.insertRule;
|
|
932
1168
|
//CSSOM.CSSFontFaceRule.prototype.deleteRule = CSSStyleSheet.prototype.deleteRule;
|
|
933
1169
|
|
|
1170
|
+
Object.defineProperty(CSSOM.CSSFontFaceRule.prototype, "style", {
|
|
1171
|
+
get: function() {
|
|
1172
|
+
return this.__style;
|
|
1173
|
+
},
|
|
1174
|
+
set: function(value) {
|
|
1175
|
+
if (typeof value === "string") {
|
|
1176
|
+
this.__style.cssText = value;
|
|
1177
|
+
} else {
|
|
1178
|
+
this.__style = value;
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
});
|
|
1182
|
+
|
|
934
1183
|
// http://www.opensource.apple.com/source/WebCore/WebCore-955.66.1/css/WebKitCSSFontFaceRule.cpp
|
|
935
1184
|
Object.defineProperty(CSSOM.CSSFontFaceRule.prototype, "cssText", {
|
|
936
1185
|
get: function() {
|
|
937
|
-
return "@font-face { " + this.style.cssText + " }";
|
|
1186
|
+
return "@font-face {" + (this.style.cssText ? " " + this.style.cssText : "") + " }";
|
|
938
1187
|
}
|
|
939
1188
|
});
|
|
940
1189
|
|
|
941
1190
|
|
|
942
1191
|
|
|
1192
|
+
|
|
1193
|
+
|
|
1194
|
+
|
|
943
1195
|
/**
|
|
944
1196
|
* @constructor
|
|
945
1197
|
* @see http://www.w3.org/TR/shadow-dom/#host-at-rule
|
|
@@ -968,6 +1220,9 @@ Object.defineProperty(CSSOM.CSSHostRule.prototype, "cssText", {
|
|
|
968
1220
|
|
|
969
1221
|
|
|
970
1222
|
|
|
1223
|
+
|
|
1224
|
+
|
|
1225
|
+
|
|
971
1226
|
/**
|
|
972
1227
|
* @constructor
|
|
973
1228
|
* @see http://www.w3.org/TR/shadow-dom/#host-at-rule
|
|
@@ -996,14 +1251,27 @@ Object.defineProperty(CSSOM.CSSStartingStyleRule.prototype, "cssText", {
|
|
|
996
1251
|
|
|
997
1252
|
|
|
998
1253
|
|
|
1254
|
+
|
|
1255
|
+
|
|
1256
|
+
|
|
999
1257
|
/**
|
|
1000
1258
|
* @constructor
|
|
1001
1259
|
* @see http://dev.w3.org/csswg/cssom/#the-stylesheet-interface
|
|
1002
1260
|
*/
|
|
1003
1261
|
CSSOM.StyleSheet = function StyleSheet() {
|
|
1004
|
-
this.
|
|
1262
|
+
this.__parentStyleSheet = null;
|
|
1005
1263
|
};
|
|
1006
1264
|
|
|
1265
|
+
Object.defineProperties(CSSOM.StyleSheet.prototype, {
|
|
1266
|
+
parentStyleSheet: {
|
|
1267
|
+
get: function() {
|
|
1268
|
+
return this.__parentStyleSheet;
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
});
|
|
1272
|
+
|
|
1273
|
+
|
|
1274
|
+
|
|
1007
1275
|
|
|
1008
1276
|
|
|
1009
1277
|
/**
|
|
@@ -1038,25 +1306,113 @@ CSSOM.CSSStyleSheet.prototype.constructor = CSSOM.CSSStyleSheet;
|
|
|
1038
1306
|
*/
|
|
1039
1307
|
CSSOM.CSSStyleSheet.prototype.insertRule = function(rule, index) {
|
|
1040
1308
|
if (rule === undefined && index === undefined) {
|
|
1041
|
-
|
|
1309
|
+
errorUtils.throwMissingArguments(this, 'insertRule', this.constructor.name);
|
|
1042
1310
|
}
|
|
1043
1311
|
if (index === void 0) {
|
|
1044
1312
|
index = 0;
|
|
1045
1313
|
}
|
|
1046
|
-
|
|
1047
|
-
|
|
1314
|
+
index = Number(index);
|
|
1315
|
+
if (index < 0) {
|
|
1316
|
+
index = 4294967296 + index;
|
|
1048
1317
|
}
|
|
1318
|
+
if (index > this.cssRules.length) {
|
|
1319
|
+
errorUtils.throwIndexError(this, 'insertRule', this.constructor.name, index, this.cssRules.length);
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1049
1322
|
var ruleToParse = String(rule);
|
|
1050
1323
|
var parsedSheet = CSSOM.parse(ruleToParse);
|
|
1051
1324
|
if (parsedSheet.cssRules.length !== 1) {
|
|
1052
|
-
|
|
1053
|
-
if (ruleToParse.trimStart().startsWith('@namespace')) {
|
|
1054
|
-
domExceptionName = "InvalidStateError";
|
|
1055
|
-
}
|
|
1056
|
-
throw new (this._globalObject && this._globalObject.DOMException || DOMException)("Failed to execute 'insertRule' on 'CSSStyleSheet': Failed to parse the rule '" + ruleToParse + "'.", domExceptionName);
|
|
1325
|
+
errorUtils.throwParseError(this, 'insertRule', this.constructor.name, ruleToParse, 'SyntaxError');
|
|
1057
1326
|
}
|
|
1058
1327
|
var cssRule = parsedSheet.cssRules[0];
|
|
1059
|
-
|
|
1328
|
+
|
|
1329
|
+
// Helper function to find the last index of a specific rule constructor
|
|
1330
|
+
function findLastIndexOfConstructor(rules, constructorName) {
|
|
1331
|
+
for (var i = rules.length - 1; i >= 0; i--) {
|
|
1332
|
+
if (rules[i].constructor.name === constructorName) {
|
|
1333
|
+
return i;
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
1336
|
+
return -1;
|
|
1337
|
+
}
|
|
1338
|
+
|
|
1339
|
+
// Helper function to find the first index of a rule that's NOT of specified constructors
|
|
1340
|
+
function findFirstNonConstructorIndex(rules, constructorNames) {
|
|
1341
|
+
for (var i = 0; i < rules.length; i++) {
|
|
1342
|
+
if (constructorNames.indexOf(rules[i].constructor.name) === -1) {
|
|
1343
|
+
return i;
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1346
|
+
return rules.length;
|
|
1347
|
+
}
|
|
1348
|
+
|
|
1349
|
+
// Validate rule ordering based on CSS specification
|
|
1350
|
+
if (cssRule.constructor.name === 'CSSImportRule') {
|
|
1351
|
+
// @import rules cannot be inserted after @layer rules that already exist
|
|
1352
|
+
// They can only be inserted at the beginning or after other @import rules
|
|
1353
|
+
var firstLayerIndex = findFirstNonConstructorIndex(this.cssRules, ['CSSImportRule']);
|
|
1354
|
+
if (firstLayerIndex < this.cssRules.length && this.cssRules[firstLayerIndex].constructor.name === 'CSSLayerStatementRule' && index > firstLayerIndex) {
|
|
1355
|
+
errorUtils.throwError(this, 'DOMException',
|
|
1356
|
+
"Failed to execute 'insertRule' on '" + this.constructor.name + "': Failed to insert the rule.",
|
|
1357
|
+
'HierarchyRequestError');
|
|
1358
|
+
}
|
|
1359
|
+
|
|
1360
|
+
// Also cannot insert after @namespace or other rules
|
|
1361
|
+
var firstNonImportIndex = findFirstNonConstructorIndex(this.cssRules, ['CSSImportRule']);
|
|
1362
|
+
if (index > firstNonImportIndex && firstNonImportIndex < this.cssRules.length &&
|
|
1363
|
+
this.cssRules[firstNonImportIndex].constructor.name !== 'CSSLayerStatementRule') {
|
|
1364
|
+
errorUtils.throwError(this, 'DOMException',
|
|
1365
|
+
"Failed to execute 'insertRule' on '" + this.constructor.name + "': Failed to insert the rule.",
|
|
1366
|
+
'HierarchyRequestError');
|
|
1367
|
+
}
|
|
1368
|
+
} else if (cssRule.constructor.name === 'CSSNamespaceRule') {
|
|
1369
|
+
// @namespace rules can come after @layer and @import, but before any other rules
|
|
1370
|
+
// They cannot come before @import rules
|
|
1371
|
+
var firstImportIndex = -1;
|
|
1372
|
+
for (var i = 0; i < this.cssRules.length; i++) {
|
|
1373
|
+
if (this.cssRules[i].constructor.name === 'CSSImportRule') {
|
|
1374
|
+
firstImportIndex = i;
|
|
1375
|
+
break;
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1378
|
+
var firstNonImportNamespaceIndex = findFirstNonConstructorIndex(this.cssRules, [
|
|
1379
|
+
'CSSLayerStatementRule',
|
|
1380
|
+
'CSSImportRule',
|
|
1381
|
+
'CSSNamespaceRule'
|
|
1382
|
+
]);
|
|
1383
|
+
|
|
1384
|
+
// Cannot insert before @import rules
|
|
1385
|
+
if (firstImportIndex !== -1 && index <= firstImportIndex) {
|
|
1386
|
+
errorUtils.throwError(this, 'DOMException',
|
|
1387
|
+
"Failed to execute 'insertRule' on '" + this.constructor.name + "': Failed to insert the rule.",
|
|
1388
|
+
'HierarchyRequestError');
|
|
1389
|
+
}
|
|
1390
|
+
|
|
1391
|
+
// Cannot insert after other types of rules
|
|
1392
|
+
if (index > firstNonImportNamespaceIndex) {
|
|
1393
|
+
errorUtils.throwError(this, 'DOMException',
|
|
1394
|
+
"Failed to execute 'insertRule' on '" + this.constructor.name + "': Failed to insert the rule.",
|
|
1395
|
+
'HierarchyRequestError');
|
|
1396
|
+
}
|
|
1397
|
+
} else if (cssRule.constructor.name === 'CSSLayerStatementRule') {
|
|
1398
|
+
// @layer statement rules can be inserted anywhere before @import and @namespace
|
|
1399
|
+
// No additional restrictions beyond what's already handled
|
|
1400
|
+
} else {
|
|
1401
|
+
// Any other rule cannot be inserted before @import and @namespace
|
|
1402
|
+
var firstNonSpecialRuleIndex = findFirstNonConstructorIndex(this.cssRules, [
|
|
1403
|
+
'CSSLayerStatementRule',
|
|
1404
|
+
'CSSImportRule',
|
|
1405
|
+
'CSSNamespaceRule'
|
|
1406
|
+
]);
|
|
1407
|
+
|
|
1408
|
+
if (index < firstNonSpecialRuleIndex) {
|
|
1409
|
+
errorUtils.throwError(this, 'DOMException',
|
|
1410
|
+
"Failed to execute 'insertRule' on '" + this.constructor.name + "': Failed to insert the rule.",
|
|
1411
|
+
'HierarchyRequestError');
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1414
|
+
|
|
1415
|
+
cssRule.__parentStyleSheet = this;
|
|
1060
1416
|
this.cssRules.splice(index, 0, cssRule);
|
|
1061
1417
|
return index;
|
|
1062
1418
|
};
|
|
@@ -1077,21 +1433,21 @@ CSSOM.CSSStyleSheet.prototype.insertRule = function(rule, index) {
|
|
|
1077
1433
|
*/
|
|
1078
1434
|
CSSOM.CSSStyleSheet.prototype.deleteRule = function(index) {
|
|
1079
1435
|
if (index === undefined) {
|
|
1080
|
-
|
|
1436
|
+
errorUtils.throwMissingArguments(this, 'deleteRule', this.constructor.name);
|
|
1081
1437
|
}
|
|
1082
1438
|
index = Number(index);
|
|
1083
1439
|
if (index < 0) {
|
|
1084
1440
|
index = 4294967296 + index;
|
|
1085
1441
|
}
|
|
1086
1442
|
if (index >= this.cssRules.length) {
|
|
1087
|
-
|
|
1443
|
+
errorUtils.throwIndexError(this, 'deleteRule', this.constructor.name, index, this.cssRules.length);
|
|
1088
1444
|
}
|
|
1089
1445
|
if (this.cssRules[index] && this.cssRules[index].constructor.name == "CSSNamespaceRule") {
|
|
1090
1446
|
var shouldContinue = this.cssRules.every(function (rule) {
|
|
1091
1447
|
return ['CSSImportRule','CSSLayerStatementRule','CSSNamespaceRule'].indexOf(rule.constructor.name) !== -1
|
|
1092
1448
|
});
|
|
1093
1449
|
if (!shouldContinue) {
|
|
1094
|
-
|
|
1450
|
+
errorUtils.throwError(this, 'DOMException', "Failed to execute 'deleteRule' on '" + this.constructor.name + "': Failed to delete rule.", "InvalidStateError");
|
|
1095
1451
|
}
|
|
1096
1452
|
}
|
|
1097
1453
|
this.cssRules.splice(index, 1);
|
|
@@ -1113,6 +1469,9 @@ CSSOM.CSSStyleSheet.prototype.toString = function() {
|
|
|
1113
1469
|
|
|
1114
1470
|
|
|
1115
1471
|
|
|
1472
|
+
|
|
1473
|
+
|
|
1474
|
+
|
|
1116
1475
|
/**
|
|
1117
1476
|
* @constructor
|
|
1118
1477
|
* @see http://www.w3.org/TR/css3-animations/#DOM-CSSKeyframesRule
|
|
@@ -1121,14 +1480,42 @@ CSSOM.CSSKeyframesRule = function CSSKeyframesRule() {
|
|
|
1121
1480
|
CSSOM.CSSRule.call(this);
|
|
1122
1481
|
this.name = '';
|
|
1123
1482
|
this.cssRules = [];
|
|
1483
|
+
|
|
1484
|
+
// Set up initial indexed access
|
|
1485
|
+
this._setupIndexedAccess();
|
|
1486
|
+
|
|
1487
|
+
// Override cssRules methods after initial setup, store references as non-enumerable properties
|
|
1488
|
+
var self = this;
|
|
1489
|
+
var originalPush = this.cssRules.push;
|
|
1490
|
+
var originalSplice = this.cssRules.splice;
|
|
1491
|
+
|
|
1492
|
+
// Create non-enumerable method overrides
|
|
1493
|
+
Object.defineProperty(this.cssRules, 'push', {
|
|
1494
|
+
value: function() {
|
|
1495
|
+
var result = originalPush.apply(this, arguments);
|
|
1496
|
+
self._setupIndexedAccess();
|
|
1497
|
+
return result;
|
|
1498
|
+
},
|
|
1499
|
+
writable: true,
|
|
1500
|
+
enumerable: false,
|
|
1501
|
+
configurable: true
|
|
1502
|
+
});
|
|
1503
|
+
|
|
1504
|
+
Object.defineProperty(this.cssRules, 'splice', {
|
|
1505
|
+
value: function() {
|
|
1506
|
+
var result = originalSplice.apply(this, arguments);
|
|
1507
|
+
self._setupIndexedAccess();
|
|
1508
|
+
return result;
|
|
1509
|
+
},
|
|
1510
|
+
writable: true,
|
|
1511
|
+
enumerable: false,
|
|
1512
|
+
configurable: true
|
|
1513
|
+
});
|
|
1124
1514
|
};
|
|
1125
1515
|
|
|
1126
1516
|
CSSOM.CSSKeyframesRule.prototype = new CSSOM.CSSRule();
|
|
1127
1517
|
CSSOM.CSSKeyframesRule.prototype.constructor = CSSOM.CSSKeyframesRule;
|
|
1128
1518
|
CSSOM.CSSKeyframesRule.prototype.type = 7;
|
|
1129
|
-
//FIXME
|
|
1130
|
-
//CSSOM.CSSKeyframesRule.prototype.insertRule = CSSStyleSheet.prototype.insertRule;
|
|
1131
|
-
//CSSOM.CSSKeyframesRule.prototype.deleteRule = CSSStyleSheet.prototype.deleteRule;
|
|
1132
1519
|
|
|
1133
1520
|
// http://www.opensource.apple.com/source/WebCore/WebCore-955.66.1/css/WebKitCSSKeyframesRule.cpp
|
|
1134
1521
|
Object.defineProperty(CSSOM.CSSKeyframesRule.prototype, "cssText", {
|
|
@@ -1137,10 +1524,177 @@ Object.defineProperty(CSSOM.CSSKeyframesRule.prototype, "cssText", {
|
|
|
1137
1524
|
for (var i=0, length=this.cssRules.length; i < length; i++) {
|
|
1138
1525
|
cssTexts.push(this.cssRules[i].cssText);
|
|
1139
1526
|
}
|
|
1140
|
-
|
|
1527
|
+
var cssWideKeywords = ['initial', 'inherit', 'revert', 'revert-layer', 'unset', 'none'];
|
|
1528
|
+
var processedName = cssWideKeywords.includes(this.name) ? '"' + this.name + '"' : this.name;
|
|
1529
|
+
return "@" + (this._vendorPrefix || '') + "keyframes " + processedName + (processedName && " ") + "{" + (cssTexts.length ? "\n " + cssTexts.join("\n ") : "") + "\n}";
|
|
1141
1530
|
}
|
|
1142
1531
|
});
|
|
1143
1532
|
|
|
1533
|
+
/**
|
|
1534
|
+
* Appends a new keyframe rule to the list of keyframes.
|
|
1535
|
+
*
|
|
1536
|
+
* @param {string} rule - The keyframe rule string to append (e.g., "50% { opacity: 0.5; }")
|
|
1537
|
+
* @see https://www.w3.org/TR/css-animations-1/#dom-csskeyframesrule-appendrule
|
|
1538
|
+
*/
|
|
1539
|
+
CSSOM.CSSKeyframesRule.prototype.appendRule = function appendRule(rule) {
|
|
1540
|
+
if (arguments.length === 0) {
|
|
1541
|
+
errorUtils.throwMissingArguments(this, 'appendRule', 'CSSKeyframesRule');
|
|
1542
|
+
}
|
|
1543
|
+
|
|
1544
|
+
var parsedRule;
|
|
1545
|
+
try {
|
|
1546
|
+
// Parse the rule string as a keyframe rule
|
|
1547
|
+
var tempStyleSheet = CSSOM.parse("@keyframes temp { " + rule + " }");
|
|
1548
|
+
if (tempStyleSheet.cssRules.length > 0 && tempStyleSheet.cssRules[0].cssRules.length > 0) {
|
|
1549
|
+
parsedRule = tempStyleSheet.cssRules[0].cssRules[0];
|
|
1550
|
+
} else {
|
|
1551
|
+
throw new Error("Failed to parse keyframe rule");
|
|
1552
|
+
}
|
|
1553
|
+
} catch (e) {
|
|
1554
|
+
errorUtils.throwParseError(this, 'appendRule', 'CSSKeyframesRule', rule);
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1557
|
+
parsedRule.__parentRule = this;
|
|
1558
|
+
this.cssRules.push(parsedRule);
|
|
1559
|
+
};
|
|
1560
|
+
|
|
1561
|
+
/**
|
|
1562
|
+
* Deletes a keyframe rule that matches the specified key.
|
|
1563
|
+
*
|
|
1564
|
+
* @param {string} select - The keyframe selector to delete (e.g., "50%", "from", "to")
|
|
1565
|
+
* @see https://www.w3.org/TR/css-animations-1/#dom-csskeyframesrule-deleterule
|
|
1566
|
+
*/
|
|
1567
|
+
CSSOM.CSSKeyframesRule.prototype.deleteRule = function deleteRule(select) {
|
|
1568
|
+
if (arguments.length === 0) {
|
|
1569
|
+
errorUtils.throwMissingArguments(this, 'deleteRule', 'CSSKeyframesRule');
|
|
1570
|
+
}
|
|
1571
|
+
|
|
1572
|
+
var normalizedSelect = this._normalizeKeyText(select);
|
|
1573
|
+
|
|
1574
|
+
for (var i = 0; i < this.cssRules.length; i++) {
|
|
1575
|
+
var rule = this.cssRules[i];
|
|
1576
|
+
if (this._normalizeKeyText(rule.keyText) === normalizedSelect) {
|
|
1577
|
+
rule.__parentRule = null;
|
|
1578
|
+
this.cssRules.splice(i, 1);
|
|
1579
|
+
return;
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1582
|
+
};
|
|
1583
|
+
|
|
1584
|
+
/**
|
|
1585
|
+
* Finds and returns the keyframe rule that matches the specified key.
|
|
1586
|
+
* When multiple rules have the same key, returns the last one.
|
|
1587
|
+
*
|
|
1588
|
+
* @param {string} select - The keyframe selector to find (e.g., "50%", "from", "to")
|
|
1589
|
+
* @return {CSSKeyframeRule|null} The matching keyframe rule, or null if not found
|
|
1590
|
+
* @see https://www.w3.org/TR/css-animations-1/#dom-csskeyframesrule-findrule
|
|
1591
|
+
*/
|
|
1592
|
+
CSSOM.CSSKeyframesRule.prototype.findRule = function findRule(select) {
|
|
1593
|
+
if (arguments.length === 0) {
|
|
1594
|
+
errorUtils.throwMissingArguments(this, 'findRule', 'CSSKeyframesRule');
|
|
1595
|
+
}
|
|
1596
|
+
|
|
1597
|
+
var normalizedSelect = this._normalizeKeyText(select);
|
|
1598
|
+
|
|
1599
|
+
// Iterate backwards to find the last matching rule
|
|
1600
|
+
for (var i = this.cssRules.length - 1; i >= 0; i--) {
|
|
1601
|
+
var rule = this.cssRules[i];
|
|
1602
|
+
if (this._normalizeKeyText(rule.keyText) === normalizedSelect) {
|
|
1603
|
+
return rule;
|
|
1604
|
+
}
|
|
1605
|
+
}
|
|
1606
|
+
|
|
1607
|
+
return null;
|
|
1608
|
+
};
|
|
1609
|
+
|
|
1610
|
+
/**
|
|
1611
|
+
* Normalizes keyframe selector text for comparison.
|
|
1612
|
+
* Handles "from" -> "0%" and "to" -> "100%" conversions and trims whitespace.
|
|
1613
|
+
*
|
|
1614
|
+
* @private
|
|
1615
|
+
* @param {string} keyText - The keyframe selector text to normalize
|
|
1616
|
+
* @return {string} The normalized keyframe selector text
|
|
1617
|
+
*/
|
|
1618
|
+
CSSOM.CSSKeyframesRule.prototype._normalizeKeyText = function _normalizeKeyText(keyText) {
|
|
1619
|
+
if (!keyText) return '';
|
|
1620
|
+
|
|
1621
|
+
var normalized = keyText.toString().trim().toLowerCase();
|
|
1622
|
+
|
|
1623
|
+
// Convert keywords to percentages for comparison
|
|
1624
|
+
if (normalized === 'from') {
|
|
1625
|
+
return '0%';
|
|
1626
|
+
} else if (normalized === 'to') {
|
|
1627
|
+
return '100%';
|
|
1628
|
+
}
|
|
1629
|
+
|
|
1630
|
+
return normalized;
|
|
1631
|
+
};
|
|
1632
|
+
|
|
1633
|
+
/**
|
|
1634
|
+
* Makes CSSKeyframesRule iterable over its cssRules.
|
|
1635
|
+
* Allows for...of loops and other iterable methods.
|
|
1636
|
+
*/
|
|
1637
|
+
if (typeof Symbol !== 'undefined' && Symbol.iterator) {
|
|
1638
|
+
CSSOM.CSSKeyframesRule.prototype[Symbol.iterator] = function() {
|
|
1639
|
+
var index = 0;
|
|
1640
|
+
var cssRules = this.cssRules;
|
|
1641
|
+
|
|
1642
|
+
return {
|
|
1643
|
+
next: function() {
|
|
1644
|
+
if (index < cssRules.length) {
|
|
1645
|
+
return { value: cssRules[index++], done: false };
|
|
1646
|
+
} else {
|
|
1647
|
+
return { done: true };
|
|
1648
|
+
}
|
|
1649
|
+
}
|
|
1650
|
+
};
|
|
1651
|
+
};
|
|
1652
|
+
}
|
|
1653
|
+
|
|
1654
|
+
/**
|
|
1655
|
+
* Adds indexed getters for direct access to cssRules by index.
|
|
1656
|
+
* This enables rule[0], rule[1], etc. access patterns.
|
|
1657
|
+
* Works in environments where Proxy is not available (like jsdom).
|
|
1658
|
+
*/
|
|
1659
|
+
CSSOM.CSSKeyframesRule.prototype._setupIndexedAccess = function() {
|
|
1660
|
+
// Remove any existing indexed properties
|
|
1661
|
+
for (var i = 0; i < 1000; i++) { // reasonable upper limit
|
|
1662
|
+
if (this.hasOwnProperty(i)) {
|
|
1663
|
+
delete this[i];
|
|
1664
|
+
} else {
|
|
1665
|
+
break;
|
|
1666
|
+
}
|
|
1667
|
+
}
|
|
1668
|
+
|
|
1669
|
+
// Add indexed getters for current cssRules
|
|
1670
|
+
for (var i = 0; i < this.cssRules.length; i++) {
|
|
1671
|
+
(function(index) {
|
|
1672
|
+
Object.defineProperty(this, index, {
|
|
1673
|
+
get: function() {
|
|
1674
|
+
return this.cssRules[index];
|
|
1675
|
+
},
|
|
1676
|
+
enumerable: false,
|
|
1677
|
+
configurable: true
|
|
1678
|
+
});
|
|
1679
|
+
}.call(this, i));
|
|
1680
|
+
}
|
|
1681
|
+
|
|
1682
|
+
// Update length property
|
|
1683
|
+
Object.defineProperty(this, 'length', {
|
|
1684
|
+
get: function() {
|
|
1685
|
+
return this.cssRules.length;
|
|
1686
|
+
},
|
|
1687
|
+
enumerable: false,
|
|
1688
|
+
configurable: true
|
|
1689
|
+
});
|
|
1690
|
+
};
|
|
1691
|
+
|
|
1692
|
+
|
|
1693
|
+
|
|
1694
|
+
|
|
1695
|
+
|
|
1696
|
+
|
|
1697
|
+
|
|
1144
1698
|
|
|
1145
1699
|
|
|
1146
1700
|
/**
|
|
@@ -1150,8 +1704,8 @@ Object.defineProperty(CSSOM.CSSKeyframesRule.prototype, "cssText", {
|
|
|
1150
1704
|
CSSOM.CSSKeyframeRule = function CSSKeyframeRule() {
|
|
1151
1705
|
CSSOM.CSSRule.call(this);
|
|
1152
1706
|
this.keyText = '';
|
|
1153
|
-
this.
|
|
1154
|
-
this.
|
|
1707
|
+
this.__style = new CSSOM.CSSStyleDeclaration();
|
|
1708
|
+
this.__style.parentRule = this;
|
|
1155
1709
|
};
|
|
1156
1710
|
|
|
1157
1711
|
CSSOM.CSSKeyframeRule.prototype = new CSSOM.CSSRule();
|
|
@@ -1161,15 +1715,31 @@ CSSOM.CSSKeyframeRule.prototype.type = 8;
|
|
|
1161
1715
|
//CSSOM.CSSKeyframeRule.prototype.insertRule = CSSStyleSheet.prototype.insertRule;
|
|
1162
1716
|
//CSSOM.CSSKeyframeRule.prototype.deleteRule = CSSStyleSheet.prototype.deleteRule;
|
|
1163
1717
|
|
|
1718
|
+
Object.defineProperty(CSSOM.CSSKeyframeRule.prototype, "style", {
|
|
1719
|
+
get: function() {
|
|
1720
|
+
return this.__style;
|
|
1721
|
+
},
|
|
1722
|
+
set: function(value) {
|
|
1723
|
+
if (typeof value === "string") {
|
|
1724
|
+
this.__style.cssText = value;
|
|
1725
|
+
} else {
|
|
1726
|
+
this.__style = value;
|
|
1727
|
+
}
|
|
1728
|
+
}
|
|
1729
|
+
});
|
|
1730
|
+
|
|
1164
1731
|
// http://www.opensource.apple.com/source/WebCore/WebCore-955.66.1/css/WebKitCSSKeyframeRule.cpp
|
|
1165
1732
|
Object.defineProperty(CSSOM.CSSKeyframeRule.prototype, "cssText", {
|
|
1166
1733
|
get: function() {
|
|
1167
|
-
return this.keyText + " { " + this.style.cssText + " }
|
|
1734
|
+
return this.keyText + " {" + (this.style.cssText ? " " + this.style.cssText : "") + " }";
|
|
1168
1735
|
}
|
|
1169
1736
|
});
|
|
1170
1737
|
|
|
1171
1738
|
|
|
1172
1739
|
|
|
1740
|
+
|
|
1741
|
+
|
|
1742
|
+
|
|
1173
1743
|
/**
|
|
1174
1744
|
* @constructor
|
|
1175
1745
|
* @see https://developer.mozilla.org/en/CSS/@-moz-document
|
|
@@ -1225,6 +1795,9 @@ CSSOM.MatcherList.prototype = {
|
|
|
1225
1795
|
|
|
1226
1796
|
|
|
1227
1797
|
|
|
1798
|
+
|
|
1799
|
+
|
|
1800
|
+
|
|
1228
1801
|
/**
|
|
1229
1802
|
* @constructor
|
|
1230
1803
|
* @see https://developer.mozilla.org/en/CSS/@-moz-document
|
|
@@ -1254,6 +1827,9 @@ Object.defineProperty(CSSOM.CSSDocumentRule.prototype, "cssText", {
|
|
|
1254
1827
|
|
|
1255
1828
|
|
|
1256
1829
|
|
|
1830
|
+
|
|
1831
|
+
|
|
1832
|
+
|
|
1257
1833
|
/**
|
|
1258
1834
|
* @constructor
|
|
1259
1835
|
* @see http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSValue
|
|
@@ -1290,6 +1866,9 @@ CSSOM.CSSValue.prototype = {
|
|
|
1290
1866
|
|
|
1291
1867
|
|
|
1292
1868
|
|
|
1869
|
+
|
|
1870
|
+
|
|
1871
|
+
|
|
1293
1872
|
/**
|
|
1294
1873
|
* @constructor
|
|
1295
1874
|
* @see http://msdn.microsoft.com/en-us/library/ms537634(v=vs.85).aspx
|
|
@@ -1625,6 +2204,8 @@ CSSOM.CSSValueExpression.prototype._findMatchedIdx = function(token, idx, sep) {
|
|
|
1625
2204
|
|
|
1626
2205
|
|
|
1627
2206
|
|
|
2207
|
+
|
|
2208
|
+
|
|
1628
2209
|
/**
|
|
1629
2210
|
* @constructor
|
|
1630
2211
|
* @see https://drafts.csswg.org/css-cascade-5/#csslayerblockrule
|
|
@@ -1654,6 +2235,8 @@ Object.defineProperties(CSSOM.CSSLayerBlockRule.prototype, {
|
|
|
1654
2235
|
});
|
|
1655
2236
|
|
|
1656
2237
|
|
|
2238
|
+
|
|
2239
|
+
|
|
1657
2240
|
/**
|
|
1658
2241
|
* @constructor
|
|
1659
2242
|
* @see https://drafts.csswg.org/css-cascade-5/#csslayerstatementrule
|
|
@@ -1678,11 +2261,20 @@ Object.defineProperties(CSSOM.CSSLayerStatementRule.prototype, {
|
|
|
1678
2261
|
});
|
|
1679
2262
|
|
|
1680
2263
|
|
|
2264
|
+
|
|
2265
|
+
|
|
2266
|
+
|
|
1681
2267
|
/**
|
|
1682
|
-
*
|
|
2268
|
+
* Parses a CSS string and returns a CSSOM.CSSStyleSheet object representing the parsed stylesheet.
|
|
2269
|
+
*
|
|
2270
|
+
* @param {string} token - The CSS string to parse.
|
|
2271
|
+
* @param {object} [opts] - Optional parsing options.
|
|
2272
|
+
* @param {object} [opts.globalObject] - An optional global object to attach to the stylesheet. Useful on jsdom webplatform tests.
|
|
2273
|
+
* @param {function|boolean} [errorHandler] - Optional error handler function or `true` to use `console.error`.
|
|
2274
|
+
* @returns {CSSOM.CSSStyleSheet} The parsed CSSStyleSheet object.
|
|
1683
2275
|
*/
|
|
1684
|
-
CSSOM.parse = function parse(token, errorHandler) {
|
|
1685
|
-
errorHandler = errorHandler ===
|
|
2276
|
+
CSSOM.parse = function parse(token, opts, errorHandler) {
|
|
2277
|
+
errorHandler = errorHandler === true ? (console && console.error) : errorHandler;
|
|
1686
2278
|
|
|
1687
2279
|
var i = 0;
|
|
1688
2280
|
|
|
@@ -1724,6 +2316,10 @@ CSSOM.parse = function parse(token, errorHandler) {
|
|
|
1724
2316
|
|
|
1725
2317
|
var styleSheet = new CSSOM.CSSStyleSheet();
|
|
1726
2318
|
|
|
2319
|
+
if (opts && opts.globalObject) {
|
|
2320
|
+
styleSheet.__globalObject = opts.globalObject;
|
|
2321
|
+
}
|
|
2322
|
+
|
|
1727
2323
|
// @type CSSStyleSheet|CSSMediaRule|CSSContainerRule|CSSSupportsRule|CSSFontFaceRule|CSSKeyframesRule|CSSDocumentRule
|
|
1728
2324
|
var currentScope = styleSheet;
|
|
1729
2325
|
|
|
@@ -2421,7 +3017,7 @@ CSSOM.parse = function parse(token, errorHandler) {
|
|
|
2421
3017
|
i += "font-face".length;
|
|
2422
3018
|
fontFaceRule = new CSSOM.CSSFontFaceRule();
|
|
2423
3019
|
fontFaceRule.__starts = i;
|
|
2424
|
-
},
|
|
3020
|
+
}, true);
|
|
2425
3021
|
break;
|
|
2426
3022
|
} else {
|
|
2427
3023
|
atKeyframesRegExp.lastIndex = i;
|
|
@@ -2463,7 +3059,7 @@ CSSOM.parse = function parse(token, errorHandler) {
|
|
|
2463
3059
|
}
|
|
2464
3060
|
|
|
2465
3061
|
if (parentRule) {
|
|
2466
|
-
styleRule.
|
|
3062
|
+
styleRule.__parentRule = parentRule;
|
|
2467
3063
|
ancestorRules.push(parentRule);
|
|
2468
3064
|
}
|
|
2469
3065
|
|
|
@@ -2473,48 +3069,48 @@ CSSOM.parse = function parse(token, errorHandler) {
|
|
|
2473
3069
|
return match;
|
|
2474
3070
|
});
|
|
2475
3071
|
styleRule.style.__starts = i;
|
|
2476
|
-
styleRule.
|
|
3072
|
+
styleRule.__parentStyleSheet = styleSheet;
|
|
2477
3073
|
buffer = "";
|
|
2478
3074
|
state = "before-name";
|
|
2479
3075
|
} else if (state === "atBlock") {
|
|
2480
3076
|
mediaRule.media.mediaText = buffer.trim();
|
|
2481
3077
|
|
|
2482
3078
|
if (parentRule) {
|
|
2483
|
-
mediaRule.
|
|
3079
|
+
mediaRule.__parentRule = parentRule;
|
|
2484
3080
|
ancestorRules.push(parentRule);
|
|
2485
3081
|
}
|
|
2486
3082
|
|
|
2487
3083
|
currentScope = parentRule = mediaRule;
|
|
2488
|
-
mediaRule.
|
|
3084
|
+
mediaRule.__parentStyleSheet = styleSheet;
|
|
2489
3085
|
buffer = "";
|
|
2490
3086
|
state = "before-selector";
|
|
2491
3087
|
} else if (state === "containerBlock") {
|
|
2492
3088
|
containerRule.containerText = buffer.trim();
|
|
2493
3089
|
|
|
2494
3090
|
if (parentRule) {
|
|
2495
|
-
containerRule.
|
|
3091
|
+
containerRule.__parentRule = parentRule;
|
|
2496
3092
|
ancestorRules.push(parentRule);
|
|
2497
3093
|
}
|
|
2498
3094
|
currentScope = parentRule = containerRule;
|
|
2499
|
-
containerRule.
|
|
3095
|
+
containerRule.__parentStyleSheet = styleSheet;
|
|
2500
3096
|
buffer = "";
|
|
2501
3097
|
state = "before-selector";
|
|
2502
3098
|
} else if (state === "counterStyleBlock") {
|
|
2503
3099
|
// TODO: Validate counter-style name. At least that it cannot be empty nor multiple
|
|
2504
3100
|
counterStyleRule.name = buffer.trim().replace(/\n/g, "");
|
|
2505
3101
|
currentScope = parentRule = counterStyleRule;
|
|
2506
|
-
counterStyleRule.
|
|
3102
|
+
counterStyleRule.__parentStyleSheet = styleSheet;
|
|
2507
3103
|
buffer = "";
|
|
2508
3104
|
} else if (state === "conditionBlock") {
|
|
2509
3105
|
supportsRule.conditionText = buffer.trim();
|
|
2510
3106
|
|
|
2511
3107
|
if (parentRule) {
|
|
2512
|
-
supportsRule.
|
|
3108
|
+
supportsRule.__parentRule = parentRule;
|
|
2513
3109
|
ancestorRules.push(parentRule);
|
|
2514
3110
|
}
|
|
2515
3111
|
|
|
2516
3112
|
currentScope = parentRule = supportsRule;
|
|
2517
|
-
supportsRule.
|
|
3113
|
+
supportsRule.__parentStyleSheet = styleSheet;
|
|
2518
3114
|
buffer = "";
|
|
2519
3115
|
state = "before-selector";
|
|
2520
3116
|
} else if (state === "layerBlock") {
|
|
@@ -2524,12 +3120,12 @@ CSSOM.parse = function parse(token, errorHandler) {
|
|
|
2524
3120
|
|
|
2525
3121
|
if (isValidName) {
|
|
2526
3122
|
if (parentRule) {
|
|
2527
|
-
layerBlockRule.
|
|
3123
|
+
layerBlockRule.__parentRule = parentRule;
|
|
2528
3124
|
ancestorRules.push(parentRule);
|
|
2529
3125
|
}
|
|
2530
3126
|
|
|
2531
3127
|
currentScope = parentRule = layerBlockRule;
|
|
2532
|
-
layerBlockRule.
|
|
3128
|
+
layerBlockRule.__parentStyleSheet = styleSheet;
|
|
2533
3129
|
}
|
|
2534
3130
|
buffer = "";
|
|
2535
3131
|
state = "before-selector";
|
|
@@ -2539,25 +3135,25 @@ CSSOM.parse = function parse(token, errorHandler) {
|
|
|
2539
3135
|
}
|
|
2540
3136
|
|
|
2541
3137
|
currentScope = parentRule = hostRule;
|
|
2542
|
-
hostRule.
|
|
3138
|
+
hostRule.__parentStyleSheet = styleSheet;
|
|
2543
3139
|
buffer = "";
|
|
2544
3140
|
state = "before-selector";
|
|
2545
3141
|
} else if (state === "startingStyleRule-begin") {
|
|
2546
3142
|
if (parentRule) {
|
|
2547
|
-
startingStyleRule.
|
|
3143
|
+
startingStyleRule.__parentRule = parentRule;
|
|
2548
3144
|
ancestorRules.push(parentRule);
|
|
2549
3145
|
}
|
|
2550
3146
|
|
|
2551
3147
|
currentScope = parentRule = startingStyleRule;
|
|
2552
|
-
startingStyleRule.
|
|
3148
|
+
startingStyleRule.__parentStyleSheet = styleSheet;
|
|
2553
3149
|
buffer = "";
|
|
2554
3150
|
state = "before-selector";
|
|
2555
3151
|
|
|
2556
3152
|
} else if (state === "fontFaceRule-begin") {
|
|
2557
3153
|
if (parentRule) {
|
|
2558
|
-
fontFaceRule.
|
|
3154
|
+
fontFaceRule.__parentRule = parentRule;
|
|
2559
3155
|
}
|
|
2560
|
-
fontFaceRule.
|
|
3156
|
+
fontFaceRule.__parentStyleSheet = styleSheet;
|
|
2561
3157
|
styleRule = fontFaceRule;
|
|
2562
3158
|
buffer = "";
|
|
2563
3159
|
state = "before-name";
|
|
@@ -2565,9 +3161,9 @@ CSSOM.parse = function parse(token, errorHandler) {
|
|
|
2565
3161
|
keyframesRule.name = buffer.trim();
|
|
2566
3162
|
if (parentRule) {
|
|
2567
3163
|
ancestorRules.push(parentRule);
|
|
2568
|
-
keyframesRule.
|
|
3164
|
+
keyframesRule.__parentRule = parentRule;
|
|
2569
3165
|
}
|
|
2570
|
-
keyframesRule.
|
|
3166
|
+
keyframesRule.__parentStyleSheet = styleSheet;
|
|
2571
3167
|
currentScope = parentRule = keyframesRule;
|
|
2572
3168
|
buffer = "";
|
|
2573
3169
|
state = "keyframeRule-begin";
|
|
@@ -2582,18 +3178,18 @@ CSSOM.parse = function parse(token, errorHandler) {
|
|
|
2582
3178
|
documentRule.matcher.matcherText = buffer.trim();
|
|
2583
3179
|
if (parentRule) {
|
|
2584
3180
|
ancestorRules.push(parentRule);
|
|
2585
|
-
documentRule.
|
|
3181
|
+
documentRule.__parentRule = parentRule;
|
|
2586
3182
|
}
|
|
2587
3183
|
currentScope = parentRule = documentRule;
|
|
2588
|
-
documentRule.
|
|
3184
|
+
documentRule.__parentStyleSheet = styleSheet;
|
|
2589
3185
|
buffer = "";
|
|
2590
3186
|
state = "before-selector";
|
|
2591
3187
|
} else if (state === "before-name" || state === "name") {
|
|
2592
3188
|
if (styleRule.constructor.name === "CSSNestedDeclarations") {
|
|
2593
3189
|
if (styleRule.style.length) {
|
|
2594
3190
|
parentRule.cssRules.push(styleRule);
|
|
2595
|
-
styleRule.
|
|
2596
|
-
styleRule.
|
|
3191
|
+
styleRule.__parentRule = parentRule;
|
|
3192
|
+
styleRule.__parentStyleSheet = styleSheet;
|
|
2597
3193
|
ancestorRules.push(parentRule);
|
|
2598
3194
|
} else {
|
|
2599
3195
|
// If the styleRule is empty, we can assume that it's a nested selector
|
|
@@ -2602,7 +3198,7 @@ CSSOM.parse = function parse(token, errorHandler) {
|
|
|
2602
3198
|
} else {
|
|
2603
3199
|
currentScope = parentRule = styleRule;
|
|
2604
3200
|
ancestorRules.push(parentRule);
|
|
2605
|
-
styleRule.
|
|
3201
|
+
styleRule.__parentStyleSheet = styleSheet;
|
|
2606
3202
|
}
|
|
2607
3203
|
|
|
2608
3204
|
styleRule = new CSSOM.CSSStyleRule();
|
|
@@ -2619,7 +3215,7 @@ CSSOM.parse = function parse(token, errorHandler) {
|
|
|
2619
3215
|
}).join(', ');
|
|
2620
3216
|
}
|
|
2621
3217
|
styleRule.style.__starts = i - buffer.length;
|
|
2622
|
-
styleRule.
|
|
3218
|
+
styleRule.__parentRule = parentRule;
|
|
2623
3219
|
nestedSelectorRule = styleRule;
|
|
2624
3220
|
|
|
2625
3221
|
buffer = "";
|
|
@@ -2714,7 +3310,7 @@ CSSOM.parse = function parse(token, errorHandler) {
|
|
|
2714
3310
|
});
|
|
2715
3311
|
if (isValid) {
|
|
2716
3312
|
importRule = new CSSOM.CSSImportRule();
|
|
2717
|
-
importRule.
|
|
3313
|
+
importRule.__parentStyleSheet = importRule.styleSheet.__parentStyleSheet = styleSheet;
|
|
2718
3314
|
importRule.cssText = buffer + character;
|
|
2719
3315
|
styleSheet.cssRules.push(importRule);
|
|
2720
3316
|
}
|
|
@@ -2732,7 +3328,7 @@ CSSOM.parse = function parse(token, errorHandler) {
|
|
|
2732
3328
|
testNamespaceRule.cssText = buffer + character;
|
|
2733
3329
|
|
|
2734
3330
|
namespaceRule = testNamespaceRule;
|
|
2735
|
-
namespaceRule.
|
|
3331
|
+
namespaceRule.__parentStyleSheet = namespaceRule.styleSheet.__parentStyleSheet = styleSheet;
|
|
2736
3332
|
styleSheet.cssRules.push(namespaceRule);
|
|
2737
3333
|
|
|
2738
3334
|
// Track the namespace prefix for validation
|
|
@@ -2756,7 +3352,7 @@ CSSOM.parse = function parse(token, errorHandler) {
|
|
|
2756
3352
|
|
|
2757
3353
|
if (!isInvalid) {
|
|
2758
3354
|
layerStatementRule = new CSSOM.CSSLayerStatementRule();
|
|
2759
|
-
layerStatementRule.
|
|
3355
|
+
layerStatementRule.__parentStyleSheet = styleSheet;
|
|
2760
3356
|
layerStatementRule.__starts = layerBlockRule.__starts;
|
|
2761
3357
|
layerStatementRule.__ends = i;
|
|
2762
3358
|
layerStatementRule.nameList = nameListStr;
|
|
@@ -2796,9 +3392,9 @@ CSSOM.parse = function parse(token, errorHandler) {
|
|
|
2796
3392
|
}
|
|
2797
3393
|
|
|
2798
3394
|
if (parentRule) {
|
|
2799
|
-
styleRule.
|
|
3395
|
+
styleRule.__parentRule = parentRule;
|
|
2800
3396
|
}
|
|
2801
|
-
styleRule.
|
|
3397
|
+
styleRule.__parentStyleSheet = styleSheet;
|
|
2802
3398
|
|
|
2803
3399
|
if (currentScope === styleRule) {
|
|
2804
3400
|
currentScope = parentRule || styleSheet;
|
|
@@ -2924,7 +3520,7 @@ CSSOM.parse = function parse(token, errorHandler) {
|
|
|
2924
3520
|
|| parentRule.constructor.name === "CSSLayerBlockRule"
|
|
2925
3521
|
|| parentRule.constructor.name === "CSSStartingStyleRule"
|
|
2926
3522
|
) {
|
|
2927
|
-
// parentRule.
|
|
3523
|
+
// parentRule.__parentRule = styleRule;
|
|
2928
3524
|
state = "before-name";
|
|
2929
3525
|
if (styleRule !== parentRule) {
|
|
2930
3526
|
styleRule = new CSSOM.CSSNestedDeclarations();
|
|
@@ -2981,6 +3577,9 @@ CSSOM.parse = function parse(token, errorHandler) {
|
|
|
2981
3577
|
|
|
2982
3578
|
|
|
2983
3579
|
|
|
3580
|
+
|
|
3581
|
+
|
|
3582
|
+
|
|
2984
3583
|
/**
|
|
2985
3584
|
* Produces a deep copy of stylesheet — the instance variables of stylesheet are copied recursively.
|
|
2986
3585
|
* @param {CSSStyleSheet|CSSOM.CSSStyleSheet} stylesheet
|