tailwindcss-patch 9.3.0 → 9.3.2

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/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  const require_chunk = require("./chunk-8l464Juk.js");
2
- const require_validate = require("./validate-DzKStQUM.js");
3
- const require_index_bundle = require("./index.bundle-DSIUuQAH.js");
2
+ const require_validate = require("./validate-CF0M_7KH.js");
3
+ const require_index_bundle = require("./index.bundle-CcVIAfDb.js");
4
4
  let node_process = require("node:process");
5
5
  node_process = require_chunk.__toESM(node_process);
6
6
  //#region src/cli.bundle.ts
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { j as logger, r as ValidateCommandError } from "./validate-B_jsptz9.mjs";
2
- import { t as createTailwindcssPatchCli } from "./index.bundle-CsMNxjyL.mjs";
1
+ import { j as logger, r as ValidateCommandError } from "./validate-Sq_yuh3r.mjs";
2
+ import { t as createTailwindcssPatchCli } from "./index.bundle-DjS24i5r.mjs";
3
3
  import process from "node:process";
4
4
  //#region src/cli.bundle.ts
5
5
  async function main() {
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_chunk = require("../chunk-8l464Juk.js");
3
- const require_validate = require("../validate-DzKStQUM.js");
3
+ const require_validate = require("../validate-CF0M_7KH.js");
4
4
  let node_process = require("node:process");
5
5
  node_process = require_chunk.__toESM(node_process);
6
6
  let fs_extra = require("fs-extra");
@@ -1,4 +1,4 @@
1
- import { D as loadPatchOptionsForWorkspace, O as loadWorkspaceConfigModule, a as tailwindcssPatchCommands, b as groupTokensByFile, i as classifyValidateError, j as logger, n as VALIDATE_FAILURE_REASONS, o as migrateConfigFiles, r as ValidateCommandError, s as restoreConfigFiles, t as VALIDATE_EXIT_CODES, u as TailwindcssPatcher } from "../validate-B_jsptz9.mjs";
1
+ import { D as loadPatchOptionsForWorkspace, O as loadWorkspaceConfigModule, a as tailwindcssPatchCommands, b as groupTokensByFile, i as classifyValidateError, j as logger, n as VALIDATE_FAILURE_REASONS, o as migrateConfigFiles, r as ValidateCommandError, s as restoreConfigFiles, t as VALIDATE_EXIT_CODES, u as TailwindcssPatcher } from "../validate-Sq_yuh3r.mjs";
2
2
  import process from "node:process";
3
3
  import fs from "fs-extra";
4
4
  import path from "pathe";
@@ -1,5 +1,5 @@
1
1
  const require_chunk = require("./chunk-8l464Juk.js");
2
- const require_validate = require("./validate-DzKStQUM.js");
2
+ const require_validate = require("./validate-CF0M_7KH.js");
3
3
  let node_module = require("node:module");
4
4
  let node_process = require("node:process");
5
5
  node_process = require_chunk.__toESM(node_process);
@@ -1,4 +1,4 @@
1
- import { C as canonicalizeBareArbitraryValueCandidates, E as resolveValidTailwindV4Candidates, S as loadTailwindV4DesignSystem, T as replaceBareArbitraryValueSelectors, _ as extractRawCandidates, k as normalizeOptions, v as extractRawCandidatesWithPositions, w as extractTailwindV4InlineSourceCandidates, x as compileTailwindV4Source } from "./validate-B_jsptz9.mjs";
1
+ import { C as canonicalizeBareArbitraryValueCandidates, E as resolveValidTailwindV4Candidates, S as loadTailwindV4DesignSystem, T as replaceBareArbitraryValueSelectors, _ as extractRawCandidates, k as normalizeOptions, v as extractRawCandidatesWithPositions, w as extractTailwindV4InlineSourceCandidates, x as compileTailwindV4Source } from "./validate-Sq_yuh3r.mjs";
2
2
  import { createRequire } from "node:module";
3
3
  import process from "node:process";
4
4
  import path from "pathe";
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_validate = require("./validate-DzKStQUM.js");
3
- const require_index_bundle = require("./index.bundle-DSIUuQAH.js");
2
+ const require_validate = require("./validate-CF0M_7KH.js");
3
+ const require_index_bundle = require("./index.bundle-CcVIAfDb.js");
4
4
  exports.CacheStore = require_validate.CacheStore;
5
5
  exports.MIGRATION_REPORT_KIND = require_validate.MIGRATION_REPORT_KIND;
6
6
  exports.MIGRATION_REPORT_SCHEMA_VERSION = require_validate.MIGRATION_REPORT_SCHEMA_VERSION;
package/dist/index.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import { A as CacheStore, E as resolveValidTailwindV4Candidates, S as loadTailwindV4DesignSystem, _ as extractRawCandidates, a as tailwindcssPatchCommands, b as groupTokensByFile, c as MIGRATION_REPORT_KIND, d as getPatchStatusReport, f as runTailwindBuild, g as extractProjectCandidatesWithPositions, h as collectClassesFromTailwindV4, j as logger, k as normalizeOptions, l as MIGRATION_REPORT_SCHEMA_VERSION, m as collectClassesFromContexts, n as VALIDATE_FAILURE_REASONS, o as migrateConfigFiles, p as loadRuntimeContexts, r as ValidateCommandError, s as restoreConfigFiles, t as VALIDATE_EXIT_CODES, u as TailwindcssPatcher, v as extractRawCandidatesWithPositions, y as extractValidCandidates } from "./validate-B_jsptz9.mjs";
2
- import { a as resolveTailwindV4SourceFromPatchOptions, i as resolveTailwindV4Source, n as defineConfig, o as createTailwindV4Engine, r as mountTailwindcssPatchCommands, t as createTailwindcssPatchCli } from "./index.bundle-CsMNxjyL.mjs";
1
+ import { A as CacheStore, E as resolveValidTailwindV4Candidates, S as loadTailwindV4DesignSystem, _ as extractRawCandidates, a as tailwindcssPatchCommands, b as groupTokensByFile, c as MIGRATION_REPORT_KIND, d as getPatchStatusReport, f as runTailwindBuild, g as extractProjectCandidatesWithPositions, h as collectClassesFromTailwindV4, j as logger, k as normalizeOptions, l as MIGRATION_REPORT_SCHEMA_VERSION, m as collectClassesFromContexts, n as VALIDATE_FAILURE_REASONS, o as migrateConfigFiles, p as loadRuntimeContexts, r as ValidateCommandError, s as restoreConfigFiles, t as VALIDATE_EXIT_CODES, u as TailwindcssPatcher, v as extractRawCandidatesWithPositions, y as extractValidCandidates } from "./validate-Sq_yuh3r.mjs";
2
+ import { a as resolveTailwindV4SourceFromPatchOptions, i as resolveTailwindV4Source, n as defineConfig, o as createTailwindV4Engine, r as mountTailwindcssPatchCommands, t as createTailwindcssPatchCli } from "./index.bundle-DjS24i5r.mjs";
3
3
  export { CacheStore, MIGRATION_REPORT_KIND, MIGRATION_REPORT_SCHEMA_VERSION, TailwindcssPatcher, VALIDATE_EXIT_CODES, VALIDATE_FAILURE_REASONS, ValidateCommandError, collectClassesFromContexts, collectClassesFromTailwindV4, createTailwindV4Engine, createTailwindcssPatchCli, defineConfig, extractProjectCandidatesWithPositions, extractRawCandidates, extractRawCandidatesWithPositions, extractValidCandidates, getPatchStatusReport, groupTokensByFile, loadRuntimeContexts, loadTailwindV4DesignSystem, logger, migrateConfigFiles, mountTailwindcssPatchCommands, normalizeOptions, resolveTailwindV4Source, resolveTailwindV4SourceFromPatchOptions, resolveValidTailwindV4Candidates, restoreConfigFiles, runTailwindBuild, tailwindcssPatchCommands };
@@ -23,7 +23,7 @@ _babel_traverse = require_chunk.__toESM(_babel_traverse);
23
23
  let _babel_parser = require("@babel/parser");
24
24
  let tailwindcss_config = require("tailwindcss-config");
25
25
  //#region package.json
26
- var version = "9.3.0";
26
+ var version = "9.3.2";
27
27
  //#endregion
28
28
  //#region src/constants.ts
29
29
  const pkgName = "tailwindcss-patch";
@@ -184,6 +184,8 @@ function cloneEntry(entry) {
184
184
  };
185
185
  }
