@weapp-tailwindcss/postcss 2.1.4 → 2.1.5-beta.0

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/dist/index.js CHANGED
@@ -1037,6 +1037,55 @@ function normalizeSpacingDeclarations(rule) {
1037
1037
  // src/selectorParser/rule-transformer.ts
1038
1038
  var ruleTransformCache = /* @__PURE__ */ new WeakMap();
1039
1039
  var SELECTOR_TRANSFORM_OPTIONS = normalizeTransformOptions();
1040
+ var SIMPLE_SELECTOR_FAST_PATH = /^[#.][\w-]+(?:\s+[#.][\w-]+)*$/;
1041
+ var RTL_LANGUAGE_ANY_PSEUDO_SET = /* @__PURE__ */ new Set([
1042
+ ":-moz-any",
1043
+ ":-webkit-any",
1044
+ ":lang"
1045
+ ]);
1046
+ var EMPTY_FUNCTIONAL_PSEUDO_CLEANUP_SET = /* @__PURE__ */ new Set([
1047
+ ":not",
1048
+ ":is",
1049
+ ":where",
1050
+ ":has",
1051
+ ":matches",
1052
+ ":-webkit-any",
1053
+ ":-moz-any",
1054
+ ":lang"
1055
+ ]);
1056
+ function isRtlLanguageAnyPseudo(node) {
1057
+ return node.type === "pseudo" && RTL_LANGUAGE_ANY_PSEUDO_SET.has(node.value);
1058
+ }
1059
+ function getTopLevelSelector(node) {
1060
+ let current = node;
1061
+ let topLevel = node;
1062
+ while (current.parent) {
1063
+ const parent = current.parent;
1064
+ if (parent.type === "root") {
1065
+ break;
1066
+ }
1067
+ if (parent.type === "selector") {
1068
+ topLevel = parent;
1069
+ }
1070
+ current = parent;
1071
+ }
1072
+ return topLevel;
1073
+ }
1074
+ function stripUnsupportedRtlLanguagePseudo(node) {
1075
+ const selectorParent = node.parent;
1076
+ if (!selectorParent || selectorParent.type !== "selector") {
1077
+ return;
1078
+ }
1079
+ const maybeNot = selectorParent.parent;
1080
+ if (maybeNot && maybeNot.type === "pseudo" && maybeNot.value === ":not") {
1081
+ maybeNot.remove();
1082
+ return;
1083
+ }
1084
+ getTopLevelSelector(selectorParent).remove();
1085
+ }
1086
+ function shouldRemoveEmptyFunctionalPseudo(node) {
1087
+ return node.type === "pseudo" && EMPTY_FUNCTIONAL_PSEUDO_CLEANUP_SET.has(node.value) && Array.isArray(node.nodes) && node.nodes.length === 0;
1088
+ }
1040
1089
  function flattenWherePseudo(node, context, index, parent) {
1041
1090
  if (isUniAppXEnabled(context.options)) {
1042
1091
  node.value = ":is";
@@ -1074,6 +1123,13 @@ function shouldRemoveHoverSelector(selector, options) {
1074
1123
  }
1075
1124
  return selector.nodes.some((node) => node.type === "pseudo" && node.value === ":hover");
1076
1125
  }
1126
+ var UNSUPPORTED_PSEUDO_ELEMENT_SELECTOR_SET = /* @__PURE__ */ new Set([
1127
+ "::backdrop",
1128
+ "::file-selector-button"
1129
+ ]);
1130
+ function shouldRemoveUnsupportedPseudoElementSelector(selector) {
1131
+ return selector.nodes.some((node) => node.type === "pseudo" && UNSUPPORTED_PSEUDO_ELEMENT_SELECTOR_SET.has(node.value));
1132
+ }
1077
1133
  function isHiddenOrTemplateNotPseudo(node) {
1078
1134
  if (!node || node.type !== "pseudo" || node.value !== ":not") {
1079
1135
  return false;
@@ -1114,6 +1170,10 @@ function handlePseudoNode(node, index, context, parent) {
1114
1170
  if (node.type !== "pseudo") {
1115
1171
  return;
1116
1172
  }
1173
+ if (isRtlLanguageAnyPseudo(node)) {
1174
+ stripUnsupportedRtlLanguagePseudo(node);
1175
+ return;
1176
+ }
1117
1177
  if (node.value === ":root" && _optionalChain([context, 'access', _40 => _40.options, 'access', _41 => _41.cssSelectorReplacement, 'optionalAccess', _42 => _42.root])) {
1118
1178
  node.value = composeIsPseudo(context.options.cssSelectorReplacement.root);
1119
1179
  return;
@@ -1126,6 +1186,10 @@ function handleTagOrAttribute(node, context) {
1126
1186
  stripUnsupportedNodeForUniAppX(node, context.options);
1127
1187
  }
1128
1188
  function handleSelectorNode(selector, context) {
1189
+ if (shouldRemoveUnsupportedPseudoElementSelector(selector)) {
1190
+ selector.remove();
1191
+ return;
1192
+ }
1129
1193
  if (shouldRemoveHoverSelector(selector, context.options)) {
1130
1194
  selector.remove();
1131
1195
  return;
@@ -1134,6 +1198,13 @@ function handleSelectorNode(selector, context) {
1134
1198
  context.requiresSpacingNormalization = true;
1135
1199
  }
1136
1200
  }
1201
+ function canSkipRuleTransform(rule) {
1202
+ const selector = rule.selector.trim();
1203
+ if (!selector) {
1204
+ return false;
1205
+ }
1206
+ return SIMPLE_SELECTOR_FAST_PATH.test(selector);
1207
+ }
1137
1208
  function transformSelectors(selectors, context) {
1138
1209
  selectors.walk((node, index) => {
1139
1210
  const parent = _optionalChain([node, 'access', _43 => _43.parent, 'optionalAccess', _44 => _44.type]) === "selector" ? node.parent : void 0;
@@ -1167,6 +1238,10 @@ function transformSelectors(selectors, context) {
1167
1238
  normalizeSpacingDeclarations(context.rule);
1168
1239
  }
1169
1240
  selectors.walk((node) => {
1241
+ if (shouldRemoveEmptyFunctionalPseudo(node)) {
1242
+ node.remove();
1243
+ return;
1244
+ }
1170
1245
  if (node.type === "selector" && node.length === 0) {
1171
1246
  node.remove();
1172
1247
  }
@@ -1177,6 +1252,14 @@ function transformSelectors(selectors, context) {
1177
1252
  }
1178
1253
  function createRuleTransformer(options) {
1179
1254
  let context;
1255
+ const selectorResultCache = /* @__PURE__ */ new Map();
1256
+ const selectorResultCacheLimit = 5e4;
1257
+ function writeSelectorResultCache(selector, result) {
1258
+ if (selectorResultCache.size >= selectorResultCacheLimit) {
1259
+ selectorResultCache.clear();
1260
+ }
1261
+ selectorResultCache.set(selector, result);
1262
+ }
1180
1263
  const transform = (selectors) => {
1181
1264
  if (!context) {
1182
1265
  return;
@@ -1185,16 +1268,54 @@ function createRuleTransformer(options) {
1185
1268
  };
1186
1269
  const parser = _postcssselectorparser2.default.call(void 0, transform);
1187
1270
  return (rule) => {
1271
+ const sourceSelector = rule.selector;
1272
+ if (!sourceSelector) {
1273
+ return;
1274
+ }
1275
+ const cached = selectorResultCache.get(sourceSelector);
1276
+ if (cached) {
1277
+ if (cached.action === "remove") {
1278
+ rule.remove();
1279
+ } else if (cached.action === "update" && cached.selector && cached.selector !== sourceSelector) {
1280
+ rule.selector = cached.selector;
1281
+ }
1282
+ return;
1283
+ }
1284
+ if (canSkipRuleTransform(rule)) {
1285
+ writeSelectorResultCache(sourceSelector, { action: "keep" });
1286
+ return;
1287
+ }
1188
1288
  context = {
1189
1289
  options,
1190
1290
  requiresSpacingNormalization: false,
1191
1291
  rule
1192
1292
  };
1293
+ let wasRemoved = false;
1294
+ let requiresSpacingNormalization = false;
1193
1295
  try {
1194
1296
  parser.transformSync(rule, SELECTOR_TRANSFORM_OPTIONS);
1195
1297
  } finally {
1298
+ const currentContext = context;
1299
+ wasRemoved = rule.parent == null;
1300
+ requiresSpacingNormalization = _optionalChain([currentContext, 'optionalAccess', _45 => _45.requiresSpacingNormalization]) === true;
1196
1301
  context = void 0;
1197
1302
  }
1303
+ if (wasRemoved) {
1304
+ writeSelectorResultCache(sourceSelector, { action: "remove" });
1305
+ return;
1306
+ }
1307
+ if (requiresSpacingNormalization) {
1308
+ return;
1309
+ }
1310
+ const transformedSelector = rule.selector;
1311
+ if (transformedSelector === sourceSelector) {
1312
+ writeSelectorResultCache(sourceSelector, { action: "keep" });
1313
+ } else {
1314
+ writeSelectorResultCache(sourceSelector, {
1315
+ action: "update",
1316
+ selector: transformedSelector
1317
+ });
1318
+ }
1198
1319
  };
1199
1320
  }
1200
1321
  function ruleTransformSync(rule, options) {
@@ -1344,7 +1465,7 @@ function normalizeSelectorList(value) {
1344
1465
  return Array.isArray(value) ? value.filter(Boolean) : [value];
1345
1466
  }
1346
1467
  function getSpecificityMatchingName(options) {
1347
- const feature = _optionalChain([options, 'access', _45 => _45.cssPresetEnv, 'optionalAccess', _46 => _46.features, 'optionalAccess', _47 => _47["is-pseudo-class"]]);
1468
+ const feature = _optionalChain([options, 'access', _46 => _46.cssPresetEnv, 'optionalAccess', _47 => _47.features, 'optionalAccess', _48 => _48["is-pseudo-class"]]);
1348
1469
  if (feature && typeof feature === "object" && "specificityMatchingName" in feature) {
1349
1470
  const specificityName = feature.specificityMatchingName;
1350
1471
  return typeof specificityName === "string" && specificityName.length > 0 ? specificityName : void 0;
@@ -1353,12 +1474,12 @@ function getSpecificityMatchingName(options) {
1353
1474
  }
1354
1475
  function createRootSpecificityCleaner(options) {
1355
1476
  const specificityMatchingName = getSpecificityMatchingName(options);
1356
- const selectors = normalizeSelectorList(_optionalChain([options, 'access', _48 => _48.cssSelectorReplacement, 'optionalAccess', _49 => _49.root]));
1477
+ const selectors = normalizeSelectorList(_optionalChain([options, 'access', _49 => _49.cssSelectorReplacement, 'optionalAccess', _50 => _50.root]));
1357
1478
  if (!specificityMatchingName || selectors.length === 0) {
1358
1479
  return void 0;
1359
1480
  }
1360
1481
  const suffix = `:not(.${specificityMatchingName})`;
1361
- const targets = selectors.map((selector) => _optionalChain([selector, 'optionalAccess', _50 => _50.trim, 'call', _51 => _51()])).filter((selector) => Boolean(_optionalChain([selector, 'optionalAccess', _52 => _52.length]))).map((selector) => ({
1482
+ const targets = selectors.map((selector) => _optionalChain([selector, 'optionalAccess', _51 => _51.trim, 'call', _52 => _52()])).filter((selector) => Boolean(_optionalChain([selector, 'optionalAccess', _53 => _53.length]))).map((selector) => ({
1362
1483
  match: `${selector}${suffix}`,
1363
1484
  spacedMatch: `${selector} ${suffix}`,
1364
1485
  replacement: selector
@@ -1387,6 +1508,24 @@ function createRootSpecificityCleaner(options) {
1387
1508
  }
1388
1509
 
1389
1510
  // src/plugins/post.ts
1511
+ var DEFAULT_ROOT_SELECTORS = ["page", ".tw-root", "wx-root-portal-content"];
1512
+ function normalizeRootSelectors(value) {
1513
+ if (value === void 0 || value === false) {
1514
+ return [];
1515
+ }
1516
+ return Array.isArray(value) ? value.filter(Boolean) : [value];
1517
+ }
1518
+ function shouldAppendHostSelector(rule, options) {
1519
+ const selectors = _nullishCoalesce(rule.selectors, () => ( []));
1520
+ if (selectors.includes(":host")) {
1521
+ return false;
1522
+ }
1523
+ const rootSelectors = normalizeRootSelectors(_optionalChain([options, 'access', _54 => _54.cssSelectorReplacement, 'optionalAccess', _55 => _55.root]));
1524
+ if (rootSelectors.length !== DEFAULT_ROOT_SELECTORS.length || !rootSelectors.every((selector, index) => selector === DEFAULT_ROOT_SELECTORS[index])) {
1525
+ return false;
1526
+ }
1527
+ return DEFAULT_ROOT_SELECTORS.every((selector) => selectors.includes(selector));
1528
+ }
1390
1529
  var postcssWeappTailwindcssPostPlugin = (options) => {
1391
1530
  const opts = _shared.defu.call(void 0, options, {
1392
1531
  isMainChunk: true
@@ -1400,10 +1539,13 @@ var postcssWeappTailwindcssPostPlugin = (options) => {
1400
1539
  const fallbackRemove = enableMainChunkTransforms ? getFallbackRemove(void 0, opts) : void 0;
1401
1540
  p.RuleExit = (rule) => {
1402
1541
  if (enableMainChunkTransforms) {
1403
- _optionalChain([fallbackRemove, 'optionalAccess', _53 => _53.transformSync, 'call', _54 => _54(rule)]);
1542
+ _optionalChain([fallbackRemove, 'optionalAccess', _56 => _56.transformSync, 'call', _57 => _57(rule)]);
1404
1543
  }
1405
- _optionalChain([cleanRootSpecificity, 'optionalCall', _55 => _55(rule)]);
1544
+ _optionalChain([cleanRootSpecificity, 'optionalCall', _58 => _58(rule)]);
1406
1545
  if (enableMainChunkTransforms) {
1546
+ if (shouldAppendHostSelector(rule, opts)) {
1547
+ rule.selectors = [...rule.selectors, ":host"];
1548
+ }
1407
1549
  dedupeDeclarations(rule);
1408
1550
  if (rule.selectors.length === 0 || rule.selectors.length === 1 && rule.selector.trim() === "") {
1409
1551
  rule.remove();
@@ -1427,7 +1569,7 @@ var postcssWeappTailwindcssPostPlugin = (options) => {
1427
1569
  if (opts.cssRemoveProperty && atRule.name === "property") {
1428
1570
  atRule.remove();
1429
1571
  }
1430
- _optionalChain([atRule, 'access', _56 => _56.nodes, 'optionalAccess', _57 => _57.length]) === 0 && atRule.remove();
1572
+ _optionalChain([atRule, 'access', _59 => _59.nodes, 'optionalAccess', _60 => _60.length]) === 0 && atRule.remove();
1431
1573
  };
1432
1574
  }
1433
1575
  return p;
@@ -1664,6 +1806,7 @@ function hasTwVars(rule, count = 2) {
1664
1806
 
1665
1807
  // src/mp.ts
1666
1808
  var cssVarsV3Nodes = createCssVarNodes(cssVarsV3_default);
1809
+ var DEFAULT_ROOT_SELECTORS2 = ["page", ".tw-root", "wx-root-portal-content"];
1667
1810
  function testIfVariablesScope(node, count = 2) {
1668
1811
  if (isOnlyBeforeAndAfterPseudoElement(node)) {
1669
1812
  return hasTwVars(node, count);
@@ -1709,8 +1852,16 @@ function remakeCssVarSelector(selectors, options) {
1709
1852
  }
1710
1853
  function commonChunkPreflight(node, options) {
1711
1854
  const { ctx, cssInjectPreflight, injectAdditionalCssVarScope } = options;
1855
+ const rootOption = _optionalChain([options, 'access', _61 => _61.cssSelectorReplacement, 'optionalAccess', _62 => _62.root]);
1856
+ const rootSelectors = rootOption === false || rootOption === void 0 ? [] : Array.isArray(rootOption) ? rootOption.filter(Boolean) : [rootOption];
1857
+ const hasHostSelector = node.selectors.some((selector) => selector.includes(":host"));
1858
+ const hasRootPseudoSelector = node.selectors.some((selector) => selector.includes(":root"));
1859
+ const hasAllDefaultRootSelectors = DEFAULT_ROOT_SELECTORS2.every((selector) => node.selectors.includes(selector));
1860
+ if (!hasHostSelector && !rootSelectors.includes(":host") && (hasRootPseudoSelector || rootSelectors.length === DEFAULT_ROOT_SELECTORS2.length && rootSelectors.every((selector, index) => selector === DEFAULT_ROOT_SELECTORS2[index]) && hasAllDefaultRootSelectors)) {
1861
+ node.selectors = [...node.selectors, ":host"];
1862
+ }
1712
1863
  if (testIfVariablesScope(node)) {
1713
- _optionalChain([ctx, 'optionalAccess', _58 => _58.markVariablesScope, 'call', _59 => _59(node)]);
1864
+ _optionalChain([ctx, 'optionalAccess', _63 => _63.markVariablesScope, 'call', _64 => _64(node)]);
1714
1865
  node.selectors = remakeCssVarSelector(node.selectors, options);
1715
1866
  node.before(makePseudoVarRule());
1716
1867
  if (typeof cssInjectPreflight === "function") {
@@ -1767,9 +1918,9 @@ var postcssWeappTailwindcssPrePlugin = (options) => {
1767
1918
  root.walkAtRules((atRule) => {
1768
1919
  if (atRule.name === "layer") {
1769
1920
  if (atRule.params === "properties") {
1770
- if (atRule.nodes === void 0 || _optionalChain([atRule, 'access', _60 => _60.nodes, 'optionalAccess', _61 => _61.length]) === 0) {
1921
+ if (atRule.nodes === void 0 || _optionalChain([atRule, 'access', _65 => _65.nodes, 'optionalAccess', _66 => _66.length]) === 0) {
1771
1922
  layerProperties = atRule;
1772
- } else if (_optionalChain([atRule, 'access', _62 => _62.first, 'optionalAccess', _63 => _63.type]) === "atrule" && isTailwindcssV4ModernCheck(atRule.first)) {
1923
+ } else if (_optionalChain([atRule, 'access', _67 => _67.first, 'optionalAccess', _68 => _68.type]) === "atrule" && isTailwindcssV4ModernCheck(atRule.first)) {
1773
1924
  if (layerProperties) {
1774
1925
  layerProperties.replaceWith(atRule.first.nodes);
1775
1926
  atRule.remove();
@@ -1781,7 +1932,7 @@ var postcssWeappTailwindcssPrePlugin = (options) => {
1781
1932
  atRule.replaceWith(atRule.nodes);
1782
1933
  }
1783
1934
  } else if (isTailwindcssV4ModernCheck(atRule)) {
1784
- if (_optionalChain([atRule, 'access', _64 => _64.first, 'optionalAccess', _65 => _65.type]) === "atrule" && atRule.first.name === "layer") {
1935
+ if (_optionalChain([atRule, 'access', _69 => _69.first, 'optionalAccess', _70 => _70.type]) === "atrule" && atRule.first.name === "layer") {
1785
1936
  atRule.replaceWith(atRule.first.nodes);
1786
1937
  }
1787
1938
  }
@@ -1826,7 +1977,7 @@ function createPipelineDefinitions(options) {
1826
1977
  normal: [],
1827
1978
  post: []
1828
1979
  };
1829
- const userPlugins = normalizeUserPlugins(_optionalChain([options, 'access', _66 => _66.postcssOptions, 'optionalAccess', _67 => _67.plugins]));
1980
+ const userPlugins = normalizeUserPlugins(_optionalChain([options, 'access', _71 => _71.postcssOptions, 'optionalAccess', _72 => _72.plugins]));
1830
1981
  userPlugins.forEach((plugin, index) => {
1831
1982
  stages.pre.push(createStaticDefinition(`pre:user-${index}`, "pre", plugin));
1832
1983
  });
@@ -2001,13 +2152,31 @@ function createStylePipeline(options) {
2001
2152
  function createProcessOptions(options) {
2002
2153
  return {
2003
2154
  from: void 0,
2004
- ..._nullishCoalesce(_optionalChain([options, 'access', _68 => _68.postcssOptions, 'optionalAccess', _69 => _69.options]), () => ( {}))
2155
+ ..._nullishCoalesce(_optionalChain([options, 'access', _73 => _73.postcssOptions, 'optionalAccess', _74 => _74.options]), () => ( {}))
2005
2156
  };
2006
2157
  }
2007
- var StyleProcessorCache = (_class = class {constructor() { _class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this); }
2158
+ var StyleProcessorCache = (_class = class {constructor() { _class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);_class.prototype.__init4.call(this);_class.prototype.__init5.call(this); }
2008
2159
  __init() {this.pipelineCache = /* @__PURE__ */ new WeakMap()}
2009
2160
  __init2() {this.processOptionsCache = /* @__PURE__ */ new WeakMap()}
2010
2161
  __init3() {this.processorCache = /* @__PURE__ */ new WeakMap()}
2162
+ __init4() {this.processorCacheByKey = /* @__PURE__ */ new Map()}
2163
+ __init5() {this.processorKeyCache = /* @__PURE__ */ new WeakMap()}
2164
+ createProcessorCacheKey(options) {
2165
+ const from = _optionalChain([options, 'access', _75 => _75.postcssOptions, 'optionalAccess', _76 => _76.options, 'optionalAccess', _77 => _77.from]);
2166
+ if (from == null) {
2167
+ return fingerprintOptions(options);
2168
+ }
2169
+ return fingerprintOptions({
2170
+ ...options,
2171
+ postcssOptions: {
2172
+ ..._nullishCoalesce(options.postcssOptions, () => ( {})),
2173
+ options: {
2174
+ ..._nullishCoalesce(_optionalChain([options, 'access', _78 => _78.postcssOptions, 'optionalAccess', _79 => _79.options]), () => ( {})),
2175
+ from: void 0
2176
+ }
2177
+ }
2178
+ });
2179
+ }
2011
2180
  getPipeline(options) {
2012
2181
  let pipeline = this.pipelineCache.get(options);
2013
2182
  if (!pipeline) {
@@ -2017,7 +2186,7 @@ var StyleProcessorCache = (_class = class {constructor() { _class.prototype.__in
2017
2186
  return pipeline;
2018
2187
  }
2019
2188
  getProcessOptions(options) {
2020
- const source = _optionalChain([options, 'access', _70 => _70.postcssOptions, 'optionalAccess', _71 => _71.options]);
2189
+ const source = _optionalChain([options, 'access', _80 => _80.postcssOptions, 'optionalAccess', _81 => _81.options]);
2021
2190
  const fingerprint = source ? fingerprintOptions(source) : void 0;
2022
2191
  const cached = this.processOptionsCache.get(options);
2023
2192
  if (!cached || cached.fingerprint !== fingerprint) {
@@ -2030,8 +2199,17 @@ var StyleProcessorCache = (_class = class {constructor() { _class.prototype.__in
2030
2199
  getProcessor(options) {
2031
2200
  let processor = this.processorCache.get(options);
2032
2201
  if (!processor) {
2033
- const pipeline = this.getPipeline(options);
2034
- processor = _postcss2.default.call(void 0, pipeline.plugins);
2202
+ let cacheKey = this.processorKeyCache.get(options);
2203
+ if (!cacheKey) {
2204
+ cacheKey = this.createProcessorCacheKey(options);
2205
+ this.processorKeyCache.set(options, cacheKey);
2206
+ }
2207
+ processor = this.processorCacheByKey.get(cacheKey);
2208
+ if (!processor) {
2209
+ const pipeline = this.getPipeline(options);
2210
+ processor = _postcss2.default.call(void 0, pipeline.plugins);
2211
+ this.processorCacheByKey.set(cacheKey, processor);
2212
+ }
2035
2213
  this.processorCache.set(options, processor);
2036
2214
  }
2037
2215
  return processor;
package/dist/index.mjs CHANGED
@@ -1037,6 +1037,55 @@ function normalizeSpacingDeclarations(rule) {
1037
1037
  // src/selectorParser/rule-transformer.ts
1038
1038
  var ruleTransformCache = /* @__PURE__ */ new WeakMap();
1039
1039
  var SELECTOR_TRANSFORM_OPTIONS = normalizeTransformOptions();
1040
+ var SIMPLE_SELECTOR_FAST_PATH = /^[#.][\w-]+(?:\s+[#.][\w-]+)*$/;
1041
+ var RTL_LANGUAGE_ANY_PSEUDO_SET = /* @__PURE__ */ new Set([
1042
+ ":-moz-any",
1043
+ ":-webkit-any",
1044
+ ":lang"
1045
+ ]);
1046
+ var EMPTY_FUNCTIONAL_PSEUDO_CLEANUP_SET = /* @__PURE__ */ new Set([
1047
+ ":not",
1048
+ ":is",
1049
+ ":where",
1050
+ ":has",
1051
+ ":matches",
1052
+ ":-webkit-any",
1053
+ ":-moz-any",
1054
+ ":lang"
1055
+ ]);
1056
+ function isRtlLanguageAnyPseudo(node) {
1057
+ return node.type === "pseudo" && RTL_LANGUAGE_ANY_PSEUDO_SET.has(node.value);
1058
+ }
1059
+ function getTopLevelSelector(node) {
1060
+ let current = node;
1061
+ let topLevel = node;
1062
+ while (current.parent) {
1063
+ const parent = current.parent;
1064
+ if (parent.type === "root") {
1065
+ break;
1066
+ }
1067
+ if (parent.type === "selector") {
1068
+ topLevel = parent;
1069
+ }
1070
+ current = parent;
1071
+ }
1072
+ return topLevel;
1073
+ }
1074
+ function stripUnsupportedRtlLanguagePseudo(node) {
1075
+ const selectorParent = node.parent;
1076
+ if (!selectorParent || selectorParent.type !== "selector") {
1077
+ return;
1078
+ }
1079
+ const maybeNot = selectorParent.parent;
1080
+ if (maybeNot && maybeNot.type === "pseudo" && maybeNot.value === ":not") {
1081
+ maybeNot.remove();
1082
+ return;
1083
+ }
1084
+ getTopLevelSelector(selectorParent).remove();
1085
+ }
1086
+ function shouldRemoveEmptyFunctionalPseudo(node) {
1087
+ return node.type === "pseudo" && EMPTY_FUNCTIONAL_PSEUDO_CLEANUP_SET.has(node.value) && Array.isArray(node.nodes) && node.nodes.length === 0;
1088
+ }
1040
1089
  function flattenWherePseudo(node, context, index, parent) {
1041
1090
  if (isUniAppXEnabled(context.options)) {
1042
1091
  node.value = ":is";
@@ -1074,6 +1123,13 @@ function shouldRemoveHoverSelector(selector, options) {
1074
1123
  }
1075
1124
  return selector.nodes.some((node) => node.type === "pseudo" && node.value === ":hover");
1076
1125
  }
1126
+ var UNSUPPORTED_PSEUDO_ELEMENT_SELECTOR_SET = /* @__PURE__ */ new Set([
1127
+ "::backdrop",
1128
+ "::file-selector-button"
1129
+ ]);
1130
+ function shouldRemoveUnsupportedPseudoElementSelector(selector) {
1131
+ return selector.nodes.some((node) => node.type === "pseudo" && UNSUPPORTED_PSEUDO_ELEMENT_SELECTOR_SET.has(node.value));
1132
+ }
1077
1133
  function isHiddenOrTemplateNotPseudo(node) {
1078
1134
  if (!node || node.type !== "pseudo" || node.value !== ":not") {
1079
1135
  return false;
@@ -1114,6 +1170,10 @@ function handlePseudoNode(node, index, context, parent) {
1114
1170
  if (node.type !== "pseudo") {
1115
1171
  return;
1116
1172
  }
1173
+ if (isRtlLanguageAnyPseudo(node)) {
1174
+ stripUnsupportedRtlLanguagePseudo(node);
1175
+ return;
1176
+ }
1117
1177
  if (node.value === ":root" && context.options.cssSelectorReplacement?.root) {
1118
1178
  node.value = composeIsPseudo(context.options.cssSelectorReplacement.root);
1119
1179
  return;
@@ -1126,6 +1186,10 @@ function handleTagOrAttribute(node, context) {
1126
1186
  stripUnsupportedNodeForUniAppX(node, context.options);
1127
1187
  }
1128
1188
  function handleSelectorNode(selector, context) {
1189
+ if (shouldRemoveUnsupportedPseudoElementSelector(selector)) {
1190
+ selector.remove();
1191
+ return;
1192
+ }
1129
1193
  if (shouldRemoveHoverSelector(selector, context.options)) {
1130
1194
  selector.remove();
1131
1195
  return;
@@ -1134,6 +1198,13 @@ function handleSelectorNode(selector, context) {
1134
1198
  context.requiresSpacingNormalization = true;
1135
1199
  }
1136
1200
  }
1201
+ function canSkipRuleTransform(rule) {
1202
+ const selector = rule.selector.trim();
1203
+ if (!selector) {
1204
+ return false;
1205
+ }
1206
+ return SIMPLE_SELECTOR_FAST_PATH.test(selector);
1207
+ }
1137
1208
  function transformSelectors(selectors, context) {
1138
1209
  selectors.walk((node, index) => {
1139
1210
  const parent = node.parent?.type === "selector" ? node.parent : void 0;
@@ -1167,6 +1238,10 @@ function transformSelectors(selectors, context) {
1167
1238
  normalizeSpacingDeclarations(context.rule);
1168
1239
  }
1169
1240
  selectors.walk((node) => {
1241
+ if (shouldRemoveEmptyFunctionalPseudo(node)) {
1242
+ node.remove();
1243
+ return;
1244
+ }
1170
1245
  if (node.type === "selector" && node.length === 0) {
1171
1246
  node.remove();
1172
1247
  }
@@ -1177,6 +1252,14 @@ function transformSelectors(selectors, context) {
1177
1252
  }
1178
1253
  function createRuleTransformer(options) {
1179
1254
  let context;
1255
+ const selectorResultCache = /* @__PURE__ */ new Map();
1256
+ const selectorResultCacheLimit = 5e4;
1257
+ function writeSelectorResultCache(selector, result) {
1258
+ if (selectorResultCache.size >= selectorResultCacheLimit) {
1259
+ selectorResultCache.clear();
1260
+ }
1261
+ selectorResultCache.set(selector, result);
1262
+ }
1180
1263
  const transform = (selectors) => {
1181
1264
  if (!context) {
1182
1265
  return;
@@ -1185,16 +1268,54 @@ function createRuleTransformer(options) {
1185
1268
  };
1186
1269
  const parser = psp4(transform);
1187
1270
  return (rule) => {
1271
+ const sourceSelector = rule.selector;
1272
+ if (!sourceSelector) {
1273
+ return;
1274
+ }
1275
+ const cached = selectorResultCache.get(sourceSelector);
1276
+ if (cached) {
1277
+ if (cached.action === "remove") {
1278
+ rule.remove();
1279
+ } else if (cached.action === "update" && cached.selector && cached.selector !== sourceSelector) {
1280
+ rule.selector = cached.selector;
1281
+ }
1282
+ return;
1283
+ }
1284
+ if (canSkipRuleTransform(rule)) {
1285
+ writeSelectorResultCache(sourceSelector, { action: "keep" });
1286
+ return;
1287
+ }
1188
1288
  context = {
1189
1289
  options,
1190
1290
  requiresSpacingNormalization: false,
1191
1291
  rule
1192
1292
  };
1293
+ let wasRemoved = false;
1294
+ let requiresSpacingNormalization = false;
1193
1295
  try {
1194
1296
  parser.transformSync(rule, SELECTOR_TRANSFORM_OPTIONS);
1195
1297
  } finally {
1298
+ const currentContext = context;
1299
+ wasRemoved = rule.parent == null;
1300
+ requiresSpacingNormalization = currentContext?.requiresSpacingNormalization === true;
1196
1301
  context = void 0;
1197
1302
  }
1303
+ if (wasRemoved) {
1304
+ writeSelectorResultCache(sourceSelector, { action: "remove" });
1305
+ return;
1306
+ }
1307
+ if (requiresSpacingNormalization) {
1308
+ return;
1309
+ }
1310
+ const transformedSelector = rule.selector;
1311
+ if (transformedSelector === sourceSelector) {
1312
+ writeSelectorResultCache(sourceSelector, { action: "keep" });
1313
+ } else {
1314
+ writeSelectorResultCache(sourceSelector, {
1315
+ action: "update",
1316
+ selector: transformedSelector
1317
+ });
1318
+ }
1198
1319
  };
1199
1320
  }
1200
1321
  function ruleTransformSync(rule, options) {
@@ -1387,6 +1508,24 @@ function createRootSpecificityCleaner(options) {
1387
1508
  }
1388
1509
 
1389
1510
  // src/plugins/post.ts
1511
+ var DEFAULT_ROOT_SELECTORS = ["page", ".tw-root", "wx-root-portal-content"];
1512
+ function normalizeRootSelectors(value) {
1513
+ if (value === void 0 || value === false) {
1514
+ return [];
1515
+ }
1516
+ return Array.isArray(value) ? value.filter(Boolean) : [value];
1517
+ }
1518
+ function shouldAppendHostSelector(rule, options) {
1519
+ const selectors = rule.selectors ?? [];
1520
+ if (selectors.includes(":host")) {
1521
+ return false;
1522
+ }
1523
+ const rootSelectors = normalizeRootSelectors(options.cssSelectorReplacement?.root);
1524
+ if (rootSelectors.length !== DEFAULT_ROOT_SELECTORS.length || !rootSelectors.every((selector, index) => selector === DEFAULT_ROOT_SELECTORS[index])) {
1525
+ return false;
1526
+ }
1527
+ return DEFAULT_ROOT_SELECTORS.every((selector) => selectors.includes(selector));
1528
+ }
1390
1529
  var postcssWeappTailwindcssPostPlugin = (options) => {
1391
1530
  const opts = defu(options, {
1392
1531
  isMainChunk: true
@@ -1404,6 +1543,9 @@ var postcssWeappTailwindcssPostPlugin = (options) => {
1404
1543
  }
1405
1544
  cleanRootSpecificity?.(rule);
1406
1545
  if (enableMainChunkTransforms) {
1546
+ if (shouldAppendHostSelector(rule, opts)) {
1547
+ rule.selectors = [...rule.selectors, ":host"];
1548
+ }
1407
1549
  dedupeDeclarations(rule);
1408
1550
  if (rule.selectors.length === 0 || rule.selectors.length === 1 && rule.selector.trim() === "") {
1409
1551
  rule.remove();
@@ -1664,6 +1806,7 @@ function hasTwVars(rule, count = 2) {
1664
1806
 
1665
1807
  // src/mp.ts
1666
1808
  var cssVarsV3Nodes = createCssVarNodes(cssVarsV3_default);
1809
+ var DEFAULT_ROOT_SELECTORS2 = ["page", ".tw-root", "wx-root-portal-content"];
1667
1810
  function testIfVariablesScope(node, count = 2) {
1668
1811
  if (isOnlyBeforeAndAfterPseudoElement(node)) {
1669
1812
  return hasTwVars(node, count);
@@ -1709,6 +1852,14 @@ function remakeCssVarSelector(selectors, options) {
1709
1852
  }
1710
1853
  function commonChunkPreflight(node, options) {
1711
1854
  const { ctx, cssInjectPreflight, injectAdditionalCssVarScope } = options;
1855
+ const rootOption = options.cssSelectorReplacement?.root;
1856
+ const rootSelectors = rootOption === false || rootOption === void 0 ? [] : Array.isArray(rootOption) ? rootOption.filter(Boolean) : [rootOption];
1857
+ const hasHostSelector = node.selectors.some((selector) => selector.includes(":host"));
1858
+ const hasRootPseudoSelector = node.selectors.some((selector) => selector.includes(":root"));
1859
+ const hasAllDefaultRootSelectors = DEFAULT_ROOT_SELECTORS2.every((selector) => node.selectors.includes(selector));
1860
+ if (!hasHostSelector && !rootSelectors.includes(":host") && (hasRootPseudoSelector || rootSelectors.length === DEFAULT_ROOT_SELECTORS2.length && rootSelectors.every((selector, index) => selector === DEFAULT_ROOT_SELECTORS2[index]) && hasAllDefaultRootSelectors)) {
1861
+ node.selectors = [...node.selectors, ":host"];
1862
+ }
1712
1863
  if (testIfVariablesScope(node)) {
1713
1864
  ctx?.markVariablesScope(node);
1714
1865
  node.selectors = remakeCssVarSelector(node.selectors, options);
@@ -2008,6 +2159,24 @@ var StyleProcessorCache = class {
2008
2159
  pipelineCache = /* @__PURE__ */ new WeakMap();
2009
2160
  processOptionsCache = /* @__PURE__ */ new WeakMap();
2010
2161
  processorCache = /* @__PURE__ */ new WeakMap();
2162
+ processorCacheByKey = /* @__PURE__ */ new Map();
2163
+ processorKeyCache = /* @__PURE__ */ new WeakMap();
2164
+ createProcessorCacheKey(options) {
2165
+ const from = options.postcssOptions?.options?.from;
2166
+ if (from == null) {
2167
+ return fingerprintOptions(options);
2168
+ }
2169
+ return fingerprintOptions({
2170
+ ...options,
2171
+ postcssOptions: {
2172
+ ...options.postcssOptions ?? {},
2173
+ options: {
2174
+ ...options.postcssOptions?.options ?? {},
2175
+ from: void 0
2176
+ }
2177
+ }
2178
+ });
2179
+ }
2011
2180
  getPipeline(options) {
2012
2181
  let pipeline = this.pipelineCache.get(options);
2013
2182
  if (!pipeline) {
@@ -2030,8 +2199,17 @@ var StyleProcessorCache = class {
2030
2199
  getProcessor(options) {
2031
2200
  let processor = this.processorCache.get(options);
2032
2201
  if (!processor) {
2033
- const pipeline = this.getPipeline(options);
2034
- processor = postcss(pipeline.plugins);
2202
+ let cacheKey = this.processorKeyCache.get(options);
2203
+ if (!cacheKey) {
2204
+ cacheKey = this.createProcessorCacheKey(options);
2205
+ this.processorKeyCache.set(options, cacheKey);
2206
+ }
2207
+ processor = this.processorCacheByKey.get(cacheKey);
2208
+ if (!processor) {
2209
+ const pipeline = this.getPipeline(options);
2210
+ processor = postcss(pipeline.plugins);
2211
+ this.processorCacheByKey.set(cacheKey, processor);
2212
+ }
2035
2213
  this.processorCache.set(options, processor);
2036
2214
  }
2037
2215
  return processor;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@weapp-tailwindcss/postcss",
3
- "version": "2.1.4",
3
+ "version": "2.1.5-beta.0",
4
4
  "description": "@weapp-tailwindcss/postcss",
5
5
  "author": "ice breaker <1324318532@qq.com>",
6
6
  "license": "MIT",