MCPcopy
hub / github.com/tailwindlabs/tailwindcss / substituteAtApply

Function substituteAtApply

packages/tailwindcss/src/apply.ts:10–339  ·  view source on GitHub ↗
(ast: AstNode[], designSystem: DesignSystem)

Source from the content-addressed store, hash-verified

8import { walk, WalkAction } from './walk'
9
10export function substituteAtApply(ast: AstNode[], designSystem: DesignSystem) {
11 let features = Features.None
12
13 // Wrap the whole AST in a root rule to make sure there is always a parent
14 // available for `@apply` at-rules. In some cases, the incoming `ast` just
15 // contains `@apply` at-rules which means that there is no proper parent to
16 // rely on.
17 let root = rule('&', ast)
18
19 // Track all nodes containing `@apply`
20 let parents = new Set<AstNode>()
21
22 // Track all the dependencies of an `AstNode`
23 let dependencies = new DefaultMap<AstNode, Set<string>>(() => new Set<string>())
24
25 // Track all `@utility` definitions by its root (name)
26 let definitions = new DefaultMap(() => new Set<AstNode>())
27
28 // Collect all new `@utility` definitions and all `@apply` rules first
29 walk([root], (node, ctx) => {
30 if (node.kind !== 'at-rule') return
31
32 // Do not allow `@apply` rules inside `@keyframes` rules.
33 if (node.name === '@keyframes') {
34 walk(node.nodes, (child) => {
35 if (child.kind === 'at-rule' && child.name === '@apply') {
36 throw new Error(`You cannot use \`@apply\` inside \`@keyframes\`.`)
37 }
38 })
39 return WalkAction.Skip
40 }
41
42 // `@utility` defines a utility, which is important information in order to
43 // do a correct topological sort later on.
44 if (node.name === '@utility') {
45 let name = node.params.replace(/-\*$/, '')
46 definitions.get(name).add(node)
47
48 // In case `@apply` rules are used inside `@utility` rules.
49 walk(node.nodes, (child) => {
50 if (child.kind !== 'at-rule' || child.name !== '@apply') return
51
52 parents.add(node)
53
54 for (let dependency of resolveApplyDependencies(child, designSystem)) {
55 dependencies.get(node).add(dependency)
56 }
57 })
58 return
59 }
60
61 // Any other `@apply` node.
62 if (node.name === '@apply') {
63 // `@apply` cannot be top-level, so we need to have a parent such that we
64 // can replace the `@apply` node with the actual utility classes later.
65 if (ctx.parent === null) return
66
67 features |= Features.AtApply

Callers 5

parseCssFunction · 0.90
addUtilitiesFunction · 0.90
compileFnFunction · 0.90

Calls 13

getMethod · 0.95
ruleFunction · 0.90
walkFunction · 0.90
compileCandidatesFunction · 0.90
segmentFunction · 0.90
cloneAstNodeFunction · 0.90
resolveApplyDependenciesFunction · 0.85
visitFunction · 0.70
addMethod · 0.45
hasMethod · 0.45
entriesMethod · 0.45
keysMethod · 0.45

Tested by

no test coverage detected