tailwindcss 0.0.0-insiders.ea139f2 → 0.0.0-insiders.ea4e1cd

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 (236) hide show
  1. package/LICENSE +1 -2
  2. package/README.md +15 -7
  3. package/colors.d.ts +3 -0
  4. package/colors.js +2 -1
  5. package/defaultConfig.d.ts +3 -0
  6. package/defaultConfig.js +2 -1
  7. package/defaultTheme.d.ts +4 -0
  8. package/defaultTheme.js +2 -1
  9. package/lib/cli/build/deps.js +62 -0
  10. package/lib/cli/build/index.js +54 -0
  11. package/lib/cli/build/plugin.js +378 -0
  12. package/lib/cli/build/utils.js +88 -0
  13. package/lib/cli/build/watching.js +182 -0
  14. package/lib/cli/help/index.js +73 -0
  15. package/lib/cli/index.js +230 -0
  16. package/lib/cli/init/index.js +63 -0
  17. package/lib/cli-peer-dependencies.js +28 -7
  18. package/lib/cli.js +4 -703
  19. package/lib/corePluginList.js +12 -3
  20. package/lib/corePlugins.js +2373 -1863
  21. package/lib/css/preflight.css +10 -8
  22. package/lib/featureFlags.js +49 -26
  23. package/lib/index.js +1 -31
  24. package/lib/lib/cacheInvalidation.js +92 -0
  25. package/lib/lib/collapseAdjacentRules.js +30 -10
  26. package/lib/lib/collapseDuplicateDeclarations.js +60 -4
  27. package/lib/lib/content.js +181 -0
  28. package/lib/lib/defaultExtractor.js +243 -0
  29. package/lib/lib/detectNesting.js +21 -10
  30. package/lib/lib/evaluateTailwindFunctions.js +115 -50
  31. package/lib/lib/expandApplyAtRules.js +467 -161
  32. package/lib/lib/expandTailwindAtRules.js +160 -133
  33. package/lib/lib/findAtConfigPath.js +46 -0
  34. package/lib/lib/generateRules.js +553 -200
  35. package/lib/lib/getModuleDependencies.js +88 -37
  36. package/lib/lib/load-config.js +42 -0
  37. package/lib/lib/normalizeTailwindDirectives.js +46 -33
  38. package/lib/lib/offsets.js +306 -0
  39. package/lib/lib/partitionApplyAtRules.js +58 -0
  40. package/lib/lib/regex.js +74 -0
  41. package/lib/lib/remap-bitfield.js +89 -0
  42. package/lib/lib/resolveDefaultsAtRules.js +98 -58
  43. package/lib/lib/setupContextUtils.js +773 -321
  44. package/lib/lib/setupTrackingContext.js +70 -75
  45. package/lib/lib/sharedState.js +78 -10
  46. package/lib/lib/substituteScreenAtRules.js +14 -10
  47. package/lib/oxide/cli/build/deps.js +89 -0
  48. package/lib/oxide/cli/build/index.js +53 -0
  49. package/lib/oxide/cli/build/plugin.js +375 -0
  50. package/lib/oxide/cli/build/utils.js +87 -0
  51. package/lib/oxide/cli/build/watching.js +179 -0
  52. package/lib/oxide/cli/help/index.js +72 -0
  53. package/lib/oxide/cli/index.js +214 -0
  54. package/lib/oxide/cli/init/index.js +52 -0
  55. package/lib/oxide/cli.js +5 -0
  56. package/lib/oxide/postcss-plugin.js +2 -0
  57. package/lib/plugin.js +98 -0
  58. package/{nesting → lib/postcss-plugins/nesting}/README.md +2 -2
  59. package/lib/postcss-plugins/nesting/index.js +21 -0
  60. package/lib/postcss-plugins/nesting/plugin.js +89 -0
  61. package/lib/processTailwindFeatures.js +39 -26
  62. package/lib/public/colors.js +272 -246
  63. package/lib/public/create-plugin.js +9 -5
  64. package/lib/public/default-config.js +10 -6
  65. package/lib/public/default-theme.js +10 -6
  66. package/lib/public/load-config.js +12 -0
  67. package/lib/public/resolve-config.js +11 -6
  68. package/lib/util/applyImportantSelector.js +36 -0
  69. package/lib/util/bigSign.js +6 -1
  70. package/lib/util/buildMediaQuery.js +13 -6
  71. package/lib/util/cloneDeep.js +9 -6
  72. package/lib/util/cloneNodes.js +23 -3
  73. package/lib/util/color.js +70 -38
  74. package/lib/util/colorNames.js +752 -0
  75. package/lib/util/configurePlugins.js +7 -2
  76. package/lib/util/createPlugin.js +8 -6
  77. package/lib/util/createUtilityPlugin.js +16 -16
  78. package/lib/util/dataTypes.js +173 -108
  79. package/lib/util/defaults.js +14 -3
  80. package/lib/util/escapeClassName.js +13 -8
  81. package/lib/util/escapeCommas.js +7 -2
  82. package/lib/util/flattenColorPalette.js +11 -12
  83. package/lib/util/formatVariantSelector.js +228 -151
  84. package/lib/util/getAllConfigs.js +33 -12
  85. package/lib/util/hashConfig.js +9 -4
  86. package/lib/util/isKeyframeRule.js +7 -2
  87. package/lib/util/isPlainObject.js +7 -2
  88. package/lib/util/{isValidArbitraryValue.js → isSyntacticallyValidPropertyValue.js} +25 -15
  89. package/lib/util/log.js +27 -13
  90. package/lib/util/nameClass.js +27 -10
  91. package/lib/util/negateValue.js +25 -8
  92. package/lib/util/normalizeConfig.js +139 -65
  93. package/lib/util/normalizeScreens.js +131 -11
  94. package/lib/util/parseAnimationValue.js +44 -40
  95. package/lib/util/parseBoxShadowValue.js +34 -23
  96. package/lib/util/parseDependency.js +39 -55
  97. package/lib/util/parseGlob.js +36 -0
  98. package/lib/util/parseObjectStyles.js +15 -10
  99. package/lib/util/pluginUtils.js +159 -69
  100. package/lib/util/prefixSelector.js +30 -12
  101. package/lib/util/pseudoElements.js +229 -0
  102. package/lib/util/removeAlphaVariables.js +31 -0
  103. package/lib/util/resolveConfig.js +97 -75
  104. package/lib/util/resolveConfigPath.js +30 -12
  105. package/lib/util/responsive.js +11 -6
  106. package/lib/util/splitAtTopLevelOnly.js +51 -0
  107. package/lib/util/tap.js +6 -1
  108. package/lib/util/toColorValue.js +7 -3
  109. package/lib/util/toPath.js +26 -3
  110. package/lib/util/transformThemeValue.js +40 -30
  111. package/lib/util/validateConfig.js +37 -0
  112. package/lib/util/validateFormalSyntax.js +26 -0
  113. package/lib/util/withAlphaVariable.js +27 -15
  114. package/loadConfig.d.ts +4 -0
  115. package/loadConfig.js +2 -0
  116. package/nesting/index.js +2 -12
  117. package/package.json +66 -57
  118. package/peers/index.js +75964 -55560
  119. package/plugin.d.ts +11 -0
  120. package/plugin.js +2 -1
  121. package/resolveConfig.d.ts +12 -0
  122. package/resolveConfig.js +2 -1
  123. package/scripts/generate-types.js +105 -0
  124. package/scripts/release-channel.js +18 -0
  125. package/scripts/release-notes.js +21 -0
  126. package/scripts/swap-engines.js +40 -0
  127. package/scripts/type-utils.js +27 -0
  128. package/src/cli/build/deps.js +56 -0
  129. package/src/cli/build/index.js +49 -0
  130. package/src/cli/build/plugin.js +444 -0
  131. package/src/cli/build/utils.js +76 -0
  132. package/src/cli/build/watching.js +229 -0
  133. package/src/cli/help/index.js +70 -0
  134. package/src/cli/index.js +216 -0
  135. package/src/cli/init/index.js +79 -0
  136. package/src/cli-peer-dependencies.js +7 -1
  137. package/src/cli.js +4 -765
  138. package/src/corePluginList.js +1 -1
  139. package/src/corePlugins.js +786 -306
  140. package/src/css/preflight.css +10 -8
  141. package/src/featureFlags.js +21 -5
  142. package/src/index.js +1 -34
  143. package/src/lib/cacheInvalidation.js +52 -0
  144. package/src/lib/collapseAdjacentRules.js +21 -2
  145. package/src/lib/collapseDuplicateDeclarations.js +66 -1
  146. package/src/lib/content.js +208 -0
  147. package/src/lib/defaultExtractor.js +217 -0
  148. package/src/lib/detectNesting.js +9 -1
  149. package/src/lib/evaluateTailwindFunctions.js +79 -8
  150. package/src/lib/expandApplyAtRules.js +515 -153
  151. package/src/lib/expandTailwindAtRules.js +115 -86
  152. package/src/lib/findAtConfigPath.js +48 -0
  153. package/src/lib/generateRules.js +545 -147
  154. package/src/lib/getModuleDependencies.js +70 -30
  155. package/src/lib/load-config.ts +31 -0
  156. package/src/lib/normalizeTailwindDirectives.js +7 -1
  157. package/src/lib/offsets.js +373 -0
  158. package/src/lib/partitionApplyAtRules.js +52 -0
  159. package/src/lib/regex.js +74 -0
  160. package/src/lib/remap-bitfield.js +82 -0
  161. package/src/lib/resolveDefaultsAtRules.js +59 -17
  162. package/src/lib/setupContextUtils.js +701 -175
  163. package/src/lib/setupTrackingContext.js +51 -62
  164. package/src/lib/sharedState.js +58 -7
  165. package/src/oxide/cli/build/deps.ts +91 -0
  166. package/src/oxide/cli/build/index.ts +47 -0
  167. package/src/oxide/cli/build/plugin.ts +442 -0
  168. package/src/oxide/cli/build/utils.ts +74 -0
  169. package/src/oxide/cli/build/watching.ts +225 -0
  170. package/src/oxide/cli/help/index.ts +69 -0
  171. package/src/oxide/cli/index.ts +204 -0
  172. package/src/oxide/cli/init/index.ts +59 -0
  173. package/src/oxide/cli.ts +1 -0
  174. package/src/oxide/postcss-plugin.ts +1 -0
  175. package/src/plugin.js +107 -0
  176. package/src/postcss-plugins/nesting/README.md +42 -0
  177. package/src/postcss-plugins/nesting/index.js +13 -0
  178. package/src/postcss-plugins/nesting/plugin.js +80 -0
  179. package/src/processTailwindFeatures.js +12 -2
  180. package/src/public/colors.js +22 -0
  181. package/src/public/default-config.js +1 -1
  182. package/src/public/default-theme.js +2 -2
  183. package/src/public/load-config.js +2 -0
  184. package/src/util/applyImportantSelector.js +27 -0
  185. package/src/util/buildMediaQuery.js +5 -3
  186. package/src/util/cloneNodes.js +19 -2
  187. package/src/util/color.js +44 -12
  188. package/src/util/colorNames.js +150 -0
  189. package/src/util/dataTypes.js +51 -16
  190. package/src/util/defaults.js +6 -0
  191. package/src/util/formatVariantSelector.js +264 -144
  192. package/src/util/getAllConfigs.js +21 -2
  193. package/src/util/{isValidArbitraryValue.js → isSyntacticallyValidPropertyValue.js} +1 -1
  194. package/src/util/log.js +11 -7
  195. package/src/util/nameClass.js +4 -0
  196. package/src/util/negateValue.js +11 -3
  197. package/src/util/normalizeConfig.js +57 -5
  198. package/src/util/normalizeScreens.js +105 -7
  199. package/src/util/parseBoxShadowValue.js +4 -3
  200. package/src/util/parseDependency.js +37 -42
  201. package/src/util/parseGlob.js +24 -0
  202. package/src/util/pluginUtils.js +123 -24
  203. package/src/util/prefixSelector.js +30 -10
  204. package/src/util/pseudoElements.js +170 -0
  205. package/src/util/removeAlphaVariables.js +24 -0
  206. package/src/util/resolveConfig.js +74 -26
  207. package/src/util/resolveConfigPath.js +12 -1
  208. package/src/util/splitAtTopLevelOnly.js +52 -0
  209. package/src/util/toPath.js +23 -1
  210. package/src/util/transformThemeValue.js +13 -3
  211. package/src/util/validateConfig.js +26 -0
  212. package/src/util/validateFormalSyntax.js +34 -0
  213. package/src/util/withAlphaVariable.js +1 -1
  214. package/stubs/.gitignore +1 -0
  215. package/stubs/.prettierrc.json +6 -0
  216. package/stubs/{defaultConfig.stub.js → config.full.js} +206 -166
  217. package/stubs/postcss.config.js +6 -0
  218. package/stubs/tailwind.config.cjs +2 -0
  219. package/stubs/tailwind.config.js +2 -0
  220. package/stubs/tailwind.config.ts +3 -0
  221. package/types/config.d.ts +368 -0
  222. package/types/generated/.gitkeep +0 -0
  223. package/types/generated/colors.d.ts +298 -0
  224. package/types/generated/corePluginList.d.ts +1 -0
  225. package/types/generated/default-theme.d.ts +371 -0
  226. package/types/index.d.ts +7 -0
  227. package/CHANGELOG.md +0 -1843
  228. package/lib/constants.js +0 -37
  229. package/lib/lib/setupWatchingContext.js +0 -288
  230. package/nesting/plugin.js +0 -41
  231. package/scripts/install-integrations.js +0 -27
  232. package/scripts/rebuildFixtures.js +0 -68
  233. package/src/constants.js +0 -17
  234. package/src/lib/setupWatchingContext.js +0 -311
  235. /package/stubs/{simpleConfig.stub.js → config.simple.js} +0 -0
  236. /package/stubs/{defaultPostCssConfig.stub.js → postcss.config.cjs} +0 -0
