@acemir/cssom 0.9.15 → 0.9.17

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.
@@ -0,0 +1,118 @@
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 RangeError for index out of bounds.
68
+ *
69
+ * @param {Object} context - The CSSOM object
70
+ * @param {string} [message] - Optional custom message, defaults to 'INDEX_SIZE_ERR'
71
+ */
72
+ function throwIndexSizeError(context, message) {
73
+ throwError(context, 'RangeError', message || 'INDEX_SIZE_ERR');
74
+ }
75
+
76
+ /**
77
+ * Throws a DOMException for parse errors.
78
+ *
79
+ * @param {Object} context - The CSSOM object
80
+ * @param {string} methodName - The method name
81
+ * @param {string} objectName - The object name
82
+ * @param {string} rule - The rule that failed to parse
83
+ * @param {string} [name='SyntaxError'] - The DOMException name
84
+ */
85
+ function throwParseError(context, methodName, objectName, rule, name) {
86
+ var message = "Failed to execute '" + methodName + "' on '" + objectName + "': " +
87
+ "Failed to parse the rule '" + rule + "'.";
88
+ throwError(context, 'DOMException', message, name || 'SyntaxError');
89
+ }
90
+
91
+ /**
92
+ * Throws a DOMException for index errors.
93
+ *
94
+ * @param {Object} context - The CSSOM object
95
+ * @param {string} methodName - The method name
96
+ * @param {string} objectName - The object name
97
+ * @param {number} index - The invalid index
98
+ * @param {number} maxIndex - The maximum valid index
99
+ * @param {string} [name='IndexSizeError'] - The DOMException name
100
+ */
101
+ function throwIndexError(context, methodName, objectName, index, maxIndex, name) {
102
+ var message = "Failed to execute '" + methodName + "' on '" + objectName + "': " +
103
+ "The index provided (" + index + ") is larger than the maximum index (" + maxIndex + ").";
104
+ throwError(context, 'DOMException', message, name || 'IndexSizeError');
105
+ }
106
+
107
+ var errorUtils = {
108
+ getErrorConstructor: getErrorConstructor,
109
+ throwError: throwError,
110
+ throwMissingArguments: throwMissingArguments,
111
+ throwIndexSizeError: throwIndexSizeError,
112
+ throwParseError: throwParseError,
113
+ throwIndexError: throwIndexError
114
+ };
115
+
116
+ //.CommonJS
117
+ exports.errorUtils = errorUtils;
118
+ ///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
@@ -788,7 +788,7 @@ CSSOM.parse = function parse(token, errorHandler) {
788
788
  }
789
789
 
790
790
  if (parentRule) {
791
- styleRule.parentRule = parentRule;
791
+ styleRule.__parentRule = parentRule;
792
792
  ancestorRules.push(parentRule);
793
793
  }
794
794
 
@@ -798,48 +798,48 @@ CSSOM.parse = function parse(token, errorHandler) {
798
798
  return match;
799
799
  });
800
800
  styleRule.style.__starts = i;
801
- styleRule.parentStyleSheet = styleSheet;
801
+ styleRule.__parentStyleSheet = styleSheet;
802
802
  buffer = "";
803
803
  state = "before-name";
