Skip to content

Commit

Permalink
Fix source maps of variant utilities that come from an @layer rule (#…
Browse files Browse the repository at this point in the history
…12508)

* Refactor

* Keep traversing sibling nodes

* Make sure the root node has a source location for the end

* Add source map test for at-rule variants

* Update changelog
  • Loading branch information
thecrypticace authored Dec 1, 2023
1 parent 3169d15 commit 317fba1
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 15 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Improve candidate detection in minified JS arrays (without spaces) ([#12396](https:/tailwindlabs/tailwindcss/pull/12396))
- Don't crash when given applying a variant to a negated version of a simple utility ([#12514](https:/tailwindlabs/tailwindcss/pull/12514))
- Fix support for slashes in arbitrary modifiers ([#12515](https:/tailwindlabs/tailwindcss/pull/12515))
- Fix source maps of variant utilities that come from an `@layer` rule ([#12508](https:/tailwindlabs/tailwindcss/pull/12508))
- [Oxide] Remove `autoprefixer` dependency ([#11315](https:/tailwindlabs/tailwindcss/pull/11315))
- [Oxide] Fix source maps issue resulting in a crash ([#11319](https:/tailwindlabs/tailwindcss/pull/11319))
- [Oxide] Fallback to RegEx based parser when using custom transformers or extractors ([#11335](https:/tailwindlabs/tailwindcss/pull/11335))
Expand Down
3 changes: 3 additions & 0 deletions src/lib/expandTailwindAtRules.js
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,9 @@ export default function expandTailwindAtRules(context) {
root.append(cloned)
}

// TODO: Why is the root node having no source location for `end` possible?
root.source.end = root.source.end ?? root.source.start

// If we've got a utility layer and no utilities are generated there's likely something wrong
const hasUtilityVariants = variantNodes.some(
(node) => node.raws.tailwind?.parentLayer === 'utilities'
Expand Down
49 changes: 35 additions & 14 deletions src/util/cloneNodes.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,49 @@
/**
* @param {import('postcss').Container[]} nodes
* @param {any} source
* @param {any} raws
* @returns {import('postcss').Container[]}
*/
export default function cloneNodes(nodes, source = undefined, raws = undefined) {
return nodes.map((node) => {
let cloned = node.clone()

// We always want override the source map
// except when explicitly told not to
let shouldOverwriteSource = node.raws.tailwind?.preserveSource !== true || !cloned.source

if (source !== undefined && shouldOverwriteSource) {
cloned.source = source

if ('walk' in cloned) {
cloned.walk((child) => {
child.source = source
})
}
}

if (raws !== undefined) {
cloned.raws.tailwind = {
...cloned.raws.tailwind,
...raws,
}
}

if (source !== undefined) {
traverse(cloned, (node) => {
// Do not traverse nodes that have opted
// to preserve their original source
let shouldPreserveSource = node.raws.tailwind?.preserveSource === true && node.source
if (shouldPreserveSource) {
return false
}

// Otherwise we can safely replace the source
// And continue traversing
node.source = source
})
}

return cloned
})
}

/**
* Traverse a tree of nodes and don't traverse children if the callback
* returns false. Ideally we'd use Container#walk instead of this
* function but it stops traversing siblings too.
*
* @param {import('postcss').Container} node
* @param {(node: import('postcss').Container) => boolean} onNode
*/
function traverse(node, onNode) {
if (onNode(node) !== false) {
node.each?.((child) => traverse(child, onNode))
}
}
7 changes: 6 additions & 1 deletion tests/source-maps.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ test('components have source maps', async () => {

test('source maps for layer rules are not rewritten to point to @tailwind directives', async () => {
let config = {
content: [{ raw: `font-normal foo hover:foo` }],
content: [{ raw: `font-normal foo hover:foo lg:foo` }],
}

let utilitiesFile = postcss.parse(
Expand Down Expand Up @@ -481,6 +481,11 @@ test('source maps for layer rules are not rewritten to point to @tailwind direct
"6:0 -> 6:0",
"7:2-23 -> 7:2-23",
"8:0 -> 8:0",
"10:0 -> 10:0",
"11:2 -> 11:2",
"12:4-25 -> 12:4-25",
"13:2 -> 13:2",
"14:0 -> 14:0",
]
`)
})
Expand Down

0 comments on commit 317fba1

Please sign in to comment.