186
186
  var CacheStore = class {
187
+ options;
188
+ context;
187
189
  driver;
188
190
  lockPath;
189
191
  memoryCache = null;
@@ -1477,7 +1479,8 @@ const DEFAULT_BARE_ARBITRARY_VALUE_UNITS = [
1477
1479
  "ms"
1478
1480
  ];
1479
1481
  const NUMBER_RE = /^-?(?:\d+|\d*\.\d+)$/;
1480
- const FUNCTION_VALUE_RE = /^[a-zA-Z_-][a-zA-Z0-9_-]*\(/;
1482
+ const FUNCTION_VALUE_RE = /^[a-z_-][\w-]*\(/i;
1483
+ const HEX_ESCAPE_RE = /^[\da-f]$/i;
1481
1484
  function splitVariantPrefix(candidate) {
1482
1485
  let depth = 0;
1483
1486
  let quote;
@@ -1543,8 +1546,38 @@ function isBalancedFunctionValue(value) {
1543
1546
  }
1544
1547
  return depth === 0 && quote === void 0;
1545
1548
  }
1549
+ function isEscapedAt(value, index) {
1550
+ let slashCount = 0;
1551
+ for (let slashIndex = index - 1; slashIndex >= 0 && value[slashIndex] === "\\"; slashIndex--) slashCount++;
1552
+ return slashCount % 2 === 1;
1553
+ }
1554
+ function isBalancedBareArbitraryBody(value) {
1555
+ let depth = 0;
1556
+ let quote;
1557
+ for (let index = 0; index < value.length; index++) {
1558
+ const character = value[index];
1559
+ if (isEscapedAt(value, index)) continue;
1560
+ if (quote) {
1561
+ if (character === quote) quote = void 0;
1562
+ continue;
1563
+ }
1564
+ if (character === "\"" || character === "'") {
1565
+ quote = character;
1566
+ continue;
1567
+ }
1568
+ if (character === "(" || character === "{") {
1569
+ depth++;
1570
+ continue;
1571
+ }
1572
+ if (character === ")" || character === "}") {
1573
+ depth--;
1574
+ if (depth < 0) return false;
1575
+ }
1576
+ }
1577
+ return depth === 0 && quote === void 0;
1578
+ }
1546
1579
  function isHexColorValue(value) {
1547
- return /^#(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6,8})$/.test(value);
1580
+ return /^#(?:[0-9a-f]{3,4}|[0-9a-f]{6,8})$/i.test(value);
1548
1581
  }
1549
1582
  function isQuotedValue(value) {
1550
1583
  const quote = value[0];
@@ -1567,29 +1600,61 @@ function normalizeBareArbitraryValueOptions(options) {
1567
1600
  if (normalizedUnits.length === 0) return;
1568
1601
  return { units: normalizedUnits.sort((a, b) => b.length - a.length) };
1569
1602
  }
1603
+ function normalizeEscapedValue(value) {
1604
+ let result = "";
1605
+ for (let index = 0; index < value.length; index++) {
1606
+ const character = value[index];
1607
+ if (character !== "\\") {
1608
+ result += character;
1609
+ continue;
1610
+ }
1611
+ const nextCharacter = value[index + 1];
1612
+ if (nextCharacter === void 0) {
1613
+ result += character;
1614
+ continue;
1615
+ }
1616
+ if (HEX_ESCAPE_RE.test(nextCharacter)) {
1617
+ let hex = "";
1618
+ let nextIndex = index + 1;
1619
+ while (nextIndex < value.length && hex.length < 6) {
1620
+ const hexCharacter = value[nextIndex];
1621
+ if (hexCharacter === void 0 || !HEX_ESCAPE_RE.test(hexCharacter)) break;
1622
+ hex += hexCharacter;
1623
+ nextIndex++;
1624
+ }
1625
+ if (/[\t\n\f\r ]/.test(value[nextIndex] ?? "")) nextIndex++;
1626
+ const decoded = String.fromCodePoint(Number.parseInt(hex, 16));
1627
+ result += decoded === "_" ? "\\_" : decoded;
1628
+ index = nextIndex - 1;
1629
+ continue;
1630
+ }
1631
+ result += nextCharacter === "_" ? "\\_" : nextCharacter;
1632
+ index++;
1633
+ }
1634
+ return result;
1635
+ }
1570
1636
  function resolveValueWithUnit(body, units) {
1637
+ const value = normalizeEscapedValue(body);
1571
1638
  for (const unit of units) {
1572
- if (!body.endsWith(unit)) continue;
1573
- const numberPart = body.slice(0, -unit.length);
1639
+ if (!value.endsWith(unit)) continue;
1640
+ const numberPart = value.slice(0, -unit.length);
1574
1641
  if (NUMBER_RE.test(numberPart)) return `${numberPart}${unit}`;
1575
1642
  }
1576
1643
  }
1577
1644
  function resolveArbitraryValue(body, units) {
1578
- const withUnit = resolveValueWithUnit(body, units);
1645
+ const value = normalizeEscapedValue(body);
1646
+ const withUnit = resolveValueWithUnit(value, units);
1579
1647
  if (withUnit) return withUnit;
1580
- if (isHexColorValue(body)) return body;
1581
- if (isQuotedValue(body)) return body;
1582
- if (FUNCTION_VALUE_RE.test(body) && body.endsWith(")") && isBalancedFunctionValue(body)) return body;
1648
+ if (isHexColorValue(value)) return value;
1649
+ if (isQuotedValue(value)) return value;
1650
+ if (FUNCTION_VALUE_RE.test(value) && value.endsWith(")") && isBalancedFunctionValue(value)) return value;
1583
1651
  }
1584
1652
  function resolveUtilityAndValue(body, units) {
1585
1653
  let depth = 0;
1586
1654
  let quote;
1587
- for (let index = 1; index < body.length; index++) {
1655
+ for (let index = body.length - 1; index > 0; index--) {
1588
1656
  const character = body[index];
1589
- if (character === "\\") {
1590
- index++;
1591
- continue;
1592
- }
1657
+ if (isEscapedAt(body, index)) continue;
1593
1658
  if (quote) {
1594
1659
  if (character === quote) quote = void 0;
1595
1660
  continue;
@@ -1598,11 +1663,11 @@ function resolveUtilityAndValue(body, units) {
1598
1663
  quote = character;
1599
1664
  continue;
1600
1665
  }
1601
- if (character === "(" || character === "{") {
1666
+ if (character === ")" || character === "}") {
1602
1667
  depth++;
1603
1668
  continue;
1604
1669
  }
1605
- if (character === ")" || character === "}") {
1670
+ if (character === "(" || character === "{") {
1606
1671
  depth = Math.max(0, depth - 1);
1607
1672
  continue;
1608
1673
  }
@@ -1625,6 +1690,7 @@ function resolveBareArbitraryValueCandidate(candidate, options) {
1625
1690
  let normalizedBody = important ? body.slice(1) : body;
1626
1691
  const negative = normalizedBody.startsWith("-") ? "-" : "";
1627
1692
  if (negative) normalizedBody = normalizedBody.slice(1);
1693
+ if (!isBalancedBareArbitraryBody(normalizedBody)) return;
1628
1694
  const resolved = resolveUtilityAndValue(normalizedBody, normalizedOptions.units);
1629
1695
  if (!resolved) return;
1630
1696
  return {
@@ -1658,23 +1724,32 @@ function escapeCssClassName(value) {
1658
1724
  function resolveValidTailwindV4Candidates(designSystem, candidates, options) {
1659
1725
  const validCandidates = /* @__PURE__ */ new Set();
1660
1726
  const parsedCandidates = [];
1661
- const originalCandidateByCanonical = /* @__PURE__ */ new Map();
1727
+ const originalCandidatesByCanonical = /* @__PURE__ */ new Map();
1662
1728
  for (const candidate of candidates) {
1663
1729
  if (!candidate) continue;
1664
1730
  const bareArbitrary = resolveBareArbitraryValueCandidate(candidate, options?.bareArbitraryValues);
1665
1731
  const candidateToCheck = bareArbitrary?.canonicalCandidate ?? candidate;
1666
- if (parsedCandidates.includes(candidateToCheck)) continue;
1667
- if (designSystem.parseCandidate(candidateToCheck).length > 0) {
1668
- parsedCandidates.push(candidateToCheck);
1669
- if (bareArbitrary) originalCandidateByCanonical.set(candidateToCheck, candidate);
1732
+ if (bareArbitrary) {
1733
+ const originalCandidates = originalCandidatesByCanonical.get(candidateToCheck) ?? /* @__PURE__ */ new Set();
1734
+ originalCandidates.add(candidate);
1735
+ originalCandidatesByCanonical.set(candidateToCheck, originalCandidates);
1670
1736
  }
1737
+ if (parsedCandidates.includes(candidateToCheck)) continue;
1738
+ if (designSystem.parseCandidate(candidateToCheck).length > 0) parsedCandidates.push(candidateToCheck);
1671
1739
  }
1672
1740
  if (parsedCandidates.length === 0) return validCandidates;
1673
1741
  const cssByCandidate = designSystem.candidatesToCss(parsedCandidates);
1674
1742
  for (let index = 0; index < parsedCandidates.length; index++) {
1675
1743
  const candidate = parsedCandidates[index];
1676
1744
  const candidateCss = cssByCandidate[index];
1677
- if (candidate && typeof candidateCss === "string" && candidateCss.trim().length > 0) validCandidates.add(originalCandidateByCanonical.get(candidate) ?? candidate);
1745
+ if (candidate && typeof candidateCss === "string" && candidateCss.trim().length > 0) {
1746
+ const originalCandidates = originalCandidatesByCanonical.get(candidate);
1747
+ if (originalCandidates) {
1748
+ for (const originalCandidate of originalCandidates) validCandidates.add(originalCandidate);
1749
+ continue;
1750
+ }
1751
+ validCandidates.add(candidate);
1752
+ }
1678
1753
  }
1679
1754
  return validCandidates;
1680
1755
  }
@@ -1683,16 +1758,34 @@ function createSelectorAliasMap(candidates, options) {
1683
1758
  for (const candidate of candidates) {
1684
1759
  const bareArbitrary = resolveBareArbitraryValueCandidate(candidate, options);
1685
1760
  if (!bareArbitrary) continue;
1686
- aliases.set(escapeCssClassName(bareArbitrary.canonicalCandidate), escapeCssClassName(bareArbitrary.candidate));
1761
+ const canonicalSelector = escapeCssClassName(bareArbitrary.canonicalCandidate);
1762
+ const bareSelectors = aliases.get(canonicalSelector) ?? /* @__PURE__ */ new Set();
1763
+ bareSelectors.add(escapeCssClassName(bareArbitrary.candidate));
1764
+ aliases.set(canonicalSelector, bareSelectors);
1687
1765
  }
1688
1766
  return aliases;
1689
1767
  }
1690
1768
  function replaceBareArbitraryValueSelectors(css, candidates, options) {
1691
1769
  const aliases = createSelectorAliasMap(candidates, options);
1692
1770
  if (aliases.size === 0) return css;
1693
- let result = css;
1694
- for (const [canonicalSelector, bareSelector] of aliases) result = result.replaceAll(canonicalSelector, bareSelector);
1695
- return result;
1771
+ if (Array.from(aliases.values()).every((bareSelectors) => bareSelectors.size === 1)) {
1772
+ let result = css;
1773
+ for (const [canonicalSelector, bareSelectors] of aliases) {
1774
+ const bareSelector = Array.from(bareSelectors)[0];
1775
+ if (bareSelector !== void 0) result = result.replaceAll(canonicalSelector, bareSelector);
1776
+ }
1777
+ return result;
1778
+ }
1779
+ const root = postcss.default.parse(css);
1780
+ root.walkRules((rule) => {
1781
+ let selectors = rule.selectors;
1782
+ for (const [canonicalSelector, bareSelectors] of aliases) selectors = selectors.flatMap((selector) => {
1783
+ if (!selector.includes(canonicalSelector)) return selector;
1784
+ return Array.from(bareSelectors, (bareSelector) => selector.replaceAll(canonicalSelector, bareSelector));
1785
+ });
1786
+ rule.selectors = selectors;
1787
+ });
1788
+ return root.toString();
1696
1789
  }
1697
1790
  function canonicalizeBareArbitraryValueCandidates(candidates, options) {
1698
1791
  return Array.from(candidates, (candidate) => {
@@ -2913,6 +3006,9 @@ function resolveTailwindExecutionOptions(normalized, majorVersion) {
2913
3006
  };
2914
3007
  }
2915
3008
  var BaseCollector = class {
3009
+ packageInfo;
3010
+ options;
3011
+ majorVersion;
2916
3012
  constructor(packageInfo, options, majorVersion) {
2917
3013
  this.packageInfo = packageInfo;
2918
3014
  this.options = options;
@@ -2937,6 +3033,7 @@ var BaseCollector = class {
2937
3033
  }
2938
3034
  };
2939
3035
  var RuntimeCollector = class extends BaseCollector {
3036
+ snapshotFactory;
2940
3037
  inFlightBuild;
2941
3038
  constructor(packageInfo, options, majorVersion, snapshotFactory) {
2942
3039
  super(packageInfo, options, majorVersion);
@@ -16,7 +16,7 @@ import _babelTraverse from "@babel/traverse";
16
16
  import { parse, parse as parse$1 } from "@babel/parser";
17
17
  import { loadConfig } from "tailwindcss-config";
18
18
  //#region package.json
19
- var version = "9.3.0";
19
+ var version = "9.3.2";
20
20
  //#endregion
21
21
  //#region src/constants.ts
22
22
  const pkgName = "tailwindcss-patch";
@@ -177,6 +177,8 @@ function cloneEntry(entry) {
177
177
  };
178
178
  }
179
179
  var CacheStore = class {
180
+ options;
181
+ context;
180
182
  driver;
181
183
  lockPath;
182
184
  memoryCache = null;
@@ -1400,7 +1402,7 @@ function normalizeOptions(options = {}) {
1400
1402
  };
1401
1403
  }
1402
1404
  //#endregion
1403
- //#region ../../node_modules/.pnpm/tsdown@0.21.10_synckit@0.11.12_typescript@6.0.3/node_modules/tsdown/esm-shims.js
1405
+ //#region ../../node_modules/.pnpm/tsdown@0.22.0_tsx@4.21.0_typescript@6.0.3_unrun@0.2.37_synckit@0.11.12_/node_modules/tsdown/esm-shims.js
1404
1406
  const getFilename = () => fileURLToPath(import.meta.url);
1405
1407
  const getDirname = () => path$1.dirname(getFilename());
1406
1408
  const __dirname = /* @__PURE__ */ getDirname();
@@ -1475,7 +1477,8 @@ const DEFAULT_BARE_ARBITRARY_VALUE_UNITS = [
1475
1477
  "ms"
1476
1478
  ];
1477
1479
  const NUMBER_RE = /^-?(?:\d+|\d*\.\d+)$/;
1478
- const FUNCTION_VALUE_RE = /^[a-zA-Z_-][a-zA-Z0-9_-]*\(/;
1480
+ const FUNCTION_VALUE_RE = /^[a-z_-][\w-]*\(/i;
1481
+ const HEX_ESCAPE_RE = /^[\da-f]$/i;
1479
1482
  function splitVariantPrefix(candidate) {
1480
1483
  let depth = 0;
1481
1484
  let quote;
@@ -1541,8 +1544,38 @@ function isBalancedFunctionValue(value) {
1541
1544
  }
1542
1545
  return depth === 0 && quote === void 0;
1543
1546
  }
1547
+ function isEscapedAt(value, index) {
1548
+ let slashCount = 0;
1549
+ for (let slashIndex = index - 1; slashIndex >= 0 && value[slashIndex] === "\\"; slashIndex--) slashCount++;
1550
+ return slashCount % 2 === 1;
1551
+ }
1552
+ function isBalancedBareArbitraryBody(value) {
1553
+ let depth = 0;
1554
+ let quote;
1555
+ for (let index = 0; index < value.length; index++) {
1556
+ const character = value[index];
1557
+ if (isEscapedAt(value, index)) continue;
1558
+ if (quote) {
1559
+ if (character === quote) quote = void 0;
1560
+ continue;
1561
+ }
1562
+ if (character === "\"" || character === "'") {
1563
+ quote = character;
1564
+ continue;
1565
+ }
1566
+ if (character === "(" || character === "{") {
1567
+ depth++;
1568
+ continue;
1569
+ }
1570
+ if (character === ")" || character === "}") {
1571
+ depth--;
1572
+ if (depth < 0) return false;
1573
+ }
1574
+ }
1575
+ return depth === 0 && quote === void 0;
1576
+ }
1544
1577
  function isHexColorValue(value) {
1545
- return /^#(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6,8})$/.test(value);
1578
+ return /^#(?:[0-9a-f]{3,4}|[0-9a-f]{6,8})$/i.test(value);
1546
1579
  }
1547
1580
  function isQuotedValue(value) {
1548
1581
  const quote = value[0];
@@ -1565,29 +1598,61 @@ function normalizeBareArbitraryValueOptions(options) {
1565
1598
  if (normalizedUnits.length === 0) return;
1566
1599
  return { units: normalizedUnits.sort((a, b) => b.length - a.length) };
1567
1600
  }
1601
+ function normalizeEscapedValue(value) {
1602
+ let result = "";
1603
+ for (let index = 0; index < value.length; index++) {
1604
+ const character = value[index];
1605
+ if (character !== "\\") {
1606
+ result += character;
1607
+ continue;
1608
+ }
1609
+ const nextCharacter = value[index + 1];
1610
+ if (nextCharacter === void 0) {
1611
+ result += character;
1612
+ continue;
1613
+ }
1614
+ if (HEX_ESCAPE_RE.test(nextCharacter)) {
1615
+ let hex = "";
1616
+ let nextIndex = index + 1;
1617
+ while (nextIndex < value.length && hex.length < 6) {
1618
+ const hexCharacter = value[nextIndex];
1619
+ if (hexCharacter === void 0 || !HEX_ESCAPE_RE.test(hexCharacter)) break;
1620
+ hex += hexCharacter;
1621
+ nextIndex++;
1622
+ }
1623
+ if (/[\t\n\f\r ]/.test(value[nextIndex] ?? "")) nextIndex++;
1624
+ const decoded = String.fromCodePoint(Number.parseInt(hex, 16));
1625
+ result += decoded === "_" ? "\\_" : decoded;
1626
+ index = nextIndex - 1;
1627
+ continue;
1628
+ }
1629
+ result += nextCharacter === "_" ? "\\_" : nextCharacter;
1630
+ index++;
1631
+ }
1632
+ return result;
1633
+ }
1568
1634
  function resolveValueWithUnit(body, units) {
1635
+ const value = normalizeEscapedValue(body);
1569
1636
  for (const unit of units) {
1570
- if (!body.endsWith(unit)) continue;
1571
- const numberPart = body.slice(0, -unit.length);
1637
+ if (!value.endsWith(unit)) continue;
1638
+ const numberPart = value.slice(0, -unit.length);
1572
1639
  if (NUMBER_RE.test(numberPart)) return `${numberPart}${unit}`;
1573
1640
  }
1574
1641
  }
1575
1642
  function resolveArbitraryValue(body, units) {
1576
- const withUnit = resolveValueWithUnit(body, units);
1643
+ const value = normalizeEscapedValue(body);
1644
+ const withUnit = resolveValueWithUnit(value, units);
1577
1645
  if (withUnit) return withUnit;
1578
- if (isHexColorValue(body)) return body;
1579
- if (isQuotedValue(body)) return body;
1580
- if (FUNCTION_VALUE_RE.test(body) && body.endsWith(")") && isBalancedFunctionValue(body)) return body;
1646
+ if (isHexColorValue(value)) return value;
1647
+ if (isQuotedValue(value)) return value;
1648
+ if (FUNCTION_VALUE_RE.test(value) && value.endsWith(")") && isBalancedFunctionValue(value)) return value;
1581
1649
  }
1582
1650
  function resolveUtilityAndValue(body, units) {
1583
1651
  let depth = 0;
1584
1652
  let quote;
1585
- for (let index = 1; index < body.length; index++) {
1653
+ for (let index = body.length - 1; index > 0; index--) {
1586
1654
  const character = body[index];
1587
- if (character === "\\") {
1588
- index++;
1589
- continue;
1590
- }
1655
+ if (isEscapedAt(body, index)) continue;
1591
1656
  if (quote) {
1592
1657
  if (character === quote) quote = void 0;
1593
1658
  continue;
@@ -1596,11 +1661,11 @@ function resolveUtilityAndValue(body, units) {
1596
1661
  quote = character;
1597
1662
  continue;
1598
1663
  }
1599
- if (character === "(" || character === "{") {
1664
+ if (character === ")" || character === "}") {
1600
1665
  depth++;
1601
1666
  continue;
1602
1667
  }
1603
- if (character === ")" || character === "}") {
1668
+ if (character === "(" || character === "{") {
1604
1669
  depth = Math.max(0, depth - 1);
1605
1670
  continue;
1606
1671
  }
@@ -1623,6 +1688,7 @@ function resolveBareArbitraryValueCandidate(candidate, options) {
1623
1688
  let normalizedBody = important ? body.slice(1) : body;
1624
1689
  const negative = normalizedBody.startsWith("-") ? "-" : "";
1625
1690
  if (negative) normalizedBody = normalizedBody.slice(1);
1691
+ if (!isBalancedBareArbitraryBody(normalizedBody)) return;
1626
1692
  const resolved = resolveUtilityAndValue(normalizedBody, normalizedOptions.units);
1627
1693
  if (!resolved) return;
1628
1694
  return {
@@ -1656,23 +1722,32 @@ function escapeCssClassName(value) {
1656
1722
  function resolveValidTailwindV4Candidates(designSystem, candidates, options) {
1657
1723
  const validCandidates = /* @__PURE__ */ new Set();
1658
1724
  const parsedCandidates = [];
1659
- const originalCandidateByCanonical = /* @__PURE__ */ new Map();
1725
+ const originalCandidatesByCanonical = /* @__PURE__ */ new Map();
1660
1726
  for (const candidate of candidates) {
1661
1727
  if (!candidate) continue;
1662
1728
  const bareArbitrary = resolveBareArbitraryValueCandidate(candidate, options?.bareArbitraryValues);
1663
1729
  const candidateToCheck = bareArbitrary?.canonicalCandidate ?? candidate;
1664
- if (parsedCandidates.includes(candidateToCheck)) continue;
1665
- if (designSystem.parseCandidate(candidateToCheck).length > 0) {
1666
- parsedCandidates.push(candidateToCheck);
1667
- if (bareArbitrary) originalCandidateByCanonical.set(candidateToCheck, candidate);
1730
+ if (bareArbitrary) {
1731
+ const originalCandidates = originalCandidatesByCanonical.get(candidateToCheck) ?? /* @__PURE__ */ new Set();
1732
+ originalCandidates.add(candidate);
1733
+ originalCandidatesByCanonical.set(candidateToCheck, originalCandidates);
1668
1734
  }
1735
+ if (parsedCandidates.includes(candidateToCheck)) continue;
1736
+ if (designSystem.parseCandidate(candidateToCheck).length > 0) parsedCandidates.push(candidateToCheck);
1669
1737
  }
1670
1738
  if (parsedCandidates.length === 0) return validCandidates;
1671
1739
  const cssByCandidate = designSystem.candidatesToCss(parsedCandidates);
1672
1740
  for (let index = 0; index < parsedCandidates.length; index++) {
1673
1741
  const candidate = parsedCandidates[index];
1674
1742
  const candidateCss = cssByCandidate[index];
1675
- if (candidate && typeof candidateCss === "string" && candidateCss.trim().length > 0) validCandidates.add(originalCandidateByCanonical.get(candidate) ?? candidate);
1743
+ if (candidate && typeof candidateCss === "string" && candidateCss.trim().length > 0) {
1744
+ const originalCandidates = originalCandidatesByCanonical.get(candidate);
1745
+ if (originalCandidates) {
1746
+ for (const originalCandidate of originalCandidates) validCandidates.add(originalCandidate);
1747
+ continue;
1748
+ }
1749
+ validCandidates.add(candidate);
1750
+ }
1676
1751
  }
1677
1752
  return validCandidates;
1678
1753
  }
@@ -1681,16 +1756,34 @@ function createSelectorAliasMap(candidates, options) {
1681
1756
  for (const candidate of candidates) {
1682
1757
  const bareArbitrary = resolveBareArbitraryValueCandidate(candidate, options);
1683
1758
  if (!bareArbitrary) continue;
1684
- aliases.set(escapeCssClassName(bareArbitrary.canonicalCandidate), escapeCssClassName(bareArbitrary.candidate));
1759
+ const canonicalSelector = escapeCssClassName(bareArbitrary.canonicalCandidate);
1760
+ const bareSelectors = aliases.get(canonicalSelector) ?? /* @__PURE__ */ new Set();
1761
+ bareSelectors.add(escapeCssClassName(bareArbitrary.candidate));
1762
+ aliases.set(canonicalSelector, bareSelectors);
1685
1763
  }
1686
1764
  return aliases;
1687
1765
  }
1688
1766
  function replaceBareArbitraryValueSelectors(css, candidates, options) {
1689
1767
  const aliases = createSelectorAliasMap(candidates, options);
1690
1768
  if (aliases.size === 0) return css;
1691
- let result = css;
1692
- for (const [canonicalSelector, bareSelector] of aliases) result = result.replaceAll(canonicalSelector, bareSelector);
1693
- return result;
1769
+ if (Array.from(aliases.values()).every((bareSelectors) => bareSelectors.size === 1)) {
1770
+ let result = css;
1771
+ for (const [canonicalSelector, bareSelectors] of aliases) {
1772
+ const bareSelector = Array.from(bareSelectors)[0];
1773
+ if (bareSelector !== void 0) result = result.replaceAll(canonicalSelector, bareSelector);
1774
+ }
1775
+ return result;
1776
+ }
1777
+ const root = postcss.parse(css);
1778
+ root.walkRules((rule) => {
1779
+ let selectors = rule.selectors;
1780
+ for (const [canonicalSelector, bareSelectors] of aliases) selectors = selectors.flatMap((selector) => {
1781
+ if (!selector.includes(canonicalSelector)) return selector;
1782
+ return Array.from(bareSelectors, (bareSelector) => selector.replaceAll(canonicalSelector, bareSelector));
1783
+ });
1784
+ rule.selectors = selectors;
1785
+ });
1786
+ return root.toString();
1694
1787
  }
1695
1788
  function canonicalizeBareArbitraryValueCandidates(candidates, options) {
1696
1789
  return Array.from(candidates, (candidate) => {
@@ -2911,6 +3004,9 @@ function resolveTailwindExecutionOptions(normalized, majorVersion) {
2911
3004
  };
2912
3005
  }
2913
3006
  var BaseCollector = class {
3007
+ packageInfo;
3008
+ options;
3009
+ majorVersion;
2914
3010
  constructor(packageInfo, options, majorVersion) {
2915
3011
  this.packageInfo = packageInfo;
2916
3012
  this.options = options;
@@ -2935,6 +3031,7 @@ var BaseCollector = class {
2935
3031
  }
2936
3032
  };
2937
3033
  var RuntimeCollector = class extends BaseCollector {
3034
+ snapshotFactory;
2938
3035
  inFlightBuild;
2939
3036
  constructor(packageInfo, options, majorVersion, snapshotFactory) {
2940
3037
  super(packageInfo, options, majorVersion);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tailwindcss-patch",
3
- "version": "9.3.0",
3
+ "version": "9.3.2",
4
4
  "description": "patch tailwindcss for exposing context and extract classes",
5
5
  "author": "ice breaker <1324318532@qq.com>",
6
6
  "license": "MIT",
@@ -65,21 +65,21 @@
65
65
  "@babel/parser": "^7.29.3",
66
66
  "@babel/traverse": "^7.29.0",
67
67
  "@babel/types": "^7.29.0",
68
- "@tailwindcss/node": "^4.2.4",
69
- "@tailwindcss/oxide": "^4.2.4",
68
+ "@tailwindcss/node": "^4.3.0",
69
+ "@tailwindcss/oxide": "^4.3.0",
70
70
  "cac": "6.7.14",
71
71
  "consola": "^3.4.2",
72
- "fs-extra": "^11.3.4",
72
+ "fs-extra": "^11.3.5",
73
73
  "local-pkg": "^1.1.2",
74
74
  "pathe": "^2.0.3",
75
75
  "postcss": "^8.5.14",
76
- "semver": "^7.7.4",
76
+ "semver": "^7.8.0",
77
77
  "tailwindcss-config": "^1.1.5",
78
- "@tailwindcss-mangle/config": "7.0.1"
78
+ "@tailwindcss-mangle/config": "7.0.2"
79
79
  },
80
80
  "devDependencies": {
81
- "@tailwindcss/postcss": "^4.2.4",
82
- "@tailwindcss/vite": "^4.2.4",
81
+ "@tailwindcss/postcss": "^4.3.0",
82
+ "@tailwindcss/vite": "^4.3.0",
83
83
  "tailwindcss": "^4.1.18",
84
84
  "tailwindcss-3": "npm:tailwindcss@^3.4.19",
85
85
  "tailwindcss-4": "npm:tailwindcss@^4.1.18"
@@ -39,7 +39,8 @@ const DEFAULT_BARE_ARBITRARY_VALUE_UNITS = [
39
39
  ]
40
40
 
41
41
  const NUMBER_RE = /^-?(?:\d+|\d*\.\d+)$/
42
- const FUNCTION_VALUE_RE = /^[a-zA-Z_-][a-zA-Z0-9_-]*\(/
42
+ const FUNCTION_VALUE_RE = /^[a-z_-][\w-]*\(/i
43
+ const HEX_ESCAPE_RE = /^[\da-f]$/i
43
44
 
44
45
  function splitVariantPrefix(candidate: string) {
45
46
  let depth = 0
@@ -133,8 +134,55 @@ function isBalancedFunctionValue(value: string) {
133
134
  return depth === 0 && quote === undefined
134
135
  }
135
136
 
137
+ function isEscapedAt(value: string, index: number) {
138
+ let slashCount = 0
139
+ for (let slashIndex = index - 1; slashIndex >= 0 && value[slashIndex] === '\\'; slashIndex--) {
140
+ slashCount++
141
+ }
142
+ return slashCount % 2 === 1
143
+ }
144
+
145
+ function isBalancedBareArbitraryBody(value: string) {
146
+ let depth = 0
147
+ let quote: string | undefined
148
+
149
+ for (let index = 0; index < value.length; index++) {
150
+ const character = value[index]
151
+
152
+ if (isEscapedAt(value, index)) {
153
+ continue
154
+ }
155
+
156
+ if (quote) {
157
+ if (character === quote) {
158
+ quote = undefined
159
+ }
160
+ continue
161
+ }
162
+
163
+ if (character === '"' || character === '\'') {
164
+ quote = character
165
+ continue
166
+ }
167
+
168
+ if (character === '(' || character === '{') {
169
+ depth++
170
+ continue
171
+ }
172
+
173
+ if (character === ')' || character === '}') {
174
+ depth--
175
+ if (depth < 0) {
176
+ return false
177
+ }
178
+ }
179
+ }
180
+
181
+ return depth === 0 && quote === undefined
182
+ }
183
+
136
184
  function isHexColorValue(value: string) {
137
- return /^#(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6,8})$/.test(value)
185
+ return /^#(?:[0-9a-f]{3,4}|[0-9a-f]{6,8})$/i.test(value)
138
186
  }
139
187
 
140
188
  function isQuotedValue(value: string) {
@@ -173,12 +221,55 @@ function normalizeBareArbitraryValueOptions(options: boolean | BareArbitraryValu
173
221
  }
174
222
  }
175
223
 
224
+ function normalizeEscapedValue(value: string) {
225
+ let result = ''
226
+ for (let index = 0; index < value.length; index++) {
227
+ const character = value[index]
228
+ if (character !== '\\') {
229
+ result += character
230
+ continue
231
+ }
232
+
233
+ const nextCharacter = value[index + 1]
234
+ if (nextCharacter === undefined) {
235
+ result += character
236
+ continue
237
+ }
238
+
239
+ if (HEX_ESCAPE_RE.test(nextCharacter)) {
240
+ let hex = ''
241
+ let nextIndex = index + 1
242
+ while (nextIndex < value.length && hex.length < 6) {
243
+ const hexCharacter = value[nextIndex]
244
+ if (hexCharacter === undefined || !HEX_ESCAPE_RE.test(hexCharacter)) {
245
+ break
246
+ }
247
+ hex += hexCharacter
248
+ nextIndex++
249
+ }
250
+ if (/[\t\n\f\r ]/.test(value[nextIndex] ?? '')) {
251
+ nextIndex++
252
+ }
253
+
254
+ const decoded = String.fromCodePoint(Number.parseInt(hex, 16))
255
+ result += decoded === '_' ? '\\_' : decoded
256
+ index = nextIndex - 1
257
+ continue
258
+ }
259
+
260
+ result += nextCharacter === '_' ? '\\_' : nextCharacter
261
+ index++
262
+ }
263
+ return result
264
+ }
265
+
176
266
  function resolveValueWithUnit(body: string, units: string[]) {
267
+ const value = normalizeEscapedValue(body)
177
268
  for (const unit of units) {
178
- if (!body.endsWith(unit)) {
269
+ if (!value.endsWith(unit)) {
179
270
  continue
180
271
  }
181
- const numberPart = body.slice(0, -unit.length)
272
+ const numberPart = value.slice(0, -unit.length)
182
273
  if (NUMBER_RE.test(numberPart)) {
183
274
  return `${numberPart}${unit}`
184
275
  }
@@ -186,21 +277,22 @@ function resolveValueWithUnit(body: string, units: string[]) {
186
277
  }
187
278
 
188
279
  function resolveArbitraryValue(body: string, units: string[]) {
189
- const withUnit = resolveValueWithUnit(body, units)
280
+ const value = normalizeEscapedValue(body)
281
+ const withUnit = resolveValueWithUnit(value, units)
190
282
  if (withUnit) {
191
283
  return withUnit
192
284
  }
193
285
 
194
- if (isHexColorValue(body)) {
195
- return body
286
+ if (isHexColorValue(value)) {
287
+ return value
196
288
  }
197
289
 
198
- if (isQuotedValue(body)) {
199
- return body
290
+ if (isQuotedValue(value)) {
291
+ return value
200
292
  }
201
293
 
202
- if (FUNCTION_VALUE_RE.test(body) && body.endsWith(')') && isBalancedFunctionValue(body)) {
203
- return body
294
+ if (FUNCTION_VALUE_RE.test(value) && value.endsWith(')') && isBalancedFunctionValue(value)) {
295
+ return value
204
296
  }
205
297
  }
206
298
 
@@ -208,11 +300,10 @@ function resolveUtilityAndValue(body: string, units: string[]) {
208
300
  let depth = 0
209
301
  let quote: string | undefined
210
302
 
211
- for (let index = 1; index < body.length; index++) {
303
+ for (let index = body.length - 1; index > 0; index--) {
212
304
  const character = body[index]
213
305
 
214
- if (character === '\\') {
215
- index++
306
+ if (isEscapedAt(body, index)) {
216
307
  continue
217
308
  }
218
309
 
@@ -228,12 +319,12 @@ function resolveUtilityAndValue(body: string, units: string[]) {
228
319
  continue
229
320
  }
230
321
 
231
- if (character === '(' || character === '{') {
322
+ if (character === ')' || character === '}') {
232
323
  depth++
233
324
  continue
234
325
  }
235
326
 
236
- if (character === ')' || character === '}') {
327
+ if (character === '(' || character === '{') {
237
328
  depth = Math.max(0, depth - 1)
238
329
  continue
239
330
  }
@@ -274,6 +365,9 @@ export function resolveBareArbitraryValueCandidate(
274
365
  if (negative) {
275
366
  normalizedBody = normalizedBody.slice(1)
276
367
  }
368
+ if (!isBalancedBareArbitraryBody(normalizedBody)) {
369
+ return
370
+ }
277
371
 
278
372
  const resolved = resolveUtilityAndValue(normalizedBody, normalizedOptions.units)
279
373
  if (!resolved) {
@@ -1,10 +1,7 @@
1
+ import type { BareArbitraryValueOptions } from './bare-arbitrary-values'
1
2
  import type { TailwindV4DesignSystem } from './types'
2
3
  import postcss from 'postcss'
3
- import {
4
- escapeCssClassName,
5
- type BareArbitraryValueOptions,
6
- resolveBareArbitraryValueCandidate,
7
- } from './bare-arbitrary-values'
4
+ import { escapeCssClassName, resolveBareArbitraryValueCandidate } from './bare-arbitrary-values'
8
5
 
9
6
  export function resolveValidTailwindV4Candidates(
10
7
  designSystem: TailwindV4DesignSystem,
@@ -15,7 +12,7 @@ export function resolveValidTailwindV4Candidates(
15
12
  ): Set<string> {
16
13
  const validCandidates = new Set<string>()
17
14
  const parsedCandidates: string[] = []
18
- const originalCandidateByCanonical = new Map<string, string>()
15
+ const originalCandidatesByCanonical = new Map<string, Set<string>>()
19
16
 
20
17
  for (const candidate of candidates) {
21
18
  if (!candidate) {
@@ -25,15 +22,19 @@ export function resolveValidTailwindV4Candidates(
25
22
  const bareArbitrary = resolveBareArbitraryValueCandidate(candidate, options?.bareArbitraryValues)
26
23
  const candidateToCheck = bareArbitrary?.canonicalCandidate ?? candidate
27
24
 
28
- if (parsedCandidates.includes(candidateToCheck)) {
25
+ if (bareArbitrary) {
26
+ const originalCandidates = originalCandidatesByCanonical.get(candidateToCheck) ?? new Set<string>()
27
+ originalCandidates.add(candidate)
28
+ originalCandidatesByCanonical.set(candidateToCheck, originalCandidates)
29
+ }
30
+
31
+ const alreadyParsed = parsedCandidates.includes(candidateToCheck)
32
+ if (alreadyParsed) {
29
33
  continue
30
34
  }
31
35
 
32
36
  if (designSystem.parseCandidate(candidateToCheck).length > 0) {
33
37
  parsedCandidates.push(candidateToCheck)
34
- if (bareArbitrary) {
35
- originalCandidateByCanonical.set(candidateToCheck, candidate)
36
- }
37
38
  }
38
39
  }
39
40
 
@@ -46,7 +47,14 @@ export function resolveValidTailwindV4Candidates(
46
47
  const candidate = parsedCandidates[index]
47
48
  const candidateCss = cssByCandidate[index]
48
49
  if (candidate && typeof candidateCss === 'string' && candidateCss.trim().length > 0) {
49
- validCandidates.add(originalCandidateByCanonical.get(candidate) ?? candidate)
50
+ const originalCandidates = originalCandidatesByCanonical.get(candidate)
51
+ if (originalCandidates) {
52
+ for (const originalCandidate of originalCandidates) {
53
+ validCandidates.add(originalCandidate)
54
+ }
55
+ continue
56
+ }
57
+ validCandidates.add(candidate)
50
58
  }
51
59
  }
52
60
 
@@ -57,16 +65,16 @@ function createSelectorAliasMap(
57
65
  candidates: Iterable<string>,
58
66
  options?: boolean | BareArbitraryValueOptions,
59
67
  ) {
60
- const aliases = new Map<string, string>()
68
+ const aliases = new Map<string, Set<string>>()
61
69
  for (const candidate of candidates) {
62
70
  const bareArbitrary = resolveBareArbitraryValueCandidate(candidate, options)
63
71
  if (!bareArbitrary) {
64
72
  continue
65
73
  }
66
- aliases.set(
67
- escapeCssClassName(bareArbitrary.canonicalCandidate),
68
- escapeCssClassName(bareArbitrary.candidate),
69
- )
74
+ const canonicalSelector = escapeCssClassName(bareArbitrary.canonicalCandidate)
75
+ const bareSelectors = aliases.get(canonicalSelector) ?? new Set<string>()
76
+ bareSelectors.add(escapeCssClassName(bareArbitrary.candidate))
77
+ aliases.set(canonicalSelector, bareSelectors)
70
78
  }
71
79
  return aliases
72
80
  }
@@ -81,11 +89,31 @@ export function replaceBareArbitraryValueSelectors(
81
89
  return css
82
90
  }
83
91
 
84
- let result = css
85
- for (const [canonicalSelector, bareSelector] of aliases) {
86
- result = result.replaceAll(canonicalSelector, bareSelector)
92
+ if (Array.from(aliases.values()).every(bareSelectors => bareSelectors.size === 1)) {
93
+ let result = css
94
+ for (const [canonicalSelector, bareSelectors] of aliases) {
95
+ const bareSelector = Array.from(bareSelectors)[0]
96
+ if (bareSelector !== undefined) {
97
+ result = result.replaceAll(canonicalSelector, bareSelector)
98
+ }
99
+ }
100
+ return result
87
101
  }
88
- return result
102
+
103
+ const root = postcss.parse(css)
104
+ root.walkRules((rule) => {
105
+ let selectors = rule.selectors
106
+ for (const [canonicalSelector, bareSelectors] of aliases) {
107
+ selectors = selectors.flatMap((selector) => {
108
+ if (!selector.includes(canonicalSelector)) {
109
+ return selector
110
+ }
111
+ return Array.from(bareSelectors, bareSelector => selector.replaceAll(canonicalSelector, bareSelector))
112
+ })
113
+ }
114
+ rule.selectors = selectors
115
+ })
116
+ return root.toString()
89
117
  }
90
118
 
91
119
  export function canonicalizeBareArbitraryValueCandidates(