804
804
  } else if (state === "atBlock") {
805
805
  mediaRule.media.mediaText = buffer.trim();
806
806
 
807
807
  if (parentRule) {
808
- mediaRule.parentRule = parentRule;
808
+ mediaRule.__parentRule = parentRule;
809
809
  ancestorRules.push(parentRule);
810
810
  }
811
811
 
812
812
  currentScope = parentRule = mediaRule;
813
- mediaRule.parentStyleSheet = styleSheet;
813
+ mediaRule.__parentStyleSheet = styleSheet;
814
814
  buffer = "";
815
815
  state = "before-selector";
816
816
  } else if (state === "containerBlock") {
817
817
  containerRule.containerText = buffer.trim();
818
818
 
819
819
  if (parentRule) {
820
- containerRule.parentRule = parentRule;
820
+ containerRule.__parentRule = parentRule;
821
821
  ancestorRules.push(parentRule);
822
822
  }
823
823
  currentScope = parentRule = containerRule;
824
- containerRule.parentStyleSheet = styleSheet;
824
+ containerRule.__parentStyleSheet = styleSheet;
825
825
  buffer = "";
826
826
  state = "before-selector";
827
827
  } else if (state === "counterStyleBlock") {
828
828
  // TODO: Validate counter-style name. At least that it cannot be empty nor multiple
829
829
  counterStyleRule.name = buffer.trim().replace(/\n/g, "");
830
830
  currentScope = parentRule = counterStyleRule;
831
- counterStyleRule.parentStyleSheet = styleSheet;
831
+ counterStyleRule.__parentStyleSheet = styleSheet;
832
832
  buffer = "";
833
833
  } else if (state === "conditionBlock") {
834
834
  supportsRule.conditionText = buffer.trim();
835
835
 
836
836
  if (parentRule) {
837
- supportsRule.parentRule = parentRule;
837
+ supportsRule.__parentRule = parentRule;
838
838
  ancestorRules.push(parentRule);
839
839
  }
840
840
 
841
841
  currentScope = parentRule = supportsRule;
842
- supportsRule.parentStyleSheet = styleSheet;
842
+ supportsRule.__parentStyleSheet = styleSheet;
843
843
  buffer = "";
844
844
  state = "before-selector";
845
845
  } else if (state === "layerBlock") {
@@ -849,12 +849,12 @@ CSSOM.parse = function parse(token, errorHandler) {
849
849
 
850
850
  if (isValidName) {
851
851
  if (parentRule) {
852
- layerBlockRule.parentRule = parentRule;
852
+ layerBlockRule.__parentRule = parentRule;
853
853
  ancestorRules.push(parentRule);
854
854
  }
855
855
 
856
856
  currentScope = parentRule = layerBlockRule;
857
- layerBlockRule.parentStyleSheet = styleSheet;
857
+ layerBlockRule.__parentStyleSheet = styleSheet;
858
858
  }
859
859
  buffer = "";
860
860
  state = "before-selector";
@@ -864,25 +864,25 @@ CSSOM.parse = function parse(token, errorHandler) {
864
864
  }
865
865
 
866
866
  currentScope = parentRule = hostRule;
867
- hostRule.parentStyleSheet = styleSheet;
867
+ hostRule.__parentStyleSheet = styleSheet;
868
868
  buffer = "";
869
869
  state = "before-selector";
870
870
  } else if (state === "startingStyleRule-begin") {
871
871
  if (parentRule) {
872
- startingStyleRule.parentRule = parentRule;
872
+ startingStyleRule.__parentRule = parentRule;
873
873
  ancestorRules.push(parentRule);
874
874
  }
875
875
 
876
876
  currentScope = parentRule = startingStyleRule;
877
- startingStyleRule.parentStyleSheet = styleSheet;
877
+ startingStyleRule.__parentStyleSheet = styleSheet;
878
878
  buffer = "";
879
879
  state = "before-selector";
880
880
 
881
881
  } else if (state === "fontFaceRule-begin") {
882
882
  if (parentRule) {
883
- fontFaceRule.parentRule = parentRule;
883
+ fontFaceRule.__parentRule = parentRule;
884
884
  }
885
- fontFaceRule.parentStyleSheet = styleSheet;
885
+ fontFaceRule.__parentStyleSheet = styleSheet;
886
886
  styleRule = fontFaceRule;
887
887
  buffer = "";
888
888
  state = "before-name";
@@ -890,9 +890,9 @@ CSSOM.parse = function parse(token, errorHandler) {
890
890
  keyframesRule.name = buffer.trim();
891
891
  if (parentRule) {
892
892
  ancestorRules.push(parentRule);
893
- keyframesRule.parentRule = parentRule;
893
+ keyframesRule.__parentRule = parentRule;
894
894
  }
895
- keyframesRule.parentStyleSheet = styleSheet;
895
+ keyframesRule.__parentStyleSheet = styleSheet;
896
896
  currentScope = parentRule = keyframesRule;
897
897
  buffer = "";
898
898
  state = "keyframeRule-begin";
@@ -907,18 +907,18 @@ CSSOM.parse = function parse(token, errorHandler) {
907
907
  documentRule.matcher.matcherText = buffer.trim();
908
908
  if (parentRule) {
909
909
  ancestorRules.push(parentRule);
910
- documentRule.parentRule = parentRule;
910
+ documentRule.__parentRule = parentRule;
911
911
  }
912
912
  currentScope = parentRule = documentRule;
913
- documentRule.parentStyleSheet = styleSheet;
913
+ documentRule.__parentStyleSheet = styleSheet;
914
914
  buffer = "";
915
915
  state = "before-selector";
916
916
  } else if (state === "before-name" || state === "name") {
917
917
  if (styleRule.constructor.name === "CSSNestedDeclarations") {
918
918
  if (styleRule.style.length) {
919
919
  parentRule.cssRules.push(styleRule);
920
- styleRule.parentRule = parentRule;
921
- styleRule.parentStyleSheet = styleSheet;
920
+ styleRule.__parentRule = parentRule;
921
+ styleRule.__parentStyleSheet = styleSheet;
922
922
  ancestorRules.push(parentRule);
923
923
  } else {
924
924
  // If the styleRule is empty, we can assume that it's a nested selector
@@ -927,7 +927,7 @@ CSSOM.parse = function parse(token, errorHandler) {
927
927
  } else {
928
928
  currentScope = parentRule = styleRule;
929
929
  ancestorRules.push(parentRule);
930
- styleRule.parentStyleSheet = styleSheet;
930
+ styleRule.__parentStyleSheet = styleSheet;
931
931
  }
932
932
 
933
933
  styleRule = new CSSOM.CSSStyleRule();
@@ -944,7 +944,7 @@ CSSOM.parse = function parse(token, errorHandler) {
944
944
  }).join(', ');
945
945
  }
946
946
  styleRule.style.__starts = i - buffer.length;
947
- styleRule.parentRule = parentRule;
947
+ styleRule.__parentRule = parentRule;
948
948
  nestedSelectorRule = styleRule;
949
949
 
950
950
  buffer = "";
@@ -1039,7 +1039,7 @@ CSSOM.parse = function parse(token, errorHandler) {
1039
1039
  });
1040
1040
  if (isValid) {
1041
1041
  importRule = new CSSOM.CSSImportRule();
1042
- importRule.parentStyleSheet = importRule.styleSheet.parentStyleSheet = styleSheet;
1042
+ importRule.__parentStyleSheet = importRule.styleSheet.__parentStyleSheet = styleSheet;
1043
1043
  importRule.cssText = buffer + character;
1044
1044
  styleSheet.cssRules.push(importRule);
1045
1045
  }
@@ -1057,7 +1057,7 @@ CSSOM.parse = function parse(token, errorHandler) {
1057
1057
  testNamespaceRule.cssText = buffer + character;
1058
1058
 
1059
1059
  namespaceRule = testNamespaceRule;
1060
- namespaceRule.parentStyleSheet = namespaceRule.styleSheet.parentStyleSheet = styleSheet;
1060
+ namespaceRule.__parentStyleSheet = namespaceRule.styleSheet.__parentStyleSheet = styleSheet;
1061
1061
  styleSheet.cssRules.push(namespaceRule);
1062
1062
 
1063
1063
  // Track the namespace prefix for validation
@@ -1081,7 +1081,7 @@ CSSOM.parse = function parse(token, errorHandler) {
1081
1081
 
1082
1082
  if (!isInvalid) {
1083
1083
  layerStatementRule = new CSSOM.CSSLayerStatementRule();
1084
- layerStatementRule.parentStyleSheet = styleSheet;
1084
+ layerStatementRule.__parentStyleSheet = styleSheet;
1085
1085
  layerStatementRule.__starts = layerBlockRule.__starts;
1086
1086
  layerStatementRule.__ends = i;
1087
1087
  layerStatementRule.nameList = nameListStr;
@@ -1121,9 +1121,9 @@ CSSOM.parse = function parse(token, errorHandler) {
1121
1121
  }
1122
1122
 
1123
1123
  if (parentRule) {
1124
- styleRule.parentRule = parentRule;
1124
+ styleRule.__parentRule = parentRule;
1125
1125
  }
1126
- styleRule.parentStyleSheet = styleSheet;
1126
+ styleRule.__parentStyleSheet = styleSheet;
1127
1127
 
1128
1128
  if (currentScope === styleRule) {
1129
1129
  currentScope = parentRule || styleSheet;
@@ -1249,7 +1249,7 @@ CSSOM.parse = function parse(token, errorHandler) {
1249
1249
  || parentRule.constructor.name === "CSSLayerBlockRule"
1250
1250
  || parentRule.constructor.name === "CSSStartingStyleRule"
1251
1251
  ) {
1252
- // parentRule.parentRule = styleRule;
1252
+ // parentRule.__parentRule = styleRule;
1253
1253
  state = "before-name";
1254
1254
  if (styleRule !== parentRule) {
1255
1255
  styleRule = new CSSOM.CSSNestedDeclarations();
@@ -1329,4 +1329,10 @@ CSSOM.CSSValueExpression = require('./CSSValueExpression').CSSValueExpression;
1329
1329
  CSSOM.CSSDocumentRule = require('./CSSDocumentRule').CSSDocumentRule;
1330
1330
  CSSOM.CSSLayerBlockRule = require("./CSSLayerBlockRule").CSSLayerBlockRule;
1331
1331
  CSSOM.CSSLayerStatementRule = require("./CSSLayerStatementRule").CSSLayerStatementRule;
1332
+ // Use cssstyle if available
1333
+ try {
1334
+ CSSOM.CSSStyleDeclaration = require("cssstyle").CSSStyleDeclaration;
1335
+ } catch (e) {
1336
+ // ignore
1337
+ }
1332
1338
  ///CommonJS
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "parser",
8
8
  "styleSheet"
9
9
  ],
10
- "version": "0.9.15",
10
+ "version": "0.9.17",
11
11
  "author": "Nikita Vasilyev <me@elv1s.ru>",
12
12
  "contributors": [
13
13
  "Acemir Sousa Mendes <acemirsm@gmail.com>"