@@ -2,26 +2,85 @@
2
2
  Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
- exports.generateRules = exports.resolveMatches = void 0;
6
- var _postcss = _interopRequireDefault(require("postcss"));
7
- var _postcssSelectorParser = _interopRequireDefault(require("postcss-selector-parser"));
8
- var _parseObjectStyles = _interopRequireDefault(require("../util/parseObjectStyles"));
9
- var _isPlainObject = _interopRequireDefault(require("../util/isPlainObject"));
10
- var _prefixSelector = _interopRequireDefault(require("../util/prefixSelector"));
11
- var _pluginUtils = require("../util/pluginUtils");
12
- var _log = _interopRequireDefault(require("../util/log"));
13
- var _formatVariantSelector = require("../util/formatVariantSelector");
14
- var _nameClass = require("../util/nameClass");
15
- var _dataTypes = require("../util/dataTypes");
16
- var _isValidArbitraryValue = _interopRequireDefault(require("../util/isValidArbitraryValue"));
17
- function _interopRequireDefault(obj) {
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: all[name]
9
+ });
10
+ }
11
+ _export(exports, {
12
+ getClassNameFromSelector: function() {
13
+ return getClassNameFromSelector;
14
+ },
15
+ resolveMatches: function() {
16
+ return resolveMatches;
17
+ },
18
+ generateRules: function() {
19
+ return generateRules;
20
+ }
21
+ });
22
+ const _postcss = /*#__PURE__*/ _interop_require_default(require("postcss"));
23
+ const _postcssselectorparser = /*#__PURE__*/ _interop_require_default(require("postcss-selector-parser"));
24
+ const _parseObjectStyles = /*#__PURE__*/ _interop_require_default(require("../util/parseObjectStyles"));
25
+ const _isPlainObject = /*#__PURE__*/ _interop_require_default(require("../util/isPlainObject"));
26
+ const _prefixSelector = /*#__PURE__*/ _interop_require_default(require("../util/prefixSelector"));
27
+ const _pluginUtils = require("../util/pluginUtils");
28
+ const _log = /*#__PURE__*/ _interop_require_default(require("../util/log"));
29
+ const _sharedState = /*#__PURE__*/ _interop_require_wildcard(require("./sharedState"));
30
+ const _formatVariantSelector = require("../util/formatVariantSelector");
31
+ const _nameClass = require("../util/nameClass");
32
+ const _dataTypes = require("../util/dataTypes");
33
+ const _setupContextUtils = require("./setupContextUtils");
34
+ const _isSyntacticallyValidPropertyValue = /*#__PURE__*/ _interop_require_default(require("../util/isSyntacticallyValidPropertyValue"));
35
+ const _splitAtTopLevelOnly = require("../util/splitAtTopLevelOnly.js");
36
+ const _featureFlags = require("../featureFlags");
37
+ const _applyImportantSelector = require("../util/applyImportantSelector");
38
+ function _interop_require_default(obj) {
18
39
  return obj && obj.__esModule ? obj : {
19
40
  default: obj
20
41
  };
21
42
  }
