Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
rule.selectors.forEach(selector => {
const trimSelector = selector.trim()
// Ignore `.selector, { }`
if (trimSelector === "") { return }
// The edge-case of duplicate selectors will act acceptably
const index = rule.selector.indexOf(trimSelector)
// Resolve any nested selectors before checking
resolvedNestedSelector(selector, rule).forEach(resolvedSelector => {
parseSelector(resolvedSelector, result, rule, s => checkSelector(s, rule, index, comparisonContext))
})
})
})
rule.selectors.forEach(selector => {
resolvedNestedSelector(selector, rule).forEach(resolvedSelector => {
// Return early if selector contains a not pseudo-class
if (selector.indexOf(":not(") !== -1) { return }
// Return early if selector contains a matches
if (selector.indexOf(":matches(") !== -1) { return }
// Check if the selector specificity exceeds the allowed maximum
try {
if (compare(resolvedSelector, maxSpecificityArray) === 1) {
report({
ruleName,
result,
node: rule,
message: messages.expected(resolvedSelector, max),
word: selector,
})
}
} catch (e) {
if (!isStandardRule(rule)) {
return;
}
// If the selector has interpolation
if (!isStandardSelector(selector)) {
return;
}
// Nested selectors are processed in steps, as nesting levels are resolved.
// Here we skip processing intermediate parts of selectors (to process only fully resolved selectors)
// if (rule.nodes.some(node => node.type === "rule" || node.type === "atrule")) { return }
// Only resolve selectors that have an interpolating "&"
if (hasInterpolatingAmpersand(selector)) {
resolveNestedSelector(selector, rule).forEach(parse);
} else {
parse(selector);
}
});
root.walkRules(rule => {
const { selector, selectors } = rule
if (!isStandardSyntaxRule(rule)) { return }
if (!isStandardSyntaxSelector(selector)) { return }
if (selectors.some(s => isKeyframeSelector(s))) { return }
// Only bother resolving selectors that have an interpolating &
if (shouldResolveNestedSelectors && hasInterpolatingAmpersand(selector)) {
resolveNestedSelector(selector, rule).forEach(selector => {
parseSelector(selector, result, rule, s => checkSelector(s, rule))
})
} else {
parseSelector(selector, result, rule, s => checkSelector(s, rule))
}
})
rule.selectors.forEach((selector) => {
resolvedNestedSelector(selector, rule).forEach(resolvedSelector => {
// Process each resolved selector with `checkSelector` via postcss-selector-parser
selectorParser(s => checkSelector(s, rule)).process(resolvedSelector)
})
})
})
const resolvedSelectors = rule.selectors.reduce((result, selector) => {
return union(result, resolvedNestedSelector(selector, rule))
}, [])
const normalizedSelectorList = resolvedSelectors.map(normalizeSelector)
selectors.forEach(selector => {
resolveNestedSelector(selector, rule).forEach(selector => {
checkSelector(selector, rule)
})
})
} else {
if (selectorNode.type === "id" && !optionsMatches(options, "ignore", "id")) {
complain(index)
}
if (selectorNode.type === "class" && !optionsMatches(options, "ignore", "class")) {
complain(index)
}
if (selectorNode.type === "attribute" && !optionsMatches(options, "ignore", "attribute")) {
complain(index)
}
})
})
}
resolvedNestedSelector(rule.selector, rule).forEach(resolvedSelector => {
if (!isStandardSyntaxSelector(resolvedSelector)) { return }
parseSelector(resolvedSelector, result, rule, checkSelector)
})
function complain(index) {
report({
ruleName,
result,
node: rule,
message: messages.rejected,
index,
})
}
})
}