tailwindcss-patch 9.3.1 → 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 +2 -2
- package/dist/cli.mjs +2 -2
- package/dist/commands/cli-runtime.js +1 -1
- package/dist/commands/cli-runtime.mjs +1 -1
- package/dist/{index.bundle-Y1jzXpYx.js → index.bundle-CcVIAfDb.js} +1 -1
- package/dist/{index.bundle-BKRsKEHP.mjs → index.bundle-DjS24i5r.mjs} +1 -1
- package/dist/index.js +2 -2
- package/dist/index.mjs +2 -2
- package/dist/{validate-Bd1fbQsd.js → validate-CF0M_7KH.js} +117 -26
- package/dist/{validate-CVInpab6.mjs → validate-Sq_yuh3r.mjs} +117 -26
- package/package.json +1 -1
- package/src/v4/bare-arbitrary-values.ts +110 -16
- package/src/v4/candidates.ts +48 -20
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const require_chunk = require("./chunk-8l464Juk.js");
|
|
2
|
-
const require_validate = require("./validate-
|
|
3
|
-
const require_index_bundle = require("./index.bundle-
|
|
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-
|
|
2
|
-
import { t as createTailwindcssPatchCli } from "./index.bundle-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
3
|
-
const require_index_bundle = require("./index.bundle-
|
|
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-
|
|
2
|
-
import { a as resolveTailwindV4SourceFromPatchOptions, i as resolveTailwindV4Source, n as defineConfig, o as createTailwindV4Engine, r as mountTailwindcssPatchCommands, t as createTailwindcssPatchCli } from "./index.bundle-
|
|
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.
|
|
26
|
+
var version = "9.3.2";
|
|
27
27
|
//#endregion
|
|
28
28
|
//#region src/constants.ts
|
|
29
29
|
const pkgName = "tailwindcss-patch";
|
|
@@ -1479,7 +1479,8 @@ const DEFAULT_BARE_ARBITRARY_VALUE_UNITS = [
|
|
|
1479
1479
|
"ms"
|
|
1480
1480
|
];
|
|
1481
1481
|
const NUMBER_RE = /^-?(?:\d+|\d*\.\d+)$/;
|
|
1482
|
-
const FUNCTION_VALUE_RE = /^[a-
|
|
1482
|
+
const FUNCTION_VALUE_RE = /^[a-z_-][\w-]*\(/i;
|
|
1483
|
+
const HEX_ESCAPE_RE = /^[\da-f]$/i;
|
|
1483
1484
|
function splitVariantPrefix(candidate) {
|
|
1484
1485
|
let depth = 0;
|
|
1485
1486
|
let quote;
|
|
@@ -1545,8 +1546,38 @@ function isBalancedFunctionValue(value) {
|
|
|
1545
1546
|
}
|
|
1546
1547
|
return depth === 0 && quote === void 0;
|
|
1547
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
|
+
}
|
|
1548
1579
|
function isHexColorValue(value) {
|
|
1549
|
-
return /^#(?:[0-9a-
|
|
1580
|
+
return /^#(?:[0-9a-f]{3,4}|[0-9a-f]{6,8})$/i.test(value);
|
|
1550
1581
|
}
|
|
1551
1582
|
function isQuotedValue(value) {
|
|
1552
1583
|
const quote = value[0];
|
|
@@ -1569,29 +1600,61 @@ function normalizeBareArbitraryValueOptions(options) {
|
|
|
1569
1600
|
if (normalizedUnits.length === 0) return;
|
|
1570
1601
|
return { units: normalizedUnits.sort((a, b) => b.length - a.length) };
|
|
1571
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
|
+
}
|
|
1572
1636
|
function resolveValueWithUnit(body, units) {
|
|
1637
|
+
const value = normalizeEscapedValue(body);
|
|
1573
1638
|
for (const unit of units) {
|
|
1574
|
-
if (!
|
|
1575
|
-
const numberPart =
|
|
1639
|
+
if (!value.endsWith(unit)) continue;
|
|
1640
|
+
const numberPart = value.slice(0, -unit.length);
|
|
1576
1641
|
if (NUMBER_RE.test(numberPart)) return `${numberPart}${unit}`;
|
|
1577
1642
|
}
|
|
1578
1643
|
}
|
|
1579
1644
|
function resolveArbitraryValue(body, units) {
|
|
1580
|
-
const
|
|
1645
|
+
const value = normalizeEscapedValue(body);
|
|
1646
|
+
const withUnit = resolveValueWithUnit(value, units);
|
|
1581
1647
|
if (withUnit) return withUnit;
|
|
1582
|
-
if (isHexColorValue(
|
|
1583
|
-
if (isQuotedValue(
|
|
1584
|
-
if (FUNCTION_VALUE_RE.test(
|
|
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;
|
|
1585
1651
|
}
|
|
1586
1652
|
function resolveUtilityAndValue(body, units) {
|
|
1587
1653
|
let depth = 0;
|
|
1588
1654
|
let quote;
|
|
1589
|
-
for (let index = 1; index
|
|
1655
|
+
for (let index = body.length - 1; index > 0; index--) {
|
|
1590
1656
|
const character = body[index];
|
|
1591
|
-
if (
|
|
1592
|
-
index++;
|
|
1593
|
-
continue;
|
|
1594
|
-
}
|
|
1657
|
+
if (isEscapedAt(body, index)) continue;
|
|
1595
1658
|
if (quote) {
|
|
1596
1659
|
if (character === quote) quote = void 0;
|
|
1597
1660
|
continue;
|
|
@@ -1600,11 +1663,11 @@ function resolveUtilityAndValue(body, units) {
|
|
|
1600
1663
|
quote = character;
|
|
1601
1664
|
continue;
|
|
1602
1665
|
}
|
|
1603
|
-
if (character === "
|
|
1666
|
+
if (character === ")" || character === "}") {
|
|
1604
1667
|
depth++;
|
|
1605
1668
|
continue;
|
|
1606
1669
|
}
|
|
1607
|
-
if (character === "
|
|
1670
|
+
if (character === "(" || character === "{") {
|
|
1608
1671
|
depth = Math.max(0, depth - 1);
|
|
1609
1672
|
continue;
|
|
1610
1673
|
}
|
|
@@ -1627,6 +1690,7 @@ function resolveBareArbitraryValueCandidate(candidate, options) {
|
|
|
1627
1690
|
let normalizedBody = important ? body.slice(1) : body;
|
|
1628
1691
|
const negative = normalizedBody.startsWith("-") ? "-" : "";
|
|
1629
1692
|
if (negative) normalizedBody = normalizedBody.slice(1);
|
|
1693
|
+
if (!isBalancedBareArbitraryBody(normalizedBody)) return;
|
|
1630
1694
|
const resolved = resolveUtilityAndValue(normalizedBody, normalizedOptions.units);
|
|
1631
1695
|
if (!resolved) return;
|
|
1632
1696
|
return {
|
|
@@ -1660,23 +1724,32 @@ function escapeCssClassName(value) {
|
|
|
1660
1724
|
function resolveValidTailwindV4Candidates(designSystem, candidates, options) {
|
|
1661
1725
|
const validCandidates = /* @__PURE__ */ new Set();
|
|
1662
1726
|
const parsedCandidates = [];
|
|
1663
|
-
const
|
|
1727
|
+
const originalCandidatesByCanonical = /* @__PURE__ */ new Map();
|
|
1664
1728
|
for (const candidate of candidates) {
|
|
1665
1729
|
if (!candidate) continue;
|
|
1666
1730
|
const bareArbitrary = resolveBareArbitraryValueCandidate(candidate, options?.bareArbitraryValues);
|
|
1667
1731
|
const candidateToCheck = bareArbitrary?.canonicalCandidate ?? candidate;
|
|
1668
|
-
if (
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1732
|
+
if (bareArbitrary) {
|
|
1733
|
+
const originalCandidates = originalCandidatesByCanonical.get(candidateToCheck) ?? /* @__PURE__ */ new Set();
|
|
1734
|
+
originalCandidates.add(candidate);
|
|
1735
|
+
originalCandidatesByCanonical.set(candidateToCheck, originalCandidates);
|
|
1672
1736
|
}
|
|
1737
|
+
if (parsedCandidates.includes(candidateToCheck)) continue;
|
|
1738
|
+
if (designSystem.parseCandidate(candidateToCheck).length > 0) parsedCandidates.push(candidateToCheck);
|
|
1673
1739
|
}
|
|
1674
1740
|
if (parsedCandidates.length === 0) return validCandidates;
|
|
1675
1741
|
const cssByCandidate = designSystem.candidatesToCss(parsedCandidates);
|
|
1676
1742
|
for (let index = 0; index < parsedCandidates.length; index++) {
|
|
1677
1743
|
const candidate = parsedCandidates[index];
|
|
1678
1744
|
const candidateCss = cssByCandidate[index];
|
|
1679
|
-
if (candidate && typeof candidateCss === "string" && candidateCss.trim().length > 0)
|
|
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
|
+
}
|
|
1680
1753
|
}
|
|
1681
1754
|
return validCandidates;
|
|
1682
1755
|
}
|
|
@@ -1685,16 +1758,34 @@ function createSelectorAliasMap(candidates, options) {
|
|
|
1685
1758
|
for (const candidate of candidates) {
|
|
1686
1759
|
const bareArbitrary = resolveBareArbitraryValueCandidate(candidate, options);
|
|
1687
1760
|
if (!bareArbitrary) continue;
|
|
1688
|
-
|
|
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);
|
|
1689
1765
|
}
|
|
1690
1766
|
return aliases;
|
|
1691
1767
|
}
|
|
1692
1768
|
function replaceBareArbitraryValueSelectors(css, candidates, options) {
|
|
1693
1769
|
const aliases = createSelectorAliasMap(candidates, options);
|
|
1694
1770
|
if (aliases.size === 0) return css;
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
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();
|
|
1698
1789
|
}
|
|
1699
1790
|
function canonicalizeBareArbitraryValueCandidates(candidates, options) {
|
|
1700
1791
|
return Array.from(candidates, (candidate) => {
|
|
@@ -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.
|
|
19
|
+
var version = "9.3.2";
|
|
20
20
|
//#endregion
|
|
21
21
|
//#region src/constants.ts
|
|
22
22
|
const pkgName = "tailwindcss-patch";
|
|
@@ -1477,7 +1477,8 @@ const DEFAULT_BARE_ARBITRARY_VALUE_UNITS = [
|
|
|
1477
1477
|
"ms"
|
|
1478
1478
|
];
|
|
1479
1479
|
const NUMBER_RE = /^-?(?:\d+|\d*\.\d+)$/;
|
|
1480
|
-
const FUNCTION_VALUE_RE = /^[a-
|
|
1480
|
+
const FUNCTION_VALUE_RE = /^[a-z_-][\w-]*\(/i;
|
|
1481
|
+
const HEX_ESCAPE_RE = /^[\da-f]$/i;
|
|
1481
1482
|
function splitVariantPrefix(candidate) {
|
|
1482
1483
|
let depth = 0;
|
|
1483
1484
|
let quote;
|
|
@@ -1543,8 +1544,38 @@ function isBalancedFunctionValue(value) {
|
|
|
1543
1544
|
}
|
|
1544
1545
|
return depth === 0 && quote === void 0;
|
|
1545
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
|
+
}
|
|
1546
1577
|
function isHexColorValue(value) {
|
|
1547
|
-
return /^#(?:[0-9a-
|
|
1578
|
+
return /^#(?:[0-9a-f]{3,4}|[0-9a-f]{6,8})$/i.test(value);
|
|
1548
1579
|
}
|
|
1549
1580
|
function isQuotedValue(value) {
|
|
1550
1581
|
const quote = value[0];
|
|
@@ -1567,29 +1598,61 @@ function normalizeBareArbitraryValueOptions(options) {
|
|
|
1567
1598
|
if (normalizedUnits.length === 0) return;
|
|
1568
1599
|
return { units: normalizedUnits.sort((a, b) => b.length - a.length) };
|
|
1569
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
|
+
}
|
|
1570
1634
|
function resolveValueWithUnit(body, units) {
|
|
1635
|
+
const value = normalizeEscapedValue(body);
|
|
1571
1636
|
for (const unit of units) {
|
|
1572
|
-
if (!
|
|
1573
|
-
const numberPart =
|
|
1637
|
+
if (!value.endsWith(unit)) continue;
|
|
1638
|
+
const numberPart = value.slice(0, -unit.length);
|
|
1574
1639
|
if (NUMBER_RE.test(numberPart)) return `${numberPart}${unit}`;
|
|
1575
1640
|
}
|
|
1576
1641
|
}
|
|
1577
1642
|
function resolveArbitraryValue(body, units) {
|
|
1578
|
-
const
|
|
1643
|
+
const value = normalizeEscapedValue(body);
|
|
1644
|
+
const withUnit = resolveValueWithUnit(value, units);
|
|
1579
1645
|
if (withUnit) return withUnit;
|
|
1580
|
-
if (isHexColorValue(
|
|
1581
|
-
if (isQuotedValue(
|
|
1582
|
-
if (FUNCTION_VALUE_RE.test(
|
|
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;
|
|
1583
1649
|
}
|
|
1584
1650
|
function resolveUtilityAndValue(body, units) {
|
|
1585
1651
|
let depth = 0;
|
|
1586
1652
|
let quote;
|
|
1587
|
-
for (let index = 1; index
|
|
1653
|
+
for (let index = body.length - 1; index > 0; index--) {
|
|
1588
1654
|
const character = body[index];
|
|
1589
|
-
if (
|
|
1590
|
-
index++;
|
|
1591
|
-
continue;
|
|
1592
|
-
}
|
|
1655
|
+
if (isEscapedAt(body, index)) continue;
|
|
1593
1656
|
if (quote) {
|
|
1594
1657
|
if (character === quote) quote = void 0;
|
|
1595
1658
|
continue;
|
|
@@ -1598,11 +1661,11 @@ function resolveUtilityAndValue(body, units) {
|
|
|
1598
1661
|
quote = character;
|
|
1599
1662
|
continue;
|
|
1600
1663
|
}
|
|
1601
|
-
if (character === "
|
|
1664
|
+
if (character === ")" || character === "}") {
|
|
1602
1665
|
depth++;
|
|
1603
1666
|
continue;
|
|
1604
1667
|
}
|
|
1605
|
-
if (character === "
|
|
1668
|
+
if (character === "(" || character === "{") {
|
|
1606
1669
|
depth = Math.max(0, depth - 1);
|
|
1607
1670
|
continue;
|
|
1608
1671
|
}
|
|
@@ -1625,6 +1688,7 @@ function resolveBareArbitraryValueCandidate(candidate, options) {
|
|
|
1625
1688
|
let normalizedBody = important ? body.slice(1) : body;
|
|
1626
1689
|
const negative = normalizedBody.startsWith("-") ? "-" : "";
|
|
1627
1690
|
if (negative) normalizedBody = normalizedBody.slice(1);
|
|
1691
|
+
if (!isBalancedBareArbitraryBody(normalizedBody)) return;
|
|
1628
1692
|
const resolved = resolveUtilityAndValue(normalizedBody, normalizedOptions.units);
|
|
1629
1693
|
if (!resolved) return;
|
|
1630
1694
|
return {
|
|
@@ -1658,23 +1722,32 @@ function escapeCssClassName(value) {
|
|
|
1658
1722
|
function resolveValidTailwindV4Candidates(designSystem, candidates, options) {
|
|
1659
1723
|
const validCandidates = /* @__PURE__ */ new Set();
|
|
1660
1724
|
const parsedCandidates = [];
|
|
1661
|
-
const
|
|
1725
|
+
const originalCandidatesByCanonical = /* @__PURE__ */ new Map();
|
|
1662
1726
|
for (const candidate of candidates) {
|
|
1663
1727
|
if (!candidate) continue;
|
|
1664
1728
|
const bareArbitrary = resolveBareArbitraryValueCandidate(candidate, options?.bareArbitraryValues);
|
|
1665
1729
|
const candidateToCheck = bareArbitrary?.canonicalCandidate ?? candidate;
|
|
1666
|
-
if (
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1730
|
+
if (bareArbitrary) {
|
|
1731
|
+
const originalCandidates = originalCandidatesByCanonical.get(candidateToCheck) ?? /* @__PURE__ */ new Set();
|
|
1732
|
+
originalCandidates.add(candidate);
|
|
1733
|
+
originalCandidatesByCanonical.set(candidateToCheck, originalCandidates);
|
|
1670
1734
|
}
|
|
1735
|
+
if (parsedCandidates.includes(candidateToCheck)) continue;
|
|
1736
|
+
if (designSystem.parseCandidate(candidateToCheck).length > 0) parsedCandidates.push(candidateToCheck);
|
|
1671
1737
|
}
|
|
1672
1738
|
if (parsedCandidates.length === 0) return validCandidates;
|
|
1673
1739
|
const cssByCandidate = designSystem.candidatesToCss(parsedCandidates);
|
|
1674
1740
|
for (let index = 0; index < parsedCandidates.length; index++) {
|
|
1675
1741
|
const candidate = parsedCandidates[index];
|
|
1676
1742
|
const candidateCss = cssByCandidate[index];
|
|
1677
|
-
if (candidate && typeof candidateCss === "string" && candidateCss.trim().length > 0)
|
|
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
|
+
}
|
|
1678
1751
|
}
|
|
1679
1752
|
return validCandidates;
|
|
1680
1753
|
}
|
|
@@ -1683,16 +1756,34 @@ function createSelectorAliasMap(candidates, options) {
|
|
|
1683
1756
|
for (const candidate of candidates) {
|
|
1684
1757
|
const bareArbitrary = resolveBareArbitraryValueCandidate(candidate, options);
|
|
1685
1758
|
if (!bareArbitrary) continue;
|
|
1686
|
-
|
|
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);
|
|
1687
1763
|
}
|
|
1688
1764
|
return aliases;
|
|
1689
1765
|
}
|
|
1690
1766
|
function replaceBareArbitraryValueSelectors(css, candidates, options) {
|
|
1691
1767
|
const aliases = createSelectorAliasMap(candidates, options);
|
|
1692
1768
|
if (aliases.size === 0) return css;
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
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();
|
|
1696
1787
|
}
|
|
1697
1788
|
function canonicalizeBareArbitraryValueCandidates(candidates, options) {
|
|
1698
1789
|
return Array.from(candidates, (candidate) => {
|
package/package.json
CHANGED
|
@@ -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-
|
|
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-
|
|
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 (!
|
|
269
|
+
if (!value.endsWith(unit)) {
|
|
179
270
|
continue
|
|
180
271
|
}
|
|
181
|
-
const numberPart =
|
|
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
|
|
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(
|
|
195
|
-
return
|
|
286
|
+
if (isHexColorValue(value)) {
|
|
287
|
+
return value
|
|
196
288
|
}
|
|
197
289
|
|
|
198
|
-
if (isQuotedValue(
|
|
199
|
-
return
|
|
290
|
+
if (isQuotedValue(value)) {
|
|
291
|
+
return value
|
|
200
292
|
}
|
|
201
293
|
|
|
202
|
-
if (FUNCTION_VALUE_RE.test(
|
|
203
|
-
return
|
|
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
|
|
303
|
+
for (let index = body.length - 1; index > 0; index--) {
|
|
212
304
|
const character = body[index]
|
|
213
305
|
|
|
214
|
-
if (
|
|
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 === '
|
|
322
|
+
if (character === ')' || character === '}') {
|
|
232
323
|
depth++
|
|
233
324
|
continue
|
|
234
325
|
}
|
|
235
326
|
|
|
236
|
-
if (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) {
|
package/src/v4/candidates.ts
CHANGED
|
@@ -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
|
|
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 (
|
|
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
|
-
|
|
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
|
-
|
|
67
|
-
|
|
68
|
-
|
|
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
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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
|
-
|
|
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(
|