@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/lib/CSSStyleSheet.js
CHANGED
|
@@ -3,6 +3,7 @@ var CSSOM = {
|
|
|
3
3
|
StyleSheet: require("./StyleSheet").StyleSheet,
|
|
4
4
|
CSSStyleRule: require("./CSSStyleRule").CSSStyleRule
|
|
5
5
|
};
|
|
6
|
+
var errorUtils = require("./errorUtils").errorUtils;
|
|
6
7
|
///CommonJS
|
|
7
8
|
|
|
8
9
|
|
|
@@ -38,25 +39,113 @@ CSSOM.CSSStyleSheet.prototype.constructor = CSSOM.CSSStyleSheet;
|
|
|
38
39
|
*/
|
|
39
40
|
CSSOM.CSSStyleSheet.prototype.insertRule = function(rule, index) {
|
|
40
41
|
if (rule === undefined && index === undefined) {
|
|
41
|
-
|
|
42
|
+
errorUtils.throwMissingArguments(this, 'insertRule', this.constructor.name);
|
|
42
43
|
}
|
|
43
44
|
if (index === void 0) {
|
|
44
45
|
index = 0;
|
|
45
46
|
}
|
|
46
|
-
|
|
47
|
-
|
|
47
|
+
index = Number(index);
|
|
48
|
+
if (index < 0) {
|
|
49
|
+
index = 4294967296 + index;
|
|
50
|
+
}
|
|
51
|
+
if (index > this.cssRules.length) {
|
|
52
|
+
errorUtils.throwIndexError(this, 'insertRule', this.constructor.name, index, this.cssRules.length);
|
|
48
53
|
}
|
|
54
|
+
|
|
49
55
|
var ruleToParse = String(rule);
|
|
50
56
|
var parsedSheet = CSSOM.parse(ruleToParse);
|
|
51
57
|
if (parsedSheet.cssRules.length !== 1) {
|
|
52
|
-
|
|
53
|
-
if (ruleToParse.trimStart().startsWith('@namespace')) {
|
|
54
|
-
domExceptionName = "InvalidStateError";
|
|
55
|
-
}
|
|
56
|
-
throw new (this._globalObject && this._globalObject.DOMException || DOMException)("Failed to execute 'insertRule' on 'CSSStyleSheet': Failed to parse the rule '" + ruleToParse + "'.", domExceptionName);
|
|
58
|
+
errorUtils.throwParseError(this, 'insertRule', this.constructor.name, ruleToParse, 'SyntaxError');
|
|
57
59
|
}
|
|
58
60
|
var cssRule = parsedSheet.cssRules[0];
|
|
59
|
-
|
|
61
|
+
|
|
62
|
+
// Helper function to find the last index of a specific rule constructor
|
|
63
|
+
function findLastIndexOfConstructor(rules, constructorName) {
|
|
64
|
+
for (var i = rules.length - 1; i >= 0; i--) {
|
|
65
|
+
if (rules[i].constructor.name === constructorName) {
|
|
66
|
+
return i;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return -1;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Helper function to find the first index of a rule that's NOT of specified constructors
|
|
73
|
+
function findFirstNonConstructorIndex(rules, constructorNames) {
|
|
74
|
+
for (var i = 0; i < rules.length; i++) {
|
|
75
|
+
if (constructorNames.indexOf(rules[i].constructor.name) === -1) {
|
|
76
|
+
return i;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return rules.length;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Validate rule ordering based on CSS specification
|
|
83
|
+
if (cssRule.constructor.name === 'CSSImportRule') {
|
|
84
|
+
// @import rules cannot be inserted after @layer rules that already exist
|
|
85
|
+
// They can only be inserted at the beginning or after other @import rules
|
|
86
|
+
var firstLayerIndex = findFirstNonConstructorIndex(this.cssRules, ['CSSImportRule']);
|
|
87
|
+
if (firstLayerIndex < this.cssRules.length && this.cssRules[firstLayerIndex].constructor.name === 'CSSLayerStatementRule' && index > firstLayerIndex) {
|
|
88
|
+
errorUtils.throwError(this, 'DOMException',
|
|
89
|
+
"Failed to execute 'insertRule' on '" + this.constructor.name + "': Failed to insert the rule.",
|
|
90
|
+
'HierarchyRequestError');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Also cannot insert after @namespace or other rules
|
|
94
|
+
var firstNonImportIndex = findFirstNonConstructorIndex(this.cssRules, ['CSSImportRule']);
|
|
95
|
+
if (index > firstNonImportIndex && firstNonImportIndex < this.cssRules.length &&
|
|
96
|
+
this.cssRules[firstNonImportIndex].constructor.name !== 'CSSLayerStatementRule') {
|
|
97
|
+
errorUtils.throwError(this, 'DOMException',
|
|
98
|
+
"Failed to execute 'insertRule' on '" + this.constructor.name + "': Failed to insert the rule.",
|
|
99
|
+
'HierarchyRequestError');
|
|
100
|
+
}
|
|
101
|
+
} else if (cssRule.constructor.name === 'CSSNamespaceRule') {
|
|
102
|
+
// @namespace rules can come after @layer and @import, but before any other rules
|
|
103
|
+
// They cannot come before @import rules
|
|
104
|
+
var firstImportIndex = -1;
|
|
105
|
+
for (var i = 0; i < this.cssRules.length; i++) {
|
|
106
|
+
if (this.cssRules[i].constructor.name === 'CSSImportRule') {
|
|
107
|
+
firstImportIndex = i;
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
var firstNonImportNamespaceIndex = findFirstNonConstructorIndex(this.cssRules, [
|
|
112
|
+
'CSSLayerStatementRule',
|
|
113
|
+
'CSSImportRule',
|
|
114
|
+
'CSSNamespaceRule'
|
|
115
|
+
]);
|
|
116
|
+
|
|
117
|
+
// Cannot insert before @import rules
|
|
118
|
+
if (firstImportIndex !== -1 && index <= firstImportIndex) {
|
|
119
|
+
errorUtils.throwError(this, 'DOMException',
|
|
120
|
+
"Failed to execute 'insertRule' on '" + this.constructor.name + "': Failed to insert the rule.",
|
|
121
|
+
'HierarchyRequestError');
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Cannot insert after other types of rules
|
|
125
|
+
if (index > firstNonImportNamespaceIndex) {
|
|
126
|
+
errorUtils.throwError(this, 'DOMException',
|
|
127
|
+
"Failed to execute 'insertRule' on '" + this.constructor.name + "': Failed to insert the rule.",
|
|
128
|
+
'HierarchyRequestError');
|
|
129
|
+
}
|
|
130
|
+
} else if (cssRule.constructor.name === 'CSSLayerStatementRule') {
|
|
131
|
+
// @layer statement rules can be inserted anywhere before @import and @namespace
|
|
132
|
+
// No additional restrictions beyond what's already handled
|
|
133
|
+
} else {
|
|
134
|
+
// Any other rule cannot be inserted before @import and @namespace
|
|
135
|
+
var firstNonSpecialRuleIndex = findFirstNonConstructorIndex(this.cssRules, [
|
|
136
|
+
'CSSLayerStatementRule',
|
|
137
|
+
'CSSImportRule',
|
|
138
|
+
'CSSNamespaceRule'
|
|
139
|
+
]);
|
|
140
|
+
|
|
141
|
+
if (index < firstNonSpecialRuleIndex) {
|
|
142
|
+
errorUtils.throwError(this, 'DOMException',
|
|
143
|
+
"Failed to execute 'insertRule' on '" + this.constructor.name + "': Failed to insert the rule.",
|
|
144
|
+
'HierarchyRequestError');
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
cssRule.__parentStyleSheet = this;
|
|
60
149
|
this.cssRules.splice(index, 0, cssRule);
|
|
61
150
|
return index;
|
|
62
151
|
};
|
|
@@ -77,21 +166,21 @@ CSSOM.CSSStyleSheet.prototype.insertRule = function(rule, index) {
|
|
|
77
166
|
*/
|
|
78
167
|
CSSOM.CSSStyleSheet.prototype.deleteRule = function(index) {
|
|
79
168
|
if (index === undefined) {
|
|
80
|
-
|
|
169
|
+
errorUtils.throwMissingArguments(this, 'deleteRule', this.constructor.name);
|
|
81
170
|
}
|
|
82
171
|
index = Number(index);
|
|
83
172
|
if (index < 0) {
|
|
84
173
|
index = 4294967296 + index;
|
|
85
174
|
}
|
|
86
175
|
if (index >= this.cssRules.length) {
|
|
87
|
-
|
|
176
|
+
errorUtils.throwIndexError(this, 'deleteRule', this.constructor.name, index, this.cssRules.length);
|
|
88
177
|
}
|
|
89
178
|
if (this.cssRules[index] && this.cssRules[index].constructor.name == "CSSNamespaceRule") {
|
|
90
179
|
var shouldContinue = this.cssRules.every(function (rule) {
|
|
91
180
|
return ['CSSImportRule','CSSLayerStatementRule','CSSNamespaceRule'].indexOf(rule.constructor.name) !== -1
|
|
92
181
|
});
|
|
93
182
|
if (!shouldContinue) {
|
|
94
|
-
|
|
183
|
+
errorUtils.throwError(this, 'DOMException', "Failed to execute 'deleteRule' on '" + this.constructor.name + "': Failed to delete rule.", "InvalidStateError");
|
|
95
184
|
}
|
|
96
185
|
}
|
|
97
186
|
this.cssRules.splice(index, 1);
|
package/lib/StyleSheet.js
CHANGED
|
@@ -8,9 +8,16 @@ var CSSOM = {};
|
|
|
8
8
|
* @see http://dev.w3.org/csswg/cssom/#the-stylesheet-interface
|
|
9
9
|
*/
|
|
10
10
|
CSSOM.StyleSheet = function StyleSheet() {
|
|
11
|
-
this.
|
|
11
|
+
this.__parentStyleSheet = null;
|
|
12
12
|
};
|
|
13
13
|
|
|
14
|
+
Object.defineProperties(CSSOM.StyleSheet.prototype, {
|
|
15
|
+
parentStyleSheet: {
|
|
16
|
+
get: function() {
|
|
17
|
+
return this.__parentStyleSheet;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
});
|
|
14
21
|
|
|
15
22
|
//.CommonJS
|
|
16
23
|
exports.StyleSheet = CSSOM.StyleSheet;
|
package/lib/clone.js
CHANGED
|
@@ -15,6 +15,12 @@ var CSSOM = {
|
|
|
15
15
|
CSSLayerBlockRule: require('./CSSLayerBlockRule').CSSLayerBlockRule,
|
|
16
16
|
CSSLayerStatementRule: require('./CSSLayerStatementRule').CSSLayerStatementRule
|
|
17
17
|
};
|
|
18
|
+
// Use cssstyle if available
|
|
19
|
+
try {
|
|
20
|
+
CSSOM.CSSStyleDeclaration = require("cssstyle").CSSStyleDeclaration;
|
|
21
|
+
} catch (e) {
|
|
22
|
+
// ignore
|
|
23
|
+
}
|
|
18
24
|
///CommonJS
|
|
19
25
|
|
|
20
26
|
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// Utility functions for CSSOM error handling
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Gets the appropriate error constructor from the global object context.
|
|
5
|
+
* Tries to find the error constructor from parentStyleSheet.__globalObject,
|
|
6
|
+
* then from __globalObject, then falls back to the native constructor.
|
|
7
|
+
*
|
|
8
|
+
* @param {Object} context - The CSSOM object (rule, stylesheet, etc.)
|
|
9
|
+
* @param {string} errorType - The error type ('TypeError', 'RangeError', 'DOMException', etc.)
|
|
10
|
+
* @return {Function} The error constructor
|
|
11
|
+
*/
|
|
12
|
+
function getErrorConstructor(context, errorType) {
|
|
13
|
+
// Try parentStyleSheet.__globalObject first
|
|
14
|
+
if (context.parentStyleSheet && context.parentStyleSheet.__globalObject && context.parentStyleSheet.__globalObject[errorType]) {
|
|
15
|
+
return context.parentStyleSheet.__globalObject[errorType];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Try __parentStyleSheet (alternative naming)
|
|
19
|
+
if (context.__parentStyleSheet && context.__parentStyleSheet.__globalObject && context.__parentStyleSheet.__globalObject[errorType]) {
|
|
20
|
+
return context.__parentStyleSheet.__globalObject[errorType];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Try __globalObject on the context itself
|
|
24
|
+
if (context.__globalObject && context.__globalObject[errorType]) {
|
|
25
|
+
return context.__globalObject[errorType];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Fall back to native constructor
|
|
29
|
+
return (typeof global !== 'undefined' && global[errorType]) ||
|
|
30
|
+
(typeof window !== 'undefined' && window[errorType]) ||
|
|
31
|
+
eval(errorType);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Creates and throws an appropriate error with context-aware constructor.
|
|
36
|
+
*
|
|
37
|
+
* @param {Object} context - The CSSOM object (rule, stylesheet, etc.)
|
|
38
|
+
* @param {string} errorType - The error type ('TypeError', 'RangeError', 'DOMException', etc.)
|
|
39
|
+
* @param {string} message - The error message
|
|
40
|
+
* @param {string} [name] - Optional name for DOMException
|
|
41
|
+
*/
|
|
42
|
+
function throwError(context, errorType, message, name) {
|
|
43
|
+
var ErrorConstructor = getErrorConstructor(context, errorType);
|
|
44
|
+
var error = new ErrorConstructor(message, name);
|
|
45
|
+
throw error;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Throws a TypeError for missing required arguments.
|
|
50
|
+
*
|
|
51
|
+
* @param {Object} context - The CSSOM object
|
|
52
|
+
* @param {string} methodName - The method name (e.g., 'appendRule')
|
|
53
|
+
* @param {string} objectName - The object name (e.g., 'CSSKeyframesRule')
|
|
54
|
+
* @param {number} [required=1] - Number of required arguments
|
|
55
|
+
* @param {number} [provided=0] - Number of provided arguments
|
|
56
|
+
*/
|
|
57
|
+
function throwMissingArguments(context, methodName, objectName, required, provided) {
|
|
58
|
+
required = required || 1;
|
|
59
|
+
provided = provided || 0;
|
|
60
|
+
var message = "Failed to execute '" + methodName + "' on '" + objectName + "': " +
|
|
61
|
+
required + " argument" + (required > 1 ? "s" : "") + " required, but only " +
|
|
62
|
+
provided + " present.";
|
|
63
|
+
throwError(context, 'TypeError', message);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Throws a DOMException for parse errors.
|
|
68
|
+
*
|
|
69
|
+
* @param {Object} context - The CSSOM object
|
|
70
|
+
* @param {string} methodName - The method name
|
|
71
|
+
* @param {string} objectName - The object name
|
|
72
|
+
* @param {string} rule - The rule that failed to parse
|
|
73
|
+
* @param {string} [name='SyntaxError'] - The DOMException name
|
|
74
|
+
*/
|
|
75
|
+
function throwParseError(context, methodName, objectName, rule, name) {
|
|
76
|
+
var message = "Failed to execute '" + methodName + "' on '" + objectName + "': " +
|
|
77
|
+
"Failed to parse the rule '" + rule + "'.";
|
|
78
|
+
throwError(context, 'DOMException', message, name || 'SyntaxError');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Throws a DOMException for index errors.
|
|
83
|
+
*
|
|
84
|
+
* @param {Object} context - The CSSOM object
|
|
85
|
+
* @param {string} methodName - The method name
|
|
86
|
+
* @param {string} objectName - The object name
|
|
87
|
+
* @param {number} index - The invalid index
|
|
88
|
+
* @param {number} maxIndex - The maximum valid index
|
|
89
|
+
* @param {string} [name='IndexSizeError'] - The DOMException name
|
|
90
|
+
*/
|
|
91
|
+
function throwIndexError(context, methodName, objectName, index, maxIndex, name) {
|
|
92
|
+
var message = "Failed to execute '" + methodName + "' on '" + objectName + "': " +
|
|
93
|
+
"The index provided (" + index + ") is larger than the maximum index (" + maxIndex + ").";
|
|
94
|
+
throwError(context, 'DOMException', message, name || 'IndexSizeError');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
var errorUtils = {
|
|
98
|
+
getErrorConstructor: getErrorConstructor,
|
|
99
|
+
throwError: throwError,
|
|
100
|
+
throwMissingArguments: throwMissingArguments,
|
|
101
|
+
throwParseError: throwParseError,
|
|
102
|
+
throwIndexError: throwIndexError
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
//.CommonJS
|
|
106
|
+
exports.errorUtils = errorUtils;
|
|
107
|
+
///CommonJS
|
package/lib/index.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
require('./errorUtils');
|
|
4
|
+
|
|
3
5
|
exports.CSSStyleDeclaration = require('./CSSStyleDeclaration').CSSStyleDeclaration;
|
|
6
|
+
|
|
7
|
+
require('./cssstyleTryCatchBlock');
|
|
8
|
+
|
|
4
9
|
exports.CSSRule = require('./CSSRule').CSSRule;
|
|
5
10
|
exports.CSSNestedDeclarations = require('./CSSNestedDeclarations').CSSNestedDeclarations;
|
|
6
11
|
exports.CSSGroupingRule = require('./CSSGroupingRule').CSSGroupingRule;
|
package/lib/parse.js
CHANGED
|
@@ -4,10 +4,16 @@ var CSSOM = {};
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* Parses a CSS string and returns a CSSOM.CSSStyleSheet object representing the parsed stylesheet.
|
|
8
|
+
*
|
|
9
|
+
* @param {string} token - The CSS string to parse.
|
|
10
|
+
* @param {object} [opts] - Optional parsing options.
|
|
11
|
+
* @param {object} [opts.globalObject] - An optional global object to attach to the stylesheet. Useful on jsdom webplatform tests.
|
|
12
|
+
* @param {function|boolean} [errorHandler] - Optional error handler function or `true` to use `console.error`.
|
|
13
|
+
* @returns {CSSOM.CSSStyleSheet} The parsed CSSStyleSheet object.
|
|
8
14
|
*/
|
|
9
|
-
CSSOM.parse = function parse(token, errorHandler) {
|
|
10
|
-
errorHandler = errorHandler ===
|
|
15
|
+
CSSOM.parse = function parse(token, opts, errorHandler) {
|
|
16
|
+
errorHandler = errorHandler === true ? (console && console.error) : errorHandler;
|
|
11
17
|
|
|
12
18
|
var i = 0;
|
|
13
19
|
|
|
@@ -49,6 +55,10 @@ CSSOM.parse = function parse(token, errorHandler) {
|
|
|
49
55
|
|
|
50
56
|
var styleSheet = new CSSOM.CSSStyleSheet();
|
|
51
57
|
|
|
58
|
+
if (opts && opts.globalObject) {
|
|
59
|
+
styleSheet.__globalObject = opts.globalObject;
|
|
60
|
+
}
|
|
61
|
+
|
|
52
62
|
// @type CSSStyleSheet|CSSMediaRule|CSSContainerRule|CSSSupportsRule|CSSFontFaceRule|CSSKeyframesRule|CSSDocumentRule
|
|
53
63
|
var currentScope = styleSheet;
|
|
54
64
|
|
|
@@ -746,7 +756,7 @@ CSSOM.parse = function parse(token, errorHandler) {
|
|
|
746
756
|
i += "font-face".length;
|
|
747
757
|
fontFaceRule = new CSSOM.CSSFontFaceRule();
|
|
748
758
|
fontFaceRule.__starts = i;
|
|
749
|
-
},
|
|
759
|
+
}, true);
|
|
750
760
|
break;
|
|
751
761
|
} else {
|
|
752
762
|
atKeyframesRegExp.lastIndex = i;
|
|
@@ -788,7 +798,7 @@ CSSOM.parse = function parse(token, errorHandler) {
|
|
|
788
798
|
}
|
|
789
799
|
|
|
790
800
|
if (parentRule) {
|
|
791
|
-
styleRule.
|
|
801
|
+
styleRule.__parentRule = parentRule;
|
|
792
802
|
ancestorRules.push(parentRule);
|
|
793
803
|
}
|
|
794
804
|
|
|
@@ -798,48 +808,48 @@ CSSOM.parse = function parse(token, errorHandler) {
|
|
|
798
808
|
return match;
|
|
799
809
|
});
|
|
800
810
|
styleRule.style.__starts = i;
|
|
801
|
-
styleRule.
|
|
811
|
+
styleRule.__parentStyleSheet = styleSheet;
|
|
802
812
|
buffer = "";
|
|
803
813
|
state = "before-name";
|
|
804
814
|
} else if (state === "atBlock") {
|
|
805
815
|
mediaRule.media.mediaText = buffer.trim();
|
|
806
816
|
|
|
807
817
|
if (parentRule) {
|
|
808
|
-
mediaRule.
|
|
818
|
+
mediaRule.__parentRule = parentRule;
|
|
809
819
|
ancestorRules.push(parentRule);
|
|
810
820
|
}
|
|
811
821
|
|
|
812
822
|
currentScope = parentRule = mediaRule;
|
|
813
|
-
mediaRule.
|
|
823
|
+
mediaRule.__parentStyleSheet = styleSheet;
|
|
814
824
|
buffer = "";
|
|
815
825
|
state = "before-selector";
|
|
816
826
|
} else if (state === "containerBlock") {
|
|
817
827
|
containerRule.containerText = buffer.trim();
|
|
818
828
|
|
|
819
829
|
if (parentRule) {
|
|
820
|
-
containerRule.
|
|
830
|
+
containerRule.__parentRule = parentRule;
|
|
821
831
|
ancestorRules.push(parentRule);
|
|
822
832
|
}
|
|
823
833
|
currentScope = parentRule = containerRule;
|
|
824
|
-
containerRule.
|
|
834
|
+
containerRule.__parentStyleSheet = styleSheet;
|
|
825
835
|
buffer = "";
|
|
826
836
|
state = "before-selector";
|
|
827
837
|
} else if (state === "counterStyleBlock") {
|
|
828
838
|
// TODO: Validate counter-style name. At least that it cannot be empty nor multiple
|
|
829
839
|
counterStyleRule.name = buffer.trim().replace(/\n/g, "");
|
|
830
840
|
currentScope = parentRule = counterStyleRule;
|
|
831
|
-
counterStyleRule.
|
|
841
|
+
counterStyleRule.__parentStyleSheet = styleSheet;
|
|
832
842
|
buffer = "";
|
|
833
843
|
} else if (state === "conditionBlock") {
|
|
834
844
|
supportsRule.conditionText = buffer.trim();
|
|
835
845
|
|
|
836
846
|
if (parentRule) {
|
|
837
|
-
supportsRule.
|
|
847
|
+
supportsRule.__parentRule = parentRule;
|
|
838
848
|
ancestorRules.push(parentRule);
|
|
839
849
|
}
|
|
840
850
|
|
|
841
851
|
currentScope = parentRule = supportsRule;
|
|
842
|
-
supportsRule.
|
|
852
|
+
supportsRule.__parentStyleSheet = styleSheet;
|
|
843
853
|
buffer = "";
|
|
844
854
|
state = "before-selector";
|
|
845
855
|
} else if (state === "layerBlock") {
|
|
@@ -849,12 +859,12 @@ CSSOM.parse = function parse(token, errorHandler) {
|
|
|
849
859
|
|
|
850
860
|
if (isValidName) {
|
|
851
861
|
if (parentRule) {
|
|
852
|
-
layerBlockRule.
|
|
862
|
+
layerBlockRule.__parentRule = parentRule;
|
|
853
863
|
ancestorRules.push(parentRule);
|
|
854
864
|
}
|
|
855
865
|
|
|
856
866
|
currentScope = parentRule = layerBlockRule;
|
|
857
|
-
layerBlockRule.
|
|
867
|
+
layerBlockRule.__parentStyleSheet = styleSheet;
|
|
858
868
|
}
|
|
859
869
|
buffer = "";
|
|
860
870
|
state = "before-selector";
|
|
@@ -864,25 +874,25 @@ CSSOM.parse = function parse(token, errorHandler) {
|
|
|
864
874
|
}
|
|
865
875
|
|
|
866
876
|
currentScope = parentRule = hostRule;
|
|
867
|
-
hostRule.
|
|
877
|
+
hostRule.__parentStyleSheet = styleSheet;
|
|
868
878
|
buffer = "";
|
|
869
879
|
state = "before-selector";
|
|
870
880
|
} else if (state === "startingStyleRule-begin") {
|
|
871
881
|
if (parentRule) {
|
|
872
|
-
startingStyleRule.
|
|
882
|
+
startingStyleRule.__parentRule = parentRule;
|
|
873
883
|
ancestorRules.push(parentRule);
|
|
874
884
|
}
|
|
875
885
|
|
|
876
886
|
currentScope = parentRule = startingStyleRule;
|
|
877
|
-
startingStyleRule.
|
|
887
|
+
startingStyleRule.__parentStyleSheet = styleSheet;
|
|
878
888
|
buffer = "";
|
|
879
889
|
state = "before-selector";
|
|
880
890
|
|
|
881
891
|
} else if (state === "fontFaceRule-begin") {
|
|
882
892
|
if (parentRule) {
|
|
883
|
-
fontFaceRule.
|
|
893
|
+
fontFaceRule.__parentRule = parentRule;
|
|
884
894
|
}
|
|
885
|
-
fontFaceRule.
|
|
895
|
+
fontFaceRule.__parentStyleSheet = styleSheet;
|
|
886
896
|
styleRule = fontFaceRule;
|
|
887
897
|
buffer = "";
|
|
888
898
|
state = "before-name";
|
|
@@ -890,9 +900,9 @@ CSSOM.parse = function parse(token, errorHandler) {
|
|
|
890
900
|
keyframesRule.name = buffer.trim();
|
|
891
901
|
if (parentRule) {
|
|
892
902
|
ancestorRules.push(parentRule);
|
|
893
|
-
keyframesRule.
|
|
903
|
+
keyframesRule.__parentRule = parentRule;
|
|
894
904
|
}
|
|
895
|
-
keyframesRule.
|
|
905
|
+
keyframesRule.__parentStyleSheet = styleSheet;
|
|
896
906
|
currentScope = parentRule = keyframesRule;
|
|
897
907
|
buffer = "";
|
|
898
908
|
state = "keyframeRule-begin";
|
|
@@ -907,18 +917,18 @@ CSSOM.parse = function parse(token, errorHandler) {
|
|
|
907
917
|
documentRule.matcher.matcherText = buffer.trim();
|
|
908
918
|
if (parentRule) {
|
|
909
919
|
ancestorRules.push(parentRule);
|
|
910
|
-
documentRule.
|
|
920
|
+
documentRule.__parentRule = parentRule;
|
|
911
921
|
}
|
|
912
922
|
currentScope = parentRule = documentRule;
|
|
913
|
-
documentRule.
|
|
923
|
+
documentRule.__parentStyleSheet = styleSheet;
|
|
914
924
|
buffer = "";
|
|
915
925
|
state = "before-selector";
|
|
916
926
|
} else if (state === "before-name" || state === "name") {
|
|
917
927
|
if (styleRule.constructor.name === "CSSNestedDeclarations") {
|
|
918
928
|
if (styleRule.style.length) {
|
|
919
929
|
parentRule.cssRules.push(styleRule);
|
|
920
|
-
styleRule.
|
|
921
|
-
styleRule.
|
|
930
|
+
styleRule.__parentRule = parentRule;
|
|
931
|
+
styleRule.__parentStyleSheet = styleSheet;
|
|
922
932
|
ancestorRules.push(parentRule);
|
|
923
933
|
} else {
|
|
924
934
|
// If the styleRule is empty, we can assume that it's a nested selector
|
|
@@ -927,7 +937,7 @@ CSSOM.parse = function parse(token, errorHandler) {
|
|
|
927
937
|
} else {
|
|
928
938
|
currentScope = parentRule = styleRule;
|
|
929
939
|
ancestorRules.push(parentRule);
|
|
930
|
-
styleRule.
|
|
940
|
+
styleRule.__parentStyleSheet = styleSheet;
|
|
931
941
|
}
|
|
932
942
|
|
|
933
943
|
styleRule = new CSSOM.CSSStyleRule();
|
|
@@ -944,7 +954,7 @@ CSSOM.parse = function parse(token, errorHandler) {
|
|
|
944
954
|
}).join(', ');
|
|
945
955
|
}
|
|
946
956
|
styleRule.style.__starts = i - buffer.length;
|
|
947
|
-
styleRule.
|
|
957
|
+
styleRule.__parentRule = parentRule;
|
|
948
958
|
nestedSelectorRule = styleRule;
|
|
949
959
|
|
|
950
960
|
buffer = "";
|
|
@@ -1039,7 +1049,7 @@ CSSOM.parse = function parse(token, errorHandler) {
|
|
|
1039
1049
|
});
|
|
1040
1050
|
if (isValid) {
|
|
1041
1051
|
importRule = new CSSOM.CSSImportRule();
|
|
1042
|
-
importRule.
|
|
1052
|
+
importRule.__parentStyleSheet = importRule.styleSheet.__parentStyleSheet = styleSheet;
|
|
1043
1053
|
importRule.cssText = buffer + character;
|
|
1044
1054
|
styleSheet.cssRules.push(importRule);
|
|
1045
1055
|
}
|
|
@@ -1057,7 +1067,7 @@ CSSOM.parse = function parse(token, errorHandler) {
|
|
|
1057
1067
|
testNamespaceRule.cssText = buffer + character;
|
|
1058
1068
|
|
|
1059
1069
|
namespaceRule = testNamespaceRule;
|
|
1060
|
-
namespaceRule.
|
|
1070
|
+
namespaceRule.__parentStyleSheet = namespaceRule.styleSheet.__parentStyleSheet = styleSheet;
|
|
1061
1071
|
styleSheet.cssRules.push(namespaceRule);
|
|
1062
1072
|
|
|
1063
1073
|
// Track the namespace prefix for validation
|
|
@@ -1081,7 +1091,7 @@ CSSOM.parse = function parse(token, errorHandler) {
|
|
|
1081
1091
|
|
|
1082
1092
|
if (!isInvalid) {
|
|
1083
1093
|
layerStatementRule = new CSSOM.CSSLayerStatementRule();
|
|
1084
|
-
layerStatementRule.
|
|
1094
|
+
layerStatementRule.__parentStyleSheet = styleSheet;
|
|
1085
1095
|
layerStatementRule.__starts = layerBlockRule.__starts;
|
|
1086
1096
|
layerStatementRule.__ends = i;
|
|
1087
1097
|
layerStatementRule.nameList = nameListStr;
|
|
@@ -1121,9 +1131,9 @@ CSSOM.parse = function parse(token, errorHandler) {
|
|
|
1121
1131
|
}
|
|
1122
1132
|
|
|
1123
1133
|
if (parentRule) {
|
|
1124
|
-
styleRule.
|
|
1134
|
+
styleRule.__parentRule = parentRule;
|
|
1125
1135
|
}
|
|
1126
|
-
styleRule.
|
|
1136
|
+
styleRule.__parentStyleSheet = styleSheet;
|
|
1127
1137
|
|
|
1128
1138
|
if (currentScope === styleRule) {
|
|
1129
1139
|
currentScope = parentRule || styleSheet;
|
|
@@ -1249,7 +1259,7 @@ CSSOM.parse = function parse(token, errorHandler) {
|
|
|
1249
1259
|
|| parentRule.constructor.name === "CSSLayerBlockRule"
|
|
1250
1260
|
|| parentRule.constructor.name === "CSSStartingStyleRule"
|
|
1251
1261
|
) {
|
|
1252
|
-
// parentRule.
|
|
1262
|
+
// parentRule.__parentRule = styleRule;
|
|
1253
1263
|
state = "before-name";
|
|
1254
1264
|
if (styleRule !== parentRule) {
|
|
1255
1265
|
styleRule = new CSSOM.CSSNestedDeclarations();
|
|
@@ -1329,4 +1339,10 @@ CSSOM.CSSValueExpression = require('./CSSValueExpression').CSSValueExpression;
|
|
|
1329
1339
|
CSSOM.CSSDocumentRule = require('./CSSDocumentRule').CSSDocumentRule;
|
|
1330
1340
|
CSSOM.CSSLayerBlockRule = require("./CSSLayerBlockRule").CSSLayerBlockRule;
|
|
1331
1341
|
CSSOM.CSSLayerStatementRule = require("./CSSLayerStatementRule").CSSLayerStatementRule;
|
|
1342
|
+
// Use cssstyle if available
|
|
1343
|
+
try {
|
|
1344
|
+
CSSOM.CSSStyleDeclaration = require("cssstyle").CSSStyleDeclaration;
|
|
1345
|
+
} catch (e) {
|
|
1346
|
+
// ignore
|
|
1347
|
+
}
|
|
1332
1348
|
///CommonJS
|