diff --git a/src/jit/lib/expandTailwindAtRules.js b/src/jit/lib/expandTailwindAtRules.js index 12abf8faee22..3e9bef4f9c0b 100644 --- a/src/jit/lib/expandTailwindAtRules.js +++ b/src/jit/lib/expandTailwindAtRules.js @@ -6,7 +6,13 @@ import cloneNodes from '../../util/cloneNodes' let env = sharedState.env let contentMatchCache = sharedState.contentMatchCache -const BROAD_MATCH_GLOBAL_REGEXP = /([^<>"'`\s]*\[[^<>\s]+\])|([^<>"'`\s]*[^<>"'`\s:])/g +const PATTERNS = [ + "([^<>\"'`\\s]*\\['[^<>\"'`\\s]*'\\])", // `content-['hello']` but not `content-['hello']']` + '([^<>"\'`\\s]*\\["[^<>"\'`\\s]*"\\])', // `content-["hello"]` but not `content-["hello"]"]` + '([^<>"\'`\\s]*\\[[^<>"\'`\\s]+\\])', // `fill-[#bada55]` + '([^<>"\'`\\s]*[^<>"\'`\\s:])', // `px-1.5`, `uppercase` but not `uppercase:` +].join('|') +const BROAD_MATCH_GLOBAL_REGEXP = new RegExp(PATTERNS, 'g') const INNER_MATCH_GLOBAL_REGEXP = /[^<>"'`\s.(){}[\]#=%]*[^<>"'`\s.(){}[\]#=%:]/g const builtInExtractors = { diff --git a/tests/jit/extractor-edge-cases.test.js b/tests/jit/extractor-edge-cases.test.js new file mode 100644 index 000000000000..88fac0c156fa --- /dev/null +++ b/tests/jit/extractor-edge-cases.test.js @@ -0,0 +1,57 @@ +import postcss from 'postcss' +import path from 'path' +import tailwind from '../../src/jit/index.js' + +function run(input, config = {}) { + const { currentTestName } = expect.getState() + + return postcss(tailwind(config)).process(input, { + from: `${path.resolve(__filename)}?test=${currentTestName}`, + }) +} + +test('PHP arrays', async () => { + let config = { + mode: 'jit', + purge: [ + { + raw: `

">Hello world

`, + }, + ], + theme: {}, + plugins: [], + } + + let css = `@tailwind utilities` + + return run(css, config).then((result) => { + expect(result.css).toMatchFormattedCss(` + .max-w-\\[16rem\\] { + max-width: 16rem; + } + `) + }) +}) + +test('arbitrary values with quotes', async () => { + let config = { + mode: 'jit', + purge: [ + { + raw: `
`, + }, + ], + theme: {}, + plugins: [], + } + + let css = `@tailwind utilities` + + return run(css, config).then((result) => { + expect(result.css).toMatchFormattedCss(` + .content-\\[\\'hello\\]\\'\\] { + content: 'hello]'; + } + `) + }) +})