From 0664aae901b7b162c3b030276c78d8c2f086ead6 Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Thu, 9 Jun 2022 16:53:02 -0400 Subject: [PATCH] Fix class detection in markdown code fences and slim templates (#8569) * Fix detection of classes in markdown code fences * Fix candidate detection in `.slim` templates * Update changelog --- CHANGELOG.md | 1 + src/lib/defaultExtractor.js | 14 +++++++------- tests/default-extractor.test.js | 27 +++++++++++++++++++++++---- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 15dd1f44146e..279413af424e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fix candidate extractor regression ([#8558](https://github.com/tailwindlabs/tailwindcss/pull/8558)) - Split `::backdrop`` into separate defaults group ([#8567](https://github.com/tailwindlabs/tailwindcss/pull/8567)) - Fix postcss plugin type ([#8564](https://github.com/tailwindlabs/tailwindcss/pull/8564)) +- Fix class detection in markdown code fences and slim templates ([#8569](https://github.com/tailwindlabs/tailwindcss/pull/8569)) ## [3.1.0] - 2022-06-08 diff --git a/src/lib/defaultExtractor.js b/src/lib/defaultExtractor.js index 98bc7386baca..c3e5b642cc3f 100644 --- a/src/lib/defaultExtractor.js +++ b/src/lib/defaultExtractor.js @@ -25,7 +25,7 @@ function* buildRegExps(context) { let utility = regex.any([ // Arbitrary properties - /\[[^\s:'"]+:[^\s\]]+\]/, + /\[[^\s:'"`]+:[^\s\]]+\]/, // Utilities regex.pattern([ @@ -43,7 +43,7 @@ function* buildRegExps(context) { /(?![{([]])/, // optionally followed by an opacity modifier - /(?:\/[^\s'"\\><$]*)?/, + /(?:\/[^\s'"`\\><$]*)?/, ]), regex.pattern([ @@ -54,11 +54,11 @@ function* buildRegExps(context) { /(?![{([]])/, // optionally followed by an opacity modifier - /(?:\/[^\s'"\\$]*)?/, + /(?:\/[^\s'"`\\$]*)?/, ]), // Normal values w/o quotes — may include an opacity modifier - /[-\/][^\s'"\\$={><]*/, + /[-\/][^\s'"`\\$={><]*/, ]) ), ]), @@ -69,8 +69,8 @@ function* buildRegExps(context) { '((?=((', regex.any( [ - regex.pattern([/([^\s"'\[\\]+-)?\[[^\s"'\\]+\]/, separator]), - regex.pattern([/[^\s"'\[\\]+/, separator]), + regex.pattern([/([^\s"'`\[\\]+-)?\[[^\s"'`\\]+\]/, separator]), + regex.pattern([/[^\s"'`\[\\]+/, separator]), ], true ), @@ -91,7 +91,7 @@ function* buildRegExps(context) { ]) // 5. Inner matches - // yield /[^<>"'`\s.(){}[\]#=%$]*[^<>"'`\s.(){}[\]#=%:$]/g + yield /[^<>"'`\s.(){}[\]#=%$]*[^<>"'`\s.(){}[\]#=%:$]/g } // We want to capture any "special" characters diff --git a/tests/default-extractor.test.js b/tests/default-extractor.test.js index 4e1792e8e7b9..75abf4caebfd 100644 --- a/tests/default-extractor.test.js +++ b/tests/default-extractor.test.js @@ -415,28 +415,24 @@ test('with single quotes array within template literal', async () => { const extractions = defaultExtractor(`
`) expect(extractions).toContain('pr-1.5') - expect(extractions).not.toContain('pr-1') }) test('with double quotes array within template literal', async () => { const extractions = defaultExtractor(`
`) expect(extractions).toContain('pr-1.5') - expect(extractions).not.toContain('pr-1') }) test('with single quotes array within function', async () => { const extractions = defaultExtractor(`document.body.classList.add(['pl-1.5'].join(" "));`) expect(extractions).toContain('pl-1.5') - expect(extractions).not.toContain('pl-1') }) test('with double quotes array within function', async () => { const extractions = defaultExtractor(`document.body.classList.add(["pl-1.5"].join(" "));`) expect(extractions).toContain('pl-1.5') - expect(extractions).not.toContain('pl-1') }) test('with angle brackets', async () => { @@ -449,3 +445,26 @@ test('with angle brackets', async () => { expect(extractions).not.toContain('>shadow-xl') expect(extractions).not.toContain('shadow-xl<') }) + +test('markdown code fences', async () => { + const extractions = defaultExtractor('') + + expect(extractions).toContain('font-bold') + expect(extractions).toContain('font-normal') + expect(extractions).not.toContain('.font-bold') + expect(extractions).not.toContain('.font-normal') +}) + +test('classes in slim templates', async () => { + const extractions = defaultExtractor(` + p.bg-red-500.text-sm + 'This is a paragraph + small.italic.text-gray-500 + '(Look mom, no closing tag!) + `) + + expect(extractions).toContain('bg-red-500') + expect(extractions).toContain('text-sm') + expect(extractions).toContain('italic') + expect(extractions).toContain('text-gray-500') +})