22
- let classNameParser = (0, _postcssSelectorParser).default((selectors)=>{
23
- return selectors.first.filter(({ type })=>type === 'class'
24
- ).pop().value;
43
+ function _getRequireWildcardCache(nodeInterop) {
44
+ if (typeof WeakMap !== "function") return null;
45
+ var cacheBabelInterop = new WeakMap();
46
+ var cacheNodeInterop = new WeakMap();
47
+ return (_getRequireWildcardCache = function(nodeInterop) {
48
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
49
+ })(nodeInterop);
50
+ }
51
+ function _interop_require_wildcard(obj, nodeInterop) {
52
+ if (!nodeInterop && obj && obj.__esModule) {
53
+ return obj;
54
+ }
55
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
56
+ return {
57
+ default: obj
58
+ };
59
+ }
60
+ var cache = _getRequireWildcardCache(nodeInterop);
61
+ if (cache && cache.has(obj)) {
62
+ return cache.get(obj);
63
+ }
64
+ var newObj = {};
65
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
66
+ for(var key in obj){
67
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
68
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
69
+ if (desc && (desc.get || desc.set)) {
70
+ Object.defineProperty(newObj, key, desc);
71
+ } else {
72
+ newObj[key] = obj[key];
73
+ }
74
+ }
75
+ }
76
+ newObj.default = obj;
77
+ if (cache) {
78
+ cache.set(obj, newObj);
79
+ }
80
+ return newObj;
81
+ }
82
+ let classNameParser = (0, _postcssselectorparser.default)((selectors)=>{
83
+ return selectors.first.filter(({ type })=>type === "class").pop().value;
25
84
  });
