From 906be6904c7549eb869411377881710328c7ccad Mon Sep 17 00:00:00 2001 From: Brad Cornes Date: Fri, 7 May 2021 12:09:01 +0100 Subject: [PATCH 1/2] add support for "raw" purge content --- src/jit/lib/expandTailwindAtRules.js | 14 +- src/jit/lib/setupContext.js | 12 +- tests/jit/raw-content.test.css | 757 +++++++++++++++++++++++++++ tests/jit/raw-content.test.html | 147 ++++++ tests/jit/raw-content.test.js | 33 ++ 5 files changed, 957 insertions(+), 6 deletions(-) create mode 100644 tests/jit/raw-content.test.css create mode 100644 tests/jit/raw-content.test.html create mode 100644 tests/jit/raw-content.test.js diff --git a/src/jit/lib/expandTailwindAtRules.js b/src/jit/lib/expandTailwindAtRules.js index 1560895b692f..9f5db9b55250 100644 --- a/src/jit/lib/expandTailwindAtRules.js +++ b/src/jit/lib/expandTailwindAtRules.js @@ -25,8 +25,13 @@ function getDefaultExtractor(fileExtension) { } } -function getExtractor(fileName, tailwindConfig) { +function getExtractor(tailwindConfig, fileName) { const purgeOptions = tailwindConfig && tailwindConfig.purge && tailwindConfig.purge.options + + if (!fileName) { + return (purgeOptions && purgeOptions.defaultExtractor) || getDefaultExtractor() + } + const fileExtension = path.extname(fileName).slice(1) if (!purgeOptions) { @@ -208,11 +213,16 @@ export default function expandTailwindAtRules(context, registerDependency) { env.DEBUG && console.time('Reading changed files') for (let file of context.changedFiles) { let content = fs.readFileSync(file, 'utf8') - let extractor = getExtractor(file, context.tailwindConfig) + let extractor = getExtractor(context.tailwindConfig, file) getClassCandidates(content, extractor, contentMatchCache, candidates, seen) } env.DEBUG && console.timeEnd('Reading changed files') + for (let content of context.rawContent) { + let extractor = getExtractor(context.tailwindConfig) + getClassCandidates(content, extractor, contentMatchCache, candidates, seen) + } + // --- // Generate the actual CSS diff --git a/src/jit/lib/setupContext.js b/src/jit/lib/setupContext.js index 844b7ede8176..2e6cf4d5b6cc 100644 --- a/src/jit/lib/setupContext.js +++ b/src/jit/lib/setupContext.js @@ -767,6 +767,10 @@ export default function setupContext(configOrPath) { process.env.DEBUG && console.log('Setting up new context...') + let purgeContent = Array.isArray(tailwindConfig.purge) + ? tailwindConfig.purge + : tailwindConfig.purge.content + let context = { changedFiles: new Set(), ruleCache: new Set(), @@ -781,10 +785,10 @@ export default function setupContext(configOrPath) { configPath: userConfigPath, tailwindConfig: tailwindConfig, configDependencies: new Set(), - candidateFiles: (Array.isArray(tailwindConfig.purge) - ? tailwindConfig.purge - : tailwindConfig.purge.content - ).map((path) => normalizePath(path)), + candidateFiles: purgeContent + .filter((item) => typeof item === 'string') + .map((path) => normalizePath(path)), + rawContent: purgeContent.filter((item) => typeof item.raw === 'string').map(({ raw }) => raw), variantMap: new Map(), stylesheetCache: null, fileModifiedMap: new Map(), diff --git a/tests/jit/raw-content.test.css b/tests/jit/raw-content.test.css new file mode 100644 index 000000000000..aec70a93c57f --- /dev/null +++ b/tests/jit/raw-content.test.css @@ -0,0 +1,757 @@ +* { + --tw-shadow: 0 0 #0000; + --tw-ring-inset: var(--tw-empty, /*!*/ /*!*/); + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgba(59, 130, 246, 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; +} +.container { + width: 100%; +} +@media (min-width: 640px) { + .container { + max-width: 640px; + } +} +@media (min-width: 768px) { + .container { + max-width: 768px; + } +} +@media (min-width: 1024px) { + .container { + max-width: 1024px; + } +} +@media (min-width: 1280px) { + .container { + max-width: 1280px; + } +} +@media (min-width: 1536px) { + .container { + max-width: 1536px; + } +} +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border-width: 0; +} +.pointer-events-none { + pointer-events: none; +} +.invisible { + visibility: hidden; +} +.absolute { + position: absolute; +} +.inset-0 { + top: 0px; + right: 0px; + bottom: 0px; + left: 0px; +} +.inset-y-4 { + top: 1rem; + bottom: 1rem; +} +.inset-x-2 { + left: 0.5rem; + right: 0.5rem; +} +.top-6 { + top: 1.5rem; +} +.right-8 { + right: 2rem; +} +.bottom-12 { + bottom: 3rem; +} +.left-16 { + left: 4rem; +} +.isolate { + isolation: isolate; +} +.isolation-auto { + isolation: auto; +} +.z-30 { + z-index: 30; +} +.order-last { + order: 9999; +} +.order-2 { + order: 2; +} +.col-span-3 { + grid-column: span 3 / span 3; +} +.col-start-1 { + grid-column-start: 1; +} +.col-end-4 { + grid-column-end: 4; +} +.row-span-2 { + grid-row: span 2 / span 2; +} +.row-start-3 { + grid-row-start: 3; +} +.row-end-5 { + grid-row-end: 5; +} +.float-right { + float: right; +} +.clear-left { + clear: left; +} +.m-4 { + margin: 1rem; +} +.my-2 { + margin-top: 0.5rem; + margin-bottom: 0.5rem; +} +.mx-auto { + margin-left: auto; + margin-right: auto; +} +.mt-0 { + margin-top: 0px; +} +.mr-1 { + margin-right: 0.25rem; +} +.mb-3 { + margin-bottom: 0.75rem; +} +.ml-4 { + margin-left: 1rem; +} +.box-border { + box-sizing: border-box; +} +.inline-grid { + display: inline-grid; +} +.hidden { + display: none; +} +.h-16 { + height: 4rem; +} +.max-h-screen { + max-height: 100vh; +} +.min-h-0 { + min-height: 0px; +} +.w-12 { + width: 3rem; +} +.min-w-min { + min-width: min-content; +} +.max-w-full { + max-width: 100%; +} +.flex-1 { + flex: 1 1 0%; +} +.flex-shrink { + flex-shrink: 1; +} +.flex-shrink-0 { + flex-shrink: 0; +} +.flex-grow { + flex-grow: 1; +} +.flex-grow-0 { + flex-grow: 0; +} +.table-fixed { + table-layout: fixed; +} +.border-collapse { + border-collapse: collapse; +} +.transform { + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + transform: translateX(var(--tw-translate-x)) translateY(var(--tw-translate-y)) + rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) + scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} +.transform-gpu { + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + transform: translate3d(var(--tw-translate-x), var(--tw-translate-y), 0) rotate(var(--tw-rotate)) + skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) + scaleY(var(--tw-scale-y)); +} +.origin-top-right { + transform-origin: top right; +} +.translate-x-5 { + --tw-translate-x: 1.25rem; +} +.-translate-x-4 { + --tw-translate-x: -1rem; +} +.translate-y-6 { + --tw-translate-y: 1.5rem; +} +.-translate-x-3 { + --tw-translate-x: -0.75rem; +} +.rotate-3 { + --tw-rotate: 3deg; +} +.skew-y-12 { + --tw-skew-y: 12deg; +} +.skew-x-12 { + --tw-skew-x: 12deg; +} +.scale-95 { + --tw-scale-x: 0.95; + --tw-scale-y: 0.95; +} +.animate-none { + animation: none; +} +@keyframes spin { + to { + transform: rotate(360deg); + } +} +.animate-spin { + animation: spin 1s linear infinite; +} +.cursor-pointer { + cursor: pointer; +} +.select-none { + user-select: none; +} +.resize-none { + resize: none; +} +.list-inside { + list-style-position: inside; +} +.list-disc { + list-style-type: disc; +} +.appearance-none { + appearance: none; +} +.auto-cols-min { + grid-auto-columns: min-content; +} +.grid-flow-row { + grid-auto-flow: row; +} +.auto-rows-max { + grid-auto-rows: max-content; +} +.grid-cols-4 { + grid-template-columns: repeat(4, minmax(0, 1fr)); +} +.grid-rows-3 { + grid-template-rows: repeat(3, minmax(0, 1fr)); +} +.flex-row-reverse { + flex-direction: row-reverse; +} +.flex-wrap { + flex-wrap: wrap; +} +.place-content-start { + place-content: start; +} +.place-items-end { + place-items: end; +} +.content-center { + align-content: center; +} +.items-start { + align-items: flex-start; +} +.justify-center { + justify-content: center; +} +.justify-items-end { + justify-items: end; +} +.gap-4 { + gap: 1rem; +} +.gap-x-2 { + column-gap: 0.5rem; +} +.gap-y-3 { + row-gap: 0.75rem; +} +.space-x-4 > :not([hidden]) ~ :not([hidden]) { + --tw-space-x-reverse: 0; + margin-right: calc(1rem * var(--tw-space-x-reverse)); + margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse))); +} +.space-y-3 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(0.75rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(0.75rem * var(--tw-space-y-reverse)); +} +.space-y-reverse > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 1; +} +.space-x-reverse > :not([hidden]) ~ :not([hidden]) { + --tw-space-x-reverse: 1; +} +.divide-x-2 > :not([hidden]) ~ :not([hidden]) { + --tw-divide-x-reverse: 0; + border-right-width: calc(2px * var(--tw-divide-x-reverse)); + border-left-width: calc(2px * calc(1 - var(--tw-divide-x-reverse))); +} +.divide-y-4 > :not([hidden]) ~ :not([hidden]) { + --tw-divide-y-reverse: 0; + border-top-width: calc(4px * calc(1 - var(--tw-divide-y-reverse))); + border-bottom-width: calc(4px * var(--tw-divide-y-reverse)); +} +.divide-x-0 > :not([hidden]) ~ :not([hidden]) { + --tw-divide-x-reverse: 0; + border-right-width: calc(0px * var(--tw-divide-x-reverse)); + border-left-width: calc(0px * calc(1 - var(--tw-divide-x-reverse))); +} +.divide-y-0 > :not([hidden]) ~ :not([hidden]) { + --tw-divide-y-reverse: 0; + border-top-width: calc(0px * calc(1 - var(--tw-divide-y-reverse))); + border-bottom-width: calc(0px * var(--tw-divide-y-reverse)); +} +.divide-dotted > :not([hidden]) ~ :not([hidden]) { + border-style: dotted; +} +.divide-gray-200 > :not([hidden]) ~ :not([hidden]) { + --tw-divide-opacity: 1; + border-color: rgba(229, 231, 235, var(--tw-divide-opacity)); +} +.divide-opacity-50 > :not([hidden]) ~ :not([hidden]) { + --tw-divide-opacity: 0.5; +} +.place-self-center { + place-self: center; +} +.self-end { + align-self: flex-end; +} +.justify-self-start { + justify-self: start; +} +.overflow-hidden { + overflow: hidden; +} +.overscroll-contain { + overscroll-behavior: contain; +} +.truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.overflow-ellipsis { + text-overflow: ellipsis; +} +.whitespace-nowrap { + white-space: nowrap; +} +.break-words { + overflow-wrap: break-word; +} +.rounded-md { + border-radius: 0.375rem; +} +.border { + border-width: 1px; +} +.border-2 { + border-width: 2px; +} +.border-solid { + border-style: solid; +} +.border-black { + --tw-border-opacity: 1; + border-color: rgba(0, 0, 0, var(--tw-border-opacity)); +} +.border-opacity-10 { + --tw-border-opacity: 0.1; +} +.bg-green-500 { + --tw-bg-opacity: 1; + background-color: rgba(16, 185, 129, var(--tw-bg-opacity)); +} +.bg-opacity-20 { + --tw-bg-opacity: 0.2; +} +.bg-gradient-to-r { + background-image: linear-gradient(to right, var(--tw-gradient-stops)); +} +.from-red-300 { + --tw-gradient-from: #fca5a5; + --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to, rgba(252, 165, 165, 0)); +} +.via-purple-200 { + --tw-gradient-stops: var(--tw-gradient-from), #ddd6fe, + var(--tw-gradient-to, rgba(221, 214, 254, 0)); +} +.to-blue-400 { + --tw-gradient-to: #60a5fa; +} +.decoration-slice { + box-decoration-break: slice; +} +.decoration-clone { + box-decoration-break: clone; +} +.bg-cover { + background-size: cover; +} +.bg-local { + background-attachment: local; +} +.bg-clip-border { + background-clip: border-box; +} +.bg-top { + background-position: top; +} +.bg-no-repeat { + background-repeat: no-repeat; +} +.bg-origin-border { + background-origin: border-box; +} +.bg-origin-padding { + background-origin: padding-box; +} +.bg-origin-content { + background-origin: content-box; +} +.fill-current { + fill: currentColor; +} +.stroke-current { + stroke: currentColor; +} +.stroke-2 { + stroke-width: 2; +} +.object-cover { + object-fit: cover; +} +.object-bottom { + object-position: bottom; +} +.p-4 { + padding: 1rem; +} +.py-2 { + padding-top: 0.5rem; + padding-bottom: 0.5rem; +} +.px-3 { + padding-left: 0.75rem; + padding-right: 0.75rem; +} +.pt-1 { + padding-top: 0.25rem; +} +.pr-2 { + padding-right: 0.5rem; +} +.pb-3 { + padding-bottom: 0.75rem; +} +.pl-4 { + padding-left: 1rem; +} +.text-center { + text-align: center; +} +.align-middle { + vertical-align: middle; +} +.font-sans { + font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, + 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', + 'Segoe UI Symbol', 'Noto Color Emoji'; +} +.text-2xl { + font-size: 1.5rem; + line-height: 2rem; +} +.font-medium { + font-weight: 500; +} +.uppercase { + text-transform: uppercase; +} +.not-italic { + font-style: normal; +} +.ordinal, +.slashed-zero, +.lining-nums, +.oldstyle-nums, +.proportional-nums, +.tabular-nums, +.diagonal-fractions, +.stacked-fractions { + --tw-ordinal: var(--tw-empty, /*!*/ /*!*/); + --tw-slashed-zero: var(--tw-empty, /*!*/ /*!*/); + --tw-numeric-figure: var(--tw-empty, /*!*/ /*!*/); + --tw-numeric-spacing: var(--tw-empty, /*!*/ /*!*/); + --tw-numeric-fraction: var(--tw-empty, /*!*/ /*!*/); + font-variant-numeric: var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) + var(--tw-numeric-spacing) var(--tw-numeric-fraction); +} +.ordinal { + --tw-ordinal: ordinal; +} +.tabular-nums { + --tw-numeric-spacing: tabular-nums; +} +.diagonal-fractions { + --tw-numeric-fraction: diagonal-fractions; +} +.leading-relaxed { + line-height: 1.625; +} +.leading-5 { + line-height: 1.25rem; +} +.tracking-tight { + letter-spacing: -0.025em; +} +.text-indigo-500 { + --tw-text-opacity: 1; + color: rgba(99, 102, 241, var(--tw-text-opacity)); +} +.text-opacity-10 { + --tw-text-opacity: 0.1; +} +.underline { + text-decoration: underline; +} +.antialiased { + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +.placeholder-green-300::placeholder { + --tw-placeholder-opacity: 1; + color: rgba(110, 231, 183, var(--tw-placeholder-opacity)); +} +.placeholder-opacity-60::placeholder { + --tw-placeholder-opacity: 0.6; +} +.opacity-90 { + opacity: 0.9; +} +.bg-blend-darken { + background-blend-mode: darken; +} +.bg-blend-difference { + background-blend-mode: difference; +} +.mix-blend-multiply { + mix-blend-mode: multiply; +} +.mix-blend-saturation { + mix-blend-mode: saturation; +} +.shadow { + --tw-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), + var(--tw-shadow); +} +.shadow-md { + --tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), + var(--tw-shadow); +} +.shadow-lg { + --tw-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), + var(--tw-shadow); +} +.outline-none { + outline: 2px solid transparent; + outline-offset: 2px; +} +.outline-black { + outline: 2px dotted black; + outline-offset: 2px; +} +.ring { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) + var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) + var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); +} +.ring-4 { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) + var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(4px + var(--tw-ring-offset-width)) + var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); +} +.ring-white { + --tw-ring-opacity: 1; + --tw-ring-color: rgba(255, 255, 255, var(--tw-ring-opacity)); +} +.ring-opacity-40 { + --tw-ring-opacity: 0.4; +} +.ring-offset-2 { + --tw-ring-offset-width: 2px; +} +.ring-offset-blue-300 { + --tw-ring-offset-color: #93c5fd; +} +.filter { + --tw-blur: var(--tw-empty, /*!*/ /*!*/); + --tw-brightness: var(--tw-empty, /*!*/ /*!*/); + --tw-contrast: var(--tw-empty, /*!*/ /*!*/); + --tw-grayscale: var(--tw-empty, /*!*/ /*!*/); + --tw-hue-rotate: var(--tw-empty, /*!*/ /*!*/); + --tw-invert: var(--tw-empty, /*!*/ /*!*/); + --tw-saturate: var(--tw-empty, /*!*/ /*!*/); + --tw-sepia: var(--tw-empty, /*!*/ /*!*/); + --tw-drop-shadow: var(--tw-empty, /*!*/ /*!*/); + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) + var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); +} +.filter-none { + filter: none; +} +.blur-md { + --tw-blur: blur(12px); +} +.brightness-150 { + --tw-brightness: brightness(1.5); +} +.contrast-50 { + --tw-contrast: contrast(0.5); +} +.drop-shadow-md { + --tw-drop-shadow: drop-shadow(0 4px 3px rgba(0, 0, 0, 0.07)) + drop-shadow(0 2px 2px rgba(0, 0, 0, 0.06)); +} +.grayscale { + --tw-grayscale: grayscale(100%); +} +.hue-rotate-60 { + --tw-hue-rotate: hue-rotate(60deg); +} +.invert { + --tw-invert: invert(100%); +} +.saturate-200 { + --tw-saturate: saturate(2); +} +.sepia { + --tw-sepia: sepia(100%); +} +.backdrop-filter { + --tw-backdrop-blur: var(--tw-empty, /*!*/ /*!*/); + --tw-backdrop-brightness: var(--tw-empty, /*!*/ /*!*/); + --tw-backdrop-contrast: var(--tw-empty, /*!*/ /*!*/); + --tw-backdrop-grayscale: var(--tw-empty, /*!*/ /*!*/); + --tw-backdrop-hue-rotate: var(--tw-empty, /*!*/ /*!*/); + --tw-backdrop-invert: var(--tw-empty, /*!*/ /*!*/); + --tw-backdrop-opacity: var(--tw-empty, /*!*/ /*!*/); + --tw-backdrop-saturate: var(--tw-empty, /*!*/ /*!*/); + --tw-backdrop-sepia: var(--tw-empty, /*!*/ /*!*/); + backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) + var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) + var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); +} +.backdrop-filter-none { + backdrop-filter: none; +} +.backdrop-blur-lg { + --tw-backdrop-blur: blur(16px); +} +.backdrop-brightness-50 { + --tw-backdrop-brightness: brightness(0.5); +} +.backdrop-contrast-0 { + --tw-backdrop-contrast: contrast(0); +} +.backdrop-grayscale { + --tw-backdrop-grayscale: grayscale(100%); +} +.backdrop-hue-rotate-90 { + --tw-backdrop-hue-rotate: hue-rotate(90deg); +} +.backdrop-invert { + --tw-backdrop-invert: invert(100%); +} +.backdrop-opacity-75 { + --tw-backdrop-opacity: opacity(0.75); +} +.backdrop-saturate-150 { + --tw-backdrop-saturate: saturate(1.5); +} +.backdrop-sepia { + --tw-backdrop-sepia: sepia(100%); +} +.transition { + transition-property: background-color, border-color, color, fill, stroke, opacity, box-shadow, + transform, filter, backdrop-filter; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} +.transition-all { + transition-property: all; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} +.delay-300 { + transition-delay: 300ms; +} +.duration-200 { + transition-duration: 200ms; +} +.ease-in-out { + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} diff --git a/tests/jit/raw-content.test.html b/tests/jit/raw-content.test.html new file mode 100644 index 000000000000..1e97f5fdf4ce --- /dev/null +++ b/tests/jit/raw-content.test.html @@ -0,0 +1,147 @@ + + + + + + + Title + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+ + diff --git a/tests/jit/raw-content.test.js b/tests/jit/raw-content.test.js new file mode 100644 index 000000000000..e4509c57ec06 --- /dev/null +++ b/tests/jit/raw-content.test.js @@ -0,0 +1,33 @@ +import postcss from 'postcss' +import fs from 'fs' +import path from 'path' +import tailwind from '../../src/jit/index.js' + +function run(input, config = {}) { + return postcss(tailwind(config)).process(input, { + from: path.resolve(__filename), + }) +} + +test('raw content', () => { + let config = { + mode: 'jit', + purge: [{ raw: fs.readFileSync(path.resolve(__dirname, './raw-content.test.html'), 'utf8') }], + corePlugins: { preflight: false }, + theme: {}, + plugins: [], + } + + let css = ` + @tailwind base; + @tailwind components; + @tailwind utilities; + ` + + return run(css, config).then((result) => { + let expectedPath = path.resolve(__dirname, './raw-content.test.css') + let expected = fs.readFileSync(expectedPath, 'utf8') + + expect(result.css).toMatchFormattedCss(expected) + }) +}) From a0b2de7fa183f0d15b5a564f8caf3ffc05337026 Mon Sep 17 00:00:00 2001 From: Brad Cornes Date: Fri, 7 May 2021 12:29:08 +0100 Subject: [PATCH 2/2] add support for raw content extensions --- src/jit/lib/expandTailwindAtRules.js | 12 +++--- src/jit/lib/setupContext.js | 4 +- tests/jit/raw-content.test.js | 58 ++++++++++++++++++++++++++-- 3 files changed, 63 insertions(+), 11 deletions(-) diff --git a/src/jit/lib/expandTailwindAtRules.js b/src/jit/lib/expandTailwindAtRules.js index 9f5db9b55250..cd528f1c0f47 100644 --- a/src/jit/lib/expandTailwindAtRules.js +++ b/src/jit/lib/expandTailwindAtRules.js @@ -25,15 +25,13 @@ function getDefaultExtractor(fileExtension) { } } -function getExtractor(tailwindConfig, fileName) { +function getExtractor(tailwindConfig, fileExtension) { const purgeOptions = tailwindConfig && tailwindConfig.purge && tailwindConfig.purge.options - if (!fileName) { + if (!fileExtension) { return (purgeOptions && purgeOptions.defaultExtractor) || getDefaultExtractor() } - const fileExtension = path.extname(fileName).slice(1) - if (!purgeOptions) { return getDefaultExtractor(fileExtension) } @@ -213,13 +211,13 @@ export default function expandTailwindAtRules(context, registerDependency) { env.DEBUG && console.time('Reading changed files') for (let file of context.changedFiles) { let content = fs.readFileSync(file, 'utf8') - let extractor = getExtractor(context.tailwindConfig, file) + let extractor = getExtractor(context.tailwindConfig, path.extname(file).slice(1)) getClassCandidates(content, extractor, contentMatchCache, candidates, seen) } env.DEBUG && console.timeEnd('Reading changed files') - for (let content of context.rawContent) { - let extractor = getExtractor(context.tailwindConfig) + for (let { content, extension } of context.rawContent) { + let extractor = getExtractor(context.tailwindConfig, extension) getClassCandidates(content, extractor, contentMatchCache, candidates, seen) } diff --git a/src/jit/lib/setupContext.js b/src/jit/lib/setupContext.js index 2e6cf4d5b6cc..4b5aae4df755 100644 --- a/src/jit/lib/setupContext.js +++ b/src/jit/lib/setupContext.js @@ -788,7 +788,9 @@ export default function setupContext(configOrPath) { candidateFiles: purgeContent .filter((item) => typeof item === 'string') .map((path) => normalizePath(path)), - rawContent: purgeContent.filter((item) => typeof item.raw === 'string').map(({ raw }) => raw), + rawContent: purgeContent + .filter((item) => typeof item.raw === 'string') + .map(({ raw, extension }) => ({ content: raw, extension })), variantMap: new Map(), stylesheetCache: null, fileModifiedMap: new Map(), diff --git a/tests/jit/raw-content.test.js b/tests/jit/raw-content.test.js index e4509c57ec06..b699a22ab5d6 100644 --- a/tests/jit/raw-content.test.js +++ b/tests/jit/raw-content.test.js @@ -1,15 +1,20 @@ import postcss from 'postcss' import fs from 'fs' import path from 'path' -import tailwind from '../../src/jit/index.js' -function run(input, config = {}) { +beforeEach(() => { + jest.resetModules() +}) + +function run(tailwind, input, config = {}) { return postcss(tailwind(config)).process(input, { from: path.resolve(__filename), }) } test('raw content', () => { + let tailwind = require('../../src/jit/index.js').default + let config = { mode: 'jit', purge: [{ raw: fs.readFileSync(path.resolve(__dirname, './raw-content.test.html'), 'utf8') }], @@ -24,10 +29,57 @@ test('raw content', () => { @tailwind utilities; ` - return run(css, config).then((result) => { + return run(tailwind, css, config).then((result) => { let expectedPath = path.resolve(__dirname, './raw-content.test.css') let expected = fs.readFileSync(expectedPath, 'utf8') expect(result.css).toMatchFormattedCss(expected) }) }) + +test('raw content with extension', () => { + let tailwind = require('../../src/jit/index.js').default + + let config = { + mode: 'jit', + purge: { + content: [ + { + raw: fs.readFileSync(path.resolve(__dirname, './raw-content.test.html'), 'utf8'), + extension: 'html', + }, + ], + options: { + extractors: [ + { + extractor: () => [], + extensions: ['html'], + }, + ], + }, + }, + corePlugins: { preflight: false }, + theme: {}, + plugins: [], + } + + let css = ` + @tailwind base; + @tailwind components; + @tailwind utilities; + ` + + return run(tailwind, css, config).then((result) => { + expect(result.css).toMatchFormattedCss(` + * { + --tw-shadow: 0 0 #0000; + --tw-ring-inset: var(--tw-empty, /*!*/ /*!*/); + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgba(59, 130, 246, 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + } + `) + }) +})