@acemir/cssom 0.9.12 → 0.9.14

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 CHANGED
@@ -354,7 +354,7 @@ Object.defineProperty(CSSOM.CSSStyleRule.prototype, "cssText", {
354
354
  valuesArr.push(this.cssRules.map(function(rule){ return rule.cssText }).join("\n "));
355
355
  values = valuesArr.join("\n ") + "\n}"
356
356
  } else {
357
- values = " {" + this.style.cssText + "}";
357
+ values = " { " + this.style.cssText + " }";
358
358
  }
359
359
  text = this.selectorText + values;
360
360
  } else {
@@ -602,7 +602,7 @@ Object.defineProperties(CSSOM.CSSMediaRule.prototype, {
602
602
  for (var i=0, length=this.cssRules.length; i < length; i++) {
603
603
  cssTexts.push(this.cssRules[i].cssText);
604
604
  }
605
- return "@media " + this.media.mediaText + " {" + cssTexts.join("") + "}";
605
+ return "@media " + this.media.mediaText + " {" + (cssTexts.length ? "\n " + cssTexts.join("\n ") : "") + "\n}";
606
606
  },
607
607
  configurable: true,
608
608
  enumerable: true
@@ -641,7 +641,7 @@ Object.defineProperties(CSSOM.CSSContainerRule.prototype, {
641
641
  for (var i=0, length=this.cssRules.length; i < length; i++) {
642
642
  cssTexts.push(this.cssRules[i].cssText);
643
643
  }
644
- return "@container " + this.containerText + " {" + cssTexts.join("") + "}";
644
+ return "@container " + this.containerText + " {" + (cssTexts.length ? "\n " + cssTexts.join("\n ") : "") + "\n}";
645
645
  },
646
646
  configurable: true,
647
647
  enumerable: true
@@ -670,7 +670,7 @@ Object.defineProperty(CSSOM.CSSSupportsRule.prototype, "cssText", {
670
670
  cssTexts.push(this.cssRules[i].cssText);
671
671
  }
672
672
 
673
- return "@supports " + this.conditionText + " {" + cssTexts.join("") + "}";
673
+ return "@supports " + this.conditionText + " {" + (cssTexts.length ? "\n " + cssTexts.join("\n ") : "") + "\n}";
674
674
  }
675
675
  });
676
676
 
@@ -864,7 +864,7 @@ CSSOM.CSSNamespaceRule.prototype.type = 10;
864
864
 
865
865
  Object.defineProperty(CSSOM.CSSNamespaceRule.prototype, "cssText", {
866
866
  get: function() {
867
- return "@namespace" + (this.prefix && " " + this.prefix) + " url(" + this.namespaceURI + ");";
867
+ return "@namespace" + (this.prefix && " " + this.prefix) + " url(\"" + this.namespaceURI + "\");";
868
868
  },
869
869
  set: function(cssText) {
870
870
  // Reset prefix and namespaceURI
@@ -934,7 +934,7 @@ CSSOM.CSSFontFaceRule.prototype.type = 5;
934
934
  // http://www.opensource.apple.com/source/WebCore/WebCore-955.66.1/css/WebKitCSSFontFaceRule.cpp
935
935
  Object.defineProperty(CSSOM.CSSFontFaceRule.prototype, "cssText", {
936
936
  get: function() {
937
- return "@font-face {" + this.style.cssText + "}";
937
+ return "@font-face { " + this.style.cssText + " }";
938
938
  }
939
939
  });
940
940
 
@@ -962,7 +962,7 @@ Object.defineProperty(CSSOM.CSSHostRule.prototype, "cssText", {
962
962
  for (var i=0, length=this.cssRules.length; i < length; i++) {
963
963
  cssTexts.push(this.cssRules[i].cssText);
964
964
  }
965
- return "@host {" + cssTexts.join("") + "}";
965
+ return "@host {" + (cssTexts.length ? "\n " + cssTexts.join("\n ") : "") + "\n}";
966
966
  }
967
967
  });
968
968
 
@@ -990,7 +990,7 @@ Object.defineProperty(CSSOM.CSSStartingStyleRule.prototype, "cssText", {
990
990
  for (var i=0, length=this.cssRules.length; i < length; i++) {
991
991
  cssTexts.push(this.cssRules[i].cssText);
992
992
  }
993
- return "@starting-style {" + cssTexts.join("") + "}";
993
+ return "@starting-style {" + (cssTexts.length ? "\n " + cssTexts.join("\n ") : "") + "\n}";
994
994
  }
995
995
  });
996
996
 
@@ -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 = "SyntaxError";
1052
+ var domExceptionName = DOMException.SYNTAX_ERR;
1053
1053
  if (ruleToParse.trimStart().startsWith('@namespace')) {
1054
- domExceptionName = "InvalidStateError";
1054
+ domExceptionName = DOMException.INVALID_STATE_ERR;
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 + ").", "IndexSizeError");
1087
+ throw new DOMException("Failed to execute 'deleteRule' on 'CSSStyleSheet': The index provided (" + index + ") is larger than the maximum index (" + this.cssRules.length + ").", DOMException.INDEX_SIZE_ERR);
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.", "InvalidStateError");
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.", DOMException.INVALID_STATE_ERR);
1095
1095
  }
1096
1096
  }
