@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.
@@ -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
- throw new (this._globalObject && this._globalObject.TypeError || TypeError)("Failed to execute 'insertRule' on 'CSSStyleSheet': 1 argument required, but only 0 present.")
42
+ errorUtils.throwMissingArguments(this, 'insertRule', this.constructor.name);
42
43
  }
43
44
  if (index === void 0) {
44
45
  index = 0;
45
46
  }
46
- if (index < 0 || index > this.cssRules.length) {
47
- throw new (this._globalObject && this._globalObject.RangeError || RangeError)("INDEX_SIZE_ERR");
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
- var domExceptionName = "SyntaxError";
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
- cssRule.parentStyleSheet = this;
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
- throw new (this._globalObject && this._globalObject.TypeError || TypeError)("Failed to execute 'deleteRule' on 'CSSStyleSheet': 1 argument required, but only 0 present.")
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
- throw new (this._globalObject && this._globalObject.DOMException || DOMException)("Failed to execute 'deleteRule' on 'CSSStyleSheet': The index provided (" + index + ") is larger than the maximum index (" + this.cssRules.length + ").", "IndexSizeError");
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
- throw new (this._globalObject && this._globalObject.DOMException || DOMException)("Failed to execute 'deleteRule' on 'CSSStyleSheet': Deleting a CSSNamespaceRule is not allowed when there is rules other than @import, @layer statement, or @namespace.", "InvalidStateError");
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.parentStyleSheet = null;
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,5 @@
1
+ try {
2
+ CSSOM.CSSStyleDeclaration = require("cssstyle").CSSStyleDeclaration;
3
+ } catch (e) {
4
+ // ignore
5
+ }
@@ -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
- * @param {string} token
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 === undefined ? (console && console.error) : 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
- }, parentRule && parentRule.constructor.name === "CSSStyleRule" );
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.parentRule = parentRule;
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.parentStyleSheet = styleSheet;
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.parentRule = parentRule;
818
+ mediaRule.__parentRule = parentRule;
809
819
  ancestorRules.push(parentRule);
810
820
  }
811
821
 
812
822
  currentScope = parentRule = mediaRule;
813
- mediaRule.parentStyleSheet = styleSheet;
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.parentRule = parentRule;
830
+ containerRule.__parentRule = parentRule;
821
831
  ancestorRules.push(parentRule);
822
832
  }
823
833
  currentScope = parentRule = containerRule;
824
- containerRule.parentStyleSheet = styleSheet;
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.parentStyleSheet = styleSheet;
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.parentRule = parentRule;
847
+ supportsRule.__parentRule = parentRule;
838
848
  ancestorRules.push(parentRule);
839
849
  }
840
850
 
841
851
  currentScope = parentRule = supportsRule;
842
- supportsRule.parentStyleSheet = styleSheet;
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.parentRule = parentRule;
862
+ layerBlockRule.__parentRule = parentRule;
853
863
  ancestorRules.push(parentRule);
854
864
  }
855
865
 
856
866
  currentScope = parentRule = layerBlockRule;
857
- layerBlockRule.parentStyleSheet = styleSheet;
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.parentStyleSheet = styleSheet;
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.parentRule = parentRule;
882
+ startingStyleRule.__parentRule = parentRule;
873
883
  ancestorRules.push(parentRule);
874
884
  }
875
885
 
876
886
  currentScope = parentRule = startingStyleRule;
877
- startingStyleRule.parentStyleSheet = styleSheet;
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.parentRule = parentRule;
893
+ fontFaceRule.__parentRule = parentRule;
884
894
  }
885
- fontFaceRule.parentStyleSheet = styleSheet;
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.parentRule = parentRule;
903
+ keyframesRule.__parentRule = parentRule;
894
904
  }
895
- keyframesRule.parentStyleSheet = styleSheet;
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.parentRule = parentRule;
920
+ documentRule.__parentRule = parentRule;
911
921
  }
912
922
  currentScope = parentRule = documentRule;
913
- documentRule.parentStyleSheet = styleSheet;
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.parentRule = parentRule;
921
- styleRule.parentStyleSheet = styleSheet;
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.parentStyleSheet = styleSheet;
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.parentRule = parentRule;
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.parentStyleSheet = importRule.styleSheet.parentStyleSheet = styleSheet;
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.parentStyleSheet = namespaceRule.styleSheet.parentStyleSheet = styleSheet;
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.parentStyleSheet = styleSheet;
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.parentRule = parentRule;
1134
+ styleRule.__parentRule = parentRule;
1125
1135
  }
1126
- styleRule.parentStyleSheet = styleSheet;
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.parentRule = styleRule;
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
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "parser",
8
8
  "styleSheet"
9
9
  ],
10
- "version": "0.9.16",
10
+ "version": "0.9.18",
11
11
  "author": "Nikita Vasilyev <me@elv1s.ru>",
12
12
  "contributors": [
13
13
  "Acemir Sousa Mendes <acemirsm@gmail.com>"