@acemir/cssom 0.9.13 → 0.9.15
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 +42 -6
- package/lib/CSSStyleSheet.js +4 -4
- package/lib/parse.js +38 -2
- package/package.json +1 -1
package/build/CSSOM.js
CHANGED
|
@@ -1049,9 +1049,9 @@ CSSOM.CSSStyleSheet.prototype.insertRule = function(rule, index) {
|
|
|
1049
1049
|
var ruleToParse = String(rule);
|
|
1050
1050
|
var parsedSheet = CSSOM.parse(ruleToParse);
|
|
1051
1051
|
if (parsedSheet.cssRules.length !== 1) {
|
|
1052
|
-
var domExceptionName =
|
|
1052
|
+
var domExceptionName = "SyntaxError";
|
|
1053
1053
|
if (ruleToParse.trimStart().startsWith('@namespace')) {
|
|
1054
|
-
domExceptionName =
|
|
1054
|
+
domExceptionName = "InvalidStateError";
|
|
1055
1055
|
}
|
|
1056
1056
|
throw new DOMException("Failed to execute 'insertRule' on 'CSSStyleSheet': Failed to parse the rule '" + ruleToParse + "'.", domExceptionName);
|
|
1057
1057
|
}
|
|
@@ -1084,14 +1084,14 @@ CSSOM.CSSStyleSheet.prototype.deleteRule = function(index) {
|
|
|
1084
1084
|
index = 4294967296 + index;
|
|
1085
1085
|
}
|
|
1086
1086
|
if (index >= this.cssRules.length) {
|
|
1087
|
-
throw new DOMException("Failed to execute 'deleteRule' on 'CSSStyleSheet': The index provided (" + index + ") is larger than the maximum index (" + this.cssRules.length + ").",
|
|
1087
|
+
throw new DOMException("Failed to execute 'deleteRule' on 'CSSStyleSheet': The index provided (" + index + ") is larger than the maximum index (" + this.cssRules.length + ").", "IndexSizeError");
|
|
1088
1088
|
}
|
|
1089
1089
|
if (this.cssRules[index] && this.cssRules[index].constructor.name == "CSSNamespaceRule") {
|
|
1090
1090
|
var shouldContinue = this.cssRules.every(function (rule) {
|
|
1091
1091
|
return ['CSSImportRule','CSSLayerStatementRule','CSSNamespaceRule'].indexOf(rule.constructor.name) !== -1
|
|
1092
1092
|
});
|
|
1093
1093
|
if (!shouldContinue) {
|
|
1094
|
-
throw new DOMException("Failed to execute 'deleteRule' on 'CSSStyleSheet': Deleting a CSSNamespaceRule is not allowed when there is rules other than @import, @layer statement, or @namespace.",
|
|
1094
|
+
throw new 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");
|
|
1095
1095
|
}
|
|
1096
1096
|
}
|
|
1097
1097
|
this.cssRules.splice(index, 1);
|
|
@@ -1987,7 +1987,8 @@ CSSOM.parse = function parse(token, errorHandler) {
|
|
|
1987
1987
|
// Fallback to a loose regexp for the overall selector structure (without deep paren matching)
|
|
1988
1988
|
// This is similar to the original, but without nested paren limitations
|
|
1989
1989
|
// Modified to support namespace selectors: *|element, prefix|element, |element
|
|
1990
|
-
|
|
1990
|
+
// Fixed attribute selector regex to properly handle |=, ~=, ^=, $=, *= operators
|
|
1991
|
+
var looseSelectorRegExp = /^((?:(?:\*|[a-zA-Z_\u00A0-\uFFFF\\][a-zA-Z0-9_\u00A0-\uFFFF\-\\]*|)\|)?[a-zA-Z_\u00A0-\uFFFF\\][a-zA-Z0-9_\u00A0-\uFFFF\-\\]*|(?:(?:\*|[a-zA-Z_\u00A0-\uFFFF\\][a-zA-Z0-9_\u00A0-\uFFFF\-\\]*|)\|)?\*|#[a-zA-Z0-9_\u00A0-\uFFFF\-\\]+|\.[a-zA-Z0-9_\u00A0-\uFFFF\-\\]+|\[(?:[^\[\]'"]|'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*")*(?:\s+[iI])?\]|::?[a-zA-Z0-9_\u00A0-\uFFFF\-\\]+(?:\((.*)\))?|&|\s*[>+~]\s*|\s+)+$/;
|
|
1991
1992
|
return looseSelectorRegExp.test(selector);
|
|
1992
1993
|
}
|
|
1993
1994
|
|
|
@@ -2138,7 +2139,42 @@ CSSOM.parse = function parse(token, errorHandler) {
|
|
|
2138
2139
|
*/
|
|
2139
2140
|
function validateNamespaceSelector(selector) {
|
|
2140
2141
|
// Check if selector contains a namespace prefix
|
|
2141
|
-
|
|
2142
|
+
// We need to ignore pipes inside attribute selectors
|
|
2143
|
+
var pipeIndex = -1;
|
|
2144
|
+
var inAttr = false;
|
|
2145
|
+
var inSingleQuote = false;
|
|
2146
|
+
var inDoubleQuote = false;
|
|
2147
|
+
|
|
2148
|
+
for (var i = 0; i < selector.length; i++) {
|
|
2149
|
+
var char = selector[i];
|
|
2150
|
+
|
|
2151
|
+
if (inSingleQuote) {
|
|
2152
|
+
if (char === "'" && selector[i - 1] !== "\\") {
|
|
2153
|
+
inSingleQuote = false;
|
|
2154
|
+
}
|
|
2155
|
+
} else if (inDoubleQuote) {
|
|
2156
|
+
if (char === '"' && selector[i - 1] !== "\\") {
|
|
2157
|
+
inDoubleQuote = false;
|
|
2158
|
+
}
|
|
2159
|
+
} else if (inAttr) {
|
|
2160
|
+
if (char === "]") {
|
|
2161
|
+
inAttr = false;
|
|
2162
|
+
} else if (char === "'") {
|
|
2163
|
+
inSingleQuote = true;
|
|
2164
|
+
} else if (char === '"') {
|
|
2165
|
+
inDoubleQuote = true;
|
|
2166
|
+
}
|
|
2167
|
+
} else {
|
|
2168
|
+
if (char === "[") {
|
|
2169
|
+
inAttr = true;
|
|
2170
|
+
} else if (char === "|" && !inAttr) {
|
|
2171
|
+
// This is a namespace separator, not an attribute operator
|
|
2172
|
+
pipeIndex = i;
|
|
2173
|
+
break;
|
|
2174
|
+
}
|
|
2175
|
+
}
|
|
2176
|
+
}
|
|
2177
|
+
|
|
2142
2178
|
if (pipeIndex === -1) {
|
|
2143
2179
|
return true; // No namespace, always valid
|
|
2144
2180
|
}
|
package/lib/CSSStyleSheet.js
CHANGED
|
@@ -49,9 +49,9 @@ CSSOM.CSSStyleSheet.prototype.insertRule = function(rule, index) {
|
|
|
49
49
|
var ruleToParse = String(rule);
|
|
50
50
|
var parsedSheet = CSSOM.parse(ruleToParse);
|
|
51
51
|
if (parsedSheet.cssRules.length !== 1) {
|
|
52
|
-
var domExceptionName =
|
|
52
|
+
var domExceptionName = "SyntaxError";
|
|
53
53
|
if (ruleToParse.trimStart().startsWith('@namespace')) {
|
|
54
|
-
domExceptionName =
|
|
54
|
+
domExceptionName = "InvalidStateError";
|
|
55
55
|
}
|
|
56
56
|
throw new DOMException("Failed to execute 'insertRule' on 'CSSStyleSheet': Failed to parse the rule '" + ruleToParse + "'.", domExceptionName);
|
|
57
57
|
}
|
|
@@ -84,14 +84,14 @@ CSSOM.CSSStyleSheet.prototype.deleteRule = function(index) {
|
|
|
84
84
|
index = 4294967296 + index;
|
|
85
85
|
}
|
|
86
86
|
if (index >= this.cssRules.length) {
|
|
87
|
-
throw new DOMException("Failed to execute 'deleteRule' on 'CSSStyleSheet': The index provided (" + index + ") is larger than the maximum index (" + this.cssRules.length + ").",
|
|
87
|
+
throw new DOMException("Failed to execute 'deleteRule' on 'CSSStyleSheet': The index provided (" + index + ") is larger than the maximum index (" + this.cssRules.length + ").", "IndexSizeError");
|
|
88
88
|
}
|
|
89
89
|
if (this.cssRules[index] && this.cssRules[index].constructor.name == "CSSNamespaceRule") {
|
|
90
90
|
var shouldContinue = this.cssRules.every(function (rule) {
|
|
91
91
|
return ['CSSImportRule','CSSLayerStatementRule','CSSNamespaceRule'].indexOf(rule.constructor.name) !== -1
|
|
92
92
|
});
|
|
93
93
|
if (!shouldContinue) {
|
|
94
|
-
throw new DOMException("Failed to execute 'deleteRule' on 'CSSStyleSheet': Deleting a CSSNamespaceRule is not allowed when there is rules other than @import, @layer statement, or @namespace.",
|
|
94
|
+
throw new 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");
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
this.cssRules.splice(index, 1);
|
package/lib/parse.js
CHANGED
|
@@ -312,7 +312,8 @@ CSSOM.parse = function parse(token, errorHandler) {
|
|
|
312
312
|
// Fallback to a loose regexp for the overall selector structure (without deep paren matching)
|
|
313
313
|
// This is similar to the original, but without nested paren limitations
|
|
314
314
|
// Modified to support namespace selectors: *|element, prefix|element, |element
|
|
315
|
-
|
|
315
|
+
// Fixed attribute selector regex to properly handle |=, ~=, ^=, $=, *= operators
|
|
316
|
+
var looseSelectorRegExp = /^((?:(?:\*|[a-zA-Z_\u00A0-\uFFFF\\][a-zA-Z0-9_\u00A0-\uFFFF\-\\]*|)\|)?[a-zA-Z_\u00A0-\uFFFF\\][a-zA-Z0-9_\u00A0-\uFFFF\-\\]*|(?:(?:\*|[a-zA-Z_\u00A0-\uFFFF\\][a-zA-Z0-9_\u00A0-\uFFFF\-\\]*|)\|)?\*|#[a-zA-Z0-9_\u00A0-\uFFFF\-\\]+|\.[a-zA-Z0-9_\u00A0-\uFFFF\-\\]+|\[(?:[^\[\]'"]|'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*")*(?:\s+[iI])?\]|::?[a-zA-Z0-9_\u00A0-\uFFFF\-\\]+(?:\((.*)\))?|&|\s*[>+~]\s*|\s+)+$/;
|
|
316
317
|
return looseSelectorRegExp.test(selector);
|
|
317
318
|
}
|
|
318
319
|
|
|
@@ -463,7 +464,42 @@ CSSOM.parse = function parse(token, errorHandler) {
|
|
|
463
464
|
*/
|
|
464
465
|
function validateNamespaceSelector(selector) {
|
|
465
466
|
// Check if selector contains a namespace prefix
|
|
466
|
-
|
|
467
|
+
// We need to ignore pipes inside attribute selectors
|
|
468
|
+
var pipeIndex = -1;
|
|
469
|
+
var inAttr = false;
|
|
470
|
+
var inSingleQuote = false;
|
|
471
|
+
var inDoubleQuote = false;
|
|
472
|
+
|
|
473
|
+
for (var i = 0; i < selector.length; i++) {
|
|
474
|
+
var char = selector[i];
|
|
475
|
+
|
|
476
|
+
if (inSingleQuote) {
|
|
477
|
+
if (char === "'" && selector[i - 1] !== "\\") {
|
|
478
|
+
inSingleQuote = false;
|
|
479
|
+
}
|
|
480
|
+
} else if (inDoubleQuote) {
|
|
481
|
+
if (char === '"' && selector[i - 1] !== "\\") {
|
|
482
|
+
inDoubleQuote = false;
|
|
483
|
+
}
|
|
484
|
+
} else if (inAttr) {
|
|
485
|
+
if (char === "]") {
|
|
486
|
+
inAttr = false;
|
|
487
|
+
} else if (char === "'") {
|
|
488
|
+
inSingleQuote = true;
|
|
489
|
+
} else if (char === '"') {
|
|
490
|
+
inDoubleQuote = true;
|
|
491
|
+
}
|
|
492
|
+
} else {
|
|
493
|
+
if (char === "[") {
|
|
494
|
+
inAttr = true;
|
|
495
|
+
} else if (char === "|" && !inAttr) {
|
|
496
|
+
// This is a namespace separator, not an attribute operator
|
|
497
|
+
pipeIndex = i;
|
|
498
|
+
break;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
|
|
467
503
|
if (pipeIndex === -1) {
|
|
468
504
|
return true; // No namespace, always valid
|
|
469
505
|
}
|