1097
1097
  this.cssRules.splice(index, 1);
@@ -1135,9 +1135,9 @@ Object.defineProperty(CSSOM.CSSKeyframesRule.prototype, "cssText", {
1135
1135
  get: function() {
1136
1136
  var cssTexts = [];
1137
1137
  for (var i=0, length=this.cssRules.length; i < length; i++) {
1138
- cssTexts.push(" " + this.cssRules[i].cssText);
1138
+ cssTexts.push(this.cssRules[i].cssText);
1139
1139
  }
1140
- return "@" + (this._vendorPrefix || '') + "keyframes " + this.name + " { \n" + cssTexts.join("\n") + "\n}";
1140
+ return "@" + (this._vendorPrefix || '') + "keyframes " + this.name + (this.name && " ") + "{" + (cssTexts.length ? "\n " + cssTexts.join("\n ") : "") + "\n}";
1141
1141
  }
1142
1142
  });
1143
1143
 
@@ -1164,7 +1164,7 @@ CSSOM.CSSKeyframeRule.prototype.type = 8;
1164
1164
  // http://www.opensource.apple.com/source/WebCore/WebCore-955.66.1/css/WebKitCSSKeyframeRule.cpp
1165
1165
  Object.defineProperty(CSSOM.CSSKeyframeRule.prototype, "cssText", {
1166
1166
  get: function() {
1167
- return this.keyText + " {" + this.style.cssText + "} ";
1167
+ return this.keyText + " { " + this.style.cssText + " } ";
1168
1168
  }
1169
1169
  });
1170
1170
 
@@ -1248,7 +1248,7 @@ Object.defineProperty(CSSOM.CSSDocumentRule.prototype, "cssText", {
1248
1248
  for (var i=0, length=this.cssRules.length; i < length; i++) {
1249
1249
  cssTexts.push(this.cssRules[i].cssText);
1250
1250
  }
1251
- return "@-moz-document " + this.matcher.matcherText + " {" + cssTexts.join("") + "}";
1251
+ return "@-moz-document " + this.matcher.matcherText + " {" + (cssTexts.length ? "\n " + cssTexts.join("\n ") : "") + "\n}";
1252
1252
  }
1253
1253
  });
1254
1254
 
@@ -1646,7 +1646,7 @@ Object.defineProperties(CSSOM.CSSLayerBlockRule.prototype, {
1646
1646
  for (var i = 0, length = this.cssRules.length; i < length; i++) {
1647
1647
  cssTexts.push(this.cssRules[i].cssText);
1648
1648
  }
1649
- return "@layer " + this.name + (this.name && " ") + "{" + cssTexts.join("") + "}";
1649
+ return "@layer " + this.name + (this.name && " ") + "{" + (cssTexts.length ? "\n " + cssTexts.join("\n ") : "") + "\n}";
1650
1650
  },
1651
1651
  configurable: true,
1652
1652
  enumerable: true,
@@ -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
- 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+)+$/;
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
- var pipeIndex = selector.indexOf('|');
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
  }
@@ -2575,9 +2611,13 @@ CSSOM.parse = function parse(token, errorHandler) {
2575
2611
  return match;
2576
2612
  });
2577
2613
  // In a nested selector, ensure each selector contains '&' at the beginning, except for selectors that already have '&' somewhere
2578
- styleRule.selectorText = parseAndSplitNestedSelectors(processedSelectorText).map(function(sel) {
2579
- return sel.indexOf('&') === -1 ? '& ' + sel : sel;
2580
- }).join(', ');
2614
+ if (parentRule.constructor.name !== "CSSStyleRule" && parentRule.parentRule === null) {
2615
+ styleRule.selectorText = processedSelectorText;
2616
+ } else {
2617
+ styleRule.selectorText = parseAndSplitNestedSelectors(processedSelectorText).map(function(sel) {
2618
+ return sel.indexOf('&') === -1 ? '& ' + sel : sel;
2619
+ }).join(', ');
2620
+ }
2581
2621
  styleRule.style.__starts = i - buffer.length;
2582
2622
  styleRule.parentRule = parentRule;
2583
2623
  nestedSelectorRule = styleRule;
