tailwindcss 3.0.23 → 3.0.24

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.
Files changed (89) hide show
  1. package/CHANGELOG.md +29 -3
  2. package/lib/cli-peer-dependencies.js +3 -3
  3. package/lib/cli.js +183 -161
  4. package/lib/constants.js +8 -8
  5. package/lib/corePlugins.js +1572 -1523
  6. package/lib/featureFlags.js +9 -9
  7. package/lib/index.js +19 -6
  8. package/lib/lib/cacheInvalidation.js +69 -0
  9. package/lib/lib/collapseAdjacentRules.js +26 -13
  10. package/lib/lib/collapseDuplicateDeclarations.js +1 -1
  11. package/lib/lib/defaultExtractor.js +6 -6
  12. package/lib/lib/detectNesting.js +9 -9
  13. package/lib/lib/evaluateTailwindFunctions.js +16 -16
  14. package/lib/lib/expandApplyAtRules.js +180 -27
  15. package/lib/lib/expandTailwindAtRules.js +132 -122
  16. package/lib/lib/generateRules.js +90 -72
  17. package/lib/lib/getModuleDependencies.js +14 -14
  18. package/lib/lib/normalizeTailwindDirectives.js +35 -35
  19. package/lib/lib/partitionApplyAtRules.js +7 -7
  20. package/lib/lib/resolveDefaultsAtRules.js +81 -77
  21. package/lib/lib/setupContextUtils.js +78 -87
  22. package/lib/lib/setupTrackingContext.js +57 -57
  23. package/lib/lib/sharedState.js +10 -8
  24. package/lib/lib/substituteScreenAtRules.js +2 -2
  25. package/lib/postcss-plugins/nesting/README.md +2 -2
  26. package/lib/postcss-plugins/nesting/index.js +1 -1
  27. package/lib/postcss-plugins/nesting/plugin.js +41 -9
  28. package/lib/processTailwindFeatures.js +7 -7
  29. package/lib/public/colors.js +241 -241
  30. package/lib/public/resolve-config.js +5 -5
  31. package/lib/util/buildMediaQuery.js +2 -2
  32. package/lib/util/cloneDeep.js +1 -1
  33. package/lib/util/cloneNodes.js +12 -1
  34. package/lib/util/color.js +21 -20
  35. package/lib/util/createUtilityPlugin.js +6 -6
  36. package/lib/util/dataTypes.js +77 -75
  37. package/lib/util/escapeClassName.js +5 -5
  38. package/lib/util/escapeCommas.js +1 -1
  39. package/lib/util/flattenColorPalette.js +2 -2
  40. package/lib/util/formatVariantSelector.js +19 -19
  41. package/lib/util/getAllConfigs.js +5 -5
  42. package/lib/util/hashConfig.js +5 -5
  43. package/lib/util/isKeyframeRule.js +1 -1
  44. package/lib/util/isPlainObject.js +1 -1
  45. package/lib/util/isValidArbitraryValue.js +27 -27
  46. package/lib/util/log.js +8 -8
  47. package/lib/util/nameClass.js +7 -7
  48. package/lib/util/negateValue.js +4 -4
  49. package/lib/util/normalizeConfig.js +39 -39
  50. package/lib/util/normalizeScreens.js +4 -4
  51. package/lib/util/parseAnimationValue.js +56 -56
  52. package/lib/util/parseBoxShadowValue.js +60 -20
  53. package/lib/util/parseDependency.js +32 -32
  54. package/lib/util/parseObjectStyles.js +6 -6
  55. package/lib/util/pluginUtils.js +9 -9
  56. package/lib/util/prefixSelector.js +1 -1
  57. package/lib/util/resolveConfig.js +28 -28
  58. package/lib/util/resolveConfigPath.js +16 -16
  59. package/lib/util/responsive.js +6 -6
  60. package/lib/util/toColorValue.js +1 -1
  61. package/lib/util/toPath.js +2 -2
  62. package/lib/util/transformThemeValue.js +27 -27
  63. package/lib/util/withAlphaVariable.js +19 -19
  64. package/package.json +24 -23
  65. package/peers/index.js +4777 -4831
  66. package/scripts/generate-types.js +52 -0
  67. package/src/cli.js +41 -11
  68. package/src/corePlugins.js +67 -5
  69. package/src/featureFlags.js +2 -2
  70. package/src/index.js +17 -1
  71. package/src/lib/cacheInvalidation.js +52 -0
  72. package/src/lib/collapseAdjacentRules.js +16 -1
  73. package/src/lib/defaultExtractor.js +4 -4
  74. package/src/lib/expandApplyAtRules.js +179 -6
  75. package/src/lib/expandTailwindAtRules.js +25 -5
  76. package/src/lib/generateRules.js +68 -46
  77. package/src/lib/resolveDefaultsAtRules.js +6 -2
  78. package/src/lib/setupContextUtils.js +25 -26
  79. package/src/lib/setupTrackingContext.js +3 -3
  80. package/src/lib/sharedState.js +1 -0
  81. package/src/postcss-plugins/nesting/README.md +2 -2
  82. package/src/postcss-plugins/nesting/plugin.js +36 -0
  83. package/src/util/cloneNodes.js +14 -1
  84. package/src/util/color.js +7 -5
  85. package/src/util/dataTypes.js +3 -1
  86. package/src/util/log.js +7 -7
  87. package/src/util/parseBoxShadowValue.js +50 -2
  88. package/src/util/resolveConfig.js +32 -0
  89. package/stubs/defaultConfig.stub.js +5 -0
