* Add tests * Refactor refactor * Allow `prefixSelector` to take an AST * Consider multiple formats in `finalizeSelector` The functions `finalizeSelector` and `formatVariantSelector` together were using a mix for AST and string-based parsing. This now does the full transformation using the selector AST. This also parses the format strings AST as early as possible and is set up to parse them only once for a given set of rules. All of this will allow considering metadata per format string. For instance, we now know if the format string `.foo &` was produced by a normal variant or by an arbitrary variant. We use this information to control the prefixing behavior for individual format strings. * Update changelog * Cleanup code a bit
32 lines
936 B
JavaScript
32 lines
936 B
JavaScript
import parser from 'postcss-selector-parser'
|
|
|
|
/**
|
|
* @template {string | import('postcss-selector-parser').Root} T
|
|
*
|
|
* Prefix all classes in the selector with the given prefix
|
|
*
|
|
* It can take either a string or a selector AST and will return the same type
|
|
*
|
|
* @param {string} prefix
|
|
* @param {T} selector
|
|
* @param {boolean} prependNegative
|
|
* @returns {T}
|
|
*/
|
|
export default function (prefix, selector, prependNegative = false) {
|
|
if (prefix === '') {
|
|
return selector
|
|
}
|
|
|
|
let ast = typeof selector === 'string' ? parser().astSync(selector) : selector
|
|
|
|
ast.walkClasses((classSelector) => {
|
|
let baseClass = classSelector.value
|
|
let shouldPlaceNegativeBeforePrefix = prependNegative && baseClass.startsWith('-')
|
|
|
|
classSelector.value = shouldPlaceNegativeBeforePrefix
|
|
? `-${prefix}${baseClass.slice(1)}`
|
|
: `${prefix}${baseClass}`
|
|
})
|
|
|
|
return typeof selector === 'string' ? ast.toString() : ast
|
|
}
|