@@ -37,7 +37,7 @@ Object.defineProperties(CSSOM.CSSContainerRule.prototype, {
37
37
  for (var i=0, length=this.cssRules.length; i < length; i++) {
38
38
  cssTexts.push(this.cssRules[i].cssText);
39
39
  }
40
- return "@container " + this.containerText + " {" + cssTexts.join("") + "}";
40
+ return "@container " + this.containerText + " {" + (cssTexts.length ? "\n " + cssTexts.join("\n ") : "") + "\n}";
41
41
  },
42
42
  configurable: true,
43
43
  enumerable: true
@@ -29,7 +29,7 @@ Object.defineProperty(CSSOM.CSSDocumentRule.prototype, "cssText", {
29
29
  for (var i=0, length=this.cssRules.length; i < length; i++) {
30
30
  cssTexts.push(this.cssRules[i].cssText);
31
31
  }
32
- return "@-moz-document " + this.matcher.matcherText + " {" + cssTexts.join("") + "}";
32
+ return "@-moz-document " + this.matcher.matcherText + " {" + (cssTexts.length ? "\n " + cssTexts.join("\n ") : "") + "\n}";
33
33
  }
34
34
  });
35
35
 
@@ -26,7 +26,7 @@ CSSOM.CSSFontFaceRule.prototype.type = 5;
26
26
  // http://www.opensource.apple.com/source/WebCore/WebCore-955.66.1/css/WebKitCSSFontFaceRule.cpp
27
27
  Object.defineProperty(CSSOM.CSSFontFaceRule.prototype, "cssText", {
28
28
  get: function() {
29
- return "@font-face {" + this.style.cssText + "}";
29
+ return "@font-face { " + this.style.cssText + " }";
30
30
  }
31
31
  });
32
32
 
@@ -27,7 +27,7 @@ Object.defineProperty(CSSOM.CSSHostRule.prototype, "cssText", {
27
27
  for (var i=0, length=this.cssRules.length; i < length; i++) {
28
28
  cssTexts.push(this.cssRules[i].cssText);
29
29
  }
30
- return "@host {" + cssTexts.join("") + "}";
30
+ return "@host {" + (cssTexts.length ? "\n " + cssTexts.join("\n ") : "") + "\n}";
31
31
  }
32
32
  });
33
33
 
@@ -27,7 +27,7 @@ CSSOM.CSSKeyframeRule.prototype.type = 8;
27
27
  // http://www.opensource.apple.com/source/WebCore/WebCore-955.66.1/css/WebKitCSSKeyframeRule.cpp
28
28
  Object.defineProperty(CSSOM.CSSKeyframeRule.prototype, "cssText", {
29
29
  get: function() {
30
- return this.keyText + " {" + this.style.cssText + "} ";
30
+ return this.keyText + " { " + this.style.cssText + " } ";
31
31
  }
32
32
  });
33
33
 
@@ -27,9 +27,9 @@ Object.defineProperty(CSSOM.CSSKeyframesRule.prototype, "cssText", {
27
27
  get: function() {
28
28
  var cssTexts = [];
29
29
  for (var i=0, length=this.cssRules.length; i < length; i++) {
30
- cssTexts.push(" " + this.cssRules[i].cssText);
30
+ cssTexts.push(this.cssRules[i].cssText);
31
31
  }
32
- return "@" + (this._vendorPrefix || '') + "keyframes " + this.name + " { \n" + cssTexts.join("\n") + "\n}";
32
+ return "@" + (this._vendorPrefix || '') + "keyframes " + this.name + (this.name && " ") + "{" + (cssTexts.length ? "\n " + cssTexts.join("\n ") : "") + "\n}";
33
33
  }
34
34
  });
35
35
 