@@ -7,80 +7,11 @@ exports.elementSelectorParser = void 0;
7
7
  var _postcss = _interopRequireDefault(require("postcss"));
8
8
  var _postcssSelectorParser = _interopRequireDefault(require("postcss-selector-parser"));
9
9
  var _featureFlags = require("../featureFlags");
10
- function _interopRequireDefault(obj) {
11
- return obj && obj.__esModule ? obj : {
12
- default: obj
13
- };
14
- }
15
- let getNode = {
16
- id (node) {
17
- return _postcssSelectorParser.default.attribute({
18
- attribute: 'id',
19
- operator: '=',
20
- value: node.value,
21
- quoteMark: '"'
22
- });
23
- }
24
- };
25
- function minimumImpactSelector(nodes) {
26
- let rest = nodes.filter((node)=>{
27
- // Keep non-pseudo nodes
28
- if (node.type !== 'pseudo') return true;
29
- // Keep pseudo nodes that have subnodes
30
- // E.g.: `:not()` contains subnodes inside the parentheses
31
- if (node.nodes.length > 0) return true;
32
- // Keep pseudo `elements`
33
- // This implicitly means that we ignore pseudo `classes`
34
- return node.value.startsWith('::') || [
35
- ':before',
36
- ':after',
37
- ':first-line',
38
- ':first-letter'
39
- ].includes(node.value);
40
- }).reverse();
41
- let searchFor = new Set([
42
- 'tag',
43
- 'class',
44
- 'id',
45
- 'attribute'
46
- ]);
47
- let splitPointIdx = rest.findIndex((n)=>searchFor.has(n.type)
48
- );
49
- if (splitPointIdx === -1) return rest.reverse().join('').trim();
50
- let node1 = rest[splitPointIdx];
51
- let bestNode = getNode[node1.type] ? getNode[node1.type](node1) : node1;
52
- rest = rest.slice(0, splitPointIdx);
53
- let combinatorIdx = rest.findIndex((n)=>n.type === 'combinator' && n.value === '>'
54
- );
55
- if (combinatorIdx !== -1) {
56
- rest.splice(0, combinatorIdx);
57
- rest.unshift(_postcssSelectorParser.default.universal());
58
- }
59
- return [
60
- bestNode,
61
- ...rest.reverse()
62
- ].join('').trim();
63
- }
64
- let elementSelectorParser = (0, _postcssSelectorParser).default((selectors)=>{
65
- return selectors.map((s)=>{
66
- let nodes = s.split((n)=>n.type === 'combinator' && n.value === ' '
67
- ).pop();
68
- return minimumImpactSelector(nodes);
69
- });
70
- });
71
- exports.elementSelectorParser = elementSelectorParser;
72
- let cache = new Map();
73
- function extractElementSelector(selector) {
74
- if (!cache.has(selector)) {
75
- cache.set(selector, elementSelectorParser.transformSync(selector));
76
- }
77
- return cache.get(selector);
78
- }
79
10
  function resolveDefaultsAtRules({ tailwindConfig }) {
80
11
  return (root)=>{
81
12
  let variableNodeMap = new Map();
82
13
  /** @type {Set<import('postcss').AtRule>} */ let universals = new Set();
83
- root.walkAtRules('defaults', (rule)=>{
14
+ root.walkAtRules("defaults", (rule)=>{
84
15
  if (rule.nodes && rule.nodes.length > 0) {
85
16
  universals.add(rule);
86
17
  return;
@@ -102,20 +33,22 @@ function resolveDefaultsAtRules({ tailwindConfig }) {
102
33
  // we consider them separately because merging the declarations into
103
34
  // a single rule will cause browsers that do not understand the
104
35
  // vendor prefix to throw out the whole rule
105
- let selectorGroupName = selector.includes(':-') || selector.includes('::-') ? selector : '__DEFAULT__';
36
+ let selectorGroupName = selector.includes(":-") || selector.includes("::-") ? selector : "__DEFAULT__";
106
37
  var ref1;
107
38
  let selectors = (ref1 = selectorGroups.get(selectorGroupName)) !== null && ref1 !== void 0 ? ref1 : new Set();
108
39
  selectorGroups.set(selectorGroupName, selectors);
109
40
  selectors.add(selector);
110
41
  }
111
42
  }
112
- if ((0, _featureFlags).flagEnabled(tailwindConfig, 'optimizeUniversalDefaults')) {
43
+ if ((0, _featureFlags).flagEnabled(tailwindConfig, "optimizeUniversalDefaults")) {
113
44
  if (selectorGroups.size === 0) {
114
45
  universal.remove();
115
46
  continue;
116
47
  }
117
48
  for (let [, selectors] of selectorGroups){
118
- let universalRule = _postcss.default.rule();
49
+ let universalRule = _postcss.default.rule({
50
+ source: universal.source
51
+ });
119
52
  universalRule.selectors = [
120
53
  ...selectors
121
54
  ];
@@ -124,11 +57,13 @@ function resolveDefaultsAtRules({ tailwindConfig }) {
124
57
  universal.before(universalRule);
125
58
  }
126
59
  } else {
127
- let universalRule = _postcss.default.rule();
60
+ let universalRule = _postcss.default.rule({
61
+ source: universal.source
62
+ });
128
63
  universalRule.selectors = [
129
- '*',
130
- '::before',
131
- '::after'
64
+ "*",
65
+ "::before",
66
+ "::after"
132
67
  ];
133
68
  universalRule.append(universal.nodes);
134
69
  universal.before(universalRule);
@@ -137,3 +72,72 @@ function resolveDefaultsAtRules({ tailwindConfig }) {
137
72
  }
138
73
  };
139
74
  }
75
+ function _interopRequireDefault(obj) {
76
+ return obj && obj.__esModule ? obj : {
77
+ default: obj
78
+ };
79
+ }
80
+ let getNode = {
81
+ id (node) {
82
+ return _postcssSelectorParser.default.attribute({
83
+ attribute: "id",
84
+ operator: "=",
85
+ value: node.value,
86
+ quoteMark: '"'
87
+ });
88
+ }
89
+ };
90
+ function minimumImpactSelector(nodes) {
91
+ let rest = nodes.filter((node)=>{
92
+ // Keep non-pseudo nodes
93
+ if (node.type !== "pseudo") return true;
94
+ // Keep pseudo nodes that have subnodes
95
+ // E.g.: `:not()` contains subnodes inside the parentheses
96
+ if (node.nodes.length > 0) return true;
97
+ // Keep pseudo `elements`
98
+ // This implicitly means that we ignore pseudo `classes`
99
+ return node.value.startsWith("::") || [
100
+ ":before",
101
+ ":after",
102
+ ":first-line",
103
+ ":first-letter"
104
+ ].includes(node.value);
105
+ }).reverse();
106
+ let searchFor = new Set([
107
+ "tag",
108
+ "class",
109
+ "id",
110
+ "attribute"
111
+ ]);
112
+ let splitPointIdx = rest.findIndex((n)=>searchFor.has(n.type)
113
+ );
114
+ if (splitPointIdx === -1) return rest.reverse().join("").trim();
115
+ let node1 = rest[splitPointIdx];
116
+ let bestNode = getNode[node1.type] ? getNode[node1.type](node1) : node1;
117
+ rest = rest.slice(0, splitPointIdx);
118
+ let combinatorIdx = rest.findIndex((n)=>n.type === "combinator" && n.value === ">"
119
+ );
120
+ if (combinatorIdx !== -1) {
121
+ rest.splice(0, combinatorIdx);
122
+ rest.unshift(_postcssSelectorParser.default.universal());
123
+ }
124
+ return [
125
+ bestNode,
126
+ ...rest.reverse()
127
+ ].join("").trim();
128
+ }
129
+ let elementSelectorParser = (0, _postcssSelectorParser).default((selectors)=>{
130
+ return selectors.map((s)=>{
131
+ let nodes = s.split((n)=>n.type === "combinator" && n.value === " "
132
+ ).pop();
133
+ return minimumImpactSelector(nodes);
134
+ });
135
+ });
136
+ exports.elementSelectorParser = elementSelectorParser;
137
+ let cache = new Map();
138
+ function extractElementSelector(selector) {
139
+ if (!cache.has(selector)) {
140
+ cache.set(selector, elementSelectorParser.transformSync(selector));
141
+ }
142
+ return cache.get(selector);
143
+ }
@@ -25,6 +25,7 @@ var _log = _interopRequireDefault(require("../util/log"));
25
25
  var _negateValue = _interopRequireDefault(require("../util/negateValue"));
26
26
  var _isValidArbitraryValue = _interopRequireDefault(require("../util/isValidArbitraryValue"));
27
27
  var _generateRules = require("./generateRules");
28
+ var _cacheInvalidationJs = require("./cacheInvalidation.js");
28
29
  function _interopRequireDefault(obj) {
29
30
  return obj && obj.__esModule ? obj : {
30
31
  default: obj
@@ -53,10 +54,10 @@ function _interopRequireWildcard(obj) {
53
54
  }
54
55
  function prefix(context, selector) {
55
56
  let prefix1 = context.tailwindConfig.prefix;
56
- return typeof prefix1 === 'function' ? prefix1(selector) : prefix1 + selector;
57
+ return typeof prefix1 === "function" ? prefix1(selector) : prefix1 + selector;
57
58
  }
58
59
  function parseVariantFormatString(input) {
59
- if (input.includes('{')) {
60
+ if (input.includes("{")) {
60
61
  if (!isBalanced(input)) throw new Error(`Your { and } are unbalanced.`);
61
62
  return input.split(/{(.*)}/gim).flatMap((line)=>parseVariantFormatString(line)
62
63
  ).filter(Boolean);
@@ -68,9 +69,9 @@ function parseVariantFormatString(input) {
68
69
  function isBalanced(input) {
69
70
  let count = 0;
70
71
  for (let char of input){
71
- if (char === '{') {
72
+ if (char === "{") {
72
73
  count++;
73
- } else if (char === '}') {
74
+ } else if (char === "}") {
74
75
  if (--count < 0) {
75
76
  return false // unbalanced
76
77
  ;
@@ -104,9 +105,12 @@ function parseStyles(styles) {
104
105
  return isNode ? style : (0, _parseObjectStyles).default(style);
105
106
  });
106
107
  }
107
- function getClasses(selector) {
108
+ function getClasses(selector, mutate) {
108
109
  let parser = (0, _postcssSelectorParser).default((selectors)=>{
109
110
  let allClasses = [];
111
+ if (mutate) {
112
+ mutate(selectors);
113
+ }
110
114
  selectors.walkClasses((classNode)=>{
111
115
  allClasses.push(classNode.value);
112
116
  });
@@ -119,9 +123,20 @@ function extractCandidates(node, state = {
119
123
  }, depth = 0) {
120
124
  let classes = [];
121
125
  // Handle normal rules
122
- if (node.type === 'rule') {
126
+ if (node.type === "rule") {
127
+ // Ignore everything inside a :not(...). This allows you to write code like
128
+ // `div:not(.foo)`. If `.foo` is never found in your code, then we used to
129
+ // not generated it. But now we will ignore everything inside a `:not`, so
130
+ // that it still gets generated.
131
+ function ignoreNot(selectors) {
132
+ selectors.walkPseudos((pseudo)=>{
133
+ if (pseudo.value === ":not") {
134
+ pseudo.remove();
135
+ }
136
+ });
137
+ }
123
138
  for (let selector of node.selectors){
124
- let classCandidates = getClasses(selector);
139
+ let classCandidates = getClasses(selector, ignoreNot);
125
140
  // At least one of the selectors contains non-"on-demandable" candidates.
126
141
  if (classCandidates.length === 0) {
127
142
  state.containsNonOnDemandable = true;
@@ -130,9 +145,9 @@ function extractCandidates(node, state = {
130
145
  classes.push(classCandidate);
131
146
  }
132
147
  }
133
- } else if (node.type === 'atrule') {
148
+ } else if (node.type === "atrule") {
134
149
  node.walkRules((rule)=>{
135
- for (let classCandidate of rule.selectors.flatMap((selector)=>getClasses(selector, state, depth + 1)
150
+ for (let classCandidate of rule.selectors.flatMap((selector)=>getClasses(selector)
136
151
  )){
137
152
  classes.push(classCandidate);
138
153
  }
@@ -187,7 +202,7 @@ function buildPluginApi(tailwindConfig, context, { variantList , variantMap , of
187
202
  return {
188
203
  addVariant (variantName, variantFunctions, options = {}) {
189
204
  variantFunctions = [].concat(variantFunctions).map((variantFunction)=>{
190
- if (typeof variantFunction !== 'string') {
205
+ if (typeof variantFunction !== "string") {
191
206
  // Safelist public API functions
192
207
  return ({ modifySelectors , container , separator })=>{
193
208
  return variantFunction({
@@ -197,9 +212,9 @@ function buildPluginApi(tailwindConfig, context, { variantList , variantMap , of
197
212
  });
198
213
  };
199
214
  }
200
- variantFunction = variantFunction.replace(/\n+/g, '').replace(/\s{1,}/g, ' ').trim();
215
+ variantFunction = variantFunction.replace(/\n+/g, "").replace(/\s{1,}/g, " ").trim();
201
216
  let fns = parseVariantFormatString(variantFunction).map((str)=>{
202
- if (!str.startsWith('@')) {
217
+ if (!str.startsWith("@")) {
203
218
  return ({ format })=>format(str)
204
219
  ;
205
220
  }
@@ -226,7 +241,7 @@ function buildPluginApi(tailwindConfig, context, { variantList , variantMap , of
226
241
  theme (path, defaultValue) {
227
242
  const [pathRoot, ...subPaths] = (0, _toPath).toPath(path);
228
243
  const value = getConfigValue([
229
- 'theme',
244
+ "theme",
230
245
  pathRoot,
231
246
  ...subPaths
232
247
  ], defaultValue);
@@ -237,7 +252,7 @@ function buildPluginApi(tailwindConfig, context, { variantList , variantMap , of
237
252
  return tailwindConfig.corePlugins.includes(path);
238
253
  }
239
254
  return getConfigValue([
240
- 'corePlugins',
255
+ "corePlugins",
241
256
  path
242
257
  ], true);
243
258
  },
@@ -245,21 +260,6 @@ function buildPluginApi(tailwindConfig, context, { variantList , variantMap , of
245
260
  // Preserved for backwards compatibility but not used in v3.0+
246
261
  return [];
247
262
  },
248
- addUserCss (userCss) {
249
- for (let [identifier, rule] of withIdentifiers(userCss)){
250
- let offset = offsets.user++;
251
- if (!context.candidateRuleMap.has(identifier)) {
252
- context.candidateRuleMap.set(identifier, []);
253
- }
254
- context.candidateRuleMap.get(identifier).push([
255
- {
256
- sort: offset,
257
- layer: 'user'
258
- },
259
- rule
260
- ]);
261
- }
262
- },
263
263
  addBase (base) {
264
264
  for (let [identifier, rule] of withIdentifiers(base)){
265
265
  let prefixedIdentifier = prefixIdentifier(identifier, {});
@@ -270,7 +270,7 @@ function buildPluginApi(tailwindConfig, context, { variantList , variantMap , of
270
270
  context.candidateRuleMap.get(prefixedIdentifier).push([
271
271
  {
272
272
  sort: offset,
273
- layer: 'base'
273
+ layer: "base"
274
274
  },
275
275
  rule
276
276
  ]);
@@ -291,7 +291,7 @@ function buildPluginApi(tailwindConfig, context, { variantList , variantMap , of
291
291
  context.candidateRuleMap.get(prefixedIdentifier).push([
292
292
  {
293
293
  sort: offsets.base++,
294
- layer: 'defaults'
294
+ layer: "defaults"
295
295
  },
296
296
  rule
297
297
  ]);
@@ -312,7 +312,7 @@ function buildPluginApi(tailwindConfig, context, { variantList , variantMap , of
312
312
  context.candidateRuleMap.get(prefixedIdentifier).push([
313
313
  {
314
314
  sort: offsets.components++,
315
- layer: 'components',
315
+ layer: "components",
316
316
  options
317
317
  },
318
318
  rule
@@ -334,7 +334,7 @@ function buildPluginApi(tailwindConfig, context, { variantList , variantMap , of
334
334
  context.candidateRuleMap.get(prefixedIdentifier).push([
335
335
  {
336
336
  sort: offsets.utilities++,
337
- layer: 'utilities',
337
+ layer: "utilities",
338
338
  options
339
339
  },
340
340
  rule
@@ -359,7 +359,7 @@ function buildPluginApi(tailwindConfig, context, { variantList , variantMap , of
359
359
  options
360
360
  ]);
361
361
  function wrapped(modifier, { isOnlyPlugin }) {
362
- let { type ='any' } = options;
362
+ let { type ="any" } = options;
363
363
  type = [].concat(type);
364
364
  let [value, coercedType] = (0, _pluginUtils).coerceValue(type, modifier, options, tailwindConfig);
365
365
  if (value === undefined) {
@@ -380,7 +380,7 @@ function buildPluginApi(tailwindConfig, context, { variantList , variantMap , of
380
380
  let withOffsets = [
381
381
  {
382
382
  sort: offset,
383
- layer: 'utilities',
383
+ layer: "utilities",
384
384
  options
385
385
  },
386
386
  wrapped
@@ -409,7 +409,7 @@ function buildPluginApi(tailwindConfig, context, { variantList , variantMap , of
409
409
  options
410
410
  ]);
411
411
  function wrapped(modifier, { isOnlyPlugin }) {
412
- let { type ='any' } = options;
412
+ let { type ="any" } = options;
413
413
  type = [].concat(type);
414
414
  let [value, coercedType] = (0, _pluginUtils).coerceValue(type, modifier, options, tailwindConfig);
415
415
  if (value === undefined) {
@@ -419,7 +419,7 @@ function buildPluginApi(tailwindConfig, context, { variantList , variantMap , of
419
419
  if (isOnlyPlugin) {
420
420
  _log.default.warn([
421
421
  `Unnecessary typehint \`${coercedType}\` in \`${identifier}-${modifier}\`.`,
422
- `You can safely update it to \`${identifier}-${modifier.replace(coercedType + ':', '')}\`.`,
422
+ `You can safely update it to \`${identifier}-${modifier.replace(coercedType + ":", "")}\`.`,
423
423
  ]);
424
424
  } else {
425
425
  return [];
@@ -437,7 +437,7 @@ function buildPluginApi(tailwindConfig, context, { variantList , variantMap , of
437
437
  let withOffsets = [
438
438
  {
439
439
  sort: offset,
440
- layer: 'components',
440
+ layer: "components",
441
441
  options
442
442
  },
443
443
  wrapped
@@ -463,8 +463,8 @@ function trackModified(files, fileModifiedMap) {
463
463
  var ref;
464
464
  if (!file) continue;
465
465
  let parsed = _url.default.parse(file);
466
- let pathname = parsed.hash ? parsed.href.replace(parsed.hash, '') : parsed.href;
467
- pathname = parsed.search ? pathname.replace(parsed.search, '') : pathname;
466
+ let pathname = parsed.hash ? parsed.href.replace(parsed.hash, "") : parsed.href;
467
+ pathname = parsed.search ? pathname.replace(parsed.search, "") : pathname;
468
468
  let newModified = (ref = _fs.default.statSync(decodeURIComponent(pathname), {
469
469
  throwIfNoEntry: false
470
470
  })) === null || ref === void 0 ? void 0 : ref.mtimeMs;
@@ -481,8 +481,8 @@ function trackModified(files, fileModifiedMap) {
481
481
  function extractVariantAtRules(node) {
482
482
  node.walkAtRules((atRule)=>{
483
483
  if ([
484
- 'responsive',
485
- 'variants'
484
+ "responsive",
485
+ "variants"
486
486
  ].includes(atRule.name)) {
487
487
  extractVariantAtRules(atRule);
488
488
  atRule.before(atRule.nodes);
@@ -493,18 +493,18 @@ function extractVariantAtRules(node) {
493
493
  function collectLayerPlugins(root) {
494
494
  let layerPlugins = [];
495
495
  root.each((node)=>{
496
- if (node.type === 'atrule' && [
497
- 'responsive',
498
- 'variants'
496
+ if (node.type === "atrule" && [
497
+ "responsive",
498
+ "variants"
499
499
  ].includes(node.name)) {
500
- node.name = 'layer';
501
- node.params = 'utilities';
500
+ node.name = "layer";
501
+ node.params = "utilities";
502
502
  }
503
503
  });
504
504
  // Walk @layer rules and treat them like plugins
505
- root.walkAtRules('layer', (layerRule)=>{
505
+ root.walkAtRules("layer", (layerRule)=>{
506
506
  extractVariantAtRules(layerRule);
507
- if (layerRule.params === 'base') {
507
+ if (layerRule.params === "base") {
508
508
  for (let node of layerRule.nodes){
509
509
  layerPlugins.push(function({ addBase }) {
510
510
  addBase(node, {
@@ -513,7 +513,7 @@ function collectLayerPlugins(root) {
513
513
  });
514
514
  }
515
515
  layerRule.remove();
516
- } else if (layerRule.params === 'components') {
516
+ } else if (layerRule.params === "components") {
517
517
  for (let node of layerRule.nodes){
518
518
  layerPlugins.push(function({ addComponents }) {
519
519
  addComponents(node, {
@@ -522,7 +522,7 @@ function collectLayerPlugins(root) {
522
522
  });
523
523
  }
524
524
  layerRule.remove();
525
- } else if (layerRule.params === 'utilities') {
525
+ } else if (layerRule.params === "utilities") {
526
526
  for (let node of layerRule.nodes){
527
527
  layerPlugins.push(function({ addUtilities }) {
528
528
  addUtilities(node, {
@@ -533,16 +533,6 @@ function collectLayerPlugins(root) {
533
533
  layerRule.remove();
534
534
  }
535
535
  });
536
- root.walkRules((rule)=>{
537
- // At this point it is safe to include all the left-over css from the
538
- // user's css file. This is because the `@tailwind` and `@layer` directives
539
- // will already be handled and will be removed from the css tree.
540
- layerPlugins.push(function({ addUserCss }) {
541
- addUserCss(rule, {
542
- respectPrefix: false
543
- });
544
- });
545
- });
546
536
  return layerPlugins;
547
537
  }
548
538
  function resolvePlugins(context, root) {
@@ -559,22 +549,22 @@ function resolvePlugins(context, root) {
559
549
  if (plugin.__isOptionsFunction) {
560
550
  plugin = plugin();
561
551
  }
562
- return typeof plugin === 'function' ? plugin : plugin.handler;
552
+ return typeof plugin === "function" ? plugin : plugin.handler;
563
553
  });
564
554
  let layerPlugins = collectLayerPlugins(root);
565
555
  // TODO: This is a workaround for backwards compatibility, since custom variants
566
556
  // were historically sorted before screen/stackable variants.
567
557
  let beforeVariants = [
568
- _corePlugins.variantPlugins['pseudoElementVariants'],
569
- _corePlugins.variantPlugins['pseudoClassVariants'],
558
+ _corePlugins.variantPlugins["pseudoElementVariants"],
559
+ _corePlugins.variantPlugins["pseudoClassVariants"],
570
560
  ];
571
561
  let afterVariants = [
572
- _corePlugins.variantPlugins['directionVariants'],
573
- _corePlugins.variantPlugins['reducedMotionVariants'],
574
- _corePlugins.variantPlugins['darkVariants'],
575
- _corePlugins.variantPlugins['printVariant'],
576
- _corePlugins.variantPlugins['screenVariants'],
577
- _corePlugins.variantPlugins['orientationVariants'],
562
+ _corePlugins.variantPlugins["directionVariants"],
563
+ _corePlugins.variantPlugins["reducedMotionVariants"],
564
+ _corePlugins.variantPlugins["darkVariants"],
565
+ _corePlugins.variantPlugins["printVariant"],
566
+ _corePlugins.variantPlugins["screenVariants"],
567
+ _corePlugins.variantPlugins["orientationVariants"],
578
568
  ];
579
569
  return [
580
570
  ...corePluginList,
@@ -659,18 +649,18 @@ function registerPlugins(plugins, context) {
659
649
  if (safelist.length > 0) {
660
650
  let checks = [];
661
651
  for (let value1 of safelist){
662
- if (typeof value1 === 'string') {
652
+ if (typeof value1 === "string") {
663
653
  context.changedContent.push({
664
654
  content: value1,
665
- extension: 'html'
655
+ extension: "html"
666
656
  });
667
657
  continue;
668
658
  }
669
659
  if (value1 instanceof RegExp) {
670
- _log.default.warn('root-regex', [
671
- 'Regular expressions in `safelist` work differently in Tailwind CSS v3.0.',
672
- 'Update your `safelist` configuration to eliminate this warning.',
673
- 'https://tailwindcss.com/docs/content-configuration#safelisting-classes',
660
+ _log.default.warn("root-regex", [
661
+ "Regular expressions in `safelist` work differently in Tailwind CSS v3.0.",
662
+ "Update your `safelist` configuration to eliminate this warning.",
663
+ "https://tailwindcss.com/docs/content-configuration#safelisting-classes",
674
664
  ]);
675
665
  continue;
676
666
  }
@@ -691,7 +681,7 @@ function registerPlugins(plugins, context) {
691
681
  // e.g. `-inset-1` or `-tw-inset-1`
692
682
  classes = [
693
683
  ...classes,
694
- ...classes.map((cls)=>'-' + cls
684
+ ...classes.map((cls)=>"-" + cls
695
685
  )
696
686
  ];
697
687
  // This is the negated version *after* the prefix
@@ -700,7 +690,7 @@ function registerPlugins(plugins, context) {
700
690
  // So we add the negative after the prefix
701
691
  classes = [
702
692
  ...classes,
703
- ...classes.map((cls)=>cls.slice(0, prefixLength) + '-' + cls.slice(prefixLength)
693
+ ...classes.map((cls)=>cls.slice(0, prefixLength) + "-" + cls.slice(prefixLength)
704
694
  ),
705
695
  ];
706
696
  }
@@ -720,12 +710,12 @@ function registerPlugins(plugins, context) {
720
710
  patternMatchingCount.set(pattern, patternMatchingCount.get(pattern) + 1);
721
711
  context.changedContent.push({
722
712
  content: util1,
723
- extension: 'html'
713
+ extension: "html"
724
714
  });
725
715
  for (let variant of variants){
726
716
  context.changedContent.push({
727
717
  content: variant + context.tailwindConfig.separator + util1,
728
- extension: 'html'
718
+ extension: "html"
729
719
  });
730
720
  }
731
721
  }
@@ -735,8 +725,8 @@ function registerPlugins(plugins, context) {
735
725
  if (count !== 0) continue;
736
726
  _log.default.warn([
737
727
  `The safelist pattern \`${regex}\` doesn't match any Tailwind CSS classes.`,
738
- 'Fix this pattern or remove it from your `safelist` configuration.',
739
- 'https://tailwindcss.com/docs/content-configuration#safelisting-classes',
728
+ "Fix this pattern or remove it from your `safelist` configuration.",
729
+ "https://tailwindcss.com/docs/content-configuration#safelisting-classes",
740
730
  ]);
741
731
  }
742
732
  }
@@ -746,8 +736,8 @@ function registerPlugins(plugins, context) {
746
736
  // sorting could be weird since you still require them in order to make the
747
737
  // host utitlies work properly. (Thanks Biology)
748
738
  let parasiteUtilities = new Set([
749
- prefix(context, 'group'),
750
- prefix(context, 'peer')
739
+ prefix(context, "group"),
740
+ prefix(context, "peer")
751
741
  ]);
752
742
  context.getClassOrder = function getClassOrder(classes) {
753
743
  let sortedClassNames = new Map();
@@ -817,7 +807,7 @@ let contextSourcesMap = sharedState.contextSourcesMap;
817
807
  function getContext(root, result, tailwindConfig, userConfigPath, tailwindConfigHash, contextDependencies) {
818
808
  let sourcePath = result.opts.from;
819
809
  let isConfigFile = userConfigPath !== null;
820
- sharedState.env.DEBUG && console.log('Source path:', sourcePath);
810
+ sharedState.env.DEBUG && console.log("Source path:", sourcePath);
821
811
  let existingContext;
822
812
  if (isConfigFile && contextMap.has(sourcePath)) {
823
813
  existingContext = contextMap.get(sourcePath);
@@ -827,13 +817,14 @@ function getContext(root, result, tailwindConfig, userConfigPath, tailwindConfig
827
817
  contextMap.set(sourcePath, context);
828
818
  existingContext = context;
829
819
  }
820
+ let cssDidChange = (0, _cacheInvalidationJs).hasContentChanged(sourcePath, root);
830
821
  // If there's already a context in the cache and we don't need to
831
822
  // reset the context, return the cached context.
832
823
  if (existingContext) {
833
824
  let contextDependenciesChanged = trackModified([
834
825
  ...contextDependencies
835
826
  ], getFileModifiedMap(existingContext));
836
- if (!contextDependenciesChanged) {
827
+ if (!contextDependenciesChanged && !cssDidChange) {
837
828
  return [
838
829
  existingContext,
839
830
  false
@@ -862,7 +853,7 @@ function getContext(root, result, tailwindConfig, userConfigPath, tailwindConfig
862
853
  }
863
854
  }
864
855
  }
865
- sharedState.env.DEBUG && console.log('Setting up new context...');
856
+ sharedState.env.DEBUG && console.log("Setting up new context...");
866
857
  let context = createContext(tailwindConfig, [], root);
867
858
  trackModified([
868
859
  ...contextDependencies