26
85
  function getClassNameFromSelector(selector) {
27
86
  return classNameParser.transformSync(selector);
@@ -33,35 +92,47 @@ function getClassNameFromSelector(selector) {
33
92
  // Example with dynamic classes:
34
93
  // ['grid-cols', '[[linename],1fr,auto]']
35
94
  // ['grid', 'cols-[[linename],1fr,auto]']
36
- function* candidatePermutations(candidate, lastIndex = Infinity) {
37
- if (lastIndex < 0) {
38
- return;
39
- }
40
- let dashIdx;
41
- if (lastIndex === Infinity && candidate.endsWith(']')) {
42
- let bracketIdx = candidate.indexOf('[');
43
- // If character before `[` isn't a dash or a slash, this isn't a dynamic class
44
- // eg. string[]
45
- dashIdx = [
46
- '-',
47
- '/'
48
- ].includes(candidate[bracketIdx - 1]) ? bracketIdx - 1 : -1;
49
- } else {
50
- dashIdx = candidate.lastIndexOf('-', lastIndex);
51
- }
52
- if (dashIdx < 0) {
53
- return;
54
- }
55
- let prefix = candidate.slice(0, dashIdx);
56
- let modifier = candidate.slice(dashIdx + 1);
57
- yield [
58
- prefix,
59
- modifier
60
- ];
61
- yield* candidatePermutations(candidate, dashIdx - 1);
95
+ function* candidatePermutations(candidate) {
96
+ let lastIndex = Infinity;
97
+ while(lastIndex >= 0){
98
+ let dashIdx;
99
+ let wasSlash = false;
100
+ if (lastIndex === Infinity && candidate.endsWith("]")) {
101
+ let bracketIdx = candidate.indexOf("[");
102
+ // If character before `[` isn't a dash or a slash, this isn't a dynamic class
103
+ // eg. string[]
104
+ if (candidate[bracketIdx - 1] === "-") {
105
+ dashIdx = bracketIdx - 1;
106
+ } else if (candidate[bracketIdx - 1] === "/") {
107
+ dashIdx = bracketIdx - 1;
108
+ wasSlash = true;
109
+ } else {
110
+ dashIdx = -1;
111
+ }
112
+ } else if (lastIndex === Infinity && candidate.includes("/")) {
113
+ dashIdx = candidate.lastIndexOf("/");
114
+ wasSlash = true;
115
+ } else {
116
+ dashIdx = candidate.lastIndexOf("-", lastIndex);
117
+ }
118
+ if (dashIdx < 0) {
119
+ break;
120
+ }
121
+ let prefix = candidate.slice(0, dashIdx);
122
+ let modifier = candidate.slice(wasSlash ? dashIdx : dashIdx + 1);
123
+ lastIndex = dashIdx - 1;
124
+ // TODO: This feels a bit hacky
125
+ if (prefix === "" || modifier === "/") {
126
+ continue;
127
+ }
128
+ yield [
129
+ prefix,
130
+ modifier
131
+ ];
132
+ }
62
133
  }
63
134
  function applyPrefix(matches, context) {
64
- if (matches.length === 0 || context.tailwindConfig.prefix === '') {
135
+ if (matches.length === 0 || context.tailwindConfig.prefix === "") {
65
136
  return matches;
66
137
  }
67
138
  for (let match of matches){
@@ -72,15 +143,21 @@ function applyPrefix(matches, context) {
72
143
  match[1].clone()
73
144
  ]
74
145
  });
146
+ let classCandidate = match[1].raws.tailwind.classCandidate;
75
147
  container.walkRules((r)=>{
76
- r.selector = (0, _prefixSelector).default(context.tailwindConfig.prefix, r.selector);
148
+ // If this is a negative utility with a dash *before* the prefix we
149
+ // have to ensure that the generated selector matches the candidate
150
+ // Not doing this will cause `-tw-top-1` to generate the class `.tw--top-1`
151
+ // The disconnect between candidate <-> class can cause @apply to hard crash.
152
+ let shouldPrependNegative = classCandidate.startsWith("-");
153
+ r.selector = (0, _prefixSelector.default)(context.tailwindConfig.prefix, r.selector, shouldPrependNegative);
77
154
  });
78
155
  match[1] = container.nodes[0];
79
156
  }
80
157
  }
81
158
  return matches;
82
159
  }
83
- function applyImportant(matches) {
160
+ function applyImportant(matches, classCandidate) {
84
161
  if (matches.length === 0) {
85
162
  return matches;
86
163
  }
@@ -92,11 +169,13 @@ function applyImportant(matches) {
92
169
  ]
93
170
  });
94
171
  container.walkRules((r)=>{
95
- r.selector = (0, _pluginUtils).updateAllClasses(r.selector, (className)=>{
96
- return `!${className}`;
97
- });
98
- r.walkDecls((d)=>d.important = true
99
- );
172
+ let ast = (0, _postcssselectorparser.default)().astSync(r.selector);
173
+ // Remove extraneous selectors that do not include the base candidate
174
+ ast.each((sel)=>(0, _formatVariantSelector.eliminateIrrelevantSelectors)(sel, classCandidate));
175
+ // Update all instances of the base candidate to include the important marker
176
+ (0, _pluginUtils.updateAllClasses)(ast, (className)=>className === classCandidate ? `!${className}` : className);
177
+ r.selector = ast.toString();
178
+ r.walkDecls((d)=>d.important = true);
100
179
  });
101
180
  result.push([
102
181
  {
@@ -120,28 +199,94 @@ function applyVariant(variant, matches, context) {
120
199
  if (matches.length === 0) {
121
200
  return matches;
122
201
  }
202
+ /** @type {{modifier: string | null, value: string | null}} */ let args = {
203
+ modifier: null,
204
+ value: _sharedState.NONE
205
+ };
206
+ // Retrieve "modifier"
207
+ {
208
+ let [baseVariant, ...modifiers] = (0, _splitAtTopLevelOnly.splitAtTopLevelOnly)(variant, "/");
209
+ // This is a hack to support variants with `/` in them, like `ar-1/10/20:text-red-500`
210
+ // In this case 1/10 is a value but /20 is a modifier
211
+ if (modifiers.length > 1) {
212
+ baseVariant = baseVariant + "/" + modifiers.slice(0, -1).join("/");
213
+ modifiers = modifiers.slice(-1);
214
+ }
215
+ if (modifiers.length && !context.variantMap.has(variant)) {
216
+ variant = baseVariant;
217
+ args.modifier = modifiers[0];
218
+ if (!(0, _featureFlags.flagEnabled)(context.tailwindConfig, "generalizedModifiers")) {
219
+ return [];
220
+ }
221
+ }
222
+ }
223
+ // Retrieve "arbitrary value"
224
+ if (variant.endsWith("]") && !variant.startsWith("[")) {
225
+ // We either have:
226
+ // @[200px]
227
+ // group-[:hover]
228
+ //
229
+ // But we don't want:
230
+ // @-[200px] (`-` is incorrect)
231
+ // group[:hover] (`-` is missing)
232
+ let match = /(.)(-?)\[(.*)\]/g.exec(variant);
233
+ if (match) {
234
+ let [, char, seperator, value] = match;
235
+ // @-[200px] case
236
+ if (char === "@" && seperator === "-") return [];
237
+ // group[:hover] case
238
+ if (char !== "@" && seperator === "") return [];
239
+ variant = variant.replace(`${seperator}[${value}]`, "");
240
+ args.value = value;
241
+ }
242
+ }
243
+ // Register arbitrary variants
244
+ if (isArbitraryValue(variant) && !context.variantMap.has(variant)) {
245
+ let sort = context.offsets.recordVariant(variant);
246
+ let selector = (0, _dataTypes.normalize)(variant.slice(1, -1));
247
+ let selectors = (0, _splitAtTopLevelOnly.splitAtTopLevelOnly)(selector, ",");
248
+ // We do not support multiple selectors for arbitrary variants
249
+ if (selectors.length > 1) {
250
+ return [];
251
+ }
252
+ if (!selectors.every(_setupContextUtils.isValidVariantFormatString)) {
253
+ return [];
254
+ }
255
+ let records = selectors.map((sel, idx)=>[
256
+ context.offsets.applyParallelOffset(sort, idx),
257
+ (0, _setupContextUtils.parseVariant)(sel.trim())
258
+ ]);
259
+ context.variantMap.set(variant, records);
260
+ }
123
261
  if (context.variantMap.has(variant)) {
124
- let variantFunctionTuples = context.variantMap.get(variant);
262
+ let isArbitraryVariant = isArbitraryValue(variant);
263
+ let variantFunctionTuples = context.variantMap.get(variant).slice();
125
264
  let result = [];
126
- for (let [meta, rule1] of matches){
265
+ for (let [meta, rule] of matches){
266
+ // Don't generate variants for user css
267
+ if (meta.layer === "user") {
268
+ continue;
269
+ }
127
270
  let container = _postcss.default.root({
128
271
  nodes: [
129
- rule1.clone()
272
+ rule.clone()
130
273
  ]
131
274
  });
132
- for (let [variantSort, variantFunction] of variantFunctionTuples){
133
- let clone = container.clone();
275
+ for (let [variantSort, variantFunction, containerFromArray] of variantFunctionTuples){
276
+ let clone = (containerFromArray !== null && containerFromArray !== void 0 ? containerFromArray : container).clone();
134
277
  let collectedFormats = [];
135
- let originals = new Map();
136
278
  function prepareBackup() {
137
- if (originals.size > 0) return; // Already prepared, chicken out
138
- clone.walkRules((rule)=>originals.set(rule, rule.selector)
139
- );
279
+ // Already prepared, chicken out
280
+ if (clone.raws.neededBackup) {
281
+ return;
282
+ }
283
+ clone.raws.neededBackup = true;
284
+ clone.walkRules((rule)=>rule.raws.originalSelector = rule.selector);
140
285
  }
141
286
  function modifySelectors(modifierFunction) {
142
287
  prepareBackup();
143
288
  clone.each((rule)=>{
144
- if (rule.type !== 'rule') {
289
+ if (rule.type !== "rule") {
145
290
  return;
146
291
  }
147
292
  rule.selectors = rule.selectors.map((selector)=>{
@@ -171,29 +316,56 @@ function applyVariant(variant, matches, context) {
171
316
  clone.append(wrapper);
172
317
  },
173
318
  format (selectorFormat) {
174
- collectedFormats.push(selectorFormat);
175
- }
319
+ collectedFormats.push({
320
+ format: selectorFormat,
321
+ isArbitraryVariant
322
+ });
323
+ },
324
+ args
176
325
  });
177
- if (typeof ruleWithVariant === 'string') {
178
- collectedFormats.push(ruleWithVariant);
326
+ // It can happen that a list of format strings is returned from within the function. In that
327
+ // case, we have to process them as well. We can use the existing `variantSort`.
328
+ if (Array.isArray(ruleWithVariant)) {
329
+ for (let [idx, variantFunction] of ruleWithVariant.entries()){
330
+ // This is a little bit scary since we are pushing to an array of items that we are
331
+ // currently looping over. However, you can also think of it like a processing queue
332
+ // where you keep handling jobs until everything is done and each job can queue more
333
+ // jobs if needed.
334
+ variantFunctionTuples.push([
335
+ context.offsets.applyParallelOffset(variantSort, idx),
336
+ variantFunction,
337
+ // If the clone has been modified we have to pass that back
338
+ // though so each rule can use the modified container
339
+ clone.clone()
340
+ ]);
341
+ }
342
+ continue;
343
+ }
344
+ if (typeof ruleWithVariant === "string") {
345
+ collectedFormats.push({
346
+ format: ruleWithVariant,
347
+ isArbitraryVariant
348
+ });
179
349
  }
180
350
  if (ruleWithVariant === null) {
181
351
  continue;
182
352
  }
183
- // We filled the `originals`, therefore we assume that somebody touched
353
+ // We had to backup selectors, therefore we assume that somebody touched
184
354
  // `container` or `modifySelectors`. Let's see if they did, so that we
185
355
  // can restore the selectors, and collect the format strings.
186
- if (originals.size > 0) {
356
+ if (clone.raws.neededBackup) {
357
+ delete clone.raws.neededBackup;
187
358
  clone.walkRules((rule)=>{
188
- if (!originals.has(rule)) return;
189
- let before = originals.get(rule);
359
+ let before = rule.raws.originalSelector;
360
+ if (!before) return;
361
+ delete rule.raws.originalSelector;
190
362
  if (before === rule.selector) return; // No mutation happened
191
363
  let modified = rule.selector;
192
364
  // Rebuild the base selector, this is what plugin authors would do
193
365
  // as well. E.g.: `${variant}${separator}${className}`.
194
366
  // However, plugin authors probably also prepend or append certain
195
367
  // classes, pseudos, ids, ...
196
- let rebuiltBase = (0, _postcssSelectorParser).default((selectors)=>{
368
+ let rebuiltBase = (0, _postcssselectorparser.default)((selectors)=>{
197
369
  selectors.walkClasses((classNode)=>{
198
370
  classNode.value = `${variant}${context.tailwindConfig.separator}${classNode.value}`;
199
371
  });
@@ -209,18 +381,29 @@ function applyVariant(variant, matches, context) {
209
381
  // modified (by plugin): .foo .foo\\:markdown > p
210
382
  // rebuiltBase (internal): .foo\\:markdown > p
211
383
  // format: .foo &
212
- collectedFormats.push(modified.replace(rebuiltBase, '&'));
384
+ collectedFormats.push({
385
+ format: modified.replace(rebuiltBase, "&"),
386
+ isArbitraryVariant
387
+ });
213
388
  rule.selector = before;
214
389
  });
215
390
  }
216
- var _collectedFormats;
391
+ // This tracks the originating layer for the variant
392
+ // For example:
393
+ // .sm:underline {} is a variant of something in the utilities layer
394
+ // .sm:container {} is a variant of the container component
395
+ clone.nodes[0].raws.tailwind = {
396
+ ...clone.nodes[0].raws.tailwind,
397
+ parentLayer: meta.layer
398
+ };
399
+ var _meta_collectedFormats;
217
400
  let withOffset = [
218
401
  {
219
402
  ...meta,
220
- sort: variantSort | meta.sort,
221
- collectedFormats: ((_collectedFormats = meta.collectedFormats) !== null && _collectedFormats !== void 0 ? _collectedFormats : []).concat(collectedFormats)
403
+ sort: context.offsets.applyVariantOffset(meta.sort, variantSort, Object.assign(args, context.variantOptions.get(variant))),
404
+ collectedFormats: ((_meta_collectedFormats = meta.collectedFormats) !== null && _meta_collectedFormats !== void 0 ? _meta_collectedFormats : []).concat(collectedFormats)
222
405
  },
223
- clone.nodes[0],
406
+ clone.nodes[0]
224
407
  ];
225
408
  result.push(withOffset);
226
409
  }
@@ -229,10 +412,9 @@ function applyVariant(variant, matches, context) {
229
412
  }
230
413
  return [];
231
414
  }
232
- function parseRules(rule, cache, options = {
233
- }) {
415
+ function parseRules(rule, cache, options = {}) {
234
416
  // PostCSS node
235
- if (!(0, _isPlainObject).default(rule) && !Array.isArray(rule)) {
417
+ if (!(0, _isPlainObject.default)(rule) && !Array.isArray(rule)) {
236
418
  return [
237
419
  [
238
420
  rule
@@ -246,65 +428,117 @@ function parseRules(rule, cache, options = {
246
428
  }
247
429
  // Simple object
248
430
  if (!cache.has(rule)) {
249
- cache.set(rule, (0, _parseObjectStyles).default(rule));
431
+ cache.set(rule, (0, _parseObjectStyles.default)(rule));
250
432
  }
251
433
  return [
252
434
  cache.get(rule),
253
435
  options
254
436
  ];
255
437
  }
438
+ const IS_VALID_PROPERTY_NAME = /^[a-z_-]/;
439
+ function isValidPropName(name) {
440
+ return IS_VALID_PROPERTY_NAME.test(name);
441
+ }
442
+ /**
443
+ * @param {string} declaration
444
+ * @returns {boolean}
445
+ */ function looksLikeUri(declaration) {
446
+ // Quick bailout for obvious non-urls
447
+ // This doesn't support schemes that don't use a leading // but that's unlikely to be a problem
448
+ if (!declaration.includes("://")) {
449
+ return false;
450
+ }
451
+ try {
452
+ const url = new URL(declaration);
453
+ return url.scheme !== "" && url.host !== "";
454
+ } catch (err) {
455
+ // Definitely not a valid url
456
+ return false;
457
+ }
458
+ }
459
+ function isParsableNode(node) {
460
+ let isParsable = true;
461
+ node.walkDecls((decl)=>{
462
+ if (!isParsableCssValue(decl.prop, decl.value)) {
463
+ isParsable = false;
464
+ return false;
465
+ }
466
+ });
467
+ return isParsable;
468
+ }
469
+ function isParsableCssValue(property, value) {
470
+ // We don't want to to treat [https://example.com] as a custom property
471
+ // Even though, according to the CSS grammar, it's a totally valid CSS declaration
472
+ // So we short-circuit here by checking if the custom property looks like a url
473
+ if (looksLikeUri(`${property}:${value}`)) {
474
+ return false;
475
+ }
476
+ try {
477
+ _postcss.default.parse(`a{${property}:${value}}`).toResult();
478
+ return true;
479
+ } catch (err) {
480
+ return false;
481
+ }
482
+ }
256
483
  function extractArbitraryProperty(classCandidate, context) {
257
- var ref;
258
- let [, property, value] = (ref = classCandidate.match(/^\[([a-zA-Z0-9-_]+):(\S+)\]$/)) !== null && ref !== void 0 ? ref : [];
484
+ var _classCandidate_match;
485
+ let [, property, value] = (_classCandidate_match = classCandidate.match(/^\[([a-zA-Z0-9-_]+):(\S+)\]$/)) !== null && _classCandidate_match !== void 0 ? _classCandidate_match : [];
259
486
  if (value === undefined) {
260
487
  return null;
261
488
  }
262
- let normalized = (0, _dataTypes).normalize(value);
263
- if (!(0, _isValidArbitraryValue).default(normalized)) {
489
+ if (!isValidPropName(property)) {
490
+ return null;
491
+ }
492
+ if (!(0, _isSyntacticallyValidPropertyValue.default)(value)) {
264
493
  return null;
265
494
  }
495
+ let normalized = (0, _dataTypes.normalize)(value);
496
+ if (!isParsableCssValue(property, normalized)) {
497
+ return null;
498
+ }
499
+ let sort = context.offsets.arbitraryProperty();
266
500
  return [
267
501
  [
268
502
  {
269
- sort: context.arbitraryPropertiesSort,
270
- layer: 'utilities'
503
+ sort,
504
+ layer: "utilities"
271
505
  },
272
506
  ()=>({
273
- [(0, _nameClass).asClass(classCandidate)]: {
507
+ [(0, _nameClass.asClass)(classCandidate)]: {
274
508
  [property]: normalized
275
509
  }
276
510
  })
277
- ,
278
- ],
511
+ ]
279
512
  ];
280
513
  }
281
514
  function* resolveMatchedPlugins(classCandidate, context) {
282
515
  if (context.candidateRuleMap.has(classCandidate)) {
283
516
  yield [
284
517
  context.candidateRuleMap.get(classCandidate),
285
- 'DEFAULT'
518
+ "DEFAULT"
286
519
  ];
287
520
  }
288
- yield* (function*(arbitraryPropertyRule) {
521
+ yield* function*(arbitraryPropertyRule) {
289
522
  if (arbitraryPropertyRule !== null) {
290
523
  yield [
291
524
  arbitraryPropertyRule,
292
- 'DEFAULT'
525
+ "DEFAULT"
293
526
  ];
294
527
  }
295
- })(extractArbitraryProperty(classCandidate, context));
528
+ }(extractArbitraryProperty(classCandidate, context));
296
529
  let candidatePrefix = classCandidate;
297
530
  let negative = false;
298
531
  const twConfigPrefix = context.tailwindConfig.prefix;
299
532
  const twConfigPrefixLen = twConfigPrefix.length;
300
- if (candidatePrefix[twConfigPrefixLen] === '-') {
533
+ const hasMatchingPrefix = candidatePrefix.startsWith(twConfigPrefix) || candidatePrefix.startsWith(`-${twConfigPrefix}`);
534
+ if (candidatePrefix[twConfigPrefixLen] === "-" && hasMatchingPrefix) {
301
535
  negative = true;
302
536
  candidatePrefix = twConfigPrefix + candidatePrefix.slice(twConfigPrefixLen + 1);
303
537
  }
304
538
  if (negative && context.candidateRuleMap.has(candidatePrefix)) {
305
539
  yield [
306
540
  context.candidateRuleMap.get(candidatePrefix),
307
- '-DEFAULT'
541
+ "-DEFAULT"
308
542
  ];
309
543
  }
310
544
  for (let [prefix, modifier] of candidatePermutations(candidatePrefix)){
@@ -313,21 +547,45 @@ function* resolveMatchedPlugins(classCandidate, context) {
313
547
  context.candidateRuleMap.get(prefix),
314
548
  negative ? `-${modifier}` : modifier
315
549
  ];
316
- return;
317
550
  }
318
551
  }
319
552
  }
320
553
  function splitWithSeparator(input, separator) {
321
- return input.split(new RegExp(`\\${separator}(?![^[]*\\])`, 'g'));
554
+ if (input === _sharedState.NOT_ON_DEMAND) {
555
+ return [
556
+ _sharedState.NOT_ON_DEMAND
557
+ ];
558
+ }
559
+ return (0, _splitAtTopLevelOnly.splitAtTopLevelOnly)(input, separator);
560
+ }
561
+ function* recordCandidates(matches, classCandidate) {
562
+ for (const match of matches){
563
+ var _match__options;
564
+ var _match__options_preserveSource;
565
+ match[1].raws.tailwind = {
566
+ ...match[1].raws.tailwind,
567
+ classCandidate,
568
+ preserveSource: (_match__options_preserveSource = (_match__options = match[0].options) === null || _match__options === void 0 ? void 0 : _match__options.preserveSource) !== null && _match__options_preserveSource !== void 0 ? _match__options_preserveSource : false
569
+ };
570
+ yield match;
571
+ }
322
572
  }
323
- function* resolveMatches(candidate, context) {
573
+ function* resolveMatches(candidate, context, original = candidate) {
324
574
  let separator = context.tailwindConfig.separator;
325
575
  let [classCandidate, ...variants] = splitWithSeparator(candidate, separator).reverse();
326
576
  let important = false;
327
- if (classCandidate.startsWith('!')) {
577
+ if (classCandidate.startsWith("!")) {
328
578
  important = true;
329
579
  classCandidate = classCandidate.slice(1);
330
580
  }
581
+ if ((0, _featureFlags.flagEnabled)(context.tailwindConfig, "variantGrouping")) {
582
+ if (classCandidate.startsWith("(") && classCandidate.endsWith(")")) {
583
+ let base = variants.slice().reverse().join(separator);
584
+ for (let part of (0, _splitAtTopLevelOnly.splitAtTopLevelOnly)(classCandidate.slice(1, -1), ",")){
585
+ yield* resolveMatches(base + separator + part, context, original);
586
+ }
587
+ }
588
+ }
331
589
  // TODO: Reintroduce this in ways that doesn't break on false positives
332
590
  // function sortAgainst(toSort, against) {
333
591
  // return toSort.slice().sort((a, z) => {
@@ -346,7 +604,7 @@ function* resolveMatches(candidate, context) {
346
604
  let isOnlyPlugin = plugins.length === 1;
347
605
  for (let [sort, plugin] of plugins){
348
606
  let matchesPerPlugin = [];
349
- if (typeof plugin === 'function') {
607
+ if (typeof plugin === "function") {
350
608
  for (let ruleSet of [].concat(plugin(modifier, {
351
609
  isOnlyPlugin
352
610
  }))){
@@ -364,7 +622,7 @@ function* resolveMatches(candidate, context) {
364
622
  ]);
365
623
  }
366
624
  }
367
- } else if (modifier === 'DEFAULT' || modifier === '-DEFAULT') {
625
+ } else if (modifier === "DEFAULT" || modifier === "-DEFAULT") {
368
626
  let ruleSet = plugin;
369
627
  let [rules, options] = parseRules(ruleSet, context.postCssNodeCache);
370
628
  for (let rule of rules){
@@ -381,95 +639,211 @@ function* resolveMatches(candidate, context) {
381
639
  }
382
640
  }
383
641
  if (matchesPerPlugin.length > 0) {
384
- var ref;
385
- typesByMatches.set(matchesPerPlugin, (ref = sort.options) === null || ref === void 0 ? void 0 : ref.type);
642
+ var _sort_options;
643
+ var _sort_options_types, _sort_options1;
644
+ let matchingTypes = Array.from((0, _pluginUtils.getMatchingTypes)((_sort_options_types = (_sort_options = sort.options) === null || _sort_options === void 0 ? void 0 : _sort_options.types) !== null && _sort_options_types !== void 0 ? _sort_options_types : [], modifier, (_sort_options1 = sort.options) !== null && _sort_options1 !== void 0 ? _sort_options1 : {}, context.tailwindConfig)).map(([_, type])=>type);
645
+ if (matchingTypes.length > 0) {
646
+ typesByMatches.set(matchesPerPlugin, matchingTypes);
647
+ }
386
648
  matches.push(matchesPerPlugin);
387
649
  }
388
650
  }
389
- // Only keep the result of the very first plugin if we are dealing with
390
- // arbitrary values, to protect against ambiguity.
391
- if (isArbitraryValue(modifier) && matches.length > 1) {
392
- var ref1;
393
- let typesPerPlugin = matches.map((match)=>new Set([
394
- ...(ref1 = typesByMatches.get(match)) !== null && ref1 !== void 0 ? ref1 : []
395
- ])
396
- );
397
- // Remove duplicates, so that we can detect proper unique types for each plugin.
398
- for (let pluginTypes of typesPerPlugin){
399
- for (let type of pluginTypes){
400
- let removeFromOwnGroup = false;
401
- for (let otherGroup of typesPerPlugin){
402
- if (pluginTypes === otherGroup) continue;
403
- if (otherGroup.has(type)) {
404
- otherGroup.delete(type);
405
- removeFromOwnGroup = true;
406
- }
651
+ if (isArbitraryValue(modifier)) {
652
+ if (matches.length > 1) {
653
+ // Partition plugins in 2 categories so that we can start searching in the plugins that
654
+ // don't have `any` as a type first.
655
+ let [withAny, withoutAny] = matches.reduce((group, plugin)=>{
656
+ let hasAnyType = plugin.some(([{ options }])=>options.types.some(({ type })=>type === "any"));
657
+ if (hasAnyType) {
658
+ group[0].push(plugin);
659
+ } else {
660
+ group[1].push(plugin);
407
661
  }
408
- if (removeFromOwnGroup) pluginTypes.delete(type);
662
+ return group;
663
+ }, [
664
+ [],
665
+ []
666
+ ]);
667
+ function findFallback(matches) {
668
+ // If only a single plugin matches, let's take that one
669
+ if (matches.length === 1) {
670
+ return matches[0];
671
+ }
672
+ // Otherwise, find the plugin that creates a valid rule given the arbitrary value, and
673
+ // also has the correct type which preferOnConflicts the plugin in case of clashes.
674
+ return matches.find((rules)=>{
675
+ let matchingTypes = typesByMatches.get(rules);
676
+ return rules.some(([{ options }, rule])=>{
677
+ if (!isParsableNode(rule)) {
678
+ return false;
679
+ }
680
+ return options.types.some(({ type , preferOnConflict })=>matchingTypes.includes(type) && preferOnConflict);
681
+ });
682
+ });
409
683
  }
410
- }
411
- let messages = [];
412
- for (let [idx, group] of typesPerPlugin.entries()){
413
- for (let type of group){
414
- let rules = matches[idx].map(([, rule])=>rule
415
- ).flat().map((rule)=>rule.toString().split('\n').slice(1, -1) // Remove selector and closing '}'
416
- .map((line)=>line.trim()
417
- ).map((x)=>` ${x}`
418
- ) // Re-indent
419
- .join('\n')
420
- ).join('\n\n');
421
- messages.push(` Use \`${candidate.replace('[', `[${type}:`)}\` for \`${rules.trim()}\``);
422
- break;
684
+ var _findFallback;
685
+ // Try to find a fallback plugin, because we already know that multiple plugins matched for
686
+ // the given arbitrary value.
687
+ let fallback = (_findFallback = findFallback(withoutAny)) !== null && _findFallback !== void 0 ? _findFallback : findFallback(withAny);
688
+ if (fallback) {
689
+ matches = [
690
+ fallback
691
+ ];
692
+ } else {
693
+ var _typesByMatches_get;
694
+ let typesPerPlugin = matches.map((match)=>new Set([
695
+ ...(_typesByMatches_get = typesByMatches.get(match)) !== null && _typesByMatches_get !== void 0 ? _typesByMatches_get : []
696
+ ]));
697
+ // Remove duplicates, so that we can detect proper unique types for each plugin.
698
+ for (let pluginTypes of typesPerPlugin){
699
+ for (let type of pluginTypes){
700
+ let removeFromOwnGroup = false;
701
+ for (let otherGroup of typesPerPlugin){
702
+ if (pluginTypes === otherGroup) continue;
703
+ if (otherGroup.has(type)) {
704
+ otherGroup.delete(type);
705
+ removeFromOwnGroup = true;
706
+ }
707
+ }
708
+ if (removeFromOwnGroup) pluginTypes.delete(type);
709
+ }
710
+ }
711
+ let messages = [];
712
+ for (let [idx, group] of typesPerPlugin.entries()){
713
+ for (let type of group){
714
+ let rules = matches[idx].map(([, rule])=>rule).flat().map((rule)=>rule.toString().split("\n").slice(1, -1) // Remove selector and closing '}'
715
+ .map((line)=>line.trim()).map((x)=>` ${x}`) // Re-indent
716
+ .join("\n")).join("\n\n");
717
+ messages.push(` Use \`${candidate.replace("[", `[${type}:`)}\` for \`${rules.trim()}\``);
718
+ break;
719
+ }
720
+ }
721
+ _log.default.warn([
722
+ `The class \`${candidate}\` is ambiguous and matches multiple utilities.`,
723
+ ...messages,
724
+ `If this is content and not a class, replace it with \`${candidate.replace("[", "&lsqb;").replace("]", "&rsqb;")}\` to silence this warning.`
725
+ ]);
726
+ continue;
423
727
  }
424
728
  }
425
- _log.default.warn([
426
- `The class \`${candidate}\` is ambiguous and matches multiple utilities.`,
427
- ...messages,
428
- `If this is content and not a class, replace it with \`${candidate.replace('[', '&lsqb;').replace(']', '&rsqb;')}\` to silence this warning.`,
429
- ]);
430
- continue;
729
+ matches = matches.map((list)=>list.filter((match)=>isParsableNode(match[1])));
431
730
  }
432
- matches = applyPrefix(matches.flat(), context);
731
+ matches = matches.flat();
732
+ matches = Array.from(recordCandidates(matches, classCandidate));
733
+ matches = applyPrefix(matches, context);
433
734
  if (important) {
434
- matches = applyImportant(matches, context);
735
+ matches = applyImportant(matches, classCandidate);
435
736
  }
436
737
  for (let variant of variants){
437
738
  matches = applyVariant(variant, matches, context);
438
739
  }
439
- for (let match1 of matches){
740
+ for (let match of matches){
741
+ match[1].raws.tailwind = {
742
+ ...match[1].raws.tailwind,
743
+ candidate
744
+ };
440
745
  // Apply final format selector
441
- if (match1[0].collectedFormats) {
442
- let finalFormat = (0, _formatVariantSelector).formatVariantSelector('&', ...match1[0].collectedFormats);
443
- let container = _postcss.default.root({
444
- nodes: [
445
- match1[1].clone()
446
- ]
447
- });
448
- container.walkRules((rule)=>{
449
- if (inKeyframes(rule)) return;
450
- rule.selector = (0, _formatVariantSelector).finalizeSelector(finalFormat, {
451
- selector: rule.selector,
452
- candidate,
453
- context
454
- });
455
- });
456
- match1[1] = container.nodes[0];
746
+ match = applyFinalFormat(match, {
747
+ context,
748
+ candidate,
749
+ original
750
+ });
751
+ // Skip rules with invalid selectors
752
+ // This will cause the candidate to be added to the "not class"
753
+ // cache skipping it entirely for future builds
754
+ if (match === null) {
755
+ continue;
457
756
  }
458
- yield match1;
757
+ yield match;
459
758
  }
460
759
  }
461
760
  }
761
+ function applyFinalFormat(match, { context , candidate , original }) {
762
+ if (!match[0].collectedFormats) {
763
+ return match;
764
+ }
765
+ let isValid = true;
766
+ let finalFormat;
767
+ try {
768
+ finalFormat = (0, _formatVariantSelector.formatVariantSelector)(match[0].collectedFormats, {
769
+ context,
770
+ candidate
771
+ });
772
+ } catch {
773
+ // The format selector we produced is invalid
774
+ // This could be because:
775
+ // - A bug exists
776
+ // - A plugin introduced an invalid variant selector (ex: `addVariant('foo', '&;foo')`)
777
+ // - The user used an invalid arbitrary variant (ex: `[&;foo]:underline`)
778
+ // Either way the build will fail because of this
779
+ // We would rather that the build pass "silently" given that this could
780
+ // happen because of picking up invalid things when scanning content
781
+ // So we'll throw out the candidate instead
782
+ return null;
783
+ }
784
+ let container = _postcss.default.root({
785
+ nodes: [
786
+ match[1].clone()
787
+ ]
788
+ });
789
+ container.walkRules((rule)=>{
790
+ if (inKeyframes(rule)) {
791
+ return;
792
+ }
793
+ try {
794
+ rule.selector = (0, _formatVariantSelector.finalizeSelector)(rule.selector, finalFormat, {
795
+ candidate: original,
796
+ context
797
+ });
798
+ } catch {
799
+ // If this selector is invalid we also want to skip it
800
+ // But it's likely that being invalid here means there's a bug in a plugin rather than too loosely matching content
801
+ isValid = false;
802
+ return false;
803
+ }
804
+ });
805
+ if (!isValid) {
806
+ return null;
807
+ }
808
+ match[1] = container.nodes[0];
809
+ return match;
810
+ }
462
811
  function inKeyframes(rule) {
463
- return rule.parent && rule.parent.type === 'atrule' && rule.parent.name === 'keyframes';
812
+ return rule.parent && rule.parent.type === "atrule" && rule.parent.name === "keyframes";
813
+ }
814
+ function getImportantStrategy(important) {
815
+ if (important === true) {
816
+ return (rule)=>{
817
+ if (inKeyframes(rule)) {
818
+ return;
819
+ }
820
+ rule.walkDecls((d)=>{
821
+ if (d.parent.type === "rule" && !inKeyframes(d.parent)) {
822
+ d.important = true;
823
+ }
824
+ });
825
+ };
826
+ }
827
+ if (typeof important === "string") {
828
+ return (rule)=>{
829
+ if (inKeyframes(rule)) {
830
+ return;
831
+ }
832
+ rule.selectors = rule.selectors.map((selector)=>{
833
+ return (0, _applyImportantSelector.applyImportantSelector)(selector, important);
834
+ });
835
+ };
836
+ }
464
837
  }
465
838
  function generateRules(candidates, context) {
466
839
  let allRules = [];
840
+ let strategy = getImportantStrategy(context.tailwindConfig.important);
467
841
  for (let candidate of candidates){
468
842
  if (context.notClassCache.has(candidate)) {
469
843
  continue;
470
844
  }
471
- if (context.classCache.has(candidate)) {
472
- allRules.push(context.classCache.get(candidate));
845
+ if (context.candidateRuleCache.has(candidate)) {
846
+ allRules = allRules.concat(Array.from(context.candidateRuleCache.get(candidate)));
473
847
  continue;
474
848
  }
475
849
  let matches = Array.from(resolveMatches(candidate, context));
@@ -478,52 +852,31 @@ function generateRules(candidates, context) {
478
852
  continue;
479
853
  }
480
854
  context.classCache.set(candidate, matches);
481
- allRules.push(matches);
482
- }
483
- // Strategy based on `tailwindConfig.important`
484
- let strategy = ((important)=>{
485
- if (important === true) {
486
- return (rule)=>{
487
- rule.walkDecls((d)=>{
488
- if (d.parent.type === 'rule' && !inKeyframes(d.parent)) {
489
- d.important = true;
490
- }
491
- });
492
- };
493
- }
494
- if (typeof important === 'string') {
495
- return (rule)=>{
496
- rule.selectors = rule.selectors.map((selector)=>{
497
- return `${important} ${selector}`;
498
- });
499
- };
500
- }
501
- })(context.tailwindConfig.important);
502
- return allRules.flat(1).map(([{ sort , layer , options }, rule])=>{
503
- if (options.respectImportant) {
504
- if (strategy) {
855
+ var _context_candidateRuleCache_get;
856
+ let rules = (_context_candidateRuleCache_get = context.candidateRuleCache.get(candidate)) !== null && _context_candidateRuleCache_get !== void 0 ? _context_candidateRuleCache_get : new Set();
857
+ context.candidateRuleCache.set(candidate, rules);
858
+ for (const match of matches){
859
+ let [{ sort , options }, rule] = match;
860
+ if (options.respectImportant && strategy) {
505
861
  let container = _postcss.default.root({
506
862
  nodes: [
507
863
  rule.clone()
508
864
  ]
509
865
  });
510
- container.walkRules((r)=>{
511
- if (inKeyframes(r)) {
512
- return;
513
- }
514
- strategy(r);
515
- });
866
+ container.walkRules(strategy);
516
867
  rule = container.nodes[0];
517
868
  }
869
+ let newEntry = [
870
+ sort,
871
+ rule
872
+ ];
873
+ rules.add(newEntry);
874
+ context.ruleCache.add(newEntry);
875
+ allRules.push(newEntry);
518
876
  }
519
- return [
520
- sort | context.layerOrder[layer],
521
- rule
522
- ];
523
- });
877
+ }
878
+ return allRules;
524
879
  }
525
880
  function isArbitraryValue(input) {
526
- return input.startsWith('[') && input.endsWith(']');
881
+ return input.startsWith("[") && input.endsWith("]");
527
882
  }
528
- exports.resolveMatches = resolveMatches;
529
- exports.generateRules = generateRules;