@@ -26,7 +26,7 @@ Object.defineProperties(CSSOM.CSSLayerBlockRule.prototype, {
26
26
  for (var i = 0, length = this.cssRules.length; i < length; i++) {
27
27
  cssTexts.push(this.cssRules[i].cssText);
28
28
  }
29
- return "@layer " + this.name + (this.name && " ") + "{" + cssTexts.join("") + "}";
29
+ return "@layer " + this.name + (this.name && " ") + "{" + (cssTexts.length ? "\n " + cssTexts.join("\n ") : "") + "\n}";
30
30
  },
31
31
  configurable: true,
32
32
  enumerable: true,
@@ -40,7 +40,7 @@ Object.defineProperties(CSSOM.CSSMediaRule.prototype, {
40
40
  for (var i=0, length=this.cssRules.length; i < length; i++) {
41
41
  cssTexts.push(this.cssRules[i].cssText);
42
42
  }
43
- return "@media " + this.media.mediaText + " {" + cssTexts.join("") + "}";
43
+ return "@media " + this.media.mediaText + " {" + (cssTexts.length ? "\n " + cssTexts.join("\n ") : "") + "\n}";
44
44
  },
45
45
  configurable: true,
46
46
  enumerable: true
@@ -23,7 +23,7 @@ CSSOM.CSSNamespaceRule.prototype.type = 10;
23
23
 
24
24
  Object.defineProperty(CSSOM.CSSNamespaceRule.prototype, "cssText", {
25
25
  get: function() {
26
- return "@namespace" + (this.prefix && " " + this.prefix) + " url(" + this.namespaceURI + ");";
26
+ return "@namespace" + (this.prefix && " " + this.prefix) + " url(\"" + this.namespaceURI + "\");";
27
27
  },
28
28
  set: function(cssText) {
29
29
  // Reset prefix and namespaceURI
@@ -27,7 +27,7 @@ Object.defineProperty(CSSOM.CSSStartingStyleRule.prototype, "cssText", {
27
27
  for (var i=0, length=this.cssRules.length; i < length; i++) {
28
28
  cssTexts.push(this.cssRules[i].cssText);
29
29
  }
30
- return "@starting-style {" + cssTexts.join("") + "}";
30
+ return "@starting-style {" + (cssTexts.length ? "\n " + cssTexts.join("\n ") : "") + "\n}";
31
31
  }
32
32
  });
33
33
 
@@ -34,7 +34,7 @@ Object.defineProperty(CSSOM.CSSStyleRule.prototype, "cssText", {
34
34
  valuesArr.push(this.cssRules.map(function(rule){ return rule.cssText }).join("\n "));
35
35
  values = valuesArr.join("\n ") + "\n}"
36
36
  } else {
37
- values = " {" + this.style.cssText + "}";
37
+ values = " { " + this.style.cssText + " }";
38
38
  }
39
39
  text = this.selectorText + values;
40
40
  } else {
@@ -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 = "SyntaxError";
52
+ var domExceptionName = DOMException.SYNTAX_ERR;
53
53
  if (ruleToParse.trimStart().startsWith('@namespace')) {
54
- domExceptionName = "InvalidStateError";
54
+ domExceptionName = DOMException.INVALID_STATE_ERR;
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 + ").", "IndexSizeError");
87
+ throw new DOMException("Failed to execute 'deleteRule' on 'CSSStyleSheet': The index provided (" + index + ") is larger than the maximum index (" + this.cssRules.length + ").", DOMException.INDEX_SIZE_ERR);
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.", "InvalidStateError");
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.", DOMException.INVALID_STATE_ERR);
95
95
  }
96
96
  }
97
97
  this.cssRules.splice(index, 1);
@@ -27,7 +27,7 @@ Object.defineProperty(CSSOM.CSSSupportsRule.prototype, "cssText", {
27
27
  cssTexts.push(this.cssRules[i].cssText);
28
28
  }
29
29
 
30
- return "@supports " + this.conditionText + " {" + cssTexts.join("") + "}";
30
+ return "@supports " + this.conditionText + " {" + (cssTexts.length ? "\n " + cssTexts.join("\n ") : "") + "\n}";
31
31
  }
32
32
  });
33
33
 
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
- 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+)+$/;
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
- var pipeIndex = selector.indexOf('|');
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
  }
@@ -900,9 +936,13 @@ CSSOM.parse = function parse(token, errorHandler) {
900
936
  return match;
901
937
  });
902
938
  // In a nested selector, ensure each selector contains '&' at the beginning, except for selectors that already have '&' somewhere
903
- styleRule.selectorText = parseAndSplitNestedSelectors(processedSelectorText).map(function(sel) {
904
- return sel.indexOf('&') === -1 ? '& ' + sel : sel;
905
- }).join(', ');
939
+ if (parentRule.constructor.name !== "CSSStyleRule" && parentRule.parentRule === null) {
940
+ styleRule.selectorText = processedSelectorText;
941
+ } else {
942
+ styleRule.selectorText = parseAndSplitNestedSelectors(processedSelectorText).map(function(sel) {
943
+ return sel.indexOf('&') === -1 ? '& ' + sel : sel;
944
+ }).join(', ');
945
+ }
906
946
  styleRule.style.__starts = i - buffer.length;
907
947
  styleRule.parentRule = parentRule;
908
948
  nestedSelectorRule = styleRule;
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "parser",
8
8
  "styleSheet"
9
9
  ],
10
- "version": "0.9.12",
10
+ "version": "0.9.14",
11
11
  "author": "Nikita Vasilyev <me@elv1s.ru>",
12
12
  "contributors": [
13
13
  "Acemir Sousa Mendes <acemirsm@gmail.com>"