Merge pull request #695 from tailwindcss/manually-escape-variants

Require plugin authors to manually escape variants
This commit is contained in:
Adam Wathan 2019-02-28 11:11:45 -05:00 • committed by GitHub
commit 8cf5bc1537
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 50 additions and 12 deletions

View file

@ -300,10 +300,43 @@ test('plugin variants can modify selectors with a simplified API', () => {
...config,
plugins: [
...config.plugins,
function({ addVariant }) {
function({ addVariant, e }) {
addVariant('first-child', ({ modifySelectors, separator }) => {
modifySelectors(({ className }) => {
return `.first-child${separator}${className}:first-child`
return `.${e(`first-child${separator}${className}`)}:first-child`
})
})
},
],
}).then(result => {
expect(result.css).toMatchCss(output)
expect(result.warnings().length).toBe(0)
})
})
test('plugin variants that use modify selectors need to manually escape the class name they are modifying', () => {
const input = `
@variants first-child {
.banana-1\\/2 { color: yellow; }
.chocolate-1\\.5 { color: brown; }
}
`
const output = `
.banana-1\\/2 { color: yellow; }
.chocolate-1\\.5 { color: brown; }
.first-child\\:banana-1\\/2:first-child { color: yellow; }
.first-child\\:chocolate-1\\.5:first-child { color: brown; }
`
return run(input, {
...config,
plugins: [
...config.plugins,
function({ addVariant, e }) {
addVariant('first-child', ({ modifySelectors, separator }) => {
modifySelectors(({ className }) => {
return `.${e(`first-child${separator}${className}`)}:first-child`
})
})
},
@ -335,13 +368,13 @@ test('plugin variants can wrap rules in another at-rule using the raw PostCSS AP
...config,
plugins: [
...config.plugins,
function({ addVariant }) {
function({ addVariant, e }) {
addVariant('supports-grid', ({ container, separator }) => {
const supportsRule = postcss.atRule({ name: 'supports', params: '(display: grid)' })
supportsRule.nodes = container.nodes
container.nodes = [supportsRule]
supportsRule.walkRules(rule => {
rule.selector = `.supports-grid${separator}${rule.selector.slice(1)}`
rule.selector = `.${e(`supports-grid${separator}${rule.selector.slice(1)}`)}`
})
})
},

View file

@ -1,11 +1,12 @@
import _ from 'lodash'
import postcss from 'postcss'
import generateVariantFunction from '../util/generateVariantFunction'
import e from '../util/escapeClassName'
function generatePseudoClassVariant(pseudoClass) {
return generateVariantFunction(({ modifySelectors, separator }) => {
return modifySelectors(({ className }) => {
return `.${pseudoClass}${separator}${className}:${pseudoClass}`
return `.${e(`${pseudoClass}${separator}${className}`)}:${pseudoClass}`
})
})
}
@ -18,7 +19,7 @@ const defaultVariantGenerators = {
default: generateVariantFunction(() => {}),
'group-hover': generateVariantFunction(({ modifySelectors, separator }) => {
return modifySelectors(({ className }) => {
return `.group:hover .group-hover${separator}${className}`
return `.group:hover .${e(`group-hover${separator}${className}`)}`
})
}),
hover: generatePseudoClassVariant('hover'),

View file

@ -1,6 +1,6 @@
import _ from 'lodash'
import postcss from 'postcss'
import escapeClassName from './escapeClassName'
import selectorParser from 'postcss-selector-parser'
export default function generateVariantFunction(generator) {
return (container, config) => {
@ -10,15 +10,19 @@ export default function generateVariantFunction(generator) {
_.defaultTo(
generator({
container: cloned,
separator: escapeClassName(config.separator),
separator: config.separator,
modifySelectors: modifierFunction => {
cloned.walkRules(rule => {
rule.selectors = rule.selectors.map(selector =>
modifierFunction({
className: selector.slice(1),
rule.selectors = rule.selectors.map(selector => {
const className = selectorParser(selectors => {
return selectors.first.filter(({ type }) => type === 'class').pop().value
}).transformSync(selector)
return modifierFunction({
className,
selector,
})
)
})
})
return cloned
},