tailwindcss 0.0.0-insiders.e2d5f21 → 0.0.0-insiders.e302ef1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +244 -3
- package/LICENSE +1 -2
- package/README.md +8 -4
- package/colors.js +2 -1
- package/defaultConfig.js +2 -1
- package/defaultTheme.js +2 -1
- package/lib/cli.js +123 -88
- package/lib/corePlugins.js +288 -360
- package/lib/css/preflight.css +4 -4
- package/lib/featureFlags.js +4 -5
- package/lib/index.js +12 -3
- package/lib/lib/cacheInvalidation.js +69 -0
- package/lib/lib/collapseAdjacentRules.js +14 -1
- package/lib/lib/collapseDuplicateDeclarations.js +52 -1
- package/lib/lib/defaultExtractor.js +44 -0
- package/lib/lib/evaluateTailwindFunctions.js +1 -1
- package/lib/lib/expandApplyAtRules.js +265 -60
- package/lib/lib/expandTailwindAtRules.js +63 -48
- package/lib/lib/generateRules.js +136 -34
- package/lib/lib/normalizeTailwindDirectives.js +10 -2
- package/lib/lib/partitionApplyAtRules.js +53 -0
- package/lib/lib/resolveDefaultsAtRules.js +30 -12
- package/lib/lib/setupContextUtils.js +137 -81
- package/lib/lib/setupTrackingContext.js +8 -7
- package/lib/lib/sharedState.js +38 -5
- package/{nesting → lib/postcss-plugins/nesting}/README.md +0 -0
- package/lib/postcss-plugins/nesting/index.js +17 -0
- package/lib/postcss-plugins/nesting/plugin.js +85 -0
- package/lib/processTailwindFeatures.js +10 -2
- package/lib/util/cloneNodes.js +12 -1
- package/lib/util/color.js +23 -8
- package/lib/util/createPlugin.js +1 -2
- package/lib/util/createUtilityPlugin.js +4 -8
- package/lib/util/dataTypes.js +4 -2
- package/lib/util/defaults.js +6 -0
- package/lib/util/flattenColorPalette.js +1 -3
- package/lib/util/log.js +10 -6
- package/lib/util/normalizeConfig.js +47 -15
- package/lib/util/normalizeScreens.js +6 -5
- package/lib/util/parseBoxShadowValue.js +44 -4
- package/lib/util/pluginUtils.js +6 -13
- package/lib/util/prefixSelector.js +4 -5
- package/lib/util/resolveConfig.js +48 -27
- package/lib/util/resolveConfigPath.js +1 -2
- package/lib/util/toColorValue.js +1 -2
- package/lib/util/toPath.js +6 -1
- package/lib/util/transformThemeValue.js +4 -8
- package/nesting/index.js +2 -12
- package/package.json +28 -33
- package/peers/index.js +3209 -4239
- package/plugin.js +2 -1
- package/resolveConfig.js +2 -1
- package/src/cli.js +62 -15
- package/src/corePlugins.js +212 -217
- package/src/css/preflight.css +4 -4
- package/src/featureFlags.js +3 -3
- package/src/index.js +14 -6
- package/src/lib/cacheInvalidation.js +52 -0
- package/src/lib/collapseAdjacentRules.js +16 -1
- package/src/lib/collapseDuplicateDeclarations.js +66 -1
- package/src/lib/defaultExtractor.js +50 -0
- package/src/lib/evaluateTailwindFunctions.js +1 -1
- package/src/lib/expandApplyAtRules.js +285 -56
- package/src/lib/expandTailwindAtRules.js +75 -37
- package/src/lib/generateRules.js +121 -27
- package/src/lib/normalizeTailwindDirectives.js +7 -1
- package/src/lib/partitionApplyAtRules.js +52 -0
- package/src/lib/resolveDefaultsAtRules.js +35 -10
- package/src/lib/setupContextUtils.js +127 -45
- package/src/lib/setupTrackingContext.js +8 -7
- package/src/lib/sharedState.js +42 -4
- package/src/postcss-plugins/nesting/README.md +42 -0
- package/src/postcss-plugins/nesting/index.js +13 -0
- package/src/postcss-plugins/nesting/plugin.js +80 -0
- package/src/processTailwindFeatures.js +12 -2
- package/src/util/cloneNodes.js +14 -1
- package/src/util/color.js +20 -7
- package/src/util/dataTypes.js +7 -5
- package/src/util/defaults.js +6 -0
- package/src/util/log.js +10 -6
- package/src/util/normalizeConfig.js +24 -3
- package/src/util/normalizeScreens.js +6 -3
- package/src/util/parseBoxShadowValue.js +51 -3
- package/src/util/pluginUtils.js +1 -1
- package/src/util/prefixSelector.js +7 -5
- package/src/util/resolveConfig.js +41 -1
- package/src/util/toPath.js +23 -1
- package/stubs/defaultConfig.stub.js +2 -2
- package/lib/lib/setupWatchingContext.js +0 -288
- package/nesting/plugin.js +0 -41
- package/src/lib/setupWatchingContext.js +0 -311
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
});
|
|
5
5
|
exports.default = expandApplyAtRules;
|
|
6
6
|
var _postcss = _interopRequireDefault(require("postcss"));
|
|
7
|
+
var _postcssSelectorParser = _interopRequireDefault(require("postcss-selector-parser"));
|
|
7
8
|
var _generateRules = require("./generateRules");
|
|
8
9
|
var _bigSign = _interopRequireDefault(require("../util/bigSign"));
|
|
9
10
|
var _escapeClassName = _interopRequireDefault(require("../util/escapeClassName"));
|
|
@@ -12,11 +13,141 @@ function _interopRequireDefault(obj) {
|
|
|
12
13
|
default: obj
|
|
13
14
|
};
|
|
14
15
|
}
|
|
15
|
-
|
|
16
|
-
let
|
|
17
|
-
|
|
16
|
+
/** @typedef {Map<string, [any, import('postcss').Rule[]]>} ApplyCache */ function extractClasses(node) {
|
|
17
|
+
let classes = new Set();
|
|
18
|
+
let container = _postcss.default.root({
|
|
19
|
+
nodes: [
|
|
20
|
+
node.clone()
|
|
21
|
+
]
|
|
22
|
+
});
|
|
23
|
+
container.walkRules((rule)=>{
|
|
24
|
+
(0, _postcssSelectorParser).default((selectors)=>{
|
|
25
|
+
selectors.walkClasses((classSelector)=>{
|
|
26
|
+
classes.add(classSelector.value);
|
|
27
|
+
});
|
|
28
|
+
}).processSync(rule.selector);
|
|
29
|
+
});
|
|
30
|
+
return Array.from(classes);
|
|
31
|
+
}
|
|
32
|
+
function extractBaseCandidates(candidates, separator) {
|
|
33
|
+
let baseClasses = new Set();
|
|
34
|
+
for (let candidate of candidates){
|
|
35
|
+
baseClasses.add(candidate.split(separator).pop());
|
|
36
|
+
}
|
|
37
|
+
return Array.from(baseClasses);
|
|
38
|
+
}
|
|
39
|
+
function prefix(context, selector) {
|
|
40
|
+
let prefix1 = context.tailwindConfig.prefix;
|
|
41
|
+
return typeof prefix1 === 'function' ? prefix1(selector) : prefix1 + selector;
|
|
18
42
|
}
|
|
19
|
-
function
|
|
43
|
+
function* pathToRoot(node) {
|
|
44
|
+
yield node;
|
|
45
|
+
while(node.parent){
|
|
46
|
+
yield node.parent;
|
|
47
|
+
node = node.parent;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Only clone the node itself and not its children
|
|
52
|
+
*
|
|
53
|
+
* @param {*} node
|
|
54
|
+
* @param {*} overrides
|
|
55
|
+
* @returns
|
|
56
|
+
*/ function shallowClone(node, overrides = {}) {
|
|
57
|
+
let children = node.nodes;
|
|
58
|
+
node.nodes = [];
|
|
59
|
+
let tmp = node.clone(overrides);
|
|
60
|
+
node.nodes = children;
|
|
61
|
+
return tmp;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Clone just the nodes all the way to the top that are required to represent
|
|
65
|
+
* this singular rule in the tree.
|
|
66
|
+
*
|
|
67
|
+
* For example, if we have CSS like this:
|
|
68
|
+
* ```css
|
|
69
|
+
* @media (min-width: 768px) {
|
|
70
|
+
* @supports (display: grid) {
|
|
71
|
+
* .foo {
|
|
72
|
+
* display: grid;
|
|
73
|
+
* grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
74
|
+
* }
|
|
75
|
+
* }
|
|
76
|
+
*
|
|
77
|
+
* @supports (backdrop-filter: blur(1px)) {
|
|
78
|
+
* .bar {
|
|
79
|
+
* backdrop-filter: blur(1px);
|
|
80
|
+
* }
|
|
81
|
+
* }
|
|
82
|
+
*
|
|
83
|
+
* .baz {
|
|
84
|
+
* color: orange;
|
|
85
|
+
* }
|
|
86
|
+
* }
|
|
87
|
+
* ```
|
|
88
|
+
*
|
|
89
|
+
* And we're cloning `.bar` it'll return a cloned version of what's required for just that single node:
|
|
90
|
+
*
|
|
91
|
+
* ```css
|
|
92
|
+
* @media (min-width: 768px) {
|
|
93
|
+
* @supports (backdrop-filter: blur(1px)) {
|
|
94
|
+
* .bar {
|
|
95
|
+
* backdrop-filter: blur(1px);
|
|
96
|
+
* }
|
|
97
|
+
* }
|
|
98
|
+
* }
|
|
99
|
+
* ```
|
|
100
|
+
*
|
|
101
|
+
* @param {import('postcss').Node} node
|
|
102
|
+
*/ function nestedClone(node) {
|
|
103
|
+
for (let parent of pathToRoot(node)){
|
|
104
|
+
if (node === parent) {
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
if (parent.type === 'root') {
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
node = shallowClone(parent, {
|
|
111
|
+
nodes: [
|
|
112
|
+
node
|
|
113
|
+
]
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
return node;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* @param {import('postcss').Root} root
|
|
120
|
+
*/ function buildLocalApplyCache(root, context) {
|
|
121
|
+
/** @type {ApplyCache} */ let cache = new Map();
|
|
122
|
+
let highestOffset = context.layerOrder.user >> 4n;
|
|
123
|
+
root.walkRules((rule, idx)=>{
|
|
124
|
+
// Ignore rules generated by Tailwind
|
|
125
|
+
for (let node of pathToRoot(rule)){
|
|
126
|
+
var ref;
|
|
127
|
+
if (((ref = node.raws.tailwind) === null || ref === void 0 ? void 0 : ref.layer) !== undefined) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// Clone what's required to represent this singular rule in the tree
|
|
132
|
+
let container = nestedClone(rule);
|
|
133
|
+
for (let className of extractClasses(rule)){
|
|
134
|
+
let list = cache.get(className) || [];
|
|
135
|
+
cache.set(className, list);
|
|
136
|
+
list.push([
|
|
137
|
+
{
|
|
138
|
+
layer: 'user',
|
|
139
|
+
sort: BigInt(idx) + highestOffset,
|
|
140
|
+
important: false
|
|
141
|
+
},
|
|
142
|
+
container,
|
|
143
|
+
]);
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
return cache;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* @returns {ApplyCache}
|
|
150
|
+
*/ function buildApplyCache(applyCandidates, context) {
|
|
20
151
|
for (let candidate of applyCandidates){
|
|
21
152
|
if (context.notClassCache.has(candidate) || context.applyClassCache.has(candidate)) {
|
|
22
153
|
continue;
|
|
@@ -38,6 +169,39 @@ function buildApplyCache(applyCandidates, context) {
|
|
|
38
169
|
}
|
|
39
170
|
return context.applyClassCache;
|
|
40
171
|
}
|
|
172
|
+
/**
|
|
173
|
+
* Build a cache only when it's first used
|
|
174
|
+
*
|
|
175
|
+
* @param {() => ApplyCache} buildCacheFn
|
|
176
|
+
* @returns {ApplyCache}
|
|
177
|
+
*/ function lazyCache(buildCacheFn) {
|
|
178
|
+
let cache = null;
|
|
179
|
+
return {
|
|
180
|
+
get: (name)=>{
|
|
181
|
+
cache = cache || buildCacheFn();
|
|
182
|
+
return cache.get(name);
|
|
183
|
+
},
|
|
184
|
+
has: (name)=>{
|
|
185
|
+
cache = cache || buildCacheFn();
|
|
186
|
+
return cache.has(name);
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Take a series of multiple caches and merge
|
|
192
|
+
* them so they act like one large cache
|
|
193
|
+
*
|
|
194
|
+
* @param {ApplyCache[]} caches
|
|
195
|
+
* @returns {ApplyCache}
|
|
196
|
+
*/ function combineCaches(caches) {
|
|
197
|
+
return {
|
|
198
|
+
get: (name)=>caches.flatMap((cache)=>cache.get(name) || []
|
|
199
|
+
)
|
|
200
|
+
,
|
|
201
|
+
has: (name)=>caches.some((cache)=>cache.has(name)
|
|
202
|
+
)
|
|
203
|
+
};
|
|
204
|
+
}
|
|
41
205
|
function extractApplyCandidates(params) {
|
|
42
206
|
let candidates = params.split(/[\s\t\n]+/g);
|
|
43
207
|
if (candidates[candidates.length - 1] === '!important') {
|
|
@@ -51,46 +215,7 @@ function extractApplyCandidates(params) {
|
|
|
51
215
|
false
|
|
52
216
|
];
|
|
53
217
|
}
|
|
54
|
-
function
|
|
55
|
-
let applyParents = new Set();
|
|
56
|
-
root.walkAtRules('apply', (rule)=>{
|
|
57
|
-
applyParents.add(rule.parent);
|
|
58
|
-
});
|
|
59
|
-
for (let rule1 of applyParents){
|
|
60
|
-
let nodeGroups = [];
|
|
61
|
-
let lastGroup = [];
|
|
62
|
-
for (let node of rule1.nodes){
|
|
63
|
-
if (node.type === 'atrule' && node.name === 'apply') {
|
|
64
|
-
if (lastGroup.length > 0) {
|
|
65
|
-
nodeGroups.push(lastGroup);
|
|
66
|
-
lastGroup = [];
|
|
67
|
-
}
|
|
68
|
-
nodeGroups.push([
|
|
69
|
-
node
|
|
70
|
-
]);
|
|
71
|
-
} else {
|
|
72
|
-
lastGroup.push(node);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
if (lastGroup.length > 0) {
|
|
76
|
-
nodeGroups.push(lastGroup);
|
|
77
|
-
}
|
|
78
|
-
if (nodeGroups.length === 1) {
|
|
79
|
-
continue;
|
|
80
|
-
}
|
|
81
|
-
for (let group of [
|
|
82
|
-
...nodeGroups
|
|
83
|
-
].reverse()){
|
|
84
|
-
let newParent = rule1.clone({
|
|
85
|
-
nodes: []
|
|
86
|
-
});
|
|
87
|
-
newParent.append(group);
|
|
88
|
-
rule1.after(newParent);
|
|
89
|
-
}
|
|
90
|
-
rule1.remove();
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
function processApply(root, context) {
|
|
218
|
+
function processApply(root, context, localCache) {
|
|
94
219
|
let applyCandidates = new Set();
|
|
95
220
|
// Collect all @apply rules and candidates
|
|
96
221
|
let applies = [];
|
|
@@ -104,7 +229,10 @@ function processApply(root, context) {
|
|
|
104
229
|
// Start the @apply process if we have rules with @apply in them
|
|
105
230
|
if (applies.length > 0) {
|
|
106
231
|
// Fill up some caches!
|
|
107
|
-
let applyClassCache =
|
|
232
|
+
let applyClassCache = combineCaches([
|
|
233
|
+
localCache,
|
|
234
|
+
buildApplyCache(applyCandidates, context)
|
|
235
|
+
]);
|
|
108
236
|
/**
|
|
109
237
|
* When we have an apply like this:
|
|
110
238
|
*
|
|
@@ -127,8 +255,8 @@ function processApply(root, context) {
|
|
|
127
255
|
*/ // TODO: Should we use postcss-selector-parser for this instead?
|
|
128
256
|
function replaceSelector(selector, utilitySelectors, candidate) {
|
|
129
257
|
let needle = `.${(0, _escapeClassName).default(candidate)}`;
|
|
130
|
-
let utilitySelectorsList = utilitySelectors.split(/\s
|
|
131
|
-
return selector.split(/\s
|
|
258
|
+
let utilitySelectorsList = utilitySelectors.split(/\s*\,(?![^(]*\))\s*/g);
|
|
259
|
+
return selector.split(/\s*\,(?![^(]*\))\s*/g).map((s)=>{
|
|
132
260
|
let replaced = [];
|
|
133
261
|
for (let utilitySelector of utilitySelectorsList){
|
|
134
262
|
let replacedSelector = utilitySelector.replace(needle, s);
|
|
@@ -144,7 +272,10 @@ function processApply(root, context) {
|
|
|
144
272
|
// Collect all apply candidates and their rules
|
|
145
273
|
for (let apply of applies){
|
|
146
274
|
let candidates = perParentApplies.get(apply.parent) || [];
|
|
147
|
-
perParentApplies.set(apply.parent,
|
|
275
|
+
perParentApplies.set(apply.parent, [
|
|
276
|
+
candidates,
|
|
277
|
+
apply.source
|
|
278
|
+
]);
|
|
148
279
|
let [applyCandidates, important] = extractApplyCandidates(apply.params);
|
|
149
280
|
if (apply.parent.type === 'atrule') {
|
|
150
281
|
if (apply.parent.name === 'screen') {
|
|
@@ -155,11 +286,14 @@ function processApply(root, context) {
|
|
|
155
286
|
throw apply.error(`@apply is not supported within nested at-rules like @${apply.parent.name}. You can fix this by un-nesting @${apply.parent.name}.`);
|
|
156
287
|
}
|
|
157
288
|
for (let applyCandidate of applyCandidates){
|
|
289
|
+
if ([
|
|
290
|
+
prefix(context, 'group'),
|
|
291
|
+
prefix(context, 'peer')
|
|
292
|
+
].includes(applyCandidate)) {
|
|
293
|
+
// TODO: Link to specific documentation page with error code.
|
|
294
|
+
throw apply.error(`@apply should not be used with the '${applyCandidate}' utility`);
|
|
295
|
+
}
|
|
158
296
|
if (!applyClassCache.has(applyCandidate)) {
|
|
159
|
-
if (applyCandidate === prefix1(context, 'group')) {
|
|
160
|
-
// TODO: Link to specific documentation page with error code.
|
|
161
|
-
throw apply.error(`@apply should not be used with the '${applyCandidate}' utility`);
|
|
162
|
-
}
|
|
163
297
|
throw apply.error(`The \`${applyCandidate}\` class does not exist. If \`${applyCandidate}\` is a custom class, make sure it is defined within a \`@layer\` directive.`);
|
|
164
298
|
}
|
|
165
299
|
let rules = applyClassCache.get(applyCandidate);
|
|
@@ -170,18 +304,88 @@ function processApply(root, context) {
|
|
|
170
304
|
]);
|
|
171
305
|
}
|
|
172
306
|
}
|
|
173
|
-
for (const [parent, candidates] of perParentApplies){
|
|
307
|
+
for (const [parent, [candidates, atApplySource]] of perParentApplies){
|
|
174
308
|
let siblings = [];
|
|
175
309
|
for (let [applyCandidate, important, rules] of candidates){
|
|
176
|
-
for (let [meta,
|
|
310
|
+
for (let [meta, node1] of rules){
|
|
311
|
+
let parentClasses = extractClasses(parent);
|
|
312
|
+
let nodeClasses = extractClasses(node1);
|
|
313
|
+
// Add base utility classes from the @apply node to the list of
|
|
314
|
+
// classes to check whether it intersects and therefore results in a
|
|
315
|
+
// circular dependency or not.
|
|
316
|
+
//
|
|
317
|
+
// E.g.:
|
|
318
|
+
// .foo {
|
|
319
|
+
// @apply hover:a; // This applies "a" but with a modifier
|
|
320
|
+
// }
|
|
321
|
+
//
|
|
322
|
+
// We only have to do that with base classes of the `node`, not of the `parent`
|
|
323
|
+
// E.g.:
|
|
324
|
+
// .hover\:foo {
|
|
325
|
+
// @apply bar;
|
|
326
|
+
// }
|
|
327
|
+
// .bar {
|
|
328
|
+
// @apply foo;
|
|
329
|
+
// }
|
|
330
|
+
//
|
|
331
|
+
// This should not result in a circular dependency because we are
|
|
332
|
+
// just applying `.foo` and the rule above is `.hover\:foo` which is
|
|
333
|
+
// unrelated. However, if we were to apply `hover:foo` then we _did_
|
|
334
|
+
// have to include this one.
|
|
335
|
+
nodeClasses = nodeClasses.concat(extractBaseCandidates(nodeClasses, context.tailwindConfig.separator));
|
|
336
|
+
let intersects = parentClasses.some((selector)=>nodeClasses.includes(selector)
|
|
337
|
+
);
|
|
338
|
+
if (intersects) {
|
|
339
|
+
throw node1.error(`You cannot \`@apply\` the \`${applyCandidate}\` utility here because it creates a circular dependency.`);
|
|
340
|
+
}
|
|
177
341
|
let root = _postcss.default.root({
|
|
178
342
|
nodes: [
|
|
179
|
-
|
|
343
|
+
node1.clone()
|
|
180
344
|
]
|
|
181
345
|
});
|
|
182
|
-
|
|
346
|
+
// Make sure every node in the entire tree points back at the @apply rule that generated it
|
|
347
|
+
root.walk((node)=>{
|
|
348
|
+
node.source = atApplySource;
|
|
349
|
+
});
|
|
350
|
+
let canRewriteSelector = node1.type !== 'atrule' || node1.type === 'atrule' && node1.name !== 'keyframes';
|
|
183
351
|
if (canRewriteSelector) {
|
|
184
352
|
root.walkRules((rule)=>{
|
|
353
|
+
// Let's imagine you have the following structure:
|
|
354
|
+
//
|
|
355
|
+
// .foo {
|
|
356
|
+
// @apply bar;
|
|
357
|
+
// }
|
|
358
|
+
//
|
|
359
|
+
// @supports (a: b) {
|
|
360
|
+
// .bar {
|
|
361
|
+
// color: blue
|
|
362
|
+
// }
|
|
363
|
+
//
|
|
364
|
+
// .something-unrelated {}
|
|
365
|
+
// }
|
|
366
|
+
//
|
|
367
|
+
// In this case we want to apply `.bar` but it happens to be in
|
|
368
|
+
// an atrule node. We clone that node instead of the nested one
|
|
369
|
+
// because we still want that @supports rule to be there once we
|
|
370
|
+
// applied everything.
|
|
371
|
+
//
|
|
372
|
+
// However it happens to be that the `.something-unrelated` is
|
|
373
|
+
// also in that same shared @supports atrule. This is not good,
|
|
374
|
+
// and this should not be there. The good part is that this is
|
|
375
|
+
// a clone already and it can be safely removed. The question is
|
|
376
|
+
// how do we know we can remove it. Basically what we can do is
|
|
377
|
+
// match it against the applyCandidate that you want to apply. If
|
|
378
|
+
// it doesn't match the we can safely delete it.
|
|
379
|
+
//
|
|
380
|
+
// If we didn't do this, then the `replaceSelector` function
|
|
381
|
+
// would have replaced this with something that didn't exist and
|
|
382
|
+
// therefore it removed the selector altogether. In this specific
|
|
383
|
+
// case it would result in `{}` instead of `.something-unrelated {}`
|
|
384
|
+
if (!extractClasses(rule).some((candidate)=>candidate === applyCandidate
|
|
385
|
+
)) {
|
|
386
|
+
rule.remove();
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
185
389
|
rule.selector = replaceSelector(parent.selector, rule.selector, applyCandidate);
|
|
186
390
|
rule.walkDecls((d)=>{
|
|
187
391
|
d.important = meta.important || important;
|
|
@@ -203,7 +407,6 @@ function processApply(root, context) {
|
|
|
203
407
|
let nodes = siblings.sort(([a], [z])=>(0, _bigSign).default(a.sort - z.sort)
|
|
204
408
|
).map((s)=>s[1]
|
|
205
409
|
);
|
|
206
|
-
// console.log(parent)
|
|
207
410
|
// `parent` refers to the node at `.abc` in: .abc { @apply mt-2 }
|
|
208
411
|
parent.after(nodes);
|
|
209
412
|
}
|
|
@@ -217,12 +420,14 @@ function processApply(root, context) {
|
|
|
217
420
|
}
|
|
218
421
|
}
|
|
219
422
|
// Do it again, in case we have other `@apply` rules
|
|
220
|
-
processApply(root, context);
|
|
423
|
+
processApply(root, context, localCache);
|
|
221
424
|
}
|
|
222
425
|
}
|
|
223
426
|
function expandApplyAtRules(context) {
|
|
224
427
|
return (root)=>{
|
|
225
|
-
|
|
226
|
-
|
|
428
|
+
// Build a cache of the user's CSS so we can use it to resolve classes used by @apply
|
|
429
|
+
let localCache = lazyCache(()=>buildLocalApplyCache(root, context)
|
|
430
|
+
);
|
|
431
|
+
processApply(root, context, localCache);
|
|
227
432
|
};
|
|
228
433
|
}
|
|
@@ -7,7 +7,9 @@ var _quickLru = _interopRequireDefault(require("quick-lru"));
|
|
|
7
7
|
var sharedState = _interopRequireWildcard(require("./sharedState"));
|
|
8
8
|
var _generateRules = require("./generateRules");
|
|
9
9
|
var _bigSign = _interopRequireDefault(require("../util/bigSign"));
|
|
10
|
+
var _log = _interopRequireDefault(require("../util/log"));
|
|
10
11
|
var _cloneNodes = _interopRequireDefault(require("../util/cloneNodes"));
|
|
12
|
+
var _defaultExtractor = require("./defaultExtractor");
|
|
11
13
|
function _interopRequireDefault(obj) {
|
|
12
14
|
return obj && obj.__esModule ? obj : {
|
|
13
15
|
default: obj
|
|
@@ -17,13 +19,11 @@ function _interopRequireWildcard(obj) {
|
|
|
17
19
|
if (obj && obj.__esModule) {
|
|
18
20
|
return obj;
|
|
19
21
|
} else {
|
|
20
|
-
var newObj = {
|
|
21
|
-
};
|
|
22
|
+
var newObj = {};
|
|
22
23
|
if (obj != null) {
|
|
23
24
|
for(var key in obj){
|
|
24
25
|
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
25
|
-
var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {
|
|
26
|
-
};
|
|
26
|
+
var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {};
|
|
27
27
|
if (desc.get || desc.set) {
|
|
28
28
|
Object.defineProperty(newObj, key, desc);
|
|
29
29
|
} else {
|
|
@@ -37,31 +37,8 @@ function _interopRequireWildcard(obj) {
|
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
let env = sharedState.env;
|
|
40
|
-
const PATTERNS = [
|
|
41
|
-
/([^<>"'`\s]*\[\w*'[^"`\s]*'?\])/.source,
|
|
42
|
-
/([^<>"'`\s]*\[\w*"[^"`\s]*"?\])/.source,
|
|
43
|
-
/([^<>"'`\s]*\[\w*\('[^"'`\s]*'\)\])/.source,
|
|
44
|
-
/([^<>"'`\s]*\[\w*\("[^"'`\s]*"\)\])/.source,
|
|
45
|
-
/([^<>"'`\s]*\[\w*\('[^"`\s]*'\)\])/.source,
|
|
46
|
-
/([^<>"'`\s]*\[\w*\("[^'`\s]*"\)\])/.source,
|
|
47
|
-
/([^<>"'`\s]*\['[^"'`\s]*'\])/.source,
|
|
48
|
-
/([^<>"'`\s]*\["[^"'`\s]*"\])/.source,
|
|
49
|
-
/([^<>"'`\s]*\[[^<>"'`\s]*:'[^"'`\s]*'\])/.source,
|
|
50
|
-
/([^<>"'`\s]*\[[^<>"'`\s]*:"[^"'`\s]*"\])/.source,
|
|
51
|
-
/([^<>"'`\s]*\[[^"'`\s]+\][^<>"'`\s]*)/.source,
|
|
52
|
-
/([^<>"'`\s]*[^"'`\s:])/.source
|
|
53
|
-
].join('|');
|
|
54
|
-
const BROAD_MATCH_GLOBAL_REGEXP = new RegExp(PATTERNS, 'g');
|
|
55
|
-
const INNER_MATCH_GLOBAL_REGEXP = /[^<>"'`\s.(){}[\]#=%]*[^<>"'`\s.(){}[\]#=%:]/g;
|
|
56
40
|
const builtInExtractors = {
|
|
57
|
-
DEFAULT:
|
|
58
|
-
let broadMatches = content.match(BROAD_MATCH_GLOBAL_REGEXP) || [];
|
|
59
|
-
let innerMatches = content.match(INNER_MATCH_GLOBAL_REGEXP) || [];
|
|
60
|
-
return [
|
|
61
|
-
...broadMatches,
|
|
62
|
-
...innerMatches
|
|
63
|
-
];
|
|
64
|
-
}
|
|
41
|
+
DEFAULT: _defaultExtractor.defaultExtractor
|
|
65
42
|
};
|
|
66
43
|
const builtInTransformers = {
|
|
67
44
|
DEFAULT: (content)=>content
|
|
@@ -112,6 +89,7 @@ function buildStylesheet(rules, context) {
|
|
|
112
89
|
);
|
|
113
90
|
let returnValue = {
|
|
114
91
|
base: new Set(),
|
|
92
|
+
defaults: new Set(),
|
|
115
93
|
components: new Set(),
|
|
116
94
|
utilities: new Set(),
|
|
117
95
|
variants: new Set(),
|
|
@@ -134,6 +112,10 @@ function buildStylesheet(rules, context) {
|
|
|
134
112
|
returnValue.base.add(rule);
|
|
135
113
|
continue;
|
|
136
114
|
}
|
|
115
|
+
if (sort & context.layerOrder.defaults) {
|
|
116
|
+
returnValue.defaults.add(rule);
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
137
119
|
if (sort & context.layerOrder.components) {
|
|
138
120
|
returnValue.components.add(rule);
|
|
139
121
|
continue;
|
|
@@ -157,13 +139,15 @@ function expandTailwindAtRules(context) {
|
|
|
157
139
|
utilities: null,
|
|
158
140
|
variants: null
|
|
159
141
|
};
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
if (
|
|
166
|
-
layerNodes
|
|
142
|
+
root.walkAtRules((rule)=>{
|
|
143
|
+
// Make sure this file contains Tailwind directives. If not, we can save
|
|
144
|
+
// a lot of work and bail early. Also we don't have to register our touch
|
|
145
|
+
// file as a dependency since the output of this CSS does not depend on
|
|
146
|
+
// the source of any templates. Think Vue <style> blocks for example.
|
|
147
|
+
if (rule.name === 'tailwind') {
|
|
148
|
+
if (Object.keys(layerNodes).includes(rule.params)) {
|
|
149
|
+
layerNodes[rule.params] = rule;
|
|
150
|
+
}
|
|
167
151
|
}
|
|
168
152
|
});
|
|
169
153
|
if (Object.values(layerNodes).every((n)=>n === null
|
|
@@ -173,7 +157,7 @@ function expandTailwindAtRules(context) {
|
|
|
173
157
|
// ---
|
|
174
158
|
// Find potential rules in changed files
|
|
175
159
|
let candidates = new Set([
|
|
176
|
-
|
|
160
|
+
sharedState.NOT_ON_DEMAND
|
|
177
161
|
]);
|
|
178
162
|
let seen = new Set();
|
|
179
163
|
env.DEBUG && console.time('Reading changed files');
|
|
@@ -182,6 +166,7 @@ function expandTailwindAtRules(context) {
|
|
|
182
166
|
let extractor = getExtractor(context.tailwindConfig, extension);
|
|
183
167
|
getClassCandidates(transformer(content), extractor, candidates, seen);
|
|
184
168
|
}
|
|
169
|
+
env.DEBUG && console.timeEnd('Reading changed files');
|
|
185
170
|
// ---
|
|
186
171
|
// Generate the actual CSS
|
|
187
172
|
let classCacheCount = context.classCache.size;
|
|
@@ -199,36 +184,66 @@ function expandTailwindAtRules(context) {
|
|
|
199
184
|
], context);
|
|
200
185
|
}
|
|
201
186
|
env.DEBUG && console.timeEnd('Build stylesheet');
|
|
202
|
-
let { base: baseNodes , components: componentNodes , utilities: utilityNodes , variants: screenNodes , } = context.stylesheetCache;
|
|
187
|
+
let { defaults: defaultNodes , base: baseNodes , components: componentNodes , utilities: utilityNodes , variants: screenNodes , } = context.stylesheetCache;
|
|
203
188
|
// ---
|
|
204
189
|
// Replace any Tailwind directives with generated CSS
|
|
205
190
|
if (layerNodes.base) {
|
|
206
191
|
layerNodes.base.before((0, _cloneNodes).default([
|
|
207
|
-
...baseNodes
|
|
208
|
-
|
|
192
|
+
...baseNodes,
|
|
193
|
+
...defaultNodes
|
|
194
|
+
], layerNodes.base.source, {
|
|
195
|
+
layer: 'base'
|
|
196
|
+
}));
|
|
209
197
|
layerNodes.base.remove();
|
|
210
198
|
}
|
|
211
199
|
if (layerNodes.components) {
|
|
212
200
|
layerNodes.components.before((0, _cloneNodes).default([
|
|
213
201
|
...componentNodes
|
|
214
|
-
], layerNodes.components.source
|
|
202
|
+
], layerNodes.components.source, {
|
|
203
|
+
layer: 'components'
|
|
204
|
+
}));
|
|
215
205
|
layerNodes.components.remove();
|
|
216
206
|
}
|
|
217
207
|
if (layerNodes.utilities) {
|
|
218
208
|
layerNodes.utilities.before((0, _cloneNodes).default([
|
|
219
209
|
...utilityNodes
|
|
220
|
-
], layerNodes.utilities.source
|
|
210
|
+
], layerNodes.utilities.source, {
|
|
211
|
+
layer: 'utilities'
|
|
212
|
+
}));
|
|
221
213
|
layerNodes.utilities.remove();
|
|
222
214
|
}
|
|
215
|
+
// We do post-filtering to not alter the emitted order of the variants
|
|
216
|
+
const variantNodes = Array.from(screenNodes).filter((node)=>{
|
|
217
|
+
var ref;
|
|
218
|
+
const parentLayer = (ref = node.raws.tailwind) === null || ref === void 0 ? void 0 : ref.parentLayer;
|
|
219
|
+
if (parentLayer === 'components') {
|
|
220
|
+
return layerNodes.components !== null;
|
|
221
|
+
}
|
|
222
|
+
if (parentLayer === 'utilities') {
|
|
223
|
+
return layerNodes.utilities !== null;
|
|
224
|
+
}
|
|
225
|
+
return true;
|
|
226
|
+
});
|
|
223
227
|
if (layerNodes.variants) {
|
|
224
|
-
layerNodes.variants.before((0, _cloneNodes).default(
|
|
225
|
-
|
|
226
|
-
|
|
228
|
+
layerNodes.variants.before((0, _cloneNodes).default(variantNodes, layerNodes.variants.source, {
|
|
229
|
+
layer: 'variants'
|
|
230
|
+
}));
|
|
227
231
|
layerNodes.variants.remove();
|
|
228
|
-
} else {
|
|
229
|
-
root.append((0, _cloneNodes).default(
|
|
230
|
-
|
|
231
|
-
|
|
232
|
+
} else if (variantNodes.length > 0) {
|
|
233
|
+
root.append((0, _cloneNodes).default(variantNodes, root.source, {
|
|
234
|
+
layer: 'variants'
|
|
235
|
+
}));
|
|
236
|
+
}
|
|
237
|
+
// If we've got a utility layer and no utilities are generated there's likely something wrong
|
|
238
|
+
const hasUtilityVariants = variantNodes.some((node)=>{
|
|
239
|
+
var ref;
|
|
240
|
+
return ((ref = node.raws.tailwind) === null || ref === void 0 ? void 0 : ref.parentLayer) === 'utilities';
|
|
241
|
+
});
|
|
242
|
+
if (layerNodes.utilities && utilityNodes.size === 0 && !hasUtilityVariants) {
|
|
243
|
+
_log.default.warn('content-problems', [
|
|
244
|
+
'No utility classes were detected in your source files. If this is unexpected, double-check the `content` option in your Tailwind CSS configuration.',
|
|
245
|
+
'https://tailwindcss.com/docs/content-configuration',
|
|
246
|
+
]);
|
|
232
247
|
}
|
|
233
248
|
// ---
|
|
234
249
|
if (env.DEBUG) {
|