blob: ac78f489513bb32fc4c12b1cd1a2d5e7f1bc77f4 [file] [log] [blame]
Mathias Bynens79e2cf02020-05-29 14:46:171module.exports = function resolveNestedSelector(selector, node) {
Nikolay Vitkov2a1b3b32025-01-03 10:18:462 var parent = node.parent;
3 var parentIsNestAtRule = parent.type === 'atrule' && parent.name === 'nest';
Mathias Bynens79e2cf02020-05-29 14:46:174
Nikolay Vitkov2a1b3b32025-01-03 10:18:465 if (parent.type === 'root') return [selector];
6 if (parent.type !== 'rule' && !parentIsNestAtRule) return resolveNestedSelector(selector, parent);
Mathias Bynens79e2cf02020-05-29 14:46:177
Nikolay Vitkov2a1b3b32025-01-03 10:18:468 var parentSelectors = (parentIsNestAtRule)
9 ? split(parent.params, ',', false).map((x) => x.trim())
10 : parent.selectors;
Mathias Bynens79e2cf02020-05-29 14:46:1711
Nikolay Vitkov2a1b3b32025-01-03 10:18:4612 var resolvedSelectors = parentSelectors.reduce(function(result, parentSelector) {
13 if (selector.indexOf('&') !== -1) {
14 var newlyResolvedSelectors = resolveNestedSelector(parentSelector, parent).map(function(resolvedParentSelector) {
15 return split(selector, '&', true).join(resolvedParentSelector);
16 });
17 return result.concat(newlyResolvedSelectors);
18 }
Mathias Bynens79e2cf02020-05-29 14:46:1719
Nikolay Vitkov2a1b3b32025-01-03 10:18:4620 var combinedSelector = [ parentSelector, selector ].join(' ');
21 return result.concat(resolveNestedSelector(combinedSelector, parent));
22 }, []);
Mathias Bynens79e2cf02020-05-29 14:46:1723
Nikolay Vitkov2a1b3b32025-01-03 10:18:4624 return resolvedSelectors;
25}
26
27var blockPairs = {
28 '(': ')',
29 '[': ']',
30 '{': '}'
31};
32
33function split(string, separator, splitFunctions) {
34 var array = [];
35 var current = '';
36 var split = false;
37
38 var blockClose = [];
39 var inQuote = false;
40 var prevQuote = '';
41 var escape = false;
42
43 for (var letter of string) {
44 if (escape) {
45 escape = false;
46 } else if (letter === '\\') {
47 escape = true;
48 } else if (inQuote) {
49 if (letter === prevQuote) {
50 inQuote = false;
51 }
52 } else if (letter === '"' || letter === "'") {
53 inQuote = true;
54 prevQuote = letter;
55 } else if (letter === '(' || letter === '[' || letter === '{') {
56 blockClose.push(blockPairs[letter]);
57 } else if (letter === blockClose[blockClose.length - 1]) {
58 blockClose.pop();
59 } else if (blockClose.length === 0 || (splitFunctions && blockClose.every((x) => x === ')'))) {
60 if (letter === separator) split = true;
61 }
62
63 if (split) {
64 array.push(current);
65 current = '';
66 split = false;
67 } else {
68 current += letter;
69 }
70 }
71
72 array.push(current);
73 return array;
Mathias Bynens79e2cf02020-05-29 14:46:1774}