diff --git a/src/lib/generateRules.js b/src/lib/generateRules.js index 6b86515412f6..559ab39acf9b 100644 --- a/src/lib/generateRules.js +++ b/src/lib/generateRules.js @@ -25,33 +25,33 @@ function getClassNameFromSelector(selector) { // Example with dynamic classes: // ['grid-cols', '[[linename],1fr,auto]'] // ['grid', 'cols-[[linename],1fr,auto]'] -function* candidatePermutations(candidate, lastIndex = Infinity) { - if (lastIndex < 0) { - return - } +function* candidatePermutations(candidate) { + let lastIndex = Infinity - let dashIdx + while (lastIndex >= 0) { + let dashIdx - if (lastIndex === Infinity && candidate.endsWith(']')) { - let bracketIdx = candidate.indexOf('[') + if (lastIndex === Infinity && candidate.endsWith(']')) { + let bracketIdx = candidate.indexOf('[') - // If character before `[` isn't a dash or a slash, this isn't a dynamic class - // eg. string[] - dashIdx = ['-', '/'].includes(candidate[bracketIdx - 1]) ? bracketIdx - 1 : -1 - } else { - dashIdx = candidate.lastIndexOf('-', lastIndex) - } + // If character before `[` isn't a dash or a slash, this isn't a dynamic class + // eg. string[] + dashIdx = ['-', '/'].includes(candidate[bracketIdx - 1]) ? bracketIdx - 1 : -1 + } else { + dashIdx = candidate.lastIndexOf('-', lastIndex) + } - if (dashIdx < 0) { - return - } + if (dashIdx < 0) { + break + } - let prefix = candidate.slice(0, dashIdx) - let modifier = candidate.slice(dashIdx + 1) + let prefix = candidate.slice(0, dashIdx) + let modifier = candidate.slice(dashIdx + 1) - yield [prefix, modifier] + yield [prefix, modifier] - yield* candidatePermutations(candidate, dashIdx - 1) + lastIndex = dashIdx - 1 + } } function applyPrefix(matches, context) { diff --git a/tests/basic-usage.test.js b/tests/basic-usage.test.js index 2f43fa3c6cae..068a31b7309a 100644 --- a/tests/basic-usage.test.js +++ b/tests/basic-usage.test.js @@ -172,3 +172,19 @@ it('shadows support values without a leading zero', () => { `) }) }) + +it('can scan extremely long classes without crashing', () => { + let val = 'cols-' + '-a'.repeat(4000) + let config = { + content: [{ raw: html`
` }], + corePlugins: { preflight: false }, + } + + let input = css` + @tailwind utilities; + ` + + return run(input, config).then((result) => { + expect(result.css).toMatchFormattedCss(css``) + }) +})