@acemir/cssom 0.9.2 → 0.9.3

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
@@ -1816,7 +1816,7 @@ CSSOM.parse = function parse(token, errorHandler) {
1816
1816
  *
1817
1817
  * @type {RegExp}
1818
1818
  */
1819
- var basicSelectorRegExp = /^([a-zA-Z][a-zA-Z0-9_-]*|\*|#[a-zA-Z0-9_-]+|\.[a-zA-Z0-9_-]+|\[[^\[\]]*\]|::?[a-zA-Z0-9_-]+(?:\([^\(\)]*\))?|&|\s*[>+~]\s*|\s+)+$/;
1819
+ var basicSelectorRegExp = /^([a-zA-Z][a-zA-Z0-9_-]*|\*|#[a-zA-Z0-9_-]+|\.[a-zA-Z0-9_-]+|\[[^\[\]]*(?:\s+[iI])?\]|::?[a-zA-Z0-9_-]+(?:\([^\(\)]*\))?|&|\s*[>+~]\s*|\s+)+$/;
1820
1820
 
1821
1821
  /**
1822
1822
  * Regular expression to match CSS pseudo-classes with arguments.
@@ -1834,7 +1834,7 @@ CSSOM.parse = function parse(token, errorHandler) {
1834
1834
  * - Group 2: "2n+1"
1835
1835
  * @type {RegExp}
1836
1836
  */
1837
- var globalPseudoClassRegExp = /:([a-zA-Z-]+)\(([^)]*)\)/g;
1837
+ var globalPseudoClassRegExp = /:([a-zA-Z-]+)\(([^)]*?(?:\s+[iI])?)\)/g;
1838
1838
 
1839
1839
  /**
1840
1840
  * Parses a CSS selector string and splits it into parts, handling nested parentheses.
@@ -1846,30 +1846,42 @@ CSSOM.parse = function parse(token, errorHandler) {
1846
1846
  * @param {string} selector - The CSS selector string to parse.
1847
1847
  * @returns {string[]} An array of selector parts, split by top-level commas, with whitespace trimmed.
1848
1848
  */
1849
- function parseNestedSelectors(selector) {
1849
+ function parseAndSplitNestedSelectors(selector) {
1850
1850
  var depth = 0;
1851
1851
  var buffer = "";
1852
1852
  var parts = [];
1853
+ var inSingleQuote = false;
1854
+ var inDoubleQuote = false;
1853
1855
  var i, char;
1854
1856
 
1855
1857
  for (i = 0; i < selector.length; i++) {
1856
1858
  char = selector.charAt(i);
1857
1859
 
1858
- if (char === '(') {
1859
- depth++;
1860
+ if (char === "'" && !inDoubleQuote) {
1861
+ inSingleQuote = !inSingleQuote;
1860
1862
  buffer += char;
1861
- } else if (char === ')') {
1862
- depth--;
1863
+ } else if (char === '"' && !inSingleQuote) {
1864
+ inDoubleQuote = !inDoubleQuote;
1863
1865
  buffer += char;
1864
- if (depth === 0) {
1865
- parts.push(buffer.replace(/^\s+|\s+$/g, ""));
1866
+ } else if (!inSingleQuote && !inDoubleQuote) {
1867
+ if (char === '(') {
1868
+ depth++;
1869
+ buffer += char;
1870
+ } else if (char === ')') {
1871
+ depth--;
1872
+ buffer += char;
1873
+ if (depth === 0) {
1874
+ parts.push(buffer.replace(/^\s+|\s+$/g, ""));
1875
+ buffer = "";
1876
+ }
1877
+ } else if (char === ',' && depth === 0) {
1878
+ if (buffer.replace(/^\s+|\s+$/g, "")) {
1879
+ parts.push(buffer.replace(/^\s+|\s+$/g, ""));
1880
+ }
1866
1881
  buffer = "";
1882
+ } else {
1883
+ buffer += char;
1867
1884
  }
1868
- } else if (char === ',' && depth === 0) {
1869
- if (buffer.replace(/^\s+|\s+$/g, "")) {
1870
- parts.push(buffer.replace(/^\s+|\s+$/g, ""));
1871
- }
1872
- buffer = "";
1873
1885
  } else {
1874
1886
  buffer += char;
1875
1887
  }
@@ -1908,7 +1920,7 @@ CSSOM.parse = function parse(token, errorHandler) {
1908
1920
  while ((match = pseudoClassRegExp.exec(selector)) !== null) {
1909
1921
  var pseudoClass = match[1];
1910
1922
  if (selectorListPseudoClasses.hasOwnProperty(pseudoClass)) {
1911
- nestedSelectors = parseNestedSelectors(match[2]);
1923
+ nestedSelectors = parseAndSplitNestedSelectors(match[2]);
1912
1924
  // Validate each nested selector
1913
1925
  for (i = 0; i < nestedSelectors.length; i++) {
1914
1926
  if (!validateSelector(nestedSelectors[i])) {
@@ -1931,9 +1943,10 @@ CSSOM.parse = function parse(token, errorHandler) {
1931
1943
  */
1932
1944
  function isValidSelectorText(selectorText) {
1933
1945
  // Split selectorText by commas and validate each part
1934
- var selectors = selectorText.split(',');
1946
+ var selectors = parseAndSplitNestedSelectors(selectorText);
1935
1947
  for (var i = 0; i < selectors.length; i++) {
1936
- if (!validateSelector(selectors[i].replace(/^\s+|\s+$/g, ""))) {
1948
+ var processedSelectors = selectors[i].replace(/^\s+|\s+$/g, "");
1949
+ if (!validateSelector(processedSelectors)) {
1937
1950
  return false;
1938
1951
  }
1939
1952
  }
@@ -2159,7 +2172,6 @@ CSSOM.parse = function parse(token, errorHandler) {
2159
2172
  }
2160
2173
 
2161
2174
  currentScope = parentRule = styleRule;
2162
- console.log('sel out', buffer);
2163
2175
  styleRule.selectorText = buffer.trim();
2164
2176
  styleRule.style.__starts = i;
2165
2177
  styleRule.parentStyleSheet = styleSheet;
@@ -2289,9 +2301,8 @@ CSSOM.parse = function parse(token, errorHandler) {
2289
2301
  }
2290
2302
 
2291
2303
  styleRule = new CSSOM.CSSStyleRule();
2292
- console.log('sel in', buffer);
2293
2304
  // In a nested selector, ensure each selector contains '&' at the beginning, except for selectors that already have '&' somewhere
2294
- styleRule.selectorText = parseNestedSelectors(buffer.trim()).map(function(sel) {
2305
+ styleRule.selectorText = parseAndSplitNestedSelectors(buffer.trim()).map(function(sel) {
2295
2306
  return sel.indexOf('&') === -1 ? '& ' + sel : sel;
2296
2307
  }).join(', ');
2297
2308
  styleRule.style.__starts = i - buffer.length;
package/lib/parse.js CHANGED
@@ -249,7 +249,7 @@ CSSOM.parse = function parse(token, errorHandler) {
249
249
  *
250
250
  * @type {RegExp}
251
251
  */
252
- var basicSelectorRegExp = /^([a-zA-Z][a-zA-Z0-9_-]*|\*|#[a-zA-Z0-9_-]+|\.[a-zA-Z0-9_-]+|\[[^\[\]]*\]|::?[a-zA-Z0-9_-]+(?:\([^\(\)]*\))?|&|\s*[>+~]\s*|\s+)+$/;
252
+ var basicSelectorRegExp = /^([a-zA-Z][a-zA-Z0-9_-]*|\*|#[a-zA-Z0-9_-]+|\.[a-zA-Z0-9_-]+|\[[^\[\]]*(?:\s+[iI])?\]|::?[a-zA-Z0-9_-]+(?:\([^\(\)]*\))?|&|\s*[>+~]\s*|\s+)+$/;
253
253
 
254
254
  /**
255
255
  * Regular expression to match CSS pseudo-classes with arguments.
@@ -267,7 +267,7 @@ CSSOM.parse = function parse(token, errorHandler) {
267
267
  * - Group 2: "2n+1"
268
268
  * @type {RegExp}
269
269
  */
270
- var globalPseudoClassRegExp = /:([a-zA-Z-]+)\(([^)]*)\)/g;
270
+ var globalPseudoClassRegExp = /:([a-zA-Z-]+)\(([^)]*?(?:\s+[iI])?)\)/g;
271
271
 
272
272
  /**
273
273
  * Parses a CSS selector string and splits it into parts, handling nested parentheses.
@@ -279,30 +279,42 @@ CSSOM.parse = function parse(token, errorHandler) {
279
279
  * @param {string} selector - The CSS selector string to parse.
280
280
  * @returns {string[]} An array of selector parts, split by top-level commas, with whitespace trimmed.
281
281
  */
282
- function parseNestedSelectors(selector) {
282
+ function parseAndSplitNestedSelectors(selector) {
283
283
  var depth = 0;
284
284
  var buffer = "";
285
285
  var parts = [];
286
+ var inSingleQuote = false;
287
+ var inDoubleQuote = false;
286
288
  var i, char;
287
289
 
288
290
  for (i = 0; i < selector.length; i++) {
289
291
  char = selector.charAt(i);
290
292
 
291
- if (char === '(') {
292
- depth++;
293
+ if (char === "'" && !inDoubleQuote) {
294
+ inSingleQuote = !inSingleQuote;
293
295
  buffer += char;
294
- } else if (char === ')') {
295
- depth--;
296
+ } else if (char === '"' && !inSingleQuote) {
297
+ inDoubleQuote = !inDoubleQuote;
296
298
  buffer += char;
297
- if (depth === 0) {
298
- parts.push(buffer.replace(/^\s+|\s+$/g, ""));
299
+ } else if (!inSingleQuote && !inDoubleQuote) {
300
+ if (char === '(') {
301
+ depth++;
302
+ buffer += char;
303
+ } else if (char === ')') {
304
+ depth--;
305
+ buffer += char;
306
+ if (depth === 0) {
307
+ parts.push(buffer.replace(/^\s+|\s+$/g, ""));
308
+ buffer = "";
309
+ }
310
+ } else if (char === ',' && depth === 0) {
311
+ if (buffer.replace(/^\s+|\s+$/g, "")) {
312
+ parts.push(buffer.replace(/^\s+|\s+$/g, ""));
313
+ }
299
314
  buffer = "";
315
+ } else {
316
+ buffer += char;
300
317
  }
301
- } else if (char === ',' && depth === 0) {
302
- if (buffer.replace(/^\s+|\s+$/g, "")) {
303
- parts.push(buffer.replace(/^\s+|\s+$/g, ""));
304
- }
305
- buffer = "";
306
318
  } else {
307
319
  buffer += char;
308
320
  }
@@ -341,7 +353,7 @@ CSSOM.parse = function parse(token, errorHandler) {
341
353
  while ((match = pseudoClassRegExp.exec(selector)) !== null) {
342
354
  var pseudoClass = match[1];
343
355
  if (selectorListPseudoClasses.hasOwnProperty(pseudoClass)) {
344
- nestedSelectors = parseNestedSelectors(match[2]);
356
+ nestedSelectors = parseAndSplitNestedSelectors(match[2]);
345
357
  // Validate each nested selector
346
358
  for (i = 0; i < nestedSelectors.length; i++) {
347
359
  if (!validateSelector(nestedSelectors[i])) {
@@ -364,9 +376,10 @@ CSSOM.parse = function parse(token, errorHandler) {
364
376
  */
365
377
  function isValidSelectorText(selectorText) {
366
378
  // Split selectorText by commas and validate each part
367
- var selectors = selectorText.split(',');
379
+ var selectors = parseAndSplitNestedSelectors(selectorText);
368
380
  for (var i = 0; i < selectors.length; i++) {
369
- if (!validateSelector(selectors[i].replace(/^\s+|\s+$/g, ""))) {
381
+ var processedSelectors = selectors[i].replace(/^\s+|\s+$/g, "");
382
+ if (!validateSelector(processedSelectors)) {
370
383
  return false;
371
384
  }
372
385
  }
@@ -592,7 +605,6 @@ CSSOM.parse = function parse(token, errorHandler) {
592
605
  }
593
606
 
594
607
  currentScope = parentRule = styleRule;
595
- console.log('sel out', buffer);
596
608
  styleRule.selectorText = buffer.trim();
597
609
  styleRule.style.__starts = i;
598
610
  styleRule.parentStyleSheet = styleSheet;
@@ -722,9 +734,8 @@ CSSOM.parse = function parse(token, errorHandler) {
722
734
  }
723
735
 
724
736
  styleRule = new CSSOM.CSSStyleRule();
725
- console.log('sel in', buffer);
726
737
  // In a nested selector, ensure each selector contains '&' at the beginning, except for selectors that already have '&' somewhere
727
- styleRule.selectorText = parseNestedSelectors(buffer.trim()).map(function(sel) {
738
+ styleRule.selectorText = parseAndSplitNestedSelectors(buffer.trim()).map(function(sel) {
728
739
  return sel.indexOf('&') === -1 ? '& ' + sel : sel;
729
740
  }).join(', ');
730
741
  styleRule.style.__starts = i - buffer.length;
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "parser",
8
8
  "styleSheet"
9
9
  ],
10
- "version": "0.9.2",
10
+ "version": "0.9.3",
11
11
  "author": "Nikita Vasilyev <me@elv1s.ru>",
12
12
  "contributors": [
13
13
  "Acemir Sousa Mendes <acemirsm